diff --git a/build.sh b/build.sh index 99896652d..df0a13d26 100755 --- a/build.sh +++ b/build.sh @@ -158,6 +158,9 @@ function build xrelease_asan) do_build "$@" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DOB_USE_LLD=$LLD_OPTION -DOB_USE_ASAN=$ASAN_OPTION ;; + xrelease_coverage) + do_build "$@" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DOB_USE_LLD=$LLD_OPTION -DWITH_COVERAGE=ON + ;; xdebug) do_build "$@" -DCMAKE_BUILD_TYPE=Debug -DOB_USE_LLD=$LLD_OPTION ;; diff --git a/deps/easy/src/util/easy_time.c b/deps/easy/src/util/easy_time.c index e00c259d8..5ee15ab8a 100644 --- a/deps/easy/src/util/easy_time.c +++ b/deps/easy/src/util/easy_time.c @@ -208,7 +208,7 @@ void build_tsc_timestamp() tsc_obj.use_tsc = 1; } } - printf("build_tsc_timestamp: use_tsc=%d scale=%ld\n", tsc_obj.use_tsc, tsc_obj.scale); + // printf("build_tsc_timestamp: use_tsc=%d scale=%ld\n", tsc_obj.use_tsc, tsc_obj.scale); tsc_obj.is_inited = 1; } } diff --git a/deps/oblib/src/common/meta_programming/ob_meta_compare.h b/deps/oblib/src/common/meta_programming/ob_meta_compare.h new file mode 100644 index 000000000..51a4885f2 --- /dev/null +++ b/deps/oblib/src/common/meta_programming/ob_meta_compare.h @@ -0,0 +1,52 @@ +#ifndef DEPS_OBLIB_SRC_COMMON_META_PROGRAMMING_OB_META_COMPARE_H +#define DEPS_OBLIB_SRC_COMMON_META_PROGRAMMING_OB_META_COMPARE_H + +#include "lib/ob_define.h" +#include "ob_type_traits.h" + +namespace oceanbase +{ +namespace common +{ +namespace meta +{ + +template ::type = true> +int compare(const T &lhs, const T&rhs, int &result) +{ + int ret = OB_SUCCESS; + result = 0; + if (lhs < rhs) { + result = -1; + } else if (lhs == rhs) { + result = 0; + } else { + result = 1; + } + return ret; +} + +template ::type = true> +int compare(const T &lhs, const T&rhs, int &result) +{ + return lhs.compare(rhs, result); +} + +template ::type = true> +int compare(const T &lhs, const T&rhs, int &result) +{ + static_assert(!(!OB_TRAIT_IS_ORIGIN_COMPAREABLE(T) && + !OB_TRAIT_IS_METHOD_COMPAREABLE(T)), + "your type NEITHER has opertor< and operator== " + "NOR has int T::comapre(cosnt T&)"); + return OB_NOT_SUPPORTED; +} + +} +} +} +#endif \ No newline at end of file diff --git a/deps/oblib/src/common/meta_programming/ob_meta_copy.h b/deps/oblib/src/common/meta_programming/ob_meta_copy.h new file mode 100644 index 000000000..7c50f1359 --- /dev/null +++ b/deps/oblib/src/common/meta_programming/ob_meta_copy.h @@ -0,0 +1,127 @@ +#ifndef DEPS_OBLIB_SRC_COMMON_META_PROGRAMMING_OB_META_COPY_H +#define DEPS_OBLIB_SRC_COMMON_META_PROGRAMMING_OB_META_COPY_H +#include "ob_meta_define.h" +#include "lib/ob_define.h" +#include "lib/ob_errno.h" +#include "ob_type_traits.h" + +namespace oceanbase +{ +namespace common +{ +namespace meta +{ + +// 3.1 try user defined deep assign method with allocator +template ::type = true> +inline int copy_or_assign(const T &src, + T &dst, + ObIAllocator &alloc = DummyAllocator::get_instance()) +{ + return dst.assign(alloc, src); +} + +// 3.2 try user defined assign method without allocator +template ::type = true> +inline int copy_or_assign(const T &src, + T &dst, + ObIAllocator &alloc = DummyAllocator::get_instance()) +{ + UNUSED(alloc); + return dst.assign(src); +} + +// 3.3 try standard assignment +template ::value, bool>::type = true> +inline int copy_or_assign(const T &src, + T &dst, + ObIAllocator &alloc = DummyAllocator::get_instance()) +{ + UNUSED(alloc); + dst = src; + return common::OB_SUCCESS; +} + +// 3.4. try copy construction +template ::value && + std::is_copy_constructible::value, bool>::type = true> +inline int copy_or_assign(const T &src, + T &dst, + ObIAllocator &alloc = DummyAllocator::get_instance()) +{ + UNUSED(alloc); + new (&dst) T (src); + return common::OB_SUCCESS; +} + +// 3.5. compile error message +template ::value && + !std::is_copy_constructible::value, bool>::type = true> +inline int copy_or_assign(const T &src, + T &dst, + ObIAllocator &alloc = DummyAllocator::get_instance()) +{ + UNUSED(src); + UNUSED(dst); + UNUSED(alloc); + static_assert(!(!OB_TRAIT_HAS_DEEP_ASSIGN(T) && + !OB_TRAIT_HAS_ASSIGN(T) && + !std::is_copy_assignable::value && + !std::is_copy_constructible::value), + "your type is not deep assignable, not normal assignable, not copy assignable, " + "not copy constructible, there is no way to copy it"); + return OB_NOT_SUPPORTED; +} + +// user will benefit from move sematic if dst is an rvalue and support move sematic +// 1.1 try standard move assignment +template ::value && + std::is_move_assignable::value, bool>::type = true> +inline int move_or_copy_or_assign(T &&src, + T &dst, + ObIAllocator &alloc = DummyAllocator::get_instance()) +{ + UNUSED(alloc); + dst = std::move(src); + return common::OB_SUCCESS; +} + +// 1.2 try move construction +template ::value && + !std::is_move_assignable::value && + std::is_move_constructible::value, bool>::type = true> +inline int move_or_copy_or_assign(T &&src, + T &dst, + ObIAllocator &alloc = DummyAllocator::get_instance()) +{ + UNUSED(alloc); + new (&dst) T (std::move(src)); + return common::OB_SUCCESS; +} + +// if type T is not moveable or src is a lvalue, try copy path +// 2.0 deep copy with allocator +template +inline int move_or_copy_or_assign(const T &src, + T &dst, + ObIAllocator &alloc = DummyAllocator::get_instance()) +{ + return copy_or_assign(src, dst, alloc); +} + +} +} +} +#endif \ No newline at end of file diff --git a/deps/oblib/src/common/meta_programming/ob_meta_define.h b/deps/oblib/src/common/meta_programming/ob_meta_define.h new file mode 100644 index 000000000..5f570321d --- /dev/null +++ b/deps/oblib/src/common/meta_programming/ob_meta_define.h @@ -0,0 +1,22 @@ +#ifndef SRC_COMMON_META_PROGRAMMING_OB_META_DEFINE_H +#define SRC_COMMON_META_PROGRAMMING_OB_META_DEFINE_H +#include "lib/allocator/ob_allocator.h" +namespace oceanbase +{ +namespace common +{ +namespace meta +{ + +struct DummyAllocator : public ObIAllocator +{ +virtual void *alloc(const int64_t) override { return nullptr; } +virtual void* alloc(const int64_t, const ObMemAttr &) { return nullptr; } +virtual void free(void *ptr) override {} +static DummyAllocator &get_instance() { static DummyAllocator alloc; return alloc; } +}; + +} +} +} +#endif \ No newline at end of file diff --git a/deps/oblib/src/common/meta_programming/ob_meta_serialization.h b/deps/oblib/src/common/meta_programming/ob_meta_serialization.h new file mode 100644 index 000000000..78c8b935a --- /dev/null +++ b/deps/oblib/src/common/meta_programming/ob_meta_serialization.h @@ -0,0 +1,58 @@ +#ifndef DEPS_OBLIB_SRC_COMMON_META_PROGRAMMING_OB_META_SERIALIZATION_H +#define DEPS_OBLIB_SRC_COMMON_META_PROGRAMMING_OB_META_SERIALIZATION_H + +#include "ob_meta_define.h" +#include "lib/ob_errno.h" +#include "ob_type_traits.h" + +namespace oceanbase +{ +namespace common +{ +namespace meta +{ + +template +class MetaSerializer +{ + template ::type = true> + void requires() { + static_assert(!(!OB_TRAIT_SERIALIZEABLE(T2) && !OB_TRAIT_DEEP_SERIALIZEABLE(T2)), + "your type is not serializable"); + } +public: + MetaSerializer(ObIAllocator &alloc, const T &data) + : alloc_(alloc), + data_(const_cast(data)) {} + MetaSerializer(const MetaSerializer &rhs) + : alloc_(rhs.alloc_), + data_(rhs.data_) {} + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const + { + return data_.serialize(buf, buf_len, pos); + } + template ::type = true> + int deserialize(const char *buf, const int64_t buf_len, int64_t &pos) + { + return data_.deserialize(buf, buf_len, pos); + } + template ::type = true> + int deserialize(const char *buf, const int64_t buf_len, int64_t &pos) + { + return data_.deserialize(alloc_, buf, buf_len, pos); + } + int64_t get_serialize_size() const { return data_.get_serizalize_size(); } +private: + ObIAllocator &alloc_; + T &data_; +}; + +} +} +} +#endif \ No newline at end of file diff --git a/deps/oblib/src/common/meta_programming/ob_type_traits.h b/deps/oblib/src/common/meta_programming/ob_type_traits.h new file mode 100644 index 000000000..36f16d05c --- /dev/null +++ b/deps/oblib/src/common/meta_programming/ob_type_traits.h @@ -0,0 +1,323 @@ +#ifndef DEPS_OBLIB_SRC_COMMON_META_PROGRAMMING_OB_TYPE_TRAIT_H +#define DEPS_OBLIB_SRC_COMMON_META_PROGRAMMING_OB_TYPE_TRAIT_H +#include +#include +#include "lib/allocator/ob_allocator.h" +#include "lib/oblog/ob_log_print_kv.h" +#include "lib/utility/ob_print_utils.h" +#include "lib/oblog/ob_log_module.h" + +namespace oceanbase +{ +namespace share +{ +class SCN; +} +namespace storage +{ +namespace mds +{ +class BufferCtx; +} +} +namespace transaction +{ + class ObMulSourceDataNotifyArg; +} +namespace common +{ +namespace meta +{ + +#define __CONNECT_CLASS_AND_METHOD__(class, method) class.method + +#define REGISTER_FUNCTION_TRAIT(function_name) \ +template\ +struct has_##function_name {};\ +template\ +struct has_##function_name {\ +private:\ + template\ + static constexpr auto check(T*)\ + -> typename\ + std::is_same<\ + decltype( \ + __CONNECT_CLASS_AND_METHOD__(std::declval(), function_name)\ + ( std::declval()... )),\ + Ret\ + >::type;\ + template\ + static constexpr std::false_type check(...);\ + typedef decltype(check(0)) type;\ +public:\ + static constexpr bool value = type::value;\ +}; + +template +struct is_function_like {}; +template +struct is_function_like { +private: + template + static constexpr auto check(T*) + -> typename + std::is_same< + decltype( + std::declval().operator()( std::declval()... )), + Ret + >::type; + template + static constexpr std::false_type check(...); + typedef decltype(check(0)) type; +public: + static constexpr bool value = type::value; +}; + +template +struct has_less_operator { +private: + template + static constexpr auto check(T*) + -> typename + std::is_same< + decltype( + std::declval().operator<()(std::declval())), + bool + >::type; + template + static constexpr std::false_type check(...); + typedef decltype(check(0)) type; +public: + static constexpr bool value = type::value; +}; + +template +struct has_equal_operator { +private: + template + static constexpr auto check(T*) + -> typename + std::is_same< + decltype( + std::declval().operator==()(std::declval())), + bool + >::type; + template + static constexpr std::false_type check(...); + typedef decltype(check(0)) type; +public: + static constexpr bool value = type::value; +}; + +REGISTER_FUNCTION_TRAIT(init) +REGISTER_FUNCTION_TRAIT(destroy) +REGISTER_FUNCTION_TRAIT(start) +REGISTER_FUNCTION_TRAIT(stop) +REGISTER_FUNCTION_TRAIT(wait) +REGISTER_FUNCTION_TRAIT(assign) +REGISTER_FUNCTION_TRAIT(to_string) +REGISTER_FUNCTION_TRAIT(serialize) +REGISTER_FUNCTION_TRAIT(deserialize) +REGISTER_FUNCTION_TRAIT(get_serialize_size) +REGISTER_FUNCTION_TRAIT(compare) +REGISTER_FUNCTION_TRAIT(check_can_replay_commit) +REGISTER_FUNCTION_TRAIT(on_commit_for_old_mds) + +REGISTER_FUNCTION_TRAIT(on_set) +REGISTER_FUNCTION_TRAIT(on_redo) +REGISTER_FUNCTION_TRAIT(on_prepare) +REGISTER_FUNCTION_TRAIT(on_commit) +REGISTER_FUNCTION_TRAIT(on_abort) + + +#define DECAY(CLASS) typename std::decay::type + +// define thread like trait and enable_if macro +#define OB_TRAIT_IS_THREAD_LIKE(CLASS) \ +::oceanbase::common::meta::has_start::value &&\ +::oceanbase::common::meta::has_stop::value &&\ +::oceanbase::common::meta::has_wait::value +#define ENABLE_IF_LIKE_THREAD(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_LIKE_THREAD(CLASS) \ +typename std::enable_if::type = true + +// define to_string trait and enable_if macro +#define OB_TRAIT_HAS_TO_STRING(CLASS) \ +::oceanbase::common::meta::has_to_string::value +#define ENABLE_IF_HAS_TO_STRING(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_HAS_TO_STRING(CLASS) \ +typename std::enable_if::type = true + +// define serialize trait and enable_if macro +#define OB_TRAIT_SERIALIZEABLE(CLASS) \ +(::oceanbase::common::meta::has_serialize::value &&\ +::oceanbase::common::meta::has_deserialize::value &&\ +::oceanbase::common::meta::has_get_serialize_size::value) +#define ENABLE_IF_SERIALIZEABLE(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_SERIALIZEABLE(CLASS) \ +typename std::enable_if::type = true + +// define serialize trait and enable_if macro +#define OB_TRAIT_DEEP_SERIALIZEABLE(CLASS) \ +(::oceanbase::common::meta::has_serialize::value &&\ +::oceanbase::common::meta::has_deserialize::value &&\ +::oceanbase::common::meta::has_get_serialize_size::value) +#define ENABLE_IF_DEEP_SERIALIZEABLE(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_DEEP_SERIALIZEABLE(CLASS) \ +typename std::enable_if::type = true + +// define assign trait and enable_if macro +#define OB_TRAIT_HAS_ASSIGN(CLASS) \ +::oceanbase::common::meta::has_assign::value +#define ENABLE_IF_HAS_ASSIGN(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_HAS_ASSIGN(CLASS) \ +typename std::enable_if::type = true + +// define assign trait and enable_if macro +#define OB_TRAIT_HAS_DEEP_ASSIGN(CLASS) \ +::oceanbase::common::meta::has_assign::value +#define ENABLE_IF_HAS_DEEP_ASSIGN(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_HAS_DEEP_ASSIGN(CLASS) \ +typename std::enable_if::type = true + +// define funtion like trait and enable_if macro +#define OB_TRAIT_IS_FUNCTION_LIKE(CLASS, DECLEARATION) \ +::oceanbase::common::meta::is_function_like::value +#define ENABLE_IF_LIKE_FUNCTION(CLASS, DECLEARATION) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_LIKE_FUNCTION(CLASS, DECLEARATION) \ +typename std::enable_if::type = true + +// define common enable_if macro +#define ENABLE_IF_HAS(CLASS, FUNCTION, DECLEARATION) \ +typename std::enable_if<::oceanbase::common::meta::has_##FUNCTION::value,\ + bool>::type = true +#define ENABLE_IF_NOT_HAS(CLASS, FUNCTION, DECLEARATION) \ +typename std::enable_if::value,\ + bool>::type = true + +// define compare trait and enable_if macro +#define OB_TRAIT_HAS_LESS_OPERATOR(CLASS) \ +::oceanbase::common::meta::has_less_operator::value +#define OB_TRAIT_HAS_EQUAL_OPERATOR(CLASS) \ +::oceanbase::common::meta::has_equal_operator::value +#define OB_TRAIT_IS_ORIGIN_COMPAREABLE(CLASS) \ +OB_TRAIT_HAS_LESS_OPERATOR(CLASS) && OB_TRAIT_HAS_EQUAL_OPERATOR(CLASS) +#define OB_TRAIT_IS_METHOD_COMPAREABLE(CLASS) \ +::oceanbase::common::meta::has_compare::value +#define OB_TRAIT_IS_COMPAREABLE(CLASS) \ +OB_TRAIT_IS_ORIGIN_COMPAREABLE(CLASS) || OB_TRAIT_IS_METHOD_COMPAREABLE(CLASS) +#define ENABLE_IF_COMPAREABLE(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_COMPAREABLE(CLASS) \ +typename std::enable_if::type = true + +// define copy and move trait and enable_if macro +#define OB_TRAIT_IS_MOVEABLE(CLASS) \ +std::is_move_assignable::value || std::is_move_constructible::value +#define OB_TRAIT_IS_COPIABLE(CLASS) \ +OB_TRAIT_HAS_ASSIGN(T) ||\ +std::is_copy_assignable::value ||\ +std::is_copy_constructible::value +#define OB_TRAIT_IS_MOVE_OR_COPIABLE(CLASS) \ +OB_TRAIT_IS_MOVEABLE(CLASS) || OB_TRAIT_IS_COPIABLE(CLASS) +#define ENABLE_IF_MOVEABLE(CLASS, FUNCTION, DECLEARATION) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_MOVEABLE(CLASS, FUNCTION, DECLEARATION) \ +typename std::enable_if::type = true +#define ENABLE_IF_COPIABLE(CLASS, FUNCTION, DECLEARATION) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_COPIABLE(CLASS, FUNCTION, DECLEARATION) \ +typename std::enable_if::type = true +#define ENABLE_IF_MOVE_OR_COPIABLE(CLASS, FUNCTION, DECLEARATION) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_MOVE_AND_COPIABLE(CLASS, FUNCTION, DECLEARATION) \ +typename std::enable_if::type = true + +// define two-phase-commit trait and enable_if macro +#define OB_TRAIT_HAS_ON_SET(CLASS) \ +::oceanbase::common::meta::has_on_set::value +#define OB_TRAIT_HAS_ON_REDO(CLASS) \ +::oceanbase::common::meta::has_on_redo::value +#define OB_TRAIT_HAS_ON_PREPARE(CLASS) \ +::oceanbase::common::meta::has_on_prepare::value +#define OB_TRAIT_HAS_ON_COMMIT(CLASS) \ +::oceanbase::common::meta::has_on_commit::value +#define OB_TRAIT_HAS_ON_ABORT(CLASS) \ +::oceanbase::common::meta::has_on_abort::value +#define ENABLE_IF_HAS_ON_SET(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_HAS_ON_SET(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_HAS_ON_REDO(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_HAS_ON_REDO(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_HAS_ON_PREPARE(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_HAS_ON_PREPARE(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_HAS_ON_COMMIT(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_HAS_ON_COMMIT(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_HAS_ON_ABORT(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_HAS_ON_ABORT(CLASS) \ +typename std::enable_if::type = true + +#define OB_TRAIT_HAS_CHECK_CAN_REPLAY_COMMIT(CLASS) \ +::oceanbase::common::meta::has_check_can_replay_commit::value +#define ENABLE_IF_HAS_CHECK_CAN_REPLAY_COMMIT(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_HAS_CHECK_CAN_REPLAY_COMMIT(CLASS) \ +typename std::enable_if::type = true + +#define OB_TRAIT_MDS_COMMIT_FOR_OLD_MDS(CLASS) \ +::oceanbase::common::meta::has_on_commit_for_old_mds::value +#define ENABLE_IF_MDS_COMMIT_FOR_OLD_MDS(CLASS) \ +typename std::enable_if::type = true +#define ENABLE_IF_NOT_MDS_COMMIT_FOR_OLD_MDS(CLASS) \ +typename std::enable_if::type = true + +template +struct MdsCheckCanReplayWrapper { + template + static bool check_can_replay_commit(const char *buf, const int64_t buf_len, const share::SCN &scn, storage::mds::BufferCtx &ctx) { + return T::check_can_replay_commit(buf, buf_len, scn, ctx); + } + template + static bool check_can_replay_commit(const char *, const int64_t, const share::SCN &, storage::mds::BufferCtx &) { + return true; + } +}; + +template +struct MdsCommitForOldMdsWrapper { + template + static int on_commit_for_old_mds(const char *buf, const int64_t buf_len, const transaction::ObMulSourceDataNotifyArg &arg) { + return T::on_commit_for_old_mds(buf, buf_len, arg); + } + template + static int on_commit_for_old_mds(const char *, const int64_t, const transaction::ObMulSourceDataNotifyArg &) { + return OB_SUCCESS; + } +}; + +} +} +} + +#endif diff --git a/deps/oblib/src/common/ob_tablet_id.h b/deps/oblib/src/common/ob_tablet_id.h index d9f930096..2592eeb67 100644 --- a/deps/oblib/src/common/ob_tablet_id.h +++ b/deps/oblib/src/common/ob_tablet_id.h @@ -103,7 +103,9 @@ public: bool operator==(const ObTabletID &other) const { return id_ == other.id_; } bool operator!=(const ObTabletID &other) const { return id_ != other.id_; } bool operator< (const ObTabletID &other) const { return id_ < other.id_; } + bool operator<=(const ObTabletID &other) const { return id_ <= other.id_; } bool operator> (const ObTabletID &other) const { return id_ > other.id_; } + bool operator>=(const ObTabletID &other) const { return id_ >= other.id_; } int compare(const ObTabletID &other) const { if (id_ == other.id_) { diff --git a/deps/oblib/src/common/storage/ob_freeze_define.h b/deps/oblib/src/common/storage/ob_freeze_define.h index 1eeffe3ea..e73ecc3e4 100644 --- a/deps/oblib/src/common/storage/ob_freeze_define.h +++ b/deps/oblib/src/common/storage/ob_freeze_define.h @@ -33,7 +33,9 @@ enum ObFreezeType INVALID_FREEZE = 0, MAJOR_FREEZE, MINOR_FREEZE, - TX_DATA_TABLE_FREEZE + TX_DATA_TABLE_FREEZE, + MDS_TABLE_FREEZE, + MAX_FREEZE_TYPE }; struct ObFrozenStatus diff --git a/deps/oblib/src/lib/alloc/ob_malloc_allocator.cpp b/deps/oblib/src/lib/alloc/ob_malloc_allocator.cpp index 6a6b0add5..cfd7add0d 100644 --- a/deps/oblib/src/lib/alloc/ob_malloc_allocator.cpp +++ b/deps/oblib/src/lib/alloc/ob_malloc_allocator.cpp @@ -189,7 +189,7 @@ void *ObMallocAllocator::realloc( } else if (OB_ISNULL(nptr = allocator->realloc(ptr, size, inner_attr))) { // do nothing } - return nptr;; + return nptr; #endif } @@ -247,7 +247,7 @@ ObTenantCtxAllocatorGuard ObMallocAllocator::get_tenant_ctx_allocator(uint64_t t { if (OB_LIKELY(tl_ta != NULL && tl_ta->get_tenant_id() == tenant_id)) { const bool lock = false; - return ObTenantCtxAllocatorGuard(&tl_ta[ctx_id], lock);; + return ObTenantCtxAllocatorGuard(&tl_ta[ctx_id], lock); } return get_tenant_ctx_allocator_without_tlcache(tenant_id, ctx_id); } diff --git a/deps/oblib/src/lib/allocator/ob_fifo_allocator.cpp b/deps/oblib/src/lib/allocator/ob_fifo_allocator.cpp index 88bf6dcef..4e553ff13 100644 --- a/deps/oblib/src/lib/allocator/ob_fifo_allocator.cpp +++ b/deps/oblib/src/lib/allocator/ob_fifo_allocator.cpp @@ -440,9 +440,11 @@ void ObFIFOAllocator::free_normal(NormalPageHeader *page, int64_t size) if (page == current_using_ && 1 == current_using_->ref_count_) { current_using_->offset_ = reinterpret_cast(current_using_) + sizeof(NormalPageHeader); } else if (0 == page->ref_count_) { - // move this page from page_using_list to page_free_list + int64_t normal_total_size = normal_total(); + int64_t total_size = total(); using_page_list_.remove(&page->node_); - if (normal_total() > idle_size_ || total() > max_size_) { + // move this page from page_using_list to page_free_list + if (normal_total_size > idle_size_ || total_size > max_size_) { allocator_->free(page); page = nullptr; } else { diff --git a/deps/oblib/src/lib/allocator/ob_fifo_allocator.h b/deps/oblib/src/lib/allocator/ob_fifo_allocator.h index 54ffca24c..da3833a14 100644 --- a/deps/oblib/src/lib/allocator/ob_fifo_allocator.h +++ b/deps/oblib/src/lib/allocator/ob_fifo_allocator.h @@ -103,6 +103,7 @@ public: void set_attr(const ObMemAttr &attr) { attr_ = attr; } int set_idle(const int64_t idle_size, const bool sync=false); int set_max(const int64_t max_size, const bool sync=false); + int64_t get_max() const { return max_size_; } bool is_inited() const { return is_inited_; } inline int64_t normal_used() const diff --git a/deps/oblib/src/lib/allocator/ob_mod_define.h b/deps/oblib/src/lib/allocator/ob_mod_define.h index f87f824f7..388870e96 100644 --- a/deps/oblib/src/lib/allocator/ob_mod_define.h +++ b/deps/oblib/src/lib/allocator/ob_mod_define.h @@ -31,6 +31,8 @@ CTX_ITEM_DEF(RPC_CTX_ID) CTX_ITEM_DEF(PKT_NIO) CTX_ITEM_DEF(TX_DATA_TABLE) CTX_ITEM_DEF(STORAGE_LONG_TERM_META_CTX_ID) +CTX_ITEM_DEF(MDS_DATA_ID) +CTX_ITEM_DEF(MDS_CTX_ID) CTX_ITEM_DEF(SCHEMA_SERVICE) CTX_ITEM_DEF(UNEXPECTED_IN_500) CTX_ITEM_DEF(MAX_CTX_ID) @@ -239,7 +241,7 @@ LABEL_ITEM_DEF(OB_STORE_ROW_LOCK_CHECKER, StorRowLockChec) LABEL_ITEM_DEF(OB_MYSQL_PACKET, MysqlPacket) //rootservermodules -LABEL_ITEM_DEF(OB_REBALANCE_TASK_MGR, RebalaTaskMgr) +LABEL_ITEM_DEF(OB_REFERED_MAP, ReferedMap) LABEL_ITEM_DEF(OB_RS_PARTITION_TABLE_TEMP, RsPartiTableTem) LABEL_ITEM_DEF(OB_ZONE_TABLE_UPDATER, ZoneTableUpdate) LABEL_ITEM_DEF(OB_HASH_BUCKET_POOL_UNIT_MAP, HashBucPooUniMa) diff --git a/deps/oblib/src/lib/container/ob_tuple.h b/deps/oblib/src/lib/container/ob_tuple.h index 50f597702..a79f7589b 100644 --- a/deps/oblib/src/lib/container/ob_tuple.h +++ b/deps/oblib/src/lib/container/ob_tuple.h @@ -22,6 +22,7 @@ #include #include #include "lib/utility/serialization.h" +#include "lib/utility/ob_print_utils.h" namespace oceanbase { @@ -235,9 +236,25 @@ struct has_get_serialize_size_for_all_type static constexpr bool value = std::is_class::value ? has_get_serialize_size::value : true; }; +template +struct ConvertElementTypeToIndex +{ + static constexpr int index = ConvertElementTypeToIndex::index; +}; + +template +struct ConvertElementTypeToIndex +{ + static constexpr int index = sizeof...(OTHERS); +}; + template class ObTupleBaseBase { +public: + static constexpr int get_element_size() { return sizeof...(T); } + template + static constexpr int get_element_index() { return sizeof...(T) - 1 - ConvertElementTypeToIndex::index; } protected: std::tuple tuple_; template @@ -247,7 +264,7 @@ protected: { int ret = OB_SUCCESS; if (OB_FAIL(functor(std::get(tuple)))) { - OB_LOG(WARN, "apply FUNC on element failed", K(ret), K(N), K(std::get(tuple))); + // OB_LOG(WARN, "apply FUNC on element failed", K(ret), K(N), K(std::get(tuple))); } else if (OB_SUCCESS != (ret = (ForEachHelper::iterate(tuple, functor)))) { } return ret; @@ -256,30 +273,22 @@ protected: { int ret = OB_SUCCESS; if (OB_FAIL(functor(std::get(tuple)))) { - OB_LOG(WARN, "apply FUNC on element failed", K(ret), K(N), K(std::get(tuple))); + // OB_LOG(WARN, "apply FUNC on element failed", K(ret), K(N), K(std::get(tuple))); } else if (OB_SUCCESS != (ret = (ForEachHelper::iterate(tuple, functor)))) { } return ret; } }; template - struct ForEachHelper + struct ForEachHelper { static int iterate(std::tuple &tuple, FUNC &functor) { - int ret = OB_SUCCESS; - if (OB_FAIL(functor(std::get(tuple)))) { - OB_LOG(WARN, "assign element failed", K(ret), K(std::get(tuple))); - } - return ret; + return OB_SUCCESS; } static int iterate(const std::tuple &tuple, FUNC &functor) { - int ret = OB_SUCCESS; - if (OB_FAIL(functor(std::get(tuple)))) { - OB_LOG(WARN, "assign element failed", K(ret), K(std::get(tuple))); - } - return ret; + return OB_SUCCESS; } }; public: @@ -300,6 +309,10 @@ public: auto element() -> decltype(std::get(tuple_)) { return std::get(tuple_); } template auto element() const -> const decltype(std::get(tuple_)) { return std::get(tuple_); } + template + auto element() -> ELEMENT_TYPE& { return std::get()>(tuple_); } + template + auto element() const -> ELEMENT_TYPE& { return std::get()>(tuple_); } template int get_element(size_t idx, V &value) { diff --git a/deps/oblib/src/lib/function/ob_function.h b/deps/oblib/src/lib/function/ob_function.h index d0546dea6..4decf5919 100644 --- a/deps/oblib/src/lib/function/ob_function.h +++ b/deps/oblib/src/lib/function/ob_function.h @@ -92,7 +92,7 @@ namespace common namespace function { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG struct DebugRecorder { int function_default_construct_time = 0; int function_copy_construct_time = 0; @@ -119,7 +119,7 @@ struct DebugRecorder { struct DefaultFunctionAllocator : public ObIAllocator { void *alloc(const int64_t size) override { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG total_alive_num++; #endif static lib::ObMemAttr attr(OB_SERVER_TENANT_ID, "ObFunction"); @@ -131,12 +131,12 @@ struct DefaultFunctionAllocator : public ObIAllocator { return alloc(size); } void free(void *ptr) override { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG total_alive_num--; #endif ob_free(ptr); } -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG int total_alive_num = 0; #endif static DefaultFunctionAllocator &get_default_allocator() { @@ -176,7 +176,7 @@ class ObFunction { Derived(const Derived &&fn) = delete; template Derived(Arg &&fn) : func_(std::forward(fn)) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.derived_construct_time++; #endif } @@ -210,7 +210,7 @@ public: // default constructor explicit ObFunction(ObIAllocator &allocator = DEFAULT_ALLOCATOR) : base_(nullptr), allocator_(allocator) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_default_construct_time++; #endif } @@ -218,7 +218,7 @@ public: ObFunction(const ObFunction &rhs, ObIAllocator &allocator = DEFAULT_ALLOCATOR) : base_(nullptr), allocator_(allocator) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_copy_construct_time++; #endif (void)assign(rhs); @@ -227,7 +227,7 @@ public: ObFunction(ObFunction &&rhs, ObIAllocator &allocator = DEFAULT_ALLOCATOR) : base_(nullptr), allocator_(allocator) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_move_construct_time++; #endif (void)assign(std::forward>(rhs)); @@ -242,18 +242,18 @@ public: ObFunction(Fn &&rhs, ObIAllocator &allocator = DEFAULT_ALLOCATOR) : base_(nullptr), allocator_(allocator) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_general_construct_time++; #endif (void)assign(std::forward(rhs)); } -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG Abstract* get_func_ptr() { return base_; } #endif // copy assign operator ObFunction &operator=(const ObFunction &rhs) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_copy_equal_time++; #endif (void)assign(rhs); @@ -261,7 +261,7 @@ public: } // move assign operator ObFunction &operator=(ObFunction &&rhs) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_move_equal_time++; #endif (void)assign(std::forward>(rhs)); @@ -272,7 +272,7 @@ public: typename std::enable_if< !std::is_same::type, ObFunction>::value, bool>::type = true> ObFunction &operator=(Fn &&rhs) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_general_equal_time++; #endif (void)assign(std::forward(rhs)); @@ -299,14 +299,14 @@ public: bool is_valid() const { return nullptr != base_; } // copy assign int assign(const ObFunction &rhs) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_copy_assign_time++; #endif return base_assign_(rhs.base_); } // move assign int assign(ObFunction &&rhs) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_move_assign_time++; #endif int ret = OB_SUCCESS; @@ -329,7 +329,7 @@ public: typename std::enable_if< !std::is_same::type, ObFunction>::value, bool>::type = true> int assign(Fn &&rhs) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_general_assign_time++; #endif int ret = OB_SUCCESS; @@ -352,7 +352,7 @@ public: KP(&DEFAULT_ALLOCATOR)); private: int base_assign_(Abstract *rhs) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG RECORDER.function_base_assign_time++; #endif int ret = OB_SUCCESS; diff --git a/deps/oblib/src/lib/future/ob_future.h b/deps/oblib/src/lib/future/ob_future.h index 92e975c89..734aa3391 100644 --- a/deps/oblib/src/lib/future/ob_future.h +++ b/deps/oblib/src/lib/future/ob_future.h @@ -106,7 +106,7 @@ namespace future struct DefaultFutureAllocator : public ObIAllocator { void *alloc(const int64_t size) override { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG total_alive_num++; #endif return ob_malloc(size, SET_USE_500("ObFuture")); @@ -116,12 +116,12 @@ struct DefaultFutureAllocator : public ObIAllocator { return alloc(size); } void free(void *ptr) override { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG total_alive_num--; #endif ob_free(ptr); } -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG int total_alive_num = 0; #endif static DefaultFutureAllocator &get_default_allocator() { diff --git a/deps/oblib/src/lib/guard/ob_light_shared_gaurd.h b/deps/oblib/src/lib/guard/ob_light_shared_gaurd.h new file mode 100644 index 000000000..6990f3839 --- /dev/null +++ b/deps/oblib/src/lib/guard/ob_light_shared_gaurd.h @@ -0,0 +1,160 @@ +#ifndef OCEANBASE_LIB_GUARD_OB_LIGHT_SHARED_GUARD_H +#define OCEANBASE_LIB_GUARD_OB_LIGHT_SHARED_GUARD_H +#include "lib/allocator/ob_malloc.h" +#include "lib/ob_errno.h" +#include "ob_shared_guard.h" +#include "common/ob_clock_generator.h" + +namespace oceanbase +{ +namespace common +{ +namespace guard +{ +struct IData { + virtual ~IData() {} + virtual int64_t to_string(char *, const int64_t) const = 0; +}; +struct LightControlBlock +{ + LightControlBlock(ObIAllocator &alloc) : ref_(1), alloc_(alloc), p_data_block_(nullptr) {} + ~LightControlBlock() { + OCCAM_LOG(DEBUG, "control block is dec to 0, execute destruct action", K(*this), K(lbt())); + p_data_block_->~IData(); + p_data_block_ = nullptr; + alloc_.free(this); + } + void inc_ref() { OB_ASSERT(ATOMIC_LOAD(&ref_) > 0); ATOMIC_AAF(&ref_, 1); } + int64_t dec_ref() { return ATOMIC_AAF(&ref_, -1); } + int64_t get_ref() { return ATOMIC_LOAD(&ref_); } + TO_STRING_KV(K_(ref), KPC_(p_data_block)); + int64_t ref_; + ObIAllocator &alloc_; + IData *p_data_block_; +}; +template +struct LightDataBlock : public IData +{ + LightDataBlock() = default; + virtual ~LightDataBlock() override { + ((T *)(data_))->~T(); + } + int64_t to_string(char *buf, const int64_t buf_len) const override { + return ((T *)data_)->to_string(buf, buf_len); + } + char data_[sizeof(T)]; +}; +template +struct LightCombinedBlock { + LightCombinedBlock(ObIAllocator &alloc) : ctrl_block_(alloc) { + ctrl_block_.p_data_block_ = &data_block_; + new (&data_block_.data_) T(); + OB_ASSERT((void*)this == (void*)&ctrl_block_); + } + LightControlBlock ctrl_block_; + LightDataBlock data_block_; +}; +} + +template +struct ObLightSharedPtr// RAII used +{ + ObLightSharedPtr() : ctrl_ptr_(nullptr), data_(nullptr) {} + ObLightSharedPtr(const ObLightSharedPtr &rhs) : ObLightSharedPtr() { (void)assign(rhs); } + ObLightSharedPtr &operator=(const ObLightSharedPtr &rhs) { + (void)assign(rhs); + return *this; + } + template ::value, + bool>::type = true> + ObLightSharedPtr(const ObLightSharedPtr &rhs) : ObLightSharedPtr() { (void)assign(rhs); } + template ::value, + bool>::type = true> + ObLightSharedPtr &operator=(const ObLightSharedPtr &rhs) { + (void)assign(rhs); + return *this; + } + template ::value || + std::is_same::value, bool>::type = true> + int assign(const ObLightSharedPtr &rhs) { + if ((void*)this != (void*)&rhs) { + reset(); + if (OB_NOT_NULL(rhs.ctrl_ptr_)) { + rhs.ctrl_ptr_->inc_ref(); + ctrl_ptr_ = rhs.ctrl_ptr_; + data_ = static_cast(rhs.data_); + } + } + return OB_SUCCESS; + } + ~ObLightSharedPtr() { reset(); } + void reset() { + if (OB_NOT_NULL(ctrl_ptr_)) { + OCCAM_LOG(DEBUG, "ObLightSharedPtr destructed", KPC_(ctrl_ptr)); + if (0 == ctrl_ptr_->dec_ref()) { + ctrl_ptr_->~LightControlBlock(); + } + ctrl_ptr_ = nullptr; + data_ = nullptr; + } + } + bool operator==(const ObLightSharedPtr &rhs) const { return ctrl_ptr_ == rhs.ctrl_ptr_; } + int construct(ObIAllocator &alloc) { + int ret = OB_SUCCESS; + if (OB_NOT_NULL(ctrl_ptr_)) { + OCCAM_LOG(WARN, "ObLightSharedGuard is valid, need reset first", K(ret), K(lbt())); + reset(); + } + guard::LightCombinedBlock *block_ptr = nullptr; + if (OB_ISNULL(block_ptr = (guard::LightCombinedBlock *) + alloc.alloc(sizeof(guard::LightCombinedBlock)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + OCCAM_LOG(WARN, "alloc memory failed", K(ret), K(lbt())); + } else { + new (block_ptr) guard::LightCombinedBlock(alloc); + ctrl_ptr_ = &(block_ptr->ctrl_block_); + data_ = (T*)block_ptr->data_block_.data_; + } + return ret; + } + int get_ref_cnt(int64_t &ref_cnt) const { + int ret = OB_SUCCESS; + if (OB_ISNULL(ctrl_ptr_)) { + ret = OB_NOT_INIT; + OCCAM_LOG(WARN, "get ref on not inited guard", K(ret), K(lbt())); + } else { + ref_cnt = ctrl_ptr_->get_ref(); + } + return ret; + } + int sync_until_last() const { + int ret = OB_SUCCESS; + if (!is_valid()) { + ret = OB_INVALID_DATA; + } else { + int64_t start_sync_time = ObClockGenerator::getCurrentTime(); + int64_t loop_times = 0; + int64_t ref_cnt; + while (1 != (ref_cnt = ctrl_ptr_->get_ref())) { + if ((++loop_times % 100000) == 0) { + OCCAM_LOG(WARN, "sync wait too long", + KTIME(start_sync_time), K(loop_times), K(ref_cnt), K(lbt())); + } + PAUSE(); + } + } + return ret; + } + T &operator*() const { return *data_; } + T *operator->() const { return data_; } + T *ptr() { return data_; } + TO_STRING_KV(KPC_(ctrl_ptr)); + bool is_valid() const { return OB_NOT_NULL(ctrl_ptr_); } + guard::LightControlBlock *ctrl_ptr_; + T *data_; +}; + +} +} + +#endif \ No newline at end of file diff --git a/deps/oblib/src/lib/guard/ob_shared_guard.h b/deps/oblib/src/lib/guard/ob_shared_guard.h index 5dcaab8b2..fe7922e80 100644 --- a/deps/oblib/src/lib/guard/ob_shared_guard.h +++ b/deps/oblib/src/lib/guard/ob_shared_guard.h @@ -123,7 +123,7 @@ namespace guard struct DefaultSharedGuardAllocator : public ObIAllocator { void *alloc(const int64_t size) override { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG total_alive_num++; #endif static lib::ObMemAttr attr(OB_SERVER_TENANT_ID, "ObGuard"); @@ -135,12 +135,12 @@ struct DefaultSharedGuardAllocator : public ObIAllocator { return alloc(size); } void free(void *ptr) override { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG total_alive_num--; #endif ob_free(ptr); } -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG int total_alive_num = 0; #endif static DefaultSharedGuardAllocator &get_default_allocator() { diff --git a/deps/oblib/src/lib/guard/ob_unique_guard.h b/deps/oblib/src/lib/guard/ob_unique_guard.h index 30f22bc00..8a862e4f1 100644 --- a/deps/oblib/src/lib/guard/ob_unique_guard.h +++ b/deps/oblib/src/lib/guard/ob_unique_guard.h @@ -113,7 +113,7 @@ namespace guard struct DefaultUniqueGuardAllocator : public ObIAllocator { void *alloc(const int64_t size) override { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG total_alive_num++; #endif static lib::ObMemAttr attr(OB_SERVER_TENANT_ID, "ObGuard"); @@ -126,12 +126,12 @@ struct DefaultUniqueGuardAllocator : public ObIAllocator { return alloc(size); } void free(void *ptr) override { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG total_alive_num--; #endif ob_free(ptr); } -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG int total_alive_num = 0; #endif static DefaultUniqueGuardAllocator &get_default_allocator() { diff --git a/deps/oblib/src/lib/hash/ob_multi_mod_ref_mgr.h b/deps/oblib/src/lib/hash/ob_multi_mod_ref_mgr.h index a5d333cc2..1509aa151 100644 --- a/deps/oblib/src/lib/hash/ob_multi_mod_ref_mgr.h +++ b/deps/oblib/src/lib/hash/ob_multi_mod_ref_mgr.h @@ -17,6 +17,7 @@ #include "lib/oblog/ob_log.h" #include "lib/thread_local/ob_tsi_utils.h" #include "lib/container/ob_array.h" +#include "lib/string/ob_sql_string.h" namespace oceanbase { @@ -124,16 +125,18 @@ public: ATOMIC_STORE(&is_delete_, true); } void print() { - ObArray mod_ref; - mod_ref.reserve((int64_t)(T::TOTAL_MAX_MOD)); + int tmp_ret = OB_SUCCESS; + ObSqlString msg; for (int mod = 0; mod < static_cast(T::TOTAL_MAX_MOD); mod++) { int32_t ref_cnt = 0; for (int idx = 0; idx < MAX_CPU_NUM; idx++) { ref_cnt += ref_mgr_[idx].ref_info_[mod].get_ref_cnt(); } - mod_ref.push_back(ref_cnt); + if (OB_SUCCESS != (tmp_ret = msg.append_fmt("%s%d:%d", mod>0?",":"", mod, ref_cnt))) { + COMMON_LOG_RET(WARN, tmp_ret, "failed to add msg", K(mod), K(ref_cnt), K(msg)); + } } - COMMON_LOG(INFO, "RefMgr mod ref", "type", typeid(T).name(), K(this), K(mod_ref)); + COMMON_LOG(INFO, "RefMgr mod ref", "type", typeid(T).name(), K(this), K(msg)); } private: void lock_all_slot() { diff --git a/deps/oblib/src/lib/hash/ob_refered_map.h b/deps/oblib/src/lib/hash/ob_refered_map.h index 06a87ec86..c34224f93 100644 --- a/deps/oblib/src/lib/hash/ob_refered_map.h +++ b/deps/oblib/src/lib/hash/ob_refered_map.h @@ -57,9 +57,9 @@ public: common::hash::NoPthreadDefendMode, common::hash::NormalPointer, common::ObMalloc> HashTable; - ObReferedMap() : inited_(false), allocator_(), + ObReferedMap(const lib::ObLabel &label = ObModIds::OB_REFERED_MAP) : inited_(false), allocator_(), bucket_allocator_(), hash_table_() - { allocator_.set_attr(ObMemAttr(common::OB_SERVER_TENANT_ID, common::ObModIds::OB_REBALANCE_TASK_MGR)); } + { allocator_.set_attr(ObMemAttr(common::OB_SERVER_TENANT_ID, label)); } virtual ~ObReferedMap() {} int init(const int64_t bucket_num); @@ -119,7 +119,7 @@ int ObReferedMap::init(const int64_t bucket_num) ret = OB_INVALID_ARGUMENT; LIB_LOG(WARN, "invalid bucket num", K(ret), K(bucket_num)); } else { - bucket_allocator_.set_label(common::ObModIds::OB_REBALANCE_TASK_MGR); + bucket_allocator_.set_label(ObModIds::OB_REFERED_MAP); if (OB_FAIL(hash_table_.create(common::hash::cal_next_prime(bucket_num), &allocator_, &bucket_allocator_))) { LIB_LOG(WARN, "create hash table failed", K(bucket_num), K(ret)); diff --git a/deps/oblib/src/lib/json_type/ob_json_base.cpp b/deps/oblib/src/lib/json_type/ob_json_base.cpp index 1eec61d6c..3a6bc6529 100644 --- a/deps/oblib/src/lib/json_type/ob_json_base.cpp +++ b/deps/oblib/src/lib/json_type/ob_json_base.cpp @@ -2554,7 +2554,7 @@ int ObIJsonBase::cmp_to_left_strictly(ObIAllocator* allocator, ObIJsonBase* hit, cmp_based_on_node_type(node_type, cmp_res, cmp_result); } } else { - ret = OB_ERR_JSON_PATH_EXPRESSION_SYNTAX_ERROR;; + ret = OB_ERR_JSON_PATH_EXPRESSION_SYNTAX_ERROR; LOG_WARN("type incompatibility to compare.", K(ret)); } break; @@ -2579,7 +2579,7 @@ int ObIJsonBase::cmp_to_left_strictly(ObIAllocator* allocator, ObIJsonBase* hit, } } } else { - ret = OB_ERR_JSON_PATH_EXPRESSION_SYNTAX_ERROR;; + ret = OB_ERR_JSON_PATH_EXPRESSION_SYNTAX_ERROR; LOG_WARN("type incompatibility to compare.", K(ret)); } break; @@ -2604,7 +2604,7 @@ int ObIJsonBase::cmp_to_left_strictly(ObIAllocator* allocator, ObIJsonBase* hit, } } } else { - ret = OB_ERR_JSON_PATH_EXPRESSION_SYNTAX_ERROR;; + ret = OB_ERR_JSON_PATH_EXPRESSION_SYNTAX_ERROR; LOG_WARN("type incompatibility to compare.", K(ret)); } break; diff --git a/deps/oblib/src/lib/json_type/ob_json_tree.cpp b/deps/oblib/src/lib/json_type/ob_json_tree.cpp index e625782a6..8343b1f7b 100644 --- a/deps/oblib/src/lib/json_type/ob_json_tree.cpp +++ b/deps/oblib/src/lib/json_type/ob_json_tree.cpp @@ -1117,7 +1117,7 @@ int ObJsonOInterval::parse() int ret = OB_SUCCESS; if (field_type_ == ObIntervalYMType) { ObIntervalYMValue value; - ObScale scale = ObAccuracy::MAX_ACCURACY2[ORACLE_MODE][ObIntervalYMType].get_scale();; + ObScale scale = ObAccuracy::MAX_ACCURACY2[ORACLE_MODE][ObIntervalYMType].get_scale(); if ((NULL == str_val_.find('P')) ? //有P的是ISO格式 OB_FAIL(ObTimeConverter::str_to_interval_ym(str_val_, value, scale)) : OB_FAIL(ObTimeConverter::iso_str_to_interval_ym(str_val_, value))) { @@ -1127,7 +1127,7 @@ int ObJsonOInterval::parse() } } else { ObIntervalDSValue value; - ObScale scale = ObAccuracy::MAX_ACCURACY2[ORACLE_MODE][ObIntervalDSType].get_scale();; + ObScale scale = ObAccuracy::MAX_ACCURACY2[ORACLE_MODE][ObIntervalDSType].get_scale(); if ((NULL == str_val_.find('P')) ? //有P的是ISO格式 OB_FAIL(ObTimeConverter::str_to_interval_ds(str_val_, value, scale)) : OB_FAIL(ObTimeConverter::iso_str_to_interval_ds(str_val_, value))) { diff --git a/deps/oblib/src/lib/list/ob_dlink_node.h b/deps/oblib/src/lib/list/ob_dlink_node.h index fd38cd517..1fa389aec 100644 --- a/deps/oblib/src/lib/list/ob_dlink_node.h +++ b/deps/oblib/src/lib/list/ob_dlink_node.h @@ -119,10 +119,10 @@ void ObDLinkBase::replace_by(Derived *e) template void ObDLinkBase::add(Derived *prev, Derived *e, Derived *next) { - prev->next_ = e; e->prev_ = prev; - next->prev_ = e; e->next_ = next; + prev->next_ = e; + next->prev_ = e; } template diff --git a/deps/oblib/src/lib/list/ob_list.h b/deps/oblib/src/lib/list/ob_list.h index 23af1577c..ff720b525 100644 --- a/deps/oblib/src/lib/list/ob_list.h +++ b/deps/oblib/src/lib/list/ob_list.h @@ -418,6 +418,7 @@ public: } T &get_first() { return root_.next->data; } + const T &get_first() const { return root_.next->data; } T &get_last() { return root_.prev->data; } OB_INLINE iterator begin() diff --git a/deps/oblib/src/lib/literals/ob_literals.h b/deps/oblib/src/lib/literals/ob_literals.h index 4e483a4cc..6e855cd1c 100644 --- a/deps/oblib/src/lib/literals/ob_literals.h +++ b/deps/oblib/src/lib/literals/ob_literals.h @@ -9,7 +9,11 @@ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ +#ifndef DEPS_OBLIB_SRC_LIB_LITERALS_OB_LITERALS_H +#define DEPS_OBLIB_SRC_LIB_LITERALS_OB_LITERALS_H +#include "lib/ob_define.h" +#include "lib/utility/ob_print_utils.h" namespace oceanbase { // Time literals define : 1us = 1 @@ -113,4 +117,84 @@ constexpr unsigned long long operator "" _TB(long double terabyte) { return terabyte * 1024_GB; } -}// oceanbase \ No newline at end of file + +struct ObSizeLiteralPrettyPrinter { + constexpr ObSizeLiteralPrettyPrinter(unsigned long long val) : val_(val) {} + int64_t to_string(char *buf, const int64_t len) const { + int64_t pos = 0; + if (val_ < 1_KB) { + databuff_printf(buf, len, pos, "%lld_B", val_); + } else if (val_ < 1_MB) { + if ((val_ % 1_KB) == 0) { + databuff_printf(buf, len, pos, "%lld_KB", val_ / 1_KB); + } else { + databuff_printf(buf, len, pos, "%.2f_KB", val_ * 1.0 / 1_KB); + } + } else if (val_ < 1_GB) { + if ((val_ % 1_MB) == 0) { + databuff_printf(buf, len, pos, "%lld_MB", val_ / 1_MB); + } else { + databuff_printf(buf, len, pos, "%.2f_MB", val_ * 1.0 / 1_MB); + } + } else if (val_ < 1_TB) { + if ((val_ % 1_GB) == 0) { + databuff_printf(buf, len, pos, "%lld_GB", val_ / 1_GB); + } else { + databuff_printf(buf, len, pos, "%.2f_GB", val_ * 1.0 / 1_GB); + } + } else { + if ((val_ % 1_TB) == 0) { + databuff_printf(buf, len, pos, "%lld_TB", val_ / 1_TB); + } else { + databuff_printf(buf, len, pos, "%.2f_TB", val_ * 1.0 / 1_TB); + } + } + return pos; + } + unsigned long long val_; +}; + +struct ObTimeLiteralPrettyPrinter { + constexpr ObTimeLiteralPrettyPrinter(unsigned long long val) : val_(val) {} + int64_t to_string(char *buf, const int64_t len) const { + int64_t pos = 0; + if (val_ < 1_ms) { + databuff_printf(buf, len, pos, "%lld_us", val_); + } else if (val_ < 1_s) { + if ((val_ % 1_s) == 0) { + databuff_printf(buf, len, pos, "%lld_ms", val_ / 1_s); + } else { + databuff_printf(buf, len, pos, "%.2f_ms", val_ * 1.0 / 1_s); + } + } else if (val_ < 1_min) { + if ((val_ % 1_s) == 0) { + databuff_printf(buf, len, pos, "%lld_s", val_ / 1_s); + } else { + databuff_printf(buf, len, pos, "%.2f_s", val_ * 1.0 / 1_s); + } + } else if (val_ < 1_hour) { + if ((val_ % 1_min) == 0) { + databuff_printf(buf, len, pos, "%lld_min", val_ / 1_min); + } else { + databuff_printf(buf, len, pos, "%.2f_min", val_ * 1.0 / 1_min); + } + } else if (val_ < 1_day) { + if ((val_ % 1_hour) == 0) { + databuff_printf(buf, len, pos, "%lld_hour", val_ / 1_hour); + } else { + databuff_printf(buf, len, pos, "%.2f_hour", val_ * 1.0 / 1_hour); + } + } else { + if ((val_ % 1_day) == 0) { + databuff_printf(buf, len, pos, "%lld_day", val_ / 1_day); + } else { + databuff_printf(buf, len, pos, "%.2f_day", val_ * 1.0 / 1_day); + } + } + return pos; + } + unsigned long long val_; +}; + +}// oceanbase +#endif \ No newline at end of file diff --git a/deps/oblib/src/lib/lock/ob_bucket_lock.cpp b/deps/oblib/src/lib/lock/ob_bucket_lock.cpp index ec1477d91..215c09453 100644 --- a/deps/oblib/src/lib/lock/ob_bucket_lock.cpp +++ b/deps/oblib/src/lib/lock/ob_bucket_lock.cpp @@ -147,7 +147,7 @@ int ObBucketLock::wrlock(const uint64_t bucket_idx, const int64_t abs_timeout_us int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; - COMMON_LOG(WARN, "The ObBucketLock has not been inited, ", K(ret)); + COMMON_LOG(WARN, "The ObBucketLock has not been inited, ", K(ret), K(lbt())); } else if(OB_UNLIKELY(bucket_idx >= bucket_cnt_)) { ret = OB_INVALID_ARGUMENT; COMMON_LOG(ERROR, "Invalid argument, ", K(bucket_idx), K_(bucket_cnt), K(ret)); diff --git a/deps/oblib/src/lib/ob_define.h b/deps/oblib/src/lib/ob_define.h index 713bd8b3b..fed194d27 100644 --- a/deps/oblib/src/lib/ob_define.h +++ b/deps/oblib/src/lib/ob_define.h @@ -617,6 +617,12 @@ const char *const OB_SERVER_ROLE_VAR_NAME = "__ob_server_role"; //trace id const char *const OB_TRACE_ID_VAR_NAME = "__ob_trace_id"; +//balance partition sharding +const char *const OB_PARTITION_SHARDING_NONE = "NONE"; +const char *const OB_PARTITION_SHARDING_PARTITION = "PARTITION"; +const char *const OB_PARTITION_SHARDING_ADAPTIVE = "ADAPTIVE"; + + // backup and restore const int64_t OB_MAX_CLUSTER_NAME_LENGTH = OB_MAX_APP_NAME_LENGTH; const int64_t OB_MAX_URI_LENGTH = 2048; @@ -802,6 +808,8 @@ const char *const OB_DDL_ID_VAR_NAME = "__oceanbase_ddl_id"; const int64_t OB_MAX_DDL_ID_STR_LENGTH = 64; const int64_t OB_MAX_DDL_SINGLE_REPLICA_BUILD_TIMEOUT = 7L * 24L * 60L * 60L * 1000L * 1000L; // 7days +const int64_t OB_MAX_PARTITION_SHARDING_LENGTH = 10; + // The default user name of the standby database to log in to the main database const char *const OB_STANDBY_USER_NAME = "__oceanbase_inner_standby_user"; @@ -2343,7 +2351,7 @@ OB_INLINE int64_t ob_gettid() OB_INLINE uint64_t& ob_get_tenant_id() { - thread_local uint64_t tenant_id = 0;; + thread_local uint64_t tenant_id = 0; return tenant_id; } diff --git a/deps/oblib/src/lib/oblog/ob_log.h b/deps/oblib/src/lib/oblog/ob_log.h index ce16e14f2..c67faf8fc 100644 --- a/deps/oblib/src/lib/oblog/ob_log.h +++ b/deps/oblib/src/lib/oblog/ob_log.h @@ -44,8 +44,8 @@ #include "lib/oblog/ob_syslog_rate_limiter.h" #include "lib/signal/ob_signal_handlers.h" -#define OB_LOG_MAX_PAR_MOD_SIZE 32 -#define OB_LOG_MAX_SUB_MOD_SIZE 32 +#define OB_LOG_MAX_PAR_MOD_SIZE 64 +#define OB_LOG_MAX_SUB_MOD_SIZE 64 namespace oceanbase { namespace lib { @@ -867,7 +867,7 @@ inline const ObLogIdLevelMap *ObThreadLogLevelUtils::get() inline int8_t ObThreadLogLevelUtils::get_level() { - return get_level_();; + return get_level_(); } inline const ObLogIdLevelMap*& ObThreadLogLevelUtils::get_id_level_map_() diff --git a/deps/oblib/src/lib/oblog/ob_log_module.h b/deps/oblib/src/lib/oblog/ob_log_module.h index f92a4def3..b788915c9 100644 --- a/deps/oblib/src/lib/oblog/ob_log_module.h +++ b/deps/oblib/src/lib/oblog/ob_log_module.h @@ -70,6 +70,9 @@ DEFINE_LOG_SUB_MOD(STANDBY) // primary and standby cluster DEFINE_LOG_SUB_MOD(REASY) // libreasy DEFINE_LOG_SUB_MOD(COORDINATOR) // leader coordinator DEFINE_LOG_SUB_MOD(FLT) // trace +DEFINE_LOG_SUB_MOD(OBTRACE) // trace +DEFINE_LOG_SUB_MOD(BALANCE) // balance module +DEFINE_LOG_SUB_MOD(MDS) // multi data source DEFINE_LOG_SUB_MOD(DATA_DICT) // data_dictionary module DEFINE_LOG_SUB_MOD(MVCC) // concurrency_control LOG_MOD_END(ROOT) @@ -197,6 +200,11 @@ DEFINE_LOG_SUB_MOD(LB) // load balance DEFINE_LOG_SUB_MOD(RESTORE) // restore related LOG_MOD_END(RS) +// Balance submodules +LOG_MOD_BEGIN(BALANCE) +DEFINE_LOG_SUB_MOD(TRANSFER) // transfer service +LOG_MOD_END(BALANCE) + // liboblog submodules LOG_MOD_BEGIN(TLOG) DEFINE_LOG_SUB_MOD(FETCHER) // fetcher @@ -449,6 +457,12 @@ LOG_MOD_END(PL) #define _COORDINATOR_LOG(level, _fmt_, args...) _OB_MOD_LOG(COORDINATOR, level, _fmt_, ##args) #define FLT_LOG(level, info_string, args...) OB_MOD_LOG(FLT, level, info_string, ##args) #define _FLT_LOG(level, _fmt_, args...) _OB_MOD_LOG(FLT, level, _fmt_, ##args) +#define OBTRACE_LOG(level, info_string, args...) OB_MOD_LOG(OBTRACE, level, info_string, ##args) +#define _OBTRACE_LOG(level, _fmt_, args...) _OB_MOD_LOG(OBTRACE, level, _fmt_, ##args) +#define BALANCE_LOG(level, info_string, args...) OB_MOD_LOG(BALANCE, level, info_string, ##args) +#define _BALANCE_LOG(level, _fmt_, args...) _OB_MOD_LOG(BALANCE, level, _fmt_, ##args) +#define MDS_LOG(level, info_string, args...) OB_MOD_LOG(MDS, level, info_string, ##args) +#define _MDS_LOG(level, _fmt_, args...) _OB_MOD_LOG(MDS, level, _fmt_, ##args) #define DDLOG(level, info_string, args...) OB_MOD_LOG(DATA_DICT, level, info_string, ##args) #define _DDLOG(level, _fmt_, args...) _OB_MOD_LOG(DATA_DICT, level, _fmt_, ##args) #define MVCC_LOG(level, info_string, args...) OB_MOD_LOG(MVCC, level, info_string, ##args) @@ -814,6 +828,12 @@ LOG_MOD_END(PL) #define _STORAGETEST_LOG(level, info_string, args...) _OB_SUB_MOD_LOG(STORAGETEST, TEST, level, \ info_string, ##args) +// balance submodule definitions +#define BALANCE_TRANSFER_LOG(level, info_string, args...) \ + OB_SUB_MOD_LOG(BALANCE, TRANSFER, level, info_string, ##args) +#define _BALANCE_TRANSFER_LOG(level, info_string, args...) \ + _OB_SUB_MOD_LOG(BALANCE, TRANSFER, level, info_string, ##args) + // liboblog submod definition #define OBLOG_FETCHER_LOG(level, fmt, args...) OB_SUB_MOD_LOG(TLOG, FETCHER, level, fmt, ##args) #define _OBLOG_FETCHER_LOG(level, fmt, args...) _OB_SUB_MOD_LOG(TLOG, FETCHER, level, fmt, ##args) @@ -1123,10 +1143,12 @@ LOG_MOD_END(PL) #define _OBLOG_DISPATCHER_LOG_RET(level, errcode, args...) { int ret = errcode; _OBLOG_DISPATCHER_LOG(level, ##args); } #define OBLOG_SORTER_LOG_RET(level, errcode, args...) { int ret = errcode; OBLOG_SORTER_LOG(level, ##args); } #define _OBLOG_SORTER_LOG_RET(level, errcode, args...) { int ret = errcode; _OBLOG_SORTER_LOG(level, ##args); } -// END XXX_LOG_RET MACRO DEFINE - +#define MDS_LOG_RET(level, errcode, args...) { int ret = errcode; MDS_LOG(level, ##args); } +#define _MDS_LOG_RET(level, errcode, args...) { int ret = errcode; _MDS_LOG(level, ##args); } #define DDLOG_RET(level, errcode, args...){ int ret = errcode; DDLOG(level, ##args); } +#define _DDLOG_RET(level, errcode, args...){ int ret = errcode; _DDLOG(level, ##args); } +// END XXX_LOG_RET MACRO DEFINE // used for the log return for user; diff --git a/deps/oblib/src/lib/oblog/ob_log_module.ipp b/deps/oblib/src/lib/oblog/ob_log_module.ipp index 89e63cd44..ee0485c8c 100644 --- a/deps/oblib/src/lib/oblog/ob_log_module.ipp +++ b/deps/oblib/src/lib/oblog/ob_log_module.ipp @@ -52,6 +52,7 @@ REG_LOG_PAR_MOD(PALF) REG_LOG_PAR_MOD(ARCHIVE) REG_LOG_PAR_MOD(LOGTOOL) REG_LOG_PAR_MOD(DATA_DICT) +REG_LOG_PAR_MOD(BALANCE) //regist WRS's sub-modules REG_LOG_SUB_MOD(WRS, CLUSTER) @@ -163,5 +164,9 @@ REG_LOG_SUB_MOD(TLOG, STORAGER) REG_LOG_SUB_MOD(TLOG, READER) REG_LOG_SUB_MOD(TLOG, DISPATCHER) REG_LOG_SUB_MOD(TLOG, SORTER) + +// regist balance.transfer +REG_LOG_SUB_MOD(BALANCE, TRANSFER) + } } diff --git a/deps/oblib/src/lib/statistic_event/ob_stat_event.h b/deps/oblib/src/lib/statistic_event/ob_stat_event.h index 627b40229..4665ed2f4 100644 --- a/deps/oblib/src/lib/statistic_event/ob_stat_event.h +++ b/deps/oblib/src/lib/statistic_event/ob_stat_event.h @@ -199,6 +199,10 @@ STAT_EVENT_ADD_DEF(SECONDARY_META_CACHE_HIT, "secondary meta cache hit", ObStatC STAT_EVENT_ADD_DEF(SECONDARY_META_CACHE_MISS, "secondary meta cache miss", ObStatClassIds::CACHE, "secondary meta cache miss", 50054, false, true) STAT_EVENT_ADD_DEF(OPT_DS_STAT_CACHE_HIT, "opt ds stat cache hit", ObStatClassIds::CACHE, "opt ds stat cache hit", 50055, false, true) STAT_EVENT_ADD_DEF(OPT_DS_STAT_CACHE_MISS, "opt ds stat cache miss", ObStatClassIds::CACHE, "opt ds stat cache miss", 50056, false, true) +STAT_EVENT_ADD_DEF(STORAGE_META_CACHE_HIT, "storage meta cache hit", ObStatClassIds::CACHE, "storage meta cache hit", 50057, true, true) +STAT_EVENT_ADD_DEF(STORAGE_META_CACHE_MISS, "storage meta cache miss", ObStatClassIds::CACHE, "storage meta cache miss", 50058, true, true) +STAT_EVENT_ADD_DEF(TABLET_CACHE_HIT, "tablet cache hit", ObStatClassIds::CACHE, "tablet cache hit", 50059, true, true) +STAT_EVENT_ADD_DEF(TABLET_CACHE_MISS, "tablet cache miss", ObStatClassIds::CACHE, "tablet cache miss", 50060, true, true) // STORAGE //STAT_EVENT_ADD_DEF(MEMSTORE_LOGICAL_READS, "MEMSTORE_LOGICAL_READS", STORAGE, "MEMSTORE_LOGICAL_READS") diff --git a/deps/oblib/src/lib/string/ob_string.h b/deps/oblib/src/lib/string/ob_string.h index 66e999ced..6c9c4864f 100644 --- a/deps/oblib/src/lib/string/ob_string.h +++ b/deps/oblib/src/lib/string/ob_string.h @@ -170,7 +170,7 @@ public: * DO NOT USE THIS ANY MORE */ - inline void assign(char *bytes, const int64_t length) //TODO(yongle.xh): for -Wshorten-64-to-32, delete it later + inline void assign(char *bytes, const int64_t length) //TODO(yongle.xh): for -Wshorten-64-to-32, delete it later 4.3 { if (length > INT32_MAX) { LIB_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "invalid length for assign", K(length)); @@ -207,7 +207,7 @@ public: } } - inline void assign_ptr(const char *bytes, const int64_t length) //TODO(yongle.xh): for -Wshorten-64-to-32, delete it later + inline void assign_ptr(const char *bytes, const int64_t length) //TODO(yongle.xh): for -Wshorten-64-to-32, delete it later 4.3 { if (length < 0 || length > INT32_MAX) { LIB_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "invalid length for assign ptr", K(length)); @@ -215,7 +215,7 @@ public: assign_ptr(bytes, static_cast(length)); } - inline void assign_ptr(const char *bytes, const uint64_t length) //TODO(yongle.xh): for -Wshorten-64-to-32, delete it later + inline void assign_ptr(const char *bytes, const uint64_t length) //TODO(yongle.xh): for -Wshorten-64-to-32, delete it later 4.3 { if (length < 0 || length > INT32_MAX) { LIB_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "invalid length for assign ptr", K(length)); @@ -223,7 +223,7 @@ public: assign_ptr(bytes, static_cast(length)); } - inline void assign_ptr(const char *bytes, const uint32_t length) //TODO(yongle.xh): for -Wshorten-64-to-32, delete it later + inline void assign_ptr(const char *bytes, const uint32_t length) //TODO(yongle.xh): for -Wshorten-64-to-32, delete it later 4.3 { if (length > INT32_MAX) { LIB_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "invalid length for assign ptr", K(length)); diff --git a/deps/oblib/src/lib/task/ob_timer.cpp b/deps/oblib/src/lib/task/ob_timer.cpp index d66cb0ce6..6e247bab3 100644 --- a/deps/oblib/src/lib/task/ob_timer.cpp +++ b/deps/oblib/src/lib/task/ob_timer.cpp @@ -16,6 +16,7 @@ #include "lib/thread/ob_thread_name.h" #include "lib/string/ob_string.h" #include "lib/stat/ob_diagnose_info.h" +#include "common/ob_clock_generator.h" namespace oceanbase { diff --git a/deps/oblib/src/lib/utility/ob_tracepoint.h b/deps/oblib/src/lib/utility/ob_tracepoint.h index ddcfefb99..32b0d636b 100644 --- a/deps/oblib/src/lib/utility/ob_tracepoint.h +++ b/deps/oblib/src/lib/utility/ob_tracepoint.h @@ -507,8 +507,8 @@ class EventTable EN_INVALID_ADDR_WEAK_READ_FAILED = 215, EN_STACK_OVERFLOW_CHECK_EXPR_STACK_SIZE = 216, EN_ENABLE_PDML_ALL_FEATURE = 217, - // OFS错误模拟占坑 218-230 - EN_OFS_SLOG_WRITE = 218, + // slog checkpoint错误模拟占坑 218-230 + EN_SLOG_CKPT_ERROR = 218, EN_FAST_RECOVERY_AFTER_ALLOC_FILE = 219, EN_FAST_MIGRATE_ADD_MEMBER_FAIL = 220, EN_FAST_RECOVERY_BEFORE_ADD_MEMBER = 221, @@ -677,6 +677,8 @@ class EventTable EN_TABLET_GC_TASK_FAILED = 918, EN_UPDATE_TABLET_HA_STATUS_FAILED = 919, EN_GENERATE_REBUILD_TASK_FAILED = 920, + EN_CHECK_TRANSFER_TASK_EXSIT = 921, + EN_TABLET_EMPTY_SHELL_TASK_FAILED = 922, // Log Archive and Restore 1001 - 1100 EN_START_ARCHIVE_LOG_GAP = 1001, @@ -699,6 +701,7 @@ class EventTable EN_BACKUP_PERSIST_SET_TASK_FAILED = 1110, EN_BACKUP_READ_MACRO_BLOCK_FAILED = 1111, EN_FETCH_TABLE_INFO_RPC = 1112, + EN_RESTORE_TABLET_TASK_FAILED = 1113, // END OF STORAGE HA - 1101 - 2000 // sql parameterization 1170-1180 diff --git a/deps/oblib/src/lib/wait_event/ob_wait_event.h b/deps/oblib/src/lib/wait_event/ob_wait_event.h index 7bb017460..83821953c 100644 --- a/deps/oblib/src/lib/wait_event/ob_wait_event.h +++ b/deps/oblib/src/lib/wait_event/ob_wait_event.h @@ -290,9 +290,9 @@ WAIT_EVENT_DEF(TENANT_MEM_USAGE_LOCK_WAIT, 15244, "latch: tenant memory usage lo WAIT_EVENT_DEF(TX_TABLE_LOCK_WAIT, 15245, "rwlock: tx table lock wait", "address", "number", "tries", CONCURRENCY, "rwlock: tx table lock wait", true) WAIT_EVENT_DEF(MEMTABLE_STAT_LOCK_WAIT, 15246, "spinlock: memtable stat lock wait", "address", "number", "tries", CONCURRENCY, "spinlock: memtable stat lock wait", true) WAIT_EVENT_DEF(DEADLOCK_DETECT_LOCK_WAIT, 15247, "spinlock: deadlock detect lock wait", "address", "number", "tries", CONCURRENCY, "spinlock: deadlock detect lock wait", true) -//WAIT_EVENT_DEF(BACKUP_DATA_SERVICE_COND_WAIT, 15248, "backup data service condition wait", "address", "", "", CONCURRENCY, "backup data service condition wait", true) used by backup -//WAIT_EVENT_DEF(BACKUP_CLEAN_SERVICE_COND_WAIT, 15249, "backup clean service condition wait", "address", "", "", CONCURRENCY, "backup clean service condition wait", true) -//WAIT_EVENT_DEF(BACKUP_ARCHIVE_SERVICE_COND_WAIT, 15250, "backup archive service condition wait", "address", "", "", CONCURRENCY, "backup archive service condition wait", true) +WAIT_EVENT_DEF(BACKUP_DATA_SERVICE_COND_WAIT, 15248, "backup data service condition wait", "address", "", "", CONCURRENCY, "backup data service condition wait", true) +WAIT_EVENT_DEF(BACKUP_CLEAN_SERVICE_COND_WAIT, 15249, "backup clean service condition wait", "address", "", "", CONCURRENCY, "backup clean service condition wait", true) +WAIT_EVENT_DEF(BACKUP_ARCHIVE_SERVICE_COND_WAIT, 15250, "backup archive service condition wait", "address", "", "", CONCURRENCY, "backup archive service condition wait", true) WAIT_EVENT_DEF(SRS_LOCK_WAIT, 15251, "latch: srs lock wait", "address", "number", "tries", CONCURRENCY, "latch: srs lock wait", true) WAIT_EVENT_DEF(ARB_SERVER_CONFIG_WAIT, 15252, "arbserver config wait", "address", "number", "tries", CONCURRENCY, "arbserver config wait", true) WAIT_EVENT_DEF(CLOG_CKPT_RWLOCK_WAIT, 15253, "rwlock: clog checkpoint rwlock wait", "address", "number", "tries", CONCURRENCY, "rwlock: clog checkpoint rwlock wait", true) @@ -412,6 +412,7 @@ WAIT_EVENT_DEF(DTL_DESTROY_CHANNEL_SLEEP, 20002, "sleep: dtl destroy channel sle WAIT_EVENT_DEF(STORAGE_WRITING_THROTTLE_SLEEP, 20003, "sleep: storage writing throttle sleep", "sleep_interval", "", "", CONCURRENCY, "sleep: storage writing throttle sleep", true) WAIT_EVENT_DEF(STORAGE_AUTOINC_FETCH_RETRY_SLEEP, 20004, "sleep: tablet autoinc fetch new range retry wait", "sleep_interval", "", "", CONCURRENCY, "sleep: tablet autoinc fetch new range retry wait", true) WAIT_EVENT_DEF(STORAGE_AUTOINC_FETCH_CONFLICT_SLEEP, 20005, "sleep: tablet autoinc fetch new range conflict wait", "sleep_interval", "", "", CONCURRENCY, "sleep: tablet autoinc fetch new range conflict wait", true) +WAIT_EVENT_DEF(STORAGE_HA_FINISH_TRANSFER, 20006, "sleep: finish transfer sleep wait", "sleep_interval", "", "", CONCURRENCY, "sleep: finish transfer sleep wait", true) WAIT_EVENT_DEF(WAIT_EVENT_END, 99999, "event end", "", "", "", OTHER, "event end", false) #endif diff --git a/deps/oblib/src/rpc/obmysql/ob_sql_nio.cpp b/deps/oblib/src/rpc/obmysql/ob_sql_nio.cpp index f882f4a5d..48cf3550f 100644 --- a/deps/oblib/src/rpc/obmysql/ob_sql_nio.cpp +++ b/deps/oblib/src/rpc/obmysql/ob_sql_nio.cpp @@ -30,6 +30,7 @@ #include #include #include "rpc/obrpc/ob_listener.h" +#include "common/ob_clock_generator.h" using namespace oceanbase::common; diff --git a/deps/oblib/src/rpc/obrpc/ob_rpc_packet_list.h b/deps/oblib/src/rpc/obrpc/ob_rpc_packet_list.h index ddc52a901..7c5f6f7f4 100644 --- a/deps/oblib/src/rpc/obrpc/ob_rpc_packet_list.h +++ b/deps/oblib/src/rpc/obrpc/ob_rpc_packet_list.h @@ -456,21 +456,22 @@ PCODE_DEF(OB_HA_FETCH_SSTABLE_MACRO_INFO, 0x4A4) PCODE_DEF(OB_HA_FETCH_LS_MEMBER_LIST, 0x4A5) PCODE_DEF(OB_HA_FETCH_LS_META_INFO, 0x4A6) PCODE_DEF(OB_NOTIFY_CREATE_TENANT_USER_LS, 0x4A7) - PCODE_DEF(OB_INIT_TENANT_CONFIG, 0x4A8) PCODE_DEF(OB_GET_LEADER_LOCATIONS, 0x4A9) - -PCODE_DEF(OB_CHECK_SRC_TRANSFER_TABLETS, 0x4AA) +PCODE_DEF(OB_CHECK_START_TRANSFER_TABLETS, 0x4AA) PCODE_DEF(OB_GET_LS_ACTIVE_TRANSACTION_COUNT, 0x4AB) PCODE_DEF(OB_GET_TRANSFER_START_SCN, 0x4AC) PCODE_DEF(OB_FETCH_TRANSFER_TABLET_INFO, 0x4AD) PCODE_DEF(OB_HA_FETCH_LS_REPLAY_SCN, 0x4AE) PCODE_DEF(OB_HA_CHECK_TRANSFER_TABLET_BACKFILL, 0x4AF) - PCODE_DEF(OB_HA_REPLACE_MEMBER, 0x4B0) PCODE_DEF(OB_HA_ADD_MEMBER, 0x4B1) PCODE_DEF(OB_NOTIFY_CREATE_DUPLICATE_LS, 0x4B2) PCODE_DEF(OB_HA_FETCH_LS_VIEW, 0x4B3) +PCODE_DEF(OB_HA_BLOCK_TX, 0x4B4) +PCODE_DEF(OB_HA_KILL_TX, 0x4B5) +PCODE_DEF(OB_HA_UNBLOCK_TX, 0x4B6) +PCODE_DEF(OB_HA_SWITCH_LEARNER_TO_ACCEPTOR, 0x4B7) // sql, including executor @@ -547,6 +548,7 @@ PCODE_DEF(OB_RS_ACCEPT_PLAN_BASELINE, 0x579) PCODE_DEF(OB_SERVER_CANCEL_EVOLVE_TASK, 0x57A) PCODE_DEF(OB_RS_CANCEL_EVOLVE_TASK, 0x57B) +// for tansfer PCODE_DEF(OB_START_TRANSFER_TASK, 0x57C) PCODE_DEF(OB_FINISH_TRANSFER_TASK, 0x57D) @@ -886,7 +888,7 @@ PCODE_DEF(OB_DELETE_BACKUP_LS_TASK, 0x1421) PCODE_DEF(OB_DELETE_BACKUP_LS_TASK_RES, 0x1422) PCODE_DEF(OB_CHECK_BACKUP_DEST_CONNECTIVITY, 0x1423) PCODE_DEF(OB_BACKUP_META, 0x1424) -PCODE_DEF(OB_BACKUP_CHECK_TABLET_CREATE_TS, 0x1425) +//PCODE_DEF(OB_BACKUP_CHECK_TABLET_CREATE_TS, 0x1425) not used anymore PCODE_DEF(OB_DELETE_POLICY, 0x1426) // 0x1427 for OB_RECOVER_TABLE // 0x1428 for OB_BACKUP_ADVANCE_CHECKPOINT diff --git a/hotfuncs.txt b/hotfuncs.txt index 4dfeda9ab..1a29ac173 100644 --- a/hotfuncs.txt +++ b/hotfuncs.txt @@ -1,2945 +1,3497 @@ +_ZTWN9oceanbase3lib6Thread8loop_ts_E +_ZTWN9oceanbase6common7ObLatch17max_lock_slot_idxE _ZN9oceanbase3sql12ObSortOpImpl12ObAdaptiveQS29inplace_radixsort_more_bucketEllllllb _ZN9oceanbase3sql12ObSortOpImpl12ObAdaptiveQS10aqs_cps_qsElllll -_ZN9oceanbase3sql12ObSortOpImpl12ObAdaptiveQS12compare_valsEllRlll _ZN9oceanbase3sql17fast_compare_simdEPKhS2_lRll -_ZN9oceanbase3sql12ObSortOpImpl12ObAdaptiveQS9aqs_radixElllll -_ZTWN9oceanbase6common7ObLatch13current_locksE -_ZTWN9oceanbase3lib17ContextTLOptGuard13enable_tl_optE _ZTWN9oceanbase8memtable33TLOCAL_NEED_WAIT_IN_LOCK_WAIT_MGRE _ZN9oceanbase3omt10ObThWorker6workerERlS2_Ri +_ZNK9oceanbase3omt8ObTenant15get_compat_modeEv +_ZTWN9oceanbase3lib6Thread12is_blocking_E +_ZTWN9oceanbase3lib17ContextTLOptGuard13enable_tl_optE _ZN9oceanbase6common13ObTimeUtility12current_timeEv -_ZN9oceanbase6common17ObSessionDIBuffer13switch_tenantEm -_ZN9oceanbase6common16ObPriorityQueue2ILi1ELi2ELi3EE6do_popERPNS0_6ObLinkEll -_ZN9oceanbase6common13ObSpLinkQueue3popERPNS0_6ObLinkE -_ZN9oceanbase6common9SCondTempILi3EE7prepareEi -_ZN9oceanbase5share2_SILNS0_12ObEntityTypeE1ELNS0_12EntitySourceE2EED2Ev +_ZN9oceanbase6common12TCRLockGuardC2ERKNS0_8TCRWLockE _ZTWN9oceanbase6common11in_try_stmtE -_ZN9oceanbase3lib11DynamicInfoC2Ev -_ZN9oceanbase3lib2_SILNS0_13ContextSourceE1EED2Ev -_ZN9oceanbase6common16ObWaitEventGuardD1Ev -_ZN9oceanbase6common16ObWaitEventGuardD2Ev -_ZN9oceanbase3lib17__MemoryContext__15destory_contextEPS1_ -_ZN9oceanbase3lib18SetDoNothingLocker4lockEv -_ZN9oceanbase3lib18SetDoNothingLocker6unlockEv +_ZN9oceanbase6common20ObTenantStatEstGuardD2Ev +_ZN9oceanbase6common7ObDITlsINS0_17ObSessionDIBufferELm0EE12get_instanceEv +_ZN9oceanbase6common17ObSessionDIBuffer13switch_tenantEm +_ZN9oceanbase6common13ObPageManager14set_tenant_ctxEll +_ZN9oceanbase3omt8ObTenant18check_worker_countERNS0_10ObThWorkerE +_ZN9oceanbase5share11ObTenantEnv3mtlIPNS_8memtable13ObLockWaitMgrEEET_v _ZN9oceanbase3lib2_SILNS0_13ContextSourceE1EEC2IJNS0_11DynamicInfoERNS0_12ContextParamEPNS0_10StaticInfoEEEEbDpOT_ -_ZN9oceanbase3lib17__MemoryContext__14create_contextIJRNS0_12ContextParamERPNS0_10StaticInfoEEEEiRNS0_13MemoryContextERS1_RKNS0_11DynamicInfoEDpOT_ -_ZN9oceanbase3lib17__MemoryContext__4initEv -_ZN9oceanbase3lib17__MemoryContext__10init_allocERNS_6common11ObAllocatorEbj +_ZN9oceanbase3omt8ObTenant15get_new_requestERNS0_10ObThWorkerElRPNS_3rpc9ObRequestE +_ZN9oceanbase6common16ObPriorityQueue2ILi1ELi2ELi3EE6do_popERPNS0_6ObLinkEll +_ZN9oceanbase5share2_SILNS0_12ObEntityTypeE0ELNS0_12EntitySourceE0EED2Ev +_ZN9oceanbase6common16ObWaitEventGuardC1Elmlllb +_ZN9oceanbase6common16ObWaitEventGuardC2Elmlllb +_ZN9oceanbase3lib17__MemoryContext__15destory_contextEPS1_ _ZN9oceanbase3lib9ObjectSet11free_objectEPNS0_7AObjectE _ZN9oceanbase3lib8BlockSet10free_blockEPNS0_6ABlockE -_ZN9oceanbase6common11ObAllocatorUt_10free_blockEPNS_3lib6ABlockE +_ZN9oceanbase6common16ObWaitEventGuardD1Ev +_ZN9oceanbase6common16ObWaitEventGuardD2Ev +_ZN9oceanbase5share13ObTenantSpace4rootEv _ZN9oceanbase3omt17ObWorkerProcessor7processERNS_3rpc9ObRequestE -_ZN9oceanbase3rpc5frame14ObReqProcessor7destroyEv -_ZN9oceanbase6common14ObServerConfig12get_instanceEv -_ZN9oceanbase3rpc5frame14ObSqlProcessor3runEv _ZNK9oceanbase3omt10ObThWorker10need_retryEv -_ZN9oceanbase5trace16__ObFLTSpanGuardD2Ev -_ZN9oceanbase5trace7ObTrace8end_spanEPNS0_9ObSpanCtxE -_ZN9oceanbase5trace7ObTrace12get_instanceEv +_ZN9oceanbase3rpc5frame14ObReqProcessor7destroyEv _ZN9oceanbase8observer8ObMPBase12flush_bufferEb -_ZN9oceanbase6common13ObSEArrayImplINS0_8ObStringELl1ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase8observer14global_contextEv +_ZTW12co_closepbuf +_ZN9oceanbase8observer8ObMPBase14before_processEv +_ZN9oceanbase3lib15CompatModeGuardD2Ev +_ZN9oceanbase8observer8ObMPBase19setup_packet_senderEv +_ZN9oceanbase8observer16ObMPPacketSender7do_initEPNS_3rpc9ObRequestEhbbl +_ZN9oceanbase3lib11ObLockGuardINS_6common16ObRecursiveMutexEED2Ev +_ZN9oceanbase8observer8ObMPBase8responseEi +_ZN9oceanbase6common12ObCurTraceId7TraceId3setERKS2_ +_ZN9oceanbase8observer11ObSrvXlator7releaseEPNS_3rpc5frame14ObReqProcessorE +_ZN9oceanbase8observer9ObMPQueryD2Ev +_ZN9oceanbase8observer8ObMPBase13after_processEi _ZN9oceanbase8observer9ObMPQuery7processEv -_ZN9oceanbase5trace7ObTrace10begin_spanEjhb -_ZN9oceanbase6common14ObTscTimestamp12get_instanceEv -_ZN9oceanbase3sql16ObSQLSessionInfo22post_sync_session_infoEv -_ZN9oceanbase6common10EventTable8instanceEv -_ZN9oceanbase6common13ObSEArrayImplINS0_8ObStringELl1ENS0_19ModulePageAllocatorELb0EE9push_backERKS2_ -_ZN9oceanbase3sql10ObFLTUtils13init_flt_infoENS_7obmysql13Ob20ExtraInfoERNS0_16ObSQLSessionInfoEb -_ZN9oceanbase6common16ObFixedArrayImplINS_3sql18ObDupTabConstraintENS0_12ObIAllocatorEE7destroyEv -_ZN9oceanbase7obmysql23ObPocSqlRequestOperator18finish_sql_requestEPNS_3rpc9ObRequestE -_ZN9oceanbase7obmysql16ObSqlSockSession11revert_sockEv -_ZN9oceanbase7obmysql12ObSqlNioImpl11revert_sockEPNS0_9ObSqlSockE -_ZN9oceanbase3sql16ObSQLSessionInfo24ObCachedTenantConfigInfo7refreshEv -_ZNK9oceanbase8observer8ObMPBase16record_flt_traceERNS_3sql16ObSQLSessionInfoE -_ZZN9oceanbase3sql10ObFLTUtils22init_flt_log_frameworkERNS0_16ObSQLSessionInfoEbENK5$_536clEPKc -_ZN9oceanbase8observer16ObMPPacketSender14revert_sessionEPNS_3sql16ObSQLSessionInfoE -_ZNK9oceanbase3sql11ObResultSet23need_end_trans_callbackEv -_ZN9oceanbase3sql10ObFLTUtils22init_flt_log_frameworkERNS0_16ObSQLSessionInfoEb -_ZN9oceanbase5trace7ObTrace10reset_spanEv -_ZN9oceanbase11transaction8ObTxDesc20in_tx_for_free_routeEv -_ZN9oceanbase6common10to_cstringINS0_12ObCurTraceId7TraceIdEEEPKcRKT_NS0_8BoolTypeILb0EEE -_ZN9oceanbase3sql8ObParser19split_multiple_stmtERKNS_6common8ObStringERNS2_8ObIArrayIS3_EERNS0_13ObMPParseStatEbb -_ZN9oceanbase3sql18ObBasicSessionInfo21gen_configs_in_pc_strEv -_ZN9oceanbase6common15databuff_printfEPclRlPKcz -_ZN9oceanbase3sql10ObFLTUtils13clean_flt_envERNS0_16ObSQLSessionInfoE -_ZN9oceanbase8observer9ObMPQuery19process_single_stmtERKNS_3sql15ObMultiStmtItemERNS2_16ObSQLSessionInfoEbbRbS8_ _ZTWN9oceanbase6common16g_warning_bufferE -_ZN9oceanbase6common16ObClockGenerator8getClockEv -_ZN9oceanbase3sql17ObAuditRecordData24update_event_stage_stateEv -_ZN9oceanbase3sql12ObExecRecord12record_startEPNS_6common21ObDiagnoseSessionInfoE +_ZN9oceanbase6common7ObLatch6wrlockEjlPKj +_ZN9oceanbase5trace7ObTrace10begin_spanEjhb +_ZNK9oceanbase5share6schema27ObMultiVersionSchemaService37get_tenant_received_broadcast_versionEmRlb +_ZN9oceanbase6common13ObSEArrayImplINS0_8ObStringELl1ENS0_19ModulePageAllocatorELb0EE9push_backERKS2_ +_ZN9oceanbase6common13ObSEArrayImplINS0_8ObStringELl1ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase3sql16ObSQLSessionInfo22post_sync_session_infoEv +_ZN9oceanbase3sql8ObParser19split_multiple_stmtERKNS_6common8ObStringERNS2_8ObIArrayIS3_EERNS0_13ObMPParseStatEbb +_ZZN9oceanbase3sql10ObFLTUtils22init_flt_log_frameworkERNS0_16ObSQLSessionInfoEbENK5$_536clEPKc.llvm.2295368030602757402 +_ZN9oceanbase3sql10ObFLTUtils22init_flt_log_frameworkERNS0_16ObSQLSessionInfoEb +_ZN9oceanbase11transaction8ObTxDesc20in_tx_for_free_routeEv +_ZNK9oceanbase8observer8ObMPBase16record_flt_traceERNS_3sql16ObSQLSessionInfoE +_ZN9oceanbase8observer16ObMPPacketSender14revert_sessionEPNS_3sql16ObSQLSessionInfoE +_ZN9oceanbase8observer9ObMPQuery19process_single_stmtERKNS_3sql15ObMultiStmtItemERNS2_16ObSQLSessionInfoEbbRbS8_ +_ZN9oceanbase6common7ObLatch6unlockEPKj +_ZN9oceanbase3sql21ObPartIdRowMapManagerC2Ev +_ZNK9oceanbase6common13ObSEArrayImplINS_5share6schema15ObSchemaMgrInfoELl2ENS0_19ModulePageAllocatorELb0EEixEl _ZN9oceanbase3sql16ObSQLSessionInfo22get_final_audit_recordENS0_13ObExecuteModeE -_ZN9oceanbase8observer13ObReqTimeInfo15update_end_timeEv -_ZN9oceanbase8observer13ObReqTimeInfo25get_thread_local_instanceEv -_ZN9oceanbase3sql12ObExecRecord11update_statEv +_ZN9oceanbase3sql8ObDASCtxC2ERNS_6common12ObIAllocatorE +_ZN9oceanbase6common4hash9ObHashMapINS0_6ObAddrElNS1_24LatchReadWriteDefendModeENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairIS3_lEEEELi89ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_13NormalPointerENS0_8ObMallocELl1EEC2Ev +_ZN9oceanbase3sql17ObTaskExecutorCtxC1ERNS0_13ObExecContextE _ZN9oceanbase3sql11ObResultSetD1Ev _ZN9oceanbase3sql11ObResultSetD2Ev -_ZN9oceanbase6common16ObArenaAllocator4freeEPv -_ZN9oceanbase3sql9ObOpInputD2Ev -_ZN9oceanbase6common11ObArrayImplIPKNS0_8ObIArrayIlEENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS5_EENS0_22NotImplementItemEncodeIS5_EEED2Ev -_ZN9oceanbase6common11ObArrayImplINS_3sql19ObJoinFilterDataCtxENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev -_ZN9oceanbase6common10ObObjStoreIPNS_3sql12ObIDASTaskOpERNS0_12ObIAllocatorELb0EED2Ev -_ZN9oceanbase3sql15ObCacheObjGuard19force_early_releaseEPNS0_11ObPlanCacheE -_ZN9oceanbase6common17ObSessionDIBuffer14switch_sessionEmb _ZN9oceanbase6common11ObArrayImplINS_3sql18ObExecFeedbackNodeENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev -_ZN9oceanbase8observer9ObMPQuery25store_params_value_to_strERNS_6common12ObIAllocatorERNS_3sql16ObSQLSessionInfoERNS2_9Ob2DArrayINS2_10ObObjParamELi2079744ENS2_18ObWrapperAllocatorELb0ENS2_9ObSEArrayIPS9_Ll1ESA_Lb0EEEEE -_ZN9oceanbase3sql8ObDASCtxC2ERNS_6common12ObIAllocatorE -_ZN9oceanbase3sql16ObDASTaskFactoryC1ERNS_6common12ObIAllocatorE -_ZN9oceanbase3sql16ObDASTaskFactoryC2ERNS_6common12ObIAllocatorE -_ZN9oceanbase3sql10ObSQLUtils19record_execute_timeENS0_13ObPhyPlanTypeEl -_ZN9oceanbase7obmysql21ObMySQLRequestManager14record_requestERKNS_3sql17ObAuditRecordDataEbb -_ZN9oceanbase6common13ObVSliceAlloc5allocEl -_ZN9oceanbase3sql5ObSql10stmt_queryERKNS_6common8ObStringERNS0_8ObSqlCtxERNS0_11ObResultSetE -OPENSSL_cleanse -_ZN9oceanbase5trace7ObTrace10append_tagINS_6common8ObStringELb1EEEb9ObTagTypeRKT_ -_ZN9oceanbase3sql17ObPhysicalPlanCtxC1ERNS_6common12ObIAllocatorE -_ZN9oceanbase3sql17ObPhysicalPlanCtxC2ERNS_6common12ObIAllocatorE -_ZN9oceanbase3sql5ObSql18handle_large_queryEiRNS0_11ObResultSetERbRNS0_13ObExecContextE -_ZN9oceanbase3sql10ObPlanStat17update_cache_statERKNS0_15ObTableScanStatE +_ZN9oceanbase6common13ObSEArrayImplINS_3sql18ObPhyTableLocationELl2ENS0_19ModulePageAllocatorELb0EED2Ev _ZN9oceanbase3sql17ObExprOperatorCtxD2Ev -_ZN9oceanbase3sql14ObPlanCacheCtxD2Ev -_ZN9oceanbase3sql18ObBasicSessionInfo18set_session_activeERKNS_6common8ObStringEllNS_7obmysql10ObMySQLCmdE -_ZZN9oceanbase3sql10ObFLTUtils22init_flt_log_frameworkERNS0_16ObSQLSessionInfoEbENK5$_537clEPKc -_ZN9oceanbase3sql10ObSQLUtils20handle_plan_baselineERKNS0_17ObAuditRecordDataEPNS0_14ObPhysicalPlanEiRNS0_8ObSqlCtxE -_ZN9oceanbase3sql14ObPhysicalPlan16update_plan_statERKNS0_17ObAuditRecordDataEbbPKNS_6common8ObIArrayINS0_15ObTableRowCountEEE -_ZThn56_N9oceanbase8observer8ObMPBase14send_ok_packetERNS_3sql16ObSQLSessionInfoERNS0_10ObOKPParamEPNS_7obmysql13ObMySQLPacketE -_ZN9oceanbase3sql17ObLCObjectManager11common_freeEPNS0_17ObILibCacheObjectENS0_16CacheRefHandleIDE -_ZN9oceanbase3sql18ObBasicSessionInfo17set_session_sleepEv -_ZN9oceanbase11transaction17ObTxnFreeRouteCtx26init_before_handle_requestEPNS0_8ObTxDescE _ZN9oceanbase8observer16ObSyncPlanDriver15response_resultERNS0_16ObMySQLResultSetE -_ZThn56_N9oceanbase8observer8ObMPBase15response_packetERNS_7obmysql13ObMySQLPacketEPNS_3sql16ObSQLSessionInfoE +_ZN9oceanbase3sql15ObExecuteResult5closeERNS0_13ObExecContextE +_ZNK9oceanbase3sql10ObOperator23get_operator_open_orderEv _ZN9oceanbase8observer13ObQueryDriver21response_query_resultERNS_3sql11ObResultSetEbbRbl -_ZN9oceanbase3sql18ObBasicSessionInfo17create_dtc_paramsEPKS1_ -_ZN9oceanbase8observer13ObQueryDriver28convert_string_value_charsetERNS_6common5ObObjERNS_3sql11ObResultSetE +_ZN9oceanbase6common9ObCharset11get_charsetENS0_15ObCollationTypeE +_ZN9oceanbase3sql11ObResultSet12get_next_rowERPKNS_6common8ObNewRowE +_ZN9oceanbase3sql16LinkExecCtxGuard20link_current_contextEv +_ZN9oceanbase3sql16LinkExecCtxGuardD2Ev +_ZN9oceanbase3sql15ObExecuteResult12get_next_rowERNS0_13ObExecContextERPKNS_6common8ObNewRowE _ZN9oceanbase8observer16ObMPPacketSender15response_packetERNS_7obmysql13ObMySQLPacketEPNS_3sql16ObSQLSessionInfoE _ZTWN9oceanbase3lib15ObPerfModeGuard26in_disable_diagnose_guard_E +_ZNK9oceanbase7obmysql7OMPKRow9serializeEPclRl _ZN9oceanbase7obmysql23ObPocSqlRequestOperator15get_sql_sessionEPNS_3rpc9ObRequestE -_ZN9oceanbase6common20ObDiagnoseTenantInfo23get_local_diagnose_infoEv -_ZN9oceanbase8observer16ObMPPacketSender15try_encode_withERNS_7obmysql13ObMySQLPacketElRll -_ZN9oceanbase6common7ObDITlsINS0_17ObSessionDIBufferELm0EE12get_instanceEv -_ZN9oceanbase6common23ObReserveArenaAllocatorILl256EE5resetEv -_ZN9oceanbase6common8ObNewRow8get_cellEl -_ZN9oceanbase6common5ObObj28convert_string_value_charsetENS0_13ObCharsetTypeERNS0_12ObIAllocatorE -_ZN9oceanbase6common9ObCharset15charset_convertENS0_15ObCollationTypeEPKcjS2_PclRjbbm -_Z10ob_convertPcjPK13ObCharsetInfoPKcjS2_bmPj -_ZN9oceanbase6common9ObCharset20charset_type_by_collENS0_15ObCollationTypeE -_ZN9oceanbase6common5ObObj10set_stringENS0_9ObObjTypeEPKci -_ZN9oceanbase7obmysql14ObProto20Utils16do_packet_encodeERNS0_18ObProtoEncodeParamE -_ZN9oceanbase3sql15ObExecuteResult12get_next_rowERNS0_13ObExecContextERPKNS_6common8ObNewRowE -_ZNK9oceanbase6common5ObObj10get_stringERNS0_8ObStringE -_ZN9oceanbase3sql10ObSQLUtils13is_nested_sqlEPNS0_13ObExecContextE _ZNK9oceanbase7obmysql9OMPKField9serializeEPclRl +_ZN9oceanbase8observer16ObMPPacketSender15try_encode_withERNS_7obmysql13ObMySQLPacketElRll +_ZNK9oceanbase7obmysql10ObMySQLRow9serializeEPclRl +_ZNK9oceanbase6common7ObSMRow11encode_cellElPclRlS2_ _ZN9oceanbase6common9ObSMUtils8cell_strEPclRKNS0_5ObObjENS_7obmysql19MYSQL_PROTOCOL_TYPEERllS2_RKNS0_20ObDataTypeCastParamsEPKNS0_7ObFieldEPNS_5share6schema19ObSchemaGetterGuardEm _ZN9oceanbase7obmysql11ObMySQLUtil12store_lengthEPclmRl -_ZN9oceanbase3sql13ObExecContext29get_convert_charset_allocatorERPNS_6common16ObArenaAllocatorE -_ZN9oceanbase7obmysql23ObPocSqlRequestOperator25alloc_sql_response_bufferEPNS_3rpc9ObRequestEl -_ZN9oceanbase8observer16ObMPPacketSender25need_send_extra_ok_packetEv -_ZN9oceanbase6common9PageArenaIcNS0_19ModulePageAllocatorEE20free_remain_one_pageEv -_ZZNK9oceanbase3sql18ObBasicSessionInfo31is_server_status_in_transactionEvENK3$_0clEPKc.llvm.6716584109504846641 +_ZN9oceanbase3sql15ObExecuteResult4openERNS0_13ObExecContextE +_ZNK9oceanbase7obmysql7OMPKEOF9serializeEPclRl _ZN9oceanbase8observer16ObMPPacketSender19update_last_pkt_posEv -_ZN9oceanbase3lib17__MemoryContext__14create_contextIJRNS0_12ContextParamEPNS0_10StaticInfoEEEEiRNS0_13MemoryContextERKNS0_11DynamicInfoEDpOT_ -_ZN9oceanbase8observer13ObQueryDriver21response_query_headerERNS_3sql11ObResultSetEbbb +_ZN9oceanbase3sql13ObPxAdmission20exit_query_admissionERNS0_16ObSQLSessionInfoERNS0_13ObExecContextENS0_4stmt8StmtTypeERNS0_14ObPhysicalPlanE +_ZN9oceanbase8observer16ObMPPacketSender25need_send_extra_ok_packetEv +_ZNK9oceanbase7obmysql13OMPKResheader9serializeEPclRl _ZN9oceanbase8observer16ObMySQLResultSet14to_mysql_fieldERKNS_6common7ObFieldERNS_7obmysql12ObMySQLFieldE -_ZN9oceanbase6common9ObSMUtils14get_mysql_typeENS0_9ObObjTypeERNS_7obmysql15EMySQLFieldTypeERtRs -_ZN9oceanbase3sql10ObOperator14get_next_batchElRPKNS0_11ObBatchRowsE -_ZN9oceanbase3sql10ObOperator26match_rt_monitor_conditionEl -_ZN9oceanbase3sql10ObOperator10drain_exchEv +_ZZNK9oceanbase3sql18ObBasicSessionInfo31is_server_status_in_transactionEvENK3$_0clEPKc.llvm.14994795034914827030 +_ZN9oceanbase3sql5ObSql10stmt_queryERKNS_6common8ObStringERNS0_8ObSqlCtxERNS0_11ObResultSetE +_ZNK9oceanbase6common16ObArenaAllocator5totalEv +OPENSSL_cleanse +_ZN9oceanbase3sql17ObPhysicalPlanCtxC1ERNS_6common12ObIAllocatorE +_ZN9oceanbase3sql17ObPhysicalPlanCtxC2ERNS_6common12ObIAllocatorE +_ZNK9oceanbase11transaction17ObTxnFreeRouteCtx7is_tempERKNS0_8ObTxDescE +_ZN9oceanbase3sql5ObSql18handle_large_queryEiRNS0_11ObResultSetERbRNS0_13ObExecContextE +_ZN9oceanbase3sql14ObPlanCacheCtxD2Ev +_ZN9oceanbase3sql14ObExprValuesOp7destroyEv +_ZThn56_N9oceanbase8observer8ObMPBase14send_ok_packetERNS_3sql16ObSQLSessionInfoERNS0_10ObOKPParamEPNS_7obmysql13ObMySQLPacketE +_ZN9oceanbase3sql10ObOperator5closeEv +_ZN9oceanbase3sql13ObTableScanOp11inner_closeEv +_ZN9oceanbase6common18ObWrapperAllocator4freeEPv _ZZN9oceanbase3sql11ObResultSet19auto_end_plan_transERNS0_14ObPhysicalPlanEiRbENKUlPKcE_clES6_ +_ZN9oceanbase3sql18ObBasicSessionInfo21gen_configs_in_pc_strEv +_ZN9oceanbase3sql16ObSQLSessionInfo24ObCachedTenantConfigInfo7refreshEv +_ZN9oceanbase6common9ObSEArrayINS_3sql15ObPxTabletRangeELl1ENS0_19ModulePageAllocatorELb0EEC2Ev +_ZN9oceanbase5trace16__ObFLTSpanGuardD2Ev +_ZN9oceanbase3sql5ObSql27pc_get_plan_and_fill_resultERNS0_14ObPlanCacheCtxERNS0_11ObResultSetERiRb +_ZN9oceanbase6common13ObSEArrayImplImLl8ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayImEE +_ZZN9oceanbase3sql8ObDASCtx4initERKNS0_14ObPhysicalPlanERNS0_13ObExecContextEENK4$_40clEPKc.llvm.8941250701355435802 +_ZN9oceanbase5trace7ObTrace12get_instanceEv +_ZN9oceanbase8observer16ObMPPacketSender12flush_bufferEb +_ZN9oceanbase3sql18ObBasicSessionInfo18set_session_activeERKNS_6common8ObStringEllNS_7obmysql10ObMySQLCmdE +_ZZN9oceanbase8observer8ObMPBase18process_extra_infoERNS_3sql16ObSQLSessionInfoERKNS_7obmysql16ObMySQLRawPacketERbENK5$_356clEPKc +_ZN9oceanbase3sql18ObBasicSessionInfo17set_session_sleepEv +_ZN9oceanbase3sql10ObOperator14get_next_batchElRPKNS0_11ObBatchRowsE +_ZN9oceanbase3sql13ObTableScanOp20inner_get_next_batchEl +_ZN9oceanbase3sql15DASOpResultIter21reset_wild_datums_ptrEv _ZN9oceanbase3sql8ObSortOp20inner_get_next_batchEl _ZN9oceanbase3sql12ObSortOpImpl20add_quick_sort_batchERKNS_6common8ObIArrayIPNS0_6ObExprEEERKNS0_11ObBitVectorEllPl _ZN9oceanbase3sql17ObChunkDatumStore9add_batchERKNS_6common8ObIArrayIPNS0_6ObExprEEERNS0_9ObEvalCtxERKNS0_11ObBitVectorElPKtlPPNS1_9StoredRowE _ZNK9oceanbase3sql6ObExpr13do_eval_batchERNS0_9ObEvalCtxERKNS0_11ObBitVectorEl _ZN9oceanbase3sql19ObExprEncodeSortkey25eval_encode_sortkey_batchERKNS0_6ObExprERNS0_9ObEvalCtxERKNS0_11ObBitVectorEl -_ZNK9oceanbase3sql6ObExpr17alloc_str_res_memERNS0_9ObEvalCtxEll -_ZN9oceanbase6common16ObArenaAllocator5allocEl _ZN9oceanbase5share20ObSortkeyConditioner24process_key_conditioningERNS_6common7ObDatumEPhlRlRNS0_10ObEncParamE -_ZN9oceanbase5share24ObOrderPerservingEncoder25encode_from_string_varlenENS_6common8ObStringEPhlRlRNS0_10ObEncParamE -ob_mb_wc_utf8mb4_thunk _Z26ob_strnxfrm_unicode_varlenPK13ObCharsetInfoPhmjPKhmbPb -_ZL16ob_wc_mb_utf8mb4PK13ObCharsetInfomPhS2_ -_ZL16ob_mb_wc_utf8mb4PK13ObCharsetInfoPmPKhS4_ _ZN9oceanbase6common9ObCharset17is_argument_validENS0_15ObCollationTypeEPKclS4_l -_ZN9oceanbase6common9PageArenaIcNS0_19ModulePageAllocatorEE11extend_pageEl -_ZTWN9oceanbase6common13ObPageManager12tl_instance_E -_ZN9oceanbase6common19ModulePageAllocator5allocElRKNS_3lib9ObMemAttrE -_ZN9oceanbase3lib21ObMallocSampleLimiter21malloc_sample_allowedElRKNS0_9ObMemAttrE -_ZN9oceanbase6common20get_mem_leak_checkerEv -_ZN9oceanbase6common16ObMemLeakChecker8on_allocERNS_3lib7AObjectERKNS2_9ObMemAttrE -_ZN9oceanbase3lib9ObjectSet12alloc_objectEmRKNS0_9ObMemAttrE -_ZN9oceanbase3lib8BlockSet14get_free_blockEiRKNS0_9ObMemAttrE -_ZN9oceanbase3lib20ObTenantCtxAllocator5allocElRKNS0_9ObMemAttrE -_ZN9oceanbase3lib9ObjectMgr12alloc_objectEmRKNS0_9ObMemAttrE -_ZN9oceanbase3omt17ObTenantConfigMgr25get_tenant_config_versionEm -_ZN9oceanbase6common7ObLatch6rdlockEjl -_ZN9oceanbase3sql14ObExprValuesOp7destroyEv -_ZN9oceanbase3sql13ObPxAdmission20exit_query_admissionERNS0_16ObSQLSessionInfoERNS0_13ObExecContextENS0_4stmt8StmtTypeERNS0_14ObPhysicalPlanE -_ZN9oceanbase3sql18ObBasicSessionInfo38update_query_sensitive_system_variableERNS_5share6schema19ObSchemaGetterGuardE -_ZNK9oceanbase5share6schema16ObSysVariableMgr23get_sys_variable_schemaEmRPKNS1_25ObSimpleSysVariableSchemaE -_ZN9oceanbase3sql11ObResultSet4openEv -_ZN9oceanbase3sql12ObOpKitStore4initERNS_6common12ObIAllocatorEl -_ZThn32_NK9oceanbase3sql16ObStartTransStmt21cause_implicit_commitEv -_ZNK9oceanbase3sql6ObICmd21cause_implicit_commitEv -_ZN9oceanbase3sql16ObSQLSessionInfo18reset_warnings_bufEv -_ZN9oceanbase3sql16ObSQLSessionInfo19get_request_managerEv -_ZN9oceanbase3sql5ObSql27pc_get_plan_and_fill_resultERNS0_14ObPlanCacheCtxERNS0_11ObResultSetERiRb -_ZN9oceanbase3sql16ObPrivilegeCheck22check_password_expiredERKNS0_8ObSqlCtxENS0_4stmt8StmtTypeE -_ZN9oceanbase3sql16ObSQLSessionInfo25check_read_only_privilegeEbRKNS0_11ObSqlTraitsE -_ZN9oceanbase5share11ObTenantEnv3mtlIPNS_3sql8ObUDRMgrEEET_v -_ZN9oceanbase3sql16ObPrivilegeCheck15check_privilegeERKNS0_8ObSqlCtxERKNS_5share6schema15ObStmtNeedPrivsE -_ZN9oceanbase6common13ObSEArrayImplImLl8ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayImEE -_ZN9oceanbase3sql11ObPlanCache8get_planERNS_6common12ObIAllocatorERNS0_14ObPlanCacheCtxERNS0_15ObCacheObjGuardE -_ZN9oceanbase6common7ObDListINS_5trace9ObSpanCtxEE9add_firstEPS3_ -_ZNK9oceanbase5share6schema19ObSchemaGetterGuard14get_schema_mgrEmRPKNS1_11ObSchemaMgrE -_ZZN9oceanbase3sql11ObPlanCache13get_cache_objERNS0_14ObILibCacheCtxEPNS0_14ObILibCacheKeyERNS0_15ObCacheObjGuardEENK5$_195clEPKc.llvm.2638051417269291142 -_ZNK9oceanbase3omt17ObTenantConfigMgr27get_tenant_config_with_lockEmmm -_ZN9oceanbase6common4hash11ObHashTableINS_3omt10ObTenantIDENS1_11HashMapPairIS4_PNS3_14ObTenantConfigEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS8_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS8_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE32internal_get_with_timeout_unsafeERNS1_17ObHashTableBucketIS8_NS1_5NLockENS1_5NCondEEERKS4_RPKS8_l -_ZN9oceanbase3sql11ObPlanCache13get_cache_objERNS0_14ObILibCacheCtxEPNS0_14ObILibCacheKeyERNS0_15ObCacheObjGuardE -_ZNK9oceanbase3sql14ObPlanCacheKey4hashEv -_ZN9oceanbase3sql18ObLibCacheAtomicOpclERNS_6common4hash11HashMapPairIPNS0_14ObILibCacheKeyEPNS0_15ObILibCacheNodeEEE -_ZNK9oceanbase3sql14ObPlanCacheKey8is_equalERKNS0_14ObILibCacheKeyE -_ZNK9oceanbase8observer9ObMPQuery11record_statENS_3sql4stmt8StmtTypeEl -_ZN9oceanbase3sql11ObResultSet5closeEv -_ZN9oceanbase3sql16LinkExecCtxGuardD2Ev -_ZN9oceanbase3sql15ObExecuteResult5closeERNS0_13ObExecContextE -_ZNK9oceanbase3sql15ObTableModifyOp23get_operator_open_orderEv -_ZN9oceanbase3sql10ObOperator5closeEv -_ZN9oceanbase6common7ObDListINS0_9ObObjNodeIPNS_3sql20ObDasAggregatedTasksEEEE12remove_firstEv -_ZN9oceanbase6common10ObObjStoreIPNS_3sql12ObIDASTaskOpERNS0_12ObIAllocatorELb0EE7destroyEv -_ZN9oceanbase5share11ObTenantEnv3mtlIPNS_7storage15ObAccessServiceEEET_v -_ZN9oceanbase3sql11ObDASScanOp10release_opEv -_ZN9oceanbase7storage15ObAccessService16revert_scan_iterEPNS_6common16ObNewRowIteratorE -_ZN9oceanbase7storage19ObTableScanIterator5resetEv -_ZN9oceanbase6common18ObWrapperAllocator4freeEPv -_ZN9oceanbase7storage14ObTabletHandle5resetEv -_ZN9oceanbase7storage13ObSingleMergeD2Ev -_ZN9oceanbase6common16ObMultiModRefMgrINS_7storage10ObLSGetModEE3decES3_ -_ZZN9oceanbase11transaction14ObTransService16revert_store_ctxERNS_7storage10ObStoreCtxEENK6$_1323clEPKc -_ZN9oceanbase7storage19ObMultipleScanMergeD1Ev -_ZN9oceanbase7storage19ObMultipleScanMergeD2Ev -_ZN9oceanbase7storage22ObMicroBlockDataHandleD1Ev -_ZN9oceanbase7storage22ObMicroBlockDataHandleD2Ev -_ZN9oceanbase12blocksstable18ObMacroBlockHandleD1Ev -_ZN9oceanbase12blocksstable18ObMacroBlockHandle5resetEv -_ZN9oceanbase6common15ObKVCacheHandleD1Ev -_ZN9oceanbase6common15ObKVCacheHandleD2Ev -_ZN9oceanbase6common14ObKVCacheStore13de_handle_refEPNS0_18ObKVMemBlockHandleEb -_ZN9oceanbase6common16ObFixedArrayImplINS_7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE22ObIndexTreeLevelHandleENS0_12ObIAllocatorEED2Ev -_ZN9oceanbase6common16ObFixedArrayImplINS_7storage19ObSSTableReadHandleENS0_12ObIAllocatorEED2Ev -_ZN9oceanbase12blocksstable23ObIMicroBlockRowScannerD2Ev -_ZN9oceanbase7storage21ObIndexTreePrefetcherD2Ev -_ZN9oceanbase8memtable22ObMemtableScanIteratorD2Ev -_ZN9oceanbase7storage13ObVectorStoreD2Ev -_ZN9oceanbase7storage18ObSSTableRowGetterD2Ev -_ZN9oceanbase12blocksstable10ObDatumRowD1Ev -_ZN9oceanbase12blocksstable10ObDatumRowD2Ev -_ZN9oceanbase6common15ObFIFOAllocator5resetEv -_ZN9oceanbase8memtable21ObMemtableGetIteratorD2Ev -_ZN9oceanbase12blocksstable10ObDatumRow5resetEv -_ZN9oceanbase6common16ObFixedArrayImplINS_5share6schema16ObColumnSchemaV2ENS0_12ObIAllocatorEED2Ev -_ZN9oceanbase8observer16ObMPPacketSender11get_sessionERPNS_3sql16ObSQLSessionInfoE -_ZN9oceanbase3sql13ObExecContextD1Ev -_ZN9oceanbase3sql13ObExecContextD2Ev -_ZN9oceanbase6common10ObObjStoreIPNS_3sql27ObRpcDasAsyncAccessCallBackERNS0_12ObIAllocatorELb0EED2Ev -_ZN9oceanbase6common13ObSEArrayImplINS_3sql17ObSqlTempTableCtxELl2ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase3sql16ObDASTaskFactoryD1Ev -_ZN9oceanbase3sql16ObDASTaskFactoryD2Ev -_ZN9oceanbase3sql16ObDASTaskFactory7cleanupEv -_ZN9oceanbase6common13ObSEArrayImplINS0_10ObNewRangeELl4ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase3lib17ObMallocAllocator4freeEPv -_ZN9oceanbase3sql18ObTableScanOpInputD2Ev -_ZN9oceanbase6common13ObSEArrayImplINS0_10ObNewRangeELl1ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase8observer16ObMPPacketSender12flush_bufferEb -_ZN9oceanbase7obmysql23ObPocSqlRequestOperator20async_write_responseEPNS_3rpc9ObRequestEPKcl -_ZN9oceanbase7obmysql23request_finish_callbackEv -_ZN9oceanbase3sql17ObTaskExecutorCtxC1ERNS0_13ObExecContextE -_ZN9oceanbase3sql10ObOperator4openEv -_ZN9oceanbase6common13ObSEArrayImplINS_3sql21ObPartIdRowMapManager8MapEntryELl1ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase6common16ObDISessionCache8get_nodeEmRPNS0_18ObDISessionCollectE -_ZZN9oceanbase7obmysql12ObSqlNioImpl11revert_sockEPNS0_9ObSqlSockEENKUlPKcE1_clES5_ -_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEED1Ev -_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEED2Ev -_ZN9oceanbase5share6schema19ObSchemaGetterGuard20get_tenant_read_onlyEmRb -_ZN9oceanbase3sql20ObSecurityAuditUtils21handle_security_auditERNS0_11ObResultSetEPNS_5share6schema19ObSchemaGetterGuardEPKNS0_6ObStmtERKNS_6common8ObStringEi -_ZN9oceanbase8observer11ObSrvXlator7releaseEPNS_3rpc5frame14ObReqProcessorE -_ZN9oceanbase8observer9ObMPQueryD2Ev -_ZZN9oceanbase3sql8ObDASCtx4initERKNS0_14ObPhysicalPlanERNS0_13ObExecContextEENK4$_43clEPKc.llvm.10852611981086769144 -_ZN9oceanbase6common17ObVTableScanParamD2Ev -_ZN9oceanbase12blocksstable23ObIMicroBlockFlatReaderD2Ev -_ZN9oceanbase3sql16ObSQLSessionInfo21set_show_warnings_bufEi -_ZN9oceanbase3sql5ObSql14after_get_planERNS0_14ObPlanCacheCtxERNS0_16ObSQLSessionInfoEPNS0_14ObPhysicalPlanEbPKNS_6common9Ob2DArrayINS8_10ObObjParamELi2079744ENS8_18ObWrapperAllocatorELb0ENS8_9ObSEArrayIPSA_Ll1ESB_Lb0EEEEEm -_ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScannerD2Ev -_ZNK9oceanbase3lib17ObMallocAllocator40get_tenant_ctx_allocator_without_tlcacheEmm -_ZN9oceanbase5trace7ObTrace10append_tagIbLb1EEEb9ObTagTypeRKT_ -_ZN9oceanbase12blocksstable18ObMicroBlockReaderD2Ev -_ZN9oceanbase6common11ObAllocator4freeEPv -_ZN9oceanbase3rpc5frame15ObReqTranslator9translateERNS0_9ObRequestERPNS1_14ObReqProcessorE -_ZN9oceanbase3sql21ObSqlParameterization11fast_parserERNS_6common12ObIAllocatorERKNS0_9FPContextERKNS2_8ObStringERNS0_18ObFastParserResultE -_ZN9oceanbase6common9ObCharset11get_charsetENS0_15ObCollationTypeE -_ZN9oceanbase3sql16ObFastParserBase5parseERKNS_6common8ObStringERPcRlRP10_ParamListS8_ -_ZN9oceanbase3sql17ObFastParserMysql16parse_next_tokenEv -_ZN9oceanbase3sql16ObFastParserBase19is_identifier_flagsEl -_ZN9oceanbase3sql17ObFastParserMysql18process_identifierEb -_ZN9oceanbase3sql16ObFastParserBase14process_numberEb -_ZZN9oceanbase3sql11ObResultSet19auto_end_plan_transERNS0_14ObPhysicalPlanEiRbENKUlPKcE3_clES6_ -_ZN9oceanbase6common11ObArrayImplIPNS_3sql17ObChunkDatumStore9StoredRowENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS5_EENS0_22NotImplementItemEncodeIS5_EEED2Ev -_ZZN9oceanbase8observer8ObMPBase18process_extra_infoERNS_3sql16ObSQLSessionInfoERKNS_7obmysql16ObMySQLRawPacketERbENK5$_356clEPKc -_ZN9oceanbase12blocksstable18ObMacroBlockReaderD1Ev -_ZN9oceanbase12blocksstable18ObMacroBlockReaderD2Ev -_ZZN9oceanbase3sql8ObPCVSet19inner_get_cache_objERNS0_14ObILibCacheCtxEPNS0_14ObILibCacheKeyERPNS0_17ObILibCacheObjectEENK4$_86clEPKc -_ZNK9oceanbase6common9EventItem4callEv _ZN9oceanbase3sql13ObTableScanOp28inner_get_next_batch_for_tscEl -_ZN9oceanbase3sql11ObDASScanOp22get_output_result_iterEv -_ZN9oceanbase3sql15DASOpResultIter13get_next_rowsERll -_ZN9oceanbase7storage19ObTableScanIterator13get_next_rowsERll _ZN9oceanbase7storage15ObMultipleMerge13get_next_rowsERll +_ZN9oceanbase7storage18ObStoreRowIterator12get_next_rowERPKNS_12blocksstable10ObDatumRowE _ZN9oceanbase7storage18ObStoreRowIterator13get_iter_flagEv +_ZN9oceanbase7storage18ObSimpleRowsMergerINS0_24ObScanMergeLoserTreeItemENS0_23ObScanMergeLoserTreeCmpEE7rebuildEv _ZN9oceanbase8memtable22ObMemtableScanIterator13get_iter_flagEv _ZN9oceanbase7storage19ObMultipleScanMerge18inner_get_next_rowERNS_12blocksstable10ObDatumRowE -_ZN9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE13inner_rebuildEv -_ZN9oceanbase12blocksstableL21nonext_nonext_compareERKNS0_14ObStorageDatumES3_RKNS_6common9ObCmpFuncERi.llvm.6693482919459847865 -_ZN9oceanbase6common20ObNullSafeDatumTCCmpILNS0_14ObObjTypeClassE1ELS2_1ELb1EE3cmpERKNS0_7ObDatumES6_Ri -_ZN9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE3popEv +_ZN9oceanbase12blocksstableL21nonext_nonext_compareERKNS0_14ObStorageDatumES3_RKNS_6common9ObCmpFuncERi.llvm.15281195588870497899 +_ZNK9oceanbase7storage16ObMergeLoserTreeINS0_24ObScanMergeLoserTreeItemENS0_23ObScanMergeLoserTreeCmpELl80EE5emptyEv _ZN9oceanbase7storage31ObSSTableMultiVersionRowScanner18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowE _ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEE18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowE -_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE8prefetchEv -_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEE9fetch_rowERNS0_19ObSSTableReadHandleERPKNS_12blocksstable10ObDatumRowE _ZN9oceanbase12blocksstable23ObIMicroBlockRowScanner12get_next_rowERPKNS0_10ObDatumRowE -_ZThn336_N9oceanbase12blocksstable18ObMicroBlockReader7get_rowElRNS0_10ObDatumRowE -_ZN9oceanbase12blocksstable19ObMicroBlockDecoder7get_rowElRNS0_10ObDatumRowE -_ZNK9oceanbase7storage16ObMergeLoserTreeINS0_24ObScanMergeLoserTreeItemENS0_23ObScanMergeLoserTreeCmpELl80EE5emptyEv +_ZNK9oceanbase12blocksstable19ObStringDiffDecoder6decodeERNS0_18ObColumnDecoderCtxERNS_6common5ObObjElRKNS0_11ObBitStreamEPKcl +_ZNK9oceanbase12blocksstable24ObIntegerBaseDiffDecoder6decodeERNS0_18ObColumnDecoderCtxERNS_6common5ObObjElRKNS0_11ObBitStreamEPKcl +_ZN9oceanbase6common7ObDatum8from_objERKNS0_5ObObjE +_ZN9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE3popEv +_ZN9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE7rebuildEv +_ZN9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE13inner_rebuildEv +_ZN9oceanbase6common16ObArenaAllocator5allocEl _ZN9oceanbase7storage15ObMultipleMerge16process_fuse_rowEbRNS_12blocksstable10ObDatumRowERPS3_ -_ZN9oceanbase8memtable23ObIMemtableScanIterator12get_next_rowERPKNS_12blocksstable10ObDatumRowE -_ZNK9oceanbase7storage13ObSingleMerge18collect_merge_statERNS0_16ObTableStoreStatE +_ZThn336_N9oceanbase12blocksstable18ObMicroBlockReader14get_row_headerElRPKNS0_11ObRowHeaderE +_ZNK9oceanbase12blocksstable12ObRawDecoder6decodeERNS0_18ObColumnDecoderCtxERNS_6common5ObObjElRKNS0_11ObBitStreamEPKcl _ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScanner18inner_get_next_rowERPKNS0_10ObDatumRowE _ZN9oceanbase12blocksstable18ObMicroBlockReader7get_rowElRNS0_10ObDatumRowE -_ZN9oceanbase12blocksstable11ObRowReader8read_rowEPKclPKNS_7storage15ObTableReadInfoERNS0_10ObDatumRowE -_ZNK9oceanbase7storage19ObMultipleScanMerge18collect_merge_statERNS0_16ObTableStoreStatE +_ZNK9oceanbase7storage15ObTableReadInfo17get_request_countEv +_ZNK9oceanbase7storage15ObTableReadInfo25get_seq_read_column_countEv +_ZN9oceanbase12blocksstable11ObRowReader8read_rowEPKclPKNS_7storage16ObITableReadInfoERNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable11ObRowReader9setup_rowEPKcl +_ZNK9oceanbase7storage15ObTableReadInfo8is_validEv +_ZN9oceanbase12blocksstable21ObClusterColumnReader4initEPKcmmRKNS0_20ObColClusterInfoMaskE +_ZN9oceanbase12blocksstable21ObClusterColumnReader19sequence_read_datumElRNS0_14ObStorageDatumE +_ZN9oceanbase12blocksstable21ObClusterColumnReader10read_datumElRNS0_14ObStorageDatumE +_ZN9oceanbase12blocksstable21ObClusterColumnReader18read_storage_datumElRNS0_14ObStorageDatumE +_ZN9oceanbase12blocksstableL12get_offset_8EPKvl +_ZN9oceanbase12blocksstable10ObDatumRow7reserveElb +_ZNK9oceanbase7storage16ObRowkeyReadInfo25get_seq_read_column_countEv +_ZNK9oceanbase7storage18ObSimpleRowsMergerINS0_24ObScanMergeLoserTreeItemENS0_23ObScanMergeLoserTreeCmpEE5emptyEv +_ZThn336_N9oceanbase12blocksstable18ObMicroBlockReader7get_rowElRNS0_10ObDatumRowE +_ZN9oceanbase8memtable23ObIMemtableScanIterator12get_next_rowERPKNS_12blocksstable10ObDatumRowE +_ZNK9oceanbase8memtable13ObQueryEngine8IteratorINS_8keybtree13BtreeIteratorINS0_20ObStoreRowkeyWrapperEPNS0_9ObMvccRowEEEE13get_iter_flagEv +_ZN9oceanbase8memtable13ObQueryEngine8IteratorINS_8keybtree13BtreeIteratorINS0_20ObStoreRowkeyWrapperEPNS0_9ObMvccRowEEEE11set_versionEl +_ZN9oceanbase8memtable13ObQueryEngine8IteratorINS_8keybtree13BtreeIteratorINS0_20ObStoreRowkeyWrapperEPNS0_9ObMvccRowEEEE4nextEb +_ZThn336_N9oceanbase12blocksstable18ObMicroBlockReader22get_multi_version_infoEllRPKNS0_11ObRowHeaderERlS6_ +_ZN9oceanbase8memtable13ObQueryEngine8IteratorINS_8keybtree13BtreeIteratorINS0_20ObStoreRowkeyWrapperEPNS0_9ObMvccRowEEEE13next_internalEb _ZN9oceanbase7storage19ObMultipleScanMerge17prepare_blockscanERNS0_18ObStoreRowIteratorE +_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEE25refresh_blockscan_checkerERKNS_12blocksstable13ObDatumRowkeyE _ZN9oceanbase7storage16ObMergeLoserTreeINS0_24ObScanMergeLoserTreeItemENS0_23ObScanMergeLoserTreeCmpELl80EE3topERPKS2_ _ZN9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE3topERPKS3_ -_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEE25refresh_blockscan_checkerERKNS_12blocksstable13ObDatumRowkeyE -_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE19prefetch_micro_dataEv -_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner8get_nextERNS0_16ObMicroIndexInfoE -_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner17read_curr_idx_rowERPKNS0_21ObIndexBlockRowHeaderERPKNS0_13ObDatumRowkeyE -_ZN9oceanbase7storage21ObIndexTreePrefetcher19prefetch_block_dataERNS_12blocksstable16ObMicroIndexInfoERNS0_22ObMicroBlockDataHandleEb -_ZN9oceanbase12blocksstable18ObIMicroBlockCache15get_cache_blockEmNS0_12MacroBlockIdEllRNS0_24ObMicroBlockBufferHandleE -_ZN9oceanbase6common21ObDiagnoseSessionInfo23get_local_diagnose_infoEv -_ZN9oceanbase7storage15ObMultipleMerge18report_tablet_statEv +_ZN9oceanbase8keybtree8IteratorINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE13set_key_rangeES3_bS3_bl +_ZN9oceanbase7storage18ObSimpleRowsMergerINS0_24ObScanMergeLoserTreeItemENS0_23ObScanMergeLoserTreeCmpEE3topERPKS2_ _ZN9oceanbase7storage16ObMergeLoserTreeINS0_24ObScanMergeLoserTreeItemENS0_23ObScanMergeLoserTreeCmpELl80EE8push_topERKS2_ -_ZN9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE4pushERKS3_ -_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE22ObIndexTreeLevelHandle7forwardERKNS0_15ObTableReadInfoERKNS_12blocksstable13ObDatumRowkeyEb -_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner4openERKNS0_12MacroBlockIdERKNS0_16ObMicroBlockDataERKNS0_12ObDatumRangeElbb -_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner18init_by_micro_dataERKNS0_16ObMicroBlockDataE -_ZN9oceanbase7storage15ObMultipleMerge12get_next_rowERPNS_12blocksstable10ObDatumRowE -_ZN9oceanbase7storage13ObSingleMerge22get_and_fuse_cache_rowEllRNS_12blocksstable10ObDatumRowERbS5_S5_ -_ZN9oceanbase6common15ObKVCacheHandle5resetEv -_ZN9oceanbase7storage13ObSingleMerge13get_table_rowElRKNS_6common8ObIArrayIPNS0_8ObITableEEERNS_12blocksstable10ObDatumRowERbSC_ -_ZN9oceanbase8memtable19ObIMemtableIterator12get_next_rowERPKNS_12blocksstable10ObDatumRowE -_ZNK9oceanbase7storage15ObTableReadInfo8is_validEv -_ZN9oceanbase7storage18ObSSTableRowGetter9fetch_rowERNS0_19ObSSTableReadHandleERPKNS_12blocksstable10ObDatumRowE -_ZThn336_N9oceanbase12blocksstable21ObMicroBlockGetReader7get_rowERKNS0_16ObMicroBlockDataERKNS0_13ObDatumRowkeyERKNS_7storage15ObTableReadInfoERNS0_10ObDatumRowE -_ZN9oceanbase8memtable10ObMemtable3getERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_12blocksstable13ObDatumRowkeyERPNS2_18ObStoreRowIteratorE -_ZN9oceanbase12blocksstable10ObDatumRow4initERNS_6common12ObIAllocatorElPc -_ZN9oceanbase12blocksstable14ObFuseRowCache7get_rowERKNS0_17ObFuseRowCacheKeyERNS0_20ObFuseRowValueHandleE -_ZN9oceanbase6common15ObKVGlobalCache12get_instanceEv -_ZN9oceanbase6common12ObKVCacheMap3getElRKNS0_13ObIKVCacheKeyERPKNS0_15ObIKVCacheValueERPNS0_18ObKVMemBlockHandleE +_ZN9oceanbase7storage23ObScanMergeLoserTreeCmp3cmpERKNS0_24ObScanMergeLoserTreeItemES4_Rl _ZZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE25refresh_blockscan_checkerElRKNS_12blocksstable13ObDatumRowkeyEENKUlPKcE3_clES8_ -_ZN9oceanbase6common8ObLogger13need_to_printEmi -_ZN9oceanbase12blocksstable10ObDatumRow15prepare_new_rowERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEE -_ZN9oceanbase12blocksstable14ObGhostRowUtil12is_ghost_rowERKNS0_21ObMultiVersionRowFlagERb -_ZN9oceanbase3sql18ObPushdownOperator22write_trans_info_datumERNS_12blocksstable10ObDatumRowE -_ZZN9oceanbase12blocksstable22ObIndexBlockRowScanner12locate_rangeERKNS0_12ObDatumRangeEbbENK5$_841clEPKc -_ZN9oceanbase7storage21ObFuseRowCacheFetcher18put_fuse_row_cacheERKNS_12blocksstable13ObDatumRowkeyERNS2_10ObDatumRowEl -_ZN9oceanbase12blocksstable9ObSSTable3getERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS0_13ObDatumRowkeyERPNS2_18ObStoreRowIteratorE -_ZN9oceanbase12blocksstable18ObMacroBlockReaderC1Ev -_ZN9oceanbase12blocksstable18ObMacroBlockReaderC2Ev -_ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScanner10do_compactEPKNS0_10ObDatumRowERS2_Rb -_ZN9oceanbase8memtable21ObMemtableGetIterator18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowE -_ZN9oceanbase6common17ObjHashCalculatorILNS0_9ObObjTypeE4ENS0_13ObDefaultHashENS0_5ObObjEE15calc_hash_valueERKS4_mRm -_ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScanner27inner_get_next_row_directlyERPKNS0_10ObDatumRowERbS6_ -_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE19prefetch_index_treeEv +_ZN9oceanbase8memtable22ObMemtableScanIterator18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowE +_ZN9oceanbase8memtable9ObReadRow11iterate_rowERKNS_7storage16ObITableReadInfoERKNS_6common13ObStoreRowkeyERNS6_12ObIAllocatorERNS0_19ObMvccValueIteratorERNS_12blocksstable10ObDatumRowERNS0_11ObNopBitMapERl +_ZN9oceanbase12blocksstable11ObRowReader17read_memtable_rowEPKclRKNS_7storage16ObITableReadInfoERNS0_10ObDatumRowERNS_8memtable11ObNopBitMapERb +_ZN9oceanbase8memtable19ObMvccValueIterator13get_next_nodeERPKv +_ZN9oceanbase8memtable19ObMvccValueIterator4initERNS0_15ObMvccAccessCtxEPKNS0_13ObMemtableKeyEPNS0_9ObMvccRowERKNS_6common11ObQueryFlagE +_ZZN9oceanbase8memtable19ObMvccValueIterator4initERNS0_15ObMvccAccessCtxEPKNS0_13ObMemtableKeyEPNS0_9ObMvccRowERKNS_6common11ObQueryFlagEENK4$_94clEPKc +_ZN9oceanbase6common8ObLogger13need_to_printEmmi _ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEE19open_cur_data_blockERNS0_19ObSSTableReadHandleE -_ZThn336_N9oceanbase12blocksstable18ObMicroBlockReader4initERKNS0_16ObMicroBlockDataERKNS_7storage15ObTableReadInfoE -_ZThn336_N9oceanbase12blocksstable18ObMicroBlockReader10find_boundERKNS0_13ObDatumRowkeyEblRlRb -_ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScannerC2ERNS_6common12ObIAllocatorE -_ZN9oceanbase12blocksstable23ObIMicroBlockRowScannerC2ERNS_6common12ObIAllocatorE +_ZThn336_N9oceanbase12blocksstable18ObMicroBlockReader4initERKNS0_16ObMicroBlockDataERKNS_7storage16ObITableReadInfoE _ZThn336_N9oceanbase12blocksstable18ObMicroBlockReader10find_boundERKNS0_12ObDatumRangeElRlRbS5_S5_ -_ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScanner5reuseEv -_ZN9oceanbase3sql13ObTableScanOp22do_init_before_get_rowEv -_ZN9oceanbase3sql10ObSQLUtils23extract_pre_query_rangeERKNS0_12ObQueryRangeERNS_6common12ObIAllocatorERNS0_13ObExecContextERNS5_9ObSEArrayIPNS5_10ObNewRangeELl1ENS5_19ModulePageAllocatorELb0EEERKNS5_20ObDataTypeCastParamsE -_ZN9oceanbase6common13ObSEArrayImplIPNS_3sql12ObIDASTaskOpELl2ENS0_19ModulePageAllocatorELb0EED2Ev -_ZNK9oceanbase3sql12ObQueryRange20get_ss_tablet_rangesERNS_6common12ObIAllocatorERNS0_13ObExecContextERNS2_9ObSEArrayIPNS2_10ObNewRangeELl1ENS2_19ModulePageAllocatorELb0EEERKNS2_20ObDataTypeCastParamsE -_ZN9oceanbase6common13ObSEArrayImplIPNS0_10ObNewRangeELl1ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase6common13ObSEArrayImplINS0_10ObNewRangeELl1ENS0_19ModulePageAllocatorELb0EE9push_backERKS2_ -_ZNK9oceanbase3sql12ObQueryRange17get_tablet_rangesERNS_6common12ObIAllocatorERNS0_13ObExecContextERNS2_9ObSEArrayIPNS2_10ObNewRangeELl1ENS2_19ModulePageAllocatorELb0EEERbRKNS2_20ObDataTypeCastParamsE -_ZN9oceanbase3sql8ObDASRef13find_das_taskEPKNS0_14ObDASTabletLocENS0_11ObDASOpTypeE -_ZN9oceanbase3sql13ObTableScanOp25prepare_single_scan_rangeEl -_ZN9oceanbase3sql8ObDASRef16execute_all_taskEv -_ZN9oceanbase3sql12ObIDASTaskOp14start_das_taskEv -_ZN9oceanbase3sql11ObDASScanOp7open_opEv -_ZN9oceanbase3sql11ObDASScanOp23reset_access_datums_ptrEv -_ZN9oceanbase6common13ObSEArrayImplImLl4ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayImEE -_ZNK9oceanbase3sql12ObQueryRange24direct_get_tablet_rangesERNS_6common12ObIAllocatorERNS0_13ObExecContextERNS2_9ObSEArrayIPNS2_10ObNewRangeELl1ENS2_19ModulePageAllocatorELb0EEERbRKNS2_20ObDataTypeCastParamsE -_ZN9oceanbase6common15ObKVGlobalCache3getElRKNS0_13ObIKVCacheKeyERPKNS0_15ObIKVCacheValueERPNS0_18ObKVMemBlockHandleE -_ZN9oceanbase5share11ObTenantEnv16get_tenant_localEv -_ZN9oceanbase6common13ObSEArrayImplImLl4ENS0_19ModulePageAllocatorELb0EE7reserveEl -_ZN9oceanbase7storage18ObSSTableRowGetter10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv -_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner10locate_keyERKNS0_13ObDatumRowkeyE -_ZN9oceanbase6common15ObFIFOAllocator4initEPNS0_12ObIAllocatorElRKNS_3lib9ObMemAttrElll -_ZN9oceanbase12blocksstable18ObBloomFilterCache11may_containEmRKNS0_12MacroBlockIdERKNS0_13ObDatumRowkeyERKNS0_19ObStorageDatumUtilsERb -_ZN9oceanbase6common17ObAtomicReference27dec_ref_cnt_and_inc_seq_numERj -_ZZN9oceanbase12blocksstable22ObIndexBlockRowScanner10locate_keyERKNS0_13ObDatumRowkeyEENK5$_835clEPKc -_ZZN9oceanbase8memtable10ObMemtable3getERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_12blocksstable13ObDatumRowkeyERPNS2_18ObStoreRowIteratorEENK5$_119clEPKc.llvm.5153181974068449544 -_ZNK9oceanbase7storage12ObTabletStat17check_need_reportEv -_ZZN9oceanbase12blocksstable22ObIndexBlockRowScanner12locate_rangeERKNS0_12ObDatumRangeEbbENK5$_844clEPKc +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder10find_boundERKNS0_13ObDatumRowkeyEblRlRb +_ZThn336_N9oceanbase12blocksstable18ObMicroBlockReader10find_boundERKNS0_13ObDatumRowkeyEblRlRb +_ZN9oceanbase12blocksstable23ObIMicroBlockFlatReader11find_bound_ERKNS0_13ObDatumRowkeyEbllRKNS0_19ObStorageDatumUtilsERlRb +_ZN9oceanbase12blocksstable11ObRowReader19compare_meta_rowkeyERKNS0_13ObDatumRowkeyERKNS0_19ObStorageDatumUtilsEPKclRi +_ZN9oceanbase12blocksstableL18nonext_ext_compareERKNS0_14ObStorageDatumES3_RKNS_6common9ObCmpFuncERi.llvm.15281195588870497899 _ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScanner4openERKNS0_12MacroBlockIdERKNS0_16ObMicroBlockDataEbb _ZN9oceanbase12blocksstable18ObMicroBlockReader10find_boundERKNS0_13ObDatumRowkeyEblRlRb -_ZN9oceanbase12blocksstable11ObRowReader19compare_meta_rowkeyERKNS0_13ObDatumRowkeyERKNS_7storage15ObTableReadInfoEPKclRi -_ZZN9oceanbase3sql13ObTableScanOp25prepare_single_scan_rangeElENK5$_197clEPKc -_ZN9oceanbase8memtable22ObMemtableScanIterator18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowE -_ZN9oceanbase8memtable13ObQueryEngine8IteratorINS_8keybtree13BtreeIteratorINS0_20ObStoreRowkeyWrapperEPNS0_9ObMvccRowEEEE11set_versionEl -_ZN9oceanbase8memtable9ObReadRow11iterate_rowERKNS_7storage15ObTableReadInfoERKNS_6common13ObStoreRowkeyERNS6_12ObIAllocatorERNS0_20ObIMvccValueIteratorERNS_12blocksstable10ObDatumRowERNS0_11ObNopBitMapERl -_ZN9oceanbase6common7ObDatum8from_objERKNS0_5ObObjE -_ZN9oceanbase8memtable19ObMvccValueIterator13get_next_nodeERPKv -_ZN9oceanbase12blocksstable11ObRowReader17read_memtable_rowEPKclRKNS_7storage15ObTableReadInfoERNS0_10ObDatumRowERNS_8memtable11ObNopBitMapERb -_ZN9oceanbase8memtable17ObMvccRowIterator12get_next_rowERPKNS0_13ObMemtableKeyERPNS0_19ObMvccValueIteratorERhb -_ZN9oceanbase8memtable19ObMvccValueIterator14lock_for_read_ERKNS_6common11ObQueryFlagE -_ZZN9oceanbase8memtable19ObMvccValueIterator4initERNS0_15ObMvccAccessCtxEPKNS0_13ObMemtableKeyEPNS0_9ObMvccRowERKNS_6common11ObQueryFlagEbENK4$_94clEPKc.llvm.13230429984244552792 -_ZN9oceanbase6common8ObLogger13need_to_printEmmi -_ZN9oceanbase8keybtree8IteratorINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE13set_key_rangeES3_bS3_bl -_ZN9oceanbase6common13ObObjCmpFuncs7compareERKNS0_5ObObjES4_NS0_15ObCollationTypeERi +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder10find_boundERKNS0_12ObDatumRangeElRlRbS5_S5_ +_ZNK9oceanbase8memtable13ObQueryEngine8IteratorINS_8keybtree13BtreeIteratorINS0_20ObStoreRowkeyWrapperEPNS0_9ObMvccRowEEEE9get_valueEv +_ZN9oceanbase6common19ModulePageAllocator5allocElRKNS_3lib9ObMemAttrE +_ZTWN9oceanbase6common13ObPageManager12tl_instance_E +_ZN9oceanbase3lib20ObTenantCtxAllocator5allocElRKNS0_9ObMemAttrE +_ZN9oceanbase3lib9ObjectMgr12alloc_objectEmRKNS0_9ObMemAttrE +_ZN9oceanbase8observer23ObProcessMallocCallbackclERKNS_3lib9ObMemAttrEl +_ZN9oceanbase12blocksstable18ObMicroBlockReader4initERKNS0_16ObMicroBlockDataERKNS_7storage16ObITableReadInfoE _ZN9oceanbase8keybtree8IteratorINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE8get_nextERS3_RS5_ -_ZN9oceanbase6common7ObDatum9obj2datumILNS0_17ObObjDatumMapTypeE1EEEvRKNS0_5ObObjE +_ZN9oceanbase7storage15ObMultipleMerge12get_next_rowERPNS_12blocksstable10ObDatumRowE +_ZN9oceanbase6common16ObArenaAllocator5reuseEv +_ZN9oceanbase7storage13ObSingleMerge22get_and_fuse_cache_rowEllRNS_12blocksstable10ObDatumRowERbS5_S5_ +_ZN9oceanbase7storage13ObSingleMerge13get_table_rowElRKNS_6common8ObIArrayIPNS0_8ObITableEEERNS_12blocksstable10ObDatumRowERbSC_ +_ZNK9oceanbase7storage16ObReadInfoStruct8is_validEv +_ZN9oceanbase7storage18ObStoreRowIterator4initERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv +_ZN9oceanbase8memtable10ObMemtable3getERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_12blocksstable13ObDatumRowkeyERPNS2_18ObStoreRowIteratorE +_ZN9oceanbase12blocksstable9ObSSTable3getERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS0_13ObDatumRowkeyERPNS2_18ObStoreRowIteratorE +_ZN9oceanbase7storage18ObSSTableRowGetter9fetch_rowERNS0_19ObSSTableReadHandleERPKNS_12blocksstable10ObDatumRowE +_ZThn336_N9oceanbase12blocksstable21ObMicroBlockGetReader7get_rowERKNS0_16ObMicroBlockDataERKNS0_13ObDatumRowkeyERKNS_7storage16ObITableReadInfoERNS0_10ObDatumRowE +_ZZN9oceanbase8memtable10ObMemtable3getERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_12blocksstable13ObDatumRowkeyERPNS2_18ObStoreRowIteratorEENK5$_110clEPKc.llvm.566553378672739064 +_ZN9oceanbase7storage13ObObjBufArray7reserveEl +_ZN9oceanbase8memtable19ObIMemtableIterator12get_next_rowERPKNS_12blocksstable10ObDatumRowE +_ZNK9oceanbase8memtable13ObQueryEngine8IteratorINS_8keybtree13BtreeIteratorINS0_20ObStoreRowkeyWrapperEPNS0_9ObMvccRowEEEE7get_keyEv +_ZNK9oceanbase3lib17ObMallocAllocator40get_tenant_ctx_allocator_without_tlcacheEmm +_ZN9oceanbase12blocksstable18ObMicroBlockReader14get_row_headerElRPKNS0_11ObRowHeaderE +_ZN9oceanbase7storage21ObFuseRowCacheFetcher18put_fuse_row_cacheERKNS_12blocksstable13ObDatumRowkeyERNS2_10ObDatumRowEl +_ZNK9oceanbase12blocksstable17ObFuseRowCacheKey13get_tenant_idEv +_ZN9oceanbase6common15ObKVGlobalCache3putINS0_18ObKVMemBlockHandleEEEiRNS0_15ObIKVCacheStoreIT_EElRKNS0_13ObIKVCacheKeyERKNS0_15ObIKVCacheValueERPSC_RPS3_b +_ZZN9oceanbase7storage15ObMultipleMerge20get_next_normal_rowsERllENK5$_468clEPKc +_ZN9oceanbase7storage18ObSSTableRowGetter10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv +_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner4openERKNS0_12MacroBlockIdERKNS0_16ObMicroBlockDataERKNS0_13ObDatumRowkeyEl +_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner4initERKNS_6common8ObIArrayIiEERKNS3_INS_5share6schema16ObColumnSchemaV2EEERKNS0_19ObStorageDatumUtilsERNS2_12ObIAllocatorERKNS2_11ObQueryFlagEl +_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner18init_by_micro_dataERKNS0_16ObMicroBlockDataE +_ZN9oceanbase7storage21ObIndexTreePrefetcher18check_bloom_filterERKNS_12blocksstable16ObMicroIndexInfoERNS0_19ObSSTableReadHandleE +_ZN9oceanbase3sql13ObTableScanOp22do_init_before_get_rowEv +_ZN9oceanbase3sql8ObDASRef13find_das_taskEPKNS0_14ObDASTabletLocENS0_11ObDASOpTypeE +_ZN9oceanbase3sql13ObTableScanOp25prepare_single_scan_rangeEl +_ZN9oceanbase11transaction17ObTxnFreeRouteCtx26init_before_handle_requestEPNS0_8ObTxDescE +_ZN9oceanbase3sql11ObResultSet4openEv +_ZZN9oceanbase3sql11ObResultSet19auto_end_plan_transERNS0_14ObPhysicalPlanEiRbENKUlPKcE3_clES6_ +_ZN9oceanbase8observer16ObMPPacketSender11get_sessionERPNS_3sql16ObSQLSessionInfoE +_ZN9oceanbase3sql18ObBasicSessionInfo38update_query_sensitive_system_variableERNS_5share6schema19ObSchemaGetterGuardE +_ZN9oceanbase3sql11ObResultSet5closeEv +_ZN9oceanbase3sql8ObDASCtx16is_partition_hitEv +_ZN9oceanbase3sql8ObDASRef16execute_all_taskEv +_ZN9oceanbase3sql11ObDASScanOp7open_opEv +_ZNK9oceanbase7storage16ObTableScanParam8is_validEv +_ZN9oceanbase6common15ObKVGlobalCache12get_instanceEv +_ZZN9oceanbase3sql13ObTableScanOp25prepare_single_scan_rangeElENK5$_197clEPKc +_ZZN9oceanbase8observer16ObMySQLResultSet14to_mysql_fieldERKNS_6common7ObFieldERNS_7obmysql12ObMySQLFieldEENK4$_65clEPKc +_ZN9oceanbase7storage21ObMicroBlockHandleMgr4initEbbRNS_6common12ObIAllocatorE +_ZN9oceanbase8memtable21ObMemtableGetIterator18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowE +_ZN9oceanbase8memtable11ObNopBitMap14set_nop_datumsEPNS_12blocksstable14ObStorageDatumE +_ZNK9oceanbase7storage16ObTableIterParam8is_validEv +_ZN9oceanbase8memtable13ObMemtableKey6encodeERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEEPKNS2_13ObStoreRowkeyE +_ZN9oceanbase3sql13ObExecContextD1Ev +_ZN9oceanbase3sql13ObExecContextD2Ev +_ZN9oceanbase3sql14ObDASBaseRtDefD2Ev +_ZN9oceanbase6common13ObSEArrayImplINS_11transaction6ObPairINS_5share6ObLSIDElEELl1ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase6common11ObArrayImplIPKNS0_8ObIArrayIlEENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS5_EENS0_22NotImplementItemEncodeIS5_EEED2Ev +_ZN9oceanbase6common11ObArrayImplINS_3sql19ObJoinFilterDataCtxENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev +_ZN9oceanbase3sql13ObTableScanOp7destroyEv +_ZN9oceanbase3sql8ObDASRef5resetEv +_ZN9oceanbase6common13ObSEArrayImplIPNS0_7ObDatumELl4ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase6common13ObSEArrayImplIPNS0_7ObDatumELl4ENS0_19ModulePageAllocatorELb0EE7destroyEv +_ZN9oceanbase3sql6ObStmtD2Ev +_ZN9oceanbase12blocksstable9ObSSTable19get_index_tree_rootERNS0_16ObMicroBlockDataEb _ZN9oceanbase7storage15ObAccessService10table_scanERNS_6common17ObVTableScanParamERPNS2_16ObNewRowIteratorE -_ZN9oceanbase7storage14ObTxTableGuardD2Ev +_ZNK9oceanbase7storage13ObLSTxService18get_read_store_ctxERKNS_11transaction16ObTxReadSnapshotEblRNS0_10ObStoreCtxE _ZN9oceanbase7storage10ObStoreCtx5resetEv -_ZZN9oceanbase11transaction14ObTransService23check_replica_readable_ERKNS_5share3SCNEbNS0_16ObTxReadSnapshot3SRCERKNS2_6ObLSIDElRKNS_6common10ObTabletIDERNS_7storage4ObLSEENK6$_1333clEPKc _ZN9oceanbase7storage11ObLSService6get_lsERKNS_5share6ObLSIDERNS0_10ObLSHandleENS0_10ObLSGetModE -_ZN9oceanbase7storage10ObLSHandle6set_lsERKNS0_7ObLSMapERNS0_4ObLSERKNS0_10ObLSGetModE -_ZN9oceanbase11transaction14ObTransService18get_read_store_ctxERKNS0_16ObTxReadSnapshotEblRNS_7storage10ObStoreCtxE -_ZN9oceanbase6common8ObLogger10get_loggerEv -_ZN9oceanbase11transaction14ObTransService19update_max_read_ts_EmRKNS_5share6ObLSIDENS2_3SCNE -_ZZN9oceanbase11transaction14ObTransService19update_max_read_ts_EmRKNS_5share6ObLSIDENS2_3SCNEENK6$_1483clEPKc -_ZZN9oceanbase11transaction14ObTransService18get_read_store_ctxERKNS0_16ObTxReadSnapshotEblRNS_7storage10ObStoreCtxEENK6$_1297clEPKc -_ZZN9oceanbase11transaction14ObTxVersionMgr18update_max_read_tsERKNS_5share3SCNEENKUlPKcE_clES7_ -_ZN9oceanbase12blocksstable13ObSSTableMeta19get_index_tree_rootERKNS_7storage15ObTableReadInfoERNS0_16ObMicroBlockDataEb -_ZNK9oceanbase7storage14ObMetaDiskAddr8is_validEv -_ZN9oceanbase7storage22ObMicroBlockDataHandle19get_data_block_dataERNS_12blocksstable18ObMacroBlockReaderERNS2_16ObMicroBlockDataE -_ZN9oceanbase7storage22ObMicroBlockDataHandle21get_loaded_block_dataERNS_12blocksstable16ObMicroBlockDataE -_ZZN9oceanbase7storage13ObSingleMerge18inner_get_next_rowERNS_12blocksstable10ObDatumRowEENK5$_400clEPKc -_ZN9oceanbase7storage21ObTenantTabletStatMgr11report_statERKNS0_12ObTabletStatE -_ZN9oceanbase8memtable12ObMvccEngine3getERNS0_15ObMvccAccessCtxERKNS_6common11ObQueryFlagEbPKNS0_13ObMemtableKeyEPS8_RNS0_19ObMvccValueIteratorE -_ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScanner4initERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextEPKNS0_9ObSSTableE -_ZN9oceanbase12blocksstable14ObFuseRowCache7put_rowERKNS0_17ObFuseRowCacheKeyERKNS0_19ObFuseRowCacheValueE -_ZN9oceanbase7storage17ObLSTabletService10table_scanERNS0_19ObTableScanIteratorERNS0_16ObTableScanParamE +_ZZN9oceanbase11transaction14ObTransService23check_replica_readable_ERKNS_5share3SCNEbNS0_16ObTxReadSnapshot3SRCERKNS2_6ObLSIDElRKNS_6common10ObTabletIDERNS_7storage4ObLSEENK6$_1349clEPKc +_ZN9oceanbase7storage17ObLSTabletService10table_scanERNS0_14ObTabletHandleERNS0_19ObTableScanIteratorERNS0_16ObTableScanParamE +_ZN9oceanbase7storage17ObLSTabletService16inner_table_scanERNS0_14ObTabletHandleERNS0_19ObTableScanIteratorERNS0_16ObTableScanParamE _ZN9oceanbase7storage19ObTableScanIterator4initERNS0_16ObTableScanParamERKNS0_14ObTabletHandleE +_ZNK9oceanbase7storage16ObRowkeyReadInfo17get_request_countEv _ZN9oceanbase7storage14ObMetaObjGuardINS0_8ObTabletEEaSERKS3_ -_ZN9oceanbase6common9PageArenaIcNS0_19ModulePageAllocatorEE5reuseEv -_ZN9oceanbase7storage20ObTableAccessContext24build_lob_locator_helperERNS0_16ObTableScanParamERKNS0_10ObStoreCtxERKNS_6common14ObVersionRangeE +_ZN9oceanbase7storage18ObTableAccessParam4initERKNS0_16ObTableScanParamERKNS0_14ObTabletHandleE +_ZN9oceanbase7storage19ObTableScanIterator21prepare_table_contextEv _ZN9oceanbase7storage19ObTableScanIterator9open_iterEv -_ZNK9oceanbase8memtable10ObMemtable8is_emptyEv _ZN9oceanbase7storage15ObMultipleMerge4initERKNS0_18ObTableAccessParamERNS0_20ObTableAccessContextERKNS0_15ObGetTableParamE _ZNK9oceanbase12blocksstable9ObSSTable8is_emptyEv -_ZNK9oceanbase7storage8ObITable11get_end_scnEv -_ZN9oceanbase12blocksstable20ObStorageDatumBuffer7reserveElb -_ZZN9oceanbase7storage15ObMultipleMerge4initERKNS0_18ObTableAccessParamERNS0_20ObTableAccessContextERKNS0_15ObGetTableParamEENK5$_431clEPKc -_ZN9oceanbase7storage8ObTablet15get_read_tablesElRNS0_20ObTableStoreIteratorEb +_ZNK9oceanbase8memtable10ObMemtable8is_emptyEv +_ZNK9oceanbase7storage15ObTableReadInfo11get_columnsEv +_ZNK9oceanbase7storage15ObTableReadInfo23get_group_idx_col_indexEv +_ZN9oceanbase7storage15ObMultipleMerge28prepare_tables_from_iteratorERNS0_20ObTableStoreIteratorEPKNS_6common10SampleInfoE +_ZNK9oceanbase8memtable10ObMemtable13get_start_scnEv +_ZN9oceanbase7storage20ObTableStoreIterator13get_ith_tableElRPNS0_8ObITableE +_ZN9oceanbase7storage8ObTablet15get_read_tablesElRNS0_21ObTabletTableIteratorEb +_ZN9oceanbase7storage8ObTablet20auto_get_read_tablesElRNS0_21ObTabletTableIteratorEb +_ZN9oceanbase7storage20ObTableStoreIterator5resetEv +_ZN9oceanbase7storage19ObStorageMetaHandle5resetEv +_ZN9oceanbase6common13ObSEArrayImplINS_12blocksstable18ObMacroBlockHandleELl1ENS0_19ModulePageAllocatorELb0EE7destroyEv +_ZN9oceanbase6common13ObSEArrayImplINS_7storage19ObStorageMetaHandleELl1ENS0_19ModulePageAllocatorELb0EE7destroyEv +_ZN9oceanbase7storage21ObTabletTableIterator31refresh_read_tables_from_tabletElbb +_ZNK9oceanbase5share3SCN14get_val_for_txEb +_ZN9oceanbase7storage15ObLobDataReaderC1Ev +_ZZN9oceanbase7storage15ObMultipleMerge4initERKNS0_18ObTableAccessParamERNS0_20ObTableAccessContextERKNS0_15ObGetTableParamEENK5$_428clEPKc +_ZN9oceanbase7storage8ObTablet16get_read_tables_ElRNS0_20ObTableStoreIteratorERNS0_19ObStorageMetaHandleEb +_ZNK9oceanbase7storage8ObITable20get_snapshot_versionEv +_ZNK9oceanbase7storage18ObTabletTableStore15get_read_tablesElRKNS0_8ObTabletERNS0_20ObTableStoreIteratorEb +_ZNK9oceanbase8memtable10ObMemtable11get_end_scnEv +_ZN9oceanbase7storage20ObTableStoreIterator10add_tablesERKNS0_14ObSSTableArrayEll +_ZN9oceanbase7storage20ObTableStoreIterator9add_tableEPNS0_8ObITableE +_ZN9oceanbase7storage19ObStorageMetaHandleD1Ev +_ZN9oceanbase7storage19ObStorageMetaHandleD2Ev +_ZN9oceanbase6common25ObConcurrentFIFOAllocator4freeEPv +_ZN9oceanbase6common15ObKVCacheHandleD1Ev +_ZN9oceanbase6common15ObKVCacheHandleD2Ev +_ZN9oceanbase7storage23ObSharedBlockReadHandleC1ERKS1_ +_ZN9oceanbase7storage23ObSharedBlockBaseHandleD2Ev +_ZN9oceanbase6common13ObSEArrayImplINS_12blocksstable18ObMacroBlockHandleELl1ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase7storage24ObStorageMetaValueHandleaSERKS1_ +_ZN9oceanbase7storage24ObStorageMetaValueHandle15set_cache_valueEPNS0_23ObStorageMetaCacheValueEPNS_6common12ObIAllocatorE +_ZN9oceanbase7storage19ObStorageMetaHandle11get_sstableERPNS_12blocksstable9ObSSTableE +_ZNK9oceanbase7storage18ObTabletTableStore24calculate_read_memtablesERKNS0_8ObTabletERNS0_20ObTableStoreIteratorE +_ZN9oceanbase7storage20ObTableStoreIterator10add_tablesERKNS0_15ObMemtableArrayEl +_ZN9oceanbase7storage18ObTabletTableStore12load_sstableERKNS0_14ObMetaDiskAddrERNS0_19ObStorageMetaHandleE +_ZN9oceanbase7storage18ObStorageMetaCache8get_metaENS0_18ObStorageMetaValue8MetaTypeERKNS0_16ObStorageMetaKeyERNS0_19ObStorageMetaHandleEPKNS0_8ObTabletE +_ZN9oceanbase6common25ObConcurrentFIFOAllocator5allocEl +_ZN9oceanbase6common21ObDiagnoseSessionInfo23get_local_diagnose_infoEv +_ZN9oceanbase7storage24ObStorageMetaValueHandle9new_valueERNS_6common12ObIAllocatorE +_ZNK9oceanbase7storage16ObStorageMetaKey8is_validEv +_ZN9oceanbase6common13ObVSliceAlloc5allocEl +_ZN9oceanbase7storage23ObSharedBlockReadHandleaSERKS1_ +_ZN9oceanbase7storage19ObStorageMetaHandle9get_valueERPKNS0_18ObStorageMetaValueE +_ZN9oceanbase7storage23ObSharedBlockBaseHandle4waitEv +_ZN9oceanbase6common13ObSEArrayImplINS_12blocksstable18ObMacroBlockHandleELl1ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZN9oceanbase3lib17ObMallocAllocator4freeEPv +_ZZN9oceanbase11transaction14ObTransService18get_read_store_ctxERKNS0_16ObTxReadSnapshotEblRNS_7storage10ObStoreCtxEENK6$_1312clEPKc +_ZN9oceanbase6common13ObSEArrayImplINS_7storage19ObStorageMetaHandleELl1ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZN9oceanbase6common9ObKVCacheINS_7storage16ObStorageMetaKeyENS2_18ObStorageMetaValueEE3getERKS3_RPKS4_RNS0_15ObKVCacheHandleE +_ZNK9oceanbase6common13ObIKVCacheKey4hashERm +_ZNK9oceanbase12blocksstable20ObMicroBlockCacheKey4hashEv +_ZNK9oceanbase7storage16ObStorageMetaKey4hashEv +_ZNK9oceanbase12blocksstable21ObBloomFilterCacheKey4hashEv +_ZN9oceanbase7storage17ObLSTabletService23get_tablet_with_timeoutERKNS_6common10ObTabletIDERNS0_14ObTabletHandleElNS0_18ObMDSGetTabletModeERKNS_5share3SCNE +_ZN9oceanbase7storage26ObTabletCreateDeleteHelper20check_and_get_tabletERKNS0_14ObTabletMapKeyERNS0_14ObTabletHandleElNS0_18ObMDSGetTabletModeEl +_ZN9oceanbase7storage26ObTabletCreateDeleteHelper10get_tabletERKNS0_14ObTabletMapKeyERNS0_14ObTabletHandleEl _ZN9oceanbase7storage18ObTenantMetaMemMgr10get_tabletERKNS0_18WashTabletPriorityERKNS0_14ObTabletMapKeyERNS0_14ObTabletHandleE -_ZN9oceanbase6common22ObBucketHashRLockGuardC2ERNS0_12ObBucketLockEm _ZN9oceanbase7storage19ObMetaPointerHandleINS0_14ObTabletMapKeyENS0_8ObTabletEED2Ev _ZN9oceanbase7storage16ObMetaPointerMapINS0_14ObTabletMapKeyENS0_8ObTabletEE26try_get_in_memory_meta_objERKS2_RNS0_19ObMetaPointerHandleIS2_S3_EERNS0_14ObMetaObjGuardIS3_EERb -_ZNK9oceanbase6common4hash9hash_funcINS_7storage14ObTabletMapKeyEEclERKS4_Rm -_ZN9oceanbase6common4hash11ObHashTableINS_7storage14ObTabletMapKeyENS1_11HashMapPairIS4_PNS3_20ObResourceValueStoreINS3_13ObMetaPointerINS3_8ObTabletEEEEEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstISC_EENS1_13SimpleAllocerINS1_15ObHashTableNodeISC_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE32internal_get_with_timeout_unsafeERNS1_17ObHashTableBucketISC_NS1_5NLockENS1_5NCondEEERKS4_RPKSC_l -_ZN9oceanbase6common12ObBucketLock6rdlockEml -_ZN9oceanbase7storage21ObTabletBindingHelper23check_snapshot_readableERNS0_14ObTabletHandleEl -_ZN9oceanbase7storage19ObMultipleScanMerge4openERKNS_12blocksstable12ObDatumRangeE -_ZN9oceanbase7storage19ObMultipleScanMerge15construct_itersEv -_ZN9oceanbase7storage26ObTabletCreateDeleteHelper20check_and_get_tabletERKNS0_14ObTabletMapKeyERNS0_14ObTabletHandleEl -_ZNK9oceanbase7storage18ObTabletTableStore13get_memtablesERNS_6common8ObIArrayIPNS0_8ObITableEEEb -_ZN9oceanbase7storage14ObTabletHandleaSERKS1_ -_ZN9oceanbase6common12TCRLockGuardC2ERKNS0_8TCRWLockE -_ZN9oceanbase6common13ObSEArrayImplIPNS_7storage8ObITableELl16ENS0_19ModulePageAllocatorELb0EE9push_backERKS4_ -_ZN9oceanbase7storage16ObTableScanRange12init_rowkeysERKNS_6common8ObIArrayINS2_10ObNewRangeEEERKNS2_11ObQueryFlagEPKNS_12blocksstable19ObStorageDatumUtilsE -_ZN9oceanbase6common26ObWrapperAllocatorWithAttr5allocEl -_ZN9oceanbase12blocksstable9ObSSTable4scanERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS0_12ObDatumRangeERPNS2_18ObStoreRowIteratorE -_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EEC2Ev -_ZN9oceanbase7storage21ObIndexTreePrefetcherC2Ev -_ZN9oceanbase7storage13ObMetaPointerINS0_8ObTabletEE17get_in_memory_objERNS0_14ObMetaObjGuardIS2_EE +_ZN9oceanbase6common4hash11ObHashTableINS_7storage14ObTabletMapKeyENS1_11HashMapPairIS4_PNS3_20ObResourceValueStoreINS3_13ObMetaPointerINS3_8ObTabletEEEEEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstISC_EENS1_13SimpleAllocerINS1_15ObHashTableNodeISC_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14get_refactoredERKS4_RSC_l _ZN9oceanbase7storage14ObMetaObjGuardINS0_8ObTabletEE7set_objERNS0_9ObMetaObjIS2_EE -_ZZN9oceanbase8observer16ObMySQLResultSet14to_mysql_fieldERKNS_6common7ObFieldERNS_7obmysql12ObMySQLFieldEENK4$_65clEPKc -_ZN9oceanbase6common13ObSEArrayImplINS_11transaction6ObPairINS_5share6ObLSIDElEELl1ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZN9oceanbase6common18ObBucketRLockGuardD2Ev +_ZN9oceanbase7storage8ObTablet24check_new_mds_with_cacheEl +_ZN9oceanbase7storage26ObTabletCreateDeleteHelper37check_read_snapshot_by_commit_versionERNS0_8ObTabletElllRKNS0_14ObTabletStatusE +_ZN9oceanbase6common7ObLatch6rdlockEjl +_ZZN9oceanbase3sql10ObFLTUtils22init_flt_log_frameworkERNS0_16ObSQLSessionInfoEbENK5$_537clEPKc.llvm.2295368030602757402 +_ZZNK9oceanbase3sql8ObOpSpec15create_operatorERNS0_13ObExecContextERPNS0_10ObOperatorEENK5$_126clEPKc.llvm.13047935995470522486 +_ZN9oceanbase7storage16ObTableScanRange12init_rowkeysERKNS_6common8ObIArrayINS2_10ObNewRangeEEERKNS2_11ObQueryFlagEPKNS_12blocksstable19ObStorageDatumUtilsE +_ZN9oceanbase3sql16ObDASTaskFactory7cleanupEv +_ZN9oceanbase3sql12ObIDASTaskOpD2Ev +_ZN9oceanbase7storage16ObTableScanParamD2Ev +_ZN9oceanbase6common13ObSEArrayImplINS0_10ObNewRangeELl4ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase12blocksstable14ObFuseRowCache7get_rowERKNS0_17ObFuseRowCacheKeyERNS0_20ObFuseRowValueHandleE +_ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScanner4initERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextEPKNS0_9ObSSTableE +_ZN9oceanbase7storage15ObTxTableGuards5reuseEv +_ZN9oceanbase7storage20ObTableAccessContext4initERNS0_16ObTableScanParamERNS0_10ObStoreCtxERKNS_6common14ObVersionRangeE +_ZN9oceanbase7storage8ObTablet34check_snapshot_readable_with_cacheEl +_ZN9oceanbase3sql5ObSql14after_get_planERNS0_14ObPlanCacheCtxERNS0_16ObSQLSessionInfoEPNS0_14ObPhysicalPlanEbPKNS_6common9Ob2DArrayINS8_10ObObjParamELi2079744ENS8_18ObWrapperAllocatorELb0ENS8_9ObSEArrayIPSA_Ll1ESB_Lb0EEEEEm +_ZN9oceanbase3lib9ObjectSet12alloc_objectEmRKNS0_9ObMemAttrE +_ZN9oceanbase3lib8BlockSet14get_free_blockEiRKNS0_9ObMemAttrE +_ZZN9oceanbase7storage15ObAccessService19check_read_allowed_ERKNS_5share6ObLSIDERKNS_6common10ObTabletIDENS0_17ObStoreAccessTypeERKNS0_16ObTableScanParamERNS1_15ObStoreCtxGuardENS2_3SCNEENK4$_49clEPKc.llvm.15219492201927549535 +_ZZN9oceanbase7storage8ObTablet24check_new_mds_with_cacheElENK6$_1305clEPKc +_ZN9oceanbase3sql14ObDASScanRtDefD1Ev +_ZN9oceanbase3sql14ObDASScanRtDefD2Ev +_ZN9oceanbase3sql10ObOperator4openEv +_ZN9oceanbase3sql13ObTableScanOp10inner_openEv +_ZN9oceanbase6common13ObSEArrayImplINS_7storage14ObMetaDiskAddrELl1ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZN9oceanbase11transaction14ObTransService18get_read_store_ctxERKNS0_16ObTxReadSnapshotEblRNS_7storage10ObStoreCtxE +_ZN9oceanbase7storage14ObTxTableGuardD2Ev +_ZN9oceanbase11transaction14ObTransService19update_max_read_ts_EmRKNS_5share6ObLSIDENS2_3SCNE +_ZN9oceanbase11transaction14ObTransService18check_ls_readable_ERNS_7storage4ObLSERKNS_5share3SCNENS0_16ObTxReadSnapshot3SRCE +_ZZN9oceanbase11transaction14ObTransService19update_max_read_ts_EmRKNS_5share6ObLSIDENS2_3SCNEENK6$_1499clEPKc +_ZN9oceanbase12blocksstable18ObMicroBlockReader22get_multi_version_infoEllRPKNS0_11ObRowHeaderERlS6_ +_ZN9oceanbase8observer11ObSrvXlator13get_processorERNS_3rpc9ObRequestE +_ZN9oceanbase3rpc5frame14ObReqProcessor4initEv +_ZZN9oceanbase7storage13ObSingleMerge18inner_get_next_rowERNS_12blocksstable10ObDatumRowEENK5$_397clEPKc +_ZN9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE4pushERKS3_ +_ZZN9oceanbase12blocksstable22ObIndexBlockRowScanner10locate_keyERKNS0_13ObDatumRowkeyEENK5$_832clEPKc +_ZNK9oceanbase3sql12ObQueryRange24direct_get_tablet_rangesERNS_6common12ObIAllocatorERNS0_13ObExecContextERNS2_9ObSEArrayIPNS2_10ObNewRangeELl1ENS2_19ModulePageAllocatorELb0EEERbRKNS2_20ObDataTypeCastParamsE +_ZN9oceanbase5share6schema19ObSchemaGetterGuard10check_privERKNS1_17ObSessionPrivInfoERKNS1_15ObStmtNeedPrivsE +_ZN9oceanbase6common10to_cstringINS0_12ObCurTraceId7TraceIdEEEPKcRKT_NS0_8BoolTypeILb0EEE +_ZN9oceanbase6common15databuff_printfEPclRlPKcz +_ZNK9oceanbase12blocksstable9ObSSTable8get_metaERNS0_19ObSSTableMetaHandleEPNS_6common20ObSafeArenaAllocatorE +_ZN9oceanbase7storage19ObTableScanIterator14init_scan_iterINS0_19ObMultipleScanMergeEEEiRPT_ +_ZN9oceanbase3lib9ObjectSet15add_free_objectEPNS0_7AObjectE +_ZN9oceanbase3sql11ObPlanCache8get_planERNS_6common12ObIAllocatorERNS0_14ObPlanCacheCtxERNS0_15ObCacheObjGuardE +_ZNK9oceanbase6common4hash18ObPointerHashArrayINS_5share6schema24ObSysVariableHashWrapperEPNS4_25ObSimpleSysVariableSchemaENS4_19ObGetSysVariableKeyEE14get_refactoredERKS5_RS7_ +_ZN9oceanbase3sql11ObPlanCache13get_cache_objERNS0_14ObILibCacheCtxEPNS0_14ObILibCacheKeyERNS0_15ObCacheObjGuardE +_ZZN9oceanbase3sql11ObPlanCache13get_cache_objERNS0_14ObILibCacheCtxEPNS0_14ObILibCacheKeyERNS0_15ObCacheObjGuardEENK5$_196clEPKc.llvm.3267000005131453400 +_ZN9oceanbase3sql21ObSqlParameterization11fast_parserERNS_6common12ObIAllocatorERKNS0_9FPContextERKNS2_8ObStringERNS0_18ObFastParserResultE +_ZN9oceanbase3sql16ObFastParserBase5parseERKNS_6common8ObStringERPcRlRP10_ParamListS8_ +_ZN9oceanbase3sql17ObFastParserMysql16parse_next_tokenEv +_ZN9oceanbase3sql17ObFastParserMysql18process_identifierEb +_ZN9oceanbase3sql16ObFastParserBase14process_numberEb +_Z17ob_strntoull_8bitPK13ObCharsetInfoPKcmiPPcPi +_ZN9oceanbase3sql16ObFastParserBase12is_utf8_charEl +_ZZN9oceanbase7storage8ObTablet34check_snapshot_readable_with_cacheElENK6$_1324clEPKc +_ZN9oceanbase3sql11ObResultSet8end_stmtEb +_ZN9oceanbase6common11ObAllocatorUt_10free_blockEPNS_3lib6ABlockE _ZN9oceanbase3sql8ObPCVSet19inner_get_cache_objERNS0_14ObILibCacheCtxEPNS0_14ObILibCacheKeyERPNS0_17ObILibCacheObjectE +_ZZN9oceanbase3sql16ObPlanCacheValue15resolver_paramsERNS0_14ObPlanCacheCtxENS0_4stmt8StmtTypeERKNS_6common8ObIArrayINS6_13ObCharsetTypeEEERKNS6_8ObBitSetILl256ENS6_19ModulePageAllocatorELb0EEESG_SG_RNS7_IPNS0_9ObPCParamEEEPNS6_9Ob2DArrayINS6_10ObObjParamELi2079744ENS6_18ObWrapperAllocatorELb0ENS6_9ObSEArrayIPSM_Ll1ESN_Lb0EEEEEENK5$_451clEPKc _ZN9oceanbase3sql9ObPlanSet17match_params_infoEPKNS_6common9Ob2DArrayINS2_10ObObjParamELi2079744ENS2_18ObWrapperAllocatorELb0ENS2_9ObSEArrayIPS4_Ll1ES5_Lb0EEEEERNS0_14ObPlanCacheCtxElRb _ZN9oceanbase3sql17ObPhysicalPlanCtx22init_datum_param_storeEv -_ZZN9oceanbase3sql16ObPlanCacheValue15resolver_paramsERNS0_14ObPlanCacheCtxENS0_4stmt8StmtTypeERKNS_6common8ObIArrayINS6_13ObCharsetTypeEEERKNS6_8ObBitSetILl256ENS6_19ModulePageAllocatorELb0EEESG_SG_RNS7_IPNS0_9ObPCParamEEEPNS6_9Ob2DArrayINS6_10ObObjParamELi2079744ENS6_18ObWrapperAllocatorELb0ENS6_9ObSEArrayIPSM_Ll1ESN_Lb0EEEEEENK5$_450clEPKc _ZN9oceanbase3sql16ObPlanCacheValue15resolver_paramsERNS0_14ObPlanCacheCtxENS0_4stmt8StmtTypeERKNS_6common8ObIArrayINS6_13ObCharsetTypeEEERKNS6_8ObBitSetILl256ENS6_19ModulePageAllocatorELb0EEESG_SG_RNS7_IPNS0_9ObPCParamEEEPNS6_9Ob2DArrayINS6_10ObObjParamELi2079744ENS6_18ObWrapperAllocatorELb0ENS6_9ObSEArrayIPSM_Ll1ESN_Lb0EEEEE -_Z16ob_numchars_8bitPK13ObCharsetInfoPKcS3_ -_ZZN9oceanbase3sql9ObPlanSet17match_params_infoEPKNS_6common9Ob2DArrayINS2_10ObObjParamELi2079744ENS2_18ObWrapperAllocatorELb0ENS2_9ObSEArrayIPS4_Ll1ES5_Lb0EEEEERNS0_14ObPlanCacheCtxElRbENK5$_570clEPKc -_ZN9oceanbase7storage19ObTableScanIterator14init_scan_iterINS0_19ObMultipleScanMergeEEEiRPT_ -_ZN9oceanbase12blocksstable22ObMicroBlockRowScanner4openERKNS0_12MacroBlockIdERKNS0_16ObMicroBlockDataEbb -_ZN9oceanbase12blocksstable19ObMicroBlockDecoder10find_boundERKNS0_13ObDatumRowkeyEblRlRb -_ZN9oceanbase12blocksstable19ObMicroBlockDecoder10find_boundERKNS0_12ObDatumRangeElRlRbS5_S5_ -_ZN9oceanbase12blocksstable18ObMicroBlockReader4initERKNS0_16ObMicroBlockDataERKNS_7storage15ObTableReadInfoE -_ZN9oceanbase7storage22ObMicroBlockDataHandle20get_index_block_dataERKNS0_15ObTableReadInfoERNS_12blocksstable16ObMicroBlockDataE -_ZN9oceanbase6common9ObKVCacheINS_12blocksstable17ObFuseRowCacheKeyENS2_19ObFuseRowCacheValueEE3putERKS3_RKS4_b -_ZNK9oceanbase12blocksstable19ObFuseRowCacheValue4sizeEv -_ZNK9oceanbase12blocksstable17ObFuseRowCacheKey4sizeEv -_ZN9oceanbase6common15ObKVGlobalCache3putINS0_18ObKVMemBlockHandleEEEiRNS0_15ObIKVCacheStoreIT_EElRKNS0_13ObIKVCacheKeyERKNS0_15ObIKVCacheValueERPSC_RPS3_b -_ZN9oceanbase6common11DefHashFuncINS0_19DatumHashCalculatorILNS0_9ObObjTypeE4ENS0_12ObMurmurHashEEEE4hashERKNS0_7ObDatumEmRm -_ZNK9oceanbase12blocksstable19ObFuseRowCacheValue9deep_copyEPclRPNS_6common15ObIKVCacheValueE -_ZNK9oceanbase12blocksstable17ObFuseRowCacheKey9deep_copyEPclRPNS_6common13ObIKVCacheKeyE _ZN9oceanbase3sql11ObResultSet7executeEv -_ZNK9oceanbase3sql8ObOpSpec15create_operatorERNS0_13ObExecContextERPNS0_10ObOperatorE -_ZNK9oceanbase3sql8ObOpSpec25create_operator_recursiveERNS0_13ObExecContextERPNS0_10ObOperatorE _ZNK9oceanbase3sql8ObOpSpec36link_sql_plan_monitor_node_recursiveERNS0_13ObExecContextERPNS0_13ObMonitorNodeE +_ZNK9oceanbase3sql8ObOpSpec25create_operator_recursiveERNS0_13ObExecContextERPNS0_10ObOperatorE +_ZNK9oceanbase6common16ObArenaAllocator4usedEv _ZZNK9oceanbase3sql8ObOpSpec25create_operator_recursiveERNS0_13ObExecContextERPNS0_10ObOperatorEENK5$_133clEPKc -_ZNK9oceanbase3sql8ObOpSpec35create_exec_feedback_node_recursiveERNS0_13ObExecContextE -_ZN9oceanbase3sql17ObSqlTransControl10start_stmtERNS0_13ObExecContextE -_ZN9oceanbase6common13ObSEArrayImplINS_11transaction6ObPairINS_5share6ObLSIDElEELl1ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase11transaction16ObTransStatistic26add_elr_enable_trans_countEml -_ZZNK9oceanbase11transaction14ObTxVersionMgr17get_max_commit_tsEbENKUlPKcE_clES3_ -_ZNK9oceanbase3sql15ObExprFrameInfo11alloc_frameERNS_6common12ObIAllocatorERKNS2_8ObIArrayIPcEERmRPS6_ -_ZN9oceanbase11transaction14ObTransService20get_ls_read_snapshotERNS0_8ObTxDescENS0_18ObTxIsolationLevelERKNS_5share6ObLSIDElRNS0_16ObTxReadSnapshotE -_ZN9oceanbase11transaction16ObLSTxLogAdapter8get_roleERbRl -_ZNK9oceanbase4palf14PalfHandleImpl8get_roleERNS_6common6ObRoleERlRb -_ZN9oceanbase6common8TCRWLock10RLockGuardC2ERS1_ -_ZN9oceanbase3lib11ObLockGuardINS_6common10ObSpinLockEED2Ev -_ZN9oceanbase6common12ObLatchMutex4lockEjl -_ZN9oceanbase11transaction12ObLSTxCtxMgr23in_leader_serving_stateEv -_ZN9oceanbase11transaction10ObTxCtxMgr17get_ls_tx_ctx_mgrERKNS_5share6ObLSIDERPNS0_12ObLSTxCtxMgrE -_ZN9oceanbase6common11ObQSyncLock10try_rdlockEv _ZN9oceanbase11transaction11ObTxELRUtil26refresh_elr_tenant_config_Ev +_ZNK9oceanbase3sql8ObOpSpec35create_exec_feedback_node_recursiveERNS0_13ObExecContextE +_ZN9oceanbase3sql8ObDASRefC1ERNS0_9ObEvalCtxERNS0_13ObExecContextE +_ZN9oceanbase3sql16ObDASTaskFactoryC1ERNS_6common12ObIAllocatorE +_ZN9oceanbase3sql16ObDASTaskFactoryC2ERNS_6common12ObIAllocatorE _ZN9oceanbase6common12ObThreadCond4initEi -_ZZNK9oceanbase3sql8ObOpSpec25create_operator_recursiveERNS0_13ObExecContextERPNS0_10ObOperatorEENK5$_129clEPKc -_ZZNK9oceanbase3sql8ObOpSpec15create_operatorERNS0_13ObExecContextERPNS0_10ObOperatorEENK5$_126clEPKc.llvm.5412658214590587803 -_ZZN9oceanbase11transaction14ObTransService23acquire_local_snapshot_ERKNS_5share6ObLSIDERNS2_3SCNEENK6$_1342clEPKc -_ZN9oceanbase11transaction7ObTsMgr7get_gtsEmPNS0_10ObTsCbTaskERNS_5share3SCNE -_ZN9oceanbase11transaction11ObGtsSource7get_gtsEPNS0_10ObTsCbTaskERl -_ZN9oceanbase11transaction7ObTsMgr23get_ts_source_info_opt_EmRNS0_19ObTsSourceInfoGuardEbb -_ZN9oceanbase3sql11ObResultSet8end_stmtEb +_ZNK9oceanbase3sql15ObExprFrameInfo11alloc_frameERNS_6common12ObIAllocatorERKNS2_8ObIArrayIPcEERmRPS6_ +_ZN9oceanbase3sql17ObSqlTransControl10start_stmtERNS0_13ObExecContextE +_ZN9oceanbase11transaction16ObTransStatistic26add_elr_enable_trans_countEml +_ZN9oceanbase12blocksstable18ObBloomFilterCache11may_containEmRKNS0_12MacroBlockIdERKNS0_13ObDatumRowkeyERKNS0_19ObStorageDatumUtilsERb +_ZN9oceanbase3sql16ObDASTaskFactoryD1Ev +_ZN9oceanbase3sql16ObDASTaskFactoryD2Ev MD5_Init -_ZN9oceanbase7storage8ObNopPos4initERNS_6common12ObIAllocatorEl -_ZN9oceanbase3sql12ObSqlPlanSet11select_planERNS0_14ObPlanCacheCtxERPNS0_17ObPlanCacheObjectE -_ZN9oceanbase3sql16ObCandiTabletLocD1Ev -_ZN9oceanbase3sql16ObCandiTabletLocD2Ev -_ZN9oceanbase3sql12ObSqlPlanSet15get_plan_normalERNS0_14ObPlanCacheCtxERPNS0_14ObPhysicalPlanE -_ZNK9oceanbase3sql14ObPlanCacheCtx20is_retry_for_dup_tblERb -_ZN9oceanbase6common13ObSEArrayImplIPNS_3sql15ObCandiTableLocELl2ENS0_19ModulePageAllocatorELb0EE9push_backERKS4_ -_ZN9oceanbase3sql14ObOptTabletLocD2Ev -_ZN9oceanbase3sql19ObPhyLocationGetter17get_phy_locationsERKNS_6common8ObIArrayINS0_15ObTableLocationEEERKNS0_14ObPlanCacheCtxERNS3_INS0_15ObCandiTableLocEEERb -_ZN9oceanbase6common13ObSEArrayImplINS_3sql16ObCandiTabletLocELl2ENS0_19ModulePageAllocatorELb1EE5resetEv -_ZN9oceanbase6common13ObSEArrayImplIPNS_3sql15ObCandiTableLocELl2ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase6common13ObSEArrayImplIPKNS_3sql15ObTableLocationELl2ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase3sql9ObLogPlan15select_replicasERNS0_13ObExecContextERKNS_6common8ObIArrayIPKNS0_15ObTableLocationEEERKNS4_6ObAddrERNS5_IPNS0_15ObCandiTableLocEEE -_ZN9oceanbase3sql9ObLogPlan22strong_select_replicasERKNS_6common6ObAddrERNS2_8ObIArrayIPNS0_15ObCandiTableLocEEERbb -_ZN9oceanbase3sql15ObCandiTableLoc17all_select_leaderERbRNS_6common6ObAddrE -_ZZN9oceanbase3sql19ObDASLocationRouter35nonblock_get_candi_tablet_locationsERKNS0_17ObDASTableLocMetaERKNS_6common8ObIArrayINS5_10ObTabletIDEEERKNS6_ImEESD_RNS6_INS0_16ObCandiTabletLocEEEENK5$_402clEPKc -_ZN9oceanbase3sql19ObDASLocationRouter35nonblock_get_candi_tablet_locationsERKNS0_17ObDASTableLocMetaERKNS_6common8ObIArrayINS5_10ObTabletIDEEERKNS6_ImEESD_RNS6_INS0_16ObCandiTabletLocEEE -_ZN9oceanbase5share19ObLSReplicaLocationD2Ev -_ZN9oceanbase6common13ObSEArrayImplINS_3sql16ObCandiTabletLocELl2ENS0_19ModulePageAllocatorELb1EE16prepare_allocateEl -_ZN9oceanbase3sql14ObOptTabletLoc33assign_with_only_readable_replicaERKmS3_RKNS_6common10ObTabletIDERKNS_5share12ObLSLocationE -_ZN9oceanbase5share19ObLSLocationService12nonblock_getElmRKNS0_6ObLSIDERNS0_12ObLSLocationE -_ZSt11_Hash_bytesPKvmm -_ZN9oceanbase5share17ObTabletLSService12nonblock_getEmRKNS_6common10ObTabletIDERNS0_6ObLSIDE -_ZN9oceanbase5share13ObTabletLSMap3getERKNS0_13ObTabletLSKeyERNS0_15ObTabletLSCacheE -_ZN9oceanbase5share19ObLSLocationService14get_from_cacheElmRKNS0_6ObLSIDERNS0_12ObLSLocationE -_ZZN9oceanbase3sql19ObPhyLocationGetter17get_phy_locationsERKNS_6common8ObIArrayINS0_15ObTableLocationEEERKNS0_14ObPlanCacheCtxERNS3_INS0_15ObCandiTableLocEEERbENK5$_358clEPKc -_ZNK9oceanbase11transaction7ObBLMgrINS0_7ObBLKeyENS0_9ObBLValueEE19check_in_black_listERKS2_Rb -_ZN9oceanbase6common6DCHashINS_11transaction7ObBLKeyELl128EE3getERKS3_RPNS0_11KeyHashNodeIS3_EE -_ZNK9oceanbase11transaction7ObBLKey4hashEv -_ZN9oceanbase6common6DCHashINS_11transaction7ObBLKeyELl128EE6Handle10search_preEmRPNS0_8HashNodeE -_ZN9oceanbase3sql8ObDASCtx19add_candi_table_locERKNS0_17ObDASTableLocMetaERKNS0_15ObCandiTableLocE -_ZN9oceanbase3sql8ObDASCtx17check_same_serverEPKNS0_14ObDASTabletLocE -_ZZN9oceanbase3sql8ObDASCtx19add_candi_table_locERKNS0_17ObDASTableLocMetaERKNS0_15ObCandiTableLocEENK4$_77clEPKc -_ZN9oceanbase5share12ObLSLocationD1Ev -_ZN9oceanbase5share12ObLSLocationD2Ev -_ZN9oceanbase6common6DCHashINS_11transaction7ObBLKeyELl128EE6Handle6retireEil -_ZN9oceanbase6common13ObSEArrayImplINS_3sql16ObCandiTabletLocELl2ENS0_19ModulePageAllocatorELb1EE7destroyEv -_ZN9oceanbase3sql13ObTableScanOp10inner_openEv -_ZN9oceanbase3sql14ObDASScanRtDef10init_pd_opERNS0_13ObExecContextERKNS0_14ObDASScanCtDefE -_ZN9oceanbase3sql8ObParser10is_pl_stmtERKNS_6common8ObStringEPbS6_ +_ZNK9oceanbase8observer9ObMPQuery11record_statENS_3sql4stmt8StmtTypeEl +_ZZN9oceanbase3sql8ObPCVSet19inner_get_cache_objERNS0_14ObILibCacheCtxEPNS0_14ObILibCacheKeyERPNS0_17ObILibCacheObjectEENK4$_86clEPKc +_ZN9oceanbase3sql10ObOperator10drain_exchEv _ZN9oceanbase3sql13ObTableScanOp16prepare_das_taskEv _ZN9oceanbase3sql8ObDASRef15create_das_taskEPKNS0_14ObDASTabletLocENS0_11ObDASOpTypeERPNS0_12ObIDASTaskOpE _ZN9oceanbase3sql16AllocDASOpHelperILi1EE5allocERNS_6common12ObIAllocatorERPNS0_12ObIDASTaskOpE -_ZZNK9oceanbase3sql15ObTableLocation20calculate_tablet_idsERNS0_13ObExecContextERKNS_6common9Ob2DArrayINS4_10ObObjParamELi2079744ENS4_18ObWrapperAllocatorELb0ENS4_9ObSEArrayIPS6_Ll1ES7_Lb0EEEEERNS4_8ObIArrayINS4_10ObTabletIDEEERNSE_ImEESJ_RKNS4_20ObDataTypeCastParamsEENK6$_1632clEPKc -_ZZN9oceanbase7storage15ObAccessService19check_read_allowed_ERKNS_5share6ObLSIDERKNS_6common10ObTabletIDENS0_17ObStoreAccessTypeERKNS0_16ObTableScanParamERNS1_15ObStoreCtxGuardENS2_3SCNEENK4$_35clEPKc.llvm.13786454927318888195 -_ZNK9oceanbase7obmysql12ObMySQLField15serialize_pro41EPclRl -_ZN9oceanbase12blocksstable23ObIMicroBlockRowScanner5reuseEv -_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEE10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv -_ZN9oceanbase8memtable10ObMemtable4scanERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_12blocksstable12ObDatumRangeERPNS2_18ObStoreRowIteratorE -_ZNK9oceanbase7obmysql13OMPKResheader9serializeEPclRl -_ZN9oceanbase6common11ObAllocator5allocElRKNS_3lib9ObMemAttrE -_ZN9oceanbase7storage31ObSSTableMultiVersionRowScanner10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv -_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE4initEiRNS_12blocksstable9ObSSTableERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPKv -_ZNK9oceanbase7storage8ObITable20get_snapshot_versionEv -_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner4initERKNS_6common8ObIArrayIiEERKNS3_INS_5share6schema16ObColumnSchemaV2EEEPKNS_7storage15ObTableReadInfoERNS2_12ObIAllocatorERKNS2_11ObQueryFlagEl -_ZN9oceanbase7storage21ObMicroBlockHandleMgr4initEbbRNS_6common12ObIAllocatorE -_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE15init_basic_infoEiRNS_12blocksstable9ObSSTableERNS0_20ObTableAccessContextEPKvRb -_ZN9oceanbase7storage11ObHandleMgrINS0_22ObMicroBlockDataHandleENS_12blocksstable20ObMicroBlockCacheKeyELl64EE4initEbbRNS_6common12ObIAllocatorE -_ZN9oceanbase7storage23ObReallocatedFixedArrayINS0_19ObSSTableReadHandleEE18prepare_reallocateEl -_ZZN9oceanbase7storage15ObMultipleMerge20get_next_normal_rowsERllENK5$_471clEPKc -_ZN9oceanbase6common11ObArrayImplINS_3sql16ObExprConstraintENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev -_ZN9oceanbase6common16ObFixedArrayImplINS_7storage19ObSSTableReadHandleENS0_12ObIAllocatorEE16prepare_allocateEl -_ZZN9oceanbase5share17ObTabletLSService15get_from_cache_EmRKNS_6common10ObTabletIDERNS0_15ObTabletLSCacheEENK5$_414clEPKc _ZN9oceanbase6common16ObKVCacheInstMap14get_cache_instERKNS0_16ObKVCacheInstKeyERNS0_19ObKVCacheInstHandleE -_ZN9oceanbase6common4hash11ObHashTableINS0_16ObKVCacheInstKeyENS1_11HashMapPairIS3_PNS0_13ObKVCacheInstEEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE32internal_get_with_timeout_unsafeERNS1_17ObHashTableBucketIS7_NS1_5NLockENS1_5NCondEEERKS3_RPKS7_l -_ZN9oceanbase12blocksstable22ObMicroBlockRowScanner4initERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextEPKNS0_9ObSSTableE -_ZN9oceanbase6common16ObFixedArrayImplINS_7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE22ObIndexTreeLevelHandleENS0_12ObIAllocatorEE16prepare_allocateEl -_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE22ObIndexTreeLevelHandleC2Ev -_ZZN9oceanbase11transaction14ObTransService11get_tx_ctx_ERKNS_5share6ObLSIDEPNS_7storage4ObLSERKNS0_9ObTransIDERPNS0_14ObPartTransCtxEENK6$_1312clEPKc -_ZN9oceanbase12blocksstable10ObDatumRow7reserveElb -_ZN9__gnu_cxx5__ops14_Iter_comp_valIN9oceanbase12blocksstable15ObDatumComparorINS3_13ObDatumRowkeyEEEEclIPKS5_S9_EEbT_RT0_ -_ZN9oceanbase6common16ObFixedArrayImplINS_7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE22ObIndexTreeLevelHandleENS0_12ObIAllocatorEE7reserveEl -_ZN9oceanbase6common16ObFixedArrayImplINS_7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE22ObIndexTreeLevelHandleENS0_12ObIAllocatorEE4initEl -_ZZN9oceanbase7storage19ObMultipleScanMerge15construct_itersEvENK5$_608clEPKc -_ZN9oceanbase6common11ObArrayImplINS_3sql9ObVarInfoENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev -_ZN9oceanbase6common11ObArrayImplINS_3sql22ObDDLSchemaVersionHintENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev -_ZN9oceanbase8memtable17ObMvccRowIterator4initERNS0_13ObQueryEngineERNS0_15ObMvccAccessCtxERKNS0_15ObMvccScanRangeERKNS_6common11ObQueryFlagE -_ZN9oceanbase8observer16ObMPPacketSender14send_ok_packetERNS_3sql16ObSQLSessionInfoERNS0_10ObOKPParamEPNS_7obmysql13ObMySQLPacketE -_ZN9oceanbase3lib11ObLockGuardINS_6common16ObRecursiveMutexEED2Ev -_ZN9oceanbase8observer16ObSrvMySQLXlator9translateERNS_3rpc9ObRequestERPNS2_5frame14ObReqProcessorE -_ZN9oceanbase3sql8ObSqlCtxC1Ev -_ZN9oceanbase8memtable13ObQueryEngine4scanEPKNS0_13ObMemtableKeyEbS4_blRPNS0_22ObIQueryEngineIteratorE -_ZNK9oceanbase3sql12ObQueryRange27get_result_value_with_rowidERKNS0_9ObKeyPartERNS_6common5ObObjERNS0_13ObExecContextERbPNS5_12ObIAllocatorE -_ZNK9oceanbase3sql12ObQueryRange16get_result_valueERNS_6common5ObObjERNS0_13ObExecContextEPNS2_12ObIAllocatorE -_ZN9oceanbase7storage15ObMultipleMerge4openEv -_ZN9oceanbase7storage15ObBlockRowStore5reuseEv -_ZN9oceanbase6common11ObArrayImplINS_3sql13ObMonitorHintENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev -_ZN9oceanbase6common12ObKVCacheMap3putERNS0_13ObKVCacheInstERKNS0_13ObIKVCacheKeyEPKNS0_13ObKVCachePairEPNS0_18ObKVMemBlockHandleEb -_ZN9oceanbase3sql17ObSqlTransControl21stmt_setup_savepoint_EPNS0_16ObSQLSessionInfoERNS0_8ObDASCtxEPNS0_17ObPhysicalPlanCtxEPNS_11transaction14ObTransServiceEl -_ZN9oceanbase3sqlL15build_tx_param_EPNS0_16ObSQLSessionInfoERNS_11transaction9ObTxParamEPKb -_ZZN9oceanbase7storage13ObSingleMerge22get_and_fuse_cache_rowEllRNS_12blocksstable10ObDatumRowERbS5_S5_ENK5$_393clEPKc -_ZN9oceanbase12blocksstable21ObMicroBlockRowGetter7get_rowERNS_7storage19ObSSTableReadHandleERPKNS0_10ObDatumRowERNS0_18ObMacroBlockReaderE -_ZN9oceanbase12blocksstable21ObMicroBlockGetReader7get_rowERKNS0_16ObMicroBlockDataERKNS0_13ObDatumRowkeyERKNS_7storage15ObTableReadInfoERNS0_10ObDatumRowE -_ZN9oceanbase6common11ObArrayImplIPNS_3sql12ObSortOpImpl13SortStoredRowENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS5_EENS0_22NotImplementItemEncodeIS5_EEED2Ev -_ZN9oceanbase6common11ObArrayImplINS_3sql18ObPCConstParamInfoENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev -_ZN9oceanbase3sql9ObPlanSet16match_constraintERKNS_6common9Ob2DArrayINS2_10ObObjParamELi2079744ENS2_18ObWrapperAllocatorELb0ENS2_9ObSEArrayIPS4_Ll1ES5_Lb0EEEEERb -_ZN9oceanbase3sql18ObBasicSessionInfo17save_trans_statusEv -_ZN9oceanbase12blocksstable23ObIMicroBlockRowScanner4openERKNS0_12MacroBlockIdERKNS0_16ObMicroBlockDataEbb -MD5 _ZNK9oceanbase8memtable13ObMemtableKey16dup_without_hashINS_6common12ObIAllocatorEEEiRPS1_RT_ -_ZNK9oceanbase6common8ObRowkey9deep_copyINS0_12ObIAllocatorEEEiRS1_RT_ -_ZN9oceanbase8memtable13ObQueryEngine11revert_iterEPNS0_22ObIQueryEngineIteratorE -_ZN9oceanbase3sql16ObChunkStoreUtil12alloc_dir_idERl -_ZN9oceanbase6common11ObArrayImplINS_3sql12ObPCPrivInfoENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev +_ZN9oceanbase6common26ObWrapperAllocatorWithAttr5allocEl +_ZN9oceanbase3sql8ObParser10is_pl_stmtERKNS_6common8ObStringEPbS6_ +_ZZNK9oceanbase3sql8ObOpSpec25create_operator_recursiveERNS0_13ObExecContextERPNS0_10ObOperatorEENK5$_129clEPKc _ZZNK9oceanbase8observer8ObMPBase16init_process_varERNS_3sql8ObSqlCtxERKNS2_15ObMultiStmtItemERNS2_16ObSQLSessionInfoEENK5$_335clEPKc -_ZN9oceanbase3sql12ObUDRItemMgr14UDRRefObjGuardINS0_9ObUDRItemEED2Ev -_ZN9oceanbase6common7ObDITlsINS0_24ObTraceEventRecorderBaseILl189ELl1200EEELm1EE12get_instanceEv -_ZN9oceanbase3sql16ObFastParserBase19append_no_param_sqlEv -_ZN9oceanbase11transaction8ObTxDesc18fetch_conflict_txsERNS_6common8ObIArrayINS0_16ObTransIDAndAddrEEE -_ZN9oceanbase6common11ObArrayImplINS_11transaction16ObTransIDAndAddrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEE7destroyEv -_ZN9oceanbase6common11ObArrayImplINS_11transaction16ObTransIDAndAddrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE7destroyEv -_ZN9oceanbase3sql16AllocInputHelperILi26EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecERPNS0_9ObOpInputE -_ZN9oceanbase3sql16ObSQLSessionInfo32check_global_read_only_privilegeEbRKNS0_11ObSqlTraitsE -_ZN9oceanbase12blocksstable19ObMicroBlockDecoder4initERKNS0_16ObMicroBlockDataERKNS_7storage15ObTableReadInfoE +_ZN9oceanbase3sql8ObDASRef14close_all_taskEv +_ZN9oceanbase3sql11ObDASScanOp10release_opEv +_ZN9oceanbase5share11ObTenantEnv16get_tenant_localEv +_ZN9oceanbase7storage19ObTableScanIterator27check_ls_offline_after_readEv +_ZN9oceanbase7storage15ObAccessService16revert_scan_iterEPNS_6common16ObNewRowIteratorE +_ZN9oceanbase6common18ObServerObjectPoolINS_7storage19ObTableScanIteratorEE13return_objectEPS3_ +_ZNK9oceanbase8memtable15ObMvccAccessCtx15is_read_valid__Ev +_ZN9oceanbase7storage19ObTableScanIterator5resetEv +_ZN9oceanbase7storage13ObSingleMergeD2Ev +_ZN9oceanbase7storage14ObTabletHandle5resetEv +_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEED1Ev +_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEED2Ev +_ZN9oceanbase12blocksstable22ObIndexBlockRowScannerD1Ev +_ZN9oceanbase12blocksstable22ObIndexBlockRowScannerD2Ev +_ZN9oceanbase7storage22ObMicroBlockDataHandleD1Ev +_ZN9oceanbase7storage22ObMicroBlockDataHandleD2Ev +_ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScannerD2Ev +_ZN9oceanbase6common13ObSEArrayImplINS_7storage19ObStorageMetaHandleELl1ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase6common16ObMultiModRefMgrINS_7storage10ObLSGetModEE3decES3_ +_ZZN9oceanbase11transaction14ObTransService16revert_store_ctxERNS_7storage10ObStoreCtxEENK6$_1339clEPKc +_ZN9oceanbase7storage19ObMultipleScanMergeD1Ev +_ZN9oceanbase7storage19ObMultipleScanMergeD2Ev +_ZN9oceanbase6common16ObArenaAllocator4freeEPv +_ZN9oceanbase8memtable22ObMemtableScanIteratorD2Ev +_ZN9oceanbase7storage18ObSSTableRowGetterD2Ev +_ZN9oceanbase6common16ObFixedArrayImplINS_5share6schema16ObColumnSchemaV2ENS0_12ObIAllocatorEED2Ev +_ZN9oceanbase12blocksstable19ObSSTableMetaHandleD2Ev +_ZN9oceanbase6common15ObFIFOAllocator5resetEv +_ZN9oceanbase6common15ObFIFOAllocatorD1Ev +_ZN9oceanbase6common15ObFIFOAllocatorD2Ev +_ZN9oceanbase7storage15ObLobDataReader5resetEv +_ZN9oceanbase7storage13ObVectorStoreD2Ev +_ZN9oceanbase7storage14ObMetaObjGuardINS0_8ObTabletEE9reset_objEv +_ZN9oceanbase3sql18ObPushdownOperator22reset_trans_info_datumEv +_ZZN9oceanbase3sql9ObPlanSet17match_params_infoEPKNS_6common9Ob2DArrayINS2_10ObObjParamELi2079744ENS2_18ObWrapperAllocatorELb0ENS2_9ObSEArrayIPS4_Ll1ES5_Lb0EEEEERNS0_14ObPlanCacheCtxElRbENK5$_571clEPKc +_ZN9oceanbase6common11ObArrayImplIPNS_3sql17ObChunkDatumStore9StoredRowENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS5_EENS0_22NotImplementItemEncodeIS5_EEED2Ev +_ZN9oceanbase7storage30ObSSTableMultiVersionRowGetter10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv +_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEE10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv +_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE8prefetchEv +_ZN9oceanbase6common20ObDiagnoseTenantInfo23get_local_diagnose_infoEv +_ZN9oceanbase7storage22ObMicroBlockDataHandle5resetEv +_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner4openERKNS0_12MacroBlockIdERKNS0_16ObMicroBlockDataERKNS0_12ObDatumRangeElbb +_ZN9oceanbase12blocksstable18ObMacroBlockHandle5resetEv +_ZN9oceanbase6common15ObKVCacheHandle5resetEv +_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner8get_nextERNS0_16ObMicroIndexInfoE +_ZN9oceanbase7storage21ObIndexTreePrefetcher19prefetch_block_dataERNS_12blocksstable16ObMicroIndexInfoERNS0_22ObMicroBlockDataHandleEb +_ZZN9oceanbase12blocksstable22ObIndexBlockRowScanner12locate_rangeERKNS0_12ObDatumRangeEbbENK5$_838clEPKc.llvm.14300313950225948111 +_ZN9oceanbase6common8ObLogger13need_to_printEmi +_ZN9oceanbase7storage21ObMicroBlockHandleMgr22get_micro_block_handleEmRKNS_12blocksstable16ObMicroIndexInfoEbRNS0_22ObMicroBlockDataHandleE +_ZN9oceanbase12blocksstable18ObIMicroBlockCache15get_cache_blockEmNS0_12MacroBlockIdEllRNS0_24ObMicroBlockBufferHandleE +_ZN9oceanbase6common12ObKVCacheMap3getElRKNS0_13ObIKVCacheKeyERPKNS0_15ObIKVCacheValueERPNS0_18ObKVMemBlockHandleE +_ZNK9oceanbase12blocksstable17ObFuseRowCacheKey4hashERm +_ZN9oceanbase6common11DefHashFuncINS0_19DatumHashCalculatorILNS0_9ObObjTypeE4ENS0_12ObMurmurHashEEEE4hashERKNS0_7ObDatumEmRm +_ZNK9oceanbase12blocksstable13ObDatumRowkey10murmurhashEmRKNS0_19ObStorageDatumUtilsERm +_ZNK9oceanbase6common13ObIKVCacheKey5equalERKS1_Rb +_ZNK9oceanbase12blocksstable20ObMicroBlockCacheKeyeqERKNS_6common13ObIKVCacheKeyE +_ZNK9oceanbase7storage16ObStorageMetaKeyeqERKNS_6common13ObIKVCacheKeyE +_ZZN9oceanbase12blocksstable22ObIndexBlockRowScanner12locate_rangeERKNS0_12ObDatumRangeEbbENK5$_841clEPKc.llvm.14300313950225948111 +_ZN9oceanbase7storage22ObMicroBlockDataHandle20get_index_block_dataERNS_12blocksstable16ObMicroBlockDataE +_ZN9oceanbase7storage22ObMicroBlockDataHandle21get_loaded_block_dataERNS_12blocksstable16ObMicroBlockDataE +_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE15init_basic_infoEiRNS_12blocksstable9ObSSTableERNS0_20ObTableAccessContextEPKvRb +_ZN9oceanbase6common16ObFixedArrayImplINS_7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE22ObIndexTreeLevelHandleENS0_12ObIAllocatorEE16prepare_allocateEl +_ZNK9oceanbase12blocksstable17ObFuseRowCacheKey5equalERKNS_6common13ObIKVCacheKeyERb +_ZNK9oceanbase12blocksstable13ObDatumRowkey23to_multi_version_rowkeyEbRNS_6common12ObIAllocatorERS1_ +_ZNK9oceanbase12blocksstable13ObDatumRowkey5equalERKS1_RKNS0_19ObStorageDatumUtilsERb +_ZN9oceanbase6common16ObFixedArrayImplINS_7storage19ObSSTableReadHandleENS0_12ObIAllocatorEE16prepare_allocateEl +_ZNK9oceanbase12blocksstable21ObBloomFilterCacheKeyeqERKNS_6common13ObIKVCacheKeyE +_ZN9oceanbase3sql12ObSqlPlanSet11select_planERNS0_14ObPlanCacheCtxERPNS0_17ObPlanCacheObjectE +_ZN9oceanbase3sql12ObSqlPlanSet15get_plan_normalERNS0_14ObPlanCacheCtxERPNS0_14ObPhysicalPlanE +_ZZN9oceanbase3sql19ObPhyLocationGetter17get_phy_locationsERKNS_6common8ObIArrayINS0_15ObTableLocationEEERKNS0_14ObPlanCacheCtxERNS3_INS0_15ObCandiTableLocEEERbENK5$_359clEPKc +_ZN9oceanbase6common13ObSEArrayImplINS_3sql16ObCandiTabletLocELl2ENS0_19ModulePageAllocatorELb1EED2Ev +_ZN9oceanbase3sql8ObDASCtx19add_candi_table_locERKNS0_17ObDASTableLocMetaERKNS0_15ObCandiTableLocE +_ZN9oceanbase6common6ObListIPNS_3sql13ObDASTableLocENS0_12ObIAllocatorEE9push_backERKS4_ +_ZNK9oceanbase3sql17ObDASTableLocMeta17init_related_metaEmRS1_ +_ZN9oceanbase3sql19ObPhyLocationGetter17get_phy_locationsERKNS_6common8ObIArrayINS0_15ObTableLocationEEERKNS0_14ObPlanCacheCtxERNS3_INS0_15ObCandiTableLocEEERb +_ZN9oceanbase3sql9ObLogPlan15select_replicasERNS0_13ObExecContextERKNS_6common8ObIArrayIPKNS0_15ObTableLocationEEERKNS4_6ObAddrERNS5_IPNS0_15ObCandiTableLocEEE +_ZNK9oceanbase3sql15ObTableLocation32calculate_candi_tablet_locationsERNS0_13ObExecContextERKNS_6common9Ob2DArrayINS4_10ObObjParamELi2079744ENS4_18ObWrapperAllocatorELb0ENS4_9ObSEArrayIPS6_Ll1ES7_Lb0EEEEERNS4_8ObIArrayINS0_16ObCandiTabletLocEEERKNS4_20ObDataTypeCastParamsE +_ZN9oceanbase5share19ObLSReplicaLocationD2Ev +_ZN9oceanbase3sql19ObDASLocationRouter35nonblock_get_candi_tablet_locationsERKNS0_17ObDASTableLocMetaERKNS_6common8ObIArrayINS5_10ObTabletIDEEERKNS6_ImEESD_RNS6_INS0_16ObCandiTabletLocEEE +_ZN9oceanbase8observer14global_contextEv +_ZN9oceanbase6common13ObSEArrayImplINS_5share19ObLSReplicaLocationELl3ENS0_19ModulePageAllocatorELb0EE7destroyEv +_ZN9oceanbase5share17ObTabletLSService12nonblock_getEmRKNS_6common10ObTabletIDERNS0_6ObLSIDE +_ZN9oceanbase5share19ObLSLocationService12nonblock_getElmRKNS0_6ObLSIDERNS0_12ObLSLocationE +_ZSt11_Hash_bytesPKvmm +_ZN9oceanbase6common13ObSEArrayImplINS_5share19ObLSReplicaLocationELl3ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayIS3_EE +_ZN9oceanbase3sql14ObOptTabletLoc33assign_with_only_readable_replicaERKmS3_RKNS_6common10ObTabletIDERKNS_5share12ObLSLocationE +_ZN9oceanbase6common6DCHashINS_11transaction7ObBLKeyELl128EE3getERKS3_RPNS0_11KeyHashNodeIS3_EE +_ZZN9oceanbase5share19ObLSLocationService15get_from_cache_ElmRKNS0_6ObLSIDERNS0_12ObLSLocationEENK5$_373clEPKc +_ZZN9oceanbase3sql19ObDASLocationRouter35nonblock_get_candi_tablet_locationsERKNS0_17ObDASTableLocMetaERKNS_6common8ObIArrayINS5_10ObTabletIDEEERKNS6_ImEESD_RNS6_INS0_16ObCandiTabletLocEEEENK5$_402clEPKc +_ZZNK9oceanbase3sql15ObTableLocation20calculate_tablet_idsERNS0_13ObExecContextERKNS_6common9Ob2DArrayINS4_10ObObjParamELi2079744ENS4_18ObWrapperAllocatorELb0ENS4_9ObSEArrayIPS6_Ll1ES7_Lb0EEEEERNS4_8ObIArrayINS4_10ObTabletIDEEERNSE_ImEESJ_RKNS4_20ObDataTypeCastParamsEENK6$_1630clEPKc +_ZNK9oceanbase3sql15ObTableLocation20calculate_tablet_idsERNS0_13ObExecContextERKNS_6common9Ob2DArrayINS4_10ObObjParamELi2079744ENS4_18ObWrapperAllocatorELb0ENS4_9ObSEArrayIPS6_Ll1ES7_Lb0EEEEERNS4_8ObIArrayINS4_10ObTabletIDEEERNSE_ImEESJ_RKNS4_20ObDataTypeCastParamsE +_ZZN9oceanbase3sql8ObDASCtx19add_candi_table_locERKNS0_17ObDASTableLocMetaERKNS0_15ObCandiTableLocEENK4$_74clEPKc +_ZN9oceanbase6common13ObSEArrayImplINS_5share19ObLSReplicaLocationELl3ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZN9oceanbase6common16ObFixedArrayImplINS_7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE22ObIndexTreeLevelHandleENS0_12ObIAllocatorEE7reserveEl +_ZN9oceanbase3sql19DASRelatedTabletMap21add_related_tablet_idENS_6common10ObTabletIDEmS3_mm +_ZN9oceanbase3sql19ObDASLocationRouter22refresh_location_cacheEbi +_ZN9oceanbase3sql11ObResultSet20store_last_insert_idERNS0_13ObExecContextE +_ZN9oceanbase12blocksstable11ObRowReader11read_columnEPKcllRNS0_14ObStorageDatumE +_ZN9oceanbase5trace7ObTrace8end_spanEPNS0_9ObSpanCtxE +_ZN9oceanbase7storage15ObAccessService29get_source_ls_tx_table_guard_ERNS1_15ObStoreCtxGuardE +_ZN9oceanbase3lib17ObMallocAllocator12get_instanceEv +MD5 _ZNK9oceanbase3sql12ObQueryRange21gen_simple_scan_rangeERNS_6common12ObIAllocatorERNS0_13ObExecContextERNS2_9ObSEArrayIPNS2_10ObNewRangeELl1ENS2_19ModulePageAllocatorELb0EEERbRKNS2_20ObDataTypeCastParamsE -_ZN9oceanbase3sql24ObRelationalExprOperator7compareERNS_6common5ObObjERKS3_S6_RKNS2_12ObCompareCtxERNS2_15ObObjCastParamsENS2_7ObCmpOpE -_ZN9oceanbase6common13ObObjCmpFuncs7compareERNS0_5ObObjERKS2_S5_RKNS0_12ObCompareCtxENS0_7ObCmpOpERb -_ZN9oceanbase3sql24ObRelationalExprOperator16compare_nullsafeERlRKNS_6common5ObObjES6_RNS3_15ObObjCastParamsENS3_9ObObjTypeENS3_15ObCollationTypeE -_ZNK9oceanbase3sql12ObQueryRange21generate_single_rangeERNS1_13ObSearchStateElRPNS_6common10ObNewRangeERb -_ZN9oceanbase6common12ob_write_objINS0_12ObIAllocatorEEEiRT_RKNS0_5ObObjERS5_ -_ZNK9oceanbase6common8ObRowkeyeqERKS1_ -_ZN9oceanbase3sql12ObQueryRange13ObSearchState18tailor_final_rangeEl -_ZN9oceanbase3sql12ObQueryRange13ObSearchState17init_search_stateElbm -_ZN9oceanbase3sql12ObQueryRange13ObSearchStateC2ERNS_6common12ObIAllocatorE -_ZN9oceanbase3sql11ObSqlBitSetILl32ElLb0EEC2Ev -_ZN9oceanbase3sql11ObSqlBitSetILl32ElLb0EE20init_block_allocatorEv -_ZN9oceanbase6common9ob_mallocElRKNS_3lib7ObLabelE -_ZNK9oceanbase3sql12ObQueryRange20get_single_key_valueEPKNS0_9ObKeyPartERNS0_13ObExecContextERNS1_13ObSearchStateERKNS_6common20ObDataTypeCastParamsEl -_ZN9oceanbase6common13ObObjCmpFuncs16compare_nullsafeERKNS0_5ObObjES4_NS0_15ObCollationTypeE -_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE11ELS3_25EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE -_ZNK9oceanbase6common14ObTimeZoneInfo19get_timezone_offsetElRi -_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE0ELS3_25EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE -_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE25ELS3_11EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE -_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE25ELS3_0EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE -_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE11ELS3_11EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE -_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE0ELS3_11EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE -_ZN9oceanbase6common11ObObjCaster7to_typeERKNS0_12ObExpectTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS7_RPS8_ -_ZN9oceanbase3sql11ObSqlBitSetILl32ElLb0EED2Ev -_ZN9oceanbase6common16ObArenaAllocator5resetEv -_ZN9oceanbase6common7ob_freeEPv -_ZN9oceanbase3lib17ObMallocAllocator5allocElRKNS0_9ObMemAttrE +_ZNK9oceanbase3lib17ObMallocAllocator24get_tenant_ctx_allocatorEmm +_ZN9oceanbase6common11ObArrayImplIPNS_3sql12ObSortOpImpl13SortStoredRowENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS5_EENS0_22NotImplementItemEncodeIS5_EEED2Ev +_ZN9oceanbase3sql15ObTableModifyOp7destroyEv +_ZN9oceanbase3sql16ObChunkStoreUtil12alloc_dir_idERl +_ZZN9oceanbase11transaction14ObTxVersionMgr18update_max_read_tsERKNS_5share3SCNEENKUlPKcE_clES7_ _ZN9oceanbase6common11ObArrayImplIPNS_3sql21ObUserVarIdentRawExprENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS4_EENS0_17DefaultItemEncodeIS4_EEED2Ev -_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImmEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS4_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS4_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE5clearEv -_ZN9oceanbase6common11ObArrayImplINS_3sql18ObPCParamEqualInfoENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev -_ZZN9oceanbase5share19ObLSLocationService14get_from_cacheElmRKNS0_6ObLSIDERNS0_12ObLSLocationEENK5$_327clEPKc -_ZNK9oceanbase6common5ObObj32check_collation_free_and_compareERKS1_ -_ZN9oceanbase3sql17ObMergeDistinctOp10inner_openEv -_ZNK9oceanbase11transaction8ObTxDesc16has_extra_state_Ev -_ZN9oceanbase6common13ObSEArrayImplImLl8ENS0_19ModulePageAllocatorELb0EE7reserveEl -_ZZN9oceanbase11transaction30ObTransDeadlockDetectorAdapter36maintain_deadlock_info_when_end_stmtERNS_3sql13ObExecContextEbENK5$_753clEPKc.llvm.14122042739090680483 +_ZN9oceanbase6common11ObArrayImplINS_3sql9ObVarInfoENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev +_ZN9oceanbase3sql9ObPlanSet16match_constraintERKNS_6common9Ob2DArrayINS2_10ObObjParamELi2079744ENS2_18ObWrapperAllocatorELb0ENS2_9ObSEArrayIPS4_Ll1ES5_Lb0EEEEERb +_ZN9oceanbase6common11ObArrayImplINS_3sql22ObDDLSchemaVersionHintENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev +_ZN9oceanbase6common11ObArrayImplINS_3sql18ObPCConstParamInfoENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev _ZN9oceanbase3omt10ObThWorker20check_qtime_throttleEv -_ZThn336_N9oceanbase12blocksstable18ObMicroBlockReader14get_row_headerElRPKNS0_11ObRowHeaderE -_ZN9oceanbase6common11ObArrayImplINS_3sql9ObDopHintENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev -_ZN9oceanbase3sql16ObDASUpdIteratorD2Ev -_ZN9oceanbase3sql16AllocDASOpHelperILi4EE5allocERNS_6common12ObIAllocatorERPNS0_12ObIDASTaskOpE -_ZN9oceanbase3sql14ObExprValuesOp11inner_closeEv -_ZN9oceanbase12blocksstableL13get_offset_16EPKvl -_ZN9oceanbase3lib12SubObjectMgr11alloc_blockEmRKNS0_9ObMemAttrE -_ZN9oceanbase5obrpc18ObRpcProcessorBase15before_responseEi -_ZN9oceanbase5obrpc18ObRpcProcessorBase8responseEi -_ZN9oceanbase10logservice11ObLSAdapter16wait_append_syncERKNS_5share6ObLSIDE -_ZN9oceanbase7obmysql8ObSqlNio3runEl -_ZTWN9oceanbase6common7ObLatch17max_lock_slot_idxE -_ZN9oceanbase6common14ObTscTimestamp12current_timeEv -_ZTWN9oceanbase3lib6Thread8loop_ts_E -_ZN9oceanbase3lib7Threads12has_set_stopEv -_ZN9oceanbase7obmysql16ObSqlSockHandler11on_readableEPv -_ZN9oceanbase7obmysql19ObSqlSessionMemPool5allocEl -_ZN9oceanbase7obmysql24ObMysqlProtocolProcessor9do_spliceERNS_8observer14ObSMConnectionERNS0_12ObICSMemPoolERPvRb -_ZN9oceanbase7obmysql17ObMysqlPktContext5resetEv -_ZN9oceanbase6common18ob_read_regard_sslEiPvm -_ZN9oceanbase7obmysql24ObMysqlProtocolProcessor24process_one_mysql_packetERNS0_17ObMysqlPktContextEPNS0_21ObPacketRecordWrapperERNS0_12ObICSMemPoolElRPvRb -_ZN9oceanbase7obmysql9ObSqlSock16do_pending_writeERb -_ZN9oceanbase6common19ob_write_regard_sslEiPKvm -_ZN9oceanbase7obmysql24ObMysqlProtocolProcessor9do_decodeERNS_8observer14ObSMConnectionERNS0_12ObICSMemPoolERPKcS8_RPNS_3rpc8ObPacketERl -_ZN9oceanbase7obmysql11ObMySQLUtil9get_uint3ERPKcRj -_ZN9oceanbase7obmysql11ObMySQLUtil9get_uint1ERPKcRh -_ZN9oceanbase8observer12ObSrvDeliver7deliverERNS_3rpc9ObRequestE -_ZN9oceanbase3omt8ObTenant12recv_requestERNS_3rpc9ObRequestE -_ZN9oceanbase6common20ObTenantStatEstGuardD2Ev -_ZNK9oceanbase3omt13ObMultiTenant10get_tenantEmRPNS0_8ObTenantE -_ZN9oceanbase3rpc11RpcStatBulkILi10EE9add_pieceERKNS0_12RpcStatPieceE -_ZN9oceanbase3rpc11RpcStatItem9add_pieceERKNS0_12RpcStatPieceE +_ZNK9oceanbase7storage8ObITable11get_end_scnEv +_ZNK9oceanbase12blocksstable19ObFuseRowCacheValue4sizeEv +_ZN9oceanbase5obrpc18ObRpcProcessorBase14before_processEv +_ZN9oceanbase3sql23ObBasicNestedLoopJoinOp11inner_closeEv _ZN9oceanbase7obmysql21ObMySQLRequestManager11release_oldEl -_ZN9oceanbase6common25ObConcurrentFIFOAllocator4freeEPv +_ZN9oceanbase6common13ObVSliceAlloc13destroy_blockEPNS0_14ObBlockVSlicerE _ZN9oceanbase3sql17ObMergeDistinctOp20inner_get_next_batchEl _ZN9oceanbase3sql17ObMergeDistinctOp21deduplicate_for_batchEbPKNS0_11ObBatchRowsE -_ZN9oceanbase3sql17ObMergeDistinctOp7Compare14equal_in_batchEPKNS_6common8ObIArrayIPNS0_6ObExprEEEllRb -_ZN9oceanbase6common21ObNullSafeDatumStrCmpILNS0_15ObCollationTypeE45ELb0ELb0EE3cmpERKNS0_7ObDatumES6_Ri _ZL22ob_strnncollsp_utf8mb4PK13ObCharsetInfoPKhmS3_mb _ZN9oceanbase3sql17ObChunkDatumStore9StoredRow8do_buildILb0EEEiRPS2_RKNS_6common8ObIArrayIPNS0_6ObExprEEERNS0_9ObEvalCtxEPclj _ZN9oceanbase3sql17ObChunkDatumStore13row_copy_sizeERKNS_6common8ObIArrayIPNS0_6ObExprEEERNS0_9ObEvalCtxERl _Z27ob_strnncollsp_utf8mb4_helpPPKhmS1_mS1_S1_bPiS2_ -_ZN9oceanbase5share11ObTenantEnv3mtlIPNS_8memtable13ObLockWaitMgrEEET_v -_ZN9oceanbase6common13ObPageManager14set_tenant_ctxEll -_ZN9oceanbase5share6_SBaseD2Ev -_ZN9oceanbase6common18ObBucketRLockGuardD2Ev -_ZN9oceanbase6common12ObBucketLock6unlockEm +_ZN9oceanbase6common14ObTscTimestamp12current_timeEv +_ZN9oceanbase7obmysql8ObSqlNio3runEl +_ZN9oceanbase7obmysql16ObSqlSockHandler11on_readableEPv +_ZN9oceanbase8observer12ObSrvDeliver7deliverERNS_3rpc9ObRequestE +_ZN9oceanbase3omt8ObTenant12recv_requestERNS_3rpc9ObRequestE +_ZN9oceanbase6common16ObPriorityQueue2ILi1ELi2ELi3EE4pushEPNS0_6ObLinkEi +_ZN9oceanbase6common9SCondTempILi3EE6signalEji +_ZN9oceanbase6common16ObPriorityQueue2ILi0ELi1ELi0EE4pushEPNS0_6ObLinkEi +_ZN9oceanbase8observer12ObSrvDeliver19deliver_rpc_requestERNS_3rpc9ObRequestE +_ZNK9oceanbase3omt13ObMultiTenant10get_tenantEmRPNS0_8ObTenantE +_ZN9oceanbase3rpc25get_stat_srv_by_tenant_idEm +_ZN9oceanbase6common14ObTscTimestamp12get_instanceEv _Z12ob_free_hookPvPKv -_ZN9oceanbase3sql16ObHashDistinctOp20inner_get_next_batchEl -_ZN9oceanbase6common12ObIAllocatorD2Ev -_ZN9oceanbase3sql16ObHashDistinctOp29do_unblock_distinct_for_batchEl -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE25calc_hash_value_for_batchERKNS_6common8ObIArrayIPNS0_6ObExprEEElPKNS0_11ObBitVectorEPmlSF_ -_ZN9oceanbase6common11DefHashFuncINS0_22DatumStrHashCalculatorILNS0_15ObCollationTypeE45ELb0ENS0_12ObMurmurHashELb0EEEE13hash_v2_batchEPmPNS0_7ObDatumEbRKNS_3sql11ObBitVectorElPKmb -_ZN9oceanbase6common9ObCharset4hashENS0_15ObCollationTypeEPKclmbPFmPKvmmE -_ZN9oceanbase6common12ObMurmurHash4hashEPKvmm -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE9end_roundEv -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE18get_next_partitionENS0_9InputSideE -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE38do_insert_batch_with_unique_hash_tableERKNS_6common8ObIArrayIPNS0_6ObExprEEEPmlPKNS0_11ObBitVectorERPSD_ -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE18set_distinct_batchERKNS_6common8ObIArrayIPNS0_6ObExprEEEPmlPKNS0_11ObBitVectorEPtRlRSD_ -_ZNK9oceanbase6common11ObAllocator4usedEv -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE13set_item_ptrsERKNS_6common8ObIArrayIPNS0_6ObExprEEElPmPKtlRNS0_11ObBitVectorE -_ZNSt14_Function_base13_Base_managerIZN9oceanbase3sql24ObHashPartInfrastructureINS2_14ObHashPartColsENS2_19ObHashPartStoredRowEE30update_mem_status_periodicallyEvEUllE_E10_M_managerERSt9_Any_dataRKS9_St18_Manager_operation -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE12process_dumpEbRb -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE30update_mem_status_periodicallyEv -_ZNSt17_Function_handlerIFblEZN9oceanbase3sql24ObHashPartInfrastructureINS2_14ObHashPartColsENS2_19ObHashPartStoredRowEE30update_mem_status_periodicallyEvEUllE_E9_M_invokeERKSt9_Any_dataOl -_ZN9oceanbase3sql30ObHashPartitionExtendHashTableINS0_14ObHashPartColsEE16check_and_extendEv -_ZN9oceanbase3sql17ObChunkDatumStore5resetEv -_ZN9oceanbase3sql20ObSqlMemMgrProcessor42update_max_available_mem_size_periodicallyEPNS_6common12ObIAllocatorESt8functionIFblEERb -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE17finish_insert_rowEv -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE21append_all_dump_partsEv -_ZN9oceanbase3sql16ObHashDistinctOp36init_hash_partition_infras_for_batchEv -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE17init_distinct_mapEl -_ZN9oceanbase6common14ObArrayHashMapINS_3sql14ObHashPartColsEiE5resetEv -_ZN9oceanbase3sql16ObHashDistinctOp26init_hash_partition_infrasEv -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE17init_default_partEPNS4_16ObIntraPartitionElli -_ZN9oceanbase3sql30ObHashPartitionExtendHashTableINS0_14ObHashPartColsEE4initEPNS_6common12ObIAllocatorElPNS0_20ObSqlMemMgrProcessorEllb -_ZN9oceanbase6common19ModulePageAllocator5allocEl -_ZN9oceanbase3sql30ObHashPartitionExtendHashTableINS0_14ObHashPartColsEE19create_bucket_arrayElRPNS_6common9Ob2DArrayIPS2_Li65408ENS4_19ModulePageAllocatorELb0ENS4_9ObSEArrayIPS6_Ll64ES7_Lb0EEEEE -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE4initEmbbblPNS0_20ObSqlMemMgrProcessorE -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE16init_mem_contextEm -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE16est_bucket_countEllll -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE19est_partition_countEv -_ZN9oceanbase3sql20ObSqlMemMgrProcessor4initEPNS_6common12ObIAllocatorEmlNS0_17ObPhyOperatorTypeEmPNS0_13ObExecContextE -_ZN9oceanbase6common9Ob2DArrayIPNS_3sql14ObHashPartColsELi65408ENS0_19ModulePageAllocatorELb0ENS0_9ObSEArrayIPS4_Ll64ES5_Lb0EEEE4initEl -_ZN9oceanbase6common9Ob2DArrayIPNS_3sql14ObHashPartColsELi65408ENS0_19ModulePageAllocatorELb0ENS0_9ObSEArrayIPS4_Ll64ES5_Lb0EEEE7reserveEl -_ZN9oceanbase6common9Ob2DArrayIPNS_3sql14ObHashPartColsELi65408ENS0_19ModulePageAllocatorELb0ENS0_9ObSEArrayIPS4_Ll64ES5_Lb0EEEE11set_defaultEl -_ZN9oceanbase3sql20ObPxEstimateSizeUtil11get_px_sizeEPNS0_13ObExecContextENS0_14PxOpSizeFactorElRl -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE19append_dumped_partsENS0_9InputSideE -_ZN9oceanbase3sql20ObSqlMemMgrProcessor4freeEl -_ZN9oceanbase6common10FixedHash2INS_3rpc14ObLockWaitNodeEE10quick_nextEPS3_ -_ULx86_64_init_local +_ZZN9oceanbase7obmysql12ObSqlNioImpl11revert_sockEPNS0_9ObSqlSockEENKUlPKcE1_clES5_ _ZNK10__cxxabiv117__class_type_info12__do_dyncastElNS0_10__sub_kindEPKS0_PKvS3_S5_RNS0_16__dyncast_resultE -_ZN9oceanbase5share13ObTenantSpace4rootEv -_ZN9oceanbase3sql12ObSortOpImpl4sortEv -_ZN9oceanbase3sql12ObSortOpImpl12ObAdaptiveQS4sortEll -_ZN9oceanbase3sql12ObSortOpImpl12ObAdaptiveQS4initERNS_6common8ObIArrayIPNS0_17ObChunkDatumStore9StoredRowEEERNS3_12ObIAllocatorEllRb -_ZN9oceanbase6common16ObFixedArrayImplINS_3sql12ObSortOpImpl7AQSItemENS0_12ObIAllocatorEE16prepare_allocateEl -_ZN9oceanbase3sql17ObChunkDatumStore8Iterator12reset_cursorEl -_ZN9oceanbase3sql12ObSortOpImpl12ObAdaptiveQSD2Ev -_ZN9oceanbase6common16ObFixedArrayImplINS_3sql12ObSortOpImpl7AQSItemENS0_12ObIAllocatorEE7reserveEl -_ZN9oceanbase6common16ObFixedArrayImplINS_3sql12ObSortOpImpl7AQSItemENS0_12ObIAllocatorEE4initEl -_ZN9oceanbase6common11ObAllocator5allocEl -_ZNK10__cxxabiv120__si_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE +_ZN9oceanbase11transaction14ObTransService17get_read_snapshotERNS0_8ObTxDescENS0_18ObTxIsolationLevelElRNS0_16ObTxReadSnapshotE +_ZN9oceanbase6common10ObFunctionIFbvEE8AbstractD2Ev +_ZN9oceanbase11transaction14ObTransService29sync_acquire_global_snapshot_ERNS0_8ObTxDescElRNS_5share3SCNERl +_ZN9oceanbase6common12ObLatchMutex6unlockEv +_ZN9oceanbase6common12ObLatchMutex4lockEjl +_ZN9oceanbase11transaction14ObTransService25acquire_global_snapshot__EllRNS_5share3SCNERlNS_6common10ObFunctionIFbvEEE +_ZN9oceanbase11transaction7ObTsMgr7get_gtsEmNS_6common13ObMonotonicTsEPNS0_10ObTsCbTaskERNS_5share3SCNERS3_ +_ZN9oceanbase6common11ObQSyncImpl11acquire_refEv +_ZN9oceanbase11transaction11ObGtsSource7get_gtsENS_6common13ObMonotonicTsEPNS0_10ObTsCbTaskERlRS3_ +_ZN9oceanbase11transaction11ObIDService10get_numberEllRlS2_ +_ZNK9oceanbase10logservice16ObLogHandlerBase8get_roleERNS_6common6ObRoleERl +_ZN9oceanbase6common8TCRWLock10RLockGuardC2ERS1_ +_ZTWN9oceanbase6common7ObLatch13current_locksE +_ZNK9oceanbase4palf14PalfHandleImpl8get_roleERNS_6common6ObRoleERlRb +_ZNK9oceanbase4palf8election12ElectionImpl8get_roleERNS_6common6ObRoleERl +_ZN9oceanbase5share19ObTenantSwitchGuard9switch_toEmb +_ZN9oceanbase5share25get_tenant_base_with_lockEmRNS_6common10ObLDHandleERPNS0_12ObTenantBaseERSt8functionIFiS3_EE +_ZNK9oceanbase3omt13ObMultiTenant27get_tenant_with_tenant_lockEmRNS_6common10ObLDHandleERPNS0_8ObTenantE +_ZN9oceanbase11transaction11ObIDService21submit_log_with_lock_Ell +_ZN9oceanbase6common4hash11ObHashTableImNS1_12ObReferedMapImNS_10rootserver14DRUnitStatInfoEE4ItemENS1_9hash_funcImEENS1_8equal_toImEENS7_6GetKeyENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi5ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv +_ULx86_64_init_local +_ZN9oceanbase3sql15ObResolverUtils13resolve_constEPK10_ParseNodeNS0_4stmt8StmtTypeERNS_6common12ObIAllocatorENS7_15ObCollationTypeESA_PKNS7_14ObTimeZoneInfoERNS7_10ObObjParamEbRNS7_8ObStringEsSA_PNS0_11ObSqlBitSetILl96ENS0_14ObExprInfoFlagELb1EEEmb +_ZL19ob_ismbchar_utf8mb4PK13ObCharsetInfoPKcS3_ +_Z14ob_numchars_mbPK13ObCharsetInfoPKcS3_ +_ZN9oceanbase8memtable12ObMvccEngine3getERNS0_15ObMvccAccessCtxERKNS_6common11ObQueryFlagEPKNS0_13ObMemtableKeyEPS8_RNS0_19ObMvccValueIteratorE +_ZN9oceanbase8memtable13ObQueryEngine3getEPKNS0_13ObMemtableKeyERPNS0_9ObMvccRowEPS2_ +_ZN9oceanbase6common17ObjHashCalculatorILNS0_9ObObjTypeE4ENS0_13ObDefaultHashENS0_5ObObjEE15calc_hash_valueERKS4_mRm +_ZN9oceanbase8memtable8ObMtHash9fill_pairEPNS0_10ObHashNodeES3_l +_ZNK9oceanbase6common8ObRowkey5equalERKS1_Rb _ZNK10__cxxabiv121__vmi_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE -_ULx86_64_tdep_trace -md5_block_asm_data_order -_ZN9oceanbase6common13ObLinkHashMapINS0_9ObIntWarpENS_11transaction14ObTsSourceInfoENS3_19ObTsSourceInfoAllocENS0_9RefHandleELl8EE4nextEPNS0_12LinkHashNodeIS2_EE -_Ux86_64_getcontext_trace _ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi32ELi3EE23check_data_infos_borderEllRKNS_12blocksstable13ObDatumRowkeyEb _ZNK9oceanbase12blocksstable13ObDatumRowkey7compareERKS1_RKNS0_19ObStorageDatumUtilsERi -_ZN9oceanbase12blocksstableL18nonext_ext_compareERKNS0_14ObStorageDatumES3_RKNS_6common9ObCmpFuncERi.llvm.6693482919459847865 _ZN9oceanbase7storage21ObMicroInfoComparator7compareERKNS_12blocksstable16ObMicroIndexInfoERKNS2_13ObDatumRowkeyE -_ZN9oceanbase11transaction30ObTransDeadlockDetectorAdapter36maintain_deadlock_info_when_end_stmtERNS_3sql13ObExecContextEb -_ZN9oceanbase11transaction30ObTransDeadlockDetectorAdapter33unregister_from_deadlock_detectorERKNS0_9ObTransIDENS1_14UnregisterPathE -_ZN9oceanbase5share8detector21ObDeadLockDetectorMgr14unregister_keyINS_11transaction9ObTransIDEEEiRKT_ -_ZN9oceanbase5share8detector13UserBinaryKey12set_user_keyINS_11transaction9ObTransIDEEEiRKT_ -_ZNK9oceanbase11transaction9ObTransID9serializeEPclRl -_ZN9oceanbase6common11ObArrayImplINS_11transaction16ObTransIDAndAddrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE6assignERKNS0_8ObIArrayIS3_EE -_ZN9oceanbase11transaction8ObTxDesc18reset_conflict_txsEv -_ZN9oceanbase6common12ObLatchMutex6unlockEv -_ZN9oceanbase5share8detector21ObDeadLockDetectorMgr15unregister_key_ERKNS1_13UserBinaryKeyE -_ZN9oceanbase6common13ObLinkHashMapINS_5share8detector13UserBinaryKeyENS3_19ObIDeadLockDetectorENS3_21ObDeadLockDetectorMgr16InnerAllocHandleENS0_9RefHandleELl8EE3getERKS4_RPS5_ -_ZN9oceanbase6common6QClock14enter_criticalEv -_ZN9oceanbase6common6DCHashINS_5share8detector13UserBinaryKeyELl8EE3getERKS4_RPNS0_11KeyHashNodeIS4_EE -_ZN9oceanbase6common6DCHashINS_5share8detector13UserBinaryKeyELl8EE6Handle10search_preEmRPNS0_8HashNodeE -_ZNK9oceanbase5share8detector13UserBinaryKey4hashEv -_ZN9oceanbase6common6DCHashINS_5share8detector13UserBinaryKeyELl8EE6Handle6retireEil -_ZN9oceanbase6common6DCHashINS_5share8detector13UserBinaryKeyELl8EE15do_pending_taskEPNS0_7DCArrayE -_ZN9oceanbase5share8detector21ObDeadLockDetectorMgr16DetectorRefGuardD1Ev -_ZN9oceanbase5share8detector21ObDeadLockDetectorMgr16DetectorRefGuardD2Ev -_ZN9oceanbase6common6DCHashINS_5share8detector13UserBinaryKeyELl8EE24alloc_and_init_cur_arrayEv -_ZN9oceanbase11transaction10ObTxCtxMgr38get_ls_min_uncommit_tx_prepare_versionERKNS_5share6ObLSIDERNS2_3SCNE +_ZNK10__cxxabiv120__si_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE +_ZN9oceanbase3sql12ObSortOpImpl4sortEv +_ZN9oceanbase3sql12ObSortOpImpl12ObAdaptiveQS4initERNS_6common8ObIArrayIPNS0_17ObChunkDatumStore9StoredRowEEERNS3_12ObIAllocatorEllRb +_ZN9oceanbase6common16ObFixedArrayImplINS_3sql12ObSortOpImpl7AQSItemENS0_12ObIAllocatorEE16prepare_allocateEl +_ZN9oceanbase6common11ObAllocator4freeEPv +_ZN9oceanbase6common16ObFixedArrayImplINS_3sql12ObSortOpImpl7AQSItemENS0_12ObIAllocatorEE7reserveEl +_ZN9oceanbase6common11ObAllocator5allocEl +_ZN9oceanbase7storage19ObMultipleScanMerge4openERKNS_12blocksstable12ObDatumRangeE +_ZNK9oceanbase7storage18ObSimpleRowsMergerINS0_24ObScanMergeLoserTreeItemENS0_23ObScanMergeLoserTreeCmpEE9is_initedEv +_ZNK9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE9is_initedEv +_ZZN9oceanbase7storage19ObMultipleScanMerge15construct_itersEvENK5$_604clEPKc.llvm.9905903974153443566 +_ZN9oceanbase7storage19ObMultipleScanMerge15construct_itersEv +_ZN9oceanbase12blocksstable9ObSSTable4scanERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS0_12ObDatumRangeERPNS2_18ObStoreRowIteratorE +_ZN9oceanbase8memtable10ObMemtable4scanERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_12blocksstable12ObDatumRangeERPNS2_18ObStoreRowIteratorE +_ZN9oceanbase7storage18ObSimpleRowsMergerINS0_24ObScanMergeLoserTreeItemENS0_23ObScanMergeLoserTreeCmpEE4initElRNS_6common12ObIAllocatorE +_ZN9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE4initElRNS0_12ObIAllocatorE +_ULx86_64_tdep_trace +_ZN9oceanbase3sql12ObIDASTaskOp14start_das_taskEv +_ZN9oceanbase3sql13ObDASDeleteOp7open_opEv +_ZN9oceanbase3sql20ObDASIndexDMLAdaptorILi4ENS0_16ObDASDMLIteratorEE10write_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERKNS0_13ObDASDelCtDefERNS0_13ObDASDelRtDefERS2_Rl +_ZN9oceanbase7storage15ObAccessService11delete_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERNS_11transaction8ObTxDescERKNS0_14ObDMLBaseParamERKNS6_8ObIArrayImEEPNS6_16ObNewRowIteratorERl +_ZN9oceanbase3sql13ObDASInsertOp7open_opEv +_ZN9oceanbase3sql20ObDASIndexDMLAdaptorILi2ENS0_16ObDASDMLIteratorEE10write_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERKNS0_13ObDASInsCtDefERNS0_13ObDASInsRtDefERS2_Rl +_ZN9oceanbase7storage15ObAccessService11insert_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERNS_11transaction8ObTxDescERKNS0_14ObDMLBaseParamERKNS6_8ObIArrayImEEPNS6_16ObNewRowIteratorERl +_ZN9oceanbase6common16ObNewRowIterator13get_next_rowsERPNS0_8ObNewRowERl +_ZN9oceanbase3sql16ObDASDMLIterator12get_next_rowERPNS_6common8ObNewRowE +_ZZN9oceanbase3sql16ObDASDMLIterator12get_next_rowERPNS_6common8ObNewRowEENK5$_125clEPKc +_ZN9oceanbase7storage17ObLSTabletService11delete_rowsERNS0_14ObTabletHandleERNS0_10ObStoreCtxERKNS0_14ObDMLBaseParamERKNS_6common8ObIArrayImEEPNS9_16ObNewRowIteratorERl +_ZN9oceanbase7storage8ObTablet10update_rowERNS0_15ObRelativeTableERNS0_10ObStoreCtxERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS7_IlEERKNS0_10ObStoreRowESJ_PKNS7_INS_11transaction18ObEncryptMetaCacheEEE +_ZN9oceanbase7storage8ObTablet16prepare_memtableERNS0_15ObRelativeTableERNS0_10ObStoreCtxERPNS_8memtable10ObMemtableE +_ZN9oceanbase6common16ObArenaAllocatorD2Ev +_ZN9oceanbase7storage8ObTablet17prepare_param_ctxERNS_6common12ObIAllocatorERNS0_15ObRelativeTableERNS0_10ObStoreCtxERNS0_16ObTableIterParamERNS0_20ObTableAccessContextE +_ZN9oceanbase7storage19ObStorageTableGuard25refresh_and_protect_tableERNS0_15ObRelativeTableE +_ZN9oceanbase8memtable10ObMemtable15get_freeze_flagEv +_ZNK9oceanbase8memtable10ObMemtable18is_active_memtableEv +_ZN9oceanbase8memtable10ObMemtable20get_is_tablet_freezeEv +_ZNK9oceanbase8memtable10ObMemtable18is_frozen_memtableEv +_ZN9oceanbase8memtable10ObMemtable3setERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS9_IlEERKNS2_10ObStoreRowESL_PKNSA_13ObEncryptMetaE +_ZN9oceanbase8memtable10ObMemtable4set_ERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS2_10ObStoreRowEPSH_PKNS9_IlEE +_ZN9oceanbase12blocksstable11ObRowWriter5writeElRKNS_7storage10ObStoreRowEPKNS_6common8ObIArrayIlEERPcRl +_ZN9oceanbase8memtable10ObMemtable11mvcc_write_ERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextEPKNS0_13ObMemtableKeyERKNS0_11ObTxNodeArgERb +_ZN9oceanbase6common20ObGMemstoreAllocator11AllocHandle5allocEl +_ZN9oceanbase12blocksstable19ObDatumRowkeyHelperD2Ev +_ZN9oceanbase8memtable12ObMvccEngine9ensure_kvEPKNS0_13ObMemtableKeyEPNS0_9ObMvccRowE +_ZN9oceanbase6common13ObObjCmpFuncs7compareERKNS0_5ObObjES4_NS0_15ObCollationTypeERi +_ZN9oceanbase12blocksstable11ObRowWriter15inner_write_rowElRKNS_7storage10ObStoreRowEPKNS_6common8ObIArrayIlEE +_ZN9oceanbase12blocksstable13ObDatumRowkey11from_rowkeyERKNS_6common8ObRowkeyERNS0_20ObStorageDatumBufferE +_ZN9oceanbase12blocksstable9ObSSTable16check_row_lockedERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS0_13ObDatumRowkeyERNS2_19ObStoreRowLockStateE +_ZN9oceanbase12blocksstable11ObRowWriter18alloc_buf_and_initEb +_ZN9oceanbase8memtable12ObMvccEngine10mvcc_writeERNS0_14ObIMemtableCtxENS_18concurrent_control11ObWriteFlagERKNS_11transaction12ObTxSnapshotERNS0_9ObMvccRowERKNS0_11ObTxNodeArgERNS0_17ObMvccWriteResultE +_ZN9oceanbase8memtable12ObMvccEngine14build_tx_node_ERNS0_14ObIMemtableCtxERKNS0_11ObTxNodeArgERPNS0_15ObMvccTransNodeE +_ZN9oceanbase8memtable9ObMvccRow10mvcc_writeERNS0_14ObIMemtableCtxENS_18concurrent_control11ObWriteFlagERKNS_11transaction12ObTxSnapshotERNS0_15ObMvccTransNodeERNS0_17ObMvccWriteResultE +_ZN9oceanbase8memtable12ObMvccEngine9create_kvEPKNS0_13ObMemtableKeyEPS2_RPNS0_9ObMvccRowERNS0_15RowHeaderGetterERb +_ZN9oceanbase6common20ObGMemstoreAllocator5allocERNS1_11AllocHandleEl +_ZN9oceanbase8memtable10ObMemtable13need_for_saveEPKNS_5share13ObEncryptMetaE +_ZN9oceanbase8memtable10ObIMvccCtx22register_row_commit_cbEPKNS0_13ObMemtableKeyEPNS0_9ObMvccRowEPNS0_15ObMvccTransNodeElPKNS0_9ObRowDataEPNS0_10ObMemtableEll +_ZN9oceanbase8memtable18ObTransCallbackMgr14callback_allocEl +_ZN9oceanbase6common15ObFIFOAllocator5allocEl +_ZN9oceanbase6common12ObSliceAlloc5allocEv +_ZN9oceanbase7storage8ObTablet25try_update_storage_schemaEllRNS_6common12ObIAllocatorEl +_ZNK9oceanbase3omt17ObTenantConfigMgr27get_tenant_config_with_lockEmmm +_ZN9oceanbase8memtable18ObTransCallbackMgr6appendEPNS0_16ObITransCallbackE +_ZN9oceanbase8memtable16ObTxCallbackList15append_callbackEPNS0_16ObITransCallbackEb +_ZNK9oceanbase6common8ObRowkey9deep_copyINS0_12ObIAllocatorEEEiRS1_RT_ +_ZN9oceanbase7storage19ObStorageTableGuardD1Ev +_ZN9oceanbase7storage19ObStorageTableGuardD2Ev +_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi2ELi2EED2Ev +_ZN9oceanbase6common16ObFixedArrayImplINS_7storage30ObIndexTreeMultiPassPrefetcherILi2ELi2EE22ObIndexTreeLevelHandleENS0_12ObIAllocatorEED2Ev +_ZZN9oceanbase8memtable8ObMtHash6insertEPKNS0_20ObStoreRowkeyWrapperEPKNS0_9ObMvccRowEENKUlPKcE0_clES9_ +_ZN9oceanbase7storage19ObStorageTableGuard29check_freeze_to_inc_write_refEPNS0_8ObITableERbS4_ +_ZN9oceanbase8memtable10ObMemtable13inc_write_refEv +_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi2ELi2EEC2Ev +_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi2ELi2EEEED2Ev +_ZN9oceanbase8keybtree11WriteHandleINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE11split_childEPNS0_9BtreeNodeIS3_S5_EEiS3_S5_S3_S5_RS9_SA_l +_ZN9oceanbase8keybtree9BtreeNodeINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE4copyERS6_iii +_ZN9oceanbase8keybtree9BtreeNodeINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE15copy_and_insertERS6_iiiS3_S5_S3_S5_ +_ZN9oceanbase8keybtree18BtreeNodeAllocatorINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE10alloc_nodeEb +_ZZN9oceanbase8memtable10ObMemtable4set_ERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS2_10ObStoreRowEPSH_PKNS9_IlEEENK5$_256clEPKc +_ZN9oceanbase3sql12ObDMLService31check_local_index_affected_rowsEllRKNS0_17ObDASDMLBaseCtDefERNS0_17ObDASDMLBaseRtDefES4_S6_ +_ZN9oceanbase6common9PageArenaIcNS0_19ModulePageAllocatorEE9free_pageEPNS3_4PageE +_ZN9oceanbase7storage17ObLSTabletService11insert_rowsERNS0_14ObTabletHandleERNS0_10ObStoreCtxERKNS0_14ObDMLBaseParamERKNS_6common8ObIArrayImEEPNS9_16ObNewRowIteratorERl +_ZN9oceanbase7storage8ObTablet31insert_row_without_rowkey_checkERNS0_15ObRelativeTableERNS0_10ObStoreCtxERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS0_10ObStoreRowEPKNS7_INS_11transaction18ObEncryptMetaCacheEEE +_ZN9oceanbase8memtable10ObMemtable3setERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS2_10ObStoreRowEPKNSA_13ObEncryptMetaE +_ZN9oceanbase7storage19ObStorageTableGuardC1EPNS0_8ObTabletERNS0_10ObStoreCtxEbbNS_5share3SCNEb +_ZN9oceanbase7storage21ObTabletTableIteratorD2Ev +_ZN9oceanbase7storage10ObRowsInfo15check_duplicateEPNS0_10ObStoreRowElRNS0_15ObRelativeTableE +_ZN9oceanbase6common23ObReserveArenaAllocatorILl1024EE5allocEl +_ZN9oceanbase5share6schema19ObSchemaGetterGuardD1Ev +_ZN9oceanbase5share6schema19ObSchemaGetterGuardD2Ev +_ZN9oceanbase7storage20ObTableStoreIteratorD1Ev +_ZN9oceanbase7storage20ObTableStoreIteratorD2Ev +_ZN9oceanbase7storage17ObLSTabletService21insert_lob_tablet_rowERNS0_14ObTabletHandleERNS0_15ObDMLRunningCtxERNS0_10ObStoreRowE +_ZN9oceanbase7storage10ObRowsInfo11ExistHelper4initERKNS0_15ObRelativeTableERNS0_10ObStoreCtxERKNS0_16ObITableReadInfoERNS_6common23ObReserveArenaAllocatorILl1024EEE +_ZN9oceanbase12blocksstable13ObDatumRowkey11from_rowkeyERKNS_6common8ObRowkeyERNS2_12ObIAllocatorE +_ZN9oceanbase7storage8ObTablet14rowkeys_existsERNS0_10ObStoreCtxERNS0_15ObRelativeTableERNS0_10ObRowsInfoERb +_ZN9oceanbase8memtable10ObMemtable5existERNS_7storage10ObRowsInfoERbS5_ +_ZN9oceanbase7storage14ObTabletHandleD1Ev +_ZN9oceanbase7storage14ObTabletHandleD2Ev +_ZN9oceanbase7storage10ObRowsInfo18clear_found_rowkeyEl +_ZN9oceanbase11transaction16ObTransStatistic22add_read_elr_row_countEml +_ZN9oceanbase18concurrent_control28check_sequence_set_violationENS0_11ObWriteFlagElNS_11transaction9ObTransIDENS_12blocksstable9ObDmlFlagElS3_S5_l +_ZN9oceanbase12blocksstable18ObMacroBlockReaderD1Ev +_ZN9oceanbase12blocksstable18ObMacroBlockReaderD2Ev +_ZN9oceanbase7storage10ObRowsInfoC1Ev +_ZN9oceanbase6common13ObSEArrayImplIPNS_7storage8ObITableELl4ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZN9oceanbase7storage23ObSSTableRowLockChecker16check_row_lockedERNS0_19ObStoreRowLockStateE +_ZZN9oceanbase3sql20ObDASIndexDMLAdaptorILi2ENS0_16ObDASDMLIteratorEE12write_tabletERS2_RlENKUlPKcE_clES7_ +_ZZN9oceanbase3sql20ObDASIndexDMLAdaptorILi4ENS0_16ObDASDMLIteratorEE12write_tabletERS2_RlENKUlPKcE_clES7_ +_ZZN9oceanbase3sql20ObDASIndexDMLAdaptorILi2ENS0_16ObDASDMLIteratorEE12write_tabletERS2_RlENKUlPKcE3_clES7_ +_ZZN9oceanbase3sql20ObDASIndexDMLAdaptorILi4ENS0_16ObDASDMLIteratorEE12write_tabletERS2_RlENKUlPKcE3_clES7_ +_ZNK9oceanbase6common11ObFifoArena42get_writing_throttling_trigger_percentage_Ev +_ZN9oceanbase6common12ObSliceAlloc13prepare_blockEv +_ZN9oceanbase6common6QClock13try_quiescentERm +_ZN9oceanbase7storage10ObRowsInfoD1Ev +_ZN9oceanbase11transaction16ObTransStatistic12get_instanceEv +_ZNK9oceanbase6common11ObFifoArena14calc_mem_limitElll +_ZNK9oceanbase8memtable10ObMemtable13get_write_refEv +_ZN9oceanbase12blocksstable23ObIMicroBlockRowScannerC2ERNS_6common12ObIAllocatorE +_ZN9oceanbase8memtable12ObMvccEngine16check_row_lockedERNS0_15ObMvccAccessCtxEPKNS0_13ObMemtableKeyERNS_7storage19ObStoreRowLockStateE +_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi2ELi2EEEE18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowE +_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi2ELi2EEEE9fetch_rowERNS0_19ObSSTableReadHandleERPKNS_12blocksstable10ObDatumRowE +_ZN9oceanbase12blocksstable22ObMicroBlockRowScanner4initERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextEPKNS0_9ObSSTableE +_ZN9oceanbase12blocksstable26ObMicroBlockRowLockCheckerD2Ev +_ZN9oceanbase12blocksstable18ObMicroBlockReaderD2Ev +_ZN9oceanbase8keybtree11WriteHandleINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE9free_listEv +_ZN9oceanbase6common15ObDListWithLock3delEPNS0_7ObDLinkE +_ZN9oceanbase12blocksstable26ObMicroBlockRowLockChecker12get_next_rowERPKNS0_10ObDatumRowE +_ZN9oceanbase6common15ObLinearHashMapINS0_9ObIntWarpENS_11transaction9ObTransIDENS0_14ShareMemMgrTagEE7shrink_Ev +_ZN9oceanbase6common15ObLinearHashMapINS0_9ObIntWarpENS_11transaction9ObTransIDENS0_14ShareMemMgrTagEE23load_shrink_d_seg_bkts_EmmRPNS6_6BucketES9_ +_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE10ELS3_10EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE +_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi2ELi2EEEE19open_cur_data_blockERNS0_19ObSSTableReadHandleE +_ZN9oceanbase12blocksstable23ObIMicroBlockRowScanner14switch_contextERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextEPKNS0_9ObSSTableE +_ZN9oceanbase12blocksstable23ObIMicroBlockRowScanner5reuseEv +_ZN9oceanbase12blocksstable22ObMicroBlockRowScanner4openERKNS0_12MacroBlockIdERKNS0_16ObMicroBlockDataEbb +_ZN9oceanbase8memtable9ObMvccRow16check_row_lockedERNS0_15ObMvccAccessCtxERNS_7storage19ObStoreRowLockStateE +_ZN9oceanbase7storage17ObLSTabletService15get_read_tablesERKNS_6common10ObTabletIDElRNS0_21ObTabletTableIteratorEb +_ZN9oceanbase3lib20ObTenantCtxAllocator12get_obj_holdEPv +_ZN9oceanbase8memtable10ObMemtable24post_row_write_conflict_ERNS0_15ObMvccAccessCtxERKNS0_13ObMemtableKeyERNS_7storage19ObStoreRowLockStateEll +_ZN9oceanbase7storage17ObLSTabletService15create_memtableERKNS_6common10ObTabletIDElbNS_5share3SCNE +_ZN9oceanbase7storage13ObMetaPointerINS0_8ObTabletEE9reset_objEv +_ZNK9oceanbase3sql12ObQueryRange20get_single_key_valueEPKNS0_9ObKeyPartERNS0_13ObExecContextERNS1_13ObSearchStateERKNS_6common20ObDataTypeCastParamsEl +_ZN9oceanbase6common13ObObjCmpFuncs16compare_nullsafeERKNS0_5ObObjES4_NS0_15ObCollationTypeE +_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE11ELS3_25EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE +_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE0ELS3_25EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE +_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE11ELS3_11EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE +_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE25ELS3_11EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE +_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE25ELS3_0EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE +_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE0ELS3_11EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE +_ZN9oceanbase6commonL10number_intENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_m +_ZN9oceanbase12blocksstable18ObHexStringEncoder8traverseERb +_ZN9oceanbase8observer16ObSrvMySQLXlator9translateERNS_3rpc9ObRequestERPNS2_5frame14ObReqProcessorE +_ZN9oceanbase8observer9ObMPQueryC1ERKNS0_15ObGlobalContextE +_ZN9oceanbase3sql8ObSqlCtxC1Ev +md5_block_asm_data_order +_ZNK9oceanbase7obmysql12ObMySQLField15serialize_pro41EPclRl +_ZN9oceanbase8memtable13ObQueryEngine4scanEPKNS0_13ObMemtableKeyEbS4_blRPNS0_22ObIQueryEngineIteratorE +MD5_Final +_ZN9oceanbase7storage31ObSSTableMultiVersionRowScanner10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv +_ZN9oceanbase10compaction22ObPartitionMinorMerger15merge_partitionERNS0_16ObTabletMergeCtxElb +_ZNK9oceanbase7storage18ObSimpleRowsMergerINS_10compaction29ObPartitionMergeLoserTreeItemENS2_28ObPartitionMergeLoserTreeCmpEE5emptyEv +_ZN9oceanbase7storage18ObSimpleRowsMergerINS_10compaction29ObPartitionMergeLoserTreeItemENS2_28ObPartitionMergeLoserTreeCmpEE7rebuildEv +_ZTWN9oceanbase5share17ObTenantDagWorker5self_E +_ZN9oceanbase10compaction17ObPartitionMerger13set_base_iterERKNS_6common9ObSEArrayIPNS0_20ObPartitionMergeIterELl16ENS2_19ModulePageAllocatorELb0EEE +_ZN9oceanbase6common13ObSEArrayImplIlLl16ENS0_19ModulePageAllocatorELb0EE5reuseEv +_ZN9oceanbase10compaction22ObPartitionMinorMerger23merge_same_rowkey_itersERNS_6common9ObSEArrayIPNS0_20ObPartitionMergeIterELl16ENS2_19ModulePageAllocatorELb0EEE +_ZN9oceanbase10compaction17ObPartitionMerger7processERKNS_12blocksstable10ObDatumRowE +_ZN9oceanbase12blocksstable18ObMacroBlockWriter10append_rowERKNS0_10ObDatumRowEPKNS0_16ObMacroBlockDescE +_ZNK9oceanbase12blocksstable18ObMacroBlockWriter17is_keep_freespaceEv +_ZNK9oceanbase12blocksstable18ObMicroBlockWriter13get_row_countEv +_ZN9oceanbase10compaction22ObPartitionMinorMerger13inner_processERKNS_12blocksstable10ObDatumRowE +_ZN9oceanbase10compaction22ObPartitionMajorMerger13inner_processERKNS_12blocksstable10ObDatumRowE +_ZNK9oceanbase12blocksstable18ObMicroBlockWriter14get_block_sizeEv +_ZNK9oceanbase10compaction30ObPartitionMinorMacroMergeIter20get_curr_macro_blockERPKNS_12blocksstable16ObMacroBlockDescE +_ZN9oceanbase10compaction30ObPartitionMinorMacroMergeIter4nextEv +_ZN9oceanbase10compaction17ObPartitionMerger30get_base_iter_curr_macro_blockERPKNS_12blocksstable16ObMacroBlockDescE +_ZN9oceanbase12blocksstable18ObMacroBlockWriter10append_rowERKNS0_10ObDatumRowEl +_ZNK9oceanbase12blocksstable19ObMicroBlockEncoder14get_block_sizeEv +_ZN9oceanbase12blocksstable18ObMacroBlockWriter25append_row_and_hash_indexERKNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable18ObMacroBlockWriter13save_last_keyERKNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable18ObMacroBlockWriter13save_last_keyERKNS0_13ObDatumRowkeyE +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder10append_rowERKNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable19ObIMicroBlockWriter19cal_column_checksumERKNS0_10ObDatumRowEPl +_ZN9oceanbase6common11ObArrayImplINS_12blocksstable15ObConstDatumRowENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ +_ZN9oceanbase12blocksstable18ObMicroBlockWriter10append_rowERKNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable11ObRowWriter17inner_write_cellsINS0_14ObStorageDatumEEEiPKT_l +_ZN9oceanbase12blocksstable11ObRowWriter20write_col_in_clusterINS0_14ObStorageDatumEEEiPKT_lll +_ZN9oceanbase10compaction28ObPartitionMinorRowMergeIter4nextEv +_ZN9oceanbase10compaction30ObPartitionMinorMacroMergeIter10inner_nextEb +_ZN9oceanbase10compaction28ObPartitionMinorRowMergeIter35try_make_committing_trans_compactedEv +_ZNK9oceanbase12blocksstable19ObMicroBlockEncoder13get_row_countEv +_ZN9oceanbase6common13ObSEArrayImplIlLl16ENS0_19ModulePageAllocatorELb0EE9push_backERKl +_ZN9oceanbase10compaction30ObFlatMinorPartitionMergeFuser8fuse_rowERNS_6common9ObSEArrayIPNS0_20ObPartitionMergeIterELl16ENS2_19ModulePageAllocatorELb0EEE +_ZN9oceanbase10compaction22ObPartitionMinorMerger28move_and_remove_unused_itersERNS_6common9ObSEArrayIPNS0_20ObPartitionMergeIterELl16ENS2_19ModulePageAllocatorELb0EEES8_RNS2_8ObIArrayIlEE +_ZNK9oceanbase12blocksstable18ObMicroBlockWriter17get_original_sizeEv +_ZN9oceanbase6common11ObArrayImplINS_12blocksstable19ObColumnEncodingCtxENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ +_ZNK9oceanbase12blocksstable19ObMicroBlockEncoder17get_original_sizeEv +_ZN9oceanbase10compaction28ObPartitionMinorRowMergeIter21multi_version_compareERKNS0_20ObPartitionMergeIterERi +_ZN9oceanbase10compaction28ObPartitionMinorRowMergeIter25compare_multi_version_colERKNS0_20ObPartitionMergeIterElRi +_ZN9oceanbase12blocksstable18ObMacroBlockWriter17build_micro_blockEv +_ZN9oceanbase6common13ob_crc64_isalEmPKcl +_ZN9oceanbase12blocksstable24ObMicroBlockBufferHelper28compress_encrypt_micro_blockERNS0_16ObMicroBlockDescE +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder7get_rowElRNS0_10ObDatumRowE +_ZNK9oceanbase12blocksstable14ObConstDecoder6decodeERNS0_18ObColumnDecoderCtxERNS_6common5ObObjElRKNS0_11ObBitStreamEPKcl +_ZN9oceanbase12blocksstable19ObIntArrayFuncTable2atIhEElPKvl +_ZN9oceanbase12blocksstable19ObIntArrayFuncTable11lower_boundIhEElPKvlll +_ZNK9oceanbase12blocksstable14ObConstDecoder19decode_without_dictERKNS0_18ObColumnDecoderCtxERNS_6common5ObObjE +_ZNK9oceanbase12blocksstable13ObDictDecoder6decodeENS_6common9ObObjMetaERNS2_5ObObjEll +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder11build_blockERPcRl +_ZN9oceanbase12blocksstable19ObStringDiffEncoder14store_fix_dataERNS0_14ObBufferWriterE +_ZN9oceanbase6common11ObArrayImplIlNS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIlEENS0_22NotImplementItemEncodeIlEEE9push_backERKl +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder17encoder_detectionEv +_ZN9oceanbase6common11DefHashFuncINS0_19DatumHashCalculatorILNS0_9ObObjTypeE5ENS0_12ObMurmurHashEEEE4hashERKNS0_7ObDatumEmRm +_ZN9oceanbase6common11DefHashFuncINS0_22DatumStrHashCalculatorILNS0_15ObCollationTypeE45ELb0ENS0_12ObMurmurHashELb0EEEE4hashERKNS0_7ObDatumEmRm +_ZN9oceanbase6common9ObCharset4hashENS0_15ObCollationTypeEPKclmbPFmPKvmmE +_ZL16ob_mb_wc_utf8mb4PK13ObCharsetInfoPmPKhS4_ +_ZN9oceanbase6common12ObMurmurHash4hashEPKvmm +_ZN9oceanbase12blocksstable12ObRawEncoder14store_fix_dataERNS0_14ObBufferWriterE +_ZN9oceanbase12blocksstable14ObIntegerArrayIhE3setEll +_ZNK9oceanbase12blocksstable12ObRLEDecoder6decodeERNS0_18ObColumnDecoderCtxERNS_6common5ObObjElRKNS0_11ObBitStreamEPKcl +_ZN9oceanbase12blocksstable19ObIntArrayFuncTable11upper_boundIhEElPKvlll +_ZN9oceanbase12blocksstable24ObIntegerBaseDiffEncoder14store_fix_dataERNS0_14ObBufferWriterE +_ZNK9oceanbase12blocksstable24ObIntegerBaseDiffEncoder13ObIntegerDataIlE5deltaERKNS_6common7ObDatumE +_ZN9oceanbase12blocksstable19ObStringDiffEncoder10store_metaERNS0_14ObBufferWriterE +_ZNK9oceanbase12blocksstable16ObMicroBlockDesc8is_validEv +_ZN9oceanbase6common11ObArrayImplIPNS_12blocksstable19ObEncodingHashTableENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEE9push_backERKS4_ +_ZN9oceanbase12blocksstable18ObSelfBufferWriter12ensure_spaceEl +_ZNK9oceanbase12blocksstable13ObDictEncoder9calc_sizeEv +_ZN9oceanbase12blocksstable14ObConstEncoder10store_metaERNS0_14ObBufferWriterE +_ZNK9oceanbase12blocksstable13ObDictDecoder6decodeERNS0_18ObColumnDecoderCtxERNS_6common5ObObjElRKNS0_11ObBitStreamEPKcl +_ZN9oceanbase12blocksstable12ObRawEncoder10store_metaERNS0_14ObBufferWriterE +_ZNK9oceanbase12blocksstable12ObRawEncoder9calc_sizeEv +_ZN9oceanbase6common11ObArrayImplIPNS_12blocksstable16ObIColumnEncoderENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEE9push_backERKS4_ +_ZN9oceanbase6common25ObDataBlockCachePreWarmer5reuseEv +_ZN9oceanbase6common25ObDataBlockCachePreWarmer14reserve_kvpairERKNS_12blocksstable16ObMicroBlockDescEl +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder11try_encoderINS0_12ObRawEncoderEEEiRPNS0_16ObIColumnEncoderEl +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder13alloc_encoderINS0_12ObRawEncoderEEEPT_v +_ZN9oceanbase12blocksstable12ObRawEncoder8traverseEbRb +_ZN9oceanbase12blocksstable12ObRawEncoder4initERKNS0_19ObColumnEncodingCtxElRKNS_6common7ObArrayINS0_15ObConstDatumRowENS5_19ModulePageAllocatorELb0ENS5_22ObArrayDefaultCallBackIS7_EENS5_22NotImplementItemEncodeIS7_EEEE +_ZN9oceanbase12blocksstable16ObIColumnEncoder4initERKNS0_19ObColumnEncodingCtxElRKNS_6common7ObArrayINS0_15ObConstDatumRowENS5_19ModulePageAllocatorELb0ENS5_22ObArrayDefaultCallBackIS7_EENS5_22NotImplementItemEncodeIS7_EEEE +_ZN9oceanbase6common12ObDatumFuncs14get_basic_funcENS0_9ObObjTypeENS0_15ObCollationTypeEsbb +_ZN9oceanbase12blocksstable22ObMicroBlockCompressor8compressEPKclRS3_Rl +LZ4_compress_default +LZ4_compress_fast_extState +_ZNK9oceanbase12blocksstable19ObStringDiffEncoder9calc_sizeEv +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder11try_encoderINS0_14ObConstEncoderEEEiRPNS0_16ObIColumnEncoderEl +_ZN9oceanbase12blocksstable14ObConstEncoder8traverseERb +_ZN9oceanbase12blocksstable13ObDictEncoder8traverseERb +_ZN9oceanbase6common11DefHashFuncINS0_22DatumStrHashCalculatorILNS0_15ObCollationTypeE63ELb0ENS0_12ObMurmurHashELb0EEEE4hashERKNS0_7ObDatumEmRm +_ZN9oceanbase12blocksstable24ObMicroBlockBufferHelper26prepare_micro_block_readerEPKclRPNS0_19ObIMicroBlockReaderE +_ZNK9oceanbase12blocksstable24ObIntegerBaseDiffEncoder9calc_sizeEv +_ZN9oceanbase12blocksstable14ObConstEncoder4initERKNS0_19ObColumnEncodingCtxElRKNS_6common7ObArrayINS0_15ObConstDatumRowENS5_19ModulePageAllocatorELb0ENS5_22ObArrayDefaultCallBackIS7_EENS5_22NotImplementItemEncodeIS7_EEEE +_ZN9oceanbase12blocksstable13ObDictEncoder4initERKNS0_19ObColumnEncodingCtxElRKNS_6common7ObArrayINS0_15ObConstDatumRowENS5_19ModulePageAllocatorELb0ENS5_22ObArrayDefaultCallBackIS7_EENS5_22NotImplementItemEncodeIS7_EEEE +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder11try_encoderERPNS0_16ObIColumnEncoderElNS0_14ObColumnHeader4TypeEll +_ZN9oceanbase12blocksstable24ObMicroBlockReaderHelper10get_readerENS_6common14ObRowStoreTypeERPNS0_19ObIMicroBlockReaderE +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder4initERKNS0_16ObMicroBlockDataEPKNS0_19ObStorageDatumUtilsE +_ZNK9oceanbase6common15ObLZ4Compressor21get_max_overflow_sizeElRl +_ZN9oceanbase12blocksstable18ObIMicroBlockCache14reserve_kvpairERKNS0_16ObMicroBlockDescERNS_6common19ObKVCacheInstHandleERNS5_15ObKVCacheHandleERPNS5_13ObKVCachePairERl +_ZN9oceanbase12blocksstable18ObIMicroBlockCache17alloc_base_kvpairERKNS0_16ObMicroBlockDescEllRNS_6common19ObKVCacheInstHandleERNS5_15ObKVCacheHandleERPNS5_13ObKVCachePairE +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder11try_encoderINS0_13ObDictEncoderEEEiRPNS0_16ObIColumnEncoderEl +_ZN9oceanbase12blocksstable12ObRLEEncoder10store_metaERNS0_14ObBufferWriterE +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder11try_encoderINS0_19ObStringDiffEncoderEEEiRPNS0_16ObIColumnEncoderEl +_ZN9oceanbase12blocksstable19ObStringDiffEncoder8traverseERb +_ZN9oceanbase12blocksstable19ObStringDiffEncoder13traverse_cellERPcRPbRbRKNS_6common7ObDatumEl +_ZN9oceanbase12blocksstable19ObStringDiffEncoder4initERKNS0_19ObColumnEncodingCtxElRKNS_6common7ObArrayINS0_15ObConstDatumRowENS5_19ModulePageAllocatorELb0ENS5_22ObArrayDefaultCallBackIS7_EENS5_22NotImplementItemEncodeIS7_EEEE +_ZN9oceanbase6common25ObDataBlockCachePreWarmer21update_and_put_kvpairERKNS_12blocksstable16ObMicroBlockDescE +_ZNK9oceanbase12blocksstable12ObRLEEncoder9calc_sizeEv +_ZN9oceanbase6common15ObLZ4Compressor8compressEPKclPclRl +_ZN9oceanbase10compaction28ObPartitionMinorRowMergeIter10inner_nextEb +_ZN9oceanbase12blocksstable18ObMicroBlockWriter5reuseEv +_ZNK9oceanbase12blocksstable18ObHexStringEncoder9calc_sizeEv +_ZNK9oceanbase12blocksstable14ObConstEncoder9calc_sizeEv +_Z16ob_hash_sort_binPK13ObCharsetInfoPKhmPmS4_bPFmPKvmmE +_ZN9oceanbase12blocksstable18ObMacroBlockWriter11alloc_blockEv +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder23try_span_column_encoderINS0_23ObInterColSubStrEncoderEEEiRPNS0_16ObIColumnEncoderEl +_ZN9oceanbase6common10zstd_1_3_822ObZstdCompressor_1_3_810decompressEPKclPclRl +_ZN9oceanbase6common10zstd_1_3_813ObZstdWrapper10decompressERNS1_17OB_ZSTD_customMemEPKcmPcmRm +_ZL12ob_zstd_freePvS_ +_ZL14ob_zstd_mallocPvm +ZSTD_createDCtx_advanced +ZSTD_decompressMultiFrame.llvm.6347939395087608908 +ZSTD_getFrameHeader_advanced +ZSTD_decompressBegin_usingDict +ZSTD_freeDCtx +_ZN9oceanbase12blocksstable18ObMicroBlockReader4initERKNS0_16ObMicroBlockDataEPKNS0_19ObStorageDatumUtilsE +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder23try_span_column_encoderINS0_20ObColumnEqualEncoderEEEiRPNS0_16ObIColumnEncoderEl +_ZN9oceanbase12blocksstable20ObColumnEqualEncoder4initERKNS0_19ObColumnEncodingCtxElRKNS_6common7ObArrayINS0_15ObConstDatumRowENS5_19ModulePageAllocatorELb0ENS5_22ObArrayDefaultCallBackIS7_EENS5_22NotImplementItemEncodeIS7_EEEE +_ZN9oceanbase12blocksstable20ObColumnEqualEncoder15set_ref_col_idxElRKNS0_19ObColumnEncodingCtxE +_ZN9oceanbase6common10zstd_1_3_822ObZstdCompressor_1_3_88compressEPKclPclRl +_ZN9oceanbase6common10zstd_1_3_813ObZstdWrapper8compressERNS1_17OB_ZSTD_customMemEPKcmPcmRm +ZSTD_getCParams +ZSTD_compress_usingDict +ZSTD_resetCCtx_internal.llvm.15823478660316625246 +_ZN9oceanbase12blocksstable18ObMacroBlockWriter17write_micro_blockERNS0_16ObMicroBlockDescE +_ZNK9oceanbase12blocksstable19ObMicroBlockEncoder16get_column_countEv +_ZNK9oceanbase12blocksstable18ObMicroBlockWriter16get_column_countEv +_ZN9oceanbase12blocksstable23ObDataIndexBlockBuilder10append_rowERKNS0_16ObMicroBlockDescERKNS0_12ObMacroBlockE +_ZN9oceanbase12blocksstable23ObDataIndexBlockBuilder28insert_and_update_index_treeEPKNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable18ObMicroBlockWriter11build_blockERPcRl +_ZN9oceanbase12blocksstable23ObBaseIndexBlockBuilder10append_rowERKNS0_19ObIndexBlockRowDescE +_ZN9oceanbase12blocksstable18ObDataBlockMetaValD2Ev +_ZN9oceanbase12blocksstable12ObMacroBlock17write_micro_blockERKNS0_16ObMicroBlockDescERl +_ZNK9oceanbase12blocksstable18ObMicroBlockHeader9serializeEPclRl +_ZN9oceanbase12blocksstable22ObEncodingRowBufHolder9try_allocEl +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder5reuseEv +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder13free_encodersEv +_ZN9oceanbase12blocksstable24ObMultiPrefixTreeFactory7recycleEPNS0_17ObMultiPrefixTreeE +_ZN9oceanbase6common11ObArrayImplIPNS_12blocksstable17ObMultiPrefixTreeENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEE9push_backERKS4_ +_ZN9oceanbase12blocksstable26ObEncodingHashTableFactory7recycleEPNS0_19ObEncodingHashTableE +_ZZN9oceanbase12blocksstable19ObMicroBlockEncoder26update_estimate_size_limitERKNS0_23ObMicroBlockEncodingCtxEENK5$_580clEPKc +ZSTD_compressEnd +ZSTD_compressContinue_internal.llvm.15823478660316625246 +ZSTD_compressBlock_internal +ZSTD_compressBlock_fast +ZSTD_encodeSequences_bmi2 +HUF_compress_internal.llvm.13983784675777934242 +HIST_count_parallel_wksp.llvm.14440493188091616053 +HUF_buildCTable_wksp +HUF_writeCTable +FSE_compress_usingCTable_generic.llvm.4044124115888973552 +FSE_writeNCount_generic.llvm.4044124115888973552 +FSE_normalizeCount +HUF_compress4X_usingCTable_internal +HUF_compress1X_usingCTable_internal_bmi2 +ZSTD_selectEncodingType +ZSTD_buildCTable +FSE_buildCTable_wksp +_ZN9oceanbase12blocksstable13ObDictEncoder10store_metaERNS0_14ObBufferWriterE +_ZN9oceanbase12blocksstable24ObMicroBlockReaderHelper11init_readerINS0_18ObMicroBlockReaderEEEiRPT_RPNS0_19ObIMicroBlockReaderE +_ZN9oceanbase12blocksstable25ObSSTableMacroBlockHeader4initERKNS0_15ObDataStoreDescEPNS_6common9ObObjMetaEPNS5_11ObOrderTypeEPl +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder5resetEv +_ZN9oceanbase6common7ob_freeEPv +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder23try_span_column_encoderEPNS0_19ObSpanColumnEncoderEllRb +_ZN9oceanbase12blocksstable20ObColumnEqualEncoder8traverseERb +_ZN9oceanbase12blocksstable23ObInterColSubStrEncoder8traverseERb +HUF_compress1X_usingCTable_internal +_ZN9oceanbase12blocksstable23ObInterColSubStrEncoder4initERKNS0_19ObColumnEncodingCtxElRKNS_6common7ObArrayINS0_15ObConstDatumRowENS5_19ModulePageAllocatorELb0ENS5_22ObArrayDefaultCallBackIS7_EENS5_22NotImplementItemEncodeIS7_EEEE +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder11try_encoderINS0_12ObRLEEncoderEEEiRPNS0_16ObIColumnEncoderEl +_ZN9oceanbase12blocksstable12ObRLEEncoder8traverseERb +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder13alloc_encoderINS0_20ObColumnEqualEncoderEEEPT_v +ZSTD_compress_insertDictionary.llvm.15823478660316625246 +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder13alloc_encoderINS0_23ObInterColSubStrEncoderEEEPT_v +_ZN9oceanbase12blocksstable19ObMicroBlockEncoder11try_encoderINS0_24ObIntegerBaseDiffEncoderEEEiRPNS0_16ObIColumnEncoderEl +_ZN9oceanbase12blocksstable24ObIntegerBaseDiffEncoder8traverseERb +_ZN9oceanbase12blocksstable24ObIntegerBaseDiffEncoder4initERKNS0_19ObColumnEncodingCtxElRKNS_6common7ObArrayINS0_15ObConstDatumRowENS5_19ModulePageAllocatorELb0ENS5_22ObArrayDefaultCallBackIS7_EENS5_22NotImplementItemEncodeIS7_EEEE +ZSTD_decompressBlock_internal +ZSTD_decompressSequences_bmi2 +ZSTD_decodeSeqHeaders +ZSTD_buildSeqTable +ZSTD_buildFSETable +ZSTD_decodeLiteralsBlock +HUF_decompress4X1_usingDTable_internal_bmi2 +HUF_decompress4X_hufOnly_wksp_bmi2 +HUF_readDTableX1_wksp +HUF_readStats +FSE_decompress_usingDTable +FSE_buildDTable +FSE_readNCount +_ZN9oceanbase12blocksstable13ObDictEncoder14store_fix_dataERNS0_14ObBufferWriterE +HUF_decompress4X1_usingDTable_internal.llvm.10383294059120859657 _ZN9oceanbase6common18ObSimpleThreadPool4run1Ev -_ZN9oceanbase3lib18MySimpleThreadPool6handleEPv _ZN9oceanbase6common13ObLightyQueue3popERPvl +_ZN9oceanbase3lib18MySimpleThreadPool6handleEPv _ZN9oceanbase10logservice17ObLogApplyService6handleEPv _ZN9oceanbase10logservice13ObApplyStatus29submit_task_to_apply_service_ERNS0_18ObApplyServiceTaskE +_ZZN9oceanbase10logservice13ObApplyStatus19try_handle_cb_queueEPNS0_23ObApplyServiceQueueTaskERbENK4$_33clEPKc _ZZN9oceanbase10logservice13ObApplyStatus19try_handle_cb_queueEPNS0_23ObApplyServiceQueueTaskERbENK4$_38clEPKc _ZN9oceanbase11transaction9ObTxLogCb10on_successEv -_ZN9oceanbase11transaction7CtxLock4lockEv -_ZN9oceanbase11transaction12ObLSTxCtxMgr26revert_tx_ctx_without_lockEPNS0_10ObTransCtxE -_ZN9oceanbase11transaction14ObPartTransCtx14return_log_cb_EPNS0_9ObTxLogCbE -_ZN9oceanbase6common13ObSEArrayImplINS_11transaction14ObTxBufferNodeELl1ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase11transaction12CtxLockGuardD1Ev -_ZN9oceanbase11transaction12CtxLockGuardD2Ev -_ZN9oceanbase11transaction14ObTransService23handle_tx_commit_resultERKNS0_9ObTransIDEiNS_5share3SCNE -_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_8ObTxDescENS0_11ObTxDescMgr13ObTxDescAllocENS_6common10SpinRWLockELl65536EE3getERKS2_RPS3_ -_ZN9oceanbase8memtable13ObMemtableCtx19elr_trans_preparingEv -_ZN9oceanbase11transaction10ObTransCtx9test_lockEv -_ZN9oceanbase11transaction14ObPartTransCtx18common_on_success_EPNS0_9ObTxLogCbE _ZN9oceanbase8memtable18ObRedoLogGenerator13sync_log_succENS_5share3SCNERKNS0_15ObCallbackScopeE _ZN9oceanbase8memtable17ObMvccRowCallback8log_syncENS_5share3SCNE _ZN9oceanbase11transaction9tablelock17ObOBJLockCallback8log_syncENS_5share3SCNE +_ZN9oceanbase11transaction14ObPartTransCtx14return_log_cb_EPNS0_9ObTxLogCbE +_ZN9oceanbase11transaction17ObTransCtxFactory7releaseEPNS0_10ObTransCtxE _ZN9oceanbase8memtable13ObMemtableCtx32remove_callbacks_for_fast_commitEv -_ZN9oceanbase8memtable16ObTxCallbackList32remove_callbacks_for_fast_commitERb _ZN9oceanbase11transaction11ObCtxTxData14set_end_log_tsERKNS_5share3SCNE -_ZNK9oceanbase6common10ObFunctionIFiPNS_8memtable16ObITransCallbackEEE7DerivedIZNS2_16ObTxCallbackList16tx_elr_preparingEvE5$_239E4copyERNS0_12ObIAllocatorEPv$81243ea3e77486f4206578fded4b3028 -_ZN9oceanbase11transaction8ObTxDesc17execute_commit_cbEv -_ZN9oceanbase6common12ObLatchMutex8try_lockEjPKj _ZN9oceanbase6common18ObServerObjectPoolINS_11transaction14ObPartTransCtxEE13return_objectEPS3_ -_ZN9oceanbase3sql23ObEndTransAsyncCallback8callbackEi -_ZN9oceanbase8observer15ObSqlEndTransCb8callbackEi -_ZN9oceanbase3sql17ObSqlTransControl22reset_session_tx_stateEPNS0_16ObSQLSessionInfoEb -_ZN9oceanbase3sql17ObSqlTransControl22reset_session_tx_stateEPNS0_18ObBasicSessionInfoEb -_ZN9oceanbase6common10ObSpinLock11self_lockedEv -_ZN9oceanbase3sqlL14get_tx_serviceEPNS0_18ObBasicSessionInfoERPNS_11transaction14ObTransServiceE.llvm.13506435964989515801 -_ZThn8_N9oceanbase3sql16ObSQLSessionInfo17reset_tx_variableEv -_ZN9oceanbase11transaction14ObTransService8reuse_txERNS0_8ObTxDescE -_ZN9oceanbase11transaction11ObTxDescMgr6removeERNS0_8ObTxDescE -_ZZN9oceanbase11transaction14ObTransService8reuse_txERNS0_8ObTxDescEENK6$_1642clEPKc -_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_8ObTxDescENS0_11ObTxDescMgr13ObTxDescAllocENS_6common10SpinRWLockELl65536EE3delERKS2_PS3_ +_ZN9oceanbase8memtable16ObTxCallbackList32remove_callbacks_for_fast_commitEPKNS0_16ObITransCallbackERb +_ZN9oceanbase8memtable16ObTxCallbackList13SpinLockGuardC2ERNS_6common7ObLatchE _ZN9oceanbase11transaction14ObPartTransCtx19on_local_commit_tx_Ev _ZNK9oceanbase11transaction11ObCtxTxData18get_commit_versionEv -_ZN9oceanbase6common14SpinRLockGuardD2Ev -_ZN9oceanbase6common7ObLatch6unlockEPKj +_ZN9oceanbase11transaction10ObTransCtx12set_exiting_Ev +_ZN9oceanbase11transaction12ObLSTxCtxMgr10del_tx_ctxEPNS0_10ObTransCtxE +_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_10ObTransCtxENS0_13TransCtxAllocENS_6common10SpinRWLockELl16384EE3delERKS2_PS3_ +_ZN9oceanbase11transaction10ObTransCtx24unregister_timeout_task_Ev +_ZN9oceanbase11transaction14ObPartTransCtx20post_tx_commit_resp_Ei _ZN9oceanbase11transaction14ObPartTransCtx7tx_end_Eb +_ZN9oceanbase8memtable13ObMemtableCtx9trans_endEbNS_5share3SCNES3_ _ZN9oceanbase8memtable13ObMemtableCtx12do_trans_endEbNS_5share3SCNES3_i -_ZNK9oceanbase11transaction11ObCtxTxData14get_end_log_tsEv -_ZN9oceanbase6common14SpinWLockGuardD2Ev -_ZN9oceanbase11transaction11ObCtxTxData9set_stateEi _ZN9oceanbase11transaction9tablelock12ObLockMemCtx16clear_table_lockEbRKNS_5share3SCNES6_ +_ZN9oceanbase11transaction11ObCtxTxData9set_stateEi +_ZN9oceanbase11transaction11ObCtxTxData20insert_into_tx_tableEv _ZN9oceanbase8memtable18ObTransCallbackMgr9trans_endEb _ZN9oceanbase8memtable16ObTxCallbackList9tx_commitEv +_ZNK9oceanbase8memtable20ObITxCallbackFunctor11is_iter_endEPNS0_16ObITransCallbackE _ZN9oceanbase8memtable16ObTxCallbackList9callback_ERNS0_20ObITxCallbackFunctorEPNS0_16ObITransCallbackES5_ -_ZN9oceanbase11transaction9tablelock17ObOBJLockCallback3delEv +_ZN9oceanbase8memtable13ObMemtableCtx13callback_freeEPNS0_16ObITransCallbackE _ZN9oceanbase6common15ObFIFOAllocator4freeEPv -_ZN9oceanbase8memtable13ObLockWaitMgr6wakeupEm -_ZN9oceanbase11transaction9tablelock17ObOBJLockCallback12trans_commitEv -_ZN9oceanbase11transaction9tablelock14ObLockMemtable18remove_lock_recordERKNS1_13ObTableLockOpE -_ZN9oceanbase8memtable17ObMvccRowCallback19elr_trans_preparingEv -_ZN9oceanbase8memtable13ObLockWaitMgr6wakeupERKNS_6common10ObTabletIDERKNS0_13ObMemtableKeyE -_ZZN9oceanbase8memtable13ObLockWaitMgr6wakeupEmENK4$_21clEPKc -_ZN9oceanbase8memtable15RowHolderMapper17reset_hash_holderERKNS_6common10ObTabletIDERKNS0_13ObMemtableKeyERKNS_11transaction9ObTransIDE -_ZN9oceanbase6common15ObLinearHashMapINS0_9ObIntWarpENS_11transaction9ObTransIDENS0_14ShareMemMgrTagEE16load_access_bkt_ERKS2_RmRPNS6_6BucketE -_ZN9oceanbase6common12ObSliceAlloc4freeEPv -_ZN9oceanbase11transaction9tablelock12ObLockMemCtx18remove_lock_recordEPNS1_22ObMemCtxLockOpLinkNodeE +_ZNK9oceanbase11transaction11ObCtxTxData14get_end_log_tsEv +_ZZN9oceanbase8memtable13ObLockWaitMgr6wakeupEmENK4$_21clEPKc.llvm.566553378672739064 +_ZN9oceanbase11transaction9tablelock12ObLockMemCtx21free_lock_op_callbackEPv _ZN9oceanbase8memtable24ObMemtableCtxCbAllocator4freeEPv -_ZN9oceanbase8memtable10ObRowLatch5GuardD2Ev +_ZN9oceanbase6common12ObSliceAlloc4freeEPv +_ZN9oceanbase8memtable18ObTransCallbackMgr13callback_freeEPNS0_16ObITransCallbackE +_ZN9oceanbase8memtable17ObMvccRowCallback19elr_trans_preparingEv _ZN9oceanbase11transaction9tablelock12ObOBJLockMap18remove_lock_recordERKNS1_13ObTableLockOpE -_ZZN9oceanbase8memtable13ObLockWaitMgr6wakeupERKNS_6common10ObTabletIDERKNS0_13ObMemtableKeyEENK4$_43clEPKc.llvm.5153181974068449544 -_ZN9oceanbase11transaction14ObPartTransCtx19notify_data_source_ENS0_10NotifyTypeERKNS_5share3SCNEbRKNS_6common9ObSEArrayINS0_14ObTxBufferNodeELl1ENS7_19ModulePageAllocatorELb0EEEb -_ZN9oceanbase11transaction10ObTransCtx24unregister_timeout_task_Ev -_ZN9oceanbase11transaction11ObCtxTxData20insert_into_tx_tableEv -_ZN9oceanbase7storage9ObTxTable6insertERPNS0_8ObTxDataE -_ZN9oceanbase7storage17ObTxDataMiniCacheC2Ev -_ZN9oceanbase7storage9ObTxTable18get_tx_table_guardERNS0_14ObTxTableGuardE +_ZN9oceanbase11transaction9tablelock12ObLockMemCtx18remove_lock_recordEPNS1_22ObMemCtxLockOpLinkNodeE +_ZZN9oceanbase8memtable13ObLockWaitMgr6wakeupERKNS_6common10ObTabletIDERKNS0_13ObMemtableKeyEENK4$_43clEPKc.llvm.566553378672739064 +_ZNK9oceanbase8memtable13ObMemtableCtx14get_tx_end_scnEv +_ZN9oceanbase8memtable13ObLockWaitMgr6wakeupEm _ZN9oceanbase7storage13ObTxDataTable6insertERPNS0_8ObTxDataE _ZNK9oceanbase7storage8ObITable13get_start_scnEv +_ZN9oceanbase7storage15ObTableHandleV2C1Ev _ZN9oceanbase7storage26ObTxDataMemtableWriteGuardD2Ev +_ZN9oceanbase7storage15ObTableHandleV2D1Ev +_ZN9oceanbase7storage15ObTableHandleV2D2Ev _ZN9oceanbase7storage19ObTxDataMemtableMgr27get_all_memtables_for_writeERNS0_26ObTxDataMemtableWriteGuardE -_ZN9oceanbase7storage16MemMgrRLockGuardC2ERKNS0_15MemtableMgrLockE -_ZZN9oceanbase11transaction11ObTxDescMgr6removeERNS0_8ObTxDescEENK4$_69clEPKc.llvm.3520332200816746847 +_ZN9oceanbase7storage15ObTableHandleV220get_tx_data_memtableERPNS0_16ObTxDataMemtableE _ZN9oceanbase7storage13ObTxDataTable7insert_ERPNS0_8ObTxDataERNS0_26ObTxDataMemtableWriteGuardE _ZN9oceanbase7storage15ObTxDataHashMap6insertERKNS_11transaction9ObTransIDEPNS0_8ObTxDataE -_ZN9oceanbase11transaction14ObPartTransCtx20post_tx_commit_resp_Ei -_ZZN9oceanbase10logservice13ObApplyStatus19try_handle_cb_queueEPNS0_23ObApplyServiceQueueTaskERbENK4$_33clEPKc +_ZN9oceanbase11transaction14ObPartTransCtx7destroyEv +_ZN9oceanbase11transaction11ObCtxTxData7destroyEv +_ZN9oceanbase11transaction12ObTransTimer23unregister_timeout_taskERNS0_14ObITimeoutTaskE +_ZN9oceanbase11transaction21ObTxLogBigSegmentInfo5resetEv +_ZN9oceanbase11transaction14ObPartTransCtx14reset_log_cbs_Ev +_ZN9oceanbase11transaction9ObTxLogCb5resetEv +_ZN9oceanbase11transaction12ObTxExecInfo5resetEv +_ZN9oceanbase8memtable13ObMemtableCtx5resetEv +_ZN9oceanbase8memtable18ObTransCallbackMgr5resetEv +_ZN9oceanbase11transaction9tablelock12ObLockMemCtx5resetEv +_ZZN9oceanbase10logservice13ObApplyStatus29submit_task_to_apply_service_ERNS0_18ObApplyServiceTaskEENK4$_77clEPKc +_ZZN9oceanbase8memtable13ObLockWaitMgr6wakeupERKNS_11transaction9ObTransIDEENK4$_44clEPKc.llvm.566553378672739064 +_ZN9oceanbase10logservice13ObApplyStatus19statistics_cb_cost_ERKNS_4palf3LSNERKNS_5share3SCNElllll +_ZN9oceanbase10logservice17ObLogApplyService9push_taskEPNS0_18ObApplyServiceTaskE +_ZN9oceanbase3lib2TGILNS0_6TGTypeE6EE9push_taskEPv _ZN9oceanbase11transaction14ObPartTransCtx31wait_gts_elapse_commit_version_ERb _ZN9oceanbase11transaction7ObTsMgr15wait_gts_elapseEmRKNS_5share3SCNEPNS0_10ObTsCbTaskERb _ZN9oceanbase11transaction11ObGtsSource15wait_gts_elapseElPNS0_10ObTsCbTaskERb -_ZN9oceanbase11transaction10ObTransCtx12set_exiting_Ev -_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_10ObTransCtxENS0_13TransCtxAllocENS_6common10SpinRWLockELl16384EE3delERKS2_PS3_ -_ZZN9oceanbase11transaction11ObTxDescMgr3getERKNS0_9ObTransIDERPNS0_8ObTxDescEENK4$_66clEPKc.llvm.3520332200816746847 -_ZN9oceanbase5share19ObTenantSwitchGuard9switch_toEmb -_ZN9oceanbase11transaction14ObPartTransCtx7destroyEv -_ZN9oceanbase11transaction14ObPartTransCtx18reset_log_cb_list_ERNS_6common7ObDListINS0_9ObTxLogCbEEE -_ZN9oceanbase11transaction9ObTxLogCb5resetEv -_ZN9oceanbase11transaction11ObCtxTxData7destroyEv -_ZN9oceanbase11transaction12ObTransTimer23unregister_timeout_taskERNS0_14ObITimeoutTaskE -_ZN9oceanbase8memtable13ObMemtableCtx5resetEv -_ZN9oceanbase8memtable18ObTransCallbackMgr5resetEv -_ZN9oceanbase11transaction12ObTxExecInfo7destroyEv -_ZN9oceanbase11transaction14ObTransService24handle_tx_commit_result_ERNS0_8ObTxDescEiNS_5share3SCNE -_ZN9oceanbase11transaction14ObTransService18tx_post_terminate_ERNS0_8ObTxDescE -_ZN9oceanbase11transaction16ObTransStatistic12get_instanceEv -_ZN9oceanbase11transaction16ObTransStatistic25add_trans_total_used_timeEml -_ZN9oceanbase11transaction16ObTransStatistic22add_commit_trans_countEml -_ZN9oceanbase11transaction16ObTransStatistic15add_local_countEml -_ZN9oceanbase11transaction16ObTransStatistic31add_local_trans_total_used_timeEml -_ZN9oceanbase11transaction16ObTransStatistic21add_trans_commit_timeEml -_ZN9oceanbase10logservice17ObLogApplyService9push_taskEPNS0_18ObApplyServiceTaskE -_ZN9oceanbase3lib2TGILNS0_6TGTypeE6EE9push_taskEPv -_ZZN9oceanbase10logservice13ObApplyStatus29submit_task_to_apply_service_ERNS0_18ObApplyServiceTaskEENK4$_77clEPKc -_ZZN9oceanbase8memtable13ObLockWaitMgr6wakeupERKNS_11transaction9ObTransIDEENK4$_44clEPKc.llvm.5153181974068449544 +_ZN9oceanbase11transaction7ObTsMgr23get_ts_source_info_opt_EmRNS0_19ObTsSourceInfoGuardEbb +_ZZN9oceanbase8memtable13ObLockWaitMgr6wakeupEmENK4$_22clEPKc.llvm.566553378672739064 _ZN9oceanbase4palf21LogIOTaskCbThreadPool6handleEPv -_ZN9oceanbase4palf11PalfEnvImpl17get_log_allocatorEv _ZNK9oceanbase4palf14PalfHandleImpl14get_palf_epochERl -_ZZN9oceanbase11transaction8ObTxDesc17execute_commit_cbEvENK4$_15clEPKc -_ZN9oceanbase8memtable16ObTxCallbackList16tx_elr_preparingEv -_ZN9oceanbase8memtable16ObITransCallback19elr_trans_preparingEv -_ZNK9oceanbase6common10ObFunctionIFiPNS_8memtable16ObITransCallbackEEE7DerivedIZNS2_16ObTxCallbackList16tx_elr_preparingEvE5$_239E6invokeES4_$81243ea3e77486f4206578fded4b3028 +_ZN9oceanbase4palf11PalfEnvImpl17get_log_allocatorEv +_ZN9oceanbase6common11ObTimeGuardD2Ev +_ZZN9oceanbase10logservice13ObApplyStatus19try_handle_cb_queueEPNS0_23ObApplyServiceQueueTaskERbENK4$_39clEPKc _ZN9oceanbase4palf17LogIOFlushLogTask14after_consume_EPNS0_12IPalfEnvImplE -_ZZN9oceanbase4palf11PalfEnvImpl20get_palf_handle_implElRNS0_20IPalfHandleImplGuardEENK5$_782clEPKc.llvm.2452046906557810875 _ZN9oceanbase4palf11PalfEnvImpl23revert_palf_handle_implEPNS0_15IPalfHandleImplE _ZN9oceanbase4palf14PalfHandleImpl21inner_after_flush_logERKNS0_13FlushLogCbCtxE -_ZN9oceanbase6common11ObTimeGuard5clickEPKc -_ZN9oceanbase4palf17LogIOFlushLogTaskD2Ev -_ZZN9oceanbase10logservice13ObApplyStatus19try_handle_cb_queueEPNS0_23ObApplyServiceQueueTaskERbENK4$_39clEPKc _ZZN9oceanbase4palf16LogSlidingWindow15after_flush_logERKNS0_13FlushLogCbCtxEENK5$_209clEPKc -_ZN9oceanbase10logservice13ObApplyStatus19statistics_cb_cost_ERKNS_4palf3LSNERKNS_5share3SCNElllll +_ZNK9oceanbase7storage8ObTxData25is_valid_in_tx_data_tableEv +_ZZN9oceanbase4palf11PalfEnvImpl20get_palf_handle_implElRNS0_20IPalfHandleImplGuardEENK5$_785clEPKc.llvm.447907550136452219 _ZN9oceanbase4palf16LogSlidingWindow15after_flush_logERKNS0_13FlushLogCbCtxE _ZN9oceanbase4palf16LogSlidingWindow32inc_update_max_flushed_log_info_ERKNS0_3LSNES4_RKl _ZN9oceanbase6common8TCRWLock6wrlockEl _ZN9oceanbase4palf16LogSlidingWindow22gen_committed_end_lsn_ERNS0_3LSNE _ZN9oceanbase4palf16LogSlidingWindow26try_advance_committed_lsn_ERKNS0_3LSNE -_ZN9oceanbase4palf16LogSlidingWindow12LogTaskGuard12get_log_taskElRPNS0_7LogTaskE -_ZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE3getElRPS2_ -_ZN9oceanbase4palf16LogSlidingWindow12LogTaskGuardD2Ev -_ZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE6revertEl -_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE6revertElENKUlPKcE2_clES5_ _ZNK9oceanbase4palf16LogSlidingWindow23get_last_submit_log_id_Ev -_ZN9oceanbase4palf24palf_reach_time_intervalElRl _ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE3getElRPS2_ENKUlPKcE0_clES7_ +_ZN9oceanbase4palf16LogSlidingWindow25feedback_freeze_last_log_Ev +_ZN9oceanbase4palf16LogSlidingWindow21handle_committed_log_Ev +_ZNK9oceanbase4palf16LogSlidingWindow32is_all_committed_log_slided_out_ERNS0_3LSNERlS3_S3_ +_ZNK9oceanbase4palf16LogSlidingWindow24get_last_slide_log_info_ERlRNS_5share3SCNERNS0_3LSNES7_S2_S2_ +_ZN9oceanbase6common8TCRWLock21RLockGuardWithTimeoutD2Ev +_ZN9oceanbase4palf12LSNAllocator10try_freezeERNS0_3LSNERl +_ZN9oceanbase4palf16LogSlidingWindow25try_freeze_last_log_task_ElRKNS0_3LSNERb +_ZN9oceanbase4palf7LogTask11try_freeze_ERKNS0_3LSNE +_ZN9oceanbase4palf16LogSlidingWindow23handle_next_submit_log_ERb +_ZN9oceanbase6common8ObMember5resetEv +_ZNK9oceanbase4palf16LogSlidingWindow25get_last_submit_log_info_ERNS0_3LSNES3_RlS4_ +_ZNK9oceanbase4palf19LogGroupEntryHeader28get_header_parity_check_res_Ev +_ZN9oceanbase4palf19LogGroupEntryHeader8generateEbbRKNS0_11LogWriteBufElRKNS_5share3SCNElRKNS0_3LSNERKlRl +_ZN9oceanbase4palf19LogGroupEntryHeader23calculate_log_checksum_EbRKNS0_11LogWriteBufElRl +_ZN9oceanbase4palf14LogEntryHeader11deserializeEPKclRl +_ZN9oceanbase5share3SCN35fixed_deserialize_without_transformEPKclRl +_ZNK9oceanbase4palf19LogGroupEntryHeader9serializeEPclRl +_ZN9oceanbase4palf16LogSlidingWindow25set_last_submit_log_info_ERKNS0_3LSNES4_lRKl +_ZN9oceanbase4palf14LogGroupBuffer11get_log_bufERKNS0_3LSNElRNS0_11LogWriteBufE _ZNK9oceanbase4palf12LogConfigMgr24get_log_sync_member_listERNS_6common16ObMemberListBaseILl7EEERl +_ZN9oceanbase6common16ObMemberListBaseILl7EE13remove_serverERKNS0_6ObAddrE +_ZZN9oceanbase4palf7LogTask18update_header_infoERKNS0_3LSNElENK5$_660clEPKc +_ZN9oceanbase4palf16LogSlidingWindow10sliding_cbElPKNS0_22FixedSlidingWindowSlotE +_ZN9oceanbase4palf11LogChecksum21verify_accum_checksumEll +_ZN9oceanbase4palf16LogSlidingWindow31try_update_last_slide_log_info_ElRKNS_5share3SCNERKNS0_3LSNES8_RKll +_ZN9oceanbase10logservice13ObApplyStatus29update_palf_committed_end_lsnERKNS_4palf3LSNEl +_ZN9oceanbase10logservice14ObReplayStatus17update_end_offsetERKNS_4palf3LSNE +_ZZN9oceanbase4palf17LogIOFlushLogTask4initERKNS0_13FlushLogCbCtxERKNS0_11LogWriteBufEENK5$_853clEPKc.llvm.838520973738826390 +_ZSt16__insertion_sortIPN9oceanbase4palf3LSNEN9__gnu_cxx5__ops15_Iter_comp_iterINS1_10LSNCompareEEEEvT_S9_T0_ +_ZZN9oceanbase4palf14LogGroupBuffer11get_log_bufERKNS0_3LSNElRNS0_11LogWriteBufEENK5$_759clEPKc +_ZN9oceanbase10logservice12ObReplayFsCb14update_end_lsnElRKNS_4palf3LSNEl +_ZZNK9oceanbase4palf19LogGroupEntryHeader9serializeEPclRlENK5$_835clEPKc +_ZN9oceanbase6common13ObSEArrayImplINS0_8ObMemberELl7ENS0_19ModulePageAllocatorELb0EED2Ev _ZNK9oceanbase4palf16LogSlidingWindow17get_majority_lsn_ERKNS_6common16ObMemberListBaseILl7EEElRNS0_3LSNE _ZN9oceanbase6common15ObLinearHashMapINS0_6ObAddrENS_4palf9LsnTsInfoENS0_14ShareMemMgrTagEE7do_get_ERKS2_RS4_ _ZN9oceanbase6common15ObLinearHashMapINS0_6ObAddrENS_4palf9LsnTsInfoENS0_14ShareMemMgrTagEE16load_access_bkt_ERKS2_RmRPNS6_6BucketE _ZN9oceanbase6common15ObLinearHashMapINS0_6ObAddrENS_4palf9LsnTsInfoENS0_14ShareMemMgrTagEE7shrink_Ev -_ZZNK9oceanbase4palf16LogSlidingWindow17get_majority_lsn_ERKNS_6common16ObMemberListBaseILl7EEElRNS0_3LSNEENK5$_331clEPKc -_ZN9oceanbase11transaction10ObTransCtx29print_trace_log_if_necessary_Ev +_ZZN9oceanbase4palf16LogSlidingWindow21handle_committed_log_EvENK5$_162clEPKc +_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE6revertElENKUlPKcE4_clES5_ +_ZN9oceanbase6common13ObSEArrayImplINS_4palf11LogWriteBuf11InnerStructELl2ENS0_19ModulePageAllocatorELb0EED2Ev +_ZNK9oceanbase4palf12LogConfigMgr17get_children_listERNS_6common15BaseLearnerListILl15ENS0_10LogLearnerEEE +_ZZN9oceanbase4palf7LogTask11try_freeze_ERKNS0_3LSNEENK5$_664clEPKc +_ZZN9oceanbase4palf19LogGroupEntryHeader23update_header_checksum_EvENK5$_827clEPKc.llvm.838520973738826390 _ZN9oceanbase4palf16LogSlidingWindow25try_update_match_lsn_map_ERKNS_6common6ObAddrERKNS0_3LSNE -_ZZN9oceanbase8memtable13ObLockWaitMgr6wakeupEmENK4$_22clEPKc -_ZN9oceanbase11transaction9tablelock12ObLockMemCtx5resetEv -_ZN9oceanbase7storage15ObTableHandleV25resetEv -_ZZN9oceanbase4palf14PalfHandleImpl21inner_after_flush_logERKNS0_13FlushLogCbCtxEENK6$_1302clEPKc +_ZN9oceanbase6common8TCRWLock6rdlockEl +_ZN9oceanbase6common15BaseLearnerListILl2000ENS0_8ObMemberEE6appendERKS3_ +_ZZN9oceanbase4palf16LogSlidingWindow23handle_next_submit_log_ERbENK5$_183clEPKc +_ZZN9oceanbase4palf11LogChecksum22acquire_accum_checksumElRlENK5$_176clEPKc.llvm.838520973738826390 +_ZN9oceanbase11transaction10ObTransCtx29print_trace_log_if_necessary_Ev +_ZZN9oceanbase4palf19LogGroupEntryHeader23calculate_log_checksum_EbRKNS0_11LogWriteBufElRlENK5$_826clEPKc +_ZZN9oceanbase4palf16LogSlidingWindow23handle_next_submit_log_ERbENK5$_168clEPKc _ZZN9oceanbase10logservice13ObApplyStatus19try_handle_cb_queueEPNS0_23ObApplyServiceQueueTaskERbENK4$_30clEPKc -_ZSt16__introsort_loopIPN9oceanbase4palf3LSNElN9__gnu_cxx5__ops15_Iter_comp_iterINS1_10LSNCompareEEEEvT_S9_T0_T1_ -_ZZN9oceanbase10logservice17ObLogApplyService19handle_submit_task_EPNS0_13ObApplyStatusEENK5$_179clEPKc _ZZN9oceanbase4palf16LogSlidingWindow26try_advance_committed_lsn_ERKNS0_3LSNEENK5$_225clEPKc -_ZZN9oceanbase10logservice13ObApplyStatus29submit_task_to_apply_service_ERNS0_18ObApplyServiceTaskEENK4$_78clEPKc -_ZZN9oceanbase11transaction14ObTxVersionMgr20update_max_commit_tsERKNS_5share3SCNEbENKUlPKcE_clES7_ -_ZThn24_N9oceanbase11transaction20ObKeepAliveLSHandler10on_successEv -_ZN9oceanbase8memtable17ObMvccRowCallback17unlink_trans_nodeEv -_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE6revertElENKUlPKcE6_clES5_ -_ZZN9oceanbase4palf17LogIOFlushLogTask14after_consume_EPNS0_12IPalfEnvImplEENK5$_850clEPKc -_ZNK9oceanbase7storage8ObTxData25is_valid_in_tx_data_tableEv -_ZZN9oceanbase10logservice13ObApplyStatus20try_submit_cb_queuesEvENK4$_27clEPKc +_ZN9oceanbase4palf11LogChecksum21verify_accum_checksumElllRl _ZN9oceanbase6common15ObLinearHashMapINS0_6ObAddrENS_4palf9LsnTsInfoENS0_14ShareMemMgrTagEE17load_factor_ctrl_Em -_ZZN9oceanbase4palf16LogSlidingWindow25try_update_match_lsn_map_ERKNS_6common6ObAddrERKNS0_3LSNEENK5$_443clEPKc -_ZZN9oceanbase4palf16LogSlidingWindow15after_flush_logERKNS0_13FlushLogCbCtxEENK5$_219clEPKc -_ZN9oceanbase5share25get_tenant_base_with_lockEmRNS_6common10ObLDHandleERPNS0_12ObTenantBaseERSt8functionIFiS3_EE -_ZNK9oceanbase3omt13ObMultiTenant27get_tenant_with_tenant_lockEmRNS_6common10ObLDHandleERPNS0_8ObTenantE +_ZZN9oceanbase4palf16LogSlidingWindow28generate_group_entry_header_ElPNS0_7LogTaskERNS0_19LogGroupEntryHeaderERlRbENK5$_189clEPKc +_ZZN9oceanbase4palf9LogEngine21submit_flush_log_taskERKNS0_13FlushLogCbCtxERKNS0_11LogWriteBufEENK5$_570clEPKc.llvm.838520973738826390 +_ZN9oceanbase4palf9LogEngine21submit_flush_log_taskERKNS0_13FlushLogCbCtxERKNS0_11LogWriteBufE +_ZN9oceanbase6common22ObTenantMutilAllocator27alloc_log_io_flush_log_taskEll +_ZN9oceanbase6common13ObLightyQueue4pushEPv +_ZN9oceanbase4palf17LogIOFlushLogTaskC1Ell +_ZZN9oceanbase4palf19LogGroupEntryHeader8generateEbbRKNS0_11LogWriteBufElRKNS_5share3SCNElRKNS0_3LSNERKlRlENK5$_808clEPKc.llvm.838520973738826390 +_ZZN9oceanbase4palf11LogChecksum21verify_accum_checksumElllRlENK5$_179clEPKc +_ZZN9oceanbase10logservice17ObLogApplyService19handle_submit_task_EPNS0_13ObApplyStatusEENK5$_179clEPKc +_ZN9oceanbase8memtable16ObTxCallbackList16ensure_checksum_ENS_5share3SCNE _ZTWN9oceanbase6common7ObLatch12current_waitE -_ZZN9oceanbase4palf21LogIOTaskCbThreadPool6handleEPvENK5$_948clEPKc -_ZZN9oceanbase4palf14PalfHandleImpl21inner_after_flush_logERKNS0_13FlushLogCbCtxEENK6$_1304clEPKc -_ZZN9oceanbase4palf17LogIOFlushLogTask7destroyEvENK5$_837clEPKc.llvm.1832557561412309455 -_ZZN9oceanbase4palf16LogSlidingWindow32inc_update_max_flushed_log_info_ERKNS0_3LSNES4_RKlENK5$_230clEPKc -_ZN9oceanbase3sql16ObSQLSessionInfo15get_piece_cacheEb +_ZSt16__introsort_loopIPN9oceanbase4palf3LSNElN9__gnu_cxx5__ops15_Iter_comp_iterINS1_10LSNCompareEEEEvT_S9_T0_T1_ +_ZZN9oceanbase10logservice13ObApplyStatus29submit_task_to_apply_service_ERNS0_18ObApplyServiceTaskEENK4$_78clEPKc +_ZN9oceanbase10logservice11ObApplyFsCb14update_end_lsnElRKNS_4palf3LSNEl +_ZN9oceanbase4palf17LogIOFlushLogTaskD2Ev +_ZN9oceanbase4palf11LogWriteBufD1Ev +_ZN9oceanbase4palf11LogWriteBufD2Ev +_ZZN9oceanbase4palf17LogIOFlushLogTask14after_consume_EPNS0_12IPalfEnvImplEENK5$_867clEPKc +_ZZN9oceanbase4palf17LogIOFlushLogTask7destroyEvENK5$_854clEPKc.llvm.838520973738826390 +_ZZN9oceanbase10logservice13ObApplyStatus29update_palf_committed_end_lsnERKNS_4palf3LSNElENK4$_58clEPKc +_ZZNK9oceanbase4palf16LogSlidingWindow17get_majority_lsn_ERKNS_6common16ObMemberListBaseILl7EEElRNS0_3LSNEENK5$_331clEPKc +_ZZN9oceanbase4palf14PalfHandleImpl21inner_after_flush_logERKNS0_13FlushLogCbCtxEENK6$_1315clEPKc +_ZZNK9oceanbase4palf16LogSlidingWindow32is_all_committed_log_slided_out_ERNS0_3LSNERlS3_S3_ENK5$_255clEPKc.llvm.447907550136452219 +_ZZN9oceanbase4palf16LogSlidingWindow25set_last_submit_log_info_ERKNS0_3LSNES4_lRKlENK5$_221clEPKc +_ZZN9oceanbase4palf11LogChecksum21verify_accum_checksumEllENK5$_178clEPKc.llvm.838520973738826390 +_ZZN9oceanbase4palf16LogSlidingWindow25try_freeze_last_log_task_ElRKNS0_3LSNERbENK5$_195clEPKc +_ZZN9oceanbase4palf16LogSlidingWindow21handle_committed_log_EvENK5$_163clEPKc +_ZZN9oceanbase4palf16LogSlidingWindow31try_update_last_slide_log_info_ElRKNS_5share3SCNERKNS0_3LSNES8_RKllENK5$_223clEPKc +_ZZN9oceanbase4palf16LogSlidingWindow15after_flush_logERKNS0_13FlushLogCbCtxEENK5$_219clEPKc +_ZZN9oceanbase4palf14PalfHandleImpl21inner_after_flush_logERKNS0_13FlushLogCbCtxEENK6$_1317clEPKc +_ZZN9oceanbase4palf11LogIOWorker14submit_io_taskEPNS0_9LogIOTaskEENK5$_990clEPKc.llvm.838520973738826390 +_ZN9oceanbase6common12ObSliceAlloc13destroy_blockEPNS0_13ObBlockSlicerE +_ZZN9oceanbase10logservice13ObApplyStatus20try_submit_cb_queuesEvENK4$_27clEPKc +_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE5slideElPNS0_16ISlidingCallBackEENKUlPKcE1_clES7_ +_ZZN9oceanbase4palf21LogIOTaskCbThreadPool6handleEPvENK5$_965clEPKc +_ZN9oceanbase11transaction12ObTxExecInfo7destroyEv +_ZZN9oceanbase4palf16LogSlidingWindow25try_update_match_lsn_map_ERKNS_6common6ObAddrERKNS0_3LSNEENK5$_443clEPKc +_ZN9oceanbase11transaction12ObLSTxCtxMgr26revert_tx_ctx_without_lockEPNS0_10ObTransCtxE _ZN9oceanbase8memtable10ObMemtable11row_compactEPNS0_9ObMvccRowENS_5share3SCNEl -_ZN9oceanbase8memtable9ObMvccRow17unlink_trans_nodeERKNS0_15ObMvccTransNodeE -_ZN9oceanbase5share3SCN5minusERKS1_m -_ZN9oceanbase6common16ObLatchWaitQueue7wake_upERNS0_7ObLatchEb -_ZN9oceanbase8memtable22ObMemtableRowCompactor7compactENS_5share3SCNEl -_ZN9oceanbase8memtable22ObMemtableRowCompactor23construct_compact_node_ENS_5share3SCNElPNS0_15ObMvccTransNodeE -_ZN9oceanbase12blocksstable11ObRowWriter5writeElRKNS0_10ObDatumRowERPcRl -_ZN9oceanbase12blocksstable11ObRowWriter17inner_write_cellsINS0_14ObStorageDatumEEEiPKT_l -_ZN9oceanbase12blocksstable11ObRowWriter20append_row_and_indexINS0_14ObStorageDatumENS0_20ObColClusterInfoMaskEEEiPKT_lllbRT0_ -_ZN9oceanbase11transaction9tablelock16ObOBJLockFactory7releaseEPNS1_9ObOBJLockE -_ZN9oceanbase11transaction14ObTransHashMapINS0_9tablelock8ObLockIDENS2_9ObOBJLockENS2_14ObOBJLockAllocENS_6common10SpinRWLockELl1024EE3getERKS3_RPS4_ -_ZN9oceanbase6common15ObLinearHashMapINS0_9ObIntWarpENS_11transaction9ObTransIDENS0_14ShareMemMgrTagEE7expand_Ev -_ZN9oceanbase11transaction11ObGtsSource37get_gts_from_local_timestamp_service_ERNS_6common6ObAddrERlRNS2_13ObMonotonicTsE -_ZN9oceanbase10logservice18ObLogReplayService6handleEPv -_ZN9oceanbase10logservice14ObReplayStatus6unlockEv -_ZNK9oceanbase6common4hash11ObHashTableINS_3sql3dtl20ObDTLIntermResultKeyENS1_11HashMapPairIS5_PNS4_21ObDTLIntermResultInfoEEENS1_9hash_funcIS5_EENS1_8equal_toIS5_EENS1_10pair_firstIS9_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS9_EELi82ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE18foreach_refactoredINS4_19ObDTLIntermResultGCEEEiRT_ -MD5_Final -_ZN9oceanbase5share6schema19ObSchemaGetterGuard10check_privERKNS1_17ObSessionPrivInfoERKNS1_15ObStmtNeedPrivsE -_ZN9oceanbase5share6schema19ObSchemaGetterGuard23check_single_table_privERKNS1_17ObSessionPrivInfoERKNS1_10ObNeedPrivE -_ZN9oceanbase3sql13AllocOpHelperILi25EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE -_ZN9oceanbase3sql15ObTableModifyOpC2ERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputE -_ZN9oceanbase3sql10ObFLTUtils35update_flush_policy_by_control_infoERNS0_16ObSQLSessionInfoE -_ZN9oceanbase6common8ObRandom4randEll +_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE5slideElPNS0_16ISlidingCallBackEENKUlPKcE5_clES7_ +_ZN9oceanbase8dbms_job15ObDBMSJobThread6handleEPv +_ZN9oceanbase8memtable13ObQueryEngine11revert_iterEPNS0_22ObIQueryEngineIteratorE +_Ux86_64_getcontext_trace +_ZN9oceanbase7storage21ObIndexTreePrefetcher15lookup_in_cacheERNS0_19ObSSTableReadHandleE +_ZN9oceanbase6common12ObKVCacheMap3putERNS0_13ObKVCacheInstERKNS0_13ObIKVCacheKeyEPKNS0_13ObKVCachePairEPNS0_18ObKVMemBlockHandleEb +_ZN9oceanbase6common14ObKVCacheStore13de_handle_refEPNS0_18ObKVMemBlockHandleEb +_ZN9oceanbase6common19GlobalHazardVersion11delete_nodeEPNS0_17KVCacheHazardNodeE +_ZN9oceanbase6common14ObKVCacheStore13free_mbhandleEPNS0_18ObKVMemBlockHandleEb +_ZN9oceanbase6common14ObKVCacheStore16remove_mb_handleEPNS0_18ObKVMemBlockHandleEb +_ZN9oceanbase6common14ObKVCacheStore17retire_mb_handlesERNS0_10HazardListEb +_ZN9oceanbase6common12ObFixedQueueINS0_18ObKVMemBlockHandleEE4pushEPS2_ +_ZN9oceanbase6common14ObKVCacheStore10do_wash_mbEPNS0_18ObKVMemBlockHandleERPvRl +_ZN9oceanbase3sql16AllocInputHelperILi26EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecERPNS0_9ObOpInputE +_ZN9oceanbase11transaction10ObTxCtxMgr38get_ls_min_uncommit_tx_prepare_versionERKNS_5share6ObLSIDERNS2_3SCNE +_ZN9oceanbase10compaction22ObPartitionMajorMerger15merge_partitionERNS0_16ObTabletMergeCtxElb +_ZN9oceanbase7storage18ObSimpleRowsMergerINS_10compaction29ObPartitionMergeLoserTreeItemENS2_28ObPartitionMergeLoserTreeCmpEE8push_topERKS3_ +_ZN9oceanbase10compaction22ObPartitionMajorMerger23merge_same_rowkey_itersERNS_6common9ObSEArrayIPNS0_20ObPartitionMergeIterELl16ENS2_19ModulePageAllocatorELb0EEE +_ZN9oceanbase10compaction22ObPartitionMergeHelper19rebuild_rows_mergerEv +_ZN9oceanbase7storage18ObSimpleRowsMergerINS_10compaction29ObPartitionMergeLoserTreeItemENS2_28ObPartitionMergeLoserTreeCmpEE4pushERKS3_ +_ZN9oceanbase10compaction23ObPartitionRowMergeIter4nextEv +_ZN9oceanbase10compaction28ObPartitionMergeLoserTreeCmp3cmpERKNS0_29ObPartitionMergeLoserTreeItemES4_Rl +_ZN9oceanbase10compaction22ObPartitionMergeHelper25find_rowkey_minimum_itersERNS_6common9ObSEArrayIPNS0_20ObPartitionMergeIterELl16ENS2_19ModulePageAllocatorELb0EEE +_ZNK9oceanbase7storage18ObSimpleRowsMergerINS_10compaction29ObPartitionMergeLoserTreeItemENS2_28ObPartitionMergeLoserTreeCmpEE18is_unique_championEv +_ZN9oceanbase7storage18ObSimpleRowsMergerINS_10compaction29ObPartitionMergeLoserTreeItemENS2_28ObPartitionMergeLoserTreeCmpEE3popEv +_ZN9oceanbase7storage18ObSimpleRowsMergerINS_10compaction29ObPartitionMergeLoserTreeItemENS2_28ObPartitionMergeLoserTreeCmpEE3topERPKS3_ +_ZN9oceanbase10compaction26ObMajorPartitionMergeFuser8fuse_rowERNS_6common9ObSEArrayIPNS0_20ObPartitionMergeIterELl16ENS2_19ModulePageAllocatorELb0EEE +_ZN9oceanbase7storage9ObRowFuse8fuse_rowERKNS_12blocksstable10ObDatumRowERS3_RNS0_8ObNopPosERbPNS_6common12ObIAllocatorE +_ZN9oceanbase7storage24ObSSTableRowWholeScanner18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowE +_ZN9oceanbase10compaction28ObPartitionMergeLoserTreeCmp7compareERKNS0_29ObPartitionMergeLoserTreeItemES4_Rl +_ZN9oceanbase5share17ObTenantDagWorker5yieldEv +_ZN9oceanbase7storage24ObSSTableRowWholeScanner27open_next_valid_micro_blockEv +_ZN9oceanbase12blocksstable23ObIMicroBlockRowScanner16locate_range_posEbbRlS2_ +_ZN9oceanbase12blocksstable24ObMicroBlockBareIterator25get_next_micro_block_dataERNS0_16ObMicroBlockDataE +_ZN9oceanbase12blocksstable18ObMacroBlockReader27decrypt_and_decompress_dataERKNS0_25ObSSTableMacroBlockHeaderEPKclRS6_RlRb +_ZNK9oceanbase12blocksstable25ObSSTableMacroBlockHeader8is_validEv +_ZN9oceanbase6common15ObLZ4Compressor10decompressEPKclPclRl +LZ4_decompress_safe +_ZNK9oceanbase12blocksstable18ObMicroBlockHeader12check_recordEPKcls +_ZN9oceanbase12blocksstable44ObMultiVersionMicroBlockMinorMergeRowScanner4openERKNS0_12MacroBlockIdERKNS0_16ObMicroBlockDataEbb +_ZN9oceanbase12blocksstable18ObMacroBlockReader27decrypt_and_decompress_dataERKNS0_19ObMicroBlockDesMetaEPKclRS6_RlRbbPNS_6common12ObIAllocatorE +_ZN9oceanbase12blocksstable18ObMicroBlockHeader11deserializeEPKclRl +_ZN9oceanbase12blocksstable19ObIMicroBlockReader12locate_rangeERKNS0_12ObDatumRangeEbbRlS5_b +_ZN9oceanbase10compaction17ObPartitionMerger23prepare_merge_partitionERNS0_16ObMergeParameterERNS0_22ObPartitionMergeHelperE +_ZN9oceanbase8observer9ObMPQuery11deserializeEv +_ZN9oceanbase3sql17ObMergeDistinctOp10inner_openEv _ZN9oceanbase8memtable13ObLockWaitMgr12post_processEbRb -_ZN9oceanbase3sql13ObDASUpdateOp7open_opEv -_ZN9oceanbase3sql12ObDMLService14init_dml_paramERKNS0_17ObDASDMLBaseCtDefERNS0_17ObDASDMLBaseRtDefERNS_11transaction16ObTxReadSnapshotERNS_6common12ObIAllocatorERNS_7storage14ObDMLBaseParamE -_ZN9oceanbase3sql20ObDASIndexDMLAdaptorILi3ENS0_16ObDASUpdIteratorEE10write_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERKNS0_13ObDASUpdCtDefERNS0_13ObDASUpdRtDefERS2_Rl -_ZN9oceanbase6common23ObOptStatMonitorManager12get_instanceEv -_ZZN9oceanbase7storage15ObAccessService25audit_tablet_opt_dml_statERKNS0_14ObDMLBaseParamERKNS_6common10ObTabletIDENS5_16ObOptDmlStatTypeElENK5$_119clEPKc -_ZN9oceanbase7storage15ObAccessService11update_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERNS_11transaction8ObTxDescERKNS0_14ObDMLBaseParamERKNS6_8ObIArrayImEESJ_PNS6_16ObNewRowIteratorERl -_ZN9oceanbase6common9PageArenaIcNS0_19ModulePageAllocatorEED2Ev -_ZN9oceanbase7storage15ObAccessService15ObStoreCtxGuardD2Ev -_ZZN9oceanbase11transaction14ObTransService14revert_tx_ctx_EPNS_7storage4ObLSEPNS0_14ObPartTransCtxEENK6$_1313clEPKc -_ZN9oceanbase6common11ObArrayImplINS_11transaction16ObTransIDAndAddrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev -_ZZN9oceanbase11transaction14ObTransService41fetch_cflict_tx_ids_from_mem_ctx_to_desc_ERNS_8memtable15ObMvccAccessCtxEENK6$_1319clEPKc -_ZZN9oceanbase11transaction14ObPartTransCtx10end_accessEvENK5$_835clEPKc -_ZN9oceanbase11transaction14ObTransService16revert_store_ctxERNS_7storage10ObStoreCtxE -_ZN9oceanbase11transaction12ObLSTxCtxMgr13revert_tx_ctxEPNS0_10ObTransCtxE -_ZN9oceanbase8memtable13ObMemtableCtx22get_conflict_trans_idsERNS_6common8ObIArrayINS_11transaction16ObTransIDAndAddrEEE -_ZN9oceanbase6common11ObArrayImplINS_11transaction9ObTransIDENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE7destroyEv -_ZN9oceanbase7storage15ObAccessService20check_write_allowed_ERKNS_5share6ObLSIDERKNS_6common10ObTabletIDENS0_17ObStoreAccessTypeERKNS0_14ObDMLBaseParamERNS_11transaction8ObTxDescERNS1_15ObStoreCtxGuardE -_ZZN9oceanbase11transaction14ObTransService14acquire_tx_ctxERKNS_5share6ObLSIDERKNS0_8ObTxDescERPNS0_14ObPartTransCtxEPNS_7storage4ObLSEENK6$_1311clEPKc -_ZNK9oceanbase11transaction14ObTxVersionMgr17get_max_commit_tsEb -_ZZN9oceanbase11transaction14ObTransService19get_write_store_ctxERNS0_8ObTxDescERKNS0_16ObTxReadSnapshotENS_18concurrent_control11ObWriteFlagERNS_7storage10ObStoreCtxEENK6$_1307clEPKc -_ZN9oceanbase11transaction14ObTransService19get_write_store_ctxERNS0_8ObTxDescERKNS0_16ObTxReadSnapshotENS_18concurrent_control11ObWriteFlagERNS_7storage10ObStoreCtxE -_ZN9oceanbase11transaction12ObLSTxCtxMgr10get_tx_ctxERKNS0_9ObTransIDEbRPNS0_14ObPartTransCtxE -_ZN9oceanbase11transaction14ObTransHashMapINS_5share6ObLSIDENS0_12ObLSTxCtxMgrENS0_17ObLSTxCtxMgrAllocENS_6common11ObQSyncLockELl64EE6revertEPS4_ -_ZN9oceanbase6common11ObArrayImplINS_11transaction9ObTransIDENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE6assignERKNS0_8ObIArrayIS3_EE -_ZN9oceanbase6common13ObSEArrayImplINS_5share6schema15ObSchemaMgrInfoELl2ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase6common11ObArrayImplINS_11transaction9ObTransIDENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev -_ZZN9oceanbase11transaction14ObPartTransCtx12start_accessERKNS0_8ObTxDescElENK5$_834clEPKc -_ZN9oceanbase7storage17ObLSTabletService11update_rowsERNS0_10ObStoreCtxERKNS0_14ObDMLBaseParamERKNS_6common8ObIArrayImEESB_PNS7_16ObNewRowIteratorERl -_ZN9oceanbase7storage15ObDMLRunningCtx4initEPKNS_6common8ObIArrayImEES6_PNS_5share6schema27ObMultiVersionSchemaServiceERNS0_14ObTabletHandleE -_ZN9oceanbase7storage17ObLSTabletService15process_new_rowERNS0_14ObTabletHandleERNS0_15ObDMLRunningCtxERKNS_6common8ObIArrayIlEERKNS0_10ObStoreRowESD_b -_ZN9oceanbase8memtable10ObMemtable3setERNS_7storage10ObStoreCtxEmRKNS2_15ObTableReadInfoERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS9_IlEERKNS2_10ObStoreRowESL_PKNSA_13ObEncryptMetaE -_ZZN9oceanbase8memtable13ObMemtableCtx10write_authEbENK5$_311clEPKc.llvm.5153181974068449544 -_ZN9oceanbase8memtable16ObMvccWriteGuard10write_authERNS_7storage10ObStoreCtxE -_ZN9oceanbase6common7ObLatch10try_rdlockEj -_ZN9oceanbase7storage8ObTablet25try_update_storage_schemaEllRNS_6common12ObIAllocatorEl -_ZN9oceanbase8memtable10ObMemtable4set_ERNS_7storage10ObStoreCtxEmRKNS2_15ObTableReadInfoERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS2_10ObStoreRowEPSH_PKNS9_IlEE -_ZN9oceanbase8memtable10ObMemtable11mvcc_write_ERNS_7storage10ObStoreCtxEPKNS0_13ObMemtableKeyERKNS2_15ObTableReadInfoERKNS0_11ObTxNodeArgERb -_ZN9oceanbase8memtable17ObMvccRowCallback13get_data_sizeEv -_ZN9oceanbase6common20ObGMemstoreAllocator11AllocHandle5allocEl -_ZNK9oceanbase5share3SCN14get_val_for_txEb -_ZNK9oceanbase7storage8ObITable10is_sstableEv -_ZN9oceanbase8memtable9ObMvccRow24update_max_trans_versionENS_5share3SCNERKNS_11transaction9ObTransIDE -_ZN9oceanbase12blocksstable11ObRowWriter15inner_write_rowElRKNS_7storage10ObStoreRowEPKNS_6common8ObIArrayIlEE -_ZN9oceanbase12blocksstable11ObRowWriter13append_columnERKNS_6common5ObObjE -_ZN9oceanbase12blocksstable11ObRowWriter13append_columnERKNS0_14ObStorageDatumE -_ZN9oceanbase12blocksstable11ObRowWriter21append_8_bytes_columnERKNS0_14ObStorageDatumE -_ZN9oceanbase8memtable12ObMvccEngine9ensure_kvEPKNS0_13ObMemtableKeyEPNS0_9ObMvccRowE -_ZN9oceanbase6common15ObLinearHashMapINS0_9ObIntWarpENS_11transaction9ObTransIDENS0_14ShareMemMgrTagEE10do_insert_ERKS2_RKS4_ -_ZN9oceanbase8memtable12ObMvccEngine14build_tx_node_ERNS0_14ObIMemtableCtxERKNS0_11ObTxNodeArgERPNS0_15ObMvccTransNodeE -_ZN9oceanbase6common20ObGMemstoreAllocator5allocERNS1_11AllocHandleEl -_ZN9oceanbase3lib11ObTLTaGuard9switch_toEl -_ZN9oceanbase5share19ObTenantSwitchGuard7releaseEv -_ZN9oceanbase7storage15ObTenantFreezer34check_tenant_out_of_memstore_limitERb -_ZN9oceanbase8memtable9ObMvccRowC2Ev -_ZN9oceanbase8memtable13ObMTKVBuilder7dup_keyERPNS_6common13ObStoreRowkeyERNS2_12ObIAllocatorEPKS3_ -_ZN9oceanbase8memtableL11hash_rowkeyERKNS_6common10ObTabletIDERKNS0_13ObMemtableKeyE -_ZN9oceanbase12blocksstable13ObDatumRowkey11from_rowkeyERKNS_6common8ObRowkeyERNS0_20ObStorageDatumBufferE -_ZN9oceanbase6common12ObSliceAlloc5allocEv -_ZN9oceanbase12blocksstable11ObRowWriter18alloc_buf_and_initEb -_ZN9oceanbase8memtable10ObMemtable13need_for_saveEPKNS_5share13ObEncryptMetaE -_ZN9oceanbase8memtable9ObMvccRow10mvcc_writeERNS0_14ObIMemtableCtxENS_18concurrent_control11ObWriteFlagERKNS_11transaction12ObTxSnapshotERNS0_15ObMvccTransNodeERNS0_17ObMvccWriteResultE -_ZN9oceanbase12blocksstable9ObSSTable16check_row_lockedERNS_7storage10ObStoreCtxERKNS2_15ObTableReadInfoERKNS0_13ObDatumRowkeyERNS2_19ObStoreRowLockStateE -_ZN9oceanbase8memtable16ObMvccWriteGuardD1Ev -_ZN9oceanbase8memtable13ObQueryEngine3setEPKNS0_13ObMemtableKeyEPNS0_9ObMvccRowE -_ZN9oceanbase7storage19ObStorageTableGuard25refresh_and_protect_tableERNS0_15ObRelativeTableE -_ZN9oceanbase8memtable13ObQueryEngine3getEPKNS0_13ObMemtableKeyERPNS0_9ObMvccRowEPS2_ -_ZN9oceanbase8memtable18ObTransCallbackMgr14callback_allocEl -_ZN9oceanbase6common15ObFIFOAllocator5allocEl -_ZN9oceanbase8memtable18ObTransCallbackMgr6appendEPNS0_16ObITransCallbackE -_ZN9oceanbase8memtable16ObQueryAllocator4freeEPv -_ZN9oceanbase18concurrent_control28check_sequence_set_violationENS0_11ObWriteFlagElNS_11transaction9ObTransIDENS_12blocksstable9ObDmlFlagElS3_S5_l -_ZZN9oceanbase11transaction14ObTransService14create_tx_ctx_ERKNS_5share6ObLSIDEPNS_7storage4ObLSERKNS0_8ObTxDescERPNS0_14ObPartTransCtxEENK6$_1315clEPKc -_ZZN9oceanbase3sql16ObDASUpdIterator12get_next_rowERPNS_6common8ObNewRowEENK5$_538clEPKc -_ZN9oceanbase8memtable18ObTransCallbackMgr20revert_callback_listEv -_ZN9oceanbase11transaction16ObTransStatistic22add_read_elr_row_countEml -_ZN9oceanbase11transaction9tablelock11ObLockTable4lockERNS_7storage10ObStoreCtxERKNS1_11ObLockParamE -_ZN9oceanbase7storage15ObTableHandleV2D1Ev -_ZN9oceanbase7storage15ObTableHandleV2D2Ev -_ZN9oceanbase6common7ObLatch10try_wrlockEjPKj -_ZN9oceanbase6common8ObBitSetILl16ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase11transaction9tablelock11ObLockTable17get_lock_memtableERNS_7storage15ObTableHandleV2E -_ZN9oceanbase7storage15ObTableHandleV217get_lock_memtableERPNS_11transaction9tablelock14ObLockMemtableE -_ZN9oceanbase8memtable13ObMemtableCtx15add_lock_recordERKNS_11transaction9tablelock13ObTableLockOpE -_ZN9oceanbase11transaction9tablelock17ObOBJLockCallback13get_data_sizeEv -_ZN9oceanbase11transaction9tablelock12ObLockMemCtx15add_lock_recordERKNS1_13ObTableLockOpERPNS1_22ObMemCtxLockOpLinkNodeEb -_ZN9oceanbase8memtable24ObMemtableCtxCbAllocator5allocEl -_ZN9oceanbase8memtable10ObIMvccCtx23register_table_lock_cb_EPNS_11transaction9tablelock14ObLockMemtableEPNS3_22ObMemCtxLockOpLinkNodeERPNS3_17ObOBJLockCallbackE -_ZN9oceanbase8memtable16ObITransCallback13before_appendEb -_ZN9oceanbase8memtable16ObITransCallback12after_appendEb -_ZN9oceanbase8memtable16ObTxCallbackList15append_callbackEPNS0_16ObITransCallbackEb -_ZN9oceanbase8memtable16ObTxCallbackList13SpinLockGuardC2ERNS_6common7ObLatchE -_ZN9oceanbase8memtable17ObMvccRowCallback13before_appendEb -_ZN9oceanbase11transaction14ObPartTransCtx15submit_redo_logEb -_ZN9oceanbase3sql16ObDASUpdIterator12get_next_rowERPNS_6common8ObNewRowE -_ZN9oceanbase3sql10ObDASUtils19project_storage_rowERKNS0_17ObDASDMLBaseCtDefERKNS0_17ObChunkDatumStore9StoredRowERKNS_6common12ObFixedArrayIlNS9_12ObIAllocatorEEERSB_RNS9_8ObNewRowE -_ZN9oceanbase7storage14ObDMLBaseParamD2Ev -_ZN9oceanbase11transaction14ObTransService14create_tx_ctx_ERKNS_5share6ObLSIDEPNS_7storage4ObLSERKNS0_8ObTxDescERPNS0_14ObPartTransCtxE -_ZN9oceanbase6common23ObOptStatMonitorManager18update_local_cacheEmRNS0_12ObOptDmlStatE -_ZN9oceanbase6common4hash15LatchReadLockerD2Ev -_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImPNS1_9ObHashMapISt4pairImmENS0_12ObOptDmlStatENS1_24LatchReadWriteDefendModeENS1_9hash_funcIS6_EENS1_8equal_toIS6_EENS1_13SimpleAllocerINS1_15ObHashTableNodeINS3_IS6_S7_EEEELi65ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_13NormalPointerENS0_8ObMallocELl1EEEEENS9_ImEENSB_ImEENS1_10pair_firstISO_EENSD_INSE_ISO_EELi109ESH_SI_EES8_SK_SL_Ll1EE11read_atomicINS0_23ObOptStatMonitorManager15ReadMapAtomicOpENS1_8pre_procISO_EEEEiRKmRT_RT0_ -_ZN9oceanbase6common4hash15LatchReadLockerC2ERNS0_7ObLatchE -_ZN9oceanbase7storage19ObStorageTableGuardD1Ev -_ZN9oceanbase7storage19ObStorageTableGuardD2Ev -_ZN9oceanbase8memtable10ObMemtable13dec_write_refEv -_ZN9oceanbase7storage23ObStorageSchemaRecorder25try_update_storage_schemaEllRNS_6common12ObIAllocatorEl -_ZN9oceanbase8memtable16ObTxCallbackList13SpinLockGuardD2Ev -_ZN9oceanbase11transaction12ObLSTxCtxMgr13create_tx_ctxERKNS0_13ObTxCreateArgERbRPNS0_14ObPartTransCtxE -_ZNK9oceanbase10logservice16ObLogHandlerBase8get_roleERNS_6common6ObRoleERl -_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_10ObTransCtxENS0_13TransCtxAllocENS_6common10SpinRWLockELl16384EE16BucketWLockGuardC2ERKS6_m -_ZN9oceanbase6common18ObServerObjectPoolINS_11transaction14ObPartTransCtxEE13borrow_objectEv -_ZN9oceanbase7storage17ObLSTabletService24check_old_row_legitimacyERNS0_14ObTabletHandleERNS0_15ObDMLRunningCtxERKNS_6common8ObNewRowE -_ZN9oceanbase7storage15ObRelativeTableD1Ev -_ZN9oceanbase7storage15ObRelativeTableD2Ev -_ZN9oceanbase6common15ObLinearHashMapINS0_9ObIntWarpENS_11transaction9ObTransIDENS0_14ShareMemMgrTagEE17load_factor_ctrl_Em -_ZZN9oceanbase8memtable10ObMemtable4set_ERNS_7storage10ObStoreCtxEmRKNS2_15ObTableReadInfoERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS2_10ObStoreRowEPSH_PKNS9_IlEEENK5$_268clEPKc -_ZN9oceanbase11transaction12ObLSTxCtxMgr35try_wait_gts_and_inc_max_commit_ts_Ev -_ZZN9oceanbase8memtable8ObMtHash6insertEPKNS0_20ObStoreRowkeyWrapperEPKNS0_9ObMvccRowEENKUlPKcE0_clES9_ -_ZN9oceanbase6common23ObOptStatMonitorManager15ReadMapAtomicOpclERNS0_4hash11HashMapPairImPNS3_9ObHashMapISt4pairImmENS0_12ObOptDmlStatENS3_24LatchReadWriteDefendModeENS3_9hash_funcIS7_EENS3_8equal_toIS7_EENS3_13SimpleAllocerINS3_15ObHashTableNodeINS4_IS7_S8_EEEELi65ENS3_19SpinMutexDefendModeENS3_29DefaultSimpleAllocerAllocatorEEENS3_13NormalPointerENS0_8ObMallocELl1EEEEE -_ZN9oceanbase6common4hash16LatchWriteLockerD2Ev -_ZN9oceanbase6common4hash11ObHashTableISt4pairImmENS1_11HashMapPairIS4_NS0_12ObOptDmlStatEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi65ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14get_refactoredERKS4_RS7_l -_ZN9oceanbase6common4hash11ObHashTableISt4pairImmENS1_11HashMapPairIS4_NS0_12ObOptDmlStatEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi65ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE6atomicINS0_23ObOptStatMonitorManager19UpdateValueAtomicOpENS1_8pre_procIS7_EEEEiRKS4_RT_RT0_ -_ZN9oceanbase6common23ObOptStatMonitorManager19UpdateValueAtomicOpclERNS0_4hash11HashMapPairISt4pairImmENS0_12ObOptDmlStatEEE -_ZN9oceanbase6common4hash16LatchWriteLockerC2ERNS0_7ObLatchE -_ZN9oceanbase11transaction14ObPartTransCtx4initEmRKNS_6common6ObAddrEjRKNS0_9ObTransIDElRKNS_5share6ObLSIDEmPNS0_14ObTransServiceEmlPNS0_12ObLSTxCtxMgrEb -_ZN9oceanbase6common7ObDListINS_11transaction9ObTxLogCbEE8add_lastEPS3_ -_ZN9oceanbase11transaction9ObTxLogCb4initERKNS_5share6ObLSIDERKNS0_9ObTransIDEPNS0_10ObTransCtxEb -_ZN9oceanbase11transaction11ObCtxTxData5resetEv -_ZN9oceanbase11transaction11ObCtxTxData4initEPNS0_12ObLSTxCtxMgrEl -_ZN9oceanbase7storage13ObTxDataTable13alloc_tx_dataERNS0_13ObTxDataGuardE -_ZN9oceanbase8memtable18ObTransCallbackMgr11trans_startEv -_ZN9oceanbase7storage15ObTableHandleV2aSERKS1_ -_ZN9oceanbase11transaction12ObTxExecInfo5resetEv -_ZN9oceanbase8memtable13ObMemtableCtx4initEm -_ZN9oceanbase8memtable16ObQueryAllocator4initEm -_ZN9oceanbase8memtable24ObMemtableCtxCbAllocator4initEm -_ZNK9oceanbase6common11ObFifoArena42get_writing_throttling_trigger_percentage_Ev -_ZN9oceanbase8keybtree11WriteHandleINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE11split_childEPNS0_9BtreeNodeIS3_S5_EEiS3_S5_S3_S5_RS9_SA_l -_ZN9oceanbase8keybtree9BtreeNodeINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE4copyERS6_iii -_ZN9oceanbase8keybtree9BtreeNodeINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE15copy_and_insertERS6_iiiS3_S5_S3_S5_ -_ZN9oceanbase8keybtree18BtreeNodeAllocatorINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE10alloc_nodeEb -_ZN9oceanbase6common12ObSliceAlloc13prepare_blockEv -_ZZN9oceanbase11transaction14ObPartTransCtx4initEmRKNS_6common6ObAddrEjRKNS0_9ObTransIDElRKNS_5share6ObLSIDEmPNS0_14ObTransServiceEmlPNS0_12ObLSTxCtxMgrEbENK5$_135clEPKc -_ZNK9oceanbase6common11ObFifoArena14calc_mem_limitElll -_ZN9oceanbase7storage15ObTenantFreezer21get_tenant_mem_usage_ERNS0_17ObTenantFreezeCtxE -_ZN9oceanbase11transaction14ObPartTransCtx11start_transEv -_ZN9oceanbase5share11ObTenantEnv10set_tenantEPNS0_12ObTenantBaseE -_ZN9oceanbase5share12ObTenantBaseaSERKS1_ -_ZN9oceanbase5share12ObTenantBaseC1Emb -_ZN9oceanbase5share12ObTenantBaseC2Emb -_ZNK9oceanbase7storage12ObTenantInfo14get_freeze_ctxERNS0_17ObTenantFreezeCtxE -_ZN9oceanbase6common11ObFifoArena10alloc_pageEl -_ZN9oceanbase6common22ObMemstoreAllocatorMgr29get_tenant_memstore_allocatorEmRPNS0_20ObGMemstoreAllocatorE -_ZN9oceanbase6common12ObSliceAlloc12add_to_blistEPNS0_13ObBlockSlicerE -_ZN9oceanbase11transaction14ObTransHashMapINS0_9tablelock8ObLockIDENS2_9ObOBJLockENS2_14ObOBJLockAllocENS_6common10SpinRWLockELl1024EE8insert__ERKS3_PS4_iPSB_ -_ZN9oceanbase6common15ObLinearHashMapINS0_9ObIntWarpENS_11transaction9ObTransIDENS0_14ShareMemMgrTagEE7shrink_Ev -_ZN9oceanbase6common15ObLinearHashMapINS0_9ObIntWarpENS_11transaction9ObTransIDENS0_14ShareMemMgrTagEE23load_shrink_d_seg_bkts_EmmRPNS6_6BucketES9_ -_ZN9oceanbase6common15ObLinearHashMapINS0_9ObIntWarpENS_11transaction9ObTransIDENS0_14ShareMemMgrTagEE23load_expand_d_seg_bkts_EmmRPNS6_6BucketES9_ -_ZSt22__final_insertion_sortIN9oceanbase6common5array17ObSEArrayIteratorIlLl8ENS1_19ModulePageAllocatorELb0EEEN9__gnu_cxx5__ops15_Iter_less_iterEEvT_S9_T0_ +_ZN9oceanbase3sql11ObSqlBitSetILl32ElLb0EED2Ev _ZN9oceanbase3sql13AllocOpHelperILi2EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE _ZN9oceanbase12blocksstable17ObTmpFileIOHandleC1Ev _ZN9oceanbase6common8ObRandomC1Ev _ZN9oceanbase6common8ObRandomC2Ev -_ZN9oceanbase7storage16ObTableScanRange11init_rangesERKNS_6common8ObIArrayINS2_10ObNewRangeEEERKNS2_11ObQueryFlagEPKNS_12blocksstable19ObStorageDatumUtilsE -_ZN9oceanbase6common4hash11ObHashTableImNS1_12ObReferedMapImNS_10rootserver14DRUnitStatInfoEE4ItemENS1_9hash_funcImEENS1_8equal_toImEENS7_6GetKeyENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi5ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv -_ZN9oceanbase11transaction14ObTransService25create_implicit_savepointERNS0_8ObTxDescERKNS0_9ObTxParamERlb -_ZZN9oceanbase11transaction14ObTransService33create_global_implicit_savepoint_ERNS0_8ObTxDescERKNS0_9ObTxParamERlbENK6$_1690clEPKc -_ZN9oceanbase3sql15ObResolverUtils13resolve_constEPK10_ParseNodeNS0_4stmt8StmtTypeERNS_6common12ObIAllocatorENS7_15ObCollationTypeESA_PKNS7_14ObTimeZoneInfoERNS7_10ObObjParamEbRNS7_8ObStringEsSA_PNS0_11ObSqlBitSetILl96ENS0_14ObExprInfoFlagELb1EEEmb -_Z14ob_numchars_mbPK13ObCharsetInfoPKcS3_ +_ZN9oceanbase3sql16AllocInputHelperILi24EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecERPNS0_9ObOpInputE +_ZN9oceanbase3sql13ObDASUpdateOp7open_opEv +_ZN9oceanbase3sql12ObDMLService14init_dml_paramERKNS0_17ObDASDMLBaseCtDefERNS0_17ObDASDMLBaseRtDefERNS_11transaction16ObTxReadSnapshotERNS_6common12ObIAllocatorERNS_7storage14ObDMLBaseParamE +_ZN9oceanbase3sql20ObDASIndexDMLAdaptorILi3ENS0_16ObDASUpdIteratorEE10write_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERKNS0_13ObDASUpdCtDefERNS0_13ObDASUpdRtDefERS2_Rl +_ZN9oceanbase7storage15ObAccessService11update_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERNS_11transaction8ObTxDescERKNS0_14ObDMLBaseParamERKNS6_8ObIArrayImEESJ_PNS6_16ObNewRowIteratorERl +_ZN9oceanbase7storage15ObAccessService25audit_tablet_opt_dml_statERKNS0_14ObDMLBaseParamERKNS_6common10ObTabletIDENS5_16ObOptDmlStatTypeEl +_ZN9oceanbase7storage15ObAccessService20check_write_allowed_ERKNS_5share6ObLSIDERKNS_6common10ObTabletIDENS0_17ObStoreAccessTypeERKNS0_14ObDMLBaseParamERNS_11transaction8ObTxDescERNS1_15ObStoreCtxGuardE +_ZN9oceanbase7storage15ObAccessService15ObStoreCtxGuard4initERKNS_5share6ObLSIDE +_ZN9oceanbase11transaction9tablelock11get_lock_idERKNS_6common10ObTabletIDERNS1_8ObLockIDE +_ZN9oceanbase11transaction14ObPartTransCtx13check_status_Ev +_ZN9oceanbase7storage15ObTenantFreezer34check_tenant_out_of_memstore_limitERb +_ZZN9oceanbase7storage15ObAccessService25audit_tablet_opt_dml_statERKNS0_14ObDMLBaseParamERKNS_6common10ObTabletIDENS5_16ObOptDmlStatTypeElENK5$_136clEPKc +_ZNK9oceanbase11transaction8ObTxDesc13get_expire_tsEv +_ZN9oceanbase11transaction9tablelock11ObLockTable4lockERNS_7storage10ObStoreCtxERKNS1_11ObLockParamE +_ZN9oceanbase8memtable16ObMvccWriteGuard10write_authERNS_7storage10ObStoreCtxE +_ZNK9oceanbase11transaction9tablelock12ObLockMemCtx16check_lock_existERKNS1_8ObLockIDERKNS_5share10ObCommonIDEhNS1_17ObTableLockOpTypeERbRh +_ZZN9oceanbase8memtable13ObMemtableCtx10write_authEbENK5$_301clEPKc.llvm.566553378672739064 +_ZN9oceanbase6common7ObLatch10try_rdlockEj +_ZN9oceanbase6common4hash18ObPlacementHashSetINS0_11ObDLinkNodeINS_11transaction9ObTransIDEEELm16ELb0EED2Ev +_ZN9oceanbase6common7ObLatch10try_wrlockEjPKj +_ZN9oceanbase8memtable16ObMvccWriteGuardD1Ev +_ZZN9oceanbase11transaction14ObTransService14acquire_tx_ctxERKNS_5share6ObLSIDERKNS0_8ObTxDescERPNS0_14ObPartTransCtxEPNS_7storage4ObLSEbENK6$_1326clEPKc +_ZN9oceanbase11transaction14ObTransService19get_write_store_ctxERNS0_8ObTxDescERKNS0_16ObTxReadSnapshotENS_18concurrent_control11ObWriteFlagERNS_7storage10ObStoreCtxEb +__dynamic_cast +_ZN9oceanbase11transaction7CtxLock4lockEv +_ZN9oceanbase11transaction14ObTransService19get_tx_table_guard_EPNS_7storage4ObLSERKNS_5share6ObLSIDERNS2_14ObTxTableGuardE +_ZZN9oceanbase11transaction14ObTransService11get_tx_ctx_ERKNS_5share6ObLSIDEPNS_7storage4ObLSERKNS0_9ObTransIDERPNS0_14ObPartTransCtxEENK6$_1327clEPKc +_ZN9oceanbase11transaction12ObLSTxCtxMgr10get_tx_ctxERKNS0_9ObTransIDEbRPNS0_14ObPartTransCtxE +_ZN9oceanbase11transaction12CtxLockGuardD1Ev +_ZN9oceanbase11transaction12CtxLockGuardD2Ev +_ZN9oceanbase11transaction14ObTransService23handle_tx_commit_resultERKNS0_9ObTransIDEiNS_5share3SCNE +_ZZN9oceanbase11transaction14ObTransService19get_write_store_ctxERNS0_8ObTxDescERKNS0_16ObTxReadSnapshotENS_18concurrent_control11ObWriteFlagERNS_7storage10ObStoreCtxEbENK6$_1322clEPKc +_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_8ObTxDescENS0_11ObTxDescMgr13ObTxDescAllocENS_6common10SpinRWLockELl65536EE3getERKS2_RPS3_ +_ZN9oceanbase8memtable18ObTransCallbackMgr21acquire_callback_listEv +_ZN9oceanbase7storage15ObAccessService15ObStoreCtxGuardD2Ev +_ZNK9oceanbase7storage10ObStoreCtx8is_validEv +_ZN9oceanbase7storage15ObTxTableGuardsD2Ev +_ZN9oceanbase6common11ObArrayImplINS_11transaction16ObTransIDAndAddrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev +_ZZN9oceanbase11transaction14ObTransService14revert_tx_ctx_EPNS_7storage4ObLSEPNS0_14ObPartTransCtxEENK6$_1328clEPKc +_ZN9oceanbase11transaction14ObTransService16revert_store_ctxERNS_7storage10ObStoreCtxE +_ZN9oceanbase7storage15ObTxTableGuards16check_ls_offlineEv +_ZNK9oceanbase7storage13ObLSTxService13revert_tx_ctxEPNS_11transaction10ObTransCtxE +_ZZN9oceanbase11transaction14ObTransService41fetch_cflict_tx_ids_from_mem_ctx_to_desc_ERNS_8memtable15ObMvccAccessCtxEENK6$_1334clEPKc +_ZN9oceanbase11transaction14ObPartTransCtx15submit_redo_logEb +_ZN9oceanbase8memtable13ObMemtableCtx15add_lock_recordERKNS_11transaction9tablelock13ObTableLockOpE +_ZN9oceanbase8memtable10ObIMvccCtx23register_table_lock_cb_EPNS_11transaction9tablelock14ObLockMemtableEPNS3_22ObMemCtxLockOpLinkNodeERPNS3_17ObOBJLockCallbackE +_ZN9oceanbase11transaction9tablelock12ObLockMemCtx15add_lock_recordERKNS1_13ObTableLockOpERPNS1_22ObMemCtxLockOpLinkNodeEb +_ZN9oceanbase8memtable13ObMemtableCtx25alloc_table_lock_callbackERNS0_10ObIMvccCtxEPNS_11transaction9tablelock14ObLockMemtableE +_ZN9oceanbase11transaction9tablelock12ObLockMemCtx22alloc_lock_op_callbackEv +_ZN9oceanbase8memtable24ObMemtableCtxCbAllocator5allocEl +_ZNK9oceanbase7storage14ObIMemtableMgr19get_active_memtableERNS0_15ObTableHandleV2E +_ZN9oceanbase6common11ObQSyncLock8rdunlockEv +_ZN9oceanbase7storage15ObTableHandleV29set_tableEPNS0_8ObITableEPNS0_18ObTenantMetaMemMgrENS2_9TableTypeE +_ZN9oceanbase7storage8ObITable7inc_refEv +_ZN9oceanbase7storage16MemMgrRLockGuardC2ERKNS0_15MemtableMgrLockE +_ZN9oceanbase7storage15ObTableHandleV25resetEv +_ZN9oceanbase7storage8ObITable7dec_refEv +_ZNK9oceanbase7storage15ObRelativeTable19is_rowkey_column_idEmRb +_ZNK9oceanbase5share6schema9ColumnMap3getEmRi +_ZN9oceanbase8memtable13ObMemtableCtx19elr_trans_preparingEv +_ZNK9oceanbase6common10ObFunctionIFiPNS_8memtable16ObITransCallbackEEE7DerivedIZNS2_16ObTxCallbackList16tx_elr_preparingEvE5$_241E4copyERNS0_12ObIAllocatorEPv$d19ebe006a0061df2c0e66623d7c3b8d +_ZZN9oceanbase11transaction14ObPartTransCtx12start_accessERKNS0_8ObTxDescElENK5$_849clEPKc +_ZN9oceanbase6common11ObQSyncLock6rdlockEv +_ZN9oceanbase7storage17ObLSTabletService11update_rowsERNS0_14ObTabletHandleERNS0_10ObStoreCtxERKNS0_14ObDMLBaseParamERKNS_6common8ObIArrayImEESD_PNS9_16ObNewRowIteratorERl +_ZN9oceanbase8memtable16ObQueryAllocator5allocEl +_ZN9oceanbase7storage15ObDMLRunningCtxC1ERNS0_10ObStoreCtxERKNS0_14ObDMLBaseParamERNS_6common12ObIAllocatorES9_NS_12blocksstable9ObDmlFlagE +_ZN9oceanbase7storage20ObTableStoreIteratorC1Ebb +_ZN9oceanbase5share6schema19ObSchemaGetterGuardC1ENS1_15ObSchemaMgrItem3ModE +_ZN9oceanbase7storage15ObDMLRunningCtx4initEPKNS_6common8ObIArrayImEES6_PNS_5share6schema27ObMultiVersionSchemaServiceERNS0_14ObTabletHandleE +_ZNK9oceanbase5share6schema27ObMultiVersionSchemaService35get_tenant_refreshed_schema_versionEmRlb +_ZN9oceanbase7storage15ObRelativeTableD1Ev +_ZN9oceanbase7storage15ObRelativeTableD2Ev +_ZNK9oceanbase7storage14ObTabletHandle15calc_wash_scoreENS0_18WashTabletPriorityE +_ZN9oceanbase7storage8ObTablet31check_schema_version_with_cacheEl +_ZN9oceanbase6common10ObRowStoreD1Ev +_ZN9oceanbase7storage17ObLSTabletService15process_new_rowERNS0_14ObTabletHandleERNS0_15ObDMLRunningCtxERKNS_6common8ObIArrayIlEERKNS0_10ObStoreRowESD_b +_ZN9oceanbase7storage20ObTableAccessContextD1Ev +_ZN9oceanbase7storage20ObTableAccessContextD2Ev +_ZN9oceanbase3sql16ObDASUpdIterator12get_next_rowERPNS_6common8ObNewRowE +_ZN9oceanbase3sql10ObDASUtils19project_storage_rowERKNS0_17ObDASDMLBaseCtDefERKNS0_17ObChunkDatumStore9StoredRowERKNS_6common12ObFixedArrayIlNS9_12ObIAllocatorEEERSB_RNS9_8ObNewRowE +_ZZN9oceanbase3sql16ObDASUpdIterator12get_next_rowERPNS_6common8ObNewRowEENK5$_540clEPKc +_ZZN9oceanbase7storage8ObTablet31check_schema_version_with_cacheElENK6$_1317clEPKc +_ZN9oceanbase7storage8ObTablet13rowkey_existsERNS0_15ObRelativeTableERNS0_10ObStoreCtxERKNS_6common8ObNewRowERb +_ZN9oceanbase12blocksstable9ObSSTable5existERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS0_13ObDatumRowkeyERbSB_ +_ZN9oceanbase7storage19ObSSTableRowExisterD2Ev +_ZN9oceanbase12blocksstable10ObDatumRowD1Ev +_ZN9oceanbase12blocksstable10ObDatumRowD2Ev +_ZN9oceanbase7storage21ObIndexTreePrefetcherC2Ev +_ZN9oceanbase12blocksstable18ObMacroBlockReaderC1Ev +_ZN9oceanbase7storage18ObSSTableRowGetter18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowE +_ZN9oceanbase8memtable10ObMemtable5existERKNS_7storage16ObTableIterParamERNS2_20ObTableAccessContextERKNS_12blocksstable13ObDatumRowkeyERbSC_ +_ZN9oceanbase12blocksstable23ObIMicroBlockRowFetcherD2Ev +_ZN9oceanbase6common13ObObjCmpFuncs21compare_oper_nullsafeERKNS0_5ObObjES4_NS0_15ObCollationTypeENS0_7ObCmpOpE +_ZN9oceanbase11transaction7ObTsMgr7get_gtsEmPNS0_10ObTsCbTaskERNS_5share3SCNE +_ZN9oceanbase11transaction8ObTxDesc17execute_commit_cbEv +_ZN9oceanbase6common12ObLatchMutex8try_lockEjPKj +_ZN9oceanbase11transaction12ObLSTxCtxMgr23in_leader_serving_stateEv +_ZN9oceanbase7storage19ObSSTableRowExister9fetch_rowERNS0_19ObSSTableReadHandleERPKNS_12blocksstable10ObDatumRowE +_ZThn336_N9oceanbase12blocksstable21ObMicroBlockGetReader9exist_rowERKNS0_16ObMicroBlockDataERKNS0_13ObDatumRowkeyERKNS_7storage16ObITableReadInfoERbSC_ +_ZN9oceanbase12blocksstable22ObMicroBlockRowExister8is_existERKNS0_13ObDatumRowkeyERKNS0_16ObMicroBlockDataERbS8_ +_ZN9oceanbase12blocksstable21ObMicroBlockGetReader9exist_rowERKNS0_16ObMicroBlockDataERKNS0_13ObDatumRowkeyERKNS_7storage16ObITableReadInfoERbSC_ +_ZN9oceanbase12blocksstable23ObIMicroBlockRowFetcher14prepare_readerENS_6common14ObRowStoreTypeE +_ZN9oceanbase8memtable16ObQueryAllocator4freeEPv +_ZN9oceanbase6common13ObObjCmpFuncs11cmp_op_funcILNS0_14ObObjTypeClassE1ELS3_1ELNS0_7ObCmpOpE5EEEiRKNS0_5ObObjES7_RKNS0_12ObCompareCtxE +_ZN9oceanbase3sql23ObEndTransAsyncCallback8callbackEi +_ZN9oceanbase8observer15ObSqlEndTransCb8callbackEi +_ZN9oceanbase3sql17ObSqlTransControl22reset_session_tx_stateEPNS0_16ObSQLSessionInfoEb +_ZN9oceanbase7obmysql23ObPocSqlRequestOperator25alloc_sql_response_bufferEPNS_3rpc9ObRequestEl +_ZN9oceanbase3sql17ObSqlTransControl22reset_session_tx_stateEPNS0_18ObBasicSessionInfoEb +_ZThn8_N9oceanbase3sql16ObSQLSessionInfo17reset_tx_variableEv +_ZN9oceanbase11transaction14ObTransService8reuse_txERNS0_8ObTxDescE +_ZN9oceanbase11transaction11ObTxDescMgr6removeERNS0_8ObTxDescE +_ZZN9oceanbase11transaction11ObTxDescMgr6removeERNS0_8ObTxDescEENK4$_69clEPKc.llvm.9247052906010562532 +_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_8ObTxDescENS0_11ObTxDescMgr13ObTxDescAllocENS_6common10SpinRWLockELl65536EE3delERKS2_PS3_ +_ZN9oceanbase11transaction10ObTxCtxMgr17get_ls_tx_ctx_mgrERKNS_5share6ObLSIDERPNS0_12ObLSTxCtxMgrE +_ZN9oceanbase7storage17ObLSTabletService23process_old_row_lob_colERNS0_14ObTabletHandleERNS0_15ObDMLRunningCtxERNS0_10ObStoreRowE +_ZZN9oceanbase11transaction14ObTransService8reuse_txERNS0_8ObTxDescEENK6$_1655clEPKc +_ZN9oceanbase6common11ObArrayImplINS_11transaction9ObTransIDENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev +_ZN9oceanbase7storage17ObLSTabletService24check_old_row_legitimacyERNS0_14ObTabletHandleERNS0_15ObDMLRunningCtxERKNS_6common8ObNewRowE +_ZN9oceanbase3sql16ObSQLSessionInfo21set_show_warnings_bufEi +_ZN9oceanbase11transaction14ObTransService14create_tx_ctx_ERKNS_5share6ObLSIDEPNS_7storage4ObLSERKNS0_8ObTxDescERPNS0_14ObPartTransCtxEb +_ZN9oceanbase11transaction12ObLSTxCtxMgr13create_tx_ctxERKNS0_13ObTxCreateArgERbRPNS0_14ObPartTransCtxE +_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_10ObTransCtxENS0_13TransCtxAllocENS_6common10SpinRWLockELl16384EE8insert__ERKS2_PS3_iPSA_ +_ZN9oceanbase11transaction14ObPartTransCtx4initEmRKNS_6common6ObAddrEjRKNS0_9ObTransIDElRKNS_5share6ObLSIDEmPNS0_14ObTransServiceEmlPNS0_12ObLSTxCtxMgrEb +_ZN9oceanbase7storage19ObStorageMetaHandleC1Ev +_ZN9oceanbase11transaction9tablelock12ObLockMemCtx4initERNS_7storage15ObTableHandleV2E +_ZNK9oceanbase7storage8ObITable7get_refEv +_ZN9oceanbase11transaction11ObCtxTxData4initEPNS0_12ObLSTxCtxMgrEl +_ZN9oceanbase7storage13ObTxDataTable13alloc_tx_dataERNS0_13ObTxDataGuardE +_ZN9oceanbase7storage15ObTableHandleV2aSERKS1_ +_ZN9oceanbase11transaction9ObTxLogCb4initERKNS_5share6ObLSIDERKNS0_9ObTransIDEPNS0_10ObTransCtxEb +_ZN9oceanbase11transaction16ObLSTxLogAdapter8get_roleERbRl +_ZN9oceanbase11transaction17ObTransCtxFactory5allocEl +_ZN9oceanbase8memtable13ObMemtableCtx4initEm +_ZN9oceanbase8memtable16ObQueryAllocator4initEm +_ZN9oceanbase8memtable24ObMemtableCtxCbAllocator4initEm +_ZN9oceanbase8memtable18ObTransCallbackMgr11trans_startEv +_ZN9oceanbase12blocksstable21ObMicroBlockGetReaderD2Ev +_ZN9oceanbase11transaction9tablelock12ObOBJLockMap4lockERKNS1_11ObLockParamERNS_7storage10ObStoreCtxERKNS1_13ObTableLockOpERKhRNS_6common4hash19ObIteratableHashSetINS0_9ObTransIDELm16EEE +_ZN9oceanbase11transaction9tablelock9ObOBJLock17check_allow_lock_ERKNS1_13ObTableLockOpERKhRNS_6common4hash19ObIteratableHashSetINS0_9ObTransIDELm16EEERbbb +_ZN9oceanbase11transaction9tablelock12ObOBJLockMap32get_or_create_obj_lock_with_ref_ERKNS1_8ObLockIDERPNS1_9ObOBJLockE +_ZN9oceanbase11transaction14ObTransHashMapINS0_9tablelock8ObLockIDENS2_9ObOBJLockENS2_14ObOBJLockAllocENS_6common10SpinRWLockELl1024EE3getERKS3_RPS4_ +_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_10ObTransCtxENS0_13TransCtxAllocENS_6common10SpinRWLockELl16384EE16BucketWLockGuardC2ERKS6_m +_ZN9oceanbase7storage22ObMicroBlockDataHandle19get_data_block_dataERNS_12blocksstable18ObMacroBlockReaderERNS2_16ObMicroBlockDataE +_ZZN9oceanbase11transaction14ObPartTransCtx10end_accessEvENK5$_850clEPKc +_ZN9oceanbase11transaction12ObLSTxCtxMgr35try_wait_gts_and_inc_max_commit_ts_Ev +_ZN9oceanbase7storage21ObTenantTabletStatMgr11report_statERKNS0_12ObTabletStatE +_ZN9oceanbase6common23ObOptStatMonitorManager18update_local_cacheEmRNS0_12ObOptDmlStatE +_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImPNS1_9ObHashMapISt4pairImmENS0_12ObOptDmlStatENS1_24LatchReadWriteDefendModeENS1_9hash_funcIS6_EENS1_8equal_toIS6_EENS1_13SimpleAllocerINS1_15ObHashTableNodeINS3_IS6_S7_EEEELi65ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_13NormalPointerENS0_8ObMallocELl1EEEEENS9_ImEENSB_ImEENS1_10pair_firstISO_EENSD_INSE_ISO_EELi109ESH_SI_EES8_SK_SL_Ll1EE11read_atomicINS0_23ObOptStatMonitorManager15ReadMapAtomicOpENS1_8pre_procISO_EEEEiRKmRT_RT0_ +_ZN9oceanbase6common4hash11ObHashTableISt4pairImmENS1_11HashMapPairIS4_NS0_12ObOptDmlStatEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi65ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE6atomicINS0_23ObOptStatMonitorManager19UpdateValueAtomicOpENS1_8pre_procIS7_EEEEiRKS4_RT_RT0_ +_ZN9oceanbase11transaction9tablelock11ObLockTable17get_lock_memtableERNS_7storage15ObTableHandleV2E +_ZZNK9oceanbase11transaction14ObTxVersionMgr17get_max_commit_tsEbENKUlPKcE_clES3_ +_ZZN9oceanbase11transaction14ObTransService14create_tx_ctx_ERKNS_5share6ObLSIDEPNS_7storage4ObLSERKNS0_8ObTxDescERPNS0_14ObPartTransCtxEbENK6$_1330clEPKc +_ZN9oceanbase11transaction10ObTransCtx13get_ctx_guardERNS0_12CtxLockGuardE +_ZN9oceanbase8memtable16ObTxCallbackList16tx_elr_preparingEv +_ZN9oceanbase8memtable16ObITransCallback19elr_trans_preparingEv +_ZNK9oceanbase6common10ObFunctionIFiPNS_8memtable16ObITransCallbackEEE7DerivedIZNS2_16ObTxCallbackList16tx_elr_preparingEvE5$_241E6invokeES4_$d19ebe006a0061df2c0e66623d7c3b8d +_ZZN9oceanbase11transaction14ObPartTransCtx4initEmRKNS_6common6ObAddrEjRKNS0_9ObTransIDElRKNS_5share6ObLSIDEmPNS0_14ObTransServiceEmlPNS0_12ObLSTxCtxMgrEbENK5$_135clEPKc +_ZN9oceanbase11transaction14ObTransService24handle_tx_commit_result_ERNS0_8ObTxDescEiNS_5share3SCNE +_ZN9oceanbase11transaction14ObTransService18tx_post_terminate_ERNS0_8ObTxDescE +_ZNK9oceanbase7storage12ObTenantInfo14get_freeze_ctxERNS0_17ObTenantFreezeCtxE +_ZZN9oceanbase11transaction11ObTxDescMgr3getERKNS0_9ObTransIDERPNS0_8ObTxDescEENK4$_66clEPKc.llvm.9247052906010562532 +_ZN9oceanbase7storage15ObTenantFreezer21get_tenant_mem_usage_ERNS0_17ObTenantFreezeCtxE +_ZZN9oceanbase11transaction11ObTxDescMgr6revertERNS0_8ObTxDescEENK4$_68clEPKc.llvm.9247052906010562532 +_ZZN9oceanbase11transaction8ObTxDesc17execute_commit_cbEvENK4$_15clEPKc +_ZZN9oceanbase11transaction14ObTransService23acquire_local_snapshot_ERKNS_5share6ObLSIDERNS2_3SCNEENK6$_1358clEPKc +_ZN9oceanbase11transaction14ObPartTransCtx11start_transEv +_ZN9oceanbase6common22ObMemstoreAllocatorMgr29get_tenant_memstore_allocatorEmRPNS0_20ObGMemstoreAllocatorE +_ZN9oceanbase3lib22get_tenant_memory_holdEmm +_ZNK9oceanbase3lib20ObTenantCtxAllocator8get_holdEv +_ZN9oceanbase11transaction14ObPartTransCtx27submit_redo_log_for_freeze_ERb +_ZN9oceanbase12blocksstable22ObEncodeBlockGetReader9exist_rowERKNS0_16ObMicroBlockDataERKNS0_13ObDatumRowkeyERKNS_7storage16ObITableReadInfoERbSC_ +_ZNK9oceanbase12blocksstable13ObFixRowIndex3getElRPKcRl +_ZN9oceanbase12blocksstable22ObEncodeBlockGetReader10locate_rowERKNS0_13ObDatumRowkeyERKNS0_19ObStorageDatumUtilsERPKcRlSB_RbRNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable20ObIEncodeBlockReader7do_initERKNS0_16ObMicroBlockDataEl +_ZN9oceanbase6common16ObLatchWaitQueue7wake_upERNS0_7ObLatchEb +_ZZN9oceanbase11transaction14ObPartTransCtx27submit_redo_log_for_freeze_ERbENK5$_281clEPKc +_ZN9oceanbase12blocksstable20ObIEncodeBlockReader5reuseEv +_ZN9oceanbase6common16ObLatchWaitQueue8try_lockINS0_7ObLatch12LowTryRDLockEEEiRNS1_13ObLatchBucketERNS0_10ObWaitProcEjjRT_ +_ZN9oceanbase12blocksstable20ObIEncodeBlockReader7prepareEml +_ZN9oceanbase6common11ObArrayImplINS_3sql16ObExprConstraintENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev +_ZN9oceanbase12blocksstable23ObIMicroBlockRowScanner4openERKNS0_12MacroBlockIdERKNS0_16ObMicroBlockDataEbb +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder4initERKNS0_16ObMicroBlockDataERKNS_7storage16ObITableReadInfoE +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder7do_initERKNS0_16ObMicroBlockDataE +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder11add_decoderElRKNS_6common9ObObjMetaERNS0_15ObColumnDecoderE +_ZN9oceanbase12blocksstable17ObDecoderCtxArray13get_ctx_arrayEl +_ZN9oceanbase6common16ObFixedArrayImplIPKNS_12blocksstable16ObIColumnDecoderENS0_12ObIAllocatorEE7reserveEl +_ZN9oceanbase12blocksstable19ObMicroBlockDecoderC1Ev +_ZN9oceanbase12blocksstable19ObTLDecoderCtxArray5allocEv +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder11inner_resetEv +_ZN9oceanbase12blocksstable19ObTLDecoderCtxArray4freeEPNS0_17ObDecoderCtxArrayE +_ZN9oceanbase6common16ObFixedArrayImplIPKNS_12blocksstable16ObIColumnDecoderENS0_12ObIAllocatorEE4initEl +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder7acquireElRPKNS0_16ObIColumnDecoderE +_ZNK9oceanbase12blocksstable16ObIColumnDecoder15get_ref_col_idxERl +_ZN9oceanbase12blocksstable19ObEncodingAllocatorINS0_16ObIColumnDecoderEE5allocINS0_12ObRawDecoderEEEiRPT_ +_ZN9oceanbase12blocksstable18ObMicroBlockReaderC2Ev +_ZN9oceanbase12blocksstable19ObEncodingAllocatorINS0_16ObIColumnDecoderEE5allocINS0_19ObStringDiffDecoderEEEiRPT_ +_ZN9oceanbase6common16ObFixedArrayImplIPKNS_12blocksstable16ObIColumnDecoderENS0_12ObIAllocatorEE9push_backERKS5_ +_ZN9oceanbase12blocksstable19ObEncodingAllocatorINS0_16ObIColumnDecoderEE5allocINS0_24ObIntegerBaseDiffDecoderEEEiRPT_ +_ZN9oceanbase12blocksstable19ObEncodingAllocatorINS0_16ObIColumnDecoderEE5allocINS0_14ObConstDecoderEEEiRPT_ +_ZN9oceanbase8observer16ObMPPacketSender14send_ok_packetERNS_3sql16ObSQLSessionInfoERNS0_10ObOKPParamEPNS_7obmysql13ObMySQLPacketE +_ZN9oceanbase6common11ObArrayImplINS_3sql12ObPCPrivInfoENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev +_ZN9oceanbase3sql13AllocOpHelperILi25EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE +_ZN9oceanbase3sql15ObTableModifyOpC2ERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputE +_ZZN9oceanbase7storage13ObSingleMerge22get_and_fuse_cache_rowEllRNS_12blocksstable10ObDatumRowERbS5_S5_ENK5$_390clEPKc +_ZN9oceanbase3lib7ABitSet3setEi +_ZN9oceanbase6common11ObQSyncLock6wrlockEv +_ZN9oceanbase6common11ObArrayImplINS_3sql9ObDopHintENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev +_ZNK9oceanbase6common4hash11ObHashTableINS_3sql3dtl20ObDTLIntermResultKeyENS1_11HashMapPairIS5_PNS4_21ObDTLIntermResultInfoEEENS1_9hash_funcIS5_EENS1_8equal_toIS5_EENS1_10pair_firstIS9_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS9_EELi82ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE18foreach_refactoredINS4_19ObDTLIntermResultGCEEEiRT_ +_ZN9oceanbase6common11ObArrayImplINS_5share6schema18ObSchemaObjVersionENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_17DefaultItemEncodeIS4_EEED2Ev _ZN9oceanbase3sql13AllocOpHelperILi30EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE _ZN9oceanbase3sql10ObOperatorC2ERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputE +_ZN9oceanbase6common11ObArrayImplINS_3sql18ObPCParamEqualInfoENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev _ZN9oceanbase8memtable13ObQueryEngine8IteratorINS_8keybtree13BtreeIteratorINS0_20ObStoreRowkeyWrapperEPNS0_9ObMvccRowEEEE5resetEv -_ZN9oceanbase6common17ObSessionDIBuffer13reset_sessionEv -_ZN9oceanbase7storage19ObMultipleScanMerge15set_rows_mergerEl -_ZN9oceanbase6common11ObLoserTreeINS_7storage24ObScanMergeLoserTreeItemENS2_23ObScanMergeLoserTreeCmpELl80EE4initElRNS0_12ObIAllocatorE -_ZN9oceanbase3sql13ObExecContext18create_expr_op_ctxEmlRPv -_ZN9oceanbase6common11ObQSyncLock6wrlockEv +_ZN9oceanbase6common11ObArrayImplINS_3sql13ObMonitorHintENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev _ZN9oceanbase12blocksstable19ObMicroBlockDecoderD2Ev -_ZN9oceanbase3lib16ObFreeLogPrinter12get_instanceEv +_ZN9oceanbase7storage16ObTableScanRange11init_rangesERKNS_6common8ObIArrayINS2_10ObNewRangeEEERKNS2_11ObQueryFlagEPKNS_12blocksstable19ObStorageDatumUtilsE +_ZSt6__sortIN9oceanbase6common5array17ObSEArrayIteratorINS0_12blocksstable12ObDatumRangeELl8ENS1_19ModulePageAllocatorELb0EEEN9__gnu_cxx5__ops15_Iter_comp_iterINS4_15ObDatumComparorIS5_EEEEEvT_SE_T0_ +_ZN9__gnu_cxx5__ops14_Val_comp_iterIN9oceanbase12blocksstable15ObDatumComparorINS3_12ObDatumRangeEEEEclIS5_NS2_6common5array17ObSEArrayIteratorIS5_Ll8ENS9_19ModulePageAllocatorELb0EEEEEbRT_T0_ +_ZZN9oceanbase3sql11ObPlanCache13get_cache_objERNS0_14ObILibCacheCtxEPNS0_14ObILibCacheKeyERNS0_15ObCacheObjGuardEENK5$_199clEPKc.llvm.3267000005131453400 +_ZNK9oceanbase7obmysql6OMPKOK9serializeEPclRl +_ZN9oceanbase11transaction14ObTransService25create_implicit_savepointERNS0_8ObTxDescERKNS0_9ObTxParamERlb +_ZZN9oceanbase11transaction14ObTransService33create_global_implicit_savepoint_ERNS0_8ObTxDescERKNS0_9ObTxParamERlbENK6$_1703clEPKc.llvm.9247052906010562532 +_ZN9oceanbase11transaction30ObTransDeadlockDetectorAdapter36maintain_deadlock_info_when_end_stmtERNS_3sql13ObExecContextEb +_ZN9oceanbase5share8detector21ObDeadLockDetectorMgr14unregister_keyINS_11transaction9ObTransIDEEEiRKT_ +_ZN9oceanbase6common6DCHashINS_5share8detector13UserBinaryKeyELl8EE3getERKS4_RPNS0_11KeyHashNodeIS4_EE +_ZN9oceanbase11transaction8ObTxDesc18reset_conflict_txsEv +_ZN9oceanbase11transaction8ObTxDesc18fetch_conflict_txsERNS_6common8ObIArrayINS0_16ObTransIDAndAddrEEE +_ZNK9oceanbase5share8detector13UserBinaryKey7compareERKS2_ +_ZN9oceanbase12blocksstable21ObMicroBlockRowGetter7get_rowERNS_7storage19ObSSTableReadHandleERPKNS0_10ObDatumRowERNS0_18ObMacroBlockReaderE +_ZN9oceanbase12blocksstable21ObMicroBlockGetReader7get_rowERKNS0_16ObMicroBlockDataERKNS0_13ObDatumRowkeyERKNS_7storage16ObITableReadInfoERNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable21ObMicroBlockGetReader10inner_initERKNS0_16ObMicroBlockDataERKNS_7storage16ObITableReadInfoERKNS0_13ObDatumRowkeyE +_ZN9oceanbase12blocksstable21ObMicroBlockGetReader13locate_rowkeyERKNS0_13ObDatumRowkeyERl +_ZN9oceanbase12blocksstable18ObBloomFilterCache14inc_empty_readEmmRKNS0_12MacroBlockIdEl +_ZN9oceanbase12blocksstable21ObMicroBlockRowGetter17get_not_exist_rowERKNS0_13ObDatumRowkeyERPKNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable22ObEncodeBlockGetReader7get_rowERKNS0_16ObMicroBlockDataERKNS0_13ObDatumRowkeyERKNS_7storage16ObITableReadInfoERNS0_10ObDatumRowE +_ZN9oceanbase6common7ObDITlsINS_12blocksstable19ObTLDecoderCtxArrayELm1EE12get_instanceEv _ZN9oceanbase3sql16AllocDASOpHelperILi2EE5allocERNS_6common12ObIAllocatorERPNS0_12ObIDASTaskOpE _ULx86_64_r_uc_addr -_ZN9oceanbase6common12ObBucketLock12try_lock_allEb -_ZN9oceanbase11transaction12ObLSTxCtxMgr11get_rec_scnERNS_5share3SCNE -_ZN9oceanbase11transaction18GetRecLogTSFunctor17internal_operatorERKNS0_9ObTransIDEPNS0_14ObPartTransCtxE -_ZN9oceanbase7storage16ObTxCtxTableInfoC2Ev -_ZN9oceanbase11transaction9tablelock15ObTableLockInfo5resetEv -_ZN9oceanbase11transaction12ObTxExecInfoC2Ev -_ZN9oceanbase6common9ObSEArrayINS_11transaction14ObTxBufferNodeELl1ENS0_19ModulePageAllocatorELb0EEC2Ev -_ZN9oceanbase6common9ObSEArrayINS_4palf3LSNELl10ENS0_19ModulePageAllocatorELb0EEC2Ev -_ZN9oceanbase6common9Ob2DArrayIPNS_3sql20ObAggregateProcessor8GroupRowELi65408ENS0_19ModulePageAllocatorELb0ENS0_9ObSEArrayIPS5_Ll64ES6_Lb0EEEED2Ev -_ZN9oceanbase6common9Ob2DArrayIPNS_3sql20ObAggregateProcessor8GroupRowELi65408ENS0_19ModulePageAllocatorELb0ENS0_9ObSEArrayIPS5_Ll64ES6_Lb0EEEE7destroyEv +_ZZN9oceanbase5share17ObTabletLSService15get_from_cache_EmRKNS_6common10ObTabletIDERNS0_15ObTabletLSCacheEENK5$_462clEPKc +_ZN9oceanbase3sql8ObSortOp11inner_closeEv +_ZN9oceanbase3sql10ObFLTUtils35update_flush_policy_by_control_infoERNS0_16ObSQLSessionInfoE +_ZN9oceanbase6common8ObRandom4randEll +_ZN9oceanbase3sql16ObFastParserBase8ObRawSql11strncasecmpEPKcl +_ZZN9oceanbase3sql15ObTableModifyOp23get_next_row_from_childEvENK5$_793clEPKc.llvm.10049393316941204862 +_ZN9oceanbase3sql15ObTableDeleteOp10inner_openEv +_ZN9oceanbase6common11ObArrayWrapINS_3sql10ObDelRtDefEE14allocate_arrayERNS0_12ObIAllocatorEl +_ZN9oceanbase3sql15ObTableModifyOp10inner_openEv +_ZN9oceanbase3sql15ObTableInsertOp26check_need_exec_single_rowEv +_ZN9oceanbase3sql12ObDMLService14init_del_rtdefERNS0_10ObDMLRtCtxERNS0_10ObDelRtDefERKNS0_10ObDelCtDefE +_ZN9oceanbase3sql12ObDMLService22init_related_das_rtdefERNS0_10ObDMLRtCtxERKNS_6common12ObFixedArrayIPNS0_17ObDASDMLBaseCtDefENS4_12ObIAllocatorEEERNS4_11ObArrayWrapIPNS0_17ObDASDMLBaseRtDefEEE +_ZN9oceanbase3sql12ObDMLService18init_das_dml_rtdefERNS0_10ObDMLRtCtxERKNS0_17ObDASDMLBaseCtDefERNS0_17ObDASDMLBaseRtDefEPKNS0_17ObDASTableLocMetaE +_ZN9oceanbase3sql16ObDASTaskFactory16create_das_rtdefENS0_11ObDASOpTypeERPNS0_14ObDASBaseRtDefE +_ZN9oceanbase6common11ObArrayWrapIPNS_3sql17ObDASDMLBaseRtDefEE14allocate_arrayERNS0_12ObIAllocatorEl +_ZN9oceanbase3sql19AllocDASRtDefHelperILi3EE5allocERNS_6common12ObIAllocatorERPNS0_14ObDASBaseRtDefE +_ZN9oceanbase3sql19AllocDASRtDefHelperILi2EE5allocERNS_6common12ObIAllocatorERPNS0_14ObDASBaseRtDefE +_ZN9oceanbase3sql19AllocDASRtDefHelperILi4EE5allocERNS_6common12ObIAllocatorERPNS0_14ObDASBaseRtDefE +_ZN9oceanbase3sql8ObDASCtx18extended_table_locERKNS0_17ObDASTableLocMetaERPNS0_13ObDASTableLocE +_ZNK9oceanbase3sql12ObQueryRange21generate_single_rangeERNS1_13ObSearchStateElRPNS_6common10ObNewRangeERb +_ZN9oceanbase6common16ObFixedArrayImplImNS0_12ObIAllocatorEE9push_backERKm +_ZN9oceanbase6common16ObFixedArrayImplImNS0_12ObIAllocatorEE7reserveEl +_ZN9oceanbase6common16ObFixedArrayImplImNS0_12ObIAllocatorEE4initEl +_ZN9oceanbase5trace4UUID3genEv +_ZN9oceanbase10rootserver26ObMigrateUnitFinishChecker23try_finish_migrate_unitERKNS_6common4hash12ObReferedMapImNS0_14DRUnitStatInfoEEE +_ZZN9oceanbase5share24ObOrderPerservingEncoder25encode_from_string_varlenENS_6common8ObStringEPhlRlRNS0_10ObEncParamEENK6$_1289clEPKc.llvm.18054540717088142290 unw_init_local_common +_ZN9oceanbase3sql13ObCmdExecutor7executeERNS0_13ObExecContextERNS0_6ObICmdE +_ZZN9oceanbase3sql13ObCmdExecutor7executeERNS0_13ObExecContextERNS0_6ObICmdEENK4$_22clEv +_ZZN9oceanbase3sql13ObCmdExecutor7executeERNS0_13ObExecContextERNS0_6ObICmdEENK4$_21clEv +_ZN9oceanbase3sqlL14get_tx_serviceEPNS0_18ObBasicSessionInfoERPNS_11transaction14ObTransServiceE.llvm.7850757607881253614 +_ZN9oceanbase3sql17ObSqlTransControl20explicit_start_transERNS0_13ObExecContextEbNS_6common8ObStringE +_ZN9oceanbase11transaction14ObTransService8start_txERNS0_8ObTxDescERKNS0_9ObTxParamE +_ZN9oceanbase11transaction11ObTxDescMgr3addERNS0_8ObTxDescE +_ZNSt17_Function_handlerIFiRN9oceanbase11transaction9ObTransIDEESt5_BindIFMNS1_14ObTransServiceEFiS3_EPS6_St12_PlaceholderILi1EEEEE9_M_invokeERKSt9_Any_dataS3_ +_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_8ObTxDescENS0_11ObTxDescMgr13ObTxDescAllocENS_6common10SpinRWLockELl65536EE8insert__ERKS2_PS3_iPSB_ +_ZN9oceanbase3sqlL15build_tx_param_EPNS0_16ObSQLSessionInfoERNS_11transaction9ObTxParamEPKb +_ZN9oceanbase11transaction14ObTransService12gen_trans_idERNS0_9ObTransIDE +_ZN9oceanbase11transaction14ObTransService10release_txERNS0_8ObTxDescE +_ZN9oceanbase11transaction11ObTxDescMgr13ObTxDescAlloc10free_valueEPNS0_8ObTxDescE +_ZN9oceanbase3sql18ObEndTransExecutor9end_transERNS0_13ObExecContextERNS0_14ObEndTransStmtE +_ZN9oceanbase3sql17ObSqlTransControl18explicit_end_transERNS0_13ObExecContextEbNS_6common8ObStringE +_ZN9oceanbase3sql17ObSqlTransControl9end_transERNS0_13ObExecContextEbbPNS0_23ObEndTransAsyncCallbackE +_ZN9oceanbase3sql17ObSqlTransControl13do_end_trans_EPNS0_16ObSQLSessionInfoEbblPNS0_23ObEndTransAsyncCallbackE +_ZNK9oceanbase11transaction9ObTransID18get_serialize_sizeEv +_ZN9oceanbase5share8detector21ObDeadLockDetectorMgr20check_detector_existINS_11transaction9ObTransIDEEEiRKT_Rb +_ZZN9oceanbase11transaction14ObTransService13do_commit_tx_ERNS0_8ObTxDescElRNS0_13ObITxCallbackERNS_5share3SCNEENK6$_1242clEPKc +_ZN9oceanbase3sql15ObSQLSessionMgr15inc_session_refEPKNS0_16ObSQLSessionInfoE +_ZZN9oceanbase11transaction11ObTxDescMgr3addERNS0_8ObTxDescEENK4$_58clEPKc +_ZZN9oceanbase11transaction14ObTransService10release_txERNS0_8ObTxDescEENK6$_1650clEPKc +_ZN9oceanbase6common13ObLinkHashMapINS_5share8detector13UserBinaryKeyENS3_19ObIDeadLockDetectorENS3_21ObDeadLockDetectorMgr16InnerAllocHandleENS0_9RefHandleELl8EE3getERKS4_RPS5_ +_ZN9oceanbase11transaction11ObGtiSource12get_trans_idERl +_ZN9oceanbase6common13ObLinkHashMapINS_3sql14SessionInfoKeyENS2_16ObSQLSessionInfoENS2_15ObSQLSessionMgr10ValueAllocENS0_9RefHandleELl8EE3getERKS3_RPS4_ +_ZN9oceanbase11transaction14ObTransService16submit_commit_txERNS0_8ObTxDescElRNS0_13ObITxCallbackEPKNS_6common8ObStringE +_ZN9oceanbase11transaction8ObTxDesc13set_commit_cbEPNS0_13ObITxCallbackE +_ZN9oceanbase11transaction14ObTransService19local_ls_commit_tx_ERKNS0_9ObTransIDERKNS_5share6ObLSIDERKNS_6common9ObSEArrayIS6_Ll3ENS9_19ModulePageAllocatorELb0EEERKlRKNS9_8ObStringESG_RNS5_3SCNERKNS9_6ObAddrE +_ZN9oceanbase11transaction10ObTransCtx19set_app_trace_info_ERKNS_6common8ObStringE +_ZN9oceanbase11transaction10ObTxCtxMgr10get_tx_ctxERKNS_5share6ObLSIDERKNS0_9ObTransIDEbRPNS0_14ObPartTransCtxE +_ZN9oceanbase11transaction14ObTransHashMapINS_5share6ObLSIDENS0_12ObLSTxCtxMgrENS0_17ObLSTxCtxMgrAllocENS_6common11ObQSyncLockELl64EE3getERKS3_RPS4_ +_ZN9oceanbase11transaction14ObPartTransCtx16do_local_tx_end_ENS0_11TxEndActionE +_ZN9oceanbase11transaction14ObPartTransCtx19notify_data_source_ENS0_10NotifyTypeERKNS_5share3SCNEbRKNS_6common9ObSEArrayINS0_14ObTxBufferNodeELl1ENS7_19ModulePageAllocatorELb0EEEb +_ZN9oceanbase11transaction14ObPartTransCtx24generate_commit_version_Ev +_ZN9oceanbase11transaction14ObPartTransCtx31prepare_mul_data_source_tx_end_Eb +_ZN9oceanbase11transaction11ObCtxTxData18set_commit_versionERKNS_5share3SCNE +_ZN9oceanbase11transaction14ObPartTransCtx8get_gts_ERNS_5share3SCNE +_ZN9oceanbase11transaction10ObTxCtxMgr13revert_tx_ctxEPNS0_14ObPartTransCtxE +_ZZN9oceanbase11transaction14ObTransService22decide_tx_commit_info_ERNS0_8ObTxDescERPNS0_8ObTxPartEENK6$_1277clEPKc +_ZN9oceanbase11transaction14ObPartTransCtx16submit_log_impl_ENS0_11ObTxLogTypeE +_ZN9oceanbase6common13ObSEArrayImplINS_11transaction9ObTxCbArgELl3ENS0_19ModulePageAllocatorELb0EE9push_backERKS3_ +_ZNK9oceanbase10logservice12ObLogHandler8is_validEv +_ZN9oceanbase11transaction12ObTxLogBlock11add_new_logINS0_13ObTxCommitLogEEEiRT_PNS0_17ObTxBigSegmentBufE +_ZNK9oceanbase11transaction13ObTxLogHeader9serializeEPclRl +_ZN9oceanbase11transaction13ObTxCommitLog16before_serializeEv +_ZN9oceanbase11transaction18ObTxLogBlockHeader16before_serializeEv +_ZN9oceanbase11transaction14ObPartTransCtx17after_submit_log_ERNS0_12ObTxLogBlockEPNS0_9ObTxLogCbEPNS_8memtable21ObRedoLogSubmitHelperE +_ZN9oceanbase8memtable16ObITransCallback13log_submittedEv +_ZN9oceanbase8memtable18ObRedoLogGenerator13log_submittedERKNS0_15ObCallbackScopeE +_ZN9oceanbase8memtable17ObMvccRowCallback13log_submittedEv +_ZN9oceanbase11transaction14ObTxELRHandler28check_and_early_lock_releaseEbPNS0_14ObPartTransCtxE +_ZN9oceanbase11transaction12ObTxLogBlock5reuseElRKNS0_18ObTxLogBlockHeaderE +_ZN9oceanbase11transaction11ObCtxTxData16set_start_log_tsERKNS_5share3SCNE +_ZNK9oceanbase11transaction11ObCtxTxData16get_start_log_tsEv +_ZN9oceanbase11transaction14ObPartTransCtx17get_prev_log_lsn_ERKNS0_12ObTxLogBlockENS0_11ObTxLogTypeERNS_4palf3LSNE +_ZN9oceanbase11transaction12ObTxLogBlock4initElRKNS0_18ObTxLogBlockHeaderEb +_ZN9oceanbase11transaction12ObTxLogBlock27serialize_log_block_header_ElRKNS0_18ObTxLogBlockHeaderENS_10logservice19ObReplayBarrierTypeE +_ZNK9oceanbase11transaction18ObTxLogBlockHeader10serialize_EPclRl +_ZNK9oceanbase6common6ObAddr9serializeEPclRl +_ZN9oceanbase11transaction16ObLSTxLogAdapter10submit_logEPKclRKNS_5share3SCNEPNS0_13ObTxBaseLogCbEb +_ZN9oceanbase11transaction16ObTransStatistic21add_clog_submit_countEml +_ZN9oceanbase11transaction16ObTransStatistic24add_trans_log_total_sizeEml +_ZZN9oceanbase10logservice12ObLogHandler6appendEPKvlRKNS_5share3SCNEbPNS0_8AppendCbERNS_4palf3LSNERS5_ENK5$_209clEPKc +_ZN9oceanbase6common13ObSEArrayImplINS_11transaction14ObTxBufferNodeELl1ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayIS3_EE +_ZN9oceanbase11transaction14ClogBufFactory5allocEv +_ZNK9oceanbase11transaction13ObTxCommitLog19get_serialize_size_Ev +_ZN9oceanbase6common13ObSEArrayImplINS_11transaction9ObTxCbArgELl3ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayIS3_EE +_ZN9oceanbase11transaction11ObTraceInfo18set_app_trace_infoERKNS_6common8ObStringE +_ZN9oceanbase10logservice12ObLogHandler6appendEPKvlRKNS_5share3SCNEbPNS0_8AppendCbERNS_4palf3LSNERS5_ +_ZN9oceanbase10logservice13ObApplyStatus14push_append_cbEPNS0_8AppendCbE +_ZN9oceanbase4palf14PalfHandleImpl10submit_logERKNS0_17PalfAppendOptionsEPKclRKNS_5share3SCNERNS0_3LSNERS8_ +_ZN9oceanbase4palf11PalfEnvImpl23check_disk_space_enoughEv +_ZN9oceanbase4palf16LogSlidingWindow10submit_logEPKclRKNS_5share3SCNERNS0_3LSNERS5_ +_ZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE3getElRPS2_ +_ZN9oceanbase4palf14LogGroupBuffer4fillERKNS0_3LSNEPKcl +_ZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE6revertEl +_ZN9oceanbase4palf14LogEntryHeader23update_header_checksum_Ev +_ZNK9oceanbase4palf14LogEntryHeader9serializeEPclRl +_ZZN9oceanbase4palf14LogGroupBuffer4fillERKNS0_3LSNEPKclENK5$_767clES6_ +_ZNK9oceanbase4palf16LogSlidingWindow14get_max_log_idEv +_ZZN9oceanbase4palf14LogEntryHeader15generate_headerEPKclRKNS_5share3SCNEENK5$_733clES3_.llvm.838520973738826390 +_ZZN9oceanbase4palf14LogEntryHeader23update_header_checksum_EvENK5$_732clEPKc.llvm.838520973738826390 +_ZZN9oceanbase4palf14LogGroupBuffer5fill_ERKNS0_3LSNElPKclENK5$_795clES6_ +_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE6revertElENKUlPKcE2_clES5_ +_ZZN9oceanbase4palf16LogSlidingWindow10submit_logEPKclRKNS_5share3SCNERNS0_3LSNERS5_ENK5$_138clES3_ +_ZN9oceanbase11transaction14ObPartTransCtx28submit_redo_commit_info_log_ERNS0_12ObTxLogBlockERbRNS_8memtable21ObRedoLogSubmitHelperE +_ZN9oceanbase11transaction12ObTxLogBlock11add_new_logINS0_17ObTxCommitInfoLogEEEiRT_PNS0_17ObTxBigSegmentBufE +_ZN9oceanbase11transaction17ObTxCommitInfoLog16before_serializeEv +_ZNK9oceanbase11transaction17ObTxCommitInfoLog19get_serialize_size_Ev +_ZNK9oceanbase6common6ObAddr19get_serialize_size_Ev +_ZN9oceanbase11transaction14ObPartTransCtx16submit_redo_log_ERNS0_12ObTxLogBlockERbRNS_8memtable21ObRedoLogSubmitHelperE +_ZN9oceanbase8memtable13ObMemtableCtx13fill_redo_logEPclRlRNS0_21ObRedoLogSubmitHelperEb +_ZN9oceanbase8memtable18ObRedoLogGenerator13fill_redo_logEPclRlRNS0_21ObRedoLogSubmitHelperEb +_ZN9oceanbase8memtable9ObRowData9serializeEPclRl +_ZN9oceanbase8memtable17ObMvccRowCallback8get_redoERNS0_12RedoDataNodeE +_ZNK9oceanbase6common8ObRowkey9serializeEPclRl +_ZN9oceanbase11transaction14ObPartTransCtx15prepare_log_cb_EbRPNS0_9ObTxLogCbE +_ZN9oceanbase11transaction12ObTxLogBlock11add_new_logINS0_11ObTxRedoLogEEEiRT_PNS0_17ObTxBigSegmentBufE +_ZN9oceanbase11transaction12ObTxLogBlock19prepare_mutator_bufERNS0_11ObTxRedoLogE +_ZN9oceanbase11transaction12ObTxLogBlock18finish_mutator_bufERNS0_11ObTxRedoLogERKl +_ZN9oceanbase11transaction13ObCtxRedoInfo16before_serializeEv +_ZNK9oceanbase11transaction11ObTxRedoLog9serializeEPclRl +_ZZN9oceanbase11transaction14ObTransService10release_txERNS0_8ObTxDescEENK6$_1651clEPKc +_ZZN9oceanbase4palf14LogGroupBuffer30inc_update_readable_begin_lsn_ERKNS0_3LSNEENK5$_784clEPKc.llvm.838520973738826390 +_ZN9oceanbase11transaction14ObTransService22decide_tx_commit_info_ERNS0_8ObTxDescERPNS0_8ObTxPartE +_ZN9oceanbase11transaction14ObPartTransCtx18update_rec_log_ts_EbRKNS_5share3SCNE +_ZN9oceanbase11transaction8ObTxDescD1Ev +_ZN9oceanbase11transaction8ObTxDescD2Ev +_ZN9oceanbase6common11ObArrayImplINS_11transaction16ObTransIDAndAddrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev +_ZN9oceanbase11transaction8ObTxDesc5resetEv +_ZN9oceanbase8memtable16ObTxCallbackList20tx_calc_checksum_allEv +_ZN9oceanbase8memtable16ObITransCallback13calc_checksumENS_5share3SCNEPNS_6common15ObBatchChecksumE +_ZNK9oceanbase11transaction13ObTxCommitLog9serializeEPclRl +_ZNK9oceanbase11transaction17ObTxCommitInfoLog9serializeEPclRl +_ZNK9oceanbase6common13ObSEArrayImplINS_5share6ObLSIDELl3ENS0_19ModulePageAllocatorELb0EE9serializeEPclRl +_ZNK9oceanbase5share6ObLSID9serializeEPclRl +_ZZN9oceanbase11transaction14ObPartTransCtx25submit_multi_data_source_ERNS0_12ObTxLogBlockEENK5$_754clEPKc +_ZZN9oceanbase4palf16LogSlidingWindow10submit_logEPKclRKNS_5share3SCNERNS0_3LSNERS5_ENK5$_130clES3_ +_ZN9oceanbase4palf16LogSlidingWindow24wait_group_buffer_ready_ERKNS0_3LSNEl +_ZN9oceanbase5share8detector21ObDeadLockDetectorMgr16DetectorRefGuardD1Ev +_ZN9oceanbase5share8detector21ObDeadLockDetectorMgr16DetectorRefGuardD2Ev +_ZZN9oceanbase4palf12LSNAllocator13alloc_lsn_scnERKNS_5share3SCNEllRKNS0_3LSNERS6_RlRS3_RbSC_SA_ENK5$_694clEPKc +_ZNK9oceanbase11transaction14ObTxDataBackup9serializeEPclRl +_ZNK9oceanbase5share3SCN9serializeEPclRl +_ZNK9oceanbase11transaction9ObTransID9serializeEPclRl +_ZN9oceanbase8memtable18ObTransCallbackMgr20inc_pending_log_sizeEl +_ZNK9oceanbase4palf14LogGroupBuffer18can_handle_new_logERKNS0_3LSNElS4_ +_ZN9oceanbase6common13ObSEArrayImplINS_5share6ObLSIDELl3ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayIS3_EE +_ZZN9oceanbase4palf14PalfHandleImpl10submit_logERKNS0_17PalfAppendOptionsEPKclRKNS_5share3SCNERNS0_3LSNERS8_ENK5$_938clES6_ +_ZN9oceanbase11transaction14ObTransService10acquire_txERPNS0_8ObTxDescEj +_ZN9oceanbase11transaction11ObTxDescMgr5allocERPNS0_8ObTxDescE +_ZN9oceanbase6common15ObTimeWheelTask5resetEv +_ZN9oceanbase11transaction8ObTxDescC1Ev +_ZN9oceanbase11transaction8ObTxDescC2Ev +_ZN9oceanbase11transaction12ObTxLogBlockD2Ev +_ZN9oceanbase11transaction14ClogBufFactory7releaseEPNS0_6LogBufILl1965056EEE +_ZN9oceanbase6common18ObBaseResourcePoolINS_11transaction6LogBufILl1965056EEENS0_10RPStrLabelIXadL_ZNS0_8ObModIds17OB_TRANS_CLOG_BUFEEEEEE10free_node_EPNS8_4NodeE +_ZN9oceanbase6common17get_resource_poolINS_11transaction6LogBufILl1965056EEEXadL_ZNS0_8ObModIds17OB_TRANS_CLOG_BUFEEEEERNS0_14ObResourcePoolIT_NS0_10RPStrLabelIXT0_EEEEEv +_ZZN9oceanbase11transaction14ObTransService10acquire_txERPNS0_8ObTxDescEjENK6$_1647clEPKc +_ZN9oceanbase4palf16LogSlidingWindow23generate_new_group_log_ERKNS0_3LSNElRKNS_5share3SCNElRKNS0_7LogTypeEPKclRb +_ZZN9oceanbase11transaction14ObTransService12gen_trans_idERNS0_9ObTransIDEENK6$_1512clEPKc +_ZZN9oceanbase11transaction14ObTxVersionMgr20update_max_commit_tsERKNS_5share3SCNEbENKUlPKcE_clES7_ +_ZN9oceanbase3sql17ObSqlTransControl15inc_session_refEPKNS0_16ObSQLSessionInfoE +_ZN9oceanbase4palf16LogSlidingWindow20try_freeze_prev_log_ElRKNS0_3LSNERb +_ZN9oceanbase11transaction25ObMulSourceTxDataNotifier6notifyERKNS_6common9ObSEArrayINS0_14ObTxBufferNodeELl1ENS2_19ModulePageAllocatorELb0EEENS0_10NotifyTypeERKNS0_24ObMulSourceDataNotifyArgEPNS0_14ObPartTransCtxERl +_ZN9oceanbase11transaction10ObTransCtx8set_stc_ENS_6common13ObMonotonicTsE +_ZZN9oceanbase10logservice13ObApplyStatus14push_append_cbEPNS0_8AppendCbEENK4$_21clEPKc +_ZZN9oceanbase4palf16LogSlidingWindow10submit_logEPKclRKNS_5share3SCNERNS0_3LSNERS5_ENK5$_136clES3_ +_ZN9oceanbase11transaction10ObTransCtx8get_stc_Ev +_ZZN9oceanbase4palf7LogTask20try_freeze_by_myselfEvENK5$_663clEPKc +_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE6revertElENKUlPKcE6_clES5_ +_ZZN9oceanbase4palf7LogTask23set_initial_header_infoERKNS0_17LogTaskHeaderInfoEENK5$_657clEPKc +_ZZNK9oceanbase11transaction14ObTxVersionMgr15get_max_read_tsEvENKUlPKcE_clES3_ +_ZZN9oceanbase4palf16LogSlidingWindow23handle_next_submit_log_ERbENK5$_173clEPKc +_ZN9oceanbase11transaction14ObPartTransCtx25submit_multi_data_source_ERNS0_12ObTxLogBlockE +_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE6revertElENKUlPKcE3_clES5_ +_ZZNK9oceanbase8memtable17ObMvccRowCallback18is_logging_blockedEvENK5$_186clEPKc.llvm.7495450040363202369 +_ZN9oceanbase11transaction14ObPartTransCtx25submit_multi_data_source_Ev +_ZN9oceanbase11transaction14ObPartTransCtx16submit_redo_log_Ev _ZN9oceanbase3sql19ObScalarAggregateOp20inner_get_next_batchEl _ZN9oceanbase3sql20ObAggregateProcessor25process_aggr_batch_resultINS1_16ObBatchRowsSliceEEEiPKNS_6common8ObIArrayIPNS0_6ObExprEEERNS1_8AggrCellERKNS0_10ObAggrInfoERKT_ _ZN9oceanbase3sql20ObAggregateProcessor19collect_aggr_resultERNS1_8AggrCellEPKNS0_6ObExprERKNS0_10ObAggrInfoEll _ZN9oceanbase3sql20ObAggregateProcessor8AggrCell14collect_resultENS_6common14ObObjTypeClassERNS0_9ObEvalCtxERKNS0_10ObAggrInfoE _ZN9oceanbase6common6number8ObNumber10TAllocatorINS_3sql19ObNumStackAllocatorILl2EEEE5allocEl _ZN9oceanbase6common6number8ObNumber13from_integer_IlEEiT_RNS2_10IAllocatorE -_ZN9oceanbase3sql13ObDatumCaster7destroyEv +_ZN9oceanbase3sql16AllocDASOpHelperILi4EE5allocERNS_6common12ObIAllocatorERPNS0_12ObIDASTaskOpE _ZN9oceanbase3sql8ObSortOp7destroyEv _ZN9oceanbase12blocksstable17ObTmpFileIOHandle5resetEv _ZN9oceanbase12blocksstable17ObTmpFileIOHandleD1Ev _ZN9oceanbase12blocksstable17ObTmpFileIOHandleD2Ev +_ZN9oceanbase3sql13AllocOpHelperILi24EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE +_ZN9oceanbase3sql12ObQueryRange13ObSearchStateC2ERNS_6common12ObIAllocatorE _ZN9oceanbase3sql14ObExprValuesOp10inner_openEv -_ZN9oceanbase3sql13ObDatumCaster4initERNS0_13ObExecContextE _ZN9oceanbase3sql10ObSQLUtils21get_default_cast_modeEbjPKNS0_16ObSQLSessionInfoERm _ZN9oceanbase3sql10ObSQLUtils21get_default_cast_modeERKNS0_4stmt8StmtTypeEPKNS0_16ObSQLSessionInfoERm -_ZNK9oceanbase7obmysql6OMPKOK9serializeEPclRl -_ZZN9oceanbase5share24ObOrderPerservingEncoder25encode_from_string_varlenENS_6common8ObStringEPhlRlRNS0_10ObEncParamEENK6$_1289clEPKc -_ZN9oceanbase3sql17ObPhysicalPlanCtx19reserve_param_spaceEl -_ZN9oceanbase3sql15ObSchemaChecker17is_ora_priv_checkEv +_ZN9oceanbase3sql13ObDatumCaster4initERNS0_13ObExecContextE +_ZTWN9oceanbase3lib6Thread9sleep_us_E _ZN9oceanbase7storage13ObVectorStore4initERKNS0_18ObTableAccessParamE _ZN9oceanbase7storage22ObBlockBatchedRowStore4initERKNS0_18ObTableAccessParamE -_ZN9oceanbase5trace4UUID3genEv -_ZNSt24uniform_int_distributionImEclISt23mersenne_twister_engineImLm32ELm624ELm397ELm31ELm2567483615ELm11ELm4294967295ELm7ELm2636928640ELm15ELm4022730752ELm18ELm1812433253EEEEmRT_RKNS0_10param_typeE -_ZNSt23mersenne_twister_engineImLm32ELm624ELm397ELm31ELm2567483615ELm11ELm4294967295ELm7ELm2636928640ELm15ELm4022730752ELm18ELm1812433253EEclEv -_ZN9oceanbase3sql17ObSqlWorkareaUtil17get_workarea_sizeENS0_17ObSqlWorkAreaTypeElPNS0_13ObExecContextERl -_ZN9oceanbase3sql12ObSortOpImpl4initEmPKNS_6common8ObIArrayINS0_20ObSortFieldCollationEEEPKNS3_INS2_9ObCmpFuncEEEPNS0_9ObEvalCtxEPNS0_13ObExecContextEbbbllbl -_ZN9oceanbase3sql13AllocOpHelperILi26EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE -_ZN9oceanbase3sql16AllocInputHelperILi24EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecERPNS0_9ObOpInputE _ZN9oceanbase3sql10ObOperator12get_next_rowEv -_ZN9oceanbase3sql15ObTableModifyOp18inner_get_next_rowEv -_ZN9oceanbase3sql15ObTableModifyOp19submit_all_dml_taskEv _ZN9oceanbase3sql13ObDASUpdateOp10release_opEv _ZN9oceanbase3sql13ObDASDeleteOp10release_opEv _ZN9oceanbase3sql13ObDASInsertOp10release_opEv -_ZN9oceanbase3sql15ObTableModifyOp26discharge_das_write_bufferEv -_ZN9oceanbase3sql8ObDASRef5reuseEv -_ZZN9oceanbase3sql15ObTableModifyOp23get_next_row_from_childEvENK5$_793clEPKc -_ZN9oceanbase3sql19ObDataAccessService12end_das_taskERNS0_8ObDASRefERNS0_12ObIDASTaskOpE +_ZN9oceanbase6common12ObDataBuffer5allocEl +_ZN9oceanbase3sql15ObTableModifyOp19submit_all_dml_taskEv +_ZN9oceanbase3sql13ObDASUpdateOpD2Ev _ZN9oceanbase3sql14ObExprValuesOp18inner_get_next_rowEv +_ZN9oceanbase6common9ObCharset20charset_type_by_collENS0_15ObCollationTypeE +_ZN9oceanbase3sql17ObExprStrResAlloc5allocEl _ZN9oceanbase3sql13ObDatumCaster7to_typeERKNS0_11ObDatumMetaERKNS0_6ObExprERKmRPNS_6common7ObDatumEl _ZN9oceanbase3sql13ObDatumCaster15setup_cast_exprERKNS0_11ObDatumMetaERKNS0_6ObExprEmRS5_ -_ZN9oceanbase3sql13string_stringERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE +_ZN9oceanbase6common7ObDatum9deep_copyERKS1_RNS0_12ObIAllocatorE +_ZN9oceanbase3sql15ObTableUpdateOp20write_rows_post_procEi +_ZN9oceanbase3sql13ObDASInsertOpD2Ev _ZN9oceanbase3sql15ObTableInsertOp23write_row_to_das_bufferEv _ZN9oceanbase3sql15ObTableInsertOp15calc_tablet_locERKNS0_10ObInsCtDefERNS0_10ObInsRtDefERPNS0_14ObDASTabletLocE +_ZN9oceanbase6common6ObListINS0_10ObTabletIDENS0_12ObIAllocatorEE9push_backERKS2_ +_ZN9oceanbase3sql8ObDASCtx19extended_tablet_locERNS0_13ObDASTableLocERKNS_6common10ObTabletIDERPNS0_14ObDASTabletLocERKmSC_ +_ZN9oceanbase3sql13ObDASTableLoc14add_tablet_locEPNS0_14ObDASTabletLocE +_ZN9oceanbase3sql23ObExprCalcPartitionBase23calc_part_and_tablet_idEPKNS0_6ObExprERNS0_9ObEvalCtxERmRNS_6common10ObTabletIDE _ZN9oceanbase3sql12ObDMLService19write_row_to_das_opILi2EEEiRKNS0_17ObDASDMLBaseCtDefERNS0_17ObDASDMLBaseRtDefEPKNS0_14ObDASTabletLocERNS0_10ObDMLRtCtxERKNS_6common12ObFixedArrayIPNS0_6ObExprENSD_12ObIAllocatorEEESG_RPNS0_17ObChunkDatumStore9StoredRowE +_ZN9oceanbase3sql19ObDASLocationRouter14get_tablet_locERKNS0_17ObDASTableLocMetaERKNS_6common10ObTabletIDERNS0_14ObDASTabletLocE +_ZN9oceanbase6common14ObServerConfig12get_instanceEv +_ZN9oceanbase3sql23ObExprCalcPartitionBase26calc_no_partition_locationERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE +_ZN9oceanbase3sql8ObDASCtx21get_das_tablet_mapperEmRNS0_17ObDASTabletMapperEPKNS_6common12ObIArrayWrapImEE +_ZN9oceanbase5share6schema19ObSchemaGetterGuard16get_table_schemaEmmRPKNS1_13ObTableSchemaE +_ZN9oceanbase5share6schema19ObSchemaGetterGuard10get_schemaINS1_13ObTableSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_l _ZN9oceanbase3sql12ObDMLService18process_insert_rowERKNS0_10ObInsCtDefERNS0_10ObInsRtDefERNS0_15ObTableModifyOpERb _ZN9oceanbase3sql16ObExprColumnConv14column_convertERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE _ZN9oceanbase6common9ObCharset15well_formed_lenENS0_15ObCollationTypeEPKclRl -_ZN9oceanbase3sql13cast_eval_argERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE _ZN9oceanbase3sql20datum_accuracy_checkERKNS0_6ObExprEmRNS0_9ObEvalCtxERKNS_6common10ObAccuracyEbRKNS6_7ObDatumERSA_Ri -_ZN9oceanbase3sql23ObExprCalcPartitionBase23calc_part_and_tablet_idEPKNS0_6ObExprERNS0_9ObEvalCtxERmRNS_6common10ObTabletIDE -_ZN9oceanbase3sql23ObExprCalcPartitionBase26calc_no_partition_locationERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE -_ZN9oceanbase3sqlL20common_string_stringERKNS0_6ObExprENS_6common9ObObjTypeENS4_15ObCollationTypeES5_S6_RKNS4_8ObStringERNS0_9ObEvalCtxERNS4_7ObDatumERb -_ZN9oceanbase3sql11ObDASLockOp10release_opEv +_ZN9oceanbase3sql19ObDASLocationRouter19nonblock_get_leaderEmRKNS_6common10ObTabletIDERNS0_14ObDASTabletLocE _ZN9oceanbase3sql15ObTableDeleteOp23write_row_to_das_bufferEv _ZN9oceanbase3sql12ObDMLService19write_row_to_das_opILi4EEEiRKNS0_17ObDASDMLBaseCtDefERNS0_17ObDASDMLBaseRtDefEPKNS0_14ObDASTabletLocERNS0_10ObDMLRtCtxERKNS_6common12ObFixedArrayIPNS0_6ObExprENSD_12ObIAllocatorEEESG_RPNS0_17ObChunkDatumStore9StoredRowE -_ZN9oceanbase3sql12ObDMLService25filter_row_for_view_checkERKNS_6common12ObFixedArrayIPNS0_6ObExprENS2_12ObIAllocatorEEERNS0_9ObEvalCtxERb -_ZN9oceanbase3sql15ObTableDeleteOp20write_rows_post_procEi -_ZN9oceanbase3sql15ObTableModifyOp20merge_implict_cursorEllll -_ZN9oceanbase3sql17ObPhysicalPlanCtx22sync_last_value_globalEv +_ZN9oceanbase3sql12ObDMLService22add_related_index_infoERKNS0_14ObDASTabletLocERKNS_6common12ObFixedArrayIPNS0_17ObDASDMLBaseCtDefENS5_12ObIAllocatorEEERNS5_11ObArrayWrapIPNS0_17ObDASDMLBaseRtDefEEERNS0_12ObIDASTaskOpE +_ZN9oceanbase6common16ObFixedArrayImplINS0_10ObTabletIDENS0_12ObIAllocatorEE9push_backERKS2_ +_ZN9oceanbase6common16ObFixedArrayImplIPKNS_3sql14ObDASBaseCtDefENS0_12ObIAllocatorEE9push_backERKS5_ +_ZN9oceanbase6common16ObFixedArrayImplIPNS_3sql14ObDASBaseRtDefENS0_12ObIAllocatorEE9push_backERKS4_ +_ZN9oceanbase6common16ObFixedArrayImplINS0_10ObTabletIDENS0_12ObIAllocatorEE7reserveEl +_ZN9oceanbase6common16ObFixedArrayImplINS0_10ObTabletIDENS0_12ObIAllocatorEE4initEl _ZN9oceanbase3sql12ObDMLService18process_delete_rowERKNS0_10ObDelCtDefERNS0_10ObDelRtDefERbRNS0_15ObTableModifyOpE -_ZN9oceanbase3sql10ObExprTrim9eval_trimERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE -_ZN9oceanbase3sql30eval_assign_question_mark_funcERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE -_ZN9oceanbase6common11ObObjCaster7to_typeENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS5_ -_ZN9oceanbase3sql15ObDatumObjParam25alloc_datum_reserved_buffINS_6common9ObObjMetaEEEiRKT_RNS3_12ObIAllocatorE -_ZN9oceanbase6common11ObObjCaster7to_typeENS0_9ObObjTypeENS0_15ObCollationTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS6_ -_ZN9oceanbase3sql15ObDatumObjParam13from_objparamERKNS_6common10ObObjParamEPNS2_12ObIAllocatorE -_ZN9oceanbase6commonL13string_stringENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_m -_ZN9oceanbase6commonL11copy_stringERKNS0_15ObObjCastParamsENS0_9ObObjTypeEPKclRNS0_5ObObjEl -_ZN9oceanbase3sql12ObDMLService26init_heap_table_pk_for_insERKNS0_10ObInsCtDefERNS0_9ObEvalCtxE -_ZN9oceanbase6commonL11string_uintENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_m -_ZN9oceanbase3sql13TriggerHandle20do_handle_before_rowERNS0_15ObTableModifyOpERNS0_17ObDASDMLBaseCtDefERKNS0_14ObTrigDMLCtDefERNS0_14ObTrigDMLRtDefE -_ZN9oceanbase3sql12ObDMLService14check_row_nullERKNS_6common8ObIArrayIPNS0_6ObExprEEERNS0_9ObEvalCtxElRKNS3_INS0_13ColumnContentEEEbRNS0_15ObTableModifyOpE -_ZN9oceanbase6common30common_string_unsigned_integerERKmRKNS0_9ObObjTypeERKNS0_15ObCollationTypeERKNS0_8ObStringEbRm -_ZN9oceanbase3sql8ObDASCtx19extended_tablet_locERNS0_13ObDASTableLocERKNS_6common10ObTabletIDERPNS0_14ObDASTabletLocERKmSC_ -_ZN9oceanbase6common25is_partition_change_errorEi -_ZN9oceanbase3sql19ObDASLocationRouter14get_tablet_locERKNS0_17ObDASTableLocMetaERKNS_6common10ObTabletIDERNS0_14ObDASTabletLocE -_ZN9oceanbase3sql13ObDASTableLoc14add_tablet_locEPNS0_14ObDASTabletLocE -_ZN9oceanbase3sql19ObDASLocationRouter19nonblock_get_leaderEmRKNS_6common10ObTabletIDERNS0_14ObDASTabletLocE -_ZN9oceanbase5share19ObLSLocationService12is_valid_keyElmRKNS0_6ObLSIDE -_ZN9oceanbase5share19ObLSLocationService19nonblock_get_leaderElmRKNS0_6ObLSIDERNS_6common6ObAddrE -_ZNK9oceanbase5share12ObLSLocation10get_leaderERNS_6common6ObAddrE -_ZNK9oceanbase5share19ObLSLocationService17check_inner_stat_Ev +_ZN9oceanbase3sql13ObDASDeleteOpD2Ev +_ZN9oceanbase3sql15ObTableDeleteOp20write_rows_post_procEi _ZN9oceanbase3sql13ObDASTableLoc20get_tablet_loc_by_idERKNS_6common10ObTabletIDERPNS0_14ObDASTabletLocE -_ZN9oceanbase3sql12ObDMLService24set_heap_table_hidden_pkERKNS0_10ObInsCtDefERKNS_6common10ObTabletIDERNS0_9ObEvalCtxE -_ZN9oceanbase3sql12ObDMLService24filter_row_for_check_cstERKNS_6common12ObFixedArrayIPNS0_6ObExprENS2_12ObIAllocatorEEERNS0_9ObEvalCtxERb -_ZN9oceanbase3sql12ObDMLService25check_nested_sql_legalityERNS0_13ObExecContextEm -_ZN9oceanbase3sqlL15eval_trim_innerERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumERKlRNS6_8ObStringERbRKNS0_11ObDatumMetaEbRKS7_ -_ZN9oceanbase3sql10ObExprTrim4trimERNS_6common8ObStringElRKS3_S6_ -_ZN9oceanbase3sql15ObTableUpdateOp20write_rows_post_procEi -_ZN9oceanbase3sql13TriggerHandle18init_param_old_rowERNS0_9ObEvalCtxERKNS0_14ObTrigDMLCtDefERNS0_14ObTrigDMLRtDefE +_ZN9oceanbase6common16ObFixedArrayImplIPKNS_3sql14ObDASBaseCtDefENS0_12ObIAllocatorEE7reserveEl +_ZN9oceanbase6common16ObFixedArrayImplIPKNS_3sql14ObDASBaseCtDefENS0_12ObIAllocatorEE4initEl +_ZN9oceanbase5share17ObLocationService19nonblock_get_leaderElmRKNS0_6ObLSIDERNS_6common6ObAddrE +_ZN9oceanbase5share19ObLSLocationService19nonblock_get_leaderElmRKNS0_6ObLSIDERNS_6common6ObAddrE +_ZN9oceanbase3sql15ObTableModifyOp20merge_implict_cursorEllll +_ZN9oceanbase3sql17ObDASTabletMapper27get_non_partition_tablet_idERNS_6common8ObIArrayINS2_10ObTabletIDEEERNS3_ImEE +_ZN9oceanbase6common13ObSEArrayImplINS0_10ObTabletIDELl1ENS0_19ModulePageAllocatorELb0EE9push_backERKS2_ +_ZN9oceanbase6common13ObSEArrayImplImLl1ENS0_19ModulePageAllocatorELb0EE9push_backERKm +_ZN9oceanbase6common16ObFixedArrayImplIPNS_3sql14ObDASBaseRtDefENS0_12ObIAllocatorEE7reserveEl +_ZN9oceanbase6common16ObFixedArrayImplIPNS_3sql14ObDASBaseRtDefENS0_12ObIAllocatorEE4initEl +_ZN9oceanbase3sql12ObDMLService14check_row_nullERKNS_6common8ObIArrayIPNS0_6ObExprEEERNS0_9ObEvalCtxElRKNS3_INS0_13ColumnContentEEEbRNS0_15ObTableModifyOpE _ZN9oceanbase3sql15ObTableUpdateOp23write_row_to_das_bufferEv -_ZN9oceanbase3sql12ObDMLService19write_row_to_das_opILi3EEEiRKNS0_17ObDASDMLBaseCtDefERNS0_17ObDASDMLBaseRtDefEPKNS0_14ObDASTabletLocERNS0_10ObDMLRtCtxERKNS_6common12ObFixedArrayIPNS0_6ObExprENSD_12ObIAllocatorEEESG_RPNS0_17ObChunkDatumStore9StoredRowE _ZN9oceanbase3sql16ObDASWriteBuffer11try_add_rowERKNS_6common8ObIArrayIPNS0_6ObExprEEEPNS0_9ObEvalCtxElRPNS0_17ObChunkDatumStore9StoredRowERbb -_ZZN9oceanbase3sql16ObDASWriteBuffer11try_add_rowERKNS_6common8ObIArrayIPNS0_6ObExprEEEPNS0_9ObEvalCtxElRPNS0_17ObChunkDatumStore9StoredRowERbbENK5$_145clEPKc +_ZZN9oceanbase3sql16ObDASWriteBuffer11try_add_rowERKNS_6common8ObIArrayIPNS0_6ObExprEEEPNS0_9ObEvalCtxElRPNS0_17ObChunkDatumStore9StoredRowERbbENK5$_142clEPKc +_ZN9oceanbase3sql17ObPhysicalPlanCtx22sync_last_value_globalEv +_ZN9oceanbase3sql12ObDMLService25filter_row_for_view_checkERKNS_6common12ObFixedArrayIPNS0_6ObExprENS2_12ObIAllocatorEEERNS0_9ObEvalCtxERb +_ZN9oceanbase3sql12ObDMLService25check_nested_sql_legalityERNS0_13ObExecContextEm +_ZN9oceanbase3sql10ObDASUtils25check_nested_sql_mutatingEmRNS0_13ObExecContextEb +_ZN9oceanbase3sql13TriggerHandle20do_handle_before_rowERNS0_15ObTableModifyOpERNS0_17ObDASDMLBaseCtDefERKNS0_14ObTrigDMLCtDefERNS0_14ObTrigDMLRtDefE +_ZN9oceanbase3sql12ObDMLService24set_heap_table_hidden_pkERKNS0_10ObInsCtDefERKNS_6common10ObTabletIDERNS0_9ObEvalCtxE +_ZN9oceanbase3sql12ObDMLService26init_heap_table_pk_for_insERKNS0_10ObInsCtDefERNS0_9ObEvalCtxE _ZN9oceanbase3sql12ObDMLService18process_update_rowERKNS0_10ObUpdCtDefERNS0_10ObUpdRtDefERbRNS0_15ObTableModifyOpE _ZNK9oceanbase3sql6ObExpr23eval_one_datum_of_batchERNS0_9ObEvalCtxERPNS_6common7ObDatumE _ZN9oceanbase3sql7int_intERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE -_ZN9oceanbase3sql9ObExprAdd11add_int_intERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE _ZN9oceanbase3sql12ObDMLService25check_row_whether_changedERKNS0_10ObUpdCtDefERNS0_10ObUpdRtDefERNS0_9ObEvalCtxE -_ZN9oceanbase3sql12ObDMLService25check_dml_tablet_validityERNS0_10ObDMLRtCtxERKNS0_14ObDASTabletLocERKNS_6common12ObFixedArrayIPNS0_6ObExprENS7_12ObIAllocatorEEERKNS0_14ObDMLBaseCtDefERNS0_14ObDMLBaseRtDefE -_ZN9oceanbase6commonL20check_convert_stringENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_ -_ZN9oceanbase3sql13TriggerHandle18init_param_new_rowERNS0_9ObEvalCtxERKNS0_14ObTrigDMLCtDefERNS0_14ObTrigDMLRtDefE -_ZN9oceanbase3sql15ObTableInsertOp20write_rows_post_procEi -_ZN9oceanbase3sql17ObPhysicalPlanCtx21sync_last_value_localEv -_ZN9oceanbase3sql13ObTableScanOp18inner_get_next_rowEv -_ZN9oceanbase3sql12ObDMLService19write_row_to_das_opILi5EEEiRKNS0_17ObDASDMLBaseCtDefERNS0_17ObDASDMLBaseRtDefEPKNS0_14ObDASTabletLocERNS0_10ObDMLRtCtxERKNS_6common12ObFixedArrayIPNS0_6ObExprENSD_12ObIAllocatorEEESG_RPNS0_17ObChunkDatumStore9StoredRowE -_ZN9oceanbase6common16ObArenaAllocator5allocElRKNS_3lib9ObMemAttrE -_ZN9oceanbase3sql13ObTableScanOp28inner_get_next_row_implementEv -_ZN9oceanbase7storage19ObTableScanIterator12get_next_rowEv +_ZN9oceanbase3sql9ObExprAdd11add_int_intERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE _ZN9oceanbase3sql19ObIntIntBatchAddRaw9raw_checkElll -_ZN9oceanbase3sql11ObDASLockOp14init_task_infoEj -_ZN9oceanbase7storage19ObTableScanIterator12get_next_rowERPNS_6common8ObNewRowE -_ZN9oceanbase6common15ObTimeConverter21datetime_to_timestampElPKNS0_14ObTimeZoneInfoERl -_ZN9oceanbase3sql13ObTableScanOp26inner_get_next_row_for_tscEv -_ZN9oceanbase6common22ObVirtualTableIterator12get_next_rowEv -_ZN9oceanbase3sql12ObDMLService30init_das_lock_rtdef_for_updateERNS0_10ObDMLRtCtxERKNS0_10ObUpdCtDefERNS0_10ObUpdRtDefE -_ZN9oceanbase3sql19AllocDASRtDefHelperILi5EE5allocERNS_6common12ObIAllocatorERPNS0_14ObDASBaseRtDefE -_ZN9oceanbase3sql18ObPushdownOperator22reset_trans_info_datumEv -_ZN9oceanbase3sql12ObMaterialOp22get_all_row_from_childERNS0_16ObSQLSessionInfoE -_ZN9oceanbase3sql13ObTableLockOp18inner_get_next_rowEv -_ZN9oceanbase3sql17ObChunkDatumStore5Block10append_rowERKNS_6common8ObIArrayIPNS0_6ObExprEEEPNS0_9ObEvalCtxEPNS1_11BlockBufferElPPNS1_9StoredRowEb -_ZN9oceanbase6common22ObVirtualTableIterator12get_next_rowERPNS0_8ObNewRowE -_ZNK9oceanbase6common4hash18ObPointerHashArrayINS_5share6schema13ObColumnIdKeyEPNS4_16ObColumnSchemaV2ENS4_14ObGetColumnKeyEE14get_refactoredERKS5_RS7_ -_ZN9oceanbase3sql17ObChunkDatumStore7add_rowERKNS_6common8ObIArrayIPNS0_6ObExprEEEPNS0_9ObEvalCtxEPPNS1_9StoredRowE -_ZN9oceanbase3sql17ObChunkDatumStore18alloc_block_bufferERPNS1_5BlockEllb -_ZN9oceanbase3sql17ObChunkDatumStore17init_block_bufferEPvlRPNS1_5BlockE -_ZN9oceanbase3sql12ObHashJoinOp18inner_get_next_rowEv -_ZN9oceanbase3sql16ObMaterialOpImpl4initEmPNS0_9ObEvalCtxEPNS0_13ObExecContextEPNS0_17ObIOEventObserverEl -_ZN9oceanbase3sql13ObMergeJoinOp18inner_get_next_rowEv -_ZN9oceanbase3sql13ObMergeJoinOp25right_join_cache_func_endEv -_ZN9oceanbase3sql8ObSortOp18inner_get_next_rowEv -_ZN9oceanbase3sql13ObCmdExecutor7executeERNS0_13ObExecContextERNS0_6ObICmdE -_ZZN9oceanbase3sql13ObCmdExecutor7executeERNS0_13ObExecContextERNS0_6ObICmdEENK4$_22clEv -_ZZN9oceanbase3sql13ObCmdExecutor7executeERNS0_13ObExecContextERNS0_6ObICmdEENK4$_21clEv -_ZN9oceanbase3sql17ObSqlTransControl20explicit_start_transERNS0_13ObExecContextEbNS_6common8ObStringE -_ZNK9oceanbase3sql16ObSQLSessionInfo22is_txn_free_route_tempEv -_ZN9oceanbase11transaction14ObTransService8start_txERNS0_8ObTxDescERKNS0_9ObTxParamE -_ZN9oceanbase11transaction11ObTxDescMgr3addERNS0_8ObTxDescE -_ZNSt17_Function_handlerIFiRN9oceanbase11transaction9ObTransIDEESt5_BindIFMNS1_14ObTransServiceEFiS3_EPS6_St12_PlaceholderILi1EEEEE9_M_invokeERKSt9_Any_dataS3_ -_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_8ObTxDescENS0_11ObTxDescMgr13ObTxDescAllocENS_6common10SpinRWLockELl65536EE8insert__ERKS2_PS3_iPSB_ -_ZZN9oceanbase11transaction11ObTxDescMgr3addERNS0_8ObTxDescEENK4$_58clEPKc -_ZN9oceanbase11transaction14ObTransService13gen_trans_id_ERNS0_9ObTransIDE -_ZN9oceanbase11transaction14ObTransService10release_txERNS0_8ObTxDescE -_ZZN9oceanbase11transaction14ObTransService10release_txERNS0_8ObTxDescEENK6$_1638clEPKc -_ZZN9oceanbase11transaction11ObTxDescMgr6revertERNS0_8ObTxDescEENK4$_68clEPKc.llvm.3520332200816746847 -_ZN9oceanbase11transaction11ObTxDescMgr13ObTxDescAlloc10free_valueEPNS0_8ObTxDescE -_ZN9oceanbase6common11ObArrayImplINS_11transaction16ObTransIDAndAddrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev -_ZZN9oceanbase11transaction14ObTransService10release_txERNS0_8ObTxDescEENK6$_1637clEPKc -_ZN9oceanbase11transaction11ObGtiSource12get_trans_idERl -_ZN9oceanbase11transaction14ObTransService10acquire_txERPNS0_8ObTxDescEj -_ZN9oceanbase11transaction11ObTxDescMgr5allocERPNS0_8ObTxDescE -_ZN9oceanbase6common15ObTimeWheelTask5resetEv -_ZN9oceanbase11transaction8ObTxDescC1Ev -_ZN9oceanbase11transaction8ObTxDescC2Ev -_ZN6obutil9ObMonitorINS_11ObUtilMutexEEC2Ev -_ZN9oceanbase3sql18ObEndTransExecutor9end_transERNS0_13ObExecContextERNS0_14ObEndTransStmtE -_ZN9oceanbase3sql17ObSqlTransControl18explicit_end_transERNS0_13ObExecContextEbNS_6common8ObStringE -_ZN9oceanbase5trace7ObTrace10append_tagIlLb1EEEb9ObTagTypeRKT_ -_ZN9oceanbase3sql17ObSqlTransControl9end_transERNS0_13ObExecContextEbbPNS0_23ObEndTransAsyncCallbackE -_ZN9oceanbase3sql17ObSqlTransControl13do_end_trans_EPNS0_16ObSQLSessionInfoEbblPNS0_23ObEndTransAsyncCallbackE -_ZZN9oceanbase11transaction14ObTransService13do_commit_tx_ERNS0_8ObTxDescElRNS0_13ObITxCallbackERNS_5share3SCNEENK6$_1227clEPKc -_ZN9oceanbase5share8detector21ObDeadLockDetectorMgr20check_detector_existINS_11transaction9ObTransIDEEEiRKT_Rb -_ZZN9oceanbase11transaction14ObTransService13gen_trans_id_ERNS0_9ObTransIDEENK6$_1496clEPKc -_ZN9oceanbase11transaction8ObTxDescD1Ev -_ZN9oceanbase11transaction8ObTxDescD2Ev -_ZN9oceanbase11transaction8ObTxDesc5resetEv -_ZN9oceanbase3sql17ObSqlTransControl15inc_session_refEPKNS0_16ObSQLSessionInfoE -_ZN9oceanbase11transaction14ObTransService16submit_commit_txERNS0_8ObTxDescElRNS0_13ObITxCallbackEPKNS_6common8ObStringE -_ZN9oceanbase11transaction8ObTxDesc13set_commit_cbEPNS0_13ObITxCallbackE -_ZN9oceanbase11transaction10ObTransCtx19set_app_trace_info_ERKNS_6common8ObStringE -_ZN9oceanbase11transaction10ObTxCtxMgr10get_tx_ctxERKNS_5share6ObLSIDERKNS0_9ObTransIDEbRPNS0_14ObPartTransCtxE -_ZN9oceanbase11transaction14ObTransHashMapINS_5share6ObLSIDENS0_12ObLSTxCtxMgrENS0_17ObLSTxCtxMgrAllocENS_6common11ObQSyncLockELl64EE3getERKS3_RPS4_ -_ZN9oceanbase11transaction14ObTransService19local_ls_commit_tx_ERKNS0_9ObTransIDERKNS_5share6ObLSIDERKNS_6common9ObSEArrayIS6_Ll3ENS9_19ModulePageAllocatorELb0EEERKlRKNS9_8ObStringESG_RNS5_3SCNERKNS9_6ObAddrE -_ZN9oceanbase11transaction14ObPartTransCtx16do_local_tx_end_ENS0_11TxEndActionE -_ZN9oceanbase11transaction14ObPartTransCtx19do_local_commit_tx_Ev -_ZN9oceanbase11transaction14ObPartTransCtx24generate_commit_version_Ev -_ZN9oceanbase11transaction14ObPartTransCtx8get_gts_ERNS_5share3SCNE -_ZN9oceanbase11transaction11ObCtxTxData18set_commit_versionERKNS_5share3SCNE -_ZN9oceanbase11transaction14ObPartTransCtx31prepare_mul_data_source_tx_end_Eb -_ZNK9oceanbase11transaction12ObTxMDSCache7copy_toERNS_6common9ObSEArrayINS0_14ObTxBufferNodeELl1ENS2_19ModulePageAllocatorELb0EEE -_ZN9oceanbase6common13ObSEArrayImplINS_11transaction14ObTxBufferNodeELl1ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayIS3_EE -_ZN9oceanbase11transaction10ObTxCtxMgr13revert_tx_ctxEPNS0_14ObPartTransCtxE -_ZN9oceanbase11transaction14ObPartTransCtx28set_start_scn_in_commit_log_ERNS0_13ObTxCommitLogE -_ZNK9oceanbase6common13ObSEArrayImplINS_11transaction14ObTxBufferNodeELl1ENS0_19ModulePageAllocatorELb0EE18get_serialize_sizeEv -_ZN9oceanbase11transaction11ObTraceInfo18set_app_trace_infoERKNS_6common8ObStringE -_ZN9oceanbase11transaction14ObPartTransCtx16submit_log_impl_ENS0_11ObTxLogTypeE -_ZN9oceanbase11transaction10ObTransCtx16acquire_ctx_ref_Ev -_ZN9oceanbase8memtable13ObMemtableCtx17calc_checksum_allEv -_ZN9oceanbase11transaction18ObTxLogBlockHeader16before_serializeEv -_ZNK9oceanbase11transaction11ObCtxTxData16get_start_log_tsEv -_ZN9oceanbase11transaction14ObPartTransCtx17after_submit_log_ERNS0_12ObTxLogBlockEPNS0_9ObTxLogCbEPNS_8memtable21ObRedoLogSubmitHelperE -_ZN9oceanbase8memtable16ObITransCallback13log_submittedEv -_ZN9oceanbase8memtable18ObRedoLogGenerator13log_submittedERKNS0_15ObCallbackScopeE -_ZN9oceanbase8memtable17ObMvccRowCallback13log_submittedEv -_ZN9oceanbase11transaction14ObPartTransCtx27merge_tablet_modify_record_ERKNS_6common10ObTabletIDE -_ZN9oceanbase6common13ObSEArrayImplINS_11transaction9ObTxCbArgELl3ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayIS3_EE -_ZN9oceanbase11transaction11ObCtxTxData16set_start_log_tsERKNS_5share3SCNE -_ZN9oceanbase11transaction12ObTxLogBlock11add_new_logINS0_13ObTxCommitLogEEEiRT_PNS0_17ObTxBigSegmentBufE -_ZN9oceanbase11transaction13ObTxCommitLog16before_serializeEv -_ZN9oceanbase11transaction14ObPartTransCtx17get_prev_log_lsn_ERKNS0_12ObTxLogBlockENS0_11ObTxLogTypeERNS_4palf3LSNE -_ZN9oceanbase11transaction16ObLSTxLogAdapter10submit_logEPKclRKNS_5share3SCNEPNS0_13ObTxBaseLogCbEb -_ZN9oceanbase11transaction16ObTransStatistic21add_clog_submit_countEml -_ZNK9oceanbase10logservice12ObLogHandler8is_validEv -_ZN9oceanbase11transaction16ObTransStatistic24add_trans_log_total_sizeEml -_ZN9oceanbase10logservice12ObLogHandler6appendEPKvlRKNS_5share3SCNEbPNS0_8AppendCbERNS_4palf3LSNERS5_ -_ZN9oceanbase10logservice13ObApplyStatus14push_append_cbEPNS0_8AppendCbE -_ZN9oceanbase4palf14PalfHandleImpl10submit_logERKNS0_17PalfAppendOptionsEPKclRKNS_5share3SCNERNS0_3LSNERS8_ -_ZN9oceanbase4palf11PalfEnvImpl23check_disk_space_enoughEv -_ZN9oceanbase4palf16LogSlidingWindow10submit_logEPKclRKNS_5share3SCNERNS0_3LSNERS5_ -_ZN9oceanbase4palf14LogGroupBuffer4fillERKNS0_3LSNEPKcl -_ZN9oceanbase4palf14LogGroupBuffer5fill_ERKNS0_3LSNElPKcl -_ZN9oceanbase4palf14LogEntryHeader23update_header_checksum_Ev -_ZNK9oceanbase4palf14LogEntryHeader9serializeEPclRl -_ZZN9oceanbase4palf14LogGroupBuffer4fillERKNS0_3LSNEPKclENK5$_750clES6_ -_ZN9oceanbase4palf12LSNAllocator13alloc_lsn_scnERKNS_5share3SCNEllRKNS0_3LSNERS6_RlRS3_RbSC_SA_ -_ZN9oceanbase6common8TCRWLock10RLockGuardD2Ev -_ZZN9oceanbase4palf14LogEntryHeader23update_header_checksum_EvENK5$_715clEPKc.llvm.1832557561412309455 -_ZN9oceanbase4palf16LogSlidingWindow26leader_can_submit_new_log_ElRNS0_3LSNE -_ZNK9oceanbase4palf16LogSlidingWindow14get_max_log_idEv -_ZNK9oceanbase11transaction13ObTxCommitLog19get_serialize_size_Ev -_ZZN9oceanbase4palf14LogGroupBuffer5fill_ERKNS0_3LSNElPKclENK5$_778clES6_ -_ZN9oceanbase8memtable16ObTxCallbackList20tx_calc_checksum_allEv -_ZN9oceanbase11transaction12ObTxLogBlockD2Ev -_ZNK9oceanbase4palf14LogGroupBuffer18can_handle_new_logERKNS0_3LSNElS4_ -_ZN9oceanbase11transaction12ObTxLogBlock4initElRKNS0_18ObTxLogBlockHeaderEb -_ZN9oceanbase11transaction12ObTxLogBlock27serialize_log_block_header_ElRKNS0_18ObTxLogBlockHeaderENS_10logservice19ObReplayBarrierTypeE -_ZNK9oceanbase11transaction18ObTxLogBlockHeader10serialize_EPclRl -_ZNK9oceanbase11transaction17ObTxSerCompatByte15is_object_validEl -_ZNK9oceanbase6common6ObAddr9serializeEPclRl -_ZN9oceanbase11transaction14ObPartTransCtx28submit_redo_commit_info_log_ERNS0_12ObTxLogBlockERbRNS_8memtable21ObRedoLogSubmitHelperE -_ZN9oceanbase11transaction12ObTxLogBlock11add_new_logINS0_17ObTxCommitInfoLogEEEiRT_PNS0_17ObTxBigSegmentBufE -_ZN9oceanbase11transaction17ObTxCommitInfoLog16before_serializeEv -_ZNK9oceanbase6common6ObAddr19get_serialize_size_Ev -_ZNK9oceanbase11transaction17ObTxCommitInfoLog19get_serialize_size_Ev -_ZN9oceanbase11transaction14ObPartTransCtx18update_rec_log_ts_EbRKNS_5share3SCNE -_ZZN9oceanbase4palf16LogSlidingWindow10submit_logEPKclRKNS_5share3SCNERNS0_3LSNERS5_ENK5$_130clES3_ -_ZZN9oceanbase10logservice12ObLogHandler6appendEPKvlRKNS_5share3SCNEbPNS0_8AppendCbERNS_4palf3LSNERS5_ENK5$_204clEPKc -_ZN9oceanbase4palf16LogSlidingWindow24wait_group_buffer_ready_ERKNS0_3LSNEl -_ZNK9oceanbase4palf16LogSlidingWindow29leader_can_submit_larger_log_El -_ZNK9oceanbase11transaction13ObTxCommitLog9serializeEPclRl -_ZNK9oceanbase11transaction14ObTxDataBackup9serializeEPclRl -_ZNK9oceanbase5share3SCN9serializeEPclRl -_ZN9oceanbase11transaction14ObPartTransCtx16submit_redo_log_ERNS0_12ObTxLogBlockERbRNS_8memtable21ObRedoLogSubmitHelperE -_ZN9oceanbase8memtable13ObMemtableCtx13fill_redo_logEPclRlRNS0_21ObRedoLogSubmitHelperEb -_ZNK9oceanbase8memtable16ObITransCallback18is_logging_blockedEv -_ZNK9oceanbase8memtable17ObMvccRowCallback10get_seq_noEv -_ZNK9oceanbase11transaction9tablelock17ObOBJLockCallback10get_seq_noEv -_ZN9oceanbase8memtable18ObRedoLogGenerator13fill_redo_logEPclRlRNS0_21ObRedoLogSubmitHelperEb -_ZN9oceanbase6common13ob_crc64_isalEmPKcl -_ZNK9oceanbase8memtable17ObMvccRowCallback18is_logging_blockedEv -_ZN9oceanbase8memtable18ObRedoLogGenerator20fill_table_lock_redoERNS0_24ObITransCallbackIteratorERNS0_15ObMutatorWriterERNS0_21TableLockRedoDataNodeEbRb -_ZNK9oceanbase11transaction9tablelock8ObLockID9serializeEPclRl -_ZN9oceanbase8memtable18ObRedoLogGenerator13fill_row_redoERNS0_24ObITransCallbackIteratorERNS0_15ObMutatorWriterERNS0_12RedoDataNodeEbRbRNS_11transaction17ObCLogEncryptInfoE -_ZN9oceanbase8memtable9ObRowData9serializeEPclRl -_ZNK9oceanbase8memtable18ObMutatorRowHeader9serializeEPclRl -_ZNK9oceanbase6common10ObTabletID9serializeEPclRl -_ZNK9oceanbase8memtable17ObMvccRowCallback19get_cluster_versionERm -_ZN9oceanbase8memtable17ObMvccRowCallback8get_redoERNS0_12RedoDataNodeE -_ZNK9oceanbase6common8ObRowkey9serializeEPclRl -_ZN9oceanbase11transaction12ObTxLogBlock18finish_mutator_bufERNS0_11ObTxRedoLogERKl -_ZN9oceanbase11transaction13ObCtxRedoInfo16before_serializeEv -_ZN9oceanbase8memtable15ObMutatorWriter9serializeEhRlRNS_11transaction17ObCLogEncryptInfoE -_ZN9oceanbase11transaction12ObTxLogBlock11add_new_logINS0_11ObTxRedoLogEEEiRT_PNS0_17ObTxBigSegmentBufE -_ZN9oceanbase11transaction12ObTxLogBlock19prepare_mutator_bufERNS0_11ObTxRedoLogE -_ZNK9oceanbase11transaction11ObTxRedoLog9serializeEPclRl -_ZZN9oceanbase4palf12LSNAllocator13alloc_lsn_scnERKNS_5share3SCNEllRKNS0_3LSNERS6_RlRS3_RbSC_SA_ENK5$_691clEPKc -_ZNK9oceanbase11transaction17ObTxCommitInfoLog9serializeEPclRl -_ZNK9oceanbase6common13ObSEArrayImplINS_5share6ObLSIDELl3ENS0_19ModulePageAllocatorELb0EE9serializeEPclRl -_ZNK9oceanbase5share6ObLSID9serializeEPclRl -_ZN9oceanbase6common13ObSEArrayImplINS_5share6ObLSIDELl3ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayIS3_EE -_ZN9oceanbase11transaction7ObTsMgr7get_gtsEmNS_6common13ObMonotonicTsEPNS0_10ObTsCbTaskERNS_5share3SCNERS3_ -_ZN9oceanbase4palf16LogSlidingWindow25feedback_freeze_last_log_Ev -_ZN9oceanbase4palf16LogSlidingWindow21handle_committed_log_Ev -_ZN9oceanbase6common7ObLatch6wrlockEjlPKj -_ZN9oceanbase6common8TCRWLock21RLockGuardWithTimeoutD2Ev -_ZN9oceanbase11transaction14ObTransService22decide_tx_commit_info_ERNS0_8ObTxDescERPNS0_8ObTxPartE -_ZZN9oceanbase11transaction14ObTransService22decide_tx_commit_info_ERNS0_8ObTxDescERPNS0_8ObTxPartEENK6$_1262clEPKc -_ZN9oceanbase11transaction14ObPartTransCtx15prepare_log_cb_EbRPNS0_9ObTxLogCbE -_ZN9oceanbase11transaction9ObTxLogCb5reuseEv -_ZZN9oceanbase4palf14LogEntryHeader15generate_headerEPKclRKNS_5share3SCNEENK5$_716clES3_.llvm.1832557561412309455 -_ZN9oceanbase11transaction11ObGtsSource7get_gtsENS_6common13ObMonotonicTsEPNS0_10ObTsCbTaskERlRS3_ -_ZN9oceanbase11transaction11ObIDService10get_numberEllRlS2_ -_ZZN9oceanbase4palf16LogSlidingWindow10submit_logEPKclRKNS_5share3SCNERNS0_3LSNERS5_ENK5$_138clES3_ -_ZN9oceanbase4palf16LogSlidingWindow10sliding_cbElPKNS0_22FixedSlidingWindowSlotE -_ZN9oceanbase6common10ObMiniStat10ObStatItem4statEl -_ZNK9oceanbase4palf16LogSlidingWindow32is_all_committed_log_slided_out_ERNS0_3LSNERlS3_ -_ZNK9oceanbase4palf16LogSlidingWindow24get_last_slide_log_info_ERlRNS_5share3SCNERNS0_3LSNES7_S2_S2_ -_ZZN9oceanbase4palf14LogGroupBuffer30inc_update_readable_begin_lsn_ERKNS0_3LSNEENK5$_767clEPKc.llvm.1832557561412309455 -_ZN9oceanbase8memtable18ObTransCallbackMgr20inc_pending_log_sizeEl -_ZZN9oceanbase11transaction14ObTransService10acquire_txERPNS0_8ObTxDescEjENK6$_1634clEPKc -_ZZN9oceanbase4palf16LogSlidingWindow23handle_next_submit_log_ERbENK5$_183clEPKc -_ZZN9oceanbase4palf14PalfHandleImpl10submit_logERKNS0_17PalfAppendOptionsEPKclRKNS_5share3SCNERNS0_3LSNERS8_ENK5$_935clES6_ -_ZN9oceanbase3sql15ObSQLSessionMgr15inc_session_refEPKNS0_16ObSQLSessionInfoE -_ZN9oceanbase6common13ObLinkHashMapINS_3sql14SessionInfoKeyENS2_16ObSQLSessionInfoENS2_15ObSQLSessionMgr10ValueAllocENS0_9RefHandleELl8EE3getERKS3_RPS4_ -_ZN9oceanbase4palf12LSNAllocator10try_freezeERNS0_3LSNERl -_ZN9oceanbase11transaction10ObTransCtx8set_stc_ENS_6common13ObMonotonicTsE -_ZN9oceanbase4palf11LogChecksum21verify_accum_checksumEll -_ZN9oceanbase4palf16LogSlidingWindow31try_update_last_slide_log_info_ElRKNS_5share3SCNERKNS0_3LSNES8_RKll -_ZN9oceanbase10logservice13ObApplyStatus29update_palf_committed_end_lsnERKNS_4palf3LSNEl -_ZN9oceanbase4palf16LogSlidingWindow25try_freeze_last_log_task_ElRKNS0_3LSNERb -_ZN9oceanbase4palf7LogTask11try_freeze_ERKNS0_3LSNE -_ZN9oceanbase4palf16LogSlidingWindow23handle_next_submit_log_ERb -_ZN9oceanbase6common8ObMember5resetEv -_ZN9oceanbase4palf11LogChecksum22acquire_accum_checksumElRl -_ZNK9oceanbase4palf16LogSlidingWindow25get_last_submit_log_info_ERNS0_3LSNES3_RlS4_ -_ZN9oceanbase4palf19LogGroupEntryHeader22update_header_checksumEv -_ZN9oceanbase4palf11LogWriteBufD1Ev -_ZN9oceanbase4palf11LogWriteBufD2Ev -_ZNK9oceanbase4palf19LogGroupEntryHeader28get_header_parity_check_res_Ev -_ZN9oceanbase4palf19LogGroupEntryHeader8generateEbbRKNS0_11LogWriteBufElRKNS_5share3SCNElRKNS0_3LSNERKlRl -_ZNK9oceanbase4palf19LogGroupEntryHeader9serializeEPclRl -_ZN9oceanbase4palf14LogGroupBuffer11get_log_bufERKNS0_3LSNElRNS0_11LogWriteBufE -_ZN9oceanbase4palf16LogSlidingWindow25set_last_submit_log_info_ERKNS0_3LSNES4_lRKl -_ZN9oceanbase4palf19LogGroupEntryHeader23calculate_log_checksum_EbRKNS0_11LogWriteBufElRl -_ZNK9oceanbase4palf14LogEntryHeader22check_header_integrityEv -_ZN9oceanbase4palf14LogEntryHeader11deserializeEPKclRl -_ZN9oceanbase5share3SCN35fixed_deserialize_without_transformEPKclRl -_ZN9oceanbase6common16ObMemberListBaseILl7EE13remove_serverERKNS0_6ObAddrE -_ZZN9oceanbase4palf14LogGroupBuffer11get_log_bufERKNS0_3LSNElRNS0_11LogWriteBufEENK5$_742clEPKc -_ZN9oceanbase6common15BaseLearnerListILl2000ENS0_8ObMemberEE6appendERKS3_ -_ZN9oceanbase4palf7LogTask18update_header_infoERKNS0_3LSNEl -_ZN9oceanbase4palf16LogSlidingWindow23generate_new_group_log_ERKNS0_3LSNElRKNS_5share3SCNElRKNS0_7LogTypeEPKclRb -_ZN9oceanbase4palf14LogEntryHeader15generate_headerEPKclRKNS_5share3SCNE -_ZZN9oceanbase10logservice13ObApplyStatus14push_append_cbEPNS0_8AppendCbEENK4$_21clEPKc -_ZN9oceanbase4palf9LogEngine21submit_flush_log_taskERKNS0_13FlushLogCbCtxERKNS0_11LogWriteBufE -_ZN9oceanbase6common13ObLightyQueue4pushEPv -_ZN9oceanbase4palf17LogIOFlushLogTaskC1Ell -_ZZN9oceanbase4palf16LogSlidingWindow23handle_next_submit_log_ERbENK5$_168clEPKc -_ZZN9oceanbase4palf11LogChecksum22acquire_accum_checksumElRlENK5$_176clEPKc.llvm.1832557561412309455 -_ZNK9oceanbase4palf12LogConfigMgr17get_children_listERNS_6common15BaseLearnerListILl15ENS0_10LogLearnerEEE -_ZN9oceanbase6common13ObSEArrayImplINS_4palf10LogLearnerELl7ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZZNK9oceanbase4palf19LogGroupEntryHeader9serializeEPclRlENK5$_818clEPKc -_ZZN9oceanbase4palf7LogTask20try_freeze_by_myselfEvENK5$_661clEPKc -_ZZN9oceanbase4palf9LogEngine21submit_flush_log_taskERKNS0_13FlushLogCbCtxERKNS0_11LogWriteBufEENK5$_556clEPKc.llvm.1832557561412309455 -_ZN9oceanbase11transaction14ObPartTransCtx25submit_multi_data_source_ERNS0_12ObTxLogBlockE -_ZZN9oceanbase11transaction14ObPartTransCtx25submit_multi_data_source_ERNS0_12ObTxLogBlockEENK5$_743clEPKc -_ZN9oceanbase6common8TCRWLock6rdlockEl -_ZZNK9oceanbase4palf16LogSlidingWindow32is_all_committed_log_slided_out_ERNS0_3LSNERlS3_ENK5$_255clEPKc.llvm.2452046906557810875 -_ZZN9oceanbase4palf17LogIOFlushLogTask4initERKNS0_13FlushLogCbCtxERKNS0_11LogWriteBufEENK5$_836clEPKc.llvm.1832557561412309455 -_ZN9oceanbase4palf16LogSlidingWindow20try_freeze_prev_log_ElRKNS0_3LSNERb -_ZN9oceanbase10logservice14ObReplayStatus17update_end_offsetERKNS_4palf3LSNE -_ZZN9oceanbase4palf16LogSlidingWindow28generate_group_entry_header_ElPNS0_7LogTaskERNS0_19LogGroupEntryHeaderERlRbENK5$_189clEPKc -_ZZN9oceanbase4palf16LogSlidingWindow25try_freeze_last_log_task_ElRKNS0_3LSNERbENK5$_195clEPKc -_ZN9oceanbase10logservice12ObReplayFsCb14update_end_lsnElRKNS_4palf3LSNEl -_ZN9oceanbase4palf11LogChecksum21verify_accum_checksumElllRl -_ZZNK9oceanbase11transaction14ObTxVersionMgr15get_max_read_tsEvENKUlPKcE_clES3_ -_ZZN9oceanbase4palf19LogGroupEntryHeader23calculate_log_checksum_EbRKNS0_11LogWriteBufElRlENK5$_809clEPKc -_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE6revertElENKUlPKcE4_clES5_ -_ZZN9oceanbase4palf19LogGroupEntryHeader23update_header_checksum_EvENK5$_810clEPKc.llvm.1832557561412309455 -_ZZN9oceanbase4palf16LogSlidingWindow21handle_committed_log_EvENK5$_162clEPKc -_ZZN9oceanbase4palf11LogChecksum21verify_accum_checksumEllENK5$_178clEPKc.llvm.1832557561412309455 -_ZZN9oceanbase10logservice13ObApplyStatus29update_palf_committed_end_lsnERKNS_4palf3LSNElENK4$_58clEPKc -_ZZN9oceanbase4palf19LogGroupEntryHeader8generateEbbRKNS0_11LogWriteBufElRKNS_5share3SCNElRKNS0_3LSNERKlRlENK5$_791clEPKc.llvm.1832557561412309455 -_ZZN9oceanbase4palf7LogTask11try_freeze_ERKNS0_3LSNEENK5$_662clEPKc -_ZZN9oceanbase4palf16LogSlidingWindow10submit_logEPKclRKNS_5share3SCNERNS0_3LSNERS5_ENK5$_136clES3_ -_ZZN9oceanbase4palf11LogChecksum21verify_accum_checksumElllRlENK5$_179clEPKc -_ZZN9oceanbase4palf16LogSlidingWindow31try_update_last_slide_log_info_ElRKNS_5share3SCNERKNS0_3LSNES8_RKllENK5$_223clEPKc -_ZZN9oceanbase4palf16LogSlidingWindow23handle_next_submit_log_ERbENK5$_173clEPKc -_ZZN9oceanbase4palf7LogTask18update_header_infoERKNS0_3LSNElENK5$_658clEPKc -_ZZN9oceanbase4palf16LogSlidingWindow21handle_committed_log_EvENK5$_163clEPKc -_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE5slideElPNS0_16ISlidingCallBackEENKUlPKcE1_clES7_ -_ZZN9oceanbase4palf11LogIOWorker14submit_io_taskEPNS0_9LogIOTaskEENK5$_973clEPKc.llvm.1832557561412309455 -_ZZN9oceanbase4palf7LogTask23set_initial_header_infoERKNS0_17LogTaskHeaderInfoEENK5$_655clEPKc -_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE6revertElENKUlPKcE3_clES5_ -_ZZN9oceanbase4palf16LogSlidingWindow25set_last_submit_log_info_ERKNS0_3LSNES4_lRKlENK5$_221clEPKc -_ZN9oceanbase11transaction10ObTransCtx8get_stc_Ev -_ZZN9oceanbase4palf18FixedSlidingWindowINS0_7LogTaskEE5slideElPNS0_16ISlidingCallBackEENKUlPKcE5_clES7_ -_ZN9oceanbase6common16ObLatchWaitQueue12get_instanceEv -_ZN9oceanbase11transaction17ObTxSerCompatByte15set_object_flagElb -_ZN9oceanbase6common17obj_val_serializeILNS0_9ObObjTypeE22EEEiRKNS0_5ObObjEPclRl -_ZN9oceanbase6common16ObLatchWaitQueue4waitINS0_7ObLatch12LowTryWRLockEEEiRNS0_10ObWaitProcEjjRT_S8_l -_ZN9oceanbase6common16ObLatchWaitQueue8try_lockINS0_7ObLatch12LowTryWRLockEEEiRNS1_13ObLatchBucketERNS0_10ObWaitProcEjjRT_ -_ZN9oceanbase11transaction14ObTransService9commit_txERNS0_8ObTxDescElPKNS_6common8ObStringE -_ZN6obutil11ObUtilMutexD1Ev -_ZN9oceanbase11transaction11ObTransCond4waitElRi -_ZN9oceanbase3lib16ObFreeLogPrinter14print_free_logEllPNS0_7AObjectE -_ZN9oceanbase6common6DCHashINS_11transaction7ObBLKeyELl128EE24alloc_and_init_cur_arrayEv -_ZN9oceanbase3sql13ObDASInsertOp7open_opEv -_ZN9oceanbase3sql20ObDASIndexDMLAdaptorILi2ENS0_16ObDASDMLIteratorEE10write_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERKNS0_13ObDASInsCtDefERNS0_13ObDASInsRtDefERS2_Rl -_ZN9oceanbase7storage15ObAccessService11insert_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERNS_11transaction8ObTxDescERKNS0_14ObDMLBaseParamERKNS6_8ObIArrayImEEPNS6_16ObNewRowIteratorERl -_ZN9oceanbase5share6schema19ObSchemaGetterGuardD1Ev -_ZN9oceanbase5share6schema19ObSchemaGetterGuardD2Ev -_ZN9oceanbase6common13ObSEArrayImplINS_5share6schema19ObSchemaGetterGuard9SchemaObjELl2ENS0_19ModulePageAllocatorELb0EED2Ev -_ZNK9oceanbase8memtable15ObMvccAccessCtx8is_validEv -_ZN9oceanbase7storage17ObLSTabletService11insert_rowsERNS0_10ObStoreCtxERKNS0_14ObDMLBaseParamERKNS_6common8ObIArrayImEEPNS7_16ObNewRowIteratorERl -_ZN9oceanbase3sql16ObDASDMLIterator12get_next_rowERPNS_6common8ObNewRowE -_ZN9oceanbase8memtable16ObQueryAllocator5allocEl -_ZN9oceanbase7storage17ObLSTabletService23get_tablet_with_timeoutERKNS_6common10ObTabletIDERNS0_14ObTabletHandleEll -_ZN9oceanbase7storage10ObRowsInfoD1Ev -_ZN9oceanbase6common23ObReserveArenaAllocatorILl1024EED2Ev -_ZN9oceanbase7storage10ObRowsInfo11ExistHelperD2Ev -_ZN9oceanbase7storage8ObTablet31insert_row_without_rowkey_checkERNS0_15ObRelativeTableERNS0_10ObStoreCtxERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS0_10ObStoreRowEPKNS7_INS_11transaction18ObEncryptMetaCacheEEE -_ZN9oceanbase7storage17ObLSTabletService21insert_lob_tablet_rowERNS0_14ObTabletHandleERNS0_15ObDMLRunningCtxERNS0_10ObStoreRowE -_ZZN9oceanbase3sql16ObDASDMLIterator12get_next_rowERPNS_6common8ObNewRowEENK5$_128clEPKc -_ZN9oceanbase7storage10ObRowsInfo15check_duplicateEPNS0_10ObStoreRowElRNS0_15ObRelativeTableE -_ZN9oceanbase6common23ObReserveArenaAllocatorILl1024EE5allocEl -_ZN9oceanbase7storage10ObRowsInfo11ExistHelper4initERKNS0_15ObRelativeTableERNS0_10ObStoreCtxERKNS0_15ObTableReadInfoERNS_6common23ObReserveArenaAllocatorILl1024EEE -_ZN9oceanbase8memtable10ObMemtable3setERNS_7storage10ObStoreCtxEmRKNS2_15ObTableReadInfoERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS2_10ObStoreRowEPKNSA_13ObEncryptMetaE -_ZN9oceanbase7storage10ObRowsInfoC1Ev -_ZN9oceanbase7storage8ObTablet14rowkeys_existsERNS0_10ObStoreCtxERNS0_15ObRelativeTableERNS0_10ObRowsInfoERb -_ZN9oceanbase8memtable10ObMemtable5existERNS_7storage10ObRowsInfoERbS5_ -_ZN9oceanbase8memtable10ObMemtable5existERNS_7storage10ObStoreCtxEmRKNS2_15ObTableReadInfoERKNS_12blocksstable13ObDatumRowkeyERbSC_ -_ZN9oceanbase8memtable13ObMemtableKey6encodeERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEEPKNS2_13ObStoreRowkeyE -_ZN9oceanbase7storage10ObRowsInfo18clear_found_rowkeyEl -_ZN9oceanbase7storage14ObTabletHandleD1Ev -_ZN9oceanbase7storage14ObTabletHandleD2Ev -_ZN9oceanbase6common23ObReserveArenaAllocatorILl1024EE5resetEv -_ZN9oceanbase12blocksstable13ObDatumRowkey11from_rowkeyERKNS_6common8ObRowkeyERNS2_12ObIAllocatorE -_ZN9oceanbase6common13ObSEArrayImplINS_3sql15ObCandiTableLocELl2ENS0_19ModulePageAllocatorELb0EE5reuseEv -access_mem -_ZN9oceanbase3sql13ObDASDeleteOp7open_opEv -_ZN9oceanbase3sql20ObDASIndexDMLAdaptorILi4ENS0_16ObDASDMLIteratorEE10write_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERKNS0_13ObDASDelCtDefERNS0_13ObDASDelRtDefERS2_Rl -_ZN9oceanbase7storage15ObAccessService11delete_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERNS_11transaction8ObTxDescERKNS0_14ObDMLBaseParamERKNS6_8ObIArrayImEEPNS6_16ObNewRowIteratorERl -_ZN9oceanbase7storage17ObLSTabletService11delete_rowsERNS0_10ObStoreCtxERKNS0_14ObDMLBaseParamERKNS_6common8ObIArrayImEEPNS7_16ObNewRowIteratorERl -_ZN9oceanbase7storage15ObDMLRunningCtxC1ERNS0_10ObStoreCtxERKNS0_14ObDMLBaseParamERNS_6common12ObIAllocatorES9_NS_12blocksstable9ObDmlFlagE -_ZN9oceanbase5share6schema19ObSchemaGetterGuardC1ENS1_15ObSchemaMgrItem3ModE -_ZN9oceanbase7storage8ObTablet10update_rowERNS0_15ObRelativeTableERNS0_10ObStoreCtxERKNS_6common8ObIArrayINS_5share6schema9ObColDescEEERKNS7_IlEERKNS0_10ObStoreRowESJ_PKNS7_INS_11transaction18ObEncryptMetaCacheEEE -_ZN9oceanbase3sql24ObTenantSqlMemoryManager18get_work_area_sizeEPNS_6common12ObIAllocatorERNS0_20ObSqlWorkAreaProfileE -_ZN9oceanbase3sql16ObFastParserBase12process_hintEv -_ZZN9oceanbase3sql20ObDASIndexDMLAdaptorILi2ENS0_16ObDASDMLIteratorEE12write_tabletERS2_RlENKUlPKcE_clES7_ -_ZN9oceanbase3sql17ObChunkDatumStore14init_batch_ctxEll -_ZN9oceanbase3sql13ObStmtFactory7destoryEv -_ZN9oceanbase6common11ObArrayImplINS_5share6schema18ObSchemaObjVersionENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_17DefaultItemEncodeIS4_EEED2Ev -_ZN9oceanbase3sql8ObSortOp11inner_closeEv -_ZNK9oceanbase3sql15ObTableLocation20calculate_tablet_idsERNS0_13ObExecContextERKNS_6common9Ob2DArrayINS4_10ObObjParamELi2079744ENS4_18ObWrapperAllocatorELb0ENS4_9ObSEArrayIPS6_Ll1ES7_Lb0EEEEERNS4_8ObIArrayINS4_10ObTabletIDEEERNSE_ImEESJ_RKNS4_20ObDataTypeCastParamsE -_ZN9oceanbase3sql17ObDASTabletMapper27get_non_partition_tablet_idERNS_6common8ObIArrayINS2_10ObTabletIDEEERNS3_ImEE -_ZN9oceanbase3sql8ObDASCtx21get_das_tablet_mapperEmRNS0_17ObDASTabletMapperEPKNS_6common12ObIArrayWrapImEE -_ZN9oceanbase6common13ObSEArrayImplImLl4ENS0_19ModulePageAllocatorELb0EE9push_backERKm -_ZN9oceanbase6common13ObSEArrayImplINS0_10ObTabletIDELl4ENS0_19ModulePageAllocatorELb0EE9push_backERKS2_ -_ZN9oceanbase5share6schema19ObSchemaGetterGuard16get_table_schemaEmmRPKNS1_13ObTableSchemaE -_ZN9oceanbase5share6schema19ObSchemaGetterGuard10get_schemaINS1_13ObTableSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_l -_ZN9oceanbase3sql17ObDASTabletMapper24get_tablet_and_object_idENS_5share6schema16ObPartitionLevelEmRKNS_6common10ObNewRangeERNS5_8ObIArrayINS5_10ObTabletIDEEERNS9_ImEE -_ZN9oceanbase6common19append_array_no_dupImEEiRNS0_8ObIArrayIT_EERKS4_ -_ZN9oceanbase6common13ObSEArrayImplImLl1ENS0_19ModulePageAllocatorELb0EE9push_backERKm -_ZN9oceanbase6common19append_array_no_dupINS0_10ObTabletIDEEEiRNS0_8ObIArrayIT_EERKS5_ -_ZN9oceanbase6common13ObSEArrayImplINS0_10ObTabletIDELl4ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase6common13ObSEArrayImplINS0_10ObTabletIDELl1ENS0_19ModulePageAllocatorELb0EE9push_backERKS2_ -_ZN9oceanbase6common13ObSEArrayImplImLl4ENS0_19ModulePageAllocatorELb0EED2Ev -_ZZNK9oceanbase5share6schema17ObPartitionSchema24get_tablet_and_object_idERNS_6common10ObTabletIDERmENK6$_2817clEPKc.llvm.12729199996529096754 -_ZN9oceanbase5share6schema16ObPartitionUtils24get_tablet_and_object_idERKNS1_13ObTableSchemaERNS_6common10ObTabletIDERmPNS1_16RelatedTableInfoE _ZN9oceanbase5share6schema19ObSchemaGetterGuard17get_schema_statusEmRNS1_21ObRefreshSchemaStatusE +_ZZN9oceanbase5share6schema19ObSchemaGetterGuard20get_from_local_cacheINS1_13ObTableSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_ENKUlPKcE3_clESB_ +_ZN9oceanbase3sql17ObDASTabletMapper24get_tablet_and_object_idENS_5share6schema16ObPartitionLevelEmRKNS_6common10ObNewRangeERNS5_8ObIArrayINS5_10ObTabletIDEEERNS9_ImEE +_ZN9oceanbase5share6schema16ObPartitionUtils24get_tablet_and_object_idERKNS1_13ObTableSchemaERNS_6common10ObTabletIDERmPNS1_16RelatedTableInfoE +_ZNK9oceanbase5share6schema21ObSimpleTableSchemaV213get_tablet_idEv +_ZNK9oceanbase5share6schema21ObSimpleTableSchemaV213get_object_idEv +_ZNK9oceanbase5share6schema17ObPartitionSchema24get_tablet_and_object_idERNS_6common10ObTabletIDERm +_ZNK9oceanbase5share6schema21ObSimpleTableSchemaV214get_part_levelEv +_ZNK9oceanbase5share6schema21ObSimpleTableSchemaV210has_tabletEv +_ZZNK9oceanbase5share6schema17ObPartitionSchema24get_tablet_and_object_idERNS_6common10ObTabletIDERmENK6$_2842clEPKc.llvm.10295148103953922454 _ZN9oceanbase5share6schema19ObSchemaGetterGuard18put_to_local_cacheINS1_8ObSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_RNS_6common15ObKVCacheHandleE _ZNK9oceanbase5share6schema19ObSysVariableSchema16get_convert_sizeEv _ZNK9oceanbase5share6schema13ObTableSchema16get_convert_sizeEv _ZNK9oceanbase5share6schema16ObColumnSchemaV216get_convert_sizeEv -_ZZN9oceanbase5share6schema19ObSchemaGetterGuard20get_from_local_cacheINS1_13ObTableSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_ENKUlPKcE3_clESB_ +_ZN9oceanbase3sql12ObDMLService24filter_row_for_check_cstERKNS_6common12ObFixedArrayIPNS0_6ObExprENS2_12ObIAllocatorEEERNS0_9ObEvalCtxERb +_ZN9oceanbase3sql12ObDMLService25check_dml_tablet_validityERNS0_10ObDMLRtCtxERKNS0_14ObDASTabletLocERKNS_6common12ObFixedArrayIPNS0_6ObExprENS7_12ObIAllocatorEEERKNS0_14ObDMLBaseCtDefERNS0_14ObDMLBaseRtDefE +_ZN9oceanbase5share6schema19ObSchemaGetterGuard23get_simple_table_schemaEmmRPKNS1_21ObSimpleTableSchemaV2E +_ZNK9oceanbase5share6schema11ObSchemaMgr16get_table_schemaEmmRPKNS1_21ObSimpleTableSchemaV2E +_ZNK9oceanbase5share6schema19ObSchemaGetterGuard14get_schema_mgrEmRPKNS1_11ObSchemaMgrE +_ZN9oceanbase3sql13TriggerHandle18init_param_old_rowERNS0_9ObEvalCtxERKNS0_14ObTrigDMLCtDefERNS0_14ObTrigDMLRtDefE +_ZN9oceanbase3sql15ObTableInsertOp20write_rows_post_procEi +_ZN9oceanbase3sql17ObPhysicalPlanCtx21sync_last_value_localEv +_ZN9oceanbase3sql13TriggerHandle18init_param_new_rowERNS0_9ObEvalCtxERKNS0_14ObTrigDMLCtDefERNS0_14ObTrigDMLRtDefE _ZNK9oceanbase5share6schema21ObSimpleTableSchemaV216get_convert_sizeEv _ZZN9oceanbase5share6schema19ObSchemaGetterGuard20get_from_local_cacheINS1_13ObTableSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_ENKUlPKcE1_clESB_ _ZN9oceanbase5share6schema19ObSchemaGetterGuard18get_schema_versionENS1_12ObSchemaTypeEmmRl -_ZNK9oceanbase5share6schema11ObSchemaMgr16get_table_schemaEmmRPKNS1_21ObSimpleTableSchemaV2E -_ZNK9oceanbase6common4hash16ObPointerHashMapImPNS_5share6schema21ObSimpleTableSchemaV2ENS4_13GetTableKeyV2ELl8064ENS0_19ModulePageAllocatorEE14get_refactoredERKmRS6_ -_ZZN9oceanbase5share6schema19ObSchemaGetterGuard18get_schema_versionENS1_12ObSchemaTypeEmmRlENK6$_1311clEPKc +_ZNK9oceanbase5share6schema11ObSchemaMgr17get_tenant_schemaEmRPKNS1_20ObSimpleTenantSchemaE +_ZN9oceanbase3sql13ObTableScanOp28inner_get_next_row_implementEv _ZN9oceanbase5share6schema27ObMultiVersionSchemaService10get_schemaEPKNS1_11ObSchemaMgrERKNS1_21ObRefreshSchemaStatusENS1_12ObSchemaTypeEmlRNS_6common15ObKVCacheHandleERPKNS1_8ObSchemaE _ZN9oceanbase5share6schema13ObSchemaCache10get_schemaENS1_12ObSchemaTypeEmmlRNS_6common15ObKVCacheHandleERPKNS1_8ObSchemaE _ZN9oceanbase6common9ObKVCacheINS_5share6schema16ObSchemaCacheKeyENS3_18ObSchemaCacheValueEE3getERKS4_RPKS5_RNS0_15ObKVCacheHandleE _ZN9oceanbase6common4hash11ObHashTableINS_5share6schema16ObSchemaCacheKeyENS1_11HashMapPairIS5_PKNS4_18ObSchemaCacheValueEEENS1_9hash_funcIS5_EENS1_8equal_toIS5_EENS1_10pair_firstISA_EENS1_13SimpleAllocerINS1_15ObHashTableNodeISA_EELi76ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19ReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14get_refactoredERKS5_RSA_l -_ZNK9oceanbase5share6schema14ObTenantSchema16get_convert_sizeEv +_ZZN9oceanbase5share6schema19ObSchemaGetterGuard18get_schema_versionENS1_12ObSchemaTypeEmmRlENK6$_1330clEPKc +_ZN9oceanbase6common13ObSEArrayImplImLl1ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZN9oceanbase3sql13ObTableScanOp26inner_get_next_row_for_tscEv +_ZN9oceanbase3sql11ObDASScanOp22get_output_result_iterEv +_ZN9oceanbase7storage19ObTableScanIterator12get_next_rowEv +_ZN9oceanbase3sql15DASOpResultIter12get_next_rowEv +_ZN9oceanbase6common22ObVirtualTableIterator12get_next_rowEv +_ZN9oceanbase6common7ObDatum8from_objERKNS0_5ObObjENS0_17ObObjDatumMapTypeE +_ZN9oceanbase7storage19ObTableScanIterator12get_next_rowERPNS_6common8ObNewRowE _ZN9oceanbase6common13ObSEArrayImplINS_5share6schema19ObSchemaGetterGuard9SchemaObjELl2ENS0_19ModulePageAllocatorELb0EE7reserveEl -_ZN9oceanbase5share6schema13ObTableSchemaC1Ev -_ZN9oceanbase5share6schema13ObTableSchemaC2Ev +_ZN9oceanbase6common15ObKVCacheHandleaSERKS1_ +_ZN9oceanbase6common17ObAtomicReference27dec_ref_cnt_and_inc_seq_numERj +_ZN9oceanbase3sql17datetime_datetimeERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE +_ZN9oceanbase6common15ObTimeConverter21timestamp_to_datetimeElPKNS0_14ObTimeZoneInfoERl +_ZN9oceanbase3sql13ObTableLockOp18inner_get_next_rowEv +_ZN9oceanbase3sql12ObDMLService16process_lock_rowERKNS0_11ObLockCtDefERNS0_11ObLockRtDefERbRNS0_15ObTableModifyOpE +_ZZN9oceanbase5share6schema19ObSchemaGetterGuard18get_schema_versionENS1_12ObSchemaTypeEmmRlENK6$_1295clEPKc +_ZN9oceanbase3sql13ObTableLockOp15lock_row_to_dasEv +_ZN9oceanbase6common22ObVirtualTableIterator12get_next_rowERPNS0_8ObNewRowE +_ZNK9oceanbase6common4hash18ObPointerHashArrayINS_5share6schema13ObColumnIdKeyEPNS4_16ObColumnSchemaV2ENS4_14ObGetColumnKeyEE14get_refactoredERKS5_RS7_ +_ZN9oceanbase3sql18ObNestedLoopJoinOp18inner_get_next_rowEv +backtrace +unw_backtrace +_ZZN9oceanbase11transaction30ObTransDeadlockDetectorAdapter36maintain_deadlock_info_when_end_stmtERNS_3sql13ObExecContextEbENK5$_757clEPKc.llvm.3724608408039839486 +_ZN9oceanbase3sql13AllocOpHelperILi26EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE +_ZN9oceanbase3sql17ObPhysicalPlanCtx19reserve_param_spaceEl +_ZZN9oceanbase3sql20ObDASIndexDMLAdaptorILi3ENS0_16ObDASUpdIteratorEE12write_tabletERS2_RlENKUlPKcE_clES7_ +_ZN9oceanbase3sql12ObSortOpImpl4initEmPKNS_6common8ObIArrayINS0_20ObSortFieldCollationEEEPKNS3_INS2_9ObCmpFuncEEEPNS0_9ObEvalCtxEPNS0_13ObExecContextEbbbllbl +_ZN9oceanbase6common4hash11ObHashTableINS_5share6schema19ObReferenceObjTable18ObDependencyObjKeyENS1_11HashMapPairIS6_PNS5_19ObDependencyObjItemEEENS1_9hash_funcIS6_EENS1_8equal_toIS6_EENS1_10pair_firstISA_EENS1_13SimpleAllocerINS1_15ObHashTableNodeISA_EELi89ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv _ZN9oceanbase6common13ObLinkHashMapINS0_9ObIntWarpENS_3sql11ObPxResInfoENS3_13ObPxInfoAllocENS0_9RefHandleELl8EE4nextEPNS0_12LinkHashNodeIS2_EE -_ZN9oceanbase7obmysql6OMPKOKD2Ev -_ZN9oceanbase3sql12ObSortOpImpl5reuseEv -MD5_Update -_ZN9oceanbase3sql19ObScalarAggregateOp11inner_closeEv _ZN9oceanbase3sql13AllocOpHelperILi11EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE _ZN9oceanbase3sql17ObMergeDistinctOpC1ERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputE -_ZN9oceanbase3sql13AllocOpHelperILi24EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE -_ZN9oceanbase8observer16ObMPPacketSender7do_initEPNS_3rpc9ObRequestEhbbl -_ZZN9oceanbase3sql20ObDASIndexDMLAdaptorILi3ENS0_16ObDASUpdIteratorEE12write_tabletERS2_RlENKUlPKcE_clES7_ +_ZNSt24uniform_int_distributionImEclISt23mersenne_twister_engineImLm32ELm624ELm397ELm31ELm2567483615ELm11ELm4294967295ELm7ELm2636928640ELm15ELm4022730752ELm18ELm1812433253EEEEmRT_RKNS0_10param_typeE _ZNK9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImPNS_3sql17ObILibCacheObjectEEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE18foreach_refactoredINS4_25ObDumpAllCacheObjByTypeOpEEEiRT_ -_ZN9oceanbase3sql19ObDataAccessService21execute_dist_das_taskERNS0_8ObDASRefERNS0_20ObDasAggregatedTasksEb -_ZN9oceanbase6common13ObSEArrayImplINS0_9ObSEArrayIPNS_3sql12ObIDASTaskOpELl2ENS0_19ModulePageAllocatorELb0EEELl2ES6_Lb0EE9push_backERKS7_ -_ZN9oceanbase3sql12ObIDASTaskOp13state_advanceEv -_ZN9oceanbase3sql13ObDASUpdateOpD2Ev -_ZN9oceanbase11transaction14ObTransService19sql_stmt_start_hookERKNS0_11ObXATransIDERNS0_8ObTxDescEjj -_ZN9oceanbase3omt15ObResourceGroup18check_worker_countERNS0_10ObThWorkerE -_ZN9oceanbase3sql15ObTableInsertOp10inner_openEv -_ZN9oceanbase6common11ObArrayWrapINS_3sql10ObInsRtDefEE14allocate_arrayERNS0_12ObIAllocatorEl -_ZN9oceanbase3sql12ObDMLService14init_ins_rtdefERNS0_10ObDMLRtCtxERNS0_10ObInsRtDefERKNS0_10ObInsCtDefERNS_6common8ObIArrayIPNS0_6ObExprEEE -_ZN9oceanbase3sql12ObDMLService18init_das_dml_rtdefERNS0_10ObDMLRtCtxERKNS0_17ObDASDMLBaseCtDefERNS0_17ObDASDMLBaseRtDefEPKNS0_17ObDASTableLocMetaE -_ZN9oceanbase3sql12ObDMLService22init_related_das_rtdefERNS0_10ObDMLRtCtxERKNS_6common12ObFixedArrayIPNS0_17ObDASDMLBaseCtDefENS4_12ObIAllocatorEEERNS4_11ObArrayWrapIPNS0_17ObDASDMLBaseRtDefEEE -_ZN9oceanbase3sql8ObDASCtx18extended_table_locERKNS0_17ObDASTableLocMetaERPNS0_13ObDASTableLocE -_ZN9oceanbase3sql12ObDMLService27process_before_stmt_triggerERKNS0_14ObDMLBaseCtDefERNS0_14ObDMLBaseRtDefERNS0_10ObDMLRtCtxERKNS_6common14ObDmlEventTypeE -_ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE11do_foreach_INS5_20ObArbitrationService16DoUpgradeFunctorENSA_14DoForeachOnBktISD_EEEEbRT_RT0_ -_ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE18set_foreach_L_lmt_Ev -_ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE16do_foreach_scan_INS5_20ObArbitrationService16DoUpgradeFunctorENSA_14DoForeachOnBktISD_EEEEbmmRT_RT0_ +_ZN9oceanbase3sql13ObStmtFactory7destoryEv +_ZN9oceanbase6common8ObLogger13need_to_printEi +_ZZNK9oceanbase6common4hash11ObHashTableINS_5share6schema19ObReferenceObjTable18ObDependencyObjKeyENS1_11HashMapPairIS6_PNS5_19ObDependencyObjItemEEENS1_9hash_funcIS6_EENS1_8equal_toIS6_EENS1_10pair_firstISA_EENS1_13SimpleAllocerINS1_15ObHashTableNodeISA_EELi89ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE18foreach_refactoredIZNS5_5resetEvE5$_234EEiRT_ENKUlPKcE_clESW_.llvm.11938380414531492831 +_ZN9oceanbase3sql12ObQueryRange13ObSearchState17init_search_stateElbm +_ZN9oceanbase3sql16ObFastParserBase12process_hintEv _ZN9oceanbase8observer16ObAsyncCmdDriver15response_resultERNS0_16ObMySQLResultSetE -_ZN9oceanbase7storage16ObMetaPointerMapINS0_14ObTabletMapKeyENS0_8ObTabletEE20for_each_value_storeINS0_22ObT3mTabletMapIterator17FetchTabletItemOpEEEiRT_ -_ZN9oceanbase6common16ObPriorityQueue2ILi0ELi1ELi0EE6do_popERPNS0_6ObLinkEll -_ZN9oceanbase3lib7ObFutex4waitEil -futex_hook -_ZN9oceanbase3sql15ObTableDeleteOp10inner_openEv -_ZN9oceanbase3sql15ObTableModifyOp10inner_openEv -_ZN9oceanbase3sql15ObTableInsertOp26check_need_exec_single_rowEv -_ZN9oceanbase6common11ObArrayWrapINS_3sql10ObDelRtDefEE14allocate_arrayERNS0_12ObIAllocatorEl -_ZN9oceanbase3sql12ObDMLService14init_del_rtdefERNS0_10ObDMLRtCtxERNS0_10ObDelRtDefERKNS0_10ObDelCtDefE -_ZN9oceanbase3sql10ObDASUtils25check_nested_sql_mutatingEmRNS0_13ObExecContextEb -_ZN9oceanbase6common13ObLinkHashMapINS_3sql14SessionInfoKeyENS2_16ObSQLSessionInfoENS2_15ObSQLSessionMgr10ValueAllocENS0_9RefHandleELl8EE4nextEPNS0_12LinkHashNodeIS3_EE +_ZN9oceanbase3sql14ObExprValuesOp11inner_closeEv +_ZN9oceanbase3sql13ObDatumCaster7destroyEv +_ZN9oceanbase3sql9ObEvalCtxD1Ev +_ZN9oceanbase3sql9ObEvalCtxD2Ev +_ZN9oceanbase3sql19ObScalarAggregateOp11inner_closeEv +_ZN9oceanbase3sql15ObTableUpdateOp10inner_openEv +access_mem _ZN9oceanbase3sql13AllocOpHelperILi10EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE _ZN9oceanbase3sql20ObAggregateProcessorC1ERNS0_9ObEvalCtxERNS_6common8ObIArrayINS0_10ObAggrInfoEEERKNS_3lib7ObLabelERNS0_13ObMonitorNodeEl -_ZN9oceanbase3sql19ObDataAccessService16execute_das_taskERNS0_8ObDASRefERNS0_20ObDasAggregatedTasksEb +_ZN9oceanbase3sql15ObTableUpdateOp11inner_closeEv +_ZN9oceanbase3sql12ObSortOpImpl5reuseEv _ZN9oceanbase3sql15ObTableInsertOp11inner_closeEv _ZN9oceanbase3sql15ObTableModifyOp11inner_closeEv _ZN9oceanbase3sql12ObDMLService26process_after_stmt_triggerERKNS0_14ObDMLBaseCtDefERNS0_14ObDMLBaseRtDefERNS0_10ObDMLRtCtxERKNS_6common14ObDmlEventTypeE -_ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScanner19cache_cur_micro_rowEbb -_ZN9oceanbase3sql9ObEvalCtxD1Ev -_ZN9oceanbase3sql9ObEvalCtxD2Ev +_ZN9oceanbase3sql10ObExprTrim9eval_trimERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE +_ZN9oceanbase3sql13cast_eval_argERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE +_ZN9oceanbase3sql30eval_assign_question_mark_funcERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE +_ZN9oceanbase6common11ObObjCaster7to_typeENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS5_ +_ZN9oceanbase3sql15ObDatumObjParam13from_objparamERKNS_6common10ObObjParamEPNS2_12ObIAllocatorE +_ZN9oceanbase3sqlL15eval_trim_innerERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumERKlRNS6_8ObStringERbRKNS0_11ObDatumMetaEbRKS7_ +_ZN9oceanbase3sql10ObExprTrim4trimERNS_6common8ObStringElRKS3_S6_ +_ZN9oceanbase3sql17ObChunkDatumStore14init_batch_ctxEll +_ZN9oceanbase3sql15ObTableInsertOp10inner_openEv +_ZN9oceanbase6common11ObArrayWrapINS_3sql10ObInsRtDefEE14allocate_arrayERNS0_12ObIAllocatorEl +_ZN9oceanbase3sql12ObDMLService14init_ins_rtdefERNS0_10ObDMLRtCtxERNS0_10ObInsRtDefERKNS0_10ObInsCtDefERNS_6common8ObIArrayIPNS0_6ObExprEEE +_ZN9oceanbase3sql12ObDMLService27process_before_stmt_triggerERKNS0_14ObDMLBaseCtDefERNS0_14ObDMLBaseRtDefERNS0_10ObDMLRtCtxERKNS_6common14ObDmlEventTypeE +_ZN9oceanbase3sql24ObTenantSqlMemoryManager18get_work_area_sizeEPNS_6common12ObIAllocatorERNS0_20ObSqlWorkAreaProfileE +_ZThn64_N9oceanbase7storage15ObTxCtxMemtable11get_rec_scnEv +_ZN9oceanbase11transaction12ObLSTxCtxMgr11get_rec_scnERNS_5share3SCNE +_ZN9oceanbase7storage16ObTxCtxTableInfoC2Ev +_ZN9oceanbase11transaction12ObTxExecInfoC2Ev +_ZN9oceanbase7storage16ObTxCtxTableInfoD2Ev +_ZN9oceanbase7storage16ObTxCtxTableInfo5resetEv +_ZN9oceanbase6common13ObSEArrayImplINS_11transaction9tablelock13ObTableLockOpELl10ENS2_24TransModulePageAllocatorELb0EED2Ev +_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner15check_blockscanERKNS0_13ObDatumRowkeyERb +_ZN9oceanbase6common16ObPriorityQueue2ILi0ELi1ELi0EE6do_popERPNS0_6ObLinkEll +_ZN9oceanbase3lib7ObFutex4waitEil +_ZN9oceanbase6common11ObLinkQueue3popERPNS0_6ObLinkE +futex_hook +_ZN9oceanbase7storage13ObTabletIDSet7foreachINS0_17ObLSTabletService22GetAllTabletIDOperatorEEEiRT_ +_ZN9oceanbase6common12ObBucketLock12try_lock_allEb +_ZN9oceanbase6common4hash11ObHashTableINS0_10ObTabletIDENS1_11HashMapPairIS3_NS1_11HashNullObjEEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS6_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS6_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE5beginEv +_ZN9oceanbase6common13ObSEArrayImplINS0_10ObTabletIDELl128ENS0_19ModulePageAllocatorELb0EE9push_backERKS2_ +_ZN9oceanbase6common13ObSEArrayImplINS0_10ObTabletIDELl2000ENS0_19ModulePageAllocatorELb0EE9push_backERKS2_ +_ZN9oceanbase5share6schema19ObSchemaGetterGuard23check_single_table_privERKNS1_17ObSessionPrivInfoERKNS1_10ObNeedPrivE +MD5_Update +_ZN9oceanbase7storage23ObSSTableRowLockChecker10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv +_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi2ELi2EEEE10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv +_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi2ELi2EE4initEiRNS_12blocksstable9ObSSTableERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPKv +_ZNK9oceanbase12blocksstable13ObDatumRowkey22to_multi_version_rangeERNS_6common12ObIAllocatorERNS0_12ObDatumRangeE +_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi2ELi2EE15init_basic_infoEiRNS_12blocksstable9ObSSTableERNS0_20ObTableAccessContextEPKvRb +_ZN9oceanbase6common16ObFixedArrayImplINS_7storage30ObIndexTreeMultiPassPrefetcherILi2ELi2EE22ObIndexTreeLevelHandleENS0_12ObIAllocatorEE16prepare_allocateEl +_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi2ELi2EE8prefetchEv +_ZN9oceanbase7storage30ObIndexTreeMultiPassPrefetcherILi2ELi2EE22ObIndexTreeLevelHandle7forwardERKNS_12blocksstable13ObDatumRowkeyEb +_ZN9oceanbase7storage23ObReallocatedFixedArrayINS0_19ObSSTableReadHandleEE18prepare_reallocateEl +_ZN9oceanbase6common16ObFixedArrayImplINS_7storage30ObIndexTreeMultiPassPrefetcherILi2ELi2EE22ObIndexTreeLevelHandleENS0_12ObIAllocatorEE7reserveEl +_ZN9oceanbase6common16ObFixedArrayImplINS_7storage30ObIndexTreeMultiPassPrefetcherILi2ELi2EE22ObIndexTreeLevelHandleENS0_12ObIAllocatorEE4initEl +_ZN9oceanbase6common16ObMemLeakChecker8on_allocERNS_3lib7AObjectERKNS2_9ObMemAttrE +_ZN9oceanbase3sql15ObTableDeleteOp11inner_closeEv +_ZN9oceanbase3sql19ObDataAccessService21execute_dist_das_taskERNS0_8ObDASRefERNS0_20ObDasAggregatedTasksEb +_ZN9oceanbase6common13ObSEArrayImplINS0_9ObSEArrayIPNS_3sql12ObIDASTaskOpELl2ENS0_19ModulePageAllocatorELb0EEELl2ES6_Lb0EE9push_backERKS7_ +_ZN9oceanbase3sql12ObIDASTaskOp13state_advanceEv +_ZN9oceanbase3sql16ObFastParserBase19is_multi_byte_spaceEPKcllRl +_ZN9oceanbase3sql19ObScalarAggregateOp7destroyEv +_ZN9oceanbase6common9Ob2DArrayIPNS_3sql20ObAggregateProcessor8GroupRowELi65408ENS0_19ModulePageAllocatorELb0ENS0_9ObSEArrayIPS5_Ll64ES6_Lb0EEEED2Ev +_ZN9oceanbase3sql17ObChunkDatumStore15ShadowStoredRow5resetEv +_ZN9oceanbase6common7ObTimer4run1Ev +_ZN9oceanbase6common15ObKVGlobalCache16KVMapReplaceTask12runTimerTaskEv +_ZN9oceanbase6common14ObTimerMonitor8end_taskEll +_ZN9oceanbase6common14ObTimerMonitor10start_taskElllPKNS0_11ObTimerTaskE +_ZN9oceanbase3sql26ObPlanCacheEliminationTask12runTimerTaskEv +_ZN9oceanbase7storage21ObTenantTabletStatMgr17TabletStatUpdater12runTimerTaskEv +_ZN9oceanbase6common4hash11ObHashTableINS_7storage15ObTabletStatKeyENS1_11HashMapPairIS4_PNS3_18ObTabletStreamNodeEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS8_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS8_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14get_refactoredERKS4_RS8_l +_ZN9oceanbase6common12ObBucketLock6unlockEm +_ZN9oceanbase6common12ObBucketLock6wrlockEml +_ZN9oceanbase6common12ObBucketLock6rdlockEml +_ZNK6obutil9ObMonitorINS_11ObUtilMutexEE10timed_waitERKNS_9ObSysTimeE +_ZN6obutil9ObSysTime3nowENS0_5ClockE +_ZN9oceanbase6common7ObTimer12insert_tokenERKNS1_5TokenE +_ZN6obutil7ObLockTINS_9ObMonitorINS_11ObUtilMutexEEEED2Ev +_ZN9oceanbase3sql19ObDumpAllCacheObjOpclERNS_6common4hash11HashMapPairImPNS0_17ObILibCacheObjectEEE +_ZNK9oceanbase3sql25ObDumpAllCacheObjByTypeOp11should_dumpEPNS0_17ObILibCacheObjectE +_ZNK9oceanbase6common20ObSafeArenaAllocator4usedEv +_ZN9oceanbase4palf16BlockGCTimerTask12runTimerTaskEv +_ZN9oceanbase12blocksstable14ObBlockManager19InspectBadBlockTask12runTimerTaskEv +_ZN9oceanbase6common15ObKVGlobalCache15KVStoreWashTask12runTimerTaskEv +_ZN9oceanbase6common12ObKVCacheMap18clean_garbage_nodeERll +_ZN9oceanbase6common14ObKVCacheStore18reuse_wash_structsEv +_ZN9oceanbase6common19GlobalHazardVersion6retireEm +_ZN9oceanbase6common24KVCacheHazardThreadStore6retireEmm +_ZN9oceanbase6common24KVCacheHazardThreadStore9add_nodesERNS0_17KVCacheHazardNodeE +_ZN9oceanbase6common14ObKVCacheStore24compute_tenant_wash_sizeEv +_ZN9oceanbase6common16ObKVCacheInstMap14get_cache_infoEmRNS0_8ObIArrayINS0_19ObKVCacheInstHandleEEE +_ZN9oceanbase6common22ObFixedHashMapIteratorImPNS0_14ObKVCacheStore14TenantWashInfoENS0_4hash9hash_funcImEEEppEv +_ZN9oceanbase6common16ObKVCacheInstMap22inner_push_inst_handleERKNS0_4hash19ObHashTableIteratorINS0_16ObKVCacheInstKeyENS2_11HashMapPairIS4_PNS0_13ObKVCacheInstEEENS2_9hash_funcIS4_EENS2_8equal_toIS4_EENS2_10pair_firstIS8_EENS2_13SimpleAllocerINS2_15ObHashTableNodeIS8_EELi98ENS2_19SpinMutexDefendModeENS2_29DefaultSimpleAllocerAllocatorEEENS2_19NoPthreadDefendModeENS2_13NormalPointerENS0_8ObMallocELl1EEERNS0_8ObIArrayINS0_19ObKVCacheInstHandleEEE +_ZNK9oceanbase8observer22ObGlobalReqTimeService25get_global_safe_timestampERl +_ZN9oceanbase6common11ObArrayImplINS_3sql17AllocCacheObjInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ +_ZN9oceanbase7storage10checkpoint16ObEmptyShellTask12runTimerTaskEv +_ZN9oceanbase7storage18ObLSTabletIterator15get_next_tabletERNS0_14ObTabletHandleE +_ZN9oceanbase6common16ObKVCacheInstMap13refresh_scoreEv +_ZZN9oceanbase3sql26ObPlanCacheEliminationTask12runTimerTaskEvENK5$_323clEPKc +_ZN9oceanbase4palf11PalfEnvImpl18try_recycle_blocksEv +_ZN9oceanbase4palf11PalfEnvImpl15get_disk_usage_ERlS2_S2_S2_ +_ZNK9oceanbase4palf14PalfHandleImpl25get_total_used_disk_spaceERlS2_ +_ZZNK9oceanbase4palf9LogEngine25get_total_used_disk_spaceERlS2_ENK5$_660clEPKc +_ZNK9oceanbase4palf9LogEngine25get_total_used_disk_spaceERlS2_ +_ZNK9oceanbase4palf11LogBlockMgr18get_block_id_rangeERmS2_ +_ZNK9oceanbase4palf10LogStorage11get_end_lsnEv +_ZNK9oceanbase4palf9LogEngine30get_base_lsn_used_for_block_gcEv +_ZZN9oceanbase4palf11PalfEnvImpl21GetTotalUsedDiskSpaceclERKNS0_5LSKeyEPNS0_15IPalfHandleImplEENK5$_817clEPKc +_ZN9oceanbase3omt19ObTenantTimezoneMgr18UpdateTenantTZTask12runTimerTaskEv +_ZN9oceanbase6common14ObKVCacheStore30purge_mb_handle_retire_stationEv +_ZN9oceanbase4palf10LogUpdater12runTimerTaskEv +_ZNK9oceanbase6common22ObTenantMemLimitGetter20get_tenant_mem_limitEmRlS2_ +_ZN9oceanbase6common15ObKVGlobalCache20print_all_cache_infoEv +_ZN9oceanbase6common16ObKVCacheInstMap23print_tenant_cache_infoEm +_ZN9oceanbase14dbms_scheduler18ObDBMSSchedJobTask12runTimerTaskEv +_ZN9oceanbase6common16ObFixedArrayImplINS0_19ObKVCacheInstHandleENS0_16ObArenaAllocatorEE9push_backERKS2_ +_ZN9oceanbase8observer18ObTableLoadService8ObGCTask12runTimerTaskEv +_ZN9oceanbase3sql9ObPsCache17inner_cache_evictEb +_ZN9oceanbase10rootserver14ObDDLScheduler18HeartBeatCheckTask12runTimerTaskEv +_ZN9oceanbase3omt14ObTenantSrsMgr16DeleteTenantTask12runTimerTaskEv +_ZN9oceanbase12blocksstable21ObSharedMacroBlockMgr26ObBlockDefragmentationTask12runTimerTaskEv +_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdEiNS0_14ShareMemMgrTagEE16do_foreach_scan_INS2_21ObSharedMacroBlockMgr15GetSmallBlockOpENS5_14DoForeachOnBktIS8_EEEEbmmRT_RT0_ +_ZN9oceanbase3sql26ObPlanCacheEliminationTask19run_plan_cache_taskEv +_ZN9oceanbase12blocksstable21ObSharedMacroBlockMgr13update_tabletERKNS_7storage14ObTabletHandleERKNS_6common8ObIArrayINS0_12MacroBlockIdEEERlRNS0_21ObSSTableIndexBuilderERNS0_21ObIndexBlockRebuilderE +_ZN9oceanbase3sql17ObMergeDistinctOp11inner_closeEv _ZN9oceanbase8observer15ObSyncCmdDriver15response_resultERNS0_16ObMySQLResultSetE _ZN9oceanbase8observer15ObSyncCmdDriver30process_schema_version_changesERKNS0_16ObMySQLResultSetE -_ZN9oceanbase6common13ObSEArrayImplINS_3sql15ObCandiTableLocELl2ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase7storage23ObScanMergeLoserTreeCmp3cmpERKNS0_24ObScanMergeLoserTreeItemES4_Rl -backtrace -unw_backtrace -_ZN9oceanbase3sql15ObTableUpdateOp11inner_closeEv -_ZN9oceanbase3sql8ObDASRef14close_all_taskEv -_ZN9oceanbase3sql15ObTableUpdateOp10inner_openEv -_ZN9oceanbase3sql15ObTableUpdateOp26check_need_exec_single_rowEv -_ZZN9oceanbase3sql20ObDASIndexDMLAdaptorILi4ENS0_16ObDASDMLIteratorEE12write_tabletERS2_RlENKUlPKcE_clES7_ -_ZN9oceanbase7storage15ObMultipleMerge5reuseEv -_ZN9oceanbase3sql17ObMergeDistinctOp7destroyEv -_ZN9oceanbase3sql15ObTableDeleteOp11inner_closeEv -_ZN9oceanbase3sql13ObDASInsertOpD2Ev +_ZN9oceanbase7storage16ObMetaPointerMapINS0_14ObTabletMapKeyENS0_8ObTabletEE20for_each_value_storeINS0_22ObT3mTabletMapIterator17FetchTabletItemOpEEEiRT_ _ZN9oceanbase3sql19ObScalarAggregateOp10inner_openEv _ZN9oceanbase3sql11ObGroupByOp10inner_openEv _ZN9oceanbase3sql20ObAggregateProcessor4initEv _ZN9oceanbase3sql17ObChunkDatumStore15ShadowStoredRow4initERNS_6common12ObIAllocatorEl -_ZN9oceanbase6common9Ob2DArrayIPNS_3sql20ObAggregateProcessor8GroupRowELi65408ENS0_19ModulePageAllocatorELb0ENS0_9ObSEArrayIPS5_Ll64ES6_Lb0EEEE9push_backERKS5_ _ZN9oceanbase6common16ObFixedArrayImplIPNS_3sql20ObAggregateProcessor12IAggrFuncCtxENS0_12ObIAllocatorEE16prepare_allocateEl -_ZN9oceanbase6common16ObFixedArrayImplIPNS_3sql20ObAggregateProcessor12IAggrFuncCtxENS0_12ObIAllocatorEE7reserveEl +_ZN9oceanbase6common9Ob2DArrayIPNS_3sql20ObAggregateProcessor8GroupRowELi65408ENS0_19ModulePageAllocatorELb0ENS0_9ObSEArrayIPS5_Ll64ES6_Lb0EEEE9push_backERKS5_ _ZN9oceanbase6common9Ob2DArrayIPNS_3sql20ObAggregateProcessor8GroupRowELi65408ENS0_19ModulePageAllocatorELb0ENS0_9ObSEArrayIPS5_Ll64ES6_Lb0EEEE7reserveEl +_ZN9oceanbase6common16ObFixedArrayImplIPNS_3sql20ObAggregateProcessor12IAggrFuncCtxENS0_12ObIAllocatorEE7reserveEl _ZN9oceanbase6common16ObFixedArrayImplIPNS_3sql20ObAggregateProcessor12IAggrFuncCtxENS0_12ObIAllocatorEE4initEl _ZN9oceanbase3sql20ObAggregateProcessor18generate_group_rowERPNS1_8GroupRowEl -_ZN9oceanbase6common12ObBucketLock10unlock_allEv -_ZN9oceanbase3sql17ObChunkDatumStore15ShadowStoredRow5resetEv -_ZN9oceanbase3sql13ObDASDeleteOpD2Ev -_ZN9oceanbase7storage30ObSSTableMultiVersionRowGetterC2Ev -_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEEC2Ev -_ZL20ob_strnncoll_utf8mb4PK13ObCharsetInfoPKhmS3_mb -_ZN9oceanbase3sql19ObScalarAggregateOp7destroyEv -_ZN9oceanbase3sql17ObMergeDistinctOp11inner_closeEv -_ZZN9oceanbase6common5occam20ObThreadHungDetectorC1EvENKUlvE_clEv -_ZN9oceanbase7storage30ObSSTableMultiVersionRowGetterD2Ev +_ZN9oceanbase11transaction23ObTenantWeakReadService10handle_ls_ERNS_7storage4ObLSE +_Znwm +_ZTWN9oceanbase3lib21ObMallocHookAttrGuard11tl_mem_attrE +_Z14ob_malloc_hookmPKv +_ZZN9oceanbase7storage14ObLSWRSHandler38generate_ls_weak_read_snapshot_versionERNS0_4ObLSERbS4_RNS_5share3SCNElENK5$_244clEPKc +_ZN9oceanbase5share3SCN10inc_updateERKS1_ +_ZN9oceanbase7storage14ObLSWRSHandler38generate_ls_weak_read_snapshot_versionERNS0_4ObLSERbS4_RNS_5share3SCNEl +_ZNK9oceanbase5share3SCN13convert_to_tsEb +_ZN9oceanbase7storage14ObLSWRSHandler29generate_weak_read_timestamp_ERNS0_4ObLSElRNS_5share3SCNE +_ZN9oceanbase10logservice12ObLogHandler19get_max_decided_scnERNS_5share3SCNE +_ZN9oceanbase10logservice19ObReplayStatusGuardD2Ev +_ZZN9oceanbase10logservice12ObLogHandler19get_max_decided_scnERNS_5share3SCNEENK5$_323clEPKc.llvm.560452860553789535 +_ZN9oceanbase10logservice17ObLogApplyService19get_max_applied_scnERKNS_5share6ObLSIDERNS2_3SCNE +_ZN9oceanbase10logservice13ObApplyStatus19get_max_applied_scnERNS_5share3SCNE +_ZNK9oceanbase4palf14PalfHandleImpl11get_max_scnEv +_ZZN9oceanbase10logservice23ObApplyServiceQueueTask22is_snapshot_apply_doneERbENK3$_5clEPKc +_ZN9oceanbase4palf24palf_reach_time_intervalElRl +_ZN9oceanbase10logservice13ObApplyStatus22update_last_check_scn_Ev +_ZNK9oceanbase4palf12LSNAllocator11get_max_scnEv +_ZN9oceanbase10logservice17ObLogApplyService16wait_append_syncERKNS_5share6ObLSIDE +_ZN9oceanbase10logservice11ObLSAdapter16wait_append_syncERKNS_5share6ObLSIDE +_ZN9oceanbase10logservice18ObLogReplayService20get_max_replayed_scnERKNS_5share6ObLSIDERNS2_3SCNE +_ZN9oceanbase10logservice18ObLogReplayService18get_replay_status_ERKNS_5share6ObLSIDERNS0_19ObReplayStatusGuardE +_ZN9oceanbase10logservice14ObReplayStatus27get_min_unreplayed_log_infoERNS_4palf3LSNERNS_5share3SCNERlRNS0_13ObLogBaseTypeES8_S8_S8_ +_ZNK9oceanbase10logservice25ObReplayServiceSubmitTask27get_next_to_submit_log_infoERNS_4palf3LSNERNS_5share3SCNE +_ZZN9oceanbase10logservice17ObLogApplyService16get_apply_statusERKNS_5share6ObLSIDERNS0_18ObApplyStatusGuardEENK5$_158clEPKc.llvm.8551272636852309278 +_ZZN9oceanbase10logservice13ObApplyStatus19get_max_applied_scnERNS_5share3SCNEENK4$_67clEPKc +_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE16load_access_bkt_ERKS3_RmRPNS8_6BucketE +_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE7shrink_Ev +_ZNK9oceanbase5share6schema16ObSchemaCacheKeyeqERKNS_6common13ObIKVCacheKeyE +_ZN9oceanbase3sql20ObPxEstimateSizeUtil11get_px_sizeEPNS0_13ObExecContextENS0_14PxOpSizeFactorElRl +_ZN9oceanbase6common16ObArenaAllocator5resetEv +_ZN9oceanbase6common13ObSEArrayImplINS_3sql15ObCandiTableLocELl2ENS0_19ModulePageAllocatorELb0EE5reuseEv +_ZN9oceanbase3sql17ObMergeDistinctOp7destroyEv +_ZN9oceanbase6common12ObMemoryDump4run1Ev +_ZN9oceanbase6common18do_with_segv_catchIRZNS0_12ObMemoryDump6handleEPvE4$_23EEvOT_RbRDTclfL0p_EE +_ZTWN9oceanbase6common3jmpE +__tls_init.llvm.7346562358563844286 +_ZTHN9oceanbase3lib21ObMallocHookAttrGuard11tl_mem_attrE +_ZNK9oceanbase6common4hash9hash_funcINS_3lib17ObMallocSampleKeyEEclERKS4_Rm +_ZN9oceanbase6common4hash11ObHashTableINS_3lib17ObMallocSampleKeyENS1_11HashMapPairIS4_NS3_19ObMallocSampleValueEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi34ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14set_refactoredERKS4_RKS7_iii +_ZN9oceanbase3lib20ObTenantCtxAllocator10get_chunksEPPNS0_6AChunkEiRi _ZN9oceanbase3sql12ObSqlPlanSet13get_plan_typeERKNS_6common8ObIArrayINS0_15ObTableLocationEEEbRNS0_14ObPlanCacheCtxERNS3_INS0_15ObCandiTableLocEEERNS0_13ObPhyPlanTypeE +_ZN9oceanbase7obmysql11ObMySQLUtil15number_cell_strEPclRKNS_6common6number8ObNumberERlsbi +_ZNK9oceanbase6common6number8ObNumber9format_v2EPclRlsb +_ZN9oceanbase6common15ObFastFormatInt15format_unsignedEmPc +_ZN9oceanbase12blocksstable44ObMultiVersionMicroBlockMinorMergeRowScanner18inner_get_next_rowERPKNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable44ObMultiVersionMicroBlockMinorMergeRowScanner17compact_first_rowEv +_ZN9oceanbase12blocksstable10ObRowQueue7add_rowERKNS0_10ObDatumRowERNS_6common12ObIAllocatorE +_ZN9oceanbase12blocksstable10ObDatumRow9deep_copyERKS1_RNS_6common12ObIAllocatorE +_ZN9oceanbase12blocksstable44ObMultiVersionMicroBlockMinorMergeRowScanner20read_uncommitted_rowERbRPKNS0_10ObDatumRowE +_ZN9oceanbase10compaction21ObCachedTransStateMgr15get_trans_stateERKNS_11transaction9ObTransIDElRNS0_23ObMergeCachedTransStateE +_ZZN9oceanbase3sql20ObDASIndexDMLAdaptorILi3ENS0_16ObDASUpdIteratorEE12write_tabletERS2_RlENKUlPKcE3_clES7_ +_ZN9oceanbase6common12ObBucketLock10unlock_allEv +_ZN9oceanbase4palf20IPalfHandleImplGuardD1Ev +_ZN9oceanbase4palf20IPalfHandleImplGuardD2Ev +_ZZN9oceanbase6common5occam20ObThreadHungDetectorC1EvENKUlvE_clEv +_ZN9oceanbase3sql16ObSQLSessionInfo24update_show_warnings_bufEv _ZN9oceanbase4palf11PalfEnvImpl20get_palf_handle_implElRNS0_20IPalfHandleImplGuardE _ZNK9oceanbase4palf14PalfHandleImpl17check_can_be_usedEv _ZN9oceanbase4palf11PalfEnvImpl20get_palf_handle_implElRPNS0_15IPalfHandleImplE _ZN9oceanbase6common13ObLinkHashMapINS_4palf5LSKeyENS2_15IPalfHandleImplENS2_19PalfHandleImplAllocENS0_9RefHandleELl8EE3getERKS3_RPS4_ +_ZN9oceanbase6common13ObLinkHashMapINS_4palf5LSKeyENS2_15IPalfHandleImplENS2_19PalfHandleImplAllocENS0_9RefHandleELl8EE12err_code_mapEi +_ZN9oceanbase6common6QClock14enter_criticalEv _ZN9oceanbase6common6DCHashINS_4palf5LSKeyELl8EE3getERKS3_RPNS0_11KeyHashNodeIS3_EE _ZN9oceanbase6common6DCHashINS_4palf5LSKeyELl8EE6Handle10search_preEmRPNS0_8HashNodeE _ZN9oceanbase6common6DCHashINS_4palf5LSKeyELl8EE6Handle6retireEil -_ZN9oceanbase6common6DCHashINS_4palf5LSKeyELl8EE24alloc_and_init_cur_arrayEv _ZN9oceanbase6common6DCHashINS_4palf5LSKeyELl8EE15do_pending_taskEPNS0_7DCArrayE -_ZN9oceanbase10rootserver14ObDDLScheduler9DDLIdling20get_idle_interval_usEv -_ZN9oceanbase7storage13ObTabletIDSet7foreachINS0_17ObLSTabletService22GetAllTabletIDOperatorEEEiRT_ -_ZN9oceanbase6common13ObSEArrayImplINS0_10ObTabletIDELl128ENS0_19ModulePageAllocatorELb0EE9push_backERKS2_ -_ZN9oceanbase6common4hash11ObHashTableINS0_10ObTabletIDENS1_11HashMapPairIS3_NS1_11HashNullObjEEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS6_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS6_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE5beginEv -_ZN9oceanbase7storage30ObSSTableMultiVersionRowGetter10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv -_ZN9oceanbase6common12ObMemoryDump4run1Ev -_ZN9oceanbase6common18do_with_segv_catchIRZNS0_12ObMemoryDump6handleEPvE4$_23EEvOT_RbRDTclfL0p_EE -_ZNK9oceanbase6common4hash9hash_funcINS_3lib17ObMallocSampleKeyEEclERKS4_Rm -_ZN9oceanbase3lib20ObTenantCtxAllocator10get_chunksEPPNS0_6AChunkEiRi -_ZN9oceanbase6common4hash11ObHashTableINS_3lib17ObMallocSampleKeyENS1_11HashMapPairIS4_NS3_19ObMallocSampleValueEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi34ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14set_refactoredERKS4_RKS7_iii -_ZN9oceanbase7storage15ObTabletPointer14get_ddl_kv_mgrERNS0_14ObMetaObjGuardINS0_16ObTabletDDLKvMgrEEE -_ZN9oceanbase7storage14ObMetaObjGuardINS0_16ObTabletDDLKvMgrEEaSERKS3_ +_ZN9oceanbase6common6DCHashINS_4palf5LSKeyELl8EE24alloc_and_init_cur_arrayEv +_ZN9oceanbase6common13ObLinkHashMapINS_3sql14SessionInfoKeyENS2_16ObSQLSessionInfoENS2_15ObSQLSessionMgr10ValueAllocENS0_9RefHandleELl8EE3mapINS8_8HandleOnINS_5share20ObActiveSessHistTaskEEEEEiRT_ +_ZN9oceanbase6common13ObLinkHashMapINS_3sql14SessionInfoKeyENS2_16ObSQLSessionInfoENS2_15ObSQLSessionMgr10ValueAllocENS0_9RefHandleELl8EE4nextEPNS0_12LinkHashNodeIS3_EE _ZNK9oceanbase5share6schema16ObSchemaCacheKey4hashERm +_ZN9oceanbase7storage17ObLSTabletService24prepare_scan_table_paramERNS0_16ObTableScanParamERNS_5share6schema27ObMultiVersionSchemaServiceE +_ZN9oceanbase6common15ObLinearHashMapINS0_10ObTabletIDENS_7storage3mds4ListINS4_12MdsTableBaseEEENS0_14ShareMemMgrTagEE16do_foreach_scan_IZNS4_13ObMdsTableMgr11get_rec_scnEvE4$_41NS9_14DoForeachOnBktISC_EEEEbmmRT_RT0_ +_ZN9oceanbase6common15ObLinearHashMapINS0_10ObTabletIDENS_7storage3mds4ListINS4_12MdsTableBaseEEENS0_14ShareMemMgrTagEE16load_access_bkt_EmRPNS9_6BucketE +_ZN9oceanbase6common9sqlclient13ObMySQLResultD2Ev +_ZN9oceanbase5trace4UUID8gen_randEv +_ZN9oceanbase3sql17ObSqlTransControl18implicit_end_transERNS0_13ObExecContextEbPNS0_23ObEndTransAsyncCallbackE +_ZN9oceanbase6common9ob_usleepILNS0_14ObWaitEventIds17ObWaitEventIdEnumE128EEEvj +_ZN9oceanbase6common10ObIOHandle5resetEv +_ZN9oceanbase11transaction7ObTsMgr4run1Ev +_ZN9oceanbase6common13ObLinkHashMapINS0_9ObIntWarpENS_11transaction14ObTsSourceInfoENS3_19ObTsSourceInfoAllocENS0_9RefHandleELl8EE4nextEPNS0_12LinkHashNodeIS2_EE +_ZN9oceanbase6common15ObIKVCacheStoreINS0_18ObKVMemBlockHandleEE5storeERNS0_13ObKVCacheInstERKNS0_13ObIKVCacheKeyERKNS0_15ObIKVCacheValueERPNS0_13ObKVCachePairERPS2_NS0_15ObKVCachePolicyE +_ZNK9oceanbase12blocksstable19ObFuseRowCacheValue9deep_copyEPclRPNS_6common15ObIKVCacheValueE +_ZN9oceanbase6common15ObIKVCacheStoreINS0_18ObKVMemBlockHandleEE12alloc_kvpairERNS0_13ObKVCacheInstEllRPNS0_13ObKVCachePairERPS2_NS0_15ObKVCachePolicyE +_ZN9oceanbase6common17ObKVStoreMemBlock5allocElllRPNS0_13ObKVCachePairE +_ZNK9oceanbase12blocksstable17ObFuseRowCacheKey9deep_copyEPclRPNS_6common13ObIKVCacheKeyE +_ZNK9oceanbase12blocksstable20ObMicroBlockCacheKey9deep_copyEPclRPNS_6common13ObIKVCacheKeyE +_ZN9oceanbase3lib12SubObjectMgr11alloc_blockEmRKNS0_9ObMemAttrE +_ZN9oceanbase11transaction14ObTxLoopWorker4run1Ev +_ZN9oceanbase11transaction14ObTxLoopWorker12scan_all_ls_Ebb +_ZN9oceanbase6common13ObSharedGuardINS_7storage12ObLSIteratorEE5resetEv +_ZN9oceanbase6common11ObArrayImplIPNS_7storage4ObLSENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEED2Ev +_ZN9oceanbase11transaction12ObLSTxCtxMgr22check_scheduler_statusERNS_5share3SCNERNS0_17MinStartScnStatusE +_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_10ObTransCtxENS0_13TransCtxAllocENS_6common10SpinRWLockELl16384EE19generate_value_arr_ElRNS5_9ObSEArrayIPS3_Ll32ENS5_19ModulePageAllocatorELb0EEE +_ZNK9oceanbase6common10ObFunctionIFvPNS_7storage12ObLSIteratorEEE7DerivedIZNS2_11ObLSService11get_ls_iterERNS0_13ObSharedGuardIS3_EENS2_10ObLSGetModEE5$_396E6invokeES4_$f27777b3526f11015b9340ebba6db99a +_ZN9oceanbase11transaction39IteratePartCtxAskSchedulerStatusFunctor17internal_operatorERKNS0_9ObTransIDEPNS0_14ObPartTransCtxE +_ZN9oceanbase7storage11ObLSService11get_ls_iterERNS_6common13ObSharedGuardINS0_12ObLSIteratorEEENS0_10ObLSGetModE +_ZN9oceanbase6common5guard27DefaultSharedGuardAllocator5allocEl +_ZNK9oceanbase10logservice15ObLogBaseHeader9serializeEPclRl +_ZN9oceanbase11transaction14ObPartTransCtx22check_scheduler_statusEv +_ZN9oceanbase11transaction14ObPartTransCtx28check_rs_scheduler_is_alive_ERb +_ZN9oceanbase10rootserver17ObUnitStatManager11gather_statEv +_Z10futex_waitPViiPK8timespec +_ZN9oceanbase3omt13ObMultiTenant4run1Ev +_ZN9oceanbase3omt8ObTenant6timeupEv +_ZN9oceanbase3omt15ObResourceGroup18check_worker_countEv +_ZNK9oceanbase3omt8ObTenant14min_worker_cntEv +_ZN9oceanbase8observer17ObSrvNetworkFrame31reload_tenant_sql_thread_configEm +_ZN9oceanbase5share11ObTenantEnv10set_tenantEPNS0_12ObTenantBaseE +_ZN9oceanbase5share12ObTenantBaseaSERKS1_ +_ZN9oceanbase5share12ObTenantBaseC1Emb +_ZN9oceanbase5share12ObTenantBaseC2Emb +_ZN9oceanbase8observer11QueueThread16set_thread_countEi _ZN9oceanbase6common16ObCommonSqlProxy4readERNS0_12ObISQLClient10ReadResultEmPKc +_ZN9oceanbase8observer20ObInnerSQLConnection3refEv +_ZN9oceanbase6common16ObCommonSqlProxy4readEPNS0_9sqlclient16ObISQLConnectionERNS0_12ObISQLClient10ReadResultEmPKcPKNS0_6ObAddrE +_ZN9oceanbase8observer20ObInnerSQLConnection12execute_readEmPKcRNS_6common12ObISQLClient10ReadResultEbPKNS4_6ObAddrE +_ZN9oceanbase8observer20ObInnerSQLConnection12execute_readElmRKNS_6common8ObStringERNS2_12ObISQLClient10ReadResultEbPKNS2_6ObAddrE +_ZZN9oceanbase6common16ObCommonSqlProxy4readEPNS0_9sqlclient16ObISQLConnectionERNS0_12ObISQLClient10ReadResultEmPKcPKNS0_6ObAddrEENK5$_264clES9_.llvm.1081226593173334589 _ZN9oceanbase8observer24ObInnerSQLConnectionPool7acquireEmRPNS_6common9sqlclient16ObISQLConnectionEPNS2_12ObISQLClientE +_ZN9oceanbase6common10EventTable8instanceEv _ZN9oceanbase8observer24ObInnerSQLConnectionPool10alloc_connERPNS0_20ObInnerSQLConnectionE _ZN9oceanbase8observer20ObInnerSQLConnectionC2Ev -_ZN9oceanbase3sql16ObSQLSessionInfoC1Ev -_ZN9oceanbase3sql16ObSQLSessionInfoC2Ev -_ZN9oceanbase3sql29ObTenantCachedSchemaGuardInfoC2Ev -_ZN9oceanbase11transaction14ObTxExecResultC1Ev +_ZN9oceanbase3sql18ObBasicSessionInfo13SysVarIncInfoC2Ev _ZN9oceanbase8observer20ObInnerSQLConnection4initEPNS0_24ObInnerSQLConnectionPoolEPNS_5share6schema27ObMultiVersionSchemaServiceEPNS_3sql5ObSqlEPNS0_15ObVTIterCreatorEPNS_6common14ObServerConfigEPNS8_16ObSQLSessionInfoEPNSD_12ObISQLClientEPNS0_20ObRestoreSQLModifierEbb +_ZN9oceanbase3sql18ObBasicSessionInfo19update_sys_variableENS_5share17ObSysVarClassTypeERKNS_6common8ObStringE +_ZN9oceanbase3sql18ObBasicSessionInfo15get_pc_mem_confERNS0_14ObPCMemPctConfE +_ZNK9oceanbase3sql18ObBasicSessionInfo16get_sys_variableENS_5share17ObSysVarClassTypeERl _ZN9oceanbase3sql16ObSQLSessionInfo4initEjmPNS_6common12ObIAllocatorEPKNS2_11ObTZInfoMapElm -_ZN9oceanbase6common18ObDSSessionActions4initElRNS0_12ObIAllocatorE +_ZN9oceanbase6common8ObMalloc5allocEl +_ZN9oceanbase6commonL13parse_versionEPKcPml.llvm.2495651856123774465 _ZN9oceanbase8observer20ObInnerSQLConnection17init_session_infoEPNS_3sql16ObSQLSessionInfoEbbb _ZN9oceanbase3sql18ObBasicSessionInfo21init_system_variablesEbb _ZN9oceanbase3sql18ObBasicSessionInfo17load_sys_variableERNS_6common12ObIAllocatorERKNS2_8ObStringERKNS2_5ObObjESA_SA_SA_lb _Z12ob_scan_8bitPK13ObCharsetInfoPKcS3_i _ZN9oceanbase6common9ObDFMUtil28parse_datetime_format_stringERKNS0_8ObStringERNS0_8ObIArrayINS0_9ObDFMElemEEEb _ZN9oceanbase6commonL10string_intENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_m +_ZN9oceanbase6common9ObCharset18is_valid_collationEl _Z22ob_strntoull10rnd_8bitPK13ObCharsetInfoPKcmiPPcPi +_ZN9oceanbase6common11ObObjCaster7to_typeENS0_9ObObjTypeENS0_15ObCollationTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS6_ +_ZN9oceanbase6commonL11string_uintENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_m +_ZN9oceanbase6common30common_string_unsigned_integerERKmRKNS0_9ObObjTypeERKNS0_15ObCollationTypeERKNS0_8ObStringEbRm _ZN9oceanbase6common13ObSEArrayImplINS0_9ObDFMElemELl10ENS0_19ModulePageAllocatorELb0EE9push_backERKS2_ _ZN9oceanbase5share16IsoCurrencyUtils28get_currency_by_country_nameERKNS_6common8ObStringERS3_ +_ZN9oceanbase6commonL13string_stringENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_m +_ZN9oceanbase6commonL11copy_stringERKNS0_15ObObjCastParamsENS0_9ObObjTypeEPKclRNS0_5ObObjEl +_ZN9oceanbase6common5ObObj10set_stringENS0_9ObObjTypeEPKci +_ZNK9oceanbase6common5ObObj10get_stringERNS0_8ObStringE +_ZN9oceanbase6commonL20check_convert_stringENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_ +_ZN9oceanbase6common5ObObj9deep_copyERKS1_PclRl _ZN9oceanbase3sql18ObBasicSessionInfo21gen_sys_var_in_pc_strEv _ZN9oceanbase6common19obj_print_plain_strILNS0_9ObObjTypeE5EEEiRKNS0_5ObObjEPclRlRKNS0_16ObObjPrintParamsE -_ZN9oceanbase3sql12ObSysVarInPC18serialize_sys_varsEPclRl _ZN9oceanbase6common19obj_print_plain_strILNS0_9ObObjTypeE10EEEiRKNS0_5ObObjEPclRlRKNS0_16ObObjPrintParamsE +_ZN9oceanbase3sql12ObSysVarInPC18serialize_sys_varsEPclRl _ZN9oceanbase6common13ObSEArrayImplINS0_5ObObjELl32ENS0_19ModulePageAllocatorELb0EE7reserveEl _ZN9oceanbase6common19obj_print_plain_strILNS0_9ObObjTypeE22EEEiRKNS0_5ObObjEPclRlRKNS0_16ObObjPrintParamsE -_ZN9oceanbase6common5ObObj9deep_copyERKS1_PclRl +_ZN9oceanbase6common13ObSEArrayImplINS_5share17ObSysVarClassTypeELl64ENS0_19ModulePageAllocatorELb0EE9push_backERKS3_ +_ZN9oceanbase6common28ObConfigRuntimeFilterChecker23get_runtime_filter_typeEPKcl +_ZN9oceanbase6common9ObCharset27charset_type_by_name_oracleERKNS0_8ObStringE +_ZZN9oceanbase6common28ObConfigRuntimeFilterChecker23get_runtime_filter_typeEPKclENK4$_46clERNS0_8ObStringE.llvm.8855428274855757361 +_ZN9oceanbase6commonL8int_uintENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_m _ZN9oceanbase6common11ObObjCaster7to_typeENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS5_RPS6_ +_ZN9oceanbase6common20get_length_semanticsERKNS0_8ObStringE +_ZN9oceanbase3sql18ObBasicSessionInfo25process_session_log_levelERKNS_6common5ObObjE _ZN9oceanbase6commonL13string_numberENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_m _ZN9oceanbase6common5ObObj10set_numberENS0_9ObObjTypeERKNS0_6number8ObNumberE _ZN9oceanbase6common6number8ObNumber12from_sci_optINS0_15ObObjCastParamsEEEiPKclRT_PsS9_b +_ZN9oceanbase6commonL24convert_string_collationERKNS0_8ObStringENS0_15ObCollationTypeERS1_S4_RNS0_15ObObjCastParamsE _ZN9oceanbase6common6number8ObNumber8from_v3_EPKclRNS2_10IAllocatorERiPNS1_16ObNumberFmtModelEPsSA_PKNS_3lib9ObMemAttrEb _ZN9oceanbase6common6number8ObNumber10TAllocatorINS0_15ObObjCastParamsEE5allocEl -_ZN9oceanbase6commonL24convert_string_collationERKNS0_8ObStringENS0_15ObCollationTypeERS1_S4_RNS0_15ObObjCastParamsE -_ZN9oceanbase6common9ObCharset18is_valid_collationEl -_ZN9oceanbase5share15ObVarcharSysVarC2EPFiRNS_3sql13ObExecContextERKNS0_8ObSetVarERKNS0_13ObBasicSysVarERKNS_6common5ObObjERSC_EPFiS4_S7_SA_SE_EPFiRNSB_12ObIAllocatorERKNS2_18ObBasicSessionInfoESA_SF_EPFiSL_SO_SA_RNSB_8ObStringEEPFNSB_9ObObjTypeEvE +_ZN9oceanbase6common13ObSEArrayImplINS0_5ObObjELl32ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase3sql18ObBasicSessionInfo31process_session_time_zone_valueERKNS_6common5ObObjEb +_ZNK9oceanbase6common8ObString12case_compareEPKc +_ZN9oceanbase3sql18ObBasicSessionInfo14reset_timezoneEv +_ZNK9oceanbase3sql18ObBasicSessionInfo16get_sys_variableENS_5share17ObSysVarClassTypeERNS_6common5ObObjE +_ZNK9oceanbase3sql18ObBasicSessionInfo17inner_get_sys_varENS_5share17ObSysVarClassTypeERlRPNS2_13ObBasicSysVarE +_ZN9oceanbase3omt19ObTenantTimezoneMgr13get_tenant_tzEmRNS_6common11ObTZMapWrapE _ZN9oceanbase11transaction21tx_isolation_from_strERKNS_6common8ObStringE -_ZNK9oceanbase6common8ObString12case_compareERKS1_ -_ZN9oceanbase6common13ObSEArrayImplINS0_5ObObjELl32ENS0_19ModulePageAllocatorELb0EE14internal_free_EPv -_ZNK9oceanbase3sql18ObBasicSessionInfo17get_int64_sys_varENS_5share17ObSysVarClassTypeERl -_ZN9oceanbase5share17ObLabelSeResolver26deserialize_session_labelsERKNS_6common8ObStringERNS2_8ObIArrayINS0_21ObLabelSeSessionLabelEEE -_ZN9oceanbase6common28ObConfigRuntimeFilterChecker23get_runtime_filter_typeEPKcl -_ZN9oceanbase6common6number8ObNumber15round_scale_v3_ElbbPsS3_ -_ZN9oceanbase3omt19ObTenantTimezoneMgr26get_tenant_timezone_staticEmRNS_6common11ObTZMapWrapE -_ZN9oceanbase6common9ObCharset27charset_type_by_name_oracleERKNS0_8ObStringE -_ZN9oceanbase6common13ObSEArrayImplINS0_9ObDFMElemELl10ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase3sql18ObBasicSessionInfo13switch_tenantEm +_ZN9oceanbase3sql18ObBasicSessionInfo40process_session_compatibility_mode_valueERKNS_6common5ObObjE _ZN9oceanbase5share15ObSysVarFactory19create_all_sys_varsEv _ZN9oceanbase5share11ObIntSysVarC2EPFiRNS_3sql13ObExecContextERKNS0_8ObSetVarERKNS0_13ObBasicSysVarERKNS_6common5ObObjERSC_EPFiS4_S7_SA_SE_EPFiRNSB_12ObIAllocatorERKNS2_18ObBasicSessionInfoESA_SF_EPFiSL_SO_SA_RNSB_8ObStringEEPFNSB_9ObObjTypeEvE +_ZN9oceanbase5share15ObVarcharSysVarC2EPFiRNS_3sql13ObExecContextERKNS0_8ObSetVarERKNS0_13ObBasicSysVarERKNS_6common5ObObjERSC_EPFiS4_S7_SA_SE_EPFiRNSB_12ObIAllocatorERKNS2_18ObBasicSessionInfoESA_SF_EPFiSL_SO_SA_RNSB_8ObStringEEPFNSB_9ObObjTypeEvE _ZN9oceanbase5share12ObBoolSysVarC2EPFiRNS_3sql13ObExecContextERKNS0_8ObSetVarERKNS0_13ObBasicSysVarERKNS_6common5ObObjERSC_EPFiS4_S7_SA_SE_EPFiRNSB_12ObIAllocatorERKNS2_18ObBasicSessionInfoESA_SF_EPFiSL_SO_SA_RNSB_8ObStringEEPFNSB_9ObObjTypeEvE -_ZN9oceanbase5share27ObSysVarBlockEncryptionModeC2Ev _ZN9oceanbase5share12ObEnumSysVarC2EPPKcPFiRNS_3sql13ObExecContextERKNS0_8ObSetVarERKNS0_13ObBasicSysVarERKNS_6common5ObObjERSF_EPFiS7_SA_SD_SH_EPFiRNSE_12ObIAllocatorERKNS5_18ObBasicSessionInfoESD_SI_EPFiSO_SR_SD_RNSE_8ObStringEEPFNSE_9ObObjTypeEvE -_ZN9oceanbase3sql18ObBasicSessionInfo20set_default_databaseERKNS_6common8ObStringENS2_15ObCollationTypeE -_ZN9oceanbase3sql18ObBasicSessionInfo25process_session_log_levelERKNS_6common5ObObjE +_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImPNS_2pl16ObPLPackageStateEEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE6createElPSJ_PSM_ +_ZN9oceanbase3sql18ObBasicSessionInfo26process_session_debug_syncERKNS_6common5ObObjEbb +_ZN9oceanbase6common4hash9ObHashMapINS0_8ObStringEPNS_3sql17ObInnerContextMapENS1_19NoPthreadDefendModeENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairIS3_S6_EEEELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_13NormalPointerENS0_8ObMallocELl2EE6createElRKNS_3lib7ObLabelESQ_mm +_ZN9oceanbase3sql16ObSQLSessionInfoC1Ev +_ZN9oceanbase3sql16ObSQLSessionInfoC2Ev +_ZN9oceanbase3sql20ObOptimizerTraceImplC1Ev +_ZN9oceanbase11transaction14ObTxExecResultC1Ev +_ZN9oceanbase6common17ObTimeZoneInfoPosC2Ev _ZN9oceanbase8observer15ObSqlEndTransCbC1Ev -_ZN9oceanbase6commonL13parse_versionEPKcPml.llvm.13522645359488678711 -_ZN9oceanbase3sql16ObConfigInfoInPC26load_influence_plan_configEv +_ZN9oceanbase3sql18ObBasicSessionInfo13set_time_zoneERKNS_6common8ObStringEbb +_ZN9oceanbase6common6number8ObNumber15round_scale_v3_ElbbPsS3_ +_ZN9oceanbase3sql15ObSessionValMapC2ElRKNS_6common18ObWrapperAllocatorE +_ZN9oceanbase6common15ObTimeConverter13str_to_offsetERKNS0_8ObStringERiS5_bb _ZN9oceanbase3sql18ObBasicSessionInfo4initEjmPNS_6common12ObIAllocatorEPKNS2_11ObTZInfoMapE -_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_NS_3sql17ObSessionVariableEEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS7_EENS0_17ObPooledAllocatorINS1_15ObHashTableNodeIS7_EENS0_18ObWrapperAllocatorENS0_10ObNullLockEEENS1_19NoPthreadDefendModeENS1_13NormalPointerESH_Ll1EE6createElPSJ_PSH_ -_ZN9oceanbase3sql18ObBasicSessionInfo17set_session_stateENS0_17ObSQLSessionStateE +_ZN9oceanbase3sql18ObBasicSessionInfo18set_session_state_ENS0_17ObSQLSessionStateE +_ZN9oceanbase3sql18ObBasicSessionInfo30process_session_sql_mode_valueERKNS_6common5ObObjE +_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImNS_5share15ObSequenceValueEEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS6_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS6_EELi65ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE6createElPSI_PSL_ +_ZN9oceanbase3sql20ObDblinkCtxInSessionC2EPNS0_16ObSQLSessionInfoE _ZN9oceanbase8observer24ObInnerSQLConnectionPool21add_to_used_conn_listEPNS0_20ObInnerSQLConnectionE -_ZN9oceanbase3sql18ObBasicSessionInfo11init_tenantERKNS_6common8ObStringEm -_ZN9oceanbase3sql16ObSQLSessionInfo24update_show_warnings_bufEv -_ZN9oceanbase7obmysql11ObMySQLUtil15number_cell_strEPclRKNS_6common6number8ObNumberERlsbi -_ZNK9oceanbase6common6number8ObNumber9format_v2EPclRlsb -_ZN9oceanbase6common15ObFastFormatInt15format_unsignedEmPc -_ZN9oceanbase5trace4UUID8gen_randEv -_ZZN9oceanbase4palf22BatchLogIOFlushLogTask9push_backEPNS0_17LogIOFlushLogTaskEENK5$_895clEPKc -_ZZN9oceanbase4palf11LogIOWorker25BatchLogIOFlushLogTaskMgr26find_usable_batch_io_task_ElRPNS0_22BatchLogIOFlushLogTaskEENK5$_998clEPKc -_ZN9oceanbase3sql5ObSql20handle_physical_planERKNS_6common8ObStringERNS0_8ObSqlCtxERNS0_11ObResultSetERNS0_14ObPlanCacheCtxEi -_ZN9oceanbase3sql22UDRBackupRecoveryGuardD2Ev -_ZN9oceanbase3sql5ObSql22generate_physical_planER11ParseResultPNS0_14ObPlanCacheCtxERNS0_8ObSqlCtxERNS0_11ObResultSetEbNS0_13PlanCacheModeEPS2_ -_ZNK9oceanbase6common16ObArenaAllocator5totalEv -__dynamic_cast -_ZN9oceanbase6common10ObObjStoreIPNS_3sql9ObRawExprERNS0_12ObIAllocatorELb1EEC2ES6_ -_ZN9oceanbase6common13ObSEArrayImplISt4pairIPNS_3sql9ObRawExprEPNS3_14ObConstRawExprEELl8ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase3sql10ObResolverD1Ev -_ZN9oceanbase3sql10ObResolverD2Ev -_ZN9oceanbase6common10ObObjStoreIPNS_3sql6ObStmtERNS0_12ObIAllocatorELb1EEC2ES6_ -_ZN9oceanbase3sql5ObSql16parser_and_checkERKNS_6common8ObStringERNS0_13ObExecContextERNS0_14ObPlanCacheCtxER11ParseResultiRbSC_ -_ZN9oceanbase3sql8ObParser9parse_sqlERKNS_6common8ObStringER11ParseResultb -parse_sql -obsql_mysql_yy_scan_buffer -obsql_mysql_yyensure_buffer_stack.llvm.6538719198785432131 -_ZN9oceanbase3sql5ObSql13generate_stmtER11ParseResultPNS0_14ObPlanCacheCtxERNS0_8ObSqlCtxERNS_6common12ObIAllocatorERNS0_11ObResultSetERPNS0_6ObStmtEPS2_ -_ZNK9oceanbase3sql6ObStmt19has_global_variableEv -_ZN9oceanbase3sql6ObStmt11is_dcl_stmtENS0_4stmt8StmtTypeE -_ZNK9oceanbase3sql6ObStmt11is_dml_stmtEv -_ZN9oceanbase6common11ObArrayImplIPNS_5share6schema13ObTableSchemaENS0_19ModulePageAllocatorELb1ENS0_22ObArrayDefaultCallBackIS5_EENS0_22NotImplementItemEncodeIS5_EEEC2ElRKS6_ -_ZN9oceanbase3sql16ObResolverParamsC2ERKS1_ -_ZN9oceanbase6common8ObBitSetILl256ENS0_19ModulePageAllocatorELb1EED2Ev -_ZN9oceanbase6common10ObObjStoreIPNS_3sql12ObSelectStmtERNS0_12ObIAllocatorELb1EEC2ES6_ -_ZN9oceanbase6common13ObSEArrayImplISt4pairIPNS_3sql9ObRawExprEPNS3_14ObConstRawExprEELl8ENS0_19ModulePageAllocatorELb0EE7reserveEl -_ZN9oceanbase6common8ObBitSetILl256ENS0_19ModulePageAllocatorELb1EEC2ERKS3_ -_ZN9oceanbase3sql10ObQueryCtxC2Ev -_ZN9oceanbase6common13ObSEArrayImplIjLl8ENS0_19ModulePageAllocatorELb1EE7reserveEl -_ZZN9oceanbase3sql5ObSql13generate_stmtER11ParseResultPNS0_14ObPlanCacheCtxERNS0_8ObSqlCtxERNS_6common12ObIAllocatorERNS0_11ObResultSetERPNS0_6ObStmtEPS2_ENK6$_2958clEPKc -_ZN9oceanbase3sql10ObResolver7resolveENS1_10IsPreparedERK10_ParseNodeRPNS0_6ObStmtE -_ZN9oceanbase3sql6ObStmt13is_write_stmtENS0_4stmt8StmtTypeEb -_ZN9oceanbase3sql6ObStmt11is_ddl_stmtENS0_4stmt8StmtTypeEb -_ZN9oceanbase6common10smart_freeEPv -_ZN9oceanbase3sql10ObResolver18stmt_resolver_funcINS0_20ObStartTransResolverEEEiRNS0_16ObResolverParamsERK10_ParseNodeRPNS0_6ObStmtE -_ZN9oceanbase3sql10ObResolver18stmt_resolver_funcINS0_18ObEndTransResolverEEEiRNS0_16ObResolverParamsERK10_ParseNodeRPNS0_6ObStmtE -_ZN9oceanbase3sql14ObStmtResolver9init_stmtEv -_ZN9oceanbase3sql18ObEndTransResolver7resolveERK10_ParseNode -_ZN9oceanbase3sql11ObQueryHint15add_stmt_id_mapElNS0_4stmt8StmtTypeE -_ZN9oceanbase3sql20ObStartTransResolver7resolveERK10_ParseNode -_ZN9oceanbase6common11smart_allocElPKc -_ZN9oceanbase5share6schema19ObSchemaGetterGuard23get_sys_variable_schemaEmRPKNS1_25ObSimpleSysVariableSchemaE -_ZN9oceanbase3sql15ObResolverUtils26get_stmt_type_by_item_typeE10ObItemType -_ZN9oceanbase6common16ObFixedArrayImplINS_5share6schema18ObSchemaObjVersionENS0_12ObIAllocatorEE6assignERKNS0_8ObIArrayIS4_EE -obsql_mysql_yyparse -new_non_terminal_node -merge_tree -parse_malloc -merge_child -count_child -obsql_mysql_yylex -yy_get_previous_state -mysql_non_reserved_keyword_lookup -new_terminal_node -_ZNK9oceanbase12blocksstable13ObDatumRowkey22to_multi_version_rangeERNS_6common12ObIAllocatorERNS0_12ObDatumRangeE -_ZNK9oceanbase12blocksstable13ObDatumRowkey23to_multi_version_rowkeyEbRNS_6common12ObIAllocatorERS1_ -_ZNK9oceanbase12blocksstable13ObDatumRowkey5equalERKS1_RKNS0_19ObStorageDatumUtilsERb -_ZN9oceanbase12blocksstable18ObMicroBlockReader14get_row_headerElRPKNS0_11ObRowHeaderE +_ZN9oceanbase8observer20ObInnerSQLConnection30retry_while_no_tenant_resourceIZNS1_12execute_readElmRKNS_6common8ObStringERNS3_12ObISQLClient10ReadResultEbPKNS3_6ObAddrEE5$_290EEilRKmT_.llvm.2312641008631633815 +_ZN9oceanbase6common20check_stack_overflowERblPl +_ZN9oceanbase6common13get_stackattrERPvRm +_ZN9oceanbase8observer20ObInnerSQLConnection13switch_tenantEm +_ZN9oceanbase3sql18ObBasicSessionInfo8set_userERKNS_6common8ObStringES5_m +_ZN9oceanbase6common12ObStringBufTINS0_19ModulePageAllocatorENS0_9PageArenaIcS2_EEE12write_stringERKNS0_8ObStringEPS6_ +_ZN9oceanbase6common9PageArenaIcNS0_19ModulePageAllocatorEE6_allocEl +_ZN9oceanbase6common9PageArenaIcNS0_19ModulePageAllocatorEE14alloc_new_pageEl +_ZN9oceanbase8observer16ObInnerSQLResultC1ERNS_3sql16ObSQLSessionInfoE +_ZN9oceanbase8observer16ObInnerSQLResultC2ERNS_3sql16ObSQLSessionInfoE +_ZN9oceanbase8observer20ObInnerSQLConnection5queryERNS_6common9sqlclient11ObIExecutorERNS0_16ObInnerSQLResultEPNS0_29ObVirtualTableIteratorFactoryE +_ZNSt14_Function_base13_Base_managerIZN9oceanbase5share25get_tenant_base_with_lockEmRNS1_6common10ObLDHandleERPNS2_12ObTenantBaseERSt8functionIFiS5_EEE4$_13E10_M_managerERSt9_Any_dataRKSF_St18_Manager_operation +_ZNK9oceanbase8observer20ObInnerSQLTimeRecord17get_run_timestampEv +_ZNK9oceanbase8observer20ObInnerSQLTimeRecord28get_single_process_timestampEv +_ZNK9oceanbase8observer20ObInnerSQLTimeRecord18get_send_timestampEv +_ZN9oceanbase6common16ObTotalWaitGuardC1EPNS0_15ObWaitEventStatEPNS0_21ObDiagnoseSessionInfoE +_ZN9oceanbase8observer20ObInnerSQLConnection8do_queryERNS_6common9sqlclient11ObIExecutorERNS0_16ObInnerSQLResultE +_ZNSt14_Function_baseD2Ev +_ZN9oceanbase5share19ObTenantSwitchGuard7releaseEv +_ZN9oceanbase8observer20ObInnerSQLConnection18ObSqlQueryExecutor7executeERNS_3sql5ObSqlERNS3_8ObSqlCtxERNS3_11ObResultSetE +_ZN9oceanbase8observer20ObInnerSQLConnection12TimeoutGuardD2Ev +_ZN9oceanbase8observer20ObInnerSQLConnection11set_timeoutERl +_ZN9oceanbase8observer20ObInnerSQLConnection19set_session_timeoutEll +_ZN9oceanbase3sql18ObBasicSessionInfo19update_sys_variableENS_5share17ObSysVarClassTypeERKNS_6common5ObObjE +_ZN9oceanbase6common9ObDFMUtil14check_semanticERKNS0_8ObIArrayINS0_9ObDFMElemEEERNS0_13ObFixedBitSetILl64EEEm +_ZN9oceanbase3sql18ObBasicSessionInfo22deep_copy_sys_variableERNS_5share13ObBasicSysVarENS2_17ObSysVarClassTypeERKNS_6common5ObObjE +_ZNSt14_Function_base13_Base_managerIZN9oceanbase11transaction14ObWeakReadUtil35max_stale_time_for_weak_consistencyEmlE5$_235E10_M_managerERSt9_Any_dataRKS6_St18_Manager_operation +_ZNK9oceanbase6common12ObTimeoutCtx11get_timeoutEl +_ZN9oceanbase8observer16ObInnerSQLResult4openEv +_ZN9oceanbase6common12ob_write_objINS0_9PageArenaIcNS0_19ModulePageAllocatorEEEEEiRT_RKNS0_5ObObjERS7_ +_ZN9oceanbase3sql18ObBasicSessionInfo18store_query_stringERKNS_6common8ObStringE +_ZN9oceanbase3sql18ObBasicSessionInfo19store_query_string_ERKNS_6common8ObStringE +_ZN9oceanbase5share6schema27ObMultiVersionSchemaService23get_tenant_schema_guardEmRNS1_19ObSchemaGetterGuardEllNS2_17RefreshSchemaModeE +_ZN9oceanbase5share6schema27ObMultiVersionSchemaService19add_schema_mgr_infoERNS1_19ObSchemaGetterGuardEPNS1_13ObSchemaStoreERKNS1_21ObRefreshSchemaStatusEmllNS2_17RefreshSchemaModeE +_ZN9oceanbase5share6schema17ObSchemaMgrHandle5resetEv +_ZN9oceanbase5share6schema16ObSchemaMgrCache3getElRPKNS1_11ObSchemaMgrERNS1_17ObSchemaMgrHandleE +_ZN9oceanbase8observer20ObInnerSQLConnection14process_recordERNS_3sql11ObResultSetERNS2_8ObSqlCtxERNS2_16ObSQLSessionInfoERNS0_13ObITimeRecordEillRNS_6common15ObWaitEventDescERNSB_15ObWaitEventStatERNS2_12ObExecRecordERNS2_15ObExecTimestampEbRKNSB_8ObStringEb +_ZN9oceanbase3sql17ObAuditRecordData24update_event_stage_stateEv +_ZN9oceanbase3lib6_SBaseD2Ev +_ZN9oceanbase3sql10ObSQLUtils19handle_audit_recordEbNS0_13ObExecuteModeERNS0_16ObSQLSessionInfoEb +_ZN9oceanbase3sql16ObSQLSessionInfo19get_request_managerEv +_ZN9oceanbase5share6schema27ObMultiVersionSchemaService27get_baseline_schema_versionEmbRl +_ZN9oceanbase8observer16ObInnerSQLResult4initEb +_ZN9oceanbase3lib17__MemoryContext__14create_contextIJRNS0_12ContextParamEPNS0_10StaticInfoEEEEiRNS0_13MemoryContextERKNS0_11DynamicInfoEDpOT_ +_ZN9oceanbase3sql11ObResultSetC2ERNS0_16ObSQLSessionInfoERNS_6common12ObIAllocatorE +_ZN9oceanbase8observer13ObReqTimeInfo17update_start_timeEv +_ZN9oceanbase3sql13ObExecContextC1ERNS_6common12ObIAllocatorE +_ZN9oceanbase3sql13ObExecContextC2ERNS_6common12ObIAllocatorE +_ZN9oceanbase6common9ObSEArrayINS_3sql17ObSqlTempTableCtxELl2ENS0_19ModulePageAllocatorELb0EEC2Ev +_ZN9oceanbase7obmysql21ObMySQLRequestManager14record_requestERKNS_3sql17ObAuditRecordDataEbb +_ZN9oceanbase5share6schema19ObSchemaGetterGuard17get_tenant_statusEmRNS1_14ObTenantStatusE +_ZN9oceanbase3sql12ObExecRecord12record_startEPNS_6common21ObDiagnoseSessionInfoE +_ZN9oceanbase3sql14ObPhysicalPlan16update_plan_statERKNS0_17ObAuditRecordDataEbbPKNS_6common8ObIArrayINS0_15ObTableRowCountEEE +_ZN9oceanbase3sql16ObSQLSessionInfo36refresh_temp_tables_sess_active_timeEv +_ZN9oceanbase3sql18ObBasicSessionInfo13switch_tenantEm +_ZNK9oceanbase5share16ObReplicaAttrSet27get_full_replica_attr_arrayEv +_ZN9oceanbase6common16ObArenaAllocator5allocElRKNS_3lib9ObMemAttrE +_ZN9oceanbase12blocksstableL13get_offset_16EPKvl _ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE16do_foreach_scan_INS4_25GetAllMacroBlockIdFunctorENS7_14DoForeachOnBktIS9_EEEEbmmRT_RT0_ _ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE16load_access_bkt_EmRPNS7_6BucketE _ZN9oceanbase6common11ObArrayImplINS_12blocksstable12MacroBlockIdENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ -_ZN9oceanbase3omt13ObMultiTenant4run1Ev -_ZN9oceanbase3omt8ObTenant6timeupEv -_ZN9oceanbase3omt15ObResourceGroup18check_worker_countEv -_ZN9oceanbase3omt17ObTenantConfigMgr26default_fallback_tenant_idEv -_ZNK9oceanbase3omt8ObTenant14min_worker_cntEv -_ZTWN9oceanbase3lib6Thread12is_blocking_E -_ZN9oceanbase3omt8ObTenant18update_token_usageEv -_ZN9oceanbase3omt12ObRetryQueue3popERPNS_6common6ObLinkEb -_ZN9oceanbase8observer17ObSrvNetworkFrame31reload_tenant_sql_thread_configEm -_ZN9oceanbase5share19ObTenantSwitchGuardD2Ev -_ZNSt14_Function_base13_Base_managerIZN9oceanbase5share25get_tenant_base_with_lockEmRNS1_6common10ObLDHandleERPNS2_12ObTenantBaseERSt8functionIFiS5_EEE4$_13E10_M_managerERSt9_Any_dataRKSF_St18_Manager_operation.llvm.775401640709310285 -_ZNSt17_Function_handlerIFiRN9oceanbase6common10ObLDHandleEEZNS0_5share25get_tenant_base_with_lockEmS3_RPNS5_12ObTenantBaseERSt8functionIS4_EE4$_13E9_M_invokeERKSt9_Any_dataS3_ -_ZN9oceanbase6common9ob_usleepILNS0_14ObWaitEventIds17ObWaitEventIdEnumE128EEEvj -_ZN9oceanbase8observer11QueueThread16set_thread_countEi -_ZN9oceanbase6common7ObTimer4run1Ev -_ZN9oceanbase6common15ObKVGlobalCache16KVMapReplaceTask12runTimerTaskEv -_ZN9oceanbase6common12ObBucketLock6wrlockEml -_ZN9oceanbase6common14ObTimerMonitor8end_taskEll -_ZN9oceanbase3sql26ObPlanCacheEliminationTask12runTimerTaskEv -_ZN6obutil9ObSysTime3nowENS0_5ClockE -_ZN9oceanbase7storage21ObTenantTabletStatMgr17TabletStatUpdater12runTimerTaskEv -_ZN9oceanbase6common4hash11ObHashTableINS_7storage15ObTabletStatKeyENS1_11HashMapPairIS4_PNS3_18ObTabletStreamNodeEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS8_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS8_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14get_refactoredERKS4_RS8_l -_ZN9oceanbase6common18ObBucketWLockGuardD2Ev -_ZN9oceanbase6common13ObTimeUtility19current_time_coarseEv -_ZN9oceanbase6common7ObTimer12insert_tokenERKNS1_5TokenE -_ZN9oceanbase6common14ObTimerMonitor12get_instanceEv -_ZN9oceanbase12blocksstable14ObBlockManager19InspectBadBlockTask12runTimerTaskEv -_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE7do_get_ERKS3_RS5_ -_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE16load_access_bkt_ERKS3_RmRPNS7_6BucketE -_ZN9oceanbase4palf16BlockGCTimerTask12runTimerTaskEv -_ZNK6obutil9ObMonitorINS_11ObUtilMutexEE6unlockEv -_ZN9oceanbase6common15ObKVGlobalCache15KVStoreWashTask12runTimerTaskEv -_ZN9oceanbase6common12ObKVCacheMap18clean_garbage_nodeERll -_ZN9oceanbase3omt19ObTenantTimezoneMgr18UpdateTenantTZTask12runTimerTaskEv -_ZN9oceanbase3sql19ObDumpAllCacheObjOpclERNS_6common4hash11HashMapPairImPNS0_17ObILibCacheObjectEEE -_ZNK9oceanbase3sql25ObDumpAllCacheObjByTypeOp11should_dumpEPNS0_17ObILibCacheObjectE -_ZN9oceanbase6common11ObArrayImplINS_3sql17AllocCacheObjInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ -_ZN9oceanbase6common11ObArrayImplINS_3sql17AllocCacheObjInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE10extend_bufEl -_ZN9oceanbase4palf11PalfEnvImpl18try_recycle_blocksEv -_ZNK9oceanbase4palf14PalfHandleImpl25get_total_used_disk_spaceEv -_ZNK9oceanbase4palf14PalfHandleImpl11get_end_lsnEv -_ZNK9oceanbase4palf14PalfHandleImpl12get_base_lsnERNS0_3LSNE -_ZNK9oceanbase4palf9LogEngine30get_base_lsn_used_for_block_gcEv -_ZN9oceanbase4palf11PalfEnvImpl15get_disk_usage_ERlS2_S2_S2_ -_ZNK9oceanbase4palf9LogEngine25get_total_used_disk_spaceERl -_ZNK9oceanbase4palf11LogBlockMgr18get_block_id_rangeERmS2_ -_ZNK9oceanbase4palf10LogStorage11get_end_lsnEv -_ZZN9oceanbase4palf18LogIOWorkerWrapper30notify_need_writing_throttlingERKbENK6$_1544clEPKc -_ZZNK9oceanbase4palf9LogEngine25get_total_used_disk_spaceERlENK5$_646clEPKc -_ZN9oceanbase4palf10LogUpdater12runTimerTaskEv -_ZN9oceanbase4palf11PalfEnvImpl8for_eachERKNS_6common10ObFunctionIFiPNS0_15IPalfHandleImplEEEE -_ZZN9oceanbase7obmysql15ObEliminateTask12runTimerTaskEvENK4$_33clEPKc -_ZN9oceanbase3omt11ObTenantSrs27TenantSrsUpdatePeriodicTask12runTimerTaskEv -_ZN9oceanbase6common16ObKVCacheInstMap13refresh_scoreEv -_ZN9oceanbase7storage18ObTenantMetaMemMgr21MinMinorSSTableGCTask12runTimerTaskEv -_ZN9oceanbase6common4hash24ObHashTableConstIteratorINS_7storage18ObTenantMetaMemMgr19MinMinorSSTableInfoENS1_11HashMapPairIS5_NS1_11HashNullObjEEENS1_9hash_funcIS5_EENS1_8equal_toIS5_EENS1_10pair_firstIS8_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS8_EELi58ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EEppEv -_ZN9oceanbase6common4hash11ObHashTableINS_7storage18ObTenantMetaMemMgr19MinMinorSSTableInfoENS1_11HashMapPairIS5_NS1_11HashNullObjEEENS1_9hash_funcIS5_EENS1_8equal_toIS5_EENS1_10pair_firstIS8_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS8_EELi58ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE5beginEv -_ZN9oceanbase3omt14ObTenantSrsMgr16DeleteTenantTask12runTimerTaskEv -_ZN9oceanbase4palf14PalfHandleImpl22check_and_switch_stateEv -_ZN9oceanbase4palf11LogStateMgr16is_state_changedEv -_ZN9oceanbase4palf12LogConfigMgr19leader_do_loop_workERb -_ZN9oceanbase6common14ObKVCacheStore24compute_tenant_wash_sizeEv -_ZN9oceanbase6common16ObKVCacheInstMap14get_cache_infoEmRNS0_8ObIArrayINS0_19ObKVCacheInstHandleEEE -_ZN9oceanbase6common16ObKVCacheInstMap22inner_push_inst_handleERKNS0_4hash19ObHashTableIteratorINS0_16ObKVCacheInstKeyENS2_11HashMapPairIS4_PNS0_13ObKVCacheInstEEENS2_9hash_funcIS4_EENS2_8equal_toIS4_EENS2_10pair_firstIS8_EENS2_13SimpleAllocerINS2_15ObHashTableNodeIS8_EELi98ENS2_19SpinMutexDefendModeENS2_29DefaultSimpleAllocerAllocatorEEENS2_19NoPthreadDefendModeENS2_13NormalPointerENS0_8ObMallocELl1EEERNS0_8ObIArrayINS0_19ObKVCacheInstHandleEEE -_ZN9oceanbase6common16ObFixedArrayImplINS0_19ObKVCacheInstHandleENS0_16ObArenaAllocatorEE9push_backERKS2_ -_ZN9oceanbase3sql9ObPsCache17inner_cache_evictEb -_ZN9oceanbase5share30ObDumpLSLocationCacheTimerTask12runTimerTaskEv -_ZN9oceanbase4palf12LogConfigMgr21check_children_healthEv -_ZN9oceanbase7storage13ObResourceMapINS0_14ObTabletMapKeyENS0_13ObMetaPointerINS0_8ObTabletEEEE3getINS0_25ObResourceDefaultCallbackIS2_S5_EEEEiRKS2_RNS0_16ObResourceHandleIS5_EET_ -_ZN9oceanbase7storage13ObResourceMapINS0_14ObTabletMapKeyENS0_13ObMetaPointerINS0_8ObTabletEEEE16get_without_lockINS0_25ObResourceDefaultCallbackIS2_S5_EEEEiRKS2_RNS0_16ObResourceHandleIS5_EET_ -_ZN9oceanbase3sql17ObSqlTransControl18implicit_end_transERNS0_13ObExecContextEbPNS0_23ObEndTransAsyncCallbackE -_ZZN9oceanbase3sql11ObPlanCache13get_cache_objERNS0_14ObILibCacheCtxEPNS0_14ObILibCacheKeyERNS0_15ObCacheObjGuardEENK5$_198clEPKc.llvm.2638051417269291142 -pthread_mutex_lock -_ZNK9oceanbase5share6schema16ObSchemaCacheKeyeqERKNS_6common13ObIKVCacheKeyE +_ZN9oceanbase6common11ObArrayImplINS_12blocksstable12MacroBlockIdENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE10extend_bufEl +_ZTHN9oceanbase6common5occam20ObThreadHungDetector15click_point_idxE +_ZNSt17_Function_handlerIFiPN9oceanbase3lib17ObTenantMemoryMgrEEZNS1_17ObMallocAllocator15get_tenant_holdEmE4$_54E9_M_invokeERKSt9_Any_dataOS3_.llvm.7346562358563844286 +_ZZN9oceanbase4palf11LogIOWorker25BatchLogIOFlushLogTaskMgr26find_usable_batch_io_task_ElRPNS0_22BatchLogIOFlushLogTaskEENK6$_1015clEPKc +_ZN9oceanbase5share21ObSyslogPerErrLimiter13RefreshThread4run1Ev +_ZN9oceanbase10rootserver18ObPartitionBalance7destroyEv +_ZN9oceanbase6common4hash11ObHashTableINS0_10ObTabletIDENS1_11HashMapPairIS3_NS_5share6ObLSIDEEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv +_ZN9oceanbase6common4hash11ObHashTableINS_10rootserver14ObBalanceGroupENS1_11HashMapPairIS4_NS0_7ObArrayIPNS3_18ObPartitionBalance17ObLSPartGroupDescENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS9_EENS0_22NotImplementItemEncodeIS9_EEEEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstISG_EENS1_13SimpleAllocerINS1_15ObHashTableNodeISG_EELi11ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv +_ZN9oceanbase6common4hash11ObHashTableINS0_10ObTabletIDENS1_11HashMapPairIS3_mEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv +_ZN9oceanbase6common4hash11ObHashTableINS_10rootserver18ObPartitionBalance17ObTransferTaskKeyENS1_11HashMapPairIS5_NS_5share13ObDisplayListINS7_18ObTransferPartInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS9_EENS0_22NotImplementItemEncodeIS9_EEEEEENS1_9hash_funcIS5_EENS1_8equal_toIS5_EENS1_10pair_firstISG_EENS1_13SimpleAllocerINS1_15ObHashTableNodeISG_EELi44ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv +_ZN9oceanbase7storage18ObTenantMetaMemMgr21get_tablet_ddl_kv_mgrERKNS0_14ObTabletMapKeyERNS0_14ObMetaObjGuardINS0_16ObTabletDDLKvMgrEEE +_ZN9oceanbase7storage15ObTabletPointer14get_ddl_kv_mgrERNS0_14ObMetaObjGuardINS0_16ObTabletDDLKvMgrEEE +_ZN9oceanbase7storage13ObResourceMapINS0_14ObTabletMapKeyENS0_13ObMetaPointerINS0_8ObTabletEEEE3getERKS2_RNS0_16ObResourceHandleIS5_EE +_ZN9oceanbase7storage14ObMetaObjGuardINS0_16ObTabletDDLKvMgrEEaSERKS3_ +_ZN9oceanbase7storage14ObMetaObjGuardINS0_16ObTabletDDLKvMgrEE9reset_objEv _ZN9oceanbase4palf11LogIOWorker9run_loop_Ev -_ZN9oceanbase4palf20IPalfHandleImplGuardD1Ev -_ZN9oceanbase4palf20IPalfHandleImplGuardD2Ev -_ZZN9oceanbase4palf14PalfHandleImpl17advance_reuse_lsnERKNS0_3LSNEENK6$_1301clEPKc _ZN9oceanbase4palf14PalfHandleImpl17advance_reuse_lsnERKNS0_3LSNE _ZN9oceanbase4palf14PalfHandleImpl16inner_append_logERKNS_6common12ObFixedArrayINS0_3LSNENS2_12ObIAllocatorEEERKNS3_IPNS0_11LogWriteBufES5_EERKNS3_INS_5share3SCNES5_EE -_ZNK9oceanbase4palf11LogWriteBuf14get_total_sizeEv -_ZN9oceanbase6common16ObFixedArrayImplIPNS_4palf17LogIOFlushLogTaskENS0_12ObIAllocatorEE9push_backERKS4_ _ZN9oceanbase4palf10LogStorage6writevERKNS_6common12ObFixedArrayINS0_3LSNENS2_12ObIAllocatorEEERKNS3_IPNS0_11LogWriteBufES5_EERKNS3_INS_5share3SCNES5_EE -_ZN9oceanbase6common13ObSEArrayImplINS_4palf11LogWriteBuf11InnerStructELl2ENS0_19ModulePageAllocatorELb0EEixEl -_ZZN9oceanbase4palf16LogSlidingWindow17advance_reuse_lsnERKNS0_3LSNEENK5$_481clEPKc _ZN9oceanbase6common16ObFixedArrayImplINS_5share3SCNENS0_12ObIAllocatorEE9push_backERKS3_ +_ZZN9oceanbase4palf16LogSlidingWindow17advance_reuse_lsnERKNS0_3LSNEENK5$_481clEPKc.llvm.447907550136452219 +_ZN9oceanbase6common16ObFixedArrayImplIPNS_4palf17LogIOFlushLogTaskENS0_12ObIAllocatorEE9push_backERKS4_ +_ZN9oceanbase6common16ObFixedArrayImplINS_4palf3LSNENS0_12ObIAllocatorEE9push_backERKS3_ +_ZN9oceanbase6common16ObFixedArrayImplIPNS_4palf11LogWriteBufENS0_12ObIAllocatorEE9push_backERKS4_ +_ZZN9oceanbase4palf11LogWriteBuf5mergeERKS1_RbENK5$_673clEPKc +_ZZN9oceanbase4palf22BatchLogIOFlushLogTask9push_backEPNS0_17LogIOFlushLogTaskEENK5$_912clEPKc _ZN9oceanbase4palf10LogStorage6writevERKNS0_3LSNERKNS0_11LogWriteBufERKNS_5share3SCNE _ZN9oceanbase4palf11LogBlockMgr6writevEmmRKNS0_11LogWriteBufE _ZN9oceanbase4palf15LogBlockHandler17inner_write_once_EmPKcl _ZN9oceanbase4palf16LogDIOAlignedBuf9align_bufEPKclRPcRlRm +_ZZN9oceanbase4palf15LogBlockHandler6writevEmRKNS0_11LogWriteBufEENK4$_82clEPKc _ZZN9oceanbase4palf16LogDIOAlignedBuf12truncate_bufEvENK4$_63clEPKc +_ZZN9oceanbase4palf14PalfHandleImpl17advance_reuse_lsnERKNS0_3LSNEENK6$_1314clEPKc.llvm.447907550136452219 _ZZN9oceanbase4palf11LogBlockMgr6writevEmmRKNS0_11LogWriteBufEENK5$_118clEPKc _ZN9oceanbase4palf29push_task_into_cb_thread_poolElPNS0_9LogIOTaskE -_ZZN9oceanbase4palf15LogBlockHandler6writevEmRKNS0_11LogWriteBufEENK4$_82clEPKc -_ZN9oceanbase6common16ObFixedArrayImplINS_4palf3LSNENS0_12ObIAllocatorEE9push_backERKS3_ _ZZN9oceanbase4palf10LogStorage6writevERKNS_6common12ObFixedArrayINS0_3LSNENS2_12ObIAllocatorEEERKNS3_IPNS0_11LogWriteBufES5_EERKNS3_INS_5share3SCNES5_EEENK5$_583clEPKc -_ZZN9oceanbase4palf11LogWriteBuf5mergeERKS1_RbENK5$_671clEPKc -_ZN9oceanbase6common16ObFixedArrayImplIPNS_4palf11LogWriteBufENS0_12ObIAllocatorEE9push_backERKS4_ _ZN9oceanbase4palf18LogWritingThrottle25update_throttling_optionsEPNS0_12IPalfEnvImplE _ZZN9oceanbase4palf10LogStorage6writevERKNS0_3LSNERKNS0_11LogWriteBufERKNS_5share3SCNEENK5$_576clEPKc -_ZZN9oceanbase4palf14LogGroupBuffer20inc_update_reuse_lsnERKNS0_3LSNEENK5$_770clEPKc.llvm.1832557561412309455 -_ZN9oceanbase4palf18LogWritingThrottle25update_throtting_options_EPNS0_12IPalfEnvImplERb -_ZN9oceanbase5share21ObSyslogPerErrLimiter13RefreshThread4run1Ev -_ZNK9oceanbase4palf14PalfHandleImpl11get_end_scnEv -_ZNK6obutil9ObMonitorINS_11ObUtilMutexEE10timed_waitERKNS_9ObSysTimeE -_ZNK9oceanbase3lib20ObTenantCtxAllocator8get_holdEv -_ZNSt14_Function_base13_Base_managerIZNK9oceanbase3lib20ObTenantCtxAllocator8get_holdEvEUlPKNS2_17ObTenantMemoryMgrEE_E10_M_managerERSt9_Any_dataRKS9_St18_Manager_operation -_ZZN9oceanbase4palf11LogIOWorker15reduce_io_task_EPvENK5$_984clEPKc -_ZN9oceanbase12blocksstable22ObIndexBlockRowScanner15check_blockscanERKNS0_13ObDatumRowkeyERb -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE16ObIntraPartitionD2Ev -_ZN9oceanbase3sql16ObHashDistinctOp11inner_closeEv -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE5resetEv -_ZN9oceanbase6common9Ob2DArrayIPNS_3sql14ObHashPartColsELi65408ENS0_19ModulePageAllocatorELb0ENS0_9ObSEArrayIPS4_Ll64ES5_Lb0EEEE7destroyEv -_ZN9oceanbase3sql24ObTenantSqlMemoryManager28unregister_work_area_profileERNS0_20ObSqlWorkAreaProfileE -_ZZN9oceanbase3sql16ObHashDistinctOp5resetEvENK5$_621clEPKc -_ZN9oceanbase6common13ObLinkHashMapINS_3sql14SessionInfoKeyENS2_16ObSQLSessionInfoENS2_15ObSQLSessionMgr10ValueAllocENS0_9RefHandleELl8EE6revertEPS4_ +_ZZN9oceanbase4palf14LogGroupBuffer20inc_update_reuse_lsnERKNS0_3LSNEENK5$_787clEPKc.llvm.838520973738826390 +_ZN9oceanbase3sql5ObSql20handle_physical_planERKNS_6common8ObStringERNS0_8ObSqlCtxERNS0_11ObResultSetERNS0_14ObPlanCacheCtxEi +_ZN9oceanbase6common11to_hex_cstrEPKvlPclRlS4_ +_ZN9oceanbase3sql16ObPrivilegeCheck22check_password_expiredERKNS0_8ObSqlCtxENS0_4stmt8StmtTypeE +_ZN9oceanbase6common16ObFixedArrayImplINS_5share6schema13ObOraNeedPrivENS0_12ObIAllocatorEED2Ev +_ZN9oceanbase5share6schema18ObStmtOraNeedPrivsD2Ev +_ZN9oceanbase3sql5ObSql22generate_physical_planER11ParseResultPNS0_14ObPlanCacheCtxERNS0_8ObSqlCtxERNS0_11ObResultSetEbNS0_13PlanCacheModeEPS2_ +_ZN9oceanbase5share6schema15ObStmtNeedPrivsD2Ev +_ZN9oceanbase3sql16ObRawExprFactoryC2ERNS_6common12ObIAllocatorE +_ZN9oceanbase3sql5ObSql16parser_and_checkERKNS_6common8ObStringERNS0_13ObExecContextERNS0_14ObPlanCacheCtxER11ParseResultiRbSC_ +_ZN9oceanbase3sql8ObParser5parseERKNS_6common8ObStringER11ParseResult9ParseModebbb +_ZN9oceanbase3sql5ObSql13generate_stmtER11ParseResultPNS0_14ObPlanCacheCtxERNS0_8ObSqlCtxERNS_6common12ObIAllocatorERNS0_11ObResultSetERPNS0_6ObStmtEPS2_ +_ZNK9oceanbase3sql6ObStmt19has_global_variableEv +_ZNK9oceanbase3sql6ObStmt11is_dml_stmtEv +_ZN9oceanbase3sql6ObStmt17is_dml_write_stmtENS0_4stmt8StmtTypeE +_ZN9oceanbase3sql6ObStmt11is_ddl_stmtENS0_4stmt8StmtTypeEb +_ZN9oceanbase3sql10ObQueryCtxC2Ev +_ZN9oceanbase3sql12ObGlobalHint5resetEv +_ZN9oceanbase3sql16ObResolverParamsC2ERKS1_ +_ZN9oceanbase6common8ObBitSetILl256ENS0_19ModulePageAllocatorELb1EEC2ERKS3_ +_ZN9oceanbase3sql10ObResolverD1Ev +_ZN9oceanbase3sql10ObResolverD2Ev +_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_lEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE5clearEv +_ZN9oceanbase3sql13ObExecContext16get_stmt_factoryEv +_ZZN9oceanbase3sql5ObSql13generate_stmtER11ParseResultPNS0_14ObPlanCacheCtxERNS0_8ObSqlCtxERNS_6common12ObIAllocatorERNS0_11ObResultSetERPNS0_6ObStmtEPS2_ENK6$_2958clEPKc +_ZN9oceanbase3sql10ObUDRUtils24match_udr_and_refill_ctxERKNS_6common8ObStringERNS0_8ObSqlCtxERNS0_11ObResultSetERNS0_14ObPlanCacheCtxERbRNS0_12ObUDRItemMgr14UDRRefObjGuardINS0_9ObUDRItemEEE +_ZN9oceanbase3sql15ObResolverUtils26get_stmt_type_by_item_typeE10ObItemType +_ZN9oceanbase6common4hash9ObHashMapImmNS1_24LatchReadWriteDefendModeENS1_9hash_funcImEENS1_8equal_toImEENS1_13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairImmEEEELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_13NormalPointerENS0_8ObMallocELl1EE5clearEv +_ZN9oceanbase3sql8ObParser9parse_sqlERKNS_6common8ObStringER11ParseResultb +parse_sql +obsql_mysql_yy_scan_buffer +_ZN9oceanbase3sql10ObResolver7resolveENS1_10IsPreparedERK10_ParseNodeRPNS0_6ObStmtE +_ZN9oceanbase3sql14ObStmtResolver9init_stmtEv +_ZN9oceanbase3sql6ObStmt11is_dcl_stmtENS0_4stmt8StmtTypeE +_ZN9oceanbase6common10smart_freeEPv +_ZN9oceanbase3sql18ObEndTransResolver7resolveERK10_ParseNode +_ZN9oceanbase3sql20ObStartTransResolver7resolveERK10_ParseNode +_ZN9oceanbase3sql11ObQueryHint15add_stmt_id_mapElNS0_4stmt8StmtTypeE +_ZN9oceanbase6common11smart_allocElPKc +_ZN9oceanbase6common11ObAllocator5allocElRKNS_3lib9ObMemAttrE +_ZN9oceanbase5share6schema19ObSchemaGetterGuard23get_sys_variable_schemaEmRPKNS1_25ObSimpleSysVariableSchemaE +_ZNK9oceanbase5share6schema16ObSysVariableMgr23get_sys_variable_schemaEmRPKNS1_25ObSimpleSysVariableSchemaE +obsql_mysql_yyparse +new_non_terminal_node +merge_tree +obsql_mysql_yylex +yy_get_previous_state +_ZN9oceanbase8memtable13ObLockWaitMgr4run1Ev +_ZN9oceanbase6common10FixedHash2INS_3rpc14ObLockWaitNodeEE10quick_nextEPS3_ +_ZNK9oceanbase7storage15ObStorageSchema27get_progressive_merge_roundEv +_ZNK9oceanbase7storage15ObTableReadInfo19get_trans_col_indexEv _ZN9oceanbase10logservice20ObArbitrationService4run1Ev _ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE20unset_foreach_L_lmt_Em +_ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE18set_foreach_L_lmt_Ev +_ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE16do_foreach_scan_INS5_20ObArbitrationService16DoUpgradeFunctorENSA_14DoForeachOnBktISD_EEEEbmmRT_RT0_ _ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE16do_foreach_scan_INS5_20ObArbitrationService16DoDegradeFunctorENSA_14DoForeachOnBktISD_EEEEbmmRT_RT0_ _ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE16load_access_bkt_EmRPNSA_6BucketE _ZN9oceanbase4palf11PalfEnvImpl8for_eachERKNS_6common10ObFunctionIFiRKNS0_10PalfHandleEEEE _ZN9oceanbase6common13ObLinkHashMapINS_4palf5LSKeyENS2_15IPalfHandleImplENS2_19PalfHandleImplAllocENS0_9RefHandleELl8EE4nextEPNS0_12LinkHashNodeIS3_EE +_ZNK9oceanbase4palf14PalfHandleImpl11get_palf_idERl +_ZN9oceanbase6common13ObLinkHashMapINS_4palf5LSKeyENS2_15IPalfHandleImplENS2_19PalfHandleImplAllocENS0_9RefHandleELl8EE11try_inc_refEPNS0_12LinkHashNodeIS3_EE +_ZZZN9oceanbase10logservice20ObArbitrationService21get_server_sync_info_EvENK5$_710clERKNS_4palf10PalfHandleEENKUlPKcE2_clES8_ _ZN9oceanbase10logservice20ObArbitrationService16DoUpgradeFunctorD2Ev -_ZZZN9oceanbase10logservice20ObArbitrationService21get_server_sync_info_EvENK5$_687clERKNS_4palf10PalfHandleEENKUlPKcE2_clES8_ -_ZNK9oceanbase6common10ObFunctionIFiRKNS_4palf10PalfHandleEEE7DerivedIZNS_10logservice20ObArbitrationService21get_server_sync_info_EvE5$_687E6invokeES5_$cc7da69946f527619e883ba5ebf5fc09 -_ZNK9oceanbase4palf12LogConfigMgr20get_curr_member_listERNS_6common16ObMemberListBaseILl7EEERl +_ZNK9oceanbase6common10ObFunctionIFiRKNS_4palf10PalfHandleEEE7DerivedIZNS_10logservice20ObArbitrationService21get_server_sync_info_EvE5$_710E6invokeES5_$c4b1dd24eae1c19b224a06eff3f4063d _ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE7do_get_ERKS3_RS8_ +_ZNK9oceanbase4palf14PalfHandleImpl21get_paxos_member_listERNS_6common16ObMemberListBaseILl7EEERl +_ZN9oceanbase6common8TCRWLock10RLockGuardD2Ev _ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE16load_access_bkt_ERKS3_RmRPNSA_6BucketE -_ZNK9oceanbase4palf13LogConfigInfo29get_expected_paxos_memberlistERNS_6common16ObMemberListBaseILl7EEERl +_ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE17load_factor_ctrl_Em _ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE7shrink_Ev _ZNK9oceanbase4palf14PalfHandleImpl18get_ack_info_arrayERNS_6common9ObSEArrayINS0_16LogMemberAckInfoELl7ENS2_19ModulePageAllocatorELb0EEERNS2_15BaseLearnerListILl2000ENS2_8ObMemberEEE -_ZNK9oceanbase4palf14PalfHandleImpl11get_palf_idERl -_ZN9oceanbase6common15ObLinearHashMapINS_4palf5LSKeyENS0_9ObSEArrayINS_10logservice15LogMemberStatusELl7ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE17load_factor_ctrl_Em -_ZN9oceanbase6common10ObFunctionIFvvEE7DerivedIZNS0_5occam17ObOccamThreadPool11commit_taskILNS5_13TASK_PRIORITYE1ERNS5_16ObOccamTimerTask11TaskWrapperEJEEEiRNS0_8ObFutureINSt9result_ofIFT0_DpT1_EE4typeEEEOSE_DpOSF_EUlvE_EC2IRKSP_EEOT_ -_ZN9oceanbase6common24KVCacheHazardThreadStore6retireEmm -_ZNK9oceanbase4palf14PalfHandleImpl11get_max_scnEv -_ZN9oceanbase6common4hash11ObHashTableINS0_6ObAddrENS1_12ObReferedMapIS3_NS_10rootserver16DRServerStatInfoEE4ItemENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS8_6GetKeyENS1_13SimpleAllocerINS1_15ObHashTableNodeIS8_EELi76ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv -_ZN9oceanbase6common19GlobalHazardVersion11delete_nodeEPNS0_17KVCacheHazardNodeE -_ZN9oceanbase3lib12SubObjectMgr10free_blockEPNS0_6ABlockE -_ZN9oceanbase11transaction19ObTsSourceInfoGuardD2Ev -_ZNK9oceanbase5share6schema18ObTableSchemaParam21get_rowkey_column_idsERNS_6common8ObIArrayImEE +_ZNK9oceanbase4palf13LogConfigInfo29get_expected_paxos_memberlistERNS_6common16ObMemberListBaseILl7EEERl +_ZNK9oceanbase6common10ObFunctionIFiRKNS_4palf10PalfHandleEEE7DerivedIZNS_8observer20ObAllVirtualPalfStat18inner_get_next_rowERPNS0_8ObNewRowEE5$_454E6invokeES5_$9ff4fdcdb675cbd01c54d9e38a84670b +_ZN9oceanbase4palf8PalfStatC1Ev +_ZN9oceanbase4palf14PalfHandleImpl4statERNS0_8PalfStatE +_ZNK9oceanbase4palf12LogConfigMgr23get_global_learner_listERNS_6common15BaseLearnerListILl2000ENS2_8ObMemberEEE +_ZNK9oceanbase4palf12LogConfigMgr25get_degraded_learner_listERNS_6common15BaseLearnerListILl2000ENS2_8ObMemberEEE +_ZN9oceanbase6common13ObSEArrayImplINS0_8ObMemberELl7ENS0_19ModulePageAllocatorELb0EE7destroyEv +_ZNK9oceanbase4palf9LogEngine18get_min_block_infoERmRNS_5share3SCNE +_ZNK9oceanbase12blocksstable17ObFuseRowCacheKey4sizeEv +_ZN9oceanbase6common5occam16ObOccamTimerTask9begin_runEv +_ZN9oceanbase5obrpc18ObRpcProcessorBase8responseEi +_ZN9oceanbase3lib9SetLockerINS0_7ObMutexEE4lockEv _ZN9oceanbase3lib20ObTenantCtxAllocator10free_chunkEPNS0_6AChunkERKNS0_9ObMemAttrE _ZN9oceanbase3lib17ObTenantMemoryMgr10free_chunkEPNS0_6AChunkERKNS0_9ObMemAttrE -_ZN9oceanbase3lib17ObTenantMemoryMgr11update_holdElmRKNS0_7ObLabelERb -_ZN9oceanbase3lib9AChunkMgr10free_chunkEPNS0_6AChunkE -_ZN9oceanbase3sql13AllocOpHelperILi12EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE -_ZN9oceanbase3sql16ObHashDistinctOpC1ERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputE -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEEC2Ev -_ZNSt17_Function_handlerIFiPN9oceanbase3lib17ObTenantMemoryMgrEEZNS1_17ObMallocAllocator15get_tenant_holdEmE4$_53E9_M_invokeERKSt9_Any_dataOS3_.llvm.12858094529141013191 -_ZN9oceanbase11transaction14ObTxLoopWorker4run1Ev -_ZN9oceanbase11transaction12ObLSTxCtxMgr22check_scheduler_statusERNS_5share3SCNERNS0_17MinStartScnStatusE -_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_10ObTransCtxENS0_13TransCtxAllocENS_6common10SpinRWLockELl16384EE19generate_value_arr_ElRNS5_9ObSEArrayIPS3_Ll32ENS5_19ModulePageAllocatorELb0EEE -_ZN9oceanbase11transaction39IteratePartCtxAskSchedulerStatusFunctorclEPNS0_10ObTransCtxE -_ZN9oceanbase11transaction14ObPartTransCtx22check_scheduler_statusEv -_ZNK9oceanbase11transaction16ObTxKeepaliveMsg8is_validEv -_ZNK9oceanbase10logservice15ObLogBaseHeader9serializeEPclRl -_ZN9oceanbase11transaction10ObTransRpc5post_ERKNS_6common6ObAddrERNS0_7ObTxMsgE -_ZN9oceanbase5obrpc15ObTransRpcProxy20post_keep_alive_msg_ERKNS_11transaction16ObTxKeepaliveMsgEPNS0_10ObRpcProxy7AsyncCBINS1_5ObRpcILNS0_15ObRpcPacketCodeE1626EvEEEERKNS0_9ObRpcOptsE -_ZN9oceanbase5obrpc15ObPocClientStub4postINS_11transaction20ObTxKeepaliveRespMsgENS0_10ObRpcProxy7AsyncCBINS0_15ObTransRpcProxy5ObRpcILNS0_15ObRpcPacketCodeE1628EvEEEEEEiRS5_RKNS_6common6ObAddrES9_RKT_PT0_RKNS0_9ObRpcOptsE -pn_send -cfifo_alloc -_ZN9oceanbase5obrpc18fill_extra_payloadERNS0_11ObRpcPacketEPcll -_ZNK9oceanbase5trace4UUID9serializeEPclRl -_ZNK9oceanbase3lib16ObRuntimeContext9serializeEPclRl -_ZNK9oceanbase11transaction20ObTxKeepaliveRespMsg9serializeEPclRl -_ZNK9oceanbase11transaction7ObTxMsg19get_serialize_size_Ev -_ZN9oceanbase5obrpc15ObTransRpcProxy24post_keep_alive_resp_msgERKNS_11transaction20ObTxKeepaliveRespMsgEPNS0_10ObRpcProxy7AsyncCBINS1_5ObRpcILNS0_15ObRpcPacketCodeE1628EvEEEERKNS0_9ObRpcOptsE -_ZN9oceanbase7storage19ObTablesHandleArray5resetEv -_ZN9oceanbase6common13TimeWheelBase4run1Ev -_ZN9oceanbase6common16ObClockGenerator6usleepEl -_ZNK6obutil4Cond15timed_wait_implINS_11ObUtilMutexEEEbRKT_RKNS_9ObSysTimeE -_ZN9oceanbase3lib11ObLockGuardINS_6common10ObSpinLockEEC2ERS3_ -_ZN9oceanbase6common5occam16ObOccamTimerTask12runTimerTaskEv -_ZN9oceanbase6common5occam16ObOccamTimeGuard5clickEt -_ZN9oceanbase6common5occam16ObOccamTimerTask27commit_task_to_thread_pool_Ev -_ZN9oceanbase6common5occam16ObOccamTimeGuardD2Ev -_ZNK9oceanbase6common6future12ObFutureBaseIbE3getERPb -_ZN9oceanbase6common11ObTimeWheel8scheduleEPNS0_15ObTimeWheelTaskEl -_ZN9oceanbase6common11ObWeakGuardINS0_10ObFunctionIFbvEEEED2Ev -_ZN9oceanbase6common12ObThreadCond6signalEv -_ZN9oceanbase6common13TimeWheelBase8scheduleEPNS0_15ObTimeWheelTaskEl -_ZN9oceanbase6common10murmurhashEPKvim -_ZN9oceanbase6common5occam17ObOccamThreadPool11commit_taskILNS1_13TASK_PRIORITYE1ERNS1_16ObOccamTimerTask11TaskWrapperEJEEEiRNS0_8ObFutureINSt9result_ofIFT0_DpT1_EE4typeEEEOSA_DpOSB_ -_ZN9oceanbase6common13ObSharedGuardINS0_6future12ObFutureBaseIbE11FutureBlockEED2Ev -_ZN9oceanbase3lib11ObLockGuardINS_6common12ObThreadCondEEC2ERS3_ -_ZN9oceanbase6common8function24DefaultFunctionAllocator4freeEPv -_ZNK9oceanbase6common9ObPromiseIbE10get_futureEv -_ZN9oceanbase6common6future12ObFutureBaseIbE4initERNS0_12ObIAllocatorE -_ZN9oceanbase6common6future22DefaultFutureAllocator5allocEl -_ZN9oceanbase6common10ObFunctionIFvvEE6assignIZNS0_5occam17ObOccamThreadPool11commit_taskILNS5_13TASK_PRIORITYE1ERNS5_16ObOccamTimerTask11TaskWrapperEJEEEiRNS0_8ObFutureINSt9result_ofIFT0_DpT1_EE4typeEEEOSE_DpOSF_EUlvE_Lb1EEEiOT_ -_ZN9oceanbase6common6future12ObFutureBaseIbEaSEOS3_ -_ZNK9oceanbase6common6future16ObFutureBaseBase8is_readyEv -_ZNK9oceanbase6common6future16ObFutureBaseBase4waitEv -_ZN9oceanbase3lib11ObLockGuardINS_6common12ObThreadCondEED2Ev -_ZZN9oceanbase3sql16ObHashDistinctOp10inner_openEvENK5$_619clEPKc -trace_cache_buckets -_ZN9oceanbase5share8detector22ObLCLBatchSenderThread4run1Ev -_ZN9oceanbase6common15ObLinearHashMapINS_5share8detector20ObDependencyResourceENS3_12ObLCLMessageENS0_14ShareMemMgrTagEE16do_foreach_scan_INS3_22ObLCLBatchSenderThread10RemoveIfOpENS7_15DoRemoveIfOnBktISA_EEEEbmmRT_RT0_ -_ZN9oceanbase6common11ObArrayImplIPNS_7storage4ObLSENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEED2Ev -_ZN9oceanbase6common15ObIKVCacheStoreINS0_18ObKVMemBlockHandleEE5storeERNS0_13ObKVCacheInstERKNS0_13ObIKVCacheKeyERKNS0_15ObIKVCacheValueERPNS0_13ObKVCachePairERPS2_NS0_15ObKVCachePolicyE -_ZN9oceanbase6common15ObIKVCacheStoreINS0_18ObKVMemBlockHandleEE12alloc_kvpairERNS0_13ObKVCacheInstEllRPNS0_13ObKVCachePairERPS2_NS0_15ObKVCachePolicyE -_ZN9oceanbase6common17ObKVStoreMemBlock5allocElllRPNS0_13ObKVCachePairE -_ZNK9oceanbase12blocksstable20ObMicroBlockCacheKey9deep_copyEPclRPNS_6common13ObIKVCacheKeyE +_ZN9oceanbase3lib17ObTenantMemoryMgr11free_chunk_EPNS0_6AChunkERKNS0_9ObMemAttrE +_ZNK9oceanbase12blocksstable12ObRawDecoder21load_data_to_obj_cellENS_6common9ObObjMetaEPKclRNS2_5ObObjE +_ZN9oceanbase3lib12SubObjectMgr10free_blockEPNS0_6ABlockE +_ZN9oceanbase7storage8ObTablet42check_tablet_status_for_read_all_committedEv +_ZNK9oceanbase7storage21ObITabletMdsInterface17get_tablet_statusERKNS_5share3SCNERNS0_31ObTabletCreateDeleteMdsUserDataEl +_ZNK9oceanbase7storage21ObITabletMdsInterface12get_snapshotINS0_31ObTabletCreateDeleteMdsUserDataEZNKS1_17get_tablet_statusERKNS_5share3SCNERS3_lEUlRKS3_E_EEiOT0_S5_ll +_ZNK9oceanbase7storage8ObTablet21get_mds_table_handle_ERNS0_3mds14MdsTableHandleEb +_ZN9oceanbase7storage15ObTabletPointer13get_mds_tableERNS0_3mds14MdsTableHandleEb +_ZZNK9oceanbase7storage21ObITabletMdsInterface12get_snapshotINS0_31ObTabletCreateDeleteMdsUserDataEZNKS1_17get_tablet_statusERKNS_5share3SCNERS3_lEUlRKS3_E_EEiOT0_S5_llENKUlPKcE2_clESF_ +_ZN9oceanbase7storage3mds17ObMdsTableHandler20get_mds_table_handleERNS1_14MdsTableHandleERKNS_6common10ObTabletIDERKNS_5share6ObLSIDEbPNS0_15ObTabletPointerE +_ZN9oceanbase6common5occam26ObOccamTimeGuardDetectHungC2EjjPKcS4_S4_t +_ZN9oceanbase6common5occam26ObOccamTimeGuardDetectHungD2Ev +_ZN9oceanbase6common5occam26ObOccamTimeGuardDetectHung5clickEt +_ZN9oceanbase6common5occam20ObOccamFastTimeGuardD2Ev +_ZNK9oceanbase7storage21ObITabletMdsInterface24get_mds_data_from_tabletINS0_31ObTabletCreateDeleteMdsUserDataEEEiRKNS_6common10ObFunctionIFiRKT_EEE +_ZN9oceanbase6common5occam20ObThreadHungDetector13ClickPointIdx7get_idxEv +_ZZNK9oceanbase7storage8ObTablet21get_mds_table_handle_ERNS0_3mds14MdsTableHandleEbENK6$_1261clEPKc.llvm.4447807325406083300 +_ZN9oceanbase7storage10ObLSHandleD1Ev +_ZN9oceanbase7storage10ObLSHandleD2Ev +_ZN9oceanbase6common15ObBlockAllocMgr11alloc_blockElRNS_3lib9ObMemAttrE +_ZN9oceanbase6common9ob_mallocElRKNS_3lib9ObMemAttrE +_ZN9oceanbase3lib17ObMallocAllocator5allocElRKNS0_9ObMemAttrE _ZNK9oceanbase12blocksstable22ObMicroBlockCacheValue9deep_copyEPclRPNS_6common15ObIKVCacheValueE +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder22update_cached_decodersEPclPKcS4_l _ZN9oceanbase12blocksstable24ObIntegerBaseDiffDecoder14update_pointerEPKcS3_ -_ZN9oceanbase6common4hash11ObHashTableIlNS1_11HashMapPairIlNS1_11HashNullObjEEENS1_9hash_funcIlEENS1_8equal_toIlEENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19ReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv -_ZN9oceanbase6common9SCondTempILi3EE6signalEji -_ZZN9oceanbase4palf11LogIOWorker25BatchLogIOFlushLogTaskMgr6handleElPNS0_12IPalfEnvImplEENK5$_995clEPKc -_ZN9oceanbase12blocksstable18ObBloomFilterCache14inc_empty_readEmmRKNS0_12MacroBlockIdEl -_ZNK9oceanbase3sql18ObBasicSessionInfo16get_sys_variableENS_5share17ObSysVarClassTypeERl -_ZN9oceanbase3sql16ObHashDistinctOp10inner_openEv -_ZN9oceanbase8observer20ObInnerSQLConnection5unrefEv -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEED2Ev -_ZN9oceanbase3sql24ObHashPartInfrastructureINS0_14ObHashPartColsENS0_19ObHashPartStoredRowEE7destroyEv -_ZNK9oceanbase7storage21ObTenantFreezeInfoMgr26get_multi_version_durationERl -_ZNSt17_Function_handlerIFvRKN9oceanbase3omt14ObTenantConfigEEZNS0_11transaction14ObWeakReadUtil30generate_min_weak_read_versionEmE5$_220E9_M_invokeERKSt9_Any_dataS4_ -_ZNK9oceanbase8observer16ObInnerSQLResult7get_intEPKcRl -_ZNK9oceanbase8observer16ObInnerSQLResult8find_idxEPKcRl -_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_lEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14set_refactoredERKS3_RKS5_iii -_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_lEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE12internal_setERNS1_17ObHashTableBucketIS5_NS1_5NLockENS1_5NCondEEERKS5_b -_ZNK9oceanbase6common8ObStringeqERKS1_ -_ZNK9oceanbase8observer16ObInnerSQLResult7get_intElRl -_ZN9oceanbase6common8ObMalloc5allocEl -_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_lEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE32internal_get_with_timeout_unsafeERNS1_17ObHashTableBucketIS5_NS1_5NLockENS1_5NCondEEERKS3_RPKS5_l -_ZN9oceanbase6common4hash13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairINS0_8ObStringElEEEELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEE5allocIJEEEPS7_DpRT_ -_ZN9oceanbase3omt19ObTenantTimezoneMgr19get_tenant_timezoneEmRNS_6common11ObTZMapWrapERPNS2_21ObTimeZoneInfoManagerE -_ZN9oceanbase3omt19ObTenantTimezoneMgr25get_tenant_timezone_innerEmRNS_6common11ObTZMapWrapERPNS2_21ObTimeZoneInfoManagerE -_ZN9oceanbase8observer20ObInnerSQLConnectionD2Ev -_ZN9oceanbase6common11ObArrayImplINS0_22ObTZTransitionTypeInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS2_EENS0_17DefaultItemEncodeIS2_EEED2Ev -_ZN9oceanbase6common11ObArrayImplINS0_15ObWarningBuffer11WarningItemENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev -_ZN9oceanbase8observer16ObMPPacketSenderD2Ev -_ZN9oceanbase6common13ObSEArrayImplIlLl32ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase6common13ObSEArrayImplINS_5share21ObLabelSeSessionLabelELl4ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase6common13ObSEArrayImplIPNS_7obmysql12Obp20EncoderELl4ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase6common13ObSEArrayImplINS_7obmysql10ObCommonKVINS0_5ObObjES4_EELl4ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase3sql16ObSQLSessionInfoD1Ev -_ZN9oceanbase3sql16ObSQLSessionInfoD2Ev -_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_PNS_3sql17ObInnerContextMapEEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS8_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS8_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl2EE7destroyEv -_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImNS_5share15ObSequenceValueEEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS6_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS6_EELi65ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv -_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImPNS_2pl16ObPLPackageStateEEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv -_ZN9oceanbase6common11ObArrayImplIlNS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIlEENS0_22NotImplementItemEncodeIlEEED2Ev -_ZN9oceanbase6common8ObMalloc4freeEPv -_ZN9oceanbase3sql18ObBasicSessionInfo13SysVarIncInfoD2Ev -_ZN9oceanbase3sql20ObOptimizerTraceImplD1Ev -_ZN9oceanbase6common11ObSqlStringD1Ev -_ZN9oceanbase6common11ObSqlStringD2Ev -_ZN9oceanbase3sql18ObBasicSessionInfoD2Ev -_ZN9oceanbase5share15ObSysVarFactoryD1Ev -_ZN9oceanbase5share15ObSysVarFactoryD2Ev -_ZN9oceanbase3sql15ObSessionValMapD1Ev -_ZN9oceanbase3sql15ObSessionValMapD2Ev -_ZN9oceanbase3lib17ObMallocAllocator12get_instanceEv -_ZN9oceanbase6common12ObStringBufTINS0_19ModulePageAllocatorENS0_9PageArenaIcS2_EEED2Ev -_ZN9oceanbase6common12ObStringBufTINS0_19ModulePageAllocatorENS0_9PageArenaIcS2_EEE5resetEv -_ZN9oceanbase3sql20ObDblinkCtxInSessionD2Ev -_ZN9oceanbase3sql20ObDblinkCtxInSession17clean_dblink_connEb -_ZN9oceanbase6common11ObArrayImplINS0_22ObTZTransitionTypeInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS2_EENS0_17DefaultItemEncodeIS2_EEE7destroyEv -_ZN9oceanbase6common11ObArrayImplINS0_18ObTZRevertTypeInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS2_EENS0_17DefaultItemEncodeIS2_EEED2Ev -_ZN9oceanbase6common13ObSEArrayImplINS_3sql18ObBasicSessionInfo10ChangedVarELl8ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase6common23ObReserveArenaAllocatorILl256EED2Ev -_ZN9oceanbase10logservice19ObRemoteFetchWorker4run1Ev -_ZN9oceanbase7storage12ObLSIterator8get_nextERPNS0_4ObLSE -_ZTWN9oceanbase3lib7Threads11thread_idx_E -_ZN9oceanbase6common11ObArrayImplIPNS_7storage4ObLSENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEE9push_backERKS4_ -_ZN9oceanbase6common6ObCond9timedwaitEl -_ZN9oceanbase7storage11ObLSService11get_ls_iterERNS_6common13ObSharedGuardINS0_12ObLSIteratorEEENS0_10ObLSGetModE -_ZZN9oceanbase10logservice19ObRemoteFetchWorker11foreach_ls_ERKNS_5share6ObLSIDEENK5$_237clEPKc -_ZNK6obutil11ObUtilMutex4lockEv +_ZN9oceanbase12blocksstable14ObConstDecoder14update_pointerEPKcS3_ +_ZN9oceanbase12blocksstable12ObRawDecoder14update_pointerEPKcS3_ +_ZN9oceanbase12blocksstable19ObStringDiffDecoder14update_pointerEPKcS3_ +_ZN9oceanbase12blocksstable27ObIndexBlockDataTransformer18update_index_blockERKNS0_22ObIndexBlockDataHeaderEPKclPcl +_ZN9oceanbase12blocksstable27ObIndexBlockDataTransformer9transformERKNS0_16ObMicroBlockDataEPcl +_ZNSt17_Function_handlerIFiRN9oceanbase6common10ObLDHandleEEZNS0_5share25get_tenant_base_with_lockEmS3_RPNS5_12ObTenantBaseERSt8functionIS4_EE4$_13E9_M_invokeERKSt9_Any_dataS3_ +_ZN9oceanbase6common13ObSEArrayImplINS0_10ObTabletIDELl128ENS0_19ModulePageAllocatorELb0EE7destroyEv +_ZZN9oceanbase4palf11LogIOWorker15reduce_io_task_EPvENK6$_1001clEPKc +_ZN9oceanbase12blocksstable18ObMacroBlockHandleaSERKS1_ +_ZN9oceanbase6common10ObIOHandle11set_requestERNS0_11ObIORequestE +_ZN9oceanbase12blocksstable14ObBlockManager7inc_refERKNS0_12MacroBlockIdE +_ZN9oceanbase6common18ObBucketWLockGuardD2Ev +_ZN9oceanbase8keybtree10ObKeyBtreeINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE7destroyEv +_ZN9oceanbase6common13RetireStation10RetireList6retireERNS0_10HazardListES4_lRNS0_6QClockE +_ZN9oceanbase6common6QClock14wait_quiescentEm +_ZN9oceanbase8memtable34ObMemtableMultiVersionScanIterator18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowE +_ZN9oceanbase8memtable34ObMemtableMultiVersionScanIterator21iterate_compacted_rowERKNS_6common13ObStoreRowkeyERNS_12blocksstable10ObDatumRowE +_ZN9oceanbase8memtable27ObMultiVersionValueIterator25get_next_node_for_compactERPKv +_ZZN9oceanbase8memtable34ObMemtableMultiVersionScanIterator18inner_get_next_rowERPKNS_12blocksstable10ObDatumRowEENK5$_450clEPKc +_ZN9oceanbase8memtable27ObMultiVersionValueIterator23init_multi_version_iterEv +_ZN9oceanbase8memtable34ObMemtableMultiVersionScanIterator20init_next_value_iterEv +_ZN9oceanbase8memtable25ObMultiVersionRowIterator12get_next_rowERPKNS0_13ObMemtableKeyERPNS0_27ObMultiVersionValueIteratorE +_ZN9oceanbase8memtable34ObMemtableMultiVersionScanIterator23iterate_uncommitted_rowERKNS_6common13ObStoreRowkeyERNS_12blocksstable10ObDatumRowE +_ZN9oceanbase8memtable27ObMultiVersionValueIterator25get_next_uncommitted_nodeERPKvRNS_11transaction9ObTransIDERNS_5share3SCNERl +_ZN9oceanbase8memtable27ObMultiVersionValueIterator27get_next_multi_version_nodeERPKv +_ZN9oceanbase6common21ObDiagnoseSessionInfo15notify_wait_endEPNS0_20ObDiagnoseTenantInfoEb +_ZN9oceanbase12blocksstable18ObMacroBlockHandleD1Ev +_ZN9oceanbase12blocksstable18ObMacroBlockHandleD2Ev +_ZN9oceanbase12blocksstable14ObBlockManager7dec_refERKNS0_12MacroBlockIdE +_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE20do_insert_or_update_ERKS3_RKS5_ +_ZZN9oceanbase4palf11LogIOWorker25BatchLogIOFlushLogTaskMgr6handleElPNS0_12IPalfEnvImplEENK6$_1012clEPKc +_ZN9oceanbase5share8detector22ObLCLBatchSenderThread4run1Ev +_ZN9oceanbase6common15ObLinearHashMapINS_5share8detector20ObDependencyResourceENS3_12ObLCLMessageENS0_14ShareMemMgrTagEE18set_foreach_L_lmt_Ev +_ZN9oceanbase6common15ObLinearHashMapINS_5share8detector20ObDependencyResourceENS3_12ObLCLMessageENS0_14ShareMemMgrTagEE16do_foreach_scan_INS3_22ObLCLBatchSenderThread10RemoveIfOpENS7_15DoRemoveIfOnBktISA_EEEEbmmRT_RT0_ +_ZN9oceanbase5share8detector22ObLCLBatchSenderThread46record_summary_info_and_logout_when_necessary_Elll _ZN9oceanbase3sql16ObSQLSessionInfo7destroyEb _ZN9oceanbase3sql16ObSQLSessionInfo5resetEb -_ZN9oceanbase5share6schema19ObSchemaGetterGuard5resetEv -_ZN9oceanbase5share6schema17ObSchemaMgrHandle5resetEv -_ZN9oceanbase6common13ObSEArrayImplINS_5share6schema15ObSchemaMgrInfoELl2ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase5share11ObTenantEnv3mtlIPNS_11transaction14ObTransServiceEEET_v -_ZN9oceanbase3sql20ObDblinkCtxInSession21free_dblink_conn_poolEv -_ZN9oceanbase5share17ObFeedbackManager5resetEv -_ZN9oceanbase11transaction14ObTxExecResult5resetEv +_ZN9oceanbase8observer15ObSqlEndTransCb5resetEv +_ZN9oceanbase3sql20ObDblinkCtxInSession17clean_dblink_connEb _ZN9oceanbase3sql18ObBasicSessionInfo5resetEb _ZN9oceanbase5share13ObBasicSysVarD2Ev _ZN9oceanbase5share15ObTypeLibSysVarD2Ev _ZN9oceanbase3sql15ObSessionValMap5reuseEv _ZN9oceanbase5share15ObSysVarFactory7destroyEv -_ZN9oceanbase6common18ObDSSessionActions9clear_allEv -_ZN9oceanbase3sql16ObSQLSessionInfo16drop_temp_tablesEbb +_ZN9oceanbase6common12ObStringBufTINS0_19ModulePageAllocatorENS0_9PageArenaIcS2_EEE5resetEv +_ZN9oceanbase6common13ObSEArrayImplINS_3sql18ObBasicSessionInfo13TableStmtTypeELl2ENS0_19ModulePageAllocatorELb0EE7destroyEv +_ZN9oceanbase11transaction14ObTxExecResult5resetEv _ZN9oceanbase3sql18ObBasicSessionInfo26reset_session_changed_infoEv -_ZZN9oceanbase4palf7PalfEnv4openElRNS0_10PalfHandleEENK5$_729clEPKc.llvm.2452046906557810875 +_ZNK9oceanbase8observer16ObInnerSQLResult7get_intEPKcRl +_ZNK9oceanbase8observer16ObInnerSQLResult8find_idxEPKcRl +_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_lEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14set_refactoredERKS3_RKS5_iii +_ZNK9oceanbase8observer16ObInnerSQLResult7get_intElRl +_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_lEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE6createElPSH_PSK_ +_ZN9oceanbase6common4hash9do_createIPNS1_17ObHashTableBucketINS1_11HashMapPairINS0_8ObStringElEENS1_5NLockENS1_5NCondEEENS0_8ObMallocEEEiRT_lllNS1_16NormalPointerTagERT0_ +_ZN9oceanbase6common4hash13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairINS0_8ObStringElEEEELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEE5allocIJEEEPS7_DpRT_ +_ZN9oceanbase6common17ObjHashCalculatorILNS0_9ObObjTypeE5ENS0_13ObDefaultHashENS0_5ObObjEE15calc_hash_valueERKS4_mRm +_ZN9oceanbase6common13TimeWheelBase4run1Ev +_ZN6obutil4CondC1Ev +_ZN9oceanbase6common16ObClockGenerator6usleepEl +_ZNK6obutil4Cond15timed_wait_implINS_11ObUtilMutexEEEbRKT_RKNS_9ObSysTimeE +_ZN9oceanbase6common5occam16ObOccamTimerTask12runTimerTaskEv +_ZN9oceanbase6common11ObTimeWheel8scheduleEPNS0_15ObTimeWheelTaskEl +_ZN9oceanbase6common13TimeWheelBase8scheduleEPNS0_15ObTimeWheelTaskEl +_ZN9oceanbase6common5occam16ObOccamTimeGuardD2Ev +_ZN9oceanbase6common5occam16ObOccamTimerTask27commit_task_to_thread_pool_Ev +_ZN9oceanbase6common13TimeWheelBase9schedule_EPNS0_15ObTimeWheelTaskEl +_ZN9oceanbase6common5occam17ObOccamThreadPool11commit_taskILNS1_13TASK_PRIORITYE1ERNS1_16ObOccamTimerTask11TaskWrapperEJEEEiRNS0_8ObFutureINSt9result_ofIFT0_DpT1_EE4typeEEEOSA_DpOSB_ _ZN9oceanbase6common13ObSharedGuardINS0_6future12ObFutureBaseIbE11FutureBlockEE5resetEv -_ZN9oceanbase3sql16AllocDASOpHelperILi5EE5allocERNS_6common12ObIAllocatorERPNS0_12ObIDASTaskOpE -_ZN9oceanbase6common13ObSEArrayImplINS0_10ObTabletIDELl128ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE16do_foreach_scan_INS4_18ObLogReplayService15FetchLogFunctorENS8_14DoForeachOnBktISB_EEEEbmmRT_RT0_ -_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE16load_access_bkt_EmRPNS8_6BucketE -_ZN9oceanbase6common12ObLatchMutex4waitElj -_ZNSt14_Function_base13_Base_managerIZN9oceanbase3lib17ObMallocAllocator16get_tenant_limitEmE4$_52E10_M_managerERSt9_Any_dataRKS6_St18_Manager_operation.llvm.12858094529141013191 -_ZN9oceanbase3sql11ObDASLockOp7open_opEv -_ZN9oceanbase7storage15ObAccessService9lock_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERNS_11transaction8ObTxDescERKNS0_14ObDMLBaseParamElNS0_10ObLockFlagEPNS6_16ObNewRowIteratorERl -_ZN9oceanbase6common11ObTimeGuardD2Ev -_ZN9oceanbase7storage17ObLSTabletService23prepare_dml_running_ctxEPKNS_6common8ObIArrayImEES6_RNS0_14ObTabletHandleERNS0_15ObDMLRunningCtxE -_ZN9oceanbase7storage17ObLSTabletService9lock_rowsERNS0_10ObStoreCtxERKNS0_14ObDMLBaseParamElNS0_10ObLockFlagEbPNS_6common16ObNewRowIteratorERl -_ZN9oceanbase6common13ObSEArrayImplImLl1ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase7storage8ObTablet8lock_rowERNS0_15ObRelativeTableERNS0_10ObStoreCtxERKNS_6common8ObNewRowE -_ZN9oceanbase6common13ObStoreRowkey6assignEPNS0_5ObObjEl -_ZN9oceanbase8memtable10ObMemtable4lockERNS_7storage10ObStoreCtxEmRKNS2_15ObTableReadInfoERKNS_6common8ObNewRowE -_ZN9oceanbase12blocksstable11ObRowWriterD1Ev -_ZN9oceanbase12blocksstable11ObRowWriterD2Ev -_ZN9oceanbase8memtable10ObMemtable5lock_ERNS_7storage10ObStoreCtxEmRKNS2_15ObTableReadInfoERKNS_6common13ObStoreRowkeyERNS0_13ObMemtableKeyE -_ZN9oceanbase12blocksstable11ObRowWriter17append_row_headerEhhlll -_ZN9oceanbase12blocksstable11ObRowWriter12write_rowkeyERKNS_6common13ObStoreRowkeyERPcRl -_ZNK9oceanbase7storage10ObStoreCtx8is_validEv -_ZN9oceanbase6common13ObSEArrayImplINS_5share6schema9ObColDescELl52ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase7storage15ObDMLRunningCtxD2Ev -_ZN9oceanbase6common11ObTimeGuardC2EPKcl -_ZN9oceanbase12blocksstable11ObRowWriter17inner_write_cellsINS_6common5ObObjEEEiPKT_l -_ZN9oceanbase12blocksstable11ObRowWriter20write_col_in_clusterINS_6common5ObObjEEEiPKT_lll -_ZN9oceanbase12blocksstable11ObRowWriter20append_row_and_indexINS_6common5ObObjENS0_20ObColClusterInfoMaskEEEiPKT_lllbRT0_ -_ZN9oceanbase7storage8ObTablet16prepare_memtableERNS0_15ObRelativeTableERNS0_10ObStoreCtxERPNS_8memtable10ObMemtableE -_ZN9oceanbase8observer16ObInnerSQLResultD2Ev -_ZN9oceanbase8observer16ObInnerSQLResult5closeEv -_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_lEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv -_ZN9oceanbase8observer16ObInnerSQLResult11inner_closeEv -_ZN9oceanbase3sql8ObSqlCtxD2Ev -_ZN9oceanbase6common16ObFixedArrayImplINS0_8ObStringENS0_12ObIAllocatorEE7destroyEv -_ZN9oceanbase3sql8ObSqlCtx5resetEv -_ZN9oceanbase6common4hash13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairINS0_8ObStringElEEEELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEE4freeEPS7_ -_ZN9oceanbase6common15ObBaseLogWriter12do_flush_logEv -_ZNSt14_Function_base13_Base_managerIZN9oceanbase11transaction14ObWeakReadUtil30generate_min_weak_read_versionEmE5$_220E10_M_managerERSt9_Any_dataRKS6_St18_Manager_operation.llvm.3929980531529976719 +_ZN9oceanbase6common11ObWeakGuardINS0_10ObFunctionIFbvEEEED2Ev +_ZN9oceanbase6common10ObFunctionIFvvEE6assignIZNS0_5occam17ObOccamThreadPool11commit_taskILNS5_13TASK_PRIORITYE1ERNS5_16ObOccamTimerTask11TaskWrapperEJEEEiRNS0_8ObFutureINSt9result_ofIFT0_DpT1_EE4typeEEEOSE_DpOSF_EUlvE_Lb1EEEiOT_ +_ZN9oceanbase6common15ob_alloc_sharedINS0_6future12ObFutureBaseIbE11FutureBlockEJELb1EEEiRNS0_13ObSharedGuardIT_EERNS0_12ObIAllocatorE +_ZN9oceanbase6common6future22DefaultFutureAllocator5allocEl +_ZNK9oceanbase6common9ObPromiseIbE10get_futureEv +_ZN9oceanbase6common5occam17ObOccamThreadPool14InnerTaskQueue9push_taskERKNS0_10ObFunctionIFvvEEE +_ZNK9oceanbase6common10ObFunctionIFvvEE7DerivedIZNS0_5occam17ObOccamThreadPool11commit_taskILNS5_13TASK_PRIORITYE1ERNS5_16ObOccamTimerTask11TaskWrapperEJEEEiRNS0_8ObFutureINSt9result_ofIFT0_DpT1_EE4typeEEEOSE_DpOSF_EUlvE_E4copyERNS0_12ObIAllocatorEPv +_ZN9oceanbase6common8function24DefaultFunctionAllocator5allocEl +_ZNK9oceanbase6common6future16ObFutureBaseBase4waitEv +_ZNK9oceanbase3lib6Worker18get_timeout_remainEv +_ZN9oceanbase5share6schema19ObSchemaGetterGuard23get_simple_table_schemaEmmRKNS_6common8ObStringEbRPKNS1_21ObSimpleTableSchemaV2Eb +_ZN9oceanbase5share6schema17ObSysTableChecker17is_sys_table_nameEmmRKNS_6common8ObStringERb +_ZNK9oceanbase5share6schema11ObSchemaMgr16get_table_schemaEmmmRKNS_6common8ObStringERPKNS1_21ObSimpleTableSchemaV2E +_ZNK9oceanbase6common4hash16ObPointerHashMapINS_5share6schema24ObTableSchemaHashWrapperEPNS4_21ObSimpleTableSchemaV2ENS4_13GetTableKeyV2ELl1024ENS0_19ModulePageAllocatorEE14get_refactoredERKS5_RS7_ +_ZN9oceanbase5share6schema25ObCompareNameWithTenantID7compareERKNS_6common8ObStringES6_ +_ZL20ob_strnncoll_utf8mb4PK13ObCharsetInfoPKhmS3_mb +_ZN9oceanbase5share6schema17ObSysTableChecker20check_sys_table_nameEmmRKNS_6common8ObStringERb +_ZNK9oceanbase6common4hash9ObHashMapImPNS0_9ObSEArrayINS_5share6schema17ObSysTableChecker16TableNameWrapperELl2ENS0_19ModulePageAllocatorELb0EEENS1_19NoPthreadDefendModeENS1_9hash_funcImEENS1_8equal_toImEENS1_13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairImSA_EEEELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_13NormalPointerENS0_8ObMallocELl1EE14get_refactoredERKmRSA_l _ZN9oceanbase6common6parrayEPclPli -_ZN9oceanbase6common13ObSEArrayImplINS_5share6ObLSIDELl3ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase12blocksstable14ObBlockManager17mark_macro_blocksERNS_6common15ObLinearHashMapINS0_12MacroBlockIdEbNS2_14ShareMemMgrTagEEERNS2_4hash9ObHashSetIS4_NS8_19ReadWriteDefendModeENS8_9hash_funcIS4_EENS8_8equal_toIS4_EENS8_13SimpleAllocerINS8_15ObHashTableNodeINS8_11HashMapPairIS4_NS8_11HashNullObjEEEEELi89ENS8_19SpinMutexDefendModeENS8_29DefaultSimpleAllocerAllocatorEEENS8_13NormalPointerENS2_8ObMallocELl1EEE +_ZN9oceanbase6common4hash11ObHashTableINS_12blocksstable12MacroBlockIdENS1_11HashMapPairIS4_NS1_11HashNullObjEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi89ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19ReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14set_refactoredERKS4_RKS7_iii +_ZNK9oceanbase12blocksstable12MacroBlockId4hashERm +_ZN9oceanbase12blocksstable14ObBlockManager16update_mark_infoERKNS0_12MacroBlockIdERNS_6common15ObLinearHashMapIS2_bNS5_14ShareMemMgrTagEEE +_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE7do_get_ERKS3_RS5_ +_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE16load_access_bkt_ERKS3_RmRPNS7_6BucketE +_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdEbNS0_14ShareMemMgrTagEE16load_access_bkt_ERKS3_RmRPNS5_6BucketE +_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE17load_factor_ctrl_Em +_ZNK9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE15get_load_factorEv +_ZN9oceanbase6common4hash11ObHashTableINS_12blocksstable12MacroBlockIdENS1_11HashMapPairIS4_NS1_11HashNullObjEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi89ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19ReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE12internal_setERNS1_17ObHashTableBucketIS7_16pthread_rwlock_tNS1_5NCondEEERKS7_b +_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdEbNS0_14ShareMemMgrTagEE7shrink_Ev +_ZN9oceanbase6common4hash11WriteLockerC2ER16pthread_rwlock_t +pthread_rwlock_wrlock +_ZNK9oceanbase12blocksstable18ObSSTableMacroInfo19get_data_block_iterERNS0_17ObMacroIdIteratorE +_ZNK9oceanbase12blocksstable18ObSSTableMacroInfo20get_other_block_iterERNS0_17ObMacroIdIteratorE +_ZNK9oceanbase7storage8ObTablet19get_tablet_meta_idsERNS_6common8ObIArrayINS_12blocksstable12MacroBlockIdEEE +_ZNK9oceanbase7storage8ObTablet15parse_meta_addrERKNS0_14ObMetaDiskAddrERNS_6common8ObIArrayINS_12blocksstable12MacroBlockIdEEE +_ZN9oceanbase6common11ObArrayImplINS_12blocksstable12MacroBlockIdENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEE9push_backERKS3_ +_ZN9oceanbase6common11ObArrayImplINS_12blocksstable12MacroBlockIdENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEE10extend_bufEl +_ZNK9oceanbase7storage8ObTablet22inner_get_all_sstablesERNS0_20ObTableStoreIteratorE +_ZNK9oceanbase7storage18ObTabletTableStore15get_all_sstableERNS0_20ObTableStoreIteratorE +_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE16do_foreach_scan_INS4_26GetPendingFreeBlockFunctorENS7_14DoForeachOnBktIS9_EEEEbmmRT_RT0_ +_ZN9oceanbase12blocksstable14ObTmpFileStore20get_macro_block_listERNS_6common8ObIArrayINS0_12MacroBlockIdEEE +_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdEbNS0_14ShareMemMgrTagEE10do_insert_ERKS3_RKb +_ZNSt17_Function_handlerIFvRKN9oceanbase3omt14ObTenantConfigEEZNS0_11transaction14ObWeakReadUtil30generate_min_weak_read_versionEmRNS0_5share3SCNEE5$_228E9_M_invokeERKSt9_Any_dataS4_ +_ZN9oceanbase6common4hash11ObHashTableINS0_6ObAddrENS1_12ObReferedMapIS3_NS_10rootserver16DRServerStatInfoEE4ItemENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS8_6GetKeyENS1_13SimpleAllocerINS1_15ObHashTableNodeIS8_EELi76ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv +_ZN9oceanbase8observer20ObInnerSQLConnectionD2Ev +_ZN9oceanbase6common11ObArrayImplINS0_18ObTZRevertTypeInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS2_EENS0_17DefaultItemEncodeIS2_EEED2Ev +_ZN9oceanbase6common13ObSEArrayImplINS_5share21ObLabelSeSessionLabelELl4ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase6common23ObReserveArenaAllocatorILl256EED2Ev +_ZN9oceanbase6common13ObSEArrayImplImLl8ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase6common11ObArrayImplINS0_15ObWarningBuffer11WarningItemENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev +_ZN9oceanbase3sql20ObOptimizerTraceImplD1Ev +_ZN9oceanbase3sql16ObSQLSessionInfoD1Ev +_ZN9oceanbase3sql16ObSQLSessionInfoD2Ev +_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImNS_5share15ObSequenceValueEEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS6_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS6_EELi65ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv +_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_PNS_3sql17ObInnerContextMapEEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS8_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS8_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl2EE7destroyEv +_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImPNS_2pl16ObPLPackageStateEEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv +_ZN9oceanbase6common9PageArenaIcNS0_19ModulePageAllocatorEED2Ev +_ZN9oceanbase8observer16ObMPPacketSenderD2Ev +_ZN9oceanbase5share6schema19ObSchemaGetterGuard5resetEv +_ZN9oceanbase5share6schema15ObSchemaMgrInfoD1Ev +_ZN9oceanbase5share6schema15ObSchemaMgrInfoD2Ev +_ZN9oceanbase6common13ObSEArrayImplINS_5share6schema19ObSchemaGetterGuard9SchemaObjELl2ENS0_19ModulePageAllocatorELb0EE14internal_free_EPv +_ZN9oceanbase6common14ObFileAppenderD1Ev +_ZN9oceanbase6common14ObFileAppenderD2Ev +_ZN9oceanbase6common11ObArrayImplIlNS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIlEENS0_22NotImplementItemEncodeIlEEED2Ev +_ZN9oceanbase3sql18ObBasicSessionInfoD2Ev +_ZN9oceanbase5share15ObSysVarFactoryD1Ev +_ZN9oceanbase5share15ObSysVarFactoryD2Ev +_ZN9oceanbase3sql15ObSessionValMapD1Ev +_ZN9oceanbase3sql15ObSessionValMapD2Ev +_ZN9oceanbase6common18ObDSSessionActions9clear_allEv +_ZN9oceanbase6common12ObStringBufTINS0_19ModulePageAllocatorENS0_9PageArenaIcS2_EEED2Ev +_ZN9oceanbase6common9PageArenaIcNS0_19ModulePageAllocatorEE4freeEv +_ZN9oceanbase6common13ObSEArrayImplINS_11transaction8ObTxPartELl4ENS0_19ModulePageAllocatorELb0EE7destroyEv +_ZN9oceanbase6common6ObPoolINS0_18ObWrapperAllocatorENS0_10ObNullLockEED2Ev +_ZN9oceanbase6common13ObSEArrayImplIlLl32ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase11transaction14ObTxExecResultD1Ev +_ZN9oceanbase11transaction14ObTxExecResultD2Ev +_ZN9oceanbase6common11ObArrayImplINS0_22ObTZTransitionTypeInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS2_EENS0_17DefaultItemEncodeIS2_EEED2Ev +_ZN9oceanbase5share17ObFeedbackManager5resetEv +_ZN9oceanbase3sql18ObBasicSessionInfo7destroyEv +_ZN9oceanbase6common16ObFixedArrayImplINS_3sql12ObQueryRange13ExprFinalInfoENS0_12ObIAllocatorEE7destroyEv +_ZN9oceanbase10logservice19ObRemoteFetchWorker4run1Ev +_ZN9oceanbase7storage12ObLSIterator8get_nextERPNS0_4ObLSE +_ZN9oceanbase6common5guard27DefaultSharedGuardAllocator4freeEPv +_ZN9oceanbase6common11ObArrayImplIPNS_7storage4ObLSENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEE9push_backERKS4_ +_ZN9oceanbase6common11ObArrayImplIPNS_7storage4ObLSENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEE10extend_bufEl +_ZN9oceanbase6common11ObTimeGuard5clickEPKc +_ZNK9oceanbase5trace4UUID9serializeEPclRl +_ZN9oceanbase3omt19ObTenantTimezoneMgr19get_tenant_timezoneEmRNS_6common11ObTZMapWrapERPNS2_21ObTimeZoneInfoManagerE +_ZN9oceanbase3omt19ObTenantTimezoneMgr25get_tenant_timezone_innerEmRNS_6common11ObTZMapWrapERPNS2_21ObTimeZoneInfoManagerE +_ZTWN9oceanbase6common8ObLogger16disable_logging_E _ZN9oceanbase3lib8BlockSet11alloc_blockEmRKNS0_9ObMemAttrE -_ZN9oceanbase10rootserver14ObRootBalancer11all_balanceEv -_ZN9oceanbase10rootserver17ObUnitStatManager11gather_statEv -_ZN9oceanbase10rootserver16ObServerBalancer15balance_serversEv -_ZN9oceanbase6common5occam17ObOccamThreadPool14InnerTaskQueue8pop_taskERNS0_10ObFunctionIFvvEEEl -_ZN9oceanbase6common16ObClockGenerator4run1Ev -_ZTWN9oceanbase3lib6Thread9sleep_us_E -_ZN9oceanbase12blocksstable21ObMicroBlockRowGetter17get_not_exist_rowERKNS0_13ObDatumRowkeyERPKNS0_10ObDatumRowE -_ZN9oceanbase6common11ObArrayImplIPNS_7storage4ObLSENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEE7destroyEv -_ZN9oceanbase3lib9SetLockerINS0_7ObMutexEE4lockEv -_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE16do_foreach_scan_INS4_18ObLogReplayService24StatReplayProcessFunctorENS8_14DoForeachOnBktISB_EEEEbmmRT_RT0_ -_ZNK9oceanbase5share6schema18ObTableSchemaParam21get_rowkey_column_idsERNS_6common8ObIArrayINS1_9ObColDescEEE -_ZNK9oceanbase3sql18ObBasicSessionInfo16get_sys_variableENS_5share17ObSysVarClassTypeERNS_6common5ObObjE -_ZNK9oceanbase3sql18ObBasicSessionInfo17inner_get_sys_varENS_5share17ObSysVarClassTypeERlRPNS2_13ObBasicSysVarE -_ZN9oceanbase5obrpc18ObRpcProcessorBase14set_ob_requestERNS_3rpc9ObRequestE -eloop_run -_ZL16pn_pktc_flush_cbP10pktc_req_t +_ZN9oceanbase12blocksstable21ObStringPrefixEncoder8traverseERb +_ZN9oceanbase12blocksstable17ObMultiPrefixTree17traverse_by_levelElRbl +XXH64 +_ZN9oceanbase6common15ObLinearHashMapINS_10logservice18ServerProbeService11ServerLSKeyENS3_10LSProbeCtxENS0_14ShareMemMgrTagEE16do_foreach_scan_IZNS3_15run_probe_once_EvE5$_777NS7_14DoForeachOnBktIS9_EEEEbmmRT_RT0_ +_ZN9oceanbase6common15ObLinearHashMapINS_10logservice18ServerProbeService11ServerLSKeyENS3_10LSProbeCtxENS0_14ShareMemMgrTagEE16load_access_bkt_EmRPNS7_6BucketE +_ZN9oceanbase12blocksstable18ObMacroBlockHandle4waitEl +_ZN9oceanbase6common10ObIOHandle4waitEl +_ZN9oceanbase8keybtree10ObKeyBtreeINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE7destroyEPNS0_9BtreeNodeIS3_S5_EE +_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_10ObTransCtxENS0_13TransCtxAllocENS_6common10SpinRWLockELl16384EE22for_each_in_one_bucketINS0_20ObTxSubmitLogFunctorEEEiRT_l +_ZN9oceanbase11transaction15ObTransHashLinkINS0_10ObTransCtxEE7dec_refEi +_ZNK9oceanbase5share6schema11ObSchemaMgr27get_table_schemas_in_tenantEmRNS_6common8ObIArrayIPKNS1_21ObSimpleTableSchemaV2EEE +_ZN9oceanbase6common11ObArrayImplIPKNS_5share6schema21ObSimpleTableSchemaV2ENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS6_EENS0_22NotImplementItemEncodeIS6_EEE9push_backERKS6_ +_ZN9oceanbase6common11ObArrayImplIPKNS_5share6schema21ObSimpleTableSchemaV2ENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS6_EENS0_22NotImplementItemEncodeIS6_EEE10extend_bufEl +_ZN9oceanbase5share13ObLocalDevice12io_geteventsEPNS_6common11ObIOContextElPNS2_10ObIOEventsEP8timespec +_ZN9oceanbase6common15ObLinearHashMapINS0_10ObTabletIDENS_7storage3mds4ListINS4_12MdsTableBaseEEENS0_14ShareMemMgrTagEE16do_foreach_scan_IZNS4_13ObMdsTableMgr5flushENS_5share3SCNEbE4$_35NS9_14DoForeachOnBktISE_EEEEbmmRT_RT0_ +_ZN9oceanbase3lib17ObTenantMemoryMgr11alloc_chunkElRKNS0_9ObMemAttrE +_ZNK9oceanbase3lib7ObLabeleqERKS1_ +_ZN9oceanbase3lib17ObTenantMemoryMgr11update_holdElmRKNS0_7ObLabelERb +_ZN9oceanbase3lib17ObTenantMemoryMgr12alloc_chunk_ElRKNS0_9ObMemAttrE +_ZN9oceanbase3lib9AChunkMgr12direct_allocEmbRbb +_ZN9oceanbase5share17ObTenantDagWorker4run1Ev +_ZN9oceanbase6common12ObThreadCond7wait_usEm +_ZN9oceanbase6common18ObWaitEventHistory4pushElmmmm +_ZN9oceanbase6common13ObSEArrayImplINS_12blocksstable12ObDatumRangeELl4ENS0_19ModulePageAllocatorELb0EE9push_backERKS3_ +_ZN9oceanbase12blocksstable34ObMultiVersionMicroBlockRowScanner13lock_for_readERKNS_11transaction16ObLockForReadArgERbRlS6_ +_ZN9oceanbase7storage15ObTxTableGuards13lock_for_readERKNS_11transaction16ObLockForReadArgERbRNS_5share3SCNES6_ +_ZN9oceanbase7storage15ObTxDataKVCache12get_instanceEv +_ZN9oceanbase7storage9ObTxTable18check_with_tx_dataERNS0_15ObReadTxDataArgERNS0_21ObITxDataCheckFunctorE +_ZN9oceanbase7storage26ObCleanoutNothingOperationclERKNS0_8ObTxDataEPNS0_9ObTxCCCtxE +_ZN9oceanbase7storage9ObTxTable22check_state_and_epoch_ENS_11transaction9ObTransIDElbRi +_ZN9oceanbase7storage18LockForReadFunctorclERKNS0_8ObTxDataEPNS0_9ObTxCCCtxE +_ZN9oceanbase7storage15ObTxDataKVCache7get_rowERKNS0_16ObTxDataCacheKeyERNS0_19ObTxDataValueHandleE +_ZN9oceanbase11transaction12ObLSTxCtxMgr18check_with_tx_dataERKNS0_9ObTransIDERNS_7storage21ObITxDataCheckFunctorE +_ZN9oceanbase7storage17ObTxDataMiniCache3setERKNS0_14ObTxCommitDataE +_ZNK9oceanbase7storage16ObUndoStatusList10is_containEli +_ZN9oceanbase11transaction12ObLSTxCtxMgr11get_tx_ctx_ERKNS0_9ObTransIDEbRPNS0_14ObPartTransCtxE +_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_10ObTransCtxENS0_13TransCtxAllocENS_6common10SpinRWLockELl16384EE3getERKS2_RPS3_ +_ZN9oceanbase6common9ObKVCacheINS_7storage16ObTxDataCacheKeyENS2_18ObTxDataCacheValueEE3getERKS3_RPKS4_RNS0_15ObKVCacheHandleE +_ZN9oceanbase6common10ObIORunner4run1Ev +_ZNK9oceanbase12blocksstable20ObMicroBlockCacheKey4sizeEv +_ZN9oceanbase3lib11ObLockGuardINS_6common12ObThreadCondEED2Ev +_ZNK9oceanbase12blocksstable22ObMicroBlockCacheValue4sizeEv +_ZN9oceanbase6common11ObIORequest7dec_refEPKc +_ZN9oceanbase6common17ObTenantIOManager7dec_refEv +_ZThn24_N9oceanbase12blocksstable21ObDataMicroBlockCache15calc_value_sizeElRKNS_6common14ObRowStoreTypeEllRlRb +_ZN9oceanbase6common11ObIORequest6finishERKNS0_11ObIORetCodeE +pthread_mutex_lock +_ZN9oceanbase12blocksstable28ObSingleMicroBlockIOCallback13inner_processEPKcl +_ZNK9oceanbase12blocksstable18ObMicroBlockHeader20check_and_get_recordEPKclsRS3_Rl +_ZNK9oceanbase12blocksstable18ObMicroBlockHeader21check_header_checksumEv +_ZN9oceanbase6common10ObIKVCacheINS_12blocksstable20ObMicroBlockCacheKeyENS2_22ObMicroBlockCacheValueEE10put_kvpairERNS0_19ObKVCacheInstHandleEPNS0_13ObKVCachePairERNS0_15ObKVCacheHandleEb +_ZN9oceanbase6common9ObKVCacheINS_12blocksstable20ObMicroBlockCacheKeyENS2_22ObMicroBlockCacheValueEE5allocEmllRPNS0_13ObKVCachePairERNS0_15ObKVCacheHandleERNS0_19ObKVCacheInstHandleE +_ZN9oceanbase6common15ObKVGlobalCache5allocINS0_18ObKVMemBlockHandleEEEiRNS0_15ObIKVCacheStoreIT_EElmllRPNS0_13ObKVCachePairERPS3_RNS0_19ObKVCacheInstHandleE +_ZN9oceanbase6common9ObKVCacheINS_12blocksstable20ObMicroBlockCacheKeyENS2_22ObMicroBlockCacheValueEE3getERKS3_RPKS4_RNS0_15ObKVCacheHandleE +_ZN9oceanbase6common15ObKVGlobalCache3getElRKNS0_13ObIKVCacheKeyERPKNS0_15ObIKVCacheValueERPNS0_18ObKVMemBlockHandleE +_ZNK9oceanbase12blocksstable18ObMicroBlockHeader22check_payload_checksumEPKcl +_ZNK9oceanbase6common16ObCompressorPool19get_compressor_typeEPKcRNS0_16ObCompressorTypeE +_ZThn24_N9oceanbase12blocksstable21ObDataMicroBlockCache15write_extra_bufEPKcllPcRNS0_16ObMicroBlockDataE +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder22get_decoder_cache_sizeEPKclRl +_ZN9oceanbase12blocksstable19ObMicroBlockDecoder14cache_decodersEPclPKcl +_ZN9oceanbase12blocksstable18ObMacroBlockReader11decrypt_bufERKNS0_19ObMicroBlockDesMetaEPKclRS6_Rl +_ZN9oceanbase6common11ObIORequestD2Ev +_ZN9oceanbase6common11ObIORequest7destroyEv +_ZN9oceanbase5share13ObLocalDevice9free_iocbEPNS_6common6ObIOCBE +_ZN9oceanbase12blocksstable28ObSingleMicroBlockIOCallbackD2Ev +_ZN9oceanbase6common17ObTenantIOManager21trace_request_if_needEPKNS0_11ObIORequestEPKcNS0_10ObIOTracer9TraceTypeE +_ZL14pn_thread_funcPv _ZL17timerfd_handle_twP9timerfd_t -pkts_sk_handle_event -_ZL21pn_pkts_flush_cb_funcP10pkts_req_t _ZL12pkts_evfd_cbP6sock_t pktc_sk_handle_event pktc_sk_consume -_ZN9oceanbase5obrpc19ObAsyncRespCallback9client_cbEPviPKcl +delay_warn +_ZL15pn_pktc_resp_cbP9pktc_cb_tPKcl wq_flush +pkts_sk_handle_event pkts_sk_consume sk_read_with_ib sk_read _ZL17ib_prepare_bufferP9ibuffer_tl -_ZN9oceanbase5obrpc19ObAsyncRespCallback11handle_respEiPKcl -_ZN9oceanbase5obrpc17ObRpcPacketHeader11deserializeEPKclRl -_ZN9oceanbase5obrpc10ObRpcProxy7AsyncCBINS0_15ObTransRpcProxy5ObRpcILNS0_15ObRpcPacketCodeE1626EvEEE6decodeEPv -_ZN9oceanbase5obrpc10ObRpcProxy7AsyncCBINS0_13LogRpcProxyV25ObRpcILNS0_15ObRpcPacketCodeE5386EvEEE6decodeEPv -_ZL19pn_pkts_handle_funcP6pkts_tPvPKclm -_ZN9oceanbase5obrpcL24rpc_mem_pool_create_pageElPKcl.llvm.15526737708331648047 -_Z8serve_cbiPKclm -_ZN9oceanbase5obrpc15ObRpcResultCode11deserializeEPKclRl -_ZN9oceanbase6common13ObSEArrayImplINS0_15ObWarningBuffer11WarningItemELl2ENS0_19ModulePageAllocatorELb0EE11deserializeEPKclRl -_ZL15pn_pktc_resp_cbP9pktc_cb_tPKcl +fifo_free cfifo_free +_ZL19pn_pkts_handle_funcP6pkts_tPvPKclm +_Z8serve_cbiPKclm +_ZN9oceanbase5obrpcL24rpc_mem_pool_create_pageElPKcl.llvm.10533165957714831370 _ZL12pktc_evfd_cbP6sock_t -delay_warn -_ZN9oceanbase5obrpc9ObTxRPCCBILNS0_15ObRpcPacketCodeE1628EE7processEv -_ZN9oceanbase5obrpc9ObTxRPCCBILNS0_15ObRpcPacketCodeE1626EE7processEv -_ZNK9oceanbase11transaction7ObTxMsg8is_validEv -_ZN9oceanbase6common21ObNullSafeDatumStrCmpILNS0_15ObCollationTypeE45ELb0ELb1EE3cmpERKNS0_7ObDatumES6_Ri -_ZNKSt9type_info9hash_codeEv -_ZN9oceanbase11transaction23ObTenantWeakReadService23generate_server_versionElb -_Z14ob_malloc_hookmPKv -_Z15ob_malloc_retrym -_ZN9oceanbase6common9ob_mallocElRKNS_3lib9ObMemAttrE -_ZN9oceanbase5obrpc18ObRpcProcessorBase16check_cluster_idEv -_ZN9oceanbase10logservice13ObApplyStatus19get_max_applied_scnERNS_5share3SCNE -_ZN9oceanbase3lib11ObLockGuardINS0_7ObMutexEEC2ERS2_ -_ZZN9oceanbase10logservice23ObApplyServiceQueueTask22is_snapshot_apply_doneERbENK3$_5clEPKc -_ZN9oceanbase10logservice13ObApplyStatus22update_last_check_scn_Ev -_ZN9oceanbase6common20ObQSyncLockReadGuardD2Ev -_ZN9oceanbase6common11ObArrayImplINS_5share8detector12ObLCLMessageENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEE7destroyEv -_ZNK9oceanbase5share6schema19ObSchemaGetterGuard18get_schema_versionEmRl -_ZN9oceanbase5obrpc15ObTransRpcProxy19post_keep_alive_msgERKNS_11transaction16ObTxKeepaliveMsgEPNS0_10ObRpcProxy7AsyncCBINS1_5ObRpcILNS0_15ObRpcPacketCodeE1626EvEEEERKNS0_9ObRpcOptsE -_ZN9oceanbase12blocksstable15ObEmptyReadCell13inc_and_fetchEmRm -_ZN9oceanbase6common13ObSharedGuardINS_7storage12ObLSIteratorEED2Ev -_ZN9oceanbase6common13ObSharedGuardINS_7storage12ObLSIteratorEE5resetEv -_ZN9oceanbase7storage12ObLSIterator5resetEv -_ZN9oceanbase8observer20ObInnerSQLConnection12execute_readEmPKcRNS_6common12ObISQLClient10ReadResultEbPKNS4_6ObAddrE +_ZN9oceanbase3sql20ObDblinkCtxInSession21free_dblink_conn_poolEv +_ZN9oceanbase6common16ObClockGenerator4run1Ev +_ZN9oceanbase3sql10ObSQLUtils21clear_expr_eval_flagsERKNS0_6ObExprERNS0_9ObEvalCtxE +_ZN9oceanbase6common15ObBaseLogWriter9flush_logEv +_ZN9oceanbase6common15ObBaseLogWriter12do_flush_logEv +_ZN9oceanbase12blocksstable18ObIMicroBlockCache8prefetchEmRKNS0_12MacroBlockIdERKNS0_16ObMicroIndexInfoERKNS_6common11ObQueryFlagERNS0_18ObMacroBlockHandleE +_ZN9oceanbase12blocksstable18ObMacroBlockHandle10async_readERKNS0_20ObMacroBlockReadInfoE +_ZN9oceanbase12blocksstable18ObMacroBlockHandle18set_macro_block_idERKNS0_12MacroBlockIdE +_ZN9oceanbase6common11ObIOManager8aio_readERKNS0_8ObIOInfoERNS0_10ObIOHandleE +_ZN9oceanbase6common11ObIOManager10tenant_aioERKNS0_8ObIOInfoERNS0_10ObIOHandleE +_ZN9oceanbase6common11ObIORequest4initERKNS0_8ObIOInfoE +_ZNK9oceanbase12blocksstable28ObSingleMicroBlockIOCallback15inner_deep_copyEPclRPNS_6common12ObIOCallbackE +_ZN9oceanbase6common11ObIOManager21get_tenant_io_managerEmRNS0_11ObRefHolderINS0_17ObTenantIOManagerEEE +_ZN9oceanbase6common10ObIOSender15enqueue_requestERNS0_11ObIORequestE +_ZN9oceanbase6common13ObMClockQueue13push_phyqueueEPNS0_10ObPhyQueueE +_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImPNS0_15ObIOGroupQueuesEEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS6_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS6_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14get_refactoredERKmRS6_l +_ZN9oceanbase6common13ObIOAllocator5allocEl +_ZN9oceanbase6common15ObTenantIOClock19calc_phyqueue_clockEPNS0_10ObPhyQueueERKNS0_11ObIORequestE +_ZN9oceanbase6common15ObIOCalibration14get_iops_scaleENS0_8ObIOModeElRdRb +_ZN9oceanbase6common7DRWLock11RDLockGuardD2Ev +_ZN9oceanbase5obrpc24ObPocServerHandleContext4respEPNS0_11ObRpcPacketE +_ZN9oceanbase5obrpc17ObRpcPacketHeader9serializeEPclRl +pkts_resp +_ZN9oceanbase3sql13ObTableScanOp18inner_get_next_rowEv +_ZZN9oceanbase4palf10PalfHandle23unregister_file_size_cbEvENK5$_877clEPKc.llvm.447907550136452219 +_ZN9oceanbase3sql18ObBasicSessionInfo20set_query_start_timeEl +_ZN9oceanbase6common15ObLinearHashMapINS0_10ObTabletIDENS_7storage3mds4ListINS4_12MdsTableBaseEEENS0_14ShareMemMgrTagEE16do_foreach_scan_IZNS4_18ObTenantMdsService24for_each_mds_table_in_lsERNS3_4ObLSERKNS0_10ObFunctionIFiRNS3_8ObTabletEEEEE5$_111NS9_14DoForeachOnBktISL_EEEEbmmRT_RT0_ +_ZZN9oceanbase7storage3mds18ObTenantMdsService24for_each_mds_table_in_lsERNS0_4ObLSERKNS_6common10ObFunctionIFiRNS0_8ObTabletEEEEENK5$_111clERKNS5_10ObTabletIDERNS1_4ListINS1_12MdsTableBaseEEE +_ZN9oceanbase12blocksstable10ObRowQueue9alloc_rowERPNS0_10ObDatumRowERNS_6common12ObIAllocatorE +_ZN9oceanbase12blocksstable10ObDatumRow4initERNS_6common12ObIAllocatorElPc +_ZN9oceanbase6common2SVINS_8observer16ObInnerSQLResultELb0EEC2IZNS2_20ObInnerSQLConnection23start_transaction_innerERKmbE5$_204EEibOT_ +_ZN9oceanbase12blocksstable20ObServerBlockManager12get_instanceEv +_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE11ELS3_0EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE +_ZN9oceanbase6common16ObAsyncIOChannel4run1Ev +_ZN9oceanbase6common17ObTenantIOManager16enqueue_callbackERNS0_11ObIORequestE +trace_cache_buckets +_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE16do_foreach_scan_INS4_18ObLogReplayService15FetchLogFunctorENS8_14DoForeachOnBktISB_EEEEbmmRT_RT0_ +_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE16load_access_bkt_EmRPNS8_6BucketE +_ZNK9oceanbase7storage16ObTxDataCacheKey4hashEv +_ZN9oceanbase6common21ObDetectManagerThread6detectEv +_ZNK9oceanbase5share27ObTabletReplicaFilterHolder5checkERKNS0_15ObTabletReplicaERb +_ZNK9oceanbase5share6schema11ObSchemaMgr31get_table_schemas_in_tablegroupEmmRNS_6common8ObIArrayIPKNS1_21ObSimpleTableSchemaV2EEE +_ZN9oceanbase6common20ObNullSafeDatumTCCmpILNS0_14ObObjTypeClassE2ELS2_2ELb1EE3cmpERKNS0_7ObDatumES6_Ri _ZN9oceanbase6common13ObLinkHashMapINS_3sql14SessionInfoKeyENS2_16ObSQLSessionInfoENS2_15ObSQLSessionMgr10ValueAllocENS0_9RefHandleELl8EE3mapINS8_8HandleOnINS5_19CheckSessionFunctorEEEEEiRT_ _ZN9oceanbase6common13ObLinkHashMapINS_3sql14SessionInfoKeyENS2_16ObSQLSessionInfoENS2_15ObSQLSessionMgr10ValueAllocENS0_9RefHandleELl8EE8HandleOnINS5_19CheckSessionFunctorEEclERS3_PS4_ -_ZN9oceanbase6common13ObLinkHashMapINS_3sql14SessionInfoKeyENS2_16ObSQLSessionInfoENS2_15ObSQLSessionMgr10ValueAllocENS0_9RefHandleELl8EE8dec_urefEPNS0_12LinkHashNodeIS3_EE -_ZN9oceanbase3sql18ObBasicSessionInfo10is_timeoutERb _ZN9oceanbase3sql18ObBasicSessionInfo14try_lock_queryEv -_ZN9oceanbase3sql18ObBasicSessionInfo20try_lock_thread_dataEv -_ZN9oceanbase3sql18ObBasicSessionInfo20set_query_start_timeEl -_ZNK9oceanbase8observer16ObInnerSQLResult11get_varcharEPKcRNS_6common8ObStringE -_ZNK9oceanbase8observer16ObInnerSQLResult11get_varcharElRNS_6common8ObStringE -_ZN9oceanbase4palf10PalfHandle21unregister_rebuild_cbEv -_ZZN9oceanbase4palf10PalfHandle21unregister_rebuild_cbEvENK5$_884clEPKc.llvm.2452046906557810875 -_ZN9oceanbase6common4hash11ObHashTableIlNS1_11HashMapPairIllEENS1_9hash_funcIlEENS1_8equal_toIlEENS1_10pair_firstIS4_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS4_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv -_ZN9oceanbase11transaction15ObTransHashLinkINS0_10ObTransCtxEE7inc_refEi -_ZN9oceanbase6common13ObSEArrayImplINS_4palf3LSNELl10ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase10logservice11coordinator14RefeshPriorityclINS1_10PriorityV1EEEiRT_ -_ZN9oceanbase10logservice11coordinator10PriorityV18refresh_ERKNS_5share6ObLSIDE -_ZN9oceanbase6common5occam26ObOccamTimeGuardDetectHung5clickEt -_ZN9oceanbase10logservice11coordinator17ObFailureDetector25get_specified_level_eventENS1_12FailureLevelERNS_6common8ObIArrayINS1_12FailureEventEEE -_ZZN9oceanbase10logservice11coordinator10PriorityV18get_scn_ERKNS_5share6ObLSIDERNS3_3SCNEENK5$_234clEPKc -_ZN9oceanbase6common15ObLinearHashMapINS_10logservice18ServerProbeService11ServerLSKeyENS3_10LSProbeCtxENS0_14ShareMemMgrTagEE16do_foreach_scan_IZNS3_15run_probe_once_EvE5$_746NS7_14DoForeachOnBktIS9_EEEEbmmRT_RT0_ -_ZN9oceanbase3sql11ObDASLockOpD2Ev -_ZNK9oceanbase6common13ObIKVCacheKey5equalERKS1_Rb -_ZN9oceanbase5share17ObTenantDagWorker4run1Ev -_ZN9oceanbase6common12ObThreadCond7wait_usEm -ob_pthread_cond_timedwait -_ZN9oceanbase6common16ObWaitEventGuardC1Elmlllb -_ZN9oceanbase6common16ObWaitEventGuardC2Elmlllb -_ZN9oceanbase3sql16ObHashDistinctOp7destroyEv -_ZN9oceanbase3sql29ObTenantCachedSchemaGuardInfo27refresh_tenant_schema_guardEm -_ZN9oceanbase6common16ObKVCacheInstMap20print_all_cache_infoEv -_ZN9oceanbase6common16ObKVCacheInstMap23print_tenant_cache_infoEm +_ZN9oceanbase3sql18ObBasicSessionInfo10is_timeoutERb +_ZN9oceanbase3sql18ObBasicSessionInfo18unlock_thread_dataEv +_ZN9oceanbase6common9Ob2DArrayINS0_10ObObjParamELi2079744ENS0_18ObWrapperAllocatorELb0ENS0_9ObSEArrayIPS2_Ll1ES3_Lb0EEEED2Ev +_ZN9oceanbase6common15ObLinearHashMapINS_5share8detector20ObDependencyResourceENS3_12ObLCLMessageENS0_14ShareMemMgrTagEE8es_lock_Ev +_ZN9oceanbase6common15ObLinearHashMapINS_10logservice18ServerProbeService11ServerLSKeyENS3_10LSProbeCtxENS0_14ShareMemMgrTagEE20unset_foreach_L_lmt_Em +_ZN9oceanbase7storage18ObTenantMetaMemMgr18gc_tables_in_queueERb +_ZN9oceanbase6common5occam17ObOccamThreadPool30keep_fetching_task_until_stop_Em +_ZN9oceanbase6common5occam17ObOccamThreadPool14InnerTaskQueue8pop_taskERNS0_10ObFunctionIFvvEEEl +_ZN9oceanbase3lib11ObLockGuardINS_6common12ObThreadCondEEC2ERS3_ +_ZN9oceanbase12blocksstable12MacroBlockId11deserializeEPKclRl +_ZNK9oceanbase8observer16ObInnerSQLResult8get_uintEPKcRm +_ZNK9oceanbase8observer16ObInnerSQLResult8get_uintElRm +_ZN9oceanbase12blocksstable9ObSSTableD1Ev +_ZN9oceanbase12blocksstable9ObSSTableD2Ev +_ZN9oceanbase5obrpc15ObPocClientStub4postINS_11transaction16ObTxKeepaliveMsgENS0_10ObRpcProxy7AsyncCBINS0_15ObTransRpcProxy5ObRpcILNS0_15ObRpcPacketCodeE1626EvEEEEEEiRS5_RKNS_6common6ObAddrES9_RKT_PT0_RKNS0_9ObRpcOptsE +_ZN9oceanbase6common13serialization19encoded_length_vi64El +_ZN9oceanbase5obrpc19ObAsyncRespCallback6createERNS0_12ObRpcMemPoolEPNS_3rpc5frame14ObReqTransport7AsyncCBE +pn_send +cfifo_alloc +_ZNK9oceanbase5obrpc8LogRpcCBILNS0_15ObRpcPacketCodeE5386EE5cloneERKNS_3rpc5frame7SPAllocE +_ZNK9oceanbase5obrpc9ObTxRPCCBILNS0_15ObRpcPacketCodeE1628EE5cloneERKNS_3rpc5frame7SPAllocE +_ZN9oceanbase5obrpc14rpc_encode_reqINS_11transaction16ObTxKeepaliveMsgEEEiRNS0_10ObRpcProxyERNS0_12ObRpcMemPoolENS0_15ObRpcPacketCodeERKT_RKNS0_9ObRpcOptsERPcRlbbbl +_ZN9oceanbase5obrpc23calc_extra_payload_sizeEv +_ZNK9oceanbase5obrpc10ObRpcProxy8init_pktEPNS0_11ObRpcPacketENS0_15ObRpcPacketCodeERKNS0_9ObRpcOptsEb +_ZN9oceanbase6common12ObCurTraceId7TraceId4initERKNS0_6ObAddrE +_ZNK9oceanbase11transaction7ObTxMsg19get_serialize_size_Ev +_ZN9oceanbase6common10ObIOSender4run1Ev +_ZN9oceanbase6common13ObMClockQueue16remove_from_heapEPNS0_10ObPhyQueueE +_ZN9oceanbase6common15ObRemovableHeapIPNS0_10ObPhyQueueENS0_13ObMClockQueue11HeapCompareIS2_XadL_ZNS2_15reservation_ts_EEEEEXadL_ZNS2_16reservation_pos_EEELl50EE15remove_by_indexEl +_ZN9oceanbase6common10ObIOSender6submitERNS0_11ObIORequestE +_ZN9oceanbase6common15ObDeviceChannel6submitERNS0_11ObIORequestE +_ZN9oceanbase6common16ObAsyncIOChannel6submitERNS0_11ObIORequestE +_ZN9oceanbase6common11ObIOManager18get_device_channelEPKNS0_10ObIODeviceERPNS0_15ObDeviceChannelE +_ZN9oceanbase5share13ObLocalDevice9io_submitEPNS_6common11ObIOContextEPNS2_6ObIOCBE +_ZN9oceanbase6common11ObIORequest7prepareEv +_ZN9oceanbase5share13ObLocalDevice16io_prepare_preadERKNS_6common6ObIOFdEPvmlPNS2_6ObIOCBES6_ +_ZN9oceanbase5share13ObLocalDevice10alloc_iocbEv +_ZN9oceanbase6common11ObIORequest12alloc_io_bufEv _ZN9oceanbase7storage8ObTablet28get_kept_multi_version_startERNS0_4ObLSERKS1_Rl _ZN9oceanbase7storage23ObLSReservedSnapshotMgr25get_min_reserved_snapshotEv -_ZN9oceanbase6common16ObArenaAllocatorD2Ev -_ZNK9oceanbase7storage8ObTablet23get_min_medium_snapshotERl +_ZN9oceanbase7storage24ObTabletMediumInfoReader23get_min_medium_snapshotERl _ZN9oceanbase7storage15ObStorageSchemaD1Ev _ZN9oceanbase7storage15ObStorageSchemaD2Ev -_ZNK9oceanbase7storage8ObTablet22get_msd_from_memtablesERNS_8memtable22ObIMultiSourceDataUnitEPNS_6common12ObIAllocatorEb -_ZNK9oceanbase7storage8ObTablet13get_memtablesERNS_6common8ObIArrayIPNS0_8ObITableEEEb -_ZN9oceanbase5obrpc14ObNetKeepAlive8in_blackERK11easy_addr_tRbPNS0_18ObNetKeepAliveDataE -_ZN9oceanbase5obrpc10ObBatchRpc4run1Ev -_ZN9oceanbase5obrpc14ObBatchRpcBase7do_workEv -_ZN9oceanbase6common10FixedHash2INS_5obrpc11ObRpcBufferEE10quick_nextEPS3_ -_ZN9oceanbase5obrpc15ObRingRpcBuffer4readERlRPcS2_b -_ZN9oceanbase6common13ObLinkHashMapINS_3sql14SessionInfoKeyENS2_16ObSQLSessionInfoENS2_15ObSQLSessionMgr10ValueAllocENS0_9RefHandleELl8EE8HandleOnINS_5share20ObActiveSessHistTaskEEclERS3_PS4_ -_ZN9oceanbase6common15ObBlockAllocMgr11alloc_blockElRNS_3lib9ObMemAttrE -_ZN9oceanbase6common17ObjHashCalculatorILNS0_9ObObjTypeE5ENS0_13ObDefaultHashENS0_5ObObjEE15calc_hash_valueERKS4_mRm -_ZN9oceanbase3sql16ObPlanCacheValue24check_dep_schema_versionERKNS_6common8ObIArrayINS0_12PCVSchemaObjEEERKNS3_IPS4_EERb -_ZNK9oceanbase12blocksstable12ObRawDecoder6decodeERNS0_18ObColumnDecoderCtxERNS_6common5ObObjElRKNS0_11ObBitStreamEPKcl -_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE16do_foreach_scan_INS4_26GetPendingFreeBlockFunctorENS7_14DoForeachOnBktIS9_EEEEbmmRT_RT0_ -_ZN9oceanbase6common6ObAddr11set_ip_addrEPKci -_ZNK9oceanbase6common12ObTimeoutCtx12is_timeoutedEv -_ZN9oceanbase6common11ObArrayImplINS_5share11ReplicaAttrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev -_ZN9oceanbase6common8ObString10assign_ptrEPKcl -_ZN9oceanbase7storage16ObTxCtxTableInfo5resetEv -_ZN9oceanbase5share6schema19ObSchemaGetterGuard23get_simple_table_schemaEmmRKNS_6common8ObStringEbRPKNS1_21ObSimpleTableSchemaV2Eb -_ZNK9oceanbase5share6schema11ObSchemaMgr16get_table_schemaEmmmRKNS_6common8ObStringERPKNS1_21ObSimpleTableSchemaV2E -_ZNK9oceanbase6common4hash16ObPointerHashMapINS_5share6schema24ObTableSchemaHashWrapperEPNS4_21ObSimpleTableSchemaV2ENS4_13GetTableKeyV2ELl8064ENS0_19ModulePageAllocatorEE14get_refactoredERKS5_RS7_ -_ZN9oceanbase5share6schema17ObSysTableChecker20check_sys_table_nameEmmRKNS_6common8ObStringERb -_ZNK9oceanbase5share6schema17ObSysTableChecker16TableNameWrappereqERKS3_ -_ZZN9oceanbase5share6schema17ObSysTableChecker20check_sys_table_nameEmmRKNS_6common8ObStringERbENK6$_2106clEPKc -_ZN9oceanbase6common18ObWaitEventHistory4pushElmmmm -_ZNK9oceanbase3omt17ObTenantConfigMgr18read_tenant_configEmmRKSt8functionIFvRKNS0_14ObTenantConfigEEERKS2_IFvvEE -_ZN9oceanbase6common7DRWLock11RDLockGuardD2Ev -_ZN9oceanbase3omt17ObTenantConfigMgr12get_instanceEv -_ZN9oceanbase6common11DefHashFuncINS0_19DatumHashCalculatorILNS0_9ObObjTypeE5ENS0_12ObMurmurHashEEEE4hashERKNS0_7ObDatumEmRm -_ZN9oceanbase8observer24ObInnerSQLConnectionPool26remove_from_used_conn_listEPNS0_20ObInnerSQLConnectionE -_ZN9oceanbase6common16copy_assign_wrapINS0_9ObSEArrayINS_5share12SimpleMemberELl7ENS0_15ObNullAllocatorELb0EEEEEiRT_RKS7_NS0_8BoolTypeILb0EEE -_ZN9oceanbase7storage18ObLSTabletIterator15get_next_tabletERNS0_14ObTabletHandleE -_ZN9oceanbase3lib17ObTenantMemoryMgr11alloc_chunkElRKNS0_9ObMemAttrE -_ZN9oceanbase3lib9AChunkMgr11alloc_chunkEmb -_ZZN9oceanbase10logservice20ObArbitrationService9run_loop_EvENK5$_693clEPKc -_ZN9oceanbase4palf7PalfEnv5closeERNS0_10PalfHandleE -_ZZN9oceanbase4palf10PalfHandle25unregister_role_change_cbEvENK5$_879clEPKc.llvm.2452046906557810875 -_ZN9oceanbase8observer20ObInnerSQLConnection18execute_read_innerElmRKNS_6common8ObStringERNS2_12ObISQLClient10ReadResultEbPKNS2_6ObAddrE +_ZN9oceanbase7storage15ObStorageSchema5resetEv +_ZN9oceanbase6common16ObFixedArrayImplINS_7storage27ObStorageRowkeyColumnSchemaENS0_12ObIAllocatorEE7destroyEv +_ZN9oceanbase5obrpc14ObNetKeepAlive4run1Ev +_ZN9oceanbase5share25_make_tenant_switch_guardEv +_ZN9oceanbase6common6ObListINS0_12ObSpatialMBRENS0_12ObIAllocatorEED2Ev +_ZN9oceanbase8observer20ObInnerSQLConnection19execute_write_innerEmRKNS_6common8ObStringERlbPKNS2_6ObAddrE +_ZN9oceanbase6common2SVINS_8observer16ObInnerSQLResultELb0EED2Ev _ZNK9oceanbase3omt13ObMultiTenant19is_available_tenantEm -_ZN9oceanbase8observer16ObInnerSQLResultC2ERNS_3sql16ObSQLSessionInfoE -_ZN9oceanbase3lib15CompatModeGuardD2Ev -_ZN9oceanbase3sql18ObBasicSessionInfo20set_session_in_retryENS0_20ObSessionRetryStatusE -_ZN9oceanbase6common14ObMaxWaitGuardD1Ev +_ZN9oceanbase3omt8ObTenant17get_create_statusEv _ZN9oceanbase3omt8ObTenant8get_unitEv +_ZN9oceanbase3sql8ObSqlCtxD2Ev +_ZN9oceanbase6common14SpinRLockGuardD2Ev +_ZN9oceanbase6common12TCRLockGuardD2Ev +_ZN9oceanbase3sql8ObSqlCtx5resetEv +_ZN9oceanbase8observer16ObInnerSQLResultD2Ev +_ZN9oceanbase8observer16ObInnerSQLResult5closeEv +_ZN9oceanbase8observer16ObInnerSQLResult21MemEntifyDestroyGuardD2Ev +_ZN9oceanbase6common16ObFixedArrayImplINS_3sql18ObDupTabConstraintENS0_12ObIAllocatorEED2Ev +_ZN9oceanbase6common16ObFixedArrayImplINS_3sql18LocationConstraintENS0_12ObIAllocatorEED2Ev +_ZN9oceanbase6common16ObFixedArrayImplINS0_8ObStringENS0_12ObIAllocatorEED2Ev +_ZN9oceanbase6common4hash9ObHashMapINS0_8ObStringElNS1_19NoPthreadDefendModeENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairIS3_lEEEELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_13NormalPointerENS0_8ObMallocELl1EED2Ev +_ZN9oceanbase6common4hash11ObHashTableINS0_8ObStringENS1_11HashMapPairIS3_lEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv +_ZN9oceanbase6common8ObMalloc4freeEPv +_ZN9oceanbase3sql13ObSpmCacheCtxD2Ev +_ZN9oceanbase6common16ObFixedArrayImplIPNS_3sql20ObTablePartitionInfoENS0_12ObIAllocatorEED2Ev +_ZN9oceanbase8observer16ObInnerSQLResult11inner_closeEv +_ZN9oceanbase5share19ObTenantSwitchGuard9switch_toEPNS0_12ObTenantBaseE _ZN9oceanbase5share12ObUnitConfigC1ERKS1_ -_ZN9oceanbase8observer20ObInnerSQLConnection5queryERNS_6common9sqlclient11ObIExecutorERNS0_16ObInnerSQLResultEPNS0_29ObVirtualTableIteratorFactoryE -_ZNK9oceanbase8observer20ObInnerSQLTimeRecord28get_single_process_timestampEv -_ZNK9oceanbase8observer20ObInnerSQLTimeRecord17get_run_timestampEv -_ZN9oceanbase8observer20ObInnerSQLConnection12TimeoutGuardD2Ev -_ZN9oceanbase8observer20ObInnerSQLConnection11set_timeoutERl -_ZN9oceanbase8observer20ObInnerSQLConnection19set_session_timeoutEll -_ZN9oceanbase8observer20ObInnerSQLConnection12TimeoutGuardC2ERS1_ -_ZN9oceanbase6common20check_stack_overflowERblPl -_ZN9oceanbase8observer20ObInnerSQLConnection8do_queryERNS_6common9sqlclient11ObIExecutorERNS0_16ObInnerSQLResultE -_ZN9oceanbase3lib2_SILNS0_13ContextSourceE0EEC2EbRNS0_13MemoryContextE -_ZN9oceanbase3sql18ObBasicSessionInfo19update_sys_variableENS_5share17ObSysVarClassTypeERKNS_6common5ObObjE -_ZN9oceanbase3sql18ObBasicSessionInfo13SysVarIncInfo14add_sys_var_idENS_5share17ObSysVarClassTypeE -_ZN9oceanbase6common9ObDFMUtil14check_semanticERKNS0_8ObIArrayINS0_9ObDFMElemEEERNS0_13ObFixedBitSetILl64EEEm -_ZN9oceanbase6common13ObSEArrayImplINS_5share17ObSysVarClassTypeELl64ENS0_19ModulePageAllocatorELb0EE9push_backERKS3_ -_ZN9oceanbase3sql18ObBasicSessionInfo22deep_copy_sys_variableERNS_5share13ObBasicSysVarENS2_17ObSysVarClassTypeERKNS_6common5ObObjE -_ZN9oceanbase3sql18ObBasicSessionInfo30process_session_sql_mode_valueERKNS_6common5ObObjE -_ZN9oceanbase8observer20ObInnerSQLConnection18ObSqlQueryExecutor7executeERNS_3sql5ObSqlERNS3_8ObSqlCtxERNS3_11ObResultSetE -_ZNK9oceanbase3lib6Worker10is_timeoutEv -_ZN9oceanbase6common12ob_write_objINS0_9PageArenaIcNS0_19ModulePageAllocatorEEEEEiRT_RKNS0_5ObObjERS7_ -_ZN9oceanbase8observer16ObInnerSQLResult4openEv _ZN9oceanbase3sql12ObExecRecord10record_endEPNS_6common21ObDiagnoseSessionInfoE -_ZN9oceanbase5share6schema27ObMultiVersionSchemaService23get_tenant_schema_guardEmRNS1_19ObSchemaGetterGuardEllNS2_17RefreshSchemaModeE -_ZN9oceanbase5share6schema27ObMultiVersionSchemaService19add_schema_mgr_infoERNS1_19ObSchemaGetterGuardEPNS1_13ObSchemaStoreERKNS1_21ObRefreshSchemaStatusEmllNS2_17RefreshSchemaModeE -_ZN9oceanbase5share6schema16ObSchemaMgrCache3getElRPKNS1_11ObSchemaMgrERNS1_17ObSchemaMgrHandleE -_ZN9oceanbase8observer20ObInnerSQLConnection13process_finalINS_6common9sqlclient11ObIExecutorEEEiRKT_RNS0_16ObInnerSQLResultEi -_ZN9oceanbase6common14ObMaxWaitGuardC1EPNS0_15ObWaitEventDescEPNS0_21ObDiagnoseSessionInfoE -_ZN9oceanbase8observer20ObInnerSQLConnection14process_recordERNS_3sql11ObResultSetERNS2_8ObSqlCtxERNS2_16ObSQLSessionInfoERNS0_13ObITimeRecordEillRNS_6common15ObWaitEventDescERNSB_15ObWaitEventStatERNS2_12ObExecRecordERNS2_15ObExecTimestampEbRKNSB_8ObStringEb -_ZN9oceanbase3sql10ObSQLUtils19handle_audit_recordEbNS0_13ObExecuteModeERNS0_16ObSQLSessionInfoEb -_ZN9oceanbase11transaction7ObTsMgr12get_instanceEv -_ZN9oceanbase11transaction7ObTsMgr22is_external_consistentEm -_ZN9oceanbase11transaction7ObTsMgr22revert_ts_source_info_ERNS0_19ObTsSourceInfoGuardE -_ZN9oceanbase3sql18ObBasicSessionInfo18store_query_stringERKNS_6common8ObStringE -_ZN9oceanbase5share6schema27ObMultiVersionSchemaService27get_baseline_schema_versionEmbRl -_ZN9oceanbase5share6schema19ObSchemaGetterGuard17get_tenant_statusEmRNS1_14ObTenantStatusE -_ZN9oceanbase3sql18ObBasicSessionInfo19store_query_string_ERKNS_6common8ObStringE -_ZN9oceanbase8observer16ObInnerSQLResult4initEb -_ZN9oceanbase3sql11ObResultSetC2ERNS0_16ObSQLSessionInfoERNS_6common12ObIAllocatorE -_ZN9oceanbase3sql13ObExecContextC1ERNS_6common12ObIAllocatorE -_ZN9oceanbase3sql13ObExecContextC2ERNS_6common12ObIAllocatorE -_ZN9oceanbase3sql18ObBasicSessionInfo40process_session_compatibility_mode_valueERKNS_6common5ObObjE -_ZN9oceanbase6common17ObKVStoreMemBlockD2Ev -easy_hash_code -_ZN9oceanbase3sql20ObSecurityAuditUtils17check_allow_auditERNS0_16ObSQLSessionInfoERNS0_16ObAuditTrailTypeE +_ZN9oceanbase6common4hash13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairINS0_8ObStringElEEEELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEE4freeEPS7_ +_ZN9oceanbase6common19ObFixedLengthStringILl128EE6assignERKS2_ +_ZN9oceanbase7storage13ObVectorStore9fill_rowsElPNS_12blocksstable19ObIMicroBlockReaderERllPKNS_6common8ObBitmapE +_ZN9oceanbase12blocksstable18ObMicroBlockReader8get_rowsERKNS_6common8ObIArrayIiEERKNS3_IPKNS_5share6schema13ObColumnParamEEERKNS3_INS2_17ObObjDatumMapTypeEEERKNS0_10ObDatumRowEPKllRSJ_RNS3_IPNS2_7ObDatumEEERNS2_12ObFixedArrayIPNS_3sql6ObExprENS2_12ObIAllocatorEEERNSU_9ObEvalCtxE _ZN9oceanbase3sql17ObPhysicalPlanCtxD1Ev _ZN9oceanbase3sql17ObPhysicalPlanCtxD2Ev -_ZN9oceanbase6common13ObSEArrayImplIPcLl1ENS0_19ModulePageAllocatorELb1EED2Ev _ZN9oceanbase6common9Ob2DArrayINS_3sql15ObDatumObjParamELi2079744ENS0_18ObWrapperAllocatorELb0ENS0_9ObSEArrayIPS3_Ll1ES4_Lb0EEEED2Ev _ZN9oceanbase6common16ObFixedArrayImplINS_3sql17PartParamIdxArrayENS0_12ObIAllocatorEED2Ev -_ZN9oceanbase3sql17ObChunkDatumStore8Iterator12get_next_rowERKNS_6common8ObIArrayIPNS0_6ObExprEEERNS0_9ObEvalCtxEPPKNS1_9StoredRowE -_ZN9oceanbase3sql17ObChunkDatumStore8Iterator12get_next_rowERPKNS1_9StoredRowE -_ZN9oceanbase6common21ObDiagnoseSessionInfo15notify_wait_endEPNS0_20ObDiagnoseTenantInfoEb -_ZN9oceanbase5share20ObAllTenantInfoProxy16load_tenant_infoEmPNS_6common12ObISQLClientEbRNS0_15ObAllTenantInfoE -_ZNK9oceanbase11transaction30ObTenantWeakReadClusterService18check_leader_info_ERl -_ZN9oceanbase10logservice12ObLogService13get_palf_roleERKNS_5share6ObLSIDERNS_6common6ObRoleERl -_ZNK9oceanbase5share24ObVTableLocationCacheKey4hashEv -_ZN9oceanbase4palf14PalfHandleImpl4statERNS0_8PalfStatE -_ZNK9oceanbase4palf12LSNAllocator11get_max_scnEv -_ZNK9oceanbase4palf9LogEngine12get_log_metaEv -_ZN9oceanbase4palf13LogConfigInfoaSERKS1_ -_ZN9oceanbase4palf13LogConfigInfoC1Ev -_ZN9oceanbase4palf13LogConfigInfoC2Ev -_ZN9oceanbase4palf7LogMetaD1Ev -_ZN9oceanbase4palf7LogMetaD2Ev -_ZN9oceanbase4palf13LogConfigInfoD1Ev -_ZN9oceanbase4palf13LogConfigInfoD2Ev -_ZN9oceanbase6common13ObSEArrayImplINS0_8ObMemberELl7ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase4palf13LogConfigMeta5resetEv -time_update -_ZN9oceanbase6common15ObLinearHashMapINS_5share14ObCascadMemberENS2_15ObDstServerInfoENS0_14ShareMemMgrTagEE16do_foreach_scan_INS2_17ObServerBlacklist19ObMapSendReqFunctorENS6_14DoForeachOnBktIS9_EEEEbmmRT_RT0_ -_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE2ELS3_2EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE -_ZN9oceanbase6common4hash19ObHashTableIteratorIlNS1_11HashMapPairIllEENS1_9hash_funcIlEENS1_8equal_toIlEENS1_10pair_firstIS4_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS4_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EEppEv -_UIx86_64__mempool_alloc +_ZN9oceanbase4palf13LogConfigMetaD1Ev +_ZN9oceanbase4palf13LogConfigMetaD2Ev +_ZN9oceanbase6common15BaseLearnerListILl2000ENS0_8ObMemberEED2Ev +_ZN9oceanbase10rootserver14ObThreadIdling4idleEl +_ZN9oceanbase3sql16ObConfigInfoInPC17serialize_configsEPciRl +_ZN9oceanbase7storage23ObTenantTabletScheduler23schedule_ls_minor_mergeERNS0_10ObLSHandleERl +_ZN9oceanbase7storage23ObTenantTabletScheduler31schedule_tablet_ddl_major_mergeERNS0_14ObTabletHandleE +_ZN9oceanbase7storage23ObTenantTabletScheduler27schedule_tablet_minor_mergeINS_10compaction23ObTabletMergeExecuteDagEEEiRNS0_10ObLSHandleERNS0_14ObTabletHandleE +_ZN9oceanbase6common11ObArrayImplINS_7storage15ObTableHandleV2ENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev +_ZN9oceanbase6common11ObArrayImplINS_7storage15ObTableHandleV2ENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE7destroyEv +_ZN9oceanbase10compaction22ObPartitionMergePolicy27get_hist_minor_merge_tablesERKNS_7storage21ObGetMergeTablesParamERNS2_4ObLSERKNS2_8ObTabletERNS2_22ObGetMergeTablesResultE +_ZN9oceanbase10compaction22ObPartitionMergePolicy22get_minor_merge_tablesERKNS_7storage21ObGetMergeTablesParamERNS2_4ObLSERKNS2_8ObTabletERNS2_22ObGetMergeTablesResultE +_ZN9oceanbase6common11ObDebugSync8instanceEv +_ZN9oceanbase10compaction22ObPartitionMergePolicy29get_boundary_snapshot_versionERKNS_7storage8ObTabletERlS6_b +_ZNK9oceanbase7storage8ObTablet23get_max_sync_medium_scnERl +_ZNK9oceanbase7storage8ObTablet17fetch_table_storeERNS0_21ObTabletMemberWrapperINS0_18ObTabletTableStoreES3_EE +_ZN9oceanbase10compaction22ObPartitionMergePolicy23find_minor_merge_tablesERKNS_7storage21ObGetMergeTablesParamEllRNS2_4ObLSERKNS2_8ObTabletERNS2_22ObGetMergeTablesResultE +_ZN9oceanbase12blocksstable9ObSSTable7dec_refEv +_ZNK9oceanbase7storage8ObTablet23get_mini_minor_sstablesERNS0_20ObTableStoreIteratorE +_ZNK9oceanbase7storage18ObTabletTableStore23get_mini_minor_sstablesEbRNS0_20ObTableStoreIteratorE +_ZN9oceanbase3omt17ObTenantConfigMgr26default_fallback_tenant_idEv +_ZN9oceanbase3omt17ObTenantConfigMgr12get_instanceEv +_ZN9oceanbase10compaction22ObPartitionMergePolicy25refine_minor_merge_tablesERKNS_7storage8ObTabletERKNS2_19ObTablesHandleArrayERlS9_ +_ZN9oceanbase7storage19ObTablesHandleArrayD1Ev +_ZN9oceanbase10compaction22ObPartitionMergePolicy25get_neighbour_freeze_infoElPKNS_7storage8ObITableERNS2_21ObTenantFreezeInfoMgr19NeighbourFreezeInfoE +_ZN9oceanbase7storage19ObFastFreezeChecker22check_need_fast_freezeERKNS0_8ObTabletERb +_ZNK9oceanbase7storage8ObTablet19get_active_memtableERNS0_15ObTableHandleV2E +_ZNK9oceanbase7storage8ObTablet16get_memtable_mgrERPNS0_14ObIMemtableMgrE +_ZNK9oceanbase7storage19ObTabletMemtableMgr19get_active_memtableERNS0_15ObTableHandleV2E +_ZN9oceanbase7storage20ObTableStoreIterator8get_nextERNS0_15ObTableHandleV2E +_ZNK9oceanbase7storage19ObStorageMetaHandle8is_validEv +_ZNK9oceanbase7storage19ObTabletMemtableMgr20get_active_memtable_ERNS0_15ObTableHandleV2E +_ZN9oceanbase7storage15ObTableHandleV217get_data_memtableERPNS_8memtable10ObMemtableE +_ZN9oceanbase10compaction22ObPartitionMergePolicy21deal_hist_minor_mergeERKNS_7storage8ObTabletERl +_ZN9oceanbase10compaction22ObPartitionMergePolicy25refine_minor_merge_resultElRNS_7storage22ObGetMergeTablesResultE _ZN9oceanbase3sql18ObBasicSessionInfo19update_sys_variableERKNS_6common8ObStringES5_ _ZN9oceanbase5share15ObSysVarFactory23find_sys_var_id_by_nameERKNS_6common8ObStringEb -_ZN9oceanbase8observer20ObInnerSQLConnection13execute_writeEmRKNS_6common8ObStringERlbPKNS2_6ObAddrE -_ZNK9oceanbase6common12ObTimeoutCtx11get_timeoutEl -_ZN9oceanbase8observer20ObInnerSQLConnection19execute_write_innerEmRKNS_6common8ObStringERlbPKNS2_6ObAddrE -_ZN9oceanbase6common16ObTotalWaitGuardD1Ev -_ZN9oceanbase8observer20ObInnerSQLConnection13switch_tenantEm -_ZN9oceanbase3sql18ObBasicSessionInfo8set_userERKNS_6common8ObStringES5_m -_ZN9oceanbase6common9PageArenaIcNS0_19ModulePageAllocatorEE6_allocEl -_ZN9oceanbase6common12ObStringBufTINS0_19ModulePageAllocatorENS0_9PageArenaIcS2_EEE12write_stringERKNS0_8ObStringEPS6_ -_ZN9oceanbase3sql21ObSqlParameterization21is_ignore_scale_checkERNS0_16TransformTreeCtxEPK10_ParseNode -_ZN9oceanbase3sql24ObTenantSqlMemoryManager27calculate_global_bound_sizeEPNS_6common12ObIAllocatorEb -_ZN9oceanbase3sql24ObTenantSqlMemoryManager21ObSqlWorkAreaCalcInfo4initERNS_6common12ObIAllocatorEPNS0_21ObSqlWorkAreaIntervalEl -_ZN9oceanbase3sql24ObTenantSqlMemoryManager38count_profile_into_work_area_intervalsEPNS0_21ObSqlWorkAreaIntervalERlS4_ -_ZN9oceanbase7storage15ObMultipleMerge26handle_lob_before_fuse_rowEv -_ZN9oceanbase3sql10ObOperator20set_children_pointerEPPS1_j -_ZN9oceanbase5obrpc16ObTransRpcResult12deserialize_EPKclRl -_ZN9oceanbase5share3SCN11deserializeEPKclRl -_ZN9oceanbase7storage16ObMetaPointerMapINS0_14ObTabletMapKeyENS0_8ObTabletEE26try_get_in_memory_meta_objERKS2_RbRNS0_14ObMetaObjGuardIS3_EE -_ZN9oceanbase6common10ObFunctionIFvvEE12base_assign_EPNS3_8AbstractE -_ZN9oceanbase6common4hash11ObHashTableIlNS1_11HashMapPairIllEENS1_9hash_funcIlEENS1_8equal_toIlEENS1_10pair_firstIS4_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS4_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE5beginEv -_ZN9oceanbase4palf8PalfStatD2Ev -_ZN9oceanbase5obrpc18ObRpcProcessorBase3runEv -_ZN9oceanbase5obrpc14ObRpcProcessorINS0_13LogRpcProxyV25ObRpcILNS0_15ObRpcPacketCodeE5387EvEEE20m_get_encoded_lengthEv -_ZN9oceanbase5obrpc18ObRpcProcessorBase7cleanupEv -_ZN9oceanbase5obrpc20check_arb_white_listElRb -_ZZN9oceanbase4palf26ElectionAcceptResponseMsgP13process_impl_ILb1ELb1EEEivENKUlPKcE0_clES4_ -_ZN9oceanbase4palf25ElectionAcceptRequestMsgP13process_impl_ILb1ELb1EEEiv -_ZN9oceanbase5obrpc18ObRpcProcessorBase13part_responseEib -_ZN9oceanbase6common13serialization19encoded_length_vi64El -_ZN9oceanbase5obrpc23ObPocRpcRequestOperator15response_resultEPNS_3rpc9ObRequestEPNS0_11ObRpcPacketE -_ZN9oceanbase5obrpc17ObRpcPacketHeader9serializeEPclRl -_ZN9oceanbase5obrpc23ObPocRpcRequestOperator21alloc_response_bufferEPNS_3rpc9ObRequestEl -pkts_resp -_ZN9oceanbase4palf17LogRequestHandler14handle_requestINS0_8election24ElectionAcceptRequestMsgEEEilRKNS_6common6ObAddrERKT_ -_ZN9oceanbase4palf8election12ElectionImpl17refresh_priority_Ev -_ZN9oceanbase10logservice11coordinator20ElectionPriorityImpl7refreshEv -_ZNK9oceanbase5obrpc16ObTransRpcResult9serializeEPclRl -_ZN9oceanbase4palf8election12ElectionImpl14handle_messageERKNS1_24ElectionAcceptRequestMsgE -_ZN9oceanbase6common5occam26ObOccamTimeGuardDetectHungD2Ev -_ZNK9oceanbase4palf8election12ElectionImpl5send_ERKNS1_25ElectionAcceptResponseMsgE -_ZN9oceanbase4palf8election16ElectionProposer42reschedule_or_register_prepare_task_after_El -_ZNK9oceanbase6common26ObOccamTimerTaskRAIIHandle10is_runningEv -_ZN9oceanbase4palf8election31ElectionAcceptResponseMsgMiddle12set_acceptedElPKNS1_16ElectionPriorityE -_ZNK9oceanbase10logservice11coordinator20ElectionPriorityImpl9serializeEPclRl -_ZN9oceanbase6common26ObOccamTimerTaskRAIIHandle16reschedule_afterEl -_ZN9oceanbase6common26ObOccamTimerTaskRAIIHandle27remove_task_from_timewheel_Ev -_ZN9oceanbase4palf8election18ElectionMsgCounter14AddrMsgCounter19find_or_reuse_item_ERKNS_6common6ObAddrE -_ZNK9oceanbase6common6ObAddreqERKS1_ -_ZN9oceanbase4palf26ElectionAcceptResponseMsgP13process_impl_ILb1ELb1EEEiv -_ZN9oceanbase4palf17LogRequestHandler14handle_requestINS0_8election25ElectionAcceptResponseMsgEEEilRKNS_6common6ObAddrERKT_ -_ZN9oceanbase4palf19__get_palf_env_implEmRPNS0_12IPalfEnvImplEb -_ZN9oceanbase4palf8election12ElectionImpl14handle_messageERKNS1_25ElectionAcceptResponseMsgE -_ZN9oceanbase4palf8election16ElectionProposer18on_accept_responseERKNS1_25ElectionAcceptResponseMsgE -_ZN9oceanbase4palf8election16ElectionProposer31leader_revoke_if_lease_expired_ENS1_16RoleChangeReasonE -_ZN9oceanbase4palf8election20MemberListWithStates29get_server_idx_in_memberlist_ERKNS_6common6ObAddrERl -_ZN9oceanbase4palf8election16ElectionProposer31leader_takeover_if_lease_valid_ENS1_16RoleChangeReasonE -_ZN9oceanbase5obrpc14ObTxKeepaliveP7processEv -_ZN9oceanbase11transaction14ObTransService22handle_trans_keepaliveERKNS0_16ObTxKeepaliveMsgERNS_5obrpc16ObTransRpcResultE -_ZNK9oceanbase5obrpc26ObGetLeaderLocationsResult18get_serialize_sizeEv -_ZNK9oceanbase5share19ObLSReplicaLocation19get_serialize_size_Ev -_ZNK9oceanbase5obrpc15ObRpcResultCode9serializeEPclRl -_ZNK9oceanbase6common13ObSEArrayImplINS0_15ObWarningBuffer11WarningItemELl2ENS0_19ModulePageAllocatorELb0EE9serializeEPclRl -_ZN9oceanbase5obrpc18ObRpcProcessorBase11deserializeEv -_ZN9oceanbase5trace7ObTrace11deserializeEPKclRl -_ZN9oceanbase5trace4UUID11deserializeEPKclRl -_ZN9oceanbase4palf16LogRpcPacketImplINS0_8election25ElectionAcceptResponseMsgEE11deserializeEPKclRl -_ZN9oceanbase3lib16ObRuntimeContext11deserializeEPKclRl -_ZN9oceanbase11transaction20ObTxKeepaliveRespMsg11deserializeEPKclRl -_ZN9oceanbase11transaction7ObTxMsg11deserializeEPKclRl -_ZN9oceanbase6common13serialization6decodeEPKclRlS4_ -_ZN9oceanbase5share6ObLSID11deserializeEPKclRl -_ZN9oceanbase11transaction9ObTransID11deserializeEPKclRl -_ZN9oceanbase4palf16LogRpcPacketImplINS0_8election24ElectionAcceptRequestMsgEE11deserializeEPKclRl -_ZN9oceanbase4palf8election38print_debug_ts_if_reach_warn_thresholdERKNS1_15ElectionMsgBaseEl -_ZN9oceanbase4palf8election30ElectionAcceptRequestMsgMiddle11deserializeEPKclRl -_ZN9oceanbase4palf8election31ElectionAcceptResponseMsgMiddle11deserializeEPKclRl -_ZN9oceanbase4palf8election30ElectionAcceptRequestMsgMiddle12deserialize_EPKclRl -_ZN9oceanbase4palf8election15ElectionMsgBase11deserializeEPKclRl -_ZN9oceanbase4palf8election15ElectionMsgBase12deserialize_EPKclRl -_ZN9oceanbase6common6ObAddr11deserializeEPKclRl -_ZN9oceanbase4palf8election18ElectionMsgDebugTs11deserializeEPKclRl -_ZN9oceanbase4palf8election18ElectionMsgDebugTs12deserialize_EPKclRl -_ZN9oceanbase4palf8election31ElectionAcceptResponseMsgMiddle12deserialize_EPKclRl -_ZN9oceanbase6common13serialization6decodeIhLl512EEEiPKclRlRAT0__T_ -_ZN9oceanbase6common13serialization11decode_vi64EPKclRlPl -_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE10ELS3_10EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE -_ZN9oceanbase3sql12ObMaterialOp7destroyEv -_ZN9oceanbase3sql18ObBasicSessionInfo20update_timezone_infoEv -_ZN9oceanbase10logservice17ObLogApplyService16get_apply_statusERKNS_5share6ObLSIDERNS0_18ObApplyStatusGuardE -_ZN9oceanbase3sql16ObDASDMLIteratorD2Ev -_ZN9oceanbase6common5occam19CallWithTupleUnpackIbNS1_16ObOccamTimerTask11TaskWrapperEJEJELb1EEEvNS1_3seqIJXspT2_EEEERSt5tupleIJDpT1_EERT0_RNS0_9ObPromiseIT_EE -_ZN9oceanbase6common5occam16ObOccamTimerTask11TaskWrapperclEv -_ZTWN9oceanbase6common5occam20ObThreadHungDetector15click_point_idxE -_ZN9oceanbase6common5occam26ObOccamTimeGuardDetectHungC2EjjPKcS4_S4_t -_ZTHN9oceanbase6common5occam20ObThreadHungDetector15click_point_idxE -_ZN9oceanbase6common5occam20ObThreadHungDetector13ClickPointIdx7get_idxEv -_ZN9oceanbase6common15ObLinearHashMapINS_10logservice18ServerProbeService11ServerLSKeyENS3_10LSProbeCtxENS0_14ShareMemMgrTagEE20unset_foreach_L_lmt_Em -_ZN9oceanbase6common5occam16ObOccamTimeGuard10is_timeoutEv -_ZNK9oceanbase6common10ObFunctionIFbvEE7DerivedIZNS_4palf8election16ElectionProposer26register_renew_lease_task_EvE4$_80E6invokeEv$07c713b1ce86e3648c27f84ad6998511 -_ZN9oceanbase4palf8election16ElectionProposer7proposeEv -_ZN9oceanbase6common5occam20ObThreadHungDetector12get_instanceEv -_ZNK9oceanbase4palf14PalfHandleImpl17ElectionMsgSender9broadcastERKNS0_8election24ElectionAcceptRequestMsgERKNS_6common8ObIArrayINS7_6ObAddrEEE -_ZZN9oceanbase4palf13LogNetService23post_request_to_server_INS0_8election24ElectionAcceptRequestMsgEEEiRKNS_6common6ObAddrERKT_ENKUlPKcE_clESD_ -_ZNK9oceanbase6common10ObFunctionIFbvEE7DerivedIZNS_10logservice11coordinator17ObFailureDetector9mtl_startERPS7_E3$_4E6invokeEv$b02259f28edc9c6ca5b48a656cfae97b -_ZN9oceanbase6common14ObStringHolder6assignERKNS0_8ObStringE -_ZN9oceanbase6common14ObStringHolder5resetEv -_ZNK9oceanbase6common10ObFunctionIFbvEE7DerivedIZNS_10logservice18ServerProbeService18start_probe_serverERKNS0_6ObAddrElE5$_735E6invokeEv$cc7da69946f527619e883ba5ebf5fc09 -_ZN9oceanbase6common15ObLinearHashMapINS_10logservice18ServerProbeService11ServerLSKeyENS3_10LSProbeCtxENS0_14ShareMemMgrTagEE16do_foreach_scan_IZNS3_21try_clear_server_listEvE5$_739NS7_15DoRemoveIfOnBktIS9_EEEEbmmRT_RT0_ -_ZN9oceanbase6common15ObLinearHashMapINS_10logservice18ServerProbeService11ServerLSKeyENS3_10LSProbeCtxENS0_14ShareMemMgrTagEE16load_access_bkt_EmRPNS7_6BucketE -_ZN9oceanbase6common15ObLinearHashMapINS_10logservice18ServerProbeService11ServerLSKeyENS3_10LSProbeCtxENS0_14ShareMemMgrTagEE18set_foreach_L_lmt_Ev -_ZN9oceanbase6common6future12ObFutureBaseIbE3setIbEEiOT_ -_ZNK9oceanbase6common6future16ObFutureBaseBase8is_validEv -_ZNK9oceanbase6common10ObFunctionIFbvEE7DerivedIZNS_10logservice11coordinator19ObLeaderCoordinator9mtl_startERPS7_E4$_63E6invokeEv$b02259f28edc9c6ca5b48a656cfae97b -_ZNK9oceanbase6common10ObFunctionIFbvEE7DerivedIZNS_4palf8election16ElectionAcceptor5startEvE3$_1E6invokeEv$07c713b1ce86e3648c27f84ad6998511 -_ZNK9oceanbase6common10ObFunctionIFbvEE7DerivedIZNS_7storage15ObTenantFreezer5startEvE5$_410E6invokeEv$d4cb9b9ff81c69fd079e07fc734021b5 -_ZZN9oceanbase6common19ObPageManagerCenter17print_tenant_statElRlS2_PclS2_EN3$_08__invokeEPNS_9container8ObRbTreeINS0_13ObPageManagerENS5_17ObDummyCompHelperIS7_EENS7_15ObRbNode_rblinkEEEPS7_Pv -_ZN9oceanbase6common15ObLinearHashMapINS_5share14ObCascadMemberENS2_15ObDstServerInfoENS0_14ShareMemMgrTagEE16do_foreach_scan_INS2_17ObServerBlacklist21ObMapMarkBlackFunctorENS6_14DoForeachOnBktIS9_EEEEbmmRT_RT0_ -_ZN9oceanbase6common15ObLinearHashMapINS_5share14ObCascadMemberENS2_15ObDstServerInfoENS0_14ShareMemMgrTagEE16load_access_bkt_EmRPNS6_6BucketE -_ZN9oceanbase10rootserver14ObThreadIdling4idleEl -_ZN9oceanbase6common14get_tenant_idsEPmiRi -_ZNK9oceanbase3lib17ObMallocAllocator35get_tenant_ctx_allocator_unrecycledEmm -_ZN9oceanbase3sql18ObHashJoinBatchMgr5resetEv -_ZN9oceanbase6common13ObSEArrayImplINS_7storage15ObTableHandleV2ELl2ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase8observer16ObInnerSQLResult4nextEv -_ZN9oceanbase3lib4Flow6deinitEv -_ZN9oceanbase3sql11ObResultSet12get_next_rowERPKNS_6common8ObNewRowE -_ZN9oceanbase3sql18ObBasicSessionInfo31process_session_time_zone_valueERKNS_6common5ObObjEb -_ZN9oceanbase3sql18ObBasicSessionInfo13set_time_zoneERKNS_6common8ObStringEbb -_ZN9oceanbase6common15ObTimeConverter13str_to_offsetERKNS0_8ObStringERiS5_bb -_ZN9oceanbase6common11ObArrayImplINS_5share14ObLSStatusInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE7destroyEv +_ZN9oceanbase7storage21ObMicroBlockHandleMgr22put_micro_block_handleEmRKNS_12blocksstable12MacroBlockIdERKNS2_21ObIndexBlockRowHeaderERNS0_22ObMicroBlockDataHandleE +_ZNSt14_Function_base13_Base_managerIZN9oceanbase11transaction14ObWeakReadUtil30generate_min_weak_read_versionEmRNS1_5share3SCNEE5$_228E10_M_managerERSt9_Any_dataRKS9_St18_Manager_operation _ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE16do_foreach_scan_INS4_25GetOldestHoldBlockFunctorENS7_14DoForeachOnBktIS9_EEEEbmmRT_RT0_ -_ZN9oceanbase12blocksstable14ObBlockManager25GetOldestHoldBlockFunctorclERKNS0_12MacroBlockIdERKNS1_9BlockInfoE -_ZNK9oceanbase12blocksstable12MacroBlockId4hashERm -_ZN9oceanbase6common11ObArrayImplINS_5share20ObZoneReplicaAttrSetENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE7destroyEv -_ZN9oceanbase6common11ObArrayImplINS0_19ObFixedLengthStringILl128EEENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev -_ZN9oceanbase3sql3dtl22ObDtlChannelMemManager19get_max_mem_percentEv -_ZN9oceanbase5share11ObShareUtil23set_default_timeout_ctxERNS_6common12ObTimeoutCtxEl -_ZN9oceanbase6common13ObSharedGuardINS0_10ObFunctionIFbvEEEE5resetEv -_ZN9oceanbase5share19ObPersistentLSTable13get_by_tenantEmRNS_6common8ObIArrayINS0_8ObLSInfoEEE -_ZN9oceanbase6common11ObSqlString10assign_fmtEPKcz -_ZN9oceanbase5share11ObLSReplicaD1Ev -_ZN9oceanbase5share11ObLSReplicaD2Ev +_ZN9oceanbase5trace4UUID11deserializeEPKclRl +_ZN9oceanbase6common11ObArrayImplINS_12blocksstable12MacroBlockIdENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEED2Ev +_ZN9oceanbase8keybtree8IteratorINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE13next_on_levelElRS3_RS5_ +_ZN9oceanbase8keybtree10ScanHandleINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE12scan_forwardEl +_ZN9oceanbase8keybtree8IteratorINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE4compERS3_PS3_Ri +_ZN9oceanbase6common15ObLinearHashMapINS0_10ObTabletIDENS_7storage3mds4ListINS4_12MdsTableBaseEEENS0_14ShareMemMgrTagEE16do_foreach_scan_IZNS4_13ObMdsTableMgr23has_flushing_mds_table_ERNS_5share6ObLSIDERS2_E4$_37NS9_14DoForeachOnBktISG_EEEEbmmRT_RT0_ +_ZN9oceanbase11transaction17ObTxSerCompatByte16set_object_flag_Elhb +_ZNK9oceanbase3sql18ObBasicSessionInfo17get_int64_sys_varENS_5share17ObSysVarClassTypeERl +_ZNSt17_Function_handlerIFiPKN9oceanbase3lib17ObTenantMemoryMgrEEZNKS1_20ObTenantCtxAllocator11print_usageEvE4$_70E9_M_invokeERKSt9_Any_dataOS4_ +_ZN9oceanbase3omt19ObTenantTimezoneMgr12get_instanceEv +_ZN9oceanbase3sql11InParamMeta6assignERKS1_RNS_6common12ObIAllocatorE +_ZN9oceanbase6common12ob_write_objINS0_12ObIAllocatorEEEiRT_RKNS0_5ObObjERS5_ +_ZN9oceanbase6common11ObArrayImplINS0_5ObObjENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS2_EENS0_22NotImplementItemEncodeIS2_EEE9push_backERKS2_ +_ZN9oceanbase8observer20ObRootServiceMonitor4run1Ev +_ZN9oceanbase3lib7Threads12has_set_stopEv +_ZN9oceanbase8observer20ObRootServiceMonitor20monitor_root_serviceEv +_ZZN9oceanbase10logservice12ObLogService9open_palfERKNS_5share6ObLSIDERNS_4palf15PalfHandleGuardEENK5$_397clEPKc +_ZN9oceanbase5share19ObTenantSwitchGuardD2Ev +_ZNK9oceanbase10logservice12ObLogService16check_palf_existERKNS_5share6ObLSIDERb +_ZN9oceanbase4palf7PalfEnv5closeERNS0_10PalfHandleE +_ZZN9oceanbase4palf7PalfEnv5closeERNS0_10PalfHandleEENK5$_733clEPKc.llvm.447907550136452219 +_ZN9oceanbase4palf10PalfHandle25unregister_role_change_cbEv +_ZN9oceanbase4palf10PalfHandle21unregister_rebuild_cbEv +_ZZN9oceanbase4palf10PalfHandle21unregister_rebuild_cbEvENK5$_887clEPKc.llvm.447907550136452219 +_ZZN9oceanbase4palf10PalfHandle25unregister_role_change_cbEvENK5$_882clEPKc +_ZN9oceanbase10logservice20ObArbitrationService16DoDegradeFunctorD2Ev +_ZZN9oceanbase10logservice20ObArbitrationService9run_loop_EvENK5$_716clEPKc +_ZNK9oceanbase5share6schema19ObSchemaGetterGuard18get_schema_versionEmRl +_ZN9oceanbase3sql16AllocInputHelperILi7EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecERPNS0_9ObOpInputE +_ZN9oceanbase3sql16AllocInputHelperILi92EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecERPNS0_9ObOpInputE +_ZN9oceanbase7storage3mds11MdsDumpNode5resetEv +_ZNK9oceanbase7storage21ObTabletMemberWrapperINS0_18ObTabletTableStoreES2_E10get_memberERPKS2_ +_ZN9oceanbase6common11ObArrayImplINS_7storage15ObTableHandleV2ENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ +_ZN9oceanbase7storage15ObTableHandleV2C1ERKS1_ +_ZN9oceanbase12blocksstable25ObIndexBlockMacroIterator20get_next_macro_blockERNS0_16ObMacroBlockDescE +_ZN9oceanbase6common11ObArrayImplINS_12blocksstable13ObDatumRowkeyENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ +_ZN9oceanbase12blocksstable22ObIndexBlockTreeCursor19read_next_level_rowEl +_ZN9oceanbase12blocksstable21ObIndexBlockRowParser4initElRKNS0_10ObDatumRowE +_ZN9oceanbase12blocksstable21ObIndexBlockRowParser4initEPKc +_ZN9oceanbase6common11ObArrayImplINS_12blocksstable16ObMicroIndexInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ +_ZN9oceanbase6common11ObArrayImplINS_12blocksstable16ObMicroIndexInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE10extend_bufEl +_ZN9oceanbase8observer24ObInnerSQLConnectionPool9free_connEPNS0_20ObInnerSQLConnectionE +_ZN9oceanbase8observer20ObInnerSQLConnection5unrefEv +_ZN9oceanbase3omt8ObTenant6unlockERNS_6common10ObLDHandleE +_ULx86_64_Ifind_dynamic_proc_info +_ZN9oceanbase5obrpc14ObBatchRpcBase7do_workEv +_ZN9oceanbase5obrpc11ObRpcBuffer4sendERNS0_15ObBatchRpcProxyEmRKNS_6common6ObAddrEb +_ZN9oceanbase5obrpc15ObRingRpcBuffer4readERlRPcS2_b +_ZN9oceanbase10rootserver19ObRsReentrantThread25update_last_run_timestampEv +_ZN9oceanbase6common11ObSqlString10append_fmtEPKcz _ZN9oceanbase6common11ObSqlString7vappendEPKcP13__va_list_tag -_ZN9oceanbase6common11ObSqlString6extendEl _ZN9oceanbase6common11ObSqlString7reserveEl -_ZN9oceanbase6common23ObSingleConnectionProxy7connectEmPNS0_12ObISQLClientE -_ZN9oceanbase7storage16MemMgrRLockGuardD2Ev -_ZNK9oceanbase11transaction30ObTenantWeakReadClusterService14get_serve_infoERbRl -_ZN9oceanbase5share11ObLSReplica5resetEv -_ZZN9oceanbase10logservice17ObLogApplyService19get_max_applied_scnERKNS_5share6ObLSIDERNS2_3SCNEENK5$_151clEPKc +_ZN9oceanbase6common11ObSqlString6extendEl +_ZN9oceanbase6common15ObLinearHashMapINS0_10ObTabletIDENS_7storage3mds4ListINS4_12MdsTableBaseEEENS0_14ShareMemMgrTagEE20unset_foreach_L_lmt_Em +_ZN9oceanbase6common6ObPoolINS0_8ObMallocENS0_10ObNullLockEE15alloc_new_blockEv +_ZN9oceanbase10rootserver8DRLSInfo4initEv +_ZNK9oceanbase5share16ObServerTraceMap16get_servers_infoERKNS_6common19ObFixedLengthStringILl128EEERNS2_8ObIArrayINS0_19ObServerInfoInTableEEEb +_ZN9oceanbase6common11ObArrayImplINS_5share19ObServerInfoInTableENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ +_ZN9oceanbase10rootserver8DRLSInfo10fill_unitsEv +_ZN9oceanbase5obrpc14enable_pkt_nioEv +_ZN9oceanbase6common9datum_cmp13ObDatumStrCmpILNS0_15ObCollationTypeE45ELb0EE3cmpERKNS0_7ObDatumES7_Ri +_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE18set_foreach_L_lmt_Ev +_ZN9oceanbase5share6schema19ObSchemaGetterGuard23get_sys_variable_schemaEmRPKNS1_19ObSysVariableSchemaE +_ZN9oceanbase5share6schema19ObSchemaGetterGuard10get_schemaINS1_19ObSysVariableSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_l +_ZN9oceanbase5share6schema16is_normal_schemaENS1_12ObSchemaTypeE +_ZN9oceanbase5share6schema19ObSchemaGetterGuard20get_from_local_cacheINS1_19ObSysVariableSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_ +_ZNK9oceanbase4palf10LogStorage38get_readable_log_tail_guarded_by_lock_Ev +_ZZN9oceanbase5share21ObTabletTableOperator25construct_tablet_replica_ERNS_6common9sqlclient13ObMySQLResultERNS0_15ObTabletReplicaEENK4$_81clEPKc +_ZN9oceanbase5obrpc19ObAsyncRespCallback11handle_respEiPKcl +_ZN9oceanbase5obrpc17ObRpcPacketHeader11deserializeEPKclRl +_ZN9oceanbase5obrpc15ObRpcResultCodeD2Ev +_ZN9oceanbase5obrpc9ObTxRPCCBILNS0_15ObRpcPacketCodeE1628EE7processEv +_ZN9oceanbase11transaction14ObTransService25handle_trans_msg_callbackERKNS_5share6ObLSIDES5_RKNS0_9ObTransIDEsiRKNS_6common6ObAddrElRKNS2_3SCNE +_ZN9oceanbase5obrpc9ObTxRPCCBILNS0_15ObRpcPacketCodeE1626EE7processEv +_ZN9oceanbase5obrpc10ObRpcProxy7AsyncCBINS0_15ObTransRpcProxy5ObRpcILNS0_15ObRpcPacketCodeE1626EvEEE6decodeEPv +_ZN9oceanbase5obrpc16ObTransRpcResult11deserializeEPKclRl +_ZN9oceanbase5share3SCN11deserializeEPKclRl +_ZN9oceanbase5obrpc15ObRpcResultCode11deserializeEPKclRl +_ZN9oceanbase6common13ObSEArrayImplINS0_15ObWarningBuffer11WarningItemELl2ENS0_19ModulePageAllocatorELb0EE11deserializeEPKclRl +_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE2ELS3_2EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE +_ZN9oceanbase6common19GlobalHazardVersion7releaseEv +_ZN9oceanbase6common4hash11ObHashTableINS0_6ObAddrENS1_11HashMapPairIS3_NS1_11HashNullObjEEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS6_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS6_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14get_refactoredERKS3_RS6_l +_ZNK9oceanbase4palf16LogConfigVersion9serializeEPclRl +_ZN9oceanbase11transaction9tablelock12ObOBJLockMap16get_lock_id_iterERNS_6common16ObSimpleIteratorINS1_8ObLockIDEXadL_ZNS1_22ObSimpleIteratorModIds15OB_OBJ_LOCK_MAPEEELl16EEE +_ZN9oceanbase11transaction14ObTransHashMapINS0_9tablelock8ObLockIDENS2_9ObOBJLockENS2_14ObOBJLockAllocENS_6common10SpinRWLockELl1024EE19generate_value_arr_ElRNS6_9ObSEArrayIPS4_Ll32ENS6_19ModulePageAllocatorELb0EEE +_ZN9oceanbase6common15ObLinearHashMapINS_5share14ObCascadMemberENS2_15ObDstServerInfoENS0_14ShareMemMgrTagEE16do_foreach_scan_INS2_17ObServerBlacklist19ObMapSendReqFunctorENS6_14DoForeachOnBktIS9_EEEEbmmRT_RT0_ +_ZN9oceanbase6common15ObLinearHashMapINS_5share14ObCascadMemberENS2_15ObDstServerInfoENS0_14ShareMemMgrTagEE16load_access_bkt_EmRPNS6_6BucketE +_ZN9oceanbase6common4hash9do_createIPNS1_17ObHashTableBucketINS1_11HashMapPairIllEENS0_7ObLatchENS1_5NCondEEENS0_8ObMallocEEEiRT_lllNS1_16NormalPointerTagERT0_ +_ZN9oceanbase8observer20ObInnerSQLConnection12TimeoutGuardC2ERS1_ +_ZN9oceanbase3sql16ObPlanCacheValue16match_dep_schemaERKNS0_14ObPlanCacheCtxERKNS_6common8ObIArrayINS0_12PCVSchemaObjEEERb +_ZN9oceanbase9container8ObRbTreeINS_6common13ObPageManagerENS0_17ObDummyCompHelperIS3_EENS3_15ObRbNode_rblinkEE12iter_recurseEPS7_PS3_PFS9_S8_S9_PvESA_ +_ZZN9oceanbase6common19ObPageManagerCenter17print_tenant_statElRlS2_PclS2_EN3$_08__invokeEPNS_9container8ObRbTreeINS0_13ObPageManagerENS5_17ObDummyCompHelperIS7_EENS7_15ObRbNode_rblinkEEEPS7_Pv +_ZN9oceanbase6common14ObKVCacheStore14alloc_mbhandleERNS0_13ObKVCacheInstENS0_15ObKVCachePolicyElRPNS0_18ObKVMemBlockHandleE +_ZN9oceanbase6common12ObFixedQueueINS0_18ObKVMemBlockHandleEE3popERPS2_ +_ZN9oceanbase6common17ObAtomicReference11inc_ref_cntEv +_ZN9oceanbase6common14ObKVCacheStore16insert_mb_handleEPNS0_7ObDLinkEPNS0_18ObKVMemBlockHandleE +_ZN9oceanbase6common14ObKVCacheStore8alloc_mbERNS_3lib25ObTenantResourceMgrHandleEml +_ZN9oceanbase10rootserver21ObBackupTaskScheduler4run2Ev +_ZN9oceanbase6common10ObIOHandle10get_bufferEv +_ZN9oceanbase7storage15ObTxTableGuards13lock_for_readERKNS_11transaction16ObLockForReadArgERbRNS_5share3SCNES6_RNS0_12ObCleanoutOpERNS0_11ObReCheckOpE +_ZNK9oceanbase3omt17ObTenantConfigMgr18read_tenant_configEmmRKSt8functionIFvRKNS0_14ObTenantConfigEEERKS2_IFvvEE +_ZN9oceanbase3sql16ObPlanCacheValue24check_dep_schema_versionERKNS_6common8ObIArrayINS0_12PCVSchemaObjEEERKNS3_IPS4_EERb +_ZN9oceanbase6common14ObTimerMonitor12get_instanceEv _ZN9oceanbase5share6schema19ObSchemaGetterGuard15get_tenant_infoEmRPKNS1_14ObTenantSchemaE _ZN9oceanbase5share6schema19ObSchemaGetterGuard10get_schemaINS1_14ObTenantSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_l -_ZNK9oceanbase5share6schema11ObSchemaMgr17get_tenant_schemaEmRPKNS1_20ObSimpleTenantSchemaE +_ZN9oceanbase5share6schema19ObSchemaGetterGuard20get_from_local_cacheINS1_14ObTenantSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_ +_ZNK9oceanbase5share6schema14ObTenantSchema16get_convert_sizeEv +_ZNK9oceanbase5share24SchemaZoneReplicaAttrSet16get_convert_sizeEv _ZZN9oceanbase5share6schema19ObSchemaGetterGuard20get_from_local_cacheINS1_14ObTenantSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_ENKUlPKcE1_clESB_ -_ZN9oceanbase6common13ObSEArrayImplINS_3sql13ObExprResTypeELl5ENS0_19ModulePageAllocatorELb1EE7destroyEv -_ZNK9oceanbase4palf8election15ElectionMsgBase8is_validEv -_ZN9oceanbase10rootserver20ObTenantThreadHelper4idleEl -_ZN9oceanbase6common12ObCellWriter10write_charERKNS0_5ObObjENS0_9ObObjTypeERKNS0_8ObStringEPS2_ -_ZN9oceanbase3sql16ObConfigInfoInPC17serialize_configsEPciRl -_ZN9oceanbase11transaction23ObTenantWeakReadService12scan_all_ls_EPNS_7storage11ObLSServiceE -_ZN9oceanbase11transaction23ObTenantWeakReadService10handle_ls_ERNS_7storage4ObLSE -_ZN9oceanbase7storage14ObLSWRSHandler38generate_ls_weak_read_snapshot_versionERNS0_4ObLSERbS4_RNS_5share3SCNEl -_ZNK9oceanbase7storage8ObLSMeta20get_migration_statusERNS0_17ObMigrationStatusE -_ZN9oceanbase7storage14ObLSWRSHandler29generate_weak_read_timestamp_ERNS0_4ObLSElRNS_5share3SCNE -_ZN9oceanbase10logservice12ObLogHandler19get_max_decided_scnERNS_5share3SCNE -_ZN9oceanbase10logservice14ObReplayStatus20get_max_replayed_scnERNS_5share3SCNE -_ZN9oceanbase7storage8ObLSMeta19ObSpinLockTimeGuardC2ERNS_6common10ObSpinLockEl -_ZN9oceanbase10logservice14ObReplayStatus27get_min_unreplayed_log_infoERNS_4palf3LSNERNS_5share3SCNERlRNS0_13ObLogBaseTypeES8_S8_S8_ -_ZNK9oceanbase10logservice25ObReplayServiceSubmitTask27get_next_to_submit_log_infoERNS_4palf3LSNERNS_5share3SCNE -_ZZN9oceanbase10logservice12ObLogHandler19get_max_decided_scnERNS_5share3SCNEENK5$_306clEPKc.llvm.12895904678201303240 -_ZN9oceanbase10logservice18ObLogReplayService20get_max_replayed_scnERKNS_5share6ObLSIDERNS2_3SCNE -_ZN9oceanbase10logservice18ObLogReplayService18get_replay_status_ERKNS_5share6ObLSIDERNS0_19ObReplayStatusGuardE -_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE7shrink_Ev -_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE17load_factor_ctrl_Em -_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE16load_access_bkt_ERKS3_RmRPNS8_6BucketE -_ZN9oceanbase6common11ObArrayImplIiNS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIiEENS0_22NotImplementItemEncodeIiEEE9push_backERKi -_ZNK9oceanbase8observer16ObInnerSQLResult7get_objElRNS_6common5ObObjEPKNS2_14ObTimeZoneInfoEPNS2_12ObIAllocatorE -_ZN9oceanbase5share6schema19ObSchemaGetterGuard28get_outline_info_with_sql_idEmmRKNS_6common8ObStringERPKNS1_13ObOutlineInfoE -_ZNK9oceanbase5share6schema12ObOutlineMgr30get_outline_schema_with_sql_idEmmRKNS_6common8ObStringERPKNS1_21ObSimpleOutlineSchemaE -_ZN9oceanbase7storage21ObTenantFreezeInfoMgr32get_min_reserved_snapshot_for_txEv -_ZNK9oceanbase19concurrency_control30ObMultiVersionGarbageCollector36get_reserved_snapshot_for_active_txnEv -_ZNK9oceanbase7storage12ObTabletMeta8is_validEv -_ZN9oceanbase7storage18ObLSTabletIterator19get_next_ddl_kv_mgrERNS0_14ObMetaObjGuardINS0_16ObTabletDDLKvMgrEEE -_ZN9oceanbase4palf11LogStateMgr19need_update_leader_ERNS_6common6ObAddrE -_ZNK9oceanbase4palf8election12ElectionImpl25get_current_leader_likelyERNS_6common6ObAddrERl -_ZN9oceanbase6common7ObDITlsINS0_15ObDSActionArrayELm0EE12get_instanceEv -_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice13ObApplyStatusENS0_14ShareMemMgrTagEE16load_access_bkt_ERKS3_RmRPNS8_6BucketE -_ZN9oceanbase6common11ObArrayImplINS_5share22ObBackupInfoSimpleItemENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ -_ZN9oceanbase11transaction11ObGtsSource17handle_gts_resultEml -_ZN9oceanbase6common11ObArrayImplIPKNS_5obrpc26ObUpdateTenantInfoCacheResENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS5_EENS0_22NotImplementItemEncodeIS5_EEE10extend_bufEv _ZN9oceanbase5share6schema19ObSchemaGetterGuard31get_outline_info_with_signatureEmmRKNS_6common8ObStringERPKNS1_13ObOutlineInfoE _ZNK9oceanbase5share6schema12ObOutlineMgr33get_outline_schema_with_signatureEmmRKNS_6common8ObStringERPKNS1_21ObSimpleOutlineSchemaE -_ZNK9oceanbase8observer16ObInnerSQLResult8get_uintEPKcRm -_ZN9oceanbase4palf13LogLoopThread9log_loop_Ev -_ZN9oceanbase10logservice11coordinator14RefeshPriorityclINS1_10PriorityV0EEEiRT_ -_ZN9oceanbase6common13ObSEArrayImplINS_3sql12PCVSchemaObjELl4ENS0_19ModulePageAllocatorELb0EE7destroyEv -_ZN9oceanbase7storage8ObTablet26update_upper_trans_versionERNS0_4ObLSERb -_ZN9oceanbase6common13RetireStation10RetireList6retireERNS0_10HazardListES4_lRNS0_6QClockE -_ZNK9oceanbase8observer16ObInnerSQLResult8get_boolEPKcRb -_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdENS2_14ObBlockManager9BlockInfoENS0_14ShareMemMgrTagEE18set_foreach_L_lmt_Ev -_ZN9oceanbase4palf16LogSlidingWindow22period_freeze_last_logEv -_ZN9oceanbase5obrpc13LogRpcProxyV211post_packetERKNS_6common6ObAddrERKNS_4palf16LogRpcPacketImplINS6_8election25ElectionAcceptResponseMsgEEElRKNS6_28PalfTransportCompressOptionsE -_ZN9oceanbase5obrpc13LogRpcProxyV28group_idEm -_ZN9oceanbase5obrpc13LogRpcProxyV211post_packetERKNS_4palf16LogRpcPacketImplINS2_8election25ElectionAcceptResponseMsgEEEPNS0_10ObRpcProxy7AsyncCBINS1_5ObRpcILNS0_15ObRpcPacketCodeE5387EvEEEERKNS0_9ObRpcOptsE -_ZNK9oceanbase5obrpc13LogRpcProxyV22toERKNS_6common6ObAddrE -_ZN9oceanbase5obrpc10ObRpcProxy8rpc_postINS0_13LogRpcProxyV25ObRpcILNS0_15ObRpcPacketCodeE5387EvEEEEiRKNT_7RequestEPNS1_7AsyncCBIS7_EERKNS0_9ObRpcOptsE -_ZNK9oceanbase4palf16LogRpcPacketImplINS0_8election25ElectionAcceptResponseMsgEE9serializeEPclRl -_ZNK9oceanbase4palf8election31ElectionAcceptResponseMsgMiddle9serializeEPclRl -_ZNK9oceanbase4palf8election31ElectionAcceptResponseMsgMiddle19get_serialize_size_Ev -_ZZN9oceanbase5share19ObBackupInfoChecker14get_new_items_ERNS_6common12ObISQLClientEmbRNS2_8ObIArrayINS0_22ObBackupInfoSimpleItemEEEENK6$_1262clEPKc -_ZNK9oceanbase5share17ObMasterKeyGetter23get_max_stored_versionsERNS_6common8ObIArrayISt4pairImmEEE -_ZN9oceanbase10rootserver8DRLSInfo4initEv -_ZZN9oceanbase5share6schema19ObSchemaGetterGuard31get_outline_info_with_signatureEmmRKNS_6common8ObStringERPKNS1_13ObOutlineInfoEENK6$_1640clEPKc -_ZZN9oceanbase7obmysql21ObMySQLRequestManager14record_requestERKNS_3sql17ObAuditRecordDataEbbENK4$_55clEPKc -_ZN9oceanbase3omt13ObMultiTenant22operate_in_each_tenantERKSt8functionIFivEEb -_ZN9oceanbase3omt13ObMultiTenant14get_tenant_idsERNS_6common8ObVectorImNS2_9PageArenaImNS2_20DefaultPageAllocatorEEEEE -_ZN9oceanbase6common15ObLinearHashMapINS0_6ObAddrENS0_9ObSEArrayINS_5share6ObLSIDELl3ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE9cons_dir_EmPPNS9_6BucketEm -_ZN9oceanbase3lib13ObResourceMgr7dec_refEPNS0_19ObTenantResourceMgrE -apply_reg_state -_ZN9oceanbase11transaction25ObStandbyTimestampService4run1Ev -_ZN9oceanbase11transaction25ObStandbyTimestampService24query_and_update_last_idEv +_ZNK9oceanbase5share6schema19ObSchemaGetterGuard16check_lazy_guardEmRPKNS1_11ObSchemaMgrE +_ZNK9oceanbase6common4hash18ObPointerHashArrayINS_5share6schema29ObOutlineSignatureHashWrapperEPNS4_21ObSimpleOutlineSchemaENS4_17ObGetOutlineKeyV3EE14get_refactoredERKS5_RS7_ +_ZZN9oceanbase5share6schema19ObSchemaGetterGuard31get_outline_info_with_signatureEmmRKNS_6common8ObStringERPKNS1_13ObOutlineInfoEENK6$_1665clEPKc +_ZNK9oceanbase3lib17ObMallocAllocator35get_tenant_ctx_allocator_unrecycledEmm +_ZN9oceanbase6common16ObClusterVersion23get_tenant_data_versionEmRm +_ZNSt17_Function_handlerIFivEZN9oceanbase8observer20ObAllVirtualPalfStat18inner_get_next_rowERPNS1_6common8ObNewRowEE5$_186E9_M_invokeERKSt9_Any_data +_ZN9oceanbase3sql16ObMaterialOpImpl14finish_add_rowEv +_ZN9oceanbase9arbserver14ObArbWhiteList12get_instanceEv +_ZN9oceanbase3sql22ObRawExprInfoExtractor5visitERNS0_18ObColumnRefRawExprE +_ZN9oceanbase4palf7LogMetaC2ERKS1_ +_ZN9oceanbase4palf7LogMetaaSERKS1_ +_ZN9oceanbase4palf13LogConfigInfoaSERKS1_ +_ZZN9oceanbase4palf15LogConfigInfoV2aSERKS1_ENK6$_1123clEPKc +_ZN9oceanbase4palf13LogConfigInfoC2Ev +_ZN9oceanbase7storage18ObTenantMetaMemMgr12TabletGCTask12runTimerTaskEv +_ZN9oceanbase7storage18ObTenantMetaMemMgr19gc_tablets_in_queueERb +_ZN9oceanbase7storage18ObTenantMetaMemMgr14release_tabletEPNS0_8ObTabletE +_ZNK9oceanbase6common5ObObj11can_compareERKS1_ +_ZN9oceanbase6common16ObLatchWaitQueue4waitINS0_7ObLatch12LowTryWRLockEEEiRNS0_10ObWaitProcEjjRT_S8_l +_ZN9oceanbase6common16ObLatchWaitQueue8try_lockINS0_7ObLatch12LowTryWRLockEEEiRNS1_13ObLatchBucketERNS0_10ObWaitProcEjjRT_ +_ZN9oceanbase6common7ObDListINS0_10ObWaitProcEE8add_lastEPS2_ +_ZN9oceanbase5share21ObTabletTableOperator23construct_tablet_infos_ERNS_6common9sqlclient13ObMySQLResultERNS2_8ObIArrayINS0_12ObTabletInfoEEE +_ZN9oceanbase3lib15CompatModeGuardC2ENS0_6Worker10CompatModeE +_ZN9oceanbase6common6ObAddr13set_ipv4_addrEPKci +_ZN9oceanbase8observer16ObInnerSQLResult4nextEv +_ZN9oceanbase3lib2_SILNS0_13ContextSourceE0EED2Ev +_ZN9oceanbase3lib11ObTLTaGuard9switch_toEl +_ZN9oceanbase5share15ObTabletReplica4initEmRKNS_6common10ObTabletIDERKNS0_6ObLSIDERKNS2_6ObAddrEllllNS1_9ScnStatusE +_ZN9oceanbase6common11ObArrayImplINS_5share12ObTabletInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ +_ZN9oceanbase6common11ObArrayImplINS_5share15ObTabletReplicaENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE6assignERKNS0_8ObIArrayIS3_EE +_ZN9oceanbase6common11ObArrayImplINS_5share15ObTabletReplicaENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE10extend_bufEl +_ZN9oceanbase6common9ObCharset6strcmpENS0_15ObCollationTypeERKNS0_8ObStringES5_ _ZN9oceanbase5share17ObBGThreadMonitor4run1Ev -_ZN9oceanbase7storage23ObTenantTabletScheduler23schedule_ls_minor_mergeERNS0_10ObLSHandleERl -_ZN9oceanbase7storage14ObMetaObjGuardINS0_16ObTabletDDLKvMgrEE9reset_objEv -_ZNK9oceanbase7storage8ObTablet19get_active_memtableERNS0_15ObTableHandleV2E -_ZN9oceanbase10compaction22ObPartitionMergePolicy22get_minor_merge_tablesERKNS_7storage21ObGetMergeTablesParamERNS2_4ObLSERKNS2_8ObTabletERNS2_22ObGetMergeTablesResultE -_ZNK9oceanbase7storage19ObTabletMemtableMgr20get_active_memtable_ERNS0_15ObTableHandleV2E -_ZNK9oceanbase8memtable10ObMemtable18is_active_memtableEv -_ZN9oceanbase10compaction22ObPartitionMergePolicy29get_boundary_snapshot_versionERKNS_7storage8ObTabletERlS6_b -_ZNK9oceanbase7storage13ObITableArray18get_boundary_tableEb -_ZNK9oceanbase7storage8ObTablet23get_max_medium_snapshotERl -_ZN9oceanbase10compaction22ObPartitionMergePolicy27get_hist_minor_merge_tablesERKNS_7storage21ObGetMergeTablesParamERNS2_4ObLSERKNS2_8ObTabletERNS2_22ObGetMergeTablesResultE -_ZN9oceanbase10compaction22ObMediumCompactionInfoD1Ev -_ZN9oceanbase10compaction22ObMediumCompactionInfoD2Ev -_ZN9oceanbase10compaction22ObMediumCompactionInfo5resetEv -_ZN9oceanbase7storage15ObStorageSchema5resetEv -_ZN9oceanbase10compaction22ObPartitionMergePolicy23find_minor_merge_tablesERKNS_7storage21ObGetMergeTablesParamEllRNS2_4ObLSERKNS2_8ObTabletERNS2_22ObGetMergeTablesResultE -_ZN9oceanbase7storage19ObTablesHandleArray9add_tableEPNS0_8ObITableE -_ZN9oceanbase6common13ObSEArrayImplIPNS_12blocksstable9ObSSTableELl16ENS0_19ModulePageAllocatorELb0EED2Ev -_ZN9oceanbase10compaction22ObPartitionMergePolicy25get_neighbour_freeze_infoElPKNS_7storage8ObITableERNS2_21ObTenantFreezeInfoMgr19NeighbourFreezeInfoE -_ZN9oceanbase6common16ObLatchWaitQueue4waitINS0_7ObLatch12LowTryRDLockEEEiRNS0_10ObWaitProcEjjRT_S8_l -_ZN9oceanbase3sql13ObTableLockOp19inner_open_with_dasEv -_ZN9oceanbase6common11ObArrayWrapINS1_INS_3sql11ObLockRtDefEEEE14allocate_arrayERNS0_12ObIAllocatorEl -_ZN9oceanbase3sql13ObTableLockOp15init_lock_rtdefEv -_ZN9oceanbase5obrpc14ObNetKeepAlive4run1Ev -_ZN9oceanbase4palf11LogBlockMgr6pwriteEmmPKcl -_ZN9oceanbase3sql16ObFastParserBase31process_identifier_begin_with_tERb -timers_reify -_ZN9oceanbase5share8ObLSInfo21update_replica_statusEv -_ZNK9oceanbase4palf8election15ElectionMsgBase9serializeEPclRl -_ZNK9oceanbase4palf8election18ElectionMsgDebugTs9serializeEPclRl -_ZN9oceanbase6common13serialization6encodeEPclRll +_ZN9oceanbase6common11ObArrayImplIiNS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIiEENS0_22NotImplementItemEncodeIiEEED2Ev +_ZN9oceanbase6common11ObArrayImplINS_5share11ReplicaAttrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEED2Ev +_ZN9oceanbase6common11ObArrayImplIPNS0_9sqlclient28ObCommonServerConnectionPoolENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEED2Ev +_ZN9oceanbase6common11ObArrayImplIjNS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIjEENS0_22NotImplementItemEncodeIjEEED2Ev +_ZNK9oceanbase7storage21ObTenantFreezeInfoMgr26get_multi_version_durationERl +_ZN9oceanbase3sql18ObBasicSessionInfo20update_timezone_infoEv +_ZN9oceanbase3sql12ObQueryRange16and_first_searchERNS1_13ObSearchStateEPNS0_9ObKeyPartERNS_6common9ObSEArrayIPNS6_10ObNewRangeELl1ENS6_19ModulePageAllocatorELb0EEERbRKNS6_20ObDataTypeCastParamsE +_ZN9oceanbase3sql12ObQueryRange16and_first_in_keyERNS1_13ObSearchStateEPNS0_9ObKeyPartERNS_6common9ObSEArrayIPNS6_10ObNewRangeELl1ENS6_19ModulePageAllocatorELb0EEERbRKNS6_20ObDataTypeCastParamsE +_ZN9oceanbase3sql12ObQueryRange18generate_cur_rangeERNS1_13ObSearchStateElbRNS_6common9ObSEArrayIPNS4_10ObNewRangeELl1ENS4_19ModulePageAllocatorELb0EEERbb +_ZN9oceanbase3sql12ObQueryRange13ObSearchState18tailor_final_rangeEl +_ZN9oceanbase3sql12ObQueryRange11store_rangeEPNS_6common10ObNewRangeEbRNS1_13ObSearchStateERNS2_9ObSEArrayIS4_Ll1ENS2_19ModulePageAllocatorELb0EEERb +_ZNK9oceanbase6common10ObNewRange4hashEv +_ZNK9oceanbase6common8ObRowkey10murmurhashEm +_ZN9oceanbase6common17ObjHashCalculatorILNS0_9ObObjTypeE25ENS0_13ObDefaultHashENS0_5ObObjEE15calc_hash_valueERKS4_mRm +_ZN9oceanbase3sql20ObSecurityAuditUtils17check_allow_auditERNS0_16ObSQLSessionInfoERNS0_16ObAuditTrailTypeE +_ZN9oceanbase6common11ObArrayImplINS_5share8detector12ObLCLMessageENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEE7destroyEv +_ZN9oceanbase7storage4ObLS31try_update_uppder_trans_versionEv +_ZN9oceanbase7storage8ObTablet26update_upper_trans_versionERNS0_4ObLSERb +_ZN9oceanbase7storage20ObTableStoreIterator8get_nextERPNS0_8ObITableE +_ZNK9oceanbase5share6schema13ObTableSchema24get_generated_column_idsERNS_6common8ObIArrayImEE +_ZN9oceanbase6common4hash11ObHashTableIlNS1_11HashMapPairIllEENS1_9hash_funcIlEENS1_8equal_toIlEENS1_10pair_firstIS4_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS4_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv +_ZN9oceanbase6common8get_itidEv +_ZNK9oceanbase7storage8ObTablet27check_need_remove_old_tableElRb _ZNK9oceanbase7storage18ObTabletTableStore21need_remove_old_tableElRb -_ZN9oceanbase6commonL8int_uintENS0_9ObObjTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS4_m -_ZNK9oceanbase5share8ObLSInfo9find_idx_ERKNS0_11ObLSReplicaERl -_ZN9oceanbase12blocksstable14ObBlockManager14mark_and_sweepEv -_ZNK9oceanbase7storage8ObTablet16get_all_sstablesERNS_6common8ObIArrayIPNS0_8ObITableEEE -_ZN9oceanbase6common4hash11ObHashTableINS_12blocksstable12MacroBlockIdENS1_11HashMapPairIS4_NS1_11HashNullObjEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi89ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19ReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14set_refactoredERKS4_RKS7_iii -_ZN9oceanbase6common4hash11WriteLockerC2ER16pthread_rwlock_t -_ZN9oceanbase6common4hash11ObHashTableINS_12blocksstable12MacroBlockIdENS1_11HashMapPairIS4_NS1_11HashNullObjEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS7_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS7_EELi89ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19ReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE12internal_setERNS1_17ObHashTableBucketIS7_16pthread_rwlock_tNS1_5NCondEEERKS7_b -_ZNK9oceanbase7storage8ObTablet22inner_get_all_sstablesERNS_6common8ObIArrayIPNS0_8ObITableEEE -_ZNK9oceanbase7storage13ObITableArray14get_all_tablesERNS_6common8ObIArrayIPNS0_8ObITableEEE -_ZN9oceanbase6common13ObSEArrayImplIPNS_7storage8ObITableELl64ENS0_19ModulePageAllocatorELb0EE9push_backERKS4_ -_ZN9oceanbase12blocksstable14ObBlockManager16update_mark_infoERKNS0_12MacroBlockIdERNS_6common15ObLinearHashMapIS2_bNS5_14ShareMemMgrTagEEE -_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdEbNS0_14ShareMemMgrTagEE16load_access_bkt_ERKS3_RmRPNS5_6BucketE -_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdEbNS0_14ShareMemMgrTagEE17load_factor_ctrl_Em -_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdEbNS0_14ShareMemMgrTagEE7shrink_Ev -_ZN9oceanbase6common14ObKVCacheStore14alloc_mbhandleERNS0_13ObKVCacheInstENS0_15ObKVCachePolicyElRPNS0_18ObKVMemBlockHandleE -_ZN9oceanbase3lib17ObTenantMemoryMgr14alloc_cache_mbEl -_ZN9oceanbase6common14ObKVCacheStore13try_supply_mbEl -_ZN9oceanbase6common11ObArrayImplINS_5share11ObLSReplicaENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_17DefaultItemEncodeIS3_EEEaSERKS9_ -_ZN9oceanbase6common16construct_assignINS_5share11ObLSReplicaEEEiRT_RKS4_ -_ZN9oceanbase3sql9ObKeyPartC2ERNS_6common12ObIAllocatorEmi -_ZN9oceanbase5obrpc13ObSrvRpcProxy24update_tenant_info_cacheERKNS0_26ObUpdateTenantInfoCacheArgEPNS0_10ObRpcProxy7AsyncCBINS1_5ObRpcILNS0_15ObRpcPacketCodeE1861EvEEEERKNS0_9ObRpcOptsE -_ZN9oceanbase3sql9ObKeyPart9intersectEPS1_b -_ZNK9oceanbase3sql9ObKeyPart13has_intersectEPKS1_ -_ZNK9oceanbase3sql12ObKeyPartPoseqERKS1_ -_ZN9oceanbase3sql10ObOperator10filter_rowERNS0_9ObEvalCtxERKNS_6common8ObIArrayIPNS0_6ObExprEEERb -_ZN9oceanbase3sql18ObRelationalTCFuncILb1ELNS_6common14ObObjTypeClassE1ELS3_1ELNS2_7ObCmpOpE0EE4evalERKNS0_6ObExprERNS0_9ObEvalCtxERNS2_7ObDatumE -_ZN9oceanbase3sql18ObRelationalTCFuncILb1ELNS_6common14ObObjTypeClassE2ELS3_1ELNS2_7ObCmpOpE0EE4evalERKNS0_6ObExprERNS0_9ObEvalCtxERNS2_7ObDatumE -_ZN9oceanbase3sql13calc_or_exprNERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE -_ZN9oceanbase3sql24def_relational_eval_funcINS0_19ObRelationalStrFuncILb1ELNS_6common15ObCollationTypeE45ELb0ELNS3_7ObCmpOpE0EE8DatumCmpEEEiRKNS0_6ObExprERNS0_9ObEvalCtxERNS3_7ObDatumE -_ZN9oceanbase11transaction11ObGtsSource10update_gtsENS_6common13ObMonotonicTsElS3_Rb -_ZN9oceanbase6common14ObKVCacheStore13free_mbhandleEPNS0_18ObKVMemBlockHandleEb -_ZN9oceanbase6common14ObKVCacheStore16remove_mb_handleEPNS0_18ObKVMemBlockHandleEb -_ZN9oceanbase3sql13AllocOpHelperILi92EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE -_ZN9oceanbase7storage18ObTenantMetaMemMgr18gc_tables_in_queueERb -_ZN9oceanbase7storage21ObTenantTabletStatMgr22get_latest_tablet_statERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERNS0_12ObTabletStatE -_ZN9oceanbase3sql13ObExecContext19build_temp_expr_ctxERKNS0_10ObTempExprERPNS0_13ObTempExprCtxE -_ZN9oceanbase6common11ObArrayImplIPcNS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS2_EENS0_22NotImplementItemEncodeIS2_EEED2Ev -_ZN9oceanbase5share19ObLSReplicaLocation4initERKNS_6common6ObAddrERKNS2_6ObRoleERKlRKNS2_13ObReplicaTypeERKNS2_17ObReplicaPropertyERKNS0_17ObLSRestoreStatusEl -_ZNK9oceanbase4palf8election15ElectionMsgBase19get_serialize_size_Ev +_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice13ObApplyStatusENS0_14ShareMemMgrTagEE11do_operate_INS4_17ObLogApplyService21GetApplyStatusFunctorEEEiRKS3_RT_ +_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice13ObApplyStatusENS0_14ShareMemMgrTagEE16load_access_bkt_ERKS3_RmRPNS8_6BucketE +_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice13ObApplyStatusENS0_14ShareMemMgrTagEE7shrink_Ev +_ZNK9oceanbase3sql17ObChunkDatumStore9StoredRow7to_exprILb0EEEiRKNS_6common8ObIArrayIPNS0_6ObExprEEERNS0_9ObEvalCtxE +_ZN9oceanbase5share6schema8ObSchema13get_allocatorEv _ZN9oceanbase6common16ObFixedArrayImplINS_3sql15ObTableRowCountENS0_12ObIAllocatorEE9push_backERKS3_ _ZN9oceanbase6common16ObFixedArrayImplINS_3sql15ObTableRowCountENS0_12ObIAllocatorEE7reserveEl _ZN9oceanbase6common16ObFixedArrayImplINS_3sql15ObTableRowCountENS0_12ObIAllocatorEE4initEl -_ZN9oceanbase6common21ObDetectManagerThread6detectEv -_ZN9oceanbase6common13ObSEArrayImplINS_5share35ObArbitrationServiceReplicaTaskInfoELl100ENS0_15ObNullAllocatorELb0EE7destroyEv -_ZN9oceanbase5share8ObLSInfo15init_by_replicaERKNS0_11ObLSReplicaE -_ZN9oceanbase5share11ObLSReplica24transform_ob_member_listERKNS_6common16ObMemberListBaseILl7EEERNS2_9ObSEArrayINS0_12SimpleMemberELl7ENS2_15ObNullAllocatorELb0EEE -_ZN9oceanbase5obrpc10ObRpcProxy7AsyncCBINS0_13ObSrvRpcProxy5ObRpcILNS0_15ObRpcPacketCodeE1861EvEEED2Ev -_ZN9oceanbase6common13ObObjCmpFuncs11cmp_op_funcILNS0_14ObObjTypeClassE10ELS3_10ELNS0_7ObCmpOpE0EEEiRKNS0_5ObObjES7_RKNS0_12ObCompareCtxE -_ZN9oceanbase5share19ObPartitionLocationD1Ev -_ZN9oceanbase5share19ObPartitionLocationD2Ev -_ZNK9oceanbase4palf9LogEngine18get_min_block_infoERmRNS_5share3SCNE -_ZNK9oceanbase4palf10LogStorage17get_block_min_scnERKmRNS_5share3SCNE +_ZN9oceanbase7storage3mds10MdsDumpKey5resetEv +_ZZN9oceanbase10logservice19ObRemoteFetchWorker16do_consume_data_EvENK5$_239clEPKc +_ZN9oceanbase3sql16ObFastParserBase31process_identifier_begin_with_lERb +_ZN9oceanbase6common4hash13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairINS_12blocksstable12MacroBlockIdENS1_11HashNullObjEEEEELi89ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEE4freeEPS9_ +_ZN9oceanbase6common14ObMaxWaitGuardC1EPNS0_15ObWaitEventDescEPNS0_21ObDiagnoseSessionInfoE +_ZN9oceanbase3omt17ObTenantConfigMgr25get_tenant_config_versionEm _ZNK9oceanbase4palf10LogStorage18read_block_header_EmRNS0_14LogBlockHeaderE _ZN9oceanbase4palf14LogBlockHeader11deserializeEPKclRl -_ZNK9oceanbase4palf9LogReader5preadEmmlRNS0_7ReadBufERl -_ZZNK9oceanbase4palf9LogReader43limit_and_align_in_read_size_by_block_size_EmlRlENK6$_1129clEPKc -_ZNK9oceanbase4palf9LogReader12inner_pread_EimlPcRl -_ZN9__gnu_cxx5__ops14_Val_comp_iterIN9oceanbase12blocksstable15ObDatumComparorINS3_12ObDatumRangeEEEEclIS5_NS2_6common5array17ObSEArrayIteratorIS5_Ll8ENS9_19ModulePageAllocatorELb0EEEEEbRT_T0_ -_ZN9oceanbase11transaction10ObTsWorker9push_taskEmPNS0_16ObTsResponseTaskE -_ZN9oceanbase6common11ObArrayImplINS_5share19ObLSPrimaryZoneInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ -_ZN9oceanbase6common11ObArrayImplINS_5share11ReplicaAttrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE6assignERKNS0_8ObIArrayIS3_EE -_ZNK9oceanbase10rootserver20ObRsMasterKeyManager25get_all_tenant_master_keyERKNS_6common19ObFixedLengthStringILl128EEERNS2_8ObIArrayISt4pairImNS_5share15ObLeaseResponse14TLRpKeyVersionEEEE -_ZN9oceanbase8observer24ObInnerSQLConnectionPool9free_connEPNS0_20ObInnerSQLConnectionE -_ZN9oceanbase5share6schema19ObSchemaGetterGuard10get_schemaINS1_19ObSysVariableSchemaEEEiNS1_12ObSchemaTypeEmmRPKT_l -_ZZN9oceanbase5share6schema19ObSchemaGetterGuard18get_schema_versionENS1_12ObSchemaTypeEmmRlENK6$_1276clEPKc -_ZN9oceanbase4palf11PalfEnvImpl14get_disk_usageERlS2_ -_ZN9oceanbase3sql16ObMaterialOpImplD2Ev -_ZN9oceanbase5share6schema19ObSchemaGetterGuardC1Ev -_ZN9oceanbase6common4hash13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairImNS1_11HashNullObjEEEEELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEE5allocIJEEEPS7_DpRT_ -_ZN9oceanbase6common12ObDedupQueue4run1Ev -easy_baseth_pool_monitor_func.llvm.12087398431010983768 +_ZZNK9oceanbase4palf9LogReader5preadEmmlRNS0_7ReadBufERlENK6$_1171clEPKc +_ZN9oceanbase7storage3mds28ObMdsUnitRowNodeScanIteratorINS_10compaction25ObMediumCompactionInfoKeyENS3_22ObMediumCompactionInfoEED2Ev ev_invoke_pending -_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice13ObApplyStatusENS0_14ShareMemMgrTagEE7shrink_Ev -run_cfi_program -create_state_record_for.part.0 -_ZN9oceanbase7storage10checkpoint20ObCheckpointExecutor22update_clog_checkpointEv -_ZN9oceanbase7storage8ObLSMeta19set_clog_checkpointERKNS_4palf3LSNERKNS_5share3SCNEb -_ZN9oceanbase6common7ObDITlsIA16384_cLm3EE12get_instanceEv -_ZN9oceanbase5obrpc15ObPocClientStub4postINS_11transaction16ObTxKeepaliveMsgENS0_10ObRpcProxy7AsyncCBINS0_15ObTransRpcProxy5ObRpcILNS0_15ObRpcPacketCodeE1626EvEEEEEEiRS5_RKNS_6common6ObAddrES9_RKT_PT0_RKNS0_9ObRpcOptsE -_ZNK9oceanbase11transaction16ObTxKeepaliveMsg9serializeEPclRl -_ZN9oceanbase5obrpc23calc_extra_payload_sizeEv -_ZNK9oceanbase11transaction7ObTxMsg9serializeEPclRl -_ZNK9oceanbase11transaction7ObTxMsg10serialize_EPclRl -_ZNK9oceanbase6common4hash11ObHashTableINS_7storage20ObDDLCtrlSpeedHandle14SpeedHandleKeyENS1_11HashMapPairIS5_PNS3_18ObDDLCtrlSpeedItemEEENS1_9hash_funcIS5_EENS1_8equal_toIS5_EENS1_10pair_firstIS9_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS9_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE18foreach_refactoredINS4_20GetNeedRemoveItemsFnEEEiRT_ -_ZN9oceanbase7storage9ObTxTable18check_with_tx_dataERNS0_15ObReadTxDataArgERNS0_21ObITxDataCheckFunctorE -_ZN9oceanbase6common9ObKVCacheINS_7storage16ObTxDataCacheKeyENS2_18ObTxDataCacheValueEE3getERKS3_RPKS4_RNS0_15ObKVCacheHandleE -_ZN9oceanbase11transaction12ObLSTxCtxMgr18check_with_tx_dataERKNS0_9ObTransIDERNS_7storage21ObITxDataCheckFunctorE -_ZN9oceanbase11transaction12ObLSTxCtxMgr11get_tx_ctx_ERKNS0_9ObTransIDEbRPNS0_14ObPartTransCtxE -_ZN9oceanbase11transaction14ObTransHashMapINS0_9ObTransIDENS0_10ObTransCtxENS0_13TransCtxAllocENS_6common10SpinRWLockELl16384EE3getERKS2_RPS3_ -_ZN9oceanbase7storage18LockForReadFunctorclERKNS0_8ObTxDataEPNS0_9ObTxCCCtxE -HUF_readStats -_ZN9oceanbase6common10to_cstringINS0_8ObStringEEEPKcRKT_NS0_8BoolTypeILb0EEE -_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdEiNS0_14ShareMemMgrTagEE16do_foreach_scan_INS2_21ObSharedMacroBlockMgr15GetSmallBlockOpENS5_14DoForeachOnBktIS8_EEEEbmmRT_RT0_ -_ZN9oceanbase3sql12ObHashJoinOp21recursive_postprocessEv -_ZN9oceanbase7storage18ObLobLocatorHelper4initERKNS0_16ObTableScanParamERKNS0_10ObStoreCtxERKNS_5share6ObLSIDEl -_ZN9oceanbase6common13ObSEArrayImplINS0_10ObNewRangeELl16ENS0_19ModulePageAllocatorELb0EE7reserveEl -_ZN9oceanbase12blocksstable18ObMicroBlockReader8get_rowsERKNS_6common8ObIArrayIiEERKNS3_IPKNS_5share6schema13ObColumnParamEEERKNS3_INS2_17ObObjDatumMapTypeEEERKNS0_10ObDatumRowEPKllRSJ_RNS3_IPNS2_7ObDatumEEERNS2_12ObFixedArrayIPNS_3sql6ObExprENS2_12ObIAllocatorEEERNSU_9ObEvalCtxE -_ZN9oceanbase5share12ObLSLocation4initElmRKNS0_6ObLSIDEl -_ZN9oceanbase5obrpc10ObRpcProxy8rpc_postINS0_13LogRpcProxyV25ObRpcILNS0_15ObRpcPacketCodeE5386EvEEEEiRKNT_7RequestEPNS1_7AsyncCBIS7_EERKNS0_9ObRpcOptsE -_ZN9oceanbase5obrpc19ObAsyncRespCallback6createERNS0_12ObRpcMemPoolEPNS_3rpc5frame14ObReqTransport7AsyncCBE -_ZNK9oceanbase5obrpc10ObRpcProxy8init_pktEPNS0_11ObRpcPacketENS0_15ObRpcPacketCodeERKNS0_9ObRpcOptsEb -_ZN9oceanbase6common15ObLinearHashMapINS_5share14ObCascadMemberENS2_15ObDstServerInfoENS0_14ShareMemMgrTagEE16do_foreach_scan_INS2_17ObServerBlacklist18ObMapRemoveFunctorENS6_15DoRemoveIfOnBktIS9_EEEEbmmRT_RT0_ -_ZN9oceanbase7storage18ObLobLocatorHelperC1Ev -_ZNK9oceanbase3sql10ObTempExpr4evalERNS0_13ObExecContextERKNS_6common8ObNewRowERNS4_5ObObjE -_ZN9oceanbase3sql13string_numberERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE -_ZN9oceanbase6common6number8ObNumber12from_sci_optINS0_12ObIAllocatorEEEiPKclRT_PsS9_b -_ZN9oceanbase6common7ObDatum8from_objERKNS0_5ObObjENS0_17ObObjDatumMapTypeE -_ZZN9oceanbase8observer31init_srv_xlator_for_transactionEPNS0_14ObSrvRpcXlatorEEN6$_16378__invokeERKNS0_15ObGlobalContextERPNS_3rpc5frame14ObReqProcessorERNS_5obrpc19ObRpcSessionHandlerE -_ZN9oceanbase3sql20ObAggregateProcessor8min_calcERNS1_8AggrCellERNS_6common7ObDatumERKS5_PFiS8_S8_RiEb -_ZN9oceanbase5share20ObZoneReplicaAttrSet6assignERKS1_ -_ZNK9oceanbase5share16ObReplicaAttrSet31get_readonly_replica_attr_arrayEv -_ZN9oceanbase6common11ObArrayImplINS0_19ObFixedLengthStringILl128EEENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE6assignERKNS0_8ObIArrayIS3_EE -_ZN9oceanbase6common11ObArrayImplINS0_19ObFixedLengthStringILl128EEENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE10extend_bufEl -_ZN9oceanbase11transaction23ObTenantWeakReadService4run1Ev -_ZN9oceanbase11transaction23ObTenantWeakReadService15do_thread_task_ElRl -_ZN9oceanbase11transaction23ObTenantWeakReadService25generate_cluster_version_Ev -_ZNSt14_Function_baseD2Ev -_ZN9oceanbase11transaction30ObTenantWeakReadClusterService24persist_version_if_need_ENS_5share3SCNES3_S3_S3_bRl -_ZZN9oceanbase6common16ObCommonSqlProxy5writeEmPKcRlENK5$_270clES3_.llvm.1397840713389432827 -_ZN9oceanbase11transaction30ObTenantWeakReadClusterService25build_update_version_sql_ENS_5share3SCNES3_S3_S3_bRNS_6common11ObSqlStringE -_ZN9oceanbase11transaction23ObTenantWeakReadService21do_cluster_heartbeat_Ev +_ZN9oceanbase12blocksstable20ObIEncodeBlockReaderC2Ev +_ZN9oceanbase7storage21ObTenantFreezeInfoMgr32get_min_reserved_snapshot_for_txEv +_ZNK9oceanbase19concurrency_control30ObMultiVersionGarbageCollector36get_reserved_snapshot_for_active_txnEv +_ZN9oceanbase3sql24ObTenantSqlMemoryManager44calculate_global_bound_size_by_interval_infoERNS_6common12ObIAllocatorElb +_ZN9oceanbase3sql24ObTenantSqlMemoryManager38count_profile_into_work_area_intervalsEPNS0_21ObSqlWorkAreaIntervalERlS4_ _ZNK9oceanbase5share6schema14ObSysVarSchema9get_valueEPNS_6common12ObIAllocatorERKNS3_20ObDataTypeCastParamsERNS3_5ObObjE -_ZN9oceanbase5share19ObServerInfoInTable6assignERKS1_ -_ZN9oceanbase3omt17ObTenantConfigMgr17get_lease_requestERNS_5share14ObLeaseRequestE -_ZN9oceanbase7storage22ObStorageLoggerManager9free_itemEPNS0_16ObStorageLogItemE -_ZNK9oceanbase3lib20ObTenantCtxAllocator10iter_labelESt8functionIFiRNS0_7ObLabelEPNS_6common9LabelItemEEE -_ULx86_64_dwarf_extract_proc_info_from_fde -_ZN9oceanbase6common4hash11ObHashTableINS0_19ObFixedLengthStringILl128EEENS1_11HashMapPairIS4_PNS_10rootserver10ObDRWorker16ReplicaDescArrayEEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstISA_EENS1_13SimpleAllocerINS1_15ObHashTableNodeISA_EELi41ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19NoPthreadDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE7destroyEv -_ZN9oceanbase3rpc5frame10ObReqQueue4loopEv -_ZN9oceanbase10logservice11coordinator16SerializeFunctorclINS1_10PriorityV1EEEiRKT_ -_ZN9oceanbase6common13serialization14encoded_lengthINS0_9ObSEArrayINS_10logservice11coordinator12FailureEventELl3ENS0_19ModulePageAllocatorELb0EEEEElRKT_ -_ZNK9oceanbase10logservice11coordinator10PriorityV19serializeEPclRl -_ZNK9oceanbase10logservice11coordinator10PriorityV110serialize_EPclRl -_ZNK9oceanbase6common8ObString9serializeEPclRl -_ZNK9oceanbase6common4hash11ObHashTableINS_7storage20ObDDLCtrlSpeedHandle14SpeedHandleKeyENS1_11HashMapPairIS5_PNS3_18ObDDLCtrlSpeedItemEEENS1_9hash_funcIS5_EENS1_8equal_toIS5_EENS1_10pair_firstIS9_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS9_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE18foreach_refactoredINS4_23UpdateSpeedHandleItemFnEEEiRT_ -_ZN9oceanbase4palf8PalfStatC1Ev -_ZN9oceanbase6common18ObMySQLTransaction3endEb -_ZN9oceanbase6common11ObDebugSync8instanceEv -_ZN9oceanbase8observer20ObInnerSQLConnection6commitEv -_ZN9oceanbase5share17ObPrimaryZoneUtil29get_tenant_primary_zone_scoreERKNS0_6schema14ObTenantSchemaERNS2_13ObPrimaryZoneERNS_6common8ObIArrayINS0_20ObZoneReplicaAttrSetEEERNS9_INS2_11ObZoneScoreEEE -_ZNK9oceanbase5share6schema14ObTenantSchema27get_zone_replica_attr_arrayERNS_6common8ObIArrayINS0_20ObZoneReplicaAttrSetEEE -_ZN9oceanbase6common11ObArrayImplINS0_19ObFixedLengthStringILl128EEENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ -_ZN9oceanbase7storage19ObTxDataMemtableMgr17get_all_memtablesERNS_6common8ObIArrayINS0_15ObTableHandleV2EEE -_ZN9oceanbase6common13ObObjCmpFuncs8cmp_funcILNS0_14ObObjTypeClassE1ELS3_5EEEiRKNS0_5ObObjES6_RKNS0_12ObCompareCtxE -_ZN9oceanbase11transaction14ObPartTransCtx22tx_keepalive_response_El -_ZN9oceanbase6common7ObTimer13schedule_taskERNS0_11ObTimerTaskElbb -_ZNK9oceanbase6common14ObLobLocatorV214get_inrow_dataERNS0_8ObStringE -_ZN9oceanbase5share25ObArbitrationServiceUtils34get_arb_member_from_log_stat_tableEmRKNS0_6ObLSIDERNS_6common11ObSqlStringE -_ZN9oceanbase3sql15ObEqualAnalysis13new_equal_setEv -_ZN9oceanbase3sql12ObHashJoinOp15calc_basic_infoEb -_ZN9oceanbase5obrpc14rpc_encode_reqINS0_23ObGetLeaderLocationsArgEEEiRNS0_10ObRpcProxyERNS0_12ObRpcMemPoolENS0_15ObRpcPacketCodeERKT_RKNS0_9ObRpcOptsERPcRlbbbl -_ULx86_64_dwarf_callback -_ZN9oceanbase5share11ObLSReplica4initEllmRKNS0_6ObLSIDERKNS_6common6ObAddrElRKNS5_6ObRoleERKNS5_13ObReplicaTypeElRKNS0_15ObReplicaStatusERKNS0_17ObLSRestoreStatusElmRKNS5_8ObStringElllRKNS5_9ObSEArrayINS0_12SimpleMemberELl7ENS5_15ObNullAllocatorELb0EEERKNS5_15BaseLearnerListILl2000ENS5_8ObMemberEEE -_ZN9oceanbase5share18ObLSStatusOperator9fill_cellEPNS_6common9sqlclient13ObMySQLResultERNS0_14ObLSStatusInfoE -_ZN9oceanbase7storage18ObLobLocatorHelper19fill_lob_locator_v2ERNS_12blocksstable10ObDatumRowERKNS0_20ObTableAccessContextERKNS0_18ObTableAccessParamE -_ZN9oceanbase7storage18ObLobLocatorHelper15build_rowid_objERNS_12blocksstable10ObDatumRowERNS_6common8ObStringEbRKNS5_8ObIArrayINS_5share6schema9ObColDescEEERKNS8_IiEERKNS5_10ObTabletIDE -_ZN9oceanbase7storage18ObLobLocatorHelper19build_lob_locatorv2ERNS_6common14ObLobLocatorV2ERKNS2_8ObStringEmS7_RKNS0_20ObTableAccessContextENS2_15ObCollationTypeEbb -_ZN9oceanbase6common14ObLobLocatorV24fillENS0_12ObMemLobTypeERKNS0_19ObMemLobExternFlagsERKNS0_8ObStringEPKNS0_11ObLobCommonEjjb -_ZN9oceanbase7storage8ObLSLock4lockEPKNS0_4ObLSElll -_ZN9oceanbase3sql13ObMergeJoinOp19trans_to_fill_cacheEv -_ZN9oceanbase6common9ObScanner7add_rowERKNS0_8ObNewRowE -_ZN9oceanbase6common10ObRowStore20add_row_by_projectorERKNS0_8ObNewRowERPKNS1_9StoredRowEl -_ZN9oceanbase7storage36ObSSTableMultiVersionRowMultiScanner10inner_openERKNS0_16ObTableIterParamERNS0_20ObTableAccessContextEPNS0_8ObITableEPKv -_ZNK9oceanbase5share12ObTenantRole9serializeEPclRl -_ZN9oceanbase3sql9ObRawExpr15add_child_flagsERKNS0_11ObSqlBitSetILl96ENS0_14ObExprInfoFlagELb1EEE -_ZN9oceanbase8observer28ObTenantLSMetaTableCheckTask12runTimerTaskEv -_ZN9oceanbase8observer19ObTenantMetaChecker15check_ls_table_ENS_5share9ObLSTable4ModeE -_ZN9oceanbase5share11ObShareUtil41check_compat_version_for_readonly_replicaEmRb -_ZN9oceanbase6common16ObClusterVersion23get_tenant_data_versionEmRm -_ZNK9oceanbase5share11ObLSReplica19is_equal_for_reportERKS1_ -_ZN9oceanbase3sql10ObExprLike18like_varchar_innerERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumES9_S9_S9_ -_ZN9oceanbase5obrpc13LogRpcProxyV211post_packetERKNS_6common6ObAddrERKNS_4palf16LogRpcPacketImplINS6_8election24ElectionAcceptRequestMsgEEElRKNS6_28PalfTransportCompressOptionsE -_ZN9oceanbase7storage23ObTenantTabletScheduler24schedule_ls_medium_mergeERlRNS0_10ObLSHandleERbS5_S2_ +_ZSt16__introsort_loopIN9oceanbase6common5array17ObSEArrayIteratorINS0_12blocksstable12ObDatumRangeELl8ENS1_19ModulePageAllocatorELb0EEElN9__gnu_cxx5__ops15_Iter_comp_iterINS4_15ObDatumComparorIS5_EEEEEvT_SE_T0_T1_ +_ZN9__gnu_cxx5__ops15_Iter_comp_iterIN9oceanbase12blocksstable15ObDatumComparorINS3_12ObDatumRangeEEEEclINS2_6common5array17ObSEArrayIteratorIS5_Ll8ENS9_19ModulePageAllocatorELb0EEESD_EEbT_T0_ +_ZNK9oceanbase12blocksstable15ObDataStoreDesc8is_validEv +_ZN9oceanbase6common5occam20ObOccamFastTimeGuard10is_timeoutEv +_ZN9oceanbase6common11ObArrayImplINS0_8ObStringENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS2_EENS0_17DefaultItemEncodeIS2_EEEaSERKS8_ +_ZNK9oceanbase7storage3mds12MdsTableImplINS_6common7ObTupleIJNS1_7MdsUnitINS1_8DummyKeyENS0_31ObTabletCreateDeleteMdsUserDataEEENS5_IS6_NS0_26ObTabletBindingMdsUserDataEEENS5_IS6_NS_5share18ObTabletAutoincSeqEEENS5_INS_10compaction25ObMediumCompactionInfoKeyENSE_22ObMediumCompactionInfoEEEEEEE12get_snapshotElPvRNS3_10ObFunctionIFiSK_EEERKNSB_3SCNEll +_ZNK9oceanbase7storage3mds12MdsTableBase16advance_state_toENS2_5StateE +_ZN9oceanbase11transaction14ObPartTransCtx32check_and_register_timeout_task_Ev +_ZN9oceanbase3sql16ObRawExprFactory7destoryEv +_ZN9oceanbase8memtable23ObMemtableMScanIterator21get_next_row_for_scanERPKNS_12blocksstable10ObDatumRowE +_ZN9oceanbase8memtable22ObMemtableRowCompactor23construct_compact_node_ENS_5share3SCNElPNS0_15ObMvccTransNodeE +_ZN9oceanbase5share10mtl_mallocElRKNS_3lib7ObLabelE +fetch_proc_info +_ZN9oceanbase6common11ObArrayImplImNS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackImEENS0_22NotImplementItemEncodeImEEE9push_backERKm +_ZZN9oceanbase10logservice19ObRemoteFetchWorker11foreach_ls_ERKNS_5share6ObLSIDEENK5$_245clEPKc +_ZZN9oceanbase7storage21ObTenantFreezeInfoMgr28try_update_reserved_snapshotEvENK6$_1131clEPKc +_ZN9oceanbase6common11ObArrayImplIPNS_3sql17ObChunkDatumStore9StoredRowENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS5_EENS0_22NotImplementItemEncodeIS5_EEE9push_backERKS5_ +_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE20unset_foreach_L_lmt_Em +_ZN9oceanbase6common15ObLinearHashMapINS_5share14ObCascadMemberENS2_15ObDstServerInfoENS0_14ShareMemMgrTagEE20unset_foreach_L_lmt_Em +_ZN9oceanbase6common11ObDebugSync7executeENS0_16ObDebugSyncPointE +_ZN9oceanbase6common7ObDITlsINS0_15ObDSActionArrayELm0EE12get_instanceEv +_ZN9oceanbase6common15ObDListWithLock3addEPNS0_7ObDLinkE +_ZN9oceanbase5share6schema19ObSchemaGetterGuard28get_outline_info_with_sql_idEmmRKNS_6common8ObStringERPKNS1_13ObOutlineInfoE +_ZNK9oceanbase5share6schema12ObOutlineMgr30get_outline_schema_with_sql_idEmmRKNS_6common8ObStringERPKNS1_21ObSimpleOutlineSchemaE +_ZN9oceanbase5obrpc15ObPocClientStub15check_blacklistERKNS_6common6ObAddrE +_ZN9oceanbase5obrpc14ObNetKeepAlive8in_blackERK11easy_addr_tRbPNS0_18ObNetKeepAliveDataE +_ZN9oceanbase5obrpc14get_rpc_serverEPK11easy_addr_tPPNS0_14ObNetKeepAlive10rpc_serverEi +easy_hash_code +_ZN9oceanbase6common13ObSEArrayImplINS_7storage15ObTableHandleV2ELl2ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase6common15ObLinearHashMapINS_10logservice18ServerProbeService11ServerLSKeyENS3_10LSProbeCtxENS0_14ShareMemMgrTagEE18set_foreach_L_lmt_Ev +_ZN9oceanbase11transaction20ObKeepAliveLSHandler10on_successEv +_ZNK9oceanbase4palf22PalfDiskOptionsWrapper34get_disk_opts_for_recycling_blocksEv +_ZN9oceanbase3sql16ObGbyBloomFilter5existEm +_ZN9oceanbase6common11ObArrayImplINS_5share12ObTabletInfoENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE7destroyEv +_ZN9oceanbase3sql16ObFastParserBase31process_identifier_begin_with_tERb +_ZN9oceanbase11transaction17ObLocationAdapter10statisticsEv +_ZN9oceanbase8memtable13ObQueryEngine8IteratorINS_8keybtree16BtreeRawIteratorINS0_20ObStoreRowkeyWrapperEPNS0_9ObMvccRowEEEE13next_internalEb +_ZN9oceanbase4palf13LogLoopThread4run1Ev +_ZNK9oceanbase6common10ObFunctionIFiPNS_4palf15IPalfHandleImplEEE7DerivedIZNS2_13LogLoopThread9log_loop_EvE6$_1052E6invokeES4_$9ef56bf6d481ba25d33f7153397c5544 +_ZN9oceanbase4palf11PalfEnvImpl8for_eachERKNS_6common10ObFunctionIFiPNS0_15IPalfHandleImplEEEE +_ZNK9oceanbase6common10ObFunctionIFiPNS_4palf15IPalfHandleImplEEE7DerivedIZNS2_13LogLoopThread9log_loop_EvE6$_1048E6invokeES4_$9ef56bf6d481ba25d33f7153397c5544 +_ZN9oceanbase4palf14PalfHandleImpl22period_freeze_last_logEv +_ZN9oceanbase4palf16LogSlidingWindow22period_freeze_last_logEv +_ZZN9oceanbase4palf16LogSlidingWindow22period_freeze_last_logEvENK5$_202clEPKc +_ZN9oceanbase4palf16LogSlidingWindow28check_and_switch_freeze_modeEv +_ZN9oceanbase4palf14PalfHandleImpl22check_and_switch_stateEv +_ZN9oceanbase4palf11LogStateMgr16is_state_changedEv +_ZN9oceanbase4palf11LogStateMgr28check_leader_log_sync_state_Ev +_ZN9oceanbase4palf12LogConfigMgr19leader_do_loop_workERb +_ZN9oceanbase4palf11LogStateMgr19need_update_leader_ERNS_6common6ObAddrE +_ZNK9oceanbase4palf8election12ElectionImpl25get_current_leader_likelyERNS_6common6ObAddrERl +_ZN9oceanbase3sql12ObHashJoinOp43update_remain_data_memory_size_periodicallyElRbb +_ZN9oceanbase3sql16ObMaterialOpImpl7add_rowERKNS_6common8ObIArrayIPNS0_6ObExprEEERPKNS0_17ObChunkDatumStore9StoredRowE +_ZN9oceanbase3sql16ObMaterialOpImpl14before_add_rowEv +_ZN9oceanbase3sql17ObChunkDatumStore7add_rowERKNS_6common8ObIArrayIPNS0_6ObExprEEEPNS0_9ObEvalCtxEPPNS1_9StoredRowE +_ZN9oceanbase3sql17ObChunkDatumStore13alloc_blk_memElb +_ZN9oceanbase7storage23ObTenantTabletScheduler24schedule_ls_medium_mergeERlRNS0_10ObLSHandleERbS2_ +_ZN9oceanbase10compaction22ObMediumCompactionInfoD1Ev +_ZN9oceanbase10compaction22ObMediumCompactionInfoD2Ev _ZN9oceanbase7storage28ObCompactionScheduleIterator15get_next_tabletERNS0_10ObLSHandleERNS0_14ObTabletHandleE +_ZN9oceanbase7storage17ObLSTabletService10get_tabletERKNS_6common10ObTabletIDERNS0_14ObTabletHandleElNS0_18ObMDSGetTabletModeE +_ZN9oceanbase7storage14ObTabletHandleC1ERKS1_ +_ZN9oceanbase7storage32ObTabletDumpedMediumInfoIteratorD1Ev +_ZN9oceanbase7storage32ObTabletDumpedMediumInfoIterator5resetEv _ZN9oceanbase10compaction30ObMediumCompactionScheduleFunc28schedule_tablet_medium_mergeERNS_7storage4ObLSERNS2_8ObTabletElb -_ZN9oceanbase10compaction30ObMediumCompactionScheduleFunc33get_schedule_medium_from_memtableERNS_7storage8ObTabletElRlRNS0_22ObMediumCompactionInfo16ObCompactionTypeE -_ZN9oceanbase3sql9ObKeyPart14deep_node_copyERKS1_ -_ZN9oceanbase3omt17ObTenantConfigMgr18get_lease_responseERNS_5share15ObLeaseResponseE -_ZN9oceanbase8observer20ObRootServiceMonitor4run1Ev -_ZN9oceanbase8observer20ObRootServiceMonitor20monitor_root_serviceEv -_ZZN9oceanbase10logservice12ObLogService9open_palfERKNS_5share6ObLSIDERNS_4palf15PalfHandleGuardEENK5$_380clEPKc -_ZNK9oceanbase10logservice12ObLogService16check_palf_existERKNS_5share6ObLSIDERb -_ZZN9oceanbase4palf10PalfHandle23unregister_file_size_cbEvENK5$_874clEPKc.llvm.2452046906557810875 -_ZZN9oceanbase8observer31init_srv_xlator_for_transactionEPNS0_14ObSrvRpcXlatorEEN6$_16368__invokeERKNS0_15ObGlobalContextERPNS_3rpc5frame14ObReqProcessorERNS_5obrpc19ObRpcSessionHandlerE -_ZN9oceanbase6common15ObLinearHashMapINS0_6ObAddrENS0_9ObSEArrayINS_5share6ObLSIDELl3ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE16do_foreach_scan_INS_10logservice18ObGarbageCollector27QueryLSIsValidMemberFunctorENS9_14DoForeachOnBktISD_EEEEbmmRT_RT0_ -_ZN9oceanbase5share20ObSnapshotTableProxy17get_all_snapshotsERNS_6common12ObISQLClientEmRNS2_8ObIArrayINS0_14ObSnapshotInfoEEE -_ZN9oceanbase5share20ObLSTemplateOperator9exec_readINS0_16ObLSAttrOperatorENS0_8ObLSAttrEEEiRKmRKNS_6common11ObSqlStringERNS7_12ObISQLClientEPT_RNS7_8ObIArrayIT0_EE -_ZN9oceanbase6common11ObArrayImplINS_5share8ObLSAttrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ -_ZN9oceanbase6common19ObTableAccessHelper18get_my_sql_result_EPPKclRKNS0_8ObStringES7_RNS0_12ObISQLClientEmRNS8_10ReadResultERPNS0_9sqlclient13ObMySQLResultE -_ZN9oceanbase3sql12ObSortOpImpl14before_add_rowEv -_ZN9oceanbase7storage16ObMetaPointerMapINS0_14ObTabletMapKeyENS0_8ObTabletEE33get_meta_obj_with_external_memoryERKS2_RNS_6common12ObIAllocatorERNS0_14ObMetaObjGuardIS3_EEb -_ULx86_64_dwarf_step -_ZN9oceanbase6common6DCHashINS0_9ObIntWarpELl8EE24alloc_and_init_cur_arrayEv -_ZN9oceanbase5share20ObZoneTableOperation14get_zone_list_ERNS_6common12ObISQLClientERNS2_8ObIArrayINS2_19ObFixedLengthStringILl128EEEEEb -_ZN9oceanbase10rootserver8DRLSInfoC2EmPNS0_13ObUnitManagerEPNS0_13ObZoneManagerEPNS_5share6schema27ObMultiVersionSchemaServiceE -_ZN9oceanbase3sql12ObHashJoinOp17recursive_processERb -_ZN9oceanbase3sql19ObHashJoinPartition4initEiliibPNS0_16ObHashJoinBufMgrEPNS0_18ObHashJoinBatchMgrEPNS0_15ObHashJoinBatchEPNS0_10ObOperatorEPNS0_19ObSqlMemoryCallbackElPNS0_17ObIOEventObserverE -_ZN9oceanbase3sql15ObHashJoinBatchC2ERNS_6common12ObIAllocatorEPNS0_16ObHashJoinBufMgrEmill -_ZN9oceanbase3sql12ObHashJoinOp16dump_build_tableElb -_ZN9oceanbase3sql12ObQueryRange16and_first_searchERNS1_13ObSearchStateEPNS0_9ObKeyPartERNS_6common9ObSEArrayIPNS6_10ObNewRangeELl1ENS6_19ModulePageAllocatorELb0EEERbRKNS6_20ObDataTypeCastParamsE -_ZN9oceanbase3sql12ObQueryRange18generate_cur_rangeERNS1_13ObSearchStateElbRNS_6common9ObSEArrayIPNS4_10ObNewRangeELl1ENS4_19ModulePageAllocatorELb0EEERbb -_ZN9oceanbase8observer18ObHeartBeatProcess18do_heartbeat_eventERKNS_5share15ObLeaseResponseE -_ZN9oceanbase5share6schema20ObDDLTransController4run1Ev -_ZN9oceanbase3sql12ObQueryRange21replace_unknown_valueEPNS0_9ObKeyPartERNS0_13ObExecContextERKNS_6common20ObDataTypeCastParamsE +_ZN9oceanbase7storage24ObTabletMediumInfoReader4initERNS_6common16ObArenaAllocatorE +_ZZN9oceanbase7storage24ObTabletMediumInfoReader4initERNS_6common16ObArenaAllocatorEENK6$_1341clEPKc +_ZNK9oceanbase7storage8ObTablet21read_medium_info_listERNS_6common16ObArenaAllocatorERPKNS_10compaction26ObMediumCompactionInfoListE +_ZN9oceanbase7storage24ObTabletDumpedMediumInfoD1Ev +_ZN9oceanbase7storage24ObTabletDumpedMediumInfoD2Ev +_ZN9oceanbase7storage24ObTabletDumpedMediumInfo5resetEv +_ZN9oceanbase7storage15ObTabletMdsData21copy_medium_info_listElRKNS0_24ObTabletDumpedMediumInfoERS2_ +_ZNK9oceanbase7storage8ObTablet21get_finish_medium_scnERl +_ZN9oceanbase7storage15ObTabletMdsData21load_medium_info_listERNS_6common12ObIAllocatorERKNS0_19ObTabletComplexAddrINS0_24ObTabletDumpedMediumInfoEEERPKS6_ +_ZN9oceanbase10compaction19ObParallelMergeInfo7destroyEv +_ZN9oceanbase7storage4ObLS11get_ls_roleERNS_6common6ObRoleE +_ZN9oceanbase10compaction30ObMediumCompactionScheduleFuncD2Ev +_ZN9oceanbase5share27ObTabletReplicaFilterHolderD2Ev +_ZN9oceanbase7storage24ObTabletMediumInfoReader20get_next_medium_infoERNS_6common12ObIAllocatorERNS_10compaction25ObMediumCompactionInfoKeyERNS5_22ObMediumCompactionInfoE +_ZN9oceanbase10compaction26ObMediumCompactionInfoList4initERNS_6common12ObIAllocatorERKNS_7storage22ObTaletExtraMediumInfoERKNS5_24ObTabletDumpedMediumInfoE +_ZNK9oceanbase7storage3mds12MdsTableImplINS_6common7ObTupleIJNS1_7MdsUnitINS1_8DummyKeyENS0_31ObTabletCreateDeleteMdsUserDataEEENS5_IS6_NS0_26ObTabletBindingMdsUserDataEEENS5_IS6_NS_5share18ObTabletAutoincSeqEEENS5_INS_10compaction25ObMediumCompactionInfoKeyENSE_22ObMediumCompactionInfoEEEEEEE64for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dumpERNS3_10ObFunctionIFiRKNS1_9MdsDumpKVEEEEb +_ZN9oceanbase7storage8ObLSLock4lockEPKNS0_4ObLSElll +_ZN9oceanbase10compaction21ObAdaptiveMergePolicy25get_adaptive_merge_reasonERKNS_7storage8ObTabletERNS1_19AdaptiveMergeReasonE +_ZN9oceanbase10compaction21ObAdaptiveMergePolicy36check_inc_sstable_row_cnt_percentageERKNS_7storage8ObTabletERNS1_19AdaptiveMergeReasonE +_ZN9oceanbase7storage3mds12MdsTableImplINS_6common7ObTupleIJNS1_7MdsUnitINS1_8DummyKeyENS0_31ObTabletCreateDeleteMdsUserDataEEENS5_IS6_NS0_26ObTabletBindingMdsUserDataEEENS5_IS6_NS_5share18ObTabletAutoincSeqEEENS5_INS_10compaction25ObMediumCompactionInfoKeyENSE_22ObMediumCompactionInfoEEEEEEE64for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dumpIZNKSJ_64for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dumpERNS3_10ObFunctionIFiRKNS1_9MdsDumpKVEEEEbEUlSO_E_Lb1EEEiOT_b +_ZN9oceanbase3sql17ObChunkDatumStore8Iterator12reset_cursorEl +_ZN9oceanbase10rootserver18ObPartitionBalance7processEv +_ZN9oceanbase10rootserver24ObAllBalanceGroupBuilder7prepareEb +_ZN9oceanbase5share26ObTenantTabletMetaIterator4nextERNS0_12ObTabletInfoE +_ZN9oceanbase6common11ObArrayImplINS_5share15ObTabletReplicaENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE7destroyEv +_ZN9oceanbase6common11ObArrayImplINS_5share14ObTabletLSPairENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE7destroyEv +_ZN9oceanbase6common11ObArrayImplINS_5share14ObTabletLSPairENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ +_ZN9oceanbase6common4hash11ObHashTableINS0_10ObTabletIDENS1_11HashMapPairIS3_mEENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14set_refactoredERKS3_RKS5_iii +_ZN9oceanbase5share21ObTabletTableOperator9batch_getEmRKNS_6common8ObIArrayINS0_14ObTabletLSPairEEERNS3_INS0_12ObTabletInfoEEE +_ZN9oceanbase6common4hash11ObHashTableINS_5share14ObTabletLSPairENS1_11HashMapPairIS4_bEENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_10pair_firstIS6_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS6_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14set_refactoredERKS4_RKS6_iii +_ZN9oceanbase6common4hash13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairINS_5share14ObTabletLSPairEbEEEELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEE4freeEPS8_ +_ZN9oceanbase6common4hash13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairINS_5share14ObTabletLSPairEbEEEELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEE5allocIJEEEPS8_DpRT_ +_ZNK9oceanbase5share15ObTabletReplica8is_validEv +_ZNK9oceanbase3sql12ObQueryRange28generate_true_or_false_rangeEPKNS0_9ObKeyPartERNS_6common12ObIAllocatorERPNS5_10ObNewRangeE +_ZN9oceanbase3omt19ObTenantTimezoneMgr23refresh_tenant_timezoneEm +_ZN9oceanbase5share20ObLSTemplateOperator9exec_readINS0_18ObLSStatusOperatorENS0_14ObLSStatusInfoEEEiRKmRKNS_6common11ObSqlStringERNS7_12ObISQLClientEPT_RNS7_8ObIArrayIT0_EE +_ZN9oceanbase6common19ObFixedLengthStringILl128EEC2ERKNS0_8ObStringE +_ZNK9oceanbase12blocksstable12MacroBlockId9serializeEPclRl +_ZN9oceanbase11transaction10ObTransRpc5post_ERKNS_6common6ObAddrERNS0_7ObTxMsgE +_ZN9oceanbase6common13ObLatchRGuardD2Ev +_ZN9oceanbase5obrpc10ObRpcProxyD2Ev +_ZNK9oceanbase5obrpc15ObTransRpcProxy2toERKNS_6common6ObAddrE +_ZN9oceanbase3omt10ObThWorker12check_statusEv +_ZN9oceanbase6common13ObSEArrayImplINS0_10ObNewRangeELl1ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZN9oceanbase3sql13AllocOpHelperILi7EE5allocERNS_6common12ObIAllocatorERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputElRPNS0_10ObOperatorE +_ZN9oceanbase5obrpc18ObRpcProcessorBase3runEv +_ZN9oceanbase6common13ObSEArrayImplINS0_15ObWarningBuffer11WarningItemELl2ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase4palf26ElectionAcceptResponseMsgP13process_impl_ILb1ELb1EEEiv +_ZN9oceanbase4palf17LogRequestHandler14handle_requestINS0_8election25ElectionAcceptResponseMsgEEEilRKNS_6common6ObAddrERKT_ +_ZNK9oceanbase4palf8election15ElectionMsgBase8is_validEv +_ZN9oceanbase5obrpc18ObRpcProcessorBase7cleanupEv +_ZN9oceanbase3rpc11RpcStatBulkILi10EE9add_pieceERKNS0_12RpcStatPieceE +_ZN9oceanbase3rpc11RpcStatItem9add_pieceERKNS0_12RpcStatPieceE +_ZN9oceanbase5obrpc14ObTxKeepaliveP7processEv +_ZN9oceanbase5obrpc18ObTxKeepaliveRespP7processEv +_ZZN9oceanbase11transaction14ObPartTransCtx22tx_keepalive_response_ElENK5$_880clEPKc +_ZN9oceanbase11transaction20ObTxKeepaliveRespMsg11deserializeEPKclRl +_ZN9oceanbase11transaction7ObTxMsg11deserializeEPKclRl +_ZN9oceanbase5share6ObLSID11deserializeEPKclRl +_ZN9oceanbase11transaction9ObTransID11deserializeEPKclRl +_ZN9oceanbase11transaction9ObTransID12deserialize_EPKclRl +_ZN9oceanbase11transaction10ObTransRpc8post_msgERKNS_5share6ObLSIDERNS0_7ObTxMsgE +_ZN9oceanbase11transaction10ObTransRpc11statistics_Ev +_ZNK9oceanbase11transaction20ObTxKeepaliveRespMsg8is_validEv +_ZZN9oceanbase4palf26ElectionAcceptResponseMsgP13process_impl_ILb1ELb1EEEivENKUlPKcE0_clES4_ +_ZN9oceanbase6common6ObAddr11deserializeEPKclRl +_ZN9oceanbase6common13serialization6decodeEPKclRlS4_ +_ZN9oceanbase6common13serialization11EnumEncoderILb1ENS0_6ObAddr3VEREE6decodeEPKclRlRS4_ +_ZN9oceanbase5obrpc18ObRpcProcessorBase13part_responseEib +_ZN9oceanbase5obrpc14ObRpcProcessorINS0_15ObTransRpcProxy5ObRpcILNS0_15ObRpcPacketCodeE1628EvEEE11encode_baseEPclRl +_ZN9oceanbase5obrpc18ObRpcProcessorBase11do_responseERKNS1_8ResponseE +_ZN9oceanbase6common16ObCompressorPool12get_instanceEv +_ZN9oceanbase4palf25ElectionAcceptRequestMsgP13process_impl_ILb1ELb1EEEiv +_ZN9oceanbase4palf17LogRequestHandler14handle_requestINS0_8election24ElectionAcceptRequestMsgEEEilRKNS_6common6ObAddrERKT_ +_ZN9oceanbase4palf8election12ElectionImpl14handle_messageERKNS1_24ElectionAcceptRequestMsgE +_ZNK9oceanbase6common26ObOccamTimerTaskRAIIHandle10is_runningEv +_ZN9oceanbase4palf8election38print_debug_ts_if_reach_warn_thresholdERKNS1_15ElectionMsgBaseEl +_ZNK9oceanbase5obrpc15ObRpcResultCode9serializeEPclRl +_ZNK9oceanbase5obrpc15ObRpcResultCode10serialize_EPclRl +_ZNK9oceanbase5obrpc15ObRpcResultCode19get_serialize_size_Ev +_ZN9oceanbase5obrpc18ObRpcProcessorBase13after_processEi +_ZNK9oceanbase3rpc5frame14ObReqProcessor15can_force_printEi +_ZN9oceanbase4palf8election12ElectionImpl14handle_messageERKNS1_25ElectionAcceptResponseMsgE +_ZN9oceanbase4palf8election16ElectionProposer31leader_takeover_if_lease_valid_ENS1_16RoleChangeReasonE +_ZN9oceanbase5obrpc18ObRpcProcessorBase11deserializeEv +_ZN9oceanbase3lib16ObRuntimeContext12deserialize_EPKclRl +_ZN9oceanbase3lib16ObRuntimeContext11deserializeEPKclRl +_ZN9oceanbase4palf16LogRpcPacketImplINS0_8election25ElectionAcceptResponseMsgEE11deserializeEPKclRl +_ZN9oceanbase4palf16LogRpcPacketImplINS0_8election24ElectionAcceptRequestMsgEE11deserializeEPKclRl +_ZN9oceanbase4palf8election31ElectionAcceptResponseMsgMiddle11deserializeEPKclRl +_ZN9oceanbase4palf16LogConfigVersion11deserializeEPKclRl +_ZN9oceanbase4palf8election16ElectionAcceptor17on_accept_requestERKNS1_24ElectionAcceptRequestMsgEPl +_ZN9oceanbase4palf8election31ElectionAcceptResponseMsgMiddle12set_acceptedElPKNS1_16ElectionPriorityE +_ZN9oceanbase4palf8election12ElectionImpl17refresh_priority_Ev +_ZN9oceanbase10logservice11coordinator20ElectionPriorityImpl7refreshEv +_ZN9oceanbase10logservice11coordinator14RefeshPriorityclINS1_10PriorityV0EEEiRT_ +_ZN9oceanbase10logservice11coordinator14RefeshPriorityclINS1_10PriorityV1EEEiRT_ +_ZNK9oceanbase4palf8election12ElectionImpl5send_ERKNS1_25ElectionAcceptResponseMsgE +_ZNK9oceanbase10logservice11coordinator20ElectionPriorityImpl9serializeEPclRl +_ZN9oceanbase10logservice11coordinator16SerializeFunctorclINS1_10PriorityV0EEEiRKT_ +_ZN9oceanbase10logservice11coordinator16SerializeFunctorclINS1_10PriorityV1EEEiRKT_ +_ZN9oceanbase10logservice11coordinator10PriorityV18refresh_ERKNS_5share6ObLSIDE +_ZN9oceanbase6common14ObStringHolder6assignERKNS0_8ObStringE +_ZNK9oceanbase10logservice11coordinator19ObLeaderCoordinator30get_ls_election_reference_infoERKNS_5share6ObLSIDERNS_6common7ObTupleIJllbNS8_IJbNS7_14ObStringHolderEEEEbbbEEE +_ZN9oceanbase10logservice11coordinator17ObFailureDetector25get_specified_level_eventENS1_12FailureLevelERNS_6common8ObIArrayINS1_12FailureEventEEE +_ZN9oceanbase10logservice11coordinator10PriorityV18get_scn_ERKNS_5share6ObLSIDERNS3_3SCNE +_ZN9oceanbase7storage23ObSharedBlockReadHandle15verify_checksumEPKclRlS4_ +_ZN9oceanbase3sql10ObOperator10filter_rowERNS0_9ObEvalCtxERKNS_6common8ObIArrayIPNS0_6ObExprEEERb +_ZN9oceanbase3sql18ObRelationalTCFuncILb1ELNS_6common14ObObjTypeClassE2ELS3_1ELNS2_7ObCmpOpE0EE4evalERKNS0_6ObExprERNS0_9ObEvalCtxERNS2_7ObDatumE +_ZN9oceanbase3sql18ObRelationalTCFuncILb1ELNS_6common14ObObjTypeClassE1ELS3_1ELNS2_7ObCmpOpE0EE4evalERKNS0_6ObExprERNS0_9ObEvalCtxERNS2_7ObDatumE +_ZN9oceanbase3sql13calc_or_exprNERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumE +_ZN9oceanbase3sql19ObRelationalStrFuncILb1ELNS_6common15ObCollationTypeE45ELb0ELNS2_7ObCmpOpE0EE4evalERKNS0_6ObExprERNS0_9ObEvalCtxERNS2_7ObDatumE +_ZN9oceanbase6common13ObSEArrayImplINS_7storage22ObSharedBlocksWriteCtxELl16ENS0_19ModulePageAllocatorELb0EED2Ev +_ZN9oceanbase7storage22ObSharedBlocksWriteCtx5clearEv +_ZNK9oceanbase5share8ObLSInfo9find_idx_ERKNS0_11ObLSReplicaERl +_ZN9oceanbase6common13ObSEArrayImplIlLl4ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZN9oceanbase6common11ObArrayImplINS_10rootserver10ObDRWorker15ReplicaStatDescENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS4_EENS0_22NotImplementItemEncodeIS4_EEE10extend_bufEl +_ZN9oceanbase3omt13ObMultiTenant22operate_in_each_tenantERKSt8functionIFivEEb +_ZNSt8functionIFiRN9oceanbase6common10ObLDHandleEEEaSEDn +_ZNK9oceanbase11transaction7ObTxMsg9serializeEPclRl +_ZN9oceanbase6common13serialization6encodeEPclRll +_ZN9oceanbase6common13serialization11encode_vi64EPclRll +_ZZN9oceanbase8memtable10ObMemtable16ready_for_flush_EvENK5$_203clEPKc +_ZN9oceanbase6common5occam16ObOccamTimerTask11TaskWrapperclEv +_ZNK9oceanbase6common10ObFunctionIFbvEE7DerivedIZNS_10logservice11coordinator17ObFailureDetector9mtl_startERPS7_E3$_4E6invokeEv$2b02c13b9cdbd03091264b1db82f2b63 +_ZN9oceanbase6common17ObIOFaultDetector24get_device_health_statusERNS0_20ObDeviceHealthStatusERl +_ZN9oceanbase5share6schema27ObMultiVersionSchemaService23is_tenant_not_refreshedEm +_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImbEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS4_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS4_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19ReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14get_refactoredERKmRS4_l +_ZNK9oceanbase6common10ObFunctionIFbvEE7DerivedIZNS_4palf8election16ElectionProposer26register_renew_lease_task_EvE4$_80E6invokeEv$51c451f394644c593f8363255ab1e158 +_ZN9oceanbase4palf8election16ElectionProposer31leader_revoke_if_lease_expired_ENS1_16RoleChangeReasonE +_ZN9oceanbase4palf8election16ElectionProposer7proposeEv +_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImbEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS4_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS4_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19ReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE32internal_get_with_timeout_unsafeERNS1_17ObHashTableBucketIS4_16pthread_rwlock_tNS1_5NCondEEERKmRPKS4_l +_ZNK9oceanbase6common10ObFunctionIFbvEE7DerivedIZNS_10logservice11coordinator17ObFailureDetector9mtl_startERPS7_E3$_6E6invokeEv$2b02c13b9cdbd03091264b1db82f2b63 +_ZNK9oceanbase6common10ObFunctionIFbvEE7DerivedIZNS_4palf8election16ElectionAcceptor5startEvE3$_1E6invokeEv$51c451f394644c593f8363255ab1e158 +_ZN9oceanbase8keybtree10ScanHandleINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE13scan_backwardEbPl +_ZN9oceanbase3sql17ObChunkDatumStore13get_store_rowERNS1_11RowIteratorERPKNS1_9StoredRowE +_ZN9oceanbase6common11ObIORequest6cancelEv +_ZN9oceanbase6common6ObAddr17parse_from_stringERKNS0_8ObStringE +_ZNK9oceanbase6common4hash11ObHashTableINS_7storage20ObDDLCtrlSpeedHandle14SpeedHandleKeyENS1_11HashMapPairIS5_PNS3_18ObDDLCtrlSpeedItemEEENS1_9hash_funcIS5_EENS1_8equal_toIS5_EENS1_10pair_firstIS9_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS9_EELi98ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE18foreach_refactoredINS4_20GetNeedRemoveItemsFnEEEiRT_ +_ZN9oceanbase11transaction7ObTsMgr22is_external_consistentEm +_ZN9oceanbase6common22ObVirtualTableIterator5closeEv +_ZN9oceanbase6common12ob_write_objINS0_16ObArenaAllocatorEEEiRT_RKNS0_5ObObjERS5_ +_ZN9oceanbase3sql19ObScalarAggregateOp12inner_rescanEv +_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice14ObReplayStatusENS0_14ShareMemMgrTagEE16do_foreach_scan_INS4_18ObLogReplayService24StatReplayProcessFunctorENS8_14DoForeachOnBktISB_EEEEbmmRT_RT0_ +_ZN9oceanbase5share19ObLSReplicaLocation4initERKNS_6common6ObAddrERKNS2_6ObRoleERKlRKNS2_13ObReplicaTypeERKNS2_17ObReplicaPropertyERKNS0_17ObLSRestoreStatusEl +_ZN9oceanbase5share19ObPersistentLSTable13get_by_tenantEmRNS_6common8ObIArrayINS0_8ObLSInfoEEE +_ZN9oceanbase5share19ObPersistentLSTable19construct_ls_infos_ERNS_6common9sqlclient13ObMySQLResultERNS2_8ObIArrayINS0_8ObLSInfoEEE +_ZN9oceanbase5share8ObLSInfo15init_by_replicaERKNS0_11ObLSReplicaE +_ZN9oceanbase5share19ObPersistentLSTable20construct_ls_replicaERNS_6common9sqlclient13ObMySQLResultERNS0_11ObLSReplicaE +_ZNK9oceanbase8observer16ObInnerSQLResult11get_varcharEPKcRNS_6common8ObStringE +_ZNK9oceanbase8observer16ObInnerSQLResult11get_varcharElRNS_6common8ObStringE +_ZNK9oceanbase8observer16ObInnerSQLResult13get_timestampEPKcPKNS_6common14ObTimeZoneInfoERl +_ZN9oceanbase11transaction25ObStandbyTimestampService4run1Ev +_ZN9oceanbase11transaction25ObStandbyTimestampService24query_and_update_last_idEv +_ZZN9oceanbase10rootserver18ObTenantInfoLoader19get_valid_sts_afterElRNS_5share3SCNEENK6$_1181clEPKc +_ZZN9oceanbase3sql24ObTenantSqlMemoryManager30enable_auto_sql_memory_managerEvENK5$_473clEPKc +_ZN9oceanbase10rootserver29ObSchemaHistoryRecyclerIdling20get_idle_interval_usEv +_ZN9oceanbase8observer19ObTenantMetaChecker24check_dangling_replicas_ERNS_6common4hash9ObHashMapINS_5share6ObLSIDENS5_11ObLSReplicaENS3_24LatchReadWriteDefendModeENS3_9hash_funcIS6_EENS3_8equal_toIS6_EENS3_13SimpleAllocerINS3_15ObHashTableNodeINS3_11HashMapPairIS6_S7_EEEELi6ENS3_19SpinMutexDefendModeENS3_29DefaultSimpleAllocerAllocatorEEENS3_13NormalPointerENS2_8ObMallocELl1EEERl +_ZN9oceanbase3lib9ObjectSet5resetEv +_ZN9oceanbase6common11ObArrayImplINS0_19ObFixedLengthStringILl128EEENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE6assignERKNS0_8ObIArrayIS3_EE +_ZN9oceanbase6common13ObSEArrayImplINS_7storage20ObRow2ExprsProjector4ItemELl4ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZZN9oceanbase3sql3dtl22ObDtlChannelMemManager17auto_free_on_timeElENK5$_251clEPKc +_ZN9oceanbase12blocksstable24ObMicroBlockBareIterator5resetEv +_ZN9oceanbase6common13ObSEArrayImplINS_5share12SimpleMemberELl7ENS0_15ObNullAllocatorELb0EE6assignERKNS0_8ObIArrayIS3_EE +_ZN9oceanbase7storage10checkpoint20ObCheckpointExecutor22update_clog_checkpointEv +_ZN9oceanbase11transaction12ObLSTxCtxMgr33remove_callback_for_uncommited_txEPKNS_6common4hash9ObHashSetImNS3_19ReadWriteDefendModeENS3_9hash_funcImEENS3_8equal_toImEENS3_13SimpleAllocerINS3_15ObHashTableNodeINS3_11HashMapPairImNS3_11HashNullObjEEEEELi109ENS3_19SpinMutexDefendModeENS3_29DefaultSimpleAllocerAllocatorEEENS3_13NormalPointerENS2_8ObMallocELl1EEE +_ULx86_64_dwarf_read_encoded_pointer +_ZN9oceanbase6common15ObPriorityQueueILi1EE3popERPNS0_6ObLinkEl +_ZN9oceanbase6common11ObArrayImplINS0_9ObSEArrayINS0_10ObObjParamELl8ENS0_19ModulePageAllocatorELb0EEES4_Lb0ENS0_22ObArrayDefaultCallBackIS5_EENS0_17DefaultItemEncodeIS5_EEE7destroyEv +_ZN9oceanbase7storage15ObMultipleMerge26handle_lob_before_fuse_rowEv +_ZN9oceanbase7storage15ObMultipleMerge16fill_lob_locatorERNS_12blocksstable10ObDatumRowE +_ZN9oceanbase7storage18ObLobLocatorHelper19fill_lob_locator_v2ERNS_12blocksstable10ObDatumRowERKNS0_20ObTableAccessContextERKNS0_18ObTableAccessParamE +_ZN9oceanbase6common14ObLobLocatorV24fillENS0_12ObMemLobTypeERKNS0_19ObMemLobExternFlagsERKNS0_8ObStringEPKNS0_11ObLobCommonEjjb +_ZN9oceanbase7storage18ObLobLocatorHelper15build_rowid_objERNS_12blocksstable10ObDatumRowERNS_6common8ObStringEbRKNS5_8ObIArrayINS_5share6schema9ObColDescEEERKNS8_IiEERKNS5_10ObTabletIDE +_ZNK9oceanbase5obrpc16ObTransRpcResult9serializeEPclRl +_ZN9oceanbase8observer24ObInnerSQLConnectionPool26remove_from_used_conn_listEPNS0_20ObInnerSQLConnectionE +_ZN9oceanbase6common20ObSafeArenaAllocator5allocEl +_ZN9oceanbase3lib13ObResourceMgr7dec_refEPNS0_19ObTenantResourceMgrE +_ZN9oceanbase5obrpc18fill_extra_payloadERNS0_11ObRpcPacketEPcll +_ZNK9oceanbase3lib16ObRuntimeContext9serializeEPclRl +_ZNK9oceanbase5share6schema14ObTenantSchema13get_zone_listERNS_6common8ObIArrayINS3_19ObFixedLengthStringILl128EEEEE +_ZN9oceanbase3sql12ObQueryRange17definite_key_partERPNS0_9ObKeyPartERNS0_13ObExecContextERKNS_6common20ObDataTypeCastParamsE _ZN9oceanbase3sql9ObKeyPart14try_cast_valueERKNS_6common20ObDataTypeCastParamsERNS2_12ObIAllocatorERKNS0_12ObKeyPartPosERNS2_5ObObjERl -_ZN9oceanbase6common21ObDIThreadTenantCache8get_nodeEmRPNS0_17ObDITenantCollectE -_ZN9oceanbase6common10ObRowStore8Iterator12get_next_rowERNS0_8ObNewRowEPNS0_8ObStringEPPNS1_9StoredRowE -_ZN9oceanbase6common9ObRowUtil7convertEPKclRNS0_8ObNewRowE -_ZN9oceanbase6common12ObCellReader5parseEPm -_ZN9oceanbase8observer15ObUniqTaskQueueINS0_23ObTabletTableUpdateTaskENS0_20ObTabletTableUpdaterEE4run1Ev -_ZN9oceanbase5share8detector9ObLCLNode6block_ERKNS1_20ObDependencyResourceE -_ZN9oceanbase6common9ObIOTuner4run1Ev -_ZN9oceanbase6common13ObSEArrayImplINS0_9ObSEArrayIdLl8ENS0_19ModulePageAllocatorELb0EEELl2ES3_Lb0EE6assignERKNS0_8ObIArrayIS4_EE -_ZN9oceanbase6common13ObSEArrayImplINS0_9ObSEArrayIdLl8ENS0_19ModulePageAllocatorELb0EEELl2ES3_Lb0EE7reserveEl -_ZN9oceanbase6common15ObLinearHashMapINS_5share6ObLSIDEPNS_10logservice13ObApplyStatusENS0_14ShareMemMgrTagEE17load_factor_ctrl_Em -_ZN9oceanbase11transaction14ObTransService28ls_sync_rollback_savepoint__EPNS0_14ObPartTransCtxElll -_ZN9oceanbase3sql19ObExprLeastGreatest10calc_mysqlERKNS0_6ObExprERNS0_9ObEvalCtxERNS_6common7ObDatumEb -_ZN9oceanbase3sql12ObQueryRange17get_tablet_rangesERNS_6common9ObSEArrayIPNS2_10ObNewRangeELl1ENS2_19ModulePageAllocatorELb0EEERbRKNS2_20ObDataTypeCastParamsE -_ZN9oceanbase10rootserver14ObTenantLSInfo19add_ls_status_info_ERKNS_5share14ObLSStatusInfoE -_ZN9oceanbase6common10ObIORunner4run1Ev -_ZN9oceanbase10rootserver29ObStandbySchemaRefreshTrigger7do_workEv -_ZN9oceanbase12blocksstable11ObRowReader11read_columnEPKcllRNS0_14ObStorageDatumE -_ZNK9oceanbase5share19ObUnitTableOperator10read_unitsERNS_6common11ObSqlStringERNS2_8ObIArrayINS0_6ObUnitEEE -_ZN9oceanbase8observer20ObInnerSQLConnection23start_transaction_innerERKmb -_ZN9oceanbase7storage18ObLSRestoreHandler24check_before_do_restore_ERb -_ZN9oceanbase5share18ObLSLeaderLocation11deserializeEPKclRl -_ZN9oceanbase11transaction15ObGtsRequestRpc4postEmRKNS_6common6ObAddrERKNS0_12ObGtsRequestE -_ZN9oceanbase11transaction17ObTimestampAccess14handle_requestERKNS0_12ObGtsRequestERNS_5obrpc14ObGtsRpcResultE -_ZN9oceanbase11transaction16ObTransStatistic27add_gts_request_total_countEml -_ZNK9oceanbase11transaction11ObAllIDMeta9serializeEPclRl +_ZNK9oceanbase3sql12ObQueryRange16get_result_valueERNS_6common5ObObjERNS0_13ObExecContextEPNS2_12ObIAllocatorE +_ZN9oceanbase3sql9ObKeyPart15cast_value_typeERKNS_6common20ObDataTypeCastParamsEb +_ZN9oceanbase6common11ObObjCaster7to_typeERKNS0_12ObExpectTypeERNS0_15ObObjCastParamsERKNS0_5ObObjERS7_RPS8_ +_ZN9oceanbase3sql24ObRelationalExprOperator16compare_nullsafeERlRKNS_6common5ObObjES6_RNS3_15ObObjCastParamsENS3_9ObObjTypeENS3_15ObCollationTypeE +_ZN9oceanbase6common11ObArrayImplINS_5share22ObLSLocationUpdateTaskENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE10extend_bufEl +_ZN9oceanbase3lib13ObResourceMgr23get_tenant_resource_mgrEmRNS0_25ObTenantResourceMgrHandleE +_ZN9oceanbase5share12ObLSLocation4initElmRKNS0_6ObLSIDEl +_ZN9oceanbase3lib13ObResourceMgr12get_instanceEv +_ZN9oceanbase6common4hash13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairINS_3lib17ObMallocSampleKeyENS5_19ObMallocSampleValueEEEEELi34ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEE4freeEPS9_ +_ZN9oceanbase6common6future12ObFutureBaseIbE3setIbEEiOT_ +_ZN9oceanbase6common12ObDedupQueue4run1Ev +_ZN9oceanbase7storage22ObBloomFilterBuildTask7processEv +_ZN9oceanbase12blocksstable23ObBloomFilterCacheValue6insertEj +_ZN9oceanbase6common11ObArrayImplINS_5share11ReplicaAttrENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE6assignERKNS0_8ObIArrayIS3_EE +_ZN9oceanbase6common4hash11ObHashTableImNS1_11HashMapPairImNS1_11HashNullObjEEENS1_9hash_funcImEENS1_8equal_toImEENS1_10pair_firstIS5_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS5_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_19ReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE32internal_get_with_timeout_unsafeERNS1_17ObHashTableBucketIS5_16pthread_rwlock_tNS1_5NCondEEERKmRPKS5_l +_ZN9oceanbase3sql15ObTableModifyOp26discharge_das_write_bufferEv +_ZN9oceanbase7storage28ObCompactionScheduleIterator11get_next_lsERNS0_10ObLSHandleE +_ZN9oceanbase6common13serialization11encode_vstrEPclRlPKvl +_ZN9oceanbase7storage18ObLobLocatorHelper4initERKNS0_16ObTableScanParamERKNS0_10ObStoreCtxERKNS_5share6ObLSIDEl +_ZN9oceanbase3sql8ObJoinOp16calc_other_condsERb +ev_run +_ZN9oceanbase3sql11ObPlanCache21check_baseline_finishEv +_ZNK9oceanbase3lib20ObTenantCtxAllocator10iter_labelESt8functionIFiRNS0_7ObLabelEPNS_6common9LabelItemEEE +_ZNSt17_Function_handlerIFiRN9oceanbase3lib7ObLabelEPNS0_6common9LabelItemEEZNKS1_20ObTenantCtxAllocator11print_usageEvE4$_69E9_M_invokeERKSt9_Any_dataS3_OS6_ +_ZSt4sortIPZNK9oceanbase3lib20ObTenantCtxAllocator10iter_labelESt8functionIFiRNS1_7ObLabelEPNS0_6common9LabelItemEEEE11ItemWrapperZNKS2_10iter_labelESA_E4$_66EvT_SE_T0_ +_ZN9oceanbase6common12ObMemoryDumpC2Ev +_ZN9oceanbase7storage18ObColumnIndexArray4initEllRNS_6common12ObIAllocatorE +_ZN9oceanbase10rootserver20ObTenantThreadHelper17get_tenant_schemaEmRNS_5share6schema14ObTenantSchemaE +_ZN9oceanbase3sql20ObSqlMemMgrProcessor4initEPNS_6common12ObIAllocatorEmlNS0_17ObPhyOperatorTypeEmPNS0_13ObExecContextE +_ZN9oceanbase5share14ObLSStatusInfo4initEmRKNS0_6ObLSIDEmNS0_10ObLSStatusEmRKNS_6common19ObFixedLengthStringILl128EEERKNS0_8ObLSFlagE +easy_baseth_pool_monitor_func.llvm.11818200775976484207 +_ZN9oceanbase6common10ObRowStore20add_row_by_projectorERKNS0_8ObNewRowERPKNS1_9StoredRowEl +_ZN9oceanbase6common10ObRowStore9BlockInfo10append_rowERKNS0_8ObIArrayIlEERKNS0_8ObNewRowElRPNS1_9StoredRowE +_ZN9oceanbase6common12ObCellWriter6appendEmRKNS0_5ObObjEPS2_ +_ZN9oceanbase6common12ObCellWriter10write_charERKNS0_5ObObjENS0_9ObObjTypeERKNS0_8ObStringEPS2_ +_ZN9oceanbase6common12ObCellWriter9write_intERKNS0_5ObObjENS0_9ObObjTypeEl +apply_reg_state +_ZN9oceanbase12blocksstable18ObDataBlockMetaVal6assignERKS1_ +_ZN9oceanbase6common13ObSEArrayImplIlLl4ENS0_19ModulePageAllocatorELb0EE6assignERKNS0_8ObIArrayIlEE +_ZN9oceanbase12blocksstable23ObDataIndexBlockBuilder20add_macro_block_metaERKNS0_20ObDataMacroBlockMetaERNS_6common8ObIArrayIPS2_EERNS5_12ObIAllocatorE +_ZN9oceanbase8observer9ObService15fill_ls_replicaEmRKNS_5share6ObLSIDERNS2_11ObLSReplicaE +_ZNK9oceanbase3omt13ObMultiTenant17get_tenant_unsafeEmRPNS0_8ObTenantE +_ZNK9oceanbase10logservice12ObLogHandler38get_paxos_member_list_and_learner_listERNS_6common16ObMemberListBaseILl7EEERlRNS2_15BaseLearnerListILl2000ENS2_8ObMemberEEE +_ZNK9oceanbase4palf14PalfHandleImpl38get_paxos_member_list_and_learner_listERNS_6common16ObMemberListBaseILl7EEERlRNS2_15BaseLearnerListILl2000ENS2_8ObMemberEEE +_ZNK9oceanbase12blocksstable9ObSSTable9deep_copyEPclRPNS_7storage17ObIStorageMetaObjE +_ZN9oceanbase3sql13ObExecContext22get_temp_expr_eval_ctxERKNS0_10ObTempExprERPNS0_13ObTempExprCtxE +_ZN9oceanbase6common4hash11ObHashTableIlNS1_11HashMapPairIllEENS1_9hash_funcIlEENS1_8equal_toIlEENS1_10pair_firstIS4_EENS1_13SimpleAllocerINS1_15ObHashTableNodeIS4_EELi109ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_24LatchReadWriteDefendModeENS1_13NormalPointerENS0_8ObMallocELl1EE14set_refactoredERKlRKS4_iii +_ULx86_64_access_reg +_ZN9oceanbase12blocksstable23ObIMicroBlockRowScanner8fuse_rowERKNS0_10ObDatumRowERS2_RNS_7storage8ObNopPosERbPNS_6common12ObIAllocatorE +_ZN9oceanbase6common15ObLinearHashMapINS_5share14ObCascadMemberENS2_15ObDstServerInfoENS0_14ShareMemMgrTagEE16do_foreach_scan_INS2_17ObServerBlacklist21ObMapMarkBlackFunctorENS6_14DoForeachOnBktIS9_EEEEbmmRT_RT0_ +_ZN9oceanbase3omt17ObTenantConfigMgr18get_lease_responseERNS_5share15ObLeaseResponseE +_ZN9oceanbase4palf8PalfStat5resetEv +_ZN9oceanbase3sql19ObDASLocationRouter15get_vt_svr_pairEmRPKNS0_14VirtualSvrPairE +_ZN9oceanbase11transaction11ObAllIDMeta18update_all_id_metaERKS1_ +_ZN9oceanbase12blocksstable14ObBlockManager17update_write_timeERKNS0_12MacroBlockIdEb +_ZN9oceanbase12blocksstable17ObSSTableMergeResD1Ev +_ZN9oceanbase12blocksstable17ObSSTableMergeResD2Ev +_ZNK9oceanbase4palf9LogReader12inner_pread_EimlPcRl +_ZZNK9oceanbase4palf9LogReader43limit_and_align_in_read_size_by_block_size_EmlRlENK6$_1178clEPKc +_ZNK9oceanbase3sql14ObExprOperator18is_default_expr_cgEv +epoll_poll +_ZN9oceanbase7storage16ObStorageLogItem8fill_logElRKNS0_17ObStorageLogParamEi +_ZN9oceanbase6common15ObLinearHashMapINS0_6ObAddrENS0_9ObSEArrayINS_5share6ObLSIDELl3ENS0_19ModulePageAllocatorELb0EEENS0_14ShareMemMgrTagEE16do_foreach_scan_INS_10logservice18ObGarbageCollector27QueryLSIsValidMemberFunctorENS9_14DoForeachOnBktISD_EEEEbmmRT_RT0_ +_ZN9oceanbase3sql16ObSQLSessionInfo17close_all_ps_stmtEv +_ZN9oceanbase6common15ObLinearHashMapINS_10logservice18ServerProbeService11ServerLSKeyENS3_10LSProbeCtxENS0_14ShareMemMgrTagEE16do_foreach_scan_IZNS3_21try_clear_server_listEvE5$_768NS7_15DoRemoveIfOnBktIS9_EEEEbmmRT_RT0_ +_ZN9oceanbase6common4hash9ObHashMapINS_5share6ObLSIDENS3_11ObLSReplicaENS1_24LatchReadWriteDefendModeENS1_9hash_funcIS4_EENS1_8equal_toIS4_EENS1_13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairIS4_S5_EEEELi6ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_13NormalPointerENS0_8ObMallocELl1EED2Ev +_ZN9oceanbase10logservice18ObLogReplayService11submit_taskEPNS0_19ObReplayServiceTaskE +_ZN9oceanbase6common15ObSyncIOChannel4run1Ev +_ZN9oceanbase4palf15LogConfigInfoV2D1Ev +_ZN9oceanbase4palf15LogConfigInfoV2D2Ev +_ZNK9oceanbase6common17ObHexEscapeSqlStr9to_stringEPcl +_ZNK9oceanbase5share6schema14ObTenantSchema27get_zone_replica_attr_arrayERNS_6common8ObIArrayINS0_20ObZoneReplicaAttrSetEEE +_ZN9oceanbase6common11ObArrayImplINS_5share20ObZoneReplicaAttrSetENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE9push_backERKS3_ +_ZN9oceanbase6common11ObArrayImplINS_5share20ObZoneReplicaAttrSetENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE10extend_bufEl +_ZN9oceanbase6common25ObFixedSizeBlockAllocatorILl2097152EE4freeEPv +_ZNK9oceanbase4palf8election15ElectionMsgBase19get_serialize_size_Ev +_ZNK9oceanbase4palf8election18ElectionMsgDebugTs19get_serialize_size_Ev +_ZN9oceanbase8keybtree8IteratorINS_8memtable20ObStoreRowkeyWrapperEPNS2_9ObMvccRowEE18estimate_one_levelEllllldRlS7_S7_ +_ZN9oceanbase6common16ObFixedArrayImplIiNS0_12ObIAllocatorEE9push_backERKi +_ZN9oceanbase6common16ObFixedArrayImplIbNS0_12ObIAllocatorEE9push_backERKb +_ZN9oceanbase4palf8election15ElectionMsgBase11deserializeEPKclRl +_ZN9oceanbase4palf8election15ElectionMsgBase12deserialize_EPKclRl +_ZN9oceanbase4palf8election18ElectionMsgDebugTs11deserializeEPKclRl +_ZN9oceanbase4palf8election18ElectionMsgDebugTs12deserialize_EPKclRl +_ZN9oceanbase3sql16ObConfigInfoInPC26load_influence_plan_configEv +_ZN9oceanbase7storage21ObTabletObjLoadHelper14read_from_addrERNS_6common16ObArenaAllocatorERKNS0_14ObMetaDiskAddrERPcRl +_ZN9oceanbase7storage25ObSharedBlockReaderWriter10async_readERKNS0_21ObSharedBlockReadInfoERNS0_23ObSharedBlockReadHandleE +run_cfi_program +_ZNK9oceanbase7storage14ObSSTableArray16dec_meta_ref_cntEv +_ZNK9oceanbase12blocksstable13ObSSTableMeta19get_serialize_size_Ev +_ZN9oceanbase6common11ObArrayImplINS_10rootserver26ObLSStatusMachineParameterENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE10extend_bufEl +_ZN9oceanbase5share12ObLSLocation17merge_leader_fromERKS1_ +_ZN9oceanbase5share25ObArbitrationServiceUtils37get_tenant_arbitration_service_statusEmRNS0_26ObArbitrationServiceStatusE +_ZN9oceanbase11transaction23ObTenantWeakReadService4run1Ev +_ZN9oceanbase11transaction23ObTenantWeakReadService25generate_cluster_version_Ev +_ZN9oceanbase11transaction23ObTenantWeakReadService21do_cluster_heartbeat_Ev +_ZN9oceanbase11transaction23ObTenantWeakReadService27set_cluster_service_master_ERKNS_6common6ObAddrE +_ZN9oceanbase11transaction32ObTenantWeakReadServerVersionMgr20generate_new_versionEmlNS_5share3SCNEb +_ZN9oceanbase11transaction30ObTenantWeakReadClusterService22update_cluster_versionERl +_ZN9oceanbase11transaction30ObTenantWeakReadClusterService24persist_version_if_need_ENS_5share3SCNES3_S3_S3_bRl +_ZN9oceanbase6common16ObCommonSqlProxy7acquireEmRPNS0_9sqlclient16ObISQLConnectionE +_ZN9oceanbase11transaction23ObTenantWeakReadService29process_cluster_heartbeat_rpcERKNS_6common6ObAddrENS_5share3SCNElll +_ZNK9oceanbase11transaction30ObTenantWeakReadClusterService18check_leader_info_ERl +_ZN9oceanbase10logservice12ObLogService13get_palf_roleERKNS_5share6ObLSIDERNS_6common6ObRoleERl +_ZN9oceanbase10logservice12ObLogService9open_palfERKNS_5share6ObLSIDERNS_4palf15PalfHandleGuardE +_ZZN9oceanbase4palf7PalfEnv4openElRNS0_10PalfHandleEENK5$_732clEPKc.llvm.447907550136452219 +_ZNK9oceanbase10rootserver20ObRsMasterKeyManager25get_all_tenant_master_keyERKNS_6common19ObFixedLengthStringILl128EEERNS2_8ObIArrayISt4pairImNS_5share15ObLeaseResponse14TLRpKeyVersionEEEE +_ZN9oceanbase5share8ObLSInfo21update_replica_statusEv +_ZN9oceanbase7storage3mds17ObMdsTableHandler23try_release_nodes_belowERKNS_5share3SCNE +_ZN9oceanbase7storage19ObTableScanIterator14init_scan_iterINS0_24ObMultipleMultiScanMergeEEEiRPT_ +_ZN9oceanbase7storage19ObMultipleScanMerge4initERKNS0_18ObTableAccessParamERNS0_20ObTableAccessContextERKNS0_15ObGetTableParamE _ZN9oceanbase7storage15ObMultipleMergeC2Ev -_ZN9oceanbase8observer9ObService20get_leader_locationsERKNS_5obrpc23ObGetLeaderLocationsArgERNS2_26ObGetLeaderLocationsResultE -_ZN9oceanbase8observer15ObUniqTaskQueueINS_5share21ObVTableLocUpdateTaskENS2_23ObVTableLocationServiceEE4run1Ev -_ZN9oceanbase5share23ObVTableLocationService10vtable_getEmmlRbRNS_6common8ObIArrayINS3_6ObAddrEEE -_ZN9oceanbase8observer15ObUniqTaskQueueINS_5share20ObTabletLSUpdateTaskENS2_17ObTabletLSServiceEE4run1Ev -_ZN9oceanbase8observer15ObUniqTaskQueueINS_5share22ObLSLocationUpdateTaskENS2_19ObLSLocationServiceEE4run1Ev +_ZN9oceanbase4palf6LogRpc12post_requestINS0_8election25ElectionAcceptResponseMsgEEEiRKNS_6common6ObAddrElRKT_ +_ZN9oceanbase5obrpc13LogRpcProxyV211post_packetERKNS_6common6ObAddrERKNS_4palf16LogRpcPacketImplINS6_8election25ElectionAcceptResponseMsgEEElRKNS6_28PalfTransportCompressOptionsE +_ZN9oceanbase6common13ObSEArrayImplINS0_15ObWarningBuffer11WarningItemELl2ENS0_19ModulePageAllocatorELb0EE7reserveEl +_ZNK9oceanbase7storage3mds11UserMdsNodeINS_10compaction25ObMediumCompactionInfoKeyENS3_22ObMediumCompactionInfoEE11fill_event_ILi10EEEiRNS_8observer8MdsEventERAT__KcPcl +_ZN9oceanbase5share6schema27ObMultiVersionSchemaService27get_tablet_to_table_historyEmRKNS_6common8ObIArrayINS3_10ObTabletIDEEElRNS4_ImEE +_ZN9oceanbase3sql12ObQueryRange9deep_copyERKS1_b +_ZN9oceanbase3sql12ObQueryRange21deep_copy_range_graphEPNS0_9ObKeyPartERS3_ +_ZN9oceanbase10rootserver20ObAllTenantInfoCache15get_tenant_infoERNS_5share15ObAllTenantInfoERlS5_ +_ZN9oceanbase6common22ObVirtualTableIteratorD2Ev +_ZNK9oceanbase12blocksstable9ObSSTable38get_sstable_fix_serialize_payload_sizeEv +_ZN9oceanbase5obrpc13LogRpcProxyV211post_packetERKNS_6common6ObAddrERKNS_4palf16LogRpcPacketImplINS6_8election24ElectionAcceptRequestMsgEEElRKNS6_28PalfTransportCompressOptionsE +_ZN9oceanbase3sql12ObQueryRange21or_single_head_graphsERNS_6common7ObDListINS0_9ObKeyPartEEEPNS0_13ObExecContextERKNS2_20ObDataTypeCastParamsEb +_ZN9oceanbase3sql9ObKeyPart17key_node_is_equalEPKS1_ +_ZN9oceanbase6common4hash9ObHashMapINS0_6ObAddrENS_5share14ObServerHBInfoENS1_24LatchReadWriteDefendModeENS1_9hash_funcIS3_EENS1_8equal_toIS3_EENS1_13SimpleAllocerINS1_15ObHashTableNodeINS1_11HashMapPairIS3_S5_EEEELi54ENS1_19SpinMutexDefendModeENS1_29DefaultSimpleAllocerAllocatorEEENS1_13NormalPointerENS0_8ObMallocELl1EE14set_refactoredERKS3_RKS5_iii +_ULx86_64_dwarf_callback +_ZNK9oceanbase7storage8ObITable9serializeEPclRl +_ZN9oceanbase3omt8ObPxPool4run1Ev +_ZN9oceanbase8observer19ObTenantMetaChecker18build_replica_map_ERNS_6common4hash9ObHashMapINS_5share6ObLSIDENS5_11ObLSReplicaENS3_24LatchReadWriteDefendModeENS3_9hash_funcIS6_EENS3_8equal_toIS6_EENS3_13SimpleAllocerINS3_15ObHashTableNodeINS3_11HashMapPairIS6_S7_EEEELi6ENS3_19SpinMutexDefendModeENS3_29DefaultSimpleAllocerAllocatorEEENS3_13NormalPointerENS2_8ObMallocELl1EEENS5_9ObLSTable4ModeE +_ZN9oceanbase5share23ObLSReplicaFilterHolderD1Ev +_ZN9oceanbase5share23ObLSReplicaFilterHolderD2Ev +_ZN9oceanbase5share11ObLSReplicaC1Ev +_ZN9oceanbase11transaction14ObTransService20get_ls_read_snapshotERNS0_8ObTxDescENS0_18ObTxIsolationLevelERKNS_5share6ObLSIDElRNS0_16ObTxReadSnapshotE +_ZNK9oceanbase5share22ObArchivePersistHelper16get_string_valueERNS_6common12ObISQLClientElbRKNS2_8ObStringERNS2_11ObSqlStringE +_ZN9oceanbase12blocksstable11ObRowWriter12write_rowkeyERKNS_6common13ObStoreRowkeyERPcRl +_ZN9oceanbase7storage19ObSSTableRowScannerINS0_30ObIndexTreeMultiPassPrefetcherILi32ELi3EEEE13get_next_rowsEv +_ZN9oceanbase4palf13LogConfigMeta5resetEv +_ZN9oceanbase8memtable13ObMemtableCtx34remove_callback_for_uncommited_txnEPKNS_6common4hash9ObHashSetImNS3_19ReadWriteDefendModeENS3_9hash_funcImEENS3_8equal_toImEENS3_13SimpleAllocerINS3_15ObHashTableNodeINS3_11HashMapPairImNS3_11HashNullObjEEEEELi109ENS3_19SpinMutexDefendModeENS3_29DefaultSimpleAllocerAllocatorEEENS3_13NormalPointerENS2_8ObMallocELl1EEENS_5share3SCNE +_ZN9oceanbase8memtable16ObTxCallbackList36remove_callbacks_for_remove_memtableEPKNS_6common4hash9ObHashSetImNS3_19ReadWriteDefendModeENS3_9hash_funcImEENS3_8equal_toImEENS3_13SimpleAllocerINS3_15ObHashTableNodeINS3_11HashMapPairImNS3_11HashNullObjEEEEELi109ENS3_19SpinMutexDefendModeENS3_29DefaultSimpleAllocerAllocatorEEENS3_13NormalPointerENS2_8ObMallocELl1EEENS_5share3SCNE +_ZN9oceanbase3sql20ObSecurityAuditUtils21handle_security_auditERNS0_11ObResultSetEPNS_5share6schema19ObSchemaGetterGuardEPKNS0_6ObStmtERKNS_6common8ObStringEi +_ZN9oceanbase3sql12ObQueryRange17get_tablet_rangesERNS_6common9ObSEArrayIPNS2_10ObNewRangeELl1ENS2_19ModulePageAllocatorELb0EEERbRKNS2_20ObDataTypeCastParamsE +_ZZN9oceanbase3sql12ObQueryRange17get_tablet_rangesERNS_6common9ObSEArrayIPNS2_10ObNewRangeELl1ENS2_19ModulePageAllocatorELb0EEERbRKNS2_20ObDataTypeCastParamsEENK6$_1386clEPKc +_ZN9oceanbase3sql12ObQueryRange13ObSearchStateD2Ev +_ULx86_64_step +_ZN9oceanbase10rootserver18ObHeartbeatService21process_hb_responses_Ev +_ZN9oceanbase5share20ObAllTenantInfoProxy38update_tenant_recovery_status_in_transEmRNS_6common18ObMySQLTransactionERKNS0_15ObAllTenantInfoERKNS0_3SCNESA_SA_ +_ZN9oceanbase5share16ObAsyncTaskQueue4run2Ev +_ZN9oceanbase5share17ObFreezeInfoProxy46get_min_major_available_and_larger_info_inner_ERNS_6common12ObISQLClientERKNS0_3SCNERS5_RNS2_8ObIArrayINS0_20ObSimpleFrozenStatusEEE +_ZN9oceanbase12blocksstable11ObRowWriter20append_row_and_indexINS_6common5ObObjENS0_20ObColClusterInfoMaskEEEiPKT_lllbRT0_ +_ZN9oceanbase6common15ObLinearHashMapINS0_9ObIntWarpENS0_13ObSharedGuardINS0_14ObStringHolderEEENS0_14ShareMemMgrTagEE16do_foreach_scan_IZNS_7storage3mds20ObTenantMdsAllocator22dump_map_holding_item_EvE5$_133NS7_14DoForeachOnBktISC_EEEEbmmRT_RT0_.llvm.1524722193923947676 +_ZN9oceanbase6common15ObLinearHashMapINS_5share14ObCascadMemberENS2_15ObDstServerInfoENS0_14ShareMemMgrTagEE16do_foreach_scan_INS2_17ObServerBlacklist18ObMapRemoveFunctorENS6_15DoRemoveIfOnBktIS9_EEEEbmmRT_RT0_ +_ZN9oceanbase6common19ObPageManagerCenter11register_pmERNS0_13ObPageManagerE +_ZN9oceanbase7archive16ObArchiveFetcher4run1Ev +_ZN9oceanbase6common6ObCond9timedwaitEl +ob_pthread_cond_timedwait +_ZZN9oceanbase8observer31init_srv_xlator_for_transactionEPNS0_14ObSrvRpcXlatorEEN6$_15898__invokeERKNS0_15ObGlobalContextERPNS_3rpc5frame14ObReqProcessorERNS_5obrpc19ObRpcSessionHandlerE +_ZZN9oceanbase8observer31init_srv_xlator_for_transactionEPNS0_14ObSrvRpcXlatorEEN6$_15888__invokeERKNS0_15ObGlobalContextERPNS_3rpc5frame14ObReqProcessorERNS_5obrpc19ObRpcSessionHandlerE +_ZN9oceanbase6common7ObTimer13schedule_taskERNS0_11ObTimerTaskElbb +_ZN9oceanbase6common19ObTableAccessHelper34get_signle_column_from_signle_row_EPNS0_9sqlclient13ObMySQLResultEPKcRNS0_14ObStringHolderE +_ZNK9oceanbase4palf8election31ElectionAcceptResponseMsgMiddle9serializeEPclRl +_ZNK9oceanbase4palf8election15ElectionMsgBase9serializeEPclRl +_ZNK9oceanbase4palf8election15ElectionMsgBase10serialize_EPclRl +_ZNK9oceanbase4palf8election18ElectionMsgDebugTs9serializeEPclRl +_ZNK9oceanbase4palf8election18ElectionMsgDebugTs10serialize_EPclRl _ZN9oceanbase5share20ObTenantDagScheduler4run1Ev _ZN9oceanbase5share20ObTenantDagScheduler12schedule_oneEl -_ZN9oceanbase10rootserver18ObPrimaryLSService7do_workEv -_ZN9oceanbase10rootserver14ObTenantLSInfo17get_zone_priorityERKNS_6common19ObFixedLengthStringILl128EEERKNS_5share6schema14ObTenantSchemaERNS2_11ObSqlStringE -_ZN9oceanbase6common18ObMySQLTransactionC1Eb -_ZN9oceanbase6common18ObMySQLTransactionC2Eb -_ZNK9oceanbase5share18ObLSLeaderLocation9serializeEPclRl -_ZN9oceanbase8observer9ObMPQuery24process_with_tmp_contextERNS_3sql16ObSQLSessionInfoEbbRbS5_ -_ZN9oceanbase5share15ObLeaseResponse11deserializeEPKclRl -_ZN9oceanbase11transaction14ObTransService30rollback_to_implicit_savepointERNS0_8ObTxDescEllPKNS_6common9ObSEArrayINS_5share6ObLSIDELl3ENS4_19ModulePageAllocatorELb0EEE -_ZN9oceanbase10rootserver10ObDRWorker24try_ls_disaster_recoveryEbRNS0_8DRLSInfoERl -_ZN9oceanbase10rootserver8DRLSInfo16get_replica_statElRPNS_5share11ObLSReplicaERPNS0_16DRServerStatInfoERPNS0_14DRUnitStatInfoESB_ -_ZN9oceanbase7archive16ObArchiveFetcher4run1Ev -_ZN9oceanbase8observer15ObUniqTaskQueueINS0_19ObLSTableUpdateTaskENS0_16ObLSTableUpdaterEE4run1Ev -_ZN9oceanbase10rootserver18ObHeartbeatService21process_hb_responses_Ev +_ZN9oceanbase5share20ObTenantDagScheduler15dump_dag_statusEv +_ZN9oceanbase6common15ObLinearHashMapINS_12blocksstable12MacroBlockIdEbNS0_14ShareMemMgrTagEE16do_foreach_scan_INS2_14ObBlockManager23CopyBlockToArrayFunctorENS5_14DoForeachOnBktIS8_EEEEbmmRT_RT0_ +_ZN9oceanbase7storage18ObTenantMetaMemMgr20get_min_mds_ckpt_scnERKNS0_14ObTabletMapKeyERNS_5share3SCNE +_ZN9oceanbase6common26ObOccamTimerTaskRAIIHandle16reschedule_afterEl +_ZN9oceanbase6common26ObOccamTimerTaskRAIIHandle27remove_task_from_timewheel_Ev +_ZN9oceanbase7storage16ObMetaPointerMapINS0_14ObTabletMapKeyENS0_8ObTabletEE33get_meta_obj_with_external_memoryERKS2_RNS_6common16ObArenaAllocatorERNS0_14ObMetaObjGuardIS3_EEb +_ZN9oceanbase7storage18ObLSRestoreHandler24check_before_do_restore_ERb +_ZN9oceanbase5share6schema19ObSchemaGetterGuard15get_tenant_infoEmRPKNS1_20ObSimpleTenantSchemaE +_ZN9oceanbase3sql11ObDASLockOp7open_opEv +_ZN9oceanbase7storage15ObAccessService9lock_rowsERKNS_5share6ObLSIDERKNS_6common10ObTabletIDERNS_11transaction8ObTxDescERKNS0_14ObDMLBaseParamElNS0_10ObLockFlagEPNS6_16ObNewRowIteratorERl +_ZN9oceanbase7storage17ObLSTabletService9lock_rowsERNS0_14ObTabletHandleERNS0_10ObStoreCtxERKNS0_14ObDMLBaseParamElNS0_10ObLockFlagEbPNS_6common16ObNewRowIteratorERl +_ZNK9oceanbase5share6schema18ObTableSchemaParam21get_rowkey_column_idsERNS_6common8ObIArrayImEE +_ZN9oceanbase7storage8ObTablet8lock_rowERNS0_15ObRelativeTableERNS0_10ObStoreCtxERKNS_6common8ObNewRowE +_ZN9oceanbase7storage17ObTabletPersister9transformERKNS0_20ObTabletTransformArgEPcl +_ZN9oceanbase7storage18ObTabletTableStore24batch_cache_sstable_metaERNS_6common16ObArenaAllocatorEl +_ZNK9oceanbase12blocksstable15ObRootBlockInfo9deep_copyEPclRlRS1_ +_ZN9oceanbase5share20ObAllTenantInfoProxy16load_tenant_infoEmPNS_6common12ObISQLClientEbRlRNS0_15ObAllTenantInfoE +_ZN9oceanbase5share20ObAllTenantInfoProxy22load_pure_tenant_info_EmPNS_6common12ObISQLClientEbRlRNS0_15ObAllTenantInfoE +_ZN9oceanbase5share11ObShareUtil23set_default_timeout_ctxERNS_6common12ObTimeoutCtxEl +_ZN9oceanbase3sql20ObAggregateProcessor7processERNS1_8GroupRowEb +_ZN9oceanbase3sql20ObAggregateProcessor8min_calcERNS1_8AggrCellERNS_6common7ObDatumERKS5_PFiS8_S8_RiEb +_ZN9oceanbase5obrpc10ObRpcProxy8rpc_postINS0_15ObTransRpcProxy5ObRpcILNS0_15ObRpcPacketCodeE1628EvEEEEiRKNT_7RequestEPNS1_7AsyncCBIS7_EERKNS0_9ObRpcOptsE +_ZN9oceanbase12blocksstable18ObMacroBlockWriter5resetEv +_ZN9oceanbase7storage25ObSharedBlockReaderWriter11write_blockERKNS0_22ObSharedBlockWriteInfoERKNS1_22ObSharedBlockWriteArgsERNS0_23ObSharedBlockBaseHandleERNS0_22ObSharedBlocksWriteCtxE +_ZNK9oceanbase10logservice11coordinator10PriorityV110serialize_EPclRl +_ZNK9oceanbase6common13ObSEArrayImplINS_10logservice11coordinator12FailureEventELl3ENS0_19ModulePageAllocatorELb0EE9serializeEPclRl +_ZN9oceanbase5share17ObLSTableOperator3getElmRKNS0_6ObLSIDENS0_9ObLSTable4ModeERNS0_8ObLSInfoE +_ZN9oceanbase3sql17ObDASIDRequestRpc15fetch_new_rangeERKNS0_14ObDASIDRequestERNS_5obrpc16ObDASIDRpcResultElb +_ZN9oceanbase11transaction11ObGtsSource10query_gts_ERKNS_6common6ObAddrE +_ZN9oceanbase11transaction15ObGtsRequestRpc4postEmRKNS_6common6ObAddrERKNS0_12ObGtsRequestE +_ZN9oceanbase11transaction23ObTsResponseTaskFactory5allocEv +_ZN9oceanbase12blocksstable18ObMacroBlockWriter17flush_macro_blockERNS0_12ObMacroBlockE +_ZNK9oceanbase12blocksstable20ObDataMacroBlockMeta9build_rowERNS0_10ObDatumRowERNS_6common12ObIAllocatorE +_ZNK9oceanbase12blocksstable18ObDataBlockMetaVal8is_validEv +_ZNK9oceanbase12blocksstable18ObDataBlockMetaVal18get_serialize_sizeEv +_ZNK9oceanbase12blocksstable19ObLogicMacroBlockId19get_serialize_size_Ev +_ZNK9oceanbase12blocksstable18ObDataBlockMetaVal9serializeEPclRl +_ZNK9oceanbase7storage18ObColumnIndexArray9serializeEPclRl +_ZN9oceanbase8observer19ObTenantMetaChecker22check_report_replicas_ERNS_6common4hash9ObHashMapINS_5share6ObLSIDENS5_11ObLSReplicaENS3_24LatchReadWriteDefendModeENS3_9hash_funcIS6_EENS3_8equal_toIS6_EENS3_13SimpleAllocerINS3_15ObHashTableNodeINS3_11HashMapPairIS6_S7_EEEELi6ENS3_19SpinMutexDefendModeENS3_29DefaultSimpleAllocerAllocatorEEENS3_13NormalPointerENS2_8ObMallocELl1EEERl +_ZN9oceanbase7storage8ObITable11deserializeEPKclRl +_ZN9oceanbase10rootserver17ObLSServiceHelper27construct_ls_status_machineEbmPNS_6common12ObMySQLProxyERNS2_8ObIArrayINS0_26ObLSStatusMachineParameterEEE +_ZN9oceanbase6common22ObVirtualTableIterator4openEv +_ZN9oceanbase6common22ObVirtualTableIterator16init_convert_ctxEv +_ZNK9oceanbase5share19ObUnitTableOperator17read_unit_configsERNS_6common11ObSqlStringERNS2_8ObIArrayINS0_12ObUnitConfigEEE +_ZN9oceanbase6common9ObIOTuner4run1Ev +_ZN9oceanbase6common13ObSEArrayImplINS0_9ObSEArrayIdLl8ENS0_19ModulePageAllocatorELb0EEELl2ES3_Lb0EE6assignERKNS0_8ObIArrayIS4_EE +_ZN9oceanbase6common13ObSEArrayImplINS0_9ObSEArrayIdLl8ENS0_19ModulePageAllocatorELb0EEELl2ES3_Lb0EED2Ev +_ZN9oceanbase6common20ObGMemstoreAllocator14destroy_handleERNS1_11AllocHandleE +_ZN9oceanbase5share8detector21ObDeadLockDetectorMgr16InnerAllocHandle12InnerFactory6createERKNS1_13UserBinaryKeyERKNS_6common10ObFunctionIFiRKNS8_8ObIArrayINS1_25ObDetectorInnerReportInfoEEElEEERKNS9_IFiRNS1_24ObDetectorUserReportInfoEEEERKNS1_18ObDetectorPriorityEmbRPNS1_19ObIDeadLockDetectorE +_ZN9oceanbase7storage3mds17ObMdsTableHandler16try_gc_mds_tableEv +_ZN9oceanbase10compaction22ObMediumCompactionInfo4initERNS_6common12ObIAllocatorERKS1_ +_ZN9oceanbase3cdc12ObCdcService4run1Ev +_ZN9oceanbase7storage36ObSSTableMultiVersionRowMultiScannerC2Ev +_ZN9oceanbase14dbms_scheduler24ObDBMSSchedTableOperator12extract_infoERNS_6common9sqlclient13ObMySQLResultElbRNS2_12ObIAllocatorERNS0_18ObDBMSSchedJobInfoE +_ZN9oceanbase14dbms_scheduler18ObDBMSSchedJobInfo9deep_copyERNS_6common12ObIAllocatorERKS1_ +_ZN9oceanbase5obrpc13LogRpcProxyV212post_packet_ERKNS_4palf16LogRpcPacketImplINS2_8election24ElectionAcceptRequestMsgEEEPNS0_10ObRpcProxy7AsyncCBINS1_5ObRpcILNS0_15ObRpcPacketCodeE5386EvEEEERKNS0_9ObRpcOptsE +_ZN9oceanbase6common13serialization14encoded_lengthINS_4palf16LogRpcPacketImplINS3_8election24ElectionAcceptRequestMsgEEEEElRKT_ +_ZNK9oceanbase4palf16LogRpcPacketImplINS0_8election24ElectionAcceptRequestMsgEE9serializeEPclRl +_ZN9oceanbase6common4hash12ObReferedMapImNS_10rootserver14DRUnitStatInfoEE6locateERKmRPNS5_4ItemE +_ZNK9oceanbase5share15ObDMLSqlSplicer17build_rows_matrixERNS_6common8ObIArrayINS2_8ObStringEEERNS3_IlEE +_ZN9oceanbase5share20ObLSTemplateOperator9exec_readINS0_16ObLSAttrOperatorENS0_8ObLSAttrEEEiRKmRKNS_6common11ObSqlStringERNS7_12ObISQLClientEPT_RNS7_8ObIArrayIT0_EE +_ZNK9oceanbase7storage8ObLSMeta10serialize_EPclRl +_ZN9oceanbase10rootserver20ObLSRecoveryReportor4run2Ev +_ZN9oceanbase10rootserver23ObLSRecoveryStatHandler26get_ls_level_recovery_statERNS_5share16ObLSRecoveryStatE +_ZN9oceanbase10rootserver23ObLSRecoveryStatHandler21get_latest_palf_stat_ERNS_4palf8PalfStatE +_ZNK9oceanbase4palf12LogConfigMgr20get_curr_member_listERNS_6common16ObMemberListBaseILl7EEERl +_ZNK9oceanbase12blocksstable9ObSSTable13dec_macro_refEv +_ZN9oceanbase7storage8ObTablet4initERNS_6common16ObArenaAllocatorERKNS2_8ObIArrayIPNS0_8ObITableEEERKS1_ +_ZN9oceanbase8observer15ObUniqTaskQueueINS_5share20ObTabletLSUpdateTaskENS2_17ObTabletLSServiceEE4run1Ev +_ZN9oceanbase10rootserver24ObAllBalanceGroupBuilder9do_build_Ev +_ZN9oceanbase8observer15ObUniqTaskQueueINS0_18ObServerSchemaTaskENS0_21ObServerSchemaUpdaterEE4run1Ev +_ZN9oceanbase6common11ObArrayImplINS_8observer18ObServerSchemaTaskENS0_19ModulePageAllocatorELb0ENS0_22ObArrayDefaultCallBackIS3_EENS0_22NotImplementItemEncodeIS3_EEE10extend_bufEl +_ZN9oceanbase8observer21ObServerSchemaUpdater19batch_process_tasksERKNS_6common8ObIArrayINS0_18ObServerSchemaTaskEEERb +_ZN9oceanbase3sql12ObHashJoinOp17recursive_processERb +_ZN9oceanbase3sql19ObHashJoinPartition4initEiliibPNS0_16ObHashJoinBufMgrEPNS0_18ObHashJoinBatchMgrEPNS0_15ObHashJoinBatchEPNS0_10ObOperatorEPNS0_19ObSqlMemoryCallbackElPNS0_17ObIOEventObserverE +_ZN9oceanbase3sql12ObHashJoinOp30build_hash_table_for_recursiveEv +_ZN9oceanbase14dbms_scheduler24ObDBMSSchedTableOperator15calc_execute_atERNS0_18ObDBMSSchedJobInfoERlS4_b +_ZN9oceanbase7storage3mds9MdsDumpKV11deserializeERNS_6common12ObIAllocatorEPKclRl +_ZNK9oceanbase6common10ObFunctionIFiRKNS_5share19ObServerInfoInTableEEE7DerivedIZNS_10rootserver18ObTenantInfoLoader30broadcast_tenant_info_content_EvE6$_1169E6invokeES5_$527b86af4d89926f91abe7826c2190ff +_ZN9oceanbase8observer9ObService20get_leader_locationsERKNS_5obrpc23ObGetLeaderLocationsArgERNS2_26ObGetLeaderLocationsResultE +_ZN9oceanbase3sql9ObDMLStmt17iterate_stmt_exprERNS0_17ObStmtExprVisitorE +_ZN9oceanbase12blocksstable18ObDataBlockMetaVal11deserializeEPKclRl +_ZN9oceanbase12blocksstable18ObSSTableBasicMeta17decode_for_compatEPKclRl +_ZN9oceanbase6common10ObRowStore8Iterator12get_next_rowERNS0_8ObNewRowEPNS0_8ObStringEPPNS1_9StoredRowE +_ZN9oceanbase6common12ObCellReader5parseEPm +_ZN9oceanbase10logservice11coordinator13TableAccessor34get_all_ls_election_reference_infoERNS_6common8ObIArrayINS3_7ObTupleIJllbNS5_IJbNS3_14ObStringHolderEEEEbbbEEEEE +_ZN9oceanbase6common19ObTableAccessHelper27read_and_convert_to_values_IJNS0_14ObStringHolderEEEEimPPKclRKNS0_8ObStringES9_DpRT_ +_ZN9oceanbase6common19ObTableAccessHelper27read_and_convert_to_values_IJlEEEimPPKclRKNS0_8ObStringES8_DpRT_ +_ZN9oceanbase3lib2_SILNS0_13ContextSourceE0EEC2EbRNS0_13MemoryContextE +_ZN9oceanbase3sql13ObMergeJoinOpC1ERNS0_13ObExecContextERKNS0_8ObOpSpecEPNS0_9ObOpInputE +_ZN9oceanbase7storage31ObTabletCreateDeleteMdsUserData11deserializeEPKclRl +_ZN9oceanbase7storage18ObStorageHAService4run1Ev _ZN9oceanbase7storage20ObLSMigrationHandler7processEv -_ZN9oceanbase7storage13ObLSLockGuardD1Ev -_ZN9oceanbase7storage13ObLSLockGuardD2Ev -_ZZN9oceanbase8observer15ObVTIterCreator14create_vt_iterERNS_6common17ObVTableScanParamERPNS2_22ObVirtualTableIteratorEENK5$_446clEv +_ZNK9oceanbase7storage8ObLSMeta20get_migration_statusERNS0_17ObMigrationStatusE +_ZN9oceanbase7storage8ObLSMeta19ObSpinLockTimeGuardC2ERNS_6common10ObSpinLockEl +_ZN9oceanbase5share24ObZoneMergeTableOperator28inner_load_zone_merge_infos_ERNS_6common12ObISQLClientEmRNS2_8ObIArrayINS0_15ObZoneMergeInfoEEEb +_ZN9oceanbase5share19ObPartitionLocation11deserializeEPKclRl +_ZN9oceanbase7storage8ObTablet4initERNS_6common16ObArenaAllocatorERKNS0_23ObUpdateTableStoreParamERKS1_ +_ZNK9oceanbase5share15ObAllTenantInfo9serializeEPclRl +_ZN9oceanbase12blocksstable21ObSSTableIndexBuilder5closeERNS0_17ObSSTableMergeResE +_ZN9oceanbase10rootserver10ObDRWorker22try_locality_alignmentEbRNS0_8DRLSInfoERl +_ZN9oceanbase10rootserver10ObDRWorker17LocalityAlignmentD2Ev +_ZN9oceanbase7storage17ObTransferHandler7processEv +_ZNK9oceanbase7storage3mds9MdsDumpKV9serializeEPclRl +_ZN9oceanbase8observer15ObUniqTaskQueueINS0_19ObLSTableUpdateTaskENS0_16ObLSTableUpdaterEE4run1Ev _ZN9oceanbase8observer15ObVTIterCreator14create_vt_iterERNS_6common17ObVTableScanParamERPNS2_22ObVirtualTableIteratorE -_ZN9oceanbase8observer15ObVTIterCreator26get_latest_expected_schemaEmmlRNS_5share6schema19ObSchemaGetterGuardERPKNS3_13ObTableSchemaE +_ZZN9oceanbase8observer15ObVTIterCreator14create_vt_iterERNS_6common17ObVTableScanParamERPNS2_22ObVirtualTableIteratorEENK5$_604clEv +_ZN9oceanbase10rootserver11ObDRTaskMgr4run3Ev +_ZN9oceanbase10rootserver20ObFreezeInfoDetector4run3Ev +_ZN9oceanbase7storage15ObStorageSchema11deserializeERNS_6common12ObIAllocatorEPKclRl +_ZN9oceanbase5share6schema20ObDDLTransController4run1Ev +_ZNK9oceanbase12blocksstable18ObSSTableBasicMeta9serializeEPclRl +_ZN9oceanbase3sql17ObTableInsertUpOp12do_insert_upEv diff --git a/mittest/logservice/CMakeLists.txt b/mittest/logservice/CMakeLists.txt index 66f2eb430..80eecee47 100644 --- a/mittest/logservice/CMakeLists.txt +++ b/mittest/logservice/CMakeLists.txt @@ -35,7 +35,7 @@ ob_unittest_clog(test_ob_simple_log_throttling test_ob_simple_log_throttling.cp ob_unittest_clog(test_ob_simple_log_throttling_member_change test_ob_simple_log_throttling_member_change.cpp) ob_unittest_clog(test_ob_simple_log_throttling_arb test_ob_simple_log_throttling_arb.cpp) ob_unittest_clog(test_ob_simple_log_config_change_mock_ele test_ob_simple_log_config_change_mock_ele.cpp) -ob_unittest_clog(test_ob_simple_log_arb_mock_ele test_ob_simple_log_arb_mock_ele.cpp) +#ob_unittest_clog(test_ob_simple_log_arb_mock_ele test_ob_simple_log_arb_mock_ele.cpp) TODO(yunlong.cb): fix it add_subdirectory(archiveservice) diff --git a/mittest/logservice/env/ob_simple_log_cluster_env.cpp b/mittest/logservice/env/ob_simple_log_cluster_env.cpp index 0790ce4fd..2a59e5ef0 100755 --- a/mittest/logservice/env/ob_simple_log_cluster_env.cpp +++ b/mittest/logservice/env/ob_simple_log_cluster_env.cpp @@ -652,13 +652,15 @@ int ObSimpleLogClusterTestEnv::switch_leader(const int64_t id, const int64_t new common::ObAddr leader_addr = cluster[new_leader_idx]->get_addr(); PalfHandleImplGuard old_leader, new_leader; std::vector palf_list; + + CLOG_LOG(INFO, "begin to switch_leader"); if (OB_FAIL(get_leader(id, old_leader, old_leader_idx))) { PALF_LOG(WARN, "get_leader failed", K(ret), K(id)); } else { EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list)); EXPECT_EQ(OB_SUCCESS, get_palf_handle_guard(palf_list, leader_addr, new_leader)); - while (old_leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_version_ > - new_leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_version_) { + while (old_leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.config_version_ > + new_leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.config_version_) { ::usleep(500); } new_leader.reset(); @@ -666,7 +668,7 @@ int ObSimpleLogClusterTestEnv::switch_leader(const int64_t id, const int64_t new ObTenantEnv::set_tenant(cluster[old_leader_idx]->get_tenant_base()); old_leader.palf_handle_impl_->change_leader_to(leader_addr); CLOG_LOG(INFO, "switch_leader success", K(ret), "prev_leader:", cluster[prev_leader_idx_]->get_addr(), "new_leader:", cluster[new_leader_idx]->get_addr(), - "old_leader:", cluster[old_leader_idx]->get_addr()); + "old_leader:", cluster[old_leader_idx]->get_addr(), K(old_leader_idx), K(new_leader_idx)); prev_leader_idx_ = new_leader_idx; // 确保election已经切主成功. do { diff --git a/mittest/logservice/test_ob_simple_log_access_mode.cpp b/mittest/logservice/test_ob_simple_log_access_mode.cpp index e73582748..a8810b7bc 100644 --- a/mittest/logservice/test_ob_simple_log_access_mode.cpp +++ b/mittest/logservice/test_ob_simple_log_access_mode.cpp @@ -238,7 +238,9 @@ TEST_F(TestObSimpleLogClusterAccessMode, add_member) EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(ObMember(get_cluster()[3]->get_addr(), 1), CONFIG_CHANGE_TIMEOUT)); sleep(2); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_learner_to_acceptor(ObMember(get_cluster()[3]->get_addr(), 1), 4, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_learner_to_acceptor(ObMember(get_cluster()[3]->get_addr(), 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); unblock_net(leader_idx, follower2_idx); revert_cluster_palf_handle_guard(palf_list); } @@ -276,7 +278,7 @@ TEST_F(TestObSimpleLogClusterAccessMode, prev_log_slide) const int64_t leader_epoch = leader.palf_handle_impl_->state_mgr_.get_leader_epoch(); EXPECT_EQ(OB_ERR_UNEXPECTED, leader.palf_handle_impl_->config_mgr_.change_config(args, proposal_id, leader_epoch, config_version)); const LogConfigMeta new_config_meta = leader.palf_handle_impl_->config_mgr_.log_ms_meta_; - EXPECT_EQ(config_meta.curr_.config_version_, new_config_meta.curr_.config_version_); + EXPECT_EQ(config_meta.curr_.config_.config_version_, new_config_meta.curr_.config_.config_version_); // wait prepare req reaches majority sleep(1); // switch to accept state diff --git a/mittest/logservice/test_ob_simple_log_arb.cpp b/mittest/logservice/test_ob_simple_log_arb.cpp old mode 100644 new mode 100755 index 37e72a83a..5e5230b28 --- a/mittest/logservice/test_ob_simple_log_arb.cpp +++ b/mittest/logservice/test_ob_simple_log_arb.cpp @@ -185,8 +185,11 @@ TEST_F(TestObSimpleLogClusterArbService, test_4f1a_degrade_upgrade) common::ObMember dummy_member; std::vector palf_list; EXPECT_EQ(OB_SUCCESS, create_paxos_group_with_arb(id, arb_replica_idx, leader_idx, leader)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[3]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[4]->get_addr(), 1), 4, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[3]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[4]->get_addr(), 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list)); const int64_t another_f1_idx = (leader_idx+3)%5; @@ -279,8 +282,11 @@ TEST_F(TestObSimpleLogClusterArbService, test_4f1a_reconfirm_degrade_upgrade) std::vector palf_list; EXPECT_EQ(OB_SUCCESS, create_paxos_group_with_arb(id, arb_replica_idx, leader_idx, leader)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[3]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[4]->get_addr(), 1), 4, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[3]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[4]->get_addr(), 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list)); @@ -346,10 +352,13 @@ TEST_F(TestObSimpleLogClusterArbService, test_2f1a_config_change) EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); sleep(2); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); // replace member EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_member( ObMember(palf_list[3]->palf_handle_impl_->self_, 1), ObMember(palf_list[another_f_idx]->palf_handle_impl_->self_, 1), + config_version, CONFIG_CHANGE_TIMEOUT)); // add learner @@ -361,10 +370,12 @@ TEST_F(TestObSimpleLogClusterArbService, test_2f1a_config_change) EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->switch_learner_to_acceptor( ObMember(palf_list[4]->palf_handle_impl_->self_, 1), 2, + config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_learner_to_acceptor( ObMember(palf_list[4]->palf_handle_impl_->self_, 1), 3, + config_version, CONFIG_CHANGE_TIMEOUT)); revert_cluster_palf_handle_guard(palf_list); leader.reset(); @@ -479,7 +490,9 @@ TEST_F(TestObSimpleLogClusterArbService, test_2f1a_defensive) const common::ObMember added_member = ObMember(palf_list[added_member_idx]->palf_handle_impl_->self_, 1); // add a member, do not allow to append logs until config log reaches majority - LogConfigChangeArgs args(added_member, 3, ADD_MEMBER); + LogConfigVersion cur_config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(cur_config_version)); + LogConfigChangeArgs args(added_member, 3, cur_config_version, ADD_MEMBER); int64_t proposal_id = 0; int64_t election_epoch = 0; LogConfigVersion config_version; @@ -673,8 +686,8 @@ TEST_F(TestObSimpleLogClusterArbService, test_2f1a_degrade_when_no_leader) EXPECT_EQ(OB_EAGAIN, leader.palf_handle_impl_->config_mgr_.change_config(args, proposal_id, election_epoch, config_version)); // leader appended config meta - EXPECT_FALSE(palf_list[leader_idx]->get_palf_handle_impl()->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_TRUE(palf_list[another_f_idx]->get_palf_handle_impl()->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_FALSE(palf_list[leader_idx]->get_palf_handle_impl()->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(palf_list[another_f_idx]->get_palf_handle_impl()->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // block all networks of arb member, and the network from the follower to the leader block_net(arb_replica_idx, another_f_idx, true); diff --git a/mittest/logservice/test_ob_simple_log_arb_mock_ele.cpp b/mittest/logservice/test_ob_simple_log_arb_mock_ele.cpp old mode 100644 new mode 100755 index 829a6068f..6350690a6 --- a/mittest/logservice/test_ob_simple_log_arb_mock_ele.cpp +++ b/mittest/logservice/test_ob_simple_log_arb_mock_ele.cpp @@ -117,8 +117,8 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, switch_leader_during_degrading) sleep(2); EXPECT_EQ(leader_last_committed_end_lsn, leader.palf_handle_impl_->sw_.committed_end_lsn_); - EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_TRUE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // 2. the leader A revokes and takeover again for (auto srv: get_cluster()) { @@ -141,7 +141,7 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, switch_leader_during_degrading) EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx)); EXPECT_LE(leader_last_committed_end_lsn, leader.palf_handle_impl_->sw_.committed_end_lsn_); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->one_stage_config_change_(degrade_b_args, TIMEOUT_US)); - EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // 4. leader A tries to upgrade B EXPECT_EQ(OB_SUCCESS, submit_log(leader, 200, id)); @@ -180,7 +180,7 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, switch_leader_during_degrading) } EXPECT_UNTIL_EQ(true, a_handle->palf_handle_impl_->state_mgr_.is_leader_active()); - EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); EXPECT_EQ(leader_max_flushed_end_lsn, leader.palf_handle_impl_->sw_.committed_end_lsn_); dynamic_cast(get_cluster()[leader_idx])->log_service_.get_arbitration_service()->start(); @@ -231,8 +231,8 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, switch_leader_to_other_during_de sleep(2); EXPECT_EQ(leader_last_committed_end_lsn, leader.palf_handle_impl_->sw_.committed_end_lsn_); - EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_TRUE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // 2. the leader A revokes and B takeover for (auto srv: get_cluster()) { @@ -253,8 +253,8 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, switch_leader_to_other_during_de // 3. leader B degrades A leader.reset(); EXPECT_EQ(OB_SUCCESS, get_leader(id, leader, leader_idx)); - EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); LogConfigChangeArgs degrade_a_args(ObMember(a_addr, 1), 0, DEGRADE_ACCEPTOR_TO_LEARNER); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->one_stage_config_change_(degrade_a_args, TIMEOUT_US)); @@ -280,7 +280,7 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, switch_leader_to_other_during_de leader.palf_handle_impl_->config_mgr_.change_config_(upgrade_a_args, upgrade_a_pid, upgrade_a_ele_epoch, upgrade_a_version); } EXPECT_EQ(OB_EAGAIN, leader.palf_handle_impl_->config_mgr_.change_config_(upgrade_a_args, upgrade_a_pid, upgrade_a_ele_epoch, upgrade_a_version)); - EXPECT_UNTIL_EQ(a_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_version_, b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_version_); + EXPECT_UNTIL_EQ(a_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.config_version_, b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.config_version_); // 5. the leader B revokes and A takeover for (auto srv: get_cluster()) { @@ -296,7 +296,7 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, switch_leader_to_other_during_de } EXPECT_UNTIL_EQ(true, a_handle->palf_handle_impl_->state_mgr_.is_leader_active()); - EXPECT_TRUE(a_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(a_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); dynamic_cast(get_cluster()[leader_idx])->log_service_.get_arbitration_service()->start(); dynamic_cast(get_cluster()[b_idx])->log_service_.get_arbitration_service()->start(); @@ -356,12 +356,12 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, test_2f1a_degrade_when_no_leader // A sends config meta to C while (-1 == leader.palf_handle_impl_->config_mgr_.last_submit_config_log_time_us_ || - c_handle->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)) { + c_handle->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)) { EXPECT_EQ(OB_EAGAIN, leader.palf_handle_impl_->config_mgr_.change_config_(degrade_b_args, degrade_b_pid, degrade_b_ele_epoch, degrade_b_version)); usleep(500); } - EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // 2. the leader A revokes and takeover again for (auto srv: get_cluster()) { @@ -379,7 +379,7 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, test_2f1a_degrade_when_no_leader } dynamic_cast(get_cluster()[leader_idx])->log_service_.get_arbitration_service()->start(); EXPECT_UNTIL_EQ(true, a_handle->palf_handle_impl_->state_mgr_.is_leader_active()); - EXPECT_UNTIL_EQ(true, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.degraded_learnerlist_.contains(b_addr)); + EXPECT_UNTIL_EQ(true, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.degraded_learnerlist_.contains(b_addr)); unblock_net(leader_idx, b_idx); dynamic_cast(get_cluster()[b_idx])->log_service_.get_arbitration_service()->start(); @@ -478,7 +478,7 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, test_2f1a_degrade_when_arb_crash block_net(leader_idx, b_idx); sleep(4); // the leader can not degrade successfully - EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // start to degrade B manually, do not allow LogConfigChangeArgs args(ObMember(b_addr, 1), 0, DEGRADE_ACCEPTOR_TO_LEARNER); @@ -541,12 +541,12 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, test_arb_degrade_probe) EXPECT_TRUE(dynamic_cast(get_cluster()[d_idx])->deliver_.need_filter_packet_by_pcode_blacklist(ObRpcPacketCode::OB_LOG_ARB_PROBE_MSG)); EXPECT_TRUE(dynamic_cast(get_cluster()[e_idx])->deliver_.need_filter_packet_by_pcode_blacklist(ObRpcPacketCode::OB_LOG_ARB_PROBE_MSG)); sleep(6); - EXPECT_EQ(0, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.degraded_learnerlist_.get_member_number()); + EXPECT_EQ(0, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.degraded_learnerlist_.get_member_number()); // CASE 2. D block_net, E UNKNOWN, do not degrade block_net(leader_idx, d_idx); sleep(2); - EXPECT_EQ(0, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.degraded_learnerlist_.get_member_number()); + EXPECT_EQ(0, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.degraded_learnerlist_.get_member_number()); // CASE 3. D block_net, E block_net, degrade block_net(leader_idx, e_idx); @@ -557,15 +557,15 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, test_arb_degrade_probe) unblock_net(leader_idx, d_idx); unblock_net(leader_idx, e_idx); sleep(2); - EXPECT_EQ(2, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.degraded_learnerlist_.get_member_number()); + EXPECT_EQ(2, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.degraded_learnerlist_.get_member_number()); // CASE 5. D unblock_net and unblock_pcode, upgrade E unblock_pcode(d_idx, ObRpcPacketCode::OB_LOG_ARB_PROBE_MSG); - EXPECT_UNTIL_EQ(false, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.degraded_learnerlist_.contains(d_addr)); + EXPECT_UNTIL_EQ(false, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.degraded_learnerlist_.contains(d_addr)); // CASE 6. E unblock_net and unblock_pcode, upgrade E unblock_pcode(e_idx, ObRpcPacketCode::OB_LOG_ARB_PROBE_MSG); - EXPECT_UNTIL_EQ(false, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.degraded_learnerlist_.contains(d_addr)); + EXPECT_UNTIL_EQ(false, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.degraded_learnerlist_.contains(d_addr)); revert_cluster_palf_handle_guard(palf_list); } @@ -665,4 +665,4 @@ TEST_F(TestObSimpleLogClusterArbMockEleService, test_add_remove_lose_logs) int main(int argc, char **argv) { RUN_SIMPLE_LOG_CLUSTER_TEST(TEST_NAME); -} \ No newline at end of file +} diff --git a/mittest/logservice/test_ob_simple_log_config_change.cpp b/mittest/logservice/test_ob_simple_log_config_change.cpp index b29138eb0..5b99a48ca 100644 --- a/mittest/logservice/test_ob_simple_log_config_change.cpp +++ b/mittest/logservice/test_ob_simple_log_config_change.cpp @@ -15,6 +15,7 @@ #include #include #define private public +#include "logservice/palf/log_config_mgr.h" #include "env/ob_simple_log_cluster_env.h" #undef private @@ -158,7 +159,9 @@ TEST_F(TestObSimpleLogClusterConfigChange, split_brain) loc_cb.leader_ = get_cluster()[new_leader_idx]->get_addr(); PALF_LOG(INFO, "set leader for loc_cb", "leader", loc_cb.leader_); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); // step 4 EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(get_cluster()[follower_C_idx]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT)); @@ -219,13 +222,16 @@ TEST_F(TestObSimpleLogClusterConfigChange, test_config_change_defensive) unblock_net(leader_idx, lag_follower_idx); EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[remove_follower_idx]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT)); - PalfHandleImplGuard new_leader; + int64_t new_leader_idx; + PalfHandleImplGuard new_leader; EXPECT_EQ(OB_SUCCESS, get_leader(id, new_leader, new_leader_idx)); loc_cb.leader_ = get_cluster()[new_leader_idx]->get_addr(); PALF_LOG(INFO, "set leader for loc_cb", "leader", get_cluster()[new_leader_idx]->get_addr()); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[remove_follower_idx]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[remove_follower_idx]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, submit_log(leader, 10, id)); // majority of members should be normal palf_list[lag_follower_idx]->palf_handle_impl_->disable_vote(false); @@ -241,9 +247,19 @@ TEST_F(TestObSimpleLogClusterConfigChange, test_config_change_defensive) // we will send config log to 3 before add_member(3, 4), so 3 can know who is leader and fetch log from it. // so just comment this line, after leader forbit fetch log req that comes from node who is not follower or // children of leader, we will uncomment this line - // EXPECT_EQ(OB_TIMEOUT, leader.add_member(ObMember(palf_list[3]->palf_handle_.palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT / 2)); + // EXPECT_EQ(OB_TIMEOUT, leader.add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT / 2)); unblock_net(leader_idx, lag_follower_idx); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); + //test add_member_with_check + EXPECT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->remove_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion invalid_config_version; + int64_t follower_idx = (new_leader_idx +1) % 3; + EXPECT_EQ(OB_STATE_NOT_MATCH, new_leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, invalid_config_version, CONFIG_CHANGE_TIMEOUT)); + EXPECT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_NOT_MASTER, palf_list[follower_idx]->palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); + EXPECT_EQ(true, config_version.is_valid()); + EXPECT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); revert_cluster_palf_handle_guard(palf_list); } @@ -271,8 +287,11 @@ TEST_F(TestObSimpleLogClusterConfigChange, test_change_replica_num) EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); // 3->5 EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->change_replica_num(get_member_list(), 3, 5, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[4]->get_addr(), 1), 5, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[5]->get_addr(), 1), 5, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[4]->get_addr(), 1), 5, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[5]->get_addr(), 1), 5, config_version, CONFIG_CHANGE_TIMEOUT)); common::ObMemberList curr_member_list; int64_t curr_replica_num; EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(get_cluster()[4]->get_addr(), 1), 5, CONFIG_CHANGE_TIMEOUT)); @@ -308,18 +327,24 @@ TEST_F(TestObSimpleLogClusterConfigChange, test_basic_config_change) PALF_LOG(INFO, "set leader for loc_cb", "leader", get_cluster()[new_leader_idx]->get_addr()); EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list)); // add member when no log - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[(leader_idx+2)%3]->palf_handle_impl_->self_, 1), 1, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+2)%3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 2, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+2)%3]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); // add member when contains log - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[4]->palf_handle_impl_->self_, 1), 5, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[4]->palf_handle_impl_->self_, 1), 5, config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); // remove member @@ -327,11 +352,19 @@ TEST_F(TestObSimpleLogClusterConfigChange, test_basic_config_change) EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); + + EXPECT_EQ(OB_STATE_NOT_MATCH, leader.palf_handle_impl_->replace_member(ObMember(palf_list[5]->palf_handle_impl_->self_, 1), + ObMember(palf_list[3]->palf_handle_impl_->self_, 1), + config_version, + CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); // replace member EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_member(ObMember(palf_list[5]->palf_handle_impl_->self_, 1), - ObMember(palf_list[3]->palf_handle_impl_->self_, 1), - CONFIG_CHANGE_TIMEOUT)); + ObMember(palf_list[3]->palf_handle_impl_->self_, 1), + config_version, + CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); // switch acceptor to learner EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_acceptor_to_learner(ObMember(palf_list[5]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); // add learner @@ -366,18 +399,24 @@ TEST_F(TestObSimpleLogClusterConfigChange, test_replace_member) EXPECT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list)); EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); // replace member when no log - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[(leader_idx+2)%3]->palf_handle_impl_->self_, 1), 1, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+2)%3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+1)%3]->palf_handle_impl_->self_, 1), 2, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[(leader_idx+2)%3]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); // add member when contains log - EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[4]->palf_handle_impl_->self_, 1), 5, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[4]->palf_handle_impl_->self_, 1), 5, config_version, CONFIG_CHANGE_TIMEOUT)); EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); // remove member @@ -386,8 +425,10 @@ TEST_F(TestObSimpleLogClusterConfigChange, test_replace_member) EXPECT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); // replace member + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_member(ObMember(palf_list[5]->palf_handle_impl_->self_, 1), ObMember(palf_list[3]->palf_handle_impl_->self_, 1), + config_version, CONFIG_CHANGE_TIMEOUT)); // switch acceptor to learner @@ -551,6 +592,193 @@ TEST_F(TestObSimpleLogClusterConfigChange, learner) PALF_LOG(INFO, "end test learner", K(id)); } +TEST_F(TestObSimpleLogClusterConfigChange, test_config_change_lock) +{ + SET_CASE_LOG_FILE(TEST_NAME, "config_change_lock"); + int ret = OB_SUCCESS; + const int64_t id = ATOMIC_AAF(&palf_id_, 1); + PALF_LOG(INFO, "begin test config change", K(id)); + int64_t leader_idx = 0; + int64_t log_ts = 1; + PalfHandleImplGuard leader; + std::vector palf_list; + const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s + ASSERT_EQ(OB_SUCCESS, create_paxos_group(id, &loc_cb, leader_idx, leader)); + ASSERT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list)); + + ASSERT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); + loc_cb.leader_ = get_cluster()[leader_idx]->get_addr(); + PALF_LOG(INFO, "set leader for loc_cb", "leader", loc_cb.leader_); + int64_t lock_owner_out = -1; + bool lock_stat = false; + //ASSERT_EQ(OB_NOT_SUPPORTED, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + //ASSERT_EQ(OB_NOT_SUPPORTED, leader.palf_handle_impl_->try_lock_config_change(1, CONFIG_CHANGE_TIMEOUT)); + //ASSERT_EQ(OB_NOT_SUPPORTED, leader.palf_handle_impl_->unlock_config_change(1, CONFIG_CHANGE_TIMEOUT)); + //oceanbase::common::ObClusterVersion::get_instance().cluster_version_ = CLUSTER_VERSION_4_2_0_0; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + ASSERT_EQ(OB_INVALID_CONFIG_CHANGE_LOCK_OWNER, lock_owner_out); + ASSERT_EQ(false, lock_stat); + + //invalid arguments + ASSERT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->try_lock_config_change(-1, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->try_lock_config_change(1, 0)); + ASSERT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->unlock_config_change(-1, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_INVALID_ARGUMENT, leader.palf_handle_impl_->unlock_config_change(1, 0)); + + //test try lock + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->try_lock_config_change(1, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->try_lock_config_change(1, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_TRY_LOCK_CONFIG_CHANGE_CONFLICT, leader.palf_handle_impl_->try_lock_config_change(2, CONFIG_CHANGE_TIMEOUT)); + + ASSERT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); + + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + ASSERT_EQ(1, lock_owner_out); + ASSERT_EQ(true, lock_stat); + + //test unlock + ASSERT_EQ(OB_STATE_NOT_MATCH, leader.palf_handle_impl_->unlock_config_change(2, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->unlock_config_change(1, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->unlock_config_change(1, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); + + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + ASSERT_EQ(1, lock_owner_out); + ASSERT_EQ(false, lock_stat); + + //changing stat, test locking stat + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->try_lock_config_change(3, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + ASSERT_EQ(3, lock_owner_out); + ASSERT_EQ(true, lock_stat); + + //block add_member + + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + + //ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_learner(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->remove_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->remove_member(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->add_member(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->switch_acceptor_to_learner(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->switch_learner_to_acceptor(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_EAGAIN, leader.palf_handle_impl_->change_replica_num(get_member_list(), 3, 4, CONFIG_CHANGE_TIMEOUT)); + + + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->unlock_config_change(3, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + ASSERT_EQ(3, lock_owner_out); + ASSERT_EQ(false, lock_stat); + + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[3]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_acceptor_to_learner(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 2, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_STATE_NOT_MATCH, leader.palf_handle_impl_->switch_learner_to_acceptor(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->switch_learner_to_acceptor(ObMember(palf_list[2]->palf_handle_impl_->self_, 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->change_replica_num(get_member_list(), 3, 4, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->change_replica_num(get_member_list(), 4, 3, CONFIG_CHANGE_TIMEOUT)); + + //switch leader + + ASSERT_EQ(OB_SUCCESS, submit_log(leader, 100, id)); + revert_cluster_palf_handle_guard(palf_list); + PALF_LOG(INFO, "end test config change lock", K(id)); +} + +TEST_F(TestObSimpleLogClusterConfigChange, test_switch_leader) +{ + SET_CASE_LOG_FILE(TEST_NAME, "switch_leader"); + int ret = OB_SUCCESS; + const int64_t id = ATOMIC_AAF(&palf_id_, 1); + PALF_LOG(INFO, "begin test switch_leader", K(id)); + int64_t leader_idx = 0; + PalfHandleImplGuard leader; + std::vector palf_list; + oceanbase::common::ObClusterVersion::get_instance().cluster_version_ = CLUSTER_VERSION_4_2_0_0; + EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, leader_idx, leader)); + ASSERT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list)); + EXPECT_EQ(OB_SUCCESS, submit_log(leader, 200, id)); + // try lock config change + // + const int64_t follower_idx = (leader_idx+1)%3; + const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s + + int64_t lock_owner_out = -1; + bool lock_stat = false; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->try_lock_config_change(1, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + ASSERT_EQ(1, lock_owner_out); + ASSERT_EQ(true, lock_stat); + + PalfHandleImplGuard new_leader; + const int64_t new_leader_idx = (leader_idx+1)%3; + PalfHandleImplGuard &follower = *palf_list[new_leader_idx]; + ASSERT_EQ(OB_NOT_MASTER, follower.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + EXPECT_EQ(OB_SUCCESS, switch_leader(id, new_leader_idx, new_leader)); + sleep(5); + ObRole role; + int64_t curr_proposal_id = 0; + bool is_pending_stat = false; + EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_role(role, curr_proposal_id, is_pending_stat)); + EXPECT_EQ(ObRole::FOLLOWER, role); + + lock_owner_out = -1; + lock_stat = false; + + ASSERT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + ASSERT_EQ(1, lock_owner_out); + ASSERT_EQ(true, lock_stat); + EXPECT_EQ(OB_SUCCESS, submit_log(new_leader, 200, id)); + + + ASSERT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->unlock_config_change(1, CONFIG_CHANGE_TIMEOUT)); + sleep(3); + //switch leader during lock_config_change + + LogConfigChangeArgs args(2, ConfigChangeLockType::LOCK_PAXOS_MEMBER_CHANGE, TRY_LOCK_CONFIG_CHANGE); + LogConfigVersion config_version; + const int64_t proposal_id = new_leader.palf_handle_impl_->state_mgr_.get_proposal_id(); + const int64_t leader_epoch = new_leader.palf_handle_impl_->state_mgr_.get_leader_epoch(); + ASSERT_EQ(OB_EAGAIN, new_leader.palf_handle_impl_->config_mgr_.change_config(args, proposal_id, leader_epoch, config_version)); + ASSERT_EQ(LogConfigMgr::ConfigChangeState::CHANGING, new_leader.palf_handle_impl_->config_mgr_.state_); + ASSERT_EQ(OB_EAGAIN, new_leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + //block_net + const int64_t follower_idx1 = (new_leader_idx+1)%3; + const int64_t follower_idx2 = (new_leader_idx+2)%3; + block_net(follower_idx1, new_leader_idx, true); + block_net(follower_idx2, new_leader_idx, true); + //send info to follower + ASSERT_EQ(OB_EAGAIN, new_leader.palf_handle_impl_->config_mgr_.change_config(args, proposal_id, leader_epoch, config_version)); + sleep(1); + + unblock_net(follower_idx1, new_leader_idx); + unblock_net(follower_idx2, new_leader_idx); + PalfHandleImplGuard old_leader; + EXPECT_EQ(OB_SUCCESS, switch_leader(id, leader_idx, old_leader)); + + EXPECT_EQ(OB_SUCCESS, old_leader.palf_handle_impl_->get_role(role, curr_proposal_id, is_pending_stat)); + EXPECT_EQ(ObRole::LEADER, role); + + //check config change stat + sleep(1); + ASSERT_EQ(OB_SUCCESS, old_leader.palf_handle_impl_->get_config_change_lock_stat(lock_owner_out, lock_stat)); + ASSERT_EQ(2, lock_owner_out); + ASSERT_EQ(true, lock_stat); + + + revert_cluster_palf_handle_guard(palf_list); + PALF_LOG(INFO, "end test switch_leader", K(id)); +} + } // end unittest } // end oceanbase diff --git a/mittest/logservice/test_ob_simple_log_config_change_mock_ele.cpp b/mittest/logservice/test_ob_simple_log_config_change_mock_ele.cpp index 057996bb1..f2c7072cf 100644 --- a/mittest/logservice/test_ob_simple_log_config_change_mock_ele.cpp +++ b/mittest/logservice/test_ob_simple_log_config_change_mock_ele.cpp @@ -72,9 +72,9 @@ TEST_F(TestObSimpleLogClusterConfigChangeMockEle, switch_leader_during_removing_ EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->config_mgr_.start_change_config(remove_b_pid, remove_b_ele_epoch, args.type_)); EXPECT_EQ(OB_EAGAIN, leader.palf_handle_impl_->config_mgr_.change_config_(args, remove_b_pid, remove_b_ele_epoch, remove_b_version)); - EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_TRUE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_TRUE(c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // 2. B is elected to be the leader block_net(leader_idx, b_idx); @@ -88,7 +88,7 @@ TEST_F(TestObSimpleLogClusterConfigChangeMockEle, switch_leader_during_removing_ unblock_net(leader_idx, b_idx); // 4. A's memberlist will be reset - EXPECT_UNTIL_EQ(true, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_UNTIL_EQ(true, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); leader.reset(); // 5. B remove C @@ -101,9 +101,9 @@ TEST_F(TestObSimpleLogClusterConfigChangeMockEle, switch_leader_during_removing_ EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->config_mgr_.start_change_config(remove_c_pid, remove_c_ele_epoch, remove_c_args.type_)); EXPECT_EQ(OB_EAGAIN, leader.palf_handle_impl_->config_mgr_.change_config_(remove_c_args, remove_c_pid, remove_c_ele_epoch, remove_c_version)); - EXPECT_TRUE(a_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(c_addr)); - EXPECT_FALSE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(c_addr)); - EXPECT_TRUE(c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(c_addr)); + EXPECT_TRUE(a_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(c_addr)); + EXPECT_FALSE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(c_addr)); + EXPECT_TRUE(c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(c_addr)); // 6. the leader B revokes and takeover again for (auto srv: get_cluster()) { @@ -117,8 +117,8 @@ TEST_F(TestObSimpleLogClusterConfigChangeMockEle, switch_leader_during_removing_ EXPECT_UNTIL_EQ(true, b_handle->palf_handle_impl_->state_mgr_.is_leader_active()); // 7. C will be removed successfully - EXPECT_FALSE(a_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(c_addr)); - EXPECT_FALSE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(c_addr)); + EXPECT_FALSE(a_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(c_addr)); + EXPECT_FALSE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(c_addr)); revert_cluster_palf_handle_guard(palf_list); } @@ -155,21 +155,21 @@ TEST_F(TestObSimpleLogClusterConfigChangeMockEle, switch_leader_during_removing_ EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->config_mgr_.start_change_config(remove_b_pid, remove_b_ele_epoch, args.type_)); EXPECT_EQ(OB_EAGAIN, leader.palf_handle_impl_->config_mgr_.change_config_(args, remove_b_pid, remove_b_ele_epoch, remove_b_version)); - EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_TRUE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_TRUE(c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // 1. A sends config meta to C block_net(leader_idx, b_idx); while (-1 == leader.palf_handle_impl_->config_mgr_.last_submit_config_log_time_us_ || - c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)) { + c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)) { EXPECT_EQ(OB_EAGAIN, leader.palf_handle_impl_->config_mgr_.change_config_(args, remove_b_pid, remove_b_ele_epoch, remove_b_version)); usleep(500); } - EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_UNTIL_EQ(true, b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_UNTIL_EQ(false, c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_UNTIL_EQ(true, b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_UNTIL_EQ(false, c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // 2. B is elected to be the leader for (auto srv: get_cluster()) { @@ -182,7 +182,7 @@ TEST_F(TestObSimpleLogClusterConfigChangeMockEle, switch_leader_during_removing_ unblock_net(leader_idx, b_idx); // 4. A's memberlist will be reset - EXPECT_UNTIL_EQ(true, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_UNTIL_EQ(true, leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); revert_cluster_palf_handle_guard(palf_list); } @@ -220,21 +220,21 @@ TEST_F(TestObSimpleLogClusterConfigChangeMockEle, switch_leader_during_removing_ EXPECT_EQ(OB_SUCCESS, leader.palf_handle_impl_->config_mgr_.start_change_config(remove_b_pid, remove_b_ele_epoch, args.type_)); EXPECT_EQ(OB_EAGAIN, leader.palf_handle_impl_->config_mgr_.change_config_(args, remove_b_pid, remove_b_ele_epoch, remove_b_version)); - EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_TRUE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_TRUE(c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_TRUE(c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // A sends config meta to C block_net(leader_idx, b_idx); while (-1 == leader.palf_handle_impl_->config_mgr_.last_submit_config_log_time_us_ || - c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)) { + c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)) { EXPECT_EQ(OB_EAGAIN, leader.palf_handle_impl_->config_mgr_.change_config_(args, remove_b_pid, remove_b_ele_epoch, remove_b_version)); usleep(500); } - EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_UNTIL_EQ(true, b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_UNTIL_EQ(false, c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_FALSE(leader.palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_UNTIL_EQ(true, b_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_UNTIL_EQ(false, c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); // 2. C is elected to be the leader for (auto srv: get_cluster()) { @@ -247,8 +247,8 @@ TEST_F(TestObSimpleLogClusterConfigChangeMockEle, switch_leader_during_removing_ unblock_net(leader_idx, b_idx); // 4. A's memberlist will be re-sync by C successfully - EXPECT_UNTIL_EQ(false, a_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); - EXPECT_UNTIL_EQ(false, c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.log_sync_memberlist_.contains(b_addr)); + EXPECT_UNTIL_EQ(false, a_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); + EXPECT_UNTIL_EQ(false, c_handle->palf_handle_impl_->config_mgr_.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(b_addr)); leader.reset(); revert_cluster_palf_handle_guard(palf_list); @@ -263,4 +263,4 @@ TEST_F(TestObSimpleLogClusterConfigChangeMockEle, switch_leader_during_removing_ int main(int argc, char **argv) { RUN_SIMPLE_LOG_CLUSTER_TEST(TEST_NAME); -} \ No newline at end of file +} diff --git a/mittest/logservice/test_ob_simple_log_engine.cpp b/mittest/logservice/test_ob_simple_log_engine.cpp index 413ba6f08..9bf7ca5f0 100644 --- a/mittest/logservice/test_ob_simple_log_engine.cpp +++ b/mittest/logservice/test_ob_simple_log_engine.cpp @@ -467,7 +467,7 @@ TEST_F(TestObSimpleLogClusterLogEngine, io_reducer_basic_func) EXPECT_EQ(OB_SUCCESS, create_paxos_group(id_1, leader_idx_1, leader_1)); EXPECT_EQ(OB_SUCCESS, get_palf_env(leader_idx_1, palf_env)); - LogIOWorker *log_io_worker = leader_1.palf_handle_impl_->log_engine_.log_io_worker_;; + LogIOWorker *log_io_worker = leader_1.palf_handle_impl_->log_engine_.log_io_worker_; int64_t prev_log_id_1 = 0; int64_t prev_has_batched_size = 0; @@ -520,7 +520,7 @@ TEST_F(TestObSimpleLogClusterLogEngine, io_reducer_basic_func) IOTaskVerify io_task_verify_2(id_2, log_engine->palf_epoch_); EXPECT_EQ(OB_SUCCESS, create_paxos_group(id_2, leader_idx_2, leader_2)); { - LogIOWorker *log_io_worker = leader_2.palf_handle_impl_->log_engine_.log_io_worker_;; + LogIOWorker *log_io_worker = leader_2.palf_handle_impl_->log_engine_.log_io_worker_; // 聚合度为1的忽略 EXPECT_EQ(OB_SUCCESS, log_io_worker->submit_io_task(&io_task_cond_2)); EXPECT_EQ(OB_SUCCESS, submit_log(leader_1, 1, id_1, 110)); @@ -589,7 +589,7 @@ TEST_F(TestObSimpleLogClusterLogEngine, io_reducer_basic_func) IOTaskVerify io_task_verify_3(id_3, log_engine->palf_epoch_); EXPECT_EQ(OB_SUCCESS, create_paxos_group(id_3, leader_idx_3, leader_3)); { - LogIOWorker *log_io_worker = leader_3.palf_handle_impl_->log_engine_.log_io_worker_;; + LogIOWorker *log_io_worker = leader_3.palf_handle_impl_->log_engine_.log_io_worker_; EXPECT_EQ(OB_SUCCESS, log_io_worker->submit_io_task(&io_task_cond_3)); EXPECT_EQ(OB_SUCCESS, submit_log(leader_1, 1, id_1, 110)); EXPECT_EQ(OB_SUCCESS, submit_log(leader_2, 1, id_2, 110)); @@ -637,7 +637,7 @@ TEST_F(TestObSimpleLogClusterLogEngine, io_reducer_basic_func) IOTaskVerify io_task_verify_4(id_4, log_engine->palf_epoch_); EXPECT_EQ(OB_SUCCESS, create_paxos_group(id_4, leader_idx_4, leader_4)); { - LogIOWorker *log_io_worker = leader_4.palf_handle_impl_->log_engine_.log_io_worker_;; + LogIOWorker *log_io_worker = leader_4.palf_handle_impl_->log_engine_.log_io_worker_; EXPECT_EQ(OB_SUCCESS, log_io_worker->submit_io_task(&io_task_cond_4)); EXPECT_EQ(OB_SUCCESS, submit_log(leader_4, 10, id_4, 110)); sleep(1); @@ -673,7 +673,7 @@ TEST_F(TestObSimpleLogClusterLogEngine, io_reducer_basic_func) TruncateLogCbCtx ctx(LSN(0)); EXPECT_EQ(OB_SUCCESS, create_paxos_group(id_5, leader_idx_5, leader_5)); { - LogIOWorker *log_io_worker = leader_5.palf_handle_impl_->log_engine_.log_io_worker_;; + LogIOWorker *log_io_worker = leader_5.palf_handle_impl_->log_engine_.log_io_worker_; EXPECT_EQ(OB_SUCCESS, log_io_worker->submit_io_task(&io_task_cond_5)); EXPECT_EQ(OB_SUCCESS, submit_log(leader_5, 10, id_5, 110)); LSN max_lsn = leader_5.palf_handle_impl_->sw_.get_max_lsn(); @@ -701,7 +701,7 @@ TEST_F(TestObSimpleLogClusterLogEngine, io_reducer_basic_func) IOTaskVerify io_task_verify_6(id_6, log_engine->palf_epoch_); EXPECT_EQ(OB_SUCCESS, create_paxos_group(id_6, leader_idx_6, leader_6)); { - LogIOWorker *log_io_worker = leader_6.palf_handle_impl_->log_engine_.log_io_worker_;; + LogIOWorker *log_io_worker = leader_6.palf_handle_impl_->log_engine_.log_io_worker_; { EXPECT_EQ(OB_SUCCESS, submit_log(leader_6, 15, id_6, MAX_LOG_BODY_SIZE)); sleep(2); diff --git a/mittest/logservice/test_ob_simple_log_flashback.cpp b/mittest/logservice/test_ob_simple_log_flashback.cpp index 3150faf90..99fef8a35 100644 --- a/mittest/logservice/test_ob_simple_log_flashback.cpp +++ b/mittest/logservice/test_ob_simple_log_flashback.cpp @@ -144,10 +144,15 @@ TEST_F(TestObSimpleLogClusterFlashback, flashback_basic_func) unittest::PalfHandleImplGuard leader1, leader2; EXPECT_EQ(OB_SUCCESS, create_paxos_group(id1, leader_idx1, leader1)); EXPECT_EQ(OB_SUCCESS, create_paxos_group(id2, leader_idx2, leader2)); - ASSERT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[1]->get_addr(), 1), 2, CONFIG_CHANGE_TIMEOUT_US)); - EXPECT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[2]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT_US)); - EXPECT_EQ(OB_SUCCESS, leader2.palf_handle_impl_->add_member(ObMember(get_cluster()[1]->get_addr(), 1), 2, CONFIG_CHANGE_TIMEOUT_US)); - EXPECT_EQ(OB_SUCCESS, leader2.palf_handle_impl_->add_member(ObMember(get_cluster()[2]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT_US)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[1]->get_addr(), 1), 2, config_version, CONFIG_CHANGE_TIMEOUT_US)); + ASSERT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[2]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT_US)); + ASSERT_EQ(OB_SUCCESS, leader2.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader2.palf_handle_impl_->add_member(ObMember(get_cluster()[1]->get_addr(), 1), 2, config_version, CONFIG_CHANGE_TIMEOUT_US)); + ASSERT_EQ(OB_SUCCESS, leader2.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader2.palf_handle_impl_->add_member(ObMember(get_cluster()[2]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT_US)); EXPECT_EQ(OB_SUCCESS, submit_log(leader1, 500, leader_idx1)); EXPECT_EQ(OB_SUCCESS, submit_log(leader2, 500, leader_idx2)); SCN flashback_scn; @@ -211,8 +216,11 @@ TEST_F(TestObSimpleLogClusterFlashback, flashback_with_reconfirm1) if (leader_idx1 != 0) { EXPECT_EQ(OB_SUCCESS, switch_leader(id1, 0, leader1)); } - EXPECT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[1]->get_addr(), 1), 2, CONFIG_CHANGE_TIMEOUT_US)); - EXPECT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[2]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT_US)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[1]->get_addr(), 1), 2, config_version, CONFIG_CHANGE_TIMEOUT_US)); + ASSERT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[2]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT_US)); EXPECT_EQ(OB_SUCCESS, submit_log(leader1, 1000, leader_idx1)); wait_until_has_committed(leader1, leader1.palf_handle_impl_->get_max_lsn()); LogEntryHeader header_origin; @@ -377,8 +385,11 @@ TEST_F(TestObSimpleLogClusterFlashback, flashback_after_restart) if (leader_idx1 != 0) { EXPECT_EQ(OB_SUCCESS, switch_leader(id1, 0, leader1)); } - EXPECT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[1]->get_addr(), 1), 2, CONFIG_CHANGE_TIMEOUT_US)); - EXPECT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[2]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT_US)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[1]->get_addr(), 1), 2, config_version, CONFIG_CHANGE_TIMEOUT_US)); + ASSERT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->get_config_version(config_version)); + EXPECT_EQ(OB_SUCCESS, leader1.palf_handle_impl_->add_member(ObMember(get_cluster()[2]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT_US)); EXPECT_EQ(OB_SUCCESS, submit_log(leader1, 1000, leader_idx1)); wait_until_has_committed(leader1, leader1.palf_handle_impl_->get_max_lsn()); switch_append_to_raw_write(leader1, mode_version1); diff --git a/mittest/logservice/test_ob_simple_log_throttling.cpp b/mittest/logservice/test_ob_simple_log_throttling.cpp index 84698b1d5..d632d1c93 100644 --- a/mittest/logservice/test_ob_simple_log_throttling.cpp +++ b/mittest/logservice/test_ob_simple_log_throttling.cpp @@ -73,7 +73,7 @@ TEST_F(TestObSimpleLogClusterLogThrottling, test_throttling_sys) palf_env_impl.disk_options_wrapper_.set_cur_unrecyclable_log_disk_size(unrecyclable_size); PalfThrottleOptions throttle_options; palf_env_impl.disk_options_wrapper_.get_throttling_options(throttle_options); - LogIOWorker *log_io_worker = leader.palf_handle_impl_->log_engine_.log_io_worker_;; + LogIOWorker *log_io_worker = leader.palf_handle_impl_->log_engine_.log_io_worker_; LogWritingThrottle *throttle = log_io_worker->throttle_; // sys log stream no need throttling PalfThrottleOptions invalid_throttle_options; @@ -134,7 +134,7 @@ TEST_F(TestObSimpleLogClusterLogThrottling, test_throttling_basic) palf_env_impl.disk_options_wrapper_.set_cur_unrecyclable_log_disk_size(unrecyclable_size); PalfThrottleOptions throttle_options; palf_env_impl.disk_options_wrapper_.get_throttling_options(throttle_options); - LogIOWorker *log_io_worker = leader.palf_handle_impl_->log_engine_.log_io_worker_;; + LogIOWorker *log_io_worker = leader.palf_handle_impl_->log_engine_.log_io_worker_; LogWritingThrottle *throttle = log_io_worker->throttle_; PalfThrottleOptions invalid_throttle_options; diff --git a/mittest/logservice/test_ob_simple_log_throttling_arb.cpp b/mittest/logservice/test_ob_simple_log_throttling_arb.cpp index a68f39ee8..11fffbc8e 100644 --- a/mittest/logservice/test_ob_simple_log_throttling_arb.cpp +++ b/mittest/logservice/test_ob_simple_log_throttling_arb.cpp @@ -178,8 +178,12 @@ TEST_F(TestObSimpleLogThrottleArb, test_2f1a_throttling_major) palf_list[another_f_idx]->palf_handle_impl_->sw_.freeze_mode_ = PERIOD_FREEZE_MODE; palf_list[follower_D_idx]->palf_handle_impl_->sw_.freeze_mode_ = PERIOD_FREEZE_MODE; ASSERT_EQ(OB_SUCCESS, submit_log(leader, 10, id, 128 * KB)); + + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); ret = leader.palf_handle_impl_->replace_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), ObMember(get_cluster()[another_f_idx]->get_addr(), 1), + config_version, CONFIG_CHANGE_TIMEOUT); //timeout because added member can flush new meta when prev log is throttling ASSERT_TRUE(OB_TIMEOUT == ret || OB_SUCCESS == ret); @@ -299,9 +303,14 @@ TEST_F(TestObSimpleLogThrottleArb, test_2f1a_throttling_minor_leader) PALF_LOG(INFO, "[CASE 2.3]: MINOR_LEADER replace_member"); leader.palf_handle_impl_->sw_.freeze_mode_ = PERIOD_FREEZE_MODE; + ASSERT_EQ(OB_SUCCESS, submit_log(leader, 5, id, 128 * KB)); + + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), ObMember(get_cluster()[another_f_idx]->get_addr(), 1), + config_version, CONFIG_CHANGE_TIMEOUT)); ASSERT_EQ(OB_SUCCESS, submit_log(leader, 5, id, 128)); @@ -428,8 +437,12 @@ TEST_F(TestObSimpleLogThrottleArb, test_2f1a_throttling_minor_follower) ASSERT_EQ(OB_SUCCESS, submit_log(leader, 5, id, 128 * KB)); ASSERT_EQ(OB_SUCCESS, get_palf_env(another_f_idx, palf_env)); palf_env->palf_env_impl_.disk_options_wrapper_.disk_opts_for_stopping_writing_.log_disk_throttling_percentage_ = throttling_percentage; + + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->replace_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), ObMember(get_cluster()[another_f_idx]->get_addr(), 1), + config_version, CONFIG_CHANGE_TIMEOUT)); ASSERT_EQ(OB_SUCCESS, submit_log(leader, 5, id, 128)); ASSERT_EQ(OB_SUCCESS, get_palf_env(follower_D_idx, palf_env)); @@ -485,8 +498,13 @@ TEST_F(TestObSimpleLogThrottleArb, test_4f1a_degrade_upgrade) common::ObMember dummy_member; std::vector palf_list; ASSERT_EQ(OB_SUCCESS, create_paxos_group_with_arb(id, &loc_cb, arb_replica_idx, leader_idx, false, leader)); - ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[3]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT)); - ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[4]->get_addr(), 1), 4, CONFIG_CHANGE_TIMEOUT)); + + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[3]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); + + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[4]->get_addr(), 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); ASSERT_EQ(OB_SUCCESS, get_cluster_palf_handle_guard(id, palf_list)); loc_cb.leader_ = leader.palf_handle_impl_->self_; diff --git a/mittest/logservice/test_ob_simple_log_throttling_member_change.cpp b/mittest/logservice/test_ob_simple_log_throttling_member_change.cpp index e56933bfe..775d7e442 100644 --- a/mittest/logservice/test_ob_simple_log_throttling_member_change.cpp +++ b/mittest/logservice/test_ob_simple_log_throttling_member_change.cpp @@ -133,7 +133,10 @@ TEST_F(TestObSimpleLogIOWorkerThrottlingV2, test_throttling_majority) ASSERT_EQ(OB_SUCCESS, submit_log(leader, 2, id, 512 * KB)); usleep(500 * 1000); PALF_LOG(INFO, "CASE[1.4] test add_member while throttling"); - ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT)); + + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); ASSERT_EQ(OB_SUCCESS, submit_log(leader, 1, id, 1 * KB)); PALF_LOG(INFO, "CASE[1.5] test switch_leader while throttling[major]"); @@ -291,7 +294,9 @@ TEST_F(TestObSimpleLogIOWorkerThrottlingV2, test_throttling_minor_leader) ASSERT_EQ(OB_TIMEOUT, new_leader.palf_handle_impl_->remove_member(ObMember(get_cluster()[follower_C_idx]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT)); ASSERT_EQ(OB_SUCCESS, submit_log(new_leader, 1, id, 1 * KB)); usleep(500 * 1000); - ASSERT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), 4, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_SUCCESS, new_leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); ASSERT_EQ(OB_SUCCESS, submit_log(new_leader, 1, id, 1 * KB)); PALF_LOG(INFO, "end test throttling_minor_leader", K(id)); @@ -369,7 +374,9 @@ TEST_F(TestObSimpleLogIOWorkerThrottlingV2, test_throttling_minor_follower) ASSERT_EQ(OB_SUCCESS, submit_log(leader, 1, id, 512 * KB)); usleep(500 * 1000); PALF_LOG(INFO, "[CASE 3.4] test add_member(3-4)"); - ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), 4, CONFIG_CHANGE_TIMEOUT)); + LogConfigVersion config_version; + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), 4, config_version, CONFIG_CHANGE_TIMEOUT)); ASSERT_EQ(OB_SUCCESS, submit_log(leader, 1, id, 1 * KB)); ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->remove_member(ObMember(get_cluster()[follower_D_idx]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT)); @@ -383,7 +390,8 @@ TEST_F(TestObSimpleLogIOWorkerThrottlingV2, test_throttling_minor_follower) ASSERT_EQ(OB_SUCCESS, submit_log(leader, 1, id, 512 * KB)); usleep(500 * 1000); PALF_LOG(INFO, "[CASE 3.4] test add_member"); - ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_B_idx]->get_addr(), 1), 3, CONFIG_CHANGE_TIMEOUT)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->get_config_version(config_version)); + ASSERT_EQ(OB_SUCCESS, leader.palf_handle_impl_->add_member(ObMember(get_cluster()[follower_B_idx]->get_addr(), 1), 3, config_version, CONFIG_CHANGE_TIMEOUT)); ASSERT_EQ(OB_SUCCESS, submit_log(leader, 1, id, 1 * KB)); PALF_LOG(INFO, "[CASE 3.5] test switch_leader to C (not throttled replica)"); diff --git a/mittest/mtlenv/CMakeLists.txt b/mittest/mtlenv/CMakeLists.txt index 035636f6f..843ca1e61 100644 --- a/mittest/mtlenv/CMakeLists.txt +++ b/mittest/mtlenv/CMakeLists.txt @@ -2,6 +2,7 @@ sql_unittest(test_session_serde) #ob_unittest(test_ob_election_priority) storage_unittest(test_tx_data_table) storage_unittest(test_multi_tenant test_multi_tenant.cpp) +storage_unittest(test_buffer_ctx_node test_buffer_ctx_node.cpp) add_subdirectory(storage) add_subdirectory(tablelock) diff --git a/mittest/mtlenv/mock_tenant_module_env.h b/mittest/mtlenv/mock_tenant_module_env.h index 287caabe4..d7d60f3a3 100644 --- a/mittest/mtlenv/mock_tenant_module_env.h +++ b/mittest/mtlenv/mock_tenant_module_env.h @@ -36,8 +36,10 @@ #include "share/ob_alive_server_tracer.h" #include "share/ob_device_manager.h" #include "share/ob_io_device_helper.h" +#include "share/ob_simple_mem_limit_getter.h" #include "share/resource_manager/ob_cgroup_ctrl.h" #include "share/scheduler/ob_dag_scheduler.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "share/schema/ob_multi_version_schema_service.h" #include "share/schema/ob_tenant_schema_service.h" #include "share/stat/ob_opt_stat_monitor_manager.h" @@ -51,6 +53,7 @@ #include "storage/slog/ob_storage_logger.h" #include "storage/compaction/ob_sstable_merge_info_mgr.h" #include "storage/compaction/ob_tenant_freeze_info_mgr.h" +#include "storage/compaction/ob_compaction_diagnose.h" #include "storage/tx_storage/ob_checkpoint_service.h" #include "storage/tx_storage/ob_tenant_freezer.h" #include "storage/tx_storage/ob_access_service.h" @@ -73,10 +76,12 @@ #include "share/scn.h" #include "mock_gts_source.h" #include "storage/blocksstable/ob_shared_macro_block_manager.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" #include "storage/concurrency_control/ob_multi_version_garbage_collector.h" #include "storage/tablelock/ob_table_lock_service.h" #include "storage/tx/wrs/ob_tenant_weak_read_service.h" #include "logservice/palf/log_define.h" +#include "storage/high_availability/ob_rebuild_service.h" namespace oceanbase { @@ -309,6 +314,7 @@ public: int remove_sys_tenant(); void release_guard(); void destroy(); + bool is_inited() const { return inited_; } public: static int init_slogger_mgr(const char *log_dir); @@ -362,6 +368,8 @@ private: // switch tenant thread local share::ObTenantSwitchGuard guard_; + common::ObSimpleMemLimitGetter getter_; + bool inited_; bool destroyed_; @@ -497,6 +505,9 @@ int MockTenantModuleEnv::prepare_io() const int64_t async_io_thread_count = 8; const int64_t sync_io_thread_count = 2; const int64_t max_io_depth = 256; + const int64_t bucket_num = 1024L; + const int64_t max_cache_size = 1024L * 1024L * 512; + const int64_t block_size = common::OB_MALLOC_BIG_BLOCK_SIZE; if (OB_FAIL(ret)) { // do nothing } else if (OB_FAIL(THE_IO_DEVICE->init(iod_opts))) { @@ -514,6 +525,13 @@ int MockTenantModuleEnv::prepare_io() STORAGE_LOG(WARN, "fail to start io manager", K(ret)); } else if (OB_FAIL(ObIOManager::get_instance().add_tenant_io_manager(OB_SERVER_TENANT_ID, io_config))) { STORAGE_LOG(WARN, "add tenant io config failed", K(ret)); + } else if (OB_FAIL(ObKVGlobalCache::get_instance().init(&getter_, + bucket_num, + max_cache_size, + block_size))) { + STORAGE_LOG(WARN, "fail to init kv global cache ", K(ret)); + } else if (OB_FAIL(OB_STORE_CACHE.init(10, 1, 1, 1, 1, 10000, 10))) { + STORAGE_LOG(WARN, "fail to init OB_STORE_CACHE, ", K(ret)); } else { } return ret; @@ -670,13 +688,17 @@ int MockTenantModuleEnv::init() MTL_BIND2(mtl_new_default, share::detector::ObDeadLockDetectorMgr::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, storage::ObTenantTabletStatMgr::mtl_init, nullptr, mtl_stop_default, mtl_wait_default, mtl_destroy_default) MTL_BIND2(mtl_new_default, storage::ObTenantSSTableMergeInfoMgr::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); + MTL_BIND2(mtl_new_default, share::ObDagWarningHistoryManager::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); + MTL_BIND2(mtl_new_default, compaction::ObScheduleSuspectInfoMgr::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, storage::ObTenantFreezeInfoMgr::mtl_init, nullptr, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObSharedMacroBlockMgr::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); + MTL_BIND2(mtl_new_default, storage::mds::ObTenantMdsService::mtl_init, storage::mds::ObTenantMdsService::mtl_start, storage::mds::ObTenantMdsService::mtl_stop, storage::mds::ObTenantMdsService::mtl_wait, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObMultiVersionGarbageCollector::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObTableLockService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(server_obj_pool_mtl_new, nullptr, nullptr, nullptr, nullptr, server_obj_pool_mtl_destroy); MTL_BIND2(server_obj_pool_mtl_new, nullptr, nullptr, nullptr, nullptr, server_obj_pool_mtl_destroy); MTL_BIND(ObTenantSQLSessionMgr::mtl_init, ObTenantSQLSessionMgr::mtl_destroy); + MTL_BIND2(mtl_new_default, ObRebuildService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); } if (OB_FAIL(ret)) { @@ -777,7 +799,7 @@ void MockTenantModuleEnv::destroy() multi_tenant_.stop(); multi_tenant_.wait(); multi_tenant_.destroy(); - + ObKVGlobalCache::get_instance().destroy(); ObServerCheckpointSlogHandler::get_instance().destroy(); SLOGGERMGR.destroy(); diff --git a/mittest/mtlenv/storage/CMakeLists.txt b/mittest/mtlenv/storage/CMakeLists.txt index 65ff4a577..1d7524fc4 100644 --- a/mittest/mtlenv/storage/CMakeLists.txt +++ b/mittest/mtlenv/storage/CMakeLists.txt @@ -3,20 +3,26 @@ storage_unittest(test_ls_service test_ls_service.cpp) storage_dml_unittest(test_write_tablet_slog test_write_tablet_slog.cpp) storage_dml_unittest(test_table_scan_pure_data_table) storage_dml_unittest(test_tenant_meta_mem_mgr test_tenant_meta_mem_mgr.cpp) -storage_dml_unittest(test_tablet_create_delete_helper test_tablet_create_delete_helper.cpp) -storage_dml_unittest(test_tablet_status test_tablet_status.cpp) +#storage_dml_unittest(test_tablet_status test_tablet_status.cpp) TODO yq: transfer fix later +storage_dml_unittest(test_tablet_status_cache test_tablet_status_cache.cpp) +storage_dml_unittest(test_tablet_member_load_and_free test_tablet_member_load_and_free.cpp) storage_dml_unittest(test_ls_migration_param test_ls_migration_param.cpp) storage_dml_unittest(test_ls_tablet_service test_ls_tablet_service.cpp) #storage_dml_unittest(test_lob_manager test_lob_manager.cpp) storage_unittest(test_trans test_trans.cpp) -storage_unittest(test_ls_restore_task_mgr) +#storage_unittest(test_ls_restore_task_mgr) storage_dml_unittest(test_index_sstable_estimator) storage_dml_unittest(test_index_sstable_multi_estimator) storage_dml_unittest(test_multi_version_sstable_single_get) -storage_dml_unittest(test_multi_version_sstable_merge) +#storage_dml_unittest(test_multi_version_sstable_merge) TODO(dengzhi.ldz): fix it +storage_dml_unittest(test_medium_info_reader test_medium_info_reader.cpp) +storage_dml_unittest(test_tablet_mds_data test_tablet_mds_data.cpp) storage_unittest(test_physical_copy_task test_physical_copy_task.cpp) +storage_unittest(test_shared_block_reader_writer) +storage_dml_unittest(test_macro_ref_cnt test_macro_ref_cnt.cpp) # storage_dml_unittest(test_multi_version_merge_recycle) # storage_unittest(test_speed_limit test_speed_limit.cpp) +storage_dml_unittest(test_ls_tablet_info_writer_and_reader test_ls_tablet_info_writer_and_reader.cpp) add_subdirectory(checkpoint) add_subdirectory(blocksstable) diff --git a/mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h b/mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h index 48306de83..03ba0554e 100644 --- a/mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h +++ b/mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h @@ -69,7 +69,7 @@ public: const int64_t snapshot_version, const ObDmlFlag dml_flag, ObDatumRow &multi_row); static void fake_freeze_info(); virtual ObITable::TableType get_merged_table_type() const; - void prepare_query_param(const bool is_reverse_scan, const ObTableReadInfo &full_read_info); + void prepare_query_param(const bool is_reverse_scan); void destroy_query_param(); void prepare_ddl_kv(); protected: @@ -103,11 +103,13 @@ protected: ObTableAccessContext context_; ObStoreCtx store_ctx_; ObTableReadInfo read_info_; - ObArenaAllocator allocator_; + static ObArenaAllocator allocator_; ObTabletHandle tablet_handle_; }; -void TestIndexBlockDataPrepare::prepare_query_param(const bool is_reverse_scan, const ObTableReadInfo &full_read_info) +ObArenaAllocator TestIndexBlockDataPrepare::allocator_; + +void TestIndexBlockDataPrepare::prepare_query_param(const bool is_reverse_scan) { schema_cols_.set_allocator(&allocator_); schema_cols_.init(table_schema_.get_column_count()); @@ -115,10 +117,8 @@ void TestIndexBlockDataPrepare::prepare_query_param(const bool is_reverse_scan, iter_param_.table_id_ = table_schema_.get_table_id(); iter_param_.tablet_id_ = table_schema_.get_table_id(); ASSERT_EQ(OB_SUCCESS, read_info_.init( - allocator_, 10, table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), schema_cols_)); + allocator_, 10, table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), schema_cols_, nullptr/*storage_cols_index*/)); iter_param_.read_info_ = &read_info_; - iter_param_.full_read_info_ = &full_read_info; - iter_param_.tablet_handle_ = tablet_handle_; //jsut for test context_.query_flag_.set_not_use_row_cache(); context_.query_flag_.set_use_block_cache(); @@ -172,17 +172,10 @@ void TestIndexBlockDataPrepare::SetUpTestCase() SAFE_DESTROY_INSTANCE.init(); SAFE_DESTROY_INSTANCE.start(); ObServerCheckpointSlogHandler::get_instance().is_started_ = true; + ObClockGenerator::init(); - const int64_t bucket_num = 1024L; - const int64_t max_cache_size = 1024L * 1024L * 512; - const int64_t block_size = common::OB_MALLOC_BIG_BLOCK_SIZE; ObIOManager::get_instance().add_tenant_io_manager( tenant_id_, ObTenantIOConfig::default_instance()); - EXPECT_EQ(OB_SUCCESS, ObKVGlobalCache::get_instance().init(&getter, - bucket_num, - max_cache_size, - block_size)); - EXPECT_EQ(OB_SUCCESS, OB_STORE_CACHE.init(10, 1, 1, 1, 1, 10000)); fake_freeze_info(); @@ -195,12 +188,10 @@ void TestIndexBlockDataPrepare::SetUpTestCase() ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); // create tablet - obrpc::ObBatchCreateTabletArg create_tablet_arg; share::schema::ObTableSchema table_schema; - ASSERT_EQ(OB_SUCCESS, gen_create_tablet_arg(tenant_id_, ls_id, tablet_id, create_tablet_arg, 1, &table_schema)); - - ObLSTabletService *ls_tablet_svr = ls_handle.get_ls()->get_tablet_svr(); - ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(*ls_tablet_svr, create_tablet_arg)); + uint64_t table_id = 30007; + ASSERT_EQ(OB_SUCCESS, build_test_schema(table_schema, table_id)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema, allocator_)); } void TestIndexBlockDataPrepare::TearDownTestCase() @@ -216,6 +207,7 @@ void TestIndexBlockDataPrepare::TearDownTestCase() void TestIndexBlockDataPrepare::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); prepare_schema(); prepare_data(); } @@ -361,12 +353,15 @@ void TestIndexBlockDataPrepare::prepare_schema() ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); ObTabletHandle tablet_handle; + void *ptr = nullptr; ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); ObTablet *tablet = tablet_handle.get_obj(); - tablet->storage_schema_.reset(); - tablet->storage_schema_.init(*tablet->allocator_, table_schema_, lib::Worker::CompatMode::MYSQL); - tablet->full_read_info_.reset(); - tablet->build_read_info(*tablet->allocator_); + ASSERT_NE(nullptr, ptr = allocator_.alloc(sizeof(ObStorageSchema))); + tablet->storage_schema_addr_.ptr_ = new (ptr) ObStorageSchema(); + tablet->storage_schema_addr_.get_ptr()->init(allocator_, table_schema_, lib::Worker::CompatMode::MYSQL); + ASSERT_NE(nullptr, ptr = allocator_.alloc(sizeof(ObRowkeyReadInfo))); + tablet->rowkey_read_info_ = new (ptr) ObRowkeyReadInfo(); + tablet->build_read_info(allocator_); } void TestIndexBlockDataPrepare::prepare_data() @@ -384,15 +379,16 @@ void TestIndexBlockDataPrepare::prepare_data() ASSERT_NE(nullptr, root_index_builder_); desc.sstable_index_builder_ = root_index_builder_; desc.need_prebuild_bloomfilter_ = true; - desc.bloomfilter_rowkey_prefix_ = TEST_ROWKEY_COLUMN_CNT; - + desc.bloomfilter_rowkey_prefix_ = table_schema_.rowkey_column_num_; ASSERT_TRUE(desc.is_valid()); ObDataStoreDesc index_desc; - ASSERT_EQ(OB_SUCCESS, index_desc.init(index_schema_, ObLSID(ls_id_), ObTabletID(tablet_id_), merge_type_, SNAPSHOT_VERSION, CLUSTER_VERSION_4_1_0_0)); + ASSERT_EQ(OB_SUCCESS, index_desc.init_as_index(table_schema_, ObLSID(ls_id_), ObTabletID(tablet_id_), merge_type_, SNAPSHOT_VERSION, CLUSTER_VERSION_4_1_0_0)); index_desc.schema_version_ = 10; + index_desc.need_prebuild_bloomfilter_ = false; ASSERT_TRUE(index_desc.is_valid()); + ASSERT_EQ(OB_SUCCESS, root_index_builder_->init(index_desc)); root_index_builder_->index_store_desc_.need_pre_warm_ = false; // close index block pre warm @@ -419,6 +415,11 @@ void TestIndexBlockDataPrepare::prepare_data() param.recycle_version_ = 1; param.sstable_logic_seq_ = 1; param.is_ready_for_read_ = true; + int64_t column_cnt = 0; + + table_schema_.get_store_column_count(column_cnt, true); + column_cnt += ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + sstable_.reset(); insert_data(writer); @@ -432,9 +433,7 @@ void TestIndexBlockDataPrepare::prepare_data() ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); ObSSTableMergeRes res; - int64_t column_cnt = 0; - ASSERT_EQ(OB_SUCCESS, tablet_handle.get_obj()->storage_schema_.get_stored_column_count_in_sstable(column_cnt)); - ASSERT_EQ(OB_SUCCESS, root_index_builder_->close(column_cnt, res)); + ASSERT_EQ(OB_SUCCESS, root_index_builder_->close(res)); ObIndexTreeRootBlockDesc root_desc; root_desc = res.root_desc_; ASSERT_TRUE(root_desc.is_valid()); @@ -511,10 +510,11 @@ void TestIndexBlockDataPrepare::prepare_data() param.master_key_id_ = res.master_key_id_; MEMCPY(param.encrypt_key_, res.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); if (merge_type_ == MAJOR_MERGE) { - ASSERT_EQ(OB_SUCCESS, ObSSTableMergeRes::fill_column_checksum_for_empty_major(param.column_cnt_, param.column_checksums_)); + ASSERT_EQ(OB_SUCCESS, param.column_checksums_.assign(res.data_column_checksums_)); } ASSERT_EQ(OB_SUCCESS, sstable_.init(param, &allocator_)); STORAGE_LOG(INFO, "create sstable param", K(param)); + ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); prepare_ddl_kv(); root_block_data_buf_.buf_ = root_buf; @@ -545,7 +545,7 @@ void TestIndexBlockDataPrepare::prepare_ddl_kv() ASSERT_EQ(OB_SUCCESS, meta_iter.open(query_range, ObMacroBlockMetaType::DATA_BLOCK_META, sstable_, - tablet_handle.get_obj()->get_index_read_info(), + tablet_handle.get_obj()->get_rowkey_read_info(), allocator_)); while (OB_SUCC(ret)) { diff --git a/mittest/mtlenv/storage/blocksstable/test_block_cache.cpp b/mittest/mtlenv/storage/blocksstable/test_block_cache.cpp index fe461e2c0..2cb6e3735 100644 --- a/mittest/mtlenv/storage/blocksstable/test_block_cache.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_block_cache.cpp @@ -71,7 +71,7 @@ void TestObMicroBlockCache::SetUp() ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle_)); - prepare_query_param(false, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(false); } void TestObMicroBlockCache::TearDown() @@ -117,11 +117,11 @@ TEST_F(TestObMicroBlockCache, test_block_cache) ObArray agg_projector; ObArray agg_column_schema; ObArray micro_idx_infos; - sstable_.get_index_tree_root(tablet_handle_.get_obj()->get_index_read_info(), root_block); + sstable_.get_index_tree_root(root_block); ASSERT_EQ(OB_SUCCESS, idx_row_scanner.init( agg_projector, agg_column_schema, - &tablet_handle_.get_obj()->get_index_read_info(), + tablet_handle_.get_obj()->get_rowkey_read_info().get_datum_utils(), allocator_, context_.query_flag_, 0)); @@ -143,8 +143,6 @@ TEST_F(TestObMicroBlockCache, test_block_cache) micro_idx_info.get_macro_id(), micro_idx_info, context_.query_flag_, - tablet_handle_.get_obj()->get_index_read_info(), - tablet_handle_, idx_io_handle)); ASSERT_EQ(OB_SUCCESS, idx_io_handle.wait(DEFAULT_IO_WAIT_TIME_MS)); ASSERT_EQ(OB_SUCCESS, index_block_cache_->get_cache_block( @@ -184,8 +182,6 @@ TEST_F(TestObMicroBlockCache, test_block_cache) data_idx_info.get_macro_id(), data_idx_info, context_.query_flag_, - tablet_handle_.get_obj()->get_full_read_info(), - tablet_handle_, data_io_handle)); ASSERT_EQ(OB_SUCCESS, data_io_handle.wait(DEFAULT_IO_WAIT_TIME_MS)); ASSERT_EQ(OB_SUCCESS, data_block_cache_->get_cache_block( @@ -218,7 +214,6 @@ TEST_F(TestObMicroBlockCache, test_block_cache) data_idx_info.get_macro_id(), multi_io_param, context_.query_flag_, - tablet_handle_.get_obj()->get_full_read_info(), multi_io_handle)); ASSERT_EQ(OB_SUCCESS, multi_io_handle.wait(DEFAULT_IO_WAIT_TIME_MS)); const ObMultiBlockIOResult *io_result @@ -250,7 +245,6 @@ TEST_F(TestObMicroBlockCache, test_block_cache) ASSERT_EQ(OB_SUCCESS, data_block_cache_->load_block( micro_block_id, micro_des_meta, - nullptr, ¯o_reader, loaded_micro_data, nullptr)); @@ -275,7 +269,6 @@ TEST_F(TestObMicroBlockCache, test_block_cache) ASSERT_EQ(OB_SUCCESS, index_block_cache_->load_block( micro_block_id, micro_des_meta, - &tablet_handle_.get_obj()->get_index_read_info(), nullptr, loaded_index_data, &allocator_)); diff --git a/mittest/mtlenv/storage/blocksstable/test_bloom_filter_cache.cpp b/mittest/mtlenv/storage/blocksstable/test_bloom_filter_cache.cpp index aee83752f..bb227a873 100644 --- a/mittest/mtlenv/storage/blocksstable/test_bloom_filter_cache.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_bloom_filter_cache.cpp @@ -44,6 +44,7 @@ public: void TestBloomFilterCache::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); ObColDesc col_desc; ObSEArray col_descs; col_desc.col_type_.set_int32(); @@ -100,14 +101,10 @@ TEST_F(TestBloomFilterCache, test_normal) ObBloomFilterCacheValue bf_value; const uint64_t tenant_id = 1; MacroBlockId block_id(0, 3, 0); - const int64_t bucket_num = 1024; - const int64_t max_cache_size = 1024 * 1024 * 512; - const int64_t block_size = common::OB_MALLOC_BIG_BLOCK_SIZE; uint64_t key_hash; - ObKVGlobalCache::get_instance().init(&getter, bucket_num, max_cache_size, block_size); // test ObBloomFilterCache may_contain() - ret = bf_cache.init("bf_cache", 1); + ret = bf_cache.init("test_normal_bf_cache", 1); EXPECT_EQ(OB_SUCCESS, ret); ret = bf_value.init(2, 1); @@ -166,7 +163,7 @@ TEST_F(TestBloomFilterCache, test_empty_read_cell_invalid) int8_t empty_read_prefix=3; ObEmptyReadCell *cell; - ret = bf_cache.init("bf_cache", 1,7); + ret = bf_cache.init("test_bf_cache", 1,7); EXPECT_NE(OB_SUCCESS, ret); ObBloomFilterCacheKey bf_key(tenant_id, block_id, empty_read_prefix); @@ -186,7 +183,7 @@ TEST_F(TestBloomFilterCache, test_empty_read_cell_normal) const int64_t block_size = common::OB_MALLOC_BIG_BLOCK_SIZE; ObKVGlobalCache::get_instance().init(&getter, bucket_num, max_cache_size, block_size); ObBloomFilterCache bf_cache; - ret = bf_cache.init("bf_cache", 1); + ret = bf_cache.init("test_bf_cache1", 1); EXPECT_EQ(OB_SUCCESS, ret); ObStoreRowkey rowkey; @@ -232,7 +229,9 @@ TEST_F(TestBloomFilterCache, test_empty_read_cell_normal) int main(int argc, char** argv) { - OB_LOGGER.set_log_level("ERROR"); + system("rm -f test_bloom_fitler_cache.log*"); + oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); + OB_LOGGER.set_file_name("test_bloom_filter_cache.log", true); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/mittest/mtlenv/storage/blocksstable/test_index_block_row_scanner.cpp b/mittest/mtlenv/storage/blocksstable/test_index_block_row_scanner.cpp old mode 100644 new mode 100755 index 3c84067dd..84b2eaa9f --- a/mittest/mtlenv/storage/blocksstable/test_index_block_row_scanner.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_index_block_row_scanner.cpp @@ -84,8 +84,7 @@ TEST_F(TestIndexBlockRowScanner, transform) root_block_data_buf_); char * extra_buf = reinterpret_cast(allocator_.alloc(extra_size)); ASSERT_NE(nullptr, extra_buf); - ASSERT_EQ(OB_SUCCESS, index_block_transformer.transform( - tablet_handle_.get_obj()->get_index_read_info(), root_block_data_buf_, extra_buf, extra_size)); + ASSERT_EQ(OB_SUCCESS, index_block_transformer.transform(root_block_data_buf_, extra_buf, extra_size)); const ObIndexBlockDataHeader *idx_blk_header = reinterpret_cast(extra_buf); for (int64_t i = 0; i < idx_blk_header->row_cnt_; ++i) { @@ -155,15 +154,14 @@ TEST_F(TestIndexBlockRowScanner, prefetch_and_scan) root_block_data_buf_); char * extra_buf = reinterpret_cast(allocator_.alloc(extra_size)); ASSERT_NE(nullptr, extra_buf); - ASSERT_EQ(OB_SUCCESS, transformer.transform( - tablet_handle_.get_obj()->get_index_read_info(), root_block_data_buf_, extra_buf, extra_size)); + ASSERT_EQ(OB_SUCCESS, transformer.transform(root_block_data_buf_, extra_buf, extra_size)); const ObIndexBlockDataHeader *root_blk_header = reinterpret_cast(extra_buf); ASSERT_EQ(OB_SUCCESS, idx_scanner.init( - agg_projector, agg_column_schema, &tablet_handle_.get_obj()->get_index_read_info(), allocator_, query_flag, 0)); + agg_projector, agg_column_schema, tablet_handle_.get_obj()->get_rowkey_read_info().get_datum_utils(), allocator_, query_flag, 0)); ASSERT_EQ(OB_SUCCESS, raw_idx_scanner.init( - agg_projector, agg_column_schema, &tablet_handle_.get_obj()->get_index_read_info(), allocator_, query_flag, 0)); + agg_projector, agg_column_schema, tablet_handle_.get_obj()->get_rowkey_read_info().get_datum_utils(), allocator_, query_flag, 0)); ObMacroBlockHandle macro_handle; const ObIndexBlockRowHeader *idx_row_header = nullptr; @@ -180,8 +178,6 @@ TEST_F(TestIndexBlockRowScanner, prefetch_and_scan) idx_row_header->get_macro_id(), idx_row, query_flag, - tablet_handle_.get_obj()->get_index_read_info(), - tablet_handle_, macro_handle)); ASSERT_EQ(OB_SUCCESS, macro_handle.wait(2000)); // Wait at most 2 sec @@ -238,8 +234,8 @@ TEST_F(TestIndexBlockRowScanner, prefetch_and_scan) int main(int argc, char **argv) { system("rm -f test_index_block_row_scanner.log*"); - OB_LOGGER.set_file_name("test_index_block_row_scanner.log"); oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); + OB_LOGGER.set_file_name("test_index_block_row_scanner.log", true, false); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/mittest/mtlenv/storage/blocksstable/test_index_block_row_struct.cpp b/mittest/mtlenv/storage/blocksstable/test_index_block_row_struct.cpp index 60fb2b0b8..0d50ec05f 100644 --- a/mittest/mtlenv/storage/blocksstable/test_index_block_row_struct.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_index_block_row_struct.cpp @@ -53,6 +53,7 @@ void TestIndexBlockRowStruct::TearDownTestCase() void TestIndexBlockRowStruct::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); desc_.ls_id_.id_ = 1; desc_.tablet_id_.id_ = 1; desc_.micro_block_size_ = 8 * 1024; diff --git a/mittest/mtlenv/storage/blocksstable/test_index_block_tree_cursor.cpp b/mittest/mtlenv/storage/blocksstable/test_index_block_tree_cursor.cpp index 032e04985..882c02995 100644 --- a/mittest/mtlenv/storage/blocksstable/test_index_block_tree_cursor.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_index_block_tree_cursor.cpp @@ -94,7 +94,7 @@ TEST_F(TestIndexBlockTreeCursor, test_normal) STORAGE_LOG(INFO, "normal test start"); uint64_t tenant_id = table_schema_.get_tenant_id(); ObIndexBlockTreeCursor tree_cursor; - ASSERT_EQ(OB_SUCCESS, tree_cursor.init(sstable_, allocator_, &tablet_handle_.get_obj()->get_index_read_info())); + ASSERT_EQ(OB_SUCCESS, tree_cursor.init(sstable_, allocator_, &tablet_handle_.get_obj()->get_rowkey_read_info())); const int64_t query_row_seed = max_row_seed_ - 5; const int64_t large_query_row_seed = max_row_seed_ + 1; @@ -175,7 +175,7 @@ TEST_F(TestIndexBlockTreeCursor, test_normal) TEST_F(TestIndexBlockTreeCursor, test_macro_iter) { ObMicroBlockData root_block; - sstable_.get_index_tree_root(tablet_handle_.get_obj()->get_index_read_info(), root_block); + sstable_.get_index_tree_root(root_block); ASSERT_TRUE(nullptr != root_block.get_extra_buf()); ObIndexBlockMacroIterator macro_iter; MacroBlockId macro_block_id; @@ -186,7 +186,7 @@ TEST_F(TestIndexBlockTreeCursor, test_macro_iter) // reverse whole scan ASSERT_EQ(OB_SUCCESS, macro_iter.open( - sstable_, iter_range, tablet_handle_.get_obj()->get_index_read_info(), allocator_, true, true)); + sstable_, iter_range, tablet_handle_.get_obj()->get_rowkey_read_info(), allocator_, true, true)); while (OB_SUCCESS == tmp_ret) { tmp_ret = macro_iter.get_next_macro_block(macro_block_id); STORAGE_LOG(DEBUG, "Reverse get next macro block", K(tmp_ret), K(cnt), @@ -203,7 +203,7 @@ TEST_F(TestIndexBlockTreeCursor, test_macro_iter) ASSERT_EQ(OB_SUCCESS, macro_iter.open( sstable_, iter_range, - tablet_handle_.get_obj()->get_index_read_info(), + tablet_handle_.get_obj()->get_rowkey_read_info(), allocator_, false, true)); @@ -247,7 +247,7 @@ TEST_F(TestIndexBlockTreeCursor, test_macro_iter) iter_range.border_flag_.set_inclusive_start(); iter_range.border_flag_.set_inclusive_end(); ASSERT_EQ(OB_SUCCESS, macro_iter.open( - sstable_, iter_range, tablet_handle_.get_obj()->get_index_read_info(), allocator_, false, true)); + sstable_, iter_range, tablet_handle_.get_obj()->get_rowkey_read_info(), allocator_, false, true)); ASSERT_EQ(OB_SUCCESS, macro_iter.get_next_macro_block(macro_desc)); ASSERT_TRUE(macro_desc.is_valid()); ASSERT_TRUE(macro_desc.range_.get_start_key().is_min_rowkey()); @@ -267,7 +267,7 @@ TEST_F(TestIndexBlockTreeCursor, test_macro_iter) iter_range.border_flag_.set_inclusive_start(); iter_range.border_flag_.set_inclusive_end(); ASSERT_EQ(OB_SUCCESS, macro_iter.open( - sstable_, iter_range, tablet_handle_.get_obj()->get_index_read_info(), allocator_, false, true)); + sstable_, iter_range, tablet_handle_.get_obj()->get_rowkey_read_info(), allocator_, false, true)); ASSERT_EQ(OB_SUCCESS, macro_iter.get_next_macro_block(macro_desc)); ASSERT_EQ(OB_ITER_END, macro_iter.get_next_macro_block(macro_desc)); @@ -279,7 +279,7 @@ TEST_F(TestIndexBlockTreeCursor, test_macro_iter) iter_range.border_flag_.unset_inclusive_start(); iter_range.border_flag_.set_inclusive_end(); ASSERT_EQ(OB_SUCCESS, macro_iter.open( - sstable_, iter_range, tablet_handle_.get_obj()->get_index_read_info(), allocator_, false, true)); + sstable_, iter_range, tablet_handle_.get_obj()->get_rowkey_read_info(), allocator_, false, true)); ASSERT_EQ(OB_SUCCESS, macro_iter.get_next_macro_block(macro_desc)); ASSERT_NE(macro_desc.macro_block_id_, first_macro_id); } @@ -294,7 +294,7 @@ TEST_F(TestIndexBlockTreeCursor, test_bare_micro_block_iterator) ASSERT_EQ(OB_SUCCESS, macro_iter.open( sstable_, iter_range, - tablet_handle_.get_obj()->get_index_read_info(), + tablet_handle_.get_obj()->get_rowkey_read_info(), allocator_, false, true)); diff --git a/mittest/mtlenv/storage/blocksstable/test_index_tree.cpp b/mittest/mtlenv/storage/blocksstable/test_index_tree.cpp index 44389650b..7db02cf92 100644 --- a/mittest/mtlenv/storage/blocksstable/test_index_tree.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_index_tree.cpp @@ -122,6 +122,7 @@ void TestIndexTree::TearDownTestCase() void TestIndexTree::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); int ret = OB_SUCCESS; mgr_ = OB_NEW(ObTenantFreezeInfoMgr, ObModIds::TEST); shared_blk_mgr_ = OB_NEW(ObSharedMacroBlockMgr, ObModIds::TEST); @@ -505,7 +506,7 @@ void TestIndexTreeStress::run1() void TestIndexTree::prepare_index_desc(ObDataStoreDesc &index_desc) { int ret = OB_SUCCESS; - ret = index_desc.init(index_schema_, ObLSID(1), ObTabletID(1), MAJOR_MERGE); + ret = index_desc.init_as_index(table_schema_, ObLSID(1), ObTabletID(1), MAJOR_MERGE); index_desc.major_working_cluster_version_ = DATA_VERSION_4_0_0_0; ASSERT_EQ(OB_SUCCESS, ret); } @@ -565,11 +566,11 @@ void TestIndexTree::mock_compaction(const int64_t test_row_num, ASSERT_EQ(fir_blk.original_size_, fir_blk.data_zsize_); ASSERT_EQ(sec_blk.original_size_, sec_blk.data_zsize_); ASSERT_EQ(OB_SUCCESS, data_writer.close()); - ASSERT_EQ(OB_SUCCESS, sstable_builder->close(data_desc.row_column_count_, res)); + ASSERT_EQ(OB_SUCCESS, sstable_builder->close(res)); ObSSTableMergeRes tmp_res; ASSERT_EQ(OB_ERR_UNEXPECTED, data_writer.close()); // not re-entrant - OK(sstable_builder->close(data_desc.row_column_count_, tmp_res)); // re-entrant + OK(sstable_builder->close(tmp_res)); // re-entrant ASSERT_EQ(tmp_res.root_desc_.buf_, res.root_desc_.buf_); ASSERT_EQ(tmp_res.data_root_desc_.buf_, res.data_root_desc_.buf_); ASSERT_EQ(tmp_res.data_blocks_cnt_, res.data_blocks_cnt_); @@ -650,12 +651,13 @@ TEST_F(TestIndexTree, test_macro_id_index_block) ObMicroBlockData root_block(payload_buf, payload_size); ASSERT_NE(sstable_builder.micro_reader_, nullptr); ObIMicroBlockReader *micro_reader = sstable_builder.micro_reader_; - ObTableReadInfo index_read_info; - OK(index_read_info.init(allocator_, 16000, TEST_ROWKEY_COLUMN_CNT, lib::is_oracle_mode(), index_desc.col_desc_array_, true)); + ObRowkeyReadInfo index_read_info; + OK(index_read_info.init(allocator_, index_desc)); OK(micro_reader->init(root_block, index_read_info)); ObDatumRow index_row; OK(index_row.init(allocator_, TEST_ROWKEY_COLUMN_CNT + 3)); + STORAGE_LOG(INFO, "macro block id", K(index_row)); void *buf = allocator_.alloc(common::OB_ROW_MAX_COLUMNS_COUNT * sizeof(common::ObObj)); int64_t row_count = micro_reader->row_count(); ASSERT_EQ(row_count, 1); @@ -779,7 +781,7 @@ TEST_F(TestIndexTree, test_empty_index_tree) // do not insert any data ASSERT_EQ(OB_SUCCESS, data_writer.close()); ObSSTableMergeRes res; - ret = sstable_builder.close(data_desc.row_column_count_, res); + ret = sstable_builder.close(res); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(res.root_desc_.is_empty()); @@ -899,7 +901,7 @@ TEST_F(TestIndexTree, test_multi_writers_with_close) OK(sstable_builder.sort_roots()); OK(sstable_builder.merge_index_tree(res)); res.reset(); - OK(sstable_builder.close(data_desc.row_column_count_, res)); + OK(sstable_builder.close(res)); ObIndexTreeRootBlockDesc &root_desc = res.root_desc_; ASSERT_TRUE(root_desc.is_valid()); @@ -910,8 +912,8 @@ TEST_F(TestIndexTree, test_multi_writers_with_close) ObMicroBlockData root_block(root_buf, root_size); ASSERT_NE(sstable_builder.micro_reader_, nullptr); ObIMicroBlockReader *micro_reader = sstable_builder.micro_reader_; - ObTableReadInfo read_info; - ASSERT_EQ(OB_SUCCESS, read_info.init(allocator_, 16000, TEST_ROWKEY_COLUMN_CNT, lib::is_oracle_mode(), index_desc.col_desc_array_, true)); + ObRowkeyReadInfo read_info; + ASSERT_EQ(OB_SUCCESS, read_info.init(allocator_, index_desc)); ret = micro_reader->init(root_block, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -950,7 +952,7 @@ TEST_F(TestIndexTree, test_merge_info_build_row) const int64_t rowkey_cnt = TEST_ROWKEY_COLUMN_CNT; blocksstable::ObDatumRow datum_row; ASSERT_EQ(OB_SUCCESS, datum_row.init(allocator_, rowkey_cnt + 3)); - for (int64_t i = 0; i < merge_info_list->count(); ++i) { + for (int64_t i = 0; nullptr != merge_info_list && i < merge_info_list->count(); ++i) { ObDataMacroBlockMeta *info = merge_info_list->at(i); ASSERT_NE(nullptr, info); ObDataBlockMetaVal &info_val = info->val_; @@ -1008,7 +1010,7 @@ TEST_F(TestIndexTree, test_meta_builder) ASSERT_EQ(OB_SUCCESS, container_macro_writer.open(index_desc, data_seq)); ObMetaIndexBlockBuilder meta_builder; ASSERT_EQ(OB_SUCCESS, meta_builder.init(index_desc, allocator_, container_macro_writer)); - for (int64_t i = 0; i < merge_info_list->count(); ++i) { + for (int64_t i = 0; nullptr != merge_info_list && i < merge_info_list->count(); ++i) { ObDataMacroBlockMeta *info = merge_info_list->at(i); ASSERT_EQ(OB_SUCCESS, info->build_row(leaf_row, allocator_)); ASSERT_EQ(OB_SUCCESS, meta_builder.append_leaf_row(leaf_row)); @@ -1026,8 +1028,8 @@ TEST_F(TestIndexTree, test_meta_builder) prepare_index_builder(index_desc, sstable_builder); ASSERT_NE(sstable_builder.micro_reader_, nullptr); ObIMicroBlockReader *micro_reader = sstable_builder.micro_reader_; - ObTableReadInfo read_info; - ASSERT_EQ(OB_SUCCESS, read_info.init(allocator_, 16000, TEST_ROWKEY_COLUMN_CNT, lib::is_oracle_mode(), index_desc.col_desc_array_, true)); + ObRowkeyReadInfo read_info; + ASSERT_EQ(OB_SUCCESS, read_info.init(allocator_, index_desc)); ret = micro_reader->init(root_block, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -1084,8 +1086,8 @@ TEST_F(TestIndexTree, test_meta_builder_data_root) prepare_index_builder(index_desc, sstable_builder); ASSERT_NE(sstable_builder.micro_reader_, nullptr); ObIMicroBlockReader *micro_reader = sstable_builder.micro_reader_; - ObTableReadInfo read_info; - ASSERT_EQ(OB_SUCCESS, read_info.init(allocator_, 16000, TEST_ROWKEY_COLUMN_CNT, lib::is_oracle_mode(), index_desc.col_desc_array_, true)); + ObRowkeyReadInfo read_info; + ASSERT_EQ(OB_SUCCESS, read_info.init(allocator_, index_desc)); ret = micro_reader->init(root_block, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -1123,7 +1125,7 @@ TEST_F(TestIndexTree, test_single_row_desc) ObSSTableMergeRes res; sstable_builder.optimization_mode_ = ObSSTableIndexBuilder::ObSpaceOptimizationMode::DISABLE; - OK(sstable_builder.close(data_desc.row_column_count_, res)); + OK(sstable_builder.close(res)); // test rebuild sstable ObSSTableIndexBuilder sstable_builder2; @@ -1142,7 +1144,7 @@ TEST_F(TestIndexTree, test_single_row_desc) OK(rebuilder.append_macro_row(macro_handle.get_buffer(), macro_handle.get_data_size(), info.macro_block_id_)); OK(rebuilder.close()); ObSSTableMergeRes res2; - OK(sstable_builder2.close(res.data_column_cnt_, res2)); + OK(sstable_builder2.close(res2)); // test rebuild sstable by another append_macro_row ObSSTableIndexBuilder sstable_builder3; @@ -1157,7 +1159,7 @@ TEST_F(TestIndexTree, test_single_row_desc) OK(other_rebuilder.close()); ObSSTableMergeRes res3; sstable_builder3.optimization_mode_ = ObSSTableIndexBuilder::ObSpaceOptimizationMode::AUTO; - OK(sstable_builder3.close(res.data_column_cnt_, res3)); + OK(sstable_builder3.close(res3)); } TEST_F(TestIndexTree, test_data_block_checksum) @@ -1188,24 +1190,6 @@ TEST_F(TestIndexTree, test_data_block_checksum) ASSERT_EQ(OB_SUCCESS, column_metas.push_back(column_meta)); ASSERT_EQ(OB_SUCCESS, column_default_checksum.push_back(column_meta.column_default_checksum_)); } - ObArray column_checksums; - ASSERT_EQ(OB_SUCCESS, res.fill_column_checksum(column_default_checksum, column_checksums)); - int64_t expected_column_checksum[max_reported_column_id]; - for (int64_t i = 0; i < TEST_COLUMN_CNT + 2; ++i) { - expected_column_checksum[i] = 0; - for (int64_t j = 0; j < test_row_num; ++j) { - ObDataMacroBlockMeta &meta= *(merge_info_list->at(j)); - STORAGE_LOG(DEBUG, "data macro meta after copy: ", K(ret), K(meta)); - expected_column_checksum[i] += meta.val_.column_checksums_[i]; - } - } - for (int64_t i = TEST_COLUMN_CNT + 2; i < max_reported_column_id; ++i) { - expected_column_checksum[i] = 0; - expected_column_checksum[i] = test_row_num * (i - TEST_COLUMN_CNT); - } - for (int64_t i = 0; i < max_reported_column_id; ++i) { - ASSERT_EQ(expected_column_checksum[i], column_checksums.at(i)); - } } TEST_F(TestIndexTree, test_reuse_macro_block) @@ -1235,7 +1219,7 @@ TEST_F(TestIndexTree, test_reuse_macro_block) } OK(data_writer.close()); ObSSTableMergeRes reused_res; - OK(sstable_builder.close(data_desc.row_column_count_, reused_res)); + OK(sstable_builder.close(reused_res)); ASSERT_EQ(res.data_blocks_cnt_, reused_res.data_blocks_cnt_); ASSERT_EQ(res.row_count_, reused_res.row_count_); @@ -1379,7 +1363,7 @@ TEST_F(TestIndexTree, test_rebuilder) } OK(data_writer.close()); ObSSTableMergeRes res1; - OK(sstable_builder1.close(data_desc.row_column_count_, res1)); + OK(sstable_builder1.close(res1)); ObIndexBlockRebuilder rebuilder; @@ -1409,7 +1393,7 @@ TEST_F(TestIndexTree, test_rebuilder) } OK(rebuilder.close()); ObSSTableMergeRes res2; - OK(sstable_builder2.close(data_desc.row_column_count_, res2)); + OK(sstable_builder2.close(res2)); // compare merge res ASSERT_EQ(res1.root_desc_.height_, res2.root_desc_.height_); ASSERT_EQ(res1.root_desc_.height_, 2); @@ -1418,8 +1402,8 @@ TEST_F(TestIndexTree, test_rebuilder) ObIMicroBlockReader *micro_reader1 = sstable_builder1.micro_reader_; ObIMicroBlockReader *micro_reader2 = sstable_builder2.micro_reader_; - ObTableReadInfo read_info; - OK(read_info.init(allocator_, 16000, TEST_ROWKEY_COLUMN_CNT, lib::is_oracle_mode(), index_desc1.col_desc_array_, true)); + ObRowkeyReadInfo read_info; + OK(read_info.init(allocator_, index_desc1)); OK(micro_reader1->init(root_block1, read_info)); OK(micro_reader2->init(root_block2, read_info)); @@ -1477,7 +1461,7 @@ TEST_F(TestIndexTree, test_estimate_meta_block_size) ObDataStoreDesc index_desc; ObSSTableIndexBuilder sstable_builder; ObDataStoreDesc data_desc; - OK(index_desc.init(index_schema_, ObLSID(1), ObTabletID(1), MINI_MERGE)); + OK(index_desc.init_as_index(table_schema_, ObLSID(1), ObTabletID(1), MINI_MERGE)); OK(sstable_builder.init(index_desc)); OK(data_desc.init(table_schema_, ObLSID(1), ObTabletID(1), MINI_MERGE, 1)); data_desc.sstable_index_builder_ = &sstable_builder; @@ -1494,6 +1478,7 @@ TEST_F(TestIndexTree, test_estimate_meta_block_size) for(int64_t i = 0; i < 10; ++i) { OK(row_generate_.get_next_row(i, row)); convert_to_multi_version_row(row, table_schema_.get_rowkey_column_num(), table_schema_.get_column_count(), SNAPSHOT_VERSION, dml, multi_row); + STORAGE_LOG(INFO, "append row", K(i), K(multi_row)); OK(data_writer.append_row(multi_row)); } const ObDatumRowkey& last_data_key = data_writer.last_key_; @@ -1516,6 +1501,38 @@ TEST_F(TestIndexTree, test_estimate_meta_block_size) macro_header_.fixed_header_.meta_block_size_); } +TEST_F(TestIndexTree, test_close_with_old_schema) +{ + int ret = OB_SUCCESS; + const int64_t test_row_num = 10; + ObArray data_write_ctxs; + ObArray index_write_ctxs; + ObMacroMetasArray *merge_info_list = nullptr; + ObSSTableMergeRes res; + IndexMicroBlockDescList *roots = nullptr; + mock_compaction(test_row_num, data_write_ctxs, index_write_ctxs, merge_info_list, res, roots); + ASSERT_EQ(test_row_num, merge_info_list->count()); + + // mock old schema with fewer columns + ObDataStoreDesc index_desc; + OK(index_desc.init_as_index(table_schema_, ObLSID(1), ObTabletID(1), MAJOR_MERGE)); + index_desc.major_working_cluster_version_ = DATA_VERSION_4_0_0_0; + --index_desc.full_stored_col_cnt_; + index_desc.col_default_checksum_array_.pop_back(); + + // read old macro block metas + ObSSTableIndexBuilder sstable_builder; + OK(sstable_builder.init(index_desc)); + ObIndexBlockRebuilder rebuilder; + OK(rebuilder.init(sstable_builder)); + for (int64_t i = 0; i < test_row_num; ++i) { + OK(rebuilder.append_macro_row(*merge_info_list->at(i))); + } + OK(rebuilder.close()); + ObSSTableMergeRes res2; + ASSERT_EQ(OB_INVALID_ARGUMENT, sstable_builder.close(res2)); +} + }//end namespace unittest }//end namespace oceanbase diff --git a/mittest/mtlenv/storage/blocksstable/test_shared_macro_block.cpp b/mittest/mtlenv/storage/blocksstable/test_shared_macro_block.cpp index b0322a0c0..3ba08ed63 100644 --- a/mittest/mtlenv/storage/blocksstable/test_shared_macro_block.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_shared_macro_block.cpp @@ -95,34 +95,37 @@ TEST_F(TestSharedMacroBlk, test_rebuild_sstable) ObArenaAllocator allocator; ObSSTableIndexBuilder *sstable_index_builder = OB_NEW(ObSSTableIndexBuilder, "SSTableIdx"); ObIndexBlockRebuilder *index_block_rebuilder = OB_NEW(ObIndexBlockRebuilder, "IdxRebuilder"); - ObTableHandleV2 table_handle; - ObSSTable *sstable = nullptr; + ObSSTable sstable; // rebuild sstable tablet_handle.get_obj()->tablet_meta_.snapshot_version_ = 12; - ASSERT_EQ(OB_SUCCESS, shared_blk_mgr->rebuild_sstable( - *(tablet_handle.get_obj()), sstable_, 0, *sstable_index_builder, *index_block_rebuilder, table_handle)); - ASSERT_EQ(OB_SUCCESS, table_handle.get_sstable(sstable)); - ASSERT_EQ(true, sstable_.meta_.basic_meta_ == sstable->meta_.basic_meta_); + int ret = shared_blk_mgr->rebuild_sstable(allocator, + *(tablet_handle.get_obj()), sstable_, 0, *sstable_index_builder, *index_block_rebuilder, sstable); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(true, sstable_.meta_->basic_meta_ == sstable.meta_->basic_meta_); // get old and new sstable ObMacroBlockHandle old_handle; ObMacroBlockReadInfo read_info; - read_info.macro_block_id_ = sstable_.meta_.macro_info_.data_block_ids_.at(0); - read_info.offset_ = sstable_.meta_.macro_info_.nested_offset_; - read_info.size_ = sstable_.meta_.macro_info_.nested_size_; + ObMacroIdIterator id_iterator; + ASSERT_EQ(OB_SUCCESS, sstable_.meta_->macro_info_.get_data_block_iter(id_iterator)); + ASSERT_EQ(OB_SUCCESS, id_iterator.get_next_macro_id(read_info.macro_block_id_)); + read_info.offset_ = sstable_.meta_->macro_info_.nested_offset_; + read_info.size_ = sstable_.meta_->macro_info_.nested_size_; read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_READ); ASSERT_EQ(OB_SUCCESS, ObBlockManager::read_block(read_info, old_handle)); ObMacroBlockHandle new_handle; - read_info.macro_block_id_ = sstable->meta_.macro_info_.data_block_ids_.at(0); - read_info.offset_ = sstable->meta_.macro_info_.nested_offset_; - read_info.size_ = sstable->meta_.macro_info_.nested_size_; + id_iterator.reset(); + ASSERT_EQ(OB_SUCCESS, sstable.meta_->macro_info_.get_data_block_iter(id_iterator)); + ASSERT_EQ(OB_SUCCESS, id_iterator.get_next_macro_id(read_info.macro_block_id_)); + read_info.offset_ = sstable.meta_->macro_info_.nested_offset_; + read_info.size_ = sstable.meta_->macro_info_.nested_size_; ASSERT_EQ(OB_SUCCESS, ObBlockManager::read_block(read_info, new_handle)); // compare two sstables - ASSERT_EQ(sstable_.meta_.macro_info_.nested_size_, sstable->meta_.macro_info_.nested_size_); - ASSERT_EQ(0, MEMCMP(old_handle.get_buffer(), new_handle.get_buffer(), sstable->meta_.macro_info_.nested_size_)); + ASSERT_EQ(sstable_.meta_->macro_info_.nested_size_, sstable.meta_->macro_info_.nested_size_); + ASSERT_EQ(0, MEMCMP(old_handle.get_buffer(), new_handle.get_buffer(), sstable.meta_->macro_info_.nested_size_)); OB_DELETE(ObSSTableIndexBuilder, "SSTableIdx", sstable_index_builder); OB_DELETE(ObIndexBlockRebuilder, "IdxRebuilder", index_block_rebuilder); @@ -170,6 +173,7 @@ int main(int argc, char **argv) system("rm -f test_shared_macro_block.log*"); OB_LOGGER.set_file_name("test_shared_macro_block.log"); oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); + oceanbase::common::ObClusterVersion::get_instance().init(CLUSTER_VERSION_4_1_0_0); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/mittest/mtlenv/storage/blocksstable/test_sstable_row_exister.cpp b/mittest/mtlenv/storage/blocksstable/test_sstable_row_exister.cpp index b00c84d00..98eb84224 100644 --- a/mittest/mtlenv/storage/blocksstable/test_sstable_row_exister.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_sstable_row_exister.cpp @@ -65,7 +65,7 @@ void TestSSTableRowExister::SetUp() ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle_)); - prepare_query_param(true, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(true); } void TestSSTableRowExister::TearDown() diff --git a/mittest/mtlenv/storage/blocksstable/test_sstable_row_getter.cpp b/mittest/mtlenv/storage/blocksstable/test_sstable_row_getter.cpp index c24a5df87..e0553bd8d 100644 --- a/mittest/mtlenv/storage/blocksstable/test_sstable_row_getter.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_sstable_row_getter.cpp @@ -67,7 +67,7 @@ void TestSSTableRowGetter::SetUp() ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle_)); - prepare_query_param(true, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(true); } void TestSSTableRowGetter::TearDown() diff --git a/mittest/mtlenv/storage/blocksstable/test_sstable_row_multi_getter.cpp b/mittest/mtlenv/storage/blocksstable/test_sstable_row_multi_getter.cpp index 3785fc66a..f0af1d645 100644 --- a/mittest/mtlenv/storage/blocksstable/test_sstable_row_multi_getter.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_sstable_row_multi_getter.cpp @@ -216,7 +216,7 @@ void TestSSTableRowMultiGetter::test_border(const bool is_reverse_scan) ObSSTableRowMultiGetter getter; // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); /* // empty rowkey @@ -275,7 +275,7 @@ void TestSSTableRowMultiGetter::test_normal(const bool is_reverse_scan) ObArray seeds; // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); // 2 rows exist test seeds.reuse(); diff --git a/mittest/mtlenv/storage/blocksstable/test_sstable_row_multi_scanner.cpp b/mittest/mtlenv/storage/blocksstable/test_sstable_row_multi_scanner.cpp index a697219b5..cf7a61e1e 100644 --- a/mittest/mtlenv/storage/blocksstable/test_sstable_row_multi_scanner.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_sstable_row_multi_scanner.cpp @@ -243,7 +243,7 @@ void TestSSTableRowMultiScanner::test_single_get_normal(const bool is_reverse_sc int ret = OB_SUCCESS; ObArray seeds; // prepare query param and context - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); // row in first macro ret = seeds.push_back(3); @@ -275,7 +275,7 @@ void TestSSTableRowMultiScanner::test_single_get_border(const bool is_reverse_sc int ret = OB_SUCCESS; ObArray seeds; // prepare query param and context - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); // left border rowkey ret = seeds.push_back(0); @@ -308,7 +308,7 @@ void TestSSTableRowMultiScanner::test_multi_get_normal(const bool is_reverse_sca ObArray seeds; // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); // 2 rows exist test seeds.reuse(); @@ -393,7 +393,7 @@ void TestSSTableRowMultiScanner::test_multi_get_border(const bool is_reverse_sca int ret = OB_SUCCESS; ObArray seeds; // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); // first row of sstable ret = seeds.push_back(0); @@ -441,7 +441,7 @@ void TestSSTableRowMultiScanner::test_single_scan_normal(const bool is_reverse_s const int64_t end = std::max(random_start, random_end); // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); // multiple rows exist ret = seeds.push_back(start); @@ -481,7 +481,7 @@ void TestSSTableRowMultiScanner::test_single_scan_border(const bool is_reverse_s int ret = OB_SUCCESS; ObArray seeds; // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); // full table scan ret = seeds.push_back(0); @@ -569,7 +569,7 @@ void TestSSTableRowMultiScanner::test_multi_scan_multi_scan_range( ObSSTableRowMultiScanner scanner; // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); //invalid argument with 0 ranges /* @@ -693,7 +693,7 @@ void TestSSTableRowMultiScanner::test_multi_scan_multi_get_with_scan( ObSSTableRowMultiScanner kv_scanner; // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); // multi scan interact with multi get ObDatumRange mget_ranges[TEST_MULTI_GET_CNT]; diff --git a/mittest/mtlenv/storage/blocksstable/test_sstable_row_scanner.cpp b/mittest/mtlenv/storage/blocksstable/test_sstable_row_scanner.cpp index 8745d5a5b..91a02a83e 100644 --- a/mittest/mtlenv/storage/blocksstable/test_sstable_row_scanner.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_sstable_row_scanner.cpp @@ -260,7 +260,7 @@ void TestSSTableRowScanner::test_border(const bool is_reverse_scan) ObDatumRange range; // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); // full table scan range.set_whole_range(); @@ -327,7 +327,7 @@ TEST_F(TestSSTableRowScanner, test_random) bool is_reverse_scan = false; // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) { test_one_case(range, start, end, is_reverse_scan, i); } @@ -335,7 +335,7 @@ TEST_F(TestSSTableRowScanner, test_random) is_reverse_scan = true; // prepare query param - prepare_query_param(is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(is_reverse_scan); for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) { test_one_case(range, start, end, is_reverse_scan, i); } diff --git a/mittest/mtlenv/storage/blocksstable/test_sstable_row_whole_scanner.cpp b/mittest/mtlenv/storage/blocksstable/test_sstable_row_whole_scanner.cpp index d4b73e958..b3cf25744 100644 --- a/mittest/mtlenv/storage/blocksstable/test_sstable_row_whole_scanner.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_sstable_row_whole_scanner.cpp @@ -100,8 +100,7 @@ void TestSSTableRowWholeScanner::generate_range( void TestSSTableRowWholeScanner::prepare_query_param(const bool is_reverse_scan) { - TestIndexBlockDataPrepare::prepare_query_param( - is_reverse_scan, tablet_handle_.get_obj()->get_full_read_info()); + TestIndexBlockDataPrepare::prepare_query_param(is_reverse_scan); context_.query_flag_.whole_macro_scan_ = true; } @@ -176,4 +175,4 @@ int main(int argc, char **argv) oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -} \ No newline at end of file +} diff --git a/mittest/mtlenv/storage/blocksstable/test_sstable_sec_meta_iterator.cpp b/mittest/mtlenv/storage/blocksstable/test_sstable_sec_meta_iterator.cpp index 042036740..f78b9d2da 100644 --- a/mittest/mtlenv/storage/blocksstable/test_sstable_sec_meta_iterator.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_sstable_sec_meta_iterator.cpp @@ -64,7 +64,7 @@ TEST_F(TestSSTableSecMetaIterator, test_basic) { ObArray data_macro_metas; uint64_t tenant_id = MTL_ID(); - const ObTableReadInfo &index_read_info = tablet_handle_.get_obj()->get_index_read_info(); + const ObITableReadInfo &index_read_info = tablet_handle_.get_obj()->get_rowkey_read_info(); ObSSTableSecMetaIterator meta_iter; ObDataMacroBlockMeta data_macro_meta; ObDatumRange range; @@ -254,14 +254,14 @@ TEST_F(TestSSTableSecMetaIterator, test_basic) } } ObDatumRowkey endkey; - ASSERT_EQ(OB_SUCCESS, sstable_.get_last_rowkey(index_read_info, allocator_, endkey)); + ASSERT_EQ(OB_SUCCESS, sstable_.get_last_rowkey(allocator_, endkey)); ASSERT_EQ(OB_ITER_END, tmp_ret); } TEST_F(TestSSTableSecMetaIterator, test_dual_iter) { uint64_t tenant_id = MTL_ID(); - const ObTableReadInfo &index_read_info = tablet_handle_.get_obj()->get_index_read_info(); + const ObITableReadInfo &index_read_info = tablet_handle_.get_obj()->get_rowkey_read_info(); ObDualMacroMetaIterator dual_iter; ObMacroBlockDesc macro_desc; ObDataMacroBlockMeta data_macro_meta; @@ -307,7 +307,7 @@ TEST_F(TestSSTableSecMetaIterator, test_dual_iter) TEST_F(TestSSTableSecMetaIterator, test_basic_range_spliter) { const int64_t target_parallel_cnt = 3; - const ObTableReadInfo &index_read_info = tablet_handle_.get_obj()->get_index_read_info(); + const ObITableReadInfo &index_read_info = tablet_handle_.get_obj()->get_rowkey_read_info(); ObPartitionRangeSpliter range_spliter; ObRangeSplitInfo range_info; ObArray tables; @@ -318,7 +318,7 @@ TEST_F(TestSSTableSecMetaIterator, test_basic_range_spliter) store_range.get_end_key().set_max(); ASSERT_EQ(OB_SUCCESS, range_spliter.get_range_split_info( tables, index_read_info, store_range, range_info)); - ASSERT_EQ(range_info.max_macro_block_count_, sstable_.get_meta().get_basic_meta().data_macro_block_count_); + ASSERT_EQ(range_info.max_macro_block_count_, sstable_.get_data_macro_block_count()); // ASSERT_EQ(range_info.total_size_, sstable_.get_meta().basic_meta_.occupy_size_); range_info.set_parallel_target(target_parallel_cnt); ASSERT_EQ(OB_SUCCESS, range_spliter.split_ranges(range_info, allocator_, true, range_array_1)); @@ -334,7 +334,7 @@ TEST_F(TestSSTableSecMetaIterator, test_basic_range_spliter) store_range.get_end_key().assign(row_cells, TEST_ROWKEY_COLUMN_CNT); ASSERT_EQ(OB_SUCCESS, range_spliter.get_range_split_info( tables, index_read_info, store_range, range_info)); - ASSERT_EQ(range_info.max_macro_block_count_, sstable_.get_meta().get_basic_meta().data_macro_block_count_); + ASSERT_EQ(range_info.max_macro_block_count_, sstable_.get_data_macro_block_count()); // ASSERT_EQ(range_info.total_size_, sstable_.get_meta().basic_meta_.occupy_size_); range_info.set_parallel_target(target_parallel_cnt); ASSERT_EQ(OB_SUCCESS, range_spliter.split_ranges(range_info, allocator_, false, range_array_2)); diff --git a/mittest/mtlenv/storage/checkpoint/CMakeLists.txt b/mittest/mtlenv/storage/checkpoint/CMakeLists.txt index a396bbbba..a2f35f117 100644 --- a/mittest/mtlenv/storage/checkpoint/CMakeLists.txt +++ b/mittest/mtlenv/storage/checkpoint/CMakeLists.txt @@ -1,3 +1,3 @@ -storage_unittest(test_checkpoint_executor) +#storage_unittest(test_checkpoint_executor) TODO yq: transfer fix later storage_unittest(test_data_checkpoint) storage_unittest(test_lock_memtable_checkpoint) diff --git a/mittest/mtlenv/storage/checkpoint/test_checkpoint_executor.cpp b/mittest/mtlenv/storage/checkpoint/test_checkpoint_executor.cpp index 2dd46837e..da4650ead 100644 --- a/mittest/mtlenv/storage/checkpoint/test_checkpoint_executor.cpp +++ b/mittest/mtlenv/storage/checkpoint/test_checkpoint_executor.cpp @@ -216,6 +216,7 @@ TestCheckpointExecutor::TestCheckpointExecutor() void TestCheckpointExecutor::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); tenant_id_ = MTL_ID(); } @@ -282,6 +283,7 @@ TEST_F(TestCheckpointExecutor, calculate_checkpoint) ASSERT_EQ(OB_SUCCESS, checkpoint_executor2->init(ls2, &mock_log_handler_)); checkpoint_executor2->start(); + ASSERT_EQ(OB_SUCCESS, checkpoint_executor2->update_clog_checkpoint()); tmp.val_ = 5; ASSERT_EQ(tmp, ls2->get_ls_meta().get_clog_checkpoint_scn()); @@ -345,4 +347,4 @@ int main(int argc, char **argv) oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -} \ No newline at end of file +} diff --git a/mittest/mtlenv/storage/checkpoint/test_data_checkpoint.cpp b/mittest/mtlenv/storage/checkpoint/test_data_checkpoint.cpp index cfdef3bf3..a37fefc25 100644 --- a/mittest/mtlenv/storage/checkpoint/test_data_checkpoint.cpp +++ b/mittest/mtlenv/storage/checkpoint/test_data_checkpoint.cpp @@ -169,6 +169,7 @@ TestDataCheckpoint::TestDataCheckpoint() {} void TestDataCheckpoint::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); tenant_id_ = MTL_ID(); } void TestDataCheckpoint::TearDown() diff --git a/mittest/mtlenv/storage/medium_info_helper.h b/mittest/mtlenv/storage/medium_info_helper.h new file mode 100644 index 000000000..99cb4258d --- /dev/null +++ b/mittest/mtlenv/storage/medium_info_helper.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2021 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_UNITTEST_MEDIUM_INFO_HELPER +#define OCEANBASE_UNITTEST_MEDIUM_INFO_HELPER + +#include +#include "lib/allocator/ob_allocator.h" +#include "unittest/storage/init_basic_struct.h" +#include "unittest/storage/schema_utils.h" +#include "storage/compaction/ob_medium_compaction_mgr.h" + +namespace oceanbase +{ +namespace storage +{ +class MediumInfoHelper +{ +public: + static int build_medium_compaction_info( + common::ObIAllocator &allocator, + compaction::ObMediumCompactionInfo &info, + const int64_t medium_snapshot); +}; + +int MediumInfoHelper::build_medium_compaction_info( + common::ObIAllocator &allocator, + compaction::ObMediumCompactionInfo &info, + const int64_t medium_snapshot) +{ + int ret = common::OB_SUCCESS; + info.compaction_type_ = compaction::ObMediumCompactionInfo::ObCompactionType::MEDIUM_COMPACTION; + info.medium_snapshot_ = medium_snapshot; + info.last_medium_snapshot_ = medium_snapshot; + info.data_version_ = 100; + info.cluster_id_ = 1; + + // storage schema + const uint64_t table_id = 1234567; + share::schema::ObTableSchema table_schema; + build_test_schema(table_schema, table_id); + ret = info.storage_schema_.init(allocator, table_schema, lib::Worker::CompatMode::MYSQL); + + return ret; +} +} +} + +#endif // OCEANBASE_UNITTEST_MEDIUM_INFO_HELPER diff --git a/mittest/mtlenv/storage/test_index_sstable_estimator.cpp b/mittest/mtlenv/storage/test_index_sstable_estimator.cpp index 9cf80a289..32a8ce44c 100644 --- a/mittest/mtlenv/storage/test_index_sstable_estimator.cpp +++ b/mittest/mtlenv/storage/test_index_sstable_estimator.cpp @@ -67,7 +67,7 @@ void TestIndexSSTableEstimator::SetUp() ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle_)); - prepare_query_param(false, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(false); } void TestIndexSSTableEstimator::TearDown() diff --git a/mittest/mtlenv/storage/test_index_sstable_multi_estimator.cpp b/mittest/mtlenv/storage/test_index_sstable_multi_estimator.cpp index cac431247..446879bbd 100644 --- a/mittest/mtlenv/storage/test_index_sstable_multi_estimator.cpp +++ b/mittest/mtlenv/storage/test_index_sstable_multi_estimator.cpp @@ -69,7 +69,7 @@ void TestMultiVersionIndexSSTableEstimator::SetUp() ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle_)); prepare_context(); - prepare_query_param(false, tablet_handle_.get_obj()->get_full_read_info()); + prepare_query_param(false); } void TestMultiVersionIndexSSTableEstimator::TearDown() diff --git a/mittest/mtlenv/storage/test_lob_manager.cpp b/mittest/mtlenv/storage/test_lob_manager.cpp index 58ae319fd..43c246730 100644 --- a/mittest/mtlenv/storage/test_lob_manager.cpp +++ b/mittest/mtlenv/storage/test_lob_manager.cpp @@ -65,6 +65,7 @@ public: } virtual void SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); } diff --git a/mittest/mtlenv/storage/test_ls_migration_param.cpp b/mittest/mtlenv/storage/test_ls_migration_param.cpp index 12471499a..f2f251b65 100644 --- a/mittest/mtlenv/storage/test_ls_migration_param.cpp +++ b/mittest/mtlenv/storage/test_ls_migration_param.cpp @@ -55,6 +55,7 @@ public: static const int64_t TEST_LS_ID = 101; blocksstable::ObSSTableMeta sstable_meta_; + common::ObArenaAllocator allocator_; }; TestLSMigrationParam::TestLSMigrationParam() @@ -92,6 +93,7 @@ void TestLSMigrationParam::TearDownTestCase() void TestLSMigrationParam::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); int ret = OB_SUCCESS; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); @@ -122,8 +124,6 @@ void TestLSMigrationParam::SetUp() sstable_meta_.basic_meta_.latest_row_store_type_ = ObRowStoreType::ENCODING_ROW_STORE; sstable_meta_.basic_meta_.data_index_tree_height_ = 0; sstable_meta_.macro_info_.macro_meta_info_.addr_ = addr; - - sstable_meta_.allocator_ = &t3m->get_tenant_allocator(); ASSERT_TRUE(sstable_meta_.check_meta()); sstable_meta_.is_inited_ = true; ASSERT_TRUE(sstable_meta_.is_valid()); @@ -152,7 +152,6 @@ TEST_F(TestLSMigrationParam, test_migrate_sstable_param) { int ret = OB_SUCCESS; - common::ObIAllocator &allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); ObMigrationSSTableParam sstable_param; ObITable::TableKey key; key.table_type_ = ObITable::TableType::MAJOR_SSTABLE; @@ -190,7 +189,9 @@ TEST_F(TestLSMigrationParam, test_migrate_sstable_param) sstable_param.basic_meta_.master_key_id_ = sstable_meta_.basic_meta_.master_key_id_; MEMCPY(sstable_param.basic_meta_.encrypt_key_, sstable_meta_.basic_meta_.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); - ASSERT_EQ(OB_SUCCESS, sstable_param.column_checksums_.assign(sstable_meta_.column_checksums_)); + for (int64_t i = 0; i < sstable_meta_.get_col_checksum_cnt(); ++i) { + ASSERT_EQ(OB_SUCCESS, sstable_param.column_checksums_.push_back(sstable_meta_.get_col_checksum()[i])); + } ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(sstable_meta_.is_valid()); ASSERT_TRUE(sstable_param.is_valid()); @@ -199,19 +200,25 @@ TEST_F(TestLSMigrationParam, test_migrate_sstable_param) TEST_F(TestLSMigrationParam, test_placeholder_storage_schema) { int ret = OB_SUCCESS; - ObStorageSchema storage_schema; ObArenaAllocator allocator; + ObStorageSchema storage_schema; compaction::ObMediumCompactionInfoList medium_info_list; + ObTabletFullMemoryMdsData full_memory_mds_data; - ret = ObMigrationTabletParam::construct_placeholder_storage_schema_and_medium(allocator, storage_schema, medium_info_list); + ret = ObMigrationTabletParam::construct_placeholder_storage_schema_and_medium(allocator, storage_schema, medium_info_list, full_memory_mds_data); ASSERT_EQ(OB_SUCCESS, ret); + void *ptr = nullptr; ObTablet placeholder_tablet; - ret = placeholder_tablet.storage_schema_.init(allocator, storage_schema); + ASSERT_NE(nullptr, ptr = allocator.alloc(sizeof(ObStorageSchema))); + placeholder_tablet.storage_schema_addr_.ptr_ = new (ptr) ObStorageSchema(); + ret = placeholder_tablet.storage_schema_addr_.get_ptr()->init(allocator, storage_schema); ASSERT_EQ(OB_SUCCESS, ret); - placeholder_tablet.tablet_meta_.compat_mode_ = lib::Worker::get_compatibility_mode(); - ret = placeholder_tablet.build_read_info(allocator); + placeholder_tablet.tablet_meta_.compat_mode_ = lib::Worker::get_compatibility_mode(); + ASSERT_NE(nullptr, ptr = allocator.alloc(sizeof(ObRowkeyReadInfo))); + placeholder_tablet.rowkey_read_info_ = new (ptr) ObRowkeyReadInfo(); + placeholder_tablet.build_read_info(allocator); ASSERT_EQ(OB_SUCCESS, ret); } @@ -230,7 +237,7 @@ TEST_F(TestLSMigrationParam, test_migrate_tablet_param) ObTabletHandle src_handle; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - ret = t3m->acquire_tablet(WashTabletPriority::WTP_HIGH, src_key, ls_handle, src_handle, false); + ret = t3m->create_tmp_tablet(WashTabletPriority::WTP_HIGH, src_key, allocator_, ls_handle, src_handle); ASSERT_EQ(common::OB_SUCCESS, ret); share::schema::ObTableSchema table_schema; @@ -239,12 +246,11 @@ TEST_F(TestLSMigrationParam, test_migrate_tablet_param) ObTabletID empty_tablet_id; ObTabletTableStoreFlag store_flag; store_flag.set_with_major_sstable(); - ObTableHandleV2 empty_handle; SCN scn; scn.convert_from_ts(ObTimeUtility::current_time()); - ret = src_handle.get_obj()->init(src_key.ls_id_, src_key.tablet_id_, src_key.tablet_id_, - empty_tablet_id, empty_tablet_id, scn, 2022, table_schema, - lib::Worker::CompatMode::MYSQL, store_flag, empty_handle, ls_handle.get_ls()->get_freezer()); + ret = src_handle.get_obj()->init(allocator_, src_key.ls_id_, src_key.tablet_id_, src_key.tablet_id_, + scn, 2022, table_schema, + lib::Worker::CompatMode::MYSQL, store_flag, nullptr, ls_handle.get_ls()->get_freezer()); ASSERT_EQ(common::OB_SUCCESS, ret); ObMigrationTabletParam tablet_param; @@ -257,16 +263,22 @@ TEST_F(TestLSMigrationParam, test_migrate_tablet_param) dst_key.tablet_id_ = 1003; ObTabletHandle dst_handle; - ret = t3m->acquire_tablet(WashTabletPriority::WTP_HIGH, dst_key, ls_handle, dst_handle, false); + ret = t3m->create_tmp_tablet(WashTabletPriority::WTP_HIGH, dst_key, allocator_, ls_handle, dst_handle); ASSERT_EQ(common::OB_SUCCESS, ret); - ret = dst_handle.get_obj()->init(tablet_param, false, ls_handle.get_ls()->get_freezer()); + ret = dst_handle.get_obj()->init(allocator_, tablet_param, false, ls_handle.get_ls()->get_freezer()); ASSERT_EQ(common::OB_SUCCESS, ret); const ObTabletMeta &src_meta = src_handle.get_obj()->get_tablet_meta(); const ObTabletMeta &dst_meta = dst_handle.get_obj()->get_tablet_meta(); + LOG_INFO("dump meta", K(src_meta)); + LOG_INFO("dump meta", K(dst_meta)); ASSERT_TRUE(src_meta.is_valid()); ASSERT_TRUE(dst_meta.is_valid()); + + // check create_schema_version_ in tablet meta/migrate param + ASSERT_TRUE(table_schema.get_schema_version() == src_meta.create_schema_version_); + ASSERT_TRUE(table_schema.get_schema_version() == tablet_param.create_schema_version_); } TEST_F(TestLSMigrationParam, test_migration_param_compat) @@ -287,7 +299,7 @@ TEST_F(TestLSMigrationParam, test_migration_param_compat) ObTabletHandle src_handle; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - ret = t3m->acquire_tablet(WashTabletPriority::WTP_HIGH, src_key, ls_handle, src_handle, false); + ret = t3m->create_tmp_tablet(WashTabletPriority::WTP_HIGH, src_key, allocator_, ls_handle, src_handle); ASSERT_EQ(common::OB_SUCCESS, ret); share::schema::ObTableSchema table_schema; @@ -296,12 +308,11 @@ TEST_F(TestLSMigrationParam, test_migration_param_compat) ObTabletID empty_tablet_id; ObTabletTableStoreFlag store_flag; store_flag.set_with_major_sstable(); - ObTableHandleV2 empty_handle; SCN scn; scn.convert_from_ts(ObTimeUtility::current_time()); - ret = src_handle.get_obj()->init(src_key.ls_id_, src_key.tablet_id_, src_key.tablet_id_, - empty_tablet_id, empty_tablet_id, scn, 2022, table_schema, - lib::Worker::CompatMode::MYSQL, store_flag, empty_handle, ls_handle.get_ls()->get_freezer()); + ret = src_handle.get_obj()->init(allocator_, src_key.ls_id_, src_key.tablet_id_, src_key.tablet_id_, + scn, 2022, table_schema, + lib::Worker::CompatMode::MYSQL, store_flag, nullptr, ls_handle.get_ls()->get_freezer()); ASSERT_EQ(common::OB_SUCCESS, ret); ObMigrationTabletParam tablet_param; @@ -309,9 +320,15 @@ TEST_F(TestLSMigrationParam, test_migration_param_compat) ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(tablet_param.is_valid()); + // check create_schema_version_ in tablet meta/migrate param + ASSERT_TRUE(table_schema.get_schema_version() == src_handle.get_obj()->get_tablet_meta().create_schema_version_); + ASSERT_TRUE(table_schema.get_schema_version() == tablet_param.create_schema_version_); + + tablet_param.ddl_commit_scn_.convert_for_tx(20230403); int64_t pos = 0; ret = tablet_param.serialize(buf, buf_len, pos); ASSERT_EQ(OB_SUCCESS, ret); + OB_LOG(INFO, "cooper", K(tablet_param)); // normal deserialize ObMigrationTabletParam des_param; @@ -319,14 +336,31 @@ TEST_F(TestLSMigrationParam, test_migration_param_compat) ret = des_param.deserialize(buf, buf_len, pos); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(des_param.is_valid()); + OB_LOG(INFO, "cooper", K(des_param)); +} - // deserialize old format - pos = 24; // magic_number_ + version_ + length_ - des_param.reset(); +TEST_F(TestLSMigrationParam, test_deleted_tablet_info) +{ + int ret = OB_SUCCESS; + const int64_t buf_len = 4096; + char buf[buf_len] = {}; + share::ObLSID ls_id(1); + ObTabletID tablet_id(200001); + ObMigrationTabletParam param; + ret = param.build_deleted_tablet_info(ls_id, tablet_id); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(param.is_valid()); + + int64_t pos = 0; + ret = param.serialize(buf, buf_len, pos); + ASSERT_EQ(OB_SUCCESS, ret); + + pos = 0; + ObMigrationTabletParam des_param; ret = des_param.deserialize(buf, buf_len, pos); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_TRUE(des_param.is_valid()); } + } // namespace storage } // namespace oceanbase diff --git a/mittest/mtlenv/storage/test_ls_restore_task_mgr.cpp b/mittest/mtlenv/storage/test_ls_restore_task_mgr.cpp index dee246d8b..521620901 100644 --- a/mittest/mtlenv/storage/test_ls_restore_task_mgr.cpp +++ b/mittest/mtlenv/storage/test_ls_restore_task_mgr.cpp @@ -220,6 +220,10 @@ public: MockTenantModuleEnv::get_instance().destroy(); } + void SetUp() + { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); + } static void create_ls() { ObCreateLSArg arg; @@ -565,7 +569,7 @@ TEST_F(TestLSRestoreHandler, wait_state) EXPECT_EQ(OB_SUCCESS, ls->get_ls_restore_handler()->update_state_handle_()); EXPECT_EQ(ObLSRestoreStatus::Status::WAIT_RESTORE_TABLETS_META, ls->get_ls_restore_handler()->state_handler_->ls_restore_status_); EXPECT_EQ(OB_SUCCESS, ls->get_ls_restore_handler()->state_handler_->do_restore()); - EXPECT_EQ(ObLSRestoreStatus::Status::QUICK_RESTORE, ls->ls_meta_.restore_status_); + EXPECT_EQ(ObLSRestoreStatus::Status::RESTORE_TO_CONSISTENT_SCN, ls->ls_meta_.restore_status_); // leader in wait quick restore ls->get_ls_restore_handler()->state_handler_ = nullptr; ls->ls_meta_.restore_status_ = ObLSRestoreStatus::Status::WAIT_QUICK_RESTORE; @@ -615,12 +619,12 @@ TEST_F(TestLSRestoreHandler, wait_state) EXPECT_EQ(OB_SUCCESS, ls->get_ls_restore_handler()->update_state_handle_()); EXPECT_EQ(ObLSRestoreStatus::Status::WAIT_RESTORE_TABLETS_META, ls->get_ls_restore_handler()->state_handler_->ls_restore_status_); EXPECT_EQ(OB_SUCCESS, ls->get_ls_restore_handler()->state_handler_->do_restore()); - EXPECT_EQ(ObLSRestoreStatus::Status::QUICK_RESTORE, ls->ls_meta_.restore_status_); + EXPECT_EQ(ObLSRestoreStatus::Status::RESTORE_TO_CONSISTENT_SCN, ls->ls_meta_.restore_status_); leader_status = ObLSRestoreStatus::Status::WAIT_QUICK_RESTORE; ls->ls_meta_.restore_status_ = ObLSRestoreStatus::Status::WAIT_RESTORE_TABLETS_META; EXPECT_EQ(OB_SUCCESS, ls->get_ls_restore_handler()->state_handler_->do_restore()); - EXPECT_EQ(ObLSRestoreStatus::Status::QUICK_RESTORE, ls->ls_meta_.restore_status_); + EXPECT_EQ(ObLSRestoreStatus::Status::RESTORE_TO_CONSISTENT_SCN, ls->ls_meta_.restore_status_); leader_status = ObLSRestoreStatus::Status::RESTORE_TABLETS_META; ls->ls_meta_.restore_status_ = ObLSRestoreStatus::Status::WAIT_RESTORE_TABLETS_META; diff --git a/mittest/mtlenv/storage/test_ls_service.cpp b/mittest/mtlenv/storage/test_ls_service.cpp index a2618426f..73881be51 100644 --- a/mittest/mtlenv/storage/test_ls_service.cpp +++ b/mittest/mtlenv/storage/test_ls_service.cpp @@ -43,6 +43,12 @@ public: virtual ~TestLSService() = default; static void SetUpTestCase(); static void TearDownTestCase(); + void SetUp() + { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); + } +private: + common::ObArenaAllocator allocator_; }; using namespace oceanbase; @@ -171,7 +177,6 @@ TEST_F(TestLSService, tablet_test) ObLS *ls = NULL; ObLSID ls_id(103); ObTabletID tablet_id(1001); - obrpc::ObCreateTabletBatchRes res; obrpc::ObBatchCreateTabletArg create_tablet_arg; ObMemberList member_list; int64_t paxos_replica_num = 1; @@ -181,10 +186,8 @@ TEST_F(TestLSService, tablet_test) (void) member_list.add_server(MockTenantModuleEnv::get_instance().self_addr_); // TEST_F(TestLSService, create_tablet) - LOG_INFO("TestLSService::tablet_test 1. create_tablet begin"); - // 1. create a tablet + // create ls ASSERT_EQ(OB_SUCCESS, gen_create_ls_arg(tenant_id, ls_id, arg)); - ASSERT_EQ(OB_SUCCESS, gen_create_tablet_arg(tenant_id, ls_id, tablet_id, create_tablet_arg)); ASSERT_EQ(OB_SUCCESS, ls_svr->create_ls(arg)); EXPECT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, handle, ObLSGetMod::STORAGE_MOD)); ls = handle.get_ls(); @@ -204,7 +207,11 @@ TEST_F(TestLSService, tablet_test) ::sleep(1); } - ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(*ls->get_tablet_svr(), create_tablet_arg)); + // 1. create a tablet + share::schema::ObTableSchema table_schema; + uint64_t table_id = 12345; + ASSERT_EQ(OB_SUCCESS, build_test_schema(table_schema, table_id)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(handle, tablet_id, table_schema, allocator_)); // 2. test tablet LOG_INFO("TestLSService::tablet_test 2."); @@ -218,8 +225,8 @@ TEST_F(TestLSService, tablet_test) obrpc::ObBatchRemoveTabletArg remove_tablet_arg; remove_tablet_arg.id_ = ls_id; remove_tablet_arg.tablet_ids_.push_back(tablet_id); - obrpc::ObRemoveTabletRes remove_res; - EXPECT_EQ(OB_SUCCESS, ls_svr->remove_tablet(remove_tablet_arg, remove_res)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::remove_tablet(handle, tablet_id)); + EXPECT_EQ(OB_SUCCESS, ls_svr->remove_ls(ls_id, true)); } diff --git a/mittest/mtlenv/storage/test_ls_tablet_info_writer_and_reader.cpp b/mittest/mtlenv/storage/test_ls_tablet_info_writer_and_reader.cpp new file mode 100644 index 000000000..22efd8c84 --- /dev/null +++ b/mittest/mtlenv/storage/test_ls_tablet_info_writer_and_reader.cpp @@ -0,0 +1,228 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include +#include + +#define protected public +#define private public + +#include "storage/schema_utils.h" +#include "storage/ob_storage_schema.h" +#include "storage/blocksstable/ob_sstable_meta.h" +#include "storage/ls/ob_ls.h" +#include "storage/meta_mem/ob_meta_obj_struct.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/tablet/ob_tablet_meta.h" +#include "storage/tablet/ob_tablet_table_store.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "mtlenv/mock_tenant_module_env.h" +#include "storage/test_dml_common.h" +#include "observer/ob_safe_destroy_thread.h" +#include "storage/backup/ob_backup_extern_info_mgr.h" +#include "share/backup/ob_backup_io_adapter.h" + +using namespace oceanbase::common; +using namespace oceanbase::share; +using namespace oceanbase::share::schema; + +namespace oceanbase +{ +namespace storage +{ +class TestLSTabletInfoWR : public ::testing::Test +{ +public: + TestLSTabletInfoWR(); + virtual ~TestLSTabletInfoWR() = default; + + static void SetUpTestCase(); + static void TearDownTestCase(); + + virtual void SetUp() override; + virtual void TearDown() override; + void fill_tablet_meta(); + void inner_init(); + void clean_env(); +public: + static const uint64_t TEST_TENANT_ID = 1; + static const int64_t TEST_LS_ID = 101; + ObArray tablet_metas; + share::ObBackupDest backup_set_dest_; + char test_dir_[OB_MAX_URI_LENGTH]; + char test_dir_uri_[OB_MAX_URI_LENGTH]; + ObArenaAllocator arena_allocator_; +}; + +void TestLSTabletInfoWR::inner_init() +{ + int ret = OB_SUCCESS; + common::ObBackupIoAdapter util; + ret = databuff_printf(test_dir_, sizeof(test_dir_), "%s/test_backup_extern_info_mgr", get_current_dir_name()); + EXPECT_EQ(OB_SUCCESS, ret); + ret = databuff_printf(test_dir_uri_, sizeof(test_dir_uri_), "file://%s", test_dir_); + EXPECT_EQ(OB_SUCCESS, ret); + clean_env(); + ret = backup_set_dest_.set(test_dir_uri_); + EXPECT_EQ(OB_SUCCESS, ret); + ret = util.mkdir(test_dir_uri_, backup_set_dest_.get_storage_info()); + EXPECT_EQ(OB_SUCCESS, ret); +} + +void TestLSTabletInfoWR::clean_env() +{ + system((std::string("rm -rf ") + test_dir_ + std::string("*")).c_str()); +} + +TestLSTabletInfoWR::TestLSTabletInfoWR() +{ +} + +void TestLSTabletInfoWR::SetUpTestCase() +{ + int ret = OB_SUCCESS; + ret = MockTenantModuleEnv::get_instance().init(); + ASSERT_EQ(OB_SUCCESS, ret); + SAFE_DESTROY_INSTANCE.init(); + SAFE_DESTROY_INSTANCE.start(); + ObServerCheckpointSlogHandler::get_instance().is_started_ = true; + + // create ls + ObLSHandle ls_handle; + ret = TestDmlCommon::create_ls(TEST_TENANT_ID, ObLSID(TEST_LS_ID), ls_handle); + ASSERT_EQ(OB_SUCCESS, ret); +} + +void TestLSTabletInfoWR::TearDownTestCase() +{ + int ret = OB_SUCCESS; + ret = MTL(ObLSService*)->remove_ls(ObLSID(TEST_LS_ID), false); + ASSERT_EQ(OB_SUCCESS, ret); + + // tenant need destroy after safe to destroy + SAFE_DESTROY_INSTANCE.stop(); + SAFE_DESTROY_INSTANCE.wait(); + SAFE_DESTROY_INSTANCE.destroy(); + MockTenantModuleEnv::get_instance().destroy(); +} + +void TestLSTabletInfoWR::SetUp() +{ + inner_init(); + fill_tablet_meta(); +} + +void TestLSTabletInfoWR::TearDown() +{ + int ret = OB_SUCCESS; + + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + + ObTabletMapKey key; + key.ls_id_ = TEST_LS_ID; + + key.tablet_id_ = 1002; + ret = t3m->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); + + key.tablet_id_ = 1003; + ret = t3m->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); +} + +void TestLSTabletInfoWR::fill_tablet_meta() +{ + int ret = OB_SUCCESS; + + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ObLSID(TEST_LS_ID), ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletMapKey src_key; + src_key.ls_id_ = TEST_LS_ID; + src_key.tablet_id_ = 1002; + + ObTabletHandle src_handle; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ret = t3m->create_tmp_tablet(WashTabletPriority::WTP_HIGH, src_key, arena_allocator_, ls_handle, src_handle); + ASSERT_EQ(common::OB_SUCCESS, ret); + + share::schema::ObTableSchema table_schema; + TestSchemaUtils::prepare_data_schema(table_schema); + + ObTabletID empty_tablet_id; + ObTabletTableStoreFlag store_flag; + store_flag.set_with_major_sstable(); + SCN scn; + scn.convert_from_ts(ObTimeUtility::current_time()); + ret = src_handle.get_obj()->init(arena_allocator_, src_key.ls_id_, src_key.tablet_id_, src_key.tablet_id_, + scn, 2022, table_schema, + lib::Worker::CompatMode::MYSQL, store_flag, nullptr/*empty sstable*/, ls_handle.get_ls()->get_freezer()); + ASSERT_EQ(common::OB_SUCCESS, ret); + + ObMigrationTabletParam tablet_param; + ret = src_handle.get_obj()->build_migration_tablet_param(tablet_param); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(tablet_param.is_valid()); + + for (int i = 0; i < 3; i++) { + tablet_param.tablet_id_ = ObTabletID(tablet_param.tablet_id_.id() + 1); + tablet_metas.push_back(tablet_param); + } +} + +TEST_F(TestLSTabletInfoWR, testTabletInfoWriterAndReader) +{ + int ret = OB_SUCCESS; + LOG_INFO("test tablet info", K(tablet_metas.count()), K(backup_set_dest_)); + backup::ObExternTabletMetaWriter writer; + backup::ObExternTabletMetaReader reader; + ASSERT_EQ(OB_SUCCESS, writer.init(backup_set_dest_, ObLSID(TEST_LS_ID), 1, 0)); + for (int i = 0; i < tablet_metas.count(); i++) { + blocksstable::ObSelfBufferWriter buffer_writer("TestBuff"); + blocksstable::ObBufferReader buffer_reader; + if (OB_FAIL(buffer_writer.ensure_space(backup::OB_BACKUP_READ_BLOCK_SIZE))) { + LOG_WARN("failed to ensure space"); + } else if (OB_FAIL(buffer_writer.write_serialize(tablet_metas.at(i)))) { + LOG_WARN("failed to writer", K(tablet_metas.at(i))); + } else { + buffer_reader.assign(buffer_writer.data(), buffer_writer.length(), buffer_writer.length()); + ASSERT_EQ(OB_SUCCESS, writer.write_meta_data(buffer_reader, tablet_metas.at(i).tablet_id_)); + } + } + ASSERT_EQ(OB_SUCCESS, writer.close()); + ASSERT_EQ(OB_SUCCESS, reader.init(backup_set_dest_, ObLSID(TEST_LS_ID))); + while (OB_SUCC(ret)) { + storage::ObMigrationTabletParam tablet_meta; + ret = reader.get_next(tablet_meta); + if (ret == OB_ITER_END) { + ret = OB_SUCCESS; + break; + } + ASSERT_EQ(OB_SUCCESS, ret); + } + +} +} // namespace storage +} // namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -f test_ls_tablet_info_writer_and_reader.log*"); + OB_LOGGER.set_file_name("test_ls_tablet_info_writer_and_reader.log", true, false); + OB_LOGGER.set_log_level("INFO"); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/mtlenv/storage/test_ls_tablet_service.cpp b/mittest/mtlenv/storage/test_ls_tablet_service.cpp index 00c96f21f..082a9ec18 100644 --- a/mittest/mtlenv/storage/test_ls_tablet_service.cpp +++ b/mittest/mtlenv/storage/test_ls_tablet_service.cpp @@ -37,6 +37,8 @@ #include "storage/test_dml_common.h" #include "storage/test_tablet_helper.h" #include "observer/ob_safe_destroy_thread.h" +#include "storage/tablet/ob_tablet_persister.h" +#include "unittest/storage/slog/simple_ob_storage_redo_module.h" namespace oceanbase { @@ -62,6 +64,11 @@ public: const ObTabletID &node_tablet_id, ObTabletHandle &tablet_handle_head, ObTabletHandle &tablet_handle_tail); + void construct_sstable( + const ObTabletID &tablet_id, + blocksstable::ObSSTable &ob_sstable, + common::ObArenaAllocator &allocator); + void valid_tablet_num(const int64_t &inner_tablet_count); public: static const int64_t MAX_FILE_SIZE = 256 * 1024 * 1024; @@ -71,6 +78,7 @@ public: const uint64_t tenant_id_; share::ObLSID ls_id_; ObLSTabletService *ls_tablet_service_; + common::ObArenaAllocator allocator_; }; TestLSTabletService::TestLSTabletService() @@ -83,6 +91,7 @@ TestLSTabletService::TestLSTabletService() void TestLSTabletService::SetUpTestCase() { int ret = OB_SUCCESS; + LOG_INFO("TestLSTabletService::SetUpTestCase"); ret = MockTenantModuleEnv::get_instance().init(); ASSERT_EQ(OB_SUCCESS, ret); SAFE_DESTROY_INSTANCE.init(); @@ -100,7 +109,10 @@ void TestLSTabletService::SetUpTestCase() void TestLSTabletService::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); int ret = OB_SUCCESS; + LOG_INFO("TestLSTabletService::SetUp"); + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); ObLSHandle ls_handle; ObLSService *ls_svr = MTL(ObLSService*); @@ -109,11 +121,23 @@ void TestLSTabletService::SetUp() ObLS *ls = ls_handle.get_ls(); ls_tablet_service_ = ls->get_tablet_svr(); + + while (true) { + if (nullptr != MTL(ObTenantMetaMemMgr*)->gc_head_) { + LOG_INFO("wait t3m gc tablet clean"); + usleep(300 * 1000); // wait 300ms + } else { + break; + } + } } void TestLSTabletService::TearDownTestCase() { int ret = OB_SUCCESS; + while (MTL(ObTenantMetaMemMgr*)->full_tablet_creator_.transform_head_.is_valid()) { + MTL(ObTenantMetaMemMgr*)->full_tablet_creator_.persist_tablet(); + } ret = MTL(ObLSService*)->remove_ls(ObLSID(TEST_LS_ID), false); ASSERT_EQ(OB_SUCCESS, ret); @@ -139,47 +163,47 @@ void TestLSTabletService::construct_and_get_tablet_list( share::schema::ObTableSchema schema; TestSchemaUtils::prepare_data_schema(schema); - obrpc::ObCreateTabletInfo create_tablet_info; - create_tablet_info.data_tablet_id_ = tablet_id; - ret = create_tablet_info.tablet_ids_.push_back(tablet_id); - ASSERT_EQ(OB_SUCCESS, ret); - ret = create_tablet_info.table_schema_index_.push_back(0); - ASSERT_EQ(OB_SUCCESS, ret); - create_tablet_info.compat_mode_ = lib::Worker::CompatMode::MYSQL; - share::schema::ObTableSchema node_schema; TestSchemaUtils::prepare_data_schema(node_schema); - obrpc::ObCreateTabletInfo create_node_tablet_info; - create_node_tablet_info.data_tablet_id_ = node_tablet_id; - ret = create_node_tablet_info.tablet_ids_.push_back(node_tablet_id); - ASSERT_EQ(OB_SUCCESS, ret); - ret = create_node_tablet_info.table_schema_index_.push_back(0); - ASSERT_EQ(OB_SUCCESS, ret); - create_node_tablet_info.compat_mode_ = lib::Worker::CompatMode::MYSQL; + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); - obrpc::ObBatchCreateTabletArg arg; - bool is_replay = true; // does not write clog - arg.id_ = ls_id_; - arg.major_frozen_scn_ = share::SCN::min_scn(); - ret = arg.table_schemas_.push_back(schema); - ASSERT_EQ(OB_SUCCESS, ret); - ret = arg.table_schemas_.push_back(node_schema); - ASSERT_EQ(OB_SUCCESS, ret); - ret = arg.tablets_.push_back(create_tablet_info); - ASSERT_EQ(OB_SUCCESS, ret); - ret = arg.tablets_.push_back(create_node_tablet_info); + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator_); ASSERT_EQ(OB_SUCCESS, ret); - ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); + ret = TestTabletHelper::create_tablet(ls_handle, node_tablet_id, node_schema, allocator_); ASSERT_EQ(OB_SUCCESS, ret); + ObTabletHandle tmp_tablet_handle_head; + ObTabletHandle tmp_tablet_handle_tail; // get two tablets and consrtuct linked list - ret = ls_tablet_service_->get_tablet(tablet_id, tablet_handle_head); + ret = ls_tablet_service_->get_tablet(tablet_id, tmp_tablet_handle_head); ASSERT_EQ(OB_SUCCESS, ret); - ret = ls_tablet_service_->get_tablet(node_tablet_id, tablet_handle_tail); + ret = ls_tablet_service_->get_tablet(node_tablet_id, tmp_tablet_handle_tail); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = ObTabletPersister::persist_and_transform_tablet(*tmp_tablet_handle_head.get_obj(), tablet_handle_head); + ASSERT_EQ(OB_SUCCESS, ret); + ret = ObTabletPersister::persist_and_transform_tablet(*tmp_tablet_handle_tail.get_obj(), tablet_handle_tail); ASSERT_EQ(OB_SUCCESS, ret); tablet_handle_head.get_obj()->set_next_tablet_guard(tablet_handle_tail); + + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTabletHandle old_handle; + + ObTabletMapKey head_key(ls_id_, tablet_id); + ret = t3m->get_tablet(WashTabletPriority::WTP_LOW, head_key, old_handle); + ASSERT_EQ(OB_SUCCESS, ret); + ret = t3m->compare_and_swap_tablet(head_key, old_handle, tablet_handle_head); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletMapKey node_key(ls_id_, node_tablet_id); + ret = t3m->get_tablet(WashTabletPriority::WTP_LOW, node_key, old_handle); + ASSERT_EQ(OB_SUCCESS, ret); + ret = t3m->compare_and_swap_tablet(node_key, old_handle, tablet_handle_tail); + ASSERT_EQ(OB_SUCCESS, ret); } TEST_F(TestLSTabletService, test_bucket_cnt) @@ -195,40 +219,53 @@ TEST_F(TestLSTabletService, test_bucket_cnt) ASSERT_EQ(unify_bucket_num, id_set_bkt_cnt); } +void TestLSTabletService::construct_sstable( + const ObTabletID &tablet_id, + blocksstable::ObSSTable &sstable, + common::ObArenaAllocator &allocator) +{ + share::schema::ObTableSchema schema; + TestSchemaUtils::prepare_data_schema(schema); + + ObTabletCreateSSTableParam param; + TestTabletHelper::prepare_sstable_param(tablet_id, schema, param); + + int ret = sstable.init(param, &allocator); + ASSERT_EQ(common::OB_SUCCESS, ret); +} + +void TestLSTabletService::valid_tablet_num(const int64_t &inner_tablet_count) +{ + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + bool all_tablet_cleaned = false; + while (!all_tablet_cleaned) { + t3m->gc_tablets_in_queue(all_tablet_cleaned); + } + ASSERT_EQ(inner_tablet_count, t3m->tablet_buffer_pool_.inner_used_num_); +} + TEST_F(TestLSTabletService, test_create_tablet_without_index) { int ret = OB_SUCCESS; + const int64_t inner_tablet_count = INNER_TABLET_CNT; ObTabletID tablet_id(10000001); share::schema::ObTableSchema schema; TestSchemaUtils::prepare_data_schema(schema); - obrpc::ObCreateTabletInfo create_tablet_info; - create_tablet_info.data_tablet_id_ = tablet_id; - ret = create_tablet_info.tablet_ids_.push_back(tablet_id); - ASSERT_EQ(OB_SUCCESS, ret); - ret = create_tablet_info.table_schema_index_.push_back(0); - ASSERT_EQ(common::OB_SUCCESS, ret); - create_tablet_info.compat_mode_ = lib::Worker::CompatMode::MYSQL; - - obrpc::ObBatchCreateTabletArg arg; - arg.id_ = ls_id_; - arg.major_frozen_scn_ = share::SCN::min_scn(); - ret = arg.table_schemas_.push_back(schema); - ASSERT_EQ(OB_SUCCESS, ret); - ret = arg.tablets_.push_back(create_tablet_info); + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator_); ASSERT_EQ(OB_SUCCESS, ret); - ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); - ASSERT_EQ(OB_SUCCESS, ret); + valid_tablet_num(inner_tablet_count); + ASSERT_EQ(1 + inner_tablet_count, MTL(ObTenantMetaMemMgr*)->tablet_map_.map_.size()); - ASSERT_EQ(1 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_pool_.inner_used_num_); - ASSERT_EQ(1 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_map_.map_.size()); + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator_); + ASSERT_EQ(OB_ENTRY_EXIST, ret); - ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); - ASSERT_EQ(OB_ERR_UNEXPECTED, ret); - - ASSERT_EQ(1 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_pool_.inner_used_num_); - ASSERT_EQ(1 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_map_.map_.size()); + valid_tablet_num(inner_tablet_count); + ASSERT_EQ(1 + inner_tablet_count, MTL(ObTenantMetaMemMgr*)->tablet_map_.map_.size()); ObTabletMapKey key(ls_id_, tablet_id); ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); @@ -244,56 +281,62 @@ TEST_F(TestLSTabletService, test_serialize_tablet) share::schema::ObTableSchema schema; TestSchemaUtils::prepare_data_schema(schema); - obrpc::ObCreateTabletInfo create_tablet_info; - create_tablet_info.data_tablet_id_ = tablet_id; - ret = create_tablet_info.tablet_ids_.push_back(tablet_id); - ASSERT_EQ(OB_SUCCESS, ret); - ret = create_tablet_info.table_schema_index_.push_back(0); - ASSERT_EQ(OB_SUCCESS, ret); - create_tablet_info.compat_mode_ = lib::Worker::CompatMode::MYSQL; - - obrpc::ObBatchCreateTabletArg arg; - bool is_replay = true; // does not write clog - arg.id_ = ls_id_; - arg.major_frozen_scn_ = share::SCN::min_scn(); - ret = arg.table_schemas_.push_back(schema); - ASSERT_EQ(OB_SUCCESS, ret); - ret = arg.tablets_.push_back(create_tablet_info); - ASSERT_EQ(OB_SUCCESS, ret); - - ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator_); ASSERT_EQ(OB_SUCCESS, ret); // test serialize and deserialize tablet ObTabletHandle orig_tablet_handle; ret = ls_tablet_service_->get_tablet(tablet_id, orig_tablet_handle); ASSERT_EQ(OB_SUCCESS, ret); - ObTablet *orig_tablet = orig_tablet_handle.get_obj(); + const ObTablet *orig_tablet = orig_tablet_handle.get_obj(); - ObTabletHandle new_tablet_handle; - const ObTabletMapKey key(ls_id_, tablet_id); - ret = ObTabletCreateDeleteHelper::acquire_tablet(key, new_tablet_handle); + ObTabletHandle tiny_tablet_handle; + ret = ObTabletPersister::persist_and_transform_tablet(*orig_tablet, tiny_tablet_handle); ASSERT_EQ(OB_SUCCESS, ret); - ObTablet *new_tablet = new_tablet_handle.get_obj(); - int64_t tablet_length = orig_tablet->get_serialize_size(); + ObTablet *tiny_tablet = tiny_tablet_handle.get_obj(); + int64_t tablet_length = tiny_tablet->get_serialize_size(); int64_t pos = 0; char *buf = static_cast(ob_malloc(tablet_length, ObNewModIds::TEST)); - ret = orig_tablet->serialize(buf, tablet_length, pos); + const ObMetaDiskAddr &tablet_addr = tiny_tablet->tablet_addr_; + ret = tiny_tablet->serialize(buf, tablet_length, pos); ASSERT_EQ(OB_SUCCESS, ret); - ObIAllocator &allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); + const ObTabletMapKey key(ls_id_, tablet_id); + + ObTabletHandle new_4k_tablet_handle; + ret = ObTabletCreateDeleteHelper::acquire_tablet_from_pool(ObTabletPoolType::TP_NORMAL, key, new_4k_tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + ObTablet *new_4k_tablet = new_4k_tablet_handle.get_obj(); + int64_t de_pos = 0; - ret = new_tablet->deserialize(allocator, buf, tablet_length, de_pos); + ret = new_4k_tablet->deserialize(buf, tablet_length, de_pos); + new_4k_tablet->tablet_addr_ = tablet_addr; ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(tablet_id, new_4k_tablet->tablet_meta_.tablet_id_); + ASSERT_EQ(OB_SUCCESS, new_4k_tablet->inc_macro_ref_cnt()); + + ObTabletHandle new_tmp_tablet_handle; + ret = ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator_, new_tmp_tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + ObTablet *new_tmp_tablet = new_tmp_tablet_handle.get_obj(); + + de_pos = 0; + new_tmp_tablet->tablet_addr_ = tablet_addr; + ret = new_tmp_tablet->deserialize(allocator_, buf, tablet_length, de_pos); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(tablet_id, new_tmp_tablet->tablet_meta_.tablet_id_); + - ASSERT_EQ(tablet_id, new_tablet->tablet_meta_.tablet_id_); ob_free(buf); - ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); ASSERT_EQ(OB_SUCCESS, ret); } +/** TEST_F(TestLSTabletService, test_serialize_linked_list_tablet) { int ret = OB_SUCCESS; @@ -307,19 +350,20 @@ TEST_F(TestLSTabletService, test_serialize_linked_list_tablet) // serialize and deserialize linked list int64_t tablets_length = tablet_head->get_serialize_size(); int64_t se_pos = 0; - char *buf = static_cast(ob_malloc(tablets_length, ObNewModIds::TEST)); + char *buf = static_cast(ob_malloc(tablets_length, "TestBuff")); + const ObMetaDiskAddr &tablet_addr = tablet_head->tablet_addr_; ret = tablet_head->serialize(buf, tablets_length, se_pos); ASSERT_EQ(OB_SUCCESS, ret); ObTabletHandle new_tablet_handle; ObTabletMapKey key(ls_id_, tablet_id); - ret = ObTabletCreateDeleteHelper::acquire_tablet(key, new_tablet_handle); + ret = ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator_, new_tablet_handle); ASSERT_EQ(OB_SUCCESS, ret); ObTablet *new_tablet = new_tablet_handle.get_obj(); - ObIAllocator &allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); int64_t de_pos = 0; - ret = new_tablet->deserialize(allocator, buf, tablets_length, de_pos); + new_tablet->tablet_addr_ = tablet_addr; + ret = new_tablet->deserialize(allocator_, buf, tablets_length, de_pos); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(true, new_tablet->tablet_meta_.has_next_tablet_); ASSERT_EQ(tablet_id, new_tablet->tablet_meta_.tablet_id_); @@ -335,7 +379,7 @@ TEST_F(TestLSTabletService, test_serialize_linked_list_tablet) ASSERT_EQ(OB_SUCCESS, ret); } -TEST_F(TestLSTabletService, test_deserialize_tablet_with_allocator) +TEST_F(TestLSTabletService, test_serialize_linked_list_tablet_deserialize_4k) { int ret = OB_SUCCESS; const ObTabletID tablet_id(1001); @@ -352,35 +396,75 @@ TEST_F(TestLSTabletService, test_deserialize_tablet_with_allocator) ret = tablet_head->serialize(buf, tablets_length, se_pos); ASSERT_EQ(OB_SUCCESS, ret); - common::ObArenaAllocator allocator; ObTabletHandle new_tablet_handle; ObTabletMapKey key(ls_id_, tablet_id); - const ObTabletID test_tablet_id(12345678); - ObTabletMapKey test_key(ls_id_, test_tablet_id); - ret = MTL(ObTenantMetaMemMgr*)->acquire_tablet(WashTabletPriority::WTP_HIGH, test_key, allocator, new_tablet_handle, false); - ASSERT_EQ(OB_NOT_SUPPORTED, ret); - - ret = ObTabletCreateDeleteHelper::acquire_tablet(key, new_tablet_handle); - ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_TRUE(nullptr != new_tablet_handle.get_obj()); - new_tablet_handle.reset(); - - ret = MTL(ObTenantMetaMemMgr*)->acquire_tablet(WashTabletPriority::WTP_HIGH, key, allocator, new_tablet_handle, false); + ret = ObTabletCreateDeleteHelper::acquire_tablet_from_pool(ObTabletPoolType::TP_NORMAL, key, new_tablet_handle); ASSERT_EQ(OB_SUCCESS, ret); ObTablet *new_tablet = new_tablet_handle.get_obj(); int64_t de_pos = 0; - const int64_t used_tablet_cnt = MTL(ObTenantMetaMemMgr*)->tablet_pool_.used_obj_cnt_; - const int64_t used_sstable_cnt = MTL(ObTenantMetaMemMgr*)->sstable_pool_.used_obj_cnt_; - const int64_t used_size = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator().used(); - ret = new_tablet->load_deserialize(allocator, buf, tablets_length, de_pos); + ret = new_tablet->deserialize(buf, tablets_length, de_pos); + new_tablet->tablet_addr_ = tablet_head->tablet_addr_; + new_tablet->next_tablet_guard_.get_obj()->tablet_addr_ = tablet_head->tablet_addr_; ASSERT_EQ(OB_SUCCESS, ret); - ret = new_tablet->deserialize_post_work(); + ASSERT_EQ(true, new_tablet->tablet_meta_.has_next_tablet_); + ASSERT_EQ(tablet_id, new_tablet->tablet_meta_.tablet_id_); + ASSERT_EQ(OB_SUCCESS, new_tablet->inc_macro_ref_cnt()); + + ObTablet *next_tablet = new_tablet->next_tablet_guard_.get_obj(); + next_tablet->tablet_addr_ = tablet_head->tablet_addr_; + ASSERT_EQ(false, next_tablet->tablet_meta_.has_next_tablet_); + ASSERT_EQ(node_tablet_id, next_tablet->tablet_meta_.tablet_id_); + ASSERT_EQ(OB_SUCCESS, next_tablet->inc_macro_ref_cnt()); + + key.tablet_id_ = tablet_id; + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + key.tablet_id_ = node_tablet_id; + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(TestLSTabletService, test_deserialize_linked_tablet_with_allocator) +{ + int ret = OB_SUCCESS; + const ObTabletID tablet_id(1001); + const ObTabletID node_tablet_id(1002); + ObTabletHandle tablet_handle_head; + ObTabletHandle tablet_handle_tail; + construct_and_get_tablet_list(tablet_id, node_tablet_id, tablet_handle_head, tablet_handle_tail); + ObTablet *tablet_head = tablet_handle_head.get_obj(); + + // serialize and deserialize linked list + int64_t tablets_length = tablet_head->get_serialize_size(); + int64_t se_pos = 0; + char *buf = static_cast(ob_malloc(tablets_length, ObNewModIds::TEST)); + const ObMetaDiskAddr &tablet_addr = tablet_head->tablet_addr_; + ret = tablet_head->serialize(buf, tablets_length, se_pos); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(used_tablet_cnt, MTL(ObTenantMetaMemMgr*)->tablet_pool_.used_obj_cnt_); - ASSERT_EQ(used_sstable_cnt, MTL(ObTenantMetaMemMgr*)->sstable_pool_.used_obj_cnt_); - ASSERT_EQ(used_size, MTL(ObTenantMetaMemMgr*)->get_tenant_allocator().used()); + ObTabletHandle new_tablet_handle; + ObTabletMapKey key(ls_id_, tablet_id); + const ObTabletID test_tablet_id(12345678); + ObTabletMapKey test_key(ls_id_, test_tablet_id); + ret = ObTabletCreateDeleteHelper::acquire_tmp_tablet(test_key, allocator_, new_tablet_handle); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret); + + ret = ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator_, new_tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(nullptr != new_tablet_handle.get_obj()); + new_tablet_handle.reset(); + + ret = ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator_, new_tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + ObTablet *new_tablet = new_tablet_handle.get_obj(); + + int64_t de_pos = 0; + const int64_t used_tablet_cnt = MTL(ObTenantMetaMemMgr*)->tablet_buffer_pool_.used_obj_cnt_; + new_tablet->tablet_addr_ = tablet_addr; + ret = new_tablet->deserialize(allocator_, buf, tablets_length, de_pos); + ASSERT_EQ(OB_SUCCESS, ret); + + ASSERT_EQ(used_tablet_cnt, MTL(ObTenantMetaMemMgr*)->tablet_buffer_pool_.used_obj_cnt_); ASSERT_EQ(true, new_tablet->tablet_meta_.has_next_tablet_); ASSERT_EQ(tablet_id, new_tablet->tablet_meta_.tablet_id_); @@ -449,10 +533,12 @@ TEST_F(TestLSTabletService, test_commit_rebuild_tablet) ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); ASSERT_EQ(OB_SUCCESS, ret); } +*/ TEST_F(TestLSTabletService, test_create_tablet_with_index) { int ret = OB_SUCCESS; + const int64_t inner_tablet_count = INNER_TABLET_CNT; ObTabletID data_tablet_id(4001); ObTabletID index_tablet_id(4002); share::schema::ObTableSchema data_schema; @@ -461,40 +547,21 @@ TEST_F(TestLSTabletService, test_create_tablet_with_index) TestSchemaUtils::prepare_data_schema(data_schema); TestSchemaUtils::prepare_index_schema(index_schema); - obrpc::ObCreateTabletInfo create_tablet_info; - create_tablet_info.data_tablet_id_ = data_tablet_id; - ret = create_tablet_info.tablet_ids_.push_back(data_tablet_id); + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ret = TestTabletHelper::create_tablet(ls_handle, data_tablet_id, data_schema, allocator_); ASSERT_EQ(OB_SUCCESS, ret); - ret = create_tablet_info.tablet_ids_.push_back(index_tablet_id); - ASSERT_EQ(OB_SUCCESS, ret); - ret = create_tablet_info.table_schema_index_.push_back(0); - ASSERT_EQ(OB_SUCCESS, ret); - ret = create_tablet_info.table_schema_index_.push_back(1); - ASSERT_EQ(common::OB_SUCCESS, ret); - create_tablet_info.compat_mode_ = lib::Worker::CompatMode::MYSQL; - - obrpc::ObBatchCreateTabletArg arg; - const bool is_replay = true; // does not write clog - arg.id_ = ls_id_; - arg.major_frozen_scn_ = share::SCN::min_scn(); - ret = arg.table_schemas_.push_back(data_schema); - ASSERT_EQ(OB_SUCCESS, ret); - ret = arg.table_schemas_.push_back(index_schema); - ASSERT_EQ(OB_SUCCESS, ret); - ret = arg.tablets_.push_back(create_tablet_info); + ret = TestTabletHelper::create_tablet(ls_handle, index_tablet_id, index_schema, allocator_); ASSERT_EQ(OB_SUCCESS, ret); - ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); - ASSERT_EQ(OB_SUCCESS, ret); - - ASSERT_EQ(2 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_pool_.inner_used_num_); + valid_tablet_num(inner_tablet_count); ASSERT_EQ(2 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_map_.map_.size()); - ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); - //ASSERT_EQ(OB_TABLET_EXIST, ret); - ASSERT_EQ(OB_ERR_UNEXPECTED, ret); + ret = TestTabletHelper::create_tablet(ls_handle, data_tablet_id, data_schema, allocator_); + ASSERT_EQ(OB_ENTRY_EXIST, ret); - ASSERT_EQ(2 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_pool_.inner_used_num_); + valid_tablet_num(inner_tablet_count); ASSERT_EQ(2 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_map_.map_.size()); ObTabletMapKey key; @@ -509,38 +576,24 @@ TEST_F(TestLSTabletService, test_create_tablet_with_index) TEST_F(TestLSTabletService, test_create_index_tablet) { int ret = OB_SUCCESS; + const int64_t inner_tablet_count = INNER_TABLET_CNT; ObTabletID data_tablet_id(5001); share::schema::ObTableSchema data_schema; TestSchemaUtils::prepare_index_schema(data_schema); - obrpc::ObCreateTabletInfo create_tablet_info; - create_tablet_info.data_tablet_id_ = data_tablet_id; - ret = create_tablet_info.tablet_ids_.push_back(data_tablet_id); - ASSERT_EQ(OB_SUCCESS, ret); - ret = create_tablet_info.table_schema_index_.push_back(0); - ASSERT_EQ(common::OB_SUCCESS, ret); - create_tablet_info.compat_mode_ = lib::Worker::CompatMode::MYSQL; - - obrpc::ObBatchCreateTabletArg arg; - const bool is_replay = true; // does not write clog - arg.id_ = ls_id_; - arg.major_frozen_scn_ = share::SCN::min_scn(); - ret = arg.table_schemas_.push_back(data_schema); - ASSERT_EQ(OB_SUCCESS, ret); - ret = arg.tablets_.push_back(create_tablet_info); + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ret = TestTabletHelper::create_tablet(ls_handle, data_tablet_id, data_schema, allocator_); ASSERT_EQ(OB_SUCCESS, ret); - ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); - ASSERT_EQ(OB_SUCCESS, ret); - - ASSERT_EQ(1 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_pool_.inner_used_num_); + valid_tablet_num(inner_tablet_count); ASSERT_EQ(1 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_map_.map_.size()); - ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); - //ASSERT_EQ(OB_TABLET_EXIST, ret); - ASSERT_EQ(OB_ERR_UNEXPECTED, ret); + ret = TestTabletHelper::create_tablet(ls_handle, data_tablet_id, data_schema, allocator_); + ASSERT_EQ(OB_ENTRY_EXIST, ret); - ASSERT_EQ(1 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_pool_.inner_used_num_); + valid_tablet_num(inner_tablet_count); ASSERT_EQ(1 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_map_.map_.size()); ObTabletID index_tablet_id(5002); @@ -548,33 +601,17 @@ TEST_F(TestLSTabletService, test_create_index_tablet) TestSchemaUtils::prepare_index_schema(index_schema); - create_tablet_info.reset(); - create_tablet_info.data_tablet_id_ = data_tablet_id; - ret = create_tablet_info.tablet_ids_.push_back(index_tablet_id); - ASSERT_EQ(OB_SUCCESS, ret); - ret = create_tablet_info.table_schema_index_.push_back(0); - ASSERT_EQ(common::OB_SUCCESS, ret); - create_tablet_info.compat_mode_ = lib::Worker::CompatMode::MYSQL; - - arg.reset(); - arg.id_ = ls_id_; - arg.major_frozen_scn_ = share::SCN::min_scn(); - ret = arg.table_schemas_.push_back(index_schema); - ASSERT_EQ(OB_SUCCESS, ret); - ret = arg.tablets_.push_back(create_tablet_info); + ret = TestTabletHelper::create_tablet(ls_handle, index_tablet_id, index_schema, allocator_); + //ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); ASSERT_EQ(OB_SUCCESS, ret); - ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); - ASSERT_EQ(OB_SUCCESS, ret); - - ASSERT_EQ(2 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_pool_.inner_used_num_); + valid_tablet_num(inner_tablet_count); ASSERT_EQ(2 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_map_.map_.size()); - ret = TestTabletHelper::create_tablet(*ls_tablet_service_, arg); - //ASSERT_EQ(OB_TABLET_EXIST, ret); - ASSERT_EQ(OB_ERR_UNEXPECTED, ret); + ret = TestTabletHelper::create_tablet(ls_handle, index_tablet_id, index_schema, allocator_); + ASSERT_EQ(OB_ENTRY_EXIST, ret); - ASSERT_EQ(2 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_pool_.inner_used_num_); + valid_tablet_num(inner_tablet_count); ASSERT_EQ(2 + INNER_TABLET_CNT, MTL(ObTenantMetaMemMgr*)->tablet_map_.map_.size()); ObTabletMapKey key; @@ -586,6 +623,398 @@ TEST_F(TestLSTabletService, test_create_index_tablet) ASSERT_EQ(OB_SUCCESS, ret); } +TEST_F(TestLSTabletService, test_get_ls_min_end_scn) +{ + // create_tablet_without_index + int ret = OB_SUCCESS; + ObTabletID tablet_id(10000009); + share::schema::ObTableSchema schema; + TestSchemaUtils::prepare_data_schema(schema); + + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator_); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletMapKey key(ls_id_, tablet_id); + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTabletHandle tablet_handle; + ret = t3m->get_tablet(WashTabletPriority::WTP_HIGH, key, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + share::SCN test_scn = share::SCN::min_scn(); + share::SCN expect_scn; + share::SCN orig_scn; + expect_scn.val_ = 1; + + share::SCN min_end_scn_from_latest_tablets = SCN::max_scn(); + share::SCN min_end_scn_from_old_tablets = SCN::max_scn(); + ret = ls_tablet_service_->get_ls_min_end_scn(min_end_scn_from_latest_tablets, min_end_scn_from_old_tablets); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(min_end_scn_from_latest_tablets, expect_scn); + + orig_scn = tablet_handle.get_obj()->tablet_meta_.clog_checkpoint_scn_; + tablet_handle.get_obj()->tablet_meta_.clog_checkpoint_scn_ = test_scn; // modify scn of tablet + + min_end_scn_from_latest_tablets.set_max(); + min_end_scn_from_old_tablets.set_max(); + ret = ls_tablet_service_->get_ls_min_end_scn(min_end_scn_from_latest_tablets, min_end_scn_from_old_tablets); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(min_end_scn_from_latest_tablets, expect_scn); // still get from major sstable + + tablet_handle.get_obj()->tablet_meta_.clog_checkpoint_scn_ = orig_scn; // set orig_scn to del tablet + + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(TestLSTabletService, test_replay_empty_shell) +{ + // create_tablet_without_index + int ret = OB_SUCCESS; + ObTabletID tablet_id(10000009); + share::schema::ObTableSchema schema; + TestSchemaUtils::prepare_data_schema(schema); + + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator_, ObTabletStatus::Status::DELETED); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = ls_tablet_service_->update_tablet_to_empty_shell(tablet_id); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletHandle test_tablet_handle; + ret = ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, test_tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ASSERT_EQ(OB_SUCCESS, ret); + ObTabletMemberWrapper wrapper; + test_tablet_handle.get_obj()->fetch_table_store(wrapper); + ASSERT_EQ(nullptr, wrapper.get_member()->get_major_sstables().get_boundary_table(true)); + + ObTabletMapKey key(ls_id_, tablet_id); + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); + + ObLogCursor replay_start_cursor_; + ObLogCursor replay_finish_cursor_; + SimpleObStorageModule tenant_storage_; + replay_start_cursor_.file_id_ = 1; + replay_start_cursor_.log_id_ = 1; + replay_start_cursor_.offset_ = 0; + blocksstable::ObLogFileSpec log_file_spec_; + log_file_spec_.retry_write_policy_ = "normal"; + log_file_spec_.log_create_policy_ = "normal"; + log_file_spec_.log_write_policy_ = "truncate"; + ObStorageLogReplayer replayer_; + ObStorageLogger *slogger = MTL(ObStorageLogger*); + SimpleObStorageModule redo_module; + ASSERT_EQ(OB_SUCCESS, replayer_.init(slogger->get_dir(), log_file_spec_)); + ret = replayer_.register_redo_module(ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, &redo_module); + ASSERT_EQ(OB_SUCCESS, ret); + ret = replayer_.replay(replay_start_cursor_, replay_finish_cursor_, TestSchemaUtils::TEST_TENANT_ID); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletHandle tablet_handle; + ret = ls_tablet_service_->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ASSERT_EQ(OB_SUCCESS, ret); + ObTablet *empty_shell_tablet = tablet_handle.get_obj(); + ASSERT_EQ(true, empty_shell_tablet->is_empty_shell()); + + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(TestLSTabletService, test_cover_empty_shell) +{ + // create_tablet_without_index + int ret = OB_SUCCESS; + ObTabletID tablet_id(10000010); + share::schema::ObTableSchema schema; + TestSchemaUtils::prepare_data_schema(schema); + + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator_, ObTabletStatus::Status::DELETED); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletHandle old_tablet_handle; + ret = ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, old_tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ASSERT_EQ(OB_SUCCESS, ret); + + ObMigrationTabletParam tablet_meta; + ret = old_tablet_handle.get_obj()->build_migration_tablet_param(tablet_meta); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletCreateDeleteMdsUserData data; + ObTabletStatus status(ObTabletStatus::NORMAL); + data.tablet_status_ = status; + const int64_t data_serialize_size = data.get_serialize_size(); + int64_t pos = 0; + char *buf = static_cast(allocator_.alloc(data_serialize_size)); + ASSERT_EQ(OB_SUCCESS, data.serialize(buf, data_serialize_size, pos)); + tablet_meta.mds_data_.tablet_status_committed_kv_.v_.user_data_.assign_ptr(buf, data_serialize_size); + + ret = ls_tablet_service_->update_tablet_to_empty_shell(tablet_id); + ASSERT_EQ(OB_SUCCESS, ret); + ObTabletHandle test_tablet_handle; + ret = ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, test_tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ASSERT_EQ(OB_SUCCESS, ret); + ObTabletCreateDeleteMdsUserData user_data; + ASSERT_EQ(OB_SUCCESS, test_tablet_handle.get_obj()->get_tablet_status(share::SCN::max_scn(), user_data)); + ASSERT_EQ(ObTabletStatus::DELETED, user_data.tablet_status_); + + ObTabletHandle tablet_handle; + ret = ls_tablet_service_->create_transfer_in_tablet(ls_id_, tablet_meta, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, tablet_handle.get_obj()->get_tablet_status(share::SCN::max_scn(), user_data)); + ASSERT_EQ(ObTabletStatus::NORMAL, user_data.tablet_status_); + + ObTabletMapKey key(ls_id_, tablet_id); + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(TestLSTabletService, test_migrate_empty_shell) +{ + // create_tablet_without_index + int ret = OB_SUCCESS; + ObTabletID tablet_id(10000011); + share::schema::ObTableSchema schema; + TestSchemaUtils::prepare_data_schema(schema); + common::ObArenaAllocator allocator; + + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator, ObTabletStatus::Status::DELETED); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = ls_tablet_service_->update_tablet_to_empty_shell(tablet_id); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletHandle old_tablet_handle; + ret = ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, old_tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ASSERT_EQ(OB_SUCCESS, ret); + + ObMigrationTabletParam tablet_meta; + tablet_meta.reset(); + ret = old_tablet_handle.get_obj()->build_migration_tablet_param(tablet_meta); + ASSERT_EQ(OB_SUCCESS, ret); + + char buf[4096] = {0}; + int64_t pos = 0; + ASSERT_EQ(OB_SUCCESS, tablet_meta.serialize(buf, 4096, pos)); + ASSERT_EQ(pos, tablet_meta.get_serialize_size()); + + ObTabletMapKey key(ls_id_, tablet_id); + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); + + ObMigrationTabletParam new_tablet_meta; + pos = 0; + ASSERT_EQ(OB_SUCCESS, new_tablet_meta.deserialize(buf, 4096, pos)); + LOG_INFO("test_migrate_empty_shell", K(pos), "size", tablet_meta.get_serialize_size()); + ASSERT_EQ(pos, tablet_meta.get_serialize_size()); + + ret = ls_tablet_service_->create_or_update_migration_tablet(new_tablet_meta, true); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletHandle tablet_handle; + ret = ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *empty_shell_tablet = tablet_handle.get_obj(); + ASSERT_EQ(true, empty_shell_tablet->is_empty_shell()); + + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(TestLSTabletService, test_serialize_sstable_full_and_shell) +{ + ObTabletID tablet_id(99999); + blocksstable::ObSSTable sstable; + + construct_sstable(tablet_id, sstable, allocator_); + + const int64_t size = sstable.get_serialize_size(); + char *full_buf = static_cast(allocator_.alloc(size)); + int64_t pos = 0; + int ret = sstable.serialize(full_buf, size, pos); + ASSERT_EQ(common::OB_SUCCESS, ret); + + ObMetaDiskAddr addr; + MacroBlockId macro_id; + macro_id.set_block_index(1001); + macro_id.set_write_seq(111); + addr.set_block_addr(macro_id, 0, 4096); + ret = sstable.set_addr(addr); + ASSERT_EQ(common::OB_SUCCESS, ret); + + const int64_t shell_size = sstable.get_serialize_size(); + char *shell_buf = static_cast(allocator_.alloc(size)); + pos = 0; + ret = sstable.serialize(shell_buf, shell_size, pos); + ASSERT_EQ(common::OB_SUCCESS, ret); + + pos = 0; + ret = sstable.deserialize(allocator_, shell_buf, shell_size, pos); + ASSERT_EQ(common::OB_SUCCESS, ret); + pos = 0; + ret = sstable.deserialize(allocator_, full_buf, size, pos); + ASSERT_EQ(common::OB_SUCCESS, ret); +} + +TEST_F(TestLSTabletService, test_migrate_param) +{ + // create_tablet_without_index + int ret = OB_SUCCESS; + ObTabletID tablet_id(10000011); + share::schema::ObTableSchema schema; + TestSchemaUtils::prepare_data_schema(schema); + common::ObArenaAllocator allocator; + + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator, ObTabletStatus::Status::DELETED); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletHandle old_tablet_handle; + ret = ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, old_tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ASSERT_EQ(OB_SUCCESS, ret); + + ObMigrationTabletParam tablet_meta; + tablet_meta.reset(); + ret = old_tablet_handle.get_obj()->build_migration_tablet_param(tablet_meta); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t serialize_size = tablet_meta.get_serialize_size(); + char *buf = static_cast(allocator.alloc(serialize_size)); + int64_t pos = 0; + ASSERT_NE(nullptr, buf); + ASSERT_TRUE(tablet_meta.is_valid()); + ASSERT_FALSE(tablet_meta.is_empty_shell()); + ASSERT_EQ(OB_SUCCESS, tablet_meta.serialize(buf, serialize_size, pos)); + pos = 0; + ObMigrationTabletParam de_tablet_meta; + ASSERT_EQ(OB_SUCCESS, de_tablet_meta.deserialize(buf, serialize_size, pos)); + ASSERT_FALSE(de_tablet_meta.is_empty_shell()); + ASSERT_TRUE(de_tablet_meta.storage_schema_.is_valid()); + ASSERT_TRUE(de_tablet_meta.is_valid()); + ASSERT_FALSE(de_tablet_meta.is_empty_shell()); + pos = 0; + ASSERT_EQ(OB_SUCCESS, de_tablet_meta.serialize(buf, serialize_size, pos)); + + ObMigrationTabletParam other_tablet_meta; + ASSERT_EQ(OB_SUCCESS, other_tablet_meta.assign(de_tablet_meta)); + /* + ASSERT_NE(OB_SUCCESS, tablet_meta.build_deleted_tablet_info(ls_id_, tablet_id)); + tablet_meta.reset(); + ASSERT_EQ(OB_SUCCESS, tablet_meta.build_deleted_tablet_info(ls_id_, tablet_id)); + */ + + ObTabletMapKey key(ls_id_, tablet_id); + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(TestLSTabletService, test_migrate_param_empty_shell) +{ + // create_tablet_without_index + int ret = OB_SUCCESS; + ObTabletID tablet_id(10000011); + share::schema::ObTableSchema schema; + TestSchemaUtils::prepare_data_schema(schema); + common::ObArenaAllocator allocator; + + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator, ObTabletStatus::Status::DELETED); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = ls_tablet_service_->update_tablet_to_empty_shell(tablet_id); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTabletHandle old_tablet_handle; + ret = ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, old_tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ASSERT_EQ(OB_SUCCESS, ret); + + ObMigrationTabletParam tablet_meta; + tablet_meta.reset(); + ret = old_tablet_handle.get_obj()->build_migration_tablet_param(tablet_meta); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t serialize_size = tablet_meta.get_serialize_size(); + char *buf = static_cast(allocator.alloc(serialize_size)); + int64_t pos = 0; + ASSERT_NE(nullptr, buf); + ASSERT_TRUE(tablet_meta.is_valid()); + ASSERT_TRUE(tablet_meta.is_empty_shell()); + ASSERT_EQ(OB_SUCCESS, tablet_meta.serialize(buf, serialize_size, pos)); + pos = 0; + ObMigrationTabletParam de_tablet_meta; + ASSERT_EQ(OB_SUCCESS, de_tablet_meta.deserialize(buf, serialize_size, pos)); + ASSERT_TRUE(de_tablet_meta.is_empty_shell()); + ASSERT_FALSE(de_tablet_meta.storage_schema_.is_valid()); + ASSERT_TRUE(de_tablet_meta.is_valid()); + ASSERT_TRUE(de_tablet_meta.is_empty_shell()); + pos = 0; + ASSERT_EQ(OB_SUCCESS, de_tablet_meta.serialize(buf, serialize_size, pos)); + + ObMigrationTabletParam other_tablet_meta; + ASSERT_EQ(OB_SUCCESS, other_tablet_meta.assign(de_tablet_meta)); + /* + ObMigrationTabletParam other_tablet_meta; + ASSERT_EQ(OB_SUCCESS, tablet_meta.build_deleted_tablet_info(ls_id_, tablet_id)); + */ + + ObTabletMapKey key(ls_id_, tablet_id); + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(TestLSTabletService, test_update_empty_shell) +{ + // create_tablet_without_index + int ret = OB_SUCCESS; + ObTabletID tablet_id(10000009); + share::schema::ObTableSchema schema; + TestSchemaUtils::prepare_data_schema(schema); + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator_, ObTabletStatus::Status::DELETED); + ASSERT_EQ(OB_SUCCESS, ret); + ret = ls_tablet_service_->update_tablet_to_empty_shell(tablet_id); + ASSERT_EQ(OB_SUCCESS, ret); + ObTabletMapKey key(ls_id_, tablet_id); + ObTabletHandle tablet_handle; + ret = ls_tablet_service_->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ASSERT_EQ(OB_SUCCESS, ret); + ObTablet *empty_shell_tablet = tablet_handle.get_obj(); + ASSERT_TRUE(empty_shell_tablet->is_empty_shell()); + + ret = MTL(ObTenantMetaMemMgr*)->del_tablet(key); + ASSERT_EQ(OB_SUCCESS, ret); +} + } // end storage } // end oceanbase diff --git a/mittest/mtlenv/storage/test_macro_ref_cnt.cpp b/mittest/mtlenv/storage/test_macro_ref_cnt.cpp new file mode 100644 index 000000000..2af6b64ae --- /dev/null +++ b/mittest/mtlenv/storage/test_macro_ref_cnt.cpp @@ -0,0 +1,323 @@ +/** + * Copyright (c) 2021 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 +#include + +#define USING_LOG_PREFIX STORAGE +#include + +#define protected public +#define private public + +#include "storage/ls/ob_ls.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/tablet/ob_tablet_persister.h" +#include "mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h" +#include "storage/blocksstable/ob_block_manager.h" +#include "storage/schema_utils.h" +#include "share/ob_rpc_struct.h" + +namespace oceanbase +{ +namespace storage +{ +using namespace common; +using namespace blocksstable; +using namespace storage; + +class TestTabletRefCnt : public TestIndexBlockDataPrepare +{ +public: + TestTabletRefCnt(); + ~TestTabletRefCnt(); +}; + +TestTabletRefCnt::TestTabletRefCnt() + : TestIndexBlockDataPrepare( + "Test Tablet Ref Cnt", + MINI_MERGE, + OB_DEFAULT_MACRO_BLOCK_SIZE, + 10000, + 65536) +{ +} + +TestTabletRefCnt::~TestTabletRefCnt() +{ +} + +void convert_ctx_to_map( + const common::ObSEArray &tablet_meta_write_ctxs, + const common::ObSEArray &sstable_meta_write_ctxs, + std::unordered_map &ref_cnts) +{ + MacroBlockId macro_id; + int64_t offset; + int64_t size; + ObBlockManager::BlockInfo block_info; + + for (int64_t i = 0; i < tablet_meta_write_ctxs.count(); i++) { + ASSERT_EQ(OB_SUCCESS, tablet_meta_write_ctxs[i].addr_.get_block_addr(macro_id, offset, size)); + if (ref_cnts.count(macro_id.block_index_) == 0) { + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, macro_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info)); + } + ref_cnts[macro_id.block_index_] = block_info.ref_cnt_; + } + } + + for (int64_t i = 0; i < tablet_meta_write_ctxs.count(); i++) { + ASSERT_EQ(OB_SUCCESS, tablet_meta_write_ctxs[i].addr_.get_block_addr(macro_id, offset, size)); + ref_cnts[macro_id.block_index_]++; + } + + for (int64_t i = 0; i < sstable_meta_write_ctxs.count(); i++) { + ASSERT_EQ(OB_SUCCESS, sstable_meta_write_ctxs[i].addr_.get_block_addr(macro_id, offset, size)); + ref_cnts[macro_id.block_index_]++; + } +} + +TEST_F(TestTabletRefCnt, test_persist_tablet) +{ + ObTabletID tablet_id(TestIndexBlockDataPrepare::tablet_id_); + ObLSID ls_id(ls_id_); + ObLSHandle ls_handle; + ObTabletHandle tablet_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); + ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); + + common::ObArenaAllocator allocator; + common::ObSEArray tablet_meta_write_ctxs; + common::ObSEArray sstable_meta_write_ctxs; + ObTabletHandle new_tablet_handle; + std::unordered_map ref_cnts; + ObBlockManager::BlockInfo block_info; + + MacroBlockId macro_id; + int64_t offset; + int64_t size; + ObMacroBlockHandle macro_handle; + + // persist 4k tablet + ASSERT_EQ(OB_SUCCESS, ObTabletPersister::recursively_persist( + *(tablet_handle.get_obj()), allocator, tablet_meta_write_ctxs, sstable_meta_write_ctxs, new_tablet_handle)); + convert_ctx_to_map(tablet_meta_write_ctxs, sstable_meta_write_ctxs, ref_cnts); + ASSERT_EQ(OB_SUCCESS, ObTabletPersister::persist_4k_tablet(allocator, new_tablet_handle)); + ASSERT_EQ(OB_SUCCESS, new_tablet_handle.get_obj()->tablet_addr_.get_block_addr(macro_id, offset, size)); + ref_cnts[macro_id.block_index_]++; // tablet_meta_write_ctxs doesn't contain tablet_addr + + // check ref cnt + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, macro_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info)); + } + ASSERT_EQ(block_info.ref_cnt_, ref_cnts[macro_id.block_index_]); + for (int64_t i = 0; i < tablet_meta_write_ctxs.count(); i++) { + ASSERT_EQ(OB_SUCCESS, tablet_meta_write_ctxs[i].addr_.get_block_addr(macro_id, offset, size)); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, macro_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info)); + } + ASSERT_EQ(block_info.ref_cnt_, ref_cnts[macro_id.block_index_]); + } + + // transform memory + ObTabletHandle tmp_tablet_handle; + ObTabletMapKey key(ls_id, tablet_id); + ASSERT_EQ(OB_SUCCESS, ObTabletCreateDeleteHelper::acquire_tablet_from_pool( + ObTabletPoolType::TP_LARGE, key, tmp_tablet_handle)); + ASSERT_EQ(OB_SUCCESS, ObTabletPersister::transform_tablet_memory_footprint( + *(new_tablet_handle.get_obj()), (char *)(tmp_tablet_handle.get_obj()), tmp_tablet_handle.get_buf_len())); + ASSERT_EQ(true, tmp_tablet_handle.get_obj()->hold_ref_cnt_); + tmp_tablet_handle.get_obj()->hold_ref_cnt_ = false; +} + +TEST_F(TestTabletRefCnt, test_meta_ref_cnt) +{ + int ret = OB_SUCCESS; + ObTabletID tablet_id(TestIndexBlockDataPrepare::tablet_id_); + ObLSID ls_id(ls_id_); + ObLSHandle ls_handle; + ObTabletHandle tablet_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); + ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); + + int64_t offset = 0; + int64_t size = 0; + ObBlockManager::BlockInfo block_info; + MacroBlockId table_store_id; + ObMacroBlockHandle macro_handle; + int64_t ref_cnt = 0; + + ObTablet *tablet = tablet_handle.get_obj(); + ObTabletHandle new_tablet_handle; + + // persist 4k tablet + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantCheckpointSlogHandler*)->get_shared_block_reader_writer().switch_block(macro_handle)); + ASSERT_EQ(OB_SUCCESS, ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle)); + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantCheckpointSlogHandler*)->get_shared_block_reader_writer().switch_block(macro_handle)); + ObTablet *new_tablet = new_tablet_handle.get_obj(); + ASSERT_EQ(OB_SUCCESS, new_tablet->table_store_addr_.addr_.get_block_addr(table_store_id, offset, size)); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, table_store_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(table_store_id, block_info)); + } + ref_cnt = block_info.ref_cnt_; + + // increase macro ref cnt + ASSERT_EQ(OB_SUCCESS, new_tablet->inc_macro_ref_cnt()); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, table_store_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(table_store_id, block_info)); + } + ASSERT_EQ(ref_cnt * 2, block_info.ref_cnt_); + + // decrease macro ref cnt + new_tablet->dec_macro_ref_cnt(); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, table_store_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(table_store_id, block_info)); + } + ASSERT_EQ(ref_cnt, block_info.ref_cnt_); + + // deserialize tablet + ObTenantCheckpointSlogHandler *ckpt_handler = MTL(ObTenantCheckpointSlogHandler*); + ObTabletHandle tmp_tablet_handle; + ObTabletMapKey key(ls_id, tablet_id); + char *buf = nullptr; + int64_t buf_len = 0; + int64_t pos = 0; + ObArenaAllocator allocator; + ASSERT_EQ(OB_SUCCESS, ckpt_handler->read_from_disk(new_tablet->tablet_addr_, allocator, buf, buf_len)); + ASSERT_EQ(OB_SUCCESS, ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator, tmp_tablet_handle)); + tmp_tablet_handle.get_obj()->tablet_addr_ = new_tablet->tablet_addr_; + ASSERT_EQ(OB_SUCCESS, tmp_tablet_handle.get_obj()->deserialize(allocator, buf, buf_len, pos)); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, table_store_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(table_store_id, block_info)); + } + ASSERT_EQ(ref_cnt * 2, block_info.ref_cnt_); +} + +TEST_F(TestTabletRefCnt, test_data_ref_cnt) +{ + ObBlockManager::BlockInfo block_info; + MacroBlockId macro_id; + int64_t ref_cnt = 0; + common::ObArenaAllocator tmp_allocator("CacheSST"); + ObSafeArenaAllocator safe_allocator(tmp_allocator); + ObSSTableMetaHandle meta_handle; + ObMacroIdIterator iterator; + ASSERT_EQ(OB_SUCCESS, sstable_.get_meta(meta_handle, &safe_allocator)); + ASSERT_EQ(OB_SUCCESS, meta_handle.get_sstable_meta().get_macro_info().get_data_block_iter(iterator)); + ASSERT_EQ(OB_SUCCESS, iterator.get_next_macro_id(macro_id)); + + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, macro_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info)); + } + ref_cnt = block_info.ref_cnt_; + + // increase macro ref cnt + bool inc_success; + ASSERT_EQ(OB_SUCCESS, sstable_.inc_macro_ref(inc_success)); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, macro_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info)); + } + ASSERT_EQ(ref_cnt + 1, block_info.ref_cnt_); + + // decrease macro ref cnt + sstable_.dec_macro_ref(); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, macro_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info)); + } + ASSERT_EQ(ref_cnt, block_info.ref_cnt_); +} + +TEST_F(TestTabletRefCnt, test_empty_shell_macro_ref_cnt) +{ + int ret = OB_SUCCESS; + ObLSID ls_id(ls_id_); + ObTabletID tablet_id(10000009); + share::schema::ObTableSchema schema; + TestSchemaUtils::prepare_data_schema(schema); + ObTablet *tablet = nullptr; + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); + ObLSTabletService *ls_tablet_svr = ls_handle.get_ls()->get_tablet_svr(); + + // create and get empty shell + ret = TestTabletHelper::create_tablet(ls_handle, tablet_id, schema, allocator_, ObTabletStatus::Status::DELETED); + ASSERT_EQ(OB_SUCCESS, ret); + ret = ls_tablet_svr->update_tablet_to_empty_shell(tablet_id); + ASSERT_EQ(OB_SUCCESS, ret); + ObTabletMapKey key(ls_id, tablet_id); + ObTabletHandle tablet_handle; + ret = ls_tablet_svr->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK); + tablet = tablet_handle.get_obj(); + + // check increasing macro ref cnt for empty shell tablet with file addr + ASSERT_EQ(false, tablet->hold_ref_cnt_); + ASSERT_EQ(OB_SUCCESS, tablet->inc_macro_ref_cnt()); + ASSERT_EQ(true, tablet->hold_ref_cnt_); + + // check increasing macro ref cnt for empty shell tablet with file addr + MacroBlockId macro_id; + int64_t offset; + int64_t size; + ObBlockManager::BlockInfo block_info; + int64_t ref_cnt = 0; + ObTabletHandle new_tablet_handle; + ASSERT_EQ(OB_SUCCESS, ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle)); + ObTablet *new_tablet = new_tablet_handle.get_obj(); + ASSERT_EQ(OB_SUCCESS, new_tablet->tablet_addr_.get_block_addr(macro_id, offset, size)); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, macro_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info)); + } + ref_cnt = block_info.ref_cnt_; + + ASSERT_EQ(OB_SUCCESS, new_tablet->inc_macro_ref_cnt()); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, macro_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info)); + } + ASSERT_EQ(ref_cnt + 1, block_info.ref_cnt_); + + new_tablet->dec_macro_ref_cnt(); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, macro_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info)); + } + ASSERT_EQ(ref_cnt, block_info.ref_cnt_); +} + +} // storage +} // oceanbase + +int main(int argc, char **argv) +{ + system("rm -f test_tablet_ref_cnt.log*"); + OB_LOGGER.set_file_name("test_tablet_ref_cnt.log", true, true); + oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); + oceanbase::common::ObClusterVersion::get_instance().init(CLUSTER_VERSION_4_1_0_0); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/mittest/mtlenv/storage/test_medium_info_reader.cpp b/mittest/mtlenv/storage/test_medium_info_reader.cpp new file mode 100644 index 000000000..e9318f6fd --- /dev/null +++ b/mittest/mtlenv/storage/test_medium_info_reader.cpp @@ -0,0 +1,718 @@ +/** + * Copyright (c) 2021 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 + +#define private public +#define protected public + +#include "lib/oblog/ob_log.h" +#include "lib/allocator/page_arena.h" +#include "share/ob_ls_id.h" +#include "common/ob_tablet_id.h" +#include "mtlenv/mock_tenant_module_env.h" +#include "mtlenv/storage/medium_info_helper.h" +#include "share/rc/ob_tenant_base.h" +#include "unittest/storage/test_tablet_helper.h" +#include "unittest/storage/test_dml_common.h" +#include "unittest/storage/init_basic_struct.h" +#include "unittest/storage/multi_data_source/common_define.h" +#include "unittest/storage/schema_utils.h" +#include "storage/tablet/ob_tablet_medium_info_reader.h" +#include "storage/tablet/ob_tablet_persister.h" +#include "storage/multi_data_source/mds_table_handler.h" +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#include "observer/ob_safe_destroy_thread.h" + +using namespace oceanbase::common; +using namespace oceanbase::share; +using namespace oceanbase::unittest; + +#define USING_LOG_PREFIX STORAGE + +#define MOCK_INSERT_MDS_TABLE(id) \ + { \ + mds::MdsCtx ctx##id(mds::MdsWriter(transaction::ObTransID(id))); \ + compaction::ObMediumCompactionInfoKey key##id(id); \ + compaction::ObMediumCompactionInfo info##id; \ + ret = MediumInfoHelper::build_medium_compaction_info(allocator_, info##id, id); \ + ASSERT_EQ(OB_SUCCESS, ret); \ + \ + ret = mds_table_.set(key##id, info##id, ctx##id); \ + ASSERT_EQ(OB_SUCCESS, ret); \ + \ + ctx##id.on_redo(mock_scn(id)); \ + ctx##id.before_prepare(); \ + ctx##id.on_prepare(mock_scn(id)); \ + ctx##id.on_commit(mock_scn(id), mock_scn(id)); \ + } + +#define MOCK_INSERT_TABLET(id) \ + { \ + compaction::ObMediumCompactionInfoKey key##id(id); \ + compaction::ObMediumCompactionInfo info##id; \ + MediumInfoHelper::build_medium_compaction_info(allocator_, info##id, id); \ + mds::MdsDumpKey dump_key##id; \ + ret = convert(key##id, dump_key##id); \ + ASSERT_EQ(OB_SUCCESS, ret); \ + mds::MdsDumpNode dump_node##id; \ + ret = convert(info##id, dump_node##id); \ + ASSERT_EQ(OB_SUCCESS, ret); \ + \ + ret = medium_info_list.append(dump_key##id, dump_node##id); \ + ASSERT_EQ(OB_SUCCESS, ret); \ + } + + +namespace oceanbase +{ +namespace storage +{ +class TestMediumInfoReader : public ::testing::Test +{ +public: + TestMediumInfoReader(); + virtual ~TestMediumInfoReader() = default; +public: + virtual void SetUp() override; + virtual void TearDown() override; + static void SetUpTestCase(); + static void TearDownTestCase(); +public: + static int create_ls(const uint64_t tenant_id, const share::ObLSID &ls_id, ObLSHandle &ls_handle); + static int remove_ls(const share::ObLSID &ls_id); + int create_tablet(const common::ObTabletID &tablet_id, ObTabletHandle &tablet_handle); +public: + int convert(const compaction::ObMediumCompactionInfoKey &key, mds::MdsDumpKey &dump_key); + int convert(const compaction::ObMediumCompactionInfo &info, mds::MdsDumpNode &dump_node); +public: + static constexpr uint64_t TENANT_ID = 1001; + static const share::ObLSID LS_ID; + + mds::MdsTableHandle mds_table_; + common::ObArenaAllocator allocator_; // for medium info +}; + +const share::ObLSID TestMediumInfoReader::LS_ID(1001); + +TestMediumInfoReader::TestMediumInfoReader() + : mds_table_(), + allocator_() +{ +} + +void TestMediumInfoReader::SetUp() +{ +} + +void TestMediumInfoReader::TearDown() +{ +} + +void TestMediumInfoReader::SetUpTestCase() +{ + int ret = OB_SUCCESS; + ret = MockTenantModuleEnv::get_instance().init(); + ASSERT_EQ(OB_SUCCESS, ret); + + SAFE_DESTROY_INSTANCE.init(); + SAFE_DESTROY_INSTANCE.start(); + ObServerCheckpointSlogHandler::get_instance().is_started_ = true; + + // create ls + ObLSHandle ls_handle; + ret = create_ls(TENANT_ID, LS_ID, ls_handle); + ASSERT_EQ(OB_SUCCESS, ret); +} + +void TestMediumInfoReader::TearDownTestCase() +{ + int ret = OB_SUCCESS; + + // remove ls + ret = remove_ls(LS_ID); + ASSERT_EQ(OB_SUCCESS, ret); + + SAFE_DESTROY_INSTANCE.stop(); + SAFE_DESTROY_INSTANCE.wait(); + SAFE_DESTROY_INSTANCE.destroy(); + + MockTenantModuleEnv::get_instance().destroy(); +} + +int TestMediumInfoReader::create_ls(const uint64_t tenant_id, const share::ObLSID &ls_id, ObLSHandle &ls_handle) +{ + int ret = OB_SUCCESS; + ret = TestDmlCommon::create_ls(tenant_id, ls_id, ls_handle); + return ret; +} + +int TestMediumInfoReader::remove_ls(const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ret = MTL(ObLSService*)->remove_ls(ls_id, false); + return ret; +} + +int TestMediumInfoReader::create_tablet(const common::ObTabletID &tablet_id, ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + const uint64_t table_id = 1234567; + share::schema::ObTableSchema table_schema; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + mds_table_.reset(); + + if (OB_FAIL(MTL(ObLSService*)->get_ls(LS_ID, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), KP(ls)); + } else if (OB_FAIL(build_test_schema(table_schema, table_id))) { + LOG_WARN("failed to build table schema"); + } else if (OB_FAIL(TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema, allocator_))) { + LOG_WARN("failed to create tablet", K(ret)); + } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret)); + } else if (OB_FAIL(tablet_handle.get_obj()->inner_get_mds_table(mds_table_, true/*not_exist_create*/))) { + LOG_WARN("failed to get mds table", K(ret)); + } + + return ret; +} + +int TestMediumInfoReader::convert(const compaction::ObMediumCompactionInfoKey &key, mds::MdsDumpKey &dump_key) +{ + int ret = OB_SUCCESS; + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + + dump_key.mds_table_id_ = table_id; + dump_key.mds_unit_id_ = unit_id; + dump_key.crc_check_number_ = 0; + dump_key.allocator_ = &allocator_; + + const int64_t length = key.get_serialize_size(); + if (0 == length) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("key length should not be 0", K(ret), K(length)); + } else { + char *buffer = static_cast(allocator_.alloc(length)); + int64_t pos = 0; + if (OB_ISNULL(buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret), K(length)); + } else if (OB_FAIL(key.serialize(buffer, length, pos))) { + LOG_WARN("failed to serialize", K(ret)); + } else { + dump_key.key_.assign(buffer, length); + } + + if (OB_FAIL(ret)) { + if (nullptr != buffer) { + allocator_.free(buffer); + } + } + } + + return ret; +} + +int TestMediumInfoReader::convert(const compaction::ObMediumCompactionInfo &info, mds::MdsDumpNode &dump_node) +{ + int ret = OB_SUCCESS; + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + + dump_node.mds_table_id_ = table_id; + dump_node.mds_unit_id_ = unit_id; + dump_node.crc_check_number_ = 0; + dump_node.status_.union_.field_.node_type_ = mds::MdsNodeType::SET; + dump_node.status_.union_.field_.writer_type_ = mds::WriterType::TRANSACTION; + dump_node.status_.union_.field_.state_ = mds::TwoPhaseCommitState::ON_COMMIT; + dump_node.allocator_ = &allocator_; + dump_node.writer_id_ = 1; + dump_node.seq_no_ = 1; + dump_node.redo_scn_ = share::SCN::max_scn(); + dump_node.end_scn_ = share::SCN::max_scn(); + dump_node.trans_version_ = share::SCN::max_scn(); + + const int64_t length = info.get_serialize_size(); + if (0 == length) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("info length should not be 0", K(ret), K(length)); + } else { + char *buffer = static_cast(allocator_.alloc(length)); + int64_t pos = 0; + if (OB_ISNULL(buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret), K(length)); + } else if (OB_FAIL(info.serialize(buffer, length, pos))) { + LOG_WARN("failed to serialize", K(ret)); + } else { + dump_node.user_data_.assign(buffer, length); + } + + if (OB_FAIL(ret)) { + if (nullptr != buffer) { + allocator_.free(buffer); + } + } + } + + return ret; +} + +TEST_F(TestMediumInfoReader, pure_mds_table) +{ + int ret = OB_SUCCESS; + + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + ObTabletHandle tablet_handle; + ret = create_tablet(tablet_id, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + // insert data into mds table + MOCK_INSERT_MDS_TABLE(1); + MOCK_INSERT_MDS_TABLE(2); + + // iterate + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ret = reader.init(allocator); + ASSERT_EQ(OB_SUCCESS, ret); + + compaction::ObMediumCompactionInfoKey key; + compaction::ObMediumCompactionInfo info; + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(1, key.medium_snapshot_); + ASSERT_EQ(1, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(2, key.medium_snapshot_); + ASSERT_EQ(2, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_ITER_END, ret); + reader.reset(); + } + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ASSERT_EQ(OB_SUCCESS, reader.init(allocator)); + int64_t medium_snapshot = 0; + ret = reader.get_max_medium_snapshot(medium_snapshot); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(medium_snapshot, 2); + } + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ASSERT_EQ(OB_SUCCESS, reader.init(allocator)); + int64_t medium_snapshot = 0; + ret = reader.get_min_medium_snapshot(medium_snapshot); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(medium_snapshot, 1); + } +} + +TEST_F(TestMediumInfoReader, pure_dump_data) +{ + int ret = OB_SUCCESS; + + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + ObTabletHandle tablet_handle; + ObTabletHandle new_tablet_handle; + ret = create_tablet(tablet_id, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + ObTabletPointer *tablet_ptr = static_cast(tablet->get_pointer_handle().get_resource_ptr()); + ret = tablet_ptr->try_gc_mds_table(); + ASSERT_EQ(OB_SUCCESS, ret); + + // insert data into tablet + { + ObTabletDumpedMediumInfo &medium_info_list = *tablet->mds_data_.medium_info_list_.ptr_; + + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + + MOCK_INSERT_TABLET(1); + MOCK_INSERT_TABLET(2); + + // persist + ret = ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + tablet = new_tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + } + + // iterate + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ret = reader.init(allocator); + ASSERT_EQ(OB_SUCCESS, ret); + + compaction::ObMediumCompactionInfoKey key; + compaction::ObMediumCompactionInfo info; + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(1, key.medium_snapshot_); + ASSERT_EQ(1, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(2, key.medium_snapshot_); + ASSERT_EQ(2, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_ITER_END, ret); + } +} + +TEST_F(TestMediumInfoReader, mds_table_dump_data_overlap) +{ + int ret = OB_SUCCESS; + + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + ObTabletHandle tablet_handle; + ObTabletHandle new_tablet_handle; + ret = create_tablet(tablet_id, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + // insert data into mds table + MOCK_INSERT_MDS_TABLE(2); + MOCK_INSERT_MDS_TABLE(3); + + // insert data into mds data + { + ObTabletDumpedMediumInfo &medium_info_list = *tablet->mds_data_.medium_info_list_.ptr_; + + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + + MOCK_INSERT_TABLET(1); + MOCK_INSERT_TABLET(2); + + // persist + ret = ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + tablet = new_tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + } + + // iterate + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ret = reader.init(allocator); + ASSERT_EQ(OB_SUCCESS, ret); + + compaction::ObMediumCompactionInfoKey key; + compaction::ObMediumCompactionInfo info; + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(1, key.medium_snapshot_); + ASSERT_EQ(1, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(2, key.medium_snapshot_); + ASSERT_EQ(2, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(3, key.medium_snapshot_); + ASSERT_EQ(3, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_ITER_END, ret); + } + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ASSERT_EQ(OB_SUCCESS, reader.init(allocator)); + int64_t medium_snapshot = 0; + ret = reader.get_max_medium_snapshot(medium_snapshot); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(medium_snapshot, 3); + } + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ASSERT_EQ(OB_SUCCESS, reader.init(allocator)); + int64_t medium_snapshot = 0; + ret = reader.get_min_medium_snapshot(medium_snapshot); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(medium_snapshot, 1); + } + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ASSERT_EQ(OB_SUCCESS, reader.init(allocator)); + ObArenaAllocator tmp_allocator; + compaction::ObMediumCompactionInfoKey key(1); + compaction::ObMediumCompactionInfo medium_info; + ret = reader.get_specified_medium_info(tmp_allocator, key, medium_info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(medium_info.medium_snapshot_, 1); + } + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ASSERT_EQ(OB_SUCCESS, reader.init(allocator)); + ObArenaAllocator tmp_allocator; + compaction::ObMediumCompactionInfoKey key(10); + compaction::ObMediumCompactionInfo medium_info; + ret = reader.get_specified_medium_info(tmp_allocator, key, medium_info); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret); + } +} + +TEST_F(TestMediumInfoReader, mds_table_dump_data_no_overlap) +{ + int ret = OB_SUCCESS; + + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + ObTabletHandle tablet_handle; + ObTabletHandle new_tablet_handle; + ret = create_tablet(tablet_id, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + // insert data into mds table + MOCK_INSERT_MDS_TABLE(5); + MOCK_INSERT_MDS_TABLE(8); + + // insert data into mds data + { + ObTabletDumpedMediumInfo &medium_info_list = *tablet->mds_data_.medium_info_list_.ptr_; + + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + + MOCK_INSERT_TABLET(1); + MOCK_INSERT_TABLET(2); + + // persist + ret = ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + tablet = new_tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + } + + // iterate + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ret = reader.init(allocator); + ASSERT_EQ(OB_SUCCESS, ret); + + compaction::ObMediumCompactionInfoKey key; + compaction::ObMediumCompactionInfo info; + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(1, key.medium_snapshot_); + ASSERT_EQ(1, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(2, key.medium_snapshot_); + ASSERT_EQ(2, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(5, key.medium_snapshot_); + ASSERT_EQ(5, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(8, key.medium_snapshot_); + ASSERT_EQ(8, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_ITER_END, ret); + reader.reset(); + } + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ASSERT_EQ(OB_SUCCESS, reader.init(allocator)); + int64_t medium_snapshot = 0; + ret = reader.get_max_medium_snapshot(medium_snapshot); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(medium_snapshot, 8); + } + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ASSERT_EQ(OB_SUCCESS, reader.init(allocator)); + int64_t medium_snapshot = 0; + ret = reader.get_min_medium_snapshot(medium_snapshot); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(medium_snapshot, 1); + } +} + +TEST_F(TestMediumInfoReader, mds_table_dump_data_full_inclusion) +{ + int ret = OB_SUCCESS; + + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + ObTabletHandle tablet_handle; + ObTabletHandle new_tablet_handle; + ret = create_tablet(tablet_id, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + // insert data into mds table + MOCK_INSERT_MDS_TABLE(1); + MOCK_INSERT_MDS_TABLE(2); + MOCK_INSERT_MDS_TABLE(3); + MOCK_INSERT_MDS_TABLE(4); + MOCK_INSERT_MDS_TABLE(5); + + // insert data into mds data + { + ObTabletDumpedMediumInfo &medium_info_list = *tablet->mds_data_.medium_info_list_.ptr_; + + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + + MOCK_INSERT_TABLET(2); + MOCK_INSERT_TABLET(4); + + // persist + ret = ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + tablet = new_tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + } + + // iterate + { + common::ObArenaAllocator allocator; + ObTabletMediumInfoReader reader(*tablet); + ret = reader.init(allocator); + ASSERT_EQ(OB_SUCCESS, ret); + + compaction::ObMediumCompactionInfoKey key; + compaction::ObMediumCompactionInfo info; + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(1, key.medium_snapshot_); + ASSERT_EQ(1, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(2, key.medium_snapshot_); + ASSERT_EQ(2, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(3, key.medium_snapshot_); + ASSERT_EQ(3, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(4, key.medium_snapshot_); + ASSERT_EQ(4, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(5, key.medium_snapshot_); + ASSERT_EQ(5, info.medium_snapshot_); + + key.reset(); + info.reset(); + ret = reader.get_next_medium_info(allocator, key, info); + ASSERT_EQ(OB_ITER_END, ret); + } +} +} // namespace storage +} // namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -f test_medium_info_reader.log*"); + OB_LOGGER.set_file_name("test_medium_info_reader.log", true); + OB_LOGGER.set_log_level("INFO"); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/mtlenv/storage/test_memtable_v2.cpp b/mittest/mtlenv/storage/test_memtable_v2.cpp index 761a663cd..862958be7 100644 --- a/mittest/mtlenv/storage/test_memtable_v2.cpp +++ b/mittest/mtlenv/storage/test_memtable_v2.cpp @@ -136,6 +136,7 @@ private: public: virtual void SetUp() override { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); // mock sequence no ObClockGenerator::init(); // mock tx table @@ -372,7 +373,7 @@ public: tx_ctx->mt_ctx_.log_gen_.set(&(tx_ctx->mt_ctx_.trans_mgr_), &(tx_ctx->mt_ctx_)); store_ctx->mvcc_acc_ctx_.snapshot_.tx_id_ = tx_id; - store_ctx->mvcc_acc_ctx_.tx_table_guard_.init(&tx_table_); + store_ctx->mvcc_acc_ctx_.tx_table_guards_.tx_table_guard_.init(&tx_table_); if (for_replay) { store_ctx->mvcc_acc_ctx_.mem_ctx_->commit_to_replay(); } @@ -432,12 +433,23 @@ public: share::SCN snapshot_scn; snapshot_scn.convert_for_tx(snapshot); start_stmt(wtx, snapshot_scn, expire_time); - EXPECT_EQ(expect_ret, (ret = memtable->set(*wtx, - encrypt_index_, - read_info_, - columns_, - write_row, - encrypt_meta_))); + + ObTableAccessContext context; + ObVersionRange trans_version_range; + const bool read_latest = true; + ObQueryFlag query_flag; + + trans_version_range.base_version_ = 0; + trans_version_range.multi_version_start_ = 0; + trans_version_range.snapshot_version_ = EXIST_READ_SNAPSHOT_VERSION; + query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; + query_flag.read_latest_ = read_latest & ObQueryFlag::OBSF_MASK_READ_LATEST; + + if (OB_FAIL(context.init(query_flag, *wtx, allocator_, trans_version_range))) { + TRANS_LOG(WARN, "Fail to init access context", K(ret)); + } + + EXPECT_EQ(expect_ret, (ret = memtable->set(iter_param_, context, columns_, write_row, encrypt_meta_))); TRANS_LOG(INFO, "======================= end write tx ======================", K(ret), K(wtx->mvcc_acc_ctx_.tx_id_), K(*wtx), K(snapshot), K(expire_time), K(write_row)); @@ -457,10 +469,23 @@ public: share::SCN snapshot_scn; snapshot_scn.convert_for_tx(snapshot); start_stmt(ltx, snapshot_scn, expire_time); - EXPECT_EQ(expect_ret, (ret = memtable->lock(*ltx, - tablet_id_.id(), - read_info_, - rowkey))); + + ObTableAccessContext context; + ObVersionRange trans_version_range; + const bool read_latest = true; + ObQueryFlag query_flag; + + trans_version_range.base_version_ = 0; + trans_version_range.multi_version_start_ = 0; + trans_version_range.snapshot_version_ = EXIST_READ_SNAPSHOT_VERSION; + query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; + query_flag.read_latest_ = read_latest & ObQueryFlag::OBSF_MASK_READ_LATEST; + + if (OB_FAIL(context.init(query_flag, *ltx, allocator_, trans_version_range))) { + TRANS_LOG(WARN, "Fail to init access context", K(ret)); + } + + EXPECT_EQ(expect_ret, (ret = memtable->lock(iter_param_, context, rowkey))); TRANS_LOG(INFO, "======================= end lock tx ======================", K(ret), K(ltx->mvcc_acc_ctx_.tx_id_), K(*ltx), K(snapshot), K(expire_time), K(rowkey)); @@ -480,10 +505,23 @@ public: share::SCN snapshot_scn; snapshot_scn.convert_for_tx(snapshot); start_stmt(ltx, snapshot_scn, expire_time); - EXPECT_EQ(expect_ret, (ret = memtable->lock(*ltx, - tablet_id_.id(), - read_info_, - rowkey))); + + ObTableAccessContext context; + ObVersionRange trans_version_range; + const bool read_latest = true; + ObQueryFlag query_flag; + + trans_version_range.base_version_ = 0; + trans_version_range.multi_version_start_ = 0; + trans_version_range.snapshot_version_ = EXIST_READ_SNAPSHOT_VERSION; + query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; + query_flag.read_latest_ = read_latest & ObQueryFlag::OBSF_MASK_READ_LATEST; + + if (OB_FAIL(context.init(query_flag, *ltx, allocator_, trans_version_range))) { + TRANS_LOG(WARN, "Fail to init access context", K(ret)); + } + + EXPECT_EQ(expect_ret, (ret = memtable->lock(iter_param_, context, rowkey))); ObMvccTransNode *node = get_tx_last_tnode(ltx); ((ObMemtableDataHeader *)(node->buf_))->dml_flag_ = blocksstable::ObDmlFlag::DF_INSERT; @@ -862,13 +900,14 @@ public: int mock_iter_param() { + int ret = OB_SUCCESS; // iter_param_.rowkey_cnt_ = rowkey_cnt_; iter_param_.tablet_id_ = tablet_id_; iter_param_.table_id_ = tablet_id_.id(); - read_info_.init(allocator_, 16000, rowkey_cnt_, lib::is_oracle_mode(), columns_); + read_info_.init(allocator_, 16000, rowkey_cnt_, lib::is_oracle_mode(), columns_, nullptr/*storage_cols_index*/); iter_param_.read_info_ = &read_info_; - return OB_SUCCESS; + return ret; } void reset_iter_param() @@ -3301,17 +3340,31 @@ TEST_F(TestMemtableV2, test_seq_set_violation) share::SCN scn_3000; scn_3000.convert_for_tx(3000); start_pdml_stmt(wtx, scn_3000, read_seq_no, 1000000000/*expire_time*/); - EXPECT_EQ(OB_SUCCESS, (ret = memtable->set(*wtx, - tablet_id_.id(), - read_info_, + + ObTableAccessContext context; + ObVersionRange trans_version_range; + const bool read_latest = true; + ObQueryFlag query_flag; + + trans_version_range.base_version_ = 0; + trans_version_range.multi_version_start_ = 0; + trans_version_range.snapshot_version_ = EXIST_READ_SNAPSHOT_VERSION; + query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; + query_flag.read_latest_ = read_latest & ObQueryFlag::OBSF_MASK_READ_LATEST; + + if (OB_FAIL(context.init(query_flag, *wtx, allocator_, trans_version_range))) { + TRANS_LOG(WARN, "Fail to init access context", K(ret)); + } + + EXPECT_EQ(OB_SUCCESS, (ret = memtable->set(iter_param_, + context, columns_, write_row, encrypt_meta_))); start_pdml_stmt(wtx, scn_3000, read_seq_no, 1000000000/*expire_time*/); - EXPECT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, (ret = memtable->set(*wtx, - tablet_id_.id(), - read_info_, + EXPECT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, (ret = memtable->set(iter_param_, + context, columns_, write_row, encrypt_meta_))); @@ -3349,17 +3402,30 @@ TEST_F(TestMemtableV2, test_parallel_lock_with_same_txn) wtx->mvcc_acc_ctx_.abs_lock_timeout_ = abs_expire_time; wtx->mvcc_acc_ctx_.tx_scn_ = ObSequence::inc_and_get_max_seq_no(); + ObTableAccessContext context; + ObVersionRange trans_version_range; + const bool read_latest = true; + ObQueryFlag query_flag; + + trans_version_range.base_version_ = 0; + trans_version_range.multi_version_start_ = 0; + trans_version_range.snapshot_version_ = EXIST_READ_SNAPSHOT_VERSION; + query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; + query_flag.read_latest_ = read_latest & ObQueryFlag::OBSF_MASK_READ_LATEST; + + if (OB_FAIL(context.init(query_flag, *wtx, allocator_, trans_version_range))) { + TRANS_LOG(WARN, "Fail to init access context", K(ret)); + } + // Step3: lock for the first time - EXPECT_EQ(OB_SUCCESS, (ret = memtable->lock(*wtx, - tablet_id_.id(), - read_info_, + EXPECT_EQ(OB_SUCCESS, (ret = memtable->lock(iter_param_, + context, rowkey))); // Step4: lock for the second time wtx->mvcc_acc_ctx_.tx_scn_ = ObSequence::inc_and_get_max_seq_no(); - EXPECT_EQ(OB_SUCCESS, (ret = memtable->lock(*wtx, - tablet_id_.id(), - read_info_, + EXPECT_EQ(OB_SUCCESS, (ret = memtable->lock(iter_param_, + context, rowkey))); memtable->destroy(); } @@ -3401,12 +3467,13 @@ int ObTxCtxTable::release_ref_() namespace memtable { -int ObMemtable::lock_row_on_frozen_stores_(ObStoreCtx &, - const ObTxNodeArg &, - const ObMemtableKey *, - ObMvccRow *, - const storage::ObTableReadInfo &read_info, - ObMvccWriteResult &) +int ObMemtable::lock_row_on_frozen_stores_( + const storage::ObTableIterParam &, + const ObTxNodeArg &, + storage::ObTableAccessContext &, + const ObMemtableKey *, + ObMvccRow *, + ObMvccWriteResult &) { if (unittest::TestMemtableV2::is_sstable_contains_lock_) { return OB_TRY_LOCK_ROW_CONFLICT; diff --git a/mittest/mtlenv/storage/test_multi_version_merge_recycle.cpp b/mittest/mtlenv/storage/test_multi_version_merge_recycle.cpp index ab5bad5b0..e3a40567a 100644 --- a/mittest/mtlenv/storage/test_multi_version_merge_recycle.cpp +++ b/mittest/mtlenv/storage/test_multi_version_merge_recycle.cpp @@ -137,12 +137,11 @@ void TestMultiVersionMergeRecycle::SetUpTestCase() ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); // create tablet - obrpc::ObBatchCreateTabletArg create_tablet_arg; - share::schema::ObTableSchema table_schema; - ASSERT_EQ(OB_SUCCESS, gen_create_tablet_arg(tenant_id_, ls_id, tablet_id, create_tablet_arg, 1, &table_schema)); - ObLSTabletService *ls_tablet_svr = ls_handle.get_ls()->get_tablet_svr(); - ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(*ls_tablet_svr, create_tablet_arg)); + uint64_t table_id = 12345; + share::schema::ObTableSchema table_schema; + ASSERT_EQ(OB_SUCCESS, build_test_schema(table_schema, table_id)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema)); } void TestMultiVersionMergeRecycle::TearDownTestCase() @@ -249,7 +248,6 @@ void TestMultiVersionMergeRecycle::build_sstable( ObSSTable *&merged_sstable) { ASSERT_EQ(OB_SUCCESS, ctx.merge_info_.create_sstable(ctx)); - ASSERT_EQ(OB_SUCCESS, ctx.merged_table_handle_.get_sstable(merged_sstable)); } TEST_F(TestMultiVersionMergeRecycle, recycle_macro) diff --git a/mittest/mtlenv/storage/test_multi_version_sstable_merge.cpp b/mittest/mtlenv/storage/test_multi_version_sstable_merge.cpp index 53ff4c998..7cce7445a 100644 --- a/mittest/mtlenv/storage/test_multi_version_sstable_merge.cpp +++ b/mittest/mtlenv/storage/test_multi_version_sstable_merge.cpp @@ -135,12 +135,10 @@ void TestMultiVersionMerge::SetUpTestCase() MTL(ObTenantTabletScheduler*)->resume_major_merge(); // create tablet - obrpc::ObBatchCreateTabletArg create_tablet_arg; share::schema::ObTableSchema table_schema; - ASSERT_EQ(OB_SUCCESS, gen_create_tablet_arg(tenant_id_, ls_id, tablet_id, create_tablet_arg, 1, &table_schema)); - - ObLSTabletService *ls_tablet_svr = ls_handle.get_ls()->get_tablet_svr(); - ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(*ls_tablet_svr, create_tablet_arg)); + uint64_t table_id = 12345; + ASSERT_EQ(OB_SUCCESS, build_test_schema(table_schema, table_id)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema, allocator_)); } void TestMultiVersionMerge::TearDownTestCase() @@ -195,7 +193,6 @@ void TestMultiVersionMerge::prepare_query_param(const ObVersionRange &version_ra iter_param_.table_id_ = table_id_; iter_param_.tablet_id_ = tablet_id_; iter_param_.read_info_ = &full_read_info_; - iter_param_.full_read_info_ = &full_read_info_; iter_param_.out_cols_project_ = nullptr; iter_param_.is_same_schema_column_ = true; iter_param_.has_virtual_columns_ = false; @@ -256,9 +253,10 @@ void TestMultiVersionMerge::prepare_merge_context(const ObMergeType &merge_type, merge_context.sstable_version_range_ = trans_version_range; merge_context.param_.report_ = &rs_reporter_; merge_context.progressive_merge_num_ = 0; - const common::ObIArray &tables = merge_context.tables_handle_.get_tables(); - merge_context.scn_range_.start_scn_ = tables.at(0)->get_start_scn(); - merge_context.scn_range_.end_scn_ = tables.at(tables.count() - 1)->get_end_scn(); + const int64_t tables_count = merge_context.tables_handle_.get_count(); + merge_context.scn_range_.start_scn_ = merge_context.tables_handle_.get_table(0)->get_start_scn(); + merge_context.scn_range_.end_scn_ = merge_context.tables_handle_.get_table(tables_count - 1)->get_end_scn(); + merge_context.merge_scn_ = merge_context.scn_range_.end_scn_; ASSERT_EQ(OB_SUCCESS, merge_context.init_merge_info()); ASSERT_EQ(OB_SUCCESS, merge_context.merge_info_.prepare_index_builder(index_desc_)); @@ -269,7 +267,7 @@ void TestMultiVersionMerge::build_sstable( ObSSTable *&merged_sstable) { ASSERT_EQ(OB_SUCCESS, ctx.merge_info_.create_sstable(ctx)); - ASSERT_EQ(OB_SUCCESS, ctx.merged_table_handle_.get_sstable(merged_sstable)); + merged_sstable = &ctx.merged_sstable_; } TEST_F(TestMultiVersionMerge, rowkey_cross_two_macro_and_second_macro_is_filtered) diff --git a/mittest/mtlenv/storage/test_multi_version_sstable_single_get.cpp b/mittest/mtlenv/storage/test_multi_version_sstable_single_get.cpp index a30ed11d0..a6de529ee 100644 --- a/mittest/mtlenv/storage/test_multi_version_sstable_single_get.cpp +++ b/mittest/mtlenv/storage/test_multi_version_sstable_single_get.cpp @@ -54,12 +54,10 @@ void TestMultiVersionSSTableSingleGet::SetUpTestCase() ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); // create tablet - obrpc::ObBatchCreateTabletArg create_tablet_arg; share::schema::ObTableSchema table_schema; - ASSERT_EQ(OB_SUCCESS, gen_create_tablet_arg(tenant_id_, ls_id, tablet_id, create_tablet_arg, 1, &table_schema)); - - ObLSTabletService *ls_tablet_svr = ls_handle.get_ls()->get_tablet_svr(); - ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(*ls_tablet_svr, create_tablet_arg)); + uint64_t table_id = 12345; + ASSERT_EQ(OB_SUCCESS, build_test_schema(table_schema, table_id)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema, allocator_)); } void TestMultiVersionSSTableSingleGet::TearDownTestCase() @@ -91,7 +89,6 @@ void TestMultiVersionSSTableSingleGet::prepare_query_param( iter_param_.table_id_ = table_id_; iter_param_.tablet_id_ = tablet_id_; iter_param_.read_info_ = &full_read_info_; - iter_param_.full_read_info_ = &full_read_info_; iter_param_.out_cols_project_ = nullptr; iter_param_.is_same_schema_column_ = true; iter_param_.has_virtual_columns_ = false; @@ -187,9 +184,8 @@ TEST_F(TestMultiVersionSSTableSingleGet, exist) rowkey.assign(datum_row.storage_datums_, schema_rowkey_cnt); is_exist = true; is_found = true; - OK(sstable->exist(*context_.store_ctx_, - table_id_, - full_read_info_, + OK(sstable->exist(iter_param_, + context_, rowkey, is_exist, is_found)); @@ -202,9 +198,8 @@ TEST_F(TestMultiVersionSSTableSingleGet, exist) rowkey.assign(datum_row.storage_datums_, schema_rowkey_cnt); is_exist = false; is_found = false; - OK(sstable->exist(*context_.store_ctx_, - table_id_, - full_read_info_, + OK(sstable->exist(iter_param_, + context_, rowkey, is_exist, is_found)); @@ -217,9 +212,8 @@ TEST_F(TestMultiVersionSSTableSingleGet, exist) rowkey.assign(datum_row.storage_datums_, schema_rowkey_cnt); is_exist = false; is_found = true; - OK(sstable->exist(*context_.store_ctx_, - table_id_, - full_read_info_, + OK(sstable->exist(iter_param_, + context_, rowkey, is_exist, is_found)); @@ -232,9 +226,8 @@ TEST_F(TestMultiVersionSSTableSingleGet, exist) rowkey.assign(datum_row.storage_datums_, schema_rowkey_cnt); is_exist = false; is_found = false; - OK(sstable->exist(*context_.store_ctx_, - table_id_, - full_read_info_, + OK(sstable->exist(iter_param_, + context_, rowkey, is_exist, is_found)); @@ -247,9 +240,8 @@ TEST_F(TestMultiVersionSSTableSingleGet, exist) rowkey.assign(datum_row.storage_datums_, schema_rowkey_cnt); is_exist = true; is_found = true; - OK(sstable->exist(*context_.store_ctx_, - table_id_, - full_read_info_, + OK(sstable->exist(iter_param_, + context_, rowkey, is_exist, is_found)); @@ -266,9 +258,8 @@ TEST_F(TestMultiVersionSSTableSingleGet, exist) rowkey.assign(datum_row.storage_datums_, schema_rowkey_cnt); is_exist = true; is_found = true; - OK(sstable->exist(*context_.store_ctx_, - table_id_, - full_read_info_, + OK(sstable->exist(iter_param_, + context_, rowkey, is_exist, is_found)); @@ -281,9 +272,8 @@ TEST_F(TestMultiVersionSSTableSingleGet, exist) rowkey.assign(datum_row.storage_datums_, schema_rowkey_cnt); is_exist = true; is_found = true; - OK(sstable->exist(*context_.store_ctx_, - table_id_, - full_read_info_, + OK(sstable->exist(iter_param_, + context_, rowkey, is_exist, is_found)); @@ -296,9 +286,8 @@ TEST_F(TestMultiVersionSSTableSingleGet, exist) rowkey.assign(datum_row.storage_datums_, schema_rowkey_cnt); is_exist = true; is_found = true; - OK(sstable->exist(*context_.store_ctx_, - table_id_, - full_read_info_, + OK(sstable->exist(iter_param_, + context_, rowkey, is_exist, is_found)); @@ -311,9 +300,8 @@ TEST_F(TestMultiVersionSSTableSingleGet, exist) rowkey.assign(datum_row.storage_datums_, schema_rowkey_cnt); is_exist = true; is_found = true; - OK(sstable->exist(*context_.store_ctx_, - table_id_, - full_read_info_, + OK(sstable->exist(iter_param_, + context_, rowkey, is_exist, is_found)); @@ -326,9 +314,8 @@ TEST_F(TestMultiVersionSSTableSingleGet, exist) rowkey.assign(datum_row.storage_datums_, schema_rowkey_cnt); is_exist = true; is_found = true; - OK(sstable->exist(*context_.store_ctx_, - table_id_, - full_read_info_, + OK(sstable->exist(iter_param_, + context_, rowkey, is_exist, is_found)); diff --git a/mittest/mtlenv/storage/test_physical_copy_task.cpp b/mittest/mtlenv/storage/test_physical_copy_task.cpp index 9737cd5bf..78cccffdb 100644 --- a/mittest/mtlenv/storage/test_physical_copy_task.cpp +++ b/mittest/mtlenv/storage/test_physical_copy_task.cpp @@ -100,7 +100,7 @@ void TestRootBlockInfo::prepare_tablet_read_info() desc.col_order_ = ObOrderType::ASC; ASSERT_EQ(OB_SUCCESS, columns.push_back(desc)); } - ASSERT_EQ(OB_SUCCESS, table_read_info_.init(allocator_, schema_version, ROWKEY_COL_CNT, lib::is_oracle_mode(), columns, true)); + ASSERT_EQ(OB_SUCCESS, table_read_info_.init(allocator_, schema_version, ROWKEY_COL_CNT, lib::is_oracle_mode(), columns, nullptr/*storage_cols_index*/)); } void TestRootBlockInfo::prepare_block_root() @@ -154,7 +154,7 @@ void TestRootBlockInfo::prepare_block_root() write_info.size_ = buf_size; ASSERT_EQ(OB_SUCCESS, ObBlockManager::write_block(write_info, handle)); block_addr_.second_id_ = handle.get_macro_id().second_id(); - ASSERT_EQ(OB_SUCCESS, root_info_.init_root_block_info(&allocator_, block_addr_, block_data_)); + ASSERT_EQ(OB_SUCCESS, root_info_.init_root_block_info(allocator_, block_addr_, block_data_)); ASSERT_TRUE(root_info_.is_valid()); } @@ -291,11 +291,11 @@ void TestMigrationSSTableParam::SetUp() ASSERT_TRUE(!sstable_meta_.is_valid()); sstable_meta_.reset(); ASSERT_TRUE(!sstable_meta_.is_valid()); - ASSERT_EQ(OB_SUCCESS, sstable_meta_.init(param_, &allocator_)); + ASSERT_EQ(OB_SUCCESS, sstable_meta_.init(param_, allocator_)); ASSERT_TRUE(sstable_meta_.is_valid()); ASSERT_TRUE(sstable_meta_.data_root_info_.is_valid()); ASSERT_TRUE(sstable_meta_.macro_info_.is_valid()); - ASSERT_TRUE(sstable_meta_.get_col_checksum().count() > 0); + ASSERT_TRUE(sstable_meta_.get_col_checksum_cnt() > 0); table_key_.table_type_ = ObITable::TableType::MAJOR_SSTABLE; table_key_.tablet_id_ = 1101; table_key_.version_range_.base_version_ = 0; @@ -314,14 +314,16 @@ void TestMigrationSSTableParam::TearDown() TEST_F(TestMigrationSSTableParam, test_check_sstable_meta) { int ret = OB_SUCCESS; - ObPhysicalCopyFinishTask finish_task; + ObSSTableCopyFinishTask finish_task; finish_task.is_inited_ = true; ObMigrationSSTableParam mig_param; ASSERT_TRUE(!mig_param.is_valid()); mig_param.reset(); ASSERT_TRUE(!mig_param.is_valid()); mig_param.basic_meta_ = sstable_meta_.get_basic_meta(); - ASSERT_EQ(OB_SUCCESS, mig_param.column_checksums_.assign(sstable_meta_.get_col_checksum())); + for (int64_t i = 0; i < sstable_meta_.get_col_checksum_cnt(); ++i) { + ASSERT_EQ(OB_SUCCESS, mig_param.column_checksums_.push_back(sstable_meta_.get_col_checksum()[i])); + } mig_param.table_key_ = table_key_; ASSERT_TRUE(mig_param.is_valid()); ASSERT_TRUE(mig_param.basic_meta_.is_valid()); @@ -329,7 +331,7 @@ TEST_F(TestMigrationSSTableParam, test_check_sstable_meta) ASSERT_TRUE(mig_param.table_key_.is_valid()); ASSERT_EQ(sstable_meta_.get_basic_meta(), mig_param.basic_meta_); ASSERT_EQ(table_key_, mig_param.table_key_); - ASSERT_EQ(sstable_meta_.get_col_checksum().count(), mig_param.column_checksums_.count()); + ASSERT_EQ(sstable_meta_.get_col_checksum_cnt(), mig_param.column_checksums_.count()); ret = finish_task.check_sstable_meta_(mig_param, sstable_meta_); ASSERT_EQ(OB_SUCCESS, ret); diff --git a/mittest/mtlenv/storage/test_shared_block_reader_writer.cpp b/mittest/mtlenv/storage/test_shared_block_reader_writer.cpp new file mode 100644 index 000000000..677a9be85 --- /dev/null +++ b/mittest/mtlenv/storage/test_shared_block_reader_writer.cpp @@ -0,0 +1,485 @@ +/** + * 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 +#include +#define protected public +#define private public +#define OK(ass) ASSERT_EQ(OB_SUCCESS, (ass)) +#include "storage/blockstore/ob_shared_block_reader_writer.h" +#include "share/io/ob_io_define.h" +#include "share/io/ob_io_manager.h" +#include "mittest/mtlenv/mock_tenant_module_env.h" +#include "storage/meta_mem/ob_storage_meta_cache.h" +#include "storage/blocksstable/ob_sstable.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "share/ob_simple_mem_limit_getter.h" +#include "storage/blocksstable/ob_storage_cache_suite.h" +#include "storage/tablet/ob_tablet.h" + +namespace oceanbase +{ +using namespace common; +using namespace blocksstable; +using namespace storage; +static ObSimpleMemLimitGetter getter; + +namespace unittest +{ +class TestSharedBlockRWriter : public::testing::Test +{ +public: + TestSharedBlockRWriter() {} + virtual ~TestSharedBlockRWriter() = default; + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp(); + virtual void TearDown(); + void create_empty_sstable(ObSSTable &empty_sstable); + ObArenaAllocator allocator_; +}; + +void TestSharedBlockRWriter::SetUpTestCase() +{ + STORAGE_LOG(INFO, "SetUpTestCase"); + + EXPECT_EQ(OB_SUCCESS, MockTenantModuleEnv::get_instance().init()); +} + +void TestSharedBlockRWriter::TearDownTestCase() +{ + MockTenantModuleEnv::get_instance().destroy(); +} + +void TestSharedBlockRWriter::SetUp() +{ + int ret = OB_SUCCESS; + const ObTenantIOConfig &io_config = ObTenantIOConfig::default_instance(); + if (OB_FAIL(ObIOManager::get_instance().add_tenant_io_manager(OB_SERVER_TENANT_ID, io_config))) { + STORAGE_LOG(WARN, "add tenant io config failed"); + } +} + +void TestSharedBlockRWriter::TearDown() +{ +} + +void TestSharedBlockRWriter::create_empty_sstable(ObSSTable &empty_sstable) +{ + ObTabletCreateSSTableParam param; + param.encrypt_id_ = 0; + param.master_key_id_ = 0; + MEMSET(param.encrypt_key_, 0, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); + param.table_key_.table_type_ = ObITable::TableType::MAJOR_SSTABLE; + param.table_key_.tablet_id_ = 10; + param.table_key_.version_range_.snapshot_version_ = 1; + param.max_merged_trans_version_ = 1; + + param.schema_version_ = 1; + param.create_snapshot_version_ = 0; + param.progressive_merge_round_ = 0; + param.progressive_merge_step_ = 0; + + ObTableMode table_mode; + param.table_mode_ = table_mode; + param.index_type_ = ObIndexType::INDEX_TYPE_IS_NOT; + param.rowkey_column_cnt_ = 1; + param.root_block_addr_.set_none_addr(); + param.data_block_macro_meta_addr_.set_none_addr(); + param.root_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + param.latest_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + param.data_index_tree_height_ = 0; + param.index_blocks_cnt_ = 0; + param.data_blocks_cnt_ = 0; + param.micro_block_cnt_ = 0; + param.use_old_macro_block_count_ = 0; + param.data_checksum_ = 0; + param.occupy_size_ = 0; + param.ddl_scn_.set_min(); + param.filled_tx_scn_.set_min(); + param.original_size_ = 0; + param.ddl_scn_.set_min(); + param.compressor_type_ = ObCompressorType::NONE_COMPRESSOR; + param.column_cnt_ = 1; + OK(ObSSTableMergeRes::fill_column_checksum_for_empty_major(param.column_cnt_, param.column_checksums_)); + OK(empty_sstable.init(param, &allocator_)); +} + +TEST_F(TestSharedBlockRWriter, test_rwrite_easy_block) +{ + ObSharedBlockReaderWriter rwriter; + OK(rwriter.init(true/*need align*/, false/*need cross*/)); + ObMetaDiskAddr addr; + MacroBlockId macro_id; + ObMacroBlockCommonHeader common_header; + common_header.reset(); + common_header.set_attr(ObMacroBlockCommonHeader::MacroBlockType::SharedMetaData); + const int64_t header_size = common_header.get_serialize_size(); + ASSERT_EQ(rwriter.offset_, header_size); + ASSERT_TRUE(rwriter.hanging_); + ASSERT_EQ(rwriter.data_.pos_, header_size); + + + char s[10] = ""; + int test_round = 10; + while (test_round--) { + ObSharedBlockWriteInfo write_info; + ObSharedBlockWriteHandle write_handle; + ObSharedBlockReadHandle read_handle; + for (int i = 0; i < 10; ++i) { + s[i] = '0' + test_round; + } + write_info.buffer_ = s; + write_info.offset_ = 0; + write_info.size_ = 10; + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + OK(rwriter.async_write(write_info, write_handle)); + ASSERT_TRUE(write_handle.is_valid()); + + ObSharedBlocksWriteCtx write_ctx; + ObSharedBlockReadInfo read_info; + OK(write_handle.get_write_ctx(write_ctx)); + ASSERT_EQ(write_ctx.addr_.size_, 10 + sizeof(ObSharedBlockHeader)); + if (test_round == 9) { + macro_id = write_ctx.addr_.block_id(); + } + + read_info.addr_ = write_ctx.addr_; + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_READ); + OK(rwriter.async_read(read_info, read_handle)); + char *buf = nullptr; + int64_t buf_len = 0; + OK(read_handle.get_data(allocator_, buf, buf_len)); + ASSERT_EQ(10, buf_len); + for (int64_t i = 0; i < buf_len; ++i) { + ASSERT_EQ(buf[i], '0' + test_round); + } + } + + // test check shared blk + ObMacroBlockReadInfo read_info; + ObMacroBlockHandle macro_handle; + read_info.macro_block_id_ = macro_id; + read_info.offset_ = 0; + read_info.size_ = (2L << 20); + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_READ); + const int64_t io_timeout_ms = + std::max(GCONF._data_storage_io_timeout / 1000, DEFAULT_IO_WAIT_TIME_MS); + + OK(ObBlockManager::async_read_block(read_info, macro_handle)); + OK(macro_handle.wait(io_timeout_ms)); + OK((ObSSTableMacroBlockChecker::check(macro_handle.get_buffer(), + macro_handle.get_data_size(), ObMacroBlockCheckLevel::CHECK_LEVEL_PHYSICAL))); +} + +TEST_F(TestSharedBlockRWriter, test_batch_write_easy_block) +{ + ObSharedBlockReaderWriter rwriter; + OK(rwriter.init(true/*need align*/, false/*need cross*/)); + int test_round = 10; + + ObSharedBlockWriteInfo write_info; + ObArray write_infos; + char s[10][100]; + for (int i = 0; i < test_round; ++i) { + for (int j = 0; j <10; ++j) { + s[i][j] = '0' + i; + } + write_info.buffer_ = s[i]; + write_info.offset_ = 0; + write_info.size_ = 10; + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + write_infos.push_back(write_info); + } + + ObSharedBlockBatchHandle write_handle; + OK(rwriter.async_batch_write(write_infos, write_handle)); + ASSERT_TRUE(write_handle.is_valid()); + + ObArray write_ctxs; + OK(write_handle.batch_get_write_ctx(write_ctxs)); + ASSERT_EQ(test_round, write_ctxs.count()); + + for (int i = 0; i < test_round; ++i) { + ObSharedBlockReadInfo read_info; + ObSharedBlockReadHandle read_handle; + read_info.addr_ = write_ctxs.at(i).addr_; + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_READ); + OK(rwriter.async_read(read_info, read_handle)); + char *buf = nullptr; + int64_t buf_len = 0; + OK(read_handle.get_data(allocator_, buf, buf_len)); + ASSERT_EQ(10, buf_len); + for (int64_t j = 0; j < buf_len; ++j) { + ASSERT_EQ(buf[j], '0' + i); + } + } +} + + +TEST_F(TestSharedBlockRWriter, test_link_write) +{ + ObSharedBlockReaderWriter rwriter; + OK(rwriter.init(true/*need align*/, false/*need cross*/)); + int test_round = 10; + + ObSharedBlockWriteInfo write_info; + ObSharedBlockLinkHandle write_handle; + char s[10]; + for (int i = 0; i < test_round; ++i) { + for (int j = 0; j < 10; ++j) { + s[j] = '0' + i; + } + write_info.buffer_ = s; + write_info.offset_ = 0; + write_info.size_ = 10; + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + OK(rwriter.async_link_write(write_info, write_handle)); + ASSERT_TRUE(write_handle.is_valid()); + } + + ObSharedBlocksWriteCtx write_ctx; + ObSharedBlockLinkIter iter; + OK(write_handle.get_write_ctx(write_ctx)); + OK(iter.init(write_ctx.addr_)); + char *buf = nullptr; + int64_t buf_len = 0; + for (int i = 0; i < test_round; ++i) { + OK(iter.get_next(allocator_, buf, buf_len)); + ASSERT_EQ(10, buf_len); + for (int64_t j = 0; j < buf_len; ++j) { + ASSERT_EQ(buf[j], '0'+9-i); + } + } + ASSERT_EQ(OB_ITER_END, iter.get_next(allocator_, buf, buf_len)); +} + +TEST_F(TestSharedBlockRWriter, test_cb_single_write) +{ + ObSharedBlockReaderWriter rwriter; + OK(rwriter.init(true/*need align*/, false/*need cross*/)); + + ObSSTable empty_sstable; + create_empty_sstable(empty_sstable); + const int64_t sstable_size = empty_sstable.get_serialize_size(); + char *sstable_buf = static_cast(allocator_.alloc(sstable_size)); + int64_t pos = 0; + OK(empty_sstable.serialize(sstable_buf, sstable_size, pos)); + + ObSharedBlockWriteInfo write_info; + ObSharedBlockWriteHandle write_handle; + write_info.buffer_ = sstable_buf; + write_info.offset_ = 0; + write_info.size_ = sstable_size; + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + OK(rwriter.async_write(write_info, write_handle)); + ASSERT_TRUE(write_handle.is_valid()); + + ObSharedBlocksWriteCtx write_ctx; + OK(write_handle.get_write_ctx(write_ctx)); + + ObStorageMetaHandle meta_handle; + OK(meta_handle.cache_handle_.new_value(allocator_)); + const ObStorageMetaValue::MetaType meta_type = ObStorageMetaValue::SSTABLE; + ObTablet tablet; + ObTablet *fake_tablet = &tablet; + uint64_t tenant_id = 1; + ObStorageMetaKey meta_key; + meta_key.tenant_id_ = tenant_id; + meta_key.phy_addr_ = write_ctx.addr_; + ObStorageMetaCache::ObStorageMetaIOCallback cb( + meta_type, meta_key, meta_handle.cache_handle_, &allocator_, fake_tablet); + ObSharedBlockReadInfo read_info; + ObSharedBlockReadHandle read_handle; + read_info.addr_ = write_ctx.addr_; + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_READ); + read_info.io_callback_ = &cb; + OK(rwriter.async_read(read_info, read_handle)); + OK(read_handle.wait()); + // test the buf of read handle + char *buf = nullptr; + int64_t buf_len = 0; + OK(read_handle.get_data(allocator_, buf, buf_len)); + ASSERT_EQ(sstable_size, buf_len); +} + +TEST_F(TestSharedBlockRWriter, test_cb_batch_write) +{ + ObSharedBlockReaderWriter rwriter; + OK(rwriter.init(true/*need align*/, false/*need cross*/)); + int test_round = 10; + + ObSharedBlockWriteInfo write_info; + ObArray write_infos; + char s[10][100]; + for (int i = 0; i < test_round; ++i) { + for (int j = 0; j <10; ++j) { + s[i][j] = '0' + i; + } + write_info.buffer_ = s[i]; + write_info.offset_ = 0; + write_info.size_ = 10; + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + write_infos.push_back(write_info); + } + + ObSSTable empty_sstable; + create_empty_sstable(empty_sstable); + const int64_t sstable_size = empty_sstable.get_serialize_size(); + char *sstable_buf = static_cast(allocator_.alloc(sstable_size)); + int64_t pos = 0; + OK(empty_sstable.serialize(sstable_buf, sstable_size, pos)); + write_info.buffer_ = sstable_buf; + write_info.offset_ = 0; + write_info.size_ = sstable_size; + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + write_infos.push_back(write_info); + + ObSharedBlockBatchHandle write_handle; + OK(rwriter.async_batch_write(write_infos, write_handle)); + ASSERT_TRUE(write_handle.is_valid()); + + ObArray write_ctxs; + OK(write_handle.batch_get_write_ctx(write_ctxs)); + ASSERT_EQ(test_round + 1, write_ctxs.count()); + + ObStorageMetaHandle meta_handle; + OK(meta_handle.cache_handle_.new_value(allocator_)); + const ObStorageMetaValue::MetaType meta_type = ObStorageMetaValue::SSTABLE; + ObTablet tablet; + ObTablet *fake_tablet = &tablet; + uint64_t tenant_id = 1; + ObStorageMetaKey meta_key; + meta_key.tenant_id_ = tenant_id; + meta_key.phy_addr_ = write_ctxs[test_round].addr_; + ObStorageMetaCache::ObStorageMetaIOCallback cb( + meta_type, meta_key, meta_handle.cache_handle_, &allocator_, fake_tablet); + ObSharedBlockReadInfo read_info; + ObSharedBlockReadHandle read_handle; + read_info.addr_ = write_ctxs[test_round].addr_; + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_READ); + read_info.io_callback_ = &cb; + OK(rwriter.async_read(read_info, read_handle)); + OK(read_handle.wait()); + // test the buf of read handle + char *buf = nullptr; + int64_t buf_len = 0; + OK(read_handle.get_data(allocator_, buf, buf_len)); + ASSERT_EQ(sstable_size, buf_len); +} + +TEST_F(TestSharedBlockRWriter, test_batch_write_switch_block) +{ + // test switch block when batch write, which means hanging_=true + ObSharedBlockReaderWriter rwriter; + OK(rwriter.init(true/*need align*/, false/*need cross*/)); + ObSharedBlockWriteInfo write_info; + ObArray write_infos; + int64_t data_size = 3L << 10; // 3K + char s[3L << 10] = ""; + for (int i = 0; i < data_size; ++i) { + s[i] = '0' + (i % 10); + } + write_info.buffer_ = s; + write_info.offset_ = 0; + write_info.size_ = data_size; + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + OK(write_infos.push_back(write_info)); + OK(write_infos.push_back(write_info)); + + ObMacroBlockCommonHeader common_header; + common_header.reset(); + common_header.set_attr(ObMacroBlockCommonHeader::MacroBlockType::SharedMetaData); + const int64_t header_size = common_header.get_serialize_size(); + ASSERT_EQ(rwriter.data_.pos_, header_size); + + rwriter.offset_ = (2L << 20) - (4L << 10); // 2M - 4K + rwriter.align_offset_ = rwriter.offset_; + rwriter.data_.advance(rwriter.offset_ - header_size); + + ObSharedBlockBatchHandle write_handle; + OK(rwriter.async_batch_write(write_infos, write_handle)); + ASSERT_TRUE(write_handle.is_valid()); + + ObArray write_ctxs; + OK(write_handle.batch_get_write_ctx(write_ctxs)); + ASSERT_EQ(write_infos.count(), write_ctxs.count()); + + for (int i = 0; i < write_ctxs.count(); ++i) { + ObSharedBlockReadInfo read_info; + ObSharedBlockReadHandle read_handle; + read_info.addr_ = write_ctxs.at(i).addr_; + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_READ); + OK(rwriter.async_read(read_info, read_handle)); + char *buf = nullptr; + int64_t buf_len = 0; + OK(read_handle.get_data(allocator_, buf, buf_len)); + ASSERT_EQ(data_size, buf_len); + for (int64_t j = 0; j < data_size; ++j) { + ASSERT_EQ(buf[j], '0' + (j % 10)); + } + } +} + +TEST_F(TestSharedBlockRWriter, test_batch_write_bug1) +{ + /* batch_write_bug1: + The store_size of the last block in batch_write is not aligned to 4K + when hanging_ = true && we need switch_block. + This may result in 4016 read error of other blocks flushed by next async_write. + */ + ObSharedBlockReaderWriter rwriter; + OK(rwriter.init(true/*need align*/, false/*need cross*/)); + + rwriter.offset_ = (2L << 20) - 10; // nearly to 2M, ready to switch block + rwriter.align_offset_ = (2L << 20) - 4096; + rwriter.hanging_ = true; + + ObSharedBlockWriteInfo write_info; // the last block + int64_t data_size = 1L << 10; // 1K + char s[1L << 10] = ""; + for (int i = 0; i < data_size; ++i) { + s[i] = '0' + (i % 10); + } + write_info.buffer_ = s; + write_info.offset_ = 0; + write_info.size_ = data_size; + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + + ObSharedBlockWriteHandle block_handle; + OK(rwriter.async_write(write_info, block_handle)); + ObSharedBlocksWriteCtx write_ctx; + OK(block_handle.get_write_ctx(write_ctx)); + const ObMetaDiskAddr &addr = write_ctx.addr_; + + ObMacroBlockCommonHeader common_header; + common_header.reset(); + common_header.set_attr(ObMacroBlockCommonHeader::MacroBlockType::SharedMetaData); + const int64_t header_size = common_header.get_serialize_size(); + ASSERT_EQ(addr.offset_, 0 + header_size); + ASSERT_EQ(addr.size_, data_size + sizeof(ObSharedBlockHeader)); + ASSERT_EQ(rwriter.offset_, 4096); + ASSERT_EQ(rwriter.align_offset_, 4096); +} + +}//end namespace unittest +}//end namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -f test_shared_block_reader_writer.log*"); + oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); + OB_LOGGER.set_file_name("test_shared_block_reader_writer.log", true); + srand(time(NULL)); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/mtlenv/storage/test_table_scan_pure_data_table.cpp b/mittest/mtlenv/storage/test_table_scan_pure_data_table.cpp index 9ce21dfef..4a9332871 100644 --- a/mittest/mtlenv/storage/test_table_scan_pure_data_table.cpp +++ b/mittest/mtlenv/storage/test_table_scan_pure_data_table.cpp @@ -18,6 +18,7 @@ #include "storage/test_dml_common.h" #include "share/schema/ob_table_dml_param.h" #include "observer/ob_safe_destroy_thread.h" +#include "storage/test_tablet_helper.h" namespace oceanbase { @@ -38,6 +39,10 @@ public: public: static void SetUpTestCase(); static void TearDownTestCase(); + void SetUp() + { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); + } public: void insert_data_to_tablet(MockObAccessService *access_service); void table_scan( @@ -47,6 +52,7 @@ protected: uint64_t tenant_id_; share::ObLSID ls_id_; common::ObTabletID tablet_id_; + common::ObArenaAllocator allocator_; }; TestTableScanPureDataTable::TestTableScanPureDataTable() @@ -59,6 +65,11 @@ TestTableScanPureDataTable::TestTableScanPureDataTable() void TestTableScanPureDataTable::SetUpTestCase() { + uint64_t version = cal_version(4, 2, 0, 0); + ASSERT_EQ(OB_SUCCESS, ObClusterVersion::get_instance().init(version)); + ASSERT_EQ(OB_SUCCESS, omt::ObTenantConfigMgr::get_instance().add_tenant_config(MTL_ID())); + ObClusterVersion::get_instance().tenant_config_mgr_ = &omt::ObTenantConfigMgr::get_instance(); + ASSERT_EQ(OB_SUCCESS, MockTenantModuleEnv::get_instance().init()); // MTL(transaction::ObTransService*)->tx_desc_mgr_.tx_id_allocator_ = // [](transaction::ObTransID &tx_id) { tx_id = transaction::ObTransID(1001); return OB_SUCCESS; }; @@ -224,8 +235,12 @@ TEST_F(TestTableScanPureDataTable, table_scan_pure_data_table) { int ret = OB_SUCCESS; - ret = TestDmlCommon::create_data_tablet(tenant_id_, ls_id_, tablet_id_); - ASSERT_EQ(OB_SUCCESS, ret); + ObLSHandle ls_handle; + TestDmlCommon::create_ls(tenant_id_, ls_id_, ls_handle); + + ObTableSchema table_schema; + TestDmlCommon::build_data_table_schema(tenant_id_, table_schema); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id_, table_schema, allocator_)); // mock ls tablet service and access service ObLSTabletService *tablet_service = nullptr; @@ -244,6 +259,7 @@ TEST_F(TestTableScanPureDataTable, table_scan_pure_data_table) ObNewRowIterator *iter = nullptr; table_scan(access_service, iter); + // clean env TestDmlCommon::delete_mocked_access_service(access_service); TestDmlCommon::delete_mocked_ls_tablet_service(tablet_service); diff --git a/mittest/mtlenv/storage/test_tablet_mds_data.cpp b/mittest/mtlenv/storage/test_tablet_mds_data.cpp new file mode 100644 index 000000000..061e72466 --- /dev/null +++ b/mittest/mtlenv/storage/test_tablet_mds_data.cpp @@ -0,0 +1,155 @@ +/** + * 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 + +#define protected public +#define private public + +#include "lib/oblog/ob_log.h" +#include "lib/time/ob_time_utility.h" +#include "mtlenv/mock_tenant_module_env.h" +#include "mtlenv/storage/medium_info_helper.h" +#include "share/io/ob_io_manager.h" +#include "storage/tablet/ob_tablet_mds_data.h" +#include "storage/tablet/ob_tablet_obj_load_helper.h" + +#define BUILD_AND_WRITE_MEDIUM_INFO(id) \ + { \ + compaction::ObMediumCompactionInfo *info = nullptr; \ + if (OB_FAIL(ret)) { \ + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator_, info))) { \ + STORAGE_LOG(WARN, "failed to alloc and new", K(ret)); \ + } else { \ + if (OB_FAIL(MediumInfoHelper::build_medium_compaction_info(allocator_, *info, id))) { \ + STORAGE_LOG(WARN, "failed to build medium info", K(ret)); \ + } else { \ + const int64_t size = info->get_serialize_size(); \ + char *buffer = static_cast(allocator_.alloc(size)); \ + int64_t pos = 0; \ + if (OB_ISNULL(buffer)) { \ + ret = OB_ALLOCATE_MEMORY_FAILED; \ + STORAGE_LOG(WARN, "failed to alloc memory", K(ret), K(size)); \ + } else if (OB_FAIL(info->serialize(buffer, size, pos))) { \ + STORAGE_LOG(WARN, "failed to serialize", K(ret), K(size)); \ + } else { \ + ObSharedBlockWriteInfo write_info; \ + write_info.buffer_ = buffer; \ + write_info.offset_ = 0; \ + write_info.size_ = size; \ + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); \ + if (OB_FAIL(reader_writer.async_link_write(write_info, write_handle))) { \ + STORAGE_LOG(WARN, "failed to async link write", K(ret)); \ + } \ + } \ + } \ + \ + if (OB_FAIL(ret)) { \ + if (nullptr != info) { \ + allocator_.free(info); \ + } \ + } \ + } \ + } + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +class TestTabletMdsData : public::testing::Test +{ +public: + TestTabletMdsData(); + virtual ~TestTabletMdsData() = default; + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp(); + virtual void TearDown(); +public: + common::ObArenaAllocator allocator_; // for medium info +}; + +TestTabletMdsData::TestTabletMdsData() + : allocator_() +{ +} + +void TestTabletMdsData::SetUpTestCase() +{ + EXPECT_EQ(OB_SUCCESS, MockTenantModuleEnv::get_instance().init()); +} + +void TestTabletMdsData::TearDownTestCase() +{ + MockTenantModuleEnv::get_instance().destroy(); +} + +void TestTabletMdsData::SetUp() +{ + int ret = OB_SUCCESS; + const ObTenantIOConfig &io_config = ObTenantIOConfig::default_instance(); + if (OB_FAIL(ObIOManager::get_instance().add_tenant_io_manager(OB_SERVER_TENANT_ID, io_config))) { + STORAGE_LOG(WARN, "add tenant io config failed"); + } +} + +void TestTabletMdsData::TearDown() +{ +} + +TEST_F(TestTabletMdsData, read_medium_info) +{ + int ret = OB_SUCCESS; + ObSharedBlockReaderWriter reader_writer; + ret = reader_writer.init(true/*need align*/, false/*need cross*/); + ASSERT_EQ(OB_SUCCESS, ret); + + // write + ObSharedBlockLinkHandle write_handle; + const int64_t current_time = ObTimeUtility::fast_current_time(); + BUILD_AND_WRITE_MEDIUM_INFO(current_time + 1); + BUILD_AND_WRITE_MEDIUM_INFO(current_time + 2); + BUILD_AND_WRITE_MEDIUM_INFO(current_time + 3); + BUILD_AND_WRITE_MEDIUM_INFO(current_time + 4); + BUILD_AND_WRITE_MEDIUM_INFO(current_time + 5); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(write_handle.is_valid()); + + // read + ObSharedBlocksWriteCtx write_ctx; + ObSharedBlockLinkIter iter; + ret = write_handle.get_write_ctx(write_ctx); + ASSERT_EQ(OB_SUCCESS, ret); + + common::ObSEArray array; + ret = ObTabletMdsData::read_medium_info(allocator_, write_ctx.addr_, array); + ASSERT_EQ(OB_SUCCESS, ret); + + constexpr int64_t count = 5; + for (int64_t i = 0; i < count; ++i) { + const compaction::ObMediumCompactionInfo* info = array.at(i); + ASSERT_EQ(current_time + count - i, info->medium_snapshot_); + } +} +} // namespace storage +} // namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -f test_tablet_mds_data.log*"); + oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); + OB_LOGGER.set_file_name("test_tablet_mds_data.log", true); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/mittest/mtlenv/storage/test_tablet_member_load_and_free.cpp b/mittest/mtlenv/storage/test_tablet_member_load_and_free.cpp new file mode 100644 index 000000000..58fbf6d14 --- /dev/null +++ b/mittest/mtlenv/storage/test_tablet_member_load_and_free.cpp @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2021 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 + +#define USING_LOG_PREFIX STORAGE + +#define private public +#define protected public + +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log.h" +#include "lib/time/ob_time_utility.h" +#include "share/ob_ls_id.h" +#include "common/ob_tablet_id.h" +#include "storage/ls/ob_ls.h" +#include "storage/ls/ob_ls_get_mod.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_persister.h" +#include "mtlenv/mock_tenant_module_env.h" +#include "unittest/storage/test_tablet_helper.h" +#include "unittest/storage/test_dml_common.h" +#include "unittest/storage/schema_utils.h" +#include "observer/ob_safe_destroy_thread.h" + +using namespace oceanbase::share; +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +class TestTabletMemberLoadAndFree : public ::testing::Test +{ +public: + TestTabletMemberLoadAndFree(); + virtual ~TestTabletMemberLoadAndFree() = default; + + virtual void SetUp() override; + virtual void TearDown() override; + static void SetUpTestCase(); + static void TearDownTestCase(); +public: + static int create_ls(const uint64_t tenant_id, const share::ObLSID &ls_id, ObLSHandle &ls_handle); + static int remove_ls(const share::ObLSID &ls_id); + int create_tablet(const common::ObTabletID &tablet_id, ObTabletHandle &tablet_handle); +public: + static const uint64_t TENANT_ID = 1; + static const share::ObLSID LS_ID; + + common::ObArenaAllocator allocator_; +}; + +const share::ObLSID TestTabletMemberLoadAndFree::LS_ID(1001); + +TestTabletMemberLoadAndFree::TestTabletMemberLoadAndFree() + : allocator_() +{ +} + +void TestTabletMemberLoadAndFree::SetUp() +{ +} + +void TestTabletMemberLoadAndFree::TearDown() +{ +} + +void TestTabletMemberLoadAndFree::SetUpTestCase() +{ + int ret = OB_SUCCESS; + ret = MockTenantModuleEnv::get_instance().init(); + ASSERT_EQ(OB_SUCCESS, ret); + + SAFE_DESTROY_INSTANCE.init(); + SAFE_DESTROY_INSTANCE.start(); + ObServerCheckpointSlogHandler::get_instance().is_started_ = true; + + // create ls + ObLSHandle ls_handle; + ret = create_ls(TENANT_ID, LS_ID, ls_handle); + ASSERT_EQ(OB_SUCCESS, ret); +} + +void TestTabletMemberLoadAndFree::TearDownTestCase() +{ + int ret = OB_SUCCESS; + + // remove ls + ret = remove_ls(LS_ID); + ASSERT_EQ(OB_SUCCESS, ret); + + SAFE_DESTROY_INSTANCE.stop(); + SAFE_DESTROY_INSTANCE.wait(); + SAFE_DESTROY_INSTANCE.destroy(); + + MockTenantModuleEnv::get_instance().destroy(); +} + +int TestTabletMemberLoadAndFree::create_ls(const uint64_t tenant_id, const share::ObLSID &ls_id, ObLSHandle &ls_handle) +{ + int ret = OB_SUCCESS; + ret = TestDmlCommon::create_ls(tenant_id, ls_id, ls_handle); + return ret; +} + +int TestTabletMemberLoadAndFree::remove_ls(const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ret = MTL(ObLSService*)->remove_ls(ls_id, false); + return ret; +} + +int TestTabletMemberLoadAndFree::create_tablet(const common::ObTabletID &tablet_id, ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + const uint64_t table_id = 1234567; + share::schema::ObTableSchema table_schema; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + mds::MdsTableHandle mds_table; + + if (OB_FAIL(MTL(ObLSService*)->get_ls(LS_ID, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), KP(ls)); + } else if (OB_FAIL(build_test_schema(table_schema, table_id))) { + LOG_WARN("failed to build table schema"); + } else if (OB_FAIL(TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema, allocator_))) { + LOG_WARN("failed to create tablet", K(ret)); + } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret)); + } else if (OB_FAIL(tablet_handle.get_obj()->inner_get_mds_table(mds_table, true/*not_exist_create*/))) { + LOG_WARN("failed to get mds table", K(ret)); + } + + return ret; +} + +TEST_F(TestTabletMemberLoadAndFree, storage_schema) +{ + int ret = OB_SUCCESS; + ObArenaAllocator arena_allocator; + + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + ObTabletHandle tablet_handle; + ret = create_tablet(tablet_id, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + // load storage schema, memory type + ASSERT_TRUE(tablet->storage_schema_addr_.is_memory_object()); + const ObStorageSchema *storage_schema = nullptr; + ret = tablet->load_storage_schema(arena_allocator, storage_schema); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, storage_schema); + + ASSERT_NE(0, arena_allocator.used()); + ObTablet::free_storage_schema(arena_allocator, storage_schema); + arena_allocator.clear(); + ASSERT_EQ(0, arena_allocator.used()); + + // tablet persist + ObTabletHandle new_tablet_handle; + ret = ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + ObTablet *new_tablet = new_tablet_handle.get_obj(); + ASSERT_NE(nullptr, new_tablet); + + // load storage schema, disk type + ASSERT_TRUE(new_tablet->storage_schema_addr_.addr_.is_block()); + storage_schema = nullptr; + ret = new_tablet->load_storage_schema(arena_allocator, storage_schema); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, storage_schema); + + ASSERT_NE(0, arena_allocator.used()); + ObTablet::free_storage_schema(arena_allocator, storage_schema); + arena_allocator.clear(); + ASSERT_EQ(0, arena_allocator.used()); +} +} // namespace storage +} // namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -f test_tablet_member_load_and_free.log*"); + OB_LOGGER.set_file_name("test_tablet_member_load_and_free.log", true); + OB_LOGGER.set_log_level("INFO"); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/mittest/mtlenv/storage/test_tablet_status.cpp b/mittest/mtlenv/storage/test_tablet_status.cpp index 106305746..fd7546c12 100644 --- a/mittest/mtlenv/storage/test_tablet_status.cpp +++ b/mittest/mtlenv/storage/test_tablet_status.cpp @@ -61,6 +61,7 @@ public: const uint64_t tenant_id_; share::ObLSID ls_id_; ObTenantBase *tenant_base_; + common::ObArenaAllocator allocator_; }; TestTabletStatus::TestTabletStatus(const uint64_t tenant_id) @@ -72,6 +73,7 @@ TestTabletStatus::TestTabletStatus(const uint64_t tenant_id) void TestTabletStatus::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); int ret = OB_SUCCESS; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); t3m->stop(); @@ -172,7 +174,7 @@ TEST_F(TestTabletStatus, misc) ASSERT_EQ(OB_SUCCESS, ret); ObLS *ls = ls_handle.get_ls(); - ret = t3m->acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, tablet_handle, false); + ret = t3m->create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, tablet_handle); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_TRUE(tablet_handle.is_valid()); @@ -181,7 +183,6 @@ TEST_F(TestTabletStatus, misc) TestSchemaUtils::prepare_data_schema(table_schema); const transaction::ObTransID tx_id = 1; const int64_t snapshot_version = 1; - ObTableHandleV2 table_handle; const lib::Worker::CompatMode compat_mode = lib::Worker::CompatMode::MYSQL; ObTabletID empty_tablet_id; ObFreezer *freezer = ls->get_freezer(); @@ -190,14 +191,11 @@ TEST_F(TestTabletStatus, misc) tablet->tablet_meta_.tx_data_.tablet_status_ = ObTabletStatus::CREATING; // mock ObTabletTableStoreFlag store_flag; store_flag.set_with_major_sstable(); - ret = tablet->init(ls_id_, tablet_id, tablet_id, empty_tablet_id, empty_tablet_id, - share::SCN::base_scn(), snapshot_version, table_schema, compat_mode, store_flag, table_handle, freezer); + ret = tablet->init(allocator_, ls_id_, tablet_id, tablet_id, empty_tablet_id, empty_tablet_id, + share::SCN::base_scn(), snapshot_version, table_schema, compat_mode, store_flag, nullptr, freezer); ASSERT_EQ(OB_SUCCESS, ret); - ObMetaDiskAddr mem_addr; - mem_addr.type_ = ObMetaDiskAddr::DiskType::MEM; - mem_addr.size_ = sizeof(ObTablet); - ret = t3m->compare_and_swap_tablet(key, mem_addr, tablet_handle, tablet_handle); + ret = t3m->compare_and_swap_tablet(key, tablet_handle, tablet_handle); ASSERT_EQ(OB_SUCCESS, ret); // set tx data diff --git a/mittest/mtlenv/storage/test_tablet_status_cache.cpp b/mittest/mtlenv/storage/test_tablet_status_cache.cpp new file mode 100644 index 000000000..5685a9d09 --- /dev/null +++ b/mittest/mtlenv/storage/test_tablet_status_cache.cpp @@ -0,0 +1,437 @@ +/** + * 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 + +#define private public +#define protected public + +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log.h" +#include "mtlenv/mock_tenant_module_env.h" +#include "unittest/storage/test_tablet_helper.h" +#include "unittest/storage/test_dml_common.h" +#include "share/ob_ls_id.h" +#include "common/ob_tablet_id.h" +#include "storage/ls/ob_ls.h" +#include "storage/ls/ob_ls_get_mod.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/tx/ob_trans_define.h" +#include "observer/ob_safe_destroy_thread.h" + +using namespace oceanbase::common; + +#define USING_LOG_PREFIX STORAGE + +namespace oceanbase +{ +namespace storage +{ +class TestTabletStatusCache : public::testing::Test +{ +public: + TestTabletStatusCache(); + virtual ~TestTabletStatusCache() = default; + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp(); + virtual void TearDown(); +public: + static int create_ls(const uint64_t tenant_id, const share::ObLSID &ls_id, ObLSHandle &ls_handle); + static int remove_ls(const share::ObLSID &ls_id); + int create_tablet( + const common::ObTabletID &tablet_id, + ObTabletHandle &tablet_handle, + const share::SCN &create_commit_scn = share::SCN::min_scn()); +public: + static constexpr uint64_t TENANT_ID = 1001; + static const share::ObLSID LS_ID; + + common::ObArenaAllocator allocator_; +}; + +TestTabletStatusCache::TestTabletStatusCache() + : allocator_() +{ +} + +const share::ObLSID TestTabletStatusCache::LS_ID(1001); + +void TestTabletStatusCache::SetUpTestCase() +{ + int ret = OB_SUCCESS; + ret = MockTenantModuleEnv::get_instance().init(); + ASSERT_EQ(OB_SUCCESS, ret); + + SAFE_DESTROY_INSTANCE.init(); + SAFE_DESTROY_INSTANCE.start(); + ObServerCheckpointSlogHandler::get_instance().is_started_ = true; + + // create ls + ObLSHandle ls_handle; + ret = create_ls(TENANT_ID, LS_ID, ls_handle); + ASSERT_EQ(OB_SUCCESS, ret); +} + +void TestTabletStatusCache::TearDownTestCase() +{ + int ret = OB_SUCCESS; + + // remove ls + ret = remove_ls(LS_ID); + ASSERT_EQ(OB_SUCCESS, ret); + + SAFE_DESTROY_INSTANCE.stop(); + SAFE_DESTROY_INSTANCE.wait(); + SAFE_DESTROY_INSTANCE.destroy(); + + MockTenantModuleEnv::get_instance().destroy(); +} + +void TestTabletStatusCache::SetUp() +{ +} + +void TestTabletStatusCache::TearDown() +{ +} + +int TestTabletStatusCache::create_ls(const uint64_t tenant_id, const share::ObLSID &ls_id, ObLSHandle &ls_handle) +{ + int ret = OB_SUCCESS; + ret = TestDmlCommon::create_ls(tenant_id, ls_id, ls_handle); + return ret; +} + +int TestTabletStatusCache::remove_ls(const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ret = MTL(ObLSService*)->remove_ls(ls_id, false); + return ret; +} + +int TestTabletStatusCache::create_tablet( + const common::ObTabletID &tablet_id, + ObTabletHandle &tablet_handle, + const share::SCN &create_commit_scn) +{ + int ret = OB_SUCCESS; + const uint64_t table_id = 1234567; + share::schema::ObTableSchema table_schema; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + mds::MdsTableHandle mds_table; + + if (OB_FAIL(MTL(ObLSService*)->get_ls(LS_ID, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), KP(ls)); + } else if (OB_FAIL(build_test_schema(table_schema, table_id))) { + LOG_WARN("failed to build table schema"); + } else if (OB_FAIL(TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema, allocator_, + ObTabletStatus::Status::NORMAL, create_commit_scn))) { + LOG_WARN("failed to create tablet", K(ret), K(ls_id), K(tablet_id), K(create_commit_scn)); + } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret)); + } else if (OB_FAIL(tablet_handle.get_obj()->inner_get_mds_table(mds_table, true/*not_exist_create*/))) { + LOG_WARN("failed to get mds table", K(ret)); + } + + return ret; +} + +TEST_F(TestTabletStatusCache, weak_read) +{ + int ret = OB_SUCCESS; + + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + ObTabletHandle tablet_handle; + // create commit scn: 50 + share::SCN min_scn; + min_scn.set_min(); + ret = create_tablet(tablet_id, tablet_handle, share::SCN::plus(min_scn, 50)); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + // disable cache + { + SpinWLockGuard guard(tablet->mds_cache_lock_); + tablet->tablet_status_cache_.reset(); + } + + const ObTabletMapKey key(LS_ID, tablet_id); + tablet_handle.reset(); + // mode is READ_READABLE_COMMITED, snapshot version is smaller than create commit version, return OB_SNAPSHOT_DISCARDED + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, 20/*snapshot*/); + ASSERT_EQ(OB_SNAPSHOT_DISCARDED, ret); + // mode is READ_ALL_COMMITED, but snapshot is not max scn, not supported + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_ALL_COMMITED, 20/*snapshot*/); + ASSERT_EQ(OB_NOT_SUPPORTED, ret); + // mode is READ_READABLE_COMMITED, snapshot version is bigger than create commit version, return OB_SUCCESS + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, 60/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(TestTabletStatusCache, get_transfer_out_tablet) +{ + int ret = OB_SUCCESS; + + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + ObTabletHandle tablet_handle; + ret = create_tablet(tablet_id, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + // set transfer scn + // create commit scn: 50 + // transfer scn: 100 + ObTabletCreateDeleteMdsUserData user_data; + user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT; + share::SCN min_scn; + min_scn.set_min(); + user_data.transfer_scn_ = share::SCN::plus(min_scn, 100); + user_data.transfer_ls_id_ = share::ObLSID(1010); + user_data.data_type_ = ObTabletMdsUserDataType::START_TRANSFER_OUT; + user_data.create_commit_scn_ = share::SCN::plus(min_scn, 50); + user_data.create_commit_version_ = 50; + + mds::MdsCtx ctx1(mds::MdsWriter(transaction::ObTransID(123))); + ret = tablet->set(user_data, ctx1); + ASSERT_EQ(OB_SUCCESS, ret); + + // disable cache + { + SpinWLockGuard guard(tablet->mds_cache_lock_); + tablet->tablet_status_cache_.reset(); + } + + const ObTabletMapKey key(LS_ID, tablet_id); + tablet_handle.reset(); + // mode is READ_READABLE_COMMITED, can not get tablet + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_SCHEMA_EAGAIN, ret); + // mode is READ_ALL_COMMITED, allow to get TRANSFER_OUT status tablet + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + + tablet_handle.reset(); + // read snapshot: 80. not max scn, return OB_NOT_SUPPORTED + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_ALL_COMMITED, 80/*snapshot*/); + ASSERT_EQ(OB_NOT_SUPPORTED, ret); + // read snapshot: 80. less than transfer scn + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + + // check tablet status cache + { + SpinRLockGuard guard(tablet->mds_cache_lock_); + const ObTabletStatusCache &tablet_status_cache = tablet->tablet_status_cache_; + + // we won't update tablet status cache if current status is TRANSFER_OUT, + // so here the cache remains invalid + ASSERT_EQ(ObTabletStatus::MAX, tablet_status_cache.tablet_status_); + } + + // let transaction commit + // commit scn: 120 + share::SCN commit_scn = share::SCN::plus(min_scn, 120); + ctx1.single_log_commit(commit_scn, commit_scn); + + tablet_handle.reset(); + // mode is READ_READABLE_COMMITED, read snapshot is max scn, greater than transfer scn 100, not allow to get tablet + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + // mode is READ_ALL_COMMITED, allow to get tablet + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + + tablet_handle.reset(); + // mode is READ_READABLE_COMMITED, read snapshot 80 less than transfer scn 100, allow to get tablet + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, 80/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + // mode is READ_ALL_COMMITED, snapshot is not max scn, return OB_NOT_SUPPORTED + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_ALL_COMMITED, 80/*snapshot*/); + ASSERT_EQ(OB_NOT_SUPPORTED, ret); + // mode is READ_ALL_COMMITED, allow to get tablet + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + + // begin transfer out deleted transaction + user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT_DELETED; + user_data.transfer_scn_ = share::SCN::plus(min_scn, 100); + user_data.transfer_ls_id_ = share::ObLSID(1010); + user_data.data_type_ = ObTabletMdsUserDataType::FINISH_TRANSFER_OUT; + user_data.create_commit_scn_ = share::SCN::plus(min_scn, 50); + user_data.create_commit_version_ = 50; + user_data.delete_commit_scn_ = share::SCN::plus(min_scn, 200); + user_data.delete_commit_version_ = 200; + + mds::MdsCtx ctx2(mds::MdsWriter(transaction::ObTransID(456))); + ret = tablet->set(user_data, ctx2); + ASSERT_EQ(OB_SUCCESS, ret); + + // disable cache + { + SpinWLockGuard guard(tablet->mds_cache_lock_); + tablet->tablet_status_cache_.reset(); + } + + // mode is READ_READABLE_COMMITED, snpashot status is transfer out, not allow to get + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + // mode is READ_ALL_COMMITED, allow to get tablet whose snapshot status is transfer out + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + + // transaction commit + commit_scn = share::SCN::plus(min_scn, 220); + ctx2.single_log_commit(commit_scn, commit_scn); + + // mode is READ_READABLE_COMMITED, snapshot status is transfer out deleted, not allow to get + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + // mode is READ_ALL_COMMITED, snapshot status is transfer out deleted, not allow to get + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + + // begin transfer out deleted transaction + user_data.tablet_status_ = ObTabletStatus::DELETED; + user_data.transfer_scn_ = share::SCN::plus(min_scn, 100); + user_data.transfer_ls_id_ = share::ObLSID(1010); + user_data.data_type_ = ObTabletMdsUserDataType::REMOVE_TABLET; + user_data.create_commit_scn_ = share::SCN::plus(min_scn, 50); + user_data.create_commit_version_ = 50; + user_data.delete_commit_scn_ = share::SCN::plus(min_scn, 200); + user_data.delete_commit_version_ = 200; + + mds::MdsCtx ctx3(mds::MdsWriter(transaction::ObTransID(789))); + ret = tablet->set(user_data, ctx3); + ASSERT_EQ(OB_SUCCESS, ret); + + // disable cache + { + SpinWLockGuard guard(tablet->mds_cache_lock_); + tablet->tablet_status_cache_.reset(); + } + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, 100/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + + ObLSHandle ls_handle; + ret = MTL(ObLSService*)->get_ls(LS_ID, ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + ObLS *ls = ls_handle.get_ls(); + ASSERT_NE(nullptr, ls); + + ret = ls->get_tablet_svr()->update_tablet_to_empty_shell(tablet_id); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, 100/*snapshot*/); + ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); +} + +TEST_F(TestTabletStatusCache, get_transfer_deleted) +{ + int ret = OB_SUCCESS; + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + ObTabletHandle tablet_handle; + ret = create_tablet(tablet_id, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + ObLSHandle ls_handle; + ret = MTL(ObLSService*)->get_ls(LS_ID, ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + ObLS *ls = ls_handle.get_ls(); + ASSERT_NE(nullptr, ls); + + ObTabletCreateDeleteMdsUserData user_data; + share::SCN min_scn; + min_scn.set_min(); + // set transfer scn + // create commit scn: 50 + // transfer scn: 100 + // delete commit scn: 200 + // begin deleted transaction + user_data.tablet_status_ = ObTabletStatus::DELETED; + user_data.transfer_scn_ = share::SCN::plus(min_scn, 100); + user_data.transfer_ls_id_ = share::ObLSID(1010); + user_data.data_type_ = ObTabletMdsUserDataType::REMOVE_TABLET; + user_data.create_commit_scn_ = share::SCN::plus(min_scn, 50); + user_data.create_commit_version_ = 50; + user_data.delete_commit_scn_ = share::SCN::plus(min_scn, 200); + user_data.delete_commit_version_ = 200; + + mds::MdsCtx ctx(mds::MdsWriter(transaction::ObTransID(789))); + ret = tablet->set(user_data, ctx); + ASSERT_EQ(OB_SUCCESS, ret); + share::SCN commit_scn = share::SCN::plus(min_scn, 120); + ctx.single_log_commit(commit_scn, commit_scn); + + // disable cache + { + SpinWLockGuard guard(tablet->mds_cache_lock_); + tablet->tablet_status_cache_.reset(); + } + + const ObTabletMapKey key(LS_ID, tablet_id); + tablet_handle.reset(); + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, 100/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = ls->get_tablet_svr()->update_tablet_to_empty_shell(tablet_id); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, 100/*snapshot*/); + ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); +} +} // namespace storage +} // namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -f test_tablet_status_cache.log*"); + oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); + OB_LOGGER.set_file_name("test_tablet_status_cache.log", true); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp b/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp index a6bf11260..641a574b7 100644 --- a/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp +++ b/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp @@ -17,8 +17,10 @@ #define protected public #define private public +#include "storage/tablet/ob_tablet_persister.h" #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" #include "storage/ls/ob_ls.h" +#include "storage/schema_utils.h" #include "storage/mock_ob_log_handler.h" #include "storage/tablelock/ob_lock_memtable.h" #include "storage/tablet/ob_tablet_table_store_flag.h" @@ -53,17 +55,31 @@ int ObMemtable::batch_remove_unused_callback_for_uncommited_txn( namespace storage { -int ObTenantCheckpointSlogHandler::read_from_ckpt(const ObMetaDiskAddr &phy_addr, - char *buf, const int64_t buf_len, int64_t &r_len) -{ - return OB_NOT_SUPPORTED; -} -int ObTablet::update_msd_cache_on_pointer() +int ObTablet::check_and_set_initial_state() { return OB_SUCCESS; } +int ObTabletPersister::acquire_tablet( + const ObTabletPoolType &type, + const ObTabletMapKey &key, + const bool try_smaller_pool, + ObTabletHandle &new_handle) +{ + int ret = OB_SUCCESS; + UNUSED(try_smaller_pool); + if (new_handle.is_valid()) { + // nothing to do + } else { + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr *); + if (OB_FAIL(t3m->acquire_tablet_from_pool(type, WashTabletPriority::WTP_LOW, key, new_handle))) { + LOG_WARN("fail to acquire tablet from pool", K(ret), K(key), K(type)); + } + } + return ret; +} + class TestTenantMetaMemMgr : public ::testing::Test { public: @@ -76,7 +92,8 @@ public: static void TearDownTestCase(); void prepare_data_schema(ObTableSchema &table_schema); - + void prepare_create_sstable_param(); + void gc_all_tablets(); public: static const int64_t TEST_ROWKEY_COLUMN_CNT = 3; static const int64_t TEST_COLUMN_CNT = 6; @@ -87,6 +104,9 @@ public: const uint64_t tenant_id_; share::ObLSID ls_id_; ObTenantMetaMemMgr t3m_; + ObTabletCreateSSTableParam param_; + share::schema::ObTableSchema table_schema_; + common::ObArenaAllocator allocator_; }; // record the old_t3m just for ls remove @@ -94,7 +114,10 @@ ObTenantMetaMemMgr *old_t3m = nullptr; TestTenantMetaMemMgr::TestTenantMetaMemMgr() : tenant_id_(TEST_TENANT_ID), ls_id_(TEST_LS_ID), - t3m_(TEST_TENANT_ID) + t3m_(TEST_TENANT_ID), + param_(), + table_schema_(), + allocator_() { } @@ -106,6 +129,7 @@ void TestTenantMetaMemMgr::SetUpTestCase() SAFE_DESTROY_INSTANCE.init(); SAFE_DESTROY_INSTANCE.start(); ObServerCheckpointSlogHandler::get_instance().is_started_ = true; + ObClockGenerator::init(); // create ls ObLSHandle ls_handle; @@ -116,12 +140,15 @@ void TestTenantMetaMemMgr::SetUpTestCase() void TestTenantMetaMemMgr::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); int ret = OB_SUCCESS; ret = t3m_.init(); ASSERT_EQ(OB_SUCCESS, ret); ObTenantBase *tenant_base = MTL_CTX(); tenant_base->set(&t3m_); + TestSchemaUtils::prepare_data_schema(table_schema_); + prepare_create_sstable_param(); } void TestTenantMetaMemMgr::TearDownTestCase() @@ -129,7 +156,6 @@ void TestTenantMetaMemMgr::TearDownTestCase() int ret = OB_SUCCESS; ret = MTL(ObLSService*)->remove_ls(ObLSID(TEST_LS_ID), false); ASSERT_EQ(OB_SUCCESS, ret); - SAFE_DESTROY_INSTANCE.stop(); SAFE_DESTROY_INSTANCE.wait(); SAFE_DESTROY_INSTANCE.destroy(); @@ -138,6 +164,9 @@ void TestTenantMetaMemMgr::TearDownTestCase() void TestTenantMetaMemMgr::TearDown() { + table_schema_.reset(); + t3m_.stop(); + t3m_.wait(); t3m_.destroy(); // return to the old t3m to make ls destroy success. @@ -194,13 +223,57 @@ void TestTenantMetaMemMgr::prepare_data_schema(ObTableSchema &table_schema) LOG_INFO("dump data table schema", LITERAL_K(TEST_ROWKEY_COLUMN_CNT), K(table_schema)); } +void TestTenantMetaMemMgr::prepare_create_sstable_param() +{ + const int64_t multi_version_col_cnt = ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + param_.table_key_.table_type_ = ObITable::TableType::MAJOR_SSTABLE; + param_.table_key_.tablet_id_ = 1; + param_.table_key_.version_range_.base_version_ = ObVersionRange::MIN_VERSION; + param_.table_key_.version_range_.snapshot_version_ = 0; + param_.schema_version_ = table_schema_.get_schema_version(); + param_.create_snapshot_version_ = 0; + param_.progressive_merge_round_ = table_schema_.get_progressive_merge_round(); + param_.progressive_merge_step_ = 0; + param_.table_mode_ = table_schema_.get_table_mode_struct(); + param_.index_type_ = table_schema_.get_index_type(); + param_.rowkey_column_cnt_ = table_schema_.get_rowkey_column_num() + + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + param_.root_block_addr_.set_none_addr(); + param_.data_block_macro_meta_addr_.set_none_addr(); + param_.root_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + param_.data_index_tree_height_ = 0; + param_.index_blocks_cnt_ = 0; + param_.data_blocks_cnt_ = 0; + param_.micro_block_cnt_ = 0; + param_.use_old_macro_block_count_ = 0; + param_.column_cnt_ = table_schema_.get_column_count() + multi_version_col_cnt; + param_.data_checksum_ = 0; + param_.occupy_size_ = 0; + param_.ddl_scn_.set_min(); + param_.filled_tx_scn_.set_min(); + param_.original_size_ = 0; + param_.compressor_type_ = ObCompressorType::NONE_COMPRESSOR; + param_.encrypt_id_ = 0; + param_.master_key_id_ = 0; + ASSERT_EQ(OB_SUCCESS, ObSSTableMergeRes::fill_column_checksum_for_empty_major(param_.column_cnt_, param_.column_checksums_)); +} + +void TestTenantMetaMemMgr::gc_all_tablets() +{ + bool all_tablet_cleaned = false; + while (!all_tablet_cleaned) { + t3m_.gc_tablets_in_queue(all_tablet_cleaned); // do not use MTL t3m + } +} + class TestConcurrentT3M : public share::ObThreadPool { public: TestConcurrentT3M( const int64_t thread_cnt, ObTenantMetaMemMgr &t3m_, - ObTenantBase *tenant_base); + ObTenantBase *tenant_base, + common::ObArenaAllocator &allocator); virtual ~TestConcurrentT3M(); virtual void run1(); @@ -212,17 +285,20 @@ private: ObTenantMetaMemMgr &t3m_; ObTenantBase *tenant_base_; common::SpinRWLock lock_; + common::ObArenaAllocator &allocator_; }; TestConcurrentT3M::TestConcurrentT3M( const int64_t thread_cnt, ObTenantMetaMemMgr &t3m, - ObTenantBase *tenant_base) + ObTenantBase *tenant_base, + common::ObArenaAllocator &allocator) : thread_cnt_(thread_cnt), ls_id_(TestTenantMetaMemMgr::TEST_LS_ID), t3m_(t3m), tenant_base_(tenant_base), - lock_() + lock_(), + allocator_(allocator) { set_thread_count(static_cast(thread_cnt_)); } @@ -250,10 +326,13 @@ void TestConcurrentT3M::run1() while (count-- > 0) { ObTablet *tablet = nullptr; key.tablet_id_ = thread_idx_ * TABLET_CNT_PER_THREAD * 10 + count + 1; - int ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); - ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_TRUE(handle.is_valid()); - + { + SpinWLockGuard guard(lock_); + int ret = t3m_.create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle); + handle.t3m_ = &t3m_; // temporary code, use local t3m + ASSERT_EQ(common::OB_SUCCESS, ret); + ASSERT_TRUE(handle.is_valid()); + } tablet = handle.get_obj(); ASSERT_TRUE(nullptr != tablet); ASSERT_TRUE(tablet->pointer_hdl_.is_valid()); @@ -265,19 +344,23 @@ void TestConcurrentT3M::run1() tablet = handle.get_obj(); ASSERT_TRUE(nullptr != tablet); - ASSERT_TRUE(nullptr != handle.obj_pool_); + ASSERT_TRUE(nullptr != handle.allocator_); + if (0 == count % N) { /* mock empty tablet to del successfully */ + tablet->table_store_addr_.addr_.set_none_addr(); + tablet->storage_schema_addr_.addr_.set_none_addr(); + tablet->mds_data_.auto_inc_seq_.addr_.set_none_addr(); + tablet->rowkey_read_info_ = nullptr; + } ObMetaDiskAddr addr; - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); - ASSERT_EQ(common::OB_INVALID_ARGUMENT, ret); - addr.first_id_ = 1; addr.second_id_ = 2; addr.offset_ = 0; addr.size_ = 4096; addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; + handle.get_obj()->set_tablet_addr(addr); - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); + ret = t3m_.compare_and_swap_tablet(key, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ObMetaPointerHandle ptr_hdl(t3m_.tablet_map_); @@ -287,7 +370,7 @@ void TestConcurrentT3M::run1() ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_TRUE(addr == ptr_hdl.ptr_->ptr_->phy_addr_); ASSERT_TRUE(handle.obj_ == ptr_hdl.ptr_->ptr_->obj_.ptr_); - ASSERT_TRUE(handle.obj_pool_ == ptr_hdl.ptr_->ptr_->obj_.pool_); + ASSERT_TRUE(handle.allocator_ == ptr_hdl.ptr_->ptr_->obj_.allocator_); handle.reset(); @@ -308,41 +391,27 @@ TEST_F(TestTenantMetaMemMgr, test_bucket_cnt) // ASSERT_EQ(unify_bucket_num, t3m_lock_bkt_cnt); ASSERT_EQ(unify_bucket_num, t3m_map_bkt_cnt); ASSERT_EQ(unify_bucket_num, t3m_map_lock_bkt_cnt); - - const int64_t unify_pin_set_bkt_cnt = common::hash::cal_next_prime(ObTenantMetaMemMgr::DEFAULT_BUCKET_NUM); - const int64_t pin_set_lock_bkt_cnt = t3m_.pin_set_lock_.bucket_cnt_; - const int64_t pin_set_bkt_cnt = t3m_.pinned_tablet_set_.ht_.get_bucket_count(); - ASSERT_NE(unify_pin_set_bkt_cnt, 0); - ASSERT_EQ(unify_pin_set_bkt_cnt, pin_set_lock_bkt_cnt); - ASSERT_EQ(unify_pin_set_bkt_cnt, pin_set_bkt_cnt); } TEST_F(TestTenantMetaMemMgr, test_sstable) { - int ret = OB_SUCCESS; - ObTableHandleV2 handle; - - ret = t3m_.acquire_sstable(handle); - ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_TRUE(nullptr != handle.table_); - ASSERT_EQ(1, t3m_.sstable_pool_.inner_used_num_); - ASSERT_EQ(1, handle.get_table()->get_ref()); - - handle.table_->inc_ref(); - t3m_.release_sstable(static_cast(handle.table_)); - ASSERT_EQ(1, t3m_.sstable_pool_.inner_used_num_); - ASSERT_EQ(2, handle.get_table()->get_ref()); - - handle.table_->dec_ref(); - t3m_.release_sstable(static_cast(handle.table_)); - ASSERT_EQ(1, t3m_.sstable_pool_.inner_used_num_); - ASSERT_EQ(1, handle.get_table()->get_ref()); - - handle.reset(); - ASSERT_EQ(1, t3m_.sstable_pool_.inner_used_num_); - ASSERT_EQ(1, t3m_.free_tables_queue_.size()); - - t3m_.release_sstable(static_cast(handle.table_)); + void *buf = nullptr; + ObSSTable *sstable = nullptr; + ObArenaAllocator allocator; + ASSERT_NE(nullptr, (buf = allocator.alloc(sizeof(ObSSTable)))); + sstable = new (buf) ObSSTable(); + sstable->is_tmp_sstable_ = true; + ObTableHandleV2 sstable_handle; + ObTableHandleV2 handle2; + ASSERT_EQ(OB_SUCCESS, sstable_handle.set_sstable(sstable, &allocator)); + ASSERT_EQ(1, sstable->get_ref()); + handle2 = sstable_handle; + ASSERT_EQ(2, sstable->get_ref()); + handle2.reset(); + ASSERT_EQ(1, sstable->get_ref()); + sstable_handle.reset(); + ASSERT_EQ(0, sstable->get_ref()); + ASSERT_EQ(false, sstable->is_tmp_sstable_); } TEST_F(TestTenantMetaMemMgr, test_memtable) @@ -477,9 +546,10 @@ TEST_F(TestTenantMetaMemMgr, test_tablet) tablet = handle.get_obj(); ASSERT_TRUE(nullptr == tablet); - ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); + ret = t3m_.create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle); + handle.t3m_ = &t3m_; // temporary code, use local t3m ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_TRUE(handle.is_valid()); @@ -495,22 +565,19 @@ TEST_F(TestTenantMetaMemMgr, test_tablet) ASSERT_TRUE(!tmp_handle.is_valid()); ASSERT_TRUE(nullptr != tablet); - ASSERT_TRUE(nullptr != handle.obj_pool_); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_TRUE(nullptr != handle.allocator_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ObMetaDiskAddr addr; - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); - ASSERT_EQ(common::OB_INVALID_ARGUMENT, ret); - ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - addr.first_id_ = 1; addr.second_id_ = 2; addr.offset_ = 0; addr.size_ = 4096; addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; + handle.get_obj()->set_tablet_addr(addr); - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); + ret = t3m_.compare_and_swap_tablet(key, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); @@ -522,18 +589,18 @@ TEST_F(TestTenantMetaMemMgr, test_tablet) ret = t3m_.tablet_map_.inc_handle_ref(ptr_hdl.ptr_); ASSERT_TRUE(addr == ptr_hdl.ptr_->ptr_->phy_addr_); ASSERT_TRUE(handle.obj_ == ptr_hdl.ptr_->ptr_->obj_.ptr_); - ASSERT_TRUE(handle.obj_pool_ == ptr_hdl.ptr_->ptr_->obj_.pool_); + ASSERT_TRUE(handle.allocator_ == ptr_hdl.ptr_->ptr_->obj_.allocator_); ObMetaDiskAddr old_addr; old_addr.set_none_addr(); - ret = t3m_.compare_and_swap_tablet_pure_address_without_object(key, old_addr, addr); - ASSERT_EQ(common::OB_INVALID_ARGUMENT, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ret = t3m_.compare_and_swap_tablet(key, old_addr, addr); + ASSERT_EQ(common::OB_NOT_THE_OBJECT, ret); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_TRUE(handle.is_valid()); handle.reset(); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ret = t3m_.get_tablet(WashTabletPriority::WTP_HIGH, key, handle); @@ -543,22 +610,28 @@ TEST_F(TestTenantMetaMemMgr, test_tablet) tablet = handle.get_obj(); ASSERT_TRUE(nullptr != tablet); ASSERT_TRUE(tablet->pointer_hdl_.is_valid()); + /* mock empty tablet to del successfully */ + tablet->table_store_addr_.addr_.set_none_addr(); + tablet->storage_schema_addr_.addr_.set_none_addr(); + tablet->mds_data_.auto_inc_seq_.addr_.set_none_addr(); + tablet->rowkey_read_info_ = nullptr; tablet->tablet_meta_.ls_id_ = key.ls_id_; tablet->tablet_meta_.tablet_id_ = key.tablet_id_; handle.reset(); - ret = t3m_.try_wash_tablet(1); - ASSERT_EQ(common::OB_NOT_INIT, ret); + void *free_obj = nullptr; + ret = t3m_.try_wash_tablet(typeid(ObTenantMetaMemMgr::ObNormalTabletBuffer), free_obj); + ASSERT_EQ(common::OB_ITER_END, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ret = t3m_.del_tablet(key); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); ptr_hdl.reset(); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); } TEST_F(TestTenantMetaMemMgr, test_wash_tablet) @@ -574,9 +647,10 @@ TEST_F(TestTenantMetaMemMgr, test_wash_tablet) ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); ASSERT_EQ(OB_SUCCESS, ret); - ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); + ret = t3m_.create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle); + handle.t3m_ = &t3m_; // temporary code, use local t3m ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_TRUE(handle.is_valid()); @@ -584,15 +658,9 @@ TEST_F(TestTenantMetaMemMgr, test_wash_tablet) ASSERT_TRUE(nullptr != tablet); ASSERT_TRUE(tablet->pointer_hdl_.is_valid()); - // set tx data - ObTabletTxMultiSourceDataUnit &tx_data = tablet->tablet_meta_.tx_data_; - tx_data.tx_id_ = ObTabletCommon::FINAL_TX_ID; - share::SCN scn; - scn.convert_for_logservice(12345); - tx_data.tx_scn_ = scn; - tx_data.tablet_status_ = ObTabletStatus::NORMAL; - - ObTableHandleV2 table_handle; + ObSSTable sstable; + common::ObSEArray tablet_meta_write_ctxs; + common::ObSEArray sstable_meta_write_ctxs; checkpoint::ObCheckpointExecutor ckpt_executor; checkpoint::ObDataCheckpoint data_checkpoint; ObLS ls; @@ -607,9 +675,12 @@ TEST_F(TestTenantMetaMemMgr, test_wash_tablet) ret = freezer.init(&ls); ASSERT_EQ(common::OB_SUCCESS, ret); - ret = t3m_.acquire_sstable(table_handle); + ObTabletCreateSSTableParam param; + ret = ObTabletCreateDeleteHelper::build_create_sstable_param(table_schema, tablet_id, 100, param); + ASSERT_EQ(common::OB_SUCCESS, ret); + + ret = ObTabletCreateDeleteHelper::create_sstable(param, allocator_, sstable); ASSERT_EQ(common::OB_SUCCESS, ret); - table_handle.get_table()->set_table_type(ObITable::TableType::MAJOR_SSTABLE); share::SCN create_scn; create_scn.convert_from_ts(ObTimeUtility::fast_current_time()); @@ -617,40 +688,48 @@ TEST_F(TestTenantMetaMemMgr, test_wash_tablet) ObTabletID empty_tablet_id; ObTabletTableStoreFlag store_flag; store_flag.set_with_major_sstable(); - ret = tablet->init(ls_id_, tablet_id, tablet_id, empty_tablet_id, empty_tablet_id, + ret = tablet->init(allocator_, ls_id_, tablet_id, tablet_id, create_scn, create_scn.get_val_for_tx(), table_schema, - lib::Worker::CompatMode::MYSQL, store_flag, table_handle, &freezer); + lib::Worker::CompatMode::MYSQL, store_flag, &sstable, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); - ObMetaDiskAddr addr; - addr.first_id_ = 1; - addr.second_id_ = 2; - addr.offset_ = 0; - addr.size_ = 4096; - addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; + ObTabletHandle new_handle; + ASSERT_EQ(common::OB_SUCCESS, t3m_.acquire_tablet_from_pool(ObTabletPoolType::TP_NORMAL, WashTabletPriority::WTP_HIGH, key, new_handle)); + ASSERT_EQ(common::OB_SUCCESS, ObTabletPersister::persist_and_fill_tablet( + *tablet, allocator_, tablet_meta_write_ctxs, sstable_meta_write_ctxs, new_handle)); + ASSERT_EQ(common::OB_SUCCESS, ObTabletPersister::persist_4k_tablet(allocator_, new_handle)); - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); + ObMetaDiskAddr addr = new_handle.get_obj()->get_tablet_addr(); + ret = t3m_.compare_and_swap_tablet(key, new_handle, new_handle); + tablet = new_handle.get_obj(); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - handle.reset(); + void *free_obj = nullptr; + new_handle.reset(); ASSERT_EQ(1, tablet->get_ref()); - ret = t3m_.try_wash_tablet(1); + ret = t3m_.try_wash_tablet(typeid(ObTenantMetaMemMgr::ObNormalTabletBuffer), free_obj); ASSERT_EQ(common::OB_SUCCESS, ret); + ASSERT_EQ(free_obj, ObMetaObjBufferHelper::get_meta_obj_buffer_ptr(reinterpret_cast(tablet))); + t3m_.tablet_buffer_pool_.free_obj(free_obj); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ObMetaDiskAddr none_addr; none_addr.set_none_addr(); - ret = t3m_.compare_and_swap_tablet_pure_address_without_object(key, addr, none_addr); + ret = t3m_.compare_and_swap_tablet(key, addr, none_addr); ASSERT_EQ(common::OB_INVALID_ARGUMENT, ret); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); - ret = t3m_.tablet_map_.erase(key); + ObTabletHandle tmp_handle; + ret = t3m_.tablet_map_.erase(key, tmp_handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + tmp_handle.reset(); + gc_all_tablets(); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); } TEST_F(TestTenantMetaMemMgr, test_wash_inner_tablet) @@ -666,9 +745,10 @@ TEST_F(TestTenantMetaMemMgr, test_wash_inner_tablet) ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); ASSERT_EQ(OB_SUCCESS, ret); - ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); + ret = t3m_.create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle); + handle.t3m_ = &t3m_; // temporary code, use local t3m ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_TRUE(handle.is_valid()); @@ -676,7 +756,9 @@ TEST_F(TestTenantMetaMemMgr, test_wash_inner_tablet) ASSERT_TRUE(nullptr != tablet); ASSERT_TRUE(tablet->pointer_hdl_.is_valid()); - ObTableHandleV2 table_handle; + ObSSTable sstable; + common::ObSEArray tablet_meta_write_ctxs; + common::ObSEArray sstable_meta_write_ctxs; checkpoint::ObCheckpointExecutor ckpt_executor; checkpoint::ObDataCheckpoint data_checkpoint; ObLS ls; @@ -691,9 +773,12 @@ TEST_F(TestTenantMetaMemMgr, test_wash_inner_tablet) ret = freezer.init(&ls); ASSERT_EQ(common::OB_SUCCESS, ret); - ret = t3m_.acquire_sstable(table_handle); + ObTabletCreateSSTableParam param; + ret = ObTabletCreateDeleteHelper::build_create_sstable_param(table_schema, tablet_id, 100, param); + ASSERT_EQ(common::OB_SUCCESS, ret); + + ret = ObTabletCreateDeleteHelper::create_sstable(param, allocator_, sstable); ASSERT_EQ(common::OB_SUCCESS, ret); - table_handle.get_table()->set_table_type(ObITable::TableType::MAJOR_SSTABLE); share::SCN create_scn; create_scn.convert_from_ts(ObTimeUtility::fast_current_time()); @@ -701,52 +786,51 @@ TEST_F(TestTenantMetaMemMgr, test_wash_inner_tablet) ObTabletID empty_tablet_id; ObTabletTableStoreFlag store_flag; store_flag.set_with_major_sstable(); - ret = tablet->init(ls_id_, tablet_id, tablet_id, empty_tablet_id, empty_tablet_id, + ret = tablet->init(allocator_, ls_id_, tablet_id, tablet_id, create_scn, create_scn.get_val_for_tx(), table_schema, lib::Worker::CompatMode::MYSQL, - store_flag, table_handle, &freezer); + store_flag, &sstable, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); - // set tx data - ObTabletTxMultiSourceDataUnit &tx_data = tablet->tablet_meta_.tx_data_; - tx_data.tx_id_ = ObTabletCommon::FINAL_TX_ID; - share::SCN scn; - scn.convert_for_logservice(12345); - tx_data.tx_scn_ = scn; - tx_data.tablet_status_ = ObTabletStatus::NORMAL; + ObTabletHandle new_handle; + ASSERT_EQ(common::OB_SUCCESS, t3m_.acquire_tablet_from_pool(ObTabletPoolType::TP_NORMAL, WashTabletPriority::WTP_HIGH, key, new_handle)); + ASSERT_EQ(common::OB_SUCCESS, ObTabletPersister::persist_and_fill_tablet( + *tablet, allocator_, tablet_meta_write_ctxs, sstable_meta_write_ctxs, new_handle)); + ASSERT_EQ(common::OB_SUCCESS, ObTabletPersister::persist_4k_tablet(allocator_, new_handle)); - ObMetaDiskAddr addr; - addr.first_id_ = 1; - addr.second_id_ = 2; - addr.offset_ = 0; - addr.size_ = 4096; - addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; + ObMetaDiskAddr addr = new_handle.get_obj()->get_tablet_addr(); - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); + ret = t3m_.compare_and_swap_tablet(key, new_handle, new_handle); + tablet = new_handle.get_obj(); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - handle.reset(); + void *free_obj = nullptr; + new_handle.reset(); ASSERT_EQ(1, tablet->get_ref()); - ret = t3m_.try_wash_tablet(1); + ret = t3m_.try_wash_tablet(typeid(ObTenantMetaMemMgr::ObNormalTabletBuffer), free_obj); ASSERT_EQ(common::OB_SUCCESS, ret); + ASSERT_EQ(free_obj, ObMetaObjBufferHelper::get_meta_obj_buffer_ptr(reinterpret_cast(tablet))); + t3m_.tablet_buffer_pool_.free_obj(free_obj); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ObMetaDiskAddr mem_addr; ret = mem_addr.set_mem_addr(0, 0); ASSERT_EQ(common::OB_SUCCESS, ret); - ret = t3m_.compare_and_swap_tablet_pure_address_without_object(key, addr, mem_addr); + ret = t3m_.compare_and_swap_tablet(key, addr, mem_addr); ASSERT_EQ(common::OB_INVALID_ARGUMENT, ret); - ret = t3m_.tablet_map_.erase(key); + ObTabletHandle tmp_handle; + ret = t3m_.tablet_map_.erase(key, tmp_handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + tmp_handle.reset(); + gc_all_tablets(); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); } - TEST_F(TestTenantMetaMemMgr, test_wash_no_sstable_tablet) { int ret = OB_SUCCESS; @@ -760,9 +844,10 @@ TEST_F(TestTenantMetaMemMgr, test_wash_no_sstable_tablet) ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); ASSERT_EQ(OB_SUCCESS, ret); - ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); + ret = t3m_.create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle); + handle.t3m_ = &t3m_; // temporary code, use local t3m ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_TRUE(handle.is_valid()); @@ -770,15 +855,8 @@ TEST_F(TestTenantMetaMemMgr, test_wash_no_sstable_tablet) ASSERT_TRUE(nullptr != tablet); ASSERT_TRUE(tablet->pointer_hdl_.is_valid()); - // set tx data - ObTabletTxMultiSourceDataUnit &tx_data = tablet->tablet_meta_.tx_data_; - tx_data.tx_id_ = ObTabletCommon::FINAL_TX_ID; - share::SCN scn; - scn.convert_for_logservice(12345); - tx_data.tx_scn_ = scn; - tx_data.tablet_status_ = ObTabletStatus::NORMAL; - - ObTableHandleV2 table_handle; + common::ObSEArray tablet_meta_write_ctxs; + common::ObSEArray sstable_meta_write_ctxs; checkpoint::ObCheckpointExecutor ckpt_executor; checkpoint::ObDataCheckpoint data_checkpoint; ObLS ls; @@ -799,38 +877,43 @@ TEST_F(TestTenantMetaMemMgr, test_wash_no_sstable_tablet) ObTabletID empty_tablet_id; ObTabletTableStoreFlag store_flag; store_flag.set_with_major_sstable(); - ret = tablet->init(ls_id_, tablet_id, tablet_id, empty_tablet_id, empty_tablet_id, + ret = tablet->init(allocator_, ls_id_, tablet_id, tablet_id, create_scn, create_scn.get_val_for_tx(), table_schema, lib::Worker::CompatMode::MYSQL, - store_flag, table_handle, &freezer); + store_flag, nullptr, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); - ObMetaDiskAddr addr; - addr.first_id_ = 1; - addr.second_id_ = 2; - addr.offset_ = 0; - addr.size_ = 4096; - addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; + ObTabletHandle new_handle; + ASSERT_EQ(common::OB_SUCCESS, t3m_.acquire_tablet_from_pool(ObTabletPoolType::TP_NORMAL, WashTabletPriority::WTP_HIGH, key, new_handle)); + ASSERT_EQ(common::OB_SUCCESS, ObTabletPersister::persist_and_fill_tablet( + *tablet, allocator_, tablet_meta_write_ctxs, sstable_meta_write_ctxs, new_handle)); + ASSERT_EQ(common::OB_SUCCESS, ObTabletPersister::persist_4k_tablet(allocator_, new_handle)); - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); + ret = t3m_.compare_and_swap_tablet(key, new_handle, new_handle); ASSERT_EQ(common::OB_SUCCESS, ret); + tablet = new_handle.get_obj(); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - handle.reset(); + void *free_obj = nullptr; + new_handle.reset(); ASSERT_EQ(1, tablet->get_ref()); - ret = t3m_.try_wash_tablet(1); + ret = t3m_.try_wash_tablet(typeid(ObTenantMetaMemMgr::ObNormalTabletBuffer), free_obj); ASSERT_EQ(common::OB_SUCCESS, ret); + t3m_.tablet_buffer_pool_.free_obj(free_obj); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); - ret = t3m_.tablet_map_.erase(key); + ObTabletHandle tmp_handle; + ret = t3m_.tablet_map_.erase(key, tmp_handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + tmp_handle.reset(); + gc_all_tablets(); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); } -TEST_F(TestTenantMetaMemMgr, test_not_wash_in_tx_tablet) +/*TEST_F(TestTenantMetaMemMgr, test_not_wash_in_tx_tablet) { int ret = OB_SUCCESS; const ObTabletID tablet_id(1234567890); @@ -843,9 +926,10 @@ TEST_F(TestTenantMetaMemMgr, test_not_wash_in_tx_tablet) ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); ASSERT_EQ(common::OB_SUCCESS, ret); - ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); + ret = t3m_.create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle); + handle.t3m_ = &t3m_; // temporary code, use local t3m ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_TRUE(handle.is_valid()); @@ -853,7 +937,7 @@ TEST_F(TestTenantMetaMemMgr, test_not_wash_in_tx_tablet) ASSERT_TRUE(nullptr != tablet); ASSERT_TRUE(tablet->pointer_hdl_.is_valid()); - ObTableHandleV2 table_handle; + common::ObSEArray all_write_ctxs; checkpoint::ObCheckpointExecutor ckpt_executor; checkpoint::ObDataCheckpoint data_checkpoint; ObLS ls; @@ -874,63 +958,54 @@ TEST_F(TestTenantMetaMemMgr, test_not_wash_in_tx_tablet) ObTabletID empty_tablet_id; ObTabletTableStoreFlag store_flag; store_flag.set_with_major_sstable(); - ret = tablet->init(ls_id_, tablet_id, tablet_id, empty_tablet_id, empty_tablet_id, + ret = tablet->init(allocator_, ls_id_, tablet_id, tablet_id, create_scn, create_scn.get_val_for_tx(), table_schema, lib::Worker::CompatMode::MYSQL, - store_flag, table_handle, &freezer); + store_flag, nullptr, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); - ObMetaDiskAddr addr; - addr.first_id_ = 1; - addr.second_id_ = 2; - addr.offset_ = 0; - addr.size_ = 4096; - addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; + ObTabletHandle new_handle; + ASSERT_EQ(common::OB_SUCCESS, t3m_.acquire_tablet_from_pool(ObTabletPoolType::TP_NORMAL, WashTabletPriority::WTP_HIGH, key, new_handle)); + ASSERT_EQ(common::OB_SUCCESS, ObTabletPersister::persist_and_fill_tablet( + *tablet, allocator_, all_write_ctxs, new_handle)); + ASSERT_EQ(common::OB_SUCCESS, ObTabletPersister::persist_4k_tablet(allocator_, new_handle)); - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); + ret = t3m_.compare_and_swap_tablet(key, new_handle, new_handle); + tablet = new_handle.get_obj(); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); + new_handle.reset(); - // set tx data, status is DELETING - ObTabletTxMultiSourceDataUnit &tx_data = tablet->tablet_meta_.tx_data_; - tx_data.tx_id_ = 666; - share::SCN scn; - scn.convert_for_logservice(888); - tx_data.tx_scn_ = scn; - tx_data.tablet_status_ = ObTabletStatus::DELETING; - ret = handle.get_obj()->set_tx_data_in_tablet_pointer(tx_data); - ASSERT_EQ(common::OB_SUCCESS, ret); + // get tablet pointer + ObTabletPointer *tablet_ptr = static_cast(handle.get_obj()->pointer_hdl_.get_resource_ptr()); + + // pin tabet ASSERT_EQ(common::OB_SUCCESS, t3m_.insert_pinned_tablet(key)); - handle.reset(); - ASSERT_EQ(1, tablet->get_ref()); - ret = t3m_.try_wash_tablet(1); - ASSERT_EQ(common::OB_ALLOCATE_MEMORY_FAILED, ret); // wash failed + void *free_obj = nullptr; + ret = t3m_.try_wash_tablet(typeid(ObTenantMetaMemMgr::ObNormalTabletBuffer), free_obj); + ASSERT_EQ(common::OB_SUCCESS, ret); + ASSERT_EQ(nullptr, free_obj); // pinned tablet can't be washed. ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(1, t3m_.tablet_buffer_pool_.inner_used_num_); - // set status to DELETED - tx_data.tx_id_ = ObTabletCommon::FINAL_TX_ID; - scn.convert_for_logservice(999); - tx_data.tx_scn_ = scn; - tx_data.tablet_status_ = ObTabletStatus::DELETED; - ret = t3m_.get_tablet(WashTabletPriority::WTP_HIGH, key, handle); - ASSERT_EQ(common::OB_SUCCESS, ret); - ret = handle.get_obj()->set_tx_data_in_tablet_pointer(tx_data); - ASSERT_EQ(common::OB_SUCCESS, ret); - handle.reset(); + // unpin tablet ASSERT_EQ(common::OB_SUCCESS, t3m_.erase_pinned_tablet(key)); - - ret = t3m_.try_wash_tablet(1); + ret = t3m_.try_wash_tablet(typeid(ObTenantMetaMemMgr::ObNormalTabletBuffer), free_obj); ASSERT_EQ(common::OB_SUCCESS, ret); // wash succeeded + ASSERT_NE(nullptr, free_obj); + t3m_.tablet_buffer_pool_.free_obj(free_obj); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); - ret = t3m_.tablet_map_.erase(key); + ObTabletHandle tmp_handle; + ret = t3m_.tablet_map_.erase(key, tmp_handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); -} + tmp_handle.reset(); + gc_all_tablets(); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); +}*/ TEST_F(TestTenantMetaMemMgr, test_get_tablet_with_allocator) { @@ -945,9 +1020,10 @@ TEST_F(TestTenantMetaMemMgr, test_get_tablet_with_allocator) ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); ASSERT_EQ(OB_SUCCESS, ret); - ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); + ret = t3m_.create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle); + handle.t3m_ = &t3m_; // temporary code, use local t3m ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_TRUE(handle.is_valid()); @@ -955,14 +1031,9 @@ TEST_F(TestTenantMetaMemMgr, test_get_tablet_with_allocator) ASSERT_TRUE(nullptr != tablet); ASSERT_TRUE(tablet->pointer_hdl_.is_valid()); - ObTabletTxMultiSourceDataUnit &tx_data = tablet->tablet_meta_.tx_data_; - tx_data.tx_id_ = ObTabletCommon::FINAL_TX_ID; - share::SCN scn; - scn.convert_for_logservice(12345); - tx_data.tx_scn_ = scn; - tx_data.tablet_status_ = ObTabletStatus::NORMAL; - - ObTableHandleV2 table_handle; + ObSSTable sstable; + common::ObSEArray tablet_meta_write_ctxs; + common::ObSEArray sstable_meta_write_ctxs; checkpoint::ObCheckpointExecutor ckpt_executor; checkpoint::ObDataCheckpoint data_checkpoint; ObLS ls; @@ -972,47 +1043,17 @@ TEST_F(TestTenantMetaMemMgr, test_get_tablet_with_allocator) MockObLogHandler log_handler; ObFreezer freezer; ObTableSchema table_schema; - ObTabletCreateSSTableParam param; prepare_data_schema(table_schema); ret = freezer.init(&ls); ASSERT_EQ(common::OB_SUCCESS, ret); - ret = t3m_.acquire_sstable(table_handle); + ObTabletCreateSSTableParam param; + ret = ObTabletCreateDeleteHelper::build_create_sstable_param(table_schema, tablet_id, 100, param); + ASSERT_EQ(common::OB_SUCCESS, ret); + + ret = ObTabletCreateDeleteHelper::create_sstable(param, allocator_, sstable); ASSERT_EQ(common::OB_SUCCESS, ret); - const int64_t multi_version_col_cnt = ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); - param.table_key_.table_type_ = ObITable::TableType::MAJOR_SSTABLE; - param.table_key_.tablet_id_ = tablet_id; - param.table_key_.version_range_.base_version_ = ObVersionRange::MIN_VERSION; - param.table_key_.version_range_.snapshot_version_ = 1; - param.schema_version_ = table_schema.get_schema_version(); - param.create_snapshot_version_ = 0; - param.progressive_merge_round_ = table_schema.get_progressive_merge_round(); - param.progressive_merge_step_ = 0; - param.table_mode_ = table_schema.get_table_mode_struct(); - param.index_type_ = table_schema.get_index_type(); - param.rowkey_column_cnt_ = table_schema.get_rowkey_column_num() - + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); - param.root_block_addr_.set_none_addr(); - param.data_block_macro_meta_addr_.set_none_addr(); - param.root_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; - param.latest_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; - param.data_index_tree_height_ = 0; - param.index_blocks_cnt_ = 0; - param.data_blocks_cnt_ = 0; - param.micro_block_cnt_ = 0; - param.use_old_macro_block_count_ = 0; - param.column_cnt_ = table_schema.get_column_count() + multi_version_col_cnt; - param.data_checksum_ = 0; - param.occupy_size_ = 0; - param.ddl_scn_.set_min(); - param.filled_tx_scn_.set_min(); - param.original_size_ = 0; - param.compressor_type_ = ObCompressorType::NONE_COMPRESSOR; - param.encrypt_id_ = 0; - param.master_key_id_ = 0; - ASSERT_EQ(OB_SUCCESS, ObSSTableMergeRes::fill_column_checksum_for_empty_major(param.column_cnt_, param.column_checksums_)); - ASSERT_EQ(OB_SUCCESS, static_cast(table_handle.get_table())->init(param, &t3m_.get_tenant_allocator())); share::SCN create_scn; create_scn.convert_from_ts(ObTimeUtility::fast_current_time()); @@ -1020,36 +1061,45 @@ TEST_F(TestTenantMetaMemMgr, test_get_tablet_with_allocator) ObTabletID empty_tablet_id; ObTabletTableStoreFlag store_flag; store_flag.set_with_major_sstable(); - ret = tablet->init(ls_id_, tablet_id, tablet_id, empty_tablet_id, empty_tablet_id, + ret = tablet->init(allocator_, ls_id_, tablet_id, tablet_id, create_scn, create_scn.get_val_for_tx(), table_schema, - lib::Worker::CompatMode::MYSQL, store_flag, table_handle, &freezer); + lib::Worker::CompatMode::MYSQL, store_flag, &sstable, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); - ObMetaDiskAddr addr; - ret = ObTabletSlogHelper::write_create_tablet_slog(handle, addr); - ASSERT_EQ(common::OB_SUCCESS, ret); + ObTabletHandle new_handle; + ASSERT_EQ(common::OB_SUCCESS, t3m_.acquire_tablet_from_pool(ObTabletPoolType::TP_NORMAL, WashTabletPriority::WTP_HIGH, key, new_handle)); + ASSERT_EQ(common::OB_SUCCESS, ObTabletPersister::persist_and_fill_tablet( + *tablet, allocator_, tablet_meta_write_ctxs, sstable_meta_write_ctxs, new_handle)); + ASSERT_EQ(common::OB_SUCCESS, ObTabletPersister::persist_4k_tablet(allocator_, new_handle)); - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); + ret = t3m_.compare_and_swap_tablet(key, new_handle, new_handle); + tablet = new_handle.get_obj(); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(1, t3m_.tablet_buffer_pool_.inner_used_num_); - handle.reset(); + void *free_obj = nullptr; + new_handle.reset(); ASSERT_EQ(1, tablet->get_ref()); - ret = t3m_.try_wash_tablet(1); + ret = t3m_.try_wash_tablet(typeid(ObTenantMetaMemMgr::ObNormalTabletBuffer), free_obj); ASSERT_EQ(common::OB_SUCCESS, ret); + ASSERT_EQ(free_obj, ObMetaObjBufferHelper::get_meta_obj_buffer_ptr(reinterpret_cast(tablet))); + t3m_.tablet_buffer_pool_.free_obj(free_obj); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); common::ObArenaAllocator allocator; ASSERT_EQ(common::OB_SUCCESS, t3m_.get_tablet_with_allocator(WashTabletPriority::WTP_HIGH, key, allocator, handle)); ASSERT_TRUE(handle.is_valid()); - ret = t3m_.tablet_map_.erase(key); + ObTabletHandle tmp_handle; + ret = t3m_.tablet_map_.erase(key, tmp_handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + tmp_handle.reset(); + gc_all_tablets(); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); } TEST_F(TestTenantMetaMemMgr, test_wash_mem_tablet) @@ -1066,9 +1116,10 @@ TEST_F(TestTenantMetaMemMgr, test_wash_mem_tablet) ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); ASSERT_EQ(OB_SUCCESS, ret); - ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); + ret = t3m_.create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle); + handle.t3m_ = &t3m_; // temporary code, use local t3m ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_TRUE(handle.is_valid()); @@ -1076,13 +1127,7 @@ TEST_F(TestTenantMetaMemMgr, test_wash_mem_tablet) ASSERT_TRUE(nullptr != tablet); ASSERT_TRUE(tablet->pointer_hdl_.is_valid()); - // set tx data - ObTabletTxMultiSourceDataUnit &tx_data = tablet->tablet_meta_.tx_data_; - tx_data.tx_id_ = ObTabletCommon::FINAL_TX_ID; - tx_data.tx_scn_.convert_for_logservice(12345); - tx_data.tablet_status_ = ObTabletStatus::NORMAL; - - ObTableHandleV2 table_handle; + ObSSTable sstable; checkpoint::ObCheckpointExecutor ckpt_executor; checkpoint::ObDataCheckpoint data_checkpoint; ObLS ls; @@ -1098,8 +1143,6 @@ TEST_F(TestTenantMetaMemMgr, test_wash_mem_tablet) ret = freezer.init(&ls); ASSERT_EQ(common::OB_SUCCESS, ret); - ret = t3m_.acquire_sstable(table_handle); - ASSERT_EQ(common::OB_SUCCESS, ret); const int64_t multi_version_col_cnt = ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); param.table_key_.table_type_ = ObITable::TableType::MAJOR_SSTABLE; param.table_key_.tablet_id_ = tablet_id; @@ -1132,7 +1175,7 @@ TEST_F(TestTenantMetaMemMgr, test_wash_mem_tablet) param.encrypt_id_ = 0; param.master_key_id_ = 0; ASSERT_EQ(OB_SUCCESS, ObSSTableMergeRes::fill_column_checksum_for_empty_major(param.column_cnt_, param.column_checksums_)); - ASSERT_EQ(OB_SUCCESS, static_cast(table_handle.get_table())->init(param, &t3m_.get_tenant_allocator())); + ASSERT_EQ(OB_SUCCESS, sstable.init(param, &allocator_)); share::SCN create_scn; create_scn.convert_from_ts(ObTimeUtility::fast_current_time()); @@ -1140,9 +1183,9 @@ TEST_F(TestTenantMetaMemMgr, test_wash_mem_tablet) ObTabletID empty_tablet_id; ObTabletTableStoreFlag store_flag; store_flag.set_with_major_sstable(); - ret = tablet->init(ls_id_, tablet_id, tablet_id, empty_tablet_id, empty_tablet_id, + ret = tablet->init(allocator_, ls_id_, tablet_id, tablet_id, create_scn, create_scn.get_val_for_tx(), table_schema, - lib::Worker::CompatMode::MYSQL, store_flag, table_handle, &freezer); + lib::Worker::CompatMode::MYSQL, store_flag, &sstable, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); @@ -1150,28 +1193,34 @@ TEST_F(TestTenantMetaMemMgr, test_wash_mem_tablet) addr.offset_ = 0; addr.size_ = 4096; addr.type_ = ObMetaDiskAddr::DiskType::MEM; + handle.get_obj()->set_tablet_addr(addr); - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); + ret = t3m_.compare_and_swap_tablet(key, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); + void *free_obj = nullptr; handle.reset(); ASSERT_EQ(1, tablet->get_ref()); - ret = t3m_.try_wash_tablet(1); + ret = t3m_.try_wash_tablet(typeid(ObTenantMetaMemMgr::ObNormalTabletBuffer), free_obj); ASSERT_EQ(common::OB_SUCCESS, ret); + ASSERT_EQ(nullptr, free_obj); // memory address tablet can't be washed. ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ObMetaDiskAddr none_addr; none_addr.set_none_addr(); - ret = t3m_.compare_and_swap_tablet_pure_address_without_object(key, addr, none_addr); + ret = t3m_.compare_and_swap_tablet(key, addr, none_addr); ASSERT_EQ(common::OB_INVALID_ARGUMENT, ret); - ret = t3m_.tablet_map_.erase(key); + ObTabletHandle tmp_handle; + ret = t3m_.tablet_map_.erase(key, tmp_handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); + tmp_handle.reset(); + gc_all_tablets(); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); } TEST_F(TestTenantMetaMemMgr, test_replace_tablet) @@ -1187,39 +1236,26 @@ TEST_F(TestTenantMetaMemMgr, test_replace_tablet) ret = ls_svr->get_ls(ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD); ASSERT_EQ(OB_SUCCESS, ret); - ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); + ret = t3m_.create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle); + handle.t3m_ = &t3m_; // temporary code, use local t3m ASSERT_EQ(common::OB_SUCCESS, ret); tablet = handle.get_obj(); ASSERT_TRUE(nullptr != tablet); - tablet->inc_ref(); handle.reset(); ASSERT_TRUE(!handle.is_valid()); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ret = t3m_.del_tablet(key); ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); - t3m_.release_tablet(tablet); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); - ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); - - tablet->dec_ref(); - t3m_.release_tablet(tablet); - tablet = nullptr; - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); - ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); - - t3m_.release_tablet(tablet); - ASSERT_EQ(0, t3m_.tablet_pool_.inner_used_num_); - ASSERT_EQ(0, t3m_.tablet_map_.map_.size()); - - ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); + ret = t3m_.create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle); + handle.t3m_ = &t3m_; // temporary code, use local t3m ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); ASSERT_TRUE(handle.is_valid()); @@ -1233,22 +1269,17 @@ TEST_F(TestTenantMetaMemMgr, test_replace_tablet) ASSERT_TRUE(!tmp_handle.is_valid()); ObMetaDiskAddr addr; - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); - ASSERT_EQ(common::OB_INVALID_ARGUMENT, ret); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); - ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_TRUE(handle.is_valid()); - addr.first_id_ = 1; addr.second_id_ = 2; addr.offset_ = 0; addr.size_ = 4096; addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; + handle.get_obj()->set_tablet_addr(addr); - ret = t3m_.compare_and_swap_tablet(key, addr, handle, handle); + ret = t3m_.compare_and_swap_tablet(key, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ObMetaPointerHandle ptr_hdl(t3m_.tablet_map_); ret = t3m_.tablet_map_.map_.get_refactored(key, ptr_hdl.ptr_); @@ -1256,7 +1287,7 @@ TEST_F(TestTenantMetaMemMgr, test_replace_tablet) ret = t3m_.tablet_map_.inc_handle_ref(ptr_hdl.ptr_); ASSERT_TRUE(addr == ptr_hdl.ptr_->ptr_->phy_addr_); ASSERT_TRUE(handle.obj_ == ptr_hdl.ptr_->ptr_->obj_.ptr_); - ASSERT_TRUE(handle.obj_pool_ == ptr_hdl.ptr_->ptr_->obj_.pool_); + ASSERT_TRUE(handle.allocator_ == ptr_hdl.ptr_->ptr_->obj_.allocator_); ret = t3m_.get_tablet(WashTabletPriority::WTP_HIGH, key, handle); ASSERT_EQ(common::OB_SUCCESS, ret); @@ -1270,17 +1301,17 @@ TEST_F(TestTenantMetaMemMgr, test_replace_tablet) handle.reset(); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(0, t3m_.tablet_buffer_pool_.inner_used_num_); ObTabletHandle old_handle; ret = t3m_.get_tablet(WashTabletPriority::WTP_HIGH, key, old_handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_TRUE(old_handle.is_valid()); - ret = t3m_.acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle, false); + ret = t3m_.acquire_tablet_from_pool(ObTabletPoolType::TP_NORMAL, WashTabletPriority::WTP_HIGH, key, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(2, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(1, t3m_.tablet_buffer_pool_.inner_used_num_); ASSERT_TRUE(handle.is_valid()); tablet = handle.get_obj(); @@ -1294,48 +1325,30 @@ TEST_F(TestTenantMetaMemMgr, test_replace_tablet) addr.size_ = 4096; addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; - ret = t3m_.compare_and_swap_tablet(key, addr, old_handle, handle); + tablet->set_tablet_addr(addr); + ret = t3m_.compare_and_swap_tablet(key, old_handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); - ASSERT_EQ(2, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(1, t3m_.tablet_buffer_pool_.inner_used_num_); old_handle.reset(); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(1, t3m_.tablet_buffer_pool_.inner_used_num_); handle.reset(); - ASSERT_EQ(1, t3m_.tablet_pool_.inner_used_num_); + ASSERT_EQ(1, t3m_.tablet_buffer_pool_.inner_used_num_); } TEST_F(TestTenantMetaMemMgr, test_multi_tablet) { const int64_t thread_cnt = 16; ObTenantBase *tenant_base = MTL_CTX(); - TestConcurrentT3M multi_thread(thread_cnt, t3m_, tenant_base); + TestConcurrentT3M multi_thread(thread_cnt, t3m_, tenant_base, allocator_); int ret = multi_thread.start(); ASSERT_EQ(OB_SUCCESS, ret); multi_thread.wait(); } -TEST_F(TestTenantMetaMemMgr, test_last_min_sstable_set) -{ - ObTableHandleV2 table_handle; - ASSERT_EQ(OB_SUCCESS, t3m_.acquire_sstable(table_handle)); - ASSERT_TRUE(nullptr != table_handle.get_table()); - ObITable *table = static_cast(table_handle.get_table()); - table->key_.tablet_id_ = 1; - table->key_.scn_range_.start_scn_.set_base(); - table->key_.scn_range_.end_scn_.convert_for_tx(100); - table->key_.table_type_ = ObITable::TableType::REMOTE_LOGICAL_MINOR_SSTABLE; - - ASSERT_EQ(OB_SUCCESS, t3m_.record_min_minor_sstable(ls_id_, table_handle)); - ASSERT_EQ(1, t3m_.last_min_minor_sstable_set_.size()); - - table->key_.scn_range_.end_scn_.convert_for_tx(400); - ASSERT_EQ(OB_SUCCESS, t3m_.record_min_minor_sstable(ls_id_, table_handle)); - ASSERT_EQ(1, t3m_.last_min_minor_sstable_set_.size()); -} - TEST_F(TestTenantMetaMemMgr, test_tablet_wash_priority) { ObTabletHandle handle; @@ -1370,27 +1383,25 @@ TEST_F(TestTenantMetaMemMgr, test_table_gc) ASSERT_NE(nullptr, t3m_.pool_arr_[static_cast(type)]); } for (type = ObITable::TableType::MAJOR_SSTABLE; type < ObITable::TableType::MAX_TABLE_TYPE; type = (ObITable::TableType)(type + 1)) { - ASSERT_NE(nullptr, t3m_.pool_arr_[static_cast(type)]); + if (type != ObITable::TableType::DDL_MEM_SSTABLE) { + ASSERT_EQ(nullptr, t3m_.pool_arr_[static_cast(type)]); + } } // check the count of tables in every pool before acquirement ASSERT_EQ(0, t3m_.memtable_pool_.inner_used_num_); - ASSERT_EQ(0, t3m_.sstable_pool_.inner_used_num_); ASSERT_EQ(0, t3m_.tx_data_memtable_pool_.inner_used_num_); ASSERT_EQ(0, t3m_.tx_ctx_memtable_pool_.inner_used_num_); ASSERT_EQ(0, t3m_.lock_memtable_pool_.inner_used_num_); // acquire tables and set table_type - ObTableHandleV2 sstable_handle; ObTableHandleV2 memtable_handle; ObTableHandleV2 tx_data_memtable_handle; ObTableHandleV2 tx_ctx_memtable_handle; ObTableHandleV2 lock_memtable_handle; - ASSERT_EQ(OB_SUCCESS, t3m_.acquire_sstable(sstable_handle)); ASSERT_EQ(OB_SUCCESS, t3m_.acquire_memtable(memtable_handle)); ASSERT_EQ(OB_SUCCESS, t3m_.acquire_tx_data_memtable(tx_data_memtable_handle)); ASSERT_EQ(OB_SUCCESS, t3m_.acquire_tx_ctx_memtable(tx_ctx_memtable_handle)); ASSERT_EQ(OB_SUCCESS, t3m_.acquire_lock_memtable(lock_memtable_handle)); - sstable_handle.table_->set_table_type(ObITable::TableType::MAJOR_SSTABLE); memtable_handle.table_->set_table_type(ObITable::TableType::DATA_MEMTABLE); tx_data_memtable_handle.table_->set_table_type(ObITable::TableType::TX_DATA_MEMTABLE); tx_ctx_memtable_handle.table_->set_table_type(ObITable::TableType::TX_CTX_MEMTABLE); @@ -1398,13 +1409,11 @@ TEST_F(TestTenantMetaMemMgr, test_table_gc) // check the count of tables in every pool before reset ASSERT_EQ(1, t3m_.memtable_pool_.inner_used_num_); - ASSERT_EQ(1, t3m_.sstable_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tx_data_memtable_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tx_ctx_memtable_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.lock_memtable_pool_.inner_used_num_); // reset all handles - sstable_handle.reset(); memtable_handle.reset(); tx_data_memtable_handle.reset(); tx_ctx_memtable_handle.reset(); @@ -1412,13 +1421,12 @@ TEST_F(TestTenantMetaMemMgr, test_table_gc) // check the count of tables in every pool after reset ASSERT_EQ(1, t3m_.memtable_pool_.inner_used_num_); - ASSERT_EQ(1, t3m_.sstable_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tx_data_memtable_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.tx_ctx_memtable_pool_.inner_used_num_); ASSERT_EQ(1, t3m_.lock_memtable_pool_.inner_used_num_); // check the count of tables in free queue - ASSERT_EQ(5, t3m_.free_tables_queue_.size()); + ASSERT_EQ(4, t3m_.free_tables_queue_.size()); // recycle all tables bool all_table_cleaned = false; // no use @@ -1426,7 +1434,6 @@ TEST_F(TestTenantMetaMemMgr, test_table_gc) // check the count after gc ASSERT_EQ(0, t3m_.memtable_pool_.inner_used_num_); - ASSERT_EQ(0, t3m_.sstable_pool_.inner_used_num_); ASSERT_EQ(0, t3m_.tx_data_memtable_pool_.inner_used_num_); ASSERT_EQ(0, t3m_.tx_ctx_memtable_pool_.inner_used_num_); ASSERT_EQ(0, t3m_.lock_memtable_pool_.inner_used_num_); @@ -1483,6 +1490,69 @@ TEST_F(TestTenantMetaMemMgr, test_heap) ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(0, heap.count()); } + +TEST_F(TestTenantMetaMemMgr, test_full_tablet_queue) +{ + ObFullTabletCreator full_creator; + ObTablet *tmp_tablet; + ASSERT_EQ(OB_SUCCESS, full_creator.init(500)); + ASSERT_NE(nullptr, tmp_tablet = OB_NEWx(ObTablet, &allocator_)); + MacroBlockId tmp_id; + tmp_id.second_id_ = 100; + ASSERT_EQ(OB_SUCCESS, tmp_tablet->tablet_addr_.set_mem_addr(0, 2112)); + tmp_tablet->inc_ref(); + ObTabletHandle tablet_handle; + tablet_handle.set_obj(tmp_tablet, &allocator_, &t3m_); + tablet_handle.set_wash_priority(WashTabletPriority::WTP_LOW); + + ASSERT_FALSE(tmp_tablet->is_valid()); // test invalid tablet + ASSERT_EQ(OB_INVALID_ARGUMENT, full_creator.push_tablet_to_queue(tablet_handle)); + ASSERT_EQ(0, full_creator.persist_queue_cnt_); + + // mock valid empty shell tablet + tmp_tablet->table_store_addr_.addr_.set_none_addr(); + tmp_tablet->storage_schema_addr_.addr_.set_none_addr(); + tmp_tablet->mds_data_.auto_inc_seq_.addr_.set_none_addr(); + tmp_tablet->rowkey_read_info_ = nullptr; + ASSERT_TRUE(tmp_tablet->is_valid()); + + ASSERT_EQ(OB_SUCCESS, tmp_tablet->tablet_addr_.set_block_addr(tmp_id, 0, 2112)); // test addr + ASSERT_EQ(OB_INVALID_ARGUMENT, full_creator.push_tablet_to_queue(tablet_handle)); + ASSERT_EQ(0, full_creator.persist_queue_cnt_); + + ASSERT_EQ(OB_SUCCESS, tmp_tablet->tablet_addr_.set_mem_addr(0, 2112)); + ASSERT_EQ(OB_SUCCESS, full_creator.push_tablet_to_queue(tablet_handle)); + ASSERT_EQ(1, full_creator.persist_queue_cnt_); + ASSERT_EQ(OB_SUCCESS, tmp_tablet->tablet_addr_.set_block_addr(tmp_id, 0, 2112)); + ASSERT_EQ(OB_SUCCESS, full_creator.remove_tablet_from_queue(tablet_handle)); // skip block + ASSERT_EQ(1, full_creator.persist_queue_cnt_); + + ASSERT_EQ(OB_SUCCESS, tmp_tablet->tablet_addr_.set_mem_addr(0, 2112)); + ASSERT_EQ(OB_SUCCESS, full_creator.remove_tablet_from_queue(tablet_handle)); + ASSERT_EQ(0, full_creator.persist_queue_cnt_); + ASSERT_EQ(full_creator.transform_head_.get_obj(), full_creator.transform_tail_.get_obj()); + ASSERT_FALSE(full_creator.transform_tail_.is_valid()); + + ASSERT_EQ(OB_SUCCESS, full_creator.push_tablet_to_queue(tablet_handle)); + ASSERT_EQ(1, full_creator.persist_queue_cnt_); + ASSERT_EQ(full_creator.transform_head_.get_obj(), full_creator.transform_tail_.get_obj()); + ASSERT_EQ(full_creator.transform_head_.get_obj(), tablet_handle.get_obj()); + ASSERT_FALSE(tablet_handle.get_obj()->next_full_tablet_guard_.is_valid()); + + + ASSERT_EQ(OB_SUCCESS, full_creator.pop_tablet(tablet_handle)); + ASSERT_EQ(0, full_creator.persist_queue_cnt_); + ASSERT_FALSE(tablet_handle.get_obj()->next_full_tablet_guard_.is_valid()); + ASSERT_EQ(full_creator.transform_head_.get_obj(), full_creator.transform_tail_.get_obj()); + ASSERT_FALSE(full_creator.transform_tail_.is_valid()); + + ASSERT_EQ(OB_ITER_END, full_creator.pop_tablet(tablet_handle)); + ASSERT_FALSE(full_creator.transform_head_.is_valid()); + + tablet_handle.obj_ = nullptr; // do not use handle to gc invalid tablet + tablet_handle.reset(); +} + } // end namespace storage } // end namespace oceanbase diff --git a/mittest/mtlenv/storage/test_tenant_module_env.cpp b/mittest/mtlenv/storage/test_tenant_module_env.cpp index bcfab2da8..fd10ccb05 100644 --- a/mittest/mtlenv/storage/test_tenant_module_env.cpp +++ b/mittest/mtlenv/storage/test_tenant_module_env.cpp @@ -28,6 +28,10 @@ public: { MockTenantModuleEnv::get_instance().destroy(); } + void SetUp() + { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); + } }; TEST_F(TestTenantModuleEnv, basic) diff --git a/mittest/mtlenv/storage/test_trans.cpp b/mittest/mtlenv/storage/test_trans.cpp index ece2256b4..e0b61e443 100644 --- a/mittest/mtlenv/storage/test_trans.cpp +++ b/mittest/mtlenv/storage/test_trans.cpp @@ -99,6 +99,11 @@ public: static void SetUpTestCase() { LOG_INFO("SetUpTestCase"); + ASSERT_EQ(OB_SUCCESS, omt::ObTenantConfigMgr::get_instance().add_tenant_config(MTL_ID())); + uint64_t version = cal_version(4, 2, 0, 0); + ASSERT_EQ(OB_SUCCESS, ObClusterVersion::get_instance().init(version)); + ObClusterVersion::get_instance().tenant_config_mgr_ = &omt::ObTenantConfigMgr::get_instance(); + ASSERT_EQ(OB_SUCCESS, MockTenantModuleEnv::get_instance().init()); SAFE_DESTROY_INSTANCE.init(); SAFE_DESTROY_INSTANCE.start(); @@ -113,11 +118,16 @@ public: MockTenantModuleEnv::get_instance().destroy(); } + void SetUp() + { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); + } void create_ls(uint64_t tenant_id, ObLSID &ls_id, ObLS *&ls); void insert_rows(ObLSID &ls_id, ObTabletID &tablet_id, ObTxDesc &tx_desc, ObTxReadSnapshot snapshot, const char* in_str); void prepare_tx_desc(ObTxDesc *&tx_desc, ObTxReadSnapshot &snapshot); private: static share::schema::ObTableSchema table_schema_; + common::ObArenaAllocator allocator_; }; share::schema::ObTableSchema TestTrans::table_schema_; @@ -218,11 +228,14 @@ TEST_F(TestTrans, create_ls_and_tablet) create_ls(tenant_id, ls_id, ls); LOG_INFO("create tablet"); - obrpc::ObBatchCreateTabletArg create_tablet_arg; ObTabletID tablet_id(1001); - ASSERT_EQ(OB_SUCCESS, gen_create_tablet_arg(tenant_id, ls_id, tablet_id, create_tablet_arg, 1, &table_schema_)); ObLSTabletService *ls_tablet_svr = ls->get_tablet_svr(); - ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(*ls_tablet_svr, create_tablet_arg)); + ObLSService* ls_svr = MTL(ObLSService*); + ObLSHandle ls_handle; + uint64_t table_id = 12345; + ASSERT_EQ(OB_SUCCESS, build_test_schema(table_schema_, table_id)); + ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema_, allocator_)); } TEST_F(TestTrans, basic) @@ -314,12 +327,13 @@ TEST_F(TestTrans, dist_trans) // create tablet LOG_INFO("create tablet"); - obrpc::ObBatchCreateTabletArg create_tablet_arg; ObTabletID tablet_id2(1002); - ASSERT_EQ(OB_SUCCESS, gen_create_tablet_arg(tenant_id, ls_id2, tablet_id2, create_tablet_arg, 1, &table_schema_)); ObLSTabletService *ls_tablet_svr = ls2->get_tablet_svr(); - ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(*ls_tablet_svr, create_tablet_arg)); + ObLSService* ls_svr = MTL(ObLSService*); + ObLSHandle ls_handle2; + ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id2, ls_handle2, ObLSGetMod::STORAGE_MOD)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle2, tablet_id2, table_schema_, allocator_)); LOG_INFO("start transaction"); diff --git a/mittest/mtlenv/storage/test_write_tablet_slog.cpp b/mittest/mtlenv/storage/test_write_tablet_slog.cpp index 542e914b4..4a4db7cca 100644 --- a/mittest/mtlenv/storage/test_write_tablet_slog.cpp +++ b/mittest/mtlenv/storage/test_write_tablet_slog.cpp @@ -21,6 +21,8 @@ #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" #include "storage/meta_mem/ob_tablet_handle.h" #include "storage/tablet/ob_tablet_slog_helper.h" +#include "storage/tablet/ob_tablet_persister.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" #include "storage/tx_storage/ob_ls_service.h" #include "storage/init_basic_struct.h" #include "storage/test_tablet_helper.h" @@ -49,6 +51,7 @@ public: static constexpr int64_t TEST_LS_ID = 100; blocksstable::ObLogFileSpec log_file_spec_; share::ObLSID ls_id_; + common::ObArenaAllocator allocator_; }; TestWriteTabletSlog::TestWriteTabletSlog() @@ -87,6 +90,7 @@ void TestWriteTabletSlog::TearDownTestCase() void TestWriteTabletSlog::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); log_file_spec_.retry_write_policy_ = "normal"; log_file_spec_.log_create_policy_ = "normal"; log_file_spec_.log_write_policy_ = "truncate"; @@ -119,26 +123,32 @@ TEST_F(TestWriteTabletSlog, basic) ASSERT_EQ(OB_SUCCESS, slogger->get_active_cursor(replay_start_cursor)); // create tablet and write slog - obrpc::ObBatchCreateTabletArg tablet_arg; ObTabletID tablet_id(1001); - ASSERT_EQ(OB_SUCCESS, gen_create_tablet_arg(TEST_TENANT_ID, ls_id, tablet_id, tablet_arg)); - ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(*ls->get_tablet_svr(), tablet_arg)); + + share::schema::ObTableSchema table_schema; + uint64_t table_id = 12345; + ASSERT_EQ(OB_SUCCESS, build_test_schema(table_schema, table_id)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(handle, tablet_id, table_schema, allocator_)); // mock minor freeze, assign tx data to tablet meta ObTabletHandle tablet_handle; ASSERT_EQ(OB_SUCCESS, ls->get_tablet(tablet_id, tablet_handle)); ObTablet *tablet = tablet_handle.get_obj(); - ObTabletTxMultiSourceDataUnit tx_data; - ASSERT_EQ(OB_SUCCESS, tablet->get_tx_data(tx_data)); - ASSERT_EQ(ObTabletStatus::NORMAL, tx_data.tablet_status_); - tablet->tablet_meta_.tx_data_ = tx_data; + ObTabletCreateDeleteMdsUserData user_data; + ASSERT_EQ(OB_SUCCESS, tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data)); + ASSERT_EQ(ObTabletStatus::NORMAL, user_data.tablet_status_.status_); + + // persist and transform tablet + const ObTabletMapKey key(ls_id, tablet_id); + ObTabletHandle new_tablet_hdl; + ASSERT_EQ(OB_SUCCESS, ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_hdl)); // write create tablet slog - ObMetaDiskAddr disk_addr; - ASSERT_EQ(OB_SUCCESS, ObTabletSlogHelper::write_create_tablet_slog(tablet_handle, disk_addr)); + ObMetaDiskAddr disk_addr = new_tablet_hdl.get_obj()->tablet_addr_; + ASSERT_EQ(OB_SUCCESS, ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr)); // remove tablet without writing slog - ASSERT_EQ(OB_SUCCESS, ls->ls_tablet_svr_.do_remove_tablet(ls_id, tablet_id)); + ASSERT_EQ(OB_SUCCESS, ls->ls_tablet_svr_.inner_remove_tablet(ls_id, tablet_id)); ASSERT_NE(OB_SUCCESS, ls->get_tablet(tablet_id, invalid_tablet_handle)); // replay create tablet @@ -158,7 +168,7 @@ TEST_F(TestWriteTabletSlog, basic) ASSERT_EQ(ls_id, replay_tablet->tablet_meta_.ls_id_); ASSERT_EQ(tablet_id, replay_tablet->tablet_meta_.tablet_id_); ASSERT_EQ(tablet_id, replay_tablet->tablet_meta_.data_tablet_id_); - ASSERT_EQ(1, replay_tablet->table_store_.major_tables_.count_); + //ASSERT_EQ(1, replay_tablet->table_store_.major_tables_.count_); } } diff --git a/mittest/mtlenv/tablelock/table_lock_common_env.h b/mittest/mtlenv/tablelock/table_lock_common_env.h index 49f542987..27590fdc9 100644 --- a/mittest/mtlenv/tablelock/table_lock_common_env.h +++ b/mittest/mtlenv/tablelock/table_lock_common_env.h @@ -36,10 +36,10 @@ ObLockID TABLE_LOCK_ID2; ObLockID TABLE_LOCK_ID3; ObTableLockMode DEFAULT_LOCK_MODE = ROW_EXCLUSIVE; ObTableLockMode DEFAULT_COFLICT_LOCK_MODE = EXCLUSIVE; -ObTableLockOwnerID DEFAULT_OWNER_ID = 0; -ObTableLockOwnerID CONFLICT_OWNER_ID = 1; -ObTableLockOwnerID OWNER_ID2 = 2; -ObTableLockOwnerID OWNER_ID3 = 3; +ObTableLockOwnerID DEFAULT_OWNER_ID(0); +ObTableLockOwnerID CONFLICT_OWNER_ID(1); +ObTableLockOwnerID OWNER_ID2(2); +ObTableLockOwnerID OWNER_ID3(3); ObTableLockOpType DEFAULT_LOCK_OP_TYPE = ObTableLockOpType::IN_TRANS_DML_LOCK; ObTableLockOpType OUT_TRANS_LOCK_OP_TYPE = ObTableLockOpType::OUT_TRANS_LOCK; ObTableLockOpType OUT_TRANS_UNLOCK_OP_TYPE = ObTableLockOpType::OUT_TRANS_UNLOCK; diff --git a/mittest/mtlenv/tablelock/test_lock_memtable.cpp b/mittest/mtlenv/tablelock/test_lock_memtable.cpp index f9bfd73dc..5a40c92d9 100644 --- a/mittest/mtlenv/tablelock/test_lock_memtable.cpp +++ b/mittest/mtlenv/tablelock/test_lock_memtable.cpp @@ -67,6 +67,7 @@ public: static void TearDownTestCase(); virtual void SetUp() override { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); // mock sequence no ObClockGenerator::init(); create_memtable(); @@ -127,7 +128,7 @@ TEST_F(TestLockMemtable, lock) // 2. OUT TRANS LOCK int ret = OB_SUCCESS; bool is_try_lock = true; - int64_t expired_time = 0; + int64_t expired_time = ObClockGenerator::getClock() + 1 * 1000 * 1000; ObLockParam param; ObMemtableCtx *mem_ctx = NULL; bool lock_exist = false; @@ -285,7 +286,7 @@ TEST_F(TestLockMemtable, replay) unsigned char lock_mode_in_same_trans = 0x0; int ret = OB_SUCCESS; bool is_try_lock = true; - int64_t expired_time = 0; + int64_t expired_time = ObClockGenerator::getClock() + 1 * 1000 * 1000; share::SCN min_commited_scn; share::SCN flushed_scn; MyTxCtx default_ctx; @@ -448,7 +449,7 @@ TEST_F(TestLockMemtable, recover) LOG_INFO("TestLockMemtable::recover"); int ret = OB_SUCCESS; bool is_try_lock = true; - int64_t expired_time = 0; + int64_t expired_time = ObClockGenerator::getClock() + 1 * 1000 * 1000; share::SCN min_commited_scn; share::SCN flushed_scn; ObOBJLock *obj_lock = NULL; @@ -541,7 +542,7 @@ TEST_F(TestLockMemtable, pre_check_lock) int ret = OB_SUCCESS; bool is_try_lock = true; bool lock_exist = false; - int64_t expired_time = 0; + int64_t expired_time = ObClockGenerator::getClock() + 1 * 1000 * 1000; MyTxCtx default_ctx; ObStoreCtx store_ctx; ObOBJLock *obj_lock = NULL; @@ -614,7 +615,7 @@ TEST_F(TestLockMemtable, lock_twice_out) // 3. LOCK TWICE: LOCK, UNLOCK DOING CONFLICT int ret = OB_SUCCESS; bool is_try_lock = true; - int64_t expired_time = 0; + int64_t expired_time = ObClockGenerator::getClock() + 1 * 1000 * 1000; bool is_exact = true; ObTxIDSet conflict_tx_set; int64_t conflict_modes = 0; diff --git a/mittest/mtlenv/tablelock/test_obj_lock.cpp b/mittest/mtlenv/tablelock/test_obj_lock.cpp index 5af451933..0b512a499 100644 --- a/mittest/mtlenv/tablelock/test_obj_lock.cpp +++ b/mittest/mtlenv/tablelock/test_obj_lock.cpp @@ -57,6 +57,7 @@ public: static void TearDownTestCase(); virtual void SetUp() override { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); // mock sequence no ObClockGenerator::init(); create_memtable(); diff --git a/mittest/mtlenv/tablelock/test_obj_lock_map.cpp b/mittest/mtlenv/tablelock/test_obj_lock_map.cpp index 0579d9af2..55a6b4d9c 100644 --- a/mittest/mtlenv/tablelock/test_obj_lock_map.cpp +++ b/mittest/mtlenv/tablelock/test_obj_lock_map.cpp @@ -43,6 +43,7 @@ public: static void TearDownTestCase(); virtual void SetUp() override { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); // mock sequence no ObClockGenerator::init(); create_memtable(); diff --git a/mittest/mtlenv/tablelock/test_table_lock_flush.cpp b/mittest/mtlenv/tablelock/test_table_lock_flush.cpp index 9c80183b9..ec133f278 100644 --- a/mittest/mtlenv/tablelock/test_table_lock_flush.cpp +++ b/mittest/mtlenv/tablelock/test_table_lock_flush.cpp @@ -78,6 +78,7 @@ TestTableLockFlush::TestTableLockFlush() void TestTableLockFlush::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); tenant_id_ = MTL_ID(); } void TestTableLockFlush::TearDown() @@ -370,8 +371,8 @@ TEST_F(TestTableLockFlush, restore_tx_ctx) mock_store_ctx(ob_store_ctx, ctx1, txDesc, ls); ob_store_ctx.ls_ = ls; ob_store_ctx.ls_id_ = ls->get_ls_id(); - ob_store_ctx.mvcc_acc_ctx_.tx_table_guard_.tx_table_ = (ObTxTable*)0x1; - ob_store_ctx.mvcc_acc_ctx_.tx_table_guard_.epoch_ = ObTxTable::INVALID_READ_EPOCH; + ob_store_ctx.mvcc_acc_ctx_.tx_table_guards_.tx_table_guard_.tx_table_ = (ObTxTable*)0x1; + ob_store_ctx.mvcc_acc_ctx_.tx_table_guards_.tx_table_guard_.epoch_ = ObTxTable::INVALID_READ_EPOCH; ob_store_ctx.mvcc_acc_ctx_.abs_lock_timeout_ = 5000; ob_store_ctx.mvcc_acc_ctx_.tx_ctx_ = &ctx1; ob_store_ctx.mvcc_acc_ctx_.tx_desc_ = &txDesc; diff --git a/mittest/mtlenv/test_buffer_ctx_node.cpp b/mittest/mtlenv/test_buffer_ctx_node.cpp new file mode 100644 index 000000000..e274e9ad7 --- /dev/null +++ b/mittest/mtlenv/test_buffer_ctx_node.cpp @@ -0,0 +1,150 @@ +/** + * Copyright (c) 2021 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. + */ + +#define UNITTEST_DEBUG +#include +#define private public +#define protected public +#include "storage/multi_data_source/mds_writer.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/tx/ob_trans_define.h" +#include "storage/multi_data_source/compile_utility/mds_dummy_key.h" +#include "storage/multi_data_source/compile_utility/map_type_index_in_tuple.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include +#include +#include +#include +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_node.h" +#include "unittest/storage/multi_data_source/common_define.h" +#include "unittest/storage/multi_data_source/example_user_data_define.h" +#include "unittest/storage/multi_data_source/example_user_helper_define.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/tablet/ob_tablet_meta.h" +#define MIT_TESTCASE_LABEL +#include "mtlenv/mock_tenant_module_env.h" +#include "observer/ob_server.h" +namespace oceanbase { +namespace storage +{ +namespace mds +{ +void *MdsAllocator::alloc(const int64_t size) +{ + void *ptr = ob_malloc(size, "MDS"); + ATOMIC_INC(&alloc_times_); + MDS_LOG(DEBUG, "alloc obj", KP(ptr), K(size), K(lbt())); + return ptr; +} +void MdsAllocator::free(void *ptr) { + ATOMIC_INC(&free_times_); + MDS_LOG(DEBUG, "free obj", KP(ptr), K(lbt())); + ob_free(ptr); +} +} +} +namespace unittest { + +using namespace common; +using namespace std; +using namespace storage; +using namespace mds; +using namespace transaction; + +class TestBufferCtxNode: public ::testing::Test +{ +public: + TestBufferCtxNode() {}; + virtual ~TestBufferCtxNode() {}; + virtual void SetUp() { + }; + virtual void TearDown() { + }; + static void SetUpTestCase() { ASSERT_EQ(OB_SUCCESS, storage::MockTenantModuleEnv::get_instance().init()); } + static void TearDownTestCase() { storage::MockTenantModuleEnv::get_instance().destroy(); } +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestBufferCtxNode); +}; + +TEST_F(TestBufferCtxNode, test_mds_ctx_serialize_deserialize) { + BufferCtxNode node; + BufferCtx *buffer_ctx = nullptr; + ASSERT_EQ(OB_SUCCESS, MdsFactory::create_buffer_ctx(transaction::ObTxDataSourceType::TEST1, ObTransID(1), buffer_ctx)); + node.set_ctx(buffer_ctx); + ObTxBufferCtxArray buffer_ctx_array; + ASSERT_EQ(OB_SUCCESS, buffer_ctx_array.push_back(node)); + ASSERT_EQ(OB_SUCCESS, buffer_ctx_array.push_back(node)); + constexpr int64_t buffer_len = 2048; + char stack_buffer[buffer_len] = {0}; + int64_t pos1 = 0; + ASSERT_EQ(OB_SUCCESS, buffer_ctx_array.serialize(stack_buffer, buffer_len, pos1)); + int64_t pos2 = 0; + ASSERT_EQ(OB_SUCCESS, buffer_ctx_array.deserialize(stack_buffer, buffer_len, pos2)); + ASSERT_EQ(pos1, pos2); + for (int i = 0; i < buffer_ctx_array.count(); ++i) { + buffer_ctx_array[i].destroy_ctx(); + } + node.destroy_ctx(); +} + +TEST_F(TestBufferCtxNode, test_exec_info_serialize_deserialize) { + BufferCtx *buffer_ctx = nullptr; + ASSERT_EQ(OB_SUCCESS, MdsFactory::create_buffer_ctx(transaction::ObTxDataSourceType::TEST1, ObTransID(1), buffer_ctx)); + + constexpr int64_t buffer_size = 1024; + ObTxExecInfo exec_info; + ObTxBufferNode node; + char buffer1[buffer_size] = {1}; + node.data_.assign_buffer(buffer1, buffer_size); + node.buffer_ctx_node_.set_ctx(buffer_ctx); + ASSERT_EQ(OB_SUCCESS, exec_info.multi_data_source_.push_back(node)); + ASSERT_EQ(OB_SUCCESS, exec_info.multi_data_source_.push_back(node)); + + char serialize_buffer[4096]; + int64_t pos = 0; + ASSERT_EQ(OB_SUCCESS, exec_info.generate_mds_buffer_ctx_array()); + ASSERT_EQ(OB_SUCCESS, exec_info.serialize(serialize_buffer, 4096, pos)); + pos = 0; + ObTxExecInfo exec_info_new; + ASSERT_EQ(OB_SUCCESS, exec_info_new.deserialize(serialize_buffer, 4096, pos)); + ASSERT_EQ(exec_info_new.mds_buffer_ctx_array_.count(), 2); + exec_info_new.mrege_buffer_ctx_array_to_multi_data_source(); + for (int i = 0; i < exec_info_new.multi_data_source_.count(); ++i) { + exec_info_new.multi_data_source_[i].buffer_ctx_node_.destroy_ctx(); + } + node.buffer_ctx_node_.destroy_ctx(); +} + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_buffer_ctx_node.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_buffer_ctx_node.log", false); + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + int64_t alloc_times = oceanbase::storage::mds::MdsAllocator::get_alloc_times(); + int64_t free_times = oceanbase::storage::mds::MdsAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + ret = -1; + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} diff --git a/mittest/mtlenv/test_multi_tenant.cpp b/mittest/mtlenv/test_multi_tenant.cpp index ccb96c1c6..5a57f02e5 100644 --- a/mittest/mtlenv/test_multi_tenant.cpp +++ b/mittest/mtlenv/test_multi_tenant.cpp @@ -135,6 +135,7 @@ protected: void TestMultiTenant::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); MTL_BIND(fake_init_compat_mode, nullptr); } diff --git a/mittest/mtlenv/test_ob_election_priority.cpp b/mittest/mtlenv/test_ob_election_priority.cpp index 9715410c5..6ebe161e1 100644 --- a/mittest/mtlenv/test_ob_election_priority.cpp +++ b/mittest/mtlenv/test_ob_election_priority.cpp @@ -56,6 +56,10 @@ public: ~TestElectionPriority() {} static void SetUpTestCase() { ASSERT_EQ(OB_SUCCESS, storage::MockTenantModuleEnv::get_instance().init()); } static void TearDownTestCase() { storage::MockTenantModuleEnv::get_instance().destroy(); } + void SetUp() + { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); + } // virtual void SetUp() { } // virtual void TearDown() { } static void test_normal() diff --git a/mittest/mtlenv/test_session_serde.cpp b/mittest/mtlenv/test_session_serde.cpp index 6dd1eb253..a228c8ecf 100644 --- a/mittest/mtlenv/test_session_serde.cpp +++ b/mittest/mtlenv/test_session_serde.cpp @@ -43,6 +43,11 @@ public: LOG_INFO("TearDownTestCase"); MockTenantModuleEnv::get_instance().destroy(); } + + void SetUp() + { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); + } }; static ObTZInfoMap map; diff --git a/mittest/mtlenv/test_tx_data_table.cpp b/mittest/mtlenv/test_tx_data_table.cpp index 1195a0100..c96c790f4 100644 --- a/mittest/mtlenv/test_tx_data_table.cpp +++ b/mittest/mtlenv/test_tx_data_table.cpp @@ -164,6 +164,7 @@ public: virtual void SetUp() override { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); fake_ls_(ls_); } diff --git a/mittest/simple_server/CMakeLists.txt b/mittest/simple_server/CMakeLists.txt index ca05b7b01..9774f2e63 100644 --- a/mittest/simple_server/CMakeLists.txt +++ b/mittest/simple_server/CMakeLists.txt @@ -19,11 +19,26 @@ function(ob_unittest_observer case) set_tests_properties(${case} PROPERTIES LABELS "simpleserver") endfunction() +function(ob_ha_unittest_observer case) + ob_unittest(${ARGV}) + target_link_libraries(${case} PRIVATE gtest gmock observer_test oceanbase) +endfunction() + +function(errsim_ha_unittest_observer case) + ob_unittest(${ARGV}) + target_link_libraries(${case} PRIVATE gtest gmock observer_test oceanbase) +endfunction() + + +ob_unittest_observer(test_standby_balance test_standby_balance_ls_group.cpp) ob_unittest_observer(test_ls_recover test_ls_recover.cpp) +ob_unittest_observer(test_ob_simple_cluster test_ob_simple_cluster.cpp) +ob_unittest_observer(test_ob_partition_balance test_ob_partition_balance.cpp) ob_unittest_observer(test_ls_status_operator test_ls_status_operator.cpp) +ob_unittest_observer(test_balance_operator test_tenant_balance_operator.cpp) +ob_unittest_observer(test_mds_table_checkpoint test_mds_table_checkpoint.cpp) ob_unittest_observer(test_ob_black_list_service test_ob_black_list_service.cpp) ob_unittest_observer(test_ob_minor_freeze test_ob_minor_freeze.cpp) -ob_unittest_observer(test_ob_simple_cluster test_ob_simple_cluster.cpp) ob_unittest_observer(test_ob_table_lock_service test_ob_table_lock_service.cpp) ob_unittest_observer(test_ob_obj_lock_garbage_collector test_ob_obj_lock_garbage_collector.cpp) ob_unittest_observer(test_observer_expand_shrink test_observer_expand_shrink.cpp) @@ -35,6 +50,13 @@ ob_unittest_observer(test_lock_table_persistence test_lock_table_persistence.cpp ob_unittest_observer(test_tx_recover test_tx_recovery.cpp) ob_unittest_observer(test_tx_recover2 test_tx_recovery2.cpp) ob_unittest_observer(test_tx_recover3 test_tx_recovery3.cpp) +ob_unittest_observer(test_transfer_task_operator test_transfer_task_operator.cpp) +ob_unittest_observer(test_ob_tablet_to_ls_operator test_ob_tablet_to_ls_operator.cpp) +ob_unittest_observer(test_tenant_transfer_service test_tenant_transfer_service.cpp) +ob_unittest_observer(test_schema_service_sql_impl test_schema_service_sql_impl.cpp) +ob_unittest_observer(test_location_service test_location_service.cpp) +ob_unittest_observer(test_mds_transaction test_mds_transaction.cpp) +ob_unittest_observer(test_mds_tx_ctx_recover_mem_leak test_mds_tx_ctx_recover_mem_leak.cpp) ob_unittest_observer(test_role_change_service test_role_change_service.cpp) ob_unittest_observer(test_arbitration_service_rpc test_arbitration_service_rpc.cpp) ob_unittest_observer(test_arbitration_service_table_operator test_arbitration_service_table_operator.cpp) @@ -44,9 +66,20 @@ ob_unittest_observer(test_arbitration_service_replica_task_table_operator test_a ob_unittest_observer(test_change_arb_service_status test_change_arb_service_status.cpp) ob_unittest_observer(test_big_tx_data test_big_tx_data.cpp) ob_unittest_observer(test_fast_commit_report fast_commit_report.cpp) -ob_unittest_observer(test_mvcc_gc test_mvcc_gc.cpp) +#ob_unittest_observer(test_mvcc_gc test_mvcc_gc.cpp) ob_unittest_observer(test_ob_simple_rto test_ob_simple_rto.cpp) ob_unittest_observer(test_all_virtual_proxy_partition_info_default_value test_all_virtual_proxy_partition_info_default_value.cpp) ob_unittest_observer(test_get_stopped_zone_list test_get_stopped_zone_list.cpp) ob_unittest_observer(test_lock_table_with_tx test_lock_table_with_tx.cpp) ob_unittest_observer(test_ob_detect_manager_in_simple_server test_ob_detect_manager_in_simple_server.cpp) +ob_unittest_observer(test_transfer_lock_info_operator storage_ha/test_transfer_lock_info_operator.cpp) +ob_unittest_observer(test_mds_recover test_mds_recover.cpp) +#ob_ha_unittest_observer(test_transfer_handler storage_ha/test_transfer_handler.cpp) +#ob_ha_unittest_observer(test_transfer_and_restart_basic storage_ha/test_transfer_and_restart_basic.cpp) +ob_ha_unittest_observer(test_transfer_start_stage_restart_without_mds_flush storage_ha/test_transfer_start_stage_restart_without_mds_flush.cpp) +#ob_ha_unittest_observer(test_transfer_doing_stage_restart_without_mds_flush storage_ha/test_transfer_doing_stage_restart_without_mds_flush.cpp) +#ob_ha_unittest_observer(test_transfer_complete_restart_without_mds_flush storage_ha/test_transfer_complete_restart_without_mds_flush.cpp) +ob_ha_unittest_observer(test_transfer_doing_stage_restart_with_mds_flush storage_ha/test_transfer_doing_stage_restart_with_mds_flush.cpp) +ob_ha_unittest_observer(test_transfer_complete_restart_with_mds_flush storage_ha/test_transfer_complete_restart_with_mds_flush.cpp) +#ob_ha_unittest_observer(test_transfer_with_empty_shell storage_ha/test_transfer_with_empty_shell.cpp) +errsim_ha_unittest_observer(errsim_test_transfer_handler errsim/storage_ha/errsim_test_transfer_handler.cpp) diff --git a/mittest/simple_server/errsim/storage_ha/errsim_test_transfer_handler.cpp b/mittest/simple_server/errsim/storage_ha/errsim_test_transfer_handler.cpp new file mode 100644 index 000000000..4bfbb59e7 --- /dev/null +++ b/mittest/simple_server/errsim/storage_ha/errsim_test_transfer_handler.cpp @@ -0,0 +1,1128 @@ +/** + * 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "storage/high_availability/ob_transfer_handler.h" //ObTransferHandler +#include "lib/utility/utility.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_service.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace storage +{ +using namespace share::schema; +using namespace common; +using namespace share; +using namespace transaction::tablelock; +using namespace rootserver; + +static uint64_t g_tenant_id; +static ObTransferPartList g_part_list; +static ObTransferPartList g_batch_part_list; + +class TestTransferHandler : public unittest::ObSimpleClusterTestBase +{ +public: + TestTransferHandler() : unittest::ObSimpleClusterTestBase("test_transfer_handler") {} + int read_sql(ObMySQLProxy &sql_proxy, const ObSqlString &sql, ObTransferPartList &part_list); + int gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task); + int wait_transfer_task( + const ObTransferTaskID task_id, + const ObTransferStatus &expected_status, + const bool &is_from_his, + ObTransferTask &task); + int wait_transfer_out_deleted_tablet_gc( + const ObTransferTask &task); + int generate_transfer_task( + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + ObTransferTaskID &task_id); + int wait_error_happen(const ObTransferTask &task); +}; + +int TestTransferHandler::read_sql( + ObMySQLProxy &sql_proxy, + const ObSqlString &sql, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + if (OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", table_id, uint64_t); + } + while(OB_SUCC(ret)) { + uint64_t part_id = OB_INVALID_ID; + ObTransferPartInfo part_info; + if (OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", part_id, uint64_t); + if (OB_FAIL(part_info.init(table_id, part_id))) { + } else if (OB_FAIL(part_list.push_back(part_info))) { + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +int TestTransferHandler::gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObLSID src_ls(1001); + ObLSID dest_ls(1002); + share::SCN start_scn; + share::SCN finish_scn; + start_scn.convert_for_inner_table_field(1666844202200632); + finish_scn.convert_for_inner_table_field(1666844202208490); + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ret = task.init(task_id, src_ls, dest_ls, ObString::make_string("500016:500014"), ObString("500030:500031"), ObString("500016:500015"), + ObString::make_string("1152921504606846983"), ObString::make_string("1152921504606846983:0"), start_scn, finish_scn, status, trace_id, OB_SUCCESS, + ObTransferTaskComment::EMPTY_COMMENT, ObBalanceTaskID(123), ObTableLockOwnerID(999)); + return ret; +} + +int TestTransferHandler::wait_transfer_task( + const ObTransferTaskID task_id, + const ObTransferStatus &expected_status, + const bool &is_from_his, + ObTransferTask &task) +{ + int ret = OB_SUCCESS; + task.reset(); + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + bool get_task = false; + + if (!task_id.is_valid() || !expected_status.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer task get invalid argument", K(ret), K(task_id), K(expected_status)); + } else if (is_from_his) { + while (OB_SUCC(ret)) { + if (OB_FAIL(ObTransferTaskOperator::get_history_task(inner_sql_proxy, g_tenant_id, task_id, task, create_time, finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + LOG_WARN("cannot wait transfer task", K(ret), K(task_id), K(expected_status)); + } else { + ret = OB_SUCCESS; + usleep(SLEEP_INTERVAL); + } + } else { + LOG_WARN("failed to get history task", K(ret), K(task_id), K(expected_status)); + } + } else { + break; + } + } + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(ObTransferTaskOperator::get_task_with_time(inner_sql_proxy, g_tenant_id, task_id, false/*for_update*/, + task, create_time, finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + get_task = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get history task", K(ret), K(task_id), K(expected_status)); + } + } else if (task.get_status() != expected_status) { + get_task = false; + } else { + get_task = true; + break; + } + if (OB_SUCC(ret) && !get_task) { + if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + LOG_WARN("cannot wait transfer task", K(ret), K(task_id), K(expected_status)); + } else { + ret = OB_SUCCESS; + usleep(SLEEP_INTERVAL); + } + } + } + } + return ret; +} + +int TestTransferHandler::wait_transfer_out_deleted_tablet_gc( + const ObTransferTask &task) +{ + int ret = OB_SUCCESS; + MTL_SWITCH(g_tenant_id) { + const ObLSID &ls_id = task.src_ls_; + ObLS *ls = nullptr; + ObLSHandle ls_handle; + ObLSService *ls_svr = nullptr; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + + if (!task.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer out deleted tablet gc get invalid argument", K(ret), K(task)); + } else if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), K(task)); + } else if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else { + int64_t index = 0; + while (OB_SUCC(ret) && index < task.tablet_list_.count()) { + ObTabletHandle tablet_handle; + const ObTransferTabletInfo &transfer_info = task.tablet_list_.at(index); + if (OB_FAIL(ls->get_tablet(transfer_info.tablet_id_, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + index++; + } else { + LOG_WARN("failed to get tablet", K(ret), K(transfer_info)); + } + } else if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + ret = OB_TIMEOUT; + LOG_WARN("wait transfer out delete tablet gc timeout", K(ret), K(transfer_info)); + } else { + usleep(SLEEP_INTERVAL); + } + } + } + } + return ret; +} + +int TestTransferHandler::generate_transfer_task( + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + ObTransferTaskID &task_id) +{ + int ret = OB_SUCCESS; + task_id.reset(); + if (4 != g_part_list.count() + || !is_valid_tenant_id(g_tenant_id) + || !src_ls_id.is_valid() + || !dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("generate transfer task get invalid argument", K(ret), K(src_ls_id), K(dest_ls_id)); + } else { + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + share::ObTenantSwitchGuard tenant_guard; + ObTenantTransferService *tenant_transfer = nullptr; + ObMySQLTransaction trans; + if (OB_FAIL(tenant_guard.switch_to(g_tenant_id))) { + LOG_WARN("failed to swithc to tenant", K(ret), K(g_tenant_id)); + } else if (OB_ISNULL(tenant_transfer = MTL(ObTenantTransferService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant transfer should not be NULL", K(ret), KP(tenant_transfer)); + } else if (OB_FAIL(trans.start(&inner_sql_proxy, g_tenant_id))) { + LOG_WARN("failed to start trans", K(ret)); + } else { + if (OB_FAIL(tenant_transfer->generate_transfer_task(trans, src_ls_id, dest_ls_id, + g_part_list, ObBalanceTaskID(123), task_id))) { + LOG_WARN("failed to generate transfer task", K(ret)); + } + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + } + return ret; +} + +int TestTransferHandler::wait_error_happen(const ObTransferTask &task) +{ + int ret = OB_SUCCESS; + share::ObTenantSwitchGuard tenant_guard; + if (!task.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait error happen get invalid argument", K(ret), K(task)); + } else if (OB_FAIL(tenant_guard.switch_to(g_tenant_id))) { + LOG_WARN("failed to swithc to tenant", K(ret), K(g_tenant_id)); + } else { + const ObLSID &ls_id = task.dest_ls_; + ObLS *ls = nullptr; + ObLSHandle ls_handle; + ObLSService *ls_svr = nullptr; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + + if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), K(task)); + } else if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else { + while (OB_SUCC(ret)) { + if (ls->get_transfer_handler()->retry_count_ > 0) { + break; + } else if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + ret = OB_TIMEOUT; + LOG_WARN("wait error happen timeout", K(ret)); + } else { + usleep(SLEEP_INTERVAL); + } + } + } + } + return ret; +} + +TEST_F(TestTransferHandler, prepare_valid_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + // create table + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt1(c1 int primary key, c2 blob) partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_idx on ttt1(c1) local")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_global ON ttt1(c1) global partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_part_list)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1_global'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_part_list)); + + // create 101 partitions + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt2(c1 int primary key) partition by hash(c1) partitions 101")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt2'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_batch_part_list)); +} + +TEST_F(TestTransferHandler, start_lock_transfer_task_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_LOCK_TRANSFER_TASK_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1001), ObLSID(1), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::START); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_LOCK_TRANSFER_TASK_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); + +} + +TEST_F(TestTransferHandler, start_lock_transfer_member_list_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_LOCK_TRANSFER_MEMBER_LIST_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1 ls transfer to 1001 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1), ObLSID(1001), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::START); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_LOCK_TRANSFER_MEMBER_LIST_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); + +} + +TEST_F(TestTransferHandler, start_check_start_transfer_tablet_status_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_CHECK_START_TRANSFER_STATUS_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1001), ObLSID(1), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::START); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_CHECK_START_TRANSFER_STATUS_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); + +} + +TEST_F(TestTransferHandler, start_check_active_trans_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_CHECK_ACTIVE_TRANS_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1 ls transfer to 1001 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1), ObLSID(1001), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::START); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_CHECK_ACTIVE_TRANS_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, start_transfer_out_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_START_TRANSFER_OUT_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1001), ObLSID(1), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::START); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_START_TRANSFER_OUT_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, start_get_transfer_start_scn_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_GET_TRANSFER_START_SCN_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1 ls transfer to 1001 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1), ObLSID(1001), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::START); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_GET_TRANSFER_START_SCN_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, start_wait_src_replay_to_start_scn_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_WAIT_SRC_REPALY_TO_START_SCN_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1001), ObLSID(1), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::START); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_WAIT_SRC_REPALY_TO_START_SCN_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, start_get_transfer_tablet_meta_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_GET_TRANSFER_TABLET_META_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1 ls transfer to 1001 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1), ObLSID(1001), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::START); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_GET_TRANSFER_TABLET_META_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} +// +//TEST_F(TestTransferHandler, start_transfer_in_failed) +//{ +// int ret = OB_SUCCESS; +// ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); +// ObSqlString sql; +// int64_t affected_rows = 0; +// // inject error +// ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_START_TRANSFER_IN_FAILED, error_code = 4023, frequency = 1")); +// ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); +// usleep(100000); // wait for debug_sync_timeout to take effect +// sql.reset(); +// +// //1001 ls transfer to 1 ls +// // generate transfer task +// ObTransferTaskID task_id; +// ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1001), ObLSID(1), task_id)); +// +// //check observer transfer status +// ObTransferStatus expected_status(ObTransferStatus::START); +// ObTransferTask task; +// ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); +// LOG_INFO("generate transfer task", K(task)); +// ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); +// +// //remove error +// ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_START_TRANSFER_IN_FAILED, error_code = 4023, frequency = 0")); +// ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); +// usleep(100000); // wait for debug_sync_timeout to take effect +// sql.reset(); +// +// //check observer transfer +// expected_status = ObTransferStatus::COMPLETED; +// task.reset(); +// ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); +// LOG_INFO("generate transfer task", K(task)); +// ASSERT_EQ(OB_SUCCESS, task.result_); +// //wait 1001 ls transfer out tablet deleted gc. +// ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +//} +// +//TEST_F(TestTransferHandler, start_update_all_tablet_to_ls_failed) +//{ +// int ret = OB_SUCCESS; +// ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); +// ObSqlString sql; +// int64_t affected_rows = 0; +// // inject error +// ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_UPDATE_ALL_TABLET_TO_LS_FAILED, error_code = 4023, frequency = 1")); +// ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); +// usleep(100000); // wait for debug_sync_timeout to take effect +// sql.reset(); +// +// //1 ls transfer to 1001 ls +// // generate transfer task +// ObTransferTaskID task_id; +// ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1), ObLSID(1001), task_id)); +// +// //check observer transfer status +// ObTransferStatus expected_status(ObTransferStatus::START); +// ObTransferTask task; +// ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); +// LOG_INFO("generate transfer task", K(task)); +// ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); +// +// //remove error +// ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_UPDATE_ALL_TABLET_TO_LS_FAILED, error_code = 4023, frequency = 0")); +// ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); +// usleep(100000); // wait for debug_sync_timeout to take effect +// sql.reset(); +// +// //check observer transfer +// expected_status = ObTransferStatus::COMPLETED; +// task.reset(); +// ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); +// LOG_INFO("generate transfer task", K(task)); +// ASSERT_EQ(OB_SUCCESS, task.result_); +// //wait 1001 ls transfer out tablet deleted gc. +// ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +//} +// +//TEST_F(TestTransferHandler, start_update_transfer_task_failed) +//{ +// int ret = OB_SUCCESS; +// ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); +// ObSqlString sql; +// int64_t affected_rows = 0; +// // inject error +// ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_UPDATE_TRANSFER_TASK_FAILED, error_code = 4023, frequency = 1")); +// ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); +// usleep(100000); // wait for debug_sync_timeout to take effect +// sql.reset(); +// +// //1001 ls transfer to 1 ls +// // generate transfer task +// ObTransferTaskID task_id; +// ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1001), ObLSID(1), task_id)); +// +// //check observer transfer status +// ObTransferStatus expected_status(ObTransferStatus::START); +// ObTransferTask task; +// ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); +// LOG_INFO("generate transfer task", K(task)); +// ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); +// +// //remove error +// ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_UPDATE_TRANSFER_TASK_FAILED, error_code = 4023, frequency = 0")); +// ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); +// usleep(100000); // wait for debug_sync_timeout to take effect +// sql.reset(); +// +// //check observer transfer +// expected_status = ObTransferStatus::COMPLETED; +// task.reset(); +// ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); +// LOG_INFO("generate transfer task", K(task)); +// ASSERT_EQ(OB_SUCCESS, task.result_); +// //wait 1001 ls transfer out tablet deleted gc. +// ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +//} +// +//TEST_F(TestTransferHandler, doing_unlock_member_list_failed) +//{ +// int ret = OB_SUCCESS; +// ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); +// ObSqlString sql; +// int64_t affected_rows = 0; +// // inject error +// ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_UNLOCK_TRANSFER_MEMBER_LIST_FAILED, error_code = 4023, frequency = 1")); +// ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); +// usleep(100000); // wait for debug_sync_timeout to take effect +// sql.reset(); +// +// //1 ls transfer to 1001 ls +// // generate transfer task +// ObTransferTaskID task_id; +// ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1), ObLSID(1001), task_id)); +// +// //check observer transfer status +// ObTransferStatus expected_status(ObTransferStatus::DOING); +// ObTransferTask task; +// ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); +// LOG_INFO("generate transfer task", K(task)); +// ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); +// +// //remove error +// ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_UNLOCK_TRANSFER_MEMBER_LIST_FAILED, error_code = 4023, frequency = 0")); +// ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); +// usleep(100000); // wait for debug_sync_timeout to take effect +// sql.reset(); +// +// //check observer transfer +// expected_status = ObTransferStatus::COMPLETED; +// task.reset(); +// ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); +// LOG_INFO("generate transfer task", K(task)); +// ASSERT_EQ(OB_SUCCESS, task.result_); +// //wait 1001 ls transfer out tablet deleted gc. +// ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +//} + +TEST_F(TestTransferHandler, doing_lock_transfer_task_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_LOCK_TRANSFER_TASK_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1001), ObLSID(1), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::DOING); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_LOCK_TRANSFER_TASK_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, doing_lock_member_list_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_LOCK_MEMBER_LIST_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1 ls transfer to 1001 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1), ObLSID(1001), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::DOING); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_LOCK_MEMBER_LIST_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, finish_transfer_in_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_FINISH_TRANSFER_IN_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1001), ObLSID(1), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::DOING); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_FINISH_TRANSFER_IN_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, doing_wait_all_dest_tablet_normal_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_WAIT_ALL_DEST_TABLET_NORAML, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1 ls transfer to 1001 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1), ObLSID(1001), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::DOING); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_WAIT_ALL_DEST_TABLET_NORAML, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, finish_transfer_out_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_FINISH_TRANSFER_OUT_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1001), ObLSID(1), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::DOING); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_FINISH_TRANSFER_OUT_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, doing_update_transfer_task_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_UPDATE_TRANSFER_TASK_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1 ls transfer to 1001 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1), ObLSID(1001), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::DOING); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_UPDATE_TRANSFER_TASK_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, doing_commin_trans_failed) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // inject error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_COMMIT_TRANS_FAILED, error_code = 4023, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ASSERT_EQ(OB_SUCCESS, generate_transfer_task(ObLSID(1001), ObLSID(1), task_id)); + + //check observer transfer status + ObTransferStatus expected_status(ObTransferStatus::DOING); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, false/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_error_happen(task)); + + //remove error + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_DOING_COMMIT_TRANS_FAILED, error_code = 4023, frequency = 0")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + + //check observer transfer + expected_status = ObTransferStatus::COMPLETED; + task.reset(); + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/fast_commit_report.cpp b/mittest/simple_server/fast_commit_report.cpp index d4de785ed..4f4b5a414 100644 --- a/mittest/simple_server/fast_commit_report.cpp +++ b/mittest/simple_server/fast_commit_report.cpp @@ -123,10 +123,8 @@ int ObMemtable::flush(share::ObLSID ls_id) K(ls_id), K(*this), K(mt_stat_.ready_for_flush_time_)); compaction::ADD_SUSPECT_INFO(MINI_MERGE, ls_id, get_tablet_id(), - "memtable can not create dag successfully", - "has been ready for flush time:", + ObSuspectInfoType::SUSPECT_MEMTABLE_CANT_CREATE_DAG, cur_time - mt_stat_.ready_for_flush_time_, - "ready for flush time:", mt_stat_.ready_for_flush_time_); } compaction::ObTabletMergeDagParam param; diff --git a/mittest/simple_server/storage_ha/test_transfer_and_restart_basic.cpp b/mittest/simple_server/storage_ha/test_transfer_and_restart_basic.cpp new file mode 100644 index 000000000..9029473c3 --- /dev/null +++ b/mittest/simple_server/storage_ha/test_transfer_and_restart_basic.cpp @@ -0,0 +1,263 @@ +/** + * 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "test_transfer_common_fun.h" +#include "env/ob_simple_server_restart_helper.h" +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "storage/high_availability/ob_transfer_handler.h" //ObTransferHandler +#include "lib/utility/utility.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_service.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace storage +{ +using namespace share::schema; +using namespace common; +using namespace share; +using namespace transaction::tablelock; +using namespace rootserver; + +static uint64_t g_tenant_id; +static ObTransferPartList g_part_list; +static ObTransferPartList g_batch_part_list; + +static const char *TEST_FILE_NAME = "test_transfer_and_restart_basic"; +static const char *BORN_CASE_NAME = "TestTransferHandler"; +static const char *RESTART_CASE_NAME = "TestTransferRestart"; +static ObTransferTask g_task; + +class TestTransferHandler : public unittest::ObSimpleClusterTestBase +{ +public: + TestTransferHandler() : unittest::ObSimpleClusterTestBase(TEST_FILE_NAME) {} + int read_sql(ObMySQLProxy &sql_proxy, const ObSqlString &sql, ObTransferPartList &part_list); + int gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task); +}; + +int TestTransferHandler::read_sql( + ObMySQLProxy &sql_proxy, + const ObSqlString &sql, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + if (OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", table_id, uint64_t); + } + while(OB_SUCC(ret)) { + uint64_t part_id = OB_INVALID_ID; + ObTransferPartInfo part_info; + if (OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", part_id, uint64_t); + if (OB_FAIL(part_info.init(table_id, part_id))) { + } else if (OB_FAIL(part_list.push_back(part_info))) { + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +int TestTransferHandler::gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObLSID src_ls(1001); + ObLSID dest_ls(1002); + share::SCN start_scn; + share::SCN finish_scn; + start_scn.convert_for_inner_table_field(1666844202200632); + finish_scn.convert_for_inner_table_field(1666844202208490); + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ret = task.init(task_id, src_ls, dest_ls, ObString::make_string("500016:500014"), ObString("500030:500031"), ObString("500016:500015"), + ObString::make_string("1152921504606846983"), ObString::make_string("1152921504606846983:0"), start_scn, finish_scn, status, trace_id, OB_SUCCESS, + ObTransferTaskComment::EMPTY_COMMENT, ObBalanceTaskID(123), ObTableLockOwnerID(999)); + return ret; +} + +class TestTransferRestart : public ObSimpleClusterTestBase +{ +public: + TestTransferRestart() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} + void select_existed_data(); +}; + +void TestTransferRestart::select_existed_data() +{ + sleep(10); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + int ret = OB_SUCCESS; + const int MAX_TRY_SELECT_CNT = 20; + int try_select_cnt = 0; + bool select_succ = false; + + while (++try_select_cnt <= MAX_TRY_SELECT_CNT) { + ObSqlString sql; + int64_t affected_rows = 0; + int64_t row_cnt = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign("select count(*) row_cnt from ttt1")); + SMART_VAR(ObMySQLProxy::MySQLResult, res) + { + if (OB_FAIL(sql_proxy.read(res, sql.ptr()))) { + // table or schema may not exist yet + ret = OB_SUCCESS; + } else { + sqlclient::ObMySQLResult *result = res.get_result(); + ASSERT_NE(nullptr, result); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("row_cnt", row_cnt)); + SERVER_LOG(INFO, "row count from test_tx_data_t : ", K(row_cnt)); + } + } + + if (row_cnt > 0) { + select_succ = true; + LOG_INFO("select done", K(try_select_cnt)); + break; + } else { + LOG_INFO("select once", K(try_select_cnt)); + ::sleep(1); + } + } + + ASSERT_EQ(select_succ, true); +} + +TEST_F(TestTransferHandler, prepare_valid_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + // create table + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt1(c1 int primary key, c2 blob) partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into ttt1 values(1, 'aaa')")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_idx on ttt1(c1) local")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_global ON ttt1(c1) global partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_part_list)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1_global'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_part_list)); + + // create 101 partitions + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt2(c1 int primary key) partition by hash(c1) partitions 101")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt2'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_batch_part_list)); +} + +TEST_F(TestTransferHandler, test_transfer_1001_to_1) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + //title: 1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + //check observer transfer + ObTransferStatus expected_status(ObTransferStatus::COMPLETED); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(g_tenant_id, task_id, expected_status, true/*is_from_his*/, inner_sql_proxy, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(g_tenant_id, task)); +} + +TEST_F(TestTransferRestart, observer_restart_basic) +{ + // init sql proxy2 to use tenant tt1 + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + SERVER_LOG(INFO, "observer restart succ"); + select_existed_data(); +} + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + int ret = 0; + int time_sec = 0; + ObSimpleServerRestartHelper restart_helper(argc, argv, TEST_FILE_NAME, BORN_CASE_NAME, + RESTART_CASE_NAME); + restart_helper.set_sleep_sec(time_sec); + restart_helper.run(); + return ret; +} diff --git a/mittest/simple_server/storage_ha/test_transfer_common_fun.h b/mittest/simple_server/storage_ha/test_transfer_common_fun.h new file mode 100644 index 000000000..7ed457630 --- /dev/null +++ b/mittest/simple_server/storage_ha/test_transfer_common_fun.h @@ -0,0 +1,288 @@ +#pragma once + +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "storage/high_availability/ob_transfer_handler.h" //ObTransferHandler +#include "lib/utility/utility.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_service.h" + +#include + +namespace oceanbase +{ +namespace storage +{ + +int wait_transfer_out_deleted_tablet_gc( + const uint64_t tenant_id, + const ObTransferTask &task) +{ + int ret = OB_SUCCESS; + MTL_SWITCH(tenant_id) { + const ObLSID &ls_id = task.src_ls_; + ObLS *ls = nullptr; + ObLSHandle ls_handle; + ObLSService *ls_svr = nullptr; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + + if (!task.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer out deleted tablet gc get invalid argument", K(ret), K(task)); + } else if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), K(task)); + } else if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else { + int64_t index = 0; + while (OB_SUCC(ret) && index < task.tablet_list_.count()) { + ObTabletHandle tablet_handle; + const ObTransferTabletInfo &transfer_info = task.tablet_list_.at(index); + if (OB_FAIL(ls->get_tablet(transfer_info.tablet_id_, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + index++; + } else { + LOG_WARN("failed to get tablet", K(ret), K(transfer_info)); + } + } else if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + ret = OB_TIMEOUT; + LOG_WARN("wait transfer out delete tablet gc timeout", K(ret), K(transfer_info)); + } else { + usleep(SLEEP_INTERVAL); + } + } + } + } + return ret; +} + +int wait_transfer_task( + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &expected_status, + const bool &is_from_his, + ObMySQLProxy &inner_sql_proxy, + ObTransferTask &task) +{ + int ret = OB_SUCCESS; + task.reset(); + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + bool get_task = false; + + if (!task_id.is_valid() || !expected_status.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer task get invalid argument", K(ret), K(task_id), K(expected_status)); + } else if (is_from_his) { + while (OB_SUCC(ret)) { + if (OB_FAIL(ObTransferTaskOperator::get_history_task(inner_sql_proxy, tenant_id, task_id, task, create_time, finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + LOG_WARN("cannot wait transfer task", K(ret), K(task_id), K(expected_status)); + } else { + ret = OB_SUCCESS; + usleep(SLEEP_INTERVAL); + } + } else { + LOG_WARN("failed to get history task", K(ret), K(task_id), K(expected_status)); + } + } else { + break; + } + } + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(ObTransferTaskOperator::get_task_with_time(inner_sql_proxy, tenant_id, task_id, false/*for_update*/, + task, create_time, finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + get_task = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get history task", K(ret), K(task_id), K(expected_status)); + } + } else if (task.get_status() != expected_status) { + get_task = false; + } else { + get_task = true; + break; + } + + if (OB_SUCC(ret) && !get_task) { + if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + LOG_WARN("cannot wait transfer task", K(ret), K(task_id), K(expected_status)); + } else { + ret = OB_SUCCESS; + usleep(SLEEP_INTERVAL); + } + } + } + } + return ret; +} + +int wait_transfer_task_after_restart( + const uint64_t tenant_id, + ObMySQLProxy &inner_sql_proxy) +{ + int ret = OB_SUCCESS; + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + bool get_task = false; + common::ObArray task_status; + + while (OB_SUCC(ret)) { + if (OB_FAIL(ObTransferTaskOperator::get_all_task_status(inner_sql_proxy, tenant_id, task_status))) { + if (OB_ENTRY_NOT_EXIST == ret) { + get_task = true; + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get all task status", K(ret)); + } + } else { + get_task = false; + } + + if (!get_task) { + if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + LOG_WARN("cannot wait transfer task", K(ret)); + } else { + ret = OB_SUCCESS; + usleep(SLEEP_INTERVAL); + } + } + } + return ret; +} + +int wait_start_transfer_tablet_mds_flush( + const uint64_t tenant_id, + const ObTransferTask &task) +{ + int ret = OB_SUCCESS; + MTL_SWITCH(tenant_id) { + const ObLSID &ls_id = task.dest_ls_; + ObLS *ls = nullptr; + ObLSHandle ls_handle; + ObLSService *ls_svr = nullptr; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + + if (!task.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer out deleted tablet gc get invalid argument", K(ret), K(task)); + } else if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), K(task)); + } else if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else { + int64_t index = 0; + const SCN &scn = task.start_scn_; + while (OB_SUCC(ret) && index < task.tablet_list_.count()) { + ObTabletHandle tablet_handle; + const ObTransferTabletInfo &transfer_info = task.tablet_list_.at(index); + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + bool unused_committed_flag = false; + if (OB_FAIL(ls->get_tablet(transfer_info.tablet_id_, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(transfer_info)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(transfer_info)); + } else if (tablet->get_tablet_meta().mds_checkpoint_scn_ <= scn) { + if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + ret = OB_TIMEOUT; + LOG_WARN("wait transfer out delete tablet gc timeout", K(ret), K(transfer_info)); + } else { + usleep(SLEEP_INTERVAL); + } + } else { + index++; + } + } + } + } + return ret; +} + +int wait_finish_transfer_tablet_mds_flush( + const uint64_t tenant_id, + const ObTransferTask &task) +{ + int ret = OB_SUCCESS; + MTL_SWITCH(tenant_id) { + const ObLSID &ls_id = task.dest_ls_; + ObLS *ls = nullptr; + ObLSHandle ls_handle; + ObLSService *ls_svr = nullptr; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + + if (!task.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer out deleted tablet gc get invalid argument", K(ret), K(task)); + } else if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), K(task)); + } else if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else { + int64_t index = 0; + const SCN &scn = task.finish_scn_; + while (OB_SUCC(ret) && index < task.tablet_list_.count()) { + ObTabletHandle tablet_handle; + const ObTransferTabletInfo &transfer_info = task.tablet_list_.at(index); + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + bool unused_committed_flag = false; + if (OB_FAIL(ls->get_tablet(transfer_info.tablet_id_, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(transfer_info)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(transfer_info)); + } else if (tablet->get_tablet_meta().mds_checkpoint_scn_ < scn) { + if (OB_FAIL(ObTabletCreateDeleteMdsUserData::set_tablet_gc_trigger(task.dest_ls_))) { + LOG_WARN("failed to set_tablet_gc_trigger", K(ret), K(task)); + } else if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + ret = OB_TIMEOUT; + LOG_WARN("wait transfer out delete tablet gc timeout", K(ret), K(transfer_info), KPC(tablet)); + } else { + usleep(SLEEP_INTERVAL); + } + } else { + index++; + } + } + } + } + return ret; +} + + +} +} diff --git a/mittest/simple_server/storage_ha/test_transfer_complete_restart_with_mds_flush.cpp b/mittest/simple_server/storage_ha/test_transfer_complete_restart_with_mds_flush.cpp new file mode 100644 index 000000000..1a2745afa --- /dev/null +++ b/mittest/simple_server/storage_ha/test_transfer_complete_restart_with_mds_flush.cpp @@ -0,0 +1,281 @@ +/** + * 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "test_transfer_common_fun.h" +#include "env/ob_simple_server_restart_helper.h" +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "storage/high_availability/ob_transfer_handler.h" //ObTransferHandler +#include "lib/utility/utility.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_service.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace storage +{ +using namespace share::schema; +using namespace common; +using namespace share; +using namespace transaction::tablelock; +using namespace rootserver; + +static uint64_t g_tenant_id; +static ObTransferPartList g_part_list; +static ObTransferPartList g_batch_part_list; + +static const char *TEST_FILE_NAME = "test_transfer_complete_restart_with_mds_flush"; +static const char *BORN_CASE_NAME = "TestTransferHandler"; +static const char *RESTART_CASE_NAME = "TestTransferRestart"; +static ObTransferTask g_task; + +class TestTransferHandler : public unittest::ObSimpleClusterTestBase +{ +public: + TestTransferHandler() : unittest::ObSimpleClusterTestBase(TEST_FILE_NAME) {} + int read_sql(ObMySQLProxy &sql_proxy, const ObSqlString &sql, ObTransferPartList &part_list); + int gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task); +}; + +int TestTransferHandler::read_sql( + ObMySQLProxy &sql_proxy, + const ObSqlString &sql, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + if (OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", table_id, uint64_t); + } + while(OB_SUCC(ret)) { + uint64_t part_id = OB_INVALID_ID; + ObTransferPartInfo part_info; + if (OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", part_id, uint64_t); + if (OB_FAIL(part_info.init(table_id, part_id))) { + } else if (OB_FAIL(part_list.push_back(part_info))) { + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +int TestTransferHandler::gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObLSID src_ls(1001); + ObLSID dest_ls(1002); + share::SCN start_scn; + share::SCN finish_scn; + start_scn.convert_for_inner_table_field(1666844202200632); + finish_scn.convert_for_inner_table_field(1666844202208490); + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ret = task.init(task_id, src_ls, dest_ls, ObString::make_string("500016:500014"), ObString("500030:500031"), ObString("500016:500015"), + ObString::make_string("1152921504606846983"), ObString::make_string("1152921504606846983:0"), start_scn, finish_scn, status, trace_id, OB_SUCCESS, + ObTransferTaskComment::EMPTY_COMMENT, ObBalanceTaskID(123), ObTableLockOwnerID(999)); + return ret; +} + +class TestTransferRestart : public ObSimpleClusterTestBase +{ +public: + TestTransferRestart() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} + void select_existed_data(); +}; + +void TestTransferRestart::select_existed_data() +{ + sleep(10); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + int ret = OB_SUCCESS; + const int MAX_TRY_SELECT_CNT = 20; + int try_select_cnt = 0; + bool select_succ = false; + + while (++try_select_cnt <= MAX_TRY_SELECT_CNT) { + ObSqlString sql; + int64_t affected_rows = 0; + int64_t row_cnt = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign("select count(*) row_cnt from ttt1")); + SMART_VAR(ObMySQLProxy::MySQLResult, res) + { + if (OB_FAIL(sql_proxy.read(res, sql.ptr()))) { + // table or schema may not exist yet + ret = OB_SUCCESS; + } else { + sqlclient::ObMySQLResult *result = res.get_result(); + ASSERT_NE(nullptr, result); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("row_cnt", row_cnt)); + SERVER_LOG(INFO, "row count from test_tx_data_t : ", K(row_cnt)); + } + } + + if (row_cnt > 0) { + select_succ = true; + LOG_INFO("select done", K(try_select_cnt)); + break; + } else { + LOG_INFO("select once", K(try_select_cnt)); + ::sleep(1); + } + } + + ASSERT_EQ(select_succ, true); +} + +TEST_F(TestTransferHandler, prepare_valid_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObMySQLProxy &sql_proxy2 = get_curr_simple_server().get_sql_proxy2(); + + //set transfer service wakup interval + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set _transfer_service_wakeup_interval = '5s'")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + + // create table + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt1(c1 int primary key, c2 blob) partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into ttt1 values(1, 'aaa')")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_idx on ttt1(c1) local")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_global ON ttt1(c1) global partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_part_list)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1_global'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_part_list)); + + // create 101 partitions + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt2(c1 int primary key) partition by hash(c1) partitions 101")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt2'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_batch_part_list)); +} + +TEST_F(TestTransferHandler, test_transfer_1001_to_1_with_transfer_finish_without_mds_flush) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // stuck tablet gc service flush mds + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set debug_sync_timeout = '1000s'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("set ob_global_debug_sync = 'BEFORE_CHECKPOINT_TASK wait_for signal execute 10000'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + //title: 1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + //check observer transfer + ObTransferStatus expected_status(ObTransferStatus::COMPLETED); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(g_tenant_id, task_id, expected_status, true/*is_from_his*/, inner_sql_proxy, task)); + LOG_INFO("s", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + g_task = task; + ASSERT_EQ(OB_SUCCESS, wait_finish_transfer_tablet_mds_flush(g_tenant_id, task)); +} + +TEST_F(TestTransferRestart, observer_restart_when_transfer_finish_without_flush) +{ + // init sql proxy2 to use tenant tt1 + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + SERVER_LOG(INFO, "observer restart succ"); + select_existed_data(); +} + + + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + int ret = 0; + int time_sec = 0; + ObSimpleServerRestartHelper restart_helper(argc, argv, TEST_FILE_NAME, BORN_CASE_NAME, + RESTART_CASE_NAME); + restart_helper.set_sleep_sec(time_sec); + restart_helper.run(); + return ret; +} diff --git a/mittest/simple_server/storage_ha/test_transfer_complete_restart_without_mds_flush.cpp b/mittest/simple_server/storage_ha/test_transfer_complete_restart_without_mds_flush.cpp new file mode 100644 index 000000000..1ba0123b8 --- /dev/null +++ b/mittest/simple_server/storage_ha/test_transfer_complete_restart_without_mds_flush.cpp @@ -0,0 +1,280 @@ +/** + * 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "test_transfer_common_fun.h" +#include "env/ob_simple_server_restart_helper.h" +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "storage/high_availability/ob_transfer_handler.h" //ObTransferHandler +#include "lib/utility/utility.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_service.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace storage +{ +using namespace share::schema; +using namespace common; +using namespace share; +using namespace transaction::tablelock; +using namespace rootserver; + +static uint64_t g_tenant_id; +static ObTransferPartList g_part_list; +static ObTransferPartList g_batch_part_list; + +static const char *TEST_FILE_NAME = "test_transfer_complete_restart_without_mds_flush"; +static const char *BORN_CASE_NAME = "TestTransferHandler"; +static const char *RESTART_CASE_NAME = "TestTransferRestart"; +static ObTransferTask g_task; + +class TestTransferHandler : public unittest::ObSimpleClusterTestBase +{ +public: + TestTransferHandler() : unittest::ObSimpleClusterTestBase(TEST_FILE_NAME) {} + int read_sql(ObMySQLProxy &sql_proxy, const ObSqlString &sql, ObTransferPartList &part_list); + int gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task); +}; + +int TestTransferHandler::read_sql( + ObMySQLProxy &sql_proxy, + const ObSqlString &sql, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + if (OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", table_id, uint64_t); + } + while(OB_SUCC(ret)) { + uint64_t part_id = OB_INVALID_ID; + ObTransferPartInfo part_info; + if (OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", part_id, uint64_t); + if (OB_FAIL(part_info.init(table_id, part_id))) { + } else if (OB_FAIL(part_list.push_back(part_info))) { + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +int TestTransferHandler::gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObLSID src_ls(1001); + ObLSID dest_ls(1002); + share::SCN start_scn; + share::SCN finish_scn; + start_scn.convert_for_inner_table_field(1666844202200632); + finish_scn.convert_for_inner_table_field(1666844202208490); + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ret = task.init(task_id, src_ls, dest_ls, ObString::make_string("500016:500014"), ObString("500030:500031"), ObString("500016:500015"), + ObString::make_string("1152921504606846983"), ObString::make_string("1152921504606846983:0"), start_scn, finish_scn, status, trace_id, OB_SUCCESS, + ObTransferTaskComment::EMPTY_COMMENT, ObBalanceTaskID(123), ObTableLockOwnerID(999)); + return ret; +} + +class TestTransferRestart : public ObSimpleClusterTestBase +{ +public: + TestTransferRestart() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} + void select_existed_data(); +}; + +void TestTransferRestart::select_existed_data() +{ + sleep(10); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + int ret = OB_SUCCESS; + const int MAX_TRY_SELECT_CNT = 20; + int try_select_cnt = 0; + bool select_succ = false; + + while (++try_select_cnt <= MAX_TRY_SELECT_CNT) { + ObSqlString sql; + int64_t affected_rows = 0; + int64_t row_cnt = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign("select count(*) row_cnt from ttt1")); + SMART_VAR(ObMySQLProxy::MySQLResult, res) + { + if (OB_FAIL(sql_proxy.read(res, sql.ptr()))) { + // table or schema may not exist yet + ret = OB_SUCCESS; + } else { + sqlclient::ObMySQLResult *result = res.get_result(); + ASSERT_NE(nullptr, result); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("row_cnt", row_cnt)); + SERVER_LOG(INFO, "row count from test_tx_data_t : ", K(row_cnt)); + } + } + + if (row_cnt > 0) { + select_succ = true; + LOG_INFO("select done", K(try_select_cnt)); + break; + } else { + LOG_INFO("select once", K(try_select_cnt)); + ::sleep(1); + } + } + + ASSERT_EQ(select_succ, true); +} + +TEST_F(TestTransferHandler, prepare_valid_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObMySQLProxy &sql_proxy2 = get_curr_simple_server().get_sql_proxy2(); + + //set transfer service wakup interval + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set _transfer_service_wakeup_interval = '5s'")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + + // create table + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt1(c1 int primary key, c2 blob) partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into ttt1 values(1, 'aaa')")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_idx on ttt1(c1) local")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_global ON ttt1(c1) global partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_part_list)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1_global'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_part_list)); + + // create 101 partitions + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt2(c1 int primary key) partition by hash(c1) partitions 101")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt2'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_batch_part_list)); +} + +TEST_F(TestTransferHandler, test_transfer_1001_to_1_with_transfer_finish_without_mds_flush) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // stuck tablet gc service flush mds + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set debug_sync_timeout = '1000s'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("set ob_global_debug_sync = 'BEFORE_TABLET_MDS_FLUSH wait_for signal execute 10000'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + //title: 1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + //check observer transfer + ObTransferStatus expected_status(ObTransferStatus::COMPLETED); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(g_tenant_id, task_id, expected_status, true/*is_from_his*/, inner_sql_proxy, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + g_task = task; +} + +TEST_F(TestTransferRestart, observer_restart_when_transfer_finish_without_flush) +{ + // init sql proxy2 to use tenant tt1 + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + SERVER_LOG(INFO, "observer restart succ"); + select_existed_data(); +} + + + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + int ret = 0; + int time_sec = 0; + ObSimpleServerRestartHelper restart_helper(argc, argv, TEST_FILE_NAME, BORN_CASE_NAME, + RESTART_CASE_NAME); + restart_helper.set_sleep_sec(time_sec); + restart_helper.run(); + return ret; +} diff --git a/mittest/simple_server/storage_ha/test_transfer_doing_stage_restart_with_mds_flush.cpp b/mittest/simple_server/storage_ha/test_transfer_doing_stage_restart_with_mds_flush.cpp new file mode 100644 index 000000000..fd412682f --- /dev/null +++ b/mittest/simple_server/storage_ha/test_transfer_doing_stage_restart_with_mds_flush.cpp @@ -0,0 +1,286 @@ +/** + * 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "test_transfer_common_fun.h" +#include "env/ob_simple_server_restart_helper.h" +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "storage/high_availability/ob_transfer_handler.h" //ObTransferHandler +#include "lib/utility/utility.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_service.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace storage +{ +using namespace share::schema; +using namespace common; +using namespace share; +using namespace transaction::tablelock; +using namespace rootserver; + +static uint64_t g_tenant_id; +static ObTransferPartList g_part_list; +static ObTransferPartList g_batch_part_list; + +static const char *TEST_FILE_NAME = "test_transfer_doing_stage_restart_with_mds_flush"; +static const char *BORN_CASE_NAME = "TestTransferHandler"; +static const char *RESTART_CASE_NAME = "TestTransferRestart"; + +class TestTransferHandler : public unittest::ObSimpleClusterTestBase +{ +public: + TestTransferHandler() : unittest::ObSimpleClusterTestBase(TEST_FILE_NAME) {} + int read_sql(ObMySQLProxy &sql_proxy, const ObSqlString &sql, ObTransferPartList &part_list); + int gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task); +}; + +int TestTransferHandler::read_sql( + ObMySQLProxy &sql_proxy, + const ObSqlString &sql, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + if (OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", table_id, uint64_t); + } + while(OB_SUCC(ret)) { + uint64_t part_id = OB_INVALID_ID; + ObTransferPartInfo part_info; + if (OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", part_id, uint64_t); + if (OB_FAIL(part_info.init(table_id, part_id))) { + } else if (OB_FAIL(part_list.push_back(part_info))) { + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +int TestTransferHandler::gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObLSID src_ls(1001); + ObLSID dest_ls(1002); + share::SCN start_scn; + share::SCN finish_scn; + start_scn.convert_for_inner_table_field(1666844202200632); + finish_scn.convert_for_inner_table_field(1666844202208490); + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ret = task.init(task_id, src_ls, dest_ls, ObString::make_string("500016:500014"), ObString("500030:500031"), ObString("500016:500015"), + ObString::make_string("1152921504606846983"), ObString::make_string("1152921504606846983:0"), start_scn, finish_scn, status, trace_id, OB_SUCCESS, + ObTransferTaskComment::EMPTY_COMMENT, ObBalanceTaskID(123), ObTableLockOwnerID(999)); + return ret; +} + +class TestTransferRestart : public ObSimpleClusterTestBase +{ +public: + TestTransferRestart() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} + void select_existed_data(); +}; + +void TestTransferRestart::select_existed_data() +{ + sleep(10); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + int ret = OB_SUCCESS; + const int MAX_TRY_SELECT_CNT = 20; + int try_select_cnt = 0; + bool select_succ = false; + + while (++try_select_cnt <= MAX_TRY_SELECT_CNT) { + ObSqlString sql; + int64_t affected_rows = 0; + int64_t row_cnt = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign("select count(*) row_cnt from ttt1")); + SMART_VAR(ObMySQLProxy::MySQLResult, res) + { + if (OB_FAIL(sql_proxy.read(res, sql.ptr()))) { + // table or schema may not exist yet + ret = OB_SUCCESS; + } else { + sqlclient::ObMySQLResult *result = res.get_result(); + ASSERT_NE(nullptr, result); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("row_cnt", row_cnt)); + SERVER_LOG(INFO, "row count from test_tx_data_t : ", K(row_cnt)); + } + } + + if (row_cnt > 0) { + select_succ = true; + LOG_INFO("select done", K(try_select_cnt)); + break; + } else { + LOG_INFO("select once", K(try_select_cnt)); + ::sleep(1); + } + } + + ASSERT_EQ(select_succ, true); +} + +TEST_F(TestTransferHandler, prepare_valid_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObMySQLProxy &sql_proxy2 = get_curr_simple_server().get_sql_proxy2(); + + //set transfer service wakup interval + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set _transfer_service_wakeup_interval = '5s'")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + + // create table + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt1(c1 int primary key, c2 blob) partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into ttt1 values(1, 'aaa')")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_idx on ttt1(c1) local")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_global ON ttt1(c1) global partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_part_list)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1_global'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_part_list)); + + // create 101 partitions + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt2(c1 int primary key) partition by hash(c1) partitions 101")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt2'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_batch_part_list)); +} + +TEST_F(TestTransferHandler, test_transfer_1001_to_1_with_transfer_start_with_mds_flush) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // stuck tablet gc service flush mds + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set debug_sync_timeout = '1000s'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("set ob_global_debug_sync = 'BEFORE_CHECKPOINT_TASK wait_for signal execute 10000'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("set ob_global_debug_sync = 'SWITCH_LEADER_BEFORE_TRANSFER_DOING_START_TRANS wait_for signal1 execute 10000'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + //title: 1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + //check observer transfer + ObTransferStatus expected_status(ObTransferStatus::DOING); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(g_tenant_id, task_id, expected_status, false/*is_from_his*/, inner_sql_proxy, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, wait_start_transfer_tablet_mds_flush(g_tenant_id, task)); +} + +TEST_F(TestTransferRestart, observer_restart_when_transfer_start_without_flush) +{ + // init sql proxy2 to use tenant tt1 + g_tenant_id = 1002; + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + SERVER_LOG(INFO, "observer restart succ"); + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + //check observer transfer + ASSERT_EQ(OB_SUCCESS, wait_transfer_task_after_restart(g_tenant_id, inner_sql_proxy)); + select_existed_data(); +} + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + int ret = 0; + int time_sec = 0; + ObSimpleServerRestartHelper restart_helper(argc, argv, TEST_FILE_NAME, BORN_CASE_NAME, + RESTART_CASE_NAME); + restart_helper.set_sleep_sec(time_sec); + restart_helper.run(); + return ret; +} diff --git a/mittest/simple_server/storage_ha/test_transfer_doing_stage_restart_without_mds_flush.cpp b/mittest/simple_server/storage_ha/test_transfer_doing_stage_restart_without_mds_flush.cpp new file mode 100644 index 000000000..ca2508ea4 --- /dev/null +++ b/mittest/simple_server/storage_ha/test_transfer_doing_stage_restart_without_mds_flush.cpp @@ -0,0 +1,286 @@ +/** + * 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "test_transfer_common_fun.h" +#include "env/ob_simple_server_restart_helper.h" +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "storage/high_availability/ob_transfer_handler.h" //ObTransferHandler +#include "lib/utility/utility.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_service.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace storage +{ +using namespace share::schema; +using namespace common; +using namespace share; +using namespace transaction::tablelock; +using namespace rootserver; + +static uint64_t g_tenant_id; +static ObTransferPartList g_part_list; +static ObTransferPartList g_batch_part_list; + +static const char *TEST_FILE_NAME = "test_transfer_doing_stage_restart_without_mds_flush"; +static const char *BORN_CASE_NAME = "TestTransferHandler"; +static const char *RESTART_CASE_NAME = "TestTransferRestart"; + +class TestTransferHandler : public unittest::ObSimpleClusterTestBase +{ +public: + TestTransferHandler() : unittest::ObSimpleClusterTestBase(TEST_FILE_NAME) {} + int read_sql(ObMySQLProxy &sql_proxy, const ObSqlString &sql, ObTransferPartList &part_list); + int gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task); +}; + +int TestTransferHandler::read_sql( + ObMySQLProxy &sql_proxy, + const ObSqlString &sql, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + if (OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", table_id, uint64_t); + } + while(OB_SUCC(ret)) { + uint64_t part_id = OB_INVALID_ID; + ObTransferPartInfo part_info; + if (OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", part_id, uint64_t); + if (OB_FAIL(part_info.init(table_id, part_id))) { + } else if (OB_FAIL(part_list.push_back(part_info))) { + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +int TestTransferHandler::gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObLSID src_ls(1001); + ObLSID dest_ls(1002); + share::SCN start_scn; + share::SCN finish_scn; + start_scn.convert_for_inner_table_field(1666844202200632); + finish_scn.convert_for_inner_table_field(1666844202208490); + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ret = task.init(task_id, src_ls, dest_ls, ObString::make_string("500016:500014"), ObString("500030:500031"), ObString("500016:500015"), + ObString::make_string("1152921504606846983"), ObString::make_string("1152921504606846983:0"), start_scn, finish_scn, status, trace_id, OB_SUCCESS, + ObTransferTaskComment::EMPTY_COMMENT, ObBalanceTaskID(123), ObTableLockOwnerID(999)); + return ret; +} + +class TestTransferRestart : public ObSimpleClusterTestBase +{ +public: + TestTransferRestart() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} + void select_existed_data(); +}; + +void TestTransferRestart::select_existed_data() +{ + sleep(10); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + int ret = OB_SUCCESS; + const int MAX_TRY_SELECT_CNT = 20; + int try_select_cnt = 0; + bool select_succ = false; + + while (++try_select_cnt <= MAX_TRY_SELECT_CNT) { + ObSqlString sql; + int64_t affected_rows = 0; + int64_t row_cnt = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign("select count(*) row_cnt from ttt1")); + SMART_VAR(ObMySQLProxy::MySQLResult, res) + { + if (OB_FAIL(sql_proxy.read(res, sql.ptr()))) { + // table or schema may not exist yet + ret = OB_SUCCESS; + } else { + sqlclient::ObMySQLResult *result = res.get_result(); + ASSERT_NE(nullptr, result); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("row_cnt", row_cnt)); + SERVER_LOG(INFO, "row count from test_tx_data_t : ", K(row_cnt)); + } + } + + if (row_cnt > 0) { + select_succ = true; + LOG_INFO("select done", K(try_select_cnt)); + break; + } else { + LOG_INFO("select once", K(try_select_cnt)); + ::sleep(1); + } + } + + ASSERT_EQ(select_succ, true); +} + +TEST_F(TestTransferHandler, prepare_valid_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObMySQLProxy &sql_proxy2 = get_curr_simple_server().get_sql_proxy2(); + + //set transfer service wakup interval + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set _transfer_service_wakeup_interval = '5s'")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + + // create table + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt1(c1 int primary key, c2 blob) partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into ttt1 values(1, 'aaa')")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_idx on ttt1(c1) local")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_global ON ttt1(c1) global partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_part_list)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1_global'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_part_list)); + + // create 101 partitions + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt2(c1 int primary key) partition by hash(c1) partitions 101")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt2'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_batch_part_list)); +} + +TEST_F(TestTransferHandler, test_transfer_1_to_1001_with_transfer_doing_without_mds_flush) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // stuck tablet gc service flush mds + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set debug_sync_timeout = '1000s'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("set ob_global_debug_sync = 'BEFORE_TABLET_MDS_FLUSH wait_for signal execute 10000'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("set ob_global_debug_sync = 'SWITCH_LEADER_BETWEEN_FINISH_TRANSFER_IN_AND_OUT wait_for signal1 execute 10000'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + //title: 1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + //check observer transfer + ObTransferStatus expected_status(ObTransferStatus::DOING); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(g_tenant_id, task_id, expected_status, false/*is_from_his*/, inner_sql_proxy, task)); + LOG_INFO("generate transfer task", K(task)); +} + +TEST_F(TestTransferRestart, observer_restart_when_transfer_doing_without_flush) +{ + // init sql proxy2 to use tenant tt1 + g_tenant_id = 1002; + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + SERVER_LOG(INFO, "observer restart succ"); + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + //check observer transfer + ASSERT_EQ(OB_SUCCESS, wait_transfer_task_after_restart(g_tenant_id, inner_sql_proxy)); + select_existed_data(); +} + + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + int ret = 0; + int time_sec = 0; + ObSimpleServerRestartHelper restart_helper(argc, argv, TEST_FILE_NAME, BORN_CASE_NAME, + RESTART_CASE_NAME); + restart_helper.set_sleep_sec(time_sec); + restart_helper.run(); + return ret; +} diff --git a/mittest/simple_server/storage_ha/test_transfer_handler.cpp b/mittest/simple_server/storage_ha/test_transfer_handler.cpp new file mode 100644 index 000000000..ba36a1b6e --- /dev/null +++ b/mittest/simple_server/storage_ha/test_transfer_handler.cpp @@ -0,0 +1,360 @@ +/** + * 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "storage/high_availability/ob_transfer_handler.h" //ObTransferHandler +#include "lib/utility/utility.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_service.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace storage +{ +using namespace share::schema; +using namespace common; +using namespace share; +using namespace transaction::tablelock; +using namespace rootserver; + +static uint64_t g_tenant_id; +static ObTransferPartList g_part_list; +static ObTransferPartList g_batch_part_list; + +class TestTransferHandler : public unittest::ObSimpleClusterTestBase +{ +public: + TestTransferHandler() : unittest::ObSimpleClusterTestBase("test_transfer_handler") {} + int read_sql(ObMySQLProxy &sql_proxy, const ObSqlString &sql, ObTransferPartList &part_list); + int gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task); + int wait_transfer_task( + const ObTransferTaskID task_id, + const ObTransferStatus &expected_status, + const bool &is_from_his, + ObTransferTask &task); + int wait_transfer_out_deleted_tablet_gc( + const ObTransferTask &task); +}; + +int TestTransferHandler::read_sql( + ObMySQLProxy &sql_proxy, + const ObSqlString &sql, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + if (OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", table_id, uint64_t); + } + while(OB_SUCC(ret)) { + uint64_t part_id = OB_INVALID_ID; + ObTransferPartInfo part_info; + if (OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", part_id, uint64_t); + if (OB_FAIL(part_info.init(table_id, part_id))) { + } else if (OB_FAIL(part_list.push_back(part_info))) { + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +int TestTransferHandler::gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObLSID src_ls(1001); + ObLSID dest_ls(1002); + share::SCN start_scn; + share::SCN finish_scn; + start_scn.convert_for_inner_table_field(1666844202200632); + finish_scn.convert_for_inner_table_field(1666844202208490); + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ret = task.init(task_id, src_ls, dest_ls, ObString::make_string("500016:500014"), ObString("500030:500031"), ObString("500016:500015"), + ObString::make_string("1152921504606846983"), ObString::make_string("1152921504606846983:0"), start_scn, finish_scn, status, trace_id, OB_SUCCESS, + ObTransferTaskComment::EMPTY_COMMENT, ObBalanceTaskID(123), ObTableLockOwnerID(999)); + return ret; +} + +int TestTransferHandler::wait_transfer_task( + const ObTransferTaskID task_id, + const ObTransferStatus &expected_status, + const bool &is_from_his, + ObTransferTask &task) +{ + int ret = OB_SUCCESS; + task.reset(); + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + bool get_task = false; + + if (!task_id.is_valid() || !expected_status.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer task get invalid argument", K(ret), K(task_id), K(expected_status)); + } else if (is_from_his) { + while (OB_SUCC(ret)) { + if (OB_FAIL(ObTransferTaskOperator::get_history_task(inner_sql_proxy, g_tenant_id, task_id, task, create_time, finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + LOG_WARN("cannot wait transfer task", K(ret), K(task_id), K(expected_status)); + } else { + ret = OB_SUCCESS; + usleep(SLEEP_INTERVAL); + } + } else { + LOG_WARN("failed to get history task", K(ret), K(task_id), K(expected_status)); + } + } else { + break; + } + } + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(ObTransferTaskOperator::get_task_with_time(inner_sql_proxy, g_tenant_id, task_id, false/*for_update*/, + task, create_time, finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + get_task = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get history task", K(ret), K(task_id), K(expected_status)); + } + } else if (task.get_status() != expected_status) { + get_task = false; + } else { + get_task = true; + break; + } + + if (OB_SUCC(ret) && !get_task) { + if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + LOG_WARN("cannot wait transfer task", K(ret), K(task_id), K(expected_status)); + } else { + ret = OB_SUCCESS; + usleep(SLEEP_INTERVAL); + } + } + } + } + return ret; +} + +int TestTransferHandler::wait_transfer_out_deleted_tablet_gc( + const ObTransferTask &task) +{ + int ret = OB_SUCCESS; + MTL_SWITCH(g_tenant_id) { + const ObLSID &ls_id = task.src_ls_; + ObLS *ls = nullptr; + ObLSHandle ls_handle; + ObLSService *ls_svr = nullptr; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + + if (!task.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer out deleted tablet gc get invalid argument", K(ret), K(task)); + } else if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), K(task)); + } else if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else { + int64_t index = 0; + while (OB_SUCC(ret) && index < task.tablet_list_.count()) { + ObTabletHandle tablet_handle; + const ObTransferTabletInfo &transfer_info = task.tablet_list_.at(index); + if (OB_FAIL(ls->get_tablet(transfer_info.tablet_id_, tablet_handle, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + index++; + } else { + LOG_WARN("failed to get tablet", K(ret), K(transfer_info)); + } + } else if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + ret = OB_TIMEOUT; + LOG_WARN("wait transfer out delete tablet gc timeout", K(ret), K(transfer_info)); + } else { + usleep(SLEEP_INTERVAL); + } + } + } + } + return ret; +} + +TEST_F(TestTransferHandler, prepare_valid_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + usleep(5 * 1000 * 1000); + + // create table + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt1(c1 int primary key, c2 blob) partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_idx on ttt1(c1) local")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_global ON ttt1(c1) global partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_part_list)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1_global'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_part_list)); + + // create 101 partitions + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt2(c1 int primary key) partition by hash(c1) partitions 101")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt2'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_batch_part_list)); +} + +TEST_F(TestTransferHandler, test_transfer_1001_to_1) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // stuck storage transfer + //ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set debug_sync_timeout = '1000s'")); + //ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + //usleep(100000); // wait for debug_sync_timeout to take effect + //sql.reset(); + //ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("set ob_global_debug_sync = 'BEFORE_START_TRANSFER_TRANS wait_for signal execute 10000'")); + //ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + //title: 1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + //check observer transfer + ObTransferStatus expected_status(ObTransferStatus::COMPLETED); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +TEST_F(TestTransferHandler, test_transfer_1_to_1001) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + //title: 1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1), ObLSID(1001), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + //check observer transfer + ObTransferStatus expected_status(ObTransferStatus::COMPLETED); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_gc(task)); +} + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/storage_ha/test_transfer_lock_info_operator.cpp b/mittest/simple_server/storage_ha/test_transfer_lock_info_operator.cpp new file mode 100644 index 000000000..977a69d94 --- /dev/null +++ b/mittest/simple_server/storage_ha/test_transfer_lock_info_operator.cpp @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE +#include +#define private public +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log.h" +#include "storage/high_availability/ob_transfer_lock_info_operator.h" +#include "share/transfer/ob_transfer_info.h" + +namespace oceanbase +{ +namespace unittest +{ +using ::testing::_; +using ::testing::Invoke; +using ::testing::Return; + +using namespace schema; +using namespace rootserver; +using namespace common; +class TestTransferLockInfoOperator : public unittest::ObSimpleClusterTestBase +{ +public: + TestTransferLockInfoOperator() : unittest::ObSimpleClusterTestBase("test_transfer_lock_operator") {} +protected: + uint64_t tenant_id_; + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + int64_t task_id_; +}; + +TEST_F(TestTransferLockInfoOperator, TransferLockInfo) +{ + int ret = OB_SUCCESS; + tenant_id_ = OB_SYS_TENANT_ID; + src_ls_id_ = ObLSID(1001); + dest_ls_id_ = ObLSID(1002); + task_id_ = 1; + ObTransferLockStatus start_status = ObTransferLockStatus(ObTransferLockStatus::START); + ObTransferLockStatus doing_status = ObTransferLockStatus(ObTransferLockStatus::DOING); + int64_t start_src_lock_owner = 111; + int64_t start_dest_lock_owner = 222; + ObString comment("LOCK_AT_START"); + + // ObTransferTaskLockInfo INIT + ObTransferTaskLockInfo start_src_lock_info; + ObTransferTaskLockInfo start_dest_lock_info; + ASSERT_EQ(OB_SUCCESS, start_src_lock_info.set(tenant_id_, src_ls_id_, task_id_, start_status, start_src_lock_owner, comment)); + ASSERT_EQ(OB_SUCCESS, start_dest_lock_info.set(tenant_id_, dest_ls_id_, task_id_, start_status, start_dest_lock_owner, comment)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2("sys", "oceanbase")); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + // insert + ASSERT_EQ(OB_SUCCESS, ObTransferLockInfoOperator::insert(start_src_lock_info, sql_proxy)); + ASSERT_EQ(OB_SUCCESS, ObTransferLockInfoOperator::insert(start_dest_lock_info, sql_proxy)); + + // select + ObTransferLockInfoRowKey src_row_key; + src_row_key.tenant_id_ = tenant_id_; + src_row_key.ls_id_ = src_ls_id_; + ObTransferLockInfoRowKey dest_row_key; + dest_row_key.tenant_id_ = tenant_id_; + dest_row_key.ls_id_ = dest_ls_id_; + + ObTransferTaskLockInfo new_start_src_lock_info; + ObTransferTaskLockInfo new_start_dest_lock_info; + + ASSERT_EQ(OB_SUCCESS, ObTransferLockInfoOperator::get(src_row_key, task_id_, start_status, false, new_start_src_lock_info, sql_proxy)); + ASSERT_EQ(OB_SUCCESS, ObTransferLockInfoOperator::get(dest_row_key, task_id_, start_status, false, new_start_dest_lock_info, sql_proxy)); + + LOG_INFO("[MITTEST]transfer_lock_info", K(new_start_src_lock_info)); + ASSERT_EQ(new_start_src_lock_info.tenant_id_, start_src_lock_info.tenant_id_); + ASSERT_EQ(new_start_src_lock_info.ls_id_, start_src_lock_info.ls_id_); + ASSERT_EQ(new_start_src_lock_info.task_id_, start_src_lock_info.task_id_); + ASSERT_EQ(new_start_src_lock_info.status_.status_, start_src_lock_info.status_.status_); + ASSERT_EQ(new_start_src_lock_info.lock_owner_, start_src_lock_info.lock_owner_); + + LOG_INFO("[MITTEST]transfer_lock_info", K(new_start_dest_lock_info)); + ASSERT_EQ(new_start_dest_lock_info.tenant_id_, start_dest_lock_info.tenant_id_); + ASSERT_EQ(new_start_dest_lock_info.ls_id_, start_dest_lock_info.ls_id_); + ASSERT_EQ(new_start_dest_lock_info.task_id_, start_dest_lock_info.task_id_); + ASSERT_EQ(new_start_dest_lock_info.status_.status_, start_dest_lock_info.status_.status_); + ASSERT_EQ(new_start_dest_lock_info.lock_owner_, start_dest_lock_info.lock_owner_); + + // remove + ASSERT_EQ(OB_SUCCESS, ObTransferLockInfoOperator::remove(tenant_id_, src_ls_id_, task_id_, start_status, sql_proxy)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferLockInfoOperator::get(src_row_key, task_id_, start_status, false, new_start_src_lock_info, sql_proxy)); + + ASSERT_EQ(OB_SUCCESS, ObTransferLockInfoOperator::remove(tenant_id_, dest_ls_id_, task_id_, start_status, sql_proxy)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferLockInfoOperator::get(src_row_key, task_id_, start_status, false, new_start_dest_lock_info, sql_proxy)); +} + +} // namespace +} // namespace oceanbase + +int main(int argc, char **argv) +{ + oceanbase::unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/storage_ha/test_transfer_start_stage_restart_without_mds_flush.cpp b/mittest/simple_server/storage_ha/test_transfer_start_stage_restart_without_mds_flush.cpp new file mode 100644 index 000000000..79f8b15c7 --- /dev/null +++ b/mittest/simple_server/storage_ha/test_transfer_start_stage_restart_without_mds_flush.cpp @@ -0,0 +1,285 @@ +/** + * 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "test_transfer_common_fun.h" +#include "env/ob_simple_server_restart_helper.h" +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "storage/high_availability/ob_transfer_handler.h" //ObTransferHandler +#include "lib/utility/utility.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_service.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace storage +{ +using namespace share::schema; +using namespace common; +using namespace share; +using namespace transaction::tablelock; +using namespace rootserver; + +static uint64_t g_tenant_id; +static ObTransferPartList g_part_list; +static ObTransferPartList g_batch_part_list; + +static const char *TEST_FILE_NAME = "test_transfer_start_stage_restart_without_mds_flush"; +static const char *BORN_CASE_NAME = "TestTransferHandler"; +static const char *RESTART_CASE_NAME = "TestTransferRestart"; + +class TestTransferHandler : public unittest::ObSimpleClusterTestBase +{ +public: + TestTransferHandler() : unittest::ObSimpleClusterTestBase(TEST_FILE_NAME) {} + int read_sql(ObMySQLProxy &sql_proxy, const ObSqlString &sql, ObTransferPartList &part_list); + int gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task); +}; + +int TestTransferHandler::read_sql( + ObMySQLProxy &sql_proxy, + const ObSqlString &sql, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + if (OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", table_id, uint64_t); + } + while(OB_SUCC(ret)) { + uint64_t part_id = OB_INVALID_ID; + ObTransferPartInfo part_info; + if (OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", part_id, uint64_t); + if (OB_FAIL(part_info.init(table_id, part_id))) { + } else if (OB_FAIL(part_list.push_back(part_info))) { + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +int TestTransferHandler::gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObLSID src_ls(1001); + ObLSID dest_ls(1002); + share::SCN start_scn; + share::SCN finish_scn; + start_scn.convert_for_inner_table_field(1666844202200632); + finish_scn.convert_for_inner_table_field(1666844202208490); + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ret = task.init(task_id, src_ls, dest_ls, ObString::make_string("500016:500014"), ObString("500030:500031"), ObString("500016:500015"), + ObString::make_string("1152921504606846983"), ObString::make_string("1152921504606846983:0"), start_scn, finish_scn, status, trace_id, OB_SUCCESS, + ObTransferTaskComment::EMPTY_COMMENT, ObBalanceTaskID(123), ObTableLockOwnerID(999)); + return ret; +} + +class TestTransferRestart : public ObSimpleClusterTestBase +{ +public: + TestTransferRestart() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} + void select_existed_data(); +}; + +void TestTransferRestart::select_existed_data() +{ + sleep(10); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + int ret = OB_SUCCESS; + const int MAX_TRY_SELECT_CNT = 20; + int try_select_cnt = 0; + bool select_succ = false; + + while (++try_select_cnt <= MAX_TRY_SELECT_CNT) { + ObSqlString sql; + int64_t affected_rows = 0; + int64_t row_cnt = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign("select count(*) row_cnt from ttt1")); + SMART_VAR(ObMySQLProxy::MySQLResult, res) + { + if (OB_FAIL(sql_proxy.read(res, sql.ptr()))) { + // table or schema may not exist yet + ret = OB_SUCCESS; + } else { + sqlclient::ObMySQLResult *result = res.get_result(); + ASSERT_NE(nullptr, result); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("row_cnt", row_cnt)); + SERVER_LOG(INFO, "row count from test_tx_data_t : ", K(row_cnt)); + } + } + + if (row_cnt > 0) { + select_succ = true; + LOG_INFO("select done", K(try_select_cnt)); + break; + } else { + LOG_INFO("select once", K(try_select_cnt)); + ::sleep(1); + } + } + + ASSERT_EQ(select_succ, true); +} + +TEST_F(TestTransferHandler, prepare_valid_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObMySQLProxy &sql_proxy2 = get_curr_simple_server().get_sql_proxy2(); + + //set transfer service wakup interval + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set _transfer_service_wakeup_interval = '5s'")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + + // create table + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt1(c1 int primary key, c2 blob) partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into ttt1 values(1, 'aaa')")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_idx on ttt1(c1) local")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_global ON ttt1(c1) global partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_part_list)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1_global'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_part_list)); + + // create 101 partitions + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt2(c1 int primary key) partition by hash(c1) partitions 101")); + ASSERT_EQ(OB_SUCCESS, sql_proxy2.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt2'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy2, sql, g_batch_part_list)); +} + +TEST_F(TestTransferHandler, test_transfer_1001_to_1_with_transfer_start_without_mds_flush) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // stuck tablet gc service flush mds + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set debug_sync_timeout = '1000s'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("set ob_global_debug_sync = 'BEFORE_TABLET_MDS_FLUSH wait_for signal execute 10000'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("set ob_global_debug_sync = 'AFTER_START_TRANSFER_IN wait_for signal1 execute 10000'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + //title: 1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + //check observer transfer + ObTransferStatus expected_status(ObTransferStatus::START); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(g_tenant_id, task_id, expected_status, false/*is_from_his*/, inner_sql_proxy, task)); + LOG_INFO("generate transfer task", K(task)); +} + +TEST_F(TestTransferRestart, observer_restart_when_transfer_start_without_flush) +{ + // init sql proxy2 to use tenant tt1 + g_tenant_id = 1002; + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + SERVER_LOG(INFO, "observer restart succ"); + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + //check observer transfer + ASSERT_EQ(OB_SUCCESS, wait_transfer_task_after_restart(g_tenant_id, inner_sql_proxy)); + select_existed_data(); +} + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + int ret = 0; + int time_sec = 0; + ObSimpleServerRestartHelper restart_helper(argc, argv, TEST_FILE_NAME, BORN_CASE_NAME, + RESTART_CASE_NAME); + restart_helper.set_sleep_sec(time_sec); + restart_helper.run(); + return ret; +} diff --git a/mittest/simple_server/storage_ha/test_transfer_with_empty_shell.cpp b/mittest/simple_server/storage_ha/test_transfer_with_empty_shell.cpp new file mode 100644 index 000000000..6596203bf --- /dev/null +++ b/mittest/simple_server/storage_ha/test_transfer_with_empty_shell.cpp @@ -0,0 +1,357 @@ +/** + * 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "storage/high_availability/ob_transfer_handler.h" //ObTransferHandler +#include "lib/utility/utility.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_service.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace storage +{ +using namespace share::schema; +using namespace common; +using namespace share; +using namespace transaction::tablelock; +using namespace rootserver; + +static uint64_t g_tenant_id; +static ObTransferPartList g_part_list; +static ObTransferPartList g_batch_part_list; + +class TestTransferHandler : public unittest::ObSimpleClusterTestBase +{ +public: + TestTransferHandler() : unittest::ObSimpleClusterTestBase("test_transfer_handler") {} + int read_sql(ObMySQLProxy &sql_proxy, const ObSqlString &sql, ObTransferPartList &part_list); + int gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task); + int wait_transfer_task( + const ObTransferTaskID task_id, + const ObTransferStatus &expected_status, + const bool &is_from_his, + ObTransferTask &task); + int wait_transfer_out_deleted_tablet_become_empty_shell( + const ObTransferTask &task); +}; + +int TestTransferHandler::read_sql( + ObMySQLProxy &sql_proxy, + const ObSqlString &sql, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + if (OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", table_id, uint64_t); + } + while(OB_SUCC(ret)) { + uint64_t part_id = OB_INVALID_ID; + ObTransferPartInfo part_info; + if (OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", part_id, uint64_t); + if (OB_FAIL(part_info.init(table_id, part_id))) { + } else if (OB_FAIL(part_list.push_back(part_info))) { + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +int TestTransferHandler::gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObLSID src_ls(1001); + ObLSID dest_ls(1002); + share::SCN start_scn; + share::SCN finish_scn; + start_scn.convert_for_inner_table_field(1666844202200632); + finish_scn.convert_for_inner_table_field(1666844202208490); + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ret = task.init(task_id, src_ls, dest_ls, ObString::make_string("500016:500014"), ObString("500030:500031"), ObString("500016:500015"), + ObString::make_string("1152921504606846983"), ObString::make_string("1152921504606846983:0"), start_scn, finish_scn, status, trace_id, OB_SUCCESS, + ObTransferTaskComment::EMPTY_COMMENT, ObBalanceTaskID(123), ObTableLockOwnerID(999)); + return ret; +} + +int TestTransferHandler::wait_transfer_task( + const ObTransferTaskID task_id, + const ObTransferStatus &expected_status, + const bool &is_from_his, + ObTransferTask &task) +{ + int ret = OB_SUCCESS; + task.reset(); + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + bool get_task = false; + + if (!task_id.is_valid() || !expected_status.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer task get invalid argument", K(ret), K(task_id), K(expected_status)); + } else if (is_from_his) { + while (OB_SUCC(ret)) { + if (OB_FAIL(ObTransferTaskOperator::get_history_task(inner_sql_proxy, g_tenant_id, task_id, task, create_time, finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + LOG_WARN("cannot wait transfer task", K(ret), K(task_id), K(expected_status)); + } else { + ret = OB_SUCCESS; + usleep(SLEEP_INTERVAL); + } + } else { + LOG_WARN("failed to get history task", K(ret), K(task_id), K(expected_status)); + } + } else { + break; + } + } + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(ObTransferTaskOperator::get_task_with_time(inner_sql_proxy, g_tenant_id, task_id, false/*for_update*/, + task, create_time, finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + get_task = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get history task", K(ret), K(task_id), K(expected_status)); + } + } else if (task.get_status() != expected_status) { + get_task = false; + } else { + get_task = true; + break; + } + + if (OB_SUCC(ret) && !get_task) { + if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + LOG_WARN("cannot wait transfer task", K(ret), K(task_id), K(expected_status)); + } else { + ret = OB_SUCCESS; + usleep(SLEEP_INTERVAL); + } + } + } + } + return ret; +} + +int TestTransferHandler::wait_transfer_out_deleted_tablet_become_empty_shell( + const ObTransferTask &task) +{ + int ret = OB_SUCCESS; + MTL_SWITCH(g_tenant_id) { + const ObLSID &ls_id = task.src_ls_; + ObLS *ls = nullptr; + ObLSHandle ls_handle; + ObLSService *ls_svr = nullptr; + const int64_t current_time = ObTimeUtil::current_time(); + const int64_t MAX_WAIT_TIME = 5 * 60 * 1000 * 1000; //5min + const int64_t SLEEP_INTERVAL = 200 * 1000; // 200ms + + if (!task.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer out deleted tablet gc get invalid argument", K(ret), K(task)); + } else if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), K(task)); + } else if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else { + int64_t index = 0; + while (OB_SUCC(ret) && index < task.tablet_list_.count()) { + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + const ObTransferTabletInfo &transfer_info = task.tablet_list_.at(index); + if (OB_FAIL(ls->get_tablet(transfer_info.tablet_id_, tablet_handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + LOG_WARN("failed to get tablet", K(ret), K(transfer_info)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); + } else if (tablet->is_empty_shell()) { + index++; + } else if (ObTimeUtil::current_time() - current_time >= MAX_WAIT_TIME) { + ret = OB_TIMEOUT; + LOG_WARN("wait transfer out delete tablet gc timeout", K(ret), K(transfer_info)); + } else { + usleep(SLEEP_INTERVAL); + } + } + } + } + return ret; +} + +TEST_F(TestTransferHandler, prepare_valid_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + // create table + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt1(c1 int primary key, c2 blob) partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_idx on ttt1(c1) local")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create index ttt1_global ON ttt1(c1) global partition by hash(c1) partitions 2")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_part_list)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1_global'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_part_list)); + + // create 101 partitions + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("create table ttt2(c1 int primary key) partition by hash(c1) partitions 101")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt2'")); + ASSERT_EQ(OB_SUCCESS, read_sql(sql_proxy, sql, g_batch_part_list)); +} + +TEST_F(TestTransferHandler, test_transfer_1001_to_1) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // stuck tablet gc + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set debug_sync_timeout = '1000s'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("set ob_global_debug_sync = 'BEFORE_TABLET_GC wait_for signal execute 10000'")); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + //title: 1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + //check observer transfer + ObTransferStatus expected_status(ObTransferStatus::COMPLETED); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); + //wait 1001 ls transfer out tablet deleted gc. + ASSERT_EQ(OB_SUCCESS, wait_transfer_out_deleted_tablet_become_empty_shell(task)); +} + +TEST_F(TestTransferHandler, test_transfer_1_to_1001) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + //title: 1001 ls transfer to 1 ls + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1), ObLSID(1001), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + //check observer transfer + ObTransferStatus expected_status(ObTransferStatus::COMPLETED); + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, wait_transfer_task(task_id, expected_status, true/*is_from_his*/, task)); + LOG_INFO("generate transfer task", K(task)); + ASSERT_EQ(OB_SUCCESS, task.result_); +} + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/test_location_service.cpp b/mittest/simple_server/test_location_service.cpp new file mode 100644 index 000000000..5b05c5d2d --- /dev/null +++ b/mittest/simple_server/test_location_service.cpp @@ -0,0 +1,313 @@ +/** + * Copyright (c) 2023 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "share/location_cache/ob_location_service.h" // ObLocationService + +using namespace unittest; + +namespace oceanbase +{ +namespace share +{ +using namespace common; + +static const int64_t TOTAL_NUM = 110; +static uint64_t g_tenant_id; +static ObSEArray g_tablet_ls_pairs; + +class TestLocationService : public unittest::ObSimpleClusterTestBase +{ +public: + TestLocationService() : unittest::ObSimpleClusterTestBase("test_location_service") {} + int batch_create_table(ObMySQLProxy &sql_proxy, const int64_t TOTAL_NUM, ObIArray &tablet_ls_pairs); +}; + +int TestLocationService::batch_create_table( + ObMySQLProxy &sql_proxy, + const int64_t TOTAL_NUM, + ObIArray &tablet_ls_pairs) +{ + int ret = OB_SUCCESS; + tablet_ls_pairs.reset(); + ObSqlString sql; + // batch create table + int64_t affected_rows = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < TOTAL_NUM; ++i) { + sql.reset(); + if (OB_FAIL(sql.assign_fmt("create table t%ld(c1 int)", i))) { + } else if (OB_FAIL(sql_proxy.write(sql.ptr(), affected_rows))) { + } + } + // batch get table_id + sql.reset(); + if (OB_FAIL(sql.assign_fmt("select TABLET_ID, LS_ID from oceanbase.DBA_OB_TABLE_LOCATIONS where table_name in ("))) { + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < TOTAL_NUM; ++i) { + if (OB_FAIL(sql.append_fmt("%s't%ld'", 0 == i ? "" : ",", i))) {} + } + if (FAILEDx(sql.append_fmt(") order by TABLET_ID"))) {}; + } + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_FAIL(tablet_ls_pairs.reserve(TOTAL_NUM))) { + } else if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t tablet_id = ObTabletID::INVALID_TABLET_ID; + int64_t ls_id = ObLSID::INVALID_LS_ID; + while(OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "TABLET_ID", tablet_id, uint64_t); + EXTRACT_INT_FIELD_MYSQL(res, "LS_ID", ls_id, int64_t); + if (OB_FAIL(tablet_ls_pairs.push_back(ObTabletLSPair(tablet_id, ls_id)))) {} + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +TEST_F(TestLocationService, prepare_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + ASSERT_EQ(OB_SUCCESS, batch_create_table(sql_proxy, TOTAL_NUM, g_tablet_ls_pairs)); +} + +TEST_F(TestLocationService, test_ls_location_service) +{ + int ret = OB_SUCCESS; + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + ObLocationService *location_service = GCTX.location_service_; + ASSERT_TRUE(OB_NOT_NULL(location_service)); + ObLSLocationService *ls_location_service = &(location_service->ls_location_service_); + ASSERT_TRUE(OB_NOT_NULL(ls_location_service)); + + ObSEArray ls_ids; + ObSEArray ls_locations; + ASSERT_EQ(OB_SUCCESS, ls_ids.push_back(ObLSID(1))); + ASSERT_EQ(OB_SUCCESS, ls_ids.push_back(ObLSID(1001))); + ASSERT_EQ(OB_SUCCESS, ls_location_service->batch_renew_ls_locations(GCONF.cluster_id, g_tenant_id, ls_ids, ls_locations)); + ASSERT_TRUE(ls_ids.count() == ls_locations.count()); + ARRAY_FOREACH(ls_locations, idx) { + ASSERT_TRUE(ls_locations.at(idx).get_ls_id() == ls_ids.at(idx)); + ASSERT_TRUE(!ls_locations.at(idx).get_replica_locations().empty()); + } + + // nonexistent ls_id return fake empty location + ls_ids.reset(); + ls_locations.reset(); + ASSERT_EQ(OB_SUCCESS, ls_ids.push_back(ObLSID(1))); + ASSERT_EQ(OB_SUCCESS, ls_ids.push_back(ObLSID(1234))); // nonexistent ls_id + ASSERT_EQ(OB_SUCCESS, ls_location_service->batch_renew_ls_locations(GCONF.cluster_id, g_tenant_id, ls_ids, ls_locations)); + ASSERT_TRUE(ls_ids.count() == ls_locations.count() + 1); + ASSERT_TRUE(ls_locations.at(0).get_ls_id() == ls_ids.at(0)); + ASSERT_TRUE(!ls_locations.at(0).get_replica_locations().empty()); + + // duplicated ls_id return error + ls_ids.reset(); + ls_locations.reset(); + ASSERT_EQ(OB_SUCCESS, ls_ids.push_back(ObLSID(1001))); + ASSERT_EQ(OB_SUCCESS, ls_ids.push_back(ObLSID(1001))); // duplicated ls_id + ASSERT_EQ(OB_ERR_DUP_ARGUMENT, ls_location_service->batch_renew_ls_locations(GCONF.cluster_id, g_tenant_id, ls_ids, ls_locations)); +} + +TEST_F(TestLocationService, test_tablet_ls_service) +{ + int ret = OB_SUCCESS; + ASSERT_TRUE(g_tablet_ls_pairs.count() == TOTAL_NUM); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + ObLocationService *location_service = GCTX.location_service_; + ASSERT_TRUE(OB_NOT_NULL(location_service)); + ObTabletLSService *tablet_ls_service = &(location_service->tablet_ls_service_); + ASSERT_TRUE(OB_NOT_NULL(tablet_ls_service)); + + ObArenaAllocator allocator; + ObList tablet_list(allocator); + ObSEArray tablet_ls_caches; + ARRAY_FOREACH(g_tablet_ls_pairs, idx) { + const ObTabletLSPair &pair = g_tablet_ls_pairs.at(idx); + ASSERT_EQ(OB_SUCCESS, tablet_list.push_back(pair.get_tablet_id())); + } + ASSERT_EQ(OB_SUCCESS, tablet_ls_service->batch_renew_tablet_ls_cache(g_tenant_id, tablet_list, tablet_ls_caches)); + ASSERT_TRUE(tablet_list.size() == tablet_ls_caches.count()); + ASSERT_TRUE(tablet_ls_caches.count() == g_tablet_ls_pairs.count()); + ARRAY_FOREACH(tablet_ls_caches, idx) { + const ObTabletLSCache &cache = tablet_ls_caches.at(idx); + bool find = false; + FOREACH(tablet_id, tablet_list) { + if (*tablet_id == cache.get_tablet_id()) { + find = true; + } + } + ASSERT_TRUE(find); + ARRAY_FOREACH(g_tablet_ls_pairs, j) { + const ObTabletLSPair &pair = g_tablet_ls_pairs.at(j); + if (pair.get_tablet_id() == cache.get_tablet_id()) { + ASSERT_TRUE(pair.get_ls_id() == cache.get_ls_id()); + break; + } + } + } + + // nonexistent tablet_id return OB_SUCCESS + tablet_list.reset(); + tablet_ls_caches.reset(); + ASSERT_EQ(OB_SUCCESS, tablet_list.push_back(g_tablet_ls_pairs.at(0).get_tablet_id())); + ASSERT_EQ(OB_SUCCESS, tablet_list.push_back(ObTabletID(654321))); // nonexistent ls_id + ASSERT_EQ(OB_SUCCESS, tablet_ls_service->batch_renew_tablet_ls_cache(g_tenant_id, tablet_list, tablet_ls_caches)); + ASSERT_TRUE(tablet_ls_caches.count() == 1); + ASSERT_TRUE(tablet_ls_caches.at(0).get_tablet_id() == g_tablet_ls_pairs.at(0).get_tablet_id()); + ASSERT_TRUE(tablet_ls_caches.at(0).get_ls_id() == g_tablet_ls_pairs.at(0).get_ls_id()); + + // duplicated tablet_id return error + tablet_list.reset(); + tablet_ls_caches.reset(); + ASSERT_EQ(OB_SUCCESS, tablet_list.push_back(g_tablet_ls_pairs.at(0).get_tablet_id())); + ASSERT_EQ(OB_SUCCESS, tablet_list.push_back(g_tablet_ls_pairs.at(0).get_tablet_id())); + ASSERT_EQ(OB_SUCCESS, tablet_ls_service->batch_renew_tablet_ls_cache(g_tenant_id, tablet_list, tablet_ls_caches)); +} + +TEST_F(TestLocationService, test_location_service) +{ + int ret = OB_SUCCESS; + ASSERT_TRUE(g_tablet_ls_pairs.count() == TOTAL_NUM); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + ObLocationService *location_service = GCTX.location_service_; + ASSERT_TRUE(OB_NOT_NULL(location_service)); + + ObArenaAllocator allocator; + ObList tablet_list(allocator); + ObSEArray tablet_ls_caches; + ARRAY_FOREACH(g_tablet_ls_pairs, idx) { + const ObTabletLSPair &pair = g_tablet_ls_pairs.at(idx); + ASSERT_EQ(OB_SUCCESS, tablet_list.push_back(pair.get_tablet_id())); + } + + ASSERT_EQ(OB_SUCCESS, location_service->batch_renew_tablet_locations(g_tenant_id, tablet_list, OB_MAPPING_BETWEEN_TABLET_AND_LS_NOT_EXIST, true)); + ASSERT_EQ(OB_SUCCESS, location_service->batch_renew_tablet_locations(g_tenant_id, tablet_list, OB_MAPPING_BETWEEN_TABLET_AND_LS_NOT_EXIST, false)); + ASSERT_EQ(OB_SUCCESS, location_service->batch_renew_tablet_locations(g_tenant_id, tablet_list, OB_NOT_MASTER, true)); + ASSERT_EQ(OB_SUCCESS, location_service->batch_renew_tablet_locations(g_tenant_id, tablet_list, OB_NOT_MASTER, false)); +} + +TEST_F(TestLocationService, test_check_ls_exist) +{ + uint64_t user_tenant_id = OB_INVALID_TENANT_ID; + ASSERT_EQ(OB_SUCCESS, get_tenant_id(user_tenant_id)); + uint64_t meta_tenant_id = gen_meta_tenant_id(user_tenant_id); + + ObLSID user_ls_id(1001); + ObLSID uncreated_ls_id(6666); + ObLSID invalid_ls_id(123); + ObLSID test_creating_ls_id(1111); + ObLSID test_creat_abort_ls_id(1112); + const uint64_t not_exist_tenant_id = 1234; + ObLSExistState state; + + // user tenant + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(user_tenant_id, SYS_LS, state)); + ASSERT_TRUE(state.is_existing()); + state.reset(); + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(user_tenant_id, user_ls_id, state)); + ASSERT_TRUE(state.is_existing()); + state.reset(); + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(user_tenant_id, uncreated_ls_id, state)); + ASSERT_TRUE(state.is_uncreated()); + + common::ObMySQLProxy &inner_proxy = get_curr_simple_server().get_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("delete from oceanbase.__all_ls_status where tenant_id = %lu and ls_id = %ld", user_tenant_id, user_ls_id.id())); + ASSERT_EQ(OB_SUCCESS, inner_proxy.write(get_private_table_exec_tenant_id(user_tenant_id), sql.ptr(), affected_rows)); + state.reset(); + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(user_tenant_id, user_ls_id, state)); + ASSERT_TRUE(state.is_deleted()); + + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into oceanbase.__all_ls_status (tenant_id, ls_id, status, ls_group_id, unit_group_id) values (%lu, %ld, 'CREATING', 0, 0)", user_tenant_id, test_creating_ls_id.id())); + ASSERT_EQ(OB_SUCCESS, inner_proxy.write(get_private_table_exec_tenant_id(user_tenant_id), sql.ptr(), affected_rows)); + state.reset(); + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(user_tenant_id, test_creating_ls_id, state)); + ASSERT_TRUE(state.is_uncreated()); // treat CREATING ls as UNCREATED + + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into oceanbase.__all_ls_status (tenant_id, ls_id, status, ls_group_id, unit_group_id) values (%lu, %ld, 'CREATE_ABORT', 0, 0)", user_tenant_id, test_creat_abort_ls_id.id())); + ASSERT_EQ(OB_SUCCESS, inner_proxy.write(get_private_table_exec_tenant_id(user_tenant_id), sql.ptr(), affected_rows)); + state.reset(); + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(user_tenant_id, test_creat_abort_ls_id, state)); + ASSERT_TRUE(state.is_deleted()); // treat CREATE_ABLORT ls as DELETED + + ASSERT_EQ(OB_INVALID_ARGUMENT, ObLocationService::check_ls_exist(user_tenant_id, invalid_ls_id, state)); + + // sys tenant + state.reset(); + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(OB_SYS_TENANT_ID, SYS_LS, state)); + ASSERT_TRUE(state.is_existing()); + ASSERT_EQ(OB_INVALID_ARGUMENT, ObLocationService::check_ls_exist(OB_SYS_TENANT_ID, user_ls_id, state)); + ASSERT_EQ(OB_INVALID_ARGUMENT, ObLocationService::check_ls_exist(OB_SYS_TENANT_ID, invalid_ls_id, state)); + + // not exist tenant + ASSERT_EQ(OB_TENANT_NOT_EXIST, ObLocationService::check_ls_exist(not_exist_tenant_id, SYS_LS, state)); + // virtual tenant + ASSERT_EQ(OB_INVALID_ARGUMENT, ObLocationService::check_ls_exist(OB_SERVER_TENANT_ID, SYS_LS, state)); + + // meta tenant + state.reset(); + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(meta_tenant_id, SYS_LS, state)); + ASSERT_TRUE(state.is_existing()); + ASSERT_EQ(OB_INVALID_ARGUMENT, ObLocationService::check_ls_exist(meta_tenant_id, user_ls_id, state)); + ASSERT_EQ(OB_INVALID_ARGUMENT, ObLocationService::check_ls_exist(meta_tenant_id, invalid_ls_id, state)); + + // meta tenant not in normal status + state.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter system set_tp tp_name = EN_CHECK_LS_EXIST_WITH_TENANT_NOT_NORMAL, error_code = 4016, frequency = 1")); + ASSERT_EQ(OB_SUCCESS, inner_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(meta_tenant_id, SYS_LS, state)); + ASSERT_TRUE(state.is_existing()); + + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("update oceanbase.__all_ls_status set status = 'CREATING' where tenant_id = %lu and ls_id = %ld", meta_tenant_id, ObLSID::SYS_LS_ID)); + ASSERT_EQ(OB_SUCCESS, inner_proxy.write(get_private_table_exec_tenant_id(meta_tenant_id), sql.ptr(), affected_rows)); + state.reset(); + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(meta_tenant_id, SYS_LS, state)); + ASSERT_TRUE(state.is_uncreated()); + + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("delete from oceanbase.__all_ls_status where tenant_id = %lu and ls_id = %ld", meta_tenant_id, ObLSID::SYS_LS_ID)); + ASSERT_EQ(OB_SUCCESS, inner_proxy.write(get_private_table_exec_tenant_id(meta_tenant_id), sql.ptr(), affected_rows)); + state.reset(); + ASSERT_EQ(OB_SUCCESS, ObLocationService::check_ls_exist(meta_tenant_id, SYS_LS, state)); + ASSERT_TRUE(state.is_uncreated()); +} + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/test_lock_table_persistence.cpp b/mittest/simple_server/test_lock_table_persistence.cpp index 0644fc14c..3b88535d1 100644 --- a/mittest/simple_server/test_lock_table_persistence.cpp +++ b/mittest/simple_server/test_lock_table_persistence.cpp @@ -150,7 +150,7 @@ TEST_F(ObLockTableBeforeRestartTest, test_lock_table_flush) guard.get_table_id(RunCtx.tenant_id_, "test", "test_lock_table_persistence_t", false, share::schema::ObSchemaGetterGuard::NON_TEMP_WITH_NON_HIDDEN_TABLE_TYPE, table_id)); ObTableLockService *table_lock_ser = MTL(ObTableLockService*); - ASSERT_EQ(OB_SUCCESS, table_lock_ser->lock_table(table_id, EXCLUSIVE, 1, 0)); + ASSERT_EQ(OB_SUCCESS, table_lock_ser->lock_table(table_id, EXCLUSIVE, ObTableLockOwnerID(1), 0)); usleep(1000 * 1000); ObLockMemtable *lock_memtable @@ -178,7 +178,7 @@ TEST_F(ObLockTableBeforeRestartTest, test_lock_table_flush) ASSERT_EQ(lock_memtable->flushed_scn_, lock_memtable->freeze_scn_); //unlock table - ASSERT_EQ(OB_SUCCESS, table_lock_ser->unlock_table(table_id, EXCLUSIVE, 1, 0)); + ASSERT_EQ(OB_SUCCESS, table_lock_ser->unlock_table(table_id, EXCLUSIVE, ObTableLockOwnerID(1), 0)); usleep(1000 * 1000); unlock_scn = lock_memtable->get_rec_scn(); ASSERT_NE(lock_memtable->get_rec_scn(), SCN::max_scn()); diff --git a/mittest/simple_server/test_lock_table_with_tx.cpp b/mittest/simple_server/test_lock_table_with_tx.cpp index 7b7406d44..f65341b7a 100644 --- a/mittest/simple_server/test_lock_table_with_tx.cpp +++ b/mittest/simple_server/test_lock_table_with_tx.cpp @@ -11,7 +11,7 @@ */ #include -#define USING_LOG_PREFIX STORAGE +#define USING_LOG_PREFIX TABLELOCK #define protected public #define private public @@ -151,10 +151,10 @@ TEST_F(ObLockTableBeforeRestartTest, test_commit_log) int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; - ObTableLockOwnerID OWNER_ONE = 1; + ObTableLockOwnerID OWNER_ONE(1); uint64_t table_id = 0; ObTableLockMode lock_mode = EXCLUSIVE; - ObTableLockOwnerID lock_owner = 0; + ObTableLockOwnerID lock_owner(0); ObLS *ls = nullptr; ObLockMemtable *lock_memtable = nullptr; ObCheckpointExecutor *checkpoint_executor = nullptr; @@ -187,9 +187,13 @@ TEST_F(ObLockTableBeforeRestartTest, test_commit_log) ->common_checkpoints_[ObCommonCheckpointType::LOCK_MEMTABLE_TYPE]); lock_memtable->obj_lock_map_.print(); + LOG_INFO("ObLockTableBeforeRestartTest::test_commit_log 1.2 wait tablelock committed"); + // after the commit process return, the tablelock bottom may not committed yet. + while (lock_memtable->get_rec_scn() == SCN::max_scn()) { + usleep(100 * 1000); + } SCN rec_scn = lock_memtable->get_rec_scn(); - ASSERT_NE(rec_scn, SCN::max_scn()); - LOG_INFO("ObLockTableBeforeRestartTest::test_commit_log 1.2", K(rec_scn)); + LOG_INFO("ObLockTableBeforeRestartTest::test_commit_log 1.2 rec scn after tablelock committed", K(rec_scn)); // 1.3 dump tx ctx table/ tx data table LOG_INFO("ObLockTableBeforeRestartTest::test_commit_log 1.3"); @@ -211,8 +215,6 @@ TEST_F(ObLockTableBeforeRestartTest, test_commit_log) } LOG_INFO("ObLockTableBeforeRestartTest::test_commit_log 1.3 tx_data_mgr flush finished"); - ASSERT_NE(tx_ctx_memtable->get_rec_scn(), share::SCN::max_scn()); - ASSERT_NE(tx_data_mgr->get_rec_scn(), share::SCN::max_scn()); // 1.4 update ls checkpoint(should be the lock op commit scn) // wait until ls checkpoint updated. LOG_INFO("ObLockTableBeforeRestartTest::test_commit_log 1.4"); diff --git a/mittest/simple_server/test_ls_recover.cpp b/mittest/simple_server/test_ls_recover.cpp index 6337d9788..66a8fd623 100644 --- a/mittest/simple_server/test_ls_recover.cpp +++ b/mittest/simple_server/test_ls_recover.cpp @@ -48,12 +48,12 @@ namespace logservice { // should not gc a ls create by ob_ls_service.cpp -int ObGarbageCollector::gc_check_ls_status_(const ObLSID &id, +int ObGarbageCollector::gc_check_ls_status_(storage::ObLS &ls, ObGCCandidateArray &gc_candidates) { int ret = OB_SUCCESS; GCCandidate candidate; - candidate.ls_id_ = id; + candidate.ls_id_ = ls.get_ls_id(); candidate.ls_status_ = LSStatus::LS_NORMAL; candidate.gc_reason_ = GCReason::INVALID_GC_REASON; if (OB_FAIL(gc_candidates.push_back(candidate))) { diff --git a/mittest/simple_server/test_ls_status_operator.cpp b/mittest/simple_server/test_ls_status_operator.cpp index e48590445..9b7c9bc69 100644 --- a/mittest/simple_server/test_ls_status_operator.cpp +++ b/mittest/simple_server/test_ls_status_operator.cpp @@ -244,7 +244,7 @@ TEST_F(TestLSStatusOperator, LSLifeAgent) scn.convert_for_logservice(99); ret = recovery_stat.init_only_recovery_stat(tenant_id_, ls_id, scn, scn); ASSERT_EQ(OB_SUCCESS, ret); - ret = recovery_op.update_ls_recovery_stat(recovery_stat, get_curr_simple_server().get_observer().get_mysql_proxy()); + ret = recovery_op.update_ls_recovery_stat(recovery_stat, false, get_curr_simple_server().get_observer().get_mysql_proxy()); ASSERT_EQ(OB_SUCCESS, ret); ret = ls_life.drop_ls(tenant_id_, ls_id, share::NORMAL_SWITCHOVER_STATUS); ASSERT_EQ(OB_NEED_RETRY, ret); @@ -254,7 +254,7 @@ TEST_F(TestLSStatusOperator, LSLifeAgent) ret = recovery_stat.init_only_recovery_stat(tenant_id_, ls_id, scn, recovery_scn); ASSERT_EQ(OB_SUCCESS, ret); //recovery_stat的取最大值 - ret = recovery_op.update_ls_recovery_stat(recovery_stat, get_curr_simple_server().get_observer().get_mysql_proxy()); + ret = recovery_op.update_ls_recovery_stat(recovery_stat, false, get_curr_simple_server().get_observer().get_mysql_proxy()); ASSERT_EQ(OB_SUCCESS, ret); ret = ls_life.drop_ls(tenant_id_, ls_id, share::NORMAL_SWITCHOVER_STATUS); @@ -262,7 +262,7 @@ TEST_F(TestLSStatusOperator, LSLifeAgent) scn.convert_for_logservice(100); ret = recovery_stat.init_only_recovery_stat(tenant_id_, ls_id, scn, recovery_scn); ASSERT_EQ(OB_SUCCESS, ret); - ret = recovery_op.update_ls_recovery_stat(recovery_stat, get_curr_simple_server().get_observer().get_mysql_proxy()); + ret = recovery_op.update_ls_recovery_stat(recovery_stat, false, get_curr_simple_server().get_observer().get_mysql_proxy()); ASSERT_EQ(OB_SUCCESS, ret); ret = ls_life.drop_ls(tenant_id_, ls_id, share::NORMAL_SWITCHOVER_STATUS); ASSERT_EQ(OB_SUCCESS, ret); @@ -295,59 +295,6 @@ TEST_F(TestLSStatusOperator, add_tenant) ASSERT_EQ(OB_ITER_END, ret); }*/ -TEST_F(TestLSStatusOperator, test_check_ls_exist) -{ - uint64_t user_tenant_id = OB_INVALID_TENANT_ID; - ASSERT_EQ(OB_SUCCESS, create_tenant()); - ASSERT_EQ(OB_SUCCESS, get_tenant_id(user_tenant_id)); - uint64_t meta_tenant_id = gen_meta_tenant_id(user_tenant_id); - - ObLSID user_ls_id(1001); - ObLSID uncreated_ls_id(6666); - ObLSID invalid_ls_id(123); - const uint64_t not_exist_tenant_id = 1234; - ObLSStatusOperator::ObLSExistState state; - - // user tenant - ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(user_tenant_id, SYS_LS, state)); - ASSERT_TRUE(state.is_existing()); - state.reset(); - ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(user_tenant_id, user_ls_id, state)); - ASSERT_TRUE(state.is_existing()); - state.reset(); - ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(user_tenant_id, uncreated_ls_id, state)); - ASSERT_TRUE(state.is_uncreated()); - - common::ObMySQLProxy &inner_proxy = get_curr_simple_server().get_observer().get_mysql_proxy(); - ObSqlString sql; - int64_t affected_rows = 0; - ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("delete from oceanbase.__all_ls_status where tenant_id = %lu and ls_id = %ld", user_tenant_id, ObLSID::SYS_LS_ID)); - ASSERT_EQ(OB_SUCCESS, inner_proxy.write(ObLSLifeIAgent::get_exec_tenant_id(user_tenant_id), sql.ptr(), affected_rows)); - state.reset(); - ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(user_tenant_id, SYS_LS, state)); - ASSERT_TRUE(state.is_deleted()); - - ASSERT_EQ(OB_INVALID_ARGUMENT, ObLSStatusOperator::check_ls_exist(user_tenant_id, invalid_ls_id, state)); - - // meta tenant - state.reset(); - ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(meta_tenant_id, SYS_LS, state)); - ASSERT_TRUE(state.is_existing()); - ASSERT_EQ(OB_INVALID_ARGUMENT, ObLSStatusOperator::check_ls_exist(meta_tenant_id, user_ls_id, state)); - ASSERT_EQ(OB_INVALID_ARGUMENT, ObLSStatusOperator::check_ls_exist(meta_tenant_id, invalid_ls_id, state)); - - // sys tenant - state.reset(); - ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(OB_SYS_TENANT_ID, SYS_LS, state)); - ASSERT_TRUE(state.is_existing()); - ASSERT_EQ(OB_INVALID_ARGUMENT, ObLSStatusOperator::check_ls_exist(OB_SYS_TENANT_ID, user_ls_id, state)); - ASSERT_EQ(OB_INVALID_ARGUMENT, ObLSStatusOperator::check_ls_exist(OB_SYS_TENANT_ID, invalid_ls_id, state)); - - // not exist tenant - ASSERT_EQ(OB_TENANT_NOT_EXIST, ObLSStatusOperator::check_ls_exist(not_exist_tenant_id, SYS_LS, state)); - -} - } // namespace share } // namespace oceanbase diff --git a/mittest/simple_server/test_mds_recover.cpp b/mittest/simple_server/test_mds_recover.cpp new file mode 100644 index 000000000..48fa441b0 --- /dev/null +++ b/mittest/simple_server/test_mds_recover.cpp @@ -0,0 +1,442 @@ +/** + * Copyright (c) 2021 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 +#include +#define USING_LOG_PREFIX STORAGE +#define protected public +#define private public +#include "lib/container/ob_tuple.h" +#include "lib/ob_define.h" +#include "ob_tablet_id.h" +#include "share/inner_table/ob_inner_table_schema_constants.h" +#include "share/ob_ls_id.h" +#include "env/ob_simple_cluster_test_base.h" +#include "env/ob_simple_server_restart_helper.h" +#include "lib/mysqlclient/ob_mysql_result.h" +#include "logservice/rcservice/ob_role_change_service.h" +#include "logservice/ob_ls_adapter.h" +#include "storage/access/ob_rows_info.h" +#include "storage/checkpoint/ob_data_checkpoint.h" +#include "storage/compaction/ob_schedule_dag_func.h" +#include "storage/compaction/ob_tablet_merge_task.h" +#include "storage/ls/ob_freezer.h" +#include "storage/ls/ob_ls.h" +#include "storage/ls/ob_ls_meta.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls_tx_service.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/ob_relative_table.h" +#include "storage/ob_storage_table_guard.h" +#include "storage/tx_storage/ob_ls_map.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" +#include + +#undef private +#undef protected + +static const char *TEST_FILE_NAME = "test_mds_recover"; +static const char *BORN_CASE_NAME = "ObTestMdsBeforeRecover"; +static const char *RESTART_CASE_NAME = "ObTestMdsAfterRecover"; +static const char *BEFORE_RECOVER_RESULT_FILE = "/tmp/1.txt"; +static const char *AFTER_RECOVER_RESULT_FILE = "/tmp/2.txt"; + +using namespace std; + +ObSimpleServerRestartHelper *helper_ptr = nullptr; + +oceanbase::share::ObLSID TEST_LS_ID; +oceanbase::common::ObTabletID TEST_TABLET_ID; +oceanbase::share::SCN LAST_SCN, REPLAY_BASE_SCN; +using VirtualTableResult = oceanbase::common::ObArray>; + +VirtualTableResult RESULT; + +namespace oceanbase +{ +using namespace transaction; +using namespace storage; +using namespace share; +namespace unittest +{ +class ObTestMdsBeforeRecover : public ObSimpleClusterTestBase +{ +public: + ObTestMdsBeforeRecover() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} +}; + +void wait_user() +{ + std::cout << "Enter anything to continue..." << std::endl; + char a = '\0'; + std::cin >> a; +} + +void create_or_find_test_table(const char *table_name, share::ObLSID &ls_id, ObTabletID &tablet_id, bool create) +{ + if (create) { + int64_t _; + char create_table_sql[512] = { 0 }; + databuff_printf(create_table_sql, 512, "create table %s(a int)", table_name); + // 1. 新建一个tablet + ASSERT_EQ(OB_SUCCESS, GCTX.sql_proxy_->write(OB_SYS_TENANT_ID, create_table_sql, _)); + } + // 2. 从表名拿到它的tablet_id + char where_condition1[512] = { 0 }; + databuff_printf(where_condition1, 512, "where table_name = '%s'", table_name); + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, + {"tablet_id"}, + OB_ALL_TABLE_TNAME, + where_condition1, + tablet_id)); + // 3. 从tablet_id拿到它的ls_id + char where_condition2[512] = { 0 }; + databuff_printf(where_condition2, 512, "where tablet_id = %ld", tablet_id.id()); + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, + {"ls_id"}, + OB_ALL_TABLET_TO_LS_TNAME, + where_condition2, + ls_id)); + // 4. 从ls_id找到ls + storage::ObLSHandle ls_handle; + ASSERT_EQ(OB_SUCCESS, MTL(storage::ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::TRANS_MOD)); +} + +void insert_row_to_write_inc_seq(const char *table_name) +{ + int64_t _; + char insert_sql[512] = { 0 }; + databuff_printf(insert_sql, 512, "insert into %s values(0)", table_name); + // 1. 插入数据 + ASSERT_EQ(OB_SUCCESS, GCTX.sql_proxy_->write(OB_SYS_TENANT_ID, insert_sql, _)); +} + +void add_column_to_write_dll_info(const char *table_name, share::ObLSID &ls_id, ObTabletID &tablet_id) +{ + int64_t _; + char insert_sql[512] = { 0 }; + databuff_printf(insert_sql, 512, "alter table %s add b int after a", table_name); + // 1. 加列 + ASSERT_EQ(OB_SUCCESS, GCTX.sql_proxy_->write(OB_SYS_TENANT_ID, insert_sql, _)); + // 2. 从表名拿到它的tablet_id + char where_condition1[512] = { 0 }; + databuff_printf(where_condition1, 512, "where table_name = '%s'", table_name); + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, + {"tablet_id"}, + OB_ALL_TABLE_TNAME, + where_condition1, + tablet_id)); + // 3. 从tablet_id拿到它的ls_id + char where_condition2[512] = { 0 }; + databuff_printf(where_condition2, 512, "where tablet_id = %ld", tablet_id.id()); + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, + {"ls_id"}, + OB_ALL_TABLET_TO_LS_TNAME, + where_condition2, + ls_id)); + // 4. 从ls_id找到ls + storage::ObLSHandle ls_handle; + ASSERT_EQ(OB_SUCCESS, MTL(storage::ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::TRANS_MOD)); +} + +void do_major_to_write_medium_info() +{ + int64_t _; + // 1. 插入数据 + ASSERT_EQ(OB_SUCCESS, GCTX.sql_proxy_->write(OB_SYS_TENANT_ID, "alter system minor freeze", _)); +} + +void do_flush_mds_table(share::ObLSID ls_id, ObTabletID tablet_id) +{ + // 1. 从ls_id找到ls + storage::ObLSHandle ls_handle; + ASSERT_EQ(OB_SUCCESS, MTL(storage::ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::TRANS_MOD)); + // 2. 从ls拿到tablet handle + storage::ObTabletHandle tablet_handle; + ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); + // 3. 从tablet handle拿到tablet pointer + const ObTablet::ObTabletPointerHandle &pointer_handle = tablet_handle.get_obj()->get_pointer_handle(); + ObMetaPointer *resource_ptr = pointer_handle.get_resource_ptr(); + ObTabletPointer *tablet_pointer = dynamic_cast(resource_ptr); + // 4. 做flush动作 + mds::MdsTableHandle handle; + ASSERT_EQ(OB_SUCCESS, tablet_pointer->get_mds_table(handle)); + ASSERT_EQ(OB_SUCCESS, handle.flush(share::SCN::max_scn())); + ASSERT_EQ(true, handle.p_mds_table_base_->flushing_scn_.is_valid()); + // 5. 等flush完成 + share::SCN rec_scn = share::SCN::min_scn(); + while (!rec_scn.is_max()) { + ASSERT_EQ(OB_SUCCESS, handle.get_rec_scn(rec_scn)); + sleep(1); + OCCAM_LOG(INFO, "waiting node dump", K(rec_scn)); + } +} + +void do_recycle_and_gc_mds_table(share::ObLSID ls_id, ObTabletID tablet_id) +{ + int ret = OB_SUCCESS; + // 1. 从ls_id找到ls + storage::ObLSHandle ls_handle; + ASSERT_EQ(OB_SUCCESS, MTL(storage::ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::TRANS_MOD)); + // 2. 从ls拿到tablet handle + storage::ObTabletHandle tablet_handle; + ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); + // 3. gc mds table + mds::ObTenantMdsTimer timer; + while (OB_FAIL(timer.process_with_tablet_(*tablet_handle.get_obj()))) { + sleep(1); + } + ASSERT_EQ(OB_SUCCESS, ret); +} + +void get_latest_scn(share::ObLSID ls_id, ObTabletID tablet_id, uint64_t &latest_scn) +{ + int ret = OB_SUCCESS; + char where_condition[512] = { 0 }; + databuff_printf(where_condition, 512, "where tenant_id=%ld and ls_id =%ld and tablet_id=%ld and end_scn != 18446744073709551615 order by end_scn desc limit 1", + MTL_ID(), ls_id.id(), tablet_id.id()); + ret = ObTableAccessHelper::read_single_row(MTL_ID(), + {"end_scn"}, + OB_ALL_VIRTUAL_MDS_NODE_STAT_TNAME, + where_condition, + latest_scn); + ASSERT_EQ(OB_SUCCESS, ret); +} + +void read_virtual_mds_stat(share::ObLSID ls_id, ObTabletID tablet_id, VirtualTableResult &result) { + int ret = OB_SUCCESS; + char where_condition[512] = { 0 }; + result.reset(); + databuff_printf(where_condition, 512, "where tenant_id=%ld and ls_id =%ld and tablet_id=%ld and position='DISK'", + MTL_ID(), ls_id.id(), tablet_id.id()); + int retry_time = 0; + do { + if (ret == OB_TABLE_NOT_EXIST) { + sleep(1); + } + ret = ObTableAccessHelper::read_multi_row(MTL_ID(), + {"unit_id", "user_key", "version_idx", "writer_type", "writer_id", "seq_no", + "redo_scn", "end_scn", "trans_version", "node_type", "state", "user_data", + "position"}, + OB_ALL_VIRTUAL_MDS_NODE_STAT_TNAME, + where_condition, + result); + } while (ret == OB_TABLE_NOT_EXIST && ++retry_time < 20); + ASSERT_EQ(OB_SUCCESS, ret); +} + +void advance_checkpoint(share::ObLSID ls_id, share::SCN aim_scn) +{ + int ret = OB_SUCCESS; + // 1. 从ls_id找到ls + storage::ObLSHandle ls_handle; + ASSERT_EQ(OB_SUCCESS, MTL(storage::ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::TRANS_MOD)); + int64_t retry_times = 60; + SCN checkpoint = SCN::min_scn(); + // 2. 等max_decided_scn推过目标点 + SCN max_decided_scn; + do { + ret = ls_handle.get_ls()->get_max_decided_scn(max_decided_scn); + ::sleep(1); + fprintf(stdout, + "waiting advance max decided scn, max_decided_scn = %lu aim_scn = %lu\n", + max_decided_scn.get_val_for_inner_table_field(), + aim_scn.get_val_for_inner_table_field()); + } while (OB_SUCC(ret) && max_decided_scn <= aim_scn); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_GT(max_decided_scn, aim_scn); + // 3. 推checkpoint并且等checkpoint推过 + while (--retry_times > 0) { + checkpoint = ls_handle.get_ls()->get_clog_checkpoint_scn(); + if (checkpoint > aim_scn) { + fprintf(stdout, + "checkpoint scn is higher than aim scn, checkpoint_scn:%ld, aim_scn:%ld\n", + checkpoint.get_val_for_inner_table_field(), + aim_scn.get_val_for_inner_table_field()); + break; + } else { + ::sleep(1); + fprintf(stdout, + "waiting advance checkpoint, checkpoint = %lu aim_scn = %lu\n", + checkpoint.get_val_for_inner_table_field(), + aim_scn.get_val_for_inner_table_field()); + ls_handle.get_ls()->checkpoint_executor_.advance_checkpoint_by_flush(SCN::scn_inc(aim_scn)); + } + } + ASSERT_GT(ls_handle.get_ls()->get_clog_checkpoint_scn(), aim_scn); + // 4. 等CLOG回收日志 + SCN min_start_scn = SCN::min_scn(); + SCN keep_alive_scn = SCN::min_scn(); + MinStartScnStatus status = MinStartScnStatus::UNKOWN; + retry_times = 40; + while (--retry_times > 0) { + ls_handle.get_ls()->get_min_start_scn(min_start_scn, keep_alive_scn, status); + if (MinStartScnStatus::HAS_CTX == status) { + break; + } else { + ::sleep(1); + fprintf(stdout, + "waiting min_start_scn has ctx min_start_scn = %ld keep_alive_scn = %ld status = %d\n", + min_start_scn.get_val_for_inner_table_field(), + keep_alive_scn.get_val_for_inner_table_field(), + status); + } + } + ASSERT_NE(SCN::min_scn(), min_start_scn); + ASSERT_NE(SCN::min_scn(), keep_alive_scn); + ASSERT_EQ(MinStartScnStatus::HAS_CTX, status); + fprintf(stdout, + "advance checkpoint done, checkpoint = %lu aim_scn = %lu min_start_scn = %lu keep_alive_scn = %lu\n", + checkpoint.get_val_for_inner_table_field(), + aim_scn.get_val_for_inner_table_field(), + min_start_scn.get_val_for_inner_table_field(), + keep_alive_scn.get_val_for_inner_table_field()); +} + +void write_result_to_file(const char *file_name) +{ + char buffer[2048] = { 0 }; + databuff_printf(buffer, 2048, "result from virtual table:%s", to_cstring(RESULT)); + std::ofstream file(file_name); + file << TEST_LS_ID.id() << std::endl + << TEST_TABLET_ID.id() << std::endl + << LAST_SCN.val_ << std::endl + << buffer << std::endl; +} + +TEST_F(ObTestMdsBeforeRecover, before_recover_test) +{ + ObLSID ls_id; + common::ObTabletID tablet_id; + share::SCN aim_checkpoint; + uint64_t scn_from_table; + int ret = OB_SUCCESS; + MTL_SWITCH(OB_SYS_TENANT_ID) + { + create_or_find_test_table("test_a", ls_id, tablet_id, true); + insert_row_to_write_inc_seq("test_a"); + add_column_to_write_dll_info("test_a", TEST_LS_ID, TEST_TABLET_ID); + do_flush_mds_table(TEST_LS_ID, TEST_TABLET_ID); + do_recycle_and_gc_mds_table(TEST_LS_ID, TEST_TABLET_ID); + get_latest_scn(TEST_LS_ID, TEST_TABLET_ID, scn_from_table); + read_virtual_mds_stat(TEST_LS_ID, TEST_TABLET_ID, RESULT); + OCCAM_LOG(INFO, "xuwang.txw debug", K(RESULT), K(TEST_LS_ID), K(TEST_TABLET_ID)); + ASSERT_EQ(OB_SUCCESS, LAST_SCN.convert_for_inner_table_field(scn_from_table)); + advance_checkpoint(TEST_LS_ID, LAST_SCN); + write_result_to_file(BEFORE_RECOVER_RESULT_FILE); + } +} + +class ObTestMdsAfterRecover : public ObSimpleClusterTestBase +{ +public: + ObTestMdsAfterRecover() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} +}; + +bool compare_before_and_after_recover_results(const char *file1, const char *file2) +{ + ifstream file1_stream(file1); + ifstream file2_stream(file2); + cout << file1 << " context:" << endl << file1_stream.rdbuf() << endl; + cout << file2 << " context:" << endl << file2_stream.rdbuf() << endl; + char c1, c2; + while (file1_stream.get(c1) && file2_stream.get(c2)) { + if (c1 != c2) { + return false; + } + } + return true; +} + +TEST_F(ObTestMdsAfterRecover, after_recover_test) +{ + int ret = OB_SUCCESS; + { + std::ifstream file(BEFORE_RECOVER_RESULT_FILE); + file >> TEST_LS_ID.id_ >> TEST_TABLET_ID.id_ >> LAST_SCN.val_; + ASSERT_GE(REPLAY_BASE_SCN, LAST_SCN); + } + MTL_SWITCH(OB_SYS_TENANT_ID) + { + read_virtual_mds_stat(TEST_LS_ID, TEST_TABLET_ID, RESULT);// to fill cache + read_virtual_mds_stat(TEST_LS_ID, TEST_TABLET_ID, RESULT); + OCCAM_LOG(INFO, "xuwang.txw debug", K(RESULT), K(TEST_LS_ID), K(TEST_TABLET_ID)); + write_result_to_file(AFTER_RECOVER_RESULT_FILE); + ASSERT_EQ(true, compare_before_and_after_recover_results(BEFORE_RECOVER_RESULT_FILE, AFTER_RECOVER_RESULT_FILE)); + } +} + +} // namespace unittest +} // namespace oceanbase + +int main(int argc, char **argv) +{ + int c = 0; + int time_sec = 0; + int concurrency = 1; + char *log_level = (char *)"INFO"; + while (EOF != (c = getopt(argc, argv, "t:l:"))) { + switch (c) { + case 't': + time_sec = atoi(optarg); + break; + case 'l': + log_level = optarg; + oceanbase::unittest::ObSimpleClusterTestBase::enable_env_warn_log_ = false; + break; + case 'c': + concurrency = atoi(optarg); + break; + default: + break; + } + } + std::string gtest_file_name = std::string(TEST_FILE_NAME) + "_gtest.log"; + oceanbase::unittest::init_gtest_output(gtest_file_name); + + int ret = 0; + ObSimpleServerRestartHelper restart_helper(argc, argv, TEST_FILE_NAME, BORN_CASE_NAME, + RESTART_CASE_NAME); + helper_ptr = &restart_helper; + restart_helper.set_sleep_sec(time_sec); + restart_helper.run(); + + return ret; +} + +namespace oceanbase { +namespace logservice +{ +int ObReplayStatus::enable(const LSN &base_lsn, const SCN &base_scn) +{ + /****************************************************************************/ + REPLAY_BASE_SCN = base_scn; + /****************************************************************************/ + int ret = OB_SUCCESS; + if (is_enabled()) { + ret = OB_STATE_NOT_MATCH; + CLOG_LOG(WARN, "replay status already enable", K(ret)); + } else { + WLockGuard wlock_guard(rwlock_); + if (OB_FAIL(enable_(base_lsn, base_scn))) { + CLOG_LOG(WARN, "enable replay status failed", K(ret), K(base_lsn), K(base_scn), K(ls_id_)); + } else { + CLOG_LOG(INFO, "enable replay status success", K(ret), K(base_lsn), K(base_scn), K(ls_id_)); + } + } + return ret; +} +} +} // namespace oceanbase \ No newline at end of file diff --git a/mittest/simple_server/test_mds_table_checkpoint.cpp b/mittest/simple_server/test_mds_table_checkpoint.cpp new file mode 100644 index 000000000..9982507e4 --- /dev/null +++ b/mittest/simple_server/test_mds_table_checkpoint.cpp @@ -0,0 +1,219 @@ +/** + * Copyright (c) 2021 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 +#define USING_LOG_PREFIX STORAGE +#define DEBUG_FOR_MDS +#define protected public +#define private public + +#include "env/ob_simple_cluster_test_base.h" +#include "env/ob_fast_bootstrap.h" +#include "lib/mysqlclient/ob_mysql_result.h" + +#include "storage/ls/ob_ls.h" +#include "storage/tx_storage/ob_ls_map.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/tx_storage/ob_tenant_freezer.h" + +namespace oceanbase +{ +using namespace transaction; +using namespace storage; +using namespace share; +using namespace storage::mds; + +namespace unittest +{ + +class TestRunCtx +{ +public: + uint64_t tenant_id_ = 0; + int time_sec_ = 0; +}; + +TestRunCtx RunCtx; +ObLSID LS_ID; + +class ObMdsTableCheckpointTest : public ObSimpleClusterTestBase +{ +public: + // 指定case运行目录前缀 test_ob_simple_cluster_ + ObMdsTableCheckpointTest() : ObSimpleClusterTestBase("test_mds_table_checkpoint_") {} + + void do_basic_test(); + + void create_mds_table(); + void get_ls_id(); + + ObLS *get_ls(const int64_t tenant_id, const ObLSID ls_id) + { + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + MTL_SWITCH(tenant_id) + { + ObLSIterator *ls_iter = nullptr; + ObLSHandle ls_handle; + ObLSService *ls_svr = MTL(ObLSService *); + OB_ASSERT(OB_SUCCESS == ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); + OB_ASSERT(nullptr != (ls = ls_handle.get_ls())); + } + return ls; + } +}; + +#define EXE_SQL(connection, sql_str) \ + ASSERT_EQ(OB_SUCCESS, sql.assign(sql_str)); \ + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + +#define EXE_SQL_FMT(...) \ + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt(__VA_ARGS__)); \ + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + +#define WRITE_SQL_BY_CONN(conn, sql_str) \ + ASSERT_EQ(OB_SUCCESS, sql.assign(sql_str)); \ + ASSERT_EQ(OB_SUCCESS, conn->execute_write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + +#define WRITE_SQL_FMT_BY_CONN(conn, ...) \ + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt(__VA_ARGS__)); \ + ASSERT_EQ(OB_SUCCESS, conn->execute_write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + +#define DEF_VAL_FOR_SQL \ + int ret = OB_SUCCESS; \ + ObSqlString sql; \ + int64_t affected_rows = 0; \ + sqlclient::ObISQLConnection *connection = nullptr; + +void ObMdsTableCheckpointTest::do_basic_test() +{ + create_mds_table(); + get_ls_id(); + ObLS *ls = get_ls(RunCtx.tenant_id_, LS_ID); + + int ret = OB_SUCCESS; + MTL_SWITCH(RunCtx.tenant_id_) { + MdsTableMgrHandle mgr_handle; + ObMdsTableMgr *mgr = nullptr; + ASSERT_EQ(OB_SUCCESS, ls->get_tablet_svr()->get_mds_table_mgr(mgr_handle)); + ASSERT_NE(nullptr, mgr = mgr_handle.get_mds_table_mgr()); + SCN scn_before_flush = mgr->get_rec_scn(); + MDS_LOG(INFO, "start flush ls mds table", K(LS_ID)); + ASSERT_EQ(OB_SUCCESS, ls->flush_mds_table(INT64_MAX)); + MDS_LOG(INFO, "finish flush ls mds table", K(LS_ID)); + ::sleep(10); + SCN scn_after_flush = mgr->get_rec_scn(); + ASSERT_LT(scn_before_flush, scn_after_flush); + fprintf(stdout, + "finish flush mds table, scn_before_flush = %ld scn_after_flush = " + "%ld\n", + scn_before_flush.get_val_for_tx(), + scn_after_flush.get_val_for_tx()); + } +} + +void ObMdsTableCheckpointTest::create_mds_table() +{ + DEF_VAL_FOR_SQL + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().get_sql_proxy2().acquire(connection)); + + ObTenantFreezer::MDS_TABLE_FREEZE_TRIGGER_TENANT_PERCENTAGE = 0.01; + + for (int i = 0; i < 300; i++) { + MDS_LOG(DEBUG, "create table :", K(i)); + WRITE_SQL_FMT_BY_CONN(connection, "create table if not exists test_mds_table_checkpoint_%d (c1 int, c2 int)", i); + WRITE_SQL_FMT_BY_CONN(connection, "insert into test_mds_table_checkpoint_%d values(%d, %d)", i, 1, 1); + } +} + +void ObMdsTableCheckpointTest::get_ls_id() +{ + DEF_VAL_FOR_SQL + + HEAP_VAR(ObMySQLProxy::MySQLResult, res) + { + int64_t int_tablet_id = 0; + int64_t int_ls_id = 0; + int64_t retry_times = 10; + + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().get_sql_proxy2().acquire(connection)); + ASSERT_EQ( + OB_SUCCESS, + connection->execute_read(OB_SYS_TENANT_ID, + "SELECT tablet_id, ls_id FROM oceanbase.DBA_OB_TABLE_LOCATIONS WHERE TABLE_NAME = " + "\'test_mds_table_checkpoint_0\'", + res)); + common::sqlclient::ObMySQLResult *result = res.mysql_result(); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("tablet_id", int_tablet_id)); + ASSERT_EQ(OB_SUCCESS, result->get_int("ls_id", int_ls_id)); + LS_ID = int_ls_id; + fprintf(stdout, "get ls info finish : ls_id = %ld\n", LS_ID.id()); + } +} + +TEST_F(ObMdsTableCheckpointTest, observer_start) +{ + SERVER_LOG(INFO, "observer_start succ"); +} + +TEST_F(ObMdsTableCheckpointTest, add_tenant) +{ + // create tenant + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(RunCtx.tenant_id_)); + ASSERT_NE(0, RunCtx.tenant_id_); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); +} + +TEST_F(ObMdsTableCheckpointTest, basic_test) +{ + do_basic_test(); +} + +TEST_F(ObMdsTableCheckpointTest, end) +{ + if (RunCtx.time_sec_ > 0) { + ::sleep(RunCtx.time_sec_); + } +} + +} // end unittest +} // end oceanbase + + +int main(int argc, char **argv) +{ + int c = 0; + int time_sec = 0; + char *log_level = (char*)"INFO"; + while(EOF != (c = getopt(argc,argv,"t:l:"))) { + switch(c) { + case 't': + time_sec = atoi(optarg); + break; + case 'l': + log_level = optarg; + oceanbase::unittest::ObSimpleClusterTestBase::enable_env_warn_log_ = false; + break; + default: + break; + } + } + oceanbase::unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level(log_level); + + LOG_INFO("main>>>"); + oceanbase::unittest::RunCtx.time_sec_ = time_sec; + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/test_mds_transaction.cpp b/mittest/simple_server/test_mds_transaction.cpp new file mode 100644 index 000000000..db449ceb9 --- /dev/null +++ b/mittest/simple_server/test_mds_transaction.cpp @@ -0,0 +1,291 @@ +/** + * Copyright (c) 2021 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 DEBUG_FOR_MDS +#define DEBUG_FOR_MDS +#include "lib/ob_errno.h" +#endif +#include +#include +#define TEST_MDS_TRANSACTION +#include +#define USING_LOG_PREFIX SERVER +#define protected public +#define private public +#include "ob_tablet_id.h" +#include "storage/multi_data_source/common_define.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "lib/utility/serialization.h" +#include "share/cache/ob_kv_storecache.h" +#include "env/ob_simple_cluster_test_base.h" +#include "env/ob_fast_bootstrap.h" +#include "lib/mysqlclient/ob_mysql_result.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tablet/ob_tablet.h" +#include "unittest/storage/multi_data_source/example_user_helper_define.cpp" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" + +namespace oceanbase +{ +share::SCN mock_tablet_oldest_scn = unittest::mock_scn(1); +ObTabletID tablet_id; +namespace compaction +{ +int ObMediumCompactionInfo::assign(ObIAllocator &allocator, const ObMediumCompactionInfo &medium_info) +{ + UNUSED(allocator); + data_version_ = medium_info.data_version_; + return OB_SUCCESS; +} +} +namespace storage +{ +namespace mds +{ +int ObTenantMdsTimer::get_tablet_oldest_scn_(ObTablet &tablet, share::SCN &oldest_scn) +{ + #define PRINT_WRAPPER KR(ret), K(tablet), K(tablet_oldest_scn), KPC(this) + int ret = OB_SUCCESS; + if (tablet.tablet_meta_.tablet_id_ == tablet_id) {// for tested tablet + oldest_scn = mock_tablet_oldest_scn; + } else {// for other tablet + oldest_scn = unittest::mock_scn(1000);// FIXME: get correct min scn from oldest version tablet + } + return ret; + #undef PRINT_WRAPPER +} +} +} +namespace unittest +{ + +using namespace oceanbase::transaction; +using namespace oceanbase::storage; +using namespace mds; +using namespace compaction; + +class TestRunCtx +{ +public: + uint64_t tenant_id_ = 0; + int time_sec_ = 0; +}; + +TestRunCtx RunCtx; + +class TestMdsTransactionTest : public ObSimpleClusterTestBase +{ +public: + // 指定case运行目录前缀 test_ob_simple_cluster_ + TestMdsTransactionTest() : ObSimpleClusterTestBase("test_mds_transaction_") {} +}; + +TEST_F(TestMdsTransactionTest, simple_test) +{ + ASSERT_EQ(true, ObLSID(123).debug_for_mds()); + common::ObMySQLProxy *sql_proxy = GCTX.ddl_sql_proxy_; + sqlclient::ObISQLConnection *connection = nullptr; + ASSERT_EQ(OB_SUCCESS, sql_proxy->acquire(connection)); + observer::ObInnerSQLConnection *inner_conn = dynamic_cast(connection); + + ASSERT_EQ(OB_SUCCESS, inner_conn->start_transaction(OB_SYS_TENANT_ID)); + constexpr int64_t LEN = 128; + char buffer[LEN]; + int64_t pos = 0; + int64_t magic_number = 12345; + ASSERT_EQ(OB_SUCCESS, serialization::encode(buffer, LEN, pos, magic_number)); + ASSERT_EQ(OB_SUCCESS, inner_conn->register_multi_data_source(OB_SYS_TENANT_ID, share::ObLSID(1), transaction::ObTxDataSourceType::TEST1, buffer, pos)); + ASSERT_EQ(OB_SUCCESS, inner_conn->commit()); +} + +TEST_F(TestMdsTransactionTest, write_mds_table) +{ + common::ObMySQLProxy *sql_proxy = GCTX.ddl_sql_proxy_; + sqlclient::ObISQLConnection *connection = nullptr; + ASSERT_EQ(OB_SUCCESS, sql_proxy->acquire(connection)); + observer::ObInnerSQLConnection *inner_conn = dynamic_cast(connection); + + ASSERT_EQ(OB_SUCCESS, inner_conn->start_transaction(OB_SYS_TENANT_ID)); + constexpr int64_t LEN = 128; + char buffer[LEN]; + int64_t pos = 0; + int64_t magic_number = 12345; + ASSERT_EQ(OB_SUCCESS, serialization::encode(buffer, LEN, pos, magic_number)); + ASSERT_EQ(OB_SUCCESS, inner_conn->register_multi_data_source(OB_SYS_TENANT_ID, share::ObLSID(1), transaction::ObTxDataSourceType::TEST3, buffer, pos)); + // ASSERT_EQ(OB_SUCCESS, inner_conn->commit()); + ASSERT_EQ(OB_SUCCESS, inner_conn->rollback()); + // int64_t val = 0; + // ASSERT_EQ(OB_SUCCESS, TestMdsTable.get_snapshot([&val](const ExampleUserData1 &data) { + // val = data.value_; + // return OB_SUCCESS; + // }, share::SCN::max_scn())); + // ASSERT_EQ(magic_number, val); +} + +TEST_F(TestMdsTransactionTest, test_for_each_kv_in_unit_in_tablet) +{ + int ret = OB_SUCCESS; + ObMediumCompactionInfo data_1, data_2, data_3, data_11; + ObMediumCompactionInfo &data_1_ref = data_1; + data_1.data_version_ = 1; + data_2.data_version_ = 2; + data_3.data_version_ = 3; + data_11.data_version_ = 11; + auto mock_equal = [](const ObMediumCompactionInfo &lhs, const ObMediumCompactionInfo &rhs) -> bool { + return lhs.data_version_ == rhs.data_version_; + }; + MTL_SWITCH(OB_SYS_TENANT_ID) + { + int64_t _; + // 1. 新建一个tablet + ASSERT_EQ(OB_SUCCESS, GCTX.ddl_sql_proxy_->write(OB_SYS_TENANT_ID, "create table test_mds_table(a int)", _)); + // 2. 从表名拿到它的tablet_id + ObTabletID tablet_id; + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, + {"tablet_id"}, + OB_ALL_TABLE_TNAME, + "where table_name = 'test_mds_table'", + tablet_id)); + // 3. 从tablet_id拿到它的ls_id + ObLSID ls_id; + char where_condition[512] = { 0 }; + databuff_printf(where_condition, 512, "where tablet_id = %ld", tablet_id.id()); + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, + {"ls_id"}, + OB_ALL_TABLET_TO_LS_TNAME, + where_condition, + ls_id)); + // 4. 从ls_id找到ls + storage::ObLSHandle ls_handle; + ASSERT_EQ(OB_SUCCESS, MTL(storage::ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::TRANS_MOD)); + // 5. 从LS找到tablet结构 + storage::ObTabletHandle tablet_handle; + ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); + // 6. 调用tablet接口第一次写入多源数据,提交 + MdsCtx ctx1(mds::MdsWriter(ObTransID(1))); + ASSERT_EQ(OB_SUCCESS, tablet_handle.get_obj()->set(ObMediumCompactionInfoKey(1), data_1_ref, ctx1)); + ASSERT_EQ(OB_SUCCESS, tablet_handle.get_obj()->set(ObMediumCompactionInfoKey(3), data_3, ctx1)); + ctx1.single_log_commit(mock_scn(10), mock_scn(10)); + // 7. 调用tablet接口第二次写入多源数据,不提交 + MdsCtx ctx2(mds::MdsWriter(ObTransID(2))); + ASSERT_EQ(OB_SUCCESS, tablet_handle.get_obj()->set(ObMediumCompactionInfoKey(1), data_11, ctx2)); + ASSERT_EQ(OB_SUCCESS, tablet_handle.get_obj()->set(ObMediumCompactionInfoKey(2), data_2, ctx2)); + } +}// ctx2 is auto aborted, but print ERROR log + +TEST_F(TestMdsTransactionTest, test_mds_table_gc_and_recycle) +{ + int ret = OB_SUCCESS; + ObTabletBindingMdsUserData data_to_write; + data_to_write.schema_version_ = 1; + data_to_write.data_tablet_id_ = ObTabletID(2); + data_to_write.hidden_tablet_id_ = ObTabletID(3); + data_to_write.lob_meta_tablet_id_ = ObTabletID(4); + data_to_write.lob_piece_tablet_id_ = ObTabletID(5); + auto mock_equal = [](const ObMediumCompactionInfo &lhs, + const ObMediumCompactionInfo &rhs) -> bool { + return lhs.data_version_ == rhs.data_version_; + }; + MTL_SWITCH(OB_SYS_TENANT_ID) + { + int64_t _; + // 1. 新建一个tablet + ASSERT_EQ(OB_SUCCESS, GCTX.ddl_sql_proxy_->write(OB_SYS_TENANT_ID, "create table test_mds_table2(a int)", _)); + // 2. 从表名拿到它的tablet_id + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, + {"tablet_id"}, + OB_ALL_TABLE_TNAME, + "where table_name = 'test_mds_table2'", + tablet_id)); + // 3. 从tablet_id拿到它的ls_id + ObLSID ls_id; + char where_condition[512] = { 0 }; + databuff_printf(where_condition, 512, "where tablet_id = %ld", tablet_id.id()); + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, + {"ls_id"}, + OB_ALL_TABLET_TO_LS_TNAME, + where_condition, + ls_id)); + // 4. 从ls_id找到ls + storage::ObLSHandle ls_handle; + ASSERT_EQ(OB_SUCCESS, MTL(storage::ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::TRANS_MOD)); + // 5. 从LS找到tablet结构 + storage::ObTabletHandle tablet_handle; + ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); + MDS_LOG(ERROR, "xuwang.txw debug", K(tablet_id)); + // 6. 调用tablet接口写入多源数据,提交 + MdsCtx ctx1(mds::MdsWriter(ObTransID(1))); + share::SCN rec_scn; + ASSERT_EQ(OB_SUCCESS, tablet_handle.get_obj()->set(data_to_write, ctx1)); + // ASSERT_EQ(OB_SUCCESS, static_cast(tablet_handle.get_obj()->pointer_hdl_.get_resource_ptr())->mds_table_handler_.mds_table_handle_.get_rec_scn(rec_scn)); + // ASSERT_EQ(share::SCN::max_scn(), rec_scn); + ctx1.single_log_commit(mock_scn(10), mock_scn(10000000)); + ASSERT_EQ(true, static_cast(tablet_handle.get_obj()->pointer_hdl_.get_resource_ptr())->mds_table_handler_.mds_table_handle_.is_valid()); + // ASSERT_EQ(OB_SUCCESS, static_cast(tablet_handle.get_obj()->pointer_hdl_.get_resource_ptr())->mds_table_handler_.mds_table_handle_.get_rec_scn(rec_scn)); + // ASSERT_EQ(mock_scn(10), rec_scn); + std::this_thread::sleep_for(std::chrono::seconds(5)); + MDS_LOG(ERROR, "xuwang.txw debug1"); + ASSERT_EQ(OB_SUCCESS, tablet_handle.get_obj()->mds_table_flush(share::SCN::max_scn())); + // 7. 检查mds table的存在情况 + std::this_thread::sleep_for(std::chrono::seconds(5)); + ASSERT_EQ(true, static_cast(tablet_handle.get_obj()->pointer_hdl_.get_resource_ptr())->mds_table_handler_.mds_table_handle_.is_valid()); + ASSERT_EQ(OB_SUCCESS, static_cast(tablet_handle.get_obj()->pointer_hdl_.get_resource_ptr())->mds_table_handler_.mds_table_handle_.get_rec_scn(rec_scn)); + ASSERT_EQ(share::SCN::max_scn(), rec_scn); + MDS_LOG(ERROR, "change mock_tablet_oldest_scn", K(tablet_id)); + mock_tablet_oldest_scn = unittest::mock_scn(2074916885902668817); + std::this_thread::sleep_for(std::chrono::seconds(15)); + ASSERT_EQ(false, static_cast(tablet_handle.get_obj()->pointer_hdl_.get_resource_ptr())->mds_table_handler_.mds_table_handle_.is_valid()); + ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle));// 重新获取一下tablet handle + ASSERT_EQ(OB_SUCCESS, tablet_handle.get_obj()->get_mds_data_from_tablet([&data_to_write](const ObTabletBindingMdsUserData &data_to_read) -> int { + OB_ASSERT(data_to_write.schema_version_ == data_to_read.schema_version_); + return OB_SUCCESS; + })); + } +} + +TEST_F(TestMdsTransactionTest, end) +{ + if (RunCtx.time_sec_ > 0) { + ::sleep(RunCtx.time_sec_); + } +} + +} // end unittest +} // end oceanbase + + +int main(int argc, char **argv) +{ + int c = 0; + int time_sec = 0; + char *log_level = (char*)"INFO"; + while(EOF != (c = getopt(argc,argv,"t:l:"))) { + switch(c) { + case 't': + time_sec = atoi(optarg); + break; + case 'l': + log_level = optarg; + oceanbase::unittest::ObSimpleClusterTestBase::enable_env_warn_log_ = false; + break; + default: + break; + } + } + oceanbase::unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level(log_level); + + LOG_INFO("main>>>"); + oceanbase::unittest::RunCtx.time_sec_ = time_sec; + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/test_mds_tx_ctx_recover_mem_leak.cpp b/mittest/simple_server/test_mds_tx_ctx_recover_mem_leak.cpp new file mode 100644 index 000000000..99ad68478 --- /dev/null +++ b/mittest/simple_server/test_mds_tx_ctx_recover_mem_leak.cpp @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2021 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/time/ob_time_utility.h" +#include +#include +#define USING_LOG_PREFIX STORAGE +#define protected public +#define private public +#include "lib/container/ob_tuple.h" +#include "lib/ob_define.h" +#include "ob_tablet_id.h" +#include "share/inner_table/ob_inner_table_schema_constants.h" +#include "share/ob_ls_id.h" +#include "env/ob_simple_cluster_test_base.h" +#include "env/ob_simple_server_restart_helper.h" +#include "lib/mysqlclient/ob_mysql_result.h" +#include "logservice/rcservice/ob_role_change_service.h" +#include "logservice/ob_ls_adapter.h" +#include "storage/access/ob_rows_info.h" +#include "storage/checkpoint/ob_data_checkpoint.h" +#include "storage/compaction/ob_schedule_dag_func.h" +#include "storage/compaction/ob_tablet_merge_task.h" +#include "storage/ls/ob_freezer.h" +#include "storage/ls/ob_ls.h" +#include "storage/ls/ob_ls_meta.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls_tx_service.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/ob_relative_table.h" +#include "storage/ob_storage_table_guard.h" +#include "storage/tx_storage/ob_ls_map.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" +#include + +#undef private +#undef protected + +static const char *TEST_FILE_NAME = "test_mds_tx_ctx_recover_mem_leak"; +static const char *BORN_CASE_NAME = "ObTestMdsTxCtxRecoverMemLeakBeforeRecover"; +static const char *RESTART_CASE_NAME = "ObTestMdsTxCtxRecoverMemLeakAfterRecover"; + +using namespace std; + +ObSimpleServerRestartHelper *helper_ptr = nullptr; + +namespace oceanbase +{ +using namespace transaction; +using namespace storage; +using namespace share; +namespace unittest +{ +class ObTestMdsTxCtxRecoverMemLeakBeforeRecover : public ObSimpleClusterTestBase +{ +public: + ObTestMdsTxCtxRecoverMemLeakBeforeRecover() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} +}; + +void wait_user() +{ + std::cout << "Enter anything to continue..." << std::endl; + char a = '\0'; + std::cin >> a; +} + +class TestRunCtx +{ +public: + uint64_t tenant_id_ = 0; + int time_sec_ = 0; +}; + +TestRunCtx RunCtx; + +TEST_F(ObTestMdsTxCtxRecoverMemLeakBeforeRecover, add_tenant) +{ + OCCAM_LOG(INFO, "step 1: 创建普通租户tt1"); + ASSERT_EQ(OB_SUCCESS, create_tenant()); + OCCAM_LOG(INFO, "step 2: 获取租户tt1的tenant_id"); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(RunCtx.tenant_id_)); + ASSERT_NE(0, RunCtx.tenant_id_); + OCCAM_LOG(INFO, "step 3: 初始化普通租户tt1的sql proxy"); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); +} + +TEST_F(ObTestMdsTxCtxRecoverMemLeakBeforeRecover, create_table_then_insert_then_minor_freeze) +{ + int ret = OB_SUCCESS; + OCCAM_LOG(INFO, "step 4: 使用普通租户tt1的proxy"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + OCCAM_LOG(INFO, "step 5: 创建无主键表"); + int64_t affected_rows = 0; + sleep(3); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write("create table test(a int)", affected_rows)); + OCCAM_LOG(INFO, "step 6: 开启事务"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write("begin", affected_rows)); + OCCAM_LOG(INFO, "step 7: 插入一条数据,此时会修改多源数据auto_inc"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write("insert into test values(1)", affected_rows)); + int64_t do_freeze_time = ObTimeUtility::current_time(); + OCCAM_LOG(INFO, "step 8: 执行minor freeze,确保tx_ctx_table转储下去了(带着mds ctx一起)"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write("alter system minor freeze", affected_rows)); + OCCAM_LOG(INFO, "step 9: 从表名拿到它的tablet_id"); + ObTabletID tablet_id; + ObLSID ls_id; + char where_condition[512] = { 0 }; + databuff_printf(where_condition, 512, "where table_name = '%s'", "test"); + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(RunCtx.tenant_id_, + {"tablet_id"}, + OB_ALL_TABLE_TNAME, + where_condition, + tablet_id)); + OCCAM_LOG(INFO, "step 10: 从tablet_id拿到它的ls_id"); + databuff_printf(where_condition, 512, "where tablet_id = %ld", tablet_id.id()); + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(RunCtx.tenant_id_, + {"ls_id"}, + OB_ALL_TABLET_TO_LS_TNAME, + where_condition, + ls_id)); + int64_t tx_ctx_table_compaction_time = 0; + do { + databuff_printf(where_condition, 512, "where tenant_id = %ld and ls_id = %ld and tablet_id = 49401 order by finish_time desc limit 1", RunCtx.tenant_id_, ls_id.id()); + ret = ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, {"TIME_TO_USEC(finish_time)"}, OB_ALL_VIRTUAL_TABLET_COMPACTION_HISTORY_TNAME, where_condition, tx_ctx_table_compaction_time); + OCCAM_LOG(INFO, "read compaction history", KR(ret), K(tx_ctx_table_compaction_time), K(RunCtx.tenant_id_), K(ls_id), K(tablet_id)); + ASSERT_EQ(true, OB_SUCCESS == ret || OB_ITER_END == ret); + } while (tx_ctx_table_compaction_time <= do_freeze_time); +} + +class ObTestMdsTxCtxRecoverMemLeakAfterRecover : public ObSimpleClusterTestBase +{ +public: + ObTestMdsTxCtxRecoverMemLeakAfterRecover() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} +}; + +TEST_F(ObTestMdsTxCtxRecoverMemLeakAfterRecover, after_recover_test) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + OCCAM_LOG(INFO, "step 10: before delete tenant"); + ASSERT_EQ(OB_SUCCESS, delete_tenant("tt1")); + OCCAM_LOG(INFO, "step 11: after delete tenant"); + int64_t result_num = 0; + // 等待租户的MTL组建析构,此时会检查内存泄露 + do { + char where_condition[512] = { 0 }; + databuff_printf(where_condition, 512, "where event = 'remove_tenant' and value1 = 1002"); + ASSERT_EQ(OB_SUCCESS, ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, {"count(*)"}, OB_ALL_ROOTSERVICE_EVENT_HISTORY_TNAME, where_condition, result_num)); + std::this_thread::sleep_for(std::chrono::seconds(1)); + OCCAM_LOG(INFO, "step 12: wait MTL destroy"); + } while (result_num == 0); + OCCAM_LOG(INFO, "step 13: MTL destroy done"); +} + +} // namespace unittest +} // namespace oceanbase + +int main(int argc, char **argv) +{ + int c = 0; + int time_sec = 0; + int concurrency = 1; + char *log_level = (char *)"INFO"; + system("rm -rf ./test_mds_tx_ctx_recover_mem_leak_*"); + while (EOF != (c = getopt(argc, argv, "t:l:"))) { + switch (c) { + case 't': + time_sec = atoi(optarg); + break; + case 'l': + log_level = optarg; + oceanbase::unittest::ObSimpleClusterTestBase::enable_env_warn_log_ = false; + break; + case 'c': + concurrency = atoi(optarg); + break; + default: + break; + } + } + std::string gtest_file_name = std::string(TEST_FILE_NAME) + "_gtest.log"; + oceanbase::unittest::init_gtest_output(gtest_file_name); + + int ret = 0; + ObSimpleServerRestartHelper restart_helper(argc, argv, TEST_FILE_NAME, BORN_CASE_NAME, + RESTART_CASE_NAME); + helper_ptr = &restart_helper; + restart_helper.set_sleep_sec(time_sec); + restart_helper.run(); + + return ret; +} \ No newline at end of file diff --git a/mittest/simple_server/test_mvcc_gc.cpp b/mittest/simple_server/test_mvcc_gc.cpp index e88c03692..c7518048b 100644 --- a/mittest/simple_server/test_mvcc_gc.cpp +++ b/mittest/simple_server/test_mvcc_gc.cpp @@ -135,7 +135,7 @@ int ObLSTabletService::insert_rows( } else if (first_bulk) { first_bulk = false; row_count_first_bulk = row_count; - const ObTableReadInfo &full_read_info = tablet_handle.get_obj()->get_full_read_info(); + const ObITableReadInfo &full_read_info = tablet_handle.get_obj()->get_rowkey_read_info(); if (OB_FAIL(rows_info.init(data_table, ctx, full_read_info))) { STORAGE_LOG(WARN, "Failed to init rows info", K(ret), K(data_table)); } else if (OB_ISNULL(ptr = work_allocator.alloc(row_count * sizeof(ObStoreRow)))) { diff --git a/mittest/simple_server/test_ob_obj_lock_garbage_collector.cpp b/mittest/simple_server/test_ob_obj_lock_garbage_collector.cpp index bcfad3a97..da415e7b5 100644 --- a/mittest/simple_server/test_ob_obj_lock_garbage_collector.cpp +++ b/mittest/simple_server/test_ob_obj_lock_garbage_collector.cpp @@ -314,8 +314,8 @@ TEST_F(ObOBJLockGCBeforeRestartTest, obj_lock_gc_with_tablelock_service) { LOG_INFO("ObOBJLockGCBeforeRestartTest::obj_lock_gc_with_tablelock_service"); int ret = OB_SUCCESS; - ObTableLockOwnerID OWNER_ONE = 1; - ObTableLockOwnerID OWNER_TWO = 2; + ObTableLockOwnerID OWNER_ONE(1); + ObTableLockOwnerID OWNER_TWO(2); uint64_t table_id = 0; ObTableLockMode lock_mode = EXCLUSIVE; share::ObTenantSwitchGuard tenant_guard; diff --git a/mittest/simple_server/test_ob_partition_balance.cpp b/mittest/simple_server/test_ob_partition_balance.cpp new file mode 100644 index 000000000..8e18d36f7 --- /dev/null +++ b/mittest/simple_server/test_ob_partition_balance.cpp @@ -0,0 +1,376 @@ +/** + * Copyright (c) 2021 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 +#define USING_LOG_PREFIX SERVER +#define protected public +#define private public + +#include "env/ob_simple_cluster_test_base.h" +#include "env/ob_fast_bootstrap.h" +#include "lib/mysqlclient/ob_mysql_result.h" +#include "rootserver/ob_partition_balance.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "share/ls/ob_ls_operator.h" + +namespace oceanbase +{ + +namespace rootserver +{ + +int g_ls_cnt = 1; +int ObPartitionBalance::prepare_ls_() +{ + ls_desc_map_.create(10, lib::Label("")); + int ls_cnt = g_ls_cnt; + for (int i = 1; i <= ls_cnt; i++) { + auto ls_desc = new ObPartitionBalance::ObLSDesc(ObLSID(i), 0); + ls_desc_array_.push_back(ls_desc); + ls_desc_map_.set_refactored(ls_desc->ls_id_, ls_desc); + } + return OB_SUCCESS; +} + +int ObPartitionBalance::process() +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(prepare_balance_group_())) { + LOG_WARN("prepare_balance_group fail", KR(ret)); + } else if (OB_FAIL(save_balance_group_stat_())) { + LOG_WARN("save_balance_group_stat fail", KR(ret)); + } else if (OB_FAIL(process_balance_partition_inner_())) { + LOG_WARN("process_balance_partition_inner fail", KR(ret)); + } else if (OB_FAIL(process_balance_partition_extend_())) { + LOG_WARN("process_balance_partition_extend fail", KR(ret)); + } else if (OB_FAIL(process_balance_partition_disk_())) { + LOG_WARN("process_balance_partition_disk fail", KR(ret)); + } else if (OB_FAIL(generate_balance_job_from_logical_task_())) { + LOG_WARN("generate_balance_job_from_logical_task_ fail", KR(ret)); + } + return ret; +} +} + + +namespace unittest +{ + +using namespace oceanbase::transaction; +using namespace oceanbase::storage; +using namespace oceanbase::share; +using namespace oceanbase::rootserver; + + +class TestRunCtx +{ +public: + uint64_t tenant_id_ = 0; + int time_sec_ = 0; +}; + +TestRunCtx RunCtx; + +class ObBalancePartitionTest : public ObSimpleClusterTestBase +{ +public: + // 指定case运行目录前缀 test_ob_simple_cluster_ + ObBalancePartitionTest() : ObSimpleClusterTestBase("test_ob_balance_partition_") { + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + sql_proxy.write("drop database test", affected_rows); + sql_proxy.write("create database test", affected_rows); + sql_proxy.write("use test", affected_rows); + sql_proxy.write("drop tablegroup if exists my_tablegroup", affected_rows); + } + int run(int ls_cnt) { + int ret = OB_SUCCESS; + g_ls_cnt = ls_cnt; + ObPartitionBalance balance_part_job; + ObCurTraceId::get_trace_id()->set(std::string(std::to_string(ObTimeUtility::current_time()%10000)).c_str()); + ObTenantSwitchGuard guard; + LOG_INFO("balance_part_job start>>>>>>>>>>>>>>>>>"); + + if (OB_FAIL(guard.switch_to(OB_SYS_TENANT_ID))) { + LOG_WARN("switch tenant", KR(ret)); + } else if (OB_FAIL(balance_part_job.init(OB_SYS_TENANT_ID, GCTX.schema_service_, GCTX.sql_proxy_, 1,1))) { + LOG_WARN("balance_part_job init fail", KR(ret)); + } else if (OB_FAIL(balance_part_job.process())) { + LOG_WARN("balance_part_job process fail", KR(ret)); + } else { + std::sort(balance_part_job.ls_desc_array_.begin(), balance_part_job.ls_desc_array_.end(), [] (const ObPartitionBalance::ObLSDesc* left, const ObPartitionBalance::ObLSDesc* right) { + return left->partgroup_cnt_ < right->partgroup_cnt_; + }); + LOG_INFO("balance_part_job bg_map size", K(balance_part_job.bg_map_.size())); + for (auto iter = balance_part_job.bg_map_.begin(); iter != balance_part_job.bg_map_.end(); iter++) { + for (int i = 0; i < iter->second.count(); i++) { + LOG_INFO("balance_part_job bg_map", K(iter->first), K(iter->second.at(i)->ls_id_), K(iter->second.at(i)->part_groups_.count())); + } + } + LOG_INFO("balance_part_job res", "size", balance_part_job.transfer_logical_tasks_.size(), "ls_array", balance_part_job.ls_desc_array_); + for (auto iter = balance_part_job.transfer_logical_tasks_.begin(); iter != balance_part_job.transfer_logical_tasks_.end(); iter++) { + LOG_INFO("balance_part_job:", "task_key", iter->first, "part_cnt", iter->second.count(), "part_list", iter->second); + } + if (balance_part_job.ls_desc_array_.at(balance_part_job.ls_desc_array_.count()-1)->partgroup_cnt_ - balance_part_job.ls_desc_array_.at(0)->partgroup_cnt_ > 1) { + ret = -1; + LOG_WARN("partition not balance", KR(ret), K(balance_part_job.ls_desc_array_.at(balance_part_job.ls_desc_array_.count()-1)), K(balance_part_job.ls_desc_array_.at(0))); + } + } + return ret; + } +}; + +TEST_F(ObBalancePartitionTest, observer_start) +{ + SERVER_LOG(INFO, "observer_start succ"); +} + +TEST_F(ObBalancePartitionTest, empty) +{ + LOG_INFO("-----------empty-------------"); + for (int i = 1; i <= 2; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + +// 非分区表整体是一个均衡组,表做平铺 +TEST_F(ObBalancePartitionTest, simple_table) +{ + LOG_INFO("-----------simple_table-------------"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // 创建表 + for (int i = 1; i <= 17; i++) { + sql.assign_fmt("create table basic_%d(col1 int)", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + } + for (int i = 1; i <= 20; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + +// 每个一级分区的表是一个均衡组,一级分区做平铺 +TEST_F(ObBalancePartitionTest, partition) +{ + LOG_INFO("-----------partition-------------"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + // 创建表 + for (int i = 1; i <= 5; i++) { + ObSqlString sql; + sql.assign_fmt("create table partition_%d(col1 int) partition by hash(col1) partitions 10", i); + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + } + for (int i = 1; i <= 10; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + +TEST_F(ObBalancePartitionTest, subpart) +{ + LOG_INFO("-----------subpart-------------"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + // 创建表 + for (int i = 1; i <= 5; i++) { + ObSqlString sql; + sql.assign_fmt("create table subpart_%d(col1 int) partition by range(col1) subpartition by hash(col1) subpartitions 10 (partition p1 values less than (100), partition p2 values less than MAXVALUE)", i); + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + } + for (int i = 1; i <= 10; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + +TEST_F(ObBalancePartitionTest, tablegroup_sharding_none) +{ + LOG_INFO("-----------tablegroup_sharding_none-------------"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + sql.assign_fmt("create tablegroup my_tablegroup sharding='NONE'"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + for (int i = 0; i < 10; i++) { + sql.assign_fmt("create table stu_%d(col1 int) tablegroup='my_tablegroup'", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + sql.assign_fmt("create table part_%d(col1 int) tablegroup=my_tablegroup partition by hash(col1) partitions 10", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + sql.assign_fmt("create table subpart_%d(col1 int) tablegroup=my_tablegroup partition by range(col1) subpartition by hash(col1) subpartitions 10 (partition p1 values less than (100), partition p2 values less than MAXVALUE)", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + } + + for (int i = 1; i <= 3; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + +TEST_F(ObBalancePartitionTest, tablegroup_sharding_partition1) +{ + LOG_INFO("-----------tablegroup_sharding_partition1-------------"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + sql.assign_fmt("create tablegroup my_tablegroup sharding='PARTITION'"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + for (int i = 0; i < 10; i++) { + sql.assign_fmt("create table stu_%d(col1 int) tablegroup=my_tablegroup", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + } + + for (int i = 1; i <= 3; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + +TEST_F(ObBalancePartitionTest, tablegroup_sharding_partition2) +{ + LOG_INFO("-----------tablegroup_sharding_partition2-------------"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + sql.assign_fmt("create tablegroup my_tablegroup sharding='PARTITION'"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + for (int i = 0; i < 10; i++) { + sql.assign_fmt("create table stu_%d(col1 int) tablegroup=my_tablegroup partition by hash(col1) partitions 10", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + } + + for (int i = 1; i <= 3; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + +TEST_F(ObBalancePartitionTest, tablegroup_sharding_partition3) +{ + LOG_INFO("-----------tablegroup_sharding_partition3-------------"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + sql.assign_fmt("create tablegroup my_tablegroup sharding='PARTITION'"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + for (int i = 0; i < 10; i++) { + sql.assign_fmt("create table part_%d(col1 int) tablegroup=my_tablegroup partition by range(col1) (partition p1 values less than(100), partition p2 values less than MAXVALUE)", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + sql.assign_fmt("create table subpart_%d(col1 int) tablegroup=my_tablegroup partition by range(col1) subpartition by hash(col1) subpartitions 10 (partition p1 values less than (100), partition p2 values less than MAXVALUE)", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + } + + for (int i = 1; i <= 3; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + +TEST_F(ObBalancePartitionTest, tablegroup_sharding_adaptive1) +{ + LOG_INFO("-----------tablegroup_sharding_adaptive1-------------"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + sql.assign_fmt("create tablegroup my_tablegroup sharding='ADAPTIVE'"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + for (int i = 0; i < 10; i++) { + sql.assign_fmt("create table stu_%d(col1 int) tablegroup=my_tablegroup", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + } + + for (int i = 1; i <= 3; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + +TEST_F(ObBalancePartitionTest, tablegroup_sharding_adaptive2) +{ + LOG_INFO("-----------tablegroup_sharding_adaptive2-------------"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + sql.assign_fmt("create tablegroup my_tablegroup sharding='ADAPTIVE'"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + for (int i = 0; i < 10; i++) { + sql.assign_fmt("create table stu_%d(col1 int) tablegroup=my_tablegroup partition by hash(col1) partitions 10", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + } + + for (int i = 1; i <= 3; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + +TEST_F(ObBalancePartitionTest, tablegroup_sharding_adaptive3) +{ + LOG_INFO("-----------tablegroup_sharding_adaptive3-------------"); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + sql.assign_fmt("create tablegroup my_tablegroup sharding='ADAPTIVE'"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + for (int i = 0; i < 10; i++) { + sql.assign_fmt("create table subpart_%d(col1 int) tablegroup=my_tablegroup partition by range(col1) subpartition by hash(col1) subpartitions 10 (partition p1 values less than (100), partition p2 values less than MAXVALUE)", i); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + } + + for (int i = 1; i <= 3; i++) { + ASSERT_EQ(OB_SUCCESS, run(i)); + } +} + + +TEST_F(ObBalancePartitionTest, end) +{ + if (RunCtx.time_sec_ > 0) { + ::sleep(RunCtx.time_sec_); + } +} + +} // end unittest +} // end oceanbase + + +int main(int argc, char **argv) +{ + int c = 0; + int time_sec = 0; + char *log_level = (char*)"INFO"; + while(EOF != (c = getopt(argc,argv,"t:l:"))) { + switch(c) { + case 't': + time_sec = atoi(optarg); + break; + case 'l': + log_level = optarg; + oceanbase::unittest::ObSimpleClusterTestBase::enable_env_warn_log_ = false; + break; + default: + break; + } + } + oceanbase::unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level(log_level); + + LOG_INFO("main>>>"); + oceanbase::unittest::RunCtx.time_sec_ = time_sec; + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/test_ob_simple_rto.cpp b/mittest/simple_server/test_ob_simple_rto.cpp index aba4dc7db..00549eb9a 100644 --- a/mittest/simple_server/test_ob_simple_rto.cpp +++ b/mittest/simple_server/test_ob_simple_rto.cpp @@ -15,7 +15,6 @@ #include #define private public #include "share/scn.h" -#include "storage/slog/ob_storage_logger.h" #include "env/ob_simple_cluster_test_base.h" #include "logservice/ob_log_service.h" #include "logservice/leader_coordinator/ob_failure_detector.h" @@ -25,9 +24,7 @@ const std::string TEST_NAME = "rto_func"; const int64_t CLOG_HANG_TIME_THRESHOLD_US = 5 * 1000 * 1000; int64_t mock_fatal_err_ts = OB_INVALID_TIMESTAMP; bool mock_clog_disk_hang = false; -bool mock_sstable_io_hang = false; -//slog的路径全部为inline函数,暂时无法mock -//bool mock_slog_io_hang = false; +bool mock_disk_io_hang = false; bool mock_clog_disk_full = false; using namespace oceanbase; namespace oceanbase @@ -39,7 +36,7 @@ namespace common int ObIOFaultDetector::get_device_health_status(ObDeviceHealthStatus &dhs, int64_t &device_abnormal_time) { - if (mock_sstable_io_hang) { + if (mock_disk_io_hang) { dhs = DEVICE_HEALTH_WARNING; device_abnormal_time = mock_fatal_err_ts - GCONF.data_storage_warning_tolerance_time; } else { @@ -105,16 +102,16 @@ TEST_F(ObRTOTest, basic_rto) usleep(100 * 1000); } - //mock sstable io hang + //mock disk io hang mock_fatal_err_ts = ObTimeUtility::fast_current_time(); - mock_sstable_io_hang = true; - while (!MTL(ObFailureDetector*)->has_add_sstable_hang_event_) { - CLOG_LOG(INFO, "waiting detect sstable io hang"); + mock_disk_io_hang = true; + while (!MTL(ObFailureDetector*)->has_add_data_disk_hang_event_) { + CLOG_LOG(INFO, "waiting detect disk io hang"); usleep(100 * 1000); } - mock_sstable_io_hang = false; - while (MTL(ObFailureDetector*)->has_add_sstable_hang_event_) { - CLOG_LOG(INFO, "waiting recover sstable io hang"); + mock_disk_io_hang = false; + while (MTL(ObFailureDetector*)->has_add_data_disk_hang_event_) { + CLOG_LOG(INFO, "waiting recover disk io hang"); usleep(100 * 1000); } } diff --git a/mittest/simple_server/test_ob_table_lock_service.cpp b/mittest/simple_server/test_ob_table_lock_service.cpp index 904eff377..44a02f7ed 100644 --- a/mittest/simple_server/test_ob_table_lock_service.cpp +++ b/mittest/simple_server/test_ob_table_lock_service.cpp @@ -295,11 +295,11 @@ TEST_F(ObTableLockServiceTest, lock_table) { LOG_INFO("ObTableLockServiceTest::lock_table"); int ret = OB_SUCCESS; - ObTableLockOwnerID OWNER_ONE = 1; - ObTableLockOwnerID OWNER_TWO = 2; + ObTableLockOwnerID OWNER_ONE(1); + ObTableLockOwnerID OWNER_TWO(2); uint64_t table_id = 0; ObTableLockMode lock_mode = EXCLUSIVE; - ObTableLockOwnerID lock_owner = 0; + ObTableLockOwnerID lock_owner(0); share::ObTenantSwitchGuard tenant_guard; ret = tenant_guard.switch_to(OB_SYS_TENANT_ID); @@ -389,8 +389,8 @@ TEST_F(ObTableLockServiceTest, lock_part) uint64_t table_id = 0; ObSEArray part_ids; ObTableLockMode lock_mode = ROW_EXCLUSIVE; - ObTableLockOwnerID OWNER_ONE = 1; - ObTableLockOwnerID OWNER_TWO = 2; + ObTableLockOwnerID OWNER_ONE(1); + ObTableLockOwnerID OWNER_TWO(2); ObLockPartitionRequest lock_arg; tx_param.access_mode_ = ObTxAccessMode::RW; @@ -500,11 +500,11 @@ TEST_F(ObTableLockServiceTest, lock_tablet) // 2.1 unlock tablet of one part table // 2.2 unlock tablet of multi part table int ret = OB_SUCCESS; - ObTableLockOwnerID OWNER_ONE = 1; - ObTableLockOwnerID OWNER_TWO = 2; + ObTableLockOwnerID OWNER_ONE(1); + ObTableLockOwnerID OWNER_TWO(2); uint64_t table_id = 0; ObTableLockMode lock_mode = EXCLUSIVE; - ObTableLockOwnerID lock_owner = 0; + ObTableLockOwnerID lock_owner(0); share::ObTenantSwitchGuard tenant_guard; ObTabletIDArray tablet_list; @@ -611,7 +611,7 @@ TEST_F(ObTableLockServiceTest, in_trans_lock_table) ObTransService *txs = nullptr; uint64_t table_id = 0; ObTableLockMode lock_mode = ROW_EXCLUSIVE; - ObTableLockOwnerID OWNER_ONE = 1; + ObTableLockOwnerID OWNER_ONE(1); ObLockTableRequest lock_arg; tx_param.access_mode_ = ObTxAccessMode::RW; @@ -691,7 +691,8 @@ TEST_F(ObTableLockServiceTest, lock_out_trans_after_in_trans) ObTransService *txs = nullptr; uint64_t table_id = 0; ObTableLockMode lock_mode = ROW_EXCLUSIVE; - ObTableLockOwnerID OWNER_ONE = 1; + ObTableLockOwnerID OWNER_ONE(1); + ObTableLockOwnerID DEFAULT_OWNER_ID(0); ObLockTableRequest lock_arg; tx_param.access_mode_ = ObTxAccessMode::RW; @@ -812,7 +813,7 @@ TEST_F(ObTableLockServiceTest, lock_out_trans_after_in_trans) LOG_INFO("ObTableLockServiceTest::lock_out_trans_after_in_trans 2.6"); ret = MTL(ObTableLockService*)->unlock_table(table_id, lock_mode, - 0); + DEFAULT_OWNER_ID); ASSERT_EQ(OB_SUCCESS, ret); // 2.7 recheck after unlock @@ -843,7 +844,7 @@ TEST_F(ObTableLockServiceTest, in_trans_lock_obj) ObTransService *txs = nullptr; uint64_t obj_id1 = 1010; ObTableLockMode lock_mode1 = SHARE; - ObTableLockOwnerID OWNER_ONE = 1; + ObTableLockOwnerID OWNER_ONE(1); ObLockObjRequest lock_arg; tx_param.access_mode_ = ObTxAccessMode::RW; diff --git a/mittest/simple_server/test_ob_tablet_to_ls_operator.cpp b/mittest/simple_server/test_ob_tablet_to_ls_operator.cpp new file mode 100644 index 000000000..0b92a3dab --- /dev/null +++ b/mittest/simple_server/test_ob_tablet_to_ls_operator.cpp @@ -0,0 +1,441 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE + +#include +#include +#include "share/tablet/ob_tablet_to_ls_operator.cpp" +#include "lib/string/ob_sql_string.h" // ObSqlString +#include "lib/mysqlclient/ob_mysql_proxy.h" // ObISqlClient, SMART_VAR +#include "observer/ob_sql_client_decorator.h" // ObSQLClientRetryWeak +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log.h" + +namespace oceanbase +{ +using namespace unittest; +namespace share +{ +using ::testing::_; +using ::testing::Invoke; +using ::testing::Return; + +using namespace schema; +using namespace common; + +class TestTabletToLSOperator : public unittest::ObSimpleClusterTestBase +{ +public: + TestTabletToLSOperator() : unittest::ObSimpleClusterTestBase("test_ls_status_operator") {} +}; + +TEST_F(TestTabletToLSOperator, UpdateLSAndTransSeq) +{ + int ret = OB_SUCCESS; + ObSEArray ls_infos; + ObTabletToLSInfo info; + ObLSID ls1 = ObLSID(1); + ObLSID ls2 = ObLSID(2); + ObLSID ls3 = ObLSID(3); + ObTabletID t1 = ObTabletID(1); + ObTabletID t2 = ObTabletID(2); + ObTabletID t3 = ObTabletID(3); + const uint64_t table_id = 1; + int64_t old_transfer_seq = 0; + int64_t new_transfer_seq = 1; + int64_t ls_id = ObLSID::INVALID_LS_ID; + int64_t transfer_seq = -1; + info.reset(); + info.init(t1, ls1, table_id, old_transfer_seq); + ls_infos.push_back(info); + info.reset(); + info.init(t2, ls2, table_id, old_transfer_seq); + ls_infos.push_back(info); + info.reset(); + info.init(t3, ls3, table_id, old_transfer_seq); + ls_infos.push_back(info); + ASSERT_EQ(3, ls_infos.count()); + ret = ObTabletToLSTableOperator::batch_update( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + ls_infos); + ASSERT_EQ(OB_SUCCESS, ret); + + // test OB_INVALID_ARGUMENT: invalid tenant_id + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_INVALID_TENANT_ID, + t1, + old_transfer_seq, + ls1, + new_transfer_seq, + ls2); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); + // test OB_INVALID_ARGUMENT: invalid old_transfer_seq + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + -1, + ls1, + new_transfer_seq, + ls2); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); + // test OB_INVALID_ARGUMENT: invalid new_transfer_seq + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + old_transfer_seq, + ls1, + -1, + ls2); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); + // test OB_INVALID_ARGUMENT: old_transfer_seq == new_transfer_seq + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + old_transfer_seq, + ls1, + old_transfer_seq, + ls2); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); + // test OB_INVALID_ARGUMENT: invalid tablet_id + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + ObTabletID(), + old_transfer_seq, + ls1, + new_transfer_seq, + ls2); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); + // test OB_INVALID_ARGUMENT: invalid old_ls_id + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + old_transfer_seq, + ObLSID(), + new_transfer_seq, + ls2); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); + // test OB_INVALID_ARGUMENT: invalid new_ls_id + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + old_transfer_seq, + ls1, + new_transfer_seq, + ObLSID()); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); + // test OB_INVALID_ARGUMENT: old_ls_id == new_ls_id + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + old_transfer_seq, + ls1, + new_transfer_seq, + ls1); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); + + // test OB_ENTRY_NOT_EXIST: t1 is not in ls3 + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + old_transfer_seq, + ls3, + new_transfer_seq, + ls2); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret); + // test OB_ENTRY_NOT_EXIST: t1's transfer_seq should be 0, but here it's 3 + old_transfer_seq = 3; + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + old_transfer_seq, + ls1, + new_transfer_seq, + ls2); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret); + + // test OB_SUCCESS: transfer t1 from ls1 to ls2 + old_transfer_seq = 0; + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + old_transfer_seq, + ls1, + new_transfer_seq, + ls2); + ASSERT_EQ(OB_SUCCESS, ret); + // test OB_ENTRY_NOT_EXIST: t1 is not in ls1 + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + old_transfer_seq, + ls1, + new_transfer_seq, + ls2); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret); + // test OB_SUCCESS: transfer t1 from ls2 to ls3 + old_transfer_seq = new_transfer_seq; + new_transfer_seq = new_transfer_seq + 1; + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t1, + old_transfer_seq, + ls2, + new_transfer_seq, + ls3); + ASSERT_EQ(OB_SUCCESS, ret); + // test OB_SUCCESS: transfer t2 from ls2 to ls1 + old_transfer_seq = 0; + new_transfer_seq = 1; + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t2, + old_transfer_seq, + ls2, + new_transfer_seq, + ls1); + ASSERT_EQ(OB_SUCCESS, ret); + // test OB_ENTRY_NOT_EXIST: t2 is not in ls2 + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t2, + old_transfer_seq, + ls2, + new_transfer_seq, + ls1); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret); + // test OB_SUCCESS: transfer t2 from ls1 to ls2 + old_transfer_seq = new_transfer_seq; + new_transfer_seq = new_transfer_seq + 1; + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t2, + old_transfer_seq, + ls1, + new_transfer_seq, + ls2); + ASSERT_EQ(OB_SUCCESS, ret); + // test OB_SUCCESS: transfer t3 from ls3 to ls1 + old_transfer_seq = 0; + new_transfer_seq = 1; + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t3, + old_transfer_seq, + ls3, + new_transfer_seq, + ls1); + ASSERT_EQ(OB_SUCCESS, ret); + // test OB_ENTRY_NOT_EXIST: t3 is not in ls3 + ret = ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + t3, + old_transfer_seq, + ls3, + new_transfer_seq, + ls1); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret); + + // test final result in table __all_tablet_to_ls + SMART_VAR(ObISQLClient::ReadResult, result) { + ObSQLClientRetryWeak sql_client_retry_weak( + &get_curr_simple_server().get_observer().get_mysql_proxy(), + OB_SYS_TENANT_ID, + OB_ALL_TABLET_TO_LS_TID); + ObSqlString sql; + // t1 should be in ls3 and its transfer_seq should be 2 + ret = sql.append_fmt("SELECT ls_id, transfer_seq FROM %s WHERE tablet_id=1", + OB_ALL_TABLET_TO_LS_TNAME); + ASSERT_EQ(OB_SUCCESS, ret); + ret = sql_client_retry_weak.read(result, OB_SYS_TENANT_ID, sql.ptr()); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(false, OB_ISNULL(result.get_result())); + ret = result.get_result()->get_int("ls_id", ls_id); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(3, ls_id); + ret = result.get_result()->get_int("transfer_seq", transfer_seq); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(2, transfer_seq); + // t2 should be in ls2 and its transfer_seq should be 2 + ret = sql.append_fmt("SELECT ls_id, transfer_seq FROM %s WHERE tablet_id=2", + OB_ALL_TABLET_TO_LS_TNAME); + ASSERT_EQ(OB_SUCCESS, ret); + ret = sql_client_retry_weak.read(result, OB_SYS_TENANT_ID, sql.ptr()); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(false, OB_ISNULL(result.get_result())); + ls_id = ObLSID::INVALID_LS_ID; + transfer_seq = -1; + ret = result.get_result()->get_int("ls_id", ls_id); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(2, ls_id); + ret = result.get_result()->get_int("transfer_seq", transfer_seq); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(2, transfer_seq); + // t3 should be in ls1 and its transfer_seq should be 1 + ret = sql.append_fmt("SELECT ls_id, transfer_seq FROM %s WHERE tablet_id=3", + OB_ALL_TABLET_TO_LS_TNAME); + ASSERT_EQ(OB_SUCCESS, ret); + ret = sql_client_retry_weak.read(result, OB_SYS_TENANT_ID, sql.ptr()); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(false, OB_ISNULL(result.get_result())); + ls_id = ObLSID::INVALID_LS_ID; + transfer_seq = -1; + ret = result.get_result()->get_int("ls_id", ls_id); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(1, ls_id); + ret = result.get_result()->get_int("transfer_seq", transfer_seq); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(1, transfer_seq); + } +} + +class TestTabletToLSOperatorBatchGet : public unittest::ObSimpleClusterTestBase +{ +public: + TestTabletToLSOperatorBatchGet() : unittest::ObSimpleClusterTestBase("test_ls_status_operator_batch_get") {} +}; + +TEST_F(TestTabletToLSOperatorBatchGet, test_batch_get) +{ + int ret = OB_SUCCESS; + uint64_t tenant_id = 1002; + ObArray infos; + ObTabletToLSInfo info1(ObTabletID(200001), ObLSID(1002), 123456, 0); + ObTabletToLSInfo info2(ObTabletID(200002), ObLSID(1004), 654321, 1); + ASSERT_EQ(OB_SUCCESS, infos.push_back(info1)); + ASSERT_EQ(OB_SUCCESS, infos.push_back(info2)); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_observer().get_mysql_proxy(); + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::batch_update(sql_proxy, tenant_id, infos)); + + ObArray tablet_ids; + ObArray res_infos; + ObArray ls_ids; + ASSERT_EQ(OB_SUCCESS, tablet_ids.push_back(info1.get_tablet_id())); + ASSERT_EQ(OB_SUCCESS, tablet_ids.push_back(info2.get_tablet_id())); + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::batch_get(sql_proxy, tenant_id, tablet_ids, res_infos)); + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::batch_get_ls(sql_proxy, tenant_id, tablet_ids, ls_ids)); + ASSERT_TRUE(2 == res_infos.count()); + ASSERT_TRUE(res_infos.at(0) == info1); + ASSERT_TRUE(res_infos.at(1) == info2); + ASSERT_TRUE(2 == ls_ids.count()); + ASSERT_TRUE(ls_ids.at(0) == info1.get_ls_id()); + ASSERT_TRUE(ls_ids.at(1) == info2.get_ls_id()); + + // exist invalid tablet_ids + res_infos.reset(); + ls_ids.reset(); + ASSERT_EQ(OB_SUCCESS, tablet_ids.push_back(ObTabletID())); + ASSERT_EQ(OB_ITEM_NOT_MATCH, ObTabletToLSTableOperator::batch_get(sql_proxy, tenant_id, tablet_ids, res_infos)); + ASSERT_EQ(OB_ITEM_NOT_MATCH, ObTabletToLSTableOperator::batch_get_ls(sql_proxy, tenant_id, tablet_ids, ls_ids)); + + // exist duplicate tablet_ids + tablet_ids.reset(); + ls_ids.reset(); + res_infos.reset(); + ASSERT_EQ(OB_SUCCESS, tablet_ids.push_back(info1.get_tablet_id())); + ASSERT_EQ(OB_SUCCESS, tablet_ids.push_back(info1.get_tablet_id())); + ASSERT_EQ(OB_ITEM_NOT_MATCH, ObTabletToLSTableOperator::batch_get(sql_proxy, tenant_id, tablet_ids, res_infos)); + ASSERT_EQ(OB_ITEM_NOT_MATCH, ObTabletToLSTableOperator::batch_get_ls(sql_proxy, tenant_id, tablet_ids, ls_ids)); + + const int64_t MAX_BATCH_COUNT = 200; + ObArray input_infos; + tablet_ids.reset(); + res_infos.reset(); + ASSERT_EQ(OB_SUCCESS, input_infos.reserve(MAX_BATCH_COUNT + 1)); + ASSERT_EQ(OB_SUCCESS, tablet_ids.reserve(MAX_BATCH_COUNT + 1)); + ASSERT_EQ(OB_SUCCESS, res_infos.reserve(MAX_BATCH_COUNT + 1)); + for(int64_t i = 0; i < MAX_BATCH_COUNT - 1; ++i) { + ObTabletID tmp_tablet_id(20000 + i); + ASSERT_EQ(OB_SUCCESS, tablet_ids.push_back(tmp_tablet_id)); + ObTabletToLSInfo tmp_info(tmp_tablet_id, ObLSID(1002), 123456, 0); + ASSERT_EQ(OB_SUCCESS, input_infos.push_back(tmp_info)); + } + // MAX_BATCH_COUNT - 1 + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::batch_update(sql_proxy, tenant_id, input_infos)); + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::batch_get(sql_proxy, tenant_id, tablet_ids, res_infos)); + ASSERT_TRUE(MAX_BATCH_COUNT - 1 == res_infos.count()); + ARRAY_FOREACH(res_infos, idx) { + ASSERT_TRUE(res_infos.at(idx) == input_infos.at(idx)); + } + // MAX_BATCH_COUNT + { + ObTabletID tmp_tablet_id(20000 + MAX_BATCH_COUNT - 1); + ASSERT_EQ(OB_SUCCESS, tablet_ids.push_back(tmp_tablet_id)); + ObTabletToLSInfo tmp_info(tmp_tablet_id, ObLSID(1002), 123456, 0); + ASSERT_EQ(OB_SUCCESS, input_infos.push_back(tmp_info)); + } + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::batch_update(sql_proxy, tenant_id, input_infos)); + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::batch_get(sql_proxy, tenant_id, tablet_ids, res_infos)); + ASSERT_TRUE(MAX_BATCH_COUNT == res_infos.count()); + ARRAY_FOREACH(res_infos, idx) { + ASSERT_TRUE(res_infos.at(idx) == input_infos.at(idx)); + } + // MAX_BATCH_COUNT + 1 + { + ObTabletID tmp_tablet_id(20000 + MAX_BATCH_COUNT); + ASSERT_EQ(OB_SUCCESS, tablet_ids.push_back(tmp_tablet_id)); + ObTabletToLSInfo tmp_info(tmp_tablet_id, ObLSID(1002), 123456, 0); + ASSERT_EQ(OB_SUCCESS, input_infos.push_back(tmp_info)); + } + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::batch_update(sql_proxy, tenant_id, input_infos)); + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::batch_get(sql_proxy, tenant_id, tablet_ids, res_infos)); + ASSERT_TRUE(MAX_BATCH_COUNT + 1 == res_infos.count()); + ARRAY_FOREACH(res_infos, idx) { + ASSERT_TRUE(res_infos.at(idx) == input_infos.at(idx)); + } + + ObLSID ls_id; + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::get_ls_by_tablet(sql_proxy, tenant_id, tablet_ids.at(0), ls_id)); + ASSERT_TRUE(ls_id == input_infos.at(0).get_ls_id()); + ls_id.reset(); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTabletToLSTableOperator::get_ls_by_tablet(sql_proxy, tenant_id, ObTabletID(123456), ls_id)); + + // test batch_get_tablet_ls_cache + ObArray tablet_ls_caches; + ASSERT_EQ(OB_SUCCESS, ObTabletToLSTableOperator::batch_get_tablet_ls_cache(sql_proxy, tenant_id, tablet_ids, tablet_ls_caches)); + ASSERT_TRUE(tablet_ids.count() == tablet_ls_caches.count()); + ARRAY_FOREACH(tablet_ls_caches, idx) { + ASSERT_TRUE(common::has_exist_in_array(tablet_ids, tablet_ls_caches.at(idx).get_tablet_id())); + } + +} + +} // share +} // oceanbase + +int main(int argc, char **argv) +{ + init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/test_replay_from_middle.cpp b/mittest/simple_server/test_replay_from_middle.cpp index f2f73ed8e..75b9fb06b 100644 --- a/mittest/simple_server/test_replay_from_middle.cpp +++ b/mittest/simple_server/test_replay_from_middle.cpp @@ -699,7 +699,7 @@ int ObLSService::enable_replay() ObInnerLSStatus ls_status; common::ObSharedGuard ls_iter; ObLS *ls = nullptr; - share::ObLSRestoreStatus restore_status; + bool can_replay = true; if (OB_FAIL(get_ls_iter(ls_iter, ObLSGetMod::TXSTORAGE_MOD))) { LOG_WARN("failed to get ls iter", K(ret)); } else { @@ -711,12 +711,10 @@ int ObLSService::enable_replay() } else if (nullptr == ls) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("ls is null", K(ret)); - } else if (ls->is_need_gc()) { - // this ls will be gc later, should not enable replay - } else if (OB_FAIL(ls->get_restore_status(restore_status))) { - LOG_WARN("fail to get ls restore status", K(ret)); - } else if (!restore_status.can_replay_log()) { - // while downtime, if ls's restore status is in [restore_start, wait_restore_tablet_meta], clog can't replay + } else if (OB_FAIL(ls->check_can_replay_clog(can_replay))) { + LOG_WARN("failed to check ls can replay clog", K(ret), KPC(ls)); + } else if (!can_replay) { + // ls can not enable replay } else if (OB_FAIL(ls->enable_replay())) { LOG_ERROR("fail to enable replay", K(ret)); } diff --git a/mittest/simple_server/test_schema_service_sql_impl.cpp b/mittest/simple_server/test_schema_service_sql_impl.cpp new file mode 100644 index 000000000..d1d5f94ab --- /dev/null +++ b/mittest/simple_server/test_schema_service_sql_impl.cpp @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2023 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "share/schema/ob_schema_service_sql_impl.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace share +{ +using namespace share::schema; +using namespace common; + +static const int64_t TOTAL_NUM = 110; +static uint64_t g_tenant_id; +static ObSEArray g_table_ids; + +class TestSchemaServiceSqlImpl : public unittest::ObSimpleClusterTestBase +{ +public: + TestSchemaServiceSqlImpl() : unittest::ObSimpleClusterTestBase("test_schema_service_sql_impl") {} + int batch_create_table(ObMySQLProxy &sql_proxy, const int64_t TOTAL_NUM, ObIArray &table_ids); +}; + +int TestSchemaServiceSqlImpl::batch_create_table( + ObMySQLProxy &sql_proxy, + const int64_t TOTAL_NUM, + ObIArray &table_ids) +{ + int ret = OB_SUCCESS; + table_ids.reset(); + ObSqlString sql; + // batch create table + int64_t affected_rows = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < TOTAL_NUM; ++i) { + sql.reset(); + if (OB_FAIL(sql.assign_fmt("create table t%ld(c1 int)", i))) { + } else if (OB_FAIL(sql_proxy.write(sql.ptr(), affected_rows))) { + } + } + // batch get table_id + sql.reset(); + if (OB_FAIL(sql.assign_fmt("select table_id from oceanbase.__all_table where table_name in ("))) { + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < TOTAL_NUM; ++i) { + if (OB_FAIL(sql.append_fmt("%s't%ld'", 0 == i ? "" : ",", i))) {} + } + if (FAILEDx(sql.append_fmt(") order by table_id"))) {}; + } + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_FAIL(table_ids.reserve(TOTAL_NUM))) { + } else if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + while(OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "table_id", table_id, uint64_t); + if (OB_FAIL(table_ids.push_back(table_id))) {} + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + } + } + return ret; +} + +TEST_F(TestSchemaServiceSqlImpl, prepare_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + ASSERT_EQ(OB_SUCCESS, batch_create_table(sql_proxy, TOTAL_NUM, g_table_ids)); +} + +TEST_F(TestSchemaServiceSqlImpl, test_get_table_latest_schema_versions) +{ + int ret = OB_SUCCESS; + ASSERT_EQ(TOTAL_NUM, g_table_ids.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ASSERT_TRUE(OB_NOT_NULL(GCTX.schema_service_)); + ObSchemaService *schema_service = GCTX.schema_service_->get_schema_service(); + ASSERT_TRUE(OB_NOT_NULL(schema_service)); + + // 1.test batch get + ObSEArray schema_versions; + const int64_t small_num = ObSchemaServiceSQLImpl::MAX_IN_QUERY_PER_TIME - 1; + const int64_t batch_num = ObSchemaServiceSQLImpl::MAX_IN_QUERY_PER_TIME; + const int64_t big_num = TOTAL_NUM; + ObSEArray small_table_ids; + ObSEArray batch_table_ids; + for (int64_t i = 0; i < small_num; ++i) { + ASSERT_EQ(OB_SUCCESS, small_table_ids.push_back(g_table_ids.at(i))); + } + for (int64_t i = 0; i < batch_num; ++i) { + ASSERT_EQ(OB_SUCCESS, batch_table_ids.push_back(g_table_ids.at(i))); + } + ASSERT_EQ(OB_SUCCESS, schema_service->get_table_latest_schema_versions(inner_sql_proxy, g_tenant_id, small_table_ids, schema_versions)); + ASSERT_TRUE(schema_versions.count() == small_num); + schema_versions.reset(); + ASSERT_EQ(OB_SUCCESS, schema_service->get_table_latest_schema_versions(inner_sql_proxy, g_tenant_id, batch_table_ids, schema_versions)); + ASSERT_TRUE(schema_versions.count() == batch_num); + schema_versions.reset(); + ASSERT_EQ(OB_SUCCESS, schema_service->get_table_latest_schema_versions(inner_sql_proxy, g_tenant_id, g_table_ids, schema_versions)); + ASSERT_TRUE(schema_versions.count() == TOTAL_NUM); + + // 2.test table latest schema version + int64_t t0_old_schema_version = schema_versions.at(0).get_schema_version(); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + ObSqlString sql; + int64_t affected_rows = 0; + // 2.1 increase table schema version + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("alter table t0 add column c2 int")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + ObArray t0_table_id; + ObArray t0_latest_schema_version; + ASSERT_EQ(OB_SUCCESS, t0_table_id.push_back(g_table_ids.at(0))); + ASSERT_EQ(OB_SUCCESS, schema_service->get_table_latest_schema_versions(inner_sql_proxy, g_tenant_id, t0_table_id, t0_latest_schema_version)); + ASSERT_TRUE(t0_latest_schema_version.count() == 1); + ASSERT_TRUE(t0_latest_schema_version.at(0).get_schema_version() > t0_old_schema_version); + ASSERT_TRUE(!t0_latest_schema_version.at(0).is_deleted()); + t0_old_schema_version = t0_latest_schema_version.at(0).get_schema_version(); + // 2.2 test is_deleted + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("drop table t0")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + t0_latest_schema_version.reset(); + ASSERT_EQ(OB_SUCCESS, schema_service->get_table_latest_schema_versions(inner_sql_proxy, g_tenant_id, t0_table_id, t0_latest_schema_version)); + ASSERT_TRUE(t0_latest_schema_version.count() == 1); + ASSERT_TRUE(t0_latest_schema_version.at(0).get_schema_version() > t0_old_schema_version); + ASSERT_TRUE(t0_latest_schema_version.at(0).is_deleted()); + // 2.3 schema version of other table has no change + ObSEArray latest_schema_versions; + ASSERT_EQ(OB_SUCCESS, schema_service->get_table_latest_schema_versions(inner_sql_proxy, g_tenant_id, g_table_ids, latest_schema_versions)); + ASSERT_TRUE(latest_schema_versions.count() == TOTAL_NUM); + for (int64_t i = 0; i < TOTAL_NUM; ++i) { + if (latest_schema_versions.at(i).get_table_id() != t0_table_id.at(0)) { + ASSERT_TRUE(latest_schema_versions.at(i).get_table_id() == schema_versions.at(i).get_table_id()); + ASSERT_TRUE(latest_schema_versions.at(i).get_schema_version() == schema_versions.at(i).get_schema_version()); + ASSERT_TRUE(latest_schema_versions.at(i).is_deleted() == schema_versions.at(i).is_deleted()); + } + } + + // 3.test error + schema_versions.reset(); + ObArray empty_table_ids; + ObArray invalid_table_ids; + ObArray dup_table_ids; + ASSERT_EQ(OB_SUCCESS, invalid_table_ids.push_back(OB_INVALID_ID)); + ASSERT_EQ(OB_SUCCESS, dup_table_ids.push_back(g_table_ids.at(0))); + ASSERT_EQ(OB_SUCCESS, dup_table_ids.push_back(g_table_ids.at(0))); + + ASSERT_EQ(OB_INVALID_ARGUMENT, schema_service->get_table_latest_schema_versions(inner_sql_proxy, 123, t0_table_id, schema_versions)); + ASSERT_EQ(OB_INVALID_ARGUMENT, schema_service->get_table_latest_schema_versions(inner_sql_proxy, g_tenant_id, empty_table_ids, schema_versions)); + ASSERT_EQ(OB_INVALID_ARGUMENT, schema_service->get_table_latest_schema_versions(inner_sql_proxy, g_tenant_id, invalid_table_ids, schema_versions)); + schema_versions.reset(); + ASSERT_EQ(OB_SUCCESS, schema_service->get_table_latest_schema_versions(inner_sql_proxy, g_tenant_id, dup_table_ids, schema_versions)); + ASSERT_TRUE(schema_versions.count() == 1); + ASSERT_TRUE(dup_table_ids.at(0) == schema_versions.at(0).get_table_id()); +} + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/test_standby_balance_ls_group.cpp b/mittest/simple_server/test_standby_balance_ls_group.cpp new file mode 100644 index 000000000..6fd7f7959 --- /dev/null +++ b/mittest/simple_server/test_standby_balance_ls_group.cpp @@ -0,0 +1,199 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE + +#include +#include +#define protected public +#define private public + +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log.h" +#include "share/ob_ls_id.h" +#include "share/unit/ob_unit_info.h" +#include "share/ls/ob_ls_status_operator.h" +#include "rootserver/ob_primary_ls_service.h" + + + +namespace oceanbase +{ +using namespace unittest; +namespace share +{ +using ::testing::_; +using ::testing::Invoke; +using ::testing::Return; + +using namespace schema; +using namespace rootserver; +using namespace common; +class TestStandbyBalance : public unittest::ObSimpleClusterTestBase +{ +public: + TestStandbyBalance() : unittest::ObSimpleClusterTestBase("test_balance_operator") {} +protected: + + uint64_t tenant_id_; +}; + +TEST_F(TestStandbyBalance, BalanceLSGroup) +{ + int ret = OB_SUCCESS; + tenant_id_ = 1; + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObTenantSchema *tenant_schema = NULL; + share::schema::ObTenantSchema tenant_schema1; + if (OB_FAIL(get_curr_observer().get_schema_service().get_tenant_schema_guard( + OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(OB_SYS_TENANT_ID, tenant_schema))) { + LOG_WARN("failed to get tenant ids", KR(ret), K(tenant_id_)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant not exist", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(tenant_schema1.assign(*tenant_schema))) { + LOG_WARN("failed to assign tenant schema", KR(ret)); + } else { + tenant_schema1.set_tenant_id(tenant_id_); + } + ASSERT_EQ(OB_SUCCESS, ret); + ObZone z1("z1"); + int64_t affected_row = 0; + ObSqlString sql; + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2("sys", "oceanbase")); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + //2个unit group,四个日志流组 + uint64_t u1 = 1001; + uint64_t u2 = 1002; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into __all_unit(unit_id, unit_group_id, resource_pool_id, zone, svr_ip, svr_port, migrate_from_svr_ip, migrate_from_svr_port, status) values(%lu, %lu, 1, 'z1', '127.0.0.1', 2882, ' ', 0, 'ACTIVE')", u1, u1)); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_row)); + ASSERT_EQ(1, affected_row); + + uint64_t lg1 = 1001, lg2 = 1002, lg3 = 1003, lg4 = 1004; + int64_t ls1 = 1001, ls2 = 1002, ls3 = 1003, ls4 = 1004; + //4个日志流组都在一个ug上面 + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into __all_ls_status(tenant_id, ls_id, status, ls_group_id , unit_group_id, primary_zone) values(%ld, %lu, 'NORMAL', %lu, %lu, '%s')", tenant_id_, ls1, lg1, u1, z1.ptr())); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_row)); + ASSERT_EQ(1, affected_row); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into __all_ls_status(tenant_id, ls_id, status, ls_group_id , unit_group_id, primary_zone) values(%ld, %lu, 'NORMAL', %lu, %lu, '%s')", tenant_id_, ls2, lg2, u1, z1.ptr())); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_row)); + ASSERT_EQ(1, affected_row); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into __all_ls_status(tenant_id, ls_id, status, ls_group_id , unit_group_id, primary_zone) values(%ld, %lu, 'NORMAL', %lu, %lu, '%s')", tenant_id_, ls3, lg3, u1, z1.ptr())); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_row)); + ASSERT_EQ(1, affected_row); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into __all_ls_status(tenant_id, ls_id, status, ls_group_id , unit_group_id, primary_zone) values(%ld, %lu, 'NORMAL', %lu, %lu, '%s')", tenant_id_, ls4, lg4, u1, z1.ptr())); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(OB_SYS_TENANT_ID, sql.ptr(), affected_row)); + ASSERT_EQ(1, affected_row); + ObTenantLSInfo tenant_stat(get_curr_observer().get_gctx().sql_proxy_, &tenant_schema1, tenant_id_); + ASSERT_EQ(OB_SUCCESS, ObLSServiceHelper::balance_ls_group(tenant_stat)); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select ls_id, ls_group_id, unit_group_id from __all_ls_status where ls_id != 1 order by ls_id")); + int64_t ls_id = 0; + uint64_t ls_group_id = 0; + uint64_t unit_group_id = 0; + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + ASSERT_EQ(OB_SUCCESS, sql_proxy.read(res, sql.ptr())); + sqlclient::ObMySQLResult *result = res.get_result(); + ASSERT_NE(nullptr, result); + //1 + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("ls_id", ls_id)); + ASSERT_EQ(ls1, ls_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("ls_group_id", ls_group_id)); + ASSERT_EQ(lg1, ls_group_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("unit_group_id", unit_group_id)); + ASSERT_EQ(u1, unit_group_id); + //2 + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("ls_id", ls_id)); + ASSERT_EQ(ls2, ls_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("ls_group_id", ls_group_id)); + ASSERT_EQ(lg2, ls_group_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("unit_group_id", unit_group_id)); + ASSERT_EQ(u1, unit_group_id); + //3 + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("ls_id", ls_id)); + ASSERT_EQ(ls3, ls_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("ls_group_id", ls_group_id)); + ASSERT_EQ(lg3, ls_group_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("unit_group_id", unit_group_id)); + ASSERT_EQ(1, unit_group_id); + //4 + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("ls_id", ls_id)); + ASSERT_EQ(ls4, ls_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("ls_group_id", ls_group_id)); + ASSERT_EQ(lg4, ls_group_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("unit_group_id", unit_group_id)); + ASSERT_EQ(1, unit_group_id); + } + + //case 2: 2, 2 -> 2, 2, 1 + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("insert into __all_unit(unit_id, unit_group_id, resource_pool_id, zone, svr_ip, svr_port, migrate_from_svr_ip, migrate_from_svr_port, status) values(%lu, %lu, 1, 'z1', '127.0.0.1', 2882, ' ', 0, 'ACTIVE')", u2, u2)); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_row)); + ASSERT_EQ(1, affected_row); + ASSERT_EQ(OB_SUCCESS, ObLSServiceHelper::balance_ls_group(tenant_stat)); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select ls_id, ls_group_id, unit_group_id from __all_ls_status where ls_id != 1 order by ls_id")); + SMART_VAR(ObMySQLProxy::MySQLResult, res1) { + ASSERT_EQ(OB_SUCCESS, sql_proxy.read(res1, sql.ptr())); + sqlclient::ObMySQLResult *result = res1.get_result(); + ASSERT_NE(nullptr, result); + //1 + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("ls_id", ls_id)); + ASSERT_EQ(ls1, ls_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("ls_group_id", ls_group_id)); + ASSERT_EQ(lg1, ls_group_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("unit_group_id", unit_group_id)); + ASSERT_EQ(u1, unit_group_id); + //2 + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("ls_id", ls_id)); + ASSERT_EQ(ls2, ls_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("ls_group_id", ls_group_id)); + ASSERT_EQ(lg2, ls_group_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("unit_group_id", unit_group_id)); + ASSERT_EQ(u1, unit_group_id); + //3 + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("ls_id", ls_id)); + ASSERT_EQ(ls3, ls_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("ls_group_id", ls_group_id)); + ASSERT_EQ(lg3, ls_group_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("unit_group_id", unit_group_id)); + ASSERT_EQ(1, unit_group_id); + //4 + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("ls_id", ls_id)); + ASSERT_EQ(ls4, ls_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("ls_group_id", ls_group_id)); + ASSERT_EQ(lg4, ls_group_id); + ASSERT_EQ(OB_SUCCESS, result->get_uint("unit_group_id", unit_group_id)); + ASSERT_EQ(u2, unit_group_id); + } + + +} + +} // namespace share +} // namespace oceanbase + +int main(int argc, char **argv) +{ + init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/test_tenant_balance_operator.cpp b/mittest/simple_server/test_tenant_balance_operator.cpp new file mode 100644 index 000000000..68aaacdd8 --- /dev/null +++ b/mittest/simple_server/test_tenant_balance_operator.cpp @@ -0,0 +1,609 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE + +#include +#include +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log.h" +#define private public +#include "share/balance/ob_balance_job_table_operator.h" +#include "share/balance/ob_balance_task_table_operator.h" +#include "share/balance/ob_balance_task_helper_operator.h" +#include "rootserver/ob_ls_balance_helper.h"//ObLSBalanceTaskHelper +#include "share/transfer/ob_transfer_info.h" +#include "share/ob_ls_id.h" +#include "share/unit/ob_unit_info.h" +#include "share/ls/ob_ls_status_operator.h" +#include "share/ls/ob_ls_i_life_manager.h" + + + +namespace oceanbase +{ +using namespace unittest; +namespace share +{ +using ::testing::_; +using ::testing::Invoke; +using ::testing::Return; + +using namespace schema; +using namespace rootserver; +using namespace common; +class TestBalanceOperator : public unittest::ObSimpleClusterTestBase +{ +public: + TestBalanceOperator() : unittest::ObSimpleClusterTestBase("test_balance_operator") {} +protected: + + uint64_t tenant_id_; +}; + +TEST_F(TestBalanceOperator, BalanceJob) +{ + int ret = OB_SUCCESS; + tenant_id_ = OB_SYS_TENANT_ID; + //ObBalanceJob INIT + ObBalanceJob job; + ObBalanceJobID job_id(1); + int64_t job_start_time = 1; + int64_t job_finish_time = 1; + ObBalanceJobType job_type; + ObBalanceJobStatus job_status; + int64_t primary_zone_num = 0; + int64_t unit_group_num = 0; + ObString comment; + ObString balance_strategy(share::LS_BALANCE_BY_EXPAND); + + ASSERT_EQ(OB_INVALID_ARGUMENT, job.init(0, job_id, job_type, job_status, primary_zone_num, unit_group_num, comment, balance_strategy)); + job_type = ObBalanceJobType(ObString("LS_BALANCE")); + ASSERT_EQ(OB_INVALID_ARGUMENT, job.init(tenant_id_, job_id, job_type, job_status, primary_zone_num, unit_group_num, comment, balance_strategy)); + job_status = ObBalanceJobStatus(ObString("DOING")); + ASSERT_EQ(OB_INVALID_ARGUMENT, job.init(tenant_id_, job_id, job_type, job_status, primary_zone_num, unit_group_num, comment, balance_strategy)); + primary_zone_num = 1; + unit_group_num = 1; + ASSERT_EQ(OB_SUCCESS, job.init(tenant_id_, job_id, job_type, job_status, primary_zone_num, unit_group_num, comment, balance_strategy)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2("sys", "oceanbase")); + LOG_INFO("[MITTEST]balance_job", K(job)); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + //insert + ASSERT_EQ(OB_SUCCESS, ObBalanceJobTableOperator::insert_new_job(job, sql_proxy)); + ObBalanceJob new_job; + //select + ASSERT_EQ(OB_SUCCESS, ObBalanceJobTableOperator::get_balance_job(OB_SYS_TENANT_ID, false, sql_proxy, new_job, job_start_time, job_finish_time)); + LOG_INFO("[MITTEST]balance_job", K(new_job)); + ASSERT_EQ(new_job.get_tenant_id(), job.get_tenant_id()); + ASSERT_EQ(new_job.get_job_id(), job.get_job_id()); + ASSERT_EQ(new_job.get_primary_zone_num(), job.get_primary_zone_num()); + ASSERT_EQ(new_job.get_unit_group_num(), job.get_unit_group_num()); + ASSERT_EQ(new_job.get_job_type(), job_type); + ASSERT_EQ(new_job.get_job_status(), job_status); + + ASSERT_EQ(OB_OP_NOT_ALLOW, ObBalanceJobTableOperator::clean_job(OB_SYS_TENANT_ID, job_id, sql_proxy)); + //update + ObBalanceJobStatus new_job_status(2); + ASSERT_EQ(OB_SUCCESS, ObBalanceJobTableOperator::update_job_status(OB_SYS_TENANT_ID, job_id, job_status, new_job_status, false, ObString(), sql_proxy)); + ASSERT_EQ(OB_SUCCESS, ObBalanceJobTableOperator::get_balance_job(OB_SYS_TENANT_ID, false, sql_proxy, new_job, job_start_time, job_finish_time)); + ASSERT_EQ(new_job.get_job_status(), new_job_status); + //clean + ASSERT_EQ(OB_SUCCESS, ObBalanceJobTableOperator::clean_job(OB_SYS_TENANT_ID, job_id, sql_proxy)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObBalanceJobTableOperator::get_balance_job(OB_SYS_TENANT_ID, false, sql_proxy, new_job, job_start_time, job_finish_time)); + ObSqlString sql; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select * from __all_balance_job_history")); + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + int64_t start_time = 0; + int64_t finish_time = 0; + ASSERT_EQ(OB_SUCCESS, sql_proxy.read(res, sql.ptr())); + sqlclient::ObMySQLResult *result = res.get_result(); + ASSERT_NE(nullptr, result); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_time("create_time", start_time)); + ASSERT_EQ(OB_SUCCESS, result->get_time("finish_time", finish_time)); + LOG_INFO("[MITTEST]job status", K(start_time), K(finish_time)); + } +} + +TEST_F(TestBalanceOperator, BalanceTask) +{ + int ret = OB_SUCCESS; + //ObBalanceTask INIT + ObBalanceTask task; + uint64_t tenant_id = OB_SYS_TENANT_ID; + ObBalanceJobID job_id; + ObBalanceTaskID task_id; + int64_t ls_group_id = 0; + int64_t start_time = 0; + int64_t finish_time = 0; + int64_t src_ls_id = 0; + int64_t dest_ls_id = 0; + //TODO + ObTransferTaskID transfer_task_id; + ObString task_type, task_status; + ObString part_list_str, finished_part_list_str; + ObString parent_list_str, child_list_str; + ObTransferPartList part_list, finished_part_list; + ObBalanceTaskIDList parent_list, child_list; + ObString comment; + ASSERT_EQ(OB_INVALID_ARGUMENT, task.init( + tenant_id, job_id, task_id, + ObBalanceTaskType(task_type), + ObBalanceTaskStatus(task_status), ls_group_id, + ObLSID(src_ls_id), ObLSID(dest_ls_id), + transfer_task_id, part_list, finished_part_list, + parent_list, child_list, comment)); + job_id = 1; + task_id = 2; + ASSERT_EQ(OB_INVALID_ARGUMENT, task.init( + tenant_id, job_id, task_id, + ObBalanceTaskType(task_type), + ObBalanceTaskStatus(task_status), ls_group_id, + ObLSID(src_ls_id), ObLSID(dest_ls_id), + transfer_task_id, part_list, finished_part_list, + parent_list, child_list, comment)); + start_time = 1; + src_ls_id = 1; + dest_ls_id = 1; + task_type = ObString("LS_SPLIT"); + task_status = ObString("CREATE_LS"); + ObTransferPartInfo part_info; + ObObjectID obj_id = 1; + ASSERT_EQ(OB_SUCCESS, part_info.init(obj_id, obj_id)); + ObBalanceTaskID parent_task_id(1); + ASSERT_EQ(OB_SUCCESS, parent_list.push_back(parent_task_id)); + ASSERT_EQ(OB_SUCCESS, part_list.push_back(part_info)); + ASSERT_EQ(OB_SUCCESS, task.init( + tenant_id, job_id, task_id, + ObBalanceTaskType(task_type), + ObBalanceTaskStatus(task_status), ls_group_id, + ObLSID(src_ls_id), ObLSID(dest_ls_id), + transfer_task_id, part_list, finished_part_list, + parent_list, child_list, comment)); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + //insert + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::insert_new_task(task, sql_proxy)); + + //select + ObBalanceTask new_task; + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::get_balance_task(OB_SYS_TENANT_ID, task_id , false, sql_proxy, new_task, start_time, finish_time)); + ASSERT_EQ(new_task.get_parent_task_list().at(0), ObBalanceTaskID(1)); + LOG_INFO("[MITTEST]balance_task", K(new_task)); + //update balance task + ObBalanceTaskStatus transfer_status = ObBalanceTaskStatus::BALANCE_TASK_STATUS_TRANSFER; + common::ObMySQLTransaction trans2; + ASSERT_EQ(OB_SUCCESS, trans2.start(&sql_proxy, tenant_id)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::update_task_status(new_task, transfer_status, trans2)); + ASSERT_EQ(OB_SUCCESS, trans2.end(true)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::get_balance_task(OB_SYS_TENANT_ID, task_id , false, sql_proxy, new_task, start_time, finish_time)); + LOG_INFO("[MITTEST]balance_task", K(new_task)); + //start transfer task + transfer_task_id = 1; + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::start_transfer_task(OB_SYS_TENANT_ID, task_id, transfer_task_id, sql_proxy)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::get_balance_task(OB_SYS_TENANT_ID, task_id , false, sql_proxy, new_task, start_time, finish_time)); + LOG_INFO("[MITTEST]balance_task", K(new_task)); + //finish transfer task + finished_part_list.reset(); + ObTransferPartList to_do_part_list; + bool all_part_transferred = false; + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::finish_transfer_task(new_task, transfer_task_id, finished_part_list, sql_proxy, to_do_part_list, all_part_transferred)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::get_balance_task(OB_SYS_TENANT_ID, task_id , false, sql_proxy, new_task, start_time, finish_time)); + LOG_INFO("[MITTEST]balance_task", K(new_task)); + //remove parent task + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::remove_parent_task(OB_SYS_TENANT_ID, task_id, parent_task_id, sql_proxy)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::get_balance_task(OB_SYS_TENANT_ID, task_id , false, sql_proxy, new_task, start_time, finish_time)); + ObBalanceTaskArray task_array; + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::load_can_execute_task(OB_SYS_TENANT_ID, task_array, sql_proxy)); + LOG_INFO("[MITTEST]balance_task", K(new_task), K(task_array)); + + //clean task + //update task status into completed before clean task + ObBalanceTaskStatus completed_status = ObBalanceTaskStatus::BALANCE_TASK_STATUS_COMPLETED; + common::ObMySQLTransaction trans1; + ASSERT_EQ(OB_SUCCESS, trans1.start(&sql_proxy, tenant_id)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::update_task_status(new_task, completed_status, trans1)); + ASSERT_EQ(OB_SUCCESS, trans1.end(true)); + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&sql_proxy, tenant_id)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::clean_task(OB_SYS_TENANT_ID, task_id, trans)); + ASSERT_EQ(OB_SUCCESS, trans.end(true)); + + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObBalanceTaskTableOperator::get_balance_task(OB_SYS_TENANT_ID, task_id , false, sql_proxy, new_task, start_time, finish_time)); + ObSqlString sql; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select * from __all_balance_task_history")); + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + int64_t start_time = 0; + int64_t finish_time = 0; + ASSERT_EQ(OB_SUCCESS, sql_proxy.read(res, sql.ptr())); + sqlclient::ObMySQLResult *result = res.get_result(); + ASSERT_NE(nullptr, result); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_time("create_time", start_time)); + ASSERT_EQ(OB_SUCCESS, result->get_time("finish_time", finish_time)); + LOG_INFO("[MITTEST]balance_task", K(start_time), K(finish_time)); + } +} + +TEST_F(TestBalanceOperator, balance_execute) +{ + int ret = OB_SUCCESS; + ASSERT_EQ(OB_SUCCESS, create_tenant()); + common::ObMySQLProxy *sql_proxy = get_curr_observer().get_gctx().sql_proxy_; + int64_t primary_zone_num = 1; + uint64_t tenant_id = 1002; + ObSimpleUnitGroup unit_group1(1001, share::ObUnit::UNIT_STATUS_ACTIVE); + ObSimpleUnitGroup unit_group2(1002, share::ObUnit::UNIT_STATUS_ACTIVE); + ObSimpleUnitGroup unit_group3(1003, share::ObUnit::UNIT_STATUS_ACTIVE); + ObSimpleUnitGroup unit_group4(1004, share::ObUnit::UNIT_STATUS_ACTIVE); + ObArray unit_group; + ASSERT_EQ(OB_SUCCESS, unit_group.push_back(unit_group1)); + ObLSID ls_id(1001); + ObLSFlag ls_flag; + ObLSStatusInfo info; + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ls_id, 1, share::OB_LS_NORMAL, 1001, "z1", ls_flag)); + ObLSStatusInfoArray ls_array; + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + MTL_SWITCH(tenant_id) { + { + ObLSBalanceTaskHelper ls_balance; + //case 1. init + ASSERT_EQ(OB_SUCCESS, ls_balance.init(tenant_id, ls_array, unit_group, primary_zone_num, sql_proxy)); + LOG_INFO("testtest1", K(ls_balance.unit_group_balance_array_)); + //case 2. no need balance + + bool need_balance = false; + ASSERT_EQ(OB_SUCCESS, ls_balance.check_need_ls_balance(need_balance)); + ASSERT_EQ(false, need_balance); + ASSERT_EQ(OB_ERR_UNEXPECTED, ls_balance.generate_ls_balance_task()); + } + + //case 3 1->2; + primary_zone_num = 2; + MTL_SWITCH(tenant_id) { + ObLSBalanceTaskHelper ls_balance; + ASSERT_EQ(OB_SUCCESS, ls_balance.init(tenant_id,ls_array, unit_group, primary_zone_num, sql_proxy)); + LOG_INFO("testtest3", K(ls_balance.unit_group_balance_array_)); + bool need_balance = false; + ASSERT_EQ(OB_SUCCESS, ls_balance.check_need_ls_balance(need_balance)); + ASSERT_EQ(true, need_balance); + ASSERT_EQ(OB_SUCCESS, ls_balance.generate_ls_balance_task()); + ASSERT_EQ(primary_zone_num, ls_balance.job_.primary_zone_num_); + ASSERT_EQ(ObBalanceJobType(ObBalanceJobType::BALANCE_JOB_LS), ls_balance.job_.job_type_); + ASSERT_EQ(ObBalanceJobStatus(ObBalanceJobStatus::BALANCE_JOB_STATUS_DOING), ls_balance.job_.job_status_); + ASSERT_EQ(1, ls_balance.task_array_.count()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_SPLIT), ls_balance.task_array_[0].get_task_type()); + } + + //case 4 1-3 + primary_zone_num = 3; + MTL_SWITCH(tenant_id) { + ObLSBalanceTaskHelper ls_balance; + ASSERT_EQ(OB_SUCCESS, ls_balance.init(tenant_id,ls_array, unit_group, primary_zone_num, sql_proxy)); + LOG_INFO("testtest4", K(ls_balance.unit_group_balance_array_)); + bool need_balance = false; + ASSERT_EQ(OB_SUCCESS, ls_balance.check_need_ls_balance(need_balance)); + ASSERT_EQ(true, need_balance); + ASSERT_EQ(OB_SUCCESS, ls_balance.generate_ls_balance_task()); + ASSERT_EQ(primary_zone_num, ls_balance.job_.primary_zone_num_); + ASSERT_EQ(ObBalanceJobType(ObBalanceJobType::BALANCE_JOB_LS), ls_balance.job_.job_type_); + ASSERT_EQ(ObBalanceJobStatus(ObBalanceJobStatus::BALANCE_JOB_STATUS_DOING), ls_balance.job_.job_status_); + ASSERT_EQ(2, ls_balance.task_array_.count()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_SPLIT), ls_balance.task_array_[0].get_task_type()); + } + + + //case5 2-3 + MTL_SWITCH(tenant_id) { + ObLSID ls_id2(1002); + ObLSStatusInfo info2; + ObLSBalanceTaskHelper ls_balance; + ASSERT_EQ(OB_SUCCESS, info2.init(tenant_id, ls_id2, 1, share::OB_LS_NORMAL, 1001, "z2", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info2)); + ASSERT_EQ(OB_SUCCESS, ls_balance.init(tenant_id,ls_array, unit_group, primary_zone_num, sql_proxy)); + LOG_INFO("testtest5", K(ls_balance.unit_group_balance_array_)); + bool need_balance = false; + ASSERT_EQ(OB_SUCCESS, ls_balance.check_need_ls_balance(need_balance)); + ASSERT_EQ(true, need_balance); + ASSERT_EQ(OB_SUCCESS, ls_balance.generate_ls_balance_task()); + ASSERT_EQ(primary_zone_num, ls_balance.job_.primary_zone_num_); + ASSERT_EQ(ObBalanceJobType(ObBalanceJobType::BALANCE_JOB_LS), ls_balance.job_.job_type_); + ASSERT_EQ(ObBalanceJobStatus(ObBalanceJobStatus::BALANCE_JOB_STATUS_DOING), ls_balance.job_.job_status_); + ASSERT_EQ(3, ls_balance.task_array_.count()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_SPLIT), ls_balance.task_array_[0].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_MERGE), ls_balance.task_array_[2].get_task_type()); + //ASSERT_EQ(2, ls_balance.task_array_[2].parent_list_.count()); + } + + + //case 6 ls group not in unit group + MTL_SWITCH(tenant_id) { + ObLSID ls_id3(1003); + ObLSStatusInfo info3; + ObLSBalanceTaskHelper ls_balance; + ASSERT_EQ(OB_SUCCESS, info3.init(tenant_id, ls_id3, 1, share::OB_LS_NORMAL, 1002, "z2", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info3)); + ASSERT_EQ(OB_SUCCESS, ls_balance.init(tenant_id,ls_array, unit_group, primary_zone_num, sql_proxy)); + LOG_INFO("testtest6", K(ls_balance.unit_group_balance_array_)); + bool need_balance = false; + ASSERT_EQ(OB_SUCCESS, ls_balance.check_need_ls_balance(need_balance)); + ASSERT_EQ(true, need_balance); + ASSERT_EQ(OB_SUCCESS, ls_balance.generate_ls_balance_task()); + LOG_INFO("testtest6", K(ls_balance.get_balance_job()), K(ls_balance.get_balance_tasks())); + ASSERT_EQ(1, ls_balance.get_balance_tasks().count()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_ALTER), ls_balance.task_array_[0].get_task_type()); + + } + } + + //case7 8->6 + MTL_SWITCH(tenant_id) { + ASSERT_EQ(OB_SUCCESS, unit_group.push_back(unit_group2)); + ls_array.reset(); + ObLSBalanceTaskHelper ls_balance; + for (int64_t i = 1001; i < 1009; ++i) { + ObLSID ls_id(i); + ObLSStatusInfo info; + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ls_id, 1, share::OB_LS_NORMAL, 1001, "z2", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + i++; + ObLSID ls_id1(i); + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ls_id1, 2, share::OB_LS_NORMAL, 1002, "z2", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + } + ASSERT_EQ(OB_SUCCESS, ls_balance.init(tenant_id,ls_array, unit_group, primary_zone_num, sql_proxy)); + LOG_INFO("testtest7", K(ls_balance.unit_group_balance_array_)); + bool need_balance = false; + ASSERT_EQ(OB_SUCCESS, ls_balance.check_need_ls_balance(need_balance)); + ASSERT_EQ(true, need_balance); + ASSERT_EQ(OB_SUCCESS, ls_balance.generate_ls_balance_task()); + LOG_INFO("testtest7", K(ls_balance.get_balance_job()), K(ls_balance.get_balance_tasks())); + ASSERT_EQ(6, ls_balance.get_balance_tasks().count()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_TRANSFER), ls_balance.task_array_[0].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_TRANSFER), ls_balance.task_array_[1].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_MERGE), ls_balance.task_array_[2].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_TRANSFER), ls_balance.task_array_[3].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_TRANSFER), ls_balance.task_array_[4].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_MERGE), ls_balance.task_array_[5].get_task_type()); + + } + //case 8 6->9 + MTL_SWITCH(tenant_id) { + ASSERT_EQ(OB_SUCCESS, unit_group.push_back(unit_group3)); + ls_array.reset(); + ObLSBalanceTaskHelper ls_balance; + for (int64_t i = 1001; i < 1006; ++i) { + ObLSID ls_id(i); + ObLSStatusInfo info; + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ls_id, 1, share::OB_LS_NORMAL, 1001, "z2", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + i++; + ObLSID ls_id1(i); + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ls_id1, 2, share::OB_LS_NORMAL, 1002, "z2", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + } + ASSERT_EQ(OB_SUCCESS, ls_balance.init(tenant_id,ls_array, unit_group, primary_zone_num, sql_proxy)); + LOG_INFO("testtest8", K(ls_balance.unit_group_balance_array_)); + bool need_balance = false; + ASSERT_EQ(OB_SUCCESS, ls_balance.check_need_ls_balance(need_balance)); + ASSERT_EQ(true, need_balance); + ASSERT_EQ(OB_SUCCESS, ls_balance.generate_ls_balance_task()); + LOG_INFO("testtest8", K(ls_balance.get_balance_job()), K(ls_balance.get_balance_tasks())); + ASSERT_EQ(15, ls_balance.get_balance_tasks().count()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_SPLIT), ls_balance.task_array_[0].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_SPLIT), ls_balance.task_array_[1].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_ALTER), ls_balance.task_array_[2].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_ALTER), ls_balance.task_array_[3].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_MERGE), ls_balance.task_array_[4].get_task_type()); + + } + + //case 9 7->4 + MTL_SWITCH(tenant_id) { + ASSERT_EQ(OB_SUCCESS, unit_group.push_back(unit_group4)); + ObLSBalanceTaskHelper ls_balance; + ls_array.reset(); + for (int64_t i = 1001; i < 1007; ++i) { + ObLSID ls_id(i); + ObLSStatusInfo info; + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ls_id, 1, share::OB_LS_NORMAL, 1001, "z1", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + i++; + ObLSID ls_id1(i); + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ls_id1, 2, share::OB_LS_NORMAL, 1002, "z1", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + } + primary_zone_num = 1; + ASSERT_EQ(OB_SUCCESS, ls_balance.init(tenant_id,ls_array, unit_group, primary_zone_num, sql_proxy)); + LOG_INFO("testtest9", K(ls_balance.unit_group_balance_array_)); + bool need_balance = false; + ASSERT_EQ(OB_SUCCESS, ls_balance.check_need_ls_balance(need_balance)); + ASSERT_EQ(true, need_balance); + ASSERT_EQ(OB_SUCCESS, ls_balance.generate_ls_balance_task()); + LOG_INFO("testtest9", K(ls_balance.get_balance_job()), K(ls_balance.get_balance_tasks())); + ASSERT_EQ(2, ls_balance.get_balance_tasks().count()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_ALTER), ls_balance.task_array_[0].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_ALTER), ls_balance.task_array_[1].get_task_type()); + ls_array.reset(); + for (int64_t i = 1001; i < 1006; ++i) { + ObLSStatusInfo info; + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ObLSID(i), i%3, share::OB_LS_NORMAL, 1001, "z1", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + i++; + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ObLSID(i), i%3, share::OB_LS_NORMAL, 1002, "z1", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + i++; + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ObLSID(i), i%3, share::OB_LS_NORMAL, 1003, "z1", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + } + ASSERT_EQ(OB_SUCCESS, info.init(tenant_id, ObLSID(1007), 3, share::OB_LS_NORMAL, 1004, "z1", ls_flag)); + ASSERT_EQ(OB_SUCCESS, ls_array.push_back(info)); + primary_zone_num = 1; + { + ObLSBalanceTaskHelper ls_balance; + ASSERT_EQ(OB_SUCCESS, ls_balance.init(tenant_id,ls_array, unit_group, primary_zone_num, sql_proxy)); + LOG_INFO("testtest9", K(ls_balance.unit_group_balance_array_)); + ASSERT_EQ(OB_SUCCESS, ls_balance.check_need_ls_balance(need_balance)); + ASSERT_EQ(true, need_balance); + ASSERT_EQ(OB_SUCCESS, ls_balance.generate_ls_balance_task()); + LOG_INFO("testtest9", K(ls_balance.get_balance_job()), K(ls_balance.get_balance_tasks())); + ASSERT_EQ(9, ls_balance.get_balance_tasks().count()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_TRANSFER), ls_balance.task_array_[0].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_ALTER), ls_balance.task_array_[1].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_MERGE), ls_balance.task_array_[2].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_TRANSFER), ls_balance.task_array_[3].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_ALTER), ls_balance.task_array_[4].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_MERGE), ls_balance.task_array_[5].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_TRANSFER), ls_balance.task_array_[6].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_ALTER), ls_balance.task_array_[7].get_task_type()); + ASSERT_EQ(ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_MERGE), ls_balance.task_array_[8].get_task_type()); + + } + } +} + +//验证merge任务在transfer结束后再次设置part_list然后结束 +TEST_F(TestBalanceOperator, merge_task) +{ + ObBalanceTask task; + uint64_t tenant_id = OB_SYS_TENANT_ID; + ObBalanceJobID job_id(1); + ObBalanceTaskID task_id(1); + int64_t ls_group_id = OB_INVALID_ID; + int64_t start_time = 0; + int64_t finish_time = 0; + int64_t src_ls_id = 1; + int64_t dest_ls_id = 2; + //TODO + ObTransferTaskID transfer_task_id; + ObString task_type, task_status; + ObString part_list_str, finished_part_list_str; + ObString parent_list_str, child_list_str; + ObTransferPartList part_list, finished_part_list; + ObBalanceTaskIDList parent_list, child_list; + task_type = ObString("LS_MERGE"); + task_status = ObString("TRANSFER"); + ObString comment; + //防止后台线程结束这个任务 + ASSERT_EQ(OB_SUCCESS, parent_list.push_back(task_id)); + ASSERT_EQ(OB_SUCCESS, task.init( + tenant_id, job_id, task_id, + ObBalanceTaskType(task_type), + ObBalanceTaskStatus(task_status), ls_group_id, + ObLSID(src_ls_id), ObLSID(dest_ls_id), + transfer_task_id, part_list, finished_part_list, + parent_list, child_list, comment)); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::insert_new_task(task, sql_proxy)); + //设置part_list + ObTransferPartInfo part_info(50001, 50001); + ASSERT_EQ(OB_SUCCESS, part_list.push_back(part_info)); + transfer_task_id = ObTransferTaskID(1); + ASSERT_EQ(OB_SUCCESS, task.init( + tenant_id, job_id, task_id, + ObBalanceTaskType(task_type), + ObBalanceTaskStatus(task_status), ls_group_id, + ObLSID(src_ls_id), ObLSID(dest_ls_id), + transfer_task_id, part_list, finished_part_list, + parent_list, child_list, comment)); + LOG_INFO("testtest7: start set part list"); + common::ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&sql_proxy, tenant_id)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::update_merge_ls_part_list(tenant_id, task_id, part_list, trans)); + ASSERT_EQ(OB_SUCCESS, trans.end(true)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::start_transfer_task(tenant_id, task_id, transfer_task_id, sql_proxy)); + ObTransferPartList to_do_part_list; + bool all_part_transferred = false; + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::finish_transfer_task(task, transfer_task_id, part_list, sql_proxy, to_do_part_list, all_part_transferred)); + ASSERT_EQ(0, to_do_part_list.count()); + ASSERT_EQ(true, all_part_transferred); + LOG_INFO("testtest8: start set part list"); + common::ObMySQLTransaction trans1; + ASSERT_EQ(OB_SUCCESS, trans1.start(&sql_proxy, tenant_id)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::update_merge_ls_part_list(tenant_id, task_id, part_list, trans1)); + ASSERT_EQ(OB_SUCCESS, trans1.end(true)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::start_transfer_task(tenant_id, task_id, transfer_task_id, sql_proxy)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::finish_transfer_task(task, transfer_task_id, part_list, sql_proxy, to_do_part_list, all_part_transferred)); + ASSERT_EQ(0, to_do_part_list.count()); + ASSERT_EQ(true, all_part_transferred); + LOG_INFO("testtest9: start set part list"); + common::ObMySQLTransaction trans2; + ASSERT_EQ(OB_SUCCESS, trans2.start(&sql_proxy, tenant_id)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::update_merge_ls_part_list(tenant_id, task_id, part_list, trans2)); + ASSERT_EQ(OB_SUCCESS, trans2.end(true)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::start_transfer_task(tenant_id, task_id, transfer_task_id, sql_proxy)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskTableOperator::finish_transfer_task(task, transfer_task_id, part_list, sql_proxy, to_do_part_list, all_part_transferred)); + ASSERT_EQ(0, to_do_part_list.count()); + ASSERT_EQ(true, all_part_transferred); +} + +TEST_F(TestBalanceOperator, ls_balance_helper) +{ + ObBalanceTaskHelper task; + uint64_t tenant_id = OB_SYS_TENANT_ID; + ObBalanceTaskHelperOp invalid_op; + int64_t ls_group_id = OB_INVALID_ID; + ObLSID src_ls_id(1); + ObLSID dest_ls_id(2); + SCN invalid_scn; + ASSERT_EQ(OB_INVALID_ARGUMENT, task.init( + tenant_id, invalid_scn, invalid_op, + src_ls_id, dest_ls_id, ls_group_id)); + ObBalanceTaskHelperOp op(1); + ASSERT_EQ(OB_INVALID_ARGUMENT, task.init( + tenant_id, invalid_scn, op, + src_ls_id, dest_ls_id, ls_group_id)); + uint64_t ts = 10000000000000; + SCN scn; + ASSERT_EQ(OB_SUCCESS, scn.convert_from_ts(ts)); + ASSERT_EQ(OB_INVALID_ARGUMENT, task.init( + tenant_id, scn, op, + src_ls_id, dest_ls_id, ls_group_id)); + ls_group_id = 0; + ASSERT_EQ(OB_SUCCESS, task.init( + tenant_id, scn, op, + src_ls_id, dest_ls_id, ls_group_id)); + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskHelperTableOperator::insert_ls_balance_task(task, sql_proxy)); + + ObBalanceTaskHelper new_task; + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskHelperTableOperator::pop_task(tenant_id, sql_proxy, new_task)); + ASSERT_EQ(new_task.get_operation_scn().convert_to_ts(), ts); + ASSERT_EQ(ls_group_id, new_task.get_ls_group_id()); + ts += 10000000; + ObBalanceTaskHelperOp new_op(0); + ls_group_id = 1001; + ASSERT_EQ(OB_SUCCESS, scn.convert_from_ts(ts)); + ASSERT_EQ(OB_SUCCESS, task.init( + tenant_id, scn, new_op, + src_ls_id, dest_ls_id, ls_group_id)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskHelperTableOperator::insert_ls_balance_task(task, sql_proxy)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskHelperTableOperator::pop_task(tenant_id, sql_proxy, new_task)); + ts = 10000000000000; + ASSERT_EQ(new_task.get_operation_scn().convert_to_ts(), ts); + ASSERT_EQ(new_task.get_ls_group_id(), 0); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskHelperTableOperator::remove_task(tenant_id, new_task.get_operation_scn(), sql_proxy)); + ASSERT_EQ(OB_SUCCESS, ObBalanceTaskHelperTableOperator::pop_task(tenant_id, sql_proxy, new_task)); + + ASSERT_EQ(ls_group_id, new_task.get_ls_group_id()); +} +} // namespace share +} // namespace oceanbase + +int main(int argc, char **argv) +{ + init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/test_tenant_transfer_service.cpp b/mittest/simple_server/test_tenant_transfer_service.cpp new file mode 100644 index 000000000..d27a29dee --- /dev/null +++ b/mittest/simple_server/test_tenant_transfer_service.cpp @@ -0,0 +1,396 @@ +/** + * 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 +#include + +#define USING_LOG_PREFIX SHARE +#define protected public +#define private public + +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "lib/allocator/page_arena.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace rootserver +{ +using namespace share::schema; +using namespace common; +using namespace share; +using namespace transaction::tablelock; + +static uint64_t g_tenant_id; +static ObTransferPartList g_part_list; +static ObTransferPartList g_batch_part_list; + +#define INNER_EXE_SQL(...) \ + ASSERT_EQ(OB_SUCCESS, sql.assign(__VA_ARGS__)); \ + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(sql.ptr(), affected_rows)); + +#define EXE_SQL(...) \ + ASSERT_EQ(OB_SUCCESS, sql.assign(__VA_ARGS__)); \ + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + +#define GEN_PART_LIST(proxy, part_list, ...) \ + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt(__VA_ARGS__)); \ + ASSERT_EQ(OB_SUCCESS, read_sql(proxy, sql, part_list)); + +class TestTenantTransferService : public unittest::ObSimpleClusterTestBase +{ +public: + TestTenantTransferService() : unittest::ObSimpleClusterTestBase("test_tenant_transfer_service") {} + int read_sql(ObMySQLProxy &sql_proxy, const ObSqlString &sql, ObTransferPartList &part_list); + int gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task); + void create_hidden_table(); +}; + +int TestTenantTransferService::read_sql( + ObMySQLProxy &sql_proxy, + const ObSqlString &sql, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { + ret = OB_ERR_UNEXPECTED; + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + } else { + sqlclient::ObMySQLResult &res = *result.get_result(); + uint64_t table_id = OB_INVALID_ID; + uint64_t part_id = OB_INVALID_ID; + int64_t part_count = 0; + if (OB_SUCC(ret) && OB_SUCC(res.next())) { + EXTRACT_INT_FIELD_MYSQL(res, "object_id", table_id, uint64_t); + } + while(OB_SUCC(ret)) { + part_id = OB_INVALID_ID; + ObTransferPartInfo part_info; + if (OB_SUCC(res.next())) { + ++part_count; + EXTRACT_INT_FIELD_MYSQL(res, "object_id", part_id, uint64_t); + if (OB_FAIL(part_info.init(table_id, part_id))) { + } else if (OB_FAIL(part_list.push_back(part_info))) { + } + } + } + if (OB_ITER_END == ret) { + if (0 == part_count && OB_INVALID_ID != table_id && OB_INVALID_ID == part_id) { + ObTransferPartInfo part_info(table_id, 0); + (void)part_list.push_back(part_info); + } + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to generate data", K(sql)); + } + LOG_INFO("finish read sql", K(sql), K(part_list), K(table_id), K(part_id)); + } + } + return ret; +} + +int TestTenantTransferService::gen_mock_data(const ObTransferTaskID task_id, const ObTransferStatus &status, ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObLSID src_ls(1001); + ObLSID dest_ls(1002); + share::SCN start_scn; + share::SCN finish_scn; + start_scn.convert_for_inner_table_field(1666844202200632); + finish_scn.convert_for_inner_table_field(1666844202208490); + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ret = task.init(task_id, src_ls, dest_ls, ObString::make_string("500016:500014"), ObString("500030:500031"), ObString("500016:500015"), + ObString::make_string("1152921504606846983"), ObString::make_string("1152921504606846983:0"), start_scn, finish_scn, status, trace_id, OB_SUCCESS, + ObTransferTaskComment::EMPTY_COMMENT, ObBalanceTaskID(123), ObTableLockOwnerID(999)); + return ret; +} + +TEST_F(TestTenantTransferService, prepare_valid_data) +{ + g_tenant_id = OB_INVALID_TENANT_ID; + + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + // create table + ObSqlString sql; + int64_t affected_rows = 0; + EXE_SQL("create table ttt1(c1 int primary key, c2 blob) partition by hash(c1) partitions 2"); + EXE_SQL("create index ttt1_idx on ttt1(c1) local"); + EXE_SQL("create index ttt1_global ON ttt1(c1) global partition by hash(c1) partitions 2"); + GEN_PART_LIST(sql_proxy, g_part_list, "select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1'"); + GEN_PART_LIST(sql_proxy, g_part_list, "select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt1_global'"); + + // create 101 partitions + EXE_SQL("create table ttt2(c1 int primary key) partition by hash(c1) partitions 101"); + GEN_PART_LIST(sql_proxy, g_batch_part_list, "select object_id from oceanbase.DBA_OBJECTS where OBJECT_NAME='ttt2'"); +} + +TEST_F(TestTenantTransferService, test_service) +{ + int ret = OB_SUCCESS; + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + // stuck storage transfer + INNER_EXE_SQL("alter system set debug_sync_timeout = '1000s'"); + usleep(100000); // wait for debug_sync_timeout to take effect + sql.reset(); + INNER_EXE_SQL("set ob_global_debug_sync = 'AFTER_TRANSFER_PROCESS_INIT_TASK_AND_BEFORE_NOTIFY_STORAGE wait_for signal execute 10000'"); + + ASSERT_EQ(4, g_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + // generate transfer task + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1), + g_part_list, ObBalanceTaskID(123), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(inner_sql_proxy, g_tenant_id, task_id, false, task)); + ASSERT_TRUE(task.get_status().is_init_status() || task.get_status().is_start_status()); + ASSERT_TRUE(task.get_part_list().count() == g_part_list.count()); + ARRAY_FOREACH(g_part_list, idx) { + ASSERT_TRUE(is_contain(task.get_part_list(), g_part_list.at(idx))); + } + LOG_INFO("generate transfer task", K(task)); + + // generate tablet_list + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + sleep(10); + task.reset(); + ObArenaAllocator allocator; + ObString tablet_list_str; + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(inner_sql_proxy, g_tenant_id, task_id, false, task)); + LOG_INFO("generate tablet list", K(task)); + ASSERT_TRUE(task.is_valid()); + const ObTransferTabletList &tablet_list = task.get_tablet_list(); + ASSERT_TRUE(10 == tablet_list.count()); // 2 * (primary + local_index + lob_meta + lob_piece) + 2 * global_index + ASSERT_EQ(OB_SUCCESS, tablet_list.to_display_str(allocator, tablet_list_str)); + LOG_INFO("tablet list string", K(tablet_list_str)); + ASSERT_TRUE(0 == tablet_list_str.case_compare("200001:0,200002:0,1152921504606846977:0,1152921504606846978:0," + "1152921504606846979:0,1152921504606846980:0,1152921504606846981:0,1152921504606846982:0,1152921504606846983:0,1152921504606846984:0")); + + // try cancel transfer task + ObTransferTask init_task; + ObTransferTask aborted_task; + ObTransferTaskID init_task_id(222); + ObTransferTaskID aborted_task_id(333); + ASSERT_EQ(OB_SUCCESS, gen_mock_data(init_task_id, ObTransferStatus(ObTransferStatus::INIT), init_task)); + ASSERT_EQ(OB_SUCCESS, gen_mock_data(aborted_task_id, ObTransferStatus(ObTransferStatus::ABORTED), aborted_task)); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::insert(inner_sql_proxy, g_tenant_id, init_task)); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::insert(inner_sql_proxy, g_tenant_id, aborted_task)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->try_cancel_transfer_task(ObTransferTaskID(555))); // task which does not exist will be canceled successfully + ASSERT_EQ(OB_OP_NOT_ALLOW, tenant_transfer->try_cancel_transfer_task(aborted_task_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->try_cancel_transfer_task(init_task_id)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferTaskOperator::get(inner_sql_proxy, g_tenant_id, init_task_id, false, init_task)); + + // try clear transfer task + task.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(inner_sql_proxy, g_tenant_id, task_id, false, task)); + ASSERT_EQ(OB_SUCCESS, ret); + sql.reset(); + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("update oceanbase.__all_transfer_task set status = 'COMPLETED' where task_id = %ld", task.get_task_id().id())); + ASSERT_EQ(OB_SUCCESS, inner_sql_proxy.write(g_tenant_id, sql.ptr(), affected_rows)); + + ObTransferPartList all_part_list; + ObTransferPartList finished_part_list; + ASSERT_EQ(OB_NEED_RETRY, tenant_transfer->try_clear_transfer_task(aborted_task_id, all_part_list, finished_part_list)); + ASSERT_TRUE(all_part_list.empty() && finished_part_list.empty()); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->try_clear_transfer_task(task_id, all_part_list, finished_part_list)); + ObString all_part_list_str; + ASSERT_TRUE(all_part_list.count() == g_part_list.count()); + ARRAY_FOREACH(g_part_list, idx) { + ASSERT_TRUE(is_contain(all_part_list, g_part_list.at(idx))); + } + ASSERT_TRUE(finished_part_list.count() == all_part_list.count()); + ARRAY_FOREACH(all_part_list, idx) { + ASSERT_TRUE(is_contain(finished_part_list, all_part_list.at(idx))); + } + ObString finished_part_list_str; + ASSERT_EQ(OB_SUCCESS, finished_part_list.to_display_str(allocator, finished_part_list_str)); + LOG_WARN("finished_part_list", K(finished_part_list_str)); + ASSERT_TRUE(0 == finished_part_list_str.case_compare("500002:500003,500002:500004,500016:500014,500016:500015")); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferTaskOperator::get(inner_sql_proxy, g_tenant_id, task_id, false, task)); + create_time = OB_INVALID_TIMESTAMP; + finish_time = OB_INVALID_TIMESTAMP; + ObTransferTask history_task; + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get_history_task(inner_sql_proxy, g_tenant_id, task_id, history_task, create_time, finish_time)); + ASSERT_TRUE(history_task.get_status().is_completed_status()); +} + +TEST_F(TestTenantTransferService, test_batch_part_list) +{ + int ret = OB_SUCCESS; + ASSERT_EQ(101, g_batch_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + + // generate transfer task in batch + ObTransferTaskID batch_task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1001), + g_batch_part_list, ObBalanceTaskID(124), batch_task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(inner_sql_proxy, g_tenant_id, batch_task_id, false, task)); + ASSERT_TRUE(ObTenantTransferService::PART_COUNT_IN_A_TRANSFER == task.get_part_list().count()); + ARRAY_FOREACH(task.get_part_list(), idx) { + ASSERT_TRUE(is_contain(g_batch_part_list, task.get_part_list().at(idx))); + } +} + +TEST_F(TestTenantTransferService, test_empty_list) +{ + int ret = OB_SUCCESS; + ASSERT_EQ(101, g_batch_part_list.count()); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + // errorsim + ObSqlString sql; + int64_t affected_rows = 0; + INNER_EXE_SQL("alter system set_tp tp_name = EN_TENANT_TRANSFER_ALL_LIST_EMPTY, error_code = 4016, frequency = 1"); + // transfer + ObTransferTaskID task_id; + ObMySQLTransaction trans; + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->generate_transfer_task(trans, ObLSID(1001), ObLSID(1), + g_part_list, ObBalanceTaskID(124), task_id)); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + ASSERT_EQ(OB_ERR_UNEXPECTED, tenant_transfer->process_init_task_(task_id)); +} + +void TestTenantTransferService::create_hidden_table() +{ + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + ObSqlString sql; + int64_t affected_rows = 0; + + INNER_EXE_SQL("set ob_global_debug_sync = 'reset';"); + INNER_EXE_SQL("alter system set debug_sync_timeout = '1000s';"); + usleep(100000); + INNER_EXE_SQL("set ob_global_debug_sync = 'TABLE_REDEFINITION_REPLICA_BUILD wait_for signal execute 10000'"); + usleep(100000); + EXE_SQL("create table t_hidden_1(c1 int); "); + EXE_SQL("alter table t_hidden_1 modify c1 char(10);"); + LOG_INFO("finish create hidden table", K(sql), K(affected_rows)); +} + +TEST_F(TestTenantTransferService, test_offline_ddl_hidden_table) +{ + int ret = OB_SUCCESS; + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(g_tenant_id)); + ObTenantTransferService *tenant_transfer = MTL(ObTenantTransferService*); + ObMySQLProxy &inner_sql_proxy = get_curr_observer().get_mysql_proxy(); + ASSERT_TRUE(OB_NOT_NULL(tenant_transfer)); + // errorsim + ObSqlString sql; + int64_t affected_rows = 0; + std::thread create_hidden_table_thread([this]() { create_hidden_table(); }); + create_hidden_table_thread.detach(); + sleep(3); + sql.reset(); + ObTransferPartList primary_table_part_list; + GEN_PART_LIST(inner_sql_proxy, primary_table_part_list, "select object_id from oceanbase.CDB_OBJECTS where CON_ID = %lu and OBJECT_NAME = 't_hidden_1'", g_tenant_id); + LOG_INFO("read hidden table primary table", K(primary_table_part_list)); + ASSERT_TRUE(1 == primary_table_part_list.count()); + ASSERT_TRUE(500119 == primary_table_part_list.at(0).table_id()); + ObTransferPartList hidden_part_list; + GEN_PART_LIST(inner_sql_proxy, hidden_part_list, "select association_table_id as object_id from oceanbase.__all_virtual_table where tenant_id = %lu and table_name = 't_hidden_1'", g_tenant_id); + LOG_INFO("read hidden table", K(hidden_part_list)); + ASSERT_TRUE(500120 == hidden_part_list.at(0).table_id()); + + ObMySQLTransaction trans; + ObTransferPartList offline_ddl_table_part_list; + ObTransferPartList not_exist_part_list; + ObTransferPartList lock_conflict_part_list; + ObDisplayTabletList table_lock_tablet_list; + ObArray tablet_ids; + ObTableLockOwnerID lock_owner_id; + ASSERT_EQ(OB_SUCCESS, common::append(offline_ddl_table_part_list, primary_table_part_list)); + ASSERT_EQ(OB_SUCCESS, common::append(offline_ddl_table_part_list, hidden_part_list)); + ASSERT_EQ(OB_SUCCESS, trans.start(&inner_sql_proxy, g_tenant_id)); + ASSERT_EQ(OB_SUCCESS, tenant_transfer->lock_table_and_part_(trans, ObLSID(1001), offline_ddl_table_part_list, + not_exist_part_list, lock_conflict_part_list, table_lock_tablet_list, tablet_ids, lock_owner_id)); + LOG_INFO("lock_table_and_part", K(offline_ddl_table_part_list), K(not_exist_part_list), K(lock_conflict_part_list), K(table_lock_tablet_list), K(tablet_ids), K(lock_owner_id)); + ASSERT_TRUE(not_exist_part_list.empty() && table_lock_tablet_list.empty() && tablet_ids.empty()); + ASSERT_TRUE(2 == lock_conflict_part_list.count()); + ObArenaAllocator allocator; + ObString lock_conflict_part_list_str; + ASSERT_EQ(OB_SUCCESS, lock_conflict_part_list.to_display_str(allocator, lock_conflict_part_list_str)); + LOG_INFO("lock conflict hidden table", K(lock_conflict_part_list_str)); + ASSERT_TRUE(0 == lock_conflict_part_list_str.compare("500119:0,500120:0")); + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } +} + +} // namespace rootserver +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/simple_server/test_transfer_task_operator.cpp b/mittest/simple_server/test_transfer_task_operator.cpp new file mode 100644 index 000000000..10e43e4ee --- /dev/null +++ b/mittest/simple_server/test_transfer_task_operator.cpp @@ -0,0 +1,389 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX SHARE + +#include +#include +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "share/transfer/ob_transfer_task_operator.h" + +using namespace unittest; + +namespace oceanbase +{ +namespace share +{ +using namespace schema; +using namespace common; + +class TestTransferTaskOperator : public ObSimpleClusterTestBase +{ +public: + TestTransferTaskOperator() : ObSimpleClusterTestBase("test_transfer_task_operator") {} + virtual void SetUp(); +public: + uint64_t tenant_id_; + ObTransferTaskID task_id_; + ObLSID src_ls_; + ObLSID dest_ls_; + ObTransferPartList part_list_; + ObTransferPartList not_exist_part_list_; + ObTransferPartList lock_conflict_part_list_; + ObDisplayTabletList table_lock_tablet_list_; + ObTransferTabletList tablet_list_; + share::SCN start_scn_; + share::SCN finish_scn_; + ObTransferStatus status_; + TraceId trace_id_; + ObTransferTask task_; + transaction::tablelock::ObTableLockOwnerID lock_owner_id_; +}; + +void TestTransferTaskOperator::SetUp() +{ + tenant_id_ = 1002; + task_id_ = 111; + src_ls_ = 1001; + dest_ls_ = 1002; + status_ = ObTransferStatus::INIT; + start_scn_.convert_for_inner_table_field(1666844202200632); + finish_scn_.convert_for_inner_table_field(1666844202208490); + ObString trace_id_str = "YCDC56458724D-0005EBECD3F9DB9D-0-0"; + trace_id_.parse_from_buf(trace_id_str.ptr()); + lock_owner_id_ = 999; + for(int64_t i = 0; i < 100; ++i) { + ObTransferPartInfo part; + ObTransferTabletInfo tablet; + ASSERT_EQ(OB_SUCCESS, part.init(20000 + i, 25000 + i)); + ASSERT_EQ(OB_SUCCESS, part_list_.push_back(part)); + ASSERT_EQ(OB_SUCCESS, tablet.init(ObTabletID(10000 + i), i)); + ASSERT_EQ(OB_SUCCESS, tablet_list_.push_back(tablet)); + ASSERT_EQ(OB_SUCCESS, table_lock_tablet_list_.push_back(ObDisplayTabletID(ObTabletID(10000 + i)))); + if (i < 2) { + ASSERT_EQ(OB_SUCCESS, not_exist_part_list_.push_back(part)); + } else if (i < 4) { + ASSERT_EQ(OB_SUCCESS, lock_conflict_part_list_.push_back(part)); + } + } + ASSERT_EQ(OB_SUCCESS, task_.init(task_id_, src_ls_, dest_ls_, part_list_, status_, trace_id_, + ObBalanceTaskID(12))); + LOG_INFO("tranfer task init", K(task_)); +} + +TEST_F(TestTransferTaskOperator, test_basic_func) +{ + int ret = OB_SUCCESS; + + // ObTransferTabletInfo + ObTransferTabletInfo tablet_info; + ObTransferTabletInfo invalid_tablet_info; + char buf[100]; + int64_t pos = 0; + ASSERT_EQ(OB_SUCCESS, tablet_info.init(ObTabletID(20001), 1)); + ASSERT_EQ(OB_SUCCESS, tablet_info.to_display_str(buf, sizeof(buf), pos)); + ASSERT_TRUE(0 == strcmp(buf, "20001:1")); + LOG_INFO("tablet_info str", K(buf), K(tablet_info)); + tablet_info.reset(); + ASSERT_EQ(OB_SUCCESS, tablet_info.parse_from_display_str(ObString::make_string(buf))); + ASSERT_TRUE((tablet_info.tablet_id().id() == 20001) && (tablet_info.transfer_seq() == 1)); + + memset(buf, 0, sizeof(buf)); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_tablet_info.init(ObTabletID(), 1)); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_tablet_info.init(ObTabletID(1), -1)); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_tablet_info.to_display_str(buf, sizeof(buf), pos)); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_tablet_info.parse_from_display_str(ObString::make_string(""))); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_tablet_info.parse_from_display_str(ObString::make_string("a:1"))); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_tablet_info.parse_from_display_str(ObString::make_string("123,1"))); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_tablet_info.parse_from_display_str(ObString::make_string("123,123456789012345678901234567890"))); + + // ObTransferPartInfo + ObTransferPartInfo part_info; + ObTransferPartInfo invalid_part_info; + char part_info_buf[100]; + memset(part_info_buf, 0, sizeof(part_info_buf)); + pos = 0; + ASSERT_EQ(OB_SUCCESS, part_info.init(123456, 654321)); + ASSERT_EQ(OB_SUCCESS, part_info.to_display_str(part_info_buf, sizeof(part_info_buf), pos)); + ASSERT_TRUE(0 == strcmp(part_info_buf, "123456:654321")); + LOG_INFO("part_info str", K(part_info_buf), K(part_info)); + part_info.reset(); + ASSERT_EQ(OB_SUCCESS, part_info.parse_from_display_str(ObString::make_string(part_info_buf))); + ASSERT_TRUE((part_info.table_id() == 123456) && (part_info.part_object_id() == 654321)); + + memset(part_info_buf, 0, sizeof(part_info_buf)); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_part_info.init(OB_INVALID_ID, 1)); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_part_info.init(1, OB_INVALID_ID)); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_part_info.to_display_str(part_info_buf, sizeof(part_info_buf), pos)); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_part_info.parse_from_display_str(ObString::make_string(""))); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_part_info.parse_from_display_str(ObString::make_string("a:1"))); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_part_info.parse_from_display_str(ObString::make_string("123,1"))); + ASSERT_EQ(OB_INVALID_ARGUMENT, invalid_tablet_info.parse_from_display_str(ObString::make_string("123,123456789012345678901234567890"))); + + // to_display_str and parse_str + common::ObArenaAllocator allocator; + ObString part_list_str; + ObTransferPartList new_part_list; + ASSERT_EQ(OB_SUCCESS, part_list_.to_display_str(allocator, part_list_str)); + LOG_INFO("ObTransferPartList to str", K(part_list_str)); + ASSERT_EQ(OB_SUCCESS, new_part_list.parse_from_display_str(part_list_str)); + LOG_INFO("parse str into ObTransferPartList", K(new_part_list)); + ASSERT_TRUE(!new_part_list.empty()); + ARRAY_FOREACH_N(part_list_, idx, cnt) { + ASSERT_TRUE(part_list_.at(idx) == new_part_list.at(idx)); + } + + ObString tablet_list_str; + ObString table_lock_tablet_list_str; + ObTransferTabletList new_tablet_list; + ASSERT_EQ(OB_SUCCESS, tablet_list_.to_display_str(allocator, tablet_list_str)); + LOG_INFO("ObTransferTabletList to str", K(tablet_list_str)); + ASSERT_EQ(OB_SUCCESS, table_lock_tablet_list_.to_display_str(allocator, table_lock_tablet_list_str)); + ASSERT_EQ(OB_SUCCESS, new_tablet_list.parse_from_display_str(tablet_list_str)); + LOG_INFO("parse str into ObTransferTabletList", K(new_tablet_list)); + ASSERT_TRUE(!new_tablet_list.empty()); + ARRAY_FOREACH_N(tablet_list_, idx, cnt) { + ASSERT_TRUE(tablet_list_.at(idx) == new_tablet_list.at(idx)); + } + + // empty list and str + ObString empty_str; + new_part_list.reset(); + ASSERT_EQ(OB_SUCCESS, new_part_list.to_display_str(allocator, empty_str)); + ASSERT_EQ(OB_SUCCESS, new_part_list.parse_from_display_str(empty_str)); + ASSERT_TRUE(new_part_list.empty() && empty_str.empty()); + + // invalid str + ObString invalid_str_1 = "123,12,123,21"; + ObString invalid_str_2 = "aa:12,123:bb"; + ObString invalid_str_3 = "1:1,1:123456789012345678901234567890"; + ObString invalid_str_4 = "123:12!321:21"; + ASSERT_EQ(OB_INVALID_ARGUMENT, new_part_list.parse_from_display_str(invalid_str_1)); + ASSERT_EQ(OB_INVALID_ARGUMENT, new_part_list.parse_from_display_str(invalid_str_2)); + new_part_list.reset(); + ASSERT_EQ(OB_SUCCESS, new_part_list.parse_from_display_str(invalid_str_3)); + ASSERT_TRUE(new_part_list.count() == 2 && new_part_list.at(1).part_object_id() == OB_INVALID_ID); + new_part_list.reset(); + ASSERT_EQ(OB_SUCCESS, new_part_list.parse_from_display_str(invalid_str_4)); + ASSERT_TRUE(new_part_list.count() == 1); + + + // ObTransferTask other init + ObTransferTask task; + ASSERT_TRUE(!task.is_valid()); + ASSERT_EQ(OB_SUCCESS, task.init(task_id_, src_ls_, dest_ls_, part_list_str, empty_str, empty_str, table_lock_tablet_list_str, tablet_list_str, + start_scn_, finish_scn_, status_, trace_id_, OB_SUCCESS, ObTransferTaskComment::EMPTY_COMMENT, + ObBalanceTaskID(2), lock_owner_id_)); + LOG_INFO("tranfer task other init", K(task)); + ASSERT_TRUE(task.is_valid()); + task.reset(); + ASSERT_EQ(OB_SUCCESS, task.assign(task_)); + ASSERT_EQ(task.get_task_id(), task_.get_task_id()); + + // ObTrasnferTaskComment + ASSERT_TRUE(0 == strcmp(transfer_task_comment_to_str(ObTransferTaskComment::EMPTY_COMMENT), "")); + ASSERT_TRUE(0 == strcmp(transfer_task_comment_to_str(ObTransferTaskComment::WAIT_FOR_MEMBER_LIST), "WAIT FOR MEMBER LIST TO BE SAME")); + ASSERT_TRUE(0 == strcmp(transfer_task_comment_to_str(ObTransferTaskComment::TASK_COMPLETED_AS_NO_VALID_PARTITION), "TASK COMPLETED AS NO VALID PARTITION")); + ASSERT_TRUE(0 == strcmp(transfer_task_comment_to_str(ObTransferTaskComment::TASK_CANCELED), "TASK CANCELED")); + ASSERT_TRUE(0 == strcmp(transfer_task_comment_to_str(ObTransferTaskComment::MAX_COMMENT), "UNKNOW")); + + ASSERT_TRUE(ObTransferTaskComment::WAIT_FOR_MEMBER_LIST == str_to_transfer_task_comment("WAIT FOR MEMBER LIST TO BE SAME")); + ASSERT_TRUE(ObTransferTaskComment::TASK_COMPLETED_AS_NO_VALID_PARTITION == str_to_transfer_task_comment("TASK COMPLETED AS NO VALID PARTITION")); + ASSERT_TRUE(ObTransferTaskComment::TASK_CANCELED == str_to_transfer_task_comment("TASK CANCELED")); + ASSERT_TRUE(ObTransferTaskComment::EMPTY_COMMENT == str_to_transfer_task_comment("")); + ASSERT_TRUE(ObTransferTaskComment::MAX_COMMENT == str_to_transfer_task_comment("UNKNOW")); + ASSERT_TRUE(ObTransferTaskComment::MAX_COMMENT == str_to_transfer_task_comment("XXXXX")); +} + +TEST_F(TestTransferTaskOperator, test_operator) +{ + int ret = OB_SUCCESS; + ObSimpleClusterTestBase::SetUp(); + ASSERT_EQ(OB_SUCCESS, create_tenant()); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(tenant_id_)); + LOG_INFO("new tenant_id", K(tenant_id_)); + ObMySQLProxy &sql_proxy = get_curr_observer().get_mysql_proxy(); + + // get_all_task_status empty + ObArray task_status; + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferTaskOperator::get_all_task_status(sql_proxy, tenant_id_, task_status)); + ASSERT_TRUE(task_status.empty()); + + // insert + ObTransferTask other_task; + ObTransferTaskID other_task_id(222); + ASSERT_EQ(OB_SUCCESS, other_task.init(other_task_id, ObLSID(1003), ObLSID(1004), part_list_, + ObTransferStatus(ObTransferStatus::INIT), trace_id_, ObBalanceTaskID(2))); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::insert(sql_proxy, tenant_id_, other_task)); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::insert(sql_proxy, tenant_id_, task_)); + ASSERT_EQ(OB_ENTRY_EXIST, ObTransferTaskOperator::insert(sql_proxy, tenant_id_, task_)); + + // update comment + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::update_comment(sql_proxy, tenant_id_, task_id_, ObTransferTaskComment::TASK_CANCELED)); + + // get + ObTransferTask task; + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(sql_proxy, tenant_id_, task_id_, false, task)); + ASSERT_TRUE(task.get_task_id() == task_id_); + ASSERT_TRUE(task.get_tablet_list().empty()); + ASSERT_TRUE(0 == strcmp(transfer_task_comment_to_str(task.get_comment()), "TASK CANCELED")); + LOG_INFO("get from table", K(task)); + task.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(sql_proxy, tenant_id_, task_id_, true, task)); + LOG_INFO("get from table", K(task)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferTaskOperator::get(sql_proxy, tenant_id_, + ObTransferTaskID(555), false, task)); + + // get_task_with_time + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + task.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get_task_with_time(sql_proxy, tenant_id_, task_id_, true, task, create_time, finish_time)); + ASSERT_TRUE(OB_INVALID_TIMESTAMP != create_time); + ASSERT_TRUE(OB_INVALID_TIMESTAMP != finish_time); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferTaskOperator::get_task_with_time(sql_proxy, tenant_id_, + ObTransferTaskID(555), false, task, create_time, finish_time)); + + // get by status + ObArray tasks; + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get_by_status(sql_proxy, tenant_id_, status_, tasks)); + ASSERT_TRUE(2 == tasks.count()); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferTaskOperator::get_by_status(sql_proxy, tenant_id_, ObTransferStatus(ObTransferStatus::ABORTED), tasks)); + + // get by dest_ls + task.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get_by_dest_ls(sql_proxy, tenant_id_, dest_ls_, task)); + ASSERT_TRUE(task_id_ == task.get_task_id()); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferTaskOperator::get_by_dest_ls(sql_proxy, tenant_id_, ObLSID(555), task)); + ObTransferTask dup_dest_ls_task; + ASSERT_EQ(OB_SUCCESS, dup_dest_ls_task.init(ObTransferTaskID(2223), ObLSID(1003), ObLSID(1004), + part_list_, ObTransferStatus(ObTransferStatus::INIT), trace_id_, ObBalanceTaskID(2))); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::insert(sql_proxy, tenant_id_, dup_dest_ls_task)); + task.reset(); + ASSERT_EQ(OB_ERR_UNEXPECTED, ObTransferTaskOperator::get_by_dest_ls(sql_proxy, tenant_id_, ObLSID(1004), task)); + + // update_to_start_status + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::update_to_start_status(sql_proxy, tenant_id_,task_id_, + ObTransferStatus(ObTransferStatus::INIT), part_list_, not_exist_part_list_, lock_conflict_part_list_, table_lock_tablet_list_, tablet_list_, ObTransferStatus(ObTransferStatus::START), lock_owner_id_)); + task.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(sql_proxy, tenant_id_, task_id_, false, task)); + ASSERT_TRUE(!task.get_tablet_list().empty()); + LOG_INFO("update to start status", K(task)); + ASSERT_EQ(OB_STATE_NOT_MATCH, ObTransferTaskOperator::update_to_start_status(sql_proxy, tenant_id_,task_id_, + ObTransferStatus(ObTransferStatus::ABORTED), part_list_, not_exist_part_list_, lock_conflict_part_list_, table_lock_tablet_list_, tablet_list_, ObTransferStatus(ObTransferStatus::START), lock_owner_id_)); + + // update start_scn + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::update_start_scn(sql_proxy, tenant_id_, task_id_, ObTransferStatus(ObTransferStatus::START), start_scn_)); + task.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(sql_proxy, tenant_id_, task_id_, false, task)); + ASSERT_TRUE(task.get_start_scn() == start_scn_); + //ASSERT_EQ(OB_STATE_NOT_MATCH, ObTransferTaskOperator::update_start_scn(sql_proxy, tenant_id_, task_id_, ObTransferStatus(ObTransferStatus::ABORTED), start_scn_)); + + // update status + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::update_status_and_result(sql_proxy, tenant_id_, task_id_, + ObTransferStatus(ObTransferStatus::START), ObTransferStatus(ObTransferStatus::DOING), OB_SUCCESS)); + task.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(sql_proxy, tenant_id_, task_id_, false, task)); + ASSERT_TRUE(task.get_status().status() == ObTransferStatus::DOING); + //ASSERT_EQ(OB_STATE_NOT_MATCH, ObTransferTaskOperator::update_status(sql_proxy, tenant_id_, task_id_, + // ObTransferStatus(ObTransferStatus::ABORTED), ObTransferStatus(ObTransferStatus::ABORTED))); + + // finish task + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::finish_task(sql_proxy, tenant_id_, other_task_id, + ObTransferStatus(ObTransferStatus::INIT), ObTransferStatus(ObTransferStatus::COMPLETED), OB_SUCCESS, ObTransferTaskComment::EMPTY_COMMENT)); + task.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(sql_proxy, tenant_id_, other_task_id, false, task)); + ASSERT_TRUE(task.get_status().status() == ObTransferStatus::COMPLETED); + ASSERT_EQ(OB_STATE_NOT_MATCH, ObTransferTaskOperator::finish_task(sql_proxy, tenant_id_, other_task_id, + ObTransferStatus(ObTransferStatus::ABORTED), ObTransferStatus(ObTransferStatus::ABORTED), OB_SUCCESS, ObTransferTaskComment::EMPTY_COMMENT)); + + // finish task from init + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::finish_task_from_init(sql_proxy, tenant_id_, dup_dest_ls_task.get_task_id(), + ObTransferStatus(ObTransferStatus::INIT), part_list_, not_exist_part_list_, lock_conflict_part_list_, ObTransferStatus(ObTransferStatus::COMPLETED), OB_SUCCESS, ObTransferTaskComment::TASK_COMPLETED_AS_NO_VALID_PARTITION)); + task.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(sql_proxy, tenant_id_, other_task_id, false, task)); + ASSERT_TRUE(task.get_status().status() == ObTransferStatus::COMPLETED); + ASSERT_EQ(OB_STATE_NOT_MATCH, ObTransferTaskOperator::finish_task_from_init(sql_proxy, tenant_id_, dup_dest_ls_task.get_task_id(), + ObTransferStatus(ObTransferStatus::ABORTED), part_list_, not_exist_part_list_, lock_conflict_part_list_, ObTransferStatus(ObTransferStatus::COMPLETED), OB_SUCCESS, ObTransferTaskComment::TASK_COMPLETED_AS_NO_VALID_PARTITION)); + + // update finish_scn + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::update_finish_scn(sql_proxy, tenant_id_, task_id_, ObTransferStatus(ObTransferStatus::DOING), finish_scn_)); + task.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get(sql_proxy, tenant_id_, task_id_, false, task)); + ASSERT_TRUE(task.get_finish_scn() == finish_scn_); + ASSERT_EQ(OB_STATE_NOT_MATCH, ObTransferTaskOperator::update_finish_scn(sql_proxy, tenant_id_, task_id_, ObTransferStatus(ObTransferStatus::ABORTED), finish_scn_)); + + // get_all_task_status + task_status.reset(); + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get_all_task_status(sql_proxy, tenant_id_, task_status)); + ASSERT_TRUE(task_status.count() == 3); + bool is_same = false; + ARRAY_FOREACH(task_status, idx) { + const ObTransferTask::TaskStatus task_stat = task_status.at(idx); + if (task_stat.get_task_id() == task_id_) { + is_same = ObTransferStatus::DOING == task_stat.get_status(); + } else if (task_stat.get_task_id() == other_task_id) { + is_same = ObTransferStatus::COMPLETED == task_stat.get_status(); + } else if (task_stat.get_task_id() == dup_dest_ls_task.get_task_id()) { + is_same = ObTransferStatus::COMPLETED == task_stat.get_status(); + } else { + is_same = false; + } + } + ASSERT_TRUE(is_same); + + // remove task + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::remove(sql_proxy, tenant_id_, task_id_)); + task.reset(); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferTaskOperator::remove(sql_proxy, tenant_id_, task_id_)); + + // insert history + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::insert_history(sql_proxy, tenant_id_, task_, 111, 222)); + ASSERT_EQ(OB_ENTRY_EXIST, ObTransferTaskOperator::insert_history(sql_proxy, tenant_id_, task_, 111, 222)); + + // get history task + ObTransferTask history_task; + create_time = OB_INVALID_TIMESTAMP; + finish_time = OB_INVALID_TIMESTAMP; + ASSERT_EQ(OB_SUCCESS, ObTransferTaskOperator::get_history_task(sql_proxy, tenant_id_, task_id_, history_task, create_time, finish_time)); + ObArenaAllocator allocator; + ObString part_list_str; + ObString history_part_list_str; + ObString not_exist_part_list_str; + ObString history_not_exist_part_list_str; + ObString lock_conflict_part_list_str; + ObString history_lock_conflict_part_list_str; + ASSERT_TRUE(task_.get_task_id() == history_task.get_task_id()); + ASSERT_TRUE(task_.get_status() == history_task.get_status()); + ASSERT_EQ(OB_SUCCESS, task_.get_part_list().to_display_str(allocator, part_list_str)); + ASSERT_EQ(OB_SUCCESS, history_task.get_part_list().to_display_str(allocator, history_part_list_str)); + ASSERT_EQ(OB_SUCCESS, task_.get_not_exist_part_list().to_display_str(allocator, not_exist_part_list_str)); + ASSERT_EQ(OB_SUCCESS, history_task.get_not_exist_part_list().to_display_str(allocator, history_not_exist_part_list_str)); + ASSERT_EQ(OB_SUCCESS, task_.get_lock_conflict_part_list().to_display_str(allocator, lock_conflict_part_list_str)); + ASSERT_EQ(OB_SUCCESS, history_task.get_lock_conflict_part_list().to_display_str(allocator, history_lock_conflict_part_list_str)); + ASSERT_TRUE(0 == compare(part_list_str, history_part_list_str)); + ASSERT_TRUE(0 == compare(not_exist_part_list_str, history_not_exist_part_list_str)); + ASSERT_TRUE(0 == compare(lock_conflict_part_list_str, history_lock_conflict_part_list_str)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTransferTaskOperator::get_history_task(sql_proxy, + tenant_id_, ObTransferTaskID(555), history_task, create_time, finish_time)); +} + +} // namespace share +} // namespace oceanbase +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/diagnose/lua/ob_lua_api.cpp b/src/diagnose/lua/ob_lua_api.cpp index b3354aedc..808024af9 100644 --- a/src/diagnose/lua/ob_lua_api.cpp +++ b/src/diagnose/lua/ob_lua_api.cpp @@ -135,7 +135,6 @@ static constexpr const char *usage_str = "int = set_log_probe(string)\n" "{{row1}, {row2}, ...} = select_mem_leak_checker_info()\n" "{{row1}, {row2}, ...} = select_compaction_diagnose_info()\n" -"{{row1}, {row2}, ...} = select_dag_warning_history()\n" "{{row1}, {row2}, ...} = select_server_schema_info()\n" "{{row1}, {row2}, ...} = select_schema_slot()\n" "{{row1}, {row2}, ...} = dump_thread_info()\n" @@ -1640,73 +1639,6 @@ int select_compaction_diagnose_info(lua_State *L) return 1; } -// list{list, list...} = select_dag_warning_history() -int select_dag_warning_history(lua_State *L) -{ - int argc = lua_gettop(L); - if (argc > 1) { - OB_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "call select_dag_warning_history() failed, bad arguments count, should be less than 2."); - lua_pushnil(L); - } else { - int ret = OB_SUCCESS; - share::ObDagWarningInfoIterator dag_warning_info_iter; - // OB_SYS_TENANT_ID means dump all - if (OB_FAIL(dag_warning_info_iter.open(OB_SYS_TENANT_ID))) { - OB_LOG(ERROR, "Fail to open merge info iter", K(ret)); - lua_pushnil(L); - } else { - std::vector columns = { - "tenant_id", - "task_id", - "module", - "type", - "ret", - "status", - "gmt_create", - "gmt_modified", - "retry_cnt", - "warning_info" - }; - LuaVtableGenerator gen(L, columns); - share::ObDagWarningInfo dag_warning_info; - while (OB_SUCC(dag_warning_info_iter.get_next_info(dag_warning_info)) && !gen.is_end()) { - gen.next_row(); - // tenant_id - gen.next_column(dag_warning_info.tenant_id_); - // task_id - { - char task_id_buf[common::OB_TRACE_STAT_BUFFER_SIZE]; - int64_t n = dag_warning_info.task_id_.to_string(task_id_buf, sizeof(task_id_buf)); - if (n < 0 || n >= sizeof(task_id_buf)) { - ret = OB_BUF_NOT_ENOUGH; - } else { - gen.next_column(task_id_buf); - } - } - // module - gen.next_column(share::ObIDag::get_dag_module_str(dag_warning_info.dag_type_)); - // type - gen.next_column(share::ObIDag::get_dag_type_str(dag_warning_info.dag_type_)); - // ret - gen.next_column(common::ob_error_name(dag_warning_info.dag_ret_)); - // status - gen.next_column(ObDagWarningInfo::get_dag_status_str(dag_warning_info.dag_status_)); - // gmt_create - gen.next_column(dag_warning_info.gmt_create_); - // gmt_modified - gen.next_column(dag_warning_info.gmt_modified_); - // retry_cnt - gen.next_column(dag_warning_info.retry_cnt_); - // warning_info - gen.next_column(dag_warning_info.warning_info_); - - gen.row_end(); - } - } - } - return 1; -} - // list{list, list...} = select_server_schema_info() int select_server_schema_info(lua_State *L) { @@ -2177,7 +2109,6 @@ void APIRegister::register_api(lua_State* L) lua_register(L, "show_log_probe", show_log_probe); lua_register(L, "select_mem_leak_checker_info", select_mem_leak_checker_info); lua_register(L, "select_compaction_diagnose_info", select_compaction_diagnose_info); - lua_register(L, "select_dag_warning_history", select_dag_warning_history); lua_register(L, "select_server_schema_info", select_server_schema_info); lua_register(L, "select_schema_slot", select_schema_slot); lua_register(L, "dump_thread_info", dump_thread_info); diff --git a/src/logservice/CMakeLists.txt b/src/logservice/CMakeLists.txt index 598d40c90..d8dd959fb 100644 --- a/src/logservice/CMakeLists.txt +++ b/src/logservice/CMakeLists.txt @@ -61,6 +61,7 @@ ob_set_subtarget(ob_logservice common_mixed replayservice/ob_log_replay_service.cpp replayservice/ob_replay_handler.cpp replayservice/ob_replay_status.cpp + replayservice/ob_tablet_replay_executor.cpp ) ob_set_subtarget(ob_logservice leader_coordinator diff --git a/src/logservice/data_dictionary/ob_data_dict_meta_info.cpp b/src/logservice/data_dictionary/ob_data_dict_meta_info.cpp index 775456d79..953ff2150 100644 --- a/src/logservice/data_dictionary/ob_data_dict_meta_info.cpp +++ b/src/logservice/data_dictionary/ob_data_dict_meta_info.cpp @@ -43,7 +43,7 @@ ObDataDictMetaInfoItem::~ObDataDictMetaInfoItem() void ObDataDictMetaInfoItem::reset() { - snapshot_scn_ = share::OB_INVALID_SCN_VAL;; + snapshot_scn_ = share::OB_INVALID_SCN_VAL; start_lsn_ = palf::LOG_INVALID_LSN_VAL; end_lsn_ = palf::LOG_INVALID_LSN_VAL; } diff --git a/src/logservice/data_dictionary/ob_data_dict_struct.cpp b/src/logservice/data_dictionary/ob_data_dict_struct.cpp index eb7b46199..ff023b07c 100644 --- a/src/logservice/data_dictionary/ob_data_dict_struct.cpp +++ b/src/logservice/data_dictionary/ob_data_dict_struct.cpp @@ -388,10 +388,32 @@ int ObDictTenantMeta::incremental_data_update(const share::ObLSAttr &ls_attr) if (OB_UNLIKELY(! ls_attr.is_valid())) { ret = OB_INVALID_ARGUMENT; DDLOG(WARN, "ls attr is invalid", KR(ret), K(ls_attr)); - } else if (share::is_ls_create_end_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_create_end_op(ls_attr.get_ls_operation_type())) { if (OB_FAIL(ls_arr_.push_back(ls_attr.get_ls_id()))) { DDLOG(WARN, "ls_arr_ push_back failed", KR(ret), K(ls_attr), K(ls_arr_)); + } else { + DDLOG(TRACE, "ls_arr_ push back succ", K(ls_attr), K(ls_arr_)); } + } else if (share::is_ls_drop_end_op(ls_attr.get_ls_operation_type())) { + int64_t ls_idx = -1; + const ObLSID &ls_id = ls_attr.get_ls_id(); + ARRAY_FOREACH(ls_arr_, idx) { + const ObLSID &cur_ls_id = ls_arr_.at(idx); + // assume there is no duplicate ls_id in ls_arr_ + if (cur_ls_id == ls_id) { + ls_idx = idx; + break; + } + } + + if (-1 != ls_idx) { + if (OB_FAIL(ls_arr_.remove(ls_idx))) { + DDLOG(ERROR, "remove ls from ls_arr failed", K(ls_idx), K(ls_arr_), K(ls_attr)); + } else { + DDLOG(TRACE, "remove ls from ls_arr finished", K(ls_idx), K(ls_arr_), K(ls_attr)); + } + } + } else {} return ret; diff --git a/src/logservice/leader_coordinator/ob_failure_detector.cpp b/src/logservice/leader_coordinator/ob_failure_detector.cpp index 26a2c5bf8..3f1090233 100644 --- a/src/logservice/leader_coordinator/ob_failure_detector.cpp +++ b/src/logservice/leader_coordinator/ob_failure_detector.cpp @@ -45,8 +45,7 @@ ObFailureDetector::ObFailureDetector() : is_running_(false), coordinator_(nullptr), has_add_clog_hang_event_(false), - has_add_slog_hang_event_(false), - has_add_sstable_hang_event_(false), + has_add_data_disk_hang_event_(false), has_add_clog_full_event_(false), has_schema_error_(false), lock_(common::ObLatchIds::ELECTION_LOCK) @@ -124,8 +123,7 @@ void ObFailureDetector::destroy() { LC_TIME_GUARD(1_s); has_add_clog_hang_event_ = false; - has_add_slog_hang_event_ = false; - has_add_sstable_hang_event_ = false; + has_add_data_disk_hang_event_ = false; has_add_clog_full_event_ = false; has_schema_error_ = false; COORDINATOR_LOG(INFO, "ObFailureDetector mtl destroy"); @@ -162,10 +160,8 @@ void ObFailureDetector::detect_failure() LC_TIME_GUARD(1_s); // clog disk hang check detect_palf_hang_failure_(); - // slog writer hang check - detect_slog_writer_hang_failure_(); - // sstable hang check - detect_sstable_io_failure_(); + // data disk io hang check + detect_data_disk_io_failure_(); // clog disk full check detect_palf_disk_full_(); // schema refreshed check @@ -317,12 +313,9 @@ bool ObFailureDetector::is_clog_disk_has_fatal_error() || ATOMIC_LOAD(&has_add_clog_full_event_); } -bool ObFailureDetector::is_data_disk_has_fatal_error(bool &slog_hang, bool &data_hang) +bool ObFailureDetector::is_data_disk_has_fatal_error() { - ATOMIC_SET(&slog_hang, has_add_slog_hang_event_); - ATOMIC_SET(&data_hang, has_add_sstable_hang_event_); - return ATOMIC_LOAD(&has_add_slog_hang_event_) - || ATOMIC_LOAD(&has_add_sstable_hang_event_); + return ATOMIC_LOAD(&has_add_data_disk_hang_event_); } bool ObFailureDetector::is_schema_not_refreshed() @@ -367,74 +360,38 @@ void ObFailureDetector::detect_palf_hang_failure_() } } -void ObFailureDetector::detect_slog_writer_hang_failure_() -{ - LC_TIME_GUARD(1_s); - int ret = OB_SUCCESS; - bool is_slog_writer_hang = false; - int64_t slog_writer_last_working_time = OB_INVALID_TIMESTAMP; - const int64_t now = ObTimeUtility::current_time(); - ObStorageLogger *storage_logger = MTL(ObStorageLogger*); - FailureEvent slog_writer_hang_event(FailureType::PROCESS_HANG, FailureModule::STORAGE, FailureLevel::FATAL); - if (OB_FAIL(slog_writer_hang_event.set_info("slog writer hang event"))) { - COORDINATOR_LOG(ERROR, "slog_writer_hang_event set_info failed", K(ret)); - } else if (FALSE_IT(slog_writer_last_working_time = storage_logger->get_pwrite_ts())) { - } else if (FALSE_IT(is_slog_writer_hang = (0 != slog_writer_last_working_time - && now - slog_writer_last_working_time > GCONF.data_storage_warning_tolerance_time))) { - } else if (false == ATOMIC_LOAD(&has_add_slog_hang_event_)) { - if (!is_slog_writer_hang) { - // slog writer is normal, skip. - } else if (OB_FAIL(add_failure_event(slog_writer_hang_event))) { - COORDINATOR_LOG(ERROR, "add_failure_event failed", K(ret), K(slog_writer_hang_event)); - } else { - ATOMIC_SET(&has_add_slog_hang_event_, true); - LOG_DBA_ERROR(OB_DISK_HUNG, "msg", "slog writer may be hung, add failure event", K(slog_writer_hang_event), - K(slog_writer_last_working_time), "hung time", now - slog_writer_last_working_time); - } - } else { - if (is_slog_writer_hang) { - // slog writer still hangs, cannot remove failure_event. - } else if (OB_FAIL(remove_failure_event(slog_writer_hang_event))) { - COORDINATOR_LOG(ERROR, "remove_failure_event failed", K(ret), K(slog_writer_hang_event)); - } else { - ATOMIC_SET(&has_add_slog_hang_event_, false); - COORDINATOR_LOG(INFO, "slog writer has recoverd, remove failure event", K(ret), K(slog_writer_hang_event)); - } - } -} - -void ObFailureDetector::detect_sstable_io_failure_() +void ObFailureDetector::detect_data_disk_io_failure_() { LC_TIME_GUARD(1_s); int ret = OB_SUCCESS; ObDeviceHealthStatus data_disk_status; int64_t data_disk_error_start_ts = OB_INVALID_TIMESTAMP; const int64_t now = ObTimeUtility::current_time(); - FailureEvent sstable_io_hang_event(FailureType::PROCESS_HANG, FailureModule::STORAGE, FailureLevel::FATAL); - if (OB_FAIL(sstable_io_hang_event.set_info("sstable io hang event"))) { + FailureEvent data_disk_io_hang_event(FailureType::PROCESS_HANG, FailureModule::STORAGE, FailureLevel::FATAL); + if (OB_FAIL(data_disk_io_hang_event.set_info("data disk io hang event"))) { COORDINATOR_LOG(ERROR, "sstable_io_hang_event set_info failed", K(ret)); } else if (OB_FAIL(OB_IO_MANAGER.get_device_health_detector().get_device_health_status(data_disk_status, data_disk_error_start_ts))) { COORDINATOR_LOG(WARN, "get_device_health_status failed", K(ret)); - } else if (false == ATOMIC_LOAD(&has_add_sstable_hang_event_)) { + } else if (false == ATOMIC_LOAD(&has_add_data_disk_hang_event_)) { // TODO: modify statement if new ObDeviceHealthStatus is added if (ObDeviceHealthStatus::DEVICE_HEALTH_NORMAL == data_disk_status) { // data disk does not hang, skip. - } else if (OB_FAIL(add_failure_event(sstable_io_hang_event))) { - COORDINATOR_LOG(ERROR, "add_failure_event failed", K(ret), K(sstable_io_hang_event)); + } else if (OB_FAIL(add_failure_event(data_disk_io_hang_event))) { + COORDINATOR_LOG(ERROR, "add_failure_event failed", K(ret), K(data_disk_io_hang_event)); } else { - ATOMIC_SET(&has_add_sstable_hang_event_, true); - LOG_DBA_ERROR(OB_DISK_HUNG, "msg", "data disk may be hung, add failure event", K(sstable_io_hang_event), + ATOMIC_SET(&has_add_data_disk_hang_event_, true); + LOG_DBA_ERROR(OB_DISK_HUNG, "msg", "data disk may be hung, add failure event", K(data_disk_io_hang_event), K(data_disk_error_start_ts)); } } else { if (ObDeviceHealthStatus::DEVICE_HEALTH_NORMAL != data_disk_status) { // data disk does not recoverd, cannot remove failure_event. - } else if (OB_FAIL(remove_failure_event(sstable_io_hang_event))) { - COORDINATOR_LOG(ERROR, "remove_failure_event failed", K(ret), K(sstable_io_hang_event)); + } else if (OB_FAIL(remove_failure_event(data_disk_io_hang_event))) { + COORDINATOR_LOG(ERROR, "remove_failure_event failed", K(ret), K(data_disk_io_hang_event)); } else { - ATOMIC_SET(&has_add_sstable_hang_event_, false); - COORDINATOR_LOG(INFO, "data disk has recoverd, remove failure event", K(ret), K(sstable_io_hang_event)); + ATOMIC_SET(&has_add_data_disk_hang_event_, false); + COORDINATOR_LOG(INFO, "data disk has recoverd, remove failure event", K(ret), K(data_disk_io_hang_event)); } } } diff --git a/src/logservice/leader_coordinator/ob_failure_detector.h b/src/logservice/leader_coordinator/ob_failure_detector.h index 259eacdda..434cff861 100644 --- a/src/logservice/leader_coordinator/ob_failure_detector.h +++ b/src/logservice/leader_coordinator/ob_failure_detector.h @@ -92,14 +92,13 @@ public: */ void detect_failure(); bool is_clog_disk_has_fatal_error(); - bool is_data_disk_has_fatal_error(bool &slog_hang, bool &data_hang); + bool is_data_disk_has_fatal_error(); bool is_schema_not_refreshed(); private: bool check_is_running_() const { return is_running_; } int insert_event_to_table_(const FailureEvent &event, const ObFunction &recover_operation, ObString info); void detect_palf_hang_failure_(); - void detect_slog_writer_hang_failure_(); - void detect_sstable_io_failure_(); + void detect_data_disk_io_failure_(); void detect_palf_disk_full_(); void detect_schema_not_refreshed_(); private: @@ -117,8 +116,7 @@ private: common::ObOccamTimerTaskRAIIHandle recovery_task_handle_; ObLeaderCoordinator *coordinator_; bool has_add_clog_hang_event_; - bool has_add_slog_hang_event_; - bool has_add_sstable_hang_event_; + bool has_add_data_disk_hang_event_; bool has_add_clog_full_event_; bool has_schema_error_; ObSpinLock lock_; diff --git a/src/logservice/libobcdc/src/ob_cdc_multi_data_source_info.cpp b/src/logservice/libobcdc/src/ob_cdc_multi_data_source_info.cpp index 5c0213b9d..c2ae112ec 100644 --- a/src/logservice/libobcdc/src/ob_cdc_multi_data_source_info.cpp +++ b/src/logservice/libobcdc/src/ob_cdc_multi_data_source_info.cpp @@ -52,7 +52,7 @@ int MultiDataSourceNode::init( common::ObString data; data.assign_ptr(reinterpret_cast(buf), buf_size); - if (OB_FAIL(tx_buf_node_.init(type, data))) { + if (OB_FAIL(tx_buf_node_.init(type, data, share::SCN(), nullptr))) { LOG_ERROR("init tx_buf_node failed", KR(ret), K(lsn), K(type), K(data), K(buf_size)); } } @@ -67,8 +67,7 @@ void MultiDataSourceNode::reset() } MultiDataSourceInfo::MultiDataSourceInfo() : - has_ls_table_op_(false), - ls_attr_(), + ls_attr_arr_(), tablet_change_info_arr_(), has_ddl_trans_op_(false), dict_tenant_metas_(), @@ -78,8 +77,7 @@ MultiDataSourceInfo::MultiDataSourceInfo() : void MultiDataSourceInfo::reset() { - has_ls_table_op_ = false; - ls_attr_.reset(); + ls_attr_arr_.reset(); tablet_change_info_arr_.reset(); has_ddl_trans_op_ = false; dict_tenant_metas_.reset(); @@ -87,6 +85,20 @@ void MultiDataSourceInfo::reset() dict_table_metas_.reset(); } +int MultiDataSourceInfo::push_back_ls_table_op(const share::ObLSAttr &ls_attr) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(! ls_attr.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid ls_attr in multi_data_source_log", KR(ret), K(ls_attr), KPC(this)); + } else if (OB_FAIL(ls_attr_arr_.push_back(ls_attr))) { + LOG_ERROR("push_back ls_attr into multi_data_source_info failed", KR(ret), K(ls_attr), KPC(this)); + } + + return ret; +} + int MultiDataSourceInfo::push_back_tablet_change_info(const ObCDCTabletChangeInfo &tablet_change_info) { int ret = OB_SUCCESS; @@ -106,8 +118,8 @@ int64_t MultiDataSourceInfo::to_string(char *buf, const int64_t buf_len) const int64_t pos = 0; if (NULL != buf && buf_len > 0) { - if (has_ls_table_op_) { - (void)common::databuff_printf(buf, buf_len, pos, "{ls_table_op: %s", to_cstring(ls_attr_)); + if (has_ls_table_op()) { + (void)common::databuff_printf(buf, buf_len, pos, "{ls_table_op: %s", to_cstring(ls_attr_arr_)); } else { (void)common::databuff_printf(buf, buf_len, pos, "has_ls_table_op: false"); } diff --git a/src/logservice/libobcdc/src/ob_cdc_multi_data_source_info.h b/src/logservice/libobcdc/src/ob_cdc_multi_data_source_info.h index 601635955..71c0e5c64 100644 --- a/src/logservice/libobcdc/src/ob_cdc_multi_data_source_info.h +++ b/src/logservice/libobcdc/src/ob_cdc_multi_data_source_info.h @@ -52,8 +52,8 @@ public: inline bool is_tablet_change_node() const { - return transaction::ObTxDataSourceType::CREATE_TABLET == tx_buf_node_.get_data_source_type() - || transaction::ObTxDataSourceType::REMOVE_TABLET == tx_buf_node_.get_data_source_type(); + return transaction::ObTxDataSourceType::CREATE_TABLET_NEW_MDS == tx_buf_node_.get_data_source_type() + || transaction::ObTxDataSourceType::DELETE_TABLET_NEW_MDS == tx_buf_node_.get_data_source_type(); } inline bool is_ddl_trans_node() const @@ -82,16 +82,15 @@ public: ~MultiDataSourceInfo() { reset(); } void reset(); public: - bool is_valid() const { return has_ls_table_op_ || has_ddl_trans_op_ || ls_attr_.is_valid(); } - void set_has_ls_table_op() { has_ls_table_op_ = true; } - bool has_ls_table_op() const { return has_ls_table_op_; } - const share::ObLSAttr &get_ls_attr() const { return ls_attr_; } - share::ObLSAttr &get_ls_attr() { return ls_attr_; } // used to deserialize ls_attr_; + OB_INLINE bool is_valid() const { return has_ls_table_op() || has_tablet_change_op() || has_ddl_trans_op_; } + OB_INLINE bool has_ls_table_op() const { return 0 < ls_attr_arr_.count(); } + const share::ObLSAttrArray &get_ls_attr_arr() const { return ls_attr_arr_; } + int push_back_ls_table_op(const share::ObLSAttr &ls_attr); bool has_tablet_change_op() const { return 0 < tablet_change_info_arr_.count(); } int push_back_tablet_change_info(const ObCDCTabletChangeInfo &tablet_change_info); const CDCTabletChangeInfoArray &get_tablet_change_info_arr() const { return tablet_change_info_arr_; } - void set_ddl_trans() { has_ddl_trans_op_ = true; } - bool is_ddl_trans() const { return has_ddl_trans_op_; } + void set_ddl_trans() { ATOMIC_SET(&has_ddl_trans_op_, true); } + bool is_ddl_trans() const { return ATOMIC_LOAD(&has_ddl_trans_op_); } DictTenantArray &get_dict_tenant_array() { return dict_tenant_metas_; } DictDatabaseArray &get_dict_database_array() { return dict_database_metas_; } DictTableArray &get_dict_table_array() { return dict_table_metas_; } @@ -111,10 +110,9 @@ public: int64_t to_string(char *buf, const int64_t buf_len) const; private: - bool has_ls_table_op_; // ls change op(create/delete logstream), parse from ObTxBufferNode(LS_TABLE type) in commit_log - share::ObLSAttr ls_attr_; - // tablet_change_op(create/delete tabelt), parse from MultiDataSourceNode. + share::ObLSAttrArray ls_attr_arr_; + // tablet_change_op(create/delete tablet), parse from MultiDataSourceNode. CDCTabletChangeInfoArray tablet_change_info_arr_; // ddl_trans_info(incremental schema info) diff --git a/src/logservice/libobcdc/src/ob_cdc_part_trans_resolver.cpp b/src/logservice/libobcdc/src/ob_cdc_part_trans_resolver.cpp index 485600c04..fbeaede64 100644 --- a/src/logservice/libobcdc/src/ob_cdc_part_trans_resolver.cpp +++ b/src/logservice/libobcdc/src/ob_cdc_part_trans_resolver.cpp @@ -743,8 +743,6 @@ int ObCDCPartTransResolver::handle_commit_( } else if (OB_FAIL(obtain_task_(tx_id, part_trans_task, is_resolving_miss_log))) { LOG_ERROR("obtain_part_trans_task fail while reading commit log", KR(ret), K_(tls_id), K(tx_id), K(lsn), K(commit_log), K(missing_info)); - } else if (OB_FAIL(part_trans_task->push_multi_data_source_data(lsn, commit_log.get_multi_source_data(), true/*is_commit_log*/))) { - LOG_ERROR("push_multi_data_source_data failed", KR(ret), K_(tls_id), K(tx_id), K(lsn), K(commit_log), KPC(part_trans_task)); // TODO 下面是否检查sys日志流里非DDL/非LS_TABLE的事务? } else if (!part_trans_task->has_read_commit_info()) { if (is_resolving_miss_log) { diff --git a/src/logservice/libobcdc/src/ob_cdc_tablet_to_table_info.cpp b/src/logservice/libobcdc/src/ob_cdc_tablet_to_table_info.cpp index 374aa1a7a..8548bae9e 100644 --- a/src/logservice/libobcdc/src/ob_cdc_tablet_to_table_info.cpp +++ b/src/logservice/libobcdc/src/ob_cdc_tablet_to_table_info.cpp @@ -87,7 +87,7 @@ int ObCDCTabletChangeInfo::parse_from_multi_data_source_buf( LOG_ERROR("invalid buf to deserialize", KR(ret), K(tls_id), K(buf_len)); } else { switch (mds_type) { - case transaction::ObTxDataSourceType::CREATE_TABLET: + case transaction::ObTxDataSourceType::CREATE_TABLET_NEW_MDS: { obrpc::ObBatchCreateTabletArg create_tablet_arg; if (OB_FAIL(create_tablet_arg.deserialize(buf, buf_len, pos))) { @@ -99,7 +99,7 @@ int ObCDCTabletChangeInfo::parse_from_multi_data_source_buf( } break; } - case transaction::ObTxDataSourceType::REMOVE_TABLET: + case transaction::ObTxDataSourceType::DELETE_TABLET_NEW_MDS: { obrpc::ObBatchRemoveTabletArg remove_tablet_arg; diff --git a/src/logservice/libobcdc/src/ob_log_ls_op_processor.cpp b/src/logservice/libobcdc/src/ob_log_ls_op_processor.cpp index 646457831..7f381f0d7 100644 --- a/src/logservice/libobcdc/src/ob_log_ls_op_processor.cpp +++ b/src/logservice/libobcdc/src/ob_log_ls_op_processor.cpp @@ -38,20 +38,21 @@ int ObLogLSOpProcessor::process_ls_op( } else if (OB_ISNULL(tenant = guard.get_tenant())) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("get tenant fail, tenant is NULL", KR(ret), K(tenant_id)); - } else if (share::is_ls_create_pre_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_create_pre_op(ls_attr.get_ls_operation_type())) { LOG_INFO("[LS_PROCESSOR] ls create pre operation", K(tenant_id), K(lsn), K(start_tstamp_ns), K(ls_attr)); - } else if (share::is_ls_create_end_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_create_end_op(ls_attr.get_ls_operation_type())) { LOG_INFO("[LS_PROCESSOR] ls create end operation", K(tenant_id), K(lsn), K(start_tstamp_ns), K(ls_attr)); //create new ls; if (OB_FAIL(create_new_ls_(tenant, start_tstamp_ns, ls_attr))) { LOG_ERROR("failed to create new ls", KR(ret), K(tenant_id), K(lsn), K(start_tstamp_ns), K(ls_attr)); } - } else if (share::is_ls_create_abort_op(ls_attr.get_ls_operatin_type())) { - } else if (share::is_ls_drop_pre_op(ls_attr.get_ls_operatin_type())) { - } else if (share::is_ls_drop_end_op(ls_attr.get_ls_operatin_type())) { - } else if (share::is_ls_tenant_drop_pre_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_create_abort_op(ls_attr.get_ls_operation_type())) { + } else if (share::is_ls_drop_pre_op(ls_attr.get_ls_operation_type())) { + } else if (share::is_ls_drop_end_op(ls_attr.get_ls_operation_type())) { + } else if (share::is_ls_tenant_drop_pre_op(ls_attr.get_ls_operation_type())) { //only sys ls - } else if (share::is_ls_tenant_drop_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_tenant_drop_op(ls_attr.get_ls_operation_type())) { + } else if (share::is_ls_alter_ls_group_op(ls_attr.get_ls_operation_type())) { } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected operation type", KR(ret), K(tenant_id), K(lsn), K(start_tstamp_ns), K(ls_attr)); diff --git a/src/logservice/libobcdc/src/ob_log_meta_data_replayer.cpp b/src/logservice/libobcdc/src/ob_log_meta_data_replayer.cpp index 4787d785f..6fb243c71 100644 --- a/src/logservice/libobcdc/src/ob_log_meta_data_replayer.cpp +++ b/src/logservice/libobcdc/src/ob_log_meta_data_replayer.cpp @@ -119,6 +119,8 @@ int ObLogMetaDataReplayer::replay( if (OB_FAIL(handle_ls_op_trans_(start_timestamp_ns, tenant_info, *part_trans_task, replay_info_stat))) { LOG_ERROR("handle_ls_op_trans_ failed", KR(ret), K(tenant_id), K(start_timestamp_ns), K(tenant_info), KPC(part_trans_task)); + } else { + LOG_TRACE("handle_ls_op_trans_ succ", K(tenant_id), KPC(part_trans_task), K(tenant_info)); } } else if (part_trans_task->is_offline_ls_task()) { is_done = true; @@ -200,12 +202,28 @@ int ObLogMetaDataReplayer::handle_ls_op_trans_( ret = OB_ERR_UNEXPECTED; LOG_ERROR("PartTransTask is not ls op trans, unexpected", KR(ret), K(part_trans_task)); } else { + const int64_t part_trans_commit_version = part_trans_task.get_trans_commit_version(); replay_info_stat.ls_op_part_trans_task_count_++; - const share::ObLSAttr &ls_atrr = part_trans_task.get_ls_attr(); - - if (OB_FAIL(tenant_info.incremental_data_update(ls_atrr))) { - LOG_ERROR("tenant_info incremental_data_update failed", KR(ret), K(part_trans_task), K(tenant_info), - K(ls_atrr)); + const share::ObLSAttrArray &ls_attr_arr = part_trans_task.get_ls_attr_arr(); + int64_t idx = 0; + int64_t ls_attr_cnt = 0; + if (part_trans_commit_version <= start_timestamp_ns) { + ARRAY_FOREACH_N(ls_attr_arr, idx, ls_attr_cnt) + { + const share::ObLSAttr &ls_attr = ls_attr_arr.at(idx); + if (OB_UNLIKELY(! ls_attr.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls_attr is not valid", KR(ret), K(idx), K(ls_attr_cnt), K(ls_attr), K(ls_attr_arr)); + } else if (OB_FAIL(tenant_info.incremental_data_update(ls_attr))) { + LOG_ERROR("tenant_info incremental_data_update failed", KR(ret), K(part_trans_task), K(tenant_info), + K(idx), K(ls_attr), K(ls_attr_cnt), K(ls_attr_arr)); + } + } + } else { + ISTAT("ignore LS_OP_TRANS PartTransTask which trans commit verison is greater than start_timestamp_ns", + "tenant_id", part_trans_task.get_tenant_id(), + "trans_id", part_trans_task.get_trans_id(), + K(ls_attr_arr), K(part_trans_commit_version), K(start_timestamp_ns)); } } diff --git a/src/logservice/libobcdc/src/ob_log_part_trans_task.cpp b/src/logservice/libobcdc/src/ob_log_part_trans_task.cpp index 3caad86a6..2e379f96c 100644 --- a/src/logservice/libobcdc/src/ob_log_part_trans_task.cpp +++ b/src/logservice/libobcdc/src/ob_log_part_trans_task.cpp @@ -2463,8 +2463,8 @@ int PartTransTask::push_multi_data_source_data( } break; } - case transaction::ObTxDataSourceType::CREATE_TABLET: - case transaction::ObTxDataSourceType::REMOVE_TABLET: + case transaction::ObTxDataSourceType::CREATE_TABLET_NEW_MDS: + case transaction::ObTxDataSourceType::DELETE_TABLET_NEW_MDS: { if (! is_commit_log) { if (OB_FAIL(alloc_and_save_multi_data_source_node_(lsn, mds_buffer_node))) { @@ -2475,20 +2475,22 @@ int PartTransTask::push_multi_data_source_data( } case transaction::ObTxDataSourceType::LS_TABLE: { - if (is_commit_log) { + // only push_back ls_op in multi_data_source_log, in case of reentrant of commit_log + // while handling miss_log. + if (! is_commit_log) { int64_t pos = 0; - share::ObLSAttr &ls_attr = multi_data_source_info_.get_ls_attr(); + share::ObLSAttr ls_attr;; if (OB_FAIL(ls_attr.deserialize(data.ptr(), data_buf_size, pos))) { LOG_ERROR("deserialize ls_table_op failed", KR(ret), K_(tls_id), K_(trans_id), K(lsn), K(mds_buffer_node), K(ls_attr)); + } else if (OB_FAIL(multi_data_source_info_.push_back_ls_table_op(ls_attr))) { + LOG_ERROR("push_back ls_table_op info multi_data_source_info failed", KR(ret), + K_(tls_id), K_(trans_id), K(lsn), K(mds_buffer_node), K(ls_attr)); + } else { + LOG_INFO("resolver found ls_attr in multi_data_source log", K_(tls_id), K_(trans_id), K(lsn), + K(mds_buffer_node), K(ls_attr)); } - } else if (multi_data_source_info_.has_ls_table_op()) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("expect at most one ls_table_op per trans", KR(ret), K_(tls_id), K_(trans_id), K(lsn), - K(mds_buffer_node), K_(multi_data_source_info)); - } else { - multi_data_source_info_.set_has_ls_table_op(); } break; } @@ -2975,32 +2977,42 @@ int PartTransTask::commit( type_ = TASK_TYPE_DDL_TRANS; } else if (multi_data_source_info_.has_ls_table_op()) { type_ = TASK_TYPE_LS_OP_TRANS; - const share::ObLSAttr &ls_attr = multi_data_source_info_.get_ls_attr();; + int64_t idx = 0; + int64_t ls_attr_cnt = 0; + const share::ObLSAttrArray &ls_attr_arr = multi_data_source_info_.get_ls_attr_arr();; - if (OB_UNLIKELY(! ls_attr.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("ls_attr from multi_data_source is not valid", KR(ret), K(ls_attr), KPC(this)); - } else if (OB_FAIL(ObLogLSOpProcessor::process_ls_op(tls_id_.get_tenant_id(), commit_log_lsn, commit_log_submit_ts, - ls_attr))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_ERROR("ObLogLSOpProcessor process_ls_op failed", KR(ret), K(tls_id_), K(tx_id), K(commit_log_lsn), - K(commit_log_submit_ts), K(ls_attr)); - } else { - if (is_data_dict_mode) { - // In Data dictionary, it need to fetch the log of the baseline data dict before adding a tenant, - // and if it encounter a log stream operation in the process of building the data dictionary, - // it need to ignore it and rely on the incremental replay process of the data dictionary. - ret = OB_SUCCESS; - LOG_INFO("ObLogLSOpProcessor process_ls_op when tenant is not exist", KR(ret), K(tls_id_), K(tx_id), K(commit_log_lsn), - K(commit_log_submit_ts), K(ls_attr)); - } else { + ARRAY_FOREACH_N(ls_attr_arr, idx, ls_attr_cnt) + { + const share::ObLSAttr &ls_attr = ls_attr_arr.at(idx); + + if (OB_UNLIKELY(! ls_attr.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls_attr from multi_data_source is not valid", KR(ret), K(idx), K(ls_attr_cnt), K(ls_attr), K(ls_attr_arr), KPC(this)); + } else if (OB_FAIL(ObLogLSOpProcessor::process_ls_op( + tls_id_.get_tenant_id(), + commit_log_lsn, + commit_log_submit_ts, + ls_attr))) { + if (OB_ENTRY_NOT_EXIST != ret) { LOG_ERROR("ObLogLSOpProcessor process_ls_op failed", KR(ret), K(tls_id_), K(tx_id), K(commit_log_lsn), K(commit_log_submit_ts), K(ls_attr)); + } else { + if (is_data_dict_mode) { + // In Data dictionary, it need to fetch the log of the baseline data dict before adding a tenant, + // and if it encounter a log stream operation in the process of building the data dictionary, + // it need to ignore it and rely on the incremental replay process of the data dictionary. + ret = OB_SUCCESS; + LOG_INFO("ObLogLSOpProcessor process_ls_op when tenant is not exist", KR(ret), K(tls_id_), K(tx_id), K(commit_log_lsn), + K(commit_log_submit_ts), K(ls_attr)); + } else { + LOG_ERROR("ObLogLSOpProcessor process_ls_op failed", KR(ret), K(tls_id_), K(tx_id), K(commit_log_lsn), + K(commit_log_submit_ts), K(ls_attr), K(idx), K(ls_attr_arr)); + } } + } else { + LOG_INFO("ObLogLSOpProcessor process_ls_op succ", K(tls_id_), K(tx_id), K(commit_log_lsn), + K(commit_log_submit_ts), K(ls_attr), K(idx), K(ls_attr_arr)); } - } else { - LOG_INFO("ObLogLSOpProcessor process_ls_op succ", K(tls_id_), K(tx_id), K(commit_log_lsn), - K(commit_log_submit_ts), K(ls_attr)); } } else { ret = OB_NOT_SUPPORTED; diff --git a/src/logservice/libobcdc/src/ob_log_part_trans_task.h b/src/logservice/libobcdc/src/ob_log_part_trans_task.h index a5da83f35..371f87147 100644 --- a/src/logservice/libobcdc/src/ob_log_part_trans_task.h +++ b/src/logservice/libobcdc/src/ob_log_part_trans_task.h @@ -1113,7 +1113,7 @@ public: return tls_id_.is_sys_log_stream() && ! multi_data_source_info_.is_valid(); } const MultiDataSourceInfo &get_multi_data_source_info() const { return multi_data_source_info_; } - const share::ObLSAttr &get_ls_attr() const { return multi_data_source_info_.get_ls_attr(); } + const share::ObLSAttrArray &get_ls_attr_arr() const { return multi_data_source_info_.get_ls_attr_arr(); } DictTenantArray &get_dict_tenant_array() { return multi_data_source_info_.get_dict_tenant_array(); } DictDatabaseArray &get_dict_database_array() { return multi_data_source_info_.get_dict_database_array(); } DictTableArray &get_dict_table_array() { return multi_data_source_info_.get_dict_table_array(); } diff --git a/src/logservice/logfetcher/ob_log_fetcher.cpp b/src/logservice/logfetcher/ob_log_fetcher.cpp old mode 100644 new mode 100755 diff --git a/src/logservice/logrouteservice/ob_log_route_service.cpp b/src/logservice/logrouteservice/ob_log_route_service.cpp old mode 100644 new mode 100755 index 4760ea020..0b28b8cd7 --- a/src/logservice/logrouteservice/ob_log_route_service.cpp +++ b/src/logservice/logrouteservice/ob_log_route_service.cpp @@ -29,7 +29,7 @@ ObLogRouteService::ObLogRouteService() : is_inited_(false), cluster_id_(OB_INVALID_CLUSTER_ID), is_tenant_mode_(false), - tenant_id_(OB_INVALID_TENANT_ID), + source_tenant_id_(OB_INVALID_TENANT_ID), is_stopped_(true), ls_route_key_set_(), ls_router_map_(), @@ -114,7 +114,7 @@ int ObLogRouteService::init(ObISQLClient *proxy, LOG_WARN("TG_SET_HANDLER_AND_START failed", KR(ret), K(tg_id_)); } else { cluster_id_ = cluster_id; - tenant_id_ = tenant_id; + source_tenant_id_ = tenant_id; log_router_allocator_.set_nway(NWAY); asyn_task_allocator_.set_nway(NWAY); timer_id_ = lib::TGDefIDs::LogRouterTimer; @@ -133,7 +133,8 @@ int ObLogRouteService::init(ObISQLClient *proxy, LOG_WARN("update_all_server_and_zone_cache_ failed, will retry", K(tmp_ret)); } - LOG_INFO("ObLogRouteService init succ", K(cluster_id), K(is_tenant_mode), K(prefer_region), K(is_across_cluster), + LOG_INFO("ObLogRouteService init succ", K(cluster_id), K(is_tenant_mode), K(source_tenant_id_), + K(prefer_region), K(is_across_cluster), K(timer_id_), K(tg_id_)); } @@ -204,7 +205,7 @@ void ObLogRouteService::destroy() err_handler_ = NULL; cluster_id_ = OB_INVALID_CLUSTER_ID; - tenant_id_ = OB_INVALID_TENANT_ID; + source_tenant_id_ = OB_INVALID_TENANT_ID; background_refresh_time_sec_ = 0; blacklist_survival_time_sec_ = 0; blacklist_survival_time_upper_limit_min_ = 0; @@ -917,7 +918,7 @@ int ObLogRouteService::update_server_list_( ls_log_info))) { LOG_WARN("ObLogSysTableQueryer get_ls_log_info failed", KR(ret), K(router_key)); } else { - LOG_DEBUG("get_ls_log_info succ", K(router_key), K(ls_log_info)); + LOG_DEBUG("get_ls_log_info success", K(router_key), K(ls_log_info)); // Add Lock to update ObByteLockGuard guard(router_value.get_lock()); const ObLSLogInfo::LogStatRecordArray &log_stat_records = ls_log_info.get_log_stat_array(); @@ -937,6 +938,16 @@ int ObLogRouteService::update_server_list_( } else {} } // ARRAY_FOREACH_N + // 1. Log Stream quickly GC in the transfer scenario, so the Log Stream can not get server list from GV$OB_LOG_STAT + // 2. We employ the complementary mechanism of querying the server list from GV$OB_UNITS + if (OB_SUCC(ret)) { + if (ls_svr_list.count() <= 0) { + if (OB_FAIL(query_units_info_and_update_(router_key, router_value))) { + LOG_WARN("query_units_info_and_update_ failed", KR(ret), K(router_key)); + } + } + } + if (OB_SUCC(ret)) { // Sort by Fetch log priority when add_server_or_update completed ls_svr_list.sort_by_priority(); @@ -971,6 +982,46 @@ int ObLogRouteService::update_server_list_( return ret; } +int ObLogRouteService::query_units_info_and_update_( + const ObLSRouterKey &router_key, + ObLSRouterValue &router_value) +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_ERROR("ObLogRouteService has not been inited", KR(ret)); + } else { + LSSvrList &ls_svr_list = router_value.get_ls_svr_list(); + ObUnitsRecordInfo units_record_info; + + if (OB_FAIL(systable_queryer_.get_all_units_info(source_tenant_id_, units_record_info))) { + if (OB_NEED_RETRY == ret) { + LOG_WARN("query the GV$OB_UNITS failed, need retry", KR(ret)); + ret = OB_SUCCESS; + } else { + LOG_ERROR("query the GV$OB_UNITS failed", KR(ret)); + } + } else { + ObUnitsRecordInfo::ObUnitsRecordArray &units_record_array = units_record_info.get_units_record_array(); + + ARRAY_FOREACH_N(units_record_array, idx, count) { + ObUnitsRecord &record = units_record_array.at(idx); + ObAddr &server = record.server_; + RegionPriority region_priority = REGION_PRIORITY_UNKNOWN; + + if (OB_FAIL(ls_svr_list.add_server_or_update(server, + palf::LSN(0), palf::LSN(palf::LOG_MAX_LSN_VAL), region_priority, false/*is_leader*/))) { + LOG_WARN("ObLogRouteService add_server_or_update failed", KR(ret), K(router_key), + K(router_value)); + } + } + } + } + + return ret; +} + int ObLogRouteService::update_all_server_and_zone_cache_() { int ret = OB_SUCCESS; diff --git a/src/logservice/logrouteservice/ob_log_route_service.h b/src/logservice/logrouteservice/ob_log_route_service.h old mode 100644 new mode 100755 index 57fa51017..b459bdded --- a/src/logservice/logrouteservice/ob_log_route_service.h +++ b/src/logservice/logrouteservice/ob_log_route_service.h @@ -286,6 +286,10 @@ private: int update_server_list_( const ObLSRouterKey &router_key, ObLSRouterValue &router_value); + // query the GV$OB_UNITS + int query_units_info_and_update_( + const ObLSRouterKey &router_key, + ObLSRouterValue &router_value); int update_all_server_and_zone_cache_(); void free_mem_(); @@ -353,7 +357,7 @@ private: bool is_inited_; int64_t cluster_id_; bool is_tenant_mode_; - uint64_t tenant_id_; + int64_t source_tenant_id_; volatile bool is_stopped_ CACHE_ALIGNED; LSRouteKeySet ls_route_key_set_; LSRouterMap ls_router_map_; diff --git a/src/logservice/logrouteservice/ob_ls_server_list.cpp b/src/logservice/logrouteservice/ob_ls_server_list.cpp index 325f79f28..8547ac1d6 100644 --- a/src/logservice/logrouteservice/ob_ls_server_list.cpp +++ b/src/logservice/logrouteservice/ob_ls_server_list.cpp @@ -368,7 +368,7 @@ int LSSvrList::get_next_server_based_on_blacklist_(const palf::LSN &next_lsn, int64_t LSSvrList::LSNRange::to_string(char *buffer, int64_t length) const { int64_t pos = 0; - (void)databuff_printf(buffer, length, pos, "LSN:{%ld, %ld}", + (void)databuff_printf(buffer, length, pos, "LSN:{%lu, %lu}", start_lsn_.val_, end_lsn_.val_); return pos; diff --git a/src/logservice/logrpc/ob_log_request_handler.cpp b/src/logservice/logrpc/ob_log_request_handler.cpp old mode 100644 new mode 100755 index e5d4c67b2..05aeae60b --- a/src/logservice/logrpc/ob_log_request_handler.cpp +++ b/src/logservice/logrpc/ob_log_request_handler.cpp @@ -149,7 +149,7 @@ int LogRequestHandler::handle_sync_requestadd_member(req.added_member_, req.new_replica_num_, req.timeout_us_); - break; + ret = palf_handle_->add_member(req.added_member_, req.new_replica_num_, req.config_version_, req.timeout_us_); break; case REMOVE_MEMBER_CMD: - ret = palf_handle_->remove_member(req.removed_member_, req.new_replica_num_, - req.timeout_us_); + ret = palf_handle_->remove_member(req.removed_member_, req.new_replica_num_, req.timeout_us_); break; case REPLACE_MEMBER_CMD: - ret = palf_handle_->replace_member(req.added_member_, req.removed_member_, req.timeout_us_); + ret = palf_handle_->replace_member(req.added_member_, req.removed_member_, req.config_version_, req.timeout_us_); break; case ADD_LEARNER_CMD: ret = palf_handle_->add_learner(req.added_member_, req.timeout_us_); @@ -279,15 +278,25 @@ int ConfigChangeCmdHandler::handle_config_change_cmd(const LogConfigChangeCmd &r ret = palf_handle_->remove_learner(req.removed_member_, req.timeout_us_); break; case SWITCH_TO_ACCEPTOR_CMD: - ret = palf_handle_->switch_learner_to_acceptor(req.removed_member_, req.new_replica_num_, req.timeout_us_); + ret = palf_handle_->switch_learner_to_acceptor(req.added_member_, req.new_replica_num_, req.config_version_, req.timeout_us_); break; case SWITCH_TO_LEARNER_CMD: ret = palf_handle_->switch_acceptor_to_learner(req.removed_member_, req.new_replica_num_, req.timeout_us_); break; + case TRY_LOCK_CONFIG_CHANGE_CMD: + ret = palf_handle_->try_lock_config_change(req.lock_owner_, req.timeout_us_); + break; + case UNLOCK_CONFIG_CHANGE_CMD: + ret = palf_handle_->unlock_config_change(req.lock_owner_, req.timeout_us_); + break; + case GET_CONFIG_CHANGE_LOCK_STAT_CMD: + ret = palf_handle_->get_config_change_lock_stat(resp.lock_owner_, resp.is_locked_); + break; default: break; } } + resp.ret_ = ret; if (OB_SUCC(ret) && OB_FAIL(reporter->report_replica_info(req.palf_id_))) { CLOG_LOG(WARN, "report_replica_info failed", K(ret), K(req.palf_id_), K(req)); } diff --git a/src/logservice/logrpc/ob_log_request_handler.h b/src/logservice/logrpc/ob_log_request_handler.h index 611132ecf..3c65f5d11 100644 --- a/src/logservice/logrpc/ob_log_request_handler.h +++ b/src/logservice/logrpc/ob_log_request_handler.h @@ -68,7 +68,8 @@ public: { palf_handle_ = NULL; } - int handle_config_change_cmd(const LogConfigChangeCmd &req) const; + int handle_config_change_cmd(const LogConfigChangeCmd &req, + LogConfigChangeCmdResp &resp) const; private: int get_reporter_(ObLogReporterAdapter *&reporter) const; private: diff --git a/src/logservice/logrpc/ob_log_rpc_req.cpp b/src/logservice/logrpc/ob_log_rpc_req.cpp index 712ef2b68..9f2c9b471 100644 --- a/src/logservice/logrpc/ob_log_rpc_req.cpp +++ b/src/logservice/logrpc/ob_log_rpc_req.cpp @@ -11,6 +11,7 @@ */ #include "ob_log_rpc_req.h" +#include "logservice/palf/log_define.h" namespace oceanbase { @@ -28,7 +29,9 @@ LogConfigChangeCmd::LogConfigChangeCmd() curr_replica_num_(0), new_replica_num_(0), cmd_type_(INVALID_CONFIG_CHANGE_CMD), - timeout_us_(0) { } + timeout_us_(0), + lock_owner_(palf::OB_INVALID_CONFIG_CHANGE_LOCK_OWNER), + config_version_() { } LogConfigChangeCmd::LogConfigChangeCmd( const common::ObAddr &src, @@ -46,7 +49,9 @@ LogConfigChangeCmd::LogConfigChangeCmd( curr_replica_num_(), new_replica_num_(new_replica_num), cmd_type_(cmd_type), - timeout_us_(timeout_us) { } + timeout_us_(timeout_us), + lock_owner_(palf::OB_INVALID_CONFIG_CHANGE_LOCK_OWNER), + config_version_() { } LogConfigChangeCmd::LogConfigChangeCmd( const common::ObAddr &src, @@ -64,13 +69,36 @@ LogConfigChangeCmd::LogConfigChangeCmd( curr_replica_num_(curr_replica_num), new_replica_num_(new_replica_num), cmd_type_(cmd_type), - timeout_us_(timeout_us) { } + timeout_us_(timeout_us), + lock_owner_(palf::OB_INVALID_CONFIG_CHANGE_LOCK_OWNER), + config_version_() { } + +LogConfigChangeCmd::LogConfigChangeCmd(const common::ObAddr &src, + const int64_t palf_id, + const int64_t lock_owner, + const LogConfigChangeCmdType cmd_type, + const int64_t timeout_us) + : src_(src), + palf_id_(palf_id), + added_member_(), + removed_member_(), + curr_member_list_(), + curr_replica_num_(0), + new_replica_num_(0), + cmd_type_(cmd_type), + timeout_us_(timeout_us), + lock_owner_(lock_owner){} LogConfigChangeCmd::~LogConfigChangeCmd() { reset(); } +void LogConfigChangeCmd::in_leader(const palf::LogConfigVersion &config_version) +{ + config_version_ = config_version; +} + bool LogConfigChangeCmd::is_valid() const { bool bool_ret = false; @@ -82,7 +110,9 @@ bool LogConfigChangeCmd::is_valid() const SWITCH_TO_ACCEPTOR_CMD == cmd_type_)? removed_member_.is_valid(): true); bool_ret = bool_ret && ((is_set_new_replica_num())? is_valid_replica_num(new_replica_num_): true); bool_ret = bool_ret && ((CHANGE_REPLICA_NUM_CMD == cmd_type_)? curr_member_list_.is_valid() \ - && is_valid_replica_num(curr_replica_num_) && is_valid_replica_num(new_replica_num_): true); + && is_valid_replica_num(curr_replica_num_) && is_valid_replica_num(new_replica_num_): true);\ + bool_ret = bool_ret && ((TRY_LOCK_CONFIG_CHANGE_CMD == cmd_type_ || UNLOCK_CONFIG_CHANGE_CMD == cmd_type_) ? \ + (palf::OB_INVALID_CONFIG_CHANGE_LOCK_OWNER != lock_owner_) : true); return bool_ret; } @@ -119,19 +149,20 @@ void LogConfigChangeCmd::reset() new_replica_num_ = 0; cmd_type_ = INVALID_CONFIG_CHANGE_CMD; timeout_us_ = 0; + lock_owner_ = palf::OB_INVALID_CONFIG_CHANGE_LOCK_OWNER; + config_version_.reset(); } OB_SERIALIZE_MEMBER(LogConfigChangeCmd, src_, palf_id_, added_member_, removed_member_, -curr_member_list_, curr_replica_num_, new_replica_num_, cmd_type_, timeout_us_); +curr_member_list_, curr_replica_num_, new_replica_num_, cmd_type_, timeout_us_, lock_owner_, config_version_); // ============= LogConfigChangeCmd end ============= // ============= LogConfigChangeCmdResp begin =========== LogConfigChangeCmdResp::LogConfigChangeCmdResp() - : ret_(OB_MAX_ERROR_CODE) { } +{ + reset(); +} -LogConfigChangeCmdResp::LogConfigChangeCmdResp( - const int ret) - : ret_(ret) { } LogConfigChangeCmdResp::~LogConfigChangeCmdResp() { @@ -146,8 +177,11 @@ bool LogConfigChangeCmdResp::is_valid() const void LogConfigChangeCmdResp::reset() { ret_ = OB_MAX_ERROR_CODE; + lock_owner_ = palf::OB_INVALID_CONFIG_CHANGE_LOCK_OWNER; + is_locked_ = false; } -OB_SERIALIZE_MEMBER(LogConfigChangeCmdResp, ret_); + +OB_SERIALIZE_MEMBER(LogConfigChangeCmdResp, ret_, lock_owner_, is_locked_); // ============= LogConfigChangeCmdResp end ============= // ============= LogGetLeaderMaxScnReq begin =========== diff --git a/src/logservice/logrpc/ob_log_rpc_req.h b/src/logservice/logrpc/ob_log_rpc_req.h index 8965a4577..77561e39a 100644 --- a/src/logservice/logrpc/ob_log_rpc_req.h +++ b/src/logservice/logrpc/ob_log_rpc_req.h @@ -33,9 +33,12 @@ enum LogConfigChangeCmdType { REPLACE_MEMBER_CMD, ADD_LEARNER_CMD, REMOVE_LEARNER_CMD, - SWITCH_TO_ACCEPTOR_CMD, + SWITCH_TO_ACCEPTOR_CMD,//discarded SWITCH_TO_LEARNER_CMD, FORCE_SINGLE_MEMBER_CMD, + TRY_LOCK_CONFIG_CHANGE_CMD, + UNLOCK_CONFIG_CHANGE_CMD, + GET_CONFIG_CHANGE_LOCK_STAT_CMD, }; inline const char *log_config_change_cmd2str(const LogConfigChangeCmdType state) @@ -51,6 +54,9 @@ inline const char *log_config_change_cmd2str(const LogConfigChangeCmdType state) CHECK_CMD_TYPE_STR(SWITCH_TO_ACCEPTOR_CMD); CHECK_CMD_TYPE_STR(SWITCH_TO_LEARNER_CMD); CHECK_CMD_TYPE_STR(CHANGE_REPLICA_NUM_CMD); + CHECK_CMD_TYPE_STR(TRY_LOCK_CONFIG_CHANGE_CMD); + CHECK_CMD_TYPE_STR(UNLOCK_CONFIG_CHANGE_CMD); + CHECK_CMD_TYPE_STR(GET_CONFIG_CHANGE_LOCK_STAT_CMD); default: return "Invalid"; } @@ -75,15 +81,21 @@ public: const int64_t new_replica_num, const LogConfigChangeCmdType cmd_type, const int64_t timeout_us); + LogConfigChangeCmd(const common::ObAddr &src, + const int64_t palf_id, + const int64_t lock_owner, + const LogConfigChangeCmdType cmd_type, + const int64_t timeout_us); ~LogConfigChangeCmd(); bool is_valid() const; void reset(); bool is_remove_member_list() const; bool is_add_member_list() const; + void in_leader(const palf::LogConfigVersion &config_version); bool is_set_new_replica_num() const; TO_STRING_KV("cmd_type", log_config_change_cmd2str(cmd_type_), K_(src), K_(palf_id), \ K_(added_member), K_(removed_member), K_(curr_member_list), K_(curr_replica_num), \ - K_(new_replica_num), K_(timeout_us)); + K_(new_replica_num), K_(timeout_us), K_(lock_owner), K_(config_version)); common::ObAddr src_; int64_t palf_id_; common::ObMember added_member_; @@ -93,18 +105,22 @@ public: int64_t new_replica_num_; LogConfigChangeCmdType cmd_type_; int64_t timeout_us_; + int64_t lock_owner_; + palf::LogConfigVersion config_version_; }; struct LogConfigChangeCmdResp { OB_UNIS_VERSION(1); public: LogConfigChangeCmdResp(); - LogConfigChangeCmdResp(const int ret); ~LogConfigChangeCmdResp(); bool is_valid() const; void reset(); - TO_STRING_KV(K_(ret)); + TO_STRING_KV(K_(ret), K_(lock_owner), K_(is_locked)); +public: int ret_; + int64_t lock_owner_; + bool is_locked_; }; struct LogGetLeaderMaxScnReq { diff --git a/src/logservice/ob_garbage_collector.cpp b/src/logservice/ob_garbage_collector.cpp index 3137c6a63..839ee1b91 100644 --- a/src/logservice/ob_garbage_collector.cpp +++ b/src/logservice/ob_garbage_collector.cpp @@ -29,6 +29,7 @@ #include "share/rc/ob_tenant_base.h" #include "share/ls/ob_ls_life_manager.h" #include "storage/tx_storage/ob_ls_handle.h" +#include "rootserver/ob_ls_recovery_reportor.h" // ObLSRecoveryReportor #include "rootserver/ob_tenant_info_loader.h" // ObTenantInfoLoader #include "share/ob_occam_time_guard.h" @@ -608,6 +609,9 @@ void ObGCHandler::try_check_and_set_wait_gc_(ObGarbageCollector::LSStatus &ls_st CLOG_LOG(WARN, "get_gc_state failed", K(ls_id), K(gc_state), K(ret)); } else if (OB_FAIL(get_tenant_readable_scn_(readable_scn))) { CLOG_LOG(WARN, "get_tenant_readable_scn_ failed", K(ret), K(ls_id)); + } else if (!readable_scn.is_valid() || !offline_scn.is_valid()) { + CLOG_LOG(INFO, "try_check_and_set_wait_gc_ offline_scn or readable_scn is invalid", + K(readable_scn), K(offline_scn), K(ls_id), K(gc_state)); } else if (readable_scn < offline_scn) { CLOG_LOG(INFO, "try_check_and_set_wait_gc_ wait readable_scn", K(ret), K(ls_id), K(gc_state), K(offline_scn), K(readable_scn)); } else if (OB_FAIL(check_if_tenant_in_archive_(tenant_in_archive))) { @@ -617,7 +621,7 @@ void ObGCHandler::try_check_and_set_wait_gc_(ObGarbageCollector::LSStatus &ls_st CLOG_LOG(WARN, "set_gc_state failed", K(ls_id), K(gc_state), K(ret)); } ls_status = ObGarbageCollector::LSStatus::LS_NEED_DELETE_ENTRY; - CLOG_LOG(INFO, "try_check_and_set_wait_gc_ success", K(ls_id), K(gc_state), K(offline_scn), K(scn)); + CLOG_LOG(INFO, "try_check_and_set_wait_gc_ success", K(ls_id), K(gc_state), K(offline_scn), K(readable_scn)); } else if (OB_FAIL(archive_service->get_ls_archive_progress(ls_id, lsn, scn, force_wait, ignore))){ CLOG_LOG(WARN, "get_ls_archive_progress failed", K(ls_id), K(gc_state), K(offline_scn), K(ret)); } else if (ignore) { @@ -1096,6 +1100,7 @@ int ObGarbageCollector::construct_server_ls_map_for_member_list_(ServerLSMap &se int tmp_ret = OB_SUCCESS; while (OB_SUCC(ret)) { common::ObAddr leader; + bool allow_gc = false; if (OB_FAIL(iter->get_next(ls))) { if (OB_ITER_END != ret) { CLOG_LOG(WARN, "get next log stream failed", K(ret)); @@ -1120,8 +1125,10 @@ int ObGarbageCollector::construct_server_ls_map_for_member_list_(ServerLSMap &se CLOG_LOG(WARN, "get invalid leader from location service", K(tmp_ret), K(ls->get_ls_id())); } else if (OB_SUCCESS != (tmp_ret = ls->get_migration_status(migration_status))) { CLOG_LOG(WARN, "get_migration_status failed", K(tmp_ret), K(ls->get_ls_id())); - } else if (!ObMigrationStatusHelper::check_allow_gc(migration_status)) { - CLOG_LOG(INFO, "current ls not allowed to gc", K(ls->get_ls_id())); + } else if (OB_SUCCESS != (tmp_ret = ObMigrationStatusHelper::check_allow_gc(ls->get_ls_id(), migration_status, allow_gc))) { + CLOG_LOG(WARN, "failed to check ls allowed to gc", K(tmp_ret), K(migration_status), "ls_id", ls->get_ls_id()); + } else if (!allow_gc) { + CLOG_LOG(INFO, "The ls is dependent and is not allowed to be GC", "ls_id", ls->get_ls_id(), K(migration_status)); } else if (OB_SUCCESS != (tmp_ret = construct_server_ls_map_(server_ls_map, leader, ls->get_ls_id()))) { CLOG_LOG(WARN, "construct_server_ls_map_ failed", K(tmp_ret), K(ls->get_ls_id()), K(leader)); } @@ -1192,7 +1199,7 @@ void ObGarbageCollector::gc_check_ls_status_(ObGCCandidateArray &gc_candidates) } } else if (OB_ISNULL(ls)) { CLOG_LOG(ERROR, "log stream is NULL", K(ls)); - } else if (OB_SUCCESS != (tmp_ret = gc_check_ls_status_(ls->get_ls_id(), gc_candidates))) { + } else if (OB_SUCCESS != (tmp_ret = gc_check_ls_status_(*ls, gc_candidates))) { CLOG_LOG(WARN, "get_ls_status_ failed", K(tmp_ret), K(ls->get_ls_id())); } else {} } @@ -1217,7 +1224,7 @@ int ObGarbageCollector::check_if_tenant_has_been_dropped_(const uint64_t tenant_ return ret; } -int ObGarbageCollector::gc_check_ls_status_(const ObLSID &id, +int ObGarbageCollector::gc_check_ls_status_(storage::ObLS &ls, ObGCCandidateArray &gc_candidates) { int ret = OB_SUCCESS; @@ -1225,29 +1232,36 @@ int ObGarbageCollector::gc_check_ls_status_(const ObLSID &id, const int64_t tenant_id = MTL_ID(); ObLSStatusOperator ls_op; share::ObLSStatus ls_status = OB_LS_NORMAL; + share::ObLSID ls_id = ls.get_ls_id(); + ObMigrationStatus migration_status; + bool allow_gc = false; GCCandidate candidate; - candidate.ls_id_ = id; + candidate.ls_id_ = ls_id; candidate.ls_status_ = LSStatus::LS_NORMAL; candidate.gc_reason_ = GCReason::INVALID_GC_REASON; - if (OB_FAIL(get_ls_status_from_table(id, ls_status))) { - // 对应行被删除则说明可以gc - if (OB_ENTRY_NOT_EXIST == ret) { + if (OB_FAIL(get_ls_status_from_table(ls_id, ls_status))) { + int tmp_ret = OB_SUCCESS; + bool is_tenant_dropped = false; + if (OB_SUCCESS != (tmp_ret = check_if_tenant_has_been_dropped_(tenant_id, is_tenant_dropped))) { + CLOG_LOG(WARN, "check_if_tenant_has_been_dropped_ failed", K(tmp_ret), K(tenant_id), K(ls_id)); + } else if (is_tenant_dropped) { candidate.ls_status_ = LSStatus::LS_NEED_GC; candidate.gc_reason_ = GCReason::LS_STATUS_ENTRY_NOT_EXIST; ret = OB_SUCCESS; - // 少数派可能在查表时租户已经被删除,需要double check schema明确是否租户真的被删除 - } else { - int tmp_ret = OB_SUCCESS; - bool is_tenant_dropped = false; - if (OB_SUCCESS != (tmp_ret = check_if_tenant_has_been_dropped_(tenant_id, is_tenant_dropped))) { - CLOG_LOG(WARN, "check_if_tenant_has_been_dropped_ failed", K(tmp_ret), K(tenant_id), K(id)); - } else if (is_tenant_dropped) { + } else if (OB_ENTRY_NOT_EXIST == ret) { + if (OB_SUCCESS != (tmp_ret = ls.get_migration_status(migration_status))) { + CLOG_LOG(WARN, "get_migration_status failed", K(tmp_ret), K(ls_id)); + } else if (OB_SUCCESS != (tmp_ret = ObMigrationStatusHelper::check_allow_gc(ls.get_ls_id(), migration_status, allow_gc))) { + CLOG_LOG(WARN, "failed to check ls allowed to gc", K(tmp_ret), K(migration_status), K(ls_id)); + } else if (!allow_gc) { + CLOG_LOG(INFO, "The ls is dependent and is not allowed to be GC", K(ls_id), K(migration_status)); + } else { candidate.ls_status_ = LSStatus::LS_NEED_GC; candidate.gc_reason_ = GCReason::LS_STATUS_ENTRY_NOT_EXIST; ret = OB_SUCCESS; - } else { - CLOG_LOG(WARN, "failed to get ls status from table", K(ret), K(tenant_id), K(id)); } + } else { + CLOG_LOG(WARN, "failed to get ls status from table", K(ret), K(tenant_id), K(ls_id)); } } else { candidate.set_ls_status(ls_status); diff --git a/src/logservice/ob_garbage_collector.h b/src/logservice/ob_garbage_collector.h index d1f5eacc3..6ea54a453 100644 --- a/src/logservice/ob_garbage_collector.h +++ b/src/logservice/ob_garbage_collector.h @@ -200,7 +200,7 @@ private: const share::ObLSID &id) const; //日志流状态表相关 void gc_check_ls_status_(ObGCCandidateArray &gc_candidates); - int gc_check_ls_status_(const share::ObLSID &id, + int gc_check_ls_status_(storage::ObLS &ls, ObGCCandidateArray &gc_candidates); int check_if_tenant_has_been_dropped_(const uint64_t tenant_id, bool &has_dropped); diff --git a/src/logservice/ob_log_base_type.h b/src/logservice/ob_log_base_type.h index c161a4b7c..79d24d77c 100644 --- a/src/logservice/ob_log_base_type.h +++ b/src/logservice/ob_log_base_type.h @@ -92,6 +92,36 @@ enum ObLogBaseType // for obj lock garbage collect service OBJ_LOCK_GARBAGE_COLLECT_SERVICE_LOG_BASE_TYPE = 27, + + // for tenant_transfer_service + TENANT_TRANSFER_SERVICE_LOG_BASE_TYPE = 28, + + //for tenant balance + TENANT_BALANCE_SERVICE_LOG_BASE_TYPE = 29, + //for tenant balance task execute + + BALANCE_EXECUTE_SERVICE_LOG_BASE_TYPE = 30, + + //for backup task scheduler service + BACKUP_TASK_SCHEDULER_LOG_BASE_TYPE = 31, + + //for backup service + BACKUP_DATA_SERVICE_LOG_BASE_TYPE = 32, + + //for backup task scheduler service + BACKUP_CLEAN_SERVICE_LOG_BASE_TYPE = 33, + + //for log archive service + BACKUP_ARCHIVE_SERVICE_LOG_BASE_TYPE = 34, + + //for transfer handler + TRANSFER_HANDLER_LOG_BASE_TYPE = 35, + + COMMON_LS_SERVICE_LOG_BASE_TYPE = 36, + + // only use role change service, do not write clog + LS_BLOCK_TX_SERVICE_LOG_BASE_TYPE = 37, + // pay attention!!! // add log type in log_base_type_to_string // max value @@ -162,6 +192,26 @@ int log_base_type_to_string(const ObLogBaseType log_type, strncpy(str ,"DUP_TABLE", str_len); } else if (log_type == OBJ_LOCK_GARBAGE_COLLECT_SERVICE_LOG_BASE_TYPE) { strncpy(str ,"OBJ_LOCK_GARBAGE_COLLECT_SERVICE", str_len); + } else if (log_type == TENANT_TRANSFER_SERVICE_LOG_BASE_TYPE) { + strncpy(str ,"TENANT_TRANSFER_SERVICE", str_len); + } else if (log_type == TENANT_BALANCE_SERVICE_LOG_BASE_TYPE) { + strncpy(str ,"TENANT_BALANCE", str_len); + } else if (log_type == BALANCE_EXECUTE_SERVICE_LOG_BASE_TYPE) { + strncpy(str ,"BALANCE_EXECUTE_SERVICE", str_len); + } else if (log_type == BACKUP_DATA_SERVICE_LOG_BASE_TYPE) { + strncpy(str, "BACKUP_DATA_SERVICE", str_len); + } else if (log_type == BACKUP_CLEAN_SERVICE_LOG_BASE_TYPE) { + strncpy(str, "BACKUP_CLEAN_SERVICE", str_len); + } else if (log_type == BACKUP_ARCHIVE_SERVICE_LOG_BASE_TYPE) { + strncpy(str, "BACKUP_ARCHIVE_SERVICE", str_len); + } else if (log_type == BACKUP_TASK_SCHEDULER_LOG_BASE_TYPE) { + strncpy(str, "BACKUP_TASK_SCHEDULER", str_len); + } else if (log_type == TRANSFER_HANDLER_LOG_BASE_TYPE) { + strncpy(str, "TRANSFER_HANDLER", str_len); + } else if (log_type == COMMON_LS_SERVICE_LOG_BASE_TYPE) { + strncpy(str ,"COMMON_LS_SERVICE", str_len); + } else if (log_type == LS_BLOCK_TX_SERVICE_LOG_BASE_TYPE) { + strncpy(str ,"BLOCK_TX_SERVICE", str_len); } else { ret = OB_INVALID_ARGUMENT; } diff --git a/src/logservice/ob_log_handler.cpp b/src/logservice/ob_log_handler.cpp old mode 100644 new mode 100755 index b8fa98a02..b535861df --- a/src/logservice/ob_log_handler.cpp +++ b/src/logservice/ob_log_handler.cpp @@ -36,6 +36,7 @@ using namespace share; namespace logservice { using namespace palf; + ObLogHandler::ObLogHandler() : self_(), apply_status_(NULL), apply_service_(NULL), @@ -576,6 +577,38 @@ int ObLogHandler::get_leader_max_scn_(SCN &max_scn) const return ret; } +int ObLogHandler::get_leader_config_version(LogConfigVersion &config_version) const +{ + int ret = OB_SUCCESS; + common::ObRole role; + common::ObRole new_role; + int64_t proposal_id; + int64_t new_proposal_id; + bool is_pending_state = false; + config_version.reset(); + RLockGuard guard(lock_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + CLOG_LOG(WARN, "loghandler is not inited or maybe destroyed", K(ret), K(id_)); + } else if (is_in_stop_state_) { + ret = OB_NOT_RUNNING; + CLOG_LOG(INFO, "loghandler is stopped", K(ret), K_(id)); + } else if (OB_FAIL(palf_handle_.get_role(role, proposal_id, is_pending_state))) { + CLOG_LOG(WARN, "get_role failed", K(ret), KPC(this)); + } else if (LEADER != role || true == is_pending_state) { + ret = OB_NOT_MASTER; + } else if (OB_FAIL(palf_handle_.get_config_version(config_version))) { + CLOG_LOG(WARN, "get_config_version failed", K(ret), KPC(this)); + } else if (OB_FAIL(palf_handle_.get_role(new_role, new_proposal_id, is_pending_state))) { + CLOG_LOG(WARN, "get_role failed", K(ret), KPC(this)); + } else if (role != new_role || proposal_id != new_proposal_id) { + ret = OB_NOT_MASTER; + CLOG_LOG(INFO, "role changed during getting config version", K(ret), KPC(this), K(role), + K(new_role), K(proposal_id), K(new_proposal_id)); + } else {/*do nothing*/} + return ret; +} + // @desc: change_replica_num interface // | 1.change_replica_num() // V @@ -635,7 +668,8 @@ int ObLogHandler::force_set_as_single_replica() LogConfigChangeCmd req(self_, id_, dummy_member_list, dummy_replica_num, new_replica_num, FORCE_SINGLE_MEMBER_CMD, timeout_us); ConfigChangeCmdHandler cmd_handler(&palf_handle_); - if (OB_FAIL(cmd_handler.handle_config_change_cmd(req))) { + LogConfigChangeCmdResp resp; + if (OB_FAIL(cmd_handler.handle_config_change_cmd(req, resp))) { CLOG_LOG(WARN, "handle_config_change_cmd failed", KR(ret), K_(id)); } } @@ -650,6 +684,7 @@ int ObLogHandler::force_set_as_single_replica() // [any_member] <----[4. Sync LogConfigChangeCmdResp]--- | 3. one_stage_config_change_(ADD_MEMBER) int ObLogHandler::add_member(const common::ObMember &added_member, const int64_t new_replica_num, + const palf::LogConfigVersion &config_version, const int64_t timeout_us) { int ret = OB_SUCCESS; @@ -660,16 +695,19 @@ int ObLogHandler::add_member(const common::ObMember &added_member, ret = OB_NOT_RUNNING; } else if (!added_member.is_valid() || !is_valid_replica_num(new_replica_num) || + !config_version.is_valid() || timeout_us <= 0) { ret = OB_INVALID_ARGUMENT; - CLOG_LOG(WARN, "invalid argument", KR(ret), K_(id), K(added_member), K(new_replica_num), K(timeout_us)); + CLOG_LOG(WARN, "invalid argument", KR(ret), K_(id), K(added_member), + K(new_replica_num), K(config_version), K(timeout_us)); } else { common::ObMember dummy_member; LogConfigChangeCmd req(self_, id_, added_member, dummy_member, new_replica_num, ADD_MEMBER_CMD, timeout_us); + req.in_leader(config_version); if (OB_FAIL(submit_config_change_cmd_(req))) { - CLOG_LOG(WARN, " submit_config_change_cmd failed", KR(ret), K_(id), K(req), K(timeout_us)); + CLOG_LOG(WARN, "add_member failed", KR(ret), K_(id), K(added_member), K(new_replica_num), K(config_version)); } else { - CLOG_LOG(INFO, "add_member success", KR(ret), K_(id), K(added_member), K(new_replica_num)); + CLOG_LOG(INFO, "add_member success", KR(ret), K_(id), K(added_member), K(new_replica_num), K(config_version)); } } return ret; @@ -718,8 +756,8 @@ int ObLogHandler::remove_member(const common::ObMember &removed_member, // [any_member] <----[5. Sync LogConfigChangeCmdResp]----- int ObLogHandler::replace_member(const common::ObMember &added_member, const common::ObMember &removed_member, - const int64_t timeout_us) -{ + const palf::LogConfigVersion &config_version, + const int64_t timeout_us) { int ret = OB_SUCCESS; common::ObSpinLockGuard deps_guard(deps_lock_); if (IS_NOT_INIT) { @@ -728,15 +766,17 @@ int ObLogHandler::replace_member(const common::ObMember &added_member, ret = OB_NOT_RUNNING; } else if (!added_member.is_valid() || !removed_member.is_valid() || + !config_version.is_valid() || timeout_us <= 0) { ret = OB_INVALID_ARGUMENT; - CLOG_LOG(WARN, "invalid argument", KR(ret), K_(id), K(added_member), K(removed_member), K(timeout_us)); + CLOG_LOG(WARN, "invalid argument", KR(ret), K_(id), K(added_member), K(removed_member), K(config_version), K(timeout_us)); } else { LogConfigChangeCmd req(self_, id_, added_member, removed_member, 0, REPLACE_MEMBER_CMD, timeout_us); + req.in_leader(config_version); if (OB_FAIL(submit_config_change_cmd_(req))) { - CLOG_LOG(WARN, " submit_config_change_cmd failed", KR(ret), K_(id), K(req), K(timeout_us)); + CLOG_LOG(WARN, "replace_member failed", KR(ret), K_(id), K(added_member), K(removed_member), K(config_version)); } else { - CLOG_LOG(INFO, "replace_member success", KR(ret), K_(id), K(added_member), K(removed_member), K(timeout_us)); + CLOG_LOG(INFO, "replace_member success", KR(ret), K_(id), K(added_member), K(removed_member), K(config_version)); } } return ret; @@ -843,6 +883,7 @@ int ObLogHandler::replace_learner(const common::ObMember &added_learner, // [any_member] <----[4. Sync LogConfigChangeCmdResp]--- | 3. one_stage_config_change_(SWITCH_LEARNER_TO_ACCEPTOR) int ObLogHandler::switch_learner_to_acceptor(const common::ObMember &learner, const int64_t new_replica_num, + const palf::LogConfigVersion &config_version, const int64_t timeout_us) { int ret = OB_SUCCESS; @@ -853,15 +894,17 @@ int ObLogHandler::switch_learner_to_acceptor(const common::ObMember &learner, ret = OB_NOT_RUNNING; } else if (!learner.is_valid() || !is_valid_replica_num(new_replica_num) || + !config_version.is_valid() || timeout_us <= 0) { ret = OB_INVALID_ARGUMENT; - CLOG_LOG(WARN, "invalid argument", KR(ret), K_(id), K(learner), K(new_replica_num), K(timeout_us)); + CLOG_LOG(WARN, "invalid argument", KR(ret), K_(id), K(learner), K(new_replica_num), K(config_version), K(timeout_us)); } else { LogConfigChangeCmd req(self_, id_, learner, learner, new_replica_num, SWITCH_TO_ACCEPTOR_CMD, timeout_us); + req.in_leader(config_version); if (OB_FAIL(submit_config_change_cmd_(req))) { - CLOG_LOG(WARN, " submit_config_change_cmd failed", KR(ret), K_(id), K(req), K(timeout_us)); + CLOG_LOG(WARN, "switch_learner_to_acceptor failed", KR(ret), K_(id), K(learner), K(new_replica_num), K(config_version)); } else { - CLOG_LOG(INFO, "add_member success", KR(ret), K_(id), K(learner), K(new_replica_num)); + CLOG_LOG(INFO, "switch_learner_to_acceptor success", KR(ret), K_(id), K(learner), K(new_replica_num), K(config_version)); } } return ret; @@ -900,7 +943,84 @@ int ObLogHandler::switch_acceptor_to_learner(const common::ObMember &member, } +int ObLogHandler::try_lock_config_change(const int64_t lock_owner, const int64_t timeout_us) + +{ + int ret = OB_SUCCESS; + common::ObSpinLockGuard deps_guard(deps_lock_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + } else if (is_in_stop_state_) { + ret = OB_NOT_RUNNING; + } else if (palf::OB_INVALID_CONFIG_CHANGE_LOCK_OWNER == lock_owner || timeout_us <= 0) { + ret = OB_INVALID_ARGUMENT; + CLOG_LOG(WARN, "invalid argument", KR(ret), K_(id), K(lock_owner), K(timeout_us)); + } else { + LogConfigChangeCmd req(self_, id_, lock_owner, TRY_LOCK_CONFIG_CHANGE_CMD, timeout_us); + if (OB_FAIL(submit_config_change_cmd_(req))) { + CLOG_LOG(WARN, "try_lock_config_change failed", KR(ret), K_(id), K(lock_owner), K(timeout_us)); + } else { + CLOG_LOG(INFO, "try_lock_config_change success", KR(ret), K_(id), K(lock_owner)); + } + } + return ret; +} + +int ObLogHandler::unlock_config_change(const int64_t lock_owner, const int64_t timeout_us) +{ + int ret = OB_SUCCESS; + common::ObSpinLockGuard deps_guard(deps_lock_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + } else if (is_in_stop_state_) { + ret = OB_NOT_RUNNING; + } else if (palf::OB_INVALID_CONFIG_CHANGE_LOCK_OWNER == lock_owner || timeout_us <= 0) { + ret = OB_INVALID_ARGUMENT; + CLOG_LOG(WARN, "invalid argument", KR(ret), K_(id), K(lock_owner), K(timeout_us)); + } else { + LogConfigChangeCmd req(self_, id_, lock_owner, UNLOCK_CONFIG_CHANGE_CMD, timeout_us); + if (OB_FAIL(submit_config_change_cmd_(req))) { + CLOG_LOG(WARN, "unlock_config_change failed", KR(ret), K_(id), K(lock_owner), K(timeout_us)); + } else { + CLOG_LOG(INFO, "unlock_config_change success", KR(ret), K_(id), K(lock_owner)); + } + } + return ret; +} + +int ObLogHandler::get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked) +{ + int ret = OB_SUCCESS; + common::ObSpinLockGuard deps_guard(deps_lock_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + } else if (is_in_stop_state_) { + ret = OB_NOT_RUNNING; + } else { + const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s + LogConfigChangeCmd req(self_, id_, palf::OB_INVALID_CONFIG_CHANGE_LOCK_OWNER/*unused*/, + GET_CONFIG_CHANGE_LOCK_STAT_CMD, CONFIG_CHANGE_TIMEOUT/*timeout_us*/); + LogConfigChangeCmdResp resp; + if (OB_FAIL(submit_config_change_cmd_(req, resp))) { + CLOG_LOG(WARN, "get_config_change_lock_stat failed", KR(ret), K_(id)); + } else { + lock_owner = resp.lock_owner_; + is_locked = resp.is_locked_; + CLOG_LOG(INFO, "get_config_change_lock_stat success", KR(ret), K_(id), K(lock_owner), K(is_locked)); + } + } + return ret; +} + + int ObLogHandler::submit_config_change_cmd_(const LogConfigChangeCmd &req) +{ + LogConfigChangeCmdResp unused_resp; + return submit_config_change_cmd_(req, unused_resp); +} + +int ObLogHandler::submit_config_change_cmd_(const LogConfigChangeCmd &req, + LogConfigChangeCmdResp &resp) { int ret = OB_SUCCESS; ObSwitchLeaderAdapter switch_leader_adapter; @@ -911,11 +1031,12 @@ int ObLogHandler::submit_config_change_cmd_(const LogConfigChangeCmd &req) constexpr int64_t RENEW_LEADER_INTERVAL_US = 500 * 1000L; // 500ms const int64_t timeout_us = req.timeout_us_; const int64_t conn_timeout_us = MIN(timeout_us, MIN_CONN_TIMEOUT_US); - const int64_t start_time_us = common::ObTimeUtility::current_time(); + const int64_t start_time_us = common::ObClockGenerator::getClock(); int64_t last_renew_leader_time_us = OB_INVALID_TIMESTAMP; FLOG_INFO("config_change start", K_(id), K(req)); bool has_added_to_blacklist = false; bool has_removed_from_blacklist = false; + while(OB_SUCCESS == ret || OB_NOT_MASTER == ret) { // judge init status to avoiding log_handler destoring gets stuck if (IS_NOT_INIT || OB_ISNULL(lc_cb_) || OB_ISNULL(rpc_proxy_)) { @@ -942,14 +1063,15 @@ int ObLogHandler::submit_config_change_cmd_(const LogConfigChangeCmd &req) has_removed_from_blacklist = true; } } + common::ObAddr leader; ConfigChangeCmdHandler cmd_handler(&palf_handle_); - LogConfigChangeCmdResp resp; bool need_renew_leader = false; if (OB_FAIL(lc_cb_->get_leader(id_, leader))) { need_renew_leader = true; ret = OB_SUCCESS; - } else if (leader == self_ && FALSE_IT(resp.ret_ = cmd_handler.handle_config_change_cmd(req))) { + } else if (leader == self_ && FALSE_IT(cmd_handler.handle_config_change_cmd(req, resp))) { + CLOG_LOG(WARN, "failed to handle_config_change_cmd", KR(ret), K_(id), K(req)); } else if (leader != self_ && OB_FAIL(rpc_proxy_->to(leader).timeout(conn_timeout_us).trace_time(true). max_process_handler_time(timeout_us).by(MTL_ID()).send_log_config_change_cmd(req, resp))) { // if RPC fails, try again @@ -1245,6 +1367,8 @@ int ObLogHandler::diagnose(LogHandlerDiagnoseInfo &diagnose_info) const RLockGuard guard(lock_); if (IS_NOT_INIT) { ret = OB_NOT_INIT; + } else if (is_in_stop_state_) { + ret = OB_NOT_RUNNING; } else { diagnose_info.log_handler_role_ = ATOMIC_LOAD(&role_); diagnose_info.log_handler_proposal_id_ = ATOMIC_LOAD(&proposal_id_); @@ -1342,5 +1466,6 @@ bool ObLogHandler::is_offline() const { return true == ATOMIC_LOAD(&is_offline_); } + } // end namespace logservice } // end napespace oceanbase diff --git a/src/logservice/ob_log_handler.h b/src/logservice/ob_log_handler.h old mode 100644 new mode 100755 index a33576d19..801f4106c --- a/src/logservice/ob_log_handler.h +++ b/src/logservice/ob_log_handler.h @@ -106,6 +106,7 @@ public: int64_t &paxos_replica_num, common::GlobalLearnerList &learner_list) const = 0; virtual int get_global_learner_list(common::GlobalLearnerList &learner_list) const = 0; + virtual int get_leader_config_version(palf::LogConfigVersion &config_version) const = 0; // get leader from election, used only for non_palf_leader rebuilding. virtual int get_election_leader(common::ObAddr &addr) const = 0; virtual int change_replica_num(const common::ObMemberList &member_list, @@ -115,24 +116,30 @@ public: virtual int force_set_as_single_replica() = 0; virtual int add_member(const common::ObMember &member, const int64_t paxos_replica_num, + const palf::LogConfigVersion &config_version, const int64_t timeout_us) = 0; virtual int remove_member(const common::ObMember &member, const int64_t paxos_replica_num, const int64_t timeout_us) = 0; virtual int replace_member(const common::ObMember &added_member, const common::ObMember &removed_member, + const palf::LogConfigVersion &config_version, const int64_t timeout_us) = 0; virtual int add_learner(const common::ObMember &added_learner, const int64_t timeout_us) = 0; virtual int remove_learner(const common::ObMember &removed_learner, const int64_t timeout_us) = 0; - virtual int replace_learner(const common::ObMember &added_learner, - const common::ObMember &removed_learner, - const int64_t timeout_us) = 0; virtual int switch_learner_to_acceptor(const common::ObMember &learner, const int64_t paxos_replica_num, + const palf::LogConfigVersion &config_version, const int64_t timeout_us) = 0; virtual int switch_acceptor_to_learner(const common::ObMember &member, const int64_t paxos_replica_num, const int64_t timeout_us) = 0; + virtual int replace_learner(const common::ObMember &added_learner, + const common::ObMember &removed_learner, + const int64_t timeout_us) = 0; + virtual int try_lock_config_change(const int64_t lock_owner, const int64_t timeout_us) = 0; + virtual int unlock_config_change(const int64_t lock_owner, const int64_t timeout_us) = 0; + virtual int get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked) = 0; virtual int get_palf_base_info(const palf::LSN &base_lsn, palf::PalfBaseInfo &palf_base_info) = 0; virtual int is_in_sync(bool &is_log_sync, bool &is_need_rebuild) const = 0; virtual int enable_sync() = 0; @@ -357,6 +364,15 @@ public: // @brief, check if log sync is enabled bool is_sync_enabled() const override final; + // @brief: get config_version + // @return + // - OB_SUCCESS: get config_version successfully + // - OB_NOT_INIT: is not inited + // - OB_NOT_RUNNING: is in stopped state + // - OB_NOT_MASTER: this replica is not master + // - other: bug + int get_leader_config_version(palf::LogConfigVersion &config_version) const; + // @brief: a special config change interface, change replica number of paxos group // @param[in] common::ObMemberList: current memberlist, for pre-check // @param[in] const int64_t curr_replica_num: current replica num, for pre-check @@ -371,6 +387,7 @@ public: const int64_t curr_replica_num, const int64_t new_replica_num, const int64_t timeout_us) override final; + // @brief: force set self as single replica. // @return // - OB_SUCCESS: change_replica_num successfully @@ -380,14 +397,17 @@ public: // @brief, add a member to paxos group, can be called in any member // @param[in] common::ObMember &member: member which will be added // @param[in] const int64_t paxos_replica_num: replica number of paxos group after adding 'member' + // @param[in] const palf::LogConfigVersion &config_version: config_version for leader checking // @param[in] const int64_t timeout_us: add member timeout, us // @return // - OB_SUCCESS: add member successfully // - OB_INVALID_ARGUMENT: invalid argumemt or not supported config change - // - OB_TIMEOUT: add member timeout + // - OB_NOT_MASTER: not master + // - OB_STATE_NOT_MATCH: leader has switched // - other: bug int add_member(const common::ObMember &member, const int64_t paxos_replica_num, + const palf::LogConfigVersion &config_version, const int64_t timeout_us) override final; // @brief, remove a member from paxos group, can be called in any member @@ -406,6 +426,7 @@ public: // @brief, replace old_member with new_member, can be called in any member // @param[in] const common::ObMember &added_member: member wil be added // @param[in] const common::ObMember &removed_member: member will be removed + // @param[in] const palf::LogConfigVersion &config_version: config_version for leader checking // @param[in] const int64_t timeout_us // @return // - OB_SUCCESS: replace member successfully @@ -414,6 +435,7 @@ public: // - other: bug int replace_member(const common::ObMember &added_member, const common::ObMember &removed_member, + const palf::LogConfigVersion &config_version, const int64_t timeout_us) override final; // @brief: add a learner(read only replica) in this cluster @@ -453,6 +475,7 @@ public: // @param[in] const common::ObMember &learner: learner will be switched to acceptor // @param[in] const int64_t new_replica_num: replica number of paxos group after switching // learner to acceptor (similar to add_member) + // @param[in] const palf::LogConfigVersion &config_version: config_version for leader checking // @param[in] const int64_t timeout_us // @return // - OB_SUCCESS @@ -460,6 +483,7 @@ public: // - OB_TIMEOUT: switch_learner_to_acceptor timeout int switch_learner_to_acceptor(const common::ObMember &learner, const int64_t new_replica_num, + const palf::LogConfigVersion &config_version, const int64_t timeout_us) override final; // @brief: switch an acceptor(full replica) to learner(read only replica) in this cluster @@ -476,6 +500,43 @@ public: const int64_t timeout_us) override final; + //---------config change lock related--------// + //@brief: try lock config change which will forbidden changing on memberlist + // @param[in] const int64_ lock_owner: owner of locking_config_change operation + // @param[in] const int64_t timeout_us + //@return + // -- OB_NOT_INIT not_init + // -- OB_SUCCESS successfull lock + // -- OB_TRY_LOCK_CONFIG_CHANGE_CONFLICT failed to lock because of locked by others + // -- OB_TIMEOUT timeout, may lock successfully or not + // -- OB_EAGAIN other config change operation is going on,need retry later + // -- OB_NOT_MASTER this replica is not leader, not refresh location and retry with actual leader + // -- OB_STATE_NOT_MATCH lock_owner is smaller than previous lock_owner + int try_lock_config_change(const int64_t lock_owner, const int64_t timeout_us); + + //@brief: unlock config change which will allow changing on memberlist + // @param[in] const int64_ lock_owner: expected owner of config_change + // @param[in] const int64_t timeout_us + //@return + // -- OB_NOT_INIT not_init + // -- OB_SUCCESS successfull unlock + // -- OB_TIMEOUT timeout, may unlock successfully or not + // -- OB_EAGAIN other config change operation is going on,need retry later + // -- OB_NOT_MASTER this replica is not leader, need refresh location and retry with actual leader + // -- OB_STATE_NOT_MATCH lock_owner is smaller than previous lock_owner,or lock_owner is bigger than previous lock_owner + int unlock_config_change(const int64_t lock_owner, const int64_t timeout_us); + + //@brief: get config change lock stat + //@return + //ret: + // -- OB_NOT_INIT not_init + // -- OB_SUCCESS success + // -- OB_NOT_MASTER this replica is not leader, not refresh location and retry with actual leader + // -- OB_EAGAIN is_locking or unlocking + // lock_owner: owner of config_change_lock + // is_locked: whether config_change_lock is locked + int get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked); + // @breif, check request server is in self member list // @param[in] const common::ObAddr, request server. // @param[out] bool&, whether in self member list. @@ -518,6 +579,7 @@ public: int unregister_rebuild_cb() override final; int diagnose(LogHandlerDiagnoseInfo &diagnose_info) const; int diagnose_palf(palf::PalfDiagnoseInfo &diagnose_info) const; + TO_STRING_KV(K_(role), K_(proposal_id), KP(palf_env_), K(is_in_stop_state_), K(is_inited_)); int offline() override final; int online(const palf::LSN &lsn, const share::SCN &scn) override final; @@ -526,6 +588,8 @@ private: static constexpr int64_t MIN_CONN_TIMEOUT_US = 5 * 1000 * 1000; // 5s private: int submit_config_change_cmd_(const LogConfigChangeCmd &req); + int submit_config_change_cmd_(const LogConfigChangeCmd &req, + LogConfigChangeCmdResp &resp); int get_leader_max_scn_(share::SCN &max_scn) const; DISALLOW_COPY_AND_ASSIGN(ObLogHandler); private: diff --git a/src/logservice/palf/log_config_mgr.cpp b/src/logservice/palf/log_config_mgr.cpp old mode 100644 new mode 100755 index 13abd4247..a58ae18c5 --- a/src/logservice/palf/log_config_mgr.cpp +++ b/src/logservice/palf/log_config_mgr.cpp @@ -134,7 +134,7 @@ int LogConfigMgr::init(const int64_t palf_id, } } if (OB_SUCC(ret)) { - persistent_config_version_ = log_ms_meta_.curr_.config_version_; + persistent_config_version_ = log_ms_meta_.curr_.config_.config_version_; is_inited_ = true; PALF_LOG(INFO, "LogConfigMgr init success", K(ret), K_(palf_id), K_(self), K_(log_ms_meta), KP(this)); } @@ -202,10 +202,10 @@ int LogConfigMgr::set_initial_member_list(const ObMemberList &member_list, ret = OB_INVALID_ARGUMENT; PALF_LOG(WARN, "invalid argument", KR(ret), K_(palf_id), K(member_list), K(replica_num)); } else { - LogConfigInfo config_info = log_ms_meta_.curr_; - config_info.log_sync_memberlist_ = member_list; - config_info.log_sync_replica_num_ = replica_num; - config_info.learnerlist_ = learner_list; + LogConfigInfoV2 config_info = log_ms_meta_.curr_; + config_info.config_.log_sync_memberlist_ = member_list; + config_info.config_.log_sync_replica_num_ = replica_num; + config_info.config_.learnerlist_ = learner_list; if (OB_FAIL(set_initial_config_info_(config_info, proposal_id, init_config_version))) { PALF_LOG(WARN, "set_initial_config_info failed", K(ret), K_(palf_id), K_(self), K(config_info), K(proposal_id)); } else { @@ -237,11 +237,11 @@ int LogConfigMgr::set_initial_member_list(const common::ObMemberList &member_lis ret = OB_INVALID_ARGUMENT; PALF_LOG(WARN, "invalid argument", KR(ret), K_(palf_id), K_(self), K(member_list), K(arb_member), K(replica_num)); } else { - LogConfigInfo config_info = log_ms_meta_.curr_; - config_info.log_sync_memberlist_ = member_list; - config_info.log_sync_replica_num_ = replica_num; - config_info.arbitration_member_ = arb_member; - config_info.learnerlist_ = learner_list; + LogConfigInfoV2 config_info = log_ms_meta_.curr_; + config_info.config_.log_sync_memberlist_ = member_list; + config_info.config_.log_sync_replica_num_ = replica_num; + config_info.config_.arbitration_member_ = arb_member; + config_info.config_.learnerlist_ = learner_list; if (OB_FAIL(set_initial_config_info_(config_info, proposal_id, init_config_version))) { PALF_LOG(WARN, "set_initial_config_info failed", K(ret), K_(palf_id), K_(self), K(config_info), K(proposal_id)); } else { @@ -251,14 +251,14 @@ int LogConfigMgr::set_initial_member_list(const common::ObMemberList &member_lis return ret; } -int LogConfigMgr::set_initial_config_info_(const LogConfigInfo &config_info, +int LogConfigMgr::set_initial_config_info_(const LogConfigInfoV2 &config_info, const int64_t proposal_id, LogConfigVersion &init_config_version) { int ret = OB_SUCCESS; const int64_t initial_config_seq = 1; LogReplicaType replica_type = state_mgr_->get_replica_type(); - const bool valid_replica_type = (config_info.arbitration_member_.get_server() == self_) ? \ + const bool valid_replica_type = (config_info.config_.arbitration_member_.get_server() == self_) ? \ (replica_type == ARBITRATION_REPLICA) : true; if (false == valid_replica_type) { ret = OB_NOT_SUPPORTED; @@ -266,8 +266,8 @@ int LogConfigMgr::set_initial_config_info_(const LogConfigInfo &config_info, } else if (OB_FAIL(init_config_version.generate(proposal_id, initial_config_seq))) { PALF_LOG(WARN, "invalid argument", KR(ret), K_(palf_id), K(proposal_id), K(initial_config_seq)); } else { - LogConfigInfo init_config_info = config_info; - init_config_info.config_version_ = init_config_version; + LogConfigInfoV2 init_config_info = config_info; + init_config_info.config_.config_version_ = init_config_version; if (false == init_config_info.is_valid()) { ret = OB_INVALID_ARGUMENT; PALF_LOG(WARN, "initial config info is invalid", K_(palf_id), K(config_info), K(proposal_id)); @@ -281,7 +281,7 @@ int LogConfigMgr::set_initial_config_info_(const LogConfigInfo &config_info, FlushMetaCbCtx cb_ctx; cb_ctx.type_ = MetaType::CHANGE_CONFIG_META; cb_ctx.proposal_id_ = proposal_id; - cb_ctx.config_version_ = log_ms_meta_.curr_.config_version_; + cb_ctx.config_version_ = log_ms_meta_.curr_.config_.config_version_; if (OB_FAIL(append_config_info_(log_ms_meta_.curr_))) { PALF_LOG(WARN, "append_config_info_ failed", K(ret), K_(palf_id), K_(log_ms_meta)); } else if (OB_FAIL(update_election_meta_(log_ms_meta_.curr_))) { @@ -356,10 +356,10 @@ int LogConfigMgr::get_prev_member_list(ObMemberList &member_list) const if (IS_NOT_INIT) { ret = OB_NOT_INIT; PALF_LOG(WARN, "LogConfigMgr not init", KR(ret)); - } else if (OB_FAIL(member_list.deep_copy(log_ms_meta_.prev_.log_sync_memberlist_))) { + } else if (OB_FAIL(member_list.deep_copy(log_ms_meta_.prev_.config_.log_sync_memberlist_))) { PALF_LOG(WARN, "deep_copy member_list failed", KR(ret), K_(palf_id), K_(self), K_(log_ms_meta)); - } else if (log_ms_meta_.prev_.arbitration_member_.is_valid() && - OB_FAIL(member_list.add_member(log_ms_meta_.prev_.arbitration_member_))) { + } else if (log_ms_meta_.prev_.config_.arbitration_member_.is_valid() && + OB_FAIL(member_list.add_member(log_ms_meta_.prev_.config_.arbitration_member_))) { PALF_LOG(WARN, "add_member failed", KR(ret), K_(palf_id), K_(self), K_(log_ms_meta)); // no nothing } @@ -371,7 +371,7 @@ int LogConfigMgr::get_global_learner_list(common::GlobalLearnerList &learner_lis int ret = OB_SUCCESS; if (IS_NOT_INIT) { ret = OB_NOT_INIT; - } else if (OB_FAIL(learner_list.deep_copy(log_ms_meta_.curr_.learnerlist_))) { + } else if (OB_FAIL(learner_list.deep_copy(log_ms_meta_.curr_.config_.learnerlist_))) { PALF_LOG(WARN, "deep_copy learner_list failed", KR(ret), K_(palf_id), K_(self)); } else { // pass @@ -384,7 +384,7 @@ int LogConfigMgr::get_degraded_learner_list(common::GlobalLearnerList °raded_ int ret = OB_SUCCESS; if (IS_NOT_INIT) { ret = OB_NOT_INIT; - } else if (OB_FAIL(degraded_learner_list.deep_copy(log_ms_meta_.curr_.degraded_learnerlist_))) { + } else if (OB_FAIL(degraded_learner_list.deep_copy(log_ms_meta_.curr_.config_.degraded_learnerlist_))) { PALF_LOG(WARN, "deep_copy degraded_learnerlist_ failed", KR(ret), K_(palf_id), K_(self)); } else { // pass @@ -399,7 +399,7 @@ int LogConfigMgr::get_arbitration_member(common::ObMember &arb_member) const ret = OB_NOT_INIT; PALF_LOG(WARN, "LogConfigMgr not init", KR(ret)); } else { - arb_member = log_ms_meta_.curr_.arbitration_member_; + arb_member = log_ms_meta_.curr_.config_.arbitration_member_; } return ret; } @@ -410,7 +410,7 @@ int LogConfigMgr::get_curr_member_list(ObMemberList &member_list, int64_t &repli if (IS_NOT_INIT) { ret = OB_NOT_INIT; PALF_LOG(WARN, "LogConfigMgr not init", KR(ret)); - } else if (OB_FAIL(log_ms_meta_.curr_.get_expected_paxos_memberlist(member_list, replica_num))) { + } else if (OB_FAIL(log_ms_meta_.curr_.config_.get_expected_paxos_memberlist(member_list, replica_num))) { PALF_LOG(WARN, "get_expected_paxos_memberlist failed", KR(ret), K_(palf_id), K_(self)); } else { // no nothing @@ -453,15 +453,15 @@ int LogConfigMgr::get_log_sync_member_list_for_generate_committed_lsn( reconfig_barrier_.prev_end_lsn_.is_valid())) { is_before_barrier = true; barrier_lsn = reconfig_barrier_.prev_end_lsn_; - if (OB_FAIL(member_list.deep_copy(log_ms_meta_.prev_.log_sync_memberlist_))) { + if (OB_FAIL(member_list.deep_copy(log_ms_meta_.prev_.config_.log_sync_memberlist_))) { PALF_LOG(WARN, "deep_copy member_list failed", KR(ret), K_(palf_id), K_(self)); } else { - replica_num = log_ms_meta_.prev_.log_sync_replica_num_; + replica_num = log_ms_meta_.prev_.config_.log_sync_replica_num_; } - } else if (OB_FAIL(member_list.deep_copy(log_ms_meta_.curr_.log_sync_memberlist_))) { + } else if (OB_FAIL(member_list.deep_copy(log_ms_meta_.curr_.config_.log_sync_memberlist_))) { PALF_LOG(WARN, "deep_copy member_list failed", KR(ret), K_(palf_id), K_(self)); } else { - replica_num = log_ms_meta_.curr_.log_sync_replica_num_; + replica_num = log_ms_meta_.curr_.config_.log_sync_replica_num_; } return ret; } @@ -473,10 +473,10 @@ int LogConfigMgr::get_log_sync_member_list(ObMemberList &member_list, if (IS_NOT_INIT) { ret = OB_NOT_INIT; PALF_LOG(WARN, "LogConfigMgr not init", KR(ret)); - } else if (OB_FAIL(member_list.deep_copy(log_ms_meta_.curr_.log_sync_memberlist_))) { + } else if (OB_FAIL(member_list.deep_copy(log_ms_meta_.curr_.config_.log_sync_memberlist_))) { PALF_LOG(WARN, "deep_copy member_list failed", KR(ret), K_(palf_id), K_(self)); } else { - replica_num = log_ms_meta_.curr_.log_sync_replica_num_; + replica_num = log_ms_meta_.curr_.config_.log_sync_replica_num_; } return ret; } @@ -491,7 +491,7 @@ int LogConfigMgr::get_children_list(LogLearnerList &children) const } else if (OB_FAIL(children.deep_copy(children_))) { PALF_LOG(WARN, "deep_copy children_list failed", KR(ret), K_(palf_id), K_(self)); } else { - // pass + //pass } return ret; } @@ -502,7 +502,7 @@ int LogConfigMgr::get_config_version(LogConfigVersion &config_version) const if (IS_NOT_INIT) { ret = OB_NOT_INIT; } else { - config_version = log_ms_meta_.curr_.config_version_; + config_version = log_ms_meta_.curr_.config_.config_version_; } return ret; } @@ -514,9 +514,36 @@ int LogConfigMgr::get_replica_num(int64_t &replica_num) const if (IS_NOT_INIT) { ret = OB_NOT_INIT; PALF_LOG(WARN, "LogConfigMgr not init", KR(ret)); - } else if (OB_FAIL(log_ms_meta_.curr_.get_expected_paxos_memberlist(member_list, replica_num))) { + } else if (OB_FAIL(log_ms_meta_.curr_.config_.get_expected_paxos_memberlist(member_list, replica_num))) { PALF_LOG(WARN, "get_expected_paxos_memberlist failed", KR(ret), K_(palf_id), K_(self)); + } else {/*do nothing*/} + return ret; +} + +int LogConfigMgr::get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked) +{ + SpinLockGuard guard(lock_); + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + PALF_LOG(WARN, "LogConfigMgr not init", KR(ret)); + } else if (!state_mgr_->is_leader_active()) { + ret = OB_NOT_MASTER; + PALF_LOG(WARN, "need to be leader active", KR(ret), K_(palf_id), K_(self), + "role", state_mgr_->get_role(), "state", state_mgr_->get_state()); } else { + const bool is_curr_locked = log_ms_meta_.curr_.lock_meta_.is_locked(); + const bool is_prev_locked = log_ms_meta_.prev_.lock_meta_.is_locked(); + lock_owner = log_ms_meta_.curr_.lock_meta_.lock_owner_; + if (CHANGING == state_) { + if (is_curr_locked != is_prev_locked) { + ret = OB_EAGAIN; + } else { + is_locked = is_curr_locked; + } + } else { + is_locked = is_curr_locked; + } } return ret; } @@ -717,7 +744,7 @@ int LogConfigMgr::check_config_version_matches_state_(const LogConfigChangeType } } } else { - ret = (config_version != log_ms_meta_.curr_.config_version_)? OB_EAGAIN: OB_SUCCESS; + ret = (config_version != log_ms_meta_.curr_.config_.config_version_)? OB_EAGAIN: OB_SUCCESS; } return ret; } @@ -824,7 +851,7 @@ int LogConfigMgr::change_config_(const LogConfigChangeArgs &args, ms_ack_list_.reset(); (void) set_resend_log_info_(); state_ = ConfigChangeState::CHANGING; - config_version = log_ms_meta_.curr_.config_version_; + config_version = log_ms_meta_.curr_.config_.config_version_; running_args_ = args; need_change_config_bkgd_ = false; bkgd_config_version_.reset(); @@ -840,7 +867,7 @@ int LogConfigMgr::change_config_(const LogConfigChangeArgs &args, state_ = INIT; (void) update_match_lsn_map_(running_args_, log_ms_meta_.curr_); ms_ack_list_.reset(); - resend_config_version_ = log_ms_meta_.curr_.config_version_; + resend_config_version_ = log_ms_meta_.curr_.config_.config_version_; last_submit_config_log_time_us_ = OB_INVALID_TIMESTAMP; ret = OB_SUCCESS; } else if (need_resend_config_log_()) { @@ -980,8 +1007,7 @@ int LogConfigMgr::check_config_change_args_(const LogConfigChangeArgs &args, boo { int ret = OB_SUCCESS; is_already_finished = false; - common::ObMemberList curr_member_list; - int64_t curr_replica_num = -1; + const LogConfigVersion &config_version = log_ms_meta_.curr_.config_.config_version_; if (!args.is_valid()) { ret = OB_INVALID_ARGUMENT; PALF_LOG(WARN, "invalid argument", KR(ret), K_(palf_id), K_(self), K(args)); @@ -990,19 +1016,78 @@ int LogConfigMgr::check_config_change_args_(const LogConfigChangeArgs &args, boo // proposer of remove_member cmd will retry later and notify election to switch leader. ret = OB_NOT_ALLOW_REMOVING_LEADER; PALF_LOG(WARN, "leader can not remove itself", KR(ret), K_(palf_id), K_(self), K(args)); - } else if (OB_FAIL(get_curr_member_list(curr_member_list, curr_replica_num))) { + } else if (log_ms_meta_.curr_.is_config_change_locked() && is_paxos_member_list_change(args.type_)) { + ret = OB_EAGAIN; + PALF_LOG(WARN, "paxos_member_change is locked, can't do change config now", + KR(ret), K_(palf_id), K_(self), K(args), K_(log_ms_meta), K_(state)); + } else if (need_check_config_version(args.type_) && (args.config_version_ > config_version)) { + ret = OB_ERR_UNEXPECTED; + PALF_LOG(WARN, "config version not match", KR(ret), K_(palf_id), K_(self), K(args), K(config_version)); + } else if (OB_FAIL(check_config_change_args_by_type_(args, is_already_finished))) { + PALF_LOG(WARN, "check_config_change_args_by_type_ failed", KR(ret), K_(palf_id), K_(self), + K(args), K(is_already_finished)); + } else if (is_already_finished) { + PALF_LOG(INFO, "reconfiguration is already finished", KR(ret), K_(palf_id), K_(self), + K(args), K_(log_ms_meta)); + // Note: order if vital. we need check is the reconfiguration is already finished, + // then check if the config version equals to current config version. + } else if (need_check_config_version(args.type_) && (args.config_version_ != config_version)) { + ret = OB_STATE_NOT_MATCH; + PALF_LOG(WARN, "config version not match", KR(ret), K_(palf_id), K_(self), K(args), K(config_version)); + } else { + // check if reaches majority + LogConfigInfoV2 new_config_info; + common::ObMemberList new_paxos_memberlist; + int64_t new_paxos_replica_num; + GlobalLearnerList unused_list; + // defensive check + // 1. check if reaches majority + // 2. new memberlist contains self + // 1F1A, if command is add_member(C, 5), if add C, length of log_sync_member_list is 2, log_sync_replica_num is 4, + // so reject add_member(C, 5) + // 2F, if command is add_member(C, 5), if add C, length of log_sync_member_list is 3, log_sync_replica_num is 5, + // so allow add_member(C, 5) + // 2F2F1A(ABCDE), remove(D, 5) success, then remove(C, 5). if remove C, length of log_sync_member_list is 2, log_sync_replica_num is 4, + // so reject remove(C, 5) + if (OB_FAIL(generate_new_config_info_(state_mgr_->get_proposal_id(), args, new_config_info))) { + PALF_LOG(WARN, "generate_new_config_info_ failed", KR(ret), K_(palf_id), K_(self), K(args)); + } else if (OB_FAIL(new_config_info.convert_to_complete_config(new_paxos_memberlist, new_paxos_replica_num, unused_list))) { + } else if (false == new_paxos_memberlist.contains(self_) || false == new_config_info.config_.log_sync_memberlist_.contains(self_)) { + PALF_LOG(ERROR, "new memberlist doesn't contain self", KR(ret), K_(palf_id), K_(self), K(new_config_info), K(new_paxos_memberlist)); + } else if (false == can_memberlist_majority_(new_config_info.config_.log_sync_memberlist_.get_member_number(), + new_config_info.config_.log_sync_replica_num_) || + false == can_memberlist_majority_(new_paxos_memberlist.get_member_number(), new_paxos_replica_num)) { + ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "can't change config, memberlist don't reach majority", KR(ret), K_(palf_id), K_(self), K(new_config_info), + K(new_paxos_memberlist), K(new_paxos_replica_num), K(args)); + } + } + return ret; +} + +int LogConfigMgr::check_config_change_args_by_type_(const LogConfigChangeArgs &args, + bool &is_already_finished) const +{ + int ret = OB_SUCCESS; + common::ObMemberList curr_member_list; + int64_t curr_replica_num = -1; + is_already_finished = false; + if (OB_FAIL(get_curr_member_list(curr_member_list, curr_replica_num))) { PALF_LOG(WARN, "get_curr_member_list failed", KR(ret), K_(palf_id), K_(self), K(args)); } else { - const ObMemberList &log_sync_member_list = log_ms_meta_.curr_.log_sync_memberlist_; - const common::GlobalLearnerList &curr_learner_list = log_ms_meta_.curr_.learnerlist_; - const common::GlobalLearnerList °raded_learnerlist = log_ms_meta_.curr_.degraded_learnerlist_; + const ObMemberList &log_sync_member_list = log_ms_meta_.curr_.config_.log_sync_memberlist_; + const common::GlobalLearnerList &curr_learner_list = log_ms_meta_.curr_.config_.learnerlist_; + const common::GlobalLearnerList °raded_learnerlist = log_ms_meta_.curr_.config_.degraded_learnerlist_; const common::ObMember &member = args.server_; const int64_t new_replica_num = args.new_replica_num_; const bool is_in_log_sync_memberlist = log_sync_member_list.contains(member); const bool is_in_degraded_learnerlist = degraded_learnerlist.contains(member); const bool is_in_learnerlist = curr_learner_list.contains(member); - const bool is_arb_replica = (log_ms_meta_.curr_.arbitration_member_ == member); - const bool has_arb_replica = (log_ms_meta_.curr_.arbitration_member_.is_valid()); + const bool is_arb_replica = (log_ms_meta_.curr_.config_.arbitration_member_ == member); + const bool has_arb_replica = (log_ms_meta_.curr_.config_.arbitration_member_.is_valid()); + const bool is_curr_lock_owner_valid = log_ms_meta_.curr_.lock_meta_.is_lock_owner_valid(); + const int64_t curr_lock_owner = log_ms_meta_.curr_.lock_meta_.lock_owner_; + const int64_t curr_lock_type = log_ms_meta_.curr_.lock_meta_.lock_type_; switch (args.type_) { case CHANGE_REPLICA_NUM: { @@ -1209,6 +1294,45 @@ int LogConfigMgr::check_config_change_args_(const LogConfigChangeArgs &args, boo { break; } + case TRY_LOCK_CONFIG_CHANGE: + { + if (args.lock_owner_ == curr_lock_owner) { + if (ConfigChangeLockType::LOCK_PAXOS_MEMBER_CHANGE == curr_lock_type) { + is_already_finished = true; + } else { + ret = OB_STATE_NOT_MATCH; + PALF_LOG(WARN, "lock state not match", KR(ret), K_(self), K_(log_ms_meta), K(args), K(curr_lock_type)); + } + } else if (args.lock_owner_ > curr_lock_owner) { + if (ConfigChangeLockType::LOCK_NOTHING == curr_lock_type) { + //go on locking + } else { + ret = OB_TRY_LOCK_CONFIG_CHANGE_CONFLICT; + PALF_LOG(WARN, "config change lock conflict", KR(ret), K_(self), K_(log_ms_meta), K(args)); + } + } else if (args.lock_owner_ < curr_lock_owner) { + ret = OB_STATE_NOT_MATCH; + PALF_LOG(WARN, "config change lock state not match", KR(ret), K_(self), K_(log_ms_meta), K(args)); + } else {/*do nothing*/} + break; + } + case UNLOCK_CONFIG_CHANGE: + { + if (args.lock_owner_ == curr_lock_owner) { + if (ConfigChangeLockType::LOCK_PAXOS_MEMBER_CHANGE == curr_lock_type) { + //go on unlock + } else if (ConfigChangeLockType::LOCK_NOTHING == curr_lock_type) { + is_already_finished = true; + } else { + ret = OB_NOT_SUPPORTED; + PALF_LOG(ERROR, "not supported lock type", KR(ret), K(curr_lock_type), K_(self), K_(log_ms_meta), K(args)); + } + } else { + ret = OB_STATE_NOT_MATCH; + PALF_LOG(WARN, "config change lock state not match", KR(ret), K_(self), K_(log_ms_meta), K(args)); + } + break; + } default: { ret = OB_INVALID_ARGUMENT; @@ -1216,32 +1340,6 @@ int LogConfigMgr::check_config_change_args_(const LogConfigChangeArgs &args, boo break; } } - LogConfigInfo new_config_info; - common::ObMemberList new_paxos_memberlist; - int64_t new_paxos_replica_num; - GlobalLearnerList unused_list; - // defensive check - // 1. check if reaches majority - // 2. new memberlist contains self - // 1F1A, if command is add_member(C, 5), if add C, length of log_sync_member_list is 2, log_sync_replica_num is 4, - // so reject add_member(C, 5) - // 2F, if command is add_member(C, 5), if add C, length of log_sync_member_list is 3, log_sync_replica_num is 5, - // so allow add_member(C, 5) - // 2F2F1A(ABCDE), remove(D, 5) success, then remove(C, 5). if remove C, length of log_sync_member_list is 2, log_sync_replica_num is 4, - // so reject remove(C, 5) - if (OB_SUCC(ret) && false == is_already_finished) { - if (OB_FAIL(generate_new_config_info_(state_mgr_->get_proposal_id(), args, new_config_info))) { - PALF_LOG(WARN, "generate_new_config_info_ failed", KR(ret), K_(palf_id), K_(self), K(args)); - } else if (OB_FAIL(new_config_info.convert_to_complete_config(new_paxos_memberlist, new_paxos_replica_num, unused_list))) { - } else if (false == new_paxos_memberlist.contains(self_) || false == new_config_info.log_sync_memberlist_.contains(self_)) { - PALF_LOG(ERROR, "new memberlist doesn't contain self", KR(ret), K_(palf_id), K_(self), K(new_config_info), K(new_paxos_memberlist)); - } else if (false == can_memberlist_majority_(new_config_info.log_sync_memberlist_.get_member_number(), new_config_info.log_sync_replica_num_) || - false == can_memberlist_majority_(new_paxos_memberlist.get_member_number(), new_paxos_replica_num)) { - ret = OB_INVALID_ARGUMENT; - PALF_LOG(WARN, "can't change config, memberlist don't reach majority", KR(ret), K_(palf_id), K_(self), K(new_config_info), - K(new_paxos_memberlist), K(new_paxos_replica_num), K(args)); - } - } } return ret; } @@ -1273,7 +1371,7 @@ int LogConfigMgr::check_args_and_generate_config(const LogConfigChangeArgs &args const int64_t proposal_id, const int64_t election_epoch, bool &is_already_finished, - LogConfigInfo &new_config_info) const + LogConfigInfoV2 &new_config_info) const { int ret = OB_SUCCESS; SpinLockGuard guard(lock_); @@ -1378,7 +1476,7 @@ int LogConfigMgr::append_config_meta_(const int64_t curr_proposal_id, bool &is_already_finished) { int ret = OB_SUCCESS; - LogConfigInfo new_config_info; + LogConfigInfoV2 new_config_info; bool has_arb_member = false; bool unused_bool; if (INVALID_PROPOSAL_ID == curr_proposal_id || !args.is_valid()) { @@ -1402,7 +1500,7 @@ int LogConfigMgr::append_config_meta_(const int64_t curr_proposal_id, } else if (OB_FAIL(generate_new_config_info_(curr_proposal_id, args, new_config_info))) { PALF_LOG(WARN, "generate_new_config_info_ failed", KR(ret), K_(palf_id), K_(self), K(args)); // new_member_list contains arb member, stop appending logs and check log barrier - } else if (FALSE_IT(has_arb_member = new_config_info.arbitration_member_.is_valid())) { + } else if (FALSE_IT(has_arb_member = new_config_info.config_.arbitration_member_.is_valid())) { } else if (OB_FAIL(update_election_meta_(new_config_info))) { if (OB_OP_NOT_ALLOW == ret) { ret = OB_EAGAIN; @@ -1432,7 +1530,7 @@ int LogConfigMgr::append_config_meta_(const int64_t curr_proposal_id, } int LogConfigMgr::update_match_lsn_map_(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info) + const LogConfigInfoV2 &new_config_info) { int ret = OB_SUCCESS; ObMemberList added_memberlist; @@ -1442,16 +1540,16 @@ int LogConfigMgr::update_match_lsn_map_(const LogConfigChangeArgs &args, } else if (is_remove_log_sync_member_list(args.type_) && OB_FAIL(removed_memberlist.add_member(args.server_))) { PALF_LOG(WARN, "add_member failed", K(ret), K_(palf_id), K_(self), K(added_memberlist), K(args)); } - if (OB_SUCC(ret) && OB_FAIL(sw_->config_change_update_match_lsn_map(added_memberlist, \ - removed_memberlist, new_config_info.log_sync_memberlist_, \ - new_config_info.log_sync_replica_num_))) { + if (OB_SUCC(ret) && OB_FAIL(sw_->config_change_update_match_lsn_map(added_memberlist, + removed_memberlist, new_config_info.config_.log_sync_memberlist_, + new_config_info.config_.log_sync_replica_num_))) { PALF_LOG(WARN, "config_change_update_match_lsn_map failed", K(ret), K_(palf_id), K_(self), K(added_memberlist), K(removed_memberlist)); } return ret; } // caller hold lock_ -int LogConfigMgr::append_config_info_(const LogConfigInfo &config_info) +int LogConfigMgr::append_config_info_(const LogConfigInfoV2 &config_info) { int ret = OB_SUCCESS; common::ObMemberList alive_paxos_memberlist; @@ -1494,7 +1592,7 @@ int LogConfigMgr::set_resend_log_info_() // be applied to current ConfigMeta safely. int LogConfigMgr::generate_new_config_info_(const int64_t proposal_id, const LogConfigChangeArgs &args, - LogConfigInfo &new_config_info) const + LogConfigInfoV2 &new_config_info) const { int ret = OB_SUCCESS; const LogConfigChangeType cc_type = args.type_; @@ -1503,7 +1601,7 @@ int LogConfigMgr::generate_new_config_info_(const int64_t proposal_id, int64_t curr_replica_num = -1; if (INVALID_PROPOSAL_ID == proposal_id || !args.is_valid()) { ret = OB_INVALID_ARGUMENT; - } else if (OB_FAIL(new_config_info.config_version_.inc_update_version(proposal_id))) { + } else if (OB_FAIL(new_config_info.config_.config_version_.inc_update_version(proposal_id))) { PALF_LOG(WARN, "generate config_version failed", KR(ret), K_(palf_id), K_(self), K(new_config_info), K(proposal_id)); } else if (STARTWORKING == cc_type) { // pass @@ -1516,11 +1614,11 @@ int LogConfigMgr::generate_new_config_info_(const int64_t proposal_id, if (is_use_replica_num_args(cc_type)) { new_log_sync_replica_num = args.new_replica_num_; } else if (is_add_log_sync_member_list(cc_type)) { - new_log_sync_replica_num = new_config_info.log_sync_replica_num_ + 1; + new_log_sync_replica_num = new_config_info.config_.log_sync_replica_num_ + 1; } else if (is_remove_log_sync_member_list(cc_type)) { - new_log_sync_replica_num = new_config_info.log_sync_replica_num_ - 1; + new_log_sync_replica_num = new_config_info.config_.log_sync_replica_num_ - 1; } else if (is_arb_member_change_type(cc_type)) { - new_log_sync_replica_num = new_config_info.log_sync_replica_num_; + new_log_sync_replica_num = new_config_info.config_.log_sync_replica_num_; } else { ret = OB_ERR_UNEXPECTED; PALF_LOG(ERROR, "unexpected config change type", KR(ret), K_(palf_id), K_(self), K(args), K(new_config_info)); @@ -1530,51 +1628,51 @@ int LogConfigMgr::generate_new_config_info_(const int64_t proposal_id, if (is_add_member_list(cc_type)) { // update log_sync_member_list or arb_member if (is_add_log_sync_member_list(args.type_)) { - if (OB_FAIL(new_config_info.log_sync_memberlist_.add_member(member))) { + if (OB_FAIL(new_config_info.config_.log_sync_memberlist_.add_member(member))) { PALF_LOG(WARN, "new_member_list add_member failed", KR(ret), K_(palf_id), K_(self), K(args), K(new_config_info)); } } else { - new_config_info.arbitration_member_ = member; + new_config_info.config_.arbitration_member_ = member; } } // memberlist remove, update replica number if (OB_SUCC(ret) && is_remove_member_list(cc_type)) { // update log_sync_member_list or arb_member if (is_remove_log_sync_member_list(args.type_)) { - if (new_config_info.log_sync_memberlist_.contains(member)) { - if (OB_FAIL(new_config_info.log_sync_memberlist_.remove_server(member.get_server()))) { + if (new_config_info.config_.log_sync_memberlist_.contains(member)) { + if (OB_FAIL(new_config_info.config_.log_sync_memberlist_.remove_server(member.get_server()))) { PALF_LOG(WARN, "remove member failed", KR(ret), K_(palf_id), K_(self), K(args), K(new_config_info)); } - } else if (new_config_info.degraded_learnerlist_.contains(member)) { - if (OB_FAIL(new_config_info.degraded_learnerlist_.remove_learner(member))) { + } else if (new_config_info.config_.degraded_learnerlist_.contains(member)) { + if (OB_FAIL(new_config_info.config_.degraded_learnerlist_.remove_learner(member))) { PALF_LOG(WARN, "new_member_list remove member failed", KR(ret), K_(palf_id), K_(self), K(args), K(new_config_info)); } // If dst member is already degraded learner, just remove it and no need update log_sync_replica_num_. - new_log_sync_replica_num = new_config_info.log_sync_replica_num_; + new_log_sync_replica_num = new_config_info.config_.log_sync_replica_num_; } else { ret = OB_INVALID_ARGUMENT; PALF_LOG(WARN, "member to be removed does not exist", KR(ret), K_(palf_id), K_(self), K(args), K(new_config_info)); } } else { - new_config_info.arbitration_member_.reset(); + new_config_info.config_.arbitration_member_.reset(); } } if (OB_SUCC(ret) && FORCE_SINGLE_MEMBER == cc_type) { // force set single member - new_config_info.log_sync_memberlist_.reset(); - new_config_info.degraded_learnerlist_.reset(); - new_config_info.arbitration_member_.reset(); - new_config_info.log_sync_memberlist_.add_member(member); - new_config_info.log_sync_replica_num_ = new_log_sync_replica_num; + new_config_info.config_.log_sync_memberlist_.reset(); + new_config_info.config_.degraded_learnerlist_.reset(); + new_config_info.config_.arbitration_member_.reset(); + new_config_info.config_.log_sync_memberlist_.add_member(member); + new_config_info.config_.log_sync_replica_num_ = new_log_sync_replica_num; } // learnerlist add if (OB_SUCC(ret) && is_add_learner_list(cc_type)) { if (DEGRADE_ACCEPTOR_TO_LEARNER == cc_type) { - if (OB_FAIL(new_config_info.degraded_learnerlist_.add_learner(member))) { + if (OB_FAIL(new_config_info.config_.degraded_learnerlist_.add_learner(member))) { PALF_LOG(WARN, "new_learner_list add_learner failed", KR(ret), K_(palf_id), K_(self), K(args), K(new_config_info)); } } else { - if (OB_FAIL(new_config_info.learnerlist_.add_learner(member))) { + if (OB_FAIL(new_config_info.config_.learnerlist_.add_learner(member))) { PALF_LOG(WARN, "new_learner_list add_learner failed", KR(ret), K_(palf_id), K_(self), K(args), K(new_config_info)); } } @@ -1582,18 +1680,31 @@ int LogConfigMgr::generate_new_config_info_(const int64_t proposal_id, // learnerlist remove if (OB_SUCC(ret) && is_remove_learner_list(cc_type)) { if (UPGRADE_LEARNER_TO_ACCEPTOR == cc_type) { - if (OB_FAIL(new_config_info.degraded_learnerlist_.remove_learner(member.get_server()))) { + if (OB_FAIL(new_config_info.config_.degraded_learnerlist_.remove_learner(member.get_server()))) { PALF_LOG(WARN, "new_learner_list add_learner failed", KR(ret), K_(palf_id), K_(self), K(args), K(new_config_info)); } } else { - if (OB_FAIL(new_config_info.learnerlist_.remove_learner(member.get_server()))) { + if (OB_FAIL(new_config_info.config_.learnerlist_.remove_learner(member.get_server()))) { PALF_LOG(WARN, "new_learner_list add_learner failed", KR(ret), K_(palf_id), K_(self), K(args), K(new_config_info)); } } } + + // try lock config_change + if (OB_SUCC(ret) && is_try_lock_config_change(cc_type)) { + if (OB_FAIL(new_config_info.lock_meta_.generate(args.lock_owner_, args.lock_type_))) { + PALF_LOG(WARN, "failed to generate lock_meta", KR(ret), K_(palf_id), K_(self), K(args), K(new_config_info)); + } + } + + //unlock config_change + if (OB_SUCC(ret) && is_unlock_config_change(cc_type)) { + new_config_info.lock_meta_.unlock(); + } + // generate log_sync_replica_num_ if (OB_SUCC(ret)) { - new_config_info.log_sync_replica_num_ = new_log_sync_replica_num; + new_config_info.config_.log_sync_replica_num_ = new_log_sync_replica_num; } } return ret; @@ -1625,7 +1736,7 @@ int LogConfigMgr::update_election_meta_(const ObMemberList &member_list, return ret; } -int LogConfigMgr::update_election_meta_(const LogConfigInfo &info) +int LogConfigMgr::update_election_meta_(const LogConfigInfoV2 &info) { int ret = OB_SUCCESS; common::ObMemberList memberlist; @@ -1634,7 +1745,7 @@ int LogConfigMgr::update_election_meta_(const LogConfigInfo &info) if (OB_FAIL(info.convert_to_complete_config(memberlist, replica_num, unused_list))) { PALF_LOG(WARN, "convert_to_complete_config failed", K(ret), K_(palf_id), K(info)); } else { - ret = update_election_meta_(memberlist, info.config_version_, replica_num); + ret = update_election_meta_(memberlist, info.config_.config_version_, replica_num); } return ret; } @@ -1646,7 +1757,7 @@ int LogConfigMgr::confirm_start_working_log(const int64_t proposal_id, int ret = OB_SUCCESS; SpinLockGuard guard(lock_); const bool has_finished = (ConfigChangeState::INIT == state_ && config_version.is_valid()) || - (ConfigChangeState::CHANGING == state_ && config_version.is_valid() && log_ms_meta_.curr_.config_version_ > config_version); + (ConfigChangeState::CHANGING == state_ && config_version.is_valid() && log_ms_meta_.curr_.config_.config_version_ > config_version); common::ObMember dummy_member; const LogConfigChangeArgs args(dummy_member, 1, STARTWORKING); if (IS_NOT_INIT) { @@ -1774,7 +1885,7 @@ int LogConfigMgr::submit_config_log_(const common::ObMemberList &paxos_member_li // barrier condition may don't match, need retry } else { (void) dst_member_list.remove_server(self_); - const LogConfigVersion config_version = config_meta.curr_.config_version_; + const LogConfigVersion config_version = config_meta.curr_.config_.config_version_; FlushMetaCbCtx cb_ctx; cb_ctx.type_ = MetaType::CHANGE_CONFIG_META; cb_ctx.proposal_id_ = proposal_id; @@ -1804,11 +1915,11 @@ int LogConfigMgr::submit_config_log_(const common::ObMemberList &paxos_member_li bool LogConfigMgr::can_receive_config_log(const common::ObAddr &leader, const LogConfigMeta &meta) const { bool bool_ret = false; - const LogConfigVersion &config_version = meta.curr_.config_version_; + const LogConfigVersion &config_version = meta.curr_.config_.config_version_; int ret = OB_SUCCESS; if (IS_NOT_INIT || !config_version.is_valid()) { } else { - bool_ret = config_version > log_ms_meta_.curr_.config_version_; + bool_ret = config_version > log_ms_meta_.curr_.config_.config_version_; if ((persistent_config_version_ == config_version) && OB_FAIL(log_engine_->submit_change_config_meta_resp(leader, meta.proposal_id_, config_version))) { PALF_LOG(WARN, "submit_change_config_meta_resp fail", K(ret), K_(palf_id), K_(self), K(leader), K(meta)); @@ -1834,7 +1945,7 @@ int LogConfigMgr::receive_config_log(const common::ObAddr &leader, const LogConf FlushMetaCbCtx cb_ctx; cb_ctx.type_ = MetaType::CHANGE_CONFIG_META; cb_ctx.proposal_id_ = meta.proposal_id_; - cb_ctx.config_version_ = meta.curr_.config_version_; + cb_ctx.config_version_ = meta.curr_.config_.config_version_; if (OB_FAIL(log_engine_->submit_flush_change_config_meta_task(cb_ctx, meta))) { PALF_LOG(WARN, "LogEngine submit_flush_change_config_meta_task failed", KR(ret), K_(palf_id), K_(self), K(meta)); } else if (OB_FAIL(append_config_info_(meta.curr_))) { @@ -1860,7 +1971,7 @@ int LogConfigMgr::ack_config_log(const common::ObAddr &sender, ret = OB_INVALID_ARGUMENT; PALF_LOG(WARN, "invalid argument", KR(ret), K_(palf_id), K_(self), K(sender)); } else if (proposal_id != log_ms_meta_.proposal_id_ || - config_version != log_ms_meta_.curr_.config_version_) { + config_version != log_ms_meta_.curr_.config_.config_version_) { ret = OB_STATE_NOT_MATCH; PALF_LOG(WARN, "config_version has been changed", KR(ret), K_(palf_id), K_(self), K_(log_ms_meta), K(proposal_id), K_(state), K(config_version), K(sender)); @@ -1903,6 +2014,10 @@ bool LogConfigChangeArgs::is_valid() const bool_ret = bool_ret && ((is_use_replica_num_args(type_))? is_valid_replica_num(new_replica_num_): true); bool_ret = bool_ret && ((type_ == CHANGE_REPLICA_NUM)? \ (curr_member_list_.is_valid() && is_valid_replica_num(curr_replica_num_) && is_valid_replica_num(new_replica_num_)): true); + const bool is_lock_meta_valid = (OB_INVALID_CONFIG_CHANGE_LOCK_OWNER != lock_owner_); + bool_ret = bool_ret && ((TRY_LOCK_CONFIG_CHANGE == type_ || UNLOCK_CONFIG_CHANGE == type_) ? is_lock_meta_valid : true); + // Note: We do not check the validity of config_version_, because it's new variable in version 4.2. + // If a OBServer v4.1 sends a LogConfigChangeCmd to the leader v4.2, config_version_ may be invalid return bool_ret; } @@ -1914,11 +2029,13 @@ void LogConfigChangeArgs::reset() new_replica_num_ = 0; config_version_.reset(); ref_scn_.reset() ; + lock_owner_ = OB_INVALID_CONFIG_CHANGE_LOCK_OWNER; + lock_type_ = ConfigChangeLockType::LOCK_NOTHING; type_ = INVALID_LOG_CONFIG_CHANGE_TYPE; } int LogConfigMgr::check_follower_sync_status(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info, + const LogConfigInfoV2 &new_config_info, bool &added_member_has_new_version) const { int ret = OB_SUCCESS; @@ -1927,7 +2044,7 @@ int LogConfigMgr::check_follower_sync_status(const LogConfigChangeArgs &args, } int LogConfigMgr::wait_log_barrier(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info) const + const LogConfigInfoV2 &new_config_info) const { SpinLockGuard guard(lock_); return wait_log_barrier_(args, new_config_info); @@ -1936,10 +2053,10 @@ int LogConfigMgr::wait_log_barrier(const LogConfigChangeArgs &args, int LogConfigMgr::wait_log_barrier_before_start_working_(const LogConfigChangeArgs &args) { int ret = OB_SUCCESS; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; if (OB_FAIL(generate_new_config_info_(state_mgr_->get_proposal_id(), args, config_info))) { PALF_LOG(WARN, "generate_new_config_info_ failed", KR(ret), K_(palf_id), K_(self), K(args)); - } else if (config_info.arbitration_member_.is_valid() == false) { + } else if (config_info.config_.arbitration_member_.is_valid() == false) { } else if (OB_FAIL(state_mgr_->set_changing_config_with_arb())) { PALF_LOG(WARN, "set_changing_config_with_arb failed", KR(ret), K_(palf_id), K_(self)); } else if (OB_FAIL(renew_config_change_barrier_())) { @@ -1952,7 +2069,7 @@ int LogConfigMgr::wait_log_barrier_before_start_working_(const LogConfigChangeAr } int LogConfigMgr::wait_log_barrier_(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info) const + const LogConfigInfoV2 &new_config_info) const { int ret = OB_SUCCESS; LSN first_committed_end_lsn; @@ -1968,7 +2085,7 @@ int LogConfigMgr::wait_log_barrier_(const LogConfigChangeArgs &args, LSN prev_log_end_lsn = checking_barrier_.prev_end_lsn_; start_wait_barrier_time_us_ = (OB_INVALID_TIMESTAMP == start_wait_barrier_time_us_)? \ curr_ts_us: start_wait_barrier_time_us_; - if (new_config_info.log_sync_memberlist_.get_member_number() == 0) { + if (new_config_info.config_.log_sync_memberlist_.get_member_number() == 0) { ret = OB_INVALID_ARGUMENT; } else if (curr_ts_us - start_wait_barrier_time_us_ > MAX_WAIT_BARRIER_TIME_US_FOR_RECONFIGURATION && args.type_ != LogConfigChangeType::STARTWORKING) { @@ -2011,7 +2128,7 @@ int LogConfigMgr::wait_log_barrier_(const LogConfigChangeArgs &args, } int LogConfigMgr::check_follower_sync_status_(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info, + const LogConfigInfoV2 &new_config_info, bool &added_member_has_new_version) const { int ret = OB_SUCCESS; @@ -2028,7 +2145,7 @@ int LogConfigMgr::check_follower_sync_status_(const LogConfigChangeArgs &args, (void) sw_->get_committed_end_lsn(first_leader_committed_end_lsn); const bool need_skip_log_barrier = mode_mgr_->need_skip_log_barrier(); - if (new_config_info.log_sync_memberlist_.get_member_number() == 0) { + if (new_config_info.config_.log_sync_memberlist_.get_member_number() == 0) { ret = OB_INVALID_ARGUMENT; } else if (OB_FAIL(sync_get_committed_end_lsn_(args, new_config_info, need_purge_throttling, need_remote_check, conn_timeout_us, first_committed_end_lsn, added_member_has_new_version, @@ -2046,8 +2163,8 @@ int LogConfigMgr::check_follower_sync_status_(const LogConfigChangeArgs &args, // when quorum has been changed (e.g., 1 -> 2), committed_end_lsn of new memberlist may always be behind the committed_end_lsn of // leader, so we relax the condition for adding members which has changed quorum } else if (is_add_log_sync_member_list(args.type_) && - (new_config_info.log_sync_replica_num_ / 2) > (log_ms_meta_.curr_.log_sync_replica_num_ / 2) && - log_ms_meta_.curr_.arbitration_member_.is_valid()) { + (new_config_info.config_.log_sync_replica_num_ / 2) > (log_ms_meta_.curr_.config_.log_sync_replica_num_ / 2) && + log_ms_meta_.curr_.config_.arbitration_member_.is_valid()) { if (added_member_flushed_end_lsn.is_valid() && first_leader_committed_end_lsn - added_member_flushed_end_lsn < LEADER_DEFAULT_GROUP_BUFFER_SIZE && (added_member_last_slide_log_id != INT64_MAX && @@ -2159,7 +2276,7 @@ int LogConfigMgr::check_servers_lsn_and_version_(const common::ObAddr &server, // 2. check if the config_version of added member are same to current config_version. // if the config change don't add member to list, return true int LogConfigMgr::sync_get_committed_end_lsn_(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info, + const LogConfigInfoV2 &new_config_info, const bool need_purge_throttling, const bool need_remote_check, const int64_t conn_timeout_us, @@ -2170,10 +2287,10 @@ int LogConfigMgr::sync_get_committed_end_lsn_(const LogConfigChangeArgs &args, { int ret = OB_SUCCESS, tmp_ret = OB_SUCCESS; int64_t log_sync_resp_cnt = 0, paxos_resp_cnt = 0; - const LogConfigVersion config_version = log_ms_meta_.curr_.config_version_; + const LogConfigVersion config_version = log_ms_meta_.curr_.config_.config_version_; LSN lsn_array[OB_MAX_MEMBER_NUMBER]; - const common::ObMemberList new_log_sync_memberlist = new_config_info.log_sync_memberlist_; - const int64_t new_log_sync_replica_num = new_config_info.log_sync_replica_num_; + const common::ObMemberList new_log_sync_memberlist = new_config_info.config_.log_sync_memberlist_; + const int64_t new_log_sync_replica_num = new_config_info.config_.log_sync_replica_num_; common::ObMemberList new_paxos_memberlist; int64_t new_paxos_replica_num = 0; GlobalLearnerList unused_list; @@ -2197,7 +2314,7 @@ int LogConfigMgr::sync_get_committed_end_lsn_(const LogConfigChangeArgs &args, if (OB_SUCCESS != (tmp_ret = new_paxos_memberlist.get_server_by_index(i, server))) { PALF_LOG(ERROR, "get_server_by_index failed", KR(ret), K_(palf_id), K_(self), K(i), K(new_paxos_memberlist)); } else if (FALSE_IT(is_added_member = (is_add_member_list(args.type_) && (args.server_.get_server() == server)))) { - } else if (FALSE_IT(is_arb_member = (server == new_config_info.arbitration_member_.get_server()))) { + } else if (FALSE_IT(is_arb_member = (server == new_config_info.config_.arbitration_member_.get_server()))) { } else if (FALSE_IT(force_remote_check = is_added_member || need_purge_throttling || need_remote_check)) { } else if (OB_SUCCESS != (tmp_ret = check_servers_lsn_and_version_(server, config_version, conn_timeout_us, force_remote_check, need_purge_throttling, max_flushed_end_lsn, has_same_version, @@ -2576,7 +2693,7 @@ int LogConfigMgr::handle_register_parent_req(const LogLearner &child, const bool PALF_LOG(ERROR, "invalid register ret", K(ret), K_(palf_id), K_(self), K(reg_ret)); } PALF_LOG(INFO, "handle_register_parent_req success", K(ret), K(child), K(is_to_leader), K(candidate_list), - K(reg_ret), K_(children), "member_list", log_ms_meta_.curr_.log_sync_memberlist_); + K(reg_ret), K_(children), "member_list", log_ms_meta_.curr_.config_.log_sync_memberlist_); } if (OB_FAIL(submit_retire_children_req_(retired_children))) { PALF_LOG(WARN, "submit_retire_children_req failed", KR(ret), K_(palf_id), K_(self), K(retired_children)); @@ -2844,7 +2961,7 @@ int LogConfigMgr::generate_candidate_list_(const LogLearner &child, LogCandidate int LogConfigMgr::generate_candidate_list_from_member_(const LogLearner &child, LogCandidateList &candidate_list) { int ret = OB_SUCCESS; - const ObMemberList &curr_member_list = log_ms_meta_.curr_.log_sync_memberlist_; + const ObMemberList &curr_member_list = log_ms_meta_.curr_.config_.log_sync_memberlist_; for (int64_t i = 0; i < curr_member_list.get_member_number(); ++i) { ObAddr addr; ObRegion region; @@ -2914,7 +3031,7 @@ int LogConfigMgr::submit_retire_children_req_(const LogLearnerList &retired_chil int LogConfigMgr::get_member_regions_(common::ObArrayHashMap ®ion_map) const { int ret = OB_SUCCESS; - const ObMemberList &curr_member_list = log_ms_meta_.curr_.log_sync_memberlist_; + const ObMemberList &curr_member_list = log_ms_meta_.curr_.config_.log_sync_memberlist_; for (int64_t i = 0; i < curr_member_list.get_member_number(); ++i) { ObAddr addr; ObRegion region; diff --git a/src/logservice/palf/log_config_mgr.h b/src/logservice/palf/log_config_mgr.h old mode 100644 new mode 100755 index 2ea4de164..74a5970d0 --- a/src/logservice/palf/log_config_mgr.h +++ b/src/logservice/palf/log_config_mgr.h @@ -38,7 +38,7 @@ namespace palf { class LogSlidingWindow; class LogStateMgr; -class LogConfigInfo; +class LogConfigInfoV2; class LogConfigMeta; class LSN; class LogEngine; @@ -68,6 +68,8 @@ enum LogConfigChangeType UPGRADE_LEARNER_TO_ACCEPTOR, STARTWORKING, FORCE_SINGLE_MEMBER, + TRY_LOCK_CONFIG_CHANGE, + UNLOCK_CONFIG_CHANGE, }; inline const char *LogConfigChangeType2Str(const LogConfigChangeType state) @@ -97,6 +99,18 @@ inline const char *LogConfigChangeType2Str(const LogConfigChangeType state) typedef common::ObArrayHashMap LogMemberRegionMap; +// Note: We need to check if the cluster has been upgraded to version 4.2. +// If not, invalid config_version is allowed because OBServer v4.1 +// may send a LogConfigChangeCmd (with invalid config_version) to +// the leader v4.2, we need to allow the reconfiguration. +inline bool need_check_config_version(const LogConfigChangeType type) +{ + const bool is_cluster_already_4200 = GET_MIN_CLUSTER_VERSION() >= CLUSTER_VERSION_4_2_0_0; + return (is_cluster_already_4200) && + (ADD_MEMBER == type || ADD_MEMBER_AND_NUM == type || + SWITCH_LEARNER_TO_ACCEPTOR == type); +} + inline bool is_add_log_sync_member_list(const LogConfigChangeType type) { return ADD_MEMBER == type || ADD_MEMBER_AND_NUM == type || @@ -155,6 +169,24 @@ inline bool is_may_change_replica_num(const LogConfigChangeType type) return is_add_member_list(type) || is_remove_member_list(type) || CHANGE_REPLICA_NUM == type || FORCE_SINGLE_MEMBER == type; } +inline bool is_paxos_member_list_change(const LogConfigChangeType type) +{ + return (ADD_MEMBER == type || REMOVE_MEMBER == type + || ADD_MEMBER_AND_NUM == type || REMOVE_MEMBER_AND_NUM == type + || SWITCH_LEARNER_TO_ACCEPTOR == type || SWITCH_ACCEPTOR_TO_LEARNER == type + || CHANGE_REPLICA_NUM == type); +} + +inline bool is_try_lock_config_change(const LogConfigChangeType type) +{ + return TRY_LOCK_CONFIG_CHANGE == type; +} + +inline bool is_unlock_config_change(const LogConfigChangeType type) +{ + return UNLOCK_CONFIG_CHANGE == type; +} + struct LogConfigChangeArgs { public: @@ -165,26 +197,39 @@ public: new_replica_num_(0), config_version_(), ref_scn_(), + lock_owner_(OB_INVALID_CONFIG_CHANGE_LOCK_OWNER), + lock_type_(ConfigChangeLockType::LOCK_NOTHING), type_(INVALID_LOG_CONFIG_CHANGE_TYPE) { } - LogConfigChangeArgs(const LogConfigVersion &config_version, - const share::SCN &ref_scn, + LogConfigChangeArgs(const common::ObMember &server, + const int64_t new_replica_num, + const LogConfigVersion &config_version, const LogConfigChangeType type) - : server_(), curr_member_list_(), curr_replica_num_(0), new_replica_num_(0), - config_version_(config_version), ref_scn_(ref_scn), type_(type) { } + : server_(server), curr_member_list_(), curr_replica_num_(0), new_replica_num_(new_replica_num), + config_version_(config_version), ref_scn_(), lock_owner_(OB_INVALID_CONFIG_CHANGE_LOCK_OWNER), + lock_type_(ConfigChangeLockType::LOCK_NOTHING), type_(type) { } LogConfigChangeArgs(const common::ObMember &server, const int64_t new_replica_num, const LogConfigChangeType type) : server_(server), curr_member_list_(), curr_replica_num_(0), new_replica_num_(new_replica_num), - config_version_(), ref_scn_(), type_(type) { } + config_version_(), ref_scn_(), lock_owner_(OB_INVALID_CONFIG_CHANGE_LOCK_OWNER), + lock_type_(ConfigChangeLockType::LOCK_NOTHING), type_(type) { } LogConfigChangeArgs(const common::ObMemberList &member_list, const int64_t curr_replica_num, const int64_t new_replica_num, const LogConfigChangeType type) : server_(), curr_member_list_(member_list), curr_replica_num_(curr_replica_num), new_replica_num_(new_replica_num), - config_version_(), ref_scn_(), type_(type) { } + config_version_(), ref_scn_(), lock_owner_(OB_INVALID_CONFIG_CHANGE_LOCK_OWNER), + lock_type_(ConfigChangeLockType::LOCK_NOTHING), type_(type) { } + + LogConfigChangeArgs(const int64_t lock_owner, + const int64_t lock_type, + const LogConfigChangeType type) + : server_(), curr_member_list_(), curr_replica_num_(0), new_replica_num_(), + config_version_(), ref_scn_(), lock_owner_(lock_owner), + lock_type_(lock_type), type_(type) { } ~LogConfigChangeArgs() { @@ -192,14 +237,43 @@ public: } bool is_valid() const; void reset(); + + const char *Type2Str(const LogConfigChangeType state) const + { + #define CHECK_LOG_CONFIG_TYPE_STR(x) case(LogConfigChangeType::x): return #x + switch(state) + { + CHECK_LOG_CONFIG_TYPE_STR(CHANGE_REPLICA_NUM); + CHECK_LOG_CONFIG_TYPE_STR(ADD_MEMBER); + CHECK_LOG_CONFIG_TYPE_STR(ADD_ARB_MEMBER); + CHECK_LOG_CONFIG_TYPE_STR(REMOVE_MEMBER); + CHECK_LOG_CONFIG_TYPE_STR(REMOVE_ARB_MEMBER); + CHECK_LOG_CONFIG_TYPE_STR(ADD_MEMBER_AND_NUM); + CHECK_LOG_CONFIG_TYPE_STR(REMOVE_MEMBER_AND_NUM); + CHECK_LOG_CONFIG_TYPE_STR(ADD_LEARNER); + CHECK_LOG_CONFIG_TYPE_STR(REMOVE_LEARNER); + CHECK_LOG_CONFIG_TYPE_STR(SWITCH_LEARNER_TO_ACCEPTOR); + CHECK_LOG_CONFIG_TYPE_STR(SWITCH_ACCEPTOR_TO_LEARNER); + CHECK_LOG_CONFIG_TYPE_STR(DEGRADE_ACCEPTOR_TO_LEARNER); + CHECK_LOG_CONFIG_TYPE_STR(UPGRADE_LEARNER_TO_ACCEPTOR); + CHECK_LOG_CONFIG_TYPE_STR(STARTWORKING); + CHECK_LOG_CONFIG_TYPE_STR(TRY_LOCK_CONFIG_CHANGE); + CHECK_LOG_CONFIG_TYPE_STR(UNLOCK_CONFIG_CHANGE); + default: + return "Invalid"; + } + #undef CHECK_LOG_CONFIG_TYPE_STR + } TO_STRING_KV(K_(server), K_(curr_member_list), K_(curr_replica_num), K_(new_replica_num), - K_(config_version), K_(ref_scn), "type", LogConfigChangeType2Str(type_)); + K_(config_version), K_(ref_scn), K_(lock_owner), K_(lock_type), "type", LogConfigChangeType2Str(type_)); common::ObMember server_; common::ObMemberList curr_member_list_; int64_t curr_replica_num_; int64_t new_replica_num_; LogConfigVersion config_version_; share::SCN ref_scn_; + int64_t lock_owner_; + int64_t lock_type_; LogConfigChangeType type_; }; @@ -338,10 +412,11 @@ public: // else return other errno virtual int get_replica_num(int64_t &replica_num) const; const common::ObAddr &get_parent() const; + int get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked); virtual int leader_do_loop_work(bool &need_change_config); virtual int switch_state(); virtual int wait_log_barrier(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info) const; + const LogConfigInfoV2 &new_config_info) const; virtual int renew_config_change_barrier(); // ================= Config Change ================= @@ -349,7 +424,7 @@ public: const int64_t proposal_id, const int64_t election_epoch, bool &is_already_finished, - LogConfigInfo &new_config_info) const; + LogConfigInfoV2 &new_config_info) const; int pre_sync_config_log_and_mode_meta(const common::ObMember &server, const int64_t proposal_id); int start_change_config(int64_t &proposal_id, int64_t &election_epoch, @@ -382,10 +457,10 @@ public: virtual int submit_broadcast_leader_info(const int64_t proposal_id) const; virtual void reset_status(); int check_follower_sync_status(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info, + const LogConfigInfoV2 &new_config_info, bool &added_member_has_new_version) const; int wait_log_barrier_(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info) const; + const LogConfigInfoV2 &new_config_info) const; int wait_log_barrier_before_start_working_(const LogConfigChangeArgs &args); int sync_meta_for_arb_election_leader(); void set_sync_to_degraded_learners(); @@ -434,19 +509,22 @@ private: static constexpr int64_t MAX_WAIT_BARRIER_TIME_US_FOR_RECONFIGURATION = 2 * 1000 * 1000; static constexpr int64_t MAX_WAIT_BARRIER_TIME_US_FOR_STABLE_LOG = 1 * 1000 * 1000; private: - int set_initial_config_info_(const LogConfigInfo &config_info, + int set_initial_config_info_(const LogConfigInfoV2 &config_info, const int64_t proposal_id, LogConfigVersion &init_config_version); bool can_memberlist_majority_(const int64_t new_member_list_len, const int64_t new_replica_num) const; int check_config_change_args_(const LogConfigChangeArgs &args, bool &is_already_finished) const; + int check_config_change_args_by_type_(const LogConfigChangeArgs &args, bool &is_already_finished) const; int check_config_version_matches_state_(const LogConfigChangeType &type, const LogConfigVersion &config_version) const; int generate_new_config_info_(const int64_t proposal_id, const LogConfigChangeArgs &args, - LogConfigInfo &new_config_info) const; - int append_config_info_(const LogConfigInfo &config_info); - int apply_config_info_(const LogConfigInfo &config_info); - int update_match_lsn_map_(const LogConfigChangeArgs &args, const LogConfigInfo &new_config_info); - int update_election_meta_(const LogConfigInfo &info); + LogConfigInfoV2 &new_config_info) const; + + + int append_config_info_(const LogConfigInfoV2 &config_info); + int apply_config_info_(const LogConfigInfoV2 &config_info); + int update_match_lsn_map_(const LogConfigChangeArgs &args, const LogConfigInfoV2 &new_config_info); + int update_election_meta_(const LogConfigInfoV2 &info); int update_election_meta_(const ObMemberList &member_list, const LogConfigVersion &config_version, const int64_t new_replica_num); @@ -490,7 +568,7 @@ private: bool &has_same_version, int64_t &last_slide_log_id) const; int sync_get_committed_end_lsn_(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info, + const LogConfigInfoV2 &new_config_info, const bool need_purge_throttling, const bool need_remote_check, const int64_t conn_timeout_us, @@ -499,7 +577,7 @@ private: LSN &added_member_flushed_end_lsn, int64_t &added_member_last_slide_log_id) const; int check_follower_sync_status_(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info, + const LogConfigInfoV2 &new_config_info, bool &added_member_has_new_version) const; int pre_sync_config_log_and_mode_meta_(const common::ObMember &server, const int64_t proposal_id, diff --git a/src/logservice/palf/log_define.h b/src/logservice/palf/log_define.h index 4269bf08f..e4a0650c2 100644 --- a/src/logservice/palf/log_define.h +++ b/src/logservice/palf/log_define.h @@ -149,6 +149,8 @@ constexpr int LOG_WRITE_FLAG = O_RDWR | O_DIRECT | O_SYNC; constexpr mode_t FILE_OPEN_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // =========== Disk io end ==================== +const int64_t OB_INVALID_CONFIG_CHANGE_LOCK_OWNER = -1; + enum ObReplicaState { INVALID_STATE = 0, INIT = 1, diff --git a/src/logservice/palf/log_meta.cpp b/src/logservice/palf/log_meta.cpp old mode 100644 new mode 100755 index cc1cb716d..586f4ca13 --- a/src/logservice/palf/log_meta.cpp +++ b/src/logservice/palf/log_meta.cpp @@ -49,10 +49,10 @@ int LogMeta::generate_by_palf_base_info(const PalfBaseInfo &palf_base_info, const int64_t init_log_proposal_id = (prev_log_proposal_id != INVALID_PROPOSAL_ID)? \ prev_log_proposal_id: PALF_INITIAL_PROPOSAL_ID; const SCN init_ref_scn = (prev_scn.is_valid() ? prev_scn: SCN::min_scn()); - LogConfigInfo init_config_info; + LogConfigInfoV2 init_config_info; LogConfigVersion init_config_version; init_config_version.generate(init_log_proposal_id, 0); - init_config_info.config_version_ = init_config_version; + init_config_info.generate(init_config_version); version_ = LOG_META_VERSION; log_prepare_meta_.generate(LogVotedFor(), init_log_proposal_id); log_config_meta_.generate_for_default(init_log_proposal_id, init_config_info, init_config_info); diff --git a/src/logservice/palf/log_meta_info.cpp b/src/logservice/palf/log_meta_info.cpp old mode 100644 new mode 100755 index 81ffc4a43..6a3a506dd --- a/src/logservice/palf/log_meta_info.cpp +++ b/src/logservice/palf/log_meta_info.cpp @@ -18,10 +18,10 @@ namespace oceanbase { -namespace palf -{ using namespace common; using namespace share; +namespace palf +{ LogVotedFor::LogVotedFor() { @@ -442,6 +442,8 @@ int LogConfigInfo::generate(const ObMemberList &memberlist, if (false == memberlist.is_valid() || false == config_version.is_valid() || 0 >= replica_num || OB_MAX_MEMBER_NUMBER < replica_num) { ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "invalid argument", KR(ret), K(memberlist), K(replica_num), + K(learnerlist), K(config_version)); } else { log_sync_memberlist_ = memberlist; log_sync_replica_num_ = replica_num; @@ -579,6 +581,303 @@ DEFINE_GET_SERIALIZE_SIZE(LogConfigInfo) return size; } +bool is_valid_config_lock_type(int64_t lock_type) +{ + //only support member change so far + return (LOCK_NOTHING == lock_type || LOCK_PAXOS_MEMBER_CHANGE == lock_type); +} + +void LogLockMeta::reset() +{ + version_ = -1; + lock_owner_ = OB_INVALID_CONFIG_CHANGE_LOCK_OWNER; + lock_type_ = ConfigChangeLockType::LOCK_NOTHING; + lock_time_ = OB_INVALID_TIMESTAMP; +} + +bool LogLockMeta::is_valid() const +{ + const bool is_valid_locked_stat = + lock_owner_ > 0 + && LOCK_PAXOS_MEMBER_CHANGE == lock_type_ + && OB_INVALID_TIMESTAMP != lock_time_; + + const bool is_valid_unlocked_stat = (LOCK_NOTHING == lock_type_) + && ((OB_INVALID_CONFIG_CHANGE_LOCK_OWNER == lock_owner_ && OB_INVALID_TIMESTAMP == lock_time_) + || (OB_INVALID_CONFIG_CHANGE_LOCK_OWNER != lock_owner_ && OB_INVALID_TIMESTAMP != lock_time_)); + + return ((LOG_LOCK_META_VERSION == version_) + && (is_valid_locked_stat || is_valid_unlocked_stat)); +} + +int LogLockMeta::generate(const int64_t lock_owner, const int64_t lock_type) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY((LOCK_PAXOS_MEMBER_CHANGE != lock_type) || lock_owner <= 0)) { + ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "invalid argument", K(ret), K(lock_type), K(lock_owner)); + } else { + version_ = LOG_LOCK_META_VERSION; + lock_owner_ = lock_owner; + lock_type_ = lock_type; + lock_time_ = ObTimeUtility::fast_current_time(); + } + return ret; +} + +void LogLockMeta::unlock() +{ + lock_type_ = LOCK_NOTHING; + lock_time_ = ObTimeUtility::fast_current_time(); +} + +void LogLockMeta::reset_as_unlocked() +{ + version_ = LOG_LOCK_META_VERSION; + lock_owner_ = OB_INVALID_CONFIG_CHANGE_LOCK_OWNER; + lock_type_ = LOCK_NOTHING; + lock_time_ = OB_INVALID_TIMESTAMP; +} + +bool LogLockMeta::is_locked() const +{ + return LOCK_PAXOS_MEMBER_CHANGE == lock_type_; +} + +bool LogLockMeta::is_lock_owner_valid() const +{ + return (OB_INVALID_CONFIG_CHANGE_LOCK_OWNER != lock_owner_); +} + +void LogLockMeta::operator=(const LogLockMeta &lock_meta) +{ + version_ = lock_meta.version_; + lock_owner_ = lock_meta.lock_owner_; + lock_type_ = lock_meta.lock_type_; + lock_time_ = lock_meta.lock_time_; +} + +bool LogLockMeta::operator==(const LogLockMeta &lock_meta) const +{ + return version_ == lock_meta.version_ + && lock_owner_ == lock_meta.lock_owner_ + && lock_type_ == lock_meta.lock_type_ + && lock_time_ == lock_meta.lock_time_; +} + +DEFINE_SERIALIZE(LogLockMeta) +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + if (NULL == buf || 0 >= buf_len) { + ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "invalid argument", K(ret), KP(buf), K(buf_len)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, version_))) { + PALF_LOG(WARN, "serialize version_ failed", K(ret), K(new_pos)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, lock_owner_))) { + PALF_LOG(WARN, "serialize lock_owner_ failed", K(ret), K(new_pos)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, lock_type_))) { + PALF_LOG(WARN, "serialize log_type failed", K(ret), K(new_pos)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, lock_time_))) { + PALF_LOG(WARN, "serialize lock_ts_ failed", K(ret), K(new_pos)); + } else { + pos = new_pos; + } + return ret; +} + +DEFINE_DESERIALIZE(LogLockMeta) +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + if (NULL == buf || 0 >= data_len) { + ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "invalid argument", K(ret), KP(buf), K(data_len)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &version_))) { + PALF_LOG(WARN, "deserialize failed", K(ret), K(new_pos)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &lock_owner_))) { + PALF_LOG(WARN, "deserialize failed", K(ret), K(new_pos)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &lock_type_))) { + PALF_LOG(WARN, "deserialize failed", K(ret), K(new_pos)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &lock_time_))) { + PALF_LOG(WARN, "deserialize failed", K(ret), K(new_pos)); + } else { + pos = new_pos; + } + return ret; +} + +DEFINE_GET_SERIALIZE_SIZE(LogLockMeta) +{ + int64_t size = 0; + size += serialization::encoded_length_i64(version_); + size += serialization::encoded_length_i64(lock_owner_); + size += serialization::encoded_length_i64(lock_type_); + size += serialization::encoded_length_i64(lock_time_); + return size; +} + +LogConfigInfoV2::LogConfigInfoV2() + : version_(-1), + config_(), + lock_meta_() +{} + +LogConfigInfoV2::~LogConfigInfoV2() +{ + reset(); +} + +bool LogConfigInfoV2::is_valid() const +{ + return (LOG_CONFIG_INFO_VERSION == version_) + && config_.is_valid() + && lock_meta_.is_valid(); +} + +void LogConfigInfoV2::reset() +{ + version_ = -1; + config_.reset(); + lock_meta_.reset(); +} + + +int LogConfigInfoV2::generate(const LogConfigVersion &config_version) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!config_version.is_valid())) { + ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "invalid argument", KR(ret), K(config_version)); + } else { + version_ = LOG_CONFIG_INFO_VERSION; + config_.config_version_ = config_version; + lock_meta_.reset_as_unlocked(); + } + return ret; +} + +int LogConfigInfoV2::generate(const LogConfigInfo &config_info) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!config_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "invalid argument", KR(ret), K(config_info)); + } else { + version_ = LOG_CONFIG_INFO_VERSION; + config_ = config_info; + lock_meta_.reset_as_unlocked(); + } + return ret; +} + +int LogConfigInfoV2::transform_for_deserialize(const LogConfigInfo &config_info) +{ + int ret = OB_SUCCESS; + version_ = LOG_CONFIG_INFO_VERSION; + config_ = config_info; + lock_meta_.reset_as_unlocked(); + return ret; +} + +// generate paxos memberlist including arbitration replica +int LogConfigInfoV2::convert_to_complete_config(common::ObMemberList &all_paxos_memberlist, + int64_t &all_paxos_replica_num, + GlobalLearnerList &all_learners) const +{ + return config_.convert_to_complete_config(all_paxos_memberlist, all_paxos_replica_num, all_learners); +} + +bool LogConfigInfoV2::is_config_change_locked() const +{ + return lock_meta_.is_locked(); +} + +int LogConfigInfoV2::generate(const ObMemberList &memberlist, + const int64_t replica_num, + const common::GlobalLearnerList &learnerlist, + const LogConfigVersion &config_version) +{ + LogLockMeta lock_meta; + lock_meta.reset_as_unlocked(); + return generate(memberlist, replica_num, learnerlist, config_version, lock_meta); +} + +int LogConfigInfoV2::generate(const ObMemberList &memberlist, + const int64_t replica_num, + const common::GlobalLearnerList &learnerlist, + const LogConfigVersion &config_version, + const LogLockMeta &lock_meta) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!lock_meta.is_valid())) { + ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "invalid argument", KR(ret), K(lock_meta)); + } else if (OB_FAIL(config_.generate(memberlist, replica_num, learnerlist, config_version))) { + PALF_LOG(WARN, "failed to generate config", KR(ret)); + } else { + version_ = LOG_CONFIG_INFO_VERSION; + lock_meta_ = lock_meta; + } + return ret; +} + +void LogConfigInfoV2::operator=(const LogConfigInfoV2 &config_info) +{ + version_ = config_info.version_; + config_ = config_info.config_; + lock_meta_ = config_info.lock_meta_; + PALF_LOG(TRACE, "LogConfigInfoV2 operator =", KPC(this), K(config_info)); +} + +bool LogConfigInfoV2::operator==(const LogConfigInfoV2 &config_info) const +{ + return (version_ == config_info.version_) + && (config_ == config_info.config_) + && (lock_meta_ == config_info.lock_meta_); +} + +DEFINE_SERIALIZE(LogConfigInfoV2) +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + if (NULL == buf || 0 >= buf_len) { + ret = OB_INVALID_ARGUMENT; + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, version_)) + || OB_FAIL(config_.serialize(buf, buf_len, new_pos)) + || OB_FAIL(lock_meta_.serialize(buf, buf_len, new_pos))) { + PALF_LOG(ERROR, "LogConfigInfoV2 serialize failed", K(ret), K(new_pos)); + } else { + pos = new_pos; + } + return ret; +} + +DEFINE_DESERIALIZE(LogConfigInfoV2) +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + if (NULL == buf || 0 >= data_len) { + ret = OB_INVALID_ARGUMENT; + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &version_)) + || OB_FAIL(config_.deserialize(buf, data_len, new_pos)) + || OB_FAIL(lock_meta_.deserialize(buf, data_len, new_pos))) { + PALF_LOG(ERROR, "LogConfigInfoV2 deserialize failed", K(ret), K(new_pos)); + } else { + pos = new_pos; + } + return ret; +} + +DEFINE_GET_SERIALIZE_SIZE(LogConfigInfoV2) +{ + int64_t size = 0; + size += serialization::encoded_length_i64(version_); + size += config_.get_serialize_size(); + size += lock_meta_.get_serialize_size(); + return size; +} + LogConfigMeta::LogConfigMeta() : version_(-1), proposal_id_(INVALID_PROPOSAL_ID), @@ -596,8 +895,8 @@ LogConfigMeta::~LogConfigMeta() int LogConfigMeta::generate_for_default( const int64_t proposal_id, - const LogConfigInfo &prev_config_info, - const LogConfigInfo &curr_config_info) + const LogConfigInfoV2 &prev_config_info, + const LogConfigInfoV2 &curr_config_info) { int ret = OB_SUCCESS; if (INVALID_PROPOSAL_ID == proposal_id) { @@ -617,8 +916,8 @@ int LogConfigMeta::generate_for_default( int LogConfigMeta::generate( const int64_t proposal_id, - const LogConfigInfo &prev_config_info, - const LogConfigInfo &curr_config_info, + const LogConfigInfoV2 &prev_config_info, + const LogConfigInfoV2 &curr_config_info, const int64_t prev_log_proposal_id, const LSN &prev_lsn, const int64_t prev_mode_pid) @@ -630,12 +929,18 @@ int LogConfigMeta::generate( } else if (OB_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), tenant_data_version))) { PALF_LOG(WARN, "get tenant data version failed", K(ret)); } else { - const bool is_cluster_already_4100 = (tenant_data_version >= DATA_VERSION_4_1_0_0); - version_ = (is_cluster_already_4100)? LOG_CONFIG_META_VERSION_INC: LOG_CONFIG_META_VERSION; + if (tenant_data_version < DATA_VERSION_4_1_0_0) { + version_ = LOG_CONFIG_META_VERSION; + } else if (tenant_data_version < DATA_VERSION_4_2_0_0) { + version_ = LOG_CONFIG_META_VERSION_INC; + } else { + version_ = LOG_CONFIG_META_VERSION_42; + } + proposal_id_ = proposal_id; prev_ = prev_config_info; curr_ = curr_config_info; - if (is_cluster_already_4100) { + if (tenant_data_version >= DATA_VERSION_4_1_0_0) { prev_log_proposal_id_ = prev_log_proposal_id; prev_lsn_ = prev_lsn; prev_mode_pid_ = prev_mode_pid; @@ -647,12 +952,15 @@ int LogConfigMeta::generate( bool LogConfigMeta::is_valid() const { // NB: prev_config_info is invalid before change config - return (LOG_CONFIG_META_VERSION == version_ || LOG_CONFIG_META_VERSION_INC == version_) - && proposal_id_ != INVALID_PROPOSAL_ID; + return (LOG_CONFIG_META_VERSION == version_ + || LOG_CONFIG_META_VERSION_INC == version_ + ||LOG_CONFIG_META_VERSION_42 == version_) + && proposal_id_ != INVALID_PROPOSAL_ID; } void LogConfigMeta::reset() { + version_ = -1; proposal_id_ = INVALID_PROPOSAL_ID; curr_.reset(); prev_.reset(); @@ -681,20 +989,41 @@ DEFINE_SERIALIZE(LogConfigMeta) ret = OB_INVALID_ARGUMENT; } else if (buf_len - new_pos < get_serialize_size()) { ret = OB_BUF_NOT_ENOUGH; - } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, version_)) || - OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, proposal_id_)) || - OB_FAIL(prev_.serialize(buf, buf_len, new_pos)) || OB_FAIL(curr_.serialize(buf, buf_len, new_pos))) { - PALF_LOG(ERROR, "LogConfigMeta serialize failed", K(ret), K(new_pos)); - } else if (LOG_CONFIG_META_VERSION_INC == version_) { - if (OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, prev_log_proposal_id_)) || + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, version_))) { + PALF_LOG(ERROR, "LogConfigMeta faild to serialize version_", K(ret), K(new_pos), K(buf_len), K(pos)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, proposal_id_))) { + PALF_LOG(ERROR, "LogConfigMeta failed to serialize proposal_id_", K(ret), K(new_pos), K(buf_len), K(pos)); + } else if (LOG_CONFIG_META_VERSION_INC >= version_) { + if (OB_FAIL(prev_.config_.serialize(buf, buf_len, new_pos)) + || OB_FAIL(curr_.config_.serialize(buf, buf_len, new_pos))) { + PALF_LOG(ERROR, "LogConfigMeta serialize failed", K(ret), K(new_pos), K(buf_len), K(pos)); + } else if (LOG_CONFIG_META_VERSION_INC == version_) { + if (OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, prev_log_proposal_id_)) || + OB_FAIL(prev_lsn_.serialize(buf, buf_len, new_pos)) || + OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, prev_mode_pid_))) { + PALF_LOG(ERROR, "LogConfigMeta Version 2 serialize failed", K(ret), K(new_pos)); + } else { + PALF_LOG(TRACE, "LogConfigMeta Version 2 serialize", K(*this), K(buf + pos), KP(buf), K(pos), K(new_pos)); + pos = new_pos; + } + } + } else if (LOG_CONFIG_META_VERSION_42 == version_) { + if (OB_FAIL(prev_.serialize(buf, buf_len, new_pos)) || + OB_FAIL(curr_.serialize(buf, buf_len, new_pos)) || + OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, prev_log_proposal_id_)) || OB_FAIL(prev_lsn_.serialize(buf, buf_len, new_pos)) || OB_FAIL(serialization::encode_i64(buf, buf_len, new_pos, prev_mode_pid_))) { - PALF_LOG(ERROR, "LogConfigMeta Version 2 serialize failed", K(ret), K(new_pos)); + PALF_LOG(ERROR, "LogConfigMeta Version 3 serialize failed", K(ret), K(new_pos)); } else { - PALF_LOG(TRACE, "LogConfigMeta Version 2 serialize", K(*this), K(buf + pos), KP(buf), K(pos), K(new_pos)); + PALF_LOG(TRACE, "LogConfigMeta Version 3 serialize", K(*this), K(buf + pos), KP(buf), K(pos), K(new_pos)); pos = new_pos; } } else { + ret = OB_ERR_UNEXPECTED; + PALF_LOG(ERROR, "invalid version", K(ret), K(version_)); + } + + if (OB_SUCC(ret)) { PALF_LOG(TRACE, "LogConfigMeta serialize", K(*this), K(buf + pos), KP(buf), K(pos), K(new_pos)); pos = new_pos; } @@ -707,23 +1036,47 @@ DEFINE_DESERIALIZE(LogConfigMeta) int64_t new_pos = pos; if (NULL == buf || 0 >= data_len) { ret = OB_INVALID_ARGUMENT; - // TODO: ObAddr's serialized size is variable, replace it later. - // } else if (data_len - new_pos < get_serialize_size()) { - // ret = OB_BUF_NOT_ENOUGH; - } else if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &version_)) || - OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &proposal_id_)) || - OB_FAIL(prev_.deserialize(buf, data_len, new_pos)) || OB_FAIL(curr_.deserialize(buf, data_len, new_pos))) { - PALF_LOG(ERROR, "LogConfigMeta deserialize failed", K(ret), K(new_pos)); - } else if (LOG_CONFIG_META_VERSION_INC == version_) { - if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &prev_log_proposal_id_)) || + /* TODO: ObAddr's serialized size is variable, replace it later. + } else if (data_len - new_pos < get_serialize_size()) { + ret = OB_BUF_NOT_ENOUGH; */ + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &version_))) { + PALF_LOG(ERROR, "failed to deserialize version", K(ret)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &proposal_id_))) { + PALF_LOG(ERROR, "failed to deserialize version", K(ret)); + } else if (LOG_CONFIG_META_VERSION == version_ || LOG_CONFIG_META_VERSION_INC == version_) { + LogConfigInfo old_prev; + LogConfigInfo old_curr; + if (OB_FAIL(old_prev.deserialize(buf, data_len, new_pos))) { + PALF_LOG(ERROR, "LogConfigMeta deserialize failed", K(ret), K(new_pos)); + } else if (OB_FAIL(old_curr.deserialize(buf, data_len, new_pos))) { + PALF_LOG(ERROR, "deserialize failed", K(ret), K(new_pos)); + } else if (OB_FAIL(prev_.transform_for_deserialize(old_prev))) { + PALF_LOG(ERROR, "failed to generate pre_", K(ret)); + } else if (OB_FAIL(curr_.transform_for_deserialize(old_curr))) { + PALF_LOG(ERROR, " failed to generate curr_", K(ret)); + } else if (LOG_CONFIG_META_VERSION_INC == version_) { + if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &prev_log_proposal_id_)) || + OB_FAIL(prev_lsn_.deserialize(buf, data_len, new_pos)) || + OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &prev_mode_pid_))) { + PALF_LOG(ERROR, " failed to decode pre_log_info", K(ret)); + } + } else {/*do nothing*/} + } else if (LOG_CONFIG_META_VERSION_42 == version_) { + if (OB_FAIL(prev_.deserialize(buf, data_len, new_pos))) { + PALF_LOG(ERROR, "failed to deserialize prev_", K(ret)); + } else if (OB_FAIL(curr_.deserialize(buf, data_len, new_pos))) { + PALF_LOG(ERROR, "failed to deserialize curr_", K(ret)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &prev_log_proposal_id_)) || OB_FAIL(prev_lsn_.deserialize(buf, data_len, new_pos)) || OB_FAIL(serialization::decode_i64(buf, data_len, new_pos, &prev_mode_pid_))) { - PALF_LOG(ERROR, "LogConfigMeta Version 2 deserialize failed", K(ret), K(new_pos)); - } else { - PALF_LOG(TRACE, "LogConfigMeta Version 2 deserialize", K(*this), K(buf + pos), KP(buf), K(pos), K(new_pos)); - pos = new_pos; - } + PALF_LOG(ERROR, "LogConfigMeta Version 3 deserialize failed", K(ret), K(new_pos)); + } else {/*do nothing*/} } else { + ret = OB_ERR_UNEXPECTED; + PALF_LOG(ERROR, "invalid version", K(ret), K(version_)); + } + + if (OB_SUCC(ret)) { PALF_LOG(TRACE, "LogConfigMeta deserialize", K(*this), K(buf + pos), KP(buf), K(pos), K(new_pos)); pos = new_pos; } @@ -735,9 +1088,18 @@ DEFINE_GET_SERIALIZE_SIZE(LogConfigMeta) int64_t size = 0; size += serialization::encoded_length_i64(version_); size += serialization::encoded_length_i64(proposal_id_); - size += prev_.get_serialize_size(); - size += curr_.get_serialize_size(); - if (LOG_CONFIG_META_VERSION_INC == version_) { + if (LOG_CONFIG_META_VERSION == version_ ) { + size += prev_.config_.get_serialize_size(); + size += curr_.config_.get_serialize_size(); + } else if (LOG_CONFIG_META_VERSION_INC == version_) { + size += prev_.config_.get_serialize_size(); + size += curr_.config_.get_serialize_size(); + size += serialization::encoded_length_i64(prev_log_proposal_id_); + size += prev_lsn_.get_serialize_size(); + size += serialization::encoded_length_i64(prev_mode_pid_); + } else if (LOG_CONFIG_META_VERSION_42 == version_) { + size += prev_.get_serialize_size(); + size += curr_.get_serialize_size(); size += serialization::encoded_length_i64(prev_log_proposal_id_); size += prev_lsn_.get_serialize_size(); size += serialization::encoded_length_i64(prev_mode_pid_); diff --git a/src/logservice/palf/log_meta_info.h b/src/logservice/palf/log_meta_info.h index f474efaa8..45f8519b3 100644 --- a/src/logservice/palf/log_meta_info.h +++ b/src/logservice/palf/log_meta_info.h @@ -116,6 +116,7 @@ public: public: bool is_valid() const; void reset(); + //for unitest int generate(const common::ObMemberList &memberlist, const int64_t replica_num, const common::GlobalLearnerList &learnerlist, @@ -156,6 +157,84 @@ public: LogConfigVersion config_version_; }; +enum ConfigChangeLockType +{ + LOCK_NOTHING = 0x0, + LOCK_PAXOS_MEMBER_CHANGE = 0x1, // binary 00001 + LOCK_PAXOS_REPLICA_NUMBER_CHANGE = 0x2, // binary 00010 (TODO) + LOCK_LEARNER_CHANGE = 0x4, // binary 00100(TODO) + LOCK_ACCESS_MODE_CHANGE = 0x8, // binary 01000 (TODO) + LOCK_ARBITRATION_MEMBER_CHANGE = 0x10, // binary 10000 (TODO) +}; + +bool is_valid_config_lock_type(int64_t lock_type); + +struct LogLockMeta +{ +public: + LogLockMeta() {reset();} + ~LogLockMeta() {reset();} + void reset(); + bool is_valid() const; + int generate(const int64_t lock_owner, const int64_t lock_type); + void operator=(const LogLockMeta &lock_meta); + bool operator==(const LogLockMeta &lock_meta) const; + void reset_as_unlocked(); + void unlock(); + bool is_locked() const; + bool is_lock_owner_valid() const; + TO_STRING_KV(K_(version), K_(lock_type), K_(lock_owner), K_(lock_time)); + NEED_SERIALIZE_AND_DESERIALIZE; +public: + static constexpr int64_t LOG_LOCK_META_VERSION = 1; + int64_t version_;//for compatibilty + int64_t lock_owner_;// owner of lock + int64_t lock_type_;// ConfigChangeLockType + int64_t lock_time_;// the timestamp of executing locking or unlocking. default as OB_INVALID_TIMESTAMP, using fordebugging +}; + +struct LogConfigInfoV2 +{ +public: + LogConfigInfoV2(); + ~LogConfigInfoV2(); +public: + static constexpr int64_t LOG_CONFIG_INFO_VERSION = 1; + bool is_valid() const; + void reset(); + //for init with default + int generate(const LogConfigVersion &config_version); + //for serialize compaction + int generate(const LogConfigInfo &config_info); + //for deserialization from lower version + int transform_for_deserialize(const LogConfigInfo &config_info); + int convert_to_complete_config(common::ObMemberList &all_paxos_memberlist, + int64_t &all_paxos_replica_num, + GlobalLearnerList &all_learners) const; + bool is_config_change_locked() const; + + //for unitest + int generate(const common::ObMemberList &memberlist, + const int64_t replica_num, + const common::GlobalLearnerList &learnerlist, + const LogConfigVersion &config_version); + //for unitest + int generate(const common::ObMemberList &memberlist, + const int64_t replica_num, + const common::GlobalLearnerList &learnerlist, + const LogConfigVersion &config_version, + const LogLockMeta &lock_meta); + // For unittest + void operator=(const LogConfigInfoV2 &config_info); + bool operator==(const LogConfigInfoV2 &config_info) const; + TO_STRING_KV(K_(version), K_(config), K_(lock_meta)); + NEED_SERIALIZE_AND_DESERIALIZE; +public: + int64_t version_; + LogConfigInfo config_; + LogLockMeta lock_meta_; +}; + // Change member log for consenus struct LogConfigMeta { public: @@ -165,11 +244,11 @@ public: public: // Note: the function will generate a default version_. int generate_for_default(const int64_t proposal_id, - const LogConfigInfo &prev_config_info, - const LogConfigInfo &curr_config_info); + const LogConfigInfoV2 &prev_config_info, + const LogConfigInfoV2 &curr_config_info); int generate(const int64_t proposal_id, - const LogConfigInfo &prev_config_info, - const LogConfigInfo &curr_config_info, + const LogConfigInfoV2 &prev_config_info, + const LogConfigInfoV2 &curr_config_info, const int64_t prev_log_proposal_id, const LSN &prev_lsn, const int64_t prev_mode_pid); @@ -182,8 +261,8 @@ public: int64_t version_; // ====== members in VERSION 1 ======== int64_t proposal_id_; - LogConfigInfo prev_; - LogConfigInfo curr_; + LogConfigInfoV2 prev_;//modified in version_42 + LogConfigInfoV2 curr_;//modified in version_42 // ====== added members in VERSION 2 ======== int64_t prev_log_proposal_id_; LSN prev_lsn_; @@ -191,6 +270,7 @@ public: static constexpr int64_t LOG_CONFIG_META_VERSION = 1; static constexpr int64_t LOG_CONFIG_META_VERSION_INC = 2; + static constexpr int64_t LOG_CONFIG_META_VERSION_42 = 3;//LogConfigInfo-->LogConfigInfoV2 }; struct LogModeMeta { diff --git a/src/logservice/palf/palf_handle.cpp b/src/logservice/palf/palf_handle.cpp old mode 100644 new mode 100755 index d779a4bdf..76dd5e141 --- a/src/logservice/palf/palf_handle.cpp +++ b/src/logservice/palf/palf_handle.cpp @@ -264,6 +264,12 @@ int PalfHandle::get_max_scn(SCN &scn) const return ret; } +int PalfHandle::get_config_version(LogConfigVersion &config_version) const +{ + CHECK_VALID; + return palf_handle_impl_->get_config_version(config_version); +} + int PalfHandle::get_role(common::ObRole &role, int64_t &proposal_id, bool &is_pending_state) const { CHECK_VALID; @@ -332,10 +338,11 @@ int PalfHandle::get_ack_info_array(LogMemberAckInfoList &ack_info_array, int PalfHandle::add_member(const common::ObMember &member, const int64_t new_replica_num, + const LogConfigVersion &config_version, const int64_t timeout_us) { CHECK_VALID; - return palf_handle_impl_->add_member(member, new_replica_num, timeout_us); + return palf_handle_impl_->add_member(member, new_replica_num, config_version, timeout_us); } int PalfHandle::remove_member(const common::ObMember &member, @@ -348,10 +355,11 @@ int PalfHandle::remove_member(const common::ObMember &member, int PalfHandle::replace_member(const common::ObMember &added_member, const common::ObMember &removed_member, + const LogConfigVersion &config_version, const int64_t timeout_us) { CHECK_VALID; - return palf_handle_impl_->replace_member(added_member, removed_member, timeout_us); + return palf_handle_impl_->replace_member(added_member, removed_member, config_version, timeout_us); } int PalfHandle::add_learner(const common::ObMember &added_learner, const int64_t timeout_us) @@ -368,10 +376,11 @@ int PalfHandle::remove_learner(const common::ObMember &removed_learner, const in int PalfHandle::switch_learner_to_acceptor(const common::ObMember &learner, const int64_t new_replica_num, + const LogConfigVersion &config_version, const int64_t timeout_us) { CHECK_VALID; - return palf_handle_impl_->switch_learner_to_acceptor(learner, new_replica_num, timeout_us); + return palf_handle_impl_->switch_learner_to_acceptor(learner, new_replica_num, config_version, timeout_us); } int PalfHandle::switch_acceptor_to_learner(const common::ObMember &member, @@ -628,6 +637,25 @@ int PalfHandle::stat(PalfStat &palf_stat) const return palf_handle_impl_->stat(palf_stat); } +int PalfHandle::try_lock_config_change(int64_t lock_owner, + int64_t timeout_us) +{ + CHECK_VALID; + return palf_handle_impl_->try_lock_config_change(lock_owner, timeout_us); +} + +int PalfHandle::unlock_config_change(int64_t lock_owner, int64_t timeout_us) +{ + CHECK_VALID; + return palf_handle_impl_->unlock_config_change(lock_owner, timeout_us); +} + +int PalfHandle::get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked) +{ + CHECK_VALID; + return palf_handle_impl_->get_config_change_lock_stat(lock_owner, is_locked); +} + int PalfHandle::diagnose(PalfDiagnoseInfo &diagnose_info) const { CHECK_VALID; diff --git a/src/logservice/palf/palf_handle.h b/src/logservice/palf/palf_handle.h old mode 100644 new mode 100755 index a2936dd9b..f3432307a --- a/src/logservice/palf/palf_handle.h +++ b/src/logservice/palf/palf_handle.h @@ -182,6 +182,7 @@ public: int get_global_learner_list(common::GlobalLearnerList &learner_list) const; int get_paxos_member_list(common::ObMemberList &member_list, int64_t &paxos_replica_num) const; + int get_config_version(LogConfigVersion &config_version) const; int get_paxos_member_list_and_learner_list(common::ObMemberList &member_list, int64_t &paxos_replica_num, GlobalLearnerList &learner_list) const; @@ -210,15 +211,18 @@ public: // @brief, add a member to paxos group, can be called only in leader // @param[in] common::ObMember &member: member which will be added // @param[in] const int64_t new_replica_num: replica number of paxos group after adding 'member' + // @param[in] const LogConfigVersion &config_version: config_version for leader checking // @param[in] const int64_t timeout_us: add member timeout, us // @return // - OB_SUCCESS: add member successfully // - OB_INVALID_ARGUMENT: invalid argumemt or not supported config change // - OB_TIMEOUT: add member timeout // - OB_NOT_MASTER: not leader or rolechange during membership changing + // - OB_STATE_NOT_MATCH: not the same leader // - other: bug int add_member(const common::ObMember &member, const int64_t new_replica_num, + const LogConfigVersion &config_version, const int64_t timeout_us); // @brief, remove a member from paxos group, can be called only in leader @@ -238,6 +242,7 @@ public: // @brief, replace old_member with new_member, can be called only in leader // @param[in] const common::ObMember &added_member: member wil be added // @param[in] const common::ObMember &removed_member: member will be removed + // @param[in] const LogConfigVersion &config_version: config_version for leader checking // @param[in] const int64_t timeout_us // @return // - OB_SUCCESS: replace member successfully @@ -247,6 +252,7 @@ public: // - other: bug int replace_member(const common::ObMember &added_member, const common::ObMember &removed_member, + const LogConfigVersion &config_version, const int64_t timeout_us); // @brief: add a learner(read only replica) in this clsuter @@ -275,6 +281,7 @@ public: // @param[in] const common::ObMember &learner: learner will be switched to acceptor // @param[in] const int64_t new_replica_num: replica number of paxos group after switching // learner to acceptor (similar to add_member) + // @param[in] const LogConfigVersion &config_version: config_version for leader checking // @param[in] const int64_t timeout_us // @return // - OB_SUCCESS @@ -283,6 +290,7 @@ public: // - OB_NOT_MASTER: not leader or rolechange during membership changing int switch_learner_to_acceptor(const common::ObMember &learner, const int64_t new_replica_num, + const LogConfigVersion &config_version, const int64_t timeout_us); // @brief: switch an acceptor(full replica) to learner(read only replica) in this clsuter @@ -380,8 +388,34 @@ public: int reset_election_priority(); int stat(PalfStat &palf_stat) const; + //---------config change lock related--------// + //@return + // -- OB_NOT_INIT not_init + // -- OB_SUCCESS successfull lock + // -- OB_TRY_LOCK_CONFIG_CHANGE_CONFLICT failed to lock because of locked by others + // -- OB_TIMEOUT timeout, may lock successfully or not + // -- OB_EAGAIN other config change operation is going on,need retry later + // -- OB_NOT_MASTER this replica is not leader, not refresh location and retry with actual leader + // -- OB_STATE_NOT_MATCH lock_owner is smaller than previous lock_owner + int try_lock_config_change(int64_t lock_owner, int64_t timeout_us); + //@return + // -- OB_NOT_INIT not_init + // -- OB_SUCCESS successfull unlock + // -- OB_TIMEOUT timeout, may unlock successfully or not + // -- OB_EAGAIN other config change operation is going on,need retry later + // -- OB_NOT_MASTER this replica is not leader, need refresh location and retry with actual leader + // -- OB_STATE_NOT_MATCH lock_owner is smaller than previous lock_owner,or lock_owner is bigger than previous lock_owner + int unlock_config_change(int64_t lock_owner, int64_t timeout_us); + //@return + // -- OB_NOT_INIT not_init + // -- OB_SUCCESS success + // -- OB_NOT_MASTER this replica is not leader, not refresh location and retry with actual leader + // -- OB_EAGAIN is_locking or unlocking + int get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked); + // @param [out] diagnose info, current diagnose info of palf int diagnose(PalfDiagnoseInfo &diagnose_info) const; + TO_STRING_KV(KP(palf_handle_impl_), KP(rc_cb_), KP(fs_cb_)); private: palf::IPalfHandleImpl *palf_handle_impl_; diff --git a/src/logservice/palf/palf_handle_impl.cpp b/src/logservice/palf/palf_handle_impl.cpp old mode 100644 new mode 100755 index ec3bcb799..c3d433bc2 --- a/src/logservice/palf/palf_handle_impl.cpp +++ b/src/logservice/palf/palf_handle_impl.cpp @@ -511,6 +511,21 @@ int PalfHandleImpl::get_paxos_member_list( return ret; } +int PalfHandleImpl::get_config_version(LogConfigVersion &config_version) const +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + PALF_LOG(ERROR, "PalfHandleImpl has not inited", K(ret), K_(palf_id)); + } else { + RLockGuard guard(lock_); + if (OB_FAIL(config_mgr_.get_config_version(config_version))) { + PALF_LOG(WARN, "failed to get_config_version", K(ret), K_(palf_id)); + } + } + return ret; +} + int PalfHandleImpl::get_paxos_member_list_and_learner_list( common::ObMemberList &member_list, int64_t &paxos_replica_num, @@ -658,6 +673,7 @@ int PalfHandleImpl::change_replica_num( int PalfHandleImpl::add_member( const common::ObMember &member, const int64_t new_replica_num, + const LogConfigVersion &config_version, const int64_t timeout_us) { int ret = OB_SUCCESS; @@ -673,7 +689,7 @@ int PalfHandleImpl::add_member( } else if (OB_FAIL(config_mgr_.get_replica_num(prev_replica_num))) { PALF_LOG(WARN, "get prev_replica_num failed", KR(ret), KPC(this)); } else { - LogConfigChangeArgs args(member, new_replica_num, ADD_MEMBER); + LogConfigChangeArgs args(member, new_replica_num, config_version, ADD_MEMBER); if (OB_FAIL(one_stage_config_change_(args, timeout_us))) { PALF_LOG(WARN, "add_member failed", KR(ret), KPC(this), K(member), K(new_replica_num)); } else { @@ -716,6 +732,7 @@ int PalfHandleImpl::remove_member( int PalfHandleImpl::replace_member( const common::ObMember &added_member, const common::ObMember &removed_member, + const LogConfigVersion &config_version, const int64_t timeout_us) { int ret = OB_SUCCESS; @@ -726,11 +743,12 @@ int PalfHandleImpl::replace_member( !removed_member.is_valid() || timeout_us <= 0) { ret = OB_INVALID_ARGUMENT; - PALF_LOG(WARN, "invalid argument", KR(ret), KPC(this), K(added_member), K(removed_member), K(timeout_us)); + PALF_LOG(WARN, "invalid argument", KR(ret), KPC(this), K(added_member), K(removed_member), + K(timeout_us)); } else { ObMemberList old_member_list, curr_member_list; int64_t old_replica_num = -1, curr_replica_num = -1; - LogConfigChangeArgs args(added_member, 0, ADD_MEMBER_AND_NUM); + LogConfigChangeArgs args(added_member, 0, config_version, ADD_MEMBER_AND_NUM); const int64_t begin_time_us = common::ObTimeUtility::current_time(); if (OB_FAIL(config_mgr_.get_curr_member_list(old_member_list, old_replica_num))) { PALF_LOG(WARN, "get_curr_member_list failed", KR(ret), KPC(this)); @@ -795,15 +813,18 @@ int PalfHandleImpl::remove_learner(const common::ObMember &removed_learner, cons int PalfHandleImpl::switch_learner_to_acceptor(const common::ObMember &learner, const int64_t new_replica_num, + const LogConfigVersion &config_version, const int64_t timeout_us) { int ret = OB_SUCCESS; if (IS_NOT_INIT) { ret = OB_NOT_INIT; - } else if (!learner.is_valid() || timeout_us <= 0) { + } else if (!learner.is_valid() || + timeout_us <= 0) { ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "invalid argument", KPC(this), K(learner), K(timeout_us)); } else { - LogConfigChangeArgs args(learner, new_replica_num, SWITCH_LEARNER_TO_ACCEPTOR); + LogConfigChangeArgs args(learner, new_replica_num, config_version, SWITCH_LEARNER_TO_ACCEPTOR); if (OB_FAIL(one_stage_config_change_(args, timeout_us))) { PALF_LOG(WARN, "switch_learner_to_acceptor failed", KR(ret), KPC(this), K(args), K(timeout_us)); } else { @@ -938,7 +959,7 @@ int PalfHandleImpl::check_args_and_generate_config_(const LogConfigChangeArgs &a const int64_t proposal_id, const int64_t election_epoch, bool &is_already_finished, - LogConfigInfo &new_config_info) const + LogConfigInfoV2 &new_config_info) const { int ret = OB_SUCCESS; RLockGuard guard(lock_); @@ -952,7 +973,7 @@ int PalfHandleImpl::check_args_and_generate_config_(const LogConfigChangeArgs &a } int PalfHandleImpl::wait_log_barrier_(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info, + const LogConfigInfoV2 &new_config_info, TimeoutChecker ¬_timeout) { int ret = OB_SUCCESS; @@ -997,7 +1018,7 @@ int PalfHandleImpl::one_stage_config_change_(const LogConfigChangeArgs &args, int64_t election_epoch = INVALID_PROPOSAL_ID; bool is_already_finished = false; int get_lock = OB_EAGAIN; - LogConfigInfo new_config_info; + LogConfigInfoV2 new_config_info; if (DEGRADE_ACCEPTOR_TO_LEARNER == args.type_) { // for concurrent DEGRADE if (ATOMIC_BCAS(&has_higher_prio_config_change_, false, true)) { @@ -1076,7 +1097,7 @@ int PalfHandleImpl::one_stage_config_change_(const LogConfigChangeArgs &args, } time_guard.click("precheck"); // step 3: waiting for log barrier if a arbitration member exists - if (OB_SUCC(ret) && true == new_config_info.arbitration_member_.is_valid()) { + if (OB_SUCC(ret) && true == new_config_info.config_.arbitration_member_.is_valid()) { ret = wait_log_barrier_(args, new_config_info, not_timeout); } time_guard.click("wait_barrier"); @@ -3699,8 +3720,8 @@ int PalfHandleImpl::receive_config_log(const common::ObAddr &server, } else if (OB_FAIL(config_mgr_.receive_config_log(server, meta))) { PALF_LOG(WARN, "receive_config_log failed", KR(ret), KPC(this), K(server), K(msg_proposal_id), K(prev_log_proposal_id), K(prev_lsn)); - } else if (!meta.curr_.log_sync_memberlist_.contains(self_) && - meta.curr_.arbitration_member_.get_server() != self_ && + } else if (!meta.curr_.config_.log_sync_memberlist_.contains(self_) && + meta.curr_.config_.arbitration_member_.get_server() != self_ && !FALSE_IT(config_mgr_.register_parent()) && FALSE_IT(need_print_register_log = true)) { // it's a optimization. If self isn't in memberlist, then register parent right now, @@ -4671,6 +4692,80 @@ int PalfHandleImpl::update_palf_stat() return OB_SUCCESS; } +int PalfHandleImpl::try_lock_config_change(int64_t lock_owner, int64_t timeout_us) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + uint64_t tenant_data_version = 0; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + PALF_LOG(WARN, "PalfHandleImpl not init", KR(ret), KPC(this)); + } else if (OB_UNLIKELY(lock_owner <= 0 || timeout_us <= 0)) { + ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "invalid argument", KR(ret), KPC(this), K(lock_owner), K(timeout_us)); + } else if (OB_TMP_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), tenant_data_version))) { + ret = OB_NOT_SUPPORTED; + PALF_LOG(WARN, "not supported when data version is invalid", KR(ret), KPC(this), + K(lock_owner), K(timeout_us)); + } else if (tenant_data_version < DATA_VERSION_4_2_0_0) { + ret = OB_NOT_SUPPORTED; + PALF_LOG(WARN, "not supported with current data version", KR(ret), K(tenant_data_version), + KPC(this), K(lock_owner), K(timeout_us)); + } else { + LogConfigChangeArgs args(lock_owner, ConfigChangeLockType::LOCK_PAXOS_MEMBER_CHANGE, TRY_LOCK_CONFIG_CHANGE); + if (OB_FAIL(one_stage_config_change_(args, timeout_us))) { + PALF_LOG(WARN, "try_lock_config_change failed", KR(ret), KPC(this), K(lock_owner)); + } else { + PALF_EVENT("try_lock_config_change success", palf_id_, KR(ret), KPC(this), K(lock_owner)); + } + } + return ret; +} + +int PalfHandleImpl::unlock_config_change(int64_t lock_owner, int64_t timeout_us) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + uint64_t tenant_data_version = 0; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + PALF_LOG(WARN, "PalfHandleImpl not init", KR(ret), KPC(this)); + } else if (OB_UNLIKELY(lock_owner <= 0 || timeout_us <= 0)) { + ret = OB_INVALID_ARGUMENT; + PALF_LOG(WARN, "invalid argument", KR(ret), KPC(this), K(lock_owner), K(timeout_us)); + } else if (OB_TMP_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), tenant_data_version))) { + ret = OB_NOT_SUPPORTED; + PALF_LOG(WARN, "not supported when data version is invalid", KR(ret), KPC(this), + K(lock_owner), K(timeout_us)); + } else if (tenant_data_version < DATA_VERSION_4_2_0_0) { + ret = OB_NOT_SUPPORTED; + PALF_LOG(WARN, "not supported with current data version", KR(ret), K(tenant_data_version), + KPC(this), K(lock_owner), K(timeout_us)); + } else { + LogConfigChangeArgs args(lock_owner, ConfigChangeLockType::LOCK_NOTHING, UNLOCK_CONFIG_CHANGE); + if (OB_FAIL(one_stage_config_change_(args, timeout_us))) { + PALF_LOG(WARN, "unlock_config_change failed", KR(ret), KPC(this), K(lock_owner)); + } else { + PALF_EVENT("unlock_config_change success", palf_id_, KR(ret), KPC(this), K(lock_owner)); + } + } + return ret; +} + +int PalfHandleImpl::get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked) +{ + int ret = OB_SUCCESS; + RLockGuard guard(lock_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + PALF_LOG(WARN, "PalfHandleImpl has not inited", K(ret)); + } else if (OB_FAIL(config_mgr_.get_config_change_lock_stat(lock_owner, is_locked))) { + PALF_LOG(WARN, "get_curr_member_list failed", K(ret), KPC(this)); + } else {} + return ret; +} + void PalfHandleImpl::is_in_sync_(bool &is_log_sync, bool &is_use_cache) { int ret = OB_SUCCESS; diff --git a/src/logservice/palf/palf_handle_impl.h b/src/logservice/palf/palf_handle_impl.h index 468c4c051..8b179f347 100755 --- a/src/logservice/palf/palf_handle_impl.h +++ b/src/logservice/palf/palf_handle_impl.h @@ -343,6 +343,7 @@ public: virtual int get_global_learner_list(common::GlobalLearnerList &learner_list) const = 0; virtual int get_paxos_member_list(common::ObMemberList &member_list, int64_t &paxos_replica_num) const = 0; + virtual int get_config_version(LogConfigVersion &config_version) const = 0; virtual int get_paxos_member_list_and_learner_list(common::ObMemberList &member_list, int64_t &paxos_replica_num, common::GlobalLearnerList &learner_list) const = 0; @@ -378,6 +379,7 @@ public: // - other: bug virtual int add_member(const common::ObMember &member, const int64_t new_replica_num, + const LogConfigVersion &config_version, const int64_t timeout_us) = 0; // @brief, remove a member from paxos group @@ -397,6 +399,7 @@ public: // @brief, replace old_member with new_member // @param[in] const common::ObMember &added_member: member wil be added // @param[in] const common::ObMember &removed_member: member will be removed + // @param[in] const LogConfigVersion &config_version: config_version for leader checking // @param[in] const int64_t timeout_us // @return // - OB_SUCCESS: replace member successfully @@ -406,6 +409,7 @@ public: // - other: bug virtual int replace_member(const common::ObMember &added_member, const common::ObMember &removed_member, + const LogConfigVersion &config_version, const int64_t timeout_us) = 0; // @brief: add a learner(read only replica) in this clsuter @@ -432,6 +436,7 @@ public: // @param[in] const common::ObMember &learner: learner will be switched to acceptor // @param[in] const int64_t new_replica_num: replica number of paxos group after switching // learner to acceptor (similar to add_member) + // @param[in] const LogConfigVersion &config_version: config_version for leader checking // @param[in] const int64_t timeout_us // @return // - OB_SUCCESS @@ -440,6 +445,7 @@ public: // - OB_NOT_MASTER: not leader or rolechange during membership changing virtual int switch_learner_to_acceptor(const common::ObMember &learner, const int64_t new_replica_num, + const LogConfigVersion &config_version, const int64_t timeout_us) = 0; // @brief: switch an acceptor(full replica) to learner(read only replica) in this clsuter @@ -713,6 +719,9 @@ public: virtual int stat(PalfStat &palf_stat) = 0; virtual int get_palf_epoch(int64_t &palf_epoch) const = 0; + virtual int try_lock_config_change(int64_t lock_owner, int64_t timeout_us) = 0; + virtual int unlock_config_change(int64_t lock_owner, int64_t timeout_us) = 0; + virtual int get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked) = 0; virtual int diagnose(PalfDiagnoseInfo &diagnose_info) const = 0; virtual int update_palf_stat() = 0; virtual int read_data_from_buffer(const LSN &read_begin_lsn, @@ -784,6 +793,7 @@ public: int change_leader_to(const common::ObAddr &dest_addr) override final; int get_global_learner_list(common::GlobalLearnerList &learner_list) const override final; int get_paxos_member_list(common::ObMemberList &member_list, int64_t &paxos_replica_num) const override final; + int get_config_version(LogConfigVersion &config_version) const; int get_paxos_member_list_and_learner_list(common::ObMemberList &member_list, int64_t &paxos_replica_num, common::GlobalLearnerList &learner_list) const override final; @@ -795,12 +805,14 @@ public: const int64_t timeout_us) override final; int add_member(const common::ObMember &member, const int64_t new_replica_num, + const LogConfigVersion &config_version, const int64_t timeout_us) override final; int remove_member(const common::ObMember &member, const int64_t new_replica_num, const int64_t timeout_us) override final; int replace_member(const common::ObMember &added_member, const common::ObMember &removed_member, + const LogConfigVersion &config_version, const int64_t timeout_us) override final; int add_learner(const common::ObMember &added_learner, const int64_t timeout_us) override final; @@ -808,6 +820,7 @@ public: const int64_t timeout_us) override final; int switch_learner_to_acceptor(const common::ObMember &learner, const int64_t new_replica_num, + const LogConfigVersion &config_version, const int64_t timeout_us) override final; int switch_acceptor_to_learner(const common::ObMember &member, const int64_t new_replica_num, @@ -1012,6 +1025,13 @@ public: int flashback(const int64_t mode_version, const share::SCN &flashback_scn, const int64_t timeout_us) override final; + + //config change lock related function + int try_lock_config_change(int64_t lock_owner, int64_t timeout_us); + + int unlock_config_change(int64_t lock_owner, int64_t timeout_us); + int get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked); + int diagnose(PalfDiagnoseInfo &diagnose_info) const; int update_palf_stat() override final; TO_STRING_KV(K_(palf_id), K_(self), K_(has_set_deleted)); @@ -1122,9 +1142,9 @@ private: const int64_t proposal_id, const int64_t election_epoch, bool &is_already_finished, - LogConfigInfo &new_config_info) const; + LogConfigInfoV2 &new_config_info) const; int wait_log_barrier_(const LogConfigChangeArgs &args, - const LogConfigInfo &new_config_info, + const LogConfigInfoV2 &new_config_info, TimeoutChecker ¬_timeout); int one_stage_config_change_(const LogConfigChangeArgs &args, const int64_t timeout_us); int check_need_rebuild_(const LSN &base_lsn, diff --git a/src/logservice/palf_handle_guard.h b/src/logservice/palf_handle_guard.h index 4f25360a5..79669cd31 100644 --- a/src/logservice/palf_handle_guard.h +++ b/src/logservice/palf_handle_guard.h @@ -169,21 +169,28 @@ public: // - OB_NOT_MASTER: not leader or rolechange during membership changing // - other: bug DELEGATE_WITH_RET(palf_handle_, change_replica_num, int); - // @brief, add a member to paxos group, can be called only in leader + +// @brief, add a member to paxos group, can be called only in leader // @param[in] common::ObMember &member: member which will be added // @param[in] const int64_t paxos_replica_num: replica number of paxos group after adding 'member' // @param[in] const int64_t timeout_us: add member timeout, ns + // @param[in] const palf::LogConfigVersion &config_version: config_version for checking leader's + // config_version // @return // - OB_SUCCESS: add member successfully // - OB_INVALID_ARGUMENT: invalid argumemt or not supported config change // - OB_TIMEOUT: add member timeout // - OB_NOT_MASTER: not leader or rolechange during membership changing + // - OB_STATE_NOT_MATCH: leader has switched // - other: bug - // int add_member(const common::ObMember &member, - // const int64_t paxos_replica_num, - // const int64_t timeout_us) DELEGATE_WITH_RET(palf_handle_, add_member, int); + // @brief, get config_version + // @return + // - OB_SUCCESS: get_config_version successfully + // - OB_NOT_INIT + DELEGATE_WITH_RET(palf_handle_, get_config_version, int); + // @brief, remove a member from paxos group, can be called only in leader // @param[in] common::ObMember &member: member which will be removed // @param[in] const int64_t paxos_replica_num: replica number of paxos group after removing 'member' @@ -220,6 +227,9 @@ public: DELEGATE_WITH_RET(palf_handle_, get_access_mode, int); DELEGATE_WITH_RET(palf_handle_, flashback, int); CONST_DELEGATE_WITH_RET(palf_handle_, stat, int); + DELEGATE_WITH_RET(palf_handle_, try_lock_config_change, int); + DELEGATE_WITH_RET(palf_handle_, unlock_config_change, int); + DELEGATE_WITH_RET(palf_handle_, get_config_change_lock_stat, int); private: PalfHandle palf_handle_; PalfEnv *palf_env_; diff --git a/src/logservice/replayservice/ob_tablet_replay_executor.cpp b/src/logservice/replayservice/ob_tablet_replay_executor.cpp new file mode 100644 index 000000000..aa9cf93d2 --- /dev/null +++ b/src/logservice/replayservice/ob_tablet_replay_executor.cpp @@ -0,0 +1,270 @@ +/** + * Copyright (c) 2023 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 "logservice/replayservice/ob_tablet_replay_executor.h" +#include "storage/ls/ob_ls.h" +#include "storage/ls/ob_ls_get_mod.h" +#include "storage/tx_storage/ob_ls_service.h" + +namespace oceanbase +{ +namespace logservice +{ + +#ifdef CLOG_LOG_LIMIT +#undef CLOG_LOG_LIMIT +#endif + +#define CLOG_LOG_LIMIT(level, args...) \ + do \ + { \ + if (REACH_TIME_INTERVAL(1000 * 1000)) { \ + CLOG_LOG(level, ##args); \ + } \ + } while(0) + + +int ObTabletReplayExecutor::replay_check_restore_status(storage::ObTabletHandle &tablet_handle, const bool update_tx_data) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = tablet_handle.get_obj(); + ObTabletRestoreStatus::STATUS restore_status = ObTabletRestoreStatus::STATUS::RESTORE_STATUS_MAX; + if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "tablet is null", K(ret)); + } else if (OB_FAIL(tablet->get_restore_status(restore_status))) { + CLOG_LOG(WARN, "failed to get tablet restore status", K(ret)); + } else if (ObTabletRestoreStatus::is_undefined(restore_status)) { + // UNDEFINED tablet need replay. + ret = OB_SUCCESS; + CLOG_LOG_LIMIT(INFO, "tablet is UNDEFINED, but need replay", K(restore_status), K(update_tx_data)); + } else if (ObTabletRestoreStatus::is_pending(restore_status)) { + ret = OB_EAGAIN; + CLOG_LOG_LIMIT(WARN, "tablet is PENDING, need retry", K(ret), K(restore_status), K(update_tx_data)); + } + + return ret; +} + + +int ObTabletReplayExecutor::execute(const share::SCN &scn, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id) +{ + MDS_TG(5_ms); + int ret = OB_SUCCESS; + storage::ObTabletHandle tablet_handle; + bool can_skip_replay = false; + ObTablet *tablet = nullptr; + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + CLOG_LOG(WARN, "replay executor not init", KR(ret), K_(is_inited)); + } else if (!scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + CLOG_LOG(WARN, "replay executor get invalid argument", KR(ret), K(scn), K(ls_id)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "ls service should not be null", K(ret), KP(ls_service)); + } else if (CLICK_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::TABLET_MOD))) { + CLOG_LOG(WARN, "fail to get log stream", KR(ret), K(ls_id)); + } else if (CLICK_FAIL(check_can_skip_replay_(ls_handle, scn, can_skip_replay))) { + CLOG_LOG(WARN, "failed to check can skip reply", K(ret), K(scn), K(ls_id)); + } else if (can_skip_replay) { + // do nothing + } else if (CLICK_FAIL(replay_get_tablet_(ls_handle, tablet_id, scn, tablet_handle))) { + if (OB_OBSOLETE_CLOG_NEED_SKIP == ret) { + CLOG_LOG(INFO, "clog is already obsolete, should skip replay", K(ret), K(ls_id), K(scn)); + ret = OB_SUCCESS; + } else if (OB_EAGAIN == ret) { + CLOG_LOG_LIMIT(WARN, "need retry to get tablet", K(ret), K(ls_id), K(scn)); + } else { + CLOG_LOG(WARN, "failed to get tablet", K(ret), K(ls_id), K(scn)); + } + } else if (CLICK_FAIL(replay_check_restore_status_(tablet_handle))) { + if (OB_NO_NEED_UPDATE == ret) { + CLOG_LOG(WARN, "no need replay after check restore status, skip this log", K(ret), K(ls_id), K(scn)); + } else if (OB_EAGAIN == ret) { + CLOG_LOG_LIMIT(WARN, "need retry after check restore status", K(ret), K(ls_id), K(scn)); + } else { + CLOG_LOG(WARN, "failed to check restore status", K(ret), K(ls_id), K(scn)); + } + } else if (CLICK_FAIL(check_can_skip_replay_to_mds_(scn, tablet_handle, can_skip_replay))) { + CLOG_LOG(WARN, "failed to check can skip reply to mds", K(ret), K(ls_id), K(scn), K(tablet_handle)); + } else if (can_skip_replay) { + //do nothing + } else if (CLICK_FAIL(do_replay_(tablet_handle))) { + if (OB_NO_NEED_UPDATE == ret) { + CLOG_LOG(WARN, "no need replay, skip this log", K(ret), K(ls_id), K(scn)); + } else if (OB_EAGAIN == ret) { + CLOG_LOG_LIMIT(WARN, "failed to replay, need retry", K(ret), K(ls_id), K(scn)); + } else { + CLOG_LOG(WARN, "failed to replay", K(ret), K(ls_id), K(scn)); + } + } + + return ret; +} + +int ObTabletReplayExecutor::replay_get_tablet_( + const storage::ObLSHandle &ls_handle, + const common::ObTabletID &tablet_id, + const share::SCN &scn, + storage::ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + if (!scn.is_valid() || !tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + CLOG_LOG(WARN, "check can skip replay to mds get invalid argument", K(ret), K(scn), K(tablet_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "log stream should not be NULL", KR(ret), K(scn)); + } else if (is_replay_update_user_data_()) { + if (OB_FAIL(ls->replay_get_tablet_no_check(tablet_id, scn, tablet_handle))) { + CLOG_LOG(WARN, "replay get table failed", KR(ret), "ls_id", ls->get_ls_id()); + } + } else if (OB_FAIL(ls->replay_get_tablet(tablet_id, scn, tablet_handle))) { + CLOG_LOG(WARN, "replay get table failed", KR(ret), "ls_id", ls->get_ls_id()); + } + return ret; +} + +int ObTabletReplayExecutor::replay_check_restore_status_(storage::ObTabletHandle &tablet_handle) +{ + const bool update_user_data = is_replay_update_user_data_(); + return ObTabletReplayExecutor::replay_check_restore_status(tablet_handle, update_user_data); +} + +int ObTabletReplayExecutor::check_can_skip_replay_to_mds_( + const share::SCN &scn, + storage::ObTabletHandle &tablet_handle, + bool &can_skip) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + can_skip = false; + + if (!scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + CLOG_LOG(WARN, "check can skip replay to mds get invalid argument", K(ret), K(scn)); + } else if (!is_replay_update_mds_table_()) { + can_skip = false; + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "tablet should not be NULL", K(ret), KP(tablet)); + } else if (tablet->get_tablet_meta().mds_checkpoint_scn_ >= scn) { + can_skip = true; + CLOG_LOG(INFO, "skip replay to mds", KPC(tablet), K(scn)); + } else { + can_skip = false; + } + return ret; +} + +int ObTabletReplayExecutor::check_can_skip_replay_( + const storage::ObLSHandle &ls_handle, + const share::SCN &scn, + bool &can_skip) +{ + int ret = OB_SUCCESS; + can_skip = false; + ObLS *ls = nullptr; + share::SCN tablet_change_scn = share::SCN::min_scn(); + if (!is_replay_update_user_data_()) { + can_skip = false; + } else if (!scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + CLOG_LOG(WARN, "check can skip replay to mds get invalid argument", K(ret), K(scn)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "log stream should not be NULL", KR(ret), K(scn)); + } else if (FALSE_IT(tablet_change_scn = ls->get_tablet_change_checkpoint_scn())) { + } else if (scn <= tablet_change_scn) { + can_skip = true; + CLOG_LOG(INFO, "can skip replay", "ls_id", ls->get_ls_id(), K(tablet_change_scn), K(scn)); + } + + return ret; +} + +int ObTabletReplayExecutor::replay_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + const ObTabletCreateDeleteMdsUserData &mds, + storage::mds::MdsCtx &ctx, + const share::SCN &scn) +{ + int ret = OB_SUCCESS; + storage::ObTablet *tablet = tablet_handle.get_obj(); + if (!is_replay_update_mds_table_()) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "replay log do not update mds table, cannot replay to mds table", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "tablet should not be NULL", KR(ret)); + } else if (tablet->is_ls_inner_tablet()) { + ret = OB_NOT_SUPPORTED; + CLOG_LOG(WARN, "inner tablets have no mds table", KR(ret)); + } else { + ObLSService *ls_svr = MTL(ObLSService*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + const share::ObLSID &ls_id = tablet->get_tablet_meta().ls_id_; + const common::ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; + if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::TABLET_MOD))) { + CLOG_LOG(WARN, "failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "ls is null", K(ret), K(ls_id), KP(ls)); + } else if (OB_FAIL(ls->get_tablet_svr()->replay_set_tablet_status(tablet_id, scn, mds, ctx))) { + CLOG_LOG(WARN, "failed to replay set tablet status", K(ret), K(ls_id), K(tablet_id), K(scn), K(mds)); + } + } + return ret; +} + +int ObTabletReplayExecutor::replay_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + const ObTabletBindingMdsUserData &mds, + storage::mds::MdsCtx &ctx, + const share::SCN &scn) +{ + int ret = OB_SUCCESS; + storage::ObTablet *tablet = tablet_handle.get_obj(); + if (!is_replay_update_mds_table_()) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "replay log do not update mds table, cannot replay to mds table", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "tablet should not be NULL", KR(ret)); + } else if (tablet->is_ls_inner_tablet()) { + ret = OB_NOT_SUPPORTED; + CLOG_LOG(WARN, "inner tablets have no mds table", KR(ret)); + } else { + ObLSService *ls_svr = MTL(ObLSService*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + const share::ObLSID &ls_id = tablet->get_tablet_meta().ls_id_; + const common::ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; + if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::TABLET_MOD))) { + CLOG_LOG(WARN, "failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "ls is null", K(ret), K(ls_id), KP(ls)); + } else if (OB_FAIL(ls->get_tablet_svr()->replay_set_ddl_info(tablet_id, scn, mds, ctx))) { + CLOG_LOG(WARN, "failed to replay set ddl info", K(ret), K(ls_id), K(tablet_id), K(scn), K(mds)); + } + } + return ret; +} + +} +} diff --git a/src/logservice/replayservice/ob_tablet_replay_executor.h b/src/logservice/replayservice/ob_tablet_replay_executor.h new file mode 100644 index 000000000..def66722f --- /dev/null +++ b/src/logservice/replayservice/ob_tablet_replay_executor.h @@ -0,0 +1,229 @@ +/** + * Copyright (c) 2023 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_LOGSERVICE_OB_TABLET_REPLAY_EXECUTOR_ +#define OCEANBASE_LOGSERVICE_OB_TABLET_REPLAY_EXECUTOR_ + +#include +#include "lib/utility/ob_macro_utils.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_binding_mds_user_data.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" + +namespace oceanbase +{ + +namespace share +{ +class SCN; +class ObLSID; +} + +namespace storage +{ +namespace mds +{ +class MdsCtx; +} +} + +namespace logservice +{ + +// Adaptation method: +class ObTabletReplayExecutor +{ +public: + ObTabletReplayExecutor() : is_inited_(false) {} + virtual ~ObTabletReplayExecutor() {} + + // replay on one tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_TABLET_NOT_EXIST, the tablet is not exist. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + int execute(const share::SCN &scn, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id); + + // check restore status before replay + // @return OB_SUCCESS, need replay. + // @return OB_EAGAIN, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + static int replay_check_restore_status(storage::ObTabletHandle &tablet_handle, const bool update_tx_data); + + +protected: + // Check if this replay operation will update the tablet status(ObTabletCreateDeleteMdsUserData), for example, the following + // 6 types of ObTxDataSourceType need return TRUE. + // 1. CREATE_TABLET + // 2. REMOVE_TABLET + // 3. TX_START_TRANSFER_IN + // 4. TX_START_TRANSFER_OUT + // 5. TX_FINISH_TRANSFER_OUT + // 6. TX_FINISH_TRANSFER_IN + virtual bool is_replay_update_user_data_() const = 0; // TODO (wenjinyu.wjy) Modify the function name to is_replay_update_tablet_status_ + + // replay to the tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + virtual int do_replay_(storage::ObTabletHandle &tablet_handle) = 0; + + // The ObTxDataSourceType corresponding to the multi-source data belonging to the member variable of the class ObTabletMdsData can return true + virtual bool is_replay_update_mds_table_() const = 0; + + // Check restore status before replay. + // Usually, you need not override this function, just use the default. + // @return OB_SUCCESS, need replay. + // @return OB_EAGAIN, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + virtual int replay_check_restore_status_(storage::ObTabletHandle &tablet_handle); + + // not allowed to pass ObTabletCreateDeleteMdsUserData or ObTabletBindingMdsUserData + template ::type, ObTabletCreateDeleteMdsUserData>::value + && !std::is_same::type, ObTabletBindingMdsUserData>::value + >::type> + int replay_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + T &&mds, + storage::mds::MdsCtx &ctx, + const share::SCN &scn); + + // non template + int replay_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + const ObTabletCreateDeleteMdsUserData &mds, + storage::mds::MdsCtx &ctx, + const share::SCN &scn); + int replay_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + const ObTabletBindingMdsUserData &mds, + storage::mds::MdsCtx &ctx, + const share::SCN &scn); + template + int replay_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + const K &key, + V &&value, + storage::mds::MdsCtx &ctx, + const share::SCN &scn); + template + int replay_remove_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + const K &key, + storage::mds::MdsCtx &ctx, + const share::SCN &scn); + +private: + int check_can_skip_replay_to_mds_( + const share::SCN &scn, + storage::ObTabletHandle &tablet_handle, + bool &can_skip); + // The replay of multi-source log modified by ObTabletCreateDeleteMdsUserData needs to be filtered by tablet_change_checkpoint_scn + int check_can_skip_replay_( + const storage::ObLSHandle &ls_handle, + const share::SCN &scn, + bool &can_skip); + + int replay_get_tablet_( + const storage::ObLSHandle &ls_handle, + const common::ObTabletID &tablet_id, + const share::SCN &scn, + storage::ObTabletHandle &tablet_handle); + +protected: + bool is_inited_; + + DISALLOW_COPY_AND_ASSIGN(ObTabletReplayExecutor); +}; + +template +int ObTabletReplayExecutor::replay_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + T &&mds, + storage::mds::MdsCtx &ctx, + const share::SCN &scn) +{ + int ret = OB_SUCCESS; + storage::ObTablet *tablet = tablet_handle.get_obj(); + if (!is_replay_update_mds_table_()) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "replay log do not update mds table, cannot replay to mds table", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "tablet should not be NULL", KR(ret)); + } else if (tablet->is_ls_inner_tablet()) { + ret = OB_NOT_SUPPORTED; + CLOG_LOG(WARN, "inner tablets have no mds table", KR(ret)); + } else if (OB_FAIL(tablet->replay(std::forward(mds), ctx, scn))) { + CLOG_LOG(WARN, "failed to do tablet replay", KR(ret)); + } + return ret; +} + +template +int ObTabletReplayExecutor::replay_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + const K &key, + V &&value, + storage::mds::MdsCtx &ctx, + const share::SCN &scn) +{ + int ret = OB_SUCCESS; + storage::ObTablet *tablet = tablet_handle.get_obj(); + if (!is_replay_update_mds_table_()) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "replay log do not update mds table, cannot replay to mds table", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "tablet should not be NULL", KR(ret)); + } else if (tablet->is_ls_inner_tablet()) { + ret = OB_NOT_SUPPORTED; + CLOG_LOG(WARN, "inner tablets have no mds table", KR(ret)); + } else if (OB_FAIL(tablet->replay(key, std::forward(value), ctx, scn))) { + CLOG_LOG(WARN, "failed to do tablet replay", KR(ret)); + } + return ret; +} + +template +int ObTabletReplayExecutor::replay_remove_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + const K &key, + storage::mds::MdsCtx &ctx, + const share::SCN &scn) +{ + int ret = OB_SUCCESS; + storage::ObTablet *tablet = tablet_handle.get_obj(); + if (!is_replay_update_mds_table_()) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "replay log do not remove mds table, cannot replay to mds table", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + CLOG_LOG(WARN, "tablet should not be NULL", KR(ret)); + } else if (tablet->is_ls_inner_tablet()) { + ret = OB_NOT_SUPPORTED; + CLOG_LOG(WARN, "inner tablets have no mds table", KR(ret)); + } else if (OB_SUCCESS != (ret = tablet->replay_remove(key, ctx, scn))) { + CLOG_LOG(WARN, "failed to do tablet replay", KR(ret)); + } + return ret; +} + +} // namespace logservice +} // namespace oceanbase +#endif diff --git a/src/logservice/restoreservice/ob_log_archive_piece_mgr.cpp b/src/logservice/restoreservice/ob_log_archive_piece_mgr.cpp index 60bef1dd1..37020ca3a 100644 --- a/src/logservice/restoreservice/ob_log_archive_piece_mgr.cpp +++ b/src/logservice/restoreservice/ob_log_archive_piece_mgr.cpp @@ -928,6 +928,7 @@ int ObLogArchivePieceContext::get_piece_meta_info_(const int64_t piece_id) share::ObArchiveStore archive_store; bool piece_meta_exist = true; bool is_ls_in_piece = false; + bool is_ls_gc = false; palf::LSN min_lsn; palf::LSN max_lsn; if (piece_id > round_context_.max_piece_id_ || piece_id < round_context_.min_piece_id_) { @@ -940,7 +941,7 @@ int ObLogArchivePieceContext::get_piece_meta_info_(const int64_t piece_id) CLOG_LOG(WARN, "check single piece file exist failed", K(ret), K(piece_id), KPC(this)); } else if (! piece_meta_exist) { // single piece file not exist, active piece - } else if (OB_FAIL(get_ls_inner_piece_info_(id_, dest_id_, round_id, piece_id, min_lsn, max_lsn, is_ls_in_piece))) { + } else if (OB_FAIL(get_ls_inner_piece_info_(id_, dest_id_, round_id, piece_id, min_lsn, max_lsn, is_ls_in_piece, is_ls_gc))) { CLOG_LOG(WARN, "get ls inner piece info failed", K(ret), K(round_id), K(piece_id), K(id_)); } @@ -953,7 +954,11 @@ int ObLogArchivePieceContext::get_piece_meta_info_(const int64_t piece_id) if (is_ls_in_piece) { inner_piece_context_.min_lsn_in_piece_ = min_lsn; inner_piece_context_.max_lsn_in_piece_ = max_lsn; - if (inner_piece_context_.min_lsn_in_piece_ == inner_piece_context_.max_lsn_in_piece_) { + if (is_ls_gc) { + inner_piece_context_.state_ = InnerPieceContext::State::GC; + inner_piece_context_.min_file_id_ = cal_archive_file_id_(inner_piece_context_.min_lsn_in_piece_); + inner_piece_context_.max_file_id_ = cal_archive_file_id_(inner_piece_context_.max_lsn_in_piece_); + } else if (inner_piece_context_.min_lsn_in_piece_ == inner_piece_context_.max_lsn_in_piece_) { inner_piece_context_.state_ = InnerPieceContext::State::EMPTY; } else { inner_piece_context_.state_ = InnerPieceContext::State::FROZEN; @@ -976,13 +981,20 @@ int ObLogArchivePieceContext::get_piece_meta_info_(const int64_t piece_id) return ret; } -int ObLogArchivePieceContext::get_ls_inner_piece_info_(const share::ObLSID &id, const int64_t dest_id, - const int64_t round_id, const int64_t piece_id, palf::LSN &min_lsn, palf::LSN &max_lsn, bool &exist) +int ObLogArchivePieceContext::get_ls_inner_piece_info_(const share::ObLSID &id, + const int64_t dest_id, + const int64_t round_id, + const int64_t piece_id, + palf::LSN &min_lsn, + palf::LSN &max_lsn, + bool &exist, + bool &gc) { int ret = OB_SUCCESS; share::ObArchiveStore archive_store; share::ObSingleLSInfoDesc desc; exist = false; + gc = false; if (OB_FAIL(archive_store.init(archive_dest_))) { CLOG_LOG(WARN, "backup store init failed", K(ret), K_(archive_dest)); } else if (OB_FAIL(archive_store.read_single_ls_info(dest_id, round_id, piece_id, id, desc)) @@ -998,6 +1010,7 @@ int ObLogArchivePieceContext::get_ls_inner_piece_info_(const share::ObLSID &id, K(round_id), K(piece_id), K(id), K(desc)); } else { exist = true; + gc = desc.deleted_; min_lsn = palf::LSN(desc.min_lsn_); max_lsn = palf::LSN(desc.max_lsn_); } diff --git a/src/logservice/restoreservice/ob_log_archive_piece_mgr.h b/src/logservice/restoreservice/ob_log_archive_piece_mgr.h index b4f5c7f8b..b31bbd765 100644 --- a/src/logservice/restoreservice/ob_log_archive_piece_mgr.h +++ b/src/logservice/restoreservice/ob_log_archive_piece_mgr.h @@ -267,7 +267,7 @@ private: int advance_piece_(); virtual int get_piece_meta_info_(const int64_t piece_id); int get_ls_inner_piece_info_(const share::ObLSID &id, const int64_t dest_id, const int64_t round_id, - const int64_t piece_id, palf::LSN &min_lsn, palf::LSN &max_lsn, bool &exist); + const int64_t piece_id, palf::LSN &min_lsn, palf::LSN &max_lsn, bool &exist, bool &gc); virtual int get_piece_file_range_(); int forward_piece_(); diff --git a/src/logservice/restoreservice/ob_log_restore_handler.cpp b/src/logservice/restoreservice/ob_log_restore_handler.cpp index 8b999ff88..458fb05f2 100644 --- a/src/logservice/restoreservice/ob_log_restore_handler.cpp +++ b/src/logservice/restoreservice/ob_log_restore_handler.cpp @@ -593,8 +593,6 @@ int ObLogRestoreHandler::check_restore_done(const SCN &recovery_end_scn, bool &d } else if (OB_UNLIKELY(!recovery_end_scn.is_valid())) { ret = OB_INVALID_ARGUMENT; CLOG_LOG(WARN, "invalid argument", K(ret), K(recovery_end_scn)); - } else if (! is_strong_leader(role_)) { - ret = OB_NOT_MASTER; } else if (restore_context_.seek_done_) { end_lsn = restore_context_.lsn_; } else if (OB_FAIL(palf_handle_.get_end_scn(end_scn))) { diff --git a/src/objit/include/objit/common/ob_item_type.h b/src/objit/include/objit/common/ob_item_type.h index 5c8676895..d216874da 100755 --- a/src/objit/include/objit/common/ob_item_type.h +++ b/src/objit/include/objit/common/ob_item_type.h @@ -2029,6 +2029,7 @@ typedef enum ObItemType T_DELETE_POLICY, T_BACKUP_KEY, T_RESTORE_TENANT_2, + T_CANCEL_RESTORE, T_GEN_ROWS, T_LOAD_BATCH_SIZE, T_DIRECT, // direct load data diff --git a/src/observer/CMakeLists.txt b/src/observer/CMakeLists.txt index b06d0b68d..da92f8e7f 100644 --- a/src/observer/CMakeLists.txt +++ b/src/observer/CMakeLists.txt @@ -239,7 +239,10 @@ ob_set_subtarget(ob_server virtual_table virtual_table/ob_all_virtual_transaction_checkpoint.cpp virtual_table/ob_all_virtual_checkpoint.cpp virtual_table/ob_all_virtual_macro_block_marker_status.cpp + virtual_table/ob_all_virtual_tablet_buffer_info.cpp + virtual_table/ob_all_virtual_mds_node_stat.cpp virtual_table/ob_all_virtual_malloc_sample_info.cpp + virtual_table/ob_all_virtual_mds_event_history.cpp virtual_table/ob_all_virtual_memory_context_stat.cpp virtual_table/ob_all_virtual_memory_info.cpp virtual_table/ob_all_virtual_memstore_info.cpp diff --git a/src/observer/mysql/ob_query_retry_ctrl.cpp b/src/observer/mysql/ob_query_retry_ctrl.cpp index e7f019d9d..809d2e747 100644 --- a/src/observer/mysql/ob_query_retry_ctrl.cpp +++ b/src/observer/mysql/ob_query_retry_ctrl.cpp @@ -251,7 +251,9 @@ public: v.retry_type_ = RETRY_TYPE_NONE; v.no_more_test_ = true; } else if (ObStmt::is_ddl_stmt(v.result_.get_stmt_type(), v.result_.has_global_variable())) { - if (OB_EAGAIN == err || OB_SNAPSHOT_DISCARDED == err || OB_ERR_PARALLEL_DDL_CONFLICT == err) { + if (OB_EAGAIN == err || OB_SNAPSHOT_DISCARDED == err || OB_ERR_PARALLEL_DDL_CONFLICT == err || OB_TRANS_KILLED == err + || OB_PARTITION_IS_BLOCKED == err) { + // OB_PARTITION_IS_BLOCKED is returned when LS is block_tx by a transfer task, DDL need retry try_packet_retry(v); } else { v.client_ret_ = err; diff --git a/src/observer/ob_inner_sql_connection.cpp b/src/observer/ob_inner_sql_connection.cpp index 3c8eab143..621647f6b 100644 --- a/src/observer/ob_inner_sql_connection.cpp +++ b/src/observer/ob_inner_sql_connection.cpp @@ -1057,7 +1057,8 @@ int ObInnerSQLConnection::register_multi_data_source(const uint64_t &tenant_id, const share::ObLSID ls_id, const transaction::ObTxDataSourceType type, const char *buf, - const int64_t buf_len) + const int64_t buf_len, + const transaction::ObRegisterMdsFlag & register_flag) { int ret = OB_SUCCESS; const bool local_execute = is_local_execute(GCONF.cluster_id, tenant_id); @@ -1089,11 +1090,12 @@ int ObInnerSQLConnection::register_multi_data_source(const uint64_t &tenant_id, if (OB_ISNULL(tx_desc = get_session().get_tx_desc())) { // TODO ADD LOG and check get_session ret = OB_ERR_UNEXPECTED; - LOG_WARN("Invalid tx_desc", K(ls_id), K(type)); + LOG_WARN("Invalid tx_desc", K(ret), K(ls_id), K(type)); } else { - MTL_SWITCH(tenant_id) { + MTL_SWITCH(tenant_id) + { if (OB_FAIL(MTL(transaction::ObTransService *) - ->register_mds_into_tx(*tx_desc, ls_id, type, buf, buf_len))) { + ->register_mds_into_tx(*tx_desc, ls_id, type, buf, buf_len, 0, register_flag))) { LOG_WARN("regiser multi data source failed", K(ret), K(tenant_id), K(type)); } else if (OB_FAIL(res.close())) { LOG_WARN("close result set failed", K(ret), K(tenant_id)); @@ -1119,19 +1121,18 @@ int ObInnerSQLConnection::register_multi_data_source(const uint64_t &tenant_id, || OB_FAIL(get_session().get_tx_timeout(trx_timeout))) { LOG_WARN("get conn timeout failed", KR(ret), K(get_session())); } else { - transaction::ObMDSStr mds_str; + transaction::ObMDSInnerSQLStr mds_str; char *tmp_str = nullptr; int64_t pos = 0; ObString sql; - if (OB_FAIL(mds_str.set(buf, buf_len, type, ls_id))) { + if (OB_FAIL(mds_str.set(buf, buf_len, type, ls_id, register_flag))) { LOG_WARN("set multi source data in msd_str error", K(ret), K(type), K(ls_id)); - } else if (OB_ISNULL(tmp_str = - static_cast(ob_malloc(mds_str.get_serialize_size(),"MulTxDataStr")))) { + } else if (OB_ISNULL(tmp_str = static_cast( + ob_malloc(mds_str.get_serialize_size(), "MulTxDataStr")))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("alloc memory for sql_str failed", K(ret), K(mds_str.get_serialize_size())); } else if (OB_FAIL(mds_str.serialize(tmp_str, mds_str.get_serialize_size(), pos))) { - LOG_WARN("serialize mds_str failed", K(ret), K(mds_str), - K(mds_str.get_serialize_size())); + LOG_WARN("serialize mds_str failed", K(ret), K(mds_str), K(mds_str.get_serialize_size())); } else { sql.assign_ptr(tmp_str, mds_str.get_serialize_size()); ret = forward_request_(tenant_id, ObInnerSQLTransmitArg::OPERATION_TYPE_REGISTER_MDS, sql, res); @@ -1156,457 +1157,12 @@ int ObInnerSQLConnection::register_multi_data_source(const uint64_t &tenant_id, return ret; } -int ObInnerSQLConnection::lock_table(const uint64_t tenant_id, - const uint64_t table_id, - const transaction::tablelock::ObTableLockMode lock_mode, - const int64_t timeout_us) +int ObInnerSQLConnection::forward_request(const uint64_t tenant_id, + const int64_t op_type, + const ObString &sql, + ObInnerSQLResult &res) { - int ret = OB_SUCCESS; - ObTabletID no_used; - if (GET_MIN_CLUSTER_VERSION() > CLUSTER_VERSION_4_0_0_0) { - ObLockTableRequest lock_arg; - lock_arg.owner_id_ = 0; - lock_arg.lock_mode_ = lock_mode; - lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; - lock_arg.timeout_us_ = timeout_us; - lock_arg.table_id_ = table_id; - - ret = request_table_lock_(tenant_id, lock_arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE); - } else { - ret = request_table_lock_(tenant_id, table_id, no_used, lock_mode, timeout_us, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE); - } - return ret; -} - -int ObInnerSQLConnection::lock_table(const uint64_t tenant_id, - const ObLockTableRequest &arg) -{ - return request_table_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE); -} - -int ObInnerSQLConnection::unlock_table(const uint64_t tenant_id, - const ObUnLockTableRequest &arg) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); - } else { - ret = request_table_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLE); - } - return ret; -} - -int ObInnerSQLConnection::lock_partition(const uint64_t tenant_id, - const ObLockPartitionRequest &arg) -{ - return request_table_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_PART); -} - -int ObInnerSQLConnection::unlock_partition(const uint64_t tenant_id, - const ObUnLockPartitionRequest &arg) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); - } else { - ret = request_table_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_PART); - } - return ret; -} - -int ObInnerSQLConnection::lock_subpartition(const uint64_t tenant_id, - const ObLockPartitionRequest &arg) -{ - return request_table_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_SUBPART); -} - -int ObInnerSQLConnection::unlock_subpartition(const uint64_t tenant_id, - const ObUnLockPartitionRequest &arg) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); - } else { - ret = request_table_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_SUBPART); - } - return ret; -} - -int ObInnerSQLConnection::lock_tablet(const uint64_t tenant_id, - const uint64_t table_id, - const ObTabletID tablet_id, - const transaction::tablelock::ObTableLockMode lock_mode, - const int64_t timeout_us) -{ - int ret = OB_SUCCESS; - if (GET_MIN_CLUSTER_VERSION() > CLUSTER_VERSION_4_0_0_0) { - ObLockTabletRequest lock_arg; - lock_arg.owner_id_ = 0; - lock_arg.lock_mode_ = lock_mode; - lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; - lock_arg.timeout_us_ = timeout_us; - lock_arg.table_id_ = table_id; - lock_arg.tablet_id_ = tablet_id; - - ret = request_table_lock_(tenant_id, lock_arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET); - } else { - // for 4.0 - ret = request_table_lock_(tenant_id, table_id, tablet_id, lock_mode, timeout_us, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET); - } - return ret; -} - -int ObInnerSQLConnection::lock_tablet(const uint64_t tenant_id, - const ObLockTabletRequest &arg) -{ - return request_table_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET); -} - -int ObInnerSQLConnection::unlock_tablet(const uint64_t tenant_id, - const ObUnLockTabletRequest &arg) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); - } else { - ret = request_table_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLET); - } - return ret; -} - -int ObInnerSQLConnection::lock_obj(const uint64_t tenant_id, - const ObLockObjRequest &arg) -{ - return request_table_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJ); -} - -int ObInnerSQLConnection::unlock_obj(const uint64_t tenant_id, - const ObUnLockObjRequest &arg) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); - } else { - ret = request_table_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJ); - } - return ret; -} - - -int ObInnerSQLConnection::request_table_lock_(const uint64_t tenant_id, - const ObLockRequest &arg, - const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type) -{ - int ret = OB_SUCCESS; - observer::ObReqTimeGuard req_timeinfo_guard; - - const bool local_execute = is_local_execute(GCONF.cluster_id, tenant_id); - transaction::ObTxDesc *tx_desc = nullptr; - - SMART_VAR(ObInnerSQLResult, res, get_session()) - { - if (!inited_) { - ret = OB_NOT_INIT; - LOG_WARN("connection not inited", K(ret)); - } else if (OB_INVALID_ID == tenant_id) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tenant_id)); - } else if (local_execute) { - if (OB_FAIL(switch_tenant(tenant_id))) { - LOG_WARN("set system tenant id failed", K(ret), K(tenant_id)); - } - } else { - LOG_DEBUG("tenant may be not in server", K(ret), K(local_execute), K(tenant_id), K(MYADDR)); - } - if (OB_SUCC(ret)) { - if (!is_in_trans()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("inner conn must be already in trans", K(ret)); - } else if (OB_FAIL(res.init(local_execute))) { - LOG_WARN("init result set", K(ret), K(local_execute)); - } else if (local_execute) { - transaction::ObTxParam tx_param; - tx_param.access_mode_ = transaction::ObTxAccessMode::RW; - tx_param.isolation_ = get_session().get_tx_isolation(); - tx_param.cluster_id_ = GCONF.cluster_id; - get_session().get_tx_timeout(tx_param.timeout_us_); - tx_param.lock_timeout_us_ = get_session().get_trx_lock_timeout(); - - if (OB_ISNULL(tx_desc = get_session().get_tx_desc())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Invalid tx_desc"); - } else { - MTL_SWITCH(tenant_id) { - switch (operation_type) { - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: { - const ObLockTableRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->lock_table(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock table failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLE: { - const ObUnLockTableRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->unlock_table(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("unlock table failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: { - const ObLockTabletRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->lock_tablet(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock tablet failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLET: { - const ObUnLockTabletRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->unlock_tablet(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("unlock tablet failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_PART: { - const ObLockPartitionRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->lock_partition(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock partition failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_PART: { - const ObUnLockPartitionRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->unlock_partition(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("unlock partition failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJ: { - const ObLockObjRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->lock_obj(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock object failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJ: { - const ObUnLockObjRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->unlock_obj(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("unlock object failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_SUBPART: { - const ObLockPartitionRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->lock_subpartition(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock subpartition failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_SUBPART: { - const ObUnLockPartitionRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->unlock_subpartition(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("unlock subpartition failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - default: { - LOG_WARN("operation_type is not expected", K(operation_type)); - ret = OB_ERR_UNEXPECTED; - } // default - } // switch - if (OB_SUCC(ret) && OB_FAIL(res.close())) { - LOG_WARN("close result set failed", K(ret), K(tenant_id)); - } - } // MTL_SWITCH - } // else - } else { - char *tmp_str = nullptr; - int64_t pos = 0; - ObString sql; - if (OB_ISNULL(tmp_str = static_cast(ob_malloc(arg.get_serialize_size(), "LockTableReq")))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("alloc memory for sql_str failed", K(ret), K(arg.get_serialize_size())); - } else if (OB_FAIL(arg.serialize(tmp_str, arg.get_serialize_size(), pos))) { - LOG_WARN("serialize lock table arg failed", K(ret), K(arg)); - } else { - sql.assign_ptr(tmp_str, arg.get_serialize_size()); - ret = forward_request_(tenant_id, operation_type, sql, res); - } - - if (OB_NOT_NULL(tmp_str)) { - ob_free(tmp_str); - } - } - } - } - - return ret; -} - -// for version 4.0 -int ObInnerSQLConnection::request_table_lock_(const uint64_t tenant_id, - const uint64_t table_id, // as obj_id when lock_obj - const ObTabletID tablet_id, //just used when lock_tablet - const ObTableLockMode lock_mode, - const int64_t timeout_us, - const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type) -{ - int ret = OB_SUCCESS; - observer::ObReqTimeGuard req_timeinfo_guard; - - const bool local_execute = is_local_execute(GCONF.cluster_id, tenant_id); - transaction::ObTxDesc *tx_desc = nullptr; - - SMART_VAR(ObInnerSQLResult, res, get_session()) - { - if (!inited_) { - ret = OB_NOT_INIT; - LOG_WARN("connection not inited", K(ret)); - } else if (OB_INVALID_ID == tenant_id) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tenant_id)); - } else if (local_execute) { - if (OB_FAIL(switch_tenant(tenant_id))) { - LOG_WARN("set system tenant id failed", K(ret), K(tenant_id)); - } - } else { - LOG_DEBUG("tenant not in server", K(ret), K(tenant_id), K(MYADDR)); - } - - if (OB_SUCC(ret)) { - if (!is_in_trans()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("inner conn must be already in trans", K(ret)); - } else if (OB_FAIL(res.init(local_execute))) { - LOG_WARN("init result set", K(ret), K(local_execute)); - } else if (local_execute) { - transaction::ObTxParam tx_param; - tx_param.access_mode_ = transaction::ObTxAccessMode::RW; - tx_param.isolation_ = get_session().get_tx_isolation(); - tx_param.cluster_id_ = GCONF.cluster_id; - get_session().get_tx_timeout(tx_param.timeout_us_); - tx_param.lock_timeout_us_ = get_session().get_trx_lock_timeout(); - - if (OB_ISNULL(tx_desc = get_session().get_tx_desc())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Invalid tx_desc"); - } else { - MTL_SWITCH(tenant_id) { - switch (operation_type) { - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: { - ObLockTableRequest lock_arg; - lock_arg.owner_id_ = 0; - lock_arg.lock_mode_ = lock_mode; - lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; - lock_arg.timeout_us_ = timeout_us; - lock_arg.table_id_ = table_id; - if (OB_FAIL(MTL(ObTableLockService*)->lock_table(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock table failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: { - ObLockTabletRequest lock_arg; - lock_arg.owner_id_ = 0; - lock_arg.lock_mode_ = lock_mode; - lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; - lock_arg.timeout_us_ = timeout_us; - lock_arg.table_id_ = table_id; - lock_arg.tablet_id_ = tablet_id; - if (OB_FAIL(MTL(ObTableLockService*)->lock_tablet(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock tablet failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - default: - LOG_WARN("operation_type is not expected", K(operation_type)); - ret = OB_ERR_UNEXPECTED; - } - if (OB_SUCC(ret) && OB_FAIL(res.close())) { - LOG_WARN("close result set failed", K(ret), K(tenant_id)); - } - } - } - } else { - char *tmp_str = nullptr; - int64_t pos = 0; - ObString sql; - switch (operation_type) { - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: { - ObInTransLockTableRequest arg; - arg.table_id_ = table_id; - arg.lock_mode_ = lock_mode; - arg.timeout_us_ = timeout_us; - - if (OB_ISNULL(tmp_str = static_cast(ob_malloc(arg.get_serialize_size(), "LockTableReq")))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("alloc memory for sql_str failed", K(ret), K(arg.get_serialize_size())); - } else if (OB_FAIL(arg.serialize(tmp_str, arg.get_serialize_size(), pos))) { - LOG_WARN("serialize lock table arg failed", K(ret), K(arg)); - } else { - sql.assign_ptr(tmp_str, arg.get_serialize_size()); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: { - ObInTransLockTabletRequest arg; - arg.table_id_ = table_id; - arg.tablet_id_ = tablet_id; - arg.lock_mode_ = lock_mode; - arg.timeout_us_ = timeout_us; - - if (OB_ISNULL(tmp_str = static_cast(ob_malloc(arg.get_serialize_size(), "LockTableReq")))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("alloc memory for sql_str failed", K(ret), K(arg.get_serialize_size())); - } else if (OB_FAIL(arg.serialize(tmp_str, arg.get_serialize_size(), pos))) { - LOG_WARN("serialize lock table arg failed", K(ret), K(arg)); - } else { - sql.assign_ptr(tmp_str, arg.get_serialize_size()); - } - break; - } - default: { - LOG_WARN("operation_type is not expected", K(operation_type)); - ret = OB_ERR_UNEXPECTED; - } // default - } // switch - ret = forward_request_(tenant_id, operation_type, sql, res); - if (OB_NOT_NULL(tmp_str)) { - ob_free(tmp_str); - } - } - } - } - - return ret; + return forward_request_(tenant_id, op_type, sql, res); } int ObInnerSQLConnection::forward_request_(const uint64_t tenant_id, diff --git a/src/observer/ob_inner_sql_connection.h b/src/observer/ob_inner_sql_connection.h index 1a061672e..51e9c02b7 100644 --- a/src/observer/ob_inner_sql_connection.h +++ b/src/observer/ob_inner_sql_connection.h @@ -54,6 +54,7 @@ class ObSql; namespace transaction { enum class ObTxDataSourceType : int64_t; +struct ObRegisterMdsFlag; namespace tablelock { class ObLockRequest; @@ -160,36 +161,8 @@ public: const share::ObLSID ls_id, const transaction::ObTxDataSourceType type, const char *buf, - const int64_t buf_len); - virtual int lock_table(const uint64_t tenant_id, - const uint64_t table_id, - const transaction::tablelock::ObTableLockMode lock_mode, - const int64_t timeout_us); - virtual int lock_table(const uint64_t tenant_id, - const transaction::tablelock::ObLockTableRequest &arg); - virtual int unlock_table(const uint64_t tenant_id, - const transaction::tablelock::ObUnLockTableRequest &arg); - virtual int lock_partition(const uint64_t tenant_id, - const transaction::tablelock::ObLockPartitionRequest &arg); - virtual int unlock_partition(const uint64_t tenant_id, - const transaction::tablelock::ObUnLockPartitionRequest &arg); - virtual int lock_subpartition(const uint64_t tenant_id, - const transaction::tablelock::ObLockPartitionRequest &arg); - virtual int unlock_subpartition(const uint64_t tenant_id, - const transaction::tablelock::ObUnLockPartitionRequest &arg); - virtual int lock_tablet(const uint64_t tenant_id, - const uint64_t table_id, - const ObTabletID tablet_id, - const transaction::tablelock::ObTableLockMode lock_mode, - const int64_t timeout_us); - virtual int lock_tablet(const uint64_t tenant_id, - const transaction::tablelock::ObLockTabletRequest &arg); - virtual int unlock_tablet(const uint64_t tenant_id, - const transaction::tablelock::ObUnLockTabletRequest &arg); - virtual int lock_obj(const uint64_t tenant_id, - const transaction::tablelock::ObLockObjRequest &arg); - virtual int unlock_obj(const uint64_t tenant_id, - const transaction::tablelock::ObUnLockObjRequest &arg); + const int64_t buf_len, + const transaction::ObRegisterMdsFlag ®ister_flag = transaction::ObRegisterMdsFlag()); virtual sqlclient::ObCommonServerConnectionPool *get_common_server_pool() override; virtual int rollback() override; virtual int commit() override; @@ -269,6 +242,11 @@ public: virtual int execute(const uint64_t tenant_id, sqlclient::ObIExecutor &executor) override; + int forward_request(const uint64_t tenant_id, + const int64_t op_type, + const ObString &sql, + ObInnerSQLResult &res); + public: // nested session and sql execute for foreign key. int begin_nested_session(sql::ObSQLSessionInfo::StmtSavedValue &saved_session, @@ -319,7 +297,8 @@ public: const bool is_ddl); int64_t get_init_timestamp() const { return init_timestamp_; } - + int switch_tenant(const uint64_t tenant_id); + bool is_local_execute(const int64_t cluster_id, const uint64_t tenant_id); public: static const int64_t LOCK_RETRY_TIME = 1L * 1000 * 1000; static const int64_t TOO_MANY_REF_ALERT = 1024; @@ -354,8 +333,6 @@ private: ObVirtualTableIteratorFactory *vt_iter_factory = NULL); int do_query(sqlclient::ObIExecutor &executor, ObInnerSQLResult &res); - int switch_tenant(const uint64_t tenant_id); - // set timeout to session variable int set_timeout(int64_t &abs_timeout_us); @@ -367,8 +344,6 @@ private: const share::ObLSID ls_id, common::ObAddr &leader); - bool is_local_execute(const int64_t cluster_id, const uint64_t tenant_id); - int execute_read_inner(const int64_t cluster_id, const uint64_t tenant_id, const ObString &sql, common::ObISQLClient::ReadResult &res, bool is_user_sql = false, const common::ObAddr *sql_exec_addr = nullptr); @@ -383,15 +358,6 @@ private: const ObString &sql, ObInnerSQLResult &res); int get_session_timeout_for_rpc(int64_t &query_timeout, int64_t &trx_timeout); - int request_table_lock_(const uint64_t tenant_id, - const uint64_t table_id, - const ObTabletID tablet_id, //just used when lock_tablet - const transaction::tablelock::ObTableLockMode lock_mode, - const int64_t timeout_us, - const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type); - int request_table_lock_(const uint64_t tenant_id, - const transaction::tablelock::ObLockRequest &arg, - const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type); private: bool inited_; observer::ObQueryRetryCtrl retry_ctrl_; diff --git a/src/observer/ob_inner_sql_rpc_processor.cpp b/src/observer/ob_inner_sql_rpc_processor.cpp index 413256a93..d3b5f577c 100644 --- a/src/observer/ob_inner_sql_rpc_processor.cpp +++ b/src/observer/ob_inner_sql_rpc_processor.cpp @@ -22,10 +22,12 @@ #include "lib/container/ob_iarray.h" #include "storage/tx/ob_multi_data_source.h" #include "sql/plan_cache/ob_plan_cache_util.h" +#include "storage/tablelock/ob_lock_inner_connection_util.h" using namespace oceanbase::common; using namespace oceanbase::share::schema; using namespace oceanbase::sql; +using namespace oceanbase::transaction::tablelock; namespace oceanbase { @@ -58,14 +60,14 @@ int ObInnerSqlRpcP::process_register_mds(sqlclient::ObISQLConnection *conn, { int ret = OB_SUCCESS; observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - transaction::ObMDSStr msd_str; + transaction::ObMDSInnerSQLStr mds_str; int64_t pos = 0; - if (OB_FAIL(msd_str.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { + if (OB_FAIL(mds_str.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { LOG_WARN("deserialize multi data source str failed", K(ret), K(arg), K(pos)); } else if (OB_FAIL(inner_conn->register_multi_data_source( - arg.get_tenant_id(), msd_str.get_ls_id(), msd_str.get_msd_type(), - msd_str.get_msd_buf(), msd_str.get_msd_buf_len()))) { - LOG_WARN("register multi data source failed", K(ret), K(arg.get_tenant_id()), K(msd_str)); + arg.get_tenant_id(), mds_str.get_ls_id(), mds_str.get_msd_type(), + mds_str.get_msd_buf(), mds_str.get_msd_buf_len(), mds_str.get_register_flag()))) { + LOG_WARN("register multi data source failed", K(ret), K(arg.get_tenant_id()), K(mds_str)); } return ret; @@ -207,182 +209,6 @@ int ObInnerSqlRpcP::process_read( return ret; } -int ObInnerSqlRpcP::process_lock_table(sqlclient::ObISQLConnection *conn, - const ObInnerSQLTransmitArg &arg) -{ - int ret = OB_SUCCESS; - observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - int64_t pos = 0; - - if (GET_MIN_CLUSTER_VERSION() <= CLUSTER_VERSION_4_0_0_0) { - ObInTransLockTableRequest lock_arg; - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else { - ObLockTableRequest tmp_arg; - tmp_arg.owner_id_ = 0; - tmp_arg.lock_mode_ = lock_arg.lock_mode_; - tmp_arg.op_type_ = IN_TRANS_COMMON_LOCK; - tmp_arg.timeout_us_ = lock_arg.timeout_us_; - tmp_arg.table_id_ = lock_arg.table_id_; - if (OB_FAIL(inner_conn->lock_table(arg.get_tenant_id(), - tmp_arg))) { - LOG_WARN("lock table failed", K(ret), K(arg.get_tenant_id()), K(tmp_arg)); - } - } - } else { - ObLockTableRequest lock_arg; - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else if (OB_FAIL(inner_conn->lock_table(arg.get_tenant_id(), - lock_arg))) { - LOG_WARN("lock table failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); - } - } - - return ret; -} - -int ObInnerSqlRpcP::process_unlock_table(sqlclient::ObISQLConnection *conn, - const ObInnerSQLTransmitArg &arg) -{ - int ret = OB_SUCCESS; - observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - ObUnLockTableRequest lock_arg; - int64_t pos = 0; - - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), - arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else if (OB_FAIL(inner_conn->unlock_table(arg.get_tenant_id(), - lock_arg))) { - LOG_WARN("unlock table failed", K(ret), K(arg.get_tenant_id()), - K(lock_arg)); - } - - return ret; -} - -int ObInnerSqlRpcP::process_lock_partition(sqlclient::ObISQLConnection *conn, - const ObInnerSQLTransmitArg &arg) -{ - int ret = OB_SUCCESS; - observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - ObLockPartitionRequest lock_arg; - int64_t pos = 0; - - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else if (OB_FAIL(inner_conn->lock_partition(arg.get_tenant_id(), lock_arg))) { - LOG_WARN("lock partition failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); - } - - return ret; -} - -int ObInnerSqlRpcP::process_unlock_partition(sqlclient::ObISQLConnection *conn, - const ObInnerSQLTransmitArg &arg) -{ - int ret = OB_SUCCESS; - observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - ObUnLockPartitionRequest lock_arg; - int64_t pos = 0; - - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else if (OB_FAIL(inner_conn->unlock_partition(arg.get_tenant_id(), lock_arg))) { - LOG_WARN("unlock partition failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); - } - - return ret; -} - -int ObInnerSqlRpcP::process_lock_subpartition(sqlclient::ObISQLConnection *conn, - const ObInnerSQLTransmitArg &arg) -{ - int ret = OB_SUCCESS; - observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - ObLockPartitionRequest lock_arg; - int64_t pos = 0; - - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else if (OB_FAIL(inner_conn->lock_subpartition(arg.get_tenant_id(), lock_arg))) { - LOG_WARN("lock subpartition failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); - } - - return ret; -} - -int ObInnerSqlRpcP::process_unlock_subpartition(sqlclient::ObISQLConnection *conn, - const ObInnerSQLTransmitArg &arg) -{ - int ret = OB_SUCCESS; - observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - ObUnLockPartitionRequest lock_arg; - int64_t pos = 0; - - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else if (OB_FAIL(inner_conn->unlock_subpartition(arg.get_tenant_id(), lock_arg))) { - LOG_WARN("unlock subpartition failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); - } - - return ret; -} - -int ObInnerSqlRpcP::process_lock_tablet(sqlclient::ObISQLConnection *conn, - const ObInnerSQLTransmitArg &arg) -{ - int ret = OB_SUCCESS; - observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - int64_t pos = 0; - - if (GET_MIN_CLUSTER_VERSION() <= CLUSTER_VERSION_4_0_0_0) { - ObInTransLockTabletRequest lock_arg; - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else { - ObLockTabletRequest tmp_arg; - tmp_arg.owner_id_ = 0; - tmp_arg.lock_mode_ = lock_arg.lock_mode_; - tmp_arg.op_type_ = IN_TRANS_COMMON_LOCK; - tmp_arg.timeout_us_ = lock_arg.timeout_us_; - tmp_arg.table_id_ = lock_arg.table_id_; - tmp_arg.tablet_id_ = lock_arg.tablet_id_; - if (OB_FAIL(inner_conn->lock_tablet(arg.get_tenant_id(), tmp_arg))) { - LOG_WARN("lock tablet failed", K(ret), K(arg.get_tenant_id()), K(tmp_arg)); - } - } - } else { - ObLockTabletRequest lock_arg; - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else if (OB_FAIL(inner_conn->lock_tablet(arg.get_tenant_id(), lock_arg))) { - LOG_WARN("lock tablet failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); - } - } - - return ret; -} - -int ObInnerSqlRpcP::process_unlock_tablet(sqlclient::ObISQLConnection *conn, - const ObInnerSQLTransmitArg &arg) -{ - int ret = OB_SUCCESS; - observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - ObUnLockTabletRequest lock_arg; - int64_t pos = 0; - - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else if (OB_FAIL(inner_conn->unlock_tablet(arg.get_tenant_id(), lock_arg))) { - LOG_WARN("unlock tablet failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); - } - - return ret; -} - int ObInnerSqlRpcP::create_tmp_session( uint64_t tenant_id, sql::ObSQLSessionInfo *&tmp_session, @@ -438,40 +264,6 @@ void ObInnerSqlRpcP::cleanup_tmp_session( ObActiveSessionGuard::setup_default_ash(); // enforce cleanup for future RPC cases } -int ObInnerSqlRpcP::process_lock_obj(sqlclient::ObISQLConnection *conn, - const ObInnerSQLTransmitArg &arg) -{ - int ret = OB_SUCCESS; - observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - ObLockObjRequest lock_arg; - int64_t pos = 0; - - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else if (OB_FAIL(inner_conn->lock_obj(arg.get_tenant_id(), lock_arg))) { - LOG_WARN("lock object failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); - } - - return ret; -} - -int ObInnerSqlRpcP::process_unlock_obj(sqlclient::ObISQLConnection *conn, - const ObInnerSQLTransmitArg &arg) -{ - int ret = OB_SUCCESS; - observer::ObInnerSQLConnection *inner_conn = static_cast(conn); - ObUnLockObjRequest lock_arg; - int64_t pos = 0; - - if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { - LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); - } else if (OB_FAIL(inner_conn->unlock_obj(arg.get_tenant_id(), lock_arg))) { - LOG_WARN("unlock object failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); - } - - return ret; -} - int ObInnerSqlRpcP::process() { int ret = OB_SUCCESS; @@ -608,63 +400,21 @@ int ObInnerSqlRpcP::process() } break; } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: { - if (OB_FAIL(process_lock_table(conn, transmit_arg))) { - LOG_WARN("process lock table failed", K(ret)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLE: { - if (OB_FAIL(process_unlock_table(conn, transmit_arg))) { - LOG_WARN("process unlock table failed", K(ret)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: { - if (OB_FAIL(process_lock_tablet(conn, transmit_arg))) { - LOG_WARN("process lock tablet failed", K(ret)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLET: { - if (OB_FAIL(process_unlock_tablet(conn, transmit_arg))) { - LOG_WARN("process unlock tablet failed", K(ret)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJ: { - if (OB_FAIL(process_lock_obj(conn, transmit_arg))) { - LOG_WARN("process lock obj failed", K(ret)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJ: { - if (OB_FAIL(process_unlock_obj(conn, transmit_arg))) { - LOG_WARN("process unlock obj failed", K(ret)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_PART: { - if (OB_FAIL(process_lock_partition(conn, transmit_arg))) { - LOG_WARN("process lock partition failed", K(ret)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_PART: { - if (OB_FAIL(process_unlock_partition(conn, transmit_arg))) { - LOG_WARN("process unlock partition failed", K(ret)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_SUBPART: { - if (OB_FAIL(process_lock_subpartition(conn, transmit_arg))) { - LOG_WARN("process lock subpartition failed", K(ret)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_SUBPART: { - if (OB_FAIL(process_unlock_subpartition(conn, transmit_arg))) { - LOG_WARN("process unlock subpartition failed", K(ret)); + // deal with lock rpc + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLE: + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLET: + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJ: + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJ: + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_PART: + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_PART: + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_SUBPART: + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_SUBPART: + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_ALONE_TABLET: + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_ALONE_TABLET: { + if (OB_FAIL(ObInnerConnectionLockUtil::process_lock_rpc(transmit_arg, conn))) { + LOG_WARN("process lock rpc failed", K(ret), K(transmit_arg.get_operation_type())); } break; } diff --git a/src/observer/ob_inner_sql_rpc_processor.h b/src/observer/ob_inner_sql_rpc_processor.h index 11c48ab9d..23674307a 100644 --- a/src/observer/ob_inner_sql_rpc_processor.h +++ b/src/observer/ob_inner_sql_rpc_processor.h @@ -71,26 +71,6 @@ private: int set_session_param_to_conn( sqlclient::ObISQLConnection *conn, const ObInnerSQLTransmitArg &transmit_arg); - int process_lock_table(sqlclient::ObISQLConnection *con, - const ObInnerSQLTransmitArg &arg); - int process_unlock_table(sqlclient::ObISQLConnection *con, - const ObInnerSQLTransmitArg &arg); - int process_lock_partition(sqlclient::ObISQLConnection *con, - const ObInnerSQLTransmitArg &arg); - int process_unlock_partition(sqlclient::ObISQLConnection *con, - const ObInnerSQLTransmitArg &arg); - int process_lock_subpartition(sqlclient::ObISQLConnection *con, - const ObInnerSQLTransmitArg &arg); - int process_unlock_subpartition(sqlclient::ObISQLConnection *con, - const ObInnerSQLTransmitArg &arg); - int process_lock_tablet(sqlclient::ObISQLConnection *con, - const ObInnerSQLTransmitArg &arg); - int process_unlock_tablet(sqlclient::ObISQLConnection *con, - const ObInnerSQLTransmitArg &arg); - int process_lock_obj(sqlclient::ObISQLConnection *con, - const ObInnerSQLTransmitArg &arg); - int process_unlock_obj(sqlclient::ObISQLConnection *con, - const ObInnerSQLTransmitArg &arg); const observer::ObGlobalContext &gctx_; DISALLOW_COPY_AND_ASSIGN(ObInnerSqlRpcP); }; diff --git a/src/observer/ob_inner_sql_rpc_proxy.h b/src/observer/ob_inner_sql_rpc_proxy.h index e4b7d9a45..a8b18ad7e 100644 --- a/src/observer/ob_inner_sql_rpc_proxy.h +++ b/src/observer/ob_inner_sql_rpc_proxy.h @@ -48,6 +48,8 @@ public: OPERATION_TYPE_UNLOCK_OBJ = 14, OPERATION_TYPE_LOCK_SUBPART = 15, OPERATION_TYPE_UNLOCK_SUBPART = 16, + OPERATION_TYPE_LOCK_ALONE_TABLET = 17, + OPERATION_TYPE_UNLOCK_ALONE_TABLET = 18, OPERATION_TYPE_MAX = 100 }; diff --git a/src/observer/ob_rpc_processor_simple.cpp b/src/observer/ob_rpc_processor_simple.cpp index 16c54441e..3f21e54be 100644 --- a/src/observer/ob_rpc_processor_simple.cpp +++ b/src/observer/ob_rpc_processor_simple.cpp @@ -44,17 +44,22 @@ #include "storage/ls/ob_ls.h" #include "storage/tablet/ob_tablet.h" #include "storage/tx/ob_trans_service.h" +#include "storage/ob_tablet_autoinc_seq_rpc_handler.h" #include "share/ob_tablet_autoincrement_service.h" #include "share/sequence/ob_sequence_cache.h" #include "logservice/ob_log_service.h" #include "logservice/ob_log_handler.h" #include "share/scn.h" +#include "storage/ob_common_id_utils.h" #include "storage/high_availability/ob_storage_ha_service.h" #include "storage/tx_table/ob_tx_table.h" #include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" #include "storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h" #include "observer/ob_req_time_service.h" #include "observer/ob_server_event_history_table_operator.h" +#include "rootserver/ob_primary_ls_service.h"//PrimaryLSService +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "storage/high_availability/ob_transfer_service.h" // ObTransferService #include "sql/udr/ob_udr_mgr.h" #include "sql/plan_cache/ob_ps_cache.h" #include "rootserver/ob_primary_ls_service.h" // for ObPrimaryLSService @@ -655,18 +660,6 @@ int ObRpcBackupMetaP::process() return ret; } -int ObRpcBackupCheckTabletP::process() -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(gctx_.ob_service_)) { - ret = OB_INVALID_ARGUMENT; - LOG_ERROR("invalid argument", K(gctx_.ob_service_), K(ret)); - } else { - ret = gctx_.ob_service_->check_not_backup_tablet_create_scn(arg_); - } - return ret; -} - int ObRpcCheckBackupTaskExistP::process() { int ret = OB_SUCCESS; @@ -799,6 +792,28 @@ int ObRpcSwitchSchemaP::process() return ret; } +int ObRpcCreateTenantUserLSP::process() +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = arg_; + if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid argument", K(ret), K(tenant_id)); + } else { + MTL_SWITCH(tenant_id) { + rootserver::ObPrimaryLSService* primary_ls_service = MTL(rootserver::ObPrimaryLSService*); + if (OB_ISNULL(primary_ls_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("primary ls service is null", KR(ret), K(tenant_id)); + } else if (OB_FAIL(primary_ls_service->create_ls_for_create_tenant())) { + LOG_WARN("failed to create ls for create tenant", KR(ret), K(tenant_id)); + } + } + } + return ret; + +} + int ObRpcRefreshMemStatP::process() { int ret = OB_SUCCESS; @@ -913,7 +928,7 @@ int ObDumpMemtableP::process() } else if (OB_ISNULL(ls->get_tablet_svr())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get_tablet_svr is null", KR(ret), K(arg_.tenant_id_), K(arg_.tablet_id_)); - } else if (OB_FAIL(ls->get_tablet_svr()->get_tablet(arg_.tablet_id_, tablet_handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls->get_tablet_svr()->get_tablet(arg_.tablet_id_, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet failed", KR(ret), K(arg_.tenant_id_), K(arg_.tablet_id_)); } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { ret = OB_ERR_UNEXPECTED; @@ -1434,22 +1449,6 @@ int ObRpcCheckLSCanOfflineP::process() return ret; } -int ObRpcCreateTabletP::process() -{ - int ret = OB_SUCCESS; - if (OB_SUCC(ret)) { - ObLSService *ls_svr = nullptr; - ls_svr = MTL(ObLSService*); - if (OB_ISNULL(ls_svr)) { - ret = OB_ERR_UNEXPECTED; - COMMON_LOG(ERROR, "mtl ObLSService should not be null", K(ret)); - } else if (OB_FAIL(ls_svr->create_tablet(arg_, result_))) { - COMMON_LOG(WARN, "failed create tablet", KR(ret), K(arg_)); - } - } - return ret; -} - int ObRpcGetLSAccessModeP::process() { int ret = OB_SUCCESS; @@ -1491,7 +1490,7 @@ int ObRpcGetLSAccessModeP::process() const SCN ref_scn = SCN::min_scn(); if (OB_FAIL(log_handler->get_access_mode(mode_version, mode))) { LOG_WARN("failed to get access mode", KR(ret), K(ls_id)); - } else if (OB_FAIL(result_.init(tenant_id, ls_id, mode_version, mode, ref_scn))) { + } else if (OB_FAIL(result_.init(tenant_id, ls_id, mode_version, mode, ref_scn, GCTX.self_addr()))) { LOG_WARN("failed to init res", KR(ret), K(tenant_id), K(ls_id), K(mode_version), K(mode)); } else if (OB_FAIL(log_ls_svr->get_palf_role(ls_id, role, second_proposal_id))) { COMMON_LOG(WARN, "failed to get palf role", KR(ret), K(ls_id)); @@ -1551,25 +1550,6 @@ int ObRpcChangeLSAccessModeP::process() return ret; } - - - -int ObRpcDropTabletP::process() -{ - int ret = OB_SUCCESS; - ObLSService *ls_svr = nullptr; - if (OB_SUCC(ret)) { - ls_svr = MTL(ObLSService*); - if (OB_ISNULL(ls_svr)) { - ret = OB_ERR_UNEXPECTED; - COMMON_LOG(ERROR, "mtl ObLSService should not be null", K(ret)); - } else if (OB_FAIL(ls_svr->remove_tablet(arg_, result_))) { - COMMON_LOG(WARN, "failed create tablet", KR(ret), K(arg_)); - } - } - return ret; -} - int ObRpcSetMemberListP::process() { int ret = OB_SUCCESS; @@ -2190,7 +2170,7 @@ int ObRegisterTxDataP::process() LOG_WARN("unexpected null tx service ptr", KR(ret), K(arg_)); } else if (OB_FAIL(tx_svc->register_mds_into_tx(*(arg_.tx_desc_), arg_.ls_id_, arg_.type_, arg_.buf_.ptr(), arg_.buf_.length(), - arg_.request_id_))) { + arg_.request_id_, arg_.register_flag_))) { LOG_WARN("register into tx failed", KR(ret), K(arg_)); } else if (OB_FAIL(tx_svc->collect_tx_exec_result(*(arg_.tx_desc_), result_.tx_result_))) { LOG_WARN("collect tx result failed", KR(ret), K(result_)); @@ -2284,6 +2264,30 @@ int ObRpcCheckBackupDestConnectivityP::process() return ret; } +int ObRpcBackupLSDataResP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(gctx_.ob_service_)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid argument", K(gctx_.ob_service_), K(ret)); + } else { + ret = gctx_.ob_service_->report_backup_over(arg_); + } + return ret; +} + +int ObRpcBackupCleanLSResP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(gctx_.ob_service_)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid argument", K(gctx_.ob_service_), K(ret)); + } else { + ret = gctx_.ob_service_->report_backup_clean_over(arg_); + } + return ret; +} + int ObEstimateTabletBlockCountP::process() { @@ -2297,6 +2301,32 @@ int ObEstimateTabletBlockCountP::process() return ret; } +int ObRpcGenUniqueIDP::process() +{ + int ret = ObCommonIDUtils::gen_unique_id(arg_, result_); + return ret; +} + +int ObRpcStartTransferTaskP::process() +{ + int ret = OB_SUCCESS; + ObTransferService *transfer_service = nullptr; + + if (OB_UNLIKELY(arg_.get_tenant_id() != MTL_ID())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObRpcStartTransferTaskP::process tenant not match", KR(ret), K_(arg)); + } else if (OB_UNLIKELY(!arg_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", KR(ret), K_(arg)); + } else if (OB_ISNULL(transfer_service = MTL(ObTransferService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(transfer_service)); + } else { + transfer_service->wakeup(); + } + return ret; +} + int ObRpcGetLSSyncScnP::process() { int ret = OB_SUCCESS; @@ -2345,6 +2375,27 @@ int ObUpdateTenantInfoCacheP::process() return ret; } +int ObRpcFinishTransferTaskP::process() +{ + int ret = OB_SUCCESS; + LOG_INFO("ObRpcFinishTransferTaskP::process", K(MTL_ID()), K_(arg)); + uint64_t tenant_id = arg_.get_tenant_id(); + if (OB_UNLIKELY(tenant_id != MTL_ID())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObRpcFinishTransferTaskP::process tenant not match", KR(ret), K(tenant_id), K_(arg)); + } else { + rootserver::ObTenantTransferService *tenant_transfer = nullptr; + tenant_transfer = MTL(rootserver::ObTenantTransferService*); + if (OB_ISNULL(tenant_transfer)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("mtl ObTenantTransferService should not be null", KR(ret), K_(arg)); + } else { + tenant_transfer->wakeup(); + } + } + return ret; +} + int ObSyncRewriteRulesP::process() { int ret = OB_SUCCESS; @@ -2485,5 +2536,17 @@ int ObBroadcastConsensusVersionP::process() return ret; } +int ObRpcGetLSReplayedScnP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(gctx_.ob_service_)) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "ob_service is null", KR(ret)); + } else if (OB_FAIL(gctx_.ob_service_->get_ls_replayed_scn(arg_, result_))) { + COMMON_LOG(WARN, "failed to get_ls_replayed_scn", KR(ret), K(arg_)); + } + return ret; +} + } // end of namespace observer } // end of namespace oceanbase diff --git a/src/observer/ob_rpc_processor_simple.h b/src/observer/ob_rpc_processor_simple.h index 2b467db6b..65630600e 100644 --- a/src/observer/ob_rpc_processor_simple.h +++ b/src/observer/ob_rpc_processor_simple.h @@ -134,6 +134,7 @@ OB_DEFINE_PROCESSOR_S(Srv, OB_BOOTSTRAP, ObRpcBootstrapP); OB_DEFINE_PROCESSOR_S(Srv, OB_IS_EMPTY_SERVER, ObRpcIsEmptyServerP); OB_DEFINE_PROCESSOR_S(Srv, OB_CHECK_SERVER_FOR_ADDING_SERVER, ObRpcCheckServerForAddingServerP); OB_DEFINE_PROCESSOR_S(Srv, OB_CHECK_DEPLOYMENT_MODE, ObRpcCheckDeploymentModeP); +OB_DEFINE_PROCESSOR_S(Srv, OB_NOTIFY_CREATE_TENANT_USER_LS, ObRpcCreateTenantUserLSP); OB_DEFINE_PROCESSOR_S(Srv, OB_REFRESH_SYNC_VALUE, ObRpcSyncAutoincValueP); OB_DEFINE_PROCESSOR_S(Srv, OB_CLEAR_AUTOINC_CACHE, ObRpcClearAutoincCacheP); OB_DEFINE_PROCESSOR_OBADMIN(Srv, OB_DUMP_MEMTABLE, ObDumpMemtableP); @@ -151,8 +152,9 @@ OB_DEFINE_PROCESSOR_S(Srv, OB_BACKUP_COMPL_LOG, ObRpcBackupLSComplLOGP); OB_DEFINE_PROCESSOR_S(Srv, OB_BACKUP_BUILD_INDEX, ObRpcBackupBuildIndexP); OB_DEFINE_PROCESSOR_S(Srv, OB_DELETE_BACKUP_LS_TASK, ObRpcBackupLSCleanP); OB_DEFINE_PROCESSOR_S(Srv, OB_BACKUP_META, ObRpcBackupMetaP); -OB_DEFINE_PROCESSOR_S(Srv, OB_BACKUP_CHECK_TABLET_CREATE_TS, ObRpcBackupCheckTabletP); OB_DEFINE_PROCESSOR_S(Srv, OB_NOTIFY_CREATE_DUPLICATE_LS, ObRpcCreateDuplicateLSP); +OB_DEFINE_PROCESSOR_S(Srv, OB_DELETE_BACKUP_LS_TASK_RES, ObRpcBackupCleanLSResP); +OB_DEFINE_PROCESSOR_S(Srv, OB_BACKUP_LS_DATA_RES, ObRpcBackupLSDataResP); OB_DEFINE_PROCESSOR_S(Srv, OB_LS_MIGRATE_REPLICA, ObRpcLSMigrateReplicaP); OB_DEFINE_PROCESSOR_S(Srv, OB_LS_ADD_REPLICA, ObRpcLSAddReplicaP); @@ -199,9 +201,7 @@ OB_DEFINE_PROCESSOR_S(Srv, OB_HANDLE_PART_TRANS_CTX, ObHandlePartTransCtxP); OB_DEFINE_PROCESSOR_S(Srv, OB_SERVER_FLUSH_OPT_STAT_MONITORING_INFO, ObFlushLocalOptStatMonitoringInfoP); OB_DEFINE_PROCESSOR_S(Srv, OB_SET_MEMBER_LIST, ObRpcSetMemberListP); OB_DEFINE_PROCESSOR_S(Srv, OB_CREATE_LS, ObRpcCreateLSP); -OB_DEFINE_PROCESSOR_S(Srv, OB_CREATE_TABLET, ObRpcCreateTabletP); OB_DEFINE_PROCESSOR_S(Srv, OB_BATCH_BROADCAST_SCHEMA, ObBatchBroadcastSchemaP); -OB_DEFINE_PROCESSOR_S(Srv, OB_DROP_TABLET, ObRpcDropTabletP); OB_DEFINE_PROCESSOR_S(Srv, OB_REMOTE_WRITE_DDL_REDO_LOG, ObRpcRemoteWriteDDLRedoLogP); OB_DEFINE_PROCESSOR_S(Srv, OB_REMOTE_WRITE_DDL_COMMIT_LOG, ObRpcRemoteWriteDDLCommitLogP); OB_DEFINE_PROCESSOR_S(Srv, OB_CHECK_LS_CAN_OFFLINE, ObRpcCheckLSCanOfflineP); @@ -215,6 +215,9 @@ OB_DEFINE_PROCESSOR_S(Srv, OB_CHANGE_LS_ACCESS_MODE, ObRpcChangeLSAccessModeP); OB_DEFINE_PROCESSOR_S(Srv, OB_GET_LS_SYNC_SCN, ObRpcGetLSSyncScnP); OB_DEFINE_PROCESSOR_S(Srv, OB_LOG_FORCE_SET_LS_AS_SINGLE_REPLICA, ObForceSetLSAsSingleReplicaP); OB_DEFINE_PROCESSOR_S(Srv, OB_ESTIMATE_TABLET_BLOCK_COUNT, ObEstimateTabletBlockCountP); +OB_DEFINE_PROCESSOR_S(Srv, OB_GEN_UNIQUE_ID, ObRpcGenUniqueIDP); +OB_DEFINE_PROCESSOR_S(Srv, OB_START_TRANSFER_TASK, ObRpcStartTransferTaskP); +OB_DEFINE_PROCESSOR_S(Srv, OB_FINISH_TRANSFER_TASK, ObRpcFinishTransferTaskP); OB_DEFINE_PROCESSOR_S(Srv, OB_DDL_CHECK_TABLET_MERGE_STATUS, ObRpcDDLCheckTabletMergeStatusP); OB_DEFINE_PROCESSOR_S(Srv, OB_REFRESH_TENANT_INFO, ObRefreshTenantInfoP); OB_DEFINE_PROCESSOR_S(Srv, OB_SYNC_REWRITE_RULES, ObSyncRewriteRulesP); @@ -223,6 +226,7 @@ OB_DEFINE_PROCESSOR_S(Srv, OB_SEND_HEARTBEAT, ObRpcSendHeartbeatP); OB_DEFINE_PROCESSOR_S(Srv, OB_GET_SERVER_RESOURCE_INFO, ObRpcGetServerResourceInfoP); OB_DEFINE_PROCESSOR_S(Srv, OB_UPDATE_TENANT_INFO_CACHE, ObUpdateTenantInfoCacheP); OB_DEFINE_PROCESSOR_S(Srv, OB_BROADCAST_CONSENSUS_VERSION, ObBroadcastConsensusVersionP); +OB_DEFINE_PROCESSOR_S(Srv, OB_GET_LS_REPLAYED_SCN, ObRpcGetLSReplayedScnP); } // end of namespace observer } // end of namespace oceanbase diff --git a/src/observer/ob_server.cpp b/src/observer/ob_server.cpp index 627cf26e1..8314ec5c5 100644 --- a/src/observer/ob_server.cpp +++ b/src/observer/ob_server.cpp @@ -43,8 +43,6 @@ #include "rpc/obrpc/ob_rpc_handler.h" #include "rpc/obrpc/ob_rpc_proxy.h" #include "share/allocator/ob_tenant_mutil_allocator_mgr.h" -#include "share/backup/ob_backup_file_lock_mgr.h" -#include "share/backup/ob_backup_lease_info_mgr.h" #include "share/cache/ob_cache_name_define.h" #include "share/interrupt/ob_global_interrupt_call.h" #include "share/ob_bg_thread_monitor.h" @@ -77,6 +75,7 @@ #include "storage/tx/ob_ts_mgr.h" #include "storage/tx_table/ob_tx_data_cache.h" #include "storage/ob_file_system_router.h" +#include "storage/ob_tablet_autoinc_seq_rpc_handler.h" #include "common/log/ob_log_constants.h" #include "share/stat/ob_opt_stat_monitor_manager.h" #include "sql/engine/px/ob_px_target_mgr.h" @@ -94,14 +93,18 @@ #include "storage/ob_file_system_router.h" #include "storage/blocksstable/ob_storage_cache_suite.h" #include "storage/tablelock/ob_table_lock_rpc_client.h" +#include "storage/compaction/ob_compaction_diagnose.h" #include "share/ash/ob_active_sess_hist_task.h" #include "share/ash/ob_active_sess_hist_list.h" #include "share/ob_server_blacklist.h" #include "share/ob_primary_standby_service.h" // ObPrimaryStandbyService +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "share/longops_mgr/ob_longops_mgr.h" #include "logservice/palf/election/interface/election.h" #include "storage/ddl/ob_ddl_redo_log_writer.h" #include "observer/ob_server_utils.h" +#include "observer/table_load/ob_table_load_partition_calc.h" +#include "observer/virtual_table/ob_mds_event_buffer.h" #include "share/detect/ob_detect_manager.h" using namespace oceanbase::lib; @@ -267,6 +270,8 @@ int ObServer::init(const ObServerOptions &opts, const ObPLogWriterCfg &log_cfg) if (FAILEDx(ObQueryRetryCtrl::init())) { LOG_ERROR("init retry ctrl failed", KR(ret)); + } else if (OB_FAIL(ObMdsEventBuffer::init())) { + LOG_WARN("init MDS event buffer failed", KR(ret)); } else if (OB_FAIL(ObTableApiProcessorBase::init_session())) { LOG_ERROR("init static session failed", KR(ret)); } else if (OB_FAIL(init_loaddata_global_stat())) { @@ -385,8 +390,6 @@ int ObServer::init(const ObServerOptions &opts, const ObPLogWriterCfg &log_cfg) LOG_ERROR("init refresh network speed task failed", KR(ret)); } else if (OB_FAIL(init_refresh_cpu_frequency())) { LOG_ERROR("init refresh cpu frequency failed", KR(ret)); - } else if (OB_FAIL(init_collect_info_gc_task())) { - LOG_ERROR("init collect info gc task failed", KR(ret)); } else if (OB_FAIL(ObOptStatManager::get_instance().init( &sql_proxy_, &config_))) { LOG_ERROR("init opt stat manager failed", KR(ret)); @@ -407,18 +410,10 @@ int ObServer::init(const ObServerOptions &opts, const ObPLogWriterCfg &log_cfg) LOG_ERROR("init timer monitor failed", KR(ret)); } else if (OB_FAIL(ObBGThreadMonitor::get_instance().init())) { LOG_ERROR("init bg thread monitor failed", KR(ret)); - } else if (OB_FAIL(ObBackupInfoMgr::get_instance().init(sql_proxy_))) { - LOG_ERROR("init ObBackupInfo failed", KR(ret)); } else if (OB_FAIL(ObPxBloomFilterManager::instance().init())) { LOG_ERROR("init px blomm filter manager failed", KR(ret)); } else if (OB_FAIL(PX_P2P_DH.init())) { LOG_ERROR("init px p2p datahub failed", KR(ret)); - } else if (OB_FAIL(ObBackupFileLockMgr::get_instance().init())) { - LOG_ERROR("init backup file lock mgr failed", KR(ret)); - } else if (OB_FAIL(ObDagWarningHistoryManager::get_instance().init())) { - LOG_ERROR("init dag warning history manager failed", KR(ret)); - } else if (OB_FAIL(compaction::ObScheduleSuspectInfoMgr::get_instance().init())) { - LOG_ERROR("init ObScheduleSuspectInfoMgr failed", KR(ret)); } else if (OB_FAIL(compaction::ObCompactionSuggestionMgr::get_instance().init())) { LOG_ERROR("init ObCompactionSuggestionMgr failed", KR(ret)); } else if (OB_FAIL(G_RES_MGR.init())) { @@ -499,14 +494,6 @@ void ObServer::destroy() ObActiveSessHistTask::get_instance().destroy(); FLOG_INFO("active session history task destroyed"); - FLOG_INFO("begin to destroy backup info"); - ObBackupInfoMgr::get_instance().destroy(); - FLOG_INFO("backup info destroyed"); - - FLOG_INFO("begin to destroy backup file lock mgr"); - ObBackupFileLockMgr::get_instance().destroy(); - FLOG_INFO("backup file lock mgr destroyed"); - FLOG_INFO("begin to destroy timer monitor"); ObTimerMonitor::get_instance().destroy(); FLOG_INFO("timer monitor destroyed"); @@ -621,14 +608,6 @@ void ObServer::destroy() OB_TX_DATA_KV_CACHE.destroy(); FLOG_INFO("tx data kv cache destroyed"); - FLOG_INFO("begin to destroy ObDagWarningHistoryManager"); - ObDagWarningHistoryManager::get_instance().destroy(); - FLOG_INFO("ObDagWarningHistoryManager destroyed"); - - FLOG_INFO("begin to destroy ObScheduleSuspectInfoMgr"); - compaction::ObScheduleSuspectInfoMgr::get_instance().destroy(); - FLOG_INFO("ObScheduleSuspectInfoMgr destroyed"); - FLOG_INFO("begin to destroy location service"); location_service_.destroy(); FLOG_INFO("location service destroyed"); @@ -669,6 +648,10 @@ void ObServer::destroy() tenant_srs_mgr_.destroy(); FLOG_INFO("tenant srs manager destroyed"); + FLOG_INFO("begin to destroy ObMdsEventBuffer"); + ObMdsEventBuffer::destroy(); + FLOG_INFO("ObMdsEventBuffer destroyed"); + FLOG_INFO("begin to destroy query retry ctrl"); ObQueryRetryCtrl::destroy(); FLOG_INFO("query retry ctrl destroy"); @@ -768,9 +751,9 @@ int ObServer::start() } if (FAILEDx(multi_tenant_.start())) { - LOG_ERROR("fail to start muti tenant", KR(ret)); + LOG_ERROR("fail to start multi tenant", KR(ret)); } else { - FLOG_INFO("success to start muti tenant"); + FLOG_INFO("success to start multi tenant"); } if (FAILEDx(ObServerCheckpointSlogHandler::get_instance().start())) { @@ -779,6 +762,12 @@ int ObServer::start() FLOG_INFO("success to start server checkpoint slog handler"); } + if (FAILEDx(ObServerCheckpointSlogHandler::enable_replay_clog())) { + LOG_ERROR("fail to enable replay clog", KR(ret)); + } else { + FLOG_INFO("success to enable replay clog"); + } + if (FAILEDx(log_block_mgr_.start(storage_env_.log_disk_size_))) { LOG_ERROR("fail to start log pool", KR(ret)); } else { @@ -839,13 +828,6 @@ int ObServer::start() } else { FLOG_INFO("success to start bg thread monitor"); } - - if (FAILEDx(ObBackupInfoMgr::get_instance().start())) { - LOG_ERROR("fail to start backup info", KR(ret)); - } else { - FLOG_INFO("success to start backup info"); - } - #ifdef ENABLE_IMC if (FAILEDx(imc_tasks_.start())) { LOG_ERROR("fail to start imc tasks", KR(ret)); @@ -1091,10 +1073,6 @@ int ObServer::stop() ObActiveSessHistTask::get_instance().stop(); FLOG_INFO("active session history task stopped"); - FLOG_INFO("begin to stop backup info"); - ObBackupInfoMgr::get_instance().stop(); - FLOG_INFO("backup info stopped"); - FLOG_INFO("begin to stop table store stat mgr"); ObTableStoreStatMgr::get_instance().stop(); FLOG_INFO("table store stat mgr stopped"); @@ -1448,10 +1426,6 @@ int ObServer::wait() root_service_monitor_.wait(); FLOG_INFO("wait root service monitor success"); - FLOG_INFO("begin to wait backup info"); - ObBackupInfoMgr::get_instance().wait(); - FLOG_INFO("wait backup info success"); - //omt FLOG_INFO("begin to wait multi tenant"); multi_tenant_.wait(); @@ -2002,6 +1976,7 @@ int ObServer::init_io() storage_env_.user_row_cache_priority_ = config_.user_row_cache_priority; storage_env_.fuse_row_cache_priority_ = config_.fuse_row_cache_priority; storage_env_.bf_cache_priority_ = config_.bf_cache_priority; + storage_env_.storage_meta_cache_priority_ = config_.storage_meta_cache_priority; storage_env_.bf_cache_miss_count_threshold_ = config_.bf_cache_miss_count_threshold; // policy @@ -2511,7 +2486,8 @@ int ObServer::init_storage() storage_env_.user_row_cache_priority_, storage_env_.fuse_row_cache_priority_, storage_env_.bf_cache_priority_, - storage_env_.bf_cache_miss_count_threshold_))) { + storage_env_.bf_cache_miss_count_threshold_, + storage_env_.storage_meta_cache_priority_))) { LOG_WARN("Fail to init OB_STORE_CACHE, ", KR(ret), K(storage_env_.data_dir_)); } else if (OB_FAIL(ObTmpFileManager::get_instance().init())) { LOG_WARN("fail to init temp file manager", KR(ret)); @@ -2739,7 +2715,8 @@ int ObServer::reload_config() GCONF.user_block_cache_priority, GCONF.user_row_cache_priority, GCONF.fuse_row_cache_priority, - GCONF.bf_cache_priority))) { + GCONF.bf_cache_priority, + GCONF.storage_meta_cache_priority))) { LOG_WARN("set cache priority fail, ", KR(ret)); } else if (OB_FAIL(reload_bandwidth_throttle_limit(ethernet_speed_))) { LOG_WARN("failed to reload_bandwidth_throttle_limit", KR(ret)); @@ -3138,17 +3115,6 @@ int ObServer::refresh_cpu_frequency() return ret; } -void ObServer::ObCollectInfoGCTask::runTimerTask() -{ - int ret = OB_SUCCESS; - int64_t cost_ts = ObTimeUtility::fast_current_time(); - if (OB_FAIL(compaction::ObScheduleSuspectInfoMgr::get_instance().gc_info())) { - LOG_WARN("Fail to gc collect info", K(ret)); - } - cost_ts = ObTimeUtility::fast_current_time() - cost_ts; - LOG_INFO("ObCollectInfoGCTask", K(cost_ts)); -} - int ObServer::refresh_network_speed() { int ret = OB_SUCCESS; @@ -3227,15 +3193,6 @@ int ObServer::init_refresh_cpu_frequency() return ret; } -int ObServer::init_collect_info_gc_task() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::ServerGTimer, collect_info_gc_task_, ObCollectInfoGCTask::COLLECT_INFO_GC_INTERVAL, true /*schedule repeatly*/))) { - LOG_ERROR("fail to schedule task ObCollectInfoGCTask", KR(ret)); - } - return ret; -} - // @@Query cleanup rules for built tables and temporary tables: //1, Traverse all table_schema, if the session_id of table T <> 0 means that the table is being created or the previous creation failed or the temporary table is to be cleared, then enter 2#; //2, Create a table for the query: traverse the session, and determine whether T should be DROP according to the session_id and time of the session and table T; diff --git a/src/observer/ob_server.h b/src/observer/ob_server.h index 87205d984..793ea1b85 100644 --- a/src/observer/ob_server.h +++ b/src/observer/ob_server.h @@ -176,15 +176,6 @@ public: bool is_inited_; }; - class ObCollectInfoGCTask : public common::ObTimerTask - { - public: - ObCollectInfoGCTask() = default; - virtual ~ObCollectInfoGCTask() = default; - virtual void runTimerTask() override; - static const int64_t COLLECT_INFO_GC_INTERVAL = 6L * 60 * 60 * 1000 * 1000L; // 6hr - }; - class ObRefreshTime { public: explicit ObRefreshTime(ObServer *obs): obs_(obs){} @@ -298,7 +289,6 @@ private: int init_refresh_active_time_task(); //Regularly update the sess_active_time of the temporary table created by the proxy connection sess int init_refresh_network_speed_task(); int init_refresh_cpu_frequency(); - int init_collect_info_gc_task(); int set_running_mode(); int check_server_can_start_service(); int try_create_hidden_sys(); @@ -441,7 +431,6 @@ private: ObRefreshTimeTask refresh_active_time_task_; // repeat & no retry ObRefreshNetworkSpeedTask refresh_network_speed_task_; // repeat & no retry ObRefreshCpuFreqTimeTask refresh_cpu_frequency_task_; - ObCollectInfoGCTask collect_info_gc_task_; blocksstable::ObStorageEnv storage_env_; share::ObSchemaStatusProxy schema_status_proxy_; diff --git a/src/observer/ob_service.cpp b/src/observer/ob_service.cpp index 5a62fdddc..bbeea06b5 100644 --- a/src/observer/ob_service.cpp +++ b/src/observer/ob_service.cpp @@ -67,12 +67,17 @@ #include "storage/backup/ob_backup_handler.h" #include "storage/backup/ob_ls_backup_clean_mgr.h" #include "storage/ob_file_system_router.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" #include "share/backup/ob_backup_path.h" #include "share/backup/ob_backup_connectivity.h" +#include "storage/backup/ob_backup_utils.h" #include "observer/report/ob_tenant_meta_checker.h"//ObTenantMetaChecker +#include "rootserver/backup/ob_backup_task_scheduler.h" // ObBackupTaskScheduler +#include "rootserver/backup/ob_backup_schedule_task.h" // ObBackupScheduleTask #include "storage/compaction/ob_tenant_tablet_scheduler.h" #include "share/ob_cluster_event_history_table_operator.h"//CLUSTER_EVENT_INSTANCE #include "storage/ddl/ob_tablet_ddl_kv_mgr.h" +#include "share/backup/ob_backup_struct.h" #include "observer/ob_heartbeat_handler.h" #include "storage/slog/ob_storage_logger_manager.h" @@ -826,92 +831,6 @@ int ObService::backup_meta(const obrpc::ObBackupMetaArg &arg) return ret; } -// At backup meta stage, observer will backup tablet id list -// And RS will compare the observer's tablet id list with the newest tablet id list -// and will get the diff tablet id list, for each tablet not in observer's -// backed up list, it will compare using observer's backup scn and tx data's tx log ts -int ObService::check_not_backup_tablet_create_scn(const obrpc::ObBackupCheckTabletArg &arg) -{ - int ret = OB_SUCCESS; - LOG_INFO("success received backup check tablet from rs", K(arg)); - if (!arg.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(arg)); - } else { - MTL_SWITCH(arg.tenant_id_) { - ObLSService *ls_srv = nullptr; - ObLSHandle ls_handle; - ObLS *ls = nullptr; - ObLSTabletService *ls_tablet_svr = nullptr; - const ObSArray &tablet_ids = arg.tablet_ids_; - if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls service is nullptr", KR(ret)); - } else if (OB_FAIL(ls_srv->get_ls(arg.ls_id_, ls_handle, ObLSGetMod::OBSERVER_MOD))) { - LOG_WARN("fail to get log stream", KR(ret), K(arg.tenant_id_), K(arg.ls_id_)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("log stream should not be NULL", KR(ret), K(arg.tenant_id_), K(arg.ls_id_), KPC(ls)); - } else { - const int64_t rebuild_seq = ls->get_rebuild_seq(); - ObMigrationStatus migration_status; - share::ObLSRestoreStatus restore_status; - if (OB_FAIL(ls->is_offline())) { - ret = OB_EAGAIN; - LOG_WARN("ls is offline, retry later", K(ret), KPC(ls)); - } else if (OB_FAIL(ls->get_migration_status(migration_status))) { - LOG_WARN("failed to get migration status", K(ret), KPC(ls)); - } else if (storage::ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status) { - ret = OB_EAGAIN; - LOG_WARN("ls is in migration, retry later", K(ret), KPC(ls)); - } else if (OB_FAIL(ls->get_restore_status(restore_status))) { - LOG_WARN("failed to get restore status", K(ret), KPC(ls)); - } else if (share::ObLSRestoreStatus::RESTORE_NONE != restore_status) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("restore ls is unexpected", K(ret), KPC(ls)); - } else { - if (OB_ISNULL(ls_tablet_svr = ls->get_tablet_svr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls tablet service should not be NULL", KR(ret), K(arg.tenant_id_), K(arg.ls_id_), KPC(ls)); - } else { - const int64_t timeout_us = ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US; - ObTabletHandle tablet_handle; - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { - const ObTabletID &tablet_id = tablet_ids.at(i); - tablet_handle.reset(); - if (OB_FAIL(ls_tablet_svr->get_tablet(tablet_id, tablet_handle, timeout_us))) { - if (OB_TABLET_NOT_EXIST == ret) { - LOG_INFO("tablet has been deleted, no need to check", K(tablet_id)); - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", KR(ret), K(tablet_id), K(timeout_us)); - } - } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error : tablet handle is invalid", KR(ret), K(tablet_handle)); - } else { - const ObTabletMeta &tablet_meta = tablet_handle.get_obj()->get_tablet_meta(); - if (OB_UNLIKELY(tablet_meta.create_scn_ <= arg.backup_scn_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error : tablet has't been backup", KR(ret), - K(arg.tenant_id_), K(arg.ls_id_), K(tablet_id), - K(tablet_meta), "backup_scn", arg.backup_scn_); - } - } - } - } - } - if (OB_FAIL(ret)) { - } else if (rebuild_seq != ls->get_rebuild_seq()) { - ret = OB_EAGAIN; - LOG_WARN("ls has rebuild, retry later", K(ret), KPC(ls)); - } - } - } - } - return ret; -} - int ObService::check_backup_task_exist(const ObBackupCheckTaskArg &arg, bool &res) { int ret = OB_SUCCESS; @@ -952,7 +871,6 @@ int ObService::delete_backup_ls_task(const obrpc::ObLSBackupCleanArg &arg) return ret; } - int ObService::check_sys_task_exist( const share::ObTaskId &arg, bool &res) { @@ -1079,14 +997,18 @@ int ObService::ls_freeze_(const uint64_t tenant_id, const share::ObLSID &ls_id, } else if (tablet_id.is_valid()) { // tablet freeze if (OB_FAIL(freezer->tablet_freeze(ls_id, tablet_id))) { - LOG_WARN("fail to freeze tablet", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); + if (OB_EAGAIN == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to freeze tablet", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); + } } else { LOG_INFO("succeed to freeze tablet", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); } } else { // logstream freeze if (OB_FAIL(freezer->ls_freeze(ls_id))) { - if (OB_ENTRY_EXIST == ret) { + if (OB_EAGAIN == ret) { ret = OB_SUCCESS; } else { LOG_WARN("fail to freeze ls", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); @@ -1273,11 +1195,16 @@ int ObService::check_ddl_tablet_merge_status( } // check and update major status if (OB_SUCC(ret)) { - ObSSTable *latest_major_sstable = static_cast( - tablet_handle.get_obj()->get_table_store().get_major_sstables().get_boundary_table(true/*last*/)); - status = nullptr != latest_major_sstable; - if (OB_FAIL(result.merge_status_.push_back(status))) { - LOG_WARN("fail to push back to array", K(ret), K(status), K(tablet_id)); + ObTabletMemberWrapper table_store_wrapper; + if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else { + ObSSTable *latest_major_sstable = static_cast( + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/)); + status = nullptr != latest_major_sstable; + if (OB_FAIL(result.merge_status_.push_back(status))) { + LOG_WARN("fail to push back to array", K(ret), K(status), K(tablet_id)); + } } } } @@ -2327,7 +2254,8 @@ int ObService::inner_fill_tablet_info_( } else if (OB_FAIL(ls->get_tablet_svr()->get_tablet( tablet_id, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { if (OB_TABLET_NOT_EXIST != ret) { LOG_WARN("get tablet failed", KR(ret), K(tenant_id), K(tablet_id)); } @@ -2475,6 +2403,7 @@ int ObService::fill_ls_replica( ObReplicaStatus replica_status = REPLICA_STATUS_NORMAL; ObReplicaType replica_type = REPLICA_TYPE_FULL; bool is_compatible_with_readonly_replica = false; + ObMigrationStatus migration_status = OB_MIGRATION_STATUS_MAX; if (OB_ISNULL(ls_svr = MTL(ObLSService*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("MTL ObLSService is null", KR(ret), K(tenant_id)); @@ -2486,6 +2415,8 @@ int ObService::fill_ls_replica( LOG_WARN("get member list and learner list from ObLS failed", KR(ret)); } else if (OB_FAIL(ls_handle.get_ls()->get_restore_status(restore_status))) { LOG_WARN("get restore status failed", KR(ret)); + } else if (OB_FAIL(ls_handle.get_ls()->get_migration_status(migration_status))) { + LOG_WARN("get migration status failed", KR(ret)); } else if (OB_FAIL(ls_handle.get_ls()->get_replica_status(replica_status))) { LOG_WARN("get replica status failed", KR(ret)); } else if (OB_ISNULL(log_service = MTL(logservice::ObLogService*))) { @@ -2527,9 +2458,10 @@ int ObService::fill_ls_replica( gctx_.config_->zone.str(), /*zone*/ paxos_replica_number, /*paxos_replica_number*/ 0, /*data_size*/ - 0, + 0, /*required_size*/ member_list, - learner_list))) { /*required_size*/ + learner_list, + OB_MIGRATION_STATUS_REBUILD == migration_status /*is_rebuild*/))) { LOG_WARN("fail to init a ls replica", KR(ret), K(tenant_id), K(ls_id), K(role), K(proposal_id), K(unit_id), K(paxos_replica_number), K(member_list), K(learner_list)); } else { @@ -2540,6 +2472,64 @@ int ObService::fill_ls_replica( return ret; } +int ObService::report_backup_over(const obrpc::ObBackupTaskRes &res) +{ + int ret = OB_SUCCESS; + ObBackupDataLSTask task; + ObBackupTaskScheduler *task_scheduler = nullptr; + FLOG_INFO("receive backup over", K(res)); + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + ObHAResultInfo result_info(ObHAResultInfo::BACKUP_DATA, + res.ls_id_, + res.src_server_, + res.dag_id_, + res.result_); + MTL_SWITCH(gen_meta_tenant_id(res.tenant_id_)) { + if (nullptr == (task_scheduler = MTL(ObBackupTaskScheduler *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup task scheduler can't be nullptr", K(ret)); + } else if (OB_FAIL(task.build_from_res(res, BackupJobType::BACKUP_DATA_JOB))) { + LOG_WARN("failed to build task from res rpc", K(ret), K(res)); + } else if (OB_FAIL(task_scheduler->execute_over(task, result_info))) { + LOG_WARN("failed to remove task from scheduler", K(ret), K(res), K(task)); + } + } + } + return ret; +} + +int ObService::report_backup_clean_over(const obrpc::ObBackupTaskRes &res) +{ + int ret = OB_SUCCESS; + ObBackupCleanLSTask task; + ObBackupTaskScheduler *task_scheduler = nullptr; + FLOG_INFO("report backup clean over", K(res)); + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + ObHAResultInfo result_info(ObHAResultInfo::BACKUP_CLEAN, + res.ls_id_, + res.src_server_, + res.dag_id_, + res.result_); + MTL_SWITCH(gen_meta_tenant_id(res.tenant_id_)) { + if (nullptr == (task_scheduler = MTL(ObBackupTaskScheduler *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup task scheduler can't be nullptr", K(ret)); + } else if (OB_FAIL(task.build_from_res(res, BackupJobType::BACKUP_CLEAN_JOB))) { + LOG_WARN("failed to build task from res rpc", K(ret), K(res)); + } else if (OB_FAIL(task_scheduler->execute_over(task, result_info))) { + LOG_WARN("failed to remove task from scheduler", K(ret), K(res), K(task)); + } + } + } + return ret; +} + int ObService::get_leader_locations( const obrpc::ObGetLeaderLocationsArg &arg, obrpc::ObGetLeaderLocationsResult &result) @@ -2852,6 +2842,48 @@ int ObService::init_tenant_config( return OB_SUCCESS; } +int ObService::get_ls_replayed_scn( + const ObGetLSReplayedScnArg &arg, + ObGetLSReplayedScnRes &result) +{ + LOG_INFO("start get_ls_replayed_scn", K(arg)); + int ret = OB_SUCCESS; + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + share::SCN cur_readable_scn = SCN::min_scn(); + + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (!arg.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("arg is invaild", KR(ret), K(arg)); + } else if (arg.get_tenant_id() != MTL_ID() && OB_FAIL(guard.switch_to(arg.get_tenant_id()))) { + LOG_WARN("switch tenant failed", KR(ret), K(arg)); + } + + if (OB_SUCC(ret)) { + ObLSService *ls_svr = MTL(ObLSService*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + if (OB_ISNULL(ls_svr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("pointer is null", KR(ret), KP(ls_svr)); + } else if (OB_FAIL(ls_svr->get_ls(arg.get_ls_id(), ls_handle, ObLSGetMod::RS_MOD))) { + LOG_WARN("get log stream failed", KR(ret), K(arg)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream is null", KR(ret), K(arg), K(ls_handle)); + } else if (OB_FAIL(ls->get_max_decided_scn(cur_readable_scn))) { + LOG_WARN("failed to get_max_decided_scn", KR(ret), K(arg), KPC(ls)); + } else if (OB_FAIL(result.init(arg.get_tenant_id(), arg.get_ls_id(), cur_readable_scn))) { + LOG_WARN("failed to init res", KR(ret), K(arg), K(cur_readable_scn)); + } else { + LOG_INFO("finish get_ls_replayed_scn", KR(ret), K(cur_readable_scn), K(arg), K(result)); + } + } + return ret; +} + int ObService::handle_heartbeat( const share::ObHBRequest &hb_request, share::ObHBResponse &hb_response) @@ -2869,6 +2901,7 @@ int ObService::handle_heartbeat( FLOG_INFO("handle_heartbeat", KR(ret), K(hb_request), K(hb_response), K(time_cost)); return ret; } + int ObService::update_tenant_info_cache( const ObUpdateTenantInfoCacheArg &arg, ObUpdateTenantInfoCacheRes &result) diff --git a/src/observer/ob_service.h b/src/observer/ob_service.h index 7f87de4c3..3a28c5cad 100644 --- a/src/observer/ob_service.h +++ b/src/observer/ob_service.h @@ -142,16 +142,20 @@ public: int backup_build_index(const obrpc::ObBackupBuildIdxArg &arg); int check_backup_dest_connectivity(const obrpc::ObCheckBackupConnectivityArg &arg); int backup_meta(const obrpc::ObBackupMetaArg &arg); - int check_not_backup_tablet_create_scn(const obrpc::ObBackupCheckTabletArg &arg); int check_backup_task_exist(const obrpc::ObBackupCheckTaskArg &arg, bool &res); int check_sys_task_exist(const share::ObTaskId &arg, bool &res); int check_migrate_task_exist(const share::ObTaskId &arg, bool &res); int delete_backup_ls_task(const obrpc::ObLSBackupCleanArg &arg); + int report_backup_over(const obrpc::ObBackupTaskRes &res); + int report_backup_clean_over(const obrpc::ObBackupTaskRes &res); + int get_ls_sync_scn(const obrpc::ObGetLSSyncScnArg &arg, obrpc::ObGetLSSyncScnRes &result); int force_set_ls_as_single_replica(const obrpc::ObForceSetLSAsSingleReplicaArg &arg); int refresh_tenant_info(const obrpc::ObRefreshTenantInfoArg &arg, obrpc::ObRefreshTenantInfoRes &result); + int get_ls_replayed_scn(const obrpc::ObGetLSReplayedScnArg &arg, + obrpc::ObGetLSReplayedScnRes &result); int estimate_partition_rows(const obrpc::ObEstPartArg &arg, obrpc::ObEstPartRes &res) const; int estimate_tablet_block_count(const obrpc::ObEstBlockArg &arg, diff --git a/src/observer/ob_srv_xlator_partition.cpp b/src/observer/ob_srv_xlator_partition.cpp index 84ef4c730..8c84ab5fc 100644 --- a/src/observer/ob_srv_xlator_partition.cpp +++ b/src/observer/ob_srv_xlator_partition.cpp @@ -104,8 +104,6 @@ void oceanbase::observer::init_srv_xlator_for_partition(ObSrvRpcXlator *xlator) RPC_PROCESSOR(ObHandlePartTransCtxP, gctx_); RPC_PROCESSOR(ObRpcSetMemberListP, gctx_); RPC_PROCESSOR(ObRpcCreateLSP, gctx_); - RPC_PROCESSOR(ObRpcCreateTabletP, gctx_); - RPC_PROCESSOR(ObRpcDropTabletP, gctx_); RPC_PROCESSOR(ObRpcCheckLSCanOfflineP, gctx_); RPC_PROCESSOR(ObCleanSequenceCacheP, gctx_); RPC_PROCESSOR(ObRegisterTxDataP, gctx_); @@ -141,11 +139,26 @@ void oceanbase::observer::init_srv_xlator_for_migration(ObSrvRpcXlator *xlator) RPC_PROCESSOR(ObFetchLSMetaInfoP); RPC_PROCESSOR(ObFetchLSMemberListP); RPC_PROCESSOR(ObFetchSSTableMacroInfoP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObStorageFetchLSViewP, gctx_.bandwidth_throttle_); // restore RPC_PROCESSOR(ObNotifyRestoreTabletsP, gctx_.bandwidth_throttle_); RPC_PROCESSOR(ObInquireRestoreP, gctx_.bandwidth_throttle_); RPC_PROCESSOR(ObUpdateLSMetaP, gctx_.bandwidth_throttle_); + + //transfer + RPC_PROCESSOR(ObCheckStartTransferTabletsP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObGetLSActiveTransCountP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObGetTransferStartScnP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObFetchTransferTabletsInfoP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObFetchLSReplayScnP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObCheckTransferTabletsBackfillP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObStorageReplaceMemberP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObStorageAddMemberP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObStorageSwitchLearnerToAcceptorP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObStorageBlockTxP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObStorageKillTxP, gctx_.bandwidth_throttle_); + RPC_PROCESSOR(ObStorageUnBlockTxP, gctx_.bandwidth_throttle_); } void oceanbase::observer::init_srv_xlator_for_others(ObSrvRpcXlator *xlator) { @@ -280,6 +293,7 @@ void oceanbase::observer::init_srv_xlator_for_others(ObSrvRpcXlator *xlator) { //standby switchover/failover RPC_PROCESSOR(ObRpcGetLSSyncScnP, gctx_); RPC_PROCESSOR(ObRefreshTenantInfoP, gctx_); + RPC_PROCESSOR(ObRpcGetLSReplayedScnP, gctx_); RPC_PROCESSOR(ObUpdateTenantInfoCacheP, gctx_); RPC_PROCESSOR(ObSyncRewriteRulesP, gctx_); diff --git a/src/observer/ob_srv_xlator_rootserver.cpp b/src/observer/ob_srv_xlator_rootserver.cpp index 5eb1af9c7..9e1409a77 100644 --- a/src/observer/ob_srv_xlator_rootserver.cpp +++ b/src/observer/ob_srv_xlator_rootserver.cpp @@ -225,10 +225,6 @@ void oceanbase::observer::init_srv_xlator_for_rootserver(ObSrvRpcXlator *xlator) RPC_PROCESSOR(rootserver::ObRpcAdminFlushBalanceInfoP, *gctx_.root_service_); RPC_PROCESSOR(rootserver::ObGetTenantSchemaVersionsP, *gctx_.root_service_); - // backup and restore - RPC_PROCESSOR(rootserver::ObRpcBackupDataResP, *gctx_.root_service_); - RPC_PROCESSOR(rootserver::ObRpcBackupLSCleanResP, *gctx_.root_service_); - RPC_PROCESSOR(rootserver::ObRpcBackupComplLogResP, *gctx_.root_service_); //update optimizer statistic RPC_PROCESSOR(rootserver::ObRpcUpdateStatCacheP, *gctx_.root_service_); diff --git a/src/observer/ob_srv_xlator_storage.cpp b/src/observer/ob_srv_xlator_storage.cpp index f39b821fe..faaa2569e 100644 --- a/src/observer/ob_srv_xlator_storage.cpp +++ b/src/observer/ob_srv_xlator_storage.cpp @@ -86,7 +86,8 @@ void oceanbase::observer::init_srv_xlator_for_storage(ObSrvRpcXlator *xlator) { RPC_PROCESSOR(ObRpcBackupBuildIndexP, gctx_); RPC_PROCESSOR(ObRpcBackupLSCleanP, gctx_); RPC_PROCESSOR(ObRpcBackupMetaP, gctx_); - RPC_PROCESSOR(ObRpcBackupCheckTabletP, gctx_); + RPC_PROCESSOR(ObRpcBackupLSDataResP, gctx_); + RPC_PROCESSOR(ObRpcBackupCleanLSResP, gctx_); RPC_PROCESSOR(ObRpcCheckBackupTaskExistP, gctx_); RPC_PROCESSOR(ObRenewInZoneHbP, gctx_); @@ -105,6 +106,10 @@ void oceanbase::observer::init_srv_xlator_for_storage(ObSrvRpcXlator *xlator) { RPC_PROCESSOR(ObRpcLSRemoveNonPaxosReplicaP, gctx_); RPC_PROCESSOR(ObRpcLSModifyPaxosReplicaNumberP, gctx_); RPC_PROCESSOR(ObRpcLSCheckDRTaskExistP, gctx_); + RPC_PROCESSOR(ObRpcCreateTenantUserLSP, gctx_); + RPC_PROCESSOR(ObRpcGenUniqueIDP, gctx_); + RPC_PROCESSOR(ObRpcStartTransferTaskP, gctx_); + RPC_PROCESSOR(ObRpcFinishTransferTaskP, gctx_); RPC_PROCESSOR(ObRpcDDLCheckTabletMergeStatusP, gctx_); RPC_PROCESSOR(ObRpcCreateDuplicateLSP, gctx_); } diff --git a/src/observer/omt/ob_multi_tenant.cpp b/src/observer/omt/ob_multi_tenant.cpp index 9c2623a2f..ab06eae7c 100644 --- a/src/observer/omt/ob_multi_tenant.cpp +++ b/src/observer/omt/ob_multi_tenant.cpp @@ -51,6 +51,7 @@ #include "logservice/archiveservice/ob_archive_service.h" // ObArchiveService #include "logservice/data_dictionary/ob_data_dict_service.h" // ObDataDictService #include "ob_tenant_mtl_helper.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" #include "storage/tx_storage/ob_ls_service.h" #include "storage/tx_storage/ob_access_service.h" #include "storage/tx_storage/ob_tenant_freezer.h" @@ -62,6 +63,7 @@ #include "storage/tx/ob_timestamp_access.h" #include "storage/tx/ob_trans_id_service.h" #include "storage/tx/ob_trans_service.h" +#include "storage/tx/ob_unique_id_service.h" #include "storage/tx/ob_trans_part_ctx.h" #include "storage/compaction/ob_tenant_tablet_scheduler.h" #include "storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h" @@ -80,19 +82,29 @@ #include "storage/tablelock/ob_table_lock_service.h" #include "storage/ob_file_system_router.h" #include "storage/compaction/ob_sstable_merge_info_mgr.h" // ObTenantSSTableMergeInfoMgr +#include "share/scheduler/ob_dag_warning_history_mgr.h" +#include "storage/compaction/ob_compaction_diagnose.h" #include "storage/access/ob_table_scan_iterator.h" #include "share/io/ob_io_manager.h" #include "rootserver/freeze/ob_major_freeze_service.h" #include "observer/omt/ob_tenant_config_mgr.h" #include "observer/report/ob_tenant_meta_checker.h" #include "storage/high_availability/ob_storage_ha_service.h" -#include "rootserver/ob_tenant_recovery_reportor.h"//ObTenantRecoveryReportor +#include "rootserver/ob_tenant_info_loader.h"//ObTenantInfoLoader +#include "rootserver/ob_tenant_balance_service.h"//ObTenantBalanceService +#include "rootserver/ob_ls_recovery_reportor.h"//ObLSRecoveryReportor #include "rootserver/ob_standby_schema_refresh_trigger.h"//ObStandbySchemaRefreshTrigger #include "rootserver/ob_tenant_info_loader.h"//ObTenantInfoLoader #include "rootserver/ob_create_standby_from_net_actor.h" // ObCreateStandbyFromNetActor #include "rootserver/ob_primary_ls_service.h"//ObLSService #include "rootserver/ob_recovery_ls_service.h"//ObRecoveryLSService +#include "rootserver/ob_common_ls_service.h"//ObCommonLSService #include "rootserver/restore/ob_restore_scheduler.h" //ObRestoreService +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "rootserver/ob_balance_task_execute_service.h" //ObBalanceTaskExecuteService +#include "rootserver/backup/ob_backup_service.h" //ObBackupDataService and ObBackupCleanService +#include "rootserver/backup/ob_backup_task_scheduler.h" // ObBackupTaskScheduler +#include "rootserver/backup/ob_archive_scheduler_service.h" // ObArchiveSchedulerService #include "logservice/leader_coordinator/ob_leader_coordinator.h" #include "storage/lob/ob_lob_manager.h" #include "share/deadlock/ob_deadlock_detector_mgr.h" @@ -101,9 +113,12 @@ #include "storage/blocksstable/ob_shared_macro_block_manager.h" #include "storage/tx_storage/ob_tablet_gc_service.h" #include "share/ob_occam_time_guard.h" +#include "storage/high_availability/ob_transfer_service.h" +#include "storage/high_availability/ob_rebuild_service.h" #include "observer/table_load/ob_table_load_service.h" #include "sql/plan_cache/ob_plan_cache.h" #include "sql/plan_cache/ob_ps_cache.h" +#include "rootserver/ob_rs_event_history_table_operator.h" #include "rootserver/ob_heartbeat_service.h" #include "share/detect/ob_detect_manager.h" @@ -387,6 +402,7 @@ int ObMultiTenant::init(ObAddr myaddr, MTL_BIND(ObTenantIOManager::mtl_init, ObTenantIOManager::mtl_destroy); // base mtl + MTL_BIND2(mtl_new_default, storage::mds::ObTenantMdsService::mtl_init, storage::mds::ObTenantMdsService::mtl_start, storage::mds::ObTenantMdsService::mtl_stop, storage::mds::ObTenantMdsService::mtl_wait, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObStorageLogger::mtl_init, ObStorageLogger::mtl_start, ObStorageLogger::mtl_stop, ObStorageLogger::mtl_wait, mtl_destroy_default); MTL_BIND2(ObTenantMetaMemMgr::mtl_new, mtl_init_default, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObTransService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); @@ -405,23 +421,32 @@ int ObMultiTenant::init(ObAddr myaddr, MTL_BIND2(mtl_new_default, compaction::ObServerCompactionEventHistory::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, storage::ObTenantTabletStatMgr::mtl_init, nullptr, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, storage::ObTenantSSTableMergeInfoMgr::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); + MTL_BIND2(mtl_new_default, share::ObDagWarningHistoryManager::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); + MTL_BIND2(mtl_new_default, compaction::ObScheduleSuspectInfoMgr::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, memtable::ObLockWaitMgr::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, logservice::ObGarbageCollector::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObTableLockService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, rootserver::ObPrimaryMajorFreezeService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, rootserver::ObRestoreMajorFreezeService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObTenantMetaChecker::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); - MTL_BIND2(mtl_new_default, rootserver::ObTenantRecoveryReportor::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObLSRecoveryReportor::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, rootserver::ObStandbySchemaRefreshTrigger::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, rootserver::ObTenantInfoLoader::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, rootserver::ObCreateStandbyFromNetActor::mtl_init, nullptr, rootserver::ObCreateStandbyFromNetActor::mtl_stop, rootserver::ObCreateStandbyFromNetActor::mtl_wait, mtl_destroy_default); MTL_BIND2(mtl_new_default, rootserver::ObPrimaryLSService::mtl_init, nullptr, rootserver::ObPrimaryLSService::mtl_stop, rootserver::ObPrimaryLSService::mtl_wait, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObCommonLSService::mtl_init, nullptr, rootserver::ObCommonLSService::mtl_stop, rootserver::ObCommonLSService::mtl_wait, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObBalanceTaskExecuteService::mtl_init, nullptr, rootserver::ObBalanceTaskExecuteService::mtl_stop, rootserver::ObBalanceTaskExecuteService::mtl_wait, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObTenantBalanceService::mtl_init, nullptr, rootserver::ObTenantBalanceService::mtl_stop, rootserver::ObTenantBalanceService::mtl_wait, mtl_destroy_default); MTL_BIND2(mtl_new_default, rootserver::ObRecoveryLSService::mtl_init, nullptr, rootserver::ObRecoveryLSService::mtl_stop, rootserver::ObRecoveryLSService::mtl_wait, mtl_destroy_default); MTL_BIND2(mtl_new_default, rootserver::ObRestoreService::mtl_init, nullptr, rootserver::ObRestoreService::mtl_stop, rootserver::ObRestoreService::mtl_wait, mtl_destroy_default); MTL_BIND2(mtl_new_default, coordinator::ObLeaderCoordinator::mtl_init, coordinator::ObLeaderCoordinator::mtl_start, coordinator::ObLeaderCoordinator::mtl_stop, coordinator::ObLeaderCoordinator::mtl_wait, mtl_destroy_default); MTL_BIND2(mtl_new_default, coordinator::ObFailureDetector::mtl_init, coordinator::ObFailureDetector::mtl_start, coordinator::ObFailureDetector::mtl_stop, coordinator::ObFailureDetector::mtl_wait, mtl_destroy_default); MTL_BIND2(ObLobManager::mtl_new, mtl_init_default, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObStorageHAService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObBackupTaskScheduler::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObBackupDataService::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObBackupCleanService::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObArchiveSchedulerService::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObGlobalAutoIncService::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, share::detector::ObDeadLockDetectorMgr::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObTenantSchemaService::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); @@ -429,6 +454,7 @@ int ObMultiTenant::init(ObAddr myaddr, MTL_BIND2(mtl_new_default, ObStandbyTimestampService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObTimestampAccess::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObTransIDService::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); + MTL_BIND2(mtl_new_default, ObUniqueIDService::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObXAService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObTabletGCService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObTenantFreezer::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); @@ -436,6 +462,9 @@ int ObMultiTenant::init(ObAddr myaddr, MTL_BIND2(mtl_new_default, ObDASIDService::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObAccessService::mtl_init, nullptr, mtl_stop_default, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObCheckPointService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); + MTL_BIND2(mtl_new_default, ObTransferService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObTenantTransferService::mtl_init, nullptr, rootserver::ObTenantTransferService::mtl_stop, rootserver::ObTenantTransferService::mtl_wait, mtl_destroy_default); + MTL_BIND2(mtl_new_default, ObRebuildService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObMultiVersionGarbageCollector::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObUDRMgr::mtl_init, nullptr, ObUDRMgr::mtl_stop, nullptr, mtl_destroy_default); @@ -1444,6 +1473,7 @@ int ObMultiTenant::remove_tenant(const uint64_t tenant_id, bool &remove_tenant_s if (OB_TENANT_NOT_IN_SERVER == ret) { LOG_WARN("tenant has been removed", K(tenant_id), K(ret)); removed_tenant = nullptr; + remove_tenant_succ = true; ret = OB_SUCCESS; } else { LOG_WARN("remove tenant failed", K(tenant_id), K(ret)); @@ -1573,6 +1603,15 @@ int ObMultiTenant::remove_tenant(const uint64_t tenant_id, bool &remove_tenant_s LOG_WARN("failed to erase_tenant_interm_result_info", K(ret), K(tenant_id)); } } + ROOTSERVICE_EVENT_ADD("remove_tenant", "remove_tenant", + "tenant_id", tenant_id, + "addr", GCTX.self_addr(), + "result", ret); + if (OB_SUCC(ret) && OB_NOT_NULL(GCTX.dblink_proxy_)) { + if (OB_FAIL(GCTX.dblink_proxy_->clean_dblink_connection(tenant_id))) { + LOG_WARN("failed to clean dblink connection", K(ret), K(tenant_id)); + } + } return ret; } diff --git a/src/observer/omt/ob_tenant.h b/src/observer/omt/ob_tenant.h index b0bfab521..cbb59e8c9 100644 --- a/src/observer/omt/ob_tenant.h +++ b/src/observer/omt/ob_tenant.h @@ -454,7 +454,8 @@ public: K_(recv_level_rpc_cnt), K_(group_map), K_(rpc_stat_info), - K_(token_change_ts)) + K_(token_change_ts), + "tenant_role", get_tenant_role()) public: static bool equal(const ObTenant *t1, const ObTenant *t2) { diff --git a/src/observer/omt/ob_tenant_mtl_helper.h b/src/observer/omt/ob_tenant_mtl_helper.h index fe7bd822b..bb1f83e62 100644 --- a/src/observer/omt/ob_tenant_mtl_helper.h +++ b/src/observer/omt/ob_tenant_mtl_helper.h @@ -104,4 +104,18 @@ typename std::enable_if::value>::type mtl_destroy_default(T { m.destroy(); } + +template +typename std::enable_if::value, bool>::type get_mtl_ptr(T &m, void *&ptr) +{ + ptr = reinterpret_cast(m); + return true; +} +template +typename std::enable_if::value, bool>::type get_mtl_ptr(T &m, void *&ptr) +{ + ptr = reinterpret_cast(&m); + return false; +} + #endif diff --git a/src/observer/report/ob_tenant_meta_checker.cpp b/src/observer/report/ob_tenant_meta_checker.cpp index acb8b9e09..b07f9bb9e 100644 --- a/src/observer/report/ob_tenant_meta_checker.cpp +++ b/src/observer/report/ob_tenant_meta_checker.cpp @@ -626,7 +626,7 @@ int ObTenantMetaChecker::check_report_replicas_( LOG_WARN("failed to get ls iter", KR(ret)); } else { ObLS *ls = NULL; - ObLSTabletIterator tablet_iter; + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_READABLE_COMMITED); while(OB_SUCC(ret)) { if (OB_UNLIKELY(stopped_)) { ret = OB_CANCELED; diff --git a/src/observer/virtual_table/ob_all_virtual_dag_warning_history.cpp b/src/observer/virtual_table/ob_all_virtual_dag_warning_history.cpp index b9b5aa296..c49f0a66e 100644 --- a/src/observer/virtual_table/ob_all_virtual_dag_warning_history.cpp +++ b/src/observer/virtual_table/ob_all_virtual_dag_warning_history.cpp @@ -21,9 +21,12 @@ using namespace common; namespace observer { ObAllVirtualDagWarningHistory::ObAllVirtualDagWarningHistory() - : dag_warning_info_(), + : ip_buf_("\0"), + task_id_buf_("\0"), + dag_warning_info_(), dag_warning_info_iter_(), - is_inited_(false) + is_inited_(false), + comment_("\0") { } ObAllVirtualDagWarningHistory::~ObAllVirtualDagWarningHistory() @@ -31,46 +34,47 @@ ObAllVirtualDagWarningHistory::~ObAllVirtualDagWarningHistory() reset(); } -int ObAllVirtualDagWarningHistory::init() -{ - int ret = OB_SUCCESS; - if (is_inited_) { - ret = OB_INIT_TWICE; - SERVER_LOG(WARN, "ObAllVirtualDagWarningHistory has been inited", K(ret)); - } else if (OB_FAIL(dag_warning_info_iter_.open(effective_tenant_id_))) { - SERVER_LOG(WARN, "Fail to open merge info iter", K(ret)); - } else { - is_inited_ = true; - } - return ret; -} - - int ObAllVirtualDagWarningHistory::inner_get_next_row(common::ObNewRow *&row) { int ret = OB_SUCCESS; - - if (!is_inited_) { - ret = OB_NOT_INIT; - SERVER_LOG(WARN, "ObAllVirtualDagWarningHistory has been inited", K(ret)); - } else if (OB_FAIL(dag_warning_info_iter_.get_next_info(dag_warning_info_))) { - if (OB_ITER_END != ret) { - STORAGE_LOG(WARN, "Fail to get next merge info", K(ret)); + if (OB_FAIL(execute(row))) { + if (ret != OB_ITER_END) { + SERVER_LOG(WARN, "execute fail", K(ret)); } - } else if (OB_FAIL(fill_cells(dag_warning_info_))) { - STORAGE_LOG(WARN, "Fail to fill cells", K(ret), K(dag_warning_info_)); - } else { - row = &cur_row_; } return ret; } -int ObAllVirtualDagWarningHistory::fill_cells(ObDagWarningInfo &dag_warning_info) +bool ObAllVirtualDagWarningHistory::is_need_process(uint64_t tenant_id) +{ + if (is_sys_tenant(effective_tenant_id_) || tenant_id == effective_tenant_id_) { + return true; + } + return false; +} + +int ObAllVirtualDagWarningHistory::process_curr_tenant(ObNewRow *&row) { int ret = OB_SUCCESS; + row = nullptr; const int64_t col_count = output_column_ids_.count(); ObObj *cells = cur_row_.cells_; - int64_t n = 0; + int64_t compression_ratio = 0; + int n = 0; + if (!dag_warning_info_iter_.is_opened()) { + if (OB_FAIL(MTL(ObDagWarningHistoryManager *)->open_iter(dag_warning_info_iter_))) { + STORAGE_LOG(WARN, "fail to begin ObTenantSSTableMergeInfoMgr::Iterator", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (FALSE_IT(MEMSET(comment_, '\0', sizeof(comment_)))) { + } else if (OB_FAIL(dag_warning_info_iter_.get_next(&dag_warning_info_, comment_, sizeof(comment_)))) { + if (OB_ITER_END != ret) { + STORAGE_LOG(WARN, "fail to get next sstable merge info", K(ret)); + } + } + } for (int64_t i = 0; OB_SUCC(ret) && i < col_count; ++i) { uint64_t col_id = output_column_ids_.at(i); switch (col_id) { @@ -87,11 +91,11 @@ int ObAllVirtualDagWarningHistory::fill_cells(ObDagWarningInfo &dag_warning_info break; case TENANT_ID: //tenant_id - cells[i].set_int(dag_warning_info.tenant_id_); + cells[i].set_int(dag_warning_info_.tenant_id_); break; case TASK_ID: //table_id - n = dag_warning_info.task_id_.to_string(task_id_buf_, sizeof(task_id_buf_)); + n = dag_warning_info_.task_id_.to_string(task_id_buf_, sizeof(task_id_buf_)); if (n < 0 || n >= sizeof(task_id_buf_)) { ret = OB_BUF_NOT_ENOUGH; SERVER_LOG(WARN, "buffer not enough", K(ret)); @@ -102,40 +106,40 @@ int ObAllVirtualDagWarningHistory::fill_cells(ObDagWarningInfo &dag_warning_info break; case MODULE: //module - cells[i].set_varchar(share::ObIDag::get_dag_module_str(dag_warning_info.dag_type_)); + cells[i].set_varchar(share::ObIDag::get_dag_module_str(dag_warning_info_.dag_type_)); cells[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; case TYPE: { //dag_type - cells[i].set_varchar(share::ObIDag::get_dag_type_str(dag_warning_info.dag_type_)); + cells[i].set_varchar(share::ObIDag::get_dag_type_str(dag_warning_info_.dag_type_)); cells[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; } case RET: { // dag_ret - cells[i].set_varchar(common::ob_error_name(dag_warning_info.dag_ret_)); + cells[i].set_varchar(common::ob_error_name(dag_warning_info_.dag_ret_)); cells[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; } case STATUS: // dag_status - cells[i].set_varchar(ObDagWarningInfo::get_dag_status_str(dag_warning_info.dag_status_)); + cells[i].set_varchar(ObDagWarningInfo::get_dag_status_str(dag_warning_info_.dag_status_)); cells[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; case GMT_CREATE: //table_type - cells[i].set_timestamp(dag_warning_info.gmt_create_); + cells[i].set_timestamp(dag_warning_info_.gmt_create_); break; case GMT_MODIFIED: //major_table_id - cells[i].set_timestamp(dag_warning_info.gmt_modified_); + cells[i].set_timestamp(dag_warning_info_.gmt_modified_); break; case RETRY_CNT: - cells[i].set_int(dag_warning_info.retry_cnt_); + cells[i].set_int(dag_warning_info_.retry_cnt_); break; case WARNING_INFO: { //merge_type - cells[i].set_varchar(dag_warning_info.warning_info_); + cells[i].set_varchar(comment_); cells[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; } @@ -144,15 +148,18 @@ int ObAllVirtualDagWarningHistory::fill_cells(ObDagWarningInfo &dag_warning_info SERVER_LOG(WARN, "invalid column id", K(ret), K(col_id)); } } - + if (OB_SUCC(ret)) { + row = &cur_row_; + } return ret; } void ObAllVirtualDagWarningHistory::reset() { + omt::ObMultiTenantOperator::reset(); ObVirtualTableScannerIterator::reset(); - dag_warning_info_iter_.reset(); memset(ip_buf_, 0, sizeof(ip_buf_)); memset(task_id_buf_, 0, sizeof(task_id_buf_)); + memset(comment_, 0, sizeof(comment_)); } diff --git a/src/observer/virtual_table/ob_all_virtual_dag_warning_history.h b/src/observer/virtual_table/ob_all_virtual_dag_warning_history.h index a248c9b08..0d94cbae7 100644 --- a/src/observer/virtual_table/ob_all_virtual_dag_warning_history.h +++ b/src/observer/virtual_table/ob_all_virtual_dag_warning_history.h @@ -15,13 +15,15 @@ #include "share/ob_virtual_table_scanner_iterator.h" #include "lib/container/ob_array.h" #include "share/scheduler/ob_dag_warning_history_mgr.h" +#include "observer/omt/ob_multi_tenant_operator.h" namespace oceanbase { namespace observer { -class ObAllVirtualDagWarningHistory : public common::ObVirtualTableScannerIterator +class ObAllVirtualDagWarningHistory : public common::ObVirtualTableScannerIterator, + public omt::ObMultiTenantOperator { public: enum COLUMN_ID_LIST @@ -41,17 +43,24 @@ public: }; ObAllVirtualDagWarningHistory(); virtual ~ObAllVirtualDagWarningHistory(); - int init(); virtual int inner_get_next_row(common::ObNewRow *&row); virtual void reset(); protected: int fill_cells(share::ObDagWarningInfo &dag_warning_info); +private: + virtual bool is_need_process(uint64_t tenant_id) override; + virtual int process_curr_tenant(common::ObNewRow *&row) override; + virtual void release_last_tenant() override + { + dag_warning_info_iter_.reset(); + } private: char ip_buf_[common::OB_IP_STR_BUFF]; char task_id_buf_[common::OB_TRACE_STAT_BUFFER_SIZE]; share::ObDagWarningInfo dag_warning_info_; - share::ObDagWarningInfoIterator dag_warning_info_iter_; + compaction::ObIDiagnoseInfoMgr::Iterator dag_warning_info_iter_; bool is_inited_; + char comment_[common::OB_DAG_WARNING_INFO_LENGTH]; DISALLOW_COPY_AND_ASSIGN(ObAllVirtualDagWarningHistory); }; diff --git a/src/observer/virtual_table/ob_all_virtual_ls_info.cpp b/src/observer/virtual_table/ob_all_virtual_ls_info.cpp index 54cfcbc0b..e9d38a6ec 100644 --- a/src/observer/virtual_table/ob_all_virtual_ls_info.cpp +++ b/src/observer/virtual_table/ob_all_virtual_ls_info.cpp @@ -189,7 +189,15 @@ int ObAllVirtualLSInfo::process_curr_tenant(ObNewRow *&row) // clog_checkpoint_ts cur_row_.cells_[i].set_uint64(!ls_info.tablet_change_checkpoint_scn_.is_valid() ? 0 : ls_info.tablet_change_checkpoint_scn_.get_val_for_tx()); break; + case OB_APP_MIN_COLUMN_ID + 14: + // tablet_change_checkpoint_scn + cur_row_.cells_[i].set_uint64(!ls_info.tablet_change_checkpoint_scn_.is_valid() ? 0 : ls_info.tablet_change_checkpoint_scn_.get_val_for_inner_table_field()); + break; default: + case OB_APP_MIN_COLUMN_ID + 15: + // transfer_scn + cur_row_.cells_[i].set_uint64(!ls_info.transfer_scn_.is_valid() ? 0 : ls_info.transfer_scn_.get_val_for_inner_table_field()); + break; ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "invalid col_id", K(ret), K(col_id)); break; diff --git a/src/observer/virtual_table/ob_all_virtual_macro_block_marker_status.cpp b/src/observer/virtual_table/ob_all_virtual_macro_block_marker_status.cpp index 0303079cb..29a22d590 100644 --- a/src/observer/virtual_table/ob_all_virtual_macro_block_marker_status.cpp +++ b/src/observer/virtual_table/ob_all_virtual_macro_block_marker_status.cpp @@ -100,61 +100,76 @@ int ObAllVirtualMacroBlockMarkerStatus::inner_get_next_row(common::ObNewRow *&ro break; } case OB_APP_MIN_COLUMN_ID + 5: { + // shared_meta_block_count + cur_row_.cells_[i].set_int(marker_status_.shared_meta_block_count_); + break; + } + case OB_APP_MIN_COLUMN_ID + 6: { // tmp_file_block_count cur_row_.cells_[i].set_int(marker_status_.tmp_file_count_); break; } - case OB_APP_MIN_COLUMN_ID + 6: { + case OB_APP_MIN_COLUMN_ID + 7: { // data_block_count cur_row_.cells_[i].set_int(marker_status_.data_block_count_); break; } - case OB_APP_MIN_COLUMN_ID + 7: { + case OB_APP_MIN_COLUMN_ID + 8: { + // shared_data_block_count + cur_row_.cells_[i].set_int(marker_status_.shared_data_block_count_); + break; + } + case OB_APP_MIN_COLUMN_ID + 9: { // disk_block_count_ cur_row_.cells_[i].set_int(marker_status_.disk_block_count_); break; } - case OB_APP_MIN_COLUMN_ID + 8: { + case OB_APP_MIN_COLUMN_ID + 10: { // bloomfilter_count_ cur_row_.cells_[i].set_int(marker_status_.bloomfiter_count_); break; } - case OB_APP_MIN_COLUMN_ID + 9: { + case OB_APP_MIN_COLUMN_ID + 11: { // hold_count_ cur_row_.cells_[i].set_int(marker_status_.hold_count_); break; } - case OB_APP_MIN_COLUMN_ID + 10: { + case OB_APP_MIN_COLUMN_ID + 12: { // pending_free_count_ cur_row_.cells_[i].set_int(marker_status_.pending_free_count_); break; } - case OB_APP_MIN_COLUMN_ID + 11: { + case OB_APP_MIN_COLUMN_ID + 13: { // free_count_ cur_row_.cells_[i].set_int(marker_status_.free_count_); break; } - case OB_APP_MIN_COLUMN_ID + 12: { + case OB_APP_MIN_COLUMN_ID + 14: { // mark_cost_time cur_row_.cells_[i].set_int(marker_status_.mark_cost_time_); break; } - case OB_APP_MIN_COLUMN_ID + 13: { + case OB_APP_MIN_COLUMN_ID + 15: { // sweep_cost_time cur_row_.cells_[i].set_int(marker_status_.sweep_cost_time_); break; } - case OB_APP_MIN_COLUMN_ID + 14: { + case OB_APP_MIN_COLUMN_ID + 16: { // start_marker_time cur_row_.cells_[i].set_timestamp(marker_status_.start_time_); break; } - case OB_APP_MIN_COLUMN_ID + 15: { + case OB_APP_MIN_COLUMN_ID + 17: { // last_marker_end_time cur_row_.cells_[i].set_timestamp(marker_status_.last_end_time_); break; } - case OB_APP_MIN_COLUMN_ID + 16: { + case OB_APP_MIN_COLUMN_ID + 18: { + // whether finished marking + cur_row_.cells_[i].set_bool(marker_status_.mark_finished_); + break; + } + case OB_APP_MIN_COLUMN_ID + 19: { // comment cur_row_.cells_[i].set_varchar(comment_); cur_row_.cells_[i].set_collation_type(collcation_type); diff --git a/src/observer/virtual_table/ob_all_virtual_mds_event_history.cpp b/src/observer/virtual_table/ob_all_virtual_mds_event_history.cpp new file mode 100644 index 000000000..be6b86753 --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_mds_event_history.cpp @@ -0,0 +1,394 @@ +#include "ob_all_virtual_mds_event_history.h" +#include "lib/container/ob_tuple.h" +#include "lib/function/ob_function.h" +#include "lib/list/ob_dlist.h" +#include "lib/ob_define.h" +#include "lib/ob_errno.h" +#include "lib/utility/ob_print_utils.h" +#include "share/ob_ls_id.h" +#include "storage/multi_data_source/runtime_utility/common_define.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/ls/ob_ls.h" +#include "ob_mds_event_buffer.h" + +namespace oceanbase +{ +using namespace share; +using namespace storage; +using namespace storage::mds; +using namespace common; +using namespace omt; +namespace observer +{ + +bool ObAllVirtualMdsEventHistory::judge_key_in_ranges_(const MdsEventKey &key) const +{ + bool in_tenant_ranges = false; + bool in_ls_ranges = false; + bool in_tablet_ranges = false; + for (int64_t idx = 0; idx < tenant_ranges_.count(); ++idx) { + if (key.tenant_id_ >= tenant_ranges_[idx].element<0>() && key.tenant_id_ <= tenant_ranges_[idx].element<1>()) { + in_tenant_ranges = true; + break; + } + } + if (!in_tenant_ranges) { + for (int64_t idx = 0; idx < tenant_points_.count(); ++idx) { + if (tenant_points_[idx] == key.tenant_id_) { + in_tenant_ranges = true; + break; + } + } + } + if (in_tenant_ranges) { + for (int64_t idx = 0; idx < ls_ranges_.count(); ++idx) { + if (key.ls_id_ >= ls_ranges_[idx].element<0>() && key.ls_id_ <= ls_ranges_[idx].element<1>()) { + in_ls_ranges = true; + break; + } + } + if (!in_ls_ranges) { + for (int64_t idx = 0; idx < ls_points_.count(); ++idx) { + if (ls_points_[idx] == key.ls_id_) { + in_ls_ranges = true; + break; + } + } + } + if (in_ls_ranges) { + for (int64_t idx = 0; idx < tablet_ranges_.count(); ++idx) { + if (key.tablet_id_ >= tablet_ranges_[idx].element<0>() && key.tablet_id_ <= tablet_ranges_[idx].element<1>()) { + in_tablet_ranges = true; + break; + } + } + if (!in_ls_ranges) { + for (int64_t idx = 0; idx < tablet_points_.count(); ++idx) { + if (tablet_points_[idx] == key.tablet_id_) { + in_tablet_ranges = true; + break; + } + } + } + } + } + return in_tenant_ranges && in_ls_ranges && in_tablet_ranges; +} + +int ObAllVirtualMdsEventHistory::range_scan_(char *temp_buffer, int64_t buf_len) +{ + int ret = OB_SUCCESS; + MDS_LOG(INFO, "start range read", K(*this)); + if (OB_FAIL(ObMdsEventBuffer::for_each([this, temp_buffer, buf_len](const MdsEventKey &key, const MdsEvent &event) -> int { + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + if (judge_key_in_ranges_(key)) { + if (MTL_ID() == OB_SYS_TENANT_ID ||// SYS租户可以看到所有租户的信息 + key.tenant_id_ == MTL_ID()) {// 非SYS租户只能看到本租户的信息 + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (MTL_ID() != key.tenant_id_) { + tmp_ret = guard.switch_to(key.tenant_id_); + } + if (OB_SUCCESS == tmp_ret) { + if (OB_FAIL(convert_event_info_to_row_(key, event, temp_buffer, buf_len, cur_row_))) { + MDS_LOG(WARN, "failed to convert_node_info_to_row_", K(ret), K(*this)); + } else if (OB_FAIL(scanner_.add_row(cur_row_))) { + MDS_LOG(WARN, "fail to add_row to scanner_", K(*this)); + } else { + MDS_LOG(TRACE, "scan", K(key)); + } + } + } + } + return ret; + }))) { + MDS_LOG(WARN, "scan read failed", KR(ret), K(MTL_ID()), K(*this)); + } + return ret; +} + +int ObAllVirtualMdsEventHistory::point_read_(char *temp_buffer, int64_t buf_len) +{ + int ret = OB_SUCCESS; + MDS_LOG(INFO, "start point read", K(*this)); + if ((tenant_points_.count() != ls_points_.count()) || (ls_points_.count() != tablet_points_.count())) { + MDS_LOG(WARN, "points not match", K(MTL_ID()), K(*this)); + } else { + for (int64_t idx = 0; idx < tenant_points_.count() && OB_SUCC(ret); ++idx) { + MdsEventKey key(tenant_points_[idx], ls_points_[idx], tablet_points_[idx]); + if (OB_FAIL(ObMdsEventBuffer::for_each(key, [&key, this, temp_buffer, buf_len](const MdsEvent &event) -> int { + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + if (MTL_ID() == OB_SYS_TENANT_ID ||// SYS租户可以看到所有租户的信息 + key.tenant_id_ == MTL_ID()) {// 非SYS租户只能看到本租户的信息 + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (MTL_ID() != key.tenant_id_) { + tmp_ret = guard.switch_to(key.tenant_id_); + } + if (OB_SUCCESS == tmp_ret) { + if (OB_FAIL(convert_event_info_to_row_(key, event, temp_buffer, buf_len, cur_row_))) { + MDS_LOG(WARN, "failed to convert_node_info_to_row_", K(ret), K(*this)); + } else if (OB_FAIL(scanner_.add_row(cur_row_))) { + MDS_LOG(WARN, "fail to add_row to scanner_", K(MTL_ID()), K(*this)); + } + } + } + return ret; + }))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + MDS_LOG(WARN, "OB_ENTRY_NOT_EXIST", K(key)); + } else { + MDS_LOG(WARN, "failed to do for_each", K(ret), K(*this)); + } + } else { + MDS_LOG(INFO, "read key", K(key), K(*this)); + } + } + } + return ret; +} + +int ObAllVirtualMdsEventHistory::inner_get_next_row(common::ObNewRow *&row) +{ + int ret = OB_SUCCESS; + if (false == start_to_read_) { + if (OB_FAIL(get_primary_key_ranges_())) { + MDS_LOG(WARN, "fail to get index scan ranges", KR(ret), K(MTL_ID()), K(*this)); + } else { + char *temp_buffer = nullptr; + constexpr int64_t BUFFER_SIZE = 32_MB; + if (OB_ISNULL(temp_buffer = (char *)ob_malloc(BUFFER_SIZE, "VirMdsEvent"))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG(WARN, "fail to alloc buffer", K(MTL_ID()), K(*this)); + } else { + if (!tenant_ranges_.empty() || !ls_ranges_.empty() || !tablet_ranges_.empty()) {// scan read + ret = range_scan_(temp_buffer, BUFFER_SIZE); + } else {// point read + ret = point_read_(temp_buffer, BUFFER_SIZE); + } + if (OB_SUCC(ret)) { + scanner_it_ = scanner_.begin(); + start_to_read_ = true; + } + ob_free(temp_buffer); + } + } + } + if (OB_SUCC(ret) && true == start_to_read_) { + if (OB_FAIL(scanner_it_.get_next_row(cur_row_))) { + if (OB_ITER_END != ret) { + MDS_LOG(WARN, "failed to get_next_row", K(ret), K(*this)); + } + } else { + row = &cur_row_; + } + } + return ret; +} + +int ObAllVirtualMdsEventHistory::convert_event_info_to_row_(const MdsEventKey &key, + const MdsEvent &event, + char *buffer, + int64_t buffer_size, + common::ObNewRow &row) +{ + int ret = OB_SUCCESS; + const int64_t count = output_column_ids_.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { + uint64_t col_id = output_column_ids_.at(i); + switch (col_id) { + case OB_APP_MIN_COLUMN_ID: {// tenant_id + cur_row_.cells_[i].set_int(MTL_ID()); + break; + } + case OB_APP_MIN_COLUMN_ID + 1: {// ls_id + cur_row_.cells_[i].set_int(key.ls_id_.id()); + break; + } + case OB_APP_MIN_COLUMN_ID + 2: {// tablet_id + cur_row_.cells_[i].set_int(key.tablet_id_.id()); + break; + } + case OB_APP_MIN_COLUMN_ID + 3: {// svr_ip + if (false == (GCTX.self_addr().ip_to_string(ip_buffer_, IP_BUFFER_SIZE))) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(WARN, "ip_to_string failed", KR(ret), K(*this)); + } else { + cur_row_.cells_[i].set_varchar(ObString(ip_buffer_)); + } + break; + } + case OB_APP_MIN_COLUMN_ID + 4: {// svr_port + cur_row_.cells_[i].set_int(GCTX.self_addr().get_port()); + break; + } + case OB_APP_MIN_COLUMN_ID + 5: {// tid + cur_row_.cells_[i].set_int(event.tid_); + break; + } + case OB_APP_MIN_COLUMN_ID + 6: {// tname + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", event.tname_); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 7: {// trace + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", to_cstring(event.trace_id_)); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 8: {// timestamp + cur_row_.cells_[i].set_timestamp(event.timestamp_); + break; + } + case OB_APP_MIN_COLUMN_ID + 9: {// event + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", event.event_); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 10: {// info + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", to_cstring(event.info_str_)); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 11: {// unit_id + cur_row_.cells_[i].set_int(event.unit_id_); + break; + } + case OB_APP_MIN_COLUMN_ID + 12: {// user_key + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", to_cstring(event.key_str_)); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 13: {// writer_type + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", mds::obj_to_string(event.writer_type_)); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 14: {// writer_id + cur_row_.cells_[i].set_int(event.writer_id_); + break; + } + case OB_APP_MIN_COLUMN_ID + 15: {// seq_no + cur_row_.cells_[i].set_int(event.seq_no_); + break; + } + case OB_APP_MIN_COLUMN_ID + 16: {// redo_scn + cur_row_.cells_[i].set_uint64(event.redo_scn_.get_val_for_inner_table_field()); + break; + } + case OB_APP_MIN_COLUMN_ID + 17: {// end_scn + cur_row_.cells_[i].set_uint64(event.end_scn_.get_val_for_inner_table_field()); + break; + } + case OB_APP_MIN_COLUMN_ID + 18: {// trans_version + cur_row_.cells_[i].set_uint64(event.trans_version_.get_val_for_inner_table_field()); + break; + } + case OB_APP_MIN_COLUMN_ID + 19: {// node_type + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", mds::obj_to_string(event.node_type_)); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 20: {// state + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", mds::obj_to_string(event.state_)); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + } + } + return ret; +} + +int ObAllVirtualMdsEventHistory::get_primary_key_ranges_() +{ + int ret = OB_SUCCESS; + if (key_ranges_.count() >= 1) { + for (int64_t i = 0; OB_SUCC(ret) && i < key_ranges_.count(); i++) { + ObNewRange &key_range = key_ranges_.at(i); + if (OB_UNLIKELY(key_range.get_start_key().get_obj_cnt() != 3 + || key_range.get_end_key().get_obj_cnt() != 3)) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "unexpected # of rowkey columns", + K(ret), + "size of start key", key_range.get_start_key().get_obj_cnt(), + "size of end key", key_range.get_end_key().get_obj_cnt()); + } else { + ObObj tenant_obj_low = (key_range.get_start_key().get_obj_ptr()[0]); + ObObj tenant_obj_high = (key_range.get_end_key().get_obj_ptr()[0]); + ObObj ls_obj_low = (key_range.get_start_key().get_obj_ptr()[1]); + ObObj ls_obj_high = (key_range.get_end_key().get_obj_ptr()[1]); + ObObj tablet_obj_low = (key_range.get_start_key().get_obj_ptr()[2]); + ObObj tablet_obj_high = (key_range.get_end_key().get_obj_ptr()[2]); + + uint64_t tenant_low = tenant_obj_low.is_min_value() ? 0 : tenant_obj_low.get_uint64(); + uint64_t tenant_high = tenant_obj_high.is_max_value() ? UINT64_MAX : tenant_obj_high.get_uint64(); + ObLSID ls_low = ls_obj_low.is_min_value() ? ObLSID(0) : ObLSID(ls_obj_low.get_int()); + ObLSID ls_high = ls_obj_high.is_max_value() ? ObLSID(INT64_MAX) : ObLSID(ls_obj_high.get_int()); + ObTabletID tablet_low = tablet_obj_low.is_min_value() ? ObTabletID(0) : ObTabletID(tablet_obj_low.get_uint64()); + ObTabletID tablet_high = tablet_obj_high.is_max_value() ? ObTabletID(UINT64_MAX) : ObTabletID(tablet_obj_high.get_uint64()); + + if (OB_SUCC(ret)) { + if (tenant_low == tenant_high) { + if (OB_FAIL(tenant_points_.push_back(tenant_low))) { + MDS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } + } else if (OB_SUCCESS != (ret = + (tenant_ranges_.push_back(ObTuple(tenant_low, tenant_high))))) { + MDS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } + } + if (OB_SUCC(ret)) { + if (ls_low == ls_high) { + if (OB_FAIL(ls_points_.push_back(ls_low))) { + MDS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } + } else if (OB_SUCCESS != (ret = + (ls_ranges_.push_back(ObTuple(ls_low, ls_high))))) { + MDS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } + } + if (OB_SUCC(ret)) { + if (tablet_low == tablet_high) { + if (OB_FAIL(tablet_points_.push_back(tablet_low))) { + MDS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } + } else if (OB_SUCCESS != (ret = + (tablet_ranges_.push_back(ObTuple(tablet_low, tablet_high))))) { + MDS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } + } + } + } + } + MDS_LOG(INFO, "get_primary_key_ranges_", KR(ret), K(key_ranges_), K(*this)); + return ret; +} + +} +} \ No newline at end of file diff --git a/src/observer/virtual_table/ob_all_virtual_mds_event_history.h b/src/observer/virtual_table/ob_all_virtual_mds_event_history.h new file mode 100644 index 000000000..daab5b0e4 --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_mds_event_history.h @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2021 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 OB_ALL_VIRTUAL_MDS_EVENT_HISTORY_H +#define OB_ALL_VIRTUAL_MDS_EVENT_HISTORY_H + +#include "lib/container/ob_tuple.h" +#include "ob_tablet_id.h" +#include "share/ob_ls_id.h" +#include "share/ob_virtual_table_scanner_iterator.h" +#include "observer/omt/ob_multi_tenant_operator.h" +#include "observer/omt/ob_multi_tenant.h" +#include "ob_mds_event_buffer.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +struct MdsNodeInfoForVirtualTable; +} +} +namespace observer +{ + +class ObAllVirtualMdsEventHistory : public common::ObVirtualTableScannerIterator +{ + static constexpr int64_t IP_BUFFER_SIZE = 64; +public: + explicit ObAllVirtualMdsEventHistory(omt::ObMultiTenant *omt) : omt_(omt) {} + virtual int inner_get_next_row(common::ObNewRow *&row) override; + TO_STRING_KV(K_(tenant_ranges), K_(tenant_points), K_(ls_ranges), K_(ls_points), K_(tablet_ranges), K_(tablet_points)) +private: + int convert_event_info_to_row_(const MdsEventKey &key, + const MdsEvent &event, + char *buffer, + const int64_t buffer_size, + common::ObNewRow &row); + int get_primary_key_ranges_(); + bool judge_key_in_ranges_(const MdsEventKey &key) const; + int range_scan_(char *temp_buffer, int64_t buf_len); + int point_read_(char *temp_buffer, int64_t buf_len); + DISALLOW_COPY_AND_ASSIGN(ObAllVirtualMdsEventHistory); + omt::ObMultiTenant *omt_; + char ip_buffer_[IP_BUFFER_SIZE]; + ObArray> tenant_ranges_; + ObArray tenant_points_; + ObArray> ls_ranges_; + ObArray ls_points_; + ObArray> tablet_ranges_; + ObArray tablet_points_; +}; + +} // observer +} // oceanbase +#endif diff --git a/src/observer/virtual_table/ob_all_virtual_mds_node_stat.cpp b/src/observer/virtual_table/ob_all_virtual_mds_node_stat.cpp new file mode 100644 index 000000000..2d3be658b --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_mds_node_stat.cpp @@ -0,0 +1,316 @@ +#include "ob_all_virtual_mds_node_stat.h" +#include "lib/container/ob_tuple.h" +#include "lib/function/ob_function.h" +#include "lib/list/ob_dlist.h" +#include "lib/ob_errno.h" +#include "lib/utility/ob_print_utils.h" +#include "share/ob_ls_id.h" +#include "storage/multi_data_source/runtime_utility/common_define.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/ls/ob_ls.h" + +namespace oceanbase +{ +using namespace share; +using namespace storage; +using namespace storage::mds; +using namespace common; +using namespace omt; +namespace observer +{ + +int ObAllVirtualMdsNodeStat::inner_get_next_row(common::ObNewRow *&row) +{ + int ret = OB_SUCCESS; + if (false == start_to_read_) { + if (OB_FAIL(get_primary_key_ranges_())) { + MDS_LOG(WARN, "fail to get index scan ranges", KR(ret), K(MTL_ID()), K(*this)); + } else { + char *temp_buffer = nullptr; + char *to_string_buffer = nullptr; + constexpr int64_t BUFFER_SIZE = 32_MB; + if (OB_ISNULL(temp_buffer = (char *)ob_malloc(BUFFER_SIZE, "VirMdsStat"))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG(WARN, "fail to alloc buffer", K(MTL_ID()), K(*this)); + } else { + auto apply_on_tablet_op = [this, temp_buffer](ObTablet &tablet) -> int { + int ret = OB_SUCCESS; + MdsNodeInfoForVirtualTable mds_info; + mds::MdsTableHandle mds_table_handle; + ObArray row_array; + if (OB_FAIL(tablet.get_mds_table_handle_(mds_table_handle, false))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + MDS_LOG(WARN, "failed to get_mds_table_handle_", K(ret), K(*this)); + } + } else if (OB_FAIL(mds_table_handle.fill_virtual_info(row_array))) { + MDS_LOG(WARN, "failed to fill_virtual_info from mds_table", K(ret), K(*this)); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(tablet.fill_virtual_info(row_array))) { + MDS_LOG(WARN, "failed to fill_virtual_info from tablet", K(ret), K(*this)); + } else { + for (int64_t idx = 0; idx < row_array.count() && OB_SUCC(ret); ++idx) { + if (OB_FAIL(convert_node_info_to_row_(row_array[idx], temp_buffer, BUFFER_SIZE, cur_row_))) { + MDS_LOG(WARN, "failed to convert_node_info_to_row_", K(ret), K(*this)); + } else if (OB_FAIL(scanner_.add_row(cur_row_))) { + MDS_LOG(WARN, "fail to add_row to scanner_", K(MTL_ID()), K(*this)); + } + } + } + } + return ret; + }; + auto func_iterate_tenant = [&apply_on_tablet_op, this]() -> int + { + int ret = OB_SUCCESS; + if (judege_in_ranges(MTL_ID(), tenant_ranges_)) { + if (OB_FAIL(ObTenantMdsService::for_each_ls_in_tenant([&ret, &apply_on_tablet_op, this](ObLS &ls) { + if (judege_in_ranges(ls.get_ls_id(), ls_ranges_)) { + ret = get_tablet_info_(ls, apply_on_tablet_op); + } else { MDS_LOG(TRACE, "not in ranges", K(ret), K(*this)); } + return ret; + }))) {} + } else { MDS_LOG(TRACE, "not in ranges", K(ret), K(*this)); } + return ret; + }; + if (OB_FAIL(omt_->operate_each_tenant_for_sys_or_self(func_iterate_tenant))) { + MDS_LOG(WARN, "ObMultiTenant operate_each_tenant_for_sys_or_self failed", K(ret), K(*this)); + } else { + scanner_it_ = scanner_.begin(); + start_to_read_ = true; + } + ob_free(temp_buffer); + } + } + } + if (OB_SUCC(ret) && true == start_to_read_) { + if (OB_FAIL(scanner_it_.get_next_row(cur_row_))) { + if (OB_ITER_END != ret) { + MDS_LOG(WARN, "failed to get_next_row", K(ret), K(*this)); + } + } else { + row = &cur_row_; + } + } + return ret; +} + +int ObAllVirtualMdsNodeStat::convert_node_info_to_row_(const storage::mds::MdsNodeInfoForVirtualTable &node_info, + char *buffer, + int64_t buffer_size, + common::ObNewRow &row) +{ + int ret = OB_SUCCESS; + const int64_t count = output_column_ids_.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { + uint64_t col_id = output_column_ids_.at(i); + switch (col_id) { + case OB_APP_MIN_COLUMN_ID: {// tenant_id + cur_row_.cells_[i].set_int(MTL_ID()); + break; + } + case OB_APP_MIN_COLUMN_ID + 1: {// ls_id + cur_row_.cells_[i].set_int(node_info.ls_id_.id()); + break; + } + case OB_APP_MIN_COLUMN_ID + 2: {// tablet_id + cur_row_.cells_[i].set_int(node_info.tablet_id_.id()); + break; + } + case OB_APP_MIN_COLUMN_ID + 3: {// svr_ip + if (false == (GCTX.self_addr().ip_to_string(ip_buffer_, IP_BUFFER_SIZE))) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(WARN, "ip_to_string failed", KR(ret), K(*this)); + } else { + cur_row_.cells_[i].set_varchar(ObString(ip_buffer_)); + } + break; + } + case OB_APP_MIN_COLUMN_ID + 4: {// svr_port + cur_row_.cells_[i].set_int(GCTX.self_addr().get_port()); + break; + } + case OB_APP_MIN_COLUMN_ID + 5: {// unit_id + cur_row_.cells_[i].set_int(node_info.unit_id_); + break; + } + case OB_APP_MIN_COLUMN_ID + 6: {// user_key + int64_t write_n = node_info.user_key_.to_string(buffer, buffer_size); + buffer += write_n; + buffer_size -= write_n; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(write_n, buffer - write_n)); + break; + } + case OB_APP_MIN_COLUMN_ID + 7: {// version_idx + cur_row_.cells_[i].set_int(node_info.version_idx_); + break; + } + case OB_APP_MIN_COLUMN_ID + 8: {// writer_type + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", mds::obj_to_string(node_info.writer_.writer_type_)); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 9: {// writer_id + cur_row_.cells_[i].set_int(node_info.writer_.writer_id_); + break; + } + case OB_APP_MIN_COLUMN_ID + 10: {// seq_no + cur_row_.cells_[i].set_int(node_info.seq_no_); + break; + } + case OB_APP_MIN_COLUMN_ID + 11: {// redo_scn + cur_row_.cells_[i].set_uint64(node_info.redo_scn_.get_val_for_inner_table_field()); + break; + } + case OB_APP_MIN_COLUMN_ID + 12: {// end_scn + cur_row_.cells_[i].set_uint64(node_info.end_scn_.get_val_for_inner_table_field()); + break; + } + case OB_APP_MIN_COLUMN_ID + 13: {// trans_version + cur_row_.cells_[i].set_uint64(node_info.trans_version_.get_val_for_inner_table_field()); + break; + } + case OB_APP_MIN_COLUMN_ID + 14: {// node_type + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", mds::obj_to_string(node_info.node_type_)); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 15: {// state + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", mds::obj_to_string(node_info.state_)); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 16: {// position + int64_t pos = 0; + databuff_printf(buffer, buffer_size, pos, "%s", mds::obj_to_string(node_info.position_)); + buffer += pos; + buffer_size -= pos; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(pos, buffer - pos)); + break; + } + case OB_APP_MIN_COLUMN_ID + 17: {// user_data + int64_t write_n = node_info.user_data_.to_string(buffer, buffer_size); + buffer += write_n; + buffer_size -= write_n; + cur_row_.cells_[i].set_string(ObLongTextType, ObString(write_n, buffer - write_n)); + break; + } + } + } + return ret; +} + +int ObAllVirtualMdsNodeStat::get_primary_key_ranges_() +{ + int ret = OB_SUCCESS; + if (key_ranges_.count() >= 1) { + for (int64_t i = 0; OB_SUCC(ret) && i < key_ranges_.count(); i++) { + ObNewRange &key_range = key_ranges_.at(i); + if (OB_UNLIKELY(key_range.get_start_key().get_obj_cnt() != 3 + || key_range.get_end_key().get_obj_cnt() != 3)) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "unexpected # of rowkey columns", + K(ret), + "size of start key", key_range.get_start_key().get_obj_cnt(), + "size of end key", key_range.get_end_key().get_obj_cnt()); + } else { + ObObj tenant_obj_low = (key_range.get_start_key().get_obj_ptr()[0]); + ObObj tenant_obj_high = (key_range.get_end_key().get_obj_ptr()[0]); + ObObj ls_obj_low = (key_range.get_start_key().get_obj_ptr()[1]); + ObObj ls_obj_high = (key_range.get_end_key().get_obj_ptr()[1]); + ObObj tablet_obj_low = (key_range.get_start_key().get_obj_ptr()[2]); + ObObj tablet_obj_high = (key_range.get_end_key().get_obj_ptr()[2]); + + uint64_t tenant_low = tenant_obj_low.is_min_value() ? 0 : tenant_obj_low.get_uint64(); + uint64_t tenant_high = tenant_obj_high.is_max_value() ? UINT64_MAX : tenant_obj_high.get_uint64(); + ObLSID ls_low = ls_obj_low.is_min_value() ? ObLSID(0) : ObLSID(ls_obj_low.get_int()); + ObLSID ls_high = ls_obj_high.is_max_value() ? ObLSID(INT64_MAX) : ObLSID(ls_obj_high.get_int()); + ObTabletID tablet_low = tablet_obj_low.is_min_value() ? ObTabletID(0) : ObTabletID(tablet_obj_low.get_uint64()); + ObTabletID tablet_high = tablet_obj_high.is_max_value() ? ObTabletID(UINT64_MAX) : ObTabletID(tablet_obj_high.get_uint64()); + + if (OB_FAIL(tenant_ranges_.push_back(ObTuple(tenant_low, tenant_high)))) { + MDS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } else if (OB_SUCCESS != (ret = + (ls_ranges_.push_back(ObTuple(ls_low, ls_high))))) { + MDS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } else { + if (tablet_low == tablet_high) { + if (OB_FAIL(tablet_points_.push_back(tablet_low))) { + MDS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } + } else if (OB_SUCCESS != (ret = + (tablet_ranges_.push_back(ObTuple(tablet_low, tablet_high))))) { + MDS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } + } + } + } + } + MDS_LOG(INFO, "get_primary_key_ranges_", KR(ret), K(key_ranges_), K(*this)); + return ret; +} + +bool ObAllVirtualMdsNodeStat::in_selected_points_(common::ObTabletID tablet_id) +{ + bool is_in_points = false; + for (int64_t idx = 0; idx < tablet_points_.count(); ++idx) { + if (tablet_id == tablet_points_[idx]) { + is_in_points = true; + break; + } + } + return is_in_points; +} + +int ObAllVirtualMdsNodeStat::get_tablet_info_(ObLS &ls, const ObFunction &apply_on_tablet_op) +{ + int ret = OB_SUCCESS; + if (!apply_on_tablet_op.is_valid()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG(ERROR, "invalid ob function", KR(ret), K(key_ranges_), K(*this)); + } else { + if (!tablet_ranges_.empty()) {// scan + if (OB_FAIL(ObTenantMdsService::for_each_tablet_in_ls(ls, [&ret, &apply_on_tablet_op, this](ObTablet &tablet) { + common::ObTabletID tablet_id = tablet.get_tablet_meta().tablet_id_; + if (judege_in_ranges(tablet_id, tablet_ranges_) || in_selected_points_(tablet_id)) { + if (OB_FAIL(apply_on_tablet_op(tablet))) { + MDS_LOG(WARN, "fail to apply op on tablet", KR(ret), K(key_ranges_), K(*this)); + } + } + return ret; + }))) { + MDS_LOG(WARN, "fail to do for_each tablet in ls", KR(ret), K(key_ranges_), K(*this)); + } + } else if (!tablet_points_.empty()) {// point select + for (int64_t idx = 0; idx < tablet_points_.count() && OB_SUCC(ret); ++idx) { + ObTabletHandle tablet_handle; + if (OB_FAIL(ls.get_tablet(tablet_points_[idx], tablet_handle, 0, storage::ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + MDS_LOG(WARN, "fail to get tablet", KR(ret), K(key_ranges_), K(*this)); + } else if (OB_ISNULL(tablet_handle.get_obj())) { + MDS_LOG(ERROR, "get null tablet ptr", KR(ret), K(key_ranges_), K(*this)); + } else if (OB_FAIL(apply_on_tablet_op(*tablet_handle.get_obj()))) { + MDS_LOG(WARN, "fail to apply op on tablet", KR(ret), K(key_ranges_), K(*this)); + } + } + } else { + MDS_LOG(ERROR, "not do scan", KR(ret), K(key_ranges_), K(*this)); + } + } + MDS_LOG(INFO, "get_tablet_info_", KR(ret), K(key_ranges_), K(*this)); + return ret; +} + +} +} \ No newline at end of file diff --git a/src/observer/virtual_table/ob_all_virtual_mds_node_stat.h b/src/observer/virtual_table/ob_all_virtual_mds_node_stat.h new file mode 100644 index 000000000..e49674994 --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_mds_node_stat.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2021 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 OB_ALL_VIRTUAL_MDS__NODE_STAT_H +#define OB_ALL_VIRTUAL_MDS__NODE_STAT_H + +#include "lib/container/ob_tuple.h" +#include "ob_tablet_id.h" +#include "share/ob_ls_id.h" +#include "share/ob_virtual_table_scanner_iterator.h" +#include "observer/omt/ob_multi_tenant_operator.h" +#include "observer/omt/ob_multi_tenant.h" +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +struct MdsNodeInfoForVirtualTable; +} +} +namespace observer +{ + +class ObAllVirtualMdsNodeStat : public common::ObVirtualTableScannerIterator +{ + static constexpr int64_t IP_BUFFER_SIZE = 64; +public: + explicit ObAllVirtualMdsNodeStat(omt::ObMultiTenant *omt) : omt_(omt) {} + virtual int inner_get_next_row(common::ObNewRow *&row) override; + TO_STRING_KV(K_(tenant_ranges), K_(ls_ranges), K_(tablet_ranges), K_(tablet_points)) +private: + int convert_node_info_to_row_(const storage::mds::MdsNodeInfoForVirtualTable &node_info, + char *buffer, + const int64_t buffer_size, + common::ObNewRow &row); + int get_primary_key_ranges_(); + int get_tablet_info_(ObLS &ls, const ObFunction &apply_on_tablet_op); + template + bool judege_in_ranges(const T &element, const ObArray> &element_ranges) { + bool in_range = false; + for (auto &range : element_ranges) { + if (element >= range.template element<0>() && element <= range.template element<1>()) { + in_range = true; + break; + } + } + return in_range; + } + bool in_selected_points_(common::ObTabletID tablet_id); + DISALLOW_COPY_AND_ASSIGN(ObAllVirtualMdsNodeStat); + omt::ObMultiTenant *omt_; + char ip_buffer_[IP_BUFFER_SIZE]; + ObArray> tenant_ranges_; + ObArray> ls_ranges_; + ObArray> tablet_ranges_; + ObArray tablet_points_; +}; + +} // observer +} // oceanbase +#endif diff --git a/src/observer/virtual_table/ob_all_virtual_memstore_info.cpp b/src/observer/virtual_table/ob_all_virtual_memstore_info.cpp index 1f95f801d..70f9e5b5d 100644 --- a/src/observer/virtual_table/ob_all_virtual_memstore_info.cpp +++ b/src/observer/virtual_table/ob_all_virtual_memstore_info.cpp @@ -30,7 +30,7 @@ ObAllVirtualMemstoreInfo::ObAllVirtualMemstoreInfo() addr_(), ls_id_(share::ObLSID::INVALID_LS_ID), ls_iter_guard_(), - ls_tablet_iter_(), + ls_tablet_iter_(ObMDSGetTabletMode::READ_READABLE_COMMITED), tables_handle_(), memtable_array_pos_(0) { @@ -343,36 +343,6 @@ int ObAllVirtualMemstoreInfo::process_curr_tenant(ObNewRow *&row) case OB_APP_MIN_COLUMN_ID + 24: { // compaction info list cur_row_.cells_[i].set_varchar("-"); - if (mt->is_data_memtable()) { - if (mt->has_multi_source_data_unit(MultiSourceDataUnitType::MEDIUM_COMPACTION_INFO)) { - int64_t pos = 0; - compaction::ObMediumCompactionInfo medium_info; - ObMultiSourceData::ObIMultiSourceDataUnitList dst_list; - if (OB_SUCC(mt->get_multi_source_data_unit_list(&medium_info, dst_list, allocator_))) { - int k = 0; - DLIST_FOREACH_X(info, dst_list, OB_SUCC(ret)) { - common::databuff_printf( - compaction_info_buf_, - sizeof(compaction_info_buf_), - pos, - "medium%d_%ld,", - k++, - static_cast(info)->medium_snapshot_); - } - if (OB_SUCC(ret)) { - cur_row_.cells_[i].set_varchar(compaction_info_buf_); - } - } - - - DLIST_FOREACH_REMOVESAFE_NORET(info, dst_list) { - dst_list.remove(info); - info->~ObIMultiSourceDataUnit(); - allocator_->free(info); - } - COMMON_LOG(DEBUG, "medium_list", K(dst_list), K(cur_row_.cells_[i])); - } - } cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; } diff --git a/src/observer/virtual_table/ob_all_virtual_obj_lock.cpp b/src/observer/virtual_table/ob_all_virtual_obj_lock.cpp index 73b24cf72..ad59c39f8 100644 --- a/src/observer/virtual_table/ob_all_virtual_obj_lock.cpp +++ b/src/observer/virtual_table/ob_all_virtual_obj_lock.cpp @@ -240,7 +240,7 @@ int ObAllVirtualObjLock::process_curr_tenant(ObNewRow *&row) break; } case OWNER_ID: - cur_row_.cells_[i].set_int(lock_op.owner_id_); + cur_row_.cells_[i].set_int(lock_op.owner_id_.id()); break; case CREATE_TRANS_ID: cur_row_.cells_[i].set_int(lock_op.create_trans_id_.get_id()); diff --git a/src/observer/virtual_table/ob_all_virtual_table_mgr.cpp b/src/observer/virtual_table/ob_all_virtual_table_mgr.cpp index 78ad19983..eaf48f507 100644 --- a/src/observer/virtual_table/ob_all_virtual_table_mgr.cpp +++ b/src/observer/virtual_table/ob_all_virtual_table_mgr.cpp @@ -29,8 +29,7 @@ ObAllVirtualTableMgr::ObAllVirtualTableMgr() tablet_allocator_("VTTable"), tablet_handle_(), ls_id_(share::ObLSID::INVALID_LS_ID), - all_tables_(), - table_idx_(0), + table_store_iter_(), iter_buf_(nullptr) { } @@ -46,8 +45,7 @@ void ObAllVirtualTableMgr::reset() omt::ObMultiTenantOperator::reset(); addr_.reset(); ls_id_ = share::ObLSID::INVALID_LS_ID; - all_tables_.reset(); - table_idx_ = 0; + table_store_iter_.reset(); if (OB_NOT_NULL(iter_buf_)) { allocator_->free(iter_buf_); @@ -141,50 +139,29 @@ int ObAllVirtualTableMgr::get_next_table(ObITable *&table) { int ret = OB_SUCCESS; table = nullptr; - if (table_idx_ < all_tables_.count()) { - table = all_tables_.at(table_idx_); - ++table_idx_; - } else { - all_tables_.reuse(); - ObArray sst_tables; - while (OB_SUCC(ret)) { - if (OB_FAIL(get_next_tablet())) { - if (OB_ITER_END != ret) { - SERVER_LOG(WARN, "fail to get next tablet", K(ret)); - } - } else if (OB_UNLIKELY(!tablet_handle_.is_valid())) { - ret = OB_ERR_UNEXPECTED; - SERVER_LOG(WARN, "unexpected invalid tablet", K(ret), K_(tablet_handle)); - } else if (OB_FAIL(tablet_handle_.get_obj()->get_memtables(all_tables_, true/*need_active*/))) { - SERVER_LOG(WARN, "fail to get mem tables", K(ret), K(tablet_handle_)); - } - if (OB_SUCC(ret)) { - if (OB_FAIL(tablet_handle_.get_obj()->get_all_sstables(sst_tables))) { - SERVER_LOG(WARN, "fail to get sstables", K(ret), K(tablet_handle_)); - } else { - for (int i = 0; OB_SUCC(ret) && i < sst_tables.count(); ++i) { - if (OB_FAIL(all_tables_.push_back(sst_tables.at(i)))) { - SERVER_LOG(WARN, "fail to push back sstables", K(ret), K(tablet_handle_)); - } + if (OB_FAIL(table_store_iter_.get_next(table))) { + if (OB_UNLIKELY(ret != OB_ITER_END)) { + SERVER_LOG(WARN, "fail to iterate next table", K(ret)); + } else { + ret = OB_SUCCESS; + while (OB_SUCC(ret)) { + table_store_iter_.reset(); + if (OB_FAIL(get_next_tablet())) { + if (OB_ITER_END != ret) { + SERVER_LOG(WARN, "fail to get next tablet", K(ret)); } + } else if (OB_UNLIKELY(!tablet_handle_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "unexpected invalid tablet", K(ret), K_(tablet_handle)); + } else if (OB_FAIL(tablet_handle_.get_obj()->get_all_tables(table_store_iter_))) { + SERVER_LOG(WARN, "fail to get all tables", K(ret), K_(tablet_handle), K_(table_store_iter)); + } else if (0 != table_store_iter_.count()) { + break; } } - if (OB_SUCC(ret)) { - if (OB_FAIL(tablet_handle_.get_obj()->get_ddl_memtables(sst_tables))) { - SERVER_LOG(WARN, "fail to get ddl memtables", K(ret), K(tablet_handle_)); - } else { - for (int i = 0; OB_SUCC(ret) && i < sst_tables.count(); ++i) { - if (OB_FAIL(all_tables_.push_back(sst_tables.at(i)))) { - SERVER_LOG(WARN, "fail to push back sstables", K(ret), K(tablet_handle_)); - } - } - } - } - if (OB_SUCC(ret) && all_tables_.count() > 0) { - table_idx_ = 0; - table = all_tables_.at(table_idx_); - ++table_idx_; - break; + if (OB_FAIL(ret)) { + } else if (OB_FAIL(table_store_iter_.get_next(table))) { + SERVER_LOG(WARN, "fail to get table after switch tablet", K(ret)); } } } @@ -262,26 +239,45 @@ int ObAllVirtualTableMgr::process_curr_tenant(common::ObNewRow *&row) if (table->is_memtable()) { size = static_cast(table)->get_occupied_size(); } else if (table->is_sstable()) { - size = static_cast(table)->get_meta().get_basic_meta().occupy_size_; + blocksstable::ObSSTableMetaHandle sst_meta_hdl; + if (OB_FAIL(static_cast(table)->get_meta(sst_meta_hdl))) { + SERVER_LOG(WARN, "fail to get sstable meta handle", K(ret)); + } else { + size = sst_meta_hdl.get_sstable_meta().get_occupy_size(); + } } cur_row_.cells_[i].set_int(size); break; } case DATA_BLOCK_CNT: { const int64_t blk_cnt = table->is_memtable() ? 0 - : static_cast(table)->get_meta().get_basic_meta().get_data_macro_block_count(); + : static_cast(table)->get_data_macro_block_count(); cur_row_.cells_[i].set_int(blk_cnt); break; } case INDEX_BLOCK_CNT: { - const int64_t blk_cnt = table->is_memtable() ? 0 - : static_cast(table)->get_meta().get_basic_meta().get_index_macro_block_count(); + int64_t blk_cnt = 0; + if (table->is_sstable()) { + blocksstable::ObSSTableMetaHandle sst_meta_hdl; + if (OB_FAIL(static_cast(table)->get_meta(sst_meta_hdl))) { + SERVER_LOG(WARN, "fail to get sstable meta handle", K(ret)); + } else { + blk_cnt = sst_meta_hdl.get_sstable_meta().get_index_macro_block_count(); + } + } cur_row_.cells_[i].set_int(blk_cnt); break; } case LINKED_BLOCK_CNT: { - const int64_t blk_cnt = table->is_memtable() ? 0 - : static_cast(table)->get_meta().get_macro_info().get_linked_block_ids().count(); + int64_t blk_cnt = 0; + if (table->is_sstable()) { + blocksstable::ObSSTableMetaHandle sst_meta_hdl; + if (OB_FAIL(static_cast(table)->get_meta(sst_meta_hdl))) { + SERVER_LOG(WARN, "fail to get sstable meta handle", K(ret)); + } else { + blk_cnt = sst_meta_hdl.get_sstable_meta().get_linked_macro_block_count(); + } + } cur_row_.cells_[i].set_int(blk_cnt); break; } @@ -302,7 +298,7 @@ int ObAllVirtualTableMgr::process_curr_tenant(common::ObNewRow *&row) if (table->is_memtable()) { contain_uncommitted_row = true; } else if (table->is_sstable()) { - contain_uncommitted_row = static_cast(table)->get_meta().contain_uncommitted_row(); + contain_uncommitted_row = static_cast(table)->contain_uncommitted_row(); } cur_row_.cells_[i].set_varchar(contain_uncommitted_row ? "YES" : "NO"); cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); diff --git a/src/observer/virtual_table/ob_all_virtual_table_mgr.h b/src/observer/virtual_table/ob_all_virtual_table_mgr.h index 3b9ba8f20..cf4868ab6 100644 --- a/src/observer/virtual_table/ob_all_virtual_table_mgr.h +++ b/src/observer/virtual_table/ob_all_virtual_table_mgr.h @@ -81,8 +81,7 @@ private: ObTabletHandle tablet_handle_; int64_t ls_id_; char ip_buf_[common::OB_IP_STR_BUFF]; - common::ObArray all_tables_; - int64_t table_idx_; + storage::ObTableStoreIterator table_store_iter_; void *iter_buf_; private: DISALLOW_COPY_AND_ASSIGN(ObAllVirtualTableMgr); diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_buffer_info.cpp b/src/observer/virtual_table/ob_all_virtual_tablet_buffer_info.cpp new file mode 100644 index 000000000..0ce05cfc2 --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_tablet_buffer_info.cpp @@ -0,0 +1,208 @@ +/** + * Copyright (c) 2021 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 "ob_all_virtual_tablet_buffer_info.h" + +namespace oceanbase +{ +using namespace storage; +using namespace blocksstable; +using namespace common; +namespace observer +{ +ObAllVirtualTabletBufferInfo::ObAllVirtualTabletBufferInfo() + : addr_(), index_(0), pool_type_(ObTabletPoolType::TP_MAX), buffer_infos_() +{ +} + +ObAllVirtualTabletBufferInfo::~ObAllVirtualTabletBufferInfo() +{ + reset(); +} + +void ObAllVirtualTabletBufferInfo::reset() +{ + omt::ObMultiTenantOperator::reset(); + addr_.reset(); + index_ = 0; + pool_type_ = ObTabletPoolType::TP_MAX; + buffer_infos_.reset(); + ObVirtualTableScannerIterator::reset(); +} + +int ObAllVirtualTabletBufferInfo::init(common::ObAddr &addr) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + SERVER_LOG(WARN, "invalid arg", K(ret), K(addr)); + } else if (OB_FAIL(OB_UNLIKELY(!addr.ip_to_string(ip_buf_, sizeof(ip_buf_))))) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "fail to transfer ip to string", K(ret)); + } else { + addr_ = addr; + } + return ret; +} + +int ObAllVirtualTabletBufferInfo::inner_get_next_row(common::ObNewRow *&row) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(execute(row))) { + SERVER_LOG(WARN, "fail to execute", K(ret)); + } + return ret; +} + +int ObAllVirtualTabletBufferInfo::get_tablet_pool_infos() +{ + int ret = OB_SUCCESS; + buffer_infos_.reuse(); + ObMemAttr attr(MTL_ID(), "TabletBuffer"); + buffer_infos_.set_attr(attr); + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + if (ObTabletPoolType::TP_MAX == pool_type_) { + pool_type_ = ObTabletPoolType::TP_NORMAL; + } else if (ObTabletPoolType::TP_NORMAL == pool_type_) { + pool_type_ = ObTabletPoolType::TP_LARGE; + } else { + pool_type_ = ObTabletPoolType::TP_MAX; + ret = OB_ITER_END; + } + + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(t3m->get_tablet_buffer_infos(pool_type_, buffer_infos_))) { + SERVER_LOG(WARN, "fail to get tablet buffer infos", K_(pool_type)); + } else { + index_ = 0; + } + return ret; +} + +bool ObAllVirtualTabletBufferInfo::is_need_process(uint64_t tenant_id) +{ + bool need_process = false; + if (!is_virtual_tenant_id(tenant_id) && + (is_sys_tenant(effective_tenant_id_) || tenant_id == effective_tenant_id_)){ + need_process = true; + } + return need_process; +} + +int ObAllVirtualTabletBufferInfo::process_curr_tenant(common::ObNewRow *&row) +{ + /** + int ret = OB_SUCCESS; + if (OB_ISNULL(cur_row_.cells_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(ERROR, "cur row cell is nullptr", K(ret)); + } else if (buffer_infos_.size() <= index_) { + if (OB_FAIL(get_tablet_pool_infos())) { + if (OB_ITER_END != ret) { + SERVER_LOG(WARN, "fail to get tablet pool infos", K(ret)); + } + } + } + + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(gen_row(buffer_infos_[index_], row))) { + SERVER_LOG(WARN, "fail to gen_row", K(ret)); + } else { + index_++; + } + return ret; + */ + UNUSED(row); + return OB_ITER_END; +} + +void ObAllVirtualTabletBufferInfo::release_last_tenant() +{ + buffer_infos_.reset(); +} + +int ObAllVirtualTabletBufferInfo::gen_row( + const ObTabletBufferInfo &buffer_info, + common::ObNewRow *&row) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < output_column_ids_.count(); i++) { + uint64_t col_id = output_column_ids_.at(i); + switch(col_id) { + case SVR_IP: + //svr_ip + cur_row_.cells_[i].set_varchar(ip_buf_); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + break; + case SVR_PORT: + //svr_port + cur_row_.cells_[i].set_int(addr_.get_port()); + break; + case TENANT_ID: + //tenant_id + cur_row_.cells_[i].set_int(MTL_ID()); + break; + case TABLET_BUFFER_PTR: + //tablet_buffer_ptr + MEMSET(tablet_buffer_pointer_, 0, STR_LEN); + pos = 0; + databuff_print_obj(tablet_buffer_pointer_, STR_LEN, pos, static_cast(buffer_info.tablet_buffer_ptr_)); + cur_row_.cells_[i].set_varchar(tablet_buffer_pointer_); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + break; + case TABLET_OBJ_PTR: + //tablet_obj_ptr + MEMSET(tablet_pointer_, 0, STR_LEN); + pos = 0; + databuff_print_obj(tablet_pointer_, STR_LEN, pos, static_cast(buffer_info.tablet_)); + cur_row_.cells_[i].set_varchar(tablet_pointer_); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + break; + case POOL_TYPE: + //pool_type + cur_row_.cells_[i].set_varchar(buffer_info.pool_type_ == ObTabletPoolType::TP_LARGE + ? "TP_LARGE" : "TP_NORMAL"); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + break; + case LS_ID: + //ls_id + cur_row_.cells_[i].set_int(buffer_info.ls_id_.id()); + break; + case TABLET_ID: + //tablet_id + cur_row_.cells_[i].set_int(buffer_info.tablet_id_.id()); + break; + case IN_MAP: + //in_map + cur_row_.cells_[i].set_bool(buffer_info.in_map_); + break; + case LAST_ACCESS_TIME: + //last_access_time + cur_row_.cells_[i].set_timestamp(buffer_info.last_access_time_ / 1000L); + break; + default:{ + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(ERROR, "invalid column_id", K(ret), K(col_id)); + } + } + } + if (OB_SUCC(ret)) { + row = &cur_row_; + } + return ret; +} + +} // observer +} // oceanbase \ No newline at end of file diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_buffer_info.h b/src/observer/virtual_table/ob_all_virtual_tablet_buffer_info.h new file mode 100644 index 000000000..b375f9c8f --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_tablet_buffer_info.h @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2021 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 SRC_OBSERVER_VIRTUAL_TABLE_OB_ALL_VIRTUAL_TABLET_BUFFER_INFO_H_ +#define SRC_OBSERVER_VIRTUAL_TABLE_OB_ALL_VIRTUAL_TABLET_BUFFER_INFO_H_ + +#include "common/row/ob_row.h" +#include "lib/guard/ob_shared_guard.h" +#include "observer/omt/ob_multi_tenant.h" +#include "share/ob_scanner.h" +#include "share/ob_virtual_table_scanner_iterator.h" +#include "share/rc/ob_tenant_base.h" +#include "observer/omt/ob_multi_tenant.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "observer/omt/ob_multi_tenant_operator.h" +#include "share/ob_ls_id.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" + +namespace oceanbase +{ +namespace observer +{ +class ObAllVirtualTabletBufferInfo : public common::ObVirtualTableScannerIterator, + public omt::ObMultiTenantOperator +{ + enum COLUMN_ID_LIST + { + SVR_IP = common::OB_APP_MIN_COLUMN_ID, + SVR_PORT, + TENANT_ID, + TABLET_BUFFER_PTR, + TABLET_OBJ_PTR, + POOL_TYPE, + LS_ID, + TABLET_ID, + IN_MAP, + LAST_ACCESS_TIME + }; +public: + ObAllVirtualTabletBufferInfo(); + virtual ~ObAllVirtualTabletBufferInfo(); + virtual void reset(); + int init(common::ObAddr &addr); + virtual int inner_get_next_row(common::ObNewRow *&row); + +private: + int get_tablet_pool_infos(); + int gen_row(const ObTabletBufferInfo &buffer_info, common::ObNewRow *&row); + virtual bool is_need_process(uint64_t tenant_id) override; + virtual int process_curr_tenant(common::ObNewRow *&row) override; + virtual void release_last_tenant() override; + +private: + static const int64_t STR_LEN = 128; +private: + common::ObAddr addr_; + char ip_buf_[common::OB_IP_STR_BUFF]; + int64_t index_; + ObTabletPoolType pool_type_; + ObSArray buffer_infos_; + char tablet_pointer_[STR_LEN]; + char tablet_buffer_pointer_[STR_LEN]; +}; +} // observer +} // oceanbase +#endif \ No newline at end of file diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_compaction_history.cpp b/src/observer/virtual_table/ob_all_virtual_tablet_compaction_history.cpp index dac7b69c1..d4e8553f3 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_compaction_history.cpp +++ b/src/observer/virtual_table/ob_all_virtual_tablet_compaction_history.cpp @@ -26,12 +26,9 @@ ObAllVirtualTabletCompactionHistory::ObAllVirtualTabletCompactionHistory() participant_table_str_(), macro_id_list_(), comment_(), - major_info_idx_(0), - major_info_cnt_(0), - minor_info_idx_(0), - minor_info_cnt_(0), merge_info_(), - get_info_cnt_flag_(true) + major_merge_info_iter_(), + minor_merge_info_iter_() { } @@ -67,29 +64,20 @@ int ObAllVirtualTabletCompactionHistory::process_curr_tenant(ObNewRow *&row) ObObj *cells = cur_row_.cells_; int64_t compression_ratio = 0; int n = 0; - if (get_info_cnt_flag_) { - major_info_cnt_ = MTL(ObTenantSSTableMergeInfoMgr *)->get_major_info_array_cnt(); - minor_info_cnt_ = MTL(ObTenantSSTableMergeInfoMgr *)->get_minor_info_array_cnt(); - get_info_cnt_flag_ = false; + if (!major_merge_info_iter_.is_opened() && !minor_merge_info_iter_.is_opened()) { + if (OB_FAIL(MTL(ObTenantSSTableMergeInfoMgr *)->open_iter(major_merge_info_iter_, minor_merge_info_iter_))) { + STORAGE_LOG(WARN, "fail to open ObTenantSSTableMergeInfoMgr::Iterator", K(ret)); + } } - while (OB_SUCC(ret)) { - if (major_info_idx_ < major_info_cnt_) { - if (OB_FAIL(MTL(ObTenantSSTableMergeInfoMgr *)->get_major_info(major_info_idx_, merge_info_))) { - STORAGE_LOG(WARN, "Fail to get merge info", K(ret), K_(major_info_idx)); - } else { - major_info_idx_++; - break; + if (OB_SUCC(ret)) { + if (FALSE_IT(MEMSET(comment_, '\0', sizeof(comment_)))) { + } else if (OB_FAIL(ObTenantSSTableMergeInfoMgr::get_next_info(major_merge_info_iter_, + minor_merge_info_iter_, + merge_info_, comment_, sizeof(comment_)))){ + if (OB_ITER_END != ret) { + STORAGE_LOG(WARN, "fail to get next sstable merge info", K(ret)); } - } else if (minor_info_idx_ < minor_info_cnt_) { - if (OB_FAIL(MTL(ObTenantSSTableMergeInfoMgr *)->get_minor_info(minor_info_idx_, merge_info_))) { - STORAGE_LOG(WARN, "Fail to get merge info", K(ret), K_(minor_info_idx)); - } else { - minor_info_idx_++; - break; - } - } else { - ret = OB_ITER_END; } } @@ -203,7 +191,7 @@ int ObAllVirtualTabletCompactionHistory::process_curr_tenant(ObNewRow *&row) break; case PARTICIPANT_TABLE_INFO: MEMSET(participant_table_str_, '\0', sizeof(participant_table_str_)); - MEMCPY(participant_table_str_, merge_info_.participant_table_str_, strlen(merge_info_.participant_table_str_)); + merge_info_.participant_table_info_.fill_info(participant_table_str_, sizeof(participant_table_str_)); cells[i].set_varchar(participant_table_str_); cells[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; @@ -214,8 +202,7 @@ int ObAllVirtualTabletCompactionHistory::process_curr_tenant(ObNewRow *&row) cells[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; case COMMENT: - MEMSET(comment_, '\0', sizeof(comment_)); - MEMCPY(comment_, merge_info_.comment_, strlen(merge_info_.comment_)); + merge_info_.fill_comment(comment_, sizeof(comment_)); cells[i].set_varchar(comment_); cells[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_compaction_history.h b/src/observer/virtual_table/ob_all_virtual_tablet_compaction_history.h index 055ee1ff9..2e251ea60 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_compaction_history.h +++ b/src/observer/virtual_table/ob_all_virtual_tablet_compaction_history.h @@ -14,6 +14,7 @@ #define OB_ALL_VIRTUAL_TABLET_COMPACTION_HISTORY_H_ #include "share/ob_virtual_table_scanner_iterator.h" #include "storage/compaction/ob_sstable_merge_info_mgr.h" +#include "storage/compaction/ob_compaction_diagnose.h" #include "storage/ob_sstable_struct.h" #include "observer/omt/ob_multi_tenant_operator.h" @@ -66,11 +67,8 @@ private: virtual int process_curr_tenant(common::ObNewRow *&row) override; virtual void release_last_tenant() override { - major_info_idx_ = 0; - major_info_cnt_ = 0; - minor_info_idx_ = 0; - minor_info_cnt_ = 0; - get_info_cnt_flag_ = true; + major_merge_info_iter_.reset(); + minor_merge_info_iter_.reset(); } private: char ip_buf_[common::OB_IP_STR_BUFF]; @@ -79,12 +77,9 @@ private: char participant_table_str_[common::OB_PART_TABLE_INFO_LENGTH]; char macro_id_list_[common::OB_MACRO_ID_INFO_LENGTH]; char comment_[common::OB_COMPACTION_EVENT_STR_LENGTH]; - int64_t major_info_idx_; - int64_t major_info_cnt_; - int64_t minor_info_idx_; - int64_t minor_info_cnt_; ObSSTableMergeInfo merge_info_; - bool get_info_cnt_flag_; + compaction::ObIDiagnoseInfoMgr::Iterator major_merge_info_iter_; + compaction::ObIDiagnoseInfoMgr::Iterator minor_merge_info_iter_; DISALLOW_COPY_AND_ASSIGN(ObAllVirtualTabletCompactionHistory); }; diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_compaction_info.cpp b/src/observer/virtual_table/ob_all_virtual_tablet_compaction_info.cpp index f9bd0a59d..56d26de63 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_compaction_info.cpp +++ b/src/observer/virtual_table/ob_all_virtual_tablet_compaction_info.cpp @@ -141,6 +141,8 @@ int ObAllVirtualTabletCompactionInfo::process_curr_tenant(common::ObNewRow *&row int ret = OB_SUCCESS; ObTablet *tablet = nullptr; ObITable *table = nullptr; + ObArenaAllocator allocator; + const compaction::ObMediumCompactionInfoList *medium_info_list = nullptr; if (OB_UNLIKELY(!start_to_read_)) { ret = OB_NOT_INIT; SERVER_LOG(WARN, "not inited", K(start_to_read_), K(ret)); @@ -154,8 +156,9 @@ int ObAllVirtualTabletCompactionInfo::process_curr_tenant(common::ObNewRow *&row } else if (OB_ISNULL(tablet = tablet_handle_.get_obj())) { ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "tablet is null", K(ret), K(tablet_handle_)); + } else if (OB_FAIL(tablet->read_medium_info_list(allocator, medium_info_list))) { + SERVER_LOG(WARN, "tablet read medium info list failed", K(ret), K(tablet_handle_)); } else { - const compaction::ObMediumCompactionInfoList &medium_info_list = tablet->get_medium_compaction_info_list(); const int64_t col_count = output_column_ids_.count(); int64_t max_sync_medium_scn = 0; for (int64_t i = 0; OB_SUCC(ret) && i < col_count; ++i) { @@ -182,12 +185,18 @@ int ObAllVirtualTabletCompactionInfo::process_curr_tenant(common::ObNewRow *&row case TABLET_ID: cur_row_.cells_[i].set_int(tablet->get_tablet_meta().tablet_id_.id()); break; - case FINISH_SCN: - table = tablet->get_table_store().get_major_sstables().get_boundary_table(true/*last*/); - cur_row_.cells_[i].set_int(nullptr == table ? 0 : table->get_snapshot_version()); + case FINISH_SCN: { + ObTabletMemberWrapper table_store_wrapper; + if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + SERVER_LOG(WARN, "fail to fetch table store", K(ret)); + } else { + table = table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/); + cur_row_.cells_[i].set_int(nullptr == table ? 0 : table->get_snapshot_version()); + } break; + } case WAIT_CHECK_SCN: - cur_row_.cells_[i].set_int(medium_info_list.get_wait_check_medium_scn()); + cur_row_.cells_[i].set_int(medium_info_list->get_wait_check_medium_scn()); break; case MAX_RECEIVED_SCN: if (OB_SUCCESS == tablet->get_max_sync_medium_scn(max_sync_medium_scn)) { @@ -197,9 +206,9 @@ int ObAllVirtualTabletCompactionInfo::process_curr_tenant(common::ObNewRow *&row } break; case SERIALIZE_SCN_LIST: - if (medium_info_list.size() > 0 || compaction::ObMediumCompactionInfo::MAJOR_COMPACTION == medium_info_list.get_last_compaction_type()) { + if (medium_info_list->size() > 0 || compaction::ObMediumCompactionInfo::MAJOR_COMPACTION == medium_info_list->get_last_compaction_type()) { int64_t pos = 0; - medium_info_list.gene_info(medium_info_buf_, OB_MAX_VARCHAR_LENGTH, pos); + medium_info_list->gene_info(medium_info_buf_, OB_MAX_VARCHAR_LENGTH, pos); cur_row_.cells_[i].set_varchar(medium_info_buf_); SERVER_LOG(DEBUG, "get medium info mgr", K(medium_info_list), K(medium_info_buf_)); } else { diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_ddl_kv_info.cpp b/src/observer/virtual_table/ob_all_virtual_tablet_ddl_kv_info.cpp index e9911d8c6..5b6d9c8c1 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_ddl_kv_info.cpp +++ b/src/observer/virtual_table/ob_all_virtual_tablet_ddl_kv_info.cpp @@ -27,7 +27,7 @@ ObAllVirtualTabletDDLKVInfo::ObAllVirtualTabletDDLKVInfo() addr_(), ls_id_(share::ObLSID::INVALID_LS_ID), ls_iter_guard_(), - ls_tablet_iter_(), + ls_tablet_iter_(ObMDSGetTabletMode::READ_READABLE_COMMITED), ddl_kvs_handle_(), curr_tablet_id_(), ddl_kv_idx_(-1) diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_info.cpp b/src/observer/virtual_table/ob_all_virtual_tablet_info.cpp index 1c014f218..365718ca7 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_info.cpp +++ b/src/observer/virtual_table/ob_all_virtual_tablet_info.cpp @@ -28,7 +28,7 @@ ObAllVirtualTabletInfo::ObAllVirtualTabletInfo() addr_(), ls_id_(share::ObLSID::INVALID_LS_ID), ls_iter_guard_(), - ls_tablet_iter_() + ls_tablet_iter_(ObMDSGetTabletMode::READ_WITHOUT_CHECK) { } @@ -127,6 +127,8 @@ int ObAllVirtualTabletInfo::process_curr_tenant(ObNewRow *&row) int ret = OB_SUCCESS; ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData latest_user_data; + bool is_committed = false; if (NULL == allocator_) { ret = OB_NOT_INIT; SERVER_LOG(WARN, "allocator_ shouldn't be NULL", K(allocator_), K(ret)); @@ -143,6 +145,8 @@ int ObAllVirtualTabletInfo::process_curr_tenant(ObNewRow *&row) } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "tablet should not null", K(ret), K(tablet_handle)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_latest_tablet_status(latest_user_data, is_committed))) { + SERVER_LOG(WARN, "failed to get latest tablet status", K(ret), KPC(tablet)); } else { const ObTabletMeta &tablet_meta = tablet->get_tablet_meta(); const int64_t col_count = output_column_ids_.count(); @@ -196,6 +200,40 @@ int ObAllVirtualTabletInfo::process_curr_tenant(ObNewRow *&row) // multi_version_start cur_row_.cells_[i].set_uint64(tablet_meta.multi_version_start_); break; + case OB_APP_MIN_COLUMN_ID + 10: + // transfer_start_scn + cur_row_.cells_[i].set_uint64(tablet_meta.transfer_info_.transfer_start_scn_.get_val_for_inner_table_field()); + break; + case OB_APP_MIN_COLUMN_ID + 11: + // transfer_seq + cur_row_.cells_[i].set_int(tablet_meta.transfer_info_.transfer_seq_); + break; + case OB_APP_MIN_COLUMN_ID + 12: + // has_transfer_table + cur_row_.cells_[i].set_int(tablet_meta.transfer_info_.has_transfer_table() ? 1 : 0); + break; + case OB_APP_MIN_COLUMN_ID + 13: { + // restore_status + ObTabletRestoreStatus::STATUS restore_status; + if (OB_FAIL(tablet_meta.ha_status_.get_restore_status(restore_status))) { + SERVER_LOG(WARN, "failed to get restore status", K(ret), K(tablet_meta)); + } else { + cur_row_.cells_[i].set_int(restore_status); + } + } + break; + case OB_APP_MIN_COLUMN_ID + 14: + // tablet_status + cur_row_.cells_[i].set_int(static_cast(latest_user_data.get_tablet_status())); + break; + case OB_APP_MIN_COLUMN_ID + 15: + // is_committed + cur_row_.cells_[i].set_int(is_committed ? 1 : 0); + break; + case OB_APP_MIN_COLUMN_ID + 16: + // is_empty_shell + cur_row_.cells_[i].set_int(tablet->is_empty_shell() ? 1 : 0); + break; default: ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "invalid col_id", K(ret), K(col_id)); diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_pointer_status.cpp b/src/observer/virtual_table/ob_all_virtual_tablet_pointer_status.cpp index 33679a30d..d8b8638f5 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_pointer_status.cpp +++ b/src/observer/virtual_table/ob_all_virtual_tablet_pointer_status.cpp @@ -126,6 +126,7 @@ int ObAllVirtualTabletPtr::process_curr_tenant(ObNewRow *&row) ObTabletPointerHandle ptr_hdl; ObTabletHandle tablet_hdl; ObTablet *tablet = nullptr; + int64_t pos = 0; const ObTabletPointer *tablet_pointer = nullptr; share::ObLSID ls_id; ObTabletID tablet_id; @@ -171,7 +172,7 @@ int ObAllVirtualTabletPtr::process_curr_tenant(ObNewRow *&row) cur_row_.cells_[i].set_int(tablet_id.id()); break; case ADDRESS: - tablet_pointer->get_addr().to_string(address_, ADDRESS_LEN); + tablet_pointer->get_addr().to_string(address_, STR_LEN); cur_row_.cells_[i].set_varchar(address_); cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; @@ -187,6 +188,25 @@ int ObAllVirtualTabletPtr::process_curr_tenant(ObNewRow *&row) case WASH_SCORE: cur_row_.cells_[i].set_int(nullptr == tablet ? 0 : tablet->get_wash_score()); break; + case TABLET_PTR: + MEMSET(pointer_, 0, STR_LEN); + pos = 0; + databuff_print_obj(pointer_, STR_LEN, pos, static_cast(tablet)); + cur_row_.cells_[i].set_varchar(pointer_); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + break; + case INITIAL_STATE: + cur_row_.cells_[i].set_bool(tablet_pointer->get_initial_state()); + break; + case OLD_CHAIN: + MEMSET(old_chain_, 0, STR_LEN); + if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->print_old_chain(key, *tablet_pointer, STR_LEN, old_chain_))) { + SERVER_LOG(WARN, "fail to print old chain", K(ret), K(key), KPC(tablet_pointer)); + } else { + cur_row_.cells_[i].set_varchar(old_chain_); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + } + break; default: ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "invalid col_id", K(ret), K(col_id)); diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_pointer_status.h b/src/observer/virtual_table/ob_all_virtual_tablet_pointer_status.h index 7895ce145..9ed4f815f 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_pointer_status.h +++ b/src/observer/virtual_table/ob_all_virtual_tablet_pointer_status.h @@ -48,7 +48,10 @@ private: POINTER_REF, IN_MEMORY, TABLET_REF, - WASH_SCORE + WASH_SCORE, + TABLET_PTR, + INITIAL_STATE, + OLD_CHAIN }; public: ObAllVirtualTabletPtr(); @@ -63,18 +66,19 @@ private: virtual int process_curr_tenant(common::ObNewRow *&row) override; // 释放上一个租户的资源 virtual void release_last_tenant() override; - int get_next_tablet_pointer( ObTabletMapKey &tablet_key, ObTabletPointerHandle &pointer_handle, ObTabletHandle &tablet_handle); private: - static const int64_t ADDRESS_LEN = 128; + static const int64_t STR_LEN = 128; private: common::ObAddr addr_; char ip_buf_[common::OB_IP_STR_BUFF]; - char address_[ADDRESS_LEN]; + char address_[STR_LEN]; + char pointer_[STR_LEN]; + char old_chain_[STR_LEN]; /* 跨租户访问的资源必须由ObMultiTenantOperator来处理释放*/ storage::ObTenantTabletPtrWithInMemObjIterator *tablet_iter_; void *iter_buf_; diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.cpp b/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.cpp index afe4827b2..af532460a 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.cpp +++ b/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.cpp @@ -71,15 +71,16 @@ ObAllVirtualTabletSSTableMacroInfo::ObAllVirtualTabletSSTableMacroInfo() tablet_iter_(nullptr), tablet_allocator_("VTTable"), tablet_handle_(), + cols_desc_(), ls_id_(share::ObLSID::INVALID_LS_ID), - all_tables_(), + table_store_iter_(), curr_sstable_(nullptr), + curr_sstable_meta_handle_(), macro_iter_(nullptr), - other_block_idx_(-1), + other_blk_iter_(), iter_allocator_(), rowkey_allocator_(), curr_range_(), - table_idx_(0), block_idx_(0), iter_buf_(nullptr) { @@ -95,22 +96,23 @@ void ObAllVirtualTabletSSTableMacroInfo::reset() omt::ObMultiTenantOperator::reset(); addr_.reset(); ls_id_ = share::ObLSID::INVALID_LS_ID; - all_tables_.reset(); - table_idx_ = 0; + table_store_iter_.reset(); block_idx_ = 0; tablet_handle_.reset(); + cols_desc_.reset(); if (OB_NOT_NULL(iter_buf_)) { allocator_->free(iter_buf_); iter_buf_ = nullptr; } curr_sstable_ = nullptr; + curr_sstable_meta_handle_.reset(); if (OB_NOT_NULL(macro_iter_)) { macro_iter_->~ObIMacroBlockIterator(); macro_iter_ = nullptr; } curr_range_.reset(); - other_block_idx_ = -1; + other_blk_iter_.reset(); memset(objs_, 0, sizeof(objs_)); iter_allocator_.reset(); rowkey_allocator_.reset(); @@ -148,20 +150,24 @@ int ObAllVirtualTabletSSTableMacroInfo::get_next_macro_info(MacroInfo &info) blocksstable::ObDataMacroBlockMeta macro_meta; macro_desc.macro_meta_ = ¯o_meta; while (OB_SUCC(ret)) { - if (OB_ISNULL(macro_iter_) && -1 == other_block_idx_ && OB_FAIL(get_next_sstable())) { + if (OB_ISNULL(macro_iter_) && !other_blk_iter_.is_valid() && OB_FAIL(get_next_sstable())) { if (OB_ITER_END != ret) { SERVER_LOG(WARN, "fail to get next sstable", K(ret)); } } else if (OB_ISNULL(curr_sstable_)) { clean_cur_sstable(); - } else if (-1 != other_block_idx_) { - const ObIArray &blks = curr_sstable_->get_meta().get_macro_info().get_other_block_ids(); - if (blks.count() == other_block_idx_) { - other_block_idx_ = -1; - } else if (OB_FAIL(get_macro_info(blks.at(other_block_idx_), info))) { - SERVER_LOG(WARN, "fail to get macro info", K(ret), "macro_id", blks.at(other_block_idx_)); + } else if (other_blk_iter_.is_valid()) { + blocksstable::MacroBlockId macro_id; + if (OB_FAIL(other_blk_iter_.get_next_macro_id(macro_id))) { + if (OB_ITER_END != ret) { + SERVER_LOG(WARN, "fail to get next macro id", K(ret), K(other_blk_iter_)); + } else { + other_blk_iter_.reset(); + ret = OB_SUCCESS; + } + } else if (OB_FAIL(get_macro_info(macro_id, info))) { + SERVER_LOG(WARN, "fail to get macro info", K(ret), "macro_id", macro_id); } else { - ++other_block_idx_; break; } } else if (OB_NOT_NULL(macro_iter_) && OB_FAIL(macro_iter_->get_next_macro_block(macro_desc))) { @@ -170,8 +176,10 @@ int ObAllVirtualTabletSSTableMacroInfo::get_next_macro_info(MacroInfo &info) } else { macro_iter_->~ObIMacroBlockIterator(); macro_iter_ = nullptr; - ++other_block_idx_; - ret = OB_SUCCESS; + if (OB_FAIL(curr_sstable_meta_handle_.get_sstable_meta().get_macro_info().get_other_block_iter( + other_blk_iter_))) { + STORAGE_LOG(WARN, "fail get other block iterator", K(ret), KPC(curr_sstable_)); + } } } else if (OB_FAIL(get_macro_info(macro_desc, info))) { SERVER_LOG(WARN, "fail to get macro info", K(ret), K(macro_desc)); @@ -238,11 +246,10 @@ int ObAllVirtualTabletSSTableMacroInfo::get_macro_info( { int ret = OB_SUCCESS; rowkey_allocator_.reuse(); - const ObTableReadInfo &read_info = tablet_handle_.get_obj()->get_index_read_info(); if (OB_UNLIKELY(!macro_desc.is_valid())) { ret = OB_INVALID_ARGUMENT; SERVER_LOG(WARN, "invalid argument", K(ret), K(macro_desc)); - } else if (OB_FAIL(macro_desc.range_.to_store_range(read_info.get_columns_desc(), + } else if (OB_FAIL(macro_desc.range_.to_store_range(cols_desc_, rowkey_allocator_, info.store_range_))) { SERVER_LOG(WARN, "fail to get store range", K(ret), K(macro_desc.range_)); @@ -444,8 +451,9 @@ void ObAllVirtualTabletSSTableMacroInfo::clean_cur_sstable() iter_allocator_.reuse(); curr_range_.set_whole_range(); curr_sstable_ = nullptr; + curr_sstable_meta_handle_.reset(); block_idx_ = 0; - other_block_idx_ = -1; + other_blk_iter_.reset(); } int ObAllVirtualTabletSSTableMacroInfo::inner_get_next_row(ObNewRow *&row) @@ -525,11 +533,21 @@ int ObAllVirtualTabletSSTableMacroInfo::get_next_tablet() } else if (OB_UNLIKELY(!tablet_handle_.is_valid())) { ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "unexpected invalid tablet", K(ret), K(tablet_handle_)); + } else if (tablet_handle_.get_obj()->is_empty_shell()) { } else { bool need_ignore = check_tablet_need_ignore(tablet_handle_.get_obj()->get_tablet_meta()); if (!need_ignore) { - ls_id_ = tablet_handle_.get_obj()->get_tablet_meta().ls_id_.id(); - break; + const ObIArray &cols_desc = tablet_handle_.get_obj()->get_rowkey_read_info().get_columns_desc(); + + cols_desc_.reuse(); + if (OB_FAIL(cols_desc_.assign(cols_desc))) { + SERVER_LOG(WARN, "fail to assign rowkey col desc, ", K(ret)); + } else if (OB_FAIL(ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(cols_desc_))) { + SERVER_LOG(WARN, "fail to add extra rowkey info, ", K(ret)); + } else { + ls_id_ = tablet_handle_.get_obj()->get_tablet_meta().ls_id_.id(); + break; + } } } } @@ -542,40 +560,47 @@ int ObAllVirtualTabletSSTableMacroInfo::get_next_sstable() bool need_ignore = false; clean_cur_sstable(); blocksstable::ObDatumRange curr_range; - if (table_idx_ < all_tables_.count()) { - curr_sstable_ = static_cast(all_tables_.at(table_idx_)); - ++table_idx_; - } else { - all_tables_.reuse(); - while (OB_SUCC(ret)) { - if (OB_FAIL(get_next_tablet())) { - if (OB_ITER_END != ret) { - SERVER_LOG(WARN, "fail to get next tablet", K(ret)); + ObITable *table = nullptr; + if (OB_FAIL(table_store_iter_.get_next(table))) { + if (OB_UNLIKELY(ret != OB_ITER_END)) { + SERVER_LOG(WARN, "fail to iterate next table", K(ret)); + } else { + ret = OB_SUCCESS; + while (OB_SUCC(ret)) { + table_store_iter_.reset(); + if (OB_FAIL(get_next_tablet())) { + if (OB_ITER_END != ret) { + SERVER_LOG(WARN, "fail to get next tablet", K(ret)); + } + } else if (OB_UNLIKELY(!tablet_handle_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "unexpected invalid tablet", K(ret), K_(tablet_handle)); + } else if (OB_FAIL(tablet_handle_.get_obj()->get_all_sstables(table_store_iter_))) { + SERVER_LOG(WARN, "fail to get all tables", K(ret), K_(tablet_handle), K_(table_store_iter)); + } else if (0 != table_store_iter_.count()) { + break; } - } else if (OB_UNLIKELY(!tablet_handle_.is_valid())) { - ret = OB_ERR_UNEXPECTED; - SERVER_LOG(WARN, "unexpected invalid tablet", K(ret), K(tablet_handle_)); - } else if (OB_FAIL(tablet_handle_.get_obj()->get_all_sstables(all_tables_))) { - SERVER_LOG(WARN, "fail to get sstables", K(ret), K(tablet_handle_)); - } else if (all_tables_.count() > 0) { - table_idx_ = 0; - curr_sstable_ = static_cast(all_tables_.at(table_idx_)); - ++table_idx_; - break; + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(table_store_iter_.get_next(table))) { + SERVER_LOG(WARN, "fail to get table after switch tablet", K(ret)); } } } + if (OB_FAIL(ret)) { - } else if (OB_ISNULL(curr_sstable_)) { + } else if (OB_ISNULL(curr_sstable_ = static_cast(table))) { ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "unexpected null curr sstable", K(ret)); } else { - if (curr_sstable_->get_meta().is_empty() + if (curr_sstable_->is_empty() || check_sstable_need_ignore(curr_sstable_->get_key())) { clean_cur_sstable(); + } else if (OB_FAIL(curr_sstable_->get_meta(curr_sstable_meta_handle_))) { + SERVER_LOG(WARN, "fail to get curr sstable meta handle", K(ret)); } else if (OB_FAIL(curr_sstable_->scan_macro_block( curr_range_, - tablet_handle_.get_obj()->get_index_read_info(), + tablet_handle_.get_obj()->get_rowkey_read_info(), iter_allocator_, macro_iter_, false, diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.h b/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.h index c466012c4..1dc7f520d 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.h +++ b/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.h @@ -124,18 +124,19 @@ private: ObTenantTabletIterator *tablet_iter_; common::ObArenaAllocator tablet_allocator_; ObTabletHandle tablet_handle_; + common::ObSEArray cols_desc_; int64_t ls_id_; char ip_buf_[common::OB_IP_STR_BUFF]; char range_buf_[common::OB_MAX_RANGE_LENGTH + 1]; // extra byte for '\0' - common::ObSEArray all_tables_; + storage::ObTableStoreIterator table_store_iter_; blocksstable::ObSSTable *curr_sstable_; + blocksstable::ObSSTableMetaHandle curr_sstable_meta_handle_; blocksstable::ObIMacroBlockIterator *macro_iter_; - int64_t other_block_idx_; + blocksstable::ObMacroIdIterator other_blk_iter_; ObArenaAllocator iter_allocator_; ObArenaAllocator rowkey_allocator_; blocksstable::ObDatumRange curr_range_; common::ObObj objs_[common::OB_MAX_ROWKEY_COLUMN_NUMBER]; - int64_t table_idx_; int64_t block_idx_; void *iter_buf_; private: diff --git a/src/observer/virtual_table/ob_all_virtual_tx_data_table.cpp b/src/observer/virtual_table/ob_all_virtual_tx_data_table.cpp index 0dbf0343c..7d211bc40 100644 --- a/src/observer/virtual_table/ob_all_virtual_tx_data_table.cpp +++ b/src/observer/virtual_table/ob_all_virtual_tx_data_table.cpp @@ -68,6 +68,7 @@ int ObAllVirtualTxDataTable::process_curr_tenant(common::ObNewRow *&row) int ret = OB_SUCCESS; ObITable *tx_data_table = nullptr; + RowData row_data; if (nullptr == allocator_) { ret = OB_NOT_INIT; @@ -83,9 +84,9 @@ int ObAllVirtualTxDataTable::process_curr_tenant(common::ObNewRow *&row) } else if (OB_UNLIKELY(nullptr == tx_data_table)) { ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "tx_data_table shouldn't nullptr here", KR(ret), KP(tx_data_table)); + } else if (OB_FAIL(prepare_row_data_(tx_data_table, row_data))) { + SERVER_LOG(WARN, "prepare_row_data_ fail", KR(ret), KP(tx_data_table)); } else { - RowData row_data; - prepare_row_data_(tx_data_table, row_data); const int64_t col_count = output_column_ids_.count(); for (int64_t i = 0; OB_SUCC(ret) && i < col_count; ++i) { uint64_t col_id = output_column_ids_.at(i); @@ -161,6 +162,7 @@ int ObAllVirtualTxDataTable::get_next_tx_data_table_(ObITable *&tx_data_table) sstable_handles_.reset(); tablet_handle_.reset(); mgr_handle_.reset(); + ObTabletMemberWrapper table_store_wrapper; if (OB_FAIL(ls_iter_guard_->get_next(ls))) { if (OB_ITER_END != ret) { @@ -175,7 +177,10 @@ int ObAllVirtualTxDataTable::get_next_tx_data_table_(ObITable *&tx_data_table) } else if (OB_FAIL(ls->get_tablet_svr()->get_tablet(LS_TX_DATA_TABLET, tablet_handle_))) { SERVER_LOG(WARN, "fail to get tx data tablet", KR(ret)); } else if (FALSE_IT(tablet = tablet_handle_.get_obj())) { - } else if (OB_FAIL(tablet->get_table_store().get_minor_sstables().get_all_tables(sstable_handles_))) { + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + SERVER_LOG(WARN, "fail to fetch table store", K(ret)); + } else if (OB_FAIL( + table_store_wrapper.get_member()->get_minor_sstables().get_all_tables(sstable_handles_))) { SERVER_LOG(WARN, "fail to get sstable handles", KR(ret)); } else { // iterate from the newest memtable in memtable handles @@ -199,8 +204,9 @@ int ObAllVirtualTxDataTable::get_next_tx_data_table_(ObITable *&tx_data_table) return ret; } -void ObAllVirtualTxDataTable::prepare_row_data_(ObITable *tx_data_table, RowData &row_data) +int ObAllVirtualTxDataTable::prepare_row_data_(ObITable *tx_data_table, RowData &row_data) { + int ret = OB_SUCCESS; if (ObITable::TableType::TX_DATA_MEMTABLE == tx_data_table->get_key().table_type_) { ObTxDataMemtable *tx_data_memtable = static_cast(tx_data_table); row_data.state_ = tx_data_memtable->get_state_string(); @@ -209,13 +215,19 @@ void ObAllVirtualTxDataTable::prepare_row_data_(ObITable *tx_data_table, RowData row_data.max_tx_scn_ = tx_data_memtable->get_max_tx_scn(); } else if (tx_data_table->is_multi_version_minor_sstable()) { ObSSTable *tx_data_sstable = static_cast(tx_data_table); - row_data.state_ = ObITable::get_table_type_name(tx_data_table->get_key().table_type_); - row_data.tx_data_count_ = tx_data_sstable->get_meta().get_row_count(); - row_data.min_tx_scn_ = tx_data_sstable->get_filled_tx_scn(); - row_data.max_tx_scn_ = tx_data_sstable->get_key().scn_range_.end_scn_; + ObSSTableMetaHandle sstable_meta_hdl; + if (OB_FAIL(tx_data_sstable->get_meta(sstable_meta_hdl))) { + STORAGE_LOG(WARN, "fail to get sstable meta handle", K(ret), KPC(tx_data_sstable)); + } else { + row_data.state_ = ObITable::get_table_type_name(tx_data_table->get_key().table_type_); + row_data.tx_data_count_ = sstable_meta_hdl.get_sstable_meta().get_row_count(); + row_data.min_tx_scn_ = sstable_meta_hdl.get_sstable_meta().get_filled_tx_scn(); + row_data.max_tx_scn_ = tx_data_sstable->get_key().scn_range_.end_scn_; + } } else { STORAGE_LOG_RET(WARN, OB_ERR_UNEXPECTED, "Iterate an invalid table while select virtual tx data table."); } + return ret; } } // namespace observer diff --git a/src/observer/virtual_table/ob_all_virtual_tx_data_table.h b/src/observer/virtual_table/ob_all_virtual_tx_data_table.h index 23734dd7f..5cdf79b23 100644 --- a/src/observer/virtual_table/ob_all_virtual_tx_data_table.h +++ b/src/observer/virtual_table/ob_all_virtual_tx_data_table.h @@ -60,7 +60,7 @@ public: private: int get_next_tx_data_table_(ObITable *&tx_data_memtable); - void prepare_row_data_(ObITable *tx_data_table, RowData &row_data); + int prepare_row_data_(ObITable *tx_data_table, RowData &row_data); virtual bool is_need_process(uint64_t tenant_id) override; diff --git a/src/observer/virtual_table/ob_mds_event_buffer.h b/src/observer/virtual_table/ob_mds_event_buffer.h new file mode 100644 index 000000000..00d94f9dd --- /dev/null +++ b/src/observer/virtual_table/ob_mds_event_buffer.h @@ -0,0 +1,304 @@ +#ifndef VEITUAL_TABLE_OB_MDS_EVENT_BUFFER_H +#define VEITUAL_TABLE_OB_MDS_EVENT_BUFFER_H + +#include "lib/ob_define.h" +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/string/ob_string.h" +#include "share/cache/ob_vtable_event_recycle_buffer.h" +#include "common/ob_tablet_id.h" +#include "share/ob_ls_id.h" +#include "storage/multi_data_source/runtime_utility/common_define.h" +#include "util/easy_time.h" +#include "share/ob_task_define.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +class MdsTableBase; +template +class MdsUnit; +template +class MdsRow; +template +class UserMdsNode; +} +} +namespace observer +{ +class ObAllVirtualMdsEventHistory; +class ObMdsEventBuffer; +struct MdsEventKey { + MdsEventKey() = default; + MdsEventKey(uint64_t tenant_id, share::ObLSID ls_id, common::ObTabletID tablet_id) + : tenant_id_(tenant_id), + ls_id_(ls_id), + tablet_id_(tablet_id) {} + bool operator<(const MdsEventKey &rhs) { + return tenant_id_ < rhs.tenant_id_ && ls_id_ < rhs.ls_id_ && tablet_id_ < rhs.tablet_id_; + } + bool operator==(const MdsEventKey &rhs) { + return tenant_id_ == rhs.tenant_id_ && ls_id_ == rhs.ls_id_ && tablet_id_ == rhs.tablet_id_; + } + uint64_t hash() const { + uint64_t hash = 0; + hash = murmurhash(&tenant_id_, sizeof(tenant_id_), hash); + hash = murmurhash(&tablet_id_, sizeof(tablet_id_), hash); + hash = murmurhash(&ls_id_, sizeof(ls_id_), hash); + return hash; + } + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(tablet_id)); + uint64_t tenant_id_; + share::ObLSID ls_id_; + common::ObTabletID tablet_id_; +}; + +struct MdsEvent { + friend class storage::mds::MdsTableBase; + template + friend class storage::mds::MdsUnit; + template + friend class storage::mds::MdsRow; + template + friend class storage::mds::UserMdsNode; + friend class ObAllVirtualMdsEventHistory; + friend class ObMdsEventBuffer; + MdsEvent() + : timestamp_(0), + event_(nullptr), + info_str_(), + unit_id_(UINT8_MAX), + writer_type_(storage::mds::WriterType::UNKNOWN_WRITER), + writer_id_(0), + seq_no_(0), + redo_scn_(), + end_scn_(), + trans_version_(), + node_type_(storage::mds::MdsNodeType::UNKNOWN_NODE), + state_(storage::mds::TwoPhaseCommitState::STATE_END), + key_str_(), + alloc_(nullptr) {} + ~MdsEvent() { + if (OB_NOT_NULL(alloc_)) { + if (!key_str_.empty()) { + alloc_->free(key_str_.ptr()); + } + if (!info_str_.empty()) { + alloc_->free(info_str_.ptr()); + } + } + new (this) MdsEvent(); + } + int assign(ObIAllocator &alloc, const MdsEvent &rhs) { + int ret = OB_SUCCESS; + if (!rhs.is_valid_()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG(WARN, "invalid argument", KR(ret), K(rhs)); + } else if (OB_FAIL(set_(alloc, rhs.timestamp_, rhs.event_, rhs.info_str_, rhs.unit_id_, rhs.writer_type_, + rhs.writer_id_, rhs.seq_no_, rhs.redo_scn_, rhs.end_scn_, rhs.trans_version_, + rhs.node_type_, rhs.state_, rhs.key_str_))) { + // don't report 4013, cause alloc use ring buffer, 4013 is expected + } else { + tid_ = rhs.tid_; + trace_id_ = rhs.trace_id_; + memcpy(tname_, rhs.tname_, 16); + } + return ret; + } + TO_STRING_KV(KP_(alloc), KTIME_(timestamp), K_(event), K_(info_str), K_(unit_id), K_(key_str), K_(writer_type), \ + K_(writer_id), K_(seq_no), K_(redo_scn), K_(end_scn), K_(trans_version), K_(node_type), K_(state)); +private: + bool is_valid_() const { return OB_NOT_NULL(event_); } + int set_(ObIAllocator &alloc, + int64_t timestamp, + const char *event_str, + const ObString &info_str, + uint8_t unit_id, + storage::mds::WriterType writer_type, + int64_t writer_id, + int64_t seq_no, + share::SCN redo_scn, + share::SCN end_scn, + share::SCN trans_version, + storage::mds::MdsNodeType node_type, + storage::mds::TwoPhaseCommitState state, + const ObString &key_str) { + #define PRINT_WRAPPER K(ret), K(event_str), K(unit_id), K(writer_type), K(writer_id), K(seq_no), K(redo_scn),\ + K(trans_version), K(node_type), K(state), K(key_str) + int ret = OB_SUCCESS; + if (is_valid_()) { + ret = OB_INIT_TWICE; + MDS_LOG(WARN, "this event has been valid", PRINT_WRAPPER, K(*this)); + } + if (OB_SUCC(ret) && !info_str.empty()) { + char *ptr = nullptr; + if (nullptr == (ptr = (char *)alloc.alloc(info_str.length()))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + // MDS_LOG(WARN, "fail to alloc memory", PRINT_WRAPPER); + } else { + memcpy(ptr, info_str.ptr(), info_str.length()); + info_str_.assign_ptr(ptr, info_str.length()); + } + } + if (OB_SUCC(ret) && !key_str.empty()) { + char *ptr = nullptr; + if (nullptr == (ptr = (char *)alloc.alloc(key_str.length()))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + // MDS_LOG(WARN, "fail to alloc memory", PRINT_WRAPPER); + } else { + memcpy(ptr, key_str.ptr(), key_str.length()); + key_str_.assign_ptr(ptr, key_str.length()); + } + } + if (OB_FAIL(ret)) { + if (!key_str_.empty()) { + alloc.free(key_str_.ptr()); + } + if (!info_str_.empty()) { + alloc.free(info_str_.ptr()); + } + } else { + timestamp_ = timestamp; + event_ = event_str; + unit_id_ = unit_id; + writer_type_ = writer_type; + writer_id_ = writer_id; + seq_no_ = seq_no; + redo_scn_ = redo_scn; + end_scn_ = end_scn; + trans_version_ = trans_version; + node_type_ = node_type; + state_ = state; + alloc_ = &alloc; + } + return ret; + #undef PRINT_WRAPPER + } + void record_thread_info_() { + tid_ = (uint32_t)GETTID(); + trace_id_ = *ObCurTraceId::get_trace_id(); + char *name = ob_get_tname(); + if (OB_NOT_NULL(name)) { + int64_t name_len = strlen(name); + int64_t copy_len = std::min(name_len, 15); + memcpy(tname_, name, copy_len); + tname_[copy_len] = '\0'; + } + timestamp_ = fast_current_time(); + } +private: + // recorded by call record_thread_info_() + uint32_t tid_; + ObCurTraceId::TraceId trace_id_; + char tname_[16] = {0}; + int64_t timestamp_; + // need fill + const char *event_; + ObString info_str_; + uint8_t unit_id_; + storage::mds::WriterType writer_type_; + int64_t writer_id_; + int64_t seq_no_; + share::SCN redo_scn_; + share::SCN end_scn_; + share::SCN trans_version_; + storage::mds::MdsNodeType node_type_; + storage::mds::TwoPhaseCommitState state_; + ObString key_str_; + ObIAllocator *alloc_; +}; + +struct ObMdsEventBuffer { + struct DefaultAllocator : public ObIAllocator + { + void *alloc(const int64_t size) { return ob_malloc(size, "MDS"); } + void *alloc(const int64_t size, const ObMemAttr &attr) { return ob_malloc(size, attr); } + void free(void *ptr) { ob_free(ptr); } + void set_label(const lib::ObLabel &) {} + static DefaultAllocator &get_instance() { static DefaultAllocator alloc; return alloc; } + static int64_t get_alloc_times() { return ATOMIC_LOAD(&get_instance().alloc_times_); } + static int64_t get_free_times() { return ATOMIC_LOAD(&get_instance().free_times_); } + private: + DefaultAllocator() : alloc_times_(0), free_times_(0) {} + int64_t alloc_times_; + int64_t free_times_; + }; + struct Singleton { + int init() { + int ret = OB_SUCCESS; + if (OB_FAIL(mds_event_cache_.init("MdsEventCache", DefaultAllocator::get_instance(), 0, 128_MB, 8192))) {// not enable + ret = OB_SUCCESS; + OCCAM_LOG(WARN, "init failed", KR(ret)); + } else { + is_inited_ = true; + OCCAM_LOG(INFO, "init ObMdsEventBuffer success", KR(ret)); + } + return ret; + } + void destroy() { + mds_event_cache_.~ObVtableEventRecycleBuffer(); + } + void append(const MdsEventKey &key, const MdsEvent &event, const char *file, const uint32_t line, const char *func) { + if (OB_NOT_NULL(file) && OB_UNLIKELY(line != 0) && OB_NOT_NULL(func) && OB_NOT_NULL(event.event_)) { + share::ObTaskController::get().allow_next_syslog(); + ::oceanbase::common::OB_PRINT("[MDS.EVENT]", OB_LOG_LEVEL_INFO, file, line, func, OB_LOG_LOCATION_HASH_VAL, OB_SUCCESS, + event.event_, LOG_KVS(K(key), K(event))); + } + if (is_inited_) { + (void) mds_event_cache_.append(key, event, file, line, func); + } + } + template + int for_each(const MdsEventKey &key, OP &&op) { + int ret = OB_SUCCESS; + if (!is_inited_) { + OCCAM_LOG(INFO, "ObMdsEventBuffer is not init", KR(ret)); + } else { + ret = mds_event_cache_.for_each(key, std::forward(op)); + } + return ret; + } + template + int for_each(OP &&op) { + int ret = OB_SUCCESS; + if (!is_inited_) { + OCCAM_LOG(INFO, "ObMdsEventBuffer is not init", KR(ret)); + } else { + ret = mds_event_cache_.for_each(std::forward(op)); + } + return ret; + } + void dump_statistics() { + mds_event_cache_.dump_statistics(); + } + static Singleton &get_instance() { static Singleton s; return s; } + private: + Singleton() : is_inited_(false), mds_event_cache_() {} + bool is_inited_; + common::cache::ObVtableEventRecycleBuffer mds_event_cache_; + }; + static int init() { return Singleton::get_instance().init(); } + static void destroy() { return Singleton::get_instance().destroy(); } + static void append(const MdsEventKey &key, const MdsEvent &event, const char *file, const uint32_t line, const char *func) { + return Singleton::get_instance().append(key, event, file, line, func); + } + template + static int for_each(const MdsEventKey &key, OP &&op) { + return Singleton::get_instance().for_each(key, std::forward(op)); + } + template + static int for_each(OP &&op) { + return Singleton::get_instance().for_each(std::forward(op)); + } + static void dump_statistics() { + Singleton::get_instance().dump_statistics(); + } +}; + +} +} + +#endif \ No newline at end of file diff --git a/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp b/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp index 927add1a8..f79f631cf 100644 --- a/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp +++ b/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp @@ -199,6 +199,8 @@ #include "observer/virtual_table/ob_all_virtual_archive_dest_status.h" #include "observer/virtual_table/ob_virtual_show_trace.h" #include "observer/virtual_table/ob_all_virtual_sql_plan.h" +#include "observer/virtual_table/ob_all_virtual_mds_node_stat.h" +#include "observer/virtual_table/ob_all_virtual_mds_event_history.h" #include "observer/virtual_table/ob_all_virtual_dup_ls_lease_mgr.h" #include "observer/virtual_table/ob_all_virtual_dup_ls_tablets.h" #include "observer/virtual_table/ob_all_virtual_opt_stat_gather_monitor.h" @@ -206,6 +208,7 @@ #include "observer/virtual_table/ob_all_virtual_dup_ls_tablet_set.h" #include "observer/virtual_table/ob_all_virtual_px_p2p_datahub.h" #include "observer/virtual_table/ob_all_virtual_ls_log_restore_status.h" +#include "observer/virtual_table/ob_all_virtual_tablet_buffer_info.h" namespace oceanbase { @@ -610,12 +613,12 @@ int ObVTIterCreator::create_vt_iter(ObVTableScanParam ¶ms, } case OB_ALL_VIRTUAL_BACKUP_SCHEDULE_TASK_TID: { ObAllBackupScheduleTaskStat *all_task_stat = NULL; - if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAllBackupScheduleTaskStat, all_task_stat))) { + omt::ObMultiTenant *omt = GCTX.omt_; + if (OB_UNLIKELY(NULL == omt)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "get tenant fail", K(ret)); + } else if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAllBackupScheduleTaskStat, all_task_stat, omt))) { SERVER_LOG(ERROR, "ObAllBackupScheduleTaskStat construct failed", K(ret)); - } else if (OB_FAIL(all_task_stat->init( - root_service_.get_schema_service(), - root_service_.get_backup_task_scheduler()))) { - SERVER_LOG(WARN, "all_virtual_backup_schedule_task table init failed", K(ret)); } else { vt_iter = static_cast(all_task_stat); } @@ -1840,13 +1843,24 @@ int ObVTIterCreator::create_vt_iter(ObVTableScanParam ¶ms, if (OB_FAIL(OB_SERVER_BLOCK_MGR.get_marker_status(marker_status))) { SERVER_LOG(WARN, "failed to get marker info", K(ret)); } else if (OB_FAIL(all_virtual_marker_status->init(marker_status))) { - SERVER_LOG(WARN, "fail to init migration_status", K(ret)); + SERVER_LOG(WARN, "fail to init marker_status", K(ret)); } else { vt_iter = static_cast(all_virtual_marker_status); } } break; } + case OB_ALL_VIRTUAL_TABLET_BUFFER_INFO_TID: { + ObAllVirtualTabletBufferInfo *all_virtual_tablet_buffer_info = NULL; + if (OB_SUCC(NEW_VIRTUAL_TABLE(ObAllVirtualTabletBufferInfo, all_virtual_tablet_buffer_info))) { + if (OB_FAIL(all_virtual_tablet_buffer_info->init(addr_))) { + SERVER_LOG(WARN, "fail to init tablet_buffer_info", K(ret)); + } else { + vt_iter = static_cast(all_virtual_tablet_buffer_info); + } + } + break; + } case OB_ALL_VIRTUAL_SERVER_BLACKLIST_TID: { ObAllVirtualServerBlacklist *server_blacklist = NULL; if (OB_SUCCESS == NEW_VIRTUAL_TABLE(ObAllVirtualServerBlacklist, server_blacklist)) { @@ -2391,6 +2405,32 @@ int ObVTIterCreator::create_vt_iter(ObVTableScanParam ¶ms, } break; } + case OB_ALL_VIRTUAL_MDS_NODE_STAT_TID: { + ObAllVirtualMdsNodeStat *mds_node_stat = NULL; + omt::ObMultiTenant *omt = GCTX.omt_; + if (OB_UNLIKELY(NULL == omt)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "get tenant fail", K(ret)); + } else if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAllVirtualMdsNodeStat, mds_node_stat, omt))) { + SERVER_LOG(ERROR, "ObAllVirtualMdsNodeStat construct fail", K(ret)); + } else { + vt_iter = static_cast(mds_node_stat); + } + break; + } + case OB_ALL_VIRTUAL_MDS_EVENT_HISTORY_TID: { + ObAllVirtualMdsEventHistory *mds_node_stat = NULL; + omt::ObMultiTenant *omt = GCTX.omt_; + if (OB_UNLIKELY(NULL == omt)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "get tenant fail", K(ret)); + } else if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAllVirtualMdsEventHistory, mds_node_stat, omt))) { + SERVER_LOG(ERROR, "ObAllVirtualMdsEventHistory construct fail", K(ret)); + } else { + vt_iter = static_cast(mds_node_stat); + } + break; + } case OB_ALL_VIRTUAL_SQL_PLAN_TID: { ObAllVirtualSqlPlan *sql_plan_table = NULL; if (OB_SUCC(NEW_VIRTUAL_TABLE(ObAllVirtualSqlPlan, sql_plan_table))) { diff --git a/src/rootserver/CMakeLists.txt b/src/rootserver/CMakeLists.txt index ac38ab675..4af70da5c 100644 --- a/src/rootserver/CMakeLists.txt +++ b/src/rootserver/CMakeLists.txt @@ -8,16 +8,17 @@ ob_set_subtarget(ob_rootserver ALONE ob_set_subtarget(ob_rootserver backup backup/ob_archive_scheduler_service.cpp + backup/ob_backup_base_service.cpp backup/ob_backup_clean_ls_task_mgr.cpp backup/ob_backup_clean_scheduler.cpp backup/ob_backup_clean_task_mgr.cpp - backup/ob_backup_lease_service.cpp backup/ob_backup_service.cpp backup/ob_backup_schedule_task.cpp backup/ob_backup_task_scheduler.cpp backup/ob_tenant_archive_scheduler.cpp backup/ob_backup_data_scheduler.cpp backup/ob_backup_data_set_task_mgr.cpp + backup/ob_backup_proxy.cpp backup/ob_backup_data_ls_task_mgr.cpp ) @@ -43,6 +44,7 @@ ob_set_subtarget(ob_rootserver common ob_locality_util.cpp ob_resource_weight_parser.cpp ob_root_balancer.cpp + ob_partition_balance.cpp ob_root_minor_freeze.cpp ob_root_utils.cpp ob_root_inspection.cpp @@ -67,13 +69,22 @@ ob_set_subtarget(ob_rootserver common ob_vtable_location_getter.cpp ob_zone_manager.cpp ob_zone_unit_provider.cpp - ob_tenant_recovery_reportor.cpp + ob_tenant_info_loader.cpp + ob_tenant_thread_helper.cpp + ob_ls_recovery_reportor.cpp ob_standby_schema_refresh_trigger.cpp ob_tenant_info_loader.cpp ob_create_standby_from_net_actor.cpp ob_primary_ls_service.cpp ob_recovery_ls_service.cpp + ob_balance_ls_primary_zone.cpp + ob_common_ls_service.cpp + ob_ls_service_helper.cpp ob_tenant_role_transition_service.cpp + ob_tenant_transfer_service.cpp + ob_tenant_balance_service.cpp + ob_ls_balance_helper.cpp + ob_balance_task_execute_service.cpp ob_server_balancer.cpp ob_system_admin_util.cpp ob_update_rs_list_task.cpp @@ -83,6 +94,16 @@ ob_set_subtarget(ob_rootserver common ob_lob_piece_builder.cpp ob_lob_meta_builder.cpp ob_ls_recovery_stat_handler.cpp + ob_shrink_resource_pool_checker.cpp +) + +ob_set_subtarget(ob_rootserver balance + balance/ob_all_balance_group_builder.cpp + balance/ob_balance_group_define.cpp + balance/ob_balance_group_info.cpp + balance/ob_ls_balance_group_info.cpp + balance/ob_tenant_ls_balance_group_info.cpp + balance/ob_ls_all_part_builder.cpp ) ob_set_subtarget(ob_rootserver ddl_task diff --git a/src/rootserver/backup/ob_archive_scheduler_service.cpp b/src/rootserver/backup/ob_archive_scheduler_service.cpp index 366809e15..0ab8d0a70 100644 --- a/src/rootserver/backup/ob_archive_scheduler_service.cpp +++ b/src/rootserver/backup/ob_archive_scheduler_service.cpp @@ -10,7 +10,7 @@ * See the Mulan PubL v2 for more details. */ -#define USING_LOG_PREFIX ARCHIVE +#define USING_LOG_PREFIX RS #include "rootserver/backup/ob_archive_scheduler_service.h" #include "rootserver/backup/ob_tenant_archive_scheduler.h" #include "rootserver/ob_rs_event_history_table_operator.h" @@ -19,10 +19,8 @@ #include "lib/utility/ob_tracepoint.h" #include "lib/thread/ob_thread_name.h" #include "share/ob_srv_rpc_proxy.h" -#include "share/backup/ob_backup_lease_info_mgr.h" #include "share/backup/ob_tenant_archive_round.h" - using namespace oceanbase; using namespace rootserver; using namespace common; @@ -30,151 +28,63 @@ using namespace share; using namespace schema; using namespace obrpc; -/** - * ------------------------------ObArchiveThreadIdling--------------------- - */ -ObArchiveThreadIdling::ObArchiveThreadIdling(volatile bool &stop) - : ObThreadIdling(stop), idle_time_us_(MIN_IDLE_INTERVAL_US) -{ - -} - -int64_t ObArchiveThreadIdling::get_idle_interval_us() -{ - return idle_time_us_; -} - -void ObArchiveThreadIdling::set_checkpoint_interval(const int64_t interval_us) -{ - const int64_t max_idle_us = interval_us / 2 - RESERVED_FETCH_US; - int64_t idle_time_us = 0; - if (interval_us <= 0) { - idle_time_us = MAX_IDLE_INTERVAL_US; - } else { - if (max_idle_us <= MIN_IDLE_INTERVAL_US) { - idle_time_us = MIN_IDLE_INTERVAL_US; - } else if (max_idle_us > MAX_IDLE_INTERVAL_US) { - idle_time_us = MAX_IDLE_INTERVAL_US; - } else { - idle_time_us = max_idle_us; - } - } - - if (idle_time_us != idle_time_us_) { - FLOG_INFO("change idle_time_us", K(idle_time_us_), K(idle_time_us)); - idle_time_us_ = idle_time_us; - } -} - - /** * ------------------------------ObArchiveSchedulerService--------------------- */ ObArchiveSchedulerService::ObArchiveSchedulerService() - : is_inited_(false), is_working_(false), idling_(stop_), - zone_mgr_(nullptr), unit_mgr_(nullptr), - rpc_proxy_(nullptr), sql_proxy_(nullptr), schema_service_(nullptr), backup_lease_service_(nullptr) + : is_inited_(false), tenant_id_(OB_INVALID_TENANT_ID), rpc_proxy_(nullptr), sql_proxy_(nullptr), schema_service_(nullptr) { +} +int ObArchiveSchedulerService::mtl_init(ObArchiveSchedulerService *&archive_service) +{ + int ret = OB_SUCCESS; + common::ObMySQLProxy *sql_proxy = nullptr; + obrpc::ObSrvRpcProxy *rpc_proxy = nullptr; + share::schema::ObMultiVersionSchemaService *schema_service = nullptr; + if (OB_ISNULL(sql_proxy = GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql_proxy should not be NULL", K(ret), KP(sql_proxy)); + } else if (OB_ISNULL(rpc_proxy = GCTX.srv_rpc_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rpc_proxy should not be NULL", K(ret), KP(rpc_proxy)); + } else if (OB_ISNULL(schema_service = GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema_service should not be NULL", K(ret), KP(schema_service)); + } else if (OB_FAIL(archive_service->init(*schema_service, *rpc_proxy, *sql_proxy))) { + LOG_WARN("fail to init tenant archive service", K(ret)); + } + return ret; } int ObArchiveSchedulerService::init( - ObZoneManager &zone_mgr, - ObUnitManager &unit_manager, - share::schema::ObMultiVersionSchemaService *schema_service, + share::schema::ObMultiVersionSchemaService &schema_service, ObSrvRpcProxy &rpc_proxy, - common::ObMySQLProxy &sql_proxy, - share::ObIBackupLeaseService &backup_lease_service) + common::ObMySQLProxy &sql_proxy) { int ret = OB_SUCCESS; - const int64_t thread_cnt = 1; - if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("archive scheduler init twice", K(ret)); - } else if (OB_ISNULL(schema_service)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("schema_service is null", K(ret), KP(schema_service)); - } else if (OB_FAIL(create(thread_cnt, "LOG_ARCHIVE_SERVICE"))) { + } else if (OB_FAIL(create("ArchiveSvr", *this, ObWaitEventIds::BACKUP_ARCHIVE_SERVICE_COND_WAIT))) { LOG_WARN("failed to create log archive thread", K(ret)); } else { - zone_mgr_ = &zone_mgr; - unit_mgr_ = &unit_manager; - schema_service_ = schema_service; + schema_service_ = &schema_service; rpc_proxy_ = &rpc_proxy; sql_proxy_ = &sql_proxy; - backup_lease_service_ = &backup_lease_service; + tenant_id_ = gen_user_tenant_id(MTL_ID()); is_inited_ = true; } return ret; } -int ObArchiveSchedulerService::start() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(ObReentrantThread::logical_start())) { - LOG_WARN("failed to start", K(ret)); - } else { - is_working_ = true; - LOG_INFO("start archive scheduler service"); - } - return ret; -} - -void ObArchiveSchedulerService::stop() -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else { - ObRsReentrantThread::stop(); - idling_.wakeup(); - LOG_INFO("stop archive scheduler service"); - } -} - -void ObArchiveSchedulerService::wait() -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else { - ObRsReentrantThread::wait(); - LOG_INFO("wait archive scheduler service"); - } -} - -int ObArchiveSchedulerService::destroy() -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else { - if(OB_FAIL(ObRsReentrantThread::destroy())) { - LOG_WARN("ObRsReentrantThread::destroy failed", K(ret)); - } - is_inited_ = false; - LOG_INFO("destroy archive scheduler service", K(ret)); - } - return ret; -} - -void ObArchiveSchedulerService::wakeup() -{ - idling_.wakeup(); -} - -void ObArchiveSchedulerService::run3() +void ObArchiveSchedulerService::run2() { int tmp_ret = OB_SUCCESS; int64_t round = 0; share::ObLogArchiveStatus::STATUS last_log_archive_status = ObLogArchiveStatus::INVALID; - lib::set_thread_name("ArcSrv"); FLOG_INFO("ObArchiveSchedulerService run start"); if (IS_NOT_INIT) { tmp_ret = OB_NOT_INIT; @@ -184,7 +94,7 @@ void ObArchiveSchedulerService::run3() ++round; ObCurTraceId::init(GCONF.self_addr_); FLOG_INFO("start do ObArchiveSchedulerService round", K(round)); - if (stop_) { + if (has_set_stop()) { tmp_ret = OB_IN_STOP_STATE; LOG_WARN_RET(tmp_ret, "exit for stop state", K(tmp_ret)); break; @@ -193,12 +103,9 @@ void ObArchiveSchedulerService::run3() } int64_t checkpoint_interval = 1 * 1000 * 1000L; - idling_.set_checkpoint_interval(checkpoint_interval); - if (OB_SUCCESS != (tmp_ret = idling_.idle())) { - LOG_WARN_RET(tmp_ret, "failed to to idling", K(tmp_ret)); - } + set_checkpoint_interval_(checkpoint_interval); + idle(); } - is_working_ = false; } FLOG_INFO("ObArchiveSchedulerService run finish"); } @@ -336,7 +243,7 @@ int ObArchiveSchedulerService::start_tenant_archive_(const uint64_t tenant_id) ObArchiveHandler archive_handler; // Only one dest is supported. const int64_t dest_no = 0; - if (OB_FAIL(archive_handler.init(tenant_id, *zone_mgr_, *unit_mgr_, schema_service_, *rpc_proxy_, *sql_proxy_))) { + if (OB_FAIL(archive_handler.init(tenant_id, schema_service_, *rpc_proxy_, *sql_proxy_))) { LOG_WARN("failed to init archive_handler", K(ret)); } else if (OB_FAIL(archive_handler.enable_archive(dest_no))) { LOG_WARN("failed to enable archive tenant", K(ret), K(tenant_id), K(dest_no)); @@ -353,7 +260,7 @@ int ObArchiveSchedulerService::stop_tenant_archive_(const uint64_t tenant_id) ObArchiveHandler archive_handler; // Only one dest is supported. const int64_t dest_no = 0; - if (OB_FAIL(archive_handler.init(tenant_id, *zone_mgr_, *unit_mgr_, schema_service_, *rpc_proxy_, *sql_proxy_))) { + if (OB_FAIL(archive_handler.init(tenant_id, schema_service_, *rpc_proxy_, *sql_proxy_))) { LOG_WARN("failed to init archive_handler", K(ret), K(tenant_id)); } else if (OB_FAIL(archive_handler.disable_archive(dest_no))) { LOG_WARN("failed to disable tenant archive", K(ret), K(tenant_id), K(dest_no)); @@ -365,28 +272,6 @@ int ObArchiveSchedulerService::stop_tenant_archive_(const uint64_t tenant_id) } int ObArchiveSchedulerService::process_() -{ - int ret = OB_SUCCESS; - // advance archive state. - ObArray tenant_id_array; - ObArray tenant_round_array; - if (OB_FAIL(get_all_tenant_ids_(tenant_id_array))) { - LOG_WARN("failed to get all meta tenant ids", K(ret)); - } - - // advance normal tenant state first. - int tmp_ret = OB_SUCCESS; - for (int64_t i = 0; OB_SUCC(ret) && i < tenant_id_array.count(); i++) { - const uint64_t &tenant_id = tenant_id_array.at(i); - if (OB_TMP_FAIL(inner_process_(tenant_id))) { - LOG_WARN("failed to process", K(tmp_ret), K(tenant_id)); - } - } - - return ret; -} - -int ObArchiveSchedulerService::inner_process_(const uint64_t tenant_id) { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; @@ -400,7 +285,8 @@ int ObArchiveSchedulerService::inner_process_(const uint64_t tenant_id) bool no_round = false; ObArchiveHandler tenant_scheduler; - if (OB_FAIL(tenant_scheduler.init(tenant_id, *zone_mgr_, *unit_mgr_, schema_service_, *rpc_proxy_, *sql_proxy_))) { + const uint64_t tenant_id = tenant_id_; + if (OB_FAIL(tenant_scheduler.init(tenant_id, schema_service_, *rpc_proxy_, *sql_proxy_))) { LOG_WARN("failed to init tenant archive scheduler", K(ret), K(tenant_id)); } else if (OB_TMP_FAIL(tenant_scheduler.checkpoint())) { LOG_WARN("failed to checkpoint", K(tmp_ret), K(tenant_id)); @@ -455,7 +341,6 @@ int ObArchiveSchedulerService::inner_process_(const uint64_t tenant_id) } } } - return ret; } @@ -496,6 +381,28 @@ int ObArchiveSchedulerService::get_all_tenant_ids_(common::ObIArray &t return ret; } +void ObArchiveSchedulerService::set_checkpoint_interval_(const int64_t interval_us) +{ + const int64_t max_idle_us = interval_us / 2 - RESERVED_FETCH_US; + int64_t idle_time_us = 0; + if (interval_us <= 0) { + idle_time_us = MAX_IDLE_INTERVAL_US; + } else { + if (max_idle_us <= MIN_IDLE_INTERVAL_US) { + idle_time_us = MIN_IDLE_INTERVAL_US; + } else if (max_idle_us > MAX_IDLE_INTERVAL_US) { + idle_time_us = MAX_IDLE_INTERVAL_US; + } else { + idle_time_us = max_idle_us; + } + } + + if (idle_time_us != get_idle_time()) { + FLOG_INFO("change idle_time_us", "idle_time_ts_", get_idle_time(), K(idle_time_us)); + set_idle_time(idle_time_us); + } +} + int ObArchiveSchedulerService::open_archive_mode(const uint64_t tenant_id, const common::ObIArray &archive_tenant_ids) { // TODO: print error trace to user @@ -551,7 +458,7 @@ int ObArchiveSchedulerService::open_tenant_archive_mode_(const uint64_t tenant_i { int ret = OB_SUCCESS; ObArchiveHandler tenant_scheduler; - if (OB_FAIL(tenant_scheduler.init(tenant_id, *zone_mgr_, *unit_mgr_, schema_service_, *rpc_proxy_, *sql_proxy_))) { + if (OB_FAIL(tenant_scheduler.init(tenant_id, schema_service_, *rpc_proxy_, *sql_proxy_))) { LOG_WARN("failed to init tenant archive scheduler", K(ret), K(tenant_id)); } else if (OB_FAIL(tenant_scheduler.open_archive_mode())) { LOG_WARN("failed to open archive mode", K(ret), K(tenant_id)); @@ -613,10 +520,10 @@ int ObArchiveSchedulerService::close_tenant_archive_mode_(const uint64_t tenant_ { int ret = OB_SUCCESS; ObArchiveHandler tenant_scheduler; - if (OB_FAIL(tenant_scheduler.init(tenant_id, *zone_mgr_, *unit_mgr_, schema_service_, *rpc_proxy_, *sql_proxy_))) { + if (OB_FAIL(tenant_scheduler.init(tenant_id, schema_service_, *rpc_proxy_, *sql_proxy_))) { LOG_WARN("failed to init tenant archive scheduler", K(ret), K(tenant_id)); } else if (OB_FAIL(tenant_scheduler.close_archive_mode())) { LOG_WARN("failed to close archive mode", K(ret), K(tenant_id)); } return ret; -} \ No newline at end of file +} diff --git a/src/rootserver/backup/ob_archive_scheduler_service.h b/src/rootserver/backup/ob_archive_scheduler_service.h index d599c31d4..f0f6c6df7 100644 --- a/src/rootserver/backup/ob_archive_scheduler_service.h +++ b/src/rootserver/backup/ob_archive_scheduler_service.h @@ -13,12 +13,10 @@ #ifndef OCEANBASE_ROOTSERVER_OB_ARCHIVE_SCHEDULER_SERVICE_H_ #define OCEANBASE_ROOTSERVER_OB_ARCHIVE_SCHEDULER_SERVICE_H_ +#include "ob_backup_base_service.h" #include "lib/mysqlclient/ob_isql_client.h" #include "lib/container/ob_iarray.h" #include "share/backup/ob_backup_struct.h" -#include "rootserver/ob_i_backup_scheduler.h" -#include "rootserver/ob_thread_idling.h" -#include "rootserver/ob_rs_reentrant_thread.h" namespace oceanbase { @@ -31,66 +29,30 @@ namespace common { class ObMySQLProxy; } -namespace share { - class ObIBackupLeaseService; -} - namespace rootserver { -class ObZoneManager; -class ObUnitManager; - -class ObArchiveThreadIdling final: public ObThreadIdling +class ObArchiveSchedulerService final : public ObBackupBaseService { public: - explicit ObArchiveThreadIdling(volatile bool &stop); + ObArchiveSchedulerService(); + virtual ~ObArchiveSchedulerService() {} + const int64_t RESERVED_FETCH_US = 10 * 1000 * 1000; // 10s, used for fetch observer log archive status const int64_t MIN_IDLE_INTERVAL_US = 2 * 1000 * 1000; // 2s const int64_t FAST_IDLE_INTERVAL_US = 10 * 1000 * 1000; // 10s, used during BEGINNING or STOPPING //const int64_t MAX_IDLE_INTERVAL_US = 60 * 1000 * 1000; // 60s const int64_t MAX_IDLE_INTERVAL_US = 10 * 1000 * 1000; // 60s - virtual int64_t get_idle_interval_us(); - void set_checkpoint_interval(const int64_t interval_us); - -private: - int64_t idle_time_us_; - DISALLOW_COPY_AND_ASSIGN(ObArchiveThreadIdling); -}; - -class ObArchiveSchedulerService final : public ObIBackupScheduler -{ -public: - ObArchiveSchedulerService(); - ~ObArchiveSchedulerService() {} + static int mtl_init(ObArchiveSchedulerService *&archive_service); int init( - ObZoneManager &zone_mgr, - ObUnitManager &unit_manager, - share::schema::ObMultiVersionSchemaService *schema_service, + share::schema::ObMultiVersionSchemaService &schema_service, obrpc::ObSrvRpcProxy &rpc_proxy, - common::ObMySQLProxy &sql_proxy, - share::ObIBackupLeaseService &backup_lease_info); - - bool is_working() const override - { - return is_working_; - } + common::ObMySQLProxy &sql_proxy); - int blocking_run() override - { - BLOCKING_RUN_IMPLEMENT(); - } - - int start() override; - void stop() override; - void wait() override; - int destroy(); - void run3() override; + void run2() override; // force cancel archive - int force_cancel(const uint64_t tenant_id) override; - - void wakeup(); + int force_cancel(const uint64_t tenant_id); int open_archive_mode(const uint64_t tenant_id, const common::ObIArray &archive_tenant_ids); @@ -108,7 +70,6 @@ public: private: int process_(); - int inner_process_(const uint64_t tenant_id); int start_tenant_archive_(const uint64_t tenant_id); // Return the first error that failed to start archive if force_start is true. Otherwise, // ignore all error. @@ -119,21 +80,17 @@ private: int stop_tenant_archive_(const uint64_t tenant_id); int get_all_tenant_ids_(common::ObIArray &tenantid_array); - + void set_checkpoint_interval_(const int64_t interval_us); int open_tenant_archive_mode_(const common::ObIArray &tenant_ids_array); int open_tenant_archive_mode_(const uint64_t tenant_id); int close_tenant_archive_mode_(const common::ObIArray &tenant_ids_array); int close_tenant_archive_mode_(const uint64_t tenant_id); bool is_inited_; - bool is_working_; - mutable ObArchiveThreadIdling idling_; - ObZoneManager *zone_mgr_; - ObUnitManager *unit_mgr_; + uint64_t tenant_id_; obrpc::ObSrvRpcProxy *rpc_proxy_; common::ObMySQLProxy *sql_proxy_; share::schema::ObMultiVersionSchemaService *schema_service_; - share::ObIBackupLeaseService *backup_lease_service_; DISALLOW_COPY_AND_ASSIGN(ObArchiveSchedulerService); }; @@ -141,4 +98,4 @@ private: } } -#endif \ No newline at end of file +#endif diff --git a/src/rootserver/backup/ob_backup_base_job.h b/src/rootserver/backup/ob_backup_base_job.h index 5781096fa..369f3d237 100644 --- a/src/rootserver/backup/ob_backup_base_job.h +++ b/src/rootserver/backup/ob_backup_base_job.h @@ -13,12 +13,34 @@ #ifndef OCEANBASE_ROOTSERVER_OB_BACKUP_BASE_JOB_H_ #define OCEANBASE_ROOTSERVER_OB_BACKUP_BASE_JOB_H_ -#include "ob_backup_task_scheduler.h" +#include "lib/container/ob_iarray.h" +#include "lib/allocator/ob_allocator.h" +#include "src/share/ob_define.h" namespace oceanbase { +namespace common +{ +class ObAddr; +} +namespace share +{ +class ObHAResultInfo; +} namespace rootserver { +enum class BackupJobType : int64_t +{ + BACKUP_DATA_JOB = 0, + VALIDATE_JOB = 1, + BACKUP_BACKUP_PIECE_JOB = 2, + BACKUP_BACKUP_DATA_JOB = 3, + BACKUP_CLEAN_JOB = 4, + BACKUP_JOB_MAX +}; + +class ObBackupScheduleTask; + class ObIBackupJobScheduler { public: @@ -28,8 +50,7 @@ public: virtual int process() = 0; virtual int force_cancel(const uint64_t &tenant_id) = 0; // if can_remove return true, scheudler can remove task from scheduler - virtual int handle_execute_over(const ObBackupScheduleTask *task, bool &can_remove, - const ObAddr &black_server, const int execute_ret) = 0; + virtual int handle_execute_over(const ObBackupScheduleTask *task, const share::ObHAResultInfo &result_info, bool &can_remove) = 0; virtual int get_need_reload_task(common::ObIAllocator &allocator, common::ObIArray &tasks) = 0; // reload tasks after switch master happend public: diff --git a/src/rootserver/backup/ob_backup_base_service.cpp b/src/rootserver/backup/ob_backup_base_service.cpp new file mode 100644 index 000000000..26a1e363b --- /dev/null +++ b/src/rootserver/backup/ob_backup_base_service.cpp @@ -0,0 +1,224 @@ +// Copyright (c) 2021 OceanBase +// OceanBase 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. +#define USING_LOG_PREFIX RS +#include "ob_backup_base_service.h" +#include "observer/ob_sql_client_decorator.h" +#include "share/backup/ob_backup_data_table_operator.h" +#include "logservice/ob_log_service.h" + +using namespace oceanbase; +using namespace rootserver; + +ObBackupBaseService::ObBackupBaseService() + : is_created_(false), + tg_id_(-1), + proposal_id_(0), + wakeup_cnt_(0), + interval_idle_time_us_(INT64_MAX), + thread_cond_(), + thread_name_("") +{ +} + +ObBackupBaseService::~ObBackupBaseService() +{ +} + +void ObBackupBaseService::run1() +{ + int tmp_ret = OB_SUCCESS; + LOG_INFO("ObBackupBaseService thread run", K(thread_name_)); + if (OB_UNLIKELY(!is_created_)) { + tmp_ret = OB_NOT_INIT; + LOG_WARN_RET(OB_NOT_INIT, "not init", K(tmp_ret)); + } else { + lib::set_thread_name(thread_name_); + ObRSThreadFlag rs_work; + run2(); + } +} + +int ObBackupBaseService::create(const char* thread_name, ObBackupBaseService &tenant_thread, int32_t event_no) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_created_)) { + ret = OB_INIT_TWICE; + LOG_WARN("has inited", KR(ret)); + } else if (OB_ISNULL(thread_name)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("thread name is null", KR(ret)); + } else if (OB_FAIL(TG_CREATE_TENANT(lib::TGDefIDs::SimpleLSService, tg_id_))) { + LOG_ERROR("create tg failed", KR(ret)); + } else if (OB_FAIL(TG_SET_RUNNABLE_AND_START(tg_id_, *this))) { + LOG_ERROR("set thread runable fail", KR(ret)); + } else if (OB_FAIL(thread_cond_.init(event_no))) { + LOG_WARN("fail to init thread cond", K(ret), K(event_no)); + } else { + stop(); + thread_name_ = thread_name; + wakeup_cnt_ = 0; + is_created_ = true; + } + return ret; +} + +void ObBackupBaseService::destroy() +{ + LOG_INFO("[BACKUP_SERVICE] thread destory start", K(tg_id_), K(thread_name_)); + if (-1 != tg_id_) { + TG_STOP(tg_id_); + { + ObThreadCondGuard guard(thread_cond_); + thread_cond_.broadcast(); + } + TG_WAIT(tg_id_); + TG_DESTROY(tg_id_); + tg_id_ = -1; + } + is_created_ = false; + LOG_INFO("[BACKUP_SERVICE] thread destory finish", K(tg_id_), K(thread_name_)); +} + +int ObBackupBaseService::start() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_created_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_FAIL(TG_REENTRANT_LOGICAL_START(tg_id_))) { + LOG_WARN("failed to start", KR(ret)); + } + LOG_INFO("[BACKUP_SERVICE] thread start", K(ret), K(tg_id_), K(thread_name_)); + return ret; +} + +void ObBackupBaseService::stop() +{ + LOG_INFO("[BACKUP_SERVICE] thread ready to stop", K(tg_id_), K(thread_name_)); + if (-1 != tg_id_) { + TG_REENTRANT_LOGICAL_STOP(tg_id_); + wakeup(); + } + LOG_INFO("[BACKUP_SERVICE] thread stopped", K(tg_id_), K(thread_name_)); +} + +void ObBackupBaseService::wait() +{ + LOG_INFO("[BACKUP_SERVICE] thread ready to wait", K(tg_id_), K(thread_name_)); + if (-1 != tg_id_) { + TG_REENTRANT_LOGICAL_WAIT(tg_id_); + } + LOG_INFO("[BACKUP_SERVICE] thread in wait", K(tg_id_), K(thread_name_)); +} + +void ObBackupBaseService::wakeup() +{ + ObThreadCondGuard cond_guard(thread_cond_); + wakeup_cnt_++; + thread_cond_.signal(); +} + +void ObBackupBaseService::idle() +{ + ObThreadCondGuard cond_guard(thread_cond_); + if (has_set_stop() || wakeup_cnt_ > 0) { + wakeup_cnt_ = 0; + } else { + thread_cond_.wait_us(interval_idle_time_us_); + } +} + +void ObBackupBaseService::switch_to_follower_forcedly() +{ + stop(); + LOG_INFO("[BACKUP_SERVICE]switch to follower finish", K(tg_id_), K(thread_name_)); +} + +int ObBackupBaseService::switch_to_leader() +{ + int ret = OB_SUCCESS; + common::ObRole role; + int64_t proposal_id = 0; + if (OB_FAIL(start())) { + LOG_WARN("failed to start thread", KR(ret)); + } else if (OB_FAIL(MTL(logservice::ObLogService *)->get_palf_role(share::SYS_LS, role, proposal_id))) { + LOG_WARN("get ObBackupBaseService role fail", K(ret)); + } else { + proposal_id_ = proposal_id; + wakeup(); + LOG_INFO("[BACKUP_SERVICE]switch to leader finish", K(tg_id_), K(thread_name_)); + } + return ret; +} + +int ObBackupBaseService::switch_to_follower_gracefully() +{ + stop(); + LOG_INFO("[BACKUP_SERVICE]switch to follower gracefully", K(tg_id_), K(thread_name_)); + return OB_SUCCESS; +} + +int ObBackupBaseService::resume_leader() +{ + int ret = OB_SUCCESS; + common::ObRole role; + int64_t proposal_id = 0; + if (OB_FAIL(start())) { + LOG_WARN("failed to start thread", KR(ret)); + } else if (OB_FAIL(MTL(logservice::ObLogService *)->get_palf_role(share::SYS_LS, role, proposal_id))) { + LOG_WARN("get ObBackupBaseService role fail", K(ret)); + } else { + proposal_id_ = proposal_id; + wakeup(); + LOG_INFO("[BACKUP_SERVICE]resume leader finish", K(tg_id_), K(thread_name_)); + } + return ret; +} + +int ObBackupBaseService::replay( + const void *buffer, + const int64_t nbytes, + const palf::LSN &lsn, + const share::SCN &scn) +{ + UNUSED(buffer); + UNUSED(nbytes); + UNUSED(lsn); + UNUSED(scn); + return OB_SUCCESS; +} + +int ObBackupBaseService::flush(share::SCN &scn) +{ + UNUSED(scn); + return OB_SUCCESS; +} + +int ObBackupBaseService::check_leader() +{ + int ret = OB_SUCCESS; + common::ObRole role; + int64_t proposal_id = 0; + if (OB_UNLIKELY(!is_created_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not created backup thread", K(ret)); + } else if (OB_FAIL(MTL(logservice::ObLogService *)->get_palf_role(share::SYS_LS, role, proposal_id))) { + if (OB_LS_NOT_EXIST == ret) { + ret = OB_NOT_MASTER; + LOG_WARN("sys ls is not exist, service can't be leader", K(ret)); + } else { + LOG_WARN("get ObBackupBaseService role fail", K(ret)); + } + } else if (common::ObRole::LEADER == role && proposal_id == proposal_id_) { + } else { + ret = OB_NOT_MASTER; + } + return ret; +} diff --git a/src/rootserver/backup/ob_backup_base_service.h b/src/rootserver/backup/ob_backup_base_service.h new file mode 100644 index 000000000..c9e4e0ca2 --- /dev/null +++ b/src/rootserver/backup/ob_backup_base_service.h @@ -0,0 +1,79 @@ +// Copyright (c) 2021 OceanBase +// OceanBase 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_ROOTSERVER_OB_BACKUP_BASE_SERVICE_H_ +#define OCEANBASE_ROOTSERVER_OB_BACKUP_BASE_SERVICE_H_ + +#include "lib/thread/thread_mgr_interface.h" +#include "lib/lock/ob_thread_cond.h" +#include "logservice/ob_log_base_type.h" +#include "storage/ls/ob_ls.h" +namespace oceanbase +{ + +namespace rootserver +{ + +class ObBackupBaseService : public lib::TGRunnable, + public logservice::ObIReplaySubHandler, + public logservice::ObIRoleChangeSubHandler, + public logservice::ObICheckpointSubHandler +{ +public: + static const int64_t OB_MAX_IDLE_TIME = 60 * 1000 * 1000; // 1min + static const int64_t OB_MIDDLE_IDLE_TIME = 30 * 1000 * 1000; // 30s + static const int64_t OB_FALST_IDLE_TIME = 10 * 1000 * 1000; // 1s +public: + ObBackupBaseService(); + virtual ~ObBackupBaseService(); + +public: + int create(const char* thread_name, ObBackupBaseService &tenant_thread, int32_t event_no); + virtual void run1() override final; + virtual void run2() = 0; + virtual void destroy(); + int start(); + void stop(); + void wait(); + void idle(); + void wakeup(); + void set_idle_time(const int64_t interval_time_us) { interval_idle_time_us_ = interval_time_us; } + int64_t get_idle_time() const { return interval_idle_time_us_; } + // role change + int check_leader(); + virtual void switch_to_follower_forcedly() override; + virtual int switch_to_leader() override; + virtual int switch_to_follower_gracefully() override; + virtual int resume_leader() override; + + // backup service no need to use the above func + virtual int replay(const void *buffer, + const int64_t nbytes, + const palf::LSN &lsn, + const share::SCN &scn) override final; + virtual share::SCN get_rec_scn() override final { return share::SCN::max_scn(); } + virtual int flush(share::SCN &scn) override final; +private: + bool is_created_; + int tg_id_; + int64_t proposal_id_; + int64_t wakeup_cnt_; + int64_t interval_idle_time_us_; + common::ObThreadCond thread_cond_; + const char* thread_name_; +private: + DISALLOW_COPY_AND_ASSIGN(ObBackupBaseService); +}; + +} + +} + +#endif /* !OCEANBASE_ROOTSERVER_OB_BACKUP_BASE_SERVICE_H_ */ \ No newline at end of file diff --git a/src/rootserver/backup/ob_backup_clean_ls_task_mgr.cpp b/src/rootserver/backup/ob_backup_clean_ls_task_mgr.cpp index fa74bed8e..883563478 100644 --- a/src/rootserver/backup/ob_backup_clean_ls_task_mgr.cpp +++ b/src/rootserver/backup/ob_backup_clean_ls_task_mgr.cpp @@ -14,6 +14,8 @@ #include "ob_backup_clean_ls_task_mgr.h" #include "share/backup/ob_backup_clean_operator.h" #include "share/backup/ob_backup_clean_struct.h" +#include "ob_backup_schedule_task.h" +#include "ob_backup_task_scheduler.h" namespace oceanbase { @@ -29,7 +31,6 @@ ObBackupCleanLSTaskMgr::ObBackupCleanLSTaskMgr() ls_attr_(nullptr), task_scheduler_(nullptr), sql_proxy_(nullptr), - lease_service_(nullptr), backup_service_(nullptr) { } @@ -43,8 +44,7 @@ int ObBackupCleanLSTaskMgr::init( ObBackupCleanLSTaskAttr &ls_attr, ObBackupTaskScheduler &task_scheduler, common::ObISQLClient &sql_proxy, - ObBackupLeaseService &lease_service, - ObBackupService &backup_service) + ObBackupCleanService &backup_service) { int ret = OB_SUCCESS; if (IS_INIT) { @@ -58,7 +58,6 @@ int ObBackupCleanLSTaskMgr::init( ls_attr_ = &ls_attr; task_scheduler_ = &task_scheduler; sql_proxy_ = &sql_proxy; - lease_service_ = &lease_service; backup_service_ = &backup_service; is_inited_ = true; } @@ -116,7 +115,7 @@ int ObBackupCleanLSTaskMgr::add_task_() next_status.status_ = ObBackupTaskStatus::Status::PENDING; if (OB_FAIL(task.build(*task_attr_, *ls_attr_))) { LOG_WARN("failed to build task", K(ret), KP(task_attr_), KP(ls_attr_)); - } else if (OB_FAIL(advance_ls_task_status(*lease_service_, *sql_proxy_, *ls_attr_, next_status))) { + } else if (OB_FAIL(advance_ls_task_status(*backup_service_, *sql_proxy_, *ls_attr_, next_status))) { LOG_WARN("failed to advance ls task status", K(ret), K(*task_attr_)); } else if (OB_FAIL(task_scheduler_->add_task(task))) { LOG_WARN("failed to add task", K(ret), K(*task_attr_), K(task)); @@ -127,7 +126,7 @@ int ObBackupCleanLSTaskMgr::add_task_() } int ObBackupCleanLSTaskMgr::advance_ls_task_status( - ObBackupLeaseService &lease_service, + ObBackupCleanService &backup_service, common::ObISQLClient &sql_proxy, const ObBackupCleanLSTaskAttr &ls_attr, const ObBackupTaskStatus &next_status, @@ -138,8 +137,8 @@ int ObBackupCleanLSTaskMgr::advance_ls_task_status( if (!next_status.is_valid() || !ls_attr.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid next_status or invalid ls_attr", K(ret), K(next_status), K(ls_attr)); - } else if (OB_FAIL(lease_service.check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + } else if (OB_FAIL(backup_service.check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanLSTaskOperator::advance_ls_task_status(sql_proxy, ls_attr, next_status, result, end_ts))) { LOG_WARN("failed to advance log stream status", K(ret), K(ls_attr), K(result), K(next_status)); } @@ -147,7 +146,7 @@ int ObBackupCleanLSTaskMgr::advance_ls_task_status( } int ObBackupCleanLSTaskMgr::redo_ls_task( - ObBackupLeaseService &lease_service, + ObBackupCleanService &backup_service, common::ObISQLClient &sql_proxy, const ObBackupCleanLSTaskAttr &ls_attr, const int64_t retry_id) @@ -156,8 +155,8 @@ int ObBackupCleanLSTaskMgr::redo_ls_task( if (!ls_attr.is_valid() || retry_id < 0) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(ls_attr)); - } else if (OB_FAIL(lease_service.check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + } else if (OB_FAIL(backup_service.check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanLSTaskOperator::redo_ls_task(sql_proxy, ls_attr, retry_id))) { LOG_WARN("failed to redo ls task", K(ret), K(ls_attr)); } @@ -172,7 +171,7 @@ int ObBackupCleanLSTaskMgr::finish_(int64_t &finish_cnt) } else if (ObBackupUtils::is_need_retry_error(ls_attr_->result_)) { int64_t cur_ts = ObTimeUtility::current_time(); if (cur_ts > ls_attr_->start_ts_ + OB_BACKUP_RETRY_TIME_INTERVAL) { - if (OB_FAIL(redo_ls_task(*lease_service_, *sql_proxy_, *ls_attr_, ls_attr_->retry_id_ + 1/*increase retry id*/))) { + if (OB_FAIL(redo_ls_task(*backup_service_, *sql_proxy_, *ls_attr_, ls_attr_->retry_id_ + 1/*increase retry id*/))) { LOG_WARN("failed to redo ls task", K(ret), KP(ls_attr_)); } else { backup_service_->wakeup(); @@ -185,15 +184,15 @@ int ObBackupCleanLSTaskMgr::finish_(int64_t &finish_cnt) } int ObBackupCleanLSTaskMgr::statistic_info( - ObBackupLeaseService &lease_service, + ObBackupCleanService &backup_service, common::ObISQLClient &sql_proxy, const ObBackupCleanLSTaskAttr &ls_attr) { int ret = OB_SUCCESS; ObBackupCleanStats stats = ls_attr.stats_; if (OB_FAIL(ret)) { - } else if (OB_FAIL(lease_service.check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + } else if (OB_FAIL(backup_service.check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanLSTaskOperator::update_stats_( sql_proxy, ls_attr.task_id_, ls_attr.tenant_id_, ls_attr.ls_id_, stats))) { LOG_WARN("failed to update stats", K(ret)); @@ -223,7 +222,7 @@ int ObBackupCleanLSTaskMgr::cancel(int64_t &finish_cnt) } } if (OB_FAIL(ret)) { - } else if (OB_FAIL(advance_ls_task_status(*lease_service_, *sql_proxy_, *ls_attr_, next_status, OB_CANCELED, end_ts))) { + } else if (OB_FAIL(advance_ls_task_status(*backup_service_, *sql_proxy_, *ls_attr_, next_status, OB_CANCELED, end_ts))) { LOG_WARN("failed to advance status", K(ret), K(*ls_attr_), K(next_status)); } else { ++finish_cnt; diff --git a/src/rootserver/backup/ob_backup_clean_ls_task_mgr.h b/src/rootserver/backup/ob_backup_clean_ls_task_mgr.h index f7df78107..a245ffd89 100644 --- a/src/rootserver/backup/ob_backup_clean_ls_task_mgr.h +++ b/src/rootserver/backup/ob_backup_clean_ls_task_mgr.h @@ -13,7 +13,6 @@ #ifndef OCEANBASE_SHARE_OB_BACKUP_CLEAN_LS_TASK_MGR_H_ #define OCEANBASE_SHARE_OB_BACKUP_CLEAN_LS_TASK_MGR_H_ #include "ob_backup_service.h" -#include "rootserver/backup/ob_backup_lease_service.h" #include "share/backup/ob_backup_clean_struct.h" #include "share/backup/ob_archive_struct.h" @@ -32,24 +31,23 @@ public: share::ObBackupCleanLSTaskAttr &ls_attr, ObBackupTaskScheduler &task_scheduler, common::ObISQLClient &sql_proxy, - ObBackupLeaseService &lease_service, - ObBackupService &backup_service); + ObBackupCleanService &backup_service); int process(int64_t &finish_cnt); int cancel(int64_t &finish_cnt); static int advance_ls_task_status( - ObBackupLeaseService &lease_service, + ObBackupCleanService &backup_service, common::ObISQLClient &sql_proxy, const share::ObBackupCleanLSTaskAttr &ls_attr, const share::ObBackupTaskStatus &next_status, const int result = OB_SUCCESS, const int64_t end_ts = 0); static int redo_ls_task( - ObBackupLeaseService &lease_service, + ObBackupCleanService &backup_service, common::ObISQLClient &sql_proxy, const share::ObBackupCleanLSTaskAttr &ls_attr, const int64_t retry_id); static int statistic_info( - ObBackupLeaseService &lease_service, + ObBackupCleanService &backup_service, common::ObISQLClient &sql_proxy, const share::ObBackupCleanLSTaskAttr &ls_attr); private: @@ -61,8 +59,7 @@ private: share::ObBackupCleanLSTaskAttr *ls_attr_; ObBackupTaskScheduler *task_scheduler_; common::ObISQLClient *sql_proxy_; - ObBackupLeaseService *lease_service_; - ObBackupService *backup_service_; + ObBackupCleanService *backup_service_; DISALLOW_COPY_AND_ASSIGN(ObBackupCleanLSTaskMgr); }; diff --git a/src/rootserver/backup/ob_backup_clean_scheduler.cpp b/src/rootserver/backup/ob_backup_clean_scheduler.cpp index 4109be3bf..b228c7ab4 100644 --- a/src/rootserver/backup/ob_backup_clean_scheduler.cpp +++ b/src/rootserver/backup/ob_backup_clean_scheduler.cpp @@ -14,8 +14,9 @@ #include "ob_backup_clean_scheduler.h" #include "ob_backup_clean_ls_task_mgr.h" #include "ob_backup_clean_task_mgr.h" +#include "ob_backup_schedule_task.h" +#include "ob_backup_task_scheduler.h" #include "share/backup/ob_backup_clean_operator.h" -#include "share/backup/ob_backup_manager.h" #include "share/backup/ob_archive_persist_helper.h" #include "rootserver/ob_root_utils.h" #include "share/backup/ob_backup_helper.h" @@ -32,32 +33,32 @@ namespace rootserver ObBackupCleanScheduler::ObBackupCleanScheduler() : ObIBackupJobScheduler(BackupJobType::BACKUP_CLEAN_JOB), is_inited_(false), + tenant_id_(OB_INVALID_TENANT_ID), sql_proxy_(nullptr), rpc_proxy_(nullptr), schema_service_(nullptr), - lease_service_(nullptr), task_scheduler_(nullptr), backup_service_(nullptr) { } int ObBackupCleanScheduler::init( + const uint64_t tenant_id, common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, share::schema::ObMultiVersionSchemaService &schema_service, - ObBackupLeaseService &lease_service, ObBackupTaskScheduler &task_scheduler, - ObBackupService &backup_service) + ObBackupCleanService &backup_service) { int ret = OB_SUCCESS; if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret)); } else { + tenant_id_ = tenant_id; sql_proxy_ = &sql_proxy; rpc_proxy_ = &rpc_proxy; schema_service_ = &schema_service; - lease_service_ = &lease_service; task_scheduler_ = &task_scheduler; backup_service_ = &backup_service; is_inited_ = true; @@ -207,66 +208,32 @@ int ObBackupCleanScheduler::do_get_need_reload_task_( return ret; } -int ObBackupCleanScheduler::get_all_normal_tenants_(ObIArray &tenants) -{ - int ret = OB_SUCCESS; - ObSchemaGetterGuard schema_guard; - ObArray tmp_tenantid_array; - if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("failed to get schema guard", K(ret)); - } else if (OB_FAIL(schema_guard.get_tenant_ids(tmp_tenantid_array))) { - LOG_WARN("failed to get tenant ids", K(ret)); - } - - for (int64_t i = 0; OB_SUCC(ret) && i < tmp_tenantid_array.count(); ++i) { - const uint64_t tenant_id = tmp_tenantid_array.at(i); - const ObTenantSchema *tenant_info = nullptr; - if (is_user_tenant(tenant_id)) { - } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_info))) { - LOG_WARN("failed to get tenant info", K(ret), K(tenant_id)); - } else if (tenant_info->is_normal()) { - if (OB_FAIL(tenants.push_back(tenant_id))) { - LOG_WARN("failed to push back tenant id", K(ret), K(tenant_id)); - } - } - } - return ret; -} - int ObBackupCleanScheduler::get_need_reload_task( common::ObIAllocator &allocator, common::ObIArray &tasks) { int ret = OB_SUCCESS; bool for_update = false; - ObArray tenant_ids; + ObArray jobs; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); - } else if (OB_FAIL(get_all_normal_tenants_(tenant_ids))) { - LOG_WARN("fail to get all normal tenants", K(ret)); + } else if (OB_FAIL(ObBackupCleanJobOperator::get_jobs(*sql_proxy_, tenant_id_, for_update, jobs))) { + LOG_WARN("failed to get backup clean jobs", K(ret)); + } else if (jobs.empty()) { + LOG_INFO("[BACKUP_CLEAN]no job need to reload"); } else { - for (int i = 0; OB_SUCC(ret) && i < tenant_ids.count(); ++i) { - const uint64_t tenant_id = tenant_ids.at(i); - ObArray jobs; - if (OB_FAIL(ObBackupCleanJobOperator::get_jobs(*sql_proxy_, tenant_id, for_update, jobs))) { - LOG_WARN("failed to get backup clean jobs", K(ret)); - } else if (jobs.empty()) { - LOG_INFO("[BACKUP_CLEAN]no job need to reload"); - } else { - bool is_valid = false; - for (int i = 0; OB_SUCC(ret) && i < jobs.count(); ++i) { - const ObBackupCleanJobAttr &job = jobs.at(i); - if (is_sys_tenant(job.tenant_id_) || ObBackupCleanStatus::Status::DOING != job.status_.status_) { - // do nothing - } else if (OB_FAIL(ObBackupCleanCommon::check_tenant_status(*schema_service_, job.tenant_id_, is_valid))) { - LOG_WARN("failed to check tenant status", K(ret)); - } else if (!is_valid) { - LOG_INFO("[BACKUP_CLEAN]tenant status is not valid, no need to reload task"); - } else if (OB_FAIL(get_job_need_reload_task(job, allocator, tasks))){ - LOG_WARN("failed to get job need reload task", K(ret)); - } - } + bool is_valid = false; + for (int i = 0; OB_SUCC(ret) && i < jobs.count(); ++i) { + const ObBackupCleanJobAttr &job = jobs.at(i); + if (is_sys_tenant(job.tenant_id_) || ObBackupCleanStatus::Status::DOING != job.status_.status_) { + // do nothing + } else if (OB_FAIL(ObBackupCleanCommon::check_tenant_status(*schema_service_, job.tenant_id_, is_valid))) { + LOG_WARN("failed to check tenant status", K(ret)); + } else if (!is_valid) { + LOG_INFO("[BACKUP_CLEAN]tenant status is not valid, no need to reload task"); + } else if (OB_FAIL(get_job_need_reload_task(job, allocator, tasks))){ + LOG_WARN("failed to get job need reload task", K(ret)); } } } @@ -380,8 +347,8 @@ int ObBackupCleanScheduler::cancel_tenant_jobs_(const uint64_t tenant_id) ObBackupCleanStatus next_status; next_status.status_ = ObBackupCleanStatus::Status::CANCELING; int result = OB_CANCELED; - if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanJobOperator::advance_job_status(trans, job_attr, next_status, result, job_attr.end_ts_))) { LOG_WARN("failed to update backup delete job status to CANCELING", K(ret), K(job_attr)); } @@ -520,7 +487,7 @@ int ObBackupCleanScheduler::persist_job_task_(ObBackupCleanJobAttr &job_attr) if (OB_FAIL(get_next_job_id_(trans, job_attr.tenant_id_, job_attr.job_id_))) { LOG_WARN("failed to get next job id", K(ret)); } else if (OB_FALSE_IT(job_attr.initiator_job_id_ = job_attr.job_id_)) { - } else if (OB_FAIL(lease_service_->check_lease())) { + } else if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanJobOperator::insert_job(trans, job_attr))) { LOG_WARN("failed to insert user tenant backup clean job", K(ret), K(job_attr)); @@ -582,8 +549,8 @@ int ObBackupCleanScheduler::start_tenant_backup_clean_(const ObBackupCleanJobAtt } else if (OB_FAIL(new_job_attr.executor_tenant_id_.push_back(new_job_attr.tenant_id_))) { LOG_WARN("failed to push back tenant id", K(ret)); } else if (OB_FALSE_IT(new_job_attr.initiator_job_id_ = new_job_attr.job_id_)) { - } else if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + } else if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanJobOperator::insert_job(trans, new_job_attr))) { LOG_WARN("failed to insert backup clean job", K(ret), K(new_job_attr)); } @@ -616,9 +583,8 @@ int ObBackupCleanScheduler::get_next_job_id_(common::ObISQLClient &trans, const int ObBackupCleanScheduler::handle_execute_over( const ObBackupScheduleTask *task, - bool &can_remove, - const ObAddr &black_server, - const int execute_ret) + const share::ObHAResultInfo &result_info, + bool &can_remove) { //cases of call handle_execute_over //1. observer return a rpc to tell task scheduler task finish (success or fail) @@ -649,8 +615,8 @@ int ObBackupCleanScheduler::handle_execute_over( ObBackupTaskStatus next_status; next_status.status_ = ObBackupTaskStatus::Status::FINISH; ls_attr.end_ts_ = ObTimeUtility::current_time(); - if (OB_FAIL(ObBackupCleanLSTaskMgr::advance_ls_task_status(*lease_service_, trans, ls_attr, next_status, execute_ret, ls_attr.end_ts_))) { - LOG_WARN("failed to advance status", K(ret), K(ls_attr), K(next_status), K(execute_ret)); + if (OB_FAIL(ObBackupCleanLSTaskMgr::advance_ls_task_status(*backup_service_, trans, ls_attr, next_status, result_info.result_, ls_attr.end_ts_))) { + LOG_WARN("failed to advance status", K(ret), K(ls_attr), K(next_status), K(result_info)); } } else { LOG_WARN("concurrent scenario! this task will need reload to redo.", K(ls_attr)); @@ -713,7 +679,7 @@ int ObBackupCleanScheduler::process_tenant_delete_jobs_(const uint64_t tenant_id if (!job_attr.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("backup clean job is not valid", K(ret), K(job_attr)); - } else if (OB_FAIL(job_mgr->init(tenant_id, job_attr, *sql_proxy_, *rpc_proxy_, *task_scheduler_, *lease_service_, *schema_service_, *backup_service_))) { + } else if (OB_FAIL(job_mgr->init(tenant_id, job_attr, *sql_proxy_, *rpc_proxy_, *task_scheduler_, *schema_service_, *backup_service_))) { LOG_WARN("failed to init tenant backup clean job mgr", K(ret), K(job_attr)); } else if (OB_SUCCESS != (tmp_ret = job_mgr->process())) { // tenant level backups are isolated LOG_WARN("failed to schedule tenant backup clean job", K(tmp_ret), K(job_attr)); @@ -734,28 +700,19 @@ int ObBackupCleanScheduler::process_tenant_delete_jobs_(const uint64_t tenant_id int ObBackupCleanScheduler::process() { int ret = OB_SUCCESS; - ObArray tenant_ids; + ObArray clean_jobs; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("backup clean scheduler not init", K(ret)); - } else if (OB_FAIL(get_all_normal_tenants_(tenant_ids))) { - LOG_WARN("fail to get all normal tenants", K(ret)); + } else if (OB_FAIL(ObBackupCleanJobOperator::get_jobs(*sql_proxy_, tenant_id_, false/*not update*/, clean_jobs))) { + LOG_WARN("failed to get backup clean jobs", K(ret)); + } else if (clean_jobs.empty()) { + // do nothing + } else if (OB_FAIL(process_tenant_delete_jobs_(tenant_id_, clean_jobs))) { + LOG_WARN("failed to process tenant delete jobs", K(ret), K(tenant_id_), K(clean_jobs)); } else { - for (int i = 0; OB_SUCC(ret) && i < tenant_ids.count(); i++) { - const uint64_t tenant_id = tenant_ids.at(i); - ObArray clean_jobs; - if (OB_FAIL(ObBackupCleanJobOperator::get_jobs(*sql_proxy_, tenant_id, false/*not update*/, clean_jobs))) { - LOG_WARN("failed to get backup clean jobs", K(ret)); - } else if (clean_jobs.empty()) { - // do nothing - } else if (OB_FAIL(process_tenant_delete_jobs_(tenant_id, clean_jobs))) { - LOG_WARN("failed to process tenant delete jobs", K(ret), K(tenant_id), K(clean_jobs)); - } else { - FLOG_INFO("[BACKUP_CLEAN]finish process backup clean jobs", K(tenant_id), K(clean_jobs)); - } - } + FLOG_INFO("[BACKUP_CLEAN]finish process backup clean jobs", K(tenant_id_), K(clean_jobs)); } - return ret; } @@ -772,7 +729,6 @@ ObIBackupDeleteMgr::ObIBackupDeleteMgr() rpc_proxy_(nullptr), task_scheduler_(nullptr), schema_service_(nullptr), - lease_service_(nullptr), backup_service_(nullptr) { } @@ -783,9 +739,8 @@ int ObIBackupDeleteMgr::init( common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, ObBackupTaskScheduler &task_scheduler, - ObBackupLeaseService &lease_service, share::schema::ObMultiVersionSchemaService &schema_service, - ObBackupService &backup_service) + ObBackupCleanService &backup_service) { int ret = OB_SUCCESS; if (IS_INIT) { @@ -801,7 +756,6 @@ int ObIBackupDeleteMgr::init( rpc_proxy_ = &rpc_proxy; task_scheduler_ = &task_scheduler; schema_service_ = &schema_service; - lease_service_ = &lease_service; backup_service_ = &backup_service; is_inited_ = true; } @@ -816,7 +770,6 @@ void ObIBackupDeleteMgr::reset() rpc_proxy_ = nullptr; task_scheduler_ = nullptr; schema_service_ = nullptr; - lease_service_ = nullptr; backup_service_ = nullptr; is_inited_ = false; } @@ -861,7 +814,7 @@ int ObUserTenantBackupDeleteMgr::deal_non_reentrant_job(const int error) #endif if (OB_FAIL(ret)) { } else if (OB_FAIL(task_mgr.init(job_attr_->tenant_id_, task_attr.task_id_, *job_attr_, *sql_proxy_, - *rpc_proxy_, *task_scheduler_, *lease_service_, *backup_service_))) { + *rpc_proxy_, *task_scheduler_, *backup_service_))) { LOG_WARN("failed to init set task mgr", K(ret)); } else if (OB_FAIL(task_mgr.deal_failed_task(task_attr.result_))) { LOG_WARN("failed to deal failed set task", K(ret), K(task_attr)); @@ -1030,7 +983,7 @@ int ObUserTenantBackupDeleteMgr::move_to_history_() SMART_VAR(ObBackupCleanTaskMgr, task_mgr) { const ObBackupCleanTaskAttr &task_attr = task_attrs.at(i); if (OB_FAIL(task_mgr.init(tenant_id_, task_attr.task_id_, *job_attr_, trans, - *rpc_proxy_, *task_scheduler_, *lease_service_, *backup_service_))) { + *rpc_proxy_, *task_scheduler_, *backup_service_))) { LOG_WARN("failed to init set task mgr", K(ret)); } else if (OB_FAIL(task_mgr.process())) { LOG_WARN("failed to task move history", K(ret), K(task_attr)); @@ -1103,7 +1056,7 @@ int ObUserTenantBackupDeleteMgr::do_cancel_() const ObBackupCleanTaskAttr &task_attr = task_attrs.at(i); if (ObBackupCleanStatus::Status::CANCELING == task_attr.status_.status_) { if (OB_FAIL(task_mgr.init(tenant_id_, task_attr.task_id_, *job_attr_, *sql_proxy_, *rpc_proxy_, - *task_scheduler_, *lease_service_, *backup_service_))) { + *task_scheduler_, *backup_service_))) { LOG_WARN("failed to init set task mgr", K(ret)); } else if (OB_FAIL(task_mgr.process())) { LOG_WARN("failed to cancel task", K(ret), K(task_attr)); @@ -1187,7 +1140,7 @@ int ObUserTenantBackupDeleteMgr::do_backup_clean_tasks_(const ObArraycheck_lease())) { - LOG_WARN("failed to check lease", K(ret)); + } else if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanTaskOperator::insert_backup_clean_task(trans, task_attr))) { LOG_WARN("failed to insert backup task", K(ret), K(task_attr)); } else { @@ -1522,8 +1475,8 @@ int ObUserTenantBackupDeleteMgr::persist_backup_piece_task_( } else if (!task_attr.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("backup clean set task is valid", K(ret)); - } else if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + } else if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanTaskOperator::insert_backup_clean_task(trans, task_attr))) { LOG_WARN("failed to insert backup task", K(ret), K(task_attr)); } @@ -1654,8 +1607,8 @@ int ObUserTenantBackupDeleteMgr::advance_job_status_( const int64_t end_ts) { int ret = OB_SUCCESS; - if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanJobOperator::advance_job_status(trans, *job_attr_, next_status, result, end_ts))) { LOG_WARN("failed to advance job status", K(ret), K(*job_attr_), K(next_status), K(result), K(end_ts)); } @@ -1750,8 +1703,6 @@ int ObSysTenantBackupDeleteMgr::handle_user_tenant_backup_delete_() int ObSysTenantBackupDeleteMgr::do_handle_user_tenant_backup_delete_(const uint64_t &tenant_id) { - // TODO: adjust usr srv rpc proxy when has tenant backup thread. - int ret = OB_SUCCESS; common::ObAddr rs_addr; obrpc::ObBackupCleanArg backup_delete_arg; @@ -1830,7 +1781,7 @@ int ObSysTenantBackupDeleteMgr::statistic_user_tenant_job_() int ObSysTenantBackupDeleteMgr::move_to_history_() { int ret = OB_SUCCESS; - if (OB_FAIL(lease_service_->check_lease())) { + if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanJobOperator::move_job_to_his(*sql_proxy_, job_attr_->tenant_id_, job_attr_->job_id_))) { LOG_WARN("failed to move job to history table", K(ret), K(*job_attr_)); @@ -1868,7 +1819,7 @@ int ObSysTenantBackupDeleteMgr::cancel_user_tenant_job_() || ObBackupCleanStatus::Status::DOING == tmp_job_attr.status_.status_) { ObBackupCleanStatus next_status; next_status.status_ = ObBackupCleanStatus::Status::CANCELING; - if (OB_FAIL(lease_service_->check_lease())) { + if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanJobOperator::advance_job_status(*sql_proxy_, tmp_job_attr, next_status))) { LOG_WARN("fail to advance user job to CANCELING", K(ret), K(tmp_job_attr), K(next_status)); @@ -1899,7 +1850,7 @@ int ObSysTenantBackupDeleteMgr::advance_status_( const int64_t end_ts) { int ret = OB_SUCCESS; - if (OB_FAIL(lease_service_->check_lease())) { + if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanJobOperator::advance_job_status(sql_proxy, *job_attr_, next_status, result, end_ts))) { LOG_WARN("failed to advance job status", K(ret), K(*job_attr_), K(next_status), K(result), K(end_ts)); @@ -1911,32 +1862,32 @@ int ObSysTenantBackupDeleteMgr::advance_status_( ObBackupAutoObsoleteDeleteTrigger::ObBackupAutoObsoleteDeleteTrigger() : ObIBackupTrigger(BackupTriggerType::BACKUP_AUTO_DELETE_TRIGGER), is_inited_(false), + tenant_id_(OB_INVALID_TENANT_ID), sql_proxy_(nullptr), rpc_proxy_(nullptr), schema_service_(nullptr), - lease_service_(nullptr), task_scheduler_(nullptr), backup_service_(nullptr) { } int ObBackupAutoObsoleteDeleteTrigger::init( + const uint64_t tenant_id, common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, share::schema::ObMultiVersionSchemaService &schema_service, - ObBackupLeaseService &lease_service, ObBackupTaskScheduler &task_scheduler, - ObBackupService &backup_service) + ObBackupCleanService &backup_service) { int ret = OB_SUCCESS; if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret)); } else { + tenant_id_ = tenant_id; sql_proxy_ = &sql_proxy; rpc_proxy_ = &rpc_proxy; schema_service_ = &schema_service; - lease_service_ = &lease_service; task_scheduler_ = &task_scheduler; backup_service_ = &backup_service; is_inited_ = true; @@ -1996,29 +1947,24 @@ int ObBackupAutoObsoleteDeleteTrigger::start_auto_delete_obsolete_data_() if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("backup auto delete obsolete bakcup do not init", K(ret)); - } else if (OB_FAIL(ObBackupCleanCommon::get_all_tenants(*schema_service_,tenant_ids))) { - LOG_WARN("failed to get all tenants", K(ret)); - } else { - for (int i = 0; i < tenant_ids.count(); ++i) { - const uint64_t tenant_id = tenant_ids.at(i); - recovery_window = 0; - default_delete_policy.reset(); - obrpc::ObBackupCleanArg arg; - arg.initiator_tenant_id_ = tenant_id; // cluster-level automatic backup clean - arg.tenant_id_ = tenant_id; - arg.type_ = ObNewBackupCleanType::DELETE_OBSOLETE_BACKUP; - if (OB_FAIL(ObDeletePolicyOperator::get_default_delete_policy(*sql_proxy_, arg.tenant_id_, default_delete_policy))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("failed to get all tenants", K(ret), K(arg)); - } - } else if (OB_FAIL(get_delete_policy_parameter_(default_delete_policy, recovery_window))) { - } else if (recovery_window <= 0) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("recovery window is unepxected", K(ret), K(arg), K(recovery_window)); - } else if (FALSE_IT(arg.value_ = now_ts - recovery_window)) { - } else if (OB_FAIL(backup_service_->handle_backup_delete(arg))) { - LOG_WARN("failed to schedule backup clean", K(ret), K(arg)); + } else if (is_meta_tenant(tenant_id_)) { + recovery_window = 0; + default_delete_policy.reset(); + obrpc::ObBackupCleanArg arg; + arg.initiator_tenant_id_ = tenant_id_; // cluster-level automatic backup clean + arg.tenant_id_ = tenant_id_; + arg.type_ = ObNewBackupCleanType::DELETE_OBSOLETE_BACKUP; + if (OB_FAIL(ObDeletePolicyOperator::get_default_delete_policy(*sql_proxy_, arg.tenant_id_, default_delete_policy))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("failed to get all tenants", K(ret), K(arg)); } + } else if (OB_FAIL(get_delete_policy_parameter_(default_delete_policy, recovery_window))) { + } else if (recovery_window <= 0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("recovery window is unepxected", K(ret), K(arg), K(recovery_window)); + } else if (FALSE_IT(arg.value_ = now_ts - recovery_window)) { + } else if (OB_FAIL(backup_service_->handle_backup_delete(arg))) { + LOG_WARN("failed to schedule backup clean", K(ret), K(arg)); } FLOG_INFO("[BACKUP_CLEAN] finish schedule auto delete", K(tenant_ids)); } diff --git a/src/rootserver/backup/ob_backup_clean_scheduler.h b/src/rootserver/backup/ob_backup_clean_scheduler.h index 20d5ed284..54fcd966a 100644 --- a/src/rootserver/backup/ob_backup_clean_scheduler.h +++ b/src/rootserver/backup/ob_backup_clean_scheduler.h @@ -13,12 +13,17 @@ #ifndef OCEANBASE_ROOTSERVER_OB_BACKUP_CLEAN_SCHEDULER_H_ #define OCEANBASE_ROOTSERVER_OB_BACKUP_CLEAN_SCHEDULER_H_ #include "ob_backup_base_job.h" -#include "rootserver/backup/ob_backup_lease_service.h" #include "share/backup/ob_backup_clean_struct.h" #include "share/backup/ob_archive_struct.h" namespace oceanbase { +namespace obrpc +{ +class ObSrvRpcProxy; +struct ObBackupCleanArg; +struct ObDeletePolicyArg; +} namespace common { class ObISQLClient; @@ -26,6 +31,9 @@ class ObISQLClient; namespace rootserver { class ObIBackupDeleteMgr; +class ObBackupTaskScheduler; +class ObBackupCleanService; +class ObServerManager; class ObBackupCleanScheduler : public ObIBackupJobScheduler { public: @@ -36,18 +44,17 @@ public: virtual int force_cancel(const uint64_t &tenant_id) override; // for lease virtual int handle_execute_over( const ObBackupScheduleTask *task, - bool &can_remove, - const ObAddr &black_server, - const int execute_ret) override; + const share::ObHAResultInfo &result_info, + bool &can_remove) override; virtual int get_need_reload_task(common::ObIAllocator &allocator, common::ObIArray &tasks) override; // reload tasks after switch master happend public: int init( + const uint64_t tenant_id, common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, share::schema::ObMultiVersionSchemaService &schema_service, - ObBackupLeaseService &lease_service, ObBackupTaskScheduler &task_scheduler, - ObBackupService &backup_service); + ObBackupCleanService &backup_service); int start_schedule_backup_clean(const obrpc::ObBackupCleanArg &in_arg); int cancel_backup_clean_job(const obrpc::ObBackupCleanArg &in_arg); int add_delete_policy(const obrpc::ObDeletePolicyArg &in_arg); @@ -61,7 +68,6 @@ private: const common::ObIArray &backup_tenant_ids, common::ObIArray &job_attrs); int get_next_job_id_(common::ObISQLClient &trans, const uint64_t tenant_id, int64_t &job_id); - int get_all_normal_tenants_(ObIArray &tenants); int get_job_need_reload_task( const share::ObBackupCleanJobAttr &job, common::ObIAllocator &allocator, @@ -92,12 +98,12 @@ private: int handle_failed_job_(const uint64_t tenant_id, const int64_t result, ObIBackupDeleteMgr &job_mgr, share::ObBackupCleanJobAttr &job_attr); private: bool is_inited_; + uint64_t tenant_id_; common::ObMySQLProxy *sql_proxy_; obrpc::ObSrvRpcProxy *rpc_proxy_; share::schema::ObMultiVersionSchemaService *schema_service_; - ObBackupLeaseService *lease_service_; ObBackupTaskScheduler *task_scheduler_; - ObBackupService *backup_service_; + ObBackupCleanService *backup_service_; private: DISALLOW_COPY_AND_ASSIGN(ObBackupCleanScheduler); }; @@ -116,9 +122,8 @@ public: common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, ObBackupTaskScheduler &task_scheduler, - ObBackupLeaseService &lease_service, share::schema::ObMultiVersionSchemaService &schema_service_, - ObBackupService &backup_service); + ObBackupCleanService &backup_service); void reset(); uint64_t get_tenant_id() const { return tenant_id_; } bool is_can_retry(const int err) const; @@ -130,8 +135,7 @@ protected: obrpc::ObSrvRpcProxy *rpc_proxy_; ObBackupTaskScheduler *task_scheduler_; share::schema::ObMultiVersionSchemaService *schema_service_; - ObBackupLeaseService* lease_service_; - ObBackupService *backup_service_; + ObBackupCleanService *backup_service_; DISALLOW_COPY_AND_ASSIGN(ObIBackupDeleteMgr); }; @@ -256,12 +260,12 @@ public: virtual int process() override; public: int init( + const uint64_t tenant_id, common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, share::schema::ObMultiVersionSchemaService &schema_service, - ObBackupLeaseService &lease_service, ObBackupTaskScheduler &task_scheduler, - ObBackupService &backup_service); + ObBackupCleanService &backup_service); private: int start_auto_delete_obsolete_data_(); int get_delete_policy_parameter_( @@ -270,12 +274,12 @@ private: int parse_time_interval_(const char *str, int64_t &val); private: bool is_inited_; + uint64_t tenant_id_; common::ObMySQLProxy *sql_proxy_; obrpc::ObSrvRpcProxy *rpc_proxy_; share::schema::ObMultiVersionSchemaService *schema_service_; - ObBackupLeaseService *lease_service_; ObBackupTaskScheduler *task_scheduler_; - ObBackupService *backup_service_; + ObBackupCleanService *backup_service_; DISALLOW_COPY_AND_ASSIGN(ObBackupAutoObsoleteDeleteTrigger); }; @@ -294,4 +298,4 @@ public: } } -#endif // OCEANBASE_ROOTSERVER_OB_BACKUP_CLEAN_SCHEDULER_H_ \ No newline at end of file +#endif // OCEANBASE_ROOTSERVER_OB_BACKUP_CLEAN_SCHEDULER_H_ diff --git a/src/rootserver/backup/ob_backup_clean_task_mgr.cpp b/src/rootserver/backup/ob_backup_clean_task_mgr.cpp index 3f001e206..a5be6e844 100644 --- a/src/rootserver/backup/ob_backup_clean_task_mgr.cpp +++ b/src/rootserver/backup/ob_backup_clean_task_mgr.cpp @@ -14,7 +14,7 @@ #include "ob_backup_clean_task_mgr.h" #include "ob_backup_clean_ls_task_mgr.h" #include "storage/ls/ob_ls.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" #include "share/backup/ob_backup_path.h" #include "share/backup/ob_backup_struct.h" #include "share/backup/ob_backup_clean_struct.h" @@ -45,7 +45,6 @@ ObBackupCleanTaskMgr::ObBackupCleanTaskMgr() job_attr_(nullptr), sql_proxy_(nullptr), rpc_proxy_(nullptr), - lease_service_(nullptr), task_scheduler_(nullptr), backup_service_(nullptr) { @@ -58,8 +57,7 @@ int ObBackupCleanTaskMgr::init( common::ObISQLClient &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, ObBackupTaskScheduler &task_scheduler, - ObBackupLeaseService &lease_service, - ObBackupService &backup_service) + ObBackupCleanService &backup_service) { int ret = OB_SUCCESS; if (IS_INIT) { @@ -99,7 +97,6 @@ int ObBackupCleanTaskMgr::init( job_attr_ = &job_attr; sql_proxy_ = &sql_proxy; rpc_proxy_ = &rpc_proxy; - lease_service_ = &lease_service; task_scheduler_ = &task_scheduler; backup_service_ = &backup_service; is_inited_ = true; @@ -115,8 +112,8 @@ int ObBackupCleanTaskMgr::advance_task_status_( const int64_t end_ts) { int ret = OB_SUCCESS; - if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanTaskOperator::advance_task_status(sql_proxy, task_attr_, next_status, result, end_ts))) { LOG_WARN("failed to advance set status", K(ret), K(task_attr_), K(next_status)); } @@ -387,8 +384,8 @@ int ObBackupCleanTaskMgr::persist_ls_tasks_() new_ls_attr.reset(); if (OB_FAIL(generate_ls_task_(ls_id, new_ls_attr))) { LOG_WARN("failed to generate log stream tasks", K(ret), K(ls_ids)); - } else if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + } else if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanLSTaskOperator::insert_ls_task(trans, new_ls_attr))) { LOG_WARN("failed to insert backup log stream task", K(ret), K(new_ls_attr)); } @@ -1065,7 +1062,7 @@ int ObBackupCleanTaskMgr::do_backup_clean_ls_tasks_( job_attr_->can_retry_ = false; ret = ls_attr.result_; LOG_WARN("retry times exceeds the limit", K(ret), K(ls_attr.retry_id_), K(ls_attr.ls_id_), K(task_attr_), K(job_attr_->can_retry_)); - } else if (OB_FAIL(ls_task_mgr.init(task_attr_, ls_attr, *task_scheduler_, *sql_proxy_, *lease_service_, *backup_service_))) { + } else if (OB_FAIL(ls_task_mgr.init(task_attr_, ls_attr, *task_scheduler_, *sql_proxy_, *backup_service_))) { LOG_WARN("failed to init task advancer", K(ret), K(ls_attr)); } else if (OB_FAIL(ls_task_mgr.process(finish_cnt))) { LOG_WARN("failed to process log stream task", K(ret)); @@ -1151,7 +1148,7 @@ int ObBackupCleanTaskMgr::do_failed_ls_task_( } else if (OB_SUCCESS == result) { result = ls_attr.result_; } - } else if (OB_FAIL(ls_task_mgr.init(task_attr_, ls_attr, *task_scheduler_, sql_proxy, *lease_service_, *backup_service_))) { + } else if (OB_FAIL(ls_task_mgr.init(task_attr_, ls_attr, *task_scheduler_, sql_proxy, *backup_service_))) { LOG_WARN("failed to init task mgr", K(ret), K(ls_attr)); } else if (OB_FAIL(ls_task_mgr.cancel(finish_cnt))) { LOG_WARN("failed to cancel task", K(ret)); @@ -1176,8 +1173,8 @@ int ObBackupCleanTaskMgr::do_cleanup() int ObBackupCleanTaskMgr::move_task_to_history_() { int ret = OB_SUCCESS; - if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupCleanLSTaskOperator::move_ls_to_his(*sql_proxy_, task_attr_.tenant_id_, task_attr_.task_id_))) { LOG_WARN("failed to move ls task to history", K(ret)); } else if (OB_FAIL(ObBackupCleanTaskOperator::move_task_to_history(*sql_proxy_, task_attr_.tenant_id_, task_attr_.task_id_))) { @@ -1210,7 +1207,7 @@ int ObBackupCleanTaskMgr::do_cancel_() if (OB_SUCCESS == ls_attr.result_) { success_ls_count++; } - } else if (OB_FAIL(task_mgr.init(task_attr_, ls_attr, *task_scheduler_, trans, *lease_service_, *backup_service_))) { + } else if (OB_FAIL(task_mgr.init(task_attr_, ls_attr, *task_scheduler_, trans, *backup_service_))) { LOG_WARN("failed to init task mgr", K(ret), K(ls_attr)); } else if (OB_FAIL(task_mgr.cancel(finish_cnt))) { LOG_WARN("failed to cancel task", K(ret)); diff --git a/src/rootserver/backup/ob_backup_clean_task_mgr.h b/src/rootserver/backup/ob_backup_clean_task_mgr.h index d559db98a..7250d6ed1 100644 --- a/src/rootserver/backup/ob_backup_clean_task_mgr.h +++ b/src/rootserver/backup/ob_backup_clean_task_mgr.h @@ -15,7 +15,6 @@ #include "share/backup/ob_backup_clean_struct.h" #include "share/backup/ob_archive_struct.h" #include "ob_backup_service.h" -#include "rootserver/backup/ob_backup_lease_service.h" namespace oceanbase { namespace rootserver @@ -36,8 +35,7 @@ public: common::ObISQLClient &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, ObBackupTaskScheduler &task_scheduler, - ObBackupLeaseService &lease_service, - ObBackupService &backup_service); + ObBackupCleanService &backup_service); int persist_ls_task(); int do_ls_task(); int do_cleanup(); @@ -103,7 +101,7 @@ private: private: bool is_inited_; - int64_t tenant_id_; + uint64_t tenant_id_; share::ObBackupSetFileDesc backup_set_info_; share::ObTenantArchivePieceAttr backup_piece_info_; share::ObBackupCleanTaskAttr task_attr_; @@ -111,9 +109,8 @@ private: share::ObBackupCleanJobAttr *job_attr_; common::ObISQLClient *sql_proxy_; obrpc::ObSrvRpcProxy *rpc_proxy_; - ObBackupLeaseService *lease_service_; ObBackupTaskScheduler *task_scheduler_; - ObBackupService *backup_service_; + ObBackupCleanService *backup_service_; private: DISALLOW_COPY_AND_ASSIGN(ObBackupCleanTaskMgr); }; diff --git a/src/rootserver/backup/ob_backup_data_ls_task_mgr.cpp b/src/rootserver/backup/ob_backup_data_ls_task_mgr.cpp old mode 100644 new mode 100755 index e75ca8897..b92db6a5e --- a/src/rootserver/backup/ob_backup_data_ls_task_mgr.cpp +++ b/src/rootserver/backup/ob_backup_data_ls_task_mgr.cpp @@ -13,11 +13,18 @@ #define USING_LOG_PREFIX RS #include "ob_backup_data_ls_task_mgr.h" +#include "ob_backup_schedule_task.h" +#include "ob_backup_task_scheduler.h" #include "share/backup/ob_backup_struct.h" #include "rootserver/backup/ob_backup_service.h" #include "share/ls/ob_ls_status_operator.h" #include "storage/backup/ob_backup_operator.h" #include "rootserver/ob_rs_event_history_table_operator.h" +#include "storage/backup/ob_backup_data_store.h" +#include "share/backup/ob_backup_connectivity.h" +#include "storage/backup/ob_backup_data_struct.h" +#include "storage/backup/ob_backup_operator.h" + namespace oceanbase { @@ -33,7 +40,6 @@ ObBackupDataLSTaskMgr::ObBackupDataLSTaskMgr() set_task_attr_(nullptr), task_scheduler_(nullptr), sql_proxy_(nullptr), - lease_service_(nullptr), backup_service_(nullptr) { } @@ -48,8 +54,7 @@ int ObBackupDataLSTaskMgr::init( ObBackupLSTaskAttr &ls_attr, ObBackupTaskScheduler &task_scheduler, common::ObISQLClient &sql_proxy, - ObBackupLeaseService &lease_service, - ObBackupService &backup_service) + ObBackupDataService &backup_service) { int ret = OB_SUCCESS; if (IS_INIT) { @@ -64,7 +69,6 @@ int ObBackupDataLSTaskMgr::init( ls_attr_ = &ls_attr; task_scheduler_ = &task_scheduler; sql_proxy_ = &sql_proxy; - lease_service_ = &lease_service; backup_service_ = &backup_service; is_inited_ = true; } @@ -113,11 +117,8 @@ int ObBackupDataLSTaskMgr::process(int64_t &finish_cnt) int ObBackupDataLSTaskMgr::gen_and_add_task_() { int ret = OB_SUCCESS; - ObBackupDataTaskType type; - type.type_ = ls_attr_->task_type_.type_; DEBUG_SYNC(BEFORE_ADD_BACKUP_TASK_INTO_SCHEDULER); switch (ls_attr_->task_type_.type_) { - case ObBackupDataTaskType::Type::BACKUP_DATA_SYS: case ObBackupDataTaskType::Type::BACKUP_DATA_MINOR: case ObBackupDataTaskType::Type::BACKUP_DATA_MAJOR: { if (ObBackupDataTaskType::Type::BACKUP_DATA_MAJOR == ls_attr_->task_type_.type_) { @@ -159,20 +160,21 @@ int ObBackupDataLSTaskMgr::gen_and_add_task_() return ret; } -int ObBackupDataLSTaskMgr::check_ls_is_dropped_(bool &is_dropped) +int ObBackupDataLSTaskMgr::check_ls_is_dropped( + const share::ObBackupLSTaskAttr &ls_attr, common::ObISQLClient &sql_proxy, bool &is_dropped) { int ret = OB_SUCCESS; ObLSStatusOperator op; share::ObLSStatusInfo status_info; is_dropped = false; - if (share::ObBackupDataTaskType::Type::BACKUP_BUILD_INDEX == ls_attr_->task_type_.type_) { - } else if (OB_FAIL(op.get_ls_status_info(ls_attr_->tenant_id_, ls_attr_->ls_id_, status_info, *sql_proxy_))) { + if (share::ObBackupDataTaskType::Type::BACKUP_BUILD_INDEX == ls_attr.task_type_.type_) { + } else if (OB_FAIL(op.get_ls_status_info(ls_attr.tenant_id_, ls_attr.ls_id_, status_info, sql_proxy))) { if (OB_ENTRY_NOT_EXIST == ret) { is_dropped = true; ret = OB_SUCCESS; - LOG_INFO("ls has been dropped", K(ret), KPC(ls_attr_)); + LOG_INFO("ls has been dropped", K(ret), K(ls_attr)); } else { - LOG_WARN("fail to get ls status", K(ret), KPC(ls_attr_)); + LOG_WARN("fail to get ls status", K(ret), K(ls_attr)); } } return ret; @@ -187,18 +189,19 @@ int ObBackupDataLSTaskMgr::gen_and_add_backup_meta_task_() next_status.status_ = ObBackupTaskStatus::Status::PENDING; bool is_dropped = false; - if (OB_FAIL(check_ls_is_dropped_(is_dropped))) { + if (OB_FAIL(check_ls_is_dropped(*ls_attr_, *sql_proxy_, is_dropped))) { LOG_WARN("fail to check ls is dropped", K(ret)); } else if (is_dropped) { share::ObBackupTaskStatus next_status(ObBackupTaskStatus::Status::FINISH); - if (ObBackupDataLSTaskMgr::advance_status(*lease_service_, *sql_proxy_, *ls_attr_, next_status, - OB_LS_NOT_EXIST, ObTimeUtility::current_time())) { + ls_attr_->result_ = OB_LS_NOT_EXIST; + ls_attr_->end_ts_ = ObTimeUtility::current_time(); + if (OB_FAIL(advance_status_(next_status))) { LOG_WARN("fail to advance ls task status to finish", K(ret)); } } else if (OB_FAIL(task.build(*job_attr_, *set_task_attr_, *ls_attr_))) { - LOG_WARN("[DATA_BACKUP]failed to build task", K(ret), KPC(job_attr_), KPC(set_task_attr_), KPC(ls_attr_)); - } else if (OB_FAIL(advance_status(*lease_service_, *sql_proxy_, *ls_attr_, next_status))) { - LOG_WARN("[DATA_BACKUP]failed to advance task status", K(ret), KPC(ls_attr_), K(next_status)); + LOG_WARN("[DATA_BACKUP]failed to build task", K(ret), K(*job_attr_), K(*set_task_attr_), K(*ls_attr_)); + } else if (OB_FAIL(advance_status_(next_status))) { + LOG_WARN("[DATA_BACKUP]failed to advance task status", K(ret), K(*ls_attr_), K(next_status)); } else if (OB_FAIL(task_scheduler_->add_task(task))) { LOG_WARN("[DATA_BACKUP]failed to add task", K(ret), KPC(job_attr_), K(task)); } @@ -214,18 +217,19 @@ int ObBackupDataLSTaskMgr::gen_and_add_backup_data_task_() next_status.status_ = ObBackupTaskStatus::Status::PENDING; bool is_dropped = false; - if (OB_FAIL(check_ls_is_dropped_(is_dropped))) { + if (OB_FAIL(check_ls_is_dropped(*ls_attr_, *sql_proxy_, is_dropped))) { LOG_WARN("fail to check ls is dropped", K(ret)); } else if (is_dropped) { share::ObBackupTaskStatus next_status(ObBackupTaskStatus::Status::FINISH); - if (ObBackupDataLSTaskMgr::advance_status(*lease_service_, *sql_proxy_, *ls_attr_, next_status, - OB_LS_NOT_EXIST, ObTimeUtility::current_time())) { + ls_attr_->result_ = OB_LS_NOT_EXIST; + ls_attr_->end_ts_ = ObTimeUtility::current_time(); + if (OB_FAIL(advance_status_(next_status))) { LOG_WARN("fail to advance ls task status to finish", K(ret)); } } else if (OB_FAIL(task.build(*job_attr_, *set_task_attr_, *ls_attr_))) { - LOG_WARN("[DATA_BACKUP]failed to build task", K(ret), KPC(job_attr_), KPC(set_task_attr_), KPC(ls_attr_)); - } else if (OB_FAIL(advance_status(*lease_service_, *sql_proxy_, *ls_attr_, next_status))) { - LOG_WARN("[DATA_BACKUP]failed to advance task status", K(ret), KPC(ls_attr_), K(next_status)); + LOG_WARN("[DATA_BACKUP]failed to build task", K(ret), K(*job_attr_), K(*set_task_attr_), K(*ls_attr_)); + } else if (OB_FAIL(advance_status_(next_status))) { + LOG_WARN("[DATA_BACKUP]failed to advance task status", K(ret), K(*ls_attr_), K(next_status)); } else if (OB_FAIL(task_scheduler_->add_task(task))) { LOG_WARN("[DATA_BACKUP]failed to add task", K(ret), KPC(job_attr_), K(task)); } @@ -241,9 +245,9 @@ int ObBackupDataLSTaskMgr::gen_and_add_backup_compl_log_() ObBackupTaskStatus next_status; next_status.status_ = ObBackupTaskStatus::Status::PENDING; if (OB_FAIL(task.build(*job_attr_, *set_task_attr_, *ls_attr_))) { - LOG_WARN("[DATA_BACKUP]failed to build task", K(ret), KPC(job_attr_), KPC(set_task_attr_), KPC(ls_attr_)); - } else if (OB_FAIL(advance_status(*lease_service_, *sql_proxy_, *ls_attr_, next_status))) { - LOG_WARN("[DATA_BACKUP]failed to advance task status", K(ret), KPC(ls_attr_), K(next_status)); + LOG_WARN("[DATA_BACKUP]failed to build task", K(ret), K(*job_attr_), K(*set_task_attr_), K(*ls_attr_)); + } else if (OB_FAIL(advance_status_(next_status))) { + LOG_WARN("[DATA_BACKUP]failed to advance task status", K(ret), K(*ls_attr_), K(next_status)); } else if (OB_FAIL(task_scheduler_->add_task(task))) { LOG_WARN("[DATA_BACKUP]failed to add task", K(ret), KPC(ls_attr_)); } @@ -259,70 +263,76 @@ int ObBackupDataLSTaskMgr::gen_and_add_build_index_task_() ObBackupTaskStatus next_status; next_status.status_ = ObBackupTaskStatus::Status::PENDING; if (OB_FAIL(task.build(*job_attr_, *set_task_attr_, *ls_attr_))) { - LOG_WARN("[DATA_BACKUP]failed to build task", K(ret), KPC(job_attr_), KPC(set_task_attr_), KPC(ls_attr_)); - } else if (OB_FAIL(advance_status(*lease_service_, *sql_proxy_, *ls_attr_, next_status))) { - LOG_WARN("[DATA_BACKUP]failed to advance task status", K(ret), KPC(ls_attr_), K(next_status)); + LOG_WARN("[DATA_BACKUP]failed to build task", K(ret), K(*job_attr_), K(*set_task_attr_), K(*ls_attr_)); + } else if (OB_FAIL(advance_status_(next_status))) { + LOG_WARN("[DATA_BACKUP]failed to advance task status", K(ret), K(*ls_attr_), K(next_status)); } else if (OB_FAIL(task_scheduler_->add_task(task))) { LOG_WARN("[DATA_BACKUP]failed to add task", K(ret), KPC(ls_attr_)); } return ret; } -int ObBackupDataLSTaskMgr::advance_status( - ObBackupLeaseService &lease_service, - common::ObISQLClient &sql_proxy, - const ObBackupLSTaskAttr &ls_attr, - const ObBackupTaskStatus &next_status, - const int result, - const int64_t end_ts) +int ObBackupDataLSTaskMgr::advance_status_(const share::ObBackupTaskStatus &next_status) { int ret = OB_SUCCESS; - if (!next_status.is_valid() || !ls_attr.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(next_status), K(ls_attr)); - } else if (OB_FAIL(lease_service.check_lease())) { - LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret)); - } else if (OB_FAIL(ObBackupLSTaskOperator::advance_status(sql_proxy, ls_attr, next_status, result, end_ts))) { - LOG_WARN("[DATA_BACKUP]failed to advance log stream status", K(ret), K(ls_attr), K(next_status), K(result), K(end_ts)); + ObSqlString extra_condition; + ls_attr_->status_ = next_status; + if (OB_FAIL(extra_condition.assign_fmt( + "%s = %ld and %s = %ld", OB_STR_TURN_ID, ls_attr_->turn_id_, OB_STR_RETRY_ID, ls_attr_->retry_id_))) { + LOG_WARN("failed to assign extra condition", K(ret)); + } else if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); + } else if (OB_FAIL(ObBackupLSTaskOperator::report_ls_task(*sql_proxy_, *ls_attr_, extra_condition))) { + LOG_WARN("failed to report ls task", K(ret), KPC(ls_attr_)); + } else { + LOG_INFO("advance ls task status", KPC(ls_attr_)); } return ret; } -int ObBackupDataLSTaskMgr::update_black_server( - ObBackupLeaseService &lease_service, - common::ObISQLClient &sql_proxy, - const ObBackupLSTaskAttr &ls_attr, - const ObAddr &block_server) +int ObBackupDataLSTaskMgr::handle_execute_over( + ObBackupDataService &backup_service, common::ObISQLClient &sql_proxy, const share::ObBackupLSTaskAttr &ls_attr, + const share::ObHAResultInfo &result_info) { - int ret = OB_SUCCESS; + int ret = OB_SUCCESS; + ObBackupLSTaskAttr new_ls_attr; + ObSqlString extra_condition; + share::ObBackupDataType backup_data_type; int64_t full_replica_num = 0; - ObSqlString black_server_sql_string(""); - ObSEArray new_black_servers_; - if (!block_server.is_valid() || !ls_attr.is_valid()) { + if (!ls_attr.is_valid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(block_server), K(ls_attr)); + LOG_WARN("invalid argument", K(ret), K(ls_attr)); + } else if (OB_FAIL(new_ls_attr.assign(ls_attr))) { + LOG_WARN("failed to assign ls attr", K(ret), K(ls_attr)); + } else if (OB_FAIL(extra_condition.assign_fmt( + "%s = %ld and %s = %ld and %s='%s'", OB_STR_TURN_ID, ls_attr.turn_id_, OB_STR_RETRY_ID, ls_attr.retry_id_, + OB_STR_STATUS, ls_attr.status_.get_str()))) { + LOG_WARN("failed to assign extra condition", K(ret)); + } else if (OB_FALSE_IT(new_ls_attr.end_ts_ = ObTimeUtility::current_time())) { } else if (OB_FAIL(ObBackupUtils::get_full_replica_num(ls_attr.tenant_id_, full_replica_num))) { LOG_WARN("failed to get full replica num", K(ret)); - } else if (ls_attr.black_servers_.count() + 1 == full_replica_num) { - // all replicas are in black servers, clear the black servers. - } else if (OB_FAIL(new_black_servers_.assign(ls_attr.black_servers_))) { - LOG_WARN("failed to assign black servers", K(ret)); - } else if (OB_FAIL(new_black_servers_.push_back(block_server))) { - LOG_WARN("failed to push back black server", K(ret)); - } else if (OB_FAIL(ls_attr.get_black_server_str(new_black_servers_, black_server_sql_string))) { - LOG_WARN("failed to get black server str", K(ret), K(new_black_servers_)); - } - if (FAILEDx(lease_service.check_lease())) { - LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret)); - } else if (OB_FAIL(ObBackupLSTaskOperator::update_black_server( - sql_proxy, ls_attr.task_id_, ls_attr.tenant_id_, ls_attr.ls_id_, black_server_sql_string.string()))) { - LOG_WARN("[DATA_BACKUP]failed to update block server", K(ret), K(ls_attr), K(black_server_sql_string)); + } else if (new_ls_attr.black_servers_.count() + 1 == full_replica_num && OB_FALSE_IT(new_ls_attr.black_servers_.reset())) { + } else if (OB_SUCCESS != result_info.result_ && OB_FAIL(new_ls_attr.black_servers_.push_back(result_info.addr_))) { + LOG_WARN("failed to push back black server", K(ret), K(result_info)); + } else if (OB_FALSE_IT(new_ls_attr.result_ = result_info.result_)) { + } else if (OB_FALSE_IT(new_ls_attr.status_ = ObBackupTaskStatus::FINISH)) { + } else if (OB_FAIL(result_info.get_comment_str(new_ls_attr.comment_))) { + LOG_WARN("failed to get comment str", K(ret)); + } else if (OB_FAIL(ObBackupLSTaskOperator::report_ls_task(sql_proxy, new_ls_attr, extra_condition))) { + LOG_WARN("failed to report ls task", K(ret), K(new_ls_attr), K(extra_condition)); + } else if (!ls_attr.task_type_.is_backup_data()) { + // do nothing + } else if (OB_FAIL(ls_attr.task_type_.get_backup_data_type(backup_data_type))) { + LOG_WARN("failed to get backup data type", K(ret), K(ls_attr)); + } else if (OB_FAIL(backup::ObLSBackupOperator::mark_ls_task_info_final(ls_attr.task_id_, ls_attr.tenant_id_, + ls_attr.ls_id_, ls_attr.turn_id_, ls_attr.retry_id_, backup_data_type, sql_proxy))) { + LOG_WARN("[DATA_BACKUP]failed to update ls task info final to True", K(ret), K(ls_attr)); } return ret; } int ObBackupDataLSTaskMgr::redo_ls_task( - ObBackupLeaseService &lease_service, + ObBackupDataService &backup_service, common::ObISQLClient &sql_proxy, const ObBackupLSTaskAttr &ls_attr, const int64_t start_turn_id, @@ -331,22 +341,39 @@ int ObBackupDataLSTaskMgr::redo_ls_task( { int ret = OB_SUCCESS; share::ObBackupDataType backup_data_type; + ObBackupLSTaskAttr new_ls_attr; + ObSqlString extra_condition; if (!ls_attr.is_valid() || start_turn_id <= 0 || turn_id <= 0 || retry_id < 0) { ret = OB_INVALID_ARGUMENT; LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(ls_attr), K(start_turn_id), K(turn_id), K(retry_id)); - } else if (OB_FAIL(lease_service.check_lease())) { - LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret)); - } else if (OB_FAIL(ObBackupLSTaskOperator::redo_ls_task(sql_proxy, ls_attr, start_turn_id, turn_id, retry_id))) { - LOG_WARN("[DATA_BACKUP]failed to redo ls task", K(ret), K(ls_attr), K(start_turn_id), K(turn_id), K(retry_id)); - } else if (!ls_attr.task_type_.is_backup_data()) { - // do nothing - } else if (OB_FAIL(ls_attr.task_type_.get_backup_data_type(backup_data_type))) { - LOG_WARN("failed to get backup data type", K(ret)); - } else if (OB_FAIL(backup::ObLSBackupOperator::insert_ls_backup_task_info(ls_attr.tenant_id_, ls_attr.task_id_, - turn_id, retry_id, ls_attr.ls_id_, ls_attr.backup_set_id_, backup_data_type, sql_proxy))) { - LOG_WARN("failed to insert ls backup task info", K(ret), K(ls_attr), K(backup_data_type)); + } else if (OB_FAIL(new_ls_attr.assign(ls_attr))) { + LOG_WARN("failed to assign new ls attr", K(ret), K(ls_attr)); + } else if (OB_FAIL(extra_condition.assign_fmt( + "%s = %ld and %s = %ld and %s='%s'", OB_STR_TURN_ID, ls_attr.turn_id_, OB_STR_RETRY_ID, ls_attr.retry_id_, + OB_STR_STATUS, ls_attr.status_.get_str()))) { + LOG_WARN("failed to assign extra condition", K(ret)); } else { - LOG_INFO("redo ls task", K(turn_id), K(retry_id), K(ls_attr)); + new_ls_attr.start_turn_id_ = start_turn_id; + new_ls_attr.turn_id_ = turn_id; + new_ls_attr.retry_id_ = retry_id; + new_ls_attr.status_ = ObBackupTaskStatus::INIT; + new_ls_attr.result_ = OB_SUCCESS; + new_ls_attr.dst_.reset(); + new_ls_attr.task_trace_id_.reset(); + if (OB_FAIL(backup_service.check_leader())) { + LOG_WARN("[DATA_BACKUP]failed to check leader", K(ret)); + } else if (OB_FAIL(ObBackupLSTaskOperator::report_ls_task(sql_proxy, new_ls_attr, extra_condition))) { + LOG_WARN("[DATA_BACKUP]failed to redo ls task", K(ret), K(new_ls_attr), K(extra_condition)); + } else if (!ls_attr.task_type_.is_backup_data()) { + // do nothing + } else if (OB_FAIL(ls_attr.task_type_.get_backup_data_type(backup_data_type))) { + LOG_WARN("failed to get backup data type", K(ret)); + } else if (OB_FAIL(backup::ObLSBackupOperator::insert_ls_backup_task_info(ls_attr.tenant_id_, ls_attr.task_id_, + turn_id, retry_id, ls_attr.ls_id_, ls_attr.backup_set_id_, backup_data_type, sql_proxy))) { + LOG_WARN("failed to insert ls backup task info", K(ret), K(ls_attr), K(backup_data_type), K(turn_id), K(retry_id)); + } else { + LOG_INFO("redo ls task", K(turn_id), K(retry_id), K(ls_attr)); + } } return ret; } @@ -358,7 +385,7 @@ int ObBackupDataLSTaskMgr::finish_(int64_t &finish_cnt) if (OB_ISNULL(job_attr_) || OB_ISNULL(ls_attr_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]attr should not be null", K(ret), KP_(job_attr), KP_(ls_attr)); - } else if (OB_SUCCESS == ls_attr_->result_/* || OB_LS_NOT_EXIST == ls_attr_->result_*/) { // TODO(yangyi.yyy): change turn need use another error code in 4.1 + } else if (OB_SUCCESS == ls_attr_->result_ || OB_LS_NOT_EXIST == ls_attr_->result_ || OB_NO_TABLET_NEED_BACKUP == ls_attr_->result_) { finish_cnt++; } else { bool ls_can_retry = true; @@ -377,7 +404,6 @@ int ObBackupDataLSTaskMgr::finish_(int64_t &finish_cnt) } break; } - case ObBackupDataTaskType::BACKUP_DATA_SYS: case ObBackupDataTaskType::BACKUP_DATA_MINOR: case ObBackupDataTaskType::BACKUP_DATA_MAJOR: case ObBackupDataTaskType::BACKUP_BUILD_INDEX: { @@ -410,7 +436,7 @@ int ObBackupDataLSTaskMgr::finish_(int64_t &finish_cnt) } else if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(ls_attr_->tenant_id_)))) { LOG_WARN("fail to start trans", K(ret)); } else { - if (OB_FAIL(redo_ls_task(*lease_service_, trans, *ls_attr_, ls_attr_->start_turn_id_, + if (OB_FAIL(redo_ls_task(*backup_service_, trans, *ls_attr_, ls_attr_->start_turn_id_, ls_attr_->turn_id_, next_retry_id))) { LOG_WARN("[DATA_BACKUP]failed to redo ls task", K(ret), KPC(ls_attr_)); } @@ -431,34 +457,16 @@ int ObBackupDataLSTaskMgr::finish_(int64_t &finish_cnt) } } else { ret = ls_attr_->result_; + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(job_attr_->comment_.assign(ls_attr_->comment_))) { + LOG_WARN("failed to assign comment", K(ret), K(tmp_ret)); + } LOG_WARN("ls task failed, backup can't not continue", K(ret), KPC(ls_attr_)); } } return ret; } -int ObBackupDataLSTaskMgr::mark_ls_task_info_final( - ObBackupLeaseService &lease_service, - common::ObISQLClient &sql_proxy, - const ObBackupLSTaskAttr &ls_attr) -{ - int ret = OB_SUCCESS; - share::ObBackupDataType backup_data_type; - if (ObBackupDataTaskType::Type::BACKUP_PLUS_ARCHIVE_LOG == ls_attr.task_type_.type_ - || ObBackupDataTaskType::Type::BACKUP_BUILD_INDEX == ls_attr.task_type_.type_) { // do nothing - } else if (OB_FAIL(lease_service.check_lease())) { - LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret)); - } else if (!ls_attr.task_type_.is_backup_data()) { - // do nothing - } else if (OB_FAIL(ls_attr.task_type_.get_backup_data_type(backup_data_type))) { - LOG_WARN("failed to get backup data type", K(ret), K(ls_attr)); - } else if (OB_FAIL(backup::ObLSBackupOperator::mark_ls_task_info_final(ls_attr.task_id_, ls_attr.tenant_id_, ls_attr.ls_id_, - ls_attr.turn_id_, ls_attr.retry_id_, backup_data_type, sql_proxy))) { - LOG_WARN("[DATA_BACKUP]failed to update ls task info final to True", K(ret), K(ls_attr)); - } - return ret; -} - int ObBackupDataLSTaskMgr::cancel(int64_t &finish_cnt) { // INIT: just update status to FINISH and result to OB_CANCELED @@ -466,7 +474,6 @@ int ObBackupDataLSTaskMgr::cancel(int64_t &finish_cnt) // DOING: call cancel_task interface of task_scheduler and update status to FINISH and result to OB_CANCELED; // FINISH: just update status to FINISH and result to OB_CANCELED int ret = OB_SUCCESS; - int64_t end_ts = ObTimeUtility::current_time(); ObBackupTaskStatus next_status; next_status.status_ = ObBackupTaskStatus::Status::FINISH; if (ObBackupTaskStatus::Status::PENDING == ls_attr_->status_.status_ @@ -480,9 +487,11 @@ int ObBackupDataLSTaskMgr::cancel(int64_t &finish_cnt) } } } + ls_attr_->result_ = OB_CANCELED; + ls_attr_->end_ts_ = ObTimeUtility::current_time(); if (OB_FAIL(ret)) { - } else if (OB_FAIL(advance_status(*lease_service_, *sql_proxy_, *ls_attr_, next_status, OB_CANCELED, end_ts))) { - LOG_WARN("[DATA_BACKUP]failed to advance status", K(ret), KPC(ls_attr_), K(next_status)); + } else if (OB_FAIL(advance_status_(next_status))) { + LOG_WARN("[DATA_BACKUP]failed to advance status", K(ret), K(*ls_attr_), K(next_status)); } else { ++finish_cnt; } diff --git a/src/rootserver/backup/ob_backup_data_ls_task_mgr.h b/src/rootserver/backup/ob_backup_data_ls_task_mgr.h index ee71d7f24..988db22ee 100644 --- a/src/rootserver/backup/ob_backup_data_ls_task_mgr.h +++ b/src/rootserver/backup/ob_backup_data_ls_task_mgr.h @@ -30,38 +30,32 @@ public: share::ObBackupLSTaskAttr &ls_attr, ObBackupTaskScheduler &task_scheduler, common::ObISQLClient &sql_proxy, - ObBackupLeaseService &lease_service, - ObBackupService &backup_service); + ObBackupDataService &backup_service); // result : when task can't retry, return the result which is the error code int process(int64_t &finish_cnt); int cancel(int64_t &finish_cnt); - static int advance_status(ObBackupLeaseService &lease_service, - common::ObISQLClient &sql_proxy, - const share::ObBackupLSTaskAttr &ls_attr, - const share::ObBackupTaskStatus &next_status, - const int result = OB_SUCCESS, - const int64_t end_ts = 0); - static int redo_ls_task(ObBackupLeaseService &lease_service, + + static int redo_ls_task(ObBackupDataService &backup_service, common::ObISQLClient &sql_proxy, const share::ObBackupLSTaskAttr &ls_attr, const int64_t start_turn_id, const int64_t turn_id, const int64_t retry_id); - static int mark_ls_task_info_final(ObBackupLeaseService &lease_service, - common::ObISQLClient &sql_proxy, - const share::ObBackupLSTaskAttr &ls_attr); - static int update_black_server(ObBackupLeaseService &lease_service, + static int handle_execute_over(ObBackupDataService &backup_service, + common::ObISQLClient &sql_proxy, + const share::ObBackupLSTaskAttr &ls_attr, + const share::ObHAResultInfo &result_info); + static int check_ls_is_dropped(const share::ObBackupLSTaskAttr &ls_attr, common::ObISQLClient &sql_proxy, - const share::ObBackupLSTaskAttr &ls_attr, - const ObAddr &block_server); + bool &is_dropped); private: int gen_and_add_task_(); - int check_ls_is_dropped_(bool &is_dropped); int gen_and_add_backup_data_task_(); int gen_and_add_backup_meta_task_(); int gen_and_add_backup_compl_log_(); int gen_and_add_build_index_task_(); int finish_(int64_t &finish_cnt); + int advance_status_(const share::ObBackupTaskStatus &next_status); private: bool is_inited_; share::ObBackupJobAttr *job_attr_; @@ -69,8 +63,7 @@ private: share::ObBackupSetTaskAttr *set_task_attr_; ObBackupTaskScheduler *task_scheduler_; common::ObISQLClient *sql_proxy_; - ObBackupLeaseService *lease_service_; - ObBackupService *backup_service_; + ObBackupDataService *backup_service_; DISALLOW_COPY_AND_ASSIGN(ObBackupDataLSTaskMgr); }; diff --git a/src/rootserver/backup/ob_backup_data_scheduler.cpp b/src/rootserver/backup/ob_backup_data_scheduler.cpp index 6b9ac9c29..de86e0553 100644 --- a/src/rootserver/backup/ob_backup_data_scheduler.cpp +++ b/src/rootserver/backup/ob_backup_data_scheduler.cpp @@ -15,7 +15,9 @@ #include "ob_backup_data_scheduler.h" #include "ob_backup_data_ls_task_mgr.h" #include "ob_backup_data_set_task_mgr.h" +#include "ob_backup_task_scheduler.h" #include "ob_backup_service.h" +#include "ob_backup_schedule_task.h" #include "storage/tx/ob_ts_mgr.h" #include "rootserver/ob_root_utils.h" #include "share/backup/ob_tenant_archive_mgr.h" @@ -36,34 +38,34 @@ namespace rootserver ObBackupDataScheduler::ObBackupDataScheduler() : ObIBackupJobScheduler(BackupJobType::BACKUP_DATA_JOB), is_inited_(false), + tenant_id_(OB_INVALID_TENANT_ID), sql_proxy_(nullptr), rpc_proxy_(nullptr), schema_service_(nullptr), task_scheduler_(nullptr), - lease_service_(nullptr), backup_service_(nullptr) { } int ObBackupDataScheduler::init( + const uint64_t tenant_id, common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, share::schema::ObMultiVersionSchemaService &schema_service, - ObBackupLeaseService &lease_service, ObBackupTaskScheduler &task_scheduler, - ObBackupService &backup_service) + ObBackupDataService &backup_service) { int ret = OB_SUCCESS; if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("[DATA_BACKUP]init twice", K(ret)); } else { + tenant_id_ = tenant_id; sql_proxy_ = &sql_proxy; rpc_proxy_ = &rpc_proxy; schema_service_ = &schema_service; task_scheduler_ = &task_scheduler; backup_service_ = &backup_service; - lease_service_ = &lease_service; is_inited_ = true; } return ret; @@ -90,39 +92,32 @@ int ObBackupDataScheduler::get_need_reload_task( // 2. step1: get all peindg or doing ls tasks in __all_backup_ls_task from all doing jobs // 3. step2: add pending task into wait_list and add doing task into schedule_list int ret = OB_SUCCESS; + ObArray jobs; + ObArray ls_tasks; bool for_update = false; - ObArray tenant_ids; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("[DATA_BACKUP]not init", K(ret)); - } else if (OB_FAIL(get_all_normal_tenants_(tenant_ids))) { - LOG_WARN("fail to get all normal tenants", K(ret)); + } else if (OB_FAIL(ObBackupJobOperator::get_jobs(*sql_proxy_, tenant_id_, for_update, jobs))) { + LOG_WARN("[DATA_BACKUP]failed to get backup jobs", K(ret), K_(tenant_id)); + } else if (jobs.empty()) { + LOG_INFO("[DATA_BACKUP]no job need to reload", K_(tenant_id)); } else { - ARRAY_FOREACH(tenant_ids, i) { - const uint64_t tenant_id = tenant_ids.at(i); - ObArray jobs; - ObArray ls_tasks; - if (OB_FAIL(ObBackupJobOperator::get_jobs(*sql_proxy_, tenant_id, for_update, jobs))) { - LOG_WARN("[DATA_BACKUP]failed to get backup jobs", K(ret), K(tenant_id)); - } else if (jobs.empty()) { - LOG_INFO("[DATA_BACKUP]no job need to reload"); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < jobs.count(); ++i) { - ls_tasks.reset(); - const ObBackupJobAttr &job = jobs.at(i); - ObBackupSetTaskAttr set_task_attr; - bool is_valid = true; - if (OB_SYS_TENANT_ID == job.tenant_id_ - || ObBackupStatus::Status::DOING != job.status_.status_) { - } else if (OB_FAIL(ObBackupTaskOperator::get_backup_task(*sql_proxy_, job.job_id_, job.tenant_id_, set_task_attr))) { - LOG_WARN("[DATA_BACKUP]failed to get set task", K(ret), K(job)); - } else if (OB_FAIL(ObBackupLSTaskOperator::get_ls_tasks(*sql_proxy_, job.job_id_, job.tenant_id_, for_update, ls_tasks))) { - LOG_WARN("[DATA_BACKUP]failed to get ls tasks", K(ret), K(job)); - } else if (ls_tasks.empty()) { // no ls task, no need to reload - } else if (OB_FAIL(do_get_need_reload_task_(job, set_task_attr, ls_tasks, allocator, tasks))) { - LOG_WARN("[DATA_BACKUP]failed to reload ls task to scheduler", K(ret), K(job), K(ls_tasks)); - } - } + for (int64_t i = 0; OB_SUCC(ret) && i < jobs.count(); ++i) { + ls_tasks.reset(); + const ObBackupJobAttr &job = jobs.at(i); + ObBackupSetTaskAttr set_task_attr; + bool is_valid = true; + if (OB_SYS_TENANT_ID == job.tenant_id_ + || ObBackupStatus::Status::DOING != job.status_.status_) { + } else if (OB_FAIL(ObBackupTaskOperator::get_backup_task( + *sql_proxy_, job.job_id_, job.tenant_id_, false/*for update*/, set_task_attr))) { + LOG_WARN("[DATA_BACKUP]failed to get set task", K(ret), K(job)); + } else if (OB_FAIL(ObBackupLSTaskOperator::get_ls_tasks(*sql_proxy_, job.job_id_, job.tenant_id_, for_update, ls_tasks))) { + LOG_WARN("[DATA_BACKUP]failed to get ls tasks", K(ret), K(job)); + } else if (ls_tasks.empty()) { // no ls task, no need to reload + } else if (OB_FAIL(do_get_need_reload_task_(job, set_task_attr, ls_tasks, allocator, tasks))) { + LOG_WARN("[DATA_BACKUP]failed to reload ls task to scheduler", K(ret), K(job), K(ls_tasks)); } } } @@ -144,7 +139,20 @@ int ObBackupDataScheduler::do_get_need_reload_task_( for (int64_t i = 0; OB_SUCC(ret) && i < ls_tasks.count(); ++i) { const ObBackupLSTaskAttr &ls_task = ls_tasks.at(i); ObBackupScheduleTask *task = nullptr; - if (OB_FAIL(build_task_(job, set_task_attr, ls_task, allocator, task))) { + bool is_dropped = false; + if (OB_FAIL(ObBackupDataLSTaskMgr::check_ls_is_dropped(ls_task, *sql_proxy_, is_dropped))) { + LOG_WARN("failed to check ls is dropped", K(ret), K(ls_task)); + } else if (is_dropped) { + // ls deleted, no need to reload, mark it to finish + ObHAResultInfo result_info(ObHAResultInfo::ROOT_SERVICE, + GCONF.self_addr_, + share::ObTaskId(*ObCurTraceId::get_trace_id()), + OB_LS_NOT_EXIST); + if (OB_FAIL(ObBackupDataLSTaskMgr::handle_execute_over( + *backup_service_, *sql_proxy_, ls_task, result_info))) { + LOG_WARN("failed to handle execute over", K(ret), K(ls_task)); + } + } else if (OB_FAIL(build_task_(job, set_task_attr, ls_task, allocator, task))) { LOG_WARN("[DATA_BACKUP]failed to build task", K(ret), K(job), K(ls_task)); } else if (OB_ISNULL(task)) { ret = OB_ERR_UNEXPECTED; @@ -170,7 +178,6 @@ int ObBackupDataScheduler::build_task_( int ret = OB_SUCCESS; switch (ls_task.task_type_.type_) { - case ObBackupDataTaskType::Type::BACKUP_DATA_SYS: case ObBackupDataTaskType::Type::BACKUP_DATA_MINOR: case ObBackupDataTaskType::Type::BACKUP_DATA_MAJOR: { HEAP_VAR(ObBackupDataLSTask, tmp_task) { @@ -237,44 +244,6 @@ int ObBackupDataScheduler::do_build_task_( return ret; } -int ObBackupDataScheduler::get_all_normal_tenants_(ObIArray &tenants) -{ - int ret = OB_SUCCESS; - ObSchemaGetterGuard schema_guard; - ObArray tmp_tenantid_array; - if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("failed to get schema guard", K(ret)); - } else if (OB_FAIL(schema_guard.get_tenant_ids(tmp_tenantid_array))) { - LOG_WARN("failed to get tenant ids", K(ret)); - } - - for (int64_t i = 0; OB_SUCC(ret) && i < tmp_tenantid_array.count(); ++i) { - const uint64_t tenant_id = tmp_tenantid_array.at(i); - if (is_user_tenant(tenant_id)) { - } else { - const ObTenantSchema *meta_tenant_info = nullptr; - const ObTenantSchema *user_tenant_info = nullptr; - uint64_t user_tenant_id = gen_user_tenant_id(tenant_id); - if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, meta_tenant_info))) { - LOG_WARN("failed to get meta tenant info", K(ret), K(tenant_id)); - } else if (OB_ISNULL(meta_tenant_info)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("meta tenant info must not be nullptr", K(ret)); - } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, user_tenant_info))) { - LOG_WARN("failed to get meta tenant info", K(ret), K(tenant_id)); - } else if (OB_ISNULL(user_tenant_info)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("meta tenant info must not be nullptr", K(ret)); - } else if (meta_tenant_info->is_normal() && user_tenant_info->is_normal()) { - if (OB_FAIL(tenants.push_back(tenant_id))) { - LOG_WARN("failed to push back tenant id", K(ret), K(tenant_id)); - } - } - } - } - return ret; -} - int ObBackupDataScheduler::cancel_backup_data( const uint64_t tenant_id, const common::ObIArray &backup_tenant_ids) @@ -300,8 +269,6 @@ int ObBackupDataScheduler::cancel_backup_data( } else if (OB_FAIL(check_tenant_status(*schema_service_, need_cancel_backup_tenant, is_valid))) { } else if (!is_valid) { LOG_INFO("tenant status not normal, no need to schedule backup", K(need_cancel_backup_tenant)); - } else if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupJobOperator::cancel_jobs(*sql_proxy_, need_cancel_backup_tenant))) { LOG_WARN("fail to cancel backup jobs", K(ret), K(need_cancel_backup_tenant)); } @@ -552,7 +519,7 @@ int ObBackupDataScheduler::start_sys_backup_data_(const ObBackupJobAttr &job_att if (OB_FAIL(get_next_job_id(trans, new_job_attr.tenant_id_, new_job_attr.job_id_))) { LOG_WARN("[DATA_BACKUP]failed to get next job id", K(ret)); } else if (OB_FALSE_IT(new_job_attr.initiator_job_id_ = new_job_attr.job_id_)) { - } else if (OB_FAIL(lease_service_->check_lease())) { + } else if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupJobOperator::insert_job(trans, new_job_attr))) { LOG_WARN("[DATA_BACKUP]failed to create new backup job", K(ret), K(new_job_attr)); @@ -613,7 +580,7 @@ int ObBackupDataScheduler::start_tenant_backup_data_(const ObBackupJobAttr &job_ } else { if (OB_FAIL(persist_backup_version_(trans, new_job_attr.tenant_id_, cluster_version))) { LOG_WARN("failed to persist backup version", K(ret)); - } else if (OB_FAIL(get_next_job_id(trans, new_job_attr.tenant_id_, new_job_attr.job_id_))) { + } else if (OB_FAIL(get_next_job_id(trans, new_job_attr.tenant_id_, new_job_attr.job_id_))) { LOG_WARN("[DATA_BACKUP]failed to get next job id", K(ret)); } else if (OB_FAIL(get_next_backup_set_id(trans, new_job_attr.tenant_id_, new_job_attr.backup_set_id_))) { LOG_WARN("[DATA_BACKUP]failed to get next backup set id", K(ret)); @@ -624,7 +591,7 @@ int ObBackupDataScheduler::start_tenant_backup_data_(const ObBackupJobAttr &job_ LOG_WARN("[DATA_BACKUP]failed to push back tenant id", K(ret)); } else if (OB_FALSE_IT(new_job_attr.initiator_job_id_ = new_job_attr.tenant_id_ == new_job_attr.initiator_tenant_id_ ? 0/*no parent job*/ : new_job_attr.initiator_job_id_)) { - } else if (OB_FAIL(lease_service_->check_lease())) { + } else if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupJobOperator::insert_job(trans, new_job_attr))) { LOG_WARN("[DATA_BACKUP]failed to create new backup job", K(ret), K(job_attr)); @@ -703,18 +670,21 @@ int ObBackupDataScheduler::get_backup_scn( if (OB_FAIL(trans.end(true))) { LOG_WARN("failed to commit", K(ret)); } else { - // TODO when provide the scn_to_str, remove this . - // The conversion accuracy of SCN to time_stamp is inconsistent under MySQL mode and Oracle mode. - // The conversion accuracy in ORALCE mode is nanosecond, but it is microsecond in mysql - // for backup and restore, we keep the scn round up to microseconds that keep the conversion accuracy is consistent. - // meanwhile, in order to solve that boundary is not included in the restore, scn + 1; - // 1658475549197665190 --> 1658475549197666000 - int64_t ts = 0; - ts = tmp_scn.convert_to_ts(); - if (OB_FAIL(scn.convert_from_ts(ts))) { - LOG_WARN("fail to convert from ts", K(ret), K(ts)); - } else if (tmp_scn != scn && OB_FAIL(scn.convert_from_ts(ts + 1))) { - LOG_WARN("fail to convert from ts", K(ret), K(ts)); + if (!is_start) { + // The conversion accuracy of SCN to time_stamp is inconsistent under MySQL mode and Oracle mode. + // The conversion accuracy in ORALCE mode is nanosecond, but it is microsecond in mysql + // for backup and restore, we keep the end scn round up to microseconds that keep the conversion accuracy is consistent. + // meanwhile, in order to solve that boundary is not included in the restore, scn + 1; + // 1658475549197665190 --> 1658475549197666000 + int64_t ts = 0; + ts = tmp_scn.convert_to_ts(); + if (OB_FAIL(scn.convert_from_ts(ts))) { + LOG_WARN("fail to convert from ts", K(ret), K(ts)); + } else if (tmp_scn != scn && OB_FAIL(scn.convert_from_ts(ts + 1))) { + LOG_WARN("fail to convert from ts", K(ret), K(ts)); + } + } else { + scn = tmp_scn; } } } else { @@ -856,10 +826,7 @@ int ObBackupDataScheduler::get_backup_path(common::ObISQLClient &sql_proxy, cons } int ObBackupDataScheduler::handle_execute_over( - const ObBackupScheduleTask *task, - bool &can_remove, - const ObAddr &black_server, - const int execute_ret) + const ObBackupScheduleTask *task, const share::ObHAResultInfo &result_info, bool &can_remove) { //cases of call handle_execute_over //1. observer return a rpc to tell task scheduler task finish (success or fail) @@ -881,6 +848,7 @@ int ObBackupDataScheduler::handle_execute_over( } else { // first get task from __all_backup_log_stream_task ObBackupLSTaskAttr ls_attr; + ObSqlString extra_condition; ObMySQLTransaction trans; ObLSID ls_id(task->get_ls_id()); if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(task->get_tenant_id())))) { @@ -888,16 +856,13 @@ int ObBackupDataScheduler::handle_execute_over( } else { if (OB_FAIL(ObBackupLSTaskOperator::get_ls_task(trans, true/*for update*/, task->get_task_id(), task->get_tenant_id(), ls_id, ls_attr))) { LOG_WARN("[DATA_BACKUP]failed to get log stream task", K(ret), KPC(task)); - } else if (OB_FAIL(ObBackupDataLSTaskMgr::mark_ls_task_info_final(*lease_service_, trans, ls_attr))) { - LOG_WARN("[DATA_BACKUP]failed to update ls task info final", K(ret), K(ls_attr)); - } else if (OB_FALSE_IT(ls_attr.end_ts_ = ObTimeUtility::current_time())) { - } else if (ObBackupTaskStatus::Status::DOING == ls_attr.status_.status_) { - ObBackupTaskStatus next_status(ObBackupTaskStatus::Status::FINISH); - if (OB_SUCCESS != execute_ret && OB_FAIL(ObBackupDataLSTaskMgr::update_black_server(*lease_service_, trans, ls_attr, black_server))) { - LOG_WARN("[DATA_BACKUP]failed to update black server", K(ret), K(ls_attr), K(black_server)); - } else if (OB_FAIL(ObBackupDataLSTaskMgr::advance_status(*lease_service_, trans, ls_attr, next_status, execute_ret, ls_attr.end_ts_))) { - LOG_WARN("[DATA_BACKUP]failed to advance status", K(ret), K(ls_attr), K(next_status), K(execute_ret)); - } + } else if (!ls_attr.task_trace_id_.equals(task->get_trace_id())) { + can_remove = false; + LOG_INFO("task in backup task scheduler is not equal to ls attr, may change turn or retry", K(can_remove), KPC(task), K(ls_attr)); + } else if (ObBackupTaskStatus::DOING == ls_attr.status_.status_) { + if (OB_FAIL(ObBackupDataLSTaskMgr::handle_execute_over(*backup_service_, trans, ls_attr, result_info))) { + LOG_WARN("failed to handle execute over", K(ret), K(ls_attr), K(result_info)); + } } else { LOG_WARN("concurrent scenario! this task will need reload to redo.", K(ls_attr)); } @@ -908,7 +873,7 @@ int ObBackupDataScheduler::handle_execute_over( } else { can_remove = true; backup_service_->wakeup(); - LOG_INFO("succeed handle execute over ls task.", K(ls_attr)); + LOG_INFO("succeed handle execute over ls task.", K(ls_attr), K(result_info), KPC(task)); } } else { int tmp_ret = OB_SUCCESS; @@ -931,16 +896,19 @@ int ObBackupDataScheduler::handle_failed_job_( if (OB_SYS_TENANT_ID == tenant_id) { ret = OB_INVALID_ARGUMENT; LOG_WARN("sys tenant does not handle failed", K(ret), K(tenant_id)); + } else if (backup_service_->has_set_stop()) { //do nothing } else if (!job_mgr.is_can_retry(result) || job_attr.retry_count_ >= OB_MAX_RETRY_TIMES) { if (OB_FAIL(job_mgr.deal_non_reentrant_job(result))) { LOG_WARN("failed to deal failed job", K(ret), K(job_attr)); } } else { - job_attr.retry_count_++; - if (OB_FAIL(ObBackupJobOperator::update_retry_count(*sql_proxy_, job_attr))) { - LOG_WARN("failed to persist retry times", K(ret), K(job_attr)); - } else { - backup_service_->wakeup(); + if (result != OB_NOT_MASTER) { + job_attr.retry_count_++; + if (OB_FAIL(ObBackupJobOperator::update_retry_count(*sql_proxy_, job_attr))) { + LOG_WARN("failed to persist retry times", K(ret), K(job_attr)); + } else { + sleep(5); // sleep 5s for retry + } } } return ret; @@ -948,58 +916,45 @@ int ObBackupDataScheduler::handle_failed_job_( int ObBackupDataScheduler::process() { - - // TODO: remove get_all_normal_tenants when adjust tenant level thread. - int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; + ObArray backup_jobs; ObIBackupJobMgr *job_mgr = nullptr; - ObArray tenant_ids; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("[DATA_BACKUP]backup up data scheduler not init", K(ret)); - } else if (OB_FAIL(get_all_normal_tenants_(tenant_ids))) { - LOG_WARN("fail to get all normal tenants", K(ret)); - } else { - ARRAY_FOREACH(tenant_ids, i) { - const uint64_t tenant_id = tenant_ids.at(i); - ObArray backup_jobs; - if (OB_FAIL(ObBackupJobOperator::get_jobs(*sql_proxy_, tenant_id, false/*not for update*/, backup_jobs))) { - LOG_WARN("[DATA_BACKUP]failed to get backup jobs", K(ret)); - } else if (backup_jobs.empty()) { + } else if (OB_FAIL(ObBackupJobOperator::get_jobs(*sql_proxy_, tenant_id_, false/*not for update*/, backup_jobs))) { + LOG_WARN("[DATA_BACKUP]failed to get backup jobs", K(ret), K_(tenant_id)); + } else if (backup_jobs.empty()) { + } else if (OB_FAIL(ObBackupJobMgrAlloctor::alloc(tenant_id_, job_mgr))) { + LOG_WARN("fail to alloc job mgr", K(ret), K_(tenant_id)); + } else if (OB_ISNULL(job_mgr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup job mgr can't be nullptr", K(ret), K_(tenant_id)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < backup_jobs.count(); ++i) { + ObBackupJobAttr &job_attr = backup_jobs.at(i); + job_mgr->reset(); + if (!job_attr.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[DATA_BACKUP]backup job is not valid", K(ret), K(job_attr)); + } else if (OB_FAIL(job_mgr->init(tenant_id_, job_attr, *sql_proxy_, *rpc_proxy_, *task_scheduler_, *schema_service_, + *backup_service_))) { + LOG_WARN("[DATA_BACKUP]failed to init tenant backup job mgr", K(ret), K_(tenant_id), K(job_attr)); + } else if (OB_SUCCESS != (tmp_ret = job_mgr->process())) { // tenant level backups are isolated + LOG_WARN("[DATA_BACKUP]failed to schedule tenant backup job", K(tmp_ret), K_(tenant_id), K(job_attr)); + if (!is_sys_tenant(tenant_id_) && OB_SUCCESS != (tmp_ret = handle_failed_job_(tenant_id_, tmp_ret, *job_mgr, job_attr))) { + LOG_WARN("failed to handle user tenant failed job", K(tmp_ret), K(job_attr)); } else { - if (OB_FAIL(ObBackupJobMgrAlloctor::alloc(tenant_id, job_mgr))) { - LOG_WARN("fail to alloc job mgr", K(ret), K(tenant_id)); - } else if (OB_ISNULL(job_mgr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("backup job mgr can't be nullptr", K(ret), K(tenant_id)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < backup_jobs.count(); ++i) { - ObBackupJobAttr &job_attr = backup_jobs.at(i); - job_mgr->reset(); - if (!job_attr.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("[DATA_BACKUP]backup job is not valid", K(ret), K(job_attr)); - } else if (OB_FAIL(job_mgr->init(tenant_id, job_attr, *sql_proxy_, *rpc_proxy_, - *task_scheduler_, *lease_service_, *schema_service_, *backup_service_))) { - LOG_WARN("[DATA_BACKUP]failed to init tenant backup job mgr", K(ret), K(tenant_id), K(job_attr)); - } else if (OB_SUCCESS != (tmp_ret = job_mgr->process())) { // tenant level backups are isolated - LOG_WARN("[DATA_BACKUP]failed to schedule tenant backup job", K(tmp_ret), K(tenant_id), K(job_attr)); - if (!is_sys_tenant(tenant_id) && OB_SUCCESS != (tmp_ret = handle_failed_job_(tenant_id, tmp_ret, *job_mgr, job_attr))) { - LOG_WARN("failed to handle user tenant failed job", K(tmp_ret), K(job_attr)); - } else { - backup_service_->wakeup(); - } - } - } - if (OB_NOT_NULL(job_mgr)) { - job_mgr->~ObIBackupJobMgr(); - ObBackupJobMgrAlloctor::free(job_mgr); - job_mgr = nullptr; - } + backup_service_->wakeup(); } } } + if (OB_NOT_NULL(job_mgr)) { + job_mgr->~ObIBackupJobMgr(); + ObBackupJobMgrAlloctor::free(job_mgr); + job_mgr = nullptr; + } return ret; } @@ -1009,13 +964,12 @@ int ObBackupDataScheduler::process() ObIBackupJobMgr::ObIBackupJobMgr() : is_inited_(false), - tenant_id_(0), + tenant_id_(OB_INVALID_TENANT_ID), job_attr_(nullptr), sql_proxy_(nullptr), rpc_proxy_(nullptr), task_scheduler_(nullptr), schema_service_(nullptr), - lease_service_(nullptr), backup_service_(nullptr) { } @@ -1026,9 +980,8 @@ int ObIBackupJobMgr::init( common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, ObBackupTaskScheduler &task_scheduler, - ObBackupLeaseService &lease_service, share::schema::ObMultiVersionSchemaService &schema_service, - ObBackupService &backup_service) + ObBackupDataService &backup_service) { int ret = OB_SUCCESS; if (IS_INIT) { @@ -1044,7 +997,6 @@ int ObIBackupJobMgr::init( rpc_proxy_ = &rpc_proxy; task_scheduler_ = &task_scheduler; schema_service_ = &schema_service; - lease_service_ = &lease_service; backup_service_ = &backup_service; is_inited_ = true; } @@ -1059,7 +1011,6 @@ void ObIBackupJobMgr::reset() rpc_proxy_ = nullptr; task_scheduler_ = nullptr; schema_service_ = nullptr; - lease_service_ = nullptr; backup_service_ = nullptr; is_inited_ = false; } @@ -1089,6 +1040,18 @@ int ObUserTenantBackupJobMgr::deal_non_reentrant_job(const int err) LOG_WARN("[DATA_BACKUP]not init", K(ret)); } else if (OB_FAIL(task_scheduler_->cancel_tasks(BackupJobType::BACKUP_DATA_JOB, job_attr_->job_id_, job_attr_->tenant_id_))) { LOG_WARN("[DATA_BACKUP]failed to cancel backup tasks", K(ret), KPC(job_attr_)); + } else if (job_attr_->comment_.is_empty()) { + ObHAResultInfo result_info(ObHAResultInfo::ROOT_SERVICE, + GCONF.self_addr_, + share::ObTaskId(*ObCurTraceId::get_trace_id()), + err); + if (OB_FAIL(result_info.get_comment_str(job_attr_->comment_))) { + LOG_WARN("failed to get comment str", K(ret), K(result_info)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObBackupJobOperator::update_comment(*sql_proxy_, *job_attr_))) { + LOG_WARN("failed to update comment", K(ret)); } else if (ObBackupStatus::Status::INIT == job_attr_->status_.status_) { if (OB_FAIL(advance_job_status(*sql_proxy_, next_status, err, job_attr_->end_ts_))) { LOG_WARN("[DATA_BACKUP]failed to move job status to FAILED", K(ret), KPC(job_attr_)); @@ -1097,10 +1060,8 @@ int ObUserTenantBackupJobMgr::deal_non_reentrant_job(const int err) ObMySQLTransaction trans; ObBackupSetTaskMgr set_task_mgr; if (OB_FAIL(set_task_mgr.init(tenant_id_, *job_attr_, *sql_proxy_, - *rpc_proxy_, *task_scheduler_, *lease_service_, *schema_service_, *backup_service_))) { + *rpc_proxy_, *task_scheduler_, *schema_service_, *backup_service_))) { LOG_WARN("[DATA_BACKUP]failed to init set task mgr", K(ret)); - } else if (set_task_mgr.can_write_extern_infos(err) && OB_FAIL(set_task_mgr.write_backup_set_placeholder(is_start))) { - LOG_WARN("fail to write extern infos", K(ret)); } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id_))) { LOG_WARN("fail to start trans", K(ret), K(tenant_id_)); } else { @@ -1214,7 +1175,7 @@ int ObUserTenantBackupJobMgr::move_to_history_() LOG_WARN("[DATA_BACKUP]failed to start trans", K(ret)); } else { if (OB_FAIL(set_task_mgr.init(tenant_id_, *job_attr_, *sql_proxy_, - *rpc_proxy_, *task_scheduler_, *lease_service_, *schema_service_, *backup_service_))) { + *rpc_proxy_, *task_scheduler_, *schema_service_, *backup_service_))) { if (OB_ENTRY_NOT_EXIST == ret) { // when job was canceled in INIT STATUS, there are no set task in task table. ret = OB_SUCCESS; } else { @@ -1327,7 +1288,7 @@ int ObUserTenantBackupJobMgr::cancel_() } else { bool is_set_task_exist = true; if (OB_FAIL(set_task_mgr.init(tenant_id_, *job_attr_, *sql_proxy_, - *rpc_proxy_, *task_scheduler_, *lease_service_, *schema_service_, *backup_service_))) { + *rpc_proxy_, *task_scheduler_, *schema_service_, *backup_service_))) { if (OB_ENTRY_NOT_EXIST == ret) { // when job was canceled in INIT STATUS, there are no set task in task table. is_set_task_exist = false; ret = OB_SUCCESS; @@ -1394,7 +1355,7 @@ int ObUserTenantBackupJobMgr::do_set_task_() ObBackupStatus next_status; ObBackupSetTaskMgr set_task_mgr; if (OB_FAIL(set_task_mgr.init(tenant_id_, *job_attr_, *sql_proxy_, - *rpc_proxy_, *task_scheduler_, *lease_service_, *schema_service_, *backup_service_))) { + *rpc_proxy_, *task_scheduler_, *schema_service_, *backup_service_))) { LOG_WARN("[DATA_BACKUP]failed to init set task mgr", K(ret)); } else if (OB_FAIL(set_task_mgr.process())) { LOG_WARN("[DATA_BACKUP]failed to backup ls task", K(ret), K(set_task_mgr)); @@ -1482,10 +1443,12 @@ int ObUserTenantBackupJobMgr::insert_backup_set_task_(common::ObISQLClient &sql_ backup_set_task.result_ = job_attr_->result_; backup_set_task.start_ts_ = job_attr_->start_ts_; backup_set_task.meta_turn_id_ = 1; - backup_set_task.data_turn_id_ = 1; + backup_set_task.minor_turn_id_ = 1; + backup_set_task.major_turn_id_ = 1; + backup_set_task.data_turn_id_ = 0; backup_set_task.end_scn_ = SCN::min_scn(); backup_set_task.user_ls_start_scn_ = SCN::min_scn(); - if (OB_FAIL(lease_service_->check_lease())) { + if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupTaskOperator::insert_backup_task(sql_proxy, backup_set_task))) { LOG_WARN("[DATA_BACKUP]failed to insert backup task", K(ret), K(backup_set_task)); @@ -1511,8 +1474,8 @@ int ObUserTenantBackupJobMgr::insert_backup_set_file_(common::ObISQLClient &sql_ } else if (OB_FAIL(ObBackupStorageInfoOperator::get_dest_id(sql_proxy, job_attr_->tenant_id_, backup_dest, dest_id))) { LOG_WARN("[DATA_BACKUP]fail to get dest id", K(ret), KPC(job_attr_)); } else if (OB_FAIL(fill_backup_set_desc_(*job_attr_, prev_full_backup_set_id, prev_inc_backup_set_id, dest_id, backup_set_desc))) { - LOG_WARN("[DATA_BACKUP]fail to fill backup set desc", K(ret), KPC(job_attr_), K(prev_full_backup_set_id), K(prev_inc_backup_set_id)); - } else if (OB_FAIL(lease_service_->check_lease())) { + LOG_WARN("[DATA_BACKUP]fail to fill backup set desc", K(ret), K(*job_attr_), K(prev_full_backup_set_id), K(prev_inc_backup_set_id)); + } else if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupSetFileOperator::insert_backup_set_file(sql_proxy, backup_set_desc))) { LOG_WARN("[DATA_BACKUP]fail to insert backup set file", K(ret), K(backup_set_desc), KPC(job_attr_)); @@ -1530,6 +1493,7 @@ int ObUserTenantBackupJobMgr::fill_backup_set_desc_( int ret = OB_SUCCESS; uint64_t data_version = 0; uint64_t cluster_version = 0; + if (!job_attr.is_valid() || prev_inc_backup_set_id < 0 || prev_full_backup_set_id < 0) { ret = OB_INVALID_ARGUMENT; LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(job_attr), K(prev_inc_backup_set_id), K(prev_full_backup_set_id)); @@ -1559,8 +1523,9 @@ int ObUserTenantBackupJobMgr::fill_backup_set_desc_( backup_set_desc.result_ = job_attr.result_; backup_set_desc.encryption_mode_ = job_attr.encryption_mode_; backup_set_desc.start_replay_scn_ = SCN::min_scn(); + backup_set_desc.consistent_scn_ = SCN::min_scn(); backup_set_desc.min_restore_scn_ = SCN::min_scn(); - backup_set_desc.backup_compatible_ = ObBackupSetFileDesc::Compatible::COMPATIBLE_VERSION_2; + backup_set_desc.backup_compatible_ = ObBackupSetFileDesc::Compatible::COMPATIBLE_VERSION_3; backup_set_desc.tenant_compatible_ = data_version; backup_set_desc.cluster_version_ = cluster_version; backup_set_desc.plus_archivelog_ = job_attr.plus_archivelog_; @@ -1588,7 +1553,7 @@ int ObUserTenantBackupJobMgr::advance_job_status( const int64_t end_ts) { int ret = OB_SUCCESS; - if (OB_FAIL(lease_service_->check_lease())) { + if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupJobOperator::advance_job_status(trans, *job_attr_, next_status, result, end_ts))) { LOG_WARN("[DATA_BACKUP]failed to advance job status", K(ret), KPC(job_attr_), K(next_status), K(result), K(end_ts)); @@ -1663,11 +1628,13 @@ int ObSysTenantBackupJobMgr::handle_user_tenant_backupdatabase_() } else if (cnt != 0) { LOG_INFO("user tenant job has been inserted, just pass", K(user_tenant_id)); } else if (OB_FAIL(do_handle_user_tenant_backupdatabase_(user_tenant_id))) { - if (OB_BACKUP_CAN_NOT_START == ret || OB_BACKUP_IN_PROGRESS == ret) { - LOG_WARN("tenant can't start backup now just pass", K(ret)); + if (!ObBackupUtils::is_need_retry_error(ret)) { + LOG_WARN("tenant can't start backup now. just pass", K(ret)); + share::ObTaskId trace_id(*ObCurTraceId::get_trace_id()); + ROOTSERVICE_EVENT_ADD("backup_data", "handle_user_tenant_backup_failed", K(user_tenant_id), K(ret), K(trace_id)); ret = OB_SUCCESS; } else { - LOG_WARN("fail to do insert user tenant job", K(ret), K(user_tenant_id)); + LOG_WARN("failed to handle user tenant backup database, retry later", K(ret), K(user_tenant_id)); } } } @@ -1685,9 +1652,6 @@ int ObSysTenantBackupJobMgr::handle_user_tenant_backupdatabase_() int ObSysTenantBackupJobMgr::do_handle_user_tenant_backupdatabase_(const uint64_t &tenant_id) { - - // TODO: adjust usr srv rpc proxy when has tenant backup thread. - int ret = OB_SUCCESS; common::ObAddr rs_addr; obrpc::ObBackupDatabaseArg backup_database_arg; @@ -1736,10 +1700,6 @@ int ObSysTenantBackupJobMgr::statistic_user_tenant_job_() LOG_WARN("fail to check tenant status", K(ret), K(user_tenant_id)); } else if (!is_valid) { finish_user_backup_job++; - // TODO delete cancel tasks func when use tenant level backup thread. - if (OB_FAIL(task_scheduler_->cancel_tasks(BackupJobType::BACKUP_DATA_JOB, user_tenant_id))) { - LOG_WARN("fail to cancel task of tenant which has been dropped", K(ret), K(user_tenant_id)); - } } else if (OB_FAIL(ObBackupJobOperator::get_job(*sql_proxy_, false/*no update*/, user_tenant_id, job_attr_->job_id_, true/**/, tmp_job_attr))) { if (OB_ENTRY_NOT_EXIST == ret) { @@ -1766,7 +1726,8 @@ int ObSysTenantBackupJobMgr::statistic_user_tenant_job_() if (OB_FAIL(advance_status_(*sql_proxy_, next_status, tmp_job_attr.result_, ObTimeUtility::current_time()))) { LOG_WARN("fail to advance sys job status", K(ret), KPC(job_attr_), K(next_status)); } else { - LOG_INFO("[DATA_BACKUP]user job finished, sys job move to next status", K(next_status), KPC(job_attr_)); + backup_service_->wakeup(); + LOG_INFO("[DATA_BACKUP]user job finished, sys job move to next status", K(next_status), K(*job_attr_)); } } } @@ -1776,7 +1737,7 @@ int ObSysTenantBackupJobMgr::statistic_user_tenant_job_() int ObSysTenantBackupJobMgr::move_to_history_() { int ret = OB_SUCCESS; - if (OB_FAIL(lease_service_->check_lease())) { + if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupJobOperator::move_job_to_his(*sql_proxy_, job_attr_->tenant_id_, job_attr_->job_id_))) { LOG_WARN("[DATA_BACKUP]failed to move job to history table", K(ret), KPC(job_attr_)); @@ -1812,7 +1773,7 @@ int ObSysTenantBackupJobMgr::cancel_user_tenant_job_() } else if (tmp_job_attr.status_.status_ == ObBackupStatus::Status::INIT || tmp_job_attr.status_.status_ == ObBackupStatus::Status::DOING) { ObBackupStatus next_status(ObBackupStatus::Status::CANCELING); - if (OB_FAIL(lease_service_->check_lease())) { + if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupJobOperator::advance_job_status(*sql_proxy_, tmp_job_attr, next_status))) { LOG_WARN("fail to advance user job to CANCELING", K(ret), K(tmp_job_attr), K(next_status)); @@ -1828,7 +1789,8 @@ int ObSysTenantBackupJobMgr::cancel_user_tenant_job_() if (OB_FAIL(advance_status_(*sql_proxy_, next_status, OB_CANCELED, ObTimeUtility::current_time()))) { LOG_WARN("fail to advance sys job status", K(ret), KPC(job_attr_), K(next_status)); } else { - FLOG_INFO("[DATA_BACKUP]succeed schedule sys backup job", KPC(job_attr_)); + backup_service_->wakeup(); + FLOG_INFO("[DATA_BACKUP]succeed schedule sys backup job", K(*job_attr_)); } } } @@ -1842,7 +1804,7 @@ int ObSysTenantBackupJobMgr::advance_status_( const int64_t end_ts) { int ret = OB_SUCCESS; - if (OB_FAIL(lease_service_->check_lease())) { + if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("fail to check leader", K(ret)); } else if (OB_FAIL(ObBackupJobOperator::advance_job_status(sql_proxy, *job_attr_, next_status, result, end_ts))) { LOG_WARN("[DATA_BACKUP]failed to advance job status", K(ret), KPC(job_attr_), K(next_status), K(result), K(end_ts)); diff --git a/src/rootserver/backup/ob_backup_data_scheduler.h b/src/rootserver/backup/ob_backup_data_scheduler.h index cec478c22..ca475e10f 100644 --- a/src/rootserver/backup/ob_backup_data_scheduler.h +++ b/src/rootserver/backup/ob_backup_data_scheduler.h @@ -15,8 +15,7 @@ #include "ob_backup_base_job.h" #include "share/backup/ob_backup_data_table_operator.h" -#include "share/backup/ob_backup_data_store.h" -#include "rootserver/backup/ob_backup_lease_service.h" +#include "storage/backup/ob_backup_data_store.h" #include "storage/backup/ob_backup_data_struct.h" #include "share/backup/ob_backup_struct.h" #include "share/ob_ls_id.h" @@ -45,8 +44,7 @@ public: virtual int process() override; virtual int force_cancel(const uint64_t &tenant_id) override; // if can_remove return true, scheudler can remove task from scheduler - virtual int handle_execute_over(const ObBackupScheduleTask *task, bool &can_remove, - const ObAddr &black_server, const int execute_ret) override; + virtual int handle_execute_over(const ObBackupScheduleTask *task, const share::ObHAResultInfo &result_info, bool &can_remove) override; // reloading task from inner table which status is pending or doing virtual int get_need_reload_task(common::ObIAllocator &allocator, common::ObIArray &tasks) override; public: @@ -57,8 +55,9 @@ public: static int get_next_job_id(common::ObISQLClient &trans, const uint64_t tenant_id, int64_t &job_id); static int get_next_backup_set_id(common::ObISQLClient &trans, const uint64_t tenant_id, int64_t &next_backup_set_id); public: - int init(common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, share::schema::ObMultiVersionSchemaService &schema_service, - ObBackupLeaseService &lease_service, ObBackupTaskScheduler &task_scheduler, ObBackupService &backup_service); + int init(const uint64_t tenant_id, common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, + share::schema::ObMultiVersionSchemaService &schema_service, ObBackupTaskScheduler &task_scheduler, + ObBackupDataService &backup_service); // constructing a ObBackupJobAttr according to ObBackupDatabaseArg, them insert the ObBackupJobAttr into __all_backup_job int start_backup_data(const obrpc::ObBackupDatabaseArg &in_arg); @@ -88,13 +87,11 @@ private: int build_task_(const share::ObBackupJobAttr &job, const share::ObBackupSetTaskAttr &set_task_attr, const share::ObBackupLSTaskAttr &ls_task, ObIAllocator &allocator, ObBackupScheduleTask *&task); - int persist_backup_version_(common::ObISQLClient &sql_proxy, const uint64_t tenant_id, const uint64_t &cluster_version); template int do_build_task_(const share::ObBackupJobAttr &job, const share::ObBackupSetTaskAttr &set_task_attr, const share::ObBackupLSTaskAttr &ls_task, ObIAllocator &allocator, T &tmp_task, ObBackupScheduleTask *&task); - int get_all_normal_tenants_(ObIArray &tenants); int handle_failed_job_( const uint64_t tenant_id, const int64_t result, @@ -102,12 +99,12 @@ private: share::ObBackupJobAttr &job_attr); private: bool is_inited_; + uint64_t tenant_id_; common::ObMySQLProxy *sql_proxy_; obrpc::ObSrvRpcProxy *rpc_proxy_; share::schema::ObMultiVersionSchemaService *schema_service_; ObBackupTaskScheduler *task_scheduler_; - ObBackupLeaseService *lease_service_; - ObBackupService *backup_service_; + ObBackupDataService *backup_service_; DISALLOW_COPY_AND_ASSIGN(ObBackupDataScheduler); }; @@ -120,8 +117,8 @@ public: virtual int deal_non_reentrant_job(const int err) = 0; public: int init(const uint64_t tenant_id, share::ObBackupJobAttr &job_attr, common::ObMySQLProxy &sql_proxy, - obrpc::ObSrvRpcProxy &rpc_proxy, ObBackupTaskScheduler &task_scheduler, ObBackupLeaseService &lease_service, - share::schema::ObMultiVersionSchemaService &schema_service_, ObBackupService &backup_service); + obrpc::ObSrvRpcProxy &rpc_proxy, ObBackupTaskScheduler &task_scheduler, + share::schema::ObMultiVersionSchemaService &schema_service_, ObBackupDataService &backup_service); void reset(); uint64_t get_tenant_id() const { return tenant_id_; } bool is_can_retry(const int err) const; @@ -133,8 +130,7 @@ protected: obrpc::ObSrvRpcProxy *rpc_proxy_; ObBackupTaskScheduler *task_scheduler_; share::schema::ObMultiVersionSchemaService *schema_service_; - ObBackupLeaseService* lease_service_; - ObBackupService *backup_service_; + ObBackupDataService *backup_service_; DISALLOW_COPY_AND_ASSIGN(ObIBackupJobMgr); }; diff --git a/src/rootserver/backup/ob_backup_data_set_task_mgr.cpp b/src/rootserver/backup/ob_backup_data_set_task_mgr.cpp index bc1e862f5..182d75617 100644 --- a/src/rootserver/backup/ob_backup_data_set_task_mgr.cpp +++ b/src/rootserver/backup/ob_backup_data_set_task_mgr.cpp @@ -15,6 +15,7 @@ #include "ob_backup_data_scheduler.h" #include "ob_backup_data_ls_task_mgr.h" #include "ob_backup_data_set_task_mgr.h" +#include "ob_backup_task_scheduler.h" #include "storage/tx/ob_ts_mgr.h" #include "rootserver/ob_root_utils.h" #include "observer/omt/ob_tenant_config_mgr.h" @@ -27,10 +28,14 @@ #include "share/backup/ob_backup_struct.h" #include "storage/backup/ob_backup_extern_info_mgr.h" #include "share/ls/ob_ls_table_operator.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" #include "rootserver/ob_rs_event_history_table_operator.h" #include "share/backup/ob_backup_connectivity.h" #include "storage/backup/ob_backup_operator.h" +#include "rootserver/ob_rs_async_rpc_proxy.h" +#include "share/ob_tenant_info_proxy.h" +#include "observer/ob_inner_sql_connection.h" +#include "share/backup/ob_backup_server_mgr.h" using namespace oceanbase; using namespace omt; @@ -42,12 +47,10 @@ using namespace backup; ObBackupSetTaskMgr::ObBackupSetTaskMgr() : is_inited_(false), meta_tenant_id_(0), - next_status_(), set_task_attr_(), job_attr_(nullptr), sql_proxy_(nullptr), rpc_proxy_(nullptr), - lease_service_(nullptr), task_scheduler_(nullptr), schema_service_(nullptr), backup_service_(nullptr), @@ -62,9 +65,8 @@ int ObBackupSetTaskMgr::init( common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, ObBackupTaskScheduler &task_scheduler, - ObBackupLeaseService &lease_service, ObMultiVersionSchemaService &schema_service, - ObBackupService &backup_service) + ObBackupDataService &backup_service) { int ret = OB_SUCCESS; if (IS_INIT) { @@ -73,7 +75,7 @@ int ObBackupSetTaskMgr::init( } else if (!job_attr.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(job_attr)); - } else if (OB_FAIL(ObBackupTaskOperator::get_backup_task(sql_proxy, job_attr.job_id_, job_attr.tenant_id_, + } else if (OB_FAIL(ObBackupTaskOperator::get_backup_task(sql_proxy, job_attr.job_id_, job_attr.tenant_id_, false/*for update*/, set_task_attr_))) { LOG_WARN("[DATA_BACKUP]failed to get backup task", K(ret), "job_id", job_attr.job_id_, "tenant_id", job_attr.tenant_id_); @@ -95,11 +97,9 @@ int ObBackupSetTaskMgr::init( job_attr_ = &job_attr; sql_proxy_ = &sql_proxy; rpc_proxy_ = &rpc_proxy; - lease_service_ = &lease_service; task_scheduler_ = &task_scheduler; schema_service_ = &schema_service; backup_service_ = &backup_service; - next_status_ = set_task_attr_.status_; is_inited_ = true; } return ret; @@ -113,8 +113,8 @@ int ObBackupSetTaskMgr::advance_status_( const int64_t end_ts) { int ret = OB_SUCCESS; - if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret)); + if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("[DATA_BACKUP]failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupTaskOperator::advance_task_status(trans, set_task_attr_, next_status, result, scn, end_ts))) { LOG_WARN("[DATA_BACKUP]failed to advance set status", K(ret), K(set_task_attr_), K(next_status)); } @@ -150,7 +150,6 @@ int ObBackupSetTaskMgr::process() } break; } - case ObBackupStatus::Status::BACKUP_DATA_SYS: case ObBackupStatus::Status::BACKUP_DATA_MINOR: case ObBackupStatus::Status::BACKUP_DATA_MAJOR: { if (OB_FAIL(backup_data_())) { @@ -187,8 +186,6 @@ int ObBackupSetTaskMgr::process() int ObBackupSetTaskMgr::persist_sys_ls_task_() { int ret = OB_SUCCESS; - next_status_.status_ = ObBackupStatus::Status::BACKUP_SYS_META; - #ifdef ERRSIM if (OB_SUCC(ret)) { ret = OB_E(EventTable::EN_BACKUP_PERSIST_LS_FAILED) OB_SUCCESS; @@ -196,23 +193,25 @@ int ObBackupSetTaskMgr::persist_sys_ls_task_() #endif if (OB_FAIL(ret)) { - } else if (OB_FAIL(write_backup_set_placeholder(true/*start*/))) { + } else if (OB_FAIL(write_backup_set_placeholder_(true/*start*/))) { LOG_WARN("fail to write backup set start placeholder", K(ret), KPC(job_attr_)); } else if (OB_FAIL(trans_.start(sql_proxy_, meta_tenant_id_))) { LOG_WARN("fail to start trans", K(ret), K(meta_tenant_id_)); } else { + ObBackupStatus next_status = ObBackupStatus::BACKUP_SYS_META; if (OB_FAIL(do_persist_sys_ls_task_())) { LOG_WARN("fail to do persist ls tasks", K(ret)); - } else if (OB_FAIL(advance_status_(trans_, next_status_))) { - LOG_WARN("fail to advance status to DOING", K(ret), K(set_task_attr_)); + } else if (OB_FAIL(advance_status_(trans_, next_status))) { + LOG_WARN("fail to advance status to backup sys meta", K(ret), K(next_status)); } if (OB_SUCC(ret)) { if (OB_FAIL(trans_.end(true))) { LOG_WARN("failed to commit trans", KR(ret)); } else { + set_task_attr_.status_ = next_status; ROOTSERVICE_EVENT_ADD("backup_data", "persist sys ls task succeed", "tenant_id", job_attr_->tenant_id_, "job_id", job_attr_->job_id_, "task_id", set_task_attr_.task_id_); - LOG_INFO("[BACKUP_DATA]succeed persit sys ls task", K(ret), K(next_status_), K(set_task_attr_)); + LOG_INFO("[BACKUP_DATA]succeed persit sys ls task", K(ret), K(set_task_attr_)); backup_service_->wakeup(); } } else { @@ -240,15 +239,17 @@ int ObBackupSetTaskMgr::do_persist_sys_ls_task_() return ret; } -int ObBackupSetTaskMgr::persist_ls_attr_info_(ObIArray &ls_ids) +int ObBackupSetTaskMgr::persist_ls_attr_info_(const share::ObBackupLSTaskAttr &sys_ls_task, ObIArray &ls_ids) { int ret = OB_SUCCESS; - ObBackupDataLSAttrDesc ls_attr_desc; + storage::ObBackupDataLSAttrDesc ls_attr_desc; ObLSAttrOperator ls_attr_operator(set_task_attr_.tenant_id_, sql_proxy_); bool ls_attr_info_exist = false; if (OB_FAIL(store_.read_ls_attr_info(set_task_attr_.meta_turn_id_, ls_attr_desc))) { if (OB_BACKUP_FILE_NOT_EXIST == ret) { - if (OB_FAIL(ls_attr_operator.load_all_ls_and_snapshot(ls_attr_desc.backup_scn_, ls_attr_desc.ls_attr_array_))) { + if (OB_FAIL(sync_wait_backup_user_ls_scn_(sys_ls_task, ls_attr_desc.backup_scn_))) { + LOG_WARN("failed to calc backup user ls scn", K(ret)); + } else if (OB_FAIL(ls_attr_operator.load_all_ls_and_snapshot(ls_attr_desc.backup_scn_, ls_attr_desc.ls_attr_array_))) { LOG_WARN("fail to get all ls by order", K(ret)); } } @@ -286,6 +287,45 @@ int ObBackupSetTaskMgr::persist_ls_attr_info_(ObIArray &ls_ids) return ret; } +int ObBackupSetTaskMgr::sync_wait_backup_user_ls_scn_(const share::ObBackupLSTaskAttr &sys_ls_task, share::SCN &scn) +{ + // user ls scn must newer than backup sys ls clog checkpoint scn. + int ret = OB_SUCCESS; + share::ObBackupDest backup_dest; + share::ObBackupSetDesc desc; + desc.backup_set_id_ = job_attr_->backup_set_id_; + desc.backup_type_ = job_attr_->backup_type_; + backup::ObExternLSMetaMgr ls_meta_mgr; + ObBackupLSMetaInfo ls_meta; + int64_t sys_ls_turn_id = 1; + if (OB_FAIL(ObBackupStorageInfoOperator::get_backup_dest(*sql_proxy_, job_attr_->tenant_id_, + job_attr_->backup_path_, backup_dest))) { + LOG_WARN("fail to get backup dest", K(ret), KPC(job_attr_)); + } else if (OB_FAIL(ls_meta_mgr.init(backup_dest, desc, sys_ls_task.ls_id_, sys_ls_task.turn_id_, sys_ls_task.retry_id_))) { + LOG_WARN("failed to init ls meta mgr", K(ret), K(backup_dest), K(desc), K(sys_ls_task)); + } else if (OB_FAIL(ls_meta_mgr.read_ls_meta_info(ls_meta))) { + LOG_WARN("failed to read ls meta info", K(ret)); + } else { + share::SCN tmp_scn(SCN::min_scn()); + int64_t abs_timeout = ObTimeUtility::current_time() + 10 * 60 * 1000 * 1000; + while (OB_SUCC(ret)) { + if (OB_FAIL(ObBackupDataScheduler::get_backup_scn(*sql_proxy_, set_task_attr_.tenant_id_, true, tmp_scn))) { + LOG_WARN("failed to get backup scn", K(ret)); + } else if (tmp_scn > ls_meta.ls_meta_package_.ls_meta_.get_clog_checkpoint_scn()) { + scn = tmp_scn; + LOG_INFO("succeed get backup user ls scn", K(scn), K(ls_meta)); + break; + } else if (ObTimeUtility::current_time() > abs_timeout) { + ret = OB_TIMEOUT; + break; + } else if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); + } + } + } + return ret; +} + int ObBackupSetTaskMgr::generate_ls_tasks_( const ObIArray &ls_ids, const ObBackupDataTaskType &type) @@ -311,13 +351,16 @@ int ObBackupSetTaskMgr::generate_ls_tasks_( new_ls_attr.start_ts_ = ObTimeUtility::current_time(); new_ls_attr.end_ts_ = 0; new_ls_attr.backup_date_ = backup_date; - new_ls_attr.start_turn_id_ = type.is_backup_meta() ? set_task_attr_.meta_turn_id_ : set_task_attr_.data_turn_id_; - new_ls_attr.turn_id_ = type.is_backup_meta() ? set_task_attr_.meta_turn_id_ : set_task_attr_.data_turn_id_; + new_ls_attr.start_turn_id_ = 1; new_ls_attr.retry_id_ = 0; new_ls_attr.result_ = OB_SUCCESS; + new_ls_attr.max_tablet_checkpoint_scn_.set_min(); + share::ObBackupDataType backup_data_type; if (OB_FAIL(ret)) { - } else if (OB_FAIL(lease_service_->check_lease())) { + } else if (OB_FAIL(calc_task_turn_(new_ls_attr.task_type_, new_ls_attr.turn_id_))) { + LOG_WARN("failed to calc ls task turn id", K(ret)); + } else if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret), K(set_task_attr_)); } else if (OB_FAIL(ObBackupLSTaskOperator::insert_ls_task(trans_, new_ls_attr))) { if (OB_ERR_PRIMARY_KEY_DUPLICATE == ret) { @@ -325,15 +368,67 @@ int ObBackupSetTaskMgr::generate_ls_tasks_( } else { LOG_WARN("[DATA_BACKUP]failed to insert backup log stream task", K(ret), K(new_ls_attr)); } + } else if (!type.is_backup_data()) { + } else if (OB_FAIL(type.get_backup_data_type(backup_data_type))) { + LOG_WARN("failed to get backup data type", K(ret), K(type)); + } else if (OB_FAIL(ObLSBackupOperator::insert_ls_backup_task_info(new_ls_attr.tenant_id_, + new_ls_attr.task_id_, new_ls_attr.turn_id_, new_ls_attr.retry_id_, new_ls_attr.ls_id_, + new_ls_attr.backup_set_id_, backup_data_type, trans_))) { + LOG_WARN("failed to insert ls backup task info", K(ret), K(new_ls_attr), K(backup_data_type)); } } } return ret; } +int ObBackupSetTaskMgr::calc_task_turn_(const ObBackupDataTaskType &type, int64_t &turn_id) +{ + int ret = OB_SUCCESS; + turn_id = 0; + switch(set_task_attr_.status_) { + case ObBackupStatus::INIT: + case ObBackupStatus::BACKUP_SYS_META: { + if (type.is_backup_meta()) { + turn_id = 1; + } + break; + } + case ObBackupStatus::BACKUP_USER_META: { + if (type.is_backup_meta()) { + turn_id = set_task_attr_.meta_turn_id_; + } else if (type.is_backup_minor()) { + turn_id = set_task_attr_.minor_turn_id_; + } + break; + } + case ObBackupStatus::BACKUP_DATA_MINOR: { + if (type.is_backup_minor() || type.is_backup_index()) { + turn_id = set_task_attr_.minor_turn_id_; + } + break; + } + case ObBackupStatus::BACKUP_DATA_MAJOR: { + if (type.is_backup_major() || type.is_backup_index()) { + turn_id = set_task_attr_.major_turn_id_; + } + break; + } + default: { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("generate ls task in unmatched status", K(set_task_attr_)); + break; + } + } + + if (OB_SUCC(ret) && 0 == turn_id) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("calc task turn meets unexpected set status and ls task type", K(ret), K(set_task_attr_), K(type)); + } + return ret; +} + int ObBackupSetTaskMgr::backup_sys_meta_() { - // backup sys ls meta and persist ls attr info int ret = OB_SUCCESS; ObArray ls_task; int64_t finish_cnt = 0; @@ -341,31 +436,30 @@ int ObBackupSetTaskMgr::backup_sys_meta_() LOG_WARN("fail to get log stream tasks", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); } else if (ls_task.empty()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("no lostream task", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); + LOG_WARN("no logstream task", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); } else if (OB_FAIL(do_backup_meta_(ls_task, finish_cnt))) { - LOG_WARN("fail to do backuo meta", K(ret), K(ls_task)); + LOG_WARN("fail to do backup meta", K(ret), K(ls_task)); } else if (ls_task.count() == finish_cnt) { - next_status_.status_ = ObBackupStatus::Status::BACKUP_USER_META; ObArray ls_ids; - if (OB_FAIL(disable_transfer_())) { - LOG_WARN("fail to disable transfer", K(ret)); - } else if (OB_FAIL(persist_ls_attr_info_(ls_ids))) { - LOG_WARN("fail to do persist ls task", K(ret)); + if (OB_FAIL(persist_ls_attr_info_(ls_task.at(0), ls_ids))) { + LOG_WARN("fail to do persist ls task", K(ret)); } else if (OB_FAIL(trans_.start(sql_proxy_, meta_tenant_id_))) { LOG_WARN("fail to start trans", K(ret), K(meta_tenant_id_)); } else { + ObBackupStatus next_status = ObBackupStatus::BACKUP_USER_META; share::ObBackupDataTaskType type(share::ObBackupDataTaskType::Type::BACKUP_META); if (OB_FAIL(generate_ls_tasks_(ls_ids, type))) { - LOG_WARN("failed to generate log stream tasks", K(ret), KPC(job_attr_), K(ls_ids)); - } else if (OB_FAIL(advance_status_(trans_, next_status_))) { - LOG_WARN("fail to advance status", K(ret), K(next_status_)); + LOG_WARN("failed to generate ls tasks", K(ret), K(ls_ids), K(type)); + } else if (OB_FAIL(advance_status_(trans_, next_status))) { + LOG_WARN("fail to advance status to backup advance checkpoint", K(ret), K(next_status)); } if (OB_SUCC(ret)) { if (OB_FAIL(trans_.end(true))) { LOG_WARN("fail to commit trans", KR(ret)); } else { - ROOTSERVICE_EVENT_ADD("backup_data", "backup sys meta succeed", "tenant_id", + set_task_attr_.status_ = next_status; + ROOTSERVICE_EVENT_ADD("backup_data", "backup sys ls meta succeed", "tenant_id", job_attr_->tenant_id_, "job_id", job_attr_->job_id_, "task_id", set_task_attr_.task_id_); LOG_INFO("succeed to backup sys ls meta", K(ret), KPC(job_attr_)); backup_service_->wakeup(); @@ -391,26 +485,43 @@ int ObBackupSetTaskMgr::backup_user_meta_() LOG_WARN("[DATA_BACKUP]failed to get log stream tasks", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); } else if (ls_task.empty()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("[DATA_BACKUP]no lostream task", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); + LOG_WARN("[DATA_BACKUP]no logstream task", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); } else if (OB_FAIL(do_backup_meta_(ls_task, finish_cnt))) { LOG_WARN("[DATA_BACKUP]failed to do backup meta", K(ret), K(ls_task)); } else if (OB_FAIL(do_backup_root_key_())) { LOG_WARN("[DATA_BACKUP]failed to do backup root key", K(ret)); } else if (ls_task.count() == finish_cnt) { ROOTSERVICE_EVENT_ADD("backup_data", "before_backup_data"); - DEBUG_SYNC(BEFORE_BACKUP_DATA); - next_status_.status_ = ObBackupStatus::Status::BACKUP_DATA_SYS; - if (OB_FAIL(merge_tablet_to_ls_info_(ls_task))) { - LOG_WARN("[DATA_BACKUP]failed to merge tabelt to ls info", K(ret), K(ls_task)); + share::SCN consistent_scn; + bool need_change_meta_turn = false; + + // let consistent_scn be the biggest max_tablet_checkpoint_scn_ of all the ls. + consistent_scn.set_min(); + ARRAY_FOREACH(ls_task, i) { + const ObBackupLSTaskAttr &task = ls_task.at(i); + consistent_scn = MAX(consistent_scn, task.max_tablet_checkpoint_scn_); + } + + if (OB_FAIL(check_need_change_meta_turn_(ls_task, need_change_meta_turn))) { + LOG_WARN("failed to check need change meta turn", K(ret), K(ls_task)); + } else if (need_change_meta_turn) { + const ObBackupLSTaskAttr &sys_ls_task = ls_task.at(0); + if (OB_FAIL(change_meta_turn_(sys_ls_task))) { + LOG_WARN("failed to change meta turn", K(ret)); + } } else if (OB_FAIL(merge_ls_meta_infos_(ls_task))) { LOG_WARN("fail to merge ls meta infos", K(ret), K(ls_task)); + } else if (OB_FAIL(merge_tablet_to_ls_info_(consistent_scn, ls_task))) { + LOG_WARN("[DATA_BACKUP]failed to merge tablet to ls info", K(ret), K(ls_task)); + } else if (OB_FALSE_IT(DEBUG_SYNC(BEFORE_BACKUP_DATA))) { } else if (OB_FAIL(trans_.start(sql_proxy_, meta_tenant_id_))) { LOG_WARN("fail to start trans", K(ret), K(meta_tenant_id_)); } else { - if (OB_FAIL(update_task_type_(ls_task))) { + ObBackupStatus next_status = ObBackupStatus::BACKUP_DATA_MINOR; + if (OB_FAIL(convert_task_type_(ls_task))) { LOG_WARN("[DATA_BACKUP]fail to update task type to backup data", K(ret)); - } else if (OB_FAIL(advance_status_(trans_, next_status_, OB_SUCCESS))) { - LOG_WARN("[DATA_BACKUP]failed to advance status", K(ret), K(next_status_)); + } else if (OB_FAIL(advance_status_(trans_, next_status))) { + LOG_WARN("[DATA_BACKUP]failed to advance status to BACKUP_DATA_MINOR", K(ret), K(next_status)); } if (OB_SUCC(ret)) { @@ -433,62 +544,90 @@ int ObBackupSetTaskMgr::backup_user_meta_() return ret; } -int ObBackupSetTaskMgr::change_meta_turn_() +int ObBackupSetTaskMgr::check_need_change_meta_turn_(ObIArray &ls_tasks, bool &need_change_turn) +{ + // if deleting ls when backup user meta, the deleted ls may not has ls meta backup. + // if ls included in ls_attr has no ls meta, restore scheduler will create ls failed. + // so when deleting ls happended, we need to change meta turn and backup ls_attr and ls_meta in new turn + int ret = OB_SUCCESS; + need_change_turn = false; + ARRAY_FOREACH_X(ls_tasks, i, cnt, OB_SUCC(ret) && !need_change_turn) { + const ObBackupLSTaskAttr &ls_task = ls_tasks.at(i); + if (!ls_task.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ls task", K(ret), K(ls_task)); + } else { + need_change_turn = OB_LS_NOT_EXIST == ls_task.result_; + } + } + return ret; +} + +int ObBackupSetTaskMgr::change_meta_turn_(const share::ObBackupLSTaskAttr &sys_ls_task) { int ret = OB_SUCCESS; - int64_t next_meta_turn_id = ++set_task_attr_.meta_turn_id_; + const int64_t next_meta_turn_id = ++set_task_attr_.meta_turn_id_; ObArray ls_ids; - if (next_meta_turn_id > OB_MAX_RETRY_TIMES) { - ret = OB_TIMEOUT; - job_attr_->can_retry_ = false; - LOG_WARN("backup meta timeout, backup can't continue", K(ret), KPC(job_attr_)); - } else if (OB_FAIL(task_scheduler_->cancel_tasks(BackupJobType::BACKUP_DATA_JOB, job_attr_->job_id_, - job_attr_->tenant_id_))) { - LOG_WARN("fail to cancel task from backup task scheduelr", K(ret)); - } else if (OB_FAIL(disable_transfer_())) { - LOG_WARN("fail to disable transfer", K(ret)); - } else if (OB_FAIL(persist_ls_attr_info_(ls_ids))) { - LOG_WARN("fail to do persist ls task", K(ret)); + if (OB_FAIL(persist_ls_attr_info_(sys_ls_task, ls_ids))) { + LOG_WARN("failed to do persist ls task", K(ret)); } else if (OB_FAIL(trans_.start(sql_proxy_, meta_tenant_id_))) { - LOG_WARN("fail to start trans", K(ret), K(meta_tenant_id_)); + LOG_WARN("failed to start trans", K(ret), K(meta_tenant_id_)); } else { - share::ObBackupDataTaskType type(share::ObBackupDataTaskType::Type::BACKUP_META); + share::ObBackupDataTaskType type(share::ObBackupDataTaskType::BACKUP_META); if (OB_FAIL(ObBackupLSTaskOperator::delete_ls_task_without_sys(trans_, set_task_attr_.tenant_id_, set_task_attr_.task_id_))) { LOG_WARN("fail to delete ls task", K(ret), "tenant_id", set_task_attr_.tenant_id_, "job_id", set_task_attr_.job_id_); } else if (OB_FAIL(generate_ls_tasks_(ls_ids, type))) { LOG_WARN("failed to generate log stream tasks", K(ret), KPC(job_attr_), K(ls_ids)); - } else if (OB_FAIL(ObBackupTaskOperator::update_meta_turn_id(trans_, set_task_attr_.task_id_, + } else if (OB_FAIL(ObBackupTaskOperator::update_turn_id(trans_, set_task_attr_.status_, set_task_attr_.task_id_, set_task_attr_.tenant_id_, next_meta_turn_id))) { - LOG_WARN("fail to update meta turn id", K(ret), K(set_task_attr_)); + LOG_WARN("failed to update meta turn id", K(ret), K(set_task_attr_)); } - if (OB_SUCC(ret)) { - if (OB_FAIL(trans_.end(true))) { - LOG_WARN("fail to commit trans", KR(ret)); - } else { - LOG_INFO("backup user meta change turn.", K(ret), KPC(job_attr_)); - backup_service_->wakeup(); - } - } else { + if (trans_.is_started()) { int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans_.end(false))) { - LOG_WARN("fail to rollback", KR(ret), K(tmp_ret)); + if (OB_TMP_FAIL(trans_.end(OB_SUCC(ret)))) { + ret = OB_SUCC(ret) ? tmp_ret : ret; + LOG_WARN("failed to end trans", K(ret), K(tmp_ret)); + } + if (OB_SUCC(ret)) { + LOG_INFO("change meta turn", K(ret), K(next_meta_turn_id), KPC(job_attr_)); + backup_service_->wakeup(); } } } return ret; } -int ObBackupSetTaskMgr::merge_ls_meta_infos_(const ObIArray &ls_tasks) +int ObBackupSetTaskMgr::get_backup_user_meta_task_(ObIArray &ls_task) +{ + int ret = OB_SUCCESS; + ObArray tmp_ls_task; + if (OB_FAIL(ObBackupLSTaskOperator::get_ls_tasks(*sql_proxy_, job_attr_->job_id_, job_attr_->tenant_id_, false/*update*/, tmp_ls_task))) { + LOG_WARN("[DATA_BACKUP]failed to get log stream tasks", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); + } else { + ARRAY_FOREACH(tmp_ls_task, i) { + const ObBackupLSTaskAttr &task = tmp_ls_task.at(i); + if (task.task_type_.is_backup_meta()) { + if (OB_FAIL(ls_task.push_back(task))) { + LOG_WARN("failed to push back", K(ret), K(task)); + } + } + } + } + return ret; +} + +int ObBackupSetTaskMgr::merge_ls_meta_infos_( + const ObIArray &ls_tasks) { int ret = OB_SUCCESS; share::ObBackupDest backup_dest; share::ObBackupSetDesc desc; desc.backup_set_id_ = job_attr_->backup_set_id_; desc.backup_type_ = job_attr_->backup_type_; - ObBackupLSMetaInfosDesc ls_meta_infos; + storage::ObBackupLSMetaInfosDesc ls_meta_infos; if (OB_FAIL(ObBackupStorageInfoOperator::get_backup_dest(*sql_proxy_, job_attr_->tenant_id_, job_attr_->backup_path_, backup_dest))) { LOG_WARN("fail to get backup dest", K(ret), KPC(job_attr_)); @@ -504,7 +643,7 @@ int ObBackupSetTaskMgr::merge_ls_meta_infos_(const ObIArray &ls_tasks) +int ObBackupSetTaskMgr::merge_tablet_to_ls_info_(const share::SCN &consistent_scn, const ObIArray &ls_tasks) { - // merge ls level tablet list to tenant level tablet to ls info. int ret = OB_SUCCESS; - ObHashMap> tablet_to_ls; - ObHashMap ls_map; - share::ObBackupDataTabletToLSDesc tablet_to_ls_desc; + ObHashMap> latest_ls_tablet_map; + ObHashMap backup_ls_map; // the ls task persisted in __all_backup_ls_task + ObArray ls_ids; const int64_t OB_BACKUP_MAX_LS_BUCKET = 1024; SCN max_backup_scn; - if (ls_tasks.empty()) { + if (ls_tasks.empty() || !consistent_scn.is_valid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(ls_tasks)); - } else if (OB_FAIL(tablet_to_ls.create(OB_BACKUP_MAX_LS_BUCKET, "tabletToLS"))) { + LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(ls_tasks), K(consistent_scn)); + } else if (OB_FAIL(latest_ls_tablet_map.create(OB_BACKUP_MAX_LS_BUCKET, "tabletToLS"))) { LOG_WARN("[DATA_BACKUP]fail to create tablet to ls map", K(ret)); - } else if (OB_FAIL(ls_map.create(OB_BACKUP_MAX_LS_BUCKET, "lSTaskToLS"))) { + } else if (OB_FAIL(backup_ls_map.create(OB_BACKUP_MAX_LS_BUCKET, "lSTaskToLS"))) { LOG_WARN("[DATA_BACKUP]fail to create ls set", K(ret)); - } else if (OB_FAIL(construct_ls_task_map_(ls_tasks, ls_map))) { - LOG_WARN("[DATA_BACKUP]fail to construct ls set", K(ret), K(ls_tasks)); - } else if (OB_FAIL(ObBackupTabletToLSOperator::get_ls_and_tablet( - *sql_proxy_, set_task_attr_.tenant_id_, tablet_to_ls))) { - LOG_WARN("[DATA_BACKUP]fail to get ls and tablet", K(ret), "tenant_id", set_task_attr_.tenant_id_); + } else { + ObArray empty_tablet_ids; + for (int64_t i = 0; OB_SUCC(ret) && i < ls_tasks.count(); ++i) { + const ObBackupLSTaskAttr &ls_task_attr = ls_tasks.at(i); + if (OB_FAIL(backup_ls_map.set_refactored(ls_task_attr.ls_id_, &ls_task_attr))) { + LOG_WARN("[DATA_BACKUP]fail to insert ls id into set", K(ret)); + } else if (OB_FAIL(latest_ls_tablet_map.set_refactored(ls_task_attr.ls_id_, empty_tablet_ids))) { + LOG_WARN("failed to set refactored", K(ret), K(ls_task_attr.ls_id_)); + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(get_tablet_list_by_snapshot(consistent_scn, latest_ls_tablet_map))) { + LOG_WARN("failed to get tablet list by snapshot", K(ret)); } else { // In order to ensure observer backup all the tablet, we need to check if latest tablet list is match the - // extern tablet lists. - // if not match, return an err and backup failed. - ObHashMap::iterator iter = ls_map.begin(); - while (OB_SUCC(ret) && iter != ls_map.end()) { + // extern tablet lists. if not match, return an err and backup failed. + ObHashMap::iterator iter = backup_ls_map.begin(); + while (OB_SUCC(ret) && iter != backup_ls_map.end()) { const ObLSID &ls_id = iter->first; - const int64_t retry_id = iter->second->retry_id_; - share::ObBackupDataTabletToLSInfo tablet_to_ls_info; + ObArray user_tablet_ids; SCN backup_scn = SCN::min_scn(); ObArray latest_tablet_id; - if (OB_FAIL(get_extern_tablet_info_(ls_id, retry_id, tablet_to_ls_info, backup_scn))) { - LOG_WARN("fail to get extern tablet info", K(ret), K(ls_id), K(retry_id)); - } else if (OB_FAIL(tablet_to_ls.get_refactored(ls_id, latest_tablet_id))) { + if (OB_FAIL(get_extern_tablet_info_(ls_id, user_tablet_ids, backup_scn))) { + LOG_WARN("fail to get extern tablet info", K(ret), K(ls_id)); + } else if (OB_FAIL(latest_ls_tablet_map.get_refactored(ls_id, latest_tablet_id))) { if (OB_HASH_NOT_EXIST == ret) { // ls may be deleted, or has no tablet. ret = OB_SUCCESS; @@ -561,222 +706,206 @@ int ObBackupSetTaskMgr::merge_tablet_to_ls_info_(const ObIArray>::iterator iter = latest_ls_tablet_map.begin(); + OB_SUCC(ret) && iter != latest_ls_tablet_map.end(); ++iter) { + if (OB_FAIL(ls_ids.push_back(iter->first))) { + LOG_WARN("failed to push backup"); + } + } + } + share::ObBackupDataTaskType type(share::ObBackupDataTaskType::Type::BACKUP_DATA_MINOR); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(trans_.start(sql_proxy_, meta_tenant_id_))) { + LOG_WARN("fail to start trans", K(ret), K(meta_tenant_id_)); + } else if (OB_FAIL(generate_ls_tasks_(ls_ids, type))) { + LOG_WARN("failed to generate ls tasks", K(ret), K(ls_ids), K(type)); + } else { + ROOTSERVICE_EVENT_ADD("backup_data", "after_backup_consistent_scn"); + } + if (trans_.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans_.end(OB_SUCC(ret)))) { + ret = OB_SUCC(ret) ? tmp_ret : ret; + LOG_WARN("failed to end trans", K(ret), K(tmp_ret)); + } + } + return ret; +} + +int ObBackupSetTaskMgr::get_tablet_list_by_snapshot( + const share::SCN &consistent_scn, common::hash::ObHashMap> &latest_ls_tablet_map) +{ + int ret = OB_SUCCESS; + ObBackupDataTabletToLSDesc tablet_to_ls_info; + int64_t first_turn_id = 1; + share::ObBackupDataType type; + type.set_minor_data_backup(); + DEBUG_SYNC(BEFORE_BACKUP_CONSISTENT_SCN); + if (OB_FAIL(store_.read_tablet_to_ls_info(first_turn_id, type, tablet_to_ls_info))) { + if (OB_BACKUP_FILE_NOT_EXIST == ret) { + ret = OB_SUCCESS; + share::SCN snapshot(SCN::min_scn()); + int64_t abs_timeout = ObTimeUtility::current_time() + 10 * 60 * 1000 * 1000; + while (OB_SUCC(ret)) { + if (OB_FAIL(ObBackupDataScheduler::get_backup_scn(*sql_proxy_, set_task_attr_.tenant_id_, true, snapshot))) { + LOG_WARN("failed to get backup scn", K(ret)); + } else if (snapshot >= consistent_scn) { + snapshot = consistent_scn; + break; + } else if (ObTimeUtility::current_time() > abs_timeout) { + ret = OB_TIMEOUT; + break; + } else if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); + } + } if (OB_FAIL(ret)) { - } else if (OB_FAIL(tablet_to_ls_desc.tablet_to_ls_.push_back(tablet_to_ls_info))) { - LOG_WARN("[DATA_BACKUP]fail to push back tablet_to_ls_info", K(ret)); + } else if (OB_FAIL(fill_map_with_sys_tablets_(latest_ls_tablet_map))) { + LOG_WARN("failed to fill map with sys ls tablets", K(ret)); + } else if (OB_FAIL(ObBackupTabletToLSOperator::get_ls_and_tablet( + *sql_proxy_, set_task_attr_.tenant_id_, snapshot, latest_ls_tablet_map))) { + LOG_WARN("fail to get ls and tablet", K(ret), "tenant_id", set_task_attr_.tenant_id_); } else { - max_backup_scn = std::max(max_backup_scn, backup_scn); - tablet_to_ls_desc.backup_scn_ = max_backup_scn; - ++iter; + tablet_to_ls_info.backup_scn_ = snapshot; + common::hash::ObHashMap>::const_iterator iter = latest_ls_tablet_map.begin(); + for(; OB_SUCC(ret) && iter != latest_ls_tablet_map.end(); ++iter) { + ObBackupDataTabletToLSInfo info; + info.ls_id_ = iter->first; + ObLS::ObLSInnerTabletIDIter tablet_iter; + common::ObTabletID tablet_id; + if (!info.ls_id_.is_sys_ls()) { + while (OB_SUCC(ret)) { + if (OB_FAIL(tablet_iter.get_next(tablet_id))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(info.tablet_id_list_.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(tablet_id)); + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(append(info.tablet_id_list_, iter->second))) { + LOG_WARN("failed to append tablet id list", K(ret)); + } else if (OB_FAIL(tablet_to_ls_info.tablet_to_ls_.push_back(info))) { + LOG_WARN("failed to push backup info", K(info)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(store_.write_tablet_to_ls_info(tablet_to_ls_info, first_turn_id, type))) { + LOG_WARN("failed to write tablet to ls info", K(ret), K(tablet_to_ls_info), K(first_turn_id), K(type)); + } + } + } else { + LOG_WARN("failed to read tablet to ls info", K(ret)); + } + } else { + ObArray tablet_id_array; + ARRAY_FOREACH(tablet_to_ls_info.tablet_to_ls_, i) { + const ObBackupDataTabletToLSInfo &info = tablet_to_ls_info.tablet_to_ls_.at(i); + tablet_id_array.reset(); + ARRAY_FOREACH(info.tablet_id_list_, j) { + if (OB_FAIL(tablet_id_array.push_back(info.tablet_id_list_.at(j)))) { + LOG_WARN("failed to push back", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(latest_ls_tablet_map.set_refactored(info.ls_id_, tablet_id_array, 1/*over write*/))) { + LOG_WARN("failed to set refactored", K(ret), K(info)); } } } - if (OB_FAIL(ret)) { // when backup meta succeed, write the first turn tablet_to_ls_info file used by backup data. - } else if (OB_FAIL(store_.write_tablet_to_ls_info(tablet_to_ls_desc, 1/*first turn*/))) { - LOG_WARN("fail to write first turn tablet to ls info", K(ret), K(tablet_to_ls_desc)); + if (OB_FAIL(ret)) { + } else if (OB_FALSE_IT(type.set_major_data_backup())) { + } else if (OB_FAIL(store_.write_tablet_to_ls_info(tablet_to_ls_info, first_turn_id, type))) { + LOG_WARN("failed to write tablet to ls info", K(ret), K(tablet_to_ls_info), K(first_turn_id), K(type)); + } else if (OB_FAIL(update_tablet_id_backup_scn_(tablet_to_ls_info.backup_scn_))) { + LOG_WARN("failed to update tablet id backup scn", K(ret), K(tablet_to_ls_info.backup_scn_)); + } + return ret; +} + +int ObBackupSetTaskMgr::fill_map_with_sys_tablets_( + common::hash::ObHashMap> &latest_ls_tablet_map) +{ + int ret = OB_SUCCESS; + ObArray tablet_ids; + share::SCN backup_scn; + ObLSID sys_ls_id(ObLSID::SYS_LS_ID); + if (OB_FAIL(get_extern_tablet_info_(sys_ls_id, tablet_ids, backup_scn))) { + LOG_WARN("failed to get extern sys ls tablet info", K(ret)); + } else if (OB_FALSE_IT(std::sort(tablet_ids.begin(), tablet_ids.end()))) { + } else if (OB_FAIL(latest_ls_tablet_map.set_refactored(sys_ls_id, tablet_ids, 1))) { + LOG_WARN("failed to set refactored", K(ret), K(sys_ls_id), K(tablet_ids)); } else { - LOG_INFO("[BACKUP_DATA]succeed to write first turn tablet to ls info", K(tablet_to_ls_desc), K(set_task_attr_)); + LOG_INFO("succeed fill sys ls tablets", K(sys_ls_id), K(tablet_ids)); + } + return ret; +} + +int ObBackupSetTaskMgr::update_tablet_id_backup_scn_(const share::SCN &backup_scn) +{ + int ret = OB_SUCCESS; + int64_t dest_id = 0; + ObBackupSetFileDesc backup_set_file; + ObBackupDest backup_dest; + ObMySQLTransaction trans; + if (OB_FAIL(ObBackupStorageInfoOperator::get_backup_dest(*sql_proxy_, job_attr_->tenant_id_, set_task_attr_.backup_path_, backup_dest))) { + LOG_WARN("fail to get backup dest", K(ret), KPC(job_attr_)); + } else if (OB_FAIL(ObBackupStorageInfoOperator::get_dest_id(*sql_proxy_, job_attr_->tenant_id_, backup_dest, dest_id))) { + LOG_WARN("failed to get dest id", K(ret), KPC(job_attr_)); + } else if (OB_FAIL(trans.start(sql_proxy_, meta_tenant_id_))) { + LOG_WARN("failed to start trans", K(ret)); + } else { + if (OB_FAIL(ObBackupSetFileOperator::get_backup_set_file(trans, true/*for update*/, job_attr_->backup_set_id_, + job_attr_->incarnation_id_, job_attr_->tenant_id_, dest_id, backup_set_file))) { + LOG_WARN("failed to get backup set", K(ret), KPC(job_attr_)); + } else if (OB_FALSE_IT(backup_set_file.consistent_scn_ = backup_scn)) { + } else if (OB_FAIL(ObBackupSetFileOperator::update_backup_set_file(trans, backup_set_file))) { + LOG_WARN("failed to update backup set file", K(ret)); + } else if (OB_FAIL(trans.end(true))) { + LOG_WARN("failed to commit", K(ret)); + } + + if (OB_FAIL(ret) && trans.is_active()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(false))) { + LOG_WARN("failed to rollback", K(tmp_ret)); + } + } } return ret; } int ObBackupSetTaskMgr::get_extern_tablet_info_( - const share::ObLSID &ls_id, const int64_t &retry_cnt, - share::ObBackupDataTabletToLSInfo &tablet_to_ls_info, - SCN &backup_scn) + const share::ObLSID &ls_id, ObIArray &user_tablet_ids, SCN &backup_scn) { int ret = OB_SUCCESS; - share::ObBackupSetDesc backup_set_desc; - ObArray tablet_ids; - share::ObBackupDataTabletToLSDesc desc; - int64_t turn_id = ls_id.is_sys_ls() ? 1/*sys ls only has one meta turn*/ : set_task_attr_.meta_turn_id_; - if (OB_FAIL(store_.read_tablet_to_ls_info(ls_id, turn_id, retry_cnt, desc))) { - LOG_WARN("fail to read read_tablet_to_ls_info", K(ret), K(ls_id), K(turn_id), K(retry_cnt)); - } else { - bool found = false; - for (int64_t i = 0; OB_SUCC(ret) && i < desc.tablet_to_ls_.count(); ++i) { - const share::ObBackupDataTabletToLSInfo &info = desc.tablet_to_ls_.at(i); - if (info.ls_id_ == ls_id) { - tablet_to_ls_info.ls_id_ = ls_id; - if (OB_FAIL(tablet_to_ls_info.tablet_id_list_.assign(info.tablet_id_list_))) { - LOG_WARN("fail to assign tablet ids", K(ret), K(info)); - } else { - backup_scn = desc.backup_scn_; - } - found = true; - } - } - if (OB_SUCC(ret) && !found) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("do not found entry", K(ls_id)); - } - } - return ret; -} - -int ObBackupSetTaskMgr::check_tablets_match_( - const ObLSID &ls_id, - const ObIArray &cur_tablet_ids, - const ObIArray &user_tablet_ids, - const SCN &backup_scn) -{ - int ret = OB_SUCCESS; - ObHashSet tablet_set; - int64_t OB_BACKUP_MAX_LS_BUCKET = 1024; - ObBackupCheckTabletArg arg; - if (!ls_id.is_valid()) { + storage::ObLSMetaPackage ls_meta_package; + if (OB_FAIL(store_.read_base_tablet_list(ls_id, user_tablet_ids))) { + LOG_WARN("failed to read base tablet lsit", K(ret), K(ls_id)); + } else if (OB_FAIL(store_.read_ls_meta_infos(ls_id, ls_meta_package))) { + LOG_WARN("failed to read ls meta infos", K(ret)); + } else if (!ls_meta_package.is_valid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid ls id", K(ret), K(ls_id)); - } else if (OB_FAIL(tablet_set.create(OB_MAX_TABLE_ID_LIST_SIZE))) { - LOG_WARN("[DATA_BACKUP]fail to create ls set", K(ret)); + LOG_WARN("invalid ls meta", K(ret)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < user_tablet_ids.count(); ++i) { - const ObTabletID &tablet_id = user_tablet_ids.at(i); - if (OB_FAIL(tablet_set.set_refactored(user_tablet_ids.at(i)))) { - LOG_WARN("[DATA_BACKUP]fail to insert tablet into tablet set", K(ret), K(tablet_id)); - } - } - ObArray inc_tablets; - for (int64_t i = 0; OB_SUCC(ret) && i < cur_tablet_ids.count(); ++i) { - const ObTabletID &tablet_id = cur_tablet_ids.at(i); - if (OB_FAIL(tablet_set.exist_refactored(tablet_id))) { - if (OB_HASH_NOT_EXIST == ret) { - if (OB_FAIL(inc_tablets.push_back(tablet_id))) { - LOG_WARN("[DATA_BACKUP]fail to push back tablet id into inc tablets", K(ret), K(tablet_id)); - } - } else if (OB_HASH_EXIST == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("[DATA_BACKUP]fail to check tablet exist", K(ret), K(tablet_id)); - } - } - } - - if (OB_FAIL(ret)) { - } else if (inc_tablets.empty()) { - } else if (OB_FAIL(do_check_inc_tablets_(ls_id, inc_tablets, backup_scn))) { - LOG_WARN("[DATA_BACKUP]fail to do check backup all tablets", K(ret), K(ls_id), K(inc_tablets)); - } + backup_scn = ls_meta_package.ls_meta_.get_clog_checkpoint_scn(); } return ret; } -int ObBackupSetTaskMgr::do_check_inc_tablets_( - const ObLSID &ls_id, - const ObIArray &inc_tablets, - const SCN &backup_scn) -{ - int ret = OB_SUCCESS; - ObAddr dst_server; - const int64_t batch_size = 2048; - if (!ls_id.is_valid() || inc_tablets.empty()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(ls_id), K(inc_tablets)); - } else if (OB_FAIL(get_dst_server_(ls_id, dst_server))) { - LOG_WARN("[DATA_BACKUP]fail to get dst server", K(ret)); - } else { - ObBackupCheckTabletArg arg; - arg.tenant_id_ = set_task_attr_.tenant_id_; - arg.ls_id_ = ls_id; - arg.backup_scn_ = backup_scn; - ARRAY_FOREACH(inc_tablets, i) { - arg.tablet_ids_.reset(); - if (OB_FAIL(arg.tablet_ids_.push_back(inc_tablets.at(i)))) { - LOG_WARN("failed to push back", K(ret)); - } else if (arg.tablet_ids_.count() == batch_size || inc_tablets.count() - 1 == i) { - if (OB_FAIL(rpc_proxy_->to(dst_server).check_not_backup_tablet_create_scn(arg))) { - LOG_WARN("[DATA_BACKUP]fail to send backup check tablet rpc", K(ret), K(arg), K(dst_server)); - } else { - FLOG_INFO("[DATA_BACKUP]succeed send backup check tablet rpc", K(arg), K(dst_server)); - } - } - } - } - return ret; -} - -int ObBackupSetTaskMgr::get_dst_server_(const ObLSID &ls_id, ObAddr &dst) -{ - int ret = OB_SUCCESS; - uint64_t tenant_id = set_task_attr_.tenant_id_; - share::ObLSTableOperator *lst_operator = GCTX.lst_operator_; - int64_t cluster_id = GCONF.cluster_id; - ObLSInfo ls_info; - if (!ls_id.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(ls_id)); - } else if (OB_ISNULL(lst_operator)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("[DATA_BACKUP]lst_operator ptr is null", K(ret)); - } else { - // When change leader, the new leader may not be reported to __all_ls_meta_table timely, and we could get no leader. - // And ownerless election may cost more than 30s for choosing leader. - // So, we add retry to tolerate this scene, and set the abs timeout to 30s in the future. - const int64_t abs_timeout = ObTimeUtility::current_time() + 30 * 1000 * 1000; - do { - if (OB_FAIL(lst_operator->get(cluster_id, tenant_id, ls_id, share::ObLSTable::DEFAULT_MODE, ls_info))) { - LOG_WARN("[DATA_BACKUP]failed to get log stream info", K(ret), K(cluster_id), K(tenant_id), K(ls_id)); - } else { - const ObLSInfo::ReplicaArray &replica_array = ls_info.get_replicas(); - for (int64_t i = 0; OB_SUCC(ret) && i < replica_array.count(); ++i) { - const ObLSReplica &replica = replica_array.at(i); - if (replica.is_in_service() && replica.is_strong_leader() && replica.is_valid()) { - dst = replica.get_server(); - break; - } - } - } - if (!dst.is_valid()) { - // wait 100 ms for next retry. - usleep(100 * 1000); - if(OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("failed to check lease", K(ret)); - } - } - } while (OB_SUCC(ret) && !dst.is_valid() && ObTimeUtility::current_time() < abs_timeout); - } - - if (OB_FAIL(ret)) { - } else if (!dst.is_valid()) { - ret = OB_LEADER_NOT_EXIST; - LOG_WARN("[DATA_BACKUP]no leader be found", K(ret), K(ls_id), K(set_task_attr_)); - } - return ret; -} - -int ObBackupSetTaskMgr::construct_ls_task_map_(const ObIArray &ls_tasks, - hash::ObHashMap &ls_map) -{ - int ret = OB_SUCCESS; - for (int64_t i = 0; OB_SUCC(ret) && i < ls_tasks.count(); ++i) { - const ObBackupLSTaskAttr &ls_task_attr = ls_tasks.at(i); - if (OB_FAIL(ls_map.set_refactored(ls_task_attr.ls_id_, &ls_task_attr))) { - LOG_WARN("[DATA_BACKUP]fail to insert ls id into set", K(ret)); - } - } - return ret; -} - -int ObBackupSetTaskMgr::disable_transfer_() -{ - int ret = OB_SUCCESS; - FLOG_WARN("disable transfer success"); - return ret; -} - -int ObBackupSetTaskMgr::enable_transfer_() -{ - int ret = OB_SUCCESS; - FLOG_WARN("enable transfer success"); - return ret; -} - -int ObBackupSetTaskMgr::do_backup_meta_(ObArray &ls_task, int64_t &finish_cnt) +int ObBackupSetTaskMgr::do_backup_meta_(ObIArray &ls_task, int64_t &finish_cnt) { int ret = OB_SUCCESS; finish_cnt = 0; @@ -787,8 +916,7 @@ int ObBackupSetTaskMgr::do_backup_meta_(ObArray &ls_task, in for (int64_t i = 0; OB_SUCC(ret) && i < ls_task.count(); ++i) { ObBackupLSTaskAttr &ls_attr = ls_task.at(i); ObBackupDataLSTaskMgr ls_task_mgr; - if (OB_FAIL(ls_task_mgr.init(*job_attr_, set_task_attr_, ls_attr, *task_scheduler_, *sql_proxy_, - *lease_service_, *backup_service_))) { + if (OB_FAIL(ls_task_mgr.init(*job_attr_, set_task_attr_, ls_attr, *task_scheduler_, *sql_proxy_, *backup_service_))) { LOG_WARN("[DATA_BACKUP]failed to init task advancer", K(ret), K(ls_attr)); } else if (OB_FAIL(ls_task_mgr.process(finish_cnt))) { LOG_WARN("[DATA_BACKUP]failed to process ls backup meta task", K(ret), K(ls_attr), K(set_task_attr_)); @@ -814,7 +942,7 @@ int ObBackupSetTaskMgr::get_next_status_(const share::ObBackupStatus &cur_status ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(cur_status)); } else { - switch (cur_status.status_) + switch (cur_status) { case ObBackupStatus::Status::INIT: { next_status = ObBackupStatus::Status::BACKUP_SYS_META; @@ -825,14 +953,11 @@ int ObBackupSetTaskMgr::get_next_status_(const share::ObBackupStatus &cur_status break; } case ObBackupStatus::Status::BACKUP_USER_META: { - next_status = ObBackupStatus::Status::BACKUP_DATA_SYS; - break; - } - case ObBackupStatus::Status::BACKUP_DATA_SYS: { next_status = ObBackupStatus::Status::BACKUP_DATA_MINOR; break; } case ObBackupStatus::Status::BACKUP_DATA_MINOR: { + DEBUG_SYNC(BEFORE_BACKUP_MAJOR); next_status = ObBackupStatus::Status::BACKUP_DATA_MAJOR; break; } @@ -857,49 +982,54 @@ int ObBackupSetTaskMgr::backup_data_() ObArray ls_task; int64_t finish_cnt = 0; ObBackupLSTaskAttr *build_index_attr = nullptr; - if (OB_FAIL(enable_transfer_())) { - LOG_WARN("[DATA_BACKUP]failed to enbale transfer", K(ret)); - } else if (OB_FAIL(ObBackupLSTaskOperator::get_ls_tasks(*sql_proxy_, job_attr_->job_id_, job_attr_->tenant_id_, false/*update*/, ls_task))) { + if (OB_FAIL(ObBackupLSTaskOperator::get_ls_tasks(*sql_proxy_, job_attr_->job_id_, job_attr_->tenant_id_, false/*update*/, ls_task))) { LOG_WARN("[DATA_BACKUP]failed to get log stream tasks", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); } else if (ls_task.empty()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("[DATA_BACKUP]no lostream task", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); + LOG_WARN("[DATA_BACKUP]no logstream task", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); } else if (OB_FAIL(do_backup_data_(ls_task, finish_cnt, build_index_attr))) { LOG_WARN("[DATA_BACKUP]failed to do backup ls task", K(ret), K(ls_task)); } else if (ls_task.count() == finish_cnt) { SCN end_scn = SCN::min_scn(); bool need_change_turn = false; bool finish_build_index = false; - ObSArray tablets_to_ls; + ObSArray tablets_to_ls; ObSArray new_ls_array; - if (OB_FAIL(get_next_status_(set_task_attr_.status_, next_status_))) { - LOG_WARN("fail to get next status", K(set_task_attr_.status_), K(next_status_)); + share::ObBackupStatus next_status; + if (OB_FAIL(build_index_(build_index_attr, finish_build_index))) { + LOG_WARN("[DATA_BACKUP]failed to wait build index", K(ret), KPC(build_index_attr)); + } else if (!finish_build_index) { + } else if (OB_FAIL(check_change_task_turn_(ls_task, need_change_turn, tablets_to_ls, new_ls_array))) { + LOG_WARN("[DATA_BACKUP]failed to check change task turn", K(ret), K(set_task_attr_)); + } else if (OB_FAIL(get_next_status_(set_task_attr_.status_, next_status))) { + LOG_WARN("fail to get next status", K(set_task_attr_.status_), K(next_status)); } else if (OB_FAIL(trans_.start(sql_proxy_, meta_tenant_id_))) { LOG_WARN("fail to start trans", K(ret)); } else { - if (OB_FAIL(ObBackupDataScheduler::get_backup_scn(*sql_proxy_, job_attr_->tenant_id_, false/*end scn*/, end_scn))) { - LOG_WARN("[DATA_BACKUP]failed to get end ts", K(ret), "tenant_id", job_attr_->tenant_id_); - } else if (OB_FAIL(build_index_(build_index_attr, set_task_attr_.data_turn_id_, set_task_attr_.task_id_, finish_build_index))) { - LOG_WARN("[DATA_BACKUP]failed to wait build index", K(ret), K(set_task_attr_), KPC(build_index_attr)); - } else if (!finish_build_index) { - } else if (OB_FAIL(check_change_task_turn_(ls_task, need_change_turn, tablets_to_ls, new_ls_array))) { - LOG_WARN("[DATA_BACKUP]failed to check change task turn", K(ret), K(set_task_attr_)); + if (OB_FAIL(ObBackupLSTaskOperator::delete_build_index_task(trans_, *build_index_attr))) { + LOG_WARN("[DATA_BACKUP]failed to delete build index task", K(ret)); } else if (need_change_turn) { if (OB_FAIL(change_task_turn_(ls_task, tablets_to_ls, new_ls_array))) { LOG_WARN("[DATA_BACKUP]failed to change task turn", K(ret), K(set_task_attr_)); + } else if (OB_FAIL(ObBackupSkippedTabletOperator::move_skip_tablet_to_his( + trans_, set_task_attr_.tenant_id_, set_task_attr_.task_id_))) { + LOG_WARN("[DATA_BACKUP]failed to move skip tablet to history", K(ret)); } else { backup_service_->wakeup(); } } else { if (ObBackupStatus::Status::BACKUP_DATA_MAJOR == set_task_attr_.status_.status_ && !job_attr_->plus_archivelog_) { - } else if (OB_FAIL(update_task_type_(ls_task))) { + } else if (OB_FAIL(convert_task_type_(ls_task))) { LOG_WARN("[DATA_BACKUP]failed to update task type to PLUS_ARCHIVE_LOG", K(ret), K(ls_task)); } if (OB_FAIL(ret)) { - } else if (OB_FAIL(advance_status_(trans_, next_status_, OB_SUCCESS, end_scn))) { + } else if (OB_FAIL(ObBackupDataScheduler::get_backup_scn(*sql_proxy_, job_attr_->tenant_id_, false/*end scn*/, end_scn))) { + LOG_WARN("[DATA_BACKUP]failed to get end ts", K(ret), "tenant_id", job_attr_->tenant_id_); + } else if (OB_FAIL(advance_status_(trans_, next_status, OB_SUCCESS, end_scn))) { LOG_WARN("[DATA_BACKUP]failed to update set task status to COMPLETEING", K(ret), K(set_task_attr_)); } else { + set_task_attr_.status_ = next_status; LOG_INFO("backup data succeed, advance status to backup compelement log", "tenant_id", job_attr_->tenant_id_, "job_id", job_attr_->job_id_, "task_id", set_task_attr_.task_id_); ROOTSERVICE_EVENT_ADD("backup_data", "backup data succeed", "tenant_id", @@ -941,7 +1071,7 @@ int ObBackupSetTaskMgr::do_backup_data_( build_index_attr = &ls_attr; } ObBackupDataLSTaskMgr ls_task_mgr; - if (OB_FAIL(ls_task_mgr.init(*job_attr_, set_task_attr_, ls_attr, *task_scheduler_, *sql_proxy_, *lease_service_, *backup_service_))) { + if (OB_FAIL(ls_task_mgr.init(*job_attr_, set_task_attr_, ls_attr, *task_scheduler_, *sql_proxy_, *backup_service_))) { LOG_WARN("[DATA_BACKUP]failed to init task advancer", K(ret), K(ls_attr)); } else if (OB_FAIL(ls_task_mgr.process(finish_cnt))) { LOG_WARN("[DATA_BACKUP]failed to process log stream task", K(ret), K(ls_attr), K(set_task_attr_)); @@ -959,12 +1089,20 @@ int ObBackupSetTaskMgr::do_backup_data_( int ObBackupSetTaskMgr::check_change_task_turn_( const ObIArray &ls_tasks, bool &need_change_turn, - ObIArray &tablets_to_ls, + ObIArray &tablets_to_ls, ObIArray &new_ls_array) { int ret = OB_SUCCESS; need_change_turn = true; - if (OB_FAIL(get_change_turn_tablets_(ls_tasks, tablets_to_ls, new_ls_array))) { +#ifdef ERRSIM + ROOTSERVICE_EVENT_ADD("backup_errsim", "before_check_change_task_turn", + "tenant_id", set_task_attr_.tenant_id_, + "task_id", set_task_attr_.task_id_); +#endif + DEBUG_SYNC(BEFORE_CHANGE_BACKUP_TURN); + if (set_task_attr_.status_.is_backup_sys()) { + need_change_turn = false; + } else if (OB_FAIL(get_change_turn_tablets_(ls_tasks, tablets_to_ls, new_ls_array))) { LOG_WARN("[DATA_BACKUP]failed to get change turn tablets", K(ret), K(ls_tasks)); } else if (tablets_to_ls.empty() && new_ls_array.empty()) { need_change_turn = false; @@ -973,8 +1111,8 @@ int ObBackupSetTaskMgr::check_change_task_turn_( } int ObBackupSetTaskMgr::change_task_turn_( - ObIArray &ls_task, - ObIArray &tablets_to_ls, + ObIArray &ls_task, + ObIArray &tablets_to_ls, ObIArray &new_ls_array) { int ret = OB_SUCCESS; @@ -983,14 +1121,20 @@ int ObBackupSetTaskMgr::change_task_turn_( ret = OB_INVALID_ARGUMENT; LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(ls_task), K(tablets_to_ls), K(new_ls_array)); } else { - set_task_attr_.data_turn_id_++; - if (OB_FAIL(write_tablet_to_ls_infos_(tablets_to_ls, set_task_attr_.data_turn_id_))) { - LOG_WARN("[DATA_BACKUP]failed to write ls and tablets info when change turn", K(ret), K(tablets_to_ls), K(set_task_attr_)); + ObBackupStatus::BACKUP_DATA_MINOR == set_task_attr_.status_ ? set_task_attr_.minor_turn_id_++ : set_task_attr_.major_turn_id_++; + if (OB_FAIL(write_tablet_to_ls_infos_(tablets_to_ls))) { + LOG_WARN("[DATA_BACKUP]failed to write ls and tablets info when change turn", K(ret), K(tablets_to_ls)); } else if (OB_FAIL(get_change_turn_ls_(ls_task, tablets_to_ls, need_change_turn_ls_tasks))) { LOG_WARN("[DATA_BACKUP]failed to get change turn id and ls when change turn", K(ret), K(ls_task), K(tablets_to_ls)); } else if (OB_FAIL(update_inner_task_(new_ls_array, need_change_turn_ls_tasks))) { LOG_WARN("[DATA_BACKUP]failed to update inner task when change turn", K(ret), K(need_change_turn_ls_tasks)); } + ROOTSERVICE_EVENT_ADD("backup_data", "after_change_backup_turn_id", + "tenant_id", job_attr_->tenant_id_, + "backup_status", set_task_attr_.status_, + "new_turn_id", ObBackupStatus::BACKUP_DATA_MINOR == set_task_attr_.status_ ? + set_task_attr_.minor_turn_id_ : set_task_attr_.major_turn_id_); + DEBUG_SYNC(AFTER_CHANGE_BACKUP_TURN_ID); } return ret; } @@ -1000,19 +1144,23 @@ int ObBackupSetTaskMgr::update_inner_task_( const ObIArray &need_change_turn_ls_tasks) { int ret = OB_SUCCESS; + int64_t turn_id = 0; for (int64_t i = 0; OB_SUCC(ret) && i < need_change_turn_ls_tasks.count(); ++i) { ObBackupLSTaskAttr *ls_attr = need_change_turn_ls_tasks.at(i); if (nullptr == ls_attr) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]null ls ptr", K(ret)); // TODO use another error code to determine change turn in 4.1 + } else if (OB_FAIL(calc_task_turn_(ls_attr->task_type_, turn_id))) { + LOG_WARN("failed to calc task turn id", K(ret)); } else if (OB_FAIL(ObBackupDataLSTaskMgr::redo_ls_task( - *lease_service_, trans_, *ls_attr, ls_attr->start_turn_id_, set_task_attr_.data_turn_id_, 0/*retry_id*/))) { - LOG_WARN("[DATA_BACKUP]failed to update ls task result to success", K(ret), KPC(ls_attr)); + *backup_service_, trans_, *ls_attr, ls_attr->start_turn_id_, turn_id, 0/*retry_id*/))) { + LOG_WARN("[DATA_BACKUP]failed to update ls task result to success", K(ret), KPC(ls_attr), K(turn_id)); } } ObBackupDataTaskType type; - if (ObBackupStatus::Status::BACKUP_DATA_SYS == set_task_attr_.status_.status_) { + if (OB_FAIL(ret)) { + } else if (ObBackupStatus::Status::BACKUP_DATA_SYS == set_task_attr_.status_.status_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sys tablet must not transfer", K(ret), K(set_task_attr_)); } else if (ObBackupStatus::Status::BACKUP_DATA_MINOR == set_task_attr_.status_.status_) { @@ -1024,43 +1172,67 @@ int ObBackupSetTaskMgr::update_inner_task_( if (OB_FAIL(ret)) { } else if (!new_ls_ids.empty() && OB_FAIL(generate_ls_tasks_(new_ls_ids, type))) { LOG_WARN("[DATA_BACKUP]failed to generate new task", K(ret), K(new_ls_ids)); - } else if ((!new_ls_ids.empty() || !need_change_turn_ls_tasks.empty()) - && OB_FAIL(ObBackupTaskOperator::update_max_turn_id( - trans_, set_task_attr_.task_id_, set_task_attr_.tenant_id_, set_task_attr_.data_turn_id_))) { - LOG_WARN("[DATA_BACKUP]failed to update max turn id", K(ret), "task_id", set_task_attr_.task_id_, - "tenant_id", set_task_attr_.tenant_id_, "max_turn_id", set_task_attr_.data_turn_id_); + } else if ((!new_ls_ids.empty() || !need_change_turn_ls_tasks.empty())) { + // change backup task turn. + turn_id = ObBackupStatus::BACKUP_DATA_MINOR == set_task_attr_.status_ ? set_task_attr_.minor_turn_id_ : set_task_attr_.major_turn_id_; + if (OB_FAIL(ObBackupTaskOperator::update_turn_id( + trans_, + set_task_attr_.status_, + set_task_attr_.task_id_, + set_task_attr_.tenant_id_, + turn_id))) { + LOG_WARN("[DATA_BACKUP]failed to update backup task turn id", K(ret), K_(set_task_attr), K(turn_id)); + } } return ret; } -int ObBackupSetTaskMgr::write_tablet_to_ls_infos_( - const ObIArray &tablets_to_ls, - const int64_t turn_id) +int ObBackupSetTaskMgr::write_tablet_to_ls_infos_(const ObIArray &tablets_to_ls) { int ret = OB_SUCCESS; - share::ObBackupDataTabletToLSDesc tablet_to_ls_desc; + storage::ObBackupDataTabletToLSDesc tablet_to_ls_desc; + int64_t turn_id = 0; if (tablets_to_ls.empty()) { // no tablet, no need to write extern tablets info } else if (OB_FAIL(append(tablet_to_ls_desc.tablet_to_ls_, tablets_to_ls))) { LOG_WARN("[DATA_BACKUP]failed to append tablets_to_ls", K(ret)); - } else if (OB_FAIL(store_.write_tablet_to_ls_info(tablet_to_ls_desc, turn_id))) { - LOG_WARN("[DATA_BACKUP]failed to write tablet to log stream", K(ret), K(tablet_to_ls_desc), K(turn_id)); + } else { + ObBackupDataType data_type; + ObBackupDataTaskType task_type; + switch(set_task_attr_.status_) { + case ObBackupStatus::BACKUP_DATA_MINOR: { + data_type.set_minor_data_backup(); + task_type.set_backup_minor(); + break; + } + case ObBackupStatus::BACKUP_DATA_MAJOR: { + data_type.set_major_data_backup(); + task_type.set_backup_major(); + break; + } + default: { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected backup status while change turn", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(calc_task_turn_(task_type, turn_id))) { + LOG_WARN("failed to calc task turn id", K(ret)); + } else if (OB_FAIL(store_.write_tablet_to_ls_info(tablet_to_ls_desc, turn_id, data_type))) { + LOG_WARN("[DATA_BACKUP]failed to write tablet to log stream", K(ret), K(tablet_to_ls_desc), K(turn_id)); + } } return ret; } -int ObBackupSetTaskMgr::build_index_( - ObBackupLSTaskAttr *build_index_attr, - const int64_t turn_id, - const int64_t task_id, - bool &finish_build_index) +int ObBackupSetTaskMgr::build_index_(ObBackupLSTaskAttr *build_index_attr, bool &finish_build_index) { int ret = OB_SUCCESS; finish_build_index = false; - if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret)); + if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("[DATA_BACKUP]failed to check leader", K(ret)); } else if (nullptr == build_index_attr) { ObBackupLSTaskAttr build_index_task; - build_index_task.task_id_ = task_id; + build_index_task.task_id_ = set_task_attr_.task_id_; build_index_task.tenant_id_ = job_attr_->tenant_id_; build_index_task.ls_id_ = ObLSID(0); build_index_task.job_id_ = job_attr_->job_id_; @@ -1069,23 +1241,21 @@ int ObBackupSetTaskMgr::build_index_( build_index_task.task_type_.type_ = ObBackupDataTaskType::Type::BACKUP_BUILD_INDEX; build_index_task.status_.status_ = ObBackupTaskStatus::Status::INIT; build_index_task.start_ts_ = ObTimeUtility::current_time(); - build_index_task.start_turn_id_ = turn_id; - build_index_task.turn_id_ = turn_id; + build_index_task.start_turn_id_ = 1; build_index_task.retry_id_ = 0; build_index_task.result_ = OB_SUCCESS; - if (OB_FAIL(ObBackupUtils::convert_timestamp_to_date(build_index_task.start_ts_, build_index_task.backup_date_))) { + build_index_task.max_tablet_checkpoint_scn_.set_min(); + if (OB_FAIL(calc_task_turn_(build_index_task.task_type_, build_index_task.turn_id_))) { + LOG_WARN("failed to calc ls task turn", K(ret)); + } else if (OB_FAIL(ObBackupUtils::convert_timestamp_to_date(build_index_task.start_ts_, build_index_task.backup_date_))) { LOG_WARN("[DATA_BACKUP]failed to get date", K(ret), K(build_index_task)); - } else if (OB_FAIL(ObBackupLSTaskOperator::insert_build_index_task(trans_, build_index_task))) { + } else if (OB_FAIL(ObBackupLSTaskOperator::insert_build_index_task(*sql_proxy_, build_index_task))) { LOG_WARN("[DATA_BACKUP]failed to insert build index task", K(ret), K(build_index_task)); } else { backup_service_->wakeup(); } } else if (OB_SUCCESS == build_index_attr->result_ && ObBackupTaskStatus::Status::FINISH == build_index_attr->status_.status_) { - if (OB_FAIL(ObBackupLSTaskOperator::delete_build_index_task(trans_, *build_index_attr))) { - LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret)); - } else { - finish_build_index = true; - } + finish_build_index = true; } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]unexpected err", K(ret), KPC(build_index_attr)); @@ -1095,14 +1265,14 @@ int ObBackupSetTaskMgr::build_index_( int ObBackupSetTaskMgr::get_change_turn_ls_( ObIArray &ls_task, - const ObIArray &tablets_to_ls, + const ObIArray &tablets_to_ls, ObIArray &need_change_turn_ls_tasks) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < ls_task.count(); ++i) { for (int64_t j = 0; OB_SUCC(ret) && j < tablets_to_ls.count(); ++j) { ObBackupLSTaskAttr &ls_attr = ls_task.at(i); - const share::ObBackupDataTabletToLSInfo& tablets = tablets_to_ls.at(j); + const storage::ObBackupDataTabletToLSInfo& tablets = tablets_to_ls.at(j); if (ls_attr.ls_id_ == tablets.ls_id_) { if (OB_FAIL(need_change_turn_ls_tasks.push_back(&ls_attr))) { LOG_WARN("[DATA_BACKUP]failed to push ls task", K(ret)); @@ -1115,37 +1285,72 @@ int ObBackupSetTaskMgr::get_change_turn_ls_( int ObBackupSetTaskMgr::get_change_turn_tablets_( const ObIArray &ls_tasks, - ObIArray &tablet_to_ls, + ObIArray &tablet_to_ls, ObIArray &new_ls_ids) { int ret = OB_SUCCESS; - ObArray tablet_attrs; + ObHashSet skipped_tablets; ObBackupSkippedType skipped_type(ObBackupSkippedType::TRANSFER); - if (OB_FAIL(ObBackupSkippedTabletOperator::get_skip_tablet(trans_, true/*lock*/, set_task_attr_.tenant_id_, set_task_attr_.task_id_, skipped_type, tablet_attrs))) { + const int OB_MAX_SKIPPED_TABLET_NUM = 1000; + if (OB_FAIL(skipped_tablets.create(OB_MAX_SKIPPED_TABLET_NUM))) { + LOG_WARN("failed to create skipped tablets set", K(ret)); + } else if (OB_FAIL(get_tablets_of_deleted_ls_(ls_tasks, skipped_tablets))) { + LOG_WARN("failed to get tablets of deleted ls", K(ret), K(ls_tasks)); + } else if (OB_FAIL(ObBackupSkippedTabletOperator::get_skip_tablet(*sql_proxy_, false/*no lock*/, set_task_attr_.tenant_id_, set_task_attr_.task_id_, skipped_type, skipped_tablets))) { LOG_WARN("[DATA_BACKUP]failed to get skip tablet", K(ret), "teannt_id", set_task_attr_.tenant_id_, "task_id", set_task_attr_.task_id_); - } else if (tablet_attrs.empty()) { + } else if (skipped_tablets.empty()) { LOG_INFO("[DATA_BACKUP]no change turn tablets found", K(ret)); - } else if (OB_FAIL(do_get_change_turn_tablets_(ls_tasks, tablet_attrs, tablet_to_ls, new_ls_ids))) { - LOG_WARN("[DATA_BACKUP]failed to do get change turn tables", K(ret), K(tablet_attrs), K(set_task_attr_)); - } else if (OB_FAIL(ObBackupSkippedTabletOperator::move_skip_tablet_to_his(trans_, set_task_attr_.tenant_id_, set_task_attr_.task_id_, skipped_type))) { - LOG_WARN("[DATA_BACKUP]failed to move skip tablet to history", K(ret), K(tablet_attrs)); + } else if (OB_FAIL(do_get_change_turn_tablets_(ls_tasks, skipped_tablets, tablet_to_ls, new_ls_ids))) { + LOG_WARN("[DATA_BACKUP]failed to do get change turn tables", K(ret), K(set_task_attr_)); + } + return ret; +} + +int ObBackupSetTaskMgr::get_tablets_of_deleted_ls_( + const ObIArray &ls_tasks, common::hash::ObHashSet &skipped_tablets) +{ + int ret = OB_SUCCESS; + ObBackupDataType type; + type.type_ = set_task_attr_.status_.is_backup_minor() ? ObBackupDataType::BACKUP_MINOR : ObBackupDataType::BACKUP_MAJOR; + const int64_t set_task_turn_id = set_task_attr_.status_.is_backup_minor() ? set_task_attr_.minor_turn_id_ : set_task_attr_.major_turn_id_; + ARRAY_FOREACH(ls_tasks, i) { + ObArray tablet_ids; + const ObBackupLSTaskAttr &ls_task = ls_tasks.at(i); + if (ls_task.result_ != OB_LS_NOT_EXIST || ls_task.turn_id_ != set_task_turn_id) { + continue; + } else if (OB_FAIL(store_.read_tablet_list(type, ls_task.turn_id_, ls_task.ls_id_, tablet_ids))) { + LOG_WARN("failed to read tablet list", K(ret)); + } + + ARRAY_FOREACH(tablet_ids, i) { + if (tablet_ids.at(i).is_inner_tablet()) { + continue; + } + ObBackupSkipTabletAttr skipped_tablet; + skipped_tablet.tablet_id_ = tablet_ids.at(i); + skipped_tablet.skipped_type_ = ObBackupSkippedType(ObBackupSkippedType::TRANSFER); + if (OB_FAIL(skipped_tablets.set_refactored(skipped_tablet))) { + LOG_WARN("failed to push back skipped tablet", K(ret), K(skipped_tablet)); + } + } } return ret; } int ObBackupSetTaskMgr::do_get_change_turn_tablets_( const ObIArray &ls_tasks, - const ObIArray &all_tablets, - ObIArray &tablet_to_ls, + const common::hash::ObHashSet &skipped_tablets, + ObIArray &tablet_to_ls, ObIArray &new_ls_ids) { int ret = OB_SUCCESS; // if tablet can't be found in __all_tablet_to_ls, it need't to change turn // if tablet transfer to a new create ls, need insert a new ls task - ObHashMap> tablet_to_ls_map; + ObHashMap> tablet_to_ls_map; ObHashSet ls_id_set; ObHashSet new_ls_id_set; ObLSID ls_id; + int64_t transfer_seq = 0; const int64_t OB_BACKUP_MAX_LS_BUCKET = 1024; if (OB_FAIL(tablet_to_ls_map.create(OB_BACKUP_MAX_LS_BUCKET, "tabletToLS"))) { LOG_WARN("[DATA_BACKUP]failed to create map", K(ret)); @@ -1156,29 +1361,29 @@ int ObBackupSetTaskMgr::do_get_change_turn_tablets_( } else if (OB_FAIL(construct_cur_ls_set_(ls_tasks, ls_id_set))) { LOG_WARN("[DATA_BACKUP]failed to get last turn ls ids", K(ret), K(set_task_attr_)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < all_tablets.count(); ++i) { - const ObBackupSkipTabletAttr &skip_tablet = all_tablets.at(i); - if (OB_FAIL(ObBackupTabletToLSOperator::get_ls_of_tablet(*sql_proxy_, job_attr_->tenant_id_, skip_tablet.tablet_id_, ls_id))) { + for (auto iter = skipped_tablets.begin(); OB_SUCC(ret) && iter != skipped_tablets.end(); ++iter) { + const ObBackupSkipTabletAttr &skip_tablet = iter->first; + if (OB_FAIL(ObBackupTabletToLSOperator::get_ls_of_tablet(*sql_proxy_, job_attr_->tenant_id_, skip_tablet.tablet_id_, ls_id, transfer_seq))) { if (OB_ENTRY_NOT_EXIST == ret) { ret = OB_SUCCESS; LOG_WARN("[DATA_BACKUP]deleted tablet", K(skip_tablet)); } else { LOG_WARN("[DATA_BACKUP]failed to get tablet", K(ret), K(skip_tablet)); } - } else if (ls_id != skip_tablet.ls_id_) { // transfer or split - ObArray tmp_tablet_ids; - if (OB_FAIL(tablet_to_ls_map.get_refactored(ls_id, tmp_tablet_ids))) { - if (OB_ENTRY_NOT_EXIST) { - ret = OB_SUCCESS; - } else { - LOG_WARN("[DATA_BACKUP]failed to get refactored", K(ret), K(ls_id)); + } else { + ObArray *tablet_ids = nullptr; + if (OB_ISNULL(tablet_ids = tablet_to_ls_map.get(ls_id))) { + ObArray cur_tablet_ids; + if (OB_FAIL(cur_tablet_ids.push_back(skip_tablet.tablet_id_))) { + LOG_WARN("[DATA_BACKUP]failed to push tablet id", K(ret), K(skip_tablet.tablet_id_)); + } else if (OB_FAIL(tablet_to_ls_map.set_refactored(ls_id, cur_tablet_ids, 1/*cover exist object*/))) { + LOG_WARN("[DATA_BACKUP]failed to set_refactored", K(ret), K(ls_id)); } + } else if (OB_FAIL(tablet_ids->push_back(skip_tablet.tablet_id_))) { + LOG_WARN("fail to append tablet ids", K(ret)); } + if (OB_FAIL(ret)) { - } else if (OB_FAIL(tmp_tablet_ids.push_back(skip_tablet.tablet_id_))) { - LOG_WARN("[DATA_BACKUP]failed to push tablet id", K(ret), K(skip_tablet)); - } else if (OB_FAIL(tablet_to_ls_map.set_refactored(ls_id, tmp_tablet_ids, 1/*cover exist object*/))) { - LOG_WARN("[DATA_BACKUP]failed to set_refactored", K(ret), K(ls_id)); } else if (OB_FAIL(ls_id_set.exist_refactored(ls_id))) { if (OB_HASH_EXIST == ret) { ret = OB_SUCCESS; @@ -1194,15 +1399,16 @@ int ObBackupSetTaskMgr::do_get_change_turn_tablets_( } if (OB_FAIL(ret)) { } else { - ObHashMap>::hashtable::const_iterator map_iter = tablet_to_ls_map.begin(); + ObHashMap>::hashtable::const_iterator map_iter = tablet_to_ls_map.begin(); for (; OB_SUCC(ret) && map_iter != tablet_to_ls_map.end(); ++map_iter) { - share::ObBackupDataTabletToLSInfo ls_info; + storage::ObBackupDataTabletToLSInfo ls_info; ls_info.ls_id_ = map_iter->first; if (map_iter->second.empty()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]failed to get tablet to ls", K(ret), K(ls_info.ls_id_)); } else if (OB_FAIL(append(ls_info.tablet_id_list_, map_iter->second))) { LOG_WARN("[DATA_BACKUP]failed to append tablet to ls array", K(ret)); + } else if (OB_FALSE_IT(std::sort(ls_info.tablet_id_list_.begin(), ls_info.tablet_id_list_.end()))) { } else if (OB_FAIL(tablet_to_ls.push_back(ls_info))) { LOG_WARN("[DATA_BACKUP]failed to push backup ls info", K(ret)); } @@ -1223,78 +1429,6 @@ int ObBackupSetTaskMgr::do_get_change_turn_tablets_( return ret; } -int ObBackupSetTaskMgr::persist_deleted_tablets_info_(const common::ObIArray &skipped_tablets) -{ - int ret = OB_SUCCESS; - const int64_t MAX_BUCKET = 1024; - ObHashMap *> deleted_tablet_to_ls_map; - if (OB_FAIL(deleted_tablet_to_ls_map.create(MAX_BUCKET, ObModIds::BACKUP))) { - LOG_WARN("[DATA_BACKUP]failed to create map", K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < skipped_tablets.count(); ++i) { - const ObBackupSkipTabletAttr &skip_tablet = skipped_tablets.at(i); - const share::ObLSID &ls_id = skip_tablet.ls_id_; - ObArray *tablet_ids_ptr = NULL; - if (OB_FAIL(deleted_tablet_to_ls_map.get_refactored(ls_id, tablet_ids_ptr))) { - if (OB_HASH_NOT_EXIST == ret) { - ret = OB_SUCCESS; - if (OB_ISNULL(tablet_ids_ptr = OB_NEW(ObArray, ObModIds::BACKUP))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_ERROR("[DATA_BACKUP]failed to construct tablet id array", KR(ret)); - } else if (OB_FAIL(deleted_tablet_to_ls_map.set_refactored(ls_id, tablet_ids_ptr, 1/*overwrite*/))) { - LOG_WARN("[DATA_BACKUP]failed to set refactored", K(ret), K(ls_id), KP(tablet_ids_ptr)); - } - if (OB_FAIL(ret)) { - OB_DELETE(ObArray, ObModIds::BACKUP, tablet_ids_ptr); - } - } else { - LOG_WARN("[DATA_BACKUP]failed to get refactored", K(ret), K(skip_tablet)); - } - } - if (OB_FAIL(ret)) { - } else if (OB_ISNULL(tablet_ids_ptr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("[DATA_BACKUP]tmp tablet id array is null", K(ret)); - } else if (OB_FAIL(tablet_ids_ptr->push_back(skip_tablet.tablet_id_))) { - LOG_WARN("[DATA_BACKUP]failed to push back", K(ret), K(skip_tablet)); - } - } - } - if (OB_SUCC(ret)) { - ObBackupDeletedTabletToLSDesc deleted_tablet_to_ls; - ObHashMap *>::hashtable::const_iterator map_iter = deleted_tablet_to_ls_map.begin(); - for (; OB_SUCC(ret) && map_iter != deleted_tablet_to_ls_map.end(); ++map_iter) { - share::ObBackupDataTabletToLSInfo ls_info; - ls_info.ls_id_ = map_iter->first; - if (OB_ISNULL(map_iter->second)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("[DATA_BACKUP]map iter should not be null", K(ret), K(ls_info)); - } else if (map_iter->second->empty()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("[DATA_BACKUP]failed to get tablet to ls", K(ret), K(ls_info)); - } else if (OB_FAIL(append(ls_info.tablet_id_list_, *map_iter->second))) { - LOG_WARN("[DATA_BACKUP]failed to append tablet to ls array", K(ret)); - } else if (OB_FAIL(deleted_tablet_to_ls.deleted_tablet_to_ls_.push_back(ls_info))) { - LOG_WARN("[DATA_BACKUP]failed to push backup ls info", K(ret)); - } - } - if (FAILEDx(store_.write_deleted_tablet_info(deleted_tablet_to_ls))) { - LOG_WARN("[DATA_BACKUP]failed to write deleted tablet info", K(ret)); - } else { - LOG_INFO("write deleted tablet info", K(deleted_tablet_to_ls)); - } - } - if (deleted_tablet_to_ls_map.created()) { - ObHashMap *>::hashtable::iterator del_map_iter = deleted_tablet_to_ls_map.begin(); - for (; del_map_iter != deleted_tablet_to_ls_map.end(); ++del_map_iter) { - if (OB_NOT_NULL(del_map_iter->second)) { - OB_DELETE(ObArray, ObModIds::BACKUP, del_map_iter->second); - } - } - } - return ret; -} - int ObBackupSetTaskMgr::construct_cur_ls_set_( const ObIArray &ls_tasks, ObHashSet &ls_id_set) @@ -1312,17 +1446,12 @@ int ObBackupSetTaskMgr::construct_cur_ls_set_( return ret; } -int ObBackupSetTaskMgr::update_task_type_(const ObIArray &ls_tasks) +int ObBackupSetTaskMgr::convert_task_type_(const ObIArray &ls_tasks) { int ret = OB_SUCCESS; ObBackupDataTaskType type; - switch(set_task_attr_.status_.status_) { case ObBackupStatus::Status::BACKUP_USER_META: { - type.type_ = ObBackupDataTaskType::Type::BACKUP_DATA_SYS; - break; - } - case ObBackupStatus::Status::BACKUP_DATA_SYS: { type.type_ = ObBackupDataTaskType::Type::BACKUP_DATA_MINOR; break; } @@ -1337,6 +1466,7 @@ int ObBackupSetTaskMgr::update_task_type_(const ObIArray &ls default: break; } + // because of reusing the same ls task record at different stages of backup, // when changing task type, ls task need to reset some info. // 1. update ls task's task_type, turn_id, retry_id, status, and result. @@ -1344,21 +1474,42 @@ int ObBackupSetTaskMgr::update_task_type_(const ObIArray &ls // turn id is reset to the set_task_attr.data_turn_id, and retry_id is set to 0. for (int64_t i = 0; OB_SUCC(ret) && i < ls_tasks.count(); ++i) { const ObBackupLSTaskAttr &ls_task = ls_tasks.at(i); + ObBackupLSTaskAttr new_ls_task; if (ObBackupDataTaskType::Type::BACKUP_BUILD_INDEX == ls_task.task_type_.type_) { - } else if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret)); - } else if (OB_FAIL(ObBackupLSTaskOperator::update_task_type(trans_, ls_task, type))) { - LOG_WARN("[DATA_BACKUP]failed to update task type", K(ret), K(ls_task)); - } else if (type.is_backup_data()) { - share::ObBackupDataType backup_data_type; - if (OB_FAIL(type.get_backup_data_type(backup_data_type))) { - LOG_WARN("failed to get backup data type", K(ret), K(type)); - } else if (OB_FAIL(ObLSBackupOperator::insert_ls_backup_task_info(ls_task.tenant_id_, - ls_task.task_id_, set_task_attr_.data_turn_id_, 0/*retry_id*/, ls_task.ls_id_, ls_task.backup_set_id_, backup_data_type, trans_))) { - LOG_WARN("failed to insert ls backup task info", K(ret), K(ls_task), K(backup_data_type)); + } else if (OB_FAIL(new_ls_task.assign(ls_task))) { + LOG_WARN("failed to assign new ls task", K(ret)); + } else { + new_ls_task.task_type_ = type; + new_ls_task.status_ = ObBackupTaskStatus::INIT; + new_ls_task.result_ = OB_SUCCESS; + new_ls_task.dst_.reset(); + new_ls_task.task_trace_id_.reset(); + new_ls_task.retry_id_ = 0; + new_ls_task.turn_id_ = 1; + if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); + } else if (OB_FAIL(ObBackupLSTaskOperator::report_ls_task(trans_, new_ls_task))) { + LOG_WARN("failed to report ls task", K(ret)); + } else if (type.is_backup_data()) { + share::ObBackupDataType backup_data_type; + if (OB_FAIL(type.get_backup_data_type(backup_data_type))) { + LOG_WARN("failed to get backup data type", K(ret), K(type)); + } else if (OB_FAIL(ObLSBackupOperator::insert_ls_backup_task_info(new_ls_task.tenant_id_, + new_ls_task.task_id_, new_ls_task.turn_id_, new_ls_task.retry_id_, new_ls_task.ls_id_, + new_ls_task.backup_set_id_, backup_data_type, trans_))) { + LOG_WARN("failed to insert ls backup task info", K(ret), K(new_ls_task), K(backup_data_type)); + } + } + + if (OB_SUCC(ret)) { + LOG_INFO("succeed update ls task type", K(ls_task), K(new_ls_task)); } } } + + if (OB_SUCC(ret)) { + LOG_INFO("update ls task finish", K(type), K(set_task_attr_.task_id_), K(set_task_attr_.tenant_id_)); + } return ret; } @@ -1383,13 +1534,11 @@ int ObBackupSetTaskMgr::deal_failed_set_task(ObMySQLTransaction &trans) if (OB_FAIL(ret)) { } else { - next_status_.status_ = ObBackupStatus::Status::FAILED; + set_task_attr_.status_ = ObBackupStatus::Status::FAILED; set_task_attr_.end_ts_ = job_attr_->end_ts_; - if (OB_FAIL(enable_transfer_())) { - LOG_WARN("[DATA_BACKUP]failed to enable transfer", K(ret)); - } else if (OB_FAIL(set_backup_set_files_failed_(trans))) { + if (OB_FAIL(set_backup_set_files_failed_(trans))) { LOG_WARN("fail to set backup set files failed", K(ret)); - } else if (OB_FAIL(advance_status_(trans, next_status_, job_attr_->result_, set_task_attr_.end_scn_, + } else if (OB_FAIL(advance_status_(trans, set_task_attr_.status_, job_attr_->result_, set_task_attr_.end_scn_, job_attr_->end_ts_))) { LOG_WARN("[DATA_BACKUP]failed to advance set task status to FAILED", K(ret), K(set_task_attr_), "failed job result", job_attr_->result_); @@ -1401,21 +1550,20 @@ int ObBackupSetTaskMgr::deal_failed_set_task(ObMySQLTransaction &trans) return ret; } -bool ObBackupSetTaskMgr::is_force_cancel() const -{ - return ObBackupStatus::CANCELING == set_task_attr_.status_.status_; -} - int ObBackupSetTaskMgr::do_failed_ls_task_(ObMySQLTransaction &trans, const ObIArray &ls_task) { int ret = OB_SUCCESS; - ObBackupTaskStatus next_status; - next_status.status_ = ObBackupTaskStatus::Status::FINISH; for (int64_t i = 0; OB_SUCC(ret) && i < ls_task.count(); ++i) { const ObBackupLSTaskAttr &ls_attr = ls_task.at(i); - if (OB_FAIL(ObBackupDataLSTaskMgr::advance_status( - *lease_service_, trans, ls_attr, next_status, ls_attr.result_, job_attr_->end_ts_))) { - LOG_WARN("[DATA_BACKUP]failed to advance ls task status", K(ret), K(ls_attr), K(next_status)); + ObBackupLSTaskAttr new_ls_attr; + if (OB_FAIL(new_ls_attr.assign(ls_attr))) { + LOG_WARN("failed to assign ls attr", K(ret)); + } else { + new_ls_attr.status_ = ObBackupTaskStatus::FINISH; + new_ls_attr.end_ts_ = job_attr_->end_ts_; + if (OB_FAIL(ObBackupLSTaskOperator::report_ls_task(trans, new_ls_attr))) { + LOG_WARN("failed to report ls task", K(ret)); + } } } return ret; @@ -1431,7 +1579,7 @@ int ObBackupSetTaskMgr::backup_completing_log_() LOG_WARN("[DATA_BACKUP]failed to get log stream tasks", K(ret), "job_id", job_attr_->job_id_, "tenant_id", job_attr_->tenant_id_); } else if (ls_task.empty()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("[DATA_BACKUP]no lostream task", K(ret), K(ls_task)); + LOG_WARN("[DATA_BACKUP]no logstream task", K(ret), K(ls_task)); } else if (job_attr_->plus_archivelog_) { if (OB_FAIL(ObTenantArchiveMgr::get_tenant_current_round(job_attr_->tenant_id_, job_attr_->incarnation_id_, round_attr))) { LOG_WARN("[DATA_BACKUP]failed to get tenant current round", K(ret)); @@ -1451,20 +1599,21 @@ int ObBackupSetTaskMgr::backup_completing_log_() } if (OB_SUCC(ret) && ls_task.count() == finish_cnt) { - next_status_.status_ = ObBackupStatus::Status::COMPLETED; + ObBackupStatus next_status = ObBackupStatus::COMPLETED; set_task_attr_.end_ts_ = ObTimeUtility::current_time(); - if (OB_FAIL(write_extern_infos())) { + if (OB_FAIL(write_extern_infos_())) { LOG_WARN("fail to write_extern_infos", K(ret), K(set_task_attr_)); } else if (OB_FAIL(trans_.start(sql_proxy_, meta_tenant_id_))) { LOG_WARN("fail to start trans", K(ret), K(meta_tenant_id_)); } else { - if (OB_FAIL(advance_status_(trans_, next_status_, OB_SUCCESS, set_task_attr_.end_scn_, set_task_attr_.end_ts_))) { + if (OB_FAIL(advance_status_(trans_, next_status, OB_SUCCESS, set_task_attr_.end_scn_, set_task_attr_.end_ts_))) { LOG_WARN("fail to advance status to COMPLETED", K(ret), K(set_task_attr_)); } if (OB_SUCC(ret)) { if (OB_FAIL(trans_.end(true))) { LOG_WARN("fail to commit trans", KR(ret)); } else { + set_task_attr_.status_ = next_status; ROOTSERVICE_EVENT_ADD("backup_data", "backup completing log succeed", "tenant_id", job_attr_->tenant_id_, "job_id", job_attr_->job_id_, "task_id", set_task_attr_.task_id_); LOG_INFO("backup completing log succeed", "tenant_id", job_attr_->tenant_id_, "job_id", job_attr_->job_id_, @@ -1493,8 +1642,7 @@ int ObBackupSetTaskMgr::do_backup_completing_log_(ObArray &l for (int64_t i = 0; OB_SUCC(ret) && i < ls_task.count(); ++i) { ObBackupLSTaskAttr &ls_attr = ls_task.at(i); ObBackupDataLSTaskMgr ls_task_mgr; - if (OB_FAIL(ls_task_mgr.init(*job_attr_, set_task_attr_, ls_attr, *task_scheduler_, *sql_proxy_, *lease_service_, - *backup_service_))) { + if (OB_FAIL(ls_task_mgr.init(*job_attr_, set_task_attr_, ls_attr, *task_scheduler_, *sql_proxy_, *backup_service_))) { LOG_WARN("[DATA_BACKUP]failed to init task advancer", K(ret), K(ls_attr)); } else if (OB_FAIL(ls_task_mgr.process(finish_cnt))) { LOG_WARN("[DATA_BACKUP]failed to process log stream task", K(ret), K(ls_attr)); @@ -1507,22 +1655,20 @@ int ObBackupSetTaskMgr::do_backup_completing_log_(ObArray &l int ObBackupSetTaskMgr::do_clean_up(ObMySQLTransaction &trans) { int ret = OB_SUCCESS; - ObBackupSkippedType skipped_type(ObBackupSkippedType::DELETED); if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("[DATA_BACKUP]not init", K(ret)); - } else if (OB_FAIL(lease_service_->check_lease())) { + } else if (OB_FAIL(backup_service_->check_leader())) { LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret)); } else if (OB_FAIL(ObBackupLSTaskInfoOperator::move_ls_task_info_to_his(trans, set_task_attr_.task_id_, set_task_attr_.tenant_id_))) { LOG_WARN("[DATA_BACKUP]failed to move task to history", K(ret), K(set_task_attr_)); + } else if (OB_FAIL(ObBackupSkippedTabletOperator::move_skip_tablet_to_his(trans, set_task_attr_.tenant_id_, set_task_attr_.task_id_))) { + LOG_WARN("[DATA_BACKUP]failed to move skip tablet to history", K(ret)); } else if (OB_FAIL(ObBackupLSTaskOperator::move_ls_to_his(trans, set_task_attr_.tenant_id_, set_task_attr_.job_id_))) { LOG_WARN("[DATA_BACKUP]failed to move ls to history", K(ret), K(set_task_attr_)); } else if (OB_FAIL(ObBackupTaskOperator::move_task_to_his(trans, set_task_attr_.tenant_id_, set_task_attr_.job_id_))) { LOG_WARN("[DATA_BACKUP]failed to move task to history", K(ret), K(set_task_attr_)); - } else if (OB_FAIL(ObBackupSkippedTabletOperator::move_skip_tablet_to_his( - trans, set_task_attr_.tenant_id_, set_task_attr_.task_id_, skipped_type))) { - LOG_WARN("[DATA_BACKUP]failed to move skip tablet to history", K(ret), K(set_task_attr_)); } return ret; } @@ -1543,7 +1689,7 @@ int ObBackupSetTaskMgr::do_cancel_() for (int64_t i = 0; OB_SUCC(ret) && i < ls_task.count(); ++i) { ObBackupDataLSTaskMgr task_mgr; ObBackupLSTaskAttr ls_attr = ls_task.at(i); - if (OB_FAIL(task_mgr.init(*job_attr_, set_task_attr_, ls_attr, *task_scheduler_, *sql_proxy_, *lease_service_, *backup_service_))) { + if (OB_FAIL(task_mgr.init(*job_attr_, set_task_attr_, ls_attr, *task_scheduler_, *sql_proxy_, *backup_service_))) { LOG_WARN("[DATA_BACKUP]failed to init task mgr", K(ret), K(ls_attr)); } else if (OB_FAIL(task_mgr.cancel(finish_cnt))) { LOG_WARN("[DATA_BACKUP]failed to cancel task", K(ret), K(ls_attr), K(set_task_attr_)); @@ -1551,26 +1697,25 @@ int ObBackupSetTaskMgr::do_cancel_() } } if (OB_SUCC(ret) && ls_task.count() == finish_cnt) { - next_status_.status_ = ObBackupStatus::Status::CANCELED; + ObBackupStatus next_status = ObBackupStatus::Status::CANCELED; set_task_attr_.end_ts_ = ObTimeUtility::current_time(); - if (!is_force_cancel() && OB_FAIL(write_extern_infos())) { - LOG_WARN("[DATA_BACKUP]failed to write extern infos", K(ret), K(set_task_attr_)); - } else if (OB_FAIL(trans_.start(sql_proxy_, meta_tenant_id_))) { + if (OB_FAIL(trans_.start(sql_proxy_, meta_tenant_id_))) { LOG_WARN("fail to start trans", K(ret), K(meta_tenant_id_)); } else { if (OB_FAIL(set_backup_set_files_failed_(trans_))) { LOG_WARN("failed to set backup set files failed", K(ret)); - } else if (OB_FAIL(advance_status_(trans_, next_status_, OB_CANCELED, set_task_attr_.end_scn_, set_task_attr_.end_ts_))) { + } else if (OB_FAIL(advance_status_( + trans_, next_status, OB_CANCELED, set_task_attr_.end_scn_, set_task_attr_.end_ts_))) { LOG_WARN("[DATA_BACKUP]failed to advance set task status to CANCELED", K(ret), K(set_task_attr_)); - } else { - FLOG_INFO("[DATA_BACKUP]advance set status success", K(next_status_)); } if (OB_SUCC(ret)) { if (OB_FAIL(trans_.end(true))) { LOG_WARN("fail to commit trans", KR(ret)); } else { + set_task_attr_.status_ = next_status; ROOTSERVICE_EVENT_ADD("backup_data", "cancel backup succeed", "tenant_id", job_attr_->tenant_id_, "job_id", job_attr_->job_id_, "task_id", set_task_attr_.task_id_); + FLOG_INFO("[DATA_BACKUP]advance status to CANCELED", K(set_task_attr_)); backup_service_->wakeup(); } } else { @@ -1585,7 +1730,7 @@ int ObBackupSetTaskMgr::do_cancel_() } -int ObBackupSetTaskMgr::write_extern_infos() +int ObBackupSetTaskMgr::write_extern_infos_() { int ret = OB_SUCCESS; HEAP_VARS_2((ObExternTenantLocalityInfoDesc, locality_info), @@ -1601,10 +1746,8 @@ int ObBackupSetTaskMgr::write_extern_infos() LOG_WARN("[DATA_BACKUP]failed to write tenant backup set infos", K(ret)); } else if (OB_FAIL(write_extern_diagnose_info_(locality_info, backup_set_info))) { // LOG_WARN("[DATA_BACKUP]failed to write extern tenant diagnose info", K(ret), KPC(job_attr_)); - } else if (OB_FAIL(write_backup_set_placeholder(false/*finish job*/))) { + } else if (OB_FAIL(write_backup_set_placeholder_(false/*finish job*/))) { LOG_WARN("[DATA_BACKUP]failed to write backup set finish placeholder", K(ret), KPC(job_attr_)); - } else if (OB_FAIL(write_deleted_tablet_infos_())) { - LOG_WARN("[DATA_BACKUP]failed to write deleted tablet infos", K(ret), KPC(job_attr_)); } } return ret; @@ -1671,6 +1814,7 @@ int ObBackupSetTaskMgr::write_backup_set_info_( int64_t dest_id = 0; ObBackupSetFileDesc &backup_set_file = backup_set_info.backup_set_file_; ObBackupDest backup_dest; + uint64_t cur_data_version = 0; uint64_t cur_cluster_version = 0; if (OB_FAIL(ObShareUtil::fetch_current_data_version(*sql_proxy_, job_attr_->tenant_id_, cur_data_version))) { @@ -1706,6 +1850,8 @@ int ObBackupSetTaskMgr::write_backup_set_info_( ObBackupFileStatus::BACKUP_FILE_AVAILABLE : ObBackupFileStatus::BACKUP_FILE_BROKEN; backup_set_file.data_turn_id_ = set_task_attr.data_turn_id_; backup_set_file.meta_turn_id_ = set_task_attr.meta_turn_id_; + backup_set_file.minor_turn_id_ = set_task_attr.minor_turn_id_; + backup_set_file.major_turn_id_ = set_task_attr.major_turn_id_; backup_set_file.min_restore_scn_ = set_task_attr.end_scn_; if (OB_FAIL(calculate_start_replay_scn_(backup_set_file.start_replay_scn_))) { LOG_WARN("fail to calculate start replay scn", K(ret)); @@ -1715,34 +1861,18 @@ int ObBackupSetTaskMgr::write_backup_set_info_( } if (OB_FAIL(ret)) { - } else if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("[DATA_BACKUP]failed to check lease", K(ret)); + } else if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("[DATA_BACKUP]failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupSetFileOperator::update_backup_set_file(*sql_proxy_, backup_set_info.backup_set_file_))) { LOG_WARN("[DATA_BACKUP]failed to update backup set", K(ret), K(backup_set_info)); } return ret; } -int ObBackupSetTaskMgr::write_deleted_tablet_infos_() -{ - int ret = OB_SUCCESS; - ObArray tablet_attrs; - ObBackupSkippedType skipped_type(ObBackupSkippedType::DELETED); - if (OB_FAIL(ObBackupSkippedTabletOperator::get_skip_tablet(*sql_proxy_, false/*lock*/, - set_task_attr_.tenant_id_, set_task_attr_.task_id_, skipped_type, tablet_attrs))) { - LOG_WARN("[DATA_BACKUP]failed to get skip tablet", K(ret), "teannt_id", set_task_attr_.tenant_id_, "task_id", set_task_attr_.task_id_); - } else if (tablet_attrs.empty()) { - LOG_INFO("[DATA_BACKUP]no change turn tablets found", K(ret)); - } else if (OB_FAIL(persist_deleted_tablets_info_(tablet_attrs))) { - LOG_WARN("[DATA_BACKUP]failed to do persist deleted tablets info", K(ret), K(tablet_attrs), K(set_task_attr_)); - } - return ret; -} - int ObBackupSetTaskMgr::calculate_start_replay_scn_(SCN &start_replay_scn) { int ret = OB_SUCCESS; - ObBackupLSMetaInfosDesc ls_meta_infos; + storage::ObBackupLSMetaInfosDesc ls_meta_infos; ObTenantArchiveRoundAttr round_attr; if (OB_FAIL(ObTenantArchiveMgr::get_tenant_current_round(job_attr_->tenant_id_, job_attr_->incarnation_id_, round_attr))) { LOG_WARN("failed to get tenant current round", K(ret), KPC(job_attr_)); @@ -1754,7 +1884,7 @@ int ObBackupSetTaskMgr::calculate_start_replay_scn_(SCN &start_replay_scn) LOG_WARN("backup is not supported when archive is interrupted", K(ret), K(round_attr), K(set_task_attr_.start_scn_)); } else if (OB_FAIL(store_.read_ls_meta_infos(ls_meta_infos))) { LOG_WARN("fail to read ls meta infos", K(ret)); - } else if (OB_FAIL(ObBackupUtils::calc_start_replay_scn(set_task_attr_, ls_meta_infos, round_attr, start_replay_scn))) { + } else if (OB_FAIL(backup::ObBackupUtils::calc_start_replay_scn(set_task_attr_, ls_meta_infos, round_attr, start_replay_scn))) { LOG_WARN("failed to calc start replay scn", K(ret), K_(set_task_attr), K(ls_meta_infos), K(round_attr)); } return ret; @@ -1765,6 +1895,7 @@ int ObBackupSetTaskMgr::write_extern_locality_info_(ObExternTenantLocalityInfoDe int ret = OB_SUCCESS; ObSchemaGetterGuard schema_guard; const ObTenantSchema *tenant_info = NULL; + const ObSysVarSchema *var_schema = nullptr; if (OB_FAIL(schema_service_->get_tenant_schema_guard(job_attr_->tenant_id_, schema_guard))) { LOG_WARN("[DATA_BACKUP]failed to get_tenant_schema_guard", KR(ret), "tenant_id", job_attr_->tenant_id_); } else if (OB_FAIL(schema_guard.get_tenant_info(job_attr_->tenant_id_, tenant_info))) { @@ -1777,6 +1908,10 @@ int ObBackupSetTaskMgr::write_extern_locality_info_(ObExternTenantLocalityInfoDe LOG_WARN("[DATA_BACKUP]failed to assign primary zone", K(ret), K(tenant_info)); } else if (OB_FAIL(locality_info.cluster_name_.assign(GCONF.cluster))) { LOG_WARN("fail to assign cluster name", K(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_system_variable(job_attr_->tenant_id_, share::SYS_VAR_SYSTEM_TIME_ZONE, var_schema))) { + LOG_WARN("fail to get tenant system variable", K(ret)); + } else if (OB_FAIL(locality_info.sys_time_zone_.assign(var_schema->get_value()))) { + LOG_WARN("fail to assign time zone", K(ret), KPC(var_schema)); } else { locality_info.tenant_id_ = job_attr_->tenant_id_; locality_info.backup_set_id_ = job_attr_->backup_set_id_; @@ -1812,7 +1947,7 @@ int ObBackupSetTaskMgr::write_extern_diagnose_info_( return ret; } -int ObBackupSetTaskMgr::write_backup_set_placeholder(const bool is_start) +int ObBackupSetTaskMgr::write_backup_set_placeholder_(const bool is_start) { int ret = OB_SUCCESS; SCN start_replay_scn = job_attr_->plus_archivelog_ ? set_task_attr_.end_scn_ : set_task_attr_.start_scn_; @@ -1835,8 +1970,8 @@ int ObBackupSetTaskMgr::write_backup_set_placeholder(const bool is_start) int ObBackupSetTaskMgr::write_tenant_backup_set_infos_() { int ret = OB_SUCCESS; - share::ObTenantBackupSetInfosDesc tenant_backup_set_infos; - if (OB_FAIL(ObBackupSetFileOperator::get_backup_set_files(*sql_proxy_, job_attr_->tenant_id_, tenant_backup_set_infos))) { + storage::ObTenantBackupSetInfosDesc tenant_backup_set_infos; + if (OB_FAIL(ObBackupSetFileOperator::get_backup_set_files(*sql_proxy_, job_attr_->tenant_id_, tenant_backup_set_infos.backup_set_infos_))) { LOG_WARN("[DATA_BACKUP]failed to get backup set", K(ret), KPC(job_attr_)); } else if (!tenant_backup_set_infos.is_valid()) { ret = OB_ERR_UNEXPECTED; @@ -1847,11 +1982,6 @@ int ObBackupSetTaskMgr::write_tenant_backup_set_infos_() return ret; } -bool ObBackupSetTaskMgr::can_write_extern_infos(const int err) const -{ - return !is_force_cancel() && err != OB_BACKUP_DEVICE_OUT_OF_SPACE && err != OB_IO_ERROR; -} - int ObBackupSetTaskMgr::set_backup_set_files_failed_(ObMySQLTransaction &trans) { int ret = OB_SUCCESS; @@ -1878,8 +2008,8 @@ int ObBackupSetTaskMgr::set_backup_set_files_failed_(ObMySQLTransaction &trans) backup_set_file.data_turn_id_ = set_task_attr_.data_turn_id_; backup_set_file.meta_turn_id_ = set_task_attr_.meta_turn_id_; backup_set_file.min_restore_scn_ = set_task_attr_.end_scn_; - if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("failed to check lease", K(ret)); + if (OB_FAIL(backup_service_->check_leader())) { + LOG_WARN("failed to check leader", K(ret)); } else if (OB_FAIL(ObBackupSetFileOperator::update_backup_set_file(trans, backup_set_file))) { LOG_WARN("failed to update backup set", K(ret), K(backup_set_file)); } diff --git a/src/rootserver/backup/ob_backup_data_set_task_mgr.h b/src/rootserver/backup/ob_backup_data_set_task_mgr.h index e352ada29..7b153eaca 100644 --- a/src/rootserver/backup/ob_backup_data_set_task_mgr.h +++ b/src/rootserver/backup/ob_backup_data_set_task_mgr.h @@ -17,6 +17,15 @@ namespace oceanbase { +namespace share +{ +class ObAllTenantInfo; +struct ObBackupDataLSAttrDesc; +} +namespace storage +{ +class ObTabletMeta; +} namespace rootserver { @@ -31,86 +40,76 @@ public: common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, ObBackupTaskScheduler &task_scheduler, - ObBackupLeaseService &lease_service, ObMultiVersionSchemaService &schema_service, - ObBackupService &backup_service); + ObBackupDataService &backup_service); int process(); int do_clean_up(ObMySQLTransaction &trans); int deal_failed_set_task(ObMySQLTransaction &trans); - bool is_force_cancel() const; - bool can_write_extern_infos(const int err) const; - int write_extern_infos(); - int write_backup_set_placeholder(const bool is_start); - share::ObBackupStatus::Status get_status() const { return next_status_.status_; } + share::ObBackupStatus::Status get_status() const { return set_task_attr_.status_.status_; } TO_STRING_KV(K_(meta_tenant_id), K_(set_task_attr)); private: int persist_sys_ls_task_(); int do_persist_sys_ls_task_(); - int persist_ls_attr_info_(ObIArray &ls_ids); + int persist_ls_attr_info_(const share::ObBackupLSTaskAttr &sys_ls_task, ObIArray &ls_ids); + int sync_wait_backup_user_ls_scn_(const share::ObBackupLSTaskAttr &sys_ls_task, share::SCN &scn); int generate_ls_tasks_(const ObIArray &ls_ids, const share::ObBackupDataTaskType &type); - + int calc_task_turn_(const ObBackupDataTaskType &type, int64_t &turn_id); int backup_sys_meta_(); + int do_backup_meta_(ObIArray &ls_task, int64_t &finish_cnt); int backup_user_meta_(); - int change_meta_turn_(); - // TODO: need the enbale/disable transfer - int disable_transfer_(); - int enable_transfer_(); - int do_backup_meta_(ObArray &ls_task, int64_t &finish_cnt); - int do_backup_root_key_(); - int merge_tablet_to_ls_info_(const ObIArray &ls_tasks); - int construct_ls_task_map_(const ObIArray &ls_tasks, - hash::ObHashMap &ls_map); - int get_extern_tablet_info_(const share::ObLSID &ls_id, const int64_t &retry_cnt, - share::ObBackupDataTabletToLSInfo &tablet_to_ls_info, share::SCN &backup_scn); - int check_tablets_match_(const share::ObLSID &ls_id, const ObIArray &cur_tablet_ids, - const ObIArray &user_tablet_ids, const share::SCN &backup_scn); - int do_check_inc_tablets_(const share::ObLSID &ls_id, const ObIArray &inc_tablets, - const share::SCN &backup_scn); - int get_dst_server_(const share::ObLSID &ls_id, ObAddr &dst); + int check_need_change_meta_turn_(ObIArray &ls_tasks, bool &need_change_turn); + int change_meta_turn_(const share::ObBackupLSTaskAttr &sys_ls_task); + int get_backup_user_meta_task_(ObIArray &ls_task); + int merge_tablet_to_ls_info_(const share::SCN &consistent_scn, const ObIArray &ls_tasks); + int get_tablet_list_by_snapshot( + const share::SCN &consistent_scn, common::hash::ObHashMap> &latest_ls_tablet_map); + int fill_map_with_sys_tablets_(common::hash::ObHashMap> &latest_ls_tablet_map); + int update_tablet_id_backup_scn_(const share::SCN &backup_scn); + int get_extern_tablet_info_(const share::ObLSID &ls_id, + ObIArray &user_tablet_ids, share::SCN &backup_scn); int merge_ls_meta_infos_(const ObIArray &ls_tasks); - + int do_backup_root_key_(); int backup_data_(); int do_backup_data_(ObArray &ls_task, int64_t &finish_cnt, share::ObBackupLSTaskAttr *& build_index_attr); - int build_index_(share::ObBackupLSTaskAttr *build_index_attr, const int64_t turn_id, const int64_t task_id, - bool &finish_build_index); + int build_index_(share::ObBackupLSTaskAttr *build_index_attr, bool &finish_build_index); int check_change_task_turn_(const ObIArray &ls_tasks, bool &need_change_turn, - ObIArray &tablets_to_ls, ObIArray &new_ls_array); + ObIArray &tablets_to_ls, ObIArray &new_ls_array); int change_task_turn_(ObIArray &ls_task, - ObIArray &tablets_to_ls, ObIArray &new_ls_array); + ObIArray &tablets_to_ls, ObIArray &new_ls_array); + int get_next_turn_id_(int64_t &next_turn_id); int get_change_turn_tablets_(const ObIArray &ls_tasks, - ObIArray &tablet_to_ls, ObIArray &new_ls_ids); + ObIArray &tablet_to_ls, ObIArray &new_ls_ids); + int get_tablets_of_deleted_ls_( + const ObIArray &ls_tasks, common::hash::ObHashSet &skip_tablets); int do_get_change_turn_tablets_(const ObIArray &ls_tasks, - const ObIArray &all_tablets, - ObIArray &tablet_to_ls, ObIArray &new_ls_ids); + const common::hash::ObHashSet &skip_tablets, + ObIArray &tablet_to_ls, ObIArray &new_ls_ids); int construct_cur_ls_set_(const ObIArray &ls_tasks, common::hash::ObHashSet &ls_id_set); int get_change_turn_ls_(ObIArray &ls_task, - const ObIArray &tablets_to_ls, + const ObIArray &tablets_to_ls, ObIArray &need_change_turn_ls_tasks); - int persist_deleted_tablets_info_(const common::ObIArray &skip_tablets); int update_inner_task_(const ObIArray &new_ls_ids, const ObIArray &need_change_turn_ls_tasks); - int update_task_type_(const ObIArray &ls_task); - + int convert_task_type_(const ObIArray &ls_task); int backup_completing_log_(); int do_backup_completing_log_(ObArray &ls_task, int64_t &finish_cnt); int calculate_start_replay_scn_(share::SCN &start_replay_scn); - int do_cancel_(); - int do_failed_ls_task_(ObMySQLTransaction &trans, const ObIArray &ls_task); + int write_backup_set_placeholder_(const bool is_start); + int write_extern_infos_(); int write_tenant_backup_set_infos_(); - int write_extern_locality_info_(share::ObExternTenantLocalityInfoDesc &locality_info); + int write_extern_locality_info_(storage::ObExternTenantLocalityInfoDesc &locality_info); int write_backup_set_info_(const share::ObBackupSetTaskAttr &set_task_attr, - share::ObExternBackupSetInfoDesc &backup_set_info); - int write_extern_diagnose_info_(const share::ObExternTenantLocalityInfoDesc &locality_info, - const share::ObExternBackupSetInfoDesc &backup_set_info); + storage::ObExternBackupSetInfoDesc &backup_set_info); + int write_extern_diagnose_info_(const storage::ObExternTenantLocalityInfoDesc &locality_info, + const storage::ObExternBackupSetInfoDesc &backup_set_info); int write_log_format_file_(); int write_extern_ls_info_(const ObArray &ls_tasks); - int write_tablet_to_ls_infos_(const ObIArray &tablets_to_ls, const int64_t turn_id); - int write_deleted_tablet_infos_(); + int write_tablet_to_ls_infos_(const ObIArray &tablets_to_ls); int set_backup_set_files_failed_(ObMySQLTransaction &trans); int advance_status_(ObMySQLTransaction &trans, const share::ObBackupStatus &next_status, const int result = OB_SUCCESS, @@ -119,16 +118,14 @@ private: private: bool is_inited_; uint64_t meta_tenant_id_; - share::ObBackupStatus next_status_; share::ObBackupSetTaskAttr set_task_attr_; share::ObBackupJobAttr *job_attr_; common::ObMySQLProxy *sql_proxy_; obrpc::ObSrvRpcProxy *rpc_proxy_; - ObBackupLeaseService *lease_service_; ObBackupTaskScheduler *task_scheduler_; ObMultiVersionSchemaService *schema_service_; - ObBackupService *backup_service_; - share::ObBackupDataStore store_; + ObBackupDataService *backup_service_; + storage::ObBackupDataStore store_; ObMySQLTransaction trans_; DISALLOW_COPY_AND_ASSIGN(ObBackupSetTaskMgr); }; diff --git a/src/rootserver/backup/ob_backup_lease_service.cpp b/src/rootserver/backup/ob_backup_lease_service.cpp deleted file mode 100644 index 6e54dc897..000000000 --- a/src/rootserver/backup/ob_backup_lease_service.cpp +++ /dev/null @@ -1,512 +0,0 @@ -/** - * Copyright (c) 2021 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. - */ - -#define USING_LOG_PREFIX RS -#include "ob_backup_lease_service.h" -#include "lib/thread/ob_thread_name.h" -#include "share/backup/ob_backup_manager.h" -#include "rootserver/ob_rs_reentrant_thread.h" -#include "rootserver/ob_rs_event_history_table_operator.h" -#include "rootserver/ob_i_backup_scheduler.h" -#include "share/backup/ob_backup_operator.h" -#include "share/backup/ob_log_archive_backup_info_mgr.h" -#include "rootserver/backup/ob_backup_service.h" - -using namespace oceanbase; -using namespace common; -using namespace share; -using namespace obrpc; -using namespace rootserver; - -ObBackupLeaseService::ObBackupLeaseService() - : is_inited_(false), - can_be_leader_ts_(0), - expect_round_(0), - lock_(common::ObLatchIds::BACKUP_LOCK), - backup_lease_info_mgr_(), - lease_info_(), - sql_proxy_(nullptr), - backup_service_(nullptr), - idle_(has_set_stop()), - local_addr_() -{ -} - -ObBackupLeaseService::~ObBackupLeaseService() -{ -} - -int ObBackupLeaseService::init( - const ObAddr &addr, - ObMySQLProxy &sql_proxy) -{ - int ret = OB_SUCCESS; - SpinWLockGuard guard(lock_); - - if (is_inited_) { - ret = OB_INIT_TWICE; - LOG_WARN("cannot init twice", K(ret)); - } else if (OB_FAIL(backup_lease_info_mgr_.init(addr, sql_proxy))) { - LOG_WARN("failed to init backup_lease_info_mgr", K(ret)); - } else { - is_inited_ = true; - can_be_leader_ts_ = 0; - expect_round_ = 0; - lease_info_.reset(); - sql_proxy_ = &sql_proxy; - local_addr_ = addr; - } - - return ret; -} - -int ObBackupLeaseService::register_scheduler(ObIBackupScheduler &scheduler) -{ - int ret = OB_SUCCESS; - SpinWLockGuard guard(lock_); - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(backup_schedulers_.push_back(&scheduler))) { - LOG_WARN("failed to add scheduler", K(ret)); - } - return ret; -} - -int ObBackupLeaseService::register_mgr(ObBackupService &backup_service) -{ - int ret = OB_SUCCESS; - SpinWLockGuard guard(lock_); - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else { - backup_service_ = &backup_service; - } - return ret; -} - -int ObBackupLeaseService::start_lease() -{ - int ret = OB_SUCCESS; - { - SpinRLockGuard guard(lock_); - int64_t expect_round = expect_round_ + 1; - ROOTSERVICE_EVENT_ADD("backup_lease", "start backup lease", K_(local_addr), K(expect_round)); - } - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else { - SpinWLockGuard guard(lock_); - ++expect_round_; - can_be_leader_ts_ = ObTimeUtil::current_time(); - FLOG_INFO("start backup lease service", K(*this)); - } - wakeup(); - return ret; -} - -int ObBackupLeaseService::stop_lease() -{ - int ret = OB_SUCCESS; - - { - SpinRLockGuard guard(lock_); - int64_t expect_round = expect_round_ + 1; - - ROOTSERVICE_EVENT_ADD("backup_lease", "stop backup lease", K_(local_addr), K(expect_round)); - } - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else { - SpinWLockGuard guard(lock_); - stop_backup_scheduler_(); - stop_backup_service_(); - ++expect_round_; - can_be_leader_ts_ = 0; - FLOG_INFO("stop backup lease service", K(*this)); - } - wakeup(); - return ret; -} - -void ObBackupLeaseService::wait_lease() -{ - // do nothing -} - -int ObBackupLeaseService::start() -{ - return lib::ThreadPool::start(); -} - -void ObBackupLeaseService::stop() -{ - lib::ThreadPool::stop(); - idle_.wakeup(); -} - -void ObBackupLeaseService::wakeup() -{ - idle_.wakeup(); -} - -void ObBackupLeaseService::destroy() -{ - const int64_t start_ts = ObTimeUtil::current_time(); - - LOG_INFO("start destroy ObBackupLeaseService"); - stop_lease(); - wait_backup_scheduler_stop_(); - wait_mgr_stop_(); - stop(); - backup_schedulers_.destroy(); - wait(); - lib::ThreadPool::destroy(); - const int64_t cost_ts = ObTimeUtil::current_time() - start_ts; - LOG_INFO("finish destroy ObBackupLeaseService", K(cost_ts)); -} - -int ObBackupLeaseService::check_lease() -{ - int ret = OB_SUCCESS; - bool is_lease_valid = false; - if (OB_FAIL(get_lease_status(is_lease_valid))) { - LOG_WARN("failed to get lease status", K(ret)); - } else if (!is_lease_valid) { - ret = OB_LEASE_NOT_ENOUGH; - LOG_WARN("not own lease, cannot do work", K(ret)); - } - return ret; -} - -int ObBackupLeaseService::get_lease_status(bool &is_lease_valid) -{ - int ret = OB_SUCCESS; - is_lease_valid = false; - SpinRLockGuard guard(lock_); - const int64_t cur_ts = ObTimeUtil::current_time(); - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (expect_round_ != lease_info_.round_ || !can_be_leader_()) { - is_lease_valid = false; - LOG_WARN("not own lease, because round not match", K(*this)); - } else if (cur_ts - lease_info_.lease_start_ts_ >= ObBackupLeaseInfo::MAX_LEASE_TIME) { - is_lease_valid = false; - LOG_WARN("not own lease, because lease time not match", K(lease_info_)); - } else if (!lease_info_.is_leader_) { - is_lease_valid = false; - LOG_WARN("not own lease, because not leader now", K(lease_info_)); - } else { - is_lease_valid = true; - } - - return ret; -} - -int64_t ObBackupLeaseService::get_lease_version() const { - return lease_info_.lease_epoch_; -} - -int ObBackupLeaseService::start_backup_scheduler_() -{ - int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - FLOG_INFO("[BACKUP_LEASE] start_backup_scheduler"); - for (int64_t i = 0; i < backup_schedulers_.count(); ++i) { - ObIBackupScheduler *scheduler = backup_schedulers_.at(i); - FLOG_INFO("[BACKUP_LEASE] start scheduler", "name", scheduler->get_thread_name()); - if (OB_SUCCESS != (tmp_ret = scheduler->start())) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_ERROR("failed to start scheduler", K(tmp_ret), K(ret), "name", scheduler->get_thread_name()); - } - } - return ret; -} - -int ObBackupLeaseService::start_backup_service_() -{ - int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - FLOG_INFO("[BACKUP_LEASE] start backup mgr", "name", backup_service_->get_thread_name()); - backup_service_->disable_backup(); - if (OB_SUCCESS != (tmp_ret = backup_service_->start())) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_ERROR("failed to start backup mgr", K(tmp_ret), K(ret), "name", backup_service_->get_thread_name()); - } - return ret; -} - -void ObBackupLeaseService::stop_backup_scheduler_() -{ - FLOG_INFO("[BACKUP_LEASE] stop_backup_scheduler"); - for (int64_t i = 0; i < backup_schedulers_.count(); ++i) { - ObIBackupScheduler *scheduler = backup_schedulers_.at(i); - FLOG_INFO("[BACKUP_LEASE] stop scheduler", "name", scheduler->get_thread_name()); - scheduler->stop(); - } -} - -void ObBackupLeaseService::stop_backup_service_() -{ - FLOG_INFO("[BACKUP_LEASE] stop backup_mgr", "name", backup_service_->get_thread_name()); - backup_service_->stop(); -} - -void ObBackupLeaseService::wait_backup_scheduler_stop_() -{ - int64_t start_ts = ObTimeUtil::current_time(); - FLOG_INFO("[BACKUP_LEASE] start wait_backup_scheduler_stop_"); - for (int64_t i = 0; i < backup_schedulers_.count(); ++i) { - ObIBackupScheduler *scheduler = backup_schedulers_.at(i); - FLOG_INFO("[BACKUP_LEASE] waiting scheduler stop", - "name", scheduler->get_thread_name(), KP(scheduler)); - int64_t start_ts2 = ObTimeUtil::current_time(); - scheduler->wait(); - int64_t cost_ts2 = ObTimeUtil::current_time() - start_ts2; - FLOG_INFO("[BACKUP_LEASE] waiting scheduler stop", K(cost_ts2), - "name", scheduler->get_thread_name()); - } - int64_t cost_ts = ObTimeUtil::current_time() - start_ts; - FLOG_INFO("[BACKUP_LEASE] finish wait_backup_scheduler_stop_", K(cost_ts)); -} - -void ObBackupLeaseService::wait_mgr_stop_() -{ - FLOG_INFO("[BACKUP_LEASE] start waiting backup mgr stop"); - int64_t start_ts = ObTimeUtil::current_time(); - if (nullptr != backup_service_) { - backup_service_->wait(); - } - int64_t cost_ts = ObTimeUtil::current_time() - start_ts; - FLOG_INFO("[BACKUP_LEASE] finish waiting backup mgr stop", K(cost_ts)); -} - -int64_t ObBackupLeaseService::ObBackupLeaseIdle::get_idle_interval_us() -{ - return DEFAULT_IDLE_US; -} - -void ObBackupLeaseService::run1() -{ - int tmp_ret = OB_SUCCESS; - lib::set_thread_name("BackupLease"); - FLOG_INFO("ObBackupLeaseService start"); - - while(!has_set_stop()) { - if (OB_SUCCESS != (tmp_ret = renew_lease_())) { - LOG_WARN_RET(tmp_ret, "failed to renew lease", K(tmp_ret)); - } - do_idle(tmp_ret); - } - - FLOG_INFO("ObBackupLeaseService exit"); -} - -void ObBackupLeaseService::do_idle(const int32_t result) -{ - int64_t idle_us = ObBackupLeaseIdle::DEFAULT_IDLE_US; - - { - SpinRLockGuard guard(lock_); - if (can_be_leader_ts_ > 0 - || lease_info_.is_leader_ - || expect_round_ != lease_info_.round_ - || OB_SUCCESS != result) { - idle_us = ObBackupLeaseIdle::FAST_IDLE_US; - } else { - LOG_INFO("do idle", K(idle_us), K(can_be_leader_ts_), K(expect_round_), K(lease_info_)); - } - } - idle_.idle(idle_us); // ignore ret -} - -// Only single thread will change lease_info_ -int ObBackupLeaseService::renew_lease_() -{ - int ret = OB_SUCCESS; - bool need_wait_stop = false; - int64_t can_be_leader_ts = 0; - int64_t next_round = 0; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else { - SpinRLockGuard guard(lock_); - next_round = expect_round_; - if (expect_round_ != lease_info_.round_) { - need_wait_stop = true; - } - - can_be_leader_ts = can_be_leader_ts_; - } - - if (OB_SUCC(ret) && need_wait_stop) { - stop_backup_scheduler_(); - wait_backup_scheduler_stop_(); - stop_backup_service_(); - wait_mgr_stop_(); - if (OB_FAIL(clean_backup_lease_info_(next_round))) { - LOG_WARN("failed to clean backup leader info", K(ret), K(next_round)); - } - } - - if (OB_SUCC(ret) && can_be_leader_ts > 0 && next_round == lease_info_.round_) { - share::ObBackupLeaseInfo new_lease_info; - bool need_start_scheduler = !lease_info_.is_leader_; - const char *msg = ""; - if (OB_FAIL(check_sys_backup_info_())) { - LOG_WARN("failed to check sys backup info", K(ret)); - } else if (OB_FAIL(backup_lease_info_mgr_.renew_lease( - can_be_leader_ts, next_round, lease_info_, new_lease_info, msg))) { - LOG_WARN("failed to do renew lease", K(ret), K(lease_info_), K(new_lease_info)); - } else if (OB_FAIL(set_backup_lease_info_(new_lease_info, msg))) { - LOG_ERROR("failed to set lease info", K(ret), K(lease_info_), K(new_lease_info)); - } else if (!new_lease_info.is_leader_) { - LOG_WARN("cannot own new lease", K(new_lease_info)); - } else if (need_start_scheduler) { - if (OB_FAIL(start_backup_scheduler_())) { - LOG_ERROR("failed to start backup scheduler", K(ret)); - } else if (OB_FAIL(start_backup_service_())) { - LOG_ERROR("failed to start backup mgr", K(ret)); - } - } - } - - LOG_TRACE("after renew lease", K(next_round), K(expect_round_), K(lease_info_)); - - return ret; -} - -// Only single thread will change lease_info_ -int ObBackupLeaseService::clean_backup_lease_info_(const int64_t next_round) -{ - int ret = OB_SUCCESS; - ObBackupLeaseInfo new_lease_info; - bool is_leader_changed = false; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(backup_lease_info_mgr_.clean_backup_lease_info( - next_round, lease_info_, new_lease_info))) { - LOG_WARN("failed to release lease", K(ret), K(next_round)); - } else { - SpinWLockGuard guard(lock_); - is_leader_changed = lease_info_.is_leader_; - lease_info_ = new_lease_info; - } - FLOG_INFO("clean_backup_leader_info_", K(ret), K(lease_info_), K(is_leader_changed)); - if (is_leader_changed) { - ROOTSERVICE_EVENT_ADD("backup_lease", "release backup lease", K_(local_addr), "round", lease_info_.round_); - } - return ret; -} - -int ObBackupLeaseService::set_backup_lease_info_( - const share::ObBackupLeaseInfo &lease_info, const char *msg) -{ - int ret = OB_SUCCESS; - bool is_leader_changed = false; - - if (!lease_info.is_valid() || OB_ISNULL(msg)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), KP(msg), K(lease_info)); - } else { - SpinWLockGuard guard(lock_); - const int64_t cur_ts = ObTimeUtil::current_time(); - - if (lease_info.round_ != lease_info_.round_ || OB_ISNULL(msg)) { - ret = OB_INVALID_ARGUMENT; - LOG_ERROR("invalid lease info", K(ret), K(lease_info), K(lease_info_), KP(msg)); - } else if (lease_info.is_leader_ - && lease_info.lease_start_ts_ + ObBackupLeaseInfo::MAX_LEASE_TIME < cur_ts) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("lease info start ts is too old", K(ret), K(lease_info), K(cur_ts)); - } else { - if (lease_info.is_leader_ != lease_info_.is_leader_) { - is_leader_changed = true; - } - lease_info_ = lease_info; - } - } - - FLOG_INFO("set_backup_leader_info_", K(ret), K(lease_info_)); - if (OB_SUCC(ret) && is_leader_changed) { - if (lease_info_.is_leader_) { - ROOTSERVICE_EVENT_ADD("backup_lease", "acquire backup lease", - K_(local_addr), "round", lease_info_.round_, K(msg), K_(lease_info)); - } else { - ROOTSERVICE_EVENT_ADD("backup_lease", "release backup lease", - K_(local_addr), "round", lease_info_.round_); - } - } - return ret; -} - -int ObBackupLeaseService::check_sys_backup_info_() -{ - int ret = OB_SUCCESS; - ObBackupInfoChecker checker; - ObBackupInnerTableVersion inner_table_version = OB_BACKUP_INNER_TABLE_VMAX; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_ERROR("not inited", K(ret)); - } else if (OB_FAIL(share::ObBackupInfoOperator::get_inner_table_version(*sql_proxy_, inner_table_version))) { - LOG_WARN("failed to get backup inner table version", K(ret)); - } - - if (FAILEDx(checker.init(sql_proxy_, inner_table_version))) { - LOG_WARN("failed to init checker", K(ret)); - } else if (OB_FAIL(checker.check(OB_SYS_TENANT_ID))) { - LOG_WARN("failed to check sys backup info", K(ret)); - } - - LOG_TRACE("finish check sys backup info", K(ret)); - return ret; -} - - -int ObBackupLeaseService::force_cancel(const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - FLOG_INFO("[BACKUP_LEASE] start force_cancel"); - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_ERROR("not inited", K(ret)); - } else { - for (int64_t i = 0; i < backup_schedulers_.count(); ++i) { - int tmp_ret = OB_SUCCESS; - ObIBackupScheduler *scheduler = backup_schedulers_.at(i); - tmp_ret = scheduler->force_cancel(tenant_id); - FLOG_INFO("[BACKUP_LEASE] force_cancel", K(i), K(tmp_ret), K(tenant_id)); - } - ObSEArray &jobs = backup_service_->get_jobs(); - for (int64_t i = 0; i < jobs.count(); ++i) { - int tmp_ret = OB_SUCCESS; - ObIBackupJobScheduler *scheduler = jobs.at(i); - tmp_ret = scheduler->force_cancel(tenant_id); - FLOG_INFO("[BACKUP_LEASE] force_cancel", K(i), K(tmp_ret), K(tenant_id)); - } - } - - FLOG_INFO("[BACKUP_LEASE] end force_cancel"); - return OB_SUCCESS; -} diff --git a/src/rootserver/backup/ob_backup_lease_service.h b/src/rootserver/backup/ob_backup_lease_service.h deleted file mode 100644 index 4039b0035..000000000 --- a/src/rootserver/backup/ob_backup_lease_service.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright (c) 2021 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 SRC_ROOTSERVER_BACKUP_OB_BACKUP_LEASE_SERVICE_H_ -#define SRC_ROOTSERVER_BACKUP_OB_BACKUP_LEASE_SERVICE_H_ - -#include "share/backup/ob_backup_lease_info_mgr.h" -#include "rootserver/ob_thread_idling.h" - -namespace oceanbase -{ -namespace rootserver -{ - -class ObIBackupScheduler; -class ObBackupService; - -class ObBackupLeaseService: public share::ObIBackupLeaseService, public lib::ThreadPool -{ -public: - ObBackupLeaseService(); - virtual ~ObBackupLeaseService(); - - int init(const common::ObAddr &addr, - common::ObMySQLProxy &sql_proxy); - int register_scheduler(ObIBackupScheduler &scheduler); - int register_mgr(ObBackupService &mgr); - int schedule_renew_task(); - // start_lease/stop_lease control lease service's status: is_stop/expect_round - int start_lease(); - int stop_lease(); - void wait_lease(); - - // force cancel backup/archive/backup backupset/backup piece/validate - int force_cancel(const uint64_t tenant_id); - - virtual int start() override; - virtual void stop() override; - void destroy(); - void wakeup(); - virtual int check_lease() override; - virtual int get_lease_status(bool &is_lease_valid) override; - virtual int64_t get_lease_version() const override; - VIRTUAL_TO_STRING_KV(K_(is_inited), K_(can_be_leader_ts), K_(expect_round), K_(lease_info)); - -private: - int start_backup_scheduler_(); - void stop_backup_scheduler_(); - void wait_backup_scheduler_stop_(); - int start_backup_service_(); //4.0 - void stop_backup_service_(); //4.0 - void wait_mgr_stop_(); // 4.0 - virtual void run1() final override; - void do_idle(const int32_t result); - int renew_lease_(); - int clean_backup_lease_info_(const int64_t next_round); - int set_backup_lease_info_(const share::ObBackupLeaseInfo &lease_info, - const char *msg); - OB_INLINE bool can_be_leader_() const { return 0 != can_be_leader_ts_; } - int check_sys_backup_info_(); - - class ObBackupLeaseIdle: public rootserver::ObThreadIdling - { - public: - static const int64_t DEFAULT_IDLE_US = 60 * 1000 * 1000;//60s - static const int64_t FAST_IDLE_US = 1 * 1000 * 1000;//1s - explicit ObBackupLeaseIdle(volatile bool &stop): ObThreadIdling(stop) {} - virtual ~ObBackupLeaseIdle() {} - virtual int64_t get_idle_interval_us() override; - }; - -private: - bool is_inited_; - int64_t can_be_leader_ts_; // > 0 means can do backup scheduler - int64_t expect_round_; // usually, start/stop makes round+1. Or if rs epoch is changed, round will inc 1 also. - common::SpinRWLock lock_; - share::ObBackupLeaseInfoMgr backup_lease_info_mgr_; - share::ObBackupLeaseInfo lease_info_; // Only single thread will change lease_info_ - ObMySQLProxy *sql_proxy_;// This is the sql proxy of the observer and is not controlled by rs stop - common::ObSEArray backup_schedulers_;// There are less than 8 at present, can be adjusted larger as needed - ObBackupService *backup_service_; - ObBackupLeaseIdle idle_; - common::ObAddr local_addr_; - DISALLOW_COPY_AND_ASSIGN(ObBackupLeaseService); -}; - -}// rootserver -}// oceanbase -#endif /* SRC_ROOTSERVER_BACKUP_OB_BACKUP_LEASE_SERVICE_H_ */ diff --git a/src/rootserver/backup/ob_backup_proxy.cpp b/src/rootserver/backup/ob_backup_proxy.cpp new file mode 100644 index 000000000..3bf309f34 --- /dev/null +++ b/src/rootserver/backup/ob_backup_proxy.cpp @@ -0,0 +1,107 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX RS + +#include "ob_backup_proxy.h" +#include "ob_backup_service.h" +#include "ob_archive_scheduler_service.h" +#include "share/ob_rpc_struct.h" + +using namespace oceanbase; +using namespace rootserver; +using namespace obrpc; + +int ObBackupServiceProxy::handle_backup_database(const obrpc::ObBackupDatabaseArg &arg) +{ + int ret = OB_SUCCESS; + ObBackupDataService *backup_service = nullptr; + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (OB_FAIL(guard.switch_to(OB_SYS_TENANT_ID))) { + LOG_WARN("failed to switch to sys tenant", K(ret)); + } else if (OB_ISNULL(backup_service = MTL(ObBackupDataService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup service must not be nullptr", K(ret)); + } else if (OB_FAIL(backup_service->handle_backup_database(arg))) { + LOG_WARN("failed handle backup database", K(ret)); + } + return ret; +} + +int ObBackupServiceProxy::handle_backup_database_cancel(const obrpc::ObBackupManageArg &arg) +{ + int ret = OB_SUCCESS; + ObBackupDataService *backup_service = nullptr; + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (ObBackupManageArg::CANCEL_BACKUP != arg.type_) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("handle backup database cancel get invalid argument", K(ret), K(arg)); + } else if (OB_FAIL(guard.switch_to(OB_SYS_TENANT_ID))) { + LOG_WARN("failed to switch to sys tenant", K(ret)); + } else if (OB_ISNULL(backup_service = MTL(ObBackupDataService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup service must not be nullptr", K(ret)); + } else if (OB_FAIL(backup_service->handle_backup_database_cancel(arg.tenant_id_, arg.managed_tenant_ids_))) { + LOG_WARN("failed handle backup database", K(ret)); + } + return ret; +} + +int ObBackupServiceProxy::handle_backup_delete(const obrpc::ObBackupCleanArg &arg) +{ + int ret = OB_SUCCESS; + ObBackupCleanService *backup_service = nullptr; + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (OB_FAIL(guard.switch_to(OB_SYS_TENANT_ID))) { + LOG_WARN("failed to switch to sys tenant", K(ret)); + } else if (OB_ISNULL(backup_service = MTL(ObBackupCleanService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup service must not be nullptr", K(ret)); + } else if (OB_FAIL(backup_service->handle_backup_delete(arg))) { + LOG_WARN("failed handle backup database", K(ret)); + } + return ret; +} + +int ObBackupServiceProxy::handle_delete_policy(const obrpc::ObDeletePolicyArg &arg) +{ + int ret = OB_SUCCESS; + ObBackupCleanService *backup_service = nullptr; + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (OB_FAIL(guard.switch_to(OB_SYS_TENANT_ID))) { + LOG_WARN("failed to switch to sys tenant", K(ret)); + } else if (OB_ISNULL(backup_service = MTL(ObBackupCleanService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup service must not be nullptr", K(ret)); + } else if (OB_FAIL(backup_service->handle_delete_policy(arg))) { + LOG_WARN("failed handle backup database", K(ret)); + } + return ret; +} + +int ObBackupServiceProxy::handle_archive_log(const obrpc::ObArchiveLogArg &arg) +{ + int ret = OB_SUCCESS; + ObArchiveSchedulerService *archive_service = nullptr; + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (OB_FAIL(guard.switch_to(OB_SYS_TENANT_ID))) { + LOG_WARN("failed to switch to sys tenant", K(ret)); + } else if (OB_ISNULL(archive_service = MTL(ObArchiveSchedulerService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup service must not be nullptr", K(ret)); + } else if (arg.enable_ && OB_FAIL(archive_service->open_archive_mode(arg.tenant_id_, arg.archive_tenant_ids_))) { + LOG_WARN("failed to start archive", K(ret), K(arg)); + } else if (!arg.enable_ && OB_FAIL(archive_service->close_archive_mode(arg.tenant_id_, arg.archive_tenant_ids_))) { + LOG_WARN("failed to stop archive", K(ret), K(arg)); + } + return ret; +} diff --git a/src/rootserver/backup/ob_backup_proxy.h b/src/rootserver/backup/ob_backup_proxy.h new file mode 100644 index 000000000..315265ab2 --- /dev/null +++ b/src/rootserver/backup/ob_backup_proxy.h @@ -0,0 +1,46 @@ +/** + * 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_ROOTSERVER_OB_BACKUP_SERVICE_PROXY_H_ +#define OCEANBASE_ROOTSERVER_OB_BACKUP_SERVICE_PROXY_H_ + +namespace oceanbase +{ +namespace obrpc +{ +struct ObBackupDatabaseArg; +struct ObBackupCleanArg; +struct ObDeletePolicyArg; +struct ObBackupCleanArg; +struct ObArchiveLogArg; +struct ObBackupManageArg; +struct ObArchiveLogArg; +} + +namespace rootserver +{ + +class ObBackupServiceProxy +{ +public: + static int handle_backup_database(const obrpc::ObBackupDatabaseArg &arg); + static int handle_backup_database_cancel(const obrpc::ObBackupManageArg &arg); + static int handle_backup_delete(const obrpc::ObBackupCleanArg &arg); + static int handle_delete_policy(const obrpc::ObDeletePolicyArg &arg); + static int handle_backup_delete_obsolete(const obrpc::ObBackupCleanArg &arg); + static int handle_archive_log(const obrpc::ObArchiveLogArg &arg); +}; + +} +} + +#endif diff --git a/src/rootserver/backup/ob_backup_schedule_task.cpp b/src/rootserver/backup/ob_backup_schedule_task.cpp index f1bd20bab..8a2aa1987 100644 --- a/src/rootserver/backup/ob_backup_schedule_task.cpp +++ b/src/rootserver/backup/ob_backup_schedule_task.cpp @@ -301,11 +301,11 @@ int ObBackupScheduleTask::build_from_res(const obrpc::ObBackupTaskRes &res, cons return ret; } -/* - *---------------------ObBackupDataLSTask---------------------- - */ -ObBackupDataLSTask::ObBackupDataLSTask() +/* + *---------------------ObBackupDataBaseTask---------------------- + */ +ObBackupDataBaseTask::ObBackupDataBaseTask() : incarnation_id_(OB_BACKUP_INVALID_INCARNATION_ID), backup_set_id_(OB_BACKUP_INVALID_BACKUP_SET_ID), backup_type_(), @@ -314,108 +314,48 @@ ObBackupDataLSTask::ObBackupDataLSTask() turn_id_(OB_BACKUP_INVALID_TURN_ID), retry_id_(OB_BACKUP_INVALID_RETRY_ID), start_scn_(), + backup_user_ls_scn_(), + end_scn_(), backup_path_(), backup_status_() { } -ObBackupDataLSTask::~ObBackupDataLSTask() -{ -} - -int ObBackupDataLSTask::clone(void *input_ptr, ObBackupScheduleTask *&out_task) const +int ObBackupDataBaseTask::deep_copy(const ObBackupDataBaseTask &that) { int ret = OB_SUCCESS; - if (OB_ISNULL(input_ptr)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(input_ptr)); + if (OB_FAIL(ObBackupScheduleTask::deep_copy(that))) { + LOG_WARN("failed to deep copy backup schedule task", K(ret)); + } else if (OB_FAIL(backup_path_.assign(that.backup_path_))) { + LOG_WARN("failed to assign backup path", K(ret)); } else { - ObBackupDataLSTask *my_task = new (input_ptr) ObBackupDataLSTask(); - if (OB_ISNULL(my_task)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("taks is nullptr", K(ret)); - } else if (OB_FAIL(my_task->ObBackupScheduleTask::deep_copy(*this))) { - LOG_WARN("fail to deep copy base task", K(ret)); - } else if (OB_FAIL(my_task->backup_path_.assign(backup_path_))) { - LOG_WARN("failed to assign backup dest", K(ret)); - } else { - my_task->incarnation_id_ = incarnation_id_; - my_task->backup_set_id_ = backup_set_id_; - my_task->backup_type_.type_ = backup_type_.type_; - my_task->backup_date_ = backup_date_; - my_task->ls_id_ = ls_id_; - my_task->turn_id_ = turn_id_; - my_task->retry_id_ = retry_id_; - my_task->start_scn_ = start_scn_; - my_task->backup_status_.status_ = backup_status_.status_; - } - if (OB_SUCC(ret)) { - out_task = my_task; - } else if (OB_NOT_NULL(my_task)) { - my_task->~ObBackupDataLSTask(); - my_task = nullptr; - } + incarnation_id_ = that.incarnation_id_; + backup_set_id_ = that.backup_set_id_; + backup_type_.type_ = that.backup_type_.type_; + backup_date_ = that.backup_date_; + ls_id_ = that.ls_id_; + turn_id_ = that.turn_id_; + retry_id_ = that.retry_id_; + start_scn_ = that.start_scn_; + backup_user_ls_scn_ = that.backup_user_ls_scn_; + end_scn_ = that.end_scn_; + backup_status_.status_ = that.backup_status_.status_; } return ret; } -int64_t ObBackupDataLSTask::get_deep_copy_size() const -{ - return sizeof(ObBackupDataLSTask); -} - -bool ObBackupDataLSTask::can_execute_on_any_server() const -{ - return false; -} - -int ObBackupDataLSTask::do_update_dst_and_doing_status_(common::ObMySQLProxy &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) +int ObBackupDataBaseTask::do_update_dst_and_doing_status_(common::ObISQLClient &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) { int ret = OB_SUCCESS; ObLSID ls_id(get_ls_id()); - if (OB_FAIL(ObBackupLSTaskOperator::update_dst_and_status(sql_proxy, get_task_id(), get_tenant_id(), ls_id, trace_id, dst))) { + if (OB_FAIL(ObBackupLSTaskOperator::update_dst_and_status( + sql_proxy, get_task_id(), get_tenant_id(), ls_id, turn_id_, retry_id_, trace_id, dst))) { LOG_WARN("failed to update task status", K(ret), K(*this), K(dst)); } return ret; } -int ObBackupDataLSTask::execute(obrpc::ObSrvRpcProxy &rpc_proxy) const -{ - int ret = OB_SUCCESS; - obrpc::ObBackupDataArg arg; - arg.trace_id_ = get_trace_id(); - arg.tenant_id_ = get_tenant_id(); - arg.task_id_ = get_task_id(); - arg.backup_set_id_ = backup_set_id_; - arg.incarnation_id_ = incarnation_id_; - arg.backup_type_ = backup_type_.type_; - arg.backup_date_ = backup_date_; - arg.ls_id_ = ls_id_; - arg.turn_id_ = turn_id_; - arg.retry_id_ = retry_id_; - arg.dst_server_ = get_dst(); - arg.job_id_ = get_job_id(); - int64_t timeout = 60 * 1000 * 1000; //60s TODO(yangyi.yyy) remove after 4.1 release - if (OB_FAIL(backup_status_.get_backup_data_type(arg.backup_data_type_))) { - LOG_WARN("failed to get backup data type", K(ret), K_(backup_status)); - } else if (OB_FAIL(arg.backup_path_.assign(backup_path_))) { - LOG_WARN("failed to assign backup dest", K(ret), K(backup_path_)); - } else if (OB_FAIL(rpc_proxy.timeout(timeout).to(get_dst()).backup_ls_data(arg))) { - LOG_WARN("fail to send backup ls data task", K(ret), K(arg)); - } else { - ROOTSERVICE_EVENT_ADD("backup", "send backup data task", - "tenant_id", arg.tenant_id_, - "task_id", arg.task_id_, - "trace_id", arg.trace_id_, - "turn_id", arg.turn_id_, - "retry_id", arg.retry_id_, - "dst_server", arg.dst_server_); - LOG_INFO("start to backup ls data", K(arg)); - } - return ret; -} - -int ObBackupDataLSTask::cancel(obrpc::ObSrvRpcProxy &rpc_proxy) const +int ObBackupDataBaseTask::cancel(obrpc::ObSrvRpcProxy &rpc_proxy) const { int ret = OB_SUCCESS; obrpc::ObCancelTaskArg rpc_arg; @@ -431,7 +371,8 @@ int ObBackupDataLSTask::cancel(obrpc::ObSrvRpcProxy &rpc_proxy) const return ret; } -int ObBackupDataLSTask::build(const ObBackupJobAttr &job_attr, const ObBackupSetTaskAttr &set_task_attr, const ObBackupLSTaskAttr &ls_attr) +int ObBackupDataBaseTask::build(const share::ObBackupJobAttr &job_attr, const share::ObBackupSetTaskAttr &set_task_attr, + const share::ObBackupLSTaskAttr &ls_attr) { int ret = OB_SUCCESS; ObBackupScheduleTaskKey key; @@ -450,7 +391,9 @@ int ObBackupDataLSTask::build(const ObBackupJobAttr &job_attr, const ObBackupSet ls_id_ = ls_attr.ls_id_; turn_id_ = ls_attr.turn_id_; retry_id_ = ls_attr.retry_id_; - start_scn_ = ls_attr.ls_id_.is_sys_ls() ? set_task_attr.start_scn_ : set_task_attr.user_ls_start_scn_; + start_scn_ = set_task_attr.start_scn_; + backup_user_ls_scn_ = ls_attr.ls_id_.is_sys_ls() ? set_task_attr.start_scn_ : set_task_attr.user_ls_start_scn_; + end_scn_ = set_task_attr.end_scn_; backup_status_.status_ = set_task_attr.status_.status_; if (OB_FAIL(backup_path_.assign(job_attr.backup_path_))) { LOG_WARN("failed to assign backup dest", K(ret), K(job_attr.backup_path_)); @@ -461,7 +404,7 @@ int ObBackupDataLSTask::build(const ObBackupJobAttr &job_attr, const ObBackupSet return ret; } -int ObBackupDataLSTask::set_optional_servers_(const ObIArray &black_servers) +int ObBackupDataBaseTask::set_optional_servers_(const ObIArray &black_servers) { int ret = OB_SUCCESS; ObLSInfo ls_info; @@ -469,11 +412,11 @@ int ObBackupDataLSTask::set_optional_servers_(const ObIArray &bl uint64_t tenant_id = get_tenant_id(); share::ObLSTableOperator *lst_operator = GCTX.lst_operator_; int64_t cluster_id = GCONF.cluster_id; + ObLSID server_ls_id = ls_id_.id() == 0 ? ObLSID(ObLSID::SYS_LS_ID) : ls_id_; if (nullptr == lst_operator) { ret = OB_ERR_UNEXPECTED; LOG_WARN("lst_operator ptr is null", K(ret)); - } else if (OB_FAIL(lst_operator->get(cluster_id, tenant_id, - ls_id_, share::ObLSTable::DEFAULT_MODE, ls_info))) { + } else if (OB_FAIL(lst_operator->get(cluster_id, tenant_id, server_ls_id, share::ObLSTable::DEFAULT_MODE, ls_info))) { LOG_WARN("failed to get log stream info", K(ret), K(cluster_id), K(tenant_id), K(ls_id_)); } else { const ObLSInfo::ReplicaArray &replica_array = ls_info.get_replicas(); @@ -502,7 +445,7 @@ int ObBackupDataLSTask::set_optional_servers_(const ObIArray &bl } } if (OB_SUCC(ret) && servers.empty()) { - ret = OB_EAGAIN; + ret = OB_LS_LOCATION_NOT_EXIST; LOG_WARN("no optional servers, retry_later", K(ret), K(*this)); } } @@ -515,7 +458,7 @@ int ObBackupDataLSTask::set_optional_servers_(const ObIArray &bl return ret; } -bool ObBackupDataLSTask::check_replica_in_black_server_(const ObLSReplica &replica, const ObIArray &black_servers) +bool ObBackupDataBaseTask::check_replica_in_black_server_(const ObLSReplica &replica, const ObIArray &black_servers) { bool is_in_black_servers = false; for (int i = 0; i < black_servers.count(); ++i) { @@ -528,26 +471,70 @@ bool ObBackupDataLSTask::check_replica_in_black_server_(const ObLSReplica &repli } /* - *-------------------------ObBackupComplLogTask------------------------------ + *---------------------ObBackupDataLSTask---------------------- */ -ObBackupComplLogTask::ObBackupComplLogTask() - : incarnation_id_(OB_BACKUP_INVALID_INCARNATION_ID), - backup_set_id_(OB_BACKUP_INVALID_BACKUP_SET_ID), - backup_type_(), - backup_date_(OB_INVALID_TIMESTAMP), - ls_id_(), - start_scn_(), - end_scn_(), - backup_path_(), - backup_status_() +int ObBackupDataLSTask::clone(void *input_ptr, ObBackupScheduleTask *&out_task) const { + int ret = OB_SUCCESS; + if (OB_ISNULL(input_ptr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(input_ptr)); + } else { + ObBackupDataLSTask *my_task = new (input_ptr) ObBackupDataLSTask(); + if (OB_ISNULL(my_task)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("taks is nullptr", K(ret)); + } else if (OB_FAIL(my_task->ObBackupDataBaseTask::deep_copy(*this))) { + LOG_WARN("fail to deep copy base task", K(ret)); + } + if (OB_SUCC(ret)) { + out_task = my_task; + } else if (OB_NOT_NULL(my_task)) { + my_task->~ObBackupDataLSTask(); + my_task = nullptr; + } + } + return ret; } -ObBackupComplLogTask::~ObBackupComplLogTask() +int64_t ObBackupDataLSTask::get_deep_copy_size() const { + return sizeof(ObBackupDataLSTask); } +int ObBackupDataLSTask::execute(obrpc::ObSrvRpcProxy &rpc_proxy) const +{ + int ret = OB_SUCCESS; + obrpc::ObBackupDataArg arg; + arg.trace_id_ = get_trace_id(); + arg.tenant_id_ = get_tenant_id(); + arg.task_id_ = get_task_id(); + arg.backup_set_id_ = backup_set_id_; + arg.incarnation_id_ = incarnation_id_; + arg.backup_type_ = backup_type_.type_; + arg.backup_date_ = backup_date_; + arg.ls_id_ = ls_id_; + arg.turn_id_ = turn_id_; + arg.retry_id_ = retry_id_; + arg.dst_server_ = get_dst(); + arg.job_id_ = get_job_id(); + if (OB_FAIL(backup_status_.get_backup_data_type(arg.backup_data_type_))) { + LOG_WARN("failed to get backup data type", K(ret), K_(backup_status)); + } else if (OB_FAIL(arg.backup_path_.assign(backup_path_))) { + LOG_WARN("failed to assign backup dest", K(ret), K(backup_path_)); + } else if (OB_FAIL(rpc_proxy.to(get_dst()).backup_ls_data(arg))) { + LOG_WARN("fail to send backup ls data task", K(ret), K(arg)); + } else { + LOG_INFO("start to backup ls data", K(arg)); + } + return ret; +} + +/* + *-------------------------ObBackupComplLogTask------------------------------ + */ + int ObBackupComplLogTask::clone(void *input_ptr, ObBackupScheduleTask *&out_task) const { int ret = OB_SUCCESS; @@ -559,19 +546,8 @@ int ObBackupComplLogTask::clone(void *input_ptr, ObBackupScheduleTask *&out_task if (OB_ISNULL(my_task)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("taks is nullptr", K(ret)); - } else if (OB_FAIL(my_task->ObBackupScheduleTask::deep_copy(*this))) { + } else if (OB_FAIL(my_task->ObBackupDataBaseTask::deep_copy(*this))) { LOG_WARN("fail to deep copy base task", K(ret)); - } else if (OB_FAIL(my_task->backup_path_.assign(backup_path_))) { - LOG_WARN("failed to assign backup dest", K(ret)); - } else { - my_task->incarnation_id_ = incarnation_id_; - my_task->backup_set_id_ = backup_set_id_; - my_task->backup_type_.type_ = backup_type_.type_; - my_task->backup_date_ = backup_date_; - my_task->ls_id_ = ls_id_; - my_task->start_scn_ = start_scn_; - my_task->end_scn_ = end_scn_; - my_task->backup_status_.status_ = backup_status_.status_; } if (OB_SUCC(ret)) { out_task = my_task; @@ -582,25 +558,47 @@ int ObBackupComplLogTask::clone(void *input_ptr, ObBackupScheduleTask *&out_task } return ret; } + int64_t ObBackupComplLogTask::get_deep_copy_size() const { return sizeof(ObBackupComplLogTask); } -bool ObBackupComplLogTask::can_execute_on_any_server() const -{ - return true; -} - -int ObBackupComplLogTask::do_update_dst_and_doing_status_(common::ObMySQLProxy &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) +int ObBackupComplLogTask::build(const share::ObBackupJobAttr &job_attr, const share::ObBackupSetTaskAttr &set_task_attr, + const share::ObBackupLSTaskAttr &ls_attr) { int ret = OB_SUCCESS; - ObLSID ls_id(get_ls_id()); - if (OB_FAIL(ObBackupLSTaskOperator::update_dst_and_status(sql_proxy, get_task_id(), get_tenant_id(), ls_id, trace_id, dst))) { - LOG_WARN("failed to update task status", K(ret), K(dst), K(trace_id)); - } + ObBackupScheduleTaskKey key; + share::SCN start_replay_scn; + if (!job_attr.is_valid() || !ls_attr.is_valid()) { + ret = OB_SUCCESS; + LOG_WARN("invalid argument", K(ret), K(job_attr), K(ls_attr)); + } else if (OB_FAIL(key.init(ls_attr.tenant_id_, job_attr.job_id_, ls_attr.task_id_, ls_attr.ls_id_.id(), BackupJobType::BACKUP_DATA_JOB))) { + LOG_WARN("failed to init backup schedule task key", K(ret), K(job_attr), K(ls_attr)); + } else if (OB_FAIL(ObBackupScheduleTask::build(key, ls_attr.task_trace_id_, ls_attr.status_, ls_attr.dst_))) { + LOG_WARN("fail to build backup schedule task", K(ret), "trace_id", ls_attr.task_trace_id_, "status", ls_attr.status_, "dst", ls_attr.dst_); + } else if (OB_FAIL(calc_start_replay_scn_(job_attr, set_task_attr, ls_attr, start_replay_scn))) { + LOG_WARN("failed to calc start replay scn", K(ret), K(job_attr), K(set_task_attr), K(ls_attr)); + } else { + incarnation_id_ = job_attr.incarnation_id_; + backup_set_id_ = ls_attr.backup_set_id_; + backup_type_.type_ = ls_attr.backup_type_.type_; + backup_date_ = ls_attr.backup_date_; + ls_id_ = ls_attr.ls_id_; + start_scn_ = start_replay_scn; + end_scn_ = set_task_attr.end_scn_; + backup_status_.status_ = set_task_attr.status_.status_; + turn_id_ = ls_attr.turn_id_; + retry_id_ = ls_attr.retry_id_; + if (OB_FAIL(backup_path_.assign(job_attr.backup_path_))) { + LOG_WARN("failed to assign backup dest", K(ret), "backup dest", job_attr.backup_path_); + } else if (OB_FAIL(set_optional_servers_(ls_attr.black_servers_))) { + LOG_WARN("failed to set optional servers", K(ret), K(ls_attr)); + } + } return ret; } + int ObBackupComplLogTask::execute(obrpc::ObSrvRpcProxy &rpc_proxy) const { int ret = OB_SUCCESS; @@ -627,57 +625,12 @@ int ObBackupComplLogTask::execute(obrpc::ObSrvRpcProxy &rpc_proxy) const return ret; } -int ObBackupComplLogTask::cancel(obrpc::ObSrvRpcProxy &rpc_proxy) const -{ - int ret = OB_SUCCESS; - obrpc::ObCancelTaskArg rpc_arg; - rpc_arg.task_id_ = get_trace_id(); - if (OB_FAIL(rpc_proxy.to(get_dst()).cancel_sys_task(rpc_arg))) { - if (OB_ENTRY_NOT_EXIST == ret) { - LOG_INFO("task may not excute on server", K(rpc_arg), "dst", get_dst()); - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to cancel sys task", K(ret), K(rpc_arg)); - } - } - return ret; -} - -int ObBackupComplLogTask::build(const ObBackupJobAttr &job_attr, const ObBackupSetTaskAttr &set_task_attr, const ObBackupLSTaskAttr &ls_attr) -{ - int ret = OB_SUCCESS; - ObBackupScheduleTaskKey key; - share::SCN start_replay_scn; - if (!job_attr.is_valid() || !ls_attr.is_valid()) { - ret = OB_SUCCESS; - LOG_WARN("invalid argument", K(ret), K(job_attr), K(ls_attr)); - } else if (OB_FAIL(key.init(ls_attr.tenant_id_, job_attr.job_id_, ls_attr.task_id_, ls_attr.ls_id_.id(), BackupJobType::BACKUP_DATA_JOB))) { - LOG_WARN("failed to init backup schedule task key", K(ret), K(job_attr), K(ls_attr)); - } else if (OB_FAIL(ObBackupScheduleTask::build(key, ls_attr.task_trace_id_, ls_attr.status_, ls_attr.dst_))) { - LOG_WARN("fail to build backup schedule task", K(ret), "trace_id", ls_attr.task_trace_id_, "status", ls_attr.status_, "dst", ls_attr.dst_); - } else if (OB_FAIL(calc_start_replay_scn_(job_attr, set_task_attr, ls_attr, start_replay_scn))) { - LOG_WARN("failed to calc start replay scn", K(ret), K(job_attr), K(set_task_attr), K(ls_attr)); - } else { - incarnation_id_ = job_attr.incarnation_id_; - backup_set_id_ = ls_attr.backup_set_id_; - backup_type_.type_ = ls_attr.backup_type_.type_; - backup_date_ = ls_attr.backup_date_; - ls_id_ = ls_attr.ls_id_; - start_scn_ = start_replay_scn; - end_scn_ = set_task_attr.end_scn_; - backup_status_.status_ = set_task_attr.status_.status_; - if (OB_FAIL(backup_path_.assign(job_attr.backup_path_))) { - LOG_WARN("failed to assign backup dest", K(ret), "backup dest", job_attr.backup_path_); - } - } - return ret; -} int ObBackupComplLogTask::calc_start_replay_scn_(const ObBackupJobAttr &job_attr, const ObBackupSetTaskAttr &set_task_attr, const ObBackupLSTaskAttr &ls_attr, share::SCN &start_replay_scn) { int ret = OB_SUCCESS; - ObBackupLSMetaInfosDesc ls_meta_infos; + storage::ObBackupLSMetaInfosDesc ls_meta_infos; ObTenantArchiveRoundAttr round_attr; ObBackupDataStore store; ObBackupDest backup_dest; @@ -700,7 +653,7 @@ int ObBackupComplLogTask::calc_start_replay_scn_(const ObBackupJobAttr &job_attr LOG_WARN("backup is not supported when archive is interrupted", K(ret), K(round_attr), K(set_task_attr)); } else if (OB_FAIL(store.read_ls_meta_infos(ls_meta_infos))) { LOG_WARN("fail to read ls meta infos", K(ret)); - } else if (OB_FAIL(ObBackupUtils::calc_start_replay_scn(set_task_attr, ls_meta_infos, round_attr, start_replay_scn))) { + } else if (OB_FAIL(backup::ObBackupUtils::calc_start_replay_scn(set_task_attr, ls_meta_infos, round_attr, start_replay_scn))) { LOG_WARN("failed to calc start replay scn", K(ret), K(set_task_attr), K(ls_meta_infos), K(round_attr)); } LOG_INFO("calc start replay scn", K(ret), K(job_attr), K(set_task_attr), K(ls_attr), K(start_replay_scn)); @@ -711,23 +664,6 @@ int ObBackupComplLogTask::calc_start_replay_scn_(const ObBackupJobAttr &job_attr *------------------------ObBackupBuildIndexTask-------------------------- */ -ObBackupBuildIndexTask::ObBackupBuildIndexTask() - : incarnation_id_(OB_BACKUP_INVALID_INCARNATION_ID), - backup_set_id_(OB_BACKUP_INVALID_BACKUP_SET_ID), - backup_type_(), - backup_date_(OB_INVALID_TIMESTAMP), - turn_id_(OB_BACKUP_INVALID_TURN_ID), - retry_id_(OB_BACKUP_INVALID_RETRY_ID), - start_turn_id_(OB_BACKUP_INVALID_TURN_ID), - backup_path_(), - backup_status_() -{ -} - -ObBackupBuildIndexTask::~ObBackupBuildIndexTask() -{ -} - int ObBackupBuildIndexTask::clone(void *input_ptr, ObBackupScheduleTask *&out_task) const { int ret = OB_SUCCESS; @@ -739,18 +675,8 @@ int ObBackupBuildIndexTask::clone(void *input_ptr, ObBackupScheduleTask *&out_ta if (OB_ISNULL(my_task)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("taks is nullptr", K(ret)); - } else if (OB_FAIL(my_task->ObBackupScheduleTask::deep_copy(*this))) { + } else if (OB_FAIL(my_task->ObBackupDataBaseTask::deep_copy(*this))) { LOG_WARN("fail to deep copy base task", K(ret)); - } else if (OB_FAIL(my_task->backup_path_.assign(backup_path_))) { - LOG_WARN("failed to assign backup dest", K(ret)); - } else { - my_task->incarnation_id_ = incarnation_id_; - my_task->backup_set_id_ = backup_set_id_; - my_task->backup_type_.type_ = backup_type_.type_; - my_task->backup_date_ = backup_date_; - my_task->turn_id_ = turn_id_; - my_task->retry_id_ = retry_id_; - my_task->backup_status_.status_ = backup_status_.status_; } if (OB_SUCC(ret)) { out_task = my_task; @@ -761,26 +687,12 @@ int ObBackupBuildIndexTask::clone(void *input_ptr, ObBackupScheduleTask *&out_ta } return ret; } + int64_t ObBackupBuildIndexTask::get_deep_copy_size() const { return sizeof(ObBackupBuildIndexTask); } -bool ObBackupBuildIndexTask::can_execute_on_any_server() const -{ - return false; -} - -int ObBackupBuildIndexTask::do_update_dst_and_doing_status_(common::ObMySQLProxy &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) -{ - int ret = OB_SUCCESS; - ObLSID ls_id(get_ls_id()); - if (OB_FAIL(ObBackupLSTaskOperator::update_dst_and_status(sql_proxy, get_task_id(), get_tenant_id(), ls_id, trace_id, dst))) { - LOG_WARN("failed to update task status", K(ret), K(*this), K(dst)); - } - return ret; -} - int ObBackupBuildIndexTask::execute(obrpc::ObSrvRpcProxy &rpc_proxy) const { int ret = OB_SUCCESS; @@ -796,7 +708,6 @@ int ObBackupBuildIndexTask::execute(obrpc::ObSrvRpcProxy &rpc_proxy) const arg.turn_id_ = turn_id_; arg.retry_id_ = retry_id_; arg.dst_server_ = get_dst(); - arg.start_turn_id_ = start_turn_id_; if (OB_FAIL(backup_status_.get_backup_data_type(arg.backup_data_type_))) { LOG_WARN("failed to get backup data type", K(ret), K_(backup_status)); } else if (OB_FAIL(arg.backup_path_.assign(backup_path_))) { @@ -809,119 +720,6 @@ int ObBackupBuildIndexTask::execute(obrpc::ObSrvRpcProxy &rpc_proxy) const return ret; } -int ObBackupBuildIndexTask::cancel(obrpc::ObSrvRpcProxy &rpc_proxy) const -{ - int ret = OB_SUCCESS; - obrpc::ObCancelTaskArg rpc_arg; - rpc_arg.task_id_ = get_trace_id(); - if (OB_FAIL(rpc_proxy.to(get_dst()).cancel_sys_task(rpc_arg))) { - if (OB_ENTRY_NOT_EXIST == ret) { - LOG_INFO("task may not excute on server", K(rpc_arg), "dst", get_dst()); - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to cancel sys task", K(ret), K(rpc_arg)); - } - } - return ret; -} - -int ObBackupBuildIndexTask::build(const ObBackupJobAttr &job_attr, const ObBackupSetTaskAttr &set_task_attr, const ObBackupLSTaskAttr &ls_attr) -{ - int ret = OB_SUCCESS; - ObBackupScheduleTaskKey key; - if (!job_attr.is_valid() || !ls_attr.is_valid()) { - ret = OB_SUCCESS; - LOG_WARN("invalid argument", K(ret), K(job_attr), K(ls_attr)); - } else if (OB_FAIL(key.init(ls_attr.tenant_id_, job_attr.job_id_, ls_attr.task_id_, ls_attr.ls_id_.id(), BackupJobType::BACKUP_DATA_JOB))) { - LOG_WARN("failed to init backup schedule task key", K(ret), K(job_attr), K(ls_attr)); - } else if (OB_FAIL(ObBackupScheduleTask::build(key, ls_attr.task_trace_id_, ls_attr.status_, ls_attr.dst_))) { - LOG_WARN("fail to build backup schedule task", K(ret), "trace_id", ls_attr.task_trace_id_, "status", ls_attr.status_, "dst", ls_attr.dst_); - } else { - incarnation_id_ = job_attr.incarnation_id_; - backup_set_id_ = ls_attr.backup_set_id_; - backup_type_.type_ = ls_attr.backup_type_.type_; - backup_date_ = ls_attr.backup_date_; - turn_id_ = ls_attr.turn_id_; - retry_id_ = ls_attr.retry_id_; - start_turn_id_ = ls_attr.start_turn_id_; - backup_status_.status_ = set_task_attr.status_.status_; - if (OB_FAIL(backup_path_.assign(job_attr.backup_path_))) { - LOG_WARN("failed to assign backup path", K(ret), "backup_path", job_attr.backup_path_); - } else if (OB_FAIL(set_optional_servers_(ls_attr.black_servers_))) { - LOG_WARN("failed to set optional servers", K(ret), K(ls_attr)); - } - } - return ret; -} - -int ObBackupBuildIndexTask::set_optional_servers_(const ObIArray &black_servers) -{ - int ret = OB_SUCCESS; - ObLSInfo ls_info; - ObArray servers; - uint64_t tenant_id = get_tenant_id(); - share::ObLSTableOperator *lst_operator = GCTX.lst_operator_; - int64_t cluster_id = GCONF.cluster_id; - share::ObLSID ls_id(share::ObLSID::SYS_LS_ID); - if (nullptr == lst_operator) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("lst_operator ptr is null", K(ret)); - } else if (OB_FAIL(lst_operator->get(cluster_id, tenant_id, - ls_id, share::ObLSTable::DEFAULT_MODE, ls_info))) { - LOG_WARN("failed to get log stream info", K(ret), K(cluster_id), K(tenant_id), K(ls_id)); - } else { - const ObLSInfo::ReplicaArray &replica_array = ls_info.get_replicas(); - for (int i = 0; OB_SUCC(ret) && i < replica_array.count(); ++i) { - const ObLSReplica &replica = replica_array.at(i); - if (replica.is_in_service() && !replica.is_strong_leader() && replica.is_valid() && !replica.is_in_restore() - && !check_replica_in_black_server_(replica, black_servers)) { - ObBackupServer server; - server.set(replica.get_server(), 0/*high priority*/); - if (OB_FAIL(servers.push_back(server))) { - LOG_WARN("failed to push server", K(ret), K(server)); - } - } - } - for (int i = 0; OB_SUCC(ret) && i < replica_array.count(); ++i) { - const ObLSReplica &replica = replica_array.at(i); - if (replica.is_in_service() && replica.is_strong_leader() && replica.is_valid() && !replica.is_in_restore() - && (replica_array.count() == 1 || !check_replica_in_black_server_(replica, black_servers))) { - // if only has one replica. no use black server. - ObBackupServer server; - server.set(replica.get_server(), 1/*low priority*/); - if (OB_FAIL(servers.push_back(server))) { - LOG_WARN("failed to push server", K(ret), K(server)); - } - } - } - if (OB_SUCC(ret) && servers.empty()) { - ret = OB_EAGAIN; - LOG_WARN("no optional servers, retry_later", K(ret), K(*this)); - } - } - - if (OB_SUCC(ret) && OB_FAIL(set_optional_servers(servers))) { - LOG_WARN("failed to optional servers", K(ret)); - } else { - FLOG_INFO("task optional servers are:", K(*this), K(servers)); - } - return ret; -} - -bool ObBackupBuildIndexTask::check_replica_in_black_server_( - const ObLSReplica &replica, const ObIArray &black_servers) -{ - bool is_in_black_servers = false; - for (int64_t i = 0; i < black_servers.count(); ++i) { - const ObAddr &server = black_servers.at(i); - if (server == replica.get_server()) { - is_in_black_servers = true; - break; - } - } - return is_in_black_servers; -} - /* *-------------------------ObBackupCleanLSTask------------------------------ */ @@ -986,7 +784,7 @@ bool ObBackupCleanLSTask::can_execute_on_any_server() const return false; } -int ObBackupCleanLSTask::do_update_dst_and_doing_status_(common::ObMySQLProxy &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) +int ObBackupCleanLSTask::do_update_dst_and_doing_status_(common::ObISQLClient &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) { int ret = OB_SUCCESS; ObLSID ls_id(get_ls_id()); @@ -1126,19 +924,8 @@ int ObBackupDataLSMetaTask::clone(void *input_ptr, ObBackupScheduleTask *&out_ta if (OB_ISNULL(my_task)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("taks is nullptr", K(ret)); - } else if (OB_FAIL(my_task->ObBackupScheduleTask::deep_copy(*this))) { + } else if (OB_FAIL(my_task->ObBackupDataBaseTask::deep_copy(*this))) { LOG_WARN("fail to deep copy base task", K(ret)); - } else if (OB_FAIL(my_task->backup_path_.assign(backup_path_))) { - LOG_WARN("failed to assign backup path", K(ret)); - } else { - my_task->incarnation_id_ = incarnation_id_; - my_task->backup_set_id_ = backup_set_id_; - my_task->backup_type_.type_ = backup_type_.type_; - my_task->backup_date_ = backup_date_; - my_task->ls_id_ = ls_id_; - my_task->turn_id_ = turn_id_; - my_task->retry_id_ = retry_id_; - my_task->start_scn_ = start_scn_; } if (OB_SUCC(ret)) { out_task = my_task; @@ -1171,7 +958,7 @@ int ObBackupDataLSMetaTask::execute(obrpc::ObSrvRpcProxy &rpc_proxy) const arg.retry_id_ = retry_id_; arg.dst_server_ = get_dst(); arg.job_id_ = get_job_id(); - arg.start_scn_ = start_scn_; + arg.start_scn_ = backup_user_ls_scn_; if (OB_FAIL(arg.backup_path_.assign(backup_path_))) { LOG_WARN("failed to assign backup path", K(ret), K(backup_path_)); } else if (OB_FAIL(rpc_proxy.to(get_dst()).backup_meta(arg))) { diff --git a/src/rootserver/backup/ob_backup_schedule_task.h b/src/rootserver/backup/ob_backup_schedule_task.h index 923e04b05..a433b354f 100644 --- a/src/rootserver/backup/ob_backup_schedule_task.h +++ b/src/rootserver/backup/ob_backup_schedule_task.h @@ -21,6 +21,7 @@ #include "lib/net/ob_addr.h" #include "share/ob_rpc_struct.h" #include "observer/ob_server_struct.h" +#include "ob_backup_base_job.h" namespace oceanbase { @@ -29,17 +30,6 @@ namespace rootserver { class ObBackupTaskScheduler; class ObBackupTaskQueue; -class ObIBackupJobScheduler; - -enum class BackupJobType : int64_t -{ - BACKUP_DATA_JOB = 0, - VALIDATE_JOB = 1, - BACKUP_BACKUP_PIECE_JOB = 2, - BACKUP_BACKUP_DATA_JOB = 3, - BACKUP_CLEAN_JOB = 4, - BACKUP_JOB_MAX -}; class ObBackupServerStatKey final { @@ -217,7 +207,7 @@ public: virtual bool can_cross_machine_exec() { return false; }; private: // write inner table to update task dst, trace id and advnace task status to doing - virtual int do_update_dst_and_doing_status_(common::ObMySQLProxy &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) = 0; + virtual int do_update_dst_and_doing_status_(common::ObISQLClient &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) = 0; public: int build_from_res(const obrpc::ObBackupTaskRes &res, const BackupJobType &type); int build(const ObBackupScheduleTaskKey &key, const share::ObTaskId &trace_id, const share::ObBackupTaskStatus &status, const common::ObAddr &dst); @@ -266,30 +256,27 @@ private: }; // backup data task -class ObBackupDataLSTask : public ObBackupScheduleTask + +class ObBackupDataBaseTask : public ObBackupScheduleTask { public: - ObBackupDataLSTask(); - virtual ~ObBackupDataLSTask(); + ObBackupDataBaseTask(); + virtual ~ObBackupDataBaseTask() {} public: - virtual int clone(void *input_ptr, ObBackupScheduleTask *&out_task) const override; - virtual int64_t get_deep_copy_size() const override; - virtual bool can_execute_on_any_server() const override; - virtual int execute(obrpc::ObSrvRpcProxy &rpc_proxy) const override; + virtual bool can_execute_on_any_server() const final override { return false; } virtual int cancel(obrpc::ObSrvRpcProxy &rpc_proxy) const override; -private: - virtual int do_update_dst_and_doing_status_(common::ObMySQLProxy &sql_proxy, common::ObAddr &dst, - share::ObTaskId &trace_id) override; -public: - int build(const share::ObBackupJobAttr &job_attr, const share::ObBackupSetTaskAttr &set_task_attr, + virtual int build(const share::ObBackupJobAttr &job_attr, const share::ObBackupSetTaskAttr &set_task_attr, const share::ObBackupLSTaskAttr &ls_attr); + int deep_copy(const ObBackupDataBaseTask &that); int set_optional_servers_(const ObIArray &black_servers); - - INHERIT_TO_STRING_KV("ObBackupScheduleTask", ObBackupScheduleTask, K_(incarnation_id), K_(backup_set_id), - K_(backup_type), K_(backup_date), K_(ls_id), K_(turn_id), K_(retry_id), K_(start_scn), K_(backup_path), - K_(backup_status)); private: + virtual int do_update_dst_and_doing_status_(common::ObISQLClient &sql_proxy, common::ObAddr &dst, + share::ObTaskId &trace_id) final override; bool check_replica_in_black_server_(const share::ObLSReplica &replica, const ObIArray &black_servers); +public: + INHERIT_TO_STRING_KV("ObBackupScheduleTask", ObBackupScheduleTask, K_(incarnation_id), K_(backup_set_id), + K_(backup_type), K_(backup_date), K_(ls_id), K_(turn_id), K_(retry_id), K_(start_scn), + K_(backup_user_ls_scn), K_(end_scn), K_(backup_path), K_(backup_status)); protected: int64_t incarnation_id_; int64_t backup_set_id_; @@ -299,82 +286,65 @@ protected: int64_t turn_id_; int64_t retry_id_; share::SCN start_scn_; - share::ObBackupPathString backup_path_; - share::ObBackupStatus backup_status_; -private: - DISALLOW_COPY_AND_ASSIGN(ObBackupDataLSTask); -}; - -class ObBackupComplLogTask : public ObBackupScheduleTask -{ -public: - ObBackupComplLogTask(); - virtual ~ObBackupComplLogTask(); -public: - virtual int clone(void *input_ptr, ObBackupScheduleTask *&out_task) const override; - virtual int64_t get_deep_copy_size() const override; - // interfaces related to execution - virtual bool can_execute_on_any_server() const override; - virtual int execute(obrpc::ObSrvRpcProxy &rpc_proxy) const override; - virtual int cancel(obrpc::ObSrvRpcProxy &rpc_proxy) const override; -private: - virtual int do_update_dst_and_doing_status_(common::ObMySQLProxy &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) override; -public: - int build(const share::ObBackupJobAttr &job_attr, const share::ObBackupSetTaskAttr &set_task_attr, const share::ObBackupLSTaskAttr &ls_attr); - -private: - int calc_start_replay_scn_(const share::ObBackupJobAttr &job_attr, const share::ObBackupSetTaskAttr &set_task_attr, - const share::ObBackupLSTaskAttr &ls_attr, share::SCN &scn); - - INHERIT_TO_STRING_KV("ObBackupScheduleTask", ObBackupScheduleTask, K_(incarnation_id), K_(backup_set_id), K_(backup_type), K_(backup_date), - K_(ls_id), K_(start_scn), K_(end_scn), K_(backup_path), K_(backup_status)); -private: - int64_t incarnation_id_; - int64_t backup_set_id_; - share::ObBackupType backup_type_; - int64_t backup_date_; - share::ObLSID ls_id_; - share::SCN start_scn_; + share::SCN backup_user_ls_scn_; share::SCN end_scn_; share::ObBackupPathString backup_path_; share::ObBackupStatus backup_status_; +private: + DISALLOW_COPY_AND_ASSIGN(ObBackupDataBaseTask); +}; + +class ObBackupDataLSTask : public ObBackupDataBaseTask +{ +public: + ObBackupDataLSTask() {} + virtual ~ObBackupDataLSTask() {} + virtual int clone(void *input_ptr, ObBackupScheduleTask *&out_task) const override; + virtual int64_t get_deep_copy_size() const override; + virtual int execute(obrpc::ObSrvRpcProxy &rpc_proxy) const override; +private: + DISALLOW_COPY_AND_ASSIGN(ObBackupDataLSTask); +}; + +class ObBackupComplLogTask final: public ObBackupDataBaseTask +{ +public: + ObBackupComplLogTask() {} + virtual ~ObBackupComplLogTask() {} + virtual int clone(void *input_ptr, ObBackupScheduleTask *&out_task) const override; + virtual int64_t get_deep_copy_size() const override; + virtual int execute(obrpc::ObSrvRpcProxy &rpc_proxy) const override; + virtual int build(const share::ObBackupJobAttr &job_attr, const share::ObBackupSetTaskAttr &set_task_attr, + const share::ObBackupLSTaskAttr &ls_attr); +private: + int calc_start_replay_scn_(const share::ObBackupJobAttr &job_attr, const share::ObBackupSetTaskAttr &set_task_attr, + const share::ObBackupLSTaskAttr &ls_attr, share::SCN &scn); private: DISALLOW_COPY_AND_ASSIGN(ObBackupComplLogTask); }; -class ObBackupBuildIndexTask : public ObBackupScheduleTask +class ObBackupBuildIndexTask final : public ObBackupDataBaseTask { public: - ObBackupBuildIndexTask(); - virtual ~ObBackupBuildIndexTask(); -public: + ObBackupBuildIndexTask() {} + virtual ~ObBackupBuildIndexTask() {} virtual int clone(void *input_ptr, ObBackupScheduleTask *&out_task) const override; virtual int64_t get_deep_copy_size() const override; - // interfaces related to execution - virtual bool can_execute_on_any_server() const override; virtual int execute(obrpc::ObSrvRpcProxy &rpc_proxy) const override; - virtual int cancel(obrpc::ObSrvRpcProxy &rpc_proxy) const override; private: - virtual int do_update_dst_and_doing_status_(common::ObMySQLProxy &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) override; - int set_optional_servers_(const ObIArray &black_servers); -private: - bool check_replica_in_black_server_(const share::ObLSReplica &replica, const ObIArray &black_servers); + DISALLOW_COPY_AND_ASSIGN(ObBackupBuildIndexTask); +}; + +class ObBackupDataLSMetaTask final : public ObBackupDataLSTask +{ public: - int build(const share::ObBackupJobAttr &job_attr, const share::ObBackupSetTaskAttr &set_task_attr, const share::ObBackupLSTaskAttr &ls_attr); - INHERIT_TO_STRING_KV("ObBackupScheduleTask", ObBackupScheduleTask, K_(incarnation_id), K_(backup_set_id), K_(backup_type), K_(backup_date), - K_(turn_id), K_(start_turn_id), K_(backup_path), K_(backup_status)); + ObBackupDataLSMetaTask() {} + virtual ~ObBackupDataLSMetaTask() {} + virtual int clone(void *input_ptr, ObBackupScheduleTask *&out_task) const override; + virtual int64_t get_deep_copy_size() const override; + virtual int execute(obrpc::ObSrvRpcProxy &rpc_proxy) const override; private: - int64_t incarnation_id_; - int64_t backup_set_id_; - share::ObBackupType backup_type_; - int64_t backup_date_; - int64_t turn_id_; - int64_t retry_id_; - int64_t start_turn_id_; - share::ObBackupPathString backup_path_; - share::ObBackupStatus backup_status_; -private: - DISALLOW_COPY_AND_ASSIGN(ObBackupBuildIndexTask); + DISALLOW_COPY_AND_ASSIGN(ObBackupDataLSMetaTask); }; class ObBackupCleanLSTask : public ObBackupScheduleTask @@ -390,7 +360,7 @@ public: virtual int execute(obrpc::ObSrvRpcProxy &rpc_proxy) const override; virtual int cancel(obrpc::ObSrvRpcProxy &rpc_proxy) const override; private: - virtual int do_update_dst_and_doing_status_(common::ObMySQLProxy &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) override; + virtual int do_update_dst_and_doing_status_(common::ObISQLClient &sql_proxy, common::ObAddr &dst, share::ObTaskId &trace_id) final override; int set_optional_servers_(); public: int build(const share::ObBackupCleanTaskAttr &task_attr, const share::ObBackupCleanLSTaskAttr &ls_attr); @@ -409,18 +379,6 @@ private: DISALLOW_COPY_AND_ASSIGN(ObBackupCleanLSTask); }; -class ObBackupDataLSMetaTask : public ObBackupDataLSTask -{ -public: - ObBackupDataLSMetaTask() {} - virtual ~ObBackupDataLSMetaTask() {} - virtual int clone(void *input_ptr, ObBackupScheduleTask *&out_task) const override; - virtual int64_t get_deep_copy_size() const override; - virtual int execute(obrpc::ObSrvRpcProxy &rpc_proxy) const override; -private: - DISALLOW_COPY_AND_ASSIGN(ObBackupDataLSMetaTask); -}; - } // namespace rootserver } // end namespace oceanbase #endif // OCEANBASE_ROOTSERVER_OB_BACKUP_SCHEDULE_TASK_H_ diff --git a/src/rootserver/backup/ob_backup_service.cpp b/src/rootserver/backup/ob_backup_service.cpp index 2b1f5ab5e..c2326dfb0 100644 --- a/src/rootserver/backup/ob_backup_service.cpp +++ b/src/rootserver/backup/ob_backup_service.cpp @@ -26,214 +26,183 @@ using namespace share; namespace rootserver { - -int64_t ObBackupMgrIdling::get_idle_interval_us() -{ - const int64_t backup_check_interval = GCONF._backup_idle_time; - return backup_check_interval; -} - -ObBackupService::ObBackupService() - : is_inited_(false), - mgr_mtx_(), - can_schedule_(false), - idling_(stop_), - backup_data_scheduler_(), - backup_clean_scheduler_(), - backup_auto_obsolete_delete_trigger_(), - jobs_(), - triggers_(), - task_scheduler_(nullptr), - lease_service_(nullptr) -{ -} +/* +*----------------------------- ObBackupService ----------------------------- +*/ int ObBackupService::init( common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, schema::ObMultiVersionSchemaService &schema_service, - ObBackupLeaseService &lease_service, + share::ObLocationService &loacation_service, ObBackupTaskScheduler &task_scheduler) { int ret = OB_SUCCESS; - const int64_t backup_mgr_thread_cnt = 1; + uint64_t tenant_id = MTL_ID(); if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("backup mgr already inited", K(ret)); - } else if (OB_FAIL(backup_data_scheduler_.init( - sql_proxy, rpc_proxy, schema_service, lease_service, task_scheduler, *this))) { - LOG_WARN("fail to init backup data scheduler", K(ret)); - } else if (OB_FAIL(register_job_(&backup_data_scheduler_))) { - LOG_WARN("fail to regist job", K(ret), "job_type", backup_data_scheduler_.get_job_type()); - } else if (OB_FAIL(backup_clean_scheduler_.init( - sql_proxy, rpc_proxy, schema_service, lease_service, task_scheduler, *this))) { - LOG_WARN("fail to init backup clean scheduler", K(ret)); - } else if (OB_FAIL(register_job_(&backup_clean_scheduler_))) { - LOG_WARN("fail to regist job", K(ret), "job_type", backup_clean_scheduler_.get_job_type()); - } else if (OB_FAIL(backup_auto_obsolete_delete_trigger_.init( - sql_proxy, rpc_proxy, schema_service, lease_service, task_scheduler, *this))) { - LOG_WARN("fail to init backup auto obsolete delete trigger", K(ret)); - } else if (OB_FAIL(register_trigger_(&backup_auto_obsolete_delete_trigger_))) { - LOG_WARN("fail to regist job", K(ret), "job_type", backup_auto_obsolete_delete_trigger_.get_trigger_type()); - } else if (OB_FAIL(create(backup_mgr_thread_cnt, "BackupMgr"))) { - LOG_WARN("create thread failed", K(ret), K(backup_mgr_thread_cnt)); + } else if (OB_FAIL(task_scheduler.register_backup_srv(*this))) { + LOG_WARN("failed to register backup srv", K(ret)); + } else if (OB_FAIL(sub_init(sql_proxy, rpc_proxy, schema_service, loacation_service, task_scheduler))) { + LOG_WARN("failed to do sub init", K(ret)); } else { + tenant_id_ = tenant_id; task_scheduler_ = &task_scheduler; - lease_service_ = &lease_service; + schema_service_ = &schema_service; is_inited_ = true; } return ret; } -void ObBackupService::stop() +void ObBackupService::run2() { int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else { - ObRsReentrantThread::stop(); - idling_.wakeup(); - } - LOG_INFO("Backup mgr stop", K(ret)); -} - -int ObBackupService::register_job_(ObIBackupJobScheduler *new_job) -{ - int ret = OB_SUCCESS; - ObMutexGuard guard(mgr_mtx_); - if (nullptr == new_job) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("new job is nullptr", K(ret)); - } else if (OB_FAIL(jobs_.push_back(new_job))) { - LOG_WARN("regist job error", K(ret)); - } else { - BackupJobType job_type = new_job->get_job_type(); - LOG_INFO("backup mgr register job", K(job_type)); - } - return ret; -} - -int ObBackupService::register_trigger_(ObIBackupTrigger *new_trigger) -{ - int ret = OB_SUCCESS; - ObMutexGuard guard(mgr_mtx_); - if (nullptr == new_trigger) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("new trigger is nullptr", K(ret)); - } else if (OB_FAIL(triggers_.push_back(new_trigger))) { - LOG_WARN("regist trigger error", K(ret)); - } else { - BackupTriggerType trigger_type = new_trigger->get_trigger_type(); - LOG_INFO("backup mgr register trigger", K(trigger_type)); - } - return ret; -} - -int ObBackupService::idle() const -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (OB_FAIL(idling_.idle())) { - LOG_WARN("idle failed", K(ret)); - } - return ret; -} - -void ObBackupService::wakeup() -{ - int ret = OB_SUCCESS; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else { - idling_.wakeup(); - } -} - -int ObBackupService::get_job(const BackupJobType &type, ObIBackupJobScheduler *&new_job) -{ - int ret = OB_SUCCESS; - new_job = nullptr; - ObMutexGuard guard(mgr_mtx_); - for (int i = 0; i < jobs_.count(); ++i) { - ObIBackupJobScheduler *tmp_job = jobs_.at(i); - if (type == tmp_job->get_job_type()) { - new_job = jobs_.at(i); - break; - } - } - if (nullptr == new_job) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("job not exist", K(ret), K(type)); - } - return ret; -} - -void ObBackupService::start_trigger_(int64_t &last_trigger_ts) -{ - int ret = OB_SUCCESS; - const int64_t now_ts = ObTimeUtility::current_time(); -#ifdef ERRSIM - const int64_t MAX_TRIGGET_TIME_INTERVAL = GCONF.trigger_auto_backup_delete_interval; -#else - const int64_t MAX_TRIGGET_TIME_INTERVAL = 60 * 60 * 1000 * 1000L;// 1h -#endif - if (now_ts > (last_trigger_ts + MAX_TRIGGET_TIME_INTERVAL)) { - for (int64_t i = 0; i < triggers_.count(); ++i) { - ObIBackupTrigger *trigger = triggers_.at(i); - if (OB_FAIL(trigger->process())) { // status move forward, generate task and add task - LOG_WARN("job status move forward failed", K(ret), K(*trigger)); - } - } - last_trigger_ts = now_ts; - } -} - -void ObBackupService::start_scheduler_() -{ - int ret = OB_SUCCESS; - for (int64_t i = 0; i < jobs_.count(); ++i) { - ObIBackupJobScheduler *job = jobs_.at(i); - if (OB_FAIL(job->process())) { // status move forward, generate task and add task - LOG_WARN("job status move forward failed", K(ret), K(*job)); - } - } -} -void ObBackupService::run3() -{ - int ret = OB_SUCCESS; - LOG_INFO("backup mgr start"); + LOG_INFO("[backupService]backup service start"); int64_t last_trigger_ts = ObTimeUtility::current_time(); - while (!stop_) { - if (can_schedule()) { - if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("fail to check lease", K(ret)); + while (!has_set_stop()) { + set_idle_time(ObBackupBaseService::OB_MIDDLE_IDLE_TIME); + ObCurTraceId::init(GCONF.self_addr_); + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObTenantSchema *tenant_schema = NULL; + if (OB_FAIL(schema_service_->get_tenant_schema_guard(tenant_id_, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id_, tenant_schema))) { + LOG_WARN("failed to get schema ", KR(ret), K(tenant_id_)); + } else if (tenant_schema->is_normal()) { + if (can_schedule()) { + process(last_trigger_ts); } else { - LOG_INFO("start scheduler"); - ObCurTraceId::init(GCONF.self_addr_); - start_trigger_(last_trigger_ts); - start_scheduler_(); + task_scheduler_->wakeup(); + wakeup(); } - } else { - task_scheduler_->wakeup(); - wakeup(); - } - - if (OB_FAIL(idle())) { - LOG_WARN("idle failed", K(ret)); - } else { - continue; } + idle(); } - LOG_INFO("backup mgr stop"); + LOG_INFO("[backupService]backup service stop"); } -int ObBackupService::handle_backup_database(const obrpc::ObBackupDatabaseArg &arg) +bool ObBackupService::can_schedule() +{ + bool can = false; + if (is_sys_tenant(tenant_id_)) { + // sys tenant has no task need be reload by backup task scheduler, so no need to wait reload, always return can + can = true; + } else { + can = ATOMIC_LOAD(&can_schedule_); + } + return can; +} + +void ObBackupService::enable_backup() +{ + ATOMIC_SET(&can_schedule_, true); +} + +void ObBackupService::disable_backup() +{ + ATOMIC_SET(&can_schedule_, false); +} + +void ObBackupService::destroy() +{ + ObBackupBaseService::destroy(); + task_scheduler_ = nullptr; + is_inited_ = false; +} + +/* +*----------------------------- ObBackupDataService ----------------------------- +*/ + +int ObBackupDataService::mtl_init(ObBackupDataService *&srv) { int ret = OB_SUCCESS; + common::ObMySQLProxy *sql_proxy = nullptr; + obrpc::ObSrvRpcProxy *rpc_proxy = nullptr; + share::schema::ObMultiVersionSchemaService *schema_service = nullptr; + ObBackupTaskScheduler *backup_task_scheduler = nullptr; + share::ObLocationService *location_service = nullptr; + if (OB_ISNULL(sql_proxy = GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql_proxy should not be NULL", K(ret), KP(sql_proxy)); + } else if (OB_ISNULL(rpc_proxy = GCTX.srv_rpc_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rpc_proxy should not be NULL", K(ret), KP(rpc_proxy)); + } else if (OB_ISNULL(schema_service = GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema_service should not be NULL", K(ret), KP(schema_service)); + } else if (OB_ISNULL(backup_task_scheduler = MTL(ObBackupTaskScheduler *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup_task_scheduler should not be NULL", K(ret), KP(backup_task_scheduler)); + } else if (OB_ISNULL(location_service = GCTX.location_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("location_service should not be NULL", K(ret), KP(backup_task_scheduler)); + } else if (OB_FAIL(srv->init(*sql_proxy, *rpc_proxy, *schema_service, *location_service, *backup_task_scheduler))) { + LOG_WARN("fail to ini backup service"); + } + return ret; +} + +int ObBackupDataService::sub_init( + common::ObMySQLProxy &sql_proxy, + obrpc::ObSrvRpcProxy &rpc_proxy, + schema::ObMultiVersionSchemaService &schema_service, + share::ObLocationService &loacation_service, + ObBackupTaskScheduler &task_scheduler) +{ + int ret = OB_SUCCESS; + uint64_t tenant_id = MTL_ID(); + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("backup mgr already inited", K(ret)); + } else if (OB_FAIL(backup_data_scheduler_.init( + tenant_id, sql_proxy, rpc_proxy, schema_service, task_scheduler, *this))) { + LOG_WARN("fail to init backup data scheduler", K(ret)); + } else if (OB_FAIL(create("BackupDataSrv", *this, ObWaitEventIds::BACKUP_DATA_SERVICE_COND_WAIT))) { + LOG_WARN("failed to create backup data service", K(ret)); + } + return ret; +} + +int ObBackupDataService::process(int64_t &last_schedule_ts) { + int ret = OB_SUCCESS; + UNUSED(last_schedule_ts); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(backup_data_scheduler_.process())) { + LOG_WARN("failed to process backup data", K(ret)); + } + return ret; +} + +ObIBackupJobScheduler *ObBackupDataService::get_scheduler(const BackupJobType &type) +{ + ObIBackupJobScheduler *ptr = nullptr; + if (BackupJobType::BACKUP_DATA_JOB == type) { + ptr = &backup_data_scheduler_; + } + return ptr; +} + +int ObBackupDataService::get_need_reload_task( + common::ObIAllocator &allocator, common::ObIArray &tasks) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(backup_data_scheduler_.get_need_reload_task(allocator, tasks))) { + LOG_WARN("failed to get need reload task", K(ret)); + } + return ret; +} + +int ObBackupDataService::handle_backup_database(const obrpc::ObBackupDatabaseArg &arg) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); @@ -248,7 +217,7 @@ int ObBackupService::handle_backup_database(const obrpc::ObBackupDatabaseArg &ar return ret; } -int ObBackupService::handle_backup_database_cancel(const uint64_t tenant_id, const ObIArray &managed_tenant_ids) +int ObBackupDataService::handle_backup_database_cancel(const uint64_t tenant_id, const ObIArray &managed_tenant_ids) { int ret = OB_SUCCESS; if (IS_NOT_INIT) { @@ -265,7 +234,118 @@ int ObBackupService::handle_backup_database_cancel(const uint64_t tenant_id, con return ret; } -int ObBackupService::handle_backup_delete(const obrpc::ObBackupCleanArg &arg) +/* +*----------------------------- ObBackupCleanService ----------------------------- +*/ + + +int ObBackupCleanService::mtl_init(ObBackupCleanService *&srv) +{ + int ret = OB_SUCCESS; + common::ObMySQLProxy *sql_proxy = nullptr; + obrpc::ObSrvRpcProxy *rpc_proxy = nullptr; + share::schema::ObMultiVersionSchemaService *schema_service = nullptr; + ObBackupTaskScheduler *backup_task_scheduler = nullptr; + share::ObLocationService *location_service = nullptr; + if (OB_ISNULL(sql_proxy = GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql_proxy should not be NULL", K(ret), KP(sql_proxy)); + } else if (OB_ISNULL(rpc_proxy = GCTX.srv_rpc_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rpc_proxy should not be NULL", K(ret), KP(rpc_proxy)); + } else if (OB_ISNULL(schema_service = GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema_service should not be NULL", K(ret), KP(schema_service)); + } else if (OB_ISNULL(backup_task_scheduler = MTL(ObBackupTaskScheduler *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup_task_scheduler should not be NULL", K(ret), KP(backup_task_scheduler)); + } else if (OB_ISNULL(location_service = GCTX.location_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("location_service should not be NULL", K(ret), KP(backup_task_scheduler)); + } else if (OB_FAIL(srv->init(*sql_proxy, *rpc_proxy, *schema_service, *location_service, *backup_task_scheduler))) { + LOG_WARN("fail to ini backup service"); + } + return ret; +} + +int ObBackupCleanService::sub_init( + common::ObMySQLProxy &sql_proxy, + obrpc::ObSrvRpcProxy &rpc_proxy, + schema::ObMultiVersionSchemaService &schema_service, + share::ObLocationService &loacation_service, + ObBackupTaskScheduler &task_scheduler) +{ + int ret = OB_SUCCESS; + uint64_t tenant_id = MTL_ID(); + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("backup mgr already inited", K(ret)); + } else if (OB_FAIL(backup_clean_scheduler_.init( + tenant_id, sql_proxy, rpc_proxy, schema_service, task_scheduler, *this))) { + LOG_WARN("fail to init backup clean scheduler", K(ret)); + } else if (OB_FAIL(register_job_(&backup_clean_scheduler_))) { + LOG_WARN("fail to regist job", K(ret), "job_type", backup_clean_scheduler_.get_job_type()); + } else if (OB_FAIL(backup_auto_obsolete_delete_trigger_.init(tenant_id, + sql_proxy, rpc_proxy, schema_service, task_scheduler, *this))) { + LOG_WARN("fail to init backup data scheduler", K(ret)); + } else if (OB_FAIL(register_trigger_(&backup_auto_obsolete_delete_trigger_))) { + LOG_WARN("fail to regist job", K(ret), "job_type", backup_auto_obsolete_delete_trigger_.get_trigger_type()); + } else if (OB_FAIL(create("BackupCleanSrv", *this, ObWaitEventIds::BACKUP_CLEAN_SERVICE_COND_WAIT))) { + LOG_WARN("create BackupService thread failed", K(ret)); + } + return ret; +} + +int ObBackupCleanService::process(int64_t &last_schedule_ts) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else { + process_trigger_(last_schedule_ts); + process_scheduler_(); + } + return ret; +} + +ObIBackupJobScheduler *ObBackupCleanService::get_scheduler(const BackupJobType &type) +{ + ObIBackupJobScheduler *ptr = nullptr; + int ret = OB_SUCCESS; + bool find_job = false; + ARRAY_FOREACH(jobs_, i) { + ObIBackupJobScheduler *job = jobs_.at(i); + if (nullptr == job) { + } else if (type == job->get_job_type()) { + ptr = job; + } + } + return ptr; +} + +int ObBackupCleanService::get_need_reload_task( + common::ObIAllocator &allocator, common::ObIArray &tasks) +{ + int ret = OB_SUCCESS; + ObSArray need_reload_tasks; + for (int i = 0; OB_SUCC(ret) && i < jobs_.count(); ++i) { + ObIBackupJobScheduler *job = jobs_.at(i); + need_reload_tasks.reset(); + if (nullptr == job) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("nullptr backup job", K(ret)); + } else if (OB_FAIL(job->get_need_reload_task(allocator, need_reload_tasks))) { + LOG_WARN("failed to get need reload task", K(ret), K(*job)); + } else if (need_reload_tasks.empty()) { + } else if (OB_FAIL(append(tasks, need_reload_tasks))) { + LOG_WARN("failed to append tasks", K(ret), K(need_reload_tasks)); + } + } + return ret; +} + +int ObBackupCleanService::handle_backup_delete(const obrpc::ObBackupCleanArg &arg) { int ret = OB_SUCCESS; @@ -313,7 +393,7 @@ int ObBackupService::handle_backup_delete(const obrpc::ObBackupCleanArg &arg) } -int ObBackupService::handle_delete_policy(const obrpc::ObDeletePolicyArg &arg) +int ObBackupCleanService::handle_delete_policy(const obrpc::ObDeletePolicyArg &arg) { int ret = OB_SUCCESS; @@ -353,7 +433,7 @@ int ObBackupService::handle_delete_policy(const obrpc::ObDeletePolicyArg &arg) return ret; } -int ObBackupService::handle_backup_delete_obsolete(const obrpc::ObBackupCleanArg &arg) +int ObBackupCleanService::handle_backup_delete_obsolete(const obrpc::ObBackupCleanArg &arg) { int ret = OB_SUCCESS; if (IS_NOT_INIT) { @@ -368,42 +448,67 @@ int ObBackupService::handle_backup_delete_obsolete(const obrpc::ObBackupCleanArg return ret; } -int ObBackupService::get_need_reload_task(common::ObIAllocator &allocator, common::ObIArray &tasks) + +int ObBackupCleanService::register_job_(ObIBackupJobScheduler *new_job) { int ret = OB_SUCCESS; - ObMutexGuard guard(mgr_mtx_); - ObSArray need_reload_tasks; - for (int i = 0; OB_SUCC(ret) && i < jobs_.count(); ++i) { - ObIBackupJobScheduler *job = jobs_.at(i); - need_reload_tasks.reset(); - if (nullptr == job) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("nullptr backup job", K(ret)); - } else if (OB_FAIL(job->get_need_reload_task(allocator, need_reload_tasks))) { - LOG_WARN("failed to get need reload task", K(ret), K(*job)); - } else if (need_reload_tasks.empty()) { - } else if (OB_FAIL(append(tasks, need_reload_tasks))) { - LOG_WARN("failed to append tasks", K(ret), K(need_reload_tasks)); - } + if (nullptr == new_job) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("new job is nullptr", K(ret)); + } else if (OB_FAIL(jobs_.push_back(new_job))) { + LOG_WARN("regist job error", K(ret)); + } else { + BackupJobType job_type = new_job->get_job_type(); + LOG_INFO("backup mgr register job", K(job_type)); } return ret; } -bool ObBackupService::can_schedule() +int ObBackupCleanService::register_trigger_(ObIBackupTrigger *new_trigger) { - bool can = ATOMIC_LOAD(&can_schedule_); - return can; + int ret = OB_SUCCESS; + if (nullptr == new_trigger) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("new trigger is nullptr", K(ret)); + } else if (OB_FAIL(triggers_.push_back(new_trigger))) { + LOG_WARN("regist trigger error", K(ret)); + } else { + BackupTriggerType trigger_type = new_trigger->get_trigger_type(); + LOG_INFO("backup mgr register trigger", K(trigger_type)); + } + return ret; } -void ObBackupService::enable_backup() +void ObBackupCleanService::process_trigger_(int64_t &last_trigger_ts) { - ATOMIC_SET(&can_schedule_, true); + int tmp_ret = OB_SUCCESS; + const int64_t now_ts = ObTimeUtility::current_time(); +#ifdef ERRSIM + const int64_t MAX_TRIGGET_TIME_INTERVAL = GCONF.trigger_auto_backup_delete_interval; +#else + const int64_t MAX_TRIGGET_TIME_INTERVAL = 60 * 60 * 1000 * 1000L;// 1h +#endif + if (now_ts > (last_trigger_ts + MAX_TRIGGET_TIME_INTERVAL)) { + for (int64_t i = 0; i < triggers_.count(); ++i) { + ObIBackupTrigger *trigger = triggers_.at(i); + if (OB_SUCCESS != (tmp_ret = trigger->process())) { // status move forward, generate task and add task + LOG_WARN_RET(tmp_ret, "job status move forward failed", K(*trigger)); + } + } + last_trigger_ts = now_ts; + } } -void ObBackupService::disable_backup() +void ObBackupCleanService::process_scheduler_() { - ATOMIC_SET(&can_schedule_, false); + int tmp_ret = OB_SUCCESS; + for (int64_t i = 0; i < jobs_.count(); ++i) { + ObIBackupJobScheduler *job = jobs_.at(i); + if (OB_SUCCESS != (tmp_ret = job->process())) { // status move forward, generate task and add task + LOG_WARN_RET(tmp_ret, "job status move forward failed", K(*job)); + } + } } } // namespace rootserver -} // namespace oceanbase \ No newline at end of file +} // namespace oceanbase diff --git a/src/rootserver/backup/ob_backup_service.h b/src/rootserver/backup/ob_backup_service.h index ca5c86a96..d40f7b508 100644 --- a/src/rootserver/backup/ob_backup_service.h +++ b/src/rootserver/backup/ob_backup_service.h @@ -13,69 +13,119 @@ #ifndef OCEANBASE_ROOTSERVER_OB_BACKUP_SERVICE_H_ #define OCEANBASE_ROOTSERVER_OB_BACKUP_SERVICE_H_ -#include "ob_backup_task_scheduler.h" +#include "ob_backup_base_service.h" #include "ob_backup_data_scheduler.h" -#include "ob_backup_base_job.h" -#include "rootserver/ob_thread_idling.h" -#include "rootserver/ob_rs_reentrant_thread.h" #include "ob_backup_clean_scheduler.h" namespace oceanbase { namespace rootserver { -class ObBackupMgrIdling : public ObThreadIdling +class ObBackupTaskScheduler; +// the backup service who relay on ObBackupTaskScheduler must inherit this. +class ObBackupService : public ObBackupBaseService { public: - explicit ObBackupMgrIdling(volatile bool &stop) : ObThreadIdling(stop) {} - virtual int64_t get_idle_interval_us(); -}; - -class ObBackupService : public ObRsReentrantThread -{ -public: - ObBackupService(); + ObBackupService(): is_inited_(false), tenant_id_(OB_INVALID_TENANT_ID), can_schedule_(false), task_scheduler_(nullptr), + schema_service_(nullptr) {} virtual ~ObBackupService() {}; int init(common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, - share::schema::ObMultiVersionSchemaService &schema_service, ObBackupLeaseService &lease_service, - ObBackupTaskScheduler &task_scheduler); - virtual void run3() override; - virtual int blocking_run() { BLOCKING_RUN_IMPLEMENT(); } - void stop(); - void wakeup(); - int idle() const; + share::schema::ObMultiVersionSchemaService &schema_service, + share::ObLocationService &loacation_service, + ObBackupTaskScheduler &task_scheduler); + void run2() override final; + virtual int process(int64_t &last_schedule_ts) = 0; + void destroy() override final; public: - int handle_backup_database(const obrpc::ObBackupDatabaseArg &arg); - int handle_backup_database_cancel(const uint64_t tenant_id, const ObIArray &managed_tenant_ids); - int handle_backup_delete(const obrpc::ObBackupCleanArg &arg); - int handle_delete_policy(const obrpc::ObDeletePolicyArg &arg); - int handle_backup_delete_obsolete(const obrpc::ObBackupCleanArg &arg); - common::ObSEArray &get_jobs() { return jobs_; } - virtual int get_job(const BackupJobType &type, ObIBackupJobScheduler *&new_job); - int get_need_reload_task(common::ObIAllocator &allocator, common::ObIArray &tasks); + virtual ObIBackupJobScheduler *get_scheduler(const BackupJobType &type) = 0; + virtual int get_need_reload_task( + common::ObIAllocator &allocator, common::ObIArray &tasks) = 0; + + virtual int switch_to_leader() override { disable_backup(); return ObBackupBaseService::switch_to_leader(); } + virtual int resume_leader() override { disable_backup(); return ObBackupBaseService::resume_leader(); } + + // called by ObBackupTaskScheduler. + // if ObBackupTaskScheduler reload ls task succeed, call enable_backup. + // otherwise call disable_backup(). void disable_backup(); void enable_backup(); bool can_schedule(); + TO_STRING_KV(K_(tenant_id), K_(can_schedule)) +protected: + virtual int sub_init(common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, + share::schema::ObMultiVersionSchemaService &schema_service, + share::ObLocationService &loacation_service, + ObBackupTaskScheduler &task_scheduler) = 0; +protected: + bool is_inited_; + uint64_t tenant_id_; + bool can_schedule_; + ObBackupTaskScheduler *task_scheduler_; + share::schema::ObMultiVersionSchemaService *schema_service_; +private: + DISALLOW_COPY_AND_ASSIGN(ObBackupService); +}; + +class ObBackupDataService final : public ObBackupService +{ +public: + ObBackupDataService(): ObBackupService(), backup_data_scheduler_() {} + virtual ~ObBackupDataService() {} + static int mtl_init(ObBackupDataService *&srv); + int process(int64_t &last_schedule_ts) override; + + ObIBackupJobScheduler *get_scheduler(const BackupJobType &type); + int get_need_reload_task( + common::ObIAllocator &allocator, common::ObIArray &tasks) override; + + int handle_backup_database(const obrpc::ObBackupDatabaseArg &arg); + int handle_backup_database_cancel(const uint64_t tenant_id, const ObIArray &managed_tenant_ids); +private: + int sub_init(common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, + share::schema::ObMultiVersionSchemaService &schema_service, share::ObLocationService &loacation_service, + ObBackupTaskScheduler &task_scheduler) override; +private: + ObBackupDataScheduler backup_data_scheduler_; + DISALLOW_COPY_AND_ASSIGN(ObBackupDataService); +}; + +class ObBackupCleanService final : public ObBackupService +{ +public: + ObBackupCleanService() : ObBackupService(), backup_clean_scheduler_(), backup_auto_obsolete_delete_trigger_(), + jobs_(), triggers_() {} + virtual ~ObBackupCleanService() {} + static int mtl_init(ObBackupCleanService *&srv); + int process(int64_t &last_schedule_ts) override; + + ObIBackupJobScheduler *get_scheduler(const BackupJobType &type); + int get_need_reload_task( + common::ObIAllocator &allocator, common::ObIArray &tasks) override; + + int handle_backup_delete(const obrpc::ObBackupCleanArg &arg); + int handle_delete_policy(const obrpc::ObDeletePolicyArg &arg); + int handle_backup_delete_obsolete(const obrpc::ObBackupCleanArg &arg); +private: + virtual int sub_init(common::ObMySQLProxy &sql_proxy, obrpc::ObSrvRpcProxy &rpc_proxy, + share::schema::ObMultiVersionSchemaService &schema_service, + share::ObLocationService &loacation_service, + ObBackupTaskScheduler &task_scheduler) override; + private: int register_job_(ObIBackupJobScheduler *new_job); int register_trigger_(ObIBackupTrigger *new_trigger); - void start_trigger_(int64_t &last_trigger_ts); - void start_scheduler_(); + void process_trigger_(int64_t &last_trigger_ts); + void process_scheduler_(); + private: - bool is_inited_; - lib::ObMutex mgr_mtx_; - bool can_schedule_; - mutable ObBackupMgrIdling idling_; - ObBackupDataScheduler backup_data_scheduler_; ObBackupCleanScheduler backup_clean_scheduler_; ObBackupAutoObsoleteDeleteTrigger backup_auto_obsolete_delete_trigger_; common::ObSEArray jobs_; common::ObSEArray triggers_; - ObBackupTaskScheduler *task_scheduler_; - ObBackupLeaseService *lease_service_; -private: - DISALLOW_COPY_AND_ASSIGN(ObBackupService); + DISALLOW_COPY_AND_ASSIGN(ObBackupCleanService); }; + + } // end namespace rootserver } // namespace oceanbase -#endif // OCEANBASE_ROOTSERVER_OB_BACKUP_SERVICE_H_ \ No newline at end of file +#endif // OCEANBASE_ROOTSERVER_OB_BACKUP_SERVICE_H_ diff --git a/src/rootserver/backup/ob_backup_task_scheduler.cpp b/src/rootserver/backup/ob_backup_task_scheduler.cpp index f455978d5..7492700bc 100644 --- a/src/rootserver/backup/ob_backup_task_scheduler.cpp +++ b/src/rootserver/backup/ob_backup_task_scheduler.cpp @@ -14,6 +14,7 @@ #include "ob_backup_task_scheduler.h" #include "ob_backup_service.h" +#include "rootserver/ob_root_service.h" #include "lib/lock/ob_mutex.h" #include "lib/stat/ob_diagnose_info.h" #include "lib/profile/ob_trace_id.h" @@ -22,8 +23,14 @@ #include "share/ob_rpc_struct.h" #include "rootserver/ob_rs_event_history_table_operator.h" #include "share/ob_srv_rpc_proxy.h" -#include "share/ob_all_server_tracer.h" +#include "share/ob_zone_table_operation.h" +#include "share/ob_zone_info.h" +#include "share/ob_unit_table_operator.h" +#include "share/backup/ob_backup_server_mgr.h" +#include "share/ob_srv_rpc_proxy.h" + namespace oceanbase + { using namespace common; using namespace lib; @@ -35,18 +42,15 @@ ObBackupTaskSchedulerQueue::ObBackupTaskSchedulerQueue() : is_inited_(false), mutex_(common::ObLatchIds::BACKUP_LOCK), max_size_(0), - tenant_stat_map_(nullptr), - server_stat_map_(nullptr), + tenant_stat_map_("BackUpTMap"), + server_stat_map_("BackUpSMap"), task_allocator_(), wait_list_(), schedule_list_(), task_map_(), rpc_proxy_(nullptr), task_scheduler_(nullptr), - zone_mgr_(nullptr), - backup_service_(nullptr), - sql_proxy_(nullptr), - lease_service_(nullptr) + sql_proxy_(nullptr) { } @@ -91,43 +95,40 @@ void ObBackupTaskSchedulerQueue::reset() } } task_map_.clear(); + tenant_stat_map_.reuse(); + server_stat_map_.reuse(); } int ObBackupTaskSchedulerQueue::init( - ObTenantBackupScheduleTaskStatMap &tenant_stat_map, - ObServerBackupScheduleTaskStatMap &server_stat_map, - ObZoneManager &zone_manager, - ObBackupService &backup_service, const int64_t bucket_num, obrpc::ObSrvRpcProxy *rpc_proxy, ObBackupTaskScheduler *task_scheduler, const int64_t max_size, - common::ObMySQLProxy &sql_proxy, - ObBackupLeaseService &lease_service) + common::ObMySQLProxy &sql_proxy) { int ret = OB_SUCCESS; const char *OB_BACKUP_TASK_SCHEDULER = "backupTaskScheduler"; + const ObMemAttr attr(MTL_ID(), OB_BACKUP_TASK_SCHEDULER); if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("backup scheduler queue init twice", K(ret)); } else if (bucket_num <= 0 || nullptr == rpc_proxy || nullptr == task_scheduler) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(bucket_num), K(rpc_proxy), K(task_scheduler)); - } else if (OB_FAIL(task_map_.create(bucket_num, OB_BACKUP_TASK_SCHEDULER))) { + } else if (OB_FAIL(tenant_stat_map_.init(ObBackupTaskScheduler::MAX_BACKUP_TASK_QUEUE_LIMIT))) { + LOG_WARN("init tenant stat failed", K(ret)); + } else if (OB_FAIL(server_stat_map_.init(ObBackupTaskScheduler::MAX_BACKUP_TASK_QUEUE_LIMIT))) { + LOG_WARN("init server stat failed", K(ret)); + } else if (OB_FAIL(task_map_.create(bucket_num, attr))) { LOG_WARN("fail to init task map", K(ret), K(bucket_num)); - } else if (OB_FAIL(task_allocator_.init(ObMallocAllocator::get_instance(), OB_MALLOC_MIDDLE_BLOCK_SIZE, - ObMemAttr(common::OB_SERVER_TENANT_ID, OB_BACKUP_TASK_SCHEDULER)))) { + } else if (OB_FAIL(task_allocator_.init(ObMallocAllocator::get_instance(), OB_MALLOC_MIDDLE_BLOCK_SIZE, attr))) { LOG_WARN("fail to init task allocator", K(ret)); } else { max_size_ = max_size; - tenant_stat_map_ = &tenant_stat_map; - server_stat_map_ = &server_stat_map; - zone_mgr_ = &zone_manager; + task_allocator_.set_label(OB_BACKUP_TASK_SCHEDULER); rpc_proxy_ = rpc_proxy; task_scheduler_ = task_scheduler; - backup_service_ = &backup_service; sql_proxy_ = &sql_proxy; - lease_service_ = &lease_service; is_inited_ = true; } return ret; @@ -140,6 +141,7 @@ int ObBackupTaskSchedulerQueue::push_task(const ObBackupScheduleTask &task) if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("backup scheduler queue not inited", K(ret)); + } else if (task_scheduler_->has_set_stop()) { } else if (get_task_cnt_() >= max_size_) { ret = OB_SIZE_OVERFLOW; LOG_WARN("task scheduler queue is full, cant't push task", K(ret), K(get_task_cnt_())); @@ -241,12 +243,12 @@ int ObBackupTaskSchedulerQueue::dump_statistics() get_wait_task_cnt_(), "executing_task_cnt", get_in_schedule_task_cnt_()); - ObServerBackupScheduleTaskStatMap::HashTable::const_iterator sit = server_stat_map_->get_hash_table().begin(); - for (; sit != server_stat_map_->get_hash_table().end(); ++sit) { + ObServerBackupScheduleTaskStatMap::HashTable::const_iterator sit = server_stat_map_.get_hash_table().begin(); + for (; sit != server_stat_map_.get_hash_table().end(); ++sit) { LOG_INFO("server task", "stat", sit->v_); } - ObTenantBackupScheduleTaskStatMap::HashTable::const_iterator tit = tenant_stat_map_->get_hash_table().begin(); - for (; tit != tenant_stat_map_->get_hash_table().end(); ++tit) { + ObTenantBackupScheduleTaskStatMap::HashTable::const_iterator tit = tenant_stat_map_.get_hash_table().begin(); + for (; tit != tenant_stat_map_.get_hash_table().end(); ++tit) { LOG_INFO("tenant task", "stat", tit->v_); } } @@ -316,23 +318,7 @@ int ObBackupTaskSchedulerQueue::pop_task(ObBackupScheduleTask *&output_task, com LOG_WARN("set server stat faled", K(ret), K(dst)); } else { wait_list_.remove(task); - bool is_valid = false; - if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("fail to check lease", K(ret)); - } else if (OB_FAIL(ObBackupDataScheduler::check_tenant_status(task_scheduler_->get_schema_service(), - task->get_tenant_id(), is_valid))) { - LOG_WARN("fail to check tenant status", K(ret)); - } else if (!is_valid) { - // TODO: remove this check tenant status when tenant thread is ready - // tenant has been dropped, so just remove the task from wait list, and don't add it into schedule list - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = clean_server_ref_(dst, task->get_type()))) { - LOG_ERROR("fail to clean server ref", K(ret), KPC(task)); - } - if (OB_SUCCESS != (tmp_ret = clean_tenant_ref_(task->get_tenant_id()))) { - LOG_ERROR("fail to clean tenant ref", K(ret), KPC(task)); - } - } else if (OB_FAIL(task->update_dst_and_doing_status(*sql_proxy_))) { + if (OB_FAIL(task->update_dst_and_doing_status(*sql_proxy_))) { LOG_WARN("fail to update task dst in internal table", K(ret), KPC(task), K(dst)); } else if (!schedule_list_.add_last(task)) { // This step must be successful ret = OB_ERR_UNEXPECTED; @@ -381,7 +367,7 @@ int ObBackupTaskSchedulerQueue::get_backup_region_and_zone_( ObIArray &backup_region) { int ret = OB_SUCCESS; - // TODO(chongrong.th) redefine backup region and backup zone in 4.1 + // TODO(chongrong.th) redefine backup region and backup zone in 4.3 return ret; } @@ -392,19 +378,22 @@ int ObBackupTaskSchedulerQueue::get_all_servers_( { int ret = OB_SUCCESS; ObArray all_zones; + share::ObBackupServerMgr server_mgr; if (!servers.empty()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(servers)); } else if (OB_FAIL(get_all_zones_(backup_zone, backup_region, all_zones))) { LOG_WARN("failed to get all zones", K(ret), K(backup_zone), K(backup_region)); + } else if (OB_FAIL(server_mgr.init(task_scheduler_->get_exec_tenant_id(), *sql_proxy_))) { + LOG_WARN("fail to init server operator", K(ret)); } else { + const bool force_update = false; ObArray tmp_server_list; for (int64_t i = 0; OB_SUCC(ret) && i < all_zones.count(); ++i) { tmp_server_list.reuse(); const ObZone &zone = all_zones.at(i).zone_; const int64_t priority = all_zones.at(i).priority_; - // **FIXME (linqiucen.lqc): temp. solution, this will be replaced when transfer branch is merged - if (OB_FAIL(SVR_TRACER.get_alive_servers(zone, tmp_server_list))) { + if (OB_FAIL(server_mgr.get_alive_servers(force_update, zone, tmp_server_list))) { LOG_WARN("failed to get alive servers", KR(ret), K(zone)); } else { for (int64_t j = 0; OB_SUCC(ret) && j < tmp_server_list.count(); ++j) { @@ -429,6 +418,7 @@ int ObBackupTaskSchedulerQueue::get_all_zones_( ObIArray &zones) { int ret = OB_SUCCESS; + ObArray zone_list; ObArray tmp_zones; if (!zones.empty()) { ret = OB_INVALID_ARGUMENT; @@ -441,7 +431,7 @@ int ObBackupTaskSchedulerQueue::get_all_zones_( for (int64_t i = 0; OB_SUCC(ret) && i < backup_region.count(); ++i) { const ObRegion ®ion = backup_region.at(i).region_; const int64_t priority = backup_region.at(i).priority_; - if (OB_FAIL(zone_mgr_->get_zone(region, tmp_zones))) { + if (OB_FAIL(get_zone_list_from_region_(region, tmp_zones))) { LOG_WARN("fail to get zones", K(ret), K(region)); } else { for (int j = 0; OB_SUCC(ret) && j < tmp_zones.count(); ++j) { @@ -456,8 +446,8 @@ int ObBackupTaskSchedulerQueue::get_all_zones_( } } } else { - if (OB_FAIL(zone_mgr_->get_zone(tmp_zones))) { - LOG_WARN("failed to get zones", KR(ret)); + if (OB_FAIL(get_tenant_zone_list_(task_scheduler_->get_exec_tenant_id(), tmp_zones))) { + LOG_WARN("fail to get zone list of tenant", K(ret), "tenant_id", task_scheduler_->get_exec_tenant_id()); } else { // priority = 0 to express all the zone has the same priority int64_t priority = 0; @@ -475,6 +465,61 @@ int ObBackupTaskSchedulerQueue::get_all_zones_( return ret; } +int ObBackupTaskSchedulerQueue::get_zone_list_from_region_(const common::ObRegion ®ion, ObIArray &zone_list) +{ + int ret = OB_SUCCESS; + ObArray tmp_zone_list; + common::ObRegion tmp_region; + if (region.is_empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("region is empty", K(region), K(ret)); + } else if (OB_FAIL(get_tenant_zone_list_(task_scheduler_->get_exec_tenant_id(), tmp_zone_list))) { + LOG_WARN("fail to get zone list of tenant", K(ret), "tenant_id", task_scheduler_->get_exec_tenant_id()); + } + SMART_VAR(share::ObZoneInfo, info) { + ARRAY_FOREACH_X(tmp_zone_list, i, cur, OB_SUCC(ret)) { + const common::ObZone &zone = tmp_zone_list.at(i); + info.reset(); + info.zone_ = zone; + if (OB_FAIL(share::ObZoneTableOperation::load_zone_info(*sql_proxy_, info))) { + LOG_WARN("fail to load zone info", K(ret)); + } else if (!info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid zone info", K(ret), K(info)); + } else if (OB_FAIL(info.get_region(tmp_region))) { + LOG_WARN("fail to get region", K(ret)); + } else if (region == tmp_region) { + if (OB_FAIL(zone_list.push_back(zone))) { + LOG_WARN("fail to push backup zone", K(ret)); + } + } + } + } + return ret; +} + +int ObBackupTaskSchedulerQueue::get_tenant_zone_list_(const uint64_t tenant_id, ObIArray &zone_list) +{ + int ret = OB_SUCCESS; + common::ObArray units; + share::ObUnitTableOperator unit_op; + if (OB_FAIL(unit_op.init(*sql_proxy_))) { + LOG_WARN("fail to init unit table operator", K(ret)); + } else if (OB_FAIL(unit_op.get_units_by_tenant(tenant_id, units))) { + LOG_WARN("fail to get units by tenant", K(ret), K(tenant_id)); + } else if (units.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("units must not be empty", K(ret), K(tenant_id)); + } + ARRAY_FOREACH_X(units, i, cur, OB_SUCC(ret)) { + const share::ObUnit &unit = units.at(i); + if (OB_FAIL(zone_list.push_back(unit.zone_))) { + LOG_WARN("fail to push back zone", K(ret), K(unit)); + } + } + return ret; +} + int ObBackupTaskSchedulerQueue::choose_dst_( const ObBackupScheduleTask &task, const ObIArray &servers, @@ -591,7 +636,7 @@ int ObBackupTaskSchedulerQueue::check_server_can_become_dst_( ObServerBackupScheduleTaskStatMap::Item *server_stat = nullptr; if (OB_FAIL(key.init(server, type))) { LOG_WARN("fail to init ObBackupServerStatKey", K(ret)); - } else if (OB_FAIL(server_stat_map_->locate(key, server_stat))) { + } else if (OB_FAIL(server_stat_map_.locate(key, server_stat))) { LOG_WARN("fail to get server stat item", K(ret), K(key)); } else if (OB_UNLIKELY(nullptr == server_stat)) { ret = OB_ERR_UNEXPECTED; @@ -617,7 +662,7 @@ int ObBackupTaskSchedulerQueue::set_server_stat_(const ObAddr &dst, const Backup LOG_WARN("fail to init ObBackupServerStatKey", K(ret), K(dst), K(type)); } else { ObServerBackupScheduleTaskStatMap::Item *server_stat = NULL; - if (OB_FAIL(server_stat_map_->locate(key, server_stat))) { + if (OB_FAIL(server_stat_map_.locate(key, server_stat))) { LOG_WARN("fail to locate server stat", K(ret), K(key)); } else if (OB_UNLIKELY(nullptr == server_stat)) { ret = OB_ERR_UNEXPECTED; @@ -639,7 +684,7 @@ int ObBackupTaskSchedulerQueue::set_tenant_stat_(const int64_t &tenant_id) LOG_WARN("invalid argument", K(ret), K(tenant_id)); } else { ObTenantBackupScheduleTaskStatMap::Item *tenant_stat = NULL; - if (OB_FAIL(tenant_stat_map_->locate(tenant_id, tenant_stat))) { + if (OB_FAIL(tenant_stat_map_.locate(tenant_id, tenant_stat))) { LOG_WARN("fail to locate tenant stat", K(ret), K(tenant_id)); } else if (OB_UNLIKELY(nullptr == tenant_stat)) { ret = OB_ERR_UNEXPECTED; @@ -664,7 +709,7 @@ int ObBackupTaskSchedulerQueue::clean_server_ref_(const ObAddr &dst, const Backu LOG_WARN("fail to init ObBackupServerStatKey", K(ret)); } else { ObServerBackupScheduleTaskStatMap::Item *server_stat = NULL; - if (OB_FAIL(server_stat_map_->locate(key, server_stat))) { + if (OB_FAIL(server_stat_map_.locate(key, server_stat))) { LOG_ERROR("fail to locate server stat", K(ret), K(key)); } else if (OB_UNLIKELY(nullptr == server_stat)) { ret = OB_ERR_UNEXPECTED; @@ -686,7 +731,7 @@ int ObBackupTaskSchedulerQueue::clean_tenant_ref_(const int64_t &tenant_id) LOG_WARN("invalid argument", K(ret), K(tenant_id)); } else { ObTenantBackupScheduleTaskStatMap::Item *tenant_stat = NULL; - if (OB_FAIL(tenant_stat_map_->locate(tenant_id, tenant_stat))) { + if (OB_FAIL(tenant_stat_map_.locate(tenant_id, tenant_stat))) { LOG_ERROR("fail to locate tenant stat", K(ret), K(tenant_id)); } else if (nullptr == tenant_stat) { ret = OB_ERR_UNEXPECTED; @@ -712,7 +757,7 @@ int ObBackupTaskSchedulerQueue::clean_task_map(const ObBackupScheduleTaskKey &ta return ret; } -int ObBackupTaskSchedulerQueue::execute_over(const ObBackupScheduleTask &task, const int execute_ret) +int ObBackupTaskSchedulerQueue::execute_over(const ObBackupScheduleTask &task, const share::ObHAResultInfo &result_info) { int ret = OB_SUCCESS; ObBackupScheduleTask *tmp_task = nullptr; @@ -726,19 +771,20 @@ int ObBackupTaskSchedulerQueue::execute_over(const ObBackupScheduleTask &task, c } else if (!dst.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("task's dst is not valid", K(ret), K(task)); - } else if (OB_FAIL(backup_service_->get_job(task.get_type(), job))) { - LOG_WARN("failed to get task's job", K(ret)); + } else if (OB_FAIL(task_scheduler_->get_backup_job(task.get_type(), job))) { + LOG_WARN("failed to get backup service", K(ret)); } else if (nullptr == job) { ret = OB_ERR_UNEXPECTED; LOG_WARN("job is nullptr", K(ret), K(task)); } else { ObMutexGuard guard(mutex_); - if (OB_FAIL(get_schedule_task_(task, tmp_task))) { // if task not exist in map ,tmp_task = nullptr + if (task_scheduler_->has_set_stop()) { + } else if (OB_FAIL(get_schedule_task_(task, tmp_task))) { // if task not exist in map ,tmp_task = nullptr LOG_WARN("get schedule task failed", K(ret)); } else if (nullptr == tmp_task) { ret = OB_ENTRY_NOT_EXIST; LOG_WARN("in schedule list task not found", K(task)); - } else if (OB_FAIL(job->handle_execute_over(tmp_task, can_remove, dst, execute_ret))) { + } else if (OB_FAIL(job->handle_execute_over(tmp_task, result_info, can_remove))) { LOG_WARN("failed to handle execute over", K(ret), K(task)); } else if (!can_remove) { } else if (OB_FAIL(remove_task_(tmp_task, in_schedule))) { @@ -1066,147 +1112,162 @@ int ObBackupTaskSchedulerQueue::get_schedule_tasks( return ret; } -int64_t ObBackupSchedulerIdling::get_idle_interval_us() -{ - const int64_t backup_check_interval = GCONF._backup_idle_time; - return backup_check_interval; -} - // ObBackupTaskScheduler ObBackupTaskScheduler::ObBackupTaskScheduler() - : ObRsReentrantThread(true), - is_inited_(false), - idling_(stop_), - scheduler_mtx_(common::ObLatchIds::BACKUP_LOCK), - tenant_stat_map_(), - server_stat_map_(), + : is_inited_(false), + tenant_id_(OB_INVALID_TENANT_ID), queue_(), - self_(), - zone_mgr_(nullptr), rpc_proxy_(nullptr), - backup_service_(nullptr), - lease_service_(nullptr), - schema_service_(nullptr) + sql_proxy_(nullptr), + schema_service_(nullptr), + backup_srv_array_() { } +int ObBackupTaskScheduler::mtl_init(ObBackupTaskScheduler *&backup_task_scheduler) +{ + int ret = OB_SUCCESS; + common::ObMySQLProxy *sql_proxy = GCTX.sql_proxy_; + obrpc::ObSrvRpcProxy *rpc_proxy = GCTX.srv_rpc_proxy_; + share::schema::ObMultiVersionSchemaService *schema_service = GCTX.schema_service_; + if (OB_ISNULL(sql_proxy)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql_proxy should not be NULL", K(ret), KP(sql_proxy)); + } else if (OB_ISNULL(rpc_proxy)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rpc_proxy should not be NULL", K(ret), KP(rpc_proxy)); + } else if (OB_ISNULL(schema_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("scheam service can not be NULL", K(ret), KP(schema_service)); + } else if (OB_FAIL(backup_task_scheduler->init(rpc_proxy, *sql_proxy, *schema_service))) { + LOG_WARN("fail to init backup_task_scheduler", K(ret)); + } + return ret; +} + int ObBackupTaskScheduler::init( - ObZoneManager *zone_mgr, obrpc::ObSrvRpcProxy *rpc_proxy, - ObBackupService *backup_mgr, common::ObMySQLProxy &sql_proxy, - ObBackupLeaseService &lease_service) + share::schema::ObMultiVersionSchemaService &schema_service) { int ret = OB_SUCCESS; - const int64_t backup_task_scheduler_thread_cnt = 1; - const char *BACKUPTASKSCHEDULER = "BackupTaskScheduler"; - share::schema::ObMultiVersionSchemaService *service = GCTX.schema_service_; if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret)); - } else if (OB_UNLIKELY(nullptr == rpc_proxy || nullptr == zone_mgr || nullptr == service)) { + } else if (OB_UNLIKELY(nullptr == rpc_proxy)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(rpc_proxy), K(zone_mgr)); - } else if (OB_FAIL(create(backup_task_scheduler_thread_cnt, BACKUPTASKSCHEDULER))) { - LOG_WARN("create backup task scheduler thread failed", K(ret), K(backup_task_scheduler_thread_cnt)); + LOG_WARN("invalid argument", K(ret), K(rpc_proxy)); + } else if (OB_FAIL(create("BACKUP_SCHE", *this, ObWaitEventIds::BACKUP_TASK_SCHEDULER_COND_WAIT))) { + LOG_WARN("create backup task scheduler thread failed", K(ret)); } else { - zone_mgr_ = zone_mgr; + tenant_id_ = MTL_ID(); rpc_proxy_ = rpc_proxy; - backup_service_ = backup_mgr; - lease_service_ = &lease_service; - schema_service_ = service; - if (OB_FAIL(tenant_stat_map_.init(MAX_BACKUP_TASK_QUEUE_LIMIT))) { - LOG_WARN("init tenant stat failed", K(ret), LITERAL_K(MAX_BACKUP_TASK_QUEUE_LIMIT)); - } else if (OB_FAIL(server_stat_map_.init(MAX_BACKUP_TASK_QUEUE_LIMIT))) { - LOG_WARN("init server stat failed", K(ret), LITERAL_K(MAX_BACKUP_TASK_QUEUE_LIMIT)); - } else if (OB_FAIL(queue_.init(tenant_stat_map_, server_stat_map_, - *zone_mgr, *backup_mgr, MAX_BACKUP_TASK_QUEUE_LIMIT, rpc_proxy_, this, MAX_BACKUP_TASK_QUEUE_LIMIT, sql_proxy, lease_service))) { + schema_service_ = &schema_service; + if (OB_FAIL(queue_.init(MAX_BACKUP_TASK_QUEUE_LIMIT, rpc_proxy_, this, MAX_BACKUP_TASK_QUEUE_LIMIT, sql_proxy))) { LOG_WARN("init rebalance task queue failed", K(ret), LITERAL_K(MAX_BACKUP_TASK_QUEUE_LIMIT)); } else { + sql_proxy_ = &sql_proxy; is_inited_ = true; } } return ret; } -void ObBackupTaskScheduler::stop() +void ObBackupTaskScheduler::destroy() { - int tmp_ret = OB_SUCCESS; - if (IS_NOT_INIT) { - tmp_ret = OB_NOT_INIT; - LOG_WARN_RET(tmp_ret, "not init", K(tmp_ret)); - } else { - ObRsReentrantThread::stop(); - idling_.wakeup(); - } - LOG_INFO("Backup task scheduler stop", K(tmp_ret)); + reuse(); + rpc_proxy_ = nullptr; + sql_proxy_ = nullptr; + schema_service_ = nullptr; + is_inited_ = false; + ObBackupBaseService::destroy(); } -int ObBackupTaskScheduler::idle() const +int ObBackupTaskScheduler::switch_to_leader() { - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (OB_FAIL(idling_.idle())) { - LOG_WARN("idle failed", K(ret)); - } else { - LOG_INFO("backup scheduler idle", "idle_time", idling_.get_idle_interval_us()); - } + reuse(); + return ObBackupBaseService::switch_to_leader(); +} + +void ObBackupTaskScheduler::switch_to_follower_forcedly() +{ + ObBackupBaseService::switch_to_follower_forcedly(); + reuse(); +} + +int ObBackupTaskScheduler::switch_to_follower_gracefully() +{ + int ret = ObBackupBaseService::switch_to_follower_gracefully(); + reuse(); return ret; } -void ObBackupTaskScheduler::wakeup() +int ObBackupTaskScheduler::resume_leader() { - int tmp_ret = OB_SUCCESS; - if (!is_inited_) { - tmp_ret = OB_NOT_INIT; - LOG_WARN_RET(tmp_ret, "not init", K(tmp_ret)); - } else { - idling_.wakeup(); - } + reuse(); + return ObBackupBaseService::resume_leader(); } -void ObBackupTaskScheduler::run3() +void ObBackupTaskScheduler::run2() { int ret = OB_SUCCESS; - LOG_INFO("backup task Scheduler start"); ObCurTraceId::init(GCONF.self_addr_); if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); } else { + LOG_INFO("backup task Scheduler start"); int64_t last_dump_time = ObTimeUtility::current_time(); int64_t last_check_alive_ts = ObTimeUtility::current_time(); int64_t last_reload_task_ts = ObTimeUtility::current_time(); bool reload_flag = false; - while (!stop_) { - update_last_run_timestamp(); - dump_statistics_(last_dump_time); - if (OB_FAIL(lease_service_->check_lease())) { - LOG_WARN("fail to check lease", K(ret)); - } else if (OB_FAIL(reload_task_(last_reload_task_ts, reload_flag))) { - LOG_WARN("failed to reload task", K(ret)); - } else { - // error code has no effect between pop_and_send_task() and check_alive() - if (OB_FAIL(pop_and_send_task_())) { - LOG_WARN("fail to pop and send task", K(ret)); - } - if (OB_FAIL(check_alive_(last_check_alive_ts, reload_flag))) { - LOG_WARN("fail to check alive", K(ret)); - } - } - - if (0 == queue_.get_task_cnt()) { - if (OB_FAIL(idle())) { - LOG_WARN("idle failed", K(ret)); + while (!has_set_stop()) { + bool is_normal = false; + if (!is_meta_tenant(tenant_id_)) { // only meta tenant has backup task need to schedule + set_idle_time(ObBackupBaseService::OB_MAX_IDLE_TIME); + idle(); + } else if (OB_FAIL(check_tenant_status_normal_(is_normal))) { + LOG_WARN("fail to chaeck tenant status normal", K(ret)); + } else if (is_normal) { + dump_statistics_(last_dump_time); + if (OB_FAIL(check_leader())) { + LOG_WARN("fail to check leader", K(ret)); + } else if (OB_FAIL(reload_task_(last_reload_task_ts, reload_flag))) { + LOG_WARN("failed to reload task", K(ret)); } else { - continue; + // error code has no effect between pop_and_send_task() and check_alive() + if (OB_FAIL(pop_and_send_task_())) { + LOG_WARN("fail to pop and send task", K(ret)); + } + if (OB_FAIL(check_alive_(last_check_alive_ts, reload_flag))) { + LOG_WARN("fail to check alive", K(ret)); + } + } + + if (0 == queue_.get_task_cnt()) { + set_idle_time(60*1000*1000); + idle(); } } } + LOG_INFO("backup task scheduler stop"); } - LOG_INFO("backup task scheduler stop"); +} + +int ObBackupTaskScheduler::check_tenant_status_normal_(bool &is_normal) +{ + int ret = OB_SUCCESS; + is_normal = false; + share::schema::ObSchemaGetterGuard guard; + const share::schema::ObSimpleTenantSchema *tenant_info = nullptr; + if (OB_FAIL(schema_service_->get_tenant_schema_guard(tenant_id_, guard))) { + LOG_WARN("fail to get schema guard", K(ret), K(tenant_id_)); + } else if (OB_FAIL(guard.get_tenant_info(tenant_id_, tenant_info))) { + LOG_WARN("fail to get tenant info", K(ret), K(tenant_id_)); + } else if (tenant_info->is_normal()) { + is_normal = true; + } + return ret; } int ObBackupTaskScheduler::reload_task_(int64_t &last_reload_task_ts, bool &reload_flag) @@ -1216,32 +1277,41 @@ int ObBackupTaskScheduler::reload_task_(int64_t &last_reload_task_ts, bool &relo const int64_t MAX_CHECK_TIME_INTERVAL = 10 * 60 * 1000 * 1000L; common::ObArenaAllocator allocator; ObArray need_reload_tasks; - if (!backup_service_->can_schedule() || now > MAX_CHECK_TIME_INTERVAL + last_reload_task_ts) { - if (OB_FAIL(backup_service_->get_need_reload_task(allocator, need_reload_tasks))) { - LOG_WARN("failed to get need reload tasks", K(ret)); - } else if (need_reload_tasks.empty()) { - } else if (OB_FAIL(queue_.reload_task(need_reload_tasks))) { - LOG_WARN("failed to reload task", K(ret), K(need_reload_tasks)); - } else { - LOG_INFO("succeed reload tasks", K(need_reload_tasks)); - } + reload_flag = false; + ARRAY_FOREACH(backup_srv_array_, i) { + need_reload_tasks.reset(); + ObBackupService *backup_service = backup_srv_array_.at(i); + if (!backup_service->can_schedule() || now > MAX_CHECK_TIME_INTERVAL + last_reload_task_ts) { + if (OB_FAIL(backup_service->get_need_reload_task(allocator, need_reload_tasks))) { + LOG_WARN("failed to get need reload tasks", K(ret)); + } else if (need_reload_tasks.empty()) { + } else if (OB_FAIL(queue_.reload_task(need_reload_tasks))) { + LOG_WARN("failed to reload task", K(ret), K(need_reload_tasks)); + } else { + LOG_INFO("succeed reload tasks", K(need_reload_tasks)); + } - if (OB_SUCC(ret)) { - backup_service_->enable_backup(); - last_reload_task_ts = now; - reload_flag = true; - backup_service_->wakeup(); - } else { - backup_service_->disable_backup(); - } - for (int j = 0; j < need_reload_tasks.count(); ++j) { - ObBackupScheduleTask *task = need_reload_tasks.at(j); - if (nullptr != task) { - task->~ObBackupScheduleTask(); - task = nullptr; + if (OB_SUCC(ret)) { + backup_service->enable_backup(); + last_reload_task_ts = now; + reload_flag = true; + backup_service->wakeup(); + } else { + reload_flag = false; + backup_service->disable_backup(); + } + ARRAY_FOREACH(need_reload_tasks, i) { + ObBackupScheduleTask *task = need_reload_tasks.at(i); + if (nullptr != task) { + task->~ObBackupScheduleTask(); + task = nullptr; + } } } - } + } + if (OB_SUCC(ret) && reload_flag) { + last_reload_task_ts = now; + } return ret; } @@ -1271,13 +1341,18 @@ int ObBackupTaskScheduler::check_alive_(int64_t &last_check_task_on_server_ts, b int ret = OB_SUCCESS; ObArray schedule_tasks; ObArenaAllocator allocator; + share::ObBackupServerMgr server_mgr; + ObServerStatus server_status; Bool res = false; + bool force_update = false; const int64_t now = ObTimeUtility::current_time(); const int64_t backup_task_keep_alive_interval = GCONF._backup_task_keep_alive_interval; const int64_t backup_task_keep_alive_timeout = GCONF._backup_task_keep_alive_timeout; if ((now <= backup_task_keep_alive_interval + last_check_task_on_server_ts) && !reload_flag) { } else if (OB_FAIL(queue_.get_schedule_tasks(schedule_tasks, allocator))) { LOG_WARN("get scheduelr tasks error", K(ret)); + } else if (OB_FAIL(server_mgr.init(get_exec_tenant_id(), *sql_proxy_))) { + LOG_WARN("fail to init server mgr", K(ret)); } else { last_check_task_on_server_ts = now; for (int64_t i = 0; OB_SUCC(ret) && i < schedule_tasks.count(); ++i) { @@ -1290,15 +1365,13 @@ int ObBackupTaskScheduler::check_alive_(int64_t &last_check_task_on_server_ts, b check_task_arg.trace_id_ = task->get_trace_id(); if ((now - task->get_generate_time() < backup_task_keep_alive_interval) && !reload_flag) { // no need to check alive, wait next turn - // **FIXME (linqiucen.lqc): temp. solution, this will be replaced when transfer branch is merged - } else if (OB_FAIL(SVR_TRACER.is_server_exist(dst, is_exist))) { + } else if (OB_FAIL(server_mgr.is_server_exist(dst, force_update, is_exist))) { LOG_WARN("fail to check server exist", K(ret), K(dst)); } else if (!is_exist) { LOG_WARN("backup dest server is not exist", K(ret), K(dst)); - // **FIXME (linqiucen.lqc): temp. solution, this will be replaced when transfer branch is merged - } else if (OB_FAIL(SVR_TRACER.get_server_info(dst, server_info))) { - LOG_WARN("fail to get server_info", K(ret), K(dst)); - } else if (!server_info.is_active() || !server_info.in_service()) { + } else if (OB_FAIL(server_mgr.get_server_status(dst, force_update, server_status))) { + LOG_WARN("fail to get server status", K(ret), K(dst)); + } else if (!server_status.is_active() || !server_status.in_service()) { is_exist = false; LOG_WARN("server status may not active or in service", K(ret), K(dst)); } else if (OB_FAIL(rpc_proxy_->to(dst).check_backup_task_exist(check_task_arg, res))) { @@ -1312,7 +1385,11 @@ int ObBackupTaskScheduler::check_alive_(int64_t &last_check_task_on_server_ts, b if (!is_exist) { LOG_INFO("task not on server, need remove", KPC(task)); const int rc = OB_REBALANCE_TASK_NOT_IN_PROGRESS; - if (OB_FAIL(execute_over(*task, rc))) { + ObHAResultInfo result_info(ObHAResultInfo::ROOT_SERVICE, + task->get_dst(), + task->get_trace_id(), + rc); + if (OB_FAIL(execute_over(*task, result_info))) { LOG_WARN("do execute over failed", K(ret), KPC(task)); } } @@ -1334,7 +1411,6 @@ int ObBackupTaskScheduler::check_alive_(int64_t &last_check_task_on_server_ts, b int ObBackupTaskScheduler::execute_task_(const ObBackupScheduleTask &task) { int ret = OB_SUCCESS; - ObCurTraceId::init(self_); THIS_WORKER.set_timeout_ts(INT64_MAX); LOG_INFO("execute task", K(task)); if (OB_FAIL(do_execute_(task))) { @@ -1342,18 +1418,22 @@ int ObBackupTaskScheduler::execute_task_(const ObBackupScheduleTask &task) } if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = execute_over(task, ret))) { - LOG_WARN("do execute over failed", K(tmp_ret), K(ret), K(task)); + ObHAResultInfo result_info(ObHAResultInfo::ROOT_SERVICE, + task.get_dst(), + task.get_trace_id(), + ret); + if (OB_SUCCESS != (tmp_ret = execute_over(task, result_info))) { + LOG_WARN("do execute over failed", K(tmp_ret), K(result_info), K(task)); } } return ret; } -int ObBackupTaskScheduler::execute_over(const ObBackupScheduleTask &input_task, const int &execute_ret) +int ObBackupTaskScheduler::execute_over(const ObBackupScheduleTask &input_task, const share::ObHAResultInfo &result_info) { int ret = OB_SUCCESS; - if (OB_FAIL(queue_.execute_over(input_task, execute_ret))) { - LOG_WARN("remove task failed", K(ret), K(input_task), K(execute_ret)); + if (OB_FAIL(queue_.execute_over(input_task, result_info))) { + LOG_WARN("failed to execute over", K(ret), K(result_info)); } else { wakeup(); } @@ -1377,21 +1457,23 @@ int ObBackupTaskScheduler::do_execute_(const ObBackupScheduleTask &task) int ret = OB_SUCCESS; // check dst server avaiable const ObAddr &online_server = task.get_dst(); - bool is_alive = false; + bool is_exist = false; bool in_service = false; - common::ObAddr leader; - // **FIXME (linqiucen.lqc): temp. solution, this will be replaced when transfer branch is merged - if (OB_FAIL(SVR_TRACER.check_server_alive(online_server, is_alive))) { + const bool force_update = false; + share::ObBackupServerMgr server_mgr; + share::ObServerStatus server_status; + if (OB_FAIL(server_mgr.init(get_exec_tenant_id(), *sql_proxy_))) { + LOG_WARN("fail to init server mgr", K(ret)); + } else if (OB_FAIL(server_mgr.is_server_exist(online_server, force_update, is_exist))) { LOG_WARN("check server alive failed", K(ret), K(online_server)); - } else if (!is_alive) { + } else if (!is_exist) { ret = OB_REBALANCE_TASK_CANT_EXEC; - LOG_WARN("dst server not alive", K(ret), K(online_server)); - // **FIXME (linqiucen.lqc): temp. solution, this will be replaced when transfer branch is merged - } else if (OB_FAIL(SVR_TRACER.check_in_service(online_server, in_service))) { - LOG_WARN("check in service failed", K(ret), K(online_server)); - } else if (!in_service) { + LOG_WARN("dst server not exist", K(ret), K(online_server)); + } else if (OB_FAIL(server_mgr.get_server_status(online_server, force_update, server_status))) { + LOG_WARN("fail to get server status", K(ret), K(online_server)); + } else if (!server_status.is_active() || !server_status.in_service()) { ret = OB_REBALANCE_TASK_CANT_EXEC; - LOG_WARN("dst server not in service", K(ret), K(online_server)); + LOG_WARN("server status may not active or in service, task can't execute", K(ret), K(online_server)); } else if (OB_UNLIKELY(nullptr == rpc_proxy_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("null ptr", K(ret), KP(rpc_proxy_)); @@ -1465,10 +1547,48 @@ int ObBackupTaskScheduler::reuse() { int ret = OB_SUCCESS; if (IS_INIT) { - ObMutexGuard guard(scheduler_mtx_); queue_.reset(); - server_stat_map_.reuse(); - tenant_stat_map_.reuse(); + } + return ret; +} + +int ObBackupTaskScheduler::get_backup_job(const BackupJobType &type, ObIBackupJobScheduler *&job) +{ + int ret = OB_SUCCESS; + ObMutexGuard guard(scheduler_mtx_); + ARRAY_FOREACH(backup_srv_array_, i) { + ObBackupService *srv = backup_srv_array_.at(i); + if (OB_ISNULL(srv)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup service must not be null", K(ret)); + } else if (OB_NOT_NULL(job = srv->get_scheduler(type))) { + if (job->get_job_type() != type) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("backup job not match job type", K(ret)); + } else { + break; + } + } + } + + if (OB_FAIL(ret)) { + job = nullptr; + } + return ret; +} + +int ObBackupTaskScheduler::register_backup_srv(ObBackupService &srv) +{ + int ret = OB_SUCCESS; + ObMutexGuard guard(scheduler_mtx_); + ARRAY_FOREACH(backup_srv_array_, i) { + if (&srv == backup_srv_array_.at(i)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("duplicate register", K(ret)); + } + } + if (OB_SUCC(ret) && OB_FAIL(backup_srv_array_.push_back(&srv))) { + LOG_WARN("failed to push backup backup service", K(ret)); } return ret; } diff --git a/src/rootserver/backup/ob_backup_task_scheduler.h b/src/rootserver/backup/ob_backup_task_scheduler.h index 7422fd9a8..751cb1195 100644 --- a/src/rootserver/backup/ob_backup_task_scheduler.h +++ b/src/rootserver/backup/ob_backup_task_scheduler.h @@ -13,21 +13,24 @@ #ifndef OCEANBASE_ROOTSERVER_OB_BACKUP_TASK_SCHEDULER_H_ #define OCEANBASE_ROOTSERVER_OB_BACKUP_TASK_SCHEDULER_H_ +#include "ob_backup_base_service.h" #include "ob_backup_schedule_task.h" -#include "ob_backup_lease_service.h" -#include "lib/lock/ob_thread_cond.h" -#include "rootserver/ob_rs_reentrant_thread.h" -#include "rootserver/ob_thread_idling.h" -#include "share/ob_srv_rpc_proxy.h" +#include "ob_backup_service.h" + namespace oceanbase { namespace lib { class ObMutex; } + +namespace share +{ +class ObZoneInfo; +} + namespace rootserver { -class ObZoneManager; class ObBackupTaskScheduler; class ObBackupService; class ObBackupTaskSchedulerQueue @@ -40,16 +43,11 @@ public: ObBackupTaskSchedulerQueue(); virtual ~ObBackupTaskSchedulerQueue(); - int init(ObTenantBackupScheduleTaskStatMap &tenant_stat_map, - ObServerBackupScheduleTaskStatMap &server_stat_map, - ObZoneManager &zone_manager, - ObBackupService &backup_mgr, - const int64_t bucket_num, + int init(const int64_t bucket_num, obrpc::ObSrvRpcProxy *rpc_proxy, ObBackupTaskScheduler *task_scheduler, const int64_t max_size, - common::ObMySQLProxy &sql_proxy, - ObBackupLeaseService &lease_service); + common::ObMySQLProxy &sql_proxy); // try to add task in queue // return OB_ENTRY_EXIST if insert a task which already in queue @@ -61,7 +59,7 @@ public: // then set to scheduler state and move to schedule_list; // return OB_SUCCESS or assign NULL to task, if no task can be scheduled int pop_task(ObBackupScheduleTask *&output_task, common::ObArenaAllocator &allocator); - int execute_over(const ObBackupScheduleTask &task, const int execute_ret); + int execute_over(const ObBackupScheduleTask &task, const share::ObHAResultInfo &result_info); // remove task // When finished, task memory will be released and %task can not be used again. int reload_task(const ObArray &need_reload_tasks); @@ -82,6 +80,8 @@ private: virtual int get_all_zones_(const ObIArray &backup_zone, const ObIArray &backup_region, ObIArray &zones); + int get_tenant_zone_list_(const uint64_t tenant_id, ObIArray &zone_list); + int get_zone_list_from_region_(const ObRegion ®ion, ObIArray &zone_list); int choose_dst_(const ObBackupScheduleTask &task, const ObIArray &servers, ObAddr &dst, @@ -114,9 +114,9 @@ private: lib::ObMutex mutex_; int64_t max_size_; // Count the number of tasks per tenant. key: tenant_id, value :struct for task_cnt - ObTenantBackupScheduleTaskStatMap *tenant_stat_map_; + ObTenantBackupScheduleTaskStatMap tenant_stat_map_; // Count the number of tasks per server, key: server_addr value :struct for statistical information - ObServerBackupScheduleTaskStatMap *server_stat_map_; + ObServerBackupScheduleTaskStatMap server_stat_map_; common::ObFIFOAllocator task_allocator_; // task in wait_list waiting to schedule TaskList wait_list_; @@ -126,23 +126,14 @@ private: TaskMap task_map_; obrpc::ObSrvRpcProxy *rpc_proxy_; ObBackupTaskScheduler *task_scheduler_; - ObZoneManager *zone_mgr_; - ObBackupService *backup_service_; common::ObMySQLProxy *sql_proxy_; - ObBackupLeaseService *lease_service_; DISALLOW_COPY_AND_ASSIGN(ObBackupTaskSchedulerQueue); }; -class ObBackupSchedulerIdling : public ObThreadIdling { -public: - explicit ObBackupSchedulerIdling(volatile bool &stop) : ObThreadIdling(stop) {} - virtual int64_t get_idle_interval_us(); -}; - -class ObBackupTaskScheduler : public ObRsReentrantThread +class ObBackupTaskScheduler : public ObBackupBaseService { public: - const static int64_t MAX_BACKUP_TASK_QUEUE_LIMIT = 1 << 20; + const static int64_t MAX_BACKUP_TASK_QUEUE_LIMIT = 1024; const static int64_t CONCURRENCY_LIMIT_INTERVAL = 10 * 60 * 1000000L; // 10min const static int64_t BACKUP_TASK_CONCURRENCY = 1; const static int64_t BACKUP_SERVER_DATA_LIMIT_INTERVAL = 20 * 60 * 1000000; // 60 min; @@ -150,18 +141,19 @@ public: public: ObBackupTaskScheduler(); - - int init(ObZoneManager *zone_mgr_, - obrpc::ObSrvRpcProxy *rpc_proxy, - ObBackupService *backup_mgr, + virtual ~ObBackupTaskScheduler() {} + static int mtl_init(ObBackupTaskScheduler *&backup_task_scheduler); + int init(obrpc::ObSrvRpcProxy *rpc_proxy, common::ObMySQLProxy &sql_proxy, - ObBackupLeaseService &lease_service); + share::schema::ObMultiVersionSchemaService &schema_service); + + virtual void run2() override final; + virtual void destroy() override final; + virtual void switch_to_follower_forcedly() override; + virtual int switch_to_leader() override; + virtual int switch_to_follower_gracefully() override; + virtual int resume_leader() override; - virtual void run3() override; - virtual int blocking_run() { BLOCKING_RUN_IMPLEMENT(); } - void stop(); - void wakeup(); - int idle() const; public: // add_task() will nerver block // Return OB_ENTRY_EXIST if the task already exist in the scheduler @@ -171,41 +163,38 @@ public: virtual int check_task_exist(const ObBackupScheduleTaskKey key, bool &is_exist); // call when task execute finish // remove task from scheduler - virtual int execute_over(const ObBackupScheduleTask &input_task, const int &execute_ret); + virtual int execute_over(const ObBackupScheduleTask &input_task, const share::ObHAResultInfo &result_info); virtual int get_all_tasks(common::ObIAllocator &allocator, common::ObIArray &tasks); virtual int cancel_tasks(const BackupJobType &type, const uint64_t job_id, const uint64_t tenant_id); int cancel_tasks(const BackupJobType &type, const uint64_t tenant_id); + int get_backup_job(const BackupJobType &type, ObIBackupJobScheduler *&job); + int register_backup_srv(ObBackupService &srv); int reuse(); - int reload_task_(int64_t &last_reload_task_ts, bool &reload_flag); - share::schema::ObMultiVersionSchemaService &get_schema_service() { return *schema_service_; } + uint64_t get_exec_tenant_id() { return gen_user_tenant_id(tenant_id_); } private: + int reload_task_(int64_t &last_reload_task_ts, bool &reload_flag); // Send task to execute. int execute_task_(const ObBackupScheduleTask &task); int do_execute_(const ObBackupScheduleTask &task); void dump_statistics_(int64_t &last_dump_time); int check_alive_(int64_t &last_check_task_on_server_ts, bool &reload_flag); int pop_and_send_task_(); + + int check_tenant_status_normal_(bool &is_normal); private: bool is_inited_; - mutable ObBackupSchedulerIdling idling_; + uint64_t tenant_id_; lib::ObMutex scheduler_mtx_; - // Count the number of tasks per tenant. key: tenant_id, value :struct for task_cnt - ObTenantBackupScheduleTaskStatMap tenant_stat_map_; - // Count the number of tasks per server, key: server_addr value :struct for statistical information - ObServerBackupScheduleTaskStatMap server_stat_map_; ObBackupTaskSchedulerQueue queue_; - // scheduler's self server addr - common::ObAddr self_; - ObZoneManager *zone_mgr_; obrpc::ObSrvRpcProxy *rpc_proxy_; - ObBackupService *backup_service_; - ObBackupLeaseService *lease_service_; + common::ObMySQLProxy *sql_proxy_; share::schema::ObMultiVersionSchemaService *schema_service_; + common::ObArray backup_srv_array_; DISALLOW_COPY_AND_ASSIGN(ObBackupTaskScheduler); }; } // end namespace rootserver } // end namespace oceanbase -#endif // OCEANBASE_ROOTSERVER_OB_BACKUP_TASK_SCHEDULER_H_ \ No newline at end of file +#endif // OCEANBASE_ROOTSERVER_OB_BACKUP_TASK_SCHEDULER_H_ diff --git a/src/rootserver/backup/ob_tenant_archive_scheduler.cpp b/src/rootserver/backup/ob_tenant_archive_scheduler.cpp index 905a1af40..afa1ed4d2 100644 --- a/src/rootserver/backup/ob_tenant_archive_scheduler.cpp +++ b/src/rootserver/backup/ob_tenant_archive_scheduler.cpp @@ -387,8 +387,7 @@ static int round_checkpoint_cb( * ------------------------------ObArchiveHandler--------------------- */ ObArchiveHandler::ObArchiveHandler() - : is_inited_(false), tenant_id_(OB_INVALID_TENANT_ID), - zone_mgr_(nullptr), unit_mgr_(nullptr), rpc_proxy_(nullptr), + : is_inited_(false), tenant_id_(OB_INVALID_TENANT_ID), rpc_proxy_(nullptr), sql_proxy_(nullptr), schema_service_(nullptr), round_handler_(), archive_table_op_() { @@ -397,8 +396,6 @@ ObArchiveHandler::ObArchiveHandler() int ObArchiveHandler::init( const uint64_t tenant_id, - ObZoneManager &zone_mgr, - ObUnitManager &unit_manager, share::schema::ObMultiVersionSchemaService *schema_service, obrpc::ObSrvRpcProxy &rpc_proxy, common::ObMySQLProxy &sql_proxy) @@ -417,8 +414,6 @@ int ObArchiveHandler::init( LOG_WARN("failed to init archive round", K(ret), K(tenant_id)); } else { tenant_id_ = tenant_id; - zone_mgr_ = &zone_mgr; - unit_mgr_ = &unit_manager; schema_service_ = schema_service; rpc_proxy_ = &rpc_proxy; sql_proxy_ = &sql_proxy; diff --git a/src/rootserver/backup/ob_tenant_archive_scheduler.h b/src/rootserver/backup/ob_tenant_archive_scheduler.h index 27e0193b8..f913c5b18 100644 --- a/src/rootserver/backup/ob_tenant_archive_scheduler.h +++ b/src/rootserver/backup/ob_tenant_archive_scheduler.h @@ -32,9 +32,6 @@ namespace common { namespace rootserver { -class ObZoneManager; -class ObUnitManager; - class ObArchiveHandler final { public: @@ -43,8 +40,6 @@ public: int init( const uint64_t tenant_id, - ObZoneManager &zone_mgr, - ObUnitManager &unit_manager, share::schema::ObMultiVersionSchemaService *schema_service, obrpc::ObSrvRpcProxy &rpc_proxy, common::ObMySQLProxy &sql_proxy); @@ -75,8 +70,6 @@ private: private: bool is_inited_; uint64_t tenant_id_; // user tenant id - ObZoneManager *zone_mgr_; - ObUnitManager *unit_mgr_; obrpc::ObSrvRpcProxy *rpc_proxy_; common::ObMySQLProxy *sql_proxy_; share::schema::ObMultiVersionSchemaService *schema_service_; @@ -90,4 +83,4 @@ private: } -#endif \ No newline at end of file +#endif diff --git a/src/rootserver/balance/ob_all_balance_group_builder.cpp b/src/rootserver/balance/ob_all_balance_group_builder.cpp new file mode 100644 index 000000000..2b9fbe8b3 --- /dev/null +++ b/src/rootserver/balance/ob_all_balance_group_builder.cpp @@ -0,0 +1,711 @@ +/** + * Copyright (c) 2021 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. + */ +#define USING_LOG_PREFIX BALANCE + +#include "share/ob_balance_define.h" // need_balance_table() +#include "share/tablet/ob_tablet_to_ls_iterator.h" // ObTenantTabletToLSIterator +#include "share/tablet/ob_tablet_table_iterator.h" // ObTenantTabletMetaIterator +#include "share/schema/ob_part_mgr_util.h" // ObPartitionSchemaIter +#include "share/schema/ob_schema_mgr_cache.h" // ObSchemaMgrItem + +#include "rootserver/ob_partition_balance.h" // ObPartitionHelper +#include "ob_all_balance_group_builder.h" + +#define ISTAT(fmt, args...) FLOG_INFO("[BALANCE_GROUP_BUILDER] " fmt, K_(mod), ##args) +#define WSTAT(fmt, args...) FLOG_WARN("[BALANCE_GROUP_BUILDER] " fmt, K_(mod), ##args) + +#define ADD_NEW_PART(bg, table_id, part_object_id, tablet_id, dest_ls_id, in_new_pg) \ + do {\ + if (OB_FAIL(add_new_part_(bg, table_id, part_object_id, tablet_id, dest_ls_id, in_new_pg))) {\ + LOG_WARN("add new partition fail", KR(ret), K(bg), K(table_id), K(part_object_id), \ + K(dest_ls_id), K(in_new_pg));\ + }\ + } while (0) + +namespace oceanbase +{ +using namespace share; +using namespace share::schema; +using namespace common; +namespace rootserver +{ +ObAllBalanceGroupBuilder::ObAllBalanceGroupBuilder() : + inited_(false), + mod_(""), + tenant_id_(OB_INVALID_TENANT_ID), + callback_(NULL), + sql_proxy_(NULL), + schema_service_(NULL), + schema_guard_(schema::ObSchemaMgrItem::MOD_PARTITION_BALANCE), + tablet_to_ls_(), + tablet_data_size_() +{ +} + +ObAllBalanceGroupBuilder::~ObAllBalanceGroupBuilder() +{ + destroy(); +} + +int ObAllBalanceGroupBuilder::init(const int64_t tenant_id, + const char *mod, + NewPartitionCallback &callback, + common::ObMySQLProxy &sql_proxy, + share::schema::ObMultiVersionSchemaService &schema_service) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("ObAllBalanceGroupBuilder init twice", KR(ret), K(inited_)); + } else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id) || OB_ISNULL(mod)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(mod)); + } else if (OB_FAIL(tablet_to_ls_.init(MAP_BUCKET_NUM, lib::ObLabel("TabletToLS")))) { + LOG_WARN("create map for tablet to LS fail", KR(ret), K(tenant_id)); + } else if (OB_FAIL(tablet_data_size_.create(MAP_BUCKET_NUM, lib::ObLabel("TabletSizeMap")))) { + LOG_WARN("create map for tablet data size fail", KR(ret), K(tenant_id)); + } else { + mod_ = mod; + tenant_id_ = tenant_id; + callback_ = &callback; + sql_proxy_ = &sql_proxy; + schema_service_ = &schema_service; + schema_guard_.reset(); + inited_ = true; + } + return ret; +} + +void ObAllBalanceGroupBuilder::destroy() +{ + inited_ = false; + tablet_data_size_.destroy(); + tablet_to_ls_.destroy(); + schema_guard_.reset(); + schema_service_ = NULL; + sql_proxy_ = NULL; + callback_ = NULL; + tenant_id_ = OB_INVALID_TENANT_ID; + mod_ = ""; +} + +int ObAllBalanceGroupBuilder::prepare(bool need_load_tablet_size) +{ + int ret = OB_SUCCESS; + int64_t start_time = ObTimeUtility::current_time(); + int64_t step_time = 0; + + if (OB_UNLIKELY(! inited_) || OB_ISNULL(schema_service_) || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObAllBalanceGroupBuilder not inited", KR(ret), K(inited_), K(schema_service_), + K(sql_proxy_)); + } + // prepare schema first, to ensure that tablet_to_ls is newer than schema + else if (OB_FAIL(schema_service_->get_tenant_schema_guard(tenant_id_, schema_guard_))) { + LOG_WARN("get tenant schema guard fail", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(tablet_to_ls_.build(tenant_id_, *sql_proxy_))) { + LOG_WARN("build tablet to LS info fail", KR(ret), K(tenant_id_)); + } else if (FALSE_IT(step_time = ObTimeUtility::current_time())) { + } else if (need_load_tablet_size && OB_FAIL(prepare_tablet_data_size_())) { + LOG_WARN("prepare tablet data size fail", KR(ret)); + } + + int64_t finish_time = ObTimeUtility::current_time(); + ISTAT("prepare data", KR(ret), K_(tenant_id), "cost", finish_time - start_time, + "tablet_to_ls_count", tablet_to_ls_.size(), + "cost1", step_time - start_time, + "cost2", finish_time - step_time); + return ret; +} + +int ObAllBalanceGroupBuilder::build() +{ + int ret = OB_SUCCESS; + int64_t start_time = ObTimeUtility::current_time(); + + ISTAT("begin build balance group"); + + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObAllBalanceGroupBuilder not init", KR(ret), K(this)); + } else if (OB_FAIL(do_build_())) { + LOG_WARN("do build balance group info fail", KR(ret)); + } + + ISTAT("finish build balance group", KR(ret), + "cost", ObTimeUtility::current_time() - start_time); + + return ret; +} + +int ObAllBalanceGroupBuilder::do_build_() +{ + int ret = OB_SUCCESS; + // process table in tablegroup + ObArray tablegroup_schemas; + // process table not in tablegroup + ObArray tenant_table_schemas; + + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObAllBalanceGroupBuilder not init", KR(ret), K(inited_)); + } else if (OB_FAIL(schema_guard_.get_tablegroup_schemas_in_tenant(tenant_id_, tablegroup_schemas))) { + LOG_WARN("get tablegroup schemas in tenant fail", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(schema_guard_.get_table_schemas_in_tenant(tenant_id_, tenant_table_schemas))) { + LOG_WARN("get table schemas fail", KR(ret), K(tenant_id_)); + } else { + for (int64_t tg = 0; OB_SUCC(ret) && tg < tablegroup_schemas.count(); tg++) { + int max_part_level = PARTITION_LEVEL_ZERO; + ObArray tg_table_schemas; + const ObSimpleTablegroupSchema *tablegroup_schema = tablegroup_schemas.at(tg); + if (OB_ISNULL(tablegroup_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablegroup schema is null", KR(ret), K(tenant_id_), K(tg)); + } else if (OB_FAIL(get_table_schemas_in_tablegroup_(*tablegroup_schema, + tg_table_schemas, max_part_level))) { + LOG_WARN("get table schemas in tablegroup fail", KR(ret), K(tenant_id_), K(tablegroup_schema)); + } else if (OB_FAIL(build_balance_group_for_tablegroup_(*tablegroup_schema, tg_table_schemas, + max_part_level))) { + LOG_WARN("build balance group for tablegroup fail", KR(ret), KPC(tablegroup_schema), + K(max_part_level), K(tg_table_schemas)); + } + } + + for (int64_t idx = 0; OB_SUCC(ret) && idx < tenant_table_schemas.count(); idx++) { + const ObSimpleTableSchemaV2 *table_schema = tenant_table_schemas.at(idx); + if (OB_ISNULL(table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table schema is null", KR(ret), K(tenant_id_), K(idx)); + } else if (OB_FAIL(build_balance_group_for_table_not_in_tablegroup_(*table_schema))) { + LOG_WARN("build balance group for table not in tablegroup fail", KR(ret), KPC(table_schema)); + } + } + } + + return ret; +} + +int ObAllBalanceGroupBuilder::get_table_schemas_in_tablegroup_( + const ObSimpleTablegroupSchema &tablegroup_schema, + ObArray &table_schemas, + int &max_part_level) +{ + int ret = OB_SUCCESS; + int64_t tablegroup_id = tablegroup_schema.get_tablegroup_id(); + ObArray all_table_schemas; + + max_part_level = PARTITION_LEVEL_ZERO; + + if (OB_FAIL(schema_guard_.get_table_schemas_in_tablegroup(tenant_id_, tablegroup_id, all_table_schemas))) { + LOG_WARN("get_table_schemas_in_tablegroup fail", KR(ret), K(tenant_id_), K(tablegroup_id)); + } else if (all_table_schemas.empty()) { + // + } else { + for (int64_t t = 0; OB_SUCC(ret) && t < all_table_schemas.count(); t++) { + if (OB_ISNULL(all_table_schemas.at(t))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table_schema ptr is null", KR(ret), K(tablegroup_id), K(t)); + } else if (all_table_schemas.at(t)->is_global_index_table()) { + //skip + } else if (OB_FAIL(table_schemas.push_back(all_table_schemas.at(t)))) { + LOG_WARN("push table_schema to array fail", KR(ret)); + } else if (all_table_schemas.at(t)->get_part_level() > max_part_level) { + max_part_level = all_table_schemas.at(t)->get_part_level(); + } + } + } + return ret; +} + + +int ObAllBalanceGroupBuilder::build_balance_group_for_tablegroup_( + const ObSimpleTablegroupSchema &tablegroup_schema, + const ObArray &table_schemas, + const int max_part_level) +{ + int ret = OB_SUCCESS; + uint64_t tablegroup_id = tablegroup_schema.get_tablegroup_id(); + + if (is_sys_tablegroup_id(tablegroup_id)) { + // skip sys tablegroup + } else if (table_schemas.empty()) { + ISTAT("table_schemas empty in tablegroup, need not build balance group", K_(tenant_id), K(tablegroup_schema)); + // do nothing + } else if (tablegroup_schema.is_sharding_none() || PARTITION_LEVEL_ZERO == max_part_level) { + // sharding none tablegroup or non-partition tables always distribute together on same LS + if (OB_FAIL(build_bg_for_tablegroup_sharding_none_(tablegroup_schema, table_schemas, max_part_level))) { + LOG_WARN("fail to build balance group for tablegroup NONE sharding or non-part tables", KR(ret), K(tenant_id_), + K(tablegroup_schema), K(max_part_level)); + } + } else if (tablegroup_schema.is_sharding_partition() || PARTITION_LEVEL_ONE == max_part_level) { + if (OB_FAIL(build_bg_for_tablegroup_sharding_partition_(tablegroup_schema, table_schemas, max_part_level))) { + LOG_WARN("fail to build balance group for tablegroup PARTITION sharding or level-one part tables", + KR(ret), K(tenant_id_), K(tablegroup_schema), K(max_part_level)); + } + } else if (tablegroup_schema.is_sharding_adaptive()) { + if (PARTITION_LEVEL_TWO != max_part_level) { + // should be two-level part tables, other part level should not be here + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid partition level", KR(ret), K(max_part_level), K(tenant_id_), K(tablegroup_schema)); + } else if (OB_FAIL(build_bg_for_tablegroup_sharding_subpart_(tablegroup_schema, table_schemas, + max_part_level))) { + LOG_WARN("fail build balance group for tablegroup ADAPTIVE sharding and two level partition tables", + KR(ret), K(tenant_id_), K(tablegroup_schema), K(max_part_level)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tablegroup sharding", KR(ret), K(tenant_id_), K(tablegroup_schema), + K(max_part_level)); + } + + return ret; +} + +int ObAllBalanceGroupBuilder::build_balance_group_for_table_not_in_tablegroup_( + const ObSimpleTableSchemaV2 &table_schema) +{ + int ret = OB_SUCCESS; + + if (!table_schema.is_global_index_table() && OB_INVALID_ID != table_schema.get_tablegroup_id()) { + // skip table not in tablegroup + // global index should not in tablegroup, here is defensive code + } else if (need_balance_table(table_schema)) { + if (PARTITION_LEVEL_ZERO == table_schema.get_part_level()) { + if (OB_FAIL(build_bg_for_partlevel_zero_(table_schema))) { + LOG_WARN("fail build balance group for partlevel zero table", KR(ret), K(tenant_id_), K(table_schema)); + } + } else if (PARTITION_LEVEL_ONE == table_schema.get_part_level()) { + if (OB_FAIL(build_bg_for_partlevel_one_(table_schema))) { + LOG_WARN("fail build balance group for partlevel one table", KR(ret), K(tenant_id_), + K(table_schema)); + } + } else if (PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + if (OB_FAIL(build_bg_for_partlevel_two_(table_schema))) { + LOG_WARN("fail build balance group for partlevel two table", KR(ret), K(tenant_id_), K(table_schema)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table part level", KR(ret), K(table_schema)); + } + } + return ret; +} + +// all part in one partition group and balance group +int ObAllBalanceGroupBuilder::build_bg_for_tablegroup_sharding_none_( + const ObSimpleTablegroupSchema &tablegroup_schema, + const ObArray &table_schemas, + const int64_t max_part_level) +{ + int ret = OB_SUCCESS; + ObBalanceGroup bg; + const ObString &tablegroup_name = tablegroup_schema.get_tablegroup_name(); + if (OB_FAIL(bg.init_by_tablegroup(tablegroup_schema, max_part_level))) { + LOG_WARN("init balance group by tablegroup fail", KR(ret), K(bg), K(max_part_level), + K(tablegroup_schema)); + } else { + ObLSID dest_ls_id; // binding to the first table first tablet + bool in_new_pg = true; // in new partition group + for (int64_t t = 0; OB_SUCC(ret) && t < table_schemas.count(); t++) { + const ObSimpleTableSchemaV2 *table_schema = table_schemas.at(t); + if (OB_ISNULL(table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table_schema is null", KR(ret), K(tenant_id_), K(tablegroup_schema), K(t)); + } else { + const uint64_t table_id = table_schema->get_table_id(); + ObPartitionSchemaIter iter(*table_schema, CHECK_PARTITION_MODE_NORMAL); + ObPartitionSchemaIter::Info info; + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.next_partition_info(info))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } + } else { + ObObjectID part_object_id = info.object_id_; + ObTabletID tablet_id = info.tablet_id_; + + ADD_NEW_PART(bg, table_id, part_object_id, tablet_id, dest_ls_id, in_new_pg); + } + } + } + } + } + + ISTAT("build balance group for table group of NONE sharding or non-partition tables", + KR(ret), + K(max_part_level), + K(tablegroup_schema), + "table_count", table_schemas.count()); + return ret; +} + +int ObAllBalanceGroupBuilder::get_primary_schema_and_check_all_partition_matched_( + const ObSimpleTablegroupSchema &tablegroup_schema, + const ObArray &table_schemas, + const ObSimpleTableSchemaV2* &primary_table_schema, + const bool is_subpart) +{ + int ret = OB_SUCCESS; + // check partition match + for (int64_t t = 0; OB_SUCC(ret) && t < table_schemas.count(); t++) { + bool match = false; + if (OB_ISNULL(table_schemas.at(t))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table schema is null", KR(ret), K(tablegroup_schema), K(t)); + } else if (PARTITION_LEVEL_ZERO == table_schemas.at(t)->get_part_level()) { + // other logic ensures that code will not be here + ret = OB_ERR_UNEXPECTED; + LOG_WARN("non-partition table should not be here", KR(ret), K(tablegroup_schema), KPC(table_schemas.at(t))); + } else if (is_subpart && PARTITION_LEVEL_TWO != table_schemas.at(t)->get_part_level()) { + // other logic ensures that code will not be here + ret = OB_ERR_UNEXPECTED; + LOG_WARN("only two-level partition table should be here", KR(ret), K(tablegroup_schema), KPC(table_schemas.at(t))); + } else if (OB_ISNULL(primary_table_schema)) { + primary_table_schema = table_schemas.at(t); + } else if (OB_FAIL(ObPartitionHelper::check_partition_option(*table_schemas.at(t), *primary_table_schema, is_subpart, match))) { + LOG_WARN("check partition option fail", KR(ret), K(*table_schemas.at(t)), K(*primary_table_schema), K(is_subpart)); + } else if (!match) { + LOG_WARN("two tables’ partition method not consistent, skip balance for this table group", + K(tablegroup_schema), "table", *table_schemas.at(t), "primary_table", *primary_table_schema); + primary_table_schema = nullptr; + break; + } + } + return ret; +} + +int ObAllBalanceGroupBuilder::build_bg_for_tablegroup_sharding_partition_( + const ObSimpleTablegroupSchema &tablegroup_schema, + const ObArray &table_schemas, + const int64_t max_part_level) +{ + int ret = OB_SUCCESS; + ObBalanceGroup bg; + const ObSimpleTableSchemaV2* primary_table_schema = nullptr; + + // tablegroup is one balance group + if (OB_FAIL(bg.init_by_tablegroup(tablegroup_schema, max_part_level))) { + LOG_WARN("init balance group by tablegroup fail", KR(ret), K(bg), K(max_part_level), + K(tablegroup_schema)); + } else if (OB_FAIL(get_primary_schema_and_check_all_partition_matched_(tablegroup_schema, + table_schemas, primary_table_schema, false/*is_subpart*/))) { + LOG_WARN("get primary schema and check all partition matched in table group fail", KR(ret), + K(tablegroup_schema), K(table_schemas.count())); + } + + for (int64_t p = 0; OB_SUCC(ret) && primary_table_schema != nullptr && p < primary_table_schema->get_partition_num(); p++) { + ObLSID dest_ls_id; + // partitions/subpartitions of all tables with same one-level-partition-value, are in the same partition group. + // Here, partitions/subpartitions with same one-level-partition-index of all tables are in the same partition group + bool in_new_pg = true; // in new partition group + for (int64_t t = 0; OB_SUCC(ret) && t < table_schemas.count(); t++) { + const ObSimpleTableSchemaV2 &table_schema = *table_schemas.at(t); + const uint64_t table_id = table_schema.get_table_id(); + if (PARTITION_LEVEL_ONE == table_schema.get_part_level()) { + ObPartitionHelper::ObPartInfo part_info; + if (OB_FAIL(ObPartitionHelper::get_part_info(table_schema, p, part_info))) { + LOG_WARN("get part info fail", KR(ret), K(table_schema), K(p)); + } else { + // one-level partition object id + ObObjectID part_object_id = part_info.get_part_id(); + ObTabletID tablet_id = part_info.get_tablet_id(); + + ADD_NEW_PART(bg, table_id, part_object_id, tablet_id, dest_ls_id, in_new_pg); + } + } else if (PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + int64_t sub_part_num = 0; + if (OB_FAIL(ObPartitionHelper::get_sub_part_num(table_schema, p, sub_part_num))) { + LOG_WARN("get sub partition number fail", KR(ret), K(p), K(table_schema)); + } else { + for (int64_t sp = 0; OB_SUCC(ret) && sp < sub_part_num; sp++) { + ObPartitionHelper::ObPartInfo part_info; + if (OB_FAIL(ObPartitionHelper::get_sub_part_info(table_schema, p, sp, part_info))) { + LOG_WARN("get sub partition info fail", KR(ret), K(table_schema), K(p), K(sp)); + } else { + // two-level subpartition object id + ObObjectID part_object_id = part_info.get_part_id(); + ObTabletID tablet_id = part_info.get_tablet_id(); + + ADD_NEW_PART(bg, table_id, part_object_id, tablet_id, dest_ls_id, in_new_pg); + } + } + } + } else { + // PARTITION_LEVEL_ZERO should not be here + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table part_level", KR(ret), K(tablegroup_schema), K(table_schema)); + } + } + } + ISTAT("build balance group for tablegroup of PARTITION sharding or one-level partition tables", + KR(ret), + K(max_part_level), + K(tablegroup_schema), + "table_count", table_schemas.count()); + return ret; +} + +int ObAllBalanceGroupBuilder::build_bg_for_tablegroup_sharding_subpart_( + const ObSimpleTablegroupSchema &tablegroup_schema, + const ObArray &table_schemas, + const int max_part_level) +{ + int ret = OB_SUCCESS; + const ObSimpleTableSchemaV2* primary_table_schema = nullptr; + + // check partition + if (OB_FAIL(get_primary_schema_and_check_all_partition_matched_(tablegroup_schema, table_schemas, + primary_table_schema, true/*is_subpart*/))) { + LOG_WARN("get primary schema and check all partition is matched fail", KR(ret), + K(tablegroup_schema), K(table_schemas.count())); + } + + // every level one part(all table) as one balance group + // every level two part(all table) as one partition group + for (int64_t part_idx = 0; OB_SUCC(ret) && primary_table_schema != nullptr && part_idx < primary_table_schema->get_partition_num(); part_idx++) { + ObBalanceGroup bg; + const ObPartition *partition = NULL; + if (OB_FAIL(primary_table_schema->get_partition_by_partition_index(part_idx, CHECK_PARTITION_MODE_NORMAL, partition))) { + LOG_WARN("get_partition_by_partition_index fail", KR(ret), K(part_idx), K(primary_table_schema)); + } else if (OB_ISNULL(partition)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part ptr is null", KR(ret), K(part_idx), K(primary_table_schema)); + } else if (OB_FAIL(bg.init_by_tablegroup(tablegroup_schema, max_part_level, part_idx))) { + LOG_WARN("init balance group by tablegroup fail", KR(ret), K(bg), K(max_part_level), + K(tablegroup_schema), K(part_idx)); + } else { + for (int64_t sp = 0; OB_SUCC(ret) && sp < partition->get_sub_part_num(); sp++) { + ObLSID dest_ls_id; + bool in_new_pg = true; // in new partition group + for (int64_t t = 0; OB_SUCC(ret) && t < table_schemas.count(); t++) { + const ObSimpleTableSchemaV2 &table_schema = *table_schemas.at(t); + const uint64_t table_id = table_schema.get_table_id(); + ObPartitionHelper::ObPartInfo part_info; + if (OB_FAIL(ObPartitionHelper::get_sub_part_info(table_schema, part_idx, sp, part_info))) { + LOG_WARN("get sub partition info fail", KR(ret), K(table_schema), K(part_idx), K(sp)); + } else { + // two-level subpartition object id + ObObjectID part_object_id = part_info.get_part_id(); + ObTabletID tablet_id = part_info.get_tablet_id(); + + ADD_NEW_PART(bg, table_id, part_object_id, tablet_id, dest_ls_id, in_new_pg); + } + } + } + } + } + + ISTAT("build balance group for table group of SUBPARTITION sharding", + KR(ret), + K(max_part_level), + K(tablegroup_schema), + "table_count", table_schemas.count()); + return ret; +} + +int ObAllBalanceGroupBuilder::build_bg_for_partlevel_zero_(const ObSimpleTableSchemaV2 &table_schema) +{ + // all none partition tables belong to one balance group + // every table tablet is a single partition group + int ret = OB_SUCCESS; + ObBalanceGroup bg; + if (OB_FAIL(bg.init_by_table(table_schema, NULL/*partition*/))) { + LOG_WARN("init balance group by table fail", KR(ret), K(bg), K(table_schema)); + } else { + bool in_new_pg = true; // in new partition group + ObLSID dest_ls_id; + const uint64_t table_id = table_schema.get_table_id(); + ObObjectID part_object_id = 0; + ObTabletID tablet_id = table_schema.get_tablet_id(); + + ADD_NEW_PART(bg, table_id, part_object_id, tablet_id, dest_ls_id, in_new_pg); + } + return ret; +} + +int ObAllBalanceGroupBuilder::build_bg_for_partlevel_one_(const ObSimpleTableSchemaV2 &table_schema) +{ + int ret = OB_SUCCESS; + // one-level partition table is oneself a balance group + // every partition of table is a single partition group + ObBalanceGroup bg; + if (OB_FAIL(bg.init_by_table(table_schema, NULL/*partition*/))) { + LOG_WARN("init balance group by table fail", KR(ret), K(bg), K(table_schema)); + } else { + const uint64_t table_id = table_schema.get_table_id(); + for (int64_t part_idx = 0; OB_SUCC(ret) && part_idx < table_schema.get_partition_num(); part_idx++) { + const ObPartition *part = nullptr; + if (OB_FAIL(table_schema.get_partition_by_partition_index(part_idx, CHECK_PARTITION_MODE_NORMAL, part))) { + LOG_WARN("get partition by part_idx fail", KR(ret), K(table_schema), K(part_idx)); + } else if (OB_ISNULL(part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition is null", KR(ret), K(table_schema)); + } else { + bool in_new_pg = true; // in new partition group + ObLSID dest_ls_id; + ObObjectID part_object_id = part->get_part_id(); + ObTabletID tablet_id = part->get_tablet_id(); + + ADD_NEW_PART(bg, table_id, part_object_id, tablet_id, dest_ls_id, in_new_pg); + } + } + } + return ret; +} + +int ObAllBalanceGroupBuilder::build_bg_for_partlevel_two_(const ObSimpleTableSchemaV2 &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t table_id = table_schema.get_table_id(); + ObPartIterator iter(table_schema, CHECK_PARTITION_MODE_NORMAL); + while (OB_SUCC(ret)) { + const ObPartition *part = nullptr; + if (OB_FAIL(iter.next(part))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } + } else if (OB_ISNULL(part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition is null", KR(ret), K(table_schema)); + } else { + // every partition is a independent balance group + ObBalanceGroup bg; + if (OB_FAIL(bg.init_by_table(table_schema, part/*partition*/))) { + LOG_WARN("init balance group by table fail", KR(ret), K(bg), K(table_schema), KPC(part)); + } else { + ObSubPartIterator subpart_iter(table_schema, *part, CHECK_PARTITION_MODE_NORMAL); + while (OB_SUCC(ret)) { + const ObSubPartition *sub_part = nullptr; + if (OB_FAIL(subpart_iter.next(sub_part))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } + } else if (OB_ISNULL(sub_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sub partition is null", KR(ret), K(table_schema)); + } else { + // every subpartition is a independent partition group + ObLSID dest_ls_id; + bool in_new_pg = true; // in new partition group + ObObjectID part_object_id = sub_part->get_sub_part_id(); + ObTabletID tablet_id = sub_part->get_tablet_id(); + + ADD_NEW_PART(bg, table_id, part_object_id, tablet_id, dest_ls_id, in_new_pg); + } + } + } + } + } + return ret; +} + +int ObAllBalanceGroupBuilder::add_new_part_( + const ObBalanceGroup &bg, + const ObObjectID table_id, + const ObObjectID part_object_id, + const ObTabletID tablet_id, + ObLSID &dest_ls_id, + bool &in_new_partition_group) +{ + int ret = OB_SUCCESS; + ObLSID src_ls_id; + + // Tablet data size may not exist, as meta table may not be reported or tablet be dropped + // Ignore tablet size not exist error + const uint64_t *tablet_size_ptr = tablet_data_size_.get(tablet_id); + const uint64_t tablet_size = (tablet_size_ptr != nullptr ? *tablet_size_ptr : 0); + + if (OB_ISNULL(callback_)) { + ret = OB_NOT_INIT; + LOG_WARN("callback is NULL, unexpected", KR(ret), K(callback_)); + } else if (OB_FAIL(tablet_to_ls_.get(tablet_id, src_ls_id))) { + LOG_WARN("fail to get LS info for tablet, tablet may be dropped", KR(ret), K(tablet_id), K(table_id)); + if (OB_HASH_NOT_EXIST == ret) { + ret = OB_SUCCESS; + // skip this partition + } + } else if ((in_new_partition_group && dest_ls_id.is_valid()) + || (!in_new_partition_group && !dest_ls_id.is_valid())) { + // dest_ls_id should only be valid when this partition is the first partition in new partition group + ret = OB_INVALID_ARGUMENT; + LOG_WARN("dest_ls_id or in_new_partition_group is invalid", KR(ret), K(in_new_partition_group), + K(dest_ls_id), K(bg), K(table_id), K(part_object_id), K(tablet_id)); + } else if (in_new_partition_group && FALSE_IT(dest_ls_id = src_ls_id)) { + // use first partition's LS as all other partitions' LS in same partition group + } else if (OB_FAIL(callback_->on_new_partition( + bg, + table_id, + part_object_id, + tablet_id, + src_ls_id, + dest_ls_id, + tablet_size, + in_new_partition_group))) { + LOG_WARN("callback handle new partition fail", KR(ret), K(bg), K(table_id), K(part_object_id), + K(tablet_id), K(src_ls_id), K(dest_ls_id), K(tablet_size), K(in_new_partition_group)); + } else { + // auto clear flag + in_new_partition_group = false; + } + return ret; +} + +// TODO: @wanhong.wwh only load USER LS tablet data size +int ObAllBalanceGroupBuilder::prepare_tablet_data_size_() +{ + int ret = OB_SUCCESS; + int64_t start_time = ObTimeUtility::current_time(); + ObTenantTabletMetaIterator iter; + if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql_proxy is null", KR(ret)); + } else if (OB_FAIL(iter.init(*sql_proxy_, tenant_id_))) { + LOG_WARN("init tenant tablet meta table iterator fail", KR(ret), K(tenant_id_)); + } else { + iter.set_batch_size(1000); + ObTabletInfo tablet_info; + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.next(tablet_info))) { + if (OB_ITER_END != ret) { + LOG_WARN("iter next tenant meta table info fail", KR(ret), K(tenant_id_)); + } else { + ret = OB_SUCCESS; + break; + } + } else { + int64_t tablet_size = 0; + for (int64_t i = 0; i < tablet_info.get_replicas().count(); i++) { + if (tablet_info.get_replicas().at(i).get_data_size() > tablet_size) { + tablet_size = tablet_info.get_replicas().at(i).get_data_size(); + } + } + if (OB_FAIL(tablet_data_size_.set_refactored(tablet_info.get_tablet_id(), tablet_size))) { + LOG_WARN("tablet_data_size set_refactored fail", KR(ret), K(tenant_id_), K(tablet_info)); + } + } + } + } + + int64_t finish_time = ObTimeUtility::current_time(); + ISTAT("prepare tablet data_size", KR(ret), K_(tenant_id), "cost", finish_time - start_time, "count", tablet_data_size_.size()); + return ret; +} + +} +} + +#undef ISTAT +#undef WSTAT +#undef ADD_NEW_PART diff --git a/src/rootserver/balance/ob_all_balance_group_builder.h b/src/rootserver/balance/ob_all_balance_group_builder.h new file mode 100644 index 000000000..83baed537 --- /dev/null +++ b/src/rootserver/balance/ob_all_balance_group_builder.h @@ -0,0 +1,161 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_ALL_BALANCE_GROUP_BUILDER_H +#define OCEANBASE_ROOTSERVER_OB_ALL_BALANCE_GROUP_BUILDER_H + +#include "lib/ob_define.h" // ObObjectID +#include "lib/container/ob_array.h" //ObArray +#include "common/ob_tablet_id.h" // ObTabletID +#include "share/ob_ls_id.h" // ObLSID +#include "share/schema/ob_multi_version_schema_service.h" // share::schema +#include "share/schema/ob_schema_getter_guard.h" // ObSchemaGetterGuard +#include "share/tablet/ob_tenant_tablet_to_ls_map.h" // ObTenantTabletToLSMap + +#include "ob_balance_group_define.h" //ObBalanceGroupID, ObBalanceGroup + +namespace oceanbase +{ +namespace rootserver +{ + +// Tenant all balance group builder +// +// You can use the builder to build all balance groups of tenant. +// It will iterate all partitions of user table/global index/tmp table to decide balance group info. +// You can register NewPartitionCallback to handle every partiitons, to get their balance group info. +// +// Partition belongs to one Partition Group. one or more Partition Groups forms a balance group. +// Tenant have multiple balance groups. Every table have one or more balance groups. +// +// USAGE: +// 1. define a type derived from ObAllBalanceGroupBuilder::NewPartitionCallback to handle new +// partition info of every balance group +// +// 2. define ObAllBalanceGroupBuilder object +// 1) call prepare() function to prepare data for this build +// 2) call build() function to build all balance groups for all partitions. +class ObAllBalanceGroupBuilder final +{ +public: + ObAllBalanceGroupBuilder(); + ~ObAllBalanceGroupBuilder(); + + class NewPartitionCallback; + int init(const int64_t tenant_id, + const char *mod, + NewPartitionCallback &callback, + common::ObMySQLProxy &sql_proxy, + share::schema::ObMultiVersionSchemaService &schema_service); + void destroy(); + + // do prepare work + // prepare data before build + int prepare(bool need_load_tablet_size = false); + + // Iterator tenant all partitions, to build balance group info + // + // This function will call NewPartitionCallback to handle new partition + int build(); + +public: + class NewPartitionCallback + { + public: + virtual ~NewPartitionCallback() {} + + // callback function callled when find new partition in one balance group + // NOTE: partitions in same partition group will output successively. + // You can check 'in_new_partition_group' to find whether new partition group found + // + // @param [in] bg balance group + // @param [in] table_id table id of partition + // @param [in] part_object_id partition object id: part id for one-level part table, subpart id for two-level part table + // @param [in] tablet_id tablet id + // @param [in] src_ls_id the LS that partition is current located + // @param [in] dest_ls_id the LS that partition should be located + // @param [in] tablet_size tablet data size + // @param [in] in_new_partition_group is this partition in new partition group + virtual int on_new_partition( + const ObBalanceGroup &bg, + const common::ObObjectID table_id, + const common::ObObjectID part_object_id, + const common::ObTabletID tablet_id, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const int64_t tablet_size, + const bool in_new_partition_group) = 0; + }; + +private: + int prepare_tablet_to_ls_( + const uint64_t tenant_id, + common::ObMySQLProxy &sql_proxy); + int do_build_(); + int get_table_schemas_in_tablegroup_( + const share::schema::ObSimpleTablegroupSchema &tablegroup_schema, + common::ObArray &table_schemas, + int &max_part_level); + int build_balance_group_for_tablegroup_( + const share::schema::ObSimpleTablegroupSchema &tablegroup_schema, + const common::ObArray &table_schemas, + const int max_part_level); + int build_balance_group_for_table_not_in_tablegroup_( + const share::schema::ObSimpleTableSchemaV2 &table_schema); + int build_bg_for_tablegroup_sharding_none_( + const share::schema::ObSimpleTablegroupSchema &tablegroup_schema, + const common::ObArray &table_schemas, + const int64_t max_part_level); + int get_primary_schema_and_check_all_partition_matched_( + const share::schema::ObSimpleTablegroupSchema &tablegroup_schema, + const common::ObArray &table_schemas, + const share::schema::ObSimpleTableSchemaV2* &primary_table_schema, + const bool is_subpart); + int build_bg_for_tablegroup_sharding_partition_( + const share::schema::ObSimpleTablegroupSchema &tablegroup_schema, + const common::ObArray &table_schemas, + const int64_t max_part_level); + int build_bg_for_tablegroup_sharding_subpart_( + const share::schema::ObSimpleTablegroupSchema &tablegroup_schema, + const common::ObArray &table_schemas, + const int max_part_level); + int build_bg_for_partlevel_zero_(const share::schema::ObSimpleTableSchemaV2 &table_schema); + int build_bg_for_partlevel_one_(const share::schema::ObSimpleTableSchemaV2 &table_schema); + int build_bg_for_partlevel_two_(const share::schema::ObSimpleTableSchemaV2 &table_schema); + int add_new_part_( + const ObBalanceGroup &bg, + const common::ObObjectID table_id, + const common::ObObjectID part_object_id, + const common::ObTabletID tablet_id, + share::ObLSID &dest_ls_id, + bool &in_new_partition_group); + int prepare_tablet_data_size_(); + +private: + static const int64_t MAP_BUCKET_NUM = 40960; + + bool inited_; + const char* mod_; + uint64_t tenant_id_; + NewPartitionCallback *callback_; + common::ObMySQLProxy *sql_proxy_; + share::schema::ObMultiVersionSchemaService *schema_service_; + + share::schema::ObSchemaGetterGuard schema_guard_; + share::ObTenantTabletToLSMap tablet_to_ls_; + + hash::ObHashMap tablet_data_size_; +}; + +} +} +#endif /* !OCEANBASE_ROOTSERVER_OB_ALL_BALANCE_GROUP_BUILDER_H */ diff --git a/src/rootserver/balance/ob_balance_group_define.cpp b/src/rootserver/balance/ob_balance_group_define.cpp new file mode 100644 index 000000000..dab546279 --- /dev/null +++ b/src/rootserver/balance/ob_balance_group_define.cpp @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2021 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. + */ +#define USING_LOG_PREFIX BALANCE + +#include "lib/string/ob_string.h" // ObString +#include "lib/string/ob_sql_string.h" // ObSqlString +#include "share/schema/ob_schema_mgr.h" // ObSimpleTableSchemaV2 +#include "share/schema/ob_table_schema.h" // ObTableSchema +#include "share/schema/ob_schema_struct.h" // ObPartition + +#include "ob_balance_group_define.h" + +namespace oceanbase +{ +using namespace common; +using namespace share; +using namespace share::schema; +namespace rootserver +{ + +int ObBalanceGroup::init_by_tablegroup(const ObSimpleTablegroupSchema &tg, + const int64_t max_part_level, + const int64_t part_group_index/* = 0*/) +{ + int ret = OB_SUCCESS; + ObSqlString bg_name_str; + const ObString &tg_name = tg.get_tablegroup_name(); + + if (tg.is_sharding_none() + || tg.is_sharding_partition() + || (tg.is_sharding_adaptive() + && (PARTITION_LEVEL_ZERO == max_part_level || PARTITION_LEVEL_ONE == max_part_level))) { + // Table Group is a independent balance group + if (OB_FAIL(bg_name_str.append_fmt("TABLEGROUP_%s", tg_name.ptr()))) { + LOG_WARN("fail to append fmt", KR(ret), K(tg)); + } else { + id_ = ObBalanceGroupID(tg.get_tablegroup_id(), 0); + } + } else if (!tg.is_sharding_adaptive() || PARTITION_LEVEL_TWO != max_part_level || part_group_index < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(max_part_level), K(part_group_index), K(tg)); + } else { + // Every one-level partition is an independent balance group + if (OB_FAIL(bg_name_str.append_fmt("TABLEGROUP_%s_PART_GROUP_%ld", tg_name.ptr(), part_group_index))) { + LOG_WARN("fail to append fmt", KR(ret), K(tg)); + } else { + id_ = ObBalanceGroupID(tg.get_tablegroup_id(), 0); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(name_.assign(bg_name_str.ptr()))) { + LOG_WARN("fail to assign bg name", KR(ret), K(bg_name_str)); + } + return ret; +} + +int ObBalanceGroup::hash(uint64_t &res) const +{ + return id_.hash(res); +} +int ObBalanceGroup::init_by_table(const ObSimpleTableSchemaV2 &table_schema, + const ObPartition *partition/* = NULL*/) +{ + int ret = OB_SUCCESS; + ObSqlString bg_name_str; + const uint64_t table_id = table_schema.get_table_id(); + const ObString &table_name = table_schema.get_table_name(); + const int64_t part_level = table_schema.get_part_level(); + const bool is_in_tablegroup = (OB_INVALID_ID != table_schema.get_tablegroup_id()); + + // Table should not be in tablegroup + // NOTE: global index should have no tablegroup id, if it is in tablegroup, it is BUG + if (OB_UNLIKELY(is_in_tablegroup && ! table_schema.is_global_index_table())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("table is in tablegroup, should init balance group by tablegroup", KR(ret), K(table_schema)); + } else if (PARTITION_LEVEL_ZERO == part_level) { + // All tenant's non-partition table is a balance group + if (OB_FAIL(bg_name_str.append_fmt("NON_PART_TABLE"))) { + LOG_WARN("fail to append fmt", KR(ret), K(table_schema)); + } else { + id_ = ObBalanceGroupID(0, 0); + } + } else if (PARTITION_LEVEL_ONE == part_level) { + // Level one partition table is a single balance group + if (OB_FAIL(bg_name_str.append_fmt("TABLE_%s_%lu", table_name.ptr(), table_id))) { + LOG_WARN("fail to append fmt", KR(ret), K(table_name), K(table_id)); + } else { + id_ = ObBalanceGroupID(table_id, 0); + } + } else if (PARTITION_LEVEL_TWO == part_level) { + // Every one-level partition is an independent balance group + if (OB_ISNULL(partition)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(table_schema), KPC(partition)); + } else if (OB_FAIL(bg_name_str.append_fmt("TABLE_%s_%lu_PART_%s", + table_name.ptr(), table_id, partition->get_part_name().ptr()))) { + LOG_WARN("fail to append fmt", KR(ret), K(table_name), K(table_id), KPC(partition)); + } else { + id_ = ObBalanceGroupID(table_id, partition->get_part_id()); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(name_.assign(bg_name_str.ptr()))) { + LOG_WARN("fail to assign bg name", KR(ret), K(bg_name_str)); + } + return ret; +} + +} +} diff --git a/src/rootserver/balance/ob_balance_group_define.h b/src/rootserver/balance/ob_balance_group_define.h new file mode 100644 index 000000000..99e331f0e --- /dev/null +++ b/src/rootserver/balance/ob_balance_group_define.h @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_BALANCE_GROUP_DEFINE_H_ +#define OCEANBASE_ROOTSERVER_OB_BALANCE_GROUP_DEFINE_H_ +#include "lib/ob_define.h" +#include "lib/string/ob_fixed_length_string.h" +#include "share/ob_ls_id.h" + +namespace oceanbase +{ + +namespace share +{ +namespace schema +{ +class ObSimpleTablegroupSchema; +class ObSimpleTableSchemaV2; +class ObPartition; +} +} + +namespace rootserver +{ +typedef common::ObFixedLengthString< + common::OB_MAX_BALANCE_GROUP_NAME_LENGTH> + ObBalanceGroupName; + +struct ObBalanceGroupID +{ +public: + ObBalanceGroupID() : id_high_(common::OB_INVALID_ID), + id_low_(common::OB_INVALID_ID) {} + ObBalanceGroupID(const uint64_t id_high, + const uint64_t id_low) + : id_high_(id_high), + id_low_(id_low) {} + + int hash(uint64_t &res) const { + res = 0; + res = murmurhash(&id_high_, sizeof(id_high_), res); + res = murmurhash(&id_low_, sizeof(id_low_), res); + return common::OB_SUCCESS; + } + bool operator ==(const ObBalanceGroupID &other) const { + return id_high_ == other.id_high_ && + id_low_ == other.id_low_; + } + bool operator !=(const ObBalanceGroupID &other) const { + return !(*this == other); + } + + TO_STRING_KV(K_(id_high), + K_(id_low)); + + bool is_valid() const { + return OB_INVALID_ID != id_high_ + && OB_INVALID_ID != id_low_; + } + +public: + uint64_t id_high_; + uint64_t id_low_; +}; + +class ObBalanceGroup +{ +public: + ObBalanceGroup() : id_(), name_() {} + ~ObBalanceGroup() {} + + const ObBalanceGroupID &id() const { return id_; } + const ObBalanceGroupName &name() const { return name_; } + + int init_by_tablegroup(const share::schema::ObSimpleTablegroupSchema &tg, + const int64_t max_part_level, + const int64_t part_group_index = 0); + int init_by_table(const share::schema::ObSimpleTableSchemaV2 &table_schema, + const share::schema::ObPartition *partition = NULL); + + int hash(uint64_t &res) const; + bool operator ==(const ObBalanceGroup &other) const { + return id_ == other.id_; + } + bool operator !=(const ObBalanceGroup &other) const { + return !(*this == other); + } + + TO_STRING_KV(K_(id), K_(name)); + +private: + ObBalanceGroupID id_; + ObBalanceGroupName name_; + // TODO: add type +}; + +}//end namespace rootserver +}//end namespace oceanbase + +#endif // OCEANBASE_ROOTSERVER_OB_BALANCE_GROUP_DEFINE_H_ diff --git a/src/rootserver/balance/ob_balance_group_info.cpp b/src/rootserver/balance/ob_balance_group_info.cpp new file mode 100644 index 000000000..9c65a42b7 --- /dev/null +++ b/src/rootserver/balance/ob_balance_group_info.cpp @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2021 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. + */ +#define USING_LOG_PREFIX BALANCE + +#include "ob_balance_group_info.h" + +namespace oceanbase +{ +using namespace share; +namespace rootserver +{ +int ObTransferPartGroup::add_part(const ObTransferPartInfo &part, int64_t data_size) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(! part.is_valid() || data_size < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(part), K(data_size)); + } else if (OB_FAIL(part_list_.push_back(part))) { + LOG_WARN("push back part into part info fail", KR(ret), K(part), K(part_list_)); + } else { + data_size_ += data_size; + } + return ret; +} + +/////////////////////////////////////////////// + +ObBalanceGroupInfo::~ObBalanceGroupInfo() +{ + // for each partition group in array, release its memory + for (int64_t i = 0; i < part_groups_.count(); i++) { + ObTransferPartGroup *part_group = part_groups_.at(i); + if (OB_NOT_NULL(part_group)) { + part_group->~ObTransferPartGroup(); + alloc_.free(part_group); + part_group = NULL; + } + } + + part_groups_.destroy(); +} + + +int ObBalanceGroupInfo::append_part(ObTransferPartInfo &part, + const int64_t data_size, + const bool need_create_new_part_group/* = false*/) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(! part.is_valid() || data_size < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(part), K(data_size)); + } else if (need_create_new_part_group && OB_FAIL(create_new_part_group_())) { + LOG_WARN("create new partition group fail", KR(ret), K(need_create_new_part_group)); + } else if (part_groups_.count() <= 0) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("no partition groups in this balance group", KPC(this), KR(ret), K(part)); + } else { + ObTransferPartGroup *part_group = part_groups_.at(part_groups_.count() - 1); + + if (OB_ISNULL(part_group)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid data", KR(ret), KPC(part_group), KPC(this)); + } else if (OB_FAIL(part_group->add_part(part, data_size))) { + LOG_WARN("add part into partition group fail", KR(ret), KPC(part_group), K(part), K(data_size), KPC(this)); + } + + LOG_TRACE("[ObBalanceGroupInfo] append part", K(part), K(data_size), + K(need_create_new_part_group), + "part_group_count", part_groups_.count(), KPC(part_group)); + } + return ret; +} + +int ObBalanceGroupInfo::create_new_part_group_() +{ + int ret = OB_SUCCESS; + ObTransferPartGroup *part_group = NULL; + const int64_t part_group_size = sizeof(ObTransferPartGroup); + + void *buf = alloc_.alloc(part_group_size); + if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory for partition group fail", KR(ret), K(buf), K(part_group_size)); + } else if (OB_ISNULL(part_group = new(buf) ObTransferPartGroup())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("construct ObTransferPartGroup fail", KR(ret), K(buf), K(part_group_size)); + } else if (OB_FAIL(part_groups_.push_back(part_group))) { + LOG_WARN("push back new partition group fail", KR(ret), K(part_group), K(part_groups_)); + } else { + // success + } + return ret; +} + +int ObBalanceGroupInfo::pop_back(const int64_t part_group_count, + share::ObTransferPartList &part, + int64_t &popped_part_count) +{ + int ret = OB_SUCCESS; + + popped_part_count = 0; + if (OB_UNLIKELY(part_group_count > part_groups_.count() || part_group_count <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid part_group_count", KR(ret), K(part_group_count), K(part_groups_.count())); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < part_group_count; i++) { + ObTransferPartGroup *pg = NULL; + if (OB_FAIL(part_groups_.pop_back(pg))) { + LOG_WARN("pop back from part group array fail", KR(ret), K(part_groups_)); + } else if (OB_ISNULL(pg)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part group, is NULL, unexpected", K(pg), K(i), K(part_groups_)); + } else if (FALSE_IT(popped_part_count += pg->count())) { + } else if (OB_FAIL(append(part, pg->get_part_list()))) { + LOG_WARN("append array to part list fail", KR(ret), K(part), KPC(pg)); + } else { + // succ + } + + // free pg memory anyway + if (OB_NOT_NULL(pg)) { + pg->~ObTransferPartGroup(); + alloc_.free(pg); + pg = NULL; + } + } + } + return ret; +} + +} +} diff --git a/src/rootserver/balance/ob_balance_group_info.h b/src/rootserver/balance/ob_balance_group_info.h new file mode 100644 index 000000000..5da87d1e1 --- /dev/null +++ b/src/rootserver/balance/ob_balance_group_info.h @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_BALANCE_GROUP_INFO_H +#define OCEANBASE_ROOTSERVER_OB_BALANCE_GROUP_INFO_H + +#include "lib/container/ob_array.h" //ObArray +#include "lib/allocator/ob_allocator.h" // ObIAllocator +#include "share/transfer/ob_transfer_info.h" // ObTransferPartInfo, ObTransferPartList +#include "ob_balance_group_define.h"//ObBalanceGroupID + +namespace oceanbase +{ +namespace rootserver +{ + +// A group of partitions that should be distributed on the same LS and transfered together +class ObTransferPartGroup +{ +public: + ObTransferPartGroup() : data_size_(0), part_list_() {} + ~ObTransferPartGroup() { + data_size_ = 0; + part_list_.reset(); + } + + int64_t get_data_size() const { return data_size_; } + const share::ObTransferPartList &get_part_list() const { return part_list_; } + int64_t count() const { return part_list_.count(); } + + // add new partition into partition group + int add_part(const share::ObTransferPartInfo &part, int64_t data_size); + + TO_STRING_KV(K_(data_size), K_(part_list)); +private: + int64_t data_size_; + share::ObTransferPartList part_list_; +}; + +// Balance Group Partition Info +// +// A group of Partition Groups (ObTransferPartGroup) that should be evenly distributed on all LS. +class ObBalanceGroupInfo final +{ +public: + explicit ObBalanceGroupInfo(const ObBalanceGroupID &id, common::ObIAllocator &alloc) : + id_(id), + alloc_(alloc), + part_groups_() + { + } + + ~ObBalanceGroupInfo(); + + bool is_valid() { return id_.is_valid(); } + const ObBalanceGroupID &id() const { return id_; } + const common::ObArray get_part_groups() const { return part_groups_; } + int64_t get_part_group_count() const { return part_groups_.count(); } + + // append partition at the newest partition group. create new partition group if needed + // + // @param [in] part target partition info which will be added + // @param [in] data_size partition data size + // @param [in] need_create_new_part_group whether to create new partition group + // + // @return OB_SUCCESS success + // @return OB_ENTRY_EXIST no partition group found + // @return other fail + int append_part(share::ObTransferPartInfo &part, + const int64_t data_size, + const bool need_create_new_part_group = false); + + // pop partition groups from back of array, and push back into part list + // + // @param [in] part_group_count partition group count that need be popped + // @param [in/out] part_list push popped part into the part list + // @param [out] popped_part_count popped partition count + int pop_back(const int64_t part_group_count, + share::ObTransferPartList &part, + int64_t &popped_part_count); + + TO_STRING_KV(K_(id), "part_group_count", part_groups_.count()); + +private: + int create_new_part_group_(); + +private: + ObBalanceGroupID id_; + ObIAllocator &alloc_; // allocator for ObTransferPartGroup + // Partition Group Array + common::ObArray part_groups_; +}; + +} +} +#endif /* !OCEANBASE_ROOTSERVER_OB_BALANCE_GROUP_INFO_H */ diff --git a/src/rootserver/balance/ob_ls_all_part_builder.cpp b/src/rootserver/balance/ob_ls_all_part_builder.cpp new file mode 100644 index 000000000..d6f52ab66 --- /dev/null +++ b/src/rootserver/balance/ob_ls_all_part_builder.cpp @@ -0,0 +1,176 @@ +/** + * Copyright (c) 2021 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. + */ +#define USING_LOG_PREFIX BALANCE + +#include "ob_ls_all_part_builder.h" + +#include "lib/container/ob_se_array.h" // ObSEArray +#include "share/ob_ls_id.h" // ObLSID +#include "share/schema/ob_schema_getter_guard.h" // ObSchemaGetterGuard +#include "share/schema/ob_multi_version_schema_service.h" // ObMultiVersionSchemaService +#include "share/tablet/ob_tablet_to_ls_iterator.h" // ObTenantTabletToLSIterator +#include "share/ob_balance_define.h" // need_balance_table() + +namespace oceanbase +{ +using namespace share; +using namespace share::schema; +using namespace common; +namespace rootserver +{ + +int ObLSAllPartBuilder::build( + const uint64_t tenant_id, + const ObLSID &ls_id, + ObMultiVersionSchemaService &schema_service, + ObISQLClient &sql_proxy, + ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + ObSEArray ls_white_list; + ObTenantTabletToLSIterator iter; + ObSchemaGetterGuard schema_guard; + + part_list.reset(); + if (OB_UNLIKELY(!ls_id.is_valid() || !ls_id.is_valid_with_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_id), K(tenant_id)); + } else if (OB_FAIL(get_latest_schema_guard_(tenant_id, schema_service, sql_proxy, schema_guard))) { + LOG_WARN("get latest schema guard fail", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ls_white_list.push_back(ls_id))) { + LOG_WARN("push back into LS white list fail", KR(ret), K(ls_white_list), K(ls_id)); + } else if (OB_FAIL(iter.init(sql_proxy, tenant_id, ls_white_list))) { + LOG_WARN("init tenant tablet to LS iterator fail", KR(ret), K(tenant_id), K(ls_white_list)); + } else { + ObTabletToLSInfo tablet; + // iterate all tablets on this LS + while (OB_SUCC(ret) && OB_SUCC(iter.next(tablet))) { + ObTransferPartInfo part_info; + bool need_skip = false; + + // build partition info for this tablet + if (OB_FAIL(build_part_info_(tenant_id, tablet, schema_guard, part_info, need_skip))) { + if (OB_NEED_RETRY != ret) { + LOG_WARN("build part info fail", KR(ret), K(tenant_id), K(tablet)); + } + } else if (! need_skip && OB_FAIL(part_list.push_back(part_info))) { + LOG_WARN("failed to push back part_list", KR(ret), K(part_info)); + } else { + tablet.reset(); + } + } + + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + } + return ret; +} + +int ObLSAllPartBuilder::get_latest_schema_guard_( + const uint64_t tenant_id, + ObMultiVersionSchemaService &schema_service, + ObISQLClient &sql_proxy, + ObSchemaGetterGuard &schema_guard) +{ + int ret = OB_SUCCESS; + int64_t version_in_inner_table = OB_INVALID_VERSION; + int64_t schema_version_local = OB_INVALID_VERSION; + ObRefreshSchemaStatus schema_status(tenant_id, OB_INVALID_TIMESTAMP, OB_INVALID_VERSION); + + // get local latest schema guard + if (OB_FAIL(schema_service.get_tenant_schema_guard(tenant_id, schema_guard))) { + LOG_WARN("get tenant schema guard fail", KR(ret), K(tenant_id)); + } + // get latest schema version + else if (OB_FAIL(schema_service.get_schema_version_in_inner_table(sql_proxy, schema_status, + version_in_inner_table))) { + LOG_WARN("fail to get latest schema version in inner table", KR(ret), K(schema_status), + K(tenant_id)); + } else if (OB_FAIL(schema_guard.get_schema_version(tenant_id, schema_version_local))) { + LOG_WARN("failed to get schema version", KR(ret), K(tenant_id)); + } else if (schema_version_local < version_in_inner_table) { + ret = OB_NEED_RETRY; + LOG_WARN("schema not refresh lastest, need wait", KR(ret), K(version_in_inner_table), K(schema_version_local)); + } + return ret; +} + +int ObLSAllPartBuilder::build_part_info_( + const uint64_t tenant_id, + ObTabletToLSInfo &tablet, + ObSchemaGetterGuard &schema_guard, + ObTransferPartInfo &part_info, + bool &need_skip) +{ + int ret = OB_SUCCESS; + const schema::ObSimpleTableSchemaV2 *table_schema = NULL; + + need_skip = false; + + if (OB_UNLIKELY(! tablet.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tablet to ls info", KR(ret), K(tablet)); + } else if (OB_FAIL(schema_guard.get_simple_table_schema(tenant_id, tablet.get_table_id(), table_schema))) { + LOG_WARN("get simple table schema fail", KR(ret), K(tenant_id), K(tablet)); + } else if (OB_ISNULL(table_schema)) { + // schema guard may be not latest, can not find table schema, need retry + ret = OB_NEED_RETRY; + LOG_WARN("table schema is NULL, maybe schema guard is not latest, retry again", KR(ret), K(tablet)); + } else if (! need_balance_table(*table_schema)) { + LOG_INFO("[BUILD_LS_ALL_PART] ignore need not balance table", K(tablet), KPC(table_schema)); + need_skip = true; + } else { + const ObTabletID &tablet_id = tablet.get_tablet_id(); + const uint64_t table_id = tablet.get_table_id(); + + // part object id + // for non-part table, is 0 + // for level-one part table, is partition id + // for level-two part table, is subpartition id + uint64_t part_object_id = OB_INVALID_ID; + + // level-one partition id + int64_t part_id = OB_INVALID_INDEX; // invalid value same with get_part_id_by_table() + // level-two subpartition id + int64_t subpart_id = OB_INVALID_INDEX; // invalid value same with get_part_id_by_table() + + // compute part object id based on table schema and tablet id + if (PARTITION_LEVEL_ZERO == table_schema->get_part_level()) { + part_object_id = 0; + } else if (OB_FAIL(table_schema->get_part_id_by_tablet(tablet_id, part_id, subpart_id))) { + if (OB_TABLET_NOT_EXIST == ret) { + LOG_WARN("tablet not exist in table schema, need retry", KR(ret), K(tablet_id), KPC(table_schema)); + ret = OB_NEED_RETRY; + } else { + LOG_WARN("get part id by tablet fail", KR(ret), K(tablet_id), KPC(table_schema)); + } + } else if (PARTITION_LEVEL_ONE == table_schema->get_part_level()) { + part_object_id = part_id; + } else if (PARTITION_LEVEL_TWO == table_schema->get_part_level()) { + part_object_id = subpart_id; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid partition level", KR(ret), K(table_schema->get_part_level()), + KPC(table_schema)); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(part_info.init(table_id, part_object_id))) { + LOG_WARN("init part info fail", KR(ret), K(table_id), K(part_object_id)); + } + } + return ret; +} + +} +} diff --git a/src/rootserver/balance/ob_ls_all_part_builder.h b/src/rootserver/balance/ob_ls_all_part_builder.h new file mode 100644 index 000000000..1eb326cac --- /dev/null +++ b/src/rootserver/balance/ob_ls_all_part_builder.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_LS_ALL_PART_BUILDER_H +#define OCEANBASE_ROOTSERVER_OB_LS_ALL_PART_BUILDER_H + +#include "share/transfer/ob_transfer_info.h" // ObTransferPartList, ObTransferPartInfo + +namespace oceanbase +{ +namespace common +{ +class ObISQLClient; +} // ns common + +namespace share +{ +class ObLSID; +class ObTabletToLSInfo; + +namespace schema +{ +class ObMultiVersionSchemaService; +class ObSchemaGetterGuard; +} // ns schema +} // ns share + +namespace rootserver +{ + +class ObLSAllPartBuilder +{ +public: + // build current all part list on specific LS + // + // @return OB_NEED_RETRY schema not latest or schema changed during handling + static int build( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + share::schema::ObMultiVersionSchemaService &schema_service, + common::ObISQLClient &sql_proxy, + share::ObTransferPartList &part_list); + +private: + static int get_latest_schema_guard_( + const uint64_t tenant_id, + share::schema::ObMultiVersionSchemaService &schema_service, + common::ObISQLClient &sql_proxy, + share::schema::ObSchemaGetterGuard &schema_guard); + static int build_part_info_( + const uint64_t tenant_id, + share::ObTabletToLSInfo &tablet, + share::schema::ObSchemaGetterGuard &schema_guard, + share::ObTransferPartInfo &part_info, + bool &need_skip); +}; + +} +} +#endif /* !OCEANBASE_ROOTSERVER_OB_LS_ALL_PART_BUILDER_H */ diff --git a/src/rootserver/balance/ob_ls_balance_group_info.cpp b/src/rootserver/balance/ob_ls_balance_group_info.cpp new file mode 100644 index 000000000..d7e5e9a4d --- /dev/null +++ b/src/rootserver/balance/ob_ls_balance_group_info.cpp @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2021 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. + */ +#define USING_LOG_PREFIX BALANCE + +#include "lib/ob_define.h" // OB_FLOAT_EPSINON + +#include "ob_ls_balance_group_info.h" + +namespace oceanbase +{ +using namespace share; +using namespace common; +namespace rootserver +{ + +int ObLSBalanceGroupInfo::init(const ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret), K(inited_), K(ls_id), KPC(this)); + } else if (OB_FAIL(bg_map_.create(MAP_BUCKET_NUM, "LSBGMap"))) { + LOG_WARN("create map for balance group fail", KR(ret), LITERAL_K(MAP_BUCKET_NUM)); + } else if (OB_FAIL(orig_part_group_cnt_map_.create(MAP_BUCKET_NUM, "LSPGCntMap"))) { + LOG_WARN("create map for balance group original partition group cnt fail", KR(ret), LITERAL_K(MAP_BUCKET_NUM)); + } else { + ls_id_ = ls_id; + inited_ = true; + } + return ret; +} + +void ObLSBalanceGroupInfo::destroy() +{ + for (auto iter = bg_map_.begin(); iter != bg_map_.end(); iter++) { + ObBalanceGroupInfo *bg = iter->second; + if (OB_NOT_NULL(bg)) { + bg->~ObBalanceGroupInfo(); + alloc_.free(bg); + bg = NULL; + } + } + + bg_map_.destroy(); + orig_part_group_cnt_map_.destroy(); + ls_id_.reset(); + inited_ = false; +} + +int ObLSBalanceGroupInfo::append_part_into_balance_group(const ObBalanceGroupID &bg_id, + share::ObTransferPartInfo &part, + const int64_t data_size, + const bool need_create_new_part_group) +{ + int ret = OB_SUCCESS; + ObBalanceGroupInfo *bg = NULL; + int64_t part_group_cnt = 0; + + if (OB_UNLIKELY(! inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret), K(inited_)); + } else if (OB_UNLIKELY(! bg_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(bg_id), K(part), K(data_size), + K(need_create_new_part_group)); + } else if (OB_FAIL(bg_map_.get_refactored(bg_id, bg))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(create_new_balance_group_(bg_id, bg))) { + LOG_WARN("create new balance group fail", KR(ret), K(bg_id)); + } + } else { + LOG_WARN("get from balance group map fail", KR(ret), K(bg_id)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(bg)) { + ret = OB_INVALID_DATA; + LOG_WARN("balance group is invalid", KR(ret), KPC(bg), K(bg_id)); + } else if (OB_FAIL(bg->append_part(part, data_size, need_create_new_part_group))) { + LOG_WARN("append part info balance group fail", KR(ret), K(part), K(data_size), + K(need_create_new_part_group)); + } else if (FALSE_IT(part_group_cnt = bg->get_part_group_count())) { + } else if (OB_FAIL(orig_part_group_cnt_map_.set_refactored(bg_id, part_group_cnt, 1/*overwrite*/))) { + LOG_WARN("overwrite partition group count map fail", KR(ret), K(bg_id), K(part_group_cnt)); + } + + return ret; +} + +int ObLSBalanceGroupInfo::create_new_balance_group_(const ObBalanceGroupID &bg_id, + ObBalanceGroupInfo *&bg) +{ + int ret = OB_SUCCESS; + int64_t bg_size = sizeof(ObBalanceGroupInfo); + bg = NULL; + + void *buf = alloc_.alloc(bg_size); + if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory for ObBalanceGroupInfo fail", KR(ret), K(bg_size), K(buf)); + } else if (OB_ISNULL(bg = new(buf) ObBalanceGroupInfo(bg_id, alloc_))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("construct ObBalanceGroupInfo fail", KR(ret), K(bg_size), K(buf), K(bg_id)); + } else if (OB_FAIL(bg_map_.set_refactored(bg_id, bg))) { + LOG_WARN("set into balance group map fail", KR(ret), K(bg_id), KPC(bg)); + } else if (OB_FAIL(orig_part_group_cnt_map_.set_refactored(bg_id, 0))) { + LOG_WARN("set into original partition group count map fail", KR(ret), K(bg_id)); + } + return ret; +} + +int ObLSBalanceGroupInfo::transfer_out_by_factor(const float factor, share::ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(factor <= OB_FLOAT_EPSINON)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("factor is invalid", KR(ret), K(factor)); + } else { + for (auto iter = bg_map_.begin(); OB_SUCC(ret) && iter != bg_map_.end(); ++iter) { + const ObBalanceGroupID &bg_id = iter->first; + ObBalanceGroupInfo *bg_info = iter->second; + + // original count before transfer-out partitions + const int64_t *total_count_ptr = orig_part_group_cnt_map_.get(bg_id); + + if (OB_ISNULL(bg_info) || OB_ISNULL(total_count_ptr) || OB_UNLIKELY(0 == *total_count_ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("original part group count or balance group info is invalid, unexpected", KR(ret), + K(total_count_ptr), K(bg_id), KPC(bg_info)); + } else if (OB_UNLIKELY(bg_info->get_part_group_count() <= 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part group can not be empty, unexpected", KR(ret), K(bg_id), KPC(bg_info)); + } else { + // Remove the appropriate proportion of partitions from the balance group + // + // expected remove count should be computed by factor of total count. + // It should be ceil() + const int64_t total_count = *total_count_ptr; + const int64_t expected_remove_count = ceil(factor * total_count); + const int64_t avail_count = bg_info->get_part_group_count(); + + // left count after remove should be greater than remove count + const int64_t left_count_lower_bound = expected_remove_count; + const int64_t can_remove_count_upper_bound = avail_count - left_count_lower_bound; + + const int64_t remove_count = std::min(can_remove_count_upper_bound, expected_remove_count); + + int64_t removed_part_count = 0; + + if (remove_count >= avail_count) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("remove count should be greater than avail count", K(avail_count), K(remove_count)); + } + // transfer out part only when remove count > 0 + else if (remove_count > 0 && OB_FAIL(bg_info->pop_back(remove_count, part_list, removed_part_count))) { + LOG_WARN("pop back from balance group fail", KR(ret), K(remove_count), K(part_list), + KPC(bg_info)); + } + + FLOG_INFO("transfer out partition groups from LS one balance group by factor", KR(ret), + K(factor), K_(ls_id), K(bg_id), + "removed_part_group_count", remove_count, + K(removed_part_count), + K(total_count), K(avail_count), K(expected_remove_count)); + } + } + } + return ret; +} + +} +} diff --git a/src/rootserver/balance/ob_ls_balance_group_info.h b/src/rootserver/balance/ob_ls_balance_group_info.h new file mode 100644 index 000000000..70b9fc8c3 --- /dev/null +++ b/src/rootserver/balance/ob_ls_balance_group_info.h @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_LS_BALANCE_GROUP_INFO_H +#define OCEANBASE_ROOTSERVER_OB_LS_BALANCE_GROUP_INFO_H + +#include "share/transfer/ob_transfer_info.h" //ObTransferPartList, ObTransferPartInfo +#include "share/ob_ls_id.h" //ObLSID +#include "lib/hash/ob_hashmap.h" //ObHashMap +#include "lib/allocator/page_arena.h" //ObArenaAllocator +#include "ob_balance_group_define.h" //ObBalanceGroupID +#include "ob_balance_group_info.h" //ObBalanceGroupInfo + +namespace oceanbase +{ +namespace rootserver +{ + +// LS Balance Statistic Info +class ObLSBalanceGroupInfo final +{ +public: + ObLSBalanceGroupInfo() : inited_(false), ls_id_(), alloc_(), bg_map_(), orig_part_group_cnt_map_() {} + ~ObLSBalanceGroupInfo() { destroy(); } + + int init(const share::ObLSID &ls_id); + void destroy(); + + // append partition at the newest partition group in target balance group. + // create new partition group in balance group if needed. + // + // NOTE: if balance group not exist, it will create a new balance group automatically + // + // @param [in] bg_id target balance group id + // @param [in] part target partition info which will be added + // @param [in] data_size partition data size + // @param [in] need_create_new_part_group whether to create new partition group in balance group + // + // @return OB_SUCCESS success + // @return OB_ENTRY_EXIST no partition group found + // @return other fail + int append_part_into_balance_group(const ObBalanceGroupID &bg_id, + share::ObTransferPartInfo &part, + const int64_t data_size, + const bool need_create_new_part_group); + + //////////////////////////////////////////////// + // Transfer out partition groups by specified factor + // + // NOTE: This function can be called only if all partitions are added. + int transfer_out_by_factor(const float factor, share::ObTransferPartList &part_list); + + TO_STRING_KV(K_(inited), K_(ls_id), "balance_group_count", bg_map_.size()); + +private: + int create_new_balance_group_(const ObBalanceGroupID &bg_id, + ObBalanceGroupInfo *&bg); + +private: + static const int64_t MAP_BUCKET_NUM = 4096; + + bool inited_; + share::ObLSID ls_id_; + common::ObArenaAllocator alloc_; + // map for all balance groups on this LS + common::hash::ObHashMap bg_map_; + // map for all balance groups' original partition group count + // This original count will be maintained during adding partitions into balance group. + // When all partitions are added, the original count will not change anymore. + common::hash::ObHashMap orig_part_group_cnt_map_; +}; + +} +} +#endif /* !OCEANBASE_ROOTSERVER_OB_LS_BALANCE_GROUP_INFO_H */ diff --git a/src/rootserver/balance/ob_tenant_ls_balance_group_info.cpp b/src/rootserver/balance/ob_tenant_ls_balance_group_info.cpp new file mode 100644 index 000000000..2c683543e --- /dev/null +++ b/src/rootserver/balance/ob_tenant_ls_balance_group_info.cpp @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2021 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. + */ +#define USING_LOG_PREFIX BALANCE + +#include "share/transfer/ob_transfer_info.h" // ObTransferPartInfo + +#include "ob_tenant_ls_balance_group_info.h" + +namespace oceanbase +{ +using namespace share; +using namespace common; +namespace rootserver +{ + +int ObTenantLSBalanceGroupInfo::init(const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret), K(inited_)); + } else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ls_bg_map_.create(MAP_BUCKET_NUM, "TntLSBGMap"))) { + LOG_WARN("create map for tenant balance group info fail", KR(ret), LITERAL_K(MAP_BUCKET_NUM)); + } else { + tenant_id_ = tenant_id; + inited_ = true; + } + return ret; +} + +void ObTenantLSBalanceGroupInfo::destroy() +{ + for (auto iter = ls_bg_map_.begin(); iter != ls_bg_map_.end(); iter++) { + ObLSBalanceGroupInfo *ls_bg_info = iter->second; + if (OB_NOT_NULL(ls_bg_info)) { + ls_bg_info->~ObLSBalanceGroupInfo(); + alloc_.free(ls_bg_info); + ls_bg_info = NULL; + } + } + + inited_ = false; + ls_bg_map_.destroy(); + tenant_id_ = OB_INVALID_TENANT_ID; +} + +int ObTenantLSBalanceGroupInfo::build(const char *mod, + common::ObMySQLProxy &sql_proxy, + share::schema::ObMultiVersionSchemaService &schema_service) +{ + int ret = OB_SUCCESS; + ObAllBalanceGroupBuilder bg_builder; + + if (OB_UNLIKELY(! inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantLSBalanceGroupInfo not init", KR(ret), KR(inited_)); + } else if (OB_FAIL(bg_builder.init(tenant_id_, mod, *this, sql_proxy, schema_service))) { + LOG_WARN("balance group builder init fail", KR(ret), K(tenant_id_), K(mod)); + } else if (OB_FAIL(bg_builder.prepare())) { + LOG_WARN("prepare for balance group builder fail", KR(ret)); + } else if (OB_FAIL(bg_builder.build())) { + LOG_WARN("build balance group fail", KR(ret)); + } else { + // succ + } + return ret; +} + +int ObTenantLSBalanceGroupInfo::on_new_partition( + const ObBalanceGroup &bg, + const common::ObObjectID table_id, + const common::ObObjectID part_object_id, + const common::ObTabletID tablet_id, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const int64_t tablet_size, + const bool in_new_partition_group) +{ + int ret = OB_SUCCESS; + ObLSBalanceGroupInfo *ls_bg_info = NULL; + ObTransferPartInfo part_info(table_id, part_object_id); + //This partition_group is iterated for the first time and needs to be newly created; + bool create_new_partition_group = in_new_partition_group; + + if (OB_UNLIKELY(! inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantLSBalanceGroupInfo not inited", KR(ret), K(inited_)); + } else if (OB_FAIL(ls_bg_map_.get_refactored(src_ls_id, ls_bg_info))) { + if (OB_HASH_NOT_EXIST != ret) { + LOG_WARN("get ls balance group info from map fail", KR(ret), K(src_ls_id)); + } else if (OB_FAIL(create_new_ls_bg_info_(src_ls_id, ls_bg_info))) { + LOG_WARN("create new ls balance group info fail", KR(ret), K(src_ls_id)); + } else if (OB_FAIL(ls_bg_map_.set_refactored(src_ls_id, ls_bg_info))) { + LOG_WARN("set new ls balance group info fail", KR(ret), K(src_ls_id), K(ls_bg_info)); + } else { + //It is not the first time that the partition in this partition_group has been iterated, + //but this partition is not on the same LS as the previous partition, and needs to be newly created. + create_new_partition_group = true; + } + } + + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(ls_bg_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid ls balance group info", KR(ret), K(ls_bg_info), K(src_ls_id)); + } else if (OB_FAIL(ls_bg_info->append_part_into_balance_group(bg.id(), part_info, tablet_size, + create_new_partition_group))) { + LOG_WARN("append part into balance group for LS balance group info fail", KR(ret), K(bg), + K(part_info), K(tablet_size), K(in_new_partition_group), K(create_new_partition_group)); + } + return ret; +} + +int ObTenantLSBalanceGroupInfo::create_new_ls_bg_info_(const ObLSID ls_id, + ObLSBalanceGroupInfo *&ls_bg_info) +{ + int ret = OB_SUCCESS; + void *buf = alloc_.alloc(sizeof(ObLSBalanceGroupInfo)); + if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory for ObLSBalanceGroupInfo fail", KR(ret), K(buf)); + } else if (OB_ISNULL(ls_bg_info = new(buf) ObLSBalanceGroupInfo())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("construct ObLSBalanceGroupInfo fail", KR(ret)); + } else if (OB_FAIL(ls_bg_info->init(ls_id))) { + LOG_WARN("init ls balance group info fail", KR(ret), K(ls_id), KPC(ls_bg_info)); + } + return ret; +} + +} +} diff --git a/src/rootserver/balance/ob_tenant_ls_balance_group_info.h b/src/rootserver/balance/ob_tenant_ls_balance_group_info.h new file mode 100644 index 000000000..5dd5b00ed --- /dev/null +++ b/src/rootserver/balance/ob_tenant_ls_balance_group_info.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_TENANT_LS_BALANCE_GROUP_INFO_H +#define OCEANBASE_ROOTSERVER_OB_TENANT_LS_BALANCE_GROUP_INFO_H + +#include "share/ob_ls_id.h" //ObLSID +#include "lib/hash/ob_hashmap.h" //ObHashMap +#include "lib/ob_define.h" // OB_INVALID_TENANT_ID +#include "lib/allocator/page_arena.h" // ObArenaAllocator + +#include "ob_all_balance_group_builder.h" // ObAllBalanceGroupBuilder +#include "ob_ls_balance_group_info.h" // ObLSBalanceGroupInfo + +namespace oceanbase +{ +namespace rootserver +{ + +// Tenant All LS Balance Group Info +// +// Build current balance group info on every LS. +// +// NOTE: if partitions are not balanced, partitions of same partition group may locate on different LS +class ObTenantLSBalanceGroupInfo final : public ObAllBalanceGroupBuilder::NewPartitionCallback +{ +public: + ObTenantLSBalanceGroupInfo() : inited_(false), tenant_id_(OB_INVALID_TENANT_ID), ls_bg_map_() {} + ~ObTenantLSBalanceGroupInfo() { destroy(); } + + int init(const uint64_t tenant_id); + void destroy(); + + // build All LS Balance Group Info + int build(const char *mod, + common::ObMySQLProxy &sql_proxy, + share::schema::ObMultiVersionSchemaService &schema_service); + + int get(const share::ObLSID &ls_id, ObLSBalanceGroupInfo *&ls_bg_info) const + { + return ls_bg_map_.get_refactored(ls_id, ls_bg_info); + } + +public: + // for ObAllBalanceGroupBuilder + // Handle new partition when building balance group + virtual int on_new_partition( + const ObBalanceGroup &bg, + const common::ObObjectID table_id, + const common::ObObjectID part_object_id, + const common::ObTabletID tablet_id, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const int64_t tablet_size, + const bool in_new_partition_group); + + TO_STRING_KV(K_(inited), K_(tenant_id), "valid_ls_count", ls_bg_map_.size()); + +private: + int create_new_ls_bg_info_(const share::ObLSID ls_id, + ObLSBalanceGroupInfo *&ls_bg_info); + +private: + static const int64_t MAP_BUCKET_NUM = 100; + + bool inited_; + uint64_t tenant_id_; + common::ObArenaAllocator alloc_; + + // map for all balance groups on tenant every LS + // If LS is empty, it does not exist in this map + common::hash::ObHashMap ls_bg_map_; +}; + +} +} +#endif /* !OCEANBASE_ROOTSERVER_OB_TENANT_LS_BALANCE_GROUP_INFO_H */ diff --git a/src/rootserver/ddl_task/ob_column_redefinition_task.cpp b/src/rootserver/ddl_task/ob_column_redefinition_task.cpp index d50224e52..4b53e8b43 100644 --- a/src/rootserver/ddl_task/ob_column_redefinition_task.cpp +++ b/src/rootserver/ddl_task/ob_column_redefinition_task.cpp @@ -605,6 +605,7 @@ int ObColumnRedefinitionTask::take_effect(const ObDDLTaskStatus next_task_status alter_table_arg_.hidden_table_id_ = target_object_id_; // offline ddl is allowed on table with trigger(enable/disable). alter_table_arg_.need_rebuild_trigger_ = true; + alter_table_arg_.task_id_ = task_id_; alter_table_arg_.alter_table_schema_.set_tenant_id(tenant_id_); ObRootService *root_service = GCTX.root_service_; ObSchemaGetterGuard schema_guard; @@ -677,12 +678,12 @@ int ObColumnRedefinitionTask::process() } break; case ObDDLTaskStatus::WAIT_TRANS_END: - if (OB_FAIL(wait_trans_end(wait_trans_ctx_, ObDDLTaskStatus::LOCK_TABLE))) { + if (OB_FAIL(wait_trans_end(wait_trans_ctx_, ObDDLTaskStatus::OBTAIN_SNAPSHOT))) { LOG_WARN("fail to wait trans end", K(ret)); } break; - case ObDDLTaskStatus::LOCK_TABLE: - if (OB_FAIL(lock_table(ObDDLTaskStatus::REDEFINITION))) { + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: + if (OB_FAIL(obtain_snapshot(ObDDLTaskStatus::REDEFINITION))) { LOG_WARN("fail to lock table", K(ret)); } break; @@ -757,11 +758,11 @@ int ObColumnRedefinitionTask::collect_longops_stat(ObLongopsValue &value) } break; } - case ObDDLTaskStatus::LOCK_TABLE: { + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: { if (OB_FAIL(databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, - "STATUS: ACQUIRE TABLE LOCK"))) { + "STATUS: OBTAIN SNAPSHOT"))) { LOG_WARN("failed to print", K(ret)); } break; @@ -860,7 +861,7 @@ void ObColumnRedefinitionTask::flt_set_status_span_tag() const FLT_SET_TAG(ddl_data_table_id, object_id_, ddl_ret_code, ret_code_); break; } - case ObDDLTaskStatus::LOCK_TABLE: { + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: { FLT_SET_TAG(ddl_ret_code, ret_code_); break; } diff --git a/src/rootserver/ddl_task/ob_constraint_task.cpp b/src/rootserver/ddl_task/ob_constraint_task.cpp old mode 100644 new mode 100755 index f2e512b94..7665a815d --- a/src/rootserver/ddl_task/ob_constraint_task.cpp +++ b/src/rootserver/ddl_task/ob_constraint_task.cpp @@ -16,6 +16,7 @@ #include "share/schema/ob_schema_struct.h" #include "share/ob_ddl_error_message_table_operator.h" #include "share/ob_ddl_common.h" +#include "storage/ddl/ob_ddl_lock.h" #include "rootserver/ob_root_service.h" #include "rootserver/ob_snapshot_info_manager.h" #include "share/scn.h" @@ -55,7 +56,7 @@ int ObCheckConstraintValidationTask::process() const ObDatabaseSchema *database_schema = nullptr; int tmp_ret = OB_SUCCESS; ObTabletID unused_tablet_id; - ObDDLTaskKey task_key(target_object_id_, schema_version_); + ObDDLTaskKey task_key(tenant_id_, target_object_id_, schema_version_); if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(tenant_id_, schema_guard))) { LOG_WARN("get tenant schema guard failed", K(ret), K(tenant_id_)); } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, data_table_id_, table_schema))) { @@ -189,7 +190,7 @@ int ObForeignKeyConstraintValidationTask::process() LOG_WARN("error sys, root service must not be nullptr", K(ret)); } else { ObTabletID unused_tablet_id; - ObDDLTaskKey task_key(foregin_key_id_, schema_version_); + ObDDLTaskKey task_key(tenant_id_, foregin_key_id_, schema_version_); ObDDLTaskInfo info; int tmp_ret = OB_SUCCESS; if (OB_FAIL(check_fk_by_send_sql())) { @@ -233,7 +234,7 @@ int ObForeignKeyConstraintValidationTask::check_fk_by_send_sql() const // ob drop database to recyclebin won't drop its tables to recyclebin, but will drop fk of its tables directly. ret = OB_TABLE_NOT_EXIST; LOG_WARN("database schema not exist", K(ret)); - } else if (OB_FAIL(get_foreign_key_info(data_table_schema, fk_info))) { + } else if (OB_FAIL(get_foreign_key_info(data_table_schema, foregin_key_id_, fk_info))) { LOG_WARN("get foreign key info failed", K(ret)); } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, fk_info.parent_table_id_, parent_table_schema))) { LOG_WARN("get table schema failed", K(ret), K(tenant_id_), K(fk_info.parent_table_id_)); @@ -263,7 +264,7 @@ int ObForeignKeyConstraintValidationTask::check_fk_by_send_sql() const return ret; } -int ObForeignKeyConstraintValidationTask::get_foreign_key_info(const ObTableSchema *table_schema, ObForeignKeyInfo &fk_info) const +int ObForeignKeyConstraintValidationTask::get_foreign_key_info(const ObTableSchema *table_schema, const int64_t foreign_key_id, ObForeignKeyInfo &fk_info) { int ret = OB_SUCCESS; if (OB_ISNULL(table_schema)) { @@ -273,7 +274,7 @@ int ObForeignKeyConstraintValidationTask::get_foreign_key_info(const ObTableSche const ObIArray &fk_infos = table_schema->get_foreign_key_infos(); bool found = false; for (int64_t i = 0; OB_SUCC(ret) && i < fk_infos.count() && !found; ++i) { - if (foregin_key_id_ == fk_infos.at(i).foreign_key_id_) { + if (foreign_key_id == fk_infos.at(i).foreign_key_id_) { fk_info = fk_infos.at(i); found = true; } @@ -818,6 +819,79 @@ int ObConstraintTask::check_replica_end(bool &is_end) return ret; } +int ObConstraintTask::release_ddl_locks() +{ + int ret = OB_SUCCESS; + int64_t total_tablet_cnt = 0; + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObTableSchema *table_schema = nullptr; + const ObTableSchema *another_table_schema = nullptr; + if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard( + tenant_id_, schema_guard))) { + LOG_WARN("get tenant schema guard failed", K(ret), K(tenant_id_)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, object_id_, table_schema))) { + LOG_WARN("get table schema failed", K(ret), K(tenant_id_), K(object_id_)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("table dropped", K(ret), K(object_id_)); + } else if (OB_FALSE_IT(total_tablet_cnt += table_schema->get_all_part_num())) { + } else if (ObDDLType::DDL_FOREIGN_KEY_CONSTRAINT == task_type_) { + const ObIArray &obj_infos = alter_table_arg_.based_schema_object_infos_; + for (int64_t i = 0; OB_SUCC(ret) && i < obj_infos.count(); i++) { + const ObBasedSchemaObjectInfo &obj_info = obj_infos.at(i); + if (TABLE_SCHEMA == obj_info.schema_type_ && object_id_ != obj_info.schema_id_) { + const uint64_t another_table_id = obj_info.schema_id_; + if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, another_table_id, another_table_schema))) { + LOG_WARN("get table schema failed", K(ret), K(tenant_id_), K(another_table_id)); + } else if (OB_ISNULL(another_table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("table dropped", K(ret), K(another_table_id)); + } else { + total_tablet_cnt += another_table_schema->get_all_part_num(); + break; + } + } + } + } + + ObTimeoutCtx timeout_ctx; + int64_t ddl_tx_timeout = 0; + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObDDLUtil::get_ddl_tx_timeout(total_tablet_cnt, ddl_tx_timeout))) { + LOG_WARN("get ddl tx timeout failed", K(ret)); + } else if (OB_FAIL(timeout_ctx.set_trx_timeout_us(ddl_tx_timeout))) { + LOG_WARN("set timeout ctx failed", K(ret)); + } else if (OB_FAIL(timeout_ctx.set_timeout(ddl_tx_timeout))) { + LOG_WARN("set timeout failed", K(ret)); + } + + ObMySQLTransaction trans; + if (OB_FAIL(ret)) { + } else if (OB_FAIL(trans.start(&root_service_->get_sql_proxy(), tenant_id_))) { + LOG_WARN("start transaction failed", K(ret)); + } else if (OB_FAIL(ObDDLLock::unlock_for_common_ddl(*table_schema, + transaction::tablelock::ObTableLockOwnerID(task_id_), + trans))) { + LOG_WARN("failed to unlock ddl", K(ret)); + } else if (nullptr != another_table_schema) { + if (OB_FAIL(ObDDLLock::unlock_for_common_ddl(*another_table_schema, + transaction::tablelock::ObTableLockOwnerID(task_id_), + trans))) { + LOG_WARN("failed to unlock ddl", K(ret)); + } + } + + bool commit = (OB_SUCCESS == ret); + int tmp_ret = trans.end(commit); + if (OB_SUCCESS != tmp_ret) { + ret = (OB_SUCCESS == ret) ? tmp_ret : ret; + } + if (OB_TABLE_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } + return ret; +} + int ObConstraintTask::cleanup_impl() { int ret = OB_SUCCESS; @@ -827,6 +901,8 @@ int ObConstraintTask::cleanup_impl() LOG_WARN("ObConstraintTask has not been inited", K(ret)); } else if (snapshot_version_ > 0 && OB_FAIL(release_snapshot(snapshot_version_))) { LOG_WARN("release snapshot failed", K(ret)); + } else if (OB_FAIL(release_ddl_locks())) { + LOG_WARN("failed to release ddl locks", K(ret)); } else if (OB_FAIL(report_error_code())) { LOG_WARN("report error code failed", K(ret)); } @@ -1258,7 +1334,6 @@ int ObConstraintTask::rollback_failed_schema() ret = OB_NOT_INIT; LOG_WARN("ObConstraintTask has not been inited", K(ret)); } else { - alter_table_arg_.based_schema_object_infos_.reset(); if (ObDDLType::DDL_CHECK_CONSTRAINT == task_type_) { if (OB_FAIL(rollback_failed_check_constraint())) { LOG_WARN("drop failed check constraint failed", K(ret)); @@ -1290,6 +1365,7 @@ int ObConstraintTask::rollback_failed_check_constraint() if (OB_FAIL(deep_copy_table_arg(allocator, alter_table_arg_, alter_table_arg))) { LOG_WARN("fail to deep copy table arg", K(ret)); } else { + alter_table_arg.based_schema_object_infos_.reset(); ObTableSchema::const_constraint_iterator iter = alter_table_arg.alter_table_schema_.constraint_begin(); if (obrpc::ObAlterTableArg::ADD_CONSTRAINT == alter_table_arg.alter_constraint_type_) { (*iter)->set_constraint_id(target_object_id_); @@ -1400,6 +1476,7 @@ int ObConstraintTask::rollback_failed_foregin_key() LOG_WARN("get ddl rpc timeout failed", K(ret)); } if (OB_SUCC(ret)) { + alter_table_arg.based_schema_object_infos_.reset(); alter_table_arg.is_inner_ = true; if (is_table_hidden_) { ObSArray unused_ids; @@ -1492,6 +1569,7 @@ int ObConstraintTask::rollback_failed_add_not_null_columns() alter_table_arg.ddl_task_type_ = share::DELETE_COLUMN_FROM_SCHEMA; alter_table_arg.index_arg_list_.reset(); alter_table_arg.foreign_key_arg_list_.reset(); + alter_table_arg.based_schema_object_infos_.reset(); alter_table_arg.alter_table_schema_.set_tenant_id(tenant_id_); AlterColumnSchema *col_schema = NULL; for (int64_t i = 0; i < alter_table_arg.alter_table_schema_.get_column_count() && OB_SUCC(ret); i++) { diff --git a/src/rootserver/ddl_task/ob_constraint_task.h b/src/rootserver/ddl_task/ob_constraint_task.h index 46a4db80b..c8b49315b 100644 --- a/src/rootserver/ddl_task/ob_constraint_task.h +++ b/src/rootserver/ddl_task/ob_constraint_task.h @@ -63,9 +63,9 @@ public: virtual int process() override; virtual int64_t get_deep_copy_size() const override { return sizeof(*this); } virtual ObAsyncTask *deep_copy(char *buf, const int64_t buf_size) const override; + static int get_foreign_key_info(const share::schema::ObTableSchema *table_schema, const int64_t foreign_key_id, share::schema::ObForeignKeyInfo &fk_info); private: int check_fk_by_send_sql() const; - int get_foreign_key_info(const share::schema::ObTableSchema *table_schema, share::schema::ObForeignKeyInfo &fk_info) const; int get_column_names(const share::schema::ObTableSchema &table_schema, const common::ObIArray &column_ids, common::ObIArray &column_name_str) const; @@ -142,6 +142,7 @@ private: common::ObIAllocator &allocator); int check_replica_end(bool &is_end); int check_health(); + int release_ddl_locks(); private: static const int64_t OB_CONSTRAINT_TASK_VERSION = 1; common::TCRWLock lock_; diff --git a/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp b/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp index cd705c299..0c8b03e74 100644 --- a/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp +++ b/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp @@ -86,7 +86,7 @@ int ObDDLRedefinitionSSTableBuildTask::process() ObSqlString sql_string; ObSchemaGetterGuard schema_guard; const ObSysVariableSchema *sys_variable_schema = nullptr; - ObDDLTaskKey task_key(dest_table_id_, schema_version_); + ObDDLTaskKey task_key(tenant_id_, dest_table_id_, schema_version_); ObDDLTaskInfo info; bool oracle_mode = false; bool need_exec_new_inner_sql = true; @@ -233,78 +233,6 @@ int ObDDLRedefinitionTask::prepare(const ObDDLTaskStatus next_task_status) return ret; } -int ObDDLRedefinitionTask::lock_table(const ObDDLTaskStatus next_task_status) -{ - int ret = OB_SUCCESS; - int64_t rpc_timeout = 0; - int64_t target_rpc_timeout = 0; - ObSchemaGetterGuard schema_guard; - const ObTableSchema *data_table_schema = nullptr; - const ObTableSchema *dest_table_schema = nullptr; - ObDDLTaskStatus new_status = ObDDLTaskStatus::LOCK_TABLE; - ObMultiVersionSchemaService &schema_service = ObMultiVersionSchemaService::get_instance(); - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("ObTableRedefinitionTask has not been inited", K(ret)); - } else if (OB_FAIL(schema_service.get_tenant_schema_guard(tenant_id_, schema_guard))) { - LOG_WARN("get tenant schema guard failed", K(ret)); - } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, object_id_, data_table_schema))) { - LOG_WARN("get table schema failed", K(ret), K(object_id_)); - } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, target_object_id_, dest_table_schema))) { - LOG_WARN("get table schema failed", K(ret), K(target_object_id_)); - } else if (OB_ISNULL(data_table_schema) || OB_ISNULL(dest_table_schema)) { - ret = OB_TABLE_NOT_EXIST; - LOG_WARN("table not exist", K(ret), K(object_id_), K(target_object_id_), KP(data_table_schema), KP(dest_table_schema)); - } else if (data_table_schema->is_tmp_table() != dest_table_schema->is_tmp_table()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table type is different", K(ret), K(data_table_schema->is_tmp_table()), K(dest_table_schema->is_tmp_table())); - } else if (data_table_schema->is_tmp_table()) { - // no need to lock table and unlock table. - } else if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(tenant_id_, object_id_, rpc_timeout))) { - LOG_WARN("get ddl rpc timeout fail", K(ret)); - } else if (OB_FAIL(ObTableLockRpcClient::get_instance().lock_table(object_id_, - EXCLUSIVE, schema_version_, rpc_timeout, tenant_id_))) { - if (!ObDDLUtil::is_table_lock_retry_ret_code(ret)) { - LOG_WARN("lock source table failed", K(ret), K(object_id_)); - } else { - if (REACH_TIME_INTERVAL(10 * 1000 * 1000)) { - ObTaskController::get().allow_next_syslog(); - LOG_INFO("cannot lock source table", K(ret), K(object_id_)); - } - } - } else if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(tenant_id_, target_object_id_, target_rpc_timeout))) { - LOG_WARN("get ddl rpc timeout fail", K(ret)); - } else if (OB_FAIL(ObTableLockRpcClient::get_instance().lock_table(target_object_id_, - EXCLUSIVE, schema_version_, target_rpc_timeout, tenant_id_))) { - if (!ObDDLUtil::is_table_lock_retry_ret_code(ret)) { - LOG_WARN("lock dest table failed", K(ret), K(target_object_id_)); - } else { - if (REACH_TIME_INTERVAL(10 * 1000 * 1000)) { - ObTaskController::get().allow_next_syslog(); - LOG_INFO("cannot lock dest table", K(ret), K(target_object_id_)); - } - } - } - DEBUG_SYNC(DDL_REDEFINITION_LOCK_TABLE); - if (OB_FAIL(ret)) { - ret = ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_SUCCESS : ret; - } else if (OB_FAIL(obtain_snapshot())) { - if (OB_SNAPSHOT_DISCARDED == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("fail to obtain snapshot version", K(ret)); - } - } else { - new_status = next_task_status; - } - if (new_status == next_task_status || OB_FAIL(ret)) { - if (OB_FAIL(switch_status(new_status, true, ret))) { - LOG_WARN("fail to switch task status", K(ret)); - } - } - return ret; -} - int ObDDLRedefinitionTask::check_table_empty(const ObDDLTaskStatus next_task_status) { int ret = OB_SUCCESS; @@ -453,10 +381,11 @@ int ObDDLRedefinitionTask::release_snapshot(const int64_t snapshot_version) } // to hold snapshot, containing data in old table with new schema version. -int ObDDLRedefinitionTask::obtain_snapshot() +int ObDDLRedefinitionTask::obtain_snapshot(const ObDDLTaskStatus next_task_status) { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; + ObDDLTaskStatus new_status = ObDDLTaskStatus::OBTAIN_SNAPSHOT; ObRootService *root_service = GCTX.root_service_; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -504,6 +433,21 @@ int ObDDLRedefinitionTask::obtain_snapshot() snapshot_held_ = true; } } + + if (OB_FAIL(ret)) { + if (OB_SNAPSHOT_DISCARDED == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to obtain snapshot version", K(ret)); + } + } else { + new_status = next_task_status; + } + if (new_status == next_task_status || OB_FAIL(ret)) { + if (OB_FAIL(switch_status(new_status, true, ret))) { + LOG_WARN("fail to switch task status", K(ret)); + } + } return ret; } @@ -1043,50 +987,6 @@ int ObDDLRedefinitionTask::sync_auto_increment_position() return ret; } -int ObDDLRedefinitionTask::unlock_table() -{ - int ret = OB_SUCCESS; - ObSchemaGetterGuard schema_guard; - const ObTableSchema *data_table_schema = nullptr; - const ObTableSchema *dest_table_schema = nullptr; - ObMultiVersionSchemaService &schema_service = ObMultiVersionSchemaService::get_instance(); - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("ObDDLRedefinitionTask has not been inited", K(ret)); - } else if (OB_FAIL(schema_service.get_tenant_schema_guard(tenant_id_, schema_guard))) { - LOG_WARN("get tenant schema failed", K(ret)); - } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, object_id_, data_table_schema))) { - LOG_WARN("get table schema failed", K(ret)); - } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, target_object_id_, dest_table_schema))) { - LOG_WARN("get table schema failed", K(ret)); - } - - // In scenario like succeed to cleanup garbage but RPC timeout occurs, executing the function again - // will find data/dest table not exist. - if (OB_FAIL(ret)) { - } else if (nullptr == data_table_schema || data_table_schema->is_tmp_table()) { - } else if (OB_FAIL(ObTableLockRpcClient::get_instance().unlock_table(object_id_, - EXCLUSIVE, schema_version_, 0, tenant_id_))) { - if (OB_OBJ_LOCK_NOT_EXIST == ret || OB_TABLE_NOT_EXIST == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("unlock source table failed", K(ret), K(object_id_)); - } - } - - if (OB_FAIL(ret)) { - } else if (nullptr == dest_table_schema || dest_table_schema->is_tmp_table()) { - } else if (OB_FAIL(ObTableLockRpcClient::get_instance().unlock_table(target_object_id_, - EXCLUSIVE, schema_version_, 0, tenant_id_))) { - if (OB_OBJ_LOCK_NOT_EXIST == ret || OB_TABLE_NOT_EXIST == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("unlock dest table failed", K(ret), K(target_object_id_)); - } - } - return ret; -} - int ObDDLRedefinitionTask::modify_autoinc(const ObDDLTaskStatus next_task_status) { int ret = OB_SUCCESS; @@ -1239,6 +1139,7 @@ int ObDDLRedefinitionTask::finish() alter_table_arg_.ddl_task_type_ = share::CLEANUP_GARBAGE_TASK; alter_table_arg_.table_id_ = object_id_; alter_table_arg_.hidden_table_id_ = target_object_id_; + alter_table_arg_.task_id_ = task_id_; alter_table_arg_.alter_table_schema_.set_tenant_id(tenant_id_); ObRootService *root_service = GCTX.root_service_; if (OB_UNLIKELY(!is_inited_)) { @@ -1247,8 +1148,6 @@ int ObDDLRedefinitionTask::finish() } else if (OB_ISNULL(root_service)) { ret = OB_ERR_SYS; LOG_WARN("error sys, root service must not be nullptr", K(ret)); - } else if (OB_FAIL(unlock_table())) { - LOG_WARN("unlock table failed", K(ret)); } else if (snapshot_version_ > 0 && OB_FAIL(release_snapshot(snapshot_version_))) { LOG_WARN("release snapshot failed", K(ret)); } else if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(tenant_id_, schema_guard))) { diff --git a/src/rootserver/ddl_task/ob_ddl_redefinition_task.h b/src/rootserver/ddl_task/ob_ddl_redefinition_task.h index dd8ec0958..96cdc023e 100644 --- a/src/rootserver/ddl_task/ob_ddl_redefinition_task.h +++ b/src/rootserver/ddl_task/ob_ddl_redefinition_task.h @@ -137,9 +137,8 @@ public: K(check_table_empty_job_ret_code_), K(check_table_empty_job_time_)); protected: int prepare(const share::ObDDLTaskStatus next_task_status); - int lock_table(const share::ObDDLTaskStatus next_task_status); int check_table_empty(const share::ObDDLTaskStatus next_task_status); - int obtain_snapshot(); + int obtain_snapshot(const share::ObDDLTaskStatus next_task_status); bool check_can_validate_column_checksum( const bool is_oracle_mode, const share::schema::ObColumnSchemaV2 &src_column_schema, @@ -149,7 +148,6 @@ protected: const share::schema::ObTableSchema &dest_table_schema, common::hash::ObHashMap &validate_checksum_column_ids); int check_data_dest_tables_columns_checksum(const int64_t execution_id); - int unlock_table(); int fail(); int success(); int hold_snapshot(const int64_t snapshot_version); diff --git a/src/rootserver/ddl_task/ob_ddl_scheduler.cpp b/src/rootserver/ddl_task/ob_ddl_scheduler.cpp old mode 100644 new mode 100755 index af8cbe533..7bb0d23f9 --- a/src/rootserver/ddl_task/ob_ddl_scheduler.cpp +++ b/src/rootserver/ddl_task/ob_ddl_scheduler.cpp @@ -106,8 +106,7 @@ int ObDDLTaskQueue::push_task(ObDDLTask *task) } } else { task_add_to_map = true; - if (OB_FAIL(ret)) { - } else if (OB_FAIL(task_id_map_.set_refactored(task->get_ddl_task_id(), task, is_overwrite))) { + if (OB_FAIL(task_id_map_.set_refactored(task->get_ddl_task_id(), task, is_overwrite))) { if (common::OB_HASH_EXIST == ret) { ret = common::OB_ENTRY_EXIST; } else { @@ -1321,7 +1320,7 @@ int ObDDLScheduler::create_build_index_task( } else if (OB_ISNULL(create_index_arg) || OB_ISNULL(data_table_schema) || OB_ISNULL(index_schema)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(create_index_arg), K(data_table_schema), K(index_schema)); - } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), task_id))) { + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), data_table_schema->get_tenant_id(), task_id))) { LOG_WARN("fetch new task id failed", K(ret)); } else if (OB_FAIL(index_task.init(data_table_schema->get_tenant_id(), task_id, @@ -1365,7 +1364,7 @@ int ObDDLScheduler::create_drop_index_task( } else if (index_schema->is_domain_index()) { ret = OB_NOT_SUPPORTED; LOG_WARN("drop domain index is not supported", K(ret)); - } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), task_id))) { + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), index_schema->get_tenant_id(), task_id))) { LOG_WARN("fetch new task id failed", K(ret)); } else { const uint64_t data_table_id = index_schema->get_data_table_id(); @@ -1410,7 +1409,7 @@ int ObDDLScheduler::create_constraint_task( || nullptr == arg || !arg->is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(table_schema), K(constraint_id), K(schema_version), K(arg)); - } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), task_id))) { + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), table_schema->get_tenant_id(), task_id))) { LOG_WARN("fetch new task id failed", K(ret)); } else if (OB_FAIL(constraint_task.init(task_id, table_schema, constraint_id, ddl_type, schema_version, *arg, consumer_group_id, parent_task_id))) { LOG_WARN("init constraint task failed", K(ret), K(table_schema), K(constraint_id)); @@ -1444,7 +1443,7 @@ int ObDDLScheduler::create_table_redefinition_task( } else if (OB_ISNULL(alter_table_arg) || OB_ISNULL(src_schema) || OB_ISNULL(dest_schema)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), KP(alter_table_arg), KP(src_schema), KP(dest_schema)); - } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), task_id))) { + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), src_schema->get_tenant_id(), task_id))) { LOG_WARN("fetch new task id failed", K(ret)); } else if (OB_FAIL(redefinition_task.init(src_schema->get_tenant_id(), task_id, @@ -1486,7 +1485,7 @@ int ObDDLScheduler::create_drop_primary_key_task( } else if (OB_ISNULL(alter_table_arg) || OB_ISNULL(src_schema) || OB_ISNULL(dest_schema)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), KP(alter_table_arg), KP(src_schema), KP(dest_schema)); - } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), task_id))) { + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), src_schema->get_tenant_id(), task_id))) { LOG_WARN("fetch new task id failed", K(ret)); } else if (OB_FAIL(drop_pk_task.init(src_schema->get_tenant_id(), task_id, @@ -1528,7 +1527,7 @@ int ObDDLScheduler::create_column_redefinition_task( } else if (OB_ISNULL(alter_table_arg) || OB_ISNULL(src_schema) || OB_ISNULL(dest_schema)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), KP(alter_table_arg), KP(src_schema), KP(dest_schema)); - } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), task_id))) { + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), src_schema->get_tenant_id(), task_id))) { LOG_WARN("fetch new task id failed", K(ret)); } else if (OB_FAIL(redefinition_task.init(src_schema->get_tenant_id(), task_id, @@ -1570,7 +1569,7 @@ int ObDDLScheduler::create_modify_autoinc_task( || schema_version <= 0 || nullptr == arg || !arg->is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(tenant_id), K(table_id), K(schema_version), K(arg)); - } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), task_id))) { + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), tenant_id, task_id))) { LOG_WARN("fetch new task id failed", K(ret)); } else if (OB_FAIL(modify_autoinc_task.init(tenant_id, task_id, table_id, schema_version, consumer_group_id, *arg))) { LOG_WARN("init global index task failed", K(ret), K(table_id), K(arg)); @@ -1607,7 +1606,7 @@ int ObDDLScheduler::create_ddl_retry_task( || schema_version <= 0) || OB_ISNULL(arg)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(tenant_id), K(object_id), K(schema_version), K(arg)); - } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), task_id))) { + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), tenant_id, task_id))) { LOG_WARN("fetch new task id failed", K(ret)); } else if (OB_FAIL(ddl_retry_task.init(tenant_id, task_id, object_id, schema_version, consumer_group_id, type, arg))) { LOG_WARN("init ddl retry task failed", K(ret), K(arg)); diff --git a/src/rootserver/ddl_task/ob_ddl_scheduler.h b/src/rootserver/ddl_task/ob_ddl_scheduler.h old mode 100644 new mode 100755 diff --git a/src/rootserver/ddl_task/ob_ddl_task.cpp b/src/rootserver/ddl_task/ob_ddl_task.cpp index d5d261bd8..f9e405c31 100644 --- a/src/rootserver/ddl_task/ob_ddl_task.cpp +++ b/src/rootserver/ddl_task/ob_ddl_task.cpp @@ -38,6 +38,7 @@ #include "rootserver/ob_ddl_service.h" #include "rootserver/ob_root_service.h" #include "rootserver/ob_snapshot_info_manager.h" +#include "storage/ob_common_id_utils.h" #include "storage/tx/ob_ts_mgr.h" #include "observer/ob_server_struct.h" @@ -55,30 +56,32 @@ using namespace sql; namespace rootserver { ObDDLTaskKey::ObDDLTaskKey() - : object_id_(OB_INVALID_ID), schema_version_(0) + : tenant_id_(OB_INVALID_TENANT_ID), object_id_(OB_INVALID_ID), schema_version_(0) { } -ObDDLTaskKey::ObDDLTaskKey(const int64_t object_id, const int64_t schema_version) - : object_id_(object_id), schema_version_(schema_version) +ObDDLTaskKey::ObDDLTaskKey(const uint64_t tenant_id, const int64_t object_id, const int64_t schema_version) + : tenant_id_(tenant_id), object_id_(object_id), schema_version_(schema_version) { } uint64_t ObDDLTaskKey::hash() const { - uint64_t hash_val = murmurhash(&object_id_, sizeof(object_id_), 0); + uint64_t hash_val = murmurhash(&tenant_id_, sizeof(tenant_id_), 0); + hash_val = murmurhash(&object_id_, sizeof(object_id_), hash_val); hash_val = murmurhash(&schema_version_, sizeof(schema_version_), hash_val); return hash_val; } bool ObDDLTaskKey::operator==(const ObDDLTaskKey &other) const { - return object_id_ == other.object_id_ && schema_version_ == other.schema_version_; + return tenant_id_ == other.tenant_id_ && object_id_ == other.object_id_ && schema_version_ == other.schema_version_; } int ObDDLTaskKey::assign(const ObDDLTaskKey &other) { int ret = OB_SUCCESS; + tenant_id_ = other.tenant_id_; object_id_ = other.object_id_; schema_version_ = other.schema_version_; return ret; @@ -408,7 +411,7 @@ trace::ObSpanCtx* ObDDLTracing::begin_status_span(const share::ObDDLTaskStatus s case ObDDLTaskStatus::PREPARE: span = FLT_BEGIN_SPAN(ddl_prepare); break; - case ObDDLTaskStatus::LOCK_TABLE: + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: span = FLT_BEGIN_SPAN(ddl_lock_table); break; case ObDDLTaskStatus::WAIT_TRANS_END: @@ -502,7 +505,7 @@ trace::ObSpanCtx* ObDDLTracing::restore_status_span() case ObDDLTaskStatus::PREPARE: span = FLT_RESTORE_DDL_SPAN(ddl_prepare, status_span_id_, status_start_ts_); break; - case ObDDLTaskStatus::LOCK_TABLE: + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: span = FLT_RESTORE_DDL_SPAN(ddl_lock_table, status_span_id_, status_start_ts_); break; case ObDDLTaskStatus::WAIT_TRANS_END: @@ -789,16 +792,23 @@ int ObDDLTask::deep_copy_table_arg(common::ObIAllocator &allocator, const ObDDLA return ret; } -int ObDDLTask::fetch_new_task_id(ObMySQLProxy &sql_proxy, int64_t &new_task_id) +int ObDDLTask::fetch_new_task_id(ObMySQLProxy &sql_proxy, const uint64_t tenant_id, int64_t &new_task_id) { int ret = OB_SUCCESS; - uint64_t tmp_task_id = OB_INVALID_ID; - ObMaxIdFetcher id_fetcher(sql_proxy); - if (OB_FAIL(id_fetcher.fetch_new_max_id(OB_SYS_TENANT_ID, - OB_MAX_USED_DDL_TASK_ID_TYPE, tmp_task_id, 1L/*ddl start id*/))) { - LOG_WARN("fetch_new_max_id failed", K(ret), "id_type", OB_MAX_USED_DDL_TASK_ID_TYPE); + ObCommonID tmp_task_id; + UNUSED(sql_proxy); + MTL_SWITCH(tenant_id) { + if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id, tmp_task_id))) { + LOG_WARN("failed to gen unique id", K(ret)); + } else { + new_task_id = tmp_task_id.id(); + } } else { - new_task_id = tmp_task_id; + if (OB_FAIL(ObCommonIDUtils::gen_unique_id_by_rpc(tenant_id, tmp_task_id))) { + LOG_WARN("failed to gen unique id", K(ret)); + } else { + new_task_id = tmp_task_id.id(); + } } return ret; } @@ -1344,7 +1354,7 @@ void ObDDLTask::calc_next_schedule_ts(const int ret_code, const int64_t total_ta int64_t ddl_rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); if (OB_TIMEOUT == ret_code) { const int64_t SEC = 1000000; - const int64_t max_delay = total_task_cnt * ddl_rpc_timeout * 10; + const int64_t max_delay = std::min(total_task_cnt * ddl_rpc_timeout * 10, 600 * 1000 * 1000L/*10 min*/); delay_schedule_time_ = std::min(delay_schedule_time_ * 6/5 + SEC/10, max_delay); const int64_t max_dt = delay_schedule_time_; const int64_t min_dt = max_dt / 2; @@ -2804,6 +2814,42 @@ int ObDDLTaskRecordOperator::check_has_conflict_ddl( return ret; } +int ObDDLTaskRecordOperator::check_has_index_task( + common::ObISQLClient &proxy, + const uint64_t tenant_id, + const uint64_t data_table_id, + const uint64_t index_table_id, + bool &has_index_task) +{ + int ret = OB_SUCCESS; + has_index_task = false; + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id + || OB_INVALID_ID == data_table_id + || OB_INVALID_ID == index_table_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(tenant_id), K(data_table_id)); + } else { + ObSqlString sql_string; + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + sqlclient::ObMySQLResult *result = NULL; + if (OB_FAIL(sql_string.assign_fmt("SELECT EXISTS(SELECT 1 FROM %s WHERE object_id = %lu AND target_object_id = %lu AND ddl_type IN (%d, %d)) as has", + OB_ALL_DDL_TASK_STATUS_TNAME, data_table_id, index_table_id, ObDDLType::DDL_CREATE_INDEX, ObDDLType::DDL_DROP_INDEX))) { + LOG_WARN("assign sql string failed", K(ret)); + } else if (OB_FAIL(proxy.read(res, tenant_id, sql_string.ptr()))) { + LOG_WARN("query ddl task record failed", K(ret), K(sql_string)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get sql result", K(ret), KP(result)); + } else if (OB_FAIL(result->next())) { + LOG_WARN("result next failed", K(ret), K(tenant_id), K(index_table_id)); + } else { + EXTRACT_BOOL_FIELD_MYSQL(*result, "has", has_index_task); + } + } + } + return ret; +} + int ObDDLTaskRecordOperator::get_task_record(const ObSqlString &sql_string, common::ObMySQLProxy &proxy, common::ObIAllocator &allocator, @@ -2901,6 +2947,7 @@ int ObDDLTaskRecordOperator::check_task_id_exist(common::ObMySQLProxy &proxy, co ObSqlString sql_string; SMART_VAR(ObMySQLProxy::MySQLResult, res) { sqlclient::ObMySQLResult *result = NULL; + // TODO: if (OB_FAIL(sql_string.assign_fmt("SELECT count(*) as have FROM %s WHERE task_id=%lu", OB_ALL_VIRTUAL_DDL_TASK_STATUS_TNAME, task_id))) { LOG_WARN("assign sql string failed", K(ret)); } else if (OB_FAIL(proxy.read(res, sql_string.ptr()))) { diff --git a/src/rootserver/ddl_task/ob_ddl_task.h b/src/rootserver/ddl_task/ob_ddl_task.h old mode 100644 new mode 100755 index 2175116a2..a9186dd81 --- a/src/rootserver/ddl_task/ob_ddl_task.h +++ b/src/rootserver/ddl_task/ob_ddl_task.h @@ -34,15 +34,16 @@ struct ObDDLTaskKey final { public: ObDDLTaskKey(); - ObDDLTaskKey(const int64_t object_id, const int64_t schema_version); + ObDDLTaskKey(const uint64_t tenant_id, const int64_t object_id, const int64_t schema_version); ~ObDDLTaskKey() = default; uint64_t hash() const; int hash(uint64_t &hash_val) const { hash_val = hash(); return OB_SUCCESS; } bool operator==(const ObDDLTaskKey &other) const; - bool is_valid() const { return OB_INVALID_ID != object_id_ && schema_version_ > 0; } + bool is_valid() const { return OB_INVALID_TENANT_ID != tenant_id_ && OB_INVALID_ID != object_id_ && schema_version_ > 0; } int assign(const ObDDLTaskKey &other); - TO_STRING_KV(K_(object_id), K_(schema_version)); + TO_STRING_KV(K_(tenant_id), K_(object_id), K_(schema_version)); public: + uint64_t tenant_id_; int64_t object_id_; int64_t schema_version_; }; @@ -249,6 +250,13 @@ public: const share::ObDDLType ddl_type, bool &has_conflict_ddl); + static int check_has_index_task( + common::ObISQLClient &proxy, + const uint64_t tenant_id, + const uint64_t data_table_id, + const uint64_t index_table_id, + bool &has_index_task); + static int insert_record( common::ObISQLClient &proxy, ObDDLTaskRecord &record); @@ -461,7 +469,7 @@ public: int64_t get_ret_code() const { return ret_code_; } int64_t get_task_id() const { return task_id_; } ObDDLTaskID get_ddl_task_id() const { return ObDDLTaskID(tenant_id_, task_id_); } - ObDDLTaskKey get_task_key() const { return ObDDLTaskKey(target_object_id_, schema_version_); } + ObDDLTaskKey get_task_key() const { return ObDDLTaskKey(tenant_id_, target_object_id_, schema_version_); } int64_t get_parent_task_id() const { return parent_task_id_; } int64_t get_task_version() const { return task_version_; } int64_t get_parallelism() const { return parallelism_; } @@ -473,7 +481,7 @@ public: void set_longops_stat(share::ObDDLLongopsStat *longops_stat) { longops_stat_ = longops_stat; } share::ObDDLLongopsStat *get_longops_stat() const { return longops_stat_; } int64_t get_data_format_version() const { return data_format_version_; } - static int fetch_new_task_id(ObMySQLProxy &sql_proxy, int64_t &new_task_id); + static int fetch_new_task_id(ObMySQLProxy &sql_proxy, const uint64_t tenant_id, int64_t &new_task_id); virtual int serialize_params_to_message(char *buf, const int64_t buf_size, int64_t &pos) const; virtual int deserlize_params_from_message(const uint64_t tenant_id, const char *buf, const int64_t buf_size, int64_t &pos); virtual int64_t get_serialize_param_size() const; diff --git a/src/rootserver/ddl_task/ob_drop_index_task.cpp b/src/rootserver/ddl_task/ob_drop_index_task.cpp index 07cdb4964..1b80ea313 100644 --- a/src/rootserver/ddl_task/ob_drop_index_task.cpp +++ b/src/rootserver/ddl_task/ob_drop_index_task.cpp @@ -229,6 +229,7 @@ int ObDropIndexTask::drop_index_impl() } else if (OB_FAIL(drop_index_sql.assign(drop_index_arg_.ddl_stmt_str_))) { LOG_WARN("assign user drop index sql failed", K(ret)); } else { + int64_t ddl_rpc_timeout = 0; obrpc::ObDropIndexArg drop_index_arg; obrpc::ObDropIndexRes drop_index_res; drop_index_arg.tenant_id_ = tenant_id_; @@ -241,8 +242,11 @@ int ObDropIndexTask::drop_index_impl() drop_index_arg.index_action_type_ = obrpc::ObIndexArg::DROP_INDEX; drop_index_arg.ddl_stmt_str_ = drop_index_sql.string(); drop_index_arg.is_add_to_scheduler_ = false; - if (OB_FAIL(root_service_->get_common_rpc_proxy().drop_index(drop_index_arg, drop_index_res))) { - LOG_WARN("drop index failed", K(ret)); + drop_index_arg.task_id_ = task_id_; + if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(index_schema->get_all_part_num() + data_table_schema->get_all_part_num(), ddl_rpc_timeout))) { + LOG_WARN("failed to get ddl rpc timeout", K(ret)); + } else if (OB_FAIL(root_service_->get_common_rpc_proxy().timeout(ddl_rpc_timeout).drop_index(drop_index_arg, drop_index_res))) { + LOG_WARN("drop index failed", K(ret), K(ddl_rpc_timeout)); } LOG_INFO("drop index", K(ret), K(drop_index_sql.ptr()), K(drop_index_arg)); } diff --git a/src/rootserver/ddl_task/ob_drop_primary_key_task.cpp b/src/rootserver/ddl_task/ob_drop_primary_key_task.cpp index d510b8e68..6af717a42 100644 --- a/src/rootserver/ddl_task/ob_drop_primary_key_task.cpp +++ b/src/rootserver/ddl_task/ob_drop_primary_key_task.cpp @@ -73,12 +73,12 @@ int ObDropPrimaryKeyTask::process() } break; case ObDDLTaskStatus::WAIT_TRANS_END: - if (OB_FAIL(wait_trans_end(wait_trans_ctx_, ObDDLTaskStatus::LOCK_TABLE))) { + if (OB_FAIL(wait_trans_end(wait_trans_ctx_, ObDDLTaskStatus::OBTAIN_SNAPSHOT))) { LOG_WARN("fail to wait trans end", K(ret)); } break; - case ObDDLTaskStatus::LOCK_TABLE: - if (OB_FAIL(lock_table(ObDDLTaskStatus::REDEFINITION))) { + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: + if (OB_FAIL(obtain_snapshot(ObDDLTaskStatus::REDEFINITION))) { LOG_WARN("fail to wait trans end", K(ret)); } break; @@ -134,7 +134,7 @@ void ObDropPrimaryKeyTask::flt_set_status_span_tag() const FLT_SET_TAG(ddl_ret_code, ret_code_); break; } - case ObDDLTaskStatus::LOCK_TABLE: { + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: { FLT_SET_TAG(ddl_ret_code, ret_code_); break; } diff --git a/src/rootserver/ddl_task/ob_index_build_task.cpp b/src/rootserver/ddl_task/ob_index_build_task.cpp old mode 100644 new mode 100755 index 2e303f159..2c9868f1d --- a/src/rootserver/ddl_task/ob_index_build_task.cpp +++ b/src/rootserver/ddl_task/ob_index_build_task.cpp @@ -16,6 +16,7 @@ #include "share/schema/ob_multi_version_schema_service.h" #include "share/ob_ddl_checksum.h" #include "share/ob_ddl_error_message_table_operator.h" +#include "storage/ddl/ob_ddl_lock.h" #include "share/ob_ddl_common.h" #include "rootserver/ob_root_service.h" #include "share/scn.h" @@ -141,7 +142,7 @@ int ObIndexSSTableBuildTask::process() } LOG_INFO("build index sstable finish", K(ret), K(*this)); - ObDDLTaskKey task_key(dest_table_id_, schema_version_); + ObDDLTaskKey task_key(tenant_id_, dest_table_id_, schema_version_); ObDDLTaskInfo info; int tmp_ret = root_service_->get_ddl_scheduler().on_sstable_complement_job_reply( unused_tablet_id, task_key, snapshot_version_, execution_id_, ret, info); @@ -1204,16 +1205,20 @@ int ObIndexBuildTask::update_index_status_in_schema(const ObTableSchema &index_s arg.status_ = new_status; arg.exec_tenant_id_ = tenant_id_; arg.in_offline_ddl_white_list_ = index_schema.get_table_state_flag() != TABLE_STATE_NORMAL; + arg.task_id_ = task_id_; int64_t ddl_rpc_timeout = 0; - int64_t table_id = index_schema.get_table_id(); + int64_t tmp_timeout = 0; DEBUG_SYNC(BEFORE_UPDATE_GLOBAL_INDEX_STATUS); - if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(tenant_id_, table_id, ddl_rpc_timeout))) { + if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(index_schema.get_all_part_num(), ddl_rpc_timeout))) { LOG_WARN("get ddl rpc timeout fail", K(ret)); + } else if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(tenant_id_, index_schema.get_data_table_id(), tmp_timeout))) { + LOG_WARN("get ddl rpc timeout fail", K(ret)); + } else if (OB_FALSE_IT(ddl_rpc_timeout += tmp_timeout)) { } else if (OB_FAIL(root_service_->get_common_rpc_proxy().to(GCTX.self_addr()).timeout(ddl_rpc_timeout).update_index_status(arg))) { LOG_WARN("update index status failed", K(ret), K(arg)); } else { - LOG_INFO("notify index status changed finish", K(new_status), K(index_table_id_)); + LOG_INFO("notify index status changed finish", K(new_status), K(index_table_id_), K(ddl_rpc_timeout)); } } return ret; @@ -1305,6 +1310,7 @@ int ObIndexBuildTask::clean_on_failed() } } if (OB_SUCC(ret)) { + int64_t ddl_rpc_timeout = 0; obrpc::ObDropIndexArg drop_index_arg; obrpc::ObDropIndexRes drop_index_res; drop_index_arg.tenant_id_ = tenant_id_; @@ -1320,7 +1326,10 @@ int ObIndexBuildTask::clean_on_failed() drop_index_arg.is_hidden_ = index_schema->is_user_hidden_table(); drop_index_arg.is_in_recyclebin_ = index_schema->is_in_recyclebin(); drop_index_arg.is_inner_ = true; - if (OB_FAIL(root_service_->get_common_rpc_proxy().drop_index(drop_index_arg, drop_index_res))) { + drop_index_arg.task_id_ = task_id_; + if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(index_schema->get_all_part_num() + data_table_schema->get_all_part_num(), ddl_rpc_timeout))) { + LOG_WARN("get ddl rpc timeout fail", K(ret)); + } else if (OB_FAIL(root_service_->get_common_rpc_proxy().timeout(ddl_rpc_timeout).drop_index(drop_index_arg, drop_index_res))) { LOG_WARN("drop index failed", K(ret)); } LOG_INFO("drop index when build failed", K(ret), K(drop_index_arg)); diff --git a/src/rootserver/ddl_task/ob_modify_autoinc_task.cpp b/src/rootserver/ddl_task/ob_modify_autoinc_task.cpp index 7881dd733..bdf46bddb 100644 --- a/src/rootserver/ddl_task/ob_modify_autoinc_task.cpp +++ b/src/rootserver/ddl_task/ob_modify_autoinc_task.cpp @@ -17,6 +17,7 @@ #include "share/ob_ddl_error_message_table_operator.h" #include "storage/tablelock/ob_table_lock_service.h" #include "storage/tablelock/ob_table_lock_rpc_client.h" +#include "storage/ddl/ob_ddl_lock.h" using namespace oceanbase::common; using namespace oceanbase::share; @@ -63,7 +64,7 @@ int ObUpdateAutoincSequenceTask::process() const ObDatabaseSchema *db_schema = nullptr; const ObColumnSchemaV2 *column_schema = nullptr; ObSchemaGetterGuard schema_guard; - ObDDLTaskKey task_key(dest_table_id_, schema_version_); + ObDDLTaskKey task_key(tenant_id_, dest_table_id_, schema_version_); if (OB_FAIL(schema_service.get_tenant_schema_guard(tenant_id_, schema_guard))) { LOG_WARN("get schema guard failed", K(ret), K(tenant_id_)); } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, dest_table_id_, table_schema))) { @@ -240,12 +241,6 @@ int ObModifyAutoincTask::process() } break; } - case ObDDLTaskStatus::LOCK_TABLE: { - if (OB_FAIL(lock_table())) { - LOG_WARN("lock table failed", K(ret), K(*this)); - } - break; - } case ObDDLTaskStatus::MODIFY_AUTOINC: { if (OB_FAIL(modify_autoinc())) { LOG_WARN("update schema failed", K(ret), K(*this)); @@ -275,45 +270,27 @@ int ObModifyAutoincTask::process() return ret; } -int ObModifyAutoincTask::lock_table() -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("ObModifyAutoincTask has not been inited", K(ret)); - } else if (OB_FAIL(ObTableLockRpcClient::get_instance().lock_table(object_id_, - EXCLUSIVE, schema_version_, 0, tenant_id_))) { - if (!ObDDLUtil::is_table_lock_retry_ret_code(ret)) { - LOG_WARN("lock source table failed", K(ret), K(object_id_)); - } else { - if (REACH_TIME_INTERVAL(10 * 1000 * 1000)) { - ObTaskController::get().allow_next_syslog(); - LOG_INFO("cannot lock source table", K(object_id_)); - } - } - } - DEBUG_SYNC(DDL_REDEFINITION_LOCK_TABLE); - if (ObDDLUtil::is_table_lock_retry_ret_code(ret)) { - ret = OB_SUCCESS; - } else if (OB_FAIL(switch_status(ObDDLTaskStatus::MODIFY_AUTOINC, true, ret))) { - LOG_WARN("fail to switch status", K(ret)); - } - return ret; -} - int ObModifyAutoincTask::unlock_table() { int ret = OB_SUCCESS; + ObRootService *root_service = GCTX.root_service_; + ObMySQLTransaction trans; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObModifyAutoincTask has not been inited", K(ret)); - } else if (OB_FAIL(ObTableLockRpcClient::get_instance().unlock_table(object_id_, - EXCLUSIVE, schema_version_, 0, tenant_id_))) { - if (OB_OBJ_LOCK_NOT_EXIST == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("unlock source table failed", K(ret), K(object_id_)); - } + } else if (OB_ISNULL(root_service)) { + ret = OB_ERR_SYS; + LOG_WARN("error sys, root service must not be nullptr", K(ret)); + } else if (OB_FAIL(trans.start(&root_service->get_sql_proxy(), tenant_id_))) { + LOG_WARN("start transaction failed", K(ret)); + } else if (OB_FAIL(ObDDLLock::unlock_for_offline_ddl(tenant_id_, object_id_, ObTableLockOwnerID(task_id_), trans))) { + LOG_WARN("failed to unlock table", K(ret)); + } + + bool commit = (OB_SUCCESS == ret); + int tmp_ret = trans.end(commit); + if (OB_SUCCESS != tmp_ret) { + ret = (OB_SUCCESS == ret) ? tmp_ret : ret; } return ret; } @@ -640,7 +617,7 @@ void ObModifyAutoincTask::flt_set_status_span_tag() const FLT_SET_TAG(ddl_data_table_id, object_id_, ddl_ret_code, ret_code_); break; } - case ObDDLTaskStatus::LOCK_TABLE: { + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: { FLT_SET_TAG(ddl_data_table_id, object_id_, ddl_ret_code, ret_code_); break; } diff --git a/src/rootserver/ddl_task/ob_modify_autoinc_task.h b/src/rootserver/ddl_task/ob_modify_autoinc_task.h index d8e975784..1ba5004c0 100644 --- a/src/rootserver/ddl_task/ob_modify_autoinc_task.h +++ b/src/rootserver/ddl_task/ob_modify_autoinc_task.h @@ -60,7 +60,7 @@ public: const int64_t schema_version, const int64_t consumer_group_id, const obrpc::ObAlterTableArg &alter_table_arg, - const int64_t task_status = share::ObDDLTaskStatus::LOCK_TABLE, + const int64_t task_status = share::ObDDLTaskStatus::MODIFY_AUTOINC, const int64_t snapshot_version = 0); int init(const ObDDLTaskRecord &task_record); virtual int process() override; @@ -72,7 +72,6 @@ public: virtual void flt_set_status_span_tag() const override; virtual int cleanup_impl() override; private: - int lock_table(); int unlock_table(); int modify_autoinc(); int wait_trans_end(); diff --git a/src/rootserver/ddl_task/ob_table_redefinition_task.cpp b/src/rootserver/ddl_task/ob_table_redefinition_task.cpp old mode 100644 new mode 100755 index 7af851dec..7f7645eaf --- a/src/rootserver/ddl_task/ob_table_redefinition_task.cpp +++ b/src/rootserver/ddl_task/ob_table_redefinition_task.cpp @@ -743,6 +743,7 @@ int ObTableRedefinitionTask::take_effect(const ObDDLTaskStatus next_task_status) alter_table_arg_.hidden_table_id_ = target_object_id_; // offline ddl is allowed on table with trigger(enable/disable). alter_table_arg_.need_rebuild_trigger_ = true; + alter_table_arg_.task_id_ = task_id_; alter_table_arg_.alter_table_schema_.set_tenant_id(tenant_id_); ObRootService *root_service = GCTX.root_service_; ObSchemaGetterGuard schema_guard; @@ -849,12 +850,12 @@ int ObTableRedefinitionTask::process() } break; case ObDDLTaskStatus::WAIT_TRANS_END: - if (OB_FAIL(wait_trans_end(wait_trans_ctx_, ObDDLTaskStatus::LOCK_TABLE))) { + if (OB_FAIL(wait_trans_end(wait_trans_ctx_, ObDDLTaskStatus::OBTAIN_SNAPSHOT))) { LOG_WARN("fail to wait trans end", K(ret)); } break; - case ObDDLTaskStatus::LOCK_TABLE: - if (OB_FAIL(lock_table(ObDDLTaskStatus::CHECK_TABLE_EMPTY))) { + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: + if (OB_FAIL(obtain_snapshot(ObDDLTaskStatus::CHECK_TABLE_EMPTY))) { LOG_WARN("fail to lock table", K(ret)); } break; @@ -1077,11 +1078,11 @@ int ObTableRedefinitionTask::collect_longops_stat(ObLongopsValue &value) } break; } - case ObDDLTaskStatus::LOCK_TABLE: { + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: { if (OB_FAIL(databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, - "STATUS: ACQUIRE TABLE LOCK"))) { + "STATUS: OBTAIN SNAPSHOT"))) { LOG_WARN("failed to print", K(ret)); } break; @@ -1232,7 +1233,7 @@ void ObTableRedefinitionTask::flt_set_status_span_tag() const FLT_SET_TAG(ddl_data_table_id, object_id_, ddl_ret_code, ret_code_); break; } - case ObDDLTaskStatus::LOCK_TABLE: { + case ObDDLTaskStatus::OBTAIN_SNAPSHOT: { FLT_SET_TAG(ddl_ret_code, ret_code_); break; } diff --git a/src/rootserver/freeze/ob_checksum_validator.cpp b/src/rootserver/freeze/ob_checksum_validator.cpp old mode 100644 new mode 100755 index ef225e895..bf533f663 --- a/src/rootserver/freeze/ob_checksum_validator.cpp +++ b/src/rootserver/freeze/ob_checksum_validator.cpp @@ -21,7 +21,6 @@ #include "lib/mysqlclient/ob_mysql_proxy.h" #include "lib/mysqlclient/ob_isql_client.h" #include "lib/time/ob_time_utility.h" -#include "share/backup/ob_backup_manager.h" #include "share/ob_service_epoch_proxy.h" #include "share/ob_tablet_replica_checksum_operator.h" #include "share/ob_tablet_checksum_operator.h" diff --git a/src/rootserver/freeze/ob_major_merge_scheduler.cpp b/src/rootserver/freeze/ob_major_merge_scheduler.cpp index d6b534272..19d252e5a 100644 --- a/src/rootserver/freeze/ob_major_merge_scheduler.cpp +++ b/src/rootserver/freeze/ob_major_merge_scheduler.cpp @@ -609,14 +609,21 @@ int ObMajorMergeScheduler::handle_all_zone_merge( // 2. Greater: In backup-restore situation, tablets may have higher snapshot_version, which // is larger than current frozen_scn. // - // cur_all_merged_scn >= ori_all_merged_scn + // cur_all_merged_scn >=< ori_all_merged_scn // 1. Greater: all_merged_scn will increase like last_merged_scn after major compaction // 2. Equal: In backup-restore situation, tablets may have higher snapshot_version(eg. version=10). // If major_freeze with version=4, all_merged_scn will be updated to 10; if major_freeze with version=5, // all_merged_scn will still be 10. - if ((cur_all_merged_scn < cur_merged_scn) - || (cur_all_merged_scn < ori_all_merged_scn) - || (cur_merged_scn < info.last_merged_scn())) { + // 3. Smaller: In backup-restore situation, part of tablets with higher compaction_scn + // (e.g., 5) are reported to __all_tablet_meta_table earlier, part of tablets with lower + // compaction_scn (e.g., 4) are reported to __all_tablet_meta_table later. all_merged_scn + // will fall back. + if (cur_all_merged_scn < ori_all_merged_scn) { + // do not generate error code, just print one log for analyzing + LOG_WARN("all_merged_scn fall back", K(cur_merged_scn), K(cur_all_merged_scn), + K(ori_all_merged_scn), K(info)); + } + if ((cur_all_merged_scn < cur_merged_scn) || (cur_merged_scn < info.last_merged_scn())) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("unexpected merged scn", KR(ret), K(merged), K(cur_merged_scn), K(cur_all_merged_scn), K(ori_all_merged_scn), K(info)); diff --git a/src/rootserver/ob_balance_group_ls_stat_operator.cpp b/src/rootserver/ob_balance_group_ls_stat_operator.cpp old mode 100644 new mode 100755 index 43116dd9d..4aa40338b --- a/src/rootserver/ob_balance_group_ls_stat_operator.cpp +++ b/src/rootserver/ob_balance_group_ls_stat_operator.cpp @@ -12,8 +12,8 @@ #define USING_LOG_PREFIX SHARE -#include "ob_balance_group_ls_stat_operator.h" - +#include "share/schema/ob_schema_mgr.h" +#include "rootserver/ob_balance_group_ls_stat_operator.h" #include "lib/hash/ob_hashset.h" #include "lib/oblog/ob_log_module.h" #include "lib/utility/ob_print_utils.h" @@ -26,6 +26,11 @@ #include "share/inner_table/ob_inner_table_schema_constants.h" #include "share/ob_srv_rpc_proxy.h" // ObSrvRpcProxy #include "share/tablet/ob_tablet_to_ls_operator.h" +#include "share/ls/ob_ls_operator.h" // ObLSAttrOperator +#include "share/balance/ob_balance_task_table_operator.h" // ObBalanceTaskTableOperator +#include "share/schema/ob_part_mgr_util.h" +#include "share/ob_debug_sync.h" // DEBUG_SYNC +#include "storage/tablelock/ob_lock_utils.h" // ObLSObjLockUtil #include "share/ls/ob_ls_table.h" // ObLSTable #include "share/ls/ob_ls_table_operator.h" // ObLSTableOperator #include "share/location_cache/ob_location_service.h" // ObLocationService @@ -37,10 +42,14 @@ using namespace common; using namespace common::sqlclient; using namespace share; using namespace share::schema; +using namespace transaction::tablelock; namespace rootserver { + +int64_t ObNewTableTabletAllocator::alloc_tablet_ls_offset_ = 0; + int ObBalanceGroupLSStat::build( const uint64_t tenant_id, const ObBalanceGroupID &balance_group_id, @@ -329,6 +338,25 @@ int ObBalanceGroupLSStatOperator::insert_update_balance_group_ls_stat( return ret; } +int ObBalanceGroupLSStatOperator::delete_balance_group_ls_stat( + const int64_t timeout, + common::ObISQLClient &sql_client, + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_FAIL(sql.assign_fmt("delete from %s where tenant_id= %ld", OB_ALL_BALANCE_GROUP_LS_STAT_TNAME, tenant_id))) { + LOG_WARN("fail to format sql", KR(ret)); + } else if (OB_FAIL(sql_client.write(gen_meta_tenant_id(tenant_id), sql.ptr(), affected_rows))) { + LOG_WARN("fail to delete inner table", KR(ret), K(sql)); + } + return ret; +} + int ObBalanceGroupLSStatOperator::generate_insert_update_sql( const ObBalanceGroupLSStat &bg_ls_stat, common::ObSqlString &sql_string) @@ -382,7 +410,8 @@ ObNewTableTabletAllocator::ObNewTableTabletAllocator( bg_ls_stat_operator_(), status_(MyStatus::INVALID), ls_id_array_(), - inited_(false) + inited_(false), + is_add_partition_(false) { } @@ -406,15 +435,19 @@ int ObNewTableTabletAllocator::init() LOG_WARN("fail to start trans", KR(ret), K(meta_tenant_id)); } else { status_ = MyStatus::WAIT_TO_PREPARE; + is_add_partition_ = false; inited_ = true; } return ret; } int ObNewTableTabletAllocator::prepare( - const share::schema::ObTableSchema &table_schema) + ObMySQLTransaction &trans, + const share::schema::ObTableSchema &table_schema, + bool is_add_partition) { int ret = OB_SUCCESS; + is_add_partition_ = is_add_partition; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObNewTableTabletAllocator not init", KR(ret)); @@ -457,10 +490,22 @@ int ObNewTableTabletAllocator::prepare( } } } + + DEBUG_SYNC(BEFORE_LOCK_LS_WHEN_CREATE_TABLE); + // If ls status is not normal or is blocking tablet in, choose new ls for tablet creating. + if (OB_FAIL(ret)) { + } else if (is_related_table(table_schema.get_table_type(), table_schema.get_index_type())) { + // skip lock ls + } else if (OB_FAIL(check_and_replace_ls_(trans, table_schema.get_tenant_id()))) { + LOG_WARN("lock user ls failed", KR(ret), + "tenant_id", table_schema.get_tenant_id(), K_(ls_id_array)); + } } + if (OB_SUCC(ret)) { status_ = MyStatus::WAIT_TO_OUTPUT; } + is_add_partition_ = false; return ret; } @@ -540,55 +585,19 @@ int ObNewTableTabletAllocator::get_tablet_id_array( if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); - } else if (PARTITION_LEVEL_ZERO == table_schema.get_part_level()) { - if (OB_FAIL(tablet_id_array.push_back(table_schema.get_tablet_id()))) { - LOG_WARN("fail to append fmt", KR(ret), K(table_schema)); - } - } else if (PARTITION_LEVEL_ONE == table_schema.get_part_level()) { - ObPartition **part_array = table_schema.get_part_array(); - if (OB_UNLIKELY(nullptr == part_array)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("part array is null", K(table_schema), KR(ret)); - } else { - for (int64_t i = 0; i < table_schema.get_partition_num() && OB_SUCC(ret); ++i) { - ObPartition *this_part = part_array[i]; - if (OB_UNLIKELY(nullptr == this_part)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("NULL ptr", K(i), K(table_schema), KR(ret)); - } else if (OB_FAIL(tablet_id_array.push_back(this_part->get_tablet_id()))) { - LOG_WARN("fail to append fmt", KR(ret), K(table_schema)); - } - } - } - } else if (PARTITION_LEVEL_TWO == table_schema.get_part_level()) { - ObPartition **part_array = table_schema.get_part_array(); - if (OB_UNLIKELY(nullptr == part_array)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("part array is null", K(table_schema), KR(ret)); - } else { - for (int64_t i = 0; i < table_schema.get_partition_num() && OB_SUCC(ret); ++i) { - ObPartition *this_part = nullptr; - ObSubPartition **sub_part_array = nullptr; - if (OB_UNLIKELY(nullptr == (this_part = part_array[i]) - || nullptr == (sub_part_array = this_part->get_subpart_array()))) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("NULL ptr", K(i), K(table_schema), KR(ret)); - } else { - for (int64_t j = 0; j < this_part->get_subpartition_num() && OB_SUCC(ret); j++) { - ObSubPartition *this_sub_part = sub_part_array[j]; - if (OB_UNLIKELY(nullptr == this_sub_part)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("NULL ptr", K(j), K(table_schema), KR(ret)); - } else if (OB_FAIL(tablet_id_array.push_back(this_sub_part->get_tablet_id()))) { - LOG_WARN("fail to append fmt", KR(ret), K(table_schema)); - } - } - } - } - } } else { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("part level invalid", KR(ret), K(table_schema)); + schema::ObPartitionSchemaIter iter(table_schema, schema::CHECK_PARTITION_MODE_NORMAL); + schema::ObPartitionSchemaIter::Info info; + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.next_partition_info(info))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(tablet_id_array.push_back(info.tablet_id_))) { + LOG_WARN("fail to push tablet_id to array", KR(ret), K(info.tablet_id_)); + } + } } return ret; } @@ -615,14 +624,14 @@ int ObNewTableTabletAllocator::alloc_tablet_by_primary_schema( tenant_id_, tablet_id_array, ls_id_array_))) { - LOG_WARN("fail to batch get ls", KR(ret)); + LOG_WARN("fail to batch get ls", KR(ret)); } } return ret; } int ObNewTableTabletAllocator::get_available_ls( - common::ObIArray &ls_status_info_array) + common::ObIArray &ls_id_array) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!inited_)) { @@ -632,19 +641,19 @@ int ObNewTableTabletAllocator::get_available_ls( ret = OB_ERR_UNEXPECTED; LOG_WARN("sql_proxy ptr is null", KR(ret)); } else { - share::ObLSStatusOperator ls_status_operator; - common::ObArray my_ls_array; - if (OB_FAIL(ls_status_operator.get_all_ls_status_by_order( - tenant_id_, - my_ls_array, - *sql_proxy_))) { - LOG_WARN("fail to get all ls status by order", KR(ret)); + share::ObLSAttrOperator ls_attr_operator(tenant_id_, sql_proxy_); + ObLSAttrArray ls_attr_array; + if (OB_FAIL(ls_attr_operator.get_all_ls_by_order(ls_attr_array))) { + LOG_WARN("fail to load all ls", KR(ret), K_(tenant_id)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < my_ls_array.count(); ++i) { - share::ObLSStatusInfo &ls_status_info = my_ls_array.at(i); - if (ls_status_info.ls_is_normal() && SYS_LS != ls_status_info.ls_id_ && !ls_status_info.is_duplicate_ls()) { - if (OB_FAIL(ls_status_info_array.push_back(ls_status_info))) { - LOG_WARN("fail to push back", KR(ret)); + ARRAY_FOREACH(ls_attr_array, idx) { + share::ObLSAttr &ls_attr = ls_attr_array.at(idx); + if (ls_attr.ls_is_normal() + && SYS_LS != ls_attr.get_ls_id() + && !ls_attr.get_ls_flag().is_block_tablet_in() + && !ls_attr.get_ls_flag().is_duplicate_ls()) { + if (OB_FAIL(ls_id_array.push_back(ls_attr.get_ls_id()))) { + LOG_WARN("fail to push back", KR(ret), K(ls_attr), K(ls_id_array)); } } } @@ -653,37 +662,10 @@ int ObNewTableTabletAllocator::get_available_ls( return ret; } -int ObNewTableTabletAllocator::get_balance_group_primary_schema( - const share::schema::ObTableSchema &table_schema, - const share::schema::ObPartitionSchema *&primary_schema) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("ObNewTableTabletAllocator not init", KR(ret)); - } else if (OB_INVALID_ID == table_schema.get_tablegroup_id()) { - primary_schema = &table_schema; - } else { - const share::schema::ObTablegroupSchema *tg_schema = nullptr; - if (OB_FAIL(schema_guard_.get_tablegroup_schema( - table_schema.get_tenant_id(), - table_schema.get_tablegroup_id(), - tg_schema))) { - LOG_WARN("fail to get tablegroup schema", KR(ret), K(table_schema)); - } else if (OB_UNLIKELY(nullptr == tg_schema)) { - ret = OB_TABLEGROUP_NOT_EXIST; - LOG_WARN("tablegroup not exist", KR(ret), "tg_id", table_schema.get_tablegroup_id()); - } else { - primary_schema = tg_schema; - } - } - return ret; -} - int ObNewTableTabletAllocator::alloc_tablet_for_create_balance_group( const ObBalanceGroupName &bg_name, const ObBalanceGroupID &bg_id, - const common::ObIArray &ls_status_info_array, + const common::ObIArray &ls_id_array, const int64_t part_num) { int ret = OB_SUCCESS; @@ -692,23 +674,24 @@ int ObNewTableTabletAllocator::alloc_tablet_for_create_balance_group( LOG_WARN("ObNewTableTabletAllocator not init", KR(ret)); } else if (OB_UNLIKELY(bg_name.is_empty() || !bg_id.is_valid() - || ls_status_info_array.count() <= 0 + || ls_id_array.count() <= 0 || part_num <= 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(bg_name), K(bg_id), - K(ls_status_info_array), + K(ls_id_array), K(part_num)); } else { - const int64_t bucket_num = ls_status_info_array.count(); + const int64_t bucket_num = ls_id_array.count(); const int64_t min_itl = part_num / bucket_num; const int64_t max_itl = ((min_itl * bucket_num == part_num) ? (min_itl) : (min_itl + 1)); const int64_t min_cnt = max_itl * bucket_num - part_num; const int64_t max_cnt = bucket_num - min_cnt; common::ObArray bg_ls_stat_array; - for (int64_t i = 0; OB_SUCC(ret) && i < ls_status_info_array.count(); ++i) { - const share::ObLSID &ls_id = ls_status_info_array.at(i).ls_id_; + int64_t start_idx = fetch_ls_offset(); + for (int64_t i = 0; OB_SUCC(ret) && i < ls_id_array.count(); ++i) { + const share::ObLSID &ls_id = ls_id_array.at((start_idx + i) % ls_id_array.count()); const int64_t tablet_cnt = ((i < min_cnt) ? min_itl : max_itl); for (int64_t j = 0; OB_SUCC(ret) && j < tablet_cnt; ++j) { if (OB_FAIL(ls_id_array_.push_back(ls_id))) { @@ -748,7 +731,7 @@ int ObNewTableTabletAllocator::alloc_tablet_for_add_balance_group( const common::ObIArray &bg_ls_stat_array, const ObBalanceGroupName &bg_name, const ObBalanceGroupID &bg_id, - const common::ObIArray &ls_status_info_array, + const common::ObIArray &ls_id_array, const int64_t partition_num) { int ret = OB_SUCCESS; @@ -759,13 +742,13 @@ int ObNewTableTabletAllocator::alloc_tablet_for_add_balance_group( LOG_WARN("ObNewTableTabletAllocator not init", KR(ret)); } else if (OB_UNLIKELY(bg_name.is_empty() || !bg_id.is_valid() - || ls_status_info_array.count() <= 0 + || ls_id_array.count() <= 0 || partition_num <= 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(bg_name), K(bg_id), - K(ls_status_info_array), + K(ls_id_array), K(partition_num)); } else if (OB_FAIL(ls_id_set.create(MAX_TENANT_LS_CNT))) { LOG_WARN("fail to create ls id set", KR(ret)); @@ -773,8 +756,8 @@ int ObNewTableTabletAllocator::alloc_tablet_for_add_balance_group( common::ObArray final_ls_stat_array; int64_t total_alloc_num = partition_num; int64_t valid_bg_cnt = total_alloc_num; - for (int64_t i = 0; OB_SUCC(ret) && i < ls_status_info_array.count(); ++i) { - const share::ObLSID &ls_id = ls_status_info_array.at(i).ls_id_; + for (int64_t i = 0; OB_SUCC(ret) && i < ls_id_array.count(); ++i) { + const share::ObLSID &ls_id = ls_id_array.at(i); if (OB_FAIL(ls_id_set.set_refactored(ls_id, 0/*not overwrite*/))) { LOG_WARN("fail to set refactored", KR(ret)); } @@ -824,30 +807,21 @@ int ObNewTableTabletAllocator::alloc_tablet_for_add_balance_group( ret = OB_ERR_UNEXPECTED; LOG_WARN("final ls stat array count unexpected", KR(ret), K(final_ls_stat_array)); } else { - const int64_t valid_ls_num = final_ls_stat_array.count(); - const int64_t min_itl = valid_bg_cnt / valid_ls_num; - const int64_t max_itl = (min_itl * valid_ls_num == valid_bg_cnt) ? min_itl : min_itl + 1; - int64_t min_cnt = max_itl * valid_ls_num - valid_bg_cnt; - int64_t max_cnt = valid_ls_num - min_cnt; std::sort(final_ls_stat_array.begin(), final_ls_stat_array.end()); - for (int64_t i = 0; - OB_SUCC(ret) && i < final_ls_stat_array.count() && total_alloc_num > 0; - ++i) { - int64_t alloc_num = 0; - ObBalanceGroupLSStat &bg_ls_stat = final_ls_stat_array.at(i); - if (bg_ls_stat.get_tablet_group_count() >= max_itl) { - max_cnt--; - } else if (max_cnt > 0) { - max_cnt--; - alloc_num = max_itl - bg_ls_stat.get_tablet_group_count(); - } else { - alloc_num = min_itl - bg_ls_stat.get_tablet_group_count(); + for (int64_t alloc_seq = 0; OB_SUCC(ret) && alloc_seq < total_alloc_num; alloc_seq++) { + int64_t min_ls_tg_idx = 0; + int64_t min_ls_tg_cnt = final_ls_stat_array.at(0).get_tablet_group_count(); + // find min + for (int64_t i = 1; OB_SUCC(ret) && i < final_ls_stat_array.count(); ++i) { + ObBalanceGroupLSStat &bg_ls_stat = final_ls_stat_array.at(i); + if (bg_ls_stat.get_tablet_group_count() < min_ls_tg_cnt) { + min_ls_tg_idx = i; + min_ls_tg_cnt = bg_ls_stat.get_tablet_group_count(); + } } - alloc_num = total_alloc_num > alloc_num ? alloc_num : total_alloc_num; - total_alloc_num -= alloc_num; - bg_ls_stat.add_tablet_group_count(alloc_num); - for (int64_t j = 0; OB_SUCC(ret) && j < alloc_num; ++j) { - if (OB_FAIL(ls_id_array_.push_back(bg_ls_stat.get_ls_id()))) { + if (OB_SUCC(ret)) { + final_ls_stat_array.at(min_ls_tg_idx).add_tablet_group_count(1); + if (OB_FAIL(ls_id_array_.push_back(final_ls_stat_array.at(min_ls_tg_idx).get_ls_id()))) { LOG_WARN("fail to push back", KR(ret)); } } @@ -866,7 +840,7 @@ int ObNewTableTabletAllocator::alloc_tablet_for_add_balance_group( } return ret; } - + int ObNewTableTabletAllocator::alloc_tablet_for_one_level_partitioned_balance_group( const share::schema::ObTableSchema &table_schema) { @@ -874,36 +848,47 @@ int ObNewTableTabletAllocator::alloc_tablet_for_one_level_partitioned_balance_gr LOG_INFO("alloc tablet for one level partitioned balance group", "tenant_id", table_schema.get_tenant_id(), "table_id", table_schema.get_table_id()); - ObBalanceGroupName bg_name; - ObBalanceGroupID bg_id; - common::ObArray ls_status_info_array; - const share::schema::ObPartitionSchema *partition_schema = nullptr; + common::ObArray ls_id_array; + ObBalanceGroup bg; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObNewTableTabletAllocator not init", KR(ret)); } else if (OB_UNLIKELY(PARTITION_LEVEL_ONE != table_schema.get_part_level())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), "part_level", table_schema.get_part_level()); - } else if (OB_FAIL(get_balance_group_primary_schema( - table_schema, - partition_schema))) { - LOG_WARN("fail to get balance group partition schema", KR(ret)); - } else if (OB_UNLIKELY(nullptr == partition_schema)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition schema ptr is null", KR(ret), KP(partition_schema)); - } else if (OB_FAIL(get_one_level_partitioned_bg_info( - *partition_schema, - bg_name, - bg_id))) { + } else if (OB_FAIL(bg.init_by_table(table_schema, NULL/*partition*/))) { LOG_WARN("fail to get one level partitioned bg info", KR(ret)); - } else if (OB_FAIL(get_available_ls(ls_status_info_array))) { + } else if (OB_FAIL(get_available_ls(ls_id_array))) { LOG_WARN("fail to get available ls", KR(ret)); - } else if (OB_FAIL(alloc_tablet_for_create_balance_group( - bg_name, - bg_id, - ls_status_info_array, + } else { + if (!is_add_partition_) { + if (OB_FAIL(alloc_tablet_for_create_balance_group( + bg.name(), + bg.id(), + ls_id_array, table_schema.get_partition_num()))) { - LOG_WARN("fail to alloc tablet for create balance group", KR(ret)); + LOG_WARN("fail to alloc tablet for create balance group", KR(ret)); + } + } else { + common::ObArray bg_ls_stat_array; + if (OB_FAIL(bg_ls_stat_operator_.get_balance_group_ls_stat( + THIS_WORKER.get_timeout_remain(), + trans_, + tenant_id_, + bg.id(), + true, /*for update*/ + bg_ls_stat_array))) { + LOG_WARN("fail to get balance group ls stat", KR(ret), + K(tenant_id_), K(bg)); + } else if (OB_FAIL(alloc_tablet_for_add_balance_group( + bg_ls_stat_array, + bg.name(), + bg.id(), + ls_id_array, + table_schema.get_partition_num()))) { + LOG_WARN("fail to alloc tablet for add balance group", KR(ret), K(bg)); + } + } } return ret; } @@ -916,10 +901,8 @@ int ObNewTableTabletAllocator::alloc_tablet_for_two_level_partitioned_balance_gr LOG_INFO("alloc tablet for two level partitioned balance group", "tenant_id", table_schema.get_tenant_id(), "table_id", table_schema.get_table_id()); - ObBalanceGroupName bg_name; - ObBalanceGroupID bg_id; - common::ObArray ls_status_info_array; - const share::schema::ObPartitionSchema *partition_schema = nullptr; + common::ObArray ls_id_array; + ObBalanceGroup bg; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObNewTableTabletAllocator not init", KR(ret)); @@ -930,36 +913,48 @@ int ObNewTableTabletAllocator::alloc_tablet_for_two_level_partitioned_balance_gr ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid part idx", KR(ret), K(part_idx), "part_num", table_schema.get_partition_num()); - } else if (OB_FAIL(get_balance_group_primary_schema( - table_schema, - partition_schema))) { - LOG_WARN("fail to get balance group partition schema", KR(ret)); - } else if (OB_UNLIKELY(nullptr == partition_schema)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition schema ptr is null", KR(ret), KP(partition_schema)); } else { - ObPartition **part_array = nullptr; - ObPartition *this_part = nullptr; - if (OB_UNLIKELY(nullptr == (part_array = table_schema.get_part_array()) - || nullptr == (this_part = part_array[part_idx]))) { + const schema::ObPartition *partition = NULL; + if (OB_FAIL(table_schema.get_partition_by_partition_index(part_idx, schema::CHECK_PARTITION_MODE_NORMAL, partition))) { + LOG_WARN("get_partition_by_partition_index fail", KR(ret), K(part_idx), K(table_schema)); + } else if (OB_ISNULL(partition)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("part ptr is null", KR(ret), KP(part_array), KP(this_part)); - } else if (OB_FAIL(get_two_level_partitioned_bg_info( - *partition_schema, - *this_part, - bg_name, - bg_id))) { - LOG_WARN("fail to get two level partitioned bg info", KR(ret)); - } else if (OB_FAIL(get_available_ls(ls_status_info_array))) { + LOG_WARN("part ptr is null", KR(ret), K(part_idx), K(table_schema)); + } else if (OB_FAIL(bg.init_by_table(table_schema, partition))) { + LOG_WARN("fail to init two level partitioned bg info", KR(ret), K(table_schema), K(partition)); + } else if (OB_FAIL(get_available_ls(ls_id_array))) { LOG_WARN("fail to get available ls", KR(ret)); - } else if (OB_FAIL(alloc_tablet_for_create_balance_group( - bg_name, - bg_id, - ls_status_info_array, - this_part->get_subpartition_num()))) { - LOG_WARN("fail to alloc tablet for create balance group", KR(ret)); + } else { + if (!is_add_partition_) { + if (OB_FAIL(alloc_tablet_for_create_balance_group( + bg.name(), + bg.id(), + ls_id_array, + partition->get_subpartition_num()))) { + LOG_WARN("fail to alloc tablet for create balance group", KR(ret)); + } + } else { + common::ObArray bg_ls_stat_array; + if (OB_FAIL(bg_ls_stat_operator_.get_balance_group_ls_stat( + THIS_WORKER.get_timeout_remain(), + trans_, + tenant_id_, + bg.id(), + true, /*for update*/ + bg_ls_stat_array))) { + LOG_WARN("fail to get balance group ls stat", KR(ret), + K(tenant_id_), K(bg)); + } else if (OB_FAIL(alloc_tablet_for_add_balance_group( + bg_ls_stat_array, + bg.name(), + bg.id(), + ls_id_array, + partition->get_subpartition_num()))) { + LOG_WARN("fail to alloc tablet for add balance group", KR(ret), K(bg)); + } + } } - } + } return ret; } @@ -970,41 +965,38 @@ int ObNewTableTabletAllocator::alloc_tablet_for_non_partitioned_balance_group( LOG_INFO("alloc tablet for non partitioned balance group", "tenant_id", table_schema.get_tenant_id(), "table_id", table_schema.get_table_id()); - ObBalanceGroupName bg_name; - ObBalanceGroupID bg_id; + ObBalanceGroup bg; common::ObArray bg_ls_stat_array; - common::ObArray ls_status_info_array; + common::ObArray ls_id_array; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObNewTableTabletAllocator not init", KR(ret)); - } else if (OB_UNLIKELY(table_schema.get_all_part_num() > 1)) { + } else if (OB_UNLIKELY(PARTITION_LEVEL_ZERO != table_schema.get_part_level())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), "part_num", table_schema.get_all_part_num(), + "part_level", table_schema.get_part_level(), K(table_schema)); - } else if (OB_FAIL(get_non_partitioned_bg_info( - tenant_id_, - bg_name, - bg_id))) { - LOG_WARN("fail to get non partitioned bg info", KR(ret), K(tenant_id_)); - } else if (OB_FAIL(get_available_ls(ls_status_info_array))) { + } else if (OB_FAIL(bg.init_by_table(table_schema, NULL/*partition*/))) { + LOG_WARN("fail to init non partitioned bg info", KR(ret), K(bg), K(table_schema)); + } else if (OB_FAIL(get_available_ls(ls_id_array))) { LOG_WARN("fail to get available ls", KR(ret)); } else if (OB_FAIL(bg_ls_stat_operator_.get_balance_group_ls_stat( THIS_WORKER.get_timeout_remain(), trans_, tenant_id_, - bg_id, + bg.id(), true, /*for update*/ bg_ls_stat_array))) { - LOG_WARN("fail to get balance group ls stat", KR(ret), - K(tenant_id_), K(bg_id)); + LOG_WARN("fail to get balance group ls stat", KR(ret), K(tenant_id_), K(bg)); } else if (OB_FAIL(alloc_tablet_for_add_balance_group( bg_ls_stat_array, - bg_name, - bg_id, - ls_status_info_array, + bg.name(), + bg.id(), + ls_id_array, table_schema.get_all_part_num()))) { - LOG_WARN("fail to alloc tablet for add balance group", KR(ret)); + LOG_WARN("fail to alloc tablet for add balance group", KR(ret), K(bg), K(bg_ls_stat_array), + K(ls_id_array), K(table_schema.get_all_part_num())); } return ret; } @@ -1057,7 +1049,7 @@ int ObNewTableTabletAllocator::alloc_tablet_by_count_balance( LOG_WARN("failed to push_back", KR(ret), K(i)); } } - } else if (1 == table_schema.get_all_part_num()) { + } else if (PARTITION_LEVEL_ZERO == table_schema.get_part_level()) { if (OB_FAIL(alloc_tablet_for_non_partitioned_balance_group(table_schema))) { LOG_WARN("fail to alloc tablet by non partitioned balance group", KR(ret)); } @@ -1161,6 +1153,7 @@ int ObNewTableTabletAllocator::alloc_ls_for_in_tablegroup_tablet( } } else { common::ObArray table_schema_array; + const share::schema::ObSimpleTablegroupSchema *tablegroup_schema = NULL; if (OB_FAIL(schema_guard_.get_table_schemas_in_tablegroup( tenant_id_, table_schema.get_tablegroup_id(), @@ -1168,22 +1161,317 @@ int ObNewTableTabletAllocator::alloc_ls_for_in_tablegroup_tablet( LOG_WARN("fail to get table schemas in tablegroup", KR(ret), "tenant_id", tenant_id_, "tablegroup_id", table_schema.get_tablegroup_id()); + } else if (OB_FAIL(schema_guard_.get_tablegroup_schema(tenant_id_, table_schema.get_tablegroup_id(), tablegroup_schema))) { + LOG_WARN("fail to get tablegroup_schema", KR(ret), K(table_schema.get_tablegroup_id())); + } else if (OB_ISNULL(tablegroup_schema) || !tablegroup_schema->is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablegroup_schema invalid", KR(ret), K(tablegroup_schema)); } else if (table_schema_array.count() > 0) { if (OB_UNLIKELY(nullptr == table_schema_array.at(0))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table schema ptr is null", KR(ret), K(table_schema_array)); - } else if (OB_FAIL(alloc_tablet_by_primary_schema(*table_schema_array.at(0)))) { - LOG_WARN("fail to alloc tablet by guard", KR(ret)); + } else if (!is_add_partition_ || tablegroup_schema->get_sharding() == OB_PARTITION_SHARDING_NONE) { + if (OB_FAIL(alloc_tablet_for_tablegroup(*table_schema_array.at(0), table_schema, *tablegroup_schema))) { + LOG_WARN("fail to alloc tablet for tablegroup", KR(ret), K(is_add_partition_), K(tablegroup_schema), K(*table_schema_array.at(0)), K(table_schema)); + } + } else if (tablegroup_schema->get_sharding() == OB_PARTITION_SHARDING_ADAPTIVE) { + // add partition for tablegroup table may break the constraint of sharding ADAPTIVE + // so alloc tablet as new table + if (OB_FAIL(alloc_tablet_for_tablegroup(table_schema, *tablegroup_schema))) { + LOG_WARN("fail to alloc tablet for tablegroup", KR(ret), K(table_schema), K(tablegroup_schema)); + } + } else if (tablegroup_schema->get_sharding() == OB_PARTITION_SHARDING_PARTITION) { + /* add partition for tablegroup sharding=PARTITION, we process only add subpart binding to existing one level partition + * otherwise alloc tablet as new table + */ + const ObTableSchema *origin_table_schema = NULL; + if (OB_FAIL(schema_guard_.get_table_schema(table_schema.get_tenant_id(), table_schema.get_table_id(), origin_table_schema))) { + LOG_WARN("fail to get origin table_schema", KR(ret), K(table_schema.get_table_id())); + } else if (OB_ISNULL(origin_table_schema)) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("origin_table_schema is null", KR(ret), K(table_schema.get_table_id())); + } else if (OB_FAIL(alloc_tablet_for_add_part_in_tablegroup_sharding_partition(table_schema, *origin_table_schema))) { + LOG_WARN("fail to alloc_tablet_for_tablegroup_add_part", KR(ret), K(table_schema), K(origin_table_schema)); + } } } else { - if (OB_FAIL(alloc_tablet_by_count_balance(table_schema))) { - LOG_WARN("fail to alloc tablet by count balance", KR(ret), K(table_schema)); + if (OB_FAIL(alloc_tablet_for_tablegroup(table_schema, *tablegroup_schema))) { + LOG_WARN("fail to alloc tablet for tablegroup", KR(ret), K(table_schema)); } } } return ret; } +int ObNewTableTabletAllocator::alloc_tablet_for_add_part_in_tablegroup_sharding_partition( + const schema::ObTableSchema &table_schema, + const schema::ObTableSchema &origin_table_schema) +{ + int ret = OB_SUCCESS; + common::ObArray origin_ls_id_array; + common::ObArray pre_ls_id_array; + common::ObArray avail_ls_id_array; + if (table_schema.get_table_id() != origin_table_schema.get_table_id()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table schema not match", KR(ret), K(table_schema), K(origin_table_schema)); + } else if (OB_FAIL(generate_ls_array_by_primary_schema(origin_table_schema, origin_ls_id_array))) { + LOG_WARN("fail to generate_ls_array_by_primary_schema", KR(ret), K(origin_table_schema)); + } else if (OB_FAIL(extract_one_level_ls_array_by_primary_schema(origin_table_schema, origin_ls_id_array, pre_ls_id_array))) { + LOG_WARN("fail to extract_one_level_ls_array_by_primary_schema", KR(ret), K(origin_table_schema)); + } else if (OB_FAIL(get_available_ls(avail_ls_id_array))) { + LOG_WARN("fail get_available_ls", KR(ret)); + } else if (avail_ls_id_array.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("no available ls", KR(ret)); + } else { + for (int i = 0; OB_SUCC(ret) && i < table_schema.get_partition_num(); i++) { + const schema::ObPartition *partition = NULL; + if (OB_FAIL(table_schema.get_partition_by_partition_index(i, schema::CHECK_PARTITION_MODE_NORMAL, partition))) { + LOG_WARN("get_partition_by_partition_index fail", KR(ret), K(i), K(table_schema)); + } else if (OB_ISNULL(partition)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part ptr is null", KR(ret), K(i), K(table_schema)); + } else { + int64_t origin_part_index = OB_INVALID_INDEX; + ObLSID dest_ls_id; + int64_t need_ls_count = 1; + if (schema::PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + need_ls_count = partition->get_sub_part_num(); + } + if (OB_FAIL(origin_table_schema.get_partition_index_by_id(partition->get_part_id(), schema::CHECK_PARTITION_MODE_NORMAL, origin_part_index))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + int64_t dest_idx = (fetch_ls_offset() % avail_ls_id_array.count()); + // table_group can't use count balance because no partition value assign ls rule + dest_ls_id = avail_ls_id_array.at(dest_idx); + } + } else { + dest_ls_id = pre_ls_id_array.at(origin_part_index); + } + for (int c = 0; OB_SUCC(ret) && c < need_ls_count; c++) { + if (OB_FAIL(ls_id_array_.push_back(dest_ls_id))) { + LOG_WARN("fail to push ls_id to array", KR(ret), K(pre_ls_id_array), K(origin_part_index)); + } + } + } + } + } + return ret; +} + +int ObNewTableTabletAllocator::alloc_tablet_for_tablegroup( + const schema::ObTableSchema &table_schema, + const schema::ObSimpleTablegroupSchema &tablegroup_schema) +{ + int ret = OB_SUCCESS; + common::ObArray ls_id_array; + if (OB_FAIL(get_available_ls(ls_id_array))) { + LOG_WARN("fail to get available ls", KR(ret), K(tenant_id_)); + } else if (ls_id_array.empty()) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("empty ls to alloc", KR(ret), K(tenant_id_)); + } else if (tablegroup_schema.get_sharding() == OB_PARTITION_SHARDING_NONE || schema::PARTITION_LEVEL_ZERO == table_schema.get_part_level()) { + int64_t start_idx = fetch_ls_offset(); + ObLSID dest_ls_id = ls_id_array.at(start_idx % ls_id_array.count()); + for (int64_t i = 0; i < table_schema.get_all_part_num() && OB_SUCC(ret); i++) { + if (OB_FAIL(ls_id_array_.push_back(dest_ls_id))) { + LOG_WARN("failed to push_back", KR(ret), K(i)); + } + } + } else if (tablegroup_schema.get_sharding() == OB_PARTITION_SHARDING_PARTITION || schema::PARTITION_LEVEL_ONE == table_schema.get_part_level()) { + int64_t start_idx = fetch_ls_offset(); + for (int64_t i = 0; i < table_schema.get_partition_num() && OB_SUCC(ret); i++) { + ObLSID dest_ls_id = ls_id_array.at((start_idx + i) % ls_id_array.count()); + if (schema::PARTITION_LEVEL_ONE == table_schema.get_part_level()) { + if (OB_FAIL(ls_id_array_.push_back(dest_ls_id))) { + LOG_WARN("failed to push_back", KR(ret), K(i)); + } + } else if (schema::PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + const schema::ObPartition *partition = NULL; + if (OB_FAIL(table_schema.get_partition_by_partition_index(i, schema::CHECK_PARTITION_MODE_NORMAL, partition))) { + LOG_WARN("get_partition_by_partition_index fail", KR(ret), K(i), K(table_schema)); + } else if (OB_ISNULL(partition)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part ptr is null", KR(ret), K(i), K(table_schema)); + } else { + for (int64_t sp = 0; OB_SUCC(ret) && sp < partition->get_subpartition_num(); sp++) { + if (OB_FAIL(ls_id_array_.push_back(dest_ls_id))) { + LOG_WARN("failed to push ls_id to array", KR(ret), K(dest_ls_id)); + } + } + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected part_level", KR(ret), K(table_schema.get_part_level())); + } + } + } else if (tablegroup_schema.get_sharding() == OB_PARTITION_SHARDING_ADAPTIVE) { + for (int64_t i = 0; i < table_schema.get_partition_num() && OB_SUCC(ret); i++) { + int64_t start_idx = fetch_ls_offset(); + if (schema::PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + const schema::ObPartition *partition = NULL; + if (OB_FAIL(table_schema.get_partition_by_partition_index(i, schema::CHECK_PARTITION_MODE_NORMAL, partition))) { + LOG_WARN("get_partition_by_partition_index fail", KR(ret), K(i), K(table_schema)); + } else if (OB_ISNULL(partition)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part ptr is null", KR(ret), K(i), K(table_schema)); + } else { + for (int64_t sp = 0; OB_SUCC(ret) && sp < partition->get_subpartition_num(); sp++) { + ObLSID dest_ls_id = ls_id_array.at((start_idx + sp) % ls_id_array.count()); + if (OB_FAIL(ls_id_array_.push_back(dest_ls_id))) { + LOG_WARN("failed to push ls_id to array", KR(ret), K(dest_ls_id)); + } + } + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected part_level", KR(ret), K(table_schema.get_part_level())); + } + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unknow sharding option", KR(ret), K(tablegroup_schema.get_sharding())); + } + return ret; +} + +int ObNewTableTabletAllocator::generate_ls_array_by_primary_schema( + const schema::ObTableSchema &primary_schema, + common::ObArray &ls_id_array) +{ + int ret = OB_SUCCESS; + + ls_id_array.reuse(); + common::ObArray tablet_id_array; + if (OB_FAIL(get_tablet_id_array(primary_schema, tablet_id_array))) { + LOG_WARN("fail to get tablet id array", KR(ret), K(primary_schema)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql_proxy is null", KR(ret)); + } else if (OB_FAIL(ObTabletToLSTableOperator::batch_get_ls( + *sql_proxy_, + tenant_id_, + tablet_id_array, + ls_id_array))) { + LOG_WARN("fail to batch get ls", KR(ret), K(tenant_id_), K(tablet_id_array), K(primary_schema)); + } else if (ls_id_array.count() != primary_schema.get_all_part_num()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("empty pre_ls_id_array", KR(ret), K(tenant_id_), K(tablet_id_array), K(primary_schema)); + } + + return ret; +} + +int ObNewTableTabletAllocator::extract_one_level_ls_array_by_primary_schema( + const schema::ObTableSchema &primary_schema, + common::ObArray &all_ls_id_array, + common::ObArray &pre_ls_id_array) +{ + int ret = OB_SUCCESS; + pre_ls_id_array.reuse(); + if (primary_schema.get_all_part_num() != all_ls_id_array.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part count not match", KR(ret), K(primary_schema.get_all_part_num()), K(all_ls_id_array.count())); + } else { + int64_t primary_partition_offset = 0; + for (int64_t part_idx = 0; OB_SUCC(ret) && part_idx < primary_schema.get_partition_num(); part_idx++) { + if (OB_FAIL(pre_ls_id_array.push_back(all_ls_id_array.at(primary_partition_offset)))) { + LOG_WARN("push ls_id to array", KR(ret), K(primary_partition_offset), K(all_ls_id_array)); + } else if (schema::PARTITION_LEVEL_ONE == primary_schema.get_part_level()) { + primary_partition_offset++; + } else if (schema::PARTITION_LEVEL_TWO == primary_schema.get_part_level()) { + const schema::ObPartition *partition = NULL; + if (OB_FAIL(primary_schema.get_partition_by_partition_index(part_idx, schema::CHECK_PARTITION_MODE_NORMAL, partition))) { + LOG_WARN("get_partition_by_partition_index fail", KR(ret), K(part_idx), K(primary_schema)); + } else if (OB_ISNULL(partition)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part ptr is null", KR(ret), K(part_idx), K(primary_schema)); + } else { + primary_partition_offset += partition->get_subpartition_num(); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unknow table part_level", KR(ret), K(primary_schema)); + } + } + } + + return ret; +} + +int ObNewTableTabletAllocator::alloc_tablet_for_tablegroup( + const schema::ObTableSchema &primary_schema, + const schema::ObTableSchema &table_schema, + const schema::ObSimpleTablegroupSchema &tablegroup_schema) +{ + int ret = OB_SUCCESS; + if (tablegroup_schema.get_sharding() == OB_PARTITION_SHARDING_NONE || table_schema.get_part_level() == schema::PARTITION_LEVEL_ZERO) { + common::ObArray pre_ls_id_array; + if (OB_FAIL(generate_ls_array_by_primary_schema(primary_schema, pre_ls_id_array))) { + LOG_WARN("fail to generate_ls_array_by_primary_schema", KR(ret), K(primary_schema)); + } else { + // first tablet location ls + ObLSID dest_ls_id = pre_ls_id_array.at(0); + for (int64_t i = 0; i < table_schema.get_all_part_num() && OB_SUCC(ret); i++) { + if (OB_FAIL(ls_id_array_.push_back(dest_ls_id))) { + LOG_WARN("failed to push_back", KR(ret), K(i), K(tenant_id_), K(table_schema)); + } + } + } + } else if (tablegroup_schema.get_sharding() == OB_PARTITION_SHARDING_PARTITION) { + common::ObArray all_ls_id_array; + common::ObArray pre_ls_id_array; + if (primary_schema.get_partition_num() != table_schema.get_partition_num()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("mismatch partition num in tablegroup", KR(ret), K(primary_schema), K(table_schema)); + } else if (OB_FAIL(generate_ls_array_by_primary_schema(primary_schema, all_ls_id_array))) { + LOG_WARN("fail to generate_ls_array_by_primary_schema", KR(ret), K(primary_schema)); + } else if (OB_FAIL(extract_one_level_ls_array_by_primary_schema(primary_schema, all_ls_id_array, pre_ls_id_array))) { + LOG_WARN("fail to extract_one_level_ls_array_by_primary_schema", KR(ret), K(primary_schema)); + } else { + /* + * keep align with one level partition + */ + for (int64_t i = 0; i < table_schema.get_partition_num() && OB_SUCC(ret); i++) { + ObLSID dest_ls_id = pre_ls_id_array.at(i); + if (schema::PARTITION_LEVEL_ONE == table_schema.get_part_level()) { + if (OB_FAIL(ls_id_array_.push_back(dest_ls_id))) { + LOG_WARN("failed to push_back", KR(ret), K(i)); + } + } else if (schema::PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + const schema::ObPartition *partition = NULL; + if (OB_FAIL(table_schema.get_partition_by_partition_index(i, schema::CHECK_PARTITION_MODE_NORMAL, partition))) { + LOG_WARN("get_partition_by_partition_index fail", KR(ret), K(i), K(table_schema)); + } else if (OB_ISNULL(partition)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part ptr is null", KR(ret), K(i), K(table_schema)); + } else { + for (int64_t sp = 0; OB_SUCC(ret) && sp < partition->get_subpartition_num(); sp++) { + if (OB_FAIL(ls_id_array_.push_back(dest_ls_id))) { + LOG_WARN("failed to push ls_id to array", KR(ret), K(dest_ls_id)); + } + } + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unknow table part_level", KR(ret), K(table_schema)); + } + } + } + } else if (tablegroup_schema.get_sharding() == OB_PARTITION_SHARDING_ADAPTIVE) { + if (primary_schema.get_all_part_num() != table_schema.get_all_part_num()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("mismatch partition in tablegroup", KR(ret), K(table_schema), K(primary_schema)); + } else if (OB_FAIL(alloc_tablet_by_primary_schema(primary_schema))) { + LOG_WARN("fail to alloc tablet by primary_schema", KR(ret), K(primary_schema)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unknow sharding option", KR(ret), K(tablegroup_schema.get_sharding())); + } + return ret; +} + int ObNewTableTabletAllocator::alloc_ls_for_normal_table_tablet( const share::schema::ObTableSchema &table_schema) { @@ -1313,92 +1601,165 @@ int ObNewTableTabletAllocator::alloc_ls_for_duplicate_table_( return ret; } -int ObNewTableTabletAllocator::get_non_partitioned_bg_info( - const uint64_t tenant_id, - ObBalanceGroupName &bg_name, - ObBalanceGroupID &bg_id) +int ObNewTableTabletAllocator::check_and_replace_ls_( + ObMySQLTransaction &trans, + const uint64_t tenant_id) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + ObArray locked_ls_id_array; + if (OB_UNLIKELY(!inited_) || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObNewTableTabletAllocator not init", KR(ret)); + } else if (OB_FAIL(locked_ls_id_array.reserve(ls_id_array_.count()))) { + LOG_WARN("reserve failed", KR(ret), K(tenant_id), K_(ls_id_array)); } else { - common::ObSqlString bg_name_str; - if (OB_FAIL(bg_name_str.append_fmt( - "BG_TENANT_%ld", - tenant_id))) { - LOG_WARN("fail to append fmt", KR(ret)); - } else if (OB_FAIL(bg_name.assign( - bg_name_str.ptr()))) { - LOG_WARN("fail to assign bg name", KR(ret), K(bg_name_str)); - } else { - bg_id = ObBalanceGroupID(tenant_id, - 0); - LOG_INFO("get non partitioned bg info", - K(tenant_id), - K(bg_name), - K(bg_id)); + ARRAY_FOREACH(ls_id_array_, idx) { + ObLSID prev_ls_id; + ObLSID new_ls_id; + ObLSAttr new_ls_attr; + ObLSAttr curr_ls_attr; + const ObLSID curr_ls_id = ls_id_array_.at(idx); + if (idx > 0) { + int64_t index = OB_INVALID_INDEX; + find_last_user_ls_(locked_ls_id_array, index); + if (index >= 0 && index < locked_ls_id_array.count()) { + prev_ls_id = locked_ls_id_array.at(index); + } + } + if (curr_ls_id.is_sys_ls()) { // do not lock sys ls + new_ls_id = curr_ls_id; + } else if (OB_FAIL(lock_and_check_ls_( + trans, + tenant_id, + locked_ls_id_array, + curr_ls_id, + curr_ls_attr))) { + if (OB_STATE_NOT_MATCH == ret) { + if (OB_FAIL(choose_new_ls_(tenant_id, curr_ls_attr, prev_ls_id, new_ls_id))) { + LOG_WARN("choose new ls failed", KR(ret), + K(tenant_id), K(curr_ls_attr), K(prev_ls_id), K(new_ls_id)); + } else if (OB_FAIL(lock_and_check_ls_( + trans, + tenant_id, + locked_ls_id_array, + new_ls_id, + new_ls_attr))) { + LOG_WARN("check and lock ls failed", KR(ret), + K(tenant_id), K(locked_ls_id_array), K(new_ls_id), K(new_ls_attr)); + } else { + LOG_INFO("the ls allocated for tablet creating has changed", + KR(ret), K(tenant_id), "old_ls_id", curr_ls_id, K(new_ls_id)); + } + } else { + LOG_WARN("check and lock ls failed", KR(ret), + K(tenant_id), K(locked_ls_id_array), K(curr_ls_id), K(curr_ls_attr)); + } + } else { // lock user ls successfully + new_ls_id = curr_ls_id; + } + if (FAILEDx(locked_ls_id_array.push_back(new_ls_id))){ + LOG_WARN("push back failed", KR(ret), K(new_ls_id), K(locked_ls_id_array)); + } + } + if (OB_FAIL(ret)) { + } else if (locked_ls_id_array.count() != ls_id_array_.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls_id_array count not match", KR(ret), K(tenant_id), + "tmp_ls_id_arry count", locked_ls_id_array.count(), + "ls_id_array_ count", ls_id_array_.count(), K(locked_ls_id_array), K_(ls_id_array)); + } else if (OB_FAIL(ls_id_array_.assign(locked_ls_id_array))) { + LOG_WARN("assign failed", KR(ret), K(locked_ls_id_array), K_(ls_id_array)); } } return ret; } -int ObNewTableTabletAllocator::get_one_level_partitioned_bg_info( - const share::schema::ObPartitionSchema &entity_schema, - ObBalanceGroupName &bg_name, - ObBalanceGroupID &bg_id) +void ObNewTableTabletAllocator::find_last_user_ls_( + const ObIArray &ls_id_array, + int64_t &index) +{ + index = OB_INVALID_INDEX; + for (int64_t i = ls_id_array.count() - 1; i >= 0; --i) { + const ObLSID &curr_ls = ls_id_array.at(i); + if (curr_ls.id() > ObLSID::MIN_USER_LS_ID) { + index = i; + break; + } + } +} + +int ObNewTableTabletAllocator::lock_and_check_ls_( + ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObIArray &locked_ls_id_array, + const ObLSID &ls_id, + ObLSAttr &ls_attr) { int ret = OB_SUCCESS; - common::ObSqlString bg_name_str; - if (OB_FAIL(bg_name_str.append_fmt( - "BG_ONE_LEVEL_PART_%s_%ld_%s", - (OB_INVALID_ID != entity_schema.get_tablegroup_id() - ? "TG" : "TB"), - entity_schema.get_tenant_id(), - entity_schema.get_entity_name()))) { - LOG_WARN("fail to append fmt", KR(ret)); - } else if (OB_FAIL(bg_name.assign( - bg_name_str.ptr()))) { - LOG_WARN("fail to assign bg name", KR(ret), K(bg_name_str)); + ls_attr.reset(); + if (OB_UNLIKELY(!inited_) || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObNewTableTabletAllocator not init", KR(ret)); + } else if (!ls_id.is_valid_with_tenant(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(ls_id)); + } else if (common::has_exist_in_array(locked_ls_id_array, ls_id)) { + // ls has been locked } else { - bg_id = ObBalanceGroupID(entity_schema.get_table_id(), - 0); - LOG_INFO("get non partitioned bg info", - "tenant_id", entity_schema.get_tenant_id(), - K(bg_name), - K(bg_id)); + ObLSAttrOperator ls_operator(tenant_id, sql_proxy_); + if (OB_FAIL(ObLSObjLockUtil::lock_ls_in_trans( + trans, + tenant_id, + ls_id, + SHARE))) { + LOG_WARN("lock ls in trans failed", KR(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(ls_operator.get_ls_attr(ls_id, false/*for_update*/, trans, ls_attr))) { + LOG_WARN("get ls attr failed", KR(ret), K(ls_id), K(ls_attr)); + } else if (!ls_attr.ls_is_normal() || ls_attr.get_ls_flag().is_block_tablet_in()) { + ret = OB_STATE_NOT_MATCH; + LOG_TRACE("can not create tablet on this ls beacuse it is not in normal status or is block tablet in", + KR(ret), K(tenant_id), K(ls_id), K(ls_attr)); + } } return ret; } -int ObNewTableTabletAllocator::get_two_level_partitioned_bg_info( - const share::schema::ObPartitionSchema &entity_schema, - const share::schema::ObPartition &partition_schema, - ObBalanceGroupName &bg_name, - ObBalanceGroupID &bg_id) +int ObNewTableTabletAllocator::choose_new_ls_( + const uint64_t tenant_id, + const ObLSAttr &old_ls_attr, + const ObLSID &prev_ls_id, + ObLSID &new_ls_id) { int ret = OB_SUCCESS; - common::ObSqlString bg_name_str; - if (OB_FAIL(bg_name_str.append_fmt( - "BG_TWO_LEVEL_PART_%s_%ld_%s_%s", - (OB_INVALID_ID != entity_schema.get_tablegroup_id() - ? "TG" : "TB"), - entity_schema.get_tenant_id(), - entity_schema.get_entity_name(), - partition_schema.get_part_name().ptr()))) { - LOG_WARN("fail to append fmt", KR(ret)); - } else if (OB_FAIL(bg_name.assign( - bg_name_str.ptr()))) { - LOG_WARN("fail to assign bg name", KR(ret), K(bg_name_str)); + if (OB_UNLIKELY(!inited_) || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObNewTableTabletAllocator not init", KR(ret)); + } else if (!old_ls_attr.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(old_ls_attr)); + } else if (!old_ls_attr.ls_is_normal()) { + if (prev_ls_id.is_valid()) { + new_ls_id = prev_ls_id; + } else { + ObLSAttrOperator ls_operator(tenant_id, sql_proxy_); + if (OB_FAIL(ls_operator.get_random_normal_user_ls(new_ls_id))) { + LOG_WARN("get random normal user ls failed", KR(ret), K(tenant_id), K(new_ls_id)); + } + } + } else if (old_ls_attr.get_ls_flag().is_block_tablet_in()) { + if (OB_FAIL(ObBalanceTaskTableOperator::get_merge_task_dest_ls_by_src_ls( + *sql_proxy_, + tenant_id, + old_ls_attr.get_ls_id(), + new_ls_id))) { + LOG_WARN("get dest ls by src ls failed", KR(ret), K(tenant_id), K(old_ls_attr), K(new_ls_id)); + } } else { - bg_id = ObBalanceGroupID(entity_schema.get_table_id(), - partition_schema.get_part_id()); - LOG_INFO("get non partitioned bg info", - "tenant_id", entity_schema.get_tenant_id(), - K(bg_name), - K(bg_id)); + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected ls_attr", KR(ret), K(old_ls_attr)); } return ret; } + }//end namespace rootserver }//end namespace oceanbase diff --git a/src/rootserver/ob_balance_group_ls_stat_operator.h b/src/rootserver/ob_balance_group_ls_stat_operator.h index 1235c67b7..13cf51a0d 100644 --- a/src/rootserver/ob_balance_group_ls_stat_operator.h +++ b/src/rootserver/ob_balance_group_ls_stat_operator.h @@ -22,6 +22,9 @@ #include "lib/mysqlclient/ob_mysql_proxy.h" #include "share/ob_ls_id.h" #include "share/ls/ob_ls_status_operator.h" +#include "share/schema/ob_schema_mgr.h" + +#include "balance/ob_balance_group_define.h" // ObBalanceGroupID, ObBalanceGroupName namespace oceanbase { @@ -32,6 +35,7 @@ class ObISQLClient; } namespace share { +class ObLSAttr; namespace schema { class ObSchemaGetterGuard; @@ -40,33 +44,13 @@ class ObPartition; class ObTableSchema; } } +namespace observer +{ +class ObInnerSQLConnection; +} namespace rootserver { -typedef common::ObFixedLengthString< - common::OB_MAX_BALANCE_GROUP_NAME_LENGTH> - ObBalanceGroupName; -struct ObBalanceGroupID -{ -public: - ObBalanceGroupID() : id_high_(common::OB_INVALID_ID), - id_low_(common::OB_INVALID_ID) {} - ObBalanceGroupID(const uint64_t id_high, - const uint64_t id_low) - : id_high_(id_high), - id_low_(id_low) {} -public: - uint64_t id_high_; - uint64_t id_low_; - - TO_STRING_KV(K(id_high_), - K(id_low_)); - bool is_valid() const { - return OB_INVALID_ID != id_high_ - && OB_INVALID_ID != id_low_; - } -}; - class ObBalanceGroupLSStat { public: @@ -146,6 +130,10 @@ public: const uint64_t tenant_id, const ObBalanceGroupID &balance_group_id, const common::ObIArray &balance_group_ls_stat_array); + int delete_balance_group_ls_stat( + const int64_t timeout, + common::ObISQLClient &sql_client, + const uint64_t tenant_id); private: int generate_insert_update_sql( const ObBalanceGroupLSStat &bg_ls_stat, @@ -159,20 +147,6 @@ private: class ObNewTableTabletAllocator { -public: - static int get_non_partitioned_bg_info( - const uint64_t tenant_id, - ObBalanceGroupName &bg_name, - ObBalanceGroupID &bg_id); - static int get_one_level_partitioned_bg_info( - const share::schema::ObPartitionSchema &entity_schema, - ObBalanceGroupName &bg_name, - ObBalanceGroupID &bg_id); - static int get_two_level_partitioned_bg_info( - const share::schema::ObPartitionSchema &entity_schema, - const share::schema::ObPartition &partition_schema, - ObBalanceGroupName &bg_name, - ObBalanceGroupID &bg_id); public: ObNewTableTabletAllocator( const uint64_t tenant_id, @@ -182,7 +156,9 @@ public: public: int init(); int prepare( - const share::schema::ObTableSchema &table_schema); + ObMySQLTransaction &trans, + const share::schema::ObTableSchema &table_schema, + bool is_add_partition = false); int prepare_like( const share::schema::ObTableSchema &table_schema); int get_ls_id_array( @@ -202,6 +178,13 @@ private: int alloc_ls_for_duplicate_table_( const share::schema::ObTableSchema &table_schema); private: + int alloc_tablet_for_tablegroup( + const share::schema::ObTableSchema &table_schema, + const share::schema::ObSimpleTablegroupSchema &tablegroup_schema); + int alloc_tablet_for_tablegroup( + const share::schema::ObTableSchema &primary_schema, + const share::schema::ObTableSchema &table_schema, + const share::schema::ObSimpleTablegroupSchema &tablegroup_schema); int wait_ls_elect_leader_( const uint64_t tenant_id, const share::ObLSID &ls_id); @@ -221,22 +204,46 @@ private: int alloc_tablet_for_two_level_partitioned_balance_group( const share::schema::ObTableSchema &table_schema, const int64_t part_idx); - int get_available_ls( - common::ObIArray &ls_status_info_array); - int get_balance_group_primary_schema( - const share::schema::ObTableSchema &table_schema, - const share::schema::ObPartitionSchema *&primary_schema); + int get_available_ls(common::ObIArray &ls_id_array); int alloc_tablet_for_create_balance_group( const ObBalanceGroupName &bg_name, const ObBalanceGroupID &bg_id, - const common::ObIArray &ls_status_info_array, + const common::ObIArray &ls_id_array, const int64_t partition_num); int alloc_tablet_for_add_balance_group( const common::ObIArray &bg_ls_stat_array, const ObBalanceGroupName &bg_name, const ObBalanceGroupID &bg_id, - const common::ObIArray &ls_status_info_array, + const common::ObIArray &ls_id_array, const int64_t partition_num); + int check_and_replace_ls_(common::ObMySQLTransaction &trans, const uint64_t tenant_id); + void find_last_user_ls_( + const common::ObIArray &ls_id_array, + int64_t &index); + int lock_and_check_ls_( + common::ObMySQLTransaction &trans, + const uint64_t tenant_id, + const common::ObIArray &locked_ls_id_array, + const share::ObLSID &ls_id, + share::ObLSAttr &ls_attr); + int choose_new_ls_( + const uint64_t tenant_id, + const share::ObLSAttr &old_ls_attr, + const share::ObLSID &prev_ls_id, + share::ObLSID &new_ls_id); + int generate_ls_array_by_primary_schema( + const share::schema::ObTableSchema &primary_schema, + common::ObArray &pre_ls_id_array); + int extract_one_level_ls_array_by_primary_schema( + const share::schema::ObTableSchema &primary_schema, + common::ObArray &all_ls_id_array, + common::ObArray &pre_ls_id_array); + int alloc_tablet_for_add_part_in_tablegroup_sharding_partition( + const share::schema::ObTableSchema &table_schema, + const share::schema::ObTableSchema &origin_table_schema); + int64_t fetch_ls_offset() { + return ATOMIC_FAA(&alloc_tablet_ls_offset_, 1); + } private: static const int64_t MAX_TENANT_LS_CNT = 1024; static const int64_t WAIT_INTERVAL_US = 1000 * 1000; // 1s @@ -254,6 +261,8 @@ private: MyStatus status_; common::ObArray ls_id_array_; bool inited_; + bool is_add_partition_; + static int64_t alloc_tablet_ls_offset_; }; }//end namespace rootserver diff --git a/src/rootserver/ob_balance_ls_primary_zone.cpp b/src/rootserver/ob_balance_ls_primary_zone.cpp new file mode 100755 index 000000000..b8a6843b9 --- /dev/null +++ b/src/rootserver/ob_balance_ls_primary_zone.cpp @@ -0,0 +1,359 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX RS +#include "ob_balance_ls_primary_zone.h" +#include "lib/profile/ob_trace_id.h" +#include "share/ob_errno.h" +#include "share/schema/ob_schema_struct.h"//ObTenantSchema +#include "share/schema/ob_schema_service.h"//ObMultiSchemaService +#include "share/ls/ob_ls_life_manager.h"//ObLSLifeAgentManager +#include "share/ls/ob_ls_status_operator.h"//ObLSStatusOperator +#include "share/ob_primary_zone_util.h"//ObPrimaryZoneUtil +#include "observer/ob_server_struct.h"//GCTX +#include "rootserver/ob_tenant_thread_helper.h"//get_zone_priority + +namespace oceanbase +{ +using namespace common; +using namespace share; +namespace rootserver +{ + +int ObBalanceLSPrimaryZone::try_adjust_user_ls_primary_zone(const share::schema::ObTenantSchema &tenant_schema) +{ + int ret = OB_SUCCESS; + share::ObLSStatusOperator status_op; + share::ObLSPrimaryZoneInfoArray info_array; + ObArray primary_zone; + const uint64_t tenant_id = tenant_schema.get_tenant_id(); + if (OB_ISNULL(GCTX.schema_service_) || OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", KR(ret), KP(GCTX.sql_proxy_), KP(GCTX.schema_service_)); + } else if (!is_user_tenant(tenant_id) || !tenant_schema.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant iS invalid", KR(ret), K(tenant_id), K(tenant_schema)); + } else if (OB_FAIL(ObPrimaryZoneUtil::get_tenant_primary_zone_array( + tenant_schema, primary_zone))) { + LOG_WARN("failed to get tenant primary zone array", KR(ret), K(tenant_schema)); + } else if (OB_FAIL(status_op.get_ls_primary_zone_info_by_order_ls_group( + tenant_id, info_array, *GCTX.sql_proxy_))) { + LOG_WARN("failed to get ls primary zone info array", KR(ret), K(tenant_id)); + } else { + uint64_t last_ls_group_id = OB_INVALID_ID; + share::ObLSPrimaryZoneInfoArray tmp_info_array; + for (int64_t i = 0; OB_SUCC(ret) && i < info_array.count(); ++i) { + //TODO ls group id maybe zero + const ObLSPrimaryZoneInfo &info = info_array.at(i); + if (!info.get_ls_id().is_sys_ls()) { + if (OB_INVALID_ID == last_ls_group_id) { + last_ls_group_id = info.get_ls_group_id(); + } + if (last_ls_group_id != info.get_ls_group_id()) { + //process the ls group + if (OB_FAIL(adjust_primary_zone_by_ls_group_(primary_zone, tmp_info_array, tenant_schema))) { + LOG_WARN("failed to update primary zone of each ls group", KR(ret), + K(tmp_info_array), K(primary_zone), K(tenant_schema)); + } else { + tmp_info_array.reset(); + last_ls_group_id = info.get_ls_group_id(); + } + } + if (FAILEDx(tmp_info_array.push_back(info))) { + LOG_WARN("failed to push back primary info array", KR(ret), K(i)); + } + } + } + if (OB_SUCC(ret) && 0 < tmp_info_array.count()) { + if (OB_FAIL(adjust_primary_zone_by_ls_group_(primary_zone, tmp_info_array, tenant_schema))) { + LOG_WARN("failed to update primary zone of each ls group", KR(ret), + K(tmp_info_array), K(primary_zone), K(tenant_schema)); + } + } + } + return ret; +} + +//check every ls has right primary zone in ls group +//if primary_zone of ls not in primary zone, try to choose a right zone, +//if can not find a zone to modify, modify the ls to exist zone, +//load_balancer will choose the right ls to drop +//eg: +//if ls group has z1, z2 and primary zone is : z1. need modify z2 to z1 +//if ls group has z1, z2 and primary zone is : z1, z3. modify z2 to z3; +int ObBalanceLSPrimaryZone::adjust_primary_zone_by_ls_group_( + const common::ObIArray &primary_zone_array, + const ObIArray &primary_zone_infos, + const share::schema::ObTenantSchema &tenant_schema) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = tenant_schema.get_tenant_id(); + const int64_t ls_count = primary_zone_infos.count(); + const int64_t primary_zone_count = primary_zone_array.count(); + if (OB_UNLIKELY(0 == primary_zone_count + || 0 == ls_count || !tenant_schema.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(primary_zone_infos), + K(primary_zone_array), K(tenant_schema)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret)); + } else if (1 == ls_count + && primary_zone_infos.at(0).get_ls_id().is_sys_ls()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("can not be sys ls", KR(ret), K(ls_count), K(primary_zone_infos)); + } else { + //Algorithm Description: + //Assumption: We have 5 ls, 3 primary_zones(z1, z2, z3). + //1. Set the primary zone of ls to tenant's primary zone, + //choose the least number of log streams on the zone is selected for all zones + //2. After all the primary_zone of the ls are in the primary_zone of the tenant, + //choose the primary_zone with the most and least ls. Adjust a certain number of ls to the smallest zone without exceeding the balance + //while guaranteeing that the number of the zone with the most is no less than the average. + ObArray ls_primary_zone;//is match with primary_zone_infos + ObSEArray count_group_by_zone;//ls count of each primary zone + ObSqlString new_zone_priority; + if (OB_FAIL(set_ls_to_primary_zone_(primary_zone_array, primary_zone_infos, ls_primary_zone, + count_group_by_zone))) { + LOG_WARN("failed to set ls to primary zone", KR(ret), K(primary_zone_array), K(primary_zone_infos)); + } else if (OB_FAIL(balance_ls_primary_zone_(primary_zone_array, ls_primary_zone, count_group_by_zone))) { + LOG_WARN("failed to balance ls primary zone", KR(ret), K(ls_primary_zone), K(count_group_by_zone)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < ls_count; ++i) { + const ObZone &new_primary_zone = ls_primary_zone.at(i); + if (OB_FAIL(ObTenantThreadHelper::get_zone_priority(new_primary_zone, tenant_schema, new_zone_priority))) { + LOG_WARN("failed to get normalize primary zone", KR(ret), K(new_primary_zone)); + } + if (FAILEDx(try_update_ls_primary_zone(primary_zone_infos.at(i), new_primary_zone, new_zone_priority))) { + LOG_WARN("failed to update ls primary zone", KR(ret), "primary_zone_info", primary_zone_infos.at(i), + K(new_primary_zone), K(new_zone_priority)); + } + } + } + return ret; +} + +int ObBalanceLSPrimaryZone::set_ls_to_primary_zone_( + const common::ObIArray &primary_zone_array, + const ObIArray &primary_zone_infos, + common::ObIArray &ls_primary_zone, + common::ObIArray &count_group_by_zone) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(0 == primary_zone_array.count() + || 0 == primary_zone_infos.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(primary_zone_array), K(primary_zone_infos)); + } else { + const int64_t primary_zone_count = primary_zone_array.count(); + const int64_t ls_count = primary_zone_infos.count(); + //ls may not in primary zone, record the index of primary_zone_infos not in primary zone + ObSEArray index_not_primary_zone; + int64_t index = 0; + ARRAY_FOREACH_X(primary_zone_array, idx, cnt, OB_SUCC(ret)) { + if (OB_FAIL(count_group_by_zone.push_back(0))) { + LOG_WARN("failed to push back", KR(ret), K(idx)); + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < ls_count; ++i) { + const ObZone ¤t_zone = primary_zone_infos.at(i).get_primary_zone(); + if (has_exist_in_array(primary_zone_array, current_zone, &index)) { + count_group_by_zone.at(index)++; + } else if (OB_FAIL(index_not_primary_zone.push_back(i))) { + LOG_WARN("failed to push back", KR(ret), K(i), K(current_zone)); + } + if (FAILEDx(ls_primary_zone.push_back(current_zone))) { + LOG_WARN("failed to push back current zone", KR(ret), K(i), K(current_zone)); + } + } + //1. take all ls primary zone to tenant primary zone, choose the less primary zone count + int64_t min_count = INT64_MAX; + int64_t min_index = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < index_not_primary_zone.count(); ++i) { + const int64_t ls_index = index_not_primary_zone.at(i); + min_count = INT64_MAX; + ARRAY_FOREACH_X(primary_zone_array, idx, cnt, OB_SUCC(ret)) { + if (min_count > count_group_by_zone.at(idx)) { + min_count = count_group_by_zone.at(idx); + min_index = idx; + } + }//end for search min count + if (OB_FAIL(ret)) { + } else if (min_index >= primary_zone_count) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to found min count", KR(ret), K(min_index), K(primary_zone_array)); + } else if (OB_FAIL(ls_primary_zone.at(ls_index).assign(primary_zone_array.at(min_index)))) { + LOG_WARN("failed to assign primary zone", KR(ret), K(min_index), K(min_count), K(ls_index)); + } else { + count_group_by_zone.at(min_index)++; + } + } + } + return ret; + +} + +int ObBalanceLSPrimaryZone::balance_ls_primary_zone_( + const common::ObIArray &primary_zone_array, + common::ObIArray &ls_primary_zone, + common::ObIArray &count_group_by_zone) +{ + int ret = OB_SUCCESS; + const int64_t ls_count = ls_primary_zone.count(); + const int64_t primary_zone_count = count_group_by_zone.count(); + if (OB_UNLIKELY(0 == primary_zone_count + || 0 == ls_count + || primary_zone_count != primary_zone_array.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(count_group_by_zone), K(ls_primary_zone)); + } else { + int64_t max_count = -1, max_index = 0; + int64_t min_count = INT64_MAX, min_index = 0; + do { + max_count = -1, max_index = 0; + min_count = INT64_MAX, min_index = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < primary_zone_count; ++i) { + const int64_t ls_count = count_group_by_zone.at(i); + if (min_count > ls_count) { + min_count = ls_count; + min_index = i; + } + if (max_count < ls_count) { + max_count = ls_count; + max_index = i; + } + }//end for find min and max count + if (OB_UNLIKELY(max_index >= primary_zone_count || min_index >= primary_zone_count + || -1 == max_count || INT64_MAX == min_count)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get primary zone", KR(ret), K(max_index), K(min_index), + K(min_count), K(max_count), + K(primary_zone_array), K(primary_zone_count), K(ls_primary_zone)); + } else if (max_count - min_count > 1) { + for (int64_t i = 0; OB_SUCC(ret) && i < ls_count; ++i) { + if (ls_primary_zone.at(i) == primary_zone_array.at(max_index)) { + if (OB_FAIL(ls_primary_zone.at(i).assign(primary_zone_array.at(min_index)))) { + LOG_WARN("failed to push back ls primary zone", KR(ret), K(min_index)); + } else { + count_group_by_zone.at(max_index)--; + count_group_by_zone.at(min_index)++; + } + break;//only change one by one + } + } + } + } while (max_count - min_count > 1); + } + return ret; +} + +int ObBalanceLSPrimaryZone::try_update_ls_primary_zone( + const share::ObLSPrimaryZoneInfo &primary_zone_info, + const common::ObZone &new_primary_zone, + const common::ObSqlString &zone_priority) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!primary_zone_info.is_valid() + || new_primary_zone.is_empty() || zone_priority.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("primary zone info is invalid", KR(ret), K(primary_zone_info), + K(new_primary_zone), K(zone_priority)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret)); + } else if (new_primary_zone != primary_zone_info.get_primary_zone() + || zone_priority.string() != primary_zone_info.get_zone_priority_str()) { + ObLSLifeAgentManager ls_life_agent(*GCTX.sql_proxy_); + if (OB_FAIL(ls_life_agent.update_ls_primary_zone(primary_zone_info.get_tenant_id(), + primary_zone_info.get_ls_id(), + new_primary_zone, zone_priority.string()))) { + LOG_WARN("failed to update ls primary zone", KR(ret), K(primary_zone_info), + K(new_primary_zone), K(zone_priority)); + } + LOG_INFO("update ls primary zone", KR(ret), K(new_primary_zone), + K(zone_priority), K(primary_zone_info)); + } else { + //no need update + } + return ret; +} + +int ObBalanceLSPrimaryZone::try_update_sys_ls_primary_zone(const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + share::schema::ObTenantSchema tenant_schema; + if (OB_ISNULL(GCTX.schema_service_) || OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", KR(ret), KP(GCTX.sql_proxy_), KP(GCTX.schema_service_)); + } else if (OB_UNLIKELY(is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("user tenant no need update sys ls primary zone", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ObTenantThreadHelper::get_tenant_schema(tenant_id, tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(tenant_id)); + } else { + share::ObLSPrimaryZoneInfo primary_zone_info; + ObArray primary_zone; + share::ObLSStatusOperator status_op; + ObZone new_primary_zone; + ObSqlString new_zone_priority; + if (OB_FAIL(ObPrimaryZoneUtil::get_tenant_primary_zone_array( + tenant_schema, primary_zone))) { + LOG_WARN("failed to get tenant primary zone array", KR(ret), K(tenant_schema)); + } else if (OB_FAIL(status_op.get_ls_primary_zone_info(tenant_id, + SYS_LS, primary_zone_info, *GCTX.sql_proxy_))) { + LOG_WARN("failed to get ls primary_zone info", KR(ret), K(tenant_id)); + } else if (OB_UNLIKELY(0 == primary_zone.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("primary zone is empty", KR(ret), K(tenant_schema)); + } else if (has_exist_in_array(primary_zone, primary_zone_info.get_primary_zone())) { + if (OB_FAIL(new_primary_zone.assign(primary_zone_info.get_primary_zone()))) { + LOG_WARN("failed to assign primary zone", KR(ret), K(primary_zone_info)); + } + } else if (OB_FAIL(new_primary_zone.assign(primary_zone.at(0)))) { + LOG_WARN("failed to assign primary zone", KR(ret), K(primary_zone)); + } + if (OB_FAIL(ret)) { + } else if (is_sys_tenant(tenant_id)) { + //sys tenant use tenant normalize primary zone + if (OB_FAIL(ObPrimaryZoneUtil::get_tenant_zone_priority( + tenant_schema, new_zone_priority))) { + LOG_WARN("failed to get tenant primary zone array", KR(ret), K(tenant_schema)); + } + } else if (OB_FAIL(ObTenantThreadHelper::get_zone_priority(new_primary_zone, + tenant_schema, new_zone_priority))) { + LOG_WARN("failed to get normalize primary zone", KR(ret), K(new_primary_zone)); + } + if (FAILEDx(try_update_ls_primary_zone( + primary_zone_info, new_primary_zone, new_zone_priority))) { + LOG_WARN("failed to update ls primary zone", KR(ret), K(primary_zone_info), + K(new_primary_zone), K(new_zone_priority)); + } else if (is_meta_tenant(tenant_id)) { + //user sys ls has same primary zone with meta sys ls + share::ObLSPrimaryZoneInfo user_primary_zone_info; + const uint64_t user_tenant_id = gen_user_tenant_id(tenant_id); + if (OB_FAIL(status_op.get_ls_primary_zone_info(user_tenant_id, SYS_LS, + user_primary_zone_info, *GCTX.sql_proxy_))) { + LOG_WARN("failed to get ls primary_zone info", KR(ret), K(tenant_id), K(user_tenant_id)); + } else if (OB_FAIL(try_update_ls_primary_zone( + user_primary_zone_info, new_primary_zone, + new_zone_priority))) { + LOG_WARN("failed to update ls primary zone", KR(ret), K(user_primary_zone_info), + K(new_primary_zone), K(new_zone_priority)); + } + } + } + return ret; +} + +}//end of rootserver +} diff --git a/src/rootserver/ob_balance_ls_primary_zone.h b/src/rootserver/ob_balance_ls_primary_zone.h new file mode 100644 index 000000000..b72e6dbba --- /dev/null +++ b/src/rootserver/ob_balance_ls_primary_zone.h @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_BALANCE_LS_PRIMARY_ZONE_H +#define OCEANBASE_ROOTSERVER_OB_BALANCE_LS_PRIMARY_ZONE_H +#include "lib/container/ob_array.h"//ObIArray +#include "common/ob_zone.h"//ObZone +namespace oceanbase +{ + +namespace common +{ +class ObMySQLProxy; +class ObISQLClient; +class ObMySQLTransaction; +class ObSqlString; +} +namespace share +{ +class ObLSTableOperator; +class SCN; +struct ObLSPrimaryZoneInfo; +namespace schema +{ +class ObMultiVersionSchemaService; +class ObTenantSchema; +} +} + +namespace rootserver +{ + +class ObBalanceLSPrimaryZone +{ +public: + ObBalanceLSPrimaryZone() {}; + virtual ~ObBalanceLSPrimaryZone() {}; + +public: + static int try_update_sys_ls_primary_zone(const uint64_t tenant_id); + static int try_adjust_user_ls_primary_zone(const share::schema::ObTenantSchema &tenant_schema); + static int try_update_ls_primary_zone( + const share::ObLSPrimaryZoneInfo &primary_zone_info, + const common::ObZone &new_primary_zone, + const common::ObSqlString &zone_priority); + +private: + static int adjust_primary_zone_by_ls_group_(const common::ObIArray &primary_zone_array, + const ObIArray &primary_zone_infos, + const share::schema::ObTenantSchema &tenant_schema); + static int set_ls_to_primary_zone_(const common::ObIArray &primary_zone_array, + const ObIArray &primary_zone_infos, + common::ObIArray &ls_primary_zone, + common::ObIArray &count_group_by_zone); + static int balance_ls_primary_zone_(const common::ObIArray &primary_zone_array, + common::ObIArray &ls_primary_zone, + common::ObIArray &count_group_by_zone); +}; + +} +} + + +#endif /* !OCEANBASE_ROOTSERVER_OB_BALANCE_LS_PRIMARY_ZONE_H */ diff --git a/src/rootserver/ob_balance_task_execute_service.cpp b/src/rootserver/ob_balance_task_execute_service.cpp new file mode 100755 index 000000000..325c835ba --- /dev/null +++ b/src/rootserver/ob_balance_task_execute_service.cpp @@ -0,0 +1,859 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX BALANCE +#include "ob_balance_task_execute_service.h" +#include "lib/mysqlclient/ob_mysql_transaction.h"//trans +#include "share/schema/ob_schema_struct.h"//ObTenantInfo +#include "share/schema/ob_multi_version_schema_service.h"//ObMultiVersionSchemaService +#include "share/schema/ob_part_mgr_util.h"//ObPartitionSchemaIter +#include "share/ob_unit_table_operator.h" //ObUnitTableOperator +#include "share/balance/ob_balance_job_table_operator.h"//ObBalanceJob +#include "share/ob_primary_zone_util.h"//get_primary_zone +#include "share/rc/ob_tenant_base.h"//MTL +#include "share/ls/ob_ls_operator.h"//ls_op +#include "share/ls/ob_ls_status_operator.h"//status_op +#include "share/ls/ob_ls_table_operator.h"//lst_operator->get +#include "rootserver/ob_tenant_transfer_service.h"//transfer +#include "rootserver/balance/ob_ls_all_part_builder.h" // ObLSAllPartBuilder +#include "rootserver/ob_root_utils.h"//get_rs_default_timeout_ctx +#include "observer/ob_server_struct.h"//GCTX + +#define ISTAT(fmt, args...) FLOG_INFO("[BALANCE_EXECUTE] " fmt, ##args) +#define WSTAT(fmt, args...) FLOG_WARN("[BALANCE_EXECUTE] " fmt, ##args) + + +namespace oceanbase +{ +using namespace common; +using namespace share; + +namespace rootserver +{ +//////////////ObBalanceTaskExecuteService +int ObBalanceTaskExecuteService::init() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("has inited", KR(ret)); + } else if (OB_FAIL(ObTenantThreadHelper::create("BalanceExec", + lib::TGDefIDs::SimpleLSService, *this))) { + LOG_WARN("failed to create thread", KR(ret)); + } else if (OB_FAIL(ObTenantThreadHelper::start())) { + LOG_WARN("fail to start thread", KR(ret)); + } else { + sql_proxy_ = GCTX.sql_proxy_; + task_comment_.reset(); + tenant_id_ = MTL_ID(); + task_array_.reset(); + inited_ = true; + } + return ret; +} + +void ObBalanceTaskExecuteService::destroy() +{ + ObTenantThreadHelper::destroy(); + tenant_id_ = OB_INVALID_TENANT_ID; + task_comment_.reset(); + task_array_.reset(); + sql_proxy_ = NULL; + inited_ = false; +} + +int ObBalanceTaskExecuteService::wait_tenant_ready_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema ptr is null", KR(ret), KP(GCTX.schema_service_)); + } else { + bool is_ready = false; + while (!is_ready && !has_set_stop()) { + ret = OB_SUCCESS; + + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObTenantSchema *tenant_schema = NULL; + if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id_, tenant_schema))) { + LOG_WARN("failed to get tenant ids", KR(ret), K(tenant_id_)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant not exist", KR(ret), K(tenant_id_)); + } else if (!tenant_schema->is_normal()) { + ret = OB_NEED_WAIT; + WSTAT("tenant schema not ready, no need tenant balance", KR(ret)); + } else { + is_ready = true; + } + + if (! is_ready) { + idle(10 * 1000 *1000); + } + } + + if (has_set_stop()) { + WSTAT("thread has been stopped", K(is_ready), K(tenant_id_)); + ret = OB_IN_STOP_STATE; + } + } + return ret; +} + +int ObBalanceTaskExecuteService::try_update_task_comment_( + const share::ObBalanceTask &task, const common::ObSqlString &comment, + ObISQLClient &sql_client) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(inited_)); + } else if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("job is invalid", KR(ret), K(task)); + } else if (comment.empty() || 0 == task.get_comment().string().case_compare(comment.ptr())) { + //comment is empty or commet is same, no need to update + } else if (OB_FAIL(ObBalanceTaskTableOperator::update_task_comment(tenant_id_, + task.get_balance_task_id(), comment.string(), sql_client))) { + LOG_WARN("failed to update task comment", KR(ret), K(task), K(comment), K(tenant_id_)); + } + return ret; +} + +void ObBalanceTaskExecuteService::do_work() +{ + int ret = OB_SUCCESS; + ISTAT("balance task execute thread", K(tenant_id_)); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("sql proxy is null", KR(ret)); + } else if (OB_FAIL(wait_tenant_ready_())) { + LOG_WARN("wait tenant ready fail", KR(ret), K(tenant_id_)); + } else { + int64_t idle_time_us = 100 * 1000L; + int tmp_ret = OB_SUCCESS; + while (!has_set_stop()) { + idle_time_us = 1 * 1000 * 1000L; + ObCurTraceId::init(GCONF.self_addr_); + task_array_.reset(); + DEBUG_SYNC(BEFORE_PROCESS_BALANCE_EXECUTE_WORK); + //TODO, check schema ready + if (OB_FAIL(ObBalanceTaskTableOperator::load_can_execute_task( + tenant_id_, task_array_, *sql_proxy_))) { + LOG_WARN("failed to load all balance task", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(execute_task_())) { + LOG_WARN("failed to execute balance task", KR(ret)); + } + if (OB_FAIL(ret)) { + idle_time_us = 100 * 1000; + } + ISTAT("finish one round", KR(ret), K(task_array_), K(idle_time_us), K(task_comment_)); + task_comment_.reset(); + idle(idle_time_us); + }// end while + } +} + +int ObBalanceTaskExecuteService::finish_task_( + const share::ObBalanceTask &task, + const ObBalanceTaskStatus finish_task_status, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(! task.is_valid() + || ! finish_task_status.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", KR(ret), K(task), K(finish_task_status)); + } + // clean finish task, move to history + else if (OB_FAIL(ObBalanceTaskTableOperator::clean_task(tenant_id_, task.get_balance_task_id(), trans))) { + LOG_WARN("failed to clean task", KR(ret), K(tenant_id_), K(task)); + } + // clean parent info of completed task + // ignore failed status tasks + else if (finish_task_status.is_completed()) { + const ObBalanceTaskIDList &child_list = task.get_child_task_list(); + for (int64_t i = 0; OB_SUCC(ret) && i < child_list.count(); ++i) { + if (OB_FAIL(ObBalanceTaskTableOperator::remove_parent_task(tenant_id_, child_list.at(i), + task.get_balance_task_id(), trans))) { + LOG_WARN("failed to clean parent info of task", KR(ret), K(child_list), K(i), K(task)); + } + } + } + ISTAT("clean finished task", KR(ret), K(task), K(finish_task_status)); + return ret; +} + +int ObBalanceTaskExecuteService::update_task_status_( + const share::ObBalanceTask &task, + const share::ObBalanceJobStatus &job_status, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObBalanceTaskStatus finish_task_status; + bool task_is_finished = false; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(! task.is_valid() + || !job_status.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", KR(ret), K(task), K(job_status)); + } else if (task.get_task_status().is_finish_status()) { + task_is_finished = true; + finish_task_status = task.get_task_status(); + } else { + ObBalanceTaskStatus next_task_status = task.get_next_status(job_status); + if (OB_UNLIKELY(!next_task_status.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("next task status is invalid", KR(ret), K(task)); + } else if (OB_FAIL(ObBalanceTaskTableOperator::update_task_status( + task, next_task_status, trans))) { + LOG_WARN("failed to update task status", KR(ret), K(tenant_id_), K(task), + K(next_task_status)); + } else { + task_is_finished = (next_task_status.is_finish_status()); + // get latest task status + finish_task_status = next_task_status; + } + ISTAT("update task status", KR(ret), "old_status", task.get_task_status(), + K(next_task_status), K(task_is_finished), K(task), K(job_status), K(task_comment_)); + } + + // finish task as soon as possible in one trans after task is finished + if (OB_FAIL(ret)) { + } else if (task_is_finished && + OB_FAIL(finish_task_(task, finish_task_status, trans))) { + LOG_WARN("fail to finish task", KR(ret), K(finish_task_status), + K(task)); + } + return ret; +} + +int ObBalanceTaskExecuteService::process_current_task_status_( + const share::ObBalanceTask &task, ObMySQLTransaction &trans, + bool &skip_next_status) +{ + int ret = OB_SUCCESS; + skip_next_status = false; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("task is invalid", KR(ret), K(task)); + } else { + if (task.get_task_status().is_init()) { + DEBUG_SYNC(BEFORE_PROCESS_BALANCE_TASK_INIT); + if (OB_FAIL(process_init_task_(task, trans))) { + LOG_WARN("failed to init trans", KR(ret)); + } + } else if (task.get_task_status().is_create_ls()) { + DEBUG_SYNC(BEFORE_PROCESS_BALANCE_TASK_CREATE_LS); + if (OB_FAIL(wait_ls_to_target_status_(task.get_dest_ls_id(), + share::OB_LS_NORMAL, skip_next_status))) { + LOG_WARN("failed to wait ls to normal", KR(ret), K(task)); + } + } else if (task.get_task_status().is_transfer()) { + DEBUG_SYNC(BEFORE_PROCESS_BALANCE_TASK_TRANSFER); + bool all_part_transfered = false; + if (OB_FAIL( + execute_transfer_in_trans_(task, trans, all_part_transfered))) { + LOG_WARN("failed to execute transfer in trans", KR(ret), K(task)); + } else if (!all_part_transfered) { + skip_next_status = true; + } else if (task.get_task_type().is_merge_task()) { + DEBUG_SYNC(BEFORE_DROPPING_LS_IN_BALANCE_MERGE_TASK); + if (OB_FAIL(set_ls_to_dropping_(task.get_src_ls_id(), trans))) { + LOG_WARN("failed to set ls dropping", KR(ret), K(task)); + } + } + } else if (task.get_task_status().is_alter_ls()) { + DEBUG_SYNC(BEFORE_PROCESS_BALANCE_TASK_ALTER_LS); + if (OB_FAIL(wait_alter_ls_(task, skip_next_status))) { + LOG_WARN("failed to wait alter ls", KR(ret), K(task)); + } + } else if (task.get_task_status().is_set_merge_ls()) { + DEBUG_SYNC(BEFORE_PROCESS_BALANCE_TASK_SET_MERGE); + if (OB_FAIL(set_ls_to_merge_(task, trans))) { + LOG_WARN("failed to set ls to merge", KR(ret), K(task)); + } + } else if (task.get_task_status().is_drop_ls()) { + DEBUG_SYNC(BEFORE_PROCESS_BALANCE_TASK_DROP_LS); + if (OB_FAIL(wait_ls_to_target_status_(task.get_src_ls_id(), + share::OB_LS_WAIT_OFFLINE, skip_next_status))) { + LOG_WARN("failed to wait to wait offline", KR(ret), K(task)); + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + // ls status already drop end + } + } + } else { + ret = OB_ERR_UNDEFINED; + LOG_WARN("unexpected task status", KR(ret), K(task)); + } + } + return ret; +} + +int ObBalanceTaskExecuteService::execute_task_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("sql proxy is null", KR(ret)); + } else { + int tmp_ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < task_array_.count(); ++i) { + ObBalanceJob job; + task_comment_.reset(); + bool skip_next_status = false; + common::ObMySQLTransaction trans; + const ObBalanceTask &task = task_array_.at(i); + const ObBalanceTaskID task_id = task.get_balance_task_id(); + ObBalanceTask task_in_trans;//for update + ObTimeoutCtx timeout_ctx; + DEBUG_SYNC(BEFORE_EXECUTE_BALANCE_TASK); + if (OB_FAIL(trans.start(sql_proxy_, tenant_id_))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(timeout_ctx, GCONF.internal_sql_execute_timeout))) { + LOG_WARN("failed to get rs default timeout ctx", KR(ret)); + } else if (OB_FAIL(get_balance_job_task_for_update_(task, job, task_in_trans, trans))) { + LOG_WARN("failed to get job", KR(ret), K(task)); + } else if (task_in_trans.get_task_status().is_finish_status()) { + } else { + if (job.get_job_status().is_doing()) { + if (OB_FAIL(process_current_task_status_(task_in_trans, trans, skip_next_status))) { + LOG_WARN("failed to process current task status", KR(ret), K(task_in_trans)); + } + } else if (job.get_job_status().is_canceling()) { + if (OB_FAIL(cancel_current_task_status_(task_in_trans, trans, skip_next_status))) { + LOG_WARN("failed to cancel current task", KR(ret), K(task_in_trans)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("balance job status not expected", KR(ret), K(task_in_trans), K(job)); + } + } + if (!task_comment_.empty()) { + if (FAILEDx(try_update_task_comment_(task_in_trans, task_comment_, trans))) { + LOG_WARN("failed to update task commet", KR(ret), K(task_in_trans), + K(task_comment_)); + } + } + + // move on to next status or clean up + if (OB_SUCC(ret) && !skip_next_status) { + if (OB_FAIL(update_task_status_(task_in_trans, job.get_job_status(), trans))) { + LOG_WARN("failed to update task status", KR(ret), K(task_in_trans), K(job)); + } + } + + + if (trans.is_started()) { + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to end trans", KR(ret), K(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + if (task_in_trans.get_task_status().is_set_merge_ls()) { + DEBUG_SYNC(AFTER_BLOCK_TABLET_IN_WHEN_LS_MERGE); + } + ISTAT("process task", KR(ret), K(task_in_trans), K(job), K(task_comment_)); + //isolate error of each task + ret = OB_SUCCESS; + } + } + return ret; +} + +int ObBalanceTaskExecuteService::get_balance_job_task_for_update_( + const ObBalanceTask &task, ObBalanceJob &job, ObBalanceTask &task_in_trans, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + job.reset(); + task_in_trans.reset();; + int64_t start_time = 0; //no use + int64_t finish_time = 0; //no use + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("sql proxy is null", KR(ret)); + } else if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("task is invalid", KR(ret), K(task)); + } else if (OB_FAIL(ObBalanceJobTableOperator::get_balance_job(tenant_id_, true, + trans, job, start_time, finish_time))) { + LOG_WARN("failed to get balance job", KR(ret), K(tenant_id_)); + } else if (task.get_job_id() != job.get_job_id()) { + ret = OB_ERR_UNEXPECTED; + WSTAT("job not expected", KR(ret), K(task), K(job)); + } else if (OB_FAIL(ObBalanceTaskTableOperator::get_balance_task(tenant_id_, + task.get_balance_task_id(), true, trans, task_in_trans, start_time, finish_time))) { + LOG_WARN("failed to get balance task", KR(ret), K(tenant_id_), K(task)); + } + return ret; +} + +int ObBalanceTaskExecuteService::cancel_current_task_status_( + const share::ObBalanceTask &task, ObMySQLTransaction &trans, bool &skip_next_status) +{ + int ret = OB_SUCCESS; + skip_next_status = false; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("task is invalid", KR(ret), K(task)); + } else { + if (task.get_task_status().is_transfer()) { + if (!task.get_current_transfer_task_id().is_valid()) { + //no transfer, no need to todo + } else { + //try to wait transfer end + ObTenantTransferService *transfer_service = + MTL(ObTenantTransferService *); + if (OB_ISNULL(transfer_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer service is null", KR(ret)); + } else if (OB_FAIL(transfer_service->try_cancel_transfer_task( + task.get_current_transfer_task_id()))) { + LOG_WARN("failed to cancel transfer task", KR(ret), K(task)); + skip_next_status = true; + int tmp_ret = ret; + ret = OB_SUCCESS; + if (OB_FAIL(task_comment_.assign_fmt("Fail to cancel transfer task %ld, result is %d", + task.get_current_transfer_task_id().id(), tmp_ret))) { + LOG_WARN("failed to assign fmt", KR(ret), KR(tmp_ret), K(task)); + } + } + } + } else { + //init, create ls, alter_ls, drop ls, set_ls_merge + //no need wait task end + } + if (OB_SUCC(ret) && !task.get_task_status().is_init() + && task.get_task_type().is_merge_task() && !skip_next_status) { + //rollback flag + ObLSAttrOperator ls_op(tenant_id_, sql_proxy_); + share::ObLSAttr ls_info; + share::ObLSFlag flag; + if (OB_FAIL(ls_op.get_ls_attr(task.get_src_ls_id(), true, trans, ls_info))) { + LOG_WARN("failed to get ls attr", KR(ret), K(task)); + if (OB_ENTRY_NOT_EXIST == ret) { + //while task in dropping status, ls may not exist + ret = OB_SUCCESS; + } + } else if (!ls_info.get_ls_flag().is_block_tablet_in()) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("ls must in block tablet in", KR(ret), K(ls_info)); + } else { + share::ObLSFlag new_flag = ls_info.get_ls_flag(); + new_flag.clear_block_tablet_in(); + if (OB_FAIL(ls_op.update_ls_flag_in_trans( + ls_info.get_ls_id(), ls_info.get_ls_flag(), new_flag, trans))) { + LOG_WARN("failed to update ls flag", KR(ret), K(ls_info)); + } + } + ISTAT("rollback flag of the ls", KR(ret), K(ls_info)); + } + ISTAT("cancel task", KR(ret), K(task), K(task_comment_)); + //clear other init task which parent_list not empty + if (OB_FAIL(ret)) { + } else if (skip_next_status) { + } else if (OB_FAIL(task_comment_.assign_fmt("Canceled on %s status", + task.get_task_status().to_str()))) { + LOG_WARN("failed to assign fmt", KR(ret), K(task)); + } else if (OB_FAIL(cancel_other_init_task_(task, trans))) { + LOG_WARN("failed to cancel other init task", KR(ret), K(task)); + } + } + return ret; +} +int ObBalanceTaskExecuteService::cancel_other_init_task_( + const share::ObBalanceTask &task, ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObBalanceTaskArray task_array; + int tmp_ret = OB_SUCCESS; + ObSqlString comment; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("task is invalid", KR(ret), K(task)); + } else if (OB_FAIL(ObBalanceTaskTableOperator::get_job_cannot_execute_task( + tenant_id_, task.get_job_id(), task_array, trans))) { + LOG_WARN("failed to get job init task", KR(ret), K(tenant_id_), K(task)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < task_array.count(); ++i) { + comment.reset(); + const ObBalanceTask &other_task = task_array.at(i); + if (!other_task.get_task_status().is_init()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task parent not empty, must be init", KR(ret), K(other_task)); + } else { + //set task status to failed + if (OB_FAIL(comment.assign_fmt("Canceled due to parent task %ld was canceled", + other_task.get_balance_task_id().id()))) { + LOG_WARN("failed to assign fmt", KR(tmp_ret), K(task), K(other_task)); + } else if (OB_FAIL(try_update_task_comment_(other_task, comment, trans))) { + LOG_WARN("failed to update task comment", KR(tmp_ret), KR(ret), K(task), K(comment)); + } else if (OB_FAIL(update_task_status_( + other_task, + share::ObBalanceJobStatus( + share::ObBalanceJobStatus::BALANCE_JOB_STATUS_CANCELING), + trans))) { + LOG_WARN("failed to update task status", KR(ret), K(other_task)); + } + } + ISTAT("cancel task", KR(ret), K(other_task), K(task_comment_)); + } + } + return ret; +} + +int ObBalanceTaskExecuteService::process_init_task_(const ObBalanceTask &task, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObLSAttrOperator ls_op(tenant_id_, sql_proxy_); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!task.is_valid() || !task.get_task_status().is_init())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("task is invalid", KR(ret), K(task)); + } else if (task.get_task_type().is_split_task()) { + //insert a ls attr + share::ObLSAttr ls_info; + share::ObLSFlag flag; + SCN create_scn; + if (OB_FAIL(ObLSAttrOperator::get_tenant_gts(tenant_id_, create_scn))) { + LOG_WARN("failed to get tenant gts", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(ls_info.init(task.get_dest_ls_id(), task.get_ls_group_id(), flag, + share::OB_LS_CREATING, share::OB_LS_OP_CREATE_PRE, create_scn))) { + LOG_WARN("failed to init new operation", KR(ret), K(create_scn), K(task)); + //TODO msy164651 + } else if (OB_FAIL(ls_op.insert_ls(ls_info, share::NORMAL_SWITCHOVER_STATUS, &trans))) { + LOG_WARN("failed to insert new operation", KR(ret), K(ls_info)); + } + ISTAT("create new ls", KR(ret), K(ls_info), K(task)); + } else if (task.get_task_type().is_alter_task()) { + share::ObLSAttr ls_info; + if (OB_FAIL(ls_op.get_ls_attr(task.get_src_ls_id(), true, trans, ls_info))) { + LOG_WARN("failed to get ls attr", KR(ret), K(task)); + } else if (ls_info.get_ls_group_id() == task.get_ls_group_id()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls group is is same, no need alter", KR(ret), K(ls_info), K(task)); + } else if (OB_FAIL(ls_op.alter_ls_group_in_trans(ls_info, + task.get_ls_group_id(), trans))) { + LOG_WARN("failed to alter ls group in trans", KR(ret), K(ls_info), K(task)); + } + ISTAT("alter ls group id", KR(ret), K(ls_info), K(task)); + } else if (task.get_task_type().is_merge_task()) { + share::ObLSAttr ls_info; + if (OB_FAIL(ls_op.get_ls_attr(task.get_src_ls_id(), true, trans, ls_info))) { + LOG_WARN("failed to get ls attr", KR(ret), K(task)); + } else if (ls_info.get_ls_flag().is_block_tablet_in()) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("ls already in block tablet in", KR(ret), K(ls_info)); + } else { + share::ObLSFlag new_flag = ls_info.get_ls_flag(); + new_flag.set_block_tablet_in(); + if (OB_FAIL(ls_op.update_ls_flag_in_trans( + ls_info.get_ls_id(), + ls_info.get_ls_flag(), + new_flag, + trans))) { + LOG_WARN("failed to update ls flag", KR(ret), K(ls_info)); + } + } + ISTAT("update ls flag", KR(ret), K(ls_info), K(task)); + } else if (task.get_task_type().is_transfer_task()) { + //nothing todo + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task type is invalid", KR(ret), K(task)); + } + return ret; +} + +int ObBalanceTaskExecuteService::wait_ls_to_target_status_(const ObLSID &ls_id, + const share::ObLSStatus ls_status, bool &skip_next_status) +{ + int ret = OB_SUCCESS; + skip_next_status = false; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("sql proxy is null", KR(ret)); + } else if (OB_UNLIKELY(!ls_id.is_valid() || share::ls_is_empty_status(ls_status))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_id), K(ls_status)); + } else { + ObLSStatusInfo status_info; + ObLSStatusOperator ls_status_op; + if (OB_FAIL(ls_status_op.get_ls_status_info(tenant_id_, ls_id, status_info, *sql_proxy_))) { + LOG_WARN("failed to get ls status info", KR(ret), K(tenant_id_), K(ls_id)); + } else if (ls_status == status_info.status_) { + //nothing + } else { + skip_next_status = true; + if (OB_FAIL(task_comment_.assign_fmt("Wait for status of LS %ld to change from %s to %s", + ls_id.id(), share::ls_status_to_str(status_info.status_), share::ls_status_to_str(ls_status)))) { + LOG_WARN("failed to assign fmt", KR(ret), K(ls_id), K(ls_status), K(status_info)); + } + WSTAT("need wait, ls not in target status", KR(ret), K(ls_status), K(status_info), K(task_comment_)); + } + } + return ret; +} + +int ObBalanceTaskExecuteService::wait_alter_ls_(const share::ObBalanceTask &task, bool &skip_next_status) +{ + int ret = OB_SUCCESS; + skip_next_status = false; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret)); + } else if (OB_UNLIKELY(!task.get_task_status().is_alter_ls())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(task)); + } else { + ObLSStatusInfo status_info; + ObLSStatusOperator ls_status_op; + if (OB_FAIL(ls_status_op.get_ls_status_info(tenant_id_, + task.get_src_ls_id(), status_info, *sql_proxy_))) { + LOG_WARN("failed to get ls status info", KR(ret), K(tenant_id_), K(task)); + } else if (status_info.ls_group_id_ == task.get_ls_group_id()) { + //nothing + } else { + skip_next_status = true; + if (OB_FAIL(task_comment_.assign_fmt("Wait for LS group id of LS %ld to change from %lu to %lu", + task.get_src_ls_id().id(), status_info.ls_group_id_, task.get_ls_group_id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(task), K(status_info)); + } + WSTAT("need wait, alter ls not ready", KR(ret), K(status_info), K(task), K(task_comment_)); + } + } + return ret; +} + +int ObBalanceTaskExecuteService::execute_transfer_in_trans_(const ObBalanceTask &task, + ObMySQLTransaction &trans, + bool &all_part_transferred) +{ + int ret = OB_SUCCESS; + ObTenantTransferService *transfer_service = MTL(ObTenantTransferService*); + const ObTransferTaskID cur_transfer_task_id = task.get_current_transfer_task_id(); + bool transfer_task_executing = false; + ObTransferPartList transfer_all_part_list; + ObTransferPartList transfer_finished_part_list; + ObTransferPartList to_do_part_list; + all_part_transferred = false; + + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!task.is_valid() || !task.get_task_status().is_transfer())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("task is invalid", KR(ret), K(task)); + } else if (OB_ISNULL(transfer_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer service is null", KR(ret)); + } else if (OB_FAIL(to_do_part_list.assign(task.get_part_list()))) { + LOG_WARN("assign failed", KR(ret), K(task)); + } else if (!cur_transfer_task_id.is_valid()) { + // No transfer task is executing + // NEED new task when transfer is finished + all_part_transferred = (task.get_part_list().count() == 0); + } else if (OB_FAIL(transfer_service->try_clear_transfer_task( + cur_transfer_task_id, + transfer_all_part_list, + transfer_finished_part_list))) { + if (OB_NEED_RETRY != ret) { + LOG_WARN("failed to clear transfer task", KR(ret), K(task)); + } else { + // Transfer task is still executing + all_part_transferred = false; + transfer_task_executing = true; + ret = OB_SUCCESS; + } + } + // Finish current Transfer Task of Balance Task + else if (OB_FAIL(ObBalanceTaskTableOperator::finish_transfer_task( + task, + cur_transfer_task_id, + transfer_finished_part_list, + trans, + to_do_part_list, + all_part_transferred))) { + LOG_WARN("failed to finish tranfer task", KR(ret), + K(task), K(cur_transfer_task_id), K(transfer_finished_part_list)); + } + + // if transfer is not finished and transfer task not executing, generate new task + if (OB_SUCC(ret) && !all_part_transferred && !transfer_task_executing) { + ObTransferTaskID transfer_id; + if (OB_FAIL(transfer_service->generate_transfer_task( + trans, + task.get_src_ls_id(), + task.get_dest_ls_id(), + to_do_part_list, + task.get_balance_task_id(), + transfer_id))) { + LOG_WARN("failed to generate task id", KR(ret), K(to_do_part_list), K(task)); + } else if (OB_FAIL(ObBalanceTaskTableOperator::start_transfer_task( + tenant_id_, + task.get_balance_task_id(), + transfer_id, + trans))) { + LOG_WARN("failed to generate new transfer task", KR(ret), K(tenant_id_), K(task), K(transfer_id)); + } else { + transfer_service->wakeup(); + } + ISTAT("generate new transfer task", KR(ret), K(transfer_id), K(to_do_part_list), K(task), K(task_comment_)); + } + + // double check for merge task to make sure that all partitions on src_ls have been transferred + // because some tables (e.g. hidden table) cannot be prevented from being created on the src ls when ls is merging + if (OB_SUCC(ret) && task.get_task_type().is_merge_task() && all_part_transferred) { + all_part_transferred = false; + if (OB_FAIL(get_and_update_merge_ls_part_list_(trans, task, all_part_transferred))) { + if (OB_NEED_RETRY == ret) { + all_part_transferred = false; + ISTAT("get and update merge ls part list failed because schema is old, need retry", + KR(ret), K(all_part_transferred)); + ret = OB_SUCCESS; + } else { + LOG_WARN("double check all part transferred failed", KR(ret), K(all_part_transferred)); + } + } + } + + return ret; +} + + +int ObBalanceTaskExecuteService::set_ls_to_merge_(const share::ObBalanceTask &task, ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + bool all_part_transferred = false; + if (OB_UNLIKELY(!task.get_task_status().is_set_merge_ls())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(task)); + } else if (OB_FAIL(get_and_update_merge_ls_part_list_(trans, task, all_part_transferred))) { + LOG_WARN("get and update merge ls part list failed", KR(ret), K(task), K(all_part_transferred)); + } + return ret; +} + +int ObBalanceTaskExecuteService::get_and_update_merge_ls_part_list_( + ObMySQLTransaction &trans, + const share::ObBalanceTask &task, + bool &all_part_transferred) +{ + int ret = OB_SUCCESS; + int64_t start_time = ObTimeUtility::current_time(); + share::ObTransferPartList part_list; + const ObLSID &src_ls = task.get_src_ls_id(); + schema::ObMultiVersionSchemaService *schemaS = GCTX.schema_service_; + + all_part_transferred = false; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(schemaS) || OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected", KR(ret), K(sql_proxy_), KP(GCTX.schema_service_)); + } else if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(task)); + } + // build all part on src LS + else if (OB_FAIL(ObLSAllPartBuilder::build(tenant_id_, src_ls, *schemaS, *sql_proxy_, part_list))) { + // need retry, it is normal + if (OB_NEED_RETRY == ret) { + LOG_WARN("build all part of src LS fail, need retry", KR(ret), K(src_ls), K(tenant_id_), K(task)); + } else { + LOG_WARN("build all part of src LS fail", KR(ret), K(src_ls), K(tenant_id_), K(task)); + } + } else if (0 == part_list.count()) { + all_part_transferred = true; + ISTAT("there is no partition on src ls, no need update part list", K(task), + K(all_part_transferred), K(part_list)); + } else if (OB_FAIL(ObBalanceTaskTableOperator::update_merge_ls_part_list( + tenant_id_, + task.get_balance_task_id(), + part_list, + trans))) { + LOG_WARN("failed to update merge ls part list", KR(ret), K(tenant_id_), K(task), K(part_list)); + } + int64_t finish_time = ObTimeUtility::current_time(); + + ISTAT("build all part list for src LS of merge task and update finish", KR(ret), + "cost", finish_time - start_time, + K_(tenant_id), K(src_ls), + K(all_part_transferred), + "part_list_count", part_list.count(), + K(task)); + return ret; +} + +int ObBalanceTaskExecuteService::set_ls_to_dropping_(const ObLSID &ls_id, ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObLSAttrOperator ls_op(tenant_id_, sql_proxy_); + //TODO exclusion lock of ls + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("task is invalid", KR(ret), K(ls_id)); + } else if (OB_FAIL(ls_op.update_ls_status_in_trans(ls_id, share::OB_LS_NORMAL, + share::OB_LS_DROPPING, + share::NORMAL_SWITCHOVER_STATUS, + trans))) { + LOG_WARN("failed to update ls status", KR(ret), K(ls_id)); + } + return ret; +} + +} +} diff --git a/src/rootserver/ob_balance_task_execute_service.h b/src/rootserver/ob_balance_task_execute_service.h new file mode 100644 index 000000000..18dc9faba --- /dev/null +++ b/src/rootserver/ob_balance_task_execute_service.h @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_BALANCE_TASK_EXECUTE_H +#define OCEANBASE_ROOTSERVER_OB_BALANCE_TASK_EXECUTE_H +#include "lib/thread/ob_reentrant_thread.h"//ObRsReentrantThread +#include "lib/thread/thread_mgr_interface.h" // TGRunnable +#include "lib/lock/ob_thread_cond.h"//ObThreadCond +#include "rootserver/ob_tenant_thread_helper.h"//ObTenantTheadHelper +#include "share/balance/ob_balance_task_table_operator.h"//ObBalanceTask +#include "share/ob_thread_mgr.h" //OBTGDefIDEnum +#include "share/ob_balance_define.h" // ObBalanceJobID, ObBalanceTaskID +#include "share/ls/ob_ls_i_life_manager.h"//ObLSStatus + +namespace oceanbase +{ + +namespace common +{ +class ObMySQLProxy; +class ObMySQLTransaction; +class ObTabletID; +class ObISQLClient; +} +namespace share +{ +class ObBalanceJob; +namespace schema +{ +class ObSchemaGetterGuard; +} +} +namespace rootserver +{ + +/*description: + * only one thread in threadpool + * the service process expand, shrink and partition balance + */ +class ObBalanceTaskExecuteService : public ObTenantThreadHelper, + public logservice::ObICheckpointSubHandler, + public logservice::ObIReplaySubHandler +{ +public: + ObBalanceTaskExecuteService():inited_(false), tenant_id_(OB_INVALID_TENANT_ID), + sql_proxy_(NULL), task_array_(), task_comment_(){} + virtual ~ObBalanceTaskExecuteService() {} + int init(); + void destroy(); + virtual void do_work() override; + DEFINE_MTL_FUNC(ObBalanceTaskExecuteService) + +public: + virtual share::SCN get_rec_scn() override { return share::SCN::max_scn();} + virtual int flush(share::SCN &) override { return OB_SUCCESS; } + int replay(const void *buffer, const int64_t nbytes, const palf::LSN &lsn, const share::SCN &) override + { + UNUSED(buffer); + UNUSED(nbytes); + UNUSED(lsn); + return OB_SUCCESS; + } +private: + int load_all_balance_task_(); + int execute_task_(); + int get_balance_job_task_for_update_(const share::ObBalanceTask &task, + share::ObBalanceJob &job, share::ObBalanceTask &task_in_trans, + ObMySQLTransaction &trans); + int finish_task_( + const share::ObBalanceTask &task, + const share::ObBalanceTaskStatus finish_task_status, + ObMySQLTransaction &trans); + int update_task_status_(const share::ObBalanceTask &task, + const share::ObBalanceJobStatus &job_status, + ObMySQLTransaction &trans); + int process_current_task_status_(const share::ObBalanceTask &task, ObMySQLTransaction &trans, + bool &skip_next_status); + int cancel_current_task_status_(const share::ObBalanceTask &task, ObMySQLTransaction &trans, bool &skip_next_status); + int cancel_other_init_task_(const share::ObBalanceTask &task, ObMySQLTransaction &trans); + int process_init_task_(const share::ObBalanceTask &task, ObMySQLTransaction &trans); + int wait_ls_to_target_status_(const share::ObLSID &ls_id, const share::ObLSStatus ls_status, bool &skip_next_status); + int wait_alter_ls_(const share::ObBalanceTask &task, bool &skip_next_status); + int set_ls_to_merge_(const share::ObBalanceTask &task, ObMySQLTransaction &trans); + int set_ls_to_dropping_(const share::ObLSID &ls_id, ObMySQLTransaction &trans); + int execute_transfer_in_trans_(const share::ObBalanceTask &task, + ObMySQLTransaction &trans, + bool &all_part_transferred); + int get_and_update_merge_ls_part_list_( + ObMySQLTransaction &trans, + const share::ObBalanceTask &task, + bool &all_part_transferred); + int wait_tenant_ready_(); + int try_update_task_comment_(const share::ObBalanceTask &task, + const common::ObSqlString &comment, ObISQLClient &sql_client); +private: + bool inited_; + uint64_t tenant_id_; + common::ObMySQLProxy *sql_proxy_; + ObArray task_array_; + ObSqlString task_comment_; +}; +} +} + + +#endif /* !OCEANBASE_ROOTSERVER_OB_BALANCE_TASK_EXECUTE_H */ diff --git a/src/rootserver/ob_bootstrap.cpp b/src/rootserver/ob_bootstrap.cpp index 81ce855ae..a6912e2d7 100644 --- a/src/rootserver/ob_bootstrap.cpp +++ b/src/rootserver/ob_bootstrap.cpp @@ -40,7 +40,6 @@ #include "share/ob_schema_status_proxy.h" #include "share/ob_ls_id.h" #include "share/ls/ob_ls_table_operator.h" -#include "share/backup/ob_backup_operator.h" #include "storage/ob_file_system_router.h" #include "share/ls/ob_ls_creator.h"//ObLSCreator #include "share/ls/ob_ls_life_manager.h"//ObLSLifeAgentManager @@ -559,14 +558,11 @@ int ObBootstrap::execute_bootstrap(rootserver::ObServerZoneOpService &server_zon } } BOOTSTRAP_CHECK_SUCCESS_V2("refresh_schema"); + if (FAILEDx(add_servers_in_rs_list(server_zone_op_service))) { LOG_WARN("fail to add servers in rs_list_", KR(ret)); } else if (OB_FAIL(wait_all_rs_in_service())) { LOG_WARN("failed to wait all rs in service", KR(ret)); - } else if (OB_FAIL(init_backup_inner_table())) { - LOG_WARN("failed to init backup inner table", KR(ret)); - } else if (OB_FAIL(init_backup_data())) { - LOG_WARN("failed to init backup inner table version", KR(ret)); } else { ROOTSERVICE_EVENT_ADD("bootstrap", "bootstrap_succeed"); } @@ -1411,46 +1407,6 @@ int ObBootstrap::init_system_data() return ret; } -int ObBootstrap::init_backup_inner_table() -{ - int ret = OB_SUCCESS; - - if (OB_FAIL(check_inner_stat())) { - LOG_WARN("fail to check inner stat", K(ret)); - } else if (OB_FAIL(ObBackupInfoOperator::set_inner_table_version( - ddl_service_.get_sql_proxy(), OB_BACKUP_INNER_TABLE_V3))) { - LOG_WARN("failed to init backup inner table version", K(ret)); - } else if (OB_FAIL(ObBackupInfoOperator::set_max_piece_id( - ddl_service_.get_sql_proxy(), 0))) { - LOG_WARN("failed to init max piece id", K(ret)); - } else if (OB_FAIL(ObBackupInfoOperator::set_max_piece_create_date( - ddl_service_.get_sql_proxy(), 0))) { - LOG_WARN("failed to init set_max_piece_create_date", K(ret)); - } - - return ret; -} - -int ObBootstrap::init_backup_data() -{ - int ret = OB_SUCCESS; - - if (OB_FAIL(check_inner_stat())) { - LOG_WARN("fail to check inner stat", K(ret)); - } else if (OB_FAIL(ObBackupInfoOperator::set_inner_table_version( - ddl_service_.get_sql_proxy(), OB_BACKUP_INNER_TABLE_V3))) { - LOG_WARN("failed to init backup inner table version", K(ret)); - } else if (OB_FAIL(ObBackupInfoOperator::set_backup_leader_epoch(ddl_service_.get_sql_proxy(), 1))) { - LOG_WARN("failed to init backup leader epoch", K(ret)); - // mark - } else if (OB_FAIL(ObBackupInfoOperator::set_backup_leader(ddl_service_.get_sql_proxy(), GCTX.self_addr()))) { - // - LOG_WARN("failed to init backup leader", K(ret)); - } - - return ret; -} - int ObBootstrap::init_sys_unit_config(share::ObUnitConfig &unit_config) { int ret = OB_SUCCESS; @@ -1506,6 +1462,7 @@ int ObBootstrap::create_sys_resource_pool() share::ObResourcePool pool; bool is_bootstrap = true; const bool if_not_exist = false; + common::ObMySQLTransaction trans; common::ObArray new_ug_id_array; if (OB_FAIL(check_inner_stat())) { LOG_WARN("check_inner_stat failed", K(ret)); @@ -1521,18 +1478,25 @@ int ObBootstrap::create_sys_resource_pool() LOG_WARN("create_sys_units failed", K(sys_units), K(ret)); } else if (OB_FAIL(pool_names.push_back(pool.name_))) { LOG_WARN("push_back failed", K(ret)); + } else if (OB_FAIL(trans.start(&unit_mgr_.get_sql_proxy(), OB_SYS_TENANT_ID))) { + LOG_WARN("start transaction failed", KR(ret)); } else if (OB_FAIL(unit_mgr_.grant_pools( - ddl_service_.get_sql_proxy(), new_ug_id_array, + trans, new_ug_id_array, lib::Worker::CompatMode::MYSQL, pool_names, OB_SYS_TENANT_ID, is_bootstrap))) { LOG_WARN("grant_pools_to_tenant failed", K(pool_names), "tenant_id", static_cast(OB_SYS_TENANT_ID), K(ret)); } else { - const bool grant = true; - if (OB_FAIL(unit_mgr_.commit_change_pool_owner( - new_ug_id_array, grant, pool_names, OB_SYS_TENANT_ID))) { - LOG_WARN("commit_change_pool_owner failed", K(grant), K(pool_names), - "tenant_id", static_cast(OB_SYS_TENANT_ID), K(ret)); + if (OB_FAIL(unit_mgr_.load())) { + LOG_WARN("unit_manager reload failed", K(ret)); + } + } + if (trans.is_started()) { + const bool commit = (OB_SUCC(ret)); + int temp_ret = OB_SUCCESS; + if (OB_SUCCESS != (temp_ret = trans.end(commit))) { + LOG_WARN("trans end failed", K(commit), K(temp_ret)); + ret = (OB_SUCCESS == ret) ? temp_ret : ret; } } BOOTSTRAP_CHECK_SUCCESS(); diff --git a/src/rootserver/ob_bootstrap.h b/src/rootserver/ob_bootstrap.h index 595f5829a..eb1f79b15 100644 --- a/src/rootserver/ob_bootstrap.h +++ b/src/rootserver/ob_bootstrap.h @@ -177,8 +177,6 @@ private: virtual int init_multiple_zone_deployment_table(common::ObISQLClient &sql_client); virtual int add_servers_in_rs_list(rootserver::ObServerZoneOpService &server_zone_op_service); virtual int wait_all_rs_in_service(); - int init_backup_inner_table(); - int init_backup_data(); template int set_replica_options(SCHEMA &schema); int build_zone_region_list( diff --git a/src/rootserver/ob_common_ls_service.cpp b/src/rootserver/ob_common_ls_service.cpp new file mode 100755 index 000000000..9b82728a9 --- /dev/null +++ b/src/rootserver/ob_common_ls_service.cpp @@ -0,0 +1,244 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX RS +#include "ob_common_ls_service.h" +#include "ob_ls_service_helper.h" +#include "ob_balance_ls_primary_zone.h" +#include "lib/profile/ob_trace_id.h" +#include "share/ob_errno.h" +#include "share/ob_max_id_fetcher.h" +#include "share/schema/ob_schema_struct.h"//ObTenantInfo +#include "share/ls/ob_ls_creator.h" //ObLSCreator +#include "share/ls/ob_ls_life_manager.h"//ObLSLifeAgentManager +#include "share/ob_primary_zone_util.h"//ObPrimaryZoneUtil +#include "share/ob_share_util.h"//ObShareUtil +#include "share/ob_tenant_info_proxy.h"//ObAllTenantInfo +#include "share/ob_common_rpc_proxy.h"//common_rpc_proxy +#include "observer/ob_server_struct.h"//GCTX +#include "logservice/palf/palf_base_info.h"//PalfBaseInfo + +namespace oceanbase +{ +using namespace common; +using namespace share; +using namespace transaction; +using namespace palf; +namespace rootserver +{ +//////////////ObCommonLSService +int ObCommonLSService::init() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("has inited", KR(ret)); + } else if (OB_FAIL(ObTenantThreadHelper::create("COMMONLSSe", + lib::TGDefIDs::SimpleLSService, *this))) { + LOG_WARN("failed to create thread", KR(ret)); + } else if (OB_FAIL(ObTenantThreadHelper::start())) { + LOG_WARN("fail to start", KR(ret)); + } else { + tenant_id_ = MTL_ID(); + inited_ = true; + } + return ret; +} + +void ObCommonLSService::destroy() +{ + ObTenantThreadHelper::destroy(); + tenant_id_ = OB_INVALID_TENANT_ID; + inited_ = false; +} + +void ObCommonLSService::do_work() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (is_user_tenant(tenant_id_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("is user tenant", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(wait_tenant_schema_and_version_ready_(tenant_id_, DATA_VERSION_4_1_0_0))) { + LOG_WARN("failed to wait tenant schema version ready", KR(ret), K(tenant_id_), K(DATA_CURRENT_VERSION)); + } else { + int64_t idle_time_us = 1000 * 1000L;//1s + share::schema::ObTenantSchema user_tenant_schema; + int tmp_ret = OB_SUCCESS; + while (!has_set_stop()) { + ret = OB_SUCCESS; + ObCurTraceId::init(GCONF.self_addr_); + if (is_meta_tenant(tenant_id_)) { + const uint64_t user_tenant_id = gen_user_tenant_id(tenant_id_); + if (OB_FAIL(check_can_do_recovery_(user_tenant_id))) { + LOG_WARN("can not do recovery now", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(get_tenant_schema(user_tenant_id, user_tenant_schema))) { + LOG_WARN("failed to get user tenant schema", KR(ret), K(user_tenant_id)); + } else if (user_tenant_schema.is_dropping()) { + if (OB_TMP_FAIL(try_force_drop_tenant_(user_tenant_schema))) { + LOG_WARN("failed to force drop tenant", KR(ret), KR(tmp_ret), K(user_tenant_id)); + } + } else if (OB_TMP_FAIL(try_create_ls_(user_tenant_schema))) { + LOG_WARN("failed to create ls", KR(ret), KR(tmp_ret), K(user_tenant_schema)); + } + } + + if (OB_TMP_FAIL(ObBalanceLSPrimaryZone::try_update_sys_ls_primary_zone(tenant_id_))) { + LOG_WARN("failed to update sys ls primary zone", KR(ret), KR(tmp_ret), K(tenant_id_)); + } + + user_tenant_schema.reset(); + LOG_INFO("[COMMON_LS_SERVICE] finish one round", KR(ret), KR(tmp_ret), K(idle_time_us)); + idle(idle_time_us); + } // end while + } +} + + +int ObCommonLSService::try_create_ls_(const share::schema::ObTenantSchema &tenant_schema) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = tenant_schema.get_tenant_id(); + if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(GCTX.sql_proxy_)); + } else if (!is_user_tenant(tenant_id) || !tenant_schema.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant is invalid", KR(ret), K(tenant_id), K(tenant_schema)); + } else { + share::ObLSStatusInfoArray status_info_array; + share::ObLSStatusOperator ls_op; + ObLSRecoveryStat recovery_stat; + ObLSRecoveryStatOperator ls_recovery_operator; + palf::PalfBaseInfo palf_base_info; + int tmp_ret = OB_SUCCESS; + if (OB_FAIL(ls_op.get_all_ls_status_by_order( + tenant_id, status_info_array, *GCTX.sql_proxy_))) { + LOG_WARN("failed to get all ls status", KR(ret), K(tenant_id)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < status_info_array.count(); ++i) { + const ObLSStatusInfo &status_info = status_info_array.at(i); + if (status_info.ls_is_creating()) { + recovery_stat.reset(); + if (OB_FAIL(ls_recovery_operator.get_ls_recovery_stat( + tenant_id, status_info.ls_id_, false /*for_update*/, + recovery_stat, *GCTX.sql_proxy_))) { + LOG_WARN("failed to get ls recovery stat", KR(ret), K(tenant_id), + K(status_info)); + } else if (OB_FAIL(do_create_user_ls(tenant_schema, status_info, + recovery_stat.get_create_scn(), + false, palf_base_info))) { + LOG_WARN("failed to create new ls", KR(ret), K(status_info), + K(recovery_stat)); + } + } + } // end for + } + return ret; +} +int ObCommonLSService::do_create_user_ls( + const share::schema::ObTenantSchema &tenant_schema, + const share::ObLSStatusInfo &info, const SCN &create_scn, + bool create_with_palf, const palf::PalfBaseInfo &palf_base_info) +{ + int ret = OB_SUCCESS; + LOG_INFO("[COMMON_LS_SERVICE] start to create ls", K(info), K(create_scn)); + const int64_t start_time = ObTimeUtility::fast_current_time(); + if (OB_UNLIKELY(!info.is_valid() || !info.ls_is_creating())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("info not valid", KR(ret), K(info)); + } else { + CK(OB_NOT_NULL(GCTX.sql_proxy_), OB_NOT_NULL(GCTX.srv_rpc_proxy_)) + common::ObArray locality_array; + int64_t paxos_replica_num = 0; + ObSchemaGetterGuard guard;//nothing + if (FAILEDx(tenant_schema.get_zone_replica_attr_array( + locality_array))) { + LOG_WARN("failed to get zone locality array", KR(ret)); + } else if (OB_FAIL(tenant_schema.get_paxos_replica_num( + guard, paxos_replica_num))) { + LOG_WARN("failed to get paxos replica num", KR(ret)); + } else { + ObLSCreator creator(*GCTX.srv_rpc_proxy_, info.tenant_id_, + info.ls_id_, GCTX.sql_proxy_); + if (OB_FAIL(creator.create_user_ls(info, paxos_replica_num, + locality_array, create_scn, + tenant_schema.get_compatibility_mode(), + create_with_palf, + palf_base_info))) { + LOG_WARN("failed to create user ls", KR(ret), K(info), K(locality_array), K(create_scn), + K(palf_base_info), K(create_with_palf)); + } + } + } + const int64_t cost = ObTimeUtility::fast_current_time() - start_time; + LOG_INFO("[COMMON_LS_SERVICE] end to create ls", KR(ret), K(info), K(cost)); + return ret; +} + +int ObCommonLSService::try_force_drop_tenant_( + const share::schema::ObTenantSchema &tenant_schema) +{ + int ret = OB_SUCCESS; + ObTimeoutCtx ctx; + const uint64_t tenant_id = tenant_schema.get_tenant_id(); + + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(GCTX.sql_proxy_) + || OB_ISNULL(GCTX.rs_rpc_proxy_) + || OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_), KP(GCTX.rs_rpc_proxy_), + KP(GCTX.schema_service_)); + } else if (!is_user_tenant(tenant_id) || !tenant_schema.is_valid() + || !tenant_schema.is_dropping()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant is invalid", KR(ret), K(tenant_id), K(tenant_schema)); + } else { + ObLSStatusOperator op; + share::ObLSStatusInfoArray ls_array; + const int64_t start_time = ObTimeUtility::fast_current_time(); + if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, GCONF.internal_sql_execute_timeout))) { + LOG_WARN("fail to set timeout ctx", KR(ret), K(tenant_id)); + } else if (OB_FAIL(op.get_all_ls_status_by_order(tenant_id, ls_array, *GCTX.sql_proxy_))) { + LOG_WARN("fail to get all ls status", KR(ret), K(tenant_id)); + } else if (ls_array.count() <= 0) { + obrpc::ObDropTenantArg arg; + arg.exec_tenant_id_ = OB_SYS_TENANT_ID; + arg.tenant_name_ = tenant_schema.get_tenant_name(); + arg.tenant_id_ = tenant_schema.get_tenant_id(); + arg.if_exist_ = true; + arg.delay_to_drop_ = false; + ObSqlString sql; + const int64_t timeout_ts = ctx.get_timeout(); + if (OB_FAIL(sql.append_fmt("DROP TENANT IF EXISTS %s FORCE", arg.tenant_name_.ptr()))) { + LOG_WARN("fail to generate sql", KR(ret), K(arg)); + } else if (FALSE_IT(arg.ddl_stmt_str_ = sql.string())) { + } else if (OB_FAIL(GCTX.rs_rpc_proxy_->timeout(timeout_ts).drop_tenant(arg))) { + LOG_WARN("fail to drop tenant", KR(ret), K(arg), K(timeout_ts)); + } + } else { + // tenant's logstream is still dropping, check next round + } + const int64_t cost = ObTimeUtility::fast_current_time() - start_time; + LOG_INFO("finish try drop tenant", KR(ret), K(tenant_id), K(ls_array), + "timeout", ctx.get_timeout(), K(cost)); + } + return ret; +} + +}//end of rootserver +} diff --git a/src/rootserver/ob_common_ls_service.h b/src/rootserver/ob_common_ls_service.h new file mode 100644 index 000000000..249baa228 --- /dev/null +++ b/src/rootserver/ob_common_ls_service.h @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_COMMON_LS_SERVICE_H +#define OCEANBASE_ROOTSERVER_OB_COMMON_LS_SERVICE_H +#include "lib/thread/ob_reentrant_thread.h"//ObRsReentrantThread +#include "logservice/ob_log_base_type.h" +#include "share/scn.h"//SCN +#include "share/ls/ob_ls_status_operator.h"//ObLSStatusOperator +#include "share/ls/ob_ls_operator.h" //ObLSAttr +#include "share/ob_thread_mgr.h" //OBTGDefIDEnum +#include "logservice/palf/palf_iterator.h" //PalfBufferIterator +#include "share/unit/ob_unit_info.h"//ObUnit::Status +#include "lib/thread/thread_mgr_interface.h" // TGRunnable +#include "lib/lock/ob_thread_cond.h"//ObThreadCond +#include "rootserver/ob_tenant_thread_helper.h"//ObTenantThreadHelper + + +namespace oceanbase +{ +namespace obrpc +{ +class ObSrvRpcProxy; +} +namespace common +{ +class ObMySQLProxy; +class ObMySQLTransaction; +} +namespace share +{ +namespace schema +{ +class ObMultiVersionSchemaService; +class ObTenantSchema; +} + +} +namespace palf +{ +struct PalfBaseInfo; +} +namespace rootserver +{ +/*description: + *COMMON_LS_SERVICE thread: Started on the leader of the meta tenant sys ls + * 1. adjust sys ls primary zone of meta and user tenant + * 2. adjust user ls primary zone + * 3. make ls status from creating to created of __all_ls_status + * 4. check dropping tenant need drop tenant force; + * */ +class ObCommonLSService : public ObTenantThreadHelper, + public logservice::ObICheckpointSubHandler, + public logservice::ObIReplaySubHandler +{ +public: + ObCommonLSService():inited_(false), tenant_id_(OB_INVALID_TENANT_ID) {} + virtual ~ObCommonLSService() {} + int init(); + void destroy(); + virtual void do_work() override; + DEFINE_MTL_FUNC(ObCommonLSService) + +public: + virtual share::SCN get_rec_scn() override { return share::SCN::max_scn();} + virtual int flush(share::SCN &scn) override { return OB_SUCCESS; } + int replay(const void *buffer, const int64_t nbytes, const palf::LSN &lsn, const share::SCN &scn) override + { + UNUSED(buffer); + UNUSED(nbytes); + UNUSED(lsn); + UNUSED(scn); + return OB_SUCCESS; + } + +private: + // force drop user tenant if tenant is in dropping status + int try_force_drop_tenant_( + const share::schema::ObTenantSchema &tenant_schema); + int try_create_ls_(const share::schema::ObTenantSchema &tenant_schema); +public: + //restore_service need create init ls too + static int do_create_user_ls(const share::schema::ObTenantSchema &tenant_schema, + const share::ObLSStatusInfo &info, + const SCN &create_scn, + bool create_with_palf, + const palf::PalfBaseInfo &palf_base_info); + static int update_tenant_info(const uint64_t tenant_id, + const share::ObTenantSwitchoverStatus &staus, + ObMySQLProxy *proxy); +private: + bool inited_; + uint64_t tenant_id_; + +}; +} +} + + +#endif /* !OCEANBASE_ROOTSERVER_OB_COMMON_LS_SERVICE_H */ diff --git a/src/rootserver/ob_ddl_help.cpp b/src/rootserver/ob_ddl_help.cpp index 932121557..d19c1099c 100644 --- a/src/rootserver/ob_ddl_help.cpp +++ b/src/rootserver/ob_ddl_help.cpp @@ -10,6 +10,7 @@ * See the Mulan PubL v2 for more details. */ +#include "lib/ob_errno.h" #define USING_LOG_PREFIX RS #include "rootserver/ob_ddl_help.h" #include "rootserver/ob_ddl_operator.h" @@ -21,6 +22,7 @@ #include "share/ob_rpc_struct.h" #include "lib/string/ob_sql_string.h" #include "sql/resolver/ob_resolver_utils.h" +#include "share/schema/ob_schema_service_sql_impl.h" namespace oceanbase { using namespace common; @@ -47,21 +49,30 @@ int ObTableGroupHelp::add_tables_to_tablegroup(ObMySQLTransaction &trans, const uint64_t tablegroup_id = tablegroup_schema.get_tablegroup_id(); if (OB_UNLIKELY(!trans.is_started()) || OB_UNLIKELY(!arg.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(arg)); + LOG_WARN("invalid argument", KR(ret), K(arg)); } else if (table_items.count() <= 0) { //nothing todo - } else if (OB_INVALID_ID == tablegroup_id || is_sys_tablegroup_id(tablegroup_id)) { + } else if (OB_INVALID_ID == tablegroup_id) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("tablegroup_id is invalid", K(ret), K(tablegroup_id)); + LOG_WARN("tablegroup_id is invalid", KR(ret), K(tablegroup_id)); + } else if (is_sys_tablegroup_id(tablegroup_id)) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("can not handle with sys tablegroup", KR(ret), K(tablegroup_id)); } else if (OB_ISNULL(ddl_service_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("ddl_service is null", K(ret)); + LOG_WARN("ddl_service is null", KR(ret)); } else { ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_); const bool is_index = false; const uint64_t tenant_id = arg.tenant_id_; ObString tablegroup_name = tablegroup_schema.get_tablegroup_name(); - for (int64_t i = 0; OB_SUCC(ret) && i < table_items.count(); ++i) { + // first table is used for tablegroup is empty, but add list's num more than one to compare partition + const ObTableSchema *first_table_schema = NULL; + int64_t table_items_count = table_items.count(); + ObArray table_ids; + bool duplicate_table = false; + for (int64_t i = 0; OB_SUCC(ret) && i < table_items_count; ++i) { + duplicate_table = false; const ObTableItem &table_item = table_items.at(i); const ObTableSchema *table_schema = NULL; uint64_t database_id = common::OB_INVALID_ID; @@ -72,27 +83,34 @@ int ObTableGroupHelp::add_tables_to_tablegroup(ObMySQLTransaction &trans, K(tenant_id), K(table_item)); } else if (OB_FAIL(schema_guard.get_table_schema( tenant_id, database_id, table_item.table_name_, is_index, table_schema))) { - LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(database_id), K(table_item)); + LOG_WARN("fail to get table schema", KR(ret), K(tenant_id), K(database_id), K(table_item)); } else if (OB_ISNULL(table_schema)) { ret = OB_TABLE_NOT_EXIST; LOG_USER_ERROR(OB_TABLE_NOT_EXIST, to_cstring(table_item.database_name_), to_cstring(table_item.table_name_)); - LOG_WARN("table not exist!", K(tenant_id), K(database_id), K(table_item), K(ret)); + LOG_WARN("table not exist!", KR(ret), K(tenant_id), K(database_id), K(table_item)); } else if (is_inner_table(table_schema->get_table_id())) { //the tablegroup of sys table must be oceanbase ret = OB_OP_NOT_ALLOW; LOG_WARN("sys table's tablegroup should be oceanbase", KR(ret), K(arg), KPC(table_schema)); LOG_USER_ERROR(OB_OP_NOT_ALLOW, "set the tablegroup of system table besides oceanbase"); } else { + if (is_contain(table_ids, table_schema->get_table_id())) { + duplicate_table = true; + } else if (OB_FAIL(table_ids.push_back(table_schema->get_table_id()))) { + LOG_WARN("fail to push back table", KR(ret)); + } + } + if (OB_SUCC(ret) && !duplicate_table) { ObTableSchema new_table_schema; ObSqlString sql; if (OB_FAIL(new_table_schema.assign(*table_schema))) { - LOG_WARN("fail to assign schema", K(ret)); + LOG_WARN("fail to assign schema", KR(ret)); } else { new_table_schema.set_tablegroup_id(tablegroup_id); } if (OB_FAIL(ret)) { - } else if (OB_FAIL(check_table_alter_tablegroup(schema_guard, *table_schema, new_table_schema))) { - LOG_WARN("fail to check primary zone and locality", K(ret)); + } else if (OB_FAIL(check_table_alter_tablegroup(schema_guard, first_table_schema, *table_schema, new_table_schema))) { + LOG_WARN("fail to check primary zone and locality", KR(ret)); } else if (OB_FAIL(sql.append_fmt("ALTER TABLEGROUP %.*s ADD TABLE %.*s.%.*s", tablegroup_name.length(), tablegroup_name.ptr(), @@ -100,13 +118,15 @@ int ObTableGroupHelp::add_tables_to_tablegroup(ObMySQLTransaction &trans, table_item.database_name_.ptr(), table_item.table_name_.length(), table_item.table_name_.ptr()))) { - LOG_WARN("failed to append sql", K(ret)); + LOG_WARN("failed to append sql", KR(ret)); } else if (OB_FAIL(ddl_service_->check_tablegroup_in_single_database(schema_guard, new_table_schema))) { - LOG_WARN("fail to check tablegroup in single database", K(ret)); + LOG_WARN("fail to check tablegroup in single database", KR(ret)); } else { ObString sql_str = sql.string(); if (OB_FAIL(ddl_operator.alter_tablegroup(schema_guard, new_table_schema, trans, &sql_str))) { - LOG_WARN("ddl operator alter tablegroup failed", K(ret), K(tenant_id), K(tablegroup_id)); + LOG_WARN("ddl operator alter tablegroup failed", KR(ret), K(tenant_id), K(tablegroup_id)); + } else if (table_items_count >= 2 && i == 0) { + first_table_schema = table_schema; } } } // no more @@ -122,6 +142,7 @@ int ObTableGroupHelp::add_tables_to_tablegroup(ObMySQLTransaction &trans, */ int ObTableGroupHelp::check_table_alter_tablegroup( share::schema::ObSchemaGetterGuard &schema_guard, + const share::schema::ObTableSchema *first_table_schema, const share::schema::ObTableSchema &orig_table_schema, share::schema::ObTableSchema &new_table_schema) { @@ -130,16 +151,15 @@ int ObTableGroupHelp::check_table_alter_tablegroup( ObString src_previous_locality_str; ObString dst_previous_locality_str; if (!can_alter_tablegroup) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("cann't alter table's tablegroup", K(ret), + ret = OB_OP_NOT_ALLOW; + LOG_WARN("cann't alter table's tablegroup", KR(ret), "src_tg_id", orig_table_schema.get_tablegroup_id(), "dst_tg_id", new_table_schema.get_tablegroup_id()); } else if (OB_INVALID_ID == new_table_schema.get_tablegroup_id()) { // skip } else { - // Handling the source is a tablegroup created after 2.0 - if (OB_FAIL(check_partition_option_for_create_table(schema_guard, new_table_schema))) { - LOG_WARN("fail to check tablegroup partition", K(ret), K(new_table_schema)); + if (OB_FAIL(check_table_partition_in_tablegroup(first_table_schema, new_table_schema, schema_guard))) { + LOG_WARN("fail to check table partition in tablegroup", KR(ret), K(new_table_schema)); } } if (OB_SUCC(ret)) { @@ -151,25 +171,25 @@ int ObTableGroupHelp::check_table_alter_tablegroup( if (OB_INVALID_ID == orig_tg_id) { // Did not belong to any tablegroup } else if (OB_FAIL(schema_guard.get_tablegroup_schema(tenant_id, orig_tg_id, orig_tg))) { - LOG_WARN("fail to get tablegroup schema", K(ret), K(tenant_id), K(orig_tg_id)); + LOG_WARN("fail to get tablegroup schema", KR(ret), K(tenant_id), K(orig_tg_id)); } else if (OB_UNLIKELY(nullptr == orig_tg)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("orig tg ptr is null", K(ret), K(orig_tg_id)); + LOG_WARN("orig tg ptr is null", KR(ret), K(orig_tg_id)); } if (OB_FAIL(ret)) { } else if (OB_INVALID_ID == new_tg_id) { // Did not belong to any tablegroup } else if (OB_FAIL(schema_guard.get_tablegroup_schema(tenant_id, new_tg_id, new_tg))) { - LOG_WARN("fail to get tablegroup schema", K(ret), K(tenant_id), K(new_tg_id)); + LOG_WARN("fail to get tablegroup schema", KR(ret), K(tenant_id), K(new_tg_id)); } else if (OB_UNLIKELY(nullptr == new_tg)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("orig tg ptr is null", K(ret), K(new_tg_id)); + LOG_WARN("orig tg ptr is null", KR(ret), K(new_tg_id)); } if (OB_SUCC(ret)) { if (ObDuplicateScope::DUPLICATE_SCOPE_NONE != new_table_schema.get_duplicate_scope() && OB_INVALID_ID != new_table_schema.get_tablegroup_id()) { ret = OB_NOT_SUPPORTED; - LOG_WARN("duplicate table in tablegroup is not supported", K(ret), + LOG_WARN("duplicate table in tablegroup is not supported", KR(ret), "table_id",new_table_schema.get_table_id(), "tablegroup_id", new_table_schema.get_tablegroup_id()); LOG_USER_ERROR(OB_NOT_SUPPORTED, "duplicate table in tablegroup"); @@ -179,27 +199,131 @@ int ObTableGroupHelp::check_table_alter_tablegroup( return ret; } -// When creating a table, need to check whether the partition type of tablegroup and table are consistent -int ObTableGroupHelp::check_partition_option_for_create_table(ObSchemaGetterGuard &schema_guard, - ObTableSchema &table) +//need to check whether the partition type of tablegroup and table are consistent +int ObTableGroupHelp::check_table_partition_in_tablegroup(const ObTableSchema *first_table_schema, + ObTableSchema &table, + ObSchemaGetterGuard &schema_guard ) { int ret = OB_SUCCESS; const uint64_t tenant_id = table.get_tenant_id(); const uint64_t tablegroup_id = table.get_tablegroup_id(); const ObTablegroupSchema *tablegroup = NULL; - if (OB_INVALID_ID == tablegroup_id || is_sys_tablegroup_id(tablegroup_id)) { - LOG_INFO("skip to check tablegroup partition", KPC(tablegroup), K(table)); + if (OB_INVALID_ID == tablegroup_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablegroup_id is invalid", KR(ret), K(tablegroup_id)); + } else if (is_sys_tablegroup_id(tablegroup_id)) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("can not handle with sys tablegroup", KR(ret), K(tablegroup_id)); } else if (OB_FAIL(schema_guard.get_tablegroup_schema(tenant_id, tablegroup_id, tablegroup))) { - LOG_WARN("fail to get tablegroup schema", K(ret), K(tenant_id), KT(tablegroup_id)); + LOG_WARN("fail to get tablegroup schema", KR(ret), K(tenant_id), KT(tablegroup_id)); } else if (OB_ISNULL(tablegroup)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablegroup schema is null", K(ret), KT(tablegroup_id)); + LOG_WARN("tablegroup schema is null", KR(ret), KT(tablegroup_id)); } else if (table.is_in_splitting() || tablegroup->is_in_splitting()) { ret = OB_NOT_SUPPORTED; - LOG_WARN("table or tablegroup is splitting", K(ret), K(table), K(tablegroup)); + LOG_WARN("table or tablegroup is splitting", KR(ret), K(table), K(tablegroup)); LOG_USER_ERROR(OB_NOT_SUPPORTED, "add table to tablegroup while either object is splitting"); - } else if (OB_FAIL(check_partition_option(*tablegroup, table))) { - LOG_WARN("fail to check partition option", K(ret), KPC(tablegroup), K(table)); + } else { + // sort partition info in order, to prevent same value not in order from being misjudged + if (OB_FAIL(ObSchemaServiceSQLImpl::sort_table_partition_info_v2(table))) { + LOG_WARN("fail to sort table partition", K(ret)); + } else if (OB_FAIL(check_partition_option(*tablegroup, first_table_schema, table, schema_guard))) { + LOG_WARN("fail to check partition option", KR(ret), KPC(tablegroup), K(table)); + } + } + return ret; +} + +#define PRINT_CHECK_PARTITION_ERROR(ERROR_STRING, USER_ERROR) { \ + if (OB_SUCC(ret)) {\ + if (OB_FAIL(ERROR_STRING.append(USER_ERROR))) { \ + LOG_WARN("fail to append user error", KR(ret));\ + } else {\ + LOG_USER_ERROR(OB_OP_NOT_ALLOW, ERROR_STRING.ptr());\ + }\ + }\ +}\ +//when modify tablegroup's sharding, we need to check all tables' partition info whether fit new sharding +int ObTableGroupHelp::check_all_table_partition_option(const ObTablegroupSchema &tablegroup_schema, + ObSchemaGetterGuard &schema_guard, + bool check_subpart, + bool &is_matched) +{ + int ret = OB_SUCCESS; + is_matched = true; + ObSqlString user_error; + const uint64_t tenant_id = tablegroup_schema.get_tenant_id(); + const uint64_t tablegroup_id = tablegroup_schema.get_tablegroup_id(); + ObArray table_schemas; + + if (OB_FAIL(schema_guard.get_table_schemas_in_tablegroup(tenant_id, tablegroup_id, table_schemas))) { + LOG_WARN("fail get table schemas from tablegroup", KR(ret), K(tenant_id), K(tablegroup_id)); + } else if (0 == table_schemas.count()) { + // do nothing + } else { + int64_t table_schemas_count = table_schemas.count(); + const ObSimpleTableSchemaV2* primary_table_schema = NULL; + for (int64_t i = 0; OB_SUCC(ret) && i < table_schemas_count && is_matched; i++) { + if (OB_ISNULL(table_schemas.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table schema is null", KR(ret), K(tablegroup_schema), K(i)); + } else if (OB_ISNULL(primary_table_schema)) { + primary_table_schema = table_schemas.at(i); + } else if (OB_FAIL(ObSimpleTableSchemaV2::compare_partition_option(*table_schemas.at(i), *primary_table_schema, + check_subpart, is_matched, &user_error))) { + LOG_WARN("fail to check partition option", KR(ret), K(*table_schemas.at(i)), K(*primary_table_schema)); + } else if (!is_matched) { + LOG_WARN("two tables’ part method not consistent, not suit sharding type", + K(tablegroup_id), K(*table_schemas.at(i)), + K(*primary_table_schema), K(tablegroup_schema.get_sharding())); + PRINT_CHECK_PARTITION_ERROR(user_error, ", modify tablegroup sharding attribute"); + } + } + } + return ret; +} + +//first table schema is for tablegroup is empty,but add list num more than one +// eg:alter tablegroup tg add test1,test2,test3; +// when tablegroup tg is empty, first table is test1, we need to compare other tables' partition with test1 +// when tablegroup tg is not empty, we just ignore first table to use tablegroup's fist table; +int ObTableGroupHelp::check_table_partition_option(const ObTableSchema *table_schema, + const ObTableSchema *first_table_schema, + ObSchemaGetterGuard &schema_guard, + bool check_subpart, + bool &is_matched) +{ + int ret = OB_SUCCESS; + is_matched = true; + ObSqlString user_error; + const ObSimpleTableSchemaV2 *tmp_table_schema = NULL; + if (OB_ISNULL(table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table schema is NULL", KR(ret)); + } else if (OB_FAIL(schema_guard.get_primary_table_schema_in_tablegroup(table_schema->get_tenant_id(), + table_schema->get_tablegroup_id(), + tmp_table_schema))) { + LOG_WARN("fail get table schemas from tablegroup", KR(ret), K(table_schema->get_tenant_id()), K(table_schema->get_tablegroup_id())); + } else if (OB_ISNULL(first_table_schema) && OB_ISNULL(tmp_table_schema)) { + // do nothing + } else { + const ObSimpleTableSchemaV2* primary_table_schema = NULL; + //1.if tablegroup is empty,just compare with add list's first table + //2.if tablegroup not empty,ignore add list's fist table,just compare with tablegroup's fist table + if (OB_NOT_NULL(tmp_table_schema)) { + primary_table_schema = tmp_table_schema; + } else if (OB_NOT_NULL(first_table_schema)) { + primary_table_schema = first_table_schema; + } + if (OB_FAIL(ObSimpleTableSchemaV2::compare_partition_option(*primary_table_schema, *table_schema, + check_subpart, is_matched, &user_error))) { + LOG_WARN("fail to check partition option", KR(ret), K(*primary_table_schema), K(*table_schema)); + } else if (!is_matched) { + LOG_WARN("two tables’ part method not consistent, not suit sharding type", + K(table_schema->get_tablegroup_id()), K(*primary_table_schema), + K(*table_schema), K(check_subpart)); + PRINT_CHECK_PARTITION_ERROR(user_error, ", add table to tablegroup"); + } } return ret; } @@ -212,953 +336,92 @@ int ObTableGroupHelp::check_partition_option_for_create_table(ObSchemaGetterGuar * 3.For range/range column or list/list column partition, * the number of partition expressions partitions/partition split point are required to be same */ + int ObTableGroupHelp::check_partition_option( const ObTablegroupSchema &tablegroup, - ObTableSchema &table) + const ObTableSchema *first_table_schema, + const ObTableSchema &table, + ObSchemaGetterGuard &schema_guard) { int ret = OB_SUCCESS; bool is_matched = false; const uint64_t tablegroup_id = tablegroup.get_tablegroup_id(); const uint64_t table_id = table.get_table_id(); - if (PARTITION_LEVEL_TWO == table.get_part_level()) { - is_matched = false; - LOG_WARN("Add composited-partitioned table to tablegroup is not supported yet", K(tablegroup), K(table)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "add composited-partitioned table to tablegroup"); - } else if (is_sys_tablegroup_id(tablegroup_id)) { + if (tablegroup.get_sharding().empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablegroup sharding can not be empty", KR(ret)); + } else if (tablegroup.get_sharding() == OB_PARTITION_SHARDING_NONE) { is_matched = true; - LOG_INFO("skip to check tablegroup partition", K(tablegroup), K(table)); - } else if (tablegroup.get_part_level() != table.get_part_level()) { - LOG_WARN("part level not matched", K(ret), KT(tablegroup_id), KT(table_id), - "tg_part_level", tablegroup.get_part_level(), "table_part_level", table.get_part_level()); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "partition level not matched"); - } else if (PARTITION_LEVEL_ZERO == tablegroup.get_part_level()) { - // Non-partitioned table - is_matched = true; - LOG_INFO("tablegroup & table has no partitions, just pass", K(ret)); + } else if (table.is_partitioned_table() && table.is_interval_part()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("interval part add to tablegroup when sharding is not NONE", + KR(ret), K(tablegroup_id), K(table_id)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "add interval part table to tablegroup when sharding is not NONE"); + } else if (tablegroup.get_sharding() == OB_PARTITION_SHARDING_PARTITION) { + // check level one partitions info + if (OB_FAIL(check_table_partition_option(&table, first_table_schema, schema_guard, false, is_matched))) { + LOG_WARN("fail to check partition sharding type", KR(ret), K(tablegroup_id), K(table_id), K(is_matched)); + } + } else if (tablegroup.get_sharding() == OB_PARTITION_SHARDING_ADAPTIVE) { + //check level one and two partitions info + if (OB_FAIL(check_table_partition_option(&table, first_table_schema, schema_guard, true, is_matched))) { + LOG_WARN("fail to check adaptive sharding type", KR(ret), K(tablegroup_id), K(table_id), K(is_matched)); + } } else { - if (PARTITION_LEVEL_ONE == table.get_part_level() - || PARTITION_LEVEL_TWO == table.get_part_level()) { - const bool is_subpart = false; - if (OB_FAIL(check_partition_option(tablegroup, table, is_subpart, is_matched))) { - LOG_WARN("level one partition not matched", K(ret), KT(tablegroup_id), KT(table_id)); - } else if (!is_matched) { - // bypass - } - } - if (OB_SUCC(ret) && is_matched - && PARTITION_LEVEL_TWO == table.get_part_level()) { - const bool is_subpart = true; - if (OB_FAIL(check_partition_option(tablegroup, table, is_subpart, is_matched))) { - LOG_WARN("level two partition not matched", K(ret), KT(tablegroup_id), KT(table_id)); - } else if (!is_matched) { - // bypass - } - } + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not found sharding", KR(ret), K(tablegroup)); } if (OB_SUCC(ret) && !is_matched) { ret = OB_OP_NOT_ALLOW; - LOG_WARN("partition option not match", K(ret)); - // LOG_USER_ERROR will be printed under each 'is_matched=false' conditions + LOG_WARN("partition option not match", KR(ret)); } return ret; } -// FIXME:Support non-template subpartition -int ObTableGroupHelp::check_partition_option( - const ObTablegroupSchema &tablegroup, - ObTableSchema &table, - bool is_subpart, - bool &is_matched) +int ObTableGroupHelp::modify_sharding_type(const ObAlterTablegroupArg &arg, + const ObTablegroupSchema &tablegroup_schema, + common::ObMySQLTransaction &trans, + ObSchemaGetterGuard &schema_guard) { int ret = OB_SUCCESS; - is_matched = false; - const uint64_t tablegroup_id = tablegroup.get_tablegroup_id(); - const uint64_t table_id = table.get_table_id(); - bool is_oracle_mode = false; - bool table_is_oracle_mode = false; - if (OB_FAIL(tablegroup.check_if_oracle_compat_mode(is_oracle_mode))) { - LOG_WARN("fail to get tenant mode", KR(ret), K(tablegroup)); - } else if (OB_FAIL(table.check_if_oracle_compat_mode(table_is_oracle_mode))) { - LOG_WARN("fail to get tenant mode", KR(ret), K(table)); - } else if (is_oracle_mode != table_is_oracle_mode) { - is_matched = false; - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "table mode not match"); - } else { - if (is_sys_tablegroup_id(tablegroup_id)) { + bool is_matched = false; + ObTablegroupSchema new_tablegroup_schema; + if (arg.alter_option_bitset_.has_member(ObAlterTablegroupArg::SHARDING)) { + if (is_sys_tablegroup_id(tablegroup_schema.get_tablegroup_id())) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("modify sys tablegroup's sharding type is not allowed", KR(ret), K(tablegroup_schema.get_tablegroup_id())); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "modify sys tablegroup's sharding type"); + } else if (OB_FAIL(new_tablegroup_schema.assign(tablegroup_schema))) { + LOG_WARN("fail to assign tablegroup schema", KR(ret), K(tablegroup_schema)); + } else if (OB_FAIL(new_tablegroup_schema.set_sharding(arg.alter_tablegroup_schema_.get_sharding()))) { + LOG_WARN("fail to set tablegroup name", KR(ret), K(tablegroup_schema)); + } else if (new_tablegroup_schema.get_sharding().empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("new tablegroup schema's sharding should not be empty", KR(ret)); + } else if (new_tablegroup_schema.get_sharding() == OB_PARTITION_SHARDING_NONE) { is_matched = true; - LOG_WARN("skip to check tablegroup partition", K(tablegroup), K(table)); - } else { - const ObPartitionOption &tablegroup_part = !is_subpart ? tablegroup.get_part_option() - : tablegroup.get_sub_part_option(); - const ObPartitionOption &table_part = !is_subpart ? table.get_part_option() - : table.get_sub_part_option(); - ObPartitionFuncType tg_part_func_type = tablegroup_part.get_part_func_type(); - ObPartitionFuncType table_part_func_type = table_part.get_part_func_type(); - if (tg_part_func_type != table_part_func_type - && (!is_key_part(tg_part_func_type) || !is_key_part(table_part_func_type))) { - //skip - LOG_WARN("partition func type not matched", - KT(tablegroup_id), KT(table_id), K(tablegroup_part), K(table_part)); - } else if (PARTITION_FUNC_TYPE_MAX == tg_part_func_type) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid part_func_type", K(ret), K(tg_part_func_type), K(table_part_func_type)); - } else if (is_hash_like_part(tg_part_func_type)) { - is_matched = tablegroup_part.get_part_num() == table_part.get_part_num(); - if (!is_matched) { - LOG_WARN("partition num not matched", - KT(tablegroup_id), KT(table_id), K(tablegroup_part), K(table_part)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "range partition number not match"); - } else if (is_key_part(tg_part_func_type)) { - // For key partition, needs compared column_list_num - is_matched = false; - int64_t tablegroup_expr_num = OB_INVALID_INDEX; - int64_t table_expr_num = OB_INVALID_INDEX; - if (!is_subpart) { - if (OB_FAIL(tablegroup.calc_part_func_expr_num(tablegroup_expr_num))) { - LOG_WARN("fail to get part_func_expr_num", K(ret), K(tablegroup)); - } else if (OB_FAIL(table.calc_part_func_expr_num(table_expr_num))) { - LOG_WARN("fail to get part_func_expr_num", K(ret), K(table)); - } - } else { - if (OB_FAIL(tablegroup.calc_subpart_func_expr_num(tablegroup_expr_num))) { - LOG_WARN("fail to get subpart_func_expr_num", K(ret), K(tablegroup)); - } else if (OB_FAIL(table.calc_subpart_func_expr_num(table_expr_num))) { - LOG_WARN("fail to get subpart_func_expr_num", K(ret), K(table)); - } - } - if (OB_FAIL(ret)) { - // skip - } else if (OB_INVALID_INDEX == tablegroup_expr_num - || OB_INVALID_INDEX == table_expr_num) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("expr num is invalid", K(ret), K(tablegroup_expr_num), K(table_expr_num)); - } else { - is_matched = (tablegroup_expr_num == table_expr_num); - } - } - } else if (is_range_part(tg_part_func_type) - || is_list_part(tg_part_func_type)) { - const int64_t tg_part_num = tablegroup_part.get_part_num(); - const int64_t table_part_num = table_part.get_part_num(); - if (tg_part_num != table_part_num) { - LOG_WARN("range partition number not matched", KT(tablegroup_id), KT(table_id), - K(tablegroup_part), K(table_part), K(tg_part_num), K(table_part_num)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "range or list partition number not match"); - } else if (!is_subpart) { - if (OB_ISNULL(tablegroup.get_part_array()) - || OB_ISNULL(table.get_part_array())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition_array is null", K(ret), K(tablegroup), K(table)); - } else { - is_matched = true; - for (int i = 0; i < tg_part_num && is_matched && OB_SUCC(ret); i++) { - is_matched = false; - ObPartition *tg_part = tablegroup.get_part_array()[i]; - for (int j = 0; j < table_part_num && !is_matched && OB_SUCC(ret); j++) { - ObPartition *table_part = table.get_part_array()[j]; - if (OB_ISNULL(tg_part) || OB_ISNULL(table_part)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition is null", K(ret), KPC(tg_part), KPC(table_part)); - } else if (OB_FAIL(ObPartitionUtils::check_partition_value( - is_oracle_mode, *tg_part, *table_part, tg_part_func_type, is_matched))) { - LOG_WARN("fail to check partition value", KPC(tg_part), KPC(table_part), K(tg_part_func_type)); - } - } - } - } - if (!is_matched) { - LOG_WARN("range partition value not matched", K(ret), KT(tablegroup_id), KT(table_id), - "tg_partition_array", ObArrayWrap(tablegroup.get_part_array(), tg_part_num), - "table_part_array", ObArrayWrap(table.get_part_array(), table_part_num)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "range or list partition with not matched collation or value"); - } - } else { - if (OB_ISNULL(tablegroup.get_def_subpart_array()) - || OB_ISNULL(table.get_def_subpart_array())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("def_sub_partition_array is null", K(ret), K(tablegroup), K(table)); - } else { - is_matched = true; - for (int i = 0; i < tg_part_num && is_matched && OB_SUCC(ret); i++) { - is_matched = false; - ObSubPartition *tg_part = tablegroup.get_def_subpart_array()[i]; - for (int j = 0; j < table_part_num && !is_matched && OB_SUCC(ret); j++) { - ObSubPartition *table_part = table.get_def_subpart_array()[j]; - if (OB_ISNULL(tg_part) || OB_ISNULL(table_part)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition is null", K(ret), KPC(tg_part), KPC(table_part)); - } else if (OB_FAIL(ObPartitionUtils::check_partition_value( - is_oracle_mode, *tg_part, *table_part, tg_part_func_type, is_matched))) { - LOG_WARN("fail to check partition value", KPC(tg_part), KPC(table_part), K(tg_part_func_type)); - } - } - } - } - if (!is_matched) { - LOG_WARN("range partition value not matched", K(ret), KT(tablegroup_id), KT(table_id), - "tg_partition_array", ObArrayWrap(tablegroup.get_def_subpart_array(), tg_part_num), - "table_part_array", ObArrayWrap(table.get_def_subpart_array(), table_part_num)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "range or list partition with not matched collation or value"); - } - } - } else { - ret = OB_NOT_SUPPORTED; - LOG_WARN("invalid part func type", KT(tablegroup_id), KT(table_id), K(tablegroup_part), K(table_part)); + } else if (new_tablegroup_schema.get_sharding() == OB_PARTITION_SHARDING_PARTITION) { + if (OB_FAIL(check_all_table_partition_option(new_tablegroup_schema, schema_guard, false, is_matched))) { + LOG_WARN("fail to check table sharding partition", KR(ret), K(new_tablegroup_schema)); } + } else if (new_tablegroup_schema.get_sharding() == OB_PARTITION_SHARDING_ADAPTIVE) { + if (OB_FAIL(check_all_table_partition_option(new_tablegroup_schema, schema_guard, true, is_matched))) { + LOG_WARN("fail to check table sharding adaptive", KR(ret), K(new_tablegroup_schema)); + } + } + if (OB_SUCC(ret) && is_matched) { + ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_); + // update sharding type + if (OB_FAIL(ddl_operator.alter_tablegroup(new_tablegroup_schema, trans, &arg.ddl_stmt_str_))) { + LOG_WARN("fail to alter tablegroup sharding type", KR(ret), K(new_tablegroup_schema)); + } + } else if (OB_SUCC(ret) && !is_matched) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("can not modify sharding type", KR(ret), K(new_tablegroup_schema.get_sharding())); } } return ret; } -/** - * Check whether adding or dropping partition is legal, currently only adding or dropping the - * first-level range/range columns partition is allowed - * For drop partition: - * 1.part_name need exist(When drop a partition which has same name partition, - * it is intercepted by resolver) - * For add partition: - * 1.part_name needs to not exist - * 2.Ensure that high_bound_val increases monotonically - * For modify partition: - * The partition expressions of all tables are required to exist - */ -int ObTableGroupHelp::check_alter_partition(const ObPartitionSchema *&orig_part_schema, - ObPartitionSchema *&alter_part_schema, - const ObAlterTablegroupArg::ModifiableOptions alter_part_type, - int64_t expr_num, - bool is_tablegroup) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(orig_part_schema) - || OB_ISNULL(alter_part_schema)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("orig_part_schema or alter_part_schema is null", - KP(orig_part_schema), KP(alter_part_schema), K(ret)); - } else if (ObAlterTablegroupArg::MAX_OPTION == alter_part_type) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid alter_part_type", K(ret), K(alter_part_type)); - } else if (GCONF.in_upgrade_mode()) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("in upgrade, can not do partition maintenance", K(ret)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "partition maintenance during upgrade"); - } else if (ObAlterTablegroupArg::REORGANIZE_PARTITION == alter_part_type - || ObAlterTablegroupArg::SPLIT_PARTITION == alter_part_type - || ObAlterTablegroupArg::PARTITIONED_TABLE == alter_part_type) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("split partitions is not supported", KR(ret), K(orig_part_schema)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partitions is"); - } else if (ObAlterTablegroupArg::DROP_PARTITION == alter_part_type) { - if (OB_FAIL(check_drop_partition(orig_part_schema, alter_part_schema, is_tablegroup))) { - LOG_WARN("failed to check drop partition", K(ret)); - } - } else { - // Except drop partition, may lack for the definition of partition name in Oracle mode - ObTablegroupSchema *tablegroup_schema = NULL; - AlterTableSchema *alter_table_schema = NULL; - if (is_tablegroup) { - tablegroup_schema = static_cast(alter_part_schema); - if (OB_ISNULL(tablegroup_schema)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed get tablegroup schema", K(ret), K(tablegroup_schema)); - } else if (tablegroup_schema->is_range_part() || tablegroup_schema->is_list_part()) { - if (OB_FAIL(ddl_service_->fill_part_name(*orig_part_schema, *tablegroup_schema))) { - LOG_WARN("failed to fill part name", K(ret)); - } - } - } else { - // For split partition, if the split partition name of the table is not filled, - // then do not fill the last partition range, only fill the partition name - alter_table_schema = static_cast(alter_part_schema); - if (OB_ISNULL(alter_table_schema)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed get alter table schema", K(ret), KP(alter_part_schema)); - } else if (alter_table_schema->is_range_part() || alter_table_schema->is_list_part()) { - if (OB_FAIL(ddl_service_->fill_part_name(*orig_part_schema, *alter_table_schema))) { - LOG_WARN("failed to fill part name", K(ret)); - } - } - } - } - if (OB_FAIL(ret)) { - } else if (!orig_part_schema->is_range_part() - && !orig_part_schema->is_list_part()) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("can only be used on RANGE/RANGE COLUMNS, list/list columns partitions", K(ret)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "current partition maintenance operation for non {range/range, list/list} partitions"); - } else if (expr_num <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("expr num is invalid", K(ret), K(expr_num)); - } else if (ObAlterTablegroupArg::ADD_PARTITION == alter_part_type) { - if (OB_FAIL(check_add_partition(orig_part_schema, alter_part_schema, expr_num, is_tablegroup))) { - LOG_WARN("failed to check add partition", K(ret)); - } - } else if (ObAlterTablegroupArg::DROP_PARTITION != alter_part_type) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected alter partition type", K(ret), K(alter_part_type)); - } - return ret; -} - -int ObTableGroupHelp::check_drop_partition(const share::schema::ObPartitionSchema *&orig_part_schema, - const share::schema::ObPartitionSchema *alter_part_schema, - bool is_tablegroup) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(orig_part_schema) - || OB_ISNULL(alter_part_schema)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("orig_part_schema or alter_part_schema is null", K(ret), - KP(orig_part_schema), KP(alter_part_schema)); - } else { - if (alter_part_schema->get_part_option().get_part_num() >= - orig_part_schema->get_part_option().get_part_num()) { - ret = OB_ERR_DROP_LAST_PARTITION; - LOG_WARN("cannot drop all partitions", K(ret), - "partitions current", orig_part_schema->get_part_option().get_part_num(), - "partitions to be dropped", alter_part_schema->get_part_option().get_part_num()); - LOG_USER_ERROR(OB_ERR_DROP_LAST_PARTITION); - } else { - const int64_t part_num = alter_part_schema->get_part_option().get_part_num(); - ObPartition **part_array = alter_part_schema->get_part_array(); - const int64_t orig_part_num = orig_part_schema->get_part_option().get_part_num(); - for (int64_t i = 0; OB_SUCC(ret) && i < part_num; ++i) { - ObPartition *alter_part = part_array[i]; - bool found = false; - for (int64_t j = 0; j < orig_part_num && OB_SUCC(ret) && !found; j++) { - const ObPartition *part = orig_part_schema->get_part_array()[j]; - if (OB_ISNULL(part) || OB_ISNULL(alter_part)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("NULL ptr", K(ret), KP(part), KP(alter_part)); - } else if (is_tablegroup) { - if (ObCharset::case_insensitive_equal(part->get_part_name(), - alter_part->get_part_name())) { - if (OB_FAIL(alter_part->assign(*part))) { - LOG_WARN("partition assign failed", K(ret), K(part), K(alter_part)); - } - found = true; - } - } else if (OB_FAIL(ObDDLOperator::check_part_equal( - orig_part_schema->get_part_option().get_part_func_type(), - part, alter_part, found))) { - LOG_WARN("check_part_equal failed", K(ret)); - } else if (found) { - if (OB_FAIL(alter_part->assign(*part))) { - LOG_WARN("partition assign failed", K(ret), K(part), K(alter_part)); - } - } - }// end for - if (OB_SUCC(ret)) { - if (!found) { - ret = OB_ERR_DROP_PARTITION_NON_EXISTENT; - LOG_WARN("partition to be dropped not exist", K(ret), "partition name", part_array[i]->get_part_name()); - LOG_USER_ERROR(OB_ERR_DROP_PARTITION_NON_EXISTENT); - } - } - } - } - } - return ret; -} - -int ObTableGroupHelp::check_partarray_expr_name_valid(const share::schema::ObPartitionSchema *&orig_part_schema, - const share::schema::ObPartitionSchema *alter_part_schema, - int64_t expr_num, - const ObString *split_part_name) -{ - int ret = OB_SUCCESS; - bool is_oracle_mode = false; - if (OB_ISNULL(orig_part_schema) - || OB_ISNULL(alter_part_schema)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("orig_part_schema or alter_part_schema is null", K(ret), - KP(orig_part_schema), KP(alter_part_schema)); - } else if (OB_FAIL(orig_part_schema->check_if_oracle_compat_mode(is_oracle_mode))) { - LOG_WARN("fail to check oracle mode", KR(ret), KPC(orig_part_schema)); - } else { - const int64_t part_num = alter_part_schema->get_part_option().get_part_num(); - ObPartition **part_array = alter_part_schema->get_part_array(); - ObPartition **orig_part_array = orig_part_schema->get_part_array(); - const int64_t orig_part_num = orig_part_schema->get_part_option().get_part_num(); - const ObPartitionFuncType part_func_type = orig_part_schema->get_part_option().get_part_func_type(); - if (OB_ISNULL(part_array) || OB_ISNULL(orig_part_array) || orig_part_num < 1) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("part array is null", K(ret), KP(part_array), KP(orig_part_array), K(orig_part_num)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < part_num; ++i) { - ObPartition *alter_part = part_array[i]; - bool found = false; - // Check whether the type and number of partition value meet the requirements - const ObPartition *orig_part = orig_part_array[0]; - if (OB_ISNULL(orig_part) || OB_ISNULL(alter_part)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("NULL ptr", K(ret), KP(orig_part), KP(alter_part)); - } else if (OB_FAIL(check_part_expr_num_and_value_type(is_oracle_mode, - alter_part, - orig_part, - part_func_type, - expr_num))) { - LOG_WARN("fail to check part", K(ret), K(part_func_type), K(expr_num), K(alter_part), K(orig_part)); - } - // Check partition name for naming conflict - for (int64_t j = 0; j < orig_part_num && OB_SUCC(ret) && !found; j++) { - const ObPartition *part = orig_part_array[j]; - if (OB_ISNULL(part) || OB_ISNULL(alter_part)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("NULL ptr", K(ret), KP(part), KP(alter_part)); - } else if (ObCharset::case_insensitive_equal(part->get_part_name(), alter_part->get_part_name())) { - if (OB_NOT_NULL(split_part_name) - && ObCharset::case_insensitive_equal(part->get_part_name(), *split_part_name)) { - found = false; - } else { - found = true; - } - } - } - if (OB_SUCC(ret)) { - if (found) { - ret = OB_ERR_SAME_NAME_PARTITION; - LOG_WARN("duplicate partition name", K(part_array[i]->get_part_name()), K(ret)); - LOG_USER_ERROR(OB_ERR_SAME_NAME_PARTITION, part_array[i]->get_part_name().length(), - part_array[i]->get_part_name().ptr()); - } - } - } - } - return ret; -} - -int ObTableGroupHelp::check_add_partition(const share::schema::ObPartitionSchema *&orig_part_schema, - share::schema::ObPartitionSchema *&alter_part_schema, - int64_t expr_num, bool is_tablegroup) -{ - int ret = OB_SUCCESS; - UNUSED(is_tablegroup); - if (OB_ISNULL(orig_part_schema) - || OB_ISNULL(alter_part_schema)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("orig_part_schema or alter_part_schema is null", K(ret), - KP(orig_part_schema), KP(alter_part_schema)); - } else { - bool is_oracle_mode = false; - const int64_t part_num = alter_part_schema->get_part_option().get_part_num(); - if (OB_FAIL(ObCompatModeGetter::check_is_oracle_mode_with_tenant_id(orig_part_schema->get_tenant_id(), is_oracle_mode))) { - LOG_WARN("fail to check is oracle mode", K(ret)); - } else if ((is_oracle_mode && orig_part_schema->get_all_part_num() + part_num > OB_MAX_PARTITION_NUM_ORACLE) - || (!is_oracle_mode && orig_part_schema->get_all_part_num() + part_num > OB_MAX_PARTITION_NUM_MYSQL)) { - ret = OB_TOO_MANY_PARTITIONS_ERROR; - LOG_WARN("too partitions", K(ret), - "partition cnt current", orig_part_schema->get_all_part_num(), - "partition cnt to be added", part_num); - } else if (OB_FAIL(check_partarray_expr_name_valid(orig_part_schema, alter_part_schema, - expr_num))) { - LOG_WARN("failed to check new partition expr and name", K(ret)); - } else if (orig_part_schema->is_range_part()) { - const ObRowkey *rowkey_last = - &orig_part_schema->get_part_array()[orig_part_schema->get_part_option().get_part_num()- 1]->get_high_bound_val(); - for (int64_t i = 0; OB_SUCC(ret) && i < part_num; ++i) { - const ObRowkey *rowkey_cur = - &alter_part_schema->get_part_array()[i]->get_high_bound_val(); - if (*rowkey_cur <= *rowkey_last) { - ret = OB_ERR_RANGE_NOT_INCREASING_ERROR; - LOG_WARN("range values should increasing", K(ret), K(rowkey_cur), K(rowkey_last)); - const ObString &err_msg = orig_part_schema->get_part_array()[orig_part_schema->get_part_option().get_part_num()- 1]->get_part_name(); - LOG_USER_ERROR(OB_ERR_RANGE_NOT_INCREASING_ERROR, lib::is_oracle_mode() ? err_msg.length() : 0, err_msg.ptr()); - } else { - rowkey_last = rowkey_cur; - } - } - } else if (orig_part_schema->is_list_part()) { - if (OB_FAIL(ddl_service_->check_add_list_partition(*orig_part_schema, *alter_part_schema))) { - LOG_WARN("failed to check add list partition", K(ret)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected alter partition type", K(ret), - "part type", orig_part_schema->get_part_option().get_part_func_type()); - } - } - return ret; -} -//1. check the validity of partition_option -//2. create or drop tablegroup partition -//3. create or drop table partition which is in one tablegroup -int ObTableGroupHelp::modify_partition_option(ObMySQLTransaction &trans, - ObSchemaGetterGuard &schema_guard, - const ObTablegroupSchema &tablegroup_schema, - const ObAlterTablegroupArg &arg) -{ - int ret = OB_SUCCESS; - const uint64_t tablegroup_id = tablegroup_schema.get_tablegroup_id(); - const uint64_t tenant_id = tablegroup_schema.get_tenant_id(); - int64_t new_schema_version = OB_INVALID_VERSION; - int64_t expr_num = tablegroup_schema.get_part_func_expr_num(); - ObTablegroupSchema &alter_tablegroup_schema = const_cast(arg.alter_tablegroup_schema_); - alter_tablegroup_schema.set_tablegroup_id(tablegroup_id); - alter_tablegroup_schema.set_tenant_id(tenant_id); - ObAlterTablegroupArg::ModifiableOptions alter_part_type = ObAlterTablegroupArg::MAX_OPTION; - if (!arg.is_alter_partitions()) { - // skip - } else if (is_sys_tablegroup_id(tablegroup_id)) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("modify sys tablegroup's partition optition is not supported", K(ret), K(tablegroup_id)); - } else if (OB_ISNULL(schema_service_) - || OB_ISNULL(schema_service_->get_schema_service())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("schema_service is null", K(ret), KP(schema_service_)); - } else if (OB_FAIL(schema_service_->gen_new_schema_version(tenant_id, new_schema_version))) { - LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id)); - } else { - if (arg.alter_option_bitset_.has_member(ObAlterTablegroupArg::ADD_PARTITION)) { - alter_tablegroup_schema.get_part_option().set_part_num(alter_tablegroup_schema.get_partition_num()); - alter_part_type = ObAlterTablegroupArg::ADD_PARTITION; - if (OB_FAIL(modify_add_partition(trans, - schema_guard, - tablegroup_schema, - alter_tablegroup_schema, - new_schema_version, - expr_num, - arg))) { - LOG_WARN("failed to modify add partition", K(ret)); - } - } else if (arg.alter_option_bitset_.has_member(ObAlterTablegroupArg::DROP_PARTITION)) { - alter_part_type = ObAlterTablegroupArg::DROP_PARTITION; - alter_tablegroup_schema.get_part_option().set_part_num(alter_tablegroup_schema.get_partition_num()); - if (OB_FAIL(modify_drop_partition(trans, - schema_guard, - tablegroup_schema, - alter_tablegroup_schema, - new_schema_version, - expr_num, - arg))) { - LOG_WARN("failed to modify drop partition", K(ret)); - } - } else if (arg.alter_option_bitset_.has_member(ObAlterTablegroupArg::PARTITIONED_TABLE)) { - alter_part_type = ObAlterTablegroupArg::PARTITIONED_TABLE; - } else if (arg.alter_option_bitset_.has_member(ObAlterTablegroupArg::REORGANIZE_PARTITION)) { - alter_part_type = ObAlterTablegroupArg::REORGANIZE_PARTITION; - } else if (arg.alter_option_bitset_.has_member(ObAlterTablegroupArg::SPLIT_PARTITION)) { - alter_part_type = ObAlterTablegroupArg::SPLIT_PARTITION; - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid alter_part_type", K(ret), K(alter_part_type)); - } - if (OB_FAIL(ret)) { - } else if (ObAlterTablegroupArg::PARTITIONED_TABLE == alter_part_type - || ObAlterTablegroupArg::REORGANIZE_PARTITION == alter_part_type - || ObAlterTablegroupArg::SPLIT_PARTITION == alter_part_type) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("split partition in tablegroup is not supported", KR(ret), K(tablegroup_schema)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partition in tablegroup"); - } - } - return ret; -} -//drop partition -//check alter tabletablegroup partition, batch modify table schema, modify tablegroup schema -int ObTableGroupHelp::modify_drop_partition(common::ObMySQLTransaction &trans, - share::schema::ObSchemaGetterGuard &schema_guard, - const share::schema::ObTablegroupSchema &orig_tablegroup_schema, - share::schema::ObTablegroupSchema &inc_tablegroup_schema, - const int64_t new_schema_version, - const int64_t expr_num, - const obrpc::ObAlterTablegroupArg &arg) -{ - int ret = OB_SUCCESS; - const ObPartitionSchema *orig_schema = &orig_tablegroup_schema; - ObPartitionSchema *alter_schema = &inc_tablegroup_schema; - ObTablegroupSchema new_tablegroup_schema; - bool is_tablegroup = true; - if (PARTITION_LEVEL_ZERO == orig_schema->get_part_level()) { - ret = OB_ERR_PARTITION_MGMT_ON_NONPARTITIONED; - LOG_WARN("unsupport management on non-partition table", K(ret)); - } else if (!orig_schema->is_list_part() && !orig_schema->is_range_part()) { - ret = OB_ERR_ONLY_ON_RANGE_LIST_PARTITION; - LOG_WARN("can only be used on RANGE/LIST partitions", K(ret)); - } else if (OB_FAIL(check_alter_partition(orig_schema, - alter_schema, - ObAlterTablegroupArg::DROP_PARTITION, - expr_num, - is_tablegroup))) { - LOG_WARN("failed to check alter partition", K(ret), K(orig_schema), K(alter_schema)); - } else if (OB_FAIL(batch_modify_table_partitions(trans, - schema_guard, - inc_tablegroup_schema, - orig_tablegroup_schema, - new_schema_version, - expr_num, - ObAlterTablegroupArg::DROP_PARTITION))) { - LOG_WARN("failed to modify table partition", K(ret), K(orig_schema), K(alter_schema)); - } else if (OB_ISNULL(schema_service_) || OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("schema_service or sql_proxy is null", K(ret), KP(schema_service_), KP(sql_proxy_)); - } else { - ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_); - if (OB_FAIL(ddl_operator.drop_tablegroup_partitions(orig_tablegroup_schema, - inc_tablegroup_schema, - new_schema_version, - new_tablegroup_schema, - trans, - &(arg.ddl_stmt_str_)))) { - LOG_WARN("fail to drop tablegroup partition", K(ret), K(orig_schema), K(new_tablegroup_schema)); - } - } - return ret; -} -// Add partition - -// Modify the table schema, fill table partition name, check table partition name conflicts, -// fill tablegroup partition name, check tablegroup partition, modify tablegroup schema -int ObTableGroupHelp::modify_add_partition(common::ObMySQLTransaction &trans, - share::schema::ObSchemaGetterGuard &schema_guard, - const share::schema::ObTablegroupSchema &orig_tablegroup_schema, - share::schema::ObTablegroupSchema &inc_tablegroup_schema, - const int64_t new_schema_version, - const int64_t expr_num, - const obrpc::ObAlterTablegroupArg &arg) -{ - int ret = OB_SUCCESS; - const ObPartitionSchema *orig_schema = &orig_tablegroup_schema; - ObPartitionSchema *alter_schema = &inc_tablegroup_schema; - ObTablegroupSchema new_tablegroup_schema; - bool is_tablegroup = true; - - if (PARTITION_LEVEL_ZERO == orig_schema->get_part_level()) { - ret = OB_ERR_PARTITION_MGMT_ON_NONPARTITIONED; - LOG_WARN("unsupport management on non-partition table", K(ret)); - } else if (!orig_schema->is_list_part() && !orig_schema->is_range_part()) { - ret = OB_ERR_ONLY_ON_RANGE_LIST_PARTITION; - LOG_WARN("can only be used on RANGE/LIST partitions", K(ret)); - } else if (OB_FAIL(check_alter_partition(orig_schema, - alter_schema, - ObAlterTablegroupArg::ADD_PARTITION, - expr_num, - is_tablegroup))) { - LOG_WARN("failed to check tablegroup schema", K(ret), K(inc_tablegroup_schema)); - } else if (OB_ISNULL(schema_service_) || OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("schema_service or sql_proxy is null", K(ret), KP(schema_service_), KP(sql_proxy_)); - } else { - ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_); - if (OB_FAIL(ddl_operator.add_tablegroup_partitions(orig_tablegroup_schema, - inc_tablegroup_schema, - new_schema_version, - new_tablegroup_schema, - trans, - &(arg.ddl_stmt_str_)))) { - LOG_WARN("fail to add tablegroup partition", K(ret), K(orig_tablegroup_schema), K(inc_tablegroup_schema)); - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(batch_modify_table_partitions(trans, - schema_guard, - inc_tablegroup_schema, - inc_tablegroup_schema, - new_schema_version, - expr_num, - ObAlterTablegroupArg::ADD_PARTITION))) { - // add_partition does not construct new_tablegroup_schema, use inc instead - LOG_WARN("failed to modify table schema", K(ret), K(inc_tablegroup_schema)); - } - - return ret; -} - -int ObTableGroupHelp::batch_modify_table_partitions( - ObMySQLTransaction &trans, - ObSchemaGetterGuard &schema_guard, - ObTablegroupSchema &inc_tablegroup_schema, - const ObTablegroupSchema &new_tablegroup_schema, - const int64_t new_schema_version, - const int64_t expr_num, - ObAlterTablegroupArg::ModifiableOptions alter_part_type) -{ - int ret = OB_SUCCESS; - const int64_t tablegroup_id = new_tablegroup_schema.get_tablegroup_id(); - uint64_t tenant_id = new_tablegroup_schema.get_tenant_id(); - ObArray table_schemas; - if (OB_INVALID_ID == tablegroup_id || is_sys_tablegroup_id(tablegroup_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid tablegroup_id", K(ret), K(tablegroup_id)); - } else if (new_schema_version <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("schema_version is invalid", K(ret), K(new_schema_version)); - } else if (ObAlterTablegroupArg::MAX_OPTION == alter_part_type) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(alter_part_type)); - } else if (OB_FAIL(schema_guard.get_table_schemas_in_tablegroup(tenant_id, tablegroup_id, table_schemas))) { - LOG_WARN("fail to get table schemas in tablegroup", K(ret), K(tenant_id), K(tablegroup_id)); - } else { - bool is_tablegroup = false; - for (int64_t i = 0; i < table_schemas.count() && OB_SUCC(ret); i++) { - const ObTableSchema &orig_table_schema = *(table_schemas.at(i)); - if (!orig_table_schema.has_partition()) { - // No need to deal with tables without partition - continue; - } - AlterTableSchema alter_table_schema; - bool is_split = false; - if (ObAlterTablegroupArg::SPLIT_PARTITION == alter_part_type - || ObAlterTablegroupArg::PARTITIONED_TABLE == alter_part_type - || ObAlterTablegroupArg::REORGANIZE_PARTITION == alter_part_type) { - is_split = true; - // TODO: Need to support merge in the future - } - // When the index is not available, partition management is prohibited. - // Does not need to check whether the partition key meets the requirements of the index key for tablegroup - if (OB_FAIL(ddl_service_->check_index_valid_for_alter_partition(orig_table_schema, - schema_guard, - ObAlterTablegroupArg::DROP_PARTITION == alter_part_type, - is_split))) { - LOG_WARN("failed to check index valid", K(ret), "alter_part_type", alter_part_type, - K(is_split), K(orig_table_schema)); - } else if (OB_FAIL(alter_table_schema.assign(orig_table_schema))) { - LOG_WARN("failed to assign from origin table schema", K(ret), K(orig_table_schema)); - } else if (OB_FAIL(alter_table_schema.assign_tablegroup_partition(inc_tablegroup_schema))) { - LOG_WARN("fail to assign from tablegroup_schema", K(ret), K(orig_table_schema), - K(inc_tablegroup_schema)); - } else { - ObPartitionSchema *inc_table = &alter_table_schema; - const ObPartitionSchema *orig_table = &orig_table_schema; - if (OB_FAIL(check_alter_partition(orig_table, inc_table, alter_part_type, - expr_num, is_tablegroup))) { - LOG_WARN("fail to check partition optition", K(ret)); - } else if (ObAlterTablegroupArg::PARTITIONED_TABLE == alter_part_type - && 1 == alter_table_schema.get_part_option().get_part_num()) { - // When partition num is 1, no real split is performed, and have already written the table - // schema for all tables in the tablegroup, no further processing is required - } else { - ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_); - if (ObAlterTablegroupArg::ADD_PARTITION == alter_part_type) { - if (OB_FAIL(add_table_partition_in_tablegroup(orig_table_schema, - inc_tablegroup_schema, - new_schema_version, - alter_table_schema, - trans))) { - LOG_WARN("fail to add table partition", K(ret)); - } - } else if (ObAlterTablegroupArg::DROP_PARTITION == alter_part_type) { - ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_); - if (OB_FAIL(ddl_operator.drop_table_partitions(orig_table_schema, - alter_table_schema, - new_schema_version, - trans))) { - LOG_WARN("fail to drop table partitions", K(ret)); - } - } else if (ObAlterTablegroupArg::PARTITIONED_TABLE == alter_part_type) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("split partition in tablegroup is not supported", - KR(ret), K(orig_table_schema)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partition in tablegroup"); - } else if (ObAlterTablegroupArg::REORGANIZE_PARTITION == alter_part_type - || ObAlterTablegroupArg::SPLIT_PARTITION == alter_part_type) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("split partition in tablegroup is not supported", - KR(ret), K(orig_table_schema)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partition in tablegroup"); - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid alter_part_type", K(ret), K(alter_part_type)); - } - } - } - } - } - return ret; -} - -int ObTableGroupHelp::check_part_expr_num_and_value_type( - const bool is_oracle_mode, - const ObPartition *alter_part, - const ObPartition *orig_part, - const ObPartitionFuncType part_type, - int64_t expr_num) -{ - int ret = OB_SUCCESS; - const bool is_check_value = true; - lib::CompatModeGuard g(is_oracle_mode ? - lib::Worker::CompatMode::ORACLE : - lib::Worker::CompatMode::MYSQL); - if (OB_ISNULL(alter_part) || OB_ISNULL(orig_part)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("alter_part is null", K(ret)); - } else if (expr_num <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("expr num is invalid", K(ret), K(expr_num)); - } else if (is_range_part(part_type)) { - const ObRowkey rowkey = alter_part->get_high_bound_val(); - const ObRowkey tg_rowkey = orig_part->get_high_bound_val(); - if (PARTITION_FUNC_TYPE_RANGE == part_type) { - // For range partition, need to ensure that the number of expressions is 1, - // and the value is an integer - if (1 != rowkey.get_obj_cnt()) { - ret = OB_ERR_PARTITION_COLUMN_LIST_ERROR; - LOG_WARN("Inconsistency in usage of column lists for partitioning near", K(ret), "expr_num", rowkey.get_obj_cnt()); - } else if (OB_ISNULL(rowkey.get_obj_ptr()) || OB_ISNULL(tg_rowkey.get_obj_ptr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("rowkey obj ptr is null", K(ret), KPC(alter_part)); - } else { - const ObObj &obj = rowkey.get_obj_ptr()[0]; - if (obj.is_max_value()) { - // just pass - } else if (!ob_is_integer_type(obj.get_type())) { - ret = OB_ERR_VALUES_IS_NOT_INT_TYPE_ERROR; - LOG_WARN("obj type is invalid", K(ret), K(rowkey)); - LOG_USER_ERROR(OB_ERR_VALUES_IS_NOT_INT_TYPE_ERROR, - alter_part->get_part_name().length(), - alter_part->get_part_name().ptr()); - } - } - } else if (PARTITION_FUNC_TYPE_RANGE_COLUMNS == part_type) { - // For range column partition, need to ensure that the number of partition expression is - // consistent with that of the tablegroup - if (expr_num != rowkey.get_obj_cnt()) { - ret = OB_ERR_PARTITION_COLUMN_LIST_ERROR; - LOG_WARN("Inconsistency in usage of column lists for partitioning near", - K(ret), K(expr_num), "obj_cnt", rowkey.get_obj_cnt()); - } else if (expr_num != tg_rowkey.get_obj_cnt()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("obj cnt not matched", K(ret), K(expr_num), "obj_cnt", tg_rowkey.get_obj_cnt()); - } else if (OB_ISNULL(rowkey.get_obj_ptr()) || OB_ISNULL(tg_rowkey.get_obj_ptr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("rowkey obj ptr is null", K(ret), KPC(alter_part), KPC(orig_part)); - } else { - ObCastCtx cast_ctx(const_cast(alter_part)->get_allocator(), NULL, - CM_NONE, ObCharset::get_system_collation()); - for (int64_t k = 0; k < rowkey.get_obj_cnt() && OB_SUCC(ret); k++) { - const ObObj &obj = rowkey.get_obj_ptr()[k]; - ObObj &tg_obj = const_cast(tg_rowkey.get_obj_ptr()[k]); - if (obj.is_max_value() ||tg_obj.is_max_value()) { - // just pass - } else if (!sql::ObResolverUtils::is_valid_partition_column_type(obj.get_type(), part_type, is_check_value)) { - ret = OB_ERR_VALUES_IS_NOT_INT_TYPE_ERROR; - LOG_WARN("obj type is invalid", K(ret), K(obj)); - LOG_USER_ERROR(OB_ERR_VALUES_IS_NOT_INT_TYPE_ERROR, - alter_part->get_part_name().length(), - alter_part->get_part_name().ptr()); - } else if (obj.get_type() != tg_obj.get_type()) { - if (!ObPartitionUtils::is_types_equal_for_partition_check( - is_oracle_mode, obj.get_type(), tg_obj.get_type())) { - ret = OB_ERR_WRONG_TYPE_COLUMN_VALUE_ERROR; - LOG_USER_ERROR(OB_ERR_WRONG_TYPE_COLUMN_VALUE_ERROR); - LOG_WARN("object type is invalid ", K(ret), KPC(alter_part), KPC(orig_part), K(is_oracle_mode)); - } else if (OB_FAIL(ObObjCaster::to_type(obj.get_type(), - cast_ctx, - tg_obj, - tg_obj))) { - LOG_WARN("failed to cast object", K(obj), K(ret), K(k)); - } - } - } - } - } - } else if (is_list_part(part_type)) { - const common::ObIArray* new_rowkey = &(alter_part->get_list_row_values()); - const common::ObIArray* orig_rowkey = &(orig_part->get_list_row_values()); - if (1 > new_rowkey->count() || 1 > orig_rowkey->count()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("list value is empty", K(ret), - "orig num", orig_rowkey->count(), "new num", new_rowkey->count()); - } else if (PARTITION_FUNC_TYPE_LIST == part_type) { - int64_t count = new_rowkey->count(); - for (int64_t index = 0; OB_SUCC(ret) && index < count; ++index) { - if (1 != new_rowkey->at(index).get_count()) { - ret = OB_ERR_PARTITION_COLUMN_LIST_ERROR; - LOG_WARN("Inconsistency in usage of column lists for partitioning near", - K(ret), K(index), "obj count", new_rowkey->at(index).get_count()); - } else if (new_rowkey->at(index).get_cell(0).is_max_value()) { - // No need to check default partition - } else if (!ob_is_integer_type(new_rowkey->at(index).get_cell(0).get_type())) { - // Currently only support int type for list partition - ret = OB_ERR_VALUES_IS_NOT_INT_TYPE_ERROR; - LOG_WARN("obj type is invalid", K(ret), K(index), K(new_rowkey)); - LOG_USER_ERROR(OB_ERR_VALUES_IS_NOT_INT_TYPE_ERROR, - alter_part->get_part_name().length(), - alter_part->get_part_name().ptr()); - } - } - } else if (PARTITION_FUNC_TYPE_LIST_COLUMNS == part_type) { - if ((1 == new_rowkey->count() - && 1 == new_rowkey->at(0).get_count() - && new_rowkey->at(0).get_cell(0).is_max_value())) { - // There will only be one default partition, and the semantics is different from - // the maxvalue of the range partition - } else { - int64_t count = new_rowkey->count(); - for (int64_t index = 0; OB_SUCC(ret) && index < count; ++index) { - int64_t obj_count = new_rowkey->at(index).get_count(); - if (obj_count != expr_num) { - ret = OB_ERR_PARTITION_COLUMN_LIST_ERROR; - LOG_WARN("Inconsistency in usage of column lists for partitioning near", - K(ret), K(expr_num), K(obj_count)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < obj_count; ++i) { - const ObObj &obj = new_rowkey->at(index).get_cell(i); - if (!sql::ObResolverUtils::is_valid_partition_column_type(obj.get_type(), part_type, is_check_value)) { - ret = OB_ERR_VALUES_IS_NOT_INT_TYPE_ERROR; - LOG_WARN("obj type is invalid", K(ret), K(obj)); - LOG_USER_ERROR(OB_ERR_VALUES_IS_NOT_INT_TYPE_ERROR, - alter_part->get_part_name().length(), - alter_part->get_part_name().ptr()); - } - } - }// end for - if (OB_FAIL(ret)) { - } else if (1 == orig_rowkey->count() - && 1 == orig_rowkey->at(0).get_count() - && orig_rowkey->at(0).get_cell(0).is_max_value()) { - //pass nothing to check - } else { - // Compare the number of column partition expressions is consistent - int64_t count = new_rowkey->count(); - for (int64_t index = 0; OB_SUCC(ret) && index < count; ++index) { - if (new_rowkey->at(index).get_count() != orig_rowkey->at(0).get_count()) { - ret = OB_ERR_PARTITION_COLUMN_LIST_ERROR; - LOG_WARN("Inconsistency in usage of column lists for partitioning near", - K(ret), K(index), "obj count", new_rowkey->at(index).get_count(), - "orig count", orig_rowkey->at(0).get_count()); - } else { - int64_t obj_count = new_rowkey->at(index).get_count(); - ObCastCtx cast_ctx(const_cast(alter_part)->get_allocator(), NULL, CM_NONE, ObCharset::get_system_collation()); - for (int64_t i = 0; OB_SUCC(ret) && i < obj_count; ++i) { - ObObj &obj = const_cast(new_rowkey->at(index).get_cell(i)); - if (obj.get_type() != orig_rowkey->at(0).get_cell(i).get_type()) { - if (!ObPartitionUtils::is_types_equal_for_partition_check( - is_oracle_mode, obj.get_type(), orig_rowkey->at(0).get_cell(i).get_type())) { - ret = OB_ERR_WRONG_TYPE_COLUMN_VALUE_ERROR; - LOG_USER_ERROR(OB_ERR_WRONG_TYPE_COLUMN_VALUE_ERROR); - LOG_WARN("object type is invalid ", K(ret), KPC(alter_part), KPC(orig_part), K(is_oracle_mode)); - } else if (OB_FAIL(ObObjCaster::to_type(orig_rowkey->at(0).get_cell(i).get_type(), - cast_ctx, - obj, - obj))) { - LOG_WARN("failed to cast object", K(orig_rowkey->at(0).get_cell(i)), K(ret)); - } - } - }//end for check obj type - } - }// end for check newrow - } - } - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("only support range/range column, list/list columns partition", K(ret), K(part_type)); - } - return ret; -} -////////////////////////////// -////////////////////////////// - -int ObTableGroupHelp::add_table_partition_in_tablegroup( - const share::schema::ObTableSchema &orig_table_schema, - const share::schema::ObTablegroupSchema &inc_tablegroup_schema, - const int64_t schema_version, - share::schema::AlterTableSchema &alter_table_schema, - common::ObMySQLTransaction &client) -{ - return OB_NOT_SUPPORTED; -} - } // end namespace rootserver } // end namespace oceanbase diff --git a/src/rootserver/ob_ddl_help.h b/src/rootserver/ob_ddl_help.h index 6cfad16c4..73d393f88 100644 --- a/src/rootserver/ob_ddl_help.h +++ b/src/rootserver/ob_ddl_help.h @@ -46,87 +46,46 @@ public: {} ~ObTableGroupHelp() {} - int check_partition_option_for_create_table(share::schema::ObSchemaGetterGuard &schema_guard, - share::schema::ObTableSchema &table_schema); + int check_table_partition_in_tablegroup(const share::schema::ObTableSchema *first_table_schema, + share::schema::ObTableSchema &table_schema, + share::schema::ObSchemaGetterGuard &schema_guard); int add_tables_to_tablegroup(common::ObMySQLTransaction &trans, share::schema::ObSchemaGetterGuard &schema_guard, const share::schema::ObTablegroupSchema &tablegroup_schema, const obrpc::ObAlterTablegroupArg &arg); - - - int modify_partition_option(common::ObMySQLTransaction &trans, - share::schema::ObSchemaGetterGuard &schema_guard, - const share::schema::ObTablegroupSchema &tablegroup_schema, + int modify_partition_option(ObMySQLTransaction &trans, + ObSchemaGetterGuard &schema_guard, + const ObTablegroupSchema &tablegroup_schema, const obrpc::ObAlterTablegroupArg &arg); int check_table_alter_tablegroup( share::schema::ObSchemaGetterGuard &schema_guard, + const share::schema::ObTableSchema *first_table_schema, const share::schema::ObTableSchema &orig_table_schema, share::schema::ObTableSchema &new_table_schema); + int modify_sharding_type(const obrpc::ObAlterTablegroupArg &arg, + const ObTablegroupSchema &tablegroup_schema, + common::ObMySQLTransaction &trans, + ObSchemaGetterGuard &schema_guard); + private: + + int check_table_partition_option(const ObTableSchema *table_schema, + const ObTableSchema *first_table_schema, + ObSchemaGetterGuard &schema_guard, + bool check_subpart, + bool &is_matched); + int check_all_table_partition_option(const ObTablegroupSchema &tablegroup_schema, + ObSchemaGetterGuard &schema_guard, + bool check_subpart, + bool &is_matched); + int check_partition_option(const share::schema::ObTablegroupSchema &tablegroup, - share::schema::ObTableSchema &table); - - int check_partition_option( - const share::schema::ObTablegroupSchema &tablegroup, - share::schema::ObTableSchema &table, - bool is_subpart, - bool &is_matched); - - int check_alter_partition(const share::schema::ObPartitionSchema *&orig_part_schema, - share::schema::ObPartitionSchema *&alter_part_schema, - const obrpc::ObAlterTablegroupArg::ModifiableOptions alter_part_type, - int64_t expr_num, - bool is_tablegroup); - int check_add_partition(const share::schema::ObPartitionSchema *&orig_part_schema, - share::schema::ObPartitionSchema *&alter_part_schema, - int64_t expr_num, - bool is_tablegroup); - int check_drop_partition(const share::schema::ObPartitionSchema *&orig_part_schema, - const share::schema::ObPartitionSchema *alter_part_schema, - bool is_tablegroup); - int check_partarray_expr_name_valid(const share::schema::ObPartitionSchema *&orig_part_schema, - const share::schema::ObPartitionSchema *alter_part_schema, - int64_t expr_num, - const ObString *split_part_name = NULL); - - int batch_modify_table_partitions( - common::ObMySQLTransaction &trans, - share::schema::ObSchemaGetterGuard &schema_guard, - share::schema::ObTablegroupSchema &inc_tablegroup_schema, - const share::schema::ObTablegroupSchema &orig_tablegroup_schema, - const int64_t new_schema_version, - const int64_t expr_num, - obrpc::ObAlterTablegroupArg::ModifiableOptions alter_part_type); - - int modify_drop_partition(common::ObMySQLTransaction &trans, - share::schema::ObSchemaGetterGuard &schema_guard, - const share::schema::ObTablegroupSchema &orig_tablegroup_schema, - share::schema::ObTablegroupSchema &inc_tablegroup_schema, - const int64_t new_schema_version, - const int64_t expr_num, - const obrpc::ObAlterTablegroupArg &arg); - int modify_add_partition(common::ObMySQLTransaction &trans, - share::schema::ObSchemaGetterGuard &schema_guard, - const share::schema::ObTablegroupSchema &orig_tablegroup_schema, - share::schema::ObTablegroupSchema &inc_tablegroup_schema, - const int64_t new_schema_version, - const int64_t expr_num, - const obrpc::ObAlterTablegroupArg &arg); - int check_part_expr_num_and_value_type( - const bool is_oracle_mode, - const share::schema::ObPartition *alter_part, - const share::schema::ObPartition *orig_part, - const share::schema::ObPartitionFuncType part_func_type, - int64_t expr_num); - - int add_table_partition_in_tablegroup(const share::schema::ObTableSchema &orig_table_schema, - const share::schema::ObTablegroupSchema &inc_tablegroup_schema, - const int64_t schema_version, - share::schema::AlterTableSchema &alter_table_schema, - common::ObMySQLTransaction &client); + const share::schema::ObTableSchema *fist_table_schema, + const share::schema::ObTableSchema &table, + ObSchemaGetterGuard &schema_guard); DISALLOW_COPY_AND_ASSIGN(ObTableGroupHelp); diff --git a/src/rootserver/ob_ddl_operator.cpp b/src/rootserver/ob_ddl_operator.cpp index eb9732f25..431cafdd7 100644 --- a/src/rootserver/ob_ddl_operator.cpp +++ b/src/rootserver/ob_ddl_operator.cpp @@ -2435,45 +2435,6 @@ int ObDDLOperator::add_table_partitions(const ObTableSchema &orig_table_schema, return ret; } -int ObDDLOperator::add_tablegroup_partitions(const ObTablegroupSchema &orig_tablegroup_schema, - const ObTablegroupSchema &inc_tablegroup_schema, - const int64_t new_schema_version, - ObTablegroupSchema &new_tablegroup_schema, - ObMySQLTransaction &trans, - const ObString *ddl_stmt_str) -{ - int ret = OB_SUCCESS; - ObSchemaService *schema_service = schema_service_.get_schema_service(); - if (OB_ISNULL(schema_service)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("schema_service is NULL", K(ret)); - } else if (new_schema_version <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("schema_version is invalid", K(ret), K(new_schema_version)); - } else { - const int64_t inc_part_num = inc_tablegroup_schema.get_part_option().get_part_num(); - if (OB_FAIL(schema_service->get_tablegroup_sql_service().add_inc_part_info(trans, - orig_tablegroup_schema, - inc_tablegroup_schema, - new_schema_version))) { - LOG_WARN("add inc part info failed", K(ret)); - } else if (OB_FAIL(new_tablegroup_schema.assign(orig_tablegroup_schema))) { - LOG_WARN("failed to assign schema", K(ret), K(orig_tablegroup_schema)); - } else { - const int64_t part_num = orig_tablegroup_schema.get_part_option().get_part_num(); - const int64_t all_part_num = part_num + inc_part_num; - new_tablegroup_schema.get_part_option().set_part_num(all_part_num); - new_tablegroup_schema.set_schema_version(new_schema_version); - ObSchemaOperationType opt_type = OB_DDL_ALTER_TABLEGROUP_PARTITION; - if (OB_FAIL(schema_service->get_tablegroup_sql_service() - .update_partition_option(trans, new_tablegroup_schema, opt_type, ddl_stmt_str))) { - LOG_WARN("update partition option failed", K(ret), K(part_num), K(inc_part_num)); - } - } - } - return ret; -} - int ObDDLOperator::get_part_array_from_table(const ObTableSchema &new_table_schema, const ObTableSchema &inc_table_schema, ObIArray &out_part_array) @@ -2739,48 +2700,6 @@ int ObDDLOperator::drop_table_partitions(const ObTableSchema &orig_table_schema, return ret; } -int ObDDLOperator::drop_tablegroup_partitions(const ObTablegroupSchema &orig_tablegroup_schema, - ObTablegroupSchema &inc_tablegroup_schema, - const int64_t new_schema_version, - ObTablegroupSchema &new_tablegroup_schema, - ObMySQLTransaction &trans, - const ObString *ddl_stmt_str) -{ - int ret = OB_SUCCESS; - ObSchemaService *schema_service = schema_service_.get_schema_service(); - if (OB_ISNULL(schema_service)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("schema_service is NULL", K(ret)); - } else if (new_schema_version <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("schema_version is invalid", K(ret), K(new_schema_version)); - } else if (OB_INVALID_ID == orig_tablegroup_schema.get_tablegroup_id() - || is_sys_tablegroup_id(orig_tablegroup_schema.get_tablegroup_id())) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("can't drop partition while tablegroup is created before ver 2.0", - K(ret), K(orig_tablegroup_schema)); - } else if (OB_FAIL(schema_service->get_tablegroup_sql_service().drop_inc_part_info( - trans, - orig_tablegroup_schema, - inc_tablegroup_schema, - new_schema_version))) { - LOG_WARN("delete inc part info failed", K(ret)); - } else { - new_tablegroup_schema = orig_tablegroup_schema; - const int64_t part_num = orig_tablegroup_schema.get_part_option().get_part_num(); - const int64_t inc_part_num = inc_tablegroup_schema.get_part_option().get_part_num(); - const int64_t all_part_num = part_num - inc_part_num; - new_tablegroup_schema.get_part_option().set_part_num(all_part_num); - new_tablegroup_schema.set_schema_version(new_schema_version); - ObSchemaOperationType opt_type = OB_DDL_ALTER_TABLEGROUP_PARTITION; - if (OB_FAIL(schema_service->get_tablegroup_sql_service() - .update_partition_option(trans, new_tablegroup_schema, opt_type, ddl_stmt_str))) { - LOG_WARN("update partition option failed", K(ret), K(part_num), K(inc_part_num)); - } - } - return ret; -} - int ObDDLOperator::insert_single_column(ObMySQLTransaction &trans, const ObTableSchema &new_table_schema, ObColumnSchemaV2 &new_column) @@ -5236,7 +5155,9 @@ int ObDDLOperator::init_tenant_tablegroup(const uint64_t tenant_id, tg_schema.set_schema_version(OB_CORE_SCHEMA_VERSION); tg_schema.set_part_level(PARTITION_LEVEL_ZERO); tg_schema.set_schema_version(new_schema_version); - if (OB_FAIL(schema_service->get_tablegroup_sql_service().insert_tablegroup(tg_schema, trans))) { + if (OB_FAIL(tg_schema.set_sharding(OB_PARTITION_SHARDING_ADAPTIVE))) { + LOG_WARN("set sharding failed", K(ret), K(tg_schema)); + } else if (OB_FAIL(schema_service->get_tablegroup_sql_service().insert_tablegroup(tg_schema, trans))) { LOG_WARN("insert_tablegroup failed", K(tg_schema), K(ret)); } } diff --git a/src/rootserver/ob_ddl_operator.h b/src/rootserver/ob_ddl_operator.h index 93b6c5a28..e43fdbd52 100644 --- a/src/rootserver/ob_ddl_operator.h +++ b/src/rootserver/ob_ddl_operator.h @@ -199,18 +199,6 @@ public: share::schema::ObTableSchema &new_table_schema, common::ObMySQLTransaction &trans, const common::ObString *ddl_stmt_str = NULL); - int add_tablegroup_partitions(const share::schema::ObTablegroupSchema &orig_tablegroup_schema, - const share::schema::ObTablegroupSchema &inc_tablegroup_schema, - const int64_t new_schema_version, - share::schema::ObTablegroupSchema &new_tablegroup_schema, - common::ObMySQLTransaction &trans, - const common::ObString *ddl_stmt_str); - int drop_tablegroup_partitions(const share::schema::ObTablegroupSchema &orig_tablegroup_schema, - share::schema::ObTablegroupSchema &inc_tablegroup_schema, - const int64_t new_schema_version, - share::schema::ObTablegroupSchema &new_tablegroup_schema, - common::ObMySQLTransaction &trans, - const common::ObString *ddl_stmt_str); static int check_part_equal( const share::schema::ObPartitionFuncType part_type, const share::schema::ObPartition *r_part, diff --git a/src/rootserver/ob_ddl_service.cpp b/src/rootserver/ob_ddl_service.cpp old mode 100644 new mode 100755 index 90d359ffd..0f86fce5c --- a/src/rootserver/ob_ddl_service.cpp +++ b/src/rootserver/ob_ddl_service.cpp @@ -72,7 +72,7 @@ #include "rootserver/ddl_task/ob_ddl_retry_task.h" #include "rootserver/freeze/ob_freeze_info_manager.h" #include "rootserver/freeze/ob_major_freeze_helper.h" -#include "rootserver/ob_primary_ls_service.h"//ObTenantLSInfo +#include "rootserver/ob_tenant_thread_helper.h"//get_zone_priority #include "lib/utility/ob_tracepoint.h" #include "observer/ob_server_struct.h" #include "storage/tx/ob_ts_mgr.h" @@ -98,6 +98,7 @@ #include "share/ls/ob_ls_life_manager.h"//ObLSLifeAgentManager #include "share/restore/ob_physical_restore_table_operator.h"//ObPhysicalRestoreTableOperator #include "storage/tablelock/ob_table_lock_rpc_client.h" +#include "storage/ddl/ob_ddl_lock.h" #include "rootserver/restore/ob_restore_util.h"//insert_user_tenant_restore_job #include "logservice/palf/palf_base_info.h"//PalfBaseInfo #include "logservice/data_dictionary/ob_data_dict_storager.h" // ObDataDictStorage @@ -105,6 +106,7 @@ #include "share/backup/ob_backup_config.h" // ObBackupConfigParserMgr #include "storage/tx_storage/ob_ls_map.h" #include "storage/tx_storage/ob_ls_service.h" +#include "storage/tablelock/ob_lock_inner_connection_util.h" namespace oceanbase { @@ -554,9 +556,6 @@ int ObDDLService::create_index_table( if (OB_ISNULL(schema_service)) { ret = OB_ERR_SYS; LOG_ERROR("schema_service must not null"); - } else if (OB_FAIL(set_tablegroup_id(table_schema))) { - LOG_WARN("set_tablegroup_id failed", - K(table_schema.get_tablegroup_name()), K(ret)); } else if (OB_FAIL(schema_service->fetch_new_table_id( table_schema.get_tenant_id(), new_table_id))) { LOG_WARN("fail to fetch new table id", K(ret)); @@ -574,19 +573,11 @@ int ObDDLService::create_index_table( ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT; LOG_WARN("can not create index in recyclebin", K(ret), K(*database_schema)); } else {} // no more to do - - if (OB_SUCC(ret)) { - if (OB_FAIL(try_check_and_set_table_schema_in_tablegroup(schema_guard, table_schema))) { - LOG_WARN("check table schema in tablegroup failed", K(ret)); - } - } } if (OB_SUCC(ret)) { - if (OB_SUCC(ret)) { - if (OB_FAIL(create_table_in_trans(table_schema, - ddl_stmt_str, &sql_trans, schema_guard, true/*need_check_tablet_cnt*/))) { - LOG_WARN("create_table_in_trans failed", KR(ret), K(ddl_stmt_str), K(table_schema)); - } + if (OB_FAIL(create_table_in_trans(table_schema, + ddl_stmt_str, &sql_trans, schema_guard, true/*need_check_tablet_cnt*/))) { + LOG_WARN("create_table_in_trans failed", KR(ret), K(ddl_stmt_str), K(table_schema)); } } } @@ -1648,6 +1639,15 @@ int ObDDLService::set_tablegroup_id(ObTableSchema &table_schema) } } + if (OB_SUCC(ret)) { + uint64_t table_id = table_schema.get_table_id(); + if (!(is_inner_table(table_id) + || table_schema.is_user_table() + || table_schema.is_mysql_tmp_table())) { + table_schema.set_tablegroup_id(OB_INVALID_ID); + } + } + return ret; } @@ -1899,6 +1899,7 @@ int ObDDLService::create_tables_in_trans(const bool if_not_exist, } } } + if (OB_SUCC(ret) && (0 == i) && table_schema.is_view_table() && OB_NOT_NULL(old_view_schema) && is_oracle_mode) { const uint64_t db_id = table_schema.get_database_id(); @@ -1982,7 +1983,7 @@ int ObDDLService::create_tables_in_trans(const bool if_not_exist, LOG_WARN("failed to push_back", KR(ret), K(this_table)); } } else { - if (OB_FAIL(new_table_tablet_allocator.prepare(this_table))) { + if (OB_FAIL(new_table_tablet_allocator.prepare(trans, this_table))) { LOG_WARN("fail to prepare ls for index schema tablets"); } else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array( ls_id_array))) { @@ -2008,7 +2009,7 @@ int ObDDLService::create_tables_in_trans(const bool if_not_exist, if (OB_FAIL(ret)) { } else if (schemas.count() <= 0) { // virtual tablet and view skip - } else if (OB_FAIL(new_table_tablet_allocator.prepare(*first_table))) { + } else if (OB_FAIL(new_table_tablet_allocator.prepare(trans, *first_table))) { LOG_WARN("fail to prepare ls for index schema tablets"); } else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array( ls_id_array))) { @@ -2198,7 +2199,7 @@ int ObDDLService::set_new_table_options( if (OB_FAIL(check_tablegroup_in_single_database(schema_guard, new_table_schema))) { LOG_WARN("fail to check tablegroup in single database", K(ret)); } else if (OB_FAIL(helper.check_table_alter_tablegroup( - schema_guard, orig_table_schema, new_table_schema))) { + schema_guard, NULL, orig_table_schema, new_table_schema))) { LOG_WARN("fail to check table schema in tablegroup", K(ret)); } else {} // good } @@ -2436,13 +2437,14 @@ int ObDDLService::set_raw_table_options( break; } case ObAlterTableArg::TABLEGROUP_NAME: { - uint64_t tablegroup_id = OB_INVALID_ID; const ObString &tablegroup_name = alter_table_schema.get_tablegroup_name(); if (!tablegroup_name.empty()) { + uint64_t tablegroup_id = OB_INVALID_ID; + uint64_t tenant_id = alter_table_schema.get_tenant_id(); //tablegroup_id not set in resolver, only record tablegroup name - if (OB_FAIL(schema_guard.get_tablegroup_id(alter_table_schema.get_tenant_id(), - tablegroup_name, - tablegroup_id))) { + if (OB_FAIL(schema_guard.get_tablegroup_id(tenant_id, + tablegroup_name, + tablegroup_id))) { LOG_WARN("failed to get tablegroup id", K(ret), K(tablegroup_name)); } else if (OB_INVALID_ID == tablegroup_id) { ret = OB_TABLEGROUP_NOT_EXIST; @@ -3610,13 +3612,17 @@ int ObDDLService::check_alter_table_partition(const obrpc::ObAlterTableArg &alte ObDDLType &ddl_type) { int ret = OB_SUCCESS; + uint64_t compat_version = OB_INVALID_VERSION; + const uint64_t tenant_id = orig_table_schema.get_tenant_id(); const uint64_t tablegroup_id = orig_table_schema.get_tablegroup_id(); const ObPartitionLevel part_level = orig_table_schema.get_part_level(); - if (obrpc::ObAlterTableArg::REPARTITION_TABLE == alter_table_arg.alter_part_type_) { + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) { + LOG_WARN("get min data_version failed", K(ret), K(tenant_id)); + } else if (obrpc::ObAlterTableArg::REPARTITION_TABLE == alter_table_arg.alter_part_type_) { if (is_oracle_mode && PARTITION_LEVEL_ZERO != part_level) { ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "re-partition a patitioned table"); - } else if (OB_INVALID_ID != tablegroup_id) { + } else if (OB_INVALID_ID != tablegroup_id && compat_version < DATA_VERSION_4_2_0_0) { ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "can't modify table partition in tablegroup"); } else { @@ -3668,6 +3674,23 @@ int ObDDLService::gen_alter_partition_new_table_schema_offline( return ret; } +int ObDDLService::check_alter_partition_with_tablegroup(const ObTableSchema *orig_table_schema, + ObTableSchema &new_table_schema, + ObSchemaGetterGuard &schema_guard) +{ + int ret = OB_SUCCESS; + const uint64_t tablegroup_id = new_table_schema.get_tablegroup_id(); + if (OB_FAIL(check_inner_stat())) { + LOG_WARN("variable is not init", KR(ret)); + } else if (OB_INVALID_ID != tablegroup_id) { + ObTableGroupHelp helper(*this, *schema_service_, *sql_proxy_); + if (OB_FAIL(helper.check_table_partition_in_tablegroup(orig_table_schema, new_table_schema, schema_guard))) { + LOG_WARN("check partition option failed", KR(ret)); + } + } + return ret; +} + int ObDDLService::alter_table_partition_by( obrpc::ObAlterTableArg &alter_table_arg, const ObTableSchema &orig_table_schema, @@ -4788,7 +4811,7 @@ int ObDDLService::lock_partitions(ObMySQLTransaction &trans, const int64_t table_id = table_schema.get_table_id(); // skip those type table for lock table if (!table_schema.has_tablet() || table_schema.is_aux_table() - || table_schema.is_tmp_table() || table_schema.is_sys_table()) { + || table_schema.is_sys_table()) { } else if (OB_FAIL(table_schema.get_tablet_ids(tablet_ids))) { LOG_WARN("failed to get tablet ids", KR(ret), K(table_schema)); } else if (OB_FAIL(lock_tablets(trans, tenant_id, table_id, tablet_ids))) { @@ -4813,7 +4836,12 @@ int ObDDLService::lock_tablets(ObMySQLTransaction &trans, } else { LOG_INFO("lock tablet", KR(ret), K(tablet_ids), K(table_id), K(tenant_id), KPC(conn)); for (int i = 0; i < tablet_ids.count() && OB_SUCC(ret); i++) { - if (OB_FAIL(conn->lock_tablet(tenant_id, table_id, tablet_ids.at(i), EXCLUSIVE, timeout))) { + if (OB_FAIL(ObInnerConnectionLockUtil::lock_tablet(tenant_id, + table_id, + tablet_ids.at(i), + EXCLUSIVE, + timeout, + conn))) { LOG_WARN("lock dest table failed", KR(ret), K(table_id), K(tenant_id)); } } @@ -4833,20 +4861,96 @@ int ObDDLService::lock_table(ObMySQLTransaction &trans, observer::ObInnerSQLConnection *conn = NULL; // skip those type table for lock table if (!table_schema.has_tablet() || table_schema.is_aux_table() - || table_schema.is_tmp_table() || table_schema.is_sys_table()) { + || table_schema.is_sys_table()) { } else if (OB_ISNULL(conn = dynamic_cast (trans.get_connection()))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("conn_ is NULL", KR(ret)); } else { LOG_INFO("lock table", KR(ret), K(table_id), K(tenant_id), KPC(conn)); - if (OB_FAIL(conn->lock_table(tenant_id, table_id, EXCLUSIVE, timeout))) { + if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(tenant_id, + table_id, + EXCLUSIVE, + timeout, + conn))) { LOG_WARN("lock dest table failed", KR(ret), K(table_schema)); } } return ret; } +int ObDDLService::lock_tables_of_database(const ObDatabaseSchema &database_schema, + ObSchemaGetterGuard &schema_guard, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = database_schema.get_tenant_id(); + const uint64_t database_id = database_schema.get_database_id(); + ObArray table_ids; + if (OB_FAIL(schema_guard.get_table_ids_in_database(tenant_id, + database_id, + table_ids))) { + LOG_WARN("fail to get table ids in database", K(tenant_id), K(database_id), K(ret)); + } else { + const ObTableSchema *table_schema = NULL; + for (int64_t i = 0; OB_SUCC(ret) && i < table_ids.count(); i++) { + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_ids.at(i), table_schema))) { + LOG_WARN("fail to get table schema", K(ret), "table_id", table_ids.at(i)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table schema should not be null", K(ret)); + } else if (!table_schema->check_can_do_ddl()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("offline ddl is being executed, other ddl operations are not allowed", + K(table_schema->get_table_id()), K(ret)); + } else if (OB_FAIL(lock_table(trans, *table_schema))) { + LOG_WARN("fail to lock_table", KR(ret), KPC(table_schema)); + ret = ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; + } + } + } + return ret; +} + +int ObDDLService::lock_tables_in_recyclebin(const ObDatabaseSchema &database_schema, + ObSchemaGetterGuard &schema_guard, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObArray recycle_objs; + ObSchemaService *schema_service = nullptr; + if (OB_ISNULL(schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema_service is null", K(ret)); + } else if (OB_ISNULL(schema_service = schema_service_->get_schema_service())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema service is null", K(ret)); + } else if (OB_FAIL(schema_service->fetch_recycle_objects_of_db(database_schema.get_tenant_id(), + database_schema.get_database_id(), + trans, + recycle_objs))) { + LOG_WARN("fetch recycle objects of db failed", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < recycle_objs.count(); ++i) { + const ObRecycleObject &recycle_obj = recycle_objs.at(i); + const ObTableSchema* table_schema = NULL; + if (OB_FAIL(schema_guard.get_table_schema(recycle_obj.get_tenant_id(), + recycle_obj.get_table_id(), table_schema))) { + LOG_WARN("get table schema failed", K(ret), K(recycle_obj)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("table is not exist", K(ret), K(recycle_obj)); + LOG_USER_ERROR(OB_TABLE_NOT_EXIST, to_cstring(database_schema.get_database_name_str()), + to_cstring(recycle_obj.get_object_name())); + } else if (OB_FAIL(lock_table(trans, *table_schema))) { + LOG_WARN("fail to lock_table", KR(ret), KPC(table_schema)); + ret = ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; + } + } + } + return ret; +} + int ObDDLService::create_index_tablet(const ObTableSchema &index_schema, ObMySQLTransaction &trans, share::schema::ObSchemaGetterGuard &schema_guard, @@ -4892,7 +4996,7 @@ int ObDDLService::create_index_tablet(const ObTableSchema &index_schema, LOG_WARN("data table schema not exists", KR(ret), K(data_table_id)); } else if (OB_FAIL(schemas.push_back(&index_schema))) { LOG_WARN("failed to push_back", KR(ret), K(index_schema)); - } else if (OB_FAIL(new_table_tablet_allocator.prepare(index_schema))) { + } else if (OB_FAIL(new_table_tablet_allocator.prepare(trans, index_schema))) { LOG_WARN("fail to prepare ls for index schema tablets", KR(ret)); } else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array( ls_id_array))) { @@ -4904,7 +5008,7 @@ int ObDDLService::create_index_tablet(const ObTableSchema &index_schema, LOG_WARN("create table tablet failed", KR(ret), K(index_schema)); } } else { - if (OB_FAIL(new_table_tablet_allocator.prepare(index_schema))) { + if (OB_FAIL(new_table_tablet_allocator.prepare(trans, index_schema))) { LOG_WARN("fail to prepare ls for index schema tablets"); } else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array( ls_id_array))) { @@ -5170,8 +5274,16 @@ int ObDDLService::alter_table_index(const obrpc::ObAlterTableArg &alter_table_ar } else if (drop_index_arg->is_add_to_scheduler_) { ObDDLRes ddl_res; ObDDLTaskRecord task_record; + bool has_index_task = false; SMART_VAR(ObTableSchema, new_index_schema) { - if (OB_FAIL(rename_dropping_index_name(origin_table_schema.get_table_id(), + if (!drop_index_arg->is_inner_ && !index_table_schema->can_read_index() && OB_FAIL(ObDDLTaskRecordOperator::check_has_index_task( + trans, origin_table_schema.get_tenant_id(), origin_table_schema.get_table_id(), index_table_schema->get_table_id(), has_index_task))) { + LOG_WARN("failed to check ddl conflict", K(ret)); + } else if (has_index_task) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to drop a building or dropping index", K(ret), K(drop_index_arg->is_inner_), KPC(index_table_schema)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "dropping a building or dropping index is"); + } else if (OB_FAIL(rename_dropping_index_name(origin_table_schema.get_table_id(), origin_table_schema.get_database_id(), *drop_index_arg, schema_guard, @@ -5179,28 +5291,17 @@ int ObDDLService::alter_table_index(const obrpc::ObAlterTableArg &alter_table_ar trans, new_index_schema))) { LOG_WARN("submit drop index arg failed", K(ret)); + } else if (OB_FAIL(index_builder.submit_drop_index_task(trans, origin_table_schema, *index_table_schema, + new_index_schema.get_schema_version(), *drop_index_arg, allocator, task_record))) { + LOG_WARN("failed to submit drop index task", K(ret)); } else { - ObCreateDDLTaskParam param(new_index_schema.get_tenant_id(), - DDL_DROP_INDEX, - index_table_schema, - nullptr, - 0/*object_id*/, - new_index_schema.get_schema_version(), - 0L/*parallelism*/, - drop_index_arg->consumer_group_id_, - &allocator, - drop_index_arg); - if (OB_FAIL(GCTX.root_service_->get_ddl_scheduler().create_ddl_task(param, trans, task_record))) { - LOG_WARN("submit ddl task failed", K(ret)); - } else { - ddl_res.task_id_ = task_record.task_id_; - ddl_res.tenant_id_ = new_index_schema.get_tenant_id(); - ddl_res.schema_id_ = new_index_schema.get_table_id(); - if (OB_FAIL(ddl_tasks.push_back(task_record))) { - LOG_WARN("push back ddl task failed", K(ret)); - } else if (OB_FAIL(ddl_res_array.push_back(ddl_res))) { - LOG_WARN("push back ddl res array failed", K(ret)); - } + ddl_res.task_id_ = task_record.task_id_; + ddl_res.tenant_id_ = new_index_schema.get_tenant_id(); + ddl_res.schema_id_ = new_index_schema.get_table_id(); + if (OB_FAIL(ddl_tasks.push_back(task_record))) { + LOG_WARN("push back ddl task failed", K(ret)); + } else if (OB_FAIL(ddl_res_array.push_back(ddl_res))) { + LOG_WARN("push back ddl res array failed", K(ret)); } } } @@ -8683,12 +8784,18 @@ int ObDDLService::alter_table_column(const ObTableSchema &origin_table_schema, } } + bool is_add_lob = false; if (OB_SUCC(ret) && !is_origin_table_has_lob_column) { if (OB_FAIL(create_aux_lob_table_if_need( - new_table_schema, schema_guard, ddl_operator, trans))) { + new_table_schema, schema_guard, ddl_operator, trans, is_add_lob))) { LOG_WARN("fail to create_aux_lob_table_if_need", K(ret), K(new_table_schema)); } } + if (OB_SUCC(ret) && !is_add_lob) { + if (OB_FAIL(ObDDLLock::lock_for_common_ddl_in_trans(new_table_schema, trans))) { + LOG_WARN("failed to lock ddl lock", K(ret)); + } + } } return ret; @@ -8697,7 +8804,8 @@ int ObDDLService::alter_table_column(const ObTableSchema &origin_table_schema, int ObDDLService::create_aux_lob_table_if_need(ObTableSchema &data_table_schema, ObSchemaGetterGuard &schema_guard, ObDDLOperator &ddl_operator, - common::ObMySQLTransaction &trans) + common::ObMySQLTransaction &trans, + bool &is_add_lob) { int ret = OB_SUCCESS; ObArray aux_table_schemas; @@ -8728,8 +8836,11 @@ int ObDDLService::create_aux_lob_table_if_need(ObTableSchema &data_table_schema, schema_guard, sql_proxy_); int64_t last_schema_version = OB_INVALID_VERSION; + is_add_lob = true; if (OB_FAIL(get_last_schema_version(last_schema_version))) { LOG_WARN("fail to get last schema version", KR(ret)); + } else if (OB_FAIL(ObDDLLock::lock_for_add_lob_in_trans(data_table_schema, trans))) { + LOG_WARN("failed to add lock online ddl lock", K(ret)); } else if (OB_FAIL(table_creator.init(true/*need_tablet_cnt_check*/))) { LOG_WARN("fail to init table creator", KR(ret)); } else if (OB_FAIL(new_table_tablet_allocator.init())) { @@ -9497,7 +9608,7 @@ int ObDDLService::update_global_index(ObAlterTableArg &arg, ObTableSchema new_table_schema; if (OB_FAIL(new_table_schema.assign(*index_table_schema))) { LOG_WARN("fail to assign schema", K(ret)); - } else if (OB_FAIL(rebuild_index_in_trans(schema_guard, new_table_schema, + } else if (OB_FAIL(rebuild_index_in_trans(schema_guard, orig_table_schema, new_table_schema, NULL, &trans))) { LOG_WARN("ddl_service_ rebuild_index failed", KR(ret)); } else { @@ -9745,6 +9856,7 @@ int ObDDLService::alter_tables_partitions(const obrpc::ObAlterTableArg &alter_ta ObIArray &inc_table_schemas, ObIArray &del_table_schemas, ObDDLOperator &ddl_operator, + ObSchemaGetterGuard &schema_guard, ObMySQLTransaction &trans) { int ret = OB_SUCCESS; @@ -9776,6 +9888,7 @@ int ObDDLService::alter_tables_partitions(const obrpc::ObAlterTableArg &alter_ta *del_table_schemas.at(i), *new_table_schemas.at(i), ddl_operator, + schema_guard, trans))) { LOG_WARN("alter table partitions failed", KR(ret), K(i), KPC(new_table_schemas.at(i)), KPC(inc_table_schemas.at(i))); } @@ -9783,12 +9896,23 @@ int ObDDLService::alter_tables_partitions(const obrpc::ObAlterTableArg &alter_ta return ret; } +bool ObDDLService::is_add_and_drop_partition(const obrpc::ObAlterTableArg::AlterPartitionType &op_type) +{ + return obrpc::ObAlterTableArg::ADD_PARTITION == op_type + || obrpc::ObAlterTableArg::ADD_SUB_PARTITION == op_type + || obrpc::ObAlterTableArg::DROP_PARTITION == op_type + || obrpc::ObAlterTableArg::DROP_SUB_PARTITION == op_type + || obrpc::ObAlterTableArg::TRUNCATE_PARTITION == op_type + || obrpc::ObAlterTableArg::TRUNCATE_SUB_PARTITION == op_type; +} + int ObDDLService::alter_table_partitions(const obrpc::ObAlterTableArg &alter_table_arg, const ObTableSchema &orig_table_schema, AlterTableSchema &inc_table_schema, AlterTableSchema &del_table_schema, ObTableSchema &new_table_schema, ObDDLOperator &ddl_operator, + ObSchemaGetterGuard &schema_guard, ObMySQLTransaction &trans) { DEBUG_SYNC(BEFORE_ALTER_TABLE_PARTITION); @@ -9839,11 +9963,6 @@ int ObDDLService::alter_table_partitions(const obrpc::ObAlterTableArg &alter_tab if (OB_FAIL(gen_inc_table_schema_for_drop_part(orig_table_schema, inc_table_schema))) { LOG_WARN("fail to gen inc table schema for drop part", KR(ret), K(orig_table_schema), K(inc_table_schema)); - } else if (OB_FAIL(lock_partitions(trans, inc_table_schema))) { - LOG_WARN("failed to get tablet ids", KR(ret), K(orig_table_schema), K(inc_table_schema)); - // for ddl retry task, upper layer only focus on `OB_TRY_LOCK_ROW_CONFLICT`, and then retry it. - const bool is_ddl_scheduled_task = alter_table_arg.task_id_ > 0 ? true : false; - ret = is_ddl_scheduled_task && ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_TRY_LOCK_ROW_CONFLICT : ret; } else if (OB_FAIL(ddl_operator.drop_table_partitions(orig_table_schema, inc_table_schema, new_table_schema, @@ -9857,11 +9976,6 @@ int ObDDLService::alter_table_partitions(const obrpc::ObAlterTableArg &alter_tab } else if (OB_FAIL(gen_inc_table_schema_for_drop_subpart(orig_table_schema, inc_table_schema))) { LOG_WARN("fail to gen inc table for drop subpart", KR(ret), K(orig_table_schema), K(inc_table_schema)); - } else if (OB_FAIL(lock_partitions(trans, inc_table_schema))) { - LOG_WARN("failed to get tablet ids", KR(ret), K(orig_table_schema), K(inc_table_schema)); - // for ddl retry task, upper layer only focus on `OB_TRY_LOCK_ROW_CONFLICT`, and then retry it. - const bool is_ddl_scheduled_task = alter_table_arg.task_id_ > 0 ? true : false; - ret = is_ddl_scheduled_task && ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_TRY_LOCK_ROW_CONFLICT : ret; } else if (OB_FAIL(ddl_operator.drop_table_subpartitions(orig_table_schema, inc_table_schema, new_table_schema, @@ -9872,11 +9986,6 @@ int ObDDLService::alter_table_partitions(const obrpc::ObAlterTableArg &alter_tab if (OB_FAIL(gen_inc_table_schema_for_trun_part( orig_table_schema, inc_table_schema, del_table_schema))) { LOG_WARN("fail to generate inc table schema", KR(ret), K(orig_table_schema)); - } else if (OB_FAIL(lock_partitions(trans, del_table_schema))) { - LOG_WARN("failed to get tablet ids", KR(ret), K(orig_table_schema), K(del_table_schema)); - // for ddl retry task, upper layer only focus on `OB_TRY_LOCK_ROW_CONFLICT`, and then retry it. - const bool is_ddl_scheduled_task = alter_table_arg.task_id_ > 0 ? true : false; - ret = is_ddl_scheduled_task && ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_TRY_LOCK_ROW_CONFLICT : ret; } else if (OB_FAIL(generate_object_id_for_partition_schema(inc_table_schema))) { LOG_WARN("fail to generate object_id for partition schema", KR(ret), K(inc_table_schema)); } else if (OB_FAIL(generate_tablet_id(inc_table_schema))) { @@ -9891,11 +10000,6 @@ int ObDDLService::alter_table_partitions(const obrpc::ObAlterTableArg &alter_tab if (OB_FAIL(gen_inc_table_schema_for_trun_subpart( orig_table_schema, inc_table_schema, del_table_schema))) { LOG_WARN("fail to generate inc table schema", KR(ret), K(orig_table_schema)); - } else if (OB_FAIL(lock_partitions(trans, del_table_schema))) { - LOG_WARN("failed to get tablet ids", KR(ret), K(orig_table_schema), K(del_table_schema)); - // for ddl retry task, upper layer only focus on `OB_TRY_LOCK_ROW_CONFLICT`, and then retry it. - const bool is_ddl_scheduled_task = alter_table_arg.task_id_ > 0 ? true : false; - ret = is_ddl_scheduled_task && ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_TRY_LOCK_ROW_CONFLICT : ret; } else if (OB_FAIL(generate_object_id_for_partition_schema(inc_table_schema, true))) { LOG_WARN("fail to generate object_id for partition schema", KR(ret), K(inc_table_schema)); } else if (OB_FAIL(generate_tablet_id(inc_table_schema))) { @@ -9921,6 +10025,33 @@ int ObDDLService::alter_table_partitions(const obrpc::ObAlterTableArg &alter_tab K(orig_table_schema), K(inc_table_schema)); } } + + if (OB_SUCC(ret) && !is_add_and_drop_partition(op_type)) { + if (OB_FAIL(check_alter_partition_with_tablegroup(&orig_table_schema, new_table_schema, schema_guard))) { + LOG_WARN("fail to check alter partition with tablegroup", KR(ret), K(orig_table_schema), K(new_table_schema)); + } + } + + if (OB_FAIL(ret)) { + } else if (obrpc::ObAlterTableArg::ADD_SUB_PARTITION == op_type + || obrpc::ObAlterTableArg::ADD_PARTITION == op_type) { + if (OB_FAIL(ObDDLLock::lock_for_add_partition_in_trans(orig_table_schema, trans))) { + LOG_WARN("failed to lock for add drop partition", K(ret)); + } + } else if (obrpc::ObAlterTableArg::DROP_PARTITION == op_type + || obrpc::ObAlterTableArg::DROP_SUB_PARTITION == op_type + || obrpc::ObAlterTableArg::TRUNCATE_PARTITION == op_type + || obrpc::ObAlterTableArg::TRUNCATE_SUB_PARTITION == op_type) { + ObSEArray del_tablet_ids; + if (OB_FAIL(del_table_schema.get_tablet_ids(del_tablet_ids))) { + LOG_WARN("failed to get del tablet ids", K(ret)); + } else if (OB_FAIL(ObDDLLock::lock_for_drop_partition_in_trans(orig_table_schema, del_tablet_ids, trans))) { + LOG_WARN("failed to lock for add drop partition", K(ret), K(alter_table_arg.task_id_)); + // for ddl retry task, upper layer only focus on `OB_TRY_LOCK_ROW_CONFLICT`, and then retry it. + const bool is_ddl_scheduled_task = alter_table_arg.task_id_ > 0 ? true : false; + ret = is_ddl_scheduled_task && ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_TRY_LOCK_ROW_CONFLICT : ret; + } + } return ret; } @@ -10093,8 +10224,7 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, HEAP_VAR(ObTableSchema, new_table_schema) { HEAP_VAR(ObAlterTableArg, const_alter_table_arg) { HEAP_VAR(ObMockFKParentTableSchema, mock_fk_parent_table_schema) { - - ObSchemaGetterGuard schema_guard; + HEAP_VAR(ObSchemaGetterGuard, schema_guard) { const ObTableSchema *orig_table_schema = NULL; const ObTenantSchema *tenant_schema = NULL; uint64_t tenant_id = alter_table_schema.get_tenant_id(); @@ -10262,6 +10392,11 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, ObString origin_table_name = alter_table_schema.get_origin_table_name(); LOG_WARN("failed to alter table options,", K(origin_table_name), K(ret)); } + if (OB_SUCC(ret) && !alter_table_schema.alter_option_bitset_.is_empty()) { + if (OB_FAIL(ObDDLLock::lock_for_common_ddl_in_trans(*orig_table_schema, trans))) { + LOG_WARN("failed to lock ddl", K(ret)); + } + } // table foreign key if (OB_SUCC(ret) && !alter_table_arg.alter_table_schema_.get_foreign_key_infos().empty()) { @@ -10346,6 +10481,7 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, inc_table_schemas, del_table_schemas, ddl_operator, + schema_guard, trans))) { LOG_WARN("alter table partitions failed", K(ret)); } else if (orig_table_schemas.count() != new_table_schemas.count() @@ -10541,7 +10677,7 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, LOG_WARN("fail to init table creator", KR(ret)); } else if (OB_FAIL(new_table_tablet_allocator.init())) { LOG_WARN("fail to init new table tablet allocator", KR(ret)); - } else if (OB_FAIL(new_table_tablet_allocator.prepare(*tmp_table_schema))) { + } else if (OB_FAIL(new_table_tablet_allocator.prepare(trans, *tmp_table_schema, true))) { LOG_WARN("failed to prepare tablet allocator", KR(ret), KPC(tmp_table_schema)); } else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array(ls_id_array))) { LOG_WARN("fail to get ls id array", KR(ret)); @@ -10594,30 +10730,49 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, ObTableSchema &index_schema = create_index_arg->index_schema_; if (INDEX_TYPE_PRIMARY == create_index_arg->index_type_) { // do nothing - } else if (OB_FAIL(index_builder.submit_build_index_task(trans, - *create_index_arg, - &new_table_schema, - &index_schema, - alter_table_arg.parallelism_, - alter_table_arg.allocator_, - task_record, - alter_table_arg.consumer_group_id_))) { - LOG_WARN("fail to submit build index task", K(ret), "type", create_index_arg->index_type_); - } else if (OB_FAIL(ddl_tasks.push_back(task_record))) { - LOG_WARN("fail to push ddl task", K(ret), K(task_record)); } else { - res.task_id_ = task_record.task_id_; - ObDDLRes ddl_res; - ddl_res.tenant_id_ = tenant_id; - ddl_res.schema_id_ = create_index_arg->index_schema_.get_schema_version(); - ddl_res.task_id_ = task_record.task_id_; - obrpc::ObAlterTableResArg arg(TABLE_SCHEMA, - create_index_arg->index_schema_.get_table_id(), - create_index_arg->index_schema_.get_schema_version()); - if (OB_FAIL(res.res_arg_array_.push_back(arg))) { - LOG_WARN("push back to res_arg_array failed", K(ret), K(arg)); - } else if (OB_FAIL(res.ddl_res_array_.push_back(ddl_res))) { - LOG_WARN("failed to push back ddl res array", K(ret)); + ObArray del_tablet_ids; + if (obrpc::ObAlterTableArg::DROP_PARTITION == alter_table_arg.alter_part_type_ + || obrpc::ObAlterTableArg::DROP_SUB_PARTITION == alter_table_arg.alter_part_type_ + || obrpc::ObAlterTableArg::TRUNCATE_PARTITION == alter_table_arg.alter_part_type_ + || obrpc::ObAlterTableArg::TRUNCATE_SUB_PARTITION == alter_table_arg.alter_part_type_) { + for (int64_t i = 0; OB_SUCC(ret) && i < del_table_schemas.count(); i++) { + ObTableSchema *del_table_schema = del_table_schemas[i]; + if (del_table_schema->get_table_id() == new_table_schema.get_table_id()) { + if (OB_FAIL(del_table_schema->get_tablet_ids(del_tablet_ids))) { + LOG_WARN("failed to get del tablet ids", K(ret)); + } + break; + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(index_builder.submit_build_index_task(trans, + *create_index_arg, + orig_table_schema, + &del_tablet_ids, + &index_schema, + alter_table_arg.parallelism_, + alter_table_arg.allocator_, + task_record, + const_alter_table_arg.consumer_group_id_))) { + LOG_WARN("fail to submit build index task", K(ret), "type", create_index_arg->index_type_); + } else if (OB_FAIL(ddl_tasks.push_back(task_record))) { + LOG_WARN("fail to push ddl task", K(ret), K(task_record)); + } else { + res.task_id_ = task_record.task_id_; + ObDDLRes ddl_res; + ddl_res.tenant_id_ = tenant_id; + ddl_res.schema_id_ = create_index_arg->index_schema_.get_schema_version(); + ddl_res.task_id_ = task_record.task_id_; + obrpc::ObAlterTableResArg arg(TABLE_SCHEMA, + create_index_arg->index_schema_.get_table_id(), + create_index_arg->index_schema_.get_schema_version()); + if (OB_FAIL(res.res_arg_array_.push_back(arg))) { + LOG_WARN("push back to res_arg_array failed", K(ret), K(arg)); + } else if (OB_FAIL(res.ddl_res_array_.push_back(ddl_res))) { + LOG_WARN("failed to push back ddl res array", K(ret)); + } } } } @@ -10656,6 +10811,10 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, &const_alter_table_arg); if (OB_FAIL(GCTX.root_service_->get_ddl_scheduler().create_ddl_task(param, trans, task_record))) { LOG_WARN("submit constraint task failed", K(ret)); + } else if (OB_FAIL(ObDDLLock::lock_for_common_ddl(new_table_schema, + ObTableLockOwnerID(task_record.task_id_), + trans))) { + LOG_WARN("failed to lock online ddl lock", K(ret)); } else if (OB_FAIL(ddl_tasks.push_back(task_record))) { LOG_WARN("fail to push ddl task", K(ret), K(task_record)); } else { @@ -10678,10 +10837,25 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, && foreign_key_arg.validate_flag_))) { const ObIArray &fk_infos = alter_table_schema.get_foreign_key_infos(); const int64_t fk_cnt = fk_infos.count(); + const ObTableSchema *parent_table_schema = nullptr; ObDDLTaskRecord task_record; for (int64_t i = 0; OB_SUCC(ret) && i < fk_infos.count(); ++i) { - if (0 == foreign_key_arg.foreign_key_name_.compare(fk_infos.at(i).foreign_key_name_)) { - fk_id = fk_infos.at(i).foreign_key_id_; + const ObForeignKeyInfo fk_info = fk_infos.at(i); + if (0 == foreign_key_arg.foreign_key_name_.compare(fk_info.foreign_key_name_)) { + fk_id = fk_info.foreign_key_id_; + if (fk_info.parent_table_id_ != fk_info.child_table_id_) { + // add fk parent table obj info for ddl task record + const_alter_table_arg.based_schema_object_infos_.reset(); + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, fk_info.parent_table_id_, parent_table_schema))) { + LOG_WARN("failed to get fk parent table schema", K(ret)); + } else if (OB_ISNULL(parent_table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("parent table not exist", K(ret), K(fk_info)); + } else if (OB_FAIL(const_alter_table_arg.based_schema_object_infos_.push_back(ObBasedSchemaObjectInfo( + parent_table_schema->get_table_id(), TABLE_SCHEMA, parent_table_schema->get_schema_version())))) { + LOG_WARN("failed to add fk info", K(ret)); + } + } break; } } @@ -10702,6 +10876,14 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, &const_alter_table_arg); if (OB_FAIL(GCTX.root_service_->get_ddl_scheduler().create_ddl_task(param, trans, task_record))) { LOG_WARN("submit constraint task", K(ret)); + } else if (nullptr != parent_table_schema && OB_FAIL(ObDDLLock::lock_for_common_ddl(*parent_table_schema, + ObTableLockOwnerID(task_record.task_id_), + trans))) { + LOG_WARN("failed to lock online ddl lock", K(ret)); + } else if (OB_FAIL(ObDDLLock::lock_for_common_ddl(new_table_schema, + ObTableLockOwnerID(task_record.task_id_), + trans))) { + LOG_WARN("failed to lock online ddl lock", K(ret)); } else if (OB_FAIL(ddl_tasks.push_back(task_record))) { LOG_WARN("fail to push ddl task", K(ret), K(task_record)); } else { @@ -10743,6 +10925,7 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, } } } + } } return ret; } @@ -11200,6 +11383,11 @@ int ObDDLService::do_offline_ddl_in_trans(obrpc::ObAlterTableArg &alter_table_ar LOG_WARN("failed to alter table that has conflict ddl", K(ret), K(orig_table_schema->get_table_id())); } else if (OB_FAIL(root_service->get_ddl_scheduler().create_ddl_task(param, trans, task_record))) { LOG_WARN("submit ddl task failed", K(ret)); + } else if (OB_FAIL(ObDDLLock::lock_for_offline_ddl(*orig_table_schema, + bind_tablets ? &new_table_schema : nullptr, + ObTableLockOwnerID(task_record.task_id_), + trans))) { + LOG_WARN("failed to lock ddl lock", K(ret)); } else { res.task_id_ = task_record.task_id_; } @@ -11216,6 +11404,11 @@ int ObDDLService::do_offline_ddl_in_trans(obrpc::ObAlterTableArg &alter_table_ar &alter_table_arg); if (OB_FAIL(root_service->get_ddl_scheduler().create_ddl_task(param, trans, task_record))) { LOG_WARN("submit ddl task failed", K(ret)); + } else if (OB_FAIL(ObDDLLock::lock_for_offline_ddl(new_table_schema, + nullptr, + ObTableLockOwnerID(task_record.task_id_), + trans))) { + LOG_WARN("failed to lock ddl lock", K(ret)); } else { res.task_id_ = task_record.task_id_; } @@ -11290,10 +11483,7 @@ int ObDDLService::create_hidden_table( int64_t refreshed_schema_version = 0; new_table_schema.set_tenant_id(dest_tenant_id); new_table_schema.set_table_state_flag(ObTableStateFlag::TABLE_STATE_OFFLINE_DDL); - if (orig_table_schema->get_table_state_flag() == ObTableStateFlag::TABLE_STATE_OFFLINE_DDL) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("offline ddl is being executed, other ddl operations are not allowed, create hidden table fail", K(ret), K(create_hidden_table_arg)); - } else if (OB_FAIL(schema_guard.get_schema_version(tenant_id, refreshed_schema_version))) { + if (OB_FAIL(schema_guard.get_schema_version(tenant_id, refreshed_schema_version))) { LOG_WARN("failed to get tenant schema version", KR(ret), K(tenant_id)); } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id, refreshed_schema_version))) { LOG_WARN("start transaction failed", KR(ret), K(tenant_id), K(refreshed_schema_version)); @@ -11340,6 +11530,14 @@ int ObDDLService::create_hidden_table( &alter_table_arg); if (OB_FAIL(root_service->get_ddl_scheduler().create_ddl_task(param, trans, task_record))) { LOG_WARN("submit ddl task failed", K(ret)); + } else if (OB_FAIL(ObDDLLock::lock_for_offline_ddl(*orig_table_schema, + bind_tablets ? &new_table_schema : nullptr, + ObTableLockOwnerID(task_record.task_id_), + trans))) { + LOG_WARN("failed to lock ddl lock", K(ret)); + } else if (orig_table_schema->get_table_state_flag() == ObTableStateFlag::TABLE_STATE_OFFLINE_DDL) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("offline ddl is being executed, other ddl operations are not allowed, create hidden table fail", K(ret), K(create_hidden_table_arg)); } else { res.tenant_id_ = tenant_id; res.table_id_ = table_id; @@ -11351,22 +11549,22 @@ int ObDDLService::create_hidden_table( } } } - if (trans.is_started()) { - int temp_ret = OB_SUCCESS; - if (OB_SUCCESS != (temp_ret = trans.end(OB_SUCC(ret)))) { - LOG_WARN("trans end failed", "is_commit", OB_SUCCESS == ret, K(temp_ret)); - ret = (OB_SUCC(ret)) ? temp_ret : ret; - } + } + if (trans.is_started()) { + int temp_ret = OB_SUCCESS; + if (OB_SUCCESS != (temp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", OB_SUCCESS == ret, K(temp_ret)); + ret = (OB_SUCC(ret)) ? temp_ret : ret; } - if (OB_SUCC(ret)) { - int tmp_ret = OB_SUCCESS; - if (OB_FAIL(publish_schema(tenant_id))) { - LOG_WARN("publish_schema failed", K(ret)); - } else if (OB_TMP_FAIL(root_service->get_ddl_scheduler().schedule_ddl_task(task_record))) { - LOG_WARN("fail to schedule ddl task", K(tmp_ret), K(task_record)); - } else { - LOG_INFO("schedule ddl task success"); - } + } + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_FAIL(publish_schema(tenant_id))) { + LOG_WARN("publish_schema failed", K(ret)); + } else if (OB_TMP_FAIL(root_service->get_ddl_scheduler().schedule_ddl_task(task_record))) { + LOG_WARN("fail to schedule ddl task", K(tmp_ret), K(task_record)); + } else { + LOG_INFO("schedule ddl task success"); } } } @@ -11609,16 +11807,17 @@ int ObDDLService::check_alter_partitions(const ObTableSchema &orig_table_schema, bool is_split = false; bool is_oracle_mode = false; bool has_local_index = false; - if (GCONF.in_upgrade_mode()) { + uint64_t compat_version = OB_INVALID_VERSION; + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) { + LOG_WARN("get min data_version failed", K(ret), K(tenant_id)); + } else if (compat_version < DATA_VERSION_4_2_0_0 && OB_INVALID_ID != tablegroup_id) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can not handle table in tablegroup when observer is upgrading", K(ret), K(tenant_id)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "Can Not Handle Table In Tablegroup When Observer Is Upgrading"); + } else if (GCONF.in_upgrade_mode()) { ret = OB_OP_NOT_ALLOW; LOG_WARN("in upgrade, can not do partition maintenance", K(ret)); LOG_USER_ERROR(OB_OP_NOT_ALLOW, "partition maintenance during upgrade"); - } else if (OB_INVALID_ID != tablegroup_id - && !is_sys_tablegroup_id(tablegroup_id) - && obrpc::ObAlterTableArg::TRUNCATE_PARTITION != alter_part_type) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("add/drop table partition in 2.0 tablegroup not allowed", K(ret), K(tablegroup_id)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "add/drop table partition in 2.0 tablegroup"); } else if (OB_FAIL(get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { LOG_WARN("fail to get schema guard with version in inner table", K(ret), K(tenant_id)); } else if (OB_FAIL(ObCompatModeGetter::check_is_oracle_mode_with_tenant_id(tenant_id, is_oracle_mode))) { @@ -13245,7 +13444,7 @@ int ObDDLService::truncate_table_in_trans(const obrpc::ObTruncateTableArg &arg, LOG_WARN("failed to push_back", KR(ret), K(this_table)); } } else { - if (OB_FAIL(new_table_tablet_allocator.prepare(this_table))) { + if (OB_FAIL(new_table_tablet_allocator.prepare(trans, this_table))) { LOG_WARN("fail to prepare ls for index schema tablets"); } else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array( ls_id_array))) { @@ -13271,7 +13470,7 @@ int ObDDLService::truncate_table_in_trans(const obrpc::ObTruncateTableArg &arg, } // virtual table and view skip else if (schemas.count() <= 0) { - } else if (OB_FAIL(new_table_tablet_allocator.prepare(*schemas.at(0)))) { + } else if (OB_FAIL(new_table_tablet_allocator.prepare(trans, *schemas.at(0)))) { LOG_WARN("new table tablet allocator prepared failed", KR(ret)); } else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array( ls_id_array))) { @@ -13843,6 +14042,9 @@ int ObDDLService::create_user_hidden_table(const ObTableSchema &orig_table_schem ddl_operator, trans))) { LOG_WARN("failed to rebuild hidden table rls objects", K(ret)); + // to prevent other action to effect table partition info in tablegroup + } else if (OB_FAIL(check_alter_partition_with_tablegroup(&orig_table_schema, hidden_table_schema, schema_guard))) { + LOG_WARN("fail to check alter partition with tablegroup", KR(ret)); } else { if (OB_FAIL(schemas.push_back(&hidden_table_schema))) { LOG_WARN("fail to push back hidden table schema" , K(ret)); @@ -13905,7 +14107,7 @@ int ObDDLService::create_user_hidden_table(const ObTableSchema &orig_table_schem if (OB_SUCC(ret) && hidden_table_schema.has_tablet()) { if (bind_tablets && OB_FAIL(new_table_tablet_allocator.prepare_like(orig_table_schema))) { LOG_WARN("fail to prepare like", KR(ret), K(orig_table_schema)); - } else if (!bind_tablets && OB_FAIL(new_table_tablet_allocator.prepare(hidden_table_schema))) { + } else if (!bind_tablets && OB_FAIL(new_table_tablet_allocator.prepare(trans, hidden_table_schema))) { LOG_WARN("fail to prepare", KR(ret), K(hidden_table_schema)); } else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array(ls_id_array))) { LOG_WARN("fail to get ls id array", KR(ret)); @@ -15558,8 +15760,8 @@ int ObDDLService::unbind_hidden_tablets( LOG_WARN("failed to allocate", K(ret)); } else if (OB_FAIL(args[i].serialize(buf, size, pos))) { LOG_WARN("failed to serialize arg", K(ret)); - } else if (OB_FAIL(trans.register_tx_data(args[i].tenant_id_, args[i].ls_id_, transaction::ObTxDataSourceType::MODIFY_TABLET_BINDING, buf, pos))) { - LOG_WARN("failed to register tx data", K(ret)); + } else if (OB_FAIL(trans.register_tx_data(args[i].tenant_id_, args[i].ls_id_, transaction::ObTxDataSourceType::UNBIND_TABLET_NEW_MDS, buf, pos))) { + LOG_WARN("failed to register tx data", K(ret)); } } return ret; @@ -15786,6 +15988,14 @@ int ObDDLService::swap_orig_and_hidden_table_state(obrpc::ObAlterTableArg &alter LOG_WARN("failed to write ddl barrier", K(ret)); } } + if (OB_SUCC(ret)) { + if (OB_FAIL(ObDDLLock::unlock_for_offline_ddl(tenant_id, + orig_table_schema->get_table_id(), + ObTableLockOwnerID(alter_table_arg.task_id_), + trans))) { + LOG_WARN("failed to unlock ddl", K(ret)); + } + } } } if (trans.is_started()) { @@ -16002,6 +16212,7 @@ int ObDDLService::modify_hidden_table_fk_state(obrpc::ObAlterTableArg &alter_tab hidden_column_id))) { LOG_WARN("failed to get hidden table column id", K(ret), K(orig_column_id)); } + if (OB_SUCC(ret)) { const ObColumnSchemaV2 *col_schema = new_hidden_table_schema.get_column_schema(hidden_column_id); ObColumnSchemaV2 new_col_schema; @@ -16153,6 +16364,14 @@ int ObDDLService::cleanup_garbage(ObAlterTableArg &alter_table_arg) LOG_WARN("failed to update data table schema attribute", K(ret)); } } + if (OB_SUCC(ret)) { + if (OB_FAIL(ObDDLLock::unlock_for_offline_ddl(tenant_id, + orig_table_schema->get_table_id(), + ObTableLockOwnerID(alter_table_arg.task_id_), + trans))) { + LOG_WARN("failed to unlock ddl", K(ret)); + } + } } } if (trans.is_started()) { @@ -16919,7 +17138,11 @@ int ObDDLService::new_truncate_table(const obrpc::ObTruncateTableArg &arg, bool lock_table_not_allow = false; LOG_INFO("truncate cost after trans start and check_db_table_is_exist", KR(ret), "cost_ts", before_table_lock - start_time); // try lock - if (OB_FAIL(conn->lock_table(tenant_id, table_id, EXCLUSIVE, 0))) { + if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(tenant_id, + table_id, + EXCLUSIVE, + 0, + conn))) { LOG_WARN("failed to lock table", KR(ret), K(arg.table_name_), K(table_id)); // for error code convert if (OB_OP_NOT_ALLOW == ret) { @@ -17862,7 +18085,7 @@ int ObDDLService::drop_table_in_trans( if (OB_NOT_NULL(drop_table_set)) { if (drop_table_set->count() > 1) { ret = OB_NOT_SUPPORTED; - LOG_WARN("drop muti tables with mock fks in one sql is not supported ", K(ret)); + LOG_WARN("drop multi tables with mock fks in one sql is not supported ", K(ret)); } } if (OB_FAIL(ret)) { @@ -18670,10 +18893,18 @@ int ObDDLService::purge_index(const obrpc::ObPurgeIndexArg &arg) ObDDLSQLTransaction trans(schema_service_); ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_); int64_t refreshed_schema_version = 0; + const ObTableSchema *data_table_schema = NULL; if (OB_FAIL(schema_guard.get_schema_version(tenant_id, refreshed_schema_version))) { LOG_WARN("failed to get tenant schema version", KR(ret), K(tenant_id)); } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id, refreshed_schema_version))) { LOG_WARN("start transaction failed", KR(ret), K(tenant_id), K(refreshed_schema_version)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_schema->get_data_table_id(), data_table_schema))) { + LOG_WARN("failed to get data table schema", K(ret)); + } else if (OB_ISNULL(data_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table_shema is null", K(ret), K(table_schema->get_data_table_id())); + } else if (OB_FAIL(ObDDLLock::lock_for_add_drop_index_in_trans(*data_table_schema, *table_schema, trans))) { + LOG_WARN("failed to lock for purge index", K(ret)); } else if (OB_FAIL(ddl_operator.purge_table_in_recyclebin( *table_schema, trans, @@ -18753,6 +18984,9 @@ int ObDDLService::purge_table( } else if (OB_ISNULL(pr_trans) && OB_FAIL(trans.start(sql_proxy_, tenant_id, refreshed_schema_version))) { LOG_WARN("start transaction failed", KR(ret), K(tenant_id), K(refreshed_schema_version)); + } else if (OB_FAIL(lock_table(OB_ISNULL(pr_trans) ? trans : *pr_trans, *table_schema))) { + LOG_WARN("fail to lock_table", KR(ret), KPC(table_schema)); + ret = ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; } else if (OB_FAIL(ddl_operator.purge_table_with_aux_table(*table_schema, schema_guard, OB_ISNULL(pr_trans) ? trans : *pr_trans, @@ -18898,6 +19132,10 @@ int ObDDLService::purge_database( } else if (OB_ISNULL(pr_trans) && OB_FAIL(trans.start(sql_proxy_, tenant_id, refreshed_schema_version))) { LOG_WARN("start transaction failed", KR(ret), K(tenant_id), K(refreshed_schema_version)); + } else if (OB_FAIL(lock_tables_of_database(*database_schema, schema_guard, OB_ISNULL(pr_trans) ? trans : *pr_trans))) { + LOG_WARN("failed to lock tables of database", K(ret)); + } else if (OB_FAIL(lock_tables_in_recyclebin(*database_schema, schema_guard, OB_ISNULL(pr_trans) ? trans : *pr_trans))) { + LOG_WARN("failed to lock tables in recyclebin", K(ret)); } else if (OB_FAIL(ddl_operator.purge_database_in_recyclebin(*database_schema, OB_ISNULL(pr_trans) ? trans : *pr_trans, schema_guard, @@ -19736,6 +19974,19 @@ int ObDDLService::drop_table(const ObDropTableArg &drop_table_arg, const obrpc:: &drop_table_set, mock_fk_parent_table_ptr /* will use it when drop a fk_parent_table */))) { LOG_WARN("ddl_service_ drop_table failed", K(table_item), K(tenant_id), K(ret)); + } else if (drop_table_arg.task_id_ != 0 && drop_table_arg.table_type_ == USER_INDEX) { + const ObTableSchema *data_table_schema = nullptr; + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, tmp_table_schema.get_data_table_id(), data_table_schema))) { + LOG_WARN("failed to get data table schema", K(ret)); + } else if (OB_ISNULL(data_table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("data table not found", K(ret), K(tmp_table_schema.get_data_table_id())); + } else if (OB_FAIL(ObDDLLock::unlock_for_add_drop_index(*data_table_schema, + tmp_table_schema, + ObTableLockOwnerID(drop_table_arg.task_id_), + trans))) { + LOG_WARN("failed to unlock for add drop index", K(ret)); + } } } } @@ -19795,7 +20046,7 @@ int ObDDLService::drop_table(const ObDropTableArg &drop_table_arg, const obrpc:: // to avoid drop table again in some scenarios like succeed to drop table but RPC timeout, // drop table and update ddl task status should be done in single trans. if (OB_FAIL(ret)) { - } else if (drop_table_arg.task_id_ > 0 + } else if (drop_table_arg.task_id_ > 0 && drop_table_arg.table_type_ != USER_INDEX && OB_FAIL(ObDDLRetryTask::update_task_status_wait_child_task_finish(trans, tenant_id, drop_table_arg.task_id_))) { LOG_WARN("update task status of drop table failed", K(ret)); } @@ -19890,6 +20141,7 @@ int ObDDLService::rebuild_index(const ObRebuildIndexArg &arg, obrpc::ObAlterTabl } else if (OB_FAIL(new_table_schema.assign(*index_table_schema))) { LOG_WARN("fail to assign schema", KR(ret)); } else if (OB_FAIL(rebuild_index_in_trans(schema_guard, + *table_schema, new_table_schema, &ddl_stmt_str, &trans))) { @@ -19897,6 +20149,7 @@ int ObDDLService::rebuild_index(const ObRebuildIndexArg &arg, obrpc::ObAlterTabl } else if (OB_FAIL(index_builder.submit_build_index_task(trans, create_index_arg, table_schema, + nullptr/*del_data_tablet_ids*/, &new_table_schema, arg.parallelism_, allocator, @@ -19945,6 +20198,7 @@ int ObDDLService::rebuild_index(const ObRebuildIndexArg &arg, obrpc::ObAlterTabl // If sql_trans is NULL, you need to create a transaction inside the function int ObDDLService::rebuild_index_in_trans( ObSchemaGetterGuard &schema_guard, + const ObTableSchema &data_table_schema, ObTableSchema &index_schema, const ObString *ddl_stmt_str, ObMySQLTransaction *sql_trans) @@ -19964,6 +20218,8 @@ int ObDDLService::rebuild_index_in_trans( } else if (OB_ISNULL(sql_trans) && OB_FAIL(trans.start(sql_proxy_, tenant_id, refreshed_schema_version))) { LOG_WARN("start transaction failed", KR(ret), K(tenant_id), K(refreshed_schema_version)); + } else if (OB_FAIL(ObDDLLock::lock_for_add_drop_index_in_trans(data_table_schema, index_schema, trans))) { + LOG_WARN("failed to lock for drop index", K(ret)); } else if (OB_FAIL(drop_table_in_trans( schema_guard, index_schema, true, true, false, ddl_stmt_str, &trans, NULL, NULL))) { @@ -20048,6 +20304,23 @@ int ObDDLService::update_index_status(const obrpc::ObUpdateIndexStatusArg &arg) new_status, arg.in_offline_ddl_white_list_, trans))) { } + if (OB_SUCC(ret) && arg.task_id_ != 0) { + if (table->get_index_status() != new_status && new_status == INDEX_STATUS_AVAILABLE) { + const ObTableSchema *data_table_schema = nullptr; + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table->get_data_table_id(), data_table_schema))) { + LOG_WARN("failed to get data table schema", K(ret)); + } else if (nullptr == data_table_schema) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("data table has been deleted", K(ret), K(table->get_data_table_id())); + } else if (OB_FAIL(ObDDLLock::unlock_for_add_drop_index(*data_table_schema, + *table, + ObTableLockOwnerID(arg.task_id_), + trans))) { + LOG_WARN("failed to unlock ddl lock", K(ret)); + } + } + } + if (trans.is_started()) { int commit_ret = trans.end(OB_SUCC(ret)); if (OB_SUCCESS != commit_ret) { @@ -20838,9 +21111,7 @@ int ObDDLService::create_tenant_schema( trans, new_ug_id_array, compat_mode, pools, user_tenant_id, - false, /*is_bootstrap*/ - false, /*if not grant*/ - false /*skip_offline_server*/))) { + false/*is_bootstrap*/))) { LOG_WARN("grant_pools_to_tenant failed", KR(ret), K(pools), K(user_tenant_id)); } LOG_INFO("[CREATE_TENANT] STEP 1.2. finish grant pools", KR(ret), K(user_tenant_id), @@ -20875,13 +21146,12 @@ int ObDDLService::create_tenant_schema( // the transaction is considered to have failed, and the unit_mgr memory state is not modified at this time, // and the transaction 1 is subsequently rolled back through drop tenant. if (OB_SUCC(ret)) { - LOG_INFO("[CREATE_TENANT] STEP 1.4. start change pool owners", K(user_tenant_id)); + LOG_INFO("[CREATE_TENANT] STEP 1.4. start reload unit_manager", K(user_tenant_id)); const int64_t tmp_start_time = ObTimeUtility::fast_current_time(); - const bool grant = true; - if (OB_FAIL(unit_mgr_->commit_change_pool_owner(new_ug_id_array, grant, pools, user_tenant_id))) { - LOG_WARN("commit change pool owner failed", K(grant), K(pools), K(user_tenant_id), KR(ret)); + if (OB_FAIL(unit_mgr_->load())) { + LOG_WARN("unit_manager reload failed", K(ret)); } - LOG_INFO("[CREATE_TENANT] STEP 1.4. finish change pool owners", KR(ret), K(user_tenant_id), + LOG_INFO("[CREATE_TENANT] STEP 1.4. finish reload unit_manager", KR(ret), K(user_tenant_id), "cost", ObTimeUtility::fast_current_time() - tmp_start_time); } @@ -21039,6 +21309,9 @@ int ObDDLService::create_normal_tenant( LOG_WARN("fail to init tenant schema", KR(ret), K(tenant_role), K(recovery_until_scn), K(tenant_id), K(tenant_schema), K(sys_variable), K(init_configs), K(is_creating_standby), K(log_restore_source)); + } else if (is_user_tenant(tenant_id) && OB_FAIL(create_tenant_user_ls(tenant_id))) { + //create user ls + LOG_WARN("failed to create tenant user ls", KR(ret), K(tenant_id)); } LOG_INFO("[CREATE_TENANT] STEP 2. finish create tenant", KR(ret), K(tenant_id), "cost", ObTimeUtility::fast_current_time() - start_time); @@ -21068,6 +21341,49 @@ int ObDDLService::insert_restore_tenant_job( return ret; } +int ObDDLService::create_tenant_user_ls(const uint64_t tenant_id) +{ + const int64_t start_time = ObTimeUtility::fast_current_time(); + LOG_INFO("[CREATE_TENANT] STEP 2.5. start create user log stream", K(tenant_id)); + int ret = OB_SUCCESS; + common::ObTimeoutCtx ctx; + + if (OB_FAIL(check_inner_stat())) { + LOG_WARN("variable is not init", KR(ret)); + } else if (!is_user_tenant(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_id is invalid", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(rpc_proxy_) || OB_ISNULL(GCTX.location_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret)); + } else if (OB_FAIL(ObRootUtils::get_rs_default_timeout_ctx(ctx))) { + LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx)); + } else { + ObAddr leader; + int64_t tmp_ret = OB_SUCCESS; + //ignore failed + while(!ctx.is_timeouted() && OB_SUCC(ret)) { + const int64_t timeout = ctx.get_timeout(); + if (OB_TMP_FAIL(GCTX.location_service_->get_leader(GCONF.cluster_id, tenant_id, SYS_LS, FALSE, leader))) { + LOG_WARN("failed to get leader", KR(ret), KR(tmp_ret), K(tenant_id)); + } else if (OB_TMP_FAIL(rpc_proxy_->to(leader).timeout(timeout) + .notify_create_tenant_user_ls(tenant_id))) { + LOG_WARN("failed to create tenant user ls", KR(ret), KR(tmp_ret), K(tenant_id), K(leader), K(timeout)); + } else { + break; + } + } + if (OB_SUCC(ret) && ctx.is_timeouted()) { + ret = OB_TIMEOUT; + LOG_WARN("create user ls timeout", KR(ret)); + } + } + LOG_INFO("[CREATE_TENANT] STEP 2.5. finish create user log stream", KR(ret), K(tenant_id), + "cost", ObTimeUtility::fast_current_time() - start_time); + + return ret; +} + int ObDDLService::create_tenant_sys_ls( const ObTenantSchema &tenant_schema, const ObIArray &pool_list, @@ -21105,7 +21421,7 @@ int ObDDLService::create_tenant_sys_ls( } else if (OB_UNLIKELY(0 == primary_zone_list.count())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("primary zone is empty", KR(ret), K(tenant_schema)); - } else if (OB_FAIL(ObTenantLSInfo::get_zone_priority( + } else if (OB_FAIL(ObTenantThreadHelper::get_zone_priority( primary_zone_list.at(0), tenant_schema, zone_priority))) { LOG_WARN("failed to get zone priority", KR(ret), K(primary_zone_list), K(tenant_schema)); } else if (OB_FAIL(ls_creator.create_tenant_sys_ls( @@ -21332,7 +21648,7 @@ int ObDDLService::create_tenant_sys_tablets( } if (OB_FAIL(ret)) { // failed, bypass - } else if (OB_FAIL(new_table_tablet_allocator.prepare(data_table))) { + } else if (OB_FAIL(new_table_tablet_allocator.prepare(trans, data_table))) { LOG_WARN("fail to prepare ls for index schema tablets"); } else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array( ls_id_array))) { @@ -21618,13 +21934,13 @@ int ObDDLService::set_sys_ls_status(const uint64_t tenant_id) } else { share::ObLSAttr new_ls; share::ObLSFlag flag(share::ObLSFlag::NORMAL_FLAG); - int64_t ls_group_id = 0; + uint64_t ls_group_id = 0; SCN create_scn = SCN::base_scn(); share::ObLSAttrOperator ls_operator(tenant_id, sql_proxy_); if (OB_FAIL(new_ls.init(SYS_LS, ls_group_id, flag, share::OB_LS_NORMAL, share::OB_LS_OP_CREATE_END, create_scn))) { LOG_WARN("failed to init new operation", KR(ret), K(flag), K(create_scn)); - } else if (OB_FAIL(ls_operator.insert_ls(new_ls, ls_group_id, share::NORMAL_SWITCHOVER_STATUS))) { + } else if (OB_FAIL(ls_operator.insert_ls(new_ls, share::NORMAL_SWITCHOVER_STATUS))) { LOG_WARN("failed to insert new ls", KR(ret), K(new_ls), K(ls_group_id)); } } @@ -22481,7 +22797,7 @@ int ObDDLService::set_raw_tenant_options( * diff_pools: the diff from newresource pool list and old resource pool list. */ int ObDDLService::modify_and_cal_resource_pool_diff( - common::ObISQLClient &client, + common::ObMySQLTransaction &trans, common::ObIArray &new_ug_id_array, share::schema::ObSchemaGetterGuard &schema_guard, const share::schema::ObTenantSchema &new_tenant_schema, @@ -22527,7 +22843,7 @@ int ObDDLService::modify_and_cal_resource_pool_diff( ret = OB_NOT_SUPPORTED; LOG_WARN("fail to grant pool", K(ret), K(diff_pools)); } else if (OB_FAIL(unit_mgr_->grant_pools( - client, new_ug_id_array, compat_mode, diff_pools, tenant_id))) { + trans, new_ug_id_array, compat_mode, diff_pools, tenant_id))) { LOG_WARN("fail to grant pools", K(ret)); } } else if (new_pool_name_list.count() + 1 == old_pool_name_list.count()) { @@ -22542,7 +22858,7 @@ int ObDDLService::modify_and_cal_resource_pool_diff( ret = OB_OP_NOT_ALLOW; LOG_WARN("revoking resource pools is not allowed", K(ret), K(diff_pools)); } else if (OB_FAIL(unit_mgr_->revoke_pools( - client, new_ug_id_array, diff_pools, tenant_id))) { + trans, new_ug_id_array, diff_pools, tenant_id))) { LOG_WARN("fail to revoke pools", K(ret)); } else {} // no more to do } else if (new_pool_name_list.count() == old_pool_name_list.count()) { @@ -22961,9 +23277,8 @@ int ObDDLService::modify_tenant_inner_phase(const ObModifyTenantArg &arg, const if (OB_SUCC(ret) && arg.alter_option_bitset_.has_member(obrpc::ObModifyTenantArg::RESOURCE_POOL_LIST) && diff_pools.count() > 0) { - if (OB_FAIL(unit_mgr_->commit_change_pool_owner( - new_ug_id_array, grant, diff_pools, tenant_id))) { - LOG_WARN("commit change pool owner failed", K(grant), K(diff_pools), K(tenant_id), K(ret)); + if (OB_FAIL(unit_mgr_->load())) { + LOG_WARN("unit_manager reload failed", K(ret)); } } } @@ -23333,7 +23648,20 @@ int ObDDLService::drop_tenant(const ObDropTenantArg &arg) //1.drop tenant force if (drop_force) { const uint64_t meta_tenant_id = gen_meta_tenant_id(user_tenant_id); - if (OB_FAIL(drop_resource_pool_pre( + if (arg.drop_only_in_restore_) { + // if drop_restore_tenant is true, it demands that the tenant must be in restore status after drop tenant trans start. + if (OB_ISNULL(tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_USER_ERROR(OB_TENANT_NOT_EXIST, arg.tenant_name_.length(), arg.tenant_name_.ptr()); + LOG_WARN("tenant not exist, can't delete it", K(arg), KR(ret)); + } else if (!tenant_schema->is_restore()) { + ret = OB_OP_NOT_ALLOW; + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "Cancel tenant not in restore is"); + LOG_WARN("Cancel tenant not in restore is not allowed", K(ret), K(user_tenant_id)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(drop_resource_pool_pre( user_tenant_id, drop_ug_id_array, pool_names, trans))) { LOG_WARN("fail to drop resource pool pre", KR(ret)); } else if (OB_FAIL(ddl_operator.drop_tenant(user_tenant_id, trans, &arg.ddl_stmt_str_))) { @@ -23474,6 +23802,8 @@ int ObDDLService::drop_resource_pool_pre(const uint64_t tenant_id, LOG_WARN("get_pool_names_of_tenant failed", K(tenant_id), KR(ret)); } else if (OB_FAIL(unit_mgr_->revoke_pools(trans, drop_ug_id_array, pool_names, tenant_id))) { LOG_WARN("revoke_pools failed", K(pool_names), K(tenant_id), KR(ret)); + } else if (OB_FAIL(unit_mgr_->try_complete_shrink_tenant_pool_unit_num_rs_job(tenant_id, trans))) { + LOG_WARN("complete shrinking tenant job failed", K(pool_names), K(tenant_id), KR(ret)); } return ret; } @@ -23486,9 +23816,8 @@ int ObDDLService::drop_resource_pool_final(const uint64_t tenant_id, const bool grant = false; if (OB_FAIL(check_inner_stat())) { LOG_WARN("variable is not init"); - } else if (OB_FAIL(unit_mgr_->commit_change_pool_owner( - drop_ug_id_array, grant, pool_names, tenant_id))) { - LOG_WARN("commit change pool owner failed", K(grant), K(pool_names), K(tenant_id), KR(ret)); + } else if (OB_FAIL(unit_mgr_->load())) { + LOG_WARN("unit_manager reload failed", K(ret)); } // delete from __all_schema_status @@ -24277,22 +24606,10 @@ int ObDDLService::drop_database(const ObDropDatabaseArg &arg, ObDDLSQLTransaction &actual_trans = OB_ISNULL(ora_user_trans) ? trans : *ora_user_trans; const ObTableSchema *schema = NULL; // lock table when drop data table - for (int64_t i = 0; OB_SUCC(ret) && i < table_count; i++) { - if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_ids.at(i), schema))) { - LOG_WARN("fail to get table schema", K(ret), "table_id", table_ids.at(i)); - } else if (OB_ISNULL(schema)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table schema should not be null", K(ret)); - } else if (!schema->check_can_do_ddl()) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("offline ddl is being executed, other ddl operations are not allowed", - K(schema), K(ret)); - } else if (OB_FAIL(lock_table(actual_trans, *schema))) { - LOG_WARN("fail to lock_table", KR(ret), KPC(schema)); - // for ddl retry task, upper layer only focus on `OB_TRY_LOCK_ROW_CONFLICT`, and then retry it. - const bool is_ddl_scheduled_task = arg.task_id_ > 0 ? true : false; - ret = is_ddl_scheduled_task && ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_TRY_LOCK_ROW_CONFLICT : ret; - } + if (OB_FAIL(lock_tables_of_database(*db_schema, schema_guard, actual_trans))) { + LOG_WARN("lock tables of database", K(ret)); + } else if (!arg.to_recyclebin_ && OB_FAIL(lock_tables_in_recyclebin(*db_schema, schema_guard, actual_trans))) { + LOG_WARN("failed to lock tables in recyclebin", K(ret)); } // drop mv force @@ -24367,10 +24684,6 @@ int ObDDLService::create_tablegroup(const bool if_not_exist, ObSchemaGetterGuard schema_guard; if (OB_FAIL(check_inner_stat())) { LOG_WARN("variable is not init"); - } else if (OB_FAIL(try_format_partition_schema(tablegroup_schema))) { - LOG_WARN("fail to try_format_partition_schema", K(tablegroup_schema), KR(ret)); - } else if (OB_FAIL(generate_object_id_for_partition_schema(tablegroup_schema))) { - LOG_WARN("fail to generate object_id for partition schema", KR(ret), K(tablegroup_schema)); } else if (OB_FAIL(get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { LOG_WARN("fail to get schema guard with version in inner table", K(ret), K(tenant_id)); } else if (OB_FAIL(schema_service_->check_tablegroup_exist( @@ -24379,6 +24692,15 @@ int ObDDLService::create_tablegroup(const bool if_not_exist, LOG_WARN("check tablegroup exist failed", "tenant_id", tenant_id, "tablegroup_name", tablegroup_schema.get_tablegroup_name_str(), K(ret)); } else { + uint64_t compat_version = OB_INVALID_VERSION; + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) { + LOG_WARN("get min data_version failed", K(ret), K(tenant_id)); + } else if (compat_version < DATA_VERSION_4_2_0_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can not create tablegroup while observer is upgrading", KR(ret), K(tenant_id)); + } + } + if (OB_SUCC(ret)) { if (is_exist) { if (if_not_exist) { ret = OB_SUCCESS; @@ -24534,7 +24856,16 @@ int ObDDLService::alter_tablegroup(const ObAlterTablegroupArg &arg) } else if (OB_ISNULL(schema_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("schema service should not be null", K(ret)); - } else if (OB_FAIL(get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { + } else { + uint64_t compat_version = OB_INVALID_VERSION; + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) { + LOG_WARN("get min data_version failed", K(ret), K(tenant_id)); + } else if (compat_version < DATA_VERSION_4_2_0_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can not alter tablegroup while observer is upgrading", KR(ret), K(tenant_id)); + } + } + if (FAILEDx(get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { LOG_WARN("fail to get schema guard with version in inner table", K(ret), K(tenant_id)); } else if (OB_FAIL(schema_guard.get_tablegroup_id(tenant_id, tablegroup_name, tablegroup_id))) { LOG_WARN("fail to get tablegroup id", K(ret), K(tenant_id), K(arg)); @@ -24568,8 +24899,8 @@ int ObDDLService::alter_tablegroup(const ObAlterTablegroupArg &arg) LOG_WARN("get invalid tablegroup schema", K(ret), K(orig_tablegroup)); } else if (OB_FAIL(helper.add_tables_to_tablegroup(trans, new_schema_guard, *orig_tablegroup, arg))) { LOG_WARN("fail to add tables to tablegroup", K(ret)); - } else if (OB_FAIL(helper.modify_partition_option(trans, new_schema_guard, new_tablegroup, arg))) { - LOG_WARN("fail to modify partition option", K(ret), K(new_tablegroup), K(arg)); + } else if (OB_FAIL(helper.modify_sharding_type(arg, *orig_tablegroup, trans, new_schema_guard))) { + LOG_WARN("fail to modify partition option", K(ret), K(*orig_tablegroup), K(arg)); } // however, end the trans int temp_ret = OB_SUCCESS; @@ -29869,11 +30200,10 @@ int ObDDLService::check_create_schema_replica_options( return ret; } -template int ObDDLService::check_alter_schema_replica_options( const bool alter_primary_zone, - SCHEMA &new_schema, - const SCHEMA &orig_schema, + share::schema::ObTenantSchema &new_schema, + const share::schema::ObTenantSchema &orig_schema, common::ObArray &zone_list, share::schema::ObSchemaGetterGuard &schema_guard) { @@ -29904,6 +30234,12 @@ int ObDDLService::check_alter_schema_replica_options( } } } + + // retrun OB_OP_NOT_ALLOW if first_primary_zone changed when tenant rebalance is disabled. + if (FAILEDx(check_alter_tenant_when_rebalance_is_disabled_(orig_schema, new_schema))) { + LOG_WARN("failed to check alter tenant when rebalance is disabled", KR(ret), K(orig_schema), K(new_schema)); + } + if (OB_SUCC(ret)) { int64_t paxos_num = 0; bool is_standby = false; @@ -30546,12 +30882,24 @@ int ObDDLService::try_check_and_set_table_schema_in_tablegroup( const uint64_t tablegroup_id = schema.get_tablegroup_id(); if (!schema.has_partition()) { // include standalone table and binding table // do nohthing - } else if (OB_INVALID_ID != tablegroup_id && !is_sys_tablegroup_id(tablegroup_id)) { - ObTableGroupHelp helper(*this, *schema_service_, *sql_proxy_); - if (OB_FAIL(helper.check_partition_option_for_create_table(schema_guard, schema))) { - LOG_WARN("fail to check tablegroup partition", K(ret), K(schema)); + } else if (OB_INVALID_ID != tablegroup_id) { + //user table cannot add to sys tablegroup + if (is_sys_tablegroup_id(tablegroup_id) + && !is_inner_table(schema.get_table_id())) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("user table cannot add to sys tablegroup", KR(ret), K(schema.get_table_id())); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "user table cannot add to sys tablegroup"); + } else if (!is_sys_tablegroup_id(tablegroup_id) + && is_inner_table(schema.get_table_id())) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("inner table cannot add to user tablegroup", KR(ret), K(schema.get_table_id())); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "inner table cannot add to user tablegroup"); + } else if (!is_sys_tablegroup_id(tablegroup_id)) { + ObTableGroupHelp helper(*this, *schema_service_, *sql_proxy_); + if (OB_FAIL(helper.check_table_partition_in_tablegroup(NULL, schema, schema_guard))) { + LOG_WARN("fail to check tablegroup partition", KR(ret), K(schema.get_table_id())); + } } - } else { } return ret; } @@ -31675,7 +32023,9 @@ int ObDDLSQLTransaction::lock_all_ddl_operation( lock_arg.lock_mode_ = !enable_parallel ? EXCLUSIVE : SHARE; lock_arg.op_type_ = ObTableLockOpType::IN_TRANS_COMMON_LOCK; lock_arg.timeout_us_ = ctx.get_timeout(); - if (OB_FAIL(conn->lock_obj(tenant_id, lock_arg))) { + if (OB_FAIL(ObInnerConnectionLockUtil::lock_obj(tenant_id, + lock_arg, + conn))) { LOG_WARN("lock table failed", KR(ret), K(table_id), K(tenant_id)); } } else { @@ -31694,7 +32044,9 @@ int ObDDLSQLTransaction::lock_all_ddl_operation( lock_arg.lock_mode_ = !enable_parallel ? EXCLUSIVE : SHARE; lock_arg.op_type_ = ObTableLockOpType::IN_TRANS_COMMON_LOCK; lock_arg.timeout_us_ = ctx.get_timeout(); - if (OB_FAIL(conn->lock_obj(tenant_id, lock_arg))) { + if (OB_FAIL(ObInnerConnectionLockUtil::lock_obj(tenant_id, + lock_arg, + conn))) { LOG_WARN("lock table failed", KR(ret), K(table_id), K(tenant_id)); } else if (OB_FAIL(schema_service_->get_ddl_trans_controller().set_enable_ddl_trans_new_lock(tenant_id))) { LOG_WARN("set enable_ddl_lock_obj failed", K(ret), K(tenant_id)); @@ -32872,5 +33224,71 @@ int ObDDLService::try_add_dep_info_for_all_synonyms_batch(const uint64_t tenant_ } return ret; } + +// alter tenant with primary_zone changed is not allowed when tenant rebalance is disabled. +int ObDDLService::check_alter_tenant_when_rebalance_is_disabled_( + const share::schema::ObTenantSchema &orig_tenant_schema, + const share::schema::ObTenantSchema &new_tenant_schema) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = orig_tenant_schema.get_tenant_id(); + ObArray orig_first_primary_zone; + ObArray new_first_primary_zone; + bool is_allowed = true; + if (OB_UNLIKELY(orig_tenant_schema.get_tenant_id() != new_tenant_schema.get_tenant_id())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid input tenant schema", KR(ret), K(orig_tenant_schema), K(new_tenant_schema)); + } else if (is_sys_tenant(tenant_id)) { + // primary_zone and locality changes in sys tenant do not cause rebalance, + // so alter sys tenant is not controlled by enable_rebalance. + is_allowed = true; + } else if (ObShareUtil::is_tenant_enable_rebalance(tenant_id)) { + is_allowed = true; + } else if (OB_FAIL(ObPrimaryZoneUtil::get_tenant_primary_zone_array( + orig_tenant_schema, + orig_first_primary_zone))) { + LOG_WARN("fail to get tenant primary zone array", KR(ret), + K(orig_tenant_schema), K(orig_first_primary_zone)); + } else if (OB_FAIL(ObPrimaryZoneUtil::get_tenant_primary_zone_array( + new_tenant_schema, + new_first_primary_zone))) { + LOG_WARN("fail to get tenant primary zone array", KR(ret), + K(new_tenant_schema), K(new_first_primary_zone)); + } else if (orig_first_primary_zone.count() != new_first_primary_zone.count()) { + is_allowed = false; + } else { + ARRAY_FOREACH(new_first_primary_zone, idx) { + const ObZone &zone = new_first_primary_zone.at(idx); + if (!common::has_exist_in_array(orig_first_primary_zone, zone)) { + is_allowed = false; + break; + } + } + } + if (OB_SUCC(ret) && !is_allowed) { + ObSqlString orig_str; + ObSqlString new_str; + ARRAY_FOREACH(orig_first_primary_zone, idx) { + if (OB_FAIL(orig_str.append_fmt(0 == idx ? "%s" : ",%s", orig_first_primary_zone.at(idx).ptr()))) { + LOG_WARN("append fmt failed", KR(ret), K(orig_first_primary_zone), K(idx)); + } + } + ARRAY_FOREACH(new_first_primary_zone, idx) { + if (OB_FAIL(new_str.append_fmt(0 == idx ? "%s" : ",%s", new_first_primary_zone.at(idx).ptr()))) { + LOG_WARN("append fmt failed", KR(ret), K(new_first_primary_zone), K(idx)); + } + } + ret = OB_OP_NOT_ALLOW; + LOG_WARN("enable_rebalance is disabled, alter tenant with primary zone changed not allowed", KR(ret), + K(tenant_id), K(orig_first_primary_zone), K(new_first_primary_zone)); + char err_msg[DEFAULT_BUF_LENGTH]; + (void)snprintf(err_msg, sizeof(err_msg), + "Tenant (%lu) Primary Zone with the first priority will be changed from '%s' to '%s', " + "but tenant 'enable_rebalance' is disabled, alter tenant", tenant_id, orig_str.ptr(), new_str.ptr()); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, err_msg); + } + return ret; +} + } // end namespace rootserver } // end namespace oceanbase diff --git a/src/rootserver/ob_ddl_service.h b/src/rootserver/ob_ddl_service.h index ccdc817bf..0a42629d2 100644 --- a/src/rootserver/ob_ddl_service.h +++ b/src/rootserver/ob_ddl_service.h @@ -155,6 +155,7 @@ public: obrpc::ObAlterTableRes &res); int rebuild_index_in_trans(share::schema::ObSchemaGetterGuard &schema_guard, + const share::schema::ObTableSchema &data_table_schema, share::schema::ObTableSchema &table_schema, const ObString *ddl_stmt_str, ObMySQLTransaction *sql_trans); @@ -395,7 +396,7 @@ public: AlterTableSchema &inc_table_schema, share::schema::ObSchemaGetterGuard &schema_guard, ObArenaAllocator &allocator); - + bool is_add_and_drop_partition(const obrpc::ObAlterTableArg::AlterPartitionType &op_type); // execute alter_table_partitions for some tables which are data table and its local indexes // // @param [in] op_type, modify part ddl op @@ -409,6 +410,7 @@ public: common::ObIArray &inc_table_schemas, common::ObIArray &del_table_schemas, ObDDLOperator &ddl_operator, + ObSchemaGetterGuard &schema_guard, ObMySQLTransaction &trans); virtual int alter_table_partitions(const obrpc::ObAlterTableArg &alter_table_arg, const share::schema::ObTableSchema &orig_table_schema, @@ -416,6 +418,7 @@ public: share::schema::AlterTableSchema &del_table_schema, share::schema::ObTableSchema &new_table_schema, ObDDLOperator &ddl_operator, + ObSchemaGetterGuard &schema_guard, ObMySQLTransaction &trans); virtual int alter_table_constraints(const obrpc::ObAlterTableArg::AlterConstraintType type, share::schema::ObSchemaGetterGuard &schema_guard, @@ -1422,6 +1425,9 @@ private: ObDDLOperator &ddl_operator, common::ObMySQLTransaction &trans, common::ObArenaAllocator &allocator); + int check_alter_partition_with_tablegroup(const ObTableSchema *orig_table_schema, + ObTableSchema &new_table_schema, + ObSchemaGetterGuard &schema_guard); int alter_table_partition_by(obrpc::ObAlterTableArg &alter_table_arg, const share::schema::ObTableSchema &orgin_table_schema, share::schema::ObTableSchema &new_table_schema, @@ -1798,7 +1804,14 @@ private: ObTableSchema &data_table_schema, ObSchemaGetterGuard &schema_guard, ObDDLOperator &ddl_operator, - common::ObMySQLTransaction &trans); + common::ObMySQLTransaction &trans, + bool &is_add_lob); + int lock_tables_of_database(const share::schema::ObDatabaseSchema &database_schema, + share::schema::ObSchemaGetterGuard &schema_guard, + ObMySQLTransaction &trans); + int lock_tables_in_recyclebin(const share::schema::ObDatabaseSchema &database_schema, + share::schema::ObSchemaGetterGuard &schema_guard, + ObMySQLTransaction &trans); public: int construct_zone_region_list( @@ -1907,6 +1920,7 @@ private: const common::ObIArray &pool_list, const bool create_ls_with_palf, const palf::PalfBaseInfo &palf_base_info); + int create_tenant_user_ls(const uint64_t tenant_id); int broadcast_sys_table_schemas( const uint64_t tenant_id, common::ObIArray &tables); @@ -2017,11 +2031,10 @@ private: share::schema::ObSchemaGetterGuard &schema_guard); int check_schema_zone_list( common::ObArray &zone_list); - template int check_alter_schema_replica_options( const bool alter_primary_zone, - SCHEMA &new_schema, - const SCHEMA &orig_schema, + share::schema::ObTenantSchema &new_schema, + const share::schema::ObTenantSchema &orig_schema, common::ObArray &zone_list, share::schema::ObSchemaGetterGuard &schema_guard); template @@ -2136,7 +2149,7 @@ private: common::ObIArray ®ion_list, const common::ObIArray &zone_list); int modify_and_cal_resource_pool_diff( - common::ObISQLClient &client, + common::ObMySQLTransaction &trans, common::ObIArray &new_ug_id_array, share::schema::ObSchemaGetterGuard &schema_guard, const share::schema::ObTenantSchema &new_tenant_schema, @@ -2322,6 +2335,10 @@ private: const ObIArray &orig_table_schemas, const ObIArray &new_table_schemas, ObMySQLTransaction &trans); +int check_alter_tenant_when_rebalance_is_disabled_( + const share::schema::ObTenantSchema &orig_tenant_schema, + const share::schema::ObTenantSchema &new_tenant_schema); + private: int check_locality_compatible_(ObTenantSchema &schema); private: diff --git a/src/rootserver/ob_disaster_recovery_info.h b/src/rootserver/ob_disaster_recovery_info.h index bd446a1c8..dfd68a670 100644 --- a/src/rootserver/ob_disaster_recovery_info.h +++ b/src/rootserver/ob_disaster_recovery_info.h @@ -147,8 +147,8 @@ public: unit_mgr_(unit_mgr), zone_mgr_(zone_mgr), schema_service_(schema_service), - unit_stat_info_map_(), - server_stat_info_map_(), + unit_stat_info_map_("DRUnitStatMap"), + server_stat_info_map_("DRSerStatMap"), zone_locality_array_(), inner_ls_info_(), ls_status_info_(), diff --git a/src/rootserver/ob_disaster_recovery_task.cpp b/src/rootserver/ob_disaster_recovery_task.cpp index 1cdc0b9b5..cc4de16e2 100644 --- a/src/rootserver/ob_disaster_recovery_task.cpp +++ b/src/rootserver/ob_disaster_recovery_task.cpp @@ -1016,6 +1016,7 @@ int ObAddLSReplicaTask::check_before_execute( return ret; } +ERRSIM_POINT_DEF(ERRSIM_EXECUTE_ADD_REPLICA_ERROR); int ObAddLSReplicaTask::execute( obrpc::ObSrvRpcProxy &rpc_proxy, int &ret_code, @@ -1023,8 +1024,11 @@ int ObAddLSReplicaTask::execute( { int ret = OB_SUCCESS; + DEBUG_SYNC(BEFORE_SEND_ADD_REPLICA_DRTASK); ObLSAddReplicaArg arg; - if (OB_FAIL(arg.init( + if (OB_UNLIKELY(ERRSIM_EXECUTE_ADD_REPLICA_ERROR)) { + ret = ERRSIM_EXECUTE_ADD_REPLICA_ERROR; + } else if (OB_FAIL(arg.init( get_task_id(), get_tenant_id(), get_ls_id(), @@ -1621,29 +1625,9 @@ int ObLSTypeTransformTask::check_paxos_member( ObDRTaskRetComment &ret_comment) const { int ret = OB_SUCCESS; - if (!ObReplicaTypeCheck::is_paxos_replica_V2(dst_replica_.get_replica_type())) { - // no need to check non paxos replica - } else { - const ObZone &dst_zone = dst_replica_.get_zone(); - FOREACH_CNT_X(r, ls_info.get_replicas(), OB_SUCC(ret)) { - if (OB_UNLIKELY(nullptr == r)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get invalid replica", K(ret), K(ls_info)); - } else if (r->get_server() == dst_replica_.get_server()) { - // already check in check online - } else if (r->get_zone() == dst_zone - && r->is_in_service() - && ObReplicaTypeCheck::is_paxos_replica_V2(r->get_replica_type()) - && r->get_replica_type() == dst_replica_.get_replica_type()) { - ret = OB_REBALANCE_TASK_CANT_EXEC; - LOG_WARN("only one paxos member allowed in a single zone", K(ret), - "zone", dst_zone, "task", *this); - } else {} // no more to do - } - } - if (OB_FAIL(ret)) { - ret_comment = ObDRTaskRetComment::CANNOT_EXECUTE_DUE_TO_PAXOS_REPLICA_NUMBER; - } + // no need to make sure only one F-replica in one zone. + // Because shrink unit number may shrink unit with F-replica on it, + // thus making another R type transform to F, then 2F in one zone is expected return ret; } diff --git a/src/rootserver/ob_disaster_recovery_worker.cpp b/src/rootserver/ob_disaster_recovery_worker.cpp old mode 100644 new mode 100755 index 8f8049df4..39dc85ef5 --- a/src/rootserver/ob_disaster_recovery_worker.cpp +++ b/src/rootserver/ob_disaster_recovery_worker.cpp @@ -234,8 +234,7 @@ ObDRWorker::LocalityAlignment::LocalityAlignment(ObUnitManager *unit_mgr, locality_paxos_replica_number_(0), locality_map_(), replica_stat_map_(), - unit_set_(), - unit_provider_(unit_set_), + unit_provider_(), allocator_() { } @@ -413,6 +412,28 @@ int ObDRWorker::LocalityAlignment::try_remove_match( ReplicaStatDesc &replica_stat_desc, const int64_t index) { + // replica_stat_desc contains informations of one replica in __all_ls_meta_table. + // try_remove_match() aimed to figure out whether this replica's location and type is expected. + // If is expected, we remove it from both replica_desc and locality_desc. + // If is not expected, reserve this replica in replica_desc and locality_desc, + // let do_generate_locality_task() generate certain tasks by referencing replica_desc and locality_desc later. + // + // We regard a replica is expected if these rules below all satisfied: + // (rule 1) this replica's unit is in pool + // (rule 2) this replica's unit is in active status + // (rule 3) the server of the replica is the same as the server of the unit it belongs + // (rule 4) the type of this replica is the same as locality described + // (rule 5) the memstore_percent is the same as locality described + // (rule 6) the remained replica number described in locality is not 0 + // + // Rule 2 can ensure not removing replica on active unit when another unit is in deleting status + // Rule 3 can ensure not removing migrate dest replica when source replica and dest replica both exists in member_list(learner_list) + // + // Under the rules described above, consider this case: + // This replica is migrate source replica or the unit it belongs is deleting AND dest replica not exist yet. + // This replica can remained in replica_desc and locality_desc, because one of those rules not satisfied. + // BUT we should treat this replica is expected and remove it from replica_desc and locality_desc anyway. + // Because we want migrate_unit() and shrink_resource_pool() to handle this situation, DO NOT let locality_alignment generate tasks int ret = OB_SUCCESS; share::ObLSReplica *replica = nullptr; DRServerStatInfo *server_stat_info = nullptr; @@ -422,13 +443,13 @@ int ObDRWorker::LocalityAlignment::try_remove_match( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(replica_stat_desc), K(index), "replica_stat_map_count", replica_stat_map_.count()); - } else if (OB_UNLIKELY(nullptr == (replica = replica_stat_desc.replica_))) { + } else if (OB_ISNULL(replica = replica_stat_desc.replica_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("replica ptr is null", KR(ret), K(replica_stat_desc)); - } else if (OB_UNLIKELY(nullptr == (server_stat_info = replica_stat_desc.server_stat_info_))) { + } else if (OB_ISNULL(server_stat_info = replica_stat_desc.server_stat_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("server stat info ptr is null", KR(ret)); - } else if (OB_UNLIKELY(nullptr == (unit_stat_info = replica_stat_desc.unit_stat_info_))) { + } else if (OB_ISNULL(unit_stat_info = replica_stat_desc.unit_stat_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("server stat info ptr is null", KR(ret)); } else { @@ -436,20 +457,65 @@ int ObDRWorker::LocalityAlignment::try_remove_match( ReplicaDescArray *zone_replica_desc = nullptr; int tmp_ret = locality_map_.get_refactored(zone, zone_replica_desc); if (OB_HASH_NOT_EXIST == tmp_ret) { - // zone not exist, not match + // zone not exist in locality, not match } else if (OB_SUCCESS == tmp_ret) { if (OB_ISNULL(zone_replica_desc)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("zone replica desc ptr is null", KR(ret), K(zone)); } else { + bool has_correct_dest_replica = false; + if (replica->get_server() != unit_stat_info->get_unit_info().unit_.server_ + || !unit_stat_info->get_unit_info().unit_.is_active_status()) { + // this replica is migrating or unit is deleting, check whether has a correct dest replica + LOG_TRACE("try to check whether has dest replica", KPC(replica), KPC(unit_stat_info)); + const int64_t map_count = replica_stat_map_.count(); + for (int64_t i = map_count - 1; OB_SUCC(ret) && i >= 0; --i) { + ReplicaStatDesc &replica_stat_desc_to_compare = replica_stat_map_.at(i); + if (OB_UNLIKELY(!replica_stat_desc_to_compare.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("replica stat desc unexpected", KR(ret), K(replica_stat_desc_to_compare)); + } else if (OB_ISNULL(replica_stat_desc_to_compare.unit_stat_info_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid argument", KR(ret), K(replica_stat_desc_to_compare)); + } else if (replica->get_zone() != replica_stat_desc_to_compare.replica_->get_zone()) { + // not the same zone, just skip + } else if (replica->is_in_service() + && replica_stat_desc_to_compare.replica_->get_replica_type() == replica->get_replica_type() + && replica_stat_desc_to_compare.replica_->get_server() != replica->get_server() + && (replica_stat_desc_to_compare.replica_->get_server() == unit_stat_info->get_unit_info().unit_.server_ + || replica_stat_desc_to_compare.replica_->get_server() == replica_stat_desc_to_compare.unit_stat_info_->get_unit_info().unit_.server_) + && replica_stat_desc_to_compare.unit_stat_info_->get_unit_info().unit_.is_active_status()) { + // A replica is a correct dest replica if these conditions above all satisfied + // (1) replica is in member_list(learner_lsit) + // (2) replica type is expected + // (3) replica is not on deleting unit + // (4) replica is on the server the same as its own unit (a unit migrate task triggered expected dest replica) + // OR replica is on the server the same as source replica's unit (a shrink resource task triggerd expected dest replica) + has_correct_dest_replica = true; + break; + } else { + LOG_TRACE("dest replica not match", + "replica_type_to_compare", replica_stat_desc_to_compare.replica_->get_replica_type(), + "replica_type", replica->get_replica_type(), + "server_to_compare", replica_stat_desc_to_compare.replica_->get_server(), + "server", replica->get_server(), + "server_with_unit", unit_stat_info->get_unit_info().unit_.server_, + "server_with_unit_to_compare", replica_stat_desc_to_compare.unit_stat_info_->get_unit_info().unit_.server_, + "unit_status_is_active", replica_stat_desc_to_compare.unit_stat_info_->get_unit_info().unit_.is_active_status()); + } + } + } + for (int64_t i = zone_replica_desc->count() - 1; OB_SUCC(ret) && i >= 0; --i) { bool found = false; ReplicaDesc &replica_desc = zone_replica_desc->at(i); if (unit_stat_info->is_in_pool() - && server_stat_info->get_server() == unit_stat_info->get_unit_info().unit_.server_ && replica->get_replica_type() == replica_desc.replica_type_ && replica->get_memstore_percent() == replica_desc.memstore_percent_ - && replica_desc.replica_num_ > 0) { + && replica_desc.replica_num_ > 0 + && (!has_correct_dest_replica + || (unit_stat_info->get_unit_info().unit_.is_active_status() + && server_stat_info->get_server() == unit_stat_info->get_unit_info().unit_.server_))) { found = true; if (OB_FAIL(replica_stat_map_.remove(index))) { LOG_WARN("fail to remove from stat map", KR(ret)); @@ -463,23 +529,6 @@ int ObDRWorker::LocalityAlignment::try_remove_match( break; } } - if (OB_SUCC(ret) - && !found - && replica->get_replica_type() == replica_desc.replica_type_ - && replica->get_memstore_percent() == replica_desc.memstore_percent_ - && replica_desc.replica_num_ > 0) { - if (OB_FAIL(replica_stat_map_.remove(index))) { - LOG_WARN("fail to remove from stat map", KR(ret)); - } else if (FALSE_IT(--replica_desc.replica_num_)) { - // shall never be here - } else if (replica_desc.replica_num_ > 0) { - // bypass - } else if (OB_FAIL(zone_replica_desc->remove(i))) { - LOG_WARN("fail to remove element", KR(ret)); - } else { - break; - } - } } } } else { @@ -927,7 +976,7 @@ int ObDRWorker::LocalityAlignment::generate_type_transform_task( } else { void *raw_ptr = nullptr; TypeTransformLATask *task = nullptr; - ObLSReplica *replica = replica_stat_desc.replica_; + share::ObLSReplica *replica = replica_stat_desc.replica_; DRUnitStatInfo *unit_stat_info = replica_stat_desc.unit_stat_info_; if (OB_UNLIKELY(nullptr == replica || nullptr == unit_stat_info)) { ret = OB_ERR_UNEXPECTED; @@ -1043,54 +1092,9 @@ int ObDRWorker::LocalityAlignment::build() LOG_WARN("fail to generate locality task", KR(ret)); } else if (OB_FAIL(dr_ls_info_.get_tenant_id(tenant_id))) { LOG_WARN("fail to get tenant id", KR(ret), K(tenant_id)); - } else if (OB_FAIL(unit_set_.create(UNIT_SET_BUCKET_NUM))) { - LOG_WARN("fail to create unit set", KR(ret)); - } else if (OB_FAIL(init_unit_set(unit_set_))) { - LOG_WARN("fail to init unit set", KR(ret)); - } else if (OB_FAIL(unit_provider_.init(gen_user_tenant_id(tenant_id), unit_mgr_))) { - LOG_WARN("fail to init unit provider", KR(ret), K(tenant_id)); - } - return ret; -} - -int ObDRWorker::LocalityAlignment::init_unit_set( - common::hash::ObHashSet &unit_set) -{ - int ret = OB_SUCCESS; - int64_t replica_cnt = 0; - if (OB_FAIL(dr_ls_info_.get_replica_cnt(replica_cnt))) { - LOG_WARN("fail to get replica cnt", KR(ret)); - } else { - for (int64_t index = 0; OB_SUCC(ret) && index < replica_cnt; ++index) { - share::ObLSReplica *ls_replica = nullptr; - DRServerStatInfo *server_stat_info = nullptr; - DRUnitStatInfo *unit_stat_info = nullptr; - DRUnitStatInfo *unit_in_group_stat_info = nullptr; - if (OB_FAIL(dr_ls_info_.get_replica_stat( - index, - ls_replica, - server_stat_info, - unit_stat_info, - unit_in_group_stat_info))) { - LOG_WARN("fail to get replica stat", KR(ret)); - } else if (OB_UNLIKELY(nullptr == ls_replica - || nullptr == server_stat_info - || nullptr == unit_stat_info - || nullptr == unit_in_group_stat_info)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("replica stat unexpected", KR(ret), - KP(ls_replica), - KP(server_stat_info), - KP(unit_stat_info), - KP(unit_in_group_stat_info)); - } else if ((ObReplicaTypeCheck::is_paxos_replica_V2(ls_replica->get_replica_type()) - && ls_replica->get_in_member_list()) - || (!ObReplicaTypeCheck::is_paxos_replica_V2(ls_replica->get_replica_type()))) { - if (OB_FAIL(unit_set.set_refactored(unit_stat_info->get_unit_info().unit_.unit_id_))) { - LOG_WARN("fail to set refactored", KR(ret)); - } - } - } + } else if (OB_FAIL(unit_provider_.init(gen_user_tenant_id(tenant_id), + dr_ls_info_, unit_mgr_))) { + LOG_WARN("fail to init unit provider", KR(ret), K(tenant_id), K_(dr_ls_info)); } return ret; } @@ -1157,7 +1161,7 @@ int ObDRWorker::LocalityAlignment::try_review_add_replica_task( found = false; share::ObUnitInfo unit_info; const common::ObZone &zone = my_task->zone_; - int tmp_ret = unit_provider.get_unit(zone, ls_status_info->unit_group_id_, unit_info); + int tmp_ret = unit_provider.allocate_unit(zone, ls_status_info->unit_group_id_, unit_info); if (OB_ITER_END == tmp_ret) { // bypass } else if (OB_SUCCESS == tmp_ret) { @@ -1391,7 +1395,7 @@ int ObDRWorker::LocalityAlignment::try_get_readonly_all_server_locality_alignmen LOG_WARN("ls status info ptr is null", KR(ret), KP(ls_status_info)); } else { share::ObUnitInfo unit_info; - int tmp_ret = unit_provider.get_unit(zone, ls_status_info->unit_group_id_, unit_info); + int tmp_ret = unit_provider.allocate_unit(zone, ls_status_info->unit_group_id_, unit_info); if (OB_ITER_END == tmp_ret) { // bypass } else if (OB_SUCCESS == tmp_ret) { @@ -1404,9 +1408,6 @@ int ObDRWorker::LocalityAlignment::try_get_readonly_all_server_locality_alignmen add_replica_task_.orig_paxos_replica_number_ = curr_paxos_replica_number_; add_replica_task_.paxos_replica_number_ = curr_paxos_replica_number_; task = &add_replica_task_; - if (OB_FAIL(unit_set_.set_refactored(unit_info.unit_.unit_id_))) { - LOG_WARN("fail to set refactored", KR(ret)); - } break; } else { ret = tmp_ret; @@ -1447,19 +1448,77 @@ int ObDRWorker::LocalityAlignment::get_next_locality_alignment_task( int ObDRWorker::UnitProvider::init( const uint64_t tenant_id, + DRLSInfo &dr_ls_info, ObUnitManager *unit_mgr) { int ret = OB_SUCCESS; + int64_t replica_cnt = 0; if (OB_UNLIKELY(inited_)) { ret = OB_INIT_TWICE; LOG_WARN("init twice", KR(ret)); } else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || nullptr == unit_mgr)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(tenant_id), KP(unit_mgr)); + LOG_WARN("invalid argument", KR(ret), + K(tenant_id), + KP(unit_mgr)); + } else if (OB_FAIL(dr_ls_info.get_replica_cnt(replica_cnt))) { + LOG_WARN("failed to get replica count", KR(ret)); } else { - tenant_id_ = tenant_id; - unit_mgr_ = unit_mgr; - inited_ = true; + const int64_t hash_count = max(replica_cnt, 1); + if (OB_FAIL(unit_set_.create(hash::cal_next_prime(hash_count)))) { + LOG_WARN("failed to create unit set", KR(ret), K(replica_cnt), K(hash_count)); + } else if (OB_FAIL(init_unit_set(dr_ls_info))) { + LOG_WARN("failed to init unit set", KR(ret), K(dr_ls_info)); + } else { + tenant_id_ = tenant_id; + unit_mgr_ = unit_mgr; + inited_ = true; + } + } + return ret; +} + +int ObDRWorker::UnitProvider::init_unit_set( + DRLSInfo &dr_ls_info) +{ + int ret = OB_SUCCESS; + int64_t replica_cnt = 0; + if (OB_UNLIKELY(inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret)); + } else if (OB_FAIL(dr_ls_info.get_replica_cnt(replica_cnt))) { + LOG_WARN("fail to get replica cnt", KR(ret)); + } else { + for (int64_t index = 0; OB_SUCC(ret) && index < replica_cnt; ++index) { + share::ObLSReplica *ls_replica = nullptr; + DRServerStatInfo *server_stat_info = nullptr; + DRUnitStatInfo *unit_stat_info = nullptr; + DRUnitStatInfo *unit_in_group_stat_info = nullptr; + if (OB_FAIL(dr_ls_info.get_replica_stat( + index, + ls_replica, + server_stat_info, + unit_stat_info, + unit_in_group_stat_info))) { + LOG_WARN("fail to get replica stat", KR(ret)); + } else if (OB_UNLIKELY(nullptr == ls_replica + || nullptr == server_stat_info + || nullptr == unit_stat_info + || nullptr == unit_in_group_stat_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("replica stat unexpected", KR(ret), + KP(ls_replica), + KP(server_stat_info), + KP(unit_stat_info), + KP(unit_in_group_stat_info)); + } else if ((ObReplicaTypeCheck::is_paxos_replica_V2(ls_replica->get_replica_type()) + && ls_replica->get_in_member_list()) + || (!ObReplicaTypeCheck::is_paxos_replica_V2(ls_replica->get_replica_type()))) { + if (OB_FAIL(unit_set_.set_refactored(unit_stat_info->get_unit_info().unit_.unit_id_))) { + LOG_WARN("fail to set refactored", KR(ret)); + } + } + } } return ret; } @@ -1468,6 +1527,7 @@ int ObDRWorker::UnitProvider::inner_get_valid_unit_( const common::ObZone &zone, const common::ObArray &unit_array, share::ObUnitInfo &output_unit_info, + const bool &force_get, bool &found) { int ret = OB_SUCCESS; @@ -1486,31 +1546,42 @@ int ObDRWorker::UnitProvider::inner_get_valid_unit_( const share::ObUnitInfo &unit_info = unit_array.at(i); const uint64_t unit_id = unit_info.unit_.unit_id_; int hash_ret = OB_SUCCESS; + bool server_and_unit_status_is_valid = true; if (unit_info.unit_.zone_ != zone) { // bypass, because we do not support operation between different zones - } else if (OB_FAIL(SVR_TRACER.check_server_active(unit_info.unit_.server_, server_is_active))) { - LOG_WARN("fail to check server active", KR(ret), "server", unit_info.unit_.server_); - } else if (!server_is_active) { - FLOG_INFO("server is not active", "server", unit_info.unit_.server_, K(server_is_active)); - } else if (!unit_info.unit_.is_active_status()) { - FLOG_INFO("unit status is not normal", K(unit_info)); - } else if (OB_HASH_EXIST == (hash_ret = unit_set_.exist_refactored(unit_id))) { - FLOG_INFO("unit existed", K(unit_id)); - } else if (OB_HASH_NOT_EXIST != hash_ret) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("exist refactored failed", KR(ret), KR(hash_ret)); - } else if (OB_FAIL(output_unit_info.assign(unit_info))) { - LOG_WARN("fail to assign unit info", KR(ret), K(unit_info)); } else { - found = true; - break; + if (!force_get) { + if (OB_FAIL(SVR_TRACER.check_server_active(unit_info.unit_.server_, server_is_active))) { + LOG_WARN("fail to check server active", KR(ret), "server", unit_info.unit_.server_); + } else if (!server_is_active) { + server_and_unit_status_is_valid = false; + FLOG_INFO("server is not active", "server", unit_info.unit_.server_, K(server_is_active)); + } else if (!unit_info.unit_.is_active_status()) { + server_and_unit_status_is_valid = false; + FLOG_INFO("unit status is not normal", K(unit_info)); + } else { + server_and_unit_status_is_valid = true; + } + } + + if (OB_FAIL(ret) || !server_and_unit_status_is_valid) { + } else if (OB_HASH_EXIST == (hash_ret = unit_set_.set_refactored(unit_id, 0))) { + FLOG_INFO("unit existed", K(unit_id)); + } else if (OB_FAIL(hash_ret)) { + LOG_WARN("set refactored failed", KR(ret), KR(hash_ret)); + } else if (OB_FAIL(output_unit_info.assign(unit_info))) { + LOG_WARN("fail to assign unit info", KR(ret), K(unit_info)); + } else { + found = true; + break; + } } } } return ret; } -int ObDRWorker::UnitProvider::get_unit( +int ObDRWorker::UnitProvider::allocate_unit( const common::ObZone &zone, const uint64_t unit_group_id, share::ObUnitInfo &unit_info) @@ -1522,21 +1593,23 @@ int ObDRWorker::UnitProvider::get_unit( } else { common::ObArray unit_array; bool found = false; + bool force_get = true; // if unit_group_id is given, just allocate unit belongs to this unit group // 1. if unit_group_id is valid, try get valid unit in this unit group if (unit_group_id > 0) { + force_get = true; if (OB_FAIL(unit_mgr_->get_unit_group(tenant_id_, unit_group_id, unit_array))) { LOG_WARN("fail to get unit group", KR(ret), K(tenant_id_), K(unit_group_id)); - } else if (OB_FAIL(inner_get_valid_unit_(zone, unit_array, unit_info, found))) { - LOG_WARN("fail to get valid unit from certain unit group", KR(ret), K(zone), K(unit_array)); + } else if (OB_FAIL(inner_get_valid_unit_(zone, unit_array, unit_info, force_get, found))) { + LOG_WARN("fail to get valid unit from certain unit group", KR(ret), K(zone), K(unit_array), K(force_get)); } - } - // 2. if unit_group_id = 0 or no valid unit foudn in certain unit group, try get from all units - if (OB_SUCC(ret) && !found) { + } else { + // 2. if unit_group_id = 0, try get from all units unit_array.reset(); + force_get = false; if (OB_FAIL(unit_mgr_->get_all_unit_infos_by_tenant(tenant_id_, unit_array))) { LOG_WARN("fail to get ll unit infos by tenant", KR(ret), K(tenant_id_)); - } else if (OB_FAIL(inner_get_valid_unit_(zone, unit_array, unit_info, found))) { - LOG_WARN("fail to get valid unit from all units in tenant", KR(ret), K(zone), K(unit_array)); + } else if (OB_FAIL(inner_get_valid_unit_(zone, unit_array, unit_info, force_get, found))) { + LOG_WARN("fail to get valid unit from all units in tenant", KR(ret), K(zone), K(unit_array), K(force_get)); } } if (OB_SUCC(ret) && !found) { @@ -2540,6 +2613,7 @@ int ObDRWorker::generate_replicate_to_unit_and_push_into_task_manager( const ObReplicaMember &src_member, const ObReplicaMember &data_source, const int64_t &old_paxos_replica_number, + const char* task_comment, int64_t &acc_dr_task) { int ret = OB_SUCCESS; @@ -2547,6 +2621,9 @@ int ObDRWorker::generate_replicate_to_unit_and_push_into_task_manager( if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(task_comment)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("task comment is null", KR(ret)); } else if (OB_FAIL(migrate_task.build( task_key, tenant_id, @@ -2559,7 +2636,7 @@ int ObDRWorker::generate_replicate_to_unit_and_push_into_task_manager( obrpc::ObAdminClearDRTaskArg::TaskType::AUTO, skip_change_member_list, ObDRTaskPriority::HIGH_PRI, - ObString(drtask::REPLICATE_REPLICA), + task_comment, dst_replica, src_member, data_source, @@ -2595,7 +2672,6 @@ int ObDRWorker::try_replicate_to_unit( } else { for (int64_t index = 0; OB_SUCC(ret) && index < replica_cnt; ++index) { bool need_generate = false; - bool can_generate = false; share::ObLSReplica *ls_replica = nullptr; DRServerStatInfo *server_stat_info = nullptr; DRUnitStatInfo *unit_stat_info = nullptr; @@ -2610,85 +2686,16 @@ int ObDRWorker::try_replicate_to_unit( need_generate))) { LOG_WARN("fail to check need generate replicate to unit task", KR(ret)); } else if (need_generate) { - uint64_t tenant_id; - share::ObLSID ls_id; - share::ObTaskId task_id; - ObReplicaMember data_source; - int64_t data_size = 0; - bool skip_change_member_list = false; - ObDstReplica dst_replica; - int64_t old_paxos_replica_number; - const bool need_check_has_leader_while_remove_replica = false; - const bool is_high_priority_task = true; ObReplicaMember dst_member(unit_stat_info->get_unit_info().unit_.server_, ObTimeUtility::current_time(), ls_replica->get_replica_type(), ls_replica->get_memstore_percent()); - ObReplicaMember src_member(ls_replica->get_server(), - ls_replica->get_member_time_us(), - ls_replica->get_replica_type(), - ls_replica->get_memstore_percent()); - if (OB_FAIL(construct_extra_infos_to_build_migrate_task( - dr_ls_info, - *ls_replica, - *unit_stat_info, - *unit_in_group_stat_info, - dst_member, - src_member, - tenant_id, - ls_id, - task_id, - data_source, - data_size, - dst_replica, - skip_change_member_list, - old_paxos_replica_number))) { - LOG_WARN("fail to construct extra infos to build migrate task", KR(ret)); - } else if (only_for_display) { - ObLSReplicaTaskDisplayInfo display_info; - if (OB_FAIL(display_info.init( - tenant_id, - ls_id, - ObDRTaskType::LS_MIGRATE_REPLICA, - ObDRTaskPriority::HIGH_PRI, - unit_stat_info->get_unit_info().unit_.server_, - ls_replica->get_replica_type(), - old_paxos_replica_number, - ls_replica->get_server(), - ls_replica->get_replica_type(), - old_paxos_replica_number, - unit_stat_info->get_unit_info().unit_.server_, - ObString(drtask::REPLICATE_REPLICA)))) { - LOG_WARN("fail to init a ObLSReplicaTaskDisplayInfo", KR(ret)); - } else if (OB_FAIL(add_display_info(display_info))) { - LOG_WARN("fail to add display info", KR(ret), K(display_info)); - } else { - LOG_INFO("success to add display info", KR(ret), K(display_info)); - } - } else if (OB_FAIL(check_can_generate_task( - acc_dr_task, - need_check_has_leader_while_remove_replica, - is_high_priority_task, - ls_replica->get_server(), - dr_ls_info, - task_key, - can_generate))) { - LOG_WARN("fail to check can generate replicate to unit task", KR(ret)); - } else if (can_generate) { - if (OB_FAIL(generate_replicate_to_unit_and_push_into_task_manager( - task_key, - tenant_id, - ls_id, - task_id, - data_size, - skip_change_member_list, - dst_replica, - src_member, - data_source, - old_paxos_replica_number, - acc_dr_task))) { - LOG_WARN("fail to generate replicate to unit task", KR(ret)); - } + if (OB_FAIL(generate_migrate_ls_task( + only_for_display, drtask::REPLICATE_REPLICA, *ls_replica, + *server_stat_info, *unit_stat_info, *unit_in_group_stat_info, + dst_member, dr_ls_info, acc_dr_task))) { + LOG_WARN("failed to generate migrate ls task", KR(ret), K(dst_member), + K(only_for_display), KPC(ls_replica)); } } } @@ -2697,6 +2704,79 @@ int ObDRWorker::try_replicate_to_unit( return ret; } +int ObDRWorker::generate_migrate_ls_task( + const bool only_for_display, + const char* task_comment, + const share::ObLSReplica &ls_replica, + const DRServerStatInfo &server_stat_info, + const DRUnitStatInfo &unit_stat_info, + const DRUnitStatInfo &unit_in_group_stat_info, + const ObReplicaMember &dst_member, + DRLSInfo &dr_ls_info, + int64_t &acc_dr_task) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!ls_replica.is_valid() || !dst_member.is_valid()) + || OB_ISNULL(task_comment)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), KP(task_comment), K(ls_replica)); + } else { + ObDRTaskKey task_key; + bool task_exist = false; + uint64_t tenant_id; + share::ObLSID ls_id; + share::ObTaskId task_id; + ObReplicaMember data_source; + int64_t data_size = 0; + bool skip_change_member_list = false; + ObDstReplica dst_replica; + int64_t old_paxos_replica_number; + const bool need_check_has_leader_while_remove_replica = false; + const bool is_high_priority_task = true; + bool can_generate = false; + ObReplicaMember src_member( + ls_replica.get_server(), ls_replica.get_member_time_us(), + ls_replica.get_replica_type(), ls_replica.get_memstore_percent()); + if (OB_FAIL(construct_extra_infos_to_build_migrate_task( + dr_ls_info, ls_replica, unit_stat_info, unit_in_group_stat_info, + dst_member, src_member, tenant_id, ls_id, task_id, data_source, + data_size, dst_replica, skip_change_member_list, + old_paxos_replica_number))) { + LOG_WARN("fail to construct extra infos to build migrate task", KR(ret)); + } else if (only_for_display) { + ObLSReplicaTaskDisplayInfo display_info; + if (OB_FAIL(display_info.init( + tenant_id, ls_id, ObDRTaskType::LS_MIGRATE_REPLICA, + ObDRTaskPriority::HIGH_PRI, + unit_stat_info.get_unit_info().unit_.server_, + ls_replica.get_replica_type(), old_paxos_replica_number, + ls_replica.get_server(), ls_replica.get_replica_type(), + old_paxos_replica_number, + unit_stat_info.get_unit_info().unit_.server_, + task_comment))) { + LOG_WARN("fail to init a ObLSReplicaTaskDisplayInfo", KR(ret)); + } else if (OB_FAIL(add_display_info(display_info))) { + LOG_WARN("fail to add display info", KR(ret), K(display_info)); + } else { + LOG_INFO("success to add display info", KR(ret), K(display_info)); + } + } else if (OB_FAIL(check_can_generate_task( + acc_dr_task, need_check_has_leader_while_remove_replica, + is_high_priority_task, server_stat_info.get_server(), dr_ls_info, + task_key, can_generate))) { + LOG_WARN("fail to check can generate replicate to unit task", KR(ret)); + } else if (can_generate) { + if (OB_FAIL(generate_replicate_to_unit_and_push_into_task_manager( + task_key, tenant_id, ls_id, task_id, data_size, + skip_change_member_list, dst_replica, src_member, data_source, + old_paxos_replica_number, task_comment, acc_dr_task))) { + LOG_WARN("fail to generate replicate to unit task", KR(ret)); + } + } + } + return ret; +} + int ObDRWorker::try_generate_remove_replica_locality_alignment_task( DRLSInfo &dr_ls_info, const ObDRTaskKey &task_key, @@ -3303,9 +3383,601 @@ int ObDRWorker::try_shrink_resource_pools( int64_t &acc_dr_task) { int ret = OB_SUCCESS; - UNUSED(only_for_display); - UNUSED(dr_ls_info); - UNUSED(acc_dr_task); + int64_t replica_cnt = 0; + const share::ObLSStatusInfo *ls_status_info = NULL; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(config_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("config_ ptr is null", KR(ret), KP(config_)); + } else if (!config_->is_rereplication_enabled()) { + // bypass + } else if (!dr_ls_info.has_leader()) { + LOG_WARN("has no leader, maybe not report yet", + KR(ret), K(dr_ls_info)); + } else if (dr_ls_info.get_paxos_replica_number() <= 0) { + LOG_WARN("paxos_replica_number is invalid, maybe not report yet", + KR(ret), K(dr_ls_info)); + } else if (OB_FAIL(dr_ls_info.get_replica_cnt(replica_cnt))) { + LOG_WARN("fail to get replica cnt", KR(ret), K(dr_ls_info)); + } else if (OB_FAIL(dr_ls_info.get_ls_status_info(ls_status_info))) { + LOG_WARN("failed to get ls status info", KR(ret), K(dr_ls_info)); + } else if (OB_ISNULL(ls_status_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ls status info", KR(ret)); + } else { + ObDRWorker::UnitProvider unit_provider; + const uint64_t tenant_id = ls_status_info->tenant_id_; + if (OB_FAIL(unit_provider.init(gen_user_tenant_id(tenant_id), dr_ls_info, + unit_mgr_))) { + LOG_WARN("fail to init unit provider", KR(ret), K(tenant_id), K(dr_ls_info)); + } + for (int64_t index = 0; OB_SUCC(ret) && index < replica_cnt; ++index) { + share::ObLSReplica *ls_replica = nullptr; + DRServerStatInfo *server_stat_info = nullptr; + DRUnitStatInfo *unit_stat_info = nullptr; + DRUnitStatInfo *unit_in_group_stat_info = nullptr; + bool need_generate = false; + bool is_unit_in_group_related = false; + if (OB_FAIL(dr_ls_info.get_replica_stat( + index, + ls_replica, + server_stat_info, + unit_stat_info, + unit_in_group_stat_info))) { + LOG_WARN("fail to get replica stat", KR(ret), K(index)); + } else if (OB_ISNULL(ls_replica) + || OB_ISNULL(server_stat_info) + || OB_ISNULL(unit_stat_info) + || OB_ISNULL(unit_in_group_stat_info) + || (unit_stat_info->is_in_pool() && OB_ISNULL(unit_stat_info->get_server_stat())) + || (unit_in_group_stat_info->is_in_pool() && OB_ISNULL(unit_in_group_stat_info->get_server_stat()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("replica stat unexpected", + KR(ret), + KP(ls_replica), + KP(server_stat_info), + KP(unit_stat_info), + KP(unit_in_group_stat_info)); + } else if (REPLICA_STATUS_NORMAL == ls_replica->get_replica_status() + && share::ObUnit::UNIT_STATUS_DELETING == unit_stat_info->get_unit_info().unit_.status_) { + // replica is still in member_list, but unit is in DELETING status + // If this is a duplicate log stream + // 1.1 for R-replica: execute remove_learner task directly + // 1.2 for F-replica: try to execute migrate-replica first, + // if migrate-replica task can not generate then try to type_transform another R to F + // If this is a normal log stream + // 2.1 try to execute migrate-replica task for both R-replica and F-replica + if (dr_ls_info.is_duplicate_ls()) { + if (REPLICA_TYPE_READONLY == ls_replica->get_replica_type()) { + // 1.1 try to generate and execute remove learner task + if (OB_FAIL(try_remove_readonly_replica_for_deleting_unit_( + *ls_replica, + only_for_display, + dr_ls_info, + acc_dr_task))) { + LOG_WARN("fail to try remove readonly replica for deleting unit", KPC(ls_replica), + K(only_for_display), K(dr_ls_info), K(acc_dr_task)); + } + } else if (REPLICA_TYPE_FULL == ls_replica->get_replica_type()) { + // 1.2 try to generate and execute migrate replica task + int64_t previous_acc_dr_task = acc_dr_task; // to check whether migrate task generated + bool migrate_task_generated = false; + if (OB_FAIL(try_migrate_replica_for_deleting_unit_( + unit_provider, + dr_ls_info, + *ls_replica, + *ls_status_info, + *server_stat_info, + *unit_stat_info, + *unit_in_group_stat_info, + only_for_display, + acc_dr_task))) { + LOG_WARN("fail to try migrate replica for deleting unit", KR(ret), K(dr_ls_info), + KPC(ls_replica), KPC(ls_status_info), KPC(server_stat_info), + KPC(unit_stat_info), KPC(unit_in_group_stat_info), K(only_for_display)); + } else if (FALSE_IT(migrate_task_generated = acc_dr_task != previous_acc_dr_task)) { + // 1.2 A migrate task already generated, do nothing. + // If migrate-task not generated, try to do type transform + } else if (OB_FAIL(try_type_transform_for_deleting_unit_( + dr_ls_info, + *ls_replica, + only_for_display, + acc_dr_task))) { + LOG_WARN("fail to try type transform for deleting unit", KR(ret), K(dr_ls_info), + KPC(ls_replica), K(only_for_display)); + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("unexpected replica type", KR(ret), KPC(ls_replica)); + } + } else { + // generate task for normal log stream replica + if (0 == ls_status_info->ls_group_id_ + || ls_status_info->unit_group_id_ != unit_stat_info->get_unit_info().unit_.unit_group_id_) { + //If the Unit Group is in the DELETING status, we need to migrate out the LS that do not belong to that Unit Group. + //LS belonging to this Unit Group will be automatically processed by Balance module + // 2.1 try generate and execute migrate replica for normal log stream + if (OB_FAIL(try_migrate_replica_for_deleting_unit_( + unit_provider, + dr_ls_info, + *ls_replica, + *ls_status_info, + *server_stat_info, + *unit_stat_info, + *unit_in_group_stat_info, + only_for_display, + acc_dr_task))) { + LOG_WARN("fail to try migrate replica for deleting unit", KR(ret), K(dr_ls_info), + KPC(ls_replica), KPC(ls_status_info), KPC(server_stat_info), + KPC(unit_stat_info), KPC(unit_in_group_stat_info), K(only_for_display)); + } + } + } + } + }//end for each ls replica + } + LOG_INFO("finish try shrink resource pool", KR(ret), K(acc_dr_task)); + return ret; +} + +int ObDRWorker::try_remove_readonly_replica_for_deleting_unit_( + const share::ObLSReplica &ls_replica, + const bool &only_for_display, + DRLSInfo &dr_ls_info, + int64_t &acc_dr_task) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!ls_replica.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_replica)); + } else { + share::ObTaskId task_id; + int64_t new_paxos_replica_number; + int64_t old_paxos_replica_number; + common::ObAddr leader_addr; + const common::ObAddr source_server; // not useful + const bool need_check_has_leader_while_remove_replica = false; + const bool is_high_priority_task = true; + const int64_t memstore_percent = 100; + ObDRTaskKey task_key; + bool can_generate = false; + uint64_t tenant_id = OB_INVALID_TENANT_ID; + share::ObLSID ls_id; + ObDRTaskType task_type = ObDRTaskType::LS_REMOVE_NON_PAXOS_REPLICA; + ObReplicaMember remove_learner(ls_replica.get_server(), + ls_replica.get_member_time_us(), + ls_replica.get_replica_type(), + memstore_percent); + if (OB_FAIL(construct_extra_infos_to_build_remove_replica_task( + dr_ls_info, + task_id, + new_paxos_replica_number, + old_paxos_replica_number, + leader_addr, + ls_replica.get_replica_type()))) { + LOG_WARN("fail to construct extra infos to build remove replica task", KR(ret), K(dr_ls_info), K(ls_replica)); + } else if (OB_FAIL(dr_ls_info.get_ls_id(tenant_id, ls_id))) { + LOG_WARN("fail to get ls id", KR(ret), K(dr_ls_info), K(tenant_id), K(ls_id)); + } else if (only_for_display) { + // only for display, no need to execute this task + ObLSReplicaTaskDisplayInfo display_info; + if (OB_FAIL(display_info.init( + tenant_id, + ls_id, + task_type, + is_high_priority_task ? ObDRTaskPriority::HIGH_PRI : ObDRTaskPriority::LOW_PRI, + ls_replica.get_server(), + ls_replica.get_replica_type(), + new_paxos_replica_number, + source_server, + REPLICA_TYPE_MAX/*source_replica_type*/, + old_paxos_replica_number, + leader_addr, + "shrink unit task"))) { + LOG_WARN("fail to init a ObLSReplicaTaskDisplayInfo", KR(ret), K(tenant_id), K(ls_id), + K(task_type), K(ls_replica), K(new_paxos_replica_number), + K(old_paxos_replica_number), K(leader_addr)); + } else if (OB_FAIL(add_display_info(display_info))) { + LOG_WARN("fail to add display info", KR(ret), K(display_info)); + } else { + LOG_INFO("success to add display info", KR(ret), K(display_info)); + } + } else if (OB_FAIL(check_can_generate_task( + acc_dr_task, + need_check_has_leader_while_remove_replica, + is_high_priority_task, + ls_replica.get_server(), + dr_ls_info, + task_key, + can_generate))) { + LOG_WARN("fail to check can generate remove permanent offline task", KR(ret), K(acc_dr_task), + K(need_check_has_leader_while_remove_replica), K(is_high_priority_task), K(ls_replica), + K(dr_ls_info), K(task_key), K(can_generate)); + } else if (can_generate) { + ObRemoveLSReplicaTask remove_replica_task; + if (OB_FAIL(remove_replica_task.build( + task_key, + tenant_id, + ls_id, + task_id, + 0,/*schdule_time*/ + 0,/*generate_time*/ + GCONF.cluster_id, + 0/*transmit_data_size*/, + obrpc::ObAdminClearDRTaskArg::TaskType::AUTO, + false/*skip change member list*/, + ObDRTaskPriority::HIGH_PRI, + "shrink unit task", + leader_addr, + remove_learner, + old_paxos_replica_number, + new_paxos_replica_number, + ls_replica.get_replica_type()))) { + LOG_WARN("fail to build remove member task", KR(ret), K(task_key), K(tenant_id), K(ls_id), K(leader_addr), + K(remove_learner), K(old_paxos_replica_number), K(new_paxos_replica_number)); + } else if (OB_FAIL(disaster_recovery_task_mgr_->add_task(remove_replica_task))) { + LOG_WARN("fail to add task", KR(ret), K(remove_replica_task)); + } else { + acc_dr_task++; + } + } + } + return ret; +} + +int ObDRWorker::try_migrate_replica_for_deleting_unit_( + ObDRWorker::UnitProvider &unit_provider, + DRLSInfo &dr_ls_info, + const share::ObLSReplica &ls_replica, + const share::ObLSStatusInfo &ls_status_info, + const DRServerStatInfo &server_stat_info, + const DRUnitStatInfo &unit_stat_info, + const DRUnitStatInfo &unit_in_group_stat_info, + const bool &only_for_display, + int64_t &acc_dr_task) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!ls_replica.is_valid() + || !ls_status_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_replica), K(ls_status_info)); + } else { + share::ObUnitInfo dest_unit; + if (OB_FAIL(unit_provider.allocate_unit( + ls_replica.get_zone(), + ls_status_info.unit_group_id_, + dest_unit))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + LOG_INFO("can not allocate valid unit for this ls replica to do migration", + K(ls_replica), K(ls_status_info)); + } else { + LOG_WARN("failed to allocate unit for this log stream", KR(ret), + K(ls_replica), K(ls_status_info)); + } + } else { + ObReplicaMember dst_member( + dest_unit.unit_.server_, + ObTimeUtility::current_time(), + ls_replica.get_replica_type(), + ls_replica.get_memstore_percent()); + if (OB_FAIL(generate_migrate_ls_task( + only_for_display, "shrink unit task", ls_replica, + server_stat_info, unit_stat_info, + unit_in_group_stat_info, dst_member, dr_ls_info, + acc_dr_task))) { + LOG_WARN("failed to generate migrate ls task", KR(ret), + K(dst_member), K(only_for_display), K(ls_replica)); + } + } + } + return ret; +} + +int ObDRWorker::try_type_transform_for_deleting_unit_( + DRLSInfo &dr_ls_info, + const share::ObLSReplica &ls_replica, + const bool &only_for_display, + int64_t &acc_dr_task) +{ + int ret = OB_SUCCESS; + ObLSReplica target_replica; + uint64_t target_unit_id = 0; + uint64_t target_unit_group_id = 0; + bool find_a_valid_readonly_replica = false; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_FAIL(find_valid_readonly_replica_( + dr_ls_info, + ls_replica, + ls_replica.get_zone(), + target_replica, + target_unit_id, + target_unit_group_id, + find_a_valid_readonly_replica))) { + LOG_WARN("fail to find a valid readonly replica", KR(ret), K(dr_ls_info), K(ls_replica)); + } else if (!find_a_valid_readonly_replica) { + // do nothing, because no valid R-replica to do type transform + LOG_INFO("no valid readonly replica found to do type transform task for deleting unit", K(dr_ls_info), K(ls_replica)); + } else { + // try to generate type transform task + share::ObTaskId task_id; + ObDRTaskKey task_key; + uint64_t tenant_id; + share::ObLSID ls_id; + common::ObAddr leader_addr; + int64_t old_paxos_replica_number = 0; + int64_t new_paxos_replica_number = 0; + ObReplicaMember data_source; + int64_t data_size = 0; + ObDstReplica dst_replica; + bool can_generate = false; + ObReplicaMember src_member(target_replica.get_server(), + target_replica.get_member_time_us(), + target_replica.get_replica_type(), + target_replica.get_memstore_percent()); + ObReplicaMember dst_member(target_replica.get_server(), + target_replica.get_member_time_us(), + REPLICA_TYPE_FULL, + target_replica.get_memstore_percent()); + if (OB_FAIL(construct_extra_info_to_build_type_transform_task_( + dr_ls_info, + ls_replica, + dst_member, + src_member, + target_unit_id, + target_unit_group_id, + task_id, + tenant_id, + ls_id, + leader_addr, + data_source, + data_size, + dst_replica, + old_paxos_replica_number, + new_paxos_replica_number))) { + LOG_WARN("fail to construct extra info to build a type transform task", KR(ret), + K(dr_ls_info), K(ls_replica), K(dst_member), K(src_member), + K(target_unit_id), K(target_unit_group_id)); + } else if (only_for_display) { + ObLSReplicaTaskDisplayInfo display_info; + if (OB_FAIL(display_info.init( + tenant_id, + ls_id, + ObDRTaskType::LS_TYPE_TRANSFORM, + ObDRTaskPriority::HIGH_PRI, + target_replica.get_server(), + REPLICA_TYPE_FULL/*target_replica_type*/, + new_paxos_replica_number, + data_source.get_server(), + REPLICA_TYPE_READONLY/*source_replica_type*/, + old_paxos_replica_number, + leader_addr, + "shrink unit number"))) { + LOG_WARN("fail to init a ObLSReplicaTaskDisplayInfo", KR(ret), K(tenant_id), + K(ls_id), K(target_replica), K(new_paxos_replica_number), K(data_source), + K(old_paxos_replica_number), K(leader_addr)); + } else if (OB_FAIL(add_display_info(display_info))) { + LOG_WARN("fail to add display info", KR(ret), K(display_info)); + } else { + LOG_INFO("success to add display info", KR(ret), K(display_info)); + } + } else if (OB_FAIL(check_can_generate_task( + acc_dr_task, + false/*need_check_has_leader_while_remove_replica*/, + true/*is_high_priority_task*/, + target_replica.get_server(), + dr_ls_info, + task_key, + can_generate))) { + LOG_WARN("fail to check whether can generate task", KR(ret), K(acc_dr_task), + K(target_replica), K(dr_ls_info)); + } else if (!can_generate) { + LOG_INFO("can not generate type transform task"); + } else if (OB_FAIL(generate_type_transform_task_( + task_key, + tenant_id, + ls_id, + task_id, + data_size, + dst_replica, + src_member, + data_source, + old_paxos_replica_number, + new_paxos_replica_number, + acc_dr_task))) { + LOG_WARN("fail to generate type transform task", KR(ret), K(task_key), + K(tenant_id), K(ls_id), K(task_id), K(data_size), K(dst_replica), + K(src_member), K(data_source), K(old_paxos_replica_number), + K(new_paxos_replica_number), K(acc_dr_task)); + } + } + return ret; +} + +int ObDRWorker::find_valid_readonly_replica_( + DRLSInfo &dr_ls_info, + const share::ObLSReplica &exclude_replica, + const ObZone &target_zone, + share::ObLSReplica &target_replica, + uint64_t &unit_id, + uint64_t &unit_group_id, + bool &find_a_valid_readonly_replica) +{ + int ret = OB_SUCCESS; + find_a_valid_readonly_replica = false; + int64_t replica_cnt = 0; + target_replica.reset(); + unit_id = 0; + unit_group_id = 0; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret), K_(inited)); + } else if (OB_FAIL(dr_ls_info.get_replica_cnt(replica_cnt))) { + LOG_WARN("fail to get replica count", KR(ret), K(dr_ls_info)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < replica_cnt; i++) { + share::ObLSReplica *replica = nullptr; + DRServerStatInfo *server_stat_info = nullptr; + DRUnitStatInfo *unit_stat_info = nullptr; + DRUnitStatInfo *unit_in_group_stat_info = nullptr; + if (OB_FAIL(dr_ls_info.get_replica_stat( + i, + replica, + server_stat_info, + unit_stat_info, + unit_in_group_stat_info))) { + LOG_WARN("fail to get replica stat", KR(ret)); + } else if (OB_ISNULL(replica) + || OB_ISNULL(server_stat_info) + || OB_ISNULL(unit_stat_info) + || OB_ISNULL(unit_in_group_stat_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("replica related ptrs are null", KR(ret), + KP(replica), + KP(server_stat_info), + KP(unit_stat_info), + KP(unit_in_group_stat_info)); + } else if (target_zone != replica->get_zone() + || common::REPLICA_TYPE_READONLY != replica->get_replica_type() + || exclude_replica.get_server() == replica->get_server()) { + // bypass + } else if (replica->is_in_service() + && server_stat_info->is_alive() + && !server_stat_info->is_stopped() + && !replica->get_restore_status().is_restore_failed() + && unit_stat_info->get_server_stat()->is_alive() + && !unit_stat_info->get_server_stat()->is_block()) { + if (OB_FAIL(target_replica.assign(*replica))) { + LOG_WARN("fail to assign replica", KR(ret), KPC(replica)); + } else { + unit_id = unit_stat_info->get_unit_info().unit_.unit_id_; + unit_group_id = unit_stat_info->get_unit_info().unit_.unit_group_id_; + find_a_valid_readonly_replica = true; + LOG_INFO("find a valid readonly replica to do type transform", K(dr_ls_info), + K(exclude_replica), K(target_zone), K(target_replica)); + break; + } + } + } + } + return ret; +} + +int ObDRWorker::construct_extra_info_to_build_type_transform_task_( + DRLSInfo &dr_ls_info, + const share::ObLSReplica &ls_replica, + const ObReplicaMember &dst_member, + const ObReplicaMember &src_member, + const uint64_t &target_unit_id, + const uint64_t &target_unit_group_id, + share::ObTaskId &task_id, + uint64_t &tenant_id, + share::ObLSID &ls_id, + common::ObAddr &leader_addr, + ObReplicaMember &data_source, + int64_t &data_size, + ObDstReplica &dst_replica, + int64_t &old_paxos_replica_number, + int64_t &new_paxos_replica_number) +{ + int ret = OB_SUCCESS; + tenant_id = OB_INVALID_TENANT_ID; + ls_id = OB_INVALID_ID; + leader_addr.reset(); + dst_replica.reset(); + data_size = 0; + old_paxos_replica_number = 0; + new_paxos_replica_number = 0; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!ls_replica.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_replica)); + } else if (FALSE_IT(task_id.init(self_addr_))) { + //shall never be here + } else if (OB_FAIL(dr_ls_info.get_leader(leader_addr))) { + LOG_WARN("fail to get leader address", KR(ret), K(dr_ls_info)); + } else if (OB_FAIL(dr_ls_info.get_ls_id(tenant_id, ls_id))) { + LOG_WARN("fail to get tenant and ls id", KR(ret), K(dr_ls_info), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(choose_disaster_recovery_data_source( + zone_mgr_, + dr_ls_info, + dst_member, + src_member, + data_source, + data_size))) { + LOG_WARN("fail to choose disaster recovery data source", KR(ret), K(dr_ls_info), + K(dst_member), K(src_member)); + } else if (OB_FAIL(dst_replica.assign( + target_unit_id, + target_unit_group_id, + ls_replica.get_zone(), + dst_member))) { + LOG_WARN("fail to assign dst replica", KR(ret), K(target_unit_id), K(target_unit_group_id), + K(ls_replica), K(dst_member)); + } else { + old_paxos_replica_number = dr_ls_info.get_paxos_replica_number(); + new_paxos_replica_number = dr_ls_info.get_paxos_replica_number() + 1; + } + return ret; +} + +int ObDRWorker::generate_type_transform_task_( + const ObDRTaskKey &task_key, + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const share::ObTaskId &task_id, + const int64_t data_size, + const ObDstReplica &dst_replica, + const ObReplicaMember &src_member, + const ObReplicaMember &data_source, + const int64_t old_paxos_replica_number, + const int64_t new_paxos_replica_number, + int64_t &acc_dr_task) +{ + int ret = OB_SUCCESS; + ObLSTypeTransformTask type_transform_task; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret), K_(inited)); + } else if (OB_FAIL(type_transform_task.build( + task_key, + tenant_id, + ls_id, + task_id, + 0,/*schedule_time*/ + 0,/*generate_time*/ + GCONF.cluster_id, + data_size, + obrpc::ObAdminClearDRTaskArg::TaskType::AUTO, + false,/*skip change member list*/ + ObDRTaskPriority::HIGH_PRI, + "shrink unit number", + dst_replica, + src_member, + data_source, + old_paxos_replica_number, + new_paxos_replica_number))) { + LOG_WARN("fail to build type transform task", KR(ret), K(task_key), K(tenant_id), K(ls_id), + K(data_size), K(dst_replica), K(src_member), K(data_source), K(old_paxos_replica_number), + K(new_paxos_replica_number)); + } else if (OB_FAIL(disaster_recovery_task_mgr_->add_task(type_transform_task))) { + LOG_WARN("fail to add task", KR(ret), K(type_transform_task)); + } else { + LOG_INFO("success to add a ObLSTypeTransformTask to task manager", KR(ret), K(type_transform_task)); + acc_dr_task++; + } return ret; } diff --git a/src/rootserver/ob_disaster_recovery_worker.h b/src/rootserver/ob_disaster_recovery_worker.h old mode 100644 new mode 100755 index 671be185f..31baf7918 --- a/src/rootserver/ob_disaster_recovery_worker.h +++ b/src/rootserver/ob_disaster_recovery_worker.h @@ -514,27 +514,34 @@ private: class UnitProvider { public: - UnitProvider(common::hash::ObHashSet &unit_set) + UnitProvider() : inited_(false), tenant_id_(OB_INVALID_ID), unit_mgr_(nullptr), - unit_set_(unit_set) {} - int init(const uint64_t tenant_id, ObUnitManager *unit_mgr); - int get_unit( + unit_set_() {} + int init( + const uint64_t tenant_id, + DRLSInfo &dr_ls_info, + ObUnitManager *unit_mgr); + int allocate_unit( const common::ObZone &zone, const uint64_t unit_group_id, share::ObUnitInfo &unit_info); + int init_unit_set( + DRLSInfo &dr_ls_info); + private: int inner_get_valid_unit_( const common::ObZone &zone, const common::ObArray &unit_array, share::ObUnitInfo &output_unit_info, + const bool &force_get, bool &found); private: bool inited_; uint64_t tenant_id_; ObUnitManager *unit_mgr_; - common::hash::ObHashSet &unit_set_; + common::hash::ObHashSet unit_set_; }; typedef common::hash::ObHashMap< @@ -596,8 +603,6 @@ private: ReplicaDesc &replica_desc); int generate_modify_paxos_replica_number_task(); // private func for get_next_locality_alignment_task - int init_unit_set( - common::hash::ObHashSet &unit_set); int try_get_readonly_all_server_locality_alignment_task( UnitProvider &unit_provider, const LATask *&task); @@ -638,7 +643,6 @@ private: int64_t locality_paxos_replica_number_; LocalityMap locality_map_; ReplicaStatMap replica_stat_map_; - common::hash::ObHashSet unit_set_; UnitProvider unit_provider_; common::ObArenaAllocator allocator_; }; @@ -738,6 +742,17 @@ private: DRUnitStatInfo *&unit_in_group_stat_info, bool &need_generate); + int generate_migrate_ls_task( + const bool only_for_display, + const char* task_comment, + const share::ObLSReplica &ls_replica, + const DRServerStatInfo &server_stat_info, + const DRUnitStatInfo &unit_stat_info, + const DRUnitStatInfo &unit_in_group_stat_info, + const ObReplicaMember &dst_member, + DRLSInfo &dr_ls_info, + int64_t &acc_dr_task); + int construct_extra_infos_to_build_migrate_task( DRLSInfo &dr_ls_info, const share::ObLSReplica &ls_replica, @@ -765,6 +780,7 @@ private: const ObReplicaMember &src_member, const ObReplicaMember &data_source, const int64_t &old_paxos_replica_number, + const char* task_comment, int64_t &acc_dr_task); int try_locality_alignment( @@ -900,6 +916,128 @@ private: const LATask *task, int64_t &acc_dr_task); + // If unit is deleting and a R-replica of duplicate log stream is on it, + // we have to remove this replica from learner_list directly + // @params[in] ls_replica, the replica to remove + // @params[in] only_for_display, whether just to display this task + // @params[in] dr_ls_info, disaster recovery infos of this log stream + // @params[out] acc_dr_task, accumulated disaster recovery task count + int try_remove_readonly_replica_for_deleting_unit_( + const share::ObLSReplica &ls_replica, + const bool &only_for_display, + DRLSInfo &dr_ls_info, + int64_t &acc_dr_task); + + // If unit is delting and a replica is on it, + // we have to migrate this replica to another unit + // @params[in] unit_provider, allocate a valid unit to do migration + // @params[in] dr_ls_info, disaster recovery infos of this log stream + // @params[in] ls_replica, the replica to migrate + // @params[in] ls_status_info, status info of this log stream + // @params[in] server_stat_info, server info of this replica + // @params[in] unit_stat_info, unit info of this replica + // @params[in] unit_in_group_stat_info, unit group info of this log stream + // @params[in] only_for_display, whether just to display this task + // @params[out] acc_dr_task, accumulated disaster recovery task count + int try_migrate_replica_for_deleting_unit_( + ObDRWorker::UnitProvider &unit_provider, + DRLSInfo &dr_ls_info, + const share::ObLSReplica &ls_replica, + const share::ObLSStatusInfo &ls_status_info, + const DRServerStatInfo &server_stat_info, + const DRUnitStatInfo &unit_stat_info, + const DRUnitStatInfo &unit_in_group_stat_info, + const bool &only_for_display, + int64_t &acc_dr_task); + + // If unit is deleting and a F-replica of duplicate log stream is on it, + // we have to type transform another valid R-replica to F-replica + // @params[in] dr_ls_info, disaster recovery infos of this log stream + // @params[in] ls_replica, the replica to do type transform + // @params[in] only_for_display, whether just to display this task + // @params[out] acc_dr_task, accumulated disaster recovery task count + int try_type_transform_for_deleting_unit_( + DRLSInfo &dr_ls_info, + const share::ObLSReplica &ls_replica, + const bool &only_for_display, + int64_t &acc_dr_task); + + // When need to type transform a R-replica to F-replica, + // use this function to get a valid R-replica + // @params[in] dr_ls_info, disaster recovery infos of this log stream + // @params[in] exclude_replica, excluded replica + // @params[in] target_zone, which zone to scan + // @params[out] replica, the expected valid R-replica + // @params[out] unit_id, which unit does this replica belongs to + // @params[out] unit_group_id, which unit group does this replica belongs to + // @params[out] find_a_valid_readonly_replica, whether find a valid replica + int find_valid_readonly_replica_( + DRLSInfo &dr_ls_info, + const share::ObLSReplica &exclude_replica, + const ObZone &target_zone, + share::ObLSReplica &replica, + uint64_t &unit_id, + uint64_t &unit_group_id, + bool &find_a_valid_readonly_replica); + + // construct extra infos to build a type transform task + // @params[in] dr_ls_info, disaster recovery infos of this log stream + // @params[in] ls_replica, which replica to do type transform + // @params[in] dst_member, dest replica + // @params[in] src_member, source replica + // @params[in] target_unit_id, dest replica belongs to whcih unit + // @params[in] target_unit_group_id, dest replica belongs to which unit group + // @params[out] task_id, the unique task key + // @params[out] tenant_id, which tenant's task + // @params[out] ls_id, which log stream's task + // @params[out] leader_addr, leader replica address + // @params[out] data_source, data source replica + // @params[out] data_size, data_size of this replica + // @params[out] dst_replica, dest replica infos + // @params[out] old_paxos_replica_number, previous number of F-replica count + // @params[out] new_paxos_replica_number, new number of F-replica count + int construct_extra_info_to_build_type_transform_task_( + DRLSInfo &dr_ls_info, + const share::ObLSReplica &ls_replica, + const ObReplicaMember &dst_member, + const ObReplicaMember &src_member, + const uint64_t &target_unit_id, + const uint64_t &target_unit_group_id, + share::ObTaskId &task_id, + uint64_t &tenant_id, + share::ObLSID &ls_id, + common::ObAddr &leader_addr, + ObReplicaMember &data_source, + int64_t &data_size, + ObDstReplica &dst_replica, + int64_t &old_paxos_replica_number, + int64_t &new_paxos_replica_number); + + // generate a type transform and push into task manager + // @params[in] task_key, the key of this task + // @params[in] tenant_id, which tenant's task + // @params[in] ls_id, which log stream's task + // @params[in] task_id, the id of this task + // @params[in] data_size, data_size of this replica + // @params[in] dst_replica, dest replica + // @params[in] src_member, source member + // @params[in] data_source, data source replica + // @params[in] old_paxos_replica_number, previous number of F-replica count + // @params[in] new_paxos_replica_number, new number of F-replica count + // @params[out] acc_dr_task, accumulated disaster recovery task count + int generate_type_transform_task_( + const ObDRTaskKey &task_key, + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const share::ObTaskId &task_id, + const int64_t data_size, + const ObDstReplica &dst_replica, + const ObReplicaMember &src_member, + const ObReplicaMember &data_source, + const int64_t old_paxos_replica_number, + const int64_t new_paxos_replica_number, + int64_t &acc_dr_task); + private: volatile bool &stop_; bool inited_; diff --git a/src/rootserver/ob_index_builder.cpp b/src/rootserver/ob_index_builder.cpp index 5cbf5213b..a3a5edee5 100644 --- a/src/rootserver/ob_index_builder.cpp +++ b/src/rootserver/ob_index_builder.cpp @@ -36,6 +36,7 @@ #include "ob_snapshot_info_manager.h" #include "share/ob_thread_mgr.h" #include "sql/resolver/ob_resolver_utils.h" +#include "storage/ddl/ob_ddl_lock.h" #include "storage/tx/ob_ts_mgr.h" #include "storage/tx/ob_i_ts_source.h" #include "storage/tx/ob_ts_mgr.h" @@ -178,11 +179,21 @@ int ObIndexBuilder::drop_index(const ObDropIndexArg &arg, obrpc::ObDropIndexRes ObDDLOperator ddl_operator(ddl_service_.get_schema_service(), ddl_service_.get_sql_proxy()); ObDDLSQLTransaction trans(&ddl_service_.get_schema_service()); int64_t refreshed_schema_version = 0; + ObArenaAllocator allocator(lib::ObLabel("DdlTaskTmp")); + ObDDLTaskRecord task_record; + bool has_index_task = false; SMART_VAR(ObTableSchema, new_index_schema) { if (OB_FAIL(schema_guard.get_schema_version(tenant_id, refreshed_schema_version))) { LOG_WARN("failed to get tenant schema version", KR(ret), K(tenant_id)); } else if (OB_FAIL(trans.start(&ddl_service_.get_sql_proxy(), tenant_id, refreshed_schema_version))) { LOG_WARN("start transaction failed", KR(ret), K(tenant_id), K(refreshed_schema_version)); + } else if (!arg.is_inner_ && !index_table_schema->can_read_index() && OB_FAIL(ObDDLTaskRecordOperator::check_has_index_task( + trans, tenant_id, data_table_id, index_table_schema->get_table_id(), has_index_task))) { + LOG_WARN("failed to check ddl conflict", K(ret)); + } else if (has_index_task) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to drop a building or dropping index", K(ret), K(arg.is_inner_), KPC(index_table_schema)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "dropping a building or dropping index is"); } else if (OB_FAIL(ddl_service_.rename_dropping_index_name( table_schema->get_table_id(), table_schema->get_database_id(), @@ -192,12 +203,13 @@ int ObIndexBuilder::drop_index(const ObDropIndexArg &arg, obrpc::ObDropIndexRes trans, new_index_schema))) { LOG_WARN("renmae index name failed", K(ret)); - } else if (OB_FAIL(submit_drop_index_task(new_index_schema, arg, res.task_id_))) { + } else if (OB_FAIL(submit_drop_index_task(trans, *table_schema, new_index_schema, new_index_schema.get_schema_version(), arg, allocator, task_record))) { LOG_WARN("submit drop index task failed", K(ret)); } else { res.tenant_id_ = new_index_schema.get_tenant_id(); res.index_table_id_ = new_index_schema.get_table_id(); res.schema_version_ = new_index_schema.get_schema_version(); + res.task_id_ = task_record.task_id_; } } if (trans.is_started()) { @@ -208,8 +220,11 @@ int ObIndexBuilder::drop_index(const ObDropIndexArg &arg, obrpc::ObDropIndexRes } } if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; if (OB_FAIL(ddl_service_.publish_schema(tenant_id))) { LOG_WARN("fail to publish schema", K(ret), K(tenant_id)); + } else if (OB_TMP_FAIL(GCTX.root_service_->get_ddl_task_scheduler().schedule_ddl_task(task_record))) { + LOG_WARN("fail to schedule ddl task", K(tmp_ret), K(task_record)); } } } else { @@ -225,6 +240,7 @@ int ObIndexBuilder::drop_index(const ObDropIndexArg &arg, obrpc::ObDropIndexRes drop_table_arg.table_type_ = USER_INDEX; drop_table_arg.ddl_stmt_str_ = arg.ddl_stmt_str_; drop_table_arg.force_drop_ = arg.is_in_recyclebin_; + drop_table_arg.task_id_ = arg.task_id_; if (OB_FAIL(drop_table_arg.tables_.push_back(table_item))) { LOG_WARN("failed to add table item!", K(table_item), K(ret)); } else if (OB_FAIL(ddl_service_.drop_table(drop_table_arg, ddl_res))) { @@ -296,6 +312,7 @@ int ObIndexBuilder::do_create_global_index( } else if (OB_FAIL(submit_build_index_task(trans, new_arg, &new_table_schema, + nullptr/*del_data_tablet_ids*/, &index_schema, arg.parallelism_, allocator, @@ -332,6 +349,7 @@ int ObIndexBuilder::submit_build_index_task( ObMySQLTransaction &trans, const obrpc::ObCreateIndexArg &create_index_arg, const ObTableSchema *data_schema, + const ObIArray *del_data_tablet_ids, const ObTableSchema *index_schema, const int64_t parallelism, common::ObIAllocator &allocator, @@ -354,13 +372,20 @@ int ObIndexBuilder::submit_build_index_task( LOG_WARN("schema is invalid", K(ret), K(data_schema), K(index_schema)); } else if (OB_FAIL(GCTX.root_service_->get_ddl_task_scheduler().create_ddl_task(param, trans, task_record))) { LOG_WARN("submit create index ddl task failed", K(ret)); + } else if (OB_FAIL(ObDDLLock::lock_for_add_drop_index( + *data_schema, del_data_tablet_ids, *index_schema, ObTableLockOwnerID(task_record.task_id_), trans))) { + LOG_WARN("failed to lock online ddl lock", K(ret)); } return ret; } -int ObIndexBuilder::submit_drop_index_task(const ObTableSchema &index_schema, +int ObIndexBuilder::submit_drop_index_task(ObMySQLTransaction &trans, + const ObTableSchema &data_schema, + const ObTableSchema &index_schema, + const int64_t schema_version, const obrpc::ObDropIndexArg &arg, - int64_t &task_id) + common::ObIAllocator &allocator, + ObDDLTaskRecord &task_record) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!index_schema.is_valid())) { @@ -369,24 +394,21 @@ int ObIndexBuilder::submit_drop_index_task(const ObTableSchema &index_schema, } else { int64_t refreshed_schema_version = 0; const uint64_t tenant_id = index_schema.get_tenant_id(); - ObDDLTaskRecord task_record; - ObArenaAllocator allocator(lib::ObLabel("DdlTaskTmp")); ObCreateDDLTaskParam param(tenant_id, ObDDLType::DDL_DROP_INDEX, &index_schema, nullptr, 0/*object_id*/, - index_schema.get_schema_version(), + schema_version, 0/*parallelism*/, arg.consumer_group_id_, &allocator, &arg); - if (OB_FAIL(GCTX.root_service_->get_ddl_task_scheduler().create_ddl_task(param, ddl_service_.get_sql_proxy(), task_record))) { + if (OB_FAIL(GCTX.root_service_->get_ddl_task_scheduler().create_ddl_task(param, trans, task_record))) { LOG_WARN("submit create index ddl task failed", K(ret)); - } else if (OB_FAIL(GCTX.root_service_->get_ddl_task_scheduler().schedule_ddl_task(task_record))) { - LOG_WARN("fail to schedule ddl task", K(ret), K(task_record)); - } else { - task_id = task_record.task_id_; + } else if (OB_FAIL(ObDDLLock::lock_for_add_drop_index( + data_schema, nullptr/*del_data_tablet_ids*/, index_schema, ObTableLockOwnerID(task_record.task_id_), trans))) { + LOG_WARN("failed to lock online ddl lock", K(ret)); } } return ret; @@ -470,6 +492,7 @@ int ObIndexBuilder::do_create_local_index( } else if (OB_FAIL(submit_build_index_task(trans, create_index_arg, &new_table_schema, + nullptr/*del_data_tablet_ids*/, &index_schema, create_index_arg.parallelism_, allocator, diff --git a/src/rootserver/ob_index_builder.h b/src/rootserver/ob_index_builder.h index 92e18e387..a2439eaf1 100644 --- a/src/rootserver/ob_index_builder.h +++ b/src/rootserver/ob_index_builder.h @@ -78,12 +78,17 @@ public: const bool global_index_without_column_info, share::schema::ObTableSchema &index_schema); int submit_drop_index_task( + common::ObMySQLTransaction &trans, + const share::schema::ObTableSchema &data_schema, const share::schema::ObTableSchema &index_schema, + const int64_t schema_version, const obrpc::ObDropIndexArg &arg, - int64_t &task_id); + common::ObIAllocator &allocator, + ObDDLTaskRecord &task_record); int submit_build_index_task(common::ObMySQLTransaction &trans, const obrpc::ObCreateIndexArg &arg, const share::schema::ObTableSchema *data_schema, + const common::ObIArray *del_data_tablet_ids, const share::schema::ObTableSchema *index_schema, const int64_t parallelism, common::ObIAllocator &allocator, diff --git a/src/rootserver/ob_lob_meta_builder.cpp b/src/rootserver/ob_lob_meta_builder.cpp index e8e9f4b8d..69b017495 100644 --- a/src/rootserver/ob_lob_meta_builder.cpp +++ b/src/rootserver/ob_lob_meta_builder.cpp @@ -122,7 +122,11 @@ int ObLobMetaBuilder::set_basic_infos( // priority same with data table schema aux_lob_meta_schema.set_tenant_id(data_schema.get_tenant_id()); aux_lob_meta_schema.set_database_id(data_schema.get_database_id()); - aux_lob_meta_schema.set_tablegroup_id(data_schema.get_tablegroup_id()); + if (is_inner_table(data_schema.get_table_id())) { + aux_lob_meta_schema.set_tablegroup_id(data_schema.get_tablegroup_id()); + } else { + aux_lob_meta_schema.set_tablegroup_id(OB_INVALID_ID); + } aux_lob_meta_schema.set_load_type(data_schema.get_load_type()); aux_lob_meta_schema.set_def_type(data_schema.get_def_type()); aux_lob_meta_schema.set_charset_type(data_schema.get_charset_type()); diff --git a/src/rootserver/ob_lob_piece_builder.cpp b/src/rootserver/ob_lob_piece_builder.cpp index 6e95f2a24..d55b195bc 100644 --- a/src/rootserver/ob_lob_piece_builder.cpp +++ b/src/rootserver/ob_lob_piece_builder.cpp @@ -121,7 +121,11 @@ int ObLobPieceBuilder::set_basic_infos( // priority same with data table schema aux_lob_piece_schema.set_tenant_id(data_schema.get_tenant_id()); aux_lob_piece_schema.set_database_id(data_schema.get_database_id()); - aux_lob_piece_schema.set_tablegroup_id(data_schema.get_tablegroup_id()); + if (is_inner_table(data_schema.get_table_id())) { + aux_lob_piece_schema.set_tablegroup_id(data_schema.get_tablegroup_id()); + } else { + aux_lob_piece_schema.set_tablegroup_id(OB_INVALID_ID); + } aux_lob_piece_schema.set_load_type(data_schema.get_load_type()); aux_lob_piece_schema.set_def_type(data_schema.get_def_type()); aux_lob_piece_schema.set_charset_type(data_schema.get_charset_type()); diff --git a/src/rootserver/ob_ls_balance_helper.cpp b/src/rootserver/ob_ls_balance_helper.cpp new file mode 100644 index 000000000..b0430cf16 --- /dev/null +++ b/src/rootserver/ob_ls_balance_helper.cpp @@ -0,0 +1,889 @@ +/** + * Copyright (c) 2021 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. + */ +#define USING_LOG_PREFIX BALANCE +#include "rootserver/ob_ls_balance_helper.h" +#include "rootserver/ob_primary_ls_service.h"//fetch max ls id +#include "lib/mysqlclient/ob_mysql_transaction.h"//trans +#include "observer/ob_server_struct.h"//GCTX +#include "share/schema/ob_schema_getter_guard.h"//ObSchemaGetGuard +#include "share/schema/ob_multi_version_schema_service.h"//ObMultiSchemaService +#include "share/schema/ob_table_schema.h"//ObTableSchema +#include "share/ob_balance_define.h" // ObBalanceTaskID, ObBalanceJobID +#include "storage/tx/ob_unique_id_service.h" // ObUniqueIDService +#include "storage/ob_common_id_utils.h" // ObCommonIDUtils +#include "ob_ls_balance_helper.h" + +#define ISTAT(fmt, args...) FLOG_INFO("[LS_BALANCE] " fmt, ##args) +#define WSTAT(fmt, args...) FLOG_WARN("[LS_BALANCE] " fmt, ##args) + +namespace oceanbase +{ +using namespace share; +namespace rootserver +{ +//////ObUnitGroupBalanceInfo +void ObUnitGroupBalanceInfo::reset() +{ + primary_zone_count_ = OB_INVALID_COUNT; + unit_group_.reset(); + redundant_ls_array_.reset(); + normal_ls_array_.reset(); +} + +int ObUnitGroupBalanceInfo::add_ls_status_info(const ObLSStatusInfo &ls_info) +{ + int ret = OB_SUCCESS; + //TODO has ls group id not match + if (OB_UNLIKELY(!ls_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_info)); + } else if (normal_ls_array_.count() >= primary_zone_count_ + || !is_active_unit_group()) { + if (OB_FAIL(redundant_ls_array_.push_back(ls_info))) { + LOG_WARN("failed to push back ls info", KR(ret), K(ls_info)); + } + } else if (OB_FAIL(normal_ls_array_.push_back(ls_info))) { + LOG_WARN("failed to push back ls info", KR(ret), K(ls_info)); + } + return ret; +} + +int ObUnitGroupBalanceInfo::remove_redundant_ls(const int64_t &index) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(index >= redundant_ls_array_.count() || index < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(index)); + } else if (OB_FAIL(redundant_ls_array_.remove(index))) { + LOG_WARN("failed to remove index", KR(ret), K(index)); + } + return ret; +} + + +//////////////ObLSBalanceTaskHelper + +ObLSBalanceTaskHelper::ObLSBalanceTaskHelper() : + inited_(false), + tenant_id_(OB_INVALID_TENANT_ID), + primary_zone_num_(0), + unit_group_balance_array_(), + sql_proxy_(NULL), + job_(), + task_array_(), + tenant_ls_bg_info_() +{ +} + +int ObLSBalanceTaskHelper::init(const uint64_t tenant_id, + const share::ObLSStatusInfoArray &status_array, + const ObIArray &unit_group_array, + const int64_t primary_zone_num, ObMySQLProxy *sql_proxy) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(0 == status_array.count() || 0 == unit_group_array.count() + || 0 >= primary_zone_num || OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(status_array), K(unit_group_array), + K(primary_zone_num), K(tenant_id)); + } else if (OB_FAIL(tenant_ls_bg_info_.init(tenant_id))) { + LOG_WARN("init tenant LS balance group info fail", KR(ret), K(tenant_id)); + } else { + //1. init all unit balance info + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_array.count(); ++i) { + ObUnitGroupBalanceInfo balance_info(unit_group_array.at(i), primary_zone_num); + if (OB_FAIL(unit_group_balance_array_.push_back(balance_info))) { + LOG_WARN("failed to push back balance info", KR(ret), K(balance_info), K(i)); + } + } + int64_t index = OB_INVALID_INDEX_INT64; + for (int64_t i = 0; OB_SUCC(ret) && i < status_array.count(); ++i) { + const ObLSStatusInfo &ls_status = status_array.at(i); + if (OB_FAIL(find_unit_group_balance_index(ls_status.unit_group_id_, index))) { + if (OB_ENTRY_NOT_EXIST == ret) { + //normal, ls status must has target unit_group, + //but maybe migrate unit and ls group balance concurrency + LOG_WARN("has ls in not valid unit group", KR(ret), K(ls_status), K(unit_group_array)); + ret = OB_SUCCESS; + index = unit_group_balance_array_.count(); + ObSimpleUnitGroup unit_group(ls_status.unit_group_id_, ObUnit::UNIT_STATUS_DELETING); + ObUnitGroupBalanceInfo balance_info(unit_group, primary_zone_num); + if (OB_FAIL(unit_group_balance_array_.push_back(balance_info))) { + LOG_WARN("failed to push back balance info", KR(ret), K(balance_info)); + } + } else { + LOG_WARN("failed to find index", KR(ret), K(ls_status)); + } + } + if (FAILEDx(unit_group_balance_array_.at(index).add_ls_status_info(ls_status))) { + LOG_WARN("failed to add ls status info", KR(ret), K(ls_status)); + } + } + } + if (OB_SUCC(ret)) { + primary_zone_num_ = primary_zone_num; + tenant_id_ = tenant_id; + sql_proxy_ = sql_proxy; + job_.reset(); + task_array_.reset(); + inited_ = true; + } + return ret; +} + +int ObLSBalanceTaskHelper::find_unit_group_balance_index(const uint64_t unit_group_id, int64_t &index) +{ + int ret = OB_SUCCESS; + index = OB_INVALID_INDEX_INT64; + if (OB_UNLIKELY(OB_INVALID_ID == unit_group_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(unit_group_id)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_balance_array_.count(); ++i) { + if (unit_group_id == unit_group_balance_array_.at(i).get_unit_group_id()) { + index = i; + break; + } + } + if (OB_SUCC(ret) && OB_INVALID_INDEX_INT64 == index) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("failed to find ls unit group", KR(ret), K(unit_group_id), K(unit_group_balance_array_)); + } + } + return ret; +} + +int ObLSBalanceTaskHelper::check_need_ls_balance(bool &need_balance) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(unit_group_balance_array_.count() <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("unit group balance array not expected", KR(ret)); + } else { + need_balance = false; + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_balance_array_.count() && !need_balance; ++i) { + const ObUnitGroupBalanceInfo &balance_info = unit_group_balance_array_.at(i); + if (balance_info.get_lack_ls_count() > 0 || balance_info.get_redundant_ls_array().count() > 0) { + //has more ls or less ls + need_balance = true; + ISTAT("has more or less ls, need balance", K(balance_info)); + } + } + } + return ret; +} + +int ObLSBalanceTaskHelper::generate_ls_balance_task() +{ + int ret = OB_SUCCESS; + ObMultiVersionSchemaService *schema_service = GCTX.schema_service_; + + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_FAIL(generate_balance_job_())) { + LOG_WARN("failed to generate job", KR(ret)); + } else if (OB_ISNULL(sql_proxy_) || OB_ISNULL(schema_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy or schema service is null", KR(ret), K(sql_proxy_), K(schema_service)); + } + // build tenant all balance group info for ALL LS + else if (OB_FAIL(tenant_ls_bg_info_.build("LS_BALANCE", *sql_proxy_, *schema_service))) { + LOG_WARN("build tenant all balance group info for all LS fail", KR(ret)); + } else { + if (0 == job_.get_balance_strategy().string().compare(share::LS_BALANCE_BY_ALTER)) { + if (OB_FAIL(generate_alter_task_())) { + LOG_WARN("failed to generate alter task", KR(ret)); + } + } else if (0 == job_.get_balance_strategy().string().compare(share::LS_BALANCE_BY_MIGRATE)) { + // 1. first migrate task + if (OB_FAIL(generate_migrate_task_())) { + LOG_WARN("failed to generate migrate task", KR(ret)); + } + } else if (0 == job_.get_balance_strategy().string().compare(share::LS_BALANCE_BY_EXPAND)) { + //2. try expand + if (OB_FAIL(generate_expand_task_())) { + LOG_WARN("failed to generate expand task", KR(ret)); + } + } else if (0 == job_.get_balance_strategy().string().compare(share::LS_BALANCE_BY_SHRINK)) { + //3. try shrink + if (OB_FAIL(generate_shrink_task_())) { + LOG_WARN("failed to generate expand task", KR(ret)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("no other balance job", KR(ret), K_(job)); + } + if (OB_SUCC(ret) && 0 == task_array_.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("has no task", KR(ret), K(job_)); + } + ISTAT("generate task", KR(ret), K(job_), K(task_array_)); + } + return ret; +} + +int ObLSBalanceTaskHelper::generate_balance_job_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(unit_group_balance_array_.count() <= 0) + || OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("error unexpected", KR(ret), KP(sql_proxy_), K(unit_group_balance_array_)); + } else { + bool lack_ls = false; + bool redundant_ls = false; + bool need_modify_ls_group = false; + ObBalanceJobType job_type(ObBalanceJobType::BALANCE_JOB_LS); + ObBalanceJobStatus job_status(ObBalanceJobStatus::BALANCE_JOB_STATUS_DOING); + int64_t unit_group_num = 0; + ObBalanceJobID job_id; + ObString comment; + const char* balance_stradegy = NULL; + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_balance_array_.count(); ++i) { + const ObUnitGroupBalanceInfo &balance_info = unit_group_balance_array_.at(i); + if (balance_info.is_active_unit_group()) { + unit_group_num++; + } + if (balance_info.get_lack_ls_count() > 0) { + lack_ls = true; + ISTAT("unit group has little ls than expected", K(balance_info)); + } + if (balance_info.get_redundant_ls_array().count() > 0) { + redundant_ls = true; + ISTAT("unit group has more ls than expected", K(balance_info)); + } + uint64_t ls_group_id = OB_INVALID_ID; + for (int64_t j = 0; + OB_SUCC(ret) && j < balance_info.get_normal_ls_array().count() && + !need_modify_ls_group; ++j) { + const ObLSStatusInfo &ls_status_info = balance_info.get_normal_ls_array().at(j); + if (OB_INVALID_ID == ls_status_info.ls_group_id_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls group id not expected", KR(ret), K(ls_status_info)); + } else if (OB_INVALID_ID == ls_group_id) { + ls_group_id = ls_status_info.ls_group_id_; + } else if (ls_group_id != ls_status_info.ls_group_id_) { + need_modify_ls_group = true; + ISTAT("unit group has different ls group", K(ls_group_id), K(ls_status_info), K(balance_info)); + } + } + } + if (OB_SUCC(ret)) { + if (need_modify_ls_group) { + balance_stradegy = share::LS_BALANCE_BY_ALTER; + } else if (lack_ls && redundant_ls) { + balance_stradegy = share::LS_BALANCE_BY_MIGRATE; + } else if (lack_ls) { + balance_stradegy = share::LS_BALANCE_BY_EXPAND; + } else if (redundant_ls) { + balance_stradegy = share::LS_BALANCE_BY_SHRINK; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("must has balance job for ls", KR(ret), K(unit_group_balance_array_)); + } + + if (FAILEDx(ObCommonIDUtils::gen_unique_id(tenant_id_, job_id))) { + LOG_WARN("generate unique id for balance job fail", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(job_.init(tenant_id_, job_id, job_type, job_status, primary_zone_num_, + unit_group_num, comment, ObString(balance_stradegy)))) { + LOG_WARN("failed to init job", KR(ret), K(tenant_id_), K(job_id), K(job_type), + K(job_status), K(primary_zone_num_), K(unit_group_num), K(balance_stradegy)); + } + } + } + return ret; +} + +int ObLSBalanceTaskHelper::generate_alter_task_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + uint64_t ls_group_id = OB_INVALID_ID; + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_balance_array_.count(); ++i) { + ObUnitGroupBalanceInfo &balance_info = unit_group_balance_array_.at(i); + ls_group_id = OB_INVALID_ID; + for (int64_t j = 0; OB_SUCC(ret) && j < balance_info.get_normal_ls_array().count(); ++j) { + const ObLSStatusInfo &ls_status_info = balance_info.get_normal_ls_array().at(j); + if (OB_INVALID_ID == ls_group_id) { + ls_group_id = ls_status_info.ls_group_id_; + } else if (ls_group_id != ls_status_info.ls_group_id_) { + if (OB_FAIL(construct_ls_alter_task_(ls_status_info.ls_id_, ls_group_id))) { + LOG_WARN("failed to construct ls alter task", KR(ret), + K(ls_status_info), K(ls_group_id)); + } + } + } + } + } + return ret; +} + +int ObLSBalanceTaskHelper::generate_migrate_task_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + //get a redundant ls, and found one unit group less ls + bool new_task = true; + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_balance_array_.count() && new_task; ++i) { + ObUnitGroupBalanceInfo &balance_info = unit_group_balance_array_.at(i); + for (int64_t j = balance_info.get_redundant_ls_array().count() - 1; OB_SUCC(ret) && j >= 0 && new_task; --j) { + //get one unit group, which less than primary_zone_unit_num + const ObLSStatusInfo &ls_status = balance_info.get_redundant_ls_array().at(j); + new_task = false; + for (int64_t k = 0; OB_SUCC(ret) && k < unit_group_balance_array_.count(); ++k) { + ObUnitGroupBalanceInfo &dest_balance_info = unit_group_balance_array_.at(k); + if (dest_balance_info.get_lack_ls_count() > 0) { + new_task = true; + if (balance_info.get_unit_group_id() == dest_balance_info.get_unit_group_id()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls group can not has more ls and lack ls", KR(ret), + K(i), K(k), K(j), K(balance_info), K(dest_balance_info)); + } else if (OB_FAIL(generate_ls_alter_task_(ls_status, dest_balance_info))) { + LOG_WARN("failed to generate ls alter task", KR(ret), K(ls_status), K(dest_balance_info)); + } + } + }//end for k + if (OB_SUCC(ret) && new_task) { + //remove ls status from the unit group + if (OB_FAIL(balance_info.remove_redundant_ls(j))) { + LOG_WARN("failed to remove redundant ls", KR(ret), K(j)); + } + } + }//end for j + }//end for i + } + return ret; +} + +int ObLSBalanceTaskHelper::generate_ls_alter_task_(const ObLSStatusInfo &ls_status_info, ObUnitGroupBalanceInfo &dest_unit_group) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!ls_status_info.is_valid() + || dest_unit_group.get_lack_ls_count() <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_status_info), K(dest_unit_group)); + } else { + uint64_t ls_group_id = OB_INVALID_ID; + ObLSStatusInfo dest_ls_status; + if (dest_unit_group.get_normal_ls_array().count() > 0) { + ls_group_id = dest_unit_group.get_normal_ls_array().at(0).ls_group_id_; + } else if (OB_FAIL(ObLSServiceHelper::fetch_new_ls_group_id(sql_proxy_, tenant_id_, ls_group_id))) { + LOG_WARN("failed to fetch new ls id", KR(ret), K(tenant_id_)); + } + if (FAILEDx(construct_ls_alter_task_(ls_status_info.ls_id_, ls_group_id))) { + LOG_WARN("failed to construct ls alter task", KR(ret), K(ls_status_info), K(ls_group_id)); + } else if (OB_FAIL(dest_ls_status.init(ls_status_info.tenant_id_, + ls_status_info.ls_id_, ls_group_id, + ls_status_info.status_, + ls_status_info.unit_group_id_, + ls_status_info.primary_zone_, + ls_status_info.get_flag()))) { + LOG_WARN("failed to init ls status", KR(ret), K(ls_group_id), K(ls_status_info)); + } else if (OB_FAIL(dest_unit_group.add_ls_status_info(dest_ls_status))) { + LOG_WARN("failed to add ls status info", KR(ret), K(dest_ls_status)); + } + } + return ret; +} + +int ObLSBalanceTaskHelper::generate_expand_task_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + int64_t lack_count = 0; + ObSplitLSParamArray src_ls; + ObArray dest_ls; + const double src_factor = 1; + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_balance_array_.count(); ++i) { + const ObUnitGroupBalanceInfo & balance_info = unit_group_balance_array_.at(i); + for (int64_t j = 0; OB_SUCC(ret) && j < balance_info.get_normal_ls_array().count(); ++j) { + ObSplitLSParam param(&balance_info.get_normal_ls_array().at(j), src_factor); + if (OB_FAIL(src_ls.push_back(param))) { + LOG_WARN("failed to push back param", KR(ret), K(param), K(i)); + } + } + if (OB_SUCC(ret)) { + lack_count += balance_info.get_lack_ls_count(); + } + } + if (FAILEDx(construct_expand_dest_param_(lack_count, src_ls, dest_ls))) { + LOG_WARN("failed to construct expand dest param", KR(ret), K(lack_count), K(src_ls)); + } + int64_t dest_ls_index = 0; + uint64_t ls_group_id = OB_INVALID_ID; + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_balance_array_.count(); ++i) { + ls_group_id = OB_INVALID_ID; + const ObUnitGroupBalanceInfo &balance_info = unit_group_balance_array_.at(i); + if (balance_info.get_normal_ls_array().count() > 0) { + ls_group_id = balance_info.get_normal_ls_array().at(0).ls_group_id_; + } else if (OB_FAIL(ObLSServiceHelper::fetch_new_ls_group_id(sql_proxy_, tenant_id_, ls_group_id))) { + LOG_WARN("failed to fetch new ls group id", KR(ret), K(tenant_id_)); + } + for (int64_t j = 0; OB_SUCC(ret) && j < balance_info.get_lack_ls_count(); ++j) { + if (OB_UNLIKELY(dest_ls_index >= dest_ls.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dest ls index not expected", KR(ret), K(dest_ls_index)); + } else if (OB_FAIL(generate_balance_task_for_expand_(dest_ls.at(dest_ls_index), + ls_group_id))) { + LOG_WARN("failed to get balance task", KR(ret), K(i), K(j), K(ls_group_id), + "dest_ls_param", dest_ls.at(dest_ls_index)); + } else { + ++dest_ls_index; + } + } + if (OB_SUCC(ret)) { + lack_count += balance_info.get_lack_ls_count(); + } + } + } + return ret; +} + +int ObLSBalanceTaskHelper::generate_shrink_task_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + const int64_t normal_ls_count = job_.get_primary_zone_num() * job_.get_unit_group_num(); + ObSplitLSParamArray src_ls; + ObArray dest_ls; + const double src_factor = 1; + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_balance_array_.count(); ++i) { + const ObUnitGroupBalanceInfo & balance_info = unit_group_balance_array_.at(i); + for (int64_t j = 0; OB_SUCC(ret) && j < balance_info.get_redundant_ls_array().count(); ++j) { + ObSplitLSParam param(&balance_info.get_redundant_ls_array().at(j), src_factor); + if (OB_FAIL(src_ls.push_back(param))) { + LOG_WARN("failed to push back param", KR(ret), K(param), K(i), K(j)); + } + } + } + if (FAILEDx(construct_shrink_src_param_(normal_ls_count, src_ls, dest_ls))) { + LOG_WARN("failed to construct expand dest param", KR(ret), K(normal_ls_count), K(src_ls)); + } + int64_t dest_index = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_balance_array_.count(); ++i) { + const ObUnitGroupBalanceInfo & balance_info = unit_group_balance_array_.at(i); + for (int64_t j = 0; OB_SUCC(ret) && j < balance_info.get_normal_ls_array().count(); ++j) { + if (OB_UNLIKELY(dest_ls.count() < dest_index)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src ls is unexpected", KR(ret), K(dest_ls), K(dest_ls)); + } else if (OB_FAIL(generate_task_for_shrink_( + dest_ls.at(dest_index++), + balance_info.get_normal_ls_array().at(j)))) { + LOG_WARN("failed to generate task for shrink", KR(ret), K(dest_index), K(dest_ls), K(j), K(balance_info)); + } + } + } + } + return ret; +} + +int ObLSBalanceTaskHelper::generate_task_for_shrink_( + const ObSplitLSParamArray &src_split_param, + const ObLSStatusInfo &ls_status_info) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!job_.is_valid() || src_split_param.count() <= 0 + || !ls_status_info.is_valid())) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("error unexpected", KR(ret), K(job_), K(src_split_param), K(ls_status_info)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < src_split_param.count(); ++i) { + const ObSplitLSParam ¶m = src_split_param.at(i); + ObLSID merge_ls_id; + if (1 == param.get_current_factor()) { + //nothing + merge_ls_id = param.get_ls_info()->ls_id_; + } else { + if (param.get_ls_info()->ls_group_id_ == ls_status_info.ls_group_id_) { + //need_transfer, no need merge + if (OB_FAIL(generate_transfer_task_(param, ls_status_info))) { + LOG_WARN("failed to generate transfer task", KR(ret), K(param)); + } + } else { + // need split + ObSplitLSParamArray tmp_split_param; + int64_t task_index = OB_INVALID_INDEX_INT64; + if (OB_FAIL(tmp_split_param.push_back(param))) { + LOG_WARN("failed to push back param", KR(ret), K(param)); + } else if (OB_FAIL(generate_ls_split_task_(tmp_split_param, task_index))) { + LOG_WARN("failed to generate ls info", KR(ret), K(tmp_split_param)); + } else { + merge_ls_id = task_array_.at(task_index).get_dest_ls_id(); + } + } + } + if (OB_SUCC(ret)) { + if (param.get_ls_info()->ls_group_id_ != ls_status_info.ls_group_id_) { + //need alter task + if (OB_FAIL(construct_ls_alter_task_(merge_ls_id, ls_status_info.ls_group_id_))) { + LOG_WARN("failed to construct ls alter task", KR(ret), K(merge_ls_id), K(ls_status_info)); + } + } + } + if (OB_SUCC(ret) && merge_ls_id.is_valid()) { + //need merge + if (OB_FAIL(construct_ls_merge_task_(merge_ls_id, ls_status_info.ls_id_, + ls_status_info.ls_group_id_))) { + LOG_WARN("failed to construct ls merge task", KR(ret), K(merge_ls_id), K(ls_status_info)); + } + } + }//end for + } + return ret; +} + +int ObLSBalanceTaskHelper::generate_transfer_task_( + const ObSplitLSParam ¶m, const ObLSStatusInfo &ls_status_info) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!param.is_valid() || !ls_status_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(param), K(ls_status_info)); + } else { + ObBalanceTaskType task_type( + ObBalanceTaskType::BALANCE_TASK_TRANSFER); // transfer task + ObBalanceTask task; + ObTransferPartList part_list; + ObBalanceTaskID task_id; + if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id_, task_id))) { + LOG_WARN("gen_unique_id for balance task failed", KR(ret), K(task_id), + K_(tenant_id)); + } else if (OB_FAIL(construct_ls_part_info_(param, part_list))) { + LOG_WARN("failed to construct ls part info", KR(ret), K(param)); + } else if (OB_FAIL(task.simple_init( + tenant_id_, job_.get_job_id(), task_id, task_type, + ls_status_info.ls_group_id_, + param.get_ls_info()->ls_id_, ls_status_info.ls_id_, part_list))) { + LOG_WARN("failed to init task", KR(ret), K(tenant_id_), K(job_), + K(task_id), K(task_type), K(part_list)); + } else if (OB_FAIL(task_array_.push_back(task))) { + LOG_WARN("failed to push back task", KR(ret), K(task)); + } + ISTAT("generate transfer task", KR(ret), K(task), K(job_)); + } + return ret; +} + +int ObLSBalanceTaskHelper::construct_shrink_src_param_(const int64_t target_count, ObSplitLSParamArray &src_ls, + ObIArray &dest_split_array) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(0 == target_count || 0 == src_ls.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(target_count), K(src_ls)); + } else { + const double each_ls_target_factor = double(src_ls.count()) / (target_count); + if (each_ls_target_factor <= OB_DOUBLE_EPSINON) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("too many ls", KR(ret), K(each_ls_target_factor), K(target_count), K(src_ls)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < target_count; ++i) { + double need_factor = each_ls_target_factor; + ObSplitLSParamArray src_array; + for (int64_t j = 0; OB_SUCC(ret) && j < src_ls.count() && need_factor > OB_DOUBLE_EPSINON; ++j) { + ObSplitLSParam ¶m = src_ls.at(j); + double get_factor = param.reduce_enough_factor(need_factor); + if (0 == get_factor) { + //empty + } else if (OB_DOUBLE_EPSINON >= get_factor) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("factor is too small", KR(ret), K(need_factor), K(src_ls), K(src_array), K(dest_split_array)); + } else { + need_factor -= get_factor; + if (OB_DOUBLE_EPSINON >= param.get_current_factor()) { + param.reduce_all(); + //for ex + //if current ls is 3, need shrink to 2, first ls need transfer, second need merge + get_factor = 1; + } + ObSplitLSParam split_param(param.get_ls_info(), get_factor); + LOG_TRACE("split param", KR(ret), K(split_param), K(i), K(j)); + if (OB_FAIL(src_array.push_back(split_param))) { + LOG_WARN("failed to push back split param", KR(ret), K(split_param)); + } + } + }//end for j + if (FAILEDx(dest_split_array.push_back(src_array))) { + LOG_WARN("failed to push back src array", KR(ret), K(i), K(src_array)); + } + } + } + return ret; +} + +int ObLSBalanceTaskHelper::construct_expand_dest_param_(const int64_t lack_ls_count, ObSplitLSParamArray &src_ls, + ObIArray &dest_split_array) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(0 == lack_ls_count || 0 == src_ls.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(lack_ls_count), K(src_ls)); + } else { + const double each_ls_target_factor = double(src_ls.count()) / (src_ls.count() + lack_ls_count); + if (each_ls_target_factor <= OB_DOUBLE_EPSINON) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("too many lack ls count", KR(ret), K(each_ls_target_factor), K(lack_ls_count), K(src_ls)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < lack_ls_count; ++i) { + double need_factor = each_ls_target_factor; + ObSplitLSParamArray src_array; + for (int64_t j = 0; OB_SUCC(ret) && j < src_ls.count() && need_factor > OB_DOUBLE_EPSINON; ++j) { + ObSplitLSParam ¶m = src_ls.at(j); + double get_factor = param.reduce_factor_for_dest(need_factor, each_ls_target_factor); + if (get_factor > OB_DOUBLE_EPSINON) { + ObSplitLSParam split_param(param.get_ls_info(), get_factor); + need_factor -= get_factor; + if (OB_FAIL(src_array.push_back(split_param))) { + LOG_WARN("failed to push back split param", KR(ret), K(split_param)); + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(0 >= src_array.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src array is empty", KR(ret), K(src_ls)); + } else if (OB_FAIL(dest_split_array.push_back(src_array))) { + LOG_WARN("failed to push back src array", KR(ret), K(i), K(src_array)); + } + } + } + return ret; +} + +int ObLSBalanceTaskHelper::generate_balance_task_for_expand_( + const ObSplitLSParamArray &dest_split_param, const uint64_t ls_group_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!job_.is_valid() || dest_split_param.count() <= 0 + || OB_INVALID_ID == ls_group_id)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected", KR(ret), K(job_), K(dest_split_param), K(ls_group_id)); + } else { + //generate new ls info for split + int64_t task_begin_index = OB_INVALID_INDEX_INT64; + if (OB_FAIL(generate_ls_split_task_(dest_split_param, task_begin_index))) { + LOG_WARN("failed to generate ls info", KR(ret), K(dest_split_param)); + } else if (OB_UNLIKELY(task_begin_index < 0 || task_begin_index > task_array_.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task_begin_index is invalid", KR(ret), K(task_begin_index)); + } + + for (int64_t i = task_begin_index; OB_SUCC(ret) && i < task_array_.count(); ++i) { + if (ls_group_id != task_array_.at(i).get_ls_group_id()) { + if (OB_FAIL(construct_ls_alter_task_(task_array_.at(i).get_dest_ls_id(), ls_group_id))) { + LOG_WARN("failed to init task", KR(ret), K(task_array_.at(i)), K(ls_group_id)); + } + } + } + if (OB_SUCC(ret)) { + ObLSID dest_ls_id = task_array_.at(task_begin_index).get_dest_ls_id(); + for (int64_t i = task_begin_index + 1; OB_SUCC(ret) && i < task_array_.count(); ++i) { + if (task_array_.at(i).get_task_type().is_split_task()) { + if (OB_FAIL(construct_ls_merge_task_(task_array_.at(i).get_dest_ls_id(), + dest_ls_id, ls_group_id))) { + LOG_WARN("failed to construct ls merge task", KR(ret), + K(task_array_.at(i)), K(dest_ls_id), K(ls_group_id)); + } + } + } + } + } + return ret; +} +int ObLSBalanceTaskHelper::generate_ls_split_task_(const ObSplitLSParamArray &dest_split_param, + int64_t &task_begin_index) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!job_.is_valid() || dest_split_param.count() <= 0)) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("error unexpected", KR(ret), K(job_), K(dest_split_param)); + } + ObBalanceTask task; + ObBalanceTaskType task_type(ObBalanceTaskType::BALANCE_TASK_SPLIT);//split task + ObTransferPartList part_list;//TODO + task_begin_index = task_array_.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < dest_split_param.count(); ++i) { + // split task has equal ls group id with source + //TODO part_list fill partition_info of task + task.reset(); + ObLSID dest_ls_id; + ObBalanceTaskID task_id; + const share::ObLSStatusInfo *src_ls = dest_split_param.at(i).get_ls_info(); + if (OB_ISNULL(src_ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src ls is null", KR(ret), K(i), K(dest_split_param)); + } else if (OB_FAIL(construct_ls_part_info_(dest_split_param.at(i), part_list))) { + LOG_WARN("failed to construct ls part info", KR(ret), KPC(src_ls)); + } else if (OB_FAIL(ObLSServiceHelper::fetch_new_ls_id(sql_proxy_, tenant_id_, dest_ls_id))) { + LOG_WARN("failed to fetch new ls id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id_, task_id))) { + LOG_WARN("failed to gen unique id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(task.simple_init(tenant_id_, job_.get_job_id(), task_id, task_type, + src_ls->ls_group_id_, src_ls->ls_id_, dest_ls_id, + part_list))) { + LOG_WARN("failed to init task", KR(ret), K(tenant_id_), K(job_), K(task_id), K(task_type), + KPC(src_ls), K(dest_ls_id), K(part_list)); + } else if (OB_FAIL(task_array_.push_back(task))) { + LOG_WARN("failed to push back task", KR(ret), K(task)); + } + ISTAT("generate split task", KR(ret), K(task), K(job_)); + } + return ret; +} + +int ObLSBalanceTaskHelper::construct_ls_alter_task_(const share::ObLSID &ls_id, const uint64_t ls_group_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!job_.is_valid() || !ls_id.is_valid() + || OB_INVALID_ID == ls_group_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_), K(ls_id), K(ls_group_id)); + } else { + //for alter + ObBalanceTask task; + ObBalanceTaskID task_id; + ObBalanceTaskType task_type(ObBalanceTaskType::BALANCE_TASK_ALTER); + ObTransferPartList part_list; + ObLSID dest_ls_id; + if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id_, task_id))) { + LOG_WARN("failed to gen unique id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(task.simple_init(tenant_id_, job_.get_job_id(), + task_id, task_type, ls_group_id, + ls_id, + dest_ls_id, + part_list))) { + LOG_WARN("failed to init task", KR(ret), K(tenant_id_), K(job_), + K(task_id), K(task_type), K(ls_id), K(part_list)); + } else if (OB_FAIL(task_array_.push_back(task))) { + LOG_WARN("failed to push back task", KR(ret), K(task)); + } + ISTAT("generate alter task", KR(ret), K(task), K(job_)); + } + return ret; +} + +int ObLSBalanceTaskHelper::construct_ls_merge_task_( + const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id, + const uint64_t ls_group_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!job_.is_valid() || !src_ls_id.is_valid() + || OB_INVALID_ID == ls_group_id + || !dest_ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_), K(src_ls_id), K(ls_group_id), K(dest_ls_id)); + } else { + //for merge + ObBalanceTask task; + ObBalanceTaskID task_id; + ObBalanceTaskType task_type(ObBalanceTaskType::BALANCE_TASK_MERGE);// merge task + ObTransferPartList part_list; + if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id_, task_id))) { + LOG_WARN("failed to gen unique id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(task.simple_init(tenant_id_, job_.get_job_id(), + task_id, task_type, ls_group_id, + src_ls_id, + dest_ls_id, + part_list))) { + LOG_WARN("failed to init task", KR(ret), K(tenant_id_), K(job_), + K(task_id), K(task_type), K(ls_id), K(part_list)); + } else if (OB_FAIL(task_array_.push_back(task))) { + LOG_WARN("failed to push back task", KR(ret), K(task)); + } + ISTAT("generate merge task", KR(ret), K(task), K(job_)); + } + return ret; +} + +int ObLSBalanceTaskHelper::construct_ls_part_info_(const ObSplitLSParam &src_ls, ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + ObLSID src_ls_id = src_ls.get_ls_id(); + const double factor = src_ls.get_current_factor(); + ObLSBalanceGroupInfo *ls_bg_info = NULL; + + part_list.reset(); + + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!src_ls.is_valid() || !src_ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("src ls is invalid", KR(ret), K(src_ls), K(src_ls_id)); + } else if (OB_FAIL(tenant_ls_bg_info_.get(src_ls_id, ls_bg_info))) { + if (OB_HASH_NOT_EXIST == ret) { + ret = OB_SUCCESS; + ISTAT("src ls is empty, no need to transfer out", KR(ret), K(src_ls_id)); + } else { + LOG_WARN("get src ls balance group info fail", KR(ret), K(src_ls_id), K(src_ls)); + } + } else if (OB_ISNULL(ls_bg_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid ls balance group info", KR(ret), K(ls_bg_info), K(src_ls_id)); + } else if (OB_FAIL(ls_bg_info->transfer_out_by_factor(factor, part_list))) { + LOG_WARN("transfer out part list from LS balance group info fail", KR(ret), K(factor), + KPC(ls_bg_info), K(part_list)); + } + return ret; +} + +#undef ISTAT +#undef WSTAT + +} +} diff --git a/src/rootserver/ob_ls_balance_helper.h b/src/rootserver/ob_ls_balance_helper.h new file mode 100644 index 000000000..f9d74c752 --- /dev/null +++ b/src/rootserver/ob_ls_balance_helper.h @@ -0,0 +1,222 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_LS_BALANCE_HELPER_H +#define OCEANBASE_ROOTSERVER_OB_LS_BALANCE_HELPER_H +#include "lib/container/ob_array.h" //ObArray +#include "lib/hash/ob_hashmap.h"//ObHashMap +#include "share/unit/ob_unit_info.h" //ObSimpleUnitGroup +#include "share/balance/ob_balance_task_table_operator.h" //ObBalanceTask +#include "share/balance/ob_balance_job_table_operator.h" //ObBalanceJob +#include "share/ls/ob_ls_status_operator.h" +#include "share/ls/ob_ls_operator.h"//ObLSAttr +#include "share/transfer/ob_transfer_info.h"//ObPartList +#include "rootserver/ob_balance_group_ls_stat_operator.h"//ObBalanceGroupID + +#include "rootserver/balance/ob_tenant_ls_balance_group_info.h" //ObTenantLSBalanceGroupInfo + +namespace oceanbase +{ +namespace common +{ +class ObMySQLProxy; +} +namespace share +{ +struct ObBalanceJob; +} +namespace rootserver +{ +struct ObUnitGroupBalanceInfo +{ +public: + ObUnitGroupBalanceInfo() { reset(); } + ObUnitGroupBalanceInfo(const share::ObSimpleUnitGroup &unit_group, + const int64_t primary_zone_num) : + primary_zone_count_(primary_zone_num), unit_group_(unit_group), + redundant_ls_array_(), normal_ls_array_() {} + ~ObUnitGroupBalanceInfo() {} + int init_basic_info(const share::ObSimpleUnitGroup &unit_group, + const int64_t primary_zone_num) + { + unit_group_ = unit_group; + primary_zone_count_ = primary_zone_num; + return OB_SUCCESS; + } + int64_t get_lack_ls_count() const + { + int64_t count = 0; + if (unit_group_.is_active()) { + count = primary_zone_count_ - normal_ls_array_.count(); + } + return count; + } + int64_t get_primary_zone_count() const + { + return primary_zone_count_; + } + uint64_t get_unit_group_id() const + { + return unit_group_.get_unit_group_id(); + } + const share::ObLSStatusInfoArray & get_redundant_ls_array() const + { + return redundant_ls_array_; + } + const share::ObLSStatusInfoArray & get_normal_ls_array() const + { + return normal_ls_array_; + } + bool is_active_unit_group() const + { + return unit_group_.is_active(); + } + int remove_redundant_ls(const int64_t &index); + void reset(); + int add_ls_status_info(const share::ObLSStatusInfo &ls_info); + TO_STRING_KV(K_(primary_zone_count), K_(unit_group), + K_(redundant_ls_array), K_(normal_ls_array)); +private: + int64_t primary_zone_count_; + share::ObSimpleUnitGroup unit_group_; + share::ObLSStatusInfoArray redundant_ls_array_;// ls need merge to other normal ls + share::ObLSStatusInfoArray normal_ls_array_;//normal ls need keep +}; +typedef ObArray ObUnitGroupBalanceInfoArray; + +//for split or transfer +struct ObSplitLSParam +{ +public: + ObSplitLSParam(const share::ObLSStatusInfo *ls_info, const double current_factor) : + info_(ls_info), current_factor_(current_factor){} + ObSplitLSParam() : info_(NULL), current_factor_(OB_FLOAT_EPSINON) {} + bool is_valid() const + { + return OB_NOT_NULL(info_) && current_factor_ > OB_FLOAT_EPSINON; + } + double get_current_factor() const + { + return current_factor_; + } + const share::ObLSStatusInfo * get_ls_info() const + { + return info_; + } + const share::ObLSID get_ls_id() const { + return (NULL == info_) ? share::ObLSID() : info_->ls_id_; + } + //Each time you split, you need to ensure that there is + //enough factor on the source side, and then allocate the rest + double reduce_factor_for_dest(const double need_factor, const double target_factor) + { + double can_split = 0; + if (need_factor <= 0 || target_factor <= 0 || current_factor_ <= target_factor) { + } else { + can_split = std::min(current_factor_ - target_factor, target_factor); + can_split = std::min(can_split, need_factor); + current_factor_ -= can_split; + } + return can_split; + } + double reduce_enough_factor(const double need_factor) + { + double can_split = 0; + if (need_factor <= 0) { + } else { + can_split = std::min(need_factor, current_factor_); + current_factor_ -= can_split; + } + return can_split; + } + void reduce_all() + { + current_factor_ = 0; + } + TO_STRING_KV(KPC_(info), K_(current_factor)); +private: + const share::ObLSStatusInfo *info_; + double current_factor_; +}; +typedef ObArray ObSplitLSParamArray; + + +class ObLSBalanceTaskHelper +{ +public: + ObLSBalanceTaskHelper (); + ~ObLSBalanceTaskHelper() {} + int init(const uint64_t tenant_id, const share::ObLSStatusInfoArray &status_array, + const ObIArray &unit_group_array, + const int64_t primary_zone_num, + ObMySQLProxy *sql_proxy); + //check need ls balance + int check_need_ls_balance(bool &need_balance); + //generate ls balance job and task + int generate_ls_balance_task(); + share::ObBalanceJob& get_balance_job() + { + return job_; + } + ObArray& get_balance_tasks() + { + return task_array_; + } + private: + int generate_balance_job_(); + int generate_alter_task_(); + int generate_migrate_task_(); + int generate_expand_task_(); + int generate_shrink_task_(); + /* description: get index of the unit_group_id in unit_group_balance_array + * param[in] unit_group_id : unit_group_id + * param[out] index : index of unit_group in unit_group_balance_array + * return: + * OB_SUCCESS : find the valid index + * OB_ENTRY_NOT_EXIST: the unit_group not exist + * OTHER : failed + */ + int find_unit_group_balance_index(const uint64_t unit_group_id, int64_t &index); + int construct_expand_dest_param_(const int64_t lack_ls_count, ObSplitLSParamArray &src_ls, + ObIArray &dest_array); + int construct_shrink_src_param_(const int64_t target_count, ObSplitLSParamArray &src_ls, + ObIArray &dest_array); + int generate_balance_task_for_expand_(const ObSplitLSParamArray &dest_split_param, + const uint64_t ls_group_id); + int generate_ls_split_task_(const ObSplitLSParamArray &dest_split_param, + int64_t &task_begin_index); + int prepare_ls_partition_info_(); + int add_ls_part_info(const share::ObLSID &ls_id, const share::ObTransferPartInfo &part_info, + const ObBalanceGroupID &bg_id); + int construct_ls_part_info_(const ObSplitLSParam &src_ls, share::ObTransferPartList &part_list); + int generate_ls_alter_task_(const share::ObLSStatusInfo &ls_status_info, ObUnitGroupBalanceInfo &dest_unit_group); + int generate_task_for_shrink_(const ObSplitLSParamArray &src_split_param, const share::ObLSStatusInfo &ls_status_info); + int generate_transfer_task_(const ObSplitLSParam ¶m, const share::ObLSStatusInfo &ls_status_info); + //for task + int construct_ls_alter_task_(const share::ObLSID &ls_id, const uint64_t ls_group_id); + int construct_ls_merge_task_(const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const uint64_t ls_group_id); + private: + bool inited_; + uint64_t tenant_id_; + int64_t primary_zone_num_; + ObUnitGroupBalanceInfoArray unit_group_balance_array_; + ObMySQLProxy *sql_proxy_; + share::ObBalanceJob job_; + ObArray task_array_; + ObTenantLSBalanceGroupInfo tenant_ls_bg_info_; +}; + +} +} +#endif /* !OCEANBASE_ROOTSERVER_OB_LS_BALANCE_HELPER_H */ diff --git a/src/rootserver/ob_tenant_recovery_reportor.cpp b/src/rootserver/ob_ls_recovery_reportor.cpp old mode 100644 new mode 100755 similarity index 68% rename from src/rootserver/ob_tenant_recovery_reportor.cpp rename to src/rootserver/ob_ls_recovery_reportor.cpp index 65cdc2491..8639bffbe --- a/src/rootserver/ob_tenant_recovery_reportor.cpp +++ b/src/rootserver/ob_ls_recovery_reportor.cpp @@ -12,9 +12,12 @@ #define USING_LOG_PREFIX RS -#include "rootserver/ob_tenant_recovery_reportor.h" +#include "rootserver/ob_ls_recovery_reportor.h" #include "rootserver/ob_tenant_info_loader.h" #include "rootserver/ob_tenant_role_transition_service.h"//ObTenantRoleTransitionConstants +#include "rootserver/ob_rs_async_rpc_proxy.h" //ObGetLSReplayedScnProxy +#include "rootserver/ob_ls_recovery_stat_handler.h" //ObLSRecoveryStatHandler +#include "rootserver/ob_ls_service_helper.h"//update_ls_stat_in_trans #include "storage/tx_storage/ob_ls_service.h" //ObLSService #include "storage/tx_storage/ob_ls_map.h"//ObLSIterator #include "storage/ls/ob_ls.h"//ObLSGetMod @@ -36,11 +39,11 @@ using namespace storage; using namespace palf; namespace rootserver { -int ObTenantRecoveryReportor::mtl_init(ObTenantRecoveryReportor *&ka) +int ObLSRecoveryReportor::mtl_init(ObLSRecoveryReportor *&ka) { return ka->init(); } -int ObTenantRecoveryReportor::init() +int ObLSRecoveryReportor::init() { int ret = OB_SUCCESS; lib::ThreadPool::set_run_wrapper(MTL_CTX()); @@ -66,7 +69,7 @@ int ObTenantRecoveryReportor::init() } return ret; } -void ObTenantRecoveryReportor::destroy() +void ObLSRecoveryReportor::destroy() { LOG_INFO("tenant recovery service destory", KPC(this)); stop(); @@ -76,7 +79,7 @@ void ObTenantRecoveryReportor::destroy() sql_proxy_ = NULL; } -int ObTenantRecoveryReportor::start() +int ObLSRecoveryReportor::start() { int ret = OB_SUCCESS; if (IS_NOT_INIT) { @@ -92,16 +95,16 @@ int ObTenantRecoveryReportor::start() return ret; } -void ObTenantRecoveryReportor::stop() +void ObLSRecoveryReportor::stop() { logical_stop(); } -void ObTenantRecoveryReportor::wait() +void ObLSRecoveryReportor::wait() { logical_wait(); } -void ObTenantRecoveryReportor::wakeup() +void ObLSRecoveryReportor::wakeup() { if (OB_NOT_INIT) { } else { @@ -110,7 +113,7 @@ void ObTenantRecoveryReportor::wakeup() } } -void ObTenantRecoveryReportor::run2() +void ObLSRecoveryReportor::run2() { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; @@ -152,7 +155,7 @@ void ObTenantRecoveryReportor::run2() } } -int64_t ObTenantRecoveryReportor::get_idle_time_() +int64_t ObLSRecoveryReportor::get_idle_time_() { int ret = OB_SUCCESS; rootserver::ObTenantInfoLoader *tenant_info_loader = MTL(rootserver::ObTenantInfoLoader*); @@ -173,7 +176,7 @@ int64_t ObTenantRecoveryReportor::get_idle_time_() return idle_time; } -int ObTenantRecoveryReportor::submit_tenant_refresh_schema_task_() +int ObLSRecoveryReportor::submit_tenant_refresh_schema_task_() { int ret = OB_SUCCESS; bool is_standby_normal_status = false; @@ -217,8 +220,7 @@ int ObTenantRecoveryReportor::submit_tenant_refresh_schema_task_() } return ret; } - -int ObTenantRecoveryReportor::update_ls_recovery_stat_() +int ObLSRecoveryReportor::update_ls_recovery_stat_() { int ret = OB_SUCCESS; if (IS_NOT_INIT) { @@ -246,16 +248,16 @@ int ObTenantRecoveryReportor::update_ls_recovery_stat_() ret = OB_ERR_UNEXPECTED; LOG_ERROR("ls is null", KR(ret), KP(ls)); } else { - share::SCN replayable_scn = SCN::base_scn();; + share::SCN replayable_scn = SCN::base_scn(); if (OB_TMP_FAIL(tenant_info_loader->get_replayable_scn(replayable_scn))) { LOG_WARN("failed to get replayable_scn", KR(ret), KPC(ls)); } else if (OB_TMP_FAIL(ls->update_ls_replayable_point(replayable_scn))) { LOG_WARN("failed to update_ls_replayable_point", KR(tmp_ret), KPC(ls), K(replayable_scn)); } - if (ls->is_sys_ls()) { + if (ls->is_sys_ls() && !MTL_IS_PRIMARY_TENANT()) { // nothing todo - // sys ls of user tenant is in ls_recovery + // sys ls of user standby/restore tenant is in ls_recovery } else if (OB_FAIL(update_ls_recovery(ls, sql_proxy_))) { LOG_WARN("failed to update ls recovery", KR(ret), KPC(ls)); } @@ -274,66 +276,117 @@ int ObTenantRecoveryReportor::update_ls_recovery_stat_() return ret; } -int ObTenantRecoveryReportor::update_ls_recovery(ObLS *ls, common::ObMySQLProxy *sql_proxy) +int ObLSRecoveryReportor::update_ls_recovery( + ObLS *ls, + common::ObMySQLProxy *sql_proxy) { int ret = OB_SUCCESS; - logservice::ObLogService *ls_svr = MTL(logservice::ObLogService*); + ObLSRecoveryStat ls_recovery_stat; + ObMySQLTransaction trans; + const uint64_t exec_tenant_id = ObLSLifeIAgent::get_exec_tenant_id(tenant_id_); if (OB_ISNULL(ls) || OB_ISNULL(sql_proxy)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("ls or sql proxy is null", KR(ret), KP(ls), KP(sql_proxy)); - } else { - SCN sync_scn; - SCN readable_scn; - int64_t first_proposal_id = 0; - int64_t second_proposal_id = 0; - common::ObRole role; - ObLSRecoveryStat ls_recovery_stat; - const ObLSID ls_id = ls->get_ls_id(); - const uint64_t tenant_id = MTL_ID(); - - ObLSRecoveryStatOperator ls_recovery; - if (OB_FAIL(ls_svr->get_palf_role(ls_id, role, first_proposal_id))) { - LOG_WARN("failed to get first role", KR(ret), K(ls_id), KPC(ls)); - } else if (!is_strong_leader(role)) { - // nothing todo - } else if (OB_FAIL(get_sync_point_(ls_id, sync_scn, readable_scn))) { - LOG_WARN("failed to get sync point", KR(ret), KPC(ls)); + } else if (OB_FAIL(ls->get_ls_level_recovery_stat(ls_recovery_stat))) { + if (OB_NOT_MASTER == ret) { + LOG_TRACE("follower doesn't need to report ls recovery stat", KR(ret), KPC(ls)); + ret = OB_SUCCESS; } else { - if (OB_FAIL(ls_recovery_stat.init_only_recovery_stat( - tenant_id, ls_id, - sync_scn, readable_scn))) { - LOG_WARN("failed to init ls recovery stat", KR(ret), "ls_meta", ls->get_ls_meta(), - K(sync_scn), K(readable_scn)); - } else if (OB_FAIL(ls_svr->get_palf_role(ls_id, role, second_proposal_id))) { - LOG_WARN("failed to get parl role again", KR(ret), K(role), K(ls_id)); - } else if (first_proposal_id != second_proposal_id || - !is_strong_leader(role)) { - // nothing - ret = OB_EAGAIN; - LOG_INFO("role change, try again", KR(ret), K(role), - K(first_proposal_id), K(second_proposal_id), KPC(ls)); - } else if (OB_FAIL(ls_recovery.update_ls_recovery_stat(ls_recovery_stat, - *sql_proxy))) { - LOG_WARN("failed to update ls recovery stat", KR(ret), - K(ls_recovery_stat)); - } + LOG_WARN("failed to get_ls_level_recovery_stat", KR(ret), KPC(ls)); } + } else if (OB_FAIL(trans.start(sql_proxy, exec_tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id), K(ls_recovery_stat)); + } else if (ls->is_sys_ls()) { + //only primary tenant + if (OB_FAIL(update_sys_ls_recovery_stat_and_tenant_info(ls_recovery_stat, share::PRIMARY_TENANT_ROLE, false, trans))) { + LOG_WARN("failed to update sys ls recovery stat", KR(ret), K(ls_recovery_stat)); + } + } else if (OB_FAIL(ObLSServiceHelper::update_ls_recover_in_trans(ls_recovery_stat, false, trans))) { + LOG_WARN("failed to update ls recovery stat in trans", KR(ret), K(ls_recovery_stat)); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + if (ls_recovery_stat.is_valid()) { const int64_t PRINT_INTERVAL = 10 * 1000 * 1000L; if (REACH_TIME_INTERVAL(PRINT_INTERVAL)) { - LOG_INFO("tenant update ls recovery stat", KR(ret), K(role), - K(first_proposal_id), K(second_proposal_id), - K(ls_recovery_stat)); + LOG_INFO("tenant update ls recovery stat", KR(ret), K(ls_recovery_stat)); } - LOG_TRACE("tenant update ls recovery stat", KR(ret), K(role), - K(first_proposal_id), K(second_proposal_id), + LOG_TRACE("tenant update ls recovery stat", KR(ret), K(ls_recovery_stat)); - } return ret; - } -int ObTenantRecoveryReportor::update_replayable_point_() +int ObLSRecoveryReportor::update_sys_ls_recovery_stat_and_tenant_info(share::ObLSRecoveryStat &ls_recovery_stat, + const share::ObTenantRole &tenant_role, const bool only_update_readable_scn, ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!ls_recovery_stat.is_valid() || !ls_recovery_stat.get_ls_id().is_sys_ls() + || !tenant_role.is_valid() || !trans.is_started())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_recovery_stat), K(tenant_role), "trans is start", trans.is_started()); + } else { + ObAllTenantInfo tenant_info; + const uint64_t tenant_id = ls_recovery_stat.get_tenant_id(); + if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, &trans, true, tenant_info))) { + LOG_WARN("failed to load tenant info for update", KR(ret), K(tenant_id)); + } else if (tenant_info.get_tenant_role() != tenant_role + || tenant_info.get_switchover_status().is_flashback_status() + || (!only_update_readable_scn//If you only need to report readable_scn, + //there is no need to check the validity of sync_scn and recovery_until_scn + && ls_recovery_stat.get_sync_scn() > tenant_info.get_recovery_until_scn())) { + //When reporting sync_scn, it is only guaranteed that if there are multi-source transactions, + //it will wait for other LS to push through sync_scn, + //and ensure that the sync_scn in tenant_info is equal to the sync_scn of SYS_LS. + //In other cases, the sync_scn of SYS_LS may be greater than recovery_until_scn. + ret = OB_NEED_RETRY; + LOG_WARN("tenant status is not expected, do not update ls recovery", KR(ret), + K(ls_recovery_stat), K(tenant_info), K(only_update_readable_scn)); + } else if (OB_FAIL(ObLSServiceHelper::update_ls_recover_in_trans(ls_recovery_stat, only_update_readable_scn, trans))) { + LOG_WARN("failed to update ls recovery in trans", KR(ret), K(ls_recovery_stat), K(only_update_readable_scn)); + } else if (OB_FAIL(update_tenant_info_in_trans(tenant_info, trans))) { + LOG_WARN("failed to update tenant info in trans", KR(ret), K(tenant_info)); + } + } + return ret; +} + +int ObLSRecoveryReportor::update_tenant_info_in_trans( + const share::ObAllTenantInfo &old_tenant_info, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!old_tenant_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant info is invalid", KR(ret), K(old_tenant_info)); + } else { + ObLSRecoveryStatOperator ls_recovery_op; + ObAllTenantInfoProxy info_proxy; + SCN sync_scn; + SCN readable_scn; + const uint64_t tenant_id = old_tenant_info.get_tenant_id(); + DEBUG_SYNC(BLOCK_TENANT_SYNC_SNAPSHOT_INC); + if (OB_FAIL(ls_recovery_op.get_tenant_recovery_stat( + tenant_id, trans, sync_scn, readable_scn))) { + LOG_WARN("failed to get tenant recovery stat", KR(ret), K(tenant_id)); + //TODO replayable_scn is equal to sync_scn + } else if (OB_FAIL(info_proxy.update_tenant_recovery_status_in_trans( + tenant_id, trans, old_tenant_info, sync_scn, + sync_scn, readable_scn))) { + LOG_WARN("failed to update tenant recovery stat", KR(ret), + K(tenant_id), K(sync_scn), K(readable_scn), K(old_tenant_info)); + } + } + return ret; +} + +int ObLSRecoveryReportor::update_replayable_point_() { int ret = OB_SUCCESS; if (IS_NOT_INIT) { @@ -350,7 +403,7 @@ int ObTenantRecoveryReportor::update_replayable_point_() return ret; } -int ObTenantRecoveryReportor::update_replayable_point_from_tenant_info_() +int ObLSRecoveryReportor::update_replayable_point_from_tenant_info_() { int ret = OB_SUCCESS; logservice::ObLogService *log_service = MTL(logservice::ObLogService*); @@ -371,7 +424,7 @@ int ObTenantRecoveryReportor::update_replayable_point_from_tenant_info_() return ret; } -int ObTenantRecoveryReportor::update_replayable_point_from_meta_() +int ObLSRecoveryReportor::update_replayable_point_from_meta_() { int ret = OB_SUCCESS; SCN replayable_point; @@ -411,45 +464,5 @@ int ObTenantRecoveryReportor::update_replayable_point_from_meta_() return ret; } -int ObTenantRecoveryReportor::get_sync_point_(const share::ObLSID &id, - SCN &sync_scn, SCN &read_scn) -{ - int ret = OB_SUCCESS; - palf::AccessMode access_mode; - int64_t unused_mode_version; - palf::PalfHandleGuard palf_handle_guard; - if (OB_FAIL(MTL(logservice::ObLogService*)->open_palf(id, palf_handle_guard))) { - LOG_WARN("failed to open palf", KR(ret), K(id)); - } else if (OB_FAIL(palf_handle_guard.get_end_scn(sync_scn))) { - LOG_WARN("failed to get end ts", KR(ret), K(id)); - } else if (OB_FAIL(get_readable_scn(id, read_scn))) { - LOG_WARN("failed to get readable scn", KR(ret), K(id)); - } - - return ret; -} - - -int ObTenantRecoveryReportor::get_readable_scn(const share::ObLSID &id, SCN &readable_scn) -{ - int ret = OB_SUCCESS; - storage::ObLSHandle ls_handle; - storage::ObLS *ls = NULL; - ObLSVTInfo ls_info; - readable_scn.set_min(); - if (OB_FAIL(MTL(storage::ObLSService*)->get_ls(id, ls_handle, - storage::ObLSGetMod::LOG_MOD))) { - LOG_WARN("failed to get ls", KR(ret), K(id)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("ls is NULL", K(ret), K(id), K(ls_handle)); - } else if (OB_FAIL(ls->get_max_decided_scn(readable_scn))) { - LOG_WARN("failed to get_max_decided_log_ts_ns", KR(ret), K(id), KPC(ls)); - } else { - readable_scn = (readable_scn>= SCN::base_scn()) ? readable_scn : SCN::base_scn(); - } - return ret; -} - } } diff --git a/src/rootserver/ob_tenant_recovery_reportor.h b/src/rootserver/ob_ls_recovery_reportor.h similarity index 66% rename from src/rootserver/ob_tenant_recovery_reportor.h rename to src/rootserver/ob_ls_recovery_reportor.h index b4406cc4b..d9554be5d 100644 --- a/src/rootserver/ob_tenant_recovery_reportor.h +++ b/src/rootserver/ob_ls_recovery_reportor.h @@ -10,23 +10,29 @@ * See the Mulan PubL v2 for more details. */ -#ifndef OCEANBASE_ROOTSERVER_OB_TENANT_RECOVERY_SERVICE_H -#define OCEANBASE_ROOTSERVER_OB_TENANT_RECOVERY_SERVICE_H +#ifndef OCEANBASE_ROOTSERVER_OB_LS_RECOVERY_SERVICE_H +#define OCEANBASE_ROOTSERVER_OB_LS_RECOVERY_SERVICE_H +#include "common/ob_member_list.h" // common::ObMemberList #include "lib/thread/ob_reentrant_thread.h"//ObRsReentrantThread #include "lib/utility/ob_print_utils.h" //TO_STRING_KV +#include "share/ob_tenant_role.h"//ObTenantRole #include "share/ob_tenant_info_proxy.h"//ObAllTenantInfo +#include "share/ls/ob_ls_recovery_stat_operator.h" // ObLSRecoveryStatOperator #include "lib/lock/ob_spin_rwlock.h" //lock +#include "rootserver/ob_rs_async_rpc_proxy.h" //ObGetLSReplayedScnProxy namespace oceanbase { namespace common { class ObMySQLProxy; +class ObMySQLTransaction; } namespace share { class ObLSID; class SCN; +struct ObLSRecoveryStat; } namespace storage { @@ -40,15 +46,15 @@ namespace rootserver * standby machine-readable timestamp of the majority, the minimum standby * machine-readable timestamp of all replicas, the synchronization point, etc. * Statistics for the syslog stream are not in this thread.*/ -class ObTenantRecoveryReportor : public share::ObReentrantThread +class ObLSRecoveryReportor : public share::ObReentrantThread { public: - ObTenantRecoveryReportor() + ObLSRecoveryReportor() : is_inited_(false), tenant_id_(common::OB_INVALID_TENANT_ID), sql_proxy_(nullptr) {} - ~ObTenantRecoveryReportor() {} - static int mtl_init(ObTenantRecoveryReportor *&ka); + ~ObLSRecoveryReportor() {} + static int mtl_init(ObLSRecoveryReportor *&ka); int init(); void destroy(); int start(); @@ -60,9 +66,14 @@ public: } virtual void run2() override; //description: update ls recovery - static int update_ls_recovery(storage::ObLS *ls, common::ObMySQLProxy *sql_proxy); + int update_ls_recovery(storage::ObLS *ls, common::ObMySQLProxy *sql_proxy); static int get_readable_scn(const share::ObLSID &id, share::SCN &read_scn); + static int update_sys_ls_recovery_stat_and_tenant_info(share::ObLSRecoveryStat &ls_recovery_stat, + const share::ObTenantRole &tenant_role, + const bool update_readable_scn, + common::ObMySQLTransaction &trans); + static int update_tenant_info_in_trans(const share::ObAllTenantInfo &old_tenant_info, common::ObMySQLTransaction &trans); private: static int get_sync_point_(const share::ObLSID &id, share::SCN &scn, share::SCN &read_scn); int update_ls_recovery_stat_(); @@ -80,11 +91,11 @@ private: int update_replayable_point_from_tenant_info_(); int update_replayable_point_from_meta_(); int submit_tenant_refresh_schema_task_(); - DISALLOW_COPY_AND_ASSIGN(ObTenantRecoveryReportor); + DISALLOW_COPY_AND_ASSIGN(ObLSRecoveryReportor); }; } // namespace rootserver } // namespace oceanbase -#endif /* !OCEANBASE_ROOTSERVER_OB_TENANT_RECOVERY_SERVICE_H */ +#endif /* !OCEANBASE_ROOTSERVER_OB_LS_RECOVERY_SERVICE_H */ diff --git a/src/rootserver/ob_ls_recovery_stat_handler.cpp b/src/rootserver/ob_ls_recovery_stat_handler.cpp old mode 100644 new mode 100755 index 5c61e69cf..f68508a55 --- a/src/rootserver/ob_ls_recovery_stat_handler.cpp +++ b/src/rootserver/ob_ls_recovery_stat_handler.cpp @@ -18,6 +18,8 @@ #include "lib/utility/ob_print_utils.h" // TO_STRING_KV #include "logservice/ob_log_service.h" // ObLogService #include "rootserver/ob_tenant_info_loader.h" // ObTenantInfoLoader +#include "rootserver/ob_ls_recovery_reportor.h" // ObLSRecoveryReportor +#include "rootserver/ob_ls_service_helper.h"//ObLSServiceHelper namespace oceanbase { @@ -66,16 +68,15 @@ int ObLSRecoveryStatHandler::check_inner_stat_() int ObLSRecoveryStatHandler::get_ls_replica_readable_scn(share::SCN &readable_scn) { int ret = OB_SUCCESS; - share::SCN unused_sync_scn = SCN::min_scn(); readable_scn = SCN::min_scn(); share::SCN readable_scn_to_increase = SCN::min_scn(); if (OB_FAIL(check_inner_stat_())) { LOG_WARN("inner stat error", KR(ret), K(is_inited_)); } else if (OB_FAIL(ls_->get_max_decided_scn(readable_scn))) { - LOG_WARN("failed to get readable scn", KR(ret), KPC_(ls)); + LOG_WARN("failed to get_max_decided_scn", KR(ret), KPC_(ls)); } else if (FALSE_IT(readable_scn_to_increase = readable_scn)) { - } else if (OB_FAIL(increase_ls_replica_readable_scn_(readable_scn_to_increase, unused_sync_scn))) { + } else if (OB_FAIL(increase_ls_replica_readable_scn_(readable_scn_to_increase))) { if (OB_NOT_MASTER == ret) { // if not master, do not increase_ls_replica_readable_scn ret = OB_SUCCESS; @@ -89,10 +90,10 @@ int ObLSRecoveryStatHandler::get_ls_replica_readable_scn(share::SCN &readable_sc return ret; } -int ObLSRecoveryStatHandler::increase_ls_replica_readable_scn_(SCN &readable_scn, SCN &sync_scn) +int ObLSRecoveryStatHandler::increase_ls_replica_readable_scn_(SCN &readable_scn) { int ret = OB_SUCCESS; - sync_scn = SCN::min_scn(); + SCN sync_scn = SCN::min_scn(); int64_t first_proposal_id = palf::INVALID_PROPOSAL_ID; int64_t second_proposal_id = palf::INVALID_PROPOSAL_ID; common::ObRole first_role; @@ -100,7 +101,6 @@ int ObLSRecoveryStatHandler::increase_ls_replica_readable_scn_(SCN &readable_scn logservice::ObLogService *ls_svr = MTL(logservice::ObLogService*); rootserver::ObTenantInfoLoader *tenant_info_loader = MTL(rootserver::ObTenantInfoLoader*); SCN replayable_scn = SCN::base_scn(); - palf::PalfHandleGuard palf_handle_guard; if (OB_FAIL(check_inner_stat_())) { LOG_WARN("inner stat error", KR(ret), K_(is_inited)); @@ -108,22 +108,20 @@ int ObLSRecoveryStatHandler::increase_ls_replica_readable_scn_(SCN &readable_scn ret = OB_ERR_UNEXPECTED; LOG_WARN("pointer is null", KR(ret), KP(ls_svr), KP(tenant_info_loader)); } else if (OB_FAIL(ls_svr->get_palf_role(ls_->get_ls_id(), first_role, first_proposal_id))) { - LOG_WARN("failed to get first role", KR(ret), K(ls_->get_ls_id()), KP(ls_svr)); + LOG_WARN("failed to get first role", KR(ret), K(ls_->get_ls_id()), KP(ls_svr), KPC_(ls)); } else if (!is_strong_leader(first_role)) { ret = OB_NOT_MASTER; // Since the follower replica also call this function, return OB_NOT_MASTER does not LOG_WARN } else if (!readable_scn.is_valid_and_not_min()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", KR(ret), K(readable_scn)); - } else if (OB_FAIL(ls_svr->open_palf(ls_->get_ls_id(), palf_handle_guard))) { - LOG_WARN("failed to open palf", KR(ret), K_(ls)); // scn get order: read_scn before replayable_scn before sync_scn } else if (OB_FAIL(tenant_info_loader->get_replayable_scn(replayable_scn))) { LOG_WARN("failed to get replayable_scn", KR(ret)); - } else if (OB_FAIL(palf_handle_guard.get_end_scn(sync_scn))) { - LOG_WARN("failed to get end ts", KR(ret), K_(ls)); + } else if (OB_FAIL(ObLSServiceHelper::get_ls_replica_sync_scn(MTL_ID(), ls_->get_ls_id(), sync_scn))) { + LOG_WARN("failed to get ls sync scn", KR(ret), "tenant_id", MTL_ID()); } else if (OB_FAIL(ls_svr->get_palf_role(ls_->get_ls_id(), second_role, second_proposal_id))) { - LOG_WARN("failed to get second role", KR(ret), K(ls_->get_ls_id()), KP(ls_svr)); + LOG_WARN("failed to get second role", KR(ret), K(ls_->get_ls_id()), KP(ls_svr), KPC_(ls)); } else if (!(first_proposal_id == second_proposal_id && first_role == second_role)) { ret = OB_NOT_MASTER; @@ -136,12 +134,377 @@ int ObLSRecoveryStatHandler::increase_ls_replica_readable_scn_(SCN &readable_scn // two scenarios // 1. when sync scn is pushed forward in switchover // 2. wait offline LS - sync_scn = readable_scn = replayable_scn; + readable_scn = replayable_scn; } } return ret; } +int ObLSRecoveryStatHandler::get_ls_level_recovery_stat(ObLSRecoveryStat &ls_recovery_stat) +{ + int ret = OB_SUCCESS; + share::SCN sync_scn = SCN::min_scn(); + share::SCN readable_scn = SCN::min_scn(); + logservice::ObLogService *ls_svr = MTL(logservice::ObLogService*); + common::ObRole role; + int64_t first_proposal_id = palf::INVALID_PROPOSAL_ID; + int64_t second_proposal_id = palf::INVALID_PROPOSAL_ID; + ls_recovery_stat.reset(); + + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("inner stat error", KR(ret), K_(is_inited)); + } else if (OB_ISNULL(ls_svr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("pointer is null", KR(ret), KP(ls_svr)); + } else if (OB_FAIL(ls_svr->get_palf_role(ls_->get_ls_id(), role, first_proposal_id))) { + LOG_WARN("failed to get first role", KR(ret), K(ls_id), KPC_(ls)); + } else if (!is_strong_leader(role)) { + ret = OB_NOT_MASTER; + LOG_TRACE("not leader", KR(ret), K(role), KPC_(ls)); + } else if (OB_FAIL(do_get_ls_level_readable_scn_(readable_scn))) { + LOG_WARN("failed to do_get_ls_level_readable_scn_", KR(ret), KPC_(ls)); + // scn get order: read_scn before replayable_scn before sync_scn + } else if (OB_FAIL(ObLSServiceHelper::get_ls_replica_sync_scn(MTL_ID(), ls_->get_ls_id(), sync_scn))) { + LOG_WARN("failed to get ls sync scn", KR(ret), "tenant_id", MTL_ID()); + } else if (OB_FAIL(ls_recovery_stat.init_only_recovery_stat(tenant_id_, ls_->get_ls_id(), + sync_scn, readable_scn))) { + LOG_WARN("failed to init ls recovery stat", KR(ret), KPC_(ls), K_(tenant_id), K(sync_scn), K(readable_scn)); + } else if (OB_FAIL(ls_svr->get_palf_role(ls_->get_ls_id(), role, second_proposal_id))) { + LOG_WARN("failed to get palf role again", KR(ret), K(role), KPC_(ls)); + } else if (first_proposal_id != second_proposal_id || !is_strong_leader(role)) { + ret = OB_EAGAIN; + LOG_INFO("role changed, try again", KR(ret), K(role), + K(first_proposal_id), K(second_proposal_id), KPC_(ls)); + } + + return ret; +} + +int ObLSRecoveryStatHandler::do_get_ls_level_readable_scn_(SCN &read_scn) +{ + int ret = OB_SUCCESS; + palf::AccessMode access_mode; + int64_t unused_mode_version; + share::SCN majority_min_readable_scn = SCN::min_scn(); + read_scn = SCN::min_scn(); + + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("inner stat error", KR(ret), K_(is_inited)); + // scn get order: read_scn before replayable_scn before sync_scn + } else if (OB_FAIL(ls_->get_max_decided_scn(read_scn))) { + LOG_WARN("failed to get_max_decided_scn", KR(ret), KPC_(ls)); + } else if (OB_FAIL(get_majority_readable_scn_(read_scn /* leader_readable_scn */, majority_min_readable_scn))) { + LOG_WARN("failed to get_majority_readable_scn_", KR(ret), K(read_scn), KPC_(ls)); + } else { + read_scn = share::SCN::min(majority_min_readable_scn, read_scn /* leader_readable_scn */); + } + + LOG_TRACE("do_get_ls_level_readable_scn_ finished", KR(ret), KPC_(ls), K(read_scn), + K(majority_min_readable_scn)); + + return ret; +} + +int ObLSRecoveryStatHandler::construct_new_member_list_( + const common::ObMemberList &member_list_ori, + const common::GlobalLearnerList °raded_list, + const int64_t paxos_replica_number_ori, + ObIArray &member_list_new, + int64_t &paxos_replica_number_new) +{ + int ret = OB_SUCCESS; + bool found_me = false; + member_list_new.reset(); + paxos_replica_number_new = paxos_replica_number_ori; + if (OB_UNLIKELY(0 >= member_list_ori.get_member_number() + || 0 > degraded_list.get_member_number() + || 0 >= paxos_replica_number_ori)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(member_list_ori), K(degraded_list), K(paxos_replica_number_ori)); + } else { + common::ObMember member; + + for (int64_t i = 0; OB_SUCC(ret) && i < member_list_ori.get_member_number(); ++i) { + member.reset(); + if (OB_FAIL(member_list_ori.get_member_by_index(i, member))) { + LOG_WARN("get_member_by_index failed", KR(ret), K(i)); + } else if (OB_UNLIKELY(!member.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("member is invalid", KR(ret), K(member)); + } else if (degraded_list.contains(member.get_server())) { + paxos_replica_number_new--; + // do not count degraded member + } else if (OB_FAIL(member_list_new.push_back(member.get_server()))) { + LOG_WARN("fail to push back member_list_new", KR(ret), K(member), K(member_list_new)); + } else if (member.get_server() == GCTX.self_addr()) { + found_me = true; + } + } + + if (OB_FAIL(ret)) { + } else if (!found_me) { + ret = OB_EAGAIN; + LOG_WARN("current leader degraded, try again", KR(ret), K(member_list_ori), K(degraded_list), + K(paxos_replica_number_ori), K(member_list_new), K(paxos_replica_number_new)); + } + } + return ret; +} + +int ObLSRecoveryStatHandler::get_palf_stat_( + palf::PalfStat &palf_stat) +{ + int ret = OB_SUCCESS; + palf_stat.reset(); + logservice::ObLogService *log_service = NULL; + palf::PalfHandleGuard palf_handle_guard; + + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("inner stat error", KR(ret), K_(is_inited)); + } else if (OB_ISNULL(log_service = MTL(logservice::ObLogService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get MTL log_service", KR(ret), K_(tenant_id), KPC_(ls)); + } else if (OB_FAIL(log_service->open_palf(ls_->get_ls_id(), palf_handle_guard))) { + LOG_WARN("failed to open palf", KR(ret), K_(tenant_id), KPC_(ls)); + } else if (OB_FAIL(palf_handle_guard.stat(palf_stat))) { + LOG_WARN("get palf_stat failed", KR(ret), KPC_(ls)); + } + + return ret; +} + +int ObLSRecoveryStatHandler::get_latest_palf_stat_( + palf::PalfStat &palf_stat) +{ + int ret = OB_SUCCESS; + palf_stat.reset(); + common::ObMemberList ob_member_list_latest; + int64_t paxos_replica_number_latest = 0; + + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("inner stat error", KR(ret), K_(is_inited)); + } else if (OB_FAIL(get_palf_stat_(palf_stat))) { + LOG_WARN("get palf_stat failed", KR(ret), KPC_(ls)); + } else if (OB_FAIL(ls_->get_paxos_member_list(ob_member_list_latest, paxos_replica_number_latest))) { + LOG_WARN("get latest paxos member_list failed", KR(ret), KPC_(ls)); + } else if (!ob_member_list_latest.member_addr_equal(palf_stat.paxos_member_list_) + || paxos_replica_number_latest != palf_stat.paxos_replica_num_) { + ret = OB_EAGAIN; + LOG_WARN("palf_stat is not latest, try again", KR(ret), KPC_(ls), K(ob_member_list_latest), + K(paxos_replica_number_latest), K(palf_stat)); + } + + return ret; +} + +int ObLSRecoveryStatHandler::get_majority_readable_scn_( + const share::SCN &leader_readable_scn, + share::SCN &majority_min_readable_scn) +{ + int ret = OB_SUCCESS; + majority_min_readable_scn = leader_readable_scn; + palf::PalfStat palf_stat_first; + palf::PalfStat palf_stat_second; + ObArray member_list_new; + int64_t paxos_replica_number_new = 0; + + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("inner stat error", KR(ret), K_(is_inited)); + } else if (!leader_readable_scn.is_valid_and_not_min()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(leader_readable_scn)); + } else if (OB_FAIL(get_latest_palf_stat_(palf_stat_first))) { + LOG_WARN("get latest palf_stat failed", KR(ret), KPC_(ls)); + } else if (OB_FAIL(construct_new_member_list_(palf_stat_first.paxos_member_list_, + palf_stat_first.degraded_list_, + palf_stat_first.paxos_replica_num_, + member_list_new, + paxos_replica_number_new))) { + LOG_WARN("construct_new_member_list failed", KR(ret), KPC_(ls), K(palf_stat_first)); + } else if (OB_FAIL(do_get_majority_readable_scn_(member_list_new, + leader_readable_scn, rootserver::majority(paxos_replica_number_new), majority_min_readable_scn))) { + LOG_WARN("do_get_majority_readable_scn_ failed", KR(ret), K(member_list_new), K(leader_readable_scn), + K(paxos_replica_number_new), K(palf_stat_first), K(majority_min_readable_scn)); + } else if (OB_FAIL(get_latest_palf_stat_(palf_stat_second))) { + LOG_WARN("get latest palf_stat failed", KR(ret), KPC_(ls)); + } else if (palf_stat_first.config_version_ != palf_stat_second.config_version_) { + ret = OB_EAGAIN; + LOG_WARN("config_version changed, try again", KR(ret), K(palf_stat_first), K(palf_stat_second)); + } + + return ret; +} + +int ObLSRecoveryStatHandler::do_get_majority_readable_scn_( + const ObIArray &ob_member_list, + const share::SCN &leader_readable_scn, + const int64_t majority_cnt, + share::SCN &majority_min_readable_scn) +{ + int ret = OB_SUCCESS; + majority_min_readable_scn = SCN::min_scn(); + const common::ObAddr self_addr = GCTX.self_addr(); + ObTimeoutCtx ctx; + ObSEArray inactive_members; + obrpc::ObGetLSReplayedScnArg arg; + const int64_t need_query_member_cnt = majority_cnt - 1; + + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("inner stat error", KR(ret), K_(is_inited)); + } else if (!is_user_tenant(tenant_id_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument. only support for user tenant", KR(ret), K_(tenant_id)); + } else if (OB_ISNULL(GCTX.server_tracer_) || OB_ISNULL(GCTX.srv_rpc_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pointer is null", KR(ret), KP(GCTX.server_tracer_), KP(GCTX.srv_rpc_proxy_)); + } else if (!leader_readable_scn.is_valid_and_not_min() + || ob_member_list.count() <= 0 + || !self_addr.is_valid() + || 0 >= majority_cnt + || 0 > need_query_member_cnt) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(leader_readable_scn), K(self_addr), + K(majority_cnt), K(need_query_member_cnt), K(ob_member_list)); + } else if (0 == need_query_member_cnt) { + ret = OB_SUCCESS; + majority_min_readable_scn = leader_readable_scn; + LOG_INFO("single replica, majority_min_readable_scn = leader_readable_scn", KR(ret), + K(ob_member_list), K(leader_readable_scn)); + } else if (OB_FAIL(arg.init(tenant_id_, ls_->get_ls_id()))) { + LOG_WARN("failed to init arg", KR(ret), K_(tenant_id), KPC_(ls)); + } else { + int tmp_ret = OB_SUCCESS; + ObGetLSReplayedScnProxy proxy( + *GCTX.srv_rpc_proxy_, &obrpc::ObSrvRpcProxy::get_ls_replayed_scn); + int64_t rpc_count = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < ob_member_list.count(); ++i) { + const auto member = ob_member_list.at(i); + + bool alive = true; + int64_t trace_time; + if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) { + LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx)); + } else if (OB_UNLIKELY(!member.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("member is invalid", KR(ret), K(member)); + } else if (self_addr == member) { + //skip myself + } else if (OB_FAIL(GCTX.server_tracer_->is_alive(member, alive, trace_time))) { + LOG_WARN("check server alive failed", KR(ret), K(member)); + } else if (!alive) { + //not send to alive + if (OB_FAIL(inactive_members.push_back(member))) { + LOG_WARN("fail to push back inactive_members", KR(ret), K(member), K(inactive_members)); + } + // use meta rpc process thread + } else if (OB_TMP_FAIL(proxy.call(member, ctx.get_timeout(), gen_meta_tenant_id(tenant_id_), arg))) { + LOG_WARN("failed to send rpc", KR(tmp_ret), K(member), K(i), K(ctx), K_(tenant_id), K(arg), K(ob_member_list)); + } else { + rpc_count++; + } + } + + if (OB_FAIL(ret)) { + } else if (need_query_member_cnt > rpc_count) { + // If the number of alive servers is not enough for a majority, send to majority servers + for (int64_t i = 0; OB_SUCC(ret) && i < inactive_members.count(); ++i) { + if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) { + LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx)); + } else if (OB_TMP_FAIL(proxy.call(inactive_members.at(i), ctx.get_timeout(), tenant_id_, arg))) { + LOG_WARN("failed to send rpc", KR(tmp_ret), K(i), K(ctx), K_(tenant_id), K(arg), K(inactive_members)); + } else { + rpc_count++; + } + } + } + + //get result + ObArray return_code_array; + if (OB_SUCCESS != (tmp_ret = proxy.wait_all(return_code_array))) { + LOG_WARN("wait all batch result failed", KR(ret), KR(tmp_ret)); + ret = OB_SUCCESS == ret ? tmp_ret : ret; + } else if (OB_FAIL(ret)) { + } else if (OB_FAIL(calc_majority_min_readable_scn_( + leader_readable_scn, + majority_cnt, + return_code_array, + proxy, + rpc_count, + majority_min_readable_scn))) { + LOG_WARN("failed to calc_majority_min_readable_scn", KR(ret), K(leader_readable_scn), + K(ob_member_list), K(return_code_array), K(rpc_count)); + } + } + + return ret; +} + +int ObLSRecoveryStatHandler::calc_majority_min_readable_scn_( + const SCN &leader_readable_scn, + const int64_t majority_cnt, + const ObIArray &return_code_array, + const ObGetLSReplayedScnProxy &proxy, + const int64_t rpc_count, + SCN &majority_min_readable_scn) +{ + int ret = OB_SUCCESS; + ObArray readable_scn_list; + majority_min_readable_scn = SCN::max_scn(); + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("inner stat error", KR(ret), K_(is_inited)); + } else if (!leader_readable_scn.is_valid_and_not_min() || 0 >= majority_cnt || 0 >= rpc_count) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(leader_readable_scn), K(majority_cnt), K(rpc_count)); + } else if (rpc_count != return_code_array.count() || + rpc_count != proxy.get_results().count()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("rpc count not equal to result count", KR(ret), + K(rpc_count), K(return_code_array), "arg count", + proxy.get_args().count(), K(proxy.get_results().count())); + } else if (OB_FAIL(readable_scn_list.push_back(leader_readable_scn))) { + LOG_WARN("failed to push back", KR(ret), K(leader_readable_scn), K(readable_scn_list)); + } else if (OB_FAIL(ret)) { + } else { + ObGetLSReplayedScnRes res; + int tmp_ret = OB_SUCCESS; + + for (int64_t i = 0; OB_SUCC(ret) && i < return_code_array.count(); ++i) { + tmp_ret = return_code_array.at(i); + // skip error server + if (OB_SUCCESS != tmp_ret) { + LOG_WARN("send rpc is failed", KR(tmp_ret), K(i), K(return_code_array)); + } else { + const auto *result = proxy.get_results().at(i); + if (OB_ISNULL(result)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret), K(i), K(return_code_array)); + } else if (!result->get_cur_readable_scn().is_valid_and_not_min()) { + LOG_WARN("not valid scn", KR(ret), K(i), KPC(result)); + // skip this server + } else if (OB_FAIL(readable_scn_list.push_back(result->get_cur_readable_scn()))) { + LOG_WARN("failed to push back", KR(ret), K(i), KPC(result), K(readable_scn_list)); + } + } + } + + if (OB_FAIL(ret)) { + } else if (readable_scn_list.count() < majority_cnt) { + ret = OB_EAGAIN; + LOG_WARN("can not get majority readable_scn count", KR(ret), K(majority_cnt), K(readable_scn_list), K(return_code_array)); + } else { + (void)std::sort(readable_scn_list.begin(), readable_scn_list.end(), std::greater()); + for (int64_t i = 0; OB_SUCC(ret) && i < readable_scn_list.count() && i < majority_cnt; ++i) { + if (majority_min_readable_scn > readable_scn_list.at(i)) { + majority_min_readable_scn = readable_scn_list.at(i); + } + } + LOG_TRACE("calculate majority min readable_scn finished", KR(ret), K(leader_readable_scn), K(ls_id), + K(majority_min_readable_scn), K(readable_scn_list), K(majority_cnt), K(return_code_array)); + } + } + return ret; +} + +} } -} \ No newline at end of file diff --git a/src/rootserver/ob_ls_recovery_stat_handler.h b/src/rootserver/ob_ls_recovery_stat_handler.h index e6f7c11ca..86878b9ae 100644 --- a/src/rootserver/ob_ls_recovery_stat_handler.h +++ b/src/rootserver/ob_ls_recovery_stat_handler.h @@ -16,6 +16,7 @@ #include "lib/ob_define.h" #include "rootserver/ob_rs_async_rpc_proxy.h" //ObGetLSReplayedScnProxy #include "share/ls/ob_ls_recovery_stat_operator.h" // ObLSRecoveryStatOperator +#include "logservice/palf/palf_handle_impl.h" // PalfStat namespace oceanbase { @@ -47,6 +48,15 @@ public: */ int get_ls_replica_readable_scn(share::SCN &readable_scn); + /** + * @description: + * get ls level recovery_stat by LS leader. + * If follower LS replica call this function, it will return OB_NOT_MASTER. + * @param[out] ls_recovery_stat + * @return return code + */ + int get_ls_level_recovery_stat(share::ObLSRecoveryStat &ls_recovery_stat); + TO_STRING_KV(K_(tenant_id), K_(ls)); private: @@ -58,10 +68,57 @@ private: * @param[in/out] readable_scn * in: actual readable_scn * out: increased readable_scn - * @param[out] sync_scn increased sync_scn * @return return code */ - int increase_ls_replica_readable_scn_(share::SCN &readable_scn, share::SCN &sync_scn); + int increase_ls_replica_readable_scn_(share::SCN &sync_scn); + + int do_get_ls_level_readable_scn_(share::SCN &read_scn); + + /** + * @description: + * do not use this function. + * Since PalfHandleGuard holds lock, it may cause deadlock with other palf operations, + * so use a separate function to obtain palf_stat, please do not add new operations in this function + * @param[out] palf_stat + * @return return code + */ + int get_palf_stat_( + palf::PalfStat &palf_stat); + + /** + * @description: + * palf_stat get from palf_handle_guard.stat can guarantee that + * is a snapshot, but because it is a cache, it may be not latest, in order to ensure that + * the latest palf_stat can be obtained, it is necessary to obtain the latest member list + * and compare with palf_stat. If they are same, the obtained palf_stat is considered to be latest. + * @param[out] palf_stat + * @return return code + */ + int get_latest_palf_stat_( + palf::PalfStat &palf_stat); + + int get_majority_readable_scn_( + const share::SCN &leader_readable_scn, + share::SCN &majority_min_readable_scn); + int do_get_majority_readable_scn_( + const ObIArray &ob_member_list, + const share::SCN &leader_readable_scn, + const int64_t need_query_member_cnt, + share::SCN &majority_min_readable_scn); + int calc_majority_min_readable_scn_( + const share::SCN &leader_readable_scn, + const int64_t majority_cnt, + const ObIArray &return_code_array, + const ObGetLSReplayedScnProxy &proxy, + const int64_t rpc_count, + share::SCN &majority_min_readable_scn); + + int construct_new_member_list_( + const common::ObMemberList &member_list_ori, + const common::GlobalLearnerList °raded_list, + const int64_t paxos_replica_number_ori, + ObIArray &member_list_new, + int64_t &paxos_replica_number_new); DISALLOW_COPY_AND_ASSIGN(ObLSRecoveryStatHandler); diff --git a/src/rootserver/ob_ls_service_helper.cpp b/src/rootserver/ob_ls_service_helper.cpp new file mode 100755 index 000000000..245d7f04a --- /dev/null +++ b/src/rootserver/ob_ls_service_helper.cpp @@ -0,0 +1,1231 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX RS +#include "ob_ls_service_helper.h" +#include "lib/profile/ob_trace_id.h" +#include "share/ob_errno.h" +#include "share/ob_max_id_fetcher.h" +#include "share/schema/ob_schema_struct.h"//ObTenantInfo +#include "share/schema/ob_schema_service.h"//ObMultiSchemaService +#include "share/ls/ob_ls_creator.h" //ObLSCreator +#include "share/ls/ob_ls_life_manager.h"//ObLSLifeAgentManager +#include "share/ls/ob_ls_table_operator.h"//ObLSTableOpertor +#include "share/ob_primary_zone_util.h"//ObPrimaryZoneUtil +#include "share/ob_unit_table_operator.h"//ObUnitTableOperator +#include "share/ob_zone_table_operation.h" //ObZoneTableOperation +#include "share/ob_share_util.h"//ObShareUtil +#include "share/restore/ob_physical_restore_table_operator.h"//ObTenantRestoreTableOperator +#include "share/ob_standby_upgrade.h"//ObStandbyUpgrade +#include "share/ob_upgrade_utils.h"//ObUpgradeChecker +#include "share/rc/ob_tenant_base.h"//MTL_SWITCH +#include "observer/ob_server_struct.h"//GCTX +#include "rootserver/ob_recovery_ls_service.h"//ObRecoveryLSHelper +#include "rootserver/ob_tenant_thread_helper.h"//get_zone_priority +#include "storage/tx_storage/ob_ls_map.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/tx_storage/ob_ls_handle.h" //ObLSHandle +#include "logservice/palf/palf_base_info.h"//PalfBaseInfo +#include "logservice/ob_log_service.h"//ObLogService + +namespace oceanbase +{ +using namespace common; +using namespace share; +using namespace transaction; +using namespace palf; +namespace rootserver +{ +/////////ObUnitGroupInfo +bool ObUnitGroupInfo::is_valid() const +{ + return OB_INVALID_ID != unit_group_id_ + && share::ObUnit::UNIT_STATUS_MAX != unit_status_; +} + +int ObUnitGroupInfo::init(const uint64_t unit_group_id, + const share::ObUnit::Status &unit_status) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_ID == unit_group_id + || share::ObUnit::UNIT_STATUS_MAX == unit_status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(unit_group_id), K(unit_status)); + } else { + unit_group_id_ = unit_group_id; + unit_status_ = unit_status; + } + return ret; +} + +void ObUnitGroupInfo::reset() +{ + unit_group_id_ = OB_INVALID_ID; + unit_status_ = share::ObUnit::UNIT_STATUS_MAX; + ls_group_ids_.reset(); +} + +int ObUnitGroupInfo::assign(const ObUnitGroupInfo &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + if (OB_FAIL(ls_group_ids_.assign(other.ls_group_ids_))) { + LOG_WARN("failed to assign", KR(ret), K(other)); + } else { + unit_group_id_ = other.unit_group_id_; + unit_status_ = other.unit_status_; + } + } + return ret; +} + +int ObUnitGroupInfo::remove_ls_group(const uint64_t ls_group_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(ObLSID::MIN_USER_LS_GROUP_ID >= ls_group_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls group id is invalid", KR(ret), K(ls_group_id)); + } else { + bool remove = false; + for (int64_t i = 0; OB_SUCC(ret) && i < ls_group_ids_.count(); ++i) { + if (ls_group_ids_.at(i) == ls_group_id) { + remove = true; + if (OB_FAIL(ls_group_ids_.remove(i))) { + LOG_WARN("failed to remove from array", KR(ret), K(i), + K(ls_group_id), "this", *this); + } + break; + } + } + if (OB_SUCC(ret) && !remove) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("failed to find ls group id", KR(ret), + K(ls_group_id), "this", *this); + } + } + return ret; +} + +bool ObUnitGroupInfo::operator==(const ObUnitGroupInfo &other) const +{ + return unit_group_id_ == other.unit_group_id_ + && unit_status_ == other.unit_status_; +} + +////////////ObLSGroupInfo +bool ObLSGroupInfo::is_valid() const +{ + return OB_INVALID_ID != unit_group_id_ + && OB_INVALID_ID != ls_group_id_; +} + +int ObLSGroupInfo::init(const uint64_t unit_group_id, + const uint64_t ls_group_id) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_UNLIKELY(OB_INVALID_ID == unit_group_id + || OB_INVALID_ID == ls_group_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(unit_group_id), K(ls_group_id)); + } else { + unit_group_id_ = unit_group_id; + ls_group_id_ = ls_group_id; + } + return ret; +} + +int ObLSGroupInfo::assign(const ObLSGroupInfo &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + reset(); + if (OB_FAIL(ls_ids_.assign(other.ls_ids_))) { + LOG_WARN("failed to assign ls ids", KR(ret), K(other)); + } else { + unit_group_id_ = other.unit_group_id_; + ls_group_id_ = other.ls_group_id_; + } + } + return ret; +} + +void ObLSGroupInfo::reset() +{ + ls_group_id_ = OB_INVALID_ID; + unit_group_id_ = OB_INVALID_ID; + ls_ids_.reset(); +} + +int ObLSGroupInfo::remove_ls(const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls id is invalid", KR(ret), K(ls_id)); + } else { + bool remove = false; + for (int64_t i = 0; OB_SUCC(ret) && i < ls_ids_.count(); ++i) { + if (ls_ids_.at(i) == ls_id) { + remove = true; + if (OB_FAIL(ls_ids_.remove(i))) { + LOG_WARN("failed to remove from array", KR(ret), K(i), + K(ls_id), "this", *this); + } + break; + } + } + if (OB_SUCC(ret) && !remove) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("failed to find ls id", KR(ret), + K(ls_id), "this", *this); + } + } + return ret; + +} + +///////////////ObLSStatusMachineParameter +//no need check status valid or ls_status is valid +int ObLSStatusMachineParameter::init(const share::ObLSID &id, + const share::ObLSStatusInfo &status_info, + const share::ObLSAttr &ls_info) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("id is invalid", KR(ret), K(id)); + } else if (OB_FAIL(status_info_.assign(status_info))) { + LOG_WARN("failed to assign status info", KR(ret), K(status_info)); + } else if (OB_FAIL(ls_info_.assign(ls_info))) { + LOG_WARN("failed to assign ls info", KR(ret), K(ls_info)); + } else { + ls_id_ = id; + } + return ret; +} + +void ObLSStatusMachineParameter::reset() +{ + ls_id_.reset(); + ls_info_.reset(); + status_info_.reset(); +} + +//////ObLSServiceHelper//////////// +int ObLSServiceHelper::construct_ls_status_machine( + const bool lock_sys_ls, + const uint64_t tenant_id, + ObMySQLProxy *sql_proxy, + common::ObIArray &status_machine_array) +{ + int ret = OB_SUCCESS; + status_machine_array.reset(); + share::ObLSStatusInfoArray status_info_array; + share::ObLSAttrArray ls_array; + share::ObLSAttrOperator ls_operator(tenant_id, sql_proxy); + if (OB_ISNULL(sql_proxy) || !is_valid_tenant_id(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("sql proxy is null or tenant id is invalid", KR(ret), KP(sql_proxy), K(tenant_id)); + } else if (OB_FAIL(ls_operator.get_all_ls_by_order(lock_sys_ls, ls_array))) { + LOG_WARN("failed to get get all ls", KR(ret), K(lock_sys_ls)); + } else { + ObLSStatusOperator status_op; + if (OB_FAIL(status_op.get_all_ls_status_by_order( + tenant_id, status_info_array, *sql_proxy))) { + LOG_WARN("failed to get all ls status by order", KR(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(0 == ls_array.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls array can not be empty", KR(ret), K(ls_array), K(status_info_array)); + } else { + // merge by sort + int64_t status_index = 0; + int64_t ls_index = 0; + ObLSStatusMachineParameter status_machine; + const int64_t status_count = status_info_array.count(); + const int64_t ls_count = ls_array.count(); + share::ObLSStatusInfo status_info; + ObLSID ls_id; + ObLSAttr ls_info; + while ((status_index < status_count || ls_index < ls_count) && OB_SUCC(ret)) { + status_machine.reset(); + if (status_index == status_count) { + //status already end + if (OB_FAIL(ls_info.assign(ls_array.at(ls_index)))) { + LOG_WARN("failed to assign ls info", KR(ret), K(ls_index), K(ls_array)); + } else { + ls_id = ls_array.at(ls_index).get_ls_id(); + status_info.reset(); + ls_index++; + } + } else if (ls_index == ls_count) { + //ls already end + if (OB_FAIL(status_info.assign(status_info_array.at(status_index)))) { + LOG_WARN("failed to assign status info", KR(ret), K(status_index)); + } else { + status_index++; + ls_id = status_info.ls_id_; + ls_info.reset(); + } + } else { + const share::ObLSStatusInfo &tmp_status_info = status_info_array.at(status_index); + const share::ObLSAttr &tmp_ls_info = ls_array.at(ls_index); + if (tmp_status_info.ls_id_ == tmp_ls_info.get_ls_id()) { + status_index++; + ls_index++; + ls_id = tmp_status_info.ls_id_; + if (OB_FAIL(ls_info.assign(tmp_ls_info))) { + LOG_WARN("failed to assign tmp ls info", KR(ret), K(tmp_ls_info)); + } else if (OB_FAIL(status_info.assign(tmp_status_info))) { + LOG_WARN("failed to assign status info", KR(ret), K(tmp_status_info)); + } + } else if (tmp_status_info.ls_id_ > tmp_ls_info.get_ls_id()) { + ls_index++; + ls_id = tmp_ls_info.get_ls_id(); + status_info.reset(); + if (OB_FAIL(ls_info.assign(tmp_ls_info))) { + LOG_WARN("failed to assign tmp ls info", KR(ret), K(tmp_ls_info)); + } + } else { + status_index++; + ls_id = tmp_status_info.ls_id_; + ls_info.reset(); + if (OB_FAIL(status_info.assign(tmp_status_info))) { + LOG_WARN("failed to assign status info", KR(ret), K(tmp_status_info)); + } + } + } + if (FAILEDx(status_machine.init(ls_id, status_info, ls_info))) { + LOG_WARN("failed to init status machine", KR(ret), K(ls_id), K(status_info), K(ls_info)); + } else if (OB_FAIL(status_machine_array.push_back(status_machine))) { + LOG_WARN("failed to push back status machine", KR(ret), K(status_machine)); + } + } // end while + + } + return ret; +} + +int ObLSServiceHelper::fetch_new_ls_group_id( + ObMySQLProxy *sql_proxy, + const uint64_t tenant_id, + uint64_t &ls_group_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant id is invalid", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(sql_proxy)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret)); + } else { + ls_group_id = OB_INVALID_ID; + share::ObMaxIdFetcher id_fetcher(*sql_proxy); + if (OB_FAIL(id_fetcher.fetch_new_max_id( + tenant_id, share::OB_MAX_USED_LS_GROUP_ID_TYPE, ls_group_id))) { + LOG_WARN("fetch_max_id failed", KR(ret), K(tenant_id), "id_type", + share::OB_MAX_USED_LS_GROUP_ID_TYPE); + } + } + return ret; +} + +int ObLSServiceHelper::fetch_new_ls_id(ObMySQLProxy *sql_proxy, const uint64_t tenant_id, share::ObLSID &id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant id is invalid", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(sql_proxy)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret)); + } else { + share::ObMaxIdFetcher id_fetcher(*sql_proxy); + uint64_t id_value = OB_INVALID_ID; + if (OB_FAIL(id_fetcher.fetch_new_max_id( + tenant_id, share::OB_MAX_USED_LS_ID_TYPE, id_value))) { + LOG_WARN("fetch_max_id failed", KR(ret), K(tenant_id), "id_type", + share::OB_MAX_USED_LS_ID_TYPE); + } else { + share::ObLSID new_id(id_value); + id = new_id; + } + } + return ret; +} + +int ObLSServiceHelper::get_primary_zone_unit_array(const share::schema::ObTenantSchema *tenant_schema, + ObIArray &primary_zone, ObIArray &unit_group_array) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(tenant_schema)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant schema is null", KR(ret), K(tenant_schema)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret)); + } else if (OB_FAIL(ObPrimaryZoneUtil::get_tenant_primary_zone_array( + *tenant_schema, primary_zone))) { + LOG_WARN("failed to get tenant primary zone array", KR(ret), KPC(tenant_schema)); + } + if (OB_SUCC(ret)) { + //get unit_group + ObUnitTableOperator unit_operator; + const uint64_t tenant_id = tenant_schema->get_tenant_id(); + if (OB_FAIL(unit_operator.init(*GCTX.sql_proxy_))) { + LOG_WARN("failed to init unit operator", KR(ret)); + } else if (OB_FAIL(unit_operator.get_unit_groups_by_tenant( + tenant_id, unit_group_array))) { + LOG_WARN("failed to get unit group array", KR(ret), K(tenant_id)); + } + } + + return ret; +} +int ObLSServiceHelper::update_ls_recover_in_trans( + const share::ObLSRecoveryStat &ls_recovery_stat, + const bool only_update_readable_scn, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!ls_recovery_stat.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls recovery stat is invalid", KR(ret), K(ls_recovery_stat)); + } else { + share::ObLSRecoveryStatOperator ls_recovery; + SCN new_scn; + if (OB_FAIL(ls_recovery.update_ls_recovery_stat_in_trans(ls_recovery_stat, + only_update_readable_scn, trans))) { + LOG_WARN("failed to update ls recovery stat", KR(ret), K(ls_recovery_stat)); + } else if (only_update_readable_scn) { + //only update readable_scn, no need check sync_scn is fallback + //for restore tenant, sync_scn of sys_ls maybe larger than end_scn. + //before sys_ls can iterator log, no need update sync_scn, only need update readable_scn + //so do as after flashback, sys_ls need update readable_scn too + } else if (OB_FAIL(get_ls_replica_sync_scn(ls_recovery_stat.get_tenant_id(), + ls_recovery_stat.get_ls_id(), new_scn))) { + LOG_WARN("failed to get ls sync scn", KR(ret), K(ls_recovery_stat)); + } else if (new_scn < ls_recovery_stat.get_sync_scn()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("maybe flashback, can not report sync scn", KR(ret), K(ls_recovery_stat), K(new_scn)); + } + } + return ret; +} + +int ObLSServiceHelper::get_ls_replica_sync_scn(const uint64_t tenant_id, + const ObLSID &ls_id, share::SCN &sync_scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!ls_id.is_valid() || !is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(ls_id)); + } else { + MTL_SWITCH(tenant_id) { + palf::PalfHandleGuard palf_handle_guard; + SCN end_scn; + SCN checkpoint_scn; + logservice::ObLogService *log_svr = MTL(logservice::ObLogService*); + ObLSService *ls_svr = MTL(ObLSService *); + ObLSHandle ls_handle; + + if (OB_ISNULL(ls_svr) || OB_ISNULL(log_svr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls log service is null", KR(ret), K(tenant_id), KP(ls_svr), KP(log_svr)); + } else if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, storage::ObLSGetMod::RS_MOD))) { + LOG_WARN("failed to get ls", KR(ret)); + } else { + ObLS *ls = NULL; + if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", KR(ret), K(ls_id)); + } else if (FALSE_IT(checkpoint_scn = ls->get_clog_checkpoint_scn())) { + } else if (OB_FAIL(log_svr->open_palf(ls_id, palf_handle_guard))) { + LOG_WARN("failed to open palf", KR(ret), K(ls_id)); + } else if (OB_FAIL(palf_handle_guard.get_end_scn(end_scn))) { + LOG_WARN("failed to get end scn", KR(ret)); + } else { + //The end_scn of PALF will be set to the SCN corresponding to the LSN in the checkpoint information, + //which is smaller than the SCN recorded in the checkpoint information. + //Therefore, in the recovery scenario, the end_scn of the LS will be smaller than readable_scn + //(readable_scn is provided by get_max_decided_scn of ObLogHandler, and this value is checkpoint at this time. SCN recorded in the information) + //set sync_scn = max(end_scn, checkpoint_scn); + sync_scn = SCN::max(end_scn, checkpoint_scn); + LOG_DEBUG("get sync scn", K(tenant_id), K(ls_id), K(sync_scn), K(end_scn), K(checkpoint_scn)); + } + } + } + } + return ret; +} + + +//Regardless of the tenant being dropped, +//handle the asynchronous operation of status and history table +int ObLSServiceHelper::process_status_to_steady( + const bool lock_sys_ls, + const share::ObTenantSwitchoverStatus &working_sw_status, + ObTenantLSInfo& tenant_ls_info) +{ + int ret = OB_SUCCESS; + ObArray status_machine_array; + const uint64_t tenant_id = tenant_ls_info.get_tenant_id(); + if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(GCTX.sql_proxy_)); + } else if (OB_FAIL(construct_ls_status_machine( + lock_sys_ls, tenant_id, GCTX.sql_proxy_, status_machine_array))) { + LOG_WARN("failed to construct ls status machine array", KR(ret), K(lock_sys_ls), K(tenant_id)); + } else { + int tmp_ret = OB_SUCCESS; + ARRAY_FOREACH_NORET(status_machine_array, idx) { + const ObLSStatusMachineParameter &machine = status_machine_array.at(idx); + //ignore error of each ls + //may ls can not create success + if (OB_SUCCESS != (tmp_ret = revision_to_equal_status_(machine, working_sw_status, tenant_ls_info))) { + LOG_WARN("failed to fix ls status", KR(ret), KR(tmp_ret), K(machine), K(tenant_ls_info)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } else if (machine.ls_info_.get_ls_status() != machine.status_info_.status_) { + //no need do next, or ls is normal, no need process next + //or ls status not equal, no need to next + } else if (machine.ls_info_.ls_is_normal() && machine.ls_info_.get_ls_group_id() != machine.status_info_.ls_group_id_) { + if (OB_TMP_FAIL(process_alter_ls(machine.ls_id_, machine.status_info_.ls_group_id_, + machine.ls_info_.get_ls_group_id(), tenant_ls_info, *GCTX.sql_proxy_))) { + LOG_WARN("failed to process alter ls", KR(ret), KR(tmp_ret), K(machine)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + } + } + + return ret; +} + +int ObLSServiceHelper::offline_ls(const uint64_t tenant_id, + const ObLSID &ls_id, + const ObLSStatus &cur_ls_status, + const ObTenantSwitchoverStatus &working_sw_status) +{ + int ret = OB_SUCCESS; + SCN drop_scn; + + if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("sql proxy is NULL", KP(GCTX.sql_proxy_), KR(ret)); + } else if (OB_UNLIKELY(!ls_id.is_valid() || !is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_id), K(tenant_id)); + } else { + ObLSLifeAgentManager ls_life_agent(*GCTX.sql_proxy_); + + if (ls_id.is_sys_ls()) { + // For SYS LS, drop scn can not be generated, as GTS service is down, SYS LS is blocked + // drop_scn is meaningless for SYS LS, so set it to base_scn + drop_scn.set_base(); + } + // For user LS, drop_scn should be GTS. + else if (OB_FAIL(ObLSAttrOperator::get_tenant_gts(tenant_id, drop_scn))) { + LOG_WARN("failed to get gts", KR(ret), K(tenant_id)); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ls_life_agent.set_ls_offline(tenant_id, ls_id, cur_ls_status, drop_scn, + working_sw_status))) { + LOG_WARN("failed to set ls offline", KR(ret), K(tenant_id), K(ls_id), K(cur_ls_status), + K(drop_scn), K(working_sw_status)); + } + } + return ret; +} + +int ObLSServiceHelper::revision_to_equal_status_(const ObLSStatusMachineParameter &machine, + const share::ObTenantSwitchoverStatus &working_sw_status, + ObTenantLSInfo& tenant_ls_info) +{ + int ret = OB_SUCCESS; + const share::ObLSStatusInfo &status_info = machine.status_info_; + const share::ObLSAttr &ls_info = machine.ls_info_; + const uint64_t tenant_id = tenant_ls_info.get_tenant_id(); + ObLSStatusOperator status_op; + if (OB_UNLIKELY(!machine.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("status machine is valid", KR(ret), K(machine)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(GCTX.sql_proxy_)); + } else if (ls_info.get_ls_status() == status_info.status_) { + //if ls and ls status is equal, need to process next ls status + } else if (!ls_info.is_valid()) { + // LS has beed deleted in __all_ls + ObLSLifeAgentManager ls_life_agent(*GCTX.sql_proxy_); + if (status_info.ls_is_wait_offline()) { + //already offline, status will be deleted by GC + } else if (status_info.ls_is_dropping() + || status_info.ls_is_tenant_dropping()) { + // LS has been in dropping or tenant_dropping, should be offlined + // NOTE: SYS LS will not be HERE, as SYS LS can not be deleted in __all_ls when tenant dropping. + // See ObPrimaryLSService::try_delete_ls_() for SYS LS offline operation. + if (OB_FAIL(offline_ls(tenant_id, status_info.ls_id_, status_info.status_, working_sw_status))) { + LOG_WARN("failed to offline ls", KR(ret), K(status_info), K(tenant_id), K(working_sw_status)); + } + } else if (status_info.ls_is_creating() + || status_info.ls_is_created() + || status_info.ls_is_create_abort()) { + // ls may create_abort, it should be dropped in __all_ls_status + if (OB_FAIL(ls_life_agent.drop_ls(tenant_id, machine.ls_id_, working_sw_status))) { + LOG_WARN("failed to delete ls", KR(ret), K(machine)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status machine not expected", KR(ret), K(machine)); + } + } else if (ls_info.ls_is_creating()) { + if (!status_info.is_valid()) { + //create ls + START_TRANSACTION(GCTX.sql_proxy_, ObLSLifeIAgent::get_exec_tenant_id(tenant_id)); + if (FAILEDx(create_new_ls_in_trans(ls_info.get_ls_id(), + ls_info.get_ls_group_id(), + ls_info.get_create_scn(), + working_sw_status, + tenant_ls_info, trans, ls_info.get_ls_flag()))) { + LOG_WARN("failed to create new ls in trans", KR(ret), K(ls_info), K(tenant_ls_info), K(working_sw_status)); + } + END_TRANSACTION(trans); + } else if (status_info.ls_is_created() || status_info.ls_is_create_abort()) { + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status machine not expected", KR(ret), K(machine)); + } + } else if (ls_info.ls_is_normal()) { + if (!status_info.ls_is_created()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status machine not expected", KR(ret), K(machine)); + } else if (OB_FAIL(status_op.update_ls_status( + tenant_id, status_info.ls_id_, status_info.status_, + ls_info.get_ls_status(), working_sw_status, *GCTX.sql_proxy_))) { + LOG_WARN("failed to update ls status", KR(ret), K(status_info), K(tenant_id), + K(ls_info), K(working_sw_status)); + } + } else if (ls_info.ls_is_pre_tenant_dropping()) { + if (!status_info.ls_is_normal() || !status_info.ls_id_.is_sys_ls()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status machine not expected", KR(ret), K(machine)); + } else if (OB_FAIL(status_op.update_ls_status( + tenant_id, status_info.ls_id_, status_info.status_, + ls_info.get_ls_status(), working_sw_status, *GCTX.sql_proxy_))) { + LOG_WARN("failed to update ls status", KR(ret), K(status_info), K(tenant_id), + K(ls_info), K(working_sw_status)); + } + } else if (ls_info.ls_is_dropping()) { + if (!status_info.ls_is_normal()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status machine not expected", KR(ret), K(machine)); + } else if (OB_FAIL(status_op.update_ls_status( + tenant_id, status_info.ls_id_, status_info.status_, + ls_info.get_ls_status(), working_sw_status, *GCTX.sql_proxy_))) { + LOG_WARN("failed to update ls status", KR(ret), K(status_info), K(tenant_id), + K(ls_info), K(working_sw_status)); + } + } else if (ls_info.ls_is_tenant_dropping()) { + if (status_info.ls_id_.is_sys_ls()) { + if (status_info.ls_is_wait_offline()) { + //sys ls maybe in tenant dropping and wait offline + } else if (!status_info.ls_is_pre_tenant_dropping()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status machine not expected", KR(ret), K(machine)); + } + // Change SYS LS status to TENANT_DROPPING + else if (OB_FAIL(status_op.update_ls_status( + tenant_id, status_info.ls_id_, status_info.status_, + ls_info.get_ls_status(), working_sw_status, *GCTX.sql_proxy_))) { + LOG_WARN("failed to update ls status to tenant_dropping", KR(ret), K(status_info), K(tenant_id), + K(ls_info), K(working_sw_status)); + } + } else if (OB_UNLIKELY(status_info.ls_is_creating())) { + //status_info may in created, normal, dropping, tenant_dropping + //while ls in dropping, it must be change to tenant_dropping, no need to transfer tablet + //if status in __all_ls is creating, while tenant_dropping, it will be create abort directly + //the status in __all_ls_status maybe created or creating, but status is created, status in + //__all_ls maybe normal, so while tenant_dropping, status cannot be creating. + //while status_info is wait_offline, ls_info is been drop_end, so cannot be tenant_dropping + //sys ls is special, sys ls no drop_end + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status info not expected", KR(ret), K(machine)); + } else if (OB_FAIL(status_op.update_ls_status( + tenant_id, status_info.ls_id_, status_info.status_, + ls_info.get_ls_status(), working_sw_status, *GCTX.sql_proxy_))) { + LOG_WARN("failed to update ls status", KR(ret), K(status_info), K(tenant_id), + K(ls_info), K(working_sw_status)); + } + } else { + //other status can not be in __all_ls + //such as created, wait_offline + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the ls not expected in all_ls", KR(ret), K(machine), K(working_sw_status)); + } + return ret; +} + + + +int ObLSServiceHelper::process_alter_ls(const share::ObLSID &ls_id, + const uint64_t &old_ls_group_id, + const uint64_t &new_ls_group_id, + ObTenantLSInfo& tenant_info, + ObISQLClient &sql_proxy) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = tenant_info.get_tenant_id();; + uint64_t unit_group_id = OB_INVALID_ID; + if (OB_UNLIKELY(!ls_id.is_valid() || OB_INVALID_ID == old_ls_group_id || OB_INVALID_ID == new_ls_group_id + || old_ls_group_id == new_ls_group_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_id), K(old_ls_group_id), K(new_ls_group_id)); + } else if (OB_FAIL(tenant_info.gather_stat())) { + LOG_WARN("failed to gather stat", KR(ret)); + } else { + // update ls group id in status + int64_t unit_group_index = OB_INVALID_INDEX_INT64; + ObLSGroupInfo ls_group_info; + if (OB_SUCC(tenant_info.get_ls_group_info(new_ls_group_id, ls_group_info))) { + unit_group_id = ls_group_info.unit_group_id_; + } else if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("failed to get ls group info", KR(ret), K(new_ls_group_id)); + } else { + ret = OB_SUCCESS; // try to get new unit group id + if (OB_FAIL(tenant_info.get_next_unit_group(unit_group_index))) { + LOG_WARN("failed to get next unit group", KR(ret)); + } else if (OB_UNLIKELY(OB_INVALID_INDEX_INT64 == unit_group_index || + unit_group_index >= tenant_info.get_unit_group_array().count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to next unit group", KR(ret), K(unit_group_index)); + } else { + unit_group_id = tenant_info.get_unit_group_array().at(unit_group_index).unit_group_id_; + } + } + ObLSStatusOperator status_op; + if (FAILEDx(status_op.alter_ls_group_id( + tenant_id, ls_id, old_ls_group_id, new_ls_group_id, + unit_group_id, sql_proxy))) { + LOG_WARN("failed to update ls group id", KR(ret), K(new_ls_group_id), K(old_ls_group_id), + K(unit_group_id), K(tenant_info)); + } + LOG_INFO("[LS_MGR] alter ls group id", KR(ret), K(old_ls_group_id), + K(new_ls_group_id), K(unit_group_id)); + } + return ret; +} + +int ObLSServiceHelper::create_new_ls_in_trans( + const share::ObLSID &ls_id, + const uint64_t ls_group_id, + const SCN &create_scn, + const share::ObTenantSwitchoverStatus &working_sw_status, + ObTenantLSInfo& tenant_ls_info, + ObMySQLTransaction &trans, + const share::ObLSFlag &ls_flag) +{ + int ret = OB_SUCCESS; + int64_t info_index = OB_INVALID_INDEX_INT64; + if (OB_UNLIKELY(!ls_id.is_valid() + || OB_INVALID_ID == ls_group_id + || !create_scn.is_valid() + || !ls_flag.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls id is invalid", KR(ret), K(ls_id), K(ls_group_id), K(create_scn), K(ls_flag)); + } else if (OB_ISNULL(tenant_ls_info.get_tenant_schema()) + || OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant stat not valid", KR(ret), KP(tenant_ls_info.get_tenant_schema()), KP(GCTX.sql_proxy_)); + } else if (OB_FAIL(tenant_ls_info.gather_stat())) { + LOG_WARN("failed to gather stat", KR(ret)); + } else { + const uint64_t tenant_id = tenant_ls_info.get_tenant_id(); + share::ObLSStatusInfo new_info; + ObLSGroupInfo group_info; + ObZone primary_zone; + ObLSLifeAgentManager ls_life_agent(*GCTX.sql_proxy_); + ObSqlString zone_priority; + uint64_t unit_group_id = 0; + if (0 == ls_group_id) { + unit_group_id = 0; + if (!ls_flag.is_duplicate_ls()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls without ls group must be duplate", KR(ret), + K(ls_group_id), K(ls_id), K(ls_flag)); + } else if (OB_FAIL(primary_zone.assign(tenant_ls_info.get_primary_zone().at(0)))) { + LOG_WARN("failed to assign primary zone", KR(ret), K(tenant_ls_info)); + } + } else if (OB_SUCC(tenant_ls_info.get_ls_group_info( + ls_group_id, group_info))) { + // need a new primary zone + unit_group_id = group_info.unit_group_id_; + if (OB_FAIL(tenant_ls_info.get_next_primary_zone(group_info, primary_zone))) { + LOG_WARN("failed to get next primary zone", KR(ret), K(group_info)); + } + } else if (OB_ENTRY_NOT_EXIST == ret) { + // need a new unit group + ret = OB_SUCCESS; + int64_t unit_group_index = OB_INVALID_INDEX_INT64; + if (OB_FAIL(tenant_ls_info.get_next_unit_group(unit_group_index))) { + LOG_WARN("failed to get next unit group", KR(ret)); + } else if (OB_UNLIKELY(OB_INVALID_INDEX_INT64 == unit_group_index + || unit_group_index >= tenant_ls_info.get_unit_group_array().count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to next unit group", KR(ret), K(unit_group_index), K(tenant_ls_info)); + } else { + unit_group_id = tenant_ls_info.get_unit_group_array().at(unit_group_index).unit_group_id_; + if (OB_FAIL(primary_zone.assign(tenant_ls_info.get_primary_zone().at(0)))) { + LOG_WARN("failed to assign primary zone", KR(ret), K(tenant_ls_info)); + } + } + } else { + LOG_WARN("failed to get ls group info", KR(ret), K(ls_group_id), K(tenant_ls_info)); + } + + if (FAILEDx(new_info.init(tenant_id, ls_id, + ls_group_id, + share::OB_LS_CREATING, + unit_group_id, + primary_zone, ls_flag))) { + LOG_WARN("failed to init new info", KR(ret), K(tenant_id), K(unit_group_id), + K(ls_id), K(ls_group_id), K(group_info), K(primary_zone), K(ls_flag)); + } else if (OB_FAIL(ObTenantThreadHelper::get_zone_priority(primary_zone, + *tenant_ls_info.get_tenant_schema(), zone_priority))) { + LOG_WARN("failed to get normalize primary zone", KR(ret), K(primary_zone), K(zone_priority)); + } else if (OB_FAIL(ls_life_agent.create_new_ls_in_trans(new_info, create_scn, + zone_priority.string(), working_sw_status, trans))) { + LOG_WARN("failed to insert ls info", KR(ret), K(new_info), K(create_scn), K(zone_priority)); + } + } + return ret; +} + +int ObLSServiceHelper::balance_ls_group(ObTenantLSInfo& tenant_ls_info) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(tenant_ls_info.gather_stat())) { + LOG_WARN("failed to gather stat", KR(ret)); + } else { + int64_t min_count = INT64_MAX, min_index = OB_INVALID_INDEX_INT64; + int64_t max_count = 0, max_index = OB_INVALID_INDEX_INT64; + do { + min_count = INT64_MAX; + max_count = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < tenant_ls_info.get_unit_group_array().count(); ++i) { + const ObUnitGroupInfo &unit_group_info = tenant_ls_info.get_unit_group_array().at(i); + if (share::ObUnit::UNIT_STATUS_ACTIVE != unit_group_info.unit_status_) { + ret = OB_NEED_WAIT; + LOG_INFO("has unit group need deleting, can not balance", KR(ret), K(unit_group_info)); + } else { + int64_t curr_ls_group_count = unit_group_info.ls_group_ids_.count(); + if (max_count < curr_ls_group_count) { + max_count = curr_ls_group_count; + max_index = i; + } + if (min_count > curr_ls_group_count) { + min_count = curr_ls_group_count; + min_index = i; + } + } + }//end for + if (OB_SUCC(ret) && max_count - min_count > 1) { + if (OB_FAIL(balance_ls_group_between_unit_group_(tenant_ls_info, min_index, max_index))) { + LOG_WARN("failed to balance ls group between unit group", KR(ret), K(tenant_ls_info), + K(min_index), K(max_index)); + } + } + } while (OB_SUCC(ret) && (max_count - min_count) > 1); + } + return ret; +} + +int ObLSServiceHelper::balance_ls_group_between_unit_group_(ObTenantLSInfo& tenant_ls_info, + const int64_t min_index, const int64_t max_index) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_)); + } else if (OB_UNLIKELY(min_index == max_index + || min_index < 0 || min_index > tenant_ls_info.get_unit_group_array().count() + || max_index < 0 || max_index > tenant_ls_info.get_unit_group_array().count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(min_index), K(max_index), K(tenant_ls_info)); + } else { + ObUnitGroupInfo &dest_info = tenant_ls_info.get_unit_group_array().at(min_index); + ObUnitGroupInfo &src_info = tenant_ls_info.get_unit_group_array().at(max_index); + const uint64_t tenant_id = tenant_ls_info.get_tenant_id(); + const int64_t ls_group_count = src_info.ls_group_ids_.count(); + if (ls_group_count < 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src info is unexpected", KR(ret), K(ls_group_count), K(src_info)); + } else { + const uint64_t ls_group_id = src_info.ls_group_ids_.at(ls_group_count - 1); + ObLSGroupInfo ls_group_info; + if (OB_FAIL(tenant_ls_info.get_ls_group_info(ls_group_id, ls_group_info))) { + LOG_WARN("failed to get ls group_info", KR(ret), K(ls_group_id)); + } else { + for (int64_t j = 0; OB_SUCC(ret) && j < ls_group_info.ls_ids_.count(); ++j) { + share::ObLSStatusOperator status_op; + ObLSID ls_id = ls_group_info.ls_ids_.at(j); + if (OB_FAIL(status_op.alter_ls_group_id(tenant_id, ls_id, + ls_group_id, ls_group_id, + dest_info.unit_group_id_, *GCTX.sql_proxy_))) { + LOG_WARN("failed to alter unit group", KR(ret), K(tenant_id), K(ls_id), K(ls_group_id), + K(src_info), K(dest_info)); + } + } + LOG_INFO("[LS_MGR]balance ls group to unit group", KR(ret), K(ls_group_id), K(src_info), K(dest_info)); + } + if (FAILEDx(src_info.ls_group_ids_.remove(ls_group_count - 1))) { + LOG_WARN("failed to remove", KR(ret), K(ls_group_count), K(dest_info)); + } else if (OB_FAIL(dest_info.ls_group_ids_.push_back(ls_group_id))) { + LOG_WARN("failed to push back", KR(ret), K(ls_group_id), K(src_info)); + } + } + } + return ret; +} + +/////////////ObTenantLSInfo +void ObTenantLSInfo::reset() +{ + is_load_ = false; + status_array_.reset(); + unit_group_array_.reset(); + ls_group_array_.reset(); + primary_zone_.reset(); + status_map_.reuse(); +} +bool ObTenantLSInfo::is_valid() const +{ + return ATOMIC_LOAD(&is_load_); +} + +int ObTenantLSInfo::gather_stat() +{ + int ret = OB_SUCCESS; + reset(); + if (OB_ISNULL(tenant_schema_) || OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected", KR(ret), KP(tenant_schema_), KP(sql_proxy_)); + } else { + ObArray unit_groups; + if (OB_FAIL(ObLSServiceHelper::get_primary_zone_unit_array( + tenant_schema_, primary_zone_, unit_groups))) { + LOG_WARN("failed to get primary zone unit", KR(ret), KPC(tenant_schema_)); + } else { + ObUnitGroupInfo info; + for (int64_t j = 0; OB_SUCC(ret) && j < unit_groups.count(); ++j) { + info.reset(); + const ObSimpleUnitGroup &unit_group = unit_groups.at(j); + if (OB_FAIL(info.init(unit_group.get_unit_group_id(), unit_group.get_status()))) { + LOG_WARN("failed to init unit info", KR(ret), K(unit_group)); + } else if (OB_FAIL(unit_group_array_.push_back(info))) { + LOG_WARN("fail to push back", KR(ret), K(info)); + } + } + } + + if (FAILEDx(gather_all_ls_info_())) { + LOG_WARN("failed to get all ls info", KR(ret), K(tenant_id_)); + } else { + is_load_ = true; + } + } + LOG_INFO("[LS_MGR] gather stat", KR(ret), K(primary_zone_), K(unit_group_array_)); + return ret; +} + +int ObTenantLSInfo::gather_all_ls_info_() +{ + int ret = OB_SUCCESS; + share::ObLSStatusInfoArray status_info_array; + if (OB_ISNULL(sql_proxy_) || OB_ISNULL(tenant_schema_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy or tenant schema is null", KR(ret), KP(tenant_schema_), KP(sql_proxy_)); + } else { + const uint64_t tenant_id = tenant_schema_->get_tenant_id(); + if (OB_FAIL(status_operator_.get_all_ls_status_by_order( + tenant_id, status_info_array, *sql_proxy_))) { + LOG_WARN("failed to get all ls status by order", KR(ret), K(tenant_id)); + } + } + if (OB_FAIL(ret)) { + } else { + const int64_t count = max(1, hash::cal_next_prime(status_info_array.count())); + if (!status_map_.created() && OB_FAIL(status_map_.create(count, "LogStrInfo", "LogStrInfo"))) { + LOG_WARN("failed to create ls map", KR(ret), K(count)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < status_info_array.count(); ++i) { + const share::ObLSStatusInfo &info = status_info_array.at(i); + if (info.ls_is_wait_offline()) { + //ls is already offline, no need to process + } else if (FAILEDx(add_ls_status_info_(info))) { + LOG_WARN("failed to add ls status info", KR(ret), K(i), K(info)); + } + }// end for + } + } + return ret; +} + +int ObTenantLSInfo::add_ls_to_ls_group_(const share::ObLSStatusInfo &info) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!info.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls status is invalid", KR(ret), K(info)); + } else { + int64_t group_index = OB_INVALID_INDEX_INT64; + for (int64_t j = 0; OB_SUCC(ret) && j < ls_group_array_.count(); + ++j) { + const ObLSGroupInfo &group = ls_group_array_.at(j); + if (info.ls_group_id_ == group.ls_group_id_) { + group_index = j; + break; + } + } + if (OB_SUCC(ret) && OB_INVALID_INDEX_INT64 == group_index) { + ObLSGroupInfo group; + group_index = ls_group_array_.count(); + if (OB_FAIL(group.init(info.unit_group_id_, info.ls_group_id_))) { + LOG_WARN("failed to init ls group", KR(ret), K(info)); + } else if (OB_FAIL(ls_group_array_.push_back(group))) { + LOG_WARN("failed to pushback group", KR(ret), K(group)); + } else if (0 == info.ls_group_id_) { + //duplate ls, no need to set to unit group + } else if (OB_FAIL(add_ls_group_to_unit_group_(group))) { + LOG_WARN("failed to add ls group to unit group", KR(ret), K(group)); + } + } + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(group_index >= ls_group_array_.count() + || OB_INVALID_INDEX_INT64 == group_index)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("group index is invalid", KR(ret), K(group_index), "count", + ls_group_array_.count()); + } else if (OB_FAIL(ls_group_array_.at(group_index) + .ls_ids_.push_back(info.ls_id_))) { + LOG_WARN("failed to push back ls id", KR(ret), K(group_index), + K(info)); + } + } + } + return ret; +} + +int ObTenantLSInfo::add_ls_group_to_unit_group_(const ObLSGroupInfo &group_info) +{ + int ret = OB_SUCCESS; + bool found = false; + if (OB_UNLIKELY(!group_info.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("group_info is invalid", KR(ret), K(group_info)); + } else { + found = false; + for (int64_t j = 0; OB_SUCC(ret) && j < unit_group_array_.count(); ++j) { + ObUnitGroupInfo &unit_info = unit_group_array_.at(j); + if (group_info.unit_group_id_ == unit_info.unit_group_id_) { + found = true; + if (OB_FAIL(unit_info.ls_group_ids_.push_back( + group_info.ls_group_id_))) { + LOG_WARN("failed to push back ls group id", KR(ret), + K(group_info), K(unit_info)); + } + } + } // end j + if (OB_SUCC(ret) && !found) { + //can found unit_group for a ls group + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to find unit group for ls group", KR(ret), + K(group_info), K(unit_group_array_)); + } + } + + return ret; +} + +int ObTenantLSInfo::add_ls_status_info_( + const share::ObLSStatusInfo &ls_info) +{ + int ret = OB_SUCCESS; + const int64_t index = status_array_.count(); + if (OB_UNLIKELY(!ls_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls info is invalid", KR(ret), K(ls_info)); + } else if (OB_FAIL(status_array_.push_back(ls_info))) { + LOG_WARN("failed to remove status", KR(ret), K(ls_info)); + } else if (OB_FAIL(status_map_.set_refactored(ls_info.ls_id_, index))) { + LOG_WARN("failed to remove ls from map", KR(ret), K(ls_info), K(index)); + } else if (ls_info.ls_id_.is_sys_ls()) { + //sys ls no ls group + } else if (OB_FAIL(add_ls_to_ls_group_(ls_info))) { + LOG_WARN("failed to add ls info", KR(ret), K(ls_info)); + } + return ret; +} + +int ObTenantLSInfo::get_ls_group_info( + const uint64_t ls_group_id, ObLSGroupInfo &info) const +{ + int ret = OB_SUCCESS; + info.reset(); + if (OB_UNLIKELY(OB_INVALID_ID == ls_group_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls group id is invalid", KR(ret), K(ls_group_id)); + } else if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant stat not valid", KR(ret)); + } else { + bool found = false; + for (int64_t i = 0; OB_SUCC(ret) && i < ls_group_array_.count(); ++i) { + const ObLSGroupInfo group_info = ls_group_array_.at(i); + if (ls_group_id == group_info.ls_group_id_) { + found = true; + if (OB_FAIL(info.assign(group_info))) { + LOG_WARN("failed to assign group info", KR(ret), K(group_info)); + } + break; + } + }//end for + if (OB_SUCC(ret) && !found) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("failed to find ls group info", KR(ret), + K(ls_group_id)); + } + } + return ret; +} + +int ObTenantLSInfo::get_ls_status_info( + const share::ObLSID &ls_id, + share::ObLSStatusInfo &info, + int64_t &info_index) const +{ + int ret = OB_SUCCESS; + info.reset(); + info_index = OB_INVALID_INDEX_INT64; + if (OB_UNLIKELY(!ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls id is invalid", KR(ret), K(ls_id)); + } else if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant stat not valid", KR(ret)); + } else if (OB_FAIL(status_map_.get_refactored(ls_id, info_index))) { + if (OB_HASH_NOT_EXIST == ret) { + ret = OB_ENTRY_NOT_EXIST; + } + LOG_WARN("failed to find ls index", KR(ret), K(ls_id)); + } else if (OB_UNLIKELY(info_index < 0 || info_index >= status_array_.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("info index not valid", KR(ret), K(info_index), K(ls_id), + "status_count", status_array_.count()); + } else if (OB_FAIL(info.assign(status_array_.at(info_index)))) { + LOG_WARN("failed to assign ls info", KR(ret), K(info_index), + "status", status_array_.at(info_index)); + } + return ret; +} + +int ObTenantLSInfo::get_next_unit_group(int64_t &group_index) +{ + int ret = OB_SUCCESS; + group_index = OB_INVALID_INDEX_INT64; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant stat not valid", KR(ret)); + } else { + int64_t ls_count = OB_INVALID_COUNT; + // Find the unit group with the least number of log streams + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_array_.count(); ++i) { + const ObUnitGroupInfo &info = unit_group_array_.at(i); + const int64_t count = info.ls_group_ids_.count(); + if (share::ObUnit::UNIT_STATUS_ACTIVE == info.unit_status_) { + if (OB_INVALID_COUNT == ls_count || ls_count > count) { + ls_count = count; + group_index = i; + if (0 == count) { + //the first has no ls group unit group + break; + } + } + } + } + if (OB_SUCC(ret)) { + if (OB_INVALID_INDEX_INT64 == group_index) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("failed to find next unit group", KR(ret), + K(unit_group_array_), K(ls_count)); + } + } + } + LOG_INFO("get next primary zone", KR(ret), K(group_index)); + return ret; +} + +int ObTenantLSInfo::get_next_primary_zone( + const ObLSGroupInfo &group_info, + ObZone &primary_zone) +{ + int ret = OB_SUCCESS; + primary_zone.reset(); + if (OB_UNLIKELY(!group_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("group info is invalid", KR(ret), K(group_info)); + } else if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant ls info not valid", KR(ret)); + } else { + share::ObLSStatusInfo info; + int64_t ls_count = OB_INVALID_COUNT; + int64_t info_index = OB_INVALID_INDEX_INT64; + for (int64_t i = 0; OB_SUCC(ret) && i < primary_zone_.count(); ++i) { + const ObZone &zone = primary_zone_.at(i); + int64_t primary_zone_count = 0; + for (int64_t j = 0; OB_SUCC(ret) && j < group_info.ls_ids_.count(); ++j) { + const share::ObLSID &id = group_info.ls_ids_.at(j); + if (OB_FAIL(get_ls_status_info(id, info, info_index))) { + LOG_WARN("failed to find ls info", KR(ret), K(id), K(j)); + } else if (zone == info.primary_zone_) { + primary_zone_count++; + } + }//end for j + if (OB_SUCC(ret)) { + if (OB_INVALID_COUNT == ls_count || ls_count > primary_zone_count) { + ls_count = primary_zone_count; + if (OB_FAIL(primary_zone.assign(zone))) { + LOG_WARN("failed to assign zone", KR(ret), K(zone)); + } else if (0 == primary_zone_count) { + //the first zone has no primary zone + break; + } + } + } + }//end for i + if (OB_SUCC(ret)) { + if (primary_zone.is_empty()) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("failed to find next primary zone", KR(ret), K(primary_zone_), + K(group_info), K(ls_count)); + } + } + LOG_INFO("get next primary zone", KR(ret), K(group_info), K(primary_zone)); + } + return ret; +} +}//end of rootserver +} diff --git a/src/rootserver/ob_ls_service_helper.h b/src/rootserver/ob_ls_service_helper.h new file mode 100644 index 000000000..fbbb8fbb9 --- /dev/null +++ b/src/rootserver/ob_ls_service_helper.h @@ -0,0 +1,258 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_LS_SERVICE_HELPER_H +#define OCEANBASE_ROOTSERVER_OB_LS_SERVICE_HELPER_H +#include "lib/thread/ob_reentrant_thread.h"//ObRsReentrantThread +#include "logservice/ob_log_base_type.h" +#include "share/scn.h"//SCN +#include "share/ls/ob_ls_status_operator.h"//ObLSStatusOperator +#include "share/ls/ob_ls_operator.h" //ObLSAttr +#include "share/ob_thread_mgr.h" //OBTGDefIDEnum +#include "logservice/palf/palf_iterator.h" //PalfBufferIterator +#include "share/unit/ob_unit_info.h"//ObUnit::Status +#include "lib/thread/thread_mgr_interface.h" // TGRunnable +#include "lib/lock/ob_thread_cond.h"//ObThreadCond + + +namespace oceanbase +{ +namespace obrpc +{ +class ObSrvRpcProxy; +} +namespace common +{ +class ObMySQLProxy; +class ObISQLClient; +class ObMySQLTransaction; +class ObClusterVersion; +} +namespace share +{ +class ObLSTableOperator; +class SCN; +namespace schema +{ +class ObMultiVersionSchemaService; +class ObTenantSchema; +} +} +namespace logservice +{ +class ObLogHandler; +} +namespace transaction +{ +class ObTxLogBlock; +class ObTxBufferNode; +} +namespace palf +{ +struct PalfBaseInfo; +} +namespace rootserver +{ +struct ObUnitGroupInfo +{ + ObUnitGroupInfo() : unit_group_id_(OB_INVALID_ID), unit_status_(share::ObUnit::UNIT_STATUS_MAX), + ls_group_ids_() {} + virtual ~ObUnitGroupInfo() {} + bool is_valid() const; + int init(const uint64_t unit_group_id, + const share::ObUnit::Status &unit_status); + void reset(); + int assign(const ObUnitGroupInfo &other); + int remove_ls_group(const uint64_t ls_group_id); + bool operator==(const ObUnitGroupInfo &other) const; + + uint64_t unit_group_id_; + share::ObUnit::Status unit_status_; + ObArray ls_group_ids_; + TO_STRING_KV(K_(unit_group_id), K_(unit_status), K_(ls_group_ids)); +}; +typedef ObArray ObUnitGroupInfoArray; +typedef ObIArray ObUnitGroupInfoIArray; + +struct ObLSGroupInfo +{ + ObLSGroupInfo() : ls_group_id_(OB_INVALID_ID), unit_group_id_(OB_INVALID_ID), + ls_ids_() {} + virtual ~ObLSGroupInfo() {} + bool is_valid() const; + int init(const uint64_t unit_group_id, const uint64_t ls_group_id); + int assign(const ObLSGroupInfo &other); + void reset(); + int remove_ls(const share::ObLSID &ls_id); + uint64_t ls_group_id_; + uint64_t unit_group_id_; + ObArray ls_ids_; + TO_STRING_KV(K_(ls_group_id), K_(unit_group_id), K_(ls_ids)); +}; + +typedef ObArray ObLSGroupInfoArray; +typedef ObIArray ObLSGroupInfoIArray; + +struct ObLSStatusMachineParameter +{ + ObLSStatusMachineParameter() : ls_id_(), status_info_(), ls_info_() {} + virtual ~ObLSStatusMachineParameter() {} + bool is_valid() const + { + return ls_id_.is_valid() + && (share::OB_LS_EMPTY == status_info_.status_ + || status_info_.ls_id_ == ls_id_); + } + int init(const share::ObLSID &id, const share::ObLSStatusInfo &status_info, + const share::ObLSAttr &ls_info); + void reset(); + share::ObLSID ls_id_; + share::ObLSStatusInfo status_info_;//for create ls and status of __all_ls_status + share::ObLSAttr ls_info_; + TO_STRING_KV(K_(ls_id), K_(status_info), K_(ls_info)); +}; + +/*descripthin: Tenant log stream status information: Statistical log stream + * status on __all_ls_status and __all_ls, tenant primary_zone and unit_num + * information. Provides location information for the newly created log stream. + * Whether the build needs to create or delete log streams.*/ +class ObTenantLSInfo +{ +public: + ObTenantLSInfo(ObMySQLProxy *sql_proxy, + const share::schema::ObTenantSchema *tenant_schema, + const uint64_t tenant_id) + : sql_proxy_(sql_proxy), + tenant_schema_(tenant_schema), + status_operator_(), + status_array_(), + unit_group_array_(), + ls_group_array_(), + primary_zone_(), + tenant_id_(tenant_id) {} + + virtual ~ObTenantLSInfo(){}; + void reset(); + bool is_valid() const; + int gather_stat(); + //get ls group info from ls_group_array_ by ls_group_id + //the interface must used after gather_stat(); + int get_ls_group_info(const uint64_t ls_group_id, ObLSGroupInfo &info) const; + //get ls status info from status_array_ by ls_id + //the interface must used after gather_stat(); + int get_ls_status_info(const share::ObLSID &id, share::ObLSStatusInfo &info, + int64_t &info_index) const; + int get_next_unit_group(int64_t &group_index); + // get the primary zone not in ls group + int get_next_primary_zone(const ObLSGroupInfo &group_info, + ObZone &primary_zone); + + uint64_t get_tenant_id() const { return tenant_id_; } + const share::schema::ObTenantSchema * get_tenant_schema() const + { + return tenant_schema_; + } + ObUnitGroupInfoArray& get_unit_group_array() + { + return unit_group_array_; + } + const ObIArray &get_primary_zone() const + { + return primary_zone_; + } + TO_STRING_KV(K_(tenant_id), K_(is_load), K_(status_array), K_(unit_group_array), + K_(ls_group_array), K_(primary_zone)); +private: + // get from __all_ls_status and __all_ls + int gather_all_ls_info_(); + + // base on status_array construct ls_array + int add_ls_to_ls_group_(const share::ObLSStatusInfo &info); + + // base on ls_array construct unit_group_array and __all_unit + int add_ls_group_to_unit_group_(const ObLSGroupInfo &group_info); + + int add_ls_status_info_(const share::ObLSStatusInfo &ls_info); +private: + ObMySQLProxy *sql_proxy_; + const share::schema::ObTenantSchema *tenant_schema_; + share::ObLSStatusOperator status_operator_; + bool is_load_; + share::ObLSStatusInfoArray status_array_; + common::hash::ObHashMap status_map_; + ObUnitGroupInfoArray unit_group_array_; + ObLSGroupInfoArray ls_group_array_; + ObArray primary_zone_; + uint64_t tenant_id_; +}; + +class ObLSServiceHelper +{ +public: + ObLSServiceHelper() {}; + virtual ~ObLSServiceHelper() {}; + +public: + static int construct_ls_status_machine( + const bool lock_sys, + const uint64_t tenant_id, + ObMySQLProxy *sql_proxy, + common::ObIArray &status_machine_array); + static int fetch_new_ls_group_id(ObMySQLProxy *sql_proxy, const uint64_t tenant_id, uint64_t &ls_group_id); + static int fetch_new_ls_id(ObMySQLProxy *sql_proxy, const uint64_t tenant_id, share::ObLSID &ls_id); + static int get_primary_zone_unit_array(const share::schema::ObTenantSchema *tenant_schema, + ObIArray &primary_zone, ObIArray &unit_group_array); + static int process_status_to_steady( + const bool lock_sys_ls, + const share::ObTenantSwitchoverStatus &working_sw_status, + ObTenantLSInfo& tenant_ls_info); + //for recovery tenant, create new ls according to ls_id and ls_group_id + static int create_new_ls_in_trans(const share::ObLSID &ls_id, + const uint64_t ls_group_id, + const share::SCN &create_scn, + const share::ObTenantSwitchoverStatus &working_sw_status, + ObTenantLSInfo& tenant_ls_info, + common::ObMySQLTransaction &trans, + const share::ObLSFlag &ls_flag); + static int balance_ls_group(ObTenantLSInfo& tenant_ls_info);//for standby tenant + static int update_ls_recover_in_trans( + const share::ObLSRecoveryStat &ls_recovery_stat, + const bool only_update_readable_scn, + common::ObMySQLTransaction &trans); + static int offline_ls(const uint64_t tenant_id, + const ObLSID &ls_id, + const ObLSStatus &cur_ls_status, + const ObTenantSwitchoverStatus &working_sw_status); + static int get_ls_replica_sync_scn(const uint64_t tenant_id, + const ObLSID &ls_id, share::SCN &create_scn); + static int process_alter_ls(const share::ObLSID &ls_id, + const uint64_t &old_ls_group_id, + const uint64_t &new_ls_group_id, + ObTenantLSInfo& tenant_ls_info, + common::ObISQLClient &sql_proxy); +private: + static int revision_to_equal_status_( + const ObLSStatusMachineParameter &status_machine, + const share::ObTenantSwitchoverStatus &working_sw_status, + ObTenantLSInfo& tenant_ls_info); + static int balance_ls_group_between_unit_group_( + ObTenantLSInfo& tenant_ls_info, + const int64_t min_index, const int64_t max_index); +}; + + + +} +} + + +#endif /* !OCEANBASE_ROOTSERVER_OB_LS_SERVICE_HELPER_H */ diff --git a/src/rootserver/ob_migrate_unit_finish_checker.cpp b/src/rootserver/ob_migrate_unit_finish_checker.cpp index c1cf94ff8..ff8c0d2d8 100644 --- a/src/rootserver/ob_migrate_unit_finish_checker.cpp +++ b/src/rootserver/ob_migrate_unit_finish_checker.cpp @@ -153,44 +153,6 @@ int ObMigrateUnitFinishChecker::try_check_migrate_unit_finish_not_in_tenant() return ret; } -int ObMigrateUnitFinishChecker::get_all_tenant_related_ls_status_info( - const uint64_t tenant_id, - common::ObIArray &ls_status_info_array) -{ - int ret = OB_SUCCESS; - ls_status_info_array.reset(); - share::ObLSStatusOperator ls_status_operator; - if (OB_UNLIKELY(is_meta_tenant(tenant_id))) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(tenant_id)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); - } else if (is_sys_tenant(tenant_id)) { - if (OB_FAIL(ls_status_operator.get_all_ls_status_by_order( - tenant_id, ls_status_info_array, *sql_proxy_))) { - LOG_WARN("fail to get all ls status", KR(ret), K(tenant_id)); - } - } else { // user tenant - const uint64_t user_tenant_id = tenant_id; - const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id); - common::ObArray user_ls_status_info_array; - common::ObArray meta_ls_status_info_array; - if (OB_FAIL(ls_status_operator.get_all_ls_status_by_order( - user_tenant_id, user_ls_status_info_array, *sql_proxy_))) { - LOG_WARN("fail to get all ls status by order", KR(ret), K(user_tenant_id)); - } else if (OB_FAIL(ls_status_operator.get_all_ls_status_by_order( - meta_tenant_id, meta_ls_status_info_array, *sql_proxy_))) { - LOG_WARN("fail to get all ls status by order", KR(ret), K(meta_tenant_id)); - } else if (OB_FAIL(append(ls_status_info_array, user_ls_status_info_array))) { - LOG_WARN("fail to append", KR(ret)); - } else if (OB_FAIL(append(ls_status_info_array, meta_ls_status_info_array))) { - LOG_WARN("fail to append", KR(ret)); - } - } - return ret; -} - int ObMigrateUnitFinishChecker::try_check_migrate_unit_finish_by_tenant( const uint64_t tenant_id) { @@ -203,14 +165,19 @@ int ObMigrateUnitFinishChecker::try_check_migrate_unit_finish_by_tenant( } else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret)); } else { LOG_INFO("try check migrate unit finish by tenant", K(tenant_id)); DRLSInfo dr_ls_info(gen_user_tenant_id(tenant_id), unit_mgr_, zone_mgr_, schema_service_); - common::ObArray ls_status_info_array; - if (OB_FAIL(get_all_tenant_related_ls_status_info(tenant_id, ls_status_info_array))) { + ObLSStatusInfoArray ls_status_info_array; + share::ObLSStatusOperator ls_status_operator; + if (OB_FAIL(ls_status_operator.get_all_tenant_related_ls_status_info( + *sql_proxy_, tenant_id, ls_status_info_array))) { LOG_WARN("fail to get all ls status", KR(ret), K(tenant_id)); } else if (OB_FAIL(dr_ls_info.init())) { LOG_WARN("fail to init disaster log stream info", KR(ret)); diff --git a/src/rootserver/ob_migrate_unit_finish_checker.h b/src/rootserver/ob_migrate_unit_finish_checker.h index cf9a98170..417974dd4 100644 --- a/src/rootserver/ob_migrate_unit_finish_checker.h +++ b/src/rootserver/ob_migrate_unit_finish_checker.h @@ -52,10 +52,6 @@ public: int check(); private: virtual int check_stop() const override; - int get_all_tenant_related_ls_status_info( - const uint64_t tenant_id, - common::ObIArray &ls_status_info_array); - int try_check_migrate_unit_finish_not_in_locality( const uint64_t &tenant_id); int try_check_migrate_unit_finish_not_in_tenant(); diff --git a/src/rootserver/ob_partition_balance.cpp b/src/rootserver/ob_partition_balance.cpp new file mode 100644 index 000000000..98192e2c6 --- /dev/null +++ b/src/rootserver/ob_partition_balance.cpp @@ -0,0 +1,889 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX BALANCE +#include "share/schema/ob_schema_getter_guard.h" +#include "share/tablet/ob_tablet_table_iterator.h" +#include "share/schema/ob_part_mgr_util.h" +#include "share/schema/ob_schema_struct.h" +#include "rootserver/ob_balance_group_ls_stat_operator.h" +#include "rootserver/ob_ls_service_helper.h" +#include "rootserver/ob_partition_balance.h" +#include "storage/ob_common_id_utils.h" + + +namespace oceanbase +{ +namespace rootserver +{ +using namespace oceanbase::share; +using namespace oceanbase::storage; + +const int64_t PART_GROUP_SIZE_SEGMENT[] = { + 10 * 1024L * 1024L * 1024L, // 10G + 5 * 1024L * 1024L * 1024L, // 5G + 2 * 1024L * 1024L * 1024L, // 2G + 1 * 1024L * 1024L * 1024L, // 1G + 500 * 1024L * 1024L, // 500M + 200 * 1024L * 1024L, // 200M + 100 * 1024L * 1024L // 100M +}; + +int ObPartitionBalance::init(uint64_t tenant_id, schema::ObMultiVersionSchemaService *schema_service, common::ObMySQLProxy *sql_proxy, + const int64_t primary_zone_num, const int64_t unit_group_num, TaskMode task_mode) +{ + int ret = OB_SUCCESS; + if (inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("ObPartitionBalance has inited", KR(ret), K(this)); + } else if (OB_INVALID_TENANT_ID == tenant_id || OB_ISNULL(schema_service) || OB_ISNULL(sql_proxy) + || (task_mode != GEN_BG_STAT && task_mode != GEN_TRANSFER_TASK)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObPartitionBalance run", KR(ret), K(tenant_id), K(schema_service), K(sql_proxy), K(task_mode)); + } else if (OB_FAIL(bg_builder_.init(tenant_id, "PART_BALANCE", *this, *sql_proxy, *schema_service))) { + LOG_WARN("init all balance group builder fail", KR(ret), K(tenant_id)); + } else if (OB_FAIL(bg_map_.create(40960, lib::ObLabel("PART_BALANCE")))) { + LOG_WARN("map create fail", KR(ret)); + } else if (OB_FAIL(transfer_logical_tasks_.create(1024, lib::ObLabel("PART_BALANCE")))) { + LOG_WARN("map create fail", KR(ret)); + } else if (OB_FAIL(ls_desc_map_.create(10, lib::ObLabel("PART_BALANCE")))) { + LOG_WARN("map create fail", KR(ret)); + } else if (OB_FAIL(bg_ls_stat_operator_.init(sql_proxy))) { + LOG_WARN("init balance group ls stat operator fail", KR(ret)); + } else { + tenant_id_ = tenant_id; + sql_proxy_ = sql_proxy; + + //reset + allocator_.reset(); + cur_part_group_ = NULL; + ls_desc_array_.reset(); + balance_job_.reset(); + balance_tasks_.reset(); + task_mode_ = task_mode; + + primary_zone_num_ = primary_zone_num; + unit_group_num_ = unit_group_num; + inited_ = true; + } + return ret; +} + +void ObPartitionBalance::destroy() +{ + for (auto iter = ls_desc_map_.begin(); iter != ls_desc_map_.end(); iter++) { + if (OB_NOT_NULL(iter->second)) { + iter->second->~ObLSDesc(); + } + } + for (auto iter = bg_map_.begin(); iter != bg_map_.end(); iter++) { + for (int64_t i = 0; i < iter->second.count(); i++) { + if (OB_NOT_NULL(iter->second.at(i))) { + iter->second.at(i)->~ObLSPartGroupDesc(); + } + } + } + //reset + bg_builder_.destroy(); + cur_part_group_ = NULL; + allocator_.reset(); + ls_desc_array_.reset(); + ls_desc_map_.destroy(); + bg_map_.destroy(); + transfer_logical_tasks_.destroy(); + balance_job_.reset(); + balance_tasks_.reset(); + inited_ = false; + tenant_id_ = OB_INVALID_TENANT_ID; + sql_proxy_ = NULL; + task_mode_ = GEN_BG_STAT; + primary_zone_num_ = -1; + unit_group_num_ = -1; +} + +int ObPartitionBalance::process() +{ + int ret = OB_SUCCESS; + int64_t start_time = ObTimeUtility::current_time(); + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ObPartitionBalance not init", KR(ret), K(this)); + } else if (OB_FAIL(prepare_balance_group_())) { + LOG_WARN("prepare_balance_group fail", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(save_balance_group_stat_())) { + LOG_WARN("save balance group stat fail", KR(ret), K(tenant_id_)); + } else if (GEN_BG_STAT == task_mode_) { + // finish + } else if (bg_map_.empty()) { + LOG_INFO("PART_BALANCE balance group is empty do nothing", K(tenant_id_)); + } else if (transfer_logical_tasks_.empty() && OB_FAIL(process_balance_partition_inner_())) { + LOG_WARN("process_balance_partition_inner fail", KR(ret), K(tenant_id_)); + } else if (transfer_logical_tasks_.empty() && OB_FAIL(process_balance_partition_extend_())) { + LOG_WARN("process_balance_partition_extend fail", KR(ret), K(tenant_id_)); + } else if (transfer_logical_tasks_.empty() && OB_FAIL(process_balance_partition_disk_())) { + LOG_WARN("process_balance_partition_disk fail", KR(ret), K(tenant_id_)); + } else if (!transfer_logical_tasks_.empty() && OB_FAIL(generate_balance_job_from_logical_task_())) { + LOG_WARN("generate_balance_job_from_logical_task_ fail", KR(ret), K(tenant_id_)); + } + int64_t end_time = ObTimeUtility::current_time(); + LOG_INFO("PART_BALANCE process", KR(ret), K(tenant_id_), K(task_mode_), "cost", end_time - start_time, "task_cnt", transfer_logical_tasks_.size()); + return ret; +} + +int ObPartitionBalance::prepare_ls_() +{ + int ret = OB_SUCCESS; + ObLSAttrArray ls_attr_array; + ObLSAttrOperator ls_operator(tenant_id_, sql_proxy_); + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ObPartitionBalance not init", KR(ret), K(this)); + } else if (OB_FAIL(ls_operator.get_all_ls_by_order(ls_attr_array))) { + LOG_WARN("get_all_ls fail", KR(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < ls_attr_array.count(); i++) { + ObLSDesc *ls_desc = nullptr; + if (0 == ls_attr_array.at(i).get_ls_group_id()) { + // skip sys ls and duplicate ls + } else if (!ls_attr_array.at(i).ls_is_normal()) { // TODO inclue wait offline status + ret = OB_STATE_NOT_MATCH; + LOG_WARN("ls is not in normal status", KR(ret), K(ls_attr_array.at(i).get_ls_id())); + } else if (OB_ISNULL(ls_desc = reinterpret_cast(allocator_.alloc(sizeof(ObLSDesc))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc mem fail", KR(ret)); + } else if (FALSE_IT(new(ls_desc) ObLSDesc(ls_attr_array.at(i).get_ls_id(), ls_attr_array.at(i).get_ls_group_id()))) { + } else if (OB_FAIL(ls_desc_array_.push_back(ls_desc))) { + LOG_WARN("push_back ls_desc to array fail", KR(ret), K(ls_desc->get_ls_id())); + } else if (OB_FAIL(ls_desc_map_.set_refactored(ls_desc->get_ls_id(), ls_desc))) { + LOG_WARN("init ls_desc to map fail", KR(ret), K(ls_desc->get_ls_id())); + } + } + if (OB_SUCC(ret) && ls_desc_array_.count() == 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("no ls can assign", KR(ret), K(tenant_id_)); + } + } + if (OB_SUCC(ret)) { + LOG_INFO("[PART_BALANCE] prepare_ls", K(tenant_id_), K(ls_desc_array_)); + } + return ret; +} + +int ObPartitionBalance::prepare_balance_group_() +{ + int ret = OB_SUCCESS; + cur_part_group_ = NULL; + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ObPartitionBalance not init", KR(ret), K(this)); + } + // Here must prepare balance group data first, to get schema info for this build + else if (OB_FAIL(bg_builder_.prepare(GEN_TRANSFER_TASK == task_mode_))) { + LOG_WARN("balance group builder prepare fail", KR(ret)); + } + // Then prepare LS info after schema info prepared + else if (OB_FAIL(prepare_ls_())) { + LOG_WARN("prepare_ls fail", KR(ret), K(tenant_id_)); + } + // At last, build balance group info + // During this build, on_new_partition() will be called + else if (OB_FAIL(bg_builder_.build())) { + LOG_WARN("balance group build fail", KR(ret), K(tenant_id_)); + } else { + cur_part_group_ = NULL; + } + return ret; +} + +int ObPartitionBalance::on_new_partition( + const ObBalanceGroup &bg_in, + const ObObjectID table_id, + const ObObjectID part_object_id, + const ObTabletID tablet_id, + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + const int64_t tablet_size, + const bool in_new_partition_group) +{ + int ret = OB_SUCCESS; + ObBalanceGroup bg = bg_in; // get a copy + ObLSDesc *src_ls_desc = nullptr; + ObTransferPartInfo part_info; + + if (OB_UNLIKELY(! inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObPartitionBalance not inited", KR(ret), K(inited_)); + } else if (OB_FAIL(ls_desc_map_.get_refactored(src_ls_id, src_ls_desc))) { + LOG_WARN("get LS desc fail", KR(ret), K(src_ls_id)); + } else if (OB_ISNULL(src_ls_desc)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not found LS", KR(ret), K(src_ls_id), KPC(src_ls_desc)); + } else if (OB_FAIL(part_info.init(table_id, part_object_id))) { + LOG_WARN("part_info init fail", KR(ret), K(table_id), K(part_object_id)); + } + // if dest_ls_id differs from src_ls_id, need generate balance task + else if (dest_ls_id != src_ls_id) { + ObTransferPartGroup tmp_part_group; + if (OB_FAIL(tmp_part_group.add_part(part_info, tablet_size))) { + LOG_WARN("part group add part fail", KR(ret), K(part_info), K(tablet_size)); + } else if (OB_FAIL(add_transfer_task_(src_ls_id, dest_ls_id, &tmp_part_group, false/*update_ls_desc_info*/))) { + LOG_WARN("add new transfer task fail", KR(ret), K(src_ls_id), K(dest_ls_id)); + } + } else { + // create partition group if in new partition group + if (in_new_partition_group) { + ObTransferPartGroup *part_group = nullptr; + if (OB_ISNULL(part_group = reinterpret_cast(allocator_.alloc(sizeof(ObTransferPartGroup))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc mem fail", KR(ret)); + } else if (FALSE_IT(cur_part_group_ = new(part_group) ObTransferPartGroup())) { + } else if (OB_FAIL(add_part_to_bg_map_(src_ls_id, *cur_part_group_, bg))) { + LOG_WARN("add partition to balance group fail", KR(ret), K(src_ls_id), K(bg), + K(cur_part_group_)); + } else { + // add new partition group + src_ls_desc->add_partgroup(1, 0); + } + } + // if not in new partition group, current part group should be valid + else if (OB_ISNULL(cur_part_group_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("current part group is null when not in new partition group", K(cur_part_group_), + K(in_new_partition_group), K(bg)); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(cur_part_group_->add_part(part_info, tablet_size))) { + LOG_WARN("partition group add part fail", KR(ret), K(part_info), K(tablet_size)); + } else { + // partition group not changed, data size need update + src_ls_desc->add_data_size(tablet_size); + } + } + return ret; +} + +int ObPartitionBalance::add_part_to_bg_map_(const ObLSID &ls_id, + ObTransferPartGroup &part_group, + ObBalanceGroup &bg) +{ + int ret = OB_SUCCESS; + ObArray *ls_part_desc_arr = NULL; + ls_part_desc_arr = bg_map_.get(bg); + if (OB_ISNULL(ls_part_desc_arr)) { + ObArray ls_part_desc_arr_obj; + if (OB_FAIL(bg_map_.set_refactored(bg, ls_part_desc_arr_obj))) { + LOG_WARN("init part to balance group fail", KR(ret), K(ls_id), K(bg)); + } else { + ls_part_desc_arr = bg_map_.get(bg); + if (OB_ISNULL(ls_part_desc_arr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get part from balance group fail", KR(ret), K(ls_id), K(bg)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < ls_desc_array_.count(); i++) { + ObLSPartGroupDesc *ls_part_desc = nullptr; + if (OB_ISNULL(ls_part_desc = reinterpret_cast(allocator_.alloc(sizeof(ObLSPartGroupDesc))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc mem fail", KR(ret), K(ls_id), K(bg)); + } else if (FALSE_IT(new(ls_part_desc) ObLSPartGroupDesc(ls_desc_array_.at(i)->get_ls_id()))) { + } else if (OB_FAIL(ls_part_desc_arr->push_back(ls_part_desc))) { + LOG_WARN("push_back fail", KR(ret), K(ls_id), K(bg)); + } + } + } + } + } + if (OB_SUCC(ret) && ls_part_desc_arr != nullptr) { + bool find_ls = false; + for (int64_t idx = 0; OB_SUCC(ret) && idx < ls_part_desc_arr->count(); idx++) { + if (ls_part_desc_arr->at(idx)->get_ls_id() == ls_id) { + if (OB_FAIL(ls_part_desc_arr->at(idx)->get_part_groups().push_back(&part_group))) { + LOG_WARN("push_back fail", KR(ret)); + } + find_ls = true; + break; + } + } + if (OB_SUCC(ret) && !find_ls) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not found LS", KR(ret), K(ls_id), K(part_group), K(bg)); + } + } + + return ret; +} + +int ObPartitionBalance::process_balance_partition_inner_() +{ + int ret = OB_SUCCESS; + + for (auto iter = bg_map_.begin(); OB_SUCC(ret) && iter != bg_map_.end(); iter++) { + int64_t part_group_sum = 0; + ObArray &ls_part_desc_arr = iter->second; + int64_t ls_cnt = ls_part_desc_arr.count(); + for (int64_t ls_idx = 0; ls_idx < ls_cnt; ls_idx++) { + part_group_sum += ls_part_desc_arr.at(ls_idx)->get_part_groups().count(); + } + while (OB_SUCC(ret)) { + std::sort(ls_part_desc_arr.begin(), ls_part_desc_arr.end(), [] (ObLSPartGroupDesc* left, ObLSPartGroupDesc* right) { + if (left->get_part_groups().count() < right->get_part_groups().count()) { + return true; + } else if (left->get_part_groups().count() == right->get_part_groups().count()) { + if (left->get_ls_id() > right->get_ls_id()) { + return true; + } + } + return false; + }); + ObLSPartGroupDesc *ls_max = ls_part_desc_arr.at(ls_cnt - 1); + ObLSPartGroupDesc *ls_min = ls_part_desc_arr.at(0); + //If difference in number of partition groups between LS does not exceed 1, this balance group is balanced + if (ls_part_desc_arr.at(ls_cnt - 1)->get_part_groups().count() - ls_part_desc_arr.at(0)->get_part_groups().count() <= 1) { + // balance group has done + break; + } + /* example1: ls1 ls2 ls3 ls4 ls5 + * part_group_count: 3 4 4 5 5 + * we should find ls4 -> ls1 + * + * example2: ls1 ls2 ls3 ls4 ls5 + * part_group_count: 3 3 4 4 5 + * we should find ls5 -> ls2 + * + * example3: ls1 ls2 ls3 ls4 ls5 + * part_group_count: 3 3 3 3 5 + * we should find ls5 -> ls4 + */ + + ObLSPartGroupDesc *ls_more = nullptr; + int64_t ls_more_dest = 0; + ObLSPartGroupDesc *ls_less = nullptr; + int64_t ls_less_dest = 0; + for (int64_t ls_idx = ls_part_desc_arr.count() - 1; ls_idx >= 0; ls_idx--) { + int64_t part_dest = ls_idx < (ls_cnt - (part_group_sum % ls_cnt)) ? part_group_sum / ls_cnt : part_group_sum / ls_cnt + 1;; + if (ls_part_desc_arr.at(ls_idx)->get_part_groups().count() > part_dest) { + ls_more = ls_part_desc_arr.at(ls_idx); + ls_more_dest = part_dest; + break; + } + } + for (int64_t ls_idx = 0; ls_idx < ls_part_desc_arr.count(); ls_idx++) { + int64_t part_dest = ls_idx < (ls_cnt - (part_group_sum % ls_cnt)) ? part_group_sum / ls_cnt : part_group_sum / ls_cnt + 1;; + if (ls_part_desc_arr.at(ls_idx)->get_part_groups().count() < part_dest) { + ls_less = ls_part_desc_arr.at(ls_idx); + ls_less_dest = part_dest; + break; + } + } + if (OB_ISNULL(ls_more) || OB_ISNULL(ls_less)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not found dest ls", KR(ret)); + break; + } + int64_t transfer_cnt = MIN(ls_more->get_part_groups().count() - ls_more_dest, ls_less_dest - ls_less->get_part_groups().count()); + for (int64_t i = 0; OB_SUCC(ret) && i < transfer_cnt; i++) { + if (OB_FAIL(add_transfer_task_(ls_more->get_ls_id(), ls_less->get_ls_id(), ls_more->get_part_groups().at(ls_more->get_part_groups().count() - 1)))) { + LOG_WARN("add_transfer_task_ fail", KR(ret), K(ls_more->get_ls_id()), K(ls_less->get_ls_id())); + } else if (OB_FAIL(ls_less->get_part_groups().push_back(ls_more->get_part_groups().at(ls_more->get_part_groups().count() - 1)))) { + LOG_WARN("push_back fail", KR(ret)); + } else if (OB_FAIL(ls_more->get_part_groups().remove(ls_more->get_part_groups().count() - 1))) { + LOG_WARN("parts remove", KR(ret)); + } + } + } + } + LOG_INFO("[PART_BALANCE] process_balance_partition_inner end", K(tenant_id_), K(ls_desc_array_)); + return ret; +} + +int ObPartitionBalance::add_transfer_task_(const ObLSID &src_ls_id, const ObLSID &dest_ls_id, ObTransferPartGroup *part_group, bool modify_ls_desc) +{ + int ret = OB_SUCCESS; + ObTransferTaskKey task_key(src_ls_id, dest_ls_id); + ObTransferPartList *tansfer_part_info = transfer_logical_tasks_.get(task_key); + if (OB_ISNULL(tansfer_part_info)) { + ObTransferPartList part_arr; + if (OB_FAIL(transfer_logical_tasks_.set_refactored(task_key, part_arr))) { + LOG_WARN("fail to init transfer task into map", KR(ret), K(task_key), K(part_arr)); + } else { + tansfer_part_info = transfer_logical_tasks_.get(task_key); + if (OB_ISNULL(tansfer_part_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail get transfer task from map", KR(ret), K(task_key)); + } + } + } + if (OB_SUCC(ret)) { + for (int64_t i = 0; OB_SUCC(ret) && i < part_group->get_part_list().count(); i++) { + if (OB_FAIL(tansfer_part_info->push_back(part_group->get_part_list().at(i)))) { + LOG_WARN("fail to push part info into transfer part array", KR(ret), + K(part_group->get_part_list().at(i))); + } + } + } + + if (OB_FAIL(ret)) { + } else if (modify_ls_desc && OB_FAIL(update_ls_desc_(src_ls_id, -1, part_group->get_data_size() * -1))) { + LOG_WARN("update_ls_desc", KR(ret), K(src_ls_id)); + } else if (modify_ls_desc && OB_FAIL(update_ls_desc_(dest_ls_id, 1, part_group->get_data_size()))) { + LOG_WARN("update_ls_desc", KR(ret), K(dest_ls_id)); + } + return ret; +} + +int ObPartitionBalance::update_ls_desc_(const ObLSID &ls_id, int64_t cnt, int64_t size) +{ + int ret = OB_SUCCESS; + + ObLSDesc *ls_desc = nullptr; + if (OB_FAIL(ls_desc_map_.get_refactored(ls_id, ls_desc))) { + LOG_WARN("get_refactored", KR(ret), K(ls_id)); + } else if (OB_ISNULL(ls_desc)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not found ls", KR(ret), K(ls_id)); + } else { + ls_desc->add_partgroup(cnt, size); + } + return ret; +} + +int ObPartitionBalance::process_balance_partition_extend_() +{ + int ret = OB_SUCCESS; + + int64_t ls_cnt = ls_desc_array_.count(); + uint64_t part_group_sum = 0; + for (int64_t i = 0; i < ls_cnt; i++) { + part_group_sum += ls_desc_array_.at(i)->get_partgroup_cnt(); + } + while (OB_SUCC(ret)) { + std::sort(ls_desc_array_.begin(), ls_desc_array_.end(), [] (ObLSDesc *l, ObLSDesc *r) { + if (l->get_partgroup_cnt() < r->get_partgroup_cnt()) { + return true; + } else if (l->get_partgroup_cnt() == r->get_partgroup_cnt()) { + if (l->get_data_size() < r->get_data_size()) { + return true; + } else if (l->get_data_size() == r->get_data_size()) { + if (l->get_ls_id() > r->get_ls_id()) { + return true; + } + } + } + return false; + }); + + ObLSDesc *ls_max = ls_desc_array_.at(ls_cnt - 1); + ObLSDesc *ls_min = ls_desc_array_.at(0); + if (ls_max->get_partgroup_cnt() - ls_min->get_partgroup_cnt() <= 1) { + break; + } + /* + * example: ls1 ls2 ls3 ls4 + * bg1 3 3 3 4 + * bg2 5 5 5 6 + * + * we should move ls4.bg1 -> ls3 or ls4.bg2 -> ls3 + */ + ObLSDesc *ls_more_desc = nullptr; + int64_t ls_more_dest = 0; + ObLSDesc *ls_less_desc = nullptr; + int64_t ls_less_dest = 0; + for (int64_t ls_idx = ls_desc_array_.count() -1; ls_idx >= 0; ls_idx--) { + int64_t part_dest = ls_idx < (ls_cnt - (part_group_sum % ls_cnt)) ? part_group_sum / ls_cnt : part_group_sum / ls_cnt + 1;; + if (ls_desc_array_.at(ls_idx)->get_partgroup_cnt() > part_dest) { + ls_more_desc = ls_desc_array_.at(ls_idx); + ls_more_dest = part_dest; + break; + } + } + for (int64_t ls_idx = 0; ls_idx < ls_desc_array_.count(); ls_idx++) { + int64_t part_dest = ls_idx < (ls_cnt - (part_group_sum % ls_cnt)) ? part_group_sum / ls_cnt : part_group_sum / ls_cnt + 1;; + if (ls_desc_array_.at(ls_idx)->get_partgroup_cnt() < part_dest) { + ls_less_desc = ls_desc_array_.at(ls_idx); + ls_less_dest = part_dest; + break; + } + } + if (OB_ISNULL(ls_more_desc) || OB_ISNULL(ls_less_desc)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not found dest ls", KR(ret), K(ls_more_desc), K(ls_less_desc)); + break; + } + int64_t transfer_cnt = MIN(ls_more_desc->get_partgroup_cnt() - ls_more_dest, ls_less_dest - ls_less_desc->get_partgroup_cnt()); + for (int64_t transfer_idx = 0; OB_SUCC(ret) && transfer_idx < transfer_cnt; transfer_idx++) { + for (auto iter = bg_map_.begin(); OB_SUCC(ret) && iter != bg_map_.end(); iter++) { + // find ls_more/ls_less + ObLSPartGroupDesc *ls_more = nullptr; + ObLSPartGroupDesc *ls_less = nullptr; + for (int64_t idx = 0; OB_SUCC(ret) && idx < iter->second.count(); idx++) { + if (iter->second.at(idx)->get_ls_id() == ls_more_desc->get_ls_id()) { + ls_more = iter->second.at(idx); + } else if (iter->second.at(idx)->get_ls_id() == ls_less_desc->get_ls_id()) { + ls_less = iter->second.at(idx); + } + if (ls_more != nullptr && ls_less != nullptr) { + break; + } + } + if (OB_ISNULL(ls_more) || OB_ISNULL(ls_less)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not found ls", KR(ret)); + break; + } + if (ls_more->get_part_groups().count() > ls_less->get_part_groups().count()) { + if (OB_FAIL(add_transfer_task_(ls_more->get_ls_id(), ls_less->get_ls_id(), ls_more->get_part_groups().at(ls_more->get_part_groups().count() - 1)))) { + LOG_WARN("add_transfer_task_ fail", KR(ret), K(ls_more->get_ls_id()), K(ls_less->get_ls_id())); + } else if (OB_FAIL(ls_less->get_part_groups().push_back(ls_more->get_part_groups().at(ls_more->get_part_groups().count() - 1)))) { + LOG_WARN("push_back fail", KR(ret)); + } else if (OB_FAIL(ls_more->get_part_groups().remove(ls_more->get_part_groups().count() - 1))) { + LOG_WARN("parts remove", KR(ret)); + } + break; + } + } + } + } + LOG_INFO("[PART_BALANCE] process_balance_partition_extend end", K(ret), K(tenant_id_), K(ls_desc_array_)); + return ret; +} + +int ObPartitionBalance::process_balance_partition_disk_() +{ + int ret = OB_SUCCESS; + + int64_t ls_cnt = ls_desc_array_.count(); + int64_t part_size_sum = 0; + for (int64_t i = 0; i < ls_cnt; i++) { + part_size_sum += ls_desc_array_.at(i)->get_data_size(); + } + while (OB_SUCC(ret)) { + std::sort(ls_desc_array_.begin(), ls_desc_array_.end(), [] (ObLSDesc *l, ObLSDesc *r) { + if (l->get_data_size() < r->get_data_size()) { + return true; + } else if (l->get_data_size() == r->get_data_size()) { + if (l->get_ls_id() > r->get_ls_id()) { + return true; + } + } + return false; + }); + + ObLSDesc &ls_max = *ls_desc_array_.at(ls_cnt - 1); + ObLSDesc &ls_min = *ls_desc_array_.at(0); + if (!check_ls_need_swap_(ls_max.get_data_size(), ls_min.get_data_size())) { + // disk has balance + break; + } + LOG_INFO("[PART_BALANCE] disk_balance", K(ls_max), K(ls_min)); + + /* + * select swap part_group by size segment + */ + int64_t swap_cnt = 0; + for (int64_t idx = 0; OB_SUCC(ret) && idx < sizeof(PART_GROUP_SIZE_SEGMENT) / sizeof(PART_GROUP_SIZE_SEGMENT[0]); idx++) { + if (OB_FAIL(try_swap_part_group_(ls_max, ls_min, PART_GROUP_SIZE_SEGMENT[idx], swap_cnt))) { + LOG_WARN("try_swap_part_group fail", KR(ret), K(ls_max), K(ls_min), K(PART_GROUP_SIZE_SEGMENT[idx])); + } else if (swap_cnt > 0) { + break; + } + } + if (swap_cnt == 0) { + // nothing to do + break; + } + } + LOG_INFO("[PART_BALANCE] process_balance_partition_disk end", KR(ret), K(tenant_id_), K(ls_desc_array_)); + return ret; +} + +bool ObPartitionBalance::check_ls_need_swap_(uint64_t ls_more_size, uint64_t ls_less_size) +{ + bool need_swap = false; + if (ls_more_size > PART_BALANCE_THRESHOLD_SIZE) { + if ((ls_more_size - ls_more_size * GCONF.balancer_tolerance_percentage / 100) > ls_less_size) { + need_swap = true; + } + } + return need_swap; +} + +int ObPartitionBalance::try_swap_part_group_(ObLSDesc &src_ls, ObLSDesc &dest_ls, int64_t part_group_min_size, int64_t &swap_cnt) +{ + int ret = OB_SUCCESS; + for (auto iter = bg_map_.begin(); OB_SUCC(ret) && iter != bg_map_.end(); iter++) { + if (!check_ls_need_swap_(src_ls.get_data_size(), dest_ls.get_data_size())) { + break; + } + // find ls_more/ls_less + ObLSPartGroupDesc *ls_more = nullptr; + ObLSPartGroupDesc *ls_less = nullptr; + for (int64_t idx = 0; OB_SUCC(ret) && idx < iter->second.count(); idx++) { + if (iter->second.at(idx)->get_ls_id() == src_ls.get_ls_id()) { + ls_more = iter->second.at(idx); + } else if (iter->second.at(idx)->get_ls_id() == dest_ls.get_ls_id()) { + ls_less = iter->second.at(idx); + } + if (ls_more != nullptr && ls_less != nullptr) { + break; + } + } + if (OB_ISNULL(ls_more) || OB_ISNULL(ls_less)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not found ls", KR(ret), K(ls_more), K(ls_less)); + break; + } + if (ls_more->get_part_groups().count() == 0 || ls_less->get_part_groups().count() == 0) { + continue; + } + std::sort(ls_more->get_part_groups().begin(), ls_more->get_part_groups().end(), [] (ObTransferPartGroup *l, ObTransferPartGroup *r) { + return l->get_data_size() < r->get_data_size(); + }); + std::sort(ls_less->get_part_groups().begin(), ls_less->get_part_groups().end(), [] (ObTransferPartGroup *l, ObTransferPartGroup *r) { + return l->get_data_size() < r->get_data_size(); + }); + + ObTransferPartGroup *src_part_group = ls_more->get_part_groups().at(ls_more->get_part_groups().count() -1); + ObTransferPartGroup *dest_part_group = ls_less->get_part_groups().at(0); + int64_t swap_size = src_part_group->get_data_size() - dest_part_group->get_data_size(); + if (swap_size >= part_group_min_size && src_ls.get_data_size() - dest_ls.get_data_size() > swap_size) { + LOG_INFO("[PART_BALANCE] swap_partition", K(*src_part_group), K(*dest_part_group), K(src_ls), K(dest_ls), K(swap_size), K(part_group_min_size)); + if (OB_FAIL(add_transfer_task_(ls_more->get_ls_id(), ls_less->get_ls_id(), src_part_group))) { + LOG_WARN("add_transfer_task_ fail", KR(ret), K(ls_more->get_ls_id()), K(ls_less->get_ls_id())); + } else if (OB_FAIL(ls_less->get_part_groups().push_back(src_part_group))) { + LOG_WARN("push_back fail", KR(ret), K(ls_less)); + } else if (OB_FAIL(ls_more->get_part_groups().remove(ls_more->get_part_groups().count() - 1))) { + LOG_WARN("parts remove", KR(ret), K(ls_more)); + } else if (OB_FAIL(add_transfer_task_(ls_less->get_ls_id(), ls_more->get_ls_id(), ls_less->get_part_groups().at(0)))) { + LOG_WARN("add_transfer_task_ fail", KR(ret), K(ls_more->get_ls_id()), K(ls_less->get_ls_id())); + } else if (OB_FAIL(ls_more->get_part_groups().push_back(ls_less->get_part_groups().at(0)))) { + LOG_WARN("push_back fail", KR(ret), K(ls_more)); + } else if (OB_FAIL(ls_less->get_part_groups().remove(0))) { + LOG_WARN("parts remove", KR(ret), K(ls_less)); + } else { + swap_cnt++; + } + } + } + return ret; +} + +int ObPartitionBalance::generate_balance_job_from_logical_task_() +{ + int ret = OB_SUCCESS; + + ObBalanceJobID job_id; + ObBalanceJobStatus job_status(ObBalanceJobStatus::BALANCE_JOB_STATUS_DOING); + ObBalanceJobType job_type(ObBalanceJobType::BALANCE_JOB_PARTITION); + const char* balance_stradegy = "partition balance"; // TODO + ObString comment; + + if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id_, job_id))) { + LOG_WARN("gen_unique_id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(balance_job_.init(tenant_id_, job_id, job_type, job_status, primary_zone_num_, unit_group_num_, + comment, ObString(balance_stradegy)))) { + LOG_WARN("job init fail", KR(ret), K(tenant_id_), K(job_id)); + } else { + for (auto iter = transfer_logical_tasks_.begin(); OB_SUCC(ret) && iter != transfer_logical_tasks_.end(); iter++) { + ObLSDesc *src_ls = nullptr; + ObLSDesc *dest_ls = nullptr; + if (OB_FAIL(ls_desc_map_.get_refactored(iter->first.get_src_ls_id(), src_ls))) { + LOG_WARN("get_refactored", KR(ret), K(iter->first.get_src_ls_id())); + } else if (OB_FAIL(ls_desc_map_.get_refactored(iter->first.get_dest_ls_id(), dest_ls))) { + LOG_WARN("get_refactored", KR(ret), K(iter->first.get_dest_ls_id())); + } else if (OB_ISNULL(src_ls) || OB_ISNULL(dest_ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not find ls", KR(ret), K(src_ls), K(dest_ls)); + } + if (OB_FAIL(ret)) { + } else if (src_ls->get_ls_group_id() == dest_ls->get_ls_group_id()) { + ObBalanceTask task; + ObBalanceTaskType task_type(ObBalanceTaskType::BALANCE_TASK_TRANSFER); + ObBalanceTaskID task_id; + if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id_, task_id))) { + LOG_WARN("gen_unique_id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(task.simple_init(tenant_id_, balance_job_.get_job_id(), task_id, task_type, + dest_ls->get_ls_group_id(), src_ls->get_ls_id(), dest_ls->get_ls_id(), iter->second))) { + LOG_WARN("init task fail", KR(ret)); + } else if (OB_FAIL(balance_tasks_.push_back(task))) { + LOG_WARN("push_back fail", KR(ret), K(task)); + } + } else { + // split + ObLSID tmp_ls_id; + const ObTransferPartList empty_part_list;//for alter and merge + if (OB_SUCC(ret)) { + ObBalanceTask task; + ObBalanceTaskType task_type(ObBalanceTaskType::BALANCE_TASK_SPLIT); + ObBalanceTaskID task_id; + if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id_, task_id))) { + LOG_WARN("gen_unique_id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(ObLSServiceHelper::fetch_new_ls_id(sql_proxy_, tenant_id_, tmp_ls_id))) { + LOG_WARN("failed to fetch new ls id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(task.simple_init(tenant_id_, balance_job_.get_job_id(), task_id, task_type, + src_ls->get_ls_group_id(), src_ls->get_ls_id(), tmp_ls_id, iter->second))) { + LOG_WARN("init task fail", KR(ret)); + } else if (OB_FAIL(balance_tasks_.push_back(task))) { + LOG_WARN("push_back fail", KR(ret), K(task)); + } + } + // alter + if (OB_SUCC(ret)) { + ObBalanceTask task; + ObBalanceTaskType task_type(ObBalanceTaskType::BALANCE_TASK_ALTER); + ObBalanceTaskID task_id; + if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id_, task_id))) { + LOG_WARN("gen_unique_id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(task.simple_init(tenant_id_, balance_job_.get_job_id(), task_id, task_type, + dest_ls->get_ls_group_id(), tmp_ls_id, tmp_ls_id, empty_part_list))) { + LOG_WARN("init task fail", KR(ret)); + } else if (OB_FAIL(balance_tasks_.push_back(task))) { + LOG_WARN("push_back fail", KR(ret), K(task)); + } + } + // merge + if (OB_SUCC(ret)) { + ObBalanceTask task; + ObBalanceTaskType task_type(ObBalanceTaskType::BALANCE_TASK_MERGE); + ObBalanceTaskID task_id; + if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id_, task_id))) { + LOG_WARN("gen_unique_id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(task.simple_init(tenant_id_, balance_job_.get_job_id(), task_id, task_type, + dest_ls->get_ls_group_id(), tmp_ls_id, dest_ls->get_ls_id(), empty_part_list))) { + LOG_WARN("init task fail", KR(ret)); + } else if (OB_FAIL(balance_tasks_.push_back(task))) { + LOG_WARN("push_back fail", KR(ret), K(task)); + } + } + } + } + } + return ret; +} + +int ObPartitionHelper::check_partition_option(const schema::ObSimpleTableSchemaV2 &t1, const schema::ObSimpleTableSchemaV2 &t2, bool is_subpart, bool &is_matched) +{ + int ret = OB_SUCCESS; + is_matched = false; + if (OB_FAIL(share::schema::ObSimpleTableSchemaV2::compare_partition_option(t1, t2, is_subpart, is_matched))) { + LOG_WARN("fail to compare partition optition", KR(ret)); + } + return ret; +} + +int ObPartitionBalance::save_balance_group_stat_() +{ + int ret = OB_SUCCESS; + ObMySQLTransaction trans; + ObSqlString sql; + int64_t affected_rows; + ObTimeoutCtx ctx; + int64_t start_time = ObTimeUtility::current_time(); + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ObPartitionBalance not init", KR(ret), K(this)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql_proxy is null", KR(ret)); + } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, GCONF.internal_sql_execute_timeout))) { + LOG_WARN("fail to set timeout ctx", KR(ret)); + } else if (!is_user_tenant(tenant_id_)) { + // do nothing + } else if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(tenant_id_)))) { + LOG_WARN("fail to start trans", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(bg_ls_stat_operator_.delete_balance_group_ls_stat(ctx.get_timeout(), trans, tenant_id_))) { + LOG_WARN("fail to delete balance group ls stat", KR(ret), K(tenant_id_)); + } else { + // iterator all balance group + for (auto iter = bg_map_.begin(); OB_SUCC(ret) && iter != bg_map_.end(); iter++) { + common::ObArray bg_ls_stat_array; + // iterator all ls + for (int64_t i = 0; OB_SUCC(ret) && i < iter->second.count(); i++) { + if (OB_NOT_NULL(iter->second.at(i))) { + ObBalanceGroupLSStat bg_ls_stat; + if (OB_FAIL(bg_ls_stat.build(tenant_id_, + iter->first.id(), + iter->second.at(i)->get_ls_id(), + iter->second.at(i)->get_part_groups().count(), + iter->first.name()))) { + LOG_WARN("fail to build bg ls stat", KR(ret), K(iter->first), KPC(iter->second.at(i))); + } else if (OB_FAIL(bg_ls_stat_array.push_back(bg_ls_stat))) { + LOG_WARN("fail to push back", KR(ret)); + } + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(bg_ls_stat_operator_.insert_update_balance_group_ls_stat(ctx.get_timeout(), trans, tenant_id_, + iter->first.id(), bg_ls_stat_array))) { + LOG_WARN("fail to insert update balance group ls stat", KR(ret), K(tenant_id_), K(iter->first)); + } + } + } + // commit/abort + int tmp_ret = OB_SUCCESS; + const bool is_commit = OB_SUCC(ret); + if (OB_SUCCESS != (tmp_ret = trans.end(is_commit))) { + LOG_WARN("trans end failed", K(tmp_ret), K(is_commit)); + ret = (OB_SUCCESS == ret ? tmp_ret : ret); + } + } + int64_t end_time = ObTimeUtility::current_time(); + LOG_INFO("[PART_BALANCE] save_balance_group_stat", K(ret), "cost", end_time - start_time); + return ret; +} + +int ObPartitionHelper::get_part_info(const schema::ObSimpleTableSchemaV2 &table_schema, int64_t part_idx, ObPartInfo &part_info) +{ + int ret = OB_SUCCESS; + ObTabletID tablet_id; + ObObjectID part_id; + ObObjectID first_level_part_id; + if (OB_FAIL(table_schema.get_tablet_and_object_id_by_index(part_idx, -1, tablet_id, part_id, first_level_part_id))) { + LOG_WARN("fail to get_tablet_and_object_id_by_index", KR(ret), K(table_schema), K(part_idx)); + } else if (OB_FAIL(part_info.init(tablet_id, part_id))) { + LOG_WARN("fail init part_info", KR(ret), K(tablet_id), K(part_id)); + } + return ret; +} + +int ObPartitionHelper::get_sub_part_num(const schema::ObSimpleTableSchemaV2 &table_schema, int64_t part_idx, int64_t &sub_part_num) +{ + int ret = OB_SUCCESS; + const schema::ObPartition *partition = NULL; + if (OB_FAIL(table_schema.get_partition_by_partition_index(part_idx, schema::CHECK_PARTITION_MODE_NORMAL, partition))) { + LOG_WARN("fail to get partition by part_idx", KR(ret), K(part_idx)); + } else if (OB_ISNULL(partition)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition not exist", KR(ret), K(table_schema), K(part_idx)); + } else { + sub_part_num = partition->get_sub_part_num(); + } + return ret; +} + +int ObPartitionHelper::get_sub_part_info(const schema::ObSimpleTableSchemaV2 &table_schema, int64_t part_idx, int64_t sub_part_idx, ObPartInfo &part_info) +{ + int ret = OB_SUCCESS; + + ObTabletID tablet_id; + ObObjectID part_id; + ObObjectID first_level_part_id; + if (OB_FAIL(table_schema.get_tablet_and_object_id_by_index(part_idx, sub_part_idx, tablet_id, part_id, first_level_part_id))) { + LOG_WARN("fail to get_tablet_and_object_id_by_index", KR(ret), K(table_schema), K(part_idx), K(sub_part_idx)); + } else if (OB_FAIL(part_info.init(tablet_id, part_id))) { + LOG_WARN("fail init part_info", KR(ret), K(tablet_id), K(part_id)); + } + + return ret; +} + +} // end rootserver +} // end oceanbase diff --git a/src/rootserver/ob_partition_balance.h b/src/rootserver/ob_partition_balance.h new file mode 100644 index 000000000..32ffa91aa --- /dev/null +++ b/src/rootserver/ob_partition_balance.h @@ -0,0 +1,244 @@ +/** + * Copyright (c) 2021 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 OB_OCEANBASE_BALANCE_PARTITION_JOB_H_ +#define OB_OCEANBASE_BALANCE_PARTITION_JOB_H_ + +#include "rootserver/ob_balance_group_ls_stat_operator.h" +#include "share/schema/ob_schema_getter_guard.h" +#include "share/schema/ob_table_schema.h" +#include "share/transfer/ob_transfer_info.h" +#include "share/schema/ob_multi_version_schema_service.h" +#include "share/ls/ob_ls_operator.h" +#include "share/balance/ob_balance_task_table_operator.h" //ObBalanceTask +#include "share/balance/ob_balance_job_table_operator.h" //ObBalanceJob + +#include "balance/ob_balance_group_info.h" // ObTransferPartGroup +#include "balance/ob_all_balance_group_builder.h" // ObAllBalanceGroupBuilder + +namespace oceanbase +{ +namespace rootserver +{ +using namespace oceanbase::common; +using namespace oceanbase::share; + +// Partition Balance implment +class ObPartitionBalance final : public ObAllBalanceGroupBuilder::NewPartitionCallback +{ +public: + ObPartitionBalance() : inited_(false), tenant_id_(OB_INVALID_TENANT_ID), sql_proxy_(nullptr), + allocator_(lib::ObLabel("PART_BALANCE")), + bg_builder_(), cur_part_group_(nullptr), + ls_desc_array_(), ls_desc_map_(), + bg_map_(), + transfer_logical_tasks_(), + bg_ls_stat_operator_(), + balance_job_(), + balance_tasks_(), + task_mode_(GEN_BG_STAT), + primary_zone_num_(-1), + unit_group_num_(-1) + {} + ~ObPartitionBalance() { + destroy(); + } + enum TaskMode { + GEN_BG_STAT, + GEN_TRANSFER_TASK + }; + + int init(uint64_t tenant_id, schema::ObMultiVersionSchemaService *schema_service, common::ObMySQLProxy *sql_proxy, + const int64_t primary_zone_num, const int64_t unit_group_num, + TaskMode mode = GEN_BG_STAT); + void destroy(); + int process(); + + ObBalanceJob &get_balance_job() { return balance_job_; } + ObArray &get_balance_task() { return balance_tasks_; } + + + // For ObAllBalanceGroupBuilder::NewPartitionCallback + // handle new partition of every balance group + int on_new_partition( + const ObBalanceGroup &bg, + const ObObjectID table_id, + const ObObjectID part_object_id, + const ObTabletID tablet_id, + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + const int64_t tablet_size, + const bool in_new_partition_group); + + class ObLSPartGroupDesc + { + public: + ObLSPartGroupDesc(ObLSID ls_id) : ls_id_(ls_id) {} + ~ObLSPartGroupDesc() { + ls_id_.reset(); + for (int64_t i = 0; i < part_groups_.count(); i++) { + if (OB_NOT_NULL(part_groups_.at(i))) { + part_groups_.at(i)->~ObTransferPartGroup(); + } + } + part_groups_.reset(); + } + ObLSID get_ls_id() const { return ls_id_; } + ObArray &get_part_groups() { return part_groups_; } + TO_STRING_KV(K_(ls_id), K_(part_groups)); + private: + ObLSID ls_id_; + ObArray part_groups_; + }; + + class ObLSDesc + { + public: + ObLSDesc(ObLSID ls_id, uint64_t ls_group_id) : ls_id_(ls_id), ls_group_id_(ls_group_id), partgroup_cnt_(0), data_size_(0) {} + ~ObLSDesc() { + ls_id_.reset(); + ls_group_id_ = OB_INVALID_ID; + partgroup_cnt_ = 0; + data_size_ = 0; + } + ObLSID get_ls_id() const { return ls_id_; } + uint64_t get_partgroup_cnt() const { return partgroup_cnt_; } + uint64_t get_data_size() const { return data_size_; } + uint64_t get_ls_group_id() const { return ls_group_id_; } + void add_partgroup(int64_t count, int64_t size) { partgroup_cnt_ += count; add_data_size(size); } + void add_data_size(int64_t size) { data_size_ += size; } + TO_STRING_KV(K_(ls_id), K_(partgroup_cnt), K_(data_size)); + private: + ObLSID ls_id_; + uint64_t ls_group_id_; + uint64_t partgroup_cnt_; + uint64_t data_size_; + }; + + class ObTransferTaskKey + { + public: + ObTransferTaskKey(const ObLSID &src_ls_id, const ObLSID &dest_ls_id) : + src_ls_id_(src_ls_id), dest_ls_id_(dest_ls_id) {} + ObTransferTaskKey(const ObTransferTaskKey &other) { + src_ls_id_ = other.src_ls_id_; + dest_ls_id_ = other.dest_ls_id_; + } + ObTransferTaskKey() {} + int hash(uint64_t &res) const { + res = 0; + res = murmurhash(&src_ls_id_, sizeof(src_ls_id_), res); + res = murmurhash(&dest_ls_id_, sizeof(dest_ls_id_), res); + return OB_SUCCESS; + } + bool operator ==(const ObTransferTaskKey &other) const { + return src_ls_id_ == other.src_ls_id_ && dest_ls_id_ == other.dest_ls_id_; + } + bool operator !=(const ObTransferTaskKey &other) const { return !(operator ==(other)); } + ObLSID get_src_ls_id() const { return src_ls_id_; } + ObLSID get_dest_ls_id() const { return dest_ls_id_; } + TO_STRING_KV(K_(src_ls_id), K_(dest_ls_id)); + private: + ObLSID src_ls_id_; + ObLSID dest_ls_id_; + }; + + static const int64_t PART_BALANCE_THRESHOLD_SIZE = 50 * 1024L * 1024L * 1024L; // 50GB + +private: + int prepare_balance_group_(); + int save_balance_group_stat_(); + int construct_balance_group_(); + int construct_bg_for_partlevel_zero_(const schema::ObSimpleTableSchemaV2 &table_schema); + int construct_bg_for_partlevel_one_(const schema::ObSimpleTableSchemaV2 &table_schema); + int construct_bg_for_partlevel_two_(const schema::ObSimpleTableSchemaV2 &table_schema); + int construct_bg_for_tablegroup_sharding_none_(const schema::ObSimpleTablegroupSchema &tablegroup_schema, ObArray &table_schemas); + int construct_bg_for_tablegroup_sharding_partition_(const schema::ObSimpleTablegroupSchema &tablegroup_schema, ObArray &table_schemas); + int construct_bg_for_tablegroup_sharding_subpart_(const schema::ObSimpleTablegroupSchema &tablegroup_schema, ObArray &table_schemas); + int add_tablet_to_bg_(ObTransferPartGroup *&dest_part_group, ObLSID &dest_ls_id, ObTabletID tablet_id, ObBalanceGroupID &bg_id, ObObjectID table_id, ObObjectID part_id); + // balance group inner balance + int process_balance_partition_inner_(); + // balance group extend balance + int process_balance_partition_extend_(); + // ls disk balance + int process_balance_partition_disk_(); + int generate_balance_job_from_logical_task_(); + + int prepare_ls_(); + int add_part_to_bg_map_(const ObLSID &ls_id, ObTransferPartGroup &part_group, ObBalanceGroup &bg); + int add_transfer_task_(const ObLSID &src_ls_id, const ObLSID &dest_ls_id, ObTransferPartGroup *part_group, bool modify_ls_desc = true); + int update_ls_desc_(const ObLSID &ls_id, int64_t cnt, int64_t size); + int try_swap_part_group_(ObLSDesc &src_ls, ObLSDesc &dest_ls, int64_t part_group_min_size ,int64_t &swap_cnt); + int get_table_schemas_in_tablegroup_(int64_t tablegroup_id, + ObArray &table_schemas, + int &max_part_level); + bool check_ls_need_swap_(uint64_t ls_more_size, uint64_t ls_less_size); +private: + bool inited_; + uint64_t tenant_id_; + common::ObMySQLProxy *sql_proxy_; + common::ObArenaAllocator allocator_; + + ObAllBalanceGroupBuilder bg_builder_; + ObTransferPartGroup *cur_part_group_; + + // ls array to assign part + ObArray ls_desc_array_; + hash::ObHashMap ls_desc_map_; + + // partition distribute in balance group and ls + hash::ObHashMap> bg_map_; + + // logical transfer task + hash::ObHashMap transfer_logical_tasks_; + + ObBalanceGroupLSStatOperator bg_ls_stat_operator_; + + // generate result: balance job and balance task + ObBalanceJob balance_job_; + ObArray balance_tasks_; + + TaskMode task_mode_; + //for generate balance job + int64_t primary_zone_num_; + int64_t unit_group_num_; +}; + +class ObPartitionHelper +{ +public: + class ObPartInfo { + public: + ObPartInfo() {} + int init(ObTabletID tablet_id, ObObjectID part_id) { + int ret = OB_SUCCESS; + tablet_id_ = tablet_id; + part_id_ = part_id; + return ret; + } + ObTabletID get_tablet_id() { return tablet_id_; } + ObObjectID get_part_id() { return part_id_; } + TO_STRING_KV(K_(tablet_id), K_(part_id)); + private: + ObTabletID tablet_id_; + ObObjectID part_id_; + }; + static int get_part_info(const schema::ObSimpleTableSchemaV2 &table_schema, int64_t part_idx, ObPartInfo &part_info); + static int get_sub_part_num(const schema::ObSimpleTableSchemaV2 &table_schema, int64_t part_idx, int64_t &sub_part_num); + static int get_sub_part_info(const schema::ObSimpleTableSchemaV2 &table_schema, int64_t part_idx, int64_t sub_part_idx, ObPartInfo &part_info); + static int check_partition_option(const schema::ObSimpleTableSchemaV2 &t1, const schema::ObSimpleTableSchemaV2 &t2, bool is_subpart, bool &is_matched); + static int check_partition_match(const schema::ObSimpleTableSchemaV2 &t1, const schema::ObSimpleTableSchemaV2 &t2, bool &match); +}; + +} // end rootserver +} // end oceanbase +#endif diff --git a/src/rootserver/ob_primary_ls_service.cpp b/src/rootserver/ob_primary_ls_service.cpp index 8024a2ac5..c5dc3fe2c 100755 --- a/src/rootserver/ob_primary_ls_service.cpp +++ b/src/rootserver/ob_primary_ls_service.cpp @@ -14,24 +14,16 @@ #include "ob_primary_ls_service.h" #include "lib/profile/ob_trace_id.h" #include "share/ob_errno.h" -#include "share/ob_max_id_fetcher.h" -#include "share/schema/ob_schema_struct.h"//ObTenantInfo -#include "share/schema/ob_schema_service.h"//ObMultiSchemaService #include "share/ls/ob_ls_creator.h" //ObLSCreator #include "share/ls/ob_ls_life_manager.h"//ObLSLifeAgentManager -#include "share/ls/ob_ls_table_operator.h"//ObLSTableOpertor -#include "share/ob_primary_zone_util.h"//ObPrimaryZoneUtil -#include "share/ob_unit_table_operator.h"//ObUnitTableOperator -#include "share/ob_zone_table_operation.h" //ObZoneTableOperation +#include "share/ls/ob_ls_table_operator.h"//ls_opt #include "share/ob_share_util.h"//ObShareUtil #include "observer/ob_server_struct.h"//GCTX -#include "rootserver/ob_tenant_recovery_reportor.h"//update_ls_recovery -#include "rootserver/ob_tenant_info_loader.h" -#include "rootserver/ob_tenant_role_transition_service.h" -#include "storage/tx_storage/ob_ls_map.h" #include "storage/tx_storage/ob_ls_service.h" #include "storage/tx_storage/ob_ls_handle.h" //ObLSHandle #include "logservice/palf/palf_base_info.h"//PalfBaseInfo +#include "rootserver/ob_ls_service_helper.h"//ObTenantLSInfo +#include "rootserver/ob_ls_recovery_reportor.h"//update_ls_recovery namespace oceanbase { @@ -41,2063 +33,6 @@ using namespace transaction; using namespace palf; namespace rootserver { -/////////ObUnitGroupInfo -bool ObUnitGroupInfo::is_valid() const -{ - return OB_INVALID_ID != unit_group_id_ - && share::ObUnit::UNIT_STATUS_MAX != unit_status_; -} - -int ObUnitGroupInfo::init(const uint64_t unit_group_id, - const share::ObUnit::Status &unit_status) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(OB_INVALID_ID == unit_group_id - || share::ObUnit::UNIT_STATUS_MAX == unit_status)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(unit_group_id), K(unit_status)); - } else { - unit_group_id_ = unit_group_id; - unit_status_ = unit_status; - } - return ret; -} - -void ObUnitGroupInfo::reset() -{ - unit_group_id_ = OB_INVALID_ID; - unit_status_ = share::ObUnit::UNIT_STATUS_MAX; - ls_group_ids_.reset(); -} - -int ObUnitGroupInfo::assign(const ObUnitGroupInfo &other) -{ - int ret = OB_SUCCESS; - if (this != &other) { - if (OB_FAIL(ls_group_ids_.assign(other.ls_group_ids_))) { - LOG_WARN("failed to assign", KR(ret), K(other)); - } else { - unit_group_id_ = other.unit_group_id_; - unit_status_ = other.unit_status_; - } - } - return ret; -} - -int ObUnitGroupInfo::remove_ls_group(const uint64_t ls_group_id) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(ObLSID::MIN_USER_LS_GROUP_ID >= ls_group_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls group id is invalid", KR(ret), K(ls_group_id)); - } else { - bool remove = false; - for (int64_t i = 0; OB_SUCC(ret) && i < ls_group_ids_.count(); ++i) { - if (ls_group_ids_.at(i) == ls_group_id) { - remove = true; - if (OB_FAIL(ls_group_ids_.remove(i))) { - LOG_WARN("failed to remove from array", KR(ret), K(i), - K(ls_group_id), "this", *this); - } - break; - } - } - if (OB_SUCC(ret) && !remove) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("failed to find ls group id", KR(ret), - K(ls_group_id), "this", *this); - } - } - return ret; -} - -bool ObUnitGroupInfo::operator==(const ObUnitGroupInfo &other) const -{ - return unit_group_id_ == other.unit_group_id_ - && unit_status_ == other.unit_status_; -} - -////////////ObLSGroupInfo -bool ObLSGroupInfo::is_valid() const -{ - return OB_INVALID_ID != unit_group_id_ - && OB_INVALID_ID != ls_group_id_; -} - -int ObLSGroupInfo::init(const uint64_t unit_group_id, - const uint64_t ls_group_id) -{ - int ret = OB_SUCCESS; - reset(); - if (OB_UNLIKELY(OB_INVALID_ID == unit_group_id - || OB_INVALID_ID == ls_group_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(unit_group_id), K(ls_group_id)); - } else { - unit_group_id_ = unit_group_id; - ls_group_id_ = ls_group_id; - } - return ret; -} - -int ObLSGroupInfo::assign(const ObLSGroupInfo &other) -{ - int ret = OB_SUCCESS; - if (this != &other) { - reset(); - if (OB_FAIL(ls_ids_.assign(other.ls_ids_))) { - LOG_WARN("failed to assign ls ids", KR(ret), K(other)); - } else { - unit_group_id_ = other.unit_group_id_; - ls_group_id_ = other.ls_group_id_; - } - } - return ret; -} - -void ObLSGroupInfo::reset() -{ - ls_group_id_ = OB_INVALID_ID; - unit_group_id_ = OB_INVALID_ID; - ls_ids_.reset(); -} - -int ObLSGroupInfo::remove_ls(const share::ObLSID &ls_id) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!ls_id.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls id is invalid", KR(ret), K(ls_id)); - } else { - bool remove = false; - for (int64_t i = 0; OB_SUCC(ret) && i < ls_ids_.count(); ++i) { - if (ls_ids_.at(i) == ls_id) { - remove = true; - if (OB_FAIL(ls_ids_.remove(i))) { - LOG_WARN("failed to remove from array", KR(ret), K(i), - K(ls_id), "this", *this); - } - break; - } - } - if (OB_SUCC(ret) && !remove) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("failed to find ls id", KR(ret), - K(ls_id), "this", *this); - } - } - return ret; - -} - -///////////////ObLSStatusMachineParameter -//no need check status valid or ls_status is valid -int ObLSStatusMachineParameter::init(const share::ObLSID &id, - const share::ObLSStatusInfo &status_info, - const share::ObLSStatus &ls_info) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!id.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("id is invalid", KR(ret), K(id)); - } else if (OB_FAIL(status_info_.assign(status_info))) { - LOG_WARN("failed to assign status info", KR(ret), K(status_info)); - } else { - ls_info_ = ls_info; - ls_id_ = id; - } - return ret; -} - -void ObLSStatusMachineParameter::reset() -{ - ls_id_.reset(); - ls_info_ = share::OB_LS_EMPTY; - status_info_.reset(); -} - -/////////////ObTenantLSInfo - -void ObTenantLSInfo::reset() -{ - is_load_ = false; - status_array_.reset(); - unit_group_array_.reset(); - ls_group_array_.reset(); - primary_zone_.reset(); - max_ls_id_ = OB_INVALID_ID; - max_ls_group_id_ = OB_INVALID_ID; -} - - -bool ObTenantLSInfo::is_valid() const -{ - return ATOMIC_LOAD(&is_load_); -} - -//Regardless of the tenant being dropped, -//handle the asynchronous operation of status and history table -int ObTenantLSInfo::process_ls_status_missmatch( - const bool lock_sys_ls, - const share::ObTenantSwitchoverStatus &working_sw_status) -{ - int ret = OB_SUCCESS; - share::ObLSStatusInfoArray status_info_array; - share::ObLSAttrArray ls_array; - ObArray status_machine_array; - if (OB_ISNULL(sql_proxy_) || OB_ISNULL(tenant_schema_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy or tenant schema is null", KR(ret), KP(tenant_schema_), KP(sql_proxy_)); - } else if (OB_FAIL(ls_operator_.get_all_ls_by_order(lock_sys_ls, ls_array))) { - LOG_WARN("failed to insert ls operation", KR(ret)); - } else { - const uint64_t tenant_id = tenant_schema_->get_tenant_id(); - if (OB_FAIL(status_operator_.get_all_ls_status_by_order( - tenant_id, status_info_array, *sql_proxy_))) { - LOG_WARN("failed to update ls status", KR(ret)); - } - } - if (FAILEDx(construct_ls_status_machine_(status_info_array, ls_array, - status_machine_array))) { - LOG_WARN("failed to construct ls status machine array", KR(ret), - K(status_info_array), K(ls_array)); - } else { - int tmp_ret = OB_SUCCESS; - ARRAY_FOREACH_NORET(status_machine_array, idx) { - const ObLSStatusMachineParameter &machine = status_machine_array.at(idx); - //ignore error of each ls - //may ls can not create success - if (OB_SUCCESS != (tmp_ret = fix_ls_status_(machine, working_sw_status))) { - LOG_WARN("failed to fix ls status", KR(ret), KR(tmp_ret), K(machine)); - ret = OB_SUCC(ret) ? tmp_ret : ret; - } - } - } - - return ret; -} - -int ObTenantLSInfo::construct_ls_status_machine_( - const share::ObLSStatusInfoIArray &status_info_array, - const share::ObLSAttrIArray &ls_array, - common::ObIArray &status_machine_array) -{ - int ret = OB_SUCCESS; - status_machine_array.reset(); - if (OB_UNLIKELY(0 == status_info_array.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls array can not be empty", KR(ret), K(ls_array), K(status_info_array)); - } else { - // merge by sort - int64_t status_index = 0; - int64_t ls_index = 0; - ObLSStatusMachineParameter status_machine; - const int64_t status_count = status_info_array.count(); - const int64_t ls_count = ls_array.count(); - share::ObLSStatusInfo status_info; - ObLSID ls_id; - ObLSStatus ls_info_status = share::OB_LS_EMPTY; - while ((status_index < status_count || ls_index < ls_count) && OB_SUCC(ret)) { - status_machine.reset(); - if (status_index == status_count) { - //status already end - ls_id = ls_array.at(ls_index).get_ls_id(); - ls_info_status = ls_array.at(ls_index).get_ls_status(); - status_info.reset(); - ls_index++; - } else if (ls_index == ls_count) { - //ls already end - if (OB_FAIL(status_info.assign(status_info_array.at(status_index)))) { - LOG_WARN("failed to assign status info", KR(ret), K(status_index)); - } else { - status_index++; - ls_id = status_info.ls_id_; - ls_info_status = share::OB_LS_EMPTY; - } - } else { - const share::ObLSStatusInfo &tmp_status_info = status_info_array.at(status_index); - const share::ObLSAttr &tmp_ls_info = ls_array.at(ls_index); - if (tmp_status_info.ls_id_ == tmp_ls_info.get_ls_id()) { - status_index++; - ls_index++; - ls_info_status = tmp_ls_info.get_ls_status(); - ls_id = tmp_status_info.ls_id_; - if (OB_FAIL(status_info.assign(tmp_status_info))) { - LOG_WARN("failed to assign status info", KR(ret), K(tmp_status_info)); - } - } else if (tmp_status_info.ls_id_ > tmp_ls_info.get_ls_id()) { - ls_index++; - ls_id = tmp_ls_info.get_ls_id(); - ls_info_status = tmp_ls_info.get_ls_status(); - status_info.reset(); - } else { - status_index++; - ls_id = tmp_status_info.ls_id_; - ls_info_status = share::OB_LS_EMPTY; - if (OB_FAIL(status_info.assign(tmp_status_info))) { - LOG_WARN("failed to assign status info", KR(ret), K(tmp_status_info)); - } - } - } - if (FAILEDx(status_machine.init(ls_id, status_info, ls_info_status))) { - LOG_WARN("failed to push back status", KR(ret), K(ls_id), K(status_info), K(ls_info_status)); - } else if (OB_FAIL(status_machine_array.push_back(status_machine))) { - LOG_WARN("failed to push back status machine", KR(ret), K(status_machine)); - } - } // end while - - } - return ret; -} - -//for create new ls -//ls_info:creating, status_info:creating, status_info:created, ls_info:normal, status_info:normal - -//for drop ls -//ls_info:dropping, status_info:dropping, ls_info:empty, status_info:wait_offline - -//for drop tenant -//ls_info:tenant_dropping, status_info:tenant_dropping, ls_info:empty, status_info:wait_offline -//the sys ls can be tenant_dropping in status_info after all_users ls were deleted in ls_info -int ObTenantLSInfo::fix_ls_status_(const ObLSStatusMachineParameter &machine, - const ObTenantSwitchoverStatus &working_sw_status) -{ - int ret = OB_SUCCESS; - const share::ObLSStatusInfo &status_info = machine.status_info_; - const uint64_t tenant_id = status_info.tenant_id_; - ObLSLifeAgentManager ls_life_agent(*sql_proxy_); - if (OB_UNLIKELY(!machine.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("status machine is valid", KR(ret), K(machine)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); - } else if (ls_is_empty_status(machine.ls_info_)) { - //the ls not in ls and in status - if (status_info.ls_is_wait_offline()) { - //already offline, status will be deleted by GC - } else if (status_info.ls_is_dropping() - || status_info.ls_is_tenant_dropping()) { - SCN drop_scn; - if (OB_FAIL(ObLSAttrOperator::get_tenant_gts(tenant_id, drop_scn))) { - LOG_WARN("failed to get gts", KR(ret), K(tenant_id)); - } else if (OB_FAIL(ls_life_agent.set_ls_offline(tenant_id, - status_info.ls_id_, status_info.status_, - drop_scn, working_sw_status))) { - LOG_WARN("failed to update ls status", KR(ret), K(status_info), K(tenant_id), K(drop_scn)); - } - } else if (status_info.ls_is_creating() - || status_info.ls_is_created() - || status_info.ls_is_create_abort()) { - //ls may create_abort - if (OB_FAIL(ls_life_agent.drop_ls(tenant_id, machine.ls_id_, working_sw_status))) { - LOG_WARN("failed to delete ls", KR(ret), K(machine)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("status machine not expected", KR(ret), K(machine)); - } - } else if (ls_is_creating_status(machine.ls_info_)) { - //the ls may is in creating - if (!status_info.is_valid()) { - // TODO fix later - //in primary cluster, can create continue, but no need - if (OB_FAIL(ls_operator_.delete_ls(machine.ls_id_, machine.ls_info_, working_sw_status))) { - LOG_WARN("failed to delete ls", KR(ret), K(machine)); - } - } else if (status_info.ls_is_creating() && working_sw_status.is_normal_status()) { - //TODO check the primary zone or unit group id is valid - ObLSRecoveryStat recovery_stat; - ObLSRecoveryStatOperator ls_recovery_operator; - if (OB_FAIL(ls_recovery_operator.get_ls_recovery_stat(tenant_id, status_info.ls_id_, - false/*for_update*/, recovery_stat, *sql_proxy_))) { - LOG_WARN("failed to get ls recovery stat", KR(ret), K(tenant_id), K(status_info)); - } else if (OB_FAIL(do_create_ls_(status_info, recovery_stat.get_create_scn()))) { - LOG_WARN("failed to create new ls", KR(ret), K(status_info), - K(recovery_stat)); - } - } else if (status_info.ls_is_created()) { - if (OB_FAIL(process_ls_status_after_created_(status_info, working_sw_status))) { - LOG_WARN("failed to create ls", KR(ret), K(status_info)); - } - } else if (status_info.ls_is_create_abort()) { - //drop ls - if (OB_FAIL(ls_operator_.delete_ls(status_info.ls_id_, machine.ls_info_, working_sw_status))) { - LOG_WARN("failed to remove ls not normal", KR(ret), K(machine)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("status machine not expected", KR(ret), K(machine)); - } - } else if (ls_is_normal_status(machine.ls_info_)) { - //the ls is normal - if (status_info.ls_is_normal()) { - //nothing - } else if (status_info.ls_is_created()) { - if (OB_FAIL(status_operator_.update_ls_status( - tenant_id, status_info.ls_id_, status_info.status_, - share::OB_LS_NORMAL, working_sw_status, *sql_proxy_))) { - LOG_WARN("failed to update ls status", KR(ret), K(status_info), K(tenant_id)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("status machine not expected", KR(ret), K(machine)); - } - } else if (ls_is_dropping_status(machine.ls_info_)) { - if (FAILEDx(do_drop_ls_(status_info, working_sw_status))) { - LOG_WARN("failed to drop ls", KR(ret), K(status_info)); - } - } else if (ls_is_pre_tenant_dropping_status(machine.ls_info_)) { - if (!machine.ls_id_.is_sys_ls()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("normal ls can not in pre tenant dropping status", KR(ret), K(machine)); - } else if (OB_FAIL(sys_ls_tenant_drop_(status_info, working_sw_status))) { - LOG_WARN("failed to process sys ls", KR(ret), K(status_info)); - } - } else if (ls_is_tenant_dropping_status(machine.ls_info_)) { - if (status_info.ls_is_wait_offline()) { - //sys ls will tenant_dropping and wait offline - } else if (OB_FAIL(do_tenant_drop_ls_(status_info, working_sw_status))) { - LOG_WARN("failed to drop ls", KR(ret), K(machine)); - } - } else { - //other status can not be in __all_ls - //such as created, wait_offline - ret = OB_ERR_UNEXPECTED; - LOG_WARN("the ls not expected in all_ls", KR(ret), K(machine)); - } - return ret; -} - -int ObTenantLSInfo::drop_tenant(const ObTenantSwitchoverStatus &working_sw_status) -{ - int ret = OB_SUCCESS; - share::ObLSAttrArray ls_array; - if (OB_FAIL(ls_operator_.get_all_ls_by_order(ls_array))) { - LOG_WARN("failed to get all ls", KR(ret)); - } else { - //1. set sys_ls to tenant_dropping in __all_ls - //2. set user_ls to tenant_dropping or abort in __all_ls - for (int64_t i = 0; OB_SUCC(ret) && i < ls_array.count(); ++i) { - share::ObLSAttr &attr = ls_array.at(i); - if (attr.get_ls_id().is_sys_ls()) { - if (attr.ls_is_normal()) { - if (OB_FAIL(ls_operator_.update_ls_status(attr.get_ls_id(), - attr.get_ls_status(), share::OB_LS_PRE_TENANT_DROPPING, working_sw_status))) { - LOG_WARN("failed to update ls status", KR(ret), K(attr)); - } - } - } else if (attr.ls_is_creating()) { - //drop the status - if (OB_FAIL(ls_operator_.delete_ls(attr.get_ls_id(), attr.get_ls_status(), working_sw_status))) { - LOG_WARN("failed to remove ls not normal", KR(ret), K(attr)); - } - } else { - //no matter the status is in normal or dropping - //may be the status in status info is created - if (!attr.ls_is_tenant_dropping()) { - if (OB_FAIL(ls_operator_.update_ls_status( - attr.get_ls_id(), attr.get_ls_status(), - share::OB_LS_TENANT_DROPPING, working_sw_status))) { - LOG_WARN("failed to update ls status", KR(ret), K(attr)); - } else { - LOG_INFO("[LS_MGR] set ls to tenant dropping", KR(ret), K(attr)); - } - } - } - }//end for - } - return ret; -} -int ObTenantLSInfo::gather_stat(bool for_recovery) -{ - int ret = OB_SUCCESS; - reset(); - if (OB_ISNULL(tenant_schema_) || OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected", KR(ret), KP(tenant_schema_), KP(sql_proxy_)); - } else { - ObUnitTableOperator unit_operator; - common::ObArray units; - const uint64_t tenant_id = tenant_schema_->get_tenant_id(); - if (OB_FAIL(unit_operator.init(*sql_proxy_))) { - LOG_WARN("failed to init unit operator", KR(ret)); - } else if (OB_FAIL(unit_operator.get_units_by_tenant( - tenant_id, units))) { - LOG_WARN("failed to get all tenant unit", KR(ret), K(tenant_id)); - } else { - ObUnitGroupInfo info; - for (int64_t j = 0; OB_SUCC(ret) && j < units.count(); ++j) { - info.reset(); - const ObUnit &unit = units.at(j); - if (OB_FAIL(info.init(unit.unit_group_id_, unit.status_))) { - LOG_WARN("failed to init unit info", KR(ret), K(unit)); - } else if (has_exist_in_array(unit_group_array_, info)) { - //nothing - } else if (OB_FAIL(unit_group_array_.push_back(info))) { - LOG_WARN("fail to push back", KR(ret), K(info)); - } - } - } - if (OB_SUCC(ret)) { - if (for_recovery) { - } else { - //get max ls id and max ls group id - share::ObMaxIdFetcher id_fetcher(*sql_proxy_); - if (OB_FAIL(id_fetcher.fetch_max_id(*sql_proxy_, tenant_id, - share::OB_MAX_USED_LS_GROUP_ID_TYPE, max_ls_group_id_))) { - LOG_WARN("failed to fetch max ls group id", KR(ret), K(tenant_id)); - } else if (OB_FAIL(id_fetcher.fetch_max_id(*sql_proxy_, tenant_id, - share::OB_MAX_USED_LS_ID_TYPE, max_ls_id_))) { - LOG_WARN("failed to fetch max ls id", KR(ret), K(tenant_id)); - } - } - } - if (FAILEDx(gather_all_ls_info_())) { - LOG_WARN("failed to get all ls info", KR(ret), K(tenant_id)); - } else if (OB_FAIL(ObPrimaryZoneUtil::get_tenant_primary_zone_array( - *tenant_schema_, primary_zone_))) { - LOG_WARN("failed to get tenant primary zone array", KR(ret), KPC(tenant_schema_)); - } else { - is_load_ = true; - } - } - LOG_INFO("[LS_MGR] gather stat", KR(ret), K(primary_zone_), K(unit_group_array_), - K(max_ls_id_), K(max_ls_group_id_)); - return ret; -} - -int ObTenantLSInfo::gather_all_ls_info_() -{ - int ret = OB_SUCCESS; - share::ObLSStatusInfoArray status_info_array; - if (OB_ISNULL(sql_proxy_) || OB_ISNULL(tenant_schema_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy or tenant schema is null", KR(ret), KP(tenant_schema_), KP(sql_proxy_)); - } else { - const uint64_t tenant_id = tenant_schema_->get_tenant_id(); - if (OB_FAIL(status_operator_.get_all_ls_status_by_order( - tenant_id, status_info_array, *sql_proxy_))) { - LOG_WARN("failed to update ls status", KR(ret), K(tenant_id)); - } - } - if (OB_FAIL(ret)) { - } else { - const int64_t count = max(1, hash::cal_next_prime(status_info_array.count())); - if (OB_FAIL(status_map_.create(count, "LogStrInfo", "LogStrInfo"))) { - LOG_WARN("failed to create ls map", KR(ret), K(count)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < status_info_array.count(); ++i) { - const share::ObLSStatusInfo &info = status_info_array.at(i); - if (info.ls_is_wait_offline()) { - //ls is already offline, no need to process - } else if (FAILEDx(add_ls_status_info_(info))) { - LOG_WARN("failed to add ls status info", KR(ret), K(i), K(info)); - } - }// end for - } - } - return ret; -} - -int ObTenantLSInfo::add_ls_to_ls_group_(const share::ObLSStatusInfo &info) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!info.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls status is invalid", KR(ret), K(info)); - } else { - int64_t group_index = OB_INVALID_INDEX_INT64; - for (int64_t j = 0; OB_SUCC(ret) && j < ls_group_array_.count(); - ++j) { - const ObLSGroupInfo &group = ls_group_array_.at(j); - if (info.ls_group_id_ == group.ls_group_id_) { - group_index = j; - break; - } - } - if (OB_SUCC(ret) && OB_INVALID_INDEX_INT64 == group_index) { - ObLSGroupInfo group; - group_index = ls_group_array_.count(); - if (OB_FAIL(group.init(info.unit_group_id_, info.ls_group_id_))) { - LOG_WARN("failed to init ls group", KR(ret), K(info)); - } else if (OB_FAIL(ls_group_array_.push_back(group))) { - LOG_WARN("failed to pushback group", KR(ret), K(group)); - } else if (OB_FAIL(add_ls_group_to_unit_group_(group))) { - LOG_WARN("failed to add ls group to unit group", KR(ret), K(group)); - } - } - if (OB_SUCC(ret)) { - if (OB_UNLIKELY(group_index >= ls_group_array_.count() - || OB_INVALID_INDEX_INT64 == group_index)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("group index is invalid", KR(ret), K(group_index), "count", - ls_group_array_.count()); - } else if (OB_FAIL(ls_group_array_.at(group_index) - .ls_ids_.push_back(info.ls_id_))) { - LOG_WARN("failed to push back ls id", KR(ret), K(group_index), - K(info)); - } - } - } - return ret; -} - -int ObTenantLSInfo::add_ls_group_to_unit_group_(const ObLSGroupInfo &group_info) -{ - int ret = OB_SUCCESS; - bool found = false; - if (OB_UNLIKELY(!group_info.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("group_info is invalid", KR(ret), K(group_info)); - } else { - found = false; - for (int64_t j = 0; OB_SUCC(ret) && j < unit_group_array_.count(); ++j) { - ObUnitGroupInfo &unit_info = unit_group_array_.at(j); - if (group_info.unit_group_id_ == unit_info.unit_group_id_) { - found = true; - if (OB_FAIL(unit_info.ls_group_ids_.push_back( - group_info.ls_group_id_))) { - LOG_WARN("failed to push back ls group id", KR(ret), - K(group_info), K(unit_info)); - } - } - } // end j - if (OB_SUCC(ret) && !found) { - //can found unit_group for a ls group - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to find unit group for ls group", KR(ret), - K(group_info), K(unit_group_array_)); - } - } - - return ret; -} - -int ObTenantLSInfo::check_unit_group_valid_( - const uint64_t unit_group_id, bool &is_valid_info) -{ - int ret = OB_SUCCESS; - is_valid_info = true; - if (OB_UNLIKELY(OB_INVALID_VERSION == unit_group_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls id is invalid", KR(ret), K(unit_group_id)); - } else if (OB_UNLIKELY(!is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant stat not valid", KR(ret)); - } else { - //check unit group status is valid - ret = OB_ENTRY_NOT_EXIST; - for (int64_t i = 0; OB_FAIL(ret) && i < unit_group_array_.count(); ++i) { - const ObUnitGroupInfo &group_info = unit_group_array_.at(i); - if (unit_group_id == group_info.unit_group_id_) { - ret = OB_SUCCESS; - if (share::ObUnit::UNIT_STATUS_ACTIVE != group_info.unit_status_) { - is_valid_info = false; - } - break; - } - }//end for - if (OB_FAIL(ret)) { - LOG_WARN("failed to found unit group status", KR(ret), K(unit_group_id), - K(unit_group_array_)); - } - } - return ret; -} - -//for standby -int ObTenantLSInfo::create_new_ls_for_recovery( - const share::ObLSID &ls_id, - const uint64_t ls_group_id, - const SCN &create_scn, - ObMySQLTransaction &trans, - const share::ObLSFlag &ls_flag) -{ - int ret = OB_SUCCESS; - const bool is_recovery = true; - int64_t info_index = OB_INVALID_INDEX_INT64; - if (OB_UNLIKELY(!ls_id.is_valid() - || OB_INVALID_ID == ls_group_id - || !create_scn.is_valid() - || !ls_flag.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls id is invalid", KR(ret), K(ls_id), K(ls_group_id), K(create_scn), K(ls_flag)); - } else if (OB_UNLIKELY(!is_valid()) - || OB_ISNULL(tenant_schema_) - || OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant stat not valid", KR(ret), KP(tenant_schema_), KP(sql_proxy_)); - } else { - const uint64_t tenant_id = tenant_schema_->get_tenant_id(); - share::ObLSStatusInfo new_info; - ObLSGroupInfo group_info; - ObZone primary_zone; - ObLSLifeAgentManager ls_life_agent(*sql_proxy_); - ObSqlString zone_priority; - if (OB_SUCC(get_ls_group_info( - ls_group_id, group_info))) { - // need a new primary zone - } else if (OB_ENTRY_NOT_EXIST == ret) { - // need a new unit group - ret = OB_SUCCESS; - int64_t unit_group_index = OB_INVALID_INDEX_INT64; - if (OB_FAIL(get_next_unit_group_(is_recovery, unit_group_index))) { - LOG_WARN("failed to get next unit group", KR(ret), K(is_recovery)); - } else if (OB_UNLIKELY(OB_INVALID_INDEX_INT64 == unit_group_index - || unit_group_index >= unit_group_array_.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to next unit group", KR(ret), K(unit_group_index)); - } else if (OB_FAIL(group_info.init( - unit_group_array_.at(unit_group_index).unit_group_id_, - ls_group_id))) { - LOG_WARN("failed to init group info", KR(ret), K(unit_group_index), K(ls_group_id)); - } - } else { - LOG_WARN("failed to get ls group info", KR(ret), - K(ls_group_id)); - } - - if (FAILEDx(get_next_primary_zone_(is_recovery, group_info, primary_zone))) { - LOG_WARN("failed to get next primary zone", KR(ret), K(group_info)); - } else if (OB_FAIL(new_info.init(tenant_id, ls_id, - ls_group_id, - share::OB_LS_CREATING, - ls_flag.is_duplicate_ls() ? 0 : group_info.unit_group_id_, - primary_zone, ls_flag))) { - LOG_WARN("failed to init new info", KR(ret), K(tenant_id), - K(ls_id), K(ls_group_id), K(group_info), K(primary_zone)); - } else if (OB_FAIL(get_zone_priority(primary_zone, *tenant_schema_, zone_priority))) { - LOG_WARN("failed to get normalize primary zone", KR(ret), K(primary_zone), K(zone_priority)); - } else if (OB_FAIL(ls_life_agent.create_new_ls_in_trans(new_info, create_scn, - zone_priority.string(), share::NORMAL_SWITCHOVER_STATUS, trans))) { - LOG_WARN("failed to insert ls info", KR(ret), K(new_info), K(create_scn), K(zone_priority)); - } else if (OB_FAIL(add_ls_status_info_(new_info))) { - LOG_WARN("failed to add new ls info to memory", KR(ret), K(new_info)); - } - } - return ret; -} - -int ObTenantLSInfo::process_ls_stats_for_recovery() -{ - int ret = OB_SUCCESS; - share::ObLSStatusInfoArray status_info_array; - ObLSRecoveryStat recovery_stat; - ObLSRecoveryStatOperator ls_recovery_operator; - if (OB_ISNULL(sql_proxy_) || OB_ISNULL(tenant_schema_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy or tenant schema is null", KR(ret), KP(tenant_schema_), KP(sql_proxy_)); - } else { - const uint64_t tenant_id = tenant_schema_->get_tenant_id(); - int tmp_ret = OB_SUCCESS; - if (OB_FAIL(status_operator_.get_all_ls_status_by_order( - tenant_id, status_info_array, *sql_proxy_))) { - LOG_WARN("failed to update ls status", KR(ret), K(tenant_id)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < status_info_array.count(); ++i) { - const ObLSStatusInfo &status_info = status_info_array.at(i); - recovery_stat.reset(); - if (status_info.ls_is_creating()) { - if (OB_FAIL(ls_recovery_operator.get_ls_recovery_stat(tenant_id, status_info.ls_id_, - false/*for_update*/, recovery_stat, *sql_proxy_))) { - LOG_WARN("failed to get ls recovery stat", KR(ret), K(tenant_id), K(status_info)); - } else if (OB_FAIL(do_create_ls_(status_info, recovery_stat.get_create_scn()))) { - LOG_WARN("failed to create new ls", KR(ret), K(status_info), - K(recovery_stat)); - } - } - }//end for - //adjust primary zone - if (OB_SUCCESS != (tmp_ret = adjust_user_tenant_primary_zone())) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to adjust user tenant primary zone", KR(ret), - KR(tmp_ret), K(tenant_schema_)); - } - } - return ret; -} - -int ObTenantLSInfo::add_ls_status_info_( - const share::ObLSStatusInfo &ls_info) -{ - int ret = OB_SUCCESS; - const int64_t index = status_array_.count(); - if (OB_UNLIKELY(!ls_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls info is invalid", KR(ret), K(ls_info)); - } else if (OB_FAIL(status_array_.push_back(ls_info))) { - LOG_WARN("failed to remove status", KR(ret), K(ls_info)); - } else if (OB_FAIL(status_map_.set_refactored(ls_info.ls_id_, index))) { - LOG_WARN("failed to remove ls from map", KR(ret), K(ls_info), K(index)); - } else if (ls_info.ls_id_.is_sys_ls() || ls_info.is_duplicate_ls()) { - //sys ls and duplicate ls have no ls group - } else if (OB_FAIL(add_ls_to_ls_group_(ls_info))) { - LOG_WARN("failed to add ls info", KR(ret), K(ls_info)); - } - return ret; -} - -int ObTenantLSInfo::get_ls_group_info( - const uint64_t ls_group_id, ObLSGroupInfo &info) const -{ - int ret = OB_SUCCESS; - info.reset(); - if (OB_UNLIKELY(OB_INVALID_ID == ls_group_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls group id is invalid", KR(ret), K(ls_group_id)); - } else if (OB_UNLIKELY(!is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant stat not valid", KR(ret)); - } else { - bool found = false; - for (int64_t i = 0; OB_SUCC(ret) && i < ls_group_array_.count(); ++i) { - const ObLSGroupInfo group_info = ls_group_array_.at(i); - if (ls_group_id == group_info.ls_group_id_) { - found = true; - if (OB_FAIL(info.assign(group_info))) { - LOG_WARN("failed to assign group info", KR(ret), K(group_info)); - } - break; - } - }//end for - if (OB_SUCC(ret) && !found) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("failed to find ls group info", KR(ret), - K(ls_group_id)); - } - } - return ret; -} - -int ObTenantLSInfo::get_ls_status_info( - const share::ObLSID &ls_id, - share::ObLSStatusInfo &info, - int64_t &info_index) const -{ - int ret = OB_SUCCESS; - info.reset(); - info_index = OB_INVALID_INDEX_INT64; - if (OB_UNLIKELY(!ls_id.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls id is invalid", KR(ret), K(ls_id)); - } else if (OB_UNLIKELY(!is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant stat not valid", KR(ret)); - } else if (OB_FAIL(status_map_.get_refactored(ls_id, info_index))) { - if (OB_HASH_NOT_EXIST == ret) { - ret = OB_ENTRY_NOT_EXIST; - } - LOG_WARN("failed to find ls index", KR(ret), K(ls_id)); - } else if (OB_UNLIKELY(info_index < 0 || info_index >= status_array_.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("info index not valid", KR(ret), K(info_index), K(ls_id), - "status_count", status_array_.count()); - } else if (OB_FAIL(info.assign(status_array_.at(info_index)))) { - LOG_WARN("failed to assign ls info", KR(ret), K(info_index), - "status", status_array_.at(info_index)); - } - return ret; -} - -int ObTenantLSInfo::get_next_unit_group_(const bool is_recovery, int64_t &group_index) -{ - int ret = OB_SUCCESS; - group_index = OB_INVALID_INDEX_INT64; - if (OB_UNLIKELY(!is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant stat not valid", KR(ret)); - } else { - int64_t ls_count = OB_INVALID_COUNT; - // Find the unit group with the least number of log streams - for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_array_.count(); ++i) { - const ObUnitGroupInfo &info = unit_group_array_.at(i); - const int64_t count = info.ls_group_ids_.count(); - if (share::ObUnit::UNIT_STATUS_ACTIVE == info.unit_status_) { - if (OB_INVALID_COUNT == ls_count || ls_count > count) { - ls_count = count; - group_index = i; - if (0 == count) { - //the first has no ls group unit group - break; - } - } - } - } - if (OB_SUCC(ret)) { - if (OB_INVALID_INDEX_INT64 == group_index - || (!is_recovery && 0 != ls_count)) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("failed to find next unit group", KR(ret), - K(unit_group_array_), K(is_recovery), K(ls_count)); - } - } - } - LOG_INFO("get next primary zone", KR(ret), K(group_index), K(is_recovery)); - return ret; -} - -int ObTenantLSInfo::get_next_primary_zone_( - const bool is_recovery, - const ObLSGroupInfo &group_info, - ObZone &primary_zone) -{ - int ret = OB_SUCCESS; - primary_zone.reset(); - if (OB_UNLIKELY(!group_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("group info is invalid", KR(ret), K(group_info)); - } else if (OB_UNLIKELY(!is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant ls info not valid", KR(ret)); - } else { - share::ObLSStatusInfo info; - int64_t ls_count = OB_INVALID_COUNT; - int64_t info_index = OB_INVALID_INDEX_INT64; - for (int64_t i = 0; OB_SUCC(ret) && i < primary_zone_.count(); ++i) { - const ObZone &zone = primary_zone_.at(i); - int64_t primary_zone_count = 0; - for (int64_t j = 0; OB_SUCC(ret) && j < group_info.ls_ids_.count(); ++j) { - const share::ObLSID &id = group_info.ls_ids_.at(j); - if (OB_FAIL(get_ls_status_info(id, info, info_index))) { - LOG_WARN("failed to find ls info", KR(ret), K(id), K(j)); - } else if (zone == info.primary_zone_) { - primary_zone_count++; - } - }//end for j - if (OB_SUCC(ret)) { - if (OB_INVALID_COUNT == ls_count || ls_count > primary_zone_count) { - ls_count = primary_zone_count; - if (OB_FAIL(primary_zone.assign(zone))) { - LOG_WARN("failed to assign zone", KR(ret), K(zone)); - } else if (0 == primary_zone_count) { - //the first zone has no primary zone - break; - } - } - } - }//end for i - if (OB_SUCC(ret)) { - if (primary_zone.is_empty() || (!is_recovery && 0 != ls_count)) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("failed to find next primary zone", KR(ret), K(primary_zone_), - K(group_info), K(is_recovery), K(ls_count)); - } - } - LOG_INFO("get next primary zone", KR(ret), K(group_info), K(primary_zone)); - } - return ret; -} - -//need create or delete new ls group -int ObTenantLSInfo::check_ls_group_match_unitnum() -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tenant stat not valid", KR(ret)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_array_.count(); ++i) { - const ObUnitGroupInfo &info = unit_group_array_.at(i); - if (share::ObUnit::UNIT_STATUS_MAX == info.unit_status_) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit status not valid", KR(ret), K(info)); - } else if (share::ObUnit::UNIT_STATUS_DELETING == info.unit_status_) { - // drop logstream, - if (0 == info.ls_group_ids_.count()) { - //nothing - } else if (OB_FAIL(try_drop_ls_of_deleting_unit_group_(info))) { - LOG_WARN("failed to drop ls of the unit group", KR(ret), K(info)); - } - } else if (0 == info.ls_group_ids_.count()) { - //create ls - if (OB_FAIL(create_new_ls_for_empty_unit_group_(info.unit_group_id_))) { - LOG_WARN("failed to create new ls for empty unit_group", KR(ret), - K(info)); - } - } - } - return ret; -} - -int ObTenantLSInfo::create_new_ls_for_empty_unit_group_(const uint64_t unit_group_id) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(OB_INVALID_INDEX_INT64 == unit_group_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("group id is invalid", KR(ret), K(unit_group_id)); - } else if (OB_UNLIKELY(!is_valid()) - || OB_ISNULL(tenant_schema_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant ls info not valid", KR(ret), KP(tenant_schema_)); - } else if (OB_UNLIKELY(0 == primary_zone_.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("primary zone is invalid", KR(ret)); - } else { - const uint64_t tenant_id = tenant_schema_->get_tenant_id(); - share::ObLSID new_id; - share::ObLSStatusInfo new_info; - uint64_t new_ls_group_id = OB_INVALID_INDEX_INT64; - share::ObLSFlag flag(share::ObLSFlag::NORMAL_FLAG); - if (OB_FAIL(fetch_new_ls_group_id(tenant_id, new_ls_group_id))) { - LOG_WARN("failed to fetch new id", KR(ret), K(tenant_id)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < primary_zone_.count(); ++i) { - const ObZone &zone = primary_zone_.at(i); - new_info.reset(); - if (OB_FAIL(fetch_new_ls_id(tenant_id, new_id))) { - LOG_WARN("failed to get new id", KR(ret), K(tenant_id)); - } else if (OB_FAIL(new_info.init(tenant_id, new_id, new_ls_group_id, - share::OB_LS_CREATING, unit_group_id, - zone, flag))) { - LOG_WARN("failed to init new info", KR(ret), K(new_id), - K(new_ls_group_id), K(unit_group_id), K(zone), K(tenant_id), K(flag)); - } else if (OB_FAIL(create_new_ls_(new_info, share::NORMAL_SWITCHOVER_STATUS))) { - LOG_WARN("failed to add ls info", KR(ret), K(new_info)); - } - LOG_INFO("[LS_MGR] create new ls for empty unit group", KR(ret), K(new_info)); - }//end for - } - return ret; -} - -int ObTenantLSInfo::try_drop_ls_of_deleting_unit_group_(const ObUnitGroupInfo &info) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(share::ObUnit::UNIT_STATUS_DELETING != info.unit_status_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("unit group status is invalid", KR(ret), K(info)); - } else if (OB_UNLIKELY(!is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant ls info not valid", KR(ret)); - } else { - ARRAY_FOREACH_X(info.ls_group_ids_, idx, cnt, OB_SUCC(ret)) { - ObLSGroupInfo ls_group_info; - const int64_t ls_group_id = info.ls_group_ids_.at(idx); - if (OB_FAIL(get_ls_group_info(ls_group_id, ls_group_info))) { - LOG_WARN("failed to get ls group info", KR(ret), K(idx), - K(ls_group_id)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < ls_group_info.ls_ids_.count(); ++i) { - const share::ObLSID &ls_id = ls_group_info.ls_ids_.at(i); - share::ObLSStatusInfo info; - int64_t info_index = 0; - if (OB_FAIL(get_ls_status_info(ls_id, info, info_index))) { - LOG_WARN("failed to get ls status info", KR(ret), K(ls_id)); - } else if (OB_FAIL(drop_ls_(info, share::NORMAL_SWITCHOVER_STATUS))) { - LOG_WARN("failed to drop ls", KR(ret), K(info)); - } - LOG_INFO("[LS_MGR] drop ls for deleting unit group", KR(ret), - K(ls_id), K(info)); - }//end for each ls in ls group info - } - }//end for each ls group in unit group info - } - return ret; -} - -int ObTenantLSInfo::drop_ls_(const share::ObLSStatusInfo &info, - const ObTenantSwitchoverStatus &working_sw_status) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tenant stat not valid", KR(ret)); - } else if (OB_UNLIKELY(!info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls info is invalid", KR(ret), K(info)); - } else if (info.ls_is_normal()) { - //try to set ls to dropping - if (OB_FAIL(ls_operator_.update_ls_status(info.ls_id_, - share::OB_LS_NORMAL, share::OB_LS_DROPPING, working_sw_status))) { - LOG_WARN("failed to update ls status", KR(ret), K(info)); - } - } else if (info.ls_is_created()) { - //if ls_status is created, the ls_info may creating or normal - //creating can not to dropping, so need retry after fix_status_machine. - ret = OB_NEED_RETRY; - LOG_WARN("not certain status in ls info, need retry", KR(ret), K(info)); - } else if (info.ls_is_dropping() - || info.ls_is_wait_offline()) { - //nothing - } else if (info.ls_is_creating()) { - //if status is in creating, the ls must in creating too - if (OB_FAIL(ls_operator_.delete_ls(info.ls_id_, share::OB_LS_CREATING, working_sw_status))) { - LOG_WARN("failed to process creating info", KR(ret), K(info)); - } - } else { - //other ls status not expected - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls status not expected for dropping ls", KR(ret), K(info)); - } - return ret; -} - -//need create or delete new ls -//TODO for primary cluster, The primary_zone of multiple LSs may be the same, -//the redundant ones need to be deleted, and only one is kept. -int ObTenantLSInfo::check_ls_match_primary_zone() -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_valid()) || OB_ISNULL(tenant_schema_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant ls info not valid", KR(ret), KP(tenant_schema_)); - } else { - const uint64_t tenant_id = tenant_schema_->get_tenant_id(); - ObZone zone; - share::ObLSID new_id; - share::ObLSStatusInfo new_info; - share::ObLSFlag flag(share::ObLSFlag::NORMAL_FLAG); - for (int64_t i = 0; OB_SUCC(ret) && i < ls_group_array_.count(); ++i) { - ObLSGroupInfo &group_info = ls_group_array_.at(i); - //check the unit group is active - //if unit group is in deleting, no need check primary zone - bool is_valid = false; - int64_t group_id_count = group_info.ls_ids_.count(); - if (OB_FAIL(check_unit_group_valid_(group_info.unit_group_id_, is_valid))) { - LOG_WARN("failed to check unit group valid", KR(ret), K(group_info)); - } - while (OB_SUCC(ret) && is_valid - && primary_zone_.count() > group_id_count) { - group_id_count++; - if (OB_FAIL(get_next_primary_zone_(false/*is_recovery*/, group_info, zone))) { - LOG_WARN("failed to get next primary zone", K(group_info)); - } else if (OB_FAIL(fetch_new_ls_id(tenant_id, new_id))) { - LOG_WARN("failed to get new id", KR(ret), K(tenant_id)); - } else if (OB_FAIL(new_info.init(tenant_id, new_id, group_info.ls_group_id_, - share::OB_LS_CREATING, - group_info.unit_group_id_, zone, flag))) { - LOG_WARN("failed to init new info", KR(ret), K(new_id), - K(group_info), K(zone), K(tenant_id), K(flag)); - } else if (OB_FAIL(create_new_ls_(new_info, share::NORMAL_SWITCHOVER_STATUS))) { - LOG_WARN("failed to create new ls", KR(ret), K(new_info)); - } - LOG_INFO("[LS_MGR] create new ls of primary zone", KR(ret), K(new_info), - K(group_id_count)); - } - } - } - return ret; -} - -int ObTenantLSInfo::get_zone_priority(const ObZone &primary_zone, - const share::schema::ObTenantSchema &tenant_schema, - ObSqlString &primary_zone_str) -{ - int ret = OB_SUCCESS; - primary_zone_str.reset(); - if (OB_UNLIKELY(!tenant_schema.is_valid() || primary_zone.is_empty())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(primary_zone), K(tenant_schema)); - } else if (OB_FAIL(ObPrimaryZoneUtil::get_ls_primary_zone_priority(primary_zone, - tenant_schema, primary_zone_str))) { - LOG_WARN("failed to get ls primary zone priority", KR(ret), K(primary_zone), K(tenant_schema)); - } - LOG_DEBUG("get zone priority", KR(ret), K(primary_zone_str), K(tenant_schema)); - return ret; -} - - -int ObTenantLSInfo::create_new_ls_(const share::ObLSStatusInfo &status_info, - const share::ObTenantSwitchoverStatus &working_sw_status) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tenant stat not valid", KR(ret)); - } else if (OB_UNLIKELY(!status_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls info is invalid", KR(ret), K(status_info)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else { - share::ObLSLifeAgentManager ls_life_agent(*sql_proxy_); - share::ObLSAttr ls_info; - share::ObLSFlag flag = status_info.get_flag(); - SCN create_scn; - ObSqlString zone_priority; - if (OB_FAIL(ObLSAttrOperator::get_tenant_gts(status_info.tenant_id_, create_scn))) { - LOG_WARN("failed to get tenant gts", KR(ret), K(status_info)); - } else if (OB_FAIL(ls_info.init(status_info.ls_id_, status_info.ls_group_id_, flag, - share::OB_LS_CREATING, share::OB_LS_OP_CREATE_PRE, create_scn))) { - LOG_WARN("failed to init new operation", KR(ret), K(status_info), K(create_scn)); - } else if (OB_FAIL(ls_operator_.insert_ls(ls_info, max_ls_group_id_, working_sw_status))) { - LOG_WARN("failed to insert new operation", KR(ret), K(ls_info), K(max_ls_group_id_)); - } else if (OB_FAIL(get_zone_priority(status_info.primary_zone_, - *tenant_schema_, zone_priority))) { - LOG_WARN("failed to get normalize primary zone", KR(ret), K(status_info), - K(zone_priority), K(tenant_schema_)); - } else if (OB_FAIL(ls_life_agent.create_new_ls(status_info, create_scn, - zone_priority.string(), working_sw_status))) { - LOG_WARN("failed to create new ls", KR(ret), K(status_info), K(create_scn), - K(zone_priority)); - } else if (OB_FAIL(do_create_ls_(status_info, create_scn))) { - LOG_WARN("failed to create ls", KR(ret), K(status_info), K(create_scn)); - } else if (OB_FAIL(process_ls_status_after_created_(status_info, working_sw_status))) { - LOG_WARN("failed to update ls status", KR(ret), K(status_info)); - } - LOG_INFO("[LS_MGR] create new ls", KR(ret), K(status_info)); - } - return ret; -} - -int ObTenantLSInfo::fetch_new_ls_group_id( - const uint64_t tenant_id, - uint64_t &ls_group_id) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tenant id is invalid", KR(ret), K(tenant_id)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else { - ls_group_id = OB_INVALID_ID; - share::ObMaxIdFetcher id_fetcher(*sql_proxy_); - if (OB_FAIL(id_fetcher.fetch_new_max_id( - tenant_id, share::OB_MAX_USED_LS_GROUP_ID_TYPE, ls_group_id))) { - LOG_WARN("fetch_max_id failed", KR(ret), K(tenant_id), "id_type", - share::OB_MAX_USED_LS_GROUP_ID_TYPE); - } else { - if (ls_group_id != ++max_ls_group_id_) { - ret = OB_EAGAIN; - LOG_WARN("ls may create concurrency, need retry", KR(ret), K(ls_group_id), - K(max_ls_group_id_)); - } - } - } - return ret; -} - -int ObTenantLSInfo::fetch_new_ls_id(const uint64_t tenant_id, share::ObLSID &id) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tenant id is invalid", KR(ret), K(tenant_id)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else { - share::ObMaxIdFetcher id_fetcher(*sql_proxy_); - uint64_t id_value = OB_INVALID_ID; - if (OB_FAIL(id_fetcher.fetch_new_max_id( - tenant_id, share::OB_MAX_USED_LS_ID_TYPE, id_value))) { - LOG_WARN("fetch_max_id failed", KR(ret), K(tenant_id), "id_type", - share::OB_MAX_USED_LS_ID_TYPE); - } else { - if (id_value != ++max_ls_id_) { - ret = OB_EAGAIN; - LOG_WARN("ls may create concurrency, need retry", KR(ret), K(id_value), - K(max_ls_id_)); - } else { - share::ObLSID new_id(id_value); - id = new_id; - } - } - } - return ret; -} - -int ObTenantLSInfo::create_ls_with_palf( - const share::ObLSStatusInfo &info, - const SCN &create_scn, - const bool create_ls_with_palf, - const palf::PalfBaseInfo &palf_base_info) -{ - int ret = OB_SUCCESS; - LOG_INFO("[LS_EXEC] start to create ls", K(info)); - const int64_t start_time = ObTimeUtility::fast_current_time(); - if (OB_UNLIKELY(!info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("info not valid", KR(ret), K(info)); - } else if (OB_ISNULL(rpc_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("rpc proxy is null", KR(ret)); - } else if (OB_UNLIKELY(!info.ls_is_created() && !info.ls_is_creating())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("info status not expected", KR(ret), K(info)); - } else if (info.ls_is_creating()) { - common::ObArray locality_array; - int64_t paxos_replica_num = 0; - ObSchemaGetterGuard guard;//nothing - if (OB_ISNULL(tenant_schema_)) { - ret = OB_TENANT_NOT_EXIST; - LOG_WARN("tenant not exist", KR(ret), K(info)); - } else if (tenant_schema_->is_dropping()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant is in dropping, no need create ls", KR(ret), K(tenant_schema_)); - } else if (OB_FAIL(tenant_schema_->get_zone_replica_attr_array( - locality_array))) { - LOG_WARN("failed to get zone locality array", KR(ret)); - } else if (OB_FAIL(tenant_schema_->get_paxos_replica_num( - guard, paxos_replica_num))) { - LOG_WARN("failed to get paxos replica num", KR(ret)); - } else { - ObLSCreator creator(*rpc_proxy_, info.tenant_id_, - info.ls_id_, sql_proxy_); - if (OB_FAIL(creator.create_user_ls(info, paxos_replica_num, - locality_array, create_scn, - tenant_schema_->get_compatibility_mode(), - create_ls_with_palf, - palf_base_info))) { - LOG_WARN("failed to create user ls", KR(ret), K(info), K(locality_array), K(create_scn), - K(palf_base_info), K(create_ls_with_palf)); - } - } - } - const int64_t cost = ObTimeUtility::fast_current_time() - start_time; - LOG_INFO("[LS_EXEC] end to create ls", KR(ret), K(info), K(cost)); - return ret; -} - -int ObTenantLSInfo::do_create_ls_(const share::ObLSStatusInfo &info, - const SCN &create_scn) -{ - int ret = OB_SUCCESS; - const int64_t start_time = ObTimeUtility::fast_current_time(); - if (OB_UNLIKELY(!info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("info not valid", KR(ret), K(info)); - } else { - palf::PalfBaseInfo palf_base_info; - if (OB_FAIL(create_ls_with_palf(info, create_scn, false, palf_base_info))) { - LOG_WARN("failed to create ls with palf", KR(ret), K(info), K(create_scn), K(palf_base_info)); - } - } - return ret; -} - -int ObTenantLSInfo::process_ls_status_after_created_(const share::ObLSStatusInfo &status_info, - const ObTenantSwitchoverStatus &working_sw_status) -{ - //do not check ls status - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!status_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("info not valid", KR(ret), K(status_info)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else if (OB_FAIL(ls_operator_.update_ls_status( - status_info.ls_id_, share::OB_LS_CREATING, share::OB_LS_NORMAL, working_sw_status))) { - LOG_WARN("failed to update ls status", KR(ret), K(status_info)); - } else if (OB_FAIL(status_operator_.update_ls_status( - status_info.tenant_id_, status_info.ls_id_, share::OB_LS_CREATED, - share::OB_LS_NORMAL, working_sw_status, *sql_proxy_))) { - LOG_WARN("failed to update ls status", KR(ret), K(status_info)); - } - return ret; -} - -int ObTenantLSInfo::do_tenant_drop_ls_(const share::ObLSStatusInfo &status_info, - const ObTenantSwitchoverStatus &working_sw_status) -{ - int ret = OB_SUCCESS; - LOG_INFO("[LS_EXEC] start to tenant drop ls", K(status_info)); - const int64_t start_time = ObTimeUtility::fast_current_time(); - bool can_offline = false; - if (OB_UNLIKELY(!status_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("info not valid", KR(ret), K(status_info)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else if (OB_UNLIKELY(status_info.ls_is_creating() || status_info.ls_is_wait_offline())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("status info not expected", KR(ret), K(status_info)); - } else if (!status_info.ls_is_tenant_dropping()) { - //status_info may in created, normal, dropping, tenant_dropping - if (OB_FAIL(status_operator_.update_ls_status( - status_info.tenant_id_, status_info.ls_id_, - status_info.status_, share::OB_LS_TENANT_DROPPING, working_sw_status, - *sql_proxy_))) { - LOG_WARN("failed to update ls status", KR(ret), K(status_info)); - } - } - if (FAILEDx(check_ls_can_offline_by_rpc_(status_info, share::OB_LS_TENANT_DROPPING, can_offline))) { - // send rpc to observer - LOG_WARN("failed to check ls can offline", KR(ret), K(status_info)); - } else if (can_offline) { - ObLSLifeAgentManager ls_life_agent(*sql_proxy_); - SCN drop_scn; - if (!status_info.ls_id_.is_sys_ls()) { - //sys ls cannot delete ls, after ls is in tenant dropping - if (OB_FAIL(ls_operator_.delete_ls(status_info.ls_id_, share::OB_LS_TENANT_DROPPING, - working_sw_status))) { - LOG_WARN("failed to delete ls", KR(ret), K(status_info)); - } else if (OB_FAIL(ObLSAttrOperator::get_tenant_gts(status_info.tenant_id_, drop_scn))) { - LOG_WARN("failed to get gts", KR(ret), K(status_info)); - } - } else { - //TODO sys ls can not get GTS after tenant_dropping - drop_scn.set_base(); - } - if (FAILEDx(ls_life_agent.set_ls_offline(status_info.tenant_id_, - status_info.ls_id_, status_info.status_, drop_scn, working_sw_status))) { - LOG_WARN("failed to update ls info", KR(ret), K(status_info), K(drop_scn)); - } - } - const int64_t cost = ObTimeUtility::fast_current_time() - start_time; - LOG_INFO("[LS_EXEC] end to tenant drop ls", KR(ret), K(status_info), K(cost)); - return ret; -} - -int ObTenantLSInfo::do_drop_ls_(const share::ObLSStatusInfo &status_info, - const ObTenantSwitchoverStatus &working_sw_status) -{ - int ret = OB_SUCCESS; - LOG_INFO("[LS_EXEC] start to drop ls", K(status_info)); - const int64_t start_time = ObTimeUtility::fast_current_time(); - bool tablet_empty = false; - if (OB_UNLIKELY(!status_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("info not valid", KR(ret), K(status_info)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else if (status_info.ls_is_normal()) { - if (OB_FAIL(status_operator_.update_ls_status( - status_info.tenant_id_, status_info.ls_id_, - status_info.status_, share::OB_LS_DROPPING, - working_sw_status, - *sql_proxy_))) { - LOG_WARN("failed to update ls status", KR(ret), K(status_info)); - } - } else if (status_info.ls_is_dropping()) { - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("status not expected", KR(ret), K(status_info)); - } - if (FAILEDx(check_ls_empty_(status_info, tablet_empty))) { - LOG_WARN("failed to check ls empty", KR(ret), K(status_info)); - } - if (OB_SUCC(ret) && tablet_empty) { - // send rpc to observer - bool can_offline = false; - if (OB_FAIL(check_ls_can_offline_by_rpc_(status_info, share::OB_LS_DROPPING, can_offline))) { - LOG_WARN("failed to check ls can offline", KR(ret), K(status_info)); - } else if (can_offline) { - ObLSLifeAgentManager ls_life_agent(*sql_proxy_); - SCN drop_scn; - if (OB_FAIL(ls_operator_.delete_ls(status_info.ls_id_, share::OB_LS_DROPPING, - working_sw_status))) { - LOG_WARN("failed to delete ls", KR(ret), K(status_info)); - } else if (OB_FAIL(ObLSAttrOperator::get_tenant_gts(status_info.tenant_id_, drop_scn))) { - LOG_WARN("failed to get gts", KR(ret), K(status_info)); - } else if (OB_FAIL(ls_life_agent.set_ls_offline(status_info.tenant_id_, - status_info.ls_id_, status_info.status_, drop_scn, working_sw_status))) { - LOG_WARN("failed to update ls info", KR(ret), K(status_info), K(drop_scn)); - } - } - } - const int64_t cost = ObTimeUtility::fast_current_time() - start_time; - LOG_INFO("[LS_EXEC] end to drop ls", KR(ret), K(status_info), K(cost), K(tablet_empty)); - return ret; -} - - -int ObTenantLSInfo::sys_ls_tenant_drop_(const share::ObLSStatusInfo &info, - const share::ObTenantSwitchoverStatus &working_sw_status) -{ - int ret = OB_SUCCESS; - const ObLSStatus target_status = share::OB_LS_TENANT_DROPPING; - const ObLSStatus pre_status = share::OB_LS_PRE_TENANT_DROPPING; - if (OB_UNLIKELY(!info.is_valid() - || !info.ls_id_.is_sys_ls())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(info)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); - } else if (info.ls_is_normal()) { - if (OB_FAIL(status_operator_.update_ls_status(info.tenant_id_, - info.ls_id_, info.status_, pre_status, working_sw_status, - *sql_proxy_))) { - LOG_WARN("failed to update ls status", KR(ret), K(info), K(pre_status)); - } - } else if (pre_status == info.status_) { - //nothing - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sys ls can not in other status", KR(ret), K(info)); - } - bool can_offline = false; - if (FAILEDx(check_sys_ls_can_offline_(can_offline))) { - LOG_WARN("failed to check sys ls can offline", KR(ret)); - } else if (can_offline) { - if (OB_FAIL(ls_operator_.update_ls_status(info.ls_id_, pre_status, target_status, - working_sw_status))) { - LOG_WARN("failed to update ls status", KR(ret), K(info), K(pre_status), K(target_status)); - } else if (OB_FAIL(status_operator_.update_ls_status(info.tenant_id_, - info.ls_id_, pre_status, target_status, working_sw_status, *sql_proxy_))) { - LOG_WARN("failed to update ls status", KR(ret), K(info), K(pre_status), K(target_status)); - } - } - return ret; -} - -int ObTenantLSInfo::check_sys_ls_can_offline_(bool &can_offline) -{ - int ret = OB_SUCCESS; - share::ObLSStatusInfoArray status_info_array; - can_offline = true; - if (OB_ISNULL(sql_proxy_) || OB_ISNULL(tenant_schema_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy or tenant schema is null", KR(ret), KP(tenant_schema_), KP(sql_proxy_)); - } else { - const uint64_t tenant_id = tenant_schema_->get_tenant_id(); - if (OB_FAIL(status_operator_.get_all_ls_status_by_order( - tenant_id, status_info_array, *sql_proxy_))) { - LOG_WARN("failed to update ls status", KR(ret), K(tenant_id)); - } else if (0 == status_info_array.count()) { - //if has multi ls_mgr - can_offline = true; - } - for (int64_t i = 0; OB_SUCC(ret) && i < status_info_array.count() && can_offline; ++i) { - const share::ObLSStatusInfo &status_info = status_info_array.at(i); - if (status_info.ls_id_.is_sys_ls()) { - } else if (status_info.ls_is_wait_offline()) { - //nothing - } else { - can_offline = false; - LOG_INFO("[LS_MGR] sys ls can not offline", K(status_info)); - break; - } - } - if (OB_SUCC(ret) && can_offline) { - LOG_INFO("[LS_MGR] sys ls can offline", K(status_info_array)); - } - } - return ret; -} - -int ObTenantLSInfo::check_ls_empty_(const share::ObLSStatusInfo &info, bool &empty) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("info not valid", KR(ret), K(info)); - } else { - ObSqlString sql; - if (OB_FAIL(sql.assign_fmt( - "SELECT * FROM %s where ls_id = %ld", - OB_ALL_TABLET_TO_LS_TNAME, info.ls_id_.id()))) { - LOG_WARN("failed to assign sql", KR(ret), K(sql)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else { - HEAP_VAR(ObMySQLProxy::MySQLResult, res) { - common::sqlclient::ObMySQLResult *result = NULL; - if (OB_FAIL(sql_proxy_->read(res, info.tenant_id_, sql.ptr()))) { - LOG_WARN("failed to read", KR(ret), K(info), K(sql)); - } else if (OB_ISNULL(result = res.get_result())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get sql result", KR(ret)); - } else if (OB_SUCC(result->next())) { - empty = false; - } else if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - empty = true; - } else { - LOG_WARN("failed to get next", KR(ret), K(sql)); - } - } - } - } - return ret; -} - -int ObTenantLSInfo::check_ls_can_offline_by_rpc_(const share::ObLSStatusInfo &info, - const share::ObLSStatus ¤t_ls_status, bool &can_offline) -{ - int ret = OB_SUCCESS; - share::ObLSInfo ls_info; - const share::ObLSReplica *replica = NULL; - if (OB_UNLIKELY(!info.is_valid() - || !ls_is_tenant_dropping_status(current_ls_status) && ! ls_is_dropping_status(current_ls_status))) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("info not valid", KR(ret), K(info), K(current_ls_status)); - } else if (OB_ISNULL(lst_operator_) || OB_ISNULL(rpc_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("lst operator or proxy is null", KR(ret), KP(lst_operator_), - KP(rpc_proxy_)); - } else if (OB_FAIL(lst_operator_->get(GCONF.cluster_id, info.tenant_id_, - info.ls_id_, share::ObLSTable::DEFAULT_MODE, ls_info))) { - LOG_WARN("failed to get ls info", KR(ret), K(info)); - } else if (OB_FAIL(ls_info.find_leader(replica))) { - LOG_WARN("failed to find leader", KR(ret), K(ls_info)); - } else if (OB_ISNULL(replica)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("replica is null", KR(ret), K(ls_info)); - } else { - const int64_t timeout = GCONF.rpc_timeout; - obrpc::ObCheckLSCanOfflineArg arg; - if (OB_FAIL(arg.init(info.tenant_id_, info.ls_id_, current_ls_status))) { - LOG_WARN("failed to init arg", KR(ret), K(info), K(current_ls_status)); - } else if (OB_FAIL(rpc_proxy_->to(replica->get_server()) - .by(info.tenant_id_) - .timeout(timeout) - .check_ls_can_offline(arg))) { - can_offline = false; - LOG_WARN("failed to check ls can offline", KR(ret), K(arg), K(info), - K(timeout), K(replica)); - } else { - can_offline = true; - } - } - return ret; -} -int ObTenantLSInfo::adjust_user_tenant_primary_zone() -{ - int ret = OB_SUCCESS; - share::ObLSStatusOperator status_op; - share::ObLSPrimaryZoneInfoArray info_array; - ObArray primary_zone; - if (OB_ISNULL(sql_proxy_) || OB_ISNULL(tenant_schema_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error", KR(ret), KP(sql_proxy_), KP(tenant_schema_)); - } else if (OB_FAIL(ObPrimaryZoneUtil::get_tenant_primary_zone_array( - *tenant_schema_, primary_zone))) { - LOG_WARN("failed to get tenant primary zone array", KR(ret), KPC(tenant_schema_)); - } else { - const uint64_t tenant_id = tenant_schema_->get_tenant_id(); - if (OB_FAIL(status_op.get_tenant_primary_zone_info_array( - tenant_id, info_array, *sql_proxy_))) { - LOG_WARN("failed to get tenant primary zone info array", KR(ret), K(tenant_id)); - } - } - - if (OB_SUCC(ret)) { - uint64_t last_ls_group_id = OB_INVALID_ID; - share::ObLSPrimaryZoneInfoArray tmp_info_array; - for (int64_t i = 0; OB_SUCC(ret) && i < info_array.count(); ++i) { - const ObLSPrimaryZoneInfo &info = info_array.at(i); - if (OB_INVALID_ID == last_ls_group_id) { - last_ls_group_id = info.get_ls_group_id(); - } - if (last_ls_group_id != info.get_ls_group_id()) { - //process the ls group - if (OB_FAIL(adjust_primary_zone_by_ls_group_(primary_zone, tmp_info_array, *tenant_schema_))) { - LOG_WARN("failed to update primary zone of each ls group", KR(ret), - K(tmp_info_array), K(primary_zone), KPC(tenant_schema_)); - } else { - tmp_info_array.reset(); - last_ls_group_id = info.get_ls_group_id(); - } - } - if (FAILEDx(tmp_info_array.push_back(info))) { - LOG_WARN("failed to push back primary info array", KR(ret), K(i)); - } - } - if (OB_SUCC(ret) && 0 < tmp_info_array.count()) { - if (OB_FAIL(adjust_primary_zone_by_ls_group_(primary_zone, tmp_info_array, *tenant_schema_))) { - LOG_WARN("failed to update primary zone of each ls group", KR(ret), - K(tmp_info_array), K(primary_zone), KPC(tenant_schema_)); - } - } - } - - return ret; -} - - -int ObTenantLSInfo::try_update_ls_primary_zone_( - const share::ObLSPrimaryZoneInfo &primary_zone_info, - const common::ObZone &new_primary_zone, - const common::ObSqlString &zone_priority) -{ - int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - if (OB_UNLIKELY(!primary_zone_info.is_valid() - || new_primary_zone.is_empty() || zone_priority.empty())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("primary zone info is invalid", KR(ret), K(primary_zone_info), - K(new_primary_zone), K(zone_priority)); - } else if (OB_ISNULL(GCTX.sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else if (new_primary_zone != primary_zone_info.get_primary_zone() - || zone_priority.string() != primary_zone_info.get_zone_priority_str()) { - ObLSLifeAgentManager ls_life_agent(*GCTX.sql_proxy_); - ObLSInfo ls_info; - const uint64_t tenant_id = primary_zone_info.get_tenant_id(); - const ObLSID ls_id = primary_zone_info.get_ls_id(); - if (OB_FAIL(ls_life_agent.update_ls_primary_zone(tenant_id, ls_id, - new_primary_zone, zone_priority.string()))) { - LOG_WARN("failed to update ls primary zone", KR(ret), K(primary_zone_info), - K(new_primary_zone), K(zone_priority)); - } else if (OB_ISNULL(GCTX.lst_operator_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("GCTX.lst_operator_ is NULL", KR(ret)); - } else if (OB_FAIL(GCTX.lst_operator_->get(GCONF.cluster_id, - tenant_id, ls_id, share::ObLSTable::DEFAULT_MODE, ls_info))) { - LOG_WARN("get ls info from GCTX.lst_operator_ failed", KR(ret), K(tenant_id), K(ls_id)); - } else if (OB_TMP_FAIL(ObRootUtils::try_notify_switch_ls_leader(GCTX.srv_rpc_proxy_, ls_info, - obrpc::ObNotifySwitchLeaderArg::MODIFY_PRIMARY_ZONE))) { - LOG_WARN("failed to switch ls leader", KR(ret), KR(tmp_ret), K(ls_id), K(ls_info)); - } - LOG_INFO("[LS_MGR] update ls primary zone", KR(ret), K(new_primary_zone), - K(zone_priority), K(primary_zone_info)); - } else { - //no need update - } - return ret; -} - -//check every ls has right primary zone in ls group -//if primary_zone of ls not in primary zone, try to choose a right zone, -//if can not find a zone to modify, modify the ls to exist zone, -//load_balancer will choose the right ls to drop -//eg: -//if ls group has z1, z2 and primary zone is : z1. need modify z2 to z1 -//if ls group has z1, z2 and primary zone is : z1, z3. modify z2 to z3; -int ObTenantLSInfo::adjust_primary_zone_by_ls_group_( - const common::ObIArray &primary_zone_array, - const share::ObLSPrimaryZoneInfoArray &primary_zone_infos, - const share::schema::ObTenantSchema &tenant_schema) -{ - int ret = OB_SUCCESS; - const uint64_t tenant_id = tenant_schema.get_tenant_id(); - const int64_t ls_count = primary_zone_infos.count(); - const int64_t primary_zone_count = primary_zone_array.count(); - if (OB_UNLIKELY(0 == primary_zone_count - || 0 == ls_count || !tenant_schema.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(primary_zone_infos), - K(primary_zone_array), K(tenant_schema)); - } else if (OB_ISNULL(GCTX.sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else if (1 == ls_count - && primary_zone_infos.at(0).get_ls_id().is_sys_ls()) { - //user sys ls is equal to meta sys ls - share::ObLSStatusOperator status_op; - share::ObLSPrimaryZoneInfo meta_primary_zone; - const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id); - if (OB_FAIL(status_op.get_ls_primary_zone_info(meta_tenant_id, - SYS_LS, meta_primary_zone, *GCTX.sql_proxy_))) { - LOG_WARN("failed to get ls primary_zone info", KR(ret), K(meta_tenant_id)); - } else if (OB_FAIL(try_update_ls_primary_zone_(primary_zone_infos.at(0), - meta_primary_zone.get_primary_zone(), meta_primary_zone.get_zone_priority()))) { - LOG_WARN("failed to update primary zone", KR(ret), K(primary_zone_infos), K(meta_primary_zone)); - } - } else { - //Algorithm Description: - //Assumption: We have 5 ls, 3 primary_zones(z1, z2, z3). - //1. Set the primary zone of ls to tenant's primary zone, - //choose the least number of log streams on the zone is selected for all zones - //2. After all the primary_zone of the ls are in the primary_zonw of the tenant, - //choose the primary_zone with the most and least ls. Adjust a certain number of ls to the smallest zone without exceeding the balance - //while guaranteeing that the number of the zone with the most is no less than the average. - ObArray ls_primary_zone;//is match with primary_zone_infos - ObSEArray count_group_by_zone;//ls count of each primary zone - ObSqlString new_zone_priority; - if (OB_FAIL(set_ls_to_primary_zone(primary_zone_array, primary_zone_infos, ls_primary_zone, - count_group_by_zone))) { - LOG_WARN("failed to set ls to primary zone", KR(ret), K(primary_zone_array), K(primary_zone_infos)); - } else if (OB_FAIL(balance_ls_primary_zone(primary_zone_array, ls_primary_zone, count_group_by_zone))) { - LOG_WARN("failed to balance ls primary zone", KR(ret), K(ls_primary_zone), K(count_group_by_zone)); - } - - for (int64_t i = 0; OB_SUCC(ret) && i < ls_count; ++i) { - const ObZone &new_primary_zone = ls_primary_zone.at(i); - if (OB_FAIL(ObTenantLSInfo::get_zone_priority(new_primary_zone, tenant_schema, new_zone_priority))) { - LOG_WARN("failed to get normalize primary zone", KR(ret), K(new_primary_zone)); - } - if (FAILEDx(try_update_ls_primary_zone_(primary_zone_infos.at(i), new_primary_zone, new_zone_priority))) { - LOG_WARN("failed to update ls primary zone", KR(ret), "primary_zone_info", primary_zone_infos.at(i), - K(new_primary_zone), K(new_zone_priority)); - } - } - } - return ret; -} - -int ObTenantLSInfo::set_ls_to_primary_zone( - const common::ObIArray &primary_zone_array, - const share::ObLSPrimaryZoneInfoArray &primary_zone_infos, - common::ObIArray &ls_primary_zone, - common::ObIArray &count_group_by_zone) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(0 == primary_zone_array.count() - || 0 == primary_zone_infos.count())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(primary_zone_array), K(primary_zone_infos)); - } else { - const int64_t primary_zone_count = primary_zone_array.count(); - const int64_t ls_count = primary_zone_infos.count(); - //ls may not in primary zone, record the index of primary_zone_infos not in primary zone - ObSEArray index_not_primary_zone; - int64_t index = 0; - ARRAY_FOREACH_X(primary_zone_array, idx, cnt, OB_SUCC(ret)) { - if (OB_FAIL(count_group_by_zone.push_back(0))) { - LOG_WARN("failed to push back", KR(ret), K(idx)); - } - } - for (int64_t i = 0; OB_SUCC(ret) && i < ls_count; ++i) { - const ObZone ¤t_zone = primary_zone_infos.at(i).get_primary_zone(); - if (has_exist_in_array(primary_zone_array, current_zone, &index)) { - count_group_by_zone.at(index)++; - } else if (OB_FAIL(index_not_primary_zone.push_back(i))) { - LOG_WARN("failed to push back", KR(ret), K(i), K(current_zone)); - } - if (FAILEDx(ls_primary_zone.push_back(current_zone))) { - LOG_WARN("failed to push back current zone", KR(ret), K(i), K(current_zone)); - } - } - //1. take all ls primary zone to tenant primary zone, choose the less primary zone count - int64_t min_count = INT64_MAX; - int64_t min_index = 0; - for (int64_t i = 0; OB_SUCC(ret) && i < index_not_primary_zone.count(); ++i) { - const int64_t ls_index = index_not_primary_zone.at(i); - min_count = INT64_MAX; - ARRAY_FOREACH_X(primary_zone_array, idx, cnt, OB_SUCC(ret)) { - if (min_count > count_group_by_zone.at(idx)) { - min_count = count_group_by_zone.at(idx); - min_index = idx; - } - }//end for search min count - if (OB_FAIL(ret)) { - } else if (min_index >= primary_zone_count) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to found min count", KR(ret), K(min_index), K(primary_zone_array)); - } else if (OB_FAIL(ls_primary_zone.at(ls_index).assign(primary_zone_array.at(min_index)))) { - LOG_WARN("failed to assign primary zone", KR(ret), K(min_index), K(min_count), K(ls_index)); - } else { - count_group_by_zone.at(min_index)++; - } - } - } - return ret; - -} - -int ObTenantLSInfo::balance_ls_primary_zone( - const common::ObIArray &primary_zone_array, - common::ObIArray &ls_primary_zone, - common::ObIArray &count_group_by_zone) -{ - int ret = OB_SUCCESS; - const int64_t ls_count = ls_primary_zone.count(); - const int64_t primary_zone_count = count_group_by_zone.count(); - if (OB_UNLIKELY(0 == primary_zone_count - || 0 == ls_count - || primary_zone_count != primary_zone_array.count())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(count_group_by_zone), K(ls_primary_zone)); - } else { - int64_t max_count = -1, max_index = 0; - int64_t min_count = INT64_MAX, min_index = 0; - do { - max_count = -1, max_index = 0; - min_count = INT64_MAX, min_index = 0; - for (int64_t i = 0; OB_SUCC(ret) && i < primary_zone_count; ++i) { - const int64_t ls_count = count_group_by_zone.at(i); - if (min_count > ls_count) { - min_count = ls_count; - min_index = i; - } - if (max_count < ls_count) { - max_count = ls_count; - max_index = i; - } - }//end for find min and max count - if (OB_UNLIKELY(max_index >= primary_zone_count || min_index >= primary_zone_count - || -1 == max_count || INT64_MAX == min_count)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get primary zone", KR(ret), K(max_index), K(min_index), - K(min_count), K(max_count), - K(primary_zone_array), K(primary_zone_count), K(ls_primary_zone)); - } else if (max_count - min_count > 1) { - //choose the max count to min count - for (int64_t i = 0; OB_SUCC(ret) && i < ls_count; ++i) { - if (ls_primary_zone.at(i) == primary_zone_array.at(max_index)) { - if (OB_FAIL(ls_primary_zone.at(i).assign(primary_zone_array.at(min_index)))) { - LOG_WARN("failed to push back ls primary zone", KR(ret), K(min_index)); - } else { - count_group_by_zone.at(max_index)--; - count_group_by_zone.at(min_index)++; - } - break; - } - } - } - } while (max_count - min_count > 1); - } - return ret; -} - -int ObTenantLSInfo::create_duplicate_ls() -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_valid()) || OB_ISNULL(tenant_schema_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant ls info not valid", KR(ret), KP(tenant_schema_)); - } else if (OB_UNLIKELY(0 == primary_zone_.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("primary zone is invalid", KR(ret)); - } else { - const uint64_t tenant_id = tenant_schema_->get_tenant_id(); - const ObZone &zone = primary_zone_.at(0); - share::ObLSID new_id; - share::ObLSStatusInfo new_info; - ObLSFlag flag(ObLSFlag::DUPLICATE_FLAG); - if (OB_FAIL(fetch_new_ls_id(tenant_id, new_id))) { - LOG_WARN("failed to get new id", KR(ret), K(tenant_id)); - } else if (OB_FAIL(new_info.init(tenant_id, new_id, 0/*ls_group_id*/, share::OB_LS_CREATING, - 0/*unit_group_id*/, zone, flag))) { - LOG_WARN("failed to init new info", KR(ret), K(new_id), K(zone), K(tenant_id), K(flag)); - } else if (OB_FAIL(create_new_ls_(new_info, share::NORMAL_SWITCHOVER_STATUS))) { - LOG_WARN("failed to create duplicate ls", KR(ret), K(new_info)); - } - LOG_INFO("[LS_MGR] create duplicate ls", KR(ret), K(new_info)); - } - return ret; -} -//////////////ObTenantThreadHelper -int ObTenantThreadHelper::create( - const char* thread_name, int tg_def_id, ObTenantThreadHelper &tenant_thread) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(is_created_)) { - ret = OB_INIT_TWICE; - LOG_WARN("has inited", KR(ret)); - } else if (OB_ISNULL(thread_name)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("thread name is null", KR(ret)); - } else if (OB_FAIL(TG_CREATE_TENANT(tg_def_id, tg_id_))) { - LOG_ERROR("create tg failed", KR(ret)); - } else if (OB_FAIL(TG_SET_RUNNABLE(tg_id_, *this))) { - LOG_ERROR("set thread runable fail", KR(ret)); - } else if (OB_FAIL(thread_cond_.init(ObWaitEventIds::REENTRANT_THREAD_COND_WAIT))) { - LOG_WARN("fail to init cond, ", KR(ret)); - } else { - thread_name_ = thread_name; - is_created_ = true; - is_first_time_to_start_ = true; - } - return ret; -} - -int ObTenantThreadHelper::start() -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_created_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init", KR(ret)); - } else if (is_first_time_to_start_) { - if (OB_FAIL(TG_START(tg_id_))) { - LOG_WARN("fail ed to start at first time", KR(ret), K(tg_id_), K(thread_name_)); - } else { - is_first_time_to_start_ = false; - } - } else if (OB_FAIL(TG_REENTRANT_LOGICAL_START(tg_id_))) { - LOG_WARN("failed to start", KR(ret)); - } - LOG_INFO("[TENANT THREAD] thread start", KR(ret), K(tg_id_), K(thread_name_)); - return ret; -} - -void ObTenantThreadHelper::stop() -{ - LOG_INFO("[TENANT THREAD] thread stop start", K(tg_id_), K(thread_name_)); - if (-1 != tg_id_) { - TG_REENTRANT_LOGICAL_STOP(tg_id_); - } - LOG_INFO("[TENANT THREAD] thread stop finish", K(tg_id_), K(thread_name_)); -} - -void ObTenantThreadHelper::wait() -{ - LOG_INFO("[TENANT THREAD] thread wait start", K(tg_id_), K(thread_name_)); - if (-1 != tg_id_) { - TG_REENTRANT_LOGICAL_WAIT(tg_id_); - } - LOG_INFO("[TENANT THREAD] thread wait finish", K(tg_id_), K(thread_name_)); -} - -void ObTenantThreadHelper::mtl_thread_stop() -{ - LOG_INFO("[TENANT THREAD] thread stop start", K(tg_id_), K(thread_name_)); - if (-1 != tg_id_) { - TG_STOP(tg_id_); - } - LOG_INFO("[TENANT THREAD] thread stop finish", K(tg_id_), K(thread_name_)); -} - -void ObTenantThreadHelper::mtl_thread_wait() -{ - LOG_INFO("[TENANT THREAD] thread wait start", K(tg_id_), K(thread_name_)); - if (-1 != tg_id_) { - { - ObThreadCondGuard guard(thread_cond_); - thread_cond_.broadcast(); - } - TG_WAIT(tg_id_); - is_first_time_to_start_ = true; - } - LOG_INFO("[TENANT THREAD] thread wait finish", K(tg_id_), K(thread_name_)); -} - -void ObTenantThreadHelper::destroy() -{ - LOG_INFO("[TENANT THREAD] thread destory start", K(tg_id_), K(thread_name_)); - if (-1 != tg_id_) { - TG_STOP(tg_id_); - { - ObThreadCondGuard guard(thread_cond_); - thread_cond_.broadcast(); - } - TG_WAIT(tg_id_); - TG_DESTROY(tg_id_); - tg_id_ = -1; - } - is_created_ = false; - is_first_time_to_start_ = true; - LOG_INFO("[TENANT THREAD] thread destory finish", K(tg_id_), K(thread_name_)); -} - -void ObTenantThreadHelper::switch_to_follower_forcedly() -{ - stop(); -} -int ObTenantThreadHelper::switch_to_leader() -{ - int ret = OB_SUCCESS; - LOG_INFO("[TENANT THREAD] thread start", K(tg_id_), K(thread_name_)); - if (OB_FAIL(start())) { - LOG_WARN("failed to start thread", KR(ret)); - } else { - ObThreadCondGuard guard(thread_cond_); - if (OB_FAIL(thread_cond_.broadcast())) { - LOG_WARN("failed to weakup thread cond", KR(ret)); - } - } - LOG_INFO("[TENANT THREAD] thread start finish", K(tg_id_), K(thread_name_)); - return ret; -} -void ObTenantThreadHelper::run1() -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_created_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else { - lib::set_thread_name(thread_name_); - LOG_INFO("thread run", K(thread_name_)); - do_work(); - } -} -void ObTenantThreadHelper::idle(const int64_t idle_time_us) -{ - ObThreadCondGuard guard(thread_cond_); - thread_cond_.wait_us(idle_time_us); -} //////////////ObPrimaryLSService int ObPrimaryLSService::init() @@ -2131,141 +66,45 @@ void ObPrimaryLSService::do_work() if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(wait_tenant_schema_and_version_ready_(tenant_id_, DATA_VERSION_4_1_0_0))) { + LOG_WARN("failed to wait tenant schema version ready", KR(ret), K(tenant_id_), K(DATA_CURRENT_VERSION)); } else { int64_t idle_time_us = 1000 * 1000L; int tmp_ret = OB_SUCCESS; - ObAllTenantInfo tenant_info; + share::schema::ObTenantSchema tenant_schema; while (!has_set_stop()) { - idle_time_us = 1000 * 1000L; - { - ObCurTraceId::init(GCONF.self_addr_); - share::schema::ObSchemaGetterGuard schema_guard; - const share::schema::ObTenantSchema *tenant_schema = NULL; - if (OB_ISNULL(GCTX.schema_service_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error", KR(ret)); - } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( - OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("fail to get schema guard", KR(ret)); - } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id_, tenant_schema))) { - LOG_WARN("failed to get tenant ids", KR(ret), K(tenant_id_)); - } else if (OB_ISNULL(tenant_schema)) { - ret = OB_TENANT_NOT_EXIST; - LOG_WARN("tenant not exist", KR(ret), K(tenant_id_)); - } else if (!is_user_tenant(tenant_id_)) { - if (OB_SUCCESS != (tmp_ret = process_meta_tenant_(*tenant_schema))) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to process tenant", KR(ret), KR(tmp_ret), K(tenant_id_)); - } - //drop tenant, no need process sys tenant, ignore failuer - if (!is_sys_tenant(tenant_id_)) { - const uint64_t user_tenant_id = gen_user_tenant_id(tenant_id_); - if (OB_SUCCESS != (tmp_ret = try_force_drop_tenant_(user_tenant_id))) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to drop tenant", KR(ret), KR(tmp_ret), K(user_tenant_id)); - } - MTL_SWITCH(user_tenant_id) { - if (!MTL_IS_PRIMARY_TENANT()) { - //standby and restore - idle_time_us = 100 * 1000L; - } - } - } - } else { - if (OB_SUCCESS !=( tmp_ret = process_user_tenant_(*tenant_schema))) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to process tenant", KR(ret), KR(tmp_ret), K(tenant_id_)); - } + tenant_schema.reset(); + ObCurTraceId::init(GCONF.self_addr_); - if (OB_SUCCESS != (tmp_ret = report_sys_ls_recovery_stat_())) { - //ignore error of report, no need wakeup - LOG_WARN("failed to report sys ls recovery stat", KR(ret), KR(tmp_ret), K(tenant_id_)); - } + if (OB_FAIL(get_tenant_schema(tenant_id_, tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(tenant_id_)); + } else { + if (OB_TMP_FAIL(process_all_ls(tenant_schema))) { + ret = OB_SUCC(ret) ? tmp_ret : ret; + LOG_WARN("failed to process user tenant thread0", KR(ret), + KR(tmp_ret), K(tenant_id_)); + } + if (OB_TMP_FAIL(process_all_ls_status_to_steady_(tenant_schema))) { + ret = OB_SUCC(ret) ? tmp_ret : ret; + LOG_WARN("failed to process user tenant thread1", KR(ret), KR(tmp_ret), + K(tenant_id_)); } - }//for schema guard, must be free - if (OB_FAIL(ret)) { - idle_time_us = 100 * 1000; } + + LOG_INFO("[PRIMARY_LS_SERVICE] finish one round", KR(ret), K(tenant_schema)); + tenant_schema.reset(); idle(idle_time_us); - LOG_INFO("[LS_SER] finish one round", KR(ret), K(idle_time_us)); }// end while } } -//meta tenant no need process create_new_ls or drop ls -//only need to agjust primary zone of sys_ls -int ObPrimaryLSService::process_meta_tenant_(const share::schema::ObTenantSchema &tenant_schema) +int ObPrimaryLSService::process_all_ls(const share::schema::ObTenantSchema &tenant_schema) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init", KR(ret)); - } else if (OB_UNLIKELY(!tenant_schema.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tenant schema is invalid", KR(ret), K(tenant_schema)); - } else if (OB_ISNULL(GCTX.sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else if (!share::schema::ObSchemaService::is_formal_version(tenant_schema.get_schema_version()) - || !tenant_schema.is_normal()) { - } else if (tenant_schema.is_dropping()) { - } else { - share::ObLSPrimaryZoneInfo primary_zone_info; - ObArray primary_zone; - share::ObLSStatusOperator status_op; - ObZone new_primary_zone; - ObSqlString new_zone_priority; - if (OB_FAIL(ObPrimaryZoneUtil::get_tenant_primary_zone_array( - tenant_schema, primary_zone))) { - LOG_WARN("failed to get tenant primary zone array", KR(ret), K(tenant_schema)); - } else if (OB_FAIL(status_op.get_ls_primary_zone_info(tenant_id_, - SYS_LS, primary_zone_info, *GCTX.sql_proxy_))) { - LOG_WARN("failed to get ls primary_zone info", KR(ret), K(tenant_id_)); - } else if (OB_UNLIKELY(0 == primary_zone.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("primary zone is empty", KR(ret), K(tenant_schema)); - } else if (has_exist_in_array(primary_zone, primary_zone_info.get_primary_zone())) { - if (OB_FAIL(new_primary_zone.assign(primary_zone_info.get_primary_zone()))) { - LOG_WARN("failed to assign primary zone", KR(ret), K(primary_zone_info)); - } - } else if (OB_FAIL(new_primary_zone.assign(primary_zone.at(0)))) { - LOG_WARN("failed to assign primary zone", KR(ret), K(primary_zone)); - } - if (OB_FAIL(ret)) { - } else if (is_sys_tenant(tenant_id_)) { - //sys tenant use tenant normalize primary zone - if (OB_FAIL(ObPrimaryZoneUtil::get_tenant_zone_priority( - tenant_schema, new_zone_priority))) { - LOG_WARN("failed to get tenant primary zone array", KR(ret), K(tenant_schema)); - } - } else if (OB_FAIL(ObTenantLSInfo::get_zone_priority(new_primary_zone, tenant_schema, new_zone_priority))) { - LOG_WARN("failed to get normalize primary zone", KR(ret), K(new_primary_zone)); - } - if (FAILEDx(ObTenantLSInfo::try_update_ls_primary_zone_( - primary_zone_info, new_primary_zone, new_zone_priority))) { - LOG_WARN("failed to update ls primary zone", KR(ret), K(primary_zone_info), - K(new_primary_zone), K(new_zone_priority)); - } - - if (OB_SUCC(ret) && !is_sys_tenant(tenant_id_)) { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = gather_tenant_recovery_stat_())) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to gather tenant recovery stat", KR(ret), KR(tmp_ret)); - } - } - } - return ret; -} - -int ObPrimaryLSService::process_user_tenant_(const share::schema::ObTenantSchema &tenant_schema) -{ - int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; const uint64_t tenant_id = tenant_schema.get_tenant_id(); - ObTenantLSInfo tenant_stat(GCTX.sql_proxy_, &tenant_schema, tenant_id, - GCTX.srv_rpc_proxy_, GCTX.lst_operator_); + common::ObArray machine_array; + int64_t task_cnt = 0; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); @@ -2275,190 +114,406 @@ int ObPrimaryLSService::process_user_tenant_(const share::schema::ObTenantSchema } else if (tenant_schema.is_creating()) { ret = OB_SCHEMA_EAGAIN; LOG_WARN("tenant schema not ready, no need process", KR(ret), K(tenant_schema)); + } else if (OB_FAIL(ObLSServiceHelper::construct_ls_status_machine(false, tenant_id, + GCTX.sql_proxy_, machine_array))) { + LOG_WARN("failed to construct ls status machine", KR(ret), K(tenant_id)); } else if (tenant_schema.is_dropping()) { //if tenant schema is in dropping //set the creating ls to create_abort, //set the normal or dropping tenant to drop_tennat_pre - if (OB_FAIL(tenant_stat.drop_tenant(share::NORMAL_SWITCHOVER_STATUS))) { - LOG_WARN("failed to drop tenant", KR(ret), K(tenant_id)); - } else if (OB_FAIL(tenant_stat.process_ls_status_missmatch(false/* lock_sys_ls */, - share::NORMAL_SWITCHOVER_STATUS))) { - LOG_WARN("failed to process ls status missmatch", KR(ret), KR(tmp_ret)); + if (OB_FAIL(set_tenant_dropping_status_(machine_array, task_cnt))) { + LOG_WARN("failed to set tenant dropping status", KR(ret), K(task_cnt), K(machine_array)); } - } else { - //normal tenant - //some ls may failed to create ls, but can continue - if (OB_SUCCESS != (tmp_ret = tenant_stat.process_ls_status_missmatch(false/* lock_sys_ls */, - share::NORMAL_SWITCHOVER_STATUS))) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to process ls status missmatch", KR(ret), KR(tmp_ret)); - } - - //process each ls group and primary zone is matching - //process each unit group has the right ls group - //overwrite ret - if (OB_SUCCESS != (tmp_ret = tenant_stat.gather_stat(false))) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to gather stat", KR(ret), KR(tmp_ret), K(tenant_id)); - } else { - if (OB_SUCCESS != (tmp_ret = tenant_stat.check_ls_match_primary_zone())) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to check ls match with primary zone", KR(ret), KR(tmp_ret)); - } - if (OB_SUCCESS != (tmp_ret = tenant_stat.check_ls_group_match_unitnum())) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to check ls group match unitnum", KR(ret), KR(tmp_ret)); - } - } - if (OB_SUCCESS != (tmp_ret = tenant_stat.adjust_user_tenant_primary_zone())) { - //ignore error - LOG_WARN("failed to adjust user tenant primary zone", KR(ret), KR(tmp_ret)); + } + if (OB_SUCC(ret) && 0 == task_cnt) { + if (OB_FAIL(try_set_next_ls_status_(machine_array))) { + LOG_WARN("failed to set next ls status", KR(ret), K(machine_array)); } } - LOG_INFO("finish process tenant", KR(ret), KR(tmp_ret), K(tenant_id), K(tenant_schema)); - + LOG_INFO("[PRIMARY_LS_SERVICE] finish process tenant", + KR(ret), K(tenant_id), K(task_cnt), K(machine_array), K(tenant_schema)); return ret; } - -int ObPrimaryLSService::report_sys_ls_recovery_stat_() +int ObPrimaryLSService::set_tenant_dropping_status_( + const common::ObIArray &status_machine_array, int64_t &task_cnt) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init", KR(ret), K(inited_)); - } else { - ObLSService *ls_svr = MTL(ObLSService *); - ObLSHandle ls_handle; - if (OB_FAIL(ls_svr->get_ls(SYS_LS, ls_handle, storage::ObLSGetMod::RS_MOD))) { - LOG_WARN("failed to get ls", KR(ret)); - } else if (OB_FAIL(ObTenantRecoveryReportor::update_ls_recovery(ls_handle.get_ls(), GCTX.sql_proxy_))) { - LOG_WARN("failed to update ls recovery", KR(ret)); - } - } - return ret; -} - -int ObPrimaryLSService::try_force_drop_tenant_( - const uint64_t user_tenant_id) -{ - int ret = OB_SUCCESS; - ObTimeoutCtx ctx; - share::schema::ObSchemaGetterGuard schema_guard; - const share::schema::ObTenantSchema *tenant_schema = NULL; - if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); - } else if (OB_ISNULL(GCTX.sql_proxy_) - || OB_ISNULL(GCTX.rs_rpc_proxy_) - || OB_ISNULL(GCTX.schema_service_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_), KP(GCTX.rs_rpc_proxy_), - KP(GCTX.schema_service_)); - } else if (OB_UNLIKELY(!is_user_tenant(user_tenant_id))) { + } else { + share::ObLSAttrOperator ls_operator(MTL_ID(), GCTX.sql_proxy_); + const ObTenantSwitchoverStatus working_sw_status = share::NORMAL_SWITCHOVER_STATUS; + for (int64_t i = 0; OB_SUCC(ret) && i < status_machine_array.count() && !has_set_stop(); ++i) { + const share::ObLSAttr &attr = status_machine_array.at(i).ls_info_; + if (attr.get_ls_id().is_sys_ls()) { + if (attr.ls_is_normal()) { + if (OB_FAIL(ls_operator.update_ls_status(attr.get_ls_id(), + attr.get_ls_status(), share::OB_LS_PRE_TENANT_DROPPING, working_sw_status))) { + LOG_WARN("failed to update ls status", KR(ret), K(attr)); + } + task_cnt++; + LOG_INFO("[PRIMARY_LS_SERVICE] set sys ls to pre tenant dropping", KR(ret), K(attr)); + } + // find SYS LS + break; + } + }//end for set sys ls change to pre tenant dropping + + //TODO check all user ls is large than sys ls pre_tenant_dropping + for (int64_t i = 0; OB_SUCC(ret) && i < status_machine_array.count() && !has_set_stop(); ++i) { + const share::ObLSAttr &attr = status_machine_array.at(i).ls_info_; + if (attr.get_ls_id().is_sys_ls()) { + //no need process sys ls + } else if (attr.ls_is_creating()) { + //drop the status, + if (OB_FAIL(ls_operator.delete_ls(attr.get_ls_id(), attr.get_ls_status(), working_sw_status))) { + LOG_WARN("failed to remove ls not normal", KR(ret), K(attr)); + } + LOG_INFO("[PRIMARY_LS_SERVICE] tenant is dropping, delete ls in creating", KR(ret), K(attr)); + task_cnt++; + } else { + //no matter the status is in normal or dropping + //may be the status in status info is created + if (!attr.ls_is_tenant_dropping()) { + task_cnt++; + if (OB_FAIL(ls_operator.update_ls_status( + attr.get_ls_id(), attr.get_ls_status(), + share::OB_LS_TENANT_DROPPING, working_sw_status))) { + LOG_WARN("failed to update ls status", KR(ret), K(attr)); + } + LOG_INFO("[PRIMARY_LS_SERVICE] set ls to tenant dropping", KR(ret), K(attr), K(i)); + } + } + }//end for + } + if (OB_SUCC(ret) && has_set_stop()) { + ret = OB_IN_STOP_STATE; + LOG_WARN("[PRIMARY_LS_SERVICE] thread stop", KR(ret)); + } + return ret; +} + +int ObPrimaryLSService::try_set_next_ls_status_( + const common::ObIArray &status_machine_array) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + share::ObLSAttrOperator ls_operator(MTL_ID(), GCTX.sql_proxy_); + const ObTenantSwitchoverStatus working_sw_status = + share::NORMAL_SWITCHOVER_STATUS; + for (int64_t i = 0; OB_SUCC(ret) && i < status_machine_array.count() && !has_set_stop(); ++i) { + const ObLSStatusMachineParameter &machine = status_machine_array.at(i); + const share::ObLSStatusInfo &status_info = machine.status_info_; + const share::ObLSAttr &ls_info = machine.ls_info_; + const uint64_t tenant_id = status_info.tenant_id_; + if (OB_UNLIKELY(!machine.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("machine is invalid", KR(ret), K(machine)); + } else if (!ls_info.is_valid()) { + if (status_info.ls_is_wait_offline()) { + } else if (status_info.ls_is_create_abort() + || status_info.ls_is_creating() + || status_info.ls_is_created()) { + //in switchover/failover, need create abort ls + //in drop tenant, __all_ls will be deleted while status is creating + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status info is invalid", KR(ret), K(machine)); + } + } else if (ls_info.ls_is_creating()) { + if (status_info.ls_is_create_abort()) { + //delete ls, the ls must is creating + if (OB_FAIL(ls_operator.delete_ls( + machine.ls_id_, share::OB_LS_CREATING, working_sw_status))) { + LOG_WARN("failed to process creating info", KR(ret), K(machine)); + } + } else if (status_info.ls_is_created()) { + //set ls to normal + if (OB_FAIL(ls_operator.update_ls_status( + machine.ls_id_, ls_info.get_ls_status(), share::OB_LS_NORMAL, working_sw_status))) { + LOG_WARN("failed to update ls status", KR(ret), K(machine)); + } + } else if (status_info.ls_is_creating()) { + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status info is invalid", KR(ret), K(machine)); + } + } else if (ls_info.ls_is_normal()) { + if (status_info.ls_is_normal()) { + } else if (status_info.ls_is_created()) { + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status info is invalid", KR(ret), K(machine)); + } + } else if (ls_info.ls_is_dropping()) { + if (!status_info.ls_is_dropping()) { + } else if (OB_FAIL(try_delete_ls_(status_info))) { + LOG_WARN("failed to try delete ls", KR(ret), K(status_info)); + } + } else if (ls_info.ls_is_pre_tenant_dropping()) { + if (!machine.ls_id_.is_sys_ls()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("normal ls can not in pre tenant dropping status", KR(ret), K(machine)); + } else if (!status_info.ls_is_pre_tenant_dropping()) { + } else if (OB_FAIL(sys_ls_tenant_drop_(status_info))) { + LOG_WARN("failed to process sys ls", KR(ret), K(status_info)); + } + } else if (ls_info.ls_is_tenant_dropping()) { + if (!status_info.ls_is_tenant_dropping()) { + // __all_ls_status should also be tenant_dropping to notify GC module to offline LS + } else if (OB_FAIL(try_delete_ls_(status_info))) { + LOG_WARN("failed to try delete ls", KR(ret), K(machine), K(status_info)); + } + } else { + //other status can not be in __all_ls + //such as created, wait_offline + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the ls not expected in all_ls", KR(ret), K(machine)); + } + } + } + if (OB_SUCC(ret) && has_set_stop()) { + ret = OB_IN_STOP_STATE; + LOG_WARN("[PRIMARY_LS_SERVICE] thread stop", KR(ret)); + } + return ret; +} + +int ObPrimaryLSService::try_delete_ls_(const share::ObLSStatusInfo &status_info) +{ + int ret = OB_SUCCESS; + const int64_t start_time = ObTimeUtility::fast_current_time(); + bool can_offline = false; + const ObTenantSwitchoverStatus working_sw_status = share::NORMAL_SWITCHOVER_STATUS; + if (OB_UNLIKELY(!status_info.is_valid() + || (!status_info.ls_is_dropping() && !status_info.ls_is_tenant_dropping()) + || (status_info.ls_id_.is_sys_ls() && !status_info.ls_is_tenant_dropping()))) { + // SYS LS only can be in tenant_dropping, can not be in DROPPING ret = OB_INVALID_ARGUMENT; - LOG_WARN("not user tenant", KR(ret), K(user_tenant_id)); - } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( - OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("fail to get schema guard", KR(ret)); - } else if (OB_FAIL(schema_guard.get_tenant_info(user_tenant_id, tenant_schema))) { - LOG_WARN("failed to get tenant ids", KR(ret), K(user_tenant_id)); - } else if (OB_ISNULL(tenant_schema)) { - ret = OB_TENANT_NOT_EXIST; - LOG_WARN("tenant not exist", KR(ret), K(user_tenant_id)); - } else if (!tenant_schema->is_dropping()) { + LOG_WARN("info not valid or not in dropping status or sys ls", KR(ret), K(status_info)); } else { - LOG_INFO("try drop tenant", K(user_tenant_id)); - ObLSStatusOperator op; - share::ObLSStatusInfoArray ls_array; - if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, GCONF.rpc_timeout))) { - LOG_WARN("fail to set timeout ctx", KR(ret), K(user_tenant_id)); - } else if (OB_FAIL(op.get_all_ls_status_by_order(user_tenant_id, ls_array, *GCTX.sql_proxy_))) { - LOG_WARN("fail to get all ls status", KR(ret), K(user_tenant_id)); - } else if (ls_array.count() <= 0) { - obrpc::ObDropTenantArg arg; - arg.exec_tenant_id_ = OB_SYS_TENANT_ID; - arg.tenant_name_ = tenant_schema->get_tenant_name(); - arg.tenant_id_ = tenant_schema->get_tenant_id(); - arg.if_exist_ = true; - arg.delay_to_drop_ = false; - ObSqlString sql; - const int64_t timeout_ts = ctx.get_timeout(); - if (OB_FAIL(sql.append_fmt("DROP TENANT IF EXISTS %s FORCE", arg.tenant_name_.ptr()))) { - LOG_WARN("fail to generate sql", KR(ret), K(arg)); - } else if (FALSE_IT(arg.ddl_stmt_str_ = sql.string())) { - } else if (OB_FAIL(GCTX.rs_rpc_proxy_->timeout(timeout_ts).drop_tenant(arg))) { - LOG_WARN("fail to drop tenant", KR(ret), K(arg), K(timeout_ts)); + // send rpc to observer + share::ObLSAttrOperator ls_operator(MTL_ID(), GCTX.sql_proxy_); + if (OB_FAIL(check_ls_can_offline_by_rpc_(status_info, can_offline))) { + LOG_WARN("failed to check ls can offline", KR(ret), K(status_info)); + } else if (can_offline) { + // User LS should be deleted from __all_ls + if (!status_info.ls_id_.is_sys_ls()) { + if (OB_FAIL(ls_operator.delete_ls(status_info.ls_id_, status_info.status_, working_sw_status))) { + LOG_WARN("failed to delete ls", KR(ret), K(status_info)); + } + } else { + // SYS LS can not be deleted from __all_ls, as SYS LS is blocked by GC module. + // So, SYS LS should change __all_ls_status to WAIT_OFFLINE to end its status. + if (OB_FAIL(ObLSServiceHelper::offline_ls(status_info.tenant_id_, + status_info.ls_id_, status_info.status_, working_sw_status))) { + LOG_WARN("failed to offline ls", KR(ret), K(status_info), K(working_sw_status)); + } } - } else { - // tenant's logstream is still dropping, check next round } } + const int64_t cost = ObTimeUtility::fast_current_time() - start_time; + LOG_INFO("[PRIMARY_LS_SERVICE] finish to try delete LS", KR(ret), K(status_info), K(cost), K(can_offline)); return ret; } -int ObPrimaryLSService::gather_tenant_recovery_stat_() +int ObPrimaryLSService::sys_ls_tenant_drop_(const share::ObLSStatusInfo &info) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init", KR(ret)); - } else if (is_sys_tenant(tenant_id_)) { + const ObLSStatus target_status = share::OB_LS_TENANT_DROPPING; + const ObLSStatus pre_status = share::OB_LS_PRE_TENANT_DROPPING; + const ObTenantSwitchoverStatus working_sw_status = share::NORMAL_SWITCHOVER_STATUS; + bool can_offline = false; + if (OB_UNLIKELY(!info.is_valid() + || !info.ls_id_.is_sys_ls())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(info)); + } else if (pre_status != info.status_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("sys tenant no need gather tenant recovery stat", KR(ret), K(tenant_id_)); - } else if (OB_ISNULL(GCTX.sql_proxy_)) { + LOG_WARN("sys ls can not in other status", KR(ret), K(info)); + } else if (OB_FAIL(check_sys_ls_can_offline_(can_offline))) { + LOG_WARN("failed to check sys ls can offline", KR(ret)); + } else if (can_offline) { + share::ObLSAttrOperator ls_operator(MTL_ID(), GCTX.sql_proxy_); + if (OB_FAIL(ls_operator.update_ls_status(info.ls_id_, pre_status, target_status, working_sw_status))) { + LOG_WARN("failed to update ls status", KR(ret), K(info), K(pre_status), K(target_status)); + } + } + LOG_INFO("[PRIMARY_LS_SERVICE] set sys ls tenant dropping", KR(ret), K(info), K(can_offline)); + return ret; +} + +int ObPrimaryLSService::check_sys_ls_can_offline_(bool &can_offline) +{ + int ret = OB_SUCCESS; + share::ObLSStatusInfoArray status_info_array; + can_offline = true; + const uint64_t tenant_id = MTL_ID(); + share::ObLSStatusOperator status_operator; + if (OB_ISNULL(GCTX.sql_proxy_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sql proxy is null", KR(ret)); - } else { - ObLSRecoveryStatOperator ls_recovery_op; - ObAllTenantInfoProxy info_proxy; - ObAllTenantInfo tenant_info; - const uint64_t user_tenant_id = gen_user_tenant_id(tenant_id_); - SCN sync_scn; - SCN min_wrs_scn; - DEBUG_SYNC(BLOCK_TENANT_SYNC_SNAPSHOT_INC); - if (OB_FAIL(ls_recovery_op.get_tenant_recovery_stat( - user_tenant_id, *GCTX.sql_proxy_, sync_scn, min_wrs_scn))) { - LOG_WARN("failed to get tenant recovery stat", KR(ret), K(user_tenant_id)); - //TODO replayable_scn is equal to sync_scn - } else if (OB_FAIL(info_proxy.update_tenant_recovery_status( - user_tenant_id, GCTX.sql_proxy_, share::NORMAL_SWITCHOVER_STATUS, sync_scn, - sync_scn, min_wrs_scn))) { - LOG_WARN("failed to update tenant recovery stat", KR(ret), - K(user_tenant_id), K(sync_scn), K(min_wrs_scn)); + } else if (OB_FAIL(status_operator.get_all_ls_status_by_order( + tenant_id, status_info_array, *GCTX.sql_proxy_))) { + LOG_WARN("failed to get all ls status", KR(ret), K(tenant_id)); + } else if (0 == status_info_array.count()) { + //sys ls not exist + can_offline = true; + } + for (int64_t i = 0; OB_SUCC(ret) && i < status_info_array.count() && can_offline; ++i) { + const share::ObLSStatusInfo &status_info = status_info_array.at(i); + if (status_info.ls_id_.is_sys_ls()) { + } else { + can_offline = false; + LOG_INFO("[PRIMARY_LS_SERVICE] sys ls can not offline", K(status_info)); } } + if (OB_SUCC(ret) && can_offline) { + LOG_INFO("[PRIMARY_LS_SERVICE] sys ls can offline", K(status_info_array)); + } + return ret; +} + +int ObPrimaryLSService::check_ls_can_offline_by_rpc_(const share::ObLSStatusInfo &info, bool &can_offline) +{ + int ret = OB_SUCCESS; + ObAddr leader; + if (OB_UNLIKELY(!info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("info not valid", KR(ret), K(info)); + } else if (OB_ISNULL(GCTX.location_service_) || OB_ISNULL(GCTX.srv_rpc_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("location service or proxy is null", KR(ret), KP(GCTX.location_service_), + KP(GCTX.srv_rpc_proxy_)); + } else if (OB_FAIL(GCTX.location_service_->get_leader(GCONF.cluster_id, info.tenant_id_, + info.ls_id_, false, leader))) { + LOG_WARN("failed to get ls leader", KR(ret), K(info)); + } else { + const int64_t timeout = GCONF.rpc_timeout; + obrpc::ObCheckLSCanOfflineArg arg; + can_offline = false; + if (OB_FAIL(arg.init(info.tenant_id_, info.ls_id_, info.status_))) { + LOG_WARN("failed to init arg", KR(ret), K(arg)); + } else if (OB_FAIL(GCTX.srv_rpc_proxy_->to(leader) + .by(info.tenant_id_) + .timeout(timeout) + .check_ls_can_offline(arg))) { + can_offline = false; + LOG_WARN("failed to check ls can offline", KR(ret), K(arg), K(info), + K(timeout), K(leader)); + } else { + can_offline = true; + } + } + return ret; +} + +int ObPrimaryLSService::process_all_ls_status_to_steady_(const share::schema::ObTenantSchema &tenant_schema) +{ + int ret = OB_SUCCESS; + if (!is_user_tenant(tenant_id_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls recovery thread must run on user tenant", KR(ret), + K(tenant_id_)); + } else { + ObTenantLSInfo tenant_info(GCTX.sql_proxy_, &tenant_schema, tenant_id_); + if (OB_FAIL(ObLSServiceHelper::process_status_to_steady(false, share::NORMAL_SWITCHOVER_STATUS, tenant_info))) { + LOG_WARN("failed to process status to steady", KR(ret)); + } + } + LOG_INFO("[PRIMARY_LS_SERVICE] finish process all ls status to steady", KR(ret), K(tenant_id_)); + return ret; +} + +//the interface may reentry +int ObPrimaryLSService::create_ls_for_create_tenant() +{ + int ret = OB_SUCCESS; + share::schema::ObTenantSchema tenant_schema; + ObArray primary_zone; + ObArray unit_group_array; + share::ObLSAttrOperator ls_operator(tenant_id_, GCTX.sql_proxy_); + if (OB_FAIL(get_tenant_schema(tenant_id_, tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(tenant_id_)); + } else if (!tenant_schema.is_creating()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("only creating tenant can create user ls", KR(ret), K(tenant_schema)); + } else if (OB_FAIL(ObLSServiceHelper::get_primary_zone_unit_array(&tenant_schema, + primary_zone, unit_group_array))) { + LOG_WARN("failed to get primary zone unit array", KR(ret), K(tenant_schema)); + } else { + // ensure __all_ls is emptry + START_TRANSACTION(GCTX.sql_proxy_, tenant_id_) + ObArray ls_array; + share::ObLSAttr sys_ls; + if (FAILEDx(ls_operator.get_ls_attr(SYS_LS, true, trans, sys_ls))) { + LOG_WARN("failed to get SYS_LS attr", KR(ret)); + } else if (OB_FAIL(ls_operator.get_all_ls_by_order(ls_array))) { + LOG_WARN("failed to get all_ls by order", KR(ret)); + } else if (ls_array.count() > 1) { + //nothing + } else { + uint64_t ls_group_id = OB_INVALID_ID; + ObLSID ls_id; + share::ObLSAttr new_ls; + share::ObLSFlag flag; + SCN create_scn; + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_array.count(); ++i) { + if (unit_group_array.at(i).is_active()) { + //create ls + if (OB_FAIL(ObLSServiceHelper::fetch_new_ls_group_id(GCTX.sql_proxy_, tenant_id_, ls_group_id))) { + LOG_WARN("failed to fetch new LS group id", KR(ret), K(tenant_id_)); + } + for (int64_t j = 0; OB_SUCC(ret) && j < primary_zone.count(); j++) { + if (OB_FAIL(ObLSServiceHelper::fetch_new_ls_id(GCTX.sql_proxy_, tenant_id_, ls_id))) { + LOG_WARN("failed to fetch new LS id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(ObLSAttrOperator::get_tenant_gts(tenant_id_, create_scn))) { + LOG_WARN("failed to get tenant gts", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(new_ls.init(ls_id, ls_group_id, flag, share::OB_LS_CREATING, + share::OB_LS_OP_CREATE_PRE, create_scn))) { + LOG_WARN("failed to init new operation", KR(ret), K(create_scn), + K(ls_id), K(ls_group_id)); + } else if (OB_FAIL(ls_operator.insert_ls( + new_ls, share::NORMAL_SWITCHOVER_STATUS, &trans))) { + LOG_WARN("failed to insert new operation", KR(ret), K(new_ls)); + } + }//end for each ls group + } + }//end for each unit group + } + END_TRANSACTION(trans) + } return ret; } int ObPrimaryLSService::create_duplicate_ls() { int ret = OB_SUCCESS; - share::schema::ObSchemaGetterGuard schema_guard; - const share::schema::ObTenantSchema *tenant_schema = NULL; - if (OB_ISNULL(GCTX.schema_service_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error", KR(ret)); - } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( - OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("fail to get schema guard", KR(ret)); - } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id_, tenant_schema))) { - LOG_WARN("failed to get tenant ids", KR(ret), K(tenant_id_)); - } else if (OB_ISNULL(tenant_schema)) { - ret = OB_TENANT_NOT_EXIST; - LOG_WARN("tenant not exist", KR(ret), K(tenant_id_)); - } else { - const uint64_t tenant_id = tenant_schema->get_tenant_id(); - ObTenantLSInfo tenant_stat(GCTX.sql_proxy_, tenant_schema, tenant_id, - GCTX.srv_rpc_proxy_, GCTX.lst_operator_); - if (OB_FAIL(tenant_stat.gather_stat(false))) { - LOG_WARN("failed to gather stat", KR(ret)); - } else if (OB_FAIL(tenant_stat.create_duplicate_ls())) { - LOG_WARN("failed to create ls for unit group", KR(ret)); - } + share::ObLSAttrOperator ls_operator(tenant_id_, GCTX.sql_proxy_); + share::ObLSID ls_id; + SCN create_scn; + const uint64_t ls_group_id = 0; + share::ObLSAttr new_ls; + ObLSFlag flag(ObLSFlag::DUPLICATE_FLAG); + if (OB_FAIL(ObLSServiceHelper::fetch_new_ls_id(GCTX.sql_proxy_, tenant_id_, ls_id))) { + LOG_WARN("failed to fetch new LS id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(ObLSAttrOperator::get_tenant_gts(tenant_id_, create_scn))) { + LOG_WARN("failed to get tenant gts", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(new_ls.init(ls_id, ls_group_id, flag, share::OB_LS_CREATING, + share::OB_LS_OP_CREATE_PRE, create_scn))) { + LOG_WARN("failed to init new operation", KR(ret), K(create_scn), + K(ls_id), K(ls_group_id)); + } else if (OB_FAIL(ls_operator.insert_ls( + new_ls, share::NORMAL_SWITCHOVER_STATUS))) { + LOG_WARN("failed to insert new operation", KR(ret), K(new_ls)); } + LOG_INFO("[LS_MGR] create duplicate ls", KR(ret), K(new_ls)); return ret; } }//end of rootserver diff --git a/src/rootserver/ob_primary_ls_service.h b/src/rootserver/ob_primary_ls_service.h old mode 100644 new mode 100755 index fc025c546..c0c741f84 --- a/src/rootserver/ob_primary_ls_service.h +++ b/src/rootserver/ob_primary_ls_service.h @@ -18,9 +18,12 @@ #include "share/ls/ob_ls_status_operator.h"//ObLSStatusOperator #include "share/ls/ob_ls_operator.h" //ObLSAttr #include "share/ob_thread_mgr.h" //OBTGDefIDEnum +#include "logservice/palf/palf_iterator.h" //PalfBufferIterator #include "share/unit/ob_unit_info.h"//ObUnit::Status #include "lib/thread/thread_mgr_interface.h" // TGRunnable #include "lib/lock/ob_thread_cond.h"//ObThreadCond +#include "rootserver/ob_tenant_thread_helper.h"//ObTenantThreadHelper +#include "rootserver/ob_ls_service_helper.h"//ObLSStatusMachineParameter namespace oceanbase @@ -33,10 +36,12 @@ namespace common { class ObMySQLProxy; class ObMySQLTransaction; +class ObClusterVersion; } namespace share { class ObLSTableOperator; +class SCN; namespace schema { class ObMultiVersionSchemaService; @@ -50,287 +55,6 @@ struct PalfBaseInfo; } namespace rootserver { -struct ObUnitGroupInfo -{ - ObUnitGroupInfo() : unit_group_id_(OB_INVALID_ID), unit_status_(share::ObUnit::UNIT_STATUS_MAX), - ls_group_ids_() {} - virtual ~ObUnitGroupInfo() {} - bool is_valid() const; - int init(const uint64_t unit_group_id, - const share::ObUnit::Status &unit_status); - void reset(); - int assign(const ObUnitGroupInfo &other); - int remove_ls_group(const uint64_t ls_group_id); - bool operator==(const ObUnitGroupInfo &other) const; - - uint64_t unit_group_id_; - share::ObUnit::Status unit_status_; - ObArray ls_group_ids_; - TO_STRING_KV(K_(unit_group_id), K_(unit_status), K_(ls_group_ids)); -}; -typedef ObArray ObUnitGroupInfoArray; -typedef ObIArray ObUnitGroupInfoIArray; - -struct ObLSGroupInfo -{ - ObLSGroupInfo() : ls_group_id_(OB_INVALID_ID), unit_group_id_(OB_INVALID_ID), - ls_ids_() {} - virtual ~ObLSGroupInfo() {} - bool is_valid() const; - int init(const uint64_t unit_group_id, const uint64_t ls_group_id); - int assign(const ObLSGroupInfo &other); - void reset(); - int remove_ls(const share::ObLSID &ls_id); - uint64_t ls_group_id_; - uint64_t unit_group_id_; - ObArray ls_ids_; - TO_STRING_KV(K_(ls_group_id), K_(unit_group_id), K_(ls_ids)); -}; - -typedef ObArray ObLSGroupInfoArray; -typedef ObIArray ObLSGroupInfoIArray; - -struct ObLSStatusMachineParameter -{ - ObLSStatusMachineParameter() : ls_id_(), status_info_(), ls_info_(share::OB_LS_EMPTY) {} - virtual ~ObLSStatusMachineParameter() {} - bool is_valid() const - { - return ls_id_.is_valid() - && (share::OB_LS_EMPTY == status_info_.status_ - || status_info_.ls_id_ == ls_id_); - } - int init(const share::ObLSID &id, const share::ObLSStatusInfo &status_info, - const share::ObLSStatus &ls_info); - void reset(); - share::ObLSID ls_id_; - share::ObLSStatusInfo status_info_;//for create ls and status of __all_ls_status - share::ObLSStatus ls_info_;//status in __all_ls - TO_STRING_KV(K_(ls_id), K_(status_info), K_(ls_info)); -}; - -/*descripthin: Tenant log stream status information: Statistical log stream - * status on __all_ls_status and __all_ls, tenant primary_zone and unit_num - * information. Provides location information for the newly created log stream. - * Whether the build needs to create or delete log streams.*/ -class ObTenantLSInfo -{ -public: - ObTenantLSInfo(ObMySQLProxy *sql_proxy, - const share::schema::ObTenantSchema *tenant_schema, - const uint64_t tenant_id, obrpc::ObSrvRpcProxy *rpc_proxy, - share::ObLSTableOperator *lst_operator) - : sql_proxy_(sql_proxy), - tenant_schema_(tenant_schema), - status_operator_(), - ls_operator_(tenant_id, sql_proxy), - status_array_(), - unit_group_array_(), - ls_group_array_(), - primary_zone_(), - rpc_proxy_(rpc_proxy), - lst_operator_(lst_operator), - max_ls_id_(OB_INVALID_ID), - max_ls_group_id_(OB_INVALID_ID) {} - - virtual ~ObTenantLSInfo(){}; - void reset(); - bool is_valid() const; - - int gather_stat(bool for_recovery); - //some ls not in __all_ls, but in __all_ls_status - //it need delete by gc, no need process it anymore. - //check the ls status, and delete no need ls - int process_ls_status_missmatch( - const bool lock_sys_ls, - const share::ObTenantSwitchoverStatus &working_sw_status); - - // need create or delete new ls group - int check_ls_group_match_unitnum(); - - //need create or delete new ls - int check_ls_match_primary_zone(); - - int fetch_new_ls_group_id(const uint64_t tenant_id, uint64_t &ls_group_id); - int fetch_new_ls_id(const uint64_t tenant_id, share::ObLSID &ls_id); - - //get ls group info from ls_group_array_ by ls_group_id - //the interface must used after gather_stat(); - int get_ls_group_info(const uint64_t ls_group_id, ObLSGroupInfo &info) const; - - //get ls status info from status_array_ by ls_id - //the interface must used after gather_stat(); - int get_ls_status_info(const share::ObLSID &id, share::ObLSStatusInfo &info, - int64_t &info_index) const; - //process dropping tenant, set status to tenant_dropping in __all_ls - int drop_tenant(const share::ObTenantSwitchoverStatus &working_sw_status); - //for recovery tenant, create new ls according to ls_id and ls_group_id - int create_new_ls_for_recovery(const share::ObLSID &ls_id, - const uint64_t ls_group_id, - const share::SCN &create_scn, - common::ObMySQLTransaction &trans, - const share::ObLSFlag &ls_flag); - //for recovery tenant, if ls is in creating in __all_ls_status, create the ls - int process_ls_stats_for_recovery(); - - int adjust_user_tenant_primary_zone(); - - /* - * description: create ls with palf base info for recovery - @param[in] info: status info in __all_ls_status_info - @param[in] create_scn : create scn of ls - @param[in] create_ls_with_palf: restore create init ls - @param[in] palf_base_info : palf base info - */ - int create_ls_with_palf(const share::ObLSStatusInfo &info, const share::SCN &create_scn, - const bool create_ls_with_palf, - const palf::PalfBaseInfo &palf_base_info); - - static int get_zone_priority(const ObZone &primary_zone, - const share::schema::ObTenantSchema &tenant_schema, - ObSqlString &primary_zone_str); - static int try_update_ls_primary_zone_(const share::ObLSPrimaryZoneInfo &primary_zone_info, - const common::ObZone &new_primary_zone, - const common::ObSqlString &zone_priority); - static int construct_ls_status_machine_( - const share::ObLSStatusInfoIArray &statua_info_array, - const share::ObLSAttrIArray &ls_array, - common::ObIArray &status_machine_array); - - int create_duplicate_ls(); - -private: - int fix_ls_status_(const ObLSStatusMachineParameter &status_machine, - const share::ObTenantSwitchoverStatus &working_sw_status); - // get from __all_ls_status and __all_ls - int gather_all_ls_info_(); - - // base on status_array construct ls_array - int add_ls_to_ls_group_(const share::ObLSStatusInfo &info); - - // base on ls_array construct unit_group_array and __all_unit - int add_ls_group_to_unit_group_(const ObLSGroupInfo &group_info); - - int process_creating_ls_(const share::ObLSAttr &ls_operation); - - int check_unit_group_valid_(const uint64_t unit_group_id, bool &is_valid); - int add_ls_status_info_(const share::ObLSStatusInfo &ls_info); - int create_new_ls_for_empty_unit_group_(const uint64_t unit_group_id); - - int get_next_unit_group_(const bool is_recovery, int64_t &group_index); - // get the primary zone not in ls group - int get_next_primary_zone_(const bool is_recovery, const ObLSGroupInfo &group_info, - ObZone &primary_zone); - int create_new_ls_(const share::ObLSStatusInfo &ls_info, - const share::ObTenantSwitchoverStatus &working_sw_status); - - // drop ls group info - int try_drop_ls_of_deleting_unit_group_(const ObUnitGroupInfo &info); - int drop_ls_(const share::ObLSStatusInfo &ls_info, - const share::ObTenantSwitchoverStatus &working_sw_status); - int do_drop_ls_(const share::ObLSStatusInfo &ls_info, - const share::ObTenantSwitchoverStatus &working_sw_status); - int do_tenant_drop_ls_(const share::ObLSStatusInfo &ls_info, - const share::ObTenantSwitchoverStatus &working_sw_status); - int do_create_ls_(const share::ObLSStatusInfo &info, const share::SCN &create_scn); - int sys_ls_tenant_drop_(const share::ObLSStatusInfo &info, - const share::ObTenantSwitchoverStatus &working_sw_status); - int check_sys_ls_can_offline_(bool &can_offline); - int check_ls_empty_(const share::ObLSStatusInfo &info, bool &empty); - int check_ls_can_offline_by_rpc_(const share::ObLSStatusInfo &info, - const share::ObLSStatus ¤t_ls_status, - bool &can_offline); - int process_ls_status_after_created_(const share::ObLSStatusInfo &info, - const share::ObTenantSwitchoverStatus &working_sw_status); - -private: - static int set_ls_to_primary_zone(const common::ObIArray &primary_zone_array, - const share::ObLSPrimaryZoneInfoArray &primary_zone_infos, - common::ObIArray &ls_primary_zone, - common::ObIArray &count_group_by_zone); - static int balance_ls_primary_zone(const common::ObIArray &primary_zone_array, - common::ObIArray &ls_primary_zone, - common::ObIArray &count_group_by_zone); - int adjust_primary_zone_by_ls_group_(const common::ObIArray &primary_zone_array, - const share::ObLSPrimaryZoneInfoArray &primary_zone_infos, - const share::schema::ObTenantSchema &tenant_schema); - -private: - ObMySQLProxy *sql_proxy_; - const share::schema::ObTenantSchema *tenant_schema_; - share::ObLSStatusOperator status_operator_; - share::ObLSAttrOperator ls_operator_; - bool is_load_; - share::ObLSStatusInfoArray status_array_; - common::hash::ObHashMap status_map_; - ObUnitGroupInfoArray unit_group_array_; - ObLSGroupInfoArray ls_group_array_; - ObArray primary_zone_; - obrpc::ObSrvRpcProxy *rpc_proxy_; - share::ObLSTableOperator *lst_operator_; - //ensure ls can not be concurrent created - uint64_t max_ls_id_; - uint64_t max_ls_group_id_; -}; - -class ObTenantThreadHelper : public lib::TGRunnable, - public logservice::ObIRoleChangeSubHandler -{ -public: - ObTenantThreadHelper() : tg_id_(-1), thread_cond_(), is_created_(false), is_first_time_to_start_(true), thread_name_("") {} - virtual ~ObTenantThreadHelper() {} - virtual void do_work() = 0; - virtual void run1() override; - virtual void destroy(); - int start(); - void stop(); - void wait(); - void mtl_thread_stop(); - void mtl_thread_wait(); - int create(const char* thread_name, int tg_def_id, ObTenantThreadHelper &tenant_thread); - void idle(const int64_t idle_time_us); -public: - virtual void switch_to_follower_forcedly() override; - - virtual int switch_to_leader() override; - virtual int switch_to_follower_gracefully() override - { - stop(); - return OB_SUCCESS; - } - virtual int resume_leader() override - { - return OB_SUCCESS; - } - -#define DEFINE_MTL_FUNC(TYPE)\ - static int mtl_init(TYPE *&ka) {\ - int ret = OB_SUCCESS;\ - if (OB_ISNULL(ka)) {\ - ret = OB_ERR_UNEXPECTED;\ - } else if (OB_FAIL(ka->init())) {\ - }\ - return ret;\ - }\ - static void mtl_stop(TYPE *&ka) {\ - if (OB_NOT_NULL(ka)) {\ - ka->mtl_thread_stop();\ - }\ - }\ - static void mtl_wait(TYPE *&ka) {\ - if (OB_NOT_NULL(ka)) {\ - ka->mtl_thread_wait();\ - }\ - } - -protected: - int tg_id_; -private: - common::ObThreadCond thread_cond_; - bool is_created_; - bool is_first_time_to_start_; - const char* thread_name_; -}; /*description: *Log stream management thread: Started on the leader of the system log stream @@ -365,19 +89,23 @@ public: return OB_SUCCESS; } + int create_ls_for_create_tenant(); int create_duplicate_ls(); private: - - int process_user_tenant_(const share::schema::ObTenantSchema &tenant_schema); - //no need create ls or drop ls, but need adjust primary_zone - int process_meta_tenant_(const share::schema::ObTenantSchema &tenant_schema); - //for primary cluster, sys ls recovery stat need report, - //standby cluster will be reported in RecoveryLSService + int process_all_ls(const share::schema::ObTenantSchema &tenant_schema); + int process_all_ls_status_to_steady_(const share::schema::ObTenantSchema &tenant_schema); + //TODO int report_sys_ls_recovery_stat_(); - // force drop user tenant if tenant is in dropping status - int try_force_drop_tenant_( - const uint64_t user_tenant_id); - int gather_tenant_recovery_stat_(); + int set_tenant_dropping_status_(const common::ObIArray &status_machine_array, + int64_t &task_cnt); + int try_set_next_ls_status_(const common::ObIArray &status_machine_array); + + int try_delete_ls_(const share::ObLSStatusInfo &ls_info); + int sys_ls_tenant_drop_(const share::ObLSStatusInfo &info); + int check_sys_ls_can_offline_(bool &can_offline); + int check_ls_empty_(const share::ObLSStatusInfo &info, bool &empty); + int check_ls_can_offline_by_rpc_(const share::ObLSStatusInfo &info, + bool &can_offline); private: bool inited_; uint64_t tenant_id_; diff --git a/src/rootserver/ob_recovery_ls_service.cpp b/src/rootserver/ob_recovery_ls_service.cpp old mode 100644 new mode 100755 index 6bfdd49c9..c2e2dc204 --- a/src/rootserver/ob_recovery_ls_service.cpp +++ b/src/rootserver/ob_recovery_ls_service.cpp @@ -24,9 +24,11 @@ #include "logservice/ob_garbage_collector.h"//ObGCLSLog #include "logservice/restoreservice/ob_log_restore_handler.h"//ObLogRestoreHandler #include "observer/ob_server_struct.h" //GCTX -#include "rootserver/ob_primary_ls_service.h" //ObTenantLSInfo -#include "rootserver/ob_tenant_recovery_reportor.h" //ObTenantRecoveryReportor #include "rootserver/ob_tenant_info_loader.h" // ObTenantInfoLoader +#include "rootserver/ob_ls_recovery_reportor.h" //ObLSRecoveryReportor +#include "rootserver/ob_ls_service_helper.h"//ObTenantLSInfo, ObLSServiceHelper +#include "rootserver/ob_balance_ls_primary_zone.h" +#include "src/share/balance/ob_balance_task_helper_operator.h"//insert_new_ls #include "rootserver/ob_create_standby_from_net_actor.h" // ObCreateStandbyFromNetActor #include "share/ls/ob_ls_life_manager.h" //ObLSLifeManger #include "share/ls/ob_ls_operator.h" //ObLSAttr @@ -34,8 +36,6 @@ #include "share/ob_errno.h" #include "share/ob_share_util.h" //ObShareUtil #include "share/schema/ob_multi_version_schema_service.h" //ObMultiSchemaService -#include "share/restore/ob_physical_restore_info.h" //restore_status -#include "share/restore/ob_physical_restore_table_operator.h"//ObPhysicalRestoreTableOperator #include "share/ob_primary_standby_service.h" // ObPrimaryStandbyService #include "share/ob_standby_upgrade.h" // ObStandbyUpgrade #include "share/ob_upgrade_utils.h" // ObUpgradeChecker @@ -43,6 +43,8 @@ #include "storage/tx/ob_tx_log.h" //ObTxLogHeader #include "storage/tx_storage/ob_ls_service.h" //ObLSService #include "storage/tx_storage/ob_ls_handle.h" //ObLSHandle +#include "storage/tx/ob_multi_data_source.h" //ObTxBufferNode +#include "share/ob_log_restore_proxy.h" // ObLogRestoreProxyUtil #include "src/rootserver/ob_rs_event_history_table_operator.h" namespace oceanbase @@ -111,7 +113,7 @@ void ObRecoveryLSService::do_work() ObLSRecoveryStatOperator ls_recovery; palf::PalfBufferIterator iterator; int tmp_ret = OB_SUCCESS; - const int64_t idle_time_us = 100 * 1000L; + int64_t idle_time_us = 100 * 1000L; SCN start_scn; while (!has_set_stop()) { ObCurTraceId::init(GCONF.self_addr_); @@ -127,13 +129,26 @@ void ObRecoveryLSService::do_work() LOG_WARN("tenant report is null", KR(ret), K(tenant_id_)); } else if (OB_FAIL(tenant_info_loader->get_tenant_info(tenant_info))) { LOG_WARN("failed to get tenant info", KR(ret)); - } else if (OB_FAIL(check_can_do_recovery_(tenant_info))) { - LOG_WARN("failed to check do recovery", KR(ret), K(tenant_info)); + } else if (OB_UNLIKELY(tenant_info.is_primary())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant info is primary", KR(ret), K(tenant_info)); + } else if (OB_FAIL(check_can_do_recovery_(tenant_id_))) { + LOG_WARN("can not do recovery now", KR(ret), K(tenant_id_)); } else if (0 == thread_idx) { - if (OB_SUCCESS != (tmp_ret = process_recovery_ls_manager())) { + idle_time_us = 10 * 1000 * 1000L; + DEBUG_SYNC(STOP_RECOVERY_LS_THREAD0); + //adjust primary zone and balance ls group + if (OB_TMP_FAIL(do_standby_balance_())) { ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to process recovery ls manager", KR(ret), KR(tmp_ret)); + LOG_WARN("do standby balance", KR(ret), KR(tmp_ret)); } + + if (OB_TMP_FAIL(do_ls_balance_task_())) { + ret = OB_SUCC(ret) ? tmp_ret : ret; + LOG_WARN("failed to process alter ls group", KR(ret), KR(tmp_ret)); + } + + (void)try_tenant_upgrade_end_(); if (tenant_info.is_standby()) { if (REACH_TENANT_TIME_INTERVAL(10 * 1000 * 1000)) { (void)try_update_primary_ip_list(); @@ -145,7 +160,8 @@ void ObRecoveryLSService::do_work() if (OB_FAIL(ls_recovery.get_ls_recovery_stat(tenant_id_, SYS_LS, false, ls_recovery_stat, *proxy_))) { LOG_WARN("failed to load sys recovery stat", KR(ret), K(tenant_id_)); - } else if (OB_FAIL(report_sys_ls_recovery_stat_(ls_recovery_stat.get_sync_scn()))) { + } else if (OB_FAIL(report_sys_ls_recovery_stat_(ls_recovery_stat.get_sync_scn(), true, + "report readable_scn while start_scn is invalid"))) { //may recovery end, but readable scn need report LOG_WARN("failed to report ls recovery stat", KR(ret), K(ls_recovery_stat)); } else if (tenant_info.get_recovery_until_scn() == ls_recovery_stat.get_sync_scn()) { @@ -170,11 +186,10 @@ void ObRecoveryLSService::do_work() start_scn.reset(); } - if (REACH_TIME_INTERVAL(10 * 1000 * 1000)) { // every 10 second - (void)try_tenant_upgrade_end_(); - } + } - LOG_INFO("[LS_RECOVERY] finish one round", KR(ret), KR(tmp_ret), K(start_scn), K(thread_idx), K(tenant_info)); + LOG_INFO("[LS_RECOVERY] finish one round", KR(ret), KR(tmp_ret), + K(start_scn), K(thread_idx), K(tenant_info), K(idle_time_us)); idle(idle_time_us); } } @@ -257,7 +272,8 @@ int ObRecoveryLSService::process_ls_log_( //通过scn定位的LSN是不准确的,可能会获取多余的数据,所以需要把小于等于sync_scn的过滤掉 continue; } else if (tenant_info.get_recovery_until_scn() < sync_scn) { - if (OB_FAIL(report_sys_ls_recovery_stat_(tenant_info.get_recovery_until_scn()))) { + if (OB_FAIL(report_sys_ls_recovery_stat_(tenant_info.get_recovery_until_scn(), false, + "SYS log scn beyond recovery_until_scn"))) { LOG_WARN("failed to report_sys_ls_recovery_stat_", KR(ret), K(sync_scn), K(tenant_info), K(log_entry), K(target_lsn), K(start_scn)); // SYS LS has recovered to the recovery_until_scn, need stop iterate SYS LS log and reset start_scn @@ -295,12 +311,16 @@ int ObRecoveryLSService::process_ls_log_( LOG_WARN("failed to process ls tx log", KR(ret), K(tx_log_block), K(sync_scn)); } } else {} + if (OB_SUCC(ret)) { last_sync_scn = sync_scn; - } else if (last_sync_scn.is_valid()) { + } + + if (last_sync_scn.is_valid() && (OB_FAIL(ret) || REACH_TENANT_TIME_INTERVAL(100 * 1000))) { //if ls_operator can not process, need to report last sync scn int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(report_sys_ls_recovery_stat_(last_sync_scn))) { + if (OB_TMP_FAIL(report_sys_ls_recovery_stat_(last_sync_scn, false, + "regular report when iterate log"))) { LOG_WARN("failed to report ls recovery stat", KR(ret), KR(tmp_ret), K(last_sync_scn)); } } @@ -308,12 +328,23 @@ int ObRecoveryLSService::process_ls_log_( }//end for each log if (OB_ITER_END == ret) { ret = OB_SUCCESS; - if (OB_FAIL(report_sys_ls_recovery_stat_(sync_scn))) { - LOG_WARN("failed to report ls recovery stat", KR(ret), K(sync_scn), K(iterator)); + if (!sync_scn.is_valid() || start_scn >= sync_scn) { + //No logs need to be iterated, or iterate log have beed reported + //but need to report readable_scn and tenant_info + const char* comment = sync_scn.is_valid() ? "iterate no new log" : "iterate no log"; + if (OB_FAIL(report_sys_ls_recovery_stat_(start_scn, true, comment))) { + LOG_WARN("failed to report sys ls readable scn", KR(ret), K(start_scn), K(sync_scn), K(comment)); + } + } else if (OB_FAIL(report_sys_ls_recovery_stat_(sync_scn, false, + "iterate log end"))) { + LOG_WARN("failed to report ls recovery stat", KR(ret), K(sync_scn)); + } else { + LOG_INFO("iterate log end, start scn change", K(start_scn), K(sync_scn)); + start_scn = sync_scn; } } else if (OB_SUCC(ret)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("iterator must be end", KR(ret), K(iterator)); + LOG_WARN("iterate must be end", KR(ret), K(iterator)); } else { LOG_WARN("failed to get next log", KR(ret), K(iterator)); } @@ -345,50 +376,51 @@ int ObRecoveryLSService::process_ls_tx_log_(ObTxLogBlock &tx_log_block, const SC } else if (transaction::ObTxLogType::TX_COMMIT_LOG != tx_header.get_tx_log_type()) { // nothing + } else if (has_operation) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("has more commit log", KR(ret), K(sync_scn)); } else { ObTxCommitLogTempRef temp_ref; ObTxCommitLog commit_log(temp_ref); - const int64_t COMMIT_SIZE = commit_log.get_serialize_size(); //TODO commit log may too large if (OB_FAIL(tx_log_block.deserialize_log_body(commit_log))) { LOG_WARN("failed to deserialize", KR(ret)); } else { const ObTxBufferNodeArray &source_data = commit_log.get_multi_source_data(); + const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id_); + START_TRANSACTION(proxy_, exec_tenant_id) for (int64_t i = 0; OB_SUCC(ret) && i < source_data.count(); ++i) { const ObTxBufferNode &node = source_data.at(i); if (ObTxDataSourceType::STANDBY_UPGRADE == node.get_data_source_type()) { if (OB_FAIL(process_upgrade_log_(node))) { LOG_WARN("failed to process_upgrade_log_", KR(ret), K(node)); } - } else if (ObTxDataSourceType::LS_TABLE != node.get_data_source_type()) { + } else if (ObTxDataSourceType::LS_TABLE != node.get_data_source_type() + && ObTxDataSourceType::TRANSFER_TASK != node.get_data_source_type()) { // nothing - } else if (has_operation) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("one clog has more than one operation", KR(ret), K(commit_log)); - } else { - has_operation = true; - ObLSAttr ls_attr; - const int64_t LS_SIZE = ls_attr.get_serialize_size(); - int64_t pos = 0; - if (OB_FAIL(ls_attr.deserialize(node.get_data_buf().ptr(), LS_SIZE, - pos))) { - LOG_WARN("failed to deserialize", KR(ret), K(node), K(LS_SIZE)); - } else if (OB_UNLIKELY(pos > LS_SIZE)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get ls attr", KR(ret), K(pos), K(LS_SIZE)); - } else { - LOG_INFO("get ls operation", K(ls_attr), K(sync_scn)); - //TODO ls recovery is too fast for ls manager, so it maybe failed, while change ls status - //consider how to retry - if (OB_FAIL(process_ls_operator_(ls_attr, - sync_scn))) { - LOG_WARN("failed to process ls operator", KR(ret), K(ls_attr), - K(sync_scn)); - } + } else if (FALSE_IT(has_operation = true)) { + //can not be there; + } else if (OB_FAIL(check_valid_to_operator_ls_(sync_scn))) { + LOG_WARN("failed to check valid to operator ls", KR(ret), K(sync_scn)); + } else if (ObTxDataSourceType::TRANSFER_TASK == node.get_data_source_type()) { + if (OB_FAIL(process_ls_transfer_task_in_trans_(node, sync_scn, trans))) { + LOG_WARN("failed to process ls transfer task", KR(ret), K(node)); } + } else if (OB_FAIL(process_ls_table_in_trans_(node, + sync_scn, trans))) { + //TODO ls recovery is too fast for ls manager, so it maybe failed, while change ls status + //consider how to retry + LOG_WARN("failed to process ls operator", KR(ret), K(node), + K(sync_scn)); } }// end for + if (OB_FAIL(ret) || !has_operation) { + } else if (OB_FAIL(report_sys_ls_recovery_stat_in_trans_(sync_scn, false, trans, + "report recovery stat and has multi data source"))) { + LOG_WARN("failed to report sys ls recovery stat", KR(ret), K(sync_scn)); + } + END_TRANSACTION(trans) } } } // end while for each tx_log @@ -559,15 +591,9 @@ int ObRecoveryLSService::process_gc_log_(logservice::ObGCLSLog &gc_log, const SC tenant_id_, SYS_LS, share::OB_LS_TENANT_DROPPING, sync_scn, share::NORMAL_SWITCHOVER_STATUS, trans))) { LOG_WARN("failed to set offline", KR(ret), K(tenant_id_), K(sync_scn)); - } else { - ObLSRecoveryStatOperator ls_recovery; - ObLSRecoveryStat ls_recovery_stat; - if (OB_FAIL(construct_ls_recovery_stat(sync_scn, ls_recovery_stat))) { - LOG_WARN("failed to construct ls recovery stat", KR(ret), K(sync_scn)); - } else if (OB_FAIL(ls_recovery.update_ls_recovery_stat_in_trans( - ls_recovery_stat, trans))) { - LOG_WARN("failed to update ls recovery stat", KR(ret), K(ls_recovery_stat)); - } + } else if (OB_FAIL(report_sys_ls_recovery_stat_in_trans_(sync_scn, false, trans, + "report recovery stat and process gc log"))) { + LOG_WARN("failed to report sys ls recovery stat", KR(ret), K(sync_scn)); } if (trans.is_started()) { int tmp_ret = OB_SUCCESS; @@ -579,66 +605,102 @@ int ObRecoveryLSService::process_gc_log_(logservice::ObGCLSLog &gc_log, const SC return ret; } -int ObRecoveryLSService::construct_ls_recovery_stat(const SCN &sync_scn, - ObLSRecoveryStat &ls_stat) +int ObRecoveryLSService::construct_sys_ls_recovery_stat_based_on_sync_scn_( + const SCN &sync_scn, + ObLSRecoveryStat &ls_stat, + const ObAllTenantInfo &tenant_info) { int ret = OB_SUCCESS; ls_stat.reset(); + ObLSService *ls_svr = MTL(ObLSService *); + ObLSHandle ls_handle; + ObLS *ls = NULL; + ObLSRecoveryStat tmp_ls_stat; SCN readable_scn; + if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret), K(inited_)); - } else if (OB_FAIL(ObTenantRecoveryReportor::get_readable_scn(SYS_LS, readable_scn))) { + } else if (OB_ISNULL(ls_svr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service is null", KR(ret)); + } else if (OB_FAIL(ls_svr->get_ls(SYS_LS, ls_handle, storage::ObLSGetMod::RS_MOD))) { + LOG_WARN("failed to get ls", KR(ret)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls is NULL", KR(ret), K(ls_handle)); + } else if (OB_FAIL(ls->get_ls_level_recovery_stat(tmp_ls_stat))) { LOG_WARN("failed to get readable scn", KR(ret)); - } else if (OB_FAIL(ls_stat.init_only_recovery_stat( - tenant_id_, SYS_LS, sync_scn, readable_scn))) { + } else if (sync_scn < tmp_ls_stat.get_readable_scn()) { + // SYS LS latest readable scn may be greater than sync_scn in __all_ls_recovery_stat + // + // 1. At first, Tenant is PRIMARY, SYS LS latest log scn is 100, and report to __all_ls_recovery_stat. + // + // 2. Then, Tenant switch to STANDBY, tenant sync_scn in __all_tenant_info is advanced to 200, and + // tenant replayable_scn in __all_tenant_info is also advanced to 200. + // + // 3. SYS LS continues to sync log, next log scn must be greater than 200, for example, next log + // scn is 300. Now, SYS LS sync_scn in __all_ls_recovery_stat is still 100. + // + // 4. Now, we decide to report SYS LS recovery stat. Its sync_scn is 100, but the readable_scn + // will be advanced to 200 by replay engine. Because tenant replayable scn is 200. + // There is no log between 100 and 200. + // + // So, Here SYS LS readable_scn may be greater than sync_scn in __all_ls_recovery_stat. + // + // In this case, we just change the readable_scn to be same with sync_scn. + + readable_scn = sync_scn; + + LOG_INFO("SYS LS sync_scn in __all_ls_recovery_stat is less than its real readable scn. " + "This is NORMAL after tenant switchover from PRIMARY TO STANDBY.", + KR(ret), K(readable_scn), K(tenant_info), K(tmp_ls_stat)); + } else { + readable_scn = tmp_ls_stat.get_readable_scn(); + } + + if (FAILEDx(ls_stat.init_only_recovery_stat(tenant_id_, SYS_LS, sync_scn, readable_scn))) { LOG_WARN("failed to init ls recovery stat", KR(ret), K(tenant_id_), - K(sync_scn), K(readable_scn)); + K(sync_scn), K(readable_scn), K(tmp_ls_stat), K(tenant_info)); } return ret; } -int ObRecoveryLSService::process_ls_operator_(const share::ObLSAttr &ls_attr, const SCN &sync_scn) +int ObRecoveryLSService::process_ls_table_in_trans_(const transaction::ObTxBufferNode &node, + const SCN &sync_scn, common::ObMySQLTransaction &trans) { int ret = OB_SUCCESS; - common::ObMySQLTransaction trans; - const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id_); - if (OB_UNLIKELY(!ls_attr.is_valid())) { + if (OB_UNLIKELY(!node.is_valid() || !sync_scn.is_valid() + || ObTxDataSourceType::LS_TABLE != node.get_data_source_type() + || !trans.is_started())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls attr is invalid", KR(ret), K(ls_attr)); - } else if (OB_ISNULL(proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("proxy is null", KR(ret)); - } else if (OB_FAIL(check_valid_to_operator_ls_(ls_attr, sync_scn))) { - LOG_WARN("failed to check valid to operator ls", KR(ret), K(sync_scn), K(ls_attr)); - } else if (OB_FAIL(trans.start(proxy_, meta_tenant_id))) { - LOG_WARN("failed to start trans", KR(ret), K(meta_tenant_id)); - } else if (OB_FAIL(process_ls_operator_in_trans_(ls_attr, sync_scn, trans))) { - LOG_WARN("failed to process ls operator in trans", KR(ret), K(ls_attr), K(sync_scn)); - } - - if (OB_SUCC(ret)) { - ObLSRecoveryStat ls_recovery_stat; - ObLSRecoveryStatOperator ls_recovery; - if (OB_FAIL(construct_ls_recovery_stat(sync_scn, ls_recovery_stat))) { - LOG_WARN("failed to construct ls recovery stat", KR(ret), K(sync_scn)); - } else if (OB_FAIL(ls_recovery.update_ls_recovery_stat_in_trans( - ls_recovery_stat, trans))) { - LOG_WARN("failed to update ls recovery stat", KR(ret), K(ls_recovery_stat)); - } - } - if (trans.is_started()) { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to end trans", KR(ret), K(tmp_ret)); + LOG_WARN("invalid argument", KR(ret), K(sync_scn), K(node), "trans_start", trans.is_started()); + } else { + ObLSAttr ls_attr; + int64_t pos = 0; + if (OB_FAIL(ls_attr.deserialize(node.get_data_buf().ptr(), node.get_data_buf().length(), + pos))) { + LOG_WARN("failed to deserialize", KR(ret), K(node)); + } else if (OB_UNLIKELY(pos > node.get_data_buf().length())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ls attr", KR(ret), K(pos), K(node)); + } else { + LOG_INFO("get ls operation", K(ls_attr), K(sync_scn)); + if (share::is_ls_tenant_drop_pre_op(ls_attr.get_ls_operation_type())) { + ret = OB_ITER_STOP; + LOG_WARN("can not process ls operator after tenant dropping", K(ls_attr)); + } else if (share::is_ls_tenant_drop_op(ls_attr.get_ls_operation_type())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls recovery must stop while pre tenant dropping", KR(ret), K(ls_attr)); + } else if (OB_FAIL(process_ls_operator_in_trans_(ls_attr, sync_scn, trans))) { + LOG_WARN("failed to process ls operator in trans", KR(ret), K(ls_attr), K(sync_scn)); + } } } return ret; } -int ObRecoveryLSService::check_valid_to_operator_ls_( - const share::ObLSAttr &ls_attr, const SCN &sync_scn) +int ObRecoveryLSService::check_valid_to_operator_ls_(const SCN &sync_scn) { int ret = OB_SUCCESS; bool has_user_ls = true; @@ -648,15 +710,9 @@ int ObRecoveryLSService::check_valid_to_operator_ls_( } else if (OB_ISNULL(proxy_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("proxy is null", KR(ret)); - } else if (OB_UNLIKELY(!sync_scn.is_valid() || !ls_attr.is_valid())) { + } else if (OB_UNLIKELY(!sync_scn.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("syns scn is invalid", KR(ret), K(sync_scn), K(ls_attr)); - } else if (share::is_ls_tenant_drop_pre_op(ls_attr.get_ls_operatin_type())) { - ret = OB_ITER_STOP; - LOG_WARN("can not process ls operator after tenant dropping", K(ls_attr)); - } else if (share::is_ls_tenant_drop_op(ls_attr.get_ls_operatin_type())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls recovery must stop while pre tenant dropping", KR(ret), K(ls_attr)); + LOG_WARN("syns scn is invalid", KR(ret), K(sync_scn)); } else if (OB_FAIL(ObCreateStandbyFromNetActor::check_has_user_ls(tenant_id_, proxy_, has_user_ls))) { LOG_WARN("check_has_user_ls failed", KR(ret), K(tenant_id_)); } else if (has_user_ls) { @@ -681,9 +737,9 @@ int ObRecoveryLSService::process_ls_operator_in_trans_( { int ret = OB_SUCCESS; const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id_); - if (OB_UNLIKELY(!ls_attr.is_valid())) { + if (OB_UNLIKELY(!ls_attr.is_valid() || !trans.is_started())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls attr is invalid", KR(ret), K(ls_attr)); + LOG_WARN("ls attr is invalid", KR(ret), K(ls_attr), "trans_start", trans.is_started()); } else if (OB_ISNULL(proxy_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("proxy is null", KR(ret)); @@ -694,16 +750,20 @@ int ObRecoveryLSService::process_ls_operator_in_trans_( if (OB_UNLIKELY(!ls_attr.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("ls attr is invalid", KR(ret), K(ls_attr)); - } else if (share::is_ls_create_pre_op(ls_attr.get_ls_operatin_type())) { + } else if (OB_FAIL(share::is_ls_alter_ls_group_op(ls_attr.get_ls_operation_type()))) { + if (OB_FAIL(porcess_alter_ls_group_(ls_attr, sync_scn, trans))) { + LOG_WARN("failed to process alter ls group", KR(ret), K(ls_attr), K(sync_scn)); + } + } else if (share::is_ls_create_pre_op(ls_attr.get_ls_operation_type())) { //create new ls; if (OB_FAIL(create_new_ls_(ls_attr, sync_scn, trans))) { LOG_WARN("failed to create new ls", KR(ret), K(sync_scn), K(ls_attr)); } - } else if (share::is_ls_create_abort_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_create_abort_op(ls_attr.get_ls_operation_type())) { if (OB_FAIL(ls_life_agent.drop_ls_in_trans(tenant_id_, ls_attr.get_ls_id(), share::NORMAL_SWITCHOVER_STATUS, trans))) { LOG_WARN("failed to drop ls", KR(ret), K(tenant_id_), K(ls_attr)); } - } else if (share::is_ls_drop_end_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_drop_end_op(ls_attr.get_ls_operation_type())) { if (OB_FAIL(ls_life_agent.set_ls_offline_in_trans(tenant_id_, ls_attr.get_ls_id(), ls_attr.get_ls_status(), sync_scn, share::NORMAL_SWITCHOVER_STATUS, trans))) { LOG_WARN("failed to set offline", KR(ret), K(tenant_id_), K(ls_attr), K(sync_scn)); @@ -716,14 +776,14 @@ int ObRecoveryLSService::process_ls_operator_in_trans_( } else if (ls_status.ls_is_creating()) { ret = OB_EAGAIN; LOG_WARN("ls not created, need wait", KR(ret), K(ls_status)); - } else if (share::is_ls_create_end_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_create_end_op(ls_attr.get_ls_operation_type())) { // set ls to normal target_status = share::OB_LS_NORMAL; - } else if (share::is_ls_tenant_drop_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_tenant_drop_op(ls_attr.get_ls_operation_type())) { target_status = share::OB_LS_TENANT_DROPPING; - } else if (share::is_ls_drop_pre_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_drop_pre_op(ls_attr.get_ls_operation_type())) { target_status = share::OB_LS_DROPPING; - } else if (share::is_ls_tenant_drop_pre_op(ls_attr.get_ls_operatin_type())) { + } else if (share::is_ls_tenant_drop_pre_op(ls_attr.get_ls_operation_type())) { target_status = share::OB_LS_PRE_TENANT_DROPPING; } else { ret = OB_ERR_UNEXPECTED; @@ -741,12 +801,36 @@ int ObRecoveryLSService::process_ls_operator_in_trans_( return ret; } + +int ObRecoveryLSService::porcess_alter_ls_group_(const share::ObLSAttr &ls_attr, + const share::SCN &sync_scn, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (!share::is_ls_alter_ls_group_op(ls_attr.get_ls_operation_type()) + || !sync_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_attr), K(sync_scn)); + } else { + ObBalanceTaskHelper ls_balance_task; + ObBalanceTaskHelperOp task_op(share::ObBalanceTaskHelperOp::LS_BALANCE_TASK_OP_ALTER); + if (OB_FAIL(ls_balance_task.init(tenant_id_, + sync_scn, task_op, ls_attr.get_ls_id(), ls_attr.get_ls_id(), + ls_attr.get_ls_group_id()))) { + LOG_WARN("failed to init ls balance task", KR(ret), K(ls_attr), K(sync_scn)); + } else if (OB_FAIL(ObBalanceTaskHelperTableOperator::insert_ls_balance_task(ls_balance_task, trans))) { + LOG_WARN("failed to insert ls balance task", KR(ret), K(ls_balance_task)); + } + } + return ret; +} + int ObRecoveryLSService::create_new_ls_(const share::ObLSAttr &ls_attr, const SCN &sync_scn, common::ObMySQLTransaction &trans) { int ret = OB_SUCCESS; - if (!share::is_ls_create_pre_op(ls_attr.get_ls_operatin_type())) { + if (!share::is_ls_create_pre_op(ls_attr.get_ls_operation_type())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("ls not create pre operation", KR(ret), K(ls_attr)); } else { @@ -758,7 +842,7 @@ int ObRecoveryLSService::create_new_ls_(const share::ObLSAttr &ls_attr, ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected error", KR(ret)); } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( - OB_SYS_TENANT_ID, schema_guard))) { + OB_SYS_TENANT_ID, schema_guard))) { LOG_WARN("fail to get schema guard", KR(ret)); } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id_, tenant_schema))) { LOG_WARN("failed to get tenant ids", KR(ret), K(tenant_id_)); @@ -766,14 +850,12 @@ int ObRecoveryLSService::create_new_ls_(const share::ObLSAttr &ls_attr, ret = OB_TENANT_NOT_EXIST; LOG_WARN("tenant not exist", KR(ret), K(tenant_id_)); } else { - ObTenantLSInfo tenant_stat(GCTX.sql_proxy_, tenant_schema, tenant_id_, - GCTX.srv_rpc_proxy_, GCTX.lst_operator_); + ObTenantLSInfo tenant_stat(GCTX.sql_proxy_, tenant_schema, tenant_id_); ObLSFlag ls_flag = ls_attr.get_ls_flag(); - if (OB_FAIL(tenant_stat.gather_stat(true))) { - LOG_WARN("failed to gather stat", KR(ret)); - } else if (OB_FAIL(tenant_stat.create_new_ls_for_recovery(ls_attr.get_ls_id(), - ls_attr.get_ls_group_id(), ls_attr.get_create_scn(), trans, ls_flag))) { - LOG_WARN("failed to add new ls status info", KR(ret), K(ls_attr), K(sync_scn)); + if (OB_FAIL(ObLSServiceHelper::create_new_ls_in_trans(ls_attr.get_ls_id(), + ls_attr.get_ls_group_id(), ls_attr.get_create_scn(), + share::NORMAL_SWITCHOVER_STATUS, tenant_stat, trans, ls_flag))) { + LOG_WARN("failed to add new ls status info", KR(ret), K(ls_attr), K(sync_scn), K(tenant_stat)); } } LOG_INFO("[LS_RECOVERY] create new ls", KR(ret), K(ls_attr)); @@ -781,77 +863,8 @@ int ObRecoveryLSService::create_new_ls_(const share::ObLSAttr &ls_attr, return ret; } - -int ObRecoveryLSService::process_recovery_ls_manager() -{ - int ret = OB_SUCCESS; - share::schema::ObSchemaGetterGuard schema_guard; - const share::schema::ObTenantSchema *tenant_schema = NULL; - - if (OB_UNLIKELY(!inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret), K(inited_)); - } else if (OB_ISNULL(GCTX.schema_service_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error", KR(ret)); - } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( - OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("fail to get schema guard", KR(ret)); - } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id_, tenant_schema))) { - LOG_WARN("failed to get tenant ids", KR(ret), K(tenant_id_)); - } else if (OB_ISNULL(tenant_schema)) { - ret = OB_TENANT_NOT_EXIST; - LOG_WARN("tenant not exist", KR(ret), K(tenant_id_)); - } else { - ObTenantLSInfo tenant_stat(GCTX.sql_proxy_, tenant_schema, tenant_id_, - GCTX.srv_rpc_proxy_, GCTX.lst_operator_); - if (OB_FAIL(tenant_stat.process_ls_stats_for_recovery())) { - LOG_WARN("failed to do process in standby", KR(ret), K(tenant_id_)); - } - } - return ret; -} - -int ObRecoveryLSService::check_can_do_recovery_(const ObAllTenantInfo &tenant_info) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret), K(inited_)); - } else if (OB_UNLIKELY(!tenant_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tenant_info is invalid", KR(ret), K(tenant_info)); - } else if (tenant_info.is_primary()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("primary tenant can not do recovery", KR(ret), K(tenant_info)); - } else if (tenant_info.is_standby()) { - //standby can do recovery - } else if (tenant_info.is_restore()) { - //need to check success to create init ls - share::ObPhysicalRestoreTableOperator restore_table_operator; - share::ObPhysicalRestoreJob job_info; - if (OB_ISNULL(proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql can't null", K(ret), K(proxy_)); - } else if (OB_FAIL(restore_table_operator.init(proxy_, tenant_id_))) { - LOG_WARN("fail to init restore table operator", KR(ret), K(tenant_id_)); - } else if (OB_FAIL(restore_table_operator.get_job_by_tenant_id(tenant_id_, - job_info))) { - LOG_WARN("fail to get restore job", K(ret), K(tenant_id_)); - } else if (job_info.is_valid_status_to_recovery()) { - //can do recovery - } else { - ret = OB_NEED_WAIT; - LOG_WARN("restore tenant not valid to recovery", KR(ret), K(job_info)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected tenant role", KR(ret), K(tenant_info)); - } - return ret; -} - -int ObRecoveryLSService::report_sys_ls_recovery_stat_(const SCN &sync_scn) +int ObRecoveryLSService::report_sys_ls_recovery_stat_(const SCN &sync_scn, const bool only_update_readable_scn, + const char* comment) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!inited_)) { @@ -860,20 +873,204 @@ int ObRecoveryLSService::report_sys_ls_recovery_stat_(const SCN &sync_scn) } else if (OB_ISNULL(proxy_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sql can't null", K(ret), K(proxy_)); + } else if (SCN::base_scn() != sync_scn) { + ObLSRecoveryStatOperator ls_recovery; + const uint64_t exec_tenant_id = ls_recovery.get_exec_tenant_id(tenant_id_); + START_TRANSACTION(proxy_, exec_tenant_id) + if (FAILEDx(report_sys_ls_recovery_stat_in_trans_(sync_scn, + only_update_readable_scn, trans, comment))) { + LOG_WARN("failed to report sys ls recovery stat", KR(ret), K(sync_scn), K(only_update_readable_scn)); + } + END_TRANSACTION(trans) + } + return ret; +} + +int ObRecoveryLSService::report_sys_ls_recovery_stat_in_trans_( + const share::SCN &sync_scn, const bool only_update_readable_scn, common::ObMySQLTransaction &trans, + const char* comment) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret), K(inited_)); + } else if (OB_ISNULL(proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql can't null", K(ret), K(proxy_)); + } else if (OB_UNLIKELY(!sync_scn.is_valid()) + || OB_ISNULL(comment)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(sync_scn), KP(comment)); } else if (SCN::base_scn() != sync_scn) { ObLSRecoveryStatOperator ls_recovery; ObLSRecoveryStat ls_recovery_stat; - if (OB_FAIL(construct_ls_recovery_stat(sync_scn, ls_recovery_stat))) { - LOG_WARN("failed to construct ls recovery stat", KR(ret), K(sync_scn)); - } else if (OB_FAIL(ls_recovery.update_ls_recovery_stat(ls_recovery_stat, - *proxy_))) { - LOG_WARN("failed to update ls recovery stat", KR(ret), - K(ls_recovery_stat)); + ObAllTenantInfo tenant_info; + rootserver::ObTenantInfoLoader *tenant_info_loader = MTL(rootserver::ObTenantInfoLoader*); + //two thread for seed log and recovery_ls_manager + if (OB_ISNULL(tenant_info_loader)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("mtl pointer is null", KR(ret), KP(tenant_info_loader)); + } else if (OB_FAIL(tenant_info_loader->get_tenant_info(tenant_info))) { + LOG_WARN("get_tenant_info failed", K(ret)); + } else if (tenant_info.is_primary()) { + ret = OB_ITER_STOP; + LOG_WARN("is primary cluster, no need report", KR(ret), K(tenant_info)); + } else if (OB_FAIL(construct_sys_ls_recovery_stat_based_on_sync_scn_(sync_scn, ls_recovery_stat, + tenant_info))) { + LOG_WARN("failed to construct ls recovery stat", KR(ret), K(sync_scn), K(tenant_info)); + } else if (OB_FAIL(ObLSRecoveryReportor::update_sys_ls_recovery_stat_and_tenant_info( + ls_recovery_stat, tenant_info.get_tenant_role(), only_update_readable_scn, trans))) { + LOG_WARN("failed to update sys ls recovery stat", KR(ret), + K(ls_recovery_stat), K(tenant_info)); + } + FLOG_INFO("report sys ls recovery stat", KR(ret), K(sync_scn), K(only_update_readable_scn), + K(tenant_info), K(ls_recovery_stat), K(comment)); + } + return ret; +} + +int ObRecoveryLSService::process_ls_transfer_task_in_trans_( + const transaction::ObTxBufferNode &node, const share::SCN &sync_scn, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!node.is_valid() || !sync_scn.is_valid() + || ObTxDataSourceType::TRANSFER_TASK != node.get_data_source_type() + || !trans.is_started())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(sync_scn), K(node), "trans_start", trans.is_started()); + } else { + ObBalanceTaskHelperMeta task_meta; + ObBalanceTaskHelper ls_balance_task; + int64_t pos = 0; + if (OB_FAIL(task_meta.deserialize(node.get_data_buf().ptr(), node.get_data_buf().length(), pos))) { + LOG_WARN("failed to deserialize", KR(ret), K(node)); + } else if (OB_UNLIKELY(pos > node.get_data_buf().length())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to deserialize balance task", KR(ret), K(pos), K(node)); + } else { + LOG_INFO("get new balance task", K(task_meta)); + const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id_); + if (FAILEDx(ls_balance_task.init(sync_scn, tenant_id_, task_meta))) { + LOG_WARN("failed to init ls balance task", KR(ret), K(task_meta), K(sync_scn)); + } else if (OB_FAIL(ObBalanceTaskHelperTableOperator::insert_ls_balance_task(ls_balance_task, trans))) { + LOG_WARN("failed to insert ls balance task", KR(ret), K(ls_balance_task)); + } } } return ret; } +//balance ls group and balance primary zone +int ObRecoveryLSService::do_standby_balance_() +{ + int ret = OB_SUCCESS; + ObTenantSchema tenant_schema; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret), K(inited_)); + } else if (OB_ISNULL(proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql can't null", K(ret), K(proxy_)); + } else if (OB_FAIL(get_tenant_schema(tenant_id_, tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(ObBalanceLSPrimaryZone::try_adjust_user_ls_primary_zone(tenant_schema))) { + LOG_WARN("failed to adjust user ls primary zone", KR(ret), K(tenant_schema)); + } else { + ObTenantLSInfo tenant_info(proxy_, &tenant_schema, tenant_id_); + if (OB_FAIL(ObLSServiceHelper::balance_ls_group(tenant_info))) { + LOG_WARN("failed to balance ls group", KR(ret)); + } + } + return ret; +} + +int ObRecoveryLSService::do_ls_balance_task_() +{ + int ret = OB_SUCCESS; + ObBalanceTaskHelper ls_balance_task; + ObTenantInfoLoader *tenant_info_loader = MTL(rootserver::ObTenantInfoLoader*); + ObAllTenantInfo tenant_info; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret), K(inited_)); + } else if (OB_ISNULL(proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql can't null", K(ret), K(proxy_)); + } else if (FALSE_IT(ret = ObBalanceTaskHelperTableOperator::pop_task(tenant_id_, + *proxy_, ls_balance_task))) { + } else if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else if (OB_FAIL(ret)) { + LOG_WARN("failed to pop task", KR(ret), K(tenant_id_)); + } else if (OB_ISNULL(tenant_info_loader)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("mtl pointer is null", KR(ret), KP(tenant_info_loader)); + } else if (OB_FAIL(tenant_info_loader->get_tenant_info(tenant_info))) { + LOG_WARN("get_tenant_info failed", K(ret)); + } else if (tenant_info.get_standby_scn() >= ls_balance_task.get_operation_scn()) { + const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id_); + START_TRANSACTION(proxy_, exec_tenant_id) + if (FAILEDx(ObBalanceTaskHelperTableOperator::remove_task(tenant_id_, + ls_balance_task.get_operation_scn(), trans))) { + LOG_WARN("failed to remove task", KR(ret), K(tenant_id_), K(ls_balance_task)); + } else if (ls_balance_task.get_task_op().is_ls_alter()) { + if (OB_FAIL(do_ls_balance_alter_task_(ls_balance_task, trans))) { + LOG_WARN("failed to do ls alter task", KR(ret), K(ls_balance_task)); + } + } else if (ls_balance_task.get_task_op().is_transfer_begin() + || ls_balance_task.get_task_op().is_transfer_end()) { + //nothing + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls balance task op is unexpected", KR(ret), K(ls_balance_task)); + } + END_TRANSACTION(trans) + LOG_INFO("task can be remove", KR(ret), K(ls_balance_task)); + } else { + if (REACH_TENANT_TIME_INTERVAL(10 * 1000 * 1000)) { // 10s + LOG_INFO("can not remove ls balance task helper", K(ls_balance_task), K(tenant_info)); + } + } + return ret; +} + +int ObRecoveryLSService::do_ls_balance_alter_task_(const share::ObBalanceTaskHelper &ls_balance_task, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret), K(inited_)); + } else if (OB_UNLIKELY(!ls_balance_task.is_valid() || !ls_balance_task.get_task_op().is_ls_alter())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_balance_task)); + } else { + ObLSStatusInfo status_info; + ObLSStatusOperator status_op; + ObTenantSchema tenant_schema; + if (FALSE_IT(ret = status_op.get_ls_status_info(tenant_id_, ls_balance_task.get_src_ls(), + status_info, trans))) { + } else if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + //ls maybe gc, no need to check + } else if (OB_FAIL(ret)) { + LOG_WARN("failed to get ls status info", KR(ret), K(tenant_id_), K(ls_balance_task)); + } else if (status_info.ls_group_id_ == ls_balance_task.get_ls_group_id()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected", KR(ret), K(status_info), K(ls_balance_task)); + } else if (OB_FAIL(get_tenant_schema(tenant_id_, tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(tenant_id_)); + } else { + ObTenantLSInfo tenant_info(proxy_, &tenant_schema, tenant_id_); + if (OB_FAIL(ObLSServiceHelper::process_alter_ls(ls_balance_task.get_src_ls(), status_info.ls_group_id_, + ls_balance_task.get_ls_group_id(), tenant_info, trans))) { + LOG_WARN("failed to process alter ls", KR(ret), K(ls_balance_task), K(status_info)); + } + } + } + return ret; +} void ObRecoveryLSService::try_update_primary_ip_list() { int ret = OB_SUCCESS; diff --git a/src/rootserver/ob_recovery_ls_service.h b/src/rootserver/ob_recovery_ls_service.h old mode 100644 new mode 100755 index 94dab6ed5..d11d73d33 --- a/src/rootserver/ob_recovery_ls_service.h +++ b/src/rootserver/ob_recovery_ls_service.h @@ -36,12 +36,17 @@ class ObMySQLProxy; class ObISQLClient; class ObMySQLTransaction; } +namespace transaction +{ +class ObTxBufferNode; +} namespace share { class ObLSTableOperator; struct ObLSAttr; struct ObLSRecoveryStat; class SCN; +class ObBalanceTaskHelper; namespace schema { class ObMultiVersionSchemaService; @@ -77,6 +82,7 @@ public: DEFINE_MTL_FUNC(ObRecoveryLSService) private: //get log iterator by start_scn + //interface for thread0 int seek_log_iterator_(const share::SCN &syn_scn, palf::PalfBufferIterator &iterator); int process_ls_log_(const ObAllTenantInfo &tenant_info, @@ -87,24 +93,40 @@ private: const share::SCN &syn_scn); int process_ls_tx_log_(transaction::ObTxLogBlock &tx_log, const share::SCN &syn_scn); - int process_ls_operator_(const share::ObLSAttr &ls_attr, - const share::SCN &syn_scn); + int process_ls_table_in_trans_(const transaction::ObTxBufferNode &node, + const share::SCN &syn_scn, + common::ObMySQLTransaction &trans); int create_new_ls_(const share::ObLSAttr &ls_attr, const share::SCN &syn_scn, common::ObMySQLTransaction &trans); - int process_recovery_ls_manager(); - int construct_ls_recovery_stat(const share::SCN &syn_scn, - share::ObLSRecoveryStat &ls_stat); + int construct_sys_ls_recovery_stat_based_on_sync_scn_( + const share::SCN &syn_scn, + ObLSRecoveryStat &ls_stat, + const ObAllTenantInfo &tenant_info); //wait other ls is larger than sycn ts - int check_valid_to_operator_ls_(const share::ObLSAttr &ls_attr, - const share::SCN &syn_scn); - int check_can_do_recovery_(const ObAllTenantInfo &tenant_info); + int check_valid_to_operator_ls_(const share::SCN &syn_scn); //readable scn need report - int report_sys_ls_recovery_stat_(const share::SCN &sync_scn); void try_tenant_upgrade_end_(); int get_min_data_version_(uint64_t &compatible); int process_ls_operator_in_trans_(const share::ObLSAttr &ls_attr, const share::SCN &sync_scn, common::ObMySQLTransaction &trans); + int porcess_alter_ls_group_(const share::ObLSAttr &ls_attr, + const share::SCN &sync_scn, + common::ObMySQLTransaction &trans); + int report_sys_ls_recovery_stat_(const share::SCN &sync_scn, const bool only_update_readable_scn, + const char* comment); + int report_sys_ls_recovery_stat_in_trans_(const share::SCN &sync_scn, + const bool only_update_readable_scn, + common::ObMySQLTransaction &trans, + const char* comment); + + int process_ls_transfer_task_in_trans_(const transaction::ObTxBufferNode &node, + const share::SCN &sync_scn, common::ObMySQLTransaction &trans); + //thread1 + int do_standby_balance_(); + int do_ls_balance_task_(); + int do_ls_balance_alter_task_(const share::ObBalanceTaskHelper &ls_balance_task, + common::ObMySQLTransaction &trans); int reset_restore_proxy_(ObRestoreSourceServiceAttr &service_attr); void try_update_primary_ip_list(); bool check_need_update_ip_list_(share::ObLogRestoreSourceItem &item); diff --git a/src/rootserver/ob_root_inspection.cpp b/src/rootserver/ob_root_inspection.cpp old mode 100644 new mode 100755 index 36a1a09df..a93eafa11 --- a/src/rootserver/ob_root_inspection.cpp +++ b/src/rootserver/ob_root_inspection.cpp @@ -30,7 +30,6 @@ #include "rootserver/ob_root_service.h" #include "observer/ob_server_struct.h" #include "observer/ob_sql_client_decorator.h" -#include "share/backup/ob_backup_info_mgr.h" #include "share/ob_primary_zone_util.h" #include "share/ob_upgrade_utils.h" #include "share/rc/ob_context.h" @@ -38,6 +37,7 @@ #include "share/ob_schema_status_proxy.h"//ObSchemaStatusProxy #include "share/ob_global_stat_proxy.h"//ObGlobalStatProxy #include "share/ob_tenant_info_proxy.h" // ObAllTenantInfoProxy +#include "share/schema/ob_table_schema.h" namespace oceanbase { @@ -297,9 +297,9 @@ int ObTableGroupChecker::inspect_( ObArray table_ids; if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("tablegroup checker is not init", K(ret)); + LOG_WARN("tablegroup checker is not init", KR(ret)); } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) { - LOG_WARN("get schema guard failed", K(ret), K(tenant_id)); + LOG_WARN("get schema guard failed", KR(ret), K(tenant_id)); } else if (OB_FAIL(schema_guard.get_table_ids_in_tenant(tenant_id, table_ids))) { LOG_WARN("fail to get table_ids", KR(ret), K(tenant_id)); } else if (OB_ISNULL(GCTX.root_service_)) { @@ -322,11 +322,12 @@ int ObTableGroupChecker::inspect_( } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_id, table))) { LOG_WARN("get table schema failed", K(ret), KT(table_id)); } else if (OB_ISNULL(table)) { - //ignore table not exist + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table not exist", KR(ret), K(table_id)); } else if (is_sys_table(table->get_table_id()) || !table->has_partition()) { // skip, check the partitioned user table } else if (OB_FAIL(check_part_option(*table, schema_guard))) { - LOG_WARN("check part option fail", KPC(table)); + LOG_WARN("check part option fail", KR(ret), KPC(table)); } else {} } } @@ -347,15 +348,16 @@ int ObTableGroupChecker::inspect_( // in addition, the partition_num, partition_type, partition_value and number of expression vectors of tables must be same. // 2) tablegroup is partitioned, the partition_num, partition_type, partition_value and number of expression vectors // of tables in tablegroup should be same. -int ObTableGroupChecker::check_part_option(const ObTableSchema &table, ObSchemaGetterGuard &schema_guard) +int ObTableGroupChecker::check_part_option(const ObSimpleTableSchemaV2 &table, ObSchemaGetterGuard &schema_guard) { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; + ObSqlString user_error; const uint64_t tenant_id = table.get_tenant_id(); const uint64_t tablegroup_id = table.get_tablegroup_id(); if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("tablegroup checker is not init", K(ret)); + LOG_WARN("tablegroup checker is not init", KR(ret)); } else if (OB_INVALID_ID == tablegroup_id) { // skip check while tablegroup_id is default value } else if (!table.is_user_table()) { @@ -364,218 +366,62 @@ int ObTableGroupChecker::check_part_option(const ObTableSchema &table, ObSchemaG //skip check while already in part_option_not_match_set_ if (OB_HASH_EXIST != tmp_ret) { ret = tmp_ret; - LOG_WARN("fail to check if tablegroup_id exist", K(ret), K(tablegroup_id)); + LOG_WARN("fail to check if tablegroup_id exist", KR(ret), K(tablegroup_id)); } } else { - const ObTableSchema *table_in_map; + const ObSimpleTableSchemaV2 *table_in_map = NULL; bool is_matched = true; - if (is_sys_tablegroup_id(tablegroup_id)) { + const ObTablegroupSchema *tablegroup = NULL; + const ObSimpleTableSchemaV2 *primary_table_schema = NULL; + if (OB_FAIL(schema_guard.get_tablegroup_schema(tenant_id, tablegroup_id, tablegroup))) { + LOG_WARN("fail to get tablegroup schema", KR(ret), K(tenant_id), KT(tablegroup_id)); + } else if (OB_ISNULL(tablegroup)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablegroup schema is null", KR(ret), KT(tablegroup_id)); + } else if (tablegroup->get_sharding() == OB_PARTITION_SHARDING_NONE) { + //no need to check,just ignore + } else if (tablegroup->get_sharding() == OB_PARTITION_SHARDING_PARTITION + || tablegroup->get_sharding() == OB_PARTITION_SHARDING_ADAPTIVE) { + bool check_sub_part = tablegroup->get_sharding() == OB_PARTITION_SHARDING_PARTITION ? false : true; if (OB_FAIL(check_part_option_map_.get_refactored(tablegroup_id, table_in_map))) { - //set into map while not in check_part_option_map_ + //set to the map while not in check_part_option_map_ if (OB_HASH_NOT_EXIST == ret) { - ObTableSchema *new_table_schema = NULL; - if (OB_FAIL(ObSchemaUtils::alloc_schema(allocator_, table, new_table_schema))) { - LOG_WARN("alloc schema failed", K(ret), K(table)); - } else if (OB_FAIL(check_part_option_map_.set_refactored(tablegroup_id, new_table_schema))) { - LOG_WARN("set table_schema in hashmap fail", K(ret), K(tablegroup_id), K(new_table_schema)); + if (OB_FAIL(schema_guard.get_primary_table_schema_in_tablegroup(tenant_id, tablegroup_id, primary_table_schema))) { + LOG_WARN("fail to get primary table schema in tablegroup", KR(ret), K(tablegroup_id)); + } else if (OB_ISNULL(primary_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("primary table schema is NULL", KR(ret), K(tenant_id), K(tablegroup_id)); + } else if (OB_FAIL(check_part_option_map_.set_refactored(tablegroup_id, primary_table_schema))) { + LOG_WARN("set table_schema in hashmap fail", KR(ret), K(tablegroup_id), KPC(primary_table_schema)); } } else { - LOG_WARN("check tablegroup_id in hashmap fail", K(ret), K(tablegroup_id)); + LOG_WARN("check tablegroup_id in hashmap fail", KR(ret), K(tablegroup_id)); } } else if (OB_ISNULL(table_in_map)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("table_in_map is null ptr", K(ret)); - } else if (OB_FAIL(check_if_part_option_equal(*table_in_map, table, is_matched))) { - LOG_WARN("check if part option equal fail", K(ret), KPC(table_in_map), K(table)); + LOG_WARN("table_is_map is NULL", KR(ret), K(tablegroup_id)); + } else if (OB_FAIL(ObSimpleTableSchemaV2::compare_partition_option(table, *table_in_map, check_sub_part, is_matched, &user_error))) { + LOG_WARN("fail to check partition option", KR(ret), K(table), KPC(table_in_map)); } } else { - const ObTablegroupSchema *tablegroup = NULL; - if (OB_FAIL(schema_guard.get_tablegroup_schema(tenant_id, tablegroup_id, tablegroup))) { - LOG_WARN("fail to get tablegroup schema", K(ret), K(tenant_id), KT(tablegroup_id)); - } else if (OB_ISNULL(tablegroup)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablegroup schema is null", K(ret), KT(tablegroup_id)); - } else if (PARTITION_LEVEL_ZERO == tablegroup->get_part_level()) { - if (PARTITION_LEVEL_ZERO == table.get_part_level()) { - // no need to check partition_option of nonpartitioned table - } else if (1 != table.get_all_part_num()) { - is_matched = false; - } else if (OB_FAIL(check_part_option_map_.get_refactored(tablegroup_id, table_in_map))) { - //set to the map while not in check_part_option_map_ - if (OB_HASH_NOT_EXIST == ret) { - if (OB_FAIL(check_part_option_map_.set_refactored(tablegroup_id, &table))) { - LOG_WARN("set table_schema in hashmap fail", K(ret), K(tablegroup_id), K(table)); - } - } else { - LOG_WARN("check tablegroup_id in hashmap fail", K(ret), K(tablegroup_id)); - } - } else if (OB_FAIL(check_if_part_option_equal_v2(table, *table_in_map, is_matched))) { - LOG_WARN("check if part option equal fail", K(ret), KPC(table_in_map), K(table)); - } - } else { - if (OB_FAIL(check_if_part_option_equal_v2(table, *tablegroup, is_matched))) { - LOG_WARN("check if part option equal fail", K(ret), KPC(tablegroup), K(table)); - } - } + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sharding type not suit", KR(ret), KPC(tablegroup)); } if (OB_FAIL(ret) || is_matched) { //skip } else if (OB_FAIL(part_option_not_match_set_.set_refactored(tablegroup_id))) { - LOG_WARN("set tablegroup_id in hashset fail", K(ret)); + LOG_WARN("set tablegroup_id in hashset fail", KR(ret)); + } else if (OB_ISNULL(table_in_map)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table_is_map is NULL", KR(ret), K(tablegroup_id)); } else { LOG_INFO("tables in one tablegroup have different part/subpart option", - K(tablegroup_id), "table_id", table.get_table_id()); + K(tablegroup_id), "table_id", table.get_table_id(), K(user_error), K(table_in_map->get_table_id())); } } return ret; } -// For tablegroups created before 2.0, partition_type and partition_num of tables in tablegroup should be equal -int ObTableGroupChecker::check_if_part_option_equal(const ObTableSchema &t1, const ObTableSchema &t2, bool &is_matched) -{ - int ret = OB_SUCCESS; - is_matched = false; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("tablegroup checker is not init", K(ret)); - } else { - is_matched = t1.get_part_level() == t2.get_part_level() - && t1.get_part_option().get_part_func_type() == t2.get_part_option().get_part_func_type() - && t1.get_part_option().get_part_num() == t2.get_part_option().get_part_num() - && t1.get_sub_part_option().get_part_func_type() == t2.get_sub_part_option().get_part_func_type() - && t1.get_sub_part_option().get_part_num() == t2.get_sub_part_option().get_part_num(); - if (!is_matched) { - LOG_ERROR("tables in one tablegroup have different part/subpart option", - "table1_id", t1.get_table_id(), - "table1_part_level", t1.get_part_level(), - "table1_database_id", t1.get_database_id(), - "table1_tenant_id", t1.get_tenant_id(), - "table1_part_option", t1.get_part_option(), - "table1_subpart_option", t1.get_sub_part_option(), - "table2_id", t2.get_table_id(), - "table2_part_level", t2.get_part_level(), - "table2_database_id", t2.get_database_id(), - "table2_tenant_id", t2.get_tenant_id(), - "table2_part_option", t2.get_part_option(), - "table2_subpart_option", t2.get_sub_part_option()); - } - } - return ret; -} - -// For tablegroup create after 2.0, the check of partition_option is more strict. -// You need to check the partition mode, the number of partitions, the number of expression vectors and the value of the partition point -// FIXME:Support non templated subpartition -template -int ObTableGroupChecker::check_if_part_option_equal_v2(const ObTableSchema &table, const SCHEMA &schema, bool &is_matched) -{ - int ret = OB_SUCCESS; - is_matched = false; - bool is_oracle_mode = false; - bool schema_is_oracle_mode = false; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("tablegroup checker is not init", K(ret)); - } else if (OB_FAIL(table.check_if_oracle_compat_mode(is_oracle_mode))) { - LOG_WARN("fail to check oracle mode", KR(ret), K(table)); - } else if (OB_FAIL(schema.check_if_oracle_compat_mode(schema_is_oracle_mode))) { - LOG_WARN("fail to check oracle mode", KR(ret), K(schema)); - } else { - is_matched = is_oracle_mode == schema_is_oracle_mode - && table.get_part_level() == schema.get_part_level() - && (table.get_part_option().get_part_func_type() == schema.get_part_option().get_part_func_type() - || (is_key_part(table.get_part_option().get_part_func_type()) && is_key_part(schema.get_part_option().get_part_func_type()))) - && table.get_part_option().get_part_num() == schema.get_part_option().get_part_num() - && (table.get_sub_part_option().get_part_func_type() == schema.get_sub_part_option().get_part_func_type() - || (is_key_part(table.get_sub_part_option().get_part_func_type()) && is_key_part(schema.get_sub_part_option().get_part_func_type()))) - && table.get_sub_part_option().get_part_num() == schema.get_sub_part_option().get_part_num(); - // check expr value - if (!is_matched) { - // skip - } else if (PARTITION_LEVEL_ONE <= table.get_part_level()) { - if (table.is_key_part()) { - int64_t table_expr_num = OB_INVALID_INDEX; - int64_t schema_expr_num = OB_INVALID_INDEX; - if (OB_FAIL(table.calc_part_func_expr_num(table_expr_num))) { - LOG_WARN("fail to get table part_func_expr_num", K(ret)); - } else if (OB_FAIL(schema.calc_part_func_expr_num(schema_expr_num))) { - LOG_WARN("fail to get schema part_func_expr_num", K(ret)); - } - is_matched = (table_expr_num == schema_expr_num); - } else if (table.is_range_part() - || table.is_list_part()) { - if (OB_ISNULL(table.get_part_array()) - || OB_ISNULL(schema.get_part_array())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition_array is null", K(ret), K(schema), K(table)); - } else { - is_matched = true; - const int64_t table_part_num = table.get_part_option().get_part_num(); - const int64_t schema_part_num = schema.get_part_option().get_part_num(); - const ObPartitionFuncType part_func_type = table.get_part_option().get_part_func_type(); - for (int64_t i = 0; OB_SUCC(ret) && is_matched && i < table_part_num; i++) { - is_matched = false; - ObPartition *table_part = table.get_part_array()[i]; - for (int64_t j = 0; OB_SUCC(ret) && !is_matched && j < schema_part_num; j++) { - ObPartition *schema_part = schema.get_part_array()[j]; - if (OB_ISNULL(schema_part) || OB_ISNULL(table_part)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition is null", K(ret), KPC(schema_part), KPC(table_part)); - } else if (OB_FAIL(ObPartitionUtils::check_partition_value( - is_oracle_mode, *schema_part, *table_part, part_func_type, is_matched))) { - LOG_WARN("fail to check partition value", KPC(schema_part), KPC(table_part), K(part_func_type)); - } - } - } - } - } - } - if (OB_SUCC(ret) || !is_matched) { - // skip - } else if (PARTITION_LEVEL_TWO == table.get_part_level()) { - if (table.is_key_subpart()) { - int64_t table_expr_num = OB_INVALID_INDEX; - int64_t schema_expr_num = OB_INVALID_INDEX; - if (OB_FAIL(table.calc_subpart_func_expr_num(table_expr_num))) { - LOG_WARN("fail to get table subpart_func_expr_num", K(ret)); - } else if (OB_FAIL(schema.calc_subpart_func_expr_num(schema_expr_num))) { - LOG_WARN("fail to get schema subpart_func_expr_num", K(ret)); - } - is_matched = (table_expr_num == schema_expr_num); - } else if (table.is_range_subpart() - || table.is_list_subpart()) { - if (OB_ISNULL(table.get_def_subpart_array()) - || OB_ISNULL(schema.get_def_subpart_array())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition_array is null", K(ret), K(schema), K(table)); - } else { - is_matched = true; - const int64_t table_sub_part_num = table.get_sub_part_option().get_part_num(); - const int64_t schema_sub_part_num = schema.get_sub_part_option().get_part_num(); - const ObPartitionFuncType part_func_type = table.get_sub_part_option().get_part_func_type(); - for (int64_t i = 0; OB_SUCC(ret) && is_matched && i < table_sub_part_num; i++) { - is_matched = false; - ObSubPartition *table_part = table.get_def_subpart_array()[i]; - for (int64_t j = 0; OB_SUCC(ret) && !is_matched && j < schema_sub_part_num; j++) { - ObSubPartition *schema_part = schema.get_def_subpart_array()[j]; - if (OB_ISNULL(schema_part) || OB_ISNULL(table_part)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition is null", K(ret), KPC(schema_part), KPC(table_part)); - } else if (OB_FAIL(ObPartitionUtils::check_partition_value( - is_oracle_mode, *schema_part, *table_part, part_func_type, is_matched))) { - LOG_WARN("fail to check partition value", KPC(schema_part), KPC(table_part), K(part_func_type)); - } - } - } - } - } - } - } - if (!is_matched) { - LOG_ERROR("table & tablegroup partition option not match", K(ret), K(table), K(schema)); - } - return ret; -} //////////////////////////////////////////////////////////////// ObInspector::ObInspector(ObRootService &rs) :ObAsyncTimerTask(rs.get_inspect_task_queue()), diff --git a/src/rootserver/ob_root_inspection.h b/src/rootserver/ob_root_inspection.h index 7ee78c037..1215b0044 100644 --- a/src/rootserver/ob_root_inspection.h +++ b/src/rootserver/ob_root_inspection.h @@ -19,7 +19,6 @@ #include "lib/string/ob_sql_string.h" #include "lib/string/ob_fixed_length_string.h" #include "lib/thread/ob_work_queue.h" -#include "share/backup/ob_backup_info_mgr.h" #include "share/ob_virtual_table_projector.h" #include "share/ob_common_rpc_proxy.h" #include "share/ob_schema_status_proxy.h" @@ -95,14 +94,11 @@ public: virtual const char* get_task_name() const { return "tablegroup_checker"; }; private: int inspect_(const uint64_t tenant_id, bool &passed); - int check_part_option(const share::schema::ObTableSchema &table, + int check_part_option(const share::schema::ObSimpleTableSchemaV2 &table, share::schema::ObSchemaGetterGuard &schema_guard); - int check_if_part_option_equal(const share::schema::ObTableSchema &t1, const share::schema::ObTableSchema &t2, bool &is_matched); - template - int check_if_part_option_equal_v2(const share::schema::ObTableSchema &table, const SCHEMA &schema, bool &is_matched); private: static const int TABLEGROUP_BUCKET_NUM = 1024; - typedef common::hash::ObHashMap ObTableGroupCheckInfoMap; + typedef common::hash::ObHashMap ObTableGroupCheckInfoMap; share::schema::ObMultiVersionSchemaService &schema_service_; ObTableGroupCheckInfoMap check_part_option_map_; common::hash::ObHashSet part_option_not_match_set_; diff --git a/src/rootserver/ob_root_service.cpp b/src/rootserver/ob_root_service.cpp old mode 100644 new mode 100755 index 87d92fa93..9d1b78f20 --- a/src/rootserver/ob_root_service.cpp +++ b/src/rootserver/ob_root_service.cpp @@ -97,6 +97,7 @@ #include "share/restore/ob_physical_restore_table_operator.h"//ObPhysicalRestoreTableOperator #include "share/ob_cluster_event_history_table_operator.h"//CLUSTER_EVENT_INSTANCE #include "share/scn.h" +#include "rootserver/backup/ob_backup_proxy.h" //ObBackupServiceProxy #include "logservice/palf_handle_guard.h" #include "logservice/ob_log_service.h" #include "rootserver/ob_heartbeat_service.h" @@ -650,14 +651,10 @@ ObRootService::ObRootService() update_rs_list_timer_task_(*this), update_all_server_config_task_(*this), baseline_schema_version_(0), - backup_service_(), - backup_task_scheduler_(), - archive_service_(), start_service_time_(0), rs_status_(), fail_count_(0), schema_history_recycler_(), - backup_lease_service_(), disaster_recovery_task_executor_(), disaster_recovery_task_mgr_(), global_ctx_task_(*this) @@ -737,18 +734,6 @@ int ObRootService::fake_init(ObServerConfig &config, } } - if (OB_SUCC(ret)) { - if (OB_FAIL(backup_task_scheduler_.init(&zone_manager_, &rpc_proxy_, &backup_service_, sql_proxy_, backup_lease_service_))) { - LOG_WARN("fail to init backup task scheduler", K(ret)); - } - } - - if (OB_SUCC(ret)) { - if (OB_FAIL(backup_service_.init(sql_proxy_, rpc_proxy_, *schema_service_, backup_lease_service_, backup_task_scheduler_))) { - LOG_WARN("fail to init backup service", K(ret)); - } - } - if (OB_SUCC(ret)) { if (OB_FAIL(dbms_job::ObDBMSJobMaster::get_instance() .init(&sql_proxy_, schema_service_))) { @@ -899,28 +884,10 @@ int ObRootService::init(ObServerConfig &config, FLOG_WARN("init THE_RS_JOB_TABLE failed", KR(ret)); } else if (OB_FAIL(ddl_scheduler_.init(this))) { FLOG_WARN("init ddl task scheduler failed", KR(ret)); - } else if (OB_FAIL(backup_lease_service_.init(self_addr_, sql_proxy))) { - // backup lease service需要rs切走以后将lease的leader addr重置调,所以不能用sql_proxy_ - FLOG_WARN("init backup lease service failed", KR(ret)); - } else if (OB_FAIL(backup_task_scheduler_.init(&zone_manager_, &rpc_proxy_, - &backup_service_, sql_proxy_, backup_lease_service_))) { - FLOG_WARN("init backup task scheduler failed", KR(ret)); - } else if (OB_FAIL(backup_service_.init(sql_proxy_, rpc_proxy_, *schema_service_, - backup_lease_service_, backup_task_scheduler_))) { - FLOG_WARN("init backup service failed", KR(ret)); - } else if (OB_FAIL(backup_lease_service_.register_mgr(backup_service_))) { - FLOG_WARN("register log backup mgr failed", KR(ret)); - } else if (OB_FAIL(archive_service_.init(zone_manager_, unit_manager_, schema_service_, - rpc_proxy_, sql_proxy_, backup_lease_service_))) { - FLOG_WARN("init archive_service_ failed", KR(ret)); - } else if (OB_FAIL(backup_lease_service_.register_scheduler(archive_service_))) { - FLOG_WARN("register archive_service_ failed", KR(ret)); } else if (OB_FAIL(schema_history_recycler_.init(*schema_service_, zone_manager_, sql_proxy_))) { FLOG_WARN("fail to init schema history recycler failed", KR(ret)); - } else if (OB_FAIL(backup_lease_service_.start())) { - FLOG_WARN("start backup lease task failed", KR(ret)); } else if (OB_FAIL(dbms_job::ObDBMSJobMaster::get_instance().init(&sql_proxy_, schema_service_))) { FLOG_WARN("init ObDBMSJobMaster failed", KR(ret)); @@ -962,14 +929,6 @@ void ObRootService::destroy() } } - FLOG_INFO("start destroy archive_service_"); - if (OB_FAIL(archive_service_.destroy())) { - FLOG_INFO("archive_service_ destory failed", KR(ret)); - fail_ret = OB_SUCCESS == fail_ret ? ret : fail_ret; - } else { - FLOG_INFO("finish destroy archive_service_"); - } - if (OB_FAIL(lost_replica_checker_.destroy())) { FLOG_WARN("lost replica checker failed", KR(ret)); fail_ret = OB_SUCCESS == fail_ret ? ret : fail_ret; @@ -1018,26 +977,11 @@ void ObRootService::destroy() FLOG_INFO("heartbeat checker destroy"); } - if (OB_FAIL(backup_task_scheduler_.destroy())) { - FLOG_WARN("root backup task scheduler destroy failed", KR(ret)); - fail_ret = OB_SUCCESS == fail_ret ? ret : fail_ret; - } else { - FLOG_INFO("root backup task scheduler destroy"); - } - - if (OB_FAIL(backup_service_.destroy())) { - FLOG_WARN("root backup mgr destroy failed", KR(ret)); - fail_ret = OB_SUCCESS == fail_ret ? ret : fail_ret; - } else { - FLOG_INFO("root backup mgr destroy"); - } - - FLOG_INFO("start destroy backup_lease_service_"); - backup_lease_service_.destroy(); - FLOG_INFO("finish destroy backup_lease_service_"); + ROOTSERVICE_EVENT_INSTANCE.destroy(); + FLOG_INFO("event table operator destroy"); dbms_job::ObDBMSJobMaster::get_instance().destroy(); - FLOG_INFO("ObDBMSJobMaster destory"); + FLOG_INFO("ObDBMSJobMaster destroy"); if (OB_FAIL(disaster_recovery_task_mgr_.destroy())) { @@ -1048,7 +992,7 @@ void ObRootService::destroy() } dbms_scheduler::ObDBMSSchedJobMaster::get_instance().destroy(); - FLOG_INFO("ObDBMSSchedJobMaster destory"); + FLOG_INFO("ObDBMSSchedJobMaster destroy"); TG_DESTROY(lib::TGDefIDs::GlobalCtxTimer); FLOG_INFO("global ctx timer destroyed"); @@ -1246,10 +1190,6 @@ int ObRootService::stop() FLOG_INFO("empty_server_checker stop"); lost_replica_checker_.stop(); FLOG_INFO("lost_replica_checker stop"); - backup_task_scheduler_.stop(); - FLOG_INFO("backup backup task scheduler stop"); - backup_lease_service_.stop_lease(); - FLOG_INFO("backup lease service stop"); thread_checker_.stop(); FLOG_INFO("rs_monitor_check : thread_checker stop"); schema_history_recycler_.stop(); @@ -1260,18 +1200,12 @@ int ObRootService::stop() FLOG_INFO("ddl task scheduler stop"); dbms_job::ObDBMSJobMaster::get_instance().stop(); FLOG_INFO("dbms job master stop"); - backup_task_scheduler_.stop(); - FLOG_INFO("backup_task_scheduler_ stop"); - backup_service_.stop(); - FLOG_INFO("backup_mgr stop"); disaster_recovery_task_mgr_.stop(); FLOG_INFO("disaster_recovery_task_mgr stop"); dbms_scheduler::ObDBMSSchedJobMaster::get_instance().stop(); FLOG_INFO("dbms sched job master stop"); TG_STOP(lib::TGDefIDs::GlobalCtxTimer); FLOG_INFO("global ctx timer stop"); - archive_service_.stop(); - FLOG_INFO("archive service stop"); } } @@ -1290,8 +1224,6 @@ void ObRootService::wait() FLOG_INFO("start to wait all thread exit"); root_balancer_.wait(); FLOG_INFO("root balancer exit success"); - backup_lease_service_.wait_lease(); - FLOG_INFO("log archive exit success"); empty_server_checker_.wait(); FLOG_INFO("empty server checker exit success"); lost_replica_checker_.wait(); @@ -1308,17 +1240,10 @@ void ObRootService::wait() FLOG_INFO("inspect queue exit success"); ddl_scheduler_.wait(); FLOG_INFO("ddl task scheduler exit success"); - backup_task_scheduler_.wait(); - FLOG_INFO("root backup task scheduler exit success"); - backup_service_.wait(); - FLOG_INFO("root backup mgr exit success"); disaster_recovery_task_mgr_.wait(); FLOG_INFO("rebalance task mgr exit success"); TG_WAIT(lib::TGDefIDs::GlobalCtxTimer); FLOG_INFO("global ctx timer exit success"); - archive_service_.wait(); - FLOG_INFO("archive service exit success"); - backup_task_scheduler_.reuse(); ObUpdateRsListTask::clear_lock(); THE_RS_JOB_TABLE.reset_max_job_id(); int64_t cost = ObTimeUtility::current_time() - start_time; @@ -4716,7 +4641,7 @@ int ObRootService::calc_column_checksum_repsonse(const obrpc::ObCalcColumnChecks ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), K(arg)); } else if (OB_FAIL(ddl_scheduler_.on_column_checksum_calc_reply( - arg.tablet_id_, ObDDLTaskKey(arg.target_table_id_, arg.schema_version_), arg.ret_code_))) { + arg.tablet_id_, ObDDLTaskKey(arg.tenant_id_, arg.target_table_id_, arg.schema_version_), arg.ret_code_))) { LOG_WARN("handle column checksum calc response failed", K(ret), K(arg)); } return ret; @@ -5056,23 +4981,6 @@ int ObRootService::do_restart() FLOG_INFO("success to init sequenxe id"); } - if (FAILEDx(backup_task_scheduler_.start())) { - FLOG_WARN("backup_task_scheduler_ start failed", KR(ret)); - } else { - FLOG_INFO("success to start backup_task_scheduler_"); - } - - if (FAILEDx(backup_lease_service_.start_lease())) { - FLOG_WARN("backup_lease_service_ start failed", KR(ret)); - } else { - FLOG_INFO("success to start backup_lease_service_"); - } - - if (FAILEDx(archive_service_.start())) { - FLOG_WARN("archive service start failed", KR(ret)); - } else { - FLOG_INFO("success to start archive service"); - } if (FAILEDx(disaster_recovery_task_mgr_.start())) { @@ -9062,6 +8970,52 @@ int ObRootService::set_config_pre_hook(obrpc::ObAdminSetConfigArg &arg) ret = OB_INVALID_ARGUMENT; LOG_WARN("config invalid", KR(ret), K(*item)); } + } else if (0 == STRCMP(item->name_.ptr(), PARTITION_BALANCE_SCHEDULE_INTERVAL)) { + const int64_t DEFAULT_BALANCER_IDLE_TIME = 10 * 1000 * 1000L; // 10s + for (int i = 0; i < item->tenant_ids_.count() && valid; i++) { + const uint64_t tenant_id = item->tenant_ids_.at(i); + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); + int64_t balancer_idle_time = tenant_config.is_valid() ? tenant_config->balancer_idle_time : DEFAULT_BALANCER_IDLE_TIME; + int64_t interval = ObConfigTimeParser::get(item->value_.ptr(), valid); + if (valid) { + if (0 == interval) { + valid = true; + } else if (interval >= balancer_idle_time) { + valid = true; + } else { + valid = false; + char err_msg[DEFAULT_BUF_LENGTH]; + (void)snprintf(err_msg, sizeof(err_msg), "partition_balance_schedule_interval of tenant %ld, " + "it should not be less than balancer_idle_time", tenant_id); + LOG_USER_ERROR(OB_INVALID_ARGUMENT, err_msg); + } + } + if (!valid) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("config invalid", KR(ret), K(*item), K(balancer_idle_time), K(tenant_id)); + } + } + } else if (0 == STRCMP(item->name_.ptr(), BALANCER_IDLE_TIME)) { + const int64_t DEFAULT_PARTITION_BALANCE_SCHEDULE_INTERVAL = 2 * 3600 * 1000 * 1000L; // 2h + for (int i = 0; i < item->tenant_ids_.count() && valid; i++) { + const uint64_t tenant_id = item->tenant_ids_.at(i); + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); + int64_t interval = tenant_config.is_valid() + ? tenant_config->partition_balance_schedule_interval + : DEFAULT_PARTITION_BALANCE_SCHEDULE_INTERVAL; + int64_t idle_time = ObConfigTimeParser::get(item->value_.ptr(), valid); + if (valid && (idle_time > interval)) { + valid = false; + char err_msg[DEFAULT_BUF_LENGTH]; + (void)snprintf(err_msg, sizeof(err_msg), "balancer_idle_time of tenant %ld, " + "it should not be longer than partition_balance_schedule_interval", tenant_id); + LOG_USER_ERROR(OB_INVALID_ARGUMENT, err_msg); + } + if (!valid) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("config invalid", KR(ret), K(*item), K(interval), K(tenant_id)); + } + } } } return ret; @@ -9438,10 +9392,8 @@ int ObRootService::handle_archive_log(const obrpc::ObArchiveLogArg &arg) if (!inited_) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); - } else if (arg.enable_ && OB_FAIL(archive_service_.open_archive_mode(arg.tenant_id_, arg.archive_tenant_ids_))) { - LOG_WARN("failed to open archive mode", K(ret), K(arg)); - } else if (!arg.enable_ && OB_FAIL(archive_service_.close_archive_mode(arg.tenant_id_, arg.archive_tenant_ids_))) { - LOG_WARN("failed to close archive mode", K(ret), K(arg)); + } else if (OB_FAIL(ObBackupServiceProxy::handle_archive_log(arg))) { + LOG_WARN("failed to handle archive log", K(ret)); } return ret; } @@ -9449,11 +9401,10 @@ int ObRootService::handle_archive_log(const obrpc::ObArchiveLogArg &arg) int ObRootService::handle_backup_database(const obrpc::ObBackupDatabaseArg &in_arg) { int ret = OB_SUCCESS; - obrpc::ObBackupDatabaseArg arg = in_arg; if (!inited_) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); - } else if (OB_FAIL(backup_service_.handle_backup_database(in_arg))) { + } else if (OB_FAIL(ObBackupServiceProxy::handle_backup_database(in_arg))) { LOG_WARN("failed to handle backup database", K(ret), K(in_arg)); } FLOG_INFO("handle_backup_database", K(ret), K(in_arg)); @@ -9569,7 +9520,7 @@ int ObRootService::handle_backup_delete(const obrpc::ObBackupCleanArg &arg) if (!inited_) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); - } else if (OB_FAIL(backup_service_.handle_backup_delete(arg))) { + } else if (OB_FAIL(ObBackupServiceProxy::handle_backup_delete(arg))) { LOG_WARN("failed to handle backup delete", K(ret), K(arg)); } return ret; @@ -9581,7 +9532,7 @@ int ObRootService::handle_delete_policy(const obrpc::ObDeletePolicyArg &arg) if (!inited_) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); - } else if (OB_FAIL(backup_service_.handle_delete_policy(arg))) { + } else if (OB_FAIL(ObBackupServiceProxy::handle_delete_policy(arg))) { LOG_WARN("failed to handle delete policy", K(ret), K(arg)); } return ret; @@ -9597,7 +9548,7 @@ int ObRootService::handle_backup_database_cancel( } else if (ObBackupManageArg::CANCEL_BACKUP != arg.type_) { ret = OB_INVALID_ARGUMENT; LOG_WARN("handle backup database cancel get invalid argument", K(ret), K(arg)); - } else if (OB_FAIL(backup_service_.handle_backup_database_cancel(arg.tenant_id_, arg.managed_tenant_ids_))) { + } else if (OB_FAIL(ObBackupServiceProxy::handle_backup_database_cancel(arg))) { LOG_WARN("failed to start schedule backup cancel", K(ret), K(arg)); } return ret; @@ -9640,43 +9591,8 @@ int ObRootService::handle_cancel_backup_backup(const obrpc::ObBackupManageArg &a int ObRootService::handle_cancel_all_backup_force(const obrpc::ObBackupManageArg &arg) { - int ret = OB_SUCCESS; - - FLOG_WARN("start cancel all backup force"); - // clear backup_dest and backup_backup_dest in GCONF - ObSqlString sql; - int64_t affected_rows = -1; - if (OB_FAIL(sql.assign_fmt("alter system set backup_dest=''"))) { - LOG_WARN("failed to clear backup dest", K(ret)); - } else if (OB_FAIL(sql_proxy_.write(sql.ptr(), affected_rows))) { - LOG_WARN("failed to clear backup dest", K(ret), K(sql)); - } else { - LOG_WARN("succeed to clear backup dest"); - } - - ROOTSERVICE_EVENT_ADD("root_service", "clear_backup_dest", "result", ret, K_(self_addr)); - - if (OB_SUCC(ret)) { - if (OB_FAIL(sql.assign_fmt("alter system set backup_backup_dest=''"))) { - LOG_WARN("failed to clear backup backup dest", K(ret)); - } else if (OB_FAIL(sql_proxy_.write(sql.ptr(), affected_rows))) { - LOG_WARN("failed to clear backup backup dest", K(ret), K(sql)); - } else { - LOG_WARN("succeed to clear backup backup dest"); - } - - ROOTSERVICE_EVENT_ADD("root_service", "clear_backup_backup_dest", "result", ret, K_(self_addr)); - } - - ROOTSERVICE_EVENT_ADD("root_service", "force_cancel_backup", "result", ret, K_(self_addr)); - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(backup_lease_service_.force_cancel(arg.tenant_id_))) { - LOG_WARN("failed to force stop", K(ret), K(arg)); - } - - FLOG_WARN("end cancel all backup force", K(ret)); - + int ret = OB_NOT_SUPPORTED; + LOG_ERROR("not support now", K(ret), K(arg)); return ret; } @@ -9745,7 +9661,7 @@ int ObRootService::build_ddl_single_replica_response(const obrpc::ObDDLBuildSing ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), K(arg)); } else if (OB_FAIL(ddl_scheduler_.on_sstable_complement_job_reply( - arg.tablet_id_/*source tablet id*/, ObDDLTaskKey(arg.dest_schema_id_, arg.schema_version_), arg.snapshot_version_, arg.execution_id_, arg.ret_code_, info))) { + arg.tablet_id_/*source tablet id*/, ObDDLTaskKey(arg.tenant_id_, arg.dest_schema_id_, arg.schema_version_), arg.snapshot_version_, arg.execution_id_, arg.ret_code_, info))) { LOG_WARN("handle column checksum calc response failed", K(ret), K(arg)); } return ret; @@ -9855,32 +9771,6 @@ int ObRootService::flush_opt_stat_monitoring_info(const obrpc::ObFlushOptStatArg return ret; } -int ObRootService::receive_backup_clean_over(const obrpc::ObBackupTaskRes &res) -{ - int ret = OB_SUCCESS; - ObBackupCleanLSTask task; - FLOG_INFO("receive backup clean over", K(res)); - if (OB_FAIL(task.build_from_res(res, BackupJobType::BACKUP_CLEAN_JOB))) { - LOG_WARN("failed to build task from res rpc", K(ret), K(res)); - } else if (OB_FAIL(backup_task_scheduler_.execute_over(task, res.result_))) { - LOG_WARN("failed to remove task from scheduler", K(ret), K(res), K(task)); - } - return ret; -} - -int ObRootService::receive_backup_over(const obrpc::ObBackupTaskRes &res) -{ - int ret = OB_SUCCESS; - ObBackupDataLSTask task; - FLOG_INFO("receive backup data over", K(res)); - if (OB_FAIL(task.build_from_res(res, BackupJobType::BACKUP_DATA_JOB))) { - LOG_WARN("failed to build task from res rpc", K(ret), K(res)); - } else if (OB_FAIL(backup_task_scheduler_.execute_over(task, res.result_))) { - LOG_WARN("failed to remove task from scheduler", K(ret), K(res), K(task)); - } - return ret; -} - int ObRootService::clean_global_context() { int ret = OB_SUCCESS; diff --git a/src/rootserver/ob_root_service.h b/src/rootserver/ob_root_service.h index ca637d1aa..f50fc4a25 100644 --- a/src/rootserver/ob_root_service.h +++ b/src/rootserver/ob_root_service.h @@ -16,7 +16,6 @@ #include "lib/net/ob_addr.h" #include "lib/thread/ob_work_queue.h" -#include "share/backup/ob_backup_info_mgr.h" #include "share/ob_common_rpc_proxy.h" #include "share/ob_tenant_id_schema_version.h" #include "share/ob_inner_config_root_addr.h" @@ -46,15 +45,11 @@ #include "rootserver/ob_upgrade_executor.h" #include "rootserver/ob_upgrade_storage_format_version_executor.h" #include "rootserver/ob_create_inner_schema_executor.h" -#include "rootserver/backup/ob_backup_service.h" -#include "rootserver/backup/ob_backup_task_scheduler.h" #include "rootserver/ob_update_rs_list_task.h" #include "rootserver/ob_schema_history_recycler.h" -#include "rootserver/backup/ob_backup_lease_service.h" #include "rootserver/ddl_task/ob_ddl_scheduler.h" #include "share/ls/ob_ls_info.h" #include "share/ls/ob_ls_table_operator.h" -#include "rootserver/backup/ob_archive_scheduler_service.h" #include "rootserver/ob_disaster_recovery_task_mgr.h" #include "rootserver/ob_disaster_recovery_task_executor.h" #include "rootserver/ob_empty_server_checker.h" @@ -403,7 +398,6 @@ public: // misc get functions share::ObLSTableOperator &get_lst_operator() { return *lst_operator_; } share::schema::ObMultiVersionSchemaService &get_schema_service() { return *schema_service_; } - ObBackupTaskScheduler &get_backup_task_scheduler() { return backup_task_scheduler_;} ObServerManager &get_server_mgr() { return server_manager_; } ObZoneManager &get_zone_mgr() { return zone_manager_; } ObUnitManager &get_unit_mgr() { return unit_manager_; } @@ -441,6 +435,7 @@ public: int fetch_location(const obrpc::ObFetchLocationArg &arg, obrpc::ObFetchLocationResult &res); int merge_finish(const obrpc::ObMergeFinishArg &arg); + // 4.0 backup // balance over int receive_backup_over(const obrpc::ObBackupTaskRes &res); @@ -954,16 +949,11 @@ private: ObUpdateAllServerConfigTask update_all_server_config_task_; int64_t baseline_schema_version_; - // backup - ObBackupService backup_service_; - ObBackupTaskScheduler backup_task_scheduler_; - ObArchiveSchedulerService archive_service_; int64_t start_service_time_; ObRsStatus rs_status_; int64_t fail_count_; ObSchemaHistoryRecycler schema_history_recycler_; - ObBackupLeaseService backup_lease_service_; // Disaster Recovery related ObDRTaskExecutor disaster_recovery_task_executor_; ObDRTaskMgr disaster_recovery_task_mgr_; diff --git a/src/rootserver/ob_rootservice_util_checker.cpp b/src/rootserver/ob_rootservice_util_checker.cpp index c184d446b..8c36484a1 100644 --- a/src/rootserver/ob_rootservice_util_checker.cpp +++ b/src/rootserver/ob_rootservice_util_checker.cpp @@ -20,7 +20,8 @@ ObRootServiceUtilChecker::ObRootServiceUtilChecker(volatile bool &stop) : inited_(false), stop_(stop), migrate_unit_finish_checker_(stop), - alter_locality_finish_checker_(stop) + alter_locality_finish_checker_(stop), + shrink_resource_pool_checker_(stop) { } @@ -57,6 +58,9 @@ int ObRootServiceUtilChecker::init( sql_proxy, lst_operator))) { LOG_WARN("fail to init alter locality finish checker", KR(ret)); + } else if (OB_FAIL(shrink_resource_pool_checker_.init(&schema_service, + &unit_mgr, lst_operator, sql_proxy))) { + LOG_WARN("failed to init shrink resource pool", KR(ret)); } else { inited_ = true; } @@ -79,6 +83,10 @@ int ObRootServiceUtilChecker::rootservice_util_check() if (OB_SUCCESS != (tmp_ret = alter_locality_finish_checker_.check())) { LOG_WARN("fail to check alter locality finish", KR(tmp_ret)); } + + if (OB_TMP_FAIL(shrink_resource_pool_checker_.check())) { + LOG_WARN("failed to check shrink resource pool", KR(tmp_ret)); + } } return ret; } diff --git a/src/rootserver/ob_rootservice_util_checker.h b/src/rootserver/ob_rootservice_util_checker.h index e659393b2..bb869cafe 100644 --- a/src/rootserver/ob_rootservice_util_checker.h +++ b/src/rootserver/ob_rootservice_util_checker.h @@ -16,6 +16,8 @@ #include "lib/net/ob_addr.h" #include "ob_migrate_unit_finish_checker.h" #include "ob_alter_locality_finish_checker.h" +#include "ob_shrink_resource_pool_checker.h" + namespace oceanbase { namespace rootserver @@ -43,6 +45,8 @@ private: volatile bool &stop_; ObMigrateUnitFinishChecker migrate_unit_finish_checker_; ObAlterLocalityFinishChecker alter_locality_finish_checker_; + ObShrinkResourcePoolChecker shrink_resource_pool_checker_; + private: DISALLOW_COPY_AND_ASSIGN(ObRootServiceUtilChecker); }; diff --git a/src/rootserver/ob_rs_async_rpc_proxy.h b/src/rootserver/ob_rs_async_rpc_proxy.h index da2c1d334..ec5cb26be 100644 --- a/src/rootserver/ob_rs_async_rpc_proxy.h +++ b/src/rootserver/ob_rs_async_rpc_proxy.h @@ -70,6 +70,8 @@ RPC_F(obrpc::OB_GET_LEADER_LOCATIONS, obrpc::ObGetLeaderLocationsArg, RPC_F(obrpc::OB_DDL_CHECK_TABLET_MERGE_STATUS, obrpc::ObDDLCheckTabletMergeStatusArg, obrpc::ObDDLCheckTabletMergeStatusResult, ObCheckTabletMergeStatusProxy); RPC_F(obrpc::OB_REFRESH_TENANT_INFO, obrpc::ObRefreshTenantInfoArg, obrpc::ObRefreshTenantInfoRes, ObRefreshTenantInfoProxy); +RPC_F(obrpc::OB_GET_LS_REPLAYED_SCN, obrpc::ObGetLSReplayedScnArg, + obrpc::ObGetLSReplayedScnRes, ObGetLSReplayedScnProxy); RPC_F(obrpc::OB_SEND_HEARTBEAT, share::ObHBRequest, share::ObHBResponse, ObSendHeartbeatProxy); RPC_F(obrpc::OB_GET_SERVER_RESOURCE_INFO, obrpc::ObGetServerResourceInfoArg, obrpc::ObGetServerResourceInfoResult, ObGetServerResourceInfoProxy); RPC_F(obrpc::OB_NOTIFY_SWITCH_LEADER, obrpc::ObNotifySwitchLeaderArg, diff --git a/src/rootserver/ob_rs_job_table_operator.cpp b/src/rootserver/ob_rs_job_table_operator.cpp index 61e323c73..67a71d1fd 100644 --- a/src/rootserver/ob_rs_job_table_operator.cpp +++ b/src/rootserver/ob_rs_job_table_operator.cpp @@ -57,7 +57,6 @@ static const char* job_type_str_array[JOB_TYPE_MAX] = { "ROLLBACK_ALTER_TENANT_LOCALITY", "MIGRATE_UNIT", "DELETE_SERVER", - "SHRINK_RESOURCE_POOL_UNIT_NUM", "SHRINK_RESOURCE_TENANT_UNIT_NUM", "RESTORE_TENANT", "UPGRADE_STORAGE_FORMAT_VERSION", diff --git a/src/rootserver/ob_rs_job_table_operator.h b/src/rootserver/ob_rs_job_table_operator.h index 22ae8dbd6..d48fc8a42 100644 --- a/src/rootserver/ob_rs_job_table_operator.h +++ b/src/rootserver/ob_rs_job_table_operator.h @@ -76,7 +76,6 @@ enum ObRsJobType JOB_TYPE_ROLLBACK_ALTER_TENANT_LOCALITY, JOB_TYPE_MIGRATE_UNIT, JOB_TYPE_DELETE_SERVER, - JOB_TYPE_SHRINK_RESOURCE_POOL_UNIT_NUM, JOB_TYPE_SHRINK_RESOURCE_TENANT_UNIT_NUM, JOB_TYPE_RESTORE_TENANT, JOB_TYPE_UPGRADE_STORAGE_FORMAT_VERSION, diff --git a/src/rootserver/ob_rs_rpc_processor.h b/src/rootserver/ob_rs_rpc_processor.h index 4cb95828b..9cd1a03b7 100644 --- a/src/rootserver/ob_rs_rpc_processor.h +++ b/src/rootserver/ob_rs_rpc_processor.h @@ -301,9 +301,6 @@ DEFINE_LIMITED_RS_RPC_PROCESSOR(obrpc::OB_FETCH_ALIVE_SERVER, ObRpcFetchAliveSer // DEFINE_RS_RPC_PROCESSOR(obrpc::OB_FETCH_ACTIVE_SERVER_STATUS, ObRpcFetchActiveServerStatusP, fetch_active_server_status(arg_, result_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_DISASTER_RECOVERY_TASK_REPLY, ObRpcDisasterRecoveryTaskReplyP, disaster_recovery_task_reply(arg_)); -DEFINE_RS_RPC_PROCESSOR(obrpc::OB_BACKUP_LS_DATA_RES, ObRpcBackupDataResP, receive_backup_over(arg_)); -DEFINE_RS_RPC_PROCESSOR(obrpc::OB_BACKUP_COMPL_LOG_RES, ObRpcBackupComplLogResP, receive_backup_over(arg_)); -DEFINE_RS_RPC_PROCESSOR(obrpc::OB_DELETE_BACKUP_LS_TASK_RES, ObRpcBackupLSCleanResP, receive_backup_clean_over(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_BROADCAST_DS_ACTION, ObBroadcastDSActionP, broadcast_ds_action(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_FETCH_LOCATION, ObRpcFetchLocationP, fetch_location(arg_, result_)); diff --git a/src/rootserver/ob_schema_history_recycler.cpp b/src/rootserver/ob_schema_history_recycler.cpp index 57a647a4f..939794e14 100644 --- a/src/rootserver/ob_schema_history_recycler.cpp +++ b/src/rootserver/ob_schema_history_recycler.cpp @@ -12,7 +12,6 @@ #define USING_LOG_PREFIX RS #include "share/ob_schema_status_proxy.h" -#include "share/backup/ob_backup_info_mgr.h" #include "share/schema/ob_schema_mgr.h" #include "rootserver/ob_schema_history_recycler.h" #include "rootserver/ob_rs_async_rpc_proxy.h" @@ -567,31 +566,7 @@ int ObSchemaHistoryRecycler::get_recycle_schema_version_by_global_stat( } } } - if (OB_SUCC(ret)) { - // step 3. backup reserved_schema_version - ObBackupInfoMgr &bk_info = ObBackupInfoMgr::get_instance(); - if (OB_FAIL(check_inner_stat())) { - LOG_WARN("schema history recycler is stopped", KR(ret)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < tenant_ids.count(); i++) { - const uint64_t tenant_id = tenant_ids.at(i); - int64_t reserved_schema_version = OB_INVALID_VERSION; - bool is_backup = false; - if (OB_FAIL(bk_info.get_delay_delete_schema_version( - tenant_id, *schema_service_, is_backup, reserved_schema_version))) { - LOG_WARN("fail to get reserved schema version", KR(ret), K(tenant_id)); - } else if (is_backup && reserved_schema_version > 0) { - if (OB_FAIL(fill_recycle_schema_versions( - tenant_id, reserved_schema_version, recycle_schema_versions))) { - LOG_WARN("fail to fill recycle schema versions", - KR(ret), K(tenant_id), K(reserved_schema_version)); - } - } - LOG_INFO("[SCHEMA_RECYCLE] get recycle schema version " - "by backup reserved schema version", - KR(ret), K(tenant_id), K(is_backup), K(reserved_schema_version)); - } - } + if (OB_SUCC(ret)) { // step 4. restore point // int64_t schema_version = 0; diff --git a/src/rootserver/ob_server_balancer.cpp b/src/rootserver/ob_server_balancer.cpp index ecb3a8cb3..5f4a106a2 100644 --- a/src/rootserver/ob_server_balancer.cpp +++ b/src/rootserver/ob_server_balancer.cpp @@ -24,6 +24,7 @@ #include "share/ob_all_server_tracer.h" #include "share/ob_server_table_operator.h" #include "rootserver/ob_heartbeat_service.h" +#include "share/ob_share_util.h" // ObShareUtil using namespace oceanbase::common; using namespace oceanbase::common::hash; @@ -114,7 +115,7 @@ int ObServerBalancer::tenant_group_balance() } else if (OB_FAIL(ObRootBalanceHelp::parse_balance_info( switch_config_str, balance_controller))) { LOG_WARN("fail to parse balance switch", K(ret), "balance switch", switch_config_str); - } else if (GCONF.is_rebalance_enabled() + } else if (ObShareUtil::is_tenant_enable_rebalance(OB_SYS_TENANT_ID) || balance_controller.at(ObRootBalanceHelp::ENABLE_SERVER_BALANCE)) { if (OB_FAIL(zone_mgr_->get_zone(ObZoneStatus::ACTIVE, zones))) { LOG_WARN("get_zone failed", "status", ObZoneStatus::ACTIVE, K(ret)); @@ -187,7 +188,7 @@ int ObServerBalancer::balance_servers() // When the server status changes, // try to adjust the unit on the server without configuration item control if (GCONF.is_rereplication_enabled() - || GCONF.is_rebalance_enabled() + || ObShareUtil::is_tenant_enable_rebalance(OB_SYS_TENANT_ID) || balance_controller.at(ObRootBalanceHelp::ENABLE_SERVER_BALANCE)) { if (OB_FAIL(distribute_for_server_status_change())) { LOG_WARN("fail to distribute for server status change", K(ret)); diff --git a/src/rootserver/ob_shrink_resource_pool_checker.cpp b/src/rootserver/ob_shrink_resource_pool_checker.cpp new file mode 100644 index 000000000..f4a9e4f07 --- /dev/null +++ b/src/rootserver/ob_shrink_resource_pool_checker.cpp @@ -0,0 +1,268 @@ +/** + * Copyright (c) 2021 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. + */ +#define USING_LOG_PREFIX RS + +#include "ob_shrink_resource_pool_checker.h" +#include "lib/container/ob_array.h" +#include "ob_unit_manager.h" +#include "ob_root_utils.h"//get_tenant_id +#include "ob_disaster_recovery_info.h"//DRLSInfo +#include "share/ls/ob_ls_status_operator.h"//ObLSStatusInfo +#include "share/ls/ob_ls_table_operator.h"//ls_operator_ ->get +#include "share/ls/ob_ls_info.h"//ObLSInfo + + +namespace oceanbase +{ +using namespace common; +using namespace share; +using namespace share::schema; +namespace rootserver +{ + +int ObShrinkResourcePoolChecker::check_stop() const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObShrinkResourcePoolChecker not init", KR(ret), K(is_inited_)); + } else if (is_stop_) { + ret = OB_CANCELED; + LOG_WARN("ObShrinkResourcePoolChecker stopped", KR(ret), K(is_stop_)); + } else {} // do nothing + return ret; +} + +int ObShrinkResourcePoolChecker::init( + share::schema::ObMultiVersionSchemaService *schema_service, + rootserver::ObUnitManager *unit_mgr, + share::ObLSTableOperator &lst_operator, + common::ObMySQLProxy &sql_proxy) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("ObShrinkResourcePoolChecker not init", KR(ret), K(is_inited_)); + } else if (OB_ISNULL(schema_service) + || OB_ISNULL(unit_mgr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), KP(schema_service), KP(unit_mgr)); + } else { + schema_service_ = schema_service; + unit_mgr_ = unit_mgr; + lst_operator_ = &lst_operator; + sql_proxy_ = &sql_proxy; + is_inited_ = true; + } + return ret; +} + +int ObShrinkResourcePoolChecker::check() +{ + int ret = OB_SUCCESS; + LOG_INFO("start check shrink resource pool"); + ObArray tenant_ids; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObShrinkResourcePoolChecker not init", KR(ret)); + } else if (OB_FAIL(check_stop())) { + LOG_WARN("ObShrinkResourcePoolChecker stop", KR(ret)); + } else if (OB_FAIL(ObTenantUtils::get_tenant_ids(schema_service_, tenant_ids))) { + LOG_WARN("fail to get tenant id array", KR(ret)); + } else { + DEBUG_SYNC(BEFORE_CHECK_SHRINK_RESOURCE_POOL); + int tmp_ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < tenant_ids.count(); ++i) { + const uint64_t tenant_id = tenant_ids.at(i); + if (!is_valid_tenant_id(tenant_id)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id)); + } else if (is_meta_tenant(tenant_id)) { + //nothing TODO + } else { + LOG_INFO("start check shrink resource pool", K(tenant_id)); + if (OB_TMP_FAIL(check_shrink_resource_pool_finished_by_tenant_(tenant_id))) { + LOG_WARN("fail to check shrink resource pool finish", KR(ret), KR(tmp_ret), K(tenant_id)); + } else {} // no more to do + } + } + } + LOG_INFO("finish check shrink resource pool", KR(ret)); + return ret; +} + +int ObShrinkResourcePoolChecker::check_shrink_resource_pool_finished_by_tenant_( + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + ObArray pool_ids; + bool in_shrinking = true; + bool is_finished = true; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObShrinkResourcePoolChecker not init", KR(ret)); + } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_FAIL(check_stop())) { + LOG_WARN("ObShrinkResourcePoolChecker stop", KR(ret)); + } else if (OB_ISNULL(sql_proxy_) || OB_ISNULL(unit_mgr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(sql_proxy_), KP(unit_mgr_)); + } else if (OB_FAIL(unit_mgr_->get_pool_ids_of_tenant(tenant_id, pool_ids))) { + LOG_WARN("fail to get resource pools", KR(ret), K(tenant_id)); + } else if (OB_UNLIKELY(0 == pool_ids.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get tenant resource pool", KR(ret), K(tenant_id)); + } else if (OB_FAIL(unit_mgr_->check_pool_in_shrinking(pool_ids.at(0), in_shrinking))) { + LOG_WARN("failed to check resource pool in shrink", KR(ret), K(pool_ids)); + } else if (!in_shrinking) { + //nothing todo + } else { + //check shrink finish + //get all unit and server + //check ls not in the unit and ls_meta not in the server + ObArray units; + ObArray servers; + ObArray unit_ids; + ObArray unit_group_ids; + for (int64_t i = 0; OB_SUCC(ret) && i < pool_ids.count(); ++i) { + units.reset(); + if (OB_FAIL(unit_mgr_->get_deleting_units_of_pool(pool_ids.at(i), units))) { + LOG_WARN("failed to get deleting unit", KR(ret), K(i), K(pool_ids)); + } else if (OB_FAIL(extract_units_servers_and_ids_(units, servers, unit_ids, unit_group_ids))) { + LOG_WARN("failed to extract units server and ids", KR(ret), K(units)); + } + }//end for get all unit group, units, server + if (FAILEDx(check_shrink_resource_pool_finished_by_ls_(tenant_id, + servers, unit_ids, unit_group_ids, is_finished))) { + LOG_WARN("failed to check shrink by ls", KR(ret), K(servers), K(unit_ids), K(unit_group_ids)); + } + if (OB_SUCC(ret) && is_finished) { + //commit finish of the tenant + if (OB_FAIL(commit_tenant_shrink_resource_pool_(tenant_id))) { + LOG_WARN("failed to shrink tenant resource pool", KR(ret), K(tenant_id)); + } + } + } + return ret; +} + +int ObShrinkResourcePoolChecker::extract_units_servers_and_ids_( + const ObIArray &units, + ObIArray &servers, + ObIArray &unit_ids, + ObIArray &unit_group_ids) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(0 == units.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("units is empty", KR(ret), K(units)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < units.count(); ++i) { + if (OB_FAIL(servers.push_back(units.at(i).server_))) { + LOG_WARN("fail to push back server", KR(ret), "server", units.at(i).server_); + } else if (OB_FAIL(unit_ids.push_back(units.at(i).unit_id_))) { + LOG_WARN("fail to push back unit id", KR(ret), "unit", units.at(i).unit_id_); + } else if (!has_exist_in_array(unit_group_ids, units.at(i).unit_group_id_)) { + if (OB_FAIL(unit_group_ids.push_back(units.at(i).unit_group_id_))) { + LOG_WARN("failed to push back unit group id", KR(ret), K(i), K(units)); + } + } else {} // no more to do + } + return ret; +} + +int ObShrinkResourcePoolChecker::check_shrink_resource_pool_finished_by_ls_( + const uint64_t tenant_id, + const ObIArray &servers, + const ObIArray &unit_ids, + const ObIArray &unit_group_ids, + bool &is_finished) +{ + int ret = OB_SUCCESS; + is_finished = true; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObShrinkResourcePoolChecker not init", KR(ret)); + } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || 0 == servers.count() || 0 == unit_ids.count() + || 0 == unit_group_ids.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(servers), K(unit_ids), K(unit_group_ids)); + } else if (OB_FAIL(check_stop())) { + LOG_WARN("ObShrinkResourcePoolChecker stop", KR(ret)); + } else if (OB_ISNULL(sql_proxy_) || OB_ISNULL(unit_mgr_) || OB_ISNULL(lst_operator_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(sql_proxy_), KP(unit_mgr_), KP(lst_operator_)); + } else { + ObLSStatusInfoArray ls_status_array; + ObLSStatusOperator ls_status_op; + if (OB_FAIL(ls_status_op.get_all_tenant_related_ls_status_info( + *sql_proxy_, tenant_id, ls_status_array))) { + LOG_WARN("failed to get ls status array", KR(ret), K(tenant_id)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < ls_status_array.count() && is_finished; ++i) { + share::ObLSStatusInfo &ls_status_info = ls_status_array.at(i); + share::ObLSInfo ls_info; + int64_t ls_replica_cnt = 0; + if (OB_FAIL(check_stop())) { + LOG_WARN("ObShrinkResourcePoolChecker stopped", KR(ret)); + } else if (has_exist_in_array(unit_group_ids, ls_status_info.unit_group_id_)) { + is_finished = false; + LOG_INFO("has ls in the unit group", KR(ret), K(ls_status_info)); + } else if (OB_FAIL(lst_operator_->get( + GCONF.cluster_id, + ls_status_info.tenant_id_, + ls_status_info.ls_id_, + share::ObLSTable::COMPOSITE_MODE, + ls_info))) { + LOG_WARN("fail to get ls info", KR(ret), K(ls_status_info)); + } else { + for (int64_t j = 0; OB_SUCC(ret) && j < ls_info.get_replicas_cnt() && is_finished; ++j) { + const share::ObLSReplica &ls_replica = ls_info.get_replicas().at(j); + if (has_exist_in_array(servers, ls_replica.get_server())) { + is_finished = false; + LOG_INFO("has ls in the server", KR(ret), K(ls_replica)); + } else if (has_exist_in_array(unit_ids, ls_replica.get_unit_id())) { + is_finished = false; + LOG_INFO("has ls in the unit", KR(ret), K(ls_replica)); + } + }//end for each ls replica + } + }//end for each ls + } + return ret; +} + +int ObShrinkResourcePoolChecker::commit_tenant_shrink_resource_pool_( + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObShrinkResourcePoolChecker not init", KR(ret)); + } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_FAIL(check_stop())) { + LOG_WARN("ObShrinkResourcePoolChecker stop", KR(ret)); + } else if (OB_ISNULL(unit_mgr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(unit_mgr_)); + } else if (OB_FAIL(unit_mgr_->commit_shrink_tenant_resource_pool(tenant_id))) { + LOG_WARN("fail to shrink resource pool", KR(ret), K(tenant_id)); + } else {} // no more to do + return ret; +} +} // end namespace rootserver +} // end oceanbase diff --git a/src/rootserver/ob_shrink_resource_pool_checker.h b/src/rootserver/ob_shrink_resource_pool_checker.h new file mode 100644 index 000000000..b08f74fc8 --- /dev/null +++ b/src/rootserver/ob_shrink_resource_pool_checker.h @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_SHRINK_RESOURCE_POOL_CHECKER_ +#define OCEANBASE_ROOTSERVER_OB_SHRINK_RESOURCE_POOL_CHECKER_ + +#include "share/ob_define.h" +#include "ob_root_utils.h" + +namespace oceanbase +{ + +namespace obrpc +{ +class ObSrvRpcProxy; +} +namespace share +{ +class ObLSTableOperator; +struct ObResourcePool; +namespace schema +{ +class ObMultiVersionSchemaService; +} +} + +namespace rootserver +{ +class DRLSInfo; +class ObUnitManager; +class ObServerManager; +class ObZoneManager; +class ObShrinkResourcePoolChecker : public share::ObCheckStopProvider +{ +public: + ObShrinkResourcePoolChecker(volatile bool &is_stop) + : is_stop_(is_stop), + sql_proxy_(NULL), + unit_mgr_(NULL), + schema_service_(NULL), + lst_operator_(NULL), + is_inited_(false) {} + virtual ~ObShrinkResourcePoolChecker() {} +public: + int init( + share::schema::ObMultiVersionSchemaService *schema_service, + rootserver::ObUnitManager *unit_mgr, + share::ObLSTableOperator &lst_operator, + common::ObMySQLProxy &sql_proxy); +public: + int check(); +private: + virtual int check_stop() const override; + int check_shrink_resource_pool_finished_by_tenant_( + const uint64_t tenant_id); + int extract_units_servers_and_ids_( + const ObIArray &units, + ObIArray &servers, + ObIArray &unit_ids, + ObIArray &unit_group_ids); + int check_shrink_resource_pool_finished_by_ls_( + const uint64_t tenant_id, + const ObIArray &servers, + const ObIArray &unit_ids, + const ObIArray &unit_group_ids, + bool &is_finished); + int commit_tenant_shrink_resource_pool_( + const uint64_t tenant_id); +private: + const volatile bool &is_stop_; + common::ObMySQLProxy *sql_proxy_; + rootserver::ObUnitManager *unit_mgr_; + share::schema::ObMultiVersionSchemaService *schema_service_; + share::ObLSTableOperator *lst_operator_; + bool is_inited_; +}; +} // end of namespace rootserver +} // end of namespace oceanbase +#endif diff --git a/src/rootserver/ob_table_creator.cpp b/src/rootserver/ob_table_creator.cpp index e64f71617..6e35f23ac 100644 --- a/src/rootserver/ob_table_creator.cpp +++ b/src/rootserver/ob_table_creator.cpp @@ -378,7 +378,7 @@ int ObTableCreator::generate_create_tablet_arg_( tablet_id = part->get_tablet_id(); } share::ObTabletTablePair pair; - share::ObTabletToLSInfo tablet_info(tablet_id, ls_id, table_schema_ptr->get_table_id()); + share::ObTabletToLSInfo tablet_info(tablet_id, ls_id, table_schema_ptr->get_table_id(), 0/*transfer_seq*/); if (OB_FAIL(ret)) { } else if (OB_FAIL(tablet_id_array.push_back(tablet_id))) { LOG_WARN("failed to assign table schema point", KR(ret)); diff --git a/src/rootserver/ob_tablet_creator.cpp b/src/rootserver/ob_tablet_creator.cpp index c9fc7b081..157ead2f7 100644 --- a/src/rootserver/ob_tablet_creator.cpp +++ b/src/rootserver/ob_tablet_creator.cpp @@ -335,7 +335,7 @@ int ObTabletCreator::execute() ret = OB_TIMEOUT; LOG_WARN("already timeout", KR(ret), K(ctx)); } else if (OB_FAIL(conn->register_multi_data_source(tenant_id_, iter->first, - transaction::ObTxDataSourceType::CREATE_TABLET, buf, buf_len))) { + transaction::ObTxDataSourceType::CREATE_TABLET_NEW_MDS, buf, buf_len))) { if (need_retry(ret)) { LOG_INFO("fail to register_tx_data, try again", KR(ret), K_(tenant_id), K(batch_arg->arg_)); ob_usleep(SLEEP_INTERVAL); diff --git a/src/rootserver/ob_tablet_drop.cpp b/src/rootserver/ob_tablet_drop.cpp index 6f0f11a48..09696a07e 100644 --- a/src/rootserver/ob_tablet_drop.cpp +++ b/src/rootserver/ob_tablet_drop.cpp @@ -319,7 +319,7 @@ int ObTabletDrop::execute() ret = OB_TIMEOUT; LOG_WARN("already timeout", KR(ret), K(ctx)); } else if (OB_FAIL(conn->register_multi_data_source(tenant_id_, iter->first, - transaction::ObTxDataSourceType::REMOVE_TABLET, buf, buf_len))) { + transaction::ObTxDataSourceType::DELETE_TABLET_NEW_MDS, buf, buf_len))) { LOG_WARN("fail to register_tx_data", KR(ret), K(arg), K(buf), K(buf_len)); if (OB_LS_LOCATION_LEADER_NOT_EXIST == ret || OB_NOT_MASTER == ret) { LOG_INFO("fail to find leader, try again", K_(tenant_id), K(arg)); diff --git a/src/rootserver/ob_tenant_balance_service.cpp b/src/rootserver/ob_tenant_balance_service.cpp new file mode 100755 index 000000000..f9c020ffe --- /dev/null +++ b/src/rootserver/ob_tenant_balance_service.cpp @@ -0,0 +1,751 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX BALANCE +#include "ob_tenant_balance_service.h" +#include "share/schema/ob_schema_getter_guard.h"//ObSchemaGetGuard +#include "share/schema/ob_schema_struct.h"//ObTenantInfo +#include "share/schema/ob_multi_version_schema_service.h"//ObMultiSchemaService +#include "share/ob_unit_table_operator.h" //ObUnitTableOperator +#include "share/balance/ob_balance_job_table_operator.h"//ObBalanceJob +#include "share/balance/ob_balance_task_table_operator.h"//ObBalanceTask +#include "share/ob_primary_zone_util.h"//get_primary_zone +#include "share/rc/ob_tenant_base.h"//MTL +#include "rootserver/ob_ls_balance_helper.h"//ObLSBalanceTaskHelper +#include "rootserver/ob_ls_service_helper.h"//ObLSServiceHelper +#include "rootserver/ob_balance_ls_primary_zone.h"//ObBalanceLSPrimaryZone +#include "observer/ob_server_struct.h"//GCTX +#include "rootserver/ob_partition_balance.h" // partition balance +#include "storage/tablelock/ob_lock_utils.h" // ObInnerTableLockUtil +#include "share/ob_cluster_version.h" +#include "share/ob_share_util.h" // ObShareUtil + +#define ISTAT(fmt, args...) FLOG_INFO("[TENANT_BALANCE] " fmt, ##args) +#define WSTAT(fmt, args...) FLOG_WARN("[TENANT_BALANCE] " fmt, ##args) + + +namespace oceanbase +{ +using namespace common; +using namespace share; +using namespace transaction::tablelock; + +namespace rootserver +{ +//////////////ObTenantBalanceService +int ObTenantBalanceService::init() +{ + int ret = OB_SUCCESS; + tenant_id_ = MTL_ID(); + if (OB_UNLIKELY(inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("has inited", KR(ret)); + } else if (OB_FAIL(ObTenantThreadHelper::create("TBalance", + lib::TGDefIDs::SimpleLSService, *this))) { + LOG_WARN("failed to create thread", KR(ret)); + } else if (OB_FAIL(ObTenantThreadHelper::start())) { + LOG_WARN("fail to start thread", KR(ret)); + } else { + inited_ = true; + } + return ret; +} + +void ObTenantBalanceService::destroy() +{ + ObTenantThreadHelper::destroy(); + tenant_id_ = OB_INVALID_TENANT_ID; + inited_ = false; +} + +int ObTenantBalanceService::wait_tenant_and_version_ready_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema ptr is null", KR(ret), KP(GCTX.schema_service_)); + } else { + bool is_ready = false; + uint64_t tenant_data_version = 0; + while (!is_ready && !has_set_stop()) { + ret = OB_SUCCESS; + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObTenantSchema *tenant_schema = NULL; + + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id_, tenant_data_version))) { + LOG_WARN("failed to get min data version", KR(ret), K(tenant_id_)); + } else if (tenant_data_version < DATA_VERSION_4_2_0_0) { + ret = OB_NEED_WAIT; + WSTAT("tenant version not target, need wait", KR(ret), K(tenant_data_version)); + } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id_, tenant_schema))) { + LOG_WARN("failed to get tenant ids", KR(ret), K(tenant_id_)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant not exist", KR(ret), K(tenant_id_)); + } else if (!tenant_schema->is_normal()) { + ret = OB_NEED_WAIT; + WSTAT("tenant schema not ready, no need tenant balance", KR(ret), KPC(tenant_schema)); + } else { + is_ready = true; + } + + if (! is_ready) { + idle(10 * 1000 *1000); + } + } + + if (has_set_stop()) { + WSTAT("thread has been stopped", K(is_ready), K(tenant_id_)); + ret = OB_IN_STOP_STATE; + } + } + return ret; +} + +int ObTenantBalanceService::balance_primary_zone_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(GCTX.sql_proxy_) + || OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_), KP(GCTX.schema_service_)); + } else { + ObTenantSchema tenant_schema_copy; + if (OB_FAIL(get_tenant_schema(tenant_id_, tenant_schema_copy))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(ObBalanceLSPrimaryZone::try_adjust_user_ls_primary_zone(tenant_schema_copy))) { + LOG_WARN("failed to adjust user tenant primary zone", KR(ret), + K(tenant_id_)); + } + } + return ret; +} + +void ObTenantBalanceService::do_work() +{ + int ret = OB_SUCCESS; + ISTAT("tenant balance thread", K(tenant_id_)); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_FAIL(wait_tenant_schema_and_version_ready_(tenant_id_, DATA_VERSION_4_2_0_0))) { + LOG_WARN("failed to wait tenant schema version ready", KR(ret), K(tenant_id_), K(DATA_CURRENT_VERSION)); + } else { + int64_t idle_time_us = 10 * 1000 * 1000L; + int tmp_ret = OB_SUCCESS; + int64_t job_cnt = 0; + int64_t last_statistic_bg_stat_time = ObTimeUtility::current_time(); + int64_t last_partition_balance_time = last_statistic_bg_stat_time; + while (!has_set_stop()) { + ObCurTraceId::init(GCONF.self_addr_); + reset(); + DEBUG_SYNC(BEFORE_TENANT_BALANCE_SERVICE); + if (OB_FAIL(gather_stat_())) { + LOG_WARN("failed to gather stat", KR(ret)); + } else if (OB_FAIL(try_process_current_job(job_cnt))) { + LOG_WARN("failed to process current job", KR(ret)); + } else if (0 == job_cnt && ObShareUtil::is_tenant_enable_rebalance(tenant_id_)) { + //check ls status is match with __all_ls + //TODO + if (OB_FAIL(gather_ls_status_stat_())) { + LOG_WARN("failed to gather ls status", KR(ret)); + } else if (OB_FAIL(ls_balance_(job_cnt))) { + LOG_WARN("failed to do ls balance", KR(ret)); + } else if (0 == job_cnt) { + //balance primary zone + if (OB_FAIL(balance_primary_zone_())) { + LOG_WARN("failed to balance primary zone", KR(ret)); + } else if (OB_FAIL(try_do_partition_balance_(last_partition_balance_time))) { + LOG_WARN("try do partition balance failed", KR(ret), K(last_partition_balance_time)); + } + } + } + + // separate statistic to avoid affecting balance jobs + if (OB_FAIL(ret)) { + } else if (OB_TMP_FAIL(try_statistic_balance_group_status_(last_statistic_bg_stat_time))) { + LOG_WARN("try statistic balance group status failed", KR(tmp_ret), K(last_statistic_bg_stat_time)); + } + + if (OB_FAIL(ret) && OB_NEED_WAIT != ret) { + idle_time_us = 100 * 1000; + } else { + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id_)); + idle_time_us = tenant_config.is_valid() ? tenant_config->balancer_idle_time : 10 * 1000 * 1000; + } + ISTAT("finish one round", KR(ret), KR(tmp_ret), K_(tenant_id), K(job_cnt), + K(primary_zone_num_), K(unit_group_array_), + K(ls_array_), K(idle_time_us), K(last_partition_balance_time), K(last_statistic_bg_stat_time), + "enable_rebalance", ObShareUtil::is_tenant_enable_rebalance(tenant_id_)); + reset(); + idle(idle_time_us); + }// end while + } +} + +int ObTenantBalanceService::gather_stat_() +{ + int ret = OB_SUCCESS; + ATOMIC_SET(&loaded_, false); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(GCTX.sql_proxy_) + || OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_), KP(GCTX.schema_service_)); + } else { + //get primary zone + share::schema::ObTenantSchema tenant_schema; + ObArray primary_zone; + if (OB_FAIL(get_tenant_schema(tenant_id_, tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(tenant_id_)); + } else if (!tenant_schema.is_normal()) { + //already wait tenant ready, must be normal + ret = OB_ERR_UNEXPECTED; + WSTAT("tenant schema not ready is unexpected", KR(ret)); + } else if (OB_FAIL(ObLSServiceHelper::get_primary_zone_unit_array(&tenant_schema, + primary_zone, unit_group_array_))) { + LOG_WARN("failed to get primary zone unit array", KR(ret), K(tenant_schema)); + } else { + primary_zone_num_ = primary_zone.count(); + ATOMIC_SET(&loaded_, true); + } + } + return ret; +} + +int ObTenantBalanceService::gather_ls_status_stat_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_)); + } else { + //get ls status info + //must remove ls group id = 0, those ls no need balance, such as sys ls and duplicate ls + ObLSStatusOperator status_op; + ObLSAttrOperator ls_op(tenant_id_, GCTX.sql_proxy_); + share::ObLSAttrArray ls_attr_array; + if (OB_FAIL(status_op.get_all_ls_status_by_order(tenant_id_, ls_array_, *GCTX.sql_proxy_))) { + LOG_WARN("failed to get status by order", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(ls_op.get_all_ls_by_order(ls_attr_array))) { + LOG_WARN("failed to get ls attr array", KR(ret)); + } else if (ls_attr_array.count() > ls_array_.count()) { + //only ls status has more ls, such as some ls is waitoffline + ret = OB_NEED_WAIT; + WSTAT("has ls need create", KR(ret), K(ls_attr_array)); + } + int64_t attr_index = ls_attr_array.count() - 1; + bool need_remove_ls = false; + for (int64_t i = ls_array_.count() - 1; OB_SUCC(ret) && i >= 0; --i) { + if (attr_index < 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls attr array is unexpected", KR(ret), K(i), K(ls_attr_array)); + } else { + const ObLSStatusInfo &status_info = ls_array_.at(i); + const ObLSAttr &ls_info = ls_attr_array.at(attr_index); + need_remove_ls = false; + if (status_info.ls_id_ == ls_info.get_ls_id()) { + // check ls status and ls group id; + attr_index--; + if (status_info.ls_group_id_ != ls_info.get_ls_group_id()) { + // need primary ls service work + ret = OB_NEED_WAIT; + WSTAT("has ls need modify ls group, can not balance", KR(ret), + K(ls_info), K(status_info)); + } else if (status_info.status_ != ls_info.get_ls_status() || + (!status_info.ls_is_normal() && + !status_info.ls_is_dropping())) { + ret = OB_NEED_WAIT; + WSTAT("ls status not ready, can not balance", KR(ret), K(ls_info), + K(status_info)); + } else if (0 == status_info.ls_group_id_ || status_info.ls_is_dropping()) { + //ls has no ls group such as sys ls, or ls is in dropping, can not fallback, no need to takecare + need_remove_ls = true; + } + } else if (status_info.ls_id_ > ls_info.get_ls_id()) { + // ls must be in wait offline, ls in __all_ls_stauts but not in __all_ls, must be waitoffline, need remove + need_remove_ls = true; + if (!status_info.ls_is_wait_offline()) { + ret = OB_ERR_UNEXPECTED; + WSTAT("ls status not expected", KR(ret), K(status_info), K(ls_info), + K(ls_array_), K(ls_attr_array)); + } + } else { + // ls in status can not large than in __all_ls by order + ret = OB_NEED_WAIT; + WSTAT("has ls need create, can not balance", KR(ret), K(ls_info), + K(status_info)); + } + if (OB_SUCC(ret) && need_remove_ls) { + ISTAT("LS no need balance", "ls_status", ls_array_.at(i)); + if (OB_FAIL(ls_array_.remove(i))) { + LOG_WARN("failed to remvoe no ls group ls", KR(ret), K(i)); + } + } + } + } + } + return ret; +} + + +int ObTenantBalanceService::try_process_current_job(int64_t &job_cnt) +{ + int ret = OB_SUCCESS; + job_cnt = 0; + int64_t start_time = OB_INVALID_TIMESTAMP, finish_time = OB_INVALID_TIMESTAMP; + ObBalanceJob job; + bool job_need_cancel = false; + ObSqlString comment; + if (OB_UNLIKELY(!inited_ || !ATOMIC_LOAD(&loaded_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(inited_), K(loaded_)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_)); + } else if (OB_FAIL(ObBalanceJobTableOperator::get_balance_job( + tenant_id_, false, *GCTX.sql_proxy_, job, start_time, finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + //NO JOB, need check current ls status + ret = OB_SUCCESS; + job_cnt = 0; + } else { + LOG_WARN("failed to get balance job", KR(ret), K(tenant_id_)); + } + } else if (OB_FAIL(try_finish_current_job_(job, job_cnt))) { + LOG_WARN("failed to finish current job", KR(ret), K(job)); + } else if (0 == job_cnt) { + //You can check the status of the current ls to + //decide whether you want to continue generating tasks + } else if (job.get_job_status().is_canceling()) { + //job already abort, no need to do + } else if (OB_FAIL(check_ls_job_need_cancel_(job, job_need_cancel, comment))) { + LOG_WARN("failed to check exist job need continue", KR(ret), K(job)); + } else if (job_need_cancel) { + int tmp_ret = OB_SUCCESS; + if (OB_FAIL(ObBalanceJobTableOperator::update_job_status(tenant_id_, + job.get_job_id(), job.get_job_status(), + ObBalanceJobStatus(ObBalanceJobStatus::BALANCE_JOB_STATUS_CANCELING), + true, comment.string(), + *GCTX.sql_proxy_))) { + LOG_WARN("failed to update job status", KR(ret), K(tenant_id_), K(job), K(comment)); + } + } + return ret; +} + +int ObTenantBalanceService::ls_balance_(int64_t &job_cnt) +{ + int ret = OB_SUCCESS; + job_cnt = 0; + ObLSBalanceTaskHelper ls_balance_helper; + bool need_ls_balance = false; + if (OB_UNLIKELY(!inited_ || !ATOMIC_LOAD(&loaded_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(inited_), K(loaded_)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_)); + } else { + //Build the current ls group, check if the ls group matches the primary_zone, unit_group + //If it is a partition_balance task and ls_balance is currently required, the current task needs to be cancelled + if (OB_FAIL(ls_balance_helper.init(tenant_id_, ls_array_, unit_group_array_, + primary_zone_num_, GCTX.sql_proxy_))) { + LOG_WARN("failed to init ls balance helper", KR(ret), K(ls_array_), K(unit_group_array_), + K(primary_zone_num_), K(tenant_id_)); + } else if (OB_FAIL(ls_balance_helper.check_need_ls_balance(need_ls_balance))) { + LOG_WARN("failed to check_ls need balance", KR(ret)); + } + } + + if (OB_SUCC(ret) && need_ls_balance) { + if (OB_FAIL(ls_balance_helper.generate_ls_balance_task())) { + LOG_WARN("failed to generate task", KR(ret)); + } else if (OB_FAIL(persist_job_and_task_( + ls_balance_helper.get_balance_job(), + ls_balance_helper.get_balance_tasks()))) { + LOG_WARN("failed to persist balance task and job", KR(ret), + "job", ls_balance_helper.get_balance_job(), + "tasks", ls_balance_helper.get_balance_tasks()); + } else { + job_cnt = 1; + } + } + ISTAT("finish ls balance", KR(ret), K(need_ls_balance), + "job", ls_balance_helper.get_balance_job(), "tasks", + ls_balance_helper.get_balance_tasks()); + return ret; +} + +int ObTenantBalanceService::partition_balance_(bool enable_transfer) +{ + int ret = OB_SUCCESS; + ObPartitionBalance partition_balance; + int64_t active_unit_num = 0; + if (OB_UNLIKELY(!inited_ || !ATOMIC_LOAD(&loaded_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(inited_), K(loaded_)); + } else if (OB_ISNULL(GCTX.sql_proxy_) || OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_), KP(GCTX.schema_service_)); + } else if (OB_FAIL(get_active_unit_num_(active_unit_num))) { + LOG_WARN("failed to get active unit num", KR(ret)); + } else if (OB_FAIL(partition_balance.init(tenant_id_, GCTX.schema_service_, GCTX.sql_proxy_, + primary_zone_num_, active_unit_num, + enable_transfer ? ObPartitionBalance::GEN_TRANSFER_TASK : ObPartitionBalance::GEN_BG_STAT))) { + LOG_WARN("fail to init partition balance", KR(ret), K(tenant_id_), K(primary_zone_num_), + K(active_unit_num), K(enable_transfer)); + } else if (OB_FAIL(partition_balance.process())) { + LOG_WARN("fail to process partition_balance", KR(ret)); + } else if (partition_balance.get_balance_task().empty()) { + ISTAT("partition balance generate empty task"); + } else if (OB_FAIL(persist_job_and_task_(partition_balance.get_balance_job(), partition_balance.get_balance_task()))) { + LOG_WARN("fail to persist_job_and_task", KR(ret), "job", partition_balance.get_balance_job(), "tasks", partition_balance.get_balance_task()); + } else { + ISTAT("partition balance generate task", "job", partition_balance.get_balance_job(), "tasks", partition_balance.get_balance_task()); + } + return ret; +} + +int ObTenantBalanceService::try_finish_current_job_(const share::ObBalanceJob &job, int64_t &job_cnt) +{ + int ret = OB_SUCCESS; + int64_t task_cnt = 0; + bool can_clean_job = false; + if (OB_UNLIKELY(!inited_ || ! ATOMIC_LOAD(&loaded_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(inited_), K(loaded_)); + } else if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("job is invalid", KR(ret), K(job)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_)); + } else if (job.get_job_status().is_canceled() || job.get_job_status().is_success()) { + can_clean_job = true; + } else if (OB_FAIL(ObBalanceTaskTableOperator::get_job_task_cnt(tenant_id_, job.get_job_id(), + task_cnt, *GCTX.sql_proxy_))) { + LOG_WARN("failed to get job task cnt", KR(ret), K(job), K(tenant_id_)); + } else if (0 != task_cnt) { + can_clean_job = false; + ISTAT("job has not finish task, cannot finish", K(task_cnt), K(job)); + } else { + ObBalanceJobStatus new_status; + can_clean_job = true; + ObString comment; + if (job.get_job_status().is_doing()) { + new_status = ObBalanceJobStatus(share::ObBalanceJobStatus::BALANCE_JOB_STATUS_COMPLETED); + } else if (job.get_job_status().is_canceling()) { + new_status = ObBalanceJobStatus(share::ObBalanceJobStatus::BALANCE_JOB_STATUS_CANCELED); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("job status not expected", KR(ret), K(job)); + } + if (FAILEDx(ObBalanceJobTableOperator::update_job_status(tenant_id_, job.get_job_id(), + job.get_job_status(), new_status, false, comment, + *GCTX.sql_proxy_))) { + LOG_WARN("failed to update job status", KR(ret), K(tenant_id_), K(job), K(new_status)); + } + } + if (OB_SUCC(ret)) { + if (!can_clean_job) { + job_cnt = 1; + } else if (OB_FAIL(ObBalanceJobTableOperator::clean_job(tenant_id_, job.get_job_id(), *GCTX.sql_proxy_))) { + LOG_WARN("failed to clean job", KR(ret), K(tenant_id_), K(job)); + } else { + ISTAT("clean the job", K(task_cnt), K(job)); + job_cnt = 0; + } + } + return ret; +} + +int ObTenantBalanceService::get_active_unit_num_(int64_t &active_unit_num) const +{ + int ret = OB_SUCCESS; + active_unit_num = 0; + if (OB_UNLIKELY(!inited_ || ! ATOMIC_LOAD(&loaded_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(inited_), K(loaded_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < unit_group_array_.count(); ++i) { + if (unit_group_array_.at(i).is_active()) { + active_unit_num++; + } + } + + } + return ret; +} + +int ObTenantBalanceService::check_ls_job_need_cancel_(const share::ObBalanceJob &job, + bool &need_cancel, + ObSqlString &comment) +{ + int ret = OB_SUCCESS; + need_cancel = false; + comment.reset(); + int tmp_ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_ || ! ATOMIC_LOAD(&loaded_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(inited_), K(loaded_)); + } else if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("job is invalid", KR(ret), K(job)); + } else if (!ObShareUtil::is_tenant_enable_rebalance(tenant_id_)) { + need_cancel = true; + if (OB_TMP_FAIL(comment.assign_fmt("Canceled due to tenant balance is disabled"))) { + LOG_WARN("failed to assign fmt", KR(tmp_ret), K(job)); + } + ISTAT("tenant balance is disabled, need cancel current job", K(job), K(comment)); + } else if (job.get_primary_zone_num() != primary_zone_num_) { + need_cancel = true; + if (OB_TMP_FAIL(comment.assign_fmt("Canceled due to primary zone num change from %ld to %ld", + job.get_primary_zone_num(), primary_zone_num_))) { + LOG_WARN("failed to assign fmt", KR(tmp_ret), K(job), K(primary_zone_num_)); + } + ISTAT("primary zone num change, need cancel current job", K(primary_zone_num_), K(job), K(comment)); + } else { + int64_t active_unit_num = 0; + if (OB_FAIL(get_active_unit_num_(active_unit_num))) { + LOG_WARN("failed to get active unit num", KR(ret)); + } else if (job.get_unit_group_num() != active_unit_num) { + need_cancel = true; + if (OB_TMP_FAIL(comment.assign_fmt("Canceled due to unit num change from %ld to %ld", + job.get_unit_group_num(), active_unit_num))) { + LOG_WARN("failed to assign fmt", KR(tmp_ret), K(job), K(active_unit_num)); + } + ISTAT("unit group num change, need cancel current job", + K(active_unit_num), K(job), K(unit_group_array_), K(comment)); + } + } + return ret; +} + +void ObTenantBalanceService::reset() +{ + loaded_ = false; + unit_group_array_.reset(); + ls_array_.reset(); + primary_zone_num_ = OB_INVALID_COUNT; + +} + +int ObTenantBalanceService::persist_job_and_task_(const share::ObBalanceJob &job, + ObArray &tasks) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_ || ! ATOMIC_LOAD(&loaded_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(inited_), K(loaded_)); + } else if (OB_UNLIKELY(!job.is_valid() || 0 == tasks.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("job or task is invalid", KR(ret), K(job), K(tasks)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_)); + } else if (OB_FAIL(construct_dependency_of_each_task_(tasks))) { + LOG_WARN("failed to generate dependency task", KR(ret), K(tasks)); + } else { + common::ObMySQLTransaction trans; + if (OB_FAIL(trans.start(GCTX.sql_proxy_, tenant_id_))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(lock_and_check_balance_job_(trans, tenant_id_))) { + LOG_WARN("lock and check balance job failed", KR(ret), K_(tenant_id)); + } else if (OB_FAIL(ObBalanceJobTableOperator::insert_new_job(job, trans))) { + LOG_WARN("failed to insert new job", KR(ret), K(job)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < tasks.count(); ++i) { + if (OB_FAIL(ObBalanceTaskTableOperator::insert_new_task(tasks.at(i), + trans))) { + LOG_WARN("failed to insert new task", KR(ret), K(i), K(tasks)); + } + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + } + return ret; +} + +int ObTenantBalanceService::lock_and_check_balance_job_( + common::ObMySQLTransaction &trans, + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + ObBalanceJob job; + int64_t start_time = 0; // useless + int64_t finish_time = 0; // useless + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ObInnerTableLockUtil::lock_inner_table_in_trans( + trans, + tenant_id, + OB_ALL_BALANCE_JOB_TID, + EXCLUSIVE))) { + LOG_WARN("lock inner table failed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ObBalanceJobTableOperator::get_balance_job( + tenant_id, + false, + trans, + job, + start_time, + finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + ISTAT("no job in table, check empty successfully", KR(ret), K(tenant_id)); + } else { + LOG_WARN("failed to get balance job", KR(ret), K(tenant_id)); + } + } else { + ret = OB_ENTRY_EXIST; + LOG_WARN("there should be no job in table", KR(ret), K(job)); + } + if (OB_SUCC(ret)) { + DEBUG_SYNC(AFTER_LOCK_ALL_BALANCE_JOB); + } + return ret; +} + +#define SET_TASK_DEPENDENCY(ls_id) \ + do { \ + if (OB_FAIL(ret)) { \ + } else if (ls_id.is_valid()) { \ + if (OB_SUCC(ls_task_map.get_refactored(ls_id, parent_task))) { \ + overwrite = true; \ + if (OB_FAIL(task.get_parent_task_list().push_back( \ + parent_task->get_balance_task_id()))) { \ + LOG_WARN("failed to set parent", KR(ret), KPC(parent_task)); \ + } else if (OB_FAIL(parent_task->get_child_task_list().push_back( \ + task.get_balance_task_id()))) { \ + LOG_WARN("failed to set child parent", KR(ret), K(task)); \ + } \ + } else if (OB_HASH_NOT_EXIST == ret) { \ + overwrite = false; \ + ret = OB_SUCCESS; \ + } else { \ + LOG_WARN("failed to get refactor", KR(ret), K(ls_id)); \ + } \ + if (FAILEDx(ls_task_map.set_refactored(ls_id, &task, overwrite))) { \ + LOG_WARN("failed to set refactor", KR(ret), K(ls_id)); \ + } \ + } \ + } while (0) + +int ObTenantBalanceService::construct_dependency_of_each_task_( + ObArray &tasks) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(tasks.count() <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tasks)); + } else { + hash::ObHashMap ls_task_map; + ObBalanceTask *parent_task = NULL; + bool overwrite = false; + if (OB_FAIL(ls_task_map.create(tasks.count(), lib::ObLabel("BalTask")))) { + LOG_WARN("failed to create hashmap", KR(ret), K(tasks)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < tasks.count(); ++i) { + ObBalanceTask &task = tasks.at(i); + ObLSID src_ls = task.get_src_ls_id(); + ObLSID dest_ls = task.get_dest_ls_id(); + SET_TASK_DEPENDENCY(src_ls); + if (src_ls != dest_ls) { + //ls_alter maybe src_ls equal to dest_ls + SET_TASK_DEPENDENCY(dest_ls); + } + } + } + return ret; +} + +int ObTenantBalanceService::try_do_partition_balance_(int64_t &last_partition_balance_time) +{ + int ret = OB_SUCCESS; + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id_)); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_config.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant config is invalid", KR(ret), K_(tenant_id)); + } else { + const int64_t curr_time = ObTimeUtility::current_time(); + const int64_t interval = tenant_config->partition_balance_schedule_interval; + if (0 == interval) { + // 0 means partition balance is disabled + } else if (curr_time - last_partition_balance_time > interval) { + if (OB_FAIL(partition_balance_(true/*need_balance*/))) { // generate transfer job + LOG_WARN("failed to do partition balance", + KR(ret), K(curr_time), K(last_partition_balance_time)); + } else { + LOG_INFO("do partition balance successfully", KR(ret), + K(interval), K(curr_time), K(last_partition_balance_time)); + last_partition_balance_time = curr_time; + } + } + } + return ret; +} + +int ObTenantBalanceService::try_statistic_balance_group_status_(int64_t &last_statistic_bg_stat_time) +{ + int ret = OB_SUCCESS; + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id_)); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_config.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant config is invalid", KR(ret), K_(tenant_id)); + } else { + const int64_t curr_time = ObTimeUtility::current_time(); + if (curr_time - last_statistic_bg_stat_time > tenant_config->balancer_idle_time) { + if (OB_FAIL(partition_balance_(false/*need_balance*/))) { // just statistic balance group status + LOG_WARN("failed to save balance group status", + KR(ret), K(curr_time), K(last_statistic_bg_stat_time)); + } else { + last_statistic_bg_stat_time = curr_time; + } + } + } + return ret; +} + +#undef SET_TASK_DEPENDENCY +#undef ISTAT +#undef WSTAT +#undef STAT +} +} diff --git a/src/rootserver/ob_tenant_balance_service.h b/src/rootserver/ob_tenant_balance_service.h new file mode 100644 index 000000000..a30fd1664 --- /dev/null +++ b/src/rootserver/ob_tenant_balance_service.h @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_TENANT_BALANCE_SERVICE_H +#define OCEANBASE_ROOTSERVER_OB_TENANT_BALANCE_SERVICE_H +#include "lib/thread/ob_reentrant_thread.h"//ObRsReentrantThread +#include "share/ob_thread_mgr.h" //OBTGDefIDEnum +#include "share/unit/ob_unit_info.h"//ObUnit::Status && SimpleUnitGroup +#include "lib/thread/thread_mgr_interface.h" // TGRunnable +#include "lib/lock/ob_thread_cond.h"//ObThreadCond +#include "rootserver/ob_tenant_thread_helper.h"//ObTenantTheadHelper +#include "share/ls/ob_ls_status_operator.h"//ObLSStatusInfoArray + +namespace oceanbase +{ +namespace obrpc +{ +class ObSrvRpcProxy; +} +namespace common +{ +class ObMySQLProxy; +class ObMySQLTransaction; +} +namespace share +{ +class ObBalanceJob; +class ObBalanceTask; +class ObLSTableOperator; +namespace schema +{ +class ObMultiVersionSchemaService; +class ObTenantSchema; +} +} +namespace rootserver +{ + +/*description: + * only one thread in threadpool + * the service process expand, shrink and partition balance + */ +class ObTenantBalanceService : public ObTenantThreadHelper, + public logservice::ObICheckpointSubHandler, + public logservice::ObIReplaySubHandler +{ +public: + ObTenantBalanceService():inited_(false), loaded_(false), tenant_id_(OB_INVALID_TENANT_ID), + primary_zone_num_(OB_INVALID_COUNT), ls_array_(), + unit_group_array_() {} + virtual ~ObTenantBalanceService() {} + int init(); + void destroy(); + virtual void do_work() override; + DEFINE_MTL_FUNC(ObTenantBalanceService) + +public: + virtual share::SCN get_rec_scn() override { return share::SCN::max_scn();} + virtual int flush(share::SCN &) override { return OB_SUCCESS; } + int replay(const void *buffer, const int64_t nbytes, const palf::LSN &lsn, const share::SCN &) override + { + UNUSED(buffer); + UNUSED(nbytes); + UNUSED(lsn); + return OB_SUCCESS; + } + +private: + //load current unit group and primary zone + int gather_stat_(); + //load __all_ls_status + int gather_ls_status_stat_(); + //process current job + int try_process_current_job(int64_t &job_cnt); + //accordint to primary_zone and unit group + int ls_balance_(int64_t &job_cnt); + // according balance group strategy + int partition_balance_(bool enable_transfer = false); + //if job finish success, job cnt is zero or one + int try_finish_current_job_(const share::ObBalanceJob &job, int64_t &job_cnt); + /* description: check current job need cancel + current ls group and primary zone not match with job + */ + int check_ls_job_need_cancel_(const share::ObBalanceJob &job, + bool &need_cancel, + common::ObSqlString &abort_comment); + void reset(); + int persist_job_and_task_(const share::ObBalanceJob &job, + ObArray &tasks); + int construct_dependency_of_each_task_(ObArray &tasks); + int wait_tenant_and_version_ready_(); + int lock_and_check_balance_job_(common::ObMySQLTransaction &trans, const uint64_t tenant_id); + int balance_primary_zone_(); + int try_update_job_comment_(const share::ObBalanceJob &job, const common::ObSqlString &comment); + int try_do_partition_balance_(int64_t &last_partition_balance_time); + int try_statistic_balance_group_status_(int64_t &last_statistic_bg_stat_time); + int get_active_unit_num_(int64_t &active_unit_num) const; +private: + bool inited_; + bool loaded_; + uint64_t tenant_id_; + int64_t primary_zone_num_; + share::ObLSStatusInfoArray ls_array_; + ObArray unit_group_array_; +}; +} +} + + +#endif /* !OCEANBASE_ROOTSERVER_OB_TENANT_BALANCE_SERVICE_H */ diff --git a/src/rootserver/ob_tenant_info_loader.cpp b/src/rootserver/ob_tenant_info_loader.cpp index 8064092b4..25a2409ed 100644 --- a/src/rootserver/ob_tenant_info_loader.cpp +++ b/src/rootserver/ob_tenant_info_loader.cpp @@ -264,6 +264,25 @@ bool ObTenantInfoLoader::is_sys_ls_leader_() return is_sys_ls_leader; } +int ObTenantInfoLoader::get_max_ls_id(uint64_t &tenant_id, ObLSID &max_ls_id) +{ + int ret = OB_SUCCESS; + ObAllTenantInfo tenant_info; + const uint64_t mtl_tenant_id = MTL_ID(); + tenant_id = OB_INVALID_TENANT_ID; + max_ls_id.reset(); + if (OB_SYS_TENANT_ID == mtl_tenant_id || is_meta_tenant(mtl_tenant_id)) { + tenant_id = mtl_tenant_id; + max_ls_id = ObLSID::SYS_LS_ID; + } else if (OB_FAIL(get_tenant_info(tenant_info))) { + LOG_WARN("get_tenant_info failed", KR(ret)); + } else { + tenant_id = tenant_info.get_tenant_id(); + max_ls_id = tenant_info.get_max_ls_id(); + } + return ret; +} + bool ObTenantInfoLoader::act_as_standby_() { int ret = OB_SUCCESS; diff --git a/src/rootserver/ob_tenant_info_loader.h b/src/rootserver/ob_tenant_info_loader.h index 860711761..c734ce1f7 100644 --- a/src/rootserver/ob_tenant_info_loader.h +++ b/src/rootserver/ob_tenant_info_loader.h @@ -142,6 +142,7 @@ public: int refresh_tenant_info(); int update_tenant_info_cache(const int64_t new_ora_rowscn, const ObAllTenantInfo &new_tenant_info); bool need_refresh(const int64_t refresh_time_interval_us); + int get_max_ls_id(uint64_t &tenant_id, ObLSID &max_ls_id); protected: /** @@ -187,4 +188,4 @@ private: } // namespace rootserver } // namespace oceanbase -#endif /* !OCEANBASE_ROOTSERVER_OB_TENANT_INFO_LOADER_H */ \ No newline at end of file +#endif /* !OCEANBASE_ROOTSERVER_OB_TENANT_INFO_LOADER_H */ diff --git a/src/rootserver/ob_tenant_role_transition_service.cpp b/src/rootserver/ob_tenant_role_transition_service.cpp index eac69e305..957010f03 100644 --- a/src/rootserver/ob_tenant_role_transition_service.cpp +++ b/src/rootserver/ob_tenant_role_transition_service.cpp @@ -26,6 +26,7 @@ #include "share/ob_schema_status_proxy.h"//set_schema_status #include "storage/tx/ob_timestamp_service.h" // ObTimestampService #include "share/ob_primary_standby_service.h" // ObPrimaryStandbyService +#include "share/balance/ob_balance_task_helper_operator.h"//ObBalanceTaskHelper namespace oceanbase { @@ -126,7 +127,7 @@ int ObTenantRoleTransitionService::failover_to_primary() LOG_WARN("failed to prepare flashback", KR(ret), K(tenant_info)); } } else if (tenant_info.is_flashback_status()) { - if (OB_FAIL(do_flashback_(tenant_info))) { + if (OB_FAIL(do_flashback_())) { LOG_WARN("failed to flashback", KR(ret), K(tenant_info)); } } else if (tenant_info.is_switching_to_primary_status()) { @@ -195,9 +196,7 @@ int ObTenantRoleTransitionService::do_failover_to_primary_(const share::ObAllTen int ObTenantRoleTransitionService::do_prepare_flashback_(share::ObAllTenantInfo &tenant_info) { int ret = OB_SUCCESS; - DEBUG_SYNC(BEFORE_PREPARE_FLASHBACK); - if (OB_FAIL(check_inner_stat())) { LOG_WARN("error unexpected", KR(ret), K(tenant_id_), KP(sql_proxy_), KP(rpc_proxy_)); } else if (OB_UNLIKELY(!(tenant_info.is_prepare_flashback_for_failover_to_primary_status() @@ -225,7 +224,7 @@ int ObTenantRoleTransitionService::do_prepare_flashback_(share::ObAllTenantInfo DEBUG_SYNC(BEFORE_DO_FLASHBACK); if (OB_FAIL(ret)) { - } else if (OB_FAIL(do_flashback_(tenant_info))) { + } else if (OB_FAIL(do_flashback_())) { LOG_WARN("failed to prepare flashback", KR(ret), K(tenant_info)); } return ret; @@ -249,6 +248,8 @@ int ObTenantRoleTransitionService::do_prepare_flashback_for_switch_to_primary_( } else if (OB_UNLIKELY(switchover_epoch_ != tenant_info.get_switchover_epoch())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("tenant switchover status not valid", KR(ret), K(tenant_info), K_(switchover_epoch)); + } else if (OB_FAIL(wait_ls_balance_task_finish_())) { + LOG_WARN("failed to wait ls balance task finish", KR(ret)); } else if (OB_FAIL(switchover_update_tenant_status(tenant_id_, true /* switch_to_primary */, tenant_info.get_tenant_role(), @@ -276,8 +277,6 @@ int ObTenantRoleTransitionService::do_prepare_flashback_for_failover_to_primary_ } else if (OB_UNLIKELY(switchover_epoch_ != tenant_info.get_switchover_epoch())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("tenant switchover status not valid", KR(ret), K(tenant_info), K_(switchover_epoch)); - } else if (OB_FAIL(update_tenant_stat_info_())) { - LOG_WARN("failed to update tenant stat info", KR(ret), K(tenant_info), K_(switchover_epoch)); } else if (OB_FAIL(OB_PRIMARY_STANDBY_SERVICE.do_recover_tenant(tenant_id_, share::PREPARE_FLASHBACK_FOR_FAILOVER_TO_PRIMARY_SWITCHOVER_STATUS, obrpc::ObRecoverTenantArg::RecoverType::CANCEL, @@ -286,6 +285,8 @@ int ObTenantRoleTransitionService::do_prepare_flashback_for_failover_to_primary_ // reset error code and USER_ERROR to avoid print recover error log ret = OB_ERR_UNEXPECTED; LOG_USER_ERROR(OB_ERR_UNEXPECTED, "can not do recover cancel for tenant, failed to failover to primary"); + } else if (OB_FAIL(wait_ls_balance_task_finish_())) { + LOG_WARN("failed to wait ls balance task finish", KR(ret)); } else if (OB_FAIL(ObAllTenantInfoProxy::update_tenant_switchover_status( tenant_id_, sql_proxy_, tenant_info.get_switchover_epoch(), tenant_info.get_switchover_status(), share::FLASHBACK_SWITCHOVER_STATUS))) { @@ -318,29 +319,36 @@ int ObTenantRoleTransitionService::do_switch_access_mode_to_flashback( return ret; } -int ObTenantRoleTransitionService::do_flashback_(const share::ObAllTenantInfo &tenant_info) +int ObTenantRoleTransitionService::do_flashback_() { int ret = OB_SUCCESS; ObTimeoutCtx ctx; logservice::ObLogService *log_service = NULL; ObLSStatusOperator status_op; + ObAllTenantInfo tenant_info; if (OB_FAIL(check_inner_stat())) { LOG_WARN("error unexpected", KR(ret), K(tenant_id_), KP(sql_proxy_), KP(rpc_proxy_)); - } else if (OB_UNLIKELY(!tenant_info.is_flashback_status() - || switchover_epoch_ != tenant_info.get_switchover_epoch())) { + } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info( + tenant_id_, sql_proxy_, false, tenant_info))) { + LOG_WARN("failed to load tenant info", KR(ret), K(tenant_id_)); + } else if (OB_UNLIKELY(!tenant_info.is_flashback_status() || + switchover_epoch_ != + tenant_info.get_switchover_epoch())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("tenant switchover status not valid", KR(ret), K(tenant_info), K(switchover_epoch_)); } else if (OB_FAIL(status_op.create_abort_ls_in_switch_tenant( - tenant_id_, tenant_info.get_switchover_status(), - tenant_info.get_switchover_epoch(), *sql_proxy_))) { + tenant_id_, tenant_info.get_switchover_status(), + tenant_info.get_switchover_epoch(), *sql_proxy_))) { LOG_WARN("failed to create abort ls", KR(ret), K_(tenant_id), K(tenant_info)); - } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, GCONF.internal_sql_execute_timeout))) { + } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx( + ctx, GCONF.internal_sql_execute_timeout))) { LOG_WARN("failed to set default timeout", KR(ret)); - } else if (OB_ISNULL(log_service = MTL(logservice::ObLogService*))) { + } else if (OB_ISNULL(log_service = MTL(logservice::ObLogService *))) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("failed to get MTL log_service", KR(ret), K(tenant_id_)); - } else if (OB_FAIL(log_service->flashback(tenant_id_, tenant_info.get_sync_scn(), ctx.get_timeout()))) { + } else if (OB_FAIL(log_service->flashback( + tenant_id_, tenant_info.get_sync_scn(), ctx.get_timeout()))) { LOG_WARN("failed to flashback", KR(ret), K(tenant_id_), K(tenant_info)); } else { CLUSTER_EVENT_ADD_LOG(ret, "flashback end", @@ -372,7 +380,7 @@ int ObTenantRoleTransitionService::do_switch_access_mode_to_append( { int ret = OB_SUCCESS; palf::AccessMode access_mode = logservice::ObLogService::get_palf_access_mode(target_tenant_role); - const SCN &ref_scn = tenant_info.get_sync_scn(); + SCN ref_scn; if (OB_FAIL(check_inner_stat())) { LOG_WARN("error unexpected", KR(ret), K(tenant_id_), KP(sql_proxy_), KP(rpc_proxy_)); } else if (OB_UNLIKELY(!tenant_info.is_switching_to_primary_status() @@ -381,6 +389,8 @@ int ObTenantRoleTransitionService::do_switch_access_mode_to_append( ret = OB_INVALID_ARGUMENT; LOG_WARN("tenant switchover status not valid", KR(ret), K(tenant_info), K(target_tenant_role), K(switchover_epoch_)); + } else if (OB_FAIL(get_tenant_ref_scn_(ref_scn))) { + LOG_WARN("failed to get tenant ref_scn", KR(ret)); //TODO(yaoying):xianming } else if (OB_FAIL(change_ls_access_mode_(access_mode, ref_scn))) { LOG_WARN("failed to get access mode", KR(ret), K(access_mode), K(ref_scn), K(tenant_info)); @@ -420,6 +430,76 @@ int ObTenantRoleTransitionService::do_switch_access_mode_to_append( return ret; } +int ObTenantRoleTransitionService::get_tenant_ref_scn_(share::SCN &ref_scn) +{ + int ret = OB_SUCCESS; + ObTimeoutCtx ctx; + ref_scn.set_min(); + if (OB_FAIL(check_inner_stat())) { + LOG_WARN("error unexpected", KR(ret), K(tenant_id_), KP(sql_proxy_), KP(rpc_proxy_)); + } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, GCONF.internal_sql_execute_timeout))) { + LOG_WARN("failed to set default timeout", KR(ret)); + } else { + const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id_); + share::ObLSStatusInfoArray status_info_array; + ObLSStatusOperator status_op; + ObLSRecoveryStatOperator recovery_op; + ObLSRecoveryStat ls_recovery_stat; + START_TRANSACTION(sql_proxy_, exec_tenant_id) + if (FAILEDx(status_op.get_all_ls_status_by_order_for_switch_tenant(tenant_id_, + false/* ignore_need_create_abort */, status_info_array, trans))) { + LOG_WARN("fail to get_all_ls_status_by_order", KR(ret), K_(tenant_id)); + } else if (OB_UNLIKELY(0 == status_info_array.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ls status", KR(ret), K(tenant_id_), K(status_info_array)); + } + for (int64_t i = 0; i < status_info_array.count() && OB_SUCC(ret); ++i) { + const share::ObLSStatusInfo &status_info = status_info_array.at(i); + //Get the largest sync_scn of all LS by Lock and read sync_scn of all LSs + //Ensure that the syncpoint reports of all LS have been submitted + //When each LS reports the synchronization progress, it will lock and check whether it is rolled back + if (OB_FAIL(recovery_op.get_ls_recovery_stat(status_info.tenant_id_, status_info.ls_id_, + true, ls_recovery_stat, trans))) { + LOG_WARN("failed to get ls recovery stat", KR(ret), K(status_info)); + } else if (ls_recovery_stat.get_sync_scn() > ref_scn || ls_recovery_stat.get_create_scn() > ref_scn) { + ref_scn = share::SCN::max(ls_recovery_stat.get_sync_scn(), ls_recovery_stat.get_create_scn()); + } + } + + END_TRANSACTION(trans); + } + return ret; +} + +int ObTenantRoleTransitionService::wait_ls_balance_task_finish_() +{ + int ret = OB_SUCCESS; + if (OB_FAIL(check_inner_stat())) { + LOG_WARN("error unexpected", KR(ret), K(tenant_id_), KP(sql_proxy_), KP(rpc_proxy_)); + } else { + bool is_finish = false; + ObBalanceTaskHelper ls_balance_task; + while (!THIS_WORKER.is_timeout() && OB_SUCC(ret) && !is_finish) { + if (FALSE_IT(ret = ObBalanceTaskHelperTableOperator::pop_task(tenant_id_, + *sql_proxy_, ls_balance_task))) { + } else if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + is_finish = true; + } else if (OB_SUCC(ret)) { + usleep(100L * 1000L); + LOG_INFO("has balance task not finish", K(ls_balance_task)); + } + } + if (OB_SUCC(ret)) { + if (THIS_WORKER.is_timeout() || !is_finish) { + ret = OB_TIMEOUT; + LOG_WARN("failed to wait ls balance task finish", KR(ret), K(is_finish)); + } + } + } + return ret; +} + int ObTenantRoleTransitionService::do_switch_access_mode_to_raw_rw( const share::ObAllTenantInfo &tenant_info) { @@ -445,19 +525,6 @@ int ObTenantRoleTransitionService::do_switch_access_mode_to_raw_rw( return ret; } -int ObTenantRoleTransitionService::update_tenant_stat_info_() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(check_inner_stat())) { - LOG_WARN("error unexpected", KR(ret), K(tenant_id_), KP(sql_proxy_), KP(rpc_proxy_)); - } else { - //TODO, get all ls sync_scn, update __all_tenant_info, - //the new sync_scn cannot larger than recovery_scn and sync_scn of sys_ls - } - LOG_INFO("[ROLE_TRANSITION] finish update tenant stat info", KR(ret), K(tenant_id_)); - return ret; -} - int ObTenantRoleTransitionService::change_ls_access_mode_(palf::AccessMode target_access_mode, const SCN &ref_scn) { @@ -531,10 +598,46 @@ int ObTenantRoleTransitionService::change_ls_access_mode_(palf::AccessMode targe } +template +int do_nonblock_renew(const ARRAY_L &array_l, const ARRAY_R &array_r, const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(GCTX.location_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("location service is null", KR(ret)); + } else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || 0 > array_l.count() + || 0 > array_r.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(array_l), K(array_r)); + } else { + for (int64_t i = 0; i < array_l.count(); ++i) { + const ObLSID ls_id = array_l.at(i).get_ls_id(); + bool found = false; + FOREACH_CNT_X(r, array_r, !found) { + if (OB_ISNULL(r)) { + LOG_WARN("r is null", KR(ret), K(array_r)); + } else if (*r == ls_id) { + found = true; + } + } + if (!found) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS !=(tmp_ret = GCTX.location_service_->nonblock_renew( + GCONF.cluster_id, tenant_id, ls_id))) { + LOG_WARN("failed to renew location", KR(ret), K(tenant_id), K(ls_id)); + } + } + } + } + return ret; +} + int ObTenantRoleTransitionService::get_ls_access_mode_(ObIArray &ls_access_info) { int ret = OB_SUCCESS; ls_access_info.reset(); + ObArray success_ls_ids; if (OB_FAIL(check_inner_stat())) { LOG_WARN("error unexpected", KR(ret), K(tenant_id_), KP(sql_proxy_), KP(rpc_proxy_)); } else if (OB_ISNULL(GCTX.location_service_)) { @@ -589,7 +692,6 @@ int ObTenantRoleTransitionService::get_ls_access_mode_(ObIArrayget_ls_id(), - leader, result->get_mode_version(), result->get_access_mode()))) { - LOG_WARN("failed to init info", KR(ret), KPC(result), K(leader)); + result->get_addr(), result->get_mode_version(), result->get_access_mode()))) { + LOG_WARN("failed to init info", KR(ret), KPC(result)); } else if (OB_FAIL(ls_access_info.push_back(info))) { LOG_WARN("failed to push back info", KR(ret), K(info)); + } else if (OB_TMP_FAIL(success_ls_ids.push_back(info.get_ls_id()))) { + LOG_WARN("fail to push back", KR(ret), KR(tmp_ret), K(success_ls_ids), K(info)); } } LOG_INFO("[ROLE_TRANSITION] get ls access mode", KR(ret), K(arg)); - if (OB_FAIL(ret)) { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS !=(tmp_ret = GCTX.location_service_->nonblock_renew( - GCONF.cluster_id, tenant_id_, arg.get_ls_id()))) { - LOG_WARN("failed to renew location", KR(ret), K(tenant_id_), - K(arg)); - } + } + + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = do_nonblock_renew(status_info_array, success_ls_ids, tenant_id_))) { + LOG_WARN("failed to renew location", KR(ret), KR(tmp_ret), K(tenant_id_), K(status_info_array), K(success_ls_ids)); } } } @@ -637,6 +738,7 @@ int ObTenantRoleTransitionService::do_change_ls_access_mode_(const ObIArray success_ls_ids; if (OB_FAIL(check_inner_stat())) { LOG_WARN("error unexpected", KR(ret), K(tenant_id_), KP(sql_proxy_), KP(rpc_proxy_)); } else if (OB_UNLIKELY(0== ls_access_info.count() @@ -656,7 +758,7 @@ int ObTenantRoleTransitionService::do_change_ls_access_mode_(const ObIArrayget_result())) { LOG_WARN("failed to change ls mode", KR(ret), KPC(result)); + } else if (OB_TMP_FAIL(success_ls_ids.push_back(result->get_ls_id()))) { + LOG_WARN("fail to push back", KR(ret), KR(tmp_ret), K(success_ls_ids), K(result)); } - LOG_INFO("[ROLE_TRANSITION] change ls access mode", KR(ret), K(arg), KPC(result), - "leader", proxy.get_dests().at(i)); - if (OB_FAIL(ret)) { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != - (tmp_ret = GCTX.location_service_->nonblock_renew( - GCONF.cluster_id, tenant_id_, arg.get_ls_id()))) { - LOG_WARN("failed to renew location", KR(ret), K(tenant_id_), - K(arg)); - } - } + LOG_INFO("[ROLE_TRANSITION] change ls access mode", KR(ret), K(arg), KPC(result), K(proxy.get_dests())); }// end for + + if (OB_FAIL(ret)) { + if (OB_TMP_FAIL(do_nonblock_renew(ls_access_info, success_ls_ids, tenant_id_))) { + LOG_WARN("failed to renew location", KR(ret), KR(tmp_ret), K(tenant_id_), K(ls_access_info), K(success_ls_ids)); + } + } } } return ret; } +int ObTenantRoleTransitionService::check_and_update_sys_ls_recovery_stat_in_switchover_( + const uint64_t tenant_id, + const bool switch_to_primary, + ObMySQLTransaction &trans, + const SCN &max_sys_ls_sync_scn/* SYS LS real max sync scn */, + const SCN &target_tenant_sync_scn/* tenant target sync scn in switchover */) +{ + int ret = OB_SUCCESS; + bool need_update = false; + ObLSRecoveryStat ls_recovery_stat; + ObLSRecoveryStatOperator recovery_op; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) + || max_sys_ls_sync_scn > target_tenant_sync_scn)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", KR(ret), K(tenant_id), K(max_sys_ls_sync_scn), + K(target_tenant_sync_scn)); + } + // Get latest SYS LS sync scn in table, which means SYS log recovery point + else if (OB_FAIL(recovery_op.get_ls_recovery_stat(tenant_id, SYS_LS, + false /* for update */, ls_recovery_stat, trans))) { + LOG_WARN("failed to get SYS ls recovery stat", KR(ret), K(tenant_id)); + } else if (max_sys_ls_sync_scn < ls_recovery_stat.get_sync_scn()) { + // SYS LS sync scn can not be greater than real max sync scn + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected SYS LS sync scn in table, it is greater than max sync scn", + K(tenant_id), K(max_sys_ls_sync_scn), K(ls_recovery_stat), K(switch_to_primary)); + } + // When switchover from STANDBY to PRIMARY, + // SYS LS sync scn in table must be same with its real max sync scn + else if (switch_to_primary && max_sys_ls_sync_scn != ls_recovery_stat.get_sync_scn()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("SYS LS sync scn in table is not latest, unexpected error", K(tenant_id), + K(switch_to_primary), K(ls_recovery_stat), K(max_sys_ls_sync_scn)); + } else if (max_sys_ls_sync_scn == ls_recovery_stat.get_sync_scn()) { + need_update = false; + } else { + // SYS LS recovery point should be updated to latest during switchover. + need_update = true; + if (OB_FAIL(recovery_op.update_sys_ls_sync_scn(tenant_id, trans, max_sys_ls_sync_scn))) { + LOG_WARN("update sys ls sync scn failed", KR(ret), K(tenant_id), K(max_sys_ls_sync_scn), + K(ls_recovery_stat), K(switch_to_primary)); + } + } + + LOG_INFO("check and update SYS LS sync scn in table", KR(ret), K(need_update), K(tenant_id), + K(target_tenant_sync_scn), K(max_sys_ls_sync_scn), K(switch_to_primary), K(ls_recovery_stat)); + return ret; +} + int ObTenantRoleTransitionService::switchover_update_tenant_status( const uint64_t tenant_id, const bool switch_to_primary, @@ -745,9 +893,9 @@ int ObTenantRoleTransitionService::switchover_update_tenant_status( } else if (OB_UNLIKELY(0 >= status_info_array.count())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls list is null", KR(ret), K(tenant_id), K(status_info_array)); - } else if (OB_FAIL(get_checkpoints_by_rpc_(tenant_id, status_info_array, false/* check_sync_to_latest */, + } else if (OB_FAIL(get_checkpoints_by_rpc(tenant_id, status_info_array, false/* check_sync_to_latest */, switchover_checkpoints))) { - LOG_WARN("fail to get_checkpoints_by_rpc_", KR(ret), K(tenant_id), K(status_info_array)); + LOG_WARN("fail to get_checkpoints_by_rpc", KR(ret), K(tenant_id), K(status_info_array)); } else if (OB_FAIL(get_max_checkpoint_scn_(switchover_checkpoints, max_checkpoint_scn))) { LOG_WARN("fail to get_max_checkpoint_scn_", KR(ret), K(tenant_id), K(switchover_checkpoints)); } else if (OB_FAIL(get_sys_ls_sync_scn_(switchover_checkpoints, max_sys_ls_sync_scn, is_sync_to_latest))) { @@ -784,6 +932,10 @@ int ObTenantRoleTransitionService::switchover_update_tenant_status( ret = OB_NEED_RETRY; LOG_WARN("switchover may concurrency, need retry", KR(ret), K(old_switchover_epoch), K(old_status), K(tmp_tenant_info)); + } else if (OB_FAIL(check_and_update_sys_ls_recovery_stat_in_switchover_(tenant_id, + switch_to_primary, trans, max_sys_ls_sync_scn, final_sync_scn))) { + LOG_WARN("fail to check and update sys ls recovery stat in switchover", KR(ret), K(tenant_id), + K(switch_to_primary), K(max_sys_ls_sync_scn)); } else { if (switch_to_primary) { // switch_to_primary @@ -933,9 +1085,9 @@ int ObTenantRoleTransitionService::check_sync_to_latest_(const uint64_t tenant_i LOG_WARN("failed to get ls status", KR(ret), K(tenant_id)); } else if (OB_FAIL(sys_ls_status_array.push_back(ls_status))) { LOG_WARN("fail to push back", KR(ret), K(ls_status), K(sys_ls_status_array)); - } else if (OB_FAIL(get_checkpoints_by_rpc_(tenant_id, sys_ls_status_array, true/* check_sync_to_latest */, + } else if (OB_FAIL(get_checkpoints_by_rpc(tenant_id, sys_ls_status_array, true/* check_sync_to_latest */, switchover_checkpoints))) { - LOG_WARN("fail to get_checkpoints_by_rpc_", KR(ret), K(tenant_id), K(sys_ls_status_array)); + LOG_WARN("fail to get_checkpoints_by_rpc", KR(ret), K(tenant_id), K(sys_ls_status_array)); } else if (1 != switchover_checkpoints.count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("checkpoints count is not 1", KR(ret), K(switchover_checkpoints), K(tenant_id), @@ -953,9 +1105,9 @@ int ObTenantRoleTransitionService::check_sync_to_latest_(const uint64_t tenant_i } else if (OB_FAIL(ls_status_op.get_all_ls_status_by_order_for_switch_tenant(tenant_id, true/* ignore_need_create_abort */, all_ls_status_array, *sql_proxy_))) { LOG_WARN("failed to get_all_ls_status_by_order", KR(ret), K(tenant_id)); - } else if (OB_FAIL(get_checkpoints_by_rpc_(tenant_id, all_ls_status_array, true/* check_sync_to_latest */, + } else if (OB_FAIL(get_checkpoints_by_rpc(tenant_id, all_ls_status_array, true/* check_sync_to_latest */, switchover_checkpoints))) { - LOG_WARN("fail to get_checkpoints_by_rpc_", KR(ret), K(tenant_id), K(all_ls_status_array)); + LOG_WARN("fail to get_checkpoints_by_rpc", KR(ret), K(tenant_id), K(all_ls_status_array)); } else if (switchover_checkpoints.count() != all_ls_status_array.count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect checkpoints count", KR(ret), K(switchover_checkpoints), K(tenant_id), K(tenant_info), @@ -987,7 +1139,7 @@ int ObTenantRoleTransitionService::check_sync_to_latest_(const uint64_t tenant_i return ret; } -int ObTenantRoleTransitionService::get_checkpoints_by_rpc_(const uint64_t tenant_id, +int ObTenantRoleTransitionService::get_checkpoints_by_rpc(const uint64_t tenant_id, const share::ObLSStatusInfoIArray &status_info_array, const bool check_sync_to_latest, ObIArray &checkpoints) @@ -995,10 +1147,8 @@ int ObTenantRoleTransitionService::get_checkpoints_by_rpc_(const uint64_t tenant int ret = OB_SUCCESS; checkpoints.reset(); - LOG_INFO("start to get_checkpoints_by_rpc_", KR(ret), K(tenant_id), K(check_sync_to_latest), K(status_info_array)); - if (OB_FAIL(check_inner_stat())) { - LOG_WARN("error unexpected", KR(ret), KP(sql_proxy_)); - } else if (!is_user_tenant(tenant_id) || 0 >= status_info_array.count()) { + LOG_INFO("start to get_checkpoints_by_rpc", KR(ret), K(tenant_id), K(check_sync_to_latest), K(status_info_array)); + if (!is_user_tenant(tenant_id) || 0 >= status_info_array.count()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(status_info_array)); } else if (OB_ISNULL(GCTX.location_service_) || OB_ISNULL(GCTX.srv_rpc_proxy_)) { @@ -1012,7 +1162,7 @@ int ObTenantRoleTransitionService::get_checkpoints_by_rpc_(const uint64_t tenant int64_t rpc_count = 0; for (int64_t i = 0; OB_SUCC(ret) && i < status_info_array.count(); ++i) { const ObLSStatusInfo &info = status_info_array.at(i); - const int64_t timeout_us = INT64_MAX == THIS_WORKER.get_timeout_remain() ? + const int64_t timeout_us = !THIS_WORKER.is_timeout_ts_valid() ? GCONF.rpc_timeout : THIS_WORKER.get_timeout_remain(); if (OB_FAIL(GCTX.location_service_->get_leader( GCONF.cluster_id, tenant_id, info.ls_id_, false, leader))) { @@ -1033,7 +1183,6 @@ int ObTenantRoleTransitionService::get_checkpoints_by_rpc_(const uint64_t tenant LOG_WARN("wait all batch result failed", KR(ret), KR(tmp_ret)); ret = OB_SUCCESS == ret ? tmp_ret : ret; } else if (rpc_count != return_code_array.count() || - rpc_count != proxy.get_args().count() || rpc_count != proxy.get_results().count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("rpc count not equal to result count", KR(ret), @@ -1180,7 +1329,6 @@ void ObTenantRoleTransitionService::broadcast_tenant_info(const char* const log_ LOG_WARN("wait all batch result failed", KR(ret), KR(tmp_ret)); ret = OB_SUCCESS == ret ? tmp_ret : ret; } else if (rpc_count != return_code_array.count() || - rpc_count != proxy.get_args().count() || rpc_count != proxy.get_results().count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("rpc count not equal to result count", KR(ret), @@ -1191,11 +1339,10 @@ void ObTenantRoleTransitionService::broadcast_tenant_info(const char* const log_ ObRefreshTenantInfoRes res; for (int64_t i = 0; OB_SUCC(ret) && i < return_code_array.count(); ++i) { ret = return_code_array.at(i); - const ObAddr &dest = proxy.get_dests().at(i); if (OB_FAIL(ret)) { - LOG_WARN("send rpc is failed", KR(ret), K(i), K(dest)); + LOG_WARN("send rpc is failed", KR(ret), K(i), K(proxy.get_dests())); } else { - LOG_INFO("refresh_tenant_info success", KR(ret), K(i), K(dest)); + LOG_INFO("refresh_tenant_info success", KR(ret), K(i), K(proxy.get_dests())); } } } diff --git a/src/rootserver/ob_tenant_role_transition_service.h b/src/rootserver/ob_tenant_role_transition_service.h index 32c8ae885..0852090ac 100644 --- a/src/rootserver/ob_tenant_role_transition_service.h +++ b/src/rootserver/ob_tenant_role_transition_service.h @@ -55,6 +55,17 @@ public: static const char* const RESTORE_TO_STANDBY_LOG_MOD_STR; }; +/** + * @description: + * Find the ls_id that are not in the array_r from array_l, and refresh the location of these ls + * @param[in] array_l + * @param[in] array_r + * @param[in] tenant_id + * @return return code + */ +template +int do_nonblock_renew(const ARRAY &array_l, const ARRAY &array_r, const uint64_t tenant_id); + /*description: * for primary to standby and standby to primary */ @@ -81,6 +92,11 @@ struct LSAccessModeInfo const int64_t mode_version, const palf::AccessMode &access_mode); int assign(const LSAccessModeInfo &other); void reset(); + share::ObLSID get_ls_id() const + { + return ls_id_; + } + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(leader_addr), K_(mode_version), K_(access_mode)); uint64_t tenant_id_; @@ -104,6 +120,9 @@ public: int do_switch_access_mode_to_append(const share::ObAllTenantInfo &tenant_info, const share::ObTenantRole &target_tenant_role); int do_switch_access_mode_to_raw_rw(const share::ObAllTenantInfo &tenant_info); + int get_tenant_ref_scn_(share::SCN &ref_scn); + //before primary tenant switchover to standby, must set sys LS's sync_scn to lastest + int report_sys_ls_sync_scn_(); void set_switchover_epoch(const int64_t switchover_epoch) { switchover_epoch_ = switchover_epoch; @@ -155,20 +174,6 @@ public: void broadcast_tenant_info(const char* const log_mode); -private: - int do_failover_to_primary_(const share::ObAllTenantInfo &tenant_info); - int do_prepare_flashback_(share::ObAllTenantInfo &tenant_info); - int do_flashback_(const share::ObAllTenantInfo &tenant_info); - int change_ls_access_mode_(palf::AccessMode target_access_mode, - const share::SCN &ref_scn); - int update_tenant_stat_info_(); - int get_ls_access_mode_(ObIArray &ls_access_info); - int do_change_ls_access_mode_(const ObIArray &ls_access_info, - palf::AccessMode target_access_mode, - const share::SCN &ref_scn); - int do_switch_access_mode_to_flashback( - const share::ObAllTenantInfo &tenant_info); - /** * @description: * get specified ls list sync_scn by rpc, which is named as checkpoint @@ -178,13 +183,26 @@ private: * @param[out] checkpoints switchover checkpoint * @return return code */ - int get_checkpoints_by_rpc_( + static int get_checkpoints_by_rpc( const uint64_t tenant_id, const share::ObLSStatusInfoIArray &status_info_array, const bool get_latest_scn, ObIArray &checkpoints ); +private: + int do_failover_to_primary_(const share::ObAllTenantInfo &tenant_info); + int do_prepare_flashback_(share::ObAllTenantInfo &tenant_info); + int do_flashback_(); + int change_ls_access_mode_(palf::AccessMode target_access_mode, + const share::SCN &ref_scn); + int get_ls_access_mode_(ObIArray &ls_access_info); + int do_change_ls_access_mode_(const ObIArray &ls_access_info, + palf::AccessMode target_access_mode, + const share::SCN &ref_scn); + int do_switch_access_mode_to_flashback( + const share::ObAllTenantInfo &tenant_info); + /** * @description: * get max ls sync_scn across all ls in checkpoints array @@ -221,6 +239,13 @@ private: int do_prepare_flashback_for_switch_to_primary_(share::ObAllTenantInfo &tenant_info); int do_prepare_flashback_for_failover_to_primary_(share::ObAllTenantInfo &tenant_info); + int check_and_update_sys_ls_recovery_stat_in_switchover_( + const uint64_t tenant_id, + const bool switch_to_primary, + ObMySQLTransaction &trans, + const SCN &max_sys_ls_sync_scn/* SYS LS real max sync scn */, + const SCN &target_tenant_sync_scn/* tenant target sync scn in switchover */); + int wait_ls_balance_task_finish_(); private: const static int64_t SEC_UNIT = 1000L * 1000L; diff --git a/src/rootserver/ob_tenant_thread_helper.cpp b/src/rootserver/ob_tenant_thread_helper.cpp new file mode 100755 index 000000000..fdf96da50 --- /dev/null +++ b/src/rootserver/ob_tenant_thread_helper.cpp @@ -0,0 +1,344 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX RS +#include "ob_tenant_thread_helper.h" +#include "lib/profile/ob_trace_id.h" +#include "lib/thread/thread_mgr.h"//TG +#include "share/ob_errno.h" +#include "share/schema/ob_schema_struct.h"//ObTenantInfo +#include "share/schema/ob_schema_service.h"//ObMultiSchemaService +#include "share/schema/ob_schema_getter_guard.h"//ObSchemaGetterGuard +#include "share/ob_share_util.h"//ObShareUtil +#include "share/ob_tenant_info_proxy.h"//ObAllTenantInfo +#include "share/restore/ob_physical_restore_table_operator.h"//restore_job +#include "share/restore/ob_physical_restore_info.h"//restore_info +#include "share/ob_primary_zone_util.h"//get_ls_primary_zone_priority +#include "observer/ob_server_struct.h"//GCTX +#include "share/ls/ob_ls_recovery_stat_operator.h" //ObLSRecoveryStatOperator +#include "logservice/ob_log_service.h"//get_palf_role +#include "src/logservice/palf_handle_guard.h"//palf_handle +#include "share/scn.h"//SCN + +#include "ob_tenant_info_loader.h" // ObTenantInfoLoader + + +namespace oceanbase +{ +using namespace common; +using namespace share; +using namespace transaction; +using namespace palf; +using namespace lib; +namespace rootserver +{ +//////////////ObTenantThreadHelper +int ObTenantThreadHelper::create( + const char* thread_name, int tg_def_id, ObTenantThreadHelper &tenant_thread) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_created_)) { + ret = OB_INIT_TWICE; + LOG_WARN("has inited", KR(ret)); + } else if (OB_ISNULL(thread_name)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("thread name is null", KR(ret)); + } else if (OB_FAIL(TG_CREATE_TENANT(tg_def_id, tg_id_))) { + LOG_ERROR("create tg failed", KR(ret)); + } else if (OB_FAIL(TG_SET_RUNNABLE(tg_id_, *this))) { + LOG_ERROR("set thread runable fail", KR(ret)); + } else if (OB_FAIL(thread_cond_.init(ObWaitEventIds::REENTRANT_THREAD_COND_WAIT))) { + LOG_WARN("fail to init cond, ", KR(ret)); + } else { + thread_name_ = thread_name; + is_created_ = true; + is_first_time_to_start_ = true; + } + return ret; +} + +int ObTenantThreadHelper::start() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_created_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (is_first_time_to_start_) { + if (OB_FAIL(TG_START(tg_id_))) { + LOG_WARN("fail ed to start at first time", KR(ret), K(tg_id_), K(thread_name_)); + } else { + is_first_time_to_start_ = false; + } + } else if (OB_FAIL(TG_REENTRANT_LOGICAL_START(tg_id_))) { + LOG_WARN("failed to start", KR(ret)); + } + LOG_INFO("[TENANT THREAD] thread start", KR(ret), K(tg_id_), K(thread_name_)); + return ret; +} + +void ObTenantThreadHelper::stop() +{ + LOG_INFO("[TENANT THREAD] thread stop start", K(tg_id_), K(thread_name_)); + if (-1 != tg_id_) { + TG_REENTRANT_LOGICAL_STOP(tg_id_); + } + LOG_INFO("[TENANT THREAD] thread stop finish", K(tg_id_), K(thread_name_)); +} + +void ObTenantThreadHelper::wait() +{ + LOG_INFO("[TENANT THREAD] thread wait start", K(tg_id_), K(thread_name_)); + if (-1 != tg_id_) { + TG_REENTRANT_LOGICAL_WAIT(tg_id_); + } + LOG_INFO("[TENANT THREAD] thread wait finish", K(tg_id_), K(thread_name_)); +} + +void ObTenantThreadHelper::mtl_thread_stop() +{ + LOG_INFO("[TENANT THREAD] thread stop start", K(tg_id_), K(thread_name_)); + if (-1 != tg_id_) { + TG_STOP(tg_id_); + } + LOG_INFO("[TENANT THREAD] thread stop finish", K(tg_id_), K(thread_name_)); +} + +void ObTenantThreadHelper::mtl_thread_wait() +{ + LOG_INFO("[TENANT THREAD] thread wait start", K(tg_id_), K(thread_name_)); + if (-1 != tg_id_) { + { + ObThreadCondGuard guard(thread_cond_); + thread_cond_.broadcast(); + } + TG_WAIT(tg_id_); + is_first_time_to_start_ = true; + } + LOG_INFO("[TENANT THREAD] thread wait finish", K(tg_id_), K(thread_name_)); +} +void ObTenantThreadHelper::destroy() +{ + LOG_INFO("[TENANT THREAD] thread destory start", K(tg_id_), K(thread_name_)); + if (-1 != tg_id_) { + TG_STOP(tg_id_); + { + ObThreadCondGuard guard(thread_cond_); + thread_cond_.broadcast(); + } + TG_WAIT(tg_id_); + TG_DESTROY(tg_id_); + tg_id_ = -1; + } + is_created_ = false; + is_first_time_to_start_ = true; + LOG_INFO("[TENANT THREAD] thread destory finish", K(tg_id_), K(thread_name_)); +} + +void ObTenantThreadHelper::switch_to_follower_forcedly() +{ + stop(); +} +int ObTenantThreadHelper::switch_to_leader() +{ + int ret = OB_SUCCESS; + LOG_INFO("[TENANT THREAD] thread start", K(tg_id_), K(thread_name_)); + if (OB_FAIL(start())) { + LOG_WARN("failed to start thread", KR(ret)); + } else { + ObThreadCondGuard guard(thread_cond_); + if (OB_FAIL(thread_cond_.broadcast())) { + LOG_WARN("failed to weakup thread cond", KR(ret)); + } + } + LOG_INFO("[TENANT THREAD] thread start finish", K(tg_id_), K(thread_name_)); + return ret; +} +int ObTenantThreadHelper::wait_tenant_data_version_ready_( + const uint64_t tenant_id, const uint64_t &data_version) +{ + int ret = OB_SUCCESS; + bool is_ready = false; + uint64_t tenant_data_version = 0; + while (!is_ready && !has_set_stop()) { + ret = OB_SUCCESS; + + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, tenant_data_version))) { + LOG_WARN("failed to get min data version", KR(ret), K(tenant_id)); + } else if (tenant_data_version < data_version) { + ret = OB_NEED_WAIT; + LOG_WARN("tenant version not target, need wait", KR(ret), + K(tenant_data_version), K(data_version)); + } else { + is_ready = true; + } + + if (!is_ready) { + idle(10 * 1000 * 1000); + } + } + + if (has_set_stop()) { + LOG_WARN("thread has been stopped", K(is_ready), K(tenant_id)); + ret = OB_IN_STOP_STATE; + } + return ret; +} + +int ObTenantThreadHelper::wait_tenant_schema_and_version_ready_( + const uint64_t tenant_id, const uint64_t &data_version) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema ptr is null", KR(ret), KP(GCTX.schema_service_)); + } else if (OB_FAIL(wait_tenant_data_version_ready_(tenant_id, data_version))) { + LOG_WARN("failed to wait tenant data version", KR(ret), K(tenant_id), K(data_version)); + } else { + bool is_ready = false; + share::schema::ObTenantSchema tenant_schema; + while (!is_ready && !has_set_stop()) { + ret = OB_SUCCESS; + if (OB_FAIL(get_tenant_schema(tenant_id, tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(tenant_id)); + } else if (!tenant_schema.is_normal()) { + ret = OB_NEED_WAIT; + LOG_WARN("tenant schema not ready, no need tenant balance", KR(ret), K(tenant_schema)); + } else { + is_ready = true; + } + + if (!is_ready) { + idle(10 * 1000 *1000); + } + } + + if (has_set_stop()) { + LOG_WARN("thread has been stopped", K(is_ready), K(tenant_id)); + ret = OB_IN_STOP_STATE; + } + } + return ret; +} + +void ObTenantThreadHelper::run1() { + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_created_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else { + lib::set_thread_name(thread_name_); + LOG_INFO("thread run", K(thread_name_)); + do_work(); + } +} +void ObTenantThreadHelper::idle(const int64_t idle_time_us) +{ + ObThreadCondGuard guard(thread_cond_); + thread_cond_.wait_us(idle_time_us); +} + +int ObTenantThreadHelper::get_tenant_schema(const uint64_t tenant_id, + share::schema::ObTenantSchema &tenant_schema) +{ + int ret = OB_SUCCESS; + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObTenantSchema *cur_tenant_schema = NULL; + if (!is_valid_tenant_id(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant id is invalid", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", KR(ret), KP(GCTX.schema_service_)); + } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( + OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, + cur_tenant_schema))) { + LOG_WARN("failed to get tenant ids", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(cur_tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant not exist", KR(ret), K(tenant_id)); + } else if (OB_FAIL(tenant_schema.assign(*cur_tenant_schema))) { + LOG_WARN("failed to get cur tenant schema", KR(ret), KP(cur_tenant_schema)); + } + return ret; +} + +int ObTenantThreadHelper::get_zone_priority(const ObZone &primary_zone, + const share::schema::ObTenantSchema &tenant_schema, + ObSqlString &primary_zone_str) +{ + int ret = OB_SUCCESS; + primary_zone_str.reset(); + if (OB_UNLIKELY(!tenant_schema.is_valid() || primary_zone.is_empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(primary_zone), K(tenant_schema)); + } else if (OB_FAIL(ObPrimaryZoneUtil::get_ls_primary_zone_priority(primary_zone, + tenant_schema, primary_zone_str))) { + LOG_WARN("failed to get ls primary zone priority", KR(ret), K(primary_zone), K(tenant_schema)); + } + LOG_DEBUG("get zone priority", KR(ret), K(primary_zone_str), K(tenant_schema)); + return ret; +} + +//TODO meta tenant and user tenant maybe not in same observer +int ObTenantThreadHelper::check_can_do_recovery_(const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + if (!is_user_tenant(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only user tenant need check recovery", KR(ret), K(tenant_id)); + } else { + MTL_SWITCH(tenant_id) { + share::ObTenantRole::Role tenant_role = MTL_GET_TENANT_ROLE(); + if (is_primary_tenant(tenant_role) || is_standby_tenant(tenant_role)) { + } else if (is_restore_tenant(tenant_role)) { + //need to check success to create init ls + share::ObPhysicalRestoreTableOperator restore_table_operator; + share::ObPhysicalRestoreJob job_info; + if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql can't null", K(ret), K(GCTX.sql_proxy_)); + } else if (OB_FAIL(restore_table_operator.init(GCTX.sql_proxy_, tenant_id))) { + LOG_WARN("fail to init restore table operator", KR(ret), K(tenant_id)); + } else if (OB_FAIL(restore_table_operator.get_job_by_tenant_id(tenant_id, + job_info))) { + LOG_WARN("fail to get restore job", K(ret), K(tenant_id)); + } else if (job_info.is_valid_status_to_recovery()) { + //can do recovery + } else { + ret = OB_NEED_WAIT; + LOG_WARN("restore tenant not valid to recovery", KR(ret), K(job_info)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected tenant role", KR(ret), K(tenant_role)); + } + } + } + return ret; +} + +void ObTenantThreadHelper::wakeup() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_created_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + ObThreadCondGuard guard(thread_cond_); + thread_cond_.broadcast(); + } +} + +}//end of rootserver +} diff --git a/src/rootserver/ob_tenant_thread_helper.h b/src/rootserver/ob_tenant_thread_helper.h new file mode 100644 index 000000000..f05f0be46 --- /dev/null +++ b/src/rootserver/ob_tenant_thread_helper.h @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2021 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_ROOTSERVER_OB_TENANT_THREAD_HELPER_H +#define OCEANBASE_ROOTSERVER_OB_TENANT_THREAD_HELPER_H +#include "lib/thread/ob_reentrant_thread.h"//ObRsReentrantThread +#include "logservice/ob_log_base_type.h" +#include "share/ob_thread_mgr.h" //OBTGDefIDEnum +#include "lib/thread/thread_mgr_interface.h" // TGRunnable +#include "lib/lock/ob_thread_cond.h"//ObThreadCond +#include "common/ob_zone.h"//ObZone + + +namespace oceanbase +{ +namespace obrpc +{ +class ObSrvRpcProxy; +} +namespace common +{ +class ObSqlString; +class ObMySQLTransaction; +} +namespace share +{ +class ObAllTenantInfo; +class ObLSRecoveryStat; +namespace schema +{ +class ObTenantSchema; +} +} +namespace logservice +{ +class ObLogHandler; +} + +namespace rootserver +{ +class ObTenantThreadHelper : public lib::TGRunnable, + public logservice::ObIRoleChangeSubHandler +{ +public: + ObTenantThreadHelper() : tg_id_(-1), thread_cond_(), is_created_(false), is_first_time_to_start_(true), thread_name_("") {} + virtual ~ObTenantThreadHelper() {} + virtual void do_work() = 0; + virtual void run1() override; + virtual void destroy(); + int start(); + void stop(); + void wait(); + void mtl_thread_stop(); + void mtl_thread_wait(); + int create(const char* thread_name, int tg_def_id, ObTenantThreadHelper &tenant_thread); + void idle(const int64_t idle_time_us); + void wakeup(); +public: + virtual void switch_to_follower_forcedly() override; + + virtual int switch_to_leader() override; + virtual int switch_to_follower_gracefully() override + { + stop(); + return OB_SUCCESS; + } + virtual int resume_leader() override + { + return OB_SUCCESS; + } +public: +#define DEFINE_MTL_FUNC(TYPE)\ + static int mtl_init(TYPE *&ka) {\ + int ret = OB_SUCCESS;\ + if (OB_ISNULL(ka)) {\ + ret = OB_ERR_UNEXPECTED;\ + } else if (OB_FAIL(ka->init())) {\ + }\ + return ret;\ + }\ + static void mtl_stop(TYPE *&ka) {\ + if (OB_NOT_NULL(ka)) {\ + ka->mtl_thread_stop();\ + }\ + }\ + static void mtl_wait(TYPE *&ka) {\ + if (OB_NOT_NULL(ka)) {\ + ka->mtl_thread_wait();\ + }\ + } + + + static int get_tenant_schema(const uint64_t tenant_id, + share::schema::ObTenantSchema &tenant_schema); + static int get_zone_priority(const ObZone &primary_zone, + const share::schema::ObTenantSchema &tenant_schema, + common::ObSqlString &primary_zone_str); +protected: + int wait_tenant_schema_and_version_ready_( + const uint64_t tenant_id, const uint64_t &data_version); + int wait_tenant_data_version_ready_( + const uint64_t tenant_id, const uint64_t &data_version); + int check_can_do_recovery_(const uint64_t tenant_id); + int tg_id_; +private: + common::ObThreadCond thread_cond_; + bool is_created_; + bool is_first_time_to_start_; + const char* thread_name_; +}; + + +} +} + + +#endif /* !OCEANBASE_ROOTSERVER_OB_TENANT_THREAD_HELPER_H */ diff --git a/src/rootserver/ob_tenant_transfer_service.cpp b/src/rootserver/ob_tenant_transfer_service.cpp new file mode 100644 index 000000000..f466da4c6 --- /dev/null +++ b/src/rootserver/ob_tenant_transfer_service.cpp @@ -0,0 +1,1566 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX BALANCE_TRANSFER + +#include "rootserver/ob_tenant_transfer_service.h" +#include "observer/ob_server_struct.h" //GCTX +#include "lib/mysqlclient/ob_mysql_proxy.h" // ObISqlClient, SMART_VAR +#include "lib/utility/ob_tracepoint.h" // ERRSIM_POINT_DEF +#include "share/ls/ob_ls_info.h" // MemberList +#include "share/transfer/ob_transfer_task_operator.h" // ObTransferTaskOperator +#include "share/schema/ob_multi_version_schema_service.h" // ObMultiSchemaService +#include "share/schema/ob_part_mgr_util.h" // ObPartitionSchemaIter +#include "share/tablet/ob_tablet_to_ls_operator.h" // ObTabletToLSOperator +#include "share/ob_rpc_struct.h" // ObStartTransferTaskArg +#include "share/ob_balance_define.h" // ObBalanceTaskID +#include "share/location_cache/ob_location_service.h" // location_service_ +#include "share/ob_srv_rpc_proxy.h" // srv_rpc_proxy_ +#include "storage/ob_common_id_utils.h" // ObCommonIDUtils +#include "storage/tablelock/ob_table_lock_service.h" // ObTableLockService +#include "observer/ob_inner_sql_connection.h" // ObInnerSQLConnection +#include "storage/ddl/ob_ddl_lock.h" // ObDDLLock +#include "storage/tablelock/ob_lock_inner_connection_util.h" +//#include "storage/high_availability/ob_transfer_struct.h" + +namespace oceanbase +{ +using namespace share; +using namespace share::schema; +using namespace common; +using namespace transaction; +using namespace transaction::tablelock; +using namespace observer; + +namespace rootserver +{ +#define TTS_INFO(fmt, args...) FLOG_INFO("[TENANT_TRANSFER] " fmt, ##args) + +int ObTenantTransferService::init() +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret)); + } else if (OB_FAIL(ObTenantThreadHelper::create( + "TntTransf", + lib::TGDefIDs::TenantTransferService, + *this))) { + LOG_WARN("failed to create thread", KR(ret)); + } else if (OB_FAIL(ObTenantThreadHelper::start())) { + LOG_WARN("fail to start thread", KR(ret)); + } else { + tenant_id_ = MTL_ID(); + sql_proxy_ = GCTX.sql_proxy_; + is_inited_ = true; + } + return ret; +} + +void ObTenantTransferService::destroy() +{ + is_inited_ = false; + tenant_id_ = OB_INVALID_TENANT_ID; + sql_proxy_ = NULL; + ObTenantThreadHelper::destroy(); + TTS_INFO("ObTenantTransferService destory"); +} + +void ObTenantTransferService::do_work() +{ + int ret = OB_SUCCESS; + bool tenant_schema_is_ready = false; + if (IS_NOT_INIT || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!is_user_tenant(tenant_id_))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant transfer service must run on user tenant", KR(ret), K_(tenant_id)); + } else { + const int64_t thread_count = lib::is_mini_mode() ? MINI_MODE_THREAD_COUNT : THREAD_COUNT; + const uint64_t thread_idx = get_thread_idx(); + if (OB_UNLIKELY(thread_idx >= thread_count)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected tread_idx", KR(ret), K(thread_idx), K(thread_count), K_(tenant_id)); + } else { + int tmp_ret = OB_SUCCESS; + int64_t idle_time_us = IDLE_TIME_US; + while (!has_set_stop()) { + int64_t all_tasks_count = 0; + int64_t thread_task_count = 0; + idle_time_us = IDLE_TIME_US; + ObCurTraceId::init(GCONF.self_addr_); + ObArray task_status; + if (OB_FAIL(check_tenant_schema_is_ready_(tenant_schema_is_ready))) { + LOG_WARN("check tenant schema failed", KR(ret), K_(tenant_id), K(tenant_schema_is_ready)); + } else if (!tenant_schema_is_ready) { + ret = OB_NEED_WAIT; + if (REACH_TIME_INTERVAL(10 * 1000 * 1000L)) { // 10s + LOG_WARN("tenant schema is not ready, need wait", KR(ret), K_(tenant_id)); + } + } else if (OB_FAIL(ObTransferTaskOperator::get_all_task_status( + *sql_proxy_, + tenant_id_, + task_status))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_TRACE("no transfer task", KR(ret), K_(tenant_id)); + } else { + LOG_WARN("fail to get", KR(ret), K_(tenant_id)); + } + } else { + all_tasks_count = task_status.count(); + int ret_fail = OB_SUCCESS; + ARRAY_FOREACH_X(task_status, idx, cnt, !has_set_stop()) { // ignore ret + const ObTransferTask::TaskStatus &task_stat = task_status.at(idx); + if (thread_idx == task_stat.get_task_id().id() % thread_count) { + ++thread_task_count; + if (OB_FAIL(process_task_(task_stat))) { + LOG_WARN("process task failed", KR(ret), K(task_stat), K(thread_idx)); + ret_fail = ret; + ret = OB_SUCCESS; + } + } else { + LOG_TRACE("task not for this thread", K(task_stat), K(thread_idx)); + } + } // end ARRAY_FOREACH + ret = OB_SUCC(ret) ? ret_fail : ret; + } + if (OB_FAIL(ret) && OB_NEED_WAIT != ret) { + idle_time_us = BUSY_IDLE_TIME_US; + } + TTS_INFO("finish one round", KR(ret), K(all_tasks_count), K(thread_task_count), K(thread_idx)); + idle(idle_time_us); + }// end while + } + } +} + +int ObTenantTransferService::process_task_(const ObTransferTask::TaskStatus &task_stat) +{ + int ret = OB_SUCCESS; + ObTransferStatus status; + ObTransferPartList all_part_list; + ObTransferPartList finished_part_list; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!task_stat.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid task_stat", KR(ret), K(task_stat)); + } else if (task_stat.get_status().is_init_status()) { + if (OB_FAIL(process_init_task_(task_stat.get_task_id()))) { + LOG_WARN("fail to process init task", KR(ret), K(task_stat)); + } + } else if (task_stat.get_status().is_finish_status()) { + if (OB_FAIL(try_clear_transfer_task( + task_stat.get_task_id(), + all_part_list, + finished_part_list))) { + LOG_WARN("fail to process finish task", KR(ret), K(task_stat)); + } + } else { + // do nothing + } + return ret; +} + +int ObTenantTransferService::process_init_task_(const ObTransferTaskID task_id) +{ + int ret = OB_SUCCESS; + ObTransferTask task; + ObMySQLTransaction trans; + bool member_list_is_same = false; + bool update_comment_to_wait_for_member_list = false; + ObArray tablet_ids; + ObTableLockOwnerID lock_owner_id; + ObTransferPartList not_exist_part_list; + ObTransferPartList lock_conflict_part_list; + ObDisplayTabletList table_lock_tablet_list; + ObTimeoutCtx ctx; + + const int64_t start_time = ObTimeUtil::current_time(); + TTS_INFO("start to process init task", K(task_id), K(start_time)); + if (IS_NOT_INIT || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(! task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid task_id", KR(ret), K(task_id)); + } else if (OB_FAIL(set_transaction_timeout_(ctx))) { + LOG_WARN("set transaction timeout failed", KR(ret), K(ctx)); + } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id_))) { + LOG_WARN("trans start failed", KR(ret), K_(tenant_id)); + } else if (OB_FAIL(ObTransferTaskOperator::get( + trans, + tenant_id_, + task_id, + true/*for_update*/, + task))) { + LOG_WARN("fail to get task", KR(ret), K_(tenant_id), K(task_id), K(task)); + } else if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid init task", KR(ret), K(task)); + } else if (!task.get_status().is_init_status()) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("task status is not init", KR(ret), K(task)); + } else if (FALSE_IT(ObCurTraceId::set(task.get_trace_id()))) { + } else if (OB_FAIL(check_ls_member_list_( + *sql_proxy_, + task.get_src_ls(), + task.get_dest_ls(), + member_list_is_same))) { // can't use trans + LOG_WARN("fail to check ls member_list", KR(ret), K(task), K(member_list_is_same)); + } else if (!member_list_is_same) { + ret = OB_NEED_RETRY; + TTS_INFO("member_lists of src_ls and dest_ls are not same, need retry", + KR(ret), K_(tenant_id), K(member_list_is_same), K(task)); + if (task.get_comment() != ObTransferTaskComment::WAIT_FOR_MEMBER_LIST) { + update_comment_to_wait_for_member_list = true; + } + } else if (OB_FAIL(lock_table_and_part_( + trans, + task.get_src_ls(), + task.get_part_list(), + not_exist_part_list, + lock_conflict_part_list, + table_lock_tablet_list, + tablet_ids, + lock_owner_id))) { + LOG_WARN("lock table and part failed", KR(ret), K(task), K(tablet_ids), + K(lock_owner_id), K(not_exist_part_list), K(lock_conflict_part_list), K(table_lock_tablet_list)); + } else if (tablet_ids.empty()) { + if (OB_UNLIKELY(not_exist_part_list.empty() && lock_conflict_part_list.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not exist and lock conflict part list can not be empty when tablet_ids are empty", + KR(ret), K(task), K(tablet_ids)); + } else if (OB_FAIL(ObTransferTaskOperator::finish_task_from_init( + trans, + tenant_id_, + task_id, + task.get_status(), + task.get_part_list(), + not_exist_part_list, + lock_conflict_part_list, + ObTransferStatus(ObTransferStatus::COMPLETED), + OB_SUCCESS, + ObTransferTaskComment::TASK_COMPLETED_AS_NO_VALID_PARTITION))) { + LOG_WARN("finish task from init failed", KR(ret), K_(tenant_id), + K(task), K(not_exist_part_list), K(lock_conflict_part_list)); + } + } else if (OB_FAIL(generate_tablet_list_(tablet_ids, task.get_tablet_list()))) { + LOG_WARN("fail to generate tablet list", KR(ret), K(task), K(tablet_ids)); + } else if (OB_FAIL(ObTransferTaskOperator::update_to_start_status( + trans, + tenant_id_, + task.get_task_id(), + task.get_status(), + task.get_part_list(), + not_exist_part_list, + lock_conflict_part_list, + table_lock_tablet_list, + task.get_tablet_list(), + ObTransferStatus(ObTransferStatus::START), + lock_owner_id))) { + LOG_WARN("fail to update task status from init to start", KR(ret), K_(tenant_id), K(task), + K(not_exist_part_list), K(lock_conflict_part_list), K(table_lock_tablet_list)); + } else { + // ObTransferEventRecorder::record_advance_transfer_status_event( + // tenant_id_, task.get_task_id(), task.get_src_ls(), task.get_dest_ls(), + // ObTransferStatus(ObTransferStatus::START), OB_SUCCESS); + TTS_INFO("process init task success", K_(tenant_id), K(task), + K(not_exist_part_list), K(lock_conflict_part_list), K(table_lock_tablet_list)); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + if ((OB_NEED_RETRY == ret && update_comment_to_wait_for_member_list) + || OB_TRANS_TIMEOUT == ret || OB_TIMEOUT == ret) { + ObTimeoutCtx ctx_comment; + int tmp_ret = OB_SUCCESS; + ObTransferTaskComment comment = (OB_NEED_RETRY == ret) + ? ObTransferTaskComment::WAIT_FOR_MEMBER_LIST + : ObTransferTaskComment::TRANSACTION_TIMEOUT; + if (OB_TMP_FAIL(ctx_comment.set_timeout(2000000/*2s*/))) { // overwrite timeout + LOG_WARN("set default timeout ctx failed", KR(tmp_ret), K(ctx_comment), K_(tenant_id), K(task_id)); + } else if (OB_TMP_FAIL(ObTransferTaskOperator::update_comment( + *sql_proxy_, + tenant_id_, + task_id, + comment))) { + LOG_WARN("update comment failed", KR(tmp_ret), K_(tenant_id), K(task_id), K(comment)); + } + } + + if (OB_SUCC(ret)) { + DEBUG_SYNC(AFTER_TRANSFER_PROCESS_INIT_TASK_AND_BEFORE_NOTIFY_STORAGE); + } + if (OB_FAIL(ret) || task.get_tablet_list().empty()) { + } else if (OB_FAIL(notify_storage_transfer_service_(task_id, task.get_dest_ls()))) { + LOG_WARN("notify storage transfer service failed", KR(ret), K(task_id), K(task)); + } + TTS_INFO("process init task finish", KR(ret), K(task_id), + "cost_time", ObTimeUtil::current_time() - start_time, K(task), + K(not_exist_part_list), K(lock_conflict_part_list), K(table_lock_tablet_list)); + return ret; +} + +ERRSIM_POINT_DEF(EN_TENANT_TRANSFER_CHECK_LS_MEMBER_LIST_NOT_SAME); + +int ObTenantTransferService::check_ls_member_list_( + common::ObISQLClient &sql_proxy, + const ObLSID &src_ls, + const ObLSID &dest_ls, + bool &is_same) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + is_same = false; + SMART_VAR(ObISQLClient::ReadResult, result) { + ObSqlString sql; + ObString src_ls_member_list_str; + ObString dest_ls_member_list_str; + ObLSReplica::MemberList src_ls_member_list; + ObLSReplica::MemberList dest_ls_member_list; + common::sqlclient::ObMySQLResult *res = NULL; + if (OB_FAIL(sql.assign_fmt( + "SELECT PAXOS_MEMBER_LIST FROM %s WHERE TENANT_ID = %lu AND ROLE = 'LEADER'" + " AND LS_ID IN (%ld, %ld) ORDER BY FIELD(LS_ID, %ld, %ld)", + OB_GV_OB_LOG_STAT_TNAME, + tenant_id_, + src_ls.id(), + dest_ls.id(), + src_ls.id(), + dest_ls.id()))) { + LOG_WARN("fail to assign sql", KR(ret), K_(tenant_id), K(src_ls), K(dest_ls)); + } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(sql)); + } else if (OB_ISNULL(res = result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K(sql)); + } else if (OB_FAIL(res->next())) { + LOG_WARN("next failed, neither src_ls nor dest_ls was found", KR(ret), K_(tenant_id), K(src_ls), K(dest_ls)); + } else if (OB_FAIL(res->get_varchar("PAXOS_MEMBER_LIST", src_ls_member_list_str))) { + LOG_WARN("fail to get PAXOS_MEMBER_LIST", KR(ret), K_(tenant_id), K(src_ls), K(dest_ls)); + } else if (OB_FAIL(res->next())) { + LOG_WARN("next failed, src_ls or dest_ls not found", KR(ret), K_(tenant_id), K(src_ls), K(dest_ls)); + } else if (OB_FAIL(res->get_varchar("PAXOS_MEMBER_LIST", dest_ls_member_list_str))) { + LOG_WARN("fail to get PAXOS_MEMBER_LIST", KR(ret), K_(tenant_id), K(src_ls), K(dest_ls)); + } else if (OB_FAIL(ObLSReplica::text2member_list( + to_cstring(src_ls_member_list_str), + src_ls_member_list))) { + LOG_WARN("text2member_list failed", KR(ret), K_(tenant_id), K(src_ls), K(src_ls_member_list_str)); + } else if (OB_FAIL(ObLSReplica::text2member_list( + to_cstring(dest_ls_member_list_str), + dest_ls_member_list))) { + LOG_WARN("text2member_list failed", KR(ret), K_(tenant_id), K(dest_ls), K(dest_ls_member_list_str)); + } else if (ObLSReplica::servers_in_member_list_are_same(src_ls_member_list, dest_ls_member_list)) { + is_same = true; + } else { + is_same = false; + } + + if (OB_FAIL(ret)) { + if (OB_UNLIKELY(OB_ITER_END == ret)) { // read less than two rows + ret = OB_LEADER_NOT_EXIST; + LOG_WARN("leader of src_ls or dest_ls not found", KR(ret), K_(tenant_id), K(src_ls), + K(dest_ls), K(src_ls_member_list_str), K(dest_ls_member_list_str)); + } else { + LOG_WARN("get ls member_list from inner table failed", KR(ret), K_(tenant_id), + K(src_ls), K(dest_ls), K(src_ls_member_list_str), K(dest_ls_member_list_str)); + } + } else if (OB_SUCC(res->next())) { // make sure read only two rows + ret = OB_ERR_UNEXPECTED; + LOG_WARN("read too much ls from inner table", KR(ret), K_(tenant_id), + K(src_ls), K(dest_ls), K(src_ls_member_list_str), K(dest_ls_member_list_str), K(sql)); + } else if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("next failed", KR(ret), K_(tenant_id), K(src_ls), K(dest_ls), + K(sql), K(src_ls_member_list_str), K(dest_ls_member_list_str)); + } else { + ret = OB_SUCCESS; + if (is_same) { + LOG_INFO("member_list of src_ls and dest_ls are same", KR(ret), K_(tenant_id), K(src_ls), + K(dest_ls), K(is_same), K(src_ls_member_list), K(dest_ls_member_list)); + } else { + LOG_WARN("member_list of src_ls and dest_ls are not same", KR(ret), K_(tenant_id), K(src_ls), + K(dest_ls), K(is_same), K(src_ls_member_list), K(dest_ls_member_list)); + } + } + } // end SMART_VAR + } + if (OB_SUCC(ret)) { + if (EN_TENANT_TRANSFER_CHECK_LS_MEMBER_LIST_NOT_SAME) { + is_same = false; + TTS_INFO("errsim tenant transfer check ls member list not same", K(is_same)); + } + } + return ret; +} + +ERRSIM_POINT_DEF(EN_TENANT_TRANSFER_ALL_LIST_EMPTY); + +int ObTenantTransferService::lock_table_and_part_( + ObMySQLTransaction &trans, + const share::ObLSID &src_ls, + share::ObTransferPartList &part_list, + share::ObTransferPartList ¬_exist_part_list, + share::ObTransferPartList &lock_conflict_part_list, + share::ObDisplayTabletList &table_lock_tablet_list, + ObIArray &tablet_ids, + ObTableLockOwnerID &lock_owner_id) +{ + int ret = OB_SUCCESS; + DEBUG_SYNC(BEFORE_TRANSFER_LOCK_TABLE_AND_PART); + tablet_ids.reset(); + lock_owner_id = OB_INVALID_INDEX; + ObTransferPartList ordered_part_list; + ObArenaAllocator allocator; + const int64_t start_time = ObTimeUtility::current_time(); + TTS_INFO("lock table and part start", KR(ret), K(src_ls), K(part_list), K(start_time)); + if (IS_NOT_INIT || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(part_list.empty() || !src_ls.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid part_list", KR(ret), K(part_list), K(src_ls)); + } else if (OB_ISNULL(MTL(ObTableLockService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("mtl ObTableLockService is null", KR(ret), K_(tenant_id)); + } else if (OB_FAIL(MTL(ObTableLockService*)->generate_owner_id(lock_owner_id))) { + LOG_WARN("generate owner id failed", KR(ret), K_(tenant_id), K(lock_owner_id)); + } else if (OB_FAIL(ordered_part_list.assign(part_list))) { + LOG_WARN("assign failed", KR(ret), K(part_list), K(ordered_part_list)); + } else { + part_list.reset(); + ObSimpleTableSchemaV2 *table_schema = NULL; + ObTransferPartInfo::Compare cmp; + std::sort(ordered_part_list.begin(), ordered_part_list.end(), cmp); + + ARRAY_FOREACH(ordered_part_list, idx) { + ObLSID ls_id; + ObTabletID tablet_id; + int64_t part_idx = OB_INVALID_INDEX; + int64_t subpart_idx = OB_INVALID_INDEX; + const ObTransferPartInfo &part_info = ordered_part_list.at(idx); + const ObObjectID table_id = part_info.table_id(); + const ObObjectID part_object_id = part_info.part_object_id(); + bool is_not_exist = false; + bool is_lock_conflict = false; + if (OB_NOT_NULL(table_schema) && table_schema->get_table_id() == table_id) { + // use previous table_schema + } else if (OB_FAIL(get_latest_table_schema_(allocator, table_id, table_schema))) { + if (OB_TABLE_NOT_EXIST == ret) { + is_not_exist = true; + ret = OB_SUCCESS; + TTS_INFO("discard part_info because table does not exist", + KR(ret), K(table_id), K_(tenant_id), K(is_not_exist)); + } else { + LOG_WARN("get latest table schema failed", KR(ret), K_(tenant_id), K(table_id)); + } + } + + if (OB_FAIL(ret) || OB_ISNULL(table_schema) || is_not_exist || is_lock_conflict) { + // skip + } else if (OB_FAIL(add_in_trans_lock_and_refresh_schema_( + trans, + src_ls, + part_info, + allocator, + table_schema, + tablet_id, + part_idx, + subpart_idx))) { + if (OB_TRY_LOCK_ROW_CONFLICT == ret || OB_ERR_EXCLUSIVE_LOCK_CONFLICT == ret) { + is_lock_conflict = true; + TTS_INFO("lock conflict when adding in_trans lock", + KR(ret), K(part_info), K(tablet_id), K(part_idx), K(subpart_idx), K(is_not_exist)); + ret = OB_SUCCESS; + } else if (OB_ENTRY_NOT_EXIST == ret + || OB_TABLE_NOT_EXIST == ret /*|| OB_TRY_LOCK_PART_NOT_EXIST == ret*/) { + is_not_exist = true; + TTS_INFO("part_info not exist when adding in_trans lock", + KR(ret), K(part_info), K(tablet_id), K(part_idx), K(subpart_idx), K(is_not_exist)); + ret = OB_SUCCESS; + } else { + LOG_WARN("add in trans lock and refresh schema failed", KR(ret), + K(part_info), K(tablet_id), K(part_idx), K(subpart_idx)); + } + } else if (ObTabletToLSTableOperator::get_ls_by_tablet( + *sql_proxy_, + tenant_id_, + tablet_id, + ls_id)) { // double check to make sure tablet exists on src_ls + if (OB_ENTRY_NOT_EXIST == ret) { + is_not_exist = true; + TTS_INFO("discard part_info because tablet not exists", + KR(ret), K(part_info), K(tablet_id), K(part_idx), K(subpart_idx), K(is_not_exist)); + ret = OB_SUCCESS; + } else { + LOG_WARN("get ls by tablet failed", KR(ret), K_(tenant_id), K(tablet_id), K(ls_id)); + } + } else if (ls_id != src_ls) { + is_not_exist = true; + TTS_INFO("discard part_info because tablet is not exist on src_ls", + KR(ret), K_(tenant_id), K(tablet_id), K(part_info), K(ls_id), K(src_ls)); + ret = OB_SUCCESS; + } + + if (OB_FAIL(ret) || is_not_exist || is_lock_conflict) { + // skip + } else if (OB_ISNULL(table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table schema should not be null", KR(ret), K(part_info), K(tablet_id)); + } else if (OB_FAIL(add_out_trans_lock_(trans, lock_owner_id, *table_schema, part_info, tablet_id))) { + LOG_WARN("add out trans table and online ddl lock failed", + KR(ret), K(lock_owner_id), K(part_info), K(tablet_id)); + } else if (OB_FAIL(part_list.push_back(part_info))) { // add to part_list after lock successfully + LOG_WARN("push back failed", KR(ret), K_(tenant_id), K(part_info), K(part_list)); + } else if (OB_FAIL(record_need_move_table_lock_tablet_(*table_schema, tablet_id, table_lock_tablet_list))) { + LOG_WARN("record need move table lock tablet failed", KR(ret), K(tablet_id), K(table_lock_tablet_list)); + } else if (OB_FAIL(tablet_ids.push_back(tablet_id))) { + LOG_WARN("push back failed", KR(ret), K(tablet_id), K(tablet_ids), K(part_info)); + } else if (OB_FAIL(generate_related_tablet_ids_(*table_schema, part_idx, subpart_idx, tablet_ids))) { + LOG_WARN("generate related tablet_ids failed", KR(ret), + "table_id", table_schema->get_table_id(), K(part_idx), K(subpart_idx), K(tablet_ids)); + } + + if (OB_FAIL(ret)) { + } else if (is_not_exist) { + if (OB_FAIL(not_exist_part_list.push_back(part_info))) { + LOG_WARN("push back failed", KR(ret), K(part_info), K(not_exist_part_list)); + } + } else if (is_lock_conflict) { + if (OB_FAIL(lock_conflict_part_list.push_back(part_info))) { + LOG_WARN("push back failed", KR(ret), K(part_info), K(lock_conflict_part_list)); + } + } + + // Try to limit the number of tablet_list to TABLET_COUNT_THRESHOLD_IN_A_TRANSFER. + // This is not a precise limit. In the worst case, there will be + // TABLET_COUNT_THRESHOLD_IN_A_TRANSFER + 128(max index number) + 2(lob tablet number) tablets in tablet_list. + if (OB_SUCC(ret) && tablet_ids.count() > TABLET_COUNT_THRESHOLD_IN_A_TRANSFER) { + break; + } + } // end ARRAY_FOREACH + } + // errsim + if (OB_SUCC(ret) && EN_TENANT_TRANSFER_ALL_LIST_EMPTY) { + part_list.reset(); + not_exist_part_list.reset(); + tablet_ids.reset(); + } + TTS_INFO("lock table and part finish", KR(ret), "cost_time", ObTimeUtility::current_time() - start_time, + K(part_list), K(not_exist_part_list), K(lock_conflict_part_list), K(tablet_ids), K(lock_owner_id)); + return ret; +} + +int ObTenantTransferService::add_table_lock_( + ObMySQLTransaction &trans, + share::schema::ObSimpleTableSchemaV2 &table_schema, + const share::ObTransferPartInfo &part_info, + const bool is_out_trans, + const ObTableLockOwnerID &lock_owner_id) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *conn = NULL; + if (OB_UNLIKELY(!part_info.is_valid() + || (table_schema.get_table_id() != part_info.table_id()) + || (is_out_trans && (!lock_owner_id.is_valid())))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(part_info), + "table_id of schema", table_schema.get_table_id(), K(lock_owner_id)); + } else if (OB_ISNULL(conn = dynamic_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("connection is null", KR(ret), K_(tenant_id), K(part_info)); + } else if (table_schema.is_offline_ddl_table()) { + ret = OB_TRY_LOCK_ROW_CONFLICT; + TTS_INFO("treat offline ddl hidden table as locked table, do not transfer", KR(ret), K(part_info)); + } else if (table_schema.is_global_index_table() + || PARTITION_LEVEL_ZERO == table_schema.get_part_level()) { + ObLockTableRequest table_lock_arg; + table_lock_arg.lock_mode_ = ROW_SHARE; + table_lock_arg.timeout_us_ = 0; // try lock + if (table_schema.is_global_index_table()) { + // lock primary table for global index table + table_lock_arg.table_id_ = table_schema.get_data_table_id(); + } else { + table_lock_arg.table_id_ = part_info.table_id(); + } + if (is_out_trans) { + table_lock_arg.owner_id_ = lock_owner_id; + table_lock_arg.op_type_ = OUT_TRANS_LOCK; + } else { + table_lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; + } + if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(tenant_id_, table_lock_arg, conn))) { + LOG_WARN("lock table failed", KR(ret), K(table_lock_arg)); + } + } else { + ObLockPartitionRequest part_lock_arg; + part_lock_arg.lock_mode_ = ROW_SHARE; + part_lock_arg.timeout_us_ = 0; // try lock + part_lock_arg.table_id_ = part_info.table_id(); + part_lock_arg.part_object_id_ = part_info.part_object_id(); + if (is_out_trans) { + part_lock_arg.owner_id_ = lock_owner_id; + part_lock_arg.op_type_ = OUT_TRANS_LOCK; + } else { + part_lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; + } + if (PARTITION_LEVEL_ONE == table_schema.get_part_level()) { + if (OB_FAIL(ObInnerConnectionLockUtil::lock_partition(tenant_id_, part_lock_arg, conn))) { + LOG_WARN("lock partition failed", KR(ret), K(part_lock_arg)); + } + } else if (PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + if (OB_FAIL(ObInnerConnectionLockUtil::lock_subpartition(tenant_id_, part_lock_arg, conn))) { + LOG_WARN("lock subpartition failed", KR(ret), K(part_lock_arg)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(part_info), "part_level", table_schema.get_part_level()); + } + } + return ret; +} + +int ObTenantTransferService::add_in_trans_lock_and_refresh_schema_( + ObMySQLTransaction &trans, + const share::ObLSID &src_ls, + const share::ObTransferPartInfo &part_info, + common::ObIAllocator &allocator, + ObSimpleTableSchemaV2 *&table_schema, + ObTabletID &tablet_id, + int64_t &part_idx, + int64_t &subpart_idx) +{ + int ret = OB_SUCCESS; + const uint64_t table_id = part_info.table_id(); + const bool is_out_trans = false; + const ObTableLockOwnerID invalid_owner_id; + ObSimpleTableSchemaV2 *new_table_schema = NULL; + const int64_t start_time = ObTimeUtility::current_time(); + TTS_INFO("add in trans lock and refresh schema start", K(start_time), K(part_info)); + if (IS_NOT_INIT || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!part_info.is_valid() || !src_ls.is_valid()) || OB_ISNULL(table_schema)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(part_info), K(src_ls), K(table_schema)); + } else if (OB_FAIL(add_table_lock_(trans, *table_schema, part_info, is_out_trans, invalid_owner_id))) { + if (OB_TRY_LOCK_ROW_CONFLICT != ret + && OB_ERR_EXCLUSIVE_LOCK_CONFLICT != ret + && OB_TABLE_NOT_EXIST != ret + && OB_ENTRY_NOT_EXIST != ret/*&& OB_TRY_LOCK_PART_NOT_EXIST != ret*/) { + LOG_WARN("add in trans table lock failed", + KR(ret), K(part_info), K(is_out_trans), K(invalid_owner_id)); + } + } + + if (OB_FAIL(ret)) { + } else if (table_schema->is_global_index_table()) { + DEBUG_SYNC(AFTER_TRANSFER_LOCK_TABLE_FOR_GLOBAL_INDEX); + } else { + DEBUG_SYNC(AFTER_TRANSFER_LOCK_TABLE_FOR_NORMAL_TABLE); + } + + TTS_INFO("add in trans table lock finish", KR(ret), + "cost_time", ObTimeUtility::current_time() - start_time, K(part_info)); + // After adding table lock, refresh schema to detect the concurrent online ddl + if (FAILEDx(get_latest_table_schema_(allocator, table_id, new_table_schema))) { + if (OB_TABLE_NOT_EXIST == ret) { + // With no table lock on the global index table, we lock primary table for it. + // So global index table may be deleted after adding table lock. + if (table_schema->is_global_index_table()) { + TTS_INFO("global index table not exist", KR(ret), K(part_info)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table cannot not exist", KR(ret), K(table_id), K_(tenant_id)); + } + } else { + LOG_WARN("get latest table schema failed", KR(ret), K(table_id)); + } + } else if (OB_FAIL(get_tablet_and_partition_idx_by_object_id_( + *new_table_schema, + part_info.part_object_id(), + tablet_id, + part_idx, + subpart_idx))) { + // tablet may be deleted by online ddl (e.g. partition split) after adding table lock + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("get tablet and partition idx by object_id failed", + KR(ret), K(part_info), K(tablet_id), K(part_idx), K(subpart_idx)); + } + } else if (OB_FAIL(ObOnlineDDLLock::lock_for_transfer_in_trans( + tenant_id_, + part_info.table_id(), + tablet_id, + 0,/*try lock*/ + trans))) { + if (OB_TRY_LOCK_ROW_CONFLICT != ret || OB_ERR_EXCLUSIVE_LOCK_CONFLICT != ret) { + LOG_WARN("lock for transfer in trans failed", KR(ret), + K_(tenant_id), "table_id", part_info.table_id(), K(tablet_id)); + } + } else { + table_schema = new_table_schema; + } + // Double check for online ddl on global index table. + // Global index table may be deleted after refreshing table schema and before adding online ddl lock. + // Online ddl lock can not check tablet exist, so it may lock successfully while tablet not exists. + if (OB_SUCC(ret) && table_schema->is_global_index_table()) { + if (OB_FAIL(get_latest_table_schema_(allocator, table_id, new_table_schema))) { + if (OB_TABLE_NOT_EXIST == ret) { + TTS_INFO("global index table not exist", KR(ret), K(table_id), K(part_info)); + } else { + LOG_WARN("get latest table schema failed", KR(ret), K(table_id), K(part_info)); + } + } + } + TTS_INFO("add in trans lock and refresh schema finish", KR(ret), + "cost_time", ObTimeUtility::current_time() - start_time, + K(part_info), K(tablet_id), K(part_idx), K(subpart_idx)); + return ret; +} + +int ObTenantTransferService::add_out_trans_lock_( + ObMySQLTransaction &trans, + const ObTableLockOwnerID &lock_owner_id, + share::schema::ObSimpleTableSchemaV2 &table_schema, + const share::ObTransferPartInfo &part_info, + const ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + const int64_t timeout_us = 0; // try lock + const bool is_out_trans = true; + const int64_t start_time = ObTimeUtility::current_time(); + if (OB_UNLIKELY(!lock_owner_id.is_valid() || !part_info.is_valid() || !tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(lock_owner_id), K(part_info), K(tablet_id)); + } else if (OB_FAIL(add_table_lock_(trans, table_schema, part_info, is_out_trans, lock_owner_id))) { + LOG_WARN("add out trans table lock failed", KR(ret), K(part_info), K(is_out_trans), K(lock_owner_id)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_for_transfer( + tenant_id_, + part_info.table_id(), + tablet_id, + lock_owner_id, + timeout_us, + trans))) { + LOG_WARN("lock for transfer failed", KR(ret), K_(tenant_id), + "table_id", part_info.table_id(), K(tablet_id), K(timeout_us)); + } + TTS_INFO("add out trans lock finish", "cost_time", ObTimeUtility::current_time() - start_time, + K(lock_owner_id), K(part_info), K(tablet_id)); + return ret; +} + +// record tablet_id which adds part table lock successfully +// table lock on this tablet will be moved from src_ls to dest_ls in the transfer process +int ObTenantTransferService::record_need_move_table_lock_tablet_( + share::schema::ObSimpleTableSchemaV2 &table_schema, + const ObTabletID &tablet_id, + share::ObDisplayTabletList &table_lock_tablet_list) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tablet_id", KR(ret), K(tablet_id)); + } else if (table_schema.is_global_index_table()) { + // no table lock on global index table because we lock primay table for it + } else if (PARTITION_LEVEL_ONE == table_schema.get_part_level() + || PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + if (OB_FAIL(table_lock_tablet_list.push_back(ObDisplayTabletID(tablet_id)))) { + LOG_WARN("push back failed", KR(ret), K(tablet_id)); + } + } else if (PARTITION_LEVEL_ZERO == table_schema.get_part_level()) { + // PARTITION_LEVEL_ZERO tables only need ROW_SHARE locks at the table level, but do not need ROW_SHARE locks at the Tablet level. + // Therefore, it is not need to be moved during Tablet Transfer. + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected part level", KR(ret), K(table_schema)); + } + return ret; +} + +int ObTenantTransferService::generate_related_tablet_ids_( + share::schema::ObSimpleTableSchemaV2 &table_schema, + const int64_t part_idx, + const int64_t subpart_idx, + common::ObIArray &tablet_ids) +{ + int ret = OB_SUCCESS; + ObArray related_table_schemas; + ObArenaAllocator allocator; + const uint64_t table_id = table_schema.get_table_id(); + const int64_t start_time = ObTimeUtility::current_time(); + if (IS_NOT_INIT || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (table_schema.is_global_index_table()) { + // skip get related tables + } else if (OB_UNLIKELY(! need_balance_table(table_schema))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only get related tables for user table and other need balance table", KR(ret), + K(table_id), K(table_schema)); + } else if (OB_FAIL(get_related_table_schemas_(*sql_proxy_, table_schema, allocator, related_table_schemas))) { + LOG_WARN("fail to get related table schemas", KR(ret), K_(tenant_id), K(table_id)); + } else { + ARRAY_FOREACH(related_table_schemas, idx) { + ObSimpleTableSchemaV2 *related_table_schema = related_table_schemas.at(idx); + ObTabletID related_tablet_id; + if (OB_ISNULL(related_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("related table schema is null", KR(ret), "primary_table", table_id); + } else if (OB_FAIL(get_tablet_by_partition_idx_( + *related_table_schema, + part_idx, + subpart_idx, + related_tablet_id))) { + LOG_WARN("fail to get tablet by partition_idx", KR(ret), "related_table_id", + related_table_schema->get_table_id(), K(part_idx), K(subpart_idx)); + } else if (OB_FAIL(tablet_ids.push_back(related_tablet_id))) { + LOG_WARN("fail to push back", KR(ret), K(related_tablet_id), K(tablet_ids)); + } + } + TTS_INFO("get related tablet_ids", KR(ret), K(table_id), "related_table_count", + related_table_schemas.count(), K(part_idx), K(subpart_idx), K(tablet_ids), + "cost_time", ObTimeUtility::current_time() - start_time); + } + return ret; +} + +int ObTenantTransferService::generate_tablet_list_( + const ObIArray &tablet_ids, + ObTransferTabletList &tablet_list) +{ + int ret = OB_SUCCESS; + tablet_list.reset(); + ObArray tablet_to_ls_infos; + const int64_t start_time = ObTimeUtility::current_time(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_FAIL(ObTabletToLSTableOperator::batch_get( + *sql_proxy_, + tenant_id_, + tablet_ids, + tablet_to_ls_infos))) { + LOG_WARN("batch get failed", KR(ret), K_(tenant_id), K(tablet_ids), K(tablet_to_ls_infos)); + } else if (OB_UNLIKELY(tablet_to_ls_infos.count() != tablet_ids.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("count not match", KR(ret), "tablet_ids count", tablet_ids.count(), + "tablet_to_ls_infos count", tablet_to_ls_infos.count(), K(tablet_ids), K(tablet_to_ls_infos)); + } else if (OB_FAIL(tablet_list.reserve(tablet_to_ls_infos.count()))) { + LOG_WARN("reserve failed", KR(ret), "count", tablet_to_ls_infos.count()); + } else { + ARRAY_FOREACH(tablet_to_ls_infos, idx) { + const ObTabletToLSInfo &tablet_to_ls_info = tablet_to_ls_infos.at(idx); + ObTransferTabletInfo transfer_tablet; + if (OB_FAIL(transfer_tablet.init( + tablet_to_ls_info.get_tablet_id(), + tablet_to_ls_info.get_transfer_seq()))) { + LOG_WARN("init failed", KR(ret), K(tablet_to_ls_info)); + } else if (OB_FAIL(tablet_list.push_back(transfer_tablet))) { + LOG_WARN("fail to push_back", KR(ret), K(transfer_tablet), K(tablet_list)); + } + } + TTS_INFO("generate tablet_list finish", KR(ret), + "cost_time", ObTimeUtility::current_time() - start_time, + "tablet_ids count", tablet_ids.count(), K(tablet_ids), + "tablet_list count", tablet_list.count(), K(tablet_list)); + } + return ret; +} + +int ObTenantTransferService::get_related_table_schemas_( + common::ObISQLClient &sql_proxy, + ObSimpleTableSchemaV2 &table_schema, + ObArenaAllocator &allocator, + ObArray &related_table_schemas) +{ + int ret = OB_SUCCESS; + related_table_schemas.reset(); + const int64_t schema_version = INT64_MAX - 1; // get newest schema + ObRefreshSchemaStatus schema_status; + schema_status.tenant_id_ = tenant_id_; + ObArray related_table_ids; + ObSchemaService *schema_service = NULL; + const uint64_t primary_table_id = table_schema.get_table_id(); + ObArray related_infos; + if (OB_ISNULL(GCTX.schema_service_) + || OB_ISNULL(schema_service = GCTX.schema_service_->get_schema_service())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("GCTX.schema_service_ is null", KR(ret)); + } else if (OB_FAIL(schema_service->fetch_aux_tables( + schema_status, + tenant_id_, + table_schema.get_table_id(), + schema_version, + sql_proxy, + related_infos))) { + LOG_WARN("fail to fetch_aux_tables", KR(ret), K_(tenant_id), + K(primary_table_id), K(schema_status), K(related_table_ids), K(schema_version)); + } else { + TTS_INFO("get related table infos", K(primary_table_id), K(related_infos)); + } + ARRAY_FOREACH(related_infos, idx) { + const ObAuxTableMetaInfo &info = related_infos.at(idx); + const uint64_t related_table_id = info.table_id_; + if (is_related_table(info.table_type_, info.index_type_)) { + if (OB_FAIL(related_table_ids.push_back(related_table_id))) { + LOG_WARN("push back failed", KR(ret), K(related_table_id)); + } + } + } + if (OB_FAIL(ret)) { + } else if (related_table_ids.empty()) { + // skip + } else if (OB_FAIL(batch_get_latest_table_schemas_( + allocator, + related_table_ids, + related_table_schemas))) { + LOG_WARN("fail to batch get latest table schemas", KR(ret), K(related_table_ids)); + } else { + TTS_INFO("get related table schema", K(primary_table_id), + K(related_infos), "schema count", related_table_schemas.count()); + } + return ret; +} + +int ObTenantTransferService::get_tablet_and_partition_idx_by_object_id_( + ObSimpleTableSchemaV2 &table_schema, + const ObObjectID &part_object_id, + ObTabletID &tablet_id, + int64_t &part_idx, + int64_t &subpart_idx) +{ + int ret = OB_SUCCESS; + part_idx = OB_INVALID_INDEX; + subpart_idx = OB_INVALID_INDEX; + if (OB_UNLIKELY(OB_INVALID_ID == part_object_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", KR(ret), K(part_object_id)); + } else if (PARTITION_LEVEL_ZERO == table_schema.get_part_level()) { + tablet_id = table_schema.get_tablet_id(); + part_idx = OB_INVALID_INDEX; + subpart_idx = OB_INVALID_INDEX; + } else { + ObCheckPartitionMode check_partition_mode = CHECK_PARTITION_MODE_NORMAL; + ObPartitionSchemaIter iter(table_schema, check_partition_mode); + ObPartitionSchemaIter::Info info; + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.next_partition_info(info))) { + if (OB_ITER_END != ret) { + LOG_WARN("switch the src partition info failed", KR(ret)); + } + } else if (info.object_id_ == part_object_id) { + tablet_id = info.tablet_id_; + part_idx = info.part_idx_; + subpart_idx = info.subpart_idx_; + break; + } + } + if (OB_UNLIKELY(OB_ITER_END == ret) + || (OB_SUCC(ret) && OB_UNLIKELY(!tablet_id.is_valid()))) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("object id not found", KR(ret), "table_id", + table_schema.get_table_id(), K(part_object_id)); + } + } + return ret; +} + +int ObTenantTransferService::get_tablet_by_partition_idx_( + ObSimpleTableSchemaV2 &table_schema, + const int64_t part_idx, + const int64_t subpart_idx, + ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + ObBasePartition *base_part = NULL; + if (PARTITION_LEVEL_ZERO == table_schema.get_part_level()) { + tablet_id = table_schema.get_tablet_id(); + } else if (OB_FAIL(table_schema.get_part_by_idx(part_idx, subpart_idx, base_part))) { + LOG_WARN("fail to get part by idx", KR(ret), K(part_idx), K(subpart_idx)); + } else if (OB_ISNULL(base_part) || OB_UNLIKELY(!base_part->get_tablet_id().is_valid())) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("tablet not found by part_idx", KR(ret), "table_id", + table_schema.get_table_id(), K(part_idx), K(subpart_idx), K(tablet_id)); + } else { + tablet_id = base_part->get_tablet_id(); + } + return ret; +} + +int ObTenantTransferService::check_tenant_schema_is_ready_(bool &is_ready) +{ + int ret = OB_SUCCESS; + schema::ObMultiVersionSchemaService *schema_service = GCTX.schema_service_; + schema::ObSchemaGetterGuard guard; + const ObSimpleTenantSchema *tenant_schema = NULL; + is_ready = false; + if (OB_ISNULL(schema_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema_service is null", KR(ret)); + } else if (OB_FAIL(schema_service->get_tenant_schema_guard(OB_SYS_TENANT_ID, guard))) { + LOG_WARN("fail to get schema guard", KR(ret), K_(tenant_id)); + } else if (OB_FAIL(guard.get_tenant_info(tenant_id_, tenant_schema))) { + LOG_WARN("fail to get tenant schema", KR(ret), K_(tenant_id)); + } else if (OB_ISNULL(tenant_schema)) { + is_ready = false; + } else if (tenant_schema->is_normal()) { + is_ready = true; + } + return ret; +} + +int ObTenantTransferService::generate_transfer_task( + ObMySQLTransaction &trans, + const ObLSID &src_ls, + const ObLSID &dest_ls, + const ObTransferPartList &part_list, + const ObBalanceTaskID balance_task_id, + ObTransferTaskID &task_id) +{ + int ret = OB_SUCCESS; + task_id.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!src_ls.is_valid() + || !dest_ls.is_valid() + || part_list.empty() + || !balance_task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(src_ls), K(dest_ls), K(part_list), K(balance_task_id)); + } else { + ObTransferTask task; + ObCurTraceId::TraceId trace_id; + trace_id.init(GCONF.self_addr_); + ObTransferStatus status(ObTransferStatus::INIT); + ObTransferPartList transfer_part_list; + const int64_t part_count = min(PART_COUNT_IN_A_TRANSFER, part_list.count()); + if (OB_FAIL(transfer_part_list.reserve(part_count))) { + LOG_WARN("reserve failed", KR(ret), K(part_count)); + } else if (OB_FAIL(ObCommonIDUtils::gen_unique_id(tenant_id_, task_id))) { + LOG_WARN("gen_unique_id failed", KR(ret), K(task_id), K_(tenant_id)); + } else { + // process from the back of part_list makes it easier to remove when task is done + for (int64_t i = part_list.count() - 1; OB_SUCC(ret) && (i >= part_list.count() - part_count); --i) { + if (OB_FAIL(transfer_part_list.push_back(part_list.at(i)))) { + LOG_WARN("push back failed", KR(ret), K(i), K(part_list), K(transfer_part_list)); + } + } + if (FAILEDx(task.init(task_id, src_ls, dest_ls, transfer_part_list, status, trace_id, balance_task_id))) { + LOG_WARN("init transfer task failed", KR(ret), K(task_id), K(src_ls), + K(dest_ls), K(transfer_part_list), K(status), K(trace_id), K(balance_task_id)); + } else if (OB_FAIL(ObTransferTaskOperator::insert(trans, tenant_id_, task))) { + LOG_WARN("insert failed", KR(ret), K_(tenant_id), K(task)); + } + } + } + return ret; +} + +int ObTenantTransferService::try_cancel_transfer_task(const ObTransferTaskID task_id) +{ + int ret = OB_SUCCESS; + ObMySQLTransaction trans; + ObTransferTask task; + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + bool task_exist = true; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(! task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid task_id", KR(ret), K(task_id)); + } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id_))) { + LOG_WARN("trans start failed", KR(ret), K_(tenant_id)); + } else if (OB_FAIL(ObTransferTaskOperator::get( + trans, + tenant_id_, + task_id, + true/*for_update*/, + task))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to get task", KR(ret), K_(tenant_id), K(task_id), K(task)); + } else { + ret = OB_SUCCESS; + task_exist = false; + } + } else if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid task", KR(ret), K(task)); + } else if (FALSE_IT(ObCurTraceId::set(task.get_trace_id()))) { + } else if (task.get_status().is_canceled_status()) { + // task is already canceled + } else if (!task.get_status().is_init_status()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("task status is not init, can't cancel", KR(ret), K(task)); + } else if (OB_FAIL(ObTransferTaskOperator::finish_task_from_init( + trans, + tenant_id_, + task_id, + task.get_status(), + task.get_part_list(), + task.get_not_exist_part_list(), + task.get_lock_conflict_part_list(), + ObTransferStatus(ObTransferStatus::CANCELED), + OB_CANCELED, + ObTransferTaskComment::TASK_CANCELED))) { + LOG_WARN("finish task from init failed", KR(ret), K_(tenant_id), K(task)); + } + task.reset(); + if (OB_FAIL(ret) || !task_exist) { + } else if (OB_FAIL(ObTransferTaskOperator::get_task_with_time( + trans, + tenant_id_, + task_id, + true/*for_update*/, + task, + create_time, + finish_time))) { + LOG_WARN("get task with time failed", KR(ret), + K_(tenant_id), K(task_id), K(task), K(create_time), K(finish_time)); + } else if (OB_UNLIKELY(!task.get_status().is_canceled_status())) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("task status is not canceled", KR(ret), K_(tenant_id), K(task_id), K(task)); + } else if (OB_FAIL(ObTransferTaskOperator::remove(trans, tenant_id_, task_id))) { + LOG_WARN("remove task failed", KR(ret), K_(tenant_id), K(task_id), K(task)); + } else if (OB_FAIL(ObTransferTaskOperator::insert_history( + trans, + tenant_id_, + task, + create_time, + finish_time))) { + LOG_WARN("insert history failed", KR(ret), + K_(tenant_id), K(task), K(create_time), K(finish_time)); + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + TTS_INFO("cancel task finished", KR(ret), K(task_id), K(task_exist), K(task)); + return ret; +} + +int ObTenantTransferService::try_clear_transfer_task( + const ObTransferTaskID task_id, + share::ObTransferPartList &all_part_list, + share::ObTransferPartList &finished_part_list) +{ + int ret = OB_SUCCESS; + DEBUG_SYNC(BEFORE_PROCESS_BALANCE_TASK_TRANSFER_END); + ObTransferTask task; + if (OB_FAIL(unlock_and_clear_task_(task_id, task))) { + if (OB_ENTRY_NOT_EXIST == ret) { + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + if (OB_FAIL(ObTransferTaskOperator::get_history_task( + *sql_proxy_, + tenant_id_, + task_id, + task, + create_time, + finish_time))) { + LOG_WARN("get history task status failed", KR(ret), K_(tenant_id), K(task_id), K(task)); + } else { + TTS_INFO("task is already cleared", KR(ret), K(task_id), K(task)); + } + } else if (OB_NEED_RETRY == ret) { + // skip + } else { + LOG_WARN("clear transfer task failed", KR(ret), K(task_id), K(task)); + } + } + + if (FAILEDx(fill_finished_task_info_(task, finished_part_list, all_part_list))) { + LOG_WARN("fill finished task info failed", KR(ret), K(task)); + } else { + TTS_INFO("clear transfer task successfully", KR(ret), K(task_id), + K(all_part_list), K(finished_part_list), K(task)); + } + return ret; +} + +int ObTenantTransferService::unlock_and_clear_task_( + const ObTransferTaskID task_id, + ObTransferTask &task) +{ + int ret = OB_SUCCESS; + ObMySQLTransaction trans; + task.reset(); + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + ObTimeoutCtx ctx; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid task_id", KR(ret), K(task_id)); + } else if (OB_FAIL(set_transaction_timeout_(ctx))) { + LOG_WARN("set transaction timeout failed", KR(ret), K(ctx)); + } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id_))) { + LOG_WARN("trans start failed", KR(ret), K_(tenant_id)); + } else if (OB_FAIL(ObTransferTaskOperator::get_task_with_time( + trans, + tenant_id_, + task_id, + true/*for_update*/, + task, + create_time, + finish_time))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to get task", KR(ret), K_(tenant_id), K(task_id), K(task)); + } + } else if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid task", KR(ret), K(task)); + } else if (FALSE_IT(ObCurTraceId::set(task.get_trace_id()))) { + } else if (!task.get_status().is_finish_status()) { + ret = OB_NEED_RETRY; + if (REACH_TIME_INTERVAL(10 * 1000 * 1000L)) { // 10s + TTS_INFO("task is not in finish status, can't clear", KR(ret), K(task)); + } + } else if (OB_UNLIKELY(task.get_status().is_canceled_status())) { + // if transfer task is canceled, it will be deleted at the same time + ret = OB_STATE_NOT_MATCH; + LOG_WARN("canceled status transfer task should not exist", KR(ret), K(task)); + } else if (OB_FAIL(unlock_table_and_part_( + trans, + task.get_part_list(), + task.get_table_lock_owner_id()))) { + LOG_WARN("unlock table and part failed", KR(ret), K(task)); + } else { + if (OB_FAIL(ObTransferTaskOperator::remove(trans, tenant_id_, task_id))) { + LOG_WARN("remove task failed", KR(ret), K_(tenant_id), K(task_id), K(task)); + } else if (OB_FAIL(ObTransferTaskOperator::insert_history( + trans, + tenant_id_, + task, + create_time, + finish_time))) { + LOG_WARN("insert history failed", KR(ret), + K_(tenant_id), K(task), K(create_time), K(finish_time)); + } + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + + if (OB_SUCC(ret)) { + TTS_INFO("clear transfer task success", KR(ret), K(task_id), K(task)); + } + return ret; +} + +int ObTenantTransferService::unlock_table_and_part_( + ObMySQLTransaction &trans, + const share::ObTransferPartList &part_list, + const ObTableLockOwnerID &lock_owner_id) +{ + int ret = OB_SUCCESS; + ObSchemaService *schema_service = NULL; + ObArenaAllocator allocator; + ObTransferPartList ordered_part_list; + if (IS_NOT_INIT || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (part_list.empty()) { + TTS_INFO("part list is empty, no need to unlock table and part", + KR(ret), K(part_list), K(lock_owner_id)); + } else if (OB_ISNULL(GCTX.schema_service_) + || OB_ISNULL(schema_service = GCTX.schema_service_->get_schema_service())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("GCTX.schema_service_ is null", KR(ret)); + } else if (OB_UNLIKELY(!lock_owner_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(part_list), K(lock_owner_id)); + } else if (OB_FAIL(ordered_part_list.assign(part_list))) { + LOG_WARN("assign failed", KR(ret), K(part_list), K(lock_owner_id)); + } else if (OB_ISNULL(MTL(ObTableLockService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("mtl ObTableLockService is null", KR(ret), K_(tenant_id)); + } else { + ObSimpleTableSchemaV2 *table_schema = NULL; + const int64_t timeout_us = GCONF.internal_sql_execute_timeout; + ObTransferPartInfo::Compare cmp; + std::sort(ordered_part_list.begin(), ordered_part_list.end(), cmp); + + ARRAY_FOREACH(ordered_part_list, idx) { + ObTabletID tablet_id; + int64_t part_idx = OB_INVALID_INDEX; + int64_t subpart_idx = OB_INVALID_INDEX; + const ObTransferPartInfo &part_info = ordered_part_list.at(idx); + const ObObjectID table_id = part_info.table_id(); + const ObObjectID part_object_id = part_info.part_object_id(); + if (OB_NOT_NULL(table_schema) && table_schema->get_table_id() == table_id) { + // use previous table_schema + } else if (OB_FAIL(get_latest_table_schema_(allocator, table_id, table_schema))) { + if (OB_TABLE_NOT_EXIST == ret) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table cannot not exist", KR(ret), K(table_id), K_(tenant_id)); + } else { + LOG_WARN("get table schema failed", KR(ret), K(table_id), K_(tenant_id)); + } + } + + if (FAILEDx(get_tablet_and_partition_idx_by_object_id_( + *table_schema, + part_info.part_object_id(), + tablet_id, + part_idx, + subpart_idx))) { + LOG_WARN("get tablet and partition idx by object_id failed", + KR(ret), K(part_info), K(tablet_id), K(part_idx)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_for_transfer( + tenant_id_, + table_schema->get_table_id(), + tablet_id, + lock_owner_id, + timeout_us, + trans))) { + LOG_WARN("unlock online ddl lock for transfer failed", KR(ret), K_(tenant_id), + "table_id", table_schema->get_table_id(), K(tablet_id), K(lock_owner_id), K(timeout_us)); + } + if (FAILEDx(unlock_table_lock_(trans, *table_schema, part_info, lock_owner_id, timeout_us))) { + LOG_WARN("unlock table lock failed", KR(ret), K(part_info), K(lock_owner_id), K(timeout_us)); + } + } // end ARRAY_FOREACH + } + + return ret; +} + +int ObTenantTransferService::unlock_table_lock_( + ObMySQLTransaction &trans, + share::schema::ObSimpleTableSchemaV2 &table_schema, + const share::ObTransferPartInfo &part_info, + const ObTableLockOwnerID &lock_owner_id, + const int64_t timeout_us) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *conn = NULL; + if (OB_UNLIKELY(!part_info.is_valid() + || (table_schema.get_table_id() != part_info.table_id()) + || (!lock_owner_id.is_valid()) + || (timeout_us < 0))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(part_info), + "table_id of schema", table_schema.get_table_id(), K(lock_owner_id), K(timeout_us)); + } else if (OB_ISNULL(conn = dynamic_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("connection is null", KR(ret), K_(tenant_id), K(part_info)); + } else if (table_schema.is_global_index_table() + || PARTITION_LEVEL_ZERO == table_schema.get_part_level()) { + ObUnLockTableRequest unlock_table_arg; + unlock_table_arg.lock_mode_ = ROW_SHARE; + unlock_table_arg.timeout_us_ = timeout_us; + unlock_table_arg.owner_id_ = lock_owner_id; + unlock_table_arg.op_type_ = OUT_TRANS_UNLOCK; + if (table_schema.is_global_index_table()) { + unlock_table_arg.table_id_ = table_schema.get_data_table_id(); + } else { + unlock_table_arg.table_id_ = part_info.table_id(); + } + if (OB_FAIL(ObInnerConnectionLockUtil::unlock_table(tenant_id_, unlock_table_arg, conn))) { + LOG_WARN("unlock table failed", KR(ret), K(unlock_table_arg)); + } + } else { + ObUnLockPartitionRequest unlock_part_arg; + unlock_part_arg.lock_mode_ = ROW_SHARE; + unlock_part_arg.timeout_us_ = timeout_us; + unlock_part_arg.table_id_ = part_info.table_id(); + unlock_part_arg.part_object_id_ = part_info.part_object_id(); + unlock_part_arg.owner_id_ = lock_owner_id; + unlock_part_arg.op_type_ = OUT_TRANS_UNLOCK; + + if (PARTITION_LEVEL_ONE == table_schema.get_part_level()) { + if (OB_FAIL(ObInnerConnectionLockUtil::unlock_partition(tenant_id_, unlock_part_arg, conn))) { + LOG_WARN("unlock partition failed", KR(ret), K(unlock_part_arg)); + } + } else if (PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + if (OB_FAIL(ObInnerConnectionLockUtil::unlock_subpartition(tenant_id_, unlock_part_arg, conn))) { + LOG_WARN("unlock subpartition failed", KR(ret), K(unlock_part_arg)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(part_info), "part_level", table_schema.get_part_level()); + } + } + return ret; +} + +int ObTenantTransferService::notify_storage_transfer_service_( + const ObTransferTaskID task_id, + const ObLSID &dest_ls) +{ + int ret = OB_SUCCESS; + obrpc::ObStartTransferTaskArg arg; + ObAddr leader_addr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(! task_id.is_valid() || !dest_ls.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", KR(ret), K(task_id), K(dest_ls)); + } else if (OB_FAIL(arg.init(tenant_id_, task_id, dest_ls))) { + LOG_WARN("init ObStartTransferTaskArg failed", KR(ret), K(task_id), K(dest_ls)); + } else if (OB_ISNULL(GCTX.location_service_) || OB_ISNULL(GCTX.srv_rpc_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("GCTX has null ptr", KR(ret), K(task_id), K_(tenant_id)); + } else if (OB_FAIL(GCTX.location_service_->get_leader_with_retry_until_timeout( + GCONF.cluster_id, + tenant_id_, + dest_ls, + leader_addr))) { // default 1s timeout + LOG_WARN("get leader failed", KR(ret), K(task_id), + "cluster_id", GCONF.cluster_id.get_value(), K_(tenant_id), K(dest_ls), K(leader_addr)); + } else if (OB_FAIL(GCTX.srv_rpc_proxy_->to(leader_addr).by(tenant_id_).start_transfer_task(arg))) { + LOG_WARN("send rpc failed", KR(ret), K(task_id), K(dest_ls), K(leader_addr), K(arg)); + } + TTS_INFO("send rpc to storage finished", KR(ret), K(task_id), K(dest_ls), K(leader_addr), K(arg)); + return ret; +} + +// all_part_list = part_list + not_exist_part_list + lock_conflict_part_list +// finished_part_list = not_exist_part_list + part_list (COMPLETED) +// finished_part_list = not_exist_part_list (FAILED) +int ObTenantTransferService::fill_finished_task_info_( + const share::ObTransferTask &task, + share::ObTransferPartList &finished_part_list, + share::ObTransferPartList &all_part_list) +{ + int ret = OB_SUCCESS; + finished_part_list.reset(); + all_part_list.reset(); + const int64_t all_part_list_count = task.get_part_list().count() + + task.get_not_exist_part_list().count() + task.get_lock_conflict_part_list().count(); + const int64_t finished_part_list_count = task.get_not_exist_part_list().count() + + (task.get_status().is_completed_status() ? task.get_part_list().count() : 0); + if (OB_UNLIKELY(!task.is_valid() || !task.get_status().is_finish_status())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid task", KR(ret), K(task)); + } else if (OB_FAIL(all_part_list.reserve(all_part_list_count))) { + LOG_WARN("reserve failed", KR(ret), K(all_part_list_count), K(task)); + } else if (OB_FAIL(finished_part_list.reserve(finished_part_list_count))) { + LOG_WARN("reserve failed", KR(ret), K(finished_part_list_count), K(task)); + } else if (OB_FAIL(common::append(all_part_list, task.get_part_list()))) { + LOG_WARN("append failed", KR(ret), K(all_part_list), K(task)); + } else if (OB_FAIL(common::append(all_part_list, task.get_not_exist_part_list()))) { + LOG_WARN("append failed", KR(ret), K(all_part_list), K(task)); + } else if (OB_FAIL(common::append(all_part_list, task.get_lock_conflict_part_list()))) { + LOG_WARN("append failed", KR(ret), K(all_part_list), K(task)); + } else if (OB_FAIL(common::append(finished_part_list, task.get_not_exist_part_list()))) { + LOG_WARN("append failed", KR(ret), K(finished_part_list), K(task)); + } else if (task.get_status().is_completed_status()) { + if (OB_FAIL(common::append(finished_part_list, task.get_part_list()))) { + LOG_WARN("append failed", KR(ret), K(finished_part_list), K(task)); + } + } + return ret; +} + +int ObTenantTransferService::get_latest_table_schema_( + common::ObIAllocator &allocator, + const ObObjectID &table_id, + ObSimpleTableSchemaV2 *&table_schema) +{ + int ret = OB_SUCCESS; + table_schema = NULL; + ObSEArray table_ids; + ObSEArray table_schemas; + if (IS_NOT_INIT || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(OB_INVALID_ID == table_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table_id", KR(ret), K(table_id)); + } else if (OB_FAIL(ObSchemaUtils::get_latest_table_schema( + *sql_proxy_, + allocator, + tenant_id_, + table_id, + table_schema))) { + LOG_WARN("fail to get latest table schema", KR(ret), K_(tenant_id), K(table_id)); + } + return ret; +} + +// the count of table_schemas may be smaller than table_ids +int ObTenantTransferService::batch_get_latest_table_schemas_( + common::ObIAllocator &allocator, + const common::ObIArray &table_ids, + common::ObIArray &table_schemas) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(table_ids.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table_ids", KR(ret), K(table_ids)); + } else if (OB_FAIL(ObSchemaUtils::batch_get_latest_table_schemas( + *sql_proxy_, + allocator, + tenant_id_, + table_ids, + table_schemas))) { + LOG_WARN("fail to get latest table schema", KR(ret), K_(tenant_id), K(table_ids)); + } + return ret; +} + +int ObTenantTransferService::set_transaction_timeout_(common::ObTimeoutCtx &ctx) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + int64_t tx_timeout = 0; + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id_)); + tx_timeout = tenant_config.is_valid() + ? tenant_config->_transfer_process_lock_tx_timeout + : 100 * 1000 * 1000L; // 100s + if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, tx_timeout))) { + LOG_WARN("set default timeout ctx failed", KR(ret), K(ctx), K(tx_timeout)); + } + } + return ret; +} + +#undef TTS_INFO +} // end namespace rootserver +} // end namespace oceanbase diff --git a/src/rootserver/ob_tenant_transfer_service.h b/src/rootserver/ob_tenant_transfer_service.h new file mode 100644 index 000000000..bba79c8e9 --- /dev/null +++ b/src/rootserver/ob_tenant_transfer_service.h @@ -0,0 +1,230 @@ +/** + * 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_ROOTSERVER_OB_TENANT_TRANSFER_SERVICE_H +#define OCEANBASE_ROOTSERVER_OB_TENANT_TRANSFER_SERVICE_H + +#include "rootserver/ob_tenant_thread_helper.h" // ObTenantThreadHelper +#include "share/transfer/ob_transfer_info.h" // ObTransferTask +#include "share/ob_balance_define.h" // share::ObBalanceTaskID, share::ObTransferTaskID + +namespace oceanbase +{ +namespace common +{ +class ObTimeoutCtx; +} + +namespace share +{ +class ObLSID; +namespace schema +{ +class ObSimpleTableSchemaV2; +class SchemaKey; +} +} + +namespace rootserver +{ +// ObTenantTransferService is used to manage the transfer tasks generated by the balance module. +// It will iteract with storage layer to do tablet transfer. +class ObTenantTransferService : public ObTenantThreadHelper, + public logservice::ObICheckpointSubHandler, + public logservice::ObIReplaySubHandler +{ +public: + static const int64_t THREAD_COUNT = 4; + static const int64_t MINI_MODE_THREAD_COUNT = 1; + + ObTenantTransferService() + : is_inited_(false), tenant_id_(OB_INVALID_TENANT_ID), sql_proxy_(NULL) {} + virtual ~ObTenantTransferService() {} + int init(); + void destroy(); + virtual void do_work() override; + DEFINE_MTL_FUNC(ObTenantTransferService) + + /* + * generate transfer task with INIT status (a task handles no more than 100 partitions) + * + * @param [in] trans: transaction client + * @param [in] src_ls: source log stream + * @param [in] dest_ls: destination log stream + * @param [in] part_list: partition list for transfer + * @param [in] balance_task_id: parenet balance task id + * @param [out] task_id: unique transfer task id + * @return + * - OB_SUCCESS: generate task successfully + * - other: generate task failed + */ + int generate_transfer_task( + ObMySQLTransaction &trans, + const share::ObLSID &src_ls, + const share::ObLSID &dest_ls, + const share::ObTransferPartList &part_list, + const share::ObBalanceTaskID balance_task_id, + share::ObTransferTaskID &task_id); + /* + * try cancel and clear transfer task (only task in INIT status can be canceled) + * + * @param[in] task_id: transfer task id + * @return + * - OB_SUCCESS: cancel task successfully + * - OB_OP_NOT_ALLOW: task status is not INIT, can't be cancelled + * - other: cancel task failed + */ + int try_cancel_transfer_task(const share::ObTransferTaskID task_id); + + /* + * try clear finished transfer task and record history + * if task is already cleared, return OB_SUCCESS and related info recorded in history + * + * @param[in] task_id: transfer task id + * @param[out] all_part_list: all partitons of the transfer task + * @param[out] finished_part_list: successfully transferred partitions + needless transferred (not exist or not in src LS) partitions + * @return + * - OB_SUCCESS: clear task successfully + * - OB_NEED_RETRY: task is not finished, can't be cleared + * - OB_ENTRY_NOT_EXIST: task not found + * - other: clear task failed + */ + int try_clear_transfer_task( + const share::ObTransferTaskID task_id, + share::ObTransferPartList &all_part_list, + share::ObTransferPartList &finished_part_list); + +public: + // interfaces used to register with logservice + virtual share::SCN get_rec_scn() override { return share::SCN::max_scn();} + virtual int flush(share::SCN &) override { return OB_SUCCESS; } + int replay(const void *buffer, const int64_t nbytes, const palf::LSN &lsn, const share::SCN &) override + { + UNUSED(buffer); + UNUSED(nbytes); + UNUSED(lsn); + return OB_SUCCESS; + } + +private: + int process_task_(const share::ObTransferTask::TaskStatus &task_stat); + int process_init_task_(const share::ObTransferTaskID task_id); + int check_ls_member_list_( + common::ObISQLClient &sql_proxy, + const share::ObLSID &src_ls, + const share::ObLSID &dest_ls, + bool &is_same); + int lock_table_and_part_( + ObMySQLTransaction &trans, + const share::ObLSID &src_ls, + share::ObTransferPartList &part_list, + share::ObTransferPartList ¬_exist_part_list, + share::ObTransferPartList &lock_failed_part_list, + share::ObDisplayTabletList &table_lock_tablet_list, + common::ObIArray &tablet_ids, + transaction::tablelock::ObTableLockOwnerID &lock_owner_id); + int unlock_table_and_part_( + ObMySQLTransaction &trans, + const share::ObTransferPartList &part_list, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id); + int get_related_table_schemas_( + common::ObISQLClient &sql_proxy, + share::schema::ObSimpleTableSchemaV2 &table_schema, + ObArenaAllocator &allocator, + ObArray &related_table_schemas); + int get_tablet_and_partition_idx_by_object_id_( + share::schema::ObSimpleTableSchemaV2 &table_schema, + const ObObjectID &part_object_id, + ObTabletID &tablet_id, + int64_t &part_idx); + int get_tablet_and_partition_idx_by_object_id_( + share::schema::ObSimpleTableSchemaV2 &table_schema, + const ObObjectID &part_object_id, + ObTabletID &tablet_id, + int64_t &part_idx, + int64_t &subpart_idx); + int get_tablet_by_partition_idx_( + share::schema::ObSimpleTableSchemaV2 &table_schema, + const int64_t part_idx, + const int64_t subpart_idx, + ObTabletID &tablet_id); + int check_tenant_schema_is_ready_(bool &is_ready); + int unlock_and_clear_task_( + const share::ObTransferTaskID task_id, + share::ObTransferTask &task); + int notify_storage_transfer_service_(const share::ObTransferTaskID task_id, const share::ObLSID &dest_ls); + int add_in_trans_lock_and_refresh_schema_( + ObMySQLTransaction &trans, + const share::ObLSID &src_ls, + const share::ObTransferPartInfo &part_info, + common::ObIAllocator &allocator, + share::schema::ObSimpleTableSchemaV2 *&table_schema, + ObTabletID &tablet_id, + int64_t &part_idx, + int64_t &subpart_idx); + int add_table_lock_( + ObMySQLTransaction &trans, + share::schema::ObSimpleTableSchemaV2 &table_schema, + const share::ObTransferPartInfo &part_info, + const bool is_out_trans, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id); + int add_out_trans_lock_( + ObMySQLTransaction &trans, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id, + share::schema::ObSimpleTableSchemaV2 &table_schema, + const share::ObTransferPartInfo &part_info, + const ObTabletID &tablet_id); + int generate_related_tablet_ids_( + share::schema::ObSimpleTableSchemaV2 &table_schema, + const int64_t part_idx, + const int64_t subpart_idx, + common::ObIArray &tablet_ids); + int generate_tablet_list_( + const ObIArray &tablet_ids, + share::ObTransferTabletList &tablet_list); + int unlock_table_lock_( + ObMySQLTransaction &trans, + share::schema::ObSimpleTableSchemaV2 &table_schema, + const share::ObTransferPartInfo &part_info, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id, + const int64_t timeout_us); + int fill_finished_task_info_( + const share::ObTransferTask &task, + share::ObTransferPartList &finished_part_list, + share::ObTransferPartList &all_part_list); + int batch_get_latest_table_schemas_( + common::ObIAllocator &allocator, + const common::ObIArray &table_ids, + common::ObIArray &table_schemas); + int get_latest_table_schema_( + common::ObIAllocator &allocator, + const ObObjectID &table_id, + share::schema::ObSimpleTableSchemaV2 *&table_schema); + int record_need_move_table_lock_tablet_( + share::schema::ObSimpleTableSchemaV2 &table_schema, + const ObTabletID &tablet_id, + share::ObDisplayTabletList &table_lock_tablet_list); + int set_transaction_timeout_(common::ObTimeoutCtx &ctx); +private: + static const int64_t IDLE_TIME_US = 10 * 1000 * 1000L; // 10s + static const int64_t BUSY_IDLE_TIME_US = 100 * 1000L; // 100ms + static const int64_t PART_COUNT_IN_A_TRANSFER = 100; + static const int64_t TABLET_COUNT_THRESHOLD_IN_A_TRANSFER = 100; + + bool is_inited_; + uint64_t tenant_id_; + common::ObMySQLProxy *sql_proxy_; +}; + +} // end namespace rootserver +} // end namespace oceanbase +#endif diff --git a/src/rootserver/ob_unit_manager.cpp b/src/rootserver/ob_unit_manager.cpp index 50809c41e..e7e361a14 100644 --- a/src/rootserver/ob_unit_manager.cpp +++ b/src/rootserver/ob_unit_manager.cpp @@ -916,6 +916,18 @@ int ObUnitManager::check_tenant_pools_in_shrinking( int ObUnitManager::check_pool_in_shrinking( const uint64_t pool_id, bool &is_shrinking) +{ + int ret = OB_SUCCESS; + SpinRLockGuard guard(lock_); + if (OB_FAIL(inner_check_pool_in_shrinking_(pool_id, is_shrinking))) { + LOG_WARN("inner check pool in shrinking failed", KR(ret), K(pool_id), K(is_shrinking)); + } + return ret; +} + +int ObUnitManager::inner_check_pool_in_shrinking_( + const uint64_t pool_id, + bool &is_shrinking) { int ret = OB_SUCCESS; if (!check_inner_stat()) { @@ -926,7 +938,6 @@ int ObUnitManager::check_pool_in_shrinking( LOG_WARN("invalid argument", K(ret), K(pool_id)); } else { common::ObArray *units = NULL; - SpinRLockGuard guard(lock_); if (OB_FAIL(get_units_by_pool(pool_id, units))) { LOG_WARN("fail to get units by pool", K(ret), K(pool_id)); } else if (NULL == units) { @@ -1761,7 +1772,22 @@ int ObUnitManager::rollback_shrink_tenant_pool_unit_num_rs_job( return ret; } -int ObUnitManager::complete_shrink_tenant_pool_unit_num_rs_job( +int ObUnitManager::try_complete_shrink_tenant_pool_unit_num_rs_job( + const uint64_t tenant_id, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(complete_shrink_tenant_pool_unit_num_rs_job_(tenant_id, trans))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("complete_shrink_tenant_pool_unit_num_rs_job failed", KR(ret), "tenant_id" K(tenant_id)); + } + } else {} // do nothing + return ret; +} + +int ObUnitManager::complete_shrink_tenant_pool_unit_num_rs_job_( const uint64_t tenant_id, common::ObMySQLTransaction &trans) { @@ -1988,6 +2014,19 @@ int ObUnitManager::check_shrink_tenant_pools_allowed( return ret; } +// There are two situations to consider in the shrinkage of the resource pool: +// 1. There is no resource pool granted to tenants +// the specified number of units can be directly deleted when the resource pool shrinks. +// 2. Resource pool that has been granted to tenants +// It is necessary to select the specified units from the resource pool, +// mark these units as the deleting state, +// and wait for all the replicas to be moved from such units before the whole process can be considered complete. +// The unit num of the pool that has been granted to the tenant needs to be scaled down. +// Preconditions: +// 2.1 The reduced unit num cannot be less than the number of replicas of locality in the corresponding zone +// 2.2 At present, the shrinking operation is performed when the unit is in a steady state, +// the shrinking is allowed when all units are not migrated. +// We avoid the unit being in both the migration and the deleting state, thereby reducing the complexity int ObUnitManager::shrink_tenant_pools_unit_num( const uint64_t tenant_id, common::ObIArray &pools, @@ -2224,6 +2263,21 @@ int ObUnitManager::alter_resource_tenant( ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "delete unit group without unit num change"); } else {} // good, nothing to do with unit group + } else if (AUN_ROLLBACK_SHRINK == alter_unit_num_type) { + if (delete_unit_group_id_array.count() > 0) { + ret = OB_NOT_SUPPORTED; + LOG_USER_ERROR(OB_NOT_SUPPORTED, "rollback shrink pool unit num combined with deleting unit"); + } else if (OB_FAIL(rollback_tenant_shrink_pools_unit_num( + tenant_id, *pools, new_unit_num))) { + LOG_WARN("fail to rollbakc shrink pool unit num", K(ret), K(new_unit_num)); + } + } else if (!ObShareUtil::is_tenant_enable_rebalance(tenant_id)) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("enable_rebalance is disabled, modify tenant unit num not allowed", KR(ret), K(tenant_id)); + char err_msg[DEFAULT_BUF_LENGTH]; + (void)snprintf(err_msg, sizeof(err_msg), + "Tenant (%lu) 'enable_rebalance' is disabled, alter tenant unit num", tenant_id); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, err_msg); } else if (AUN_EXPAND == alter_unit_num_type) { if (delete_unit_group_id_array.count() > 0) { ret = OB_NOT_SUPPORTED; @@ -2234,20 +2288,9 @@ int ObUnitManager::alter_resource_tenant( KPC(pools)); } } else if (AUN_SHRINK == alter_unit_num_type) { - ret = OB_NOT_SUPPORTED; - LOG_USER_ERROR(OB_NOT_SUPPORTED, "shrink resource pool unit number"); - // In 4.0, we do not support shrink resource pool unit number granted to tenant for now - //if (OB_FAIL(shrink_tenant_pools_unit_num( - // tenant_id, *pools, new_unit_num, delete_unit_group_id_array))) { - // LOG_WARN("fail to shrink pool unit num", K(ret), K(new_unit_num)); - //} - } else if (AUN_ROLLBACK_SHRINK == alter_unit_num_type) { - if (delete_unit_group_id_array.count() > 0) { - ret = OB_NOT_SUPPORTED; - LOG_USER_ERROR(OB_NOT_SUPPORTED, "rollback shrink pool unit num combined with deleting unit"); - } else if (OB_FAIL(rollback_tenant_shrink_pools_unit_num( - tenant_id, *pools, new_unit_num))) { - LOG_WARN("fail to rollbakc shrink pool unit num", K(ret), K(new_unit_num)); + if (OB_FAIL(shrink_tenant_pools_unit_num( + tenant_id, *pools, new_unit_num, delete_unit_group_id_array))) { + LOG_WARN("fail to shrink pool unit num", K(ret), K(new_unit_num)); } } else if (AUN_MAX == alter_unit_num_type) { ret = OB_OP_NOT_ALLOW; @@ -3171,7 +3214,7 @@ int ObUnitManager::check_locality_for_logonly_unit(const share::schema::ObTenant * if any tenant unit is in deleting, * @is_allowed returns false */ -int ObUnitManager::check_expand_zone_resource_allowed_by_old_unit_stat( +int ObUnitManager::check_expand_zone_resource_allowed_by_old_unit_stat_( const uint64_t tenant_id, bool &is_allowed) { @@ -3220,13 +3263,11 @@ int ObUnitManager::check_expand_zone_resource_allowed_by_old_unit_stat( return ret; } -int ObUnitManager::check_expand_zone_resource_allowed_by_new_unit_stat( - const common::ObIArray &pool_names, - bool &is_allowed) +int ObUnitManager::check_expand_zone_resource_allowed_by_new_unit_stat_( + const common::ObIArray &pool_names) { int ret = OB_SUCCESS; - is_allowed = true; - for (int64_t i = 0; is_allowed && OB_SUCC(ret) && i < pool_names.count(); ++i) { + for (int64_t i = 0; OB_SUCC(ret) && i < pool_names.count(); ++i) { share::ObResourcePool *pool = NULL; ObArray *units = nullptr; if (OB_FAIL(inner_get_resource_pool_by_name(pool_names.at(i), pool))) { @@ -3240,14 +3281,15 @@ int ObUnitManager::check_expand_zone_resource_allowed_by_new_unit_stat( ret = OB_ERR_UNEXPECTED; LOG_WARN("units ptr is null", K(ret)); } else { - for (int64_t j = 0; is_allowed && OB_SUCC(ret) && j < units->count(); ++j) { + for (int64_t j = 0; OB_SUCC(ret) && j < units->count(); ++j) { ObUnit *unit = units->at(j); if (OB_UNLIKELY(nullptr == unit)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unit ptr is null", KR(ret), KPC(pool)); - } else { - is_allowed = (unit->status_ == ObUnit::UNIT_STATUS_ACTIVE); - } + } else if (unit->status_ != ObUnit::UNIT_STATUS_ACTIVE) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected unit status", KR(ret), KPC(pool), KPC(unit)); + } else {/* good */} } } } @@ -3259,7 +3301,7 @@ int ObUnitManager::check_expand_zone_resource_allowed_by_new_unit_stat( * 2 when this is a tenant which exists: * check the input pools, each input pool unit num shall be equal to the pools already granted to the tenant. */ -int ObUnitManager::check_tenant_pools_unit_num_legal( +int ObUnitManager::check_tenant_pools_unit_num_legal_( const uint64_t tenant_id, const common::ObIArray &input_pool_names, bool &unit_num_legal, @@ -3341,7 +3383,7 @@ int ObUnitManager::get_pool_unit_group_id_( * 3.1 when this is a tenant being created: fetch unit group id from inner table * 3.2 when this is a tenant which exists: get unit group id from units granted to this tenant */ -int ObUnitManager::get_tenant_pool_unit_group_id( +int ObUnitManager::get_tenant_pool_unit_group_id_( const bool is_bootstrap, const bool grant, const uint64_t tenant_id, @@ -3657,16 +3699,16 @@ int ObUnitManager::get_unit_group( return ret; } +// TODO(cangming.zl): need a new function to abstract the process of getting pools by pool_names // TODO: disable resource pools intersect for one tenant // NEED to disable logics to handle resource pool intersect in server_balancer -int ObUnitManager::grant_pools(ObISQLClient &client, +int ObUnitManager::grant_pools(common::ObMySQLTransaction &trans, common::ObIArray &new_unit_group_id_array, const lib::Worker::CompatMode compat_mode, const ObIArray &pool_names, const uint64_t tenant_id, - const bool is_bootstrap, - const bool if_not_grant, - const bool skip_offline_server) + const bool is_bootstrap + /*arg "const bool skip_offline_server" is no longer supported*/) { int ret = OB_SUCCESS; SpinWLockGuard guard(lock_); @@ -3674,8 +3716,6 @@ int ObUnitManager::grant_pools(ObISQLClient &client, bool intersect = false; bool server_enough = true; bool is_grant_pool_allowed = false; - const bool skip_check_enough = is_bootstrap - || skip_offline_server; bool unit_num_legal = false; int64_t legal_unit_num = -1; if (!check_inner_stat()) { @@ -3684,28 +3724,29 @@ int ObUnitManager::grant_pools(ObISQLClient &client, } else if (pool_names.count() <= 0 || !is_valid_tenant_id(tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(pool_names), K(tenant_id), K(ret)); - } else if (OB_FAIL(check_pool_intersect(tenant_id, pool_names, intersect))) { + } else if (OB_FAIL(check_pool_ownership_(tenant_id, pool_names, true/*is_grant*/))) { + LOG_WARN("check pool ownership failed", KR(ret), K(pool_names)); + } else if (OB_FAIL(check_pool_intersect_(tenant_id, pool_names, intersect))) { LOG_WARN("check pool intersect failed", K(pool_names), KR(ret)); } else if (intersect) { ret = OB_POOL_SERVER_INTERSECT; LOG_USER_ERROR(OB_POOL_SERVER_INTERSECT, to_cstring(pool_names)); LOG_WARN("resource pool unit server intersect", K(pool_names), KR(ret)); - } else if (!skip_check_enough + } else if (!is_bootstrap && OB_FAIL(check_server_enough(tenant_id, pool_names, server_enough))) { LOG_WARN("fail to check server enough", KR(ret), K(tenant_id), K(pool_names)); } else if (!server_enough) { ret = OB_UNIT_NUM_OVER_SERVER_COUNT; LOG_WARN("resource pool unit num over zone server count", K(ret), K(pool_names), K(tenant_id)); - } else if (OB_FAIL(check_expand_zone_resource_allowed_by_old_unit_stat( + } else if (OB_FAIL(check_expand_zone_resource_allowed_by_old_unit_stat_( tenant_id, is_grant_pool_allowed))) { LOG_WARN("fail to check grant pools allowed by unit stat", KR(ret), K(tenant_id)); } else if (!is_grant_pool_allowed) { ret = OB_OP_NOT_ALLOW; LOG_USER_ERROR(OB_OP_NOT_ALLOW, "grant pool when pools in shrinking"); - } else if (OB_FAIL(check_expand_zone_resource_allowed_by_new_unit_stat( - pool_names, is_grant_pool_allowed))) { + } else if (OB_FAIL(check_expand_zone_resource_allowed_by_new_unit_stat_(pool_names))) { LOG_WARN("fail to check grant pools allowed by unit stat", KR(ret)); - } else if (OB_FAIL(check_tenant_pools_unit_num_legal( + } else if (OB_FAIL(check_tenant_pools_unit_num_legal_( tenant_id, pool_names, unit_num_legal, legal_unit_num))) { LOG_WARN("fail to check pools unit num legal", KR(ret), K(tenant_id), K(pool_names)); } else if (!unit_num_legal) { @@ -3713,22 +3754,20 @@ int ObUnitManager::grant_pools(ObISQLClient &client, LOG_WARN("pools belong to one tenant with different unit num are not allowed", KR(ret), K(tenant_id), K(pool_names)); LOG_USER_ERROR(OB_OP_NOT_ALLOW, "pools belong to one tenant with different unit num are"); - } else if (OB_FAIL(get_tenant_pool_unit_group_id( + } else if (OB_FAIL(get_tenant_pool_unit_group_id_( is_bootstrap, grant, tenant_id, legal_unit_num, new_unit_group_id_array))) { LOG_WARN("fail to generate new unit group id", KR(ret), K(tenant_id), K(legal_unit_num)); - } else if (OB_FAIL(change_pool_owner( - client, new_unit_group_id_array, compat_mode, grant, - pool_names, tenant_id, is_bootstrap, if_not_grant, skip_offline_server))) { - LOG_WARN("change pool owner failed", KR(ret), K(grant), K(pool_names), K(tenant_id), - K(compat_mode), K(is_bootstrap), K(if_not_grant), - K(skip_offline_server)); + } else if (OB_FAIL(do_grant_pools_( + trans, new_unit_group_id_array, compat_mode, + pool_names, tenant_id, is_bootstrap))) { + LOG_WARN("do grant pools failed", KR(ret), K(grant), K(pool_names), K(tenant_id), + K(compat_mode), K(is_bootstrap)); } - LOG_INFO("grant resource pools to tenant", K(pool_names), K(tenant_id), K(ret), K(is_bootstrap), - K(if_not_grant), K(skip_offline_server)); + LOG_INFO("grant resource pools to tenant", KR(ret), K(pool_names), K(tenant_id), K(is_bootstrap)); return ret; } -int ObUnitManager::revoke_pools(ObISQLClient &client, +int ObUnitManager::revoke_pools(common::ObMySQLTransaction &trans, common::ObIArray &new_unit_group_id_array, const ObIArray &pool_names, const uint64_t tenant_id) @@ -3736,7 +3775,6 @@ int ObUnitManager::revoke_pools(ObISQLClient &client, int ret = OB_SUCCESS; SpinWLockGuard guard(lock_); const bool grant = false; - const lib::Worker::CompatMode dummy_mode = lib::Worker::CompatMode::INVALID; bool unit_num_legal = false; int64_t legal_unit_num = -1; if (!check_inner_stat()) { @@ -3745,122 +3783,26 @@ int ObUnitManager::revoke_pools(ObISQLClient &client, } else if (pool_names.count() <= 0 || !is_valid_tenant_id(tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(pool_names), K(tenant_id), K(ret)); - } else if (OB_FAIL(check_tenant_pools_unit_num_legal( + } else if (OB_FAIL(check_pool_ownership_(tenant_id, pool_names, false/*is_grant*/))) { + LOG_WARN("check pool ownership failed", KR(ret), K(pool_names)); + } else if (OB_FAIL(check_tenant_pools_unit_num_legal_( tenant_id, pool_names, unit_num_legal, legal_unit_num))) { LOG_WARN("fail to check pools unit num legal", KR(ret), K(tenant_id), K(pool_names)); } else if (!unit_num_legal) { ret = OB_OP_NOT_ALLOW; LOG_WARN("pools belong to one tenant with different unit num are not allowed", KR(ret), K(tenant_id), K(pool_names)); - } else if (OB_FAIL(get_tenant_pool_unit_group_id( + } else if (OB_FAIL(get_tenant_pool_unit_group_id_( false /* is_bootstrap */, grant, tenant_id, legal_unit_num, new_unit_group_id_array))) { LOG_WARN("fail to generate new unit group id", KR(ret), K(tenant_id), K(legal_unit_num)); - } else if (OB_FAIL(change_pool_owner( - client, new_unit_group_id_array, dummy_mode, - grant, pool_names, tenant_id, false/*is_bootstrap*/))) { - LOG_WARN("change pool owner failed", K(grant), K(pool_names), K(tenant_id), K(ret)); + } else if (OB_FAIL(do_revoke_pools_(trans, new_unit_group_id_array, pool_names, tenant_id))) { + LOG_WARN("do revoke pools failed", KR(ret), K(grant), K(pool_names), K(tenant_id)); } LOG_INFO("revoke resource pools from tenant", K(pool_names), K(ret)); return ret; } -int ObUnitManager::commit_change_pool_owner( - common::ObIArray &new_unit_group_id_array, - const bool grant, - const ObIArray &pool_names, - const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - SpinWLockGuard guard(lock_); - if (OB_FAIL(inner_commit_change_pool_owner( - new_unit_group_id_array, grant, pool_names, tenant_id))) { - LOG_WARN("fail to inner commit change pool owner", K(ret)); - } - return ret; -} - -int ObUnitManager::inner_commit_change_pool_owner( - common::ObIArray &new_ug_id_array, - const bool grant, - const ObIArray &pool_names, - const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!check_inner_stat())) { - ret = OB_INNER_STAT_ERROR; - LOG_WARN("check_inner_stat failed", K(inited_), K(loaded_), K(ret)); - } else if (pool_names.count() <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("pool_names is empty", K(pool_names), K(ret)); - } else if (!is_valid_tenant_id(tenant_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid tenant_id", K(tenant_id), K(ret)); - } else { - common::ObArray zone_sorted_unit_array; - for (int64_t i = 0; OB_SUCC(ret) && i < pool_names.count(); ++i) { - share::ObResourcePool *pool = NULL; - ObArray *units = NULL; - zone_sorted_unit_array.reset(); - if (OB_FAIL(inner_get_resource_pool_by_name(pool_names.at(i), pool))) { - LOG_WARN("resource pool expected to exist", "pool_name", pool_names.at(i), K(ret)); - } else if (NULL == pool) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("pool is null", KP(pool), K(ret)); - } else if (pool->is_granted_to_tenant() && pool->tenant_id_ != tenant_id) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("find pool already grant to other tenant", "pool", *pool, - K(tenant_id), K(ret)); - } else if (pool->unit_count_ != new_ug_id_array.count()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit num not match", KR(ret),KPC(pool), K(new_ug_id_array)); - } else if (OB_FAIL(get_units_by_pool(pool->resource_pool_id_, units))) { - LOG_WARN("fail to get units by pool", K(ret), - "resource_pool_id", pool->resource_pool_id_); - } else if (OB_UNLIKELY(nullptr == units)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("units ptr is null", KR(ret)); - } else if (OB_FAIL(zone_sorted_unit_array.assign(*units))) { - LOG_WARN("fail to assign zone unit array", KR(ret)); - } else { - UnitZoneOrderCmp cmp_operator; - std::sort(zone_sorted_unit_array.begin(), zone_sorted_unit_array.end(), cmp_operator); - for (int64_t j = 0; j < zone_sorted_unit_array.count(); ++j) { - ObUnit *unit = zone_sorted_unit_array.at(j); - if (OB_UNLIKELY(nullptr == unit)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit ptr is null", KR(ret)); - } else { - unit->unit_group_id_ = new_ug_id_array.at(j % pool->unit_count_); - } - } - if (grant) { - if (pool->tenant_id_ == tenant_id) { - // possible if alter system reload unit before invoke this function - } else { - if (OB_FAIL(insert_tenant_pool(tenant_id, pool))) { - LOG_WARN("insert_tenant_pool failed", K(tenant_id), K(ret)); - } else { - pool->tenant_id_ = tenant_id; - } - } - } else { - if (!pool->is_granted_to_tenant()) { - // possible if alter system reload unit before invoke this function - } else { - if (OB_FAIL(delete_tenant_pool(pool->tenant_id_, pool))) { - LOG_WARN("delete_tenant_pool failed", "pool tenant_id", pool->tenant_id_, K(ret)); - } else { - pool->tenant_id_ = OB_INVALID_ID; - } - } - } - } - } - } - return ret; -} - int ObUnitManager::inner_get_pool_ids_of_tenant(const uint64_t tenant_id, ObIArray &pool_ids) const { @@ -4653,73 +4595,115 @@ int ObUnitManager::get_zone_active_unit_infos_by_tenant( return ret; } - -int ObUnitManager::commit_shrink_resource_pool( - const uint64_t resource_pool_id) +int ObUnitManager::commit_shrink_tenant_resource_pool( + const uint64_t tenant_id) { int ret = OB_SUCCESS; SpinWLockGuard guard(lock_); common::ObMySQLTransaction trans; - share::ObResourcePool *pool = NULL; + common::ObArray *pools = nullptr; + common::ObArray> resource_units; + + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K(loaded_), K(inited_)); + } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_FAIL(get_pools_by_tenant(tenant_id, pools))) { + LOG_WARN("failed to get pool by tenant", KR(ret), K(tenant_id)); + } else if (OB_UNLIKELY(NULL == pools)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pool ptr is null", KR(ret), KP(pools)); + } else if (OB_FAIL(trans.start(proxy_, OB_SYS_TENANT_ID))) { + LOG_WARN("start transaction failed", KR(ret)); + } else if (OB_FAIL(complete_shrink_tenant_pool_unit_num_rs_job_(tenant_id, trans))) { + LOG_WARN("do rs_job failed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(commit_shrink_resource_pool_in_trans_(*pools, trans, resource_units))) { + LOG_WARN("failed to shrink in trans", KR(ret), KPC(pools)); + } + const bool commit = (OB_SUCCESS == ret); + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(commit))) { + LOG_WARN("trans end failed", K(tmp_ret), K(commit)); + ret = (OB_SUCCESS == ret) ? tmp_ret : ret; + } + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(pools->count() != resource_units.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pools count must equal to unit count", KR(ret), KPC(pools), K(resource_units)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < pools->count(); ++i) { + share::ObResourcePool *pool = pools->at(i); + if (OB_ISNULL(pool)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pool is null", KR(ret), K(i), KPC(pools)); + } else if (OB_FAIL(delete_inmemory_units(pool->resource_pool_id_, resource_units.at(i)))) { + LOG_WARN("failed to delete inmemory units", KR(ret), KPC(pool), K(i), K(resource_units)); + } + } + } + return ret; +} + +int ObUnitManager::commit_shrink_resource_pool_in_trans_( + const common::ObIArray &pools, + common::ObMySQLTransaction &trans, + common::ObIArray> &resource_units) +{ + int ret = OB_SUCCESS; ObArray *units = NULL; if (!check_inner_stat()) { ret = OB_INNER_STAT_ERROR; - LOG_WARN("check_inner_stat failed", K(ret), K(loaded_), K(inited_)); - } else if (OB_UNLIKELY(OB_INVALID_ID == resource_pool_id)) { + LOG_WARN("check_inner_stat failed", KR(ret), K(loaded_), K(inited_)); + } else if (OB_UNLIKELY(0 == pools.count())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(resource_pool_id)); - } else if (OB_FAIL(get_resource_pool_by_id(resource_pool_id, pool))) { - LOG_WARN("fail to get resource pool", K(ret), K(resource_pool_id)); - } else if (OB_UNLIKELY(NULL == pool)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("pool ptr is null", K(ret), KP(pool)); - } else if (OB_FAIL(get_units_by_pool(resource_pool_id, units))) { - LOG_WARN("fail to get units by pool", K(ret), K(resource_pool_id)); - } else if (OB_UNLIKELY(NULL == units)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("pool ptr is null", K(ret), KP(units)); - } else if (OB_FAIL(trans.start(proxy_, OB_SYS_TENANT_ID))) { - LOG_WARN("start transaction failed", K(ret)); - } else if (OB_FAIL(complete_shrink_pool_unit_num_rs_job(pool->resource_pool_id_, pool->tenant_id_, trans))) { - LOG_WARN("do rs_job failed", K(ret)); + LOG_WARN("pool ptr is null", KR(ret), K(pools)); } else { - // Commit shrink resource pool only needs to change the state of the unit, - // the state of the resource pool itself has been changed before, - // and there is no need to adjust it again. - common::ObArray unit_ids; - int64_t unit_count = pool->unit_count_; - if (unit_count <= 0) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit count unexpected", K(ret), K(unit_count)); - } else if (units->count() <= 0) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("zone unit ptrs has no element", K(ret), "unit_cnt", units->count()); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < units->count(); ++i) { - const ObUnit *unit = units->at(i); - if (OB_UNLIKELY(NULL == unit)) { + for (int64_t index = 0; OB_SUCC(ret) && index < pools.count(); ++index) { + // Commit shrink resource pool only needs to change the state of the unit, + // the state of the resource pool itself has been changed before, + // and there is no need to adjust it again. + units = NULL; + share::ObResourcePool *pool = pools.at(index); + if (OB_ISNULL(pool)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pool is null", KR(ret), K(index), K(pools)); + } else if (OB_FAIL(get_units_by_pool(pool->resource_pool_id_, units))) { + LOG_WARN("failed to get pool unit", KR(ret), KPC(pool)); + } else if (OB_ISNULL(units)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("units is null of the pool", KR(ret), KPC(pool)); + } else { + common::ObArray unit_ids; + const int64_t unit_count = pool->unit_count_; + if (unit_count <= 0) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit ptr is null", K(ret), KP(unit), K(i)); - } else if (ObUnit::UNIT_STATUS_DELETING == unit->status_) { - if (OB_FAIL(ut_operator_.remove_unit(trans, *unit))) { - LOG_WARN("fail to remove unit", K(ret), "unit", *unit); - } else if (OB_FAIL(unit_ids.push_back(unit->unit_id_))) { - LOG_WARN("fail to push back", K(ret)); - } else {} // no more to do - } else {} // active unit, do nothing + LOG_WARN("unit count unexpected", KR(ret), K(unit_count)); + } else if (units->count() <= 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("zone unit ptrs has no element", KR(ret), "unit_cnt", + units->count()); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < units->count(); ++i) { + const ObUnit *unit = units->at(i); + if (OB_ISNULL(unit)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unit ptr is null", KR(ret), KP(unit), K(i), KPC(units)); + } else if (ObUnit::UNIT_STATUS_DELETING == unit->status_) { + if (OB_FAIL(ut_operator_.remove_unit(trans, *unit))) { + LOG_WARN("fail to remove unit", KR(ret), "unit", *unit); + } else if (OB_FAIL(unit_ids.push_back(unit->unit_id_))) { + LOG_WARN("fail to push back", KR(ret), KPC(unit)); + } else {} // no more to do + } else {} // active unit, do nothing + }// end for each unit + if (FAILEDx(resource_units.push_back(unit_ids))) { + LOG_WARN("failed to push back units", KR(ret), K(unit_ids)); + } + } } - } - // however, we need to end this transaction - const bool commit = (OB_SUCCESS == ret); - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(commit))) { - LOG_WARN("trans end failed", K(tmp_ret), K(commit)); - ret = (OB_SUCCESS == ret) ? tmp_ret : ret; - } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(delete_inmemory_units(pool->resource_pool_id_, unit_ids))) { - LOG_WARN("fail to delete unit groups", K(ret)); - } else {} // no more to do + }//end for each pool } return ret; } @@ -5084,7 +5068,7 @@ int ObUnitManager::check_resource_pool(share::ObResourcePool &resource_pool) con FOREACH_CNT_X(zone, resource_pool.zone_list_, OB_SUCCESS == ret) { bool zone_exist = false; if (OB_FAIL(zone_mgr_.check_zone_exist(*zone, zone_exist))) { - LOG_WARN("check_zone_exist failed", K(zone), K(ret)); + LOG_WARN("check_zone_exist failed", KPC(zone), K(ret)); } else if (!zone_exist) { ret = OB_ZONE_INFO_NOT_EXIST; LOG_USER_ERROR(OB_ZONE_INFO_NOT_EXIST, to_cstring(*zone)); @@ -6411,19 +6395,8 @@ int ObUnitManager::alter_pool_unit_config(share::ObResourcePool *pool, return ret; } -// There are two situations to consider in the shrinkage of the resource pool: -// 1. There is no resource pool granted to tenants -// the specified number of units can be directly deleted when the resource pool shrinks. -// 2. Resource pool that has been granted to tenants -// It is necessary to select the specified units from the resource pool, -// mark these units as the deleting state, -// and wait for all the replicas to be moved from such units before the whole process can be considered complete. -// The unit num of the pool that has been granted to the tenant needs to be scaled down. -// Preconditions: -// 2.1 The reduced unit num cannot be less than the number of replicas of locality in the corresponding zone -// 2.2 At present, the shrinking operation is performed when the unit is in a steady state, -// the shrinking is allowed when all units are not migrated. -// We avoid the unit being in both the migration and the deleting state, thereby reducing the complexity +// shrink pool unit num should only work on not-granted pool. +// routine that calls this function should ensure that. int ObUnitManager::shrink_pool_unit_num( share::ObResourcePool *pool, const int64_t alter_unit_num, @@ -6433,6 +6406,9 @@ int ObUnitManager::shrink_pool_unit_num( if (OB_UNLIKELY(NULL == pool || alter_unit_num <= 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), KP(pool), K(alter_unit_num)); + } else if (pool->is_granted_to_tenant()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected pool status", KR(ret), KPC(pool)); } else { ObArray sort_unit_id_array; for (int64_t i = 0; OB_SUCC(ret) && i < delete_unit_id_array.count(); ++i) { @@ -6448,17 +6424,8 @@ int ObUnitManager::shrink_pool_unit_num( LOG_USER_ERROR(OB_NOT_SUPPORTED, "delete same unit more than once"); } } - if (OB_SUCC(ret)) { - uint64_t tenant_id = pool->tenant_id_; - if (! is_valid_tenant_id(tenant_id)) { - if (OB_FAIL(shrink_not_granted_pool(pool, alter_unit_num, delete_unit_id_array))) { - LOG_WARN("fail to shrink not granted pool", K(ret)); - } - } else { - if (OB_FAIL(shrink_granted_pool(pool, alter_unit_num, delete_unit_id_array))) { - LOG_WARN("fail to shrink granted pool", K(ret)); - } - } + if (FAILEDx(shrink_not_granted_pool(pool, alter_unit_num, delete_unit_id_array))) { + LOG_WARN("fail to shrink not granted pool", KR(ret)); } } return ret; @@ -7113,79 +7080,6 @@ int ObUnitManager::check_shrink_granted_pool_allowed( return ret; } -int ObUnitManager::register_shrink_pool_unit_num_rs_job( - const uint64_t resource_pool_id, - const uint64_t tenant_id, - const int64_t new_unit_num, - common::ObMySQLTransaction &trans) -{ - int ret = OB_SUCCESS; - int64_t pos = 0; - const int64_t extra_info_len = common::MAX_ROOTSERVICE_EVENT_EXTRA_INFO_LENGTH; - char extra_info[common::MAX_ROOTSERVICE_EVENT_EXTRA_INFO_LENGTH] = {0}; - if (OB_SUCCESS != (ret = databuff_printf(extra_info, extra_info_len, pos, - "new_unit_num: %ld", new_unit_num))) { - if (OB_SIZE_OVERFLOW == ret) { - LOG_WARN("format to buff size overflow", K(ret)); - } else { - LOG_WARN("format new unit num failed", K(ret)); - } - } - if (OB_SUCC(ret)) { - int64_t job_id = RS_JOB_CREATE(SHRINK_RESOURCE_POOL_UNIT_NUM, trans, - "resource_pool_id", resource_pool_id, - "tenant_id", tenant_id, - "extra_info", extra_info); - if (job_id < 1) { - ret = OB_SQL_OPT_ERROR; - LOG_WARN("insert into all_rootservice_job failed", K(ret)); - } - } - return ret ; -} - -int ObUnitManager::rollback_shrink_pool_unit_num_rs_job( - const uint64_t resource_pool_id, - const uint64_t tenant_id, - common::ObMySQLTransaction &trans) -{ - ObRsJobInfo job_info; - int ret = RS_JOB_FIND(job_info, trans, - "job_type", "SHRINK_RESOURCE_POOL_UNIT_NUM", - "job_status", "INPROGRESS", - "resource_pool_id", resource_pool_id, - "tenant_id", tenant_id); - if (OB_SUCC(ret) && job_info.job_id_ > 0) { - if (OB_FAIL(RS_JOB_COMPLETE(job_info.job_id_, -1, trans))) { // Roll back, this shrink failed - LOG_WARN("update all_rootservice_job failed", K(ret), K(job_info)); - } - } else { - LOG_WARN("failed to find rs job", K(ret), "tenant_id", tenant_id); - } - return ret; -} - -int ObUnitManager::complete_shrink_pool_unit_num_rs_job( - const uint64_t resource_pool_id, - const uint64_t tenant_id, - common::ObMySQLTransaction &trans) - -{ - ObRsJobInfo job_info; - int ret = RS_JOB_FIND(job_info, trans, - "job_type", "SHRINK_RESOURCE_POOL_UNIT_NUM", - "job_status", "INPROGRESS", - "resource_pool_id", resource_pool_id, - "tenant_id", tenant_id); - if (OB_SUCC(ret) && job_info.job_id_ > 0) { - if (OB_FAIL(RS_JOB_COMPLETE(job_info.job_id_, 0, trans))) { // job success - LOG_WARN("update all_rootservice_job failed", K(ret), K(job_info)); - } - } else { - LOG_WARN("failed to find rs job", K(ret), "tenant_id" K(tenant_id)); - } - return ret ; -} int ObUnitManager::complete_migrate_unit_rs_job_in_pool( const int64_t resource_pool_id, const int result_ret, @@ -7230,182 +7124,6 @@ int ObUnitManager::complete_migrate_unit_rs_job_in_pool( return ret; } -int ObUnitManager::shrink_granted_pool( - share::ObResourcePool *pool, - const int64_t alter_unit_num, - const common::ObIArray &delete_unit_id_array) -{ - int ret = OB_SUCCESS; - common::ObMySQLTransaction trans; - bool is_allowed = true; - if (OB_UNLIKELY(NULL == pool || alter_unit_num <= 0)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(pool), K(alter_unit_num)); - } else if (!is_valid_tenant_id(pool->tenant_id_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("pool not grant to any tenant", K(ret), "tenant_id", pool->tenant_id_); - } else if (pool->unit_count_ <= alter_unit_num) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("should be a shrink pool operation", K(ret), - "cur_unit_num", pool->unit_count_, - "new_unit_num", alter_unit_num); - } else if (OB_FAIL(check_shrink_granted_pool_allowed(pool, alter_unit_num, is_allowed))) { - LOG_WARN("fail to check shrink granted pool allowed", - K(ret), "pool", *pool, K(alter_unit_num)); - } else if (!is_allowed) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("shrink granted pool is not allowed", K(ret), "pool", *pool); - } else if (OB_FAIL(trans.start(proxy_, OB_SYS_TENANT_ID))) { - LOG_WARN("start transaction failed", K(ret)); - } else if (OB_FAIL(register_shrink_pool_unit_num_rs_job( - pool->resource_pool_id_, pool->tenant_id_, alter_unit_num, trans))) { - LOG_WARN("do rs_job failed ", K(ret)); - } else { - common::ObArray output_delete_unit_ptr_array; - share::ObResourcePool new_pool; - if (OB_FAIL(new_pool.assign(*pool))) { - LOG_WARN("fail to assign new pool", K(ret)); - } else { - new_pool.unit_count_ = alter_unit_num; - } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { - LOG_WARN("fail to update resource pool", K(ret)); - } else if (OB_FAIL(check_shrink_unit_num_zone_condition(pool, alter_unit_num, delete_unit_id_array))) { - LOG_WARN("fail to check shrink unit num zone condition", K(ret)); - } else if (OB_FAIL(fill_delete_unit_ptr_array( - pool, delete_unit_id_array, alter_unit_num, output_delete_unit_ptr_array))) { - LOG_WARN("fail to fill delete unit id array", K(ret)); - } else if (output_delete_unit_ptr_array.count() <= 0) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("zone unit ptrs has no element", K(ret), - "zone_unit_cnt", output_delete_unit_ptr_array.count()); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < output_delete_unit_ptr_array.count(); ++i) { - const ObUnit *unit = output_delete_unit_ptr_array.at(i); - if (OB_UNLIKELY(NULL == unit)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit ptr is null", K(ret), KP(unit), K(i)); - } else { - ObUnit new_unit = *unit; - new_unit.status_ = ObUnit::UNIT_STATUS_DELETING; - if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { - LOG_WARN("fail to update unit", K(ret), K(new_unit)); - } else {} // no more to do - } - } - } - // however, we need to end this transaction - const bool commit = (OB_SUCCESS == ret); - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(commit))) { - LOG_WARN("trans end failed", K(tmp_ret), K(commit)); - ret = (OB_SUCCESS == ret) ? tmp_ret : ret; - } - if (OB_FAIL(ret)) { - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < output_delete_unit_ptr_array.count(); ++i) { - ObUnit *unit = output_delete_unit_ptr_array.at(i); - if (OB_UNLIKELY(NULL == unit)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit ptr is null", K(ret)); - } else { - unit->status_ = ObUnit::UNIT_STATUS_DELETING; - } - } - if (OB_SUCC(ret)) { - pool->unit_count_ = alter_unit_num; - } - } - } - return ret; -} - -// Roll back the pool shrinkage and directly adjust the unit num and unit status of the resource pool to active. -int ObUnitManager::rollback_shrink_pool_unit_num( - share::ObResourcePool *pool, - const int64_t alter_unit_num) -{ - int ret = OB_SUCCESS; - common::ObArray *units = NULL; - common::ObMySQLTransaction trans; - if (OB_UNLIKELY(NULL == pool || alter_unit_num <= 0)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(pool), K(alter_unit_num)); - } else if (OB_FAIL(trans.start(proxy_, OB_SYS_TENANT_ID))) { - LOG_WARN("start transaction failed", K(ret)); - } else if (OB_FAIL(rollback_shrink_pool_unit_num_rs_job(pool->resource_pool_id_, pool->tenant_id_, trans))) { - LOG_WARN("rollback rs_job failed ", K(ret)); - } else { - if (OB_FAIL(get_units_by_pool(pool->resource_pool_id_, units))) { - LOG_WARN("failt to get units by pool", K(ret), "pool_id", pool->resource_pool_id_); - } else if (OB_UNLIKELY(NULL == units)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("units is null", K(ret), KP(units), "pool_id", pool->resource_pool_id_); - } else if (units->count() <= 0) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("total unit num unexpected", K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < units->count(); ++i) { - const ObUnit *this_unit = units->at(i); - if (OB_UNLIKELY(NULL == this_unit)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit ptr is null", K(ret)); - } else if (ObUnit::UNIT_STATUS_ACTIVE == this_unit->status_) { - // go and process the unit in deleting - } else if (ObUnit::UNIT_STATUS_DELETING == this_unit->status_) { - ObUnit new_unit = *this_unit; - new_unit.status_ = ObUnit::UNIT_STATUS_ACTIVE; - if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { - LOG_WARN("fail to update unit", K(ret), K(new_unit), "cur_unit", *this_unit); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected unit status", K(ret), "unit", *this_unit); - } - } - if (OB_SUCC(ret)) { - share::ObResourcePool new_pool; - if (OB_FAIL(new_pool.assign(*pool))) { - LOG_WARN("fail to assign new pool", K(ret)); - } else { - new_pool.unit_count_ = alter_unit_num; - if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { - LOG_WARN("update resource pool failed", K(new_pool), K(ret)); - } - } - } - const bool commit = (OB_SUCCESS == ret); - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(commit))) { - LOG_WARN("trans end failed", K(commit), K(tmp_ret)); - ret = (OB_SUCCESS == ret) ? tmp_ret : ret; - } - - if (OB_SUCC(ret)) { - for (int64_t i = 0; OB_SUCC(ret) && i < units->count(); ++i) { - ObUnit *this_unit = units->at(i); - if (OB_UNLIKELY(NULL == this_unit)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit ptr is null", K(ret), KP(this_unit)); - } else if (ObUnit::UNIT_STATUS_ACTIVE == this_unit->status_) { - // go and process the unit in deleting - } else if (ObUnit::UNIT_STATUS_DELETING == this_unit->status_) { - this_unit->status_ = ObUnit::UNIT_STATUS_ACTIVE; - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected unit status", K(ret), "unit", *this_unit); - } - } - if (OB_SUCC(ret)) { - pool->unit_count_ = alter_unit_num; - } - } - } - } - return ret; -} - /* the routine that calls the expand_pool_unit_num shall * ensure that this pool is not granted to any tenant */ @@ -7560,11 +7278,10 @@ int ObUnitManager::determine_alter_unit_num_type( LOG_WARN("unexpected complete_unit_num", K(ret), K(complete_unit_num_per_zone)); } else { if (has_unit_num_modification) { // A unit num change is taking place - if (alter_unit_num == complete_unit_num_per_zone) { - alter_unit_num_type = AUN_ROLLBACK_SHRINK; - } else { - alter_unit_num_type = AUN_MAX; - } + // pool not granted should not has unit in DELETING status + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pool not granted is not expected to have unit in DELETING", + KR(ret), K(current_unit_num_per_zone), K(complete_unit_num_per_zone)); } else { if (alter_unit_num > pool->unit_count_) { alter_unit_num_type = AUN_EXPAND; @@ -7578,6 +7295,8 @@ int ObUnitManager::determine_alter_unit_num_type( return ret; } +// alter_pool_unit_num changes a single pool's unit_num, +// and only works on pool not granted to tenant. int ObUnitManager::alter_pool_unit_num( share::ObResourcePool *pool, int64_t alter_unit_num, @@ -7620,13 +7339,8 @@ int ObUnitManager::alter_pool_unit_num( LOG_WARN("fail to shrink pool unit num", K(ret), K(alter_unit_num)); } } else if (AUN_ROLLBACK_SHRINK == alter_unit_num_type) { - if (delete_unit_id_array.count() > 0) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("do not support rollback shrink pool unit num combined with deleting unit", K(ret)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "rollback shrink pool unit num combined with deleting unit"); - } else if (OB_FAIL(rollback_shrink_pool_unit_num(pool, alter_unit_num))) { - LOG_WARN("fail to rollbakc shrink pool unit num", K(ret), K(alter_unit_num)); - } + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected alter_unit_num_type", KR(ret), K(alter_unit_num)); } else if (AUN_MAX == alter_unit_num_type) { ret = OB_OP_NOT_ALLOW; LOG_USER_ERROR(OB_OP_NOT_ALLOW, "alter unit num while the previous operation is in progress"); @@ -7889,7 +7603,7 @@ int ObUnitManager::add_pool_zone_list( // good, can do add pool zone list directly is_add_pool_zone_list_allowed = true; } else { - if (OB_FAIL(check_expand_zone_resource_allowed_by_old_unit_stat( + if (OB_FAIL(check_expand_zone_resource_allowed_by_old_unit_stat_( pool->tenant_id_, is_add_pool_zone_list_allowed))) { LOG_WARN("fail to check grant pools allowed by unit stat", KR(ret), "tenant_id", pool->tenant_id_); @@ -8471,7 +8185,7 @@ int ObUnitManager::change_pool_config(share::ObResourcePool *pool, ObUnitConfig // The zones of multiple pools have no intersection // 14x new semantics. If it is the source_pool used to store the copy of L, it can be compared -int ObUnitManager::check_pool_intersect( +int ObUnitManager::check_pool_intersect_( const uint64_t tenant_id, const ObIArray &pool_names, bool &intersect) @@ -8482,30 +8196,30 @@ int ObUnitManager::check_pool_intersect( intersect = false; if (!check_inner_stat()) { ret = OB_INNER_STAT_ERROR; - LOG_WARN("check_inner_stat failed", K_(inited), K_(loaded), K(ret)); + LOG_WARN("check_inner_stat failed", K_(inited), K_(loaded), KR(ret)); } else if (pool_names.count() <= 0 || !is_valid_tenant_id(tenant_id)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("pool_names is empty", K(pool_names), K(tenant_id), K(ret)); + LOG_WARN("pool_names is empty", K(pool_names), K(tenant_id), KR(ret)); } else { FOREACH_CNT_X(pool_name, pool_names, OB_SUCCESS == ret && !intersect) { share::ObResourcePool *pool = NULL; if (OB_FAIL(inner_get_resource_pool_by_name(*pool_name, pool))) { - LOG_WARN("get resource pool by name failed", "pool_name", *pool_name, K(ret)); + LOG_WARN("get resource pool by name failed", "pool_name", *pool_name, KR(ret)); } else if (NULL == pool) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("pool is null", KP(pool), K(ret)); + LOG_WARN("pool is null", KP(pool), KR(ret)); } else { FOREACH_CNT_X(zone, pool->zone_list_, OB_SUCCESS == ret && !intersect) { if (NULL == zone) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit is null", K(ret)); + LOG_WARN("unit is null", KR(ret)); } else { ObString zone_str; zone_str.assign_ptr(zone->ptr(), static_cast(zone->size())); if (has_exist_in_array(zones, zone_str)) { intersect = true; } else if (OB_FAIL(zones.push_back(zone_str))) { - LOG_WARN("push_back failed", K(ret)); + LOG_WARN("push_back failed", KR(ret)); } } } // end foreach zone @@ -8518,22 +8232,22 @@ int ObUnitManager::check_pool_intersect( // a new tenant, without resource pool already granted ret = OB_SUCCESS; } else { - LOG_WARN("fail to get pools by tenant", K(ret), K(tenant_id)); + LOG_WARN("fail to get pools by tenant", KR(ret), K(tenant_id)); } } else if (OB_UNLIKELY(NULL == pools)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("pools is null", K(ret), KP(pools)); + LOG_WARN("pools is null", KR(ret), KP(pools)); } else { for (int64_t i = 0; !intersect && OB_SUCC(ret) && i < pools->count(); ++i) { const share::ObResourcePool *pool = pools->at(i); if (OB_UNLIKELY(NULL == pool)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("pool ptr is null", K(ret), KP(pool)); + LOG_WARN("pool ptr is null", KR(ret), KP(pool)); } else { for (int64_t j = 0; !intersect && OB_SUCC(ret) && j < zones.count(); ++j) { common::ObZone zone; if (OB_FAIL(zone.assign(zones.at(j).ptr()))) { - LOG_WARN("fail to assign zone", K(ret)); + LOG_WARN("fail to assign zone", KR(ret)); } else if (has_exist_in_array(pool->zone_list_, zone)) { intersect = true; } else {} // good @@ -8545,30 +8259,61 @@ int ObUnitManager::check_pool_intersect( return ret; } -int ObUnitManager::change_pool_owner( - ObISQLClient &client, +int ObUnitManager::check_pool_ownership_(const uint64_t tenant_id, + const common::ObIArray &pool_names, + const bool grant) +{ + int ret = OB_SUCCESS; + share::ObResourcePool *pool = NULL; + for (int64_t i = 0; OB_SUCC(ret) && i < pool_names.count(); ++i) { + if (OB_FAIL(inner_get_resource_pool_by_name(pool_names.at(i), pool))) { + LOG_WARN("get resource pool by name failed", "pool_name", pool_names.at(i), KR(ret)); + } else if (OB_ISNULL(pool)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pool is null", KP(pool), KR(ret)); + } + if (OB_FAIL(ret)) { + } else if (grant) { + if (pool->is_granted_to_tenant()) { + ret = OB_RESOURCE_POOL_ALREADY_GRANTED; + LOG_USER_ERROR(OB_RESOURCE_POOL_ALREADY_GRANTED, to_cstring(pool_names.at(i))); + LOG_WARN("pool has already granted to other tenant, can't grant again", + KR(ret), K(tenant_id), "pool", *pool); + } else {/*good*/} + } else { + if (!pool->is_granted_to_tenant()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("find pool not granted to any tenant, can not revoke", + "pool", *pool, K(tenant_id), KR(ret)); + } else if (pool->tenant_id_ != tenant_id) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("find pool already granted to other tenant, can not revoke", + "pool", *pool, K(tenant_id), KR(ret)); + } else {/*good*/} + } + } + return ret; +} + +int ObUnitManager::do_grant_pools_( + ObMySQLTransaction &trans, const common::ObIArray &new_ug_ids, const lib::Worker::CompatMode compat_mode, - const bool grant, const ObIArray &pool_names, const uint64_t tenant_id, - const bool is_bootstrap, - const bool if_not_grant, - const bool skip_offline_server) + const bool is_bootstrap) { int ret = OB_SUCCESS; if (!check_inner_stat()) { ret = OB_INNER_STAT_ERROR; - LOG_WARN("check_inner_stat failed", K_(inited), K_(loaded), K(ret)); + LOG_WARN("check_inner_stat failed", K_(inited), K_(loaded), KR(ret)); } else if (!is_valid_tenant_id(tenant_id) || pool_names.count() <= 0) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(tenant_id), K(pool_names), K(ret)); + LOG_WARN("invalid argument", K(tenant_id), K(pool_names), KR(ret)); } else if (OB_UNLIKELY(nullptr == srv_rpc_proxy_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("srv_rpc_proxy_ ptr is null", K(ret)); + LOG_WARN("srv_rpc_proxy_ ptr is null", KR(ret)); } else { - const bool is_delete_server_resource = !grant; - const uint64_t new_tenant_id = (grant ? tenant_id : OB_INVALID_ID); ObNotifyTenantServerResourceProxy notify_proxy( *srv_rpc_proxy_, &obrpc::ObSrvRpcProxy::notify_tenant_server_unit_resource); @@ -8578,65 +8323,45 @@ int ObUnitManager::change_pool_owner( ObArray pool_units; for (int64_t i = 0; OB_SUCC(ret) && i < pool_names.count(); ++i) { share::ObResourcePool *pool = NULL; - ObArray *units = nullptr; pool_units.reset(); common::ObArray zone_sorted_unit_array; if (OB_FAIL(inner_get_resource_pool_by_name(pool_names.at(i), pool))) { - LOG_WARN("get resource pool by name failed", "pool_name", pool_names.at(i), K(ret)); - } else if (NULL == pool) { + LOG_WARN("get resource pool by name failed", "pool_name", pool_names.at(i), KR(ret)); + } else if (OB_ISNULL(pool)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("pool is null", KP(pool), K(ret)); - } else if (grant && pool->is_granted_to_tenant()) { - ret = OB_RESOURCE_POOL_ALREADY_GRANTED; - LOG_USER_ERROR(OB_RESOURCE_POOL_ALREADY_GRANTED, to_cstring(pool_names.at(i))); - LOG_WARN("pool has already granted to other tenant, can't grant again", - K(ret), K(tenant_id), "pool", *pool); - } else if (!grant && pool->is_granted_to_tenant() && pool->tenant_id_ != tenant_id) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("find pool already granted to other tenant, can not revoke", - "pool", *pool, K(tenant_id), K(ret)); - } else if (!grant && ! pool->is_granted_to_tenant()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("find pool not granted to any tenant, can not revoke", - "pool", *pool, K(tenant_id), K(ret)); - } else if (OB_FAIL(new_pool.assign(*pool))) { - LOG_WARN("failed to assign new_pool", K(ret)); - } else if (FALSE_IT(new_pool.tenant_id_ = new_tenant_id)) { - // shall never be here - } else if (OB_FAIL(ut_operator_.update_resource_pool(client, new_pool))) { - LOG_WARN("update_resource_pool failed", K(new_pool), K(ret)); - } else if (OB_FAIL(get_units_by_pool(new_pool.resource_pool_id_, units))) { - LOG_WARN("fail to get units by pool", K(ret)); - } else if (OB_UNLIKELY(nullptr == units)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("units ptr is null", K(ret)); - } else if (is_bootstrap) { - //no need to notify unit and modify unit group id + LOG_WARN("pool is null", KP(pool), KR(ret)); } else if (pool->unit_count_ != new_ug_ids.count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("count not match", KR(ret), K(tenant_id), "pool", new_pool, K(new_ug_ids)); - } else if (OB_FAIL(zone_sorted_unit_array.assign(*units))) { - LOG_WARN("fail to assign zone unit array", KR(ret)); + } else if (OB_FAIL(new_pool.assign(*pool))) { + LOG_WARN("failed to assign new_pool", KR(ret)); + } else if (FALSE_IT(new_pool.tenant_id_ = tenant_id)) { + // shall never be here + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + LOG_WARN("update_resource_pool failed", K(new_pool), KR(ret)); + } else if (is_bootstrap) { + //no need to notify unit and modify unit group id + } else if (OB_FAIL(build_zone_sorted_unit_array_(pool, zone_sorted_unit_array))) { + LOG_WARN("failed to generate zone_sorted_unit_array", KR(ret), KPC(pool)); } else { - UnitZoneOrderCmp cmp_operator; - std::sort(zone_sorted_unit_array.begin(), zone_sorted_unit_array.end(), cmp_operator); ObUnit new_unit; for (int64_t j = 0; OB_SUCC(ret) && j < zone_sorted_unit_array.count(); ++j) { ObUnit *unit = zone_sorted_unit_array.at(j); new_unit.reset(); - if (OB_UNLIKELY(nullptr == unit)) { + if (OB_ISNULL(unit)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unit ptr is null", KR(ret)); } else if (OB_FAIL(try_notify_tenant_server_unit_resource( - tenant_id, is_delete_server_resource, notify_proxy, - new_pool, compat_mode, *unit, if_not_grant, skip_offline_server))) { - LOG_WARN("fail to try notify server unit resource", K(ret)); + tenant_id, false /*is_delete*/, notify_proxy, + new_pool, compat_mode, *unit, + false/*if_not_grant*/, false/*skip_offline_server*/))) { + LOG_WARN("fail to try notify server unit resource", KR(ret)); } else if (FALSE_IT(new_unit = *unit)) { // shall never be here } else if (FALSE_IT(new_unit.unit_group_id_ = new_ug_ids.at(j % (pool->unit_count_)))) { // shall never be here - } else if (OB_FAIL(ut_operator_.update_unit(client, new_unit))) { + } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { LOG_WARN("fail to update unit", KR(ret)); } else if (OB_FAIL(pool_units.push_back(*unit))) { LOG_WARN("fail to push an element into pool_units", KR(ret)); @@ -8651,23 +8376,21 @@ int ObUnitManager::change_pool_owner( } int tmp_ret = OB_SUCCESS; if (OB_SUCCESS != (tmp_ret = notify_proxy.wait())) { - LOG_WARN("fail to wait notify resource", K(ret), K(tmp_ret)); + LOG_WARN("fail to wait notify resource", KR(ret), K(tmp_ret)); ret = (OB_SUCCESS == ret) ? tmp_ret : ret; } - if (grant) { - ret = ERRSIM_UNIT_PERSISTENCE_ERROR ? : ret; - } - if (OB_FAIL(ret) && grant && pools.count() == all_pool_units.count()) { + ret = ERRSIM_UNIT_PERSISTENCE_ERROR ? : ret; + if (OB_FAIL(ret) && pools.count() == all_pool_units.count()) { LOG_WARN("start to rollback unit persistence", KR(ret), K(pools), K(tenant_id)); for (int64_t i = 0; i < pools.count(); ++i) { if (OB_TMP_FAIL(rollback_persistent_units(all_pool_units.at(i), pools.at(i), compat_mode, - if_not_grant, - skip_offline_server, + false/*if_not_grant*/, + false/*skip_offline_server*/, notify_proxy))) { LOG_WARN("fail to rollback unit persistence", KR(ret), KR(tmp_ret), K(all_pool_units.at(i)), - K(pools.at(i)), K(compat_mode), K(if_not_grant), K(skip_offline_server)); + K(pools.at(i)), K(compat_mode)); } } } @@ -8675,6 +8398,178 @@ int ObUnitManager::change_pool_owner( return ret; } +int ObUnitManager::do_revoke_pools_( + ObMySQLTransaction &trans, + const common::ObIArray &new_ug_ids, + const ObIArray &pool_names, + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + const lib::Worker::CompatMode dummy_mode = lib::Worker::CompatMode::INVALID; + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", K_(inited), K_(loaded), KR(ret)); + } else if (!is_valid_tenant_id(tenant_id) || pool_names.count() <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(tenant_id), K(pool_names), KR(ret)); + } else if (OB_UNLIKELY(nullptr == srv_rpc_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("srv_rpc_proxy_ ptr is null", KR(ret)); + } else { + ObNotifyTenantServerResourceProxy notify_proxy( + *srv_rpc_proxy_, + &obrpc::ObSrvRpcProxy::notify_tenant_server_unit_resource); + share::ObResourcePool new_pool; + ObArray shrinking_pools; + ObArray pools; + for (int64_t i = 0; OB_SUCC(ret) && i < pool_names.count(); ++i) { + share::ObResourcePool *pool = NULL; + bool is_shrinking = false; + common::ObArray zone_sorted_unit_array; + if (OB_FAIL(inner_get_resource_pool_by_name(pool_names.at(i), pool))) { + LOG_WARN("get resource pool by name failed", "pool_name", pool_names.at(i), KR(ret)); + } else if (OB_ISNULL(pool)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pool is null", KP(pool), KR(ret)); + } else if (pool->unit_count_ != new_ug_ids.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("count not match", KR(ret), K(tenant_id), + "pool", new_pool, K(new_ug_ids)); + } else if (OB_FAIL(inner_check_pool_in_shrinking_(pool->resource_pool_id_, is_shrinking))) { // TODO(cangming.zl): maybe need to move ahead + LOG_WARN("inner check pool in shrinking failed", KR(ret), "pool", *pool, K(is_shrinking)); + } else if (is_shrinking && OB_FAIL(shrinking_pools.push_back(pool))) { + LOG_WARN("fail to push back shrinking resource pool before revoked", KR(ret), K(tenant_id), "pool", *pool); + } else if (OB_FAIL(new_pool.assign(*pool))) { + LOG_WARN("failed to assign new_pool", KR(ret)); + } else if (FALSE_IT(new_pool.tenant_id_ = OB_INVALID_ID)) { + // shall never be here + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + LOG_WARN("update_resource_pool failed", K(new_pool), KR(ret)); + } else if (OB_FAIL(build_zone_sorted_unit_array_(pool, zone_sorted_unit_array))) { + LOG_WARN("failed to generate zone_sorted_unit_array", KR(ret), KPC(pool)); + } else { + ObUnit new_unit; + for (int64_t j = 0; OB_SUCC(ret) && j < zone_sorted_unit_array.count(); ++j) { + ObUnit *unit = zone_sorted_unit_array.at(j); + new_unit.reset(); + if (OB_ISNULL(unit)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unit ptr is null", KR(ret)); + } else if (OB_FAIL(try_notify_tenant_server_unit_resource( + tenant_id, true /*is_delete*/, notify_proxy, + new_pool, dummy_mode, *unit, + false/*if_not_grant*/, false/*skip_offline_server*/))) { + LOG_WARN("fail to try notify server unit resource", KR(ret)); + } else if (FALSE_IT(new_unit = *unit)) { + // shall never be here + } else if (FALSE_IT(new_unit.unit_group_id_ = new_ug_ids.at(j % (pool->unit_count_)))) { + // shall never be here + } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { + LOG_WARN("fail to update unit", KR(ret)); + } + } + } + } + // If some of the pools are shrinking, commit these shrinking pools now. + if (OB_SUCCESS != ret) { + } else if (shrinking_pools.count() > 0 && OB_FAIL(inner_commit_shrink_tenant_resource_pool_(trans, tenant_id, shrinking_pools))) { + LOG_WARN("failed to commit shrinking pools in revoking", KR(ret), K(tenant_id)); + } + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = notify_proxy.wait())) { + LOG_WARN("fail to wait notify resource", KR(ret), K(tmp_ret)); + ret = (OB_SUCCESS == ret) ? tmp_ret : ret; + } + } + return ret; +} + +int ObUnitManager::build_zone_sorted_unit_array_(const share::ObResourcePool *pool, + common::ObArray &zone_sorted_units) +{ + int ret = OB_SUCCESS; + ObArray *units; + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", K_(inited), K_(loaded), KR(ret)); + } else if (OB_ISNULL(pool)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("pool is nullptr", KR(ret)); + } else if (OB_FAIL(get_units_by_pool(pool->resource_pool_id_, units))) { + LOG_WARN("fail to get units by pool", KR(ret)); + } else if (OB_ISNULL(units)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("units ptr is null", KR(ret)); + } else if (OB_FAIL(zone_sorted_units.assign(*units))) { + LOG_WARN("fail to assign zone unit array", KR(ret)); + } else { + UnitZoneOrderCmp cmp_operator; + std::sort(zone_sorted_units.begin(), zone_sorted_units.end(), cmp_operator); + // check unit count in each zone + ObUnit *curr_unit = NULL; + ObUnit *prev_unit = NULL; + int64_t unit_count_per_zone = 0; + for (int64_t j = 0; OB_SUCC(ret) && j < zone_sorted_units.count(); ++j) { + prev_unit = curr_unit; + curr_unit = zone_sorted_units.at(j); + if (OB_ISNULL(curr_unit)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unit ptr is null", KR(ret)); + } else if (0 == j || curr_unit->zone_ == prev_unit->zone_) { + unit_count_per_zone += ObUnit::UNIT_STATUS_ACTIVE == curr_unit->status_ ? 1 : 0; + } else if (unit_count_per_zone != pool->unit_count_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("zone unit num doesn't match resource pool's unit_count", + KR(ret), "zone", prev_unit->zone_, K(unit_count_per_zone), K(pool->unit_count_)); + } else { + unit_count_per_zone = ObUnit::UNIT_STATUS_ACTIVE == curr_unit->status_ ? 1 : 0; + } + } + if (OB_SUCC(ret) && unit_count_per_zone != pool->unit_count_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("zone unit num doesn't match resource pool's unit_count", + KR(ret), "zone", curr_unit->zone_, K(unit_count_per_zone), K(pool->unit_count_)); + } + } + return ret; +} + +// this function is only used to commit part of shrinking pools of a tenant when these pools are revoked. +int ObUnitManager::inner_commit_shrink_tenant_resource_pool_( + common::ObMySQLTransaction &trans, const uint64_t tenant_id, const common::ObArray &pools) +{ + int ret = OB_SUCCESS; + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K(loaded_), K(inited_)); + } else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (pools.count() <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("pools is empty", KR(ret), K(pools)); + } else { + // first check that pools are all owned by specified tenant + FOREACH_CNT_X(pool, pools, OB_SUCCESS == ret) { + if (OB_ISNULL(*pool)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pool is null pointer", KR(ret), KP(*pool)); + } else if (tenant_id != (*pool)->tenant_id_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pool is not owned by specified tenant", KR(ret), K(tenant_id), KPC(*pool)); + } + } + ObArray> resource_units; + if (FAILEDx(commit_shrink_resource_pool_in_trans_(pools, trans, resource_units))) { + LOG_WARN("failed to shrink in trans", KR(ret), K(pools)); + } else if (OB_UNLIKELY(resource_units.count() <= 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("resource units is empty", KR(ret), K(resource_units)); + } else {/* good */} + } + return ret; +} + int ObUnitManager::get_zone_units(const ObArray &pools, ObArray &zone_units) const { diff --git a/src/rootserver/ob_unit_manager.h b/src/rootserver/ob_unit_manager.h index c32df503a..60654f157 100644 --- a/src/rootserver/ob_unit_manager.h +++ b/src/rootserver/ob_unit_manager.h @@ -265,24 +265,20 @@ public: const common::ObIArray &pool_names, bool &is_permitted); virtual int grant_pools( - common::ObISQLClient &client, + common::ObMySQLTransaction &trans, common::ObIArray &new_ug_id_array, const lib::Worker::CompatMode compat_mode, const common::ObIArray &pool_names, const uint64_t tenant_id, - const bool is_bootstrap = false, - const bool if_not_grant = false, - const bool skip_offline_server = false); + const bool is_bootstrap = false); virtual int revoke_pools( - common::ObISQLClient &client, + common::ObMySQLTransaction &trans, common::ObIArray &new_ug_id_array, const common::ObIArray &pool_names, const uint64_t tenant_id); - virtual int commit_change_pool_owner( - common::ObIArray &new_unit_group_id_array, - const bool grant, - const common::ObIArray &pool_names, - const uint64_t tenant_id); + virtual int try_complete_shrink_tenant_pool_unit_num_rs_job( + const uint64_t tenant_id, + common::ObMySQLTransaction &trans); virtual int get_pool_ids_of_tenant(const uint64_t tenant_id, common::ObIArray &pool_ids) const; virtual int get_pool_names_of_tenant(const uint64_t tenant_id, @@ -351,7 +347,7 @@ public: common::ObIArray &unit_infos) const; virtual int get_deleting_units_of_pool(const uint64_t resource_pool_id, common::ObIArray &units) const; - virtual int commit_shrink_resource_pool(const uint64_t resource_pool_id); + virtual int commit_shrink_tenant_resource_pool(const uint64_t tenant_id); virtual int get_active_unit_infos_of_pool(const uint64_t resource_pool_id, common::ObIArray &unit_infos) const; virtual int get_all_unit_infos_by_tenant(const uint64_t tenant_id, @@ -555,18 +551,17 @@ protected: const common::ObArray &excluded_servers, common::ObAddr &server) const; - int check_expand_zone_resource_allowed_by_old_unit_stat( + int check_expand_zone_resource_allowed_by_old_unit_stat_( const uint64_t tenant_id, bool &is_allowed); - int check_expand_zone_resource_allowed_by_new_unit_stat( - const common::ObIArray &pool_names, - bool &is_allowed); - int check_tenant_pools_unit_num_legal( + int check_expand_zone_resource_allowed_by_new_unit_stat_( + const common::ObIArray &pool_names); + int check_tenant_pools_unit_num_legal_( const uint64_t tenant_id, const common::ObIArray &pool_names, bool &unit_num_legal, int64_t &legal_unit_num); - int get_tenant_pool_unit_group_id( + int get_tenant_pool_unit_group_id_( const bool is_bootstrap, const bool grant, const uint64_t tenant_id, @@ -656,19 +651,6 @@ protected: const common::ObZone &zone, const common::ObReplicaType replica_type, common::ObIArray &unit_loads); - int register_shrink_pool_unit_num_rs_job( - const uint64_t resource_pool_id, - const uint64_t tenant_id, - const int64_t new_unit_num, - common::ObMySQLTransaction &trans); - int rollback_shrink_pool_unit_num_rs_job( - const uint64_t resource_pool_id, - const uint64_t tenant_id, - common::ObMySQLTransaction &trans); - int complete_shrink_pool_unit_num_rs_job( - const uint64_t resource_pool_id, - const uint64_t tenant_id, - common::ObMySQLTransaction &trans); int register_shrink_tenant_pool_unit_num_rs_job( const uint64_t tenant_id, const int64_t new_unit_num, @@ -676,7 +658,7 @@ protected: int rollback_shrink_tenant_pool_unit_num_rs_job( const uint64_t tenant_id, common::ObMySQLTransaction &trans); - int complete_shrink_tenant_pool_unit_num_rs_job( + int complete_shrink_tenant_pool_unit_num_rs_job_( const uint64_t tenant_id, common::ObMySQLTransaction &trans); int complete_migrate_unit_rs_job_in_pool( @@ -770,10 +752,6 @@ protected: share::ObResourcePool *pool, const int64_t unit_num, const common::ObIArray &delete_unit_id_array); - int shrink_granted_pool( - share::ObResourcePool *pool, - const int64_t unit_num, - const common::ObIArray &delete_unit_id_array); int check_shrink_tenant_pools_allowed( const uint64_t tenant_id, common::ObIArray &pools, @@ -809,9 +787,6 @@ protected: const common::ObIArray &pools, const common::ObIArray &new_unit_nums, bool &is_allowed); - int rollback_shrink_pool_unit_num( - share::ObResourcePool *pool, - const int64_t unit_num); int get_pool_complete_unit_num_and_status( const share::ObResourcePool *pool, int64_t &unit_num_per_zone, @@ -908,26 +883,26 @@ protected: int change_pool_config(share::ObResourcePool *pool, share::ObUnitConfig *config, share::ObUnitConfig *new_config); - int check_pool_intersect(const uint64_t tenant_id, + int check_pool_intersect_(const uint64_t tenant_id, const common::ObIArray &pool_names, bool &intersect); - // change resource pool owner - int change_pool_owner(common::ObISQLClient &client, - const common::ObIArray &new_unit_group_id_array, - const lib::Worker::CompatMode compat_mode, - const bool grant, - const common::ObIArray &pool_names, - const uint64_t tenant_id, - const bool is_bootstrap, - const bool if_not_grant = false, - const bool skip_offline_server = false); + int check_pool_ownership_(const uint64_t tenant_id, + const common::ObIArray &pool_names, + const bool grant); + int do_grant_pools_(common::ObMySQLTransaction &trans, + const common::ObIArray &new_unit_group_id_array, + const lib::Worker::CompatMode compat_mode, + const common::ObIArray &pool_names, + const uint64_t tenant_id, + const bool is_bootstrap); - // migrate all units on server to other servers -// int make_server_empty(const common::ObAddr &server, -// const common::ObIArray &excluded_servers, -// const common::ObArray *loads); -// - int add_temp_tenant(const uint64_t pool_id, const common::ObIArray &servers); + int do_revoke_pools_(common::ObMySQLTransaction &trans, + const common::ObIArray &new_unit_group_id_array, + const common::ObIArray &pool_names, + const uint64_t tenant_id); + + int build_zone_sorted_unit_array_(const share::ObResourcePool *pool, + common::ObArray &units); // build hashmaps int build_unit_map(const common::ObIArray &units); @@ -940,7 +915,6 @@ protected: int dec_config_ref_count(const uint64_t config_id); int update_pool_map(share::ObResourcePool *resource_pool); int insert_unit(share::ObUnit *unit); - int insert_units_of_pool(common::ObArray *units); int insert_unit_loads(share::ObUnit *unit); int insert_unit_load(const common::ObAddr &server, const ObUnitLoad &load); int insert_load_array(const common::ObAddr &addr, common::ObArray *load); @@ -1018,14 +992,6 @@ protected: int sum_servers_resources(ObUnitPlacementStrategy::ObServerResource &server_resource, const share::ObUnitConfig &unit_config); protected: - int inner_try_notify_tenant_server_unit_resource( - const uint64_t tenant_id, - const bool is_delete, /*Expansion of semantics, possibly deleting resources*/ - ObNotifyTenantServerResourceProxy ¬ify_proxy, - const share::ObResourcePool &new_pool, - const lib::Worker::CompatMode compat_mode, - const share::ObUnit &unit, - const bool if_not_grant); int get_pools_by_id( const common::hash::ObHashMap *> &map, const uint64_t id, common::ObArray *&pools) const; @@ -1120,11 +1086,6 @@ protected: share::ObResourcePool &resource_pool, const share::ObUnitConfigName &config_name, const bool if_not_exist); - int inner_commit_change_pool_owner( - common::ObIArray &new_unit_group_id_array, - const bool grant, - const ObIArray &pool_names, - const uint64_t tenant_id); int inner_try_delete_migrate_unit_resource( const uint64_t unit_id, const common::ObAddr &migrate_from_server); @@ -1138,6 +1099,13 @@ protected: int get_server_resource_info_via_rpc( const share::ObServerInfoInTable &server_inzfo, obrpc::ObGetServerResourceInfoResult &report_servers_resource_info) const ; + int inner_check_pool_in_shrinking_( + const uint64_t pool_id, + bool &is_shrinking); + int inner_commit_shrink_tenant_resource_pool_( + common::ObMySQLTransaction &trans, + const uint64_t tenant_id, + const common::ObArray &pools); private: int check_shrink_resource_(const common::ObIArray &pools, @@ -1215,7 +1183,11 @@ private: const double hard_limit, ObResourceType ¬_enough_resource, AlterResourceErr ¬_enough_resource_config) const; - + //LOCK IN + int commit_shrink_resource_pool_in_trans_( + const common::ObIArray &pools, + common::ObMySQLTransaction &trans, + common::ObIArray> &resource_units); private: bool inited_; diff --git a/src/rootserver/ob_unit_stat_manager.cpp b/src/rootserver/ob_unit_stat_manager.cpp index b899f5e09..2669a2d33 100644 --- a/src/rootserver/ob_unit_stat_manager.cpp +++ b/src/rootserver/ob_unit_stat_manager.cpp @@ -28,7 +28,7 @@ ObUnitStatManager::ObUnitStatManager() schema_service_(NULL), unit_mgr_(NULL), unit_stat_getter_(), - unit_stat_map_() + unit_stat_map_("UnitStatMgr") { } diff --git a/src/rootserver/restore/ob_restore_scheduler.cpp b/src/rootserver/restore/ob_restore_scheduler.cpp index 864f2f6fc..023c5e961 100644 --- a/src/rootserver/restore/ob_restore_scheduler.cpp +++ b/src/rootserver/restore/ob_restore_scheduler.cpp @@ -17,21 +17,24 @@ #include "rootserver/ob_rs_async_rpc_proxy.h" #include "rootserver/ob_rs_event_history_table_operator.h" #include "rootserver/ob_unit_manager.h"//convert_pool_name_lis -#include "rootserver/ob_tenant_role_transition_service.h"//failover_to_primary +#include "rootserver/ob_ls_service_helper.h"//create_new_ls_in_trans +#include "rootserver/ob_common_ls_service.h"//do_create_user_ls +#include "rootserver/ob_tenant_role_transition_service.h" #include "share/ob_schema_status_proxy.h" #include "share/schema/ob_schema_utils.h" #include "share/schema/ob_schema_mgr.h" #include "share/ob_upgrade_utils.h" -#include "share/backup/ob_backup_manager.h" #include "lib/mysqlclient/ob_mysql_transaction.h" //ObMySQLTransaction #include "share/ls/ob_ls_status_operator.h" //ObLSStatusOperator #include "share/ls/ob_ls_operator.h"//ObLSAttr -#include "share/backup/ob_backup_data_store.h"//ObBackupDataLSAttrDesc +#include "storage/backup/ob_backup_data_store.h"//ObBackupDataLSAttrDesc #include "share/restore/ob_physical_restore_info.h"//ObPhysicalRestoreInfo #include "share/restore/ob_physical_restore_table_operator.h"//ObPhysicalRestoreTableOperator #include "share/ob_tenant_info_proxy.h"//ObAllTenantInfo #include "share/restore/ob_log_restore_source_mgr.h" #include "share/ls/ob_ls_recovery_stat_operator.h"//ObLSRecoveryStatOperator +#include "share/ob_rpc_struct.h" +#include "share/ob_primary_standby_service.h" #include "logservice/palf/log_define.h"//scn #include "share/scn.h" @@ -122,6 +125,7 @@ void ObRestoreService::do_work() ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); } else { + ObRSThreadFlag rs_work; // avoid using default idle time when observer restarts. idle_time_us_ = GCONF._restore_idle_time; const uint64_t tenant_id = MTL_ID(); @@ -232,6 +236,9 @@ int ObRestoreService::process_restore_job(const ObPhysicalRestoreJob &job) case PHYSICAL_RESTORE_CREATE_INIT_LS: ret = restore_init_ls(job); break; + case PHYSICAL_RESTORE_WAIT_CONSISTENT_SCN: + ret = restore_wait_to_consistent_scn(job); + break; case PHYSICAL_RESTORE_WAIT_LS: ret = restore_wait_ls_finish(job); break; @@ -298,7 +305,7 @@ int ObRestoreService::restore_tenant(const ObPhysicalRestoreJob &job_info) } } int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = try_update_job_status(ret, job_info))) { + if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, ret, job_info))) { LOG_WARN("fail to update job status", K(ret), K(tmp_ret), K(job_info)); } LOG_INFO("[RESTORE] restore tenant", K(ret), K(arg), K(job_info)); @@ -342,7 +349,9 @@ int ObRestoreService::fill_create_tenant_arg( arg.tenant_schema_.set_compatibility_mode(mode); arg.if_not_exist_ = false; arg.is_restore_ = true; - arg.recovery_until_scn_ = job.get_restore_scn(); + // Physical restore is devided into 2 stages. Recover to 'consistent_scn' which was recorded during + // data backup first, then to user specified scn. + arg.recovery_until_scn_ = job.get_consistent_scn(); arg.compatible_version_ = job.get_source_data_version(); if (OB_FAIL(assign_pool_list(pool_list.ptr(), arg.pool_list_))) { LOG_WARN("fail to get pool list", K(ret), K(pool_list)); @@ -461,7 +470,7 @@ int ObRestoreService::restore_pre(const ObPhysicalRestoreJob &job_info) LOG_WARN("fail to fill restore statistics", K(ret), K(job_info)); } int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = try_update_job_status(ret, job_info))) { + if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, ret, job_info))) { LOG_WARN("fail to update job status", K(ret), K(tmp_ret), K(job_info)); } } @@ -477,20 +486,23 @@ int ObRestoreService::fill_restore_statistics(const share::ObPhysicalRestoreJob restore_progress_info.key_.tenant_id_ = job_info.get_tenant_id(); restore_progress_info.restore_scn_ = job_info.get_restore_scn(); int64_t idx = job_info.get_multi_restore_path_list().get_backup_set_path_list().count() - 1; + const int64_t turn_id = 1;// first turn; + share::ObBackupDataType type; + type.set_minor_data_backup(); if (idx < 0) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid job info", K(ret), K(idx), K(job_info)); } else { - share::ObBackupDataStore store; - share::ObExternBackupSetInfoDesc backup_set_info; - share::ObBackupDataTabletToLSDesc tablet_to_ls_info; + storage::ObBackupDataStore store; + storage::ObExternBackupSetInfoDesc backup_set_info; + storage::ObBackupDataTabletToLSDesc tablet_to_ls_info; const share::ObBackupSetPath &backup_set_path = job_info.get_multi_restore_path_list().get_backup_set_path_list().at(idx); if (OB_FAIL(store.init(backup_set_path.ptr()))) { LOG_WARN("fail to init backup data store", K(backup_set_path)); } else if (OB_FAIL(store.read_backup_set_info(backup_set_info))) { LOG_WARN("fail to read backup set info", K(ret)); - } else if (OB_FAIL(store.read_tablet_to_ls_info(1, tablet_to_ls_info))) { - LOG_WARN("fail to read tabelt to ls info", K(ret)); + } else if (OB_FAIL(store.read_tablet_to_ls_info(turn_id, type, tablet_to_ls_info))) { + LOG_WARN("fail to read tablet to ls info", K(ret)); } else { restore_progress_info.ls_count_ = tablet_to_ls_info.tablet_to_ls_.count(); ARRAY_FOREACH(tablet_to_ls_info.tablet_to_ls_, i) { @@ -591,7 +603,7 @@ int ObRestoreService::post_check(const ObPhysicalRestoreJob &job_info) if (OB_SUCC(ret)) { int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = try_update_job_status(ret, job_info))) { + if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, ret, job_info))) { LOG_WARN("fail to update job status", K(ret), K(tmp_ret), K(job_info)); } } @@ -763,7 +775,7 @@ int ObRestoreService::try_recycle_job(const ObPhysicalRestoreJob &job) } if (OB_SUCC(ret) && OB_SUCCESS != failed_ret) { int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = try_update_job_status(failed_ret, job))) { + if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, failed_ret, job))) { LOG_WARN("fail to update job status", KR(ret), K(tmp_ret), K(failed_ret), K(job)); } } @@ -771,6 +783,7 @@ int ObRestoreService::try_recycle_job(const ObPhysicalRestoreJob &job) } int ObRestoreService::try_update_job_status( + common::ObISQLClient &sql_client, int return_ret, const ObPhysicalRestoreJob &job, share::PhysicalRestoreMod mod) @@ -782,13 +795,13 @@ int ObRestoreService::try_update_job_status( LOG_WARN("not inited", K(ret)); } else if (OB_FAIL(check_stop())) { LOG_WARN("restore scheduler stopped", K(ret)); - } else if (OB_FAIL(restore_op.init(sql_proxy_, tenant_id_))) { + } else if (OB_FAIL(restore_op.init(&sql_client, tenant_id_))) { LOG_WARN("fail init", K(ret), K(tenant_id_)); } else { PhysicalRestoreStatus next_status = get_next_status(return_ret, job.get_status()); const common::ObCurTraceId::TraceId trace_id = *ObCurTraceId::get_trace_id(); - if (PHYSICAL_RESTORE_FAIL == next_status && PhysicalRestoreStatus::PHYSICAL_RESTORE_WAIT_LS != job.get_status() + if (PHYSICAL_RESTORE_FAIL == next_status && OB_LS_RESTORE_FAILED != return_ret && OB_FAIL(restore_op.update_job_error_info(job.get_job_id(), return_ret, mod, trace_id, self_addr_))) { // if restore failed at wait ls, observer has record error info, // rs no need to record error info again. @@ -855,6 +868,10 @@ PhysicalRestoreStatus ObRestoreService::get_next_status( break; } case PHYSICAL_RESTORE_CREATE_INIT_LS : { + next_status = PHYSICAL_RESTORE_WAIT_CONSISTENT_SCN; + break; + } + case PHYSICAL_RESTORE_WAIT_CONSISTENT_SCN : { next_status = PHYSICAL_RESTORE_WAIT_LS; break; } @@ -894,7 +911,7 @@ int ObRestoreService::restore_upgrade(const ObPhysicalRestoreJob &job_info) } else { if (OB_SUCC(ret)) { int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = try_update_job_status(ret, job_info))) { + if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, ret, job_info))) { LOG_WARN("fail to update job status", K(ret), K(tmp_ret), K(job_info)); } } @@ -935,9 +952,9 @@ int ObRestoreService::restore_init_ls(const share::ObPhysicalRestoreJob &job_inf } else { const int64_t backup_path_count = backup_set_path_array.count(); const ObString &backup_set_path = backup_set_path_array.at(backup_path_count - 1).ptr(); - share::ObBackupDataLSAttrDesc backup_ls_attr; + storage::ObBackupDataLSAttrDesc backup_ls_attr; ObLogRestoreSourceMgr restore_source_mgr; - share::ObBackupDataStore store; + storage::ObBackupDataStore store; if (OB_FAIL(store.init(backup_set_path.ptr()))) { LOG_WARN("fail to ini backup extern mgr", K(ret)); } else if (OB_FAIL(store.read_ls_attr_info(backup_ls_attr))) { @@ -952,8 +969,7 @@ int ObRestoreService::restore_init_ls(const share::ObPhysicalRestoreJob &job_inf tenant_id_, SYS_LS, sync_scn, readable_scn))) { LOG_WARN("failed to init ls recovery stat", KR(ret), K(backup_ls_attr.backup_scn_), K(sync_scn), K(readable_scn)); - } else if (OB_FAIL(ls_recovery.update_ls_recovery_stat(ls_recovery_stat, - *sql_proxy_))) { + } else if (OB_FAIL(ls_recovery.update_ls_recovery_stat(ls_recovery_stat, false, *sql_proxy_))) { LOG_WARN("failed to update ls recovery stat", KR(ret), K(ls_recovery_stat)); } @@ -973,7 +989,7 @@ int ObRestoreService::restore_init_ls(const share::ObPhysicalRestoreJob &job_inf } if (OB_SUCC(ret)) { int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = try_update_job_status(ret, job_info))) { + if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, ret, job_info))) { tmp_ret = OB_SUCC(ret) ? tmp_ret : ret; LOG_WARN("fail to update job status", K(ret), K(tmp_ret), K(job_info)); } @@ -985,6 +1001,39 @@ int ObRestoreService::restore_init_ls(const share::ObPhysicalRestoreJob &job_inf return ret; } + +int ObRestoreService::set_restore_to_target_scn_( + common::ObMySQLTransaction &trans, const share::ObPhysicalRestoreJob &job_info, const share::SCN &scn) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = job_info.get_tenant_id(); + ObAllTenantInfo tenant_info; + ObLSRecoveryStatOperator ls_recovery_operator; + ObLSRecoveryStat sys_ls_recovery; + ObLogRestoreSourceMgr restore_source_mgr; + if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, &trans, true/*for_update*/, tenant_info))) { + LOG_WARN("failed to load all tenant info", KR(ret), "tenant_id", job_info.get_tenant_id()); + } else if (OB_FAIL(ls_recovery_operator.get_ls_recovery_stat(tenant_id, share::SYS_LS, + true /*for_update*/, sys_ls_recovery, trans))) { + LOG_WARN("failed to get ls recovery stat", KR(ret), K(tenant_id)); + } else if (scn < tenant_info.get_sync_scn() || scn < sys_ls_recovery.get_sync_scn()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("recover before tenant sync_scn or SYS LS sync_scn is not allow", KR(ret), K(tenant_info), + K(tenant_id), K(scn), K(sys_ls_recovery)); + } else if (tenant_info.get_recovery_until_scn() == scn) { + LOG_INFO("recovery_until_scn is same with original", K(tenant_info), K(tenant_id), K(scn)); + } else if (OB_FAIL(restore_source_mgr.init(tenant_id, &trans))) { + LOG_WARN("failed to init restore_source_mgr", KR(ret), K(tenant_id), K(scn)); + } else if (OB_FAIL(restore_source_mgr.update_recovery_until_scn(scn))) { + LOG_WARN("failed to update_recovery_until_scn", KR(ret), K(tenant_id), K(scn)); + } else if (OB_FAIL(ObAllTenantInfoProxy::update_tenant_recovery_until_scn( + tenant_id, trans, tenant_info.get_switchover_epoch(), scn))) { + LOG_WARN("failed to update_tenant_recovery_until_scn", KR(ret), K(tenant_id), K(scn)); + } else { + LOG_INFO("succeed to set recover until scn", K(scn)); + } + return ret; +} int ObRestoreService::create_all_ls_( const share::schema::ObTenantSchema &tenant_schema, const common::ObIArray &ls_attr_array) @@ -1008,11 +1057,8 @@ int ObRestoreService::create_all_ls_( common::ObMySQLTransaction trans; const int64_t exec_tenant_id = ObLSLifeIAgent::get_exec_tenant_id(tenant_id_); - ObTenantLSInfo tenant_stat(sql_proxy_, &tenant_schema, tenant_id_, - srv_rpc_proxy_, GCTX.lst_operator_); - if (OB_FAIL(tenant_stat.gather_stat(true))) { - LOG_WARN("failed to gather stat", KR(ret)); - } else if (OB_FAIL(trans.start(sql_proxy_, exec_tenant_id))) { + ObTenantLSInfo tenant_stat(sql_proxy_, &tenant_schema, tenant_id_); + if (OB_FAIL(trans.start(sql_proxy_, exec_tenant_id))) { LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < ls_attr_array.count(); ++i) { @@ -1024,9 +1070,9 @@ int ObRestoreService::create_all_ls_( LOG_INFO("[RESTORE] ls already exist", K(ls_info), K(tenant_id_)); } else if (OB_ENTRY_NOT_EXIST != ret) { LOG_WARN("failed to get ls status info", KR(ret), K(tenant_id_), K(ls_info)); - } else if (OB_FAIL(tenant_stat.create_new_ls_for_recovery( + } else if (OB_FAIL(ObLSServiceHelper::create_new_ls_in_trans( ls_info.get_ls_id(), ls_info.get_ls_group_id(), ls_info.get_create_scn(), - trans, ls_flag))) { + share::NORMAL_SWITCHOVER_STATUS, tenant_stat, trans, ls_flag))) { LOG_WARN("failed to add new ls status info", KR(ret), K(ls_info)); } LOG_INFO("create init ls", KR(ret), K(ls_info)); @@ -1064,12 +1110,10 @@ int ObRestoreService::wait_all_ls_created_(const share::schema::ObTenantSchema & ObLSRecoveryStat recovery_stat; ObLSRecoveryStatOperator ls_recovery_operator; - ObTenantLSInfo tenant_stat(sql_proxy_, &tenant_schema, tenant_id_, - srv_rpc_proxy_, GCTX.lst_operator_); if (OB_FAIL(status_op.get_all_ls_status_by_order(tenant_id, ls_array, *sql_proxy_))) { LOG_WARN("failed to get all ls status", KR(ret), K(tenant_id)); - } + } for (int64_t i = 0; OB_SUCC(ret) && i < ls_array.count(); ++i) { const ObLSStatusInfo &info = ls_array.at(i); if (info.ls_is_creating()) { @@ -1081,10 +1125,11 @@ int ObRestoreService::wait_all_ls_created_(const share::schema::ObTenantSchema & job_info, info.ls_id_, palf_base_info))) { LOG_WARN("failed to get restore ls palf info", KR(ret), K(info), K(job_info)); - } else if (OB_FAIL(tenant_stat.create_ls_with_palf(info, recovery_stat.get_create_scn(), - true,/*create with palf*/ - palf_base_info))) { - LOG_WARN("failed to create ls with palf", KR(ret), K(info), + } else if (OB_FAIL(ObCommonLSService::do_create_user_ls( + tenant_schema, info, recovery_stat.get_create_scn(), + true, /*create with palf*/ + palf_base_info))) { + LOG_WARN("failed to create ls with palf", KR(ret), K(info), K(tenant_schema), K(palf_base_info)); } } @@ -1161,6 +1206,82 @@ int ObRestoreService::finish_create_ls_( return ret; } +int ObRestoreService::restore_wait_to_consistent_scn(const share::ObPhysicalRestoreJob &job_info) +{ + int ret = OB_SUCCESS; + TenantRestoreStatus tenant_restore_status; + const uint64_t tenant_id = job_info.get_tenant_id(); + const ObTenantSchema *tenant_schema = NULL; + ObSchemaGetterGuard schema_guard; + bool is_replay_finish = false; + DEBUG_SYNC(BEFORE_WAIT_RESTORE_TO_CONSISTENT_SCN); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (OB_FAIL(check_tenant_can_restore_(tenant_id))) { + LOG_WARN("failed to check tenant can restore", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); + } else if (OB_FAIL(schema_service_->get_tenant_schema_guard( + OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get tenant schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) { + LOG_WARN("fail to get tenant schema", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(tenant_schema) || !tenant_schema->is_restore()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant not exist or tenant is not in physical restore status", KR(ret), + KPC(tenant_schema)); + } else if (OB_FAIL(check_all_ls_restore_to_consistent_scn_finish_(tenant_id, tenant_restore_status))) { + LOG_WARN("fail to check all ls restore finish", KR(ret), K(job_info)); + } else if (is_tenant_restore_finish(tenant_restore_status)) { + LOG_INFO("[RESTORE] restore wait all ls restore to consistent scn done", K(tenant_id), K(tenant_restore_status)); + int tmp_ret = OB_SUCCESS; + ObMySQLTransaction trans; + const uint64_t exec_tenant_id = gen_meta_tenant_id(job_info.get_tenant_id()); + if (is_tenant_restore_failed(tenant_restore_status)) { + ret = OB_LS_RESTORE_FAILED; + LOG_INFO("[RESTORE]restore wait all ls restore to consistent scn failed", K(ret)); + if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, ret, job_info))) { + LOG_WARN("fail to update job status", KR(ret), K(job_info)); + } + } else if (OB_FAIL(check_tenant_replay_to_consistent_scn(tenant_id, job_info.get_consistent_scn(), is_replay_finish))) { + LOG_WARN("fail to check tenant replay to consistent scn", K(ret)); + } else if (!is_replay_finish) { + } else if (OB_FAIL(trans.start(sql_proxy_, exec_tenant_id))) { + LOG_WARN("fail to start trans", K(ret)); + } else if (OB_FAIL(set_restore_to_target_scn_(trans, job_info, job_info.get_restore_scn()))) { + LOG_WARN("fail to set restore to target scn", KR(ret)); + } else if (OB_FAIL(try_update_job_status(trans, ret, job_info))) { + LOG_WARN("fail to update job status", KR(ret), K(job_info)); + } + if (trans.is_started()) { + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("fail to rollback trans", KR(tmp_ret)); + } + } + } + return ret; +} + + + +int ObRestoreService::check_tenant_replay_to_consistent_scn(const uint64_t tenant_id, const share::SCN &scn, bool &is_replay_finish) +{ + int ret = OB_SUCCESS; + ObAllTenantInfo tenant_info; + if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, sql_proxy_, false/*no update*/, tenant_info))) { + LOG_WARN("failed to load tenant info", K(ret)); + } else if (tenant_info.get_recovery_until_scn() != scn) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("unexpected recovery until scn", K(ret), K(tenant_info), K(scn)); + } else { + is_replay_finish = (tenant_info.get_recovery_until_scn() <= tenant_info.get_standby_scn()); + LOG_INFO("[RESTORE]tenant replay to consistent_scn", K(is_replay_finish)); + } + return ret; +} + int ObRestoreService::restore_wait_ls_finish(const share::ObPhysicalRestoreJob &job_info) { int ret = OB_SUCCESS; @@ -1192,11 +1313,11 @@ int ObRestoreService::restore_wait_ls_finish(const share::ObPhysicalRestoreJob & } else if (is_tenant_restore_finish(tenant_restore_status)) { LOG_INFO("[RESTORE] restore wait all ls finish done", K(tenant_id), K(tenant_restore_status)); int tmp_ret = OB_SUCCESS; - int tenant_restore_result = OB_ERROR; + int tenant_restore_result = OB_LS_RESTORE_FAILED; if (is_tenant_restore_success(tenant_restore_status)) { tenant_restore_result = OB_SUCCESS; } - if (OB_SUCCESS != (tmp_ret = try_update_job_status(tenant_restore_result, job_info))) { + if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, tenant_restore_result, job_info))) { LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), KR(tenant_restore_result), K(job_info)); } } @@ -1247,7 +1368,7 @@ int ObRestoreService::check_all_ls_restore_finish_( //restore failed tenant_restore_status = TenantRestoreStatus::FAILED; } else if (!ls_restore_status.is_restore_none() - && is_tenant_restore_success(tenant_restore_status)) { + && is_tenant_restore_success(tenant_restore_status)) { tenant_restore_status = TenantRestoreStatus::IN_PROGRESS; } } // while @@ -1264,6 +1385,35 @@ int ObRestoreService::check_all_ls_restore_finish_( return ret; } +int ObRestoreService::check_all_ls_restore_to_consistent_scn_finish_( + const uint64_t tenant_id, + TenantRestoreStatus &tenant_restore_status) +{ + int ret = OB_SUCCESS; + bool is_finished = false; + bool is_success = false; + ObPhysicalRestoreTableOperator restore_op; + if (OB_FAIL(restore_op.init(sql_proxy_, tenant_id))) { + LOG_WARN("fail init", K(ret), K(tenant_id_)); + } else if (OB_FAIL(restore_op.check_finish_restore_to_consistent_scn(is_finished, is_success))) { + LOG_WARN("fail to check finish restore to consistent_scn", K(ret), K(tenant_id)); + } else if (!is_finished) { + tenant_restore_status = TenantRestoreStatus::IN_PROGRESS; + } else if (is_success) { + tenant_restore_status = TenantRestoreStatus::SUCCESS; + } else { + tenant_restore_status = TenantRestoreStatus::FAILED; + } + + if (OB_FAIL(ret)) { + } else if (TenantRestoreStatus::SUCCESS != tenant_restore_status) { + LOG_INFO("check all ls restore to consistent_scn not finish, just wait", KR(ret), + K(tenant_id), K(tenant_restore_status)); + } + + return ret; +} + int ObRestoreService::restore_wait_tenant_finish(const share::ObPhysicalRestoreJob &job_info) { int ret = OB_SUCCESS; @@ -1312,7 +1462,7 @@ int ObRestoreService::restore_wait_tenant_finish(const share::ObPhysicalRestoreJ } if (OB_SUCC(ret)) { int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = try_update_job_status(ret, job_info))) { + if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, ret, job_info))) { LOG_WARN("fail to update job status", K(ret), K(tmp_ret), K(job_info)); } @@ -1325,7 +1475,7 @@ int ObRestoreService::restore_wait_tenant_finish(const share::ObPhysicalRestoreJ //restore failed int tmp_ret = OB_SUCCESS; ret = OB_ERROR; - if (OB_SUCCESS != (tmp_ret = try_update_job_status(ret, job_info))) { + if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, ret, job_info))) { LOG_WARN("fail to update job status", K(ret), K(tmp_ret), K(job_info)); } diff --git a/src/rootserver/restore/ob_restore_scheduler.h b/src/rootserver/restore/ob_restore_scheduler.h index 8757509c6..24b910266 100644 --- a/src/rootserver/restore/ob_restore_scheduler.h +++ b/src/rootserver/restore/ob_restore_scheduler.h @@ -13,9 +13,8 @@ #ifndef OCEANBASE_ROOTSERVER_OB_RESTORE_SCHEDULER_H_ #define OCEANBASE_ROOTSERVER_OB_RESTORE_SCHEDULER_H_ -#include "share/backup/ob_backup_info_mgr.h" #include "rootserver/restore/ob_restore_util.h" -#include "rootserver/ob_primary_ls_service.h"//ObTenantThreadHelper +#include "rootserver/ob_tenant_thread_helper.h"//ObTenantThreadHelper #include "share/backup/ob_backup_struct.h" #include "share/ob_rpc_struct.h" #include "share/ob_common_rpc_proxy.h" @@ -100,6 +99,9 @@ private: int restore_finish(const share::ObPhysicalRestoreJob &job_info); int tenant_restore_finish(const share::ObPhysicalRestoreJob &job_info); int restore_init_ls(const share::ObPhysicalRestoreJob &job_info); + int restore_wait_to_consistent_scn(const share::ObPhysicalRestoreJob &job_info); + int check_tenant_replay_to_consistent_scn(const uint64_t tenant_id, const share::SCN &scn, bool &is_replay_finish); + int set_restore_to_target_scn_(common::ObMySQLTransaction &sql_client, const share::ObPhysicalRestoreJob &job_info, const share::SCN &scn); int restore_wait_ls_finish(const share::ObPhysicalRestoreJob &job_info); int restore_wait_tenant_finish(const share::ObPhysicalRestoreJob &job_info); @@ -112,6 +114,7 @@ private: int check_locality_valid(const share::schema::ZoneLocalityIArray &locality); int try_update_job_status( + common::ObISQLClient &sql_client, int return_ret, const share::ObPhysicalRestoreJob &job, share::PhysicalRestoreMod mod = share::PHYSICAL_RESTORE_MOD_RS); @@ -129,6 +132,7 @@ private: int finish_create_ls_(const share::schema::ObTenantSchema &tenant_schema, const common::ObIArray &ls_attr_array); int check_all_ls_restore_finish_(const uint64_t tenant_id, TenantRestoreStatus &tenant_restore_status); + int check_all_ls_restore_to_consistent_scn_finish_(const uint64_t tenant_id, TenantRestoreStatus &tenant_restore_status); int try_get_tenant_restore_history_(const share::ObPhysicalRestoreJob &job_info, share::ObHisRestoreJobPersistInfo &history_info, bool &restore_tenant_exist); diff --git a/src/rootserver/restore/ob_restore_util.cpp b/src/rootserver/restore/ob_restore_util.cpp index 85b185a1e..65198118d 100644 --- a/src/rootserver/restore/ob_restore_util.cpp +++ b/src/rootserver/restore/ob_restore_util.cpp @@ -23,10 +23,9 @@ #include "rootserver/ob_rs_event_history_table_operator.h" #include "storage/backup/ob_backup_restore_util.h" #include "share/backup/ob_archive_store.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" #include "share/restore/ob_restore_persist_helper.h"//ObRestorePersistHelper ObRestoreProgressPersistInfo #include "logservice/palf/palf_base_info.h"//PalfBaseInfo -#include "storage/backup/ob_backup_extern_info_mgr.h"//ObExternLSMetaMgr #include "storage/ls/ob_ls_meta_package.h"//ls_meta #include "share/backup/ob_archive_path.h" #include "share/ob_upgrade_utils.h" @@ -344,7 +343,7 @@ int ObRestoreUtil::fill_restore_scn_(const obrpc::ObPhysicalRestoreTenantArg &ar SCN min_restore_scn = SCN::min_scn(); ARRAY_FOREACH_X(tenant_path_array, i, cnt, OB_SUCC(ret)) { const ObString &tenant_path = tenant_path_array.at(i); - share::ObBackupDataStore store; + storage::ObBackupDataStore store; share::ObBackupDest backup_dest; ObBackupFormatDesc format_desc; share::ObBackupSetFileDesc backup_set_file_desc; @@ -458,7 +457,7 @@ int ObRestoreUtil::check_restore_using_complement_log_( } else { ARRAY_FOREACH_X(tenant_path_array, i, cnt, OB_SUCC(ret)) { const ObString &tenant_path = tenant_path_array.at(i); - share::ObBackupDataStore store; + storage::ObBackupDataStore store; share::ObBackupDest backup_dest; ObBackupFormatDesc format_desc; if (OB_FAIL(backup_dest.set(tenant_path.ptr()))) { @@ -491,7 +490,7 @@ int ObRestoreUtil::get_restore_backup_set_array_( } else { ARRAY_FOREACH_X(tenant_path_array, i, cnt, OB_SUCC(ret)) { const ObString &tenant_path = tenant_path_array.at(i); - share::ObBackupDataStore store; + storage::ObBackupDataStore store; share::ObBackupDest backup_dest; ObBackupFormatDesc format_desc; if (OB_FAIL(backup_dest.set(tenant_path.ptr()))) { @@ -684,7 +683,7 @@ int ObRestoreUtil::do_fill_backup_info_( share::ObPhysicalRestoreJob &job) { int ret = OB_SUCCESS; - share::ObBackupDataStore store; + storage::ObBackupDataStore store; HEAP_VARS_2((ObExternBackupSetInfoDesc, backup_set_info), (ObExternTenantLocalityInfoDesc, locality_info)) { if (backup_set_path.is_empty()) { @@ -710,6 +709,7 @@ int ObRestoreUtil::do_fill_backup_info_( job.set_source_cluster_version(backup_set_info.backup_set_file_.cluster_version_); job.set_compat_mode(locality_info.compat_mode_); job.set_backup_tenant_id(backup_set_info.backup_set_file_.tenant_id_); + job.set_consistent_scn(backup_set_info.backup_set_file_.consistent_scn_); } } return ret; @@ -783,20 +783,23 @@ int ObRestoreUtil::recycle_restore_job(const uint64_t tenant_id, } else if (OB_FAIL(history_info.init_with_job_process( job_info, restore_progress))) { LOG_WARN("failed to init history", KR(ret), K(job_info), K(restore_progress)); + } else if (history_info.is_restore_success()) { // restore succeed, no need to record comment } else if (OB_FAIL(persist_helper.get_all_ls_restore_progress(trans, ls_restore_progress_infos))) { LOG_WARN("failed to get ls restore progress", K(ret)); } else { + int64_t pos = 0; ARRAY_FOREACH_X(ls_restore_progress_infos, i, cnt, OB_SUCC(ret)) { const ObLSRestoreProgressPersistInfo &ls_restore_info = ls_restore_progress_infos.at(i); if (ls_restore_info.status_.is_restore_failed()) { - char buf[OB_MAX_SERVER_ADDR_SIZE] = { 0 }; - if (OB_FAIL(ls_restore_info.key_.addr_.ip_port_to_string(buf, OB_MAX_SERVER_ADDR_SIZE))) { - LOG_WARN("fail to addr to string", K(ret)); - } else if (OB_FAIL(history_info.comment_.append_fmt("ls_id: %ld, addr: %.*s, %.*s;", - ls_restore_info.key_.ls_id_.id(), static_cast(OB_MAX_SERVER_ADDR_SIZE), buf, - static_cast(ls_restore_info.comment_.length()), ls_restore_info.comment_.ptr()))) { - LOG_WARN("fail to append fmt", K(ret)); - } + if (OB_FAIL(databuff_printf(history_info.comment_.ptr(), history_info.comment_.capacity(), pos, + "%s;", ls_restore_info.comment_.ptr()))) { + if (OB_SIZE_OVERFLOW == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to databuff printf comment", K(ret)); + } + } } } } @@ -890,7 +893,7 @@ int ObRestoreUtil::get_restore_ls_palf_base_info( palf::PalfBaseInfo &palf_base_info) { int ret = OB_SUCCESS; - share::ObBackupDataStore store; + storage::ObBackupDataStore store; const common::ObSArray &backup_set_array = job_info.get_multi_restore_path_list().get_backup_set_path_list(); const int64_t idx = backup_set_array.count() - 1; diff --git a/src/rootserver/virtual_table/ob_all_virtual_backup_task_scheduler_stat.cpp b/src/rootserver/virtual_table/ob_all_virtual_backup_task_scheduler_stat.cpp index 9811fedbb..a651f329e 100644 --- a/src/rootserver/virtual_table/ob_all_virtual_backup_task_scheduler_stat.cpp +++ b/src/rootserver/virtual_table/ob_all_virtual_backup_task_scheduler_stat.cpp @@ -1,14 +1,12 @@ -/** - * Copyright (c) 2021 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. - */ +// Copyright (c) 2021 OceanBase +// OceanBase 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. #define USING_LOG_PREFIX RS #include "ob_all_virtual_backup_task_scheduler_stat.h" @@ -38,90 +36,35 @@ void ObAllBackupScheduleTaskStat::Display::reset() executor_ts_ = 0; } -ObAllBackupScheduleTaskStat::ObAllBackupScheduleTaskStat() - :inited_(false), - schema_service_(nullptr), - task_scheduer_(nullptr), - arena_allocator_() -{ -} - -ObAllBackupScheduleTaskStat::~ObAllBackupScheduleTaskStat() -{ -} - -int ObAllBackupScheduleTaskStat::init( - share::schema::ObMultiVersionSchemaService &schema_service, - ObBackupTaskScheduler &task_scheduler) -{ - int ret = OB_SUCCESS; - if (inited_) { - ret = OB_INIT_TWICE; - LOG_WARN("init twice", K(ret)); - } else { - schema_service_ = &schema_service; - task_scheduer_ = &task_scheduler; - inited_ = true; - } - - return ret; -} - int ObAllBackupScheduleTaskStat::inner_get_next_row(ObNewRow *&row) { int ret = OB_SUCCESS; ObSchemaGetterGuard schema_guard; - if (NULL == allocator_) { - ret = OB_NOT_INIT; - LOG_WARN("not init, allocator is null", K(ret)); - } else if (!inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("get schema guard error", K(ret)); - } else if (!start_to_read_) { - common::ObArenaAllocator allocator; - ObArray task_stats; - const ObTableSchema *table_schema = NULL; - const uint64_t table_id = OB_ALL_VIRTUAL_BACKUP_SCHEDULE_TASK_TID; - if (OB_FAIL(schema_guard.get_table_schema(OB_SYS_TENANT_ID, table_id, table_schema))) { - LOG_WARN("fail to get table schema", K(table_id), K(ret)); - } else if (NULL == table_schema) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table_schema is null", KP(table_schema), K(ret)); - } else if (OB_FAIL(task_scheduer_->get_all_tasks(allocator, task_stats))) { - LOG_WARN("fail to get tasks", K(ret)); + if (!start_to_read_) { + auto func_iterate_tenant_task_scheduler = [&]() -> int + { + int ret = OB_SUCCESS; + common::ObArenaAllocator allocator; + ObArray task_stats; + ObBackupTaskScheduler *task_scheduler = MTL(ObBackupTaskScheduler *); + if (OB_ISNULL(task_scheduler)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task scheduler can't be null", K(ret)); + } else if (OB_FAIL(task_scheduler->get_all_tasks(allocator, task_stats))) { + LOG_WARN("fail to get tasks", K(ret)); + } else if (OB_FAIL(generate_all_row_(task_stats))) { + LOG_WARN("fail to generate all row", K(ret)); + } + return ret; + }; + if (OB_FAIL(omt_->operate_in_each_tenant(func_iterate_tenant_task_scheduler))) { + LOG_WARN("fail to operater in each tenant", K(ret)); } else { - ObArray columns; - for (int64_t j = 0; OB_SUCC(ret) && j < task_stats.count(); ++j) { - const ObBackupScheduleTask *task_stat = task_stats.at(j); - columns.reuse(); - if (OB_UNLIKELY(nullptr == task_stat)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("task stat", K(ret)); - } else if (OB_FAIL(get_full_row_(table_schema, *task_stat, columns))) { - LOG_WARN("fail to get full row", "table_schema", *table_schema, "task_stat", *task_stat, K(ret)); - } else if (OB_FAIL(project_row(columns, cur_row_))) { - LOG_WARN("fail to project row", K(columns), K(ret)); - } else if (OB_FAIL(scanner_.add_row(cur_row_))) { - LOG_WARN("fail to add row", K(cur_row_), K(ret)); - } - } - } - - for (int64_t j = 0; j < task_stats.count(); ++j) { - ObBackupScheduleTask *task_stat = task_stats.at(j); - if (nullptr != task_stat) { - task_stat->~ObBackupScheduleTask(); - task_stat = nullptr; - } - } - if (OB_SUCC(ret)) { scanner_it_ = scanner_.begin(); start_to_read_ = true; } } - if (OB_SUCC(ret)) { + if (OB_SUCC(ret) && start_to_read_) { if (OB_FAIL(scanner_it_.get_next_row(cur_row_))) { if (OB_ITER_END != ret) { LOG_WARN("fail to get next row", K(ret)); @@ -133,6 +76,31 @@ int ObAllBackupScheduleTaskStat::inner_get_next_row(ObNewRow *&row) return ret; } +int ObAllBackupScheduleTaskStat::generate_all_row_(ObIArray &task_stats) +{ + int ret = OB_SUCCESS; + for (int64_t j = 0; OB_SUCC(ret) && j < task_stats.count(); ++j) { + const ObBackupScheduleTask *task_stat = task_stats.at(j); + if (OB_UNLIKELY(nullptr == task_stat)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task stat", K(ret)); + } else if (OB_FAIL(get_full_row_(*task_stat))) { + LOG_WARN("fail to get full row", "task_stat", *task_stat, K(ret)); + } else if (OB_FAIL(scanner_.add_row(cur_row_))) { + LOG_WARN("fail to add row", K(cur_row_), K(ret)); + } + } + + for (int64_t j = 0; j < task_stats.count(); ++j) { + ObBackupScheduleTask *task_stat = task_stats.at(j); + if (nullptr != task_stat) { + task_stat->~ObBackupScheduleTask(); + task_stat = nullptr; + } + } + return ret; +} + int ObAllBackupScheduleTaskStat::generate_task_stat_( const ObBackupScheduleTask &task_stat, Display &display) @@ -153,42 +121,106 @@ int ObAllBackupScheduleTaskStat::generate_task_stat_( return ret; } -int ObAllBackupScheduleTaskStat::get_full_row_( - const share::schema::ObTableSchema *table, - const ObBackupScheduleTask &task_stat, - common::ObIArray &columns) +int ObAllBackupScheduleTaskStat::get_full_row_(const ObBackupScheduleTask &task_stat) { int ret = OB_SUCCESS; Display display; + ObAddr self_addr = GCONF.self_addr_; char *dst_str = nullptr; char *trace_id_str = nullptr; - arena_allocator_.reuse(); - if (nullptr == table) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("table is nullptr", K(ret)); - } else if (OB_ISNULL(dst_str = static_cast(arena_allocator_.alloc(OB_MAX_SERVER_ADDR_SIZE)))) { + + if (OB_ISNULL(dst_str = static_cast(allocator_.alloc(OB_MAX_SERVER_ADDR_SIZE)))) { ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_ERROR("alloc dst ip buf failed", K(ret), "size", OB_MAX_SERVER_ADDR_SIZE); - } else if (OB_ISNULL(trace_id_str = static_cast(arena_allocator_.alloc(OB_MAX_TRACE_ID_BUFFER_SIZE)))) { + LOG_WARN("fail to alloc memory", KR(ret), K(dst_str)); + } else if (OB_FALSE_IT(MEMSET(dst_str, '\0', OB_MAX_SERVER_ADDR_SIZE))) { + } else if (OB_ISNULL(trace_id_str = static_cast(allocator_.alloc(OB_MAX_TRACE_ID_BUFFER_SIZE)))) { ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_ERROR("alloc trace id buf failed", K(ret), "size", OB_MAX_TRACE_ID_BUFFER_SIZE); + LOG_WARN("fail to alloc memory", KR(ret), K(trace_id_str)); + } else if (OB_FALSE_IT(MEMSET(trace_id_str, '\0', OB_MAX_TRACE_ID_BUFFER_SIZE))) { } else if (OB_FAIL(generate_task_stat_(task_stat, display))) { LOG_WARN("fail to generate task stat", K(task_stat), K(ret)); } else if (display.dst_.is_valid() && OB_FAIL(display.dst_.ip_port_to_string(dst_str, OB_MAX_SERVER_ADDR_SIZE))) { LOG_WARN("fail to change dst to string", K(ret), K(display)); - } else if (!display.trace_id_.is_invalid() && OB_FALSE_IT(display.trace_id_.to_string(trace_id_str, OB_MAX_TRACE_ID_BUFFER_SIZE))) { - } else { - ADD_COLUMN(set_int, table, "tenant_id", display.tenant_id_, columns); - ADD_COLUMN(set_int, table, "job_id", display.job_id_, columns); - ADD_COLUMN(set_int, table, "task_id", display.task_id_, columns); - ADD_COLUMN(set_int, table, "ls_id", display.key_1_, columns); - ADD_COLUMN(set_int, table, "type", static_cast(display.job_type_), columns); - ADD_COLUMN(set_varchar, table, "trace_id", trace_id_str, columns); - ADD_COLUMN(set_varchar, table, "destination", dst_str, columns); - ADD_COLUMN(set_varchar, table, "is_schedule", display.is_schedule ? "True" : "False", columns); - ADD_COLUMN(set_int, table, "generate_ts", display.generate_ts_, columns); - ADD_COLUMN(set_int, table, "schedule_ts", display.schedule_ts_, columns); - ADD_COLUMN(set_int, table, "executor_ts", display.executor_ts_, columns); + } else if (!display.trace_id_.is_invalid()) { + display.trace_id_.to_string(trace_id_str, OB_MAX_TRACE_ID_BUFFER_SIZE); + } + + const int64_t count = output_column_ids_.count(); + for (int i = 0; OB_SUCC(ret) && i < count; i++) { + uint64_t col_id = output_column_ids_.at(i); + switch (col_id) { + case Column::TENANT_ID: { + cur_row_.cells_[i].set_int(display.tenant_id_); + break; + } + case Column::SVR_IP: { + char *addr_buf = nullptr; + if (OB_ISNULL(addr_buf = static_cast(allocator_.alloc(OB_IP_PORT_STR_BUFF)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc memory", KR(ret), K(dst_str)); + } else if (OB_FALSE_IT(MEMSET(addr_buf, '\0', OB_IP_PORT_STR_BUFF))) { + } else if (!self_addr.ip_to_string(addr_buf, common::OB_IP_PORT_STR_BUFF)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "ip_to_string failed", K(ret)); + } else { + cur_row_.cells_[i].set_varchar(ObString::make_string(addr_buf)); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation( + ObCharset::get_default_charset())); + } + break; + } + case Column::SVR_PORT: { + cur_row_.cells_[i].set_int(self_addr.get_port()); + break; + } + + case Column::JOB_ID: { + cur_row_.cells_[i].set_int(display.job_id_); + break; + } + case Column::TASK_ID: { + cur_row_.cells_[i].set_int(display.task_id_); + break; + } + case Column::LS_ID: { + cur_row_.cells_[i].set_int(display.key_1_); + break; + } + case Column::JOB_TYPE: { + cur_row_.cells_[i].set_int(static_cast(display.job_type_)); + break; + } + case Column::TRACE_ID: { + cur_row_.cells_[i].set_varchar(trace_id_str); + break; + } + case Column::DST: { + cur_row_.cells_[i].set_varchar(dst_str); + break; + } + case Column::IS_SCHEDULE: { + const char *flag = display.is_schedule ? "True" : "False"; + cur_row_.cells_[i].set_varchar(flag); + break; + } + case Column::GENERATE_TS: { + cur_row_.cells_[i].set_int(display.generate_ts_); + break; + } + case Column::SCHEDULE_TS: { + cur_row_.cells_[i].set_int(display.schedule_ts_); + break; + } + case Column::EXECUTOR_TS: { + cur_row_.cells_[i].set_int(display.executor_ts_); + break; + } + default: { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unkown column", K(ret), K(col_id)); + break; + } + } } return ret; } diff --git a/src/rootserver/virtual_table/ob_all_virtual_backup_task_scheduler_stat.h b/src/rootserver/virtual_table/ob_all_virtual_backup_task_scheduler_stat.h index a3169c1f9..a31c2dc45 100644 --- a/src/rootserver/virtual_table/ob_all_virtual_backup_task_scheduler_stat.h +++ b/src/rootserver/virtual_table/ob_all_virtual_backup_task_scheduler_stat.h @@ -1,14 +1,12 @@ -/** - * Copyright (c) 2021 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. - */ +// Copyright (c) 2021 OceanBase +// OceanBase 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_ROOTSERVER_OB_ALL_VIRTUAL_BACKUP_TASK_SCHEDULER_STAT_H_ #define OCEANBASE_ROOTSERVER_OB_ALL_VIRTUAL_BACKUP_TASK_SCHEDULER_STAT_H_ @@ -17,7 +15,8 @@ #include "share/ob_virtual_table_projector.h" #include "rootserver/backup/ob_backup_task_scheduler.h" - +#include "observer/omt/ob_multi_tenant.h" +#include "share/ob_define.h" namespace oceanbase { namespace share @@ -34,14 +33,26 @@ class ObBackupScheduleTask; class ObAllBackupScheduleTaskStat : public common::ObVirtualTableProjector { public: - ObAllBackupScheduleTaskStat(); - virtual ~ObAllBackupScheduleTaskStat(); - - int init(share::schema::ObMultiVersionSchemaService &schema_service, - ObBackupTaskScheduler &task_scheduler); + explicit ObAllBackupScheduleTaskStat(omt::ObMultiTenant *omt) : omt_(omt), allocator_() {} + virtual ~ObAllBackupScheduleTaskStat() {} virtual int inner_get_next_row(common::ObNewRow *&row); - private: + enum Column : int64_t + { + TENANT_ID = common::OB_APP_MIN_COLUMN_ID, + SVR_IP = common::OB_APP_MIN_COLUMN_ID + 1, + SVR_PORT = common::OB_APP_MIN_COLUMN_ID + 2, + JOB_ID = common::OB_APP_MIN_COLUMN_ID + 3, + TASK_ID = common::OB_APP_MIN_COLUMN_ID + 4, + LS_ID = common::OB_APP_MIN_COLUMN_ID + 5, + JOB_TYPE = common::OB_APP_MIN_COLUMN_ID + 6, + TRACE_ID = common::OB_APP_MIN_COLUMN_ID + 7, + DST = common::OB_APP_MIN_COLUMN_ID + 8, + IS_SCHEDULE = common::OB_APP_MIN_COLUMN_ID + 9, + GENERATE_TS = common::OB_APP_MIN_COLUMN_ID + 10, + SCHEDULE_TS = common::OB_APP_MIN_COLUMN_ID + 11, + EXECUTOR_TS = common::OB_APP_MIN_COLUMN_ID + 12 + }; struct Display { void reset(); @@ -59,18 +70,12 @@ private: TO_STRING_KV(K_(tenant_id), K_(job_id), K_(task_id), K_(key_1), K_(job_type), K_(trace_id), K_(dst), K_(generate_ts), K_(schedule_ts), K_(executor_ts)); }; - - int generate_task_stat_(const ObBackupScheduleTask &task_stat, - Display &display); - int get_full_row_(const share::schema::ObTableSchema *table, - const ObBackupScheduleTask &task_stat, - common::ObIArray &columns); + int generate_all_row_(ObIArray &task_stats); + int generate_task_stat_(const ObBackupScheduleTask &task_stat, Display &display); + int get_full_row_(const ObBackupScheduleTask &task_stat); private: - bool inited_; - share::schema::ObMultiVersionSchemaService *schema_service_; - ObBackupTaskScheduler *task_scheduer_; - common::ObArenaAllocator arena_allocator_; - + omt::ObMultiTenant *omt_; + common::ObArenaAllocator allocator_; private: DISALLOW_COPY_AND_ASSIGN(ObAllBackupScheduleTaskStat); }; diff --git a/src/rootserver/virtual_table/ob_core_meta_table.cpp b/src/rootserver/virtual_table/ob_core_meta_table.cpp index 2ebfe6aa1..28e2d713b 100644 --- a/src/rootserver/virtual_table/ob_core_meta_table.cpp +++ b/src/rootserver/virtual_table/ob_core_meta_table.cpp @@ -168,6 +168,7 @@ int ObCoreMetaTable::get_full_row(const ObTableSchema *table, ADD_COLUMN(set_int, table, "data_size", replica.get_data_size(), columns); ADD_COLUMN(set_int, table, "required_size", replica.get_required_size(), columns); ADD_TEXT_COLUMN(ObLongTextType, table, "learner_list", learner_list, columns); + ADD_COLUMN(set_int, table, "rebuild", replica.get_rebuild(), columns); } if (OB_FAIL(ret)) { diff --git a/src/share/CMakeLists.txt b/src/share/CMakeLists.txt old mode 100644 new mode 100755 index 1a1e9b28b..3d61cceed --- a/src/share/CMakeLists.txt +++ b/src/share/CMakeLists.txt @@ -31,18 +31,12 @@ ob_set_subtarget(ob_share backup backup/ob_backup_clean_struct.cpp backup/ob_backup_clean_util.cpp backup/ob_backup_connectivity.cpp - backup/ob_backup_file_lock_mgr.cpp - backup/ob_backup_info_mgr.cpp backup/ob_backup_io_adapter.cpp - backup/ob_backup_lease_info_mgr.cpp - backup/ob_backup_manager.cpp - backup/ob_backup_operator.cpp backup/ob_backup_path.cpp + backup/ob_backup_server_mgr.cpp backup/ob_backup_struct.cpp - backup/ob_log_archive_backup_info_mgr.cpp backup/ob_tenant_archive_mgr.cpp backup/ob_tenant_archive_round.cpp - backup/ob_backup_data_store.cpp backup/ob_backup_data_table_operator.cpp backup/ob_backup_helper.cpp backup/ob_archive_persist_helper.cpp @@ -185,6 +179,7 @@ ob_set_subtarget(ob_share common ob_inner_table_operator.cpp ob_standby_upgrade.cpp ob_primary_standby_service.cpp + ob_common_id.cpp ob_cluster_event_history_table_operator.cpp scn.cpp ob_throttling_utils.cpp @@ -244,6 +239,8 @@ ob_set_subtarget(ob_share common_mixed table/ob_table_load_rpc_struct.cpp table/ob_table_load_shared_allocator.cpp table/ob_table_load_row.cpp + transfer/ob_transfer_info.cpp + transfer/ob_transfer_task_operator.cpp detect/ob_detect_manager.cpp detect/ob_detectable_id.cpp detect/ob_detect_callback.cpp @@ -261,6 +258,7 @@ ob_set_subtarget(ob_share tablet tablet/ob_tablet_to_ls_iterator.cpp tablet/ob_tablet_filter.cpp tablet/ob_tablet_to_table_history_operator.cpp + tablet/ob_tenant_tablet_to_ls_map.cpp ) ob_set_subtarget(ob_share config @@ -479,6 +477,13 @@ ob_set_subtarget(ob_share unit unit/ob_unit_resource.cpp unit/ob_unit_info.cpp ) +ob_set_subtarget(ob_share balance + ob_balance_define.cpp + balance/ob_balance_job_table_operator.cpp + balance/ob_balance_task_table_operator.cpp + balance/ob_balance_task_helper_operator.cpp +) + ob_add_new_object_target(ob_share ob_share) diff --git a/src/share/backup/ob_archive_checkpoint.cpp b/src/share/backup/ob_archive_checkpoint.cpp index d92499935..88f95429d 100644 --- a/src/share/backup/ob_archive_checkpoint.cpp +++ b/src/share/backup/ob_archive_checkpoint.cpp @@ -369,12 +369,21 @@ int ObDestRoundCheckpointer::generate_one_piece_(const ObTenantArchiveRoundAttr // fill piece - piece.piece_info_.checkpoint_scn_ = MIN(piece.piece_info_.checkpoint_scn_, ls_piece.checkpoint_scn_); + bool last_piece = false; + if (OB_FAIL(ls_round.check_is_last_piece_for_deleted_ls(piece_id, last_piece))) { + LOG_WARN("failed to check is last piece for deleted ls", K(ret)); + } else if (last_piece) { + // If the ls is deleted, and this is the last piece. It should not + // affect the checkpoint_scn. + } else { + piece.piece_info_.checkpoint_scn_ = MIN(piece.piece_info_.checkpoint_scn_, ls_piece.checkpoint_scn_); + } + piece.piece_info_.max_scn_ = MAX(piece.piece_info_.max_scn_, ls_piece.checkpoint_scn_); piece.piece_info_.input_bytes_ += ls_piece.input_bytes_; piece.piece_info_.output_bytes_ += ls_piece.output_bytes_; - if (OB_FAIL(piece.piece_info_.set_path(new_round_info.path_))) { + if (FAILEDx(piece.piece_info_.set_path(new_round_info.path_))) { LOG_WARN("failed to set path", K(ret), K(piece), K(gen_ls_piece), K(new_round_info)); } else if (OB_FAIL(piece.ls_piece_list_.push_back(gen_ls_piece))) { LOG_WARN("failed to push backup ls piece", K(ret), K(piece), K(gen_ls_piece)); diff --git a/src/share/backup/ob_archive_struct.cpp b/src/share/backup/ob_archive_struct.cpp index d8fa715ae..92ba16dac 100644 --- a/src/share/backup/ob_archive_struct.cpp +++ b/src/share/backup/ob_archive_struct.cpp @@ -1084,6 +1084,22 @@ bool ObLSDestRoundSummary::is_valid() const return OB_INVALID_TENANT_ID != tenant_id_ && ls_id_.is_valid(); } +int ObLSDestRoundSummary::check_is_last_piece_for_deleted_ls(const int64_t piece_id, bool &last_piece) const +{ + int ret = OB_SUCCESS; + const int64_t biggest_piece_id = max_piece_id(); + if (!is_deleted_) { + last_piece = false; + } else if (piece_id > biggest_piece_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid piece id", K(ret), K(piece_id), KPC(this)); + } else { + last_piece = (piece_id == biggest_piece_id); + } + + return ret; +} + /** * ------------------------------ObDestRoundSummary--------------------- */ diff --git a/src/share/backup/ob_archive_struct.h b/src/share/backup/ob_archive_struct.h index 75bc23dac..6279d1919 100644 --- a/src/share/backup/ob_archive_struct.h +++ b/src/share/backup/ob_archive_struct.h @@ -872,6 +872,8 @@ struct ObLSDestRoundSummary int64_t get_piece_idx(const int64_t piece_id) const; int64_t min_piece_id() const; int64_t max_piece_id() const; + // Return true if ls is deleted and the piece_id is the biggest piece id. + int check_is_last_piece_for_deleted_ls(const int64_t piece_id, bool &last_piece) const; TO_STRING_KV(K_(tenant_id), K_(dest_id), K_(round_id), K_(ls_id), K_(is_deleted), K_(state), K_(start_scn), K_(checkpoint_scn), K_(piece_list)); diff --git a/src/share/backup/ob_backup_connectivity.cpp b/src/share/backup/ob_backup_connectivity.cpp index cf42fb9d1..1dc36eb9f 100644 --- a/src/share/backup/ob_backup_connectivity.cpp +++ b/src/share/backup/ob_backup_connectivity.cpp @@ -380,7 +380,6 @@ int ObBackupCheckFile::generate_format_desc_(const share::ObBackupDest &dest, sh LOG_WARN("failed to assign path", K(ret), K(dest)); } else { format_desc.tenant_id_ = tenant_id_; - // TODO: use real incarnation later. format_desc.incarnation_ = OB_START_INCARNATION; format_desc.cluster_id_ = GCONF.cluster_id; } diff --git a/src/share/backup/ob_backup_data_table_operator.cpp b/src/share/backup/ob_backup_data_table_operator.cpp old mode 100644 new mode 100755 index 13a265665..b507a0906 --- a/src/share/backup/ob_backup_data_table_operator.cpp +++ b/src/share/backup/ob_backup_data_table_operator.cpp @@ -18,6 +18,7 @@ #include "common/ob_smart_var.h" #include "share/config/ob_server_config.h" #include "lib/mysqlclient/ob_mysql_transaction.h" +#include "share/ob_share_util.h" namespace oceanbase { @@ -54,7 +55,7 @@ int ObBackupSetFileOperator::insert_backup_set_file(common::ObISQLClient &proxy, ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]error unexpected, invalid affected rows", K(ret), K(affected_rows), K(backup_set_desc)); } else { - FLOG_INFO("[DATA_BACKUP]insert one backup job", K(backup_set_desc), K(sql)); + LOG_INFO("[DATA_BACKUP]insert one backup job", K(backup_set_desc), K(sql)); } return ret; } @@ -132,14 +133,20 @@ int ObBackupSetFileOperator::fill_dml_with_backup_set_(const ObBackupSetFileDesc LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } else if (OB_FAIL(dml.add_column(OB_STR_META_TURN_ID, backup_set_desc.meta_turn_id_))) { LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } + } else if (OB_FAIL(dml.add_column(OB_STR_MINOR_TURN_ID, backup_set_desc.minor_turn_id_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_MAJOR_TURN_ID, backup_set_desc.major_turn_id_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_CONSISTENT_SCN, backup_set_desc.consistent_scn_.get_val_for_inner_table_field()))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } return ret; } int ObBackupSetFileOperator::get_backup_set_files( common::ObISQLClient &proxy, const uint64_t tenant_id, - share::ObTenantBackupSetInfosDesc &tenant_backup_set_infos) + ObIArray &tenant_backup_set_infos) { int ret = OB_SUCCESS; ObSqlString sql; @@ -156,7 +163,7 @@ int ObBackupSetFileOperator::get_backup_set_files( } else if (OB_ISNULL(result = res.get_result())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]result is null", K(ret), K(sql)); - } else if (OB_FAIL(parse_backup_set_info_result_(*result, tenant_backup_set_infos.backup_set_infos_))) { + } else if (OB_FAIL(parse_backup_set_info_result_(*result, tenant_backup_set_infos))) { LOG_WARN("[DATA_BACKUP]failed to parse result", K(ret)); } else { LOG_INFO("[DATA_BACKUP]success tenant backup set infos", K(tenant_backup_set_infos)); @@ -260,7 +267,7 @@ int ObBackupSetFileOperator::get_backup_set_file( } } } - FLOG_INFO("[DATA_BACKUP]get_backup_set_file", K(ret), K(sql), K(backup_set_desc)); + LOG_INFO("[DATA_BACKUP]get_backup_set_file", K(ret), K(sql), K(backup_set_desc)); return ret; } @@ -302,7 +309,7 @@ int ObBackupSetFileOperator::get_one_backup_set_file( } } } - FLOG_INFO("[DATA_BACKUP]get_backup_set_file", K(ret), K(sql), K(backup_set_desc)); + LOG_INFO("[DATA_BACKUP]get_backup_set_file", K(ret), K(sql), K(backup_set_desc)); return ret; } @@ -312,6 +319,7 @@ int ObBackupSetFileOperator::do_parse_backup_set_(ObMySQLResult &result, ObBacku int64_t real_length = 0; uint64_t min_restore_scn = 0; uint64_t start_replay_scn = 0; + uint64_t consistent_scn = 0; int64_t backup_compatible = 0; char backup_path[OB_MAX_BACKUP_DEST_LENGTH] = ""; char encryption_mode_str[OB_DEFAULT_STATUS_LENTH] = ""; @@ -345,6 +353,7 @@ int ObBackupSetFileOperator::do_parse_backup_set_(ObMySQLResult &result, ObBacku EXTRACT_UINT_FIELD_MYSQL(result, OB_STR_START_REPLAY_SCN, start_replay_scn, uint64_t); EXTRACT_INT_FIELD_MYSQL(result, OB_STR_DATA_TURN_ID, backup_set_desc.data_turn_id_, int64_t); EXTRACT_INT_FIELD_MYSQL(result, OB_STR_META_TURN_ID, backup_set_desc.meta_turn_id_, int64_t); + EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_BACKUP_ENCRYPTION_MODE, encryption_mode_str, OB_DEFAULT_STATUS_LENTH, real_length); EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_BACKUP_PASSWD, passwd, OB_MAX_PASSWORD_LENGTH, real_length); EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_PATH, backup_path, OB_MAX_BACKUP_DEST_LENGTH, real_length); @@ -353,7 +362,9 @@ int ObBackupSetFileOperator::do_parse_backup_set_(ObMySQLResult &result, ObBacku EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_FILE_STATUS, file_status_str, OB_DEFAULT_STATUS_LENTH, real_length); EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_STATUS, status_str, OB_DEFAULT_STATUS_LENTH, real_length); EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_BACKUP_PLUS_ARCHIVELOG, plus_archivelog_str, OB_DEFAULT_STATUS_LENTH, real_length); - + EXTRACT_UINT_FIELD_MYSQL(result, OB_STR_CONSISTENT_SCN, consistent_scn, uint64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_MINOR_TURN_ID, backup_set_desc.minor_turn_id_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_MAJOR_TURN_ID, backup_set_desc.major_turn_id_, int64_t); if (OB_FAIL(ret)) { } else if (OB_FAIL(backup_set_desc.backup_path_.assign(backup_path))) { @@ -376,6 +387,8 @@ int ObBackupSetFileOperator::do_parse_backup_set_(ObMySQLResult &result, ObBacku LOG_WARN("fail to set min restore scn", K(ret), K(min_restore_scn)); } else if (OB_FAIL(backup_set_desc.start_replay_scn_.convert_for_inner_table_field(start_replay_scn))) { LOG_WARN("fail to set start_replay_scn", K(ret), K(start_replay_scn)); + } else if (OB_FAIL(backup_set_desc.consistent_scn_.convert_for_inner_table_field(consistent_scn))) { + LOG_WARN("fail to set tablet snapshot scn", K(ret), K(consistent_scn)); } else { backup_set_desc.encryption_mode_ = ObBackupEncryptionMode::parse_str(encryption_mode_str); backup_set_desc.file_status_ = ObBackupFileStatus::get_status(file_status_str); @@ -406,7 +419,7 @@ int ObBackupSetFileOperator::update_backup_set_file( LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); } else if (affected_rows > 1) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql), K(backup_set_desc)); + LOG_WARN("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql), K(backup_set_desc)); } else { LOG_INFO("[DATA_BACKUP]update backup set", K(backup_set_desc)); } @@ -463,7 +476,7 @@ int ObBackupSetFileOperator::get_prev_backup_set_id( prev_full_backup_set_id = backup_set_desc.prev_full_backup_set_id_; prev_inc_backup_set_id = backup_set_desc.backup_set_id_; } - FLOG_INFO("[DATA_BACKUP]get prev backup set id", K(prev_full_backup_set_id), K(prev_inc_backup_set_id)); + LOG_INFO("[DATA_BACKUP]get prev backup set id", K(prev_full_backup_set_id), K(prev_inc_backup_set_id)); } } return ret; @@ -497,7 +510,7 @@ int ObBackupSetFileOperator::get_candidate_obsolete_backup_sets( } } } - FLOG_INFO("get_candidate_obsolete_backup_sets", K(ret), K(sql), K(backup_set_descs)); + LOG_INFO("get_candidate_obsolete_backup_sets", K(ret), K(sql), K(backup_set_descs)); return ret; } @@ -617,7 +630,7 @@ int ObBackupJobOperator::insert_job( ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]error unexpected, invalid affected rows", K(ret), K(affected_rows), K(job_attr)); } else { - FLOG_INFO("[DATA_BACKUP]insert one backup job", K(job_attr), K(sql)); + LOG_INFO("[DATA_BACKUP]insert one backup job", K(job_attr), K(sql)); } return ret; } @@ -796,7 +809,7 @@ int ObBackupJobOperator::cancel_jobs(common::ObISQLClient &proxy, const uint64_t LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); } else if (2 < affected_rows) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows, disallow more than 2 jobs at the same", K(ret), K(affected_rows), K(sql)); + LOG_WARN("[DATA_BACKUP]invalid affected_rows, disallow more than 2 jobs at the same", K(ret), K(affected_rows), K(sql)); } else { LOG_INFO("success cancel the backup jobs of tenant", K(ret), K(tenant_id)); } @@ -957,7 +970,6 @@ int ObBackupJobOperator::advance_job_status( ObSqlString sql; int64_t affected_rows = -1; ObDMLSqlSplicer dml; - const char *comment = OB_SUCCESS == result ? "" : common::ob_strerror(result); if (!next_status.is_valid() || !job_attr.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("[DATA_BACKUP]invalid status", K(ret), K(job_attr)); @@ -971,8 +983,6 @@ int ObBackupJobOperator::advance_job_status( LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } else if (OB_FAIL(dml.add_column(OB_STR_RESULT, result))) { LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_COMMENT, comment))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_JOB_TNAME, sql))) { LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); } else if (ObBackupStatus::Status::CANCELING != next_status.status_ @@ -982,7 +992,7 @@ int ObBackupJobOperator::advance_job_status( LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); } else if (1 != affected_rows) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql), K(next_status)); + LOG_WARN("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql), K(next_status)); } else { LOG_INFO("[DATA_BACKUP]advance status", K(job_attr), K(next_status)); } @@ -1036,10 +1046,36 @@ int ObBackupJobOperator::update_retry_count( LOG_WARN("failed to exec sql", K(ret), K(sql)); } else if (1 != affected_rows) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("invalid affected_rows", K(ret), K(affected_rows), K(sql), K(job_attr)); + LOG_WARN("invalid affected_rows", K(ret), K(affected_rows), K(sql), K(job_attr)); } return ret; } + +int ObBackupJobOperator::update_comment(common::ObISQLClient &proxy, const ObBackupJobAttr &job_attr) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = -1; + ObDMLSqlSplicer dml; + if (!job_attr.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[DATA_BACKUP]invalid status", K(ret), K(job_attr)); + } else if (OB_FAIL(dml.add_pk_column(OB_STR_JOB_ID, job_attr.job_id_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, job_attr.tenant_id_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_COMMENT, job_attr.comment_.ptr()))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_JOB_TNAME, sql))) { + LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); + } else if (OB_FAIL(proxy.write(get_exec_tenant_id(job_attr.tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); + } else { + LOG_INFO("[DATA_BACKUP]update comment", K(job_attr)); + } + return ret; +} + /* *-----------------------------------__all_tablet_to_ls---------------------------- */ @@ -1048,10 +1084,10 @@ int ObBackupJobOperator::update_retry_count( int ObBackupTabletToLSOperator::get_ls_and_tablet( common::ObISQLClient &proxy, const uint64_t tenant_id, + const share::SCN &snapshot, common::hash::ObHashMap> &tablet_to_ls) { int ret = OB_SUCCESS; - bool check_sys_variable = true; if (tenant_id == OB_INVALID_TENANT_ID) { ret = OB_INVALID_ARGUMENT; LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(tenant_id)); @@ -1061,10 +1097,10 @@ int ObBackupTabletToLSOperator::get_ls_and_tablet( ObArray tablet_ls_pairs; while(OB_SUCC(ret)) { tablet_ls_pairs.reset(); - if (OB_FAIL(ObTabletToLSTableOperator::range_get_tablet( - proxy, tenant_id, start_tablet_id, range_size, tablet_ls_pairs))) { + if (OB_FAIL(range_get_tablet_( + proxy, tenant_id, snapshot, start_tablet_id, range_size, tablet_ls_pairs))) { LOG_WARN("fail to range get tablet", K(ret), K(tenant_id), K(start_tablet_id), K(range_size)); - } else if (OB_FAIL(do_parse_tablet_ls_pairs_(tablet_ls_pairs, tablet_to_ls, start_tablet_id))) { + } else if (OB_FAIL(group_tablets_by_ls_(tablet_ls_pairs, tablet_to_ls, start_tablet_id))) { LOG_WARN("fail to do parse tablet ls pairs", K(ret)); } else if (tablet_ls_pairs.count() < range_size) { break; @@ -1074,7 +1110,59 @@ int ObBackupTabletToLSOperator::get_ls_and_tablet( return ret; } -int ObBackupTabletToLSOperator::do_parse_tablet_ls_pairs_(const ObIArray &tablet_ls_pairs, +int ObBackupTabletToLSOperator::range_get_tablet_(common::ObISQLClient &sql_proxy, const uint64_t tenant_id, + const share::SCN &snapshot, const oceanbase::common::ObTabletID &start_tablet_id, const int64_t range_size, + common::ObIArray &tablet_ls_pairs) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + if (OB_UNLIKELY(range_size <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(range_size)); + } else if (OB_FAIL(sql.append_fmt("SELECT * FROM %s as of snapshot %lu WHERE tablet_id > %lu ORDER BY tablet_id LIMIT %ld", + OB_ALL_TABLET_TO_LS_TNAME, snapshot.get_val_for_inner_table_field(), start_tablet_id.id(), range_size))) { + LOG_WARN("failed to assign sql", K(ret), K(snapshot), K(start_tablet_id), K(range_size)); + } else { + SMART_VAR(ObISQLClient::ReadResult, result) { + if (OB_FAIL(sql_proxy.read(result, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K(sql)); + } else { + common::sqlclient::ObMySQLResult &res = *result.get_result(); + while (OB_SUCC(ret) && OB_SUCC(res.next())) { + int64_t tablet_id = ObTabletID::INVALID_TABLET_ID; + int64_t ls_id = ObLSID::INVALID_LS_ID; + + EXTRACT_INT_FIELD_MYSQL(res, "tablet_id", tablet_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(res, "ls_id", ls_id, int64_t); + + if (FAILEDx(tablet_ls_pairs.push_back(ObTabletLSPair(ObTabletID(tablet_id), ObLSID(ls_id))))) { + LOG_WARN("fail to push back", KR(ret), K(tablet_id), K(ls_id)); + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + if (OB_SUCC(ret)) { + ret = OB_ERR_UNEXPECTED; + } + LOG_WARN("construct results failed", KR(ret), K(tablet_ls_pairs)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(tablet_ls_pairs.count() > range_size)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get too much tablets", KR(ret), K(sql), K(range_size), "tablets count", tablet_ls_pairs.count()); + } + } + } + return ret; +} + +int ObBackupTabletToLSOperator::group_tablets_by_ls_(const ObIArray &tablet_ls_pairs, common::hash::ObHashMap> &tablet_to_ls, ObTabletID &max_tablet_id) { int ret = OB_SUCCESS; @@ -1105,7 +1193,8 @@ int ObBackupTabletToLSOperator::get_ls_of_tablet( common::ObISQLClient &proxy, const uint64_t tenant_id, const ObTabletID &tablet_id, - ObLSID &ls_id) + ObLSID &ls_id, + int64_t &transfer_seq) { int ret = OB_SUCCESS; ls_id.reset(); @@ -1114,13 +1203,13 @@ int ObBackupTabletToLSOperator::get_ls_of_tablet( if (OB_INVALID_TENANT_ID == tenant_id || !tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(tenant_id), K(tablet_id)); - } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, OB_MAX_BACKUP_QUERY_TIMEOUT))) { + } else if (OB_FAIL(share::ObShareUtil::set_default_timeout_ctx(ctx, OB_MAX_BACKUP_QUERY_TIMEOUT))) { LOG_WARN("fail to set default timeout ctx", K(ret)); } else { HEAP_VAR(ObMySQLProxy::ReadResult, res) { ObMySQLResult *result = NULL; - if (OB_FAIL(sql.assign_fmt("select %s from %s where %s=%ld", - OB_STR_LS_ID, OB_ALL_TABLET_TO_LS_TNAME, OB_STR_TABLET_ID, tablet_id.id()))) { + if (OB_FAIL(sql.assign_fmt("select %s, %s from %s where %s=%ld", + OB_STR_LS_ID, OB_STR_TRANSFER_SEQ, OB_ALL_TABLET_TO_LS_TNAME, OB_STR_TABLET_ID, tablet_id.id()))) { LOG_WARN("[DATA_BACKUP]failed to append fmt", K(ret)); } else if (OB_FAIL(proxy.read(res, tenant_id, sql.ptr()))) { LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); @@ -1137,6 +1226,7 @@ int ObBackupTabletToLSOperator::get_ls_of_tablet( int64_t tmp_id = -1; EXTRACT_INT_FIELD_MYSQL(*result, OB_STR_LS_ID, tmp_id, int64_t); ls_id = tmp_id; + EXTRACT_INT_FIELD_MYSQL(*result, OB_STR_TRANSFER_SEQ, transfer_seq, int64_t); } } } @@ -1168,7 +1258,7 @@ int ObBackupTaskOperator::insert_backup_task( ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]error unexpected, invalid affected rows", K(ret), K(affected_rows), K(backup_set_task)); } else { - FLOG_INFO("[DATA_BACKUP]insert one backup set task", K(backup_set_task), K(sql)); + LOG_INFO("[DATA_BACKUP]insert one backup set task", K(backup_set_task), K(sql)); } return ret; } @@ -1212,47 +1302,19 @@ int ObBackupTaskOperator::fill_dml_with_backup_task_( LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } else if (OB_FAIL(dml.add_column(OB_STR_INCARNATION, backup_set_task.incarnation_id_))) { LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_MINOR_TURN_ID, backup_set_task.minor_turn_id_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_MAJOR_TURN_ID, backup_set_task.major_turn_id_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } return ret; } -int ObBackupTaskOperator::update_max_turn_id( - common::ObISQLClient &proxy, - const int64_t task_id, - const uint64_t tenant_id, - const int64_t turn_id) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = -1; - ObDMLSqlSplicer dml; - if (task_id <= 0 || tenant_id == OB_INVALID_TENANT_ID || turn_id <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(task_id), K(tenant_id), K(turn_id)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, tenant_id))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, task_id))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_DATA_TURN_ID, turn_id))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_TASK_TNAME, sql))) { - LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); - } else if (OB_FAIL(proxy.write(get_exec_tenant_id(tenant_id), sql.ptr(), affected_rows))) { - LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); - } else if (affected_rows != 1) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(sql)); - } else { - LOG_INFO("[DATA_BACKUP]success update turn id", K(sql)); - } - return ret; -} - - int ObBackupTaskOperator::get_backup_task( common::ObISQLClient &proxy, const int64_t job_id, const uint64_t tenant_id, + const bool for_update, ObBackupSetTaskAttr &set_task_attr) { int ret = OB_SUCCESS; @@ -1266,6 +1328,8 @@ int ObBackupTaskOperator::get_backup_task( if (OB_FAIL(sql.assign_fmt("select * from %s where %s=%ld and %s=%lu", OB_ALL_BACKUP_TASK_TNAME, OB_STR_TENANT_ID, tenant_id, OB_STR_JOB_ID, job_id))) { LOG_WARN("[DATA_BACKUP]failed to append fmt", K(ret)); + } else if (for_update && OB_FAIL(sql.append_fmt(" for update"))) { + LOG_WARN("[DATA_BACKUP]failed to append sql", K(ret)); } else if (OB_FAIL(proxy.read(res, get_exec_tenant_id(tenant_id), sql.ptr()))) { LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql), K(tenant_id)); } else if (nullptr == (result = res.get_result())) { @@ -1307,6 +1371,9 @@ int ObBackupTaskOperator::get_backup_task( EXTRACT_INT_FIELD_MYSQL(*result, OB_STR_INCARNATION, set_task_attr.incarnation_id_, int64_t); EXTRACT_STRBUF_FIELD_MYSQL(*result, OB_STR_STATUS, status_str, OB_INNER_TABLE_DEFAULT_KEY_LENTH, tmp_str_len); EXTRACT_STRBUF_FIELD_MYSQL(*result, OB_STR_PATH, backup_path_str, OB_MAX_BACKUP_DEST_LENGTH, tmp_str_len); + EXTRACT_INT_FIELD_MYSQL(*result, OB_STR_MINOR_TURN_ID, set_task_attr.minor_turn_id_, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, OB_STR_MAJOR_TURN_ID, set_task_attr.major_turn_id_, int64_t); + if (OB_FAIL(ret)) { } else if (OB_FAIL(set_task_attr.status_.set_status(status_str))) { LOG_WARN("[DATA_BACKUP]failed to set status", K(ret), K(set_task_attr.status_), K(sql)); @@ -1365,7 +1432,7 @@ int ObBackupTaskOperator::advance_task_status( LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); } else if (1 != affected_rows) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql), K(next_status)); + LOG_WARN("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql), K(next_status)); } else { LOG_INFO("[DATA_BACKUP]advance status", K(set_task_attr), K(next_status), K(sql)); } @@ -1441,38 +1508,45 @@ int ObBackupTaskOperator::update_stats( LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); } else if (affected_rows > 1) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(sql)); + LOG_WARN("[DATA_BACKUP]invalid affected_rows", K(ret), K(sql)); } else { LOG_INFO("[DATA_BACKUP]success update stats", K(sql)); } return ret; } -int ObBackupTaskOperator::update_meta_turn_id(common::ObISQLClient &proxy, const int64_t task_id, - const uint64_t tenant_id, const int64_t turn_id) +int ObBackupTaskOperator::update_turn_id(common::ObISQLClient &proxy, share::ObBackupStatus &backup_status, + const int64_t task_id, const uint64_t tenant_id, const int64_t turn_id) { int ret = OB_SUCCESS; ObSqlString sql; int64_t affected_rows = -1; ObDMLSqlSplicer dml; - if (task_id <= 0 || tenant_id == OB_INVALID_TENANT_ID || turn_id <= 0) { + if (task_id <= 0 || tenant_id == OB_INVALID_TENANT_ID || turn_id <= 0 || !backup_status.is_valid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(task_id), K(tenant_id), K(turn_id)); + LOG_WARN("invalid argument", K(ret), K(task_id), K(tenant_id), K(turn_id), K(backup_status)); } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, tenant_id))) { LOG_WARN("failed to add column", K(ret)); } else if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, task_id))) { LOG_WARN("failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_META_TURN_ID, turn_id))) { + } else if (backup_status == ObBackupStatus::BACKUP_USER_META + && OB_FAIL(dml.add_column(OB_STR_META_TURN_ID, turn_id))) { LOG_WARN("failed to add column", K(ret)); + } else if (backup_status == ObBackupStatus::BACKUP_DATA_MINOR + && OB_FAIL(dml.add_column(OB_STR_MINOR_TURN_ID, turn_id))) { + LOG_WARN("failed to add column", K(ret)); + } else if (backup_status == ObBackupStatus::BACKUP_DATA_MAJOR + && OB_FAIL(dml.add_column(OB_STR_MAJOR_TURN_ID, turn_id))) { + LOG_WARN("failed to add column", K(ret)); } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_TASK_TNAME, sql))) { LOG_WARN("failed to splice_update_sql", K(ret)); } else if (OB_FAIL(proxy.write(get_exec_tenant_id(tenant_id), sql.ptr(), affected_rows))) { LOG_WARN("failed to exec sql", K(ret), K(sql)); } else if (affected_rows != 1) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("invalid affected_rows", K(ret), K(sql)); + LOG_WARN("invalid affected_rows", K(ret), K(sql)); } else { - LOG_INFO("[DATA_BACKUP]success update meta turn id", K(sql)); + LOG_INFO("[DATA_BACKUP]success update turn id", K(sql)); } return ret; } @@ -1499,7 +1573,7 @@ int ObBackupTaskOperator::update_user_ls_start_scn(common::ObISQLClient &proxy, LOG_WARN("failed to exec sql", K(ret), K(sql)); } else if (affected_rows > 1) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("invalid affected_rows", K(ret), K(sql)); + LOG_WARN("invalid affected_rows", K(ret), K(sql)); } else { LOG_INFO("[DATA_BACKUP]success update start scn", K(sql)); } @@ -1509,87 +1583,6 @@ int ObBackupTaskOperator::update_user_ls_start_scn(common::ObISQLClient &proxy, *--------------------------__all_backup_ls_task--------------------------------- */ -int ObBackupLSTaskOperator::update_black_server( - common::ObISQLClient &proxy, - const int64_t task_id, - const uint64_t tenant_id, - const ObLSID &ls_id, - const ObString &black_servers) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = -1; - ObDMLSqlSplicer dml; - if (task_id <= 0 || tenant_id == OB_INVALID_TENANT_ID || !ls_id.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(task_id), K(tenant_id), K(ls_id)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, tenant_id))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, task_id))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_LS_ID, ls_id.id()))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_BLACK_LIST, black_servers.ptr()))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_LS_TASK_TNAME, sql))) { - LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); - } else if (OB_FAIL(proxy.write(get_exec_tenant_id(tenant_id), sql.ptr(), affected_rows))) { - LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); - } else if (affected_rows > 1) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(sql)); - } else { - LOG_INFO("[DATA_BACKUP]success update block servers", K(sql)); - } - return ret; -} - -int ObBackupLSTaskOperator::update_stats_( - common::ObISQLClient &proxy, - const int64_t task_id, - const uint64_t tenant_id, - const ObLSID &ls_id, - const ObBackupStats &stats) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = -1; - ObDMLSqlSplicer dml; - if (task_id <= 0 || tenant_id == OB_INVALID_TENANT_ID || !ls_id.is_valid() || !stats.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(task_id), K(tenant_id), K(ls_id), K(stats)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, tenant_id))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, task_id))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_LS_ID, ls_id.id()))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_OUTPUT_BYTES, stats.output_bytes_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_INPUT_BYTES, stats.input_bytes_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_TABLET_COUNT, stats.tablet_count_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_FINISH_TABLET_COUNT, stats.finish_tablet_count_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_MACRO_BLOCK_COUNT, stats.macro_block_count_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_FINISH_MACRO_BLOCK_COUNT, stats.finish_macro_block_count_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_EXTRA_BYTES, stats.extra_bytes_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_FILE_COUNT, stats.finish_file_count_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_LS_TASK_TNAME, sql))) { - LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); - } else if (OB_FAIL(proxy.write(get_exec_tenant_id(tenant_id), sql.ptr(), affected_rows))) { - LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); - } else { - LOG_INFO("[DATA_BACKUP]success update task type", K(sql)); - } - return ret; -} - int ObBackupLSTaskOperator::insert_ls_task( common::ObISQLClient &proxy, const ObBackupLSTaskAttr &ls_attr) @@ -1611,18 +1604,81 @@ int ObBackupLSTaskOperator::insert_ls_task( ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]error unexpected, invalid affected rows", K(ret), K(affected_rows), K(ls_attr)); } else { - FLOG_INFO("[DATA_BACKUP]insert one ls task", K(ls_attr), K(sql)); + LOG_INFO("[DATA_BACKUP]insert one ls task", K(ls_attr), K(sql)); } return ret; } +int ObBackupLSTaskOperator::report_ls_task(common::ObISQLClient &proxy, const ObBackupLSTaskAttr &ls_attr) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObSqlString sql; + ObDMLSqlSplicer dml; + if (!ls_attr.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[DATA_BACKUP]invalid argument", K(ls_attr)); + } else if (OB_FAIL(fill_dml_with_ls_task_(ls_attr, dml))) { + LOG_WARN("[DATA_BACKUP]failed to fill backup job", K(ret), K(ls_attr)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_LS_TASK_TNAME, sql))) { + LOG_WARN("[DATA_BACKUP]failed to splice update sql", K(ret), K(ls_attr)); + } else if (OB_FAIL(proxy.write(get_exec_tenant_id(ls_attr.tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("[DATA_BACKUP]fail to exec sql", K(ret), K(sql)); + } else { + LOG_INFO("[DATA_BACKUP]update one ls task", K(ls_attr), K(sql), K(affected_rows)); + } + return ret; +} + +int ObBackupLSTaskOperator::report_ls_task( + common::ObISQLClient &proxy, const ObBackupLSTaskAttr &ls_attr, const ObSqlString &extra_condition) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObSqlString sql; + ObDMLSqlSplicer dml; + if (!ls_attr.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[DATA_BACKUP]invalid argument", K(ls_attr)); + } else if (OB_FAIL(fill_dml_with_ls_task_(ls_attr, dml))) { + LOG_WARN("[DATA_BACKUP]failed to fill backup job", K(ret), K(ls_attr)); + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt(" %s", extra_condition.ptr()))) { + LOG_WARN("[DATA_BACKUP]failed to assign extra confition", K(ret), K(extra_condition)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_LS_TASK_TNAME, sql))) { + LOG_WARN("[DATA_BACKUP]failed to splice update sql", K(ret), K(ls_attr)); + } else if (OB_FAIL(proxy.write(get_exec_tenant_id(ls_attr.tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("[DATA_BACKUP]fail to exec sql", K(ret), K(sql)); + } else { + LOG_INFO("[DATA_BACKUP]update one ls task", K(ls_attr), K(sql), K(affected_rows)); + } + return ret; +} + + int ObBackupLSTaskOperator::fill_dml_with_ls_task_( const ObBackupLSTaskAttr &ls_attr, ObDMLSqlSplicer &dml) { int ret = OB_SUCCESS; - if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, ls_attr.task_id_))) { + + char server_ip[OB_MAX_SERVER_ADDR_SIZE] = ""; + char trace_id_str[OB_MAX_TRACE_ID_BUFFER_SIZE] = ""; + if (ls_attr.dst_.is_valid()) { + ls_attr.dst_.ip_to_string(server_ip, OB_MAX_SERVER_ADDR_SIZE); + } + + if (!ls_attr.task_trace_id_.is_invalid()) { + ls_attr.task_trace_id_.to_string(trace_id_str, OB_MAX_TRACE_ID_BUFFER_SIZE); + } + ObSqlString black_server_sql_string; + if (!ls_attr.black_servers_.empty()) { + if (OB_FAIL(ls_attr.get_black_server_str(ls_attr.black_servers_, black_server_sql_string))) { + LOG_WARN("failed to get black server str", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, ls_attr.task_id_))) { LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, ls_attr.tenant_id_))) { LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); @@ -1644,7 +1700,29 @@ int ObBackupLSTaskOperator::fill_dml_with_ls_task_( LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } else if (OB_FAIL(dml.add_column(OB_STR_DATE, ls_attr.backup_date_))) { LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_TASK_TRACE_ID, ""))) { + } else if (OB_FAIL(dml.add_column(OB_STR_BLACK_LIST, black_server_sql_string.empty() ? "" : black_server_sql_string.ptr()))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_SEVER_IP, server_ip))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_SERVER_PORT, ls_attr.dst_.get_port()))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_TASK_TRACE_ID, trace_id_str))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_OUTPUT_BYTES, ls_attr.stats_.output_bytes_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_INPUT_BYTES, ls_attr.stats_.input_bytes_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_TABLET_COUNT, ls_attr.stats_.tablet_count_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_FINISH_TABLET_COUNT, ls_attr.stats_.finish_tablet_count_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_MACRO_BLOCK_COUNT, ls_attr.stats_.macro_block_count_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_FINISH_MACRO_BLOCK_COUNT, ls_attr.stats_.finish_macro_block_count_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_EXTRA_BYTES, ls_attr.stats_.extra_bytes_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_FILE_COUNT, ls_attr.stats_.finish_file_count_))) { LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } else if (OB_FAIL(dml.add_column(OB_STR_START_TURN_ID, ls_attr.start_turn_id_))) { LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); @@ -1654,6 +1732,10 @@ int ObBackupLSTaskOperator::fill_dml_with_ls_task_( LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } else if (OB_FAIL(dml.add_column(OB_STR_RESULT, ls_attr.result_))) { LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_COMMENT, ls_attr.comment_.ptr()))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_uint64_column(OB_STR_MAX_TABLET_CHECKPOINT_SCN, ls_attr.max_tablet_checkpoint_scn_.get_val_for_inner_table_field()))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } return ret; } @@ -1796,7 +1878,9 @@ int ObBackupLSTaskOperator::fill_select_ls_task_sql_(ObSqlString &sql) LOG_WARN("[DATA_BACKUP]failed to append fmt", K(ret)); } else if (OB_FAIL(sql.append_fmt(", %s", OB_STR_SERVER_PORT))) { LOG_WARN("[DATA_BACKUP]failed to append fmt", K(ret)); - } else if (OB_FAIL(sql.append_fmt(", %s", OB_STR_FILE_COUNT))) { + } else if (OB_FAIL(sql.append_fmt(", %s", OB_STR_COMMENT))) { + LOG_WARN("[DATA_BACKUP]failed to append fmt", K(ret)); + } else if (OB_FAIL(sql.append_fmt(", %s", OB_STR_MAX_TABLET_CHECKPOINT_SCN))) { LOG_WARN("[DATA_BACKUP]failed to append fmt", K(ret)); } else if (OB_FAIL(sql.append_fmt(" from %s", OB_ALL_BACKUP_LS_TASK_TNAME))) { LOG_WARN("[DATA_BACKUP]failed to append fmt", K(ret)); @@ -1832,209 +1916,69 @@ int ObBackupLSTaskOperator::do_parse_ls_result_(ObMySQLResult &result, ObBackupL { int ret = OB_SUCCESS; - int64_t real_length = 0; - char status_str[OB_DEFAULT_STATUS_LENTH] = ""; - char backup_type_str[OB_SYS_TASK_TYPE_LENGTH] = ""; - char task_type_str[64] = ""; - char black_list_str[OB_INNER_TABLE_DEFAULT_VALUE_LENTH] = ""; - char trace_id_str[OB_MAX_TRACE_ID_BUFFER_SIZE] = ""; - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TASK_ID, ls_attr.task_id_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_JOB_ID, ls_attr.job_id_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TENANT_ID, ls_attr.tenant_id_, uint64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_BACKUP_SET_ID, ls_attr.backup_set_id_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_LS_ID, ls_attr.ls_id_, int64_t); - EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_BACKUP_TYPE, backup_type_str, OB_SYS_TASK_TYPE_LENGTH, real_length); - EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_STATUS, status_str, OB_DEFAULT_STATUS_LENTH, real_length); - EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_TASK_TYPE, task_type_str, 64, real_length); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_START_TS, ls_attr.start_ts_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_END_TS, ls_attr.end_ts_, int64_t); - EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_BLACK_LIST, black_list_str, OB_INNER_TABLE_DEFAULT_VALUE_LENTH, real_length); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_DATE, ls_attr.backup_date_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TURN_ID, ls_attr.turn_id_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_RETRY_ID, ls_attr.retry_id_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_RESULT, ls_attr.result_, int); - EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_TASK_TRACE_ID, trace_id_str, OB_MAX_TRACE_ID_BUFFER_SIZE, real_length); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_INPUT_BYTES, ls_attr.stats_.input_bytes_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_OUTPUT_BYTES, ls_attr.stats_.output_bytes_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TABLET_COUNT, ls_attr.stats_.tablet_count_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_FINISH_TABLET_COUNT, ls_attr.stats_.finish_tablet_count_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_MACRO_BLOCK_COUNT, ls_attr.stats_.macro_block_count_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_FINISH_MACRO_BLOCK_COUNT, ls_attr.stats_.finish_macro_block_count_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_EXTRA_BYTES, ls_attr.stats_.extra_bytes_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_START_TURN_ID, ls_attr.start_turn_id_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_FILE_COUNT, ls_attr.stats_.finish_file_count_, int64_t); + HEAP_VARS_2((char[OB_INNER_TABLE_DEFAULT_VALUE_LENTH], black_list_str), (char[MAX_TABLE_COMMENT_LENGTH], comment_str)) { + int64_t real_length = 0; + char status_str[OB_DEFAULT_STATUS_LENTH] = ""; + char backup_type_str[OB_SYS_TASK_TYPE_LENGTH] = ""; + char task_type_str[64] = ""; + char trace_id_str[OB_MAX_TRACE_ID_BUFFER_SIZE] = ""; + uint64_t max_tablet_checkpoint_scn = 0; - char server_str[OB_MAX_SERVER_ADDR_SIZE] = { 0 }; - int64_t port = 0; - EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_SEVER_IP, server_str, OB_MAX_SERVER_ADDR_SIZE, real_length); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_SERVER_PORT, port, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TASK_ID, ls_attr.task_id_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_JOB_ID, ls_attr.job_id_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TENANT_ID, ls_attr.tenant_id_, uint64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_BACKUP_SET_ID, ls_attr.backup_set_id_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_LS_ID, ls_attr.ls_id_, int64_t); + EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_BACKUP_TYPE, backup_type_str, OB_SYS_TASK_TYPE_LENGTH, real_length); + EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_STATUS, status_str, OB_DEFAULT_STATUS_LENTH, real_length); + EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_TASK_TYPE, task_type_str, 64, real_length); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_START_TS, ls_attr.start_ts_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_END_TS, ls_attr.end_ts_, int64_t); + EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_BLACK_LIST, black_list_str, OB_INNER_TABLE_DEFAULT_VALUE_LENTH, real_length); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_DATE, ls_attr.backup_date_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TURN_ID, ls_attr.turn_id_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_RETRY_ID, ls_attr.retry_id_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_RESULT, ls_attr.result_, int); + EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_TASK_TRACE_ID, trace_id_str, OB_MAX_TRACE_ID_BUFFER_SIZE, real_length); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_INPUT_BYTES, ls_attr.stats_.input_bytes_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_OUTPUT_BYTES, ls_attr.stats_.output_bytes_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TABLET_COUNT, ls_attr.stats_.tablet_count_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_FINISH_TABLET_COUNT, ls_attr.stats_.finish_tablet_count_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_MACRO_BLOCK_COUNT, ls_attr.stats_.macro_block_count_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_FINISH_MACRO_BLOCK_COUNT, ls_attr.stats_.finish_macro_block_count_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_EXTRA_BYTES, ls_attr.stats_.extra_bytes_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_START_TURN_ID, ls_attr.start_turn_id_, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_FILE_COUNT, ls_attr.stats_.finish_file_count_, int64_t); + EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_COMMENT, comment_str, MAX_TABLE_COMMENT_LENGTH, real_length); + EXTRACT_UINT_FIELD_MYSQL(result, OB_STR_MAX_TABLET_CHECKPOINT_SCN, max_tablet_checkpoint_scn, uint64_t); - if (OB_FAIL(ret)) { - } else if (OB_FAIL(ls_attr.status_.set_status(status_str))) { - LOG_WARN("[DATA_BACKUP]failed to set status", K(ret), K(status_str)); - } else if (OB_FAIL(ls_attr.backup_type_.set_backup_type(backup_type_str))) { - LOG_WARN("[DATA_BACKUP]failed to set backup_type", K(ret), K(backup_type_str)); - } else if (OB_FAIL(ls_attr.task_type_.set_type(task_type_str))) { - LOG_WARN("[DATA_BACKUP]failed to set task type", K(ret), K(task_type_str)); - } else if (OB_FAIL(ls_attr.set_black_servers(black_list_str))) { - LOG_WARN("[DATA_BACKUP]failed to parse black list str", K(ret)); - } else if (strcmp(trace_id_str, "") != 0 && OB_FAIL(ls_attr.task_trace_id_.set(trace_id_str))) { - LOG_WARN("[DATA_BACKUP]failed to set task trace id", K(ret), K(trace_id_str)); - } else if (!ls_attr.dst_.set_ip_addr(server_str, static_cast(port))) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("fail to set server ip and port", K(ret), K(server_str), K(port)); - } else { - LOG_INFO("[DATA_BACKUP]success to read ls attr", K(ls_attr)); - } - return ret; -} + char server_str[OB_MAX_SERVER_ADDR_SIZE] = { 0 }; + int64_t port = 0; + EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_SEVER_IP, server_str, OB_MAX_SERVER_ADDR_SIZE, real_length); + EXTRACT_INT_FIELD_MYSQL(result, OB_STR_SERVER_PORT, port, int64_t); -int ObBackupLSTaskOperator::advance_status( - common::ObISQLClient &proxy, - const ObBackupLSTaskAttr &ls_attr, - const ObBackupTaskStatus &next_status, - const int result, - const int64_t end_ts) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = -1; - ObDMLSqlSplicer dml; - const char *comment = OB_SUCCESS == result ? "" : common::ob_strerror(result); - if (!next_status.is_valid() || !ls_attr.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid status", K(ret), K(ls_attr), K(next_status)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, ls_attr.tenant_id_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, ls_attr.task_id_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_LS_ID, ls_attr.ls_id_.id()))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_STATUS, next_status.get_str()))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_RESULT, result))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_END_TS, end_ts))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_COMMENT, comment))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s='%s'", OB_STR_STATUS, ls_attr.status_.get_str()))) { - LOG_WARN("[DATA_BACKUP]failed to get_extra_condition", K(ret)); - } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_LS_TASK_TNAME, sql))) { - LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); - } else if (OB_FAIL(proxy.write(get_exec_tenant_id(ls_attr.tenant_id_), sql.ptr(), affected_rows))) { - LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); - } else if (1 != affected_rows) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql), K(ls_attr), K(next_status)); - } else { - LOG_INFO("[DATA_BACKUP]advance status", K(ls_attr), K(next_status), K(sql)); - } - return ret; -} - -int ObBackupLSTaskOperator::redo_ls_task( - common::ObISQLClient &proxy, - const ObBackupLSTaskAttr &ls_attr, - const int64_t start_turn_id, - const int64_t turn_id, - const int64_t retry_id) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = -1; - ObDMLSqlSplicer dml; - const char *empty_str = ""; - if (!ls_attr.is_valid() || start_turn_id <= 0 || turn_id <= 0 || retry_id < 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(ls_attr), K(start_turn_id), K(turn_id), K(retry_id)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, ls_attr.task_id_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, ls_attr.tenant_id_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_LS_ID, ls_attr.ls_id_.id()))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_STATUS, "INIT"))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_RESULT, OB_SUCCESS))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_SEVER_IP, empty_str))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_SERVER_PORT, 0))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_TASK_TRACE_ID, empty_str))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_COMMENT, empty_str))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_START_TURN_ID, start_turn_id))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_TURN_ID, turn_id))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_RETRY_ID, retry_id))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s='%s'", OB_STR_STATUS, ls_attr.status_.get_str()))) { - LOG_WARN("[DATA_BACKUP]failed to assign extra condition", K(ret)); - } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_LS_TASK_TNAME, sql))) { - LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); - } else if (OB_FAIL(proxy.write(get_exec_tenant_id(ls_attr.tenant_id_), sql.ptr(), affected_rows))) { - LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); - } else if (1 != affected_rows) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql), K(ls_attr)); - } else { - LOG_INFO("[DATA_BACKUP]rollback status", K(ls_attr)); - } - return ret; -} - -int ObBackupLSTaskOperator::update_task_type( - common::ObISQLClient &proxy, - const ObBackupLSTaskAttr &ls_attr, - const ObBackupDataTaskType &type) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = -1; - ObDMLSqlSplicer dml; - const char *empty_str = ""; - int64_t default_turn_id = 1; - if (!ls_attr.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(ls_attr)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, ls_attr.tenant_id_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, ls_attr.task_id_))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_pk_column(OB_STR_LS_ID, ls_attr.ls_id_.id()))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_TASK_TYPE, type.get_str()))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_STATUS, "INIT"))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_RESULT, OB_SUCCESS))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_SEVER_IP, empty_str))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_SERVER_PORT, 0))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_TASK_TRACE_ID, empty_str))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_COMMENT, empty_str))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.add_column(OB_STR_RETRY_ID, 0))) { - LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (!type.is_backup_meta() && OB_FAIL(dml.add_column(OB_STR_TURN_ID, default_turn_id))) { - LOG_WARN("failed to add column", K(ret)); - } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_LS_TASK_TNAME, sql))) { - LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); - } else if (OB_FAIL(proxy.write(get_exec_tenant_id(ls_attr.tenant_id_), sql.ptr(), affected_rows))) { - LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); - } else if (affected_rows != 1) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(sql)); - } else { - LOG_INFO("[DATA_BACKUP]success update task type", K(sql)); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ls_attr.status_.set_status(status_str))) { + LOG_WARN("[DATA_BACKUP]failed to set status", K(ret), K(status_str)); + } else if (OB_FAIL(ls_attr.backup_type_.set_backup_type(backup_type_str))) { + LOG_WARN("[DATA_BACKUP]failed to set backup_type", K(ret), K(backup_type_str)); + } else if (OB_FAIL(ls_attr.task_type_.set_type(task_type_str))) { + LOG_WARN("[DATA_BACKUP]failed to set task type", K(ret), K(task_type_str)); + } else if (OB_FAIL(ls_attr.set_black_servers(black_list_str))) { + LOG_WARN("[DATA_BACKUP]failed to parse black list str", K(ret)); + } else if (strcmp(trace_id_str, "") != 0 && OB_FAIL(ls_attr.task_trace_id_.set(trace_id_str))) { + LOG_WARN("[DATA_BACKUP]failed to set task trace id", K(ret), K(trace_id_str)); + } else if (!ls_attr.dst_.set_ip_addr(server_str, static_cast(port))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fail to set server ip and port", K(ret), K(server_str), K(port)); + } else if (OB_FAIL(ls_attr.comment_.assign(comment_str))) { + LOG_WARN("failed to assign comment str", K(ret)); + } else if (OB_FAIL(ls_attr.max_tablet_checkpoint_scn_.convert_for_inner_table_field(max_tablet_checkpoint_scn))) { + LOG_WARN("fail to set max tablet checkpoint scn", K(ret), K(max_tablet_checkpoint_scn)); + } else { + LOG_INFO("[DATA_BACKUP]success to read ls attr", K(ls_attr)); + } } return ret; } @@ -2042,8 +1986,10 @@ int ObBackupLSTaskOperator::update_task_type( int ObBackupLSTaskOperator::update_dst_and_status( common::ObISQLClient &proxy, const int64_t task_id, - const uint64_t tenant_id, - const ObLSID &ls_id, + const uint64_t tenant_id, + const ObLSID &ls_id, + const int64_t turn_id, + const int64_t retry_id, share::ObTaskId task_trace_id, common::ObAddr &dst) { @@ -2074,7 +2020,8 @@ int ObBackupLSTaskOperator::update_dst_and_status( LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); } else if (OB_FAIL(dml.add_column(OB_STR_TASK_TRACE_ID, trace_id_str))) { LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); - } else if (OB_FAIL(dml.get_extra_condition().assign("status='PENDING'"))) { + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt( + "status='PENDING' and %s = %ld and %s = %ld", OB_STR_TURN_ID, turn_id, OB_STR_RETRY_ID, retry_id))) { LOG_WARN("[DATA_BACKUP]failed to assign extra condition", K(ret)); } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_LS_TASK_TNAME, sql))) { LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); @@ -2084,7 +2031,53 @@ int ObBackupLSTaskOperator::update_dst_and_status( ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql)); } else { - FLOG_INFO("[DATA_BACKUP]success update dst and status", K(sql)); + LOG_INFO("[DATA_BACKUP]success update dst and status", K(sql)); + } + return ret; +} + +int ObBackupLSTaskOperator::update_stats_( + common::ObISQLClient &proxy, + const int64_t task_id, + const uint64_t tenant_id, + const ObLSID &ls_id, + const ObBackupStats &stats) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = -1; + ObDMLSqlSplicer dml; + if (task_id <= 0 || tenant_id == OB_INVALID_TENANT_ID || !ls_id.is_valid() || !stats.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(task_id), K(tenant_id), K(ls_id), K(stats)); + } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, tenant_id))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, task_id))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_pk_column(OB_STR_LS_ID, ls_id.id()))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_OUTPUT_BYTES, stats.output_bytes_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_INPUT_BYTES, stats.input_bytes_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_TABLET_COUNT, stats.tablet_count_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_FINISH_TABLET_COUNT, stats.finish_tablet_count_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_MACRO_BLOCK_COUNT, stats.macro_block_count_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_FINISH_MACRO_BLOCK_COUNT, stats.finish_macro_block_count_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_EXTRA_BYTES, stats.extra_bytes_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_column(OB_STR_FILE_COUNT, stats.finish_file_count_))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_LS_TASK_TNAME, sql))) { + LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); + } else if (OB_FAIL(proxy.write(get_exec_tenant_id(tenant_id), sql.ptr(), affected_rows))) { + LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); + } else { + LOG_INFO("[DATA_BACKUP]success update task type", K(sql)); } return ret; } @@ -2100,7 +2093,7 @@ int ObBackupLSTaskOperator::insert_build_index_task( } else if (OB_FAIL(insert_ls_task(proxy, build_index_attr))) { LOG_WARN("[DATA_BACKUP]failed to insert build index task", K(ret), K(build_index_attr)); } else { - FLOG_INFO("[DATA_BACKUP]insert build index task succ", K(build_index_attr)); + LOG_INFO("[DATA_BACKUP]insert build index task succ", K(build_index_attr)); } return ret; } @@ -2122,7 +2115,7 @@ int ObBackupLSTaskOperator::delete_build_index_task( LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); } else if (1 != affected_rows) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql)); + LOG_WARN("[DATA_BACKUP]invalid affected_rows", K(ret), K(affected_rows), K(sql)); } return ret; } @@ -2174,6 +2167,38 @@ int ObBackupLSTaskOperator::delete_ls_task_without_sys(common::ObISQLClient &pro return ret; } +int ObBackupLSTaskOperator::update_max_tablet_checkpoint_scn( + common::ObISQLClient &proxy, + const int64_t task_id, + const uint64_t tenant_id, + const ObLSID &ls_id, + const SCN &max_tablet_checkpoint_scn) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = -1; + ObDMLSqlSplicer dml; + if (task_id <= 0 || tenant_id == OB_INVALID_TENANT_ID || !ls_id.is_valid() || !max_tablet_checkpoint_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(task_id), K(tenant_id), K(ls_id), K(max_tablet_checkpoint_scn)); + } else if (OB_FAIL(dml.add_pk_column(OB_STR_TENANT_ID, tenant_id))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_pk_column(OB_STR_TASK_ID, task_id))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_pk_column(OB_STR_LS_ID, ls_id.id()))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.add_uint64_column(OB_STR_MAX_TABLET_CHECKPOINT_SCN, max_tablet_checkpoint_scn.get_val_for_inner_table_field()))) { + LOG_WARN("[DATA_BACKUP]failed to add column", K(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_BACKUP_LS_TASK_TNAME, sql))) { + LOG_WARN("[DATA_BACKUP]failed to splice_update_sql", K(ret)); + } else if (OB_FAIL(proxy.write(get_exec_tenant_id(tenant_id), sql.ptr(), affected_rows))) { + LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); + } else { + LOG_INFO("[DATA_BACKUP]success update max tablet checkpoint scn", K(task_id), K(tenant_id), K(ls_id), K(max_tablet_checkpoint_scn)); + } + return ret; +} + /* *--------------------------__all_backup_skipped_tablet------------------------------ @@ -2184,8 +2209,8 @@ int ObBackupSkippedTabletOperator::get_skip_tablet( const bool need_lock, const uint64_t tenant_id, const int64_t task_id, - const share::ObBackupSkippedType &skipped_type, - ObIArray &tablet_attrs) + const share::ObBackupSkippedType skipped_type, + common::hash::ObHashSet &skip_tablets) { int ret = OB_SUCCESS; ObSqlString sql; @@ -2208,7 +2233,7 @@ int ObBackupSkippedTabletOperator::get_skip_tablet( } else if (OB_ISNULL(result = res.get_result())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[DATA_BACKUP]result is null", K(ret), K(sql)); - } else if (OB_FAIL(parse_skip_tablet_result_(*result, tablet_attrs))) { + } else if (OB_FAIL(parse_skip_tablet_result_(*result, skip_tablets))) { LOG_WARN("[DATA_BACKUP]failed to parse result", K(ret)); } } @@ -2243,7 +2268,7 @@ int ObBackupSkippedTabletOperator::fill_select_skip_tablet_sql_(ObSqlString &sql int ObBackupSkippedTabletOperator::parse_skip_tablet_result_( sqlclient::ObMySQLResult &result, - ObIArray &tablet_attrs) + common::hash::ObHashSet &skip_tablets) { int ret = OB_SUCCESS; // traverse each returned row @@ -2258,7 +2283,7 @@ int ObBackupSkippedTabletOperator::parse_skip_tablet_result_( } } else if (OB_FAIL(do_parse_skip_tablet_result_(result, tablet_attr))) { LOG_WARN("[DATA_BACKUP]failed to parse tablet result", K(ret)); - } else if (OB_FAIL(tablet_attrs.push_back(tablet_attr))) { + } else if (OB_FAIL(skip_tablets.set_refactored(tablet_attr, 1/*cover exist*/))) { LOG_WARN("[DATA_BACKUP]failed to push back tablet attr", K(ret)); } } @@ -2272,18 +2297,10 @@ int ObBackupSkippedTabletOperator::do_parse_skip_tablet_result_( int ret = OB_SUCCESS; int64_t real_length = 0; int64_t tablet_id = -1; - int64_t ls_id = -1; char skipped_type_str[OB_INNER_TABLE_DEFAULT_VALUE_LENTH] = ""; - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TENANT_ID, tablet_attr.tenant_id_, uint64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TASK_ID, tablet_attr.task_id_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TURN_ID, tablet_attr.turn_id_, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_RETRY_ID, tablet_attr.retry_id_, int64_t); EXTRACT_INT_FIELD_MYSQL(result, OB_STR_TABLET_ID, tablet_id, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_LS_ID, ls_id, int64_t); - EXTRACT_INT_FIELD_MYSQL(result, OB_STR_BACKUP_SET_ID, tablet_attr.backup_set_id_, int64_t); EXTRACT_STRBUF_FIELD_MYSQL(result, OB_STR_BACKUP_SKIPPED_TYPE, skipped_type_str, OB_INNER_TABLE_DEFAULT_VALUE_LENTH, real_length); tablet_attr.tablet_id_ = tablet_id; - tablet_attr.ls_id_ = ls_id; if (OB_FAIL(ret)) { } else if (OB_FAIL(tablet_attr.skipped_type_.parse_from_str(skipped_type_str))) { LOG_WARN("failed to parse from str", K(ret), K(skipped_type_str)); @@ -2294,8 +2311,7 @@ int ObBackupSkippedTabletOperator::do_parse_skip_tablet_result_( int ObBackupSkippedTabletOperator::move_skip_tablet_to_his( common::ObISQLClient &proxy, const uint64_t tenant_id, - const int64_t task_id, - const share::ObBackupSkippedType &skipped_type) + const int64_t task_id) { int ret = OB_SUCCESS; ObSqlString sql; @@ -2304,18 +2320,16 @@ int ObBackupSkippedTabletOperator::move_skip_tablet_to_his( ret = OB_INVALID_ARGUMENT; LOG_WARN("[DATA_BACKUP]invalid argument", K(ret), K(tenant_id), K(task_id)); } else if (OB_FAIL(sql.assign_fmt( - "insert into %s select * from %s where %s=%lu and %s=%lu and %s='%s'", + "insert into %s select * from %s where %s=%lu and %s=%lu", OB_ALL_BACKUP_SKIPPED_TABLET_HISTORY_TNAME, OB_ALL_BACKUP_SKIPPED_TABLET_TNAME, - OB_STR_TENANT_ID, tenant_id, OB_STR_TASK_ID, task_id, - OB_STR_BACKUP_SKIPPED_TYPE, skipped_type.str()))) { + OB_STR_TENANT_ID, tenant_id, OB_STR_TASK_ID, task_id))) { LOG_WARN("[DATA_BACKUP]failed to init sql", K(ret)); } else if (OB_FAIL(proxy.write(get_exec_tenant_id(tenant_id), sql.ptr(), affected_rows))) { LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); } else if (OB_FALSE_IT(sql.reset())) { } else if (OB_FAIL(sql.assign_fmt( - "delete from %s where %s=%lu and %s=%lu and %s='%s'", - OB_ALL_BACKUP_SKIPPED_TABLET_TNAME, OB_STR_TENANT_ID, tenant_id, OB_STR_TASK_ID, task_id, - OB_STR_BACKUP_SKIPPED_TYPE, skipped_type.str()))) { + "delete from %s where %s=%lu and %s=%lu", + OB_ALL_BACKUP_SKIPPED_TABLET_TNAME, OB_STR_TENANT_ID, tenant_id, OB_STR_TASK_ID, task_id))) { LOG_WARN("[DATA_BACKUP]failed to init sql", K(ret)); } else if (OB_FAIL(proxy.write(get_exec_tenant_id(tenant_id), sql.ptr(), affected_rows))) { LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); @@ -2350,7 +2364,7 @@ int ObBackupLSTaskInfoOperator::update_ls_task_info_final( LOG_WARN("[DATA_BACKUP]failed to exec sql", K(ret), K(sql)); } else if (affected_rows > 2) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[DATA_BACKUP]invalid affected_rows", K(ret), K(sql), K(affected_rows)); + LOG_WARN("[DATA_BACKUP]invalid affected_rows", K(ret), K(sql), K(affected_rows)); } else { LOG_INFO("[DATA_BACKUP]success update ls task info to final", K(sql)); } @@ -2469,7 +2483,7 @@ int ObBackupLSTaskInfoOperator::move_ls_task_info_to_his( LOG_INFO("[DATA_BACKUP]succeed move backup ls task info to history table", K(tenant_id), K(task_id)); } return ret; -} +} /* *-----------------------__all_tenant_backup_info---------------------- @@ -2613,6 +2627,7 @@ int ObLSBackupInfoOperator::set_cluster_version(common::ObISQLClient &trans, con } return ret; } + int ObLSBackupInfoOperator::get_cluster_version(common::ObISQLClient &trans, const uint64_t tenant_id, uint64_t &cluster_version) { int ret = OB_SUCCESS; @@ -2704,7 +2719,7 @@ int ObLSBackupInfoOperator::insert_item_with_update( ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected affected rows", K(ret), K(affected_rows)); } else { - FLOG_INFO("execute sql success", K(sql)); + LOG_INFO("execute sql success", K(sql)); } return ret; } @@ -2732,7 +2747,10 @@ int ObLSBackupInfoOperator::set_item_value(Value &dst_value, int64_t src_value) int ObLSBackupInfoOperator::set_item_value(Value &dst_value, uint64_t src_value) { int ret = OB_SUCCESS; - if (0 == src_value) { + if (src_value < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("backup info set value get invalid argument", K(ret), K(src_value)); + } else if (0 == src_value) { if (OB_FAIL(set_item_value(dst_value, ""))) { LOG_WARN("failed to set value", K(ret), K(src_value)); } diff --git a/src/share/backup/ob_backup_data_table_operator.h b/src/share/backup/ob_backup_data_table_operator.h old mode 100644 new mode 100755 index c1aa44942..76f2fa952 --- a/src/share/backup/ob_backup_data_table_operator.h +++ b/src/share/backup/ob_backup_data_table_operator.h @@ -13,7 +13,6 @@ #ifndef OCEANBASE_SHARE_OB_BACKUP_DATA_TABLE_OPERATOR_H_ #define OCEANBASE_SHARE_OB_BACKUP_DATA_TABLE_OPERATOR_H_ -#include "ob_backup_data_store.h" #include "lib/mysqlclient/ob_mysql_proxy.h" #include "share/ob_dml_sql_splicer.h" #include "lib/container/ob_iarray.h" @@ -35,24 +34,26 @@ protected: class ObBackupTabletToLSOperator { public: - static int get_ls_and_tablet(common::ObISQLClient &proxy, const uint64_t tenant_id, + static int get_ls_and_tablet(common::ObISQLClient &proxy, const uint64_t tenant_id, const share::SCN &snapshot, common::hash::ObHashMap> &tablet_to_ls); - static int get_ls_of_tablet(common::ObISQLClient &proxy, const uint64_t tenant_id, const ObTabletID &tablet_id, ObLSID &ls_id); + static int get_ls_of_tablet(common::ObISQLClient &proxy, const uint64_t tenant_id, const ObTabletID &tablet_id, ObLSID &ls_id, int64_t &transfer_seq); private: - static int do_parse_tablet_ls_pairs_(const ObIArray &tablet_ls_pairs, + static int group_tablets_by_ls_(const ObIArray &tablet_ls_pairs, common::hash::ObHashMap> &tablet_to_ls, ObTabletID &max_tablet_id); + static int range_get_tablet_(common::ObISQLClient &sql_proxy, const uint64_t tenant_id, const share::SCN &snapshot, + const oceanbase::common::ObTabletID &start_tablet_id, const int64_t range_size, common::ObIArray &tablet_ls_pairs); }; class ObBackupSkippedTabletOperator : public ObBackupBaseTableOperator { public: static int get_skip_tablet(common::ObISQLClient &proxy, const bool need_lock, const uint64_t tenant_id, - const int64_t task_id, const share::ObBackupSkippedType &skipped_type, ObIArray &tablet_attrs); - static int move_skip_tablet_to_his(common::ObISQLClient &proxy, const uint64_t tenant_id, const int64_t task_id, - const share::ObBackupSkippedType &skipped_type); + const int64_t task_id, const share::ObBackupSkippedType skipped_type, + common::hash::ObHashSet &skip_tablets); + static int move_skip_tablet_to_his(common::ObISQLClient &proxy, const uint64_t tenant_id, const int64_t task_id); private: static int fill_select_skip_tablet_sql_(ObSqlString &sql); - static int parse_skip_tablet_result_(sqlclient::ObMySQLResult &result, ObIArray &tablet_attrs); + static int parse_skip_tablet_result_(sqlclient::ObMySQLResult &result, common::hash::ObHashSet &skip_tablets); static int do_parse_skip_tablet_result_(sqlclient::ObMySQLResult &result, ObBackupSkipTabletAttr &backup_set_desc); }; @@ -60,7 +61,7 @@ class ObBackupSetFileOperator : public ObBackupBaseTableOperator { public: static int insert_backup_set_file(common::ObISQLClient &proxy, const ObBackupSetFileDesc &backup_set_desc); - static int get_backup_set_files(common::ObISQLClient &proxy, const uint64_t tenant_id, share::ObTenantBackupSetInfosDesc &tenant_backup_set_infos); + static int get_backup_set_files(common::ObISQLClient &proxy, const uint64_t tenant_id, ObIArray &tenant_backup_set_infos); static int get_backup_set_files_specified_dest(common::ObISQLClient &proxy, const uint64_t tenant_id, const int64_t dest_id, ObIArray &backup_set_infos); static int get_backup_set_file(common::ObISQLClient &proxy, bool need_lock, const int64_t backup_set_id_, const int64_t incarnation, const uint64_t teannt_id, const int64_t dest_id, ObBackupSetFileDesc &backup_set_desc); @@ -111,6 +112,7 @@ public: const ObBackupStatus &next_status, const int result = OB_SUCCESS, const int64_t end_ts = 0); static int move_job_to_his(common::ObISQLClient &proxy, const uint64_t tenant_id, const int64_t job_id); static int update_retry_count(common::ObISQLClient &proxy, const ObBackupJobAttr &job_attr); + static int update_comment(common::ObISQLClient &proxy, const ObBackupJobAttr &job_attr); private: static int fill_dml_with_job_(const ObBackupJobAttr &job_attr, ObDMLSqlSplicer &dml); static int fill_select_job_sql_(ObSqlString &sql); @@ -123,17 +125,15 @@ class ObBackupTaskOperator : public ObBackupBaseTableOperator { public: static int insert_backup_task(common::ObISQLClient &proxy, const ObBackupSetTaskAttr &backup_set_task); - static int update_max_turn_id(common::ObISQLClient &proxy, const int64_t task_id, const uint64_t tenant_id, - const int64_t turn_id); + static int update_turn_id(common::ObISQLClient &proxy, share::ObBackupStatus &backup_status, const int64_t task_id, + const uint64_t tenant_id, const int64_t turn_id); static int get_backup_task(common::ObISQLClient &proxy, const int64_t job_id, const uint64_t tenant_id, - ObBackupSetTaskAttr &set_task_attr); + const bool for_update, ObBackupSetTaskAttr &set_task_attr); static int advance_task_status(common::ObISQLClient &proxy, const ObBackupSetTaskAttr &set_task_attr, const ObBackupStatus &next_status, const int result, const SCN &end_scn, const int64_t end_ts); static int move_task_to_his(common::ObISQLClient &proxy, const uint64_t tenant_id, const int64_t job_id); static int update_stats(common::ObISQLClient &proxy, const int64_t task_id, const uint64_t tenant_id, const ObBackupStats &stats); - static int update_meta_turn_id(common::ObISQLClient &proxy, const int64_t task_id, const uint64_t tenant_id, - const int64_t turn_id); static int update_user_ls_start_scn(common::ObISQLClient &proxy, const int64_t task_id, const uint64_t tenant_id, const SCN &scn); private: @@ -144,25 +144,22 @@ class ObBackupLSTaskOperator : public ObBackupBaseTableOperator { public: static int insert_ls_task(common::ObISQLClient &proxy, const ObBackupLSTaskAttr &ls_attr); - static int advance_status(common::ObISQLClient &proxy, const ObBackupLSTaskAttr &ls_attr, - const ObBackupTaskStatus &next_status, const int result, const int64_t end_ts); - static int redo_ls_task(common::ObISQLClient &proxy, const ObBackupLSTaskAttr &ls_attr, - const int64_t start_turn_id, const int64_t turn_id, const int64_t retry_id); + static int report_ls_task(common::ObISQLClient &proxy, const ObBackupLSTaskAttr &ls_attr, const ObSqlString &extra_condition); + static int report_ls_task(common::ObISQLClient &proxy, const ObBackupLSTaskAttr &ls_attr); static int get_ls_task(common::ObISQLClient &proxy, bool need_lock, const int64_t task_id, const uint64_t tenant_id, const ObLSID &ls_id, ObBackupLSTaskAttr &ls_attr); static int get_ls_tasks(common::ObISQLClient &proxy, const int64_t job_id, const uint64_t tenant_id, bool need_lock, ObIArray &ls_attrs); - static int update_task_type(common::ObISQLClient &proxy, const ObBackupLSTaskAttr &ls_attr, const ObBackupDataTaskType &type); static int update_dst_and_status(common::ObISQLClient &proxy, const int64_t task_id, - const uint64_t tenant_id, const ObLSID &ls_id, share::ObTaskId task_trace_id, common::ObAddr &dst); + const uint64_t tenant_id, const ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, share::ObTaskId task_trace_id, common::ObAddr &dst); static int insert_build_index_task(common::ObISQLClient &proxy, const ObBackupLSTaskAttr &build_index_attr); static int delete_build_index_task(common::ObISQLClient &proxy, const ObBackupLSTaskAttr &build_index_attr); static int move_ls_to_his(common::ObISQLClient &proxy, const uint64_t tenant_id, const int64_t job_id); + static int delete_ls_task_without_sys(common::ObISQLClient &proxy, const uint64_t tenant_id, const int64_t task_id); static int update_stats_(common::ObISQLClient &proxy, const int64_t task_id, const uint64_t tenant_id, const ObLSID &ls_id, const ObBackupStats &stats); - static int update_black_server(common::ObISQLClient &proxy, const int64_t task_id, const uint64_t tenant_id, - const ObLSID &ls_id, const ObString &black_servers); - static int delete_ls_task_without_sys(common::ObISQLClient &proxy, const uint64_t tenant_id, const int64_t task_id); + static int update_max_tablet_checkpoint_scn(common::ObISQLClient &proxy, const int64_t task_id, const uint64_t tenant_id, + const ObLSID &ls_id, const SCN &max_tablet_checkpoint_scn); private: static int fill_dml_with_ls_task_(const ObBackupLSTaskAttr &ls_attr, ObDMLSqlSplicer &dml); static int fill_select_ls_task_sql_(ObSqlString &sql); @@ -182,6 +179,7 @@ private: static int parse_ls_task_info_(sqlclient::ObMySQLResult &result, ObIArray &task_infos); static int do_parse_ls_task_info_(sqlclient::ObMySQLResult &result, ObBackupLSTaskInfoAttr &task_info); }; + class ObLSBackupInfoOperator : public ObBackupBaseTableOperator { public: diff --git a/src/share/backup/ob_backup_file_lock_mgr.cpp b/src/share/backup/ob_backup_file_lock_mgr.cpp deleted file mode 100644 index 6484ad091..000000000 --- a/src/share/backup/ob_backup_file_lock_mgr.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/** - * Copyright (c) 2021 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. - */ - -#define USING_LOG_PREFIX SHARE -#include "ob_backup_file_lock_mgr.h" - -using namespace oceanbase; -using namespace lib; -using namespace common; -using namespace share; - -ObBackupFileLockMgr::ObBackupFileLockMgr() - : is_inited_(false), - lock_mgr_() -{ -} - -ObBackupFileLockMgr::~ObBackupFileLockMgr() -{ -} - -void ObBackupFileLockMgr::destroy() -{ - if (is_inited_) { - lock_mgr_.destroy(); - is_inited_ = false; - } -} - -ObBackupFileLockMgr &ObBackupFileLockMgr::get_instance() -{ - static ObBackupFileLockMgr instance; - return instance; -} - -int ObBackupFileLockMgr::init() -{ - int ret = OB_SUCCESS; - if (is_inited_) { - ret = OB_INIT_TWICE; - LOG_WARN("block file lock mgr init twice", K(ret)); - } else if (OB_FAIL(lock_mgr_.create(MAX_BUCKET_NUM))) { - LOG_WARN("failed to create lock mgr map", K(ret)); - } else { - is_inited_ = true; - } - return ret; -} - -int ObBackupFileLockMgr::try_lock( - const ObBackupPath &path) -{ - int ret = OB_SUCCESS; - int hash_ret = OB_SUCCESS; - - if (path.is_empty()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("path should not be empty", K(ret), K(path)); - } else { - hash_ret = lock_mgr_.exist_refactored(path); - if (OB_HASH_EXIST == hash_ret) { - ret = OB_EAGAIN; - } else if (hash_ret == OB_HASH_NOT_EXIST) { - if (OB_FAIL(lock_mgr_.set_refactored(path))) { - LOG_WARN("failed to set lock", K(ret), K(path)); - } - } else { - ret = hash_ret; - LOG_WARN("failed to try lock", K(ret), K(path)); - } - } - return ret; -} - -int ObBackupFileLockMgr::low_try_lock( - const ObBackupPath &path, - const int64_t max_spin_cnt, - uint64_t &spin_cnt) -{ - int ret = OB_SUCCESS; - int hash_ret = OB_SUCCESS; - spin_cnt = 0; - for (; OB_SUCC(ret) && spin_cnt < max_spin_cnt; ++spin_cnt) { - hash_ret = lock_mgr_.exist_refactored(path); - if (OB_HASH_EXIST == hash_ret) { - //do nothing - } else if (OB_HASH_NOT_EXIST == hash_ret) { - if (OB_FAIL(lock_mgr_.set_refactored(path))) { - LOG_WARN("failed to set lock", K(ret), K(path)); - } else { - break; - } - } else { - spin_cnt = max_spin_cnt; - ret = hash_ret; - LOG_ERROR("failed to get lock", K(ret), K(path)); - } - PAUSE(); - } - return ret; -} - -int ObBackupFileLockMgr::lock( - const ObBackupPath &path, - const int64_t abs_timeout_us) -{ - int ret = OB_SUCCESS; - uint64_t i = 0; - uint64_t yield_cnt = 0; - if (path.is_empty() - || OB_UNLIKELY(abs_timeout_us <= 0)) { - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "Invalid argument", K(ret), K(path), K(abs_timeout_us)); - } else { - while (OB_SUCC(ret)) { - //spin - if (OB_FAIL(low_try_lock(path, MAX_SPIN_TIMES, i))) { - LOG_WARN("failed to low try lock", K(ret), K(i), K(path)); - } else if (OB_LIKELY(i < MAX_SPIN_TIMES)) { - //success lock - break; - } else if (yield_cnt < MAX_YIELD_CNT) { - sched_yield(); - ++yield_cnt; - continue; - } else { - //wait - if (OB_FAIL(wait(path, abs_timeout_us))) { - if (OB_TIMEOUT != ret) { - COMMON_LOG(WARN, "Fail to wait the lock, ", K(ret)); - } - } else { - break; - } - } - } - } - return ret; -} - -int ObBackupFileLockMgr::wait(const ObBackupPath &path, const int64_t abs_timeout_us) -{ - int ret = OB_SUCCESS; - int64_t timeout = 0; - uint64_t spin_cnt = 0; - - while (OB_SUCC(ret)) { - timeout = abs_timeout_us - ObTimeUtility::current_time(); - if (OB_UNLIKELY(timeout <= 0)) { - ret = OB_TIMEOUT; - COMMON_LOG(DEBUG, "wait lock mutex timeout, ", K(abs_timeout_us), K(ret)); - } else { - // spin try lock - if (OB_FAIL(low_try_lock(path, MAX_SPIN_CNT_AFTER_WAIT, spin_cnt))) { - LOG_WARN("failed to low try lock", K(ret), K(path), K(spin_cnt)); - } else if (MAX_SPIN_CNT_AFTER_WAIT > spin_cnt) { - ret = OB_SUCCESS; - break; - } else { - ob_usleep(1 * 1000 * 1000); //1s - } - } - } - return ret; -} - -int ObBackupFileLockMgr::unlock(const ObBackupPath &path) -{ - int ret = OB_SUCCESS; - int hash_ret = OB_SUCCESS; - if (path.is_empty()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("backup path should not be empty", K(ret), K(path)); - } else if (OB_FAIL(lock_mgr_.erase_refactored(path))) { - LOG_ERROR("failed to erase path from lock mgr", K(ret), K(path)); - } - return ret; -} - -ObBackupFileSpinLock::ObBackupFileSpinLock() - : is_inited_(false), - is_locked_(false), - path_() -{ -} - -ObBackupFileSpinLock::~ObBackupFileSpinLock() -{ - int ret = OB_SUCCESS; - if (is_locked_) { - if (OB_FAIL(unlock())) { - LOG_ERROR("failed to unlock", K(ret), K(is_locked_), K(path_)); - } else { - is_locked_ = false; - } - } -} - -int ObBackupFileSpinLock::init(const ObBackupPath &path) -{ - int ret = OB_SUCCESS; - if (is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup file spin loc init twice", K(ret)); - } else { - is_locked_ = false; - path_ = path; - is_inited_ = true; - } - return ret; -} - -int ObBackupFileSpinLock::lock() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(ObBackupFileLockMgr::get_instance().lock(path_))) { - LOG_WARN("failed to lock", K(ret), K(path_)); - } else { - is_locked_ = true; - } - return ret; -} - -int ObBackupFileSpinLock::lock(const int64_t timeout_us) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(ObBackupFileLockMgr::get_instance().lock(path_, - ObTimeUtility::current_time() + timeout_us))) { - LOG_WARN("failed to lock", K(ret), K(path_)); - } else { - is_locked_ = true; - } - return ret; -} - -int ObBackupFileSpinLock::trylock() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(ObBackupFileLockMgr::get_instance().try_lock(path_))) { - LOG_WARN("failed to try lock", K(ret), K(path_)); - } else { - is_locked_ = true; - } - return ret; -} - -int ObBackupFileSpinLock::unlock() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(ObBackupFileLockMgr::get_instance().unlock(path_))) { - LOG_WARN("failed to unlock", K(ret), K(path_)); - } else { - is_locked_ = false; - } - return ret; -} - - diff --git a/src/share/backup/ob_backup_file_lock_mgr.h b/src/share/backup/ob_backup_file_lock_mgr.h deleted file mode 100644 index 4e6bb4340..000000000 --- a/src/share/backup/ob_backup_file_lock_mgr.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright (c) 2021 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_BACKUP_OB_BACKUP_FILE_LOCK_MGR_H_ -#define OCEANBASE_SHARE_BACKUP_OB_BACKUP_FILE_LOCK_MGR_H_ - -#include "lib/container/ob_array.h" -#include "lib/restore/ob_storage.h" -#include "lib/utility/utility.h" -#include "lib/worker.h" -#include "lib/hash/ob_hashset.h" -#include "share/ob_define.h" -#include "share/ob_force_print_log.h" -#include "ob_backup_path.h" -namespace oceanbase -{ -namespace share -{ - -class ObBackupFileLockMgr -{ -public: - ObBackupFileLockMgr(); - virtual ~ObBackupFileLockMgr(); - static ObBackupFileLockMgr &get_instance(); - void destroy(); - int init(); - int lock( - const ObBackupPath &path, - const int64_t abs_timeout_us = INT64_MAX); - int try_lock( - const ObBackupPath &path); - int unlock(const ObBackupPath &path); - -private: - int low_try_lock( - const ObBackupPath &path, const int64_t max_spin_cnt, - uint64_t &spin_cnt); - int wait(const ObBackupPath &path, const int64_t abs_timeout_us); -private: - static const int64_t MAX_BUCKET_NUM = 1024; - static const int64_t MAX_SPIN_TIMES = 1024; - static const int64_t MAX_YIELD_CNT = 2; - static const int64_t MAX_SPIN_CNT_AFTER_WAIT = 1; - bool is_inited_; - common::hash::ObHashSet lock_mgr_; - DISALLOW_COPY_AND_ASSIGN(ObBackupFileLockMgr); -}; - -class ObBackupFileSpinLock -{ -public: - ObBackupFileSpinLock(); - ~ObBackupFileSpinLock(); - int init(const ObBackupPath &path); - int lock(); - int lock(const int64_t timeout_us); - int trylock(); - int unlock(); - ObBackupPath &get_path() { return path_; } -private: - // data members - bool is_inited_; - bool is_locked_; - ObBackupPath path_; -private: - DISALLOW_COPY_AND_ASSIGN(ObBackupFileSpinLock); -}; - -typedef lib::ObLockGuard ObBackupFileLockGuard; - -} //share -} //oceanbase -#endif /* OCEANBASE_SHARE_BACKUP_OB_BACKUP_FILE_LOCK_MGR_H_ */ diff --git a/src/share/backup/ob_backup_info_mgr.cpp b/src/share/backup/ob_backup_info_mgr.cpp deleted file mode 100644 index b93bc7e9d..000000000 --- a/src/share/backup/ob_backup_info_mgr.cpp +++ /dev/null @@ -1,353 +0,0 @@ -/** - * Copyright (c) 2021 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. - */ - -#define USING_LOG_PREFIX SHARE -#include "lib/thread/ob_thread_name.h" -#include "ob_backup_info_mgr.h" -#include "ob_log_archive_backup_info_mgr.h" -#include "share/restore/ob_physical_restore_table_operator.h" -#include "share/ob_cluster_version.h" -#include "share/ob_force_print_log.h" -#include "share/ob_common_rpc_proxy.h" -#include "share/backup/ob_backup_lease_info_mgr.h" -#include "share/backup/ob_backup_operator.h" -#include "share/backup/ob_backup_manager.h" -#include "share/schema/ob_multi_version_schema_service.h" -#include "lib/utility/utility.h" -#include "ob_backup_manager.h" -using namespace oceanbase; -using namespace common; -using namespace share; -using namespace common; - -void ObBackupInfoMgr::ObBackupInfoUpdateTask::runTimerTask() -{ - /* - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = ObBackupInfoMgr::get_instance().reload())) { - LOG_WARN("failed to reload backup info", K(tmp_ret)); - }*/ -} - -ObBackupInfoMgr &ObBackupInfoMgr::get_instance() -{ - static ObBackupInfoMgr backup_info; - return backup_info; -} - -ObBackupInfoMgr::ObBackupInfoMgr() - :is_inited_(false), - sql_proxy_(nullptr), - timer_(), - update_task_(), - cur_backup_info_(nullptr), - cur_backup_piece_(nullptr), - cur_restore_job_(nullptr), - lock_(ObLatchIds::BACKUP_INFO_MGR_LOCK), - mutex_(ObLatchIds::BACKUP_INFO_MGR_LOCK), - is_backup_loaded_(false), - is_restore_loaded_(false) -{ -} - -ObBackupInfoMgr::~ObBackupInfoMgr() -{ - destroy(); -} - -int ObBackupInfoMgr::init(common::ObMySQLProxy &sql_proxy) -{ - int ret = OB_SUCCESS; - if (is_inited_) { - ret = OB_INIT_TWICE; - LOG_WARN("cannot init twice", K(ret)); - } else if (OB_FAIL(timer_.init("BackupInfoUpdate"))) { - LOG_WARN("failed to init backup info update task", K(ret)); - } else { - sql_proxy_ = &sql_proxy; - cur_backup_info_ = &backup_infos_[0]; - cur_backup_piece_ = &backup_pieces_[0]; - is_inited_ = true; - } - return ret; -} - -int ObBackupInfoMgr::start() -{ - int ret = OB_SUCCESS; - // TODO(chognrong.th) redesign backup info later - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } /*else if (OB_FAIL(timer_.schedule(update_task_, DEFAULT_UPDATE_INTERVAL_US, true))) { - LOG_WARN("Failed to schedule update task", K(ret)); - } */ - return ret; -} - -void ObBackupInfoMgr::stop() -{ - timer_.stop(); -} - -void ObBackupInfoMgr::wait() -{ - timer_.wait(); -} - -void ObBackupInfoMgr::destroy() -{ - FLOG_INFO("ObBackupInfoMgr::destroy"); - timer_.destroy(); - is_inited_ = false; -} - - -int ObBackupInfoMgr::get_restore_info_from_cache( - const uint64_t tenant_id, ObSimplePhysicalRestoreJob &simple_job_info) -{ - int ret = OB_ENTRY_NOT_EXIST; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else { - SpinRLockGuard guard(lock_); - if (is_restore_loaded_) { - for (int64_t i = 0; i < cur_restore_job_->count(); ++i) { - ObPhysicalRestoreJob &cur_job = cur_restore_job_->at(i); - if (cur_job.get_tenant_id() == tenant_id) { - if (OB_FAIL(cur_job.copy_to(simple_job_info))) { - LOG_WARN("failed to copy to simple job info", K(ret), K(cur_job)); - } - break; - } - } - } - } - - return ret; -} - -int ObBackupInfoMgr::get_restore_status_from_cache( - const uint64_t tenant_id, PhysicalRestoreStatus &status) -{ - int ret = OB_ENTRY_NOT_EXIST; - status = PHYSICAL_RESTORE_MAX_STATUS; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else { - SpinRLockGuard guard(lock_); - if (is_restore_loaded_) { - for (int64_t i = 0; i < cur_restore_job_->count(); ++i) { - ObPhysicalRestoreJob &cur_job = cur_restore_job_->at(i); - if (cur_job.get_tenant_id() == tenant_id) { - status = cur_job.get_status(); - ret = OB_SUCCESS; - break; - } - } - } - } - - return ret; -} - -int ObBackupInfoMgr::get_restore_status( - const uint64_t tenant_id, PhysicalRestoreStatus &status) -{ - int ret = OB_SUCCESS; - bool found = false; - status = PHYSICAL_RESTORE_MAX_STATUS; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(get_restore_status_from_cache(tenant_id, status))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("failed to get_restore_status_from_cache", K(ret), K(tenant_id)); - } else if (OB_FAIL(reload())) { - LOG_WARN("failed to reload", K(ret)); - } else if (OB_FAIL(get_restore_status_from_cache(tenant_id, status))) { - LOG_WARN("failed to get restore info from cache again", K(ret), K(tenant_id)); - } - } - - if (OB_SUCC(ret)) { - if (REACH_TIME_INTERVAL(OB_DEFAULT_BACKUP_LOG_INTERVAL)) { - FLOG_INFO("get_restore_status_from_cache", K(ret), K(tenant_id), K(status)); - } - } - return ret; -} - -int ObBackupInfoMgr::get_backup_snapshot_version( - int64_t &backup_snapshot_version) -{ - int ret = OB_SUCCESS; - const uint64_t real_tenant_id = OB_SYS_TENANT_ID; - const uint64_t cluster_version = GET_MIN_CLUSTER_VERSION(); - backup_snapshot_version = 0; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (cluster_version < CLUSTER_VERSION_2250) { - backup_snapshot_version = 0; - LOG_INFO("old cluster version, not check delay delete snapshot version", K(cluster_version)); - } else if (OB_FAIL(ObTenantBackupInfoOperation::get_backup_snapshot_version( - *sql_proxy_, real_tenant_id, backup_snapshot_version))) { - LOG_WARN("failed to get backup snapshot_version", K(ret)); - } else if (REACH_TIME_INTERVAL(60 * 1000 * 1000)) {// for each 60s - LOG_INFO("get_backup_snapshot_version", K(ret), K(real_tenant_id), K(backup_snapshot_version)); - } - - return ret; -} - -int ObBackupInfoMgr::get_delay_delete_schema_version(const uint64_t tenant_id, - share::schema::ObMultiVersionSchemaService &schema_service, - bool &is_backup, int64_t &reserved_schema_version) -{ - int ret = OB_SUCCESS; - int64_t tenant_name_backup_schema_version = 0; - bool is_restore = false; - const int64_t cluster_version = GET_MIN_CLUSTER_VERSION(); - reserved_schema_version = 0; - is_backup = false; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (CLUSTER_VERSION_2250 > cluster_version) { - LOG_INFO("skip get_delay_delete_schema_version for old cluster version", K(cluster_version)); - } else if (OB_FAIL(schema_service.check_tenant_is_restore(nullptr, tenant_id, is_restore))) { - LOG_WARN("failed to check tenant is restore", K(ret), K(tenant_id), K(is_restore)); - } else if (is_restore) { - LOG_TRACE("get_delay_delete_schema_version for restore", K(ret), K(tenant_id), - K(reserved_schema_version), K(is_backup)); - } else if (OB_FAIL(ObTenantBackupInfoOperation::get_backup_schema_version( - *sql_proxy_, tenant_id, reserved_schema_version))) { - LOG_WARN("failed to get backup snapshot_version", K(ret)); - } else if (OB_FAIL(check_if_doing_backup(is_backup))) { - LOG_WARN("failed to check_if_doing_backup", K(ret)); - } else { - if (OB_SYS_TENANT_ID == tenant_id) { - if (OB_FAIL(ObTenantBackupInfoOperation::get_tenant_name_backup_schema_version( - *sql_proxy_, tenant_name_backup_schema_version))) { - LOG_WARN("failed to get_tenant_name_backup_schema_version", K(ret)); - } else if (tenant_name_backup_schema_version < reserved_schema_version - || 0 == reserved_schema_version) { - reserved_schema_version = tenant_name_backup_schema_version; - } - } - - LOG_INFO("get_delay_delete_schema_version", K(ret), K(tenant_id), - K(tenant_name_backup_schema_version), K(reserved_schema_version), K(is_backup)); - } - - return ret; -} - -int ObBackupInfoMgr::check_if_doing_backup(bool &is_doing) -{ - int ret = OB_SUCCESS; - const uint64_t real_tenant_id = OB_SYS_TENANT_ID; - const uint64_t cluster_version = GET_MIN_CLUSTER_VERSION(); - const bool for_update = false; - ObBackupInfoItem item; - item.name_ = "backup_status"; - is_doing = false; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (cluster_version < CLUSTER_VERSION_2250) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("old cluster version, should not call check_if_doing_backup", - K(ret), K(cluster_version)); - } else if (OB_FAIL(ObTenantBackupInfoOperation::load_info_item( - *sql_proxy_, real_tenant_id, item, for_update))) { - LOG_WARN("failed to get backup status", K(ret)); - } else if (0 != STRCMP("STOP", item.get_value_ptr())) { - is_doing = true; - FLOG_INFO("doing base data backup", K(item)); - } - - FLOG_INFO("check_if_doing_backup", K(ret), K(is_doing), K(item)); - return ret; -} - -int ObBackupInfoMgr::reload() -{ - int ret = OB_SUCCESS; - ObPhysicalRestoreTableOperator restore_operator; - ObBackupInfoManager info_manager; - const uint64_t tenant_id = OB_SYS_TENANT_ID; - - lib::ObMutexGuard mutex_guard(mutex_); - ObLogArchiveBackupInfo *new_backup_info = &backup_infos_[0]; - ObNonFrozenBackupPieceInfo *new_backup_piece = &backup_pieces_[0]; - RestoreJobArray *new_restore_job = &restore_jobs_[0]; - - if (new_backup_info == cur_backup_info_) { - new_backup_info = &backup_infos_[1]; - } - if (new_backup_piece == cur_backup_piece_) { - new_backup_piece = &backup_pieces_[1]; - } - - if (new_restore_job == cur_restore_job_) { - new_restore_job = &restore_jobs_[1]; - } - - // reload backup info - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(info_manager.init(tenant_id, *sql_proxy_))) { - LOG_WARN("failed to init info manager", K(ret)); - } else if (REACH_TIME_INTERVAL(OB_DEFAULT_BACKUP_LOG_INTERVAL) - || new_backup_info->status_.status_ != cur_backup_info_->status_.status_ - || new_backup_info->status_.round_ != cur_backup_info_->status_.round_ - || new_backup_info->status_.backup_piece_id_ != cur_backup_info_->status_.backup_piece_id_) { - FLOG_INFO("succeed to reload backup info", K(ret), K(*new_backup_info), K(*new_backup_piece)); - } - - if (OB_SUCC(ret)) { - SpinWLockGuard guard(lock_); - cur_backup_info_ = new_backup_info; - cur_backup_piece_ = new_backup_piece; - is_backup_loaded_ = true; - } - - // reload restore info - if (OB_SUCC(ret)) { - if (OB_FAIL(restore_operator.init(sql_proxy_, tenant_id))) { - LOG_WARN("failed to init restore operator", K(ret), K(tenant_id)); - } else if (OB_FAIL(restore_operator.get_jobs(*new_restore_job))) { - LOG_WARN("failed to get new restore info", K(ret)); - } else { - if (REACH_TIME_INTERVAL(OB_DEFAULT_BACKUP_LOG_INTERVAL) - || new_restore_job->count() != cur_restore_job_->count()) { - FLOG_INFO("succeed to reload restore job", K(*new_restore_job)); - } - SpinWLockGuard guard(lock_); - cur_restore_job_ = new_restore_job; - is_restore_loaded_ = true; - } - } - return ret; -} - diff --git a/src/share/backup/ob_backup_info_mgr.h b/src/share/backup/ob_backup_info_mgr.h deleted file mode 100644 index c755e3ad5..000000000 --- a/src/share/backup/ob_backup_info_mgr.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (c) 2021 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 SRC_SHARE_BACKUP_OB_BACKUP_INFO_MGR_H_ -#define SRC_SHARE_BACKUP_OB_BACKUP_INFO_MGR_H_ - -#include "share/ob_define.h" -#include "share/ob_rpc_struct.h" -#include "share/ob_thread_pool.h" - -namespace oceanbase -{ -namespace share -{ -class ObRsMgr; - -class ObBackupInfoMgr final -{ -public: - typedef common::ObArray RestoreJobArray; - static ObBackupInfoMgr &get_instance(); - - int init(common::ObMySQLProxy &sql_proxy); - int start(); - void stop(); - void wait(); - void destroy(); - int get_backup_snapshot_version(int64_t &snapshot_version); - int get_delay_delete_schema_version(const uint64_t tenant_id, - share::schema::ObMultiVersionSchemaService &schema_service, bool &is_backup, - int64_t &reserved_schema_version); - int check_if_doing_backup(bool &is_doing); - int get_restore_status(const uint64_t tenant_id, PhysicalRestoreStatus &status); - int reload(); - -private: - static const int64_t DEFAULT_UPDATE_INTERVAL_US = 10 * 1000 * 1000;//10s - int get_restore_info_from_cache(const uint64_t tenant_id, - ObSimplePhysicalRestoreJob &simple_job_info); - int get_restore_status_from_cache(const uint64_t tenant_id, PhysicalRestoreStatus &status); - int check_backup_dest_(ObLogArchiveBackupInfo &backup_info); - -private: - ObBackupInfoMgr(); - ~ObBackupInfoMgr(); - class ObBackupInfoUpdateTask : public common::ObTimerTask - { - public: - ObBackupInfoUpdateTask() {} - virtual ~ObBackupInfoUpdateTask() {} - virtual void runTimerTask() override; - }; - -private: - - bool is_inited_; - common::ObMySQLProxy *sql_proxy_; - common::ObTimer timer_; - ObBackupInfoUpdateTask update_task_; - ObLogArchiveBackupInfo backup_infos_[2]; - ObLogArchiveBackupInfo *cur_backup_info_; - ObNonFrozenBackupPieceInfo backup_pieces_[2]; - ObNonFrozenBackupPieceInfo *cur_backup_piece_; - RestoreJobArray restore_jobs_[2]; - RestoreJobArray *cur_restore_job_; - common::SpinRWLock lock_; - lib::ObMutex mutex_; - bool is_backup_loaded_; - bool is_restore_loaded_; - DISALLOW_COPY_AND_ASSIGN(ObBackupInfoMgr); -}; - -}//share -}//oceanbase -#endif /* SRC_SHARE_BACKUP_OB_BACKUP_INFO_MGR_H_ */ diff --git a/src/share/backup/ob_backup_lease_info_mgr.cpp b/src/share/backup/ob_backup_lease_info_mgr.cpp deleted file mode 100644 index 67416571d..000000000 --- a/src/share/backup/ob_backup_lease_info_mgr.cpp +++ /dev/null @@ -1,557 +0,0 @@ -/** - * Copyright (c) 2021 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/ob_define.h" -#define USING_LOG_PREFIX RS -#include "ob_backup_lease_info_mgr.h" -#include "share/ob_rpc_struct.h" -#include "share/ob_common_rpc_proxy.h" -#include "rootserver/ob_root_service.h" -#include "observer/ob_server_struct.h" -#include "share/ob_server_status.h" -#include "share/backup/ob_backup_manager.h" -#include "share/ob_cluster_version.h" -#include "logservice/ob_log_service.h" -#include "share/backup/ob_backup_operator.h" - -namespace oceanbase -{ -using namespace common; -using namespace obrpc; -using namespace storage; - -namespace share -{ -ObBackupLeaseInfo::ObBackupLeaseInfo() - : is_leader_(false), - lease_start_ts_(0), - leader_epoch_(0), - leader_takeover_ts_(0), - round_(0), - lease_epoch_(0) -{ -} - -void ObBackupLeaseInfo::reset() -{ - is_leader_ = false; - lease_start_ts_ = 0; - leader_epoch_ = 0; - leader_takeover_ts_ = 0 ; - round_ = 0; -} - -bool ObBackupLeaseInfo::is_valid() const -{ - bool valid = true; - - if (round_ < 0 || lease_epoch_ < 0) { - valid = false; - } else if (is_leader_) { - if (lease_start_ts_ < 0 || leader_epoch_ < 0 || leader_takeover_ts_ < 0) { - valid = false; - } - } else { - if (lease_start_ts_ != 0 || leader_epoch_ != 0 || leader_takeover_ts_ != 0) { - valid = false; - } - } - return valid; -} - -int ObBackupLeaseInfo::set_new_lease( - const int64_t start_ts, const int64_t epoch, - const int64_t takeover_ts, const int64_t round, - const int64_t lease_epoch) -{ - int ret = OB_SUCCESS; - - if (round < round_ || start_ts < lease_start_ts_ - || epoch < leader_epoch_ || takeover_ts < leader_takeover_ts_ - || round <= 0 || lease_epoch_ < 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(start_ts), K(epoch), K(takeover_ts), K(round), K(*this)); - } else { - reset(); - is_leader_ = true; - lease_start_ts_ = start_ts; - leader_epoch_ = epoch; - leader_takeover_ts_ = takeover_ts; - round_ = round; - lease_epoch_ = lease_epoch; - - if (!is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid lease info", K(ret), K(*this)); - } - } - return ret; -} - -int ObBackupLeaseInfo::release_lease(const int64_t round) -{ - int ret = OB_SUCCESS; - - if (round < round_ || round <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid round", K(ret), K(round)); - } else { - reset(); - round_ = round; - } - return ret; -} - -int ObBackupLeaseInfo::update_lease_start_ts(const int64_t now_ts) -{ - int ret = OB_SUCCESS; - - if (now_ts <= lease_start_ts_) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(now_ts), K(*this)); - } else { - lease_start_ts_ = now_ts; - if (!is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid lease info", K(ret), K(*this)); - } - } - return ret; -} - -ObBackupLeaseInfoMgr::ObBackupLeaseInfoMgr() - : is_inited_(false), - local_addr_(), - sql_proxy_(NULL) -{ -} - -ObBackupLeaseInfoMgr::~ObBackupLeaseInfoMgr() -{ -} - -int ObBackupLeaseInfoMgr::init( - const ObAddr &addr, - ObMySQLProxy &sql_proxy) -{ - int ret = OB_SUCCESS; - if (is_inited_) { - ret = OB_INIT_TWICE; - LOG_WARN("backup lease info mgr init twice", K(ret)); - } else if (!addr.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("backup lease info mgr get invalid argument", K(ret), K(addr)); - } else { - local_addr_ = addr; - sql_proxy_ = &sql_proxy; - is_inited_ = true; - } - return ret; -} - -int ObBackupLeaseInfoMgr::clean_backup_lease_info( - const int64_t next_round, const ObBackupLeaseInfo &old_lease_info, - ObBackupLeaseInfo &new_lease_info) -{ - int ret = OB_SUCCESS; - new_lease_info = old_lease_info; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (next_round < 0 || !old_lease_info.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(next_round), K(old_lease_info)); - } else if (OB_FAIL(new_lease_info.release_lease(next_round))) { - LOG_WARN("failed to release lease", K(ret), K(next_round)); - } else if (OB_FAIL(clean_backup_scheduler_leadear_())) { - LOG_WARN("failed to clean backup scheduler leader", K(ret)); - } - - return ret; -} - -int ObBackupLeaseInfoMgr::renew_lease(const int64_t can_be_leader_ts, - const int64_t next_round, - const ObBackupLeaseInfo &old_lease_info, - ObBackupLeaseInfo &new_lease_info, - const char *&msg) -{ - int ret = OB_SUCCESS; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup lease info mgr do not init", K(ret)); - } else if (can_be_leader_ts < 0 || next_round < 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(can_be_leader_ts), K(next_round)); - } else { - MTL_SWITCH(OB_SYS_TENANT_ID) { - ObRole role = FOLLOWER; - int64_t proposal_id = OB_INVALID_TIMESTAMP; - int64_t takeover_time = OB_INVALID_TIMESTAMP; - if (OB_FAIL(MTL(logservice::ObLogService*)->get_palf_role(ObLSID(SYS_LS), role, proposal_id))) { - LOG_WARN("get palf role failed", KR(ret)); - } else if (FALSE_IT(takeover_time = proposal_id)) { - // TODO: fix me later - } else if (!is_strong_leader(role)) { - ret = OB_LEADER_NOT_EXIST; - LOG_WARN("not stronge leader, cannot renew backup lease", K(ret), K(role), - K(proposal_id), K(takeover_time)); - } else if (OB_FAIL(do_renew_lase_(proposal_id, takeover_time, - can_be_leader_ts, next_round, old_lease_info, new_lease_info, msg))) { - LOG_WARN("failed to check can backup", K(ret), K(role)); - } - } - } - return ret; -} - -int ObBackupLeaseInfoMgr::get_backup_scheduler_leader_( - common::ObISQLClient &sql_client, - common::ObAddr &backup_leader_addr, - bool &has_leader, - int64_t &lease_epoch) -{ - int ret = OB_SUCCESS; - bool is_compat = false; - if (OB_FAIL(get_backup_scheduler_leader_v2_(sql_client, backup_leader_addr, has_leader, lease_epoch))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("failed to get_backup_scheduler_leader_v2", K(ret)); - } else if (OB_FAIL(get_backup_scheduler_leader_v1_(sql_client, backup_leader_addr, has_leader))) { - LOG_WARN("failed to get_backup_scheduler_leader_v1", K(ret)); - } else { - lease_epoch = 0; - is_compat = true; - } - } - LOG_INFO("succeed to get backup scheduler leader", K(ret), K(backup_leader_addr), K(is_compat), K(has_leader), K(lease_epoch)); - return ret; -} - -int ObBackupLeaseInfoMgr::get_backup_scheduler_leader_v1_( - common::ObISQLClient &sql_client, - common::ObAddr &scheduler_leader_addr, - bool &has_leader) -{ - int ret = OB_SUCCESS; - scheduler_leader_addr.reset(); - ObBackupInfoManager info_manager; - ObArray tenant_ids; - - has_leader = true; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup lease info mgr do not init", K(ret)); - } else if (OB_FAIL(tenant_ids.push_back(OB_SYS_TENANT_ID))) { - LOG_WARN("failed to push tenant id into array", K(ret)); - } else if (OB_FAIL(info_manager.init(tenant_ids, *sql_proxy_))) { - LOG_WARN("failed to init info manager", K(ret), K(tenant_ids)); - } else if (OB_FAIL(info_manager.get_backup_scheduler_leader(OB_SYS_TENANT_ID, sql_client, - scheduler_leader_addr, has_leader))) { - LOG_WARN("failed to get backup scheduler leader", K(ret)); - } - return ret; -} - -int ObBackupLeaseInfoMgr::get_backup_scheduler_leader_v2_( - common::ObISQLClient &sql_client, - common::ObAddr &lease_leader, - bool &has_leader, - int64_t &lease_epoch) -{ - int ret = OB_SUCCESS; - const bool for_update = false; - lease_leader.reset(); - has_leader = true; - lease_epoch = 0; - if (OB_FAIL(ObBackupInfoOperator::get_backup_leader(sql_client, for_update, lease_leader, has_leader))) { - LOG_WARN("Failed to get backup leader", K(ret)); - } else if (OB_FAIL(ObBackupInfoOperator::get_backup_leader_epoch(sql_client, for_update, lease_epoch))) { - LOG_WARN("failed to get backup leader epoch", K(ret)); - } - return ret; -} - -int ObBackupLeaseInfoMgr::update_backup_scheduler_leader_( - const common::ObAddr &lease_leader, - int64_t &lease_epoch, - common::ObISQLClient &sql_client) -{ - int ret = OB_SUCCESS; - const uint64_t cluster_observer_version = GET_MIN_CLUSTER_VERSION(); - common::ObClusterVersion version; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (!lease_leader.is_valid() || lease_epoch < 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(lease_leader), K(lease_epoch)); - } else if (OB_FAIL(version.init(cluster_observer_version))) { - LOG_WARN("failed to init version", K(ret), K(cluster_observer_version)); - } else if (cluster_observer_version < CLUSTER_VERSION_2277 - || (cluster_observer_version >= CLUSTER_VERSION_3000 && cluster_observer_version <= CLUSTER_VERSION_3100)) { - if (lease_epoch > 0) { - ret = OB_ERR_SYS; - LOG_ERROR("for old version, lease epoch must be 0", K(ret), K(lease_leader), K(lease_epoch), K(version)); - } else if (OB_FAIL(update_backup_scheduler_leader_v1_(lease_leader, sql_client))) { - LOG_WARN("failed to update_backup_scheduler_leader_v1_", K(ret), K(lease_leader)); - } - } else { - int64_t new_lease_epoch = lease_epoch + 1; - if (OB_FAIL(update_backup_scheduler_leader_v2_(lease_leader, new_lease_epoch, sql_client))) { - LOG_WARN("failed to update_backup_scheduler_leader_v2_", K(ret), K(lease_leader), K(new_lease_epoch)); - } else { - lease_epoch = new_lease_epoch; - } - } - FLOG_INFO("update_backup_scheduler_leader_", K(ret), K(cluster_observer_version), K(version), K(lease_leader), K(lease_epoch)); - return ret; -} - -int ObBackupLeaseInfoMgr::update_backup_scheduler_leader_v1_( - const ObAddr &scheduler_leader_addr, - common::ObISQLClient &sql_client) -{ - int ret = OB_SUCCESS; - ObBackupInfoManager info_manager; - ObArray tenant_ids; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup lease info mgr do not init", K(ret)); - } else if (OB_FAIL(tenant_ids.push_back(OB_SYS_TENANT_ID))) { - LOG_WARN("failed to push tenant id into array", K(ret)); - } else if (OB_FAIL(info_manager.init(tenant_ids, *sql_proxy_))) { - LOG_WARN("failed to init info manager", K(ret), K(tenant_ids)); - } else if (OB_FAIL(info_manager.update_backup_scheduler_leader(OB_SYS_TENANT_ID, scheduler_leader_addr, sql_client))) { - LOG_WARN("failed to get backup scheduler leader", K(ret), K(scheduler_leader_addr)); - } else { - FLOG_INFO("succeed to update backup scheduler leader", K(scheduler_leader_addr)); - } - return ret; -} - -int ObBackupLeaseInfoMgr::update_backup_scheduler_leader_v2_( - const common::ObAddr &lease_leader, - const int64_t lease_epoch, - common::ObISQLClient &sql_client) -{ - int ret = OB_SUCCESS; - int64_t got_lease_epoch = 0; - common::ObAddr got_leader; - bool has_leader = true; - const bool for_update = true; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (!lease_leader.is_valid() || lease_epoch < 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(lease_leader), K(lease_epoch)); - } else if (OB_FAIL(ObBackupInfoOperator::get_backup_leader(sql_client, for_update, got_leader, has_leader))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("failed to get backup leader", K(ret), K(got_leader), K(has_leader)); - } else { - ret = OB_SUCCESS; - FLOG_INFO("backup leader not exist, just update it", K(ret), K(lease_leader), K(lease_epoch)); - } - } else if (OB_FAIL(ObBackupInfoOperator::get_backup_leader_epoch(sql_client, for_update, got_lease_epoch))) { - LOG_WARN("failed to get backup leader epoch", K(ret)); - } else if (0 == got_lease_epoch && 0 == lease_epoch) { - // compat mode - } else if (got_lease_epoch + 1 != lease_epoch) { - ret = OB_ERR_SYS; - LOG_ERROR("cannot set backup leader with invalid lease epoch", K(ret), K(has_leader), K(lease_epoch), K(got_lease_epoch)); - } - if (FAILEDx(ObBackupInfoOperator::set_backup_leader_epoch(sql_client, lease_epoch))) { - LOG_WARN("failed to set backup leader epoch", K(ret), K(lease_leader), K(lease_epoch)); - } else if (OB_FAIL(ObBackupInfoOperator::set_backup_leader(sql_client, lease_leader))) { - LOG_WARN("Failed set backup leader", K(ret), K(lease_leader)); - } - - return ret; -} - - -int ObBackupLeaseInfoMgr::clean_backup_scheduler_leadear_() -{ - int ret = OB_SUCCESS; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(clean_backup_scheduler_leadear_v1_())) { - LOG_WARN("Failed to clean_backup_scheduler_leadear_v1", K(ret)); - } else if (OB_FAIL(clean_backup_scheduler_leadear_v2_())) { - LOG_WARN("Failed to clean_backup_scheduler_leadear_v2", K(ret)); - } - FLOG_INFO("clean_backup_scheduler_leadear_", K(ret), K(local_addr_)); - return ret; -} - -int ObBackupLeaseInfoMgr::clean_backup_scheduler_leadear_v1_() -{ - int ret = OB_SUCCESS; - ObBackupInfoManager info_manager; - ObArray tenant_ids; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup lease info mgr do not init", K(ret)); - } else if (OB_FAIL(tenant_ids.push_back(OB_SYS_TENANT_ID))) { - LOG_WARN("failed to push tenant id into array", K(ret)); - } else if (OB_FAIL(info_manager.init(tenant_ids, *sql_proxy_))) { - LOG_WARN("failed to init info manager", K(ret), K(tenant_ids)); - } else if (OB_FAIL(info_manager.clean_backup_scheduler_leader(OB_SYS_TENANT_ID, local_addr_))) { - LOG_WARN("failed to clean backup scheduler leader", K(ret), K(local_addr_)); - } else { - FLOG_INFO("succeed to clean backup scheduler leader", K(local_addr_)); - } - return ret; -} - -int ObBackupLeaseInfoMgr::clean_backup_scheduler_leadear_v2_() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(ObBackupInfoOperator::clean_backup_leader(*sql_proxy_, local_addr_))) { - LOG_WARN("Failed to clean backup leader", K(ret)); - } - return ret; -} - -int ObBackupLeaseInfoMgr::do_renew_lase_( - const int64_t leader_epoch, - const int64_t takeover_time, - const int64_t can_be_leader_ts, - const int64_t next_round, - const ObBackupLeaseInfo &old_lease_info, - ObBackupLeaseInfo &new_lease_info, - const char *&msg) -{ - int ret = OB_SUCCESS; - int64_t now_ts = ObTimeUtil::current_time(); - new_lease_info.reset(); - msg = ""; - int64_t max_lease_takeover_time = ObBackupLeaseInfo::MAX_LEASE_TAKEOVER_TIME; - -#ifdef ERRSIM - max_lease_takeover_time = ObServerConfig::get_instance().backup_lease_takeover_time; -#endif - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup lease info mgr do not init", K(ret)); - } else if (leader_epoch < 0 || now_ts < 0 || takeover_time < 0 - || can_be_leader_ts < 0 || next_round < 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(leader_epoch), K(now_ts), K(takeover_time)); - } else { - if (old_lease_info.is_leader_ - && old_lease_info.leader_epoch_ == leader_epoch - && old_lease_info.leader_takeover_ts_ == takeover_time) { - new_lease_info = old_lease_info; - if (OB_FAIL(new_lease_info.update_lease_start_ts(now_ts))) { - LOG_WARN("failed to update lease start ts", K(ret)); - } - } else { - ObMySQLTransaction trans; - ObAddr backup_scheduler_leader; - bool has_leader = true; - int64_t lease_epoch = 0; - - if (OB_FAIL(trans.start(sql_proxy_, OB_SYS_TENANT_ID))) { - LOG_WARN("failed to start trans", K(ret)); - } else { - if (OB_FAIL(get_backup_scheduler_leader_(trans, backup_scheduler_leader, has_leader, lease_epoch))) { - LOG_WARN("failed to get backup scheduler leader", K(ret)); - } else if (!has_leader) { - // first time as leader, if the lease epoch is 0, then we donot use multi-version small files. - // Otherwise, lease epoch is bigger than 0. - int64_t new_lease_epoch = lease_epoch; - // update_backup_scheduler_leader_ will increase the lease epoch if needed. - if (OB_FAIL(update_backup_scheduler_leader_(local_addr_, new_lease_epoch, trans))) { - LOG_WARN("failed to update backup scheduler leader", K(ret), K(local_addr_), K(new_lease_epoch)); - } else { - backup_scheduler_leader = local_addr_; - lease_epoch = new_lease_epoch; - } - } - - if (OB_FAIL(ret)) { - } else { - if (local_addr_ == backup_scheduler_leader) { - if (OB_FAIL(new_lease_info.set_new_lease(now_ts, leader_epoch, - takeover_time, next_round, lease_epoch))) { - LOG_WARN("failed to set new lease info", K(ret)); - } else { - msg = "got backup lease fast"; - FLOG_INFO(msg, K(now_ts), K(new_lease_info)); - } - } else if (takeover_time + max_lease_takeover_time < now_ts - && can_be_leader_ts + max_lease_takeover_time < now_ts) { - // Leader switch, I am the leader. - int64_t new_lease_epoch = lease_epoch; - // update_backup_scheduler_leader_ will increase the lease epoch if needed. - if (OB_FAIL(update_backup_scheduler_leader_(local_addr_, new_lease_epoch, trans))) { - LOG_WARN("failed to update backup scheduler leader", K(ret), K(local_addr_)); - } else if (OB_FAIL(new_lease_info.set_new_lease(now_ts, leader_epoch, - takeover_time, next_round, new_lease_epoch))) { - LOG_WARN("failed to set new lease info", K(ret)); - } else { - msg = "got backup lease after old lease expired"; - FLOG_INFO(msg, K(now_ts), K(new_lease_info)); - } - } else { // not own lease - if (OB_FAIL(new_lease_info.release_lease(next_round))) { - LOG_WARN("failed to release lease", K(ret), K(next_round)); - } else { - const int64_t need_wait_ts = std::max( - max_lease_takeover_time + takeover_time - now_ts, - max_lease_takeover_time + can_be_leader_ts - now_ts); - LOG_INFO("not own lease now, need wait", K(takeover_time), K(can_be_leader_ts), - K(now_ts), K(need_wait_ts), K(backup_scheduler_leader)); - } - } - } - - if (OB_SUCC(ret)) { - if (OB_FAIL(trans.end(true /*commit*/))) { - new_lease_info.reset(); - LOG_WARN("failed to commit backup scheduler leader", K(ret), K(new_lease_info)); - } else if (new_lease_info.is_leader_) { - FLOG_INFO("succeed to update backup scheduler leader", K(ret), K_(local_addr), - K(new_lease_info), K(msg)); - } - } else { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(false /* commit*/))) { - OB_LOG(WARN, "failed to rollback trans", K(tmp_ret)); - } - } - } - } - } - return ret; -} - -int ObFakeBackupLeaseService::check_lease() -{ - return OB_SUCCESS; -} - -int ObFakeBackupLeaseService::get_lease_status(bool &is_lease_valid) -{ - is_lease_valid = true; - return OB_SUCCESS; -} - -int64_t ObFakeBackupLeaseService::get_lease_version() const -{ - return INT64_MAX; -} -} //share -} //oceanbase diff --git a/src/share/backup/ob_backup_lease_info_mgr.h b/src/share/backup/ob_backup_lease_info_mgr.h deleted file mode 100644 index 16d416ad4..000000000 --- a/src/share/backup/ob_backup_lease_info_mgr.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright (c) 2021 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_SRC_SHARE_BACKUP_OB_BACKUP_LEASE_INFO_MGR_H_ -#define OCEANBASE_SRC_SHARE_BACKUP_OB_BACKUP_LEASE_INFO_MGR_H_ - -#include "share/ob_define.h" -#include "share/ob_force_print_log.h" -#include "lib/mysqlclient/ob_isql_client.h" -#include "lib/mysqlclient/ob_mysql_result.h" -#include "lib/mysqlclient/ob_mysql_statement.h" -#include "lib/mysqlclient/ob_mysql_connection_pool.h" -#include "common/ob_role.h" -#include "share/ob_rpc_struct.h" -#include "share/ob_common_rpc_proxy.h" - -namespace oceanbase -{ -namespace share -{ - - -struct ObBackupLeaseInfo -{ - - - - static const int64_t MAX_LEASE_TIME = 30 * 1000 * 1000; - static const int64_t MAX_LEASE_TAKEOVER_TIME = 10 * 1000 * 1000L; - - ObBackupLeaseInfo(); - void reset(); - int set_new_lease(const int64_t start_ts, const int64_t epoch, - const int64_t takeover_ts, const int64_t round, - const int64_t lease_epoch); - int release_lease(const int64_t round); - int update_lease_start_ts(const int64_t now_ts); - bool is_valid() const; - TO_STRING_KV(K_(is_leader), K_(lease_start_ts), K_(leader_epoch), K_(leader_takeover_ts), - K_(round), K_(lease_epoch)); - bool is_leader_; - int64_t lease_start_ts_; - int64_t leader_epoch_; // for rs leader - int64_t leader_takeover_ts_; // for rs leader - int64_t round_; - int64_t lease_epoch_; // backup lease epoch -}; - -class ObBackupLeaseInfoMgr -{ -public: - ObBackupLeaseInfoMgr(); - virtual ~ObBackupLeaseInfoMgr(); - int init( - const common::ObAddr &addr, - common::ObMySQLProxy &sql_proxy); - int renew_lease(const int64_t can_be_leader_ts, const int64_t next_round, - const ObBackupLeaseInfo &old_lease_info, ObBackupLeaseInfo &new_lease_info, - const char *&msg); - int clean_backup_lease_info(const int64_t next_round, const ObBackupLeaseInfo &old_lease_info, - ObBackupLeaseInfo &new_lease_info); -private: - int get_backup_scheduler_leader_( - common::ObISQLClient &sql_client, - common::ObAddr &backup_leader_addr, - bool &has_leader, - int64_t &lease_epoch); - int get_backup_scheduler_leader_v1_( - common::ObISQLClient &sql_client, - common::ObAddr &backup_leader_addr, - bool &has_leader); - int get_backup_scheduler_leader_v2_( - common::ObISQLClient &sql_client, - common::ObAddr &backup_leader_addr, - bool &has_leader, - int64_t &lease_epoch); - int update_backup_scheduler_leader_( - const common::ObAddr &lease_leader, - int64_t &lease_epoch, - common::ObISQLClient &sql_client); - int update_backup_scheduler_leader_v1_( - const common::ObAddr &backup_leader_addr, - common::ObISQLClient &sql_client); - int update_backup_scheduler_leader_v2_( - const common::ObAddr &lease_leader, - const int64_t lease_epoch, - common::ObISQLClient &sql_client); - int clean_backup_scheduler_leadear_(); - int clean_backup_scheduler_leadear_v1_(); - int clean_backup_scheduler_leadear_v2_(); - int do_renew_lase_( - const int64_t leader_epoch, - const int64_t takeover_time, - const int64_t can_be_leader_ts, - const int64_t next_round, - const ObBackupLeaseInfo &old_lease_info, - ObBackupLeaseInfo &new_lease_info, - const char *&msg); - int get_core_table_info_(ObRole &role, int64_t &leader_epoch, int64_t &takeover_time); -private: - bool is_inited_; - common::ObAddr local_addr_; - common::ObMySQLProxy *sql_proxy_; - - DISALLOW_COPY_AND_ASSIGN(ObBackupLeaseInfoMgr); -}; - -class ObIBackupLeaseService -{ -public: - virtual ~ObIBackupLeaseService() {} - virtual int check_lease() = 0; - virtual int get_lease_status(bool &is_lease_valid) = 0; - virtual int64_t get_lease_version() const = 0; - DEFINE_VIRTUAL_TO_STRING(); -}; - -class ObFakeBackupLeaseService: public ObIBackupLeaseService -{ -public: - virtual int check_lease(); - virtual int get_lease_status(bool &is_lease_valid); - virtual int64_t get_lease_version() const; -}; - -} //share -} //oceanbase - -#define BACKUP_LEASE_MGR (::oceanbase::share::ObBackupLeaseInfoMgr::get_instance()) - -#endif /* OCEANBASE_SRC_SHARE_BACKUP_OB_BACKUP_LEASE_INFO_MGR_H_ */ diff --git a/src/share/backup/ob_backup_manager.cpp b/src/share/backup/ob_backup_manager.cpp deleted file mode 100644 index de7837c95..000000000 --- a/src/share/backup/ob_backup_manager.cpp +++ /dev/null @@ -1,959 +0,0 @@ -/** - * Copyright (c) 2021 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. - */ - -#define USING_LOG_PREFIX SERVER - -#include "lib/mysqlclient/ob_mysql_transaction.h" -#include "lib/mysqlclient/ob_mysql_result.h" -#include "share/inner_table/ob_inner_table_schema_constants.h" -#include "ob_backup_lease_info_mgr.h" -#include "ob_backup_operator.h" -#include "ob_backup_manager.h" -#include "ob_backup_struct.h" -using namespace oceanbase; -using namespace share; -using namespace common; - -static const char *BASE_BACKUP_VERSION_STR = "base_backup_version"; // only used for restore -static ObBackupInfoSimpleItem backup_info_item_list[] = { - {"backup_dest", ""}, - {"backup_backup_dest", ""}, - {"backup_status", "STOP"}, // ObBackupInfoStatus::STOP - {"backup_type", ""}, - {"backup_snapshot_version", ""}, - {"backup_schema_version", ""}, - {"backup_data_version", ""}, - {"backup_set_id", "0"}, // OB_START_BACKUP_SET_ID =1 - {"incarnation", "1"}, // OB_START_INCARNATION=1 - {"backup_task_id", "0"}, - {"detected_backup_region", ""}, - {"log_archive_status", "STOP"}, // STOP - {"backup_scheduler_leader", ""}, - {"backup_encryption_mode", ""}, - {"backup_passwd", ""}, - {"enable_auto_backup_archivelog", ""}, - {"delete_obsolete_backup_snapshot", ""}, - {"delete_obsolete_backup_backup_snapshot", ""}, -}; - - -ObBackupInfoItem::ObBackupInfoItem(ObBackupInfoItem::ItemList &list, - const char *name, const char *value) - : name_(name), value_(value) -{ - list.add_last(this); -} - -ObBackupInfoItem::ObBackupInfoItem(const ObBackupInfoItem &item) - : name_(item.name_), value_(item.value_) -{ -} - -ObBackupInfoItem::ObBackupInfoItem() - :name_(NULL), value_() -{ -} - -ObBackupInfoItem &ObBackupInfoItem::operator =(const ObBackupInfoItem &item) -{ - name_ = item.name_; - value_ = item.value_; - return *this; -} - -int ObBackupInfoItem::update( - common::ObISQLClient &sql_client, - const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - if (!is_valid() || OB_INVALID_ID == tenant_id) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(*this), K(tenant_id)); - } else if (OB_FAIL(ObTenantBackupInfoOperation::update_info_item(sql_client, tenant_id, *this))) { - LOG_WARN("update item failed", K(ret), K(tenant_id), "item", *this); - } - return ret; -} - -int ObBackupInfoItem::update( - ObBackupItemTransUpdater &updater, - const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - if (!is_valid() || OB_INVALID_ID == tenant_id) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), "self", *this); - } else if (OB_FAIL(updater.update(tenant_id, *this))) { - LOG_WARN("update item failed", K(ret), K(tenant_id), K(*this)); - } - return ret; -} - -int ObBackupInfoItem::get_int_value(int64_t &value) const -{ - int ret = OB_SUCCESS; - int64_t tmp = 0; - char *endptr = NULL; - value = 0; - - if (value_.is_empty()) { - tmp = 0; - } else { - tmp = strtoll(value_.ptr(), &endptr, 0); - if ('\0' != *endptr) { - ret = OB_INVALID_DATA; - LOG_ERROR("invalid data, is not int value", K(ret), K(tmp), K(value_)); - } else { - value = tmp; - } - } - return ret; -} - -int ObBackupInfoItem::set_value(const int64_t value) -{ - int ret = OB_SUCCESS; - if (value < 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("backup info set value get invalid argument", K(ret), K(value)); - } else if (0 == value) { - if (OB_FAIL(set_value(""))) { - LOG_WARN("failed to set value", K(ret), K(value)); - } - } else { - int strlen = sprintf(value_.ptr(), "%ld", value); - if (strlen <= 0 || strlen > common::OB_INNER_TABLE_DEFAULT_VALUE_LENTH) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to set value", K(ret), K(value), K(strlen)); - } - } - return ret; -} - -int ObBackupInfoItem::set_value(const char *buf) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(buf)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("set value get invalid argument", K(ret), KP(buf)); - } else { - const int64_t len = strlen(buf); - if (len >= OB_INNER_TABLE_DEFAULT_VALUE_LENTH) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("buffer len is unexpected", K(ret), K(len)); - } else { - STRNCPY(value_.ptr(), buf, len); - value_.ptr()[len] = '\0'; - LOG_DEBUG("set value", K(buf), K(strlen(buf)), K(value_)); - } - } - return ret; -} - -int ObBackupInfoItem::insert( - common::ObISQLClient &sql_client, - const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - if (!is_valid() || OB_INVALID_ID == tenant_id) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(*this), K(tenant_id)); - } else if (OB_FAIL(ObTenantBackupInfoOperation::insert_info_item(sql_client, tenant_id, *this))) { - LOG_WARN("update item failed", K(ret), K(tenant_id), "item", *this); - } - return ret; -} - -ObBackupItemTransUpdater::ObBackupItemTransUpdater() - : started_(false), success_(false) -{ -} - -ObBackupItemTransUpdater::~ObBackupItemTransUpdater() -{ - if (started_) { - int ret = end(success_); - if (OB_FAIL(ret)) { - LOG_WARN("end transaction failed", K(ret)); - } - } -} - -int ObBackupItemTransUpdater::start( - ObMySQLProxy &sql_proxy, - const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - if (started_) { - ret = OB_INIT_TWICE; - LOG_WARN("transaction already started", K(ret)); - } else if (OB_FAIL(trans_.start(&sql_proxy, tenant_id))) { - LOG_WARN("start transaction failed", K(ret), K(tenant_id)); - started_ = false; - } else { - started_ = true; - success_ = true; - } - return ret; -} - -int ObBackupItemTransUpdater::update( - const uint64_t tenant_id, - const ObBackupInfoItem &item) -{ - int ret = OB_SUCCESS; - if (!started_) { - ret = OB_NOT_INIT; - LOG_WARN("transaction not started", K(ret)); - } else if (!item.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(item)); - } else { - if (OB_FAIL(ObTenantBackupInfoOperation::update_info_item(trans_, tenant_id, item))) { - LOG_WARN("update backup info failed", K(ret), K(tenant_id), "item", item); - success_ = false; - } - } - return ret; -} - -int ObBackupItemTransUpdater::load( - const uint64_t tenant_id, - ObBackupInfoItem &item, - const bool need_lock) -{ - int ret = OB_SUCCESS; - if (!started_) { - ret = OB_NOT_INIT; - LOG_WARN("transaction not started", K(ret)); - } else if (!item.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(item)); - } else if (OB_FAIL(ObTenantBackupInfoOperation::load_info_item(trans_, tenant_id, item, need_lock))) { - LOG_WARN("load backup item failed", K(ret), K(tenant_id), "item", item); - success_ = false; - } - return ret; -} - -int ObBackupItemTransUpdater::end(const bool commit) -{ - int ret = OB_SUCCESS; - // can be end if ::start() fail, do not check started_ here. - if (started_) { - if (OB_FAIL(trans_.end(commit && success_))) { - LOG_WARN("transaction end failed", K(ret), K(commit), K(success_)); - } - started_ = false; - } - return ret; -} - -#define INIT_ITEM(field, value_def) field##_(list_, #field, value_def) -#define CONSTRUCT_BASE_BACKUP_INFO() \ - INIT_ITEM(backup_dest, ""), \ - INIT_ITEM(backup_backup_dest, ""), \ - INIT_ITEM(backup_status, ""), \ - INIT_ITEM(backup_type, ""), \ - INIT_ITEM(backup_snapshot_version, ""), \ - INIT_ITEM(backup_schema_version, ""), \ - INIT_ITEM(backup_data_version, ""), \ - INIT_ITEM(backup_set_id, ""), \ - INIT_ITEM(incarnation, ""), \ - INIT_ITEM(backup_task_id, ""), \ - INIT_ITEM(detected_backup_region, ""), \ - INIT_ITEM(backup_encryption_mode, ""), \ - INIT_ITEM(backup_passwd, "") - -ObBaseBackupInfo::ObBaseBackupInfo() - : tenant_id_(), - CONSTRUCT_BASE_BACKUP_INFO() -{ -} - -ObBaseBackupInfo::ObBaseBackupInfo(const ObBaseBackupInfo &other) - : CONSTRUCT_BASE_BACKUP_INFO() -{ - *this = other; -} - -#undef CONSTRUCT_BASE_BACKUP_INFO -#undef INIT_ITEM - -ObBaseBackupInfo &ObBaseBackupInfo::operator = (const ObBaseBackupInfo &other) -{ - int ret = OB_SUCCESS; - tenant_id_ = other.tenant_id_; - ObBackupInfoItem *it = list_.get_first(); - const ObBackupInfoItem *o_it = other.list_.get_first(); - while (it != list_.get_header() && o_it != other.list_.get_header()) { - if (NULL == it || NULL == o_it) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("null item", K(ret), KP(it), KP(o_it)); - break; - } - *it = *o_it; - it = it->get_next(); - o_it = o_it->get_next(); - } - return *this; -} - -void ObBaseBackupInfo::reset() -{ - int ret = OB_SUCCESS; - tenant_id_ = OB_INVALID_ID; - ObBackupInfoItem *it = list_.get_first(); - while (it != list_.get_header()) { - if (NULL == it) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("null item", K(ret), KP(it)); - break; - } - it->value_.reset(); - it = it->get_next(); - } -} - -bool ObBaseBackupInfo::is_empty() const -{ - return backup_status_.value_.is_empty(); -} - - -ObBackupInfoManager::ObBackupInfoManager() - : inited_(false), - tenant_ids_(), proxy_(NULL) -{ -} - -ObBackupInfoManager::~ObBackupInfoManager() -{ -} - -void ObBackupInfoManager::reset() -{ - tenant_ids_.reset(); - proxy_ = NULL; -} - -int ObBackupInfoManager::init( - const common::ObIArray &tenant_ids, - common::ObMySQLProxy &proxy) -{ - int ret = OB_SUCCESS; - if (inited_) { - ret = OB_INIT_TWICE; - LOG_WARN("init twice", K(ret)); - } else if (tenant_ids.empty()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tenant ids should not be empty", K(ret), K(tenant_ids)); - } else if (OB_FAIL(tenant_ids_.assign(tenant_ids))) { - LOG_WARN("fail to assign tenant ids", K(ret), K(tenant_ids)); - } else { - proxy_ = &proxy; - inited_ = true; - } - return ret; -} - -int ObBackupInfoManager::init( - const uint64_t tenant_id, - common::ObMySQLProxy &proxy) -{ - int ret = OB_SUCCESS; - ObArray tenant_ids; - - if (inited_) { - ret = OB_INIT_TWICE; - LOG_WARN("init twice", K(ret)); - } else if (OB_INVALID_ID == tenant_id) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("init backup info manager get invalid argument", K(ret), K(tenant_id)); - } else if (OB_FAIL(tenant_ids.push_back(tenant_id))) { - LOG_WARN("failed to push tenant id into array", K(ret), K(tenant_id)); - } else if (OB_FAIL(init(tenant_ids, proxy))) { - LOG_WARN("failed to init", K(ret), K(tenant_ids)); - } - return ret; -} - - -int ObBackupInfoManager::check_can_update( - const ObBaseBackupInfoStruct &src_info, - const ObBaseBackupInfoStruct &dest_info) -{ - int ret = OB_SUCCESS; - if (!inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup info manager do not init", K(ret)); - } else if (!src_info.is_valid() || !dest_info.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("src info or dest info is invalid", K(ret), K(src_info), K(dest_info)); - } else if (OB_FAIL(check_can_update_(src_info.backup_status_.status_, - dest_info.backup_status_.status_))) { - LOG_WARN("failed to check can update", K(ret), K(src_info), K(dest_info)); - } - return ret; -} - -int ObBackupInfoManager::find_tenant_id(const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - if (!inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup info manager do not init", K(ret)); - } else { - bool found = false; - for (int64_t i = 0; i < tenant_ids_.count() && !found; ++i) { - if (tenant_id == tenant_ids_.at(i)) { - found = true; - } - } - if (!found) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("can not find tenant id", K(ret), K(tenant_id), K(tenant_ids_)); - } - } - return ret; -} - -int ObBackupInfoManager::get_tenant_ids(common::ObIArray &tenant_ids) -{ - int ret = OB_SUCCESS; - tenant_ids.reset(); - if (!inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup info manager do not init", K(ret)); - } else if (OB_FAIL(tenant_ids.assign(tenant_ids_))) { - LOG_WARN("failed to assign tenant ids", K(ret), K(tenant_ids_)); - } - return ret; -} - -int ObBackupInfoManager::get_backup_scheduler_leader( - const uint64_t tenant_id, - common::ObISQLClient &trans, - common::ObAddr &scheduler_leader, - bool &has_leader) -{ - int ret = OB_SUCCESS; - scheduler_leader.reset(); - ObBackupInfoItem scheduler_leader_item; - const char *name = "backup_scheduler_leader"; - scheduler_leader_item.name_ = name; - const bool need_lock = true; - has_leader = true; - if (!inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup info manager do not init", K(ret)); - } else if (OB_FAIL(find_tenant_id(tenant_id))) { - LOG_WARN("failed to find tenant id", K(ret), K(tenant_id)); - } else if (OB_FAIL(ObTenantBackupInfoOperation::load_info_item(trans, - tenant_id, scheduler_leader_item, need_lock))) { - LOG_WARN("failed to detected info", K(ret), K(tenant_id)); - } else if (scheduler_leader_item.value_.is_empty()) { - has_leader = false; - LOG_INFO("scheduler leader not exist"); - } else if (OB_FAIL(scheduler_leader.parse_from_cstring(scheduler_leader_item.get_value_ptr()))) { - LOG_WARN("failed to set backup scheduler leader", K(ret), K(scheduler_leader_item)); - } - return ret; -} - -int ObBackupInfoManager::update_backup_scheduler_leader( - const uint64_t tenant_id, - const common::ObAddr &scheduler_leader, - common::ObISQLClient &trans) -{ - int ret = OB_SUCCESS; - ObBackupInfoItem scheduler_leader_item; - const char *name = "backup_scheduler_leader"; - scheduler_leader_item.name_ = name; - char scheduler_leader_str[MAX_IP_PORT_LENGTH] = ""; - - if (!inited_) { - ret = OB_NOT_INIT; - LOG_WARN("backup info manager do not init", K(ret)); - } else if (OB_FAIL(find_tenant_id(tenant_id))) { - LOG_WARN("failed to find tenant id", K(ret), K(tenant_id)); - } else if (!scheduler_leader.is_valid()) { - if (OB_FAIL(scheduler_leader_item.set_value(""))) { - LOG_WARN("failed to set scheduler leader", K(ret), K(tenant_id), K(scheduler_leader)); - } - } else if (OB_FAIL(scheduler_leader.ip_port_to_string(scheduler_leader_str, MAX_IP_PORT_LENGTH))) { - LOG_WARN("failed to add addr to buf", K(ret), K(scheduler_leader)); - } else if (OB_FAIL(scheduler_leader_item.set_value(scheduler_leader_str))) { - LOG_WARN("failed to set backup scheduler leader", K(ret), K(scheduler_leader), K(tenant_id)); - } else if (OB_FAIL(scheduler_leader_item.update(trans, tenant_id))) { - LOG_WARN("failed to update scheduler leader", K(ret), K(tenant_id), K(scheduler_leader)); - } - return ret; -} - -int ObBackupInfoManager::clean_backup_scheduler_leader( - const uint64_t tenant_id, - const common::ObAddr &scheduler_leader) -{ - int ret = OB_SUCCESS; - - if (!inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (tenant_id != OB_SYS_TENANT_ID || !scheduler_leader.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tenant_id), K(scheduler_leader)); - } else if (OB_FAIL(ObTenantBackupInfoOperation::clean_backup_scheduler_leader(*proxy_, - tenant_id, scheduler_leader))) { - LOG_WARN("failed to clean backup scheduler leader", K(ret)); - } - - return ret; -} - -int ObBackupInfoManager::get_job_id(int64_t& job_id) -{ - int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - ObMySQLTransaction trans; - ObBackupInfoItem job_id_item; - const char *name = "job_id"; - job_id_item.name_ = name; - const int64_t FIRST_JOB_ID = 1; - const bool need_lock = true; - if (OB_UNLIKELY(!inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("backup info manager do not init", K(ret)); - } else if (OB_FAIL(trans.start(proxy_, OB_SYS_TENANT_ID))) { - LOG_WARN("failed to start trans", K(ret)); - } else { - if (OB_FAIL(ObTenantBackupInfoOperation::load_info_item( - trans, OB_SYS_TENANT_ID, job_id_item, need_lock))) { - if (OB_BACKUP_INFO_NOT_EXIST == ret) { - ret = OB_SUCCESS; - if (OB_FAIL(job_id_item.set_value(FIRST_JOB_ID))) { - LOG_WARN("failed to set job id", K(ret)); - } else if (OB_FAIL(job_id_item.insert(trans, OB_SYS_TENANT_ID))) { - LOG_WARN("failed to update job id", K(ret)); - } else if (FALSE_IT(job_id = FIRST_JOB_ID)) { - // do nothing - } - } - } else { - int64_t tmp_job_id = 0; - if (OB_FAIL(job_id_item.get_int_value(tmp_job_id))) { - LOG_WARN("failed to get int value", K(ret)); - } else if (OB_FAIL(job_id_item.set_value(tmp_job_id + 1))) { - LOG_WARN("failed to set value", K(ret)); - } else if (OB_FAIL(job_id_item.update(trans, OB_SYS_TENANT_ID))) { - LOG_WARN("failed to update job id", K(ret)); - } else if (FALSE_IT(job_id = tmp_job_id + 1)) { - // do nothing - } - } - - if (OB_SUCC(ret)) { - if (OB_FAIL(trans.end(true/*commit*/))) { - LOG_WARN("failed to commit", K(ret)); - } else { - LOG_INFO("succeed to get_job_id", K(ret)); - } - } else { - if (OB_SUCCESS != (tmp_ret = trans.end((false/*commit*/)))) { - LOG_WARN("failed to rollback", K(ret), K(tmp_ret)); - } - } - } - return ret; -} - -int ObBackupInfoManager::check_can_update_( - const ObBackupInfoStatus::BackupStatus &src_status, - const ObBackupInfoStatus::BackupStatus &dest_status) -{ - int ret = OB_SUCCESS; - if (src_status > ObBackupInfoStatus::MAX - || dest_status > ObBackupInfoStatus::MAX) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("src or dest status is invalid", K(ret), K(src_status), K(dest_status)); - } else { - switch (src_status) { - case ObBackupInfoStatus::PREPARE : - if (ObBackupInfoStatus::SCHEDULE != dest_status - && ObBackupInfoStatus::CANCEL != dest_status - && ObBackupInfoStatus::STOP != dest_status) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("can not update backup info", K(ret), K(src_status), K(dest_status)); - } - break; - case ObBackupInfoStatus::SCHEDULE : - if (ObBackupInfoStatus::SCHEDULE != dest_status - && ObBackupInfoStatus::DOING != dest_status - && ObBackupInfoStatus::CANCEL != dest_status - && ObBackupInfoStatus::STOP != dest_status) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("can not update backup info", K(ret), K(src_status), K(dest_status)); - } - break; - case ObBackupInfoStatus::DOING : - if (ObBackupInfoStatus::DOING != dest_status - && ObBackupInfoStatus::CLEANUP != dest_status - && ObBackupInfoStatus::CANCEL != dest_status) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("can not update backup info", K(ret), K(src_status), K(dest_status)); - } - break; - case ObBackupInfoStatus::CLEANUP : - if (ObBackupInfoStatus::CLEANUP != dest_status - && ObBackupInfoStatus::STOP != dest_status - && ObBackupInfoStatus::CANCEL != dest_status) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("can not update backup info", K(ret), K(src_status), K(dest_status)); - } - break; - case ObBackupInfoStatus::CANCEL : - if (ObBackupInfoStatus::CANCEL != dest_status - && ObBackupInfoStatus::CLEANUP != dest_status) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("can not update backup info", K(ret), K(src_status), K(dest_status)); - } - break; - case ObBackupInfoStatus::STOP : - if (ObBackupInfoStatus::STOP != dest_status - && ObBackupInfoStatus::PREPARE != dest_status - && ObBackupInfoStatus::SCHEDULE != dest_status) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("can not update backup info", K(ret), K(src_status), K(dest_status)); - } - break; - case ObBackupInfoStatus::MAX : - ret = OB_ERR_UNEXPECTED; - LOG_WARN("can not update backup info", K(ret), K(src_status), K(dest_status)); - break; - } - } - return ret; -} - -ObBackupInfoSimpleItem::ObBackupInfoSimpleItem() - : name_(""), value_("") -{ -} - -ObBackupInfoSimpleItem::ObBackupInfoSimpleItem(const char *name, const char *value) - : name_(name), value_(value) -{ -} - -ObBackupInfoChecker::ObBackupInfoChecker() - : is_inited_(false), - sql_proxy_(nullptr), - inner_table_version_(OB_BACKUP_INNER_TABLE_VMAX) -{ -} - -ObBackupInfoChecker::~ObBackupInfoChecker() -{ -} - -int ObBackupInfoChecker::init(common::ObMySQLProxy *sql_proxy, - const share::ObBackupInnerTableVersion &inner_table_version) -{ - int ret = OB_SUCCESS; - - if (is_inited_) { - ret = OB_INIT_TWICE; - LOG_WARN("cannot init twice", K(ret)); - } else if (OB_ISNULL(sql_proxy)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), KP(sql_proxy)); - } else { - sql_proxy_ = sql_proxy; - inner_table_version_ = inner_table_version; - is_inited_ = true; - } - return ret; -} - -int ObBackupInfoChecker::check(const common::ObIArray &tenant_ids, - share::ObIBackupLeaseService &backup_lease_service) -{ - int ret = OB_SUCCESS; - int64_t count = tenant_ids.count(); - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } - - for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { - const uint64_t tenant_id = tenant_ids.at(i); - if (OB_FAIL(backup_lease_service.check_lease())) { - LOG_WARN("failed to check can backup", K(ret)); - } else if (OB_FAIL(check(tenant_id))) { - LOG_WARN("failed to check tenant backup info", K(ret), K(i), K(tenant_id)); - } - } - - return ret; -} - -int ObBackupInfoChecker::check(const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - ObMySQLTransaction trans; - int64_t status_line_count = 0; - common::ObArray new_items; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(get_status_line_count_(tenant_id, status_line_count))) { - LOG_WARN("failed to get_status_line_count_", K(ret), K(tenant_id)); - } else if (OB_FAIL(get_new_items_(*sql_proxy_, tenant_id, false/*for update*/, new_items))) { - LOG_WARN("failed to get new items", K(ret), K(tenant_id)); - } else if (new_items.empty() - && (0 != status_line_count || inner_table_version_ > OB_BACKUP_INNER_TABLE_V1)) { - // do no thing - } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id))) { - LOG_WARN("failed to start trans", K(ret)); - } else { - if (0 == status_line_count && OB_BACKUP_INNER_TABLE_V1 == inner_table_version_) { - if (OB_FAIL(insert_log_archive_status_(trans, tenant_id))) { - LOG_WARN("failed to insert log archive srtatus", K(ret), K(tenant_id)); - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(get_new_items_(trans, tenant_id, true/*for update*/, new_items))) { - LOG_WARN("failed to get new items", K(ret), K(tenant_id)); - } else if (OB_FAIL(insert_new_items_(trans, tenant_id, new_items))) { - LOG_WARN("failed to insert new items", K(ret), K(tenant_id)); - } - - if (OB_SUCC(ret)) { - if (OB_FAIL(trans.end(true))) {//commit - LOG_WARN("failed to commit", K(ret), K(tenant_id)); - } else { - FLOG_INFO("succeed to add backup info items", K(ret), K(tenant_id), K(new_items)); - } - } else { - if (OB_SUCCESS != (tmp_ret = trans.end((false)))) {//rollback - LOG_WARN("failed to rollback", K(ret), K(tmp_ret), K(tenant_id)); - } - } - } - - return ret; -} - - -int ObBackupInfoChecker::get_item_count_(const uint64_t tenant_id, int64_t &item_count) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - SMART_VAR(ObMySQLProxy::ReadResult, res) { - sqlclient::ObMySQLResult *result = NULL; - item_count = 0; - - if (OB_FAIL(sql.assign_fmt("select count(*) as count from %s where tenant_id=%lu and name not in ('%s')", - share::OB_ALL_BACKUP_INFO_TNAME, tenant_id, BASE_BACKUP_VERSION_STR))) { - LOG_WARN("failed to init backup info sql", K(ret)); - } else if (OB_FAIL(sql_proxy_->read(res, tenant_id, sql.ptr()))) { - OB_LOG(WARN, "fail to execute sql", K(ret), K(sql)); - } else if (OB_ISNULL(result = res.get_result())) { - ret = OB_ERR_UNEXPECTED; - OB_LOG(WARN, "result is NULL", K(ret), K(sql)); - } else if (OB_FAIL(result->next())) { - OB_LOG(WARN, "fail to get next result", K(ret), K(sql)); - } else { - EXTRACT_INT_FIELD_MYSQL(*result, "count", item_count, int64_t); - } - - } - return ret; -} - -int ObBackupInfoChecker::get_status_line_count_(const uint64_t tenant_id, int64_t &status_count) -{ - int ret = OB_SUCCESS; - - // TODO: to remove. - -#if 0 - ObSqlString sql; - SMART_VAR(ObMySQLProxy::ReadResult, res) { - sqlclient::ObMySQLResult *result = NULL; - status_count = 0; - - if (OB_FAIL(sql.assign_fmt("select count(*) as count from %s where tenant_id=%lu ", - share::OB_ALL_TENANT_BACKUP_LOG_ARCHIVE_STATUS_TNAME, tenant_id))) { - LOG_WARN("failed to init backup info sql", K(ret)); - } else if (OB_FAIL(sql_proxy_->read(res, tenant_id, sql.ptr()))) { - OB_LOG(WARN, "fail to execute sql", K(ret), K(sql)); - } else if (OB_ISNULL(result = res.get_result())) { - ret = OB_ERR_UNEXPECTED; - OB_LOG(WARN, "result is NULL", K(ret), K(sql)); - } else if (OB_FAIL(result->next())) { - OB_LOG(WARN, "fail to get next result", K(ret), K(sql)); - } else { - EXTRACT_INT_FIELD_MYSQL(*result, "count", status_count, int64_t); - } - - } -#endif - return ret; -} - -int ObBackupInfoChecker::get_new_items_(common::ObISQLClient &trans, - const uint64_t tenant_id, const bool for_update, - common::ObIArray &items) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - const char *for_update_str = for_update? "for update": ""; - - SMART_VAR(ObMySQLProxy::ReadResult, res) { - sqlclient::ObMySQLResult *result = NULL; - char name_str[OB_INNER_TABLE_DEFAULT_KEY_LENTH] = {0}; - char value_str[OB_INNER_TABLE_DEFAULT_VALUE_LENTH] = {0}; - int real_length = 0; - int64_t read_count = 0; - items.reset(); - - if (OB_FAIL(sql.assign_fmt("select name from %s where tenant_id=%lu %s", - OB_ALL_BACKUP_INFO_TNAME, tenant_id, for_update_str))) { - LOG_WARN("failed to init backup info sql", K(ret)); - } else if (OB_FAIL(trans.read(res, tenant_id, sql.ptr()))) { - OB_LOG(WARN, "fail to execute sql", K(ret), K(sql)); - } else if (OB_ISNULL(result = res.get_result())) { - ret = OB_ERR_UNEXPECTED; - OB_LOG(WARN, "result is NULL", K(ret), K(sql)); - } else { - const int64_t count = ARRAYSIZEOF(backup_info_item_list); - for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { - const ObBackupInfoSimpleItem &item = backup_info_item_list[i]; - if (inner_table_version_ > OB_BACKUP_INNER_TABLE_V1 - && (0 == strcmp("log_archive_status", item.name_))) { - // no need prepare these item for new version inner table - // TODO(zeyong): remove backup_scheduler_leader after backup lease upgrade - } else if (OB_FAIL(items.push_back(item))) { - LOG_WARN("failed to add items", K(ret), K(i)); - } - } - } - - while(OB_SUCC(ret)) { - if (OB_FAIL(result->next())) { - if (OB_ITER_END != ret) { - OB_LOG(WARN, "fail to get next result", K(ret), K(sql)); - } else { - ret = OB_SUCCESS; - } - break; - } else if (OB_ISNULL(result)) { - ret = OB_ERR_UNEXPECTED; - OB_LOG(WARN, "result is NULL", K(ret), K(sql)); - } - - EXTRACT_STRBUF_FIELD_MYSQL(*result, "name", name_str, sizeof(name_str), real_length); - const int64_t count = items.count(); - bool found = false; - for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { - if (0 == strcmp(name_str, items.at(i).name_)) { - if (OB_FAIL(items.remove(i))) { - LOG_WARN("failed to remove item", K(ret), K(i)); - } else { - LOG_TRACE("remove exist item", K(ret), K(i), K(name_str)); - } - found = true; - break; - } - } - - if (OB_SUCC(ret) && !found) { - LOG_DEBUG("unknown item", K(ret), K(sql), K(tenant_id), K(name_str), K(items)); - } - } - } - return ret; -} - -int ObBackupInfoChecker::insert_new_items_(common::ObMySQLTransaction &trans, - const uint64_t tenant_id, common::ObIArray &items) -{ - int ret = OB_SUCCESS; - const int64_t count = items.count(); - - for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { - if (OB_FAIL(insert_new_item_(trans, tenant_id, items.at(i)))) { - LOG_WARN("failed to insert new item", K(ret), K(tenant_id), "item", items.at(i)); - } - } - - return ret; -} - -int ObBackupInfoChecker::insert_new_item_(common::ObMySQLTransaction &trans, - const uint64_t tenant_id, ObBackupInfoSimpleItem &item) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = -1; - - if (OB_FAIL(sql.assign_fmt("insert into %s(tenant_id, name, value) values(%lu, '%s', '%s')", - OB_ALL_BACKUP_INFO_TNAME, tenant_id, item.name_, item.value_))) { - LOG_WARN("failed to assign sql", K(ret), K(tenant_id), K(item)); - } else if (OB_FAIL(trans.write(tenant_id, sql.ptr(), affected_rows))) { - LOG_WARN("failed to write sql", K(ret), K(sql)); - } else if (1 != affected_rows) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("invalid affected_rows", K(ret), K(affected_rows), K(sql)); - } else { - FLOG_INFO("[LOG_ARCHIVE] insert_new_item_", K(sql)); - } - - return ret; -} - - -int ObBackupInfoChecker::insert_log_archive_status_( - common::ObMySQLTransaction &trans, const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - // TODO: to remove. -#if 0 - ObSqlString sql; - int64_t affected_rows = -1; - - if (OB_FAIL(sql.assign_fmt( - "insert into %s(%s,%s,%s,%s,%s, %s) values(%lu, %ld, 0,usec_to_time(0), usec_to_time(0), 'STOP') ", - OB_ALL_TENANT_BACKUP_LOG_ARCHIVE_STATUS_TNAME, OB_STR_TENANT_ID, OB_STR_INCARNATION, - OB_STR_LOG_ARCHIVE_ROUND, OB_STR_MIN_FIRST_TIME, OB_STR_MAX_NEXT_TIME, OB_STR_STATUS, - tenant_id, OB_START_INCARNATION))) { - LOG_WARN("failed to assign sql", K(ret), K(tenant_id)); - } else if (OB_FAIL(trans.write(tenant_id, sql.ptr(), affected_rows))) { - LOG_WARN("failed to write sql", K(ret), K(sql)); - } else if (1 != affected_rows) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("invalid affected_rows", K(ret), K(affected_rows), K(sql)); - } else { - LOG_INFO("[LOG_ARCHIVE] insert_log_archive_status_", K(inner_table_version_), K(sql)); - } -#endif - return ret; -} - - - - diff --git a/src/share/backup/ob_backup_manager.h b/src/share/backup/ob_backup_manager.h deleted file mode 100644 index a815efd8d..000000000 --- a/src/share/backup/ob_backup_manager.h +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Copyright (c) 2021 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_BACKUP_OB_BACKUP_MANAGER_H_ -#define OCEANBASE_SHARE_BACKUP_OB_BACKUP_MANAGER_H_ - -#include "share/ob_define.h" -#include "lib/container/ob_array.h" -#include "lib/mysqlclient/ob_mysql_proxy.h" -#include "lib/mysqlclient/ob_mysql_transaction.h" -#include "ob_backup_struct.h" -#include "share/ob_rpc_struct.h" - -namespace oceanbase -{ -namespace share -{ - -class ObBackupItemTransUpdater; -class ObIBackupLeaseService; - -struct ObBackupInfoItem : public common::ObDLinkBase -{ - public: - typedef common::ObFixedLengthString Value; - typedef common::ObDList ItemList; - - ObBackupInfoItem(ItemList &list, const char *name, const char *info); - ObBackupInfoItem(const ObBackupInfoItem &item); - ObBackupInfoItem(); - ObBackupInfoItem &operator = (const ObBackupInfoItem &item); - - bool is_valid() const { return NULL != name_; } - TO_STRING_KV(K_(name), K_(value)); - const char* get_value_ptr() const { return value_.ptr(); } - int get_int_value(int64_t &value) const; - int set_value(const int64_t value); - int set_value(const char* buf); - - // update %value_ - int update(common::ObISQLClient &sql_client, const uint64_t tenant_id); - // update %value_ will be rollback if transaction rollback or commit failed. - int update(ObBackupItemTransUpdater &updater, const uint64_t tenant_id); - //insert - int insert(common::ObISQLClient &sql_client, const uint64_t tenant_id); - -public: - const char *name_; - Value value_; -}; - -// Update item in transaction, if transaction rollback or commit failed the item value -// value will be rollback too. -class ObBackupItemTransUpdater -{ -public: - ObBackupItemTransUpdater(); - ~ObBackupItemTransUpdater(); - - int start(common::ObMySQLProxy &sql_proxy, - const uint64_t tenant_id); - int update(const uint64_t tenant_id, - const ObBackupInfoItem &item); - int load(const uint64_t tenant_id, ObBackupInfoItem &item, const bool need_lock = true); - int end(const bool commit); - common::ObMySQLTransaction &get_trans() { return trans_; } -private: - const static int64_t PTR_OFFSET = sizeof(void *); - - bool started_; - bool success_; - common::ObMySQLTransaction trans_; -}; - -struct ObBaseBackupInfo -{ -public: - ObBaseBackupInfo(); - ObBaseBackupInfo(const ObBaseBackupInfo &other); - ObBaseBackupInfo &operator =(const ObBaseBackupInfo &other); - void reset(); - bool is_valid() const; - bool is_empty() const; - DECLARE_TO_STRING; - - inline int64_t get_item_count() const { return list_.get_size(); } - int get_backup_info_status(); - -public: - uint64_t tenant_id_; - ObBackupInfoItem::ItemList list_; - //base data backup info - ObBackupInfoItem backup_dest_; - ObBackupInfoItem backup_backup_dest_; - ObBackupInfoItem backup_status_; - ObBackupInfoItem backup_type_; - ObBackupInfoItem backup_snapshot_version_; - ObBackupInfoItem backup_schema_version_; - ObBackupInfoItem backup_data_version_; - ObBackupInfoItem backup_set_id_; - ObBackupInfoItem incarnation_; - ObBackupInfoItem backup_task_id_; - //region info - ObBackupInfoItem detected_backup_region_; - ObBackupInfoItem backup_encryption_mode_; - ObBackupInfoItem backup_passwd_; -}; - -class ObBackupInfoManager -{ -public: - //friend class FakeZoneMgr; - ObBackupInfoManager(); - virtual ~ObBackupInfoManager(); - void reset(); - int init( - const common::ObIArray &tenant_ids, - common::ObMySQLProxy &proxy); - int init( - const uint64_t tenant_id, - common::ObMySQLProxy &proxy); - - bool is_inited() { return inited_; } - int get_tenant_ids(common::ObIArray &tenant_ids); - int add_backup_info(const ObBaseBackupInfo &info); - int add_backup_info(const uint64_t tenant_id); - int cancel_backup(); - int check_can_update( - const ObBaseBackupInfoStruct &src_info, - const ObBaseBackupInfoStruct &dest_info); - int get_backup_scheduler_leader( - const uint64_t tenant_id, - common::ObISQLClient &trans, - common::ObAddr &scheduler_leader, - bool &has_leader); - int update_backup_scheduler_leader( - const uint64_t tenant_id, - const common::ObAddr &scheduler_leader, - common::ObISQLClient &trans); - int clean_backup_scheduler_leader( - const uint64_t tenant_id, - const common::ObAddr &scheduler_leader); - int get_job_id(int64_t& job_id); - -private: - int convert_info_to_struct(const ObBaseBackupInfo &info, ObBaseBackupInfoStruct &info_struct); - int find_tenant_id(const uint64_t tenant_id); - int get_backup_info( - const uint64_t tenant_id, - ObBackupItemTransUpdater &updater, - ObBaseBackupInfo &info); - int check_can_update_( - const ObBackupInfoStatus::BackupStatus &src_status, - const ObBackupInfoStatus::BackupStatus &dest_status); - -private: - bool inited_; - common::ObArray tenant_ids_; - common::ObMySQLProxy *proxy_; - -private: - DISALLOW_COPY_AND_ASSIGN(ObBackupInfoManager); -}; - -struct ObBackupInfoSimpleItem -{ - ObBackupInfoSimpleItem(); - ObBackupInfoSimpleItem(const char *name, const char *value); - const char *name_; - const char *value_; - TO_STRING_KV(K_(name), K_(value)); -}; - -class ObBackupInfoChecker final -{ -public: - ObBackupInfoChecker(); - ~ObBackupInfoChecker(); - - int init(common::ObMySQLProxy *sql_proxy, const share::ObBackupInnerTableVersion &inner_table_version); - int check(const common::ObIArray &tenant_ids, - share::ObIBackupLeaseService &backup_lease_service); - int check(const uint64_t tenant_id); - -private: - int get_item_count_(const uint64_t tenant_id, int64_t &item_count); - int get_status_line_count_(const uint64_t tenant_id, int64_t &status_count); - int get_new_items_(common::ObISQLClient &trans, const uint64_t tenant_id, - const bool for_update, common::ObIArray &items); - int insert_new_items_(common::ObMySQLTransaction &trans, - const uint64_t tenant_id, common::ObIArray &items); - int insert_new_item_(common::ObMySQLTransaction &trans, - const uint64_t tenant_id, ObBackupInfoSimpleItem &item); - int insert_log_archive_status_(common::ObMySQLTransaction &trans, const uint64_t tenant_id); - -private: - bool is_inited_; - common::ObMySQLProxy *sql_proxy_; - share::ObBackupInnerTableVersion inner_table_version_; - DISALLOW_COPY_AND_ASSIGN(ObBackupInfoChecker); -}; - -}//share -}//oceanbase -#endif /* SRC_SHARE_BACKUP_OB_BACKUP_INFO_H_ */ diff --git a/src/share/backup/ob_backup_operator.cpp b/src/share/backup/ob_backup_operator.cpp deleted file mode 100644 index b05a3aa67..000000000 --- a/src/share/backup/ob_backup_operator.cpp +++ /dev/null @@ -1,804 +0,0 @@ -/** - * Copyright (c) 2021 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. - */ - -#define USING_LOG_PREFIX SERVER - -#include "lib/string/ob_sql_string.h" -#include "share/inner_table/ob_inner_table_schema.h" -#include "share/schema/ob_part_mgr_util.h" -#include "share/backup/ob_backup_struct.h" -#include "lib/utility/utility.h" -#include "ob_backup_operator.h" - -namespace oceanbase -{ -namespace share -{ -using namespace oceanbase::common; -using namespace oceanbase::common::sqlclient; - -int ObITenantBackupTaskOperator::get_tenant_ids( - const uint64_t tenant_id, - const common::ObSqlString &sql, - common::ObIArray &tenant_ids, - common::ObISQLClient &sql_proxy) -{ - int ret = OB_SUCCESS; - SMART_VAR(ObMySQLProxy::MySQLResult, res) { - sqlclient::ObMySQLResult *result = NULL; - if (OB_UNLIKELY(!sql.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(sql)); - } else if (OB_FAIL(sql_proxy.read(res, tenant_id, sql.ptr()))) { - LOG_WARN("fail to execute sql", K(ret), K(sql)); - } else if (OB_ISNULL(result = res.get_result())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("error unexpected, query result must not be NULL", K(ret)); - } else { - while (OB_SUCC(ret)) { - int64_t tmp_tenant_id = 0; - if (OB_FAIL(result->next())) { - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - break; - } else { - LOG_WARN("fail to get next row", K(ret)); - } - } else { - EXTRACT_INT_FIELD_MYSQL(*result, "tenant_id", tmp_tenant_id, int64_t); - if (OB_FAIL(tenant_ids.push_back(tmp_tenant_id))) { - LOG_WARN("failed to push tenant id into array", K(ret), K(tmp_tenant_id)); - } - } - } - } - } - return ret; -} - -template -int ObTenantBackupInfoOperation::set_info_item( - const char *name, const char *info_str, T &info) -{ - int ret = OB_SUCCESS; - // %value and %info_str can be arbitrary values - if (NULL == name) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid name", K(ret)); - } else { - ObBackupInfoItem *it = info.list_.get_first(); - while (OB_SUCCESS == ret && it != info.list_.get_header()) { - if (NULL == it) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("null iter", K(ret)); - } else { - if (strncasecmp(it->name_, name, OB_MAX_COLUMN_NAME_LENGTH) == 0) { - it->value_ = info_str; - break; - } - it = it->get_next(); - } - } - if (OB_SUCC(ret)) { - // ignore unknown item - if (it == info.list_.get_header()) { - LOG_WARN("unknown item", K(name), "value", info_str); - } - } - } - return ret; -} - -template -int ObTenantBackupInfoOperation::load_info(common::ObISQLClient &sql_client, T &info) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - const uint64_t exec_tenant_id = gen_meta_tenant_id(info.tenant_id_); - - SMART_VAR(ObMySQLProxy::MySQLResult, res) { - ObMySQLResult *result = NULL; - ObTimeoutCtx ctx; - if (OB_FAIL(ObBackupUtils::get_backup_info_default_timeout_ctx(ctx))) { - LOG_WARN("fail to get timeout ctx", K(ret), K(ctx)); - } else if (OB_FAIL(sql.assign_fmt("SELECT name, value FROM %s WHERE tenant_id = %lu FOR UPDATE", - OB_ALL_BACKUP_INFO_TNAME, info.tenant_id_))) { - LOG_WARN("append sql failed", K(ret)); - } else if (OB_FAIL(sql_client.read(res, exec_tenant_id, sql.ptr()))) { - LOG_WARN("execute sql failed", K(ret), K(exec_tenant_id), K(sql)); - } else if (NULL == (result = res.get_result())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get sql result", K(ret)); - } else { - int64_t tmp_real_str_len = 0; - char name[OB_INNER_TABLE_DEFAULT_KEY_LENTH] = ""; - char value_str[OB_INNER_TABLE_DEFAULT_VALUE_LENTH + 1] = ""; - while (OB_SUCCESS == ret && OB_SUCCESS == (ret = result->next())) { - EXTRACT_STRBUF_FIELD_MYSQL(*result, "name", name, - static_cast(sizeof(name)), tmp_real_str_len); - EXTRACT_STRBUF_FIELD_MYSQL(*result, "value", value_str, - static_cast(sizeof(value_str)), tmp_real_str_len); - (void) tmp_real_str_len; // make compiler happy - if (OB_SUCC(ret)) { - if (OB_FAIL(set_info_item(name, value_str, info))) { - LOG_WARN("set info item failed", K(ret), K(name), K(value_str)); - } - } - } - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("get result failed", K(ret), K(sql)); - } - } - } - return ret; -} - -int ObTenantBackupInfoOperation::load_base_backup_info(ObISQLClient &sql_client, ObBaseBackupInfo &info) -{ - return load_info(sql_client, info); -} - -template -int ObTenantBackupInfoOperation::insert_info(ObISQLClient &sql_client, T &info) -{ - int ret = OB_SUCCESS; - if (!info.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(info)); - } else { - DLIST_FOREACH(it, info.list_) { - if (OB_FAIL(update_info_item(sql_client, info.tenant_id_, *it))) { - LOG_WARN("insert item failed", K(ret), "tenant_id", info.tenant_id_, "item", *it); - break; - } - } - } - return ret; -} - -int ObTenantBackupInfoOperation::load_info_item( - common::ObISQLClient &sql_client, - const uint64_t tenant_id, - ObBackupInfoItem &item, - const bool need_lock) -{ - int ret = OB_SUCCESS; - ObTimeoutCtx ctx; - ObSqlString sql; - const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id); - SMART_VAR(ObMySQLProxy::MySQLResult, res) { - ObMySQLResult *result = NULL; - - if (OB_INVALID_ID == tenant_id || !item.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(item), K(tenant_id)); - } else if (OB_FAIL(ObBackupUtils::get_backup_info_default_timeout_ctx(ctx))) { - LOG_WARN("fail to get timeout ctx", K(ret), K(ctx)); - } else if (OB_FAIL(sql.assign_fmt( - "SELECT name, value FROM %s WHERE name = '%s' AND tenant_id = %lu", - OB_ALL_BACKUP_INFO_TNAME, item.name_, tenant_id))) { - LOG_WARN("assign sql failed", K(ret)); - } else if (need_lock && OB_FAIL(sql.append(" FOR UPDATE"))) { - LOG_WARN("failed to append lock for sql", K(ret), K(sql)); - } else if (OB_FAIL(sql_client.read(res, exec_tenant_id, sql.ptr()))) { - LOG_WARN("execute sql failed", K(ret), K(sql), K(exec_tenant_id)); - } else if (NULL == (result = res.get_result())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get sql result", K(ret)); - } else if (OB_FAIL(result->next())) { - if (OB_ITER_END == ret) { - ret = OB_BACKUP_INFO_NOT_EXIST; - LOG_WARN("backup info is not exist yet, wait later", K(ret), K(tenant_id), K(sql)); - } else { - LOG_WARN("failed to get next", K(ret)); - } - } else { - int64_t tmp_real_str_len = 0; - char name[OB_INNER_TABLE_DEFAULT_KEY_LENTH] = ""; - char value_str[OB_INNER_TABLE_DEFAULT_VALUE_LENTH] = ""; - EXTRACT_STRBUF_FIELD_MYSQL(*result, "name", name, - static_cast(sizeof(name)), tmp_real_str_len); - EXTRACT_STRBUF_FIELD_MYSQL(*result, "value", value_str, - static_cast(sizeof(value_str)), tmp_real_str_len); - (void) tmp_real_str_len; // make compiler happy - if (OB_SUCC(ret)) { - if (0 != strcmp(name, item.name_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to select item", K(ret), K(item), K(name)); - } else { - MEMCPY(item.value_.ptr(), value_str, sizeof(value_str)); - } - } - } - - } - return ret; -} - -int ObTenantBackupInfoOperation::get_backup_snapshot_version( - common::ObISQLClient &sql_proxy, - const uint64_t tenant_id, - int64_t &backup_snapshot_version) -{ - int ret = OB_SUCCESS; - const bool need_lock = false; - ObBackupInfoItem item; - item.name_ = "backup_snapshot_version"; - backup_snapshot_version = 0; - - if (OB_FAIL(load_info_item(sql_proxy, tenant_id, item, need_lock))) { - if (OB_BACKUP_INFO_NOT_EXIST == ret) { - backup_snapshot_version = 0; - LOG_WARN("tenant backup info not exist", K(ret), K(backup_snapshot_version)); - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get backup snapshot_version", K(ret)); - } - } else if (OB_FAIL(item.get_int_value(backup_snapshot_version))) { - LOG_WARN("failed to get int value", K(ret), K(item)); - } - - return ret; -} - -int ObTenantBackupInfoOperation::get_backup_schema_version( - common::ObISQLClient &sql_proxy, - const uint64_t tenant_id, int64_t &backup_schema_version) -{ - int ret = OB_SUCCESS; - const bool need_lock = false; - ObBackupInfoItem item; - item.name_ = "backup_schema_version"; - backup_schema_version = 0; - - if (OB_FAIL(load_info_item(sql_proxy, tenant_id, item, need_lock))) { - if (OB_BACKUP_INFO_NOT_EXIST == ret) { - backup_schema_version = 0; - LOG_WARN("tenant backup info not exist", K(ret), K(backup_schema_version)); - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get backup schema version", K(ret)); - } - } else if (OB_FAIL(item.get_int_value(backup_schema_version))) { - LOG_WARN("failed to get int value", K(ret), K(item)); - } - - return ret; -} - -int ObTenantBackupInfoOperation::get_tenant_name_backup_schema_version( - common::ObISQLClient &sql_proxy, - int64_t &backup_schema_version) -{ - int ret = OB_SUCCESS; - const bool need_lock = false; - ObBackupInfoItem item; - item.name_ = OB_STR_TENANT_NAME_BACKUP_SCHEMA_VERSION; - backup_schema_version = 0; - - if (OB_FAIL(load_info_item(sql_proxy, OB_SYS_TENANT_ID, item, need_lock))) { - if (OB_BACKUP_INFO_NOT_EXIST == ret) { - backup_schema_version = 0; - LOG_WARN("tenant backup info not exist", K(ret), K(backup_schema_version)); - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tenant_name_backup_schema_version", K(ret)); - } - } else if (OB_FAIL(item.get_int_value(backup_schema_version))) { - LOG_WARN("failed to get int value", K(ret), K(item)); - } - - return ret; -} - -int ObTenantBackupInfoOperation::update_tenant_name_backup_schema_version( - common::ObISQLClient &sql_client, - const int64_t backup_schema_version) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = 0; - // %zone can be empty - if (backup_schema_version <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(backup_schema_version)); - } else if (OB_FAIL(sql.assign_fmt( - "replace into %s(tenant_id, name, value) values(%lu, '%s', %ld)", - OB_ALL_BACKUP_INFO_TNAME, OB_SYS_TENANT_ID, OB_STR_TENANT_NAME_BACKUP_SCHEMA_VERSION, backup_schema_version))) { - LOG_WARN("assign sql failed", K(ret)); - } else if (OB_FAIL(sql_client.write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows))) { - LOG_WARN("execute sql failed", K(ret), K(sql)); - } else { - LOG_INFO("succeed to update_tenant_name_backup_schema_version", K(backup_schema_version)); - } - return ret; -} - -int ObTenantBackupInfoOperation::clean_backup_scheduler_leader( - common::ObISQLClient &sql_client, - const uint64_t tenant_id, - const common::ObAddr &scheduler_leader) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = 0; - char scheduler_leader_str[MAX_IP_PORT_LENGTH] = ""; - - if (tenant_id != OB_SYS_TENANT_ID || !scheduler_leader.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tenant_id), K(scheduler_leader)); - } else if (OB_FAIL(scheduler_leader.ip_port_to_string(scheduler_leader_str, MAX_IP_PORT_LENGTH))) { - LOG_WARN("failed to add addr to buf", K(ret), K(scheduler_leader)); - } else if (OB_FAIL(sql.assign_fmt( - "update %s set value = '' where name = '%s' and value='%s'", - OB_ALL_BACKUP_INFO_TNAME, OB_STR_BACKUP_SCHEDULER_LEADER, scheduler_leader_str))) { - LOG_WARN("assign sql failed", K(ret)); - } else if (OB_FAIL(sql_client.write(tenant_id, sql.ptr(), affected_rows))) { - LOG_WARN("execute sql failed", K(ret), K(sql)); - } else if (0 != affected_rows) { - FLOG_INFO("succeed to clean_backup_scheduler_leader", K(scheduler_leader_str), - K(sql), K(affected_rows)); - } - return ret; - -} - -int ObTenantBackupInfoOperation::update_info_item(common::ObISQLClient &sql_client, - const uint64_t tenant_id, const ObBackupInfoItem &item) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = 0; - // %zone can be empty - if (OB_INVALID_ID == tenant_id || !item.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(item), K(tenant_id)); - } else if (OB_FAIL(sql.assign_fmt( - "UPDATE %s SET value = '%s', gmt_modified = now(6) " - "WHERE tenant_id = %lu AND name = '%s'", OB_ALL_BACKUP_INFO_TNAME, item.value_.ptr(), - tenant_id, item.name_))) { - LOG_WARN("assign sql failed", K(ret)); - } else if (OB_FAIL(sql_client.write(tenant_id, sql.ptr(), affected_rows))) { - LOG_WARN("execute sql failed", K(ret), K(sql)); - } else if (!(is_single_row(affected_rows) || is_zero_row(affected_rows))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected affected rows", K(ret), K(affected_rows)); - } else { - LOG_INFO("execute sql success", K(sql)); - } - return ret; -} - -int ObTenantBackupInfoOperation::remove_base_backup_info( - ObISQLClient &sql_client, - const uint64_t tenant_id) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = 0; - int64_t item_cnt = 0; - if (OB_INVALID_ID == tenant_id) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tenant_id)); - } else if (OB_FAIL(sql.assign_fmt("DELETE FROM %s WHERE tenant_id = %lu", - OB_ALL_BACKUP_INFO_TNAME, tenant_id))) { - LOG_WARN("sql assign_fmt failed", K(ret)); - } else if (OB_FAIL(sql_client.write(tenant_id, sql.ptr(), affected_rows))) { - LOG_WARN("execute sql failed", K(sql), K(ret)); - } else if (OB_FAIL(get_backup_info_item_count(item_cnt))) { - LOG_WARN("get zone item count failed", K(ret)); - } else if (item_cnt != affected_rows) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("affected_rows not right", "expected affected_rows", - item_cnt, K(affected_rows), K(ret)); - } - return ret; -} - -int ObTenantBackupInfoOperation::get_backup_info_item_count(int64_t &cnt) -{ - int ret = OB_SUCCESS; - ObMalloc alloc(ObModIds::OB_TEMP_VARIABLES); - ObPtrGuard base_backup_info_guard(alloc); - if (OB_FAIL(base_backup_info_guard.init())) { - LOG_WARN("init temporary variable failed", K(ret)); - } else if (NULL == base_backup_info_guard.ptr()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("null zone info ptr", K(ret)); - } else { - cnt = base_backup_info_guard.ptr()->get_item_count(); - } - return ret; -} - -int ObTenantBackupInfoOperation::insert_info_item( - common::ObISQLClient &sql_client, - const uint64_t tenant_id, - const ObBackupInfoItem &item) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id); - int64_t affected_rows = 0; - if (OB_INVALID_ID == tenant_id || !item.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(item), K(tenant_id)); - } else if (OB_FAIL(sql.assign_fmt( - "INSERT INTO %s (tenant_id, name, value) VALUES(%lu, '%s', '%s')", - OB_ALL_BACKUP_INFO_TNAME, tenant_id, item.name_, item.value_.ptr()))) { - LOG_WARN("assign sql failed", K(ret)); - } else if (OB_FAIL(sql_client.write(exec_tenant_id, sql.ptr(), affected_rows))) { - LOG_WARN("execute sql failed", K(ret), K(exec_tenant_id), K(sql)); - } else if (!is_single_row(affected_rows)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected affected rows", K(ret), K(affected_rows)); - } else { - LOG_INFO("execute sql success", K(sql)); - } - return ret; -} - -int ObTenantBackupInfoOperation::remove_info_item( - common::ObISQLClient &sql_client, - const uint64_t tenant_id, - const char *name) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = 0; - - if (OB_INVALID_ID == tenant_id || OB_ISNULL(name)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tenant_id), KP(name)); - } else if (OB_FAIL(sql.assign_fmt( - "DELETE FROM %s WHERE name = '%s'", - OB_ALL_BACKUP_INFO_TNAME, name))) { - LOG_WARN("assign sql failed", K(ret)); - } else if (OB_FAIL(sql_client.write(tenant_id, sql.ptr(), affected_rows))) { - LOG_WARN("execute sql failed", K(ret), K(sql)); - } - return ret; - -} - -///////////////////// functions for ObBackupInfoOperator ////////////////////////// -int ObBackupInfoOperator::get_inner_table_version(common::ObISQLClient &sql_proxy, - ObBackupInnerTableVersion &version) -{ - int ret = OB_SUCCESS; - int64_t value = -1; - - if (OB_FAIL(get_int_value_(sql_proxy, false /*for update*/, OB_STR_BACKUP_INNER_TABLE_VERSION, value))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("Failed to get inner table version", K(ret)); - } else { - version = OB_BACKUP_INNER_TABLE_V1; - ret = OB_SUCCESS; - LOG_INFO("inner table version not exist, set as V1", K(ret), K(version)); - } - } else { - version = static_cast(value); - if (!is_valid_backup_inner_table_version(version)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid version", K(ret), K(version)); - } - } - - return ret; -} - -int ObBackupInfoOperator::set_inner_table_version(common::ObISQLClient &sql_proxy, - const ObBackupInnerTableVersion &version) -{ - int ret = OB_SUCCESS; - - if (!is_valid_backup_inner_table_version(version)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(version)); - } else if (OB_FAIL(set_int_value_( - sql_proxy, OB_STR_BACKUP_INNER_TABLE_VERSION, static_cast(version)))) { - LOG_WARN("failed to set int value", K(ret), K(version)); - } - - return ret; -} - -int ObBackupInfoOperator::set_max_piece_id(common::ObISQLClient &sql_proxy, - const int64_t max_piece_id) -{ - int ret = OB_SUCCESS; - const bool for_update = true; - int64_t cur_max_piece_id = 0; - - if (max_piece_id < 0) { - ret = OB_INVALID_ARGUMENT; - LOG_ERROR("invalid args", K(ret), K(max_piece_id)); - } else if (OB_FAIL(get_int_value_(sql_proxy, for_update, OB_STR_MAX_BACKUP_PIECE_ID, cur_max_piece_id))) { - if (OB_ENTRY_NOT_EXIST == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("Failed to get max piece id", K(ret)); - } - } else if (cur_max_piece_id > max_piece_id) { - ret = OB_INVALID_ARGUMENT; - LOG_ERROR("new max piece id must not less than cur max piece id", K(ret), K(max_piece_id), K(cur_max_piece_id)); - } - - if (FAILEDx(set_int_value_(sql_proxy, OB_STR_MAX_BACKUP_PIECE_ID, max_piece_id))) { - LOG_WARN("failed to set int value", K(ret), K(max_piece_id)); - } - - return ret; -} - -int ObBackupInfoOperator::set_max_piece_create_date(common::ObISQLClient &sql_proxy, - const int64_t max_piece_create_date) -{ - int ret = OB_SUCCESS; - - if (max_piece_create_date < 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(max_piece_create_date)); - } else if (OB_FAIL(set_int_value_(sql_proxy, OB_STR_MAX_BACKUP_PIECE_CREATE_DATE, max_piece_create_date))) { - LOG_WARN("failed to set max_piece_create_date", K(ret), K(max_piece_create_date)); - } - - return ret; -} - -int ObBackupInfoOperator::get_tenant_name_backup_schema_version(common::ObISQLClient &sql_proxy, - int64_t &backup_schema_version) -{ - int ret = OB_SUCCESS; - - if (OB_FAIL(get_int_value_(sql_proxy, false /*for update*/,OB_STR_TENANT_NAME_BACKUP_SCHEMA_VERSION, backup_schema_version))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("Failed to get inner table version", K(ret)); - } else { - backup_schema_version = 0; - ret = OB_SUCCESS; - } - } - - return ret; -} - -int ObBackupInfoOperator::get_backup_leader(common::ObISQLClient &sql_proxy, - const bool for_update, - common::ObAddr &leader, bool &has_leader) -{ - int ret = OB_SUCCESS; - char buf[OB_INNER_TABLE_DEFAULT_VALUE_LENTH] = {0}; - leader.reset(); - has_leader = false; - - if (OB_FAIL(get_string_value_(sql_proxy, for_update, OB_STR_BACKUP_SCHEDULER_LEADER, buf, sizeof(buf)))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("failed to get scheduler leader", K(ret)); - } - } else if (0 == strlen(buf)) { - has_leader = false; - } else if (OB_FAIL(leader.parse_from_cstring(buf))) { - LOG_WARN("failed to parse addr", K(ret), K(buf)); - } else { - has_leader = true; - } - - return ret; -} - -int ObBackupInfoOperator::set_backup_leader(common::ObISQLClient &sql_proxy, - const common::ObAddr &leader) -{ - int ret = OB_SUCCESS; - char buf[MAX_IP_PORT_LENGTH] = ""; - - if (!leader.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(leader)); - } else if (OB_FAIL(leader.ip_port_to_string(buf, sizeof(buf)))) { - LOG_WARN("Failed to ip_port_to_string", K(ret), K(leader)); - } else if (OB_FAIL(set_string_value_(sql_proxy, OB_STR_BACKUP_SCHEDULER_LEADER, buf))) { - LOG_WARN("Failed to set backup leader", K(ret), K(leader)); - } - return ret; -} - -int ObBackupInfoOperator::clean_backup_leader(common::ObISQLClient &sql_proxy, - const common::ObAddr &leader) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = 0; - char buf[MAX_IP_PORT_LENGTH] = ""; - - if (!leader.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(leader)); - } else if (OB_FAIL(leader.ip_port_to_string(buf, sizeof(buf)))) { - LOG_WARN("Failed to ip_port_to_string", K(ret), K(leader)); - } else if (OB_FAIL(sql.assign_fmt("update %s set value = '' where name = '%s' and value = '%s'", - OB_ALL_BACKUP_INFO_TNAME, OB_STR_BACKUP_SCHEDULER_LEADER, buf))) { - LOG_WARN("Failed to clean backup leader", K(ret)); - } else if (OB_FAIL(sql_proxy.write(sql.ptr(), affected_rows))) { - LOG_WARN("failed to write sql", K(ret), K(sql)); - } else if (0 != affected_rows) { - FLOG_INFO("succeed to clean backup leader", K(ret), "old_leader", leader); - } - return ret; -} - - -int ObBackupInfoOperator::get_backup_leader_epoch(common::ObISQLClient &sql_proxy, - const bool for_update, int64_t &epoch) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(get_int_value_(sql_proxy, for_update,OB_STR_BACKUP_SCHEDULER_LEADER_EPOCH, epoch))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("Failed to get inner table version", K(ret)); - } else { - epoch = 0; - ret = OB_SUCCESS; - } - } - return ret; -} - -int ObBackupInfoOperator::set_backup_leader_epoch(common::ObISQLClient &sql_proxy, const int64_t epoch) -{ - int ret = OB_SUCCESS; - if (epoch < 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(epoch)); - } else if (OB_FAIL(set_int_value_( - sql_proxy, OB_STR_BACKUP_SCHEDULER_LEADER_EPOCH, epoch))) { - LOG_WARN("failed to set int value", K(ret), K(OB_STR_TENANT_NAME_BACKUP_SCHEMA_VERSION)); - } - return ret; -} - -int ObBackupInfoOperator::get_int_value_(common::ObISQLClient &sql_proxy, const bool for_update, - const char *name, int64_t &value) -{ - int ret = OB_SUCCESS; - char value_str[OB_INNER_TABLE_DEFAULT_VALUE_LENTH] = {0}; - value = -1; - - if (OB_FAIL(get_string_value_(sql_proxy, for_update, name, value_str, sizeof(value_str)))) { - LOG_WARN("failed to get string value", K(ret), K(name)); - } else if (OB_FAIL(ob_atoll(value_str, value))) { - LOG_WARN("failed to parse int", K(ret), K(value_str)); - } - - return ret; -} - -int ObBackupInfoOperator::set_int_value_(common::ObISQLClient &sql_proxy, const char *name, const int64_t &value) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = -1; - ObDMLSqlSplicer dml_splicer; - - if (OB_ISNULL(name)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), KP(name)); - } else if (OB_FAIL(dml_splicer.add_pk_column("tenant_id", OB_SYS_TENANT_ID))) { - LOG_WARN("failed to add column", K(ret)); - } else if (OB_FAIL(dml_splicer.add_pk_column("name", name))) { - LOG_WARN("failed to add column", K(ret), K(name)); - } else if (OB_FAIL(dml_splicer.add_column("value", value))) { - LOG_WARN("failed to add column", K(ret), K(value)); - } else if (OB_FAIL(dml_splicer.splice_insert_update_sql(OB_ALL_BACKUP_INFO_TNAME, sql))) { - LOG_WARN("failed to splice insert update sql", K(ret)); - } else if (OB_FAIL(sql_proxy.write(sql.ptr(), affected_rows))) { - LOG_WARN("failed to write sql", K(ret), K(sql), K(affected_rows)); - } else { - LOG_INFO("succeed to set int value", K(ret), K(name), K(value), K(affected_rows), K(sql)); - } - - return ret; -} - -int ObBackupInfoOperator::get_string_value_(common::ObISQLClient &sql_proxy, const bool for_update, - const char *name, char *buf, int64_t buf_len) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - - if (OB_ISNULL(name)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), KP(name)); - } else { - buf[0] = '\0'; - } - - SMART_VAR(ObMySQLProxy::ReadResult, res) { - sqlclient::ObMySQLResult *result = NULL; - int real_length = 0; - - if (OB_FAIL(sql.assign_fmt("select value from %s where tenant_id=%lu and name = '%s'", OB_ALL_BACKUP_INFO_TNAME, OB_SYS_TENANT_ID, name))) { - LOG_WARN("failed to init sql", K(ret)); - } else if (for_update && OB_FAIL(sql.append(" for update"))) { - LOG_WARN("failed to add for update", K(ret)); - } else if (OB_FAIL(sql_proxy.read(res, sql.ptr()))) { - LOG_WARN("failed to read sql", K(ret), K(sql)); - } else if (OB_ISNULL(result = res.get_result())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("result is null", K(ret), K(sql)); - } else if (OB_FAIL(result->next())) { - if (OB_ITER_END == ret) { - ret = OB_ENTRY_NOT_EXIST; - } else { - LOG_WARN("failed to get next", K(ret), K(sql)); - } - } else { - EXTRACT_STRBUF_FIELD_MYSQL(*result, "value", buf, buf_len, real_length); - if (OB_FAIL(ret)) { - LOG_WARN("failed to extract field", K(ret), K(name), K(sql)); - } - } - - if (OB_SUCC(ret)) { - LOG_INFO("get backup info string value", K(sql), K(name), K(real_length), K(buf)); - if (OB_ISNULL(result)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("result must not be nullptr", K(ret)); - } else { - int tmp_ret = result->next(); - if (OB_ITER_END != tmp_ret) { - char value_str[OB_INNER_TABLE_DEFAULT_VALUE_LENTH] = {0}; - EXTRACT_STRBUF_FIELD_MYSQL(*result, name, value_str, sizeof(value_str), real_length); - ret = OB_SUCCESS == tmp_ret ? OB_ERR_UNEXPECTED : tmp_ret; - LOG_WARN("got more than one row", K(ret), K(tmp_ret), K(name), K(value_str), K(sql)); - } - } - } - } - - return ret; -} - -int ObBackupInfoOperator::set_string_value_( - common::ObISQLClient &sql_proxy, const char *name, const char *value) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - int64_t affected_rows = -1; - ObDMLSqlSplicer dml_splicer; - - if (OB_ISNULL(name) || OB_ISNULL(value)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), KP(name), KP(value)); - } else if (OB_FAIL(dml_splicer.add_pk_column("tenant_id", OB_SYS_TENANT_ID))) { - LOG_WARN("failed to add column", K(ret)); - } else if (OB_FAIL(dml_splicer.add_pk_column("name", name))) { - LOG_WARN("failed to add column", K(ret), K(name)); - } else if (OB_FAIL(dml_splicer.add_column("value", value))) { - LOG_WARN("failed to add column", K(ret), K(value)); - } else if (OB_FAIL(dml_splicer.splice_insert_update_sql(OB_ALL_BACKUP_INFO_TNAME, sql))) { - LOG_WARN("failed to splice insert update sql", K(ret)); - } else if (OB_FAIL(sql_proxy.write(sql.ptr(), affected_rows))) { - LOG_WARN("failed to write sql", K(ret), K(sql), K(affected_rows)); - } else { - LOG_INFO("succeed to set string value", K(ret), K(name), K(value), K(affected_rows), K(sql)); - } - - return ret; - -} - -} //share -} //oceanbase - diff --git a/src/share/backup/ob_backup_operator.h b/src/share/backup/ob_backup_operator.h deleted file mode 100644 index 33c691efb..000000000 --- a/src/share/backup/ob_backup_operator.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright (c) 2021 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_BACKUP_OB_BACKUP_OPERATOR_H_ -#define OCEANBASE_SHARE_BACKUP_OB_BACKUP_OPERATOR_H_ - -#include "lib/net/ob_addr.h" -#include "lib/mysqlclient/ob_mysql_proxy.h" -#include "lib/hash/ob_hashmap.h" -#include "share/ob_dml_sql_splicer.h" -#include "share/schema/ob_table_schema.h" -#include "lib/mysqlclient/ob_mysql_transaction.h" -#include "lib/mysqlclient/ob_mysql_result.h" -#include "ob_backup_struct.h" -#include "ob_backup_manager.h" - -namespace oceanbase -{ -namespace share -{ - -class ObITenantBackupTaskOperator -{ -public: - ObITenantBackupTaskOperator() = default; - virtual ~ObITenantBackupTaskOperator() = default; - static int get_tenant_ids( - const uint64_t tenant_id, - const common::ObSqlString &sql, - common::ObIArray &tenant_ids, - common::ObISQLClient &sql_proxy); -}; - - -class ObTenantBackupInfoOperation -{ -public: - static int update_info_item(common::ObISQLClient &sql_client, - const uint64_t tenant_id, const ObBackupInfoItem &item); - static int get_tenant_list( - common::ObISQLClient &sql_client, common::ObIArray &tenant_id_list); - static int load_base_backup_info(common::ObISQLClient &sql_client, ObBaseBackupInfo &info); - static int remove_base_backup_info(common::ObISQLClient &sql_client, const uint64_t tenant_id); - static int load_info_item( - common::ObISQLClient &sql_client, - const uint64_t tenant_id, ObBackupInfoItem &item, const bool need_lock = true); - static int get_backup_snapshot_version(common::ObISQLClient &sql_proxy, - const uint64_t tenant_id, int64_t &backup_snapshot_version); - static int get_backup_schema_version(common::ObISQLClient &sql_proxy, - const uint64_t tenant_id, int64_t &backup_schema_version); - static int get_tenant_name_backup_schema_version(common::ObISQLClient &sql_proxy, - int64_t &backup_schema_version); - static int update_tenant_name_backup_schema_version(common::ObISQLClient &sql_proxy, - const int64_t backup_schema_version); - static int insert_info_item( - common::ObISQLClient &sql_client, - const uint64_t tenant_id, - const ObBackupInfoItem &item); - static int clean_backup_scheduler_leader( - common::ObISQLClient &sql_client, - const uint64_t tenant_id, - const common::ObAddr &scheduler_leader); - static int remove_info_item( - common::ObISQLClient &sql_client, - const uint64_t tenant_id, - const char *name); -private: - template - static int set_info_item(const char *name, const char *info_str, - T &info); - template - static int load_info(common::ObISQLClient &sql_client, T &info); - template - static int insert_info(common::ObISQLClient &sql_client, T &info); - static int get_backup_info_item_count(int64_t &cnt); - -}; - - // TODO: merge ObBackupInfoOperator into ObTenantBackupInfoOperation. -class ObBackupInfoOperator final -{ -public: - static int get_inner_table_version(common::ObISQLClient &sql_proxy, - ObBackupInnerTableVersion &version); - static int set_inner_table_version(common::ObISQLClient &sql_proxy, - const ObBackupInnerTableVersion &version); - static int set_max_piece_id(common::ObISQLClient &sql_proxy, - const int64_t max_piece_id); - static int set_max_piece_create_date(common::ObISQLClient &sql_proxy, - const int64_t max_piece_create_date); - static int get_tenant_name_backup_schema_version(common::ObISQLClient &sql_proxy, - int64_t &backup_schema_version); - static int get_backup_leader(common::ObISQLClient &sql_proxy, const bool for_update, - common::ObAddr &leader, bool &has_leader); - static int set_backup_leader(common::ObISQLClient &sql_proxy, - const common::ObAddr &leader); - static int clean_backup_leader(common::ObISQLClient &sql_proxy, - const common::ObAddr &leader); - static int get_backup_leader_epoch(common::ObISQLClient &sql_proxy, const bool for_update, int64_t &epoch); - static int set_backup_leader_epoch(common::ObISQLClient &sql_proxy, const int64_t epoch); -private: - static int get_int_value_(common::ObISQLClient &sql_proxy, const bool for_update, - const char *name, int64_t &value); - static int set_int_value_(common::ObISQLClient &sql_proxy, const char *name, const int64_t &value); - static int get_string_value_(common::ObISQLClient &sql_proxy, const bool for_update, - const char *name, char *buf, int64_t buf_len); - static int set_string_value_(common::ObISQLClient &sql_proxy, const char *name, const char *value); -}; - -} // end namespace share -} // end namespace oceanbase - -#endif // OCEANBASE_SHARE_BACKUP_OB_BACKUP_OPERATOR_H_ diff --git a/src/share/backup/ob_backup_path.cpp b/src/share/backup/ob_backup_path.cpp old mode 100644 new mode 100755 index cd773b41b..24721d553 --- a/src/share/backup/ob_backup_path.cpp +++ b/src/share/backup/ob_backup_path.cpp @@ -325,13 +325,38 @@ int ObBackupPath::join_macro_data_file(const int64_t file_id) return ret; } -int ObBackupPath::join_data_info_turn(const int64_t turn_id) +int ObBackupPath::join_tablet_info_file(const int64_t file_id) { int ret = OB_SUCCESS; + char file_name[OB_MAX_BACKUP_PATH_LENGTH] = { 0 }; if (cur_pos_ <= 0) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K(*this)); - } else if (OB_FAIL(databuff_printf(path_, sizeof(path_), cur_pos_, "/%s_%ld", OB_STR_DATA_INTO_TURN, turn_id))) { + } else if (OB_FAIL( + databuff_printf(file_name, sizeof(file_name), "%s.%ld", OB_STR_TABLET_INFO, file_id))) { + LOG_WARN("failed to join macro block data file", K(ret), K(file_id), K(*this)); + } else if (OB_FAIL(join(file_name, ObBackupFileSuffix::BACKUP))) { + LOG_WARN("failed to join file_name", K(ret), K(file_name)); + } else if (OB_FAIL(trim_right_backslash())) { + LOG_WARN("failed to trim right backslash", K(ret)); + } + return ret; +} + +int ObBackupPath::join_data_info_turn(const share::ObBackupDataType &type, const int64_t turn_id) +{ + int ret = OB_SUCCESS; + const char *type_str = ""; + if (cur_pos_ <= 0) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K(*this)); + } else if (type.is_minor_backup()) { + type_str = "minor"; + } else if (type.is_major_backup()) { + type_str = "major"; + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(databuff_printf(path_, sizeof(path_), cur_pos_, "/%s_%s_%ld", type_str, OB_STR_DATA_INTO_TURN, turn_id))) { LOG_WARN("failed to join macro block data file", K(ret), K(turn_id), K(*this)); } else if (OB_FAIL(trim_right_backslash())) { LOG_WARN("failed to trim right backslash", K(ret)); @@ -640,14 +665,14 @@ int ObBackupPathUtil::get_ls_backup_dir_path(const share::ObBackupDest &backup_s // file:///obbackup/backup_set_1_full/log_stream_1/meta_info_turn_1/tablet_info.obbak int ObBackupPathUtil::get_ls_data_tablet_info_path(const share::ObBackupDest &backup_set_dest, - const share::ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, ObBackupPath &path) + const share::ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, const int64_t file_id, ObBackupPath &path) { int ret = OB_SUCCESS; if (OB_FAIL(get_ls_backup_dir_path(backup_set_dest, ls_id, path))) { LOG_WARN("failed to get ls info dir path", K(ret), K(backup_set_dest)); } else if (OB_FAIL(path.join_meta_info_turn_and_retry(turn_id, retry_id))) { LOG_WARN("failed to join info retry", K(ret), K(retry_id)); - } else if (OB_FAIL(path.join(OB_STR_TABLET_INFO, ObBackupFileSuffix::BACKUP))) { + } else if (OB_FAIL(path.join_tablet_info_file(file_id))) { LOG_WARN("failed to join", K(ret)); } return ret; @@ -810,29 +835,30 @@ int ObBackupPathUtil::get_ls_info_dir_path(const share::ObBackupDest &backup_ten return ret; } -// file:///obbackup/backup_set_1_full/infos/data_info_turn_1 +// file:///obbackup/backup_set_1_full/infos/major_data_info_turn_1 int ObBackupPathUtil::get_ls_info_data_info_dir_path(const share::ObBackupDest &backup_set_dest, - const int64_t turn_id, share::ObBackupPath &backup_path) + const share::ObBackupDataType &type, const int64_t turn_id, share::ObBackupPath &backup_path) { int ret = OB_SUCCESS; if (OB_FAIL(get_backup_set_dir_path(backup_set_dest, backup_path))) { LOG_WARN("failed to get backup set dir path", K(ret), K(backup_set_dest)); } else if (OB_FAIL(backup_path.join(ObString::make_string("infos"), ObBackupFileSuffix::NONE))) { LOG_WARN("failed to join data", K(ret)); - } else if (OB_FAIL(backup_path.join_data_info_turn(turn_id))) { + } else if (OB_FAIL(backup_path.join_data_info_turn(type, turn_id))) { LOG_WARN("failed to join info turn", K(ret)); } return ret; } int ObBackupPathUtil::get_ls_info_data_info_dir_path(const share::ObBackupDest &backup_tenant_dest, - const share::ObBackupSetDesc &desc, const int64_t turn_id, share::ObBackupPath &backup_path) + const share::ObBackupSetDesc &desc, const share::ObBackupDataType &type, const int64_t turn_id, + share::ObBackupPath &backup_path) { int ret = OB_SUCCESS; share::ObBackupDest backup_set_dest; if (OB_FAIL(construct_backup_set_dest(backup_tenant_dest, desc, backup_set_dest))) { LOG_WARN("fail to construct backup set dest", K(ret)); - } else if (OB_FAIL(get_ls_info_data_info_dir_path(backup_set_dest, turn_id, backup_path))) { + } else if (OB_FAIL(get_ls_info_data_info_dir_path(backup_set_dest, type, turn_id, backup_path))) { LOG_WARN("fail to get ls backup data dir path", K(ret)); } return ret; @@ -884,6 +910,7 @@ int ObBackupPathUtil::get_backup_ls_attr_info_path(const share::ObBackupDest &ba int ObBackupPathUtil::get_ls_meta_infos_path(const share::ObBackupDest &backup_set_dest, ObBackupPath &backup_path) { int ret = OB_SUCCESS; + char buf[OB_BACKUP_MAX_TIME_STR_LEN] = { 0 }; if (OB_FAIL(get_tenant_meta_info_dir_path(backup_set_dest, backup_path))) { LOG_WARN("failed to get backup set dir path", K(ret), K(backup_set_dest)); } else if (OB_FAIL(backup_path.join(OB_STR_LS_META_INFOS, ObBackupFileSuffix::BACKUP))) { @@ -1033,7 +1060,7 @@ int ObBackupPathUtil::get_tenant_macro_range_index_backup_path(const share::ObBa int ret = OB_SUCCESS; if (OB_FAIL(get_ls_info_dir_path(backup_set_dest, path))) { LOG_WARN("failed to get ls info dir path", K(ret), K(backup_set_dest)); - } else if (OB_FAIL(path.join_data_info_turn(turn_id))) { + } else if (OB_FAIL(path.join_data_info_turn(backup_data_type, turn_id))) { LOG_WARN("failed to join info turn", K(ret)); } else if (OB_FAIL(path.join_tenant_macro_range_index_file(backup_data_type, retry_id))) { LOG_WARN("failed to join tenant macro range index file", K(ret), K(backup_data_type), K(retry_id)); @@ -1064,7 +1091,7 @@ int ObBackupPathUtil::get_tenant_meta_index_backup_path(const share::ObBackupDes int ret = OB_SUCCESS; if (OB_FAIL(get_ls_info_dir_path(backup_set_dest, path))) { LOG_WARN("failed to get ls info dir path", K(ret), K(backup_set_dest)); - } else if (OB_FAIL(path.join_data_info_turn(turn_id))) { + } else if (OB_FAIL(path.join_data_info_turn(backup_data_type, turn_id))) { LOG_WARN("failed to join info turn", K(ret)); } else if (OB_FAIL(path.join_tenant_meta_index_file(backup_data_type, retry_id, is_sec_meta))) { LOG_WARN("failed to join tenant macro range index file", K(ret), K(backup_data_type)); @@ -1089,12 +1116,12 @@ int ObBackupPathUtil::get_tenant_meta_index_backup_path(const share::ObBackupDes // file://obbackup/backup_set_1_full/infos/data_info_turn_1/tablet_log_stream_info.obbak int ObBackupPathUtil::get_backup_data_tablet_ls_info_path(const share::ObBackupDest &backup_set_dest, - const uint64_t turn_id, ObBackupPath &path) + const share::ObBackupDataType &backup_data_type, const uint64_t turn_id, ObBackupPath &path) { int ret = OB_SUCCESS; if (OB_FAIL(get_ls_info_dir_path(backup_set_dest, path))) { LOG_WARN("failed to get ls info dir path", K(ret), K(backup_set_dest)); - } else if (OB_FAIL(path.join_data_info_turn(turn_id))) { + } else if (OB_FAIL(path.join_data_info_turn(backup_data_type, turn_id))) { LOG_WARN("failed to join info turn", K(ret)); } else if (OB_FAIL(path.join(OB_STR_TABLET_LOG_STREAM_INFO, ObBackupFileSuffix::BACKUP))) { LOG_WARN("failed to join tablet_log_stream_info", K(ret)); @@ -1115,6 +1142,21 @@ int ObBackupPathUtil::get_deleted_tablet_info_path(const share::ObBackupDest &ba return ret; } +// file://obbackup/backup_set_1_full/infos/meta_info/tablet_log_stream_info.obbak +int ObBackupPathUtil::get_backup_data_meta_tablet_ls_info_path(const share::ObBackupDest &backup_set_dest, share::ObBackupPath &path) +{ + int ret = OB_SUCCESS; + char buf[OB_BACKUP_MAX_TIME_STR_LEN] = { 0 }; + if (OB_FAIL(get_tenant_meta_info_dir_path(backup_set_dest, path))) { + LOG_WARN("failed to get tenant meta info dir", K(ret)); + } else if (OB_FAIL(databuff_printf(buf, OB_BACKUP_MAX_TIME_STR_LEN, "%s", OB_STR_TABLET_LOG_STREAM_INFO))) { + LOG_WARN("failed to printf ls meta infos", K(ret)); + } else if (OB_FAIL(path.join(buf, ObBackupFileSuffix::BACKUP))) { + LOG_WARN("failed to join ls meta infos", K(ret)); + } + return ret; +} + // file:///obbackup/backup_set_1_full/complement_log/ int ObBackupPathUtil::get_complement_log_dir_path(const share::ObBackupDest &backup_set_dest, ObBackupPath &backup_path) { @@ -1250,4 +1292,4 @@ int ObBackupPathUtil::construct_backup_complement_log_dest(const share::ObBackup LOG_WARN("fail to set backup set dest", K(ret), K(path), K(storage_info_buf)); } return ret; -} \ No newline at end of file +} diff --git a/src/share/backup/ob_backup_path.h b/src/share/backup/ob_backup_path.h old mode 100644 new mode 100755 index 2663e49f8..937086bf5 --- a/src/share/backup/ob_backup_path.h +++ b/src/share/backup/ob_backup_path.h @@ -49,7 +49,8 @@ public: int join_complement_log(); int join_macro_data_dir(const share::ObBackupDataType &type, const int64_t turn_id, const int64_t retry_id); int join_macro_data_file(const int64_t file_id); - int join_data_info_turn(const int64_t turn_id); + int join_tablet_info_file(const int64_t file_id); + int join_data_info_turn(const share::ObBackupDataType &type, const int64_t turn_id); int join_meta_info_turn_and_retry(const int64_t turn_id, const int64_t retry_id); int join_tenant_macro_range_index_file(const share::ObBackupDataType &type, const int64_t retry_id); int join_tenant_meta_index_file(const share::ObBackupDataType &type, const int64_t retry_id, const bool is_sec_meta); @@ -115,7 +116,7 @@ struct ObBackupPathUtil // file:///obbackup/backup_set_1_full/log_stream_1/meta_info_turn_1/tablet_info.obbak static int get_ls_data_tablet_info_path(const share::ObBackupDest &backup_set_dest, - const share::ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, + const share::ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, const int64_t file_id, share::ObBackupPath &backup_path); // file:///obbackup/backup_set_1_full/log_stream_1/major_data_turn_1_retry_0/ @@ -161,12 +162,12 @@ struct ObBackupPathUtil static int get_ls_info_dir_path(const share::ObBackupDest &backup_tenant_dest, const share::ObBackupSetDesc &desc, share::ObBackupPath &backup_path); - // file:///obbackup/backup_set_1_full/infos/data_info_turn_1 + // file:///obbackup/backup_set_1_full/infos/major_data_info_turn_1 static int get_ls_info_data_info_dir_path(const share::ObBackupDest &backup_set_dest, - const int64_t turn_id, share::ObBackupPath &backup_path); + const share::ObBackupDataType &type, const int64_t turn_id, share::ObBackupPath &backup_path); static int get_ls_info_data_info_dir_path(const share::ObBackupDest &backup_tenant_dest, - const share::ObBackupSetDesc &desc, const int64_t turn_id, share::ObBackupPath &backup_path); + const share::ObBackupSetDesc &desc, const share::ObBackupDataType &type, const int64_t turn_id, share::ObBackupPath &backup_path); // file:///obbackup/backup_set_1_full/infos/meta_info/ static int get_tenant_meta_info_dir_path(const share::ObBackupDest &backup_set_dest, @@ -242,7 +243,10 @@ struct ObBackupPathUtil // file://obbackup/backup_set_1_full/infos/data_info_turn_1/tablet_log_stream_info.obbak static int get_backup_data_tablet_ls_info_path(const share::ObBackupDest &backup_set_dest, - const uint64_t turn_id, share::ObBackupPath &path); + const share::ObBackupDataType &backup_data_type, const uint64_t turn_id, share::ObBackupPath &path); + + // file://obbackup/backup_set_1_full/infos/meta_info/tablet_log_stream_info + static int get_backup_data_meta_tablet_ls_info_path(const share::ObBackupDest &backup_set_dest, share::ObBackupPath &path); // file:///obbackup/backup_set_1_full/infos/deleted_tablet_info static int get_deleted_tablet_info_path(const share::ObBackupDest &backup_set_dest, share::ObBackupPath &path); diff --git a/src/share/backup/ob_backup_server_mgr.cpp b/src/share/backup/ob_backup_server_mgr.cpp new file mode 100644 index 000000000..d27d198ae --- /dev/null +++ b/src/share/backup/ob_backup_server_mgr.cpp @@ -0,0 +1,262 @@ +// Copyright (c) 2021 OceanBase +// OceanBase 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. +#define USING_LOG_PREFIX SHARE +#include "ob_backup_server_mgr.h" + +using namespace oceanbase; +using namespace share; +using namespace lib; + +ObBackupServerMgr::ObBackupServerMgr() + : is_inited_(false), + mtx_(), + tenant_id_(OB_INVALID_TENANT_ID), + server_op_(), + unit_op_(), + server_status_array_(), + zone_array_() +{ +} + +int ObBackupServerMgr::init(const uint64_t tenant_id, common::ObMySQLProxy &sql_proxy) +{ + int ret = OB_SUCCESS; + common::ObArray units; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_FAIL(server_op_.init(&sql_proxy))) { + LOG_WARN("fail to init server op", K(ret)); + } else if (OB_FAIL(server_op_.get(server_status_array_))) { + LOG_WARN("fail to get server status info", K(ret)); + } else if (OB_FAIL(unit_op_.init(sql_proxy))) { + LOG_WARN("fail to init unit table operator", K(ret)); + } else if (OB_FAIL(unit_op_.get_units_by_tenant(tenant_id, units))) { + LOG_WARN("fail to get units by tenant", K(ret), K(tenant_id)); + } else if (units.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("units must not be empty", K(ret), K(tenant_id)); + } else { + zone_array_.reset(); + ARRAY_FOREACH_X(units, i, cur, OB_SUCC(ret)) { + const share::ObUnit &unit = units.at(i); + if (OB_FAIL(zone_array_.push_back(unit.zone_))) { + LOG_WARN("fail to push back zone", K(ret), K(unit)); + } + } + if (OB_SUCC(ret)) { + tenant_id_ = tenant_id; + is_inited_ = true; + } + } + return ret; +} + +int ObBackupServerMgr::get_alive_servers( + const bool force_update, const common::ObZone &zone, common::ObIArray &server_list) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (zone.is_empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(zone)); + } else if (force_update) { + ObMutexGuard guard(mtx_); + if (OB_FAIL(update_server_())) { + LOG_WARN("failed to update server", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else { + ObMutexGuard guard(mtx_); + ARRAY_FOREACH(server_status_array_, i) { + if (server_status_array_[i].zone_ == zone && server_status_array_.at(i).is_alive()) { + if (OB_FAIL(server_list.push_back(server_status_array_[i].server_))) { + LOG_WARN("push back to server_list failed", K(ret)); + } + } + } + } + return ret; +} + +int ObBackupServerMgr::get_alive_servers( + const bool force_update, common::ObIArray &server_list) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (force_update) { + ObMutexGuard guard(mtx_); + if (OB_FAIL(update_zone_())) { + LOG_WARN("failed to update zone", K(ret)); + } else if (OB_FAIL(update_server_())) { + LOG_WARN("failed to update server", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else { + ObMutexGuard guard(mtx_); + ARRAY_FOREACH(server_status_array_, i) { + if (OB_FAIL(server_list.push_back(server_status_array_.at(i).server_))) { + LOG_WARN("failed to push server server", K(ret)); + } + } + } + return ret; +} + +int ObBackupServerMgr::get_zone_list(const bool force_update, ObIArray &zone_list) +{ + int ret = OB_SUCCESS; + zone_list.reset(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (force_update) { + ObMutexGuard guard(mtx_); + if (OB_FAIL(update_zone_())) { + LOG_WARN("failed to update zone", K(ret)); + } + } + + ObMutexGuard guard(mtx_); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(append(zone_list, zone_array_))) { + LOG_WARN("failed to append zone list", K(zone_array_)); + } + return ret; +} + +int ObBackupServerMgr::get_server_status( + const common::ObAddr &server, const bool force_update, ObServerStatus &server_status) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (!server.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid server", K(server), K(ret)); + } else if (force_update) { + ObMutexGuard guard(mtx_); + if (OB_FAIL(update_server_())) { + LOG_WARN("failed to update server", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else { + ObMutexGuard guard(mtx_); + const ObServerStatus *status_ptr = nullptr; + if (OB_FAIL(find_(server, status_ptr))) { + LOG_WARN("find failed", K(server), K(ret)); + } else if (OB_ISNULL(status_ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status_ptr is null", "status_ptr", OB_P(status_ptr), K(ret)); + } else { + server_status = *status_ptr; + } + } + return ret; +} + +int ObBackupServerMgr::is_server_exist(const common::ObAddr &server, const bool force_update, bool &exist) +{ + int ret = OB_SUCCESS; + exist = false; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (!server.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid server", K(server), K(ret)); + } else if (force_update) { + ObMutexGuard guard(mtx_); + if (OB_FAIL(update_server_())) { + LOG_WARN("failed update server", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else { + ObMutexGuard guard(mtx_); + const ObServerStatus *status_ptr = NULL; + if (OB_FAIL(find_(server, status_ptr))) { + LOG_WARN("find failed", K(server), K(ret)); + ret = OB_SUCCESS; + exist = false; + } else if (OB_ISNULL(status_ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("status_ptr is null", "status_ptr", OB_P(status_ptr), K(ret)); + } else { + exist = true; + } + } + return ret; +} + +int ObBackupServerMgr::update_zone_() +{ + int ret = OB_SUCCESS; + zone_array_.reset(); + common::ObArray units; + if (OB_FAIL(unit_op_.get_units_by_tenant(tenant_id_, units))) { + LOG_WARN("fail to init unit table operator", K(ret), K(tenant_id_)); + } else if (units.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("units must not be empty", K(ret), K(tenant_id_)); + } + ARRAY_FOREACH_X(units, i, cur, OB_SUCC(ret)) { + const share::ObUnit &unit = units.at(i); + if (OB_FAIL(zone_array_.push_back(unit.zone_))) { + LOG_WARN("fail to push back zone", K(ret), K(unit)); + } + } + return ret; +} + +int ObBackupServerMgr::update_server_() +{ + int ret = OB_SUCCESS; + server_status_array_.reset(); + if (OB_FAIL(server_op_.get(server_status_array_))) { + LOG_WARN("failed to get server status array", K(ret)); + } + return ret; +} + +int ObBackupServerMgr::find_(const ObAddr &server, const ObServerStatus *&status) const +{ + int ret = OB_SUCCESS; + status = NULL; + if (!server.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid server", K(server), K(ret)); + } else { + bool find = false; + for (int64_t i = 0; i < server_status_array_.count() && !find; ++i) { + if (server_status_array_[i].server_ == server) { + status = &server_status_array_[i]; + find = true; + } + } + if (!find) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("server not exist", K(server), K(ret)); + } + } + return ret; +} \ No newline at end of file diff --git a/src/share/backup/ob_backup_server_mgr.h b/src/share/backup/ob_backup_server_mgr.h new file mode 100644 index 000000000..a03ae4a4d --- /dev/null +++ b/src/share/backup/ob_backup_server_mgr.h @@ -0,0 +1,57 @@ +// Copyright (c) 2021 OceanBase +// OceanBase 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_OB_BACKUP_DATA_SERVER_MGR_H_ +#define OCEANBASE_SHARE_OB_BACKUP_DATA_SERVER_MGR_H_ + +#include "lib/mysqlclient/ob_mysql_proxy.h" +#include "lib/container/ob_iarray.h" +#include "share/ob_server_table_operator.h" +#include "share/ob_unit_table_operator.h" +#include "lib/lock/ob_mutex.h" +namespace oceanbase +{ + +namespace share +{ + +class ObBackupServerMgr final +{ +public: + ObBackupServerMgr(); + ~ObBackupServerMgr() {} + int init(const uint64_t tenant_id, common::ObMySQLProxy &sql_proxy); + int get_alive_servers( + const bool force_update, const common::ObZone &zone, common::ObIArray &server_list); + int get_alive_servers(const bool force_update, common::ObIArray &server_list); + int get_zone_list(const bool force_update, ObIArray &zone_list); + + int get_server_status(const common::ObAddr &server, const bool force_update, ObServerStatus &server_status); + int is_server_exist(const common::ObAddr &server, const bool force_update, bool &exist); +private: + int find_(const ObAddr &server, const ObServerStatus *&status) const; + int update_zone_(); + int update_server_(); +private: + bool is_inited_; + lib::ObMutex mtx_; + + uint64_t tenant_id_; + ObServerTableOperator server_op_; + share::ObUnitTableOperator unit_op_; + ObArray server_status_array_; + ObArray zone_array_; + DISALLOW_COPY_AND_ASSIGN(ObBackupServerMgr); +}; + +}//end namespace share +}//end namespace oceanbase + +#endif // OCEANBASE_SHARE_OB_BACKUP_DATA_SERVER_MGR_H_ diff --git a/src/share/backup/ob_backup_store.cpp b/src/share/backup/ob_backup_store.cpp index e39c09320..9a4d7cefd 100644 --- a/src/share/backup/ob_backup_store.cpp +++ b/src/share/backup/ob_backup_store.cpp @@ -18,6 +18,7 @@ #include "share/schema/ob_multi_version_schema_service.h" #include "share/backup/ob_backup_data_table_operator.h" #include "share/backup/ob_archive_persist_helper.h" +#include "share/backup/ob_backup_path.h" using namespace oceanbase; using namespace common; @@ -505,7 +506,6 @@ int ObBackupDestMgr::generate_format_desc_( LOG_WARN("failed to get backup path", K(ret), K(backup_dest_)); } else { format_desc.tenant_id_ = tenant_id_; - // TODO: use real incarnation later. format_desc.incarnation_ = OB_START_INCARNATION; format_desc.dest_id_ = dest_id; format_desc.dest_type_ = dest_type; diff --git a/src/share/backup/ob_backup_store.h b/src/share/backup/ob_backup_store.h index 67633cef1..2b6ed6950 100644 --- a/src/share/backup/ob_backup_store.h +++ b/src/share/backup/ob_backup_store.h @@ -100,6 +100,23 @@ public: K_(tenant_id), K_(incarnation)); }; +class ObExternBackupDataDesc : public share::ObIBackupSerializeProvider +{ +public: + explicit ObExternBackupDataDesc(uint16_t type, uint16_t version) + : type_(type), version_(version) {} + virtual ~ObExternBackupDataDesc() {} + + uint16_t get_data_type() const override { return type_; } + uint16_t get_data_version() const override { return version_; } + uint16_t get_compressor_type() const override { return ObCompressorType::NONE_COMPRESSOR; } + + VIRTUAL_TO_STRING_KV(K_(type), K_(version)); +private: + uint16_t type_; + uint16_t version_; +}; + class ObBackupStore { public: diff --git a/src/share/backup/ob_backup_struct.cpp b/src/share/backup/ob_backup_struct.cpp old mode 100644 new mode 100755 index f8974a514..aa4343dbd --- a/src/share/backup/ob_backup_struct.cpp +++ b/src/share/backup/ob_backup_struct.cpp @@ -21,9 +21,8 @@ #include "share/schema/ob_multi_version_schema_service.h" #include "share/backup/ob_backup_path.h" #include "share/backup/ob_backup_config.h" -#include "share/backup/ob_backup_lease_info_mgr.h" #include "storage/tx/ob_i_ts_source.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" #include "share/backup/ob_archive_struct.h" #include "storage/tx/ob_ts_mgr.h" @@ -2125,7 +2124,11 @@ bool ObBackupUtils::is_need_retry_error(const int err) case OB_BACKUP_FILE_NOT_EXIST : case OB_LOG_ARCHIVE_INTERRUPTED : case OB_LOG_ARCHIVE_NOT_RUNNING : + case OB_BACKUP_CAN_NOT_START : + case OB_BACKUP_IN_PROGRESS : + case OB_TABLET_NOT_EXIST : case OB_CHECKSUM_ERROR : + case OB_VERSION_NOT_MATCH: bret = false; break; default: @@ -2134,42 +2137,6 @@ bool ObBackupUtils::is_need_retry_error(const int err) return bret; } -int ObBackupUtils::retry_get_tenant_schema_guard( - const uint64_t tenant_id, - schema::ObMultiVersionSchemaService &schema_service, - const int64_t tenant_schema_version, - schema::ObSchemaGetterGuard &schema_guard) -{ - int ret = OB_SUCCESS; - const schema::ObMultiVersionSchemaService::RefreshSchemaMode refresh_mode = - schema::ObMultiVersionSchemaService::RefreshSchemaMode::FORCE_FALLBACK; - - if (OB_UNLIKELY(OB_INVALID_ID == tenant_id - || tenant_schema_version < OB_INVALID_VERSION)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(tenant_id), K(tenant_schema_version)); - } else { - int retry_times = 0; - const int64_t sys_schema_version = OB_INVALID_VERSION;//sys_schema_version use latest - while (retry_times < MAX_RETRY_TIMES) { - if (OB_FAIL(schema_service.get_tenant_schema_guard( - tenant_id, - schema_guard, - tenant_schema_version, - sys_schema_version, - refresh_mode))) { - STORAGE_LOG(WARN, "fail to get schema, sleep 1s and retry", - K(ret), K(tenant_id), K(tenant_schema_version), K(sys_schema_version)); - ob_usleep(RETRY_INTERVAL); - } else { - break; - } - ++retry_times; - } - } - return ret; -} - int ObBackupUtils::convert_timestamp_to_date( const int64_t snapshot_version, int64_t &date) @@ -2338,30 +2305,6 @@ int ObBackupUtils::check_is_tmp_file(const common::ObString &file_name, bool &is return ret; } -int ObBackupUtils::calc_start_replay_scn( - const share::ObBackupSetTaskAttr &set_task_attr, - const share::ObBackupLSMetaInfosDesc &ls_meta_infos, - const share::ObTenantArchiveRoundAttr &round_attr, - share::SCN &start_replay_scn) -{ - int ret = OB_SUCCESS; - SCN tmp_start_replay_scn = set_task_attr.start_scn_; - // To ensure that restore can be successfully initiated, - // we need to avoid clearing too many logs and the start_replay_scn less than the start_scn of the first piece. - // so we choose the minimum palf_base_info.prev_log_info_.scn firstly, to ensure keep enough logs. - // Then we choose the max(minimum palf_base_info.prev_log_info_.scn, round_attr.start_scn) as the start_replay_scn, - // to ensure the start_replay_scn is greater than the start scn of first piece - ARRAY_FOREACH_X(ls_meta_infos.ls_meta_packages_, i, cnt, OB_SUCC(ret)) { - const palf::PalfBaseInfo &palf_base_info = ls_meta_infos.ls_meta_packages_.at(i).palf_meta_; - tmp_start_replay_scn = SCN::min(tmp_start_replay_scn, palf_base_info.prev_log_info_.scn_); - } - if (OB_SUCC(ret)) { - start_replay_scn = SCN::max(tmp_start_replay_scn, round_attr.start_scn_); - LOG_INFO("calculate start replay scn finish", K(start_replay_scn), K(ls_meta_infos), K(round_attr)); - } - return ret; -} - ObPhysicalRestoreInfo::ObPhysicalRestoreInfo() : cluster_id_(0), incarnation_(0), @@ -3060,6 +3003,7 @@ int ObBackupStatus::set_status(const char *str) for (int64_t i = 0; i < count; ++i) { if (0 == s.case_compare(status_strs[i])) { status_ = static_cast(i); + break; } } } @@ -3069,7 +3013,7 @@ int ObBackupStatus::set_status(const char *str) int ObBackupStatus::get_backup_data_type(share::ObBackupDataType &backup_data_type) const { int ret = OB_SUCCESS; - if (BACKUP_DATA_SYS == status_) { + if (BACKUP_USER_META == status_) { backup_data_type.set_sys_data_backup(); } else if (BACKUP_DATA_MINOR == status_) { backup_data_type.set_minor_data_backup(); @@ -3194,6 +3138,102 @@ void ObBackupStats::reset() finish_file_count_ = 0; } +ObHAResultInfo::ObHAResultInfo( + const FailedType &type, + const ObLSID &ls_id, + const ObAddr &addr, + const ObTaskId &trace_id, + const int result) +{ + type_ = type; + ls_id_ = ls_id; + trace_id_ = trace_id; + addr_ = addr; + result_ = result; +} + +ObHAResultInfo::ObHAResultInfo( + const FailedType &type, + const ObAddr &addr, + const ObTaskId &trace_id, + const int result) +{ + type_ = type; + trace_id_ = trace_id; + addr_ = addr; + result_ = result; +} + +const char *ObHAResultInfo::get_failed_type_str() const +{ + const char *ret = ""; + const char *type_strs[] = { + "ROOT_SERVICE", + "RESTORE_DATA", + "RESTORE_CLOG", + "BACKUP_DATA", + "BACKUP_CLEAN" + }; + if (type_ < ROOT_SERVICE || type_ >= MAX_FAILED_TYPE) { + LOG_ERROR_RET(OB_ERR_UNEXPECTED, "invalid failed type", K(type_)); + } else { + ret = type_strs[type_]; + } + return ret; +} + +bool ObHAResultInfo::is_valid() const +{ + return !trace_id_.is_invalid() && addr_.is_valid() && MAX_FAILED_TYPE > type_ && ROOT_SERVICE <= type_; +} + +int ObHAResultInfo::get_comment_str(Comment &comment) const +{ + int ret = OB_SUCCESS; + const char *type = get_failed_type_str(); + char trace_id[OB_MAX_TRACE_ID_BUFFER_SIZE] = ""; + char addr_buf[OB_MAX_SERVER_ADDR_SIZE] = ""; + const char *err_code_str = OB_SUCCESS == result_ ? "" : common::ob_strerror(result_); + if (!is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid result info", K(ret), KPC(this)); + } else if (OB_SUCCESS == result_) { // empty comment when result is OB_SUCCESS + } else if (OB_FALSE_IT(trace_id_.to_string(trace_id, OB_MAX_TRACE_ID_BUFFER_SIZE))) { + } else if (OB_FAIL(addr_.ip_port_to_string(addr_buf, OB_MAX_SERVER_ADDR_SIZE))) { + LOG_WARN("failed to convert addr to string", K(ret), K(addr_)); + } else if (ROOT_SERVICE == type_) { + if (OB_FAIL(databuff_printf(comment.ptr(), comment.capacity(), + "(ROOTSERVICE)addr: %.*s, result: %d(%s), trace_id: %.*s", + static_cast(OB_MAX_SERVER_ADDR_SIZE), addr_buf, + result_, + err_code_str, + static_cast(OB_MAX_TRACE_ID_BUFFER_SIZE), trace_id))) { + LOG_WARN("failed to fill comment", K(ret)); + } + } else if (OB_FAIL(databuff_printf(comment.ptr(), comment.capacity(), + "(SERVER)ls_id: %lu, addr: %.*s, module: %s, result: %d(%s), trace_id: %.*s", + ls_id_.id(), + static_cast(OB_MAX_SERVER_ADDR_SIZE), addr_buf, + type, + result_, + err_code_str, + static_cast(OB_MAX_TRACE_ID_BUFFER_SIZE), trace_id))) { + LOG_WARN("failed to fill comment", K(ret)); + } + return ret; +} + +int ObHAResultInfo::assign(const ObHAResultInfo &that) +{ + int ret = OB_SUCCESS; + type_ = that.type_; + trace_id_ = that.trace_id_; + ls_id_ = that.ls_id_; + addr_ = that.addr_; + result_ = that.result_; + return ret; +} + ObBackupJobAttr::ObBackupJobAttr() : job_id_(0), tenant_id_(0), @@ -3214,7 +3254,8 @@ ObBackupJobAttr::ObBackupJobAttr() status_(), result_(0), can_retry_(true), - retry_count_(0) + retry_count_(0), + comment_() { } @@ -3232,6 +3273,8 @@ int ObBackupJobAttr::assign(const ObBackupJobAttr &other) LOG_WARN("failed to assign passwd", K(ret), K(other.passwd_)); } else if (OB_FAIL(executor_tenant_id_.assign(other.executor_tenant_id_))) { LOG_WARN("failed to assign backup tenant id", K(ret), K(other.executor_tenant_id_)); + } else if (OB_FAIL(comment_.assign(other.comment_))) { + LOG_WARN("failed to assign comment", K(ret)); } else { job_id_ = other.job_id_; tenant_id_ = other.tenant_id_; @@ -3361,21 +3404,20 @@ bool ObBackupJobAttr::is_valid() const bool ObBackupDataTaskType::is_valid() const { - return type_ >= Type::BACKUP_DATA_SYS && type_ < Type::BACKUP_MAX; + return type_ >= Type::BACKUP_META && type_ < Type::BACKUP_MAX; } const char* ObBackupDataTaskType::get_str() const { const char *str = "UNKNOWN"; const char *type_strs[] = { - "BACKUP_DATA_SYS", + "BACKUP_META", "BACKUP_DATA_MINOR", "BACKUP_DATA_MAJOR", "PLUS_ARCHIVE_LOG", - "BUILD_INDEX", - "BACKUP_META" + "BUILD_INDEX" }; - if (type_ < Type::BACKUP_DATA_SYS || type_ >= Type::BACKUP_MAX) { + if (type_ < Type::BACKUP_META || type_ >= Type::BACKUP_MAX) { LOG_ERROR_RET(OB_ERR_UNEXPECTED, "invalid compressor type", K(type_)); } else { str = type_strs[type_]; @@ -3388,12 +3430,11 @@ int ObBackupDataTaskType::set_type(const char *buf) int ret = OB_SUCCESS; ObString s(buf); const char *type_strs[] = { - "BACKUP_DATA_SYS", + "BACKUP_META", "BACKUP_DATA_MINOR", "BACKUP_DATA_MAJOR", "PLUS_ARCHIVE_LOG", "BUILD_INDEX", - "BACKUP_META" }; const int64_t count = ARRAYSIZEOF(type_strs); if (s.empty()) { @@ -3415,7 +3456,7 @@ int ObBackupDataTaskType::get_backup_data_type(share::ObBackupDataType &backup_d if (!is_backup_data()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("not suitable backup type", K(ret)); - } else if (BACKUP_DATA_SYS == type_) { + } else if (BACKUP_META == type_) { backup_data_type.set_sys_data_backup(); } else if (BACKUP_DATA_MINOR == type_) { backup_data_type.set_minor_data_backup(); @@ -3438,13 +3479,16 @@ ObBackupSetTaskAttr::ObBackupSetTaskAttr() user_ls_start_scn_(), data_turn_id_(0), meta_turn_id_(0), + minor_turn_id_(0), + major_turn_id_(0), status_(), encryption_mode_(ObBackupEncryptionMode::EncryptionMode::NONE), passwd_(), stats_(), backup_path_(0), retry_cnt_(0), - result_(0) + result_(0), + comment_() { } @@ -3469,6 +3513,8 @@ int ObBackupSetTaskAttr::assign(const ObBackupSetTaskAttr &other) LOG_WARN("failed to assign passwd", K(ret)); } else if (OB_FAIL(backup_path_.assign(other.backup_path_.ptr()))) { LOG_WARN("failed to assign backup path", K(ret), K(other.backup_path_)); + } else if (OB_FAIL(comment_.assign(other.comment_))) { + LOG_WARN("failed to assign comment", K(ret)); } else { stats_.assign(other.stats_); incarnation_id_ = other.incarnation_id_; @@ -3485,6 +3531,8 @@ int ObBackupSetTaskAttr::assign(const ObBackupSetTaskAttr &other) meta_turn_id_ = other.meta_turn_id_; user_ls_start_scn_ = other.user_ls_start_scn_; retry_cnt_ = other.retry_cnt_; + minor_turn_id_ = other.minor_turn_id_; + major_turn_id_ = other.major_turn_id_; } return ret; } @@ -3508,7 +3556,9 @@ ObBackupLSTaskAttr::ObBackupLSTaskAttr() start_turn_id_(0), turn_id_(0), retry_id_(0), - result_(0) + result_(0), + comment_(), + max_tablet_checkpoint_scn_() { } @@ -3522,7 +3572,8 @@ bool ObBackupLSTaskAttr::is_valid() const && backup_type_.is_valid() && status_.is_valid() && start_ts_ > 0 - && turn_id_ > 0; + && turn_id_ > 0 + && max_tablet_checkpoint_scn_.is_valid(); } int ObBackupLSTaskAttr::get_black_server_str(const ObIArray &black_servers, ObSqlString &sql_string) const @@ -3585,6 +3636,8 @@ int ObBackupLSTaskAttr::assign(const ObBackupLSTaskAttr &other) LOG_WARN("invalid argument", K(ret), K(other)); } else if (OB_FAIL(append(black_servers_, other.black_servers_))) { LOG_WARN("failed to append black servers", K(ret)); + } else if (OB_FAIL(comment_.assign(other.comment_))) { + LOG_WARN("failed to assign comment", K(ret)); } else { stats_.assign(other.stats_); task_id_ = other.task_id_; @@ -3604,6 +3657,7 @@ int ObBackupLSTaskAttr::assign(const ObBackupLSTaskAttr &other) turn_id_ = other.turn_id_; retry_id_ = other.retry_id_; result_ = other.result_; + max_tablet_checkpoint_scn_ = other.max_tablet_checkpoint_scn_; } return ret; } @@ -3611,7 +3665,8 @@ int ObBackupLSTaskAttr::assign(const ObBackupLSTaskAttr &other) OB_SERIALIZE_MEMBER(ObBackupSetFileDesc, backup_set_id_, incarnation_, tenant_id_, dest_id_, backup_type_, plus_archivelog_, date_, prev_full_backup_set_id_, prev_inc_backup_set_id_, stats_, start_time_, end_time_, status_, result_, encryption_mode_, passwd_, file_status_, backup_path_, start_replay_scn_, min_restore_scn_, - tenant_compatible_, backup_compatible_, data_turn_id_, meta_turn_id_, cluster_version_); + tenant_compatible_, backup_compatible_, data_turn_id_, meta_turn_id_, cluster_version_, + minor_turn_id_, major_turn_id_, consistent_scn_); ObBackupSetFileDesc::ObBackupSetFileDesc() : backup_set_id_(0), @@ -3638,7 +3693,10 @@ ObBackupSetFileDesc::ObBackupSetFileDesc() backup_compatible_(Compatible::MAX_COMPATIBLE_VERSION), data_turn_id_(0), meta_turn_id_(0), - cluster_version_(0) + cluster_version_(0), + minor_turn_id_(0), + major_turn_id_(0), + consistent_scn_() { } @@ -3669,6 +3727,9 @@ void ObBackupSetFileDesc::reset() data_turn_id_ = 0; meta_turn_id_ = 0; cluster_version_ = 0; + minor_turn_id_ = 0; + major_turn_id_ = 0; + consistent_scn_.reset(); } @@ -3805,31 +3866,34 @@ int ObBackupSetFileDesc::assign(const ObBackupSetFileDesc &other) data_turn_id_ = other.data_turn_id_; meta_turn_id_ = other.meta_turn_id_; cluster_version_ = other.cluster_version_; + minor_turn_id_ = other.minor_turn_id_; + major_turn_id_ = other.major_turn_id_; + consistent_scn_ = other.consistent_scn_; } return ret; } ObBackupSkipTabletAttr::ObBackupSkipTabletAttr() - : task_id_(0), - tenant_id_(0), - turn_id_(0), - retry_id_(0), - backup_set_id_(0), - tablet_id_(0), - ls_id_(), + : tablet_id_(), skipped_type_() { } +int ObBackupSkipTabletAttr::assign(const ObBackupSkipTabletAttr &that) +{ + int ret = OB_SUCCESS; + if (!that.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(that)); + } else { + tablet_id_ = that.tablet_id_; + skipped_type_ = that.skipped_type_; + } + return ret; +} bool ObBackupSkipTabletAttr::is_valid() const { - return task_id_ > 0 - && tenant_id_ > 0 - && turn_id_ > 0 - && retry_id_ > 0 - && tablet_id_.is_valid() - && backup_set_id_ > 0 - && ls_id_.is_valid() + return tablet_id_.is_valid() && skipped_type_.is_valid(); } diff --git a/src/share/backup/ob_backup_struct.h b/src/share/backup/ob_backup_struct.h old mode 100644 new mode 100755 index d611556b2..8afba7eb1 --- a/src/share/backup/ob_backup_struct.h +++ b/src/share/backup/ob_backup_struct.h @@ -31,6 +31,11 @@ namespace oceanbase { + +namespace storage +{ +class ObBackupLSMetaInfosDesc; //TODO(chongrong): fix namespace circular dependency +} namespace share { @@ -100,12 +105,10 @@ const int64_t OB_MAX_COMPAT_MODE_STR_LEN = 6; //ORACLE/MYSQL const int64_t OB_MAX_RESTORE_USER_AND_TENANT_LEN = OB_MAX_ORIGINAL_NANE_LENGTH + OB_MAX_USER_NAME_LENGTH + 1; const int64_t OB_MAX_RESTORE_TYPE_LEN = 8; // LOCATION/SERVICE/RAWPATH - // TODO add tenant BACKUP_META_TIMEOUT parameters in 4.1 -static const int64_t OB_MAX_BACKUP_META_TIMEOUT = 30 * 60 * 1000 * 1000; // 30 min - static constexpr const int64_t MAX_FAKE_PROVIDE_ITEM_COUNT = 128; static constexpr const int64_t DEFAULT_FAKE_BATCH_COUNT = 32; static constexpr const int64_t FAKE_MAX_FILE_ID = MAX_FAKE_PROVIDE_ITEM_COUNT / DEFAULT_FAKE_BATCH_COUNT - 1; +static constexpr const int64_t OB_COMMENT_LENGTH = 1024; static constexpr const int64_t DEFAULT_ARCHIVE_FILE_SIZE = 64 << 20; // 64MB @@ -324,6 +327,7 @@ const char *const OB_STR_ROLE = "role"; const char *const OB_STR_USER_LS_START_SCN = "user_ls_start_scn"; const char *const OB_STR_CHECKPOINT_SCN = "checkpoint_scn"; const char *const OB_STR_MAX_SCN = "max_scn"; +const char *const OB_STR_MAX_TABLET_CHECKPOINT_SCN = "max_tablet_checkpoint_scn"; const char *const OB_STR_BASE_PIECE_ID = "base_piece_id"; const char *const OB_STR_USED_PIECE_ID = "used_piece_id"; const char *const OB_STR_BASE_PIECE_SCN = "base_piece_scn"; @@ -394,6 +398,15 @@ const char *const OB_STR_BACKUP_SET_LIST = "backup_set_list"; const char *const OB_STR_BACKUP_PIECE_LIST = "backup_piece_list"; const char *const OB_STR_LOG_PATH_LIST = "log_path_list"; const char *const OB_STR_LS_META_INFOS = "ls_meta_infos"; +const char *const OB_STR_TRANSFER_SEQ = "transfer_seq"; +const char *const OB_STR_TRANSFER_SRC_LS_ID = "transfer_src_ls_id"; +const char *const OB_STR_TRANSFER_SRC_SEQ = "transfer_src_seq"; +const char *const OB_STR_TRANSFER_DEST_LS_ID = "transfer_dest_ls_id"; +const char *const OB_STR_TRANSFER_DEST_SEQ = "transfer_dest_seq"; +const char *const OB_STR_BACKUP_LS_ID = "backup_ls_id"; +const char *const OB_STR_MINOR_TURN_ID = "minor_turn_id"; +const char *const OB_STR_MAJOR_TURN_ID = "major_turn_id"; +const char *const OB_STR_CONSISTENT_SCN = "consistent_scn"; const char *const OB_STR_ROOT_KEY = "root_key"; const char *const OB_STR_BACKUP_DATA_VERSION = "backup_data_version"; const char *const OB_STR_CLUSTER_VERSION = "cluster_version"; @@ -439,6 +452,7 @@ enum ObBackupFileType BACKUP_LS_META_INFOS_FILE = 34, BACKUP_TENANT_ARCHIVE_PIECE_INFOS = 35, BACKUP_DELETED_TABLET_INFO = 36, + BACKUP_TABLET_METAS_INFO = 37, // type <=255 is write header struct to disk directly // type > 255 is use serialization to disk BACKUP_MAX_DIRECT_WRITE_TYPE = 255, @@ -984,9 +998,7 @@ public: }; class ObBackupPath; -class ObIBackupLeaseService; class ObBackupSetTaskAttr; -class ObBackupLSMetaInfosDesc; class ObTenantArchiveRoundAttr; class ObBackupUtils { @@ -995,11 +1007,6 @@ public: virtual ~ObBackupUtils() {} static int get_backup_info_default_timeout_ctx(common::ObTimeoutCtx &ctx); static bool is_need_retry_error(const int err); - static int retry_get_tenant_schema_guard( - const uint64_t tenant_id, - schema::ObMultiVersionSchemaService &schema_service, - const int64_t tenant_schema_version, - schema::ObSchemaGetterGuard &schema_guard); //format input string split with ',' or ';' template static int parse_backup_format_input( @@ -1013,11 +1020,6 @@ public: static bool can_backup_pieces_be_deleted(const ObBackupPieceStatus::STATUS &status); static int check_passwd(const char *passwd_array, const char *passwd); static int check_is_tmp_file(const common::ObString &file_name, bool &is_tmp_file); - static int calc_start_replay_scn( - const share::ObBackupSetTaskAttr &set_task_attr, - const share::ObBackupLSMetaInfosDesc &ls_meta_infos, - const share::ObTenantArchiveRoundAttr &round_attr, - share::SCN &start_replay_scn); static int get_backup_scn(const uint64_t &tenant_id, share::SCN &scn); static int check_tenant_data_version_match(const uint64_t tenant_id, const uint64_t data_version); static int get_full_replica_num(const uint64_t tenant_id, int64_t &replica_num); @@ -1216,7 +1218,14 @@ public: ObBackupStatus(const Status &status): status_(status) {} virtual ~ObBackupStatus() = default; ObBackupStatus &operator=(const Status &status); + operator Status() const { return status_; } bool is_valid() const; + + bool is_backup_meta() const { return BACKUP_SYS_META == status_ || BACKUP_USER_META == status_; } + bool is_backup_major() const { return BACKUP_DATA_MAJOR == status_; } + bool is_backup_minor() const { return BACKUP_DATA_MINOR == status_; } + bool is_backup_log() const { return BACKUP_LOG == status_; } + bool is_backup_sys() const { return BACKUP_DATA_SYS == status_; } const char* get_str() const; int set_status(const char *str); int get_backup_data_type(share::ObBackupDataType &backup_data_type) const; @@ -1302,6 +1311,33 @@ public: Level level_; }; +struct ObHAResultInfo +{ +public: + using Comment = common::ObFixedLengthString; + enum FailedType { + ROOT_SERVICE = 0, + RESTORE_DATA, + RESTORE_CLOG, + BACKUP_DATA, + BACKUP_CLEAN, + MAX_FAILED_TYPE + }; + ObHAResultInfo(const FailedType &type, const ObLSID &ls_id, const ObAddr &addr, const ObTaskId &trace_id, + const int result); + ObHAResultInfo(const FailedType &type, const ObAddr &addr, const ObTaskId &trace_id, const int result); + const char *get_failed_type_str() const; + int get_comment_str(Comment &comment) const; + int assign(const ObHAResultInfo &that); + bool is_valid() const; + TO_STRING_KV(K_(type), K_(ls_id), K_(trace_id), K_(addr), K_(result)); + FailedType type_; + ObLSID ls_id_; + ObTaskId trace_id_; + ObAddr addr_; + int result_; +}; + struct ObBackupJobAttr final { public: @@ -1316,7 +1352,8 @@ public: const char *get_plus_archivelog_str() const; TO_STRING_KV(K_(job_id), K_(tenant_id), K_(incarnation_id), K_(backup_set_id), K_(initiator_tenant_id), K_(initiator_job_id), K_(executor_tenant_id), K_(plus_archivelog), K_(backup_level), K_(backup_type), K_(encryption_mode), - K_(passwd), K_(backup_path), K_(description), K_(start_ts), K_(end_ts), K_(status), K_(result), K_(can_retry), K_(retry_count)); + K_(passwd), K_(backup_path), K_(description), K_(start_ts), K_(end_ts), K_(status), K_(result), K_(can_retry), K_(retry_count), + K_(comment)); int64_t job_id_; uint64_t tenant_id_; int64_t incarnation_id_; @@ -1337,6 +1374,7 @@ public: int result_; bool can_retry_; int64_t retry_count_; + ObHAResultInfo::Comment comment_; }; struct ObBackupSetTaskAttr final @@ -1348,8 +1386,9 @@ public: int assign(const ObBackupSetTaskAttr &other); TO_STRING_KV(K_(task_id), K_(tenant_id), K_(incarnation_id), K_(job_id), K_(backup_set_id), K_(start_ts), K_(end_ts), - K_(start_scn), K_(end_scn), K_(user_ls_start_scn), K_(data_turn_id), K_(meta_turn_id), K_(status), - K_(encryption_mode), K_(passwd), K_(stats), K_(backup_path), K_(retry_cnt), K_(result)); + K_(start_scn), K_(end_scn), K_(user_ls_start_scn), K_(data_turn_id), K_(meta_turn_id), K_(minor_turn_id), + K_(major_turn_id), K_(status), K_(encryption_mode), K_(passwd), K_(stats), K_(backup_path), K_(retry_cnt), K_(result), + K_(comment)); int64_t task_id_; uint64_t tenant_id_; int64_t incarnation_id_; @@ -1362,6 +1401,8 @@ public: SCN user_ls_start_scn_; int64_t data_turn_id_; int64_t meta_turn_id_; + int64_t minor_turn_id_; + int64_t major_turn_id_; ObBackupStatus status_; ObBackupEncryptionMode::EncryptionMode encryption_mode_; common::ObFixedLengthString passwd_; @@ -1369,18 +1410,18 @@ public: ObBackupPathString backup_path_; int64_t retry_cnt_; int result_; + ObHAResultInfo::Comment comment_; }; struct ObBackupDataTaskType final { enum Type { - BACKUP_DATA_SYS = 0, + BACKUP_META = 0, // backup ls, tablet meta and inner tablet sstable BACKUP_DATA_MINOR = 1, BACKUP_DATA_MAJOR = 2, BACKUP_PLUS_ARCHIVE_LOG = 3, BACKUP_BUILD_INDEX = 4, - BACKUP_META = 5, BACKUP_MAX }; ObBackupDataTaskType() : type_(Type::BACKUP_MAX) {} @@ -1389,8 +1430,13 @@ struct ObBackupDataTaskType final bool is_valid() const; bool is_backup_meta() const { return Type::BACKUP_META == type_; } bool is_backup_data() const { - return BACKUP_DATA_SYS == type_ || BACKUP_DATA_MINOR == type_ || BACKUP_DATA_MAJOR == type_; + return BACKUP_META == type_ || BACKUP_DATA_MINOR == type_ || BACKUP_DATA_MAJOR == type_; } + bool is_backup_minor() const { return Type::BACKUP_DATA_MINOR == type_; } + bool is_backup_major() const { return Type::BACKUP_DATA_MAJOR == type_; } + bool is_backup_index() const { return Type::BACKUP_BUILD_INDEX == type_; } + void set_backup_major() { type_ = Type::BACKUP_DATA_MAJOR; } + void set_backup_minor() { type_ = Type::BACKUP_DATA_MINOR; } int get_backup_data_type(share::ObBackupDataType &backup_data_type) const; const char* get_str() const; int set_type(const char *buf); @@ -1407,7 +1453,7 @@ struct ObBackupLSTaskAttr final int set_black_servers(const ObString &str); TO_STRING_KV(K_(task_id), K_(tenant_id), K_(ls_id), K_(job_id), K_(backup_set_id), K_(backup_type), K_(task_type), K_(status), K_(start_ts), K_(end_ts), K_(backup_date), K_(black_servers), K_(dst), K_(task_trace_id), - K_(stats), K_(start_turn_id), K_(turn_id), K_(retry_id), K_(result)); + K_(stats), K_(start_turn_id), K_(turn_id), K_(retry_id), K_(result), K_(comment), K_(max_tablet_checkpoint_scn)); int64_t task_id_; uint64_t tenant_id_; ObLSID ls_id_; @@ -1427,6 +1473,9 @@ struct ObBackupLSTaskAttr final int64_t turn_id_; int64_t retry_id_; int result_; + ObHAResultInfo::Comment comment_; + + SCN max_tablet_checkpoint_scn_; // the checkpoint scn of all the tablets belong to the same ls while backing up tablets meta. }; struct ObBackupSetFileDesc final @@ -1444,8 +1493,8 @@ public: enum Compatible : int64_t { COMPATIBLE_VERSION_1 = 1, // 4.0 - - COMPATIBLE_VERSION_2, // 4.1 + COMPATIBLE_VERSION_2 = 2, // 4.1 + COMPATIBLE_VERSION_3 = 3, // 4.2 MAX_COMPATIBLE_VERSION, }; @@ -1472,7 +1521,7 @@ public: K_(date), K_(prev_full_backup_set_id), K_(prev_inc_backup_set_id), K_(stats), K_(start_time), K_(end_time), K_(status), K_(result), K_(encryption_mode), K_(passwd), K_(file_status), K_(backup_path), K_(start_replay_scn), K_(min_restore_scn), K_(tenant_compatible), K_(backup_compatible), K_(data_turn_id), K_(meta_turn_id), - K_(cluster_version)); + K_(cluster_version), K_(consistent_scn)); int64_t backup_set_id_; int64_t incarnation_; @@ -1499,6 +1548,9 @@ public: int64_t data_turn_id_; int64_t meta_turn_id_; uint64_t cluster_version_; + int64_t minor_turn_id_; + int64_t major_turn_id_; + SCN consistent_scn_; }; struct ObBackupSkippedType; @@ -1506,19 +1558,16 @@ struct ObBackupSkippedType; struct ObBackupSkipTabletAttr final { public: + static const int64_t BASE_MAJOR_TURN_ID = 1000000; ObBackupSkipTabletAttr(); ~ObBackupSkipTabletAttr() = default; bool is_valid() const; - TO_STRING_KV(K_(task_id), K_(tenant_id), K_(turn_id), K_(retry_id), K_(backup_set_id), K_(ls_id), - K_(tablet_id), K_(skipped_type)); + OB_INLINE int hash(uint64_t &hash_val) const { hash_val = tablet_id_.hash(); return OB_SUCCESS; } + int assign(const ObBackupSkipTabletAttr &that); + bool operator==(const ObBackupSkipTabletAttr &that) const { return tablet_id_ == that.tablet_id_; } + TO_STRING_KV(K_(tablet_id), K_(skipped_type)); public: - int64_t task_id_; - uint64_t tenant_id_; - int64_t turn_id_; - int64_t retry_id_; - int64_t backup_set_id_; ObTabletID tablet_id_; - ObLSID ls_id_; share::ObBackupSkippedType skipped_type_; }; diff --git a/src/share/backup/ob_log_archive_backup_info_mgr.cpp b/src/share/backup/ob_log_archive_backup_info_mgr.cpp deleted file mode 100644 index e0f0ed43a..000000000 --- a/src/share/backup/ob_log_archive_backup_info_mgr.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/** - * Copyright (c) 2021 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. - */ - -#define USING_LOG_PREFIX SHARE -#include "ob_log_archive_backup_info_mgr.h" -#include "lib/container/ob_array_iterator.h" -#include "lib/mysqlclient/ob_mysql_proxy.h" -#include "lib/string/ob_sql_string.h" -#include "lib/mysqlclient/ob_mysql_transaction.h" -#include "share/inner_table/ob_inner_table_schema_constants.h" -#include "share/config/ob_server_config.h" -#include "share/ob_force_print_log.h" -#include "share/backup/ob_backup_lease_info_mgr.h" -#include "ob_backup_path.h" -#include "ob_backup_file_lock_mgr.h" -#include "lib/utility/ob_tracepoint.h" -#include "share/backup/ob_backup_io_adapter.h" - -using namespace oceanbase; -using namespace common; -using namespace share; -using namespace share::schema; - -OB_SERIALIZE_MEMBER(ObExternLogArchiveBackupInfo, status_array_); -ObExternLogArchiveBackupInfo::ObExternLogArchiveBackupInfo() - : status_array_() -{ -} - -ObExternLogArchiveBackupInfo::~ObExternLogArchiveBackupInfo() -{ -} - -void ObExternLogArchiveBackupInfo::reset() -{ - status_array_.reset(); -} - -bool ObExternLogArchiveBackupInfo::is_valid() const -{ - bool bool_ret = true; - const int64_t count = status_array_.count(); - for (int64_t i = 0; bool_ret && i < count; ++i) { - bool_ret = status_array_.at(i).is_valid(); - } - return bool_ret; -} - -int64_t ObExternLogArchiveBackupInfo::get_write_buf_size() const -{ - int64_t size = sizeof(ObBackupCommonHeader); - size += this->get_serialize_size(); - return size; -} - -int ObExternLogArchiveBackupInfo::write_buf( - char *buf, const int64_t buf_len, int64_t &pos) const -{ - int ret = OB_SUCCESS; - const int64_t need_size = get_write_buf_size(); - ObBackupCommonHeader *common_header = nullptr; - - if (OB_ISNULL(buf) || buf_len - pos < need_size) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), KP(buf), K(buf_len), K(pos), K(need_size)); - } else { - common_header = new(buf + pos) ObBackupCommonHeader; - common_header->reset(); - common_header->compressor_type_ = ObCompressorType::NONE_COMPRESSOR; - common_header->data_type_ = ObBackupFileType::BACKUP_LOG_ARCHIVE_BACKUP_INFO; - common_header->data_version_ = LOG_ARCHIVE_BACKUP_INFO_FILE_VERSION; - - pos += sizeof(ObBackupCommonHeader); - int64_t saved_pos = pos; - if (OB_FAIL(this->serialize(buf, buf_len, pos))) { - LOG_WARN("failed to serialize info", K(ret), K(*this)); - } else { - common_header->data_length_ = pos - saved_pos; - common_header->data_zlength_ = common_header->data_length_; - if (OB_FAIL(common_header->set_checksum(buf + saved_pos, common_header->data_length_))) { - LOG_WARN("failed to set common header checksum", K(ret)); - } - } - } - - return ret; -} - -int ObExternLogArchiveBackupInfo::read_buf(const char *buf, const int64_t buf_len) -{ - int ret = OB_SUCCESS; - - if (OB_ISNULL(buf) || buf_len < sizeof(ObBackupCommonHeader)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), KP(buf), K(buf_len)); - } else { - int64_t pos = 0; - const ObBackupCommonHeader *common_header = - reinterpret_cast(buf + pos); - pos += common_header->header_length_; - if (OB_FAIL(common_header->check_header_checksum())) { - LOG_WARN("failed to check common header", K(ret)); - } else if (common_header->data_zlength_ > buf_len - pos) { - ret = OB_ERR_SYS; - LOG_ERROR("need more data then buf len", K(ret), KP(buf), K(buf_len), - K(*common_header)); - } else if (OB_FAIL(common_header->check_data_checksum(buf + pos, common_header->data_zlength_))) { - LOG_ERROR("failed to check archive backup info", K(ret), K(*common_header)); - } else if (OB_FAIL(this->deserialize(buf, pos + common_header->data_zlength_, pos))) { - LOG_WARN("failed to deserialize archive backup ifno", - K(ret), K(*common_header)); - } - } - return ret; -} - -int ObExternLogArchiveBackupInfo::update(const ObTenantLogArchiveStatus &status) -{ - int ret = OB_SUCCESS; - - if (!status.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(status)); - } else if (status_array_.empty()) { - if (OB_FAIL(status_array_.push_back(status))) { - LOG_WARN("Failed to add new status", K(ret)); - } else { - FLOG_INFO("add first new status", K(status)); - } - } else { - ObTenantLogArchiveStatus &last = status_array_.at(status_array_.count() - 1); - - if (last.incarnation_ != status.incarnation_) { - ret = OB_NOT_SUPPORTED; - LOG_ERROR("not support diff incarnation", K(ret), K(last), K(status)); - } else if (last.round_ < status.round_) { - if (last.status_ != ObLogArchiveStatus::STOP) { - if (ObLogArchiveStatus::BEGINNING == status.status_) { - ObTenantLogArchiveStatus new_status = last; - new_status.status_ = ObLogArchiveStatus::STOP; - if (OB_FAIL(last.update(new_status))) { - LOG_WARN("failed to update last", K(ret), K(last), K(new_status)); - } - } else { - ret = OB_ERR_SYS; - LOG_ERROR("last status must be stop", K(ret), K(last), K(status)); - } - } - - if (FAILEDx(status_array_.push_back(status))) { - LOG_WARN("failed to add status", K(ret)); - } else { - LOG_INFO("[LOG_ARCHIVE] add new log archive status", K(status), K(last)); - } - } else if (last.round_ == status.round_) { - if (OB_FAIL(last.update(status))) { - LOG_WARN("failed to update last", K(ret), K(last), K(status)); - } - } else { - ret = OB_LOG_ARCHIVE_INVALID_ROUND; - LOG_ERROR("invalid round", K(ret), K(last), K(status)); - } - } - - return ret; -} - -int ObExternLogArchiveBackupInfo::get_last(ObTenantLogArchiveStatus &status) -{ - int ret = OB_SUCCESS; - status.reset(); - - if (status_array_.empty()) { - ret = OB_LOG_ARCHIVE_BACKUP_INFO_NOT_EXIST; - } else { - status = status_array_.at(status_array_.count() - 1); - } - return ret; -} - -int ObExternLogArchiveBackupInfo::get_log_archive_status( - const int64_t restore_timestamp, ObTenantLogArchiveStatus &status) -{ - int ret = OB_LOG_ARCHIVE_BACKUP_INFO_NOT_EXIST; - - status.reset(); - - for (int64_t i = 0; i < status_array_.count(); ++i) { - const ObTenantLogArchiveStatus &cur_status = status_array_.at(i); - if (cur_status.start_ts_ <= restore_timestamp - && restore_timestamp <= cur_status.checkpoint_ts_) { - status = status_array_.at(i); - ret = OB_SUCCESS; - break; - } - } - - if (OB_FAIL(ret)) { - FLOG_INFO("not found need status", K(ret), K(restore_timestamp), K(status_array_)); - } - return ret; -} - -int ObExternLogArchiveBackupInfo::get_log_archive_status(ObIArray &status_array) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(status_array.assign(status_array_))) { - LOG_WARN("failed to get log archive status", K(ret), K(status_array_)); - } - return ret; -} - -int ObExternLogArchiveBackupInfo::mark_log_archive_deleted( - const ObIArray &round_ids) -{ - int ret = OB_SUCCESS; - for (int64_t i = 0; OB_SUCC(ret) && i < round_ids.count(); ++i) { - const int64_t round_id = round_ids.at(i); - for (int64_t j = 0; OB_SUCC(ret) && j < status_array_.count(); ++j) { - ObTenantLogArchiveStatus &tenant_archive_status = status_array_.at(j); - if (tenant_archive_status.round_ != round_id) { - //do nothing - } else { - tenant_archive_status.is_mark_deleted_ = true; - break; - } - } - } - return ret; -} - -int ObExternLogArchiveBackupInfo::delete_marked_log_archive_info( - const common::ObIArray &round_ids) -{ - int ret = OB_SUCCESS; - for (int64_t i = 0; OB_SUCC(ret) && i < round_ids.count(); ++i) { - const int64_t round_id = round_ids.at(i); - for (int64_t j = status_array_.count() - 1; OB_SUCC(ret) && j >= 0; --j) { - ObTenantLogArchiveStatus &tenant_archive_status = status_array_.at(j); - if (tenant_archive_status.is_mark_deleted_ && round_id == tenant_archive_status.round_) { - if (OB_FAIL(status_array_.remove(j))) { - LOG_WARN("failed to remove tenant archive status", K(ret), K(tenant_archive_status)); - } else { - break; - } - } - } - } - return ret; -} diff --git a/src/share/backup/ob_log_archive_backup_info_mgr.h b/src/share/backup/ob_log_archive_backup_info_mgr.h deleted file mode 100644 index a6cc8edc3..000000000 --- a/src/share/backup/ob_log_archive_backup_info_mgr.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2021 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 SRC_SHARE_BACKUP_OB_LOG_ARCHIVE_BACKUP_INFO_MGR_H_ -#define SRC_SHARE_BACKUP_OB_LOG_ARCHIVE_BACKUP_INFO_MGR_H_ - -#include "lib/mysqlclient/ob_isql_client.h" -#include "ob_backup_info_mgr.h" -#include "ob_backup_struct.h" -#include "ob_backup_path.h" - -namespace oceanbase -{ -namespace share -{ -class ObIBackupLeaseService; - -class ObExternLogArchiveBackupInfo final -{ - static const uint8_t VERSION = 1; - static const uint8_t LOG_ARCHIVE_BACKUP_INFO_FILE_VERSION = 1; - static const uint8_t LOG_ARCHIVE_BACKUP_INFO_CONTENT_VERSION = 1; - OB_UNIS_VERSION(VERSION); -public: - ObExternLogArchiveBackupInfo(); - ~ObExternLogArchiveBackupInfo(); - - void reset(); - bool is_valid() const; - int64_t get_write_buf_size() const; - int write_buf(char *buf, const int64_t buf_len, int64_t &pos) const; - int read_buf(const char *buf, const int64_t buf_len); - - int update(const ObTenantLogArchiveStatus &status); - int get_last(ObTenantLogArchiveStatus &status); - int get_log_archive_status(const int64_t restore_timestamp, ObTenantLogArchiveStatus &status); - int get_log_archive_status(common::ObIArray &status_array); - int mark_log_archive_deleted(const common::ObIArray &round_ids); - int delete_marked_log_archive_info(const common::ObIArray &round_ids); - bool is_empty() const { return status_array_.empty(); } - - TO_STRING_KV(K_(status_array)); -private: - common::ObSArray status_array_; - DISALLOW_COPY_AND_ASSIGN(ObExternLogArchiveBackupInfo); -}; - -}//share -}//oceanbase - -#endif /* SRC_SHARE_BACKUP_OB_LOG_ARCHIVE_BACKUP_INFO_MGR_H_ */ diff --git a/src/share/balance/ob_balance_job_table_operator.cpp b/src/share/balance/ob_balance_job_table_operator.cpp new file mode 100644 index 000000000..2a9b45a1c --- /dev/null +++ b/src/share/balance/ob_balance_job_table_operator.cpp @@ -0,0 +1,365 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE + +#include "ob_balance_job_table_operator.h" +#include "lib/mysqlclient/ob_isql_client.h"//ObISQLClient +#include "lib/mysqlclient/ob_mysql_result.h"//MySQLResult +#include "lib/mysqlclient/ob_mysql_proxy.h"//MySQLResult +#include "lib/mysqlclient/ob_mysql_transaction.h"//ObMySQLTrans +#include "share/inner_table/ob_inner_table_schema.h"//ALL_BALANCE_JOB_TNAME +#include "share/ob_dml_sql_splicer.h"//ObDMLSqlSplicer + +using namespace oceanbase; +using namespace oceanbase::common; +namespace oceanbase +{ +namespace share +{ +static const char* BALANCE_JOB_STATUS_ARRAY[] = +{ + "DOING", "CANCELING", "COMPLETED", "CANCELED" +}; +static const char *BALANCE_JOB_TYPE[] = +{ + "LS_BALANCE", "PARTITION_BALANCE", +}; + +const char* ObBalanceJobStatus::to_str() const +{ + STATIC_ASSERT(ARRAYSIZEOF(BALANCE_JOB_STATUS_ARRAY) == BALANCE_JOB_STATUS_MAX, "array size mismatch"); + const char *type_str = "INVALID"; + if (OB_UNLIKELY(val_ >= ARRAYSIZEOF(BALANCE_JOB_STATUS_ARRAY) || val_ < 0)) { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "fatal error, unknown balance job status", K_(val)); + } else { + type_str = BALANCE_JOB_STATUS_ARRAY[val_]; + } + return type_str; +} + +ObBalanceJobStatus::ObBalanceJobStatus(const ObString &str) +{ + val_ = BALANCE_JOB_STATUS_INVALID; + if (str.empty()) { + } else { + for (int64_t i = 0; i < ARRAYSIZEOF(BALANCE_JOB_STATUS_ARRAY); ++i) { + if (0 == str.case_compare(BALANCE_JOB_STATUS_ARRAY[i])) { + val_ = i; + break; + } + } + } + if (BALANCE_JOB_STATUS_INVALID == val_) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid balance job status", K(val_), K(str)); + } +} + +const char* ObBalanceJobType::to_str() const +{ + STATIC_ASSERT( + ARRAYSIZEOF(BALANCE_JOB_TYPE) == BALANCE_JOB_MAX, + "array size mismatch"); + const char *type_str = "INVALID"; + if (OB_UNLIKELY(val_ >= ARRAYSIZEOF(BALANCE_JOB_TYPE) || val_ < 0)) { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "fatal error, unknown balance job status", K_(val)); + } else { + type_str = BALANCE_JOB_TYPE[val_]; + } + return type_str; +} + +ObBalanceJobType::ObBalanceJobType(const ObString &str) +{ + val_ = BALANCE_JOB_INVALID; + if (str.empty()) { + } else { + for (int64_t i = 0; i < ARRAYSIZEOF(BALANCE_JOB_TYPE); ++i) { + if (0 == str.case_compare(BALANCE_JOB_TYPE[i])) { + val_ = i; + break; + } + } + } + if (BALANCE_JOB_INVALID == val_) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid balance job status", K(val_), K(str)); + } +} + +int ObBalanceJob::init(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceJobType job_type, + const ObBalanceJobStatus job_status, + const int64_t primary_zone_num, + const int64_t unit_group_num, + const ObString &comment, + const ObString &balance_strategy) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || ! job_id.is_valid() + || !job_type.is_valid() || !job_status.is_valid() + || 0 == primary_zone_num || 0 == unit_group_num + || balance_strategy.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(job_id), K(job_type), K(job_status), + K(primary_zone_num), K(unit_group_num), K(balance_strategy), K(comment)); + } else if (OB_FAIL(comment_.assign(comment))) { + LOG_WARN("failed to assign commet", KR(ret), K(comment)); + } else if (OB_FAIL(balance_strategy_.assign(balance_strategy))) { + LOG_WARN("failed to assign balance strategy", KR(ret), K(balance_strategy)); + } else { + tenant_id_ = tenant_id; + job_id_ = job_id; + job_type_ = job_type; + job_status_ = job_status; + primary_zone_num_ = primary_zone_num; + unit_group_num_ = unit_group_num; + } + return ret; +} + +bool ObBalanceJob::is_valid() const +{ + return OB_INVALID_TENANT_ID != tenant_id_ + && job_id_.is_valid() + && 0 != primary_zone_num_ + && 0 != unit_group_num_ + && job_type_.is_valid() + && job_status_.is_valid() + && !balance_strategy_.empty(); +} + +void ObBalanceJob::reset() +{ + tenant_id_ = OB_INVALID_TENANT_ID; + job_id_.reset(); + primary_zone_num_ = 0; + unit_group_num_ = 0; + job_type_.reset(); + job_status_.reset(); + comment_.reset(); + balance_strategy_.reset(); +} + +int ObBalanceJobTableOperator::insert_new_job(const ObBalanceJob &job, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObDMLExecHelper exec(client, job.get_tenant_id()); + if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("job is invalid", KR(ret), K(job)); + } else if (OB_FAIL(fill_dml_spliter(dml, job))) { + LOG_WARN("failed to assign sql", KR(ret), K(job)); + } else if (OB_FAIL(dml.finish_row())) { + LOG_WARN("failed to finish row", KR(ret), K(job)); + } else if (OB_FAIL(exec.exec_insert(OB_ALL_BALANCE_JOB_TNAME, dml, affected_rows))) { + LOG_WARN("execute update failed", KR(ret), K(job)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected single row", KR(ret), K(affected_rows)); + } + return ret; +} + +int ObBalanceJobTableOperator::get_balance_job(const uint64_t tenant_id, + const bool for_update, + ObISQLClient &client, + ObBalanceJob &job, + int64_t &start_time, + int64_t &finish_time) +{ + int ret = OB_SUCCESS; + job.reset(); + ObSqlString sql; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_FAIL(sql.assign_fmt("select time_to_usec(gmt_create) as " + "start_time, time_to_usec(gmt_modified) " + " as finish_time, * from %s", + OB_ALL_BALANCE_JOB_TNAME))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql)); + } else if (for_update && OB_FAIL(sql.append_fmt(" for update"))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql)); + } else { + HEAP_VAR(ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = NULL; + if (OB_FAIL(client.read(res, tenant_id, sql.ptr()))) { + LOG_WARN("failed to read", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("empty balance job", KR(ret), K(sql)); + } else { + LOG_WARN("failed to get balance job", KR(ret), K(sql)); + } + } else { + int64_t primary_zone_num = 0; + int64_t unit_num = 0; + int64_t job_id = ObBalanceJobID::INVALID_ID; + ObString comment; + ObString balance_strategy; + ObString job_type; + ObString job_status; + EXTRACT_INT_FIELD_MYSQL(*result, "start_time", start_time, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "finish_time", finish_time, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "job_id", job_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "target_unit_num", unit_num, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "target_primary_zone_num", primary_zone_num, int64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "job_type", job_type); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "status", job_status); + EXTRACT_VARCHAR_FIELD_MYSQL_SKIP_RET(*result, "comment", comment); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "balance_strategy_name", balance_strategy); + if (OB_FAIL(ret)) { + LOG_WARN("failed to get cell", KR(ret), K(job_id), K(unit_num), K(primary_zone_num), K(job_type), + K(job_status), K(comment), K(start_time), K(finish_time)); + } else if (OB_FAIL(job.init(tenant_id, ObBalanceJobID(job_id), ObBalanceJobType(job_type), + ObBalanceJobStatus(job_status), primary_zone_num, unit_num, comment, balance_strategy))) { + LOG_WARN("failed to init job", KR(ret), K(tenant_id), K(job_id), K(unit_num), K(start_time), + K(primary_zone_num), K(job_type), K(job_status), K(comment), K(balance_strategy)); + } + } + if (OB_SUCC(ret)) { + if (OB_SUCC(result->next())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected only one row", KR(ret), K(sql)); + } else if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("error unexpected", KR(ret), K(sql)); + } + } + } + } + return ret; +} + +int ObBalanceJobTableOperator::update_job_status(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceJobStatus old_job_status, + const ObBalanceJobStatus new_job_status, + bool update_comment, const common::ObString &new_comment, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = 0; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !old_job_status.is_valid() || !new_job_status.is_valid() + || ! job_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(old_job_status), K(new_job_status), K(job_id)); + } else if (OB_FAIL(sql.assign_fmt("update %s set status = '%s'", + OB_ALL_BALANCE_JOB_TNAME, new_job_status.to_str()))) { + LOG_WARN("failed to assign sql", KR(ret), K(new_job_status), K(old_job_status), K(job_id)); + } else if (update_comment && OB_FAIL(sql.append_fmt(", comment = '%.*s'", new_comment.length(), new_comment.ptr()))) { + LOG_WARN("failed to append sql", KR(ret), K(new_comment)); + } else if (OB_FAIL(sql.append_fmt(" where status = '%s' and job_id = %ld", old_job_status.to_str(), job_id.id()))) { + LOG_WARN("failed to append sql", KR(ret), K(old_job_status), K(job_id)); + } else if (OB_FAIL(client.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(tenant_id), K(sql)); + } else if (is_zero_row(affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("expected one row, may status change", KR(ret), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected single row", KR(ret), K(sql)); + } + return ret; +} + +int ObBalanceJobTableOperator::fill_dml_spliter(share::ObDMLSqlSplicer &dml, + const ObBalanceJob &job) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(dml.add_column("balance_strategy_name", job.get_balance_strategy())) + || OB_FAIL(dml.add_column("job_id", job.get_job_id().id())) + || OB_FAIL(dml.add_column("job_type", job.get_job_type().to_str())) + || OB_FAIL(dml.add_column("status", job.get_job_status().to_str())) + || OB_FAIL(dml.add_column("target_primary_zone_num", job.get_primary_zone_num())) + || OB_FAIL(dml.add_column("target_unit_num", job.get_unit_group_num())) + || OB_FAIL(dml.add_column("comment", job.get_comment().string()))) { + LOG_WARN("failed to fill dml spliter", KR(ret), K(job)); + } + return ret; +} + +// maybe in trans TODO +// remove job from __all_balance_job to __all_balance_job_history +int ObBalanceJobTableOperator::clean_job(const uint64_t tenant_id, + const ObBalanceJobID job_id, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + ObBalanceJob job; + int64_t affected_rows = 0; + common::ObMySQLTransaction trans; + ObSqlString sql; + int64_t finish_time = OB_INVALID_TIMESTAMP; + int64_t start_time = OB_INVALID_TIMESTAMP; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || ! job_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(job_id)); + } else if (OB_FAIL(trans.start(&client, tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id)); + } else if (OB_FAIL(get_balance_job(tenant_id, true, trans, job, start_time, finish_time))) { + LOG_WARN("failed to get job", KR(ret), K(tenant_id)); + } else if (job_id != job.get_job_id()) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("job not exist, no need clean", KR(ret), K(job_id), K(job)); + } else if (job.get_job_status().is_doing() || job.get_job_status().is_canceling()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("can not clean job while in progress", KR(ret), K(job)); + } else if (OB_FAIL(sql.assign_fmt("delete from %s where job_id = %ld", OB_ALL_BALANCE_JOB_TNAME, + job_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(job_id)); + } else if (OB_FAIL(trans.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to write", KR(ret), K(tenant_id), K(sql)); + } else if(!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expect one row", KR(ret), K(sql), K(affected_rows)); + } else { + ObDMLSqlSplicer dml; + ObDMLExecHelper exec(trans, job.get_tenant_id()); + if (OB_FAIL(fill_dml_spliter(dml, job))) { + LOG_WARN("failed to assign sql", KR(ret), K(job)); + } else if (OB_FAIL(dml.add_time_column("create_time", start_time))) { + LOG_WARN("failed to add start time", KR(ret), K(start_time)); + } else if (OB_FAIL(dml.add_time_column("finish_time", finish_time))) { + LOG_WARN("failed to add start time", KR(ret), K(job), K(finish_time)); + } else if (OB_FAIL(exec.exec_insert(OB_ALL_BALANCE_JOB_HISTORY_TNAME, dml, + affected_rows))) { + LOG_WARN("execute update failed", KR(ret), K(job)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expect one row", KR(ret), K(sql), K(affected_rows)); + } + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + return ret; +} +}//end of share +}//end of ob diff --git a/src/share/balance/ob_balance_job_table_operator.h b/src/share/balance/ob_balance_job_table_operator.h new file mode 100644 index 000000000..a4bda5834 --- /dev/null +++ b/src/share/balance/ob_balance_job_table_operator.h @@ -0,0 +1,224 @@ +/** + * Copyright (c) 2021 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_OB_BALANCE_JOB_OPERATOR_H_ +#define OCEANBASE_SHARE_OB_BALANCE_JOB_OPERATOR_H_ + +#include "share/ob_ls_id.h"//share::ObLSID +#include "share/ob_common_id.h"// ObCommonID +#include "share/ob_balance_define.h" // ObBalanceJobID +#include "lib/container/ob_array.h"//ObArray +#include "lib/container/ob_iarray.h"//ObIArray +#include "lib/string/ob_sql_string.h"//ObSqlString + +namespace oceanbase +{ + +namespace common +{ +class ObISQLClient; +class ObString; +namespace sqlclient +{ +class ObMySQLResult; +} +} + +namespace share +{ +class ObDMLSqlSplicer; +class ObBalanceJobStatus +{ + +public: + static const int64_t BALANCE_JOB_STATUS_INVALID = -1; + static const int64_t BALANCE_JOB_STATUS_DOING = 0; + static const int64_t BALANCE_JOB_STATUS_CANCELING = 1; + static const int64_t BALANCE_JOB_STATUS_COMPLETED = 2; + static const int64_t BALANCE_JOB_STATUS_CANCELED = 3; + static const int64_t BALANCE_JOB_STATUS_MAX = 4; + ObBalanceJobStatus(const int64_t value = BALANCE_JOB_STATUS_INVALID) : val_(value) {} + ObBalanceJobStatus(const ObString &str); + ~ObBalanceJobStatus() {reset(); } + +public: + void reset() { val_ = BALANCE_JOB_STATUS_INVALID; } + bool is_valid() const { return val_ != BALANCE_JOB_STATUS_INVALID; } + const char* to_str() const; + + // assignment + ObBalanceJobStatus &operator=(const int64_t value) { val_ = value; return *this; } + + // compare operator + bool operator == (const ObBalanceJobStatus &other) const { return val_ == other.val_; } + bool operator != (const ObBalanceJobStatus &other) const { return val_ != other.val_; } + + // ObBalanceJobStatus attribute interface + bool is_doing() const { return BALANCE_JOB_STATUS_DOING == val_; } + bool is_canceling() const { return BALANCE_JOB_STATUS_CANCELING == val_; } + bool is_success() const { return BALANCE_JOB_STATUS_COMPLETED == val_; } + bool is_canceled() const { return BALANCE_JOB_STATUS_CANCELED == val_; } + + TO_STRING_KV(K_(val), "job_status", to_str()); +private: + int64_t val_; +}; +class ObBalanceJobType +{ +public: + static const int64_t BALANCE_JOB_INVALID = -1; + //ls balance for expand or shrink + static const int64_t BALANCE_JOB_LS = 0; + //partition balance + static const int64_t BALANCE_JOB_PARTITION = 1; + static const int64_t BALANCE_JOB_MAX = 2; + ObBalanceJobType(const int64_t value = BALANCE_JOB_INVALID) : val_(value) {} + ObBalanceJobType(const ObString &str); +public: + void reset() { val_ = BALANCE_JOB_INVALID; } + bool is_valid() const { return val_ != BALANCE_JOB_INVALID; } + const char* to_str() const; + TO_STRING_KV(K_(val), "job_type", to_str()); + + // assignment + ObBalanceJobType &operator=(const int64_t value) { val_ = value; return *this; } + + // compare operator + bool operator == (const ObBalanceJobType &other) const { return val_ == other.val_; } + bool operator != (const ObBalanceJobType &other) const { return val_ != other.val_; } + + // ObBalanceJobStatus attribute interface + bool is_balance_ls() const { return BALANCE_JOB_LS == val_; } + bool is_balance_partition() const { return BALANCE_JOB_PARTITION == val_; } +private: + int64_t val_; +}; + +const static char * const LS_BALANCE_BY_MIGRATE = "LS balance by migrate"; +const static char * const LS_BALANCE_BY_ALTER = "LS balance by alter"; +const static char * const LS_BALANCE_BY_EXPAND = "LS balance by expand"; +const static char * const LS_BALANCE_BY_SHRINK = "LS balance by shrink"; + +struct ObBalanceJob +{ +public: + ObBalanceJob() { reset(); } + ~ObBalanceJob() {} + void reset(); + int init(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceJobType job_type, + const ObBalanceJobStatus job_status, + const int64_t primary_zone_num, + const int64_t unit_group_num, + const ObString &comment, + const ObString &balance_strategy); + bool is_valid() const; + TO_STRING_KV(K_(tenant_id), K_(job_id), K_(job_type), K_(job_status), + K_(primary_zone_num), K_(unit_group_num), K_(comment), K_(balance_strategy)); +#define Property_declare_var(variable_type, variable_name) \ + private: \ + variable_type variable_name##_; \ + \ + public: \ + variable_type get_##variable_name() const { return variable_name##_; } + + Property_declare_var(uint64_t, tenant_id) + Property_declare_var(ObBalanceJobID, job_id) + Property_declare_var(int64_t, primary_zone_num) + Property_declare_var(int64_t, unit_group_num) + Property_declare_var(ObBalanceJobType, job_type) + Property_declare_var(ObBalanceJobStatus, job_status) +#undef Property_declare_var +public: + const ObSqlString& get_comment() const + { + return comment_; + } + const ObSqlString& get_balance_strategy() const + { + return balance_strategy_; + } +private: + ObSqlString comment_; + ObSqlString balance_strategy_; +}; + +class ObBalanceJobTableOperator +{ +public: + /** + * @description: insert new job to __all_balance_job + * @param[in] job : a valid balance job include tenant_id + * @param[in] client: sql client or trans + * @return OB_SUCCESS if success, otherwise failed + */ + static int insert_new_job(const ObBalanceJob &job, + ObISQLClient &client); + /** + * @description: get job from __all_balance_job, only one job + * @param[in] tenant_id : user_tenant_id + * @param[in] for_update : whether lock the job + * @param[in] client : sql client or trans + * @param[out] job : get a valid balance job + * @param[out] start_time: the job gmt_create + * @param[out] finish_time: the job gmt_modify + * @return : + * OB_SUCCESS : get a valid job + * OB_ENTRY_NOT_EXIST : __all_balance_job is empty + * OTHER : fail + */ + static int get_balance_job(const uint64_t tenant_id, + const bool for_update, + ObISQLClient &client, + ObBalanceJob &job, + int64_t &start_time, + int64_t &finish_time); + /** + * @description: update job status of __all_balance_job, only one job + * @param[in] tenant_id : user_tenant_id + * @param[in] old_job_status : current job status + * @param[in] new_job_status : new job status + * @param[in] update_comment : weather to update comment + * @param[in] comment : reason to change job status(only for abort); + * @param[in] client: sql client or trans + * @return : + * OB_SUCCESS : update job status success + * OB_STATE_NOT_MATCH : current job status not match, can not update + * OTHER : fail + */ + static int update_job_status(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceJobStatus old_job_status, + const ObBalanceJobStatus new_job_status, + bool update_comment, const common::ObString &new_comment, + ObISQLClient &client); + /** + * @description: delete job from of __all_balance_job and insert to job to __all_balance_job_history + * @param[in] tenant_id : user_tenant_id + * @param[in] client: sql client or trans + * @return : + * OB_SUCCESS : clean job success + * OB_OP_NOT_ALLOW : job is in progress or init + * OB_STATE_NOT_MATCH /OB_ENTRY_NOT_EXIST : current job has beed clean + * OTHER : fail + */ + static int clean_job(const uint64_t tenant_id, + const ObBalanceJobID job_id, + ObISQLClient &client); + static int fill_dml_spliter(share::ObDMLSqlSplicer &dml, + const ObBalanceJob &job); +}; +} +} + +#endif /* !OCEANBASE_SHARE_OB_BALANCE_JOB_OPERATOR_H_ */ diff --git a/src/share/balance/ob_balance_task_helper_operator.cpp b/src/share/balance/ob_balance_task_helper_operator.cpp new file mode 100644 index 000000000..b98d4f6f5 --- /dev/null +++ b/src/share/balance/ob_balance_task_helper_operator.cpp @@ -0,0 +1,290 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE + +#include "ob_balance_task_helper_operator.h" +#include "lib/mysqlclient/ob_isql_client.h"//ObISQLClient +#include "lib/mysqlclient/ob_mysql_result.h"//MySQLResult +#include "lib/mysqlclient/ob_mysql_proxy.h"//MySQLResult +#include "lib/mysqlclient/ob_mysql_transaction.h"//ObMySQLTrans +#include "share/inner_table/ob_inner_table_schema.h"//ALL_LS_BALANCE_TASK_HELPER_TNAME +#include "share/ob_dml_sql_splicer.h"//ObDMLSqlSplicer + +using namespace oceanbase; +using namespace oceanbase::common; +namespace oceanbase +{ +namespace share +{ +static const char* LS_BALANCE_TASK_HELPER_OP_ARRAY[] = +{ + "ALTER_LS", "TRANSFER_BEGIN", "TRANSFER_END" +}; + +const char* ObBalanceTaskHelperOp::to_str() const +{ + STATIC_ASSERT(ARRAYSIZEOF(LS_BALANCE_TASK_HELPER_OP_ARRAY) == LS_BALANCE_TASK_OP_MAX, "array size mismatch"); + const char *op_str = "INVALID"; + if (OB_UNLIKELY(val_ >= ARRAYSIZEOF(LS_BALANCE_TASK_HELPER_OP_ARRAY) || val_ < 0)) { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "fatal error, unknown balance ls_balance_task status", K_(val)); + } else { + op_str = LS_BALANCE_TASK_HELPER_OP_ARRAY[val_]; + } + return op_str; +} + +ObBalanceTaskHelperOp::ObBalanceTaskHelperOp(const ObString &str) +{ + val_ = LS_BALANCE_TASK_OP_INVALID; + if (str.empty()) { + } else { + for (int64_t i = 0; i < ARRAYSIZEOF(LS_BALANCE_TASK_HELPER_OP_ARRAY); ++i) { + if (0 == str.case_compare(LS_BALANCE_TASK_HELPER_OP_ARRAY[i])) { + val_ = i; + break; + } + } + } + if (LS_BALANCE_TASK_OP_INVALID == val_) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid balance ls_balance_task status", K(val_), K(str)); + } +} +OB_SERIALIZE_MEMBER(ObBalanceTaskHelperOp, val_); + +int ObBalanceTaskHelperMeta::init( + const ObBalanceTaskHelperOp &task_op, + const share::ObLSID &src_ls, + const share::ObLSID &dest_ls, + const uint64_t ls_group_id) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_UNLIKELY(!task_op.is_valid() + || !src_ls.is_valid() + || OB_INVALID_ID == ls_group_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(task_op), K(src_ls), K(dest_ls), + K(ls_group_id)); + } else { + task_op_ = task_op; + src_ls_ = src_ls; + dest_ls_ = dest_ls; + ls_group_id_ = ls_group_id; + } + return ret; +} + +bool ObBalanceTaskHelperMeta::is_valid() const +{ + return task_op_.is_valid() + && src_ls_.is_valid() + && OB_INVALID_ID != ls_group_id_; +} + +void ObBalanceTaskHelperMeta::reset() +{ + task_op_.reset(); + src_ls_.reset(); + dest_ls_.reset(); + ls_group_id_ = OB_INVALID_ID; +} + +int ObBalanceTaskHelperMeta::assign(const ObBalanceTaskHelperMeta &other) +{ + task_op_ = other.task_op_; + src_ls_ = other.src_ls_; + dest_ls_ = other.dest_ls_; + ls_group_id_ = other.ls_group_id_; + return OB_SUCCESS; +} + +OB_SERIALIZE_MEMBER(ObBalanceTaskHelperMeta, task_op_, src_ls_, + dest_ls_, ls_group_id_); + +int ObBalanceTaskHelper::init(const uint64_t tenant_id, + const share::SCN &operation_scn, + const ObBalanceTaskHelperOp &task_op, + const share::ObLSID &src_ls, + const share::ObLSID &dest_ls, + const uint64_t ls_group_id) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !operation_scn.is_valid() + || !task_op.is_valid() + || !src_ls.is_valid() + || OB_INVALID_ID == ls_group_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task_op), K(src_ls), K(dest_ls), + K(ls_group_id), K(operation_scn)); + } else if (OB_FAIL(balance_task_helper_meta_.init(task_op, src_ls, dest_ls, + ls_group_id))) { + LOG_WARN("failed to init balance task helper meta", KR(ret), K(tenant_id), K(task_op), K(src_ls), + K(dest_ls), K(ls_group_id), K(operation_scn)); + } else { + operation_scn_ = operation_scn; + tenant_id_ = tenant_id; + } + return ret; +} + +int ObBalanceTaskHelper::init(const share::SCN &operation_scn, + const uint64_t tenant_id, + const ObBalanceTaskHelperMeta &balance_task_helper_meta) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_UNLIKELY(!operation_scn.is_valid() || !balance_task_helper_meta.is_valid() + || !is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(operation_scn), K(balance_task_helper_meta), K(tenant_id)); + } else if (OB_FAIL(balance_task_helper_meta_.assign(balance_task_helper_meta))) { + LOG_WARN("failed to assign balance taks helper meta", KR(ret), K(balance_task_helper_meta)); + } else { + operation_scn_ = operation_scn; + tenant_id_ = tenant_id; + } + return ret; +} + +bool ObBalanceTaskHelper::is_valid() const +{ + return operation_scn_.is_valid() && balance_task_helper_meta_.is_valid() && is_valid_tenant_id(tenant_id_); +} + +void ObBalanceTaskHelper::reset() +{ + operation_scn_.reset(); + balance_task_helper_meta_.reset(); + tenant_id_ = OB_INVALID_TENANT_ID; +} + +int ObBalanceTaskHelperTableOperator::insert_ls_balance_task(const ObBalanceTaskHelper &ls_balance_task, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + const uint64_t tenant_id = gen_meta_tenant_id(ls_balance_task.get_tenant_id()); + ObDMLExecHelper exec(client, tenant_id); + if (OB_UNLIKELY(!ls_balance_task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_balance_task is invalid", KR(ret), K(ls_balance_task)); + } else if (OB_FAIL(fill_dml_spliter(dml, ls_balance_task))) { + LOG_WARN("failed to assign sql", KR(ret), K(ls_balance_task)); + } else if (OB_FAIL(exec.exec_insert(OB_ALL_BALANCE_TASK_HELPER_TNAME, dml, affected_rows))) { + LOG_WARN("execute update failed", KR(ret), K(ls_balance_task), K(tenant_id)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected single row", KR(ret), K(affected_rows)); + } + return ret; +} + +int ObBalanceTaskHelperTableOperator::pop_task(const uint64_t tenant_id, + ObISQLClient &client, + ObBalanceTaskHelper &ls_balance_task) +{ + int ret = OB_SUCCESS; + ls_balance_task.reset(); + ObSqlString sql; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_FAIL(sql.assign_fmt("select * from %s order by operation_scn asc limit 1", + OB_ALL_BALANCE_TASK_HELPER_TNAME))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql)); + } else { + const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id); + HEAP_VAR(ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = NULL; + if (OB_FAIL(client.read(res, exec_tenant_id, sql.ptr()))) { + LOG_WARN("failed to read", KR(ret), K(exec_tenant_id), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("empty ls_balance_task", KR(ret), K(sql)); + } else { + LOG_WARN("failed to get ls_balance_task", KR(ret), K(sql)); + } + } else { + ObString task_op_str; + uint64_t op_scn_value = 0; + SCN op_scn; + int64_t src_ls = 0; + int64_t dest_ls = 0; + uint64_t ls_group_id = OB_INVALID_ID; + EXTRACT_UINT_FIELD_MYSQL(*result, "operation_scn", op_scn_value, uint64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "src_ls", src_ls, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "dest_ls", dest_ls, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "ls_group_id", ls_group_id, uint64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "operation_type", task_op_str); + if (OB_FAIL(ret)) { + LOG_WARN("failed to get cell", KR(ret), K(task_op_str), K(op_scn), K(src_ls), K(dest_ls), K(ls_group_id)); + } else if (OB_FAIL(op_scn.convert_for_inner_table_field(op_scn_value))) { + LOG_WARN("failed to convert for inner table", KR(ret), K(op_scn_value)); + } else if (OB_FAIL(ls_balance_task.init(tenant_id, op_scn, ObBalanceTaskHelperOp(task_op_str), ObLSID(src_ls), + ObLSID(dest_ls), ls_group_id))) { + LOG_WARN("failed to init ls_balance_task", KR(ret), K(tenant_id), K(task_op_str), K(op_scn), K(src_ls), K(ls_group_id)); + } + } + } + } + return ret; +} + +int ObBalanceTaskHelperTableOperator::fill_dml_spliter(share::ObDMLSqlSplicer &dml, + const ObBalanceTaskHelper &ls_balance_task) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(dml.add_column("operation_type", ls_balance_task.get_task_op().to_str())) + || OB_FAIL(dml.add_column("operation_scn", ls_balance_task.get_operation_scn().get_val_for_inner_table_field())) + || OB_FAIL(dml.add_column("src_ls", ls_balance_task.get_src_ls().id())) + || OB_FAIL(dml.add_column("dest_ls", ls_balance_task.get_dest_ls().id())) + || OB_FAIL(dml.add_column("ls_group_id", ls_balance_task.get_ls_group_id()))) { + LOG_WARN("failed to fill dml spliter", KR(ret), K(ls_balance_task)); + } + return ret; +} + +int ObBalanceTaskHelperTableOperator::remove_task(const uint64_t tenant_id, + const share::SCN &operation_scn, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObSqlString sql; + const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || !operation_scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(operation_scn)); + } else if (OB_FAIL(sql.assign_fmt("delete from %s where operation_scn = %lu", OB_ALL_BALANCE_TASK_HELPER_TNAME, + operation_scn.get_val_for_inner_table_field()))) { + LOG_WARN("failed to assign sql", KR(ret), K(operation_scn)); + } else if (OB_FAIL(client.write(exec_tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(exec_tenant_id), K(sql)); + } else if (is_zero_row(affected_rows)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("expect one row", KR(ret), K(sql), K(affected_rows)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expect one row", KR(ret), K(sql), K(affected_rows)); + } + return ret; +} +}//end of share +}//end of ob diff --git a/src/share/balance/ob_balance_task_helper_operator.h b/src/share/balance/ob_balance_task_helper_operator.h new file mode 100644 index 000000000..ba25857ad --- /dev/null +++ b/src/share/balance/ob_balance_task_helper_operator.h @@ -0,0 +1,194 @@ +/** + * Copyright (c) 2021 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_OB_LS_BALANCE_TASK_HELPER_OPERATOR_H_ +#define OCEANBASE_SHARE_OB_LS_BALANCE_TASK_HELPER_OPERATOR_H_ + +#include "share/ob_ls_id.h"//share::ObLSID +#include "share/ob_common_id.h"// ObCommonID +#include "share/scn.h"//SCN +#include "lib/container/ob_array.h"//ObArray +#include "lib/container/ob_iarray.h"//ObIArray +#include "lib/string/ob_sql_string.h"//ObSqlString + +namespace oceanbase +{ + +namespace common +{ +class ObISQLClient; +class ObString; +namespace sqlclient +{ +class ObMySQLResult; +} +} + +namespace share +{ +class ObDMLSqlSplicer; +class ObBalanceTaskHelperOp +{ +public: + OB_UNIS_VERSION(1); +public: + static const int64_t LS_BALANCE_TASK_OP_INVALID = -1; + static const int64_t LS_BALANCE_TASK_OP_ALTER = 0; + static const int64_t LS_BALANCE_TASK_OP_TRANSFER_BEGIN = 1; + static const int64_t LS_BALANCE_TASK_OP_TRANSFER_END = 2; + static const int64_t LS_BALANCE_TASK_OP_MAX = 3; + ObBalanceTaskHelperOp(const int64_t value = LS_BALANCE_TASK_OP_INVALID) : val_(value) {} + ObBalanceTaskHelperOp(const ObString &str); + ~ObBalanceTaskHelperOp() {reset(); } + +public: + void reset() { val_ = LS_BALANCE_TASK_OP_INVALID; } + bool is_valid() const { return val_ > LS_BALANCE_TASK_OP_INVALID && val_ < LS_BALANCE_TASK_OP_MAX; } + const char* to_str() const; + + // assignment + ObBalanceTaskHelperOp &operator=(const int64_t value) { val_ = value; return *this; } + + // compare operator + bool operator == (const ObBalanceTaskHelperOp &other) const { return val_ == other.val_; } + bool operator != (const ObBalanceTaskHelperOp &other) const { return val_ != other.val_; } + + // ObBalanceTaskHelperOp attribute interface + bool is_ls_alter() const { return LS_BALANCE_TASK_OP_ALTER == val_; } + bool is_transfer_begin() const { return LS_BALANCE_TASK_OP_TRANSFER_BEGIN == val_; } + bool is_transfer_end() const { return LS_BALANCE_TASK_OP_TRANSFER_END == val_; } + + TO_STRING_KV(K_(val), "ls_balance_task_op", to_str()); +private: + int64_t val_; +}; + +struct ObBalanceTaskHelperMeta +{ +public: + OB_UNIS_VERSION(1); +public: + ObBalanceTaskHelperMeta() { reset(); } + ~ObBalanceTaskHelperMeta() {} + void reset(); + int init(const ObBalanceTaskHelperOp &task_op, + const share::ObLSID &src_ls, + const share::ObLSID &dest_ls, + const uint64_t ls_group_id); + bool is_valid() const; + int assign(const ObBalanceTaskHelperMeta &other); + TO_STRING_KV(K_(task_op), K_(src_ls), + K_(dest_ls), K_(ls_group_id)); +#define Property_declare_var(variable_type, variable_name) \ + private: \ + variable_type variable_name##_; \ + \ + public: \ + variable_type get_##variable_name() const { return variable_name##_; } + + Property_declare_var(ObBalanceTaskHelperOp, task_op) + Property_declare_var(share::ObLSID, src_ls) + Property_declare_var(share::ObLSID, dest_ls) + Property_declare_var(uint64_t, ls_group_id) +#undef Property_declare_var +}; + +struct ObBalanceTaskHelper +{ +public: + ObBalanceTaskHelper() { reset(); } + ~ObBalanceTaskHelper() {} + void reset(); + int init(const share::SCN &operation_scn, + const uint64_t tenant_id, + const ObBalanceTaskHelperMeta &balance_task_helper_meta); + int init(const uint64_t tenant_id, + const share::SCN &operation_scn, + const ObBalanceTaskHelperOp &task_op, + const share::ObLSID &src_ls, + const share::ObLSID &dest_ls, + const uint64_t ls_group_id); + bool is_valid() const; + TO_STRING_KV(K_(balance_task_helper_meta), K_(operation_scn)); + share::SCN get_operation_scn() const + { + return operation_scn_; + } + ObBalanceTaskHelperOp get_task_op() const + { + return balance_task_helper_meta_.get_task_op(); + } + uint64_t get_tenant_id() const + { + return tenant_id_; + } + share::ObLSID get_src_ls() const + { + return balance_task_helper_meta_.get_src_ls(); + } + share::ObLSID get_dest_ls() const + { + return balance_task_helper_meta_.get_dest_ls(); + } + uint64_t get_ls_group_id() const + { + return balance_task_helper_meta_.get_ls_group_id(); + } +private: + share::SCN operation_scn_; + uint64_t tenant_id_; + ObBalanceTaskHelperMeta balance_task_helper_meta_; +}; + +class ObBalanceTaskHelperTableOperator +{ +public: + /** + * @description: insert new ls_task to __all_ls_balance_task_operator + * @param[in] ls_balance_task : a valid ls balance task + * @param[in] client: sql client or trans + * @return OB_SUCCESS if success, otherwise failed + */ + static int insert_ls_balance_task(const ObBalanceTaskHelper &ls_balance_task, + ObISQLClient &client); + /** + * @description: get task has min operation scn + * @param[in] tenant_id : user_tenant_id + * @param[in] client : sql client or trans + * @param[out] ls_balance_task : ls_balance_task of min operation_scn + * @return : + * OB_SUCCESS : get a valid ls_balance_task + * OB_ENTRY_NOT_EXIST : empty + * OTHER : fail + */ + static int pop_task(const uint64_t tenant_id, + ObISQLClient &client, + ObBalanceTaskHelper &ls_balance_task); + /** + * @description: remove task of operation_scn + * @param[in] tenant_id : user_tenant_id + * @param[in] op_scn : task's operation_scn + * @param[in] client : sql client or trans + * @return: + * OB_SUCCESS : remove_success; + * OB_ENTRY_NOT_EXIST : the task not exist + * OTHER : fail + */ + static int remove_task(const uint64_t tenant_id, const share::SCN &op_scn, + ObISQLClient &client); + static int fill_dml_spliter(share::ObDMLSqlSplicer &dml, + const ObBalanceTaskHelper &ls_balance_task); +}; +} +} + +#endif /* !OCEANBASE_SHARE_OB_LS_BALANCE_TASK_HELPER_OPERATOR_H_ */ diff --git a/src/share/balance/ob_balance_task_table_operator.cpp b/src/share/balance/ob_balance_task_table_operator.cpp new file mode 100644 index 000000000..32b56d418 --- /dev/null +++ b/src/share/balance/ob_balance_task_table_operator.cpp @@ -0,0 +1,1089 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE + +#include "ob_balance_task_table_operator.h" +#include "lib/mysqlclient/ob_isql_client.h"//ObISQLClient +#include "lib/mysqlclient/ob_mysql_result.h"//MySQLResult +#include "lib/mysqlclient/ob_mysql_proxy.h"//MySQLResult +#include "lib/mysqlclient/ob_mysql_transaction.h"//ObMySQLTrans +#include "share/inner_table/ob_inner_table_schema.h"//ALL_BALANCE_TASK_TNAME +#include "share/ob_dml_sql_splicer.h"//ObDMLSqlSplicer +#include "share/balance/ob_balance_job_table_operator.h"//job_status +#include "share/balance/ob_balance_task_helper_operator.h"//ObBalanceTaskHelper +#include "storage/tx/ob_multi_data_source.h" +#include "observer/ob_inner_sql_connection.h"//register + +using namespace oceanbase; +using namespace oceanbase::common; +namespace oceanbase +{ +namespace share +{ +static const char* BALANCE_TASK_STATUS_ARRAY[] = +{ + "INIT", "CREATE_LS", "ALTER_LS", "SET_LS_MERGING", "TRANSFER", "DROP_LS", "COMPLETED", "CANCELED", +}; +static const char *BALANCE_TASK_TYPE[] = +{ + "LS_SPLIT", "LS_ALTER", "LS_MERGE", "LS_TRANSFER", +}; + +const char* ObBalanceTaskStatus::to_str() const +{ + STATIC_ASSERT(ARRAYSIZEOF(BALANCE_TASK_STATUS_ARRAY) == BALANCE_TASK_STATUS_MAX, "array size mismatch"); + const char *type_str = "INVALID"; + if (OB_UNLIKELY(val_ >= ARRAYSIZEOF(BALANCE_TASK_STATUS_ARRAY) || val_ < 0)) { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "fatal error, unknown balance task status", K_(val)); + } else { + type_str = BALANCE_TASK_STATUS_ARRAY[val_]; + } + return type_str; +} + +ObBalanceTaskStatus::ObBalanceTaskStatus(const ObString &str) +{ + val_ = BALANCE_TASK_STATUS_INVALID; + if (str.empty()) { + } else { + for (int64_t i = 0; i < ARRAYSIZEOF(BALANCE_TASK_STATUS_ARRAY); ++i) { + if (0 == str.case_compare(BALANCE_TASK_STATUS_ARRAY[i])) { + val_ = i; + break; + } + } + } + if (BALANCE_TASK_STATUS_INVALID == val_) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid balance task status", K(val_), K(str)); + } +} + +const char* ObBalanceTaskType::to_str() const +{ + STATIC_ASSERT( + ARRAYSIZEOF(BALANCE_TASK_TYPE) == BALANCE_TASK_MAX, + "array size mismatch"); + const char *type_str = "INVALID"; + if (OB_UNLIKELY(val_ >= ARRAYSIZEOF(BALANCE_TASK_TYPE) || val_ < 0)) { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "fatal error, unknown balance task status", K_(val)); + } else { + type_str = BALANCE_TASK_TYPE[val_]; + } + return type_str; +} + +ObBalanceTaskType::ObBalanceTaskType(const ObString &str) +{ + val_ = BALANCE_TASK_INVALID; + if (str.empty()) { + } else { + for (int64_t i = 0; i < ARRAYSIZEOF(BALANCE_TASK_TYPE); ++i) { + if (0 == str.case_compare(BALANCE_TASK_TYPE[i])) { + val_ = i; + break; + } + } + } + if (BALANCE_TASK_INVALID == val_) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid balance task status", K(val_), K(str)); + } +} + +ObBalanceTaskStatus ObBalanceTask::get_next_status(const ObBalanceJobStatus &job_status) const +{ + ObBalanceTaskStatus task_status; + if (OB_UNLIKELY(!is_valid())) { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "task is invalid", "task", *this); + } else if (task_status_.is_completed() || task_status_.is_canceled()) { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "task alredy end, no next status", "task", *this); + } else if (job_status.is_canceling()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_CANCELED); // failed + } else if (task_type_.is_split_task()) { + if (task_status_.is_init()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_CREATE_LS); + } else if (task_status_.is_create_ls()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_TRANSFER); + } else if (task_status_.is_transfer()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_COMPLETED); + } else { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "split task has no other status", "task", *this); + } + } else if (task_type_.is_alter_task()) { + if (task_status_.is_init()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_ALTER_LS); + } else if (task_status_.is_alter_ls()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_COMPLETED); + } else { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "alter task has no other status", "task", *this); + } + } else if (task_type_.is_merge_task()) { + if (task_status_.is_init()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_SET_LS_MERGING); + } else if (task_status_.is_set_merge_ls()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_TRANSFER); + } else if (task_status_.is_transfer()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_DROP_LS); + } else if (task_status_.is_drop_ls()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_COMPLETED); + } else { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "merge task has no other status", "task", *this); + } + } else if (task_type_.is_transfer_task()) { + if (task_status_.is_init()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_TRANSFER); + } else if (task_status_.is_transfer()) { + task_status = ObBalanceTaskStatus(ObBalanceTaskStatus::BALANCE_TASK_STATUS_COMPLETED); + } else { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "transfer task has no other status", "task", *this); + } + } else { + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "task type is invalid", "task", *this); + } + return task_status; +} + +int ObBalanceTask::init_(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceTaskID balance_task_id, + const ObBalanceTaskType task_type, + const ObBalanceTaskStatus task_status, + const uint64_t ls_group_id, + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + const ObTransferTaskID curr_transfer_task_id, + const ObString &comment) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || ! job_id.is_valid() + || ! balance_task_id.is_valid() + || !task_type.is_valid() || !task_status.is_valid() + || !src_ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(job_id), K(balance_task_id), + K(task_type), K(task_status), K(src_ls_id)); + } else if (OB_FAIL(comment_.assign(comment))) { + LOG_WARN("failed to assign comment", KR(ret), K(comment)); + } else { + tenant_id_ = tenant_id; + job_id_ = job_id; + balance_task_id_ = balance_task_id; + src_ls_id_ = src_ls_id; + dest_ls_id_ = dest_ls_id; + current_transfer_task_id_ = curr_transfer_task_id; + task_type_ = task_type; + task_status_ = task_status; + ls_group_id_ = ls_group_id; + } + return ret; +} + +int ObBalanceTask::simple_init(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceTaskID balance_task_id, + const ObBalanceTaskType task_type, + const uint64_t ls_group_id, + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + const ObTransferPartList &part_list) +{ + int ret = OB_SUCCESS; + ObBalanceTaskStatus task_status(0); + ObTransferTaskID current_transfer_task_id; + ObString comment; + if (OB_FAIL(init_(tenant_id, job_id, balance_task_id, task_type, task_status, ls_group_id, + src_ls_id, dest_ls_id, current_transfer_task_id, comment))) { + LOG_WARN("failed to init", KR(ret), K(tenant_id), K(job_id), K(balance_task_id), + K(task_type), K(task_status), K(src_ls_id), K(current_transfer_task_id)); + } else if (OB_FAIL(part_list_.assign(part_list))) { + LOG_WARN("failed to assign commet", KR(ret), K(part_list)); + } + return ret; +} + +int ObBalanceTask::init(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceTaskID balance_task_id, + const ObBalanceTaskType task_type, + const ObBalanceTaskStatus task_status, + const uint64_t ls_group_id, + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + const ObTransferTaskID curr_transfer_task_id, + const ObString &part_list_str, + const ObString &finished_part_list_str, + const ObString &parent_list_str, + const ObString &child_list_str, + const ObString &comment) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(init_(tenant_id, job_id, balance_task_id, task_type, task_status, ls_group_id, + src_ls_id, dest_ls_id, curr_transfer_task_id, comment))) { + LOG_WARN("failed to init", KR(ret), K(tenant_id), K(job_id), K(balance_task_id), + K(task_type), K(task_status), K(src_ls_id), K(curr_transfer_task_id), K(comment)); + } else if (!parent_list_str.empty() && OB_FAIL(parent_list_.parse_from_display_str(parent_list_str))) { + LOG_WARN("failed to parse str into list", KR(ret), K(parent_list_str)); + } else if (!child_list_str.empty() && OB_FAIL(child_list_.parse_from_display_str(child_list_str))) { + LOG_WARN("failed to parse str into list", KR(ret), K(child_list_str)); + } else if (!part_list_str.empty() && OB_FAIL(part_list_.parse_from_display_str(part_list_str))) { + LOG_WARN("failed to parse str into list", KR(ret), K(part_list_str)); + } else if (!finished_part_list_str.empty() && OB_FAIL(finished_part_list_.parse_from_display_str(finished_part_list_str))) { + LOG_WARN("failed to parse str into list", KR(ret), K(finished_part_list_str)); + } else if (!is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("balance task is invalid", KR(ret), "this", *this); + } + return ret; +} + + +int ObBalanceTask::init(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceTaskID balance_task_id, + const ObBalanceTaskType task_type, + const ObBalanceTaskStatus task_status, + const uint64_t ls_group_id, + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + const ObTransferTaskID curr_transfer_task_id, + const ObTransferPartList &part_list, + const ObTransferPartList &finished_part_list, + const ObBalanceTaskIDList &parent_list, + const ObBalanceTaskIDList &child_list, + const ObString &comment) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(init_(tenant_id, job_id, balance_task_id, task_type, task_status, ls_group_id, + src_ls_id, dest_ls_id, curr_transfer_task_id, comment))) { + LOG_WARN("failed to init", KR(ret), K(tenant_id), K(job_id), K(balance_task_id), + K(task_type), K(task_status), K(src_ls_id), K(curr_transfer_task_id), K(comment)); + } else if (OB_FAIL(part_list_.assign(part_list))) { + LOG_WARN("failed to assign commet", KR(ret), K(part_list)); + } else if (OB_FAIL(finished_part_list_.assign(finished_part_list))) { + LOG_WARN("failed to assign finish part list", KR(ret), K(finished_part_list)); + } else if (OB_FAIL(parent_list_.assign(parent_list))) { + LOG_WARN("failed to assign parent list", KR(ret), K(parent_list)); + } else if (OB_FAIL(child_list_.assign(child_list))) { + LOG_WARN("failed to assign child list", KR(ret), K(child_list)); + } else if (!is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("balance task is invalid", KR(ret), "this", *this); + } + return ret; +} + +bool ObBalanceTask::is_valid() const +{ + int ret = OB_SUCCESS; + if (OB_INVALID_TENANT_ID == tenant_id_ + || !job_id_.is_valid() || !balance_task_id_.is_valid() + || !task_type_.is_valid() || !task_status_.is_valid() + || !src_ls_id_.is_valid()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("balance task is invalid", "this", *this); + } else if ( 0 < part_list_.count()) { + if (task_type_.is_alter_task()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("balance task is invalid", "this", *this); + } else if (task_type_.is_merge_task()) { + if (!task_status_.is_transfer() && !task_status_.is_canceled()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("balance task is invalid", "this", *this); + } + } + } + return OB_SUCC(ret); +} + +void ObBalanceTask::reset() +{ + tenant_id_ = OB_INVALID_TENANT_ID; + src_ls_id_.reset(); + dest_ls_id_.reset(); + job_id_.reset(); + balance_task_id_.reset(); + task_type_.reset(); + task_status_.reset(); + ls_group_id_ = OB_INVALID_ID; + current_transfer_task_id_.reset(); + part_list_.reset(); + finished_part_list_.reset(); + parent_list_.reset(); + child_list_.reset(); + comment_.reset(); +} + +int ObBalanceTask::assign(const ObBalanceTask &other) +{ + int ret = OB_SUCCESS; + if (&other != this) { + reset(); + if (OB_FAIL(part_list_.assign(other.part_list_))) { + LOG_WARN("failed to assign part list", KR(ret), K(other)); + } else if (OB_FAIL(finished_part_list_.assign(other.finished_part_list_))) { + LOG_WARN("failed to assign finished part list", KR(ret), K(other)); + } else if (OB_FAIL(parent_list_.assign(other.parent_list_))) { + LOG_WARN("failed to assign parent list", KR(ret), K(other)); + } else if (OB_FAIL(child_list_.assign(other.child_list_))) { + LOG_WARN("failed to assign child list", KR(ret), K(other)); + } else if (other.comment_.is_valid() && OB_FAIL(comment_.assign(other.comment_))) { + LOG_WARN("failed to assign comment", KR(ret), K(other)); + } else { + tenant_id_ = other.tenant_id_; + src_ls_id_ = other.src_ls_id_; + dest_ls_id_ = other.dest_ls_id_; + job_id_ = other.job_id_; + balance_task_id_ = other.balance_task_id_; + task_type_ = other.task_type_; + task_status_ = other.task_status_; + ls_group_id_ = other.ls_group_id_; + current_transfer_task_id_ = other.current_transfer_task_id_; + } + } + return ret; +} + + + +int ObBalanceTaskTableOperator::insert_new_task(const ObBalanceTask &task, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObDMLExecHelper exec(client, task.get_tenant_id()); + if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("task is invalid", KR(ret), K(task)); + } else if (OB_FAIL(fill_dml_spliter(dml, task))) { + LOG_WARN("failed to assign sql", KR(ret), K(task)); + } else if (OB_FAIL(exec.exec_insert(OB_ALL_BALANCE_TASK_TNAME, + dml, affected_rows))) { + LOG_WARN("execute update failed", KR(ret), K(task)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected single row", KR(ret), K(affected_rows)); + } + return ret; +} + +int ObBalanceTaskTableOperator::get_balance_task(const uint64_t tenant_id, + const ObBalanceTaskID balance_task_id, + const bool for_update, + ObISQLClient &client, + ObBalanceTask &task, + int64_t &start_time, + int64_t &finish_time) +{ + int ret = OB_SUCCESS; + task.reset(); + finish_time = OB_INVALID_TIMESTAMP; + ObSqlString sql; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || ! balance_task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(balance_task_id)); + } else if (OB_FAIL(sql.assign_fmt("select time_to_usec(gmt_create) as start_time, " + " time_to_usec(gmt_modified) as finish_time, * from %s where task_id = %ld", + OB_ALL_BALANCE_TASK_TNAME, balance_task_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(balance_task_id), K(sql)); + } else if (for_update && OB_FAIL(sql.append_fmt(" for update"))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql)); + } else { + HEAP_VAR(ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = NULL; + if (OB_FAIL(client.read(res, tenant_id, sql.ptr()))) { + LOG_WARN("failed to read", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("balance task not eixst", KR(ret), K(sql)); + } else { + LOG_WARN("failed to get balance task", KR(ret), K(sql)); + } + } else if (OB_FAIL(fill_cell(tenant_id, result, task))) { + LOG_WARN("failed to fill cell", KR(ret), K(sql)); + } else { + EXTRACT_INT_FIELD_MYSQL(*result, "start_time", start_time, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "finish_time", finish_time, int64_t); + if (OB_FAIL(ret)) { + LOG_WARN("failed to get finish time", KR(ret), K(start_time), K(finish_time), K(sql)); + } + } + } + } + return ret; +} + +int ObBalanceTaskTableOperator::update_task_status( + const ObBalanceTask &balance_task, + const ObBalanceTaskStatus new_task_status, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = 0; + bool clear_comment = new_task_status.is_canceled() ? false : true; + const ObBalanceTaskStatus old_task_status = balance_task.get_task_status(); + const uint64_t tenant_id = balance_task.get_tenant_id(); + const ObBalanceTaskID balance_task_id = balance_task.get_balance_task_id(); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || ! balance_task_id.is_valid() + || !old_task_status.is_valid() || !new_task_status.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(old_task_status), K(new_task_status), K(balance_task_id)); + } else if (OB_FAIL(sql.assign_fmt("update %s set status = '%s'", + OB_ALL_BALANCE_TASK_TNAME, + new_task_status.to_str()))) { + LOG_WARN("failed to assign sql", KR(ret), K(new_task_status), K(old_task_status)); + } else if (clear_comment && OB_FAIL(sql.append(", comment = ''"))) { + LOG_WARN("failed to append sql", KR(ret), K(sql)); + } else if (OB_FAIL(sql.append_fmt(" where status = '%s' and task_id = %ld", + old_task_status.to_str(), balance_task_id.id()))) { + LOG_WARN("failed to append sql", KR(ret), K(sql), K(old_task_status), K(balance_task_id)); + } else if (OB_FAIL(trans.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(tenant_id), K(sql)); + } else if (is_zero_row(affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("expected one row, may status change", KR(ret), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected single row", KR(ret), K(sql)); + } else if (new_task_status.is_transfer() || balance_task.get_task_status().is_transfer()) { + //sub trans + ObBalanceTaskHelperMeta ls_balance_task; + ObBalanceTaskHelperOp task_op; + if (new_task_status.is_transfer()) { + task_op = ObBalanceTaskHelperOp(ObBalanceTaskHelperOp::LS_BALANCE_TASK_OP_TRANSFER_BEGIN); + } else { + task_op = ObBalanceTaskHelperOp(ObBalanceTaskHelperOp::LS_BALANCE_TASK_OP_TRANSFER_END); + } + + observer::ObInnerSQLConnection *conn = + static_cast(trans.get_connection()); + const int64_t length = ls_balance_task.get_serialize_size(); + char *buf = NULL; + int64_t pos = 0; + const transaction::ObTxDataSourceType type = transaction::ObTxDataSourceType::TRANSFER_TASK; + ObArenaAllocator allocator("BalanceTask"); + if (OB_ISNULL(conn)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("connection or trans service is null", KR(ret), KP(conn), K(tenant_id)); + } else if (OB_ISNULL(buf = static_cast(allocator.alloc(length)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc buf", KR(ret), K(length)); + } else if (OB_FAIL(ls_balance_task.init(task_op, + balance_task.get_src_ls_id(), balance_task.get_dest_ls_id(), + balance_task.get_ls_group_id()))) { + LOG_WARN("failed to init balance task helper", KR(ret), K(tenant_id), K(balance_task)); + } else if (OB_FAIL(ls_balance_task.serialize(buf, length, pos))) { + LOG_WARN("failed to serialize balance task helper", KR(ret), K(ls_balance_task), + K(length), K(pos)); + } else if (OB_UNLIKELY(pos > length)) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("serialize error", KR(ret), K(pos), K(length)); + } else if (OB_FAIL(conn->register_multi_data_source(tenant_id, SYS_LS, type, buf, pos))) { + LOG_WARN("failed to register multi data source", KR(ret), K(tenant_id), K(type), K(buf)); + } + } + return ret; +} + +int ObBalanceTaskTableOperator::update_task_comment( + const uint64_t tenant_id, const ObBalanceTaskID task_id, + const common::ObString &new_comment, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = 0; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(new_comment), K(task_id)); + } else if (OB_FAIL(sql.assign_fmt("update %s set comment = '%.*s' where " + "task_id = %ld ", + OB_ALL_BALANCE_TASK_TNAME, + new_comment.length(), new_comment.ptr(), + task_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(new_comment), K(task_id)); + } else if (OB_FAIL(client.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(tenant_id), K(sql)); + } else if (is_zero_row(affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("expected one row, may status change", KR(ret), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected single row", KR(ret), K(sql)); + } + return ret; +} + +int ObBalanceTaskTableOperator::fill_dml_spliter(share::ObDMLSqlSplicer &dml, + const ObBalanceTask &task) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(dml.add_pk_column("task_id", task.get_balance_task_id().id())) + || OB_FAIL(dml.add_column("job_id", task.get_job_id().id())) + || OB_FAIL(dml.add_column("task_type", task.get_task_type().to_str())) + || OB_FAIL(dml.add_column("status", task.get_task_status().to_str())) + || OB_FAIL(dml.add_column("src_ls", task.get_src_ls_id().id())) + || OB_FAIL(dml.add_column("dest_ls", task.get_dest_ls_id().id())) + || OB_FAIL(dml.add_column("ls_group_id", task.get_ls_group_id())) + || OB_FAIL(dml.add_column("current_transfer_task_id", task.get_current_transfer_task_id().id())) + || OB_FAIL(dml.add_column("comment", task.get_comment()))) { + LOG_WARN("failed to fill dml spliter", KR(ret), K(task)); + } else { + common::ObArenaAllocator allocator; + ObString part_list_str; + ObString finished_part_list_str; + ObString parent_list_str; + ObString child_list_str; + if (OB_FAIL(task.get_part_list().to_display_str(allocator, part_list_str))) { + LOG_WARN("failed to get part list str", KR(ret), K(task)); + } else if (OB_FAIL(task.get_finished_part_list().to_display_str(allocator, finished_part_list_str))) { + LOG_WARN("failed to get part list str", KR(ret), K(task)); + } else if (OB_FAIL(task.get_parent_task_list().to_display_str(allocator, parent_list_str))) { + LOG_WARN("failed to get parent list", KR(ret), K(task)); + } else if (OB_FAIL(task.get_child_task_list().to_display_str(allocator, child_list_str))) { + LOG_WARN("failed to get child list str", KR(ret), K(task)); + } else if (OB_FAIL(dml.add_column("part_list", part_list_str)) + || OB_FAIL(dml.add_column("finished_part_list", finished_part_list_str)) + || OB_FAIL(dml.add_column("part_count", task.get_part_list().count())) + || OB_FAIL(dml.add_column("finished_part_count", task.get_finished_part_list().count())) + || OB_FAIL(dml.add_column("parent_list", parent_list_str)) + || OB_FAIL(dml.add_column("child_list", child_list_str))) { + LOG_WARN("failed to add column", KR(ret), K(part_list_str), K(finished_part_list_str), + K(parent_list_str), K(child_list_str)); + } + } + return ret; +} + +int ObBalanceTaskTableOperator::start_transfer_task(const uint64_t tenant_id, + const ObBalanceTaskID balance_task_id, + const ObTransferTaskID transfer_task_id, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = 0; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || ! balance_task_id.is_valid() + || ! transfer_task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(balance_task_id), K(transfer_task_id)); + } else if (OB_FAIL(sql.assign_fmt("update %s set current_transfer_task_id = %ld where " + "task_id = %ld and current_transfer_task_id = %ld", + OB_ALL_BALANCE_TASK_TNAME, transfer_task_id.id(), + balance_task_id.id(), ObTransferTaskID::INVALID_ID))) { + LOG_WARN("failed to assign sql", KR(ret), K(transfer_task_id), K(balance_task_id)); + } else if (OB_FAIL(client.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(tenant_id), K(sql)); + } else if (is_zero_row(affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("expected one row, may status change", KR(ret), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected single row", KR(ret), K(sql)); + } + + return ret; +} + +int ObBalanceTaskTableOperator::finish_transfer_task( + const ObBalanceTask &balance_task, + const ObTransferTaskID transfer_task_id, + const ObTransferPartList &transfer_finished_part_list, + ObISQLClient &client, + ObTransferPartList &to_do_part_list, + bool &all_part_transferred) +{ + int ret = OB_SUCCESS; + all_part_transferred = false; + to_do_part_list.reset(); + ObSqlString sql; + int64_t affected_rows = 0; + common::ObArenaAllocator allocator; + ObTransferPartList new_finished_part_list; // balance finished + transfer finished + ObString to_do_part_list_str; + ObString new_finished_part_list_str; + const int64_t invalid_transfer_task_id = ObTransferTaskID::INVALID_ID; + + if (OB_UNLIKELY(!balance_task.is_valid() + || !transfer_task_id.is_valid() + || balance_task.get_part_list().empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(balance_task), K(transfer_task_id)); + } else if (OB_FAIL(common::append(new_finished_part_list, balance_task.get_finished_part_list()))) { + LOG_WARN("assign failed", KR(ret), K(balance_task), K(new_finished_part_list)); + } else if (OB_FAIL(common::append(new_finished_part_list, transfer_finished_part_list))) { + LOG_WARN("append failed", KR(ret), K(transfer_finished_part_list), K(new_finished_part_list)); + } else if (OB_FAIL(new_finished_part_list.to_display_str(allocator, new_finished_part_list_str))) { + LOG_WARN("failed to transfer list to str", KR(ret), K(new_finished_part_list)); + } else if (OB_FAIL(common::get_difference( + balance_task.get_part_list(), + new_finished_part_list, + to_do_part_list))) { + LOG_WARN("get difference failed", KR(ret), K(balance_task), K(transfer_finished_part_list)); + } else if (OB_FAIL(to_do_part_list.to_display_str(allocator, to_do_part_list_str))) { + LOG_WARN("failed to transfer list to str", KR(ret), K(to_do_part_list)); + } else if (OB_FAIL(sql.assign_fmt("update %s set current_transfer_task_id = %ld, " + "finished_part_list = '%.*s', part_list = '%.*s', part_count = %ld, finished_part_count = %ld " + "where task_id = %ld and current_transfer_task_id = %ld", + OB_ALL_BALANCE_TASK_TNAME, + invalid_transfer_task_id, + new_finished_part_list_str.length(), + new_finished_part_list_str.ptr(), + to_do_part_list_str.length(), + to_do_part_list_str.ptr(), + to_do_part_list.count(), + new_finished_part_list.count(), + balance_task.get_balance_task_id().id(), + transfer_task_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(transfer_task_id), + K(balance_task), K(new_finished_part_list_str), K(to_do_part_list_str)); + } else if (OB_FAIL(client.write(balance_task.get_tenant_id(), sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(balance_task), K(sql)); + } else if (is_zero_row(affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("expected one row, may status change", KR(ret), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected single row", KR(ret), K(sql)); + } + + if (OB_SUCC(ret) && to_do_part_list.empty()) { + all_part_transferred = true; + } + + return ret; +} +//maybe in trans TODO +//remove task from __all_balance_task to __all_balance_task_history +int ObBalanceTaskTableOperator::clean_task(const uint64_t tenant_id, + const ObBalanceTaskID balance_task_id, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObBalanceTask task; + int64_t affected_rows = 0; + ObSqlString sql; + int64_t finish_time = OB_INVALID_TIMESTAMP; + int64_t start_time = OB_INVALID_TIMESTAMP; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || ! balance_task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id), K(balance_task_id)); + } else if (OB_FAIL(get_balance_task(tenant_id, balance_task_id, true, trans, task, start_time, finish_time))) { + LOG_WARN("failed to get task", KR(ret), K(tenant_id), K(balance_task_id)); + } else if (OB_UNLIKELY(! task.get_task_status().is_finish_status())) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("clean a not finished task unexpected", KR(ret), K(task)); + } else if (OB_FAIL(sql.assign_fmt("delete from %s where task_id = %ld", + OB_ALL_BALANCE_TASK_TNAME, balance_task_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(balance_task_id)); + } else if (OB_FAIL(trans.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to write", KR(ret), K(tenant_id), K(sql)); + } else if(!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expect one row", KR(ret), K(sql), K(affected_rows)); + } else { + // insert into history + ObDMLSqlSplicer dml; + ObDMLExecHelper exec(trans, task.get_tenant_id()); + if (OB_FAIL(fill_dml_spliter(dml, task))) { + LOG_WARN("failed to assign sql", KR(ret), K(task)); + } else if (OB_FAIL(dml.add_time_column("create_time", start_time))) { + LOG_WARN("failed to add start time", KR(ret), K(start_time)); + } else if (OB_FAIL(dml.add_time_column("finish_time", finish_time))) { + LOG_WARN("failed to add start time", KR(ret), K(task), K(finish_time)); + } else if (OB_FAIL(exec.exec_insert(OB_ALL_BALANCE_TASK_HISTORY_TNAME, dml, + affected_rows))) { + LOG_WARN("execute update failed", KR(ret), K(task)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expect one row", KR(ret), K(sql), K(affected_rows)); + } + } + return ret; +} + +int ObBalanceTaskTableOperator::clean_parent_info(const uint64_t tenant_id, + const ObBalanceTaskID parent_task_id, + const ObBalanceJobID balance_job_id, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = 0; + + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || ! parent_task_id.is_valid() + || ! balance_job_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", KR(ret), K(tenant_id), K(parent_task_id), K(balance_job_id)); + } else if (OB_FAIL(sql.assign_fmt("update %s set parent_list = ", OB_ALL_BALANCE_TASK_TNAME))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql)); + } else if (OB_FAIL(sql.append_fmt( + "replace(replace(replace(parent_list, ',%ld', ''), '%ld,', ''), '%ld', '')", + parent_task_id.id(), parent_task_id.id(), parent_task_id.id()))) { + LOG_WARN("failed to append fmt sql", KR(ret), K(parent_task_id), K(sql)); + } else if (OB_FAIL(sql.append_fmt(" where job_id = %ld", balance_job_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(balance_job_id), K(sql)); + } else if (OB_FAIL(trans.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(tenant_id), K(sql)); + } + + LOG_INFO("clean parent info finished", KR(ret), K(tenant_id), K(parent_task_id), K(balance_job_id), + K(affected_rows), K(sql)); + + return ret; +} + +int ObBalanceTaskTableOperator::remove_parent_task(const uint64_t tenant_id, + const ObBalanceTaskID balance_task_id, + const ObBalanceTaskID parent_task_id, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + ObBalanceTask task; + int64_t affected_rows = 0; + common::ObMySQLTransaction trans; + ObSqlString sql; + int64_t index = OB_INVALID_INDEX_INT64; + int64_t finish_time = OB_INVALID_TIMESTAMP;//no used + int64_t start_time = OB_INVALID_TIMESTAMP;//no used + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_FAIL(trans.start(&client, tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id)); + } else if (OB_FAIL(get_balance_task(tenant_id, balance_task_id, true, trans, + task, start_time, finish_time))) { + LOG_WARN("failed to get task", KR(ret), K(tenant_id), K(balance_task_id)); + } else if (!has_exist_in_array(task.get_parent_task_list(), parent_task_id, &index)) { + LOG_INFO("has not in parent list", KR(ret), K(parent_task_id), K(task)); + } else { + ObBalanceTaskIDList parent_list; + common::ObArenaAllocator allocator; + ObString parent_list_str; + if (OB_FAIL(parent_list.assign(task.get_parent_task_list()))) { + LOG_WARN("failed to assign array", KR(ret), K(task)); + } else if (OB_FAIL(parent_list.remove(index))) { + LOG_WARN("failed to remove it from parent list", KR(ret), K(index), K(parent_list)); + } else if (OB_FAIL(parent_list.to_display_str(allocator, parent_list_str))) { + LOG_WARN("failed to get str", KR(ret), K(parent_list)); + } else { + ObSqlString sql; + int64_t affected_rows = 0; + if (OB_FAIL(sql.assign_fmt("update %s set parent_list = '%.*s' where " + "task_id = %ld", OB_ALL_BALANCE_TASK_TNAME, parent_list_str.length(), + parent_list_str.ptr(), balance_task_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(parent_list_str), + K(balance_task_id)); + } else if (OB_FAIL(trans.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(tenant_id), K(sql)); + } else if (is_zero_row(affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("expected one row, may status change", KR(ret), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected single row", KR(ret), K(sql)); + } + } + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + return ret; +} +int ObBalanceTaskTableOperator::load_can_execute_task(const uint64_t tenant_id, + ObBalanceTaskIArray &task_array, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + task_array.reset(); + ObSqlString sql; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_FAIL(sql.assign_fmt("select * from %s where parent_list is null or parent_list = ''", + OB_ALL_BALANCE_TASK_TNAME))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql)); + } else if (OB_FAIL(read_tasks_(tenant_id, client, sql, task_array))) { + LOG_WARN("failed to read task", KR(ret), K(tenant_id), K(sql)); + } + LOG_INFO("load can-execute balance task", KR(ret), K(task_array), K(sql)); + return ret; +} + +int ObBalanceTaskTableOperator::get_job_cannot_execute_task( + const uint64_t tenant_id, const ObBalanceJobID balance_job_id, + ObBalanceTaskIArray &task_array, ObISQLClient &client) +{ + int ret = OB_SUCCESS; + task_array.reset(); + ObSqlString sql; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || !balance_job_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(balance_job_id)); + } else if (OB_FAIL(sql.assign_fmt("select * from %s where job_id = %ld and " + "parent_list != '' and parent_list is not null", + OB_ALL_BALANCE_TASK_TNAME, balance_job_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql), K(balance_job_id)); + } else if (OB_FAIL(read_tasks_(tenant_id, client, sql, task_array))) { + LOG_WARN("failed to read task", KR(ret), K(tenant_id), K(sql)); + } + LOG_INFO("load job's can not execute balance tasks", KR(ret), K(balance_job_id), K(task_array), K(sql)); + return ret; +} + +int ObBalanceTaskTableOperator::read_tasks_(const uint64_t tenant_id, + ObISQLClient &client, + const ObSqlString &sql, + ObBalanceTaskIArray &task_array) +{ + int ret = OB_SUCCESS; + task_array.reset(); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || sql.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(sql)); + } else { + HEAP_VAR(ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = NULL; + if (OB_FAIL(client.read(res, tenant_id, sql.ptr()))) { + LOG_WARN("failed to read", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else { + ObBalanceTask task; + while(OB_SUCC(ret) && OB_SUCC(result->next())) { + if (OB_FAIL(fill_cell(tenant_id, result, task))) { + LOG_WARN("failed to fill cell", KR(ret), K(sql)); + } else if (OB_FAIL(task_array.push_back(task))) { + LOG_WARN("failed to push back task", KR(ret), K(task)); + } + }//end while + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get cell", KR(ret)); + } + } + } + } + return ret; +} + +int ObBalanceTaskTableOperator::fill_cell(const uint64_t tenant_id, + sqlclient::ObMySQLResult *result, + ObBalanceTask &task) { + int ret = OB_SUCCESS; + task.reset(); + if (OB_ISNULL(result)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("result is null", KR(ret)); + } else { + int64_t job_id = ObBalanceJobID::INVALID_ID; + int64_t balance_task_id = ObBalanceTaskID::INVALID_ID; + uint64_t ls_group_id = OB_INVALID_ID; + int64_t src_ls_id = 0; + int64_t dest_ls_id = 0; + int64_t transfer_task_id = ObTransferTaskID::INVALID_ID; + ObString task_type, task_status; + ObString part_list_str, finished_part_list_str; + ObString parent_list_str, child_list_str; + ObString comment; + EXTRACT_INT_FIELD_MYSQL(*result, "job_id", job_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "task_id", balance_task_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "src_ls", src_ls_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "dest_ls", dest_ls_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "ls_group_id", ls_group_id, uint64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "current_transfer_task_id", transfer_task_id, int64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "task_type", task_type); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "status", task_status); + EXTRACT_VARCHAR_FIELD_MYSQL_SKIP_RET(*result, "comment", comment); + EXTRACT_VARCHAR_FIELD_MYSQL_SKIP_RET(*result, "parent_list", + parent_list_str); + EXTRACT_VARCHAR_FIELD_MYSQL_SKIP_RET(*result, "child_list", + child_list_str); + EXTRACT_VARCHAR_FIELD_MYSQL_SKIP_RET(*result, "part_list", + part_list_str); + EXTRACT_VARCHAR_FIELD_MYSQL_SKIP_RET(*result, "finished_part_list", + finished_part_list_str); + if (OB_FAIL(ret)) { + LOG_WARN("failed to get cell", KR(ret), K(job_id), + K(task_type), K(task_status), K(ls_group_id), + K(src_ls_id), K(dest_ls_id), + K(transfer_task_id), K(part_list_str), K(finished_part_list_str), + K(parent_list_str), K(child_list_str)); + } else if (OB_FAIL(task.init( + tenant_id, ObBalanceJobID(job_id), ObBalanceTaskID(balance_task_id), + ObBalanceTaskType(task_type), + ObBalanceTaskStatus(task_status), ls_group_id, + ObLSID(src_ls_id), ObLSID(dest_ls_id), + ObTransferTaskID(transfer_task_id), + part_list_str, finished_part_list_str, + parent_list_str, child_list_str, comment))) { + LOG_WARN("failed to init task", KR(ret), K(tenant_id), K(job_id), + K(balance_task_id), K(task_type), K(task_status), K(ls_group_id), + K(src_ls_id), K(dest_ls_id), K(transfer_task_id), K(comment), + K(part_list_str), K(finished_part_list_str), K(parent_list_str), K(child_list_str)); + } + } + + return ret; +} + +int ObBalanceTaskTableOperator::get_job_task_cnt(const uint64_t tenant_id, + const ObBalanceJobID job_id, int64_t &task_cnt, ObISQLClient &client) +{ + int ret = OB_SUCCESS; + task_cnt = 0; + ObSqlString sql; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || ! job_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(job_id)); + } else if (OB_FAIL(sql.assign_fmt("select count(*) as task_cnt from %s where job_id = %ld", + OB_ALL_BALANCE_TASK_TNAME, job_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(job_id), K(sql)); + } else { + HEAP_VAR(ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = NULL; + if (OB_FAIL(client.read(res, tenant_id, sql.ptr()))) { + LOG_WARN("failed to read", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else if (OB_FAIL(result->next())) { + LOG_WARN("failed to get balance task", KR(ret), K(sql)); + } else { + EXTRACT_INT_FIELD_MYSQL(*result, "task_cnt", task_cnt, int64_t); + if (OB_FAIL(ret)) { + LOG_WARN("failed to task cnt", KR(ret), K(sql)); + } + } + } + } + return ret; +} + +int ObBalanceTaskTableOperator::update_merge_ls_part_list(const uint64_t tenant_id, + const ObBalanceTaskID balance_task_id, + const ObTransferPartList &part_list, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = 0; + common::ObArenaAllocator allocator; + ObString part_list_str; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !balance_task_id.is_valid() + || 0 == part_list.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(balance_task_id), + K(part_list)); + } else if (OB_FAIL(part_list.to_display_str(allocator, part_list_str))) { + LOG_WARN("failed to transfer list to str", KR(ret), K(part_list)); + } else if (OB_FAIL(sql.assign_fmt("update %s set part_list = '%.*s', part_count = %ld where " + "task_id = %ld and part_count = 0", + OB_ALL_BALANCE_TASK_TNAME, part_list_str.length(), + part_list_str.ptr(), part_list.count(), balance_task_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(balance_task_id), K(part_list_str)); + } else if (OB_FAIL(trans.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(tenant_id), K(sql)); + } else if (is_zero_row(affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("expected one row, may status change", KR(ret), K(sql), K(affected_rows)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expected single row", KR(ret), K(sql), K(affected_rows)); + } + + return ret; +} + +int ObBalanceTaskTableOperator::get_merge_task_dest_ls_by_src_ls( + ObISQLClient &sql_client, + const uint64_t tenant_id, + const ObLSID &src_ls, + ObLSID &dest_ls) +{ + int ret = OB_SUCCESS; + dest_ls.reset(); + if (OB_UNLIKELY(!src_ls.is_valid_with_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(src_ls)); + } else { + SMART_VAR(ObISQLClient::ReadResult, result) { + ObSqlString sql; + int64_t int_ls_id; + common::sqlclient::ObMySQLResult *res; + if (OB_FAIL(sql.assign_fmt( + "select dest_ls from %s where src_ls = %ld and task_type = '%s' limit 1", + OB_ALL_BALANCE_TASK_TNAME, + src_ls.id(), + ObBalanceTaskType(ObBalanceTaskType::BALANCE_TASK_MERGE).to_str()))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql)); + } else if (OB_FAIL(sql_client.read(result, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(res = result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(res->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("balance task not found", KR(ret), K(tenant_id), K(sql)); + } else { + LOG_WARN("next failed", KR(ret), K(tenant_id), K(sql)); + } + } else if (OB_FAIL(res->get_int("dest_ls", int_ls_id))) { + LOG_WARN("get int failed", KR(ret), K(tenant_id), K(sql)); + } else { + dest_ls = int_ls_id; + } + } + } + return ret; +} + +int ObBalanceTaskMDSHelper::on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx) +{ + UNUSEDx(buf, len, ctx); + return OB_SUCCESS; +} + +int ObBalanceTaskMDSHelper::on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + UNUSEDx(buf, len, scn, ctx); + return OB_SUCCESS; +} +}//end of share +}//end of ob diff --git a/src/share/balance/ob_balance_task_table_operator.h b/src/share/balance/ob_balance_task_table_operator.h new file mode 100644 index 000000000..c7c223568 --- /dev/null +++ b/src/share/balance/ob_balance_task_table_operator.h @@ -0,0 +1,460 @@ +/** + * Copyright (c) 2021 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_OB_BALANCE_TASK_OPERATOR_H_ +#define OCEANBASE_SHARE_OB_BALANCE_TASK_OPERATOR_H_ + +#include "lib/container/ob_array.h"//ObArray +#include "lib/container/ob_iarray.h"//ObIArray +#include "lib/string/ob_sql_string.h"//ObSqlString +#include "lib/allocator/ob_allocator.h"//ObIAllocator +#include "share/ob_ls_id.h"//share::ObLSID +#include "share/ob_display_list.h" // ObDisplayList +#include "share/transfer/ob_transfer_info.h"//ObTransferPartList +#include "share/ob_balance_define.h" // ObBalanceJobID, ObBalanceTaskID, ObTransferTaskID + +namespace oceanbase +{ + +namespace common +{ +class ObISQLClient; +class ObString; +class ObMySQLTransaction; +namespace sqlclient +{ +class ObMySQLResult; +} +} +namespace storage +{ +namespace mds +{ +class BufferCtx; +} +} +namespace share +{ +class ObBalanceJobStatus; +class ObDMLSqlSplicer; +#define IS_BALANCE_TASK(BALANCE_TASK, BALANCE)\ + bool is_##BALANCE()const { return BALANCE_TASK == val_;} +class ObBalanceTaskStatus +{ +public: + static const int64_t BALANCE_TASK_STATUS_INVALID = -1; + static const int64_t BALANCE_TASK_STATUS_INIT = 0; + static const int64_t BALANCE_TASK_STATUS_CREATE_LS = 1; + static const int64_t BALANCE_TASK_STATUS_ALTER_LS = 2; + static const int64_t BALANCE_TASK_STATUS_SET_LS_MERGING = 3; + static const int64_t BALANCE_TASK_STATUS_TRANSFER = 4; + static const int64_t BALANCE_TASK_STATUS_DROP_LS = 5; + static const int64_t BALANCE_TASK_STATUS_COMPLETED = 6; + static const int64_t BALANCE_TASK_STATUS_CANCELED = 7; + static const int64_t BALANCE_TASK_STATUS_MAX = 8; + ObBalanceTaskStatus(const int64_t value = BALANCE_TASK_STATUS_INVALID) : val_(value) {}; + ObBalanceTaskStatus(const ObString &str); + ~ObBalanceTaskStatus() {reset(); } + +public: + void reset() { val_ = BALANCE_TASK_STATUS_INVALID; } + bool is_valid() const { return val_ != BALANCE_TASK_STATUS_INVALID; } + const char* to_str() const; + + // assignment + ObBalanceTaskStatus &operator=(const int64_t value) { val_ = value; return *this; } + + // compare operator + bool operator == (const ObBalanceTaskStatus &other) const { return val_ == other.val_; } + bool operator != (const ObBalanceTaskStatus &other) const { return val_ != other.val_; } + + // ObBalanceTaskStatus attribute interface + IS_BALANCE_TASK(BALANCE_TASK_STATUS_INIT, init) + IS_BALANCE_TASK(BALANCE_TASK_STATUS_CREATE_LS, create_ls) + IS_BALANCE_TASK(BALANCE_TASK_STATUS_ALTER_LS, alter_ls); + IS_BALANCE_TASK(BALANCE_TASK_STATUS_DROP_LS, drop_ls) + IS_BALANCE_TASK(BALANCE_TASK_STATUS_SET_LS_MERGING, set_merge_ls) + IS_BALANCE_TASK(BALANCE_TASK_STATUS_TRANSFER, transfer) + IS_BALANCE_TASK(BALANCE_TASK_STATUS_COMPLETED, completed) + IS_BALANCE_TASK(BALANCE_TASK_STATUS_CANCELED, canceled) + + // COMPLETED / CANCELED + bool is_finish_status() const { return (is_completed() || is_canceled()); } + + TO_STRING_KV(K_(val), "task_status", to_str()); +private: + int64_t val_; +}; +class ObBalanceTaskType +{ +public: + static const int64_t BALANCE_TASK_INVALID = -1; + static const int64_t BALANCE_TASK_SPLIT = 0; + static const int64_t BALANCE_TASK_ALTER = 1; + static const int64_t BALANCE_TASK_MERGE = 2; + static const int64_t BALANCE_TASK_TRANSFER = 3; + static const int64_t BALANCE_TASK_MAX = 4; + + + ObBalanceTaskType(const int64_t value = BALANCE_TASK_INVALID) : val_(value) {} + ObBalanceTaskType(const ObString &str); +public: + void reset() { val_ = BALANCE_TASK_INVALID; } + bool is_valid() const { return val_ != BALANCE_TASK_INVALID; } + const char* to_str() const; + TO_STRING_KV(K_(val), "task_type", to_str()); + + IS_BALANCE_TASK(BALANCE_TASK_SPLIT, split_task) + IS_BALANCE_TASK(BALANCE_TASK_ALTER, alter_task) + IS_BALANCE_TASK(BALANCE_TASK_MERGE, merge_task) + IS_BALANCE_TASK(BALANCE_TASK_TRANSFER, transfer_task) + // assignment + ObBalanceTaskType &operator=(const int64_t value) { val_ = value; return *this; } + + // compare operator + bool operator == (const ObBalanceTaskType &other) const { return val_ == other.val_; } + bool operator != (const ObBalanceTaskType &other) const { return val_ != other.val_; } + +private: + int64_t val_; +}; + +typedef ObDisplayList ObBalanceTaskIDList; + +class ObBalanceTaskMDSHelper +{ +public: + static int on_register( + const char* buf, + const int64_t len, + storage::mds::BufferCtx &ctx); + static int on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + storage::mds::BufferCtx &ctx); +}; + +struct ObBalanceTask +{ +public: + ObBalanceTask() { reset(); } + ~ObBalanceTask() {} + void reset(); + int init(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceTaskID balance_task_id, + const ObBalanceTaskType task_type, + const ObBalanceTaskStatus task_status, + const uint64_t ls_group_id, + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + const ObTransferTaskID curr_transfer_task_id, + const ObTransferPartList &part_list, + const ObTransferPartList &finished_part_list, + const ObBalanceTaskIDList &parent_list, + const ObBalanceTaskIDList &child_list, + const ObString &comment); + int init(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceTaskID balance_task_id, + const ObBalanceTaskType task_type, + const ObBalanceTaskStatus task_status, + const uint64_t ls_group_id, + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + const ObTransferTaskID curr_transfer_task_id, + const ObString &part_list_str, + const ObString &finished_part_list_str, + const ObString &parent_list_str, + const ObString &child_list_str, + const ObString &comment); + int simple_init(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceTaskID balance_task_id, + const ObBalanceTaskType task_type, + const uint64_t ls_group_id, + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + const ObTransferPartList &part_list); + + bool is_valid() const; + TO_STRING_KV(K_(tenant_id), K_(job_id), K_(balance_task_id), K_(task_status), + K_(src_ls_id), K_(dest_ls_id), + K_(task_type), K_(ls_group_id), + K_(current_transfer_task_id), K_(parent_list), K_(child_list), + K_(part_list), K_(finished_part_list), K_(comment)); +private: +int init_(const uint64_t tenant_id, + const ObBalanceJobID job_id, + const ObBalanceTaskID balance_task_id, + const ObBalanceTaskType task_type, + const ObBalanceTaskStatus task_status, + const uint64_t ls_group_id, + const ObLSID &src_ls_id, + const ObLSID &dest_ls_id, + const ObTransferTaskID curr_transfer_task_id, + const ObString &comment); +public: + ObBalanceTaskStatus get_next_status(const ObBalanceJobStatus &job_status) const; +#define Property_declare_var(variable_type, variable_name) \ + private: \ + variable_type variable_name##_; \ + \ + public: \ + variable_type get_##variable_name() const { return variable_name##_; } + + Property_declare_var(uint64_t, tenant_id) + Property_declare_var(ObLSID, src_ls_id) + Property_declare_var(ObLSID, dest_ls_id) + Property_declare_var(ObBalanceJobID, job_id) + Property_declare_var(ObBalanceTaskID, balance_task_id) + Property_declare_var(ObBalanceTaskType, task_type) + Property_declare_var(ObBalanceTaskStatus, task_status) + Property_declare_var(uint64_t, ls_group_id) + Property_declare_var(ObTransferTaskID, current_transfer_task_id) + +#undef Property_declare_var + int assign(const ObBalanceTask &other); +public: + const ObBalanceTaskIDList& get_parent_task_list() const { return parent_list_; } + const ObBalanceTaskIDList& get_child_task_list() const { return child_list_; } + const ObTransferPartList& get_part_list() const {return part_list_;} + const ObTransferPartList& get_finished_part_list() const {return finished_part_list_;} + ObBalanceTaskIDList& get_parent_task_list() { return parent_list_; } + ObBalanceTaskIDList& get_child_task_list() { return child_list_; } + const ObSqlString& get_comment() const { return comment_; } + +private: + ObTransferPartList part_list_; + ObTransferPartList finished_part_list_; + ObBalanceTaskIDList parent_list_; + ObBalanceTaskIDList child_list_; + ObSqlString comment_; +}; +typedef ObArray ObBalanceTaskArray; +typedef ObIArray ObBalanceTaskIArray; +class ObBalanceTaskTableOperator +{ +public: + /** + * @description: insert new task to __all_balance_task + * @param[in] task : a valid balance task include tenant_id + * @param[in] client : sql client or trans + * @return OB_SUCCESS if success, otherwise failed + */ + static int insert_new_task(const ObBalanceTask &task, + ObISQLClient &client); + /** + * @description: get task from __all_balance_task by balance_task_id + * @param[in] tenant_id : user_tenant_id + * @param[in] balance_task_id : target balance task id + * @param[in] for_update: whether lock the task + * @param[in] client : sql client or trans + * @param[out] task : get a valid balance task + * @param[out] start_time : task gmt_create in table + * @param[out] finish_time : task current gmt_modify + * @return : + * OB_SUCCESS : get the target balance task + * OB_ENTRY_NOT_EXIST : the task not exist + * OTHER : fail + */ + static int get_balance_task(const uint64_t tenant_id, + const ObBalanceTaskID balance_task_id, + const bool for_update, + ObISQLClient &client, + ObBalanceTask &task, + int64_t &start_time, + int64_t &finish_time); + /** + * @description: update task status of __all_balance_task + * @param[in] balance_task : target balance task id and tenant_id, and old_task_status + * @param[in] new_task_status : new task status + * @param[in] trans : must update in trans + * @return : + * OB_SUCCESS : update task status success + * OB_STATE_NOT_MATCH : current task status not match, can not update + * OTHER : fail + */ + static int update_task_status(const ObBalanceTask &balance_task, + const ObBalanceTaskStatus new_task_status, + ObMySQLTransaction &trans); + /** + * @description: update comment of balance task + * @param[in] tenant_id : user_tenant_id + * @param[in] new_comment : new comment + * @param[in] client: sql client or trans + * @return : + * OB_SUCCESS : update comment success + * OB_STATE_NOT_MATCH : task not exist + * OTHER : fail + */ + static int update_task_comment(const uint64_t tenant_id, + const ObBalanceTaskID task_id, + const common::ObString &new_comment, + ObISQLClient &client); + /** + * @description: old status must be tranfer and current transfer task must be empty + * @param[in] tenant_id : user_tenant_id + * @param[in] balance_task_id : target balance task id + * @param[in] tranfer_task_id : tranfer_task_id start by the task + * @param[in]: client: sql client or trans + * @return : + * OB_SUCCESS : start the transfer task + * OB_STATE_NOT_MATCH : already has transfer task, can not start now + * OTHER : fail + */ + static int start_transfer_task(const uint64_t tenant_id, + const ObBalanceTaskID balance_task_id, + const ObTransferTaskID transfer_task_id, + ObISQLClient &client); + /** + * @description: finish transfer task, set current_transfer_task and finish_part_list + * @param[in] balance_task : a valid balance task include tenant_id + * @param[in] tranfer_task_id : tranfer_task_id start by the task + * @param[in] transfer_finished_part_list: finished partitions of the transfer task + * @param[in] client: sql client or trans + * @param[out] to_do_part_list: to_do_part_list = balance_part_list - transfer_finished_part_list + * @param[out] all_part_transferred: whether all parts of the balance task have been transferred + * @return : + * OB_SUCCESS : finish the transfer task + * OB_STATE_NOT_MATCH : the transfer_task maybe finished + * OTHER : fail + */ + static int finish_transfer_task(const ObBalanceTask &balance_task, + const ObTransferTaskID transfer_task_id, + const ObTransferPartList &transfer_finished_part_list, + ObISQLClient &client, + ObTransferPartList &to_do_part_list, + bool &all_part_transferred); + /** + * @description: delete task from of __all_balance_task and insert to task to __all_balance_task_history + * @param[in] tenant_id : user_tenant_id + * @param[in] balance_task_id : target balance task id + * @param[in] client: sql client or trans + * @return : + * OB_SUCCESS : clean task + * OB_ENTRY_NOT_EXIST : the balance task already has been clean + * OB_STATE_NOT_MATCH : the balance task is not finished, status not match + * OTHER : fail + */ + static int clean_task(const uint64_t tenant_id, + const ObBalanceTaskID balance_task_id, + common::ObMySQLTransaction &trans); + + + /** + * @description: clean parent info of all child tasks after parent task is completed + * + * @param[in] tenant_id user_tenant_id + * @param[in] parent_task_id target parent task id which is complete + * @param[in] balance_job_id balance job id + * @param[in] trans transaction client + * + * @return : + * - OB_SUCCESS succeed to clean parent info of all child tasks + * - OTHER fail + */ + static int clean_parent_info( + const uint64_t tenant_id, + const ObBalanceTaskID parent_task_id, + const ObBalanceJobID balance_job_id, + common::ObMySQLTransaction &trans); + + /** + * @description: after process one task, set child_task can process + * @param[in] tenant_id : user_tenant_id + * @param[in] balance_task_id : target balance task id + * @param[in] parent_task_id : remove parent_task_id from the balance_task_id + * @param[in] client: sql client or trans + * @return : + * OB_SUCCESS : clean task + * OB_STATE_NOT_MATCH : the parent task has beed remove from the balance task + * OTHER : fail + */ + static int remove_parent_task(const uint64_t tenant_id, + const ObBalanceTaskID balance_task_id, + const ObBalanceTaskID parent_task_id, + ObISQLClient &client); + static int fill_dml_spliter(share::ObDMLSqlSplicer &dml, + const ObBalanceTask &task); + /* + * @description: load all task which parent_list is empty + * @param[in] tenant_id : user_tenant_id + * @param[out] balance_task_array : get all task which parent_list is empty + * @param[in] client: sql client or trans + * @return OB_SUCCESS if success, otherwise failed + * */ + static int load_can_execute_task(const uint64_t tenant_id, + ObBalanceTaskIArray &task_array, + ObISQLClient &client); + /* + * @description: load all task of the balance job that parent list not empty + * @param[in] job_id : balance_job_id + * @param[out] balance_task_array : get all task of the job + * @param[in] client: sql client or trans + * @return OB_SUCCESS if success, otherwise failed + * */ + static int get_job_cannot_execute_task(const uint64_t tenant_id, + const ObBalanceJobID balance_job_id, + ObBalanceTaskIArray &task_array, + ObISQLClient &client); + static int read_tasks_(const uint64_t tenant_id, ObISQLClient &client, + const ObSqlString &sql, ObBalanceTaskIArray &task_array); + static int fill_cell(const uint64_t tenant_id, sqlclient::ObMySQLResult*result, ObBalanceTask &task); + /* + * @description: for check job can finish, get task cnt of the job, if is zero, job can finish + * @param[in] tenant_id : user_tenant_id + * @param[in] job_id : balance_job_id + * @param[out] task_cnt : task count of the job + * @param[in] client: sql client or trans + * @return OB_SUCCESS if success, otherwise failed + * */ + static int get_job_task_cnt(const uint64_t tenant_id, const ObBalanceJobID job_id, + int64_t &task_cnt, ObISQLClient &client); + /* + * @description: update ls part list before set to transfer + * @param[in] tenant_id : user_tenant_id + * @param[in] balance_task_id : balance_task_id + * @param[in] part_list : all part list of src ls + * @param[in] trans: update in trans + * @return OB_SUCCESS if success, otherwise failed + * */ + static int update_merge_ls_part_list(const uint64_t tenant_id, + const ObBalanceTaskID balance_task_id, + const ObTransferPartList &part_list, + common::ObMySQLTransaction &trans); + + /** + * @description: get merge task dest_ls according to src_ls + * + * @param[in] sql_client sql client or trans + * @param[in] tenant_id user_tenant_id + * @param[in] src_ls source ls id + * @param[out] dest_ls destination ls id + * + * @return : + * - OB_SUCCESS succeed to get dest_ls by src_ls + * - OB_ENTRY_NOT_EXIST task not found according to src_ls + * - OTHER failed + */ + static int get_merge_task_dest_ls_by_src_ls( + ObISQLClient &sql_client, + const uint64_t tenant_id, + const ObLSID &src_ls, + ObLSID &dest_ls); +}; +#undef IS_BALANCE_TASK +} +} + +#endif /* !OCEANBASE_SHARE_OB_BALANCE_TASK_OPERATOR_H_ */ diff --git a/src/share/cache/ob_kvcache_pre_warmer.cpp b/src/share/cache/ob_kvcache_pre_warmer.cpp index adaf58436..01b430323 100644 --- a/src/share/cache/ob_kvcache_pre_warmer.cpp +++ b/src/share/cache/ob_kvcache_pre_warmer.cpp @@ -15,7 +15,6 @@ namespace common ObDataBlockCachePreWarmer::ObDataBlockCachePreWarmer() : base_percentage_(0), cache_(nullptr), - read_info_(nullptr), rest_size_(0), warm_size_percentage_(100), update_step_(0), @@ -33,7 +32,6 @@ ObDataBlockCachePreWarmer::~ObDataBlockCachePreWarmer() void ObDataBlockCachePreWarmer::reset() { cache_ = nullptr; - read_info_ = nullptr; base_percentage_ = 0; rest_size_ = 0; warm_size_percentage_ = 100; @@ -48,10 +46,10 @@ void ObDataBlockCachePreWarmer::reuse() cache_handle_.reset(); } -void ObDataBlockCachePreWarmer::init(const ObTableReadInfo &read_info) +void ObDataBlockCachePreWarmer::init() { int ret = OB_SUCCESS; - if (OB_FAIL(inner_init(DATA_BLOCK_CACHE_PERCENTAGE, read_info, OB_STORE_CACHE.get_block_cache()))) { + if (OB_FAIL(inner_init(DATA_BLOCK_CACHE_PERCENTAGE, OB_STORE_CACHE.get_block_cache()))) { COMMON_LOG(WARN, "Fail to inner init data block cache pre warmer", K(ret)); } } @@ -62,9 +60,9 @@ int ObDataBlockCachePreWarmer::reserve_kvpair(const blocksstable::ObMicroBlockDe int ret = OB_SUCCESS; int64_t kvpair_size = 0; - if (OB_UNLIKELY(nullptr == cache_ || nullptr == read_info_)) { + if (OB_UNLIKELY(nullptr == cache_)) { ret = OB_NOT_INIT; - COMMON_LOG(WARN, "The block cache pre warmer is not inited", K(ret), KP(cache_), KP(read_info_)); + COMMON_LOG(WARN, "The block cache pre warmer is not inited", K(ret), KP(cache_)); } else if (OB_UNLIKELY(!micro_block_desc.is_valid() || level < 0)) { ret = OB_INVALID_ARGUMENT; COMMON_LOG(WARN, "Invalid argument", K(ret), K(micro_block_desc), K(level)); @@ -72,9 +70,9 @@ int ObDataBlockCachePreWarmer::reserve_kvpair(const blocksstable::ObMicroBlockDe if (level < TOP_LEVEL && (rest_size_ <= 0 || !warm_block(level))) { ret = OB_BUF_NOT_ENOUGH; } else if (FALSE_IT(reuse())) { - } else if (OB_FAIL(cache_->reserve_kvpair(micro_block_desc, *read_info_, inst_handle_, + } else if (OB_FAIL(cache_->reserve_kvpair(micro_block_desc, inst_handle_, cache_handle_, kvpair_, kvpair_size))) { - COMMON_LOG(WARN, "Fail to reserve block cache value", K(ret), K(micro_block_desc), KPC(read_info_)); + COMMON_LOG(WARN, "Fail to reserve block cache value", K(ret), K(micro_block_desc)); } else { rest_size_ = MAX(0, rest_size_ - kvpair_size); } @@ -116,17 +114,15 @@ int ObDataBlockCachePreWarmer::update_and_put_kvpair(const blocksstable::ObMicro } int ObDataBlockCachePreWarmer::inner_init(const int64_t percentage, - const ObTableReadInfo &read_info, blocksstable::ObIMicroBlockCache &block_cache) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(percentage < 0 || !read_info.is_valid())) { + if (OB_UNLIKELY(percentage < 0)) { ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "Invalid argument", K(ret), K(percentage), K(read_info)); + COMMON_LOG(WARN, "Invalid argument", K(ret), K(percentage)); } else { cache_ = &block_cache; - read_info_ = &read_info; warm_size_percentage_ = percentage; inner_update_rest(); } @@ -183,10 +179,10 @@ ObIndexBlockCachePreWarmer::~ObIndexBlockCachePreWarmer() { } -void ObIndexBlockCachePreWarmer::init(const ObTableReadInfo &read_info) +void ObIndexBlockCachePreWarmer::init() { int ret = OB_SUCCESS; - if (OB_FAIL(inner_init(INDEX_BLOCK_CACHE_PERCENTAGE, read_info, OB_STORE_CACHE.get_index_block_cache()))) { + if (OB_FAIL(inner_init(INDEX_BLOCK_CACHE_PERCENTAGE, OB_STORE_CACHE.get_index_block_cache()))) { COMMON_LOG(WARN, "Fail to inner init index block cache pre warmer", K(ret)); } } @@ -199,4 +195,4 @@ void ObIndexBlockCachePreWarmer::calculate_base_percentage(const int64_t free_me }; // common -}; // oceanbase \ No newline at end of file +}; // oceanbase diff --git a/src/share/cache/ob_kvcache_pre_warmer.h b/src/share/cache/ob_kvcache_pre_warmer.h index 58fa6852d..b04528bc3 100644 --- a/src/share/cache/ob_kvcache_pre_warmer.h +++ b/src/share/cache/ob_kvcache_pre_warmer.h @@ -21,12 +21,12 @@ public: virtual ~ObDataBlockCachePreWarmer(); void reset(); void reuse(); - void init(const ObTableReadInfo &read_info); + void init(); OB_INLINE bool is_valid() const { return nullptr != cache_; } int reserve_kvpair(const blocksstable::ObMicroBlockDesc µ_block_desc, const int64_t level = 0); int update_and_put_kvpair(const blocksstable::ObMicroBlockDesc µ_block_desc); protected: - int inner_init(const int64_t ratio, const ObTableReadInfo &read_info, blocksstable::ObIMicroBlockCache &block_cache); + int inner_init(const int64_t ratio, blocksstable::ObIMicroBlockCache &block_cache); void update_rest(); void inner_update_rest(); virtual void calculate_base_percentage(const int64_t free_memory); @@ -40,7 +40,6 @@ private: static const int64_t TOP_LEVEL = 6; blocksstable::ObIMicroBlockCache *cache_; - const ObTableReadInfo *read_info_; int64_t rest_size_; int64_t warm_size_percentage_; int64_t update_step_; @@ -54,7 +53,7 @@ class ObIndexBlockCachePreWarmer : public ObDataBlockCachePreWarmer public: ObIndexBlockCachePreWarmer(); virtual ~ObIndexBlockCachePreWarmer(); - void init(const ObTableReadInfo &read_info); + void init(); protected: virtual void calculate_base_percentage(const int64_t free_memory) override; private: diff --git a/src/share/cache/ob_recycle_multi_kvcache.h b/src/share/cache/ob_recycle_multi_kvcache.h new file mode 100644 index 000000000..df57e1515 --- /dev/null +++ b/src/share/cache/ob_recycle_multi_kvcache.h @@ -0,0 +1,259 @@ +/** + * Copyright (c) 2023 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. + */ + +/** + * ObRecycleMultiKVCache + * + * ObRecycleMultiKVCache is a recycle cache buffer contains a series of KV pair data + * (the number of pairs depends on the memory size pre-allocated and the run-time memory of each node costs). + * There are some core advantages ObRecycleMultiKVCache designed for: + * 1. no dynamic memory actually allocated guaranteed, this is very important for runtime performance. + * 2. KV pair data is appended only, so makes write cost O(1) time, + * and pre-allocated memory in init() will be recycle used, the oldest KV pair data is recycled for the new one. + * 3. hash index makes point read cost O(1) time. + * 4. if V has a pointer inside and has to be deep-copied, ObRecycleMultiKVCache will pass a mock inner allocator to it, + * and acutually use the recycle buffer to alloc memory, if there is no enough memory, willl recycle the oldest data + * until the buffer is enough. + * + if V's copy action need extra memory, the function signature should be like: int V::assign(ObIAllocator &, const V &) const. + * + if V's copy action do not need allocator, it's ok with meta programing's help. + * + if V's just support move action, it's ok if you passed a rvalue. + * 5. one key can map to multi values. + * 6. tamplate implementation of course. + * + * Memory usage: + * - the dynamic memory and allocator is specified in init() interface, and no extra memory allocated guaranteed, + * ObRecycleMultiKVCache is RAII designed, the only thing you should care about lifetime is the allocator you passed + * to ObRecycleMultiKVCache shou alive longer than ObRecycleMultiKVCache. + * + * Concurrency: + * - there is no way to write a same lock-free structure, but lock will never be the performance problem, + * if you find too much cpu wasted on the lock, maybe you should consider about create multi ObRecycleMultiKVCache + * instances, and seperate the write concurrency. + * + * Manual: + * - Interface + * 1. construction & destruction & copy & move + * + default construction & default destruction: + * ObRecycleMultiKVCache() + * ~ObRecycleMultiKVCache() + * + copy & move: + * not allowed + * + init: + * init(const char (&mem_tag)[N],// tag used for alloc static memory + * ObIAllocator &alloc,// the real allocator to alloc memory + * const int64_t recycle_buffer_size,// to store kv pair + * const int64_t hash_idx_bkt_num,// to build read index + * const int64_t rehash_seed)// to recalculate hash value + * 2. write + * + apped KV pair, support r-value: + * template + * int append(const K &key, T &&event); + * 3. read + * + read by key, OP must could used like int op(const V &): + * template + * int for_each(const K &key, OP &&op) const; + * + scan read all, OP must could used like int OP(const K &, const V &) + * template + * int for_each(OP &&op) const; + * + * - Contact for help. + */ + +#ifndef OCEANBASE_LIB_CACHE_OB_RECYCLE_CACHE_H +#define OCEANBASE_LIB_CACHE_OB_RECYCLE_CACHE_H + +#include "lib/lock/ob_small_spin_lock.h" +#include "lib/lock/ob_spin_lock.h" +#include "lib/ob_errno.h" +#include "lib/string/ob_string.h" +#include "lib/utility/ob_macro_utils.h" +#include "meta_programming/ob_type_traits.h" +#include "lib/allocator/ob_allocator.h" +#include "lib/atomic/ob_atomic.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/utility/ob_print_utils.h" +#include "util/easy_time.h" +#include "lib/lock/ob_tc_rwlock.h" +#include "common/meta_programming/ob_meta_compare.h" + +namespace oceanbase +{ +namespace common +{ +namespace cache +{ + +template +struct KVNode { + KVNode() + : hash_bkt_prev_next_ptr_(nullptr), + hash_bkt_next_(nullptr), + key_node_prev_(nullptr), + key_node_next_(nullptr), + extre_buffer_size_(0) {} + KVNode(const K &key, const V &value) : KVNode() { k_ = key; v_ = value; }// for unittest + ~KVNode() { + hash_bkt_prev_next_ptr_ = nullptr; + hash_bkt_next_ = nullptr; + key_node_prev_ = nullptr; + key_node_next_ = nullptr; + extre_buffer_size_ = 0; + } + TO_STRING_KV(KP_(hash_bkt_prev_next_ptr), KP_(hash_bkt_next), KP_(key_node_prev), KP_(key_node_next),\ + K_(extre_buffer_size), K_(k), K_(v)); + K k_; + V v_; + KVNode **hash_bkt_prev_next_ptr_;// to record hash conflict next Node + KVNode *hash_bkt_next_;// to record hash conflict next Node + KVNode *key_node_prev_;// to record multi key value + KVNode *key_node_next_;// to record multi key value + uint32_t extre_buffer_size_;// dynamic alloc memory size +}; + +struct InnerMockAllocator final : public ObIAllocator +{ + InnerMockAllocator() + : can_alloc_ptr_(nullptr), + can_alloc_len_(0), + allocated_size_(0), + can_free_ptr_(nullptr), + can_free_len_(0) {} + void set_can_alloc_area(char *can_alloc_ptr, const int64_t len) { + can_alloc_ptr_ = can_alloc_ptr; + can_alloc_len_ = len; + allocated_size_ = 0; + } + void set_can_free_area(char *can_free_ptr, const int64_t len) { + can_free_ptr_ = can_free_ptr; + can_free_len_ = len; + } + virtual void *alloc(const int64_t size) override { + void *alloc_ptr = nullptr; + if (size > UINT32_MAX) { + OCCAM_LOG_RET(ERROR, OB_ALLOCATE_MEMORY_FAILED, "alloc memory too large", K(size), K(*this), K(lbt())); + } else if (size > can_alloc_len_ - allocated_size_) { + OCCAM_LOG_RET(DEBUG, OB_ALLOCATE_MEMORY_FAILED, "alloc memory failed", K(size), K(*this)); + } else { + alloc_ptr = can_alloc_ptr_ + allocated_size_; + allocated_size_ += size; + set_can_free_area(can_alloc_ptr_, allocated_size_); + } + return alloc_ptr; + } + virtual void *alloc(const int64_t size, const ObMemAttr &attr) override { + UNUSED(attr); + return alloc(size); + } + virtual void free(void *ptr) override { + OB_ASSERT(ptr >= can_free_ptr_ && ptr < can_free_ptr_ + can_free_len_); + } + TO_STRING_KV(KP_(can_alloc_ptr), K_(can_alloc_len), K_(allocated_size), KP_(can_free_ptr), K_(can_free_len)); + char *can_alloc_ptr_; + int64_t can_alloc_len_; + int64_t allocated_size_; + char *can_free_ptr_; + int64_t can_free_len_; +}; + +template +class ObRecycleMultiKVCache {// FIFO write, so can be recycled, and no extra memory allocated guaranteed +private: + struct HashBkt { + HashBkt(); + HashBkt(KVNode **hash_bkt, const int64_t hash_bkt_num, const int64_t rehash_seed); + ~HashBkt(); + void insert(KVNode *node); + void remove(KVNode *node); + KVNode *find_list(const K &key, + KVNode **&hash_bkt_prev_node_next_ptr, + KVNode *&hash_bkt_next) const; + TO_STRING_KV(KP_(hash_bkt), K_(hash_bkt_num), K_(rehash_seed)) + private: + uint64_t re_hash_idx_(const K &key) const; + private: + KVNode **hash_bkt_;// to find KVNode by Key + int64_t hash_bkt_num_; + int64_t rehash_seed_; + }; +public: + ObRecycleMultiKVCache() + : allocator_(nullptr), + offset_next_to_appended_(0), + offset_can_write_end_(0), + offset_reserved_(0), + hash_bkt_(), + buffer_(nullptr), + buffer_len_(0), + inner_mock_allocator_() {} + ObRecycleMultiKVCache(const ObRecycleMultiKVCache &) = delete; + ~ObRecycleMultiKVCache(); + template + int init(const char (&mem_tag)[N],// tag used for alloc static memory + ObIAllocator &alloc,// the real allocator to alloc memory + const int64_t recycle_buffer_size, + const int64_t hash_idx_bkt_num, + const int64_t rehash_seed = 0);// the buffer to store to_string result by KVNode + template + int append(const K &key, T &&event); + template // int OP(const V &); + int for_each(const K &key, OP &&op) const;// optimized for point select + template // int OP(const K &, const V &); + int for_each(OP &&op) const;// optimized for point select + void get_statistics(int64_t &write_pos, + int64_t &recycle_pos, + int64_t &write_number, + int64_t &recycle_number, + int64_t &buf_size) const { + ObSpinLockGuard lg(lock_); + write_pos = offset_next_to_appended_; + recycle_pos = offset_can_write_end_ - buffer_len_; + write_number = write_number_; + recycle_number = recycle_number_; + buf_size = buffer_len_; + } + TO_STRING_KV(KP_(allocator), K_(offset_next_to_appended), K_(offset_can_write_end),\ + K_(offset_reserved), K_(hash_bkt), KP_(total_buffer), KP_(buffer), K_(buffer_len),\ + K_(inner_mock_allocator), K_(write_number), K_(recycle_number)); +private: + template // bool OP(KVNode &node); + void for_each_node_continuously_until_true_(OP &&op); + template + int construct_assign_(const K &key, + Value &&event, + InnerMockAllocator &alloc, + KVNode *&p_new_node); + int recycle_one_(); + int64_t round_end_(int64_t offset) const; +private: + ObIAllocator *allocator_;// to alloc buffer in heap + int64_t offset_next_to_appended_;// ptr to append next time + int64_t offset_can_write_end_;// ptr to recycled next time, will alway not less than offset_next_to_appended_ + int64_t offset_reserved_;// if alloc memory failed at the end of some round, will try restart alloc in next round, and those end erea with no data called reserved + HashBkt hash_bkt_; + char *total_buffer_;// start pointer of heap area, including hash_idx + data_bufer + char *buffer_;// the start pointer of recycle buffer on heap + int64_t buffer_len_; + InnerMockAllocator inner_mock_allocator_; + int64_t write_number_; + int64_t recycle_number_; + mutable ObSpinLock lock_; +}; + +} +} +} +#ifndef OCEANBASE_LIB_CACHE_OB_RECYCLE_CACHE_H_IPP +#define OCEANBASE_LIB_CACHE_OB_RECYCLE_CACHE_H_IPP +#include "ob_recycle_multi_kvcache.ipp" +#endif + +#endif \ No newline at end of file diff --git a/src/share/cache/ob_recycle_multi_kvcache.ipp b/src/share/cache/ob_recycle_multi_kvcache.ipp new file mode 100644 index 000000000..f4159a1fe --- /dev/null +++ b/src/share/cache/ob_recycle_multi_kvcache.ipp @@ -0,0 +1,345 @@ + +/** + * Copyright (c) 2023 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_LIB_CACHE_OB_RECYCLE_CACHE_IPP +#define OCEANBASE_LIB_CACHE_OB_RECYCLE_CACHE_IPP + +#include "lib/list/ob_dlist.h" +#include "lib/lock/ob_small_spin_lock.h" +#include "lib/ob_errno.h" +#include "lib/utility/ob_print_utils.h" +#include "meta_programming/ob_meta_copy.h" +#include +#include +#ifndef OCEANBASE_LIB_CACHE_OB_RECYCLE_CACHE_H_IPP +#define OCEANBASE_LIB_CACHE_OB_RECYCLE_CACHE_H_IPP +#include "ob_recycle_multi_kvcache.h" +#endif + +namespace oceanbase +{ +namespace common +{ +namespace cache +{ + +template +ObRecycleMultiKVCache::HashBkt::HashBkt() +: hash_bkt_(nullptr), hash_bkt_num_(0), rehash_seed_(0) {} + +template +ObRecycleMultiKVCache::HashBkt::HashBkt(KVNode **hash_bkt, + const int64_t hash_bkt_num, + const int64_t rehash_seed) +:hash_bkt_(hash_bkt), +hash_bkt_num_(hash_bkt_num), +rehash_seed_(rehash_seed) { + for (int64_t idx = 0; idx < hash_bkt_num_; ++idx) { + hash_bkt_[idx] = nullptr; + } +} + +template +ObRecycleMultiKVCache::HashBkt::~HashBkt() { + new (this) HashBkt(); +} + +template +void ObRecycleMultiKVCache::HashBkt::insert(KVNode *node) { + KVNode **hash_prev_node_next_ptr = nullptr; + KVNode *bkt_next = nullptr; + KVNode *list = find_list(node->k_, hash_prev_node_next_ptr, bkt_next); + if (nullptr != list) {// find a list + OB_ASSERT(OB_NOT_NULL(list->hash_bkt_prev_next_ptr_)); + list->key_node_prev_->key_node_next_ = node; + node->key_node_prev_ = list->key_node_prev_; + node->key_node_next_ = list; + list->key_node_prev_ = node; + } else { + *hash_prev_node_next_ptr = node; + node->hash_bkt_next_ = bkt_next; + node->hash_bkt_prev_next_ptr_ = hash_prev_node_next_ptr; + if (nullptr != bkt_next) {// maybe no next + bkt_next->hash_bkt_prev_next_ptr_ = &(node->hash_bkt_next_); + } + node->key_node_prev_ = node; + node->key_node_next_ = node; + } +} + +template +void ObRecycleMultiKVCache::HashBkt::remove(KVNode *node) { + if (node->key_node_prev_ == node) {// last node in list + OB_ASSERT(node->key_node_next_ == node); + OB_ASSERT(OB_NOT_NULL(node->hash_bkt_prev_next_ptr_)); + *node->hash_bkt_prev_next_ptr_ = node->hash_bkt_next_;// remove this list from bucket + if (nullptr != node->hash_bkt_next_) { + node->hash_bkt_next_->hash_bkt_prev_next_ptr_ = node->hash_bkt_prev_next_ptr_; + } + } else {// not last node, remove it and check if replay list head + node->key_node_prev_->key_node_next_ = node->key_node_next_; + node->key_node_next_->key_node_prev_ = node->key_node_prev_; + if (OB_UNLIKELY(nullptr != node->hash_bkt_prev_next_ptr_)) { + KVNode *new_list_head = node->key_node_next_; + OB_ASSERT(new_list_head->hash_bkt_prev_next_ptr_ == nullptr); + OB_ASSERT(new_list_head->hash_bkt_next_ == nullptr); + *node->hash_bkt_prev_next_ptr_ = new_list_head; + new_list_head->hash_bkt_prev_next_ptr_ = node->hash_bkt_prev_next_ptr_; + new_list_head->hash_bkt_next_ = node->hash_bkt_next_; + if (nullptr != node->hash_bkt_next_) {// maybe no next + node->hash_bkt_next_->hash_bkt_prev_next_ptr_ = &(new_list_head->hash_bkt_next_); + } + } + } + // clear node self info + node->key_node_prev_ = nullptr; + node->key_node_next_ = nullptr; + node->hash_bkt_prev_next_ptr_ = nullptr; + node->hash_bkt_next_ = nullptr; +} + +template +KVNode *ObRecycleMultiKVCache::HashBkt::find_list(const K &key, + KVNode **&hash_bkt_prev_node_next_ptr, + KVNode *&bkt_next) const { + KVNode *list = nullptr; + int64_t bkt_idx = re_hash_idx_(key); + hash_bkt_prev_node_next_ptr = &hash_bkt_[bkt_idx]; + KVNode *iter = hash_bkt_[bkt_idx]; + while (nullptr != iter && nullptr == list) { + if (iter->k_ < key) {// keep iter next to find proper position + hash_bkt_prev_node_next_ptr = &iter->hash_bkt_next_; + } else if (iter->k_ == key) {// node's key is same with this list, insert into tail of it + list = iter; + } else {// no same key, insert into hash bkt between two nodes + break; + } + iter = iter->hash_bkt_next_; + } + OCCAM_LOG(DEBUG, "TO COMPILER: DO NOT OPTIMIZE IT", K(bkt_idx)); + bkt_next = iter; + return list; +} + +template +uint64_t ObRecycleMultiKVCache::HashBkt::re_hash_idx_(const K &key) const { +#ifdef UNITTEST_DEBUG + return key.hash(); +#else + uint64_t hash = key.hash(); + hash = murmurhash(&rehash_seed_, sizeof(rehash_seed_), hash); + return hash % hash_bkt_num_; +#endif +} + +template +int64_t ObRecycleMultiKVCache::round_end_(int64_t offset) const +{ + return ((offset/buffer_len_) + 1) * buffer_len_; +} + +template +ObRecycleMultiKVCache::~ObRecycleMultiKVCache() +{ + OCCAM_LOG(DEBUG, "destructed", K(*this)); + if (OB_NOT_NULL(allocator_)) { + while (OB_BUF_NOT_ENOUGH != recycle_one_());// keep recycling until meet buf not enough + allocator_->free(total_buffer_); + new (this) ObRecycleMultiKVCache(); + } +} + +template +template +int ObRecycleMultiKVCache::init(const char (&mem_tag)[N],// used for alloc static memory + ObIAllocator &alloc, + const int64_t recycle_buffer_size, + const int64_t hash_idx_bkt_num, + const int64_t rehash_seed) +{ + #define PRINT_WRAPPER K(ret), K(mem_tag), K(recycle_buffer_size), K(hash_idx_bkt_num), K(rehash_seed), K(*this) + int ret = OB_SUCCESS; + void *allocated_ptr = nullptr; + int64_t total_size = hash_idx_bkt_num * sizeof(KVNode *) + recycle_buffer_size; + char *p_buffer = nullptr; + if (OB_ISNULL(mem_tag) || recycle_buffer_size < 1 || hash_idx_bkt_num < 1) { + ret = OB_INVALID_ARGUMENT; + OCCAM_LOG(WARN, "invalid argument", PRINT_WRAPPER); + } else if (OB_NOT_NULL(buffer_)) { + ret = OB_INIT_TWICE; + OCCAM_LOG(WARN, "init twice", PRINT_WRAPPER); + } else if (nullptr == (p_buffer = (char *)alloc.alloc(total_size, ObMemAttr(common::OB_SERVER_TENANT_ID, lib::ObLabel(mem_tag))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + OCCAM_LOG(WARN, "fail to alloc memory", PRINT_WRAPPER); + } else { + total_buffer_ = p_buffer;// record this buffer pointer, for free it when destructed + new (&hash_bkt_) HashBkt((KVNode **)p_buffer, hash_idx_bkt_num, rehash_seed); + buffer_ = p_buffer + hash_idx_bkt_num * sizeof(KVNode *); + buffer_len_ = recycle_buffer_size; + offset_next_to_appended_ = 0; + offset_can_write_end_ = buffer_len_; + allocator_ = &alloc; + OCCAM_LOG(DEBUG, "succ to init", PRINT_WRAPPER, KP(p_buffer)); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int ObRecycleMultiKVCache::construct_assign_(const K &key, + Value &&data, + InnerMockAllocator &alloc, + KVNode *&p_new_node) +{ + #define PRINT_WRAPPER K(ret), K(key), K(data), K(alloc), KP(p_new_node), KP(p_new_node) + int ret = OB_SUCCESS; + p_new_node = (KVNode *)alloc.alloc(sizeof(KVNode)); + if (OB_ISNULL(p_new_node)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + OCCAM_LOG(DEBUG, "fail to alloc memory when construct KVNode", PRINT_WRAPPER); + } else { + new (p_new_node) KVNode(); + p_new_node->k_ = key; + if (OB_FAIL(meta::move_or_copy_or_assign(std::forward(data), p_new_node->v_, alloc))) { + if (OB_ALLOCATE_MEMORY_FAILED == ret) { + OCCAM_LOG(DEBUG, "fail to alloc memory when call value assign", PRINT_WRAPPER); + } else { + OCCAM_LOG(WARN, "fail to call value assign", PRINT_WRAPPER); + } + p_new_node->~KVNode(); + p_new_node = nullptr; + } else { + OCCAM_LOG(DEBUG, "succ to alloc new node", PRINT_WRAPPER); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template +int ObRecycleMultiKVCache::recycle_one_() +{ + int ret = OB_SUCCESS; + KVNode *cur = (KVNode *)&buffer_[offset_can_write_end_ % buffer_len_]; + if (offset_can_write_end_ - offset_next_to_appended_ == buffer_len_) { + ret = OB_BUF_NOT_ENOUGH; + OCCAM_LOG(DEBUG, "can not recycle", K(ret), K(*this)); + } else { + offset_can_write_end_ += sizeof(KVNode) + cur->extre_buffer_size_; + if (offset_can_write_end_ == offset_reserved_) { + offset_can_write_end_ = round_end_(offset_can_write_end_); + } + OB_ASSERT(offset_can_write_end_ - offset_next_to_appended_ <= buffer_len_); + OCCAM_LOG(DEBUG, "recycle one", K(ret), K(*this), K(*cur)); + hash_bkt_.remove(cur); + inner_mock_allocator_.set_can_free_area((char *)cur + sizeof(KVNode), cur->extre_buffer_size_); + cur->~KVNode(); + ++recycle_number_; + } + return ret; +} + +template +template +int ObRecycleMultiKVCache::append(const K &key, Value &&value) +{ + #define PRINT_WRAPPER K(ret), K(tmp_ret), K(key), K(value), K(*this) + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObSpinLockGuard lg(lock_); + if (OB_ISNULL(buffer_)) { + ret = OB_NOT_INIT; + OCCAM_LOG(WARN, "not init", PRINT_WRAPPER); + } else { + KVNode *p_new_node = nullptr; + do { + int64_t round_end_offset = round_end_(offset_next_to_appended_); + int64_t max_can_alloc_len_in_this_round = std::min(offset_can_write_end_, round_end_offset) - offset_next_to_appended_; + inner_mock_allocator_.set_can_alloc_area(&buffer_[offset_next_to_appended_ % buffer_len_], max_can_alloc_len_in_this_round); + if (OB_TMP_FAIL(construct_assign_(key, std::forward(value), inner_mock_allocator_, p_new_node))) { + OCCAM_LOG(DEBUG, "fail to appended", PRINT_WRAPPER); + if (OB_ALLOCATE_MEMORY_FAILED == tmp_ret) { + if (offset_can_write_end_ - offset_next_to_appended_ == buffer_len_) {// no data lefted + ret = OB_BUF_NOT_ENOUGH; + } else if (offset_can_write_end_ >= round_end_offset) {// this round not has enough memory to append this new one + offset_reserved_ = offset_next_to_appended_ + buffer_len_; + offset_next_to_appended_ = round_end_offset; + } else if (OB_FAIL(recycle_one_())) { + OCCAM_LOG(WARN, "fail to do recycle", PRINT_WRAPPER); + } + } else { + ret = tmp_ret; + OCCAM_LOG(WARN, "user assign functon report error", PRINT_WRAPPER); + } + } else { + offset_next_to_appended_ += inner_mock_allocator_.allocated_size_; + p_new_node->extre_buffer_size_ = (uint32_t)(inner_mock_allocator_.allocated_size_ - sizeof(KVNode)); + hash_bkt_.insert(p_new_node);// build index + ++write_number_; + } + } while (OB_SUCC(ret) && OB_ALLOCATE_MEMORY_FAILED == tmp_ret); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template // int OP(const V &); +int ObRecycleMultiKVCache::for_each(const K &key, OP &&op) const// optimized for point select +{ + int ret = OB_SUCCESS; + KVNode **_1; + KVNode *_2; + ObSpinLockGuard lg(lock_); + KVNode *list = hash_bkt_.find_list(key, _1, _2); + auto iter = list; + if (OB_ISNULL(list)) { + ret = OB_ENTRY_NOT_EXIST; + } else { + do { + if (OB_FAIL(op(iter->v_))) { + OCCAM_LOG(DEBUG, "do user op faled on iter", K(key), K(*iter), K(typeid(op).name()), K(*this)); + } + iter = iter->key_node_next_; + } while (list != iter && OB_SUCC(ret)); + } + return ret; +} + +template +template // int OP(const K &, const V &); +int ObRecycleMultiKVCache::for_each(OP &&op) const// optimized for point select +{ + int ret = OB_SUCCESS; + ObSpinLockGuard lg(lock_); + int64_t offset = offset_can_write_end_; + while (OB_SUCC(ret) && offset - offset_next_to_appended_ != buffer_len_) { + KVNode *cur = (KVNode *)&buffer_[offset % buffer_len_]; + if (OB_FAIL(op(cur->k_, cur->v_))) { + OCCAM_LOG(WARN, "fail to apply user op on KVNode", K(*cur), K(*this)); + } else { + offset += sizeof(KVNode) + cur->extre_buffer_size_; + if (offset == offset_reserved_) { + offset = round_end_(offset); + } + } + OB_ASSERT(offset - offset_next_to_appended_ <= buffer_len_); + } + return ret; +} + +} +} +} +#endif \ No newline at end of file diff --git a/src/share/cache/ob_vtable_event_recycle_buffer.h b/src/share/cache/ob_vtable_event_recycle_buffer.h new file mode 100644 index 000000000..217888a9b --- /dev/null +++ b/src/share/cache/ob_vtable_event_recycle_buffer.h @@ -0,0 +1,162 @@ +#ifndef SHARE_CACHE_OB_VTABLE_EVENT_RECYCLE_BUFFER_H +#define SHARE_CACHE_OB_VTABLE_EVENT_RECYCLE_BUFFER_H + +#include "lib/allocator/ob_allocator.h" +#include "lib/ob_define.h" +#include "lib/ob_errno.h" +#include "lib/utility/ob_macro_utils.h" +#include "ob_recycle_multi_kvcache.h" +#include "share/ob_delegate.h" +#include "lib/literals/ob_literals.h" +#include + +namespace oceanbase +{ +namespace common +{ +namespace cache +{ + +template +struct ObRecycleMultiKVCacheAligedWrapper +{ + ObRecycleMultiKVCache cache_; + DELEGATE(cache_, init); + DELEGATE(cache_, append); + DELEGATE(cache_, for_each); +} CACHE_ALIGNED; + +template +class ObVtableEventRecycleBuffer { +public: + ObVtableEventRecycleBuffer() : buffer_bkt_(nullptr), bkt_len_(0), alloc_(nullptr) {} + ~ObVtableEventRecycleBuffer() { + if (OB_NOT_NULL(alloc_)) { + for (int64_t idx = 0; idx < bkt_len_; ++idx) { + buffer_bkt_[idx].~ObRecycleMultiKVCacheAligedWrapper(); + } + alloc_->free(buffer_bkt_); + buffer_bkt_ = nullptr; + bkt_len_ = 0; + alloc_ = 0; + } + } + ObVtableEventRecycleBuffer(const ObVtableEventRecycleBuffer &) = delete; + template + int init (const char (&mem_tag)[N],// tag used for alloc static memory + ObIAllocator &alloc,// the real allocator to alloc memory + const int64_t recycle_buffer_number, + const int64_t recycle_buffer_size_each, + const int64_t hash_idx_bkt_num_each) { + #define PRINT_WRAPPER K(ret), K(mem_tag), K(recycle_buffer_number), K(recycle_buffer_number), K(hash_idx_bkt_num_each) + int ret = OB_SUCCESS; + if (OB_ISNULL(mem_tag) || + recycle_buffer_number < 1 || + recycle_buffer_size_each < 1 || + hash_idx_bkt_num_each < 1) { + ret = OB_INVALID_ARGUMENT; + OCCAM_LOG(WARN, "invalid argument", PRINT_WRAPPER); + } else if (OB_NOT_NULL(alloc_)) { + ret = OB_INIT_TWICE; + OCCAM_LOG(WARN, "invalid argument", PRINT_WRAPPER); + } else if (nullptr == (buffer_bkt_ = (ObRecycleMultiKVCacheAligedWrapper *)alloc.alloc(sizeof(ObRecycleMultiKVCacheAligedWrapper) * recycle_buffer_number))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + OCCAM_LOG(WARN, "fail to allocate", PRINT_WRAPPER); + } else { + alloc_ = &alloc; + for (int64_t idx = 0; idx < recycle_buffer_number && OB_SUCC(ret); ++idx) { + new (&buffer_bkt_[idx]) ObRecycleMultiKVCacheAligedWrapper(); + if (OB_FAIL(buffer_bkt_[idx].init(mem_tag, + alloc, + recycle_buffer_size_each, + hash_idx_bkt_num_each, + idx))) { + OCCAM_LOG(WARN, "fail init cache", PRINT_WRAPPER, K(idx)); + } else { + bkt_len_ = idx + 1; + } + } + } + if (OB_FAIL(ret)) { + this->~ObVtableEventRecycleBuffer(); + new (this) ObVtableEventRecycleBuffer(); + } + return ret; + #undef PRINT_WRAPPER + } + template + int append(const K &key, Value &&event, const char *file = nullptr, const uint32_t line = 0, const char *func = nullptr) { + int ret = OB_SUCCESS; + if (OB_ISNULL(buffer_bkt_)) { + ret = OB_NOT_INIT; + // OCCAM_LOG(WARN, "not init", K(ret), K(key), K(event)); + } else if (OB_FAIL(buffer_bkt_[key.hash() % bkt_len_].append(key, std::forward(event)))) { + OCCAM_LOG(WARN, "fail to append event", K(ret), K(key), K(event)); + } else { + OCCAM_LOG(TRACE, "succ to append event", K(ret), K(key), K(event)); + } + return ret; + } + template // int OP(const V &); + int for_each(const K &key, OP &&op) const {// optimized for point select + int ret = OB_SUCCESS; + if (OB_ISNULL(buffer_bkt_)) { + ret = OB_NOT_INIT; + OCCAM_LOG(WARN, "not init", K(ret)); + } else { + ret = buffer_bkt_[key.hash() % bkt_len_].for_each(key, std::forward(op)); + } + return ret; + } + template // int OP(const K &, const V &); + int for_each(OP &&op) const { + int ret = OB_SUCCESS; + if (OB_ISNULL(buffer_bkt_)) { + ret = OB_NOT_INIT; + OCCAM_LOG(WARN, "not init", K(ret)); + } else { + for (int64_t idx = 0; idx < bkt_len_ && OB_SUCC(ret); ++idx) { + ret = buffer_bkt_[idx].for_each(std::forward(op)); + } + } + return ret; + } + void dump_statistics() const { + constexpr int64_t stack_buffer_size = 1_KB; + int64_t buffer_size = 0; + char info[stack_buffer_size] = { 0 }; + int64_t pos = 0; + int ret = OB_SUCCESS; + if (OB_ISNULL(buffer_bkt_)) { + ret = OB_NOT_INIT; + OCCAM_LOG(WARN, "not init", K(ret)); + } else { + for (int64_t idx = 0; idx < bkt_len_; ++idx) { + if (idx != 0) { + databuff_printf(info, stack_buffer_size, pos, ", "); + } + int64_t write_pos = 0; + int64_t recycle_pos = 0; + int64_t write_number = 0; + int64_t recycle_number = 0; + buffer_bkt_[idx].cache_.get_statistics(write_pos, recycle_pos, write_number, recycle_number, buffer_size); + databuff_printf(info, stack_buffer_size, pos, + "[%ld: total_write_size:%s, total_recycle_size:%s, total_write_num:%ld, total_recycle_num:%ld]", + idx, to_cstring(ObSizeLiteralPrettyPrinter(write_pos)), to_cstring(ObSizeLiteralPrettyPrinter(recycle_pos)), + write_number, recycle_number); + } + databuff_printf(info, stack_buffer_size, pos, ", buffer_size_each:%s", to_cstring(ObSizeLiteralPrettyPrinter(buffer_size))); + OCCAM_LOG(INFO, "DUMP VTableBuffer STATISTICS", K(info)); + } + } +private: + ObRecycleMultiKVCacheAligedWrapper *buffer_bkt_; + int64_t bkt_len_; + ObIAllocator *alloc_; +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/src/share/config/ob_config_helper.cpp b/src/share/config/ob_config_helper.cpp index 34de9841e..58d0d8dd1 100644 --- a/src/share/config/ob_config_helper.cpp +++ b/src/share/config/ob_config_helper.cpp @@ -11,7 +11,6 @@ */ #include "share/config/ob_config_helper.h" -#include "share/backup/ob_backup_info_mgr.h" #include "share/config/ob_config.h" #include "lib/ob_running_mode.h" #include "lib/utility/ob_macro_utils.h" diff --git a/src/share/config/ob_server_config.h b/src/share/config/ob_server_config.h index 6f129c507..8ab1e6283 100644 --- a/src/share/config/ob_server_config.h +++ b/src/share/config/ob_server_config.h @@ -56,6 +56,8 @@ const char* const FREEZE_TRIGGER_PERCENTAGE = "freeze_trigger_percentage"; const char* const WRITING_THROTTLEIUNG_TRIGGER_PERCENTAGE = "writing_throttling_trigger_percentage"; const char* const COMPATIBLE = "compatible"; const char* const WEAK_READ_VERSION_REFRESH_INTERVAL = "weak_read_version_refresh_interval"; +const char* const PARTITION_BALANCE_SCHEDULE_INTERVAL = "partition_balance_schedule_interval"; +const char* const BALANCER_IDLE_TIME = "balancer_idle_time"; class ObServerMemoryConfig; class ObServerConfig : public ObCommonConfig @@ -80,7 +82,6 @@ public: virtual ObServerRole get_server_type() const { return common::OB_SERVER; } virtual bool is_debug_sync_enabled() const { return static_cast(debug_sync_timeout) > 0; } - virtual bool is_rebalance_enabled() { return !in_major_version_upgrade_mode() && enable_rebalance; } virtual bool is_rereplication_enabled() { return !in_major_version_upgrade_mode() && enable_rereplication; } virtual double user_location_cpu_quota() const { return location_cache_cpu_quota; } diff --git a/src/share/datum/ob_datum.h b/src/share/datum/ob_datum.h index 92705921b..c6ebbae73 100644 --- a/src/share/datum/ob_datum.h +++ b/src/share/datum/ob_datum.h @@ -353,7 +353,7 @@ public: inline void set_urowid(const ObURowIDData &urowid_data) { ptr_ = reinterpret_cast(urowid_data.rowid_content_); - pack_ = static_cast(urowid_data.rowid_len_);//TODO(yongle.xh): need check + pack_ = static_cast(urowid_data.rowid_len_); } inline void set_urowid(const char *ptr, const int64_t size) { diff --git a/src/share/detect/ob_detect_manager_utils.h b/src/share/detect/ob_detect_manager_utils.h index edd12322f..a258f7b39 100644 --- a/src/share/detect/ob_detect_manager_utils.h +++ b/src/share/detect/ob_detect_manager_utils.h @@ -11,6 +11,7 @@ */ #pragma once +#include "lib/container/ob_array.h" #include "share/detect/ob_detectable_id.h" #include "sql/engine/px/p2p_datahub/ob_p2p_dh_share_info.h" diff --git a/src/share/external_table/ob_external_table_file_mgr.cpp b/src/share/external_table/ob_external_table_file_mgr.cpp index 4d590278f..4aa73322b 100644 --- a/src/share/external_table/ob_external_table_file_mgr.cpp +++ b/src/share/external_table/ob_external_table_file_mgr.cpp @@ -36,6 +36,7 @@ #include "observer/ob_inner_sql_connection.h" #include "sql/engine/table/ob_external_table_access_service.h" #include "share/external_table/ob_external_table_utils.h" +#include "storage/tablelock/ob_lock_inner_connection_util.h" namespace oceanbase { using namespace observer; @@ -497,7 +498,7 @@ int ObExternalTableFileManager::lock_for_refresh( lock_arg.lock_mode_ = EXCLUSIVE; lock_arg.op_type_ = ObTableLockOpType::IN_TRANS_COMMON_LOCK; lock_arg.timeout_us_ = 1000L * 1000L * 2; //2s - while (OB_FAIL(conn->lock_obj(tenant_id, lock_arg)) && !THIS_WORKER.is_timeout()) { + while (OB_FAIL(ObInnerConnectionLockUtil::lock_obj(tenant_id, lock_arg, conn)) && !THIS_WORKER.is_timeout()) { LOG_WARN("lock failed try again", K(ret)); } } diff --git a/src/share/inner_table/generate_inner_table_schema.py b/src/share/inner_table/generate_inner_table_schema.py index b2205a0e6..ca0021d7d 100755 --- a/src/share/inner_table/generate_inner_table_schema.py +++ b/src/share/inner_table/generate_inner_table_schema.py @@ -975,6 +975,18 @@ def gen_history_table_def(table_id, keywords): return new_keywords +def gen_history_table_def_of_task(table_id, keywords): + new_keywords = copy.deepcopy(keywords) + new_keywords["table_id"] = table_id + new_keywords["table_name"] = "%s_history" % new_keywords["table_name"] + + cols = new_keywords["normal_columns"] + cols.append(('create_time', 'timestamp', 'false')) + cols.append(('finish_time', 'timestamp', 'false')) + + return new_keywords + + def def_all_lob_aux_table(): global lob_aux_ids # build lob meta for 30000 ~ 39999 diff --git a/src/share/inner_table/ob_inner_table_schema.101_150.cpp b/src/share/inner_table/ob_inner_table_schema.101_150.cpp index 4ca3ae668..776283bf6 100644 --- a/src/share/inner_table/ob_inner_table_schema.101_150.cpp +++ b/src/share/inner_table/ob_inner_table_schema.101_150.cpp @@ -2565,6 +2565,25 @@ int ObInnerTableSchema::all_tablegroup_schema(ObTableSchema &table_schema) sub_part_template_flags_default, sub_part_template_flags_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj sharding_default; + sharding_default.set_varchar(ObString::make_string("ADAPTIVE")); + ADD_COLUMN_SCHEMA_T("sharding", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_PARTITION_SHARDING_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + sharding_default, + sharding_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -2937,6 +2956,25 @@ int ObInnerTableSchema::all_tablegroup_history_schema(ObTableSchema &table_schem sub_part_template_flags_default, sub_part_template_flags_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj sharding_default; + sharding_default.set_varchar(ObString::make_string("ADAPTIVE")); + ADD_COLUMN_SCHEMA_T("sharding", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_PARTITION_SHARDING_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false, //is_autoincrement + sharding_default, + sharding_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema.11001_11050.cpp b/src/share/inner_table/ob_inner_table_schema.11001_11050.cpp index f26a3f773..ccddfac3b 100644 --- a/src/share/inner_table/ob_inner_table_schema.11001_11050.cpp +++ b/src/share/inner_table/ob_inner_table_schema.11001_11050.cpp @@ -356,6 +356,25 @@ int ObInnerTableSchema::all_virtual_core_meta_table_schema(ObTableSchema &table_ true, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ObObj rebuild_default; + rebuild_default.set_int(0); + ADD_COLUMN_SCHEMA_T("rebuild", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + rebuild_default, + rebuild_default); //default_value + } table_schema.set_index_using_type(USING_HASH); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema.11051_11100.cpp b/src/share/inner_table/ob_inner_table_schema.11051_11100.cpp index b54c85195..027696ab2 100644 --- a/src/share/inner_table/ob_inner_table_schema.11051_11100.cpp +++ b/src/share/inner_table/ob_inner_table_schema.11051_11100.cpp @@ -2561,6 +2561,21 @@ int ObInnerTableSchema::all_virtual_macro_block_marker_status_schema(ObTableSche false); //is_autoincrement } + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("shared_meta_block_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + if (OB_SUCC(ret)) { ADD_COLUMN_SCHEMA("tmp_file_count", //column_name ++column_id, //column_id @@ -2591,6 +2606,21 @@ int ObInnerTableSchema::all_virtual_macro_block_marker_status_schema(ObTableSche false); //is_autoincrement } + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("shared_data_block_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + if (OB_SUCC(ret)) { ADD_COLUMN_SCHEMA("disk_block_count", //column_name ++column_id, //column_id @@ -2728,6 +2758,21 @@ int ObInnerTableSchema::all_virtual_macro_block_marker_status_schema(ObTableSche false); //is_on_update_for_timestamp } + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("mark_finished", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTinyIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + 1, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + if (OB_SUCC(ret)) { ObObj comment_default; comment_default.set_varchar(ObString::make_string("")); diff --git a/src/share/inner_table/ob_inner_table_schema.12051_12100.cpp b/src/share/inner_table/ob_inner_table_schema.12051_12100.cpp index 5b4e0f36a..fd3cd2110 100644 --- a/src/share/inner_table/ob_inner_table_schema.12051_12100.cpp +++ b/src/share/inner_table/ob_inner_table_schema.12051_12100.cpp @@ -4694,6 +4694,25 @@ int ObInnerTableSchema::all_virtual_tablegroup_schema(ObTableSchema &table_schem sub_part_template_flags_default, sub_part_template_flags_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj sharding_default; + sharding_default.set_varchar(ObString::make_string("ADAPTIVE")); + ADD_COLUMN_SCHEMA_T("sharding", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_PARTITION_SHARDING_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + sharding_default, + sharding_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -5050,6 +5069,25 @@ int ObInnerTableSchema::all_virtual_tablegroup_history_schema(ObTableSchema &tab sub_part_template_flags_default, sub_part_template_flags_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj sharding_default; + sharding_default.set_varchar(ObString::make_string("ADAPTIVE")); + ADD_COLUMN_SCHEMA_T("sharding", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_PARTITION_SHARDING_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false, //is_autoincrement + sharding_default, + sharding_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema.12201_12250.cpp b/src/share/inner_table/ob_inner_table_schema.12201_12250.cpp index 41af83532..aabf17e59 100644 --- a/src/share/inner_table/ob_inner_table_schema.12201_12250.cpp +++ b/src/share/inner_table/ob_inner_table_schema.12201_12250.cpp @@ -9063,6 +9063,25 @@ int ObInnerTableSchema::all_virtual_ls_meta_table_schema(ObTableSchema &table_sc true, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ObObj rebuild_default; + rebuild_default.set_int(0); + ADD_COLUMN_SCHEMA_T("rebuild", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + rebuild_default, + rebuild_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -9437,6 +9456,25 @@ int ObInnerTableSchema::all_virtual_tablet_to_ls_schema(ObTableSchema &table_sch false, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ObObj transfer_seq_default; + transfer_seq_default.set_int(0); + ADD_COLUMN_SCHEMA_T("transfer_seq", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + transfer_seq_default, + transfer_seq_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -10861,6 +10899,44 @@ int ObInnerTableSchema::all_virtual_backup_task_schema(ObTableSchema &table_sche path_default, path_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj minor_turn_id_default; + minor_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("minor_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + minor_turn_id_default, + minor_turn_id_default); //default_value + } + + if (OB_SUCC(ret)) { + ObObj major_turn_id_default; + major_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("major_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + major_turn_id_default, + major_turn_id_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -11387,6 +11463,44 @@ int ObInnerTableSchema::all_virtual_backup_task_history_schema(ObTableSchema &ta path_default, path_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj minor_turn_id_default; + minor_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("minor_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + minor_turn_id_default, + minor_turn_id_default); //default_value + } + + if (OB_SUCC(ret)) { + ObObj major_turn_id_default; + major_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("major_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + major_turn_id_default, + major_turn_id_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -11943,6 +12057,21 @@ int ObInnerTableSchema::all_virtual_backup_ls_task_schema(ObTableSchema &table_s comment_default, comment_default); //default_value } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("max_tablet_checkpoint_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -12499,6 +12628,21 @@ int ObInnerTableSchema::all_virtual_backup_ls_task_history_schema(ObTableSchema comment_default, comment_default); //default_value } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("max_tablet_checkpoint_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema.12251_12300.cpp b/src/share/inner_table/ob_inner_table_schema.12251_12300.cpp index a9c526d08..81f18e295 100644 --- a/src/share/inner_table/ob_inner_table_schema.12251_12300.cpp +++ b/src/share/inner_table/ob_inner_table_schema.12251_12300.cpp @@ -504,6 +504,36 @@ int ObInnerTableSchema::all_virtual_backup_schedule_task_schema(ObTableSchema &t false); //is_autoincrement } + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_ip", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 1, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_port", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 2, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + if (OB_SUCC(ret)) { ADD_COLUMN_SCHEMA("job_id", //column_name ++column_id, //column_id @@ -653,6 +683,16 @@ int ObInnerTableSchema::all_virtual_backup_schedule_task_schema(ObTableSchema &t false, //is_nullable false); //is_autoincrement } + if (OB_SUCC(ret)) { + table_schema.get_part_option().set_part_num(1); + table_schema.set_part_level(PARTITION_LEVEL_ONE); + table_schema.get_part_option().set_part_func_type(PARTITION_FUNC_TYPE_LIST_COLUMNS); + if (OB_FAIL(table_schema.get_part_option().set_part_expr("svr_ip, svr_port"))) { + LOG_WARN("set_part_expr failed", K(ret)); + } else if (OB_FAIL(table_schema.mock_list_partition_array())) { + LOG_WARN("mock list partition array failed", K(ret)); + } + } table_schema.set_index_using_type(USING_HASH); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -1392,6 +1432,25 @@ int ObInnerTableSchema::all_virtual_tenant_info_schema(ObTableSchema &table_sche log_mode_default, log_mode_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj max_ls_id_default; + max_ls_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("max_ls_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + max_ls_id_default, + max_ls_id_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -9434,7 +9493,22 @@ int ObInnerTableSchema::all_virtual_ls_info_schema(ObTableSchema &table_schema) } if (OB_SUCC(ret)) { - ADD_COLUMN_SCHEMA("tablet_change_checkpoint_scn_", //column_name + ADD_COLUMN_SCHEMA("tablet_change_checkpoint_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("transfer_scn", //column_name ++column_id, //column_id 0, //rowkey_id 0, //index_id @@ -9651,6 +9725,111 @@ int ObInnerTableSchema::all_virtual_tablet_info_schema(ObTableSchema &table_sche false, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("transfer_start_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("transfer_seq", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("has_transfer_table", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("restore_status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("is_committed", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("is_empty_shell", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } if (OB_SUCC(ret)) { table_schema.get_part_option().set_part_num(1); table_schema.set_part_level(PARTITION_LEVEL_ONE); @@ -11753,6 +11932,63 @@ int ObInnerTableSchema::all_virtual_backup_set_files_schema(ObTableSchema &table cluster_version_default, cluster_version_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj consistent_scn_default; + consistent_scn_default.set_uint64(0); + ADD_COLUMN_SCHEMA_T("consistent_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + consistent_scn_default, + consistent_scn_default); //default_value + } + + if (OB_SUCC(ret)) { + ObObj minor_turn_id_default; + minor_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("minor_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + minor_turn_id_default, + minor_turn_id_default); //default_value + } + + if (OB_SUCC(ret)) { + ObObj major_turn_id_default; + major_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("major_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + major_turn_id_default, + major_turn_id_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema.12301_12350.cpp b/src/share/inner_table/ob_inner_table_schema.12301_12350.cpp index 9d96b0aa0..7e8fc87d3 100644 --- a/src/share/inner_table/ob_inner_table_schema.12301_12350.cpp +++ b/src/share/inner_table/ob_inner_table_schema.12301_12350.cpp @@ -4810,6 +4810,51 @@ int ObInnerTableSchema::all_virtual_tablet_pointer_status_schema(ObTableSchema & false, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_ptr", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 128, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("initial_state", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTinyIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + 1, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("old_chain", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 128, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } if (OB_SUCC(ret)) { table_schema.get_part_option().set_part_num(1); table_schema.set_part_level(PARTITION_LEVEL_ONE); @@ -8651,6 +8696,1848 @@ int ObInnerTableSchema::all_virtual_data_dictionary_in_log_schema(ObTableSchema return ret; } +int ObInnerTableSchema::all_virtual_transfer_task_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TRANSFER_TASK_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TRANSFER_TASK_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("src_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("dest_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("not_exist_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lock_conflict_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("table_lock_tablet_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("start_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finish_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("result", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("balance_task_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("table_lock_owner_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_transfer_task_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("src_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("dest_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("not_exist_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lock_conflict_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("table_lock_tablet_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("start_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finish_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("result", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("balance_task_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("table_lock_owner_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("create_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("finish_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_balance_job_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_BALANCE_JOB_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_BALANCE_JOB_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("balance_strategy_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("target_unit_num", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("target_primary_zone_num", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_balance_job_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("balance_strategy_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("target_unit_num", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("target_primary_zone_num", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("create_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("finish_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_balance_task_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_BALANCE_TASK_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_BALANCE_TASK_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("src_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("dest_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finished_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finished_part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_group_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("parent_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("child_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("current_transfer_task_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_balance_task_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("src_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("dest_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finished_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finished_part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_group_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("parent_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("child_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("current_transfer_task_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("create_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("finish_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_virtual_rls_policy_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.12351_12400.cpp b/src/share/inner_table/ob_inner_table_schema.12351_12400.cpp index 8dbe5514d..8f2012b9d 100644 --- a/src/share/inner_table/ob_inner_table_schema.12351_12400.cpp +++ b/src/share/inner_table/ob_inner_table_schema.12351_12400.cpp @@ -3678,6 +3678,700 @@ int ObInnerTableSchema::all_virtual_external_table_file_schema(ObTableSchema &ta return ret; } +int ObInnerTableSchema::all_virtual_mds_node_stat_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_MDS_NODE_STAT_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(3); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_MDS_NODE_STAT_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_id", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_ip", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 1, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_port", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 2, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("user_key", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("version_idx", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("writer_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("writer_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_no", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("redo_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("end_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trans_version", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("node_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("state", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("position", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("user_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + if (OB_SUCC(ret)) { + table_schema.get_part_option().set_part_num(1); + table_schema.set_part_level(PARTITION_LEVEL_ONE); + table_schema.get_part_option().set_part_func_type(PARTITION_FUNC_TYPE_LIST_COLUMNS); + if (OB_FAIL(table_schema.get_part_option().set_part_expr("svr_ip, svr_port"))) { + LOG_WARN("set_part_expr failed", K(ret)); + } else if (OB_FAIL(table_schema.mock_list_partition_array())) { + LOG_WARN("mock list partition array failed", K(ret)); + } + } + table_schema.set_index_using_type(USING_HASH); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_mds_event_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_MDS_EVENT_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(3); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_MDS_EVENT_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_id", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_ip", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 1, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_port", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 2, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tid", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tname", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("timestamp", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("event", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("info", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("user_key", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("writer_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("writer_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_no", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + 20, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("redo_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("end_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trans_version", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("node_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("state", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + if (OB_SUCC(ret)) { + table_schema.get_part_option().set_part_num(1); + table_schema.set_part_level(PARTITION_LEVEL_ONE); + table_schema.get_part_option().set_part_func_type(PARTITION_FUNC_TYPE_LIST_COLUMNS); + if (OB_FAIL(table_schema.get_part_option().set_part_expr("svr_ip, svr_port"))) { + LOG_WARN("set_part_expr failed", K(ret)); + } else if (OB_FAIL(table_schema.mock_list_partition_array())) { + LOG_WARN("mock list partition array failed", K(ret)); + } + } + table_schema.set_index_using_type(USING_HASH); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_virtual_dup_ls_lease_mgr_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -6235,6 +6929,172 @@ int ObInnerTableSchema::all_virtual_virtual_long_ops_status_mysql_sys_agent_sche return ret; } +int ObInnerTableSchema::all_virtual_ls_transfer_member_list_lock_info_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_INNER_TABLE_DEFAULT_VALUE_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lock_owner", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_virtual_timestamp_service_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -6409,6 +7269,224 @@ int ObInnerTableSchema::all_virtual_timestamp_service_schema(ObTableSchema &tabl return ret; } +int ObInnerTableSchema::all_virtual_resource_pool_mysql_sys_agent_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_RESOURCE_POOL_MYSQL_SYS_AGENT_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_RESOURCE_POOL_MYSQL_SYS_AGENT_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("resource_pool_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_RESOURCE_POOL_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_config_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("zone_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_ZONE_LIST_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ObObj replica_type_default; + replica_type_default.set_int(0); + ADD_COLUMN_SCHEMA_T("replica_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + replica_type_default, + replica_type_default); //default_value + } + + if (OB_SUCC(ret)) { + ObObj is_tenant_sys_pool_default; + is_tenant_sys_pool_default.set_tinyint(false); + ADD_COLUMN_SCHEMA_T("is_tenant_sys_pool", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTinyIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + 1, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + is_tenant_sys_pool_default, + is_tenant_sys_pool_default); //default_value + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_virtual_px_p2p_datahub_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.12401_12450.cpp b/src/share/inner_table/ob_inner_table_schema.12401_12450.cpp index a782f9c27..f0db1027c 100644 --- a/src/share/inner_table/ob_inner_table_schema.12401_12450.cpp +++ b/src/share/inner_table/ob_inner_table_schema.12401_12450.cpp @@ -214,6 +214,487 @@ int ObInnerTableSchema::all_virtual_ls_log_restore_status_schema(ObTableSchema & return ret; } +int ObInnerTableSchema::all_virtual_tenant_parameter_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TENANT_PARAMETER_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(6); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TENANT_PARAMETER_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("zone", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_ZONE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_type", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + SERVER_TYPE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_ip", //column_name + ++column_id, //column_id + 4, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_port", //column_name + ++column_id, //column_id + 5, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("name", //column_name + ++column_id, //column_id + 6, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_CONFIG_NAME_LEN, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_CONFIG_TYPE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("value", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_CONFIG_VALUE_LEN, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("info", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_CONFIG_INFO_LEN, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("section", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_CONFIG_SECTION_LEN, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("scope", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_CONFIG_SCOPE_LEN, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("source", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_CONFIG_SOURCE_LEN, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("edit_level", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_CONFIG_EDIT_LEVEL_LEN, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("config_version", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_tablet_buffer_info_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TABLET_BUFFER_INFO_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(4); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TABLET_BUFFER_INFO_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_ip", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_port", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet buffer", //column_name + ++column_id, //column_id + 4, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 128, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 128, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("pool type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 128, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("in_map", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTinyIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + 1, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("last_access_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + table_schema.set_index_using_type(USING_HASH); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.15101_15150.cpp b/src/share/inner_table/ob_inner_table_schema.15101_15150.cpp index e2c19fce7..26071b81c 100644 --- a/src/share/inner_table/ob_inner_table_schema.15101_15150.cpp +++ b/src/share/inner_table/ob_inner_table_schema.15101_15150.cpp @@ -10704,6 +10704,21 @@ int ObInnerTableSchema::all_virtual_tablegroup_real_agent_ora_schema(ObTableSche false); //is_autoincrement } + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SHARDING", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_PARTITION_SHARDING_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + if (OB_SUCC(ret)) { ADD_COLUMN_SCHEMA("GMT_CREATE", //column_name ++column_id, //column_id diff --git a/src/share/inner_table/ob_inner_table_schema.15201_15250.cpp b/src/share/inner_table/ob_inner_table_schema.15201_15250.cpp index bb7b85c1b..3557ba5e5 100644 --- a/src/share/inner_table/ob_inner_table_schema.15201_15250.cpp +++ b/src/share/inner_table/ob_inner_table_schema.15201_15250.cpp @@ -4549,6 +4549,21 @@ int ObInnerTableSchema::all_virtual_ls_meta_table_ora_schema(ObTableSchema &tabl true, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("REBUILD", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -4639,6 +4654,21 @@ int ObInnerTableSchema::all_virtual_tablet_to_ls_real_agent_ora_schema(ObTableSc false); //is_autoincrement } + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TRANSFER_SEQ", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + if (OB_SUCC(ret)) { ADD_COLUMN_SCHEMA("GMT_CREATE", //column_name ++column_id, //column_id @@ -10844,6 +10874,36 @@ int ObInnerTableSchema::all_virtual_backup_task_ora_schema(ObTableSchema &table_ true, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("MINOR_TURN_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("MAJOR_TURN_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -11308,6 +11368,36 @@ int ObInnerTableSchema::all_virtual_backup_task_history_ora_schema(ObTableSchema true, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("MINOR_TURN_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("MAJOR_TURN_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -11862,6 +11952,51 @@ int ObInnerTableSchema::all_virtual_backup_set_files_ora_schema(ObTableSchema &t true, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("CONSISTENT_SCN", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("MINOR_TURN_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("MAJOR_TURN_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema.15251_15300.cpp b/src/share/inner_table/ob_inner_table_schema.15251_15300.cpp index de65a71d9..279291baa 100644 --- a/src/share/inner_table/ob_inner_table_schema.15251_15300.cpp +++ b/src/share/inner_table/ob_inner_table_schema.15251_15300.cpp @@ -4837,6 +4837,21 @@ int ObInnerTableSchema::all_virtual_tenant_info_ora_schema(ObTableSchema &table_ false, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("MAX_LS_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema.15351_15400.cpp b/src/share/inner_table/ob_inner_table_schema.15351_15400.cpp index 699a08cea..63f37a923 100644 --- a/src/share/inner_table/ob_inner_table_schema.15351_15400.cpp +++ b/src/share/inner_table/ob_inner_table_schema.15351_15400.cpp @@ -174,6 +174,1934 @@ int ObInnerTableSchema::all_virtual_log_restore_source_ora_schema(ObTableSchema return ret; } +int ObInnerTableSchema::all_virtual_balance_job_real_agent_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("JOB_ID", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("BALANCE_STRATEGY_NAME", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("JOB_TYPE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TARGET_UNIT_NUM", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TARGET_PRIMARY_ZONE_NUM", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("STATUS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("COMMENT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_CREATE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_MODIFIED", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_balance_job_history_real_agent_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("JOB_ID", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("BALANCE_STRATEGY_NAME", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("JOB_TYPE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TARGET_UNIT_NUM", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TARGET_PRIMARY_ZONE_NUM", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("STATUS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("COMMENT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("CREATE_TIME", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("FINISH_TIME", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_CREATE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_MODIFIED", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_balance_task_real_agent_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TASK_ID", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TASK_TYPE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SRC_LS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("DEST_LS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PART_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("FINISHED_PART_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PART_COUNT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("FINISHED_PART_COUNT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("LS_GROUP_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("STATUS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PARENT_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("CHILD_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("CURRENT_TRANSFER_TASK_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("JOB_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("COMMENT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_CREATE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_MODIFIED", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_balance_task_history_real_agent_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TASK_ID", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TASK_TYPE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SRC_LS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("DEST_LS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PART_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("FINISHED_PART_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PART_COUNT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("FINISHED_PART_COUNT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("LS_GROUP_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("STATUS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PARENT_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("CHILD_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("CURRENT_TRANSFER_TASK_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("JOB_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("COMMENT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("CREATE_TIME", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("FINISH_TIME", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_CREATE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_MODIFIED", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_transfer_task_real_agent_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TASK_ID", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SRC_LS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("DEST_LS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PART_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PART_COUNT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("NOT_EXIST_PART_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("LOCK_CONFLICT_PART_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TABLE_LOCK_TABLET_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TABLET_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TABLET_COUNT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("START_SCN", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("FINISH_SCN", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("STATUS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TRACE_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("RESULT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("COMMENT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("BALANCE_TASK_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TABLE_LOCK_OWNER_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_CREATE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_MODIFIED", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_transfer_task_history_real_agent_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TASK_ID", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SRC_LS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("DEST_LS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PART_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PART_COUNT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("NOT_EXIST_PART_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("LOCK_CONFLICT_PART_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TABLE_LOCK_TABLET_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TABLET_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TABLET_COUNT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("START_SCN", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("FINISH_SCN", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("STATUS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TRACE_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("RESULT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("COMMENT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("BALANCE_TASK_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TABLE_LOCK_OWNER_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("CREATE_TIME", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("FINISH_TIME", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_CREATE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_MODIFIED", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_resource_pool_sys_agent_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("RESOURCE_POOL_ID", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("NAME", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + MAX_RESOURCE_POOL_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("UNIT_COUNT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("UNIT_CONFIG_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ZONE_LIST", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + MAX_ZONE_LIST_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TENANT_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("REPLICA_TYPE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("IS_TENANT_SYS_POOL", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_CREATE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_MODIFIED", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_virtual_px_p2p_datahub_ora_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -726,6 +2654,290 @@ int ObInnerTableSchema::all_virtual_ls_log_restore_status_ora_schema(ObTableSche return ret; } +int ObInnerTableSchema::all_virtual_tenant_parameter_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TENANT_PARAMETER_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(6); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TENANT_PARAMETER_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TENANT_ID", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ZONE", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + MAX_ZONE_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SVR_TYPE", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + SERVER_TYPE_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SVR_IP", //column_name + ++column_id, //column_id + 4, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SVR_PORT", //column_name + ++column_id, //column_id + 5, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("NAME", //column_name + ++column_id, //column_id + 6, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_CONFIG_NAME_LEN, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_CREATE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("GMT_MODIFIED", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampLTZType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("DATA_TYPE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_CONFIG_TYPE_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("VALUE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_CONFIG_VALUE_LEN, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("INFO", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_CONFIG_INFO_LEN, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SECTION", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_CONFIG_SECTION_LEN, //column_length + 2, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SCOPE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_CONFIG_SCOPE_LEN, //column_length + 2, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SOURCE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_CONFIG_SOURCE_LEN, //column_length + 2, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("EDIT_LEVEL", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + OB_MAX_CONFIG_EDIT_LEVEL_LEN, //column_length + 2, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("CONFIG_VERSION", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.21101_21150.cpp b/src/share/inner_table/ob_inner_table_schema.21101_21150.cpp index 662fd9380..89c3e0a96 100644 --- a/src/share/inner_table/ob_inner_table_schema.21101_21150.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21101_21150.cpp @@ -660,7 +660,7 @@ int ObInnerTableSchema::cdb_ob_backup_set_files_schema(ObTableSchema &table_sche table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, BACKUP_SET_ID, DEST_ID, INCARNATION, BACKUP_TYPE, PREV_FULL_BACKUP_SET_ID, PREV_INC_BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, FILE_STATUS, CASE WHEN END_TS = 0 THEN 0 ELSE ROUND((END_TS - START_TS)/1000/1000,0) END AS ELAPSED_SECONDES, PLUS_ARCHIVELOG, START_REPLAY_SCN, CASE WHEN START_REPLAY_SCN = 0 THEN NULL ELSE SCN_TO_TIMESTAMP(START_REPLAY_SCN) END AS START_REPLAY_SCN_DISPLAY, MIN_RESTORE_SCN, CASE WHEN MIN_RESTORE_SCN = 0 THEN NULL ELSE SCN_TO_TIMESTAMP(MIN_RESTORE_SCN) END AS MIN_RESTORE_SCN_DISPLAY, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, ENCRYPTION_MODE, PASSWD, TENANT_COMPATIBLE, BACKUP_COMPATIBLE, PATH, CLUSTER_VERSION FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_SET_FILES )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, BACKUP_SET_ID, DEST_ID, INCARNATION, BACKUP_TYPE, PREV_FULL_BACKUP_SET_ID, PREV_INC_BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, FILE_STATUS, CASE WHEN END_TS = 0 THEN 0 ELSE ROUND((END_TS - START_TS)/1000/1000,0) END AS ELAPSED_SECONDES, PLUS_ARCHIVELOG, START_REPLAY_SCN, CASE WHEN START_REPLAY_SCN = 0 THEN NULL ELSE SCN_TO_TIMESTAMP(START_REPLAY_SCN) END AS START_REPLAY_SCN_DISPLAY, MIN_RESTORE_SCN, CASE WHEN MIN_RESTORE_SCN = 0 THEN NULL ELSE SCN_TO_TIMESTAMP(MIN_RESTORE_SCN) END AS MIN_RESTORE_SCN_DISPLAY, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, ENCRYPTION_MODE, PASSWD, TENANT_COMPATIBLE, BACKUP_COMPATIBLE, PATH, CLUSTER_VERSION, CONSISTENT_SCN, MINOR_TURN_ID, MAJOR_TURN_ID FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_SET_FILES )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.21151_21200.cpp b/src/share/inner_table/ob_inner_table_schema.21151_21200.cpp index 0f575b8a9..a97c3cc6a 100644 --- a/src/share/inner_table/ob_inner_table_schema.21151_21200.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21151_21200.cpp @@ -260,7 +260,7 @@ int ObInnerTableSchema::cdb_ob_backup_tasks_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, PATH FROM OCEANBASE.__all_virtual_backup_task )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, PATH, MINOR_TURN_ID, MAJOR_TURN_ID FROM OCEANBASE.__all_virtual_backup_task )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -310,7 +310,7 @@ int ObInnerTableSchema::cdb_ob_backup_task_history_schema(ObTableSchema &table_s table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, PATH FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_TASK_HISTORY )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, PATH, MINOR_TURN_ID, MAJOR_TURN_ID FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_TASK_HISTORY )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -410,7 +410,7 @@ int ObInnerTableSchema::dba_ob_tenants_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT A.TENANT_ID, TENANT_NAME, (CASE WHEN A.TENANT_ID = 1 THEN 'SYS' WHEN (A.TENANT_ID & 0x1) = 1 THEN 'META' ELSE 'USER' END) AS TENANT_TYPE, A.gmt_create AS CREATE_TIME, A.gmt_modified AS MODIFY_TIME, PRIMARY_ZONE, LOCALITY, CASE previous_locality WHEN "" THEN NULL ELSE previous_locality END AS PREVIOUS_LOCALITY, CASE compatibility_mode WHEN 0 THEN 'MYSQL' WHEN 1 THEN 'ORACLE' ELSE NULL END AS COMPATIBILITY_MODE, STATUS, CASE in_recyclebin WHEN 0 THEN 'NO' ELSE 'YES' END AS IN_RECYCLEBIN, CASE locked WHEN 0 THEN 'NO' ELSE 'YES' END AS LOCKED, (CASE WHEN A.TENANT_ID = 1 THEN 'PRIMARY' WHEN (A.TENANT_ID & 0x1) = 1 THEN 'PRIMARY' ELSE TENANT_ROLE END) AS TENANT_ROLE, (CASE WHEN A.TENANT_ID = 1 THEN 'NORMAL' WHEN (A.TENANT_ID & 0x1) = 1 THEN 'NORMAL' ELSE SWITCHOVER_STATUS END) AS SWITCHOVER_STATUS, (CASE WHEN A.TENANT_ID = 1 THEN 0 WHEN (A.TENANT_ID & 0x1) = 1 THEN 0 ELSE SWITCHOVER_EPOCH END) AS SWITCHOVER_EPOCH, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (A.TENANT_ID & 0x1) = 1 THEN NULL ELSE SYNC_SCN END) AS SYNC_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (A.TENANT_ID & 0x1) = 1 THEN NULL ELSE REPLAYABLE_SCN END) AS REPLAYABLE_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (A.TENANT_ID & 0x1) = 1 THEN NULL ELSE READABLE_SCN END) AS READABLE_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (A.TENANT_ID & 0x1) = 1 THEN NULL ELSE RECOVERY_UNTIL_SCN END) AS RECOVERY_UNTIL_SCN, (CASE WHEN A.TENANT_ID = 1 THEN 'NOARCHIVELOG' WHEN (A.TENANT_ID & 0x1) = 1 THEN 'NOARCHIVELOG' ELSE LOG_MODE END) AS LOG_MODE, ARBITRATION_SERVICE_STATUS FROM OCEANBASE.__ALL_VIRTUAL_TENANT_MYSQL_SYS_AGENT AS A LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TENANT_INFO AS B ON A.TENANT_ID = B.TENANT_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT A.TENANT_ID, TENANT_NAME, (CASE WHEN A.TENANT_ID = 1 THEN 'SYS' WHEN (A.TENANT_ID & 0x1) = 1 THEN 'META' ELSE 'USER' END) AS TENANT_TYPE, A.gmt_create AS CREATE_TIME, A.gmt_modified AS MODIFY_TIME, PRIMARY_ZONE, LOCALITY, CASE previous_locality WHEN "" THEN NULL ELSE previous_locality END AS PREVIOUS_LOCALITY, CASE compatibility_mode WHEN 0 THEN 'MYSQL' WHEN 1 THEN 'ORACLE' ELSE NULL END AS COMPATIBILITY_MODE, STATUS, CASE in_recyclebin WHEN 0 THEN 'NO' ELSE 'YES' END AS IN_RECYCLEBIN, CASE locked WHEN 0 THEN 'NO' ELSE 'YES' END AS LOCKED, (CASE WHEN A.TENANT_ID = 1 THEN 'PRIMARY' WHEN (A.TENANT_ID & 0x1) = 1 THEN 'PRIMARY' ELSE TENANT_ROLE END) AS TENANT_ROLE, (CASE WHEN A.TENANT_ID = 1 THEN 'NORMAL' WHEN (A.TENANT_ID & 0x1) = 1 THEN 'NORMAL' ELSE SWITCHOVER_STATUS END) AS SWITCHOVER_STATUS, (CASE WHEN A.TENANT_ID = 1 THEN 0 WHEN (A.TENANT_ID & 0x1) = 1 THEN 0 ELSE SWITCHOVER_EPOCH END) AS SWITCHOVER_EPOCH, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (A.TENANT_ID & 0x1) = 1 THEN NULL ELSE SYNC_SCN END) AS SYNC_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (A.TENANT_ID & 0x1) = 1 THEN NULL ELSE REPLAYABLE_SCN END) AS REPLAYABLE_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (A.TENANT_ID & 0x1) = 1 THEN NULL ELSE READABLE_SCN END) AS READABLE_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (A.TENANT_ID & 0x1) = 1 THEN NULL ELSE RECOVERY_UNTIL_SCN END) AS RECOVERY_UNTIL_SCN, (CASE WHEN A.TENANT_ID = 1 THEN 'NOARCHIVELOG' WHEN (A.TENANT_ID & 0x1) = 1 THEN 'NOARCHIVELOG' ELSE LOG_MODE END) AS LOG_MODE, ARBITRATION_SERVICE_STATUS, UNIT_NUM, COMPATIBLE FROM OCEANBASE.__ALL_VIRTUAL_TENANT_MYSQL_SYS_AGENT AS A LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TENANT_INFO AS B ON A.TENANT_ID = B.TENANT_ID LEFT JOIN (SELECT TENANT_ID, (CASE WHEN TENANT_ID < 1 THEN NULL WHEN TENANT_ID != 1 THEN TENANT_ID - 1 ELSE NULL END) AS META_TENANT_ID, MIN(UNIT_COUNT) AS UNIT_NUM FROM OCEANBASE.__ALL_VIRTUAL_RESOURCE_POOL_MYSQL_SYS_AGENT GROUP BY TENANT_ID) AS C ON A.TENANT_ID = C.TENANT_ID OR A.TENANT_ID = C.META_TENANT_ID LEFT JOIN (SELECT TENANT_ID, MIN(VALUE) AS COMPATIBLE FROM OCEANBASE.__ALL_VIRTUAL_TENANT_PARAMETER WHERE NAME = 'compatible' GROUP BY TENANT_ID) AS D ON A.TENANT_ID = D.TENANT_ID )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -910,7 +910,7 @@ int ObInnerTableSchema::dba_ob_ls_locations_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( ( SELECT NOW(6) AS CREATE_TIME, NOW(6) AS MODIFY_TIME, LS_ID, SVR_IP, SVR_PORT, SQL_PORT, ZONE, (CASE ROLE WHEN 1 THEN "LEADER" ELSE "FOLLOWER" END) AS ROLE, (CASE ROLE WHEN 1 THEN MEMBER_LIST ELSE NULL END) AS MEMBER_LIST, (CASE ROLE WHEN 1 THEN PAXOS_REPLICA_NUMBER ELSE NULL END) AS PAXOS_REPLICA_NUMBER, (CASE REPLICA_TYPE WHEN 0 THEN "FULL" WHEN 5 THEN "LOGONLY" WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST FROM OCEANBASE.__ALL_VIRTUAL_CORE_META_TABLE WHERE EFFECTIVE_TENANT_ID() = 1 ) UNION ALL ( SELECT GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, LS_ID, SVR_IP, SVR_PORT, SQL_PORT, ZONE, (CASE ROLE WHEN 1 THEN "LEADER" ELSE "FOLLOWER" END) AS ROLE, (CASE ROLE WHEN 1 THEN MEMBER_LIST ELSE NULL END) AS MEMBER_LIST, (CASE ROLE WHEN 1 THEN PAXOS_REPLICA_NUMBER ELSE NULL END) AS PAXOS_REPLICA_NUMBER, (CASE REPLICA_TYPE WHEN 0 THEN "FULL" WHEN 5 THEN "LOGONLY" WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST FROM OCEANBASE.__ALL_VIRTUAL_LS_META_TABLE WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TENANT_ID != 1 ) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( ( SELECT NOW(6) AS CREATE_TIME, NOW(6) AS MODIFY_TIME, LS_ID, SVR_IP, SVR_PORT, SQL_PORT, ZONE, (CASE ROLE WHEN 1 THEN "LEADER" ELSE "FOLLOWER" END) AS ROLE, (CASE ROLE WHEN 1 THEN MEMBER_LIST ELSE NULL END) AS MEMBER_LIST, (CASE ROLE WHEN 1 THEN PAXOS_REPLICA_NUMBER ELSE NULL END) AS PAXOS_REPLICA_NUMBER, (CASE REPLICA_TYPE WHEN 0 THEN "FULL" WHEN 5 THEN "LOGONLY" WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST, (CASE REBUILD WHEN 0 THEN "FALSE" ELSE "TRUE" END) AS REBUILD FROM OCEANBASE.__ALL_VIRTUAL_CORE_META_TABLE WHERE EFFECTIVE_TENANT_ID() = 1 ) UNION ALL ( SELECT GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, LS_ID, SVR_IP, SVR_PORT, SQL_PORT, ZONE, (CASE ROLE WHEN 1 THEN "LEADER" ELSE "FOLLOWER" END) AS ROLE, (CASE ROLE WHEN 1 THEN MEMBER_LIST ELSE NULL END) AS MEMBER_LIST, (CASE ROLE WHEN 1 THEN PAXOS_REPLICA_NUMBER ELSE NULL END) AS PAXOS_REPLICA_NUMBER, (CASE REPLICA_TYPE WHEN 0 THEN "FULL" WHEN 5 THEN "LOGONLY" WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST, (CASE REBUILD WHEN 0 THEN "FALSE" ELSE "TRUE" END) AS REBUILD FROM OCEANBASE.__ALL_VIRTUAL_LS_META_TABLE WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TENANT_ID != 1 ) )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -960,7 +960,7 @@ int ObInnerTableSchema::cdb_ob_ls_locations_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( ( SELECT NOW(6) AS CREATE_TIME, NOW(6) AS MODIFY_TIME, TENANT_ID, LS_ID, SVR_IP, SVR_PORT, SQL_PORT, ZONE, (CASE ROLE WHEN 1 THEN "LEADER" ELSE "FOLLOWER" END) AS ROLE, (CASE ROLE WHEN 1 THEN MEMBER_LIST ELSE NULL END) AS MEMBER_LIST, (CASE ROLE WHEN 1 THEN PAXOS_REPLICA_NUMBER ELSE NULL END) AS PAXOS_REPLICA_NUMBER, (CASE REPLICA_TYPE WHEN 0 THEN "FULL" WHEN 5 THEN "LOGONLY" WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST FROM OCEANBASE.__ALL_VIRTUAL_CORE_META_TABLE ) UNION ALL ( SELECT GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, TENANT_ID, LS_ID, SVR_IP, SVR_PORT, SQL_PORT, ZONE, (CASE ROLE WHEN 1 THEN "LEADER" ELSE "FOLLOWER" END) AS ROLE, (CASE ROLE WHEN 1 THEN MEMBER_LIST ELSE NULL END) AS MEMBER_LIST, (CASE ROLE WHEN 1 THEN PAXOS_REPLICA_NUMBER ELSE NULL END) AS PAXOS_REPLICA_NUMBER, (CASE REPLICA_TYPE WHEN 0 THEN "FULL" WHEN 5 THEN "LOGONLY" WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST FROM OCEANBASE.__ALL_VIRTUAL_LS_META_TABLE WHERE TENANT_ID != 1 ) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( ( SELECT NOW(6) AS CREATE_TIME, NOW(6) AS MODIFY_TIME, TENANT_ID, LS_ID, SVR_IP, SVR_PORT, SQL_PORT, ZONE, (CASE ROLE WHEN 1 THEN "LEADER" ELSE "FOLLOWER" END) AS ROLE, (CASE ROLE WHEN 1 THEN MEMBER_LIST ELSE NULL END) AS MEMBER_LIST, (CASE ROLE WHEN 1 THEN PAXOS_REPLICA_NUMBER ELSE NULL END) AS PAXOS_REPLICA_NUMBER, (CASE REPLICA_TYPE WHEN 0 THEN "FULL" WHEN 5 THEN "LOGONLY" WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST, (CASE REBUILD WHEN 0 THEN "FALSE" ELSE "TRUE" END) AS REBUILD FROM OCEANBASE.__ALL_VIRTUAL_CORE_META_TABLE ) UNION ALL ( SELECT GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, TENANT_ID, LS_ID, SVR_IP, SVR_PORT, SQL_PORT, ZONE, (CASE ROLE WHEN 1 THEN "LEADER" ELSE "FOLLOWER" END) AS ROLE, (CASE ROLE WHEN 1 THEN MEMBER_LIST ELSE NULL END) AS MEMBER_LIST, (CASE ROLE WHEN 1 THEN PAXOS_REPLICA_NUMBER ELSE NULL END) AS PAXOS_REPLICA_NUMBER, (CASE REPLICA_TYPE WHEN 0 THEN "FULL" WHEN 5 THEN "LOGONLY" WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST, (CASE REBUILD WHEN 0 THEN "FALSE" ELSE "TRUE" END) AS REBUILD FROM OCEANBASE.__ALL_VIRTUAL_LS_META_TABLE WHERE TENANT_ID != 1 ) )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1210,7 +1210,7 @@ int ObInnerTableSchema::dba_ob_tablegroups_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TABLEGROUP_NAME, (CASE PART_LEVEL WHEN 0 THEN 'NONE' ELSE (CASE PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'UNKNOWN' ELSE 'UNKNOWN' END) END) AS PARTITIONING_TYPE, (CASE PART_LEVEL WHEN 2 THEN (CASE SUB_PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'UNKNOWN' ELSE 'UNKNOWN' END) ELSE 'NONE' END) AS SUBPARTITIONING_TYPE, (CASE PART_LEVEL WHEN 0 THEN NULL ELSE PART_NUM END) AS PARTITION_COUNT, CAST(NULL AS SIGNED) AS DEF_SUBPARTITION_COUNT, (CASE PART_LEVEL WHEN 0 THEN NULL ELSE PART_FUNC_EXPR_NUM END) AS PARTITIONING_KEY_COUNT, (CASE PART_LEVEL WHEN 2 THEN SUB_PART_FUNC_EXPR_NUM ELSE NULL END) AS SUBPARTITIONING_KEY_COUNT FROM OCEANBASE.__ALL_TABLEGROUP )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TABLEGROUP_NAME, CAST("NONE" AS CHAR(13)) AS PARTITIONING_TYPE, CAST("NONE" AS CHAR(13)) AS SUBPARTITIONING_TYPE, CAST(NULL AS SIGNED) AS PARTITION_COUNT, CAST(NULL AS SIGNED) AS DEF_SUBPARTITION_COUNT, CAST(NULL AS SIGNED) AS PARTITIONING_KEY_COUNT, CAST(NULL AS SIGNED) AS SUBPARTITIONING_KEY_COUNT, SHARDING FROM OCEANBASE.__ALL_TABLEGROUP )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1260,7 +1260,7 @@ int ObInnerTableSchema::cdb_ob_tablegroups_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, TABLEGROUP_NAME, (CASE PART_LEVEL WHEN 0 THEN 'NONE' ELSE (CASE PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'UNKNOWN' ELSE 'UNKNOWN' END) END) AS PARTITIONING_TYPE, (CASE PART_LEVEL WHEN 2 THEN (CASE SUB_PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'UNKNOWN' ELSE 'UNKNOWN' END) ELSE 'NONE' END) AS SUBPARTITIONING_TYPE, (CASE PART_LEVEL WHEN 0 THEN NULL ELSE PART_NUM END) AS PARTITION_COUNT, CAST(NULL AS SIGNED) AS DEF_SUBPARTITION_COUNT, (CASE PART_LEVEL WHEN 0 THEN NULL ELSE PART_FUNC_EXPR_NUM END) AS PARTITIONING_KEY_COUNT, (CASE PART_LEVEL WHEN 2 THEN SUB_PART_FUNC_EXPR_NUM ELSE NULL END) AS SUBPARTITIONING_KEY_COUNT FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, TABLEGROUP_NAME, CAST("NONE" AS CHAR(13)) AS PARTITIONING_TYPE, CAST("NONE" AS CHAR(13)) AS SUBPARTITIONING_TYPE, CAST(NULL AS SIGNED) AS PARTITION_COUNT, CAST(NULL AS SIGNED) AS DEF_SUBPARTITION_COUNT, CAST(NULL AS SIGNED) AS PARTITIONING_KEY_COUNT, CAST(NULL AS SIGNED) AS SUBPARTITIONING_KEY_COUNT, SHARDING FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1310,7 +1310,7 @@ int ObInnerTableSchema::dba_ob_tablegroup_partitions_schema(ObTableSchema &table table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT T.TABLEGROUP_NAME AS TABLEGROUP_NAME, (CASE T.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END) AS COMPOSITE, P.PART_NAME AS PARTITION_NAME, (CASE T.PART_LEVEL WHEN 2 THEN P.SUB_PART_NUM ELSE NULL END) AS SUBPARTITION_COUNT, (CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL WHEN LENGTH(P.LIST_VAL) > 0 THEN P.LIST_VAL ELSE NULL END) AS HIGH_VALUE, (CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN LENGTH(P.HIGH_BOUND_VAL) WHEN LENGTH(P.LIST_VAL) > 0 THEN LENGTH(P.LIST_VAL) ELSE NULL END) AS HIGH_VALUE_LENGTH, P.PARTITION_POSITION AS PARTITION_POSITION FROM OCEANBASE.__ALL_TABLEGROUP AS T JOIN (SELECT *, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_PART) AS P ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST("" AS CHAR(128)) AS TABLEGROUP_NAME, CAST("NO" AS CHAR(3)) AS COMPOSITE, CAST("" AS CHAR(64)) AS PARTITION_NAME, CAST(NULL AS SIGNED) AS SUBPARTITION_COUNT, CAST(NULL AS CHAR(4096)) AS HIGH_VALUE, CAST(NULL AS SIGNED) AS HIGH_VALUE_LENGTH, CAST(NULL AS UNSIGNED) AS PARTITION_POSITION FROM DUAL WHERE 0 = 1 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1360,7 +1360,7 @@ int ObInnerTableSchema::cdb_ob_tablegroup_partitions_schema(ObTableSchema &table table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT T.TENANT_ID AS TENANT_ID, T.TABLEGROUP_NAME AS TABLEGROUP_NAME, (CASE T.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END) AS COMPOSITE, P.PART_NAME AS PARTITION_NAME, (CASE T.PART_LEVEL WHEN 2 THEN P.SUB_PART_NUM ELSE NULL END) AS SUBPARTITION_COUNT, (CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL WHEN LENGTH(P.LIST_VAL) > 0 THEN P.LIST_VAL ELSE NULL END) AS HIGH_VALUE, (CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN LENGTH(P.HIGH_BOUND_VAL) WHEN LENGTH(P.LIST_VAL) > 0 THEN LENGTH(P.LIST_VAL) ELSE NULL END) AS HIGH_VALUE_LENGTH, P.PARTITION_POSITION AS PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP AS T JOIN (SELECT *, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_PART) AS P ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(NULL AS SIGNED) AS TENANT_ID, CAST('' AS CHAR(128)) AS TABLEGROUP_NAME, CAST('NO' AS CHAR(3)) AS COMPOSITE, CAST('' AS CHAR(64)) AS PARTITION_NAME, CAST(NULL AS SIGNED) AS SUBPARTITION_COUNT, CAST(NULL AS CHAR(4096)) AS HIGH_VALUE, CAST(NULL AS SIGNED) AS HIGH_VALUE_LENGTH, CAST(NULL AS UNSIGNED) AS PARTITION_POSITION FROM DUAL WHERE 0 = 1 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1410,7 +1410,7 @@ int ObInnerTableSchema::dba_ob_tablegroup_subpartitions_schema(ObTableSchema &ta table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT T.TABLEGROUP_NAME AS TABLEGROUP_NAME, P.PART_NAME AS PARTITION_NAME, SP.SUB_PART_NAME AS SUBPARTITION_NAME, (CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL WHEN LENGTH(SP.LIST_VAL) > 0 THEN SP.LIST_VAL ELSE NULL END) AS HIGH_VALUE, (CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN LENGTH(SP.HIGH_BOUND_VAL) WHEN LENGTH(SP.LIST_VAL) > 0 THEN LENGTH(SP.LIST_VAL) ELSE NULL END) AS HIGH_VALUE_LENGTH, P.PARTITION_POSITION AS PARTITION_POSITION, SP.SUBPARTITION_POSITION AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_TABLEGROUP AS T JOIN (SELECT *, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_PART) AS P ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID JOIN (SELECT *, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_SUB_PART) AS SP ON P.TENANT_ID = SP.TENANT_ID AND P.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST("" AS CHAR(128)) AS TABLEGROUP_NAME, CAST("" AS CHAR(64)) AS PARTITION_NAME, CAST("" AS CHAR(64)) AS SUBPARTITION_NAME, CAST(NULL AS CHAR(4096)) AS HIGH_VALUE, CAST(NULL AS SIGNED) AS HIGH_VALUE_LENGTH, CAST(NULL AS UNSIGNED) AS PARTITION_POSITION, CAST(NULL AS UNSIGNED) AS SUBPARTITION_POSITION FROM DUAL WHERE 0 = 1 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1460,7 +1460,7 @@ int ObInnerTableSchema::cdb_ob_tablegroup_subpartitions_schema(ObTableSchema &ta table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT T.TENANT_ID AS TENANT_ID, T.TABLEGROUP_NAME AS TABLEGROUP_NAME, P.PART_NAME AS PARTITION_NAME, SP.SUB_PART_NAME AS SUBPARTITION_NAME, (CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL WHEN LENGTH(SP.LIST_VAL) > 0 THEN SP.LIST_VAL ELSE NULL END) AS HIGH_VALUE, (CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN LENGTH(SP.HIGH_BOUND_VAL) WHEN LENGTH(SP.LIST_VAL) > 0 THEN LENGTH(SP.LIST_VAL) ELSE NULL END) AS HIGH_VALUE_LENGTH, P.PARTITION_POSITION AS PARTITION_POSITION, SP.SUBPARTITION_POSITION AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP AS T JOIN (SELECT *, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_PART) AS P ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID JOIN (SELECT *, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_SUB_PART) AS SP ON P.TENANT_ID = SP.TENANT_ID AND P.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(NULL AS SIGNED) AS TENANT_ID, CAST("" AS CHAR(128)) AS TABLEGROUP_NAME, CAST("" AS CHAR(64)) AS PARTITION_NAME, CAST("" AS CHAR(64)) AS SUBPARTITION_NAME, CAST(NULL AS CHAR(4096)) AS HIGH_VALUE, CAST(NULL AS SIGNED) AS HIGH_VALUE_LENGTH, CAST(NULL AS UNSIGNED) AS PARTITION_POSITION, CAST(NULL AS UNSIGNED) AS SUBPARTITION_POSITION FROM DUAL WHERE 0 = 1 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1610,7 +1610,7 @@ int ObInnerTableSchema::dba_ob_tablegroup_tables_schema(ObTableSchema &table_sch table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TG.TABLEGROUP_NAME AS TABLEGROUP_NAME, D.DATABASE_NAME AS OWNER, T.TABLE_NAME AS TABLE_NAME FROM OCEANBASE.__ALL_TABLE AS T JOIN OCEANBASE.__ALL_DATABASE AS D ON T.TENANT_ID = D.TENANT_ID AND T.DATABASE_ID = D.DATABASE_ID JOIN OCEANBASE.__ALL_TABLEGROUP AS TG ON T.TENANT_ID = TG.TENANT_ID AND T.TABLEGROUP_ID = TG.TABLEGROUP_ID WHERE T.TABLE_TYPE = 3 )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TG.TABLEGROUP_NAME AS TABLEGROUP_NAME, D.DATABASE_NAME AS OWNER, T.TABLE_NAME AS TABLE_NAME, TG.SHARDING AS SHARDING FROM OCEANBASE.__ALL_TABLE AS T JOIN OCEANBASE.__ALL_DATABASE AS D ON T.TENANT_ID = D.TENANT_ID AND T.DATABASE_ID = D.DATABASE_ID JOIN OCEANBASE.__ALL_TABLEGROUP AS TG ON T.TENANT_ID = TG.TENANT_ID AND T.TABLEGROUP_ID = TG.TABLEGROUP_ID WHERE T.TABLE_TYPE in (0, 3, 6) )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1660,7 +1660,7 @@ int ObInnerTableSchema::cdb_ob_tablegroup_tables_schema(ObTableSchema &table_sch table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT T.TENANT_ID AS TENANT_ID, TG.TABLEGROUP_NAME AS TABLEGROUP_NAME, D.DATABASE_NAME AS OWNER, T.TABLE_NAME AS TABLE_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE AS T JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE AS D ON T.TENANT_ID = D.TENANT_ID AND T.DATABASE_ID = D.DATABASE_ID JOIN OCEANBASE.__ALL_VIRTUAL_TABLEGROUP AS TG ON T.TENANT_ID = TG.TENANT_ID AND T.TABLEGROUP_ID = TG.TABLEGROUP_ID WHERE T.TABLE_TYPE = 3 )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT T.TENANT_ID AS TENANT_ID, TG.TABLEGROUP_NAME AS TABLEGROUP_NAME, D.DATABASE_NAME AS OWNER, T.TABLE_NAME AS TABLE_NAME, TG.SHARDING AS SHARDING FROM OCEANBASE.__ALL_VIRTUAL_TABLE AS T JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE AS D ON T.TENANT_ID = D.TENANT_ID AND T.DATABASE_ID = D.DATABASE_ID JOIN OCEANBASE.__ALL_VIRTUAL_TABLEGROUP AS TG ON T.TENANT_ID = TG.TENANT_ID AND T.TABLEGROUP_ID = TG.TABLEGROUP_ID WHERE T.TABLE_TYPE in (0, 3, 6) )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1910,7 +1910,7 @@ int ObInnerTableSchema::cdb_objects_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(A.TENANT_ID AS SIGNED) AS CON_ID, CAST(B.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS CHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS CHAR(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS SIGNED) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS SIGNED) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS CHAR(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATETIME) AS CREATED, CAST(A.GMT_MODIFIED AS DATETIME) AS LAST_DDL_TIME, CAST(A.GMT_CREATE AS DATETIME) AS TIMESTAMP, CAST(A.STATUS AS CHAR(7)) AS STATUS, CAST(A.TEMPORARY AS CHAR(1)) AS TEMPORARY, CAST(A.`GENERATED` AS CHAR(1)) AS "GENERATED", CAST(A.SECONDARY AS CHAR(1)) AS SECONDARY, CAST(A.NAMESPACE AS SIGNED) AS NAMESPACE, CAST(A.EDITION_NAME AS CHAR(128)) AS EDITION_NAME, CAST(NULL AS CHAR(18)) AS SHARING, CAST(NULL AS CHAR(1)) AS EDITIONABLE, CAST(NULL AS CHAR(1)) AS ORACLE_MAINTAINED, CAST(NULL AS CHAR(1)) AS APPLICATION, CAST(NULL AS CHAR(1)) AS DEFAULT_COLLATION, CAST(NULL AS CHAR(1)) AS DUPLICATED, CAST(NULL AS CHAR(1)) AS SHARDED, CAST(NULL AS CHAR(1)) AS IMPORTED_OBJECT, CAST(NULL AS SIGNED) AS CREATED_APPID, CAST(NULL AS SIGNED) AS CREATED_VSNID, CAST(NULL AS SIGNED) AS MODIFIED_APPID, CAST(NULL AS SIGNED) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, USEC_TO_TIME(B.SCHEMA_VERSION) AS GMT_CREATE, USEC_TO_TIME(A.SCHEMA_VERSION) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS SIGNED) AS OBJECT_ID, A.TABLET_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE A JOIN OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID AND B.TABLE_NAME = '__all_core_table' UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + POSITION('_' IN SUBSTR(TABLE_NAME, 7))) ELSE TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS CHAR(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLE_TYPE != 12 AND TABLE_TYPE != 13 UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.constraint_name AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CONSTRAINT CST, OCEANBASE.__ALL_VIRTUAL_TABLE TBL, OCEANBASE.__ALL_VIRTUAL_DATABASE DB WHERE CST.TENANT_ID = TBL.TENANT_ID AND TBL.TENANT_ID = DB.TENANT_ID AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX PARTITION' ELSE 'TABLE PARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = P.TENANT_ID UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX SUBPARTITION' ELSE 'TABLE SUBPARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_PACKAGE P UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_ROUTINE R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TYPE UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_OBJECT_TYPE WHERE TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TRIGGER T UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_SEQUENCE_OBJECT UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_SYNONYM UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS SIGNED) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TENANT_CONTEXT UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_DATABASE UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, TABLEGROUP_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP UNION ALL SELECT P.TENANT_ID, P.GMT_CREATE, P.GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TG.TABLEGROUP_NAME AS OBJECT_NAME, P.PART_NAME SUBOBJECT_NAME, P.PART_ID OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP PARTITION' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, NULL AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP TG JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON TG.TABLEGROUP_ID = P.TABLE_ID WHERE TG.TENANT_ID = P.TENANT_ID UNION ALL SELECT SUBP.TENANT_ID, SUBP.GMT_CREATE, SUBP.GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TG.TABLEGROUP_NAME AS OBJECT_NAME, SUBP.SUB_PART_NAME SUBOBJECT_NAME, SUBP.SUB_PART_ID OBJECT_ID, NULL DATA_OBJECT_ID, 'TABLEGROUP SUBPARTITION' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'Y' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP TG, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART SUBP WHERE TG.TABLEGROUP_ID = P.TABLE_ID AND P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID AND TG.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID ) A JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(A.TENANT_ID AS SIGNED) AS CON_ID, CAST(B.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS CHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS CHAR(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS SIGNED) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS SIGNED) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS CHAR(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATETIME) AS CREATED, CAST(A.GMT_MODIFIED AS DATETIME) AS LAST_DDL_TIME, CAST(A.GMT_CREATE AS DATETIME) AS TIMESTAMP, CAST(A.STATUS AS CHAR(7)) AS STATUS, CAST(A.TEMPORARY AS CHAR(1)) AS TEMPORARY, CAST(A.`GENERATED` AS CHAR(1)) AS "GENERATED", CAST(A.SECONDARY AS CHAR(1)) AS SECONDARY, CAST(A.NAMESPACE AS SIGNED) AS NAMESPACE, CAST(A.EDITION_NAME AS CHAR(128)) AS EDITION_NAME, CAST(NULL AS CHAR(18)) AS SHARING, CAST(NULL AS CHAR(1)) AS EDITIONABLE, CAST(NULL AS CHAR(1)) AS ORACLE_MAINTAINED, CAST(NULL AS CHAR(1)) AS APPLICATION, CAST(NULL AS CHAR(1)) AS DEFAULT_COLLATION, CAST(NULL AS CHAR(1)) AS DUPLICATED, CAST(NULL AS CHAR(1)) AS SHARDED, CAST(NULL AS CHAR(1)) AS IMPORTED_OBJECT, CAST(NULL AS SIGNED) AS CREATED_APPID, CAST(NULL AS SIGNED) AS CREATED_VSNID, CAST(NULL AS SIGNED) AS MODIFIED_APPID, CAST(NULL AS SIGNED) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, USEC_TO_TIME(B.SCHEMA_VERSION) AS GMT_CREATE, USEC_TO_TIME(A.SCHEMA_VERSION) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS SIGNED) AS OBJECT_ID, A.TABLET_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE A JOIN OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID AND B.TABLE_NAME = '__all_core_table' UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + POSITION('_' IN SUBSTR(TABLE_NAME, 7))) ELSE TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS CHAR(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLE_TYPE != 12 AND TABLE_TYPE != 13 UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.constraint_name AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CONSTRAINT CST, OCEANBASE.__ALL_VIRTUAL_TABLE TBL, OCEANBASE.__ALL_VIRTUAL_DATABASE DB WHERE CST.TENANT_ID = TBL.TENANT_ID AND TBL.TENANT_ID = DB.TENANT_ID AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX PARTITION' ELSE 'TABLE PARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = P.TENANT_ID UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX SUBPARTITION' ELSE 'TABLE SUBPARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_PACKAGE P UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_ROUTINE R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TYPE UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_OBJECT_TYPE WHERE TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TRIGGER T UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_SEQUENCE_OBJECT UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_SYNONYM UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS SIGNED) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TENANT_CONTEXT UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_DATABASE UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, TABLEGROUP_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP ) A JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp b/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp index ae4811322..f4a46f504 100644 --- a/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp @@ -260,7 +260,7 @@ int ObInnerTableSchema::dba_objects_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(B.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS CHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS CHAR(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS SIGNED) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS SIGNED) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS CHAR(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATETIME) AS CREATED, CAST(A.GMT_MODIFIED AS DATETIME) AS LAST_DDL_TIME, CAST(A.GMT_CREATE AS DATETIME) AS TIMESTAMP, CAST(A.STATUS AS CHAR(7)) AS STATUS, CAST(A.TEMPORARY AS CHAR(1)) AS TEMPORARY, CAST(A.`GENERATED` AS CHAR(1)) AS "GENERATED", CAST(A.SECONDARY AS CHAR(1)) AS SECONDARY, CAST(A.NAMESPACE AS SIGNED) AS NAMESPACE, CAST(A.EDITION_NAME AS CHAR(128)) AS EDITION_NAME, CAST(NULL AS CHAR(18)) AS SHARING, CAST(NULL AS CHAR(1)) AS EDITIONABLE, CAST(NULL AS CHAR(1)) AS ORACLE_MAINTAINED, CAST(NULL AS CHAR(1)) AS APPLICATION, CAST(NULL AS CHAR(1)) AS DEFAULT_COLLATION, CAST(NULL AS CHAR(1)) AS DUPLICATED, CAST(NULL AS CHAR(1)) AS SHARDED, CAST(NULL AS CHAR(1)) AS IMPORTED_OBJECT, CAST(NULL AS SIGNED) AS CREATED_APPID, CAST(NULL AS SIGNED) AS CREATED_VSNID, CAST(NULL AS SIGNED) AS MODIFIED_APPID, CAST(NULL AS SIGNED) AS MODIFIED_VSNID FROM ( SELECT CAST(0 AS SIGNED) AS TENANT_ID, USEC_TO_TIME(B.SCHEMA_VERSION) AS GMT_CREATE, USEC_TO_TIME(A.SCHEMA_VERSION) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS SIGNED) AS OBJECT_ID, A.TABLET_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE A JOIN OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID AND B.TABLE_NAME = '__all_core_table' WHERE A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + POSITION('_' IN SUBSTR(TABLE_NAME, 7))) ELSE TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,CAST(TABLE_ID AS SIGNED) AS OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS CHAR(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE WHERE TENANT_ID = 0 AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.constraint_name AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(TBL.TABLE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_CONSTRAINT CST, OCEANBASE.__ALL_TABLE TBL, OCEANBASE.__ALL_DATABASE DB WHERE CST.TENANT_ID = 0 AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX PARTITION' ELSE 'TABLE PARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = 0 AND T.TENANT_ID = P.TENANT_ID UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX SUBPARTITION' ELSE 'TABLE SUBPARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE T, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = 0 AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(P.PACKAGE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_PACKAGE P WHERE P.TENANT_ID = 0 UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(R.ROUTINE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_ROUTINE R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = 0 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(TYPE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TYPE WHERE TENANT_ID = 0 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(OBJECT_TYPE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TENANT_OBJECT_TYPE WHERE TENANT_ID = 0 AND TYPE = 2 UNION ALL SELECT TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(T.TRIGGER_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TENANT_TRIGGER T WHERE T.TENANT_ID = 0 UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(DATABASE_ID AS SIGNED) AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_DATABASE WHERE TENANT_ID = 0 UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(TABLEGROUP_ID AS SIGNED) AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLEGROUP WHERE TENANT_ID = 0 UNION ALL SELECT P.TENANT_ID, P.GMT_CREATE, P.GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TG.TABLEGROUP_NAME AS OBJECT_NAME, P.PART_NAME SUBOBJECT_NAME, P.PART_ID OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP PARTITION' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, NULL AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLEGROUP TG JOIN OCEANBASE.__ALL_PART P ON TG.TABLEGROUP_ID = P.TABLE_ID WHERE TG.TENANT_ID = 0 AND TG.TENANT_ID = P.TENANT_ID UNION ALL SELECT SUBP.TENANT_ID, SUBP.GMT_CREATE, SUBP.GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TG.TABLEGROUP_NAME AS OBJECT_NAME, SUBP.SUB_PART_NAME SUBOBJECT_NAME, SUBP.SUB_PART_ID OBJECT_ID, NULL DATA_OBJECT_ID, 'TABLEGROUP SUBPARTITION' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLEGROUP TG, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART SUBP WHERE TG.TABLEGROUP_ID = P.TABLE_ID AND P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID AND TG.TENANT_ID = 0 AND TG.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID ) A JOIN OCEANBASE.__ALL_DATABASE B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = 0 )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(B.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS CHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS CHAR(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS SIGNED) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS SIGNED) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS CHAR(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATETIME) AS CREATED, CAST(A.GMT_MODIFIED AS DATETIME) AS LAST_DDL_TIME, CAST(A.GMT_CREATE AS DATETIME) AS TIMESTAMP, CAST(A.STATUS AS CHAR(7)) AS STATUS, CAST(A.TEMPORARY AS CHAR(1)) AS TEMPORARY, CAST(A.`GENERATED` AS CHAR(1)) AS "GENERATED", CAST(A.SECONDARY AS CHAR(1)) AS SECONDARY, CAST(A.NAMESPACE AS SIGNED) AS NAMESPACE, CAST(A.EDITION_NAME AS CHAR(128)) AS EDITION_NAME, CAST(NULL AS CHAR(18)) AS SHARING, CAST(NULL AS CHAR(1)) AS EDITIONABLE, CAST(NULL AS CHAR(1)) AS ORACLE_MAINTAINED, CAST(NULL AS CHAR(1)) AS APPLICATION, CAST(NULL AS CHAR(1)) AS DEFAULT_COLLATION, CAST(NULL AS CHAR(1)) AS DUPLICATED, CAST(NULL AS CHAR(1)) AS SHARDED, CAST(NULL AS CHAR(1)) AS IMPORTED_OBJECT, CAST(NULL AS SIGNED) AS CREATED_APPID, CAST(NULL AS SIGNED) AS CREATED_VSNID, CAST(NULL AS SIGNED) AS MODIFIED_APPID, CAST(NULL AS SIGNED) AS MODIFIED_VSNID FROM ( SELECT CAST(0 AS SIGNED) AS TENANT_ID, USEC_TO_TIME(B.SCHEMA_VERSION) AS GMT_CREATE, USEC_TO_TIME(A.SCHEMA_VERSION) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS SIGNED) AS OBJECT_ID, A.TABLET_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE A JOIN OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID AND B.TABLE_NAME = '__all_core_table' WHERE A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + POSITION('_' IN SUBSTR(TABLE_NAME, 7))) ELSE TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,CAST(TABLE_ID AS SIGNED) AS OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS CHAR(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE WHERE TENANT_ID = 0 AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.constraint_name AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(TBL.TABLE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_CONSTRAINT CST, OCEANBASE.__ALL_TABLE TBL, OCEANBASE.__ALL_DATABASE DB WHERE CST.TENANT_ID = 0 AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX PARTITION' ELSE 'TABLE PARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = 0 AND T.TENANT_ID = P.TENANT_ID UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX SUBPARTITION' ELSE 'TABLE SUBPARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE T, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = 0 AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(P.PACKAGE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_PACKAGE P WHERE P.TENANT_ID = 0 UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(R.ROUTINE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_ROUTINE R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = 0 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(TYPE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TYPE WHERE TENANT_ID = 0 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(OBJECT_TYPE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TENANT_OBJECT_TYPE WHERE TENANT_ID = 0 AND TYPE = 2 UNION ALL SELECT TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(T.TRIGGER_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TENANT_TRIGGER T WHERE T.TENANT_ID = 0 UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(DATABASE_ID AS SIGNED) AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_DATABASE WHERE TENANT_ID = 0 UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(TABLEGROUP_ID AS SIGNED) AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLEGROUP WHERE TENANT_ID = 0 ) A JOIN OCEANBASE.__ALL_DATABASE B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.21251_21300.cpp b/src/share/inner_table/ob_inner_table_schema.21251_21300.cpp index 433bb61ff..b7af96093 100644 --- a/src/share/inner_table/ob_inner_table_schema.21251_21300.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21251_21300.cpp @@ -660,7 +660,7 @@ int ObInnerTableSchema::dba_ob_backup_tasks_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, PATH FROM OCEANBASE.__all_virtual_backup_task WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, PATH, MINOR_TURN_ID, MAJOR_TURN_ID FROM OCEANBASE.__all_virtual_backup_task WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -710,7 +710,7 @@ int ObInnerTableSchema::dba_ob_backup_task_history_schema(ObTableSchema &table_s table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, PATH FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_TASK_HISTORY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, PATH, MINOR_TURN_ID, MAJOR_TURN_ID FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_TASK_HISTORY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -760,7 +760,7 @@ int ObInnerTableSchema::dba_ob_backup_set_files_schema(ObTableSchema &table_sche table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT BACKUP_SET_ID, DEST_ID, INCARNATION, BACKUP_TYPE, PREV_FULL_BACKUP_SET_ID, PREV_INC_BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, FILE_STATUS, CASE WHEN END_TS = 0 THEN 0 ELSE ROUND((END_TS - START_TS)/1000/1000,0) END AS ELAPSED_SECONDES, PLUS_ARCHIVELOG, START_REPLAY_SCN, CASE WHEN START_REPLAY_SCN = 0 THEN NULL ELSE SCN_TO_TIMESTAMP(START_REPLAY_SCN) END AS START_REPLAY_SCN_DISPLAY, MIN_RESTORE_SCN, CASE WHEN MIN_RESTORE_SCN = 0 THEN NULL ELSE SCN_TO_TIMESTAMP(MIN_RESTORE_SCN) END AS MIN_RESTORE_SCN_DISPLAY, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, ENCRYPTION_MODE, PASSWD, TENANT_COMPATIBLE, BACKUP_COMPATIBLE, PATH, CLUSTER_VERSION FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_SET_FILES WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT BACKUP_SET_ID, DEST_ID, INCARNATION, BACKUP_TYPE, PREV_FULL_BACKUP_SET_ID, PREV_INC_BACKUP_SET_ID, USEC_TO_TIME(START_TS) AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE USEC_TO_TIME(END_TS) END AS END_TIMESTAMP, STATUS, FILE_STATUS, CASE WHEN END_TS = 0 THEN 0 ELSE ROUND((END_TS - START_TS)/1000/1000,0) END AS ELAPSED_SECONDES, PLUS_ARCHIVELOG, START_REPLAY_SCN, CASE WHEN START_REPLAY_SCN = 0 THEN NULL ELSE SCN_TO_TIMESTAMP(START_REPLAY_SCN) END AS START_REPLAY_SCN_DISPLAY, MIN_RESTORE_SCN, CASE WHEN MIN_RESTORE_SCN = 0 THEN NULL ELSE SCN_TO_TIMESTAMP(MIN_RESTORE_SCN) END AS MIN_RESTORE_SCN_DISPLAY, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, COMMENT, ENCRYPTION_MODE, PASSWD, TENANT_COMPATIBLE, BACKUP_COMPATIBLE, PATH, CLUSTER_VERSION, CONSISTENT_SCN, MINOR_TURN_ID, MAJOR_TURN_ID FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_SET_FILES WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.21301_21350.cpp b/src/share/inner_table/ob_inner_table_schema.21301_21350.cpp index 1f78aa113..7a2a9c509 100644 --- a/src/share/inner_table/ob_inner_table_schema.21301_21350.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21301_21350.cpp @@ -767,7 +767,7 @@ int ObInnerTableSchema::dba_ob_table_locations_schema(ObTableSchema &table_schem table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE FROM ( SELECT DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 AND TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM OCEANBASE.__ALL_TABLE WHERE TABLET_ID != 0 AND PART_LEVEL = 0 AND TENANT_ID = 0 UNION ALL SELECT T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = 0 UNION ALL SELECT T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM OCEANBASE.__ALL_TABLE T, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID = Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 AND T.TENANT_ID = 0 ) A JOIN OCEANBASE.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN OCEANBASE.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID JOIN OCEANBASE.__ALL_DATABASE D ON A.DATABASE_ID = D.DATABASE_ID WHERE D.TENANT_ID = 0 ORDER BY A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE, A.OBJECT_ID, TG.TABLEGROUP_NAME, TG.TABLEGROUP_ID, TG.SHARDING FROM ( SELECT DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 AND TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE WHERE TABLET_ID != 0 AND PART_LEVEL = 0 AND TENANT_ID = 0 UNION ALL SELECT T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = 0 UNION ALL SELECT T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE T, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID = Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 AND T.TENANT_ID = 0 ) A JOIN OCEANBASE.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN OCEANBASE.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID JOIN OCEANBASE.__ALL_DATABASE D ON A.DATABASE_ID = D.DATABASE_ID LEFT JOIN OCEANBASE.__ALL_TABLEGROUP TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID WHERE D.TENANT_ID = 0 ORDER BY A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -817,7 +817,7 @@ int ObInnerTableSchema::cdb_ob_table_locations_schema(ObTableSchema &table_schem table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT A.TENANT_ID, D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLET_ID != 0 AND PART_LEVEL = 0 UNION ALL SELECT P.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = P.TENANT_ID AND T.PART_LEVEL = 1 UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID =Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 ) A JOIN OCEANBASE.CDB_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID AND A.TENANT_ID = B.TENANT_ID JOIN OCEANBASE.CDB_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID AND A.TENANT_ID = C.TENANT_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE D ON A.TENANT_ID = D.TENANT_ID AND A.DATABASE_ID = D.DATABASE_ID ORDER BY A.TENANT_ID, A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT A.TENANT_ID, D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE, A.OBJECT_ID, TG.TABLEGROUP_NAME, TG.TABLEGROUP_ID, TG.SHARDING FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLET_ID != 0 AND PART_LEVEL = 0 UNION ALL SELECT P.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = P.TENANT_ID AND T.PART_LEVEL = 1 UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID =Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 ) A JOIN OCEANBASE.CDB_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID AND A.TENANT_ID = B.TENANT_ID JOIN OCEANBASE.CDB_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID AND A.TENANT_ID = C.TENANT_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE D ON A.TENANT_ID = D.TENANT_ID AND A.DATABASE_ID = D.DATABASE_ID LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TABLEGROUP TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID AND A.TENANT_ID = TG.TENANT_ID ORDER BY A.TENANT_ID, A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.21401_21450.cpp b/src/share/inner_table/ob_inner_table_schema.21401_21450.cpp index 62d3feb56..20e55a3c1 100644 --- a/src/share/inner_table/ob_inner_table_schema.21401_21450.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21401_21450.cpp @@ -225,6 +225,606 @@ int ObInnerTableSchema::v_ob_timestamp_service_schema(ObTableSchema &table_schem return ret; } +int ObInnerTableSchema::dba_ob_balance_jobs_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_BALANCE_JOBS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_BALANCE_JOBS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT JOB_ID, GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, JOB_TYPE, TARGET_UNIT_NUM, TARGET_PRIMARY_ZONE_NUM, STATUS, COMMENT FROM OCEANBASE.__ALL_BALANCE_JOB )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::cdb_ob_balance_jobs_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_CDB_OB_BALANCE_JOBS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_CDB_OB_BALANCE_JOBS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, JOB_ID, GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, JOB_TYPE, TARGET_UNIT_NUM, TARGET_PRIMARY_ZONE_NUM, STATUS, COMMENT FROM OCEANBASE.__ALL_VIRTUAL_BALANCE_JOB )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_balance_job_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_BALANCE_JOB_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_BALANCE_JOB_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT JOB_ID, CREATE_TIME, FINISH_TIME, BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, JOB_TYPE, TARGET_UNIT_NUM, TARGET_PRIMARY_ZONE_NUM, STATUS, COMMENT FROM OCEANBASE.__ALL_BALANCE_JOB_HISTORY )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::cdb_ob_balance_job_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_CDB_OB_BALANCE_JOB_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_CDB_OB_BALANCE_JOB_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, JOB_ID, CREATE_TIME, FINISH_TIME, BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, JOB_TYPE, TARGET_UNIT_NUM, TARGET_PRIMARY_ZONE_NUM, STATUS, COMMENT FROM OCEANBASE.__ALL_VIRTUAL_BALANCE_JOB_HISTORY )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_balance_tasks_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_BALANCE_TASKS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_BALANCE_TASKS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, TASK_TYPE, SRC_LS, DEST_LS, PART_LIST, FINISHED_PART_LIST, PART_COUNT, FINISHED_PART_COUNT, LS_GROUP_ID, STATUS, PARENT_LIST, CHILD_LIST, CURRENT_TRANSFER_TASK_ID, JOB_ID, COMMENT FROM OCEANBASE.__ALL_BALANCE_TASK )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::cdb_ob_balance_tasks_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_CDB_OB_BALANCE_TASKS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_CDB_OB_BALANCE_TASKS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, TASK_ID, GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, TASK_TYPE, SRC_LS, DEST_LS, PART_LIST, FINISHED_PART_LIST, PART_COUNT, FINISHED_PART_COUNT, LS_GROUP_ID, STATUS, PARENT_LIST, CHILD_LIST, CURRENT_TRANSFER_TASK_ID, JOB_ID, COMMENT FROM OCEANBASE.__ALL_VIRTUAL_BALANCE_TASK )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_balance_task_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_BALANCE_TASK_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_BALANCE_TASK_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, CREATE_TIME, FINISH_TIME, TASK_TYPE, SRC_LS, DEST_LS, PART_LIST, FINISHED_PART_LIST, PART_COUNT, FINISHED_PART_COUNT, LS_GROUP_ID, STATUS, PARENT_LIST, CHILD_LIST, CURRENT_TRANSFER_TASK_ID, JOB_ID, COMMENT FROM OCEANBASE.__ALL_BALANCE_TASK_HISTORY )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::cdb_ob_balance_task_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_CDB_OB_BALANCE_TASK_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_CDB_OB_BALANCE_TASK_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, TASK_ID, CREATE_TIME, FINISH_TIME, TASK_TYPE, SRC_LS, DEST_LS, PART_LIST, FINISHED_PART_LIST, PART_COUNT, FINISHED_PART_COUNT, LS_GROUP_ID, STATUS, PARENT_LIST, CHILD_LIST, CURRENT_TRANSFER_TASK_ID, JOB_ID, COMMENT FROM OCEANBASE.__ALL_VIRTUAL_BALANCE_TASK_HISTORY )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_transfer_tasks_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_TRANSFER_TASKS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_TRANSFER_TASKS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, SRC_LS, DEST_LS, PART_LIST, PART_COUNT, NOT_EXIST_PART_LIST, LOCK_CONFLICT_PART_LIST, TABLE_LOCK_TABLET_LIST, TABLET_LIST, TABLET_COUNT, START_SCN, FINISH_SCN, STATUS, TRACE_ID, RESULT, BALANCE_TASK_ID, TABLE_LOCK_OWNER_ID, COMMENT FROM OCEANBASE.__ALL_TRANSFER_TASK )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::cdb_ob_transfer_tasks_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_CDB_OB_TRANSFER_TASKS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_CDB_OB_TRANSFER_TASKS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, TASK_ID, GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, SRC_LS, DEST_LS, PART_LIST, PART_COUNT, NOT_EXIST_PART_LIST, LOCK_CONFLICT_PART_LIST, TABLE_LOCK_TABLET_LIST, TABLET_LIST, TABLET_COUNT, START_SCN, FINISH_SCN, STATUS, TRACE_ID, RESULT, BALANCE_TASK_ID, TABLE_LOCK_OWNER_ID, COMMENT FROM OCEANBASE.__ALL_VIRTUAL_TRANSFER_TASK )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_transfer_task_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_TRANSFER_TASK_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_TRANSFER_TASK_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, CREATE_TIME, FINISH_TIME, SRC_LS, DEST_LS, PART_LIST, PART_COUNT, NOT_EXIST_PART_LIST, LOCK_CONFLICT_PART_LIST, TABLE_LOCK_TABLET_LIST, TABLET_LIST, TABLET_COUNT, START_SCN, FINISH_SCN, STATUS, TRACE_ID, RESULT, BALANCE_TASK_ID, TABLE_LOCK_OWNER_ID, COMMENT FROM OCEANBASE.__ALL_TRANSFER_TASK_HISTORY )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::cdb_ob_transfer_task_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_CDB_OB_TRANSFER_TASK_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_CDB_OB_TRANSFER_TASK_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TENANT_ID, TASK_ID, CREATE_TIME, FINISH_TIME, SRC_LS, DEST_LS, PART_LIST, PART_COUNT, NOT_EXIST_PART_LIST, LOCK_CONFLICT_PART_LIST, TABLE_LOCK_TABLET_LIST, TABLET_LIST, TABLET_COUNT, START_SCN, FINISH_SCN, STATUS, TRACE_ID, RESULT, BALANCE_TASK_ID, TABLE_LOCK_OWNER_ID, COMMENT FROM OCEANBASE.__ALL_VIRTUAL_TRANSFER_TASK_HISTORY )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::dba_ob_external_table_files_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.25001_25050.cpp b/src/share/inner_table/ob_inner_table_schema.25001_25050.cpp index 2d2184de3..9ebda724a 100644 --- a/src/share/inner_table/ob_inner_table_schema.25001_25050.cpp +++ b/src/share/inner_table/ob_inner_table_schema.25001_25050.cpp @@ -110,7 +110,7 @@ int ObInnerTableSchema::dba_objects_ora_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(B.DATABASE_NAME AS VARCHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, TABLEGROUP_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT P.TENANT_ID, P.GMT_CREATE, P.GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TG.TABLEGROUP_NAME AS OBJECT_NAME, P.PART_NAME SUBOBJECT_NAME, P.PART_ID OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP PARTITION' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, NULL AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON TG.TABLEGROUP_ID = P.TABLE_ID WHERE TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT SUBP.TENANT_ID, SUBP.GMT_CREATE, SUBP.GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TG.TABLEGROUP_NAME AS OBJECT_NAME, SUBP.SUB_PART_NAME SUBOBJECT_NAME, SUBP.SUB_PART_ID OBJECT_ID, NULL DATA_OBJECT_ID, 'TABLEGROUP SUBPARTITION' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'Y' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE TG.TABLEGROUP_ID = P.TABLE_ID AND P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID AND TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(B.DATABASE_NAME AS VARCHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, TABLEGROUP_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -160,7 +160,7 @@ int ObInnerTableSchema::all_objects_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(B.DATABASE_NAME AS VARCHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, CAST(A.TABLE_ID AS NUMBER) AS PRIV_OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,TABLE_ID PRIV_OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,TBL.TABLE_ID AS PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,P.TABLE_ID PRIV_OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLE_ID PRIV_OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,PACKAGE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,P.PACKAGE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,R.ROUTINE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,TS.TYPE_ID AS PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,OBJECT_TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,OBJECT_TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,T.TRIGGER_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,SEQUENCE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,SYNONYM_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() /*UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,CONTEXT_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID()*/ UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, CAST(-1 AS NUMBER) AS PRIV_OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() /*UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, TABLEGROUP_ID AS OBJECT_ID, CAST(-1 AS NUMBER) AS PRIV_OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT P.TENANT_ID, P.GMT_CREATE, P.GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TG.TABLEGROUP_NAME AS OBJECT_NAME, P.PART_NAME SUBOBJECT_NAME, P.PART_ID OBJECT_ID, CAST(-1 AS NUMBER) AS PRIV_OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP PARTITION' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, NULL AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON TG.TABLEGROUP_ID = P.TABLE_ID WHERE TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT SUBP.TENANT_ID, SUBP.GMT_CREATE, SUBP.GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TG.TABLEGROUP_NAME AS OBJECT_NAME, SUBP.SUB_PART_NAME SUBOBJECT_NAME, SUBP.SUB_PART_ID OBJECT_ID, CAST(-1 AS NUMBER) AS PRIV_OBJECT_ID, NULL DATA_OBJECT_ID, 'TABLEGROUP SUBPARTITION' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'Y' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE TG.TABLEGROUP_ID = P.TABLE_ID AND P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID AND TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID()*/ ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() AND (A.DATABASE_ID = USERENV('SCHEMAID') OR (A.PRIV_OBJECT_ID != -1 AND USER_CAN_ACCESS_OBJ(DECODE(OBJECT_TYPE, 'TABLE', 1, 'VIEW', 1, 'INDEX', 1, 'MATERIALIZED VIEW', 1, 'TABLE PARTITION', 1, 'TABLE SUBPARTITION', 1, 'INDEX PARTITION', 1, 'INDEX SUBPARTITION', 1, 'SEQUENCE', 2, 'PACKAGE', 3, 'PACKAGE BODY', 3, 'TYPE', 4, 'TYPE BODY', 4, 'TRIGGER', 7, 'FUNCTION', 9, 'PROCEDURE', 12, 'SYNONYM', 13, 1), A.PRIV_OBJECT_ID, A.DATABASE_ID) = 1)) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(B.DATABASE_NAME AS VARCHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, CAST(A.TABLE_ID AS NUMBER) AS PRIV_OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,TABLE_ID PRIV_OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,TBL.TABLE_ID AS PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,P.TABLE_ID PRIV_OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLE_ID PRIV_OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,PACKAGE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,P.PACKAGE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,R.ROUTINE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,TS.TYPE_ID AS PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,OBJECT_TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,OBJECT_TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,T.TRIGGER_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,SEQUENCE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,SYNONYM_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() /*UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,CONTEXT_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID()*/ UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, CAST(-1 AS NUMBER) AS PRIV_OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() AND (A.DATABASE_ID = USERENV('SCHEMAID') OR (A.PRIV_OBJECT_ID != -1 AND USER_CAN_ACCESS_OBJ(DECODE(OBJECT_TYPE, 'TABLE', 1, 'VIEW', 1, 'INDEX', 1, 'MATERIALIZED VIEW', 1, 'TABLE PARTITION', 1, 'TABLE SUBPARTITION', 1, 'INDEX PARTITION', 1, 'INDEX SUBPARTITION', 1, 'SEQUENCE', 2, 'PACKAGE', 3, 'PACKAGE BODY', 3, 'TYPE', 4, 'TYPE BODY', 4, 'TRIGGER', 7, 'FUNCTION', 9, 'PROCEDURE', 12, 'SYNONYM', 13, 1), A.PRIV_OBJECT_ID, A.DATABASE_ID) = 1)) )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -210,7 +210,7 @@ int ObInnerTableSchema::user_objects_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() /*UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID()*/ UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() /*UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, TABLEGROUP_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT P.TENANT_ID, P.GMT_CREATE, P.GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TG.TABLEGROUP_NAME AS OBJECT_NAME, P.PART_NAME SUBOBJECT_NAME, P.PART_ID OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP PARTITION' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, NULL AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON TG.TABLEGROUP_ID = P.TABLE_ID WHERE TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT SUBP.TENANT_ID, SUBP.GMT_CREATE, SUBP.GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TG.TABLEGROUP_NAME AS OBJECT_NAME, SUBP.SUB_PART_NAME SUBOBJECT_NAME, SUBP.SUB_PART_ID OBJECT_ID, NULL DATA_OBJECT_ID, 'TABLEGROUP SUBPARTITION' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'Y' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE TG.TABLEGROUP_ID = P.TABLE_ID AND P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID AND TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID()*/ ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() AND A.DATABASE_ID = USERENV('SCHEMAID') )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() /*UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID()*/ UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() AND A.DATABASE_ID = USERENV('SCHEMAID') )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.25151_25200.cpp b/src/share/inner_table/ob_inner_table_schema.25151_25200.cpp index 79b753664..74f6e31e7 100644 --- a/src/share/inner_table/ob_inner_table_schema.25151_25200.cpp +++ b/src/share/inner_table/ob_inner_table_schema.25151_25200.cpp @@ -710,7 +710,7 @@ int ObInnerTableSchema::dba_ob_ls_locations_ora_schema(ObTableSchema &table_sche table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(TO_CHAR(GMT_CREATE) AS VARCHAR2(19)) AS CREATE_TIME, CAST(TO_CHAR(GMT_MODIFIED) AS VARCHAR2(19)) AS MODIFY_TIME, CAST(LS_ID AS NUMBER) AS LS_ID, SVR_IP, CAST(SVR_PORT AS NUMBER) AS SVR_PORT, CAST(SQL_PORT AS NUMBER) AS SQL_PORT, ZONE, (CASE ROLE WHEN 1 THEN 'LEADER' ELSE 'FOLLOWER' END) AS ROLE, (CASE ROLE WHEN 1 THEN MEMBER_LIST ELSE NULL END) AS MEMBER_LIST, CAST((CASE ROLE WHEN 1 THEN PAXOS_REPLICA_NUMBER ELSE NULL END) AS NUMBER) AS PAXOS_REPLICA_NUMBER, (CASE REPLICA_TYPE WHEN 0 THEN 'FULL' WHEN 5 THEN 'LOGONLY' WHEN 16 THEN 'READONLY' WHEN 261 THEN 'ENCRYPTION LOGONLY' ELSE NULL END) AS REPLICA_TYPE, (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE NULL END) AS LEARNER_LIST FROM SYS.ALL_VIRTUAL_LS_META_TABLE WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(TO_CHAR(GMT_CREATE) AS VARCHAR2(19)) AS CREATE_TIME, CAST(TO_CHAR(GMT_MODIFIED) AS VARCHAR2(19)) AS MODIFY_TIME, CAST(LS_ID AS NUMBER) AS LS_ID, SVR_IP, CAST(SVR_PORT AS NUMBER) AS SVR_PORT, CAST(SQL_PORT AS NUMBER) AS SQL_PORT, ZONE, (CASE ROLE WHEN 1 THEN 'LEADER' ELSE 'FOLLOWER' END) AS ROLE, (CASE ROLE WHEN 1 THEN MEMBER_LIST ELSE NULL END) AS MEMBER_LIST, CAST((CASE ROLE WHEN 1 THEN PAXOS_REPLICA_NUMBER ELSE NULL END) AS NUMBER) AS PAXOS_REPLICA_NUMBER, (CASE REPLICA_TYPE WHEN 0 THEN 'FULL' WHEN 5 THEN 'LOGONLY' WHEN 16 THEN 'READONLY' WHEN 261 THEN 'ENCRYPTION LOGONLY' ELSE NULL END) AS REPLICA_TYPE, (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE NULL END) AS LEARNER_LIST, (CASE REBUILD WHEN 0 THEN 'FALSE' ELSE 'TRUE' END) AS REBUILD FROM SYS.ALL_VIRTUAL_LS_META_TABLE WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -860,7 +860,7 @@ int ObInnerTableSchema::dba_ob_tablegroups_ora_schema(ObTableSchema &table_schem table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TABLEGROUP_NAME, (CASE PART_LEVEL WHEN 0 THEN 'NONE' ELSE (CASE PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'UNKNOWN' ELSE 'UNKNOWN' END) END) AS PARTITIONING_TYPE, (CASE PART_LEVEL WHEN 2 THEN (CASE SUB_PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'UNKNOWN' ELSE 'UNKNOWN' END) ELSE 'NONE' END) AS SUBPARTITIONING_TYPE, CAST((CASE PART_LEVEL WHEN 0 THEN NULL ELSE PART_NUM END) AS NUMBER) AS PARTITION_COUNT, CAST(NULL AS NUMBER) AS DEF_SUBPARTITION_COUNT, CAST((CASE PART_LEVEL WHEN 0 THEN NULL ELSE PART_FUNC_EXPR_NUM END) AS NUMBER) AS PARTITIONING_KEY_COUNT, CAST((CASE PART_LEVEL WHEN 2 THEN SUB_PART_FUNC_EXPR_NUM ELSE NULL END) AS NUMBER) AS SUBPARTITIONING_KEY_COUNT FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TABLEGROUP_NAME, CAST('NONE' AS VARCHAR2(13)) AS PARTITIONING_TYPE, CAST('NONE' AS VARCHAR2(13)) AS SUBPARTITIONING_TYPE, CAST(NULL AS NUMBER) AS PARTITION_COUNT, CAST(NULL AS NUMBER) AS DEF_SUBPARTITION_COUNT, CAST(NULL AS NUMBER) AS PARTITIONING_KEY_COUNT, CAST(NULL AS NUMBER) AS SUBPARTITIONING_KEY_COUNT, SHARDING FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -910,7 +910,7 @@ int ObInnerTableSchema::dba_ob_tablegroup_partitions_ora_schema(ObTableSchema &t table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT T.TABLEGROUP_NAME AS TABLEGROUP_NAME, (CASE T.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END) AS COMPOSITE, P.PART_NAME AS PARTITION_NAME, CAST((CASE T.PART_LEVEL WHEN 2 THEN P.SUB_PART_NUM ELSE NULL END) AS NUMBER) AS SUBPARTITION_COUNT, (CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL WHEN LENGTH(P.LIST_VAL) > 0 THEN P.LIST_VAL ELSE NULL END) AS HIGH_VALUE, CAST((CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN LENGTH(P.HIGH_BOUND_VAL) WHEN LENGTH(P.LIST_VAL) > 0 THEN LENGTH(P.LIST_VAL) ELSE NULL END) AS NUMBER) AS HIGH_VALUE_LENGTH, CAST(P.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT T JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST('' AS VARCHAR(128)) AS TABLEGROUP_NAME, CAST('NO' AS VARCHAR(3)) AS COMPOSITE, CAST('' AS VARCHAR(64)) AS PARTITION_NAME, CAST(NULL AS NUMBER) AS SUBPARTITION_COUNT, CAST(NULL AS VARCHAR(4096)) AS HIGH_VALUE, CAST(NULL AS NUMBER) AS HIGH_VALUE_LENGTH, CAST(NULL AS NUMBER) AS PARTITION_POSITION FROM DUAL WHERE 0 = 1 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -960,7 +960,7 @@ int ObInnerTableSchema::dba_ob_tablegroup_subpartitions_ora_schema(ObTableSchema table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT T.TABLEGROUP_NAME AS TABLEGROUP_NAME, P.PART_NAME AS PARTITION_NAME, SP.SUB_PART_NAME AS SUBPARTITION_NAME, (CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL WHEN LENGTH(SP.LIST_VAL) > 0 THEN SP.LIST_VAL ELSE NULL END) AS HIGH_VALUE, CAST((CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN LENGTH(SP.HIGH_BOUND_VAL) WHEN LENGTH(SP.LIST_VAL) > 0 THEN LENGTH(SP.LIST_VAL) ELSE NULL END) AS NUMBER) AS HIGH_VALUE_LENGTH, CAST(P.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(SP.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT T JOIN (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID JOIN (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) SP ON P.TENANT_ID = SP.TENANT_ID AND P.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST('' AS VARCHAR(128)) AS TABLEGROUP_NAME, CAST('' AS VARCHAR(64)) AS PARTITION_NAME, CAST('' AS VARCHAR(64)) AS SUBPARTITION_NAME, CAST(NULL AS VARCHAR(4096)) AS HIGH_VALUE, CAST(NULL AS NUMBER) AS HIGH_VALUE_LENGTH, CAST(NULL AS NUMBER) AS PARTITION_POSITION, CAST(NULL AS NUMBER) AS SUBPARTITION_POSITION FROM DUAL WHERE 0 = 1 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1060,7 +1060,7 @@ int ObInnerTableSchema::dba_ob_tablegroup_tables_ora_schema(ObTableSchema &table table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TG.TABLEGROUP_NAME AS TABLEGROUP_NAME, D.DATABASE_NAME AS OWNER, T.TABLE_NAME AS TABLE_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON T.TENANT_ID = D.TENANT_ID AND T.DATABASE_ID = D.DATABASE_ID JOIN SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG ON T.TENANT_ID = TG.TENANT_ID AND T.TABLEGROUP_ID = TG.TABLEGROUP_ID WHERE T.TABLE_TYPE = 3 )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TG.TABLEGROUP_NAME AS TABLEGROUP_NAME, D.DATABASE_NAME AS OWNER, T.TABLE_NAME AS TABLE_NAME, TG.SHARDING AS SHARDING FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON T.TENANT_ID = D.TENANT_ID AND T.DATABASE_ID = D.DATABASE_ID JOIN SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG ON T.TENANT_ID = TG.TENANT_ID AND T.TABLEGROUP_ID = TG.TABLEGROUP_ID WHERE T.TABLE_TYPE in (0, 3, 6) )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1460,7 +1460,7 @@ int ObInnerTableSchema::dba_ob_backup_tasks_ora_schema(ObTableSchema &table_sche table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, TO_CHAR(START_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE TO_CHAR(END_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, "COMMENT", PATH FROM SYS.ALL_VIRTUAL_BACKUP_TASK WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, TO_CHAR(START_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE TO_CHAR(END_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, "COMMENT", PATH, MINOR_TURN_ID, MAJOR_TURN_ID FROM SYS.ALL_VIRTUAL_BACKUP_TASK WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1510,7 +1510,7 @@ int ObInnerTableSchema::dba_ob_backup_task_history_ora_schema(ObTableSchema &tab table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, TO_CHAR(START_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE TO_CHAR(END_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, "COMMENT", PATH FROM SYS.ALL_VIRTUAL_BACKUP_TASK_HISTORY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, JOB_ID, INCARNATION, BACKUP_SET_ID, TO_CHAR(START_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE TO_CHAR(END_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') END AS END_TIMESTAMP, STATUS, START_SCN, END_SCN, USER_LS_START_SCN, ENCRYPTION_MODE, PASSWD, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, "COMMENT", PATH, MINOR_TURN_ID, MAJOR_TURN_ID FROM SYS.ALL_VIRTUAL_BACKUP_TASK_HISTORY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1560,7 +1560,7 @@ int ObInnerTableSchema::dba_ob_backup_set_files_ora_schema(ObTableSchema &table_ table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT BACKUP_SET_ID, DEST_ID, INCARNATION, BACKUP_TYPE, PREV_FULL_BACKUP_SET_ID, PREV_INC_BACKUP_SET_ID, TO_CHAR(START_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE TO_CHAR(END_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') END AS END_TIMESTAMP, STATUS, FILE_STATUS, CASE WHEN END_TS = 0 THEN 0 ELSE ROUND((END_TS - START_TS)/1000/1000,0) END AS ELAPSED_SECONDES, PLUS_ARCHIVELOG, START_REPLAY_SCN, SCN_TO_TIMESTAMP(START_REPLAY_SCN) AS START_REPLAY_SCN_DISPLAY, MIN_RESTORE_SCN, SCN_TO_TIMESTAMP(MIN_RESTORE_SCN) AS MIN_RESTORE_SCN_DISPLAY, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, "COMMENT", ENCRYPTION_MODE, PASSWD, TENANT_COMPATIBLE, BACKUP_COMPATIBLE, PATH, CLUSTER_VERSION FROM SYS.ALL_VIRTUAL_BACKUP_SET_FILES WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT BACKUP_SET_ID, DEST_ID, INCARNATION, BACKUP_TYPE, PREV_FULL_BACKUP_SET_ID, PREV_INC_BACKUP_SET_ID, TO_CHAR(START_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') AS START_TIMESTAMP, CASE WHEN END_TS = 0 THEN NULL ELSE TO_CHAR(END_TS / (1000 * 60 * 60 * 24 * 1000) + TO_DATE('1970-01-01 08:00:00', 'yyyy-mm-dd hh:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') END AS END_TIMESTAMP, STATUS, FILE_STATUS, CASE WHEN END_TS = 0 THEN 0 ELSE ROUND((END_TS - START_TS)/1000/1000,0) END AS ELAPSED_SECONDES, PLUS_ARCHIVELOG, START_REPLAY_SCN, SCN_TO_TIMESTAMP(START_REPLAY_SCN) AS START_REPLAY_SCN_DISPLAY, MIN_RESTORE_SCN, SCN_TO_TIMESTAMP(MIN_RESTORE_SCN) AS MIN_RESTORE_SCN_DISPLAY, INPUT_BYTES, OUTPUT_BYTES, CASE WHEN END_TS = 0 THEN 0 ELSE OUTPUT_BYTES / ((END_TS - START_TS)/1000/1000) END AS OUTPUT_RATE_BYTES, EXTRA_BYTES AS EXTRA_META_BYTES, TABLET_COUNT, FINISH_TABLET_COUNT, MACRO_BLOCK_COUNT, FINISH_MACRO_BLOCK_COUNT, FILE_COUNT, META_TURN_ID, DATA_TURN_ID, RESULT, "COMMENT", ENCRYPTION_MODE, PASSWD, TENANT_COMPATIBLE, BACKUP_COMPATIBLE, PATH, CLUSTER_VERSION, CONSISTENT_SCN, MINOR_TURN_ID, MAJOR_TURN_ID FROM SYS.ALL_VIRTUAL_BACKUP_SET_FILES WHERE TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.25201_25250.cpp b/src/share/inner_table/ob_inner_table_schema.25201_25250.cpp index a7c7577dc..32029623f 100644 --- a/src/share/inner_table/ob_inner_table_schema.25201_25250.cpp +++ b/src/share/inner_table/ob_inner_table_schema.25201_25250.cpp @@ -360,7 +360,7 @@ int ObInnerTableSchema::dba_ob_tenants_ora_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT A.TENANT_ID, TENANT_NAME, (CASE WHEN A.TENANT_ID = 1 THEN 'SYS' WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 'META' ELSE 'USER' END) AS TENANT_TYPE, A.gmt_create AS CREATE_TIME, A.gmt_modified AS MODIFY_TIME, PRIMARY_ZONE, LOCALITY, CASE previous_locality WHEN '' THEN NULL ELSE previous_locality END AS PREVIOUS_LOCALITY, CASE compatibility_mode WHEN 0 THEN 'MYSQL' WHEN 1 THEN 'ORACLE' ELSE NULL END AS COMPATIBILITY_MODE, STATUS, CASE in_recyclebin WHEN 0 THEN 'NO' ELSE 'YES' END AS IN_RECYCLEBIN, CASE locked WHEN 0 THEN 'NO' ELSE 'YES' END AS LOCKED, (CASE WHEN A.TENANT_ID = 1 THEN 'PRIMARY' WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 'PRIMARY' ELSE TENANT_ROLE END) AS TENANT_ROLE, (CASE WHEN A.TENANT_ID = 1 THEN 'NORMAL' WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 'NORMAL' ELSE SWITCHOVER_STATUS END) AS SWITCHOVER_STATUS, (CASE WHEN A.TENANT_ID = 1 THEN 0 WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 0 ELSE SWITCHOVER_EPOCH END) AS SWITCHOVER_EPOCH, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN NULL ELSE SYNC_SCN END) AS SYNC_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN NULL ELSE REPLAYABLE_SCN END) AS REPLAYABLE_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN NULL ELSE READABLE_SCN END) AS READABLE_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN NULL ELSE RECOVERY_UNTIL_SCN END) AS RECOVERY_UNTIL_SCN, (CASE WHEN A.TENANT_ID = 1 THEN 'NOARCHIVELOG' WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 'NOARCHIVELOG' ELSE LOG_MODE END) AS LOG_MODE, ARBITRATION_SERVICE_STATUS FROM SYS.ALL_VIRTUAL_TENANT_SYS_AGENT A LEFT JOIN SYS.ALL_VIRTUAL_TENANT_INFO B ON A.TENANT_ID = B.TENANT_ID WHERE A.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT A.TENANT_ID, TENANT_NAME, (CASE WHEN A.TENANT_ID = 1 THEN 'SYS' WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 'META' ELSE 'USER' END) AS TENANT_TYPE, A.gmt_create AS CREATE_TIME, A.gmt_modified AS MODIFY_TIME, PRIMARY_ZONE, LOCALITY, CASE previous_locality WHEN '' THEN NULL ELSE previous_locality END AS PREVIOUS_LOCALITY, CASE compatibility_mode WHEN 0 THEN 'MYSQL' WHEN 1 THEN 'ORACLE' ELSE NULL END AS COMPATIBILITY_MODE, STATUS, CASE in_recyclebin WHEN 0 THEN 'NO' ELSE 'YES' END AS IN_RECYCLEBIN, CASE locked WHEN 0 THEN 'NO' ELSE 'YES' END AS LOCKED, (CASE WHEN A.TENANT_ID = 1 THEN 'PRIMARY' WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 'PRIMARY' ELSE TENANT_ROLE END) AS TENANT_ROLE, (CASE WHEN A.TENANT_ID = 1 THEN 'NORMAL' WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 'NORMAL' ELSE SWITCHOVER_STATUS END) AS SWITCHOVER_STATUS, (CASE WHEN A.TENANT_ID = 1 THEN 0 WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 0 ELSE SWITCHOVER_EPOCH END) AS SWITCHOVER_EPOCH, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN NULL ELSE SYNC_SCN END) AS SYNC_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN NULL ELSE REPLAYABLE_SCN END) AS REPLAYABLE_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN NULL ELSE READABLE_SCN END) AS READABLE_SCN, (CASE WHEN A.TENANT_ID = 1 THEN NULL WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN NULL ELSE RECOVERY_UNTIL_SCN END) AS RECOVERY_UNTIL_SCN, (CASE WHEN A.TENANT_ID = 1 THEN 'NOARCHIVELOG' WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 'NOARCHIVELOG' ELSE LOG_MODE END) AS LOG_MODE, ARBITRATION_SERVICE_STATUS, UNIT_NUM, COMPATIBLE FROM SYS.ALL_VIRTUAL_TENANT_SYS_AGENT A LEFT JOIN SYS.ALL_VIRTUAL_TENANT_INFO B ON A.TENANT_ID = B.TENANT_ID LEFT JOIN (SELECT TENANT_ID, (CASE WHEN TENANT_ID < 1 THEN NULL WHEN TENANT_ID != 1 THEN TENANT_ID - 1 ELSE NULL END) AS META_TENANT_ID, MIN(UNIT_COUNT) AS UNIT_NUM FROM SYS.ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT GROUP BY TENANT_ID) C ON A.TENANT_ID = C.TENANT_ID OR A.TENANT_ID = C.META_TENANT_ID LEFT JOIN (SELECT TENANT_ID, MIN(VALUE) AS COMPATIBLE FROM SYS.ALL_VIRTUAL_TENANT_PARAMETER WHERE NAME = 'compatible' GROUP BY TENANT_ID) D ON A.TENANT_ID = D.TENANT_ID WHERE A.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1525,6 +1525,306 @@ int ObInnerTableSchema::all_ob_external_table_files_ora_schema(ObTableSchema &ta return ret; } +int ObInnerTableSchema::dba_ob_balance_jobs_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_BALANCE_JOBS_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_BALANCE_JOBS_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT JOB_ID, GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, JOB_TYPE, TARGET_UNIT_NUM, TARGET_PRIMARY_ZONE_NUM, STATUS, "COMMENT" FROM SYS.ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_balance_job_history_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_BALANCE_JOB_HISTORY_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_BALANCE_JOB_HISTORY_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT JOB_ID, CREATE_TIME, FINISH_TIME, BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, JOB_TYPE, TARGET_UNIT_NUM, TARGET_PRIMARY_ZONE_NUM, STATUS, "COMMENT" FROM SYS.ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_balance_tasks_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_BALANCE_TASKS_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_BALANCE_TASKS_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, TASK_TYPE, SRC_LS, DEST_LS, PART_LIST, FINISHED_PART_LIST, PART_COUNT, FINISHED_PART_COUNT, LS_GROUP_ID, STATUS, PARENT_LIST, CHILD_LIST, CURRENT_TRANSFER_TASK_ID, JOB_ID, "COMMENT" FROM SYS.ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_balance_task_history_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_BALANCE_TASK_HISTORY_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_BALANCE_TASK_HISTORY_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, CREATE_TIME, FINISH_TIME, TASK_TYPE, SRC_LS, DEST_LS, PART_LIST, FINISHED_PART_LIST, PART_COUNT, FINISHED_PART_COUNT, LS_GROUP_ID, STATUS, PARENT_LIST, CHILD_LIST, CURRENT_TRANSFER_TASK_ID, JOB_ID, "COMMENT" FROM SYS.ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_transfer_tasks_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_TRANSFER_TASKS_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_TRANSFER_TASKS_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, GMT_CREATE AS CREATE_TIME, GMT_MODIFIED AS MODIFY_TIME, SRC_LS, DEST_LS, PART_LIST, PART_COUNT, NOT_EXIST_PART_LIST, LOCK_CONFLICT_PART_LIST, TABLE_LOCK_TABLET_LIST, TABLET_LIST, TABLET_COUNT, START_SCN, FINISH_SCN, STATUS, TRACE_ID, RESULT, BALANCE_TASK_ID, TABLE_LOCK_OWNER_ID, "COMMENT" FROM SYS.ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_transfer_task_history_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_TRANSFER_TASK_HISTORY_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_TRANSFER_TASK_HISTORY_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT TASK_ID, CREATE_TIME, FINISH_TIME, SRC_LS, DEST_LS, PART_LIST, PART_COUNT, NOT_EXIST_PART_LIST, LOCK_CONFLICT_PART_LIST, TABLE_LOCK_TABLET_LIST, TABLET_LIST, TABLET_COUNT, START_SCN, FINISH_SCN, STATUS, TRACE_ID, RESULT, BALANCE_TASK_ID, TABLE_LOCK_OWNER_ID, "COMMENT" FROM SYS.ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::gv_ob_px_p2p_datahub_ora_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.28151_28200.cpp b/src/share/inner_table/ob_inner_table_schema.28151_28200.cpp index 2e1a84523..034465ccc 100644 --- a/src/share/inner_table/ob_inner_table_schema.28151_28200.cpp +++ b/src/share/inner_table/ob_inner_table_schema.28151_28200.cpp @@ -160,7 +160,7 @@ int ObInnerTableSchema::dba_ob_table_locations_ora_schema(ObTableSchema &table_s table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 AND TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLET_ID != 0 AND T.PART_LEVEL = 0 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT Q JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON P.PART_ID =Q.PART_ID AND Q.TENANT_ID = P.TENANT_ID JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID =P.TABLE_ID AND T.TENANT_ID = Q.TENANT_ID WHERE T.PART_LEVEL = 2 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN SYS.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON A.DATABASE_ID = D.DATABASE_ID AND A.TENANT_ID = D.TENANT_ID ORDER BY A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE, A.OBJECT_ID, TG.TABLEGROUP_NAME, TG.TABLEGROUP_ID, TG.SHARDING FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 AND TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLET_ID != 0 AND T.PART_LEVEL = 0 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT Q JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON P.PART_ID =Q.PART_ID AND Q.TENANT_ID = P.TENANT_ID JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID =P.TABLE_ID AND T.TENANT_ID = Q.TENANT_ID WHERE T.PART_LEVEL = 2 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN SYS.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON A.DATABASE_ID = D.DATABASE_ID AND A.TENANT_ID = D.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID ORDER BY A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.301_350.cpp b/src/share/inner_table/ob_inner_table_schema.301_350.cpp index 6f931b49d..7822f0356 100644 --- a/src/share/inner_table/ob_inner_table_schema.301_350.cpp +++ b/src/share/inner_table/ob_inner_table_schema.301_350.cpp @@ -1668,6 +1668,63 @@ int ObInnerTableSchema::all_backup_set_files_schema(ObTableSchema &table_schema) cluster_version_default, cluster_version_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj consistent_scn_default; + consistent_scn_default.set_uint64(0); + ADD_COLUMN_SCHEMA_T("consistent_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + consistent_scn_default, + consistent_scn_default); //default_value + } + + if (OB_SUCC(ret)) { + ObObj minor_turn_id_default; + minor_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("minor_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + minor_turn_id_default, + minor_turn_id_default); //default_value + } + + if (OB_SUCC(ret)) { + ObObj major_turn_id_default; + major_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("major_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + major_turn_id_default, + major_turn_id_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -7695,6 +7752,25 @@ int ObInnerTableSchema::all_ls_meta_table_schema(ObTableSchema &table_schema) true, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ObObj rebuild_default; + rebuild_default.set_int(0); + ADD_COLUMN_SCHEMA_T("rebuild", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + rebuild_default, + rebuild_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -7832,6 +7908,25 @@ int ObInnerTableSchema::all_tablet_to_ls_schema(ObTableSchema &table_schema) false, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ObObj transfer_seq_default; + transfer_seq_default.set_int(0); + ADD_COLUMN_SCHEMA_T("transfer_seq", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + transfer_seq_default, + transfer_seq_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema.351_400.cpp b/src/share/inner_table/ob_inner_table_schema.351_400.cpp index af864ce92..c5f4f33e5 100644 --- a/src/share/inner_table/ob_inner_table_schema.351_400.cpp +++ b/src/share/inner_table/ob_inner_table_schema.351_400.cpp @@ -3033,6 +3033,44 @@ int ObInnerTableSchema::all_backup_task_schema(ObTableSchema &table_schema) path_default, path_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj minor_turn_id_default; + minor_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("minor_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + minor_turn_id_default, + minor_turn_id_default); //default_value + } + + if (OB_SUCC(ret)) { + ObObj major_turn_id_default; + major_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("major_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + major_turn_id_default, + major_turn_id_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -3575,6 +3613,44 @@ int ObInnerTableSchema::all_backup_task_history_schema(ObTableSchema &table_sche path_default, path_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj minor_turn_id_default; + minor_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("minor_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + minor_turn_id_default, + minor_turn_id_default); //default_value + } + + if (OB_SUCC(ret)) { + ObObj major_turn_id_default; + major_turn_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("major_turn_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + major_turn_id_default, + major_turn_id_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -4147,6 +4223,21 @@ int ObInnerTableSchema::all_backup_ls_task_schema(ObTableSchema &table_schema) comment_default, comment_default); //default_value } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("max_tablet_checkpoint_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -4719,6 +4810,21 @@ int ObInnerTableSchema::all_backup_ls_task_history_schema(ObTableSchema &table_s comment_default, comment_default); //default_value } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("max_tablet_checkpoint_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); @@ -5775,6 +5881,25 @@ int ObInnerTableSchema::all_tenant_info_schema(ObTableSchema &table_schema) log_mode_default, log_mode_default); //default_value } + + if (OB_SUCC(ret)) { + ObObj max_ls_id_default; + max_ls_id_default.set_int(0); + ADD_COLUMN_SCHEMA_T("max_ls_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + max_ls_id_default, + max_ls_id_default); //default_value + } table_schema.set_index_using_type(USING_BTREE); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema.401_450.cpp b/src/share/inner_table/ob_inner_table_schema.401_450.cpp index 9783f1e94..a3bf61f1c 100644 --- a/src/share/inner_table/ob_inner_table_schema.401_450.cpp +++ b/src/share/inner_table/ob_inner_table_schema.401_450.cpp @@ -2857,6 +2857,1854 @@ int ObInnerTableSchema::all_column_checksum_error_info_schema(ObTableSchema &tab return ret; } +int ObInnerTableSchema::all_transfer_task_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TRANSFER_TASK_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TRANSFER_TASK_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("src_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("dest_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("not_exist_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lock_conflict_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("table_lock_tablet_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("start_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finish_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("result", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("balance_task_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("table_lock_owner_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TRANSFER_TASK_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_TRANSFER_TASK_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_TRANSFER_TASK_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_transfer_task_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TRANSFER_TASK_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TRANSFER_TASK_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("src_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("dest_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("not_exist_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lock_conflict_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("table_lock_tablet_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tablet_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("start_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finish_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("result", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("balance_task_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("table_lock_owner_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("create_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("finish_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TRANSFER_TASK_HISTORY_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_job_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_JOB_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_JOB_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("balance_strategy_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("target_unit_num", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("target_primary_zone_num", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_JOB_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_BALANCE_JOB_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_BALANCE_JOB_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_job_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_JOB_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_JOB_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("balance_strategy_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("target_unit_num", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("target_primary_zone_num", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("create_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("finish_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_JOB_HISTORY_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_task_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_TASK_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_TASK_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("src_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("dest_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finished_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finished_part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_group_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("parent_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("child_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("current_transfer_task_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_TASK_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_BALANCE_TASK_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_BALANCE_TASK_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_task_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_TASK_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_TASK_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("src_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("dest_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finished_part_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("finished_part_count", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_group_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("parent_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("child_list", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_SYS_PARAM_VALUE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("current_transfer_task_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("create_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("finish_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_TASK_HISTORY_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_arbitration_service_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -6351,6 +8199,188 @@ int ObInnerTableSchema::all_cluster_event_history_schema(ObTableSchema &table_sc return ret; } +int ObInnerTableSchema::all_ls_transfer_member_list_lock_info_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("task_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_INNER_TABLE_DEFAULT_VALUE_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lock_owner", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("comment", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.451_500.cpp b/src/share/inner_table/ob_inner_table_schema.451_500.cpp index 9f48250d0..bbcb5d93b 100644 --- a/src/share/inner_table/ob_inner_table_schema.451_500.cpp +++ b/src/share/inner_table/ob_inner_table_schema.451_500.cpp @@ -739,6 +739,177 @@ int ObInnerTableSchema::all_table_opt_stat_gather_history_schema(ObTableSchema & return ret; } +int ObInnerTableSchema::all_balance_task_helper_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_TASK_HELPER_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_TASK_HELPER_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("operation_scn", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ObObj operation_type_default; + operation_type_default.set_varchar(ObString::make_string("")); + ADD_COLUMN_SCHEMA_T("operation_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + operation_type_default, + operation_type_default); //default_value + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("src_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("dest_ls", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_group_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_TASK_HELPER_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.50401_50450.cpp b/src/share/inner_table/ob_inner_table_schema.50401_50450.cpp index 950006f5d..8537cde20 100644 --- a/src/share/inner_table/ob_inner_table_schema.50401_50450.cpp +++ b/src/share/inner_table/ob_inner_table_schema.50401_50450.cpp @@ -1780,6 +1780,816 @@ int ObInnerTableSchema::all_column_checksum_error_info_aux_lob_meta_schema(ObTab return ret; } +int ObInnerTableSchema::all_transfer_task_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TRANSFER_TASK_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TRANSFER_TASK_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TRANSFER_TASK_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_TRANSFER_TASK_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_transfer_task_history_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_TRANSFER_TASK_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_job_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_JOB_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_JOB_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_JOB_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_BALANCE_JOB_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_job_history_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_BALANCE_JOB_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_task_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_TASK_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_TASK_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_TASK_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_BALANCE_TASK_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_task_history_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_BALANCE_TASK_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_arbitration_service_aux_lob_meta_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -4075,6 +4885,141 @@ int ObInnerTableSchema::all_cluster_event_history_aux_lob_meta_schema(ObTableSch return ret; } +int ObInnerTableSchema::all_ls_transfer_member_list_lock_info_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.50451_50500.cpp b/src/share/inner_table/ob_inner_table_schema.50451_50500.cpp index cc9d2e768..239e2d169 100644 --- a/src/share/inner_table/ob_inner_table_schema.50451_50500.cpp +++ b/src/share/inner_table/ob_inner_table_schema.50451_50500.cpp @@ -430,6 +430,141 @@ int ObInnerTableSchema::all_table_opt_stat_gather_history_aux_lob_meta_schema(Ob return ret; } +int ObInnerTableSchema::all_balance_task_helper_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_BALANCE_TASK_HELPER_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.60401_60450.cpp b/src/share/inner_table/ob_inner_table_schema.60401_60450.cpp index 871b15618..94175669c 100644 --- a/src/share/inner_table/ob_inner_table_schema.60401_60450.cpp +++ b/src/share/inner_table/ob_inner_table_schema.60401_60450.cpp @@ -1195,6 +1195,546 @@ int ObInnerTableSchema::all_column_checksum_error_info_aux_lob_piece_schema(ObTa return ret; } +int ObInnerTableSchema::all_transfer_task_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TRANSFER_TASK_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TRANSFER_TASK_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TRANSFER_TASK_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_TRANSFER_TASK_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_transfer_task_history_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_TRANSFER_TASK_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_job_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_JOB_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_JOB_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_JOB_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_BALANCE_JOB_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_job_history_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_BALANCE_JOB_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_task_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_TASK_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_TASK_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_TASK_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_BALANCE_TASK_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_balance_task_history_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_BALANCE_TASK_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_arbitration_service_aux_lob_piece_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -2725,6 +3265,96 @@ int ObInnerTableSchema::all_cluster_event_history_aux_lob_piece_schema(ObTableSc return ret; } +int ObInnerTableSchema::all_ls_transfer_member_list_lock_info_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.60451_60500.cpp b/src/share/inner_table/ob_inner_table_schema.60451_60500.cpp index b4a2ab554..d851efcf4 100644 --- a/src/share/inner_table/ob_inner_table_schema.60451_60500.cpp +++ b/src/share/inner_table/ob_inner_table_schema.60451_60500.cpp @@ -295,6 +295,96 @@ int ObInnerTableSchema::all_table_opt_stat_gather_history_aux_lob_piece_schema(O return ret; } +int ObInnerTableSchema::all_balance_task_helper_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_BALANCE_TASK_HELPER_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.h b/src/share/inner_table/ob_inner_table_schema.h index 5e49edcef..adaf22d4c 100644 --- a/src/share/inner_table/ob_inner_table_schema.h +++ b/src/share/inner_table/ob_inner_table_schema.h @@ -502,6 +502,12 @@ public: static int all_service_epoch_schema(share::schema::ObTableSchema &table_schema); static int all_spatial_reference_systems_schema(share::schema::ObTableSchema &table_schema); static int all_column_checksum_error_info_schema(share::schema::ObTableSchema &table_schema); + static int all_transfer_task_schema(share::schema::ObTableSchema &table_schema); + static int all_transfer_task_history_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_job_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_job_history_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_task_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_task_history_schema(share::schema::ObTableSchema &table_schema); static int all_arbitration_service_schema(share::schema::ObTableSchema &table_schema); static int all_ls_arb_replica_task_schema(share::schema::ObTableSchema &table_schema); static int all_data_dictionary_in_log_schema(share::schema::ObTableSchema &table_schema); @@ -519,9 +525,11 @@ public: static int all_tenant_rewrite_rules_schema(share::schema::ObTableSchema &table_schema); static int all_reserved_snapshot_schema(share::schema::ObTableSchema &table_schema); static int all_cluster_event_history_schema(share::schema::ObTableSchema &table_schema); + static int all_ls_transfer_member_list_lock_info_schema(share::schema::ObTableSchema &table_schema); static int all_external_table_file_schema(share::schema::ObTableSchema &table_schema); static int all_task_opt_stat_gather_history_schema(share::schema::ObTableSchema &table_schema); static int all_table_opt_stat_gather_history_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_task_helper_schema(share::schema::ObTableSchema &table_schema); static int tenant_virtual_all_table_schema(share::schema::ObTableSchema &table_schema); static int tenant_virtual_table_column_schema(share::schema::ObTableSchema &table_schema); static int tenant_virtual_table_index_schema(share::schema::ObTableSchema &table_schema); @@ -856,6 +864,12 @@ public: static int all_virtual_show_trace_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_ha_diagnose_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_data_dictionary_in_log_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_transfer_task_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_transfer_task_history_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_balance_job_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_balance_job_history_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_balance_task_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_balance_task_history_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_rls_policy_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_rls_policy_history_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_rls_security_column_schema(share::schema::ObTableSchema &table_schema); @@ -875,6 +889,8 @@ public: static int all_virtual_archive_dest_status_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_io_scheduler_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_external_table_file_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_mds_node_stat_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_mds_event_history_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_dup_ls_lease_mgr_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_dup_ls_tablet_set_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_dup_ls_tablets_schema(share::schema::ObTableSchema &table_schema); @@ -886,9 +902,13 @@ public: static int all_virtual_arbitration_member_info_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_arbitration_service_status_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_virtual_long_ops_status_mysql_sys_agent_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_ls_transfer_member_list_lock_info_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_timestamp_service_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_resource_pool_mysql_sys_agent_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_px_p2p_datahub_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_ls_log_restore_status_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_tenant_parameter_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_tablet_buffer_info_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_sql_audit_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_plan_stat_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_plan_cache_plan_explain_ora_schema(share::schema::ObTableSchema &table_schema); @@ -1108,9 +1128,17 @@ public: static int all_virtual_arbitration_service_status_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_obj_lock_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_log_restore_source_ora_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_balance_job_real_agent_ora_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_balance_job_history_real_agent_ora_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_balance_task_real_agent_ora_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_balance_task_history_real_agent_ora_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_transfer_task_real_agent_ora_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_transfer_task_history_real_agent_ora_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_resource_pool_sys_agent_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_px_p2p_datahub_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_timestamp_service_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_ls_log_restore_status_ora_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_tenant_parameter_ora_schema(share::schema::ObTableSchema &table_schema); static int gv_ob_plan_cache_stat_schema(share::schema::ObTableSchema &table_schema); static int gv_ob_plan_cache_plan_stat_schema(share::schema::ObTableSchema &table_schema); static int schemata_schema(share::schema::ObTableSchema &table_schema); @@ -1419,6 +1447,18 @@ public: static int cdb_ob_log_restore_source_schema(share::schema::ObTableSchema &table_schema); static int dba_ob_log_restore_source_schema(share::schema::ObTableSchema &table_schema); static int v_ob_timestamp_service_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_balance_jobs_schema(share::schema::ObTableSchema &table_schema); + static int cdb_ob_balance_jobs_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_balance_job_history_schema(share::schema::ObTableSchema &table_schema); + static int cdb_ob_balance_job_history_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_balance_tasks_schema(share::schema::ObTableSchema &table_schema); + static int cdb_ob_balance_tasks_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_balance_task_history_schema(share::schema::ObTableSchema &table_schema); + static int cdb_ob_balance_task_history_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_transfer_tasks_schema(share::schema::ObTableSchema &table_schema); + static int cdb_ob_transfer_tasks_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_transfer_task_history_schema(share::schema::ObTableSchema &table_schema); + static int cdb_ob_transfer_task_history_schema(share::schema::ObTableSchema &table_schema); static int dba_ob_external_table_files_schema(share::schema::ObTableSchema &table_schema); static int all_ob_external_table_files_schema(share::schema::ObTableSchema &table_schema); static int gv_ob_px_p2p_datahub_schema(share::schema::ObTableSchema &table_schema); @@ -1656,6 +1696,12 @@ public: static int dba_ob_log_restore_source_ora_schema(share::schema::ObTableSchema &table_schema); static int dba_ob_external_table_files_ora_schema(share::schema::ObTableSchema &table_schema); static int all_ob_external_table_files_ora_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_balance_jobs_ora_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_balance_job_history_ora_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_balance_tasks_ora_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_balance_task_history_ora_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_transfer_tasks_ora_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_transfer_task_history_ora_schema(share::schema::ObTableSchema &table_schema); static int gv_ob_px_p2p_datahub_ora_schema(share::schema::ObTableSchema &table_schema); static int v_ob_px_p2p_datahub_ora_schema(share::schema::ObTableSchema &table_schema); static int gv_sql_join_filter_ora_schema(share::schema::ObTableSchema &table_schema); @@ -2043,6 +2089,12 @@ public: static int all_service_epoch_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_spatial_reference_systems_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_column_checksum_error_info_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_transfer_task_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_transfer_task_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_job_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_job_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_task_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_task_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_arbitration_service_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_ls_arb_replica_task_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_data_dictionary_in_log_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); @@ -2060,9 +2112,11 @@ public: static int all_tenant_rewrite_rules_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_reserved_snapshot_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_cluster_event_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_ls_transfer_member_list_lock_info_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_external_table_file_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_task_opt_stat_gather_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_table_opt_stat_gather_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_task_helper_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_table_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_column_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_ddl_operation_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); @@ -2279,6 +2333,12 @@ public: static int all_service_epoch_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_spatial_reference_systems_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_column_checksum_error_info_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_transfer_task_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_transfer_task_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_job_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_job_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_task_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_task_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_arbitration_service_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_ls_arb_replica_task_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_data_dictionary_in_log_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); @@ -2296,9 +2356,11 @@ public: static int all_tenant_rewrite_rules_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_reserved_snapshot_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_cluster_event_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_ls_transfer_member_list_lock_info_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_external_table_file_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_task_opt_stat_gather_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_table_opt_stat_gather_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_balance_task_helper_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_sql_plan_monitor_all_virtual_sql_plan_monitor_i1_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_sql_audit_all_virtual_sql_audit_i1_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_sysstat_all_virtual_sysstat_i1_schema(share::schema::ObTableSchema &table_schema); @@ -2711,6 +2773,12 @@ const schema_create_func sys_table_schema_creators [] = { ObInnerTableSchema::all_service_epoch_schema, ObInnerTableSchema::all_spatial_reference_systems_schema, ObInnerTableSchema::all_column_checksum_error_info_schema, + ObInnerTableSchema::all_transfer_task_schema, + ObInnerTableSchema::all_transfer_task_history_schema, + ObInnerTableSchema::all_balance_job_schema, + ObInnerTableSchema::all_balance_job_history_schema, + ObInnerTableSchema::all_balance_task_schema, + ObInnerTableSchema::all_balance_task_history_schema, ObInnerTableSchema::all_arbitration_service_schema, ObInnerTableSchema::all_ls_arb_replica_task_schema, ObInnerTableSchema::all_data_dictionary_in_log_schema, @@ -2728,9 +2796,11 @@ const schema_create_func sys_table_schema_creators [] = { ObInnerTableSchema::all_tenant_rewrite_rules_schema, ObInnerTableSchema::all_reserved_snapshot_schema, ObInnerTableSchema::all_cluster_event_history_schema, + ObInnerTableSchema::all_ls_transfer_member_list_lock_info_schema, ObInnerTableSchema::all_external_table_file_schema, ObInnerTableSchema::all_task_opt_stat_gather_history_schema, ObInnerTableSchema::all_table_opt_stat_gather_history_schema, + ObInnerTableSchema::all_balance_task_helper_schema, NULL,}; const schema_create_func virtual_table_schema_creators [] = { @@ -3068,6 +3138,12 @@ const schema_create_func virtual_table_schema_creators [] = { ObInnerTableSchema::all_virtual_show_trace_schema, ObInnerTableSchema::all_virtual_ha_diagnose_schema, ObInnerTableSchema::all_virtual_data_dictionary_in_log_schema, + ObInnerTableSchema::all_virtual_transfer_task_schema, + ObInnerTableSchema::all_virtual_transfer_task_history_schema, + ObInnerTableSchema::all_virtual_balance_job_schema, + ObInnerTableSchema::all_virtual_balance_job_history_schema, + ObInnerTableSchema::all_virtual_balance_task_schema, + ObInnerTableSchema::all_virtual_balance_task_history_schema, ObInnerTableSchema::all_virtual_rls_policy_schema, ObInnerTableSchema::all_virtual_rls_policy_history_schema, ObInnerTableSchema::all_virtual_rls_security_column_schema, @@ -3087,6 +3163,8 @@ const schema_create_func virtual_table_schema_creators [] = { ObInnerTableSchema::all_virtual_archive_dest_status_schema, ObInnerTableSchema::all_virtual_io_scheduler_schema, ObInnerTableSchema::all_virtual_external_table_file_schema, + ObInnerTableSchema::all_virtual_mds_node_stat_schema, + ObInnerTableSchema::all_virtual_mds_event_history_schema, ObInnerTableSchema::all_virtual_dup_ls_lease_mgr_schema, ObInnerTableSchema::all_virtual_dup_ls_tablet_set_schema, ObInnerTableSchema::all_virtual_dup_ls_tablets_schema, @@ -3098,9 +3176,13 @@ const schema_create_func virtual_table_schema_creators [] = { ObInnerTableSchema::all_virtual_arbitration_member_info_schema, ObInnerTableSchema::all_virtual_arbitration_service_status_schema, ObInnerTableSchema::all_virtual_virtual_long_ops_status_mysql_sys_agent_schema, + ObInnerTableSchema::all_virtual_ls_transfer_member_list_lock_info_schema, ObInnerTableSchema::all_virtual_timestamp_service_schema, + ObInnerTableSchema::all_virtual_resource_pool_mysql_sys_agent_schema, ObInnerTableSchema::all_virtual_px_p2p_datahub_schema, ObInnerTableSchema::all_virtual_ls_log_restore_status_schema, + ObInnerTableSchema::all_virtual_tenant_parameter_schema, + ObInnerTableSchema::all_virtual_tablet_buffer_info_schema, ObInnerTableSchema::all_virtual_sql_plan_monitor_all_virtual_sql_plan_monitor_i1_schema, ObInnerTableSchema::all_virtual_sql_audit_all_virtual_sql_audit_i1_schema, ObInnerTableSchema::all_virtual_sysstat_all_virtual_sysstat_i1_schema, @@ -3329,9 +3411,17 @@ const schema_create_func virtual_table_schema_creators [] = { ObInnerTableSchema::all_virtual_arbitration_service_status_ora_schema, ObInnerTableSchema::all_virtual_obj_lock_ora_schema, ObInnerTableSchema::all_virtual_log_restore_source_ora_schema, + ObInnerTableSchema::all_virtual_balance_job_real_agent_ora_schema, + ObInnerTableSchema::all_virtual_balance_job_history_real_agent_ora_schema, + ObInnerTableSchema::all_virtual_balance_task_real_agent_ora_schema, + ObInnerTableSchema::all_virtual_balance_task_history_real_agent_ora_schema, + ObInnerTableSchema::all_virtual_transfer_task_real_agent_ora_schema, + ObInnerTableSchema::all_virtual_transfer_task_history_real_agent_ora_schema, + ObInnerTableSchema::all_virtual_resource_pool_sys_agent_schema, ObInnerTableSchema::all_virtual_px_p2p_datahub_ora_schema, ObInnerTableSchema::all_virtual_timestamp_service_ora_schema, ObInnerTableSchema::all_virtual_ls_log_restore_status_ora_schema, + ObInnerTableSchema::all_virtual_tenant_parameter_ora_schema, ObInnerTableSchema::all_virtual_table_real_agent_ora_idx_data_table_id_real_agent_schema, ObInnerTableSchema::all_virtual_table_real_agent_ora_idx_db_tb_name_real_agent_schema, ObInnerTableSchema::all_virtual_table_real_agent_ora_idx_tb_name_real_agent_schema, @@ -3721,6 +3811,18 @@ const schema_create_func sys_view_schema_creators [] = { ObInnerTableSchema::cdb_ob_log_restore_source_schema, ObInnerTableSchema::dba_ob_log_restore_source_schema, ObInnerTableSchema::v_ob_timestamp_service_schema, + ObInnerTableSchema::dba_ob_balance_jobs_schema, + ObInnerTableSchema::cdb_ob_balance_jobs_schema, + ObInnerTableSchema::dba_ob_balance_job_history_schema, + ObInnerTableSchema::cdb_ob_balance_job_history_schema, + ObInnerTableSchema::dba_ob_balance_tasks_schema, + ObInnerTableSchema::cdb_ob_balance_tasks_schema, + ObInnerTableSchema::dba_ob_balance_task_history_schema, + ObInnerTableSchema::cdb_ob_balance_task_history_schema, + ObInnerTableSchema::dba_ob_transfer_tasks_schema, + ObInnerTableSchema::cdb_ob_transfer_tasks_schema, + ObInnerTableSchema::dba_ob_transfer_task_history_schema, + ObInnerTableSchema::cdb_ob_transfer_task_history_schema, ObInnerTableSchema::dba_ob_external_table_files_schema, ObInnerTableSchema::all_ob_external_table_files_schema, ObInnerTableSchema::gv_ob_px_p2p_datahub_schema, @@ -3958,6 +4060,12 @@ const schema_create_func sys_view_schema_creators [] = { ObInnerTableSchema::dba_ob_log_restore_source_ora_schema, ObInnerTableSchema::dba_ob_external_table_files_ora_schema, ObInnerTableSchema::all_ob_external_table_files_ora_schema, + ObInnerTableSchema::dba_ob_balance_jobs_ora_schema, + ObInnerTableSchema::dba_ob_balance_job_history_ora_schema, + ObInnerTableSchema::dba_ob_balance_tasks_ora_schema, + ObInnerTableSchema::dba_ob_balance_task_history_ora_schema, + ObInnerTableSchema::dba_ob_transfer_tasks_ora_schema, + ObInnerTableSchema::dba_ob_transfer_task_history_ora_schema, ObInnerTableSchema::gv_ob_px_p2p_datahub_ora_schema, ObInnerTableSchema::v_ob_px_p2p_datahub_ora_schema, ObInnerTableSchema::gv_sql_join_filter_ora_schema, @@ -4436,6 +4544,12 @@ const uint64_t tenant_space_tables [] = { OB_ALL_SERVICE_EPOCH_TID, OB_ALL_SPATIAL_REFERENCE_SYSTEMS_TID, OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_TID, + OB_ALL_TRANSFER_TASK_TID, + OB_ALL_TRANSFER_TASK_HISTORY_TID, + OB_ALL_BALANCE_JOB_TID, + OB_ALL_BALANCE_JOB_HISTORY_TID, + OB_ALL_BALANCE_TASK_TID, + OB_ALL_BALANCE_TASK_HISTORY_TID, OB_ALL_LS_ARB_REPLICA_TASK_TID, OB_ALL_DATA_DICTIONARY_IN_LOG_TID, OB_ALL_LS_ARB_REPLICA_TASK_HISTORY_TID, @@ -4451,9 +4565,11 @@ const uint64_t tenant_space_tables [] = { OB_ALL_RLS_ATTRIBUTE_HISTORY_TID, OB_ALL_TENANT_REWRITE_RULES_TID, OB_ALL_RESERVED_SNAPSHOT_TID, + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID, OB_ALL_EXTERNAL_TABLE_FILE_TID, OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_TID, OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_TID, + OB_ALL_BALANCE_TASK_HELPER_TID, OB_TENANT_VIRTUAL_ALL_TABLE_TID, OB_TENANT_VIRTUAL_TABLE_COLUMN_TID, OB_TENANT_VIRTUAL_TABLE_INDEX_TID, @@ -4615,6 +4731,8 @@ const uint64_t tenant_space_tables [] = { OB_ALL_VIRTUAL_LS_ARB_REPLICA_TASK_TID, OB_ALL_VIRTUAL_LS_ARB_REPLICA_TASK_HISTORY_TID, OB_ALL_VIRTUAL_ARCHIVE_DEST_STATUS_TID, + OB_ALL_VIRTUAL_MDS_NODE_STAT_TID, + OB_ALL_VIRTUAL_MDS_EVENT_HISTORY_TID, OB_ALL_VIRTUAL_DUP_LS_LEASE_MGR_TID, OB_ALL_VIRTUAL_DUP_LS_TABLET_SET_TID, OB_ALL_VIRTUAL_DUP_LS_TABLETS_TID, @@ -4625,9 +4743,12 @@ const uint64_t tenant_space_tables [] = { OB_ALL_VIRTUAL_ARBITRATION_MEMBER_INFO_TID, OB_ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS_TID, OB_ALL_VIRTUAL_VIRTUAL_LONG_OPS_STATUS_MYSQL_SYS_AGENT_TID, + OB_ALL_VIRTUAL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID, OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_TID, + OB_ALL_VIRTUAL_RESOURCE_POOL_MYSQL_SYS_AGENT_TID, OB_ALL_VIRTUAL_PX_P2P_DATAHUB_TID, OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TID, + OB_ALL_VIRTUAL_TENANT_PARAMETER_TID, OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TID, OB_ALL_VIRTUAL_SQL_AUDIT_ORA_ALL_VIRTUAL_SQL_AUDIT_I1_TID, OB_ALL_VIRTUAL_PLAN_STAT_ORA_TID, @@ -4855,9 +4976,17 @@ const uint64_t tenant_space_tables [] = { OB_ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS_ORA_TID, OB_ALL_VIRTUAL_OBJ_LOCK_ORA_TID, OB_ALL_VIRTUAL_LOG_RESTORE_SOURCE_ORA_TID, + OB_ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT_TID, OB_ALL_VIRTUAL_PX_P2P_DATAHUB_ORA_TID, OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_ORA_TID, OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_ORA_TID, + OB_ALL_VIRTUAL_TENANT_PARAMETER_ORA_TID, OB_GV_OB_PLAN_CACHE_STAT_TID, OB_GV_OB_PLAN_CACHE_PLAN_STAT_TID, OB_SCHEMATA_TID, @@ -5086,6 +5215,12 @@ const uint64_t tenant_space_tables [] = { OB_V_OB_LOCKS_TID, OB_DBA_OB_LOG_RESTORE_SOURCE_TID, OB_V_OB_TIMESTAMP_SERVICE_TID, + OB_DBA_OB_BALANCE_JOBS_TID, + OB_DBA_OB_BALANCE_JOB_HISTORY_TID, + OB_DBA_OB_BALANCE_TASKS_TID, + OB_DBA_OB_BALANCE_TASK_HISTORY_TID, + OB_DBA_OB_TRANSFER_TASKS_TID, + OB_DBA_OB_TRANSFER_TASK_HISTORY_TID, OB_DBA_OB_EXTERNAL_TABLE_FILES_TID, OB_ALL_OB_EXTERNAL_TABLE_FILES_TID, OB_GV_OB_PX_P2P_DATAHUB_TID, @@ -5322,6 +5457,12 @@ const uint64_t tenant_space_tables [] = { OB_DBA_OB_LOG_RESTORE_SOURCE_ORA_TID, OB_DBA_OB_EXTERNAL_TABLE_FILES_ORA_TID, OB_ALL_OB_EXTERNAL_TABLE_FILES_ORA_TID, + OB_DBA_OB_BALANCE_JOBS_ORA_TID, + OB_DBA_OB_BALANCE_JOB_HISTORY_ORA_TID, + OB_DBA_OB_BALANCE_TASKS_ORA_TID, + OB_DBA_OB_BALANCE_TASK_HISTORY_ORA_TID, + OB_DBA_OB_TRANSFER_TASKS_ORA_TID, + OB_DBA_OB_TRANSFER_TASK_HISTORY_ORA_TID, OB_GV_OB_PX_P2P_DATAHUB_ORA_TID, OB_V_OB_PX_P2P_DATAHUB_ORA_TID, OB_GV_SQL_JOIN_FILTER_ORA_TID, @@ -5848,6 +5989,12 @@ const uint64_t tenant_space_tables [] = { OB_ALL_SERVICE_EPOCH_AUX_LOB_META_TID, OB_ALL_SPATIAL_REFERENCE_SYSTEMS_AUX_LOB_META_TID, OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_META_TID, + OB_ALL_TRANSFER_TASK_AUX_LOB_META_TID, + OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_META_TID, + OB_ALL_BALANCE_JOB_AUX_LOB_META_TID, + OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_META_TID, + OB_ALL_BALANCE_TASK_AUX_LOB_META_TID, + OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_META_TID, OB_ALL_LS_ARB_REPLICA_TASK_AUX_LOB_META_TID, OB_ALL_DATA_DICTIONARY_IN_LOG_AUX_LOB_META_TID, OB_ALL_LS_ARB_REPLICA_TASK_HISTORY_AUX_LOB_META_TID, @@ -5863,9 +6010,11 @@ const uint64_t tenant_space_tables [] = { OB_ALL_RLS_ATTRIBUTE_HISTORY_AUX_LOB_META_TID, OB_ALL_TENANT_REWRITE_RULES_AUX_LOB_META_TID, OB_ALL_RESERVED_SNAPSHOT_AUX_LOB_META_TID, + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_META_TID, OB_ALL_EXTERNAL_TABLE_FILE_AUX_LOB_META_TID, OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_AUX_LOB_META_TID, OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_AUX_LOB_META_TID, + OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TID, OB_ALL_TABLE_AUX_LOB_PIECE_TID, OB_ALL_COLUMN_AUX_LOB_PIECE_TID, OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TID, @@ -6063,6 +6212,12 @@ const uint64_t tenant_space_tables [] = { OB_ALL_SERVICE_EPOCH_AUX_LOB_PIECE_TID, OB_ALL_SPATIAL_REFERENCE_SYSTEMS_AUX_LOB_PIECE_TID, OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_PIECE_TID, + OB_ALL_TRANSFER_TASK_AUX_LOB_PIECE_TID, + OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_PIECE_TID, + OB_ALL_BALANCE_JOB_AUX_LOB_PIECE_TID, + OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_PIECE_TID, + OB_ALL_BALANCE_TASK_AUX_LOB_PIECE_TID, + OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_PIECE_TID, OB_ALL_LS_ARB_REPLICA_TASK_AUX_LOB_PIECE_TID, OB_ALL_DATA_DICTIONARY_IN_LOG_AUX_LOB_PIECE_TID, OB_ALL_LS_ARB_REPLICA_TASK_HISTORY_AUX_LOB_PIECE_TID, @@ -6078,9 +6233,11 @@ const uint64_t tenant_space_tables [] = { OB_ALL_RLS_ATTRIBUTE_HISTORY_AUX_LOB_PIECE_TID, OB_ALL_TENANT_REWRITE_RULES_AUX_LOB_PIECE_TID, OB_ALL_RESERVED_SNAPSHOT_AUX_LOB_PIECE_TID, + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_PIECE_TID, OB_ALL_EXTERNAL_TABLE_FILE_AUX_LOB_PIECE_TID, OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_AUX_LOB_PIECE_TID, - OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_AUX_LOB_PIECE_TID, }; + OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_AUX_LOB_PIECE_TID, + OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TID, }; const uint64_t all_ora_mapping_virtual_table_org_tables [] = { OB_ALL_VIRTUAL_SQL_AUDIT_TID, @@ -6204,7 +6361,8 @@ const uint64_t all_ora_mapping_virtual_table_org_tables [] = { OB_ALL_VIRTUAL_LOG_RESTORE_SOURCE_TID, OB_ALL_VIRTUAL_PX_P2P_DATAHUB_TID, OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_TID, - OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TID, }; + OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TID, + OB_ALL_VIRTUAL_TENANT_PARAMETER_TID, }; const uint64_t all_ora_mapping_virtual_tables [] = { OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TID , OB_ALL_VIRTUAL_PLAN_STAT_ORA_TID @@ -6328,6 +6486,7 @@ const uint64_t all_ora_mapping_virtual_tables [] = { OB_ALL_VIRTUAL_SQL_AUDIT_O , OB_ALL_VIRTUAL_PX_P2P_DATAHUB_ORA_TID , OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_ORA_TID , OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_ORA_TID +, OB_ALL_VIRTUAL_TENANT_PARAMETER_ORA_TID , }; /* start/end_pos is start/end postition for column with tenant id */ @@ -6540,6 +6699,12 @@ const char* const tenant_space_table_names [] = { OB_ALL_SERVICE_EPOCH_TNAME, OB_ALL_SPATIAL_REFERENCE_SYSTEMS_TNAME, OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_TNAME, + OB_ALL_TRANSFER_TASK_TNAME, + OB_ALL_TRANSFER_TASK_HISTORY_TNAME, + OB_ALL_BALANCE_JOB_TNAME, + OB_ALL_BALANCE_JOB_HISTORY_TNAME, + OB_ALL_BALANCE_TASK_TNAME, + OB_ALL_BALANCE_TASK_HISTORY_TNAME, OB_ALL_LS_ARB_REPLICA_TASK_TNAME, OB_ALL_DATA_DICTIONARY_IN_LOG_TNAME, OB_ALL_LS_ARB_REPLICA_TASK_HISTORY_TNAME, @@ -6555,9 +6720,11 @@ const char* const tenant_space_table_names [] = { OB_ALL_RLS_ATTRIBUTE_HISTORY_TNAME, OB_ALL_TENANT_REWRITE_RULES_TNAME, OB_ALL_RESERVED_SNAPSHOT_TNAME, + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TNAME, OB_ALL_EXTERNAL_TABLE_FILE_TNAME, OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_TNAME, OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_TNAME, + OB_ALL_BALANCE_TASK_HELPER_TNAME, OB_TENANT_VIRTUAL_ALL_TABLE_TNAME, OB_TENANT_VIRTUAL_TABLE_COLUMN_TNAME, OB_TENANT_VIRTUAL_TABLE_INDEX_TNAME, @@ -6719,6 +6886,8 @@ const char* const tenant_space_table_names [] = { OB_ALL_VIRTUAL_LS_ARB_REPLICA_TASK_TNAME, OB_ALL_VIRTUAL_LS_ARB_REPLICA_TASK_HISTORY_TNAME, OB_ALL_VIRTUAL_ARCHIVE_DEST_STATUS_TNAME, + OB_ALL_VIRTUAL_MDS_NODE_STAT_TNAME, + OB_ALL_VIRTUAL_MDS_EVENT_HISTORY_TNAME, OB_ALL_VIRTUAL_DUP_LS_LEASE_MGR_TNAME, OB_ALL_VIRTUAL_DUP_LS_TABLET_SET_TNAME, OB_ALL_VIRTUAL_DUP_LS_TABLETS_TNAME, @@ -6729,9 +6898,12 @@ const char* const tenant_space_table_names [] = { OB_ALL_VIRTUAL_ARBITRATION_MEMBER_INFO_TNAME, OB_ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS_TNAME, OB_ALL_VIRTUAL_VIRTUAL_LONG_OPS_STATUS_MYSQL_SYS_AGENT_TNAME, + OB_ALL_VIRTUAL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TNAME, OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_TNAME, + OB_ALL_VIRTUAL_RESOURCE_POOL_MYSQL_SYS_AGENT_TNAME, OB_ALL_VIRTUAL_PX_P2P_DATAHUB_TNAME, OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TNAME, + OB_ALL_VIRTUAL_TENANT_PARAMETER_TNAME, OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TNAME, OB_ALL_VIRTUAL_SQL_AUDIT_ORA_ALL_VIRTUAL_SQL_AUDIT_I1_TNAME, OB_ALL_VIRTUAL_PLAN_STAT_ORA_TNAME, @@ -6959,9 +7131,17 @@ const char* const tenant_space_table_names [] = { OB_ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS_ORA_TNAME, OB_ALL_VIRTUAL_OBJ_LOCK_ORA_TNAME, OB_ALL_VIRTUAL_LOG_RESTORE_SOURCE_ORA_TNAME, + OB_ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT_ORA_TNAME, + OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT_ORA_TNAME, + OB_ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT_ORA_TNAME, + OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT_ORA_TNAME, + OB_ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT_ORA_TNAME, + OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT_ORA_TNAME, + OB_ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT_TNAME, OB_ALL_VIRTUAL_PX_P2P_DATAHUB_ORA_TNAME, OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_ORA_TNAME, OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_ORA_TNAME, + OB_ALL_VIRTUAL_TENANT_PARAMETER_ORA_TNAME, OB_GV_OB_PLAN_CACHE_STAT_TNAME, OB_GV_OB_PLAN_CACHE_PLAN_STAT_TNAME, OB_SCHEMATA_TNAME, @@ -7190,6 +7370,12 @@ const char* const tenant_space_table_names [] = { OB_V_OB_LOCKS_TNAME, OB_DBA_OB_LOG_RESTORE_SOURCE_TNAME, OB_V_OB_TIMESTAMP_SERVICE_TNAME, + OB_DBA_OB_BALANCE_JOBS_TNAME, + OB_DBA_OB_BALANCE_JOB_HISTORY_TNAME, + OB_DBA_OB_BALANCE_TASKS_TNAME, + OB_DBA_OB_BALANCE_TASK_HISTORY_TNAME, + OB_DBA_OB_TRANSFER_TASKS_TNAME, + OB_DBA_OB_TRANSFER_TASK_HISTORY_TNAME, OB_DBA_OB_EXTERNAL_TABLE_FILES_TNAME, OB_ALL_OB_EXTERNAL_TABLE_FILES_TNAME, OB_GV_OB_PX_P2P_DATAHUB_TNAME, @@ -7426,6 +7612,12 @@ const char* const tenant_space_table_names [] = { OB_DBA_OB_LOG_RESTORE_SOURCE_ORA_TNAME, OB_DBA_OB_EXTERNAL_TABLE_FILES_ORA_TNAME, OB_ALL_OB_EXTERNAL_TABLE_FILES_ORA_TNAME, + OB_DBA_OB_BALANCE_JOBS_ORA_TNAME, + OB_DBA_OB_BALANCE_JOB_HISTORY_ORA_TNAME, + OB_DBA_OB_BALANCE_TASKS_ORA_TNAME, + OB_DBA_OB_BALANCE_TASK_HISTORY_ORA_TNAME, + OB_DBA_OB_TRANSFER_TASKS_ORA_TNAME, + OB_DBA_OB_TRANSFER_TASK_HISTORY_ORA_TNAME, OB_GV_OB_PX_P2P_DATAHUB_ORA_TNAME, OB_V_OB_PX_P2P_DATAHUB_ORA_TNAME, OB_GV_SQL_JOIN_FILTER_ORA_TNAME, @@ -7952,6 +8144,12 @@ const char* const tenant_space_table_names [] = { OB_ALL_SERVICE_EPOCH_AUX_LOB_META_TNAME, OB_ALL_SPATIAL_REFERENCE_SYSTEMS_AUX_LOB_META_TNAME, OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_META_TNAME, + OB_ALL_TRANSFER_TASK_AUX_LOB_META_TNAME, + OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_META_TNAME, + OB_ALL_BALANCE_JOB_AUX_LOB_META_TNAME, + OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_META_TNAME, + OB_ALL_BALANCE_TASK_AUX_LOB_META_TNAME, + OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_META_TNAME, OB_ALL_LS_ARB_REPLICA_TASK_AUX_LOB_META_TNAME, OB_ALL_DATA_DICTIONARY_IN_LOG_AUX_LOB_META_TNAME, OB_ALL_LS_ARB_REPLICA_TASK_HISTORY_AUX_LOB_META_TNAME, @@ -7967,9 +8165,11 @@ const char* const tenant_space_table_names [] = { OB_ALL_RLS_ATTRIBUTE_HISTORY_AUX_LOB_META_TNAME, OB_ALL_TENANT_REWRITE_RULES_AUX_LOB_META_TNAME, OB_ALL_RESERVED_SNAPSHOT_AUX_LOB_META_TNAME, + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_META_TNAME, OB_ALL_EXTERNAL_TABLE_FILE_AUX_LOB_META_TNAME, OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_AUX_LOB_META_TNAME, OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_AUX_LOB_META_TNAME, + OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TNAME, OB_ALL_TABLE_AUX_LOB_PIECE_TNAME, OB_ALL_COLUMN_AUX_LOB_PIECE_TNAME, OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TNAME, @@ -8167,6 +8367,12 @@ const char* const tenant_space_table_names [] = { OB_ALL_SERVICE_EPOCH_AUX_LOB_PIECE_TNAME, OB_ALL_SPATIAL_REFERENCE_SYSTEMS_AUX_LOB_PIECE_TNAME, OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_PIECE_TNAME, + OB_ALL_TRANSFER_TASK_AUX_LOB_PIECE_TNAME, + OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_PIECE_TNAME, + OB_ALL_BALANCE_JOB_AUX_LOB_PIECE_TNAME, + OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_PIECE_TNAME, + OB_ALL_BALANCE_TASK_AUX_LOB_PIECE_TNAME, + OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_PIECE_TNAME, OB_ALL_LS_ARB_REPLICA_TASK_AUX_LOB_PIECE_TNAME, OB_ALL_DATA_DICTIONARY_IN_LOG_AUX_LOB_PIECE_TNAME, OB_ALL_LS_ARB_REPLICA_TASK_HISTORY_AUX_LOB_PIECE_TNAME, @@ -8182,15 +8388,16 @@ const char* const tenant_space_table_names [] = { OB_ALL_RLS_ATTRIBUTE_HISTORY_AUX_LOB_PIECE_TNAME, OB_ALL_TENANT_REWRITE_RULES_AUX_LOB_PIECE_TNAME, OB_ALL_RESERVED_SNAPSHOT_AUX_LOB_PIECE_TNAME, + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_PIECE_TNAME, OB_ALL_EXTERNAL_TABLE_FILE_AUX_LOB_PIECE_TNAME, OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_AUX_LOB_PIECE_TNAME, - OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_AUX_LOB_PIECE_TNAME, }; + OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_AUX_LOB_PIECE_TNAME, + OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TNAME, }; const uint64_t only_rs_vtables [] = { OB_ALL_VIRTUAL_CORE_META_TABLE_TID, OB_ALL_VIRTUAL_UPGRADE_INSPECTION_TID, OB_ALL_VIRTUAL_LONG_OPS_STATUS_TID, - OB_ALL_VIRTUAL_BACKUP_SCHEDULE_TASK_TID, OB_ALL_VIRTUAL_LS_REPLICA_TASK_PLAN_TID, OB_ALL_VIRTUAL_LS_REPLICA_TASK_PLAN_ORA_TID, }; @@ -8227,6 +8434,7 @@ const uint64_t cluster_distributed_vtables [] = { OB_ALL_VIRTUAL_TENANT_CTX_MEMORY_INFO_TID, OB_ALL_VIRTUAL_DBLINK_INFO_TID, OB_ALL_VIRTUAL_LOAD_DATA_STAT_TID, + OB_ALL_VIRTUAL_BACKUP_SCHEDULE_TASK_TID, OB_ALL_VIRTUAL_SERVER_TID, OB_ALL_VIRTUAL_LS_INFO_TID, OB_ALL_VIRTUAL_TABLET_INFO_TID, @@ -8314,6 +8522,8 @@ const uint64_t tenant_distributed_vtables [] = { OB_ALL_VIRTUAL_TABLET_COMPACTION_INFO_TID, OB_ALL_VIRTUAL_SQL_PLAN_TID, OB_ALL_VIRTUAL_MALLOC_SAMPLE_INFO_TID, + OB_ALL_VIRTUAL_MDS_NODE_STAT_TID, + OB_ALL_VIRTUAL_MDS_EVENT_HISTORY_TID, OB_ALL_VIRTUAL_DUP_LS_LEASE_MGR_TID, OB_ALL_VIRTUAL_DUP_LS_TABLET_SET_TID, OB_ALL_VIRTUAL_DUP_LS_TABLETS_TID, @@ -8483,9 +8693,17 @@ const uint64_t restrict_access_virtual_tables[] = { OB_ALL_VIRTUAL_THREAD_ORA_TID, OB_ALL_VIRTUAL_ARBITRATION_MEMBER_INFO_ORA_TID, OB_ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS_ORA_TID, + OB_ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT_TID, OB_ALL_VIRTUAL_PX_P2P_DATAHUB_ORA_TID, OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_ORA_TID, - OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_ORA_TID }; + OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_ORA_TID, + OB_ALL_VIRTUAL_TENANT_PARAMETER_ORA_TID }; static inline bool is_restrict_access_virtual_table(const uint64_t tid) @@ -10360,6 +10578,54 @@ LOBMapping const lob_aux_table_mappings [] = { ObInnerTableSchema::all_column_checksum_error_info_aux_lob_piece_schema }, + { + OB_ALL_TRANSFER_TASK_TID, + OB_ALL_TRANSFER_TASK_AUX_LOB_META_TID, + OB_ALL_TRANSFER_TASK_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_transfer_task_aux_lob_meta_schema, + ObInnerTableSchema::all_transfer_task_aux_lob_piece_schema + }, + + { + OB_ALL_TRANSFER_TASK_HISTORY_TID, + OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_META_TID, + OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_transfer_task_history_aux_lob_meta_schema, + ObInnerTableSchema::all_transfer_task_history_aux_lob_piece_schema + }, + + { + OB_ALL_BALANCE_JOB_TID, + OB_ALL_BALANCE_JOB_AUX_LOB_META_TID, + OB_ALL_BALANCE_JOB_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_balance_job_aux_lob_meta_schema, + ObInnerTableSchema::all_balance_job_aux_lob_piece_schema + }, + + { + OB_ALL_BALANCE_JOB_HISTORY_TID, + OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_META_TID, + OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_balance_job_history_aux_lob_meta_schema, + ObInnerTableSchema::all_balance_job_history_aux_lob_piece_schema + }, + + { + OB_ALL_BALANCE_TASK_TID, + OB_ALL_BALANCE_TASK_AUX_LOB_META_TID, + OB_ALL_BALANCE_TASK_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_balance_task_aux_lob_meta_schema, + ObInnerTableSchema::all_balance_task_aux_lob_piece_schema + }, + + { + OB_ALL_BALANCE_TASK_HISTORY_TID, + OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_META_TID, + OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_balance_task_history_aux_lob_meta_schema, + ObInnerTableSchema::all_balance_task_history_aux_lob_piece_schema + }, + { OB_ALL_ARBITRATION_SERVICE_TID, OB_ALL_ARBITRATION_SERVICE_AUX_LOB_META_TID, @@ -10496,6 +10762,14 @@ LOBMapping const lob_aux_table_mappings [] = { ObInnerTableSchema::all_cluster_event_history_aux_lob_piece_schema }, + { + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID, + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_META_TID, + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_ls_transfer_member_list_lock_info_aux_lob_meta_schema, + ObInnerTableSchema::all_ls_transfer_member_list_lock_info_aux_lob_piece_schema + }, + { OB_ALL_EXTERNAL_TABLE_FILE_TID, OB_ALL_EXTERNAL_TABLE_FILE_AUX_LOB_META_TID, @@ -10520,6 +10794,14 @@ LOBMapping const lob_aux_table_mappings [] = { ObInnerTableSchema::all_table_opt_stat_gather_history_aux_lob_piece_schema }, + { + OB_ALL_BALANCE_TASK_HELPER_TID, + OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TID, + OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_balance_task_helper_aux_lob_meta_schema, + ObInnerTableSchema::all_balance_task_helper_aux_lob_piece_schema + }, + }; static inline bool get_sys_table_lob_aux_table_id(const uint64_t tid, uint64_t& meta_tid, uint64_t& piece_tid) @@ -10557,12 +10839,12 @@ static inline int get_sys_table_lob_aux_schema(const uint64_t tid, } const int64_t OB_CORE_TABLE_COUNT = 4; -const int64_t OB_SYS_TABLE_COUNT = 233; -const int64_t OB_VIRTUAL_TABLE_COUNT = 676; -const int64_t OB_SYS_VIEW_COUNT = 716; -const int64_t OB_SYS_TENANT_TABLE_COUNT = 1630; +const int64_t OB_SYS_TABLE_COUNT = 241; +const int64_t OB_VIRTUAL_TABLE_COUNT = 696; +const int64_t OB_SYS_VIEW_COUNT = 734; +const int64_t OB_SYS_TENANT_TABLE_COUNT = 1676; const int64_t OB_CORE_SCHEMA_VERSION = 1; -const int64_t OB_BOOTSTRAP_SCHEMA_VERSION = 1633; +const int64_t OB_BOOTSTRAP_SCHEMA_VERSION = 1679; } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.lob.cpp b/src/share/inner_table/ob_inner_table_schema.lob.cpp index ece16457c..59a43aa17 100644 --- a/src/share/inner_table/ob_inner_table_schema.lob.cpp +++ b/src/share/inner_table/ob_inner_table_schema.lob.cpp @@ -21,7 +21,7 @@ inner_lob_map_t inner_lob_map; bool lob_mapping_init() { int ret = OB_SUCCESS; - if (OB_FAIL(inner_lob_map.create(236, ObModIds::OB_INNER_LOB_HASH_SET))) { + if (OB_FAIL(inner_lob_map.create(244, ObModIds::OB_INNER_LOB_HASH_SET))) { SERVER_LOG(WARN, "fail to create inner lob map", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < ARRAYSIZEOF(lob_aux_table_mappings); ++i) { diff --git a/src/share/inner_table/ob_inner_table_schema.vt.cpp b/src/share/inner_table/ob_inner_table_schema.vt.cpp index 0a3fdce3d..51c6cbb09 100644 --- a/src/share/inner_table/ob_inner_table_schema.vt.cpp +++ b/src/share/inner_table/ob_inner_table_schema.vt.cpp @@ -28,6 +28,34 @@ bool vt_mapping_init() tmp_vt_mapping.is_real_vt_ = true; } + { + int64_t idx = OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT_ORA_TID - start_idx; + VTMapping &tmp_vt_mapping = vt_mappings[idx]; + tmp_vt_mapping.mapping_tid_ = OB_ALL_BALANCE_JOB_HISTORY_TID; + tmp_vt_mapping.is_real_vt_ = true; + } + + { + int64_t idx = OB_ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT_ORA_TID - start_idx; + VTMapping &tmp_vt_mapping = vt_mappings[idx]; + tmp_vt_mapping.mapping_tid_ = OB_ALL_BALANCE_JOB_TID; + tmp_vt_mapping.is_real_vt_ = true; + } + + { + int64_t idx = OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT_ORA_TID - start_idx; + VTMapping &tmp_vt_mapping = vt_mappings[idx]; + tmp_vt_mapping.mapping_tid_ = OB_ALL_BALANCE_TASK_HISTORY_TID; + tmp_vt_mapping.is_real_vt_ = true; + } + + { + int64_t idx = OB_ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT_ORA_TID - start_idx; + VTMapping &tmp_vt_mapping = vt_mappings[idx]; + tmp_vt_mapping.mapping_tid_ = OB_ALL_BALANCE_TASK_TID; + tmp_vt_mapping.is_real_vt_ = true; + } + { int64_t idx = OB_ALL_VIRTUAL_COLL_TYPE_REAL_AGENT_ORA_TID - start_idx; VTMapping &tmp_vt_mapping = vt_mappings[idx]; @@ -1043,6 +1071,20 @@ bool vt_mapping_init() tmp_vt_mapping.is_real_vt_ = true; } + { + int64_t idx = OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT_ORA_TID - start_idx; + VTMapping &tmp_vt_mapping = vt_mappings[idx]; + tmp_vt_mapping.mapping_tid_ = OB_ALL_TRANSFER_TASK_HISTORY_TID; + tmp_vt_mapping.is_real_vt_ = true; + } + + { + int64_t idx = OB_ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT_ORA_TID - start_idx; + VTMapping &tmp_vt_mapping = vt_mappings[idx]; + tmp_vt_mapping.mapping_tid_ = OB_ALL_TRANSFER_TASK_TID; + tmp_vt_mapping.is_real_vt_ = true; + } + { int64_t idx = OB_ALL_VIRTUAL_TYPE_ATTR_REAL_AGENT_ORA_TID - start_idx; VTMapping &tmp_vt_mapping = vt_mappings[idx]; diff --git a/src/share/inner_table/ob_inner_table_schema_constants.h b/src/share/inner_table/ob_inner_table_schema_constants.h index 321ab2a55..a110da069 100644 --- a/src/share/inner_table/ob_inner_table_schema_constants.h +++ b/src/share/inner_table/ob_inner_table_schema_constants.h @@ -244,6 +244,12 @@ const uint64_t OB_ALL_LOG_RESTORE_SOURCE_TID = 409; // "__all_log_restore_source const uint64_t OB_ALL_SERVICE_EPOCH_TID = 412; // "__all_service_epoch" const uint64_t OB_ALL_SPATIAL_REFERENCE_SYSTEMS_TID = 413; // "__all_spatial_reference_systems" const uint64_t OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_TID = 416; // "__all_column_checksum_error_info" +const uint64_t OB_ALL_TRANSFER_TASK_TID = 423; // "__all_transfer_task" +const uint64_t OB_ALL_TRANSFER_TASK_HISTORY_TID = 424; // "__all_transfer_task_history" +const uint64_t OB_ALL_BALANCE_JOB_TID = 425; // "__all_balance_job" +const uint64_t OB_ALL_BALANCE_JOB_HISTORY_TID = 426; // "__all_balance_job_history" +const uint64_t OB_ALL_BALANCE_TASK_TID = 427; // "__all_balance_task" +const uint64_t OB_ALL_BALANCE_TASK_HISTORY_TID = 428; // "__all_balance_task_history" const uint64_t OB_ALL_ARBITRATION_SERVICE_TID = 429; // "__all_arbitration_service" const uint64_t OB_ALL_LS_ARB_REPLICA_TASK_TID = 430; // "__all_ls_arb_replica_task" const uint64_t OB_ALL_DATA_DICTIONARY_IN_LOG_TID = 431; // "__all_data_dictionary_in_log" @@ -261,9 +267,11 @@ const uint64_t OB_ALL_RLS_ATTRIBUTE_HISTORY_TID = 442; // "__all_rls_attribute_h const uint64_t OB_ALL_TENANT_REWRITE_RULES_TID = 443; // "__all_tenant_rewrite_rules" const uint64_t OB_ALL_RESERVED_SNAPSHOT_TID = 444; // "__all_reserved_snapshot" const uint64_t OB_ALL_CLUSTER_EVENT_HISTORY_TID = 445; // "__all_cluster_event_history" +const uint64_t OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID = 446; // "__all_ls_transfer_member_list_lock_info" const uint64_t OB_ALL_EXTERNAL_TABLE_FILE_TID = 450; // "__all_external_table_file" const uint64_t OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_TID = 451; // "__all_task_opt_stat_gather_history" const uint64_t OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_TID = 452; // "__all_table_opt_stat_gather_history" +const uint64_t OB_ALL_BALANCE_TASK_HELPER_TID = 459; // "__all_balance_task_helper" const uint64_t OB_TENANT_VIRTUAL_ALL_TABLE_TID = 10001; // "__tenant_virtual_all_table" const uint64_t OB_TENANT_VIRTUAL_TABLE_COLUMN_TID = 10002; // "__tenant_virtual_table_column" const uint64_t OB_TENANT_VIRTUAL_TABLE_INDEX_TID = 10003; // "__tenant_virtual_table_index" @@ -598,6 +606,12 @@ const uint64_t OB_ALL_VIRTUAL_MINOR_FREEZE_INFO_TID = 12338; // "__all_virtual_m const uint64_t OB_ALL_VIRTUAL_SHOW_TRACE_TID = 12339; // "__all_virtual_show_trace" const uint64_t OB_ALL_VIRTUAL_HA_DIAGNOSE_TID = 12340; // "__all_virtual_ha_diagnose" const uint64_t OB_ALL_VIRTUAL_DATA_DICTIONARY_IN_LOG_TID = 12341; // "__all_virtual_data_dictionary_in_log" +const uint64_t OB_ALL_VIRTUAL_TRANSFER_TASK_TID = 12342; // "__all_virtual_transfer_task" +const uint64_t OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_TID = 12343; // "__all_virtual_transfer_task_history" +const uint64_t OB_ALL_VIRTUAL_BALANCE_JOB_TID = 12344; // "__all_virtual_balance_job" +const uint64_t OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_TID = 12345; // "__all_virtual_balance_job_history" +const uint64_t OB_ALL_VIRTUAL_BALANCE_TASK_TID = 12346; // "__all_virtual_balance_task" +const uint64_t OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_TID = 12347; // "__all_virtual_balance_task_history" const uint64_t OB_ALL_VIRTUAL_RLS_POLICY_TID = 12348; // "__all_virtual_rls_policy" const uint64_t OB_ALL_VIRTUAL_RLS_POLICY_HISTORY_TID = 12349; // "__all_virtual_rls_policy_history" const uint64_t OB_ALL_VIRTUAL_RLS_SECURITY_COLUMN_TID = 12350; // "__all_virtual_rls_security_column" @@ -617,6 +631,8 @@ const uint64_t OB_ALL_VIRTUAL_LS_ARB_REPLICA_TASK_HISTORY_TID = 12365; // "__all const uint64_t OB_ALL_VIRTUAL_ARCHIVE_DEST_STATUS_TID = 12366; // "__all_virtual_archive_dest_status" const uint64_t OB_ALL_VIRTUAL_IO_SCHEDULER_TID = 12369; // "__all_virtual_io_scheduler" const uint64_t OB_ALL_VIRTUAL_EXTERNAL_TABLE_FILE_TID = 12371; // "__all_virtual_external_table_file" +const uint64_t OB_ALL_VIRTUAL_MDS_NODE_STAT_TID = 12373; // "__all_virtual_mds_node_stat" +const uint64_t OB_ALL_VIRTUAL_MDS_EVENT_HISTORY_TID = 12374; // "__all_virtual_mds_event_history" const uint64_t OB_ALL_VIRTUAL_DUP_LS_LEASE_MGR_TID = 12376; // "__all_virtual_dup_ls_lease_mgr" const uint64_t OB_ALL_VIRTUAL_DUP_LS_TABLET_SET_TID = 12378; // "__all_virtual_dup_ls_tablet_set" const uint64_t OB_ALL_VIRTUAL_DUP_LS_TABLETS_TID = 12379; // "__all_virtual_dup_ls_tablets" @@ -628,9 +644,13 @@ const uint64_t OB_ALL_VIRTUAL_THREAD_TID = 12384; // "__all_virtual_thread" const uint64_t OB_ALL_VIRTUAL_ARBITRATION_MEMBER_INFO_TID = 12385; // "__all_virtual_arbitration_member_info" const uint64_t OB_ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS_TID = 12387; // "__all_virtual_arbitration_service_status" const uint64_t OB_ALL_VIRTUAL_VIRTUAL_LONG_OPS_STATUS_MYSQL_SYS_AGENT_TID = 12393; // "__all_virtual_virtual_long_ops_status_mysql_sys_agent" +const uint64_t OB_ALL_VIRTUAL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID = 12394; // "__all_virtual_ls_transfer_member_list_lock_info" const uint64_t OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_TID = 12395; // "__all_virtual_timestamp_service" +const uint64_t OB_ALL_VIRTUAL_RESOURCE_POOL_MYSQL_SYS_AGENT_TID = 12396; // "__all_virtual_resource_pool_mysql_sys_agent" const uint64_t OB_ALL_VIRTUAL_PX_P2P_DATAHUB_TID = 12397; // "__all_virtual_px_p2p_datahub" const uint64_t OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TID = 12400; // "__all_virtual_ls_log_restore_status" +const uint64_t OB_ALL_VIRTUAL_TENANT_PARAMETER_TID = 12401; // "__all_virtual_tenant_parameter" +const uint64_t OB_ALL_VIRTUAL_TABLET_BUFFER_INFO_TID = 12405; // "__all_virtual_tablet_buffer_info" const uint64_t OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TID = 15009; // "ALL_VIRTUAL_SQL_AUDIT_ORA" const uint64_t OB_ALL_VIRTUAL_PLAN_STAT_ORA_TID = 15010; // "ALL_VIRTUAL_PLAN_STAT_ORA" const uint64_t OB_ALL_VIRTUAL_PLAN_CACHE_PLAN_EXPLAIN_ORA_TID = 15012; // "ALL_VIRTUAL_PLAN_CACHE_PLAN_EXPLAIN_ORA" @@ -850,9 +870,17 @@ const uint64_t OB_ALL_VIRTUAL_ARBITRATION_MEMBER_INFO_ORA_TID = 15303; // "ALL_V const uint64_t OB_ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS_ORA_TID = 15304; // "ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS_ORA" const uint64_t OB_ALL_VIRTUAL_OBJ_LOCK_ORA_TID = 15305; // "ALL_VIRTUAL_OBJ_LOCK_ORA" const uint64_t OB_ALL_VIRTUAL_LOG_RESTORE_SOURCE_ORA_TID = 15376; // "ALL_VIRTUAL_LOG_RESTORE_SOURCE_ORA" +const uint64_t OB_ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT_ORA_TID = 15377; // "ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT_ORA" +const uint64_t OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT_ORA_TID = 15378; // "ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT_ORA" +const uint64_t OB_ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT_ORA_TID = 15379; // "ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT_ORA" +const uint64_t OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT_ORA_TID = 15380; // "ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT_ORA" +const uint64_t OB_ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT_ORA_TID = 15381; // "ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT_ORA" +const uint64_t OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT_ORA_TID = 15382; // "ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT_ORA" +const uint64_t OB_ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT_TID = 15383; // "ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT" const uint64_t OB_ALL_VIRTUAL_PX_P2P_DATAHUB_ORA_TID = 15384; // "ALL_VIRTUAL_PX_P2P_DATAHUB_ORA" const uint64_t OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_ORA_TID = 15385; // "ALL_VIRTUAL_TIMESTAMP_SERVICE_ORA" const uint64_t OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_ORA_TID = 15387; // "ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_ORA" +const uint64_t OB_ALL_VIRTUAL_TENANT_PARAMETER_ORA_TID = 15388; // "ALL_VIRTUAL_TENANT_PARAMETER_ORA" const uint64_t OB_GV_OB_PLAN_CACHE_STAT_TID = 20001; // "GV$OB_PLAN_CACHE_STAT" const uint64_t OB_GV_OB_PLAN_CACHE_PLAN_STAT_TID = 20002; // "GV$OB_PLAN_CACHE_PLAN_STAT" const uint64_t OB_SCHEMATA_TID = 20003; // "SCHEMATA" @@ -1161,6 +1189,18 @@ const uint64_t OB_V_OB_LOCKS_TID = 21400; // "V$OB_LOCKS" const uint64_t OB_CDB_OB_LOG_RESTORE_SOURCE_TID = 21401; // "CDB_OB_LOG_RESTORE_SOURCE" const uint64_t OB_DBA_OB_LOG_RESTORE_SOURCE_TID = 21402; // "DBA_OB_LOG_RESTORE_SOURCE" const uint64_t OB_V_OB_TIMESTAMP_SERVICE_TID = 21404; // "V$OB_TIMESTAMP_SERVICE" +const uint64_t OB_DBA_OB_BALANCE_JOBS_TID = 21405; // "DBA_OB_BALANCE_JOBS" +const uint64_t OB_CDB_OB_BALANCE_JOBS_TID = 21406; // "CDB_OB_BALANCE_JOBS" +const uint64_t OB_DBA_OB_BALANCE_JOB_HISTORY_TID = 21407; // "DBA_OB_BALANCE_JOB_HISTORY" +const uint64_t OB_CDB_OB_BALANCE_JOB_HISTORY_TID = 21408; // "CDB_OB_BALANCE_JOB_HISTORY" +const uint64_t OB_DBA_OB_BALANCE_TASKS_TID = 21409; // "DBA_OB_BALANCE_TASKS" +const uint64_t OB_CDB_OB_BALANCE_TASKS_TID = 21410; // "CDB_OB_BALANCE_TASKS" +const uint64_t OB_DBA_OB_BALANCE_TASK_HISTORY_TID = 21411; // "DBA_OB_BALANCE_TASK_HISTORY" +const uint64_t OB_CDB_OB_BALANCE_TASK_HISTORY_TID = 21412; // "CDB_OB_BALANCE_TASK_HISTORY" +const uint64_t OB_DBA_OB_TRANSFER_TASKS_TID = 21413; // "DBA_OB_TRANSFER_TASKS" +const uint64_t OB_CDB_OB_TRANSFER_TASKS_TID = 21414; // "CDB_OB_TRANSFER_TASKS" +const uint64_t OB_DBA_OB_TRANSFER_TASK_HISTORY_TID = 21415; // "DBA_OB_TRANSFER_TASK_HISTORY" +const uint64_t OB_CDB_OB_TRANSFER_TASK_HISTORY_TID = 21416; // "CDB_OB_TRANSFER_TASK_HISTORY" const uint64_t OB_DBA_OB_EXTERNAL_TABLE_FILES_TID = 21417; // "DBA_OB_EXTERNAL_TABLE_FILES" const uint64_t OB_ALL_OB_EXTERNAL_TABLE_FILES_TID = 21418; // "ALL_OB_EXTERNAL_TABLE_FILES" const uint64_t OB_GV_OB_PX_P2P_DATAHUB_TID = 21419; // "GV$OB_PX_P2P_DATAHUB" @@ -1398,6 +1438,12 @@ const uint64_t OB_DBA_OB_TABLE_OPT_STAT_GATHER_HISTORY_ORA_TID = 25228; // "DBA_ const uint64_t OB_DBA_OB_LOG_RESTORE_SOURCE_ORA_TID = 25233; // "DBA_OB_LOG_RESTORE_SOURCE_ORA" const uint64_t OB_DBA_OB_EXTERNAL_TABLE_FILES_ORA_TID = 25234; // "DBA_OB_EXTERNAL_TABLE_FILES_ORA" const uint64_t OB_ALL_OB_EXTERNAL_TABLE_FILES_ORA_TID = 25235; // "ALL_OB_EXTERNAL_TABLE_FILES_ORA" +const uint64_t OB_DBA_OB_BALANCE_JOBS_ORA_TID = 25237; // "DBA_OB_BALANCE_JOBS_ORA" +const uint64_t OB_DBA_OB_BALANCE_JOB_HISTORY_ORA_TID = 25238; // "DBA_OB_BALANCE_JOB_HISTORY_ORA" +const uint64_t OB_DBA_OB_BALANCE_TASKS_ORA_TID = 25239; // "DBA_OB_BALANCE_TASKS_ORA" +const uint64_t OB_DBA_OB_BALANCE_TASK_HISTORY_ORA_TID = 25240; // "DBA_OB_BALANCE_TASK_HISTORY_ORA" +const uint64_t OB_DBA_OB_TRANSFER_TASKS_ORA_TID = 25241; // "DBA_OB_TRANSFER_TASKS_ORA" +const uint64_t OB_DBA_OB_TRANSFER_TASK_HISTORY_ORA_TID = 25242; // "DBA_OB_TRANSFER_TASK_HISTORY_ORA" const uint64_t OB_GV_OB_PX_P2P_DATAHUB_ORA_TID = 25243; // "GV$OB_PX_P2P_DATAHUB_ORA" const uint64_t OB_V_OB_PX_P2P_DATAHUB_ORA_TID = 25244; // "V$OB_PX_P2P_DATAHUB_ORA" const uint64_t OB_GV_SQL_JOIN_FILTER_ORA_TID = 25245; // "GV$SQL_JOIN_FILTER_ORA" @@ -1785,6 +1831,12 @@ const uint64_t OB_ALL_LOG_RESTORE_SOURCE_AUX_LOB_META_TID = 50409; // "__all_log const uint64_t OB_ALL_SERVICE_EPOCH_AUX_LOB_META_TID = 50412; // "__all_service_epoch_aux_lob_meta" const uint64_t OB_ALL_SPATIAL_REFERENCE_SYSTEMS_AUX_LOB_META_TID = 50413; // "__all_spatial_reference_systems_aux_lob_meta" const uint64_t OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_META_TID = 50416; // "__all_column_checksum_error_info_aux_lob_meta" +const uint64_t OB_ALL_TRANSFER_TASK_AUX_LOB_META_TID = 50423; // "__all_transfer_task_aux_lob_meta" +const uint64_t OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_META_TID = 50424; // "__all_transfer_task_history_aux_lob_meta" +const uint64_t OB_ALL_BALANCE_JOB_AUX_LOB_META_TID = 50425; // "__all_balance_job_aux_lob_meta" +const uint64_t OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_META_TID = 50426; // "__all_balance_job_history_aux_lob_meta" +const uint64_t OB_ALL_BALANCE_TASK_AUX_LOB_META_TID = 50427; // "__all_balance_task_aux_lob_meta" +const uint64_t OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_META_TID = 50428; // "__all_balance_task_history_aux_lob_meta" const uint64_t OB_ALL_ARBITRATION_SERVICE_AUX_LOB_META_TID = 50429; // "__all_arbitration_service_aux_lob_meta" const uint64_t OB_ALL_LS_ARB_REPLICA_TASK_AUX_LOB_META_TID = 50430; // "__all_ls_arb_replica_task_aux_lob_meta" const uint64_t OB_ALL_DATA_DICTIONARY_IN_LOG_AUX_LOB_META_TID = 50431; // "__all_data_dictionary_in_log_aux_lob_meta" @@ -1802,9 +1854,11 @@ const uint64_t OB_ALL_RLS_ATTRIBUTE_HISTORY_AUX_LOB_META_TID = 50442; // "__all_ const uint64_t OB_ALL_TENANT_REWRITE_RULES_AUX_LOB_META_TID = 50443; // "__all_tenant_rewrite_rules_aux_lob_meta" const uint64_t OB_ALL_RESERVED_SNAPSHOT_AUX_LOB_META_TID = 50444; // "__all_reserved_snapshot_aux_lob_meta" const uint64_t OB_ALL_CLUSTER_EVENT_HISTORY_AUX_LOB_META_TID = 50445; // "__all_cluster_event_history_aux_lob_meta" +const uint64_t OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_META_TID = 50446; // "__all_ls_transfer_member_list_lock_info_aux_lob_meta" const uint64_t OB_ALL_EXTERNAL_TABLE_FILE_AUX_LOB_META_TID = 50450; // "__all_external_table_file_aux_lob_meta" const uint64_t OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_AUX_LOB_META_TID = 50451; // "__all_task_opt_stat_gather_history_aux_lob_meta" const uint64_t OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_AUX_LOB_META_TID = 50452; // "__all_table_opt_stat_gather_history_aux_lob_meta" +const uint64_t OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TID = 50459; // "__all_balance_task_helper_aux_lob_meta" const uint64_t OB_ALL_TABLE_AUX_LOB_PIECE_TID = 60003; // "__all_table_aux_lob_piece" const uint64_t OB_ALL_COLUMN_AUX_LOB_PIECE_TID = 60004; // "__all_column_aux_lob_piece" const uint64_t OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TID = 60005; // "__all_ddl_operation_aux_lob_piece" @@ -2021,6 +2075,12 @@ const uint64_t OB_ALL_LOG_RESTORE_SOURCE_AUX_LOB_PIECE_TID = 60409; // "__all_lo const uint64_t OB_ALL_SERVICE_EPOCH_AUX_LOB_PIECE_TID = 60412; // "__all_service_epoch_aux_lob_piece" const uint64_t OB_ALL_SPATIAL_REFERENCE_SYSTEMS_AUX_LOB_PIECE_TID = 60413; // "__all_spatial_reference_systems_aux_lob_piece" const uint64_t OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_PIECE_TID = 60416; // "__all_column_checksum_error_info_aux_lob_piece" +const uint64_t OB_ALL_TRANSFER_TASK_AUX_LOB_PIECE_TID = 60423; // "__all_transfer_task_aux_lob_piece" +const uint64_t OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_PIECE_TID = 60424; // "__all_transfer_task_history_aux_lob_piece" +const uint64_t OB_ALL_BALANCE_JOB_AUX_LOB_PIECE_TID = 60425; // "__all_balance_job_aux_lob_piece" +const uint64_t OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_PIECE_TID = 60426; // "__all_balance_job_history_aux_lob_piece" +const uint64_t OB_ALL_BALANCE_TASK_AUX_LOB_PIECE_TID = 60427; // "__all_balance_task_aux_lob_piece" +const uint64_t OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_PIECE_TID = 60428; // "__all_balance_task_history_aux_lob_piece" const uint64_t OB_ALL_ARBITRATION_SERVICE_AUX_LOB_PIECE_TID = 60429; // "__all_arbitration_service_aux_lob_piece" const uint64_t OB_ALL_LS_ARB_REPLICA_TASK_AUX_LOB_PIECE_TID = 60430; // "__all_ls_arb_replica_task_aux_lob_piece" const uint64_t OB_ALL_DATA_DICTIONARY_IN_LOG_AUX_LOB_PIECE_TID = 60431; // "__all_data_dictionary_in_log_aux_lob_piece" @@ -2038,9 +2098,11 @@ const uint64_t OB_ALL_RLS_ATTRIBUTE_HISTORY_AUX_LOB_PIECE_TID = 60442; // "__all const uint64_t OB_ALL_TENANT_REWRITE_RULES_AUX_LOB_PIECE_TID = 60443; // "__all_tenant_rewrite_rules_aux_lob_piece" const uint64_t OB_ALL_RESERVED_SNAPSHOT_AUX_LOB_PIECE_TID = 60444; // "__all_reserved_snapshot_aux_lob_piece" const uint64_t OB_ALL_CLUSTER_EVENT_HISTORY_AUX_LOB_PIECE_TID = 60445; // "__all_cluster_event_history_aux_lob_piece" +const uint64_t OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_PIECE_TID = 60446; // "__all_ls_transfer_member_list_lock_info_aux_lob_piece" const uint64_t OB_ALL_EXTERNAL_TABLE_FILE_AUX_LOB_PIECE_TID = 60450; // "__all_external_table_file_aux_lob_piece" const uint64_t OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_AUX_LOB_PIECE_TID = 60451; // "__all_task_opt_stat_gather_history_aux_lob_piece" const uint64_t OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_AUX_LOB_PIECE_TID = 60452; // "__all_table_opt_stat_gather_history_aux_lob_piece" +const uint64_t OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TID = 60459; // "__all_balance_task_helper_aux_lob_piece" const uint64_t OB_ALL_VIRTUAL_PLAN_CACHE_STAT_ALL_VIRTUAL_PLAN_CACHE_STAT_I1_TID = 14999; // "__all_virtual_plan_cache_stat" const uint64_t OB_ALL_VIRTUAL_SESSION_EVENT_ALL_VIRTUAL_SESSION_EVENT_I1_TID = 14998; // "__all_virtual_session_event" const uint64_t OB_ALL_VIRTUAL_SESSION_WAIT_ALL_VIRTUAL_SESSION_WAIT_I1_TID = 14997; // "__all_virtual_session_wait" @@ -2440,6 +2502,12 @@ const char *const OB_ALL_LOG_RESTORE_SOURCE_TNAME = "__all_log_restore_source"; const char *const OB_ALL_SERVICE_EPOCH_TNAME = "__all_service_epoch"; const char *const OB_ALL_SPATIAL_REFERENCE_SYSTEMS_TNAME = "__all_spatial_reference_systems"; const char *const OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_TNAME = "__all_column_checksum_error_info"; +const char *const OB_ALL_TRANSFER_TASK_TNAME = "__all_transfer_task"; +const char *const OB_ALL_TRANSFER_TASK_HISTORY_TNAME = "__all_transfer_task_history"; +const char *const OB_ALL_BALANCE_JOB_TNAME = "__all_balance_job"; +const char *const OB_ALL_BALANCE_JOB_HISTORY_TNAME = "__all_balance_job_history"; +const char *const OB_ALL_BALANCE_TASK_TNAME = "__all_balance_task"; +const char *const OB_ALL_BALANCE_TASK_HISTORY_TNAME = "__all_balance_task_history"; const char *const OB_ALL_ARBITRATION_SERVICE_TNAME = "__all_arbitration_service"; const char *const OB_ALL_LS_ARB_REPLICA_TASK_TNAME = "__all_ls_arb_replica_task"; const char *const OB_ALL_DATA_DICTIONARY_IN_LOG_TNAME = "__all_data_dictionary_in_log"; @@ -2457,9 +2525,11 @@ const char *const OB_ALL_RLS_ATTRIBUTE_HISTORY_TNAME = "__all_rls_attribute_hist const char *const OB_ALL_TENANT_REWRITE_RULES_TNAME = "__all_tenant_rewrite_rules"; const char *const OB_ALL_RESERVED_SNAPSHOT_TNAME = "__all_reserved_snapshot"; const char *const OB_ALL_CLUSTER_EVENT_HISTORY_TNAME = "__all_cluster_event_history"; +const char *const OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TNAME = "__all_ls_transfer_member_list_lock_info"; const char *const OB_ALL_EXTERNAL_TABLE_FILE_TNAME = "__all_external_table_file"; const char *const OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_TNAME = "__all_task_opt_stat_gather_history"; const char *const OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_TNAME = "__all_table_opt_stat_gather_history"; +const char *const OB_ALL_BALANCE_TASK_HELPER_TNAME = "__all_balance_task_helper"; const char *const OB_TENANT_VIRTUAL_ALL_TABLE_TNAME = "__tenant_virtual_all_table"; const char *const OB_TENANT_VIRTUAL_TABLE_COLUMN_TNAME = "__tenant_virtual_table_column"; const char *const OB_TENANT_VIRTUAL_TABLE_INDEX_TNAME = "__tenant_virtual_table_index"; @@ -2794,6 +2864,12 @@ const char *const OB_ALL_VIRTUAL_MINOR_FREEZE_INFO_TNAME = "__all_virtual_minor_ const char *const OB_ALL_VIRTUAL_SHOW_TRACE_TNAME = "__all_virtual_show_trace"; const char *const OB_ALL_VIRTUAL_HA_DIAGNOSE_TNAME = "__all_virtual_ha_diagnose"; const char *const OB_ALL_VIRTUAL_DATA_DICTIONARY_IN_LOG_TNAME = "__all_virtual_data_dictionary_in_log"; +const char *const OB_ALL_VIRTUAL_TRANSFER_TASK_TNAME = "__all_virtual_transfer_task"; +const char *const OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_TNAME = "__all_virtual_transfer_task_history"; +const char *const OB_ALL_VIRTUAL_BALANCE_JOB_TNAME = "__all_virtual_balance_job"; +const char *const OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_TNAME = "__all_virtual_balance_job_history"; +const char *const OB_ALL_VIRTUAL_BALANCE_TASK_TNAME = "__all_virtual_balance_task"; +const char *const OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_TNAME = "__all_virtual_balance_task_history"; const char *const OB_ALL_VIRTUAL_RLS_POLICY_TNAME = "__all_virtual_rls_policy"; const char *const OB_ALL_VIRTUAL_RLS_POLICY_HISTORY_TNAME = "__all_virtual_rls_policy_history"; const char *const OB_ALL_VIRTUAL_RLS_SECURITY_COLUMN_TNAME = "__all_virtual_rls_security_column"; @@ -2813,6 +2889,8 @@ const char *const OB_ALL_VIRTUAL_LS_ARB_REPLICA_TASK_HISTORY_TNAME = "__all_virt const char *const OB_ALL_VIRTUAL_ARCHIVE_DEST_STATUS_TNAME = "__all_virtual_archive_dest_status"; const char *const OB_ALL_VIRTUAL_IO_SCHEDULER_TNAME = "__all_virtual_io_scheduler"; const char *const OB_ALL_VIRTUAL_EXTERNAL_TABLE_FILE_TNAME = "__all_virtual_external_table_file"; +const char *const OB_ALL_VIRTUAL_MDS_NODE_STAT_TNAME = "__all_virtual_mds_node_stat"; +const char *const OB_ALL_VIRTUAL_MDS_EVENT_HISTORY_TNAME = "__all_virtual_mds_event_history"; const char *const OB_ALL_VIRTUAL_DUP_LS_LEASE_MGR_TNAME = "__all_virtual_dup_ls_lease_mgr"; const char *const OB_ALL_VIRTUAL_DUP_LS_TABLET_SET_TNAME = "__all_virtual_dup_ls_tablet_set"; const char *const OB_ALL_VIRTUAL_DUP_LS_TABLETS_TNAME = "__all_virtual_dup_ls_tablets"; @@ -2824,9 +2902,13 @@ const char *const OB_ALL_VIRTUAL_THREAD_TNAME = "__all_virtual_thread"; const char *const OB_ALL_VIRTUAL_ARBITRATION_MEMBER_INFO_TNAME = "__all_virtual_arbitration_member_info"; const char *const OB_ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS_TNAME = "__all_virtual_arbitration_service_status"; const char *const OB_ALL_VIRTUAL_VIRTUAL_LONG_OPS_STATUS_MYSQL_SYS_AGENT_TNAME = "__all_virtual_virtual_long_ops_status_mysql_sys_agent"; +const char *const OB_ALL_VIRTUAL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TNAME = "__all_virtual_ls_transfer_member_list_lock_info"; const char *const OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_TNAME = "__all_virtual_timestamp_service"; +const char *const OB_ALL_VIRTUAL_RESOURCE_POOL_MYSQL_SYS_AGENT_TNAME = "__all_virtual_resource_pool_mysql_sys_agent"; const char *const OB_ALL_VIRTUAL_PX_P2P_DATAHUB_TNAME = "__all_virtual_px_p2p_datahub"; const char *const OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TNAME = "__all_virtual_ls_log_restore_status"; +const char *const OB_ALL_VIRTUAL_TENANT_PARAMETER_TNAME = "__all_virtual_tenant_parameter"; +const char *const OB_ALL_VIRTUAL_TABLET_BUFFER_INFO_TNAME = "__all_virtual_tablet_buffer_info"; const char *const OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TNAME = "ALL_VIRTUAL_SQL_AUDIT"; const char *const OB_ALL_VIRTUAL_PLAN_STAT_ORA_TNAME = "ALL_VIRTUAL_PLAN_STAT"; const char *const OB_ALL_VIRTUAL_PLAN_CACHE_PLAN_EXPLAIN_ORA_TNAME = "ALL_VIRTUAL_PLAN_CACHE_PLAN_EXPLAIN"; @@ -3046,9 +3128,17 @@ const char *const OB_ALL_VIRTUAL_ARBITRATION_MEMBER_INFO_ORA_TNAME = "ALL_VIRTUA const char *const OB_ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS_ORA_TNAME = "ALL_VIRTUAL_ARBITRATION_SERVICE_STATUS"; const char *const OB_ALL_VIRTUAL_OBJ_LOCK_ORA_TNAME = "ALL_VIRTUAL_OBJ_LOCK"; const char *const OB_ALL_VIRTUAL_LOG_RESTORE_SOURCE_ORA_TNAME = "ALL_VIRTUAL_LOG_RESTORE_SOURCE"; +const char *const OB_ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT_ORA_TNAME = "ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT"; +const char *const OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT_ORA_TNAME = "ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT"; +const char *const OB_ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT_ORA_TNAME = "ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT"; +const char *const OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT_ORA_TNAME = "ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT"; +const char *const OB_ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT_ORA_TNAME = "ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT"; +const char *const OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT_ORA_TNAME = "ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT"; +const char *const OB_ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT_TNAME = "ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT"; const char *const OB_ALL_VIRTUAL_PX_P2P_DATAHUB_ORA_TNAME = "ALL_VIRTUAL_PX_P2P_DATAHUB"; const char *const OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_ORA_TNAME = "ALL_VIRTUAL_TIMESTAMP_SERVICE"; const char *const OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_ORA_TNAME = "ALL_VIRTUAL_LS_LOG_RESTORE_STATUS"; +const char *const OB_ALL_VIRTUAL_TENANT_PARAMETER_ORA_TNAME = "ALL_VIRTUAL_TENANT_PARAMETER"; const char *const OB_GV_OB_PLAN_CACHE_STAT_TNAME = "GV$OB_PLAN_CACHE_STAT"; const char *const OB_GV_OB_PLAN_CACHE_PLAN_STAT_TNAME = "GV$OB_PLAN_CACHE_PLAN_STAT"; const char *const OB_SCHEMATA_TNAME = "SCHEMATA"; @@ -3357,6 +3447,18 @@ const char *const OB_V_OB_LOCKS_TNAME = "V$OB_LOCKS"; const char *const OB_CDB_OB_LOG_RESTORE_SOURCE_TNAME = "CDB_OB_LOG_RESTORE_SOURCE"; const char *const OB_DBA_OB_LOG_RESTORE_SOURCE_TNAME = "DBA_OB_LOG_RESTORE_SOURCE"; const char *const OB_V_OB_TIMESTAMP_SERVICE_TNAME = "V$OB_TIMESTAMP_SERVICE"; +const char *const OB_DBA_OB_BALANCE_JOBS_TNAME = "DBA_OB_BALANCE_JOBS"; +const char *const OB_CDB_OB_BALANCE_JOBS_TNAME = "CDB_OB_BALANCE_JOBS"; +const char *const OB_DBA_OB_BALANCE_JOB_HISTORY_TNAME = "DBA_OB_BALANCE_JOB_HISTORY"; +const char *const OB_CDB_OB_BALANCE_JOB_HISTORY_TNAME = "CDB_OB_BALANCE_JOB_HISTORY"; +const char *const OB_DBA_OB_BALANCE_TASKS_TNAME = "DBA_OB_BALANCE_TASKS"; +const char *const OB_CDB_OB_BALANCE_TASKS_TNAME = "CDB_OB_BALANCE_TASKS"; +const char *const OB_DBA_OB_BALANCE_TASK_HISTORY_TNAME = "DBA_OB_BALANCE_TASK_HISTORY"; +const char *const OB_CDB_OB_BALANCE_TASK_HISTORY_TNAME = "CDB_OB_BALANCE_TASK_HISTORY"; +const char *const OB_DBA_OB_TRANSFER_TASKS_TNAME = "DBA_OB_TRANSFER_TASKS"; +const char *const OB_CDB_OB_TRANSFER_TASKS_TNAME = "CDB_OB_TRANSFER_TASKS"; +const char *const OB_DBA_OB_TRANSFER_TASK_HISTORY_TNAME = "DBA_OB_TRANSFER_TASK_HISTORY"; +const char *const OB_CDB_OB_TRANSFER_TASK_HISTORY_TNAME = "CDB_OB_TRANSFER_TASK_HISTORY"; const char *const OB_DBA_OB_EXTERNAL_TABLE_FILES_TNAME = "DBA_OB_EXTERNAL_TABLE_FILES"; const char *const OB_ALL_OB_EXTERNAL_TABLE_FILES_TNAME = "ALL_OB_EXTERNAL_TABLE_FILES"; const char *const OB_GV_OB_PX_P2P_DATAHUB_TNAME = "GV$OB_PX_P2P_DATAHUB"; @@ -3594,6 +3696,12 @@ const char *const OB_DBA_OB_TABLE_OPT_STAT_GATHER_HISTORY_ORA_TNAME = "DBA_OB_TA const char *const OB_DBA_OB_LOG_RESTORE_SOURCE_ORA_TNAME = "DBA_OB_LOG_RESTORE_SOURCE"; const char *const OB_DBA_OB_EXTERNAL_TABLE_FILES_ORA_TNAME = "DBA_OB_EXTERNAL_TABLE_FILES"; const char *const OB_ALL_OB_EXTERNAL_TABLE_FILES_ORA_TNAME = "ALL_OB_EXTERNAL_TABLE_FILES"; +const char *const OB_DBA_OB_BALANCE_JOBS_ORA_TNAME = "DBA_OB_BALANCE_JOBS"; +const char *const OB_DBA_OB_BALANCE_JOB_HISTORY_ORA_TNAME = "DBA_OB_BALANCE_JOB_HISTORY"; +const char *const OB_DBA_OB_BALANCE_TASKS_ORA_TNAME = "DBA_OB_BALANCE_TASKS"; +const char *const OB_DBA_OB_BALANCE_TASK_HISTORY_ORA_TNAME = "DBA_OB_BALANCE_TASK_HISTORY"; +const char *const OB_DBA_OB_TRANSFER_TASKS_ORA_TNAME = "DBA_OB_TRANSFER_TASKS"; +const char *const OB_DBA_OB_TRANSFER_TASK_HISTORY_ORA_TNAME = "DBA_OB_TRANSFER_TASK_HISTORY"; const char *const OB_GV_OB_PX_P2P_DATAHUB_ORA_TNAME = "GV$OB_PX_P2P_DATAHUB"; const char *const OB_V_OB_PX_P2P_DATAHUB_ORA_TNAME = "V$OB_PX_P2P_DATAHUB"; const char *const OB_GV_SQL_JOIN_FILTER_ORA_TNAME = "GV$SQL_JOIN_FILTER"; @@ -3981,6 +4089,12 @@ const char *const OB_ALL_LOG_RESTORE_SOURCE_AUX_LOB_META_TNAME = "__all_log_rest const char *const OB_ALL_SERVICE_EPOCH_AUX_LOB_META_TNAME = "__all_service_epoch_aux_lob_meta"; const char *const OB_ALL_SPATIAL_REFERENCE_SYSTEMS_AUX_LOB_META_TNAME = "__all_spatial_reference_systems_aux_lob_meta"; const char *const OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_META_TNAME = "__all_column_checksum_error_info_aux_lob_meta"; +const char *const OB_ALL_TRANSFER_TASK_AUX_LOB_META_TNAME = "__all_transfer_task_aux_lob_meta"; +const char *const OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_META_TNAME = "__all_transfer_task_history_aux_lob_meta"; +const char *const OB_ALL_BALANCE_JOB_AUX_LOB_META_TNAME = "__all_balance_job_aux_lob_meta"; +const char *const OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_META_TNAME = "__all_balance_job_history_aux_lob_meta"; +const char *const OB_ALL_BALANCE_TASK_AUX_LOB_META_TNAME = "__all_balance_task_aux_lob_meta"; +const char *const OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_META_TNAME = "__all_balance_task_history_aux_lob_meta"; const char *const OB_ALL_ARBITRATION_SERVICE_AUX_LOB_META_TNAME = "__all_arbitration_service_aux_lob_meta"; const char *const OB_ALL_LS_ARB_REPLICA_TASK_AUX_LOB_META_TNAME = "__all_ls_arb_replica_task_aux_lob_meta"; const char *const OB_ALL_DATA_DICTIONARY_IN_LOG_AUX_LOB_META_TNAME = "__all_data_dictionary_in_log_aux_lob_meta"; @@ -3998,9 +4112,11 @@ const char *const OB_ALL_RLS_ATTRIBUTE_HISTORY_AUX_LOB_META_TNAME = "__all_rls_a const char *const OB_ALL_TENANT_REWRITE_RULES_AUX_LOB_META_TNAME = "__all_tenant_rewrite_rules_aux_lob_meta"; const char *const OB_ALL_RESERVED_SNAPSHOT_AUX_LOB_META_TNAME = "__all_reserved_snapshot_aux_lob_meta"; const char *const OB_ALL_CLUSTER_EVENT_HISTORY_AUX_LOB_META_TNAME = "__all_cluster_event_history_aux_lob_meta"; +const char *const OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_META_TNAME = "__all_ls_transfer_member_list_lock_info_aux_lob_meta"; const char *const OB_ALL_EXTERNAL_TABLE_FILE_AUX_LOB_META_TNAME = "__all_external_table_file_aux_lob_meta"; const char *const OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_AUX_LOB_META_TNAME = "__all_task_opt_stat_gather_history_aux_lob_meta"; const char *const OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_AUX_LOB_META_TNAME = "__all_table_opt_stat_gather_history_aux_lob_meta"; +const char *const OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TNAME = "__all_balance_task_helper_aux_lob_meta"; const char *const OB_ALL_TABLE_AUX_LOB_PIECE_TNAME = "__all_table_aux_lob_piece"; const char *const OB_ALL_COLUMN_AUX_LOB_PIECE_TNAME = "__all_column_aux_lob_piece"; const char *const OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TNAME = "__all_ddl_operation_aux_lob_piece"; @@ -4217,6 +4333,12 @@ const char *const OB_ALL_LOG_RESTORE_SOURCE_AUX_LOB_PIECE_TNAME = "__all_log_res const char *const OB_ALL_SERVICE_EPOCH_AUX_LOB_PIECE_TNAME = "__all_service_epoch_aux_lob_piece"; const char *const OB_ALL_SPATIAL_REFERENCE_SYSTEMS_AUX_LOB_PIECE_TNAME = "__all_spatial_reference_systems_aux_lob_piece"; const char *const OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_PIECE_TNAME = "__all_column_checksum_error_info_aux_lob_piece"; +const char *const OB_ALL_TRANSFER_TASK_AUX_LOB_PIECE_TNAME = "__all_transfer_task_aux_lob_piece"; +const char *const OB_ALL_TRANSFER_TASK_HISTORY_AUX_LOB_PIECE_TNAME = "__all_transfer_task_history_aux_lob_piece"; +const char *const OB_ALL_BALANCE_JOB_AUX_LOB_PIECE_TNAME = "__all_balance_job_aux_lob_piece"; +const char *const OB_ALL_BALANCE_JOB_HISTORY_AUX_LOB_PIECE_TNAME = "__all_balance_job_history_aux_lob_piece"; +const char *const OB_ALL_BALANCE_TASK_AUX_LOB_PIECE_TNAME = "__all_balance_task_aux_lob_piece"; +const char *const OB_ALL_BALANCE_TASK_HISTORY_AUX_LOB_PIECE_TNAME = "__all_balance_task_history_aux_lob_piece"; const char *const OB_ALL_ARBITRATION_SERVICE_AUX_LOB_PIECE_TNAME = "__all_arbitration_service_aux_lob_piece"; const char *const OB_ALL_LS_ARB_REPLICA_TASK_AUX_LOB_PIECE_TNAME = "__all_ls_arb_replica_task_aux_lob_piece"; const char *const OB_ALL_DATA_DICTIONARY_IN_LOG_AUX_LOB_PIECE_TNAME = "__all_data_dictionary_in_log_aux_lob_piece"; @@ -4234,9 +4356,11 @@ const char *const OB_ALL_RLS_ATTRIBUTE_HISTORY_AUX_LOB_PIECE_TNAME = "__all_rls_ const char *const OB_ALL_TENANT_REWRITE_RULES_AUX_LOB_PIECE_TNAME = "__all_tenant_rewrite_rules_aux_lob_piece"; const char *const OB_ALL_RESERVED_SNAPSHOT_AUX_LOB_PIECE_TNAME = "__all_reserved_snapshot_aux_lob_piece"; const char *const OB_ALL_CLUSTER_EVENT_HISTORY_AUX_LOB_PIECE_TNAME = "__all_cluster_event_history_aux_lob_piece"; +const char *const OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_PIECE_TNAME = "__all_ls_transfer_member_list_lock_info_aux_lob_piece"; const char *const OB_ALL_EXTERNAL_TABLE_FILE_AUX_LOB_PIECE_TNAME = "__all_external_table_file_aux_lob_piece"; const char *const OB_ALL_TASK_OPT_STAT_GATHER_HISTORY_AUX_LOB_PIECE_TNAME = "__all_task_opt_stat_gather_history_aux_lob_piece"; const char *const OB_ALL_TABLE_OPT_STAT_GATHER_HISTORY_AUX_LOB_PIECE_TNAME = "__all_table_opt_stat_gather_history_aux_lob_piece"; +const char *const OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TNAME = "__all_balance_task_helper_aux_lob_piece"; const char *const OB_ALL_VIRTUAL_PLAN_CACHE_STAT_ALL_VIRTUAL_PLAN_CACHE_STAT_I1_TNAME = "__idx_11003_all_virtual_plan_cache_stat_i1"; const char *const OB_ALL_VIRTUAL_SESSION_EVENT_ALL_VIRTUAL_SESSION_EVENT_I1_TNAME = "__idx_11013_all_virtual_session_event_i1"; const char *const OB_ALL_VIRTUAL_SESSION_WAIT_ALL_VIRTUAL_SESSION_WAIT_I1_TNAME = "__idx_11014_all_virtual_session_wait_i1"; diff --git a/src/share/inner_table/ob_inner_table_schema_def.py b/src/share/inner_table/ob_inner_table_schema_def.py index 419a3745b..039900e87 100644 --- a/src/share/inner_table/ob_inner_table_schema_def.py +++ b/src/share/inner_table/ob_inner_table_schema_def.py @@ -469,6 +469,7 @@ all_tablegroup_def = dict( ('partition_status', 'int', 'true', '0'), ('partition_schema_version', 'int', 'true', '0'), ('sub_part_template_flags', 'int', 'false', '0'), + ('sharding', 'varchar:OB_MAX_PARTITION_SHARDING_LENGTH', 'false', 'ADAPTIVE'), ], ) @@ -2860,6 +2861,9 @@ all_backup_set_files_def = dict( ('backup_compatible', 'int'), ('path', 'varchar:OB_INNER_TABLE_DEFAULT_VALUE_LENTH', 'true', ''), ('cluster_version', 'varchar:OB_INNER_TABLE_DEFAULT_VALUE_LENTH', 'false', ''), + ('consistent_scn', 'uint', 'false', '0'), + ('minor_turn_id', 'int', 'false', '0'), + ('major_turn_id', 'int', 'false', '0'), ], ) def_table_schema(**all_backup_set_files_def) @@ -3412,6 +3416,7 @@ def_table_schema( ('data_size', 'int'), ('required_size', 'int', 'false', '0'), ('learner_list', 'longtext', 'true'), + ('rebuild', 'int', 'false', '0'), ], ) @@ -3429,6 +3434,7 @@ def_table_schema( normal_columns = [ ('ls_id', 'int'), ('table_id', 'int'), + ('transfer_seq', 'int', 'false', '0'), ], ) @@ -3832,6 +3838,8 @@ def_table_schema( ('result', 'int', 'true', '0'), ('comment', 'varchar:OB_INNER_TABLE_DEFAULT_VALUE_LENTH', 'true', ''), ('path', 'varchar:OB_INNER_TABLE_DEFAULT_VALUE_LENTH', 'true', ''), + ('minor_turn_id', 'int', 'false', '0'), + ('major_turn_id', 'int', 'false', '0'), ], ) def_table_schema( @@ -3873,6 +3881,8 @@ def_table_schema( ('result', 'int', 'true', '0'), ('comment', 'varchar:OB_INNER_TABLE_DEFAULT_VALUE_LENTH', 'true', ''), ('path', 'varchar:OB_INNER_TABLE_DEFAULT_VALUE_LENTH', 'true', ''), + ('minor_turn_id', 'int', 'false', '0'), + ('major_turn_id', 'int', 'false', '0'), ], ) def_table_schema( @@ -3916,6 +3926,7 @@ def_table_schema( ('retry_id', 'int', 'true', '0'), ('result', 'int', 'true', '0'), ('comment', 'varchar:OB_INNER_TABLE_DEFAULT_VALUE_LENTH', 'true', ''), + ('max_tablet_checkpoint_scn', 'uint'), ], ) def_table_schema( @@ -3959,6 +3970,7 @@ def_table_schema( ('retry_id', 'int', 'true', '0'), ('result', 'int', 'true', '0'), ('comment', 'varchar:OB_INNER_TABLE_DEFAULT_VALUE_LENTH', 'true', ''), + ('max_tablet_checkpoint_scn', 'uint'), ], ) def_table_schema( @@ -4064,6 +4076,7 @@ def_table_schema( ('readable_scn', 'uint'), ('recovery_until_scn', 'uint', 'false', 'OB_MAX_SCN_TS_NS'), ('log_mode', 'varchar:100', 'false', 'NOARCHIVELOG'), + ('max_ls_id', 'int', 'false', '0'), ], ) @@ -5164,12 +5177,107 @@ def_table_schema( # 420 : __all_column_group_history # 421 : __all_column_group_mapping # 422 : __all_column_group_mapping_history -# 423 : __all_transfer_task -# 424 : __all_transfer_task_history -# 425 : __all_balance_task -# 426 : __all_balance_task_history -# 427 : __all_ls_balance_job -# 428 : __all_ls_balance_job_history + +all_transfer_task_def = dict( + owner = 'wangzhennan.wzn', + table_name = '__all_transfer_task', + table_id = '423', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('task_id', 'int'), + ], + + in_tenant_space = True, + is_cluster_private = False, + meta_record_in_sys = False, + + normal_columns = [ + ('src_ls', 'int', 'false'), + ('dest_ls', 'int', 'false'), + ('part_list', 'longtext', 'true'), + ('part_count', 'int', 'true'), + ('not_exist_part_list', 'longtext', 'true'), + ('lock_conflict_part_list', 'longtext', 'true'), + ('table_lock_tablet_list', 'longtext', 'true'), + ('tablet_list', 'longtext', 'true'), + ('tablet_count', 'int', 'true'), + ('start_scn', 'uint', 'true'), + ('finish_scn', 'uint', 'true'), + ('status', 'varchar:OB_DEFAULT_STATUS_LENTH', 'false'), + ('trace_id', 'varchar:OB_MAX_TRACE_ID_BUFFER_SIZE', 'false'), + ('result', 'int', 'true'), + ('comment', 'longtext', 'true'), + ('balance_task_id', 'int', 'false'), + ('table_lock_owner_id', 'int', 'true'), + ], +) +def_table_schema(**all_transfer_task_def) + +def_table_schema(**gen_history_table_def_of_task(424, all_transfer_task_def)) + +all_balance_job_def= dict( + owner = 'msy164651', + table_name = '__all_balance_job', + table_id = '425', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('job_id', 'int'), + ], + + in_tenant_space = True, + is_cluster_private = False, + meta_record_in_sys = False, + + normal_columns = [ + ('balance_strategy_name', 'varchar:OB_DEFAULT_STATUS_LENTH', 'false'), + ('job_type', 'varchar:OB_DEFAULT_STATUS_LENTH', 'false'), + ('target_unit_num', 'int', 'false'), + ('target_primary_zone_num', 'int', 'false'), + ('status', 'varchar:OB_DEFAULT_STATUS_LENTH', 'false'), + ('comment', 'longtext', 'true'), + ], +) + +def_table_schema(**all_balance_job_def) +def_table_schema(**gen_history_table_def_of_task(426, all_balance_job_def)) + +all_balance_task_def= dict( + owner = 'msy164651', + table_name = '__all_balance_task', + table_id = '427', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('task_id', 'int'), + ], + + in_tenant_space = True, + is_cluster_private = False, + meta_record_in_sys = False, + + normal_columns = [ + ('task_type', 'varchar:OB_DEFAULT_STATUS_LENTH', 'false'), + ('src_ls', 'int', 'false'), + ('dest_ls', 'int', 'false'), + ('part_list', 'longtext', 'true'), + ('finished_part_list', 'longtext', 'true'), + ('part_count', 'int', 'true'), + ('finished_part_count', 'int', 'true'), + ('ls_group_id','int', 'false'), + ('status', 'varchar:OB_DEFAULT_STATUS_LENTH', 'false'), + ('parent_list', 'varchar:OB_MAX_SYS_PARAM_VALUE_LENGTH', 'true'), + ('child_list', 'varchar:OB_MAX_SYS_PARAM_VALUE_LENGTH', 'true'), + ('current_transfer_task_id', 'int', 'false'), + ('job_id', 'int', 'false'), + ('comment', 'longtext', 'true'), + ], +) +def_table_schema(**all_balance_task_def) + +def_table_schema(**gen_history_table_def_of_task(428, all_balance_task_def)) + def_table_schema( owner = 'jingyu.cr', @@ -5455,10 +5563,30 @@ def_table_schema( ('extra_info', 'varchar:MAX_CLUSTER_EVENT_VALUE_LENGTH', 'false', '') ], ) -# 446 : __all_ls_transfer_member_list_lock_info + +def_table_schema( + owner = 'yangyi.yyy', + table_name = '__all_ls_transfer_member_list_lock_info', + table_id = '446', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('tenant_id', 'int'), + ('ls_id', 'int'), + ], + in_tenant_space = True, + is_cluster_private = True, + meta_record_in_sys = False, + + normal_columns = [ + ('task_id', 'int'), + ('status', 'varchar:OB_INNER_TABLE_DEFAULT_VALUE_LENTH'), + ('lock_owner', 'int'), + ('comment', 'longtext', 'true'), + ], +) # 447 : __all_ls_log_restore_stat # 448 : __all_backup_transferring_tablets - # 449 : __all_wait_for_partition_split_tablet def_table_schema( @@ -5542,8 +5670,27 @@ def_table_schema( # 456 : __wr_snapshot # 457 : __wr_statname # 458 : __wr_sysstat -# 459 : __all_balance_task_helper +def_table_schema( + owner = 'msy164651', + table_name = '__all_balance_task_helper', + table_id = '459', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('operation_scn', 'uint', 'false'), + ], + in_tenant_space = True, + is_cluster_private = True, + meta_record_in_sys = False, + + normal_columns = [ + ('operation_type', 'varchar:OB_DEFAULT_STATUS_LENTH', 'false', ''), + ('src_ls', 'int', 'false'), + ('dest_ls', 'int', 'false'), + ('ls_group_id', 'int', 'false'), + ], +) # 460 : __all_tenant_snapshots # 461 : __all_tenant_snapshot_ls # 462 : __all_tenant_snapshot_ls_meta_table @@ -5558,6 +5705,9 @@ def_table_schema( # 470 : __all_mview_refresh_stmt_stats ################################################################################ + + + # Virtual Table (10000, 20000] # Normally, virtual table's index_using_type should be USING_HASH. ################################################################################ @@ -5973,6 +6123,7 @@ def_table_schema( ('data_size', 'int'), ('required_size', 'int', 'false', '0'), ('learner_list', 'longtext', 'true'), + ('rebuild', 'int', 'false', '0'), ], ) @@ -7400,8 +7551,10 @@ def_table_schema( ('total_count', 'int'), ('reserved_count', 'int'), ('meta_block_count', 'int'), + ('shared_meta_block_count', 'int'), ('tmp_file_count', 'int'), ('data_block_count', 'int'), + ('shared_data_block_count', 'int'), ('disk_block_count', 'int'), ('bloomfilter_count', 'int'), ('hold_count', 'int'), @@ -7411,6 +7564,7 @@ def_table_schema( ('sweep_cost_time', 'int'), ('start_time', 'timestamp'), ('last_end_time', 'timestamp'), + ('mark_finished', 'bool'), ('comment', 'varchar:MAX_TABLE_COMMENT_LENGTH', 'false', ''), ], partition_columns = ['svr_ip', 'svr_port'], @@ -10210,6 +10364,8 @@ def_table_schema( normal_columns = [ ('tenant_id', 'int'), + ('svr_ip', 'varchar:MAX_IP_ADDR_LENGTH'), + ('svr_port', 'int'), ('job_id', 'int'), ('task_id', 'int'), ('ls_id', 'int'), @@ -10221,7 +10377,9 @@ def_table_schema( ('schedule_ts', 'int'), ('executor_ts', 'int'), ], - vtable_route_policy = 'only_rs', + + partition_columns = ['svr_ip', 'svr_port'], + vtable_route_policy = 'distributed', ) def_table_schema(**gen_iterate_virtual_table_def( @@ -10626,7 +10784,8 @@ def_table_schema( ('checkpoint_lsn', 'uint'), ('migrate_status', 'int'), ('rebuild_seq', 'int'), - ('tablet_change_checkpoint_scn_', 'uint'), + ('tablet_change_checkpoint_scn', 'uint'), + ('transfer_scn', 'uint'), ], partition_columns = ['svr_ip', 'svr_port'], vtable_route_policy = 'distributed', @@ -10652,6 +10811,13 @@ def_table_schema( ('checkpoint_scn', 'uint'), ('compaction_scn', 'uint'), ('multi_version_start', 'uint'), + ('transfer_start_scn', 'uint'), + ('transfer_seq', 'int'), + ('has_transfer_table', 'int'), + ('restore_status', 'int'), + ('tablet_status', 'int'), + ('is_committed', 'int'), + ('is_empty_shell', 'int'), ], partition_columns = ['svr_ip', 'svr_port'], vtable_route_policy = 'distributed', @@ -11019,7 +11185,10 @@ def_table_schema( ('pointer_ref', 'int'), ('in_memory', 'bool'), ('tablet_ref', 'int'), - ('wash_score', 'int') + ('wash_score', 'int'), + ('tablet_ptr', 'varchar:128'), + ('initial_state', 'bool'), + ('old_chain', 'varchar:128'), ], partition_columns = ['svr_ip', 'svr_port'], vtable_route_policy = 'distributed', @@ -11042,7 +11211,7 @@ def_table_schema( ('total_size', 'int'), ('used_obj_cnt', 'int'), ('free_obj_cnt', 'int'), - ('each_obj_size', 'int') + ('each_obj_size', 'int'), ], partition_columns = ['svr_ip', 'svr_port'], vtable_route_policy = 'distributed', @@ -11371,12 +11540,36 @@ def_table_schema(**gen_iterate_virtual_table_def( table_name = '__all_virtual_data_dictionary_in_log', keywords = all_def_keywords['__all_data_dictionary_in_log'])) -# 12342: __all_virtual_transfer_task -# 12343: __all_virtual_transfer_task_history -# 12344: __all_virtual_balance_job -# 12345: __all_virtual_balance_job_history -# 12346: __all_virtual_balance_task -# 12347: __all_virtual_balance_task_history +def_table_schema(**gen_iterate_virtual_table_def( + table_id = '12342', + table_name = '__all_virtual_transfer_task', + keywords = all_def_keywords['__all_transfer_task'])) + +def_table_schema(**gen_iterate_virtual_table_def( + table_id = '12343', + table_name = '__all_virtual_transfer_task_history', + keywords = all_def_keywords['__all_transfer_task_history'])) + +def_table_schema(**gen_iterate_virtual_table_def( + table_id = '12344', + table_name = '__all_virtual_balance_job', + keywords = all_def_keywords['__all_balance_job'])) + +def_table_schema(**gen_iterate_virtual_table_def( + table_id = '12345', + table_name = '__all_virtual_balance_job_history', + keywords = all_def_keywords['__all_balance_job_history'])) + +def_table_schema(**gen_iterate_virtual_table_def( + table_id = '12346', + table_name = '__all_virtual_balance_task', + keywords = all_def_keywords['__all_balance_task'])) + +def_table_schema(**gen_iterate_virtual_table_def( + table_id = '12347', + table_name = '__all_virtual_balance_task_history', + keywords = all_def_keywords['__all_balance_task_history'])) + def_table_schema(**gen_iterate_virtual_table_def( table_id = '12348', @@ -11593,8 +11786,75 @@ def_table_schema(**gen_iterate_virtual_table_def( keywords = all_def_keywords['__all_external_table_file'])) # 12372: __all_virtual_io_tracer -# 12373: __all_virtual_mds_node_stat -# 12374: __all_virtual_mds_event_history + +def_table_schema( + owner = 'xuwang.txw', + table_name = '__all_virtual_mds_node_stat', + table_id = '12373', + table_type = 'VIRTUAL_TABLE', + in_tenant_space = True, + gm_columns = [], + rowkey_columns = [ + ('tenant_id', 'int'), + ('ls_id', 'bigint'), + ('tablet_id', 'bigint'), + ], + normal_columns = [ + ('svr_ip', 'varchar:MAX_IP_ADDR_LENGTH'), + ('svr_port', 'int'), + ('unit_id', 'bigint'), + ('user_key', 'longtext'), + ('version_idx', 'bigint'), + ('writer_type', 'longtext'), + ('writer_id', 'bigint'), + ('seq_no', 'bigint'), + ('redo_scn', 'uint'), + ('end_scn', 'uint'), + ('trans_version', 'uint'), + ('node_type', 'longtext'), + ('state', 'longtext'), + ('position', 'longtext'), + ('user_data', 'longtext') + ], + partition_columns = ['svr_ip', 'svr_port'], + vtable_route_policy = 'distributed', +) + +def_table_schema( + owner = 'xuwang.txw', + table_name = '__all_virtual_mds_event_history', + table_id = '12374', + table_type = 'VIRTUAL_TABLE', + in_tenant_space = True, + gm_columns = [], + rowkey_columns = [ + ('tenant_id', 'int'), + ('ls_id', 'bigint'), + ('tablet_id', 'bigint'), + ], + normal_columns = [ + ('svr_ip', 'varchar:MAX_IP_ADDR_LENGTH'), + ('svr_port', 'int'), + ('tid', 'int'),# common info + ('tname', 'longtext'),# common info + ('trace', 'longtext'),# common info + ('timestamp', 'timestamp'),# common info + ('event', 'longtext'),# common info + ('info', 'longtext'),# common info + ('unit_id', 'bigint'),# unit info + ('user_key', 'longtext'),# row info + ('writer_type', 'longtext'),# node info + ('writer_id', 'bigint'),# node info + ('seq_no', 'bigint'),# node info + ('redo_scn', 'uint'),# node info + ('end_scn', 'uint'),# node info + ('trans_version', 'uint'),# node info + ('node_type', 'longtext'),# node info + ('state', 'longtext')# node info + ], + partition_columns = ['svr_ip', 'svr_port'], + vtable_route_policy = 'distributed', +) # 12375: __all_virtual_time_guard_slow_history def_table_schema( owner = 'wyh329796', @@ -11628,6 +11888,7 @@ def_table_schema( vtable_route_policy = 'distributed', ) # 12377: __all_virtual_dup_ls_follower_lease_info + def_table_schema( owner = 'wyh329796', table_name = '__all_virtual_dup_ls_tablet_set', @@ -11833,7 +12094,12 @@ def_table_schema( # 12391: __all_virtual_wr_sysstat # 12392: __all_virtual_kv_connection def_table_schema(**gen_mysql_sys_agent_virtual_table_def('12393', all_def_keywords['__all_virtual_long_ops_status'])) -# 12394: __all_virtual_ls_transfer_member_list_lock_info + +def_table_schema(**gen_iterate_private_virtual_table_def( + table_id = '12394', + table_name = '__all_virtual_ls_transfer_member_list_lock_info', + in_tenant_space = True, + keywords = all_def_keywords['__all_ls_transfer_member_list_lock_info'])) def_table_schema( owner = 'lixinze.lxz', @@ -11857,7 +12123,7 @@ def_table_schema( vtable_route_policy = 'distributed', ) -# 12396: __all_virtual_resource_pool_mysql_sys_agent +def_table_schema(**gen_mysql_sys_agent_virtual_table_def('12396', all_def_keywords['__all_resource_pool'])) def_table_schema( owner = 'mingdou.tmd', @@ -11909,19 +12175,47 @@ def_table_schema( vtable_route_policy = 'distributed', ) -# 12401: __all_virtual_tenant_parameter +def_table_schema(**gen_iterate_private_virtual_table_def( + table_id = '12401', + table_name = '__all_virtual_tenant_parameter', + in_tenant_space = True, + keywords = all_def_keywords['__tenant_parameter'])) + # 12402: __all_virtual_tenant_snapshots # 12403: __all_virtual_tenant_snapshot_ls # 12404: __all_virtual_tenant_snapshot_ls_meta_table -# 12405: __all_virtual_mlogs -# 12406: __all_virtual_mviews -# 12407: __all_virtual_mview_refresh_stats_sys_defaults -# 12408: __all_virtual_mview_refresh_stats_params -# 12409: __all_virtual_mview_refresh_run_stats -# 12410: __all_virtual_mview_refresh_stats -# 12411: __all_virtual_mview_refresh_change_stats -# 12412: __all_virtual_mview_refresh_stmt_stats +def_table_schema( + owner = 'zhouxinlan.zxl', + table_name = '__all_virtual_tablet_buffer_info', + table_id = '12405', + table_type = 'VIRTUAL_TABLE', + gm_columns = [], + rowkey_columns = [ + ('svr_ip', 'varchar:MAX_IP_ADDR_LENGTH'), + ('svr_port', 'int'), + ('tenant_id', 'int'), + ('tablet buffer', 'varchar:128'), + ], + + normal_columns = [ + ('tablet', 'varchar:128'), + ('pool type', 'varchar:128'), + ('ls_id', 'int'), + ('tablet_id', 'int'), + ('in_map', 'bool'), + ('last_access_time', 'timestamp'), + ] +) + +# 12406: __all_virtual_mlogs +# 12407: __all_virtual_mviews +# 12408: __all_virtual_mview_refresh_stats_sys_defaults +# 12409: __all_virtual_mview_refresh_stats_params +# 12410: __all_virtual_mview_refresh_run_stats +# 12411: __all_virtual_mview_refresh_stats +# 12412: __all_virtual_mview_refresh_change_stats +# 12413: __all_virtual_mview_refresh_stmt_stats # 余留位置 # @@ -12268,18 +12562,19 @@ def_table_schema(**gen_oracle_mapping_virtual_table_def('15305', all_def_keyword def_table_schema(**gen_oracle_mapping_virtual_table_def('15376', all_def_keywords['__all_virtual_log_restore_source'])) -# 15377: __all_virtual_balance_job -# 15378: __all_virtual_balance_job_history -# 15379: __all_virtual_balance_task -# 15380: __all_virtual_balance_task_history -# 15381: __all_virtual_transfer_task -# 15382: __all_virtual_transfer_task_history -# 15383: __all_virtual_resource_pool_sys_agent + +def_table_schema(**no_direct_access(gen_oracle_mapping_real_virtual_table_def('15377', all_def_keywords['__all_balance_job']))) +def_table_schema(**no_direct_access(gen_oracle_mapping_real_virtual_table_def('15378', all_def_keywords['__all_balance_job_history']))) +def_table_schema(**no_direct_access(gen_oracle_mapping_real_virtual_table_def('15379', all_def_keywords['__all_balance_task']))) +def_table_schema(**no_direct_access(gen_oracle_mapping_real_virtual_table_def('15380', all_def_keywords['__all_balance_task_history']))) +def_table_schema(**no_direct_access(gen_oracle_mapping_real_virtual_table_def('15381', all_def_keywords['__all_transfer_task']))) +def_table_schema(**no_direct_access(gen_oracle_mapping_real_virtual_table_def('15382', all_def_keywords['__all_transfer_task_history']))) +def_table_schema(**no_direct_access(gen_sys_agent_virtual_table_def('15383', all_def_keywords['__all_resource_pool']))) def_table_schema(**no_direct_access(gen_oracle_mapping_virtual_table_def('15384', all_def_keywords['__all_virtual_px_p2p_datahub']))) def_table_schema(**no_direct_access(gen_oracle_mapping_virtual_table_def('15385', all_def_keywords['__all_virtual_timestamp_service']))) # 15386: __all_virtual_column_group def_table_schema(**no_direct_access(gen_oracle_mapping_virtual_table_def('15387', all_def_keywords['__all_virtual_ls_log_restore_status']))) -# 15388: __all_virtual_tenant_parameter +def_table_schema(**no_direct_access(gen_oracle_mapping_virtual_table_def('15388', all_def_keywords['__all_virtual_tenant_parameter']))) # 15389: __all_mlogs # 15390: __all_mviews @@ -15574,7 +15869,10 @@ def_table_schema( TENANT_COMPATIBLE, BACKUP_COMPATIBLE, PATH, - CLUSTER_VERSION + CLUSTER_VERSION, + CONSISTENT_SCN, + MINOR_TURN_ID, + MAJOR_TURN_ID FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_SET_FILES """.replace("\n", " ") ) @@ -15901,7 +16199,9 @@ def_table_schema( DATA_TURN_ID, RESULT, COMMENT, - PATH + PATH, + MINOR_TURN_ID, + MAJOR_TURN_ID FROM OCEANBASE.__all_virtual_backup_task """.replace("\n", " ") ) @@ -15952,7 +16252,9 @@ def_table_schema( DATA_TURN_ID, RESULT, COMMENT, - PATH + PATH, + MINOR_TURN_ID, + MAJOR_TURN_ID FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_TASK_HISTORY """.replace("\n", " ") ) @@ -16062,10 +16364,30 @@ SELECT A.TENANT_ID, WHEN (A.TENANT_ID & 0x1) = 1 THEN 'NOARCHIVELOG' ELSE LOG_MODE END) AS LOG_MODE, - ARBITRATION_SERVICE_STATUS + ARBITRATION_SERVICE_STATUS, + UNIT_NUM, + COMPATIBLE FROM OCEANBASE.__ALL_VIRTUAL_TENANT_MYSQL_SYS_AGENT AS A LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TENANT_INFO AS B ON A.TENANT_ID = B.TENANT_ID +LEFT JOIN + (SELECT TENANT_ID, + (CASE + WHEN TENANT_ID < 1 THEN NULL + WHEN TENANT_ID != 1 THEN TENANT_ID - 1 + ELSE NULL + END) AS META_TENANT_ID, + MIN(UNIT_COUNT) AS UNIT_NUM + FROM OCEANBASE.__ALL_VIRTUAL_RESOURCE_POOL_MYSQL_SYS_AGENT + GROUP BY TENANT_ID) AS C + ON A.TENANT_ID = C.TENANT_ID OR A.TENANT_ID = C.META_TENANT_ID +LEFT JOIN + (SELECT TENANT_ID, + MIN(VALUE) AS COMPATIBLE + FROM OCEANBASE.__ALL_VIRTUAL_TENANT_PARAMETER + WHERE NAME = 'compatible' + GROUP BY TENANT_ID) AS D + ON A.TENANT_ID = D.TENANT_ID """.replace("\n", " ") ) @@ -16423,7 +16745,10 @@ def_table_schema( WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, - (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST + (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST, + (CASE REBUILD + WHEN 0 THEN "FALSE" + ELSE "TRUE" END) AS REBUILD FROM OCEANBASE.__ALL_VIRTUAL_CORE_META_TABLE WHERE EFFECTIVE_TENANT_ID() = 1 @@ -16446,7 +16771,10 @@ def_table_schema( WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, - (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST + (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST, + (CASE REBUILD + WHEN 0 THEN "FALSE" + ELSE "TRUE" END) AS REBUILD FROM OCEANBASE.__ALL_VIRTUAL_LS_META_TABLE WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TENANT_ID != 1 @@ -16482,7 +16810,10 @@ def_table_schema( WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, - (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST + (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST, + (CASE REBUILD + WHEN 0 THEN "FALSE" + ELSE "TRUE" END) AS REBUILD FROM OCEANBASE.__ALL_VIRTUAL_CORE_META_TABLE ) UNION ALL @@ -16504,7 +16835,10 @@ def_table_schema( WHEN 16 THEN "READONLY" WHEN 261 THEN "ENCRYPTION LOGONLY" ELSE NULL END) AS REPLICA_TYPE, - (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST + (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE "" END) AS LEARNER_LIST, + (CASE REBUILD + WHEN 0 THEN "FALSE" + ELSE "TRUE" END) AS REBUILD FROM OCEANBASE.__ALL_VIRTUAL_LS_META_TABLE WHERE TENANT_ID != 1 ) @@ -16645,52 +16979,19 @@ def_table_schema( """ SELECT TABLEGROUP_NAME, - (CASE PART_LEVEL - WHEN 0 THEN 'NONE' - ELSE (CASE PART_FUNC_TYPE - WHEN 0 THEN 'HASH' - WHEN 1 THEN 'KEY' - WHEN 2 THEN 'KEY' - WHEN 3 THEN 'RANGE' - WHEN 4 THEN 'RANGE COLUMNS' - WHEN 5 THEN 'LIST' - WHEN 6 THEN 'LIST COLUMNS' - WHEN 7 THEN 'UNKNOWN' - ELSE 'UNKNOWN' - END) - END) AS PARTITIONING_TYPE, + CAST("NONE" AS CHAR(13)) AS PARTITIONING_TYPE, - (CASE PART_LEVEL - WHEN 2 THEN (CASE SUB_PART_FUNC_TYPE - WHEN 0 THEN 'HASH' - WHEN 1 THEN 'KEY' - WHEN 2 THEN 'KEY' - WHEN 3 THEN 'RANGE' - WHEN 4 THEN 'RANGE COLUMNS' - WHEN 5 THEN 'LIST' - WHEN 6 THEN 'LIST COLUMNS' - WHEN 7 THEN 'UNKNOWN' - ELSE 'UNKNOWN' - END) - ELSE 'NONE' - END) AS SUBPARTITIONING_TYPE, + CAST("NONE" AS CHAR(13)) AS SUBPARTITIONING_TYPE, - (CASE PART_LEVEL - WHEN 0 THEN NULL - ELSE PART_NUM - END) AS PARTITION_COUNT, + CAST(NULL AS SIGNED) AS PARTITION_COUNT, CAST(NULL AS SIGNED) AS DEF_SUBPARTITION_COUNT, - (CASE PART_LEVEL - WHEN 0 THEN NULL - ELSE PART_FUNC_EXPR_NUM - END) AS PARTITIONING_KEY_COUNT, + CAST(NULL AS SIGNED) AS PARTITIONING_KEY_COUNT, - (CASE PART_LEVEL - WHEN 2 THEN SUB_PART_FUNC_EXPR_NUM - ELSE NULL - END) AS SUBPARTITIONING_KEY_COUNT + CAST(NULL AS SIGNED) AS SUBPARTITIONING_KEY_COUNT, + + SHARDING FROM OCEANBASE.__ALL_TABLEGROUP """.replace("\n", " "), @@ -16710,52 +17011,19 @@ def_table_schema( TABLEGROUP_NAME, - (CASE PART_LEVEL - WHEN 0 THEN 'NONE' - ELSE (CASE PART_FUNC_TYPE - WHEN 0 THEN 'HASH' - WHEN 1 THEN 'KEY' - WHEN 2 THEN 'KEY' - WHEN 3 THEN 'RANGE' - WHEN 4 THEN 'RANGE COLUMNS' - WHEN 5 THEN 'LIST' - WHEN 6 THEN 'LIST COLUMNS' - WHEN 7 THEN 'UNKNOWN' - ELSE 'UNKNOWN' - END) - END) AS PARTITIONING_TYPE, + CAST("NONE" AS CHAR(13)) AS PARTITIONING_TYPE, - (CASE PART_LEVEL - WHEN 2 THEN (CASE SUB_PART_FUNC_TYPE - WHEN 0 THEN 'HASH' - WHEN 1 THEN 'KEY' - WHEN 2 THEN 'KEY' - WHEN 3 THEN 'RANGE' - WHEN 4 THEN 'RANGE COLUMNS' - WHEN 5 THEN 'LIST' - WHEN 6 THEN 'LIST COLUMNS' - WHEN 7 THEN 'UNKNOWN' - ELSE 'UNKNOWN' - END) - ELSE 'NONE' - END) AS SUBPARTITIONING_TYPE, + CAST("NONE" AS CHAR(13)) AS SUBPARTITIONING_TYPE, - (CASE PART_LEVEL - WHEN 0 THEN NULL - ELSE PART_NUM - END) AS PARTITION_COUNT, + CAST(NULL AS SIGNED) AS PARTITION_COUNT, - CAST(NULL AS SIGNED) AS DEF_SUBPARTITION_COUNT, + CAST(NULL AS SIGNED) AS DEF_SUBPARTITION_COUNT, - (CASE PART_LEVEL - WHEN 0 THEN NULL - ELSE PART_FUNC_EXPR_NUM - END) AS PARTITIONING_KEY_COUNT, + CAST(NULL AS SIGNED) AS PARTITIONING_KEY_COUNT, - (CASE PART_LEVEL - WHEN 2 THEN SUB_PART_FUNC_EXPR_NUM - ELSE NULL - END) AS SUBPARTITIONING_KEY_COUNT + CAST(NULL AS SIGNED) AS SUBPARTITIONING_KEY_COUNT, + + SHARDING FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP """.replace("\n", " "), @@ -16772,41 +17040,23 @@ def_table_schema( in_tenant_space = True, view_definition = """ - SELECT T.TABLEGROUP_NAME AS TABLEGROUP_NAME, + SELECT CAST("" AS CHAR(128)) AS TABLEGROUP_NAME, - (CASE T.PART_LEVEL - WHEN 2 THEN 'YES' - ELSE 'NO' - END) AS COMPOSITE, + CAST("NO" AS CHAR(3)) AS COMPOSITE, - P.PART_NAME AS PARTITION_NAME, + CAST("" AS CHAR(64)) AS PARTITION_NAME, - (CASE T.PART_LEVEL - WHEN 2 THEN P.SUB_PART_NUM - ELSE NULL - END) AS SUBPARTITION_COUNT, + CAST(NULL AS SIGNED) AS SUBPARTITION_COUNT, - (CASE - WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL - WHEN LENGTH(P.LIST_VAL) > 0 THEN P.LIST_VAL - ELSE NULL - END) AS HIGH_VALUE, + CAST(NULL AS CHAR(4096)) AS HIGH_VALUE, - (CASE - WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN LENGTH(P.HIGH_BOUND_VAL) - WHEN LENGTH(P.LIST_VAL) > 0 THEN LENGTH(P.LIST_VAL) - ELSE NULL - END) AS HIGH_VALUE_LENGTH, + CAST(NULL AS SIGNED) AS HIGH_VALUE_LENGTH, - P.PARTITION_POSITION AS PARTITION_POSITION - FROM OCEANBASE.__ALL_TABLEGROUP AS T - JOIN (SELECT *, - ROW_NUMBER() OVER ( - PARTITION BY TENANT_ID, TABLE_ID - ORDER BY PART_IDX, PART_ID ASC - ) AS PARTITION_POSITION - FROM OCEANBASE.__ALL_PART) AS P - ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID + CAST(NULL AS UNSIGNED) AS PARTITION_POSITION + FROM + DUAL + WHERE + 0 = 1 """.replace("\n", " "), ) @@ -16820,43 +17070,25 @@ def_table_schema( normal_columns = [], view_definition = """ - SELECT T.TENANT_ID AS TENANT_ID, + SELECT CAST(NULL AS SIGNED) AS TENANT_ID, - T.TABLEGROUP_NAME AS TABLEGROUP_NAME, + CAST('' AS CHAR(128)) AS TABLEGROUP_NAME, - (CASE T.PART_LEVEL - WHEN 2 THEN 'YES' - ELSE 'NO' - END) AS COMPOSITE, + CAST('NO' AS CHAR(3)) AS COMPOSITE, - P.PART_NAME AS PARTITION_NAME, + CAST('' AS CHAR(64)) AS PARTITION_NAME, - (CASE T.PART_LEVEL - WHEN 2 THEN P.SUB_PART_NUM - ELSE NULL - END) AS SUBPARTITION_COUNT, + CAST(NULL AS SIGNED) AS SUBPARTITION_COUNT, - (CASE - WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL - WHEN LENGTH(P.LIST_VAL) > 0 THEN P.LIST_VAL - ELSE NULL - END) AS HIGH_VALUE, + CAST(NULL AS CHAR(4096)) AS HIGH_VALUE, - (CASE - WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN LENGTH(P.HIGH_BOUND_VAL) - WHEN LENGTH(P.LIST_VAL) > 0 THEN LENGTH(P.LIST_VAL) - ELSE NULL - END) AS HIGH_VALUE_LENGTH, + CAST(NULL AS SIGNED) AS HIGH_VALUE_LENGTH, - P.PARTITION_POSITION AS PARTITION_POSITION - FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP AS T - JOIN (SELECT *, - ROW_NUMBER() OVER ( - PARTITION BY TENANT_ID, TABLE_ID - ORDER BY PART_IDX, PART_ID ASC - ) AS PARTITION_POSITION - FROM OCEANBASE.__ALL_VIRTUAL_PART) AS P - ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID + CAST(NULL AS UNSIGNED) AS PARTITION_POSITION + FROM + DUAL + WHERE + 0 = 1 """.replace("\n", " "), ) @@ -16871,45 +17103,23 @@ def_table_schema( in_tenant_space = True, view_definition = """ - SELECT T.TABLEGROUP_NAME AS TABLEGROUP_NAME, + SELECT CAST("" AS CHAR(128)) AS TABLEGROUP_NAME, - P.PART_NAME AS PARTITION_NAME, + CAST("" AS CHAR(64)) AS PARTITION_NAME, - SP.SUB_PART_NAME AS SUBPARTITION_NAME, + CAST("" AS CHAR(64)) AS SUBPARTITION_NAME, - (CASE - WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL - WHEN LENGTH(SP.LIST_VAL) > 0 THEN SP.LIST_VAL - ELSE NULL - END) AS HIGH_VALUE, + CAST(NULL AS CHAR(4096)) AS HIGH_VALUE, - (CASE - WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN LENGTH(SP.HIGH_BOUND_VAL) - WHEN LENGTH(SP.LIST_VAL) > 0 THEN LENGTH(SP.LIST_VAL) - ELSE NULL - END) AS HIGH_VALUE_LENGTH, + CAST(NULL AS SIGNED) AS HIGH_VALUE_LENGTH, - P.PARTITION_POSITION AS PARTITION_POSITION, + CAST(NULL AS UNSIGNED) AS PARTITION_POSITION, - SP.SUBPARTITION_POSITION AS SUBPARTITION_POSITION - - FROM OCEANBASE.__ALL_TABLEGROUP AS T - - JOIN (SELECT *, - ROW_NUMBER() OVER ( - PARTITION BY TENANT_ID, TABLE_ID - ORDER BY PART_IDX, PART_ID ASC - ) AS PARTITION_POSITION - FROM OCEANBASE.__ALL_PART) AS P - ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID - - JOIN (SELECT *, - ROW_NUMBER() OVER ( - PARTITION BY TENANT_ID, TABLE_ID, PART_ID - ORDER BY SUB_PART_IDX, SUB_PART_ID ASC - ) AS SUBPARTITION_POSITION - FROM OCEANBASE.__ALL_SUB_PART) AS SP - ON P.TENANT_ID = SP.TENANT_ID AND P.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID + CAST(NULL AS UNSIGNED) AS SUBPARTITION_POSITION + FROM + DUAL + WHERE + 0 = 1 """.replace("\n", " "), ) @@ -16923,47 +17133,26 @@ def_table_schema( normal_columns = [], view_definition = """ - SELECT T.TENANT_ID AS TENANT_ID, + SELECT CAST(NULL AS SIGNED) AS TENANT_ID, - T.TABLEGROUP_NAME AS TABLEGROUP_NAME, + CAST("" AS CHAR(128)) AS TABLEGROUP_NAME, - P.PART_NAME AS PARTITION_NAME, + CAST("" AS CHAR(64)) AS PARTITION_NAME, - SP.SUB_PART_NAME AS SUBPARTITION_NAME, + CAST("" AS CHAR(64)) AS SUBPARTITION_NAME, - (CASE - WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL - WHEN LENGTH(SP.LIST_VAL) > 0 THEN SP.LIST_VAL - ELSE NULL - END) AS HIGH_VALUE, + CAST(NULL AS CHAR(4096)) AS HIGH_VALUE, - (CASE - WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN LENGTH(SP.HIGH_BOUND_VAL) - WHEN LENGTH(SP.LIST_VAL) > 0 THEN LENGTH(SP.LIST_VAL) - ELSE NULL - END) AS HIGH_VALUE_LENGTH, + CAST(NULL AS SIGNED) AS HIGH_VALUE_LENGTH, - P.PARTITION_POSITION AS PARTITION_POSITION, + CAST(NULL AS UNSIGNED) AS PARTITION_POSITION, - SP.SUBPARTITION_POSITION AS SUBPARTITION_POSITION + CAST(NULL AS UNSIGNED) AS SUBPARTITION_POSITION - FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP AS T - - JOIN (SELECT *, - ROW_NUMBER() OVER ( - PARTITION BY TENANT_ID, TABLE_ID - ORDER BY PART_IDX, PART_ID ASC - ) AS PARTITION_POSITION - FROM OCEANBASE.__ALL_VIRTUAL_PART) AS P - ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID - - JOIN (SELECT *, - ROW_NUMBER() OVER ( - PARTITION BY TENANT_ID, TABLE_ID, PART_ID - ORDER BY SUB_PART_IDX, SUB_PART_ID ASC - ) AS SUBPARTITION_POSITION - FROM OCEANBASE.__ALL_VIRTUAL_SUB_PART) AS SP - ON P.TENANT_ID = SP.TENANT_ID AND P.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID + FROM + DUAL + WHERE + 0 = 1 """.replace("\n", " "), ) @@ -17024,13 +17213,14 @@ def_table_schema( """ SELECT TG.TABLEGROUP_NAME AS TABLEGROUP_NAME, D.DATABASE_NAME AS OWNER, - T.TABLE_NAME AS TABLE_NAME + T.TABLE_NAME AS TABLE_NAME, + TG.SHARDING AS SHARDING FROM OCEANBASE.__ALL_TABLE AS T JOIN OCEANBASE.__ALL_DATABASE AS D ON T.TENANT_ID = D.TENANT_ID AND T.DATABASE_ID = D.DATABASE_ID JOIN OCEANBASE.__ALL_TABLEGROUP AS TG ON T.TENANT_ID = TG.TENANT_ID AND T.TABLEGROUP_ID = TG.TABLEGROUP_ID - WHERE T.TABLE_TYPE = 3 + WHERE T.TABLE_TYPE in (0, 3, 6) """.replace("\n", " "), ) @@ -17047,13 +17237,14 @@ def_table_schema( SELECT T.TENANT_ID AS TENANT_ID, TG.TABLEGROUP_NAME AS TABLEGROUP_NAME, D.DATABASE_NAME AS OWNER, - T.TABLE_NAME AS TABLE_NAME + T.TABLE_NAME AS TABLE_NAME, + TG.SHARDING AS SHARDING FROM OCEANBASE.__ALL_VIRTUAL_TABLE AS T JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE AS D ON T.TENANT_ID = D.TENANT_ID AND T.DATABASE_ID = D.DATABASE_ID JOIN OCEANBASE.__ALL_VIRTUAL_TABLEGROUP AS TG ON T.TENANT_ID = TG.TENANT_ID AND T.TABLEGROUP_ID = TG.TABLEGROUP_ID - WHERE T.TABLE_TYPE = 3 + WHERE T.TABLE_TYPE in (0, 3, 6) """.replace("\n", " "), ) @@ -17183,7 +17374,7 @@ def_table_schema( normal_columns = [], gm_columns = [], view_definition = """ - SELECT + SELECT CAST(A.TENANT_ID AS SIGNED) AS CON_ID, CAST(B.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS CHAR(128)) AS OBJECT_NAME, @@ -17558,50 +17749,6 @@ def_table_schema( 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP - - UNION ALL - - SELECT - P.TENANT_ID, - P.GMT_CREATE, - P.GMT_MODIFIED, - CAST(201001 AS SIGNED) AS DATABASE_ID, - TG.TABLEGROUP_NAME AS OBJECT_NAME, - P.PART_NAME SUBOBJECT_NAME, - P.PART_ID OBJECT_ID, - NULL AS DATA_OBJECT_ID, - 'TABLEGROUP PARTITION' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - NULL AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP TG JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON TG.TABLEGROUP_ID = P.TABLE_ID - WHERE TG.TENANT_ID = P.TENANT_ID - - UNION ALL - - SELECT - SUBP.TENANT_ID, - SUBP.GMT_CREATE, - SUBP.GMT_MODIFIED, - CAST(201001 AS SIGNED) AS DATABASE_ID, - TG.TABLEGROUP_NAME AS OBJECT_NAME, - SUBP.SUB_PART_NAME SUBOBJECT_NAME, - SUBP.SUB_PART_ID OBJECT_ID, - NULL DATA_OBJECT_ID, - 'TABLEGROUP SUBPARTITION' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - 'Y' AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP TG, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART SUBP - WHERE TG.TABLEGROUP_ID = P.TABLE_ID AND P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID - AND TG.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID - ) A JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE B ON A.TENANT_ID = B.TENANT_ID @@ -19541,50 +19688,6 @@ def_table_schema( NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLEGROUP WHERE TENANT_ID = 0 - - UNION ALL - - SELECT - P.TENANT_ID, - P.GMT_CREATE, - P.GMT_MODIFIED, - CAST(201001 AS SIGNED) AS DATABASE_ID, - TG.TABLEGROUP_NAME AS OBJECT_NAME, - P.PART_NAME SUBOBJECT_NAME, - P.PART_ID OBJECT_ID, - NULL AS DATA_OBJECT_ID, - 'TABLEGROUP PARTITION' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - NULL AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM OCEANBASE.__ALL_TABLEGROUP TG JOIN OCEANBASE.__ALL_PART P ON TG.TABLEGROUP_ID = P.TABLE_ID - WHERE TG.TENANT_ID = 0 AND TG.TENANT_ID = P.TENANT_ID - - UNION ALL - - SELECT - SUBP.TENANT_ID, - SUBP.GMT_CREATE, - SUBP.GMT_MODIFIED, - CAST(201001 AS SIGNED) AS DATABASE_ID, - TG.TABLEGROUP_NAME AS OBJECT_NAME, - SUBP.SUB_PART_NAME SUBOBJECT_NAME, - SUBP.SUB_PART_ID OBJECT_ID, - NULL DATA_OBJECT_ID, - 'TABLEGROUP SUBPARTITION' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - 'N' AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM OCEANBASE.__ALL_TABLEGROUP TG, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART SUBP - WHERE TG.TABLEGROUP_ID = P.TABLE_ID AND P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID - AND TG.TENANT_ID = 0 AND TG.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID - ) A JOIN OCEANBASE.__ALL_DATABASE B ON A.TENANT_ID = B.TENANT_ID @@ -22165,7 +22268,9 @@ def_table_schema( DATA_TURN_ID, RESULT, COMMENT, - PATH + PATH, + MINOR_TURN_ID, + MAJOR_TURN_ID FROM OCEANBASE.__all_virtual_backup_task WHERE TENANT_ID = EFFECTIVE_TENANT_ID() """.replace("\n", " ") @@ -22217,7 +22322,9 @@ def_table_schema( DATA_TURN_ID, RESULT, COMMENT, - PATH + PATH, + MINOR_TURN_ID, + MAJOR_TURN_ID FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_TASK_HISTORY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() """.replace("\n", " ") @@ -22293,7 +22400,10 @@ def_table_schema( TENANT_COMPATIBLE, BACKUP_COMPATIBLE, PATH, - CLUSTER_VERSION + CLUSTER_VERSION, + CONSISTENT_SCN, + MINOR_TURN_ID, + MAJOR_TURN_ID FROM OCEANBASE.__ALL_VIRTUAL_BACKUP_SET_FILES WHERE TENANT_ID = EFFECTIVE_TENANT_ID() """.replace("\n", " ") @@ -24327,17 +24437,23 @@ SELECT C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' - END AS DUPLICATE_SCOPE + END AS DUPLICATE_SCOPE, + A.OBJECT_ID, + TG.TABLEGROUP_NAME, + TG.TABLEGROUP_ID, + TG.SHARDING FROM ( SELECT DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, + TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 AND TENANT_ID = EFFECTIVE_TENANT_ID() @@ -24349,10 +24465,12 @@ FROM ( TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, + TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE WHERE TABLET_ID != 0 AND PART_LEVEL = 0 AND TENANT_ID = 0 @@ -24364,10 +24482,12 @@ FROM ( T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, + P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = 0 @@ -24380,10 +24500,12 @@ FROM ( T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, + Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE T, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID = Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 @@ -24392,6 +24514,7 @@ FROM ( JOIN OCEANBASE.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN OCEANBASE.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID JOIN OCEANBASE.__ALL_DATABASE D ON A.DATABASE_ID = D.DATABASE_ID + LEFT JOIN OCEANBASE.__ALL_TABLEGROUP TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID WHERE D.TENANT_ID = 0 ORDER BY A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT """.replace("\n", " "), @@ -24443,7 +24566,11 @@ SELECT C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' - END AS DUPLICATE_SCOPE + END AS DUPLICATE_SCOPE, + A.OBJECT_ID, + TG.TABLEGROUP_NAME, + TG.TABLEGROUP_ID, + TG.SHARDING FROM ( SELECT TENANT_ID, DATABASE_ID, @@ -24451,10 +24578,12 @@ FROM ( TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, + TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 @@ -24467,10 +24596,12 @@ FROM ( TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, + TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLET_ID != 0 AND PART_LEVEL = 0 @@ -24483,10 +24614,12 @@ FROM ( T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, + P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = P.TENANT_ID AND T.PART_LEVEL = 1 @@ -24499,10 +24632,12 @@ FROM ( T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, + Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID =Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 @@ -24510,6 +24645,7 @@ FROM ( JOIN OCEANBASE.CDB_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID AND A.TENANT_ID = B.TENANT_ID JOIN OCEANBASE.CDB_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID AND A.TENANT_ID = C.TENANT_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE D ON A.TENANT_ID = D.TENANT_ID AND A.DATABASE_ID = D.DATABASE_ID + LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TABLEGROUP TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID AND A.TENANT_ID = TG.TENANT_ID ORDER BY A.TENANT_ID, A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT """.replace("\n", " "), ) @@ -26868,17 +27004,370 @@ def_table_schema( ) # 21405: DBA_OB_BALANCE_JOBS +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_BALANCE_JOBS', + table_id = '21405', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT JOB_ID, + GMT_CREATE AS CREATE_TIME, + GMT_MODIFIED AS MODIFY_TIME, + BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, + JOB_TYPE, + TARGET_UNIT_NUM, + TARGET_PRIMARY_ZONE_NUM, + STATUS, + COMMENT + FROM OCEANBASE.__ALL_BALANCE_JOB + """.replace("\n", " "), +) + # 21406: CDB_OB_BALANCE_JOBS +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'CDB_OB_BALANCE_JOBS', + table_id = '21406', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + view_definition = + """ + SELECT TENANT_ID, + JOB_ID, + GMT_CREATE AS CREATE_TIME, + GMT_MODIFIED AS MODIFY_TIME, + BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, + JOB_TYPE, + TARGET_UNIT_NUM, + TARGET_PRIMARY_ZONE_NUM, + STATUS, + COMMENT + FROM OCEANBASE.__ALL_VIRTUAL_BALANCE_JOB + """.replace("\n", " "), +) # 21407: DBA_OB_BALANCE_JOB_HISTORY +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_BALANCE_JOB_HISTORY', + table_id = '21407', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT JOB_ID, + CREATE_TIME, + FINISH_TIME, + BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, + JOB_TYPE, + TARGET_UNIT_NUM, + TARGET_PRIMARY_ZONE_NUM, + STATUS, + COMMENT + FROM OCEANBASE.__ALL_BALANCE_JOB_HISTORY + """.replace("\n", " "), +) # 21408: CDB_OB_BALANCE_JOB_HISTORY +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'CDB_OB_BALANCE_JOB_HISTORY', + table_id = '21408', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + view_definition = + """ + SELECT TENANT_ID, + JOB_ID, + CREATE_TIME, + FINISH_TIME, + BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, + JOB_TYPE, + TARGET_UNIT_NUM, + TARGET_PRIMARY_ZONE_NUM, + STATUS, + COMMENT + FROM OCEANBASE.__ALL_VIRTUAL_BALANCE_JOB_HISTORY + """.replace("\n", " "), +) # 21409: DBA_OB_BALANCE_TASKS +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_BALANCE_TASKS', + table_id = '21409', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT TASK_ID, + GMT_CREATE AS CREATE_TIME, + GMT_MODIFIED AS MODIFY_TIME, + TASK_TYPE, + SRC_LS, + DEST_LS, + PART_LIST, + FINISHED_PART_LIST, + PART_COUNT, + FINISHED_PART_COUNT, + LS_GROUP_ID, + STATUS, + PARENT_LIST, + CHILD_LIST, + CURRENT_TRANSFER_TASK_ID, + JOB_ID, + COMMENT + FROM OCEANBASE.__ALL_BALANCE_TASK + """.replace("\n", " "), +) # 21410: CDB_OB_BALANCE_TASKS +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'CDB_OB_BALANCE_TASKS', + table_id = '21410', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + view_definition = + """ + SELECT TENANT_ID, + TASK_ID, + GMT_CREATE AS CREATE_TIME, + GMT_MODIFIED AS MODIFY_TIME, + TASK_TYPE, + SRC_LS, + DEST_LS, + PART_LIST, + FINISHED_PART_LIST, + PART_COUNT, + FINISHED_PART_COUNT, + LS_GROUP_ID, + STATUS, + PARENT_LIST, + CHILD_LIST, + CURRENT_TRANSFER_TASK_ID, + JOB_ID, + COMMENT + FROM OCEANBASE.__ALL_VIRTUAL_BALANCE_TASK + """.replace("\n", " "), +) # 21411: DBA_OB_BALANCE_TASK_HISTORY +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_BALANCE_TASK_HISTORY', + table_id = '21411', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT TASK_ID, + CREATE_TIME, + FINISH_TIME, + TASK_TYPE, + SRC_LS, + DEST_LS, + PART_LIST, + FINISHED_PART_LIST, + PART_COUNT, + FINISHED_PART_COUNT, + LS_GROUP_ID, + STATUS, + PARENT_LIST, + CHILD_LIST, + CURRENT_TRANSFER_TASK_ID, + JOB_ID, + COMMENT + FROM OCEANBASE.__ALL_BALANCE_TASK_HISTORY + """.replace("\n", " "), +) # 21412: CDB_OB_BALANCE_TASK_HISTORY +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'CDB_OB_BALANCE_TASK_HISTORY', + table_id = '21412', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + view_definition = + """ + SELECT TENANT_ID, + TASK_ID, + CREATE_TIME, + FINISH_TIME, + TASK_TYPE, + SRC_LS, + DEST_LS, + PART_LIST, + FINISHED_PART_LIST, + PART_COUNT, + FINISHED_PART_COUNT, + LS_GROUP_ID, + STATUS, + PARENT_LIST, + CHILD_LIST, + CURRENT_TRANSFER_TASK_ID, + JOB_ID, + COMMENT + FROM OCEANBASE.__ALL_VIRTUAL_BALANCE_TASK_HISTORY + """.replace("\n", " "), +) # 21413: DBA_OB_TRANSFER_TASKS +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_TRANSFER_TASKS', + table_id = '21413', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT TASK_ID, + GMT_CREATE AS CREATE_TIME, + GMT_MODIFIED AS MODIFY_TIME, + SRC_LS, + DEST_LS, + PART_LIST, + PART_COUNT, + NOT_EXIST_PART_LIST, + LOCK_CONFLICT_PART_LIST, + TABLE_LOCK_TABLET_LIST, + TABLET_LIST, + TABLET_COUNT, + START_SCN, + FINISH_SCN, + STATUS, + TRACE_ID, + RESULT, + BALANCE_TASK_ID, + TABLE_LOCK_OWNER_ID, + COMMENT + FROM OCEANBASE.__ALL_TRANSFER_TASK + """.replace("\n", " "), +) # 21414: CDB_OB_TRANSFER_TASKS +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'CDB_OB_TRANSFER_TASKS', + table_id = '21414', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + view_definition = + """ + SELECT TENANT_ID, + TASK_ID, + GMT_CREATE AS CREATE_TIME, + GMT_MODIFIED AS MODIFY_TIME, + SRC_LS, + DEST_LS, + PART_LIST, + PART_COUNT, + NOT_EXIST_PART_LIST, + LOCK_CONFLICT_PART_LIST, + TABLE_LOCK_TABLET_LIST, + TABLET_LIST, + TABLET_COUNT, + START_SCN, + FINISH_SCN, + STATUS, + TRACE_ID, + RESULT, + BALANCE_TASK_ID, + TABLE_LOCK_OWNER_ID, + COMMENT + FROM OCEANBASE.__ALL_VIRTUAL_TRANSFER_TASK + """.replace("\n", " "), +) # 21415: DBA_OB_TRANSFER_TASK_HISTORY +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_TRANSFER_TASK_HISTORY', + table_id = '21415', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT TASK_ID, + CREATE_TIME, + FINISH_TIME, + SRC_LS, + DEST_LS, + PART_LIST, + PART_COUNT, + NOT_EXIST_PART_LIST, + LOCK_CONFLICT_PART_LIST, + TABLE_LOCK_TABLET_LIST, + TABLET_LIST, + TABLET_COUNT, + START_SCN, + FINISH_SCN, + STATUS, + TRACE_ID, + RESULT, + BALANCE_TASK_ID, + TABLE_LOCK_OWNER_ID, + COMMENT + FROM OCEANBASE.__ALL_TRANSFER_TASK_HISTORY + """.replace("\n", " "), +) # 21416: CDB_OB_TRANSFER_TASK_HISTORY +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'CDB_OB_TRANSFER_TASK_HISTORY', + table_id = '21416', + table_type = 'SYSTEM_VIEW', + gm_columns = [], + rowkey_columns = [], + normal_columns = [], + view_definition = + """ + SELECT TENANT_ID, + TASK_ID, + CREATE_TIME, + FINISH_TIME, + SRC_LS, + DEST_LS, + PART_LIST, + PART_COUNT, + NOT_EXIST_PART_LIST, + LOCK_CONFLICT_PART_LIST, + TABLE_LOCK_TABLET_LIST, + TABLET_LIST, + TABLET_COUNT, + START_SCN, + FINISH_SCN, + STATUS, + TRACE_ID, + RESULT, + BALANCE_TASK_ID, + TABLE_LOCK_OWNER_ID, + COMMENT + FROM OCEANBASE.__ALL_VIRTUAL_TRANSFER_TASK_HISTORY + """.replace("\n", " "), +) def_table_schema( owner = 'jim.wjh', @@ -27801,49 +28290,6 @@ def_table_schema( NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() - - UNION ALL - - SELECT - P.TENANT_ID, - P.GMT_CREATE, - P.GMT_MODIFIED, - CAST(201001 AS NUMBER) AS DATABASE_ID, - TG.TABLEGROUP_NAME AS OBJECT_NAME, - P.PART_NAME SUBOBJECT_NAME, - P.PART_ID OBJECT_ID, - NULL AS DATA_OBJECT_ID, - 'TABLEGROUP PARTITION' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - NULL AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON TG.TABLEGROUP_ID = P.TABLE_ID - WHERE TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() - - UNION ALL - - SELECT - SUBP.TENANT_ID, - SUBP.GMT_CREATE, - SUBP.GMT_MODIFIED, - CAST(201001 AS NUMBER) AS DATABASE_ID, - TG.TABLEGROUP_NAME AS OBJECT_NAME, - SUBP.SUB_PART_NAME SUBOBJECT_NAME, - SUBP.SUB_PART_ID OBJECT_ID, - NULL DATA_OBJECT_ID, - 'TABLEGROUP SUBPARTITION' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - 'Y' AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP - WHERE TG.TABLEGROUP_ID = P.TABLE_ID AND P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID - AND TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID @@ -28326,73 +28772,6 @@ def_table_schema( NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() - - /*UNION ALL - - SELECT - TENANT_ID, - GMT_CREATE, - GMT_MODIFIED, - CAST(201001 AS NUMBER) AS DATABASE_ID, - TABLEGROUP_NAME AS OBJECT_NAME, - NULL AS SUBOBJECT_NAME, - TABLEGROUP_ID AS OBJECT_ID, - CAST(-1 AS NUMBER) AS PRIV_OBJECT_ID, - NULL AS DATA_OBJECT_ID, - 'TABLEGROUP' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - 'N' AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT - WHERE TENANT_ID = EFFECTIVE_TENANT_ID() - - UNION ALL - - SELECT - P.TENANT_ID, - P.GMT_CREATE, - P.GMT_MODIFIED, - CAST(201001 AS NUMBER) AS DATABASE_ID, - TG.TABLEGROUP_NAME AS OBJECT_NAME, - P.PART_NAME SUBOBJECT_NAME, - P.PART_ID OBJECT_ID, - CAST(-1 AS NUMBER) AS PRIV_OBJECT_ID, - NULL AS DATA_OBJECT_ID, - 'TABLEGROUP PARTITION' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - NULL AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON TG.TABLEGROUP_ID = P.TABLE_ID - WHERE TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() - - UNION ALL - - SELECT - SUBP.TENANT_ID, - SUBP.GMT_CREATE, - SUBP.GMT_MODIFIED, - CAST(201001 AS NUMBER) AS DATABASE_ID, - TG.TABLEGROUP_NAME AS OBJECT_NAME, - SUBP.SUB_PART_NAME SUBOBJECT_NAME, - SUBP.SUB_PART_ID OBJECT_ID, - CAST(-1 AS NUMBER) AS PRIV_OBJECT_ID, - NULL DATA_OBJECT_ID, - 'TABLEGROUP SUBPARTITION' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - 'Y' AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP - WHERE TG.TABLEGROUP_ID = P.TABLE_ID AND P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID - AND TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID()*/ ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID @@ -28878,70 +29257,6 @@ def_table_schema( NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() - - /*UNION ALL - - SELECT - TENANT_ID, - GMT_CREATE, - GMT_MODIFIED, - CAST(201001 AS NUMBER) AS DATABASE_ID, - TABLEGROUP_NAME AS OBJECT_NAME, - NULL AS SUBOBJECT_NAME, - TABLEGROUP_ID AS OBJECT_ID, - NULL AS DATA_OBJECT_ID, - 'TABLEGROUP' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - 'N' AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT - WHERE TENANT_ID = EFFECTIVE_TENANT_ID() - - UNION ALL - - SELECT - P.TENANT_ID, - P.GMT_CREATE, - P.GMT_MODIFIED, - CAST(201001 AS NUMBER) AS DATABASE_ID, - TG.TABLEGROUP_NAME AS OBJECT_NAME, - P.PART_NAME SUBOBJECT_NAME, - P.PART_ID OBJECT_ID, - NULL AS DATA_OBJECT_ID, - 'TABLEGROUP PARTITION' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - NULL AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON TG.TABLEGROUP_ID = P.TABLE_ID - WHERE TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() - - UNION ALL - - SELECT - SUBP.TENANT_ID, - SUBP.GMT_CREATE, - SUBP.GMT_MODIFIED, - CAST(201001 AS NUMBER) AS DATABASE_ID, - TG.TABLEGROUP_NAME AS OBJECT_NAME, - SUBP.SUB_PART_NAME SUBOBJECT_NAME, - SUBP.SUB_PART_ID OBJECT_ID, - NULL DATA_OBJECT_ID, - 'TABLEGROUP SUBPARTITION' AS OBJECT_TYPE, - 'VALID' AS STATUS, - 'N' AS TEMPORARY, - 'Y' AS "GENERATED", - 'N' AS SECONDARY, - 0 AS NAMESPACE, - NULL AS EDITION_NAME - FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP - WHERE TG.TABLEGROUP_ID = P.TABLE_ID AND P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID - AND TG.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID()*/ ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID @@ -41745,7 +42060,10 @@ def_table_schema( WHEN 16 THEN 'READONLY' WHEN 261 THEN 'ENCRYPTION LOGONLY' ELSE NULL END) AS REPLICA_TYPE, - (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE NULL END) AS LEARNER_LIST + (CASE ROLE WHEN 1 THEN LEARNER_LIST ELSE NULL END) AS LEARNER_LIST, + (CASE REBUILD + WHEN 0 THEN 'FALSE' + ELSE 'TRUE' END) AS REBUILD FROM SYS.ALL_VIRTUAL_LS_META_TABLE WHERE TENANT_ID = EFFECTIVE_TENANT_ID() @@ -41832,52 +42150,19 @@ def_table_schema( """ SELECT TABLEGROUP_NAME, - (CASE PART_LEVEL - WHEN 0 THEN 'NONE' - ELSE (CASE PART_FUNC_TYPE - WHEN 0 THEN 'HASH' - WHEN 1 THEN 'KEY' - WHEN 2 THEN 'KEY' - WHEN 3 THEN 'RANGE' - WHEN 4 THEN 'RANGE COLUMNS' - WHEN 5 THEN 'LIST' - WHEN 6 THEN 'LIST COLUMNS' - WHEN 7 THEN 'UNKNOWN' - ELSE 'UNKNOWN' - END) - END) AS PARTITIONING_TYPE, + CAST('NONE' AS VARCHAR2(13)) AS PARTITIONING_TYPE, - (CASE PART_LEVEL - WHEN 2 THEN (CASE SUB_PART_FUNC_TYPE - WHEN 0 THEN 'HASH' - WHEN 1 THEN 'KEY' - WHEN 2 THEN 'KEY' - WHEN 3 THEN 'RANGE' - WHEN 4 THEN 'RANGE COLUMNS' - WHEN 5 THEN 'LIST' - WHEN 6 THEN 'LIST COLUMNS' - WHEN 7 THEN 'UNKNOWN' - ELSE 'UNKNOWN' - END) - ELSE 'NONE' - END) AS SUBPARTITIONING_TYPE, + CAST('NONE' AS VARCHAR2(13)) AS SUBPARTITIONING_TYPE, - CAST((CASE PART_LEVEL - WHEN 0 THEN NULL - ELSE PART_NUM - END) AS NUMBER) AS PARTITION_COUNT, + CAST(NULL AS NUMBER) AS PARTITION_COUNT, CAST(NULL AS NUMBER) AS DEF_SUBPARTITION_COUNT, - CAST((CASE PART_LEVEL - WHEN 0 THEN NULL - ELSE PART_FUNC_EXPR_NUM - END) AS NUMBER) AS PARTITIONING_KEY_COUNT, + CAST(NULL AS NUMBER) AS PARTITIONING_KEY_COUNT, - CAST((CASE PART_LEVEL - WHEN 2 THEN SUB_PART_FUNC_EXPR_NUM - ELSE NULL - END) AS NUMBER) AS SUBPARTITIONING_KEY_COUNT + CAST(NULL AS NUMBER) AS SUBPARTITIONING_KEY_COUNT, + + SHARDING FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT """.replace("\n", " "), ) @@ -41895,47 +42180,23 @@ def_table_schema( in_tenant_space = True, view_definition = """ - SELECT T.TABLEGROUP_NAME AS TABLEGROUP_NAME, + SELECT CAST('' AS VARCHAR(128)) AS TABLEGROUP_NAME, - (CASE T.PART_LEVEL - WHEN 2 THEN 'YES' - ELSE 'NO' - END) AS COMPOSITE, + CAST('NO' AS VARCHAR(3)) AS COMPOSITE, - P.PART_NAME AS PARTITION_NAME, + CAST('' AS VARCHAR(64)) AS PARTITION_NAME, - CAST((CASE T.PART_LEVEL - WHEN 2 THEN P.SUB_PART_NUM - ELSE NULL - END) AS NUMBER) AS SUBPARTITION_COUNT, + CAST(NULL AS NUMBER) AS SUBPARTITION_COUNT, - (CASE - WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL - WHEN LENGTH(P.LIST_VAL) > 0 THEN P.LIST_VAL - ELSE NULL - END) AS HIGH_VALUE, + CAST(NULL AS VARCHAR(4096)) AS HIGH_VALUE, - CAST((CASE - WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN LENGTH(P.HIGH_BOUND_VAL) - WHEN LENGTH(P.LIST_VAL) > 0 THEN LENGTH(P.LIST_VAL) - ELSE NULL - END) AS NUMBER) AS HIGH_VALUE_LENGTH, + CAST(NULL AS NUMBER) AS HIGH_VALUE_LENGTH, - CAST(P.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION - FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT T - JOIN (SELECT - TENANT_ID, - TABLE_ID, - PART_NAME, - SUB_PART_NUM, - HIGH_BOUND_VAL, - LIST_VAL, - ROW_NUMBER() OVER ( - PARTITION BY TENANT_ID, TABLE_ID - ORDER BY PART_IDX, PART_ID ASC - ) PARTITION_POSITION - FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P - ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID + CAST(NULL AS NUMBER) AS PARTITION_POSITION + FROM + DUAL + WHERE + 0 = 1 """.replace("\n", " "), ) @@ -41952,55 +42213,23 @@ def_table_schema( in_tenant_space = True, view_definition = """ - SELECT T.TABLEGROUP_NAME AS TABLEGROUP_NAME, + SELECT CAST('' AS VARCHAR(128)) AS TABLEGROUP_NAME, - P.PART_NAME AS PARTITION_NAME, + CAST('' AS VARCHAR(64)) AS PARTITION_NAME, - SP.SUB_PART_NAME AS SUBPARTITION_NAME, + CAST('' AS VARCHAR(64)) AS SUBPARTITION_NAME, - (CASE - WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL - WHEN LENGTH(SP.LIST_VAL) > 0 THEN SP.LIST_VAL - ELSE NULL - END) AS HIGH_VALUE, + CAST(NULL AS VARCHAR(4096)) AS HIGH_VALUE, - CAST((CASE - WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN LENGTH(SP.HIGH_BOUND_VAL) - WHEN LENGTH(SP.LIST_VAL) > 0 THEN LENGTH(SP.LIST_VAL) - ELSE NULL - END) AS NUMBER) AS HIGH_VALUE_LENGTH, + CAST(NULL AS NUMBER) AS HIGH_VALUE_LENGTH, - CAST(P.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, + CAST(NULL AS NUMBER) AS PARTITION_POSITION, - CAST(SP.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION - - FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT T - - JOIN (SELECT - TENANT_ID, - TABLE_ID, - PART_ID, - PART_NAME, - ROW_NUMBER() OVER ( - PARTITION BY TENANT_ID, TABLE_ID - ORDER BY PART_IDX, PART_ID ASC - ) PARTITION_POSITION - FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P - ON T.TENANT_ID = P.TENANT_ID AND T.TABLEGROUP_ID = P.TABLE_ID - - JOIN (SELECT - TENANT_ID, - TABLE_ID, - PART_ID, - SUB_PART_NAME, - HIGH_BOUND_VAL, - LIST_VAL, - ROW_NUMBER() OVER ( - PARTITION BY TENANT_ID, TABLE_ID, PART_ID - ORDER BY SUB_PART_IDX, SUB_PART_ID ASC - ) SUBPARTITION_POSITION - FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) SP - ON P.TENANT_ID = SP.TENANT_ID AND P.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID + CAST(NULL AS NUMBER) AS SUBPARTITION_POSITION + FROM + DUAL + WHERE + 0 = 1 """.replace("\n", " "), ) @@ -42043,13 +42272,14 @@ def_table_schema( """ SELECT TG.TABLEGROUP_NAME AS TABLEGROUP_NAME, D.DATABASE_NAME AS OWNER, - T.TABLE_NAME AS TABLE_NAME + T.TABLE_NAME AS TABLE_NAME, + TG.SHARDING AS SHARDING FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON T.TENANT_ID = D.TENANT_ID AND T.DATABASE_ID = D.DATABASE_ID JOIN SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG ON T.TENANT_ID = TG.TENANT_ID AND T.TABLEGROUP_ID = TG.TABLEGROUP_ID - WHERE T.TABLE_TYPE = 3 + WHERE T.TABLE_TYPE in (0, 3, 6) """.replace("\n", " "), ) @@ -42625,7 +42855,9 @@ def_table_schema( DATA_TURN_ID, RESULT, "COMMENT", - PATH + PATH, + MINOR_TURN_ID, + MAJOR_TURN_ID FROM SYS.ALL_VIRTUAL_BACKUP_TASK WHERE TENANT_ID = EFFECTIVE_TENANT_ID() """.replace("\n", " ") @@ -42679,7 +42911,9 @@ def_table_schema( DATA_TURN_ID, RESULT, "COMMENT", - PATH + PATH, + MINOR_TURN_ID, + MAJOR_TURN_ID FROM SYS.ALL_VIRTUAL_BACKUP_TASK_HISTORY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() """.replace("\n", " ") @@ -42747,7 +42981,10 @@ def_table_schema( TENANT_COMPATIBLE, BACKUP_COMPATIBLE, PATH, - CLUSTER_VERSION + CLUSTER_VERSION, + CONSISTENT_SCN, + MINOR_TURN_ID, + MAJOR_TURN_ID FROM SYS.ALL_VIRTUAL_BACKUP_SET_FILES WHERE TENANT_ID = EFFECTIVE_TENANT_ID() """.replace("\n", " ") @@ -43948,10 +44185,30 @@ SELECT A.TENANT_ID, WHEN (MOD(A.TENANT_ID, 2)) = 1 THEN 'NOARCHIVELOG' ELSE LOG_MODE END) AS LOG_MODE, - ARBITRATION_SERVICE_STATUS + ARBITRATION_SERVICE_STATUS, + UNIT_NUM, + COMPATIBLE FROM SYS.ALL_VIRTUAL_TENANT_SYS_AGENT A LEFT JOIN SYS.ALL_VIRTUAL_TENANT_INFO B ON A.TENANT_ID = B.TENANT_ID +LEFT JOIN + (SELECT TENANT_ID, + (CASE + WHEN TENANT_ID < 1 THEN NULL + WHEN TENANT_ID != 1 THEN TENANT_ID - 1 + ELSE NULL + END) AS META_TENANT_ID, + MIN(UNIT_COUNT) AS UNIT_NUM + FROM SYS.ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT + GROUP BY TENANT_ID) C + ON A.TENANT_ID = C.TENANT_ID OR A.TENANT_ID = C.META_TENANT_ID +LEFT JOIN + (SELECT TENANT_ID, + MIN(VALUE) AS COMPATIBLE + FROM SYS.ALL_VIRTUAL_TENANT_PARAMETER + WHERE NAME = 'compatible' + GROUP BY TENANT_ID) D + ON A.TENANT_ID = D.TENANT_ID WHERE A.TENANT_ID = EFFECTIVE_TENANT_ID() """.replace("\n", " "), ) @@ -44661,6 +44918,7 @@ def_table_schema( """.replace("\n", " ") ) + def_table_schema( owner = 'jiangxiu.wt', table_name = 'DBA_OB_TASK_OPT_STAT_GATHER_HISTORY', @@ -44841,12 +45099,200 @@ def_table_schema( """.replace("\n", " ") ) -# 25237: DBA_OB_BALANCE_JOBS -# 25238: DBA_OB_BALANCE_JOB_HISTORY -# 25239: DBA_OB_BALANCE_TASKS -# 25240: DBA_OB_BALANCE_TASK_HISTORY -# 25241: DBA_OB_TRANSFER_TASKS -# 25242: DBA_OB_TRANSFER_TASK_HISTORY +# 25237: DBA_OB_BALANCE_JOBS +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_BALANCE_JOBS', + name_postfix = '_ORA', + database_id = 'OB_ORA_SYS_DATABASE_ID', + table_id = '25237', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT JOB_ID, + GMT_CREATE AS CREATE_TIME, + GMT_MODIFIED AS MODIFY_TIME, + BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, + JOB_TYPE, + TARGET_UNIT_NUM, + TARGET_PRIMARY_ZONE_NUM, + STATUS, + "COMMENT" + FROM SYS.ALL_VIRTUAL_BALANCE_JOB_REAL_AGENT + """.replace("\n", " "), +) +# 25238: DBA_OB_BALANCE_JOB_HISTORY +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_BALANCE_JOB_HISTORY', + name_postfix = '_ORA', + database_id = 'OB_ORA_SYS_DATABASE_ID', + table_id = '25238', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT JOB_ID, + CREATE_TIME, + FINISH_TIME, + BALANCE_STRATEGY_NAME AS BALANCE_STRATEGY, + JOB_TYPE, + TARGET_UNIT_NUM, + TARGET_PRIMARY_ZONE_NUM, + STATUS, + "COMMENT" + FROM SYS.ALL_VIRTUAL_BALANCE_JOB_HISTORY_REAL_AGENT + """.replace("\n", " "), +) +# 25239: DBA_OB_BALANCE_TASKS +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_BALANCE_TASKS', + name_postfix = '_ORA', + database_id = 'OB_ORA_SYS_DATABASE_ID', + table_id = '25239', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT TASK_ID, + GMT_CREATE AS CREATE_TIME, + GMT_MODIFIED AS MODIFY_TIME, + TASK_TYPE, + SRC_LS, + DEST_LS, + PART_LIST, + FINISHED_PART_LIST, + PART_COUNT, + FINISHED_PART_COUNT, + LS_GROUP_ID, + STATUS, + PARENT_LIST, + CHILD_LIST, + CURRENT_TRANSFER_TASK_ID, + JOB_ID, + "COMMENT" + FROM SYS.ALL_VIRTUAL_BALANCE_TASK_REAL_AGENT + """.replace("\n", " "), +) +# 25240: DBA_OB_BALANCE_TASK_HISTORY +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_BALANCE_TASK_HISTORY', + name_postfix = '_ORA', + database_id = 'OB_ORA_SYS_DATABASE_ID', + table_id = '25240', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT TASK_ID, + CREATE_TIME, + FINISH_TIME, + TASK_TYPE, + SRC_LS, + DEST_LS, + PART_LIST, + FINISHED_PART_LIST, + PART_COUNT, + FINISHED_PART_COUNT, + LS_GROUP_ID, + STATUS, + PARENT_LIST, + CHILD_LIST, + CURRENT_TRANSFER_TASK_ID, + JOB_ID, + "COMMENT" + FROM SYS.ALL_VIRTUAL_BALANCE_TASK_HISTORY_REAL_AGENT + """.replace("\n", " "), +) +# 25241: DBA_OB_TRANSFER_TASKS +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_TRANSFER_TASKS', + name_postfix = '_ORA', + database_id = 'OB_ORA_SYS_DATABASE_ID', + table_id = '25241', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT TASK_ID, + GMT_CREATE AS CREATE_TIME, + GMT_MODIFIED AS MODIFY_TIME, + SRC_LS, + DEST_LS, + PART_LIST, + PART_COUNT, + NOT_EXIST_PART_LIST, + LOCK_CONFLICT_PART_LIST, + TABLE_LOCK_TABLET_LIST, + TABLET_LIST, + TABLET_COUNT, + START_SCN, + FINISH_SCN, + STATUS, + TRACE_ID, + RESULT, + BALANCE_TASK_ID, + TABLE_LOCK_OWNER_ID, + "COMMENT" + FROM SYS.ALL_VIRTUAL_TRANSFER_TASK_REAL_AGENT + """.replace("\n", " "), +) +# 25242: DBA_OB_TRANSFER_TASK_HISTORY +def_table_schema( + owner = 'wangzhennan.wzn', + table_name = 'DBA_OB_TRANSFER_TASK_HISTORY', + name_postfix = '_ORA', + database_id = 'OB_ORA_SYS_DATABASE_ID', + table_id = '25242', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = True, + view_definition = + """ + SELECT TASK_ID, + CREATE_TIME, + FINISH_TIME, + SRC_LS, + DEST_LS, + PART_LIST, + PART_COUNT, + NOT_EXIST_PART_LIST, + LOCK_CONFLICT_PART_LIST, + TABLE_LOCK_TABLET_LIST, + TABLET_LIST, + TABLET_COUNT, + START_SCN, + FINISH_SCN, + STATUS, + TRACE_ID, + RESULT, + BALANCE_TASK_ID, + TABLE_LOCK_OWNER_ID, + "COMMENT" + FROM SYS.ALL_VIRTUAL_TRANSFER_TASK_HISTORY_REAL_AGENT + """.replace("\n", " "), +) def_table_schema( owner = 'mingdou.tmd', @@ -50220,7 +50666,11 @@ SELECT C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' - END AS DUPLICATE_SCOPE + END AS DUPLICATE_SCOPE, + A.OBJECT_ID, + TG.TABLEGROUP_NAME, + TG.TABLEGROUP_ID, + TG.SHARDING FROM ( SELECT TENANT_ID, DATABASE_ID, @@ -50228,10 +50678,12 @@ FROM ( TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, + TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 AND TENANT_ID = EFFECTIVE_TENANT_ID() @@ -50244,10 +50696,12 @@ FROM ( T.TABLE_ID AS TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, + TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLET_ID != 0 AND T.PART_LEVEL = 0 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() @@ -50260,10 +50714,12 @@ FROM ( T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, + P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() @@ -50277,10 +50733,12 @@ FROM ( T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, + Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, - DUPLICATE_SCOPE + DUPLICATE_SCOPE, + TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT Q JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON P.PART_ID =Q.PART_ID AND Q.TENANT_ID = P.TENANT_ID JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID =P.TABLE_ID AND T.TENANT_ID = Q.TENANT_ID @@ -50289,6 +50747,7 @@ FROM ( JOIN SYS.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN SYS.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON A.DATABASE_ID = D.DATABASE_ID AND A.TENANT_ID = D.TENANT_ID + LEFT JOIN SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID ORDER BY A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT """.replace("\n", " "), ) diff --git a/src/share/inner_table/ob_inner_table_schema_misc.ipp b/src/share/inner_table/ob_inner_table_schema_misc.ipp index 0a6938d0b..b142b94a5 100644 --- a/src/share/inner_table/ob_inner_table_schema_misc.ipp +++ b/src/share/inner_table/ob_inner_table_schema_misc.ipp @@ -15,6 +15,7 @@ case OB_ALL_VIRTUAL_COLL_TYPE_SYS_AGENT_TID: case OB_ALL_VIRTUAL_LONG_OPS_STATUS_SYS_AGENT_TID: case OB_ALL_VIRTUAL_PACKAGE_SYS_AGENT_TID: +case OB_ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT_TID: case OB_ALL_VIRTUAL_ROUTINE_PARAM_SYS_AGENT_TID: case OB_ALL_VIRTUAL_ROUTINE_SYS_AGENT_TID: case OB_ALL_VIRTUAL_SERVER_AGENT_TID: @@ -29,6 +30,7 @@ case OB_TENANT_VIRTUAL_CHARSET_AGENT_TID: case OB_TENANT_VIRTUAL_CONCURRENT_LIMIT_SQL_AGENT_TID: case OB_TENANT_VIRTUAL_OUTLINE_AGENT_TID: case OB_TENANT_VIRTUAL_TABLE_INDEX_AGENT_TID: +case OB_ALL_VIRTUAL_RESOURCE_POOL_MYSQL_SYS_AGENT_TID: case OB_ALL_VIRTUAL_TENANT_MYSQL_SYS_AGENT_TID: case OB_ALL_VIRTUAL_VIRTUAL_LONG_OPS_STATUS_MYSQL_SYS_AGENT_TID: @@ -92,6 +94,24 @@ case OB_ALL_VIRTUAL_VIRTUAL_LONG_OPS_STATUS_MYSQL_SYS_AGENT_TID: break; } + case OB_ALL_VIRTUAL_RESOURCE_POOL_SYS_AGENT_TID: { + ObAgentVirtualTable *agent_iter = NULL; + const uint64_t base_tid = OB_ALL_RESOURCE_POOL_TID; + const bool sys_tenant_base_table = true; + const bool only_sys_data = true; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAgentVirtualTable, agent_iter))) { + SERVER_LOG(WARN, "create virtual table iterator failed", K(ret)); + } else if (OB_FAIL(agent_iter->init(base_tid, sys_tenant_base_table, index_schema, params, only_sys_data))) { + SERVER_LOG(WARN, "virtual table iter init failed", K(ret)); + agent_iter->~ObAgentVirtualTable(); + allocator.free(agent_iter); + agent_iter = NULL; + } else { + vt_iter = agent_iter; + } + break; + } + case OB_ALL_VIRTUAL_ROUTINE_PARAM_SYS_AGENT_TID: { ObAgentVirtualTable *agent_iter = NULL; const uint64_t base_tid = OB_ALL_ROUTINE_PARAM_TID; @@ -344,6 +364,24 @@ case OB_ALL_VIRTUAL_VIRTUAL_LONG_OPS_STATUS_MYSQL_SYS_AGENT_TID: break; } + case OB_ALL_VIRTUAL_RESOURCE_POOL_MYSQL_SYS_AGENT_TID: { + ObAgentVirtualTable *agent_iter = NULL; + const uint64_t base_tid = OB_ALL_RESOURCE_POOL_TID; + const bool sys_tenant_base_table = true; + const bool only_sys_data = false; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAgentVirtualTable, agent_iter))) { + SERVER_LOG(WARN, "create virtual table iterator failed", K(ret)); + } else if (OB_FAIL(agent_iter->init(base_tid, sys_tenant_base_table, index_schema, params, only_sys_data, Worker::CompatMode::MYSQL))) { + SERVER_LOG(WARN, "virtual table iter init failed", K(ret)); + agent_iter->~ObAgentVirtualTable(); + allocator.free(agent_iter); + agent_iter = NULL; + } else { + vt_iter = agent_iter; + } + break; + } + case OB_ALL_VIRTUAL_TENANT_MYSQL_SYS_AGENT_TID: { ObAgentVirtualTable *agent_iter = NULL; const uint64_t base_tid = OB_ALL_TENANT_TID; @@ -361,7 +399,9 @@ case OB_ALL_VIRTUAL_VIRTUAL_LONG_OPS_STATUS_MYSQL_SYS_AGENT_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_VIRTUAL_LONG_OPS_STATUS_MYSQL_SYS_AGENT_TID: { ObAgentVirtualTable *agent_iter = NULL; const uint64_t base_tid = OB_ALL_VIRTUAL_LONG_OPS_STATUS_TID; @@ -428,6 +468,7 @@ case OB_ALL_VIRTUAL_LS_REPLICA_TASK_TID: case OB_ALL_VIRTUAL_LS_RESTORE_HISTORY_TID: case OB_ALL_VIRTUAL_LS_RESTORE_PROGRESS_TID: case OB_ALL_VIRTUAL_LS_STATUS_TID: +case OB_ALL_VIRTUAL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID: case OB_ALL_VIRTUAL_MERGE_INFO_TID: case OB_ALL_VIRTUAL_RESTORE_JOB_TID: case OB_ALL_VIRTUAL_RESTORE_JOB_HISTORY_TID: @@ -437,6 +478,7 @@ case OB_ALL_VIRTUAL_TABLET_META_TABLE_TID: case OB_ALL_VIRTUAL_TABLET_REPLICA_CHECKSUM_TID: case OB_ALL_VIRTUAL_TASK_OPT_STAT_GATHER_HISTORY_TID: case OB_ALL_VIRTUAL_TENANT_INFO_TID: +case OB_ALL_VIRTUAL_TENANT_PARAMETER_TID: case OB_ALL_VIRTUAL_TENANT_USER_FAILED_LOGIN_STAT_TID: case OB_ALL_VIRTUAL_ZONE_MERGE_INFO_TID: @@ -1106,6 +1148,22 @@ case OB_ALL_VIRTUAL_ZONE_MERGE_INFO_TID: break; } + case OB_ALL_VIRTUAL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID: { + ObIteratePrivateVirtualTable *iter = NULL; + const bool meta_record_in_sys = false; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIteratePrivateVirtualTable, iter))) { + SERVER_LOG(WARN, "create iterate private virtual table iterator failed", KR(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID, meta_record_in_sys, index_schema, params))) { + SERVER_LOG(WARN, "iterate private virtual table iter init failed", KR(ret)); + iter->~ObIteratePrivateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + case OB_ALL_VIRTUAL_MERGE_INFO_TID: { ObIteratePrivateVirtualTable *iter = NULL; const bool meta_record_in_sys = false; @@ -1250,6 +1308,22 @@ case OB_ALL_VIRTUAL_ZONE_MERGE_INFO_TID: break; } + case OB_ALL_VIRTUAL_TENANT_PARAMETER_TID: { + ObIteratePrivateVirtualTable *iter = NULL; + const bool meta_record_in_sys = false; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIteratePrivateVirtualTable, iter))) { + SERVER_LOG(WARN, "create iterate private virtual table iterator failed", KR(ret)); + } else if (OB_FAIL(iter->init(OB_TENANT_PARAMETER_TID, meta_record_in_sys, index_schema, params))) { + SERVER_LOG(WARN, "iterate private virtual table iter init failed", KR(ret)); + iter->~ObIteratePrivateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + case OB_ALL_VIRTUAL_TENANT_USER_FAILED_LOGIN_STAT_TID: { ObIteratePrivateVirtualTable *iter = NULL; const bool meta_record_in_sys = false; @@ -1289,6 +1363,10 @@ case OB_ALL_VIRTUAL_ZONE_MERGE_INFO_TID: #ifdef ITERATE_VIRTUAL_TABLE_LOCATION_SWITCH case OB_ALL_VIRTUAL_AUTO_INCREMENT_TID: +case OB_ALL_VIRTUAL_BALANCE_JOB_TID: +case OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_TID: +case OB_ALL_VIRTUAL_BALANCE_TASK_TID: +case OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_TID: case OB_ALL_VIRTUAL_COLL_TYPE_TID: case OB_ALL_VIRTUAL_COLL_TYPE_HISTORY_TID: case OB_ALL_VIRTUAL_COLUMN_TID: @@ -1423,6 +1501,8 @@ case OB_ALL_VIRTUAL_TIME_ZONE_TID: case OB_ALL_VIRTUAL_TIME_ZONE_NAME_TID: case OB_ALL_VIRTUAL_TIME_ZONE_TRANSITION_TID: case OB_ALL_VIRTUAL_TIME_ZONE_TRANSITION_TYPE_TID: +case OB_ALL_VIRTUAL_TRANSFER_TASK_TID: +case OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_TID: case OB_ALL_VIRTUAL_TRIGGER_TID: case OB_ALL_VIRTUAL_TRIGGER_HISTORY_TID: case OB_ALL_VIRTUAL_TYPE_TID: @@ -1453,6 +1533,66 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: break; } + case OB_ALL_VIRTUAL_BALANCE_JOB_TID: { + ObIterateVirtualTable *iter = NULL; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { + SERVER_LOG(WARN, "create virtual table iterator failed", K(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_BALANCE_JOB_TID, index_schema, params))) { + SERVER_LOG(WARN, "virtual table iter init failed", K(ret)); + iter->~ObIterateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + + case OB_ALL_VIRTUAL_BALANCE_JOB_HISTORY_TID: { + ObIterateVirtualTable *iter = NULL; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { + SERVER_LOG(WARN, "create virtual table iterator failed", K(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_BALANCE_JOB_HISTORY_TID, index_schema, params))) { + SERVER_LOG(WARN, "virtual table iter init failed", K(ret)); + iter->~ObIterateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + + case OB_ALL_VIRTUAL_BALANCE_TASK_TID: { + ObIterateVirtualTable *iter = NULL; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { + SERVER_LOG(WARN, "create virtual table iterator failed", K(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_BALANCE_TASK_TID, index_schema, params))) { + SERVER_LOG(WARN, "virtual table iter init failed", K(ret)); + iter->~ObIterateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + + case OB_ALL_VIRTUAL_BALANCE_TASK_HISTORY_TID: { + ObIterateVirtualTable *iter = NULL; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { + SERVER_LOG(WARN, "create virtual table iterator failed", K(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_BALANCE_TASK_HISTORY_TID, index_schema, params))) { + SERVER_LOG(WARN, "virtual table iter init failed", K(ret)); + iter->~ObIterateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + case OB_ALL_VIRTUAL_COLL_TYPE_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -1677,7 +1817,9 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_DATABASE_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -1737,9 +1879,7 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_DBLINK_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -1979,7 +2119,9 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_FUNC_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -2039,9 +2181,7 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_JOB_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -2281,7 +2421,9 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_PACKAGE_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -2341,9 +2483,7 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_PART_INFO_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -2583,7 +2723,9 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_ROUTINE_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -2643,9 +2785,7 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_SECURITY_AUDIT_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -2885,7 +3025,9 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TABLE_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -2945,9 +3087,7 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TABLE_STAT_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -3187,7 +3327,9 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TENANT_OLS_LABEL_HISTORY_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -3247,9 +3389,7 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TENANT_OLS_USER_LEVEL_HISTORY_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -3475,6 +3615,38 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: break; } + case OB_ALL_VIRTUAL_TRANSFER_TASK_TID: { + ObIterateVirtualTable *iter = NULL; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { + SERVER_LOG(WARN, "create virtual table iterator failed", K(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_TRANSFER_TASK_TID, index_schema, params))) { + SERVER_LOG(WARN, "virtual table iter init failed", K(ret)); + iter->~ObIterateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + END_CREATE_VT_ITER_SWITCH_LAMBDA + + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA + case OB_ALL_VIRTUAL_TRANSFER_TASK_HISTORY_TID: { + ObIterateVirtualTable *iter = NULL; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { + SERVER_LOG(WARN, "create virtual table iterator failed", K(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_TRANSFER_TASK_HISTORY_TID, index_schema, params))) { + SERVER_LOG(WARN, "virtual table iter init failed", K(ret)); + iter->~ObIterateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + case OB_ALL_VIRTUAL_TRIGGER_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -3549,9 +3721,7 @@ case OB_ALL_VIRTUAL_USER_HISTORY_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TYPE_HISTORY_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -3673,6 +3843,9 @@ case OB_ALL_BACKUP_TASK_HISTORY_AUX_LOB_PIECE_TID: case OB_ALL_BALANCE_GROUP_LS_STAT_TID: case OB_ALL_BALANCE_GROUP_LS_STAT_AUX_LOB_META_TID: case OB_ALL_BALANCE_GROUP_LS_STAT_AUX_LOB_PIECE_TID: +case OB_ALL_BALANCE_TASK_HELPER_TID: +case OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TID: +case OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TID: case OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_TID: case OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_META_TID: case OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_PIECE_TID: @@ -3728,6 +3901,9 @@ case OB_ALL_LS_RESTORE_PROGRESS_AUX_LOB_PIECE_TID: case OB_ALL_LS_STATUS_TID: case OB_ALL_LS_STATUS_AUX_LOB_META_TID: case OB_ALL_LS_STATUS_AUX_LOB_PIECE_TID: +case OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TID: +case OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_META_TID: +case OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_AUX_LOB_PIECE_TID: case OB_ALL_MERGE_INFO_TID: case OB_ALL_MERGE_INFO_AUX_LOB_META_TID: case OB_ALL_MERGE_INFO_AUX_LOB_PIECE_TID: diff --git a/src/share/io/ob_io_define.cpp b/src/share/io/ob_io_define.cpp index 6c748d236..314373b9b 100644 --- a/src/share/io/ob_io_define.cpp +++ b/src/share/io/ob_io_define.cpp @@ -178,10 +178,10 @@ ObIOCallback::~ObIOCallback() } -int ObIOCallback::process(const bool is_success) +int ObIOCallback::process(const char *data_buffer, const int64_t size) { lib::set_compat_mode(compat_mode_); - return inner_process(is_success); + return inner_process(data_buffer, size); } int ObIOCallback::deep_copy(char *buf, const int64_t buf_len, ObIOCallback *&copied_callback) const @@ -392,10 +392,7 @@ void ObIORequest::destroy() control_block_ = nullptr; } io_info_.reset(); - if (nullptr != raw_buf_ && nullptr != tenant_io_mgr_.get_ptr()) { - tenant_io_mgr_.get_ptr()->io_allocator_.free(raw_buf_); - raw_buf_ = nullptr; - } + free_io_buffer(); io_buf_ = nullptr; io_offset_ = 0; io_size_ = 0; @@ -455,8 +452,22 @@ const char *ObIORequest::get_data() buf = io_buf_; } else { // re-calculate with const parameters, in case of partial return change aligned_buf and so on. + + //todo QILU: buf = get_user_data_buf(),完成no_callback memcpy改造后替换 + buf = get_io_data_buf(); + } + return buf; +} + +const char *ObIORequest::get_io_data_buf() +{ + char *buf = nullptr; + int ret = OB_SUCCESS; + if (OB_UNLIKELY(nullptr == raw_buf_)) { + LOG_ERROR("raw buf is null, maybe has been recycle"); + } else { const int64_t aligned_offset = lower_align(io_info_.offset_, DIO_READ_ALIGN_SIZE); - const char *aligned_buf = reinterpret_cast(upper_align(reinterpret_cast(raw_buf_), DIO_READ_ALIGN_SIZE)); + char *aligned_buf = reinterpret_cast(upper_align(reinterpret_cast(raw_buf_), DIO_READ_ALIGN_SIZE)); buf = aligned_buf + io_info_.offset_ - aligned_offset; } return buf; @@ -499,21 +510,18 @@ int ObIORequest::alloc_aligned_io_buf() && OB_UNLIKELY(!is_io_aligned(io_info_.offset_) || !is_io_aligned(io_info_.size_))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("write io info not aligned", K(ret), K(io_info_)); - } else if (nullptr == copied_callback_) { + } else { align_offset_size(io_info_.offset_, io_info_.size_, io_offset_, io_size_); + const int64_t io_buffer_size = io_size_ + DIO_READ_ALIGN_SIZE; if (OB_ISNULL(tenant_io_mgr_.get_ptr())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tenant io manager is null", K(ret)); - } else if (OB_ISNULL(raw_buf_ = tenant_io_mgr_.get_ptr()->io_allocator_.alloc(io_size_ + DIO_READ_ALIGN_SIZE))) { + } else if (OB_ISNULL(raw_buf_ = tenant_io_mgr_.get_ptr()->io_allocator_.alloc(io_buffer_size))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("allocate memory failed", K(ret), K(io_size_)); } else { io_buf_ = reinterpret_cast(upper_align(reinterpret_cast(raw_buf_), DIO_READ_ALIGN_SIZE)); } - } else { - if (OB_FAIL(copied_callback_->alloc_io_buf(io_buf_, io_size_, io_offset_))) { - LOG_WARN("callback allocate memory failed", K(ret), K(io_info_)); - } } if (OB_SUCC(ret)) { if (OB_ISNULL(io_buf_)) { @@ -581,6 +589,14 @@ bool ObIORequest::can_callback() const return nullptr != copied_callback_ && nullptr != io_buf_; } +void ObIORequest::free_io_buffer() +{ + if (nullptr != raw_buf_ && nullptr != tenant_io_mgr_.get_ptr()) { + tenant_io_mgr_.get_ptr()->io_allocator_.free(raw_buf_); + raw_buf_ = nullptr; + } +} + void ObIORequest::cancel() { int ret = OB_SUCCESS; diff --git a/src/share/io/ob_io_define.h b/src/share/io/ob_io_define.h index 826d25393..fb341b5a5 100644 --- a/src/share/io/ob_io_define.h +++ b/src/share/io/ob_io_define.h @@ -103,12 +103,11 @@ public: ObIOCallback(); virtual ~ObIOCallback(); - int process(const bool is_success); + int process(const char *data_buffer, const int64_t size); int deep_copy(char *buf, const int64_t buf_len, ObIOCallback *&copied_callback) const; virtual const char *get_data() = 0; virtual int64_t size() const = 0; - virtual int alloc_io_buf(char *&io_buf, int64_t &io_buf_size, int64_t &aligned_offset) = 0; - virtual int inner_process(const bool is_success) = 0; + virtual int inner_process(const char *data_buffer, const int64_t size) = 0; virtual int inner_deep_copy(char *buf, const int64_t buf_len, ObIOCallback *&copied_callback) const = 0; DECLARE_PURE_VIRTUAL_TO_STRING; @@ -211,13 +210,14 @@ public: int64_t get_data_size() const; int64_t get_group_id() const; uint64_t get_io_usage_index(); - const char *get_data(); + const char *get_data(); //get data buf after io_buf recycle const ObIOFlag &get_flag() const; ObIOMode get_mode() const; void cancel(); int alloc_io_buf(); int prepare(); bool can_callback() const; + void free_io_buffer(); void finish(const ObIORetCode &ret_code); void inc_ref(const char *msg = nullptr); void dec_ref(const char *msg = nullptr); @@ -228,6 +228,8 @@ public: K(time_log_), KP(channel_), K(ref_cnt_), K(out_ref_cnt_), K(trace_id_), K(ret_code_), K(retry_count_), K(callback_buf_size_), KP(copied_callback_), K(tenant_io_mgr_)); private: + friend class ObIORunner; + const char *get_io_data_buf(); //get data buf for MEMCPY before io_buf recycle int alloc_aligned_io_buf(); public: bool is_inited_; @@ -238,8 +240,8 @@ public: int64_t deadline_ts_; int64_t sender_index_; ObIOCB *control_block_; - void *raw_buf_; - char *io_buf_; + void *raw_buf_;//actual allocated buf + char *io_buf_;//the aligned one of raw_buf_, interact with the operating system int64_t io_offset_; int64_t io_size_; int64_t complete_size_; diff --git a/src/share/io/ob_io_manager.cpp b/src/share/io/ob_io_manager.cpp index 9236ca53c..585bbf050 100644 --- a/src/share/io/ob_io_manager.cpp +++ b/src/share/io/ob_io_manager.cpp @@ -237,6 +237,8 @@ int ObIOManager::pread(ObIOInfo &info, int64_t &read_size) if (OB_DATA_OUT_OF_RANGE != ret) { LOG_WARN("sync read failed", K(ret), K(info)); } + } else { + break; } } } @@ -271,8 +273,10 @@ int ObIOManager::pwrite(ObIOInfo &info, int64_t &write_size) while (OB_SUCC(ret) || OB_TIMEOUT == ret) { // wait to die if (OB_FAIL(handle.wait(MAX_IO_WAIT_TIME_MS))) { if (OB_DATA_OUT_OF_RANGE != ret) { - LOG_WARN("sync read failed", K(ret), K(info)); + LOG_WARN("sync write failed", K(ret), K(info)); } + } else { + break; } } } @@ -728,8 +732,6 @@ int ObTenantIOManager::inner_aio(const ObIOInfo &info, ObIOHandle &handle) int ret = OB_SUCCESS; handle.reset(); ObIORequest *req = nullptr; - bool data_hang = false; - bool slog_hang = false; const int64_t callback_size = nullptr == info.callback_ ? 0 : info.callback_->size(); logservice::coordinator::ObFailureDetector *detector = MTL(logservice::coordinator::ObFailureDetector *); if (OB_UNLIKELY(!is_inited_)) { @@ -738,11 +740,10 @@ int ObTenantIOManager::inner_aio(const ObIOInfo &info, ObIOHandle &handle) } else if (OB_UNLIKELY(!is_working())) { ret = OB_STATE_NOT_MATCH; LOG_WARN("tenant not working", K(ret), K(tenant_id_)); - } else if (NULL != detector && - detector->is_data_disk_has_fatal_error(slog_hang, data_hang)) { // also consider slog writer hung + } else if (NULL != detector && detector->is_data_disk_has_fatal_error()) { ret = OB_DISK_HUNG; // for temporary positioning issue, get lbt of log replay - LOG_DBA_ERROR(OB_DISK_HUNG, "msg", "data disk or slog disk has fatal error", K(slog_hang), K(data_hang)); + LOG_DBA_ERROR(OB_DISK_HUNG, "msg", "data disk has fatal error"); } else if (OB_FAIL(alloc_io_request(io_allocator_, callback_size, req))) { LOG_WARN("alloc io request failed", K(ret), KP(req)); } else if (FALSE_IT(req->tenant_io_mgr_.hold(this))) { diff --git a/src/share/io/ob_io_struct.cpp b/src/share/io/ob_io_struct.cpp index c1d6d730f..55992568f 100644 --- a/src/share/io/ob_io_struct.cpp +++ b/src/share/io/ob_io_struct.cpp @@ -227,7 +227,7 @@ int ObIOAllocator::init(const uint64_t tenant_id, const int64_t memory_limit) } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || memory_limit <= 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(tenant_id), K(memory_limit)); - } else if (OB_FAIL(inner_allocator_.init(OB_MALLOC_BIG_BLOCK_SIZE, + } else if (OB_FAIL(inner_allocator_.init(OB_MALLOC_MIDDLE_BLOCK_SIZE, ObModIds::OB_IO_CONTROL, tenant_id, memory_limit))) { @@ -2516,10 +2516,14 @@ int ObIORunner::handle(ObIORequest *req) } else if (!req->can_callback()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("io request can not do callback", K(ret), K(*req)); - } else if (OB_FAIL(req->copied_callback_->process(OB_SUCCESS == req->ret_code_.io_ret_))) { + } else if (OB_FAIL(req->ret_code_.io_ret_)) { + //failed, ignore + } else if (OB_FAIL(req->copied_callback_->process(req->get_io_data_buf(), req->io_info_.size_))) { LOG_WARN("fail to callback", K(ret), K(*req), K(MTL_ID())); } req->time_log_.callback_finish_ts_ = ObTimeUtility::fast_current_time(); + //recycle buffer after process + req->free_io_buffer(); } req->finish(ret); } diff --git a/src/share/location_cache/ob_location_service.cpp b/src/share/location_cache/ob_location_service.cpp index a095c67e0..9b0e6fc71 100644 --- a/src/share/location_cache/ob_location_service.cpp +++ b/src/share/location_cache/ob_location_service.cpp @@ -13,7 +13,12 @@ #define USING_LOG_PREFIX SHARE_LOCATION #include "share/location_cache/ob_location_service.h" +#include "share/config/ob_server_config.h" // GCONF #include "share/inner_table/ob_inner_table_schema.h" +#include "share/schema/ob_multi_version_schema_service.h" // ObMultiVersionSchemaService +#include "observer/ob_server_struct.h" // GCTX +#include "lib/utility/ob_tracepoint.h" // ERRSIM_POINT_DEF +#include "share/ls/ob_ls_status_operator.h" // ObLSStatus namespace oceanbase { @@ -336,7 +341,7 @@ int ObLocationService::destroy() LOG_WARN("destroy ls_location_service failed", KR(ret)); } else if (OB_FAIL(tablet_ls_service_.destroy())) { LOG_WARN("destroy tablet_ls_service failed", KR(ret)); - } else if(OB_FAIL(vtable_location_service_.destroy())){ + } else if (OB_FAIL(vtable_location_service_.destroy())) { LOG_WARN("destroy vtable_location_service failed", KR(ret)); } else { stopped_ = true; @@ -356,10 +361,256 @@ int ObLocationService::reload_config() LOG_WARN("ls_location_service reload config failed", KR(ret)); } else if (OB_FAIL(tablet_ls_service_.reload_config())) { LOG_WARN("tablet_ls_service reload config failed", KR(ret)); + } else if (OB_FAIL(vtable_location_service_.reload_config())) { + LOG_WARN("vtable_location_service reload config failed", KR(ret)); } } return ret; } +int ObLocationService::batch_renew_tablet_locations( + const uint64_t tenant_id, + const ObList &tablet_list, + const int error_code, + const bool is_nonblock) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (0 == tablet_list.size()) { + // do nothing + } else { + ObArray ls_ids; + RenewType renew_type = DEFAULT_RENEW_BOTH; + renew_type = gen_renew_type_(error_code); + ObArray tablet_ls_caches; + ObArray ls_locations; + // 1. renew tablet ls mapping + if (OB_FAIL(ret)) { + } else if (ONLY_RENEW_LS_LOCATION != renew_type) { + if (is_nonblock) { + FOREACH_X(tablet_id, tablet_list, OB_SUCC(ret)) { + if (OB_FAIL(tablet_ls_service_.nonblock_renew(tenant_id, *tablet_id))) { + LOG_WARN("nonblock renew failed", KR(ret), K(tenant_id), K(*tablet_id)); + } + } + } else if (OB_FAIL(tablet_ls_service_.batch_renew_tablet_ls_cache( // block + tenant_id, + tablet_list, + tablet_ls_caches))) { + LOG_WARN("batch renew cache failed", KR(ret), K(tenant_id), K(tablet_list)); + } + } + // 2. renew ls location + if (OB_FAIL(ret)) { + } else if (ONLY_RENEW_TABLET_LS_MAPPING != renew_type) { + if (is_nonblock) { + if (OB_FAIL(ls_location_service_.nonblock_renew(GCONF.cluster_id, tenant_id))) { + LOG_WARN("nonblock renew tenant ls locations failed", KR(ret), K(tenant_id)); + } + } else if (!tablet_ls_caches.empty()) { // block renew both + ls_ids.reset(); + ARRAY_FOREACH(tablet_ls_caches, idx) { + const ObTabletLSCache &tablet_ls = tablet_ls_caches.at(idx); + if (!common::has_exist_in_array(ls_ids, tablet_ls.get_ls_id())) { + if (OB_FAIL(ls_ids.push_back(tablet_ls.get_ls_id()))) { + LOG_WARN("push back failed", KR(ret), K(tablet_ls)); + } + } + } + if (FAILEDx(ls_location_service_.batch_renew_ls_locations( + GCONF.cluster_id, + tenant_id, + ls_ids, + ls_locations))) { + LOG_WARN("batch renew cache failed", KR(ret), K(tenant_id), K(tablet_list), K(ls_ids)); + } + } else { // block only renew ls location or block renew both with empty tablet_ls_caches + if (OB_FAIL(ls_location_service_.renew_location_for_tenant( + GCONF.cluster_id, + tenant_id, + ls_locations))) { + LOG_WARN("renew location for tenant failed", KR(ret), K(tenant_id), K(ls_locations)); + } + } + } + FLOG_INFO("[TABLET_LOCATION] batch renew tablet locations finished", + KR(ret), K(tenant_id), K(renew_type), K(is_nonblock), K(tablet_list), K(ls_ids)); + } + return ret; +} + +// ONLY_RENEW_TABLET_LS_MAPPING is not used yet +ObLocationService::RenewType ObLocationService::gen_renew_type_(const int error) const +{ + RenewType renew_type = DEFAULT_RENEW_BOTH; + switch (error) { + case OB_NOT_MASTER: { + renew_type = ONLY_RENEW_LS_LOCATION; + break; + } + default: { + renew_type = DEFAULT_RENEW_BOTH; + break; + } + } + return renew_type; +} + +int ObLocationService::renew_tablet_location( + const uint64_t tenant_id, + const common::ObTabletID &tablet_id, + const int error_code, + const bool is_nonblock) +{ + int ret = OB_SUCCESS; + ObArenaAllocator allocator; + ObList tablet_list(allocator); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(!tablet_id.is_valid_with_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(tablet_id)); + } else if (OB_FAIL(tablet_list.push_back(tablet_id))) { + LOG_WARN("push back failed", KR(ret), K(tablet_id)); + } else if (OB_FAIL(batch_renew_tablet_locations(tenant_id, tablet_list, error_code, is_nonblock))) { + LOG_WARN("renew tablet locations failed", KR(ret), + K(tenant_id), K(tablet_list), K(error_code), K(is_nonblock)); + } + return ret; +} + +ERRSIM_POINT_DEF(EN_CHECK_LS_EXIST_WITH_TENANT_NOT_NORMAL); + +int ObLocationService::check_ls_exist( + const uint64_t tenant_id, + const ObLSID &ls_id, + ObLSExistState &state) +{ + int ret = OB_SUCCESS; + state.reset(); + ObSqlString sql; + if (OB_UNLIKELY(!ls_id.is_valid_with_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(ls_id)); + } else if (OB_ISNULL(GCTX.schema_service_) || OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("GCTX has null ptr", KR(ret), KP(GCTX.schema_service_), KP(GCTX.sql_proxy_)); + } else { + schema::ObSchemaGetterGuard schema_guard; + const ObSimpleTenantSchema *tenant_schema = NULL; + if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get tenant schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) { + LOG_WARN("fail to get tenant schema", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant does not exist", KR(ret), K(tenant_id)); + } else if ((is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id)) + && (tenant_schema->is_normal() || tenant_schema->is_dropping())) { + // sys and meta tenants only have sys ls. If tenant is in normal or dropping status, sys ls exists. + state.set_existing(); + } + } // release schema_guard as soon as possible + + // errsim for test + if (EN_CHECK_LS_EXIST_WITH_TENANT_NOT_NORMAL) { + state.reset(); + } + + if (OB_FAIL(ret) || state.is_valid()) { + } else if (OB_FAIL(construct_check_ls_exist_sql_(tenant_id, ls_id, sql))) { + LOG_WARN("construct check ls exist sql failed", KR(ret), K(tenant_id), K(ls_id), K(sql)); + } else { + SMART_VAR(ObISQLClient::ReadResult, result) { + int64_t ls_state = -1; + common::sqlclient::ObMySQLResult *res = NULL; + const uint64_t exec_tenant_id = get_private_table_exec_tenant_id(tenant_id); + if (OB_FAIL(GCTX.sql_proxy_->read(result, exec_tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), + K(tenant_id), K(ls_id), K(exec_tenant_id), K(sql)); + } else if (OB_ISNULL(res = result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), + K(tenant_id), K(ls_id), K(exec_tenant_id), K(sql)); + } else if (OB_FAIL(res->next())) { + LOG_WARN("next failed", KR(ret), K(tenant_id), K(ls_id), K(sql)); + } else if (OB_FAIL(res->get_int("ls_state", ls_state))) { + LOG_WARN("fail to get ls_state", KR(ret), K(tenant_id), K(ls_id)); + } else if (OB_UNLIKELY(ls_state <= ObLSExistState::INVALID_STATE + || ls_state >= ObLSExistState::MAX_STATE)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected state value", KR(ret), K(ls_state), K(tenant_id), K(ls_id), K(sql)); + } else { + state = ObLSExistState(ObLSExistState::State(ls_state)); + } + LOG_INFO("check ls exist finished", KR(ret), K(tenant_id), K(ls_id), K(ls_state), K(state), K(sql)); + } + } + return ret; +} + +// 1.relationship between ObLSStatus and ObLSExistState +// +// CREATING --> UNCREATED +// CREATE_ABORT --> DELETED +// OTHER --> EXISTING +// +// 2.check ls exist for sys and meta tenants only accesses __all_ls_status; +// for user tenant need access __all_ls_status and __all_tenant_info; +int ObLocationService::construct_check_ls_exist_sql_( + const uint64_t tenant_id, + const ObLSID &ls_id, + ObSqlString &sql) +{ + int ret = OB_SUCCESS; + sql.reset(); + if (OB_UNLIKELY(!ls_id.is_valid_with_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(sql.append_fmt( + "SELECT CASE WHEN exist = 1 THEN " + "(CASE WHEN status = '%s' THEN %d WHEN status = '%s' THEN %d ELSE %d END) ", + ls_status_to_str(ObLSStatus::OB_LS_CREATING), + ObLSExistState::UNCREATED, + ls_status_to_str(ObLSStatus::OB_LS_CREATE_ABORT), + ObLSExistState::DELETED, + ObLSExistState::EXISTING))) { + LOG_WARN("assign sql failed", KR(ret), K(tenant_id), K(ls_id), K(sql)); + } else if (is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id)) { + if (OB_FAIL(sql.append_fmt("ELSE %d END AS ls_state ", ObLSExistState::UNCREATED))) { + LOG_WARN("assign sql failed", KR(ret), K(tenant_id), K(ls_id), K(sql)); + } + } else if (is_user_tenant(tenant_id)) { // need max_ls_id + if (OB_FAIL(sql.append_fmt( + "ELSE (SELECT CASE WHEN max_ls_id < %ld THEN %d ELSE %d END FROM %s WHERE tenant_id = %lu) END AS ls_state ", + ls_id.id(), + ObLSExistState::UNCREATED, + ObLSExistState::DELETED, + OB_ALL_TENANT_INFO_TNAME, + tenant_id))) { + LOG_WARN("assign sql failed", KR(ret), K(tenant_id), K(ls_id), K(sql)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("can't be here", KR(ret), K(tenant_id), K(ls_id), K(sql)); + } + + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(sql.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql can't be empty", KR(ret), K(tenant_id), K(ls_id), K(sql)); + } else if (OB_FAIL(sql.append_fmt( + "FROM (SELECT COUNT(*) > 0 as exist, status FROM %s WHERE tenant_id = %lu AND ls_id = %ld)", + OB_ALL_LS_STATUS_TNAME, + tenant_id, + ls_id.id()))) { + LOG_WARN("assign sql failed", KR(ret), K(tenant_id), K(ls_id), K(sql)); + } + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/location_cache/ob_location_service.h b/src/share/location_cache/ob_location_service.h index b4dfa2007..26c804f96 100644 --- a/src/share/location_cache/ob_location_service.h +++ b/src/share/location_cache/ob_location_service.h @@ -148,6 +148,27 @@ public: int nonblock_renew( const uint64_t tenant_id, const ObTabletID &tablet_id); + + // renew location cache according to error_code for tablets + // + // @param [in] tenant_id: target tenant which the tablets belong to + // @param [in] tablet_list: target tablet_id list(there may be duplicate values) + // @param [in] error_code: the error code form sql which needs retry + // @param [in] is_nonblock: renew locations synchronously or asynchronously + // @return OB_GET_LOCATION_TIME_OUT if inner_sql timeout when you block renew + int batch_renew_tablet_locations( + const uint64_t tenant_id, + const ObList &tablet_list, + const int error_code, + const bool is_nonblock); + + // renew tablet ls mapping and ls location according to error_code + // implementation is based on batch_renew_tablet_locations + int renew_tablet_location( + const uint64_t tenant_id, + const common::ObTabletID &tablet_id, + const int error_code, + const bool is_nonblock); // ----------------------- End interfaces for tablet to log stream ----------------------- // ----------------------- Interfaces for virtual table location ------------------------- @@ -181,6 +202,19 @@ public: const uint64_t table_id); // --------------------- End interfaces for virtual table location ----------------------- + /* check if the ls exists by querying __all_ls_status and __all_tenant_info + * + * @param[in] tenant_id: target tenant_id + * @param[in] ls_id: target ls_id + * @param[out] state: EXISTING/DELETED/UNCREATED + * @return + * - OB_SUCCESS: check successfully + * - OB_TENANT_NOT_EXIST: tenant not exist + * - OB_INVALID_ARGUMENT: invalid ls_id or tenant_id + * - other: other failures + */ + static int check_ls_exist(const uint64_t tenant_id, const ObLSID &ls_id, ObLSExistState &state); + int init( ObLSTableOperator &ls_pt, schema::ObMultiVersionSchemaService &schema_service, @@ -195,6 +229,18 @@ public: int destroy(); int reload_config(); +private: + enum RenewType { + DEFAULT_RENEW_BOTH = 0, + ONLY_RENEW_TABLET_LS_MAPPING = 1, + ONLY_RENEW_LS_LOCATION = 2 + }; + RenewType gen_renew_type_(const int error) const; + + static int construct_check_ls_exist_sql_( + const uint64_t tenant_id, + const ObLSID &ls_id, + ObSqlString &sql); private: bool inited_; bool stopped_; diff --git a/src/share/location_cache/ob_location_struct.cpp b/src/share/location_cache/ob_location_struct.cpp index b0c2d5ea6..6c36f234a 100644 --- a/src/share/location_cache/ob_location_struct.cpp +++ b/src/share/location_cache/ob_location_struct.cpp @@ -1105,11 +1105,7 @@ int ObLocationSem::acquire(const int64_t abs_timeout_us) if (wait_time_ms > INT32_MAX) { wait_time_ms = INT32_MAX; const bool force_print = true; - BACKTRACE(ERROR, - force_print, - "Invalid wait time, use INT32_MAX. wait_time_ms=%ld abs_timeout_us=%ld", - wait_time_ms, - abs_timeout_us); + LOG_DEBUG("wait time is longer than INT32_MAX", K(wait_time_ms), K(abs_timeout_us)); } has_wait = true; cond_.wait(static_cast(wait_time_ms)); diff --git a/src/share/location_cache/ob_location_struct.h b/src/share/location_cache/ob_location_struct.h index 6fc4499aa..e70509fac 100644 --- a/src/share/location_cache/ob_location_struct.h +++ b/src/share/location_cache/ob_location_struct.h @@ -399,6 +399,34 @@ private: common::ObThreadCond cond_; }; +struct ObLSExistState final +{ +public: + enum State + { + INVALID_STATE = -1, + UNCREATED, + DELETED, + EXISTING, + MAX_STATE + }; + ObLSExistState() : state_(INVALID_STATE) {} + ObLSExistState(State state) : state_(state) {} + ~ObLSExistState() {} + void reset() { state_ = INVALID_STATE; } + void set_existing() { state_ = EXISTING; } + void set_deleted() { state_ = DELETED; } + void set_uncreated() { state_ = UNCREATED; } + bool is_valid() const { return state_ > INVALID_STATE && state_ < MAX_STATE; } + bool is_existing() const { return EXISTING == state_; } + bool is_deleted() const { return DELETED == state_; } + bool is_uncreated() const { return UNCREATED == state_; } + + TO_STRING_KV(K_(state)); +private: + State state_; +}; + } // end namespace share } // end namespace oceanbase #endif diff --git a/src/share/location_cache/ob_location_update_task.cpp b/src/share/location_cache/ob_location_update_task.cpp index 64982dbba..f8d4852d8 100644 --- a/src/share/location_cache/ob_location_update_task.cpp +++ b/src/share/location_cache/ob_location_update_task.cpp @@ -24,13 +24,21 @@ int ObLSLocationUpdateTask::init( const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id, + const bool renew_for_tenant, const int64_t add_timestamp) { int ret = OB_SUCCESS; - cluster_id_ = cluster_id; - tenant_id_ = tenant_id; - ls_id_ = ls_id; - add_timestamp_ = add_timestamp; + if (OB_UNLIKELY(OB_INVALID_CLUSTER_ID == cluster_id + || !ls_id.is_valid_with_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); + } else { + cluster_id_ = cluster_id; + tenant_id_ = tenant_id; + ls_id_ = ls_id; + renew_for_tenant_ = renew_for_tenant; + add_timestamp_ = add_timestamp; + } return ret; } @@ -39,6 +47,7 @@ void ObLSLocationUpdateTask::reset() cluster_id_ = OB_INVALID_CLUSTER_ID; tenant_id_ = OB_INVALID_TENANT_ID; ls_id_.reset(); + renew_for_tenant_ = false; add_timestamp_ = OB_INVALID_TIMESTAMP; } @@ -57,6 +66,7 @@ int ObLSLocationUpdateTask::assign(const ObLSLocationUpdateTask &other) cluster_id_ = other.cluster_id_; tenant_id_ = other.tenant_id_; ls_id_ = other.ls_id_; + renew_for_tenant_ = other.renew_for_tenant_; add_timestamp_ = other.add_timestamp_; } return ret; @@ -68,6 +78,7 @@ int64_t ObLSLocationUpdateTask::hash() const hash_val = murmurhash(&cluster_id_, sizeof(cluster_id_), hash_val); hash_val = murmurhash(&tenant_id_, sizeof(tenant_id_), hash_val); hash_val = murmurhash(&ls_id_, sizeof(ls_id_), hash_val); + hash_val = murmurhash(&renew_for_tenant_, sizeof(renew_for_tenant_), hash_val); return hash_val; } @@ -81,7 +92,8 @@ bool ObLSLocationUpdateTask::operator ==(const ObLSLocationUpdateTask &other) co } else { equal = (cluster_id_ == other.cluster_id_ && tenant_id_ == other.tenant_id_ - && ls_id_ == other.ls_id_); + && ls_id_ == other.ls_id_ + && renew_for_tenant_ == other.renew_for_tenant_); } return equal; } diff --git a/src/share/location_cache/ob_location_update_task.h b/src/share/location_cache/ob_location_update_task.h index 0e9b22263..2df686d4f 100644 --- a/src/share/location_cache/ob_location_update_task.h +++ b/src/share/location_cache/ob_location_update_task.h @@ -30,21 +30,25 @@ public: : cluster_id_(OB_INVALID_CLUSTER_ID), tenant_id_(OB_INVALID_TENANT_ID), ls_id_(), + renew_for_tenant_(false), add_timestamp_(OB_INVALID_TIMESTAMP) {} explicit ObLSLocationUpdateTask( const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id, + const bool renew_for_tenant, const int64_t add_timestamp) : cluster_id_(cluster_id), tenant_id_(tenant_id), ls_id_(ls_id), + renew_for_tenant_(renew_for_tenant), add_timestamp_(add_timestamp) {} virtual ~ObLSLocationUpdateTask() {} int init( const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id, + const bool renew_for_tenant, const int64_t add_timestamp); int assign(const ObLSLocationUpdateTask &other); virtual void reset(); @@ -64,12 +68,14 @@ public: inline int64_t get_tenant_id() const { return tenant_id_; } inline ObLSID get_ls_id() const { return ls_id_; } inline int64_t get_add_timestamp() const { return add_timestamp_; } + inline bool is_renew_for_tenant() const { return renew_for_tenant_; } - TO_STRING_KV(K_(cluster_id), K_(tenant_id), K_(ls_id), K_(add_timestamp)); + TO_STRING_KV(K_(cluster_id), K_(tenant_id), K_(ls_id), K_(renew_for_tenant), K_(add_timestamp)); private: int64_t cluster_id_; uint64_t tenant_id_; ObLSID ls_id_; + bool renew_for_tenant_; // renew all ls location caches for tenant int64_t add_timestamp_; }; diff --git a/src/share/location_cache/ob_ls_location_service.cpp b/src/share/location_cache/ob_ls_location_service.cpp index 1cde15b3f..a2c27a5a2 100644 --- a/src/share/location_cache/ob_ls_location_service.cpp +++ b/src/share/location_cache/ob_ls_location_service.cpp @@ -101,7 +101,6 @@ int ObLSLocationUpdateQueueSet::add_task(const ObLSLocationUpdateTask &task) LOG_WARN("invalid task", KR(ret), K(task)); } else { uint64_t tenant_id = task.get_tenant_id(); - ObLSID ls_id = task.get_ls_id(); if (is_sys_tenant(tenant_id)) { // high priority if (OB_FAIL(sys_tenant_queue_.add(task))) { if (OB_EAGAIN != ret) { @@ -279,13 +278,13 @@ int ObLSLocationService::get( LOG_WARN("invalid key for get", KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); } else { - ret = get_from_cache(cluster_id, tenant_id, ls_id, location); + ret = get_from_cache_(cluster_id, tenant_id, ls_id, location); if (OB_SUCCESS != ret && OB_CACHE_NOT_HIT != ret) { LOG_WARN("get location from cache failed", KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); } else if (OB_CACHE_NOT_HIT == ret || location.get_renew_time() <= expire_renew_time) { - if (OB_FAIL(renew_location(cluster_id, tenant_id, ls_id, location))) { + if (OB_FAIL(renew_location_(cluster_id, tenant_id, ls_id, location))) { LOG_WARN("renew location failed", KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); } @@ -415,7 +414,7 @@ int ObLSLocationService::nonblock_get( LOG_WARN("invalid key for get", KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); } else { - ret = get_from_cache(cluster_id, tenant_id, ls_id, location); + ret = get_from_cache_(cluster_id, tenant_id, ls_id, location); if (OB_SUCCESS != ret && OB_CACHE_NOT_HIT != ret) { LOG_WARN("get location from cache failed", KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); @@ -467,7 +466,31 @@ int ObLSLocationService::nonblock_renew( KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); } else { const int64_t now = ObTimeUtility::current_time(); - ObLSLocationUpdateTask task(cluster_id, tenant_id, ls_id, now); + const bool renew_all_tenant = false; + ObLSLocationUpdateTask task(cluster_id, tenant_id, ls_id, renew_all_tenant, now); + if (OB_FAIL(add_update_task(task))) { + LOG_WARN("add location update task failed", KR(ret), K(task)); + } + } + return ret; +} + +int ObLSLocationService::nonblock_renew( + const int64_t cluster_id, + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("service not init", KR(ret)); + } else if (OB_UNLIKELY(OB_INVALID_CLUSTER_ID == cluster_id + || !is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid log stream key", KR(ret), K(cluster_id), K(tenant_id)); + } else { + const int64_t now = ObTimeUtility::current_time(); + const bool renew_all_tenant = true; + ObLSLocationUpdateTask task(cluster_id, tenant_id, SYS_LS, renew_all_tenant, now); if (OB_FAIL(add_update_task(task))) { LOG_WARN("add location update task failed", KR(ret), K(task)); } @@ -512,23 +535,29 @@ int ObLSLocationService::batch_process_tasks( ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected task count", KR(ret), "tasks count", tasks.count()); } else { - const uint64_t tenant_id = tasks.at(0).get_tenant_id(); + const ObLSLocationUpdateTask &task = tasks.at(0); + const uint64_t tenant_id = task.get_tenant_id(); const uint64_t superior_tenant_id = get_private_table_exec_tenant_id(tenant_id); ObLSLocation location; + ObArray locations; if (OB_ISNULL(GCTX.schema_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("GCTX.schema_service_ is null", KR(ret)); } else if (!GCTX.schema_service_->is_tenant_full_schema(superior_tenant_id)) { // do not process tasks if tenant schema is not ready if (REACH_TIME_INTERVAL(1000 * 1000L)) { // 1s - LOG_WARN("tenant schema is not ready, need wait", KR(ret), K(superior_tenant_id), K(tasks)); + LOG_WARN("tenant schema is not ready, need wait", KR(ret), K(superior_tenant_id), K(task)); } - } else if (OB_FAIL(renew_location( - tasks.at(0).get_cluster_id(), - tasks.at(0).get_tenant_id(), - tasks.at(0).get_ls_id(), + } else if (task.is_renew_for_tenant()) { + if (OB_FAIL(renew_location_for_tenant(task.get_cluster_id(), task.get_tenant_id(), locations))) { + LOG_WARN("renew cache for tenant failed", KR(ret), K(task)); + } + } else if (OB_FAIL(renew_location_( + task.get_cluster_id(), + task.get_tenant_id(), + task.get_ls_id(), location))) { - LOG_WARN("fail to renew location", KR(ret), "task", tasks.at(0)); + LOG_WARN("fail to renew location", KR(ret), K(task)); } } return ret; @@ -593,7 +622,7 @@ int ObLSLocationService::reload_config() } //FIXME: Not used. The GC logic needs to be reconsidered. Should not rely on __all_ls_status. -int ObLSLocationService::build_tenant_ls_info_hash(ObTenantLsInfoHashMap &hash) +int ObLSLocationService::build_tenant_ls_info_hash_(ObTenantLsInfoHashMap &hash) { int ret = OB_SUCCESS; ObArray tenant_ids; @@ -650,7 +679,7 @@ int ObLSLocationService::check_and_clear_dead_cache() LOG_WARN("check and generate dead cache error", KR(ret)); } else if (total_arr.count() <= 0) { LOG_INFO("no dead cache need to clear", K(total_arr)); - } else if (OB_FAIL(build_tenant_ls_info_hash(hash))) { + } else if (OB_FAIL(build_tenant_ls_info_hash_(hash))) { LOG_WARN("build tenant ls info hash error", KR(ret), K(total_arr)); } else { LOG_INFO("start to clear dead cache"); @@ -689,70 +718,29 @@ int ObLSLocationService::renew_all_ls_locations() ObCurTraceId::init(GCONF.self_addr_); int ret = OB_SUCCESS; int ret_fail = OB_SUCCESS; - ObArray ls_infos; ObArray tenant_ids; - const bool can_erase = true; - const int64_t renew_all_ls_loc_timeout = GCONF.location_cache_refresh_sql_timeout; - const bool inner_table_only = false; if (OB_FAIL(check_inner_stat_())) { LOG_WARN("fail to check inner stat", KR(ret)); } else if (OB_FAIL(schema_service_->get_tenant_ids(tenant_ids))) { LOG_WARN("get tenant_ids failed", KR(ret)); } else { + ObArray locations; ARRAY_FOREACH_NORET(tenant_ids, idx) { // ignore ret to ensure that each tenant's renewing is independent. ret = OB_SUCCESS; - ls_infos.reset(); + locations.reset(); const uint64_t tenant_id = tenant_ids.at(idx); - ObTimeoutCtx ctx; if (!is_valid_tenant_id(tenant_id) || is_virtual_tenant_id(tenant_id)) { continue; - } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx( - ctx, - renew_all_ls_loc_timeout))) { - LOG_WARN("fail to set default_timeout_ctx", KR(ret)); - } else if (OB_FAIL(lst_->get_by_tenant(tenant_id, inner_table_only, ls_infos))) { - LOG_WARN("fail to get all ls info", KR(ret), K(tenant_id), K(ls_infos)); - } else { - ARRAY_FOREACH_N(ls_infos, i, cnt) { - const ObLSInfo &ls_info = ls_infos.at(i); - ObLSLocation old_location; - ObLSLocation new_location; - bool is_same = false; - int tmp_ret = OB_SUCCESS; - // get from cache does not affect renew process - if (OB_SUCCESS != (tmp_ret = get_from_cache( - GCONF.cluster_id, - ls_info.get_tenant_id(), - ls_info.get_ls_id(), - old_location))) { - if (OB_CACHE_NOT_HIT == tmp_ret) { - tmp_ret = OB_SUCCESS; - } else { - LOG_WARN("fail to get from cache", KR(tmp_ret), K(ls_info)); - } - } - if (OB_FAIL(fill_location(GCONF.cluster_id, ls_info, new_location))) { - LOG_WARN("fail to fill location", KR(ret), K(ls_info)); - } else if (OB_FAIL(update_cache( - GCONF.cluster_id, - new_location.get_tenant_id(), - new_location.get_ls_id(), - can_erase, - new_location))) { - LOG_WARN("fail to update cache", KR(ret), K(tenant_id), K(new_location)); - } - if (OB_SUCC(ret) && (OB_SUCCESS == tmp_ret) && !new_location.is_same_with(old_location)) { - FLOG_INFO("[LS_LOCATION]ls location cache has changed", KR(ret), K(old_location), K(new_location)); - } - } + } else if (OB_FAIL(renew_location_for_tenant(GCONF.cluster_id, tenant_id, locations))) { + LOG_WARN("renew cache for tenant failed", KR(ret), K(tenant_id)); } if (OB_FAIL(ret)) { ret_fail = ret; } } // end ARRAY_FOREACH_NORET - ret = ret_fail; + ret = OB_FAIL(ret) ? ret : ret_fail; } return ret; } @@ -798,6 +786,30 @@ int ObLSLocationService::renew_all_ls_locations_by_rpc() return ret; } +int ObLSLocationService::renew_location_for_tenant( + const int64_t cluster_id, + const uint64_t tenant_id, + common::ObIArray &locations) +{ + int ret = OB_SUCCESS; + locations.reset(); + const bool can_erase = true; + const int64_t timeout = GCONF.location_cache_refresh_sql_timeout; + const bool inner_table_only = false; + ObTimeoutCtx ctx; + ObArray ls_infos; + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("fail to check inner stat", KR(ret)); + } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, timeout))) { + LOG_WARN("fail to set default_timeout_ctx", KR(ret)); + } else if (OB_FAIL(lst_->get_by_tenant(tenant_id, inner_table_only, ls_infos))) { + LOG_WARN("fail to get all ls info", KR(ret), K(tenant_id), K(ls_infos)); + } else if (OB_FAIL(batch_update_caches_(cluster_id, ls_infos, can_erase, locations))) { + LOG_WARN("batch update caches failed", KR(ret), K(cluster_id), K(tenant_id), K(can_erase)); + } + return ret; +} + int ObLSLocationService::construct_rpc_dests_( ObIArray &dests) { @@ -869,8 +881,67 @@ int ObLSLocationService::detect_ls_leaders_( } } // end for } + } + return ret; +} +int ObLSLocationService::batch_update_caches_( + const int64_t cluster_id, + const common::ObIArray &ls_infos, + const bool can_erase, + common::ObIArray &locations) +{ + int ret = OB_SUCCESS; + int ret_fail = OB_SUCCESS; + locations.reset(); + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("fail to check inner stat", KR(ret)); + } else if (OB_UNLIKELY(OB_INVALID_CLUSTER_ID == cluster_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid cluster_id", KR(ret), K(cluster_id)); + } else if (OB_FAIL(locations.reserve(ls_infos.count()))) { + LOG_WARN("reserve failed", KR(ret), "count", ls_infos.count()); + } + ARRAY_FOREACH(ls_infos, i) { + const ObLSInfo &ls_info = ls_infos.at(i); + ObLSLocation old_location; + ObLSLocation new_location; + bool is_same = false; + int tmp_ret = OB_SUCCESS; + // get from cache does not affect renew process + if (OB_TMP_FAIL(get_from_cache_( + cluster_id, + ls_info.get_tenant_id(), + ls_info.get_ls_id(), + old_location))) { + if (OB_CACHE_NOT_HIT == tmp_ret) { + tmp_ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get from cache", KR(tmp_ret), K(ls_info)); + } + } + + if (FAILEDx(fill_location_(cluster_id, ls_info, new_location))) { + LOG_WARN("fail to fill location", KR(ret), K(ls_info)); + } else if (new_location.get_replica_locations().empty()) { + if (!can_erase) { + // do nothing + } else if (OB_FAIL(erase_location_(cluster_id, ls_info.get_tenant_id(), ls_info.get_ls_id()))) { + LOG_WARN("fail to erase location", KR(ret), K(cluster_id), K(ls_info)); + } + } else if (OB_FAIL(update_cache_( + cluster_id, + new_location.get_tenant_id(), + new_location.get_ls_id(), + new_location))) { + LOG_WARN("fail to update cache", KR(ret), K(new_location)); + } else if (OB_FAIL(locations.push_back(new_location))) { + LOG_WARN("push back failed", KR(ret), K(new_location)); + } + if (OB_SUCC(ret) && (OB_SUCCESS == tmp_ret) && !new_location.is_same_with(old_location)) { + FLOG_INFO("[LS_LOCATION]ls location cache has changed", KR(ret), K(old_location), K(new_location)); + } } return ret; } @@ -885,7 +956,7 @@ bool ObLSLocationService::is_valid_key( && ls_id.is_valid_with_tenant(tenant_id); } -int ObLSLocationService::get_from_cache( +int ObLSLocationService::get_from_cache_( const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id, @@ -912,65 +983,35 @@ int ObLSLocationService::get_from_cache( return ret; } -int ObLSLocationService::renew_location( +int ObLSLocationService::renew_location_( const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id, ObLSLocation &location) { int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - ObLSLocation old_location; - ObTimeoutCtx ctx; location.reset(); - ObLSInfo ls_info; - const bool can_erase = true; - int64_t default_timeout = GCONF.location_cache_refresh_sql_timeout; + ObSEArray ls_ids; + ObSEArray ls_locations; if (OB_FAIL(check_inner_stat_())) { LOG_WARN("fail to check inner stat", KR(ret)); } else if (!is_valid_key(cluster_id, tenant_id, ls_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); - } else if (OB_ISNULL(lst_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("lst_ is null", KR(ret)); - } - - // get from cache just for printing cache changes log - if (OB_FAIL(ret)) { - } else if (OB_SUCCESS != (tmp_ret = get_from_cache(cluster_id, tenant_id, ls_id, old_location))) { - if (OB_CACHE_NOT_HIT == tmp_ret) { - tmp_ret = OB_SUCCESS; - } else { - LOG_WARN("fail to get from cache", KR(tmp_ret), K(cluster_id), K(tenant_id), K(ls_id)); - } - } - - if (FAILEDx(ObShareUtil::set_default_timeout_ctx(ctx, default_timeout))) { - LOG_WARN("fail to set default_timeout_ctx", KR(ret)); - } else if (OB_FAIL(lst_->get(cluster_id, tenant_id, - ls_id, share::ObLSTable::DEFAULT_MODE, ls_info))) { - LOG_WARN("fail to get log stream info by operator", - KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); - if (ObLocationServiceUtility::treat_sql_as_timeout(ret)) { - ret = OB_GET_LOCATION_TIME_OUT; - } - } else if (OB_FAIL(fill_location(cluster_id, ls_info, location))) { - LOG_WARN("fail to fill location", KR(ret), K(ls_info)); - } else if (OB_FAIL(update_cache(cluster_id, tenant_id, ls_id, can_erase, location))) { - LOG_WARN("fail to update cache", KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); - } else if (location.get_replica_locations().count() < 1) { + } else if (OB_FAIL(ls_ids.push_back(ls_id))) { + LOG_WARN("push back faile", KR(ret), K(ls_ids)); + } else if (OB_FAIL(batch_renew_ls_locations(cluster_id, tenant_id, ls_ids, ls_locations))) { + LOG_WARN("batch renew ls locations failed", KR(ret), K(cluster_id), K(tenant_id), K(ls_ids)); + } else if (ls_locations.empty()) { ret = OB_LS_LOCATION_NOT_EXIST; LOG_WARN("get empty location from meta table", KR(ret), K(location)); - } - // print cache changes - if (OB_SUCC(ret) && (OB_SUCCESS == tmp_ret) && !location.is_same_with(old_location)) { - FLOG_INFO("[LS_LOCATION]ls location cache has changed", KR(ret), K(old_location), "new_location", location); + } else if (OB_FAIL(location.assign(ls_locations.at(0)))) { + LOG_WARN("assign failed", KR(ret), K(ls_locations)); } return ret; } -int ObLSLocationService::fill_location( +int ObLSLocationService::fill_location_( const int64_t cluster_id, const ObLSInfo &ls_info, ObLSLocation &location) @@ -1014,11 +1055,10 @@ int ObLSLocationService::fill_location( return ret; } -int ObLSLocationService::update_cache( +int ObLSLocationService::update_cache_( const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id, - const bool can_erase, ObLSLocation &location) { int ret = OB_SUCCESS; @@ -1029,14 +1069,8 @@ int ObLSLocationService::update_cache( } else if (!cache_key.is_valid() || !location.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(cache_key), K(location)); - } else if (location.get_replica_locations().count() < 1) { - if (!can_erase) { - ret = OB_LS_LOCATION_NOT_EXIST; - LOG_WARN("location is empty", KR(ret), - K(cluster_id), K(tenant_id), K(ls_id), K(can_erase), K(location)); - } else if (OB_FAIL(erase_location(cluster_id, tenant_id, ls_id))) { - LOG_WARN("fail to erase location", KR(ret), K(cluster_id), K(tenant_id), K(ls_id)); - } + } else if (location.get_replica_locations().empty()) { + // skip empty location } else if (OB_FAIL(inner_cache_.update(from_rpc, cache_key, location))) { LOG_WARN("put location to user location cache failed", KR(ret), K(from_rpc), K(cache_key), K(location)); @@ -1047,7 +1081,7 @@ int ObLSLocationService::update_cache( return ret; } -int ObLSLocationService::erase_location( +int ObLSLocationService::erase_location_( const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id) @@ -1177,5 +1211,50 @@ int ObLSLocationService::dump_cache() return ret; } +int ObLSLocationService::batch_renew_ls_locations( + const int64_t cluster_id, + const uint64_t tenant_id, + const common::ObIArray &ls_ids, + common::ObIArray &ls_locations) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("fail to check inner stat", KR(ret)); + } else if (OB_UNLIKELY(OB_INVALID_CLUSTER_ID == cluster_id + || !is_valid_tenant_id(tenant_id) + || ls_ids.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(ls_ids)); + } else { + ObArray ls_infos; + const bool can_erase = true; + ObLSLocation location; + ObTimeoutCtx ctx; + const int64_t default_timeout = GCONF.location_cache_refresh_sql_timeout; + if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, default_timeout))) { + LOG_WARN("fail to set default_timeout_ctx", KR(ret)); + } else if (OB_FAIL(lst_->batch_get( + cluster_id, + tenant_id, + ls_ids, + ObLSTable::DEFAULT_MODE, + ls_infos))) { + if (ObLocationServiceUtility::treat_sql_as_timeout(ret)) { + int previous_ret = ret; + ret = OB_GET_LOCATION_TIME_OUT; + LOG_WARN("the sql used to get ls locations error, treat as timeout", + KR(ret), K(previous_ret), K(ls_ids)); + } else { + LOG_WARN("fail to batch get ls info by operator", + KR(ret), K(cluster_id), K(tenant_id), K(ls_ids)); + } + } else if (OB_FAIL(batch_update_caches_(cluster_id, ls_infos, can_erase, ls_locations))) { + LOG_WARN("batch update caches failed", KR(ret), + K(cluster_id), K(ls_infos), K(can_erase), K(ls_locations)); + } + } + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/location_cache/ob_ls_location_service.h b/src/share/location_cache/ob_ls_location_service.h index dcadc0bbb..0de0f9b42 100644 --- a/src/share/location_cache/ob_ls_location_service.h +++ b/src/share/location_cache/ob_ls_location_service.h @@ -147,6 +147,26 @@ public: const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id); + // Nonblock way to renew location cache for all ls in a tenant. + int nonblock_renew( + const int64_t cluster_id, + const uint64_t tenant_id); + // renew location cache of ls_ids synchronously + // @param [in] cluster_id: target cluster which the ls belongs to + // @param [in] tenant_id: target tenant which the ls belongs to + // @param [in] ls_ids: target ls_id array(can't have duplicate values) + // @param [out] ls_locations: locations of ls_ids recorded in inner_table + // (may be less than ls_ids when ls location not exist) + int batch_renew_ls_locations( + const int64_t cluster_id, + const uint64_t tenant_id, + const common::ObIArray &ls_ids, + common::ObIArray &ls_locations); + // renew all ls location caches for tenant + int renew_location_for_tenant( + const int64_t cluster_id, + const uint64_t tenant_id, + common::ObIArray &locations); // Add update task into async_queue_set. int add_update_task(const ObLSLocationUpdateTask &task); // Process update tasks. @@ -180,34 +200,36 @@ public: private: int check_inner_stat_() const; - - int get_from_cache( + int get_from_cache_( const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id, ObLSLocation &location); - int renew_location( + int renew_location_( const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id, ObLSLocation &location); - int fill_location(const int64_t cluster_id, const ObLSInfo &ls_info, ObLSLocation &location); - int update_cache( + int fill_location_(const int64_t cluster_id, const ObLSInfo &ls_info, ObLSLocation &location); + int update_cache_( const int64_t cluster_id, const uint64_t tenant_id, const ObLSID &ls_id, - const bool can_erase, ObLSLocation &location); - int erase_location( - const int64_t cluster_id, - const uint64_t tenant_id, - const ObLSID &ls_id); - int build_tenant_ls_info_hash(ObTenantLsInfoHashMap &hash); - + int erase_location_( + const int64_t cluster_id, + const uint64_t tenant_id, + const ObLSID &ls_id); + int build_tenant_ls_info_hash_(ObTenantLsInfoHashMap &hash); int construct_rpc_dests_(common::ObIArray &addrs); int detect_ls_leaders_( const common::ObIArray &dests, common::ObArray &leaders); + int batch_update_caches_( + const int64_t cluster_id, + const common::ObIArray &ls_infos, + const bool can_erase, + common::ObIArray &locations); private: static const int64_t OB_LOCATION_CACHE_BUCKET_NUM = 512; static const int64_t RENEW_LS_LOCATION_INTERVAL_US = 5 * 1000 * 1000L; // 5s diff --git a/src/share/location_cache/ob_tablet_ls_service.cpp b/src/share/location_cache/ob_tablet_ls_service.cpp index e243fd4fe..734ec5256 100644 --- a/src/share/location_cache/ob_tablet_ls_service.cpp +++ b/src/share/location_cache/ob_tablet_ls_service.cpp @@ -22,6 +22,7 @@ #include "observer/ob_server_struct.h" #include "common/ob_timeout_ctx.h" #include "share/schema/ob_multi_version_schema_service.h" // ObMultiVersionSchemaService +#include "share/tablet/ob_tablet_to_ls_operator.h" // ObTabletToLSOperator namespace oceanbase { @@ -45,7 +46,7 @@ int ObTabletLSService::init(common::ObMySQLProxy &sql_proxy) LOG_WARN("init twice", KR(ret)); } else if (OB_FAIL(inner_cache_.init())) { LOG_WARN("inner_cache init failed", KR(ret)); - } else if (OB_FAIL(async_queue_.init(this, user_thread_cnt, user_queue_size, "TbltLSSrv"))) { + } else if (OB_FAIL(async_queue_.init(this, user_thread_cnt, user_queue_size, "TabletLSAUp"))) { LOG_WARN("async_queue init failed", KR(ret), K(user_thread_cnt), K(user_queue_size)); } else { @@ -75,7 +76,7 @@ int ObTabletLSService::get( KR(ret), K(tenant_id), K(tablet_id)); - } else if (is_sys_tenant(tenant_id) || tablet_id.is_sys_tablet()) { + } else if (belong_to_sys_ls_(tenant_id, tablet_id)) { is_cache_hit = true; ls_id = SYS_LS; } else { @@ -120,7 +121,7 @@ int ObTabletLSService::nonblock_get( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid key for get", KR(ret), K(tenant_id), K(tablet_id)); - } else if (is_sys_tenant(tenant_id) || tablet_id.is_sys_tablet()) { + } else if (belong_to_sys_ls_(tenant_id, tablet_id)) { ls_id = SYS_LS; } else if (OB_FAIL(get_from_cache_(tenant_id, tablet_id, tablet_cache))) { if (OB_CACHE_NOT_HIT != ret) { @@ -151,7 +152,7 @@ int ObTabletLSService::nonblock_renew( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid log stream key", KR(ret), K(tenant_id), K(tablet_id)); - } else if (is_sys_tenant(tenant_id) || tablet_id.is_sys_tablet()) { + } else if (belong_to_sys_ls_(tenant_id, tablet_id)) { // do nothing } else { const int64_t now = ObTimeUtility::current_time(); @@ -175,7 +176,12 @@ int ObTabletLSService::add_update_task(const ObTabletLSUpdateTask &task) ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid task", KR(ret), K(task)); } else if (OB_FAIL(async_queue_.add(task))) { - LOG_WARN("fail to add task", KR(ret), K(task)); + if (OB_EAGAIN != ret) { + LOG_WARN("fail to add task", KR(ret), K(task)); + } else { + ret = OB_SUCCESS; + LOG_TRACE("task already exists", KR(ret), K(task)); + } } return ret; } @@ -195,7 +201,8 @@ int ObTabletLSService::batch_process_tasks( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid task count", KR(ret)); } else { - const uint64_t meta_tenant_id = gen_meta_tenant_id(tasks.at(0).get_tenant_id()); + const uint64_t tenant_id = tasks.at(0).get_tenant_id(); + const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id); if (OB_ISNULL(GCTX.schema_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("GCTX.schema_service_ is null", KR(ret)); @@ -205,24 +212,24 @@ int ObTabletLSService::batch_process_tasks( LOG_WARN("tenant schema is not ready, need wait", KR(ret), K(meta_tenant_id), K(tasks)); } } else { - ObTabletLSCache tablet_cache; - ARRAY_FOREACH_NORET(tasks, i) { - tablet_cache.reset(); - const ObTabletLSUpdateTask &task = tasks.at(i); - if (OB_UNLIKELY(!task.is_valid())) { - tmp_ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid task", KR(tmp_ret), K(task)); - } else { - tmp_ret = renew_cache_( - task.get_tenant_id(), - task.get_tablet_id(), - tablet_cache); - if (OB_SUCCESS != tmp_ret) { - ret = tmp_ret; - LOG_WARN("fail to renew tablet_cache", KR(ret), K(task)); - } + ObArenaAllocator allocator; + ObList tablet_list(allocator); + ObArray tablet_ls_caches; + ARRAY_FOREACH(tasks, idx) { + const ObTabletLSUpdateTask &task = tasks.at(idx); + if (OB_UNLIKELY(tenant_id != task.get_tenant_id())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid task", KR(ret), K(tenant_id), K(task)); + } else if (belong_to_sys_ls_(task.get_tenant_id(), task.get_tablet_id())) { + // skip + } else if (OB_FAIL(tablet_list.push_back(task.get_tablet_id()))) { + LOG_WARN("push back failed", KR(ret), K(idx), K(task)); } - } // end foreach + } + if (OB_FAIL(ret) || 0 == tablet_list.size()) { + } else if (OB_FAIL(batch_renew_tablet_ls_cache(tenant_id, tablet_list, tablet_ls_caches))) { + LOG_WARN("batch renew tablet ls mapping failed", KR(ret), K(tenant_id), K(tablet_list)); + } } } return ret; @@ -283,7 +290,7 @@ int ObTabletLSService::get_from_cache_( } else if(OB_UNLIKELY(!cache_key.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tablet_id)); - } else if (is_sys_tenant(tenant_id) || tablet_id.is_sys_tablet()) { + } else if (belong_to_sys_ls_(tenant_id, tablet_id)) { const int64_t now = ObTimeUtility::current_time(); if (OB_FAIL(tablet_cache.init(tenant_id, tablet_id, @@ -318,15 +325,16 @@ int ObTabletLSService::renew_cache_( int ret = OB_SUCCESS; ObTimeoutCtx ctx; tablet_cache.reset(); - ObLSID ls_id; - int64_t row_scn; + ObArenaAllocator allocator; + ObList tablet_list(allocator); + ObSEArray tablet_ls_caches; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("service not init", KR(ret)); } else if (!is_valid_key_(tenant_id, tablet_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tablet_id)); - } else if (is_sys_tenant(tenant_id) || tablet_id.is_sys_tablet()) { + } else if (belong_to_sys_ls_(tenant_id, tablet_id)) { const int64_t now = ObTimeUtility::current_time(); if (OB_FAIL(tablet_cache.init(tenant_id, tablet_id, @@ -336,15 +344,15 @@ int ObTabletLSService::renew_cache_( LOG_WARN("init tablet_cache failed", KR(ret), K(tenant_id), K(tablet_id), K(SYS_LS), K(now)); } - } else if (OB_FAIL(set_timeout_ctx_(ctx))) { - LOG_WARN("failed to set timeout ctx", KR(ret)); - } else if (OB_FAIL(inner_get_by_sql_(tenant_id, tablet_id, tablet_cache))) { - LOG_WARN("fail to get log stream info", KR(ret), K(tenant_id), K(tablet_id)); - if (ObLocationServiceUtility::treat_sql_as_timeout(ret)) { - ret = OB_GET_LOCATION_TIME_OUT; - } - } else if (OB_FAIL(update_cache_(tablet_cache))) { - LOG_WARN("fail to update cache", KR(ret), K(tablet_cache)); + } else if (OB_FAIL(tablet_list.push_back(tablet_id))) { + LOG_WARN("push back failed", KR(ret), K(tablet_id)); + } else if (OB_FAIL(batch_renew_tablet_ls_cache(tenant_id, tablet_list, tablet_ls_caches))) { + LOG_WARN("batch renew tablet ls cache failed", KR(ret), K(tablet_list)); + } else if (tablet_ls_caches.empty()) { + ret = OB_MAPPING_BETWEEN_TABLET_AND_LS_NOT_EXIST; + LOG_WARN("tablet ls mapping not exist in inner table", KR(ret), K(tenant_id), K(tablet_id)); + } else if (tablet_cache.assign(tablet_ls_caches.at(0))) { + LOG_WARN("assign failed", KR(ret), K(tablet_ls_caches)); } else { FLOG_INFO("[TABLET_LOCATION]success to renew tablet cache", K(tablet_cache)); } @@ -368,66 +376,6 @@ int ObTabletLSService::update_cache_(const ObTabletLSCache &tablet_cache) return ret; } -int ObTabletLSService::inner_get_by_sql_( - const uint64_t tenant_id, - const ObTabletID &tablet_id, - ObTabletLSCache &tablet_cache) -{ - int ret = OB_SUCCESS; - ObSqlString sql; - tablet_cache.reset(); - int64_t row_scn = 0; - if (OB_UNLIKELY(!inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("service not init", KR(ret)); - } else if (OB_ISNULL(sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sql proxy is null", KR(ret)); - } else { - SMART_VAR(ObMySQLProxy::MySQLResult, res) { - sqlclient::ObMySQLResult *result = NULL; - if (OB_INVALID_TENANT_ID == tenant_id || !tablet_id.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", KR(ret), K(tenant_id), K(tablet_id)); - } else if (OB_FAIL(sql.assign_fmt( - "SELECT ls_id, ORA_ROWSCN from %s WHERE tablet_id = %lu", - OB_ALL_TABLET_TO_LS_TNAME, tablet_id.id()))) { - LOG_WARN("fail to assign sql", KR(ret)); - } else if (OB_FAIL(sql_proxy_->read(res, tenant_id, sql.ptr()))) { - LOG_WARN("fail to execute sql", KR(ret), K(tenant_id), K(sql)); - } else if (OB_ISNULL(result = res.get_result())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fail to get sql result", KR(ret)); - } else if (OB_FAIL(result->next())) { - if (OB_ITER_END == ret) { - ret = OB_MAPPING_BETWEEN_TABLET_AND_LS_NOT_EXIST; - LOG_TRACE("fail to get tablet by sql", KR(ret), K(tenant_id), K(tablet_id)); - } else { - LOG_WARN("result next failed", KR(ret)); - } - } else { - int64_t int_ls_id = ObLSID::INVALID_LS_ID; - EXTRACT_INT_FIELD_MYSQL(*result, "ls_id", int_ls_id, int64_t); - EXTRACT_INT_FIELD_MYSQL(*result, "ORA_ROWSCN", row_scn, int64_t); - ObLSID ls_id(int_ls_id); - const int64_t now = ObTimeUtility::current_time(); - if (OB_FAIL(tablet_cache.init( - tenant_id, - tablet_id, - ls_id, - now, - row_scn))) { - LOG_WARN("init tablet_cache failed", KR(ret), K(tenant_id), - K(tablet_id), K(ls_id), K(now), K(row_scn)); - } else { - LOG_TRACE("success to get tablet by sql", KR(ret), K(tablet_cache)); - } - } - } - } - return ret; -} - int ObTabletLSService::set_timeout_ctx_(common::ObTimeoutCtx &ctx) { int ret = OB_SUCCESS; @@ -448,5 +396,131 @@ bool ObTabletLSService::is_valid_key_( return tablet_id.is_valid_with_tenant(tenant_id) && !tablet_id.is_reserved_tablet(); } +int ObTabletLSService::batch_renew_tablet_ls_cache( + const uint64_t tenant_id, + const ObList &tablet_list, + common::ObIArray &tablet_ls_caches) +{ + int ret = OB_SUCCESS; + tablet_ls_caches.reset(); + if (OB_UNLIKELY(!inited_) || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("service not init", KR(ret)); + } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || 0 == tablet_list.size())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(tablet_list)); + } else if (OB_FAIL(tablet_ls_caches.reserve(tablet_list.size()))) { + LOG_WARN("reserve failed", KR(ret), "count", tablet_list.size()); + } else { + ObArray user_tablet_ids; + ObArray user_tablet_ls_caches; + const int64_t now = ObTimeUtility::current_time(); + ObTimeoutCtx ctx; + // mock cache for sys tablet and filter out user tablet + FOREACH_X(tablet_id, tablet_list, OB_SUCC(ret)) { + if (belong_to_sys_ls_(tenant_id, *tablet_id)) { + ObTabletLSCache cache; + if (OB_FAIL(cache.init(tenant_id, *tablet_id, SYS_LS, now, INT64_MAX))) { + LOG_WARN("init cache failed", KR(ret), K(tenant_id), K(*tablet_id), K(now)); + } else if (OB_FAIL(tablet_ls_caches.push_back(cache))) { + LOG_WARN("push back failed", KR(ret), K(cache)); + } + } else if (OB_FAIL(user_tablet_ids.push_back(*tablet_id))) { + LOG_WARN("push back failed", KR(ret), K(tenant_id), K(*tablet_id)); + } + } + + if (OB_FAIL(ret) || user_tablet_ids.empty()) { + // skip + } else { + const int64_t single_get_timeout = GCONF.location_cache_refresh_sql_timeout; + // calculate timeout by count of inner_sql + const int64_t batch_get_timeout = (user_tablet_ids.count() / ObTabletToLSTableOperator::MAX_BATCH_COUNT + 1) * single_get_timeout; + if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, batch_get_timeout))) { + LOG_WARN("fail to set default_timeout_ctx", KR(ret)); + } else if (OB_FAIL(ObTabletToLSTableOperator::batch_get_tablet_ls_cache( + *sql_proxy_, + tenant_id, + user_tablet_ids, + user_tablet_ls_caches))) { + if (ObLocationServiceUtility::treat_sql_as_timeout(ret)) { + int previous_ret = ret; + ret = OB_GET_LOCATION_TIME_OUT; + LOG_WARN("the sql used to get tablets locations error, treat as timeout", + KR(ret), K(previous_ret), K(tablet_list)); + } else { + LOG_WARN("batch get tablet ls cache failed", KR(ret), K(tenant_id), K(user_tablet_ids)); + } + } + } + // update user tablet ls cache + ARRAY_FOREACH(user_tablet_ls_caches, idx) { + const ObTabletLSCache &tablet_ls = user_tablet_ls_caches.at(idx); + if (OB_FAIL(update_cache_(tablet_ls))) { + LOG_WARN("update cache failed", KR(ret), K(tablet_ls)); + } else if (OB_FAIL(tablet_ls_caches.push_back(tablet_ls))) { + LOG_WARN("push back faled", KR(ret), K(tablet_ls)); + } + } // end ARRAY_FOREACH + // erase nonexistent user tablet ls cache + if (OB_SUCC(ret) && (user_tablet_ls_caches.count() != user_tablet_ids.count())) { + int64_t erase_count = 0; + ARRAY_FOREACH(user_tablet_ids, i) { + const ObTabletID &tablet_id = user_tablet_ids.at(i); + bool found = false; + ARRAY_FOREACH(user_tablet_ls_caches, j) { + if (user_tablet_ls_caches.at(j).get_tablet_id() == tablet_id) { + found = true; + break; + } + } + if (OB_SUCC(ret) && !found) { + if (OB_FAIL(erase_cache_(tenant_id, tablet_id))) { + LOG_WARN("erase cache failed", KR(ret), K(tenant_id), K(tablet_id)); + } else { + ++erase_count; + LOG_INFO("[TABLET_LOCATION] tablet ls mapping not exist", KR(ret), K(tenant_id), K(tablet_id)); + } + } + } // end ARRAY_FOREACH tablet_ids + } + } + return ret; +} + +int ObTabletLSService::erase_cache_(const uint64_t tenant_id, const ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("service not init", KR(ret)); + } else if (OB_UNLIKELY(!is_valid_key_(tenant_id, tablet_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid key for tablet get", KR(ret), K(tenant_id), K(tablet_id)); + } else if (belong_to_sys_ls_(tenant_id, tablet_id)) { + // skip + } else { + ObTabletLSKey cache_key(tenant_id, tablet_id); + if (OB_FAIL(inner_cache_.del(cache_key))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_TRACE("not exist in inner_cache_", K(cache_key)); + } else { + LOG_WARN("fail to erase cache from inner_cache_", KR(ret), K(cache_key)); + } + } else { + LOG_TRACE("erase cache from inner_cache_", K(cache_key)); + } + } + return ret; +} + +bool ObTabletLSService::belong_to_sys_ls_( + const uint64_t tenant_id, + const ObTabletID &tablet_id) const +{ + return is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id) || tablet_id.is_sys_tablet(); +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/location_cache/ob_tablet_ls_service.h b/src/share/location_cache/ob_tablet_ls_service.h index 54d9d69ba..a8c57f9df 100644 --- a/src/share/location_cache/ob_tablet_ls_service.h +++ b/src/share/location_cache/ob_tablet_ls_service.h @@ -64,6 +64,16 @@ public: int nonblock_renew( const uint64_t tenant_id, const ObTabletID &tablet_id); + // Batch renew the mapping between the tablet and LS synchronously + // @param [in] tenant_id: target tenant which the tablet belongs to + // @param [in] tablet_ids: target tablet_id list + // @param [out] ls_ids: array of ls_ids that tablet belongs to + // @return OB_SUCCESS: process successfully + // other: inner_sql execution error + int batch_renew_tablet_ls_cache( + const uint64_t tenant_id, + const ObList &tablet_list, + common::ObIArray &tablet_ls_caches); // Add update task into async_queue_. int add_update_task(const ObTabletLSUpdateTask &task); // Process update tasks. @@ -87,12 +97,11 @@ private: const ObTabletID &tablet_id, ObTabletLSCache &tablet_cache); int update_cache_(const ObTabletLSCache &tablet_cache); - int inner_get_by_sql_( - const uint64_t tenant_id, - const ObTabletID &tablet_id, - ObTabletLSCache &tablet_cache); int set_timeout_ctx_(common::ObTimeoutCtx &ctx); bool is_valid_key_(const uint64_t tenant_id, const ObTabletID &tablet_id) const; + int erase_cache_(const uint64_t tenant_id, const ObTabletID &tablet_id); + bool belong_to_sys_ls_(const uint64_t tenant_id, const ObTabletID &tablet_id) const; + const int64_t MINI_MODE_UPDATE_THREAD_CNT = 1; const int64_t USER_TASK_QUEUE_SIZE = 200 * 1000; // 20W partitions const int64_t MINI_MODE_USER_TASK_QUEUE_SIZE = 10 * 1000; // 1W partitions diff --git a/src/share/location_cache/ob_vtable_location_service.cpp b/src/share/location_cache/ob_vtable_location_service.cpp index e6a9dc71d..f15fb3980 100644 --- a/src/share/location_cache/ob_vtable_location_service.cpp +++ b/src/share/location_cache/ob_vtable_location_service.cpp @@ -90,23 +90,6 @@ int ObVTableLocationService::init( return ret; } -void ObVTableLocationService::stop() -{ - update_queue_.stop(); -} - -void ObVTableLocationService::wait() -{ - update_queue_.wait(); -} - -int ObVTableLocationService::destroy() -{ - int ret = OB_SUCCESS; - update_queue_.destroy(); - vtable_cache_.destroy(); - return ret; -} //TODO: 1.remove ObPartitionLocation 2.add auto renew 3.cached by tenant_id int ObVTableLocationService::vtable_get( const uint64_t tenant_id, @@ -221,7 +204,7 @@ int ObVTableLocationService::renew_vtable_location_( LOG_WARN("update_vtable_location failed", KR(ret), K(table_id)); } else { ObTaskController::get().allow_next_syslog(); - LOG_INFO("renew vtable location success", KR(ret), K(table_id), K(locations)); + LOG_INFO("renew vtable location success", KR(ret), K(tenant_id), K(table_id), K(locations)); } return ret; } @@ -507,5 +490,29 @@ int ObVTableLocationService::location2cache_value_( return ret; } +void ObVTableLocationService::stop() +{ + update_queue_.stop(); +} + +void ObVTableLocationService::wait() +{ + update_queue_.wait(); +} + +int ObVTableLocationService::destroy() +{ + int ret = OB_SUCCESS; + update_queue_.destroy(); + vtable_cache_.destroy(); + return ret; +} + +int ObVTableLocationService::reload_config() +{ + // nothing need reload + return OB_SUCCESS; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/location_cache/ob_vtable_location_service.h b/src/share/location_cache/ob_vtable_location_service.h index d140196c8..cba7775da 100644 --- a/src/share/location_cache/ob_vtable_location_service.h +++ b/src/share/location_cache/ob_vtable_location_service.h @@ -77,9 +77,6 @@ public: ObIAliveServerTracer &server_tracer, ObRsMgr &rs_mgr, obrpc::ObCommonRpcProxy &rpc_proxy); - void stop(); - void wait(); - int destroy(); int vtable_get( const uint64_t tenant_id, const uint64_t table_id, @@ -94,6 +91,10 @@ public: const common::ObIArray &tasks, bool &stopped); int process_barrier(const ObVTableLocUpdateTask &task, bool &stopped); + void stop(); + void wait(); + int destroy(); + int reload_config(); private: int renew_vtable_location_( const uint64_t tenant_id, @@ -133,4 +134,4 @@ private: } // end namespace share } // end namespace oceanbase -#endif \ No newline at end of file +#endif diff --git a/src/share/ls/ob_ls_election_reference_info_operator.h b/src/share/ls/ob_ls_election_reference_info_operator.h index f52a217b5..60cfbdd80 100644 --- a/src/share/ls/ob_ls_election_reference_info_operator.h +++ b/src/share/ls/ob_ls_election_reference_info_operator.h @@ -19,6 +19,7 @@ #include "lib/container/ob_array.h"//ObArray #include "lib/container/ob_iarray.h"//ObIArray #include "logservice/palf/lsn.h"//LSN +#include "share/ob_tenant_switchover_status.h" namespace oceanbase { diff --git a/src/share/ls/ob_ls_i_life_manager.h b/src/share/ls/ob_ls_i_life_manager.h index 47b307d70..99212bc11 100644 --- a/src/share/ls/ob_ls_i_life_manager.h +++ b/src/share/ls/ob_ls_i_life_manager.h @@ -241,7 +241,44 @@ int ObLSTemplateOperator::exec_write(const uint64_t &tenant_id, return ret; } +#define DEFINE_IN_TRANS_FUC(func_name, ...)\ +int func_name ##_in_trans(__VA_ARGS__, ObMySQLTransaction &trans);\ +int func_name(__VA_ARGS__); +#define DEFINE_IN_TRANS_FUC1(func_name, ...)\ +static int func_name ##_in_trans(__VA_ARGS__, ObMySQLTransaction &trans);\ +static int func_name(__VA_ARGS__, ObISQLClient *proxy); + +#define TAKE_IN_TRANS(func_name, proxy, exec_tenant_id, ...)\ +do {\ + ObMySQLTransaction trans; \ + if (FAILEDx(trans.start(proxy, exec_tenant_id))) {\ + SHARE_LOG(WARN, "failed to start trans", KR(ret), K(exec_tenant_id));\ + } else if (OB_FAIL(func_name##_in_trans(__VA_ARGS__, trans))) {\ + SHARE_LOG(WARN, "failed to do it in trans", KR(ret));\ + }\ + if (trans.is_started()) {\ + int tmp_ret = OB_SUCCESS;\ + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) {\ + SHARE_LOG(WARN, "failed to commit trans", KR(ret), KR(tmp_ret));\ + ret = OB_SUCC(ret) ? tmp_ret : ret;\ + }\ + }\ +} while (0) + +#define START_TRANSACTION(proxy, exec_tenant_id) \ + ObMySQLTransaction trans; \ + if (FAILEDx(trans.start(proxy, exec_tenant_id))) { \ + SHARE_LOG(WARN, "failed to start trans", KR(ret), K(exec_tenant_id)); \ + } +#define END_TRANSACTION(trans)\ + if (trans.is_started()) {\ + int tmp_ret = OB_SUCCESS;\ + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) {\ + ret = OB_SUCC(ret) ? tmp_ret : ret;\ + SHARE_LOG(WARN, "failed to end trans", KR(ret), K(tmp_ret));\ + }\ + } } } diff --git a/src/share/ls/ob_ls_info.cpp b/src/share/ls/ob_ls_info.cpp index 7d7caff02..14a8ba0be 100644 --- a/src/share/ls/ob_ls_info.cpp +++ b/src/share/ls/ob_ls_info.cpp @@ -123,7 +123,8 @@ ObLSReplica::ObLSReplica() in_member_list_(false), member_time_us_(0), learner_list_(), - in_learner_list_(false) + in_learner_list_(false), + rebuild_(false) { } @@ -157,6 +158,7 @@ void ObLSReplica::reset() member_time_us_ = 0; learner_list_.reset(); in_learner_list_ = false; + rebuild_ = false; } int ObLSReplica::init( @@ -178,7 +180,8 @@ int ObLSReplica::init( const int64_t data_size, const int64_t required_size, const MemberList &member_list, - const GlobalLearnerList &learner_list) + const GlobalLearnerList &learner_list, + const bool rebuild) { int ret = OB_SUCCESS; reset(); @@ -210,6 +213,7 @@ int ObLSReplica::init( paxos_replica_number_ = paxos_replica_number; data_size_ = data_size; required_size_ = required_size; + rebuild_ = rebuild; } return ret; } @@ -248,6 +252,7 @@ int ObLSReplica::assign(const ObLSReplica &other) in_member_list_ = other.in_member_list_; member_time_us_ = other.member_time_us_; in_learner_list_ = other.in_learner_list_; + rebuild_ = other.rebuild_; } } return ret; @@ -279,16 +284,18 @@ bool ObLSReplica::is_equal_for_report(const ObLSReplica &other) const is_equal = (proposal_id_ == other.proposal_id_); } - // check replica_type and learner_list if necessary - bool is_compatible_with_readonly_replica = false; - int ret = OB_SUCCESS; - if (is_equal && OB_FAIL(ObShareUtil::check_compat_version_for_readonly_replica( - tenant_id_, - is_compatible_with_readonly_replica))) { - LOG_WARN("failed to check compat version for readonly replica", KR(ret), K_(tenant_id)); - } else if (is_equal && is_compatible_with_readonly_replica) { - is_equal = learner_list_is_equal(learner_list_, other.learner_list_) - && replica_type_ == other.replica_type_; + // check replica_type/learner_list/rebuild if necessary (>=4.2.0.0) + if (is_equal) { + bool is_compatible_with_readonly_replica = false; + int ret = OB_SUCCESS; + if (OB_FAIL(ObShareUtil::check_compat_version_for_readonly_replica( + tenant_id_, is_compatible_with_readonly_replica))) { + LOG_WARN("failed to check compat version for readonly replica", KR(ret), K_(tenant_id)); + } else if (is_compatible_with_readonly_replica) { + is_equal = learner_list_is_equal(learner_list_, other.learner_list_) + && replica_type_ == other.replica_type_ + && rebuild_ == other.rebuild_; + } } return is_equal; @@ -314,25 +321,59 @@ bool ObLSReplica::learner_list_is_equal(const common::GlobalLearnerList &a, cons return is_equal; } -bool ObLSReplica::member_list_is_equal(const MemberList &a, const MemberList &b) const +bool ObLSReplica::member_list_is_equal(const MemberList &a, const MemberList &b) { bool is_equal = true; if (a.count() != b.count()) { is_equal = false; } else { - for (int i = 0; is_equal && i < a.count(); ++i) { - is_equal = false; - for (int j = 0; j < b.count(); ++j) { - if (a[i] == b[j]) { - is_equal = true; - break; - } + ARRAY_FOREACH_X(a, idx, cnt, is_equal) { + if (!common::is_contain(b, a.at(idx))) { + is_equal = false; + } + } + ARRAY_FOREACH_X(b, idx, cnt, is_equal) { + if (!common::is_contain(a, b.at(idx))) { + is_equal = false; } } } return is_equal; } +bool ObLSReplica::server_is_in_member_list( + const MemberList &member_list, + const common::ObAddr &server) +{ + bool is_found = false; + ARRAY_FOREACH_X(member_list, idx, cnt, !is_found) { + if (server == member_list.at(idx).get_server()) { + is_found = true; + } + } + return is_found; +} + +bool ObLSReplica::servers_in_member_list_are_same(const MemberList &a, const MemberList &b) +{ + bool is_same = true; + if (a.count() != b.count()) { + is_same = false; + } else { + ARRAY_FOREACH_X(a, idx, cnt, is_same) { + if (!server_is_in_member_list(b, a.at(idx).get_server())) { + is_same = false; + } + } + ARRAY_FOREACH_X(b, idx, cnt, is_same) { + if (!server_is_in_member_list(a, b.at(idx).get_server())) { + is_same = false; + } + } + } + return is_same; +} + int64_t ObLSReplica::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; @@ -361,7 +402,8 @@ int64_t ObLSReplica::to_string(char *buf, const int64_t buf_len) const K_(in_member_list), K_(member_time_us), K_(learner_list), - K_(in_learner_list)); + K_(in_learner_list), + K_(rebuild)); J_OBJ_END(); return pos; } @@ -390,7 +432,8 @@ OB_SERIALIZE_MEMBER(ObLSReplica, in_member_list_, member_time_us_, learner_list_, - in_learner_list_); + in_learner_list_, + rebuild_); int ObLSReplica::member_list2text( const MemberList &member_list, diff --git a/src/share/ls/ob_ls_info.h b/src/share/ls/ob_ls_info.h index 5fb88419d..dbf5f130b 100644 --- a/src/share/ls/ob_ls_info.h +++ b/src/share/ls/ob_ls_info.h @@ -108,7 +108,8 @@ public: const int64_t data_size, const int64_t required_size, const MemberList &member_list, - const GlobalLearnerList &learner_list); + const GlobalLearnerList &learner_list, + const bool rebuild); // check-related functions inline bool is_valid() const; inline bool is_strong_leader() const { return common::is_strong_leader(role_); } @@ -125,6 +126,11 @@ public: static int transform_ob_member_list( const common::ObMemberList &ob_member_list, MemberList &member_list); + static bool member_list_is_equal(const MemberList &a, const MemberList &b); + static bool server_is_in_member_list( + const MemberList &member_list, + const common::ObAddr &server); + static bool servers_in_member_list_are_same(const MemberList &a, const MemberList &b); int64_t to_string(char *buf, const int64_t buf_len) const; // operator-related functions int assign(const ObLSReplica &other); @@ -154,6 +160,7 @@ public: inline int64_t get_member_time_us() const { return member_time_us_; } inline int64_t get_data_size() const { return data_size_; } inline int64_t get_required_size() const { return required_size_; } + inline bool get_rebuild() const { return rebuild_; } inline const common::GlobalLearnerList &get_learner_list() const { return learner_list_; } // functions to set values @@ -174,7 +181,6 @@ public: //set replica role(FOLLOWER), proposal_id(0), modify_time(now) inline void update_to_follower_role(); bool learner_list_is_equal(const common::GlobalLearnerList &a, const common::GlobalLearnerList &b) const; - bool member_list_is_equal(const MemberList &a, const MemberList &b) const; private: int64_t create_time_us_; // store utc time int64_t modify_time_us_; // store utc time @@ -202,6 +208,7 @@ private: int64_t member_time_us_; // member_time_us common::GlobalLearnerList learner_list_; // list to record R-replicas bool in_learner_list_; // whether in learner_list + bool rebuild_; // whether in rebuild }; // [class_full_name] class ObLSInfo diff --git a/src/share/ls/ob_ls_life_manager.cpp b/src/share/ls/ob_ls_life_manager.cpp index bb2c1f0e9..938d21564 100644 --- a/src/share/ls/ob_ls_life_manager.cpp +++ b/src/share/ls/ob_ls_life_manager.cpp @@ -34,21 +34,13 @@ int ObLSLifeAgentManager::create_new_ls( if (OB_UNLIKELY(!ls_info.is_valid() || !create_ls_scn.is_valid() || zone_priority.empty())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(ls_info), K(create_ls_scn), K(zone_priority)); - } else if (OB_FAIL(trans.start(proxy_, exec_tenant_id))) { - LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id), K(ls_info)); - } else if (OB_FAIL(create_new_ls_in_trans(ls_info, create_ls_scn, zone_priority, working_sw_status, trans))) { - LOG_WARN("failed to create new ls", KR(ret), K(ls_info), K(create_ls_scn), K(zone_priority)); + } else { + TAKE_IN_TRANS(create_new_ls, proxy_, + exec_tenant_id, ls_info, create_ls_scn, zone_priority, working_sw_status); } - if (trans.is_started()) { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { - LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); - ret = OB_SUCC(ret) ? tmp_ret : ret; - } - } - return ret; } + int ObLSLifeAgentManager::drop_ls(const uint64_t &tenant_id, const share::ObLSID &ls_id, const ObTenantSwitchoverStatus &working_sw_status) @@ -59,19 +51,10 @@ int ObLSLifeAgentManager::drop_ls(const uint64_t &tenant_id, if (OB_UNLIKELY(!ls_id.is_valid() || OB_INVALID_TENANT_ID == tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(ls_id), K(tenant_id)); - } else if (OB_FAIL(trans.start(proxy_, exec_tenant_id))) { - LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id), K(tenant_id)); - } else if (OB_FAIL(drop_ls_in_trans(tenant_id, ls_id, working_sw_status, trans))) { - LOG_WARN("failed to create new ls", KR(ret), K(tenant_id), K(ls_id)); + } else { + TAKE_IN_TRANS(drop_ls, proxy_, exec_tenant_id, tenant_id, + ls_id, working_sw_status); } - if (trans.is_started()) { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { - LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); - ret = OB_SUCC(ret) ? tmp_ret : ret; - } - } - return ret; } @@ -90,22 +73,10 @@ int ObLSLifeAgentManager::set_ls_offline(const uint64_t &tenant_id, || (!ls_is_dropping_status(ls_status) && !ls_is_tenant_dropping_status(ls_status)))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(ls_id), K(tenant_id), K(drop_scn), K(ls_status)); - } else if (OB_FAIL(trans.start(proxy_, exec_tenant_id))) { - LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id), K(tenant_id)); - } else if (OB_FAIL(set_ls_offline_in_trans(tenant_id, ls_id, ls_status, drop_scn, - working_sw_status, trans))) { - LOG_WARN("failed to create new ls", KR(ret), K(tenant_id), K(ls_id), - K(ls_status), K(drop_scn)); + } else { + TAKE_IN_TRANS(set_ls_offline, proxy_, exec_tenant_id, tenant_id, + ls_id, ls_status, drop_scn, working_sw_status); } - - if (trans.is_started()) { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { - LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); - ret = OB_SUCC(ret) ? tmp_ret : ret; - } - } - return ret; } diff --git a/src/share/ls/ob_ls_life_manager.h b/src/share/ls/ob_ls_life_manager.h index 9097f4894..937e9eb0b 100644 --- a/src/share/ls/ob_ls_life_manager.h +++ b/src/share/ls/ob_ls_life_manager.h @@ -71,19 +71,19 @@ public: * @param[in]zone_priority: the primary_zone of OB_ALL_LS_ELECTION_REFERENCE_INFO * @param[in] working_sw_status only support working on specified switchover status * */ - int create_new_ls(const ObLSStatusInfo &ls_info, - const SCN &create_ls_scn, - const common::ObString &zone_priority, - const share::ObTenantSwitchoverStatus &working_sw_status); + DEFINE_IN_TRANS_FUC(create_new_ls, const ObLSStatusInfo &ls_info,\ + const SCN &create_ls_scn,\ + const common::ObString &zone_priority,\ + const share::ObTenantSwitchoverStatus &working_sw_status) /* * description: for primary cluster and GC of standby, delete ls from each inner_table * @param[in] tenant_id: tenant_id * @param[in] ls_id: need delete ls * @param[in] working_sw_status only support working on specified switchover status * */ - int drop_ls(const uint64_t &tenant_id, - const share::ObLSID &ls_id, - const ObTenantSwitchoverStatus &working_sw_status); + DEFINE_IN_TRANS_FUC(drop_ls, const uint64_t &tenant_id,\ + const share::ObLSID &ls_id,\ + const ObTenantSwitchoverStatus &working_sw_status) /* * description: for primary cluster set ls to wait offline from tenant_dropping or dropping status * @param[in] tenant_id: tenant_id @@ -92,11 +92,11 @@ public: * @param[in] drop_scn: there is no user data after drop_scn except offline * @param[in] working_sw_status only support working on specified switchover status * */ - int set_ls_offline(const uint64_t &tenant_id, - const share::ObLSID &ls_id, - const ObLSStatus &ls_status, - const SCN &drop_scn, - const ObTenantSwitchoverStatus &working_sw_status); + DEFINE_IN_TRANS_FUC(set_ls_offline, const uint64_t &tenant_id,\ + const share::ObLSID &ls_id,\ + const ObLSStatus &ls_status,\ + const SCN &drop_scn,\ + const ObTenantSwitchoverStatus &working_sw_status) /* * description: update ls primary zone, need update __all_ls_status and __all_ls_election_reference * @param[in] tenant_id: tenant_id @@ -110,32 +110,6 @@ public: const common::ObZone &primary_zone, const common::ObString &zone_priority); -public: - /* - * description: for standby cluster, create new ls - */ - int create_new_ls_in_trans(const ObLSStatusInfo &ls_info, - const SCN &create_ls_scn, - const common::ObString &zone_priority, - const share::ObTenantSwitchoverStatus &working_sw_status, - ObMySQLTransaction &trans); - /* - * description: for standby cluster, create new ls - */ - int drop_ls_in_trans(const uint64_t &tenant_id, - const share::ObLSID &ls_id, - const ObTenantSwitchoverStatus &working_sw_status, - ObMySQLTransaction &trans); - /* - * description: for standby cluster set ls to offline - * */ - int set_ls_offline_in_trans(const uint64_t &tenant_id, - const share::ObLSID &ls_id, - const ObLSStatus &ls_status, - const SCN &drop_scn, - const ObTenantSwitchoverStatus &working_sw_status, - ObMySQLTransaction &trans); - private: bool inited_; //table_operator diff --git a/src/share/ls/ob_ls_operator.cpp b/src/share/ls/ob_ls_operator.cpp old mode 100644 new mode 100755 index 7c7ee70fa..44aee7333 --- a/src/share/ls/ob_ls_operator.cpp +++ b/src/share/ls/ob_ls_operator.cpp @@ -20,6 +20,7 @@ #include "lib/time/ob_time_utility.h" #include "lib/mysqlclient/ob_mysql_transaction.h" #include "lib/string/ob_sql_string.h" +#include "lib/string/ob_fixed_length_string.h"//ObFixedLengthString #include "common/ob_timeout_ctx.h" #include "lib/utility/ob_unify_serialize.h" //OB_SERIALIZE_MEMBER #include "observer/ob_inner_sql_connection.h"//ObInnerSQLConnection @@ -28,6 +29,7 @@ #include "storage/tx/ob_trans_define.h"//MonotonicTs #include "storage/tx/ob_ts_mgr.h"//GET_GTS #include "storage/tx/ob_trans_service.h" +#include "storage/tablelock/ob_lock_utils.h" // ObLSObjLockUtil #include "share/ob_max_id_fetcher.h"//ObMaxIdFetcher #include "share/ob_global_stat_proxy.h"//get gc #include "logservice/palf/log_define.h"//SCN @@ -40,8 +42,11 @@ namespace oceanbase { using namespace transaction; using namespace palf; +using namespace transaction::tablelock; + namespace share { +static const char* LS_FLAG_ARRAY[] = { ""/*NORMAL*/, "DUPLICATE", "BLOCK_TABLET_IN" }; int ObLSFlag::assign(const ObLSFlag &ls_flag) { int ret = OB_SUCCESS; @@ -54,6 +59,7 @@ int ObLSFlag::assign(const ObLSFlag &ls_flag) return ret; } +//maybe empty, DUPLICATE, BLOCK_TABLET_IN, DUPLICATE|BLOCK_TABLET_IN int ObLSFlag::flag_to_str(ObLSFlagStr &str) const { STATIC_ASSERT(ARRAYSIZEOF(LS_FLAG_ARRAY) == (int64_t)MAX_FLAG, @@ -182,7 +188,7 @@ void ObLSAttr::reset() id_.reset(); ls_group_id_ = OB_INVALID_ID; status_ = OB_LS_EMPTY; - flag_ = OB_LS_FLAG_NORMAL; + flag_.reset(); operation_type_ = OB_LS_OP_INVALID_TYPE; create_scn_.reset(); } @@ -203,17 +209,14 @@ bool ObLSAttrOperator::is_valid() const int ObLSAttrOperator::operator_ls_( const ObLSAttr &ls_attr, const common::ObSqlString &sql, - const uint64_t target_max_ls_group_id, const ObTenantSwitchoverStatus &working_sw_status) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!ls_attr.is_valid() || sql.empty() - || OB_INVALID_ID == target_max_ls_group_id || !working_sw_status.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("operation is invalid", KR(ret), K(ls_attr), K(sql), - K(target_max_ls_group_id), K(working_sw_status)); + LOG_WARN("operation is invalid", KR(ret), K(ls_attr), K(sql), K(working_sw_status)); } else { ObMySQLTransaction trans; const bool for_update = true; @@ -223,7 +226,41 @@ int ObLSAttrOperator::operator_ls_( ObAllTenantInfo tenant_info; if (OB_FAIL(trans.start(proxy_, tenant_id_))) { LOG_WARN("failed to start transaction", KR(ret), K(tenant_id_)); - } else if (ls_attr.get_ls_id().is_sys_ls()) { + } else if (OB_FAIL(operator_ls_in_trans_(ls_attr, sql, + working_sw_status, trans))) { + LOG_WARN("failed to operator ls in trans", KR(ret), K(ls_attr), K(sql)); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to end trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + } + return ret; +} + +int ObLSAttrOperator::operator_ls_in_trans_( + const ObLSAttr &ls_attr, + const common::ObSqlString &sql, + const ObTenantSwitchoverStatus &working_sw_status, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!ls_attr.is_valid() + || sql.empty() + || !trans.is_started())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("operation is invalid", KR(ret), K(ls_attr), K(sql), + "is_started", trans.is_started()); + } else { + const bool for_update = true; + ObLSAttr sys_ls_attr; + bool skip_sub_trans = false; + ObAllTenantInfo tenant_info; + ObLSAttr duplicate_ls_attr; + if (ls_attr.get_ls_id().is_sys_ls()) { if (OB_LS_NORMAL == ls_attr.get_ls_status()) { skip_sub_trans = true; } @@ -257,54 +294,26 @@ int ObLSAttrOperator::operator_ls_( ret = OB_LS_EXIST; LOG_WARN("duplicate ls already exist", KR(ret), K(duplicate_ls_attr), K(ls_attr)); } - if (OB_FAIL(ret)) { - } else { - //check ls create not concurrency - uint64_t max_ls_id = 0; - uint64_t max_ls_group_id = 0; - if (OB_FAIL(ObMaxIdFetcher::fetch_max_id(trans, tenant_id_, - share::OB_MAX_USED_LS_GROUP_ID_TYPE, max_ls_group_id))) { - LOG_WARN("failed to fetch max id", KR(ret), K(tenant_id_)); - } else if (max_ls_group_id != target_max_ls_group_id) { - ret = OB_NEED_RETRY; - LOG_WARN("max ls group id not equal, ls may be concurrency created", KR(ret), - K(target_max_ls_group_id), K(max_ls_group_id)); - } else if (OB_FAIL(ObMaxIdFetcher::fetch_max_id(trans, tenant_id_, - share::OB_MAX_USED_LS_ID_TYPE, max_ls_id))) { - LOG_WARN("failed to fetch max id", KR(ret), K(tenant_id_)); - } else if (max_ls_id != ls_attr.get_ls_id().id()) { - ret = OB_NEED_RETRY; - LOG_WARN("max ls id not equal, ls may be concurrency created", KR(ret), - K(max_ls_id), K(ls_attr)); - } - } } if (FAILEDx(exec_write(tenant_id_, sql, this, trans))) { LOG_WARN("failed to exec write", KR(ret), K(tenant_id_), K(sql)); } else if (!skip_sub_trans && OB_FAIL(process_sub_trans_(ls_attr, trans))) { LOG_WARN("failed to process sub trans", KR(ret), K(ls_attr)); } - if (trans.is_started()) { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { - LOG_WARN("failed to end trans", KR(ret), KR(tmp_ret)); - ret = OB_SUCC(ret) ? tmp_ret : ret; - } - } } return ret; } int ObLSAttrOperator::insert_ls( const ObLSAttr &ls_attr, - const uint64_t max_ls_group_id, - const ObTenantSwitchoverStatus &working_sw_status) + const ObTenantSwitchoverStatus &working_sw_status, + ObMySQLTransaction *trans) { int ret = OB_SUCCESS; ObLSFlagStr flag_str; - if (OB_UNLIKELY(!ls_attr.is_valid() || OB_INVALID_ID == max_ls_group_id)) { + if (OB_UNLIKELY(!ls_attr.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("operation is invalid", KR(ret), K(ls_attr), K(max_ls_group_id)); + LOG_WARN("operation is invalid", KR(ret), K(ls_attr)); } else if (OB_UNLIKELY(!is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("operation is not valid", KR(ret), "operation", *this); @@ -316,14 +325,20 @@ int ObLSAttrOperator::insert_ls( "insert into %s (ls_id, ls_group_id, status, flag, create_scn) values(%ld, " "%ld, '%s', '%s', '%lu')", OB_ALL_LS_TNAME, ls_attr.get_ls_id().id(), ls_attr.get_ls_group_id(), - ObLSStatusOperator::ls_status_to_str(ls_attr.get_ls_status()), flag_str.ptr(), + ls_status_to_str(ls_attr.get_ls_status()), flag_str.ptr(), ls_attr.get_create_scn().get_val_for_inner_table_field()))) { LOG_WARN("failed to assign sql", KR(ret), K(ls_attr), K(sql)); - } else if (OB_FAIL(operator_ls_(ls_attr, sql, max_ls_group_id, working_sw_status))) { - LOG_WARN("failed to operator ls", KR(ret), K(ls_attr), K(sql)); + } else if (OB_ISNULL(trans)) { + if (OB_FAIL(operator_ls_(ls_attr, sql, working_sw_status))) { + LOG_WARN("failed to operator ls", KR(ret), K(ls_attr), K(sql)); + } + } else { + if (OB_FAIL(operator_ls_in_trans_(ls_attr, sql, working_sw_status, *trans))) { + LOG_WARN("failed to operator ls", KR(ret), K(ls_attr), K(sql)); + } } } - LOG_INFO("[LS_OPERATOR] insert ls", KR(ret), K(ls_attr)); + LOG_INFO("[LS_OPERATOR] insert ls", KR(ret), K(ls_attr), KP(trans)); return ret; } @@ -351,7 +366,7 @@ int ObLSAttrOperator::delete_ls( ret = OB_EAGAIN; LOG_WARN("status not match", KR(ret), K(ls_attr), K(old_status)); } else if (OB_FAIL(sql.assign_fmt("delete from %s where ls_id = %ld and status = '%s'", - OB_ALL_LS_TNAME, ls_id.id(), ObLSStatusOperator::ls_status_to_str(old_status)))) { + OB_ALL_LS_TNAME, ls_id.id(), ls_status_to_str(old_status)))) { LOG_WARN("failed to assign sql", KR(ret), K(ls_id), K(sql)); } else { ObLSAttr new_ls_attr; @@ -362,8 +377,7 @@ int ObLSAttrOperator::delete_ls( ls_attr.get_ls_flag(), ls_attr.get_ls_status(), operation_type, SCN::base_scn()))) { LOG_WARN("failed to init new ls attr", KR(ret), K(ls_id), K(ls_attr), K(operation_type)); - } else if (OB_FAIL(operator_ls_(new_ls_attr, sql, new_ls_attr.get_ls_group_id(), - working_sw_status))) { + } else if (OB_FAIL(operator_ls_(new_ls_attr, sql, working_sw_status))) { LOG_WARN("failed to operator ls", KR(ret), K(new_ls_attr), K(sql)); } LOG_INFO("[LS_OPERATOR] delete ls", KR(ret), K(ls_id), K(old_status)); @@ -429,6 +443,36 @@ int ObLSAttrOperator::update_ls_status(const ObLSID &id, const share::ObLSStatus &old_status, const share::ObLSStatus &new_status, const ObTenantSwitchoverStatus &working_sw_status) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!id.is_valid() + || !is_valid_status_in_ls(old_status) + || !is_valid_status_in_ls(new_status))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid_argument", KR(ret), K(id), K(new_status), K(old_status)); + } else { + ObMySQLTransaction trans; + if (OB_FAIL(trans.start(proxy_, tenant_id_))) { + LOG_WARN("failed to start transaction", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(update_ls_status_in_trans(id, old_status, new_status, working_sw_status, trans))) { + LOG_WARN("failed to update ls status in trans", KR(ret), K(id), K(old_status), K(new_status)); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to end trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + } + return ret; +} + +int ObLSAttrOperator::update_ls_status_in_trans(const ObLSID &id, + const share::ObLSStatus &old_status, + const share::ObLSStatus &new_status, + const ObTenantSwitchoverStatus &working_sw_status, + common::ObMySQLTransaction &trans) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!id.is_valid() @@ -439,15 +483,15 @@ int ObLSAttrOperator::update_ls_status(const ObLSID &id, } else { common::ObSqlString sql; ObLSAttr ls_attr; - if (OB_FAIL(get_ls_attr(id, false/*for_update*/, *proxy_, ls_attr))) { + if (OB_FAIL(get_ls_attr(id, false/*for_update*/, trans, ls_attr))) { LOG_WARN("failed to get ls attr", KR(ret), K(id)); } else if (ls_attr.get_ls_status() != old_status) { ret = OB_EAGAIN; LOG_WARN("status not match", KR(ret), K(ls_attr), K(old_status)); } else if (OB_FAIL(sql.assign_fmt( "UPDATE %s set status = '%s' where ls_id = %ld and status = '%s'", - OB_ALL_LS_TNAME, ObLSStatusOperator::ls_status_to_str(new_status), - id.id(), ObLSStatusOperator::ls_status_to_str(old_status)))) { + OB_ALL_LS_TNAME, ls_status_to_str(new_status), + id.id(), ls_status_to_str(old_status)))) { LOG_WARN("failed to assign sql", KR(ret), K(id), K(new_status), K(old_status), K(sql)); } else { ObLSAttr new_ls_attr; @@ -457,8 +501,8 @@ int ObLSAttrOperator::update_ls_status(const ObLSID &id, operation_type, SCN::base_scn()))) { LOG_WARN("failed to init new ls attr", KR(ret), K(id), K(ls_attr), K(operation_type)); - } else if (OB_FAIL(operator_ls_(new_ls_attr, sql, new_ls_attr.get_ls_group_id(), - working_sw_status))) { + } else if (OB_FAIL(operator_ls_in_trans_(new_ls_attr, sql, + working_sw_status, trans))) { LOG_WARN("failed to operator ls", KR(ret), K(new_ls_attr), K(sql)); } LOG_INFO("[LS_OPERATOR] update ls status", KR(ret), K(ls_attr), K(new_ls_attr)); @@ -491,7 +535,7 @@ int ObLSAttrOperator::get_ls_attr(const ObLSID &id, const bool for_update, commo LOG_WARN("failed to get ls array", KR(ret), K(tenant_id_), K(sql)); } else if (0 == ls_array.count()) { ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("failed to ls array", KR(ret), K(id)); + LOG_WARN("failed to get ls array", KR(ret), K(id), K(sql)); } else if (OB_UNLIKELY(1 != ls_array.count())) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("more than one ls is unexpected", KR(ret), K(ls_array), K(sql)); @@ -560,28 +604,23 @@ int ObLSAttrOperator::get_all_ls_by_order( } int ObLSAttrOperator::load_all_ls_and_snapshot( - SCN &read_scn, ObLSAttrIArray &ls_array) + const SCN &read_scn, ObLSAttrIArray &ls_array) { int ret = OB_SUCCESS; ls_array.reset(); - read_scn.reset(); if (OB_UNLIKELY(!is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("operation is not valid", KR(ret), "operation", *this); } else { - if (OB_FAIL(get_tenant_gts(tenant_id_, read_scn))) { - LOG_WARN("failed to get tenant gts", KR(ret), K(tenant_id_)); - } else { - ObSqlString sql; - if (OB_UNLIKELY(!read_scn.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("read scn is invalid", KR(ret), K(read_scn)); - } else if (OB_FAIL(sql.assign_fmt("select * from %s as of snapshot %lu", - OB_ALL_LS_TNAME, read_scn.get_val_for_inner_table_field()))) { - LOG_WARN("failed to assign sql", KR(ret), K(sql), K(read_scn)); - } else if (OB_FAIL(exec_read(tenant_id_, sql, *proxy_, this, ls_array))) { - LOG_WARN("failed to construct ls attr", KR(ret), K(sql)); - } + ObSqlString sql; + if (OB_UNLIKELY(!read_scn.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("read scn is invalid", KR(ret), K(read_scn)); + } else if (OB_FAIL(sql.assign_fmt("select * from %s as of snapshot %lu", + OB_ALL_LS_TNAME, read_scn.get_val_for_inner_table_field()))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql), K(read_scn)); + } else if (OB_FAIL(exec_read(tenant_id_, sql, *proxy_, this, ls_array))) { + LOG_WARN("failed to construct ls attr", KR(ret), K(sql)); } } return ret; @@ -608,11 +647,12 @@ int ObLSAttrOperator::fill_cell(common::sqlclient::ObMySQLResult *result, ObLSAt EXTRACT_INT_FIELD_MYSQL(*result, "ls_id", id_value, int64_t); EXTRACT_INT_FIELD_MYSQL(*result, "ls_group_id", ls_group_id, uint64_t); EXTRACT_VARCHAR_FIELD_MYSQL(*result, "status", status_str); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "flag", flag_str); EXTRACT_UINT_FIELD_MYSQL(*result, "create_scn", create_scn_val, uint64_t); EXTRACT_VARCHAR_FIELD_MYSQL(*result, "flag", flag_str); if (OB_FAIL(ret)) { LOG_WARN("failed to get result", KR(ret), K(ls_group_id), K(status_str), - K(id_value)); + K(id_value), K(flag_str)); } else if (OB_FAIL(create_scn.convert_for_inner_table_field(create_scn_val))) { LOG_WARN("failed to convert create_scn", KR(ret), K(ls_group_id), K(status_str), K(id_value), K(create_scn)); @@ -620,7 +660,7 @@ int ObLSAttrOperator::fill_cell(common::sqlclient::ObMySQLResult *result, ObLSAt LOG_WARN("failed to convert flag", KR(ret), K(flag_str)); } else { ObLSID ls_id(id_value); - ObLSStatus status = ObLSStatusOperator::str_to_ls_status(status_str); + ObLSStatus status = str_to_ls_status(status_str); ObLSOperationType type = get_ls_operation_by_status(status); if (OB_FAIL(ls_attr.init( ls_id, ls_group_id, flag, @@ -691,6 +731,126 @@ int ObLSAttrOperator::get_tenant_gts(const uint64_t &tenant_id, SCN >s_scn) return ret; } +int ObLSAttrOperator::alter_ls_group_in_trans(const ObLSAttr &ls_info, + const uint64_t new_ls_group_id, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + if (OB_UNLIKELY(!ls_info.is_valid() + || OB_INVALID_ID == new_ls_group_id + || !trans.is_started())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid_argument", KR(ret), K(ls_info), + K(new_ls_group_id), "trans_started", trans.is_started()); + } else if (OB_FAIL(sql.assign_fmt( + "UPDATE %s set ls_group_id = %lu where ls_id = %ld and ls_group_id = %lu", + OB_ALL_LS_TNAME, new_ls_group_id, ls_info.get_ls_id().id(), ls_info.get_ls_group_id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(new_ls_group_id), K(ls_info), K(sql)); + } else if (OB_FAIL(exec_write(tenant_id_, sql, this, trans))) { + LOG_WARN("failed to exec write", KR(ret), K(tenant_id_), K(sql)); + } else { + ObLSAttr new_ls_info; + if (OB_FAIL(new_ls_info.init(ls_info.get_ls_id(), new_ls_group_id, ls_info.get_ls_flag(), ls_info.get_ls_status(), + OB_LS_OP_ALTER_LS_GROUP, ls_info.get_create_scn()))) { + LOG_WARN("failed to init new ls info", KR(ret), K(ls_info), K(new_ls_group_id)); + } else if (OB_FAIL(process_sub_trans_(new_ls_info, trans))) { + LOG_WARN("failed to process sub trans", KR(ret), K(new_ls_info)); + } + } + return ret; +} + +int ObLSAttrOperator::update_ls_flag_in_trans(const ObLSID &id, + const ObLSFlag &old_flag, const ObLSFlag &new_flag, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + ObLSFlagStr old_flag_str; + ObLSFlagStr new_flag_str; + + if (OB_UNLIKELY(!id.is_valid() + || !new_flag.is_valid() + || !old_flag.is_valid() + || !trans.is_started())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid_argument", KR(ret), K(id), K(old_flag), + K(new_flag), "trans_started", trans.is_started()); + } else if (OB_FAIL(ObLSObjLockUtil::lock_ls_in_trans( + trans, + tenant_id_, + id, + EXCLUSIVE))) { + LOG_WARN("lock ls in trans failed", KR(ret), K_(tenant_id), K(id)); + } else { + DEBUG_SYNC(AFTER_LOCK_LS_AND_BEFORE_CHANGE_LS_FLAG); + if (OB_FAIL(new_flag.flag_to_str(new_flag_str))) { + LOG_WARN("failed to flag to str", KR(ret), K(new_flag)); + } else if (OB_FAIL(old_flag.flag_to_str(old_flag_str))) { + LOG_WARN("failed to flag to str", KR(ret), K(old_flag)); + } else if (OB_FAIL(sql.assign_fmt( + "UPDATE %s set flag = '%s' where ls_id = %ld and flag = '%s'", + OB_ALL_LS_TNAME, new_flag_str.ptr(), id.id(), old_flag_str.ptr()))) { + LOG_WARN("failed to assign sql", KR(ret), K(id), K(new_flag_str), + K(old_flag_str), K(sql)); + } else if (OB_FAIL(exec_write(tenant_id_, sql, this, trans))) { + LOG_WARN("failed to exec write", KR(ret), K(tenant_id_), K(sql)); + } + } + return ret; +} + +int ObLSAttrOperator::get_random_normal_user_ls( + ObLSID &ls_id, + const ObLSFlag &flag) +{ + int ret = OB_SUCCESS; + ls_id.reset(); + ObLSFlagStr flag_str; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("operation is not valid", KR(ret), "operation", *this); + } else if (OB_UNLIKELY(!is_user_tenant(tenant_id_) || !flag.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K_(tenant_id), K(flag)); + } else if (OB_FAIL(flag.flag_to_str(flag_str))) { + LOG_WARN("flag to str failed", KR(ret), K(flag), K_(tenant_id)); + } else { + SMART_VAR(ObISQLClient::ReadResult, result) { + ObSqlString sql; + int64_t int_ls_id; + common::sqlclient::ObMySQLResult *res; + if (OB_FAIL(sql.assign_fmt( + "select ls_id from %s where ls_id > %ld and status = '%s' and flag = '%s' order by rand() limit 1", + OB_ALL_LS_TNAME, + ObLSID::MIN_USER_LS_ID, + ls_status_to_str(OB_LS_NORMAL), + flag_str.ptr()))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql)); + } else if (OB_FAIL(proxy_->read(result, tenant_id_, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K_(tenant_id), K(sql)); + } else if (OB_ISNULL(res = result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K_(tenant_id), K(sql)); + } else if (OB_FAIL(res->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("normal user ls not found", KR(ret), K_(tenant_id), K(sql)); + } else { + LOG_WARN("next failed", KR(ret), K_(tenant_id), K(sql)); + } + } else if (OB_FAIL(res->get_int("ls_id", int_ls_id))) { + LOG_WARN("get int failed", KR(ret), K_(tenant_id), K(sql)); + } else { + ls_id = int_ls_id; + } + } + } + + return ret; +} + int ObLSAttrOperator::get_all_ls_by_order(const bool lock_sys_ls, ObLSAttrIArray &ls_operation_array) { int ret = OB_SUCCESS; diff --git a/src/share/ls/ob_ls_operator.h b/src/share/ls/ob_ls_operator.h old mode 100644 new mode 100755 index 4965659cd..a883bb242 --- a/src/share/ls/ob_ls_operator.h +++ b/src/share/ls/ob_ls_operator.h @@ -37,7 +37,7 @@ class ObMySQLResult; } namespace share { -static const char* LS_FLAG_ARRAY[] = { ""/*NORMAL*/, "DUPLICATE", "BLOCK_TABLET_IN" }; +class SCN; //maybe empty, DUPLICATE, BLOCK_TABLET_IN, DUPLICATE|BLOCK_TABLET_IN static const int64_t FLAG_STR_LENGTH = 100; typedef common::ObFixedLengthString ObLSFlagStr; @@ -103,6 +103,7 @@ enum ObLSOperationType OB_LS_OP_TENANT_DROP_PRE, OB_LS_OP_DROP_END, OB_LS_OP_TENANT_DROP, + OB_LS_OP_ALTER_LS_GROUP, }; #define IS_LS_OPERATION(OPERATION_TYPE, OPERATION) \ static bool is_ls_##OPERATION##_op(const ObLSOperationType type) { \ @@ -116,6 +117,7 @@ IS_LS_OPERATION(TENANT_DROP_PRE, tenant_drop_pre) IS_LS_OPERATION(DROP_END, drop_end) IS_LS_OPERATION(CREATE_ABORT, create_abort) IS_LS_OPERATION(TENANT_DROP, tenant_drop) +IS_LS_OPERATION(ALTER_LS_GROUP, alter_ls_group) struct ObLSAttr { @@ -151,14 +153,15 @@ struct ObLSAttr { return ls_is_tenant_dropping_status(status_); } + bool ls_is_pre_tenant_dropping() const + { + return ls_is_pre_tenant_dropping_status(status_); + } + bool ls_is_normal() const { return ls_is_normal_status(status_); } - ObLSOperationType get_ls_operatin_type() const - { - return operation_type_; - } ObLSID get_ls_id() const { return id_; @@ -192,7 +195,7 @@ struct ObLSAttr private: ObLSID id_; uint64_t ls_group_id_; - ObLSFlagForCompatible flag_compatible_; + ObLSFlagForCompatible flag_compatible_;//no use, only for compatiable ObLSFlag flag_; ObLSStatus status_; ObLSOperationType operation_type_; @@ -243,28 +246,48 @@ public: * @return return code */ int get_all_ls_by_order(const bool lock_sys_ls, ObLSAttrIArray &ls_operation_array); - int insert_ls(const ObLSAttr &ls_attr, const uint64_t max_ls_group_id, - const ObTenantSwitchoverStatus &working_sw_status); + int insert_ls(const ObLSAttr &ls_attr, + const ObTenantSwitchoverStatus &working_sw_status, + ObMySQLTransaction *trans = NULL); //prevent the concurrency of create and drop ls int delete_ls(const ObLSID &id, const share::ObLSStatus &old_status, const ObTenantSwitchoverStatus &working_sw_status); int update_ls_status(const ObLSID &id, const share::ObLSStatus &old_status, const share::ObLSStatus &new_status, const ObTenantSwitchoverStatus &working_sw_status); + int update_ls_status_in_trans(const ObLSID &id, const share::ObLSStatus &old_status, const share::ObLSStatus &new_status, + const ObTenantSwitchoverStatus &working_sw_status, + common::ObMySQLTransaction &trans); static ObLSOperationType get_ls_operation_by_status(const ObLSStatus &ls_status); int get_ls_attr(const ObLSID &id, const bool for_update, common::ObISQLClient &client, ObLSAttr &ls_attr); /* * description: get all ls with snapshot - * @param[out] read_scn:the snapshot of read_version + * @param[in] read_scn:the snapshot of read_version * @param[out] ObLSAttrIArray ls_info in __all_ls * */ - int load_all_ls_and_snapshot(share::SCN &read_scn, ObLSAttrIArray &ls_array); + int load_all_ls_and_snapshot(const share::SCN &read_scn, ObLSAttrIArray &ls_array); static int get_tenant_gts(const uint64_t &tenant_id, SCN >s_scn); + static int get_tenant_gts(const uint64_t &tenant_id, int64_t >s_ts_ns); + int alter_ls_group_in_trans(const ObLSAttr &ls_info, + const uint64_t new_ls_group_id, + common::ObMySQLTransaction &trans); + int update_ls_flag_in_trans(const ObLSID &id, const ObLSFlag &old_flag, const ObLSFlag &new_flag, + common::ObMySQLTransaction &trans); + /* + * description: get random user ls in normal status with specific flag which default is normal + * + * @param[out] ls_id: ls_id of user ls + * @param[in] flag: ls flag (default normal) + * */ + int get_random_normal_user_ls(ObLSID &ls_id, const ObLSFlag &flag = ObLSFlag()); private: int process_sub_trans_(const ObLSAttr &ls_attr, ObMySQLTransaction &trans); - int operator_ls_(const ObLSAttr &ls_attr, const common::ObSqlString &sql, const uint64_t max_ls_group_id, + int operator_ls_(const ObLSAttr &ls_attr, const common::ObSqlString &sql, const ObTenantSwitchoverStatus &working_sw_status); + int operator_ls_in_trans_(const ObLSAttr &ls_attr, const common::ObSqlString &sql, + const ObTenantSwitchoverStatus &working_sw_status, + ObMySQLTransaction &trans); private: uint64_t tenant_id_; common::ObMySQLProxy *proxy_; diff --git a/src/share/ls/ob_ls_recovery_stat_operator.cpp b/src/share/ls/ob_ls_recovery_stat_operator.cpp index 5b7b87248..d3564ae25 100644 --- a/src/share/ls/ob_ls_recovery_stat_operator.cpp +++ b/src/share/ls/ob_ls_recovery_stat_operator.cpp @@ -37,6 +37,7 @@ bool ObLSRecoveryStat::is_valid() const return OB_INVALID_TENANT_ID != tenant_id_ && ls_id_.is_valid() && sync_scn_.is_valid() && readable_scn_.is_valid() + && sync_scn_ >= readable_scn_ && create_scn_.is_valid() && drop_scn_.is_valid(); } @@ -57,6 +58,10 @@ int ObLSRecoveryStat::init(const uint64_t tenant_id, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(id), K(sync_scn), K(readable_scn), K(create_scn), K(drop_scn)); + } else if (OB_UNLIKELY(sync_scn < readable_scn)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("readable_scn > sync_scn, invalid argument", KR(ret), K(sync_scn), K(readable_scn), + K(tenant_id), K(id), K(lbt())); } else { tenant_id_ = tenant_id; ls_id_ = id; @@ -81,6 +86,10 @@ int ObLSRecoveryStat::init_only_recovery_stat(const uint64_t tenant_id, const Ob ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(id), K(sync_scn), K(readable_scn)); + } else if (OB_UNLIKELY(sync_scn < readable_scn)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("readable_scn > sync_scn, invalid argument", KR(ret), K(sync_scn), K(readable_scn), + K(tenant_id), K(id), K(lbt())); } else { tenant_id_ = tenant_id; ls_id_ = id; @@ -180,6 +189,7 @@ int ObLSRecoveryStatOperator::drop_ls(const uint64_t &tenant_id, } int ObLSRecoveryStatOperator::update_ls_recovery_stat( const ObLSRecoveryStat &ls_recovery, + const bool only_update_readable_scn, ObMySQLProxy &proxy) { int ret = OB_SUCCESS; @@ -191,8 +201,8 @@ int ObLSRecoveryStatOperator::update_ls_recovery_stat( const uint64_t exec_tenant_id = get_exec_tenant_id(ls_recovery.get_tenant_id()); if (OB_FAIL(trans.start(&proxy, exec_tenant_id))) { LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id), K(ls_recovery)); - } else if (OB_FAIL(update_ls_recovery_stat_in_trans(ls_recovery, trans))) { - LOG_WARN("update ls recovery in trans", KR(ret), K(ls_recovery)); + } else if (OB_FAIL(update_ls_recovery_stat_in_trans(ls_recovery, only_update_readable_scn, trans))) { + LOG_WARN("update ls recovery in trans", KR(ret), K(ls_recovery), K(only_update_readable_scn)); } if (trans.is_started()) { int tmp_ret = OB_SUCCESS; @@ -207,34 +217,32 @@ int ObLSRecoveryStatOperator::update_ls_recovery_stat( int ObLSRecoveryStatOperator::update_ls_recovery_stat_in_trans( const ObLSRecoveryStat &ls_recovery, + const bool only_update_readable_scn, ObMySQLTransaction &trans) { int ret = OB_SUCCESS; ObLSRecoveryStat old_ls_recovery; - ObAllTenantInfo tenant_info; if (OB_UNLIKELY(!ls_recovery.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid_argument", KR(ret), K(ls_recovery)); } else if (OB_FAIL(get_ls_recovery_stat(ls_recovery.get_tenant_id(), ls_recovery.get_ls_id(), true, old_ls_recovery, trans))) { LOG_WARN("failed to get ls current recovery stat", KR(ret), K(ls_recovery)); - } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(ls_recovery.get_tenant_id(), &trans, - true /* for update */, tenant_info))) { - LOG_WARN("failed to load tenant info", KR(ret), K(ls_recovery)); - } else if (OB_UNLIKELY(!tenant_info.is_normal_status())) { + } else if (only_update_readable_scn && old_ls_recovery.get_sync_scn() != ls_recovery.get_sync_scn()) { + //if only update readable_scn, sync_scn no need change + //Possible situations: + //1. After the sync_scn is initialized to restore the tenant's SYS_LS, only readable_scn is reported before it iterates to the log. + //2. After the flashback is executed, the SYS_LS does not need to report sync_scn. ret = OB_NEED_RETRY; - LOG_WARN("switchover status is not normal, do not update ls recovery", KR(ret), - K(ls_recovery), K(tenant_info)); + LOG_WARN("only update readabld_scn, sync_scn can not change", KR(ret), K(old_ls_recovery), + K(ls_recovery), K(only_update_readable_scn)); } else { const SCN sync_scn = ls_recovery.get_sync_scn() > old_ls_recovery.get_sync_scn() ? ls_recovery.get_sync_scn() : old_ls_recovery.get_sync_scn(); const SCN &readable_scn = ls_recovery.get_readable_scn() > old_ls_recovery.get_readable_scn() ? ls_recovery.get_readable_scn() : old_ls_recovery.get_readable_scn(); common::ObSqlString sql; - if (ls_recovery.get_ls_id() == share::SYS_LS && tenant_info.get_recovery_until_scn() < sync_scn) { - ret = OB_NEED_RETRY; - LOG_WARN("can not recovery bigger than recovery_until_scn", KR(ret), K(sync_scn), K(tenant_info)); - } else if (OB_FAIL(sql.assign_fmt("UPDATE %s SET sync_scn = %lu, readable_scn = " + if (OB_FAIL(sql.assign_fmt("UPDATE %s SET sync_scn = %lu, readable_scn = " "%lu where ls_id = %ld and tenant_id = %lu", OB_ALL_LS_RECOVERY_STAT_TNAME, sync_scn.get_val_for_inner_table_field(), readable_scn.get_val_for_inner_table_field(), @@ -246,6 +254,41 @@ int ObLSRecoveryStatOperator::update_ls_recovery_stat_in_trans( } return ret; } + +int ObLSRecoveryStatOperator::update_sys_ls_sync_scn( + const uint64_t tenant_id, + ObMySQLTransaction &trans, + const SCN &sync_scn) +{ + int ret = OB_SUCCESS; + ObLSRecoveryStat old_ls_recovery; + if (OB_UNLIKELY(!sync_scn.is_valid_and_not_min() || !is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid_argument", KR(ret), K(sync_scn), K(tenant_id)); + } else if (OB_FAIL(get_ls_recovery_stat(tenant_id, SYS_LS, true/*for update*/, old_ls_recovery, trans))) { + LOG_WARN("failed to get SYS ls current recovery stat", KR(ret), K(old_ls_recovery)); + } else if (old_ls_recovery.get_sync_scn() >= sync_scn) { + LOG_INFO("update_sys_ls_sync_scn: current sync_scn >= target sync_scn, need not update", + "target_sync_scn", sync_scn, "current_sync_scn", old_ls_recovery.get_sync_scn(), + K(tenant_id)); + } else { + LOG_INFO("start to update sys ls sync_scn", + "target_sync_scn", sync_scn, "current_sync_scn", old_ls_recovery.get_sync_scn(), + K(tenant_id), K(old_ls_recovery)); + + common::ObSqlString sql; + if (OB_FAIL(sql.assign_fmt("UPDATE %s SET sync_scn = %lu " + "WHERE ls_id = %ld and tenant_id = %lu", + OB_ALL_LS_RECOVERY_STAT_TNAME, sync_scn.get_val_for_inner_table_field(), + ObLSID::SYS_LS_ID, tenant_id))) { + LOG_WARN("failed to assign sql", KR(ret), K(sync_scn), K(tenant_id), K(sql)); + } else if (OB_FAIL(exec_write(tenant_id, sql, this, trans, true))) { + LOG_WARN("failed to exec write", KR(ret), K(tenant_id), K(sql), K(sync_scn)); + } + } + return ret; +} + int ObLSRecoveryStatOperator::set_ls_offline(const uint64_t &tenant_id, const share::ObLSID &ls_id, const ObLSStatus &ls_status, @@ -372,11 +415,23 @@ int ObLSRecoveryStatOperator::get_tenant_recovery_stat(const uint64_t tenant_id, } else { common::ObSqlString sql; const uint64_t exec_tenant_id = get_exec_tenant_id(tenant_id); + //The sync_scn and readable_scn at the tenant level need to be calculated separately, and the reference LS list is different. + //The following statement collects sync_scn and readable_scn at the same time in one SQL. + // + //The sync_scn calculation refers to all LSs that have not entered the deletion state. + // When drop_scn = SCN::base_scn(), it means that the LS has not entered the deletion state. + // It is guaranteed that once LS enters the delete state, sync_scn will be greater than drop_scn. + // + //readable_scn indicates the readable site, it will lag behind sync_scn, and need to consider the LS entering the deletion state. + //Specifically, two types of LS need to be referred to when calculating readable_scn: + // 1) LS that has not entered the deletion state; + // 2) LS that has entered the deletion state, but drop_scn > readable_scn, that is, the deletion site of the LS is greater than the readable site scenario if (OB_FAIL(sql.assign_fmt( - "select min(greatest(create_scn, sync_scn)) as sync_scn, " - "min(greatest(create_scn, readable_scn)) as min_wrs from %s where " - "(drop_scn = %ld or drop_scn > sync_scn) and tenant_id = %lu ", - OB_ALL_LS_RECOVERY_STAT_TNAME, SCN::base_scn().get_val_for_inner_table_field(), tenant_id))) { + "select sync_scn, min_wrs from " + "(select min(greatest(create_scn, sync_scn)) as sync_scn from %s where drop_scn = %ld) p, " + "(select min(greatest(create_scn, readable_scn)) as min_wrs from %s where drop_scn = %ld or drop_scn > readable_scn) q", + OB_ALL_LS_RECOVERY_STAT_TNAME, SCN::base_scn().get_val_for_inner_table_field(), + OB_ALL_LS_RECOVERY_STAT_TNAME, SCN::base_scn().get_val_for_inner_table_field()))) { LOG_WARN("failed to assign sql", KR(ret), K(sql), K(tenant_id)); } else if (OB_FAIL(get_all_ls_recovery_stat_(tenant_id, sql, client, sync_scn, min_wrs))) { LOG_WARN("failed to get tenant stat", KR(ret), K(tenant_id), K(sql)); diff --git a/src/share/ls/ob_ls_recovery_stat_operator.h b/src/share/ls/ob_ls_recovery_stat_operator.h index dd9766273..87ceda605 100644 --- a/src/share/ls/ob_ls_recovery_stat_operator.h +++ b/src/share/ls/ob_ls_recovery_stat_operator.h @@ -15,6 +15,7 @@ #include "share/ob_ls_id.h"//share::ObLSID #include "share/ls/ob_ls_i_life_manager.h" //ObLSLifeIAgent +#include "share/ob_tenant_role.h"//ObTenantRole #include "common/ob_zone.h"//ObZone #include "lib/container/ob_array.h"//ObArray #include "lib/container/ob_iarray.h"//ObIArray @@ -172,14 +173,30 @@ public: /* * description: update ls recovery stat, only update sync_ts/readable_ts * @param[in] recovery_stat: new_recovery_stat + * @param[in] only_update_readable_scn:only update readable_scn and check sync_scn is same * @param[in] proxy*/ int update_ls_recovery_stat(const ObLSRecoveryStat &recovery_stat, + const bool only_update_readable_scn, ObMySQLProxy &proxy); + + /* + * description: update SYS LS sync scn + * @param[in] tenant_id: target user tenant id + * @param[in] trans: transaction cient + * @param[in] sync_scn: target scn to be updated*/ + int update_sys_ls_sync_scn( + const uint64_t tenant_id, + ObMySQLTransaction &trans, + const SCN &sync_scn); + /* - * description: update ls recovery stat in trans, only update sync_ts/readable_ts + * description: update ls recovery stat in trans, only update sync_ts/readable_ts. + only can update when tenant role is normal switchover status * @param[in] recovery_stat - * @param[in] client*/ + * @param[in] only_update_readable_scn:only update readable_scn and check sync_scn is same + * @param[in] trans*/ int update_ls_recovery_stat_in_trans(const ObLSRecoveryStat &recovery_stat, + const bool only_update_readable_scn, ObMySQLTransaction &trans); /* * description: get ls recovery stat diff --git a/src/share/ls/ob_ls_status_operator.cpp b/src/share/ls/ob_ls_status_operator.cpp index 28fe65253..251fb843b 100755 --- a/src/share/ls/ob_ls_status_operator.cpp +++ b/src/share/ls/ob_ls_status_operator.cpp @@ -29,6 +29,7 @@ #include "share/schema/ob_multi_version_schema_service.h" // ObMultiVersionSchemaService #include "share/scn.h" // SCN #include "share/ls/ob_ls_operator.h" //ObLSFlag +#include "share/ls/ob_ls_status_operator.h" using namespace oceanbase; using namespace oceanbase::common; @@ -38,6 +39,46 @@ namespace oceanbase { namespace share { +const char* LS_STATUS_ARRAY[] = +{ + "CREATING", + "CREATED", + "NORMAL", + "DROPPING", + "TENANT_DROPPING", + "WAIT_OFFLINE", + "CREATE_ABORT", + "PRE_TENANT_DROPPING" +}; + +ObLSStatus str_to_ls_status(const ObString &status_str) +{ + ObLSStatus ret_status = OB_LS_EMPTY; + if (status_str.empty()) { + ret_status = OB_LS_EMPTY; + } else { + for (int64_t i = 0; i < ARRAYSIZEOF(LS_STATUS_ARRAY); i++) { + if (0 == status_str.case_compare(LS_STATUS_ARRAY[i])) { + ret_status = static_cast(i); + break; + } + } + } + return ret_status; +} + +const char* ls_status_to_str(const ObLSStatus &status) +{ + const char* str = "UNKNOWN"; + + if (OB_UNLIKELY(OB_LS_EMPTY == status)) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid log stream status", K(status)); + } else { + str = LS_STATUS_ARRAY[status]; + } + return str; +} + OB_SERIALIZE_MEMBER(ObMemberListFlag, flag_); int64_t ObMemberListFlag::to_string(char *buf, const int64_t buf_len) const @@ -223,46 +264,6 @@ int ObLSPrimaryZoneInfo::assign(const ObLSPrimaryZoneInfo &other) } ////////ObLSStatusOperator -const char* ObLSStatusOperator::LS_STATUS_ARRAY[] = -{ - "CREATING", - "CREATED", - "NORMAL", - "DROPPING", - "TENANT_DROPPING", - "WAIT_OFFLINE", - "CREATE_ABORT", - "PRE_TENANT_DROPPING" -}; - -ObLSStatus ObLSStatusOperator::str_to_ls_status(const ObString &status_str) -{ - ObLSStatus ret_status = OB_LS_EMPTY; - if (status_str.empty()) { - ret_status = OB_LS_EMPTY; - } else { - for (int64_t i = 0; i < ARRAYSIZEOF(LS_STATUS_ARRAY); i++) { - if (0 == status_str.case_compare(LS_STATUS_ARRAY[i])) { - ret_status = static_cast(i); - break; - } - } - } - return ret_status; -} - -const char* ObLSStatusOperator::ls_status_to_str(const ObLSStatus &status) -{ - const char* str = "UNKNOWN"; - - if (OB_UNLIKELY(OB_LS_EMPTY == status)) { - LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid log stream status", K(status)); - } else { - str = LS_STATUS_ARRAY[status]; - } - return str; -} - int ObLSStatusOperator::create_new_ls(const ObLSStatusInfo &ls_info, const SCN ¤t_tenant_scn, const common::ObString &zone_priority, @@ -314,6 +315,11 @@ int ObLSStatusOperator::create_new_ls(const ObLSStatusInfo &ls_info, LOG_WARN("fail to splice insert sql", KR(ret), K(sql), K(ls_info), K(flag_str)); } else if (OB_FAIL(exec_write(ls_info.tenant_id_, sql, this, trans))) { LOG_WARN("failed to exec write", KR(ret), K(ls_info), K(sql)); + } else if (ls_info.ls_id_.is_sys_ls()) { + LOG_INFO("sys ls no need update max ls id", KR(ret), K(ls_info)); + } else if (OB_FAIL(ObAllTenantInfoProxy::update_tenant_max_ls_id( + ls_info.tenant_id_, ls_info.ls_id_, trans, false))) { + LOG_WARN("failed to update tenant max ls id", KR(ret), K(ls_info)); } } return ret; @@ -487,6 +493,41 @@ int ObLSStatusOperator::update_ls_status_in_trans_( return ret; } + +int ObLSStatusOperator::alter_ls_group_id(const uint64_t tenant_id, const ObLSID &id, + const uint64_t old_ls_group_id, + const uint64_t new_ls_group_id, + const uint64_t new_unit_group_id, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!id.is_valid() + || OB_INVALID_ID == old_ls_group_id + || OB_INVALID_ID == new_ls_group_id + || OB_INVALID_ID == new_unit_group_id + || OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid_argument", KR(ret), K(id), K(new_ls_group_id), + K(old_ls_group_id), K(tenant_id)); + } else { + //init_member_list is no need after create success + common::ObSqlString sql; + const uint64_t exec_tenant_id = + ObLSLifeIAgent::get_exec_tenant_id(tenant_id); + if (OB_FAIL(sql.assign_fmt("UPDATE %s set ls_group_id = %lu, unit_group_id = %lu " + " where ls_id = %ld and tenant_id = %lu and ls_group_id = %lu", + OB_ALL_LS_STATUS_TNAME, + new_ls_group_id, new_unit_group_id, id.id(), + tenant_id, old_ls_group_id))) { + LOG_WARN("failed to assign sql", KR(ret), K(id), K(new_ls_group_id), + K(old_ls_group_id), K(tenant_id), K(sql)); + } else if (OB_FAIL(exec_write(tenant_id, sql, this, client))) { + LOG_WARN("failed to exec write", KR(ret), K(tenant_id), K(id), K(sql)); + } + } + return ret; +} + int ObLSStatusOperator::update_init_member_list( const uint64_t tenant_id, const ObLSID &id, const ObMemberList &member_list, ObISQLClient &client, @@ -661,13 +702,18 @@ int ObLSStatusOperator::get_duplicate_ls_status_info( ObMemberList member_list; common::GlobalLearnerList learner_list; ObMember arb_member; + ObLSFlag ls_flag(ObLSFlag::DUPLICATE_FLAG); + ObLSFlagStr flag_str; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ls_flag.flag_to_str(flag_str))) { + LOG_WARN("failed to get flag str", K(ret), K(ls_flag)); } else if (OB_FAIL(sql.assign_fmt( "SELECT * FROM %s where tenant_id = %lu and flag like \"%%%s%%\"", OB_ALL_LS_STATUS_TNAME, tenant_id, - LS_FLAG_ARRAY[ObLSFlag::DUPLICATE_FLAG]))) { + flag_str.ptr()))) { LOG_WARN("failed to assign sql", KR(ret), K(sql)); } else if (OB_FAIL(inner_get_ls_status_(sql, get_exec_tenant_id(tenant_id), need_member_list, client, member_list, status_info, arb_member, learner_list))) { @@ -1070,7 +1116,7 @@ int ObLSStatusOperator::get_ls_primary_zone_info(const uint64_t tenant_id, const return ret; } -int ObLSStatusOperator::get_tenant_primary_zone_info_array(const uint64_t tenant_id, +int ObLSStatusOperator::get_ls_primary_zone_info_by_order_ls_group(const uint64_t tenant_id, ObLSPrimaryZoneInfoIArray &primary_zone_info_array, ObISQLClient &client) { int ret = OB_SUCCESS; @@ -1515,6 +1561,82 @@ int ObLSStatusOperator::check_all_ls_has_leader( return ret; } +int ObLSStatusOperator::get_all_tenant_related_ls_status_info( + common::ObMySQLProxy &sql_proxy, + const uint64_t tenant_id, + ObLSStatusInfoIArray &ls_status_info_array) +{ + int ret = OB_SUCCESS; + ls_status_info_array.reset(); + if (OB_UNLIKELY(is_meta_tenant(tenant_id) || !is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (is_sys_tenant(tenant_id)) { + if (OB_FAIL(get_all_ls_status_by_order( + tenant_id, ls_status_info_array, sql_proxy))) { + LOG_WARN("fail to get all ls status", KR(ret), K(tenant_id)); + } + } else { // user tenant + const uint64_t user_tenant_id = tenant_id; + const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id); + ObLSStatusInfoArray meta_ls_status_info_array; + if (OB_FAIL(get_all_ls_status_by_order( + user_tenant_id, ls_status_info_array, sql_proxy))) { + LOG_WARN("fail to get all ls status by order", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(get_all_ls_status_by_order( + meta_tenant_id, meta_ls_status_info_array, sql_proxy))) { + LOG_WARN("fail to get all ls status by order", KR(ret), K(meta_tenant_id)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < meta_ls_status_info_array.count(); ++i) { + if (OB_FAIL(ls_status_info_array.push_back(meta_ls_status_info_array.at(i)))) { + LOG_WARN("failed to push back ls status info", KR(ret), K(i), K(meta_ls_status_info_array)); + } + } + } + } + return ret; +} + +int ObLSStatusOperator::get_tenant_max_ls_id(const uint64_t tenant_id, ObLSID &max_id, + ObISQLClient &client) +{ + int ret = OB_SUCCESS; + max_id.reset(); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("operation is not valid", KR(ret), K(tenant_id)); + } else { + ObSqlString sql; + if (OB_FAIL(sql.assign_fmt( + "SELECT max(ls_id) as max_ls_id FROM %s WHERE tenant_id = %lu", + OB_ALL_LS_STATUS_TNAME, tenant_id))) { + LOG_WARN("failed to assign sql", KR(ret), K(sql), K(tenant_id)); + } else { + HEAP_VAR(ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = NULL; + const uint64_t exec_tenant_id = get_exec_tenant_id(tenant_id); + if (OB_FAIL(client.read(res, exec_tenant_id, sql.ptr()))) { + LOG_WARN("failed to read", KR(ret), K(exec_tenant_id), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret), K(sql)); + } else if (OB_FAIL(result->next())) { + LOG_WARN("failed to get max ls id", KR(ret), K(sql), K(exec_tenant_id)); + } else { + int64_t ls_id = ObLSID::INVALID_LS_ID; + EXTRACT_INT_FIELD_MYSQL(*result, "max_ls_id", ls_id, int64_t); + if (OB_FAIL(ret)) { + LOG_WARN("failed to get int", KR(ret), K(sql), K(exec_tenant_id)); + } else { + max_id = ls_id; + } + } + } + } + } + return ret; +} + int ObLSStatusOperator::create_abort_ls_in_switch_tenant( const uint64_t tenant_id, const share::ObTenantSwitchoverStatus &status, @@ -1563,71 +1685,5 @@ int ObLSStatusOperator::create_abort_ls_in_switch_tenant( return ret; } -int ObLSStatusOperator::check_ls_exist( - const uint64_t tenant_id, - const ObLSID &ls_id, - ObLSExistState &state) -{ - int ret = OB_SUCCESS; - state.reset(); - schema::ObSchemaGetterGuard schema_guard; - bool tenant_exist = false; - ObSqlString sql; - if (OB_UNLIKELY(!ls_id.is_valid_with_tenant(tenant_id))) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", KR(ret), K(tenant_id), K(ls_id)); - } else if (OB_ISNULL(GCTX.schema_service_) || OB_ISNULL(GCTX.sql_proxy_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("GCTX has null ptr", KR(ret)); - } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("fail to get tenant schema guard", KR(ret)); - } else if (OB_FAIL(schema_guard.check_tenant_exist(tenant_id, tenant_exist))) { - LOG_WARN("fail to check tenant exist", KR(ret), K(tenant_id)); - } else if (OB_UNLIKELY(!tenant_exist)) { - ret = OB_TENANT_NOT_EXIST; - LOG_WARN("tenant not exist", KR(ret), K(tenant_id)); - } else if (OB_FAIL(sql.assign_fmt( - "SELECT (SELECT COUNT(*) > 0 FROM %s WHERE tenant_id = %lu AND ls_id = %ld) AS ls_is_existing, " - "MAX(ls_id) < %ld AS ls_is_uncreated FROM %s WHERE tenant_id = %lu", - OB_ALL_LS_STATUS_TNAME, - tenant_id, - ls_id.id(), - ls_id.id(), - OB_ALL_LS_STATUS_TNAME, - tenant_id))) { - LOG_WARN("assign sql failed", KR(ret), K(tenant_id), K(ls_id), K(sql)); - } else { - SMART_VAR(ObISQLClient::ReadResult, result) { - bool ls_is_existing = false; - bool ls_is_uncreated = false; - common::sqlclient::ObMySQLResult *res = NULL; - uint64_t exec_tenant_id = ObLSLifeIAgent::get_exec_tenant_id(tenant_id); - if (OB_FAIL(GCTX.sql_proxy_->read(result, exec_tenant_id, sql.ptr()))) { - LOG_WARN("execute sql failed", KR(ret), - K(tenant_id), K(ls_id), K(exec_tenant_id), K(sql)); - } else if (OB_ISNULL(res = result.get_result())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get mysql result failed", KR(ret), - K(tenant_id), K(ls_id), K(exec_tenant_id), K(sql)); - } else if (OB_FAIL(res->next())) { - LOG_WARN("next failed", KR(ret), K(tenant_id), K(ls_id), K(sql)); - } else if (OB_FAIL(res->get_bool("ls_is_existing", ls_is_existing))) { - LOG_WARN("fail to get ls_is_existing", KR(ret), K(tenant_id), K(ls_id)); - } else if (OB_FAIL(res->get_bool("ls_is_uncreated", ls_is_uncreated))) { - LOG_WARN("fail to get ls_is_uncreated", KR(ret), K(tenant_id), K(ls_id)); - } else if (ls_is_existing) { - state.set_existing(); - } else if (ls_is_uncreated) { - state.set_uncreated(); - } else { - state.set_deleted(); - } - LOG_INFO("check ls exist finished", KR(ret), - K(tenant_id), K(ls_id), K(state), K(ls_is_existing), K(ls_is_uncreated)); - } - } - return ret; -} - }//end of share }//end of ob diff --git a/src/share/ls/ob_ls_status_operator.h b/src/share/ls/ob_ls_status_operator.h index 3550724d5..b60a551d8 100755 --- a/src/share/ls/ob_ls_status_operator.h +++ b/src/share/ls/ob_ls_status_operator.h @@ -58,6 +58,7 @@ class ObMultiVersionSchemaService; ObLSStatus str_to_ls_status(const ObString &status_str); const char* ls_status_to_str(const ObLSStatus &status); + bool ls_is_empty_status(const ObLSStatus &status); bool ls_is_creating_status(const ObLSStatus &status); bool ls_is_created_status(const ObLSStatus &status); @@ -69,6 +70,8 @@ bool is_valid_status_in_ls(const ObLSStatus &status); bool ls_is_create_abort_status(const ObLSStatus &status); bool ls_need_create_abort_status(const ObLSStatus &status); bool ls_is_pre_tenant_dropping_status(const ObLSStatus &status); +class ObLSStatusOperator; + const int64_t MAX_MEMBERLIST_FLAG_LENGTH = 10; class ObMemberListFlag { @@ -156,6 +159,12 @@ struct ObLSStatusInfo { return status_; } + + ObLSID get_ls_id() const + { + return ls_id_; + } + ObLSFlag get_flag() const { return flag_; @@ -177,7 +186,8 @@ struct ObLSStatusInfo ObZone primary_zone_; share::ObLSFlag flag_; - TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(ls_group_id), K_(status), + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(ls_group_id), + "status", ls_status_to_str(status_), K_(unit_group_id), K_(primary_zone), K_(flag)); }; @@ -249,10 +259,6 @@ class ObLSStatusOperator : public ObLSLifeIAgent, public ObLSTemplateOperator ObLSStatusOperator() {}; virtual ~ObLSStatusOperator(){} - static const char* LS_STATUS_ARRAY[]; - static ObLSStatus str_to_ls_status(const ObString &status_str); - static const char* ls_status_to_str(const ObLSStatus &status); - public: /* * description: override of ObLSLifeIAgent @@ -331,6 +337,19 @@ public: ObISQLClient &client, const ObMember &arb_member, const common::GlobalLearnerList &learner_list); + /* + * description: update ls's ls group id + * @param[in] tenant_id + * @param[in] ls_id + * @param[in] old_ls_group_id + * @param[in] new_ls_group_id + * @param[in] unit_group_id : the new ls group's target unit group + * @param[in] client*/ + int alter_ls_group_id(const uint64_t tenant_id, const ObLSID &id, + const uint64_t old_ls_group_id, + const uint64_t new_ls_group_id, + const uint64_t new_unit_group_id, + ObISQLClient &client); int get_all_ls_status_by_order(const uint64_t tenant_id, ObLSStatusInfoIArray &ls_array, @@ -386,9 +405,16 @@ public: share::ObLSPrimaryZoneInfo &status_info); int get_ls_primary_zone_info(const uint64_t tenant_id, const ObLSID &id, ObLSPrimaryZoneInfo &primary_zone_info, ObISQLClient &client); - int get_tenant_primary_zone_info_array(const uint64_t tenant_id, + int get_ls_primary_zone_info_by_order_ls_group(const uint64_t tenant_id, ObLSPrimaryZoneInfoIArray &primary_zone_info_array, ObISQLClient &client); + /* + * description: get user tenant max ls id, only for compatible + * @param[in] tenant_id + * @param[out] max_id: max ls id of the tenant + * @param[in] client*/ + int get_tenant_max_ls_id(const uint64_t tenant_id, ObLSID &max_id, + ObISQLClient &client); /** * @description: @@ -434,47 +460,17 @@ public: ObISQLClient &client, const char *print_str, bool &has_ls_without_leader, - common::ObSqlString &error_msg); - - struct ObLSExistState final - { - public: - enum State - { - INVALID_STATE = -1, - EXISTING, - DELETED, - UNCREATED, - MAX_STATE - }; - ObLSExistState() : state_(INVALID_STATE) {} - ~ObLSExistState() {} - void reset() { state_ = INVALID_STATE; } - void set_existing() { state_ = EXISTING; } - void set_deleted() { state_ = DELETED; } - void set_uncreated() { state_ = UNCREATED; } - bool is_valid() const { return state_ > INVALID_STATE && state_ < MAX_STATE; } - bool is_existing() const { return EXISTING == state_; } - bool is_deleted() const { return DELETED == state_; } - bool is_uncreated() const { return UNCREATED == state_; } - - TO_STRING_KV(K_(state)); - private: - State state_; - }; - - /* check if the ls exists by __all_virtual_ls_status - * - * @param[in] tenant_id: target tenant_id - * @param[in] ls_id: target ls_id - * @param[out] state: EXISTING/DELETED/UNCREATED - * @return - * - OB_SUCCESS: check successfully - * - OB_TENANT_NOT_EXIST: tenant not exist - * - OB_INVALID_ARGUMENT: invalid ls_id or tenant_id - * - other: other failures - */ - static int check_ls_exist(const uint64_t tenant_id, const ObLSID &ls_id, ObLSExistState &state); + ObSqlString &error_msg); + /* + * description: get all tenant ls status. for user tenant: get user tenant ls status info and meta tenant ls status info + * @param[in] sql_proxy + * @param[in] tenant_id : maybe user tenant id and sys tenant id + * @param[out] ls status info array + * */ + int get_all_tenant_related_ls_status_info( + common::ObMySQLProxy &sql_proxy, + const uint64_t tenant_id, + ObLSStatusInfoIArray &ls_status_info_array); private: template int get_list_hex_( diff --git a/src/share/ls/ob_ls_table_operator.cpp b/src/share/ls/ob_ls_table_operator.cpp index 7c787cf60..66aa04909 100644 --- a/src/share/ls/ob_ls_table_operator.cpp +++ b/src/share/ls/ob_ls_table_operator.cpp @@ -375,5 +375,35 @@ int ObLSTableOperator::remove_residual_ls( return ret; } +int ObLSTableOperator::batch_get( + const int64_t cluster_id, + const uint64_t tenant_id, + const common::ObIArray &ls_ids, + const ObLSTable::Mode mode, + common::ObIArray &ls_infos) +{ + int ret = OB_SUCCESS; + ls_infos.reset(); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (is_sys_tenant(tenant_id)) { + ObLSInfo ls_info; + if (OB_FAIL(get(cluster_id, OB_SYS_TENANT_ID, SYS_LS, mode, ls_info))) { + LOG_WARN("fail to get sys_tenant ls", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ls_infos.push_back(ls_info))) { + LOG_WARN("fail to assign", KR(ret), K(ls_info)); + } + } else if (is_meta_tenant(tenant_id) || is_user_tenant(tenant_id)) { + if (OB_FAIL(persistent_ls_.batch_get(cluster_id, tenant_id, ls_ids, ls_infos))) { + LOG_WARN("get all ls info by persistent_ls_ failed", KR(ret), K(tenant_id)); + } + } else { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant_id for ObLSTableOperator", KR(ret), K(tenant_id)); + } + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/ls/ob_ls_table_operator.h b/src/share/ls/ob_ls_table_operator.h index a140e5c19..ed1113524 100644 --- a/src/share/ls/ob_ls_table_operator.h +++ b/src/share/ls/ob_ls_table_operator.h @@ -118,6 +118,20 @@ public: const uint64_t tenant_id, const ObAddr &server, int64_t &residual_count); + // batch get ls info + // + // @param [in] cluster_id, target cluster_id + // @parma [in] tenant_id, target tenant_id + // @param [in] ls_ids, target ls_id array + // @param [in] mode, determine data source of sys tenant's ls info + // @param [out] ls_infos, information of ls + // @return OB_ERR_DUP_ARGUMENT if ls_ids have duplicate values + int batch_get( + const int64_t cluster_id, + const uint64_t tenant_id, + const common::ObIArray &ls_ids, + const ObLSTable::Mode mode, + common::ObIArray &ls_infos); private: // to use inmemory path to get and update informations int set_use_memory_ls_(ObIRsListChangeCb &rs_list_change_cb); diff --git a/src/share/ls/ob_persistent_ls_table.cpp b/src/share/ls/ob_persistent_ls_table.cpp index e0c13fa72..d98b666d8 100644 --- a/src/share/ls/ob_persistent_ls_table.cpp +++ b/src/share/ls/ob_persistent_ls_table.cpp @@ -201,6 +201,7 @@ int ObPersistentLSTable::construct_ls_replica( int64_t required_size = 0; ObString learner_list; GlobalLearnerList learner_list_to_set; + int64_t rebuild_flag = 0; // TODO: try to fetch coulmn_value by column_name // column select order defined in LSTableColNames::LSTableColNames // location related @@ -231,6 +232,7 @@ int ObPersistentLSTable::construct_ls_replica( (void)GET_COL_IGNORE_NULL(res.get_int, "data_size", data_size); (void)GET_COL_IGNORE_NULL_WITH_DEFAULT_VALUE(res.get_int, "required_size", required_size, 0); EXTRACT_VARCHAR_FIELD_MYSQL_SKIP_RET(res, "learner_list", learner_list); + EXTRACT_INT_FIELD_MYSQL_WITH_DEFAULT_VALUE(res, "rebuild", rebuild_flag, int64_t, true, true, 0); if (OB_FAIL(ret)) { } else if (OB_FAIL(ObLSReplica::text2member_list( @@ -275,7 +277,8 @@ int ObPersistentLSTable::construct_ls_replica( data_size, required_size, member_list_to_set, - learner_list_to_set))) { + learner_list_to_set, + 0 != rebuild_flag))) { LOG_WARN("fail to init a ls replica", KR(ret), K(create_time_us), K(modify_time_us), K(tenant_id), K(ls_id), K(server), K(sql_port), K(role), K(replica_type), K(proposal_id), K(unit_id), K(zone), @@ -557,11 +560,14 @@ int ObPersistentLSTable::fill_dml_splicer_( { int ret = OB_SUCCESS; char ip[OB_MAX_SERVER_ADDR_SIZE] = ""; + uint64_t compat_version = 0; ObSqlString member_list; ObSqlString learner_list; if (!replica.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid replica", KR(ret), K(replica)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(replica.get_tenant_id(), compat_version))) { + LOG_WARN("fail to get data version", KR(ret), K(replica)); } else if (false == replica.get_server().ip_to_string(ip, sizeof(ip))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("convert server ip to string failed", KR(ret), "server", replica.get_server()); @@ -588,6 +594,9 @@ int ObPersistentLSTable::fill_dml_splicer_( || OB_FAIL(dml_splicer.add_column("data_size", replica.get_data_size())) || OB_FAIL(dml_splicer.add_column("required_size", replica.get_required_size()))){ LOG_WARN("add column failed", KR(ret), K(replica)); + } else if (compat_version >= DATA_VERSION_4_2_0_0 + && OB_FAIL(dml_splicer.add_column("rebuild", replica.get_rebuild()))) { + LOG_WARN("add column rebuild failed", KR(ret), K(replica)); } uint64_t tenant_to_check_data_version = replica.get_tenant_id(); @@ -811,5 +820,83 @@ int ObPersistentLSTable::remove_residual_ls( return ret; } +int ObPersistentLSTable::batch_get( + const int64_t cluster_id, + const uint64_t tenant_id, + const common::ObIArray &ls_ids, + common::ObIArray &ls_infos) +{ + int ret = OB_SUCCESS; + ls_infos.reset(); + ObSqlString sql; + if (OB_UNLIKELY(!inited_) || OB_ISNULL(sql_proxy_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObPersistentLSTable not init", KR(ret)); + } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || is_virtual_tenant_id(tenant_id) + || ls_ids.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant_id", KR(ret), K(cluster_id), K(tenant_id), K(ls_ids)); + } else if (OB_FAIL(sql.assign_fmt( + "SELECT * FROM %s WHERE tenant_id = %lu AND ls_id IN (", + OB_ALL_LS_META_TABLE_TNAME, + tenant_id))) { + LOG_WARN("assign sql string failed", KR(ret), K(sql)); + } + ARRAY_FOREACH(ls_ids, idx) { + const ObLSID &ls_id = ls_ids.at(idx); + if (OB_UNLIKELY(!ls_id.is_valid_with_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ls_id with tenant", KR(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(sql.append_fmt( + "%s%ld", + 0 == idx ? "" : ",", + ls_id.id()))) { + LOG_WARN("fail to assign sql", KR(ret), K(tenant_id), K(ls_id)); + } + } + if (FAILEDx(sql.append_fmt(") ORDER BY tenant_id, ls_id, svr_ip, svr_port"))) { + LOG_WARN("appent fmt failed", KR(ret), K(tenant_id), K(ls_ids), K(sql)); + } else { + const uint64_t exec_tenant_id = get_private_table_exec_tenant_id(tenant_id); + SMART_VAR(ObISQLClient::ReadResult, result) { + if (OB_FAIL(sql_proxy_->read(result, cluster_id, exec_tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(exec_tenant_id), K(sql)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K(sql)); + } else if (OB_FAIL(construct_ls_infos_(*result.get_result(), ls_infos))) { + LOG_WARN("construct log stream infos failed", KR(ret), K(ls_infos)); + } + } + // if ls not found, return empty ls_info + if (OB_SUCC(ret) && (ls_ids.count() != ls_infos.count())) { + ARRAY_FOREACH(ls_ids, i) { + const ObLSID &ls_id = ls_ids.at(i); + bool found = false; + ARRAY_FOREACH(ls_infos, j) { + if (ls_id == ls_infos.at(j).get_ls_id()) { + found = true; + break; + } + } + if (OB_SUCC(ret) && !found) { + ObLSInfo ls_info; + if (OB_FAIL(ls_info.init(tenant_id, ls_id))) { + LOG_WARN("init ls_info failed", KR(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(ls_infos.push_back(ls_info))) { + LOG_WARN("push back failed", KR(ret), K(ls_info)); + } + } + } // end ARRAY_FOREACH ls_ids + if (OB_SUCC(ret) && OB_UNLIKELY(ls_ids.count() != ls_infos.count())) { + ret = OB_ERR_DUP_ARGUMENT; + LOG_WARN("there are duplicate values in ls_ids", KR(ret), K(ls_ids)); + } + } + } + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/ls/ob_persistent_ls_table.h b/src/share/ls/ob_persistent_ls_table.h index debf7a186..e44802a03 100644 --- a/src/share/ls/ob_persistent_ls_table.h +++ b/src/share/ls/ob_persistent_ls_table.h @@ -105,7 +105,7 @@ public: const ObAddr &server, const bool inner_table_only) override; - // remove residual ls in __all_tablet_meta_table for ObServerMetaTableChecker + // remove residual ls in __all_ls_meta_table for ObServerMetaTableChecker // // @param [in] tenant_id, tenant for query // @param [in] server, target ObAddr @@ -115,6 +115,20 @@ public: const ObAddr &server, int64_t &residual_count); + // batch get ls info from __all_ls_meta_table + // + // @param [in] cluster_id, target cluster_id + // @parma [in] tenant_id, target tenant_id + // @param [in] ls_ids, target ls_id array + // @param [out] ls_infos, information of ls + // @return OB_SUCCESS if success + // OB_ERR_DUP_ARGUMENT if ls_ids have duplicate values + int batch_get( + const int64_t cluster_id, + const uint64_t tenant_id, + const common::ObIArray &ls_ids, + common::ObIArray &ls_infos); + private: // ls table sql operation // use select for update for reading if lock_replica is true. diff --git a/src/share/ob_balance_define.cpp b/src/share/ob_balance_define.cpp new file mode 100644 index 000000000..3859566f2 --- /dev/null +++ b/src/share/ob_balance_define.cpp @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2021 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. + */ +#define USING_LOG_PREFIX SHARE + +#include "ob_balance_define.h" + +namespace oceanbase +{ +namespace share +{ +bool need_balance_table(const schema::ObSimpleTableSchemaV2 &table_schema) +{ + //TODO not support nonduplicate and duplicate exchange + return !table_schema.is_duplicate_table() + && (table_schema.is_user_table() + || table_schema.is_global_index_table() + || table_schema.is_tmp_table()); +} + +} +} diff --git a/src/share/ob_balance_define.h b/src/share/ob_balance_define.h new file mode 100644 index 000000000..bf28b9b8f --- /dev/null +++ b/src/share/ob_balance_define.h @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2021 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_OB_BALANCE_DEFINE_H_ +#define OCEANBASE_SHARE_OB_BALANCE_DEFINE_H_ + +#include "share/ob_common_id.h" // ObCommonID +#include "share/schema/ob_table_schema.h" // ObSimpleTableSchemaV2 + +namespace oceanbase +{ +namespace share +{ +typedef ObCommonID ObBalanceJobID; +typedef ObCommonID ObBalanceTaskID; +typedef ObCommonID ObTransferTaskID; + +// check Tables that need balance by RS +// +// 1. USER TABLE: user created table, need balance +// 2. GLOBAL INDEX: global index is distributed independently from the main table, need balance +// 3. TMP TABLE: temp table is created by user, need balance +bool need_balance_table(const schema::ObSimpleTableSchemaV2 &table_schema); + +} +} + +#endif /* !OCEANBASE_SHARE_OB_BALANCE_DEFINE_H_ */ diff --git a/src/share/ob_common_id.cpp b/src/share/ob_common_id.cpp new file mode 100644 index 000000000..fc651d231 --- /dev/null +++ b/src/share/ob_common_id.cpp @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX COMMON + +#include "ob_common_id.h" + +#include "lib/oblog/ob_log_module.h" // LOG_* +#include "lib/oblog/ob_log.h" // LOG_* +#include "lib/utility/ob_unify_serialize.h" +#include "lib/utility/serialization.h" +#include "share/ob_errno.h" + +namespace oceanbase +{ +using namespace common; +namespace share +{ + +uint64_t ObCommonID::hash() const +{ + OB_ASSERT(id_ >= 0); + return id_; +} + +int ObCommonID::serialize(char* buf, const int64_t buf_len, int64_t& pos) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), KP(buf), K(buf_len)); + } else if (OB_FAIL(serialization::encode_vi64(buf, buf_len, pos, id_))) { + LOG_WARN("serialize ID failed", KR(ret), KP(buf), K(buf_len), K(pos)); + } + return ret; +} + +int ObCommonID::deserialize(const char* buf, const int64_t data_len, int64_t& pos) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(data_len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), KP(buf), K(data_len)); + } else if (OB_FAIL(serialization::decode_vi64(buf, data_len, pos, &id_))) { + LOG_WARN("deserialize ID failed", KR(ret), KP(buf), K(data_len), K(pos)); + } + return ret; +} + +int64_t ObCommonID::get_serialize_size() const +{ + int64_t size = 0; + size += serialization::encoded_length_i64(id_); + return size; +} + +int ObCommonID::parse_from_display_str(const common::ObString &str) +{ + int ret = OB_SUCCESS; + errno = 0; + if (OB_UNLIKELY(1 != sscanf(str.ptr(), "%ld", &id_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ObCommonID str", KR(ret), K(str), K(errno), KERRMSG, K(id_)); + } + return ret; +} + +int ObCommonID::to_display_str(char *buf, const int64_t len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0 || pos < 0 || pos >= len || !is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), KP(buf), K(len), K(pos), KPC(this)); + } else if (OB_FAIL(databuff_printf(buf, len, pos, "%ld", id_))) { + LOG_WARN("databuff_printf failed", KR(ret), K(len), K(pos), K(buf), KPC(this)); + } + return ret; +} + + +} // end namespace share +} // end namespace oceanbase diff --git a/src/share/ob_common_id.h b/src/share/ob_common_id.h new file mode 100644 index 000000000..b3dd17f37 --- /dev/null +++ b/src/share/ob_common_id.h @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2021 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_OB_COMMON_ID_H_ +#define OCEANBASE_SHARE_OB_COMMON_ID_H_ + +#include +#include "lib/utility/ob_print_utils.h" // TO_STRING_KV +#include "share/ob_display_list.h" // ObDisplayType + +namespace oceanbase +{ +namespace share +{ + +// Define a common ID type for all ID requirement. +class ObCommonID +{ +public: + static const int64_t INVALID_ID = -1; + +public: + ObCommonID() : id_(INVALID_ID) {} + ObCommonID(const ObCommonID &other) : id_(other.id_) {} + explicit ObCommonID(const int64_t id) : id_(id) {} + ~ObCommonID() { reset(); } + +public: + int64_t id() const { return id_; } + void reset() { id_ = INVALID_ID; } + + // assignment + ObCommonID &operator=(const int64_t id) { id_ = id; return *this; } + ObCommonID &operator=(const ObCommonID &other) { id_ = other.id_; return *this; } + + bool is_valid() const { return INVALID_ID != id_; } + + // compare operator + bool operator == (const ObCommonID &other) const { return id_ == other.id_; } + bool operator > (const ObCommonID &other) const { return id_ > other.id_; } + bool operator != (const ObCommonID &other) const { return id_ != other.id_; } + bool operator < (const ObCommonID &other) const { return id_ < other.id_; } + int compare(const ObCommonID &other) const + { + if (id_ == other.id_) { + return 0; + } else if (id_ < other.id_) { + return -1; + } else { + return 1; + } + } + + /////////////////////// for ObDisplayType /////////////////////// + //NOTE: to use ObDisplayList, we should implement all interfaces of ObDisplayType + // + // max length of "id": 20 + '\0' + int64_t max_display_str_len() const { return 21; } + // convert to "id" + int to_display_str(char *buf, const int64_t len, int64_t &pos) const; + // parse from "id" + int parse_from_display_str(const common::ObString &str); + + uint64_t hash() const; + NEED_SERIALIZE_AND_DESERIALIZE; + TO_STRING_KV(K_(id)); +private: + int64_t id_; +}; + +} +} + +#endif /* OCEANBASE_SHARE_OB_COMMON_ID_H_ */ diff --git a/src/share/ob_common_rpc_proxy.h b/src/share/ob_common_rpc_proxy.h index 8b1bc1828..86f7c5e31 100644 --- a/src/share/ob_common_rpc_proxy.h +++ b/src/share/ob_common_rpc_proxy.h @@ -246,9 +246,6 @@ public: RPC_S(PR5 abort_redef_table, obrpc::OB_ABORT_REDEF_TABLE, (obrpc::ObAbortRedefTableArg)); RPC_S(PR5 update_ddl_task_active_time, obrpc::OB_UPDATE_DDL_TASK_ACTIVE_TIME, (obrpc::ObUpdateDDLTaskActiveTimeArg)); - RPC_S(PR5 backup_ls_data_res, OB_BACKUP_LS_DATA_RES, (ObBackupTaskRes)); - RPC_S(PR5 delete_backup_ls_task_res, OB_DELETE_BACKUP_LS_TASK_RES, (ObBackupTaskRes)); - RPC_S(PR5 disaster_recovery_task_reply, OB_DISASTER_RECOVERY_TASK_REPLY, (ObDRTaskReplyResult)); RPC_S(PR5 backup_compl_log_res, obrpc::OB_BACKUP_COMPL_LOG_RES, (ObBackupTaskRes)); diff --git a/src/share/ob_ddl_common.cpp b/src/share/ob_ddl_common.cpp index a8badb21b..418859513 100644 --- a/src/share/ob_ddl_common.cpp +++ b/src/share/ob_ddl_common.cpp @@ -833,7 +833,7 @@ int ObDDLUtil::ddl_get_tablet( ObLSHandle &ls_handle, const ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle, - const int64_t get_timeout_ts) + storage::ObMDSGetTabletMode mode) { int ret = OB_SUCCESS; ObLS *ls = nullptr; @@ -845,7 +845,7 @@ int ObDDLUtil::ddl_get_tablet( } else if (OB_FAIL(ls->get_tablet_svr()->get_tablet_with_timeout(tablet_id, tablet_handle, timeout_ts, - get_timeout_ts))) { + mode))) { LOG_WARN("fail to get tablet handle", K(ret), K(tablet_id)); if (OB_ALLOCATE_MEMORY_FAILED == ret) { ret = OB_TIMEOUT; diff --git a/src/share/ob_ddl_common.h b/src/share/ob_ddl_common.h index 2387eee81..9b6c9eab3 100644 --- a/src/share/ob_ddl_common.h +++ b/src/share/ob_ddl_common.h @@ -109,7 +109,7 @@ enum ObDDLTaskType enum ObDDLTaskStatus { PREPARE = 0, - LOCK_TABLE = 1, + OBTAIN_SNAPSHOT = 1, WAIT_TRANS_END = 2, REDEFINITION = 3, VALIDATE_CHECKSUM = 4, @@ -136,8 +136,8 @@ static const char* ddl_task_status_to_str(const ObDDLTaskStatus &task_status) { case share::ObDDLTaskStatus::PREPARE: str = "PREPARE"; break; - case share::ObDDLTaskStatus::LOCK_TABLE: - str = "LOCK_TABLE"; + case share::ObDDLTaskStatus::OBTAIN_SNAPSHOT: + str = "OBTAIN_SNAPSHOT"; break; case share::ObDDLTaskStatus::WAIT_TRANS_END: str = "WAIT_TRANS_END"; @@ -352,7 +352,7 @@ public: storage::ObLSHandle &ls_handle, const ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle, - const int64_t timeout_us = storage::ObTabletCommon::DEFAULT_GET_TABLET_TIMEOUT_US); + const storage::ObMDSGetTabletMode mode = storage::ObMDSGetTabletMode::READ_READABLE_COMMITED); static int clear_ddl_checksum(sql::ObPhysicalPlan *phy_plan); diff --git a/src/share/ob_debug_sync_point.h b/src/share/ob_debug_sync_point.h old mode 100644 new mode 100755 index e14b18675..5446e3324 --- a/src/share/ob_debug_sync_point.h +++ b/src/share/ob_debug_sync_point.h @@ -401,6 +401,7 @@ class ObString; ACT(BEFORE_LS_RESTORE_SYS_TABLETS,)\ ACT(BEFORE_WAIT_RESTORE_SYS_TABLETS,)\ ACT(BEFORE_WAIT_RESTORE_TABLETS_META,)\ + ACT(BEFORE_WAIT_LS_RESTORE_TO_CONSISTENT_SCN,)\ ACT(BEFORE_WAIT_QUICK_RESTORE,)\ ACT(BEFORE_WAIT_MAJOR_RESTORE,)\ ACT(SWAP_ORIG_AND_HIDDEN_TABLE_BEFORE_PUBLISH_SCHEMA,)\ @@ -432,6 +433,15 @@ class ObString; ACT(BLOCK_TENANT_SYNC_SNAPSHOT_INC,)\ ACT(AFTER_FLASHBACK_CLOG,)\ ACT(BEFORE_LOAD_ARCHIVE_ROUND,)\ + ACT(BEFORE_PREPARE_MIGRATION_TASK,)\ + ACT(BEFORE_INITIAL_MIGRATION_TASK,)\ + ACT(BEFORE_START_TRANSFER_TRANS,)\ + ACT(START_TRANSFER_TRANS,)\ + ACT(SWITCH_LEADER_BEFORE_TRANSFER_DOING_START_TRANS,)\ + ACT(SWITCH_LEADER_AFTER_TRANSFER_DOING_START_TRANS,)\ + ACT(SWITCH_LEADER_BETWEEN_FINISH_TRANSFER_IN_AND_OUT,)\ + ACT(TRANSFER_BACKFILL_TX_BEFORE,)\ + ACT(TRANSFER_REPLACE_TABLE_BEFORE,)\ ACT(BEFORE_MIG_DDL_TABLE_MERGE_TASK,)\ ACT(BEFORE_COPY_DDL_SSTABLE,)\ ACT(BEFORE_DDL_WRITE_PREPARE_LOG,)\ @@ -440,9 +450,39 @@ class ObString; ACT(ALTER_LS_CHOOSE_SRC,)\ ACT(BEFORE_LOCK_SERVICE_UNLOCK,)\ ACT(DDL_CHECK_TABLET_MERGE_STATUS,)\ - ACT(BEFORE_FOREIGN_KEY_CONSTRAINT_CHECK,)\ + ACT(BEFORE_LOCK_LS_WHEN_CREATE_TABLE,)\ + ACT(AFTER_BLOCK_TABLET_IN_WHEN_LS_MERGE,)\ + ACT(BEFORE_TENANT_BALANCE_SERVICE,)\ + ACT(BEFORE_TENANT_BALANCE_SERVICE_EXECUTE,)\ + ACT(BEFORE_PROCESS_BALANCE_TASK_INIT,)\ + ACT(BEFORE_PROCESS_BALANCE_TASK_CREATE_LS,)\ + ACT(BEFORE_PROCESS_BALANCE_TASK_TRANSFER,)\ + ACT(BEFORE_PROCESS_BALANCE_TASK_ALTER_LS,)\ + ACT(BEFORE_PROCESS_BALANCE_TASK_SET_MERGE,)\ + ACT(BEFORE_PROCESS_BALANCE_TASK_DROP_LS,)\ + ACT(BEFORE_PROCESS_BALANCE_TASK_TRANSFER_END,)\ ACT(MODIFY_HIDDEN_TABLE_NOT_NULL_COLUMN_STATE_BEFORE_PUBLISH_SCHEMA,)\ ACT(AFTER_MIGRATION_FETCH_TABLET_INFO,)\ + ACT(AFTER_LOCK_LS_AND_BEFORE_CHANGE_LS_FLAG,)\ + ACT(AFTER_LOCK_ALL_BALANCE_JOB,)\ + ACT(BEFORE_TRANSFER_START_LOCK_MEMBER_LIST,)\ + ACT(AFTER_TRANSFER_START_LOCK_MEMBER_LIST,)\ + ACT(BEFORE_ON_REDO_START_TRANSFER_OUT,)\ + ACT(AFTER_ON_REDO_START_TRANSFER_OUT,)\ + ACT(AFTER_PART_ON_REDO_FINISH_TRANSFER_OUT,)\ + ACT(AFTER_ON_REDO_FINISH_TRANSFER_OUT,)\ + ACT(BEFORE_ON_REDO_START_TRANSFER_IN,)\ + ACT(AFTER_ON_REDO_START_TRANSFER_IN,)\ + ACT(AFTER_ON_COMMIT_START_TRANSFER_IN,)\ + ACT(BEFORE_TRANSFER_LOCK_TABLE_AND_PART,)\ + ACT(AFTER_TRANSFER_LOCK_TABLE_FOR_GLOBAL_INDEX,)\ + ACT(AFTER_TRANSFER_LOCK_TABLE_FOR_NORMAL_TABLE,)\ + ACT(AFTER_TRANSFER_PROCESS_INIT_TASK_AND_BEFORE_NOTIFY_STORAGE,)\ + ACT(BEFORE_TRANSFER_ADD_ONLINE_DDL_LOCK,)\ + ACT(BEFORE_DROPPING_LS_IN_BALANCE_MERGE_TASK,)\ + ACT(BEFORE_WAIT_LOG_SYNC,)\ + ACT(BEFORE_WAIT_LOG_REPLAY_SYNC,)\ + ACT(BEFORE_FOREIGN_KEY_CONSTRAINT_CHECK,)\ ACT(BEFORE_EXECUTE_ARB_REPLICA_TASK,)\ ACT(ARCHIVE_SENDER_HANDLE_TASK_DONE,)\ ACT(BEFORE_SET_LS_MEMBER_LIST,)\ @@ -455,6 +495,36 @@ class ObString; ACT(AFTER_LS_GC_DELETE_ALL_TABLETS,)\ ACT(BEFORE_ARCHIVE_ADD_LS_TASK,)\ ACT(AFTER_UPDATE_INDEX_STATUS,)\ + ACT(BEFORE_COMPLETE_MIGRATION_UPDATE_STATUS,)\ + ACT(AFTER_TRANSFER_DUMP_MDS_TABLE,)\ + ACT(BEFORE_PROCESS_BALANCE_EXECUTE_WORK,)\ + ACT(BEFORE_WAIT_RESTORE_TO_CONSISTENT_SCN,)\ + ACT(BEFORE_BACKUP_1001_META,)\ + ACT(BEFORE_BACKUP_1002_META,)\ + ACT(BEFORE_BACKUP_CONSISTENT_SCN,)\ + ACT(BEFORE_TRANSFER_UPDATE_TABLET_TO_LS,)\ + ACT(AFTER_CHANGE_BACKUP_TURN_ID,)\ + ACT(AFTER_START_TRANSFER_WAIT_REPLAY_TO_START_SCN,)\ + ACT(AFTER_START_TRANSFER_GET_TABLET_META,)\ + ACT(AFTER_START_TRANSFER_OUT,)\ + ACT(AFTER_START_TRANSFER_GET_START_SCN,)\ + ACT(AFTER_START_TRANSFER_IN,)\ + ACT(AFTER_UPDATE_TABLET_TO_LS,)\ + ACT(AFTER_DOING_TRANSFER_LOCK_MEMBER_LIST,)\ + ACT(AFTER_DOING_TRANSFER_WAIT_REPLAY_SCN,)\ + ACT(AFTER_FINISH_TRANSFER_OUT,)\ + ACT(BEFORE_DOING_TRANSFER_COMMIT,)\ + ACT(BEFORE_BACKUP_MAJOR,)\ + ACT(BEFORE_TABLET_MDS_FLUSH,)\ + ACT(BEFORE_CHECKPOINT_TASK,)\ + ACT(AFTER_EMPTY_SHELL_TABLET_CREATE,)\ + ACT(AFTER_RESTORE_TABLET_TASK,)\ + ACT(BEFORE_TABLET_GC,)\ + ACT(AFTER_TRANSFER_BLOCK_AND_KILL_TX,)\ + ACT(AFTER_TRANSFER_UNBLOCK_TX,)\ + ACT(AFTER_CHECKPOINT_GET_CURSOR,)\ + ACT(BEFORE_EXECUTE_BALANCE_TASK,)\ + ACT(BEFORE_CHANGE_BACKUP_TURN,)\ ACT(BEFORE_PROCESS_AFTER_HAS_MEMBER_LIST,)\ ACT(END_DELETE_SERVER_BEFORE_CHECK_META_TABLE,)\ ACT(BEFORE_MIGRATION_DISABLE_VOTE,)\ @@ -463,6 +533,10 @@ class ObString; ACT(BEFORE_UNIQ_TASK_RUN,)\ ACT(BEFORE_PARELLEL_TRUNCATE,)\ ACT(END_DDL_IN_PX_SUBCOORD,)\ + ACT(BEFORE_SEND_ADD_REPLICA_DRTASK,)\ + ACT(BETWEEN_INSERT_LOCK_INFO_AND_TRY_LOCK_CONFIG_CHANGE,)\ + ACT(BEFORE_CHECK_SHRINK_RESOURCE_POOL,)\ + ACT(STOP_RECOVERY_LS_THREAD0,)\ ACT(MAX_DEBUG_SYNC_POINT,) DECLARE_ENUM(ObDebugSyncPoint, debug_sync_point, OB_DEBUG_SYNC_POINT_DEF); diff --git a/src/share/ob_delegate.h b/src/share/ob_delegate.h index ec9654a0a..7491c6929 100644 --- a/src/share/ob_delegate.h +++ b/src/share/ob_delegate.h @@ -22,6 +22,13 @@ return delegate_obj.func_name(std::forward(args)...); \ } +#define CONST_DELEGATE(delegate_obj, func_name) \ + template \ + auto func_name(Args &&...args) \ + ->decltype(delegate_obj.func_name(std::forward(args)...)) const { \ + return delegate_obj.func_name(std::forward(args)...); \ + } + #define DELEGATE_WITH_RET(delegate_obj, func_name, ret) \ template \ ret func_name(Args &&...args) { \ diff --git a/src/share/ob_display_list.h b/src/share/ob_display_list.h new file mode 100644 index 000000000..1675632a2 --- /dev/null +++ b/src/share/ob_display_list.h @@ -0,0 +1,171 @@ +/** + * Copyright (c) 2021 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_OB_DISPLAY_LIST +#define OCEANBASE_SHARE_OB_DISPLAY_LIST +#include +#include "lib/container/ob_iarray.h" // ObIArray +#include "lib/container/ob_array.h" // ObArrayImpl +#include "lib/string/ob_string.h" // ObString +#include "lib/ob_errno.h" // OB_xx +#include "lib/utility/ob_print_utils.h" // COMMON_LOG +#include "lib/utility/ob_macro_utils.h" // FOREACH_CNT_X +#include "lib/allocator/page_arena.h" // ObArenaAllocator +#include "share/ob_errno.h" // KR, ob_error_name + +namespace oceanbase +{ +namespace share +{ +/* + * Parse List of objects to ObString using comma connected, which can be displayed in inner table or views + * + * Object type should inherit from ObDisplayType to implement all its interface functions. + * + * Pair function: display_str_to_list(...) + * + * @param [in] allocator: allocator used to manage memory of ObString + * @param [in] list: List of objects + * @param [out] str: comma-connected string + * @return OB_SUCCESS if success, otherwise failed + */ +template +int list_to_display_str(Allocator &allocator, const common::ObIArray &list, common::ObString &str) +{ + int ret = OB_SUCCESS; + str.reset(); + if (OB_UNLIKELY(list.empty())) { + // do nothing + } else { + char *buf = NULL; + int64_t pos = 0; + const int64_t obj_max_str_len = list.at(0).max_display_str_len(); + const int64_t len = list.count() * obj_max_str_len; + + if (OB_ISNULL(buf = static_cast(allocator.alloc(len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + COMMON_LOG(WARN, "allocate memory failed", KR(ret), K(len), K(obj_max_str_len)); + } else { + FOREACH_CNT_X(data, list, OB_SUCCESS == ret) { + if (0 != pos) { + if (pos + 1 < len) { + buf[pos++] = ','; + } else { + ret = OB_BUF_NOT_ENOUGH; + COMMON_LOG(WARN, "buffer not enough", KR(ret), K(pos), K(len)); + } + } + if (FAILEDx(data->to_display_str(buf, len, pos))) { + COMMON_LOG(WARN, "to display str failed", KR(ret), KPC(data), K(len), K(pos)); + } + } + } + + if (OB_SUCC(ret)) { + str.assign_ptr(buf, static_cast(pos)); + } + } + return ret; +} + +/* + * Parse comma-connected ObString into a list of objects + * + * Pair function with list_to_display_str(...) + * + * For more information, please refer to list_to_display_str(..) + * + * @param [in] str: comma-connected string + * @param [out] list: returned list + * @return OB_SUCCESS if success, otherwise failed + */ +template +int display_str_to_list(const common::ObString &str, common::ObIArray &list) +{ + int ret = OB_SUCCESS; + list.reset(); + common::ObArenaAllocator allocator; + ObString tmp_str; + if (OB_UNLIKELY(str.empty())) { + // do nothing + } else if (OB_FAIL(ob_write_string(allocator, str, tmp_str, true/*c_style*/))) { + COMMON_LOG(WARN, "fail to write string", KR(ret), K(str)); + } else { + char *data_str = NULL; + char *save_ptr = NULL; + while (OB_SUCC(ret)) { + Type data; + data_str = strtok_r((NULL == data_str ? tmp_str.ptr() : NULL), ",", &save_ptr); + if (NULL != data_str) { + if (OB_FAIL(data.parse_from_display_str(ObString::make_string(data_str)))) { + COMMON_LOG(WARN, "fail to parse from display str", KR(ret), K(data_str), K(data)); + } else if (OB_FAIL(list.push_back(data))) { + COMMON_LOG(WARN, "fail to push back into list", KR(ret), K(data), K(list)); + } + } else { + break; + } + } // while + } + if (OB_SUCC(ret) && !str.empty() && list.empty()) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "invalid str", KR(ret), K(str)); + } + return ret; +} + +// A type which can convert to/from display string +// +// If you want to use ObDisplayList, you can define a Type derived from ObDisplayType, then, define ObDisplayList +// +// If you does not want to inherit ObDisplayType, you must implement all interfaces just like ObDisplayType +class ObDisplayType +{ +public: + // max length of converted display string + virtual int64_t max_display_str_len() const = 0; + + // to display string which can not include commas ',' + virtual int to_display_str(char *buf, const int64_t len, int64_t &pos) const = 0; + + // parse from display string + virtual int parse_from_display_str(const common::ObString &str) = 0; +}; + + +// ObDisplayList: a list which can convert to string or parse from string +template, typename ItemEncode = NotImplementItemEncode > +class ObDisplayList : public common::ObArrayImpl +{ +public: + // use ObArrayImpl constructors + using common::ObArrayImpl::ObArrayImpl; + + // to display string + // See list_to_display_str(..) for more information + int to_display_str(ObIAllocator &allocator, ObString &str) const + { + return list_to_display_str(allocator, *this, str); + } + + // parse from display string + // See display_str_to_list(...) for more information + int parse_from_display_str(const common::ObString &str) + { + return display_str_to_list(str, *this); + } +}; + +} // end namespace share +} // end namespace oceanbase + +#endif // OCEANBASE_SHARE_OB_DISPLAY_LIST diff --git a/src/share/ob_errno.cpp b/src/share/ob_errno.cpp old mode 100644 new mode 100755 index 9e47b3743..da91e4b5e --- a/src/share/ob_errno.cpp +++ b/src/share/ob_errno.cpp @@ -19533,6 +19533,18 @@ static const _error _error_OB_LS_NEED_REBUILD = { .oracle_str_error = "ORA-00600: internal error code, arguments: -7117, ls need rebuild", .oracle_str_user_error = "ORA-00600: internal error code, arguments: -7117, ls need rebuild" }; +static const _error _error_OB_OBSOLETE_CLOG_NEED_SKIP = { + .error_name = "OB_OBSOLETE_CLOG_NEED_SKIP", + .error_cause = "Internal Error", + .error_solution = "Contact OceanBase Support", + .mysql_errno = -1, + .sqlstate = "HY000", + .str_error = "obsolete clog need skip", + .str_user_error = "obsolete clog need skip", + .oracle_errno = 600, + .oracle_str_error = "ORA-00600: internal error code, arguments: -7118, obsolete clog need skip", + .oracle_str_user_error = "ORA-00600: internal error code, arguments: -7118, obsolete clog need skip" +}; static const _error _error_OB_ERR_GIS_DIFFERENT_SRIDS = { .error_name = "OB_ERR_GIS_DIFFERENT_SRIDS", .error_cause = "Internal Error", @@ -24981,6 +24993,18 @@ static const _error _error_OB_ERR_VIEW_SELECT_CONTAIN_QUESTIONMARK = { .oracle_str_error = "ORA-00600: internal error code, arguments: -9748, View's SELECT contains a variable or parameter", .oracle_str_user_error = "ORA-00600: internal error code, arguments: -9748, View's SELECT contains a variable or parameter" }; +static const _error _error_OB_ERR_OBJECT_NOT_EXIST = { + .error_name = "OB_ERR_OBJECT_NOT_EXIST", + .error_cause = "Internal Error", + .error_solution = "Contact OceanBase Support", + .mysql_errno = -1, + .sqlstate = "HY000", + .str_error = "object does not exist", + .str_user_error = "object does not exist", + .oracle_errno = 6564, + .oracle_str_error = "ORA-06564: object does not exist", + .oracle_str_user_error = "ORA-06564: object does not exist" +}; static const _error _error_OB_SP_RAISE_APPLICATION_ERROR = { .error_name = "OB_SP_RAISE_APPLICATION_ERROR", .error_cause = "Internal Error", @@ -26698,6 +26722,7 @@ struct ObStrErrorInit _errors[-OB_TRANSFER_SRC_LS_NOT_EXIST] = &_error_OB_TRANSFER_SRC_LS_NOT_EXIST; _errors[-OB_TRANSFER_SRC_TABLET_NOT_EXIST] = &_error_OB_TRANSFER_SRC_TABLET_NOT_EXIST; _errors[-OB_LS_NEED_REBUILD] = &_error_OB_LS_NEED_REBUILD; + _errors[-OB_OBSOLETE_CLOG_NEED_SKIP] = &_error_OB_OBSOLETE_CLOG_NEED_SKIP; _errors[-OB_ERR_GIS_DIFFERENT_SRIDS] = &_error_OB_ERR_GIS_DIFFERENT_SRIDS; _errors[-OB_ERR_GIS_UNSUPPORTED_ARGUMENT] = &_error_OB_ERR_GIS_UNSUPPORTED_ARGUMENT; _errors[-OB_ERR_GIS_UNKNOWN_ERROR] = &_error_OB_ERR_GIS_UNKNOWN_ERROR; @@ -27152,6 +27177,7 @@ struct ObStrErrorInit _errors[-OB_ERR_MULTI_RECORD] = &_error_OB_ERR_MULTI_RECORD; _errors[-OB_ERR_MALFORMED_PS_PACKET] = &_error_OB_ERR_MALFORMED_PS_PACKET; _errors[-OB_ERR_VIEW_SELECT_CONTAIN_QUESTIONMARK] = &_error_OB_ERR_VIEW_SELECT_CONTAIN_QUESTIONMARK; + _errors[-OB_ERR_OBJECT_NOT_EXIST] = &_error_OB_ERR_OBJECT_NOT_EXIST; _errors[-OB_SP_RAISE_APPLICATION_ERROR] = &_error_OB_SP_RAISE_APPLICATION_ERROR; _errors[-OB_SP_RAISE_APPLICATION_ERROR_NUM] = &_error_OB_SP_RAISE_APPLICATION_ERROR_NUM; _errors[-OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN] = &_error_OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN; @@ -27193,7 +27219,7 @@ namespace oceanbase { namespace common { -int g_all_ob_errnos[2084] = {0, -4000, -4001, -4002, -4003, -4004, -4005, -4006, -4007, -4008, -4009, -4010, -4011, -4012, -4013, -4014, -4015, -4016, -4017, -4018, -4019, -4020, -4021, -4022, -4023, -4024, -4025, -4026, -4027, -4028, -4029, -4030, -4031, -4032, -4033, -4034, -4035, -4036, -4037, -4038, -4039, -4041, -4042, -4043, -4044, -4045, -4046, -4047, -4048, -4049, -4050, -4051, -4052, -4053, -4054, -4055, -4057, -4058, -4060, -4061, -4062, -4063, -4064, -4065, -4066, -4067, -4068, -4070, -4071, -4072, -4073, -4074, -4075, -4076, -4077, -4078, -4080, -4081, -4084, -4085, -4090, -4097, -4098, -4099, -4100, -4101, -4102, -4103, -4104, -4105, -4106, -4107, -4108, -4109, -4110, -4111, -4112, -4113, -4114, -4115, -4116, -4117, -4118, -4119, -4120, -4121, -4122, -4123, -4124, -4125, -4126, -4127, -4128, -4133, -4138, -4139, -4142, -4143, -4144, -4146, -4147, -4149, -4150, -4151, -4152, -4153, -4154, -4155, -4156, -4157, -4158, -4159, -4160, -4161, -4162, -4163, -4164, -4165, -4166, -4167, -4168, -4169, -4170, -4171, -4172, -4173, -4174, -4175, -4176, -4177, -4178, -4179, -4180, -4181, -4182, -4183, -4184, -4185, -4186, -4187, -4188, -4189, -4190, -4191, -4192, -4200, -4201, -4204, -4205, -4206, -4207, -4208, -4209, -4210, -4211, -4212, -4213, -4214, -4215, -4216, -4217, -4218, -4219, -4220, -4221, -4222, -4223, -4224, -4225, -4226, -4227, -4228, -4229, -4230, -4231, -4232, -4233, -4234, -4235, -4236, -4237, -4238, -4239, -4240, -4241, -4242, -4243, -4244, -4245, -4246, -4247, -4248, -4249, -4250, -4251, -4252, -4253, -4254, -4255, -4256, -4257, -4258, -4260, -4261, -4262, -4263, -4264, -4265, -4266, -4267, -4268, -4269, -4270, -4271, -4273, -4274, -4275, -4276, -4277, -4278, -4279, -4280, -4281, -4282, -4283, -4284, -4285, -4286, -4287, -4288, -4289, -4290, -4291, -4292, -4293, -4294, -4295, -4296, -4297, -4298, -4299, -4300, -4301, -4302, -4303, -4304, -4305, -4306, -4307, -4308, -4309, -4310, -4311, -4312, -4313, -4314, -4315, -4316, -4317, -4318, -4319, -4320, -4321, -4322, -4323, -4324, -4325, -4326, -4327, -4328, -4329, -4330, -4331, -4332, -4333, -4334, -4335, -4336, -4337, -4338, -4339, -4340, -4341, -4342, -4343, -4344, -4345, -4346, -4347, -4348, -4349, -4350, -4351, -4352, -4353, -4354, -4355, -4356, -4357, -4358, -4359, -4360, -4361, -4362, -4363, -4364, -4365, -4366, -4367, -4368, -4369, -4370, -4371, -4372, -4373, -4374, -4375, -4376, -4377, -4378, -4379, -4380, -4381, -4382, -4383, -4385, -4386, -4387, -4388, -4389, -4390, -4391, -4392, -4393, -4394, -4395, -4396, -4397, -4398, -4399, -4505, -4507, -4510, -4512, -4515, -4517, -4518, -4519, -4523, -4524, -4525, -4526, -4527, -4528, -4529, -4530, -4531, -4532, -4533, -4537, -4538, -4539, -4540, -4541, -4542, -4543, -4544, -4545, -4546, -4547, -4548, -4549, -4550, -4551, -4552, -4553, -4554, -4600, -4601, -4602, -4603, -4604, -4605, -4606, -4607, -4608, -4609, -4610, -4611, -4613, -4614, -4615, -4620, -4621, -4622, -4623, -4624, -4625, -4626, -4628, -4629, -4630, -4631, -4632, -4633, -4634, -4636, -4637, -4638, -4639, -4640, -4641, -4642, -4643, -4644, -4645, -4646, -4647, -4648, -4649, -4650, -4651, -4652, -4653, -4654, -4655, -4656, -4657, -4658, -4659, -4660, -4661, -4662, -4663, -4664, -4665, -4666, -4667, -4668, -4669, -4670, -4671, -4672, -4673, -4674, -4675, -4676, -4677, -4678, -4679, -4680, -4681, -4682, -4683, -4684, -4685, -4686, -4687, -4688, -4689, -4690, -4691, -4692, -4693, -4694, -4695, -4696, -4697, -4698, -4699, -4700, -4701, -4702, -4703, -4704, -4705, -4706, -4707, -4708, -4709, -4710, -4711, -4712, -4713, -4714, -4715, -4716, -4717, -4718, -4719, -4720, -4721, -4722, -4723, -4724, -4725, -4726, -4727, -4728, -4729, -4730, -4731, -4732, -4733, -4734, -4735, -4736, -4737, -4738, -4739, -4740, -4741, -4742, -4743, -4744, -4745, -4746, -4747, -4748, -4749, -4750, -4751, -4752, -4753, -4754, -4755, -4756, -4757, -4758, -4759, -4760, -4761, -4762, -5000, -5001, -5002, -5003, -5006, -5007, -5008, -5010, -5011, -5012, -5014, -5015, -5016, -5017, -5018, -5019, -5020, -5022, -5023, -5024, -5025, -5026, -5027, -5028, -5029, -5030, -5031, -5032, -5034, -5035, -5036, -5037, -5038, -5039, -5040, -5041, -5042, -5043, -5044, -5046, -5047, -5050, -5051, -5052, -5053, -5054, -5055, -5056, -5057, -5058, -5059, -5061, -5063, -5064, -5065, -5066, -5067, -5068, -5069, -5070, -5071, -5072, -5073, -5074, -5080, -5081, -5083, -5084, -5085, -5086, -5087, -5088, -5089, -5090, -5091, -5092, -5093, -5094, -5095, -5096, -5097, -5098, -5099, -5100, -5101, -5102, -5103, -5104, -5105, -5106, -5107, -5108, -5109, -5110, -5111, -5112, -5113, -5114, -5115, -5116, -5117, -5118, -5119, -5120, -5121, -5122, -5123, -5124, -5125, -5130, -5131, -5133, -5134, -5135, -5136, -5137, -5138, -5139, -5140, -5142, -5143, -5144, -5145, -5146, -5147, -5148, -5149, -5150, -5151, -5153, -5154, -5155, -5156, -5157, -5158, -5159, -5160, -5161, -5162, -5163, -5164, -5165, -5166, -5167, -5168, -5169, -5170, -5171, -5172, -5173, -5174, -5175, -5176, -5177, -5178, -5179, -5180, -5181, -5182, -5183, -5184, -5185, -5187, -5188, -5189, -5190, -5191, -5192, -5193, -5194, -5195, -5196, -5197, -5198, -5199, -5200, -5201, -5202, -5203, -5204, -5205, -5206, -5207, -5208, -5209, -5210, -5211, -5212, -5213, -5214, -5215, -5216, -5217, -5218, -5219, -5220, -5221, -5222, -5223, -5224, -5225, -5226, -5227, -5228, -5229, -5230, -5231, -5233, -5234, -5235, -5236, -5237, -5238, -5239, -5240, -5241, -5242, -5243, -5244, -5245, -5246, -5247, -5248, -5249, -5250, -5251, -5252, -5253, -5254, -5255, -5256, -5257, -5258, -5259, -5260, -5261, -5262, -5263, -5264, -5265, -5266, -5267, -5268, -5269, -5270, -5271, -5272, -5273, -5274, -5275, -5276, -5277, -5278, -5279, -5280, -5281, -5282, -5283, -5284, -5285, -5286, -5287, -5288, -5289, -5290, -5291, -5292, -5293, -5294, -5295, -5296, -5297, -5298, -5299, -5300, -5301, -5302, -5303, -5304, -5305, -5306, -5307, -5308, -5309, -5310, -5311, -5312, -5313, -5314, -5315, -5316, -5317, -5318, -5319, -5320, -5321, -5322, -5323, -5324, -5325, -5326, -5327, -5328, -5329, -5330, -5331, -5332, -5333, -5334, -5335, -5336, -5337, -5338, -5339, -5340, -5341, -5342, -5343, -5344, -5345, -5346, -5347, -5348, -5349, -5350, -5351, -5352, -5353, -5354, -5355, -5356, -5357, -5358, -5359, -5360, -5361, -5362, -5363, -5364, -5365, -5366, -5367, -5368, -5369, -5370, -5371, -5372, -5373, -5374, -5375, -5376, -5377, -5378, -5379, -5380, -5381, -5382, -5383, -5384, -5385, -5400, -5401, -5402, -5403, -5404, -5405, -5406, -5407, -5408, -5409, -5410, -5411, -5412, -5413, -5414, -5415, -5416, -5417, -5418, -5419, -5420, -5421, -5422, -5423, -5424, -5425, -5426, -5427, -5428, -5429, -5430, -5431, -5432, -5433, -5434, -5435, -5436, -5437, -5438, -5439, -5440, -5441, -5442, -5443, -5444, -5445, -5446, -5447, -5448, -5449, -5450, -5451, -5452, -5453, -5454, -5455, -5456, -5457, -5458, -5459, -5460, -5461, -5462, -5463, -5464, -5465, -5466, -5467, -5468, -5469, -5470, -5471, -5472, -5473, -5474, -5475, -5476, -5477, -5478, -5479, -5480, -5481, -5482, -5483, -5484, -5485, -5486, -5487, -5488, -5489, -5490, -5491, -5492, -5493, -5494, -5495, -5496, -5497, -5498, -5499, -5541, -5542, -5543, -5544, -5545, -5546, -5547, -5548, -5549, -5550, -5551, -5552, -5553, -5554, -5555, -5556, -5557, -5558, -5559, -5560, -5561, -5562, -5563, -5564, -5565, -5566, -5567, -5568, -5569, -5570, -5571, -5572, -5573, -5574, -5575, -5576, -5577, -5578, -5579, -5580, -5581, -5582, -5583, -5584, -5585, -5586, -5587, -5588, -5589, -5590, -5591, -5592, -5593, -5594, -5595, -5596, -5597, -5598, -5599, -5600, -5601, -5602, -5603, -5604, -5605, -5607, -5608, -5609, -5610, -5611, -5612, -5613, -5614, -5615, -5616, -5617, -5618, -5619, -5620, -5621, -5622, -5623, -5624, -5625, -5626, -5627, -5628, -5629, -5630, -5631, -5632, -5633, -5634, -5635, -5636, -5637, -5638, -5639, -5640, -5641, -5642, -5643, -5644, -5645, -5646, -5647, -5648, -5649, -5650, -5651, -5652, -5653, -5654, -5655, -5656, -5657, -5658, -5659, -5660, -5661, -5662, -5663, -5664, -5665, -5666, -5667, -5668, -5671, -5672, -5673, -5674, -5675, -5676, -5677, -5678, -5679, -5680, -5681, -5682, -5683, -5684, -5685, -5686, -5687, -5688, -5689, -5690, -5691, -5692, -5693, -5694, -5695, -5696, -5697, -5698, -5699, -5700, -5701, -5702, -5703, -5704, -5705, -5706, -5707, -5708, -5709, -5710, -5711, -5712, -5713, -5714, -5715, -5716, -5717, -5718, -5719, -5720, -5721, -5722, -5723, -5724, -5725, -5726, -5727, -5728, -5729, -5730, -5731, -5732, -5733, -5734, -5735, -5736, -5737, -5738, -5739, -5740, -5741, -5742, -5743, -5744, -5745, -5746, -5747, -5748, -5749, -5750, -5751, -5752, -5753, -5754, -5755, -5756, -5757, -5758, -5759, -5760, -5761, -5762, -5763, -5764, -5765, -5766, -5768, -5769, -5770, -5771, -5772, -5773, -5774, -5777, -5778, -5779, -5780, -5781, -5785, -5786, -5787, -5788, -5789, -5790, -5791, -5792, -5793, -5794, -5795, -5796, -5797, -5798, -5799, -5800, -5801, -5802, -5803, -5804, -5805, -5806, -5807, -5808, -5809, -5810, -5811, -5812, -5813, -5814, -5815, -5816, -5817, -5818, -5819, -5820, -5821, -5822, -5823, -5824, -5825, -5826, -5827, -5828, -5829, -5830, -5831, -5832, -5833, -5834, -5835, -5836, -5837, -5838, -5839, -5840, -5841, -5842, -5843, -5844, -5845, -5846, -5847, -5848, -5849, -5850, -5851, -5852, -5853, -5854, -5855, -5856, -5857, -5858, -5859, -5860, -5861, -5862, -5863, -5864, -5865, -5866, -5867, -5868, -5869, -5870, -5871, -5872, -5873, -5874, -5875, -5876, -5877, -5878, -5879, -5880, -5881, -5882, -5883, -5884, -5885, -5886, -5887, -5888, -5889, -5890, -5891, -5892, -5893, -5894, -5895, -5896, -5897, -5898, -5899, -5900, -5901, -5902, -5903, -5904, -5905, -5906, -5907, -5908, -5909, -5910, -5911, -5912, -5913, -5914, -5915, -5916, -5917, -5918, -5919, -5920, -5921, -5922, -5923, -5924, -5925, -5926, -5927, -5928, -5929, -5930, -5931, -5932, -5933, -5934, -5935, -5936, -5937, -5938, -5939, -5940, -5941, -5942, -5943, -5944, -5945, -5946, -5947, -5948, -5949, -5950, -5951, -5952, -5953, -5954, -5955, -5956, -5957, -5958, -5959, -5960, -5961, -5962, -5963, -5964, -5965, -5966, -5967, -5968, -5969, -5970, -5971, -5972, -5973, -5974, -5975, -5976, -5977, -5978, -5979, -5980, -5981, -5982, -5983, -5984, -5985, -5986, -5987, -5988, -5989, -5990, -5991, -5992, -5993, -5994, -5995, -5996, -5997, -5998, -5999, -6000, -6001, -6002, -6003, -6004, -6005, -6006, -6201, -6202, -6203, -6204, -6205, -6206, -6207, -6208, -6209, -6210, -6211, -6212, -6213, -6214, -6215, -6219, -6220, -6221, -6222, -6223, -6224, -6225, -6226, -6227, -6228, -6229, -6230, -6231, -6232, -6233, -6234, -6235, -6236, -6237, -6238, -6239, -6240, -6241, -6242, -6243, -6244, -6245, -6246, -6247, -6248, -6249, -6250, -6251, -6252, -6253, -6254, -6255, -6256, -6257, -6258, -6259, -6260, -6261, -6262, -6263, -6264, -6265, -6266, -6267, -6268, -6269, -6270, -6271, -6272, -6273, -6274, -6275, -6276, -6277, -6278, -6279, -6280, -6281, -6282, -6283, -6301, -6302, -6303, -6304, -6305, -6306, -6307, -6308, -6309, -6310, -6311, -6312, -6313, -6314, -6315, -6316, -6317, -6318, -6319, -6320, -6321, -6322, -6323, -6324, -7000, -7001, -7002, -7003, -7004, -7005, -7006, -7007, -7010, -7011, -7012, -7013, -7014, -7015, -7021, -7022, -7024, -7025, -7026, -7027, -7029, -7030, -7031, -7032, -7033, -7034, -7035, -7036, -7037, -7038, -7039, -7040, -7041, -7100, -7101, -7102, -7103, -7104, -7105, -7106, -7107, -7108, -7109, -7110, -7111, -7112, -7113, -7114, -7115, -7116, -7117, -7201, -7202, -7203, -7204, -7205, -7206, -7207, -7208, -7209, -7210, -7211, -7212, -7213, -7214, -7215, -7216, -7217, -7218, -7219, -7220, -7221, -7222, -7223, -7224, -7225, -7226, -7227, -7228, -7229, -7230, -7231, -7232, -7233, -7234, -7235, -7236, -7237, -7238, -7239, -7240, -7241, -7242, -7243, -7244, -7246, -7247, -7248, -7249, -7250, -7251, -7252, -7253, -7254, -7255, -7256, -7257, -7258, -7259, -7260, -7261, -7262, -7263, -7264, -7265, -7266, -7267, -7268, -7269, -7270, -7271, -7272, -7273, -7274, -7275, -7276, -7277, -7278, -7279, -7280, -7281, -7282, -7283, -7284, -7285, -7286, -7287, -7288, -7402, -7403, -7404, -7405, -7406, -7407, -7408, -7409, -7410, -7411, -7412, -7413, -7414, -7415, -7416, -7417, -7418, -7419, -8001, -8002, -8003, -8004, -8005, -9001, -9002, -9003, -9004, -9005, -9006, -9007, -9008, -9009, -9010, -9011, -9012, -9013, -9014, -9015, -9016, -9017, -9018, -9019, -9020, -9022, -9023, -9024, -9025, -9026, -9027, -9028, -9029, -9030, -9031, -9032, -9033, -9034, -9035, -9036, -9037, -9038, -9039, -9040, -9041, -9042, -9043, -9044, -9045, -9046, -9047, -9048, -9049, -9050, -9051, -9052, -9053, -9054, -9057, -9058, -9059, -9060, -9061, -9062, -9063, -9064, -9065, -9069, -9070, -9071, -9072, -9073, -9074, -9075, -9076, -9077, -9078, -9079, -9080, -9081, -9082, -9083, -9084, -9085, -9086, -9087, -9088, -9089, -9090, -9091, -9092, -9093, -9094, -9095, -9100, -9101, -9102, -9103, -9200, -9201, -9202, -9501, -9502, -9503, -9504, -9505, -9506, -9507, -9508, -9509, -9510, -9512, -9513, -9514, -9515, -9516, -9518, -9519, -9520, -9521, -9522, -9523, -9524, -9525, -9526, -9527, -9528, -9529, -9530, -9531, -9532, -9533, -9534, -9535, -9536, -9537, -9538, -9539, -9540, -9541, -9542, -9543, -9544, -9545, -9546, -9547, -9548, -9549, -9550, -9551, -9552, -9553, -9554, -9555, -9556, -9557, -9558, -9559, -9560, -9561, -9562, -9563, -9564, -9565, -9566, -9567, -9568, -9569, -9570, -9571, -9572, -9573, -9574, -9575, -9576, -9577, -9578, -9579, -9580, -9581, -9582, -9583, -9584, -9585, -9586, -9587, -9588, -9589, -9590, -9591, -9592, -9593, -9594, -9595, -9596, -9597, -9598, -9599, -9600, -9601, -9602, -9603, -9604, -9605, -9606, -9607, -9608, -9609, -9610, -9611, -9612, -9613, -9614, -9615, -9616, -9617, -9618, -9619, -9620, -9621, -9622, -9623, -9624, -9625, -9626, -9627, -9628, -9629, -9630, -9631, -9632, -9633, -9634, -9635, -9636, -9637, -9638, -9639, -9640, -9641, -9642, -9643, -9644, -9645, -9646, -9647, -9648, -9649, -9650, -9651, -9652, -9653, -9654, -9655, -9656, -9657, -9658, -9659, -9660, -9661, -9662, -9663, -9664, -9665, -9666, -9667, -9668, -9669, -9670, -9671, -9672, -9673, -9674, -9675, -9676, -9677, -9678, -9679, -9680, -9681, -9682, -9683, -9684, -9685, -9686, -9687, -9688, -9689, -9690, -9691, -9692, -9693, -9694, -9695, -9696, -9697, -9698, -9699, -9700, -9701, -9702, -9703, -9704, -9705, -9706, -9707, -9708, -9709, -9710, -9711, -9712, -9713, -9714, -9715, -9716, -9717, -9718, -9719, -9720, -9721, -9722, -9723, -9724, -9725, -9726, -9727, -9728, -9729, -9730, -9731, -9732, -9733, -9734, -9735, -9736, -9737, -9738, -9739, -9740, -9741, -9742, -9743, -9744, -9745, -9746, -9747, -9748, -20000, -21000, -22998, -30926, -32491, -38104, -38105}; +int g_all_ob_errnos[2088] = {0, -4000, -4001, -4002, -4003, -4004, -4005, -4006, -4007, -4008, -4009, -4010, -4011, -4012, -4013, -4014, -4015, -4016, -4017, -4018, -4019, -4020, -4021, -4022, -4023, -4024, -4025, -4026, -4027, -4028, -4029, -4030, -4031, -4032, -4033, -4034, -4035, -4036, -4037, -4038, -4039, -4041, -4042, -4043, -4044, -4045, -4046, -4047, -4048, -4049, -4050, -4051, -4052, -4053, -4054, -4055, -4057, -4058, -4060, -4061, -4062, -4063, -4064, -4065, -4066, -4067, -4068, -4070, -4071, -4072, -4073, -4074, -4075, -4076, -4077, -4078, -4080, -4081, -4084, -4085, -4090, -4097, -4098, -4099, -4100, -4101, -4102, -4103, -4104, -4105, -4106, -4107, -4108, -4109, -4110, -4111, -4112, -4113, -4114, -4115, -4116, -4117, -4118, -4119, -4120, -4121, -4122, -4123, -4124, -4125, -4126, -4127, -4128, -4133, -4138, -4139, -4142, -4143, -4144, -4146, -4147, -4149, -4150, -4151, -4152, -4153, -4154, -4155, -4156, -4157, -4158, -4159, -4160, -4161, -4162, -4163, -4164, -4165, -4166, -4167, -4168, -4169, -4170, -4171, -4172, -4173, -4174, -4175, -4176, -4177, -4178, -4179, -4180, -4181, -4182, -4183, -4184, -4185, -4186, -4187, -4188, -4189, -4190, -4191, -4192, -4200, -4201, -4204, -4205, -4206, -4207, -4208, -4209, -4210, -4211, -4212, -4213, -4214, -4215, -4216, -4217, -4218, -4219, -4220, -4221, -4222, -4223, -4224, -4225, -4226, -4227, -4228, -4229, -4230, -4231, -4232, -4233, -4234, -4235, -4236, -4237, -4238, -4239, -4240, -4241, -4242, -4243, -4244, -4245, -4246, -4247, -4248, -4249, -4250, -4251, -4252, -4253, -4254, -4255, -4256, -4257, -4258, -4260, -4261, -4262, -4263, -4264, -4265, -4266, -4267, -4268, -4269, -4270, -4271, -4273, -4274, -4275, -4276, -4277, -4278, -4279, -4280, -4281, -4282, -4283, -4284, -4285, -4286, -4287, -4288, -4289, -4290, -4291, -4292, -4293, -4294, -4295, -4296, -4297, -4298, -4299, -4300, -4301, -4302, -4303, -4304, -4305, -4306, -4307, -4308, -4309, -4310, -4311, -4312, -4313, -4314, -4315, -4316, -4317, -4318, -4319, -4320, -4321, -4322, -4323, -4324, -4325, -4326, -4327, -4328, -4329, -4330, -4331, -4332, -4333, -4334, -4335, -4336, -4337, -4338, -4339, -4340, -4341, -4342, -4343, -4344, -4345, -4346, -4347, -4348, -4349, -4350, -4351, -4352, -4353, -4354, -4355, -4356, -4357, -4358, -4359, -4360, -4361, -4362, -4363, -4364, -4365, -4366, -4367, -4368, -4369, -4370, -4371, -4372, -4373, -4374, -4375, -4376, -4377, -4378, -4379, -4380, -4381, -4382, -4383, -4385, -4386, -4387, -4388, -4389, -4390, -4391, -4392, -4393, -4394, -4395, -4396, -4397, -4398, -4399, -4505, -4507, -4510, -4512, -4515, -4517, -4518, -4519, -4523, -4524, -4525, -4526, -4527, -4528, -4529, -4530, -4531, -4532, -4533, -4537, -4538, -4539, -4540, -4541, -4542, -4543, -4544, -4545, -4546, -4547, -4548, -4549, -4550, -4551, -4552, -4553, -4554, -4600, -4601, -4602, -4603, -4604, -4605, -4606, -4607, -4608, -4609, -4610, -4611, -4613, -4614, -4615, -4620, -4621, -4622, -4623, -4624, -4625, -4626, -4628, -4629, -4630, -4631, -4632, -4633, -4634, -4636, -4637, -4638, -4639, -4640, -4641, -4642, -4643, -4644, -4645, -4646, -4647, -4648, -4649, -4650, -4651, -4652, -4653, -4654, -4655, -4656, -4657, -4658, -4659, -4660, -4661, -4662, -4663, -4664, -4665, -4666, -4667, -4668, -4669, -4670, -4671, -4672, -4673, -4674, -4675, -4676, -4677, -4678, -4679, -4680, -4681, -4682, -4683, -4684, -4685, -4686, -4687, -4688, -4689, -4690, -4691, -4692, -4693, -4694, -4695, -4696, -4697, -4698, -4699, -4700, -4701, -4702, -4703, -4704, -4705, -4706, -4707, -4708, -4709, -4710, -4711, -4712, -4713, -4714, -4715, -4716, -4717, -4718, -4719, -4720, -4721, -4722, -4723, -4724, -4725, -4726, -4727, -4728, -4729, -4730, -4731, -4732, -4733, -4734, -4735, -4736, -4737, -4738, -4739, -4740, -4741, -4742, -4743, -4744, -4745, -4746, -4747, -4748, -4749, -4750, -4751, -4752, -4753, -4754, -4755, -4756, -4757, -4758, -4759, -4760, -4761, -4762, -5000, -5001, -5002, -5003, -5006, -5007, -5008, -5010, -5011, -5012, -5014, -5015, -5016, -5017, -5018, -5019, -5020, -5022, -5023, -5024, -5025, -5026, -5027, -5028, -5029, -5030, -5031, -5032, -5034, -5035, -5036, -5037, -5038, -5039, -5040, -5041, -5042, -5043, -5044, -5046, -5047, -5050, -5051, -5052, -5053, -5054, -5055, -5056, -5057, -5058, -5059, -5061, -5063, -5064, -5065, -5066, -5067, -5068, -5069, -5070, -5071, -5072, -5073, -5074, -5080, -5081, -5083, -5084, -5085, -5086, -5087, -5088, -5089, -5090, -5091, -5092, -5093, -5094, -5095, -5096, -5097, -5098, -5099, -5100, -5101, -5102, -5103, -5104, -5105, -5106, -5107, -5108, -5109, -5110, -5111, -5112, -5113, -5114, -5115, -5116, -5117, -5118, -5119, -5120, -5121, -5122, -5123, -5124, -5125, -5130, -5131, -5133, -5134, -5135, -5136, -5137, -5138, -5139, -5140, -5142, -5143, -5144, -5145, -5146, -5147, -5148, -5149, -5150, -5151, -5153, -5154, -5155, -5156, -5157, -5158, -5159, -5160, -5161, -5162, -5163, -5164, -5165, -5166, -5167, -5168, -5169, -5170, -5171, -5172, -5173, -5174, -5175, -5176, -5177, -5178, -5179, -5180, -5181, -5182, -5183, -5184, -5185, -5187, -5188, -5189, -5190, -5191, -5192, -5193, -5194, -5195, -5196, -5197, -5198, -5199, -5200, -5201, -5202, -5203, -5204, -5205, -5206, -5207, -5208, -5209, -5210, -5211, -5212, -5213, -5214, -5215, -5216, -5217, -5218, -5219, -5220, -5221, -5222, -5223, -5224, -5225, -5226, -5227, -5228, -5229, -5230, -5231, -5233, -5234, -5235, -5236, -5237, -5238, -5239, -5240, -5241, -5242, -5243, -5244, -5245, -5246, -5247, -5248, -5249, -5250, -5251, -5252, -5253, -5254, -5255, -5256, -5257, -5258, -5259, -5260, -5261, -5262, -5263, -5264, -5265, -5266, -5267, -5268, -5269, -5270, -5271, -5272, -5273, -5274, -5275, -5276, -5277, -5278, -5279, -5280, -5281, -5282, -5283, -5284, -5285, -5286, -5287, -5288, -5289, -5290, -5291, -5292, -5293, -5294, -5295, -5296, -5297, -5298, -5299, -5300, -5301, -5302, -5303, -5304, -5305, -5306, -5307, -5308, -5309, -5310, -5311, -5312, -5313, -5314, -5315, -5316, -5317, -5318, -5319, -5320, -5321, -5322, -5323, -5324, -5325, -5326, -5327, -5328, -5329, -5330, -5331, -5332, -5333, -5334, -5335, -5336, -5337, -5338, -5339, -5340, -5341, -5342, -5343, -5344, -5345, -5346, -5347, -5348, -5349, -5350, -5351, -5352, -5353, -5354, -5355, -5356, -5357, -5358, -5359, -5360, -5361, -5362, -5363, -5364, -5365, -5366, -5367, -5368, -5369, -5370, -5371, -5372, -5373, -5374, -5375, -5376, -5377, -5378, -5379, -5380, -5381, -5382, -5383, -5384, -5385, -5400, -5401, -5402, -5403, -5404, -5405, -5406, -5407, -5408, -5409, -5410, -5411, -5412, -5413, -5414, -5415, -5416, -5417, -5418, -5419, -5420, -5421, -5422, -5423, -5424, -5425, -5426, -5427, -5428, -5429, -5430, -5431, -5432, -5433, -5434, -5435, -5436, -5437, -5438, -5439, -5440, -5441, -5442, -5443, -5444, -5445, -5446, -5447, -5448, -5449, -5450, -5451, -5452, -5453, -5454, -5455, -5456, -5457, -5458, -5459, -5460, -5461, -5462, -5463, -5464, -5465, -5466, -5467, -5468, -5469, -5470, -5471, -5472, -5473, -5474, -5475, -5476, -5477, -5478, -5479, -5480, -5481, -5482, -5483, -5484, -5485, -5486, -5487, -5488, -5489, -5490, -5491, -5492, -5493, -5494, -5495, -5496, -5497, -5498, -5499, -5541, -5542, -5543, -5544, -5545, -5546, -5547, -5548, -5549, -5550, -5551, -5552, -5553, -5554, -5555, -5556, -5557, -5558, -5559, -5560, -5561, -5562, -5563, -5564, -5565, -5566, -5567, -5568, -5569, -5570, -5571, -5572, -5573, -5574, -5575, -5576, -5577, -5578, -5579, -5580, -5581, -5582, -5583, -5584, -5585, -5586, -5587, -5588, -5589, -5590, -5591, -5592, -5593, -5594, -5595, -5596, -5597, -5598, -5599, -5600, -5601, -5602, -5603, -5604, -5605, -5607, -5608, -5609, -5610, -5611, -5612, -5613, -5614, -5615, -5616, -5617, -5618, -5619, -5620, -5621, -5622, -5623, -5624, -5625, -5626, -5627, -5628, -5629, -5630, -5631, -5632, -5633, -5634, -5635, -5636, -5637, -5638, -5639, -5640, -5641, -5642, -5643, -5644, -5645, -5646, -5647, -5648, -5649, -5650, -5651, -5652, -5653, -5654, -5655, -5656, -5657, -5658, -5659, -5660, -5661, -5662, -5663, -5664, -5665, -5666, -5667, -5668, -5671, -5672, -5673, -5674, -5675, -5676, -5677, -5678, -5679, -5680, -5681, -5682, -5683, -5684, -5685, -5686, -5687, -5688, -5689, -5690, -5691, -5692, -5693, -5694, -5695, -5696, -5697, -5698, -5699, -5700, -5701, -5702, -5703, -5704, -5705, -5706, -5707, -5708, -5709, -5710, -5711, -5712, -5713, -5714, -5715, -5716, -5717, -5718, -5719, -5720, -5721, -5722, -5723, -5724, -5725, -5726, -5727, -5728, -5729, -5730, -5731, -5732, -5733, -5734, -5735, -5736, -5737, -5738, -5739, -5740, -5741, -5742, -5743, -5744, -5745, -5746, -5747, -5748, -5749, -5750, -5751, -5752, -5753, -5754, -5755, -5756, -5757, -5758, -5759, -5760, -5761, -5762, -5763, -5764, -5765, -5766, -5768, -5769, -5770, -5771, -5772, -5773, -5774, -5777, -5778, -5779, -5780, -5781, -5785, -5786, -5787, -5788, -5789, -5790, -5791, -5792, -5793, -5794, -5795, -5796, -5797, -5798, -5799, -5800, -5801, -5802, -5803, -5804, -5805, -5806, -5807, -5808, -5809, -5810, -5811, -5812, -5813, -5814, -5815, -5816, -5817, -5818, -5819, -5820, -5821, -5822, -5823, -5824, -5825, -5826, -5827, -5828, -5829, -5830, -5831, -5832, -5833, -5834, -5835, -5836, -5837, -5838, -5839, -5840, -5841, -5842, -5843, -5844, -5845, -5846, -5847, -5848, -5849, -5850, -5851, -5852, -5853, -5854, -5855, -5856, -5857, -5858, -5859, -5860, -5861, -5862, -5863, -5864, -5865, -5866, -5867, -5868, -5869, -5870, -5871, -5872, -5873, -5874, -5875, -5876, -5877, -5878, -5879, -5880, -5881, -5882, -5883, -5884, -5885, -5886, -5887, -5888, -5889, -5890, -5891, -5892, -5893, -5894, -5895, -5896, -5897, -5898, -5899, -5900, -5901, -5902, -5903, -5904, -5905, -5906, -5907, -5908, -5909, -5910, -5911, -5912, -5913, -5914, -5915, -5916, -5917, -5918, -5919, -5920, -5921, -5922, -5923, -5924, -5925, -5926, -5927, -5928, -5929, -5930, -5931, -5932, -5933, -5934, -5935, -5936, -5937, -5938, -5939, -5940, -5941, -5942, -5943, -5944, -5945, -5946, -5947, -5948, -5949, -5950, -5951, -5952, -5953, -5954, -5955, -5956, -5957, -5958, -5959, -5960, -5961, -5962, -5963, -5964, -5965, -5966, -5967, -5968, -5969, -5970, -5971, -5972, -5973, -5974, -5975, -5976, -5977, -5978, -5979, -5980, -5981, -5982, -5983, -5984, -5985, -5986, -5987, -5988, -5989, -5990, -5991, -5992, -5993, -5994, -5995, -5996, -5997, -5998, -5999, -6000, -6001, -6002, -6003, -6004, -6005, -6006, -6201, -6202, -6203, -6204, -6205, -6206, -6207, -6208, -6209, -6210, -6211, -6212, -6213, -6214, -6215, -6219, -6220, -6221, -6222, -6223, -6224, -6225, -6226, -6227, -6228, -6229, -6230, -6231, -6232, -6233, -6234, -6235, -6236, -6237, -6238, -6239, -6240, -6241, -6242, -6243, -6244, -6245, -6246, -6247, -6248, -6249, -6250, -6251, -6252, -6253, -6254, -6255, -6256, -6257, -6258, -6259, -6260, -6261, -6262, -6263, -6264, -6265, -6266, -6267, -6268, -6269, -6270, -6271, -6272, -6273, -6274, -6275, -6276, -6277, -6278, -6279, -6280, -6281, -6282, -6283, -6301, -6302, -6303, -6304, -6305, -6306, -6307, -6308, -6309, -6310, -6311, -6312, -6313, -6314, -6315, -6316, -6317, -6318, -6319, -6320, -6321, -6322, -6323, -6324, -7000, -7001, -7002, -7003, -7004, -7005, -7006, -7007, -7010, -7011, -7012, -7013, -7014, -7015, -7021, -7022, -7024, -7025, -7026, -7027, -7029, -7030, -7031, -7032, -7033, -7034, -7035, -7036, -7037, -7038, -7039, -7040, -7041, -7100, -7101, -7102, -7103, -7104, -7105, -7106, -7107, -7108, -7109, -7110, -7111, -7112, -7113, -7114, -7115, -7116, -7117, -7118, -7201, -7202, -7203, -7204, -7205, -7206, -7207, -7208, -7209, -7210, -7211, -7212, -7213, -7214, -7215, -7216, -7217, -7218, -7219, -7220, -7221, -7222, -7223, -7224, -7225, -7226, -7227, -7228, -7229, -7230, -7231, -7232, -7233, -7234, -7235, -7236, -7237, -7238, -7239, -7240, -7241, -7242, -7243, -7244, -7246, -7247, -7248, -7249, -7250, -7251, -7252, -7253, -7254, -7255, -7256, -7257, -7258, -7259, -7260, -7261, -7262, -7263, -7264, -7265, -7266, -7267, -7268, -7269, -7270, -7271, -7272, -7273, -7274, -7275, -7276, -7277, -7278, -7279, -7280, -7281, -7282, -7283, -7284, -7285, -7286, -7287, -7288, -7402, -7403, -7404, -7405, -7406, -7407, -7408, -7409, -7410, -7411, -7412, -7413, -7414, -7415, -7416, -7417, -7418, -7419, -8001, -8002, -8003, -8004, -8005, -9001, -9002, -9003, -9004, -9005, -9006, -9007, -9008, -9009, -9010, -9011, -9012, -9013, -9014, -9015, -9016, -9017, -9018, -9019, -9020, -9022, -9023, -9024, -9025, -9026, -9027, -9028, -9029, -9030, -9031, -9032, -9033, -9034, -9035, -9036, -9037, -9038, -9039, -9040, -9041, -9042, -9043, -9044, -9045, -9046, -9047, -9048, -9049, -9050, -9051, -9052, -9053, -9054, -9057, -9058, -9059, -9060, -9061, -9062, -9063, -9064, -9065, -9069, -9070, -9071, -9072, -9073, -9074, -9075, -9076, -9077, -9078, -9079, -9080, -9081, -9082, -9083, -9084, -9085, -9086, -9087, -9088, -9089, -9090, -9091, -9092, -9093, -9094, -9095, -9096, -9097, -9100, -9101, -9102, -9103, -9200, -9201, -9202, -9501, -9502, -9503, -9504, -9505, -9506, -9507, -9508, -9509, -9510, -9512, -9513, -9514, -9515, -9516, -9518, -9519, -9520, -9521, -9522, -9523, -9524, -9525, -9526, -9527, -9528, -9529, -9530, -9531, -9532, -9533, -9534, -9535, -9536, -9537, -9538, -9539, -9540, -9541, -9542, -9543, -9544, -9545, -9546, -9547, -9548, -9549, -9550, -9551, -9552, -9553, -9554, -9555, -9556, -9557, -9558, -9559, -9560, -9561, -9562, -9563, -9564, -9565, -9566, -9567, -9568, -9569, -9570, -9571, -9572, -9573, -9574, -9575, -9576, -9577, -9578, -9579, -9580, -9581, -9582, -9583, -9584, -9585, -9586, -9587, -9588, -9589, -9590, -9591, -9592, -9593, -9594, -9595, -9596, -9597, -9598, -9599, -9600, -9601, -9602, -9603, -9604, -9605, -9606, -9607, -9608, -9609, -9610, -9611, -9612, -9613, -9614, -9615, -9616, -9617, -9618, -9619, -9620, -9621, -9622, -9623, -9624, -9625, -9626, -9627, -9628, -9629, -9630, -9631, -9632, -9633, -9634, -9635, -9636, -9637, -9638, -9639, -9640, -9641, -9642, -9643, -9644, -9645, -9646, -9647, -9648, -9649, -9650, -9651, -9652, -9653, -9654, -9655, -9656, -9657, -9658, -9659, -9660, -9661, -9662, -9663, -9664, -9665, -9666, -9667, -9668, -9669, -9670, -9671, -9672, -9673, -9674, -9675, -9676, -9677, -9678, -9679, -9680, -9681, -9682, -9683, -9684, -9685, -9686, -9687, -9688, -9689, -9690, -9691, -9692, -9693, -9694, -9695, -9696, -9697, -9698, -9699, -9700, -9701, -9702, -9703, -9704, -9705, -9706, -9707, -9708, -9709, -9710, -9711, -9712, -9713, -9714, -9715, -9716, -9717, -9718, -9719, -9720, -9721, -9722, -9723, -9724, -9725, -9726, -9727, -9728, -9729, -9730, -9731, -9732, -9733, -9734, -9735, -9736, -9737, -9738, -9739, -9740, -9741, -9742, -9743, -9744, -9745, -9746, -9747, -9748, -9749, -20000, -21000, -22998, -30926, -32491, -38104, -38105}; const char *ob_error_name(const int err) { const char *ret = "Unknown error"; diff --git a/src/share/ob_errno.def b/src/share/ob_errno.def old mode 100644 new mode 100755 index c8cf0bb99..091bf7a4c --- a/src/share/ob_errno.def +++ b/src/share/ob_errno.def @@ -647,7 +647,6 @@ DEFINE_ERROR(OB_ERR_ROOT_INSPECTION, -4754, -1, "HY000", "root inspection is not DEFINE_ERROR(OB_ERR_ROOTSERVICE_THREAD_HUNG, -4755, -1, "HY000", "rootservice background thread may be hung"); DEFINE_ERROR(OB_MIGRATE_NOT_COMPATIBLE, -4756, -1, "HY000", "Migration src and dest version is not compatible."); DEFINE_ERROR(OB_CLUSTER_INFO_MAYBE_REMAINED, -4757, -1, "HY000", "Cluster info may remain on arbitration server '%.*s', please make sure whether to use ob_admin to clean it."); -//DEFINE_ERROR(OB_CLUSTER_INFO_MAYBE_REMAINED, -4757, -1, "HY000", "Cluster info may remain on arbitration server '%.*s', please make sure whether to use ob_admin to clean it."); DEFINE_ERROR(OB_ARBITRATION_INFO_QUERY_FAILED, -4758, -1, "HY000", "the arbitration service may be unavailable, please check and retry"); DEFINE_ERROR(OB_IGNORE_ERR_ACCESS_VIRTUAL_TABLE, -4759, -1, "HY000", "An error was ignored when accessing virtual table, actual error code: %d"); DEFINE_ERROR(OB_LS_OFFLINE, -4760, -1, "HY000", "log stream is offline"); @@ -1792,7 +1791,7 @@ DEFINE_ERROR(OB_TRANSFER_DETECT_ACTIVE_TRANS, -7114, -1, "HY000", "transfer dete DEFINE_ERROR(OB_TRANSFER_SRC_LS_NOT_EXIST, -7115, -1, "HY000", "transfer src ls does not exist"); DEFINE_ERROR(OB_TRANSFER_SRC_TABLET_NOT_EXIST, -7116, -1, "HY000", "transfer src tablet does not exist"); DEFINE_ERROR(OB_LS_NEED_REBUILD, -7117, -1, "HY000", "ls need rebuild"); - +DEFINE_ERROR(OB_OBSOLETE_CLOG_NEED_SKIP, -7118, -1, "HY000", "obsolete clog need skip"); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //error code for gis -7201 ---- -7300 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/share/ob_errno.h b/src/share/ob_errno.h old mode 100644 new mode 100755 index dffac0a53..470a7aecf --- a/src/share/ob_errno.h +++ b/src/share/ob_errno.h @@ -1401,6 +1401,7 @@ constexpr int OB_TRANSFER_DETECT_ACTIVE_TRANS = -7114; constexpr int OB_TRANSFER_SRC_LS_NOT_EXIST = -7115; constexpr int OB_TRANSFER_SRC_TABLET_NOT_EXIST = -7116; constexpr int OB_LS_NEED_REBUILD = -7117; +constexpr int OB_OBSOLETE_CLOG_NEED_SKIP = -7118; constexpr int OB_ERR_INVALID_XML_DATATYPE = -7402; constexpr int OB_ERR_XML_MISSING_COMMA = -7403; constexpr int OB_ERR_INVALID_XPATH_EXPRESSION = -7404; @@ -1745,6 +1746,7 @@ constexpr int OB_ERR_VARIABLE_NOT_IN_SELECT_LIST = -9745; constexpr int OB_ERR_MULTI_RECORD = -9746; constexpr int OB_ERR_MALFORMED_PS_PACKET = -9747; constexpr int OB_ERR_VIEW_SELECT_CONTAIN_QUESTIONMARK = -9748; +constexpr int OB_ERR_OBJECT_NOT_EXIST = -9749; constexpr int OB_SP_RAISE_APPLICATION_ERROR = -20000; constexpr int OB_SP_RAISE_APPLICATION_ERROR_NUM = -21000; constexpr int OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN = -22998; @@ -3381,6 +3383,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_TRANSFER_SRC_LS_NOT_EXIST__USER_ERROR_MSG "transfer src ls does not exist" #define OB_TRANSFER_SRC_TABLET_NOT_EXIST__USER_ERROR_MSG "transfer src tablet does not exist" #define OB_LS_NEED_REBUILD__USER_ERROR_MSG "ls need rebuild" +#define OB_OBSOLETE_CLOG_NEED_SKIP__USER_ERROR_MSG "obsolete clog need skip" #define OB_ERR_GIS_DIFFERENT_SRIDS__USER_ERROR_MSG "Binary geometry function %s given two geometries of different srids: %u and %u, which should have been identical." #define OB_ERR_GIS_UNSUPPORTED_ARGUMENT__USER_ERROR_MSG "Calling geometry function %s with unsupported types of arguments." #define OB_ERR_GIS_UNKNOWN_ERROR__USER_ERROR_MSG "Unknown GIS error occurred in function %s." @@ -3835,6 +3838,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_ERR_MULTI_RECORD__USER_ERROR_MSG "coercion into multiple record targets not supported" #define OB_ERR_MALFORMED_PS_PACKET__USER_ERROR_MSG "malformed ps packet" #define OB_ERR_VIEW_SELECT_CONTAIN_QUESTIONMARK__USER_ERROR_MSG "View's SELECT contains a variable or parameter" +#define OB_ERR_OBJECT_NOT_EXIST__USER_ERROR_MSG "object does not exist" #define OB_SP_RAISE_APPLICATION_ERROR__USER_ERROR_MSG "%.*s" #define OB_SP_RAISE_APPLICATION_ERROR_NUM__USER_ERROR_MSG "error number argument to raise_application_error of '%d' is out of range" #define OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN__USER_ERROR_MSG "CLOB or NCLOB in multibyte character set not supported" @@ -5471,6 +5475,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_TRANSFER_SRC_LS_NOT_EXIST__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -7115, transfer src ls does not exist" #define OB_TRANSFER_SRC_TABLET_NOT_EXIST__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -7116, transfer src tablet does not exist" #define OB_LS_NEED_REBUILD__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -7117, ls need rebuild" +#define OB_OBSOLETE_CLOG_NEED_SKIP__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -7118, obsolete clog need skip" #define OB_ERR_GIS_DIFFERENT_SRIDS__ORA_USER_ERROR_MSG "ORA-00600: Binary geometry function %s given two geometries of different srids: %u and %u, which should have been identical." #define OB_ERR_GIS_UNSUPPORTED_ARGUMENT__ORA_USER_ERROR_MSG "ORA-00600: Calling geometry function %s with unsupported types of arguments." #define OB_ERR_GIS_UNKNOWN_ERROR__ORA_USER_ERROR_MSG "ORA-00600: Unknown GIS error occurred in function %s." @@ -5925,6 +5930,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_ERR_MULTI_RECORD__ORA_USER_ERROR_MSG "ORA-00494: coercion into multiple record targets not supported" #define OB_ERR_MALFORMED_PS_PACKET__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -9747, malformed ps packet" #define OB_ERR_VIEW_SELECT_CONTAIN_QUESTIONMARK__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -9748, View's SELECT contains a variable or parameter" +#define OB_ERR_OBJECT_NOT_EXIST__ORA_USER_ERROR_MSG "ORA-06564: object does not exist" #define OB_SP_RAISE_APPLICATION_ERROR__ORA_USER_ERROR_MSG "ORA%06ld: %.*s" #define OB_SP_RAISE_APPLICATION_ERROR_NUM__ORA_USER_ERROR_MSG "ORA-21000: error number argument to raise_application_error of '%d' is out of range" #define OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN__ORA_USER_ERROR_MSG "ORA-22998: CLOB or NCLOB in multibyte character set not supported" @@ -5935,7 +5941,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_ERR_DATA_TOO_LONG_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-12899: value too large for column %.*s (actual: %ld, maximum: %ld)" #define OB_ERR_INVALID_DATE_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-01861: Incorrect datetime value for column '%.*s' at row %ld" -extern int g_all_ob_errnos[2084]; +extern int g_all_ob_errnos[2088]; const char *ob_error_name(const int oberr); const char* ob_error_cause(const int oberr); diff --git a/src/share/ob_ls_id.h b/src/share/ob_ls_id.h index cbf588362..53c139db1 100644 --- a/src/share/ob_ls_id.h +++ b/src/share/ob_ls_id.h @@ -17,6 +17,8 @@ #include "lib/container/ob_se_array.h" // ObSEArray #include "lib/utility/ob_print_utils.h" // TO_STRING_KV +#define DEBUG_FOR_MDS + namespace oceanbase { namespace share @@ -69,8 +71,10 @@ public: // compare operator bool operator == (const ObLSID &other) const { return id_ == other.id_; } bool operator > (const ObLSID &other) const { return id_ > other.id_; } + bool operator >= (const ObLSID &other) const { return id_ >= other.id_; } bool operator != (const ObLSID &other) const { return id_ != other.id_; } bool operator < (const ObLSID &other) const { return id_ < other.id_; } + bool operator <= (const ObLSID &other) const { return id_ <= other.id_; } int compare(const ObLSID &other) const { if (id_ == other.id_) { @@ -86,6 +90,17 @@ public: int hash(uint64_t &hash_val) const; NEED_SERIALIZE_AND_DESERIALIZE; TO_STRING_KV(K_(id)); + + bool debug_for_mds() const + { +#ifdef DEBUG_FOR_MDS + //if (SYS_LS_ID != id_) { + return true; + //} +#endif + return false; + } + private: int64_t id_; }; diff --git a/src/share/ob_max_id_fetcher.cpp b/src/share/ob_max_id_fetcher.cpp old mode 100644 new mode 100755 index da6cfcb40..3a50648ae --- a/src/share/ob_max_id_fetcher.cpp +++ b/src/share/ob_max_id_fetcher.cpp @@ -49,6 +49,7 @@ const char *ObMaxIdFetcher::max_id_name_info_[OB_MAX_ID_TYPE][2] = { { "ob_max_used_logstrema_group_id", "max used log stream group id"}, { "ob_max_used_sys_pl_object_id", "max used sys pl object id"}, { "ob_max_used_object_id", "max used object id"}, + { "ob_max_used_lock_owner_id", "max used lock owner id"}, { "ob_max_used_rewrite_rule_version", "max used rewrite rule version"}, /* the following id_type will be changed to ob_max_used_object_id and won't be persisted. */ { "ob_max_used_table_id", "max used table id"}, @@ -112,6 +113,7 @@ int ObMaxIdFetcher::convert_id_type( case OB_MAX_USED_LS_GROUP_ID_TYPE: case OB_MAX_USED_SYS_PL_OBJECT_ID_TYPE: case OB_MAX_USED_OBJECT_ID_TYPE: + case OB_MAX_USED_LOCK_OWNER_ID_TYPE: case OB_MAX_USED_REWRITE_RULE_VERSION_TYPE: { dst = src; break; @@ -299,6 +301,7 @@ int ObMaxIdFetcher::fetch_new_max_id(const uint64_t tenant_id, case OB_MAX_USED_SERVER_ID_TYPE: case OB_MAX_USED_DDL_TASK_ID_TYPE: case OB_MAX_USED_UNIT_GROUP_ID_TYPE: + case OB_MAX_USED_LOCK_OWNER_ID_TYPE: case OB_MAX_USED_LS_ID_TYPE: case OB_MAX_USED_LS_GROUP_ID_TYPE: case OB_MAX_USED_REWRITE_RULE_VERSION_TYPE: { diff --git a/src/share/ob_max_id_fetcher.h b/src/share/ob_max_id_fetcher.h old mode 100644 new mode 100755 index 5e23ef79d..a6d9e4b98 --- a/src/share/ob_max_id_fetcher.h +++ b/src/share/ob_max_id_fetcher.h @@ -41,6 +41,7 @@ enum ObMaxIdType OB_MAX_USED_LS_GROUP_ID_TYPE, OB_MAX_USED_SYS_PL_OBJECT_ID_TYPE, /* used for sys package object id */ OB_MAX_USED_OBJECT_ID_TYPE, /* used for all kinds of user schema objects */ + OB_MAX_USED_LOCK_OWNER_ID_TYPE, OB_MAX_USED_REWRITE_RULE_VERSION_TYPE, /* the following ObMaxIdType will be changed to OB_MAX_USED_OBJECT_ID_TYPE and won't be persisted. */ diff --git a/src/share/ob_occam_thread_pool.h b/src/share/ob_occam_thread_pool.h index 4e88de8ba..4e8b380d7 100644 --- a/src/share/ob_occam_thread_pool.h +++ b/src/share/ob_occam_thread_pool.h @@ -46,7 +46,7 @@ namespace occam struct DefaultAllocator : public ObIAllocator { void *alloc(const int64_t size) { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG total_alive_num++; #endif return ob_malloc(size, SET_USE_UNEXPECTED_500("OccamThreadPool")); @@ -56,12 +56,12 @@ struct DefaultAllocator : public ObIAllocator { return alloc(size); } void free(void *ptr) override { -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG total_alive_num--; #endif ob_free(ptr); } -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG int total_alive_num = 0; #endif static DefaultAllocator &get_default_allocator() { diff --git a/src/share/ob_occam_time_guard.h b/src/share/ob_occam_time_guard.h index ee6487323..bda8f48bb 100644 --- a/src/share/ob_occam_time_guard.h +++ b/src/share/ob_occam_time_guard.h @@ -242,7 +242,7 @@ public: const char *mod) :warn_threshold_(warn_threshold), idx_(0), - last_click_ts_(common::ObTimeUtility::fast_current_time()), + last_click_ts_(common::ObTimeUtility::current_time()), file_(file), func_name_(func), log_mod_(mod) @@ -255,7 +255,7 @@ public: for (int64_t idx = 0; idx < idx_; ++idx) { total_cost += click_poinsts_[idx]; } - total_cost += common::ObTimeUtility::fast_current_time() - last_click_ts_; + total_cost += common::ObTimeUtility::current_time() - last_click_ts_; if (OB_UNLIKELY(total_cost >= warn_threshold_)) { constexpr int buffer_size = 256; char strbuffer[buffer_size] = { 0 }; @@ -274,13 +274,13 @@ public: for (int64_t idx = 0; idx < idx_; ++idx) { total_cost += click_poinsts_[idx]; } - total_cost += common::ObTimeUtility::fast_current_time() - last_click_ts_; + total_cost += common::ObTimeUtility::current_time() - last_click_ts_; return total_cost > warn_threshold_; } bool click(const uint16_t line) { if (OB_LIKELY(idx_ < CAPACITY)) { - int64_t now = common::ObTimeUtility::fast_current_time(); + int64_t now = common::ObTimeUtility::current_time(); line_array_[idx_] = static_cast(line); click_poinsts_[idx_] = static_cast(now - last_click_ts_); last_click_ts_ = now; @@ -302,7 +302,7 @@ public: fmt_ts_to_meaningful_str(buf, buf_len, pos, line_array_[idx], click_poinsts_[idx]); total_cost += click_poinsts_[idx]; } - total_cost += common::ObTimeUtility::fast_current_time() - last_click_ts_; + total_cost += common::ObTimeUtility::current_time() - last_click_ts_; fmt_ts_to_meaningful_str(buf, buf_len, pos, "total", total_cost); if (pos != 0 && pos < buf_len) { pos -= 1; @@ -357,7 +357,131 @@ protected: uint32_t click_poinsts_[CAPACITY]; }; -class ObOccamTimeGuardDetectHung : public ObOccamTimeGuard +class ObOccamFastTimeGuard// must used in same thread +{ +public: + ObOccamFastTimeGuard(const uint32_t warn_threshold, + const char *file, + const char *func, + const char *mod) + :warn_threshold_(warn_threshold), + idx_(0), + last_click_ts_(common::ObTscTimestamp::get_instance().current_time()), + file_(file), + func_name_(func), + log_mod_(mod) + { + static_assert(CAPACITY > 0, "CAPACITY must greater than 0"); + } + ~ObOccamFastTimeGuard() + { + int64_t total_cost = 0; + for (int64_t idx = 0; idx < idx_; ++idx) { + total_cost += click_poinsts_[idx]; + } + total_cost += common::ObTscTimestamp::get_instance().current_time() - last_click_ts_; + if (OB_UNLIKELY(total_cost >= warn_threshold_)) { + constexpr int buffer_size = 256; + char strbuffer[buffer_size] = { 0 }; + int n = snprintf(strbuffer, buffer_size, "cost too much time:%s:%s, ", + file_, + func_name_); + if (n >= buffer_size) { + snprintf(&strbuffer[buffer_size - 6], 6, "..., "); + } + ::oceanbase::common::OB_PRINT(log_mod_, OB_LOG_LEVEL_DIRECT_NO_ERRCODE(WARN), OB_SUCCESS, strbuffer, LOG_KVS(K(*this))); + } + } + bool is_timeout() + { + int64_t total_cost = 0; + for (int64_t idx = 0; idx < idx_; ++idx) { + total_cost += click_poinsts_[idx]; + } + total_cost += common::ObTscTimestamp::get_instance().current_time() - last_click_ts_; + return total_cost > warn_threshold_; + } + bool click(const uint16_t line) + { + if (OB_LIKELY(idx_ < CAPACITY)) { + int64_t now = common::ObTscTimestamp::get_instance().current_time(); + line_array_[idx_] = static_cast(line); + click_poinsts_[idx_] = static_cast(now - last_click_ts_); + last_click_ts_ = now; + ++idx_; + } + return true; + } + int64_t to_string(char *buf, const int64_t buf_len) const + { + int64_t pos = 0; + fmt_ts_to_meaningful_str(buf, buf_len, pos, "|threshold", warn_threshold_); + int64_t start_click_ts = common::ObTimeUtility::current_time(); + for (int64_t idx = 0; idx < idx_; ++idx) { + start_click_ts -= click_poinsts_[idx]; + } + common::databuff_printf(buf, buf_len, pos, "start at %s|", common::ObTime2Str::ob_timestamp_str_range(start_click_ts)); + int64_t total_cost = 0; + for (int64_t idx = 0; idx < idx_; ++idx) { + fmt_ts_to_meaningful_str(buf, buf_len, pos, line_array_[idx], click_poinsts_[idx]); + total_cost += click_poinsts_[idx]; + } + total_cost += common::ObTscTimestamp::get_instance().current_time() - last_click_ts_; + fmt_ts_to_meaningful_str(buf, buf_len, pos, "total", total_cost); + if (pos != 0 && pos < buf_len) { + pos -= 1; + } + return pos; + } +protected: + void fmt_ts_to_meaningful_str(char *buf, + const int64_t buf_len, + int64_t &pos, + const uint16_t line, + const int64_t ts) const + { + if (line != UINT16_MAX) { + common::databuff_printf(buf, buf_len, pos, "%d", line); + } else { + common::databuff_printf(buf, buf_len, pos, "end"); + } + if (ts < 1_ms) { + common::databuff_printf(buf, buf_len, pos, "=%ldus|", ts); + } else if (ts < 1_s) { + common::databuff_printf(buf, buf_len, pos, "=%.2lfms|", double(ts) / 1_ms); + } else { + common::databuff_printf(buf, buf_len, pos, "=%.2lfs|", double(ts) / 1_s); + } + } + void fmt_ts_to_meaningful_str(char *buf, + const int64_t buf_len, + int64_t &pos, + const char *lvalue, + const int64_t ts) const + { + common::databuff_printf(buf, buf_len, pos, "%s", lvalue); + if (ts < 1_ms) { + common::databuff_printf(buf, buf_len, pos, "=%ldus|", ts); + } else if (ts < 1_s) { + common::databuff_printf(buf, buf_len, pos, "=%.2lfms|", double(ts) / 1_ms); + } else { + common::databuff_printf(buf, buf_len, pos, "=%.2lfs|", double(ts) / 1_s); + } + } +protected: + static constexpr int64_t CAPACITY = 16; +protected: + const uint32_t warn_threshold_; + uint32_t idx_; + int64_t last_click_ts_; + const char * const file_; + const char * const func_name_; + const char * const log_mod_; + uint16_t line_array_[CAPACITY]; + uint32_t click_poinsts_[CAPACITY]; +}; + +class ObOccamTimeGuardDetectHung : public ObOccamFastTimeGuard { public: ObOccamTimeGuardDetectHung(const uint32_t warn_threshold, @@ -366,7 +490,7 @@ public: const char *func, const char *mod, const uint16_t line) : - ObOccamTimeGuard(warn_threshold, file, func, mod), + ObOccamFastTimeGuard(warn_threshold, file, func, mod), g_idx_(-1), saved_timeout_ts_(0), saved_file_(0), @@ -384,7 +508,7 @@ public: saved_last_click_ts_ = g_point.last_click_ts_; saved_last_click_line_ = g_point.last_click_line_; } - int64_t cur_ts = common::ObTimeUtility::fast_current_time(); + int64_t cur_ts = common::ObTimeUtility::current_time(); int64_t hung_timeout_ts = cur_ts + hung_threshold; // recover global slot ++g_point.version_; @@ -425,7 +549,7 @@ public: } } bool click(const uint16_t line) { - ObOccamTimeGuard::click(line); + ObOccamFastTimeGuard::click(line); if (OB_LIKELY(g_idx_ != -1)) { ObThreadHungDetector::ClickPoint &g_point = THREAD_HUNG_DETECTOR.points_[g_idx_]; ++g_point.version_; diff --git a/src/share/ob_occam_timer.h b/src/share/ob_occam_timer.h index c4b1ea66c..305496997 100644 --- a/src/share/ob_occam_timer.h +++ b/src/share/ob_occam_timer.h @@ -229,7 +229,7 @@ public: try_delete_this_task_if_there_is_no_handle = true; } } - #ifdef UNIITTEST_DEBUG + #ifdef UNITTEST_DEBUG ob_usleep(10_ms); #endif // try delete task if: @@ -263,7 +263,7 @@ public: ObOccamTimerTask *task = this; int64_t schedule_time = ObClockGenerator::getRealClock(); TaskWrapper commit_task(func_shared_ptr_, task, need_delete, schedule_time); -#ifdef UNIITTEST_DEBUG +#ifdef UNITTEST_DEBUG OCCAM_LOG(DEBUG, "print size of", K(sizeof(commit_task))); #endif switch (task_priority_) { diff --git a/src/share/ob_primary_standby_service.cpp b/src/share/ob_primary_standby_service.cpp index 7bdb834ba..1ebe5bcb1 100644 --- a/src/share/ob_primary_standby_service.cpp +++ b/src/share/ob_primary_standby_service.cpp @@ -18,7 +18,8 @@ #include "rootserver/ob_cluster_event.h" // CLUSTER_EVENT_ADD_CONTROL #include "rootserver/ob_rs_event_history_table_operator.h" // ROOTSERVICE_EVENT_ADD #include "rootserver/ob_tenant_role_transition_service.h" // ObTenantRoleTransitionService -#include "rootserver/ob_primary_ls_service.h"//ObTenantLSInfo +#include "rootserver/ob_ls_service_helper.h"//ObTenantLSInfo +#include "share/restore/ob_log_restore_source_mgr.h" // ObLogRestoreSourceMgr #include "share/ls/ob_ls_recovery_stat_operator.h"// ObLSRecoveryStatOperator #include "share/ls/ob_ls_life_manager.h" //ObLSLifeAgentManager #include "share/ls/ob_ls_operator.h" //ObLSAttr @@ -86,9 +87,8 @@ int ObPrimaryStandbyService::switch_tenant(const obrpc::ObSwitchTenantArg &arg) int ret = OB_SUCCESS; int64_t begin_time = ObTimeUtility::current_time(); uint64_t switch_tenant_id = OB_INVALID_ID; - ObSchemaGetterGuard schema_guard; const char *alter_cluster_event = arg.get_alter_type_str(); - const ObSimpleTenantSchema *tenant_schema = nullptr; + ObTenantStatus tenant_status = TENANT_STATUS_MAX; uint64_t compat_version = 0; CLUSTER_EVENT_ADD_CONTROL_START(ret, alter_cluster_event, "stmt_str", arg.get_stmt_str()); if (OB_FAIL(check_inner_stat_())) { @@ -104,28 +104,23 @@ int ObPrimaryStandbyService::switch_tenant(const obrpc::ObSwitchTenantArg &arg) ret = OB_NOT_SUPPORTED; LOG_WARN("Tenant COMPATIBLE is below 4.1.0.0, switch tenant is not supported", KR(ret)); LOG_USER_ERROR(OB_NOT_SUPPORTED, "Tenant COMPATIBLE is below 4.1.0.0, switch tenant is"); - } else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("failed to get schema guard", KR(ret)); - } else if (OB_FAIL(schema_guard.get_tenant_info(switch_tenant_id, tenant_schema))) { - LOG_WARN("failed to get tenant info", KR(ret), K(switch_tenant_id)); - } else if (OB_ISNULL(tenant_schema)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant_schema is null", KR(ret), K(switch_tenant_id), K(arg)); - } else if (tenant_schema->is_normal()) { + } else if (OB_FAIL(get_tenant_status_(switch_tenant_id, tenant_status))) { + LOG_WARN("failed to get tenant status", KR(ret), K(switch_tenant_id)); + } else if (is_tenant_normal(tenant_status)) { switch (arg.get_op_type()) { case ObSwitchTenantArg::SWITCH_TO_PRIMARY : if (OB_FAIL(switch_to_primary(switch_tenant_id, arg.get_op_type()))) { - LOG_WARN("failed to switch_to_primary", KR(ret), K(switch_tenant_id), K(arg), KPC(tenant_schema)); + LOG_WARN("failed to switch_to_primary", KR(ret), K(switch_tenant_id), K(arg), K(tenant_status)); } break; case ObSwitchTenantArg::SWITCH_TO_STANDBY : if (OB_FAIL(switch_to_standby(switch_tenant_id, arg.get_op_type()))) { - LOG_WARN("failed to switch_to_standby", KR(ret), K(switch_tenant_id), K(arg), KPC(tenant_schema)); + LOG_WARN("failed to switch_to_standby", KR(ret), K(switch_tenant_id), K(arg), K(tenant_status)); } break; case ObSwitchTenantArg::FAILOVER_TO_PRIMARY : if (OB_FAIL(failover_to_primary(switch_tenant_id, arg.get_op_type()))) { - LOG_WARN("failed to failover_to_primary", KR(ret), K(switch_tenant_id), K(arg), KPC(tenant_schema)); + LOG_WARN("failed to failover_to_primary", KR(ret), K(switch_tenant_id), K(arg), K(tenant_status)); } break; default : @@ -134,7 +129,7 @@ int ObPrimaryStandbyService::switch_tenant(const obrpc::ObSwitchTenantArg &arg) } } else { ret = OB_OP_NOT_ALLOW; - LOG_WARN("tenant status is not normal, switch tenant is not allowed", KR(ret), K(switch_tenant_id), K(arg), KPC(tenant_schema)); + LOG_WARN("tenant status is not normal, switch tenant is not allowed", KR(ret), K(switch_tenant_id), K(arg), K(tenant_status)); LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant status is not normal, switch tenant is"); } @@ -156,8 +151,7 @@ int ObPrimaryStandbyService::failover_to_primary(const uint64_t tenant_id, { int ret = OB_SUCCESS; ObAllTenantInfo tenant_info; - ObSchemaGetterGuard schema_guard; - const ObSimpleTenantSchema *tenant_schema = nullptr; + ObTenantStatus tenant_status = TENANT_STATUS_MAX; if (OB_FAIL(check_inner_stat_())) { LOG_WARN("inner stat error", KR(ret), K_(inited)); } else if (OB_ISNULL(GCTX.srv_rpc_proxy_) || OB_ISNULL(schema_service_)) { @@ -175,21 +169,16 @@ int ObPrimaryStandbyService::failover_to_primary(const uint64_t tenant_id, LOG_WARN("failed to load tenant info", KR(ret), K(tenant_id)); } else if (tenant_info.is_primary() && tenant_info.is_normal_status()) { LOG_INFO("already is primary tenant, no need switch", K(tenant_info)); - } else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id)); - } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) { - LOG_WARN("failed to get tenant info", KR(ret), K(tenant_id)); - } else if (OB_ISNULL(tenant_schema)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant_schema is null", KR(ret), K(tenant_id)); - } else if (tenant_schema->is_normal()) { + } else if (OB_FAIL(get_tenant_status_(tenant_id, tenant_status))) { + LOG_WARN("failed to get tenant status", KR(ret), K(tenant_id)); + } else if (is_tenant_normal(tenant_status)) { ObTenantRoleTransitionService role_transition_service(tenant_id, sql_proxy_, GCTX.srv_rpc_proxy_, switch_optype); if (OB_FAIL(role_transition_service.failover_to_primary())) { LOG_WARN("failed to failover to primary", KR(ret), K(tenant_id)); } } else { ret = OB_OP_NOT_ALLOW; - LOG_WARN("tenant status is not normal, failover is not allowed", KR(ret), K(tenant_id), KPC(tenant_schema)); + LOG_WARN("tenant status is not normal, failover is not allowed", KR(ret), K(tenant_id), K(tenant_status)); LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant status is not normal, failover is"); } @@ -274,6 +263,60 @@ int ObPrimaryStandbyService::recover_tenant(const obrpc::ObRecoverTenantArg &arg return ret; } +int ObPrimaryStandbyService::get_tenant_status_( + const uint64_t tenant_id, + ObTenantStatus &status) +{ + int ret = OB_SUCCESS; + status = TENANT_STATUS_MAX; + if (OB_FAIL(check_inner_stat_())) { + LOG_WARN("inner stat error", KR(ret), K_(inited)); + } else if (!is_user_tenant(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only support get user tenant status", KR(ret), K(tenant_id)); + LOG_USER_ERROR(OB_INVALID_ARGUMENT, "tenant id, only support operating user tenant"); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pointer is null", KR(ret), KP(sql_proxy_)); + } else { + ObSqlString sql; + SMART_VAR(ObISQLClient::ReadResult, result) { + if (OB_FAIL(sql.assign_fmt( + "SELECT status FROM %s WHERE tenant_id = %lu", + OB_ALL_TENANT_TNAME, tenant_id))) { + LOG_WARN("assign sql string failed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(sql_proxy_->read(result, OB_SYS_TENANT_ID, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get result failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(result.get_result()->next())) { + LOG_WARN("get next result failed", KR(ret), K(tenant_id), K(sql)); + if (OB_ITER_END == ret) { + ret = OB_TENANT_NOT_EXIST; + } + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret), K(tenant_id), K(sql)); + } else { + ObString tenant_status_str(""); + ObString default_tenant_status_str("NORMAL"); + bool skip_null_error = false; + + EXTRACT_VARCHAR_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result.get_result(), "status", tenant_status_str, + skip_null_error, ObSchemaService::g_ignore_column_retrieve_error_, default_tenant_status_str); + + if (OB_FAIL(ret)) { + LOG_WARN("failed to get result", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(get_tenant_status(tenant_status_str, status))) { + LOG_WARN("fail to get tenant status", KR(ret), K(tenant_status_str), K(tenant_id), K(sql)); + } + } + } + } + return ret; +} + int ObPrimaryStandbyService::do_recover_tenant( const uint64_t tenant_id, const share::ObTenantSwitchoverStatus &working_sw_status, @@ -282,31 +325,25 @@ int ObPrimaryStandbyService::do_recover_tenant( { int ret = OB_SUCCESS; ObAllTenantInfo tenant_info; - ObSchemaGetterGuard schema_guard; const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id); common::ObMySQLTransaction trans; - const ObSimpleTenantSchema *tenant_schema = nullptr; ObLSRecoveryStatOperator ls_recovery_operator; ObLSRecoveryStat sys_ls_recovery; + ObTenantStatus tenant_status = TENANT_STATUS_MAX; if (OB_FAIL(check_inner_stat_())) { LOG_WARN("inner stat error", KR(ret), K_(inited)); } else if (!obrpc::ObRecoverTenantArg::is_valid(recover_type, recovery_until_scn) || !working_sw_status.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(recover_type), K(recovery_until_scn), KR(ret)); - } else if (OB_ISNULL(GCTX.srv_rpc_proxy_) || OB_ISNULL(schema_service_) || OB_ISNULL(sql_proxy_)) { + } else if (OB_ISNULL(sql_proxy_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("pointer is null", KR(ret), KP(GCTX.srv_rpc_proxy_), KP(schema_service_), KP(sql_proxy_)); + LOG_WARN("pointer is null", KR(ret), KP(sql_proxy_)); } else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id)); - } else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id)); - } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) { - LOG_WARN("failed to get tenant info", KR(ret), K(tenant_id)); - } else if (OB_ISNULL(tenant_schema)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tenant_schema is null", KR(ret), K(tenant_id), K(recover_type), K(recovery_until_scn)); + } else if (OB_FAIL(get_tenant_status_(tenant_id, tenant_status))) { + LOG_WARN("failed to get tenant status", KR(ret), K(tenant_id)); } else if (OB_FAIL(trans.start(sql_proxy_, exec_tenant_id))) { LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id), K(tenant_id)); } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, &trans, true, tenant_info))) { @@ -328,7 +365,7 @@ int ObPrimaryStandbyService::do_recover_tenant( LOG_WARN("recover before tenant sync_scn or SYS LS sync_scn is not allow", KR(ret), K(tenant_info), K(tenant_id), K(recover_type), K(recovery_until_scn), K(sys_ls_recovery)); LOG_USER_ERROR(OB_OP_NOT_ALLOW, "recover before tenant sync_scn or SYS LS sync_scn is"); - } else if (tenant_schema->is_normal()) { + } else if (is_tenant_normal(tenant_status)) { const SCN &recovery_until_scn_to_set = obrpc::ObRecoverTenantArg::RecoverType::UNTIL == recover_type ? recovery_until_scn : SCN::max(tenant_info.get_sync_scn(), sys_ls_recovery.get_sync_scn()); if (tenant_info.get_recovery_until_scn() == recovery_until_scn_to_set) { @@ -342,7 +379,7 @@ int ObPrimaryStandbyService::do_recover_tenant( } else { ret = OB_OP_NOT_ALLOW; LOG_WARN("tenant status is not normal, recover is not allowed", KR(ret), K(tenant_id), - K(recover_type), K(recovery_until_scn), KPC(tenant_schema)); + K(recover_type), K(recovery_until_scn), K(tenant_status)); LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant status is not normal, recover is"); } @@ -572,14 +609,14 @@ int ObPrimaryStandbyService::switch_to_standby_prepare_ls_status_( ret = OB_TENANT_NOT_EXIST; LOG_WARN("tenant not exist", KR(ret), K(tenant_id)); } else { - ObTenantLSInfo tenant_stat(GCTX.sql_proxy_, tenant_schema, tenant_id, - GCTX.srv_rpc_proxy_, GCTX.lst_operator_); + ObTenantLSInfo tenant_stat(GCTX.sql_proxy_, tenant_schema, tenant_id); /* lock SYS_LS to get accurate LS list, then fix ls status to make ls status consistency between __all_ls&__all_ls_status. Refer to ls operator, insert/update/delete of ls table are executed in the SYS_LS lock and normal switchover status */ - if (OB_FAIL(tenant_stat.process_ls_status_missmatch(true/* lock_sys_ls */, - share::PREP_SWITCHING_TO_STANDBY_SWITCHOVER_STATUS))) { + if (OB_FAIL(ObLSServiceHelper::process_status_to_steady(true/* lock_sys_ls */, + share::PREP_SWITCHING_TO_STANDBY_SWITCHOVER_STATUS, + tenant_stat))) { LOG_WARN("failed to process_ls_status_missmatch", KR(ret)); } else if (OB_FAIL(ObAllTenantInfoProxy::update_tenant_role( tenant_id, sql_proxy_, switchover_epoch, diff --git a/src/share/ob_primary_standby_service.h b/src/share/ob_primary_standby_service.h index 9d6440173..4be20c40f 100644 --- a/src/share/ob_primary_standby_service.h +++ b/src/share/ob_primary_standby_service.h @@ -174,6 +174,17 @@ private: const int64_t switchover_epoch, ObAllTenantInfo &new_tenant_info); + /** + * @description: + * get tenant status from all_tenant + * @param[in] tenant_id + * @param[out] status tenant status from all_tenant + * @return return code + */ + int get_tenant_status_( + const uint64_t tenant_id, + ObTenantStatus &status); + private: const static int64_t SEC_UNIT = 1000L * 1000L; const static int64_t PRINT_INTERVAL = 10 * 1000 * 1000L; diff --git a/src/share/ob_rpc_struct.cpp b/src/share/ob_rpc_struct.cpp old mode 100644 new mode 100755 index f4a4f032b..b9887912f --- a/src/share/ob_rpc_struct.cpp +++ b/src/share/ob_rpc_struct.cpp @@ -1167,7 +1167,8 @@ OB_SERIALIZE_MEMBER((ObLockTenantArg, ObDDLArg), tenant_name_, is_locked_); bool ObDropTenantArg::is_valid() const { - return !tenant_name_.empty(); + bool b_ret = drop_only_in_restore_ ? force_drop_ : true; + return !tenant_name_.empty() && b_ret; } DEF_TO_STRING(ObDropTenantArg) @@ -1179,7 +1180,8 @@ DEF_TO_STRING(ObDropTenantArg) K_(force_drop), K_(object_name), K_(open_recyclebin), - K_(tenant_id)); + K_(tenant_id), + K_(drop_only_in_restore)); return pos; } @@ -1196,6 +1198,7 @@ int ObDropTenantArg::assign(const ObDropTenantArg &other) object_name_ = other.object_name_; open_recyclebin_ = other.object_name_; tenant_id_ = other.tenant_id_; + drop_only_in_restore_ = other.drop_only_in_restore_; } return ret; } @@ -1203,7 +1206,7 @@ int ObDropTenantArg::assign(const ObDropTenantArg &other) OB_SERIALIZE_MEMBER((ObDropTenantArg, ObDDLArg), tenant_name_, if_exist_, delay_to_drop_, force_drop_, object_name_, open_recyclebin_, - tenant_id_); + tenant_id_, drop_only_in_restore_); bool ObAddSysVarArg::is_valid() const { @@ -3159,7 +3162,8 @@ OB_SERIALIZE_MEMBER( ret_code_, source_table_id_, schema_version_, - task_id_); + task_id_, + tenant_id_); bool ObCalcColumnChecksumResponseArg::is_valid() const { @@ -3167,7 +3171,8 @@ bool ObCalcColumnChecksumResponseArg::is_valid() const && OB_INVALID_ID != target_table_id_ && OB_INVALID_ID != source_table_id_ && schema_version_ > 0 - && task_id_ > 0; + && task_id_ > 0 + && tenant_id_ != OB_INVALID_TENANT_ID; } void ObCalcColumnChecksumResponseArg::reset() @@ -3178,6 +3183,7 @@ void ObCalcColumnChecksumResponseArg::reset() source_table_id_ = OB_INVALID_ID; schema_version_ = OB_INVALID_VERSION; task_id_ = 0; + tenant_id_ = OB_INVALID_TENANT_ID; } OB_SERIALIZE_MEMBER(ObLSMigrateReplicaArg, @@ -5497,6 +5503,75 @@ int ObGetLSSyncScnRes::assign(const ObGetLSSyncScnRes &other) return ret; } +OB_SERIALIZE_MEMBER(ObGetLSReplayedScnArg, tenant_id_, ls_id_); + +bool ObGetLSReplayedScnArg::is_valid() const +{ + return OB_INVALID_TENANT_ID != tenant_id_ + && ls_id_.is_valid(); +} +int ObGetLSReplayedScnArg::init( + const uint64_t tenant_id, const ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(ls_id)); + } else { + tenant_id_ = tenant_id; + ls_id_ = ls_id; + } + return ret; +} +int ObGetLSReplayedScnArg::assign(const ObGetLSReplayedScnArg &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + tenant_id_ = other.tenant_id_; + ls_id_ = other.ls_id_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObGetLSReplayedScnRes, tenant_id_, ls_id_, cur_readable_scn_); + +bool ObGetLSReplayedScnRes::is_valid() const +{ + return OB_INVALID_TENANT_ID != tenant_id_ + && ls_id_.is_valid() + && cur_readable_scn_.is_valid_and_not_min(); +} +int ObGetLSReplayedScnRes::init( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const share::SCN &cur_readable_scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !ls_id.is_valid() + || !cur_readable_scn.is_valid_and_not_min())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(ls_id), K(cur_readable_scn)); + } else { + tenant_id_ = tenant_id; + ls_id_ = ls_id; + cur_readable_scn_ = cur_readable_scn; + } + return ret; +} + +int ObGetLSReplayedScnRes::assign(const ObGetLSReplayedScnRes &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + tenant_id_ = other.tenant_id_; + ls_id_ = other.ls_id_; + cur_readable_scn_ = other.cur_readable_scn_; + } + return ret; +} + OB_SERIALIZE_MEMBER(ObRefreshTenantInfoArg, tenant_id_); bool ObRefreshTenantInfoArg::is_valid() const @@ -6050,7 +6125,7 @@ int ObBackupDataArg::assign(const ObBackupDataArg &arg) return ret; } -OB_SERIALIZE_MEMBER(ObBackupTaskRes, task_id_, job_id_, tenant_id_, ls_id_, src_server_, result_, trace_id_); +OB_SERIALIZE_MEMBER(ObBackupTaskRes, task_id_, job_id_, tenant_id_, ls_id_, src_server_, result_, trace_id_, dag_id_); bool ObBackupTaskRes::is_valid() const { @@ -6059,7 +6134,8 @@ bool ObBackupTaskRes::is_valid() const && tenant_id_ > 0 && src_server_.is_valid() && ls_id_.is_valid() - && !trace_id_.is_invalid(); + && !trace_id_.is_invalid() + && !dag_id_.is_invalid(); } int ObBackupTaskRes::assign(const ObBackupTaskRes &res) @@ -6076,6 +6152,7 @@ int ObBackupTaskRes::assign(const ObBackupTaskRes &res) src_server_ = res.src_server_; result_ = res.result_; trace_id_ = res.trace_id_; + dag_id_ = res.dag_id_; } return ret; } @@ -6858,29 +6935,33 @@ bool ObLSAccessModeInfo::is_valid() const && ls_id_.is_valid() && palf::INVALID_PROPOSAL_ID != mode_version_ && palf::AccessMode::INVALID_ACCESS_MODE != access_mode_ - && ref_scn_.is_valid(); + && ref_scn_.is_valid() + && addr_.is_valid(); } int ObLSAccessModeInfo::init( uint64_t tenant_id, const ObLSID &ls_id, const int64_t mode_version, const palf::AccessMode &access_mode, - const SCN &ref_scn) + const SCN &ref_scn, + const ObAddr &addr) { int ret = OB_SUCCESS; if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || !ls_id.is_valid() || palf::AccessMode::INVALID_ACCESS_MODE == access_mode || palf::INVALID_PROPOSAL_ID == mode_version - || !ref_scn.is_valid())) { + || !ref_scn.is_valid() + || !addr.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(ls_id), - K(mode_version), K(access_mode), K(ref_scn)); + K(mode_version), K(access_mode), K(ref_scn), K(addr)); } else { tenant_id_ = tenant_id; ls_id_ = ls_id; mode_version_ = mode_version; access_mode_ = access_mode; ref_scn_ = ref_scn; + addr_ = addr; } return ret; } @@ -6893,10 +6974,11 @@ int ObLSAccessModeInfo::assign(const ObLSAccessModeInfo &other) mode_version_ = other.mode_version_; access_mode_ = other.access_mode_; ref_scn_ = other.ref_scn_; + addr_ = other.addr_; } return ret; } -OB_SERIALIZE_MEMBER(ObLSAccessModeInfo, tenant_id_, ls_id_, mode_version_, access_mode_, ref_scn_); +OB_SERIALIZE_MEMBER(ObLSAccessModeInfo, tenant_id_, ls_id_, mode_version_, access_mode_, ref_scn_, addr_); bool ObChangeLSAccessModeRes::is_valid() const { @@ -6989,6 +7071,7 @@ void ObBatchRemoveTabletArg::reset() { tablet_ids_.reset(); id_.reset(); + is_old_mds_ = false; } int ObBatchRemoveTabletArg::assign(const ObBatchRemoveTabletArg &arg) @@ -6998,6 +7081,7 @@ int ObBatchRemoveTabletArg::assign(const ObBatchRemoveTabletArg &arg) LOG_WARN("failed to assign table ids", KR(ret), K(arg)); } else { id_ = arg.id_; + is_old_mds_ = arg.is_old_mds_; } return ret; } @@ -7024,11 +7108,38 @@ int ObBatchRemoveTabletArg::init(const ObIArray &tablet_ids, DEF_TO_STRING(ObBatchRemoveTabletArg) { int64_t pos = 0; - J_KV(K_(id), K_(tablet_ids)); + J_KV(K_(id), K_(tablet_ids), K_(is_old_mds)); return pos; } -OB_SERIALIZE_MEMBER(ObBatchRemoveTabletArg, tablet_ids_, id_); +OB_DEF_SERIALIZE(ObBatchRemoveTabletArg) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, tablet_ids_, id_, is_old_mds_); + return ret; +} + +OB_DEF_SERIALIZE_SIZE(ObBatchRemoveTabletArg) +{ + int len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, tablet_ids_, id_, is_old_mds_); + return len; +} + +OB_DEF_DESERIALIZE(ObBatchRemoveTabletArg) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, tablet_ids_, id_); + if (OB_SUCC(ret)) { + if (pos == data_len) { + is_old_mds_ = true; + } else { + LST_DO_CODE(OB_UNIS_DECODE, is_old_mds_); + } + } + return ret; +} + // ---------------------- bool ObCreateTabletInfo::is_valid() const { @@ -7143,6 +7254,7 @@ void ObBatchCreateTabletArg::reset() tablets_.reset(); table_schemas_.reset(); need_check_tablet_cnt_ = false; + is_old_mds_ = false; } int ObBatchCreateTabletArg::assign(const ObBatchCreateTabletArg &arg) @@ -7159,6 +7271,7 @@ int ObBatchCreateTabletArg::assign(const ObBatchCreateTabletArg &arg) id_ = arg.id_; major_frozen_scn_ = arg.major_frozen_scn_; need_check_tablet_cnt_ = arg.need_check_tablet_cnt_; + is_old_mds_ = arg.is_old_mds_; } return ret; } @@ -7212,12 +7325,39 @@ int64_t ObBatchCreateTabletArg::get_tablet_count() const DEF_TO_STRING(ObBatchCreateTabletArg) { int64_t pos = 0; - J_KV(K_(id), K_(major_frozen_scn), K_(need_check_tablet_cnt), K_(tablets)); + J_KV(K_(id), K_(major_frozen_scn), K_(need_check_tablet_cnt), K_(is_old_mds), K_(tablets)); return pos; } -OB_SERIALIZE_MEMBER(ObBatchCreateTabletArg, id_, major_frozen_scn_, - tablets_, table_schemas_, need_check_tablet_cnt_); +OB_DEF_SERIALIZE(ObBatchCreateTabletArg) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, id_, major_frozen_scn_, tablets_, table_schemas_, need_check_tablet_cnt_, is_old_mds_); + return ret; +} + +OB_DEF_SERIALIZE_SIZE(ObBatchCreateTabletArg) +{ + int len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, id_, major_frozen_scn_, tablets_, table_schemas_, need_check_tablet_cnt_, is_old_mds_); + return len; +} + +OB_DEF_DESERIALIZE(ObBatchCreateTabletArg) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, id_, major_frozen_scn_, tablets_, table_schemas_, need_check_tablet_cnt_); + if (OB_SUCC(ret)) { + if (pos == data_len) { + is_old_mds_ = true; + } else { + LST_DO_CODE(OB_UNIS_DECODE, is_old_mds_); + } + } + return ret; +} + + OB_SERIALIZE_MEMBER(ObCreateDupLSResult, ret_); bool ObCreateDupLSResult::is_valid() const @@ -7742,7 +7882,8 @@ int ObRegisterTxDataArg::init(const uint64_t tenant_id, const ObLSID &ls_id, const ObTxDataSourceType &type, const ObString &buf, - const int64_t base_request_id) + const int64_t base_request_id, + const transaction::ObRegisterMdsFlag ®ister_flag) { int ret = OB_SUCCESS; if (OB_UNLIKELY(tenant_id == OB_INVALID_TENANT_ID || !tx_desc.is_valid() || !ls_id.is_valid() @@ -7756,6 +7897,7 @@ int ObRegisterTxDataArg::init(const uint64_t tenant_id, type_ = type; buf_ = buf; request_id_ = base_request_id; + register_flag_ = register_flag; } return ret; } @@ -7768,6 +7910,7 @@ void ObRegisterTxDataArg::reset() type_ = ObTxDataSourceType::UNKNOWN; buf_.reset(); request_id_ = 0; + register_flag_.reset(); return; } @@ -7785,7 +7928,7 @@ OB_DEF_SERIALIZE(ObRegisterTxDataArg) int ret = OB_SUCCESS; OB_UNIS_ENCODE(tenant_id_); OB_UNIS_ENCODE(*tx_desc_); - LST_DO_CODE(OB_UNIS_ENCODE, ls_id_, type_, buf_, request_id_); + LST_DO_CODE(OB_UNIS_ENCODE, ls_id_, type_, buf_, request_id_, register_flag_); return ret; } OB_DEF_DESERIALIZE(ObRegisterTxDataArg) @@ -7800,7 +7943,7 @@ OB_DEF_DESERIALIZE(ObRegisterTxDataArg) } else if (OB_FAIL(tx_svc->acquire_tx(buf, data_len, pos, tx_desc_))) { LOG_WARN("acquire tx by deserialize fail", K(data_len), K(pos), KR(ret)); } else { - LST_DO_CODE(OB_UNIS_DECODE, ls_id_, type_, buf_, request_id_); + LST_DO_CODE(OB_UNIS_DECODE, ls_id_, type_, buf_, request_id_, register_flag_); LOG_INFO("deserialize txDesc from session", KPC_(tx_desc), KPC(this)); } } @@ -7811,7 +7954,7 @@ OB_DEF_SERIALIZE_SIZE(ObRegisterTxDataArg) int64_t len = 0; OB_UNIS_ADD_LEN(tenant_id_); OB_UNIS_ADD_LEN(*tx_desc_); - LST_DO_CODE(OB_UNIS_ADD_LEN, ls_id_, type_, buf_, request_id_); + LST_DO_CODE(OB_UNIS_ADD_LEN, ls_id_, type_, buf_, request_id_, register_flag_); return len; } @@ -8291,6 +8434,60 @@ int ObRlsContextDDLArg::assign(const ObRlsContextDDLArg &other) return ret; } +OB_SERIALIZE_MEMBER(ObStartTransferTaskArg, tenant_id_, task_id_, dest_ls_); + +int ObStartTransferTaskArg::init( + const uint64_t tenant_id, + const ObTransferTaskID &task_id, + const ObLSID &dest_ls) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || ! task_id.is_valid()) + || !dest_ls.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(task_id), K(dest_ls)); + } else { + tenant_id_ = tenant_id; + task_id_ = task_id; + dest_ls_ = dest_ls; + } + return ret; +} + +int ObStartTransferTaskArg::assign(const ObStartTransferTaskArg &other) +{ + int ret = OB_SUCCESS; + tenant_id_ = other.tenant_id_; + task_id_ = other.task_id_; + dest_ls_ = other.dest_ls_; + return ret; +} + + +OB_SERIALIZE_MEMBER(ObFinishTransferTaskArg, tenant_id_, task_id_); + +int ObFinishTransferTaskArg::init(const uint64_t tenant_id, const ObTransferTaskID &task_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || ! task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(task_id)); + } else { + tenant_id_ = tenant_id; + task_id_ = task_id; + } + return ret; +} + +int ObFinishTransferTaskArg::assign(const ObFinishTransferTaskArg &other) +{ + int ret = OB_SUCCESS; + tenant_id_ = other.tenant_id_; + task_id_ = other.task_id_; + return ret; +} + OB_SERIALIZE_MEMBER((ObTryAddDepInofsForSynonymBatchArg, ObDDLArg), tenant_id_, synonym_ids_); diff --git a/src/share/ob_rpc_struct.h b/src/share/ob_rpc_struct.h old mode 100644 new mode 100755 index 6feae9da5..de2684e5b --- a/src/share/ob_rpc_struct.h +++ b/src/share/ob_rpc_struct.h @@ -64,7 +64,7 @@ #include "logservice/palf/palf_base_info.h"//PalfBaseInfo #include "logservice/palf/log_define.h"//INVALID_PROPOSAL_ID #include "share/location_cache/ob_vtable_location_service.h" // share::ObVtableLocationType -//#include "share/ls/ob_ls_i_life_manager.h" +#include "share/ob_balance_define.h" // share::ObTransferTaskID #include "share/config/ob_config.h" // ObConfigArray #include "logservice/palf/log_meta_info.h"//LogConfigVersion #include "share/scn.h"//SCN @@ -618,7 +618,8 @@ public: delay_to_drop_(true), force_drop_(false),//Obsolete field open_recyclebin_(true), - tenant_id_(OB_INVALID_TENANT_ID) {} + tenant_id_(OB_INVALID_TENANT_ID), + drop_only_in_restore_(false) {} virtual ~ObDropTenantArg() {} /* * drop tenant force最高优先级 @@ -641,6 +642,7 @@ public: common::ObString object_name_;//no use in 4.0 bool open_recyclebin_; uint64_t tenant_id_; // drop tenant with tenant_id_ if it's valid. + bool drop_only_in_restore_; // when cancel restore tenant, drop_only_in_restore_ is set to true }; struct ObSequenceDDLArg : public ObDDLArg @@ -899,6 +901,7 @@ public: REORGANIZE_PARTITION, SPLIT_PARTITION, FORCE_LOCALITY, + SHARDING, MAX_OPTION, }; uint64_t tenant_id_; @@ -3020,16 +3023,18 @@ public: ls_id_(), mode_version_(palf::INVALID_PROPOSAL_ID), access_mode_(palf::AccessMode::INVALID_ACCESS_MODE), - ref_scn_() {} + ref_scn_(), + addr_() {} ~ObLSAccessModeInfo() {} bool is_valid() const; int init(uint64_t tenant_id, const share::ObLSID &ls_idd, const int64_t mode_version, const palf::AccessMode &access_mode, - const share::SCN &ref_scn); + const share::SCN &ref_scn, + const ObAddr &addr); int assign(const ObLSAccessModeInfo &other); TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(mode_version), - K_(access_mode), K_(ref_scn)); + K_(access_mode), K_(ref_scn), K_(addr)); uint64_t get_tenant_id() const { return tenant_id_; @@ -3050,6 +3055,11 @@ public: { return ref_scn_; } + + const ObAddr &get_addr() const + { + return addr_; + } private: DISALLOW_COPY_AND_ASSIGN(ObLSAccessModeInfo); private: @@ -3058,6 +3068,7 @@ private: int64_t mode_version_; palf::AccessMode access_mode_; share::SCN ref_scn_; + ObAddr addr_; }; struct ObChangeLSAccessModeRes @@ -3184,6 +3195,7 @@ public: common::ObSArray table_schemas_; common::ObSArray tablets_; bool need_check_tablet_cnt_; + bool is_old_mds_; }; struct ObBatchRemoveTabletArg @@ -3203,6 +3215,7 @@ public: public: share::ObLSID id_; common::ObSArray tablet_ids_; + bool is_old_mds_; }; struct ObRemoveTabletRes @@ -3379,9 +3392,10 @@ public: source_table_id_ = other.source_table_id_; schema_version_ = other.schema_version_; task_id_ = other.task_id_; + tenant_id_ = other.tenant_id_; return ret; } - TO_STRING_KV(K_(task_id), K_(tablet_id), K_(target_table_id), K_(ret_code), K_(source_table_id), K_(schema_version)); + TO_STRING_KV(K_(task_id), K_(tablet_id), K_(target_table_id), K_(ret_code), K_(source_table_id), K_(schema_version), K_(tenant_id)); public: common::ObTabletID tablet_id_; uint64_t target_table_id_; @@ -3389,6 +3403,7 @@ public: int64_t source_table_id_; int64_t schema_version_; int64_t task_id_; + uint64_t tenant_id_; private: DISALLOW_COPY_AND_ASSIGN(ObCalcColumnChecksumResponseArg); }; @@ -3793,7 +3808,7 @@ public: public: bool is_valid() const; int assign(const ObBackupTaskRes &res); - TO_STRING_KV(K_(task_id), K_(job_id), K_(tenant_id), K_(src_server), K_(ls_id), K_(result), K_(trace_id)); + TO_STRING_KV(K_(task_id), K_(job_id), K_(tenant_id), K_(src_server), K_(ls_id), K_(result), K_(trace_id), K_(dag_id)); public: int64_t task_id_; int64_t job_id_; @@ -3802,6 +3817,7 @@ public: common::ObAddr src_server_; int result_; share::ObTaskId trace_id_; + share::ObTaskId dag_id_; }; struct ObBackupDataArg { @@ -3838,8 +3854,8 @@ public: share::ObBackupType::BackupType backup_type_; int64_t backup_date_; share::ObLSID ls_id_; - int64_t turn_id_; - int64_t retry_id_; + int64_t turn_id_; + int64_t retry_id_; common::ObAddr dst_server_; share::ObBackupPathString backup_path_; share::ObBackupDataType backup_data_type_; @@ -6480,6 +6496,64 @@ public: share::SCN cur_restore_source_max_scn_; }; +struct ObGetLSReplayedScnArg +{ + OB_UNIS_VERSION(1); +public: + ObGetLSReplayedScnArg(): tenant_id_(OB_INVALID_TENANT_ID), ls_id_() {} + ~ObGetLSReplayedScnArg() {} + bool is_valid() const; + int init(const uint64_t tenant_id, const share::ObLSID &ls_id); + int assign(const ObGetLSReplayedScnArg &other); + TO_STRING_KV(K_(tenant_id), K_(ls_id)); + + uint64_t get_tenant_id() const + { + return tenant_id_; + } + share::ObLSID get_ls_id() const + { + return ls_id_; + } +private: + DISALLOW_COPY_AND_ASSIGN(ObGetLSReplayedScnArg); +private: + uint64_t tenant_id_; + share::ObLSID ls_id_; +}; + +struct ObGetLSReplayedScnRes +{ + OB_UNIS_VERSION(1); +public: + ObGetLSReplayedScnRes(): tenant_id_(OB_INVALID_TENANT_ID), + ls_id_(), + cur_readable_scn_(share::SCN::min_scn()) {} + ~ObGetLSReplayedScnRes() {} + bool is_valid() const; + int init(const uint64_t tenant_id, const share::ObLSID &ls_id, const share::SCN &cur_readable_scn); + int assign(const ObGetLSReplayedScnRes &other); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(cur_readable_scn)); + uint64_t get_tenant_id() const + { + return tenant_id_; + } + share::ObLSID get_ls_id() const + { + return ls_id_; + } + share::SCN get_cur_readable_scn() const + { + return cur_readable_scn_; + } +private: + DISALLOW_COPY_AND_ASSIGN(ObGetLSReplayedScnRes); +private: + uint64_t tenant_id_; + share::ObLSID ls_id_; + share::SCN cur_readable_scn_; +}; + struct ObSwitchTenantArg { OB_UNIS_VERSION(1); @@ -8421,7 +8495,7 @@ struct ObRegisterTxDataArg public: ObRegisterTxDataArg() : tenant_id_(OB_INVALID_TENANT_ID), tx_desc_(nullptr), ls_id_(), - type_(transaction::ObTxDataSourceType::UNKNOWN), buf_(), request_id_(0) + type_(transaction::ObTxDataSourceType::UNKNOWN), buf_(), request_id_(0),register_flag_() {} ~ObRegisterTxDataArg() {} bool is_valid() const; @@ -8432,13 +8506,15 @@ public: const share::ObLSID &ls_id, const transaction::ObTxDataSourceType &type, const common::ObString &buf, - const int64_t base_request_id); + const int64_t base_request_id, + const transaction::ObRegisterMdsFlag ®ister_flag); TO_STRING_KV(K_(tenant_id), KPC_(tx_desc), K_(ls_id), K_(type), KP(buf_.length()), - K_(request_id)); + K_(request_id), + K_(register_flag)); public: uint64_t tenant_id_; @@ -8448,6 +8524,7 @@ public: common::ObString buf_; int64_t request_id_; + transaction::ObRegisterMdsFlag register_flag_; private: DISALLOW_COPY_AND_ASSIGN(ObRegisterTxDataArg); }; @@ -8882,6 +8959,47 @@ private: common::ObSArray servers_; }; +struct ObStartTransferTaskArg final +{ + OB_UNIS_VERSION(1); +public: + ObStartTransferTaskArg(): tenant_id_(OB_INVALID_TENANT_ID), task_id_(), dest_ls_() {} + ~ObStartTransferTaskArg() {} + int init(const uint64_t tenant_id, const share::ObTransferTaskID &task_id, const share::ObLSID &dest_ls); + uint64_t get_tenant_id() const { return tenant_id_; } + const share::ObTransferTaskID get_task_id() const { return task_id_; } + const share::ObLSID &get_dest_ls() { return dest_ls_; } + bool is_valid() const { return is_valid_tenant_id(tenant_id_) && task_id_.is_valid(); } + int assign(const ObStartTransferTaskArg &other); + TO_STRING_KV(K_(tenant_id), K_(task_id), K_(dest_ls)); + +private: + uint64_t tenant_id_; + share::ObTransferTaskID task_id_; + share::ObLSID dest_ls_; + + DISALLOW_COPY_AND_ASSIGN(ObStartTransferTaskArg); +}; + +struct ObFinishTransferTaskArg final +{ + OB_UNIS_VERSION(1); +public: + ObFinishTransferTaskArg(): task_id_() {} + int init(const uint64_t tenant_id, const share::ObTransferTaskID &task_id); + uint64_t get_tenant_id() const { return tenant_id_; } + const share::ObTransferTaskID get_task_id() const { return task_id_; } + bool is_valid() const { return is_valid_tenant_id(tenant_id_) && task_id_.is_valid(); } + int assign(const ObFinishTransferTaskArg &other); + TO_STRING_KV(K_(tenant_id), K_(task_id)); + +private: + uint64_t tenant_id_; + share::ObTransferTaskID task_id_; + + DISALLOW_COPY_AND_ASSIGN(ObFinishTransferTaskArg); +}; + struct ObSyncRewriteRuleArg { diff --git a/src/share/ob_share_util.cpp b/src/share/ob_share_util.cpp index eed145a66..71e18c1c0 100644 --- a/src/share/ob_share_util.cpp +++ b/src/share/ob_share_util.cpp @@ -18,6 +18,7 @@ #include "lib/oblog/ob_log_module.h" #include "share/ob_cluster_version.h" // for GET_MIN_DATA_VERSION #include "lib/mysqlclient/ob_isql_client.h" +#include "observer/omt/ob_tenant_config_mgr.h" // ObTenantConfigGuard namespace oceanbase { @@ -270,5 +271,20 @@ int ObShareUtil::parse_all_server_list( } return ret; } + +bool ObShareUtil::is_tenant_enable_rebalance(const uint64_t tenant_id) +{ + bool bret = false; + if (is_valid_tenant_id(tenant_id)) { + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); + if (OB_UNLIKELY(!tenant_config.is_valid())) { + LOG_WARN_RET(OB_ERR_UNEXPECTED, "tenant config is invalid", K(tenant_id)); + } else { + bret = tenant_config->enable_rebalance; + } + } + return bret; +} + } //end namespace share } //end namespace oceanbase diff --git a/src/share/ob_share_util.h b/src/share/ob_share_util.h index fd9cd8d11..07a8b92d4 100644 --- a/src/share/ob_share_util.h +++ b/src/share/ob_share_util.h @@ -60,12 +60,15 @@ public: common::ObISQLClient &client, const uint64_t tenant_id, uint64_t &data_version); + // parse GCONF.all_server_list // @params[in] excluded_server_list, servers which will not be included in the output // @params[out] config_all_server_list, servers in (GCONF.all_server_list - excluded_server_list) static int parse_all_server_list( const ObArray &excluded_server_list, ObArray &config_all_server_list); + + static bool is_tenant_enable_rebalance(const uint64_t tenant_id); }; }//end namespace share }//end namespace oceanbase diff --git a/src/share/ob_srv_rpc_proxy.h b/src/share/ob_srv_rpc_proxy.h old mode 100644 new mode 100755 index 4d94e69d3..cfdda9dce --- a/src/share/ob_srv_rpc_proxy.h +++ b/src/share/ob_srv_rpc_proxy.h @@ -16,6 +16,7 @@ #include "sql/engine/cmd/ob_kill_session_arg.h" #include "storage/tablelock/ob_table_lock_rpc_struct.h" #include "rpc/obrpc/ob_rpc_proxy.h" +#include "share/ob_common_id.h" #include "share/ob_rpc_struct.h" #include "observer/ob_server_struct.h" #include "observer/net/ob_net_endpoint_ingress_rpc_struct.h" @@ -65,8 +66,10 @@ public: RPC_S(PR5 backup_completing_log, OB_BACKUP_COMPL_LOG, (ObBackupComplLogArg)); RPC_S(PR5 backup_build_index, OB_BACKUP_BUILD_INDEX, (ObBackupBuildIdxArg)); RPC_S(PR5 backup_meta, OB_BACKUP_META, (ObBackupMetaArg)); - RPC_S(PR5 check_not_backup_tablet_create_scn, OB_BACKUP_CHECK_TABLET_CREATE_TS, (ObBackupCheckTabletArg)); RPC_S(PR5 check_backup_task_exist, OB_CHECK_BACKUP_TASK_EXIST, (ObBackupCheckTaskArg), obrpc::Bool); + RPC_S(PR5 report_backup_over, OB_BACKUP_LS_DATA_RES, (ObBackupTaskRes)); + RPC_S(PR5 report_backup_clean_over, OB_DELETE_BACKUP_LS_TASK_RES, (ObBackupTaskRes)); + // ls disaster recovery rpc RPC_S(PR5 ls_migrate_replica, OB_LS_MIGRATE_REPLICA, (ObLSMigrateReplicaArg)); RPC_S(PR5 ls_add_replica, OB_LS_ADD_REPLICA, (ObLSAddReplicaArg)); @@ -94,6 +97,7 @@ public: RPC_S(PR5 is_empty_server, OB_IS_EMPTY_SERVER, (ObCheckServerEmptyArg), Bool); RPC_S(PR5 check_server_for_adding_server, OB_CHECK_SERVER_FOR_ADDING_SERVER, (ObCheckServerForAddingServerArg), ObCheckServerForAddingServerResult); RPC_S(PR5 check_deployment_mode_match, OB_CHECK_DEPLOYMENT_MODE, (ObCheckDeploymentModeArg), Bool); + RPC_S(PR5 notify_create_tenant_user_ls, OB_NOTIFY_CREATE_TENANT_USER_LS, (obrpc::UInt64)); RPC_S(PR5 report_replica, OB_REPORT_REPLICA); RPC_S(PR5 recycle_replica, OB_RECYCLE_REPLICA); RPC_S(PR5 clear_location_cache, OB_CLEAR_LOCATION_CACHE); @@ -184,9 +188,13 @@ public: RPC_AP(PR1 get_ls_access_mode, OB_GET_LS_ACCESS_MODE, (obrpc::ObGetLSAccessModeInfoArg), obrpc::ObLSAccessModeInfo); RPC_AP(PR1 change_ls_access_mode, OB_CHANGE_LS_ACCESS_MODE, (obrpc::ObLSAccessModeInfo), obrpc::ObChangeLSAccessModeRes); RPC_S(PR5 estimate_tablet_block_count, OB_ESTIMATE_TABLET_BLOCK_COUNT, (ObEstBlockArg), ObEstBlockRes); + RPC_S(PR5 gen_unique_id, OB_GEN_UNIQUE_ID, (obrpc::UInt64), share::ObCommonID); + RPC_S(PR5 start_transfer_task, OB_START_TRANSFER_TASK, (ObStartTransferTaskArg)); + RPC_S(PR5 finish_transfer_task, OB_FINISH_TRANSFER_TASK, (ObFinishTransferTaskArg)); RPC_AP(PR1 get_ls_sync_scn, OB_GET_LS_SYNC_SCN, (obrpc::ObGetLSSyncScnArg), obrpc::ObGetLSSyncScnRes); RPC_AP(PR5 refresh_tenant_info, OB_REFRESH_TENANT_INFO, (obrpc::ObRefreshTenantInfoArg), obrpc::ObRefreshTenantInfoRes); RPC_S(PR5 sync_rewrite_rules, OB_SYNC_REWRITE_RULES, (ObSyncRewriteRuleArg)); + RPC_AP(PR1 get_ls_replayed_scn, OB_GET_LS_REPLAYED_SCN, (ObGetLSReplayedScnArg), obrpc::ObGetLSReplayedScnRes); RPC_S(PR5 force_set_ls_as_single_replica, OB_LOG_FORCE_SET_LS_AS_SINGLE_REPLICA, (obrpc::ObForceSetLSAsSingleReplicaArg)); RPC_AP(PR5 net_endpoint_predict_ingress, OB_PREDICT_INGRESS_BW, (obrpc::ObNetEndpointPredictIngressArg), obrpc::ObNetEndpointPredictIngressRes); RPC_AP(PR5 net_endpoint_set_ingress, OB_SET_INGRESS_BW, (obrpc::ObNetEndpointSetIngressArg), obrpc::ObNetEndpointSetIngressRes); diff --git a/src/share/ob_table_access_helper.h b/src/share/ob_table_access_helper.h index b732017ae..35d15e68b 100644 --- a/src/share/ob_table_access_helper.h +++ b/src/share/ob_table_access_helper.h @@ -211,7 +211,7 @@ public: condition, output_array); } - template + template static int read_multi_row(const uint64_t tenant_id, const std::initializer_list &columns, const ObString &table, @@ -556,6 +556,19 @@ private: } return ret; } + static int get_signle_column_from_signle_row_(common::sqlclient::ObMySQLResult *row, + const char *column, + uint64_t &value) + { + TIMEGUARD_INIT(OCCAM, 1_s, 60_s); + int ret = common::OB_SUCCESS; + if (CLICK_FAIL(row->get_uint(column, value))) { + OB_LOG(WARN, "get_column_from_signle_row failed", KR(ret), K(MTL_ID()), K(column)); + } else { + OB_LOG(TRACE, "get_column_from_signle_row success", KR(ret), K(MTL_ID()), K(column), K(value)); + } + return ret; + } static int get_signle_column_from_signle_row_(common::sqlclient::ObMySQLResult *row, const char *column, ObStringHolder &value) diff --git a/src/share/ob_tablet_autoincrement_param.cpp b/src/share/ob_tablet_autoincrement_param.cpp index 9e867d8d9..e529c551b 100644 --- a/src/share/ob_tablet_autoincrement_param.cpp +++ b/src/share/ob_tablet_autoincrement_param.cpp @@ -65,62 +65,112 @@ OB_SERIALIZE_MEMBER(ObTabletAutoincParam, OB_SERIALIZE_MEMBER(ObMigrateTabletAutoincSeqParam, src_tablet_id_, dest_tablet_id_, ret_code_, autoinc_seq_); -ObTabletAutoincSeq::ObTabletAutoincSeq() : intervals_() + +ObTabletAutoincSeq::ObTabletAutoincSeq() + : version_(AUTOINC_SEQ_VERSION), + allocator_(nullptr), + intervals_(nullptr), + intervals_count_(0) { - intervals_.set_attr(ObMemAttr(OB_SERVER_TENANT_ID, "TabletAutoInc")); } -int ObTabletAutoincSeq::assign(const ObTabletAutoincSeq &other) +ObTabletAutoincSeq::~ObTabletAutoincSeq() +{ + reset(); +} + +int ObTabletAutoincSeq::assign(common::ObIAllocator &allocator, const ObTabletAutoincSeq &other) { int ret = OB_SUCCESS; - if (OB_FAIL(intervals_.assign(other.intervals_))) { - LOG_WARN("failed to assign intervals", K(ret)); + + if (this != &other) { + reset(); + + void *buf = nullptr; + if (0 == other.intervals_count_) { + LOG_DEBUG("intervals count equals 0", K(ret)); + } else if (OB_ISNULL(buf = allocator.alloc(other.intervals_count_ * sizeof(ObTabletAutoincInterval)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc memory failed", K(ret)); + } else { + allocator_ = &allocator; + intervals_count_ = other.intervals_count_; + intervals_ = new (buf) ObTabletAutoincInterval[other.intervals_count_](); + for (int64_t i = 0; i < other.intervals_count_; ++i) { + intervals_[i] = other.intervals_[i]; + } + } + + if (OB_FAIL(ret)) { + reset(); + } + } + + return ret; +} + +int ObTabletAutoincSeq::deep_copy( + char *buf, + const int64_t buf_size, + ObIStorageMetaObj *&value) const +{ + int ret = OB_SUCCESS; + value = nullptr; + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_size < get_deep_copy_size())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invaild argument", K(ret), KP(buf), K(buf_size), K(get_deep_copy_size())); + } else { + ObTabletAutoincSeq *new_seq = new (buf) ObTabletAutoincSeq(); + new_seq->intervals_ = new (buf + sizeof(ObTabletAutoincSeq)) ObTabletAutoincInterval[intervals_count_](); + for (int64_t i = 0; i < intervals_count_; ++i) { + new_seq->intervals_[i] = intervals_[i]; + } + new_seq->intervals_count_ = intervals_count_; + new_seq->allocator_ = nullptr; + + if (OB_SUCC(ret)) { + value = new_seq; + } } return ret; } int ObTabletAutoincSeq::deep_copy(const ObIMultiSourceDataUnit *src, ObIAllocator *allocator) { - UNUSED(allocator); - int ret = OB_SUCCESS; - if (OB_ISNULL(src)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid src info", K(ret)); - } else if (OB_UNLIKELY(src->type() != type())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid type", K(ret)); - } else if (OB_FAIL(assign(*static_cast(src)))) { - LOG_WARN("failed to copy tablet autoinc seq", K(ret)); - } + int ret = OB_NOT_SUPPORTED; + return ret; } void ObTabletAutoincSeq::reset() { - intervals_.reset(); + if (0 != intervals_count_ && nullptr != intervals_) { + for (int64_t i = 0; i < intervals_count_ ; ++i) { + intervals_[i].~ObTabletAutoincInterval(); + } + if (OB_NOT_NULL(allocator_)) { + allocator_->free(intervals_); + allocator_ = nullptr; + } + intervals_ = nullptr; + } + intervals_count_ = 0; } bool ObTabletAutoincSeq::is_valid() const { - bool valid = true; - - if (intervals_.empty()) { - valid = false; - } - // TODO(shuangcan.yjw): verify elemetns in array - - return valid; + return 0 != intervals_count_ && nullptr != intervals_; } int ObTabletAutoincSeq::get_autoinc_seq_value(uint64_t &autoinc_seq) { int ret = OB_SUCCESS; - if (intervals_.count() == 0) { + if (0 == intervals_count_) { autoinc_seq = 1; - } else if (intervals_.count() == 1) { + } else if (1 == intervals_count_) { // currently, there will only be one interval - for (int64_t i = 0; OB_SUCC(ret) && i < intervals_.count(); i++) { - const ObTabletAutoincInterval &interval = intervals_.at(i); + for (int64_t i = 0; OB_SUCC(ret) && i < intervals_count_; i++) { + const ObTabletAutoincInterval &interval = intervals_[i]; if (interval.end_ > interval.start_) { autoinc_seq = interval.start_; break; @@ -133,19 +183,25 @@ int ObTabletAutoincSeq::get_autoinc_seq_value(uint64_t &autoinc_seq) return ret; } -int ObTabletAutoincSeq::set_autoinc_seq_value(const uint64_t autoinc_seq) +int ObTabletAutoincSeq::set_autoinc_seq_value( + common::ObArenaAllocator &allocator, + const uint64_t autoinc_seq) { int ret = OB_SUCCESS; - // currently, there will only be one interval - if (intervals_.count() == 0) { + if (0 == intervals_count_) { ObTabletAutoincInterval interval; interval.start_ = autoinc_seq; interval.end_ = INT64_MAX; - if (OB_FAIL(intervals_.push_back(interval))) { - LOG_WARN("failed to push autoinc interval", K(ret)); + intervals_count_ = 1; + void *buf = nullptr; + if(OB_ISNULL(buf = allocator.alloc(sizeof(share::ObTabletAutoincInterval) * intervals_count_))) { + LOG_WARN("fail to allocate memory", K(ret)); + } else { + intervals_ = new (buf) ObTabletAutoincInterval[intervals_count_]; + intervals_[intervals_count_ - 1] = interval; } - } else if (intervals_.count() == 1) { - intervals_.at(0).start_ = autoinc_seq; + } else if (1 == intervals_count_) { + intervals_[0].start_ = autoinc_seq; } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected autoinc seq interval count", K(ret)); @@ -153,7 +209,107 @@ int ObTabletAutoincSeq::set_autoinc_seq_value(const uint64_t autoinc_seq) return ret; } -OB_SERIALIZE_MEMBER(ObTabletAutoincSeq, intervals_); +int ObTabletAutoincSeq::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + OB_UNIS_ENCODE(AUTOINC_SEQ_VERSION); + if (OB_SUCC(ret)) { + int64_t size_nbytes = NS_::OB_SERIALIZE_SIZE_NEED_BYTES; + int64_t pos_bak = (pos += size_nbytes); + if (OB_SUCC(ret)) { + if (OB_FAIL(serialize_(buf, buf_len, pos))) { + LOG_WARN("fail to serialize", K(ret), KP(buf), K(buf_len), K(pos)); + } + } + + if (OB_SUCC(ret)) { + int64_t serial_size = pos - pos_bak; + int64_t tmp_pos = 0; + int64_t expect_size = get_serialize_size_(); + if (expect_size < serial_size) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expect size < serial size", K(ret), KP(expect_size), K(serial_size)); + } else { + ret = common::serialization::encode_fixed_bytes_i64(buf + pos_bak - size_nbytes, size_nbytes, tmp_pos, serial_size); + } + } + } + return ret; +} + +int ObTabletAutoincSeq::serialize_(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + OB_UNIS_ENCODE_ARRAY(intervals_, intervals_count_); + return ret; +} + +// multi source deserialize with ObIAllocator. +int ObTabletAutoincSeq::deserialize( + common::ObIAllocator &allocator, + const char *buf, + const int64_t data_len, + int64_t &pos) +{ + int ret = OB_SUCCESS; + int64_t len = 0; + OB_UNIS_DECODEx(version_); + OB_UNIS_DECODEx(len); + if (OB_SUCC(ret)) { + int64_t tmp_pos = 0; + if (OB_FAIL(deserialize_(allocator, buf + pos, len, tmp_pos))) { + LOG_WARN("fail to deserialize", K(ret), "slen", len, K(pos)); + } else if (OB_UNLIKELY(len != tmp_pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("deserialize length is not correct", K(ret), K(len), K(pos)); + } else { + pos = pos + tmp_pos; + } + } + return ret; +} + +int ObTabletAutoincSeq::deserialize_(common::ObIAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + void *ptr = nullptr; + if (OB_FAIL(serialization::decode_vi64(buf, data_len, pos, &intervals_count_))) { + LOG_WARN("fail to decode ob array count", K(ret)); + } else if (0 == intervals_count_) { + LOG_DEBUG("intervals count equals 0", K(ret), K_(intervals_count)); + } else if (OB_ISNULL(ptr = allocator.alloc(intervals_count_ * sizeof(ObTabletAutoincInterval)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc memory failed", K(ret), K(intervals_count_)); + } else { + allocator_ = &allocator; + intervals_ = new (ptr) ObTabletAutoincInterval[intervals_count_]; + for (int64_t i = 0; OB_SUCC(ret) && i < intervals_count_; i++) { + ObTabletAutoincInterval &item = intervals_[i]; + if (OB_FAIL(item.deserialize(buf, data_len, pos))) { + LOG_WARN("fail to decode array item", K(ret), K(i), K_(intervals_count), K(item)); + } + } + } + + if (OB_FAIL(ret)) { + reset(); + } + return ret; +} + +int64_t ObTabletAutoincSeq::get_serialize_size() const +{ + int64_t len = get_serialize_size_(); + SERIALIZE_SIZE_HEADER(version_); + return len; +} + +int64_t ObTabletAutoincSeq::get_serialize_size_(void) const +{ + int64_t len = 0; + OB_UNIS_ADD_LEN_ARRAY(intervals_, intervals_count_); + return len; +} }// end namespace share }// end namespace oceanbase diff --git a/src/share/ob_tablet_autoincrement_param.h b/src/share/ob_tablet_autoincrement_param.h index 65fd592a2..9a2394734 100644 --- a/src/share/ob_tablet_autoincrement_param.h +++ b/src/share/ob_tablet_autoincrement_param.h @@ -19,6 +19,7 @@ #include "common/object/ob_obj_type.h" #include "common/ob_tablet_id.h" #include "storage/memtable/ob_multi_source_data.h" +#include "storage/meta_mem/ob_storage_meta_cache.h" namespace oceanbase { @@ -153,31 +154,68 @@ public: uint64_t autoinc_seq_; }; -class ObTabletAutoincSeq : public memtable::ObIMultiSourceDataUnit +class ObTabletAutoincSeq : public memtable::ObIMultiSourceDataUnit, public storage::ObIStorageMetaObj { public: - OB_UNIS_VERSION_V(1); + //friend class ObTabletAutoincSeqMdsUserData; + const int32_t AUTOINC_SEQ_VERSION = 1; public: ObTabletAutoincSeq(); - ~ObTabletAutoincSeq() - { - reset(); - } - int assign(const ObTabletAutoincSeq &other); + ~ObTabletAutoincSeq(); + + int assign(common::ObIAllocator &allocator, const ObTabletAutoincSeq &other); + // Only for old multi_data_source + // Free origin data with allocator and alloc new. + // TODO yq: remove later virtual int deep_copy(const ObIMultiSourceDataUnit *src, ObIAllocator *allocator) override; + virtual int deep_copy( + char *dst_buf, + const int64_t buf_size, + storage::ObIStorageMetaObj *&value) const; + virtual int64_t get_deep_copy_size() const { return sizeof(ObTabletAutoincSeq) + sizeof(ObTabletAutoincInterval) * intervals_count_; } virtual void reset() override; virtual bool is_valid() const override; - virtual inline int64_t get_data_size() const override { return sizeof(ObTabletAutoincSeq); } + virtual inline int64_t get_data_size() const override { return get_deep_copy_size(); } virtual inline memtable::MultiSourceDataUnitType type() const override { return memtable::MultiSourceDataUnitType::TABLET_SEQ; } int get_autoinc_seq_value(uint64_t &autoinc_seq); - int set_autoinc_seq_value(const uint64_t autoinc_seq); - const common::ObSArray &get_intervals() const { return intervals_; } - TO_STRING_KV(K_(intervals)); + int set_autoinc_seq_value( + common::ObArenaAllocator &allocator, + const uint64_t autoinc_seq); + const share::ObTabletAutoincInterval* get_intervals() const { return intervals_; } + int64_t get_intervals_count() const { return intervals_count_; } + + int serialize( + char *buf, + const int64_t buf_len, + int64_t &pos) const; + // multi source deserialize with ObIAllocator, will set allocator_ + int deserialize( + common::ObIAllocator &allocator, + const char *buf, + const int64_t data_len, + int64_t &pos); + int64_t get_serialize_size() const; + + TO_STRING_KV(K_(version), K_(intervals_count), KPC_(intervals)); private: - common::ObSArray intervals_; + int deserialize_( + common::ObIAllocator &allocator, + const char *buf, + const int64_t data_len, + int64_t &pos); + int serialize_( + char *buf, + const int64_t buf_len, + int64_t &pos) const; + int64_t get_serialize_size_(void) const; +private: + int64_t version_; + ObIAllocator *allocator_; + share::ObTabletAutoincInterval *intervals_; + int64_t intervals_count_; DISALLOW_COPY_AND_ASSIGN(ObTabletAutoincSeq); }; diff --git a/src/share/ob_tablet_autoincrement_service.cpp b/src/share/ob_tablet_autoincrement_service.cpp index 76a9e54e3..d501cfe14 100644 --- a/src/share/ob_tablet_autoincrement_service.cpp +++ b/src/share/ob_tablet_autoincrement_service.cpp @@ -345,206 +345,5 @@ int ObTabletAutoincrementService::get_tablet_cache_interval(const uint64_t tenan return ret; } - -ObTabletAutoincSeqRpcHandler::ObTabletAutoincSeqRpcHandler() - : is_inited_(false), bucket_lock_() -{ -} - -ObTabletAutoincSeqRpcHandler::~ObTabletAutoincSeqRpcHandler() -{ -} - -ObTabletAutoincSeqRpcHandler &ObTabletAutoincSeqRpcHandler::get_instance() -{ - static ObTabletAutoincSeqRpcHandler autoinc_rpc_handler; - return autoinc_rpc_handler; -} - -int ObTabletAutoincSeqRpcHandler::init() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(bucket_lock_.init(BUCKET_LOCK_BUCKET_CNT))) { - LOG_WARN("fail to init bucket lock", K(ret)); - } else { - is_inited_ = true; - } - return ret; -} - -int ObTabletAutoincSeqRpcHandler::fetch_tablet_autoinc_seq_cache( - const ObFetchTabletSeqArg &arg, - ObFetchTabletSeqRes &res) -{ - int ret = OB_SUCCESS; - uint64_t tenant_id = arg.tenant_id_; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - MTL_SWITCH(tenant_id) { - ObLSHandle ls_handle; - share::ObLSID ls_id = arg.ls_id_; - ObRole role = common::INVALID_ROLE; - ObTabletHandle tablet_handle; - ObTabletAutoincInterval autoinc_interval; - const ObTabletID &tablet_id = arg.tablet_id_; - int64_t proposal_id = -1; - ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); - if (OB_FAIL(MTL(logservice::ObLogService*)->get_palf_role(ls_id, role, proposal_id))) { - LOG_WARN("get palf role failed", K(ret)); - } else if (!is_strong_leader(role)) { - ret = OB_NOT_MASTER; - LOG_WARN("follwer received FetchTabletsSeq rpc", K(ret), K(ls_id)); - } else if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { - LOG_WARN("get ls failed", K(ret), K(ls_id)); - } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle))) { - LOG_WARN("failed to get tablet", KR(ret), K(arg)); - } else if (OB_FAIL(tablet_handle.get_obj()->fetch_tablet_autoinc_seq_cache( - arg.cache_size_, autoinc_interval))) { - LOG_WARN("failed to fetch tablet autoinc seq on tablet", K(ret), K(tablet_id)); - } else { - res.cache_interval_ = autoinc_interval; - } - } - } - return ret; -} - -int ObTabletAutoincSeqRpcHandler::batch_get_tablet_autoinc_seq( - const obrpc::ObBatchGetTabletAutoincSeqArg &arg, - obrpc::ObBatchGetTabletAutoincSeqRes &res) -{ - int ret = OB_SUCCESS; - uint64_t tenant_id = arg.tenant_id_; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(arg)); - } else { - MTL_SWITCH(tenant_id) { - ObLSHandle ls_handle; - share::ObLSID ls_id = arg.ls_id_; - ObRole role = common::INVALID_ROLE; - int64_t proposal_id = -1; - if (OB_FAIL(MTL(logservice::ObLogService*)->get_palf_role(ls_id, role, proposal_id))) { - LOG_WARN("get palf role failed", K(ret)); - } else if (!is_strong_leader(role)) { - ret = OB_NOT_MASTER; - LOG_WARN("follwer received FetchTabletsSeq rpc", K(ret), K(ls_id)); - } else if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { - LOG_WARN("get ls failed", K(ret), K(ls_id)); - } else if (OB_FAIL(res.autoinc_params_.reserve(arg.src_tablet_ids_.count()))) { - LOG_WARN("failed to reserve autoinc param", K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < arg.src_tablet_ids_.count(); i++) { - int tmp_ret = OB_SUCCESS; - const ObTabletID &src_tablet_id = arg.src_tablet_ids_.at(i); - ObTabletHandle tablet_handle; - share::ObMigrateTabletAutoincSeqParam autoinc_param; - autoinc_param.src_tablet_id_ = src_tablet_id; - autoinc_param.dest_tablet_id_ = arg.dest_tablet_ids_.at(i); - ObBucketHashRLockGuard lock_guard(bucket_lock_, src_tablet_id.hash()); - ObTabletAutoincSeq autoinc_seq; - if (OB_TMP_FAIL(ls_handle.get_ls()->get_tablet(src_tablet_id, tablet_handle))) { - LOG_WARN("failed to get tablet", K(tmp_ret), K(src_tablet_id)); - } else if (OB_TMP_FAIL(tablet_handle.get_obj()->get_latest_autoinc_seq(autoinc_seq))) { - LOG_WARN("failed to get latest autoinc seq", K(tmp_ret)); - } else if (OB_TMP_FAIL(autoinc_seq.get_autoinc_seq_value(autoinc_param.autoinc_seq_))) { - LOG_WARN("failed to get autoinc seq value", K(tmp_ret)); - } - autoinc_param.ret_code_ = tmp_ret; - if (OB_FAIL(res.autoinc_params_.push_back(autoinc_param))) { - LOG_WARN("failed to push autoinc param", K(ret), K(autoinc_param)); - } - } - } - } - } - return ret; -} - -int ObTabletAutoincSeqRpcHandler::batch_set_tablet_autoinc_seq( - const obrpc::ObBatchSetTabletAutoincSeqArg &arg, - obrpc::ObBatchSetTabletAutoincSeqRes &res) -{ - int ret = OB_SUCCESS; - uint64_t tenant_id = arg.tenant_id_; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(arg)); - } else if (OB_FAIL(res.autoinc_params_.assign(arg.autoinc_params_))) { - LOG_WARN("failed to assign autoinc params", K(ret), K(arg)); - } else { - MTL_SWITCH(tenant_id) { - ObLSHandle ls_handle; - ObLS *ls = nullptr; - share::ObLSID ls_id = arg.ls_id_; - ObRole role = common::INVALID_ROLE; - int64_t proposal_id = -1; - if (OB_FAIL(MTL(logservice::ObLogService*)->get_palf_role(ls_id, role, proposal_id))) { - LOG_WARN("get palf role failed", K(ret)); - } else if (!is_strong_leader(role)) { - ret = OB_NOT_MASTER; - LOG_WARN("follwer received FetchTabletsSeq rpc", K(ret), K(ls_id)); - } else if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { - LOG_WARN("get ls failed", K(ret), K(ls_id)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < res.autoinc_params_.count(); i++) { - int tmp_ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - share::ObMigrateTabletAutoincSeqParam &autoinc_param = res.autoinc_params_.at(i); - ObBucketHashWLockGuard lock_guard(bucket_lock_, autoinc_param.dest_tablet_id_.hash()); - if (OB_TMP_FAIL(ls_handle.get_ls()->get_tablet(autoinc_param.dest_tablet_id_, tablet_handle))) { - LOG_WARN("failed to get tablet", K(tmp_ret), K(autoinc_param)); - } else if (OB_TMP_FAIL(tablet_handle.get_obj()->update_tablet_autoinc_seq(autoinc_param.autoinc_seq_, - SCN::max_scn()))) { - LOG_WARN("failed to update tablet autoinc seq", K(tmp_ret), K(autoinc_param)); - } - autoinc_param.ret_code_ = tmp_ret; - } - } - } - } - return ret; -} - -int ObTabletAutoincSeqRpcHandler::replay_update_tablet_autoinc_seq( - const ObLS *ls, - const ObTabletID &tablet_id, - const uint64_t autoinc_seq, - const SCN &replay_scn) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(ls == nullptr || !tablet_id.is_valid() || autoinc_seq == 0 || !replay_scn.is_valid_and_not_min())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tablet_id), K(autoinc_seq), K(replay_scn)); - } else { - ObTabletHandle tablet_handle; - ObBucketHashWLockGuard guard(bucket_lock_, tablet_id.hash()); - if (OB_FAIL(ls->replay_get_tablet(tablet_id, - replay_scn, - tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - LOG_INFO("tablet may be deleted, skip this log", K(ret), K(tablet_id), K(replay_scn)); - ret = OB_SUCCESS; - } else if (OB_EAGAIN == ret) { - // retry replay again - } else { - LOG_WARN("fail to replay get tablet, retry again", K(ret), K(tablet_id), K(replay_scn)); - ret = OB_EAGAIN; - } - } else if (OB_FAIL(tablet_handle.get_obj()->update_tablet_autoinc_seq(autoinc_seq, replay_scn))) { - LOG_WARN("failed to update tablet auto inc seq", K(ret), K(autoinc_seq), K(replay_scn)); - } - } - return ret; -} - } } diff --git a/src/share/ob_tablet_autoincrement_service.h b/src/share/ob_tablet_autoincrement_service.h index f046ea61c..c42f55052 100644 --- a/src/share/ob_tablet_autoincrement_service.h +++ b/src/share/ob_tablet_autoincrement_service.h @@ -121,33 +121,6 @@ private: lib::ObMutex init_node_mutexs_[INIT_NODE_MUTEX_NUM]; }; -class ObTabletAutoincSeqRpcHandler final -{ -public: - static ObTabletAutoincSeqRpcHandler &get_instance(); - int init(); - int fetch_tablet_autoinc_seq_cache( - const obrpc::ObFetchTabletSeqArg &arg, - obrpc::ObFetchTabletSeqRes &res); - int batch_get_tablet_autoinc_seq( - const obrpc::ObBatchGetTabletAutoincSeqArg &arg, - obrpc::ObBatchGetTabletAutoincSeqRes &res); - int batch_set_tablet_autoinc_seq( - const obrpc::ObBatchSetTabletAutoincSeqArg &arg, - obrpc::ObBatchSetTabletAutoincSeqRes &res); - int replay_update_tablet_autoinc_seq( - const ObLS *ls, - const ObTabletID &tablet_id, - const uint64_t autoinc_seq, - const SCN &replay_scn); -private: - ObTabletAutoincSeqRpcHandler(); - ~ObTabletAutoincSeqRpcHandler(); -private: - static const int64_t BUCKET_LOCK_BUCKET_CNT = 10243L; - bool is_inited_; - common::ObBucketLock bucket_lock_; -}; } // end namespace share } // end namespace oceanbase diff --git a/src/share/ob_tenant_info_proxy.cpp b/src/share/ob_tenant_info_proxy.cpp old mode 100644 new mode 100755 index af2557073..6f5197232 --- a/src/share/ob_tenant_info_proxy.cpp +++ b/src/share/ob_tenant_info_proxy.cpp @@ -18,6 +18,11 @@ #include "share/config/ob_server_config.h"//GCONF #include "share/inner_table/ob_inner_table_schema.h"//ALL_TENANT_INFO_TNAME #include "share/ls/ob_ls_i_life_manager.h"//TODO SCN VALUE +#include "share/ls/ob_ls_status_operator.h"//get_tenant max ls id +#include "lib/string/ob_sql_string.h"//ObSqlString +#include "lib/mysqlclient/ob_mysql_transaction.h"//ObMySQLTrans +#include "common/ob_timeout_ctx.h"//ObTimeoutCtx +#include "ob_tenant_info_proxy.h" #include "share/ls/ob_ls_recovery_stat_operator.h"//ObLSRecoveryStatOperator #include "lib/string/ob_sql_string.h"//ObSqlString #include "lib/mysqlclient/ob_mysql_transaction.h"//ObMySQLTrans @@ -56,7 +61,6 @@ SCN gen_new_standby_scn(const SCN &cur_standby_scn, const SCN &desired_standby_s { return MIN(MAX(cur_standby_scn, desired_standby_scn), new_replayable_scn); } - ////////////ObAllTenantInfo DEFINE_TO_YSON_KV(ObAllTenantInfo, OB_ID(tenant_id), tenant_id_, @@ -91,7 +95,8 @@ int ObAllTenantInfo::init( const SCN &replayable_scn, const SCN &standby_scn, const SCN &recovery_until_scn, - const ObArchiveMode &log_mode) + const ObArchiveMode &log_mode, + const share::ObLSID &max_ls_id) { int ret = OB_SUCCESS; if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id @@ -103,11 +108,12 @@ int ObAllTenantInfo::init( || !standby_scn.is_valid_and_not_min() || !recovery_until_scn.is_valid_and_not_min() || !log_mode.is_valid() - || !is_valid_tenant_scn(sync_scn, replayable_scn, standby_scn, recovery_until_scn))) { + || !is_valid_tenant_scn(sync_scn, replayable_scn, standby_scn, recovery_until_scn) + || !max_ls_id.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_role), K(switchover_status), K(switchover_epoch), K(sync_scn), K(replayable_scn), K(standby_scn), K(recovery_until_scn), - K(log_mode)); + K(log_mode), K(max_ls_id)); } else { tenant_id_ = tenant_id; tenant_role_ = tenant_role; @@ -118,6 +124,7 @@ int ObAllTenantInfo::init( standby_scn_ = standby_scn; recovery_until_scn_ = recovery_until_scn; log_mode_ = log_mode; + max_ls_id_ = max_ls_id; } return ret; } @@ -135,6 +142,7 @@ void ObAllTenantInfo::assign(const ObAllTenantInfo &other) standby_scn_ = other.standby_scn_; recovery_until_scn_ = other.recovery_until_scn_; log_mode_ = other.log_mode_; + max_ls_id_ = other.max_ls_id_; } return ; } @@ -150,10 +158,13 @@ void ObAllTenantInfo::reset() standby_scn_.set_min() ; recovery_until_scn_.set_min(); log_mode_.reset(); + max_ls_id_.reset(); } + OB_SERIALIZE_MEMBER(ObAllTenantInfo, tenant_id_, tenant_role_, switchover_status_, switchover_epoch_, sync_scn_, - replayable_scn_, standby_scn_, recovery_until_scn_, log_mode_); + replayable_scn_, standby_scn_, recovery_until_scn_, log_mode_, + max_ls_id_); ObAllTenantInfo& ObAllTenantInfo::operator= (const ObAllTenantInfo &other) { @@ -188,8 +199,8 @@ int ObAllTenantInfoProxy::init_tenant_info( } else if (OB_FAIL(sql.assign_fmt( "insert into %s (tenant_id, tenant_role, " "switchover_status, switchover_epoch, " - "sync_scn, replayable_scn, readable_scn, recovery_until_scn, log_mode) " - "values(%lu, '%s', '%s', %ld, %lu, %lu, %lu, %lu, '%s')", + "sync_scn, replayable_scn, readable_scn, recovery_until_scn, log_mode, max_ls_id) " + "values(%lu, '%s', '%s', %ld, %lu, %lu, %lu, %lu, '%s', %ld)", OB_ALL_TENANT_INFO_TNAME, tenant_info.get_tenant_id(), tenant_info.get_tenant_role().to_str(), tenant_info.get_switchover_status().to_str(), @@ -198,7 +209,8 @@ int ObAllTenantInfoProxy::init_tenant_info( tenant_info.get_replayable_scn().get_val_for_inner_table_field(), tenant_info.get_standby_scn().get_val_for_inner_table_field(), tenant_info.get_recovery_until_scn().get_val_for_inner_table_field(), - tenant_info.get_log_mode().to_str()))) { + tenant_info.get_log_mode().to_str(), + tenant_info.get_max_ls_id().id()))) { LOG_WARN("failed to assign sql", KR(ret), K(tenant_info), K(sql)); } else if (OB_FAIL(proxy->write(exec_tenant_id, sql.ptr(), affected_rows))) { LOG_WARN("failed to execute sql", KR(ret), K(exec_tenant_id), K(sql)); @@ -349,6 +361,38 @@ int ObAllTenantInfoProxy::load_tenant_info(const uint64_t tenant_id, if (OB_FAIL(tenant_info.init(tenant_id, share::PRIMARY_TENANT_ROLE))) { LOG_WARN("failed to init tenant info", KR(ret), K(tenant_id)); } + } else { + if (OB_FAIL(load_pure_tenant_info_(tenant_id, proxy, for_update, ora_rowscn, tenant_info))) { + LOG_WARN("failed to load purge tenant info", KR(ret), K(tenant_id), K(for_update)); + } else if (DEFAULT_MAX_LS_ID == tenant_info.get_max_ls_id().id()) { + //get ls from __all_ls_status + share::ObLSStatusOperator ls_op; + ObLSID max_ls_id; + if (OB_FAIL(ls_op.get_tenant_max_ls_id(tenant_id, max_ls_id, *proxy))) { + LOG_WARN("failed to get tenant max ls id", KR(ret), K(tenant_id)); + } else { + tenant_info.set_max_ls_id(max_ls_id); + } + } + } + return ret; +} + +int ObAllTenantInfoProxy::load_pure_tenant_info_(const uint64_t tenant_id, + ObISQLClient *proxy, + const bool for_update, + int64_t &ora_rowscn, + ObAllTenantInfo &tenant_info) +{ + int ret = OB_SUCCESS; + ObTimeoutCtx ctx; + tenant_info.reset(); + if (OB_ISNULL(proxy)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("proxy is null", KR(ret), KP(proxy)); + } else if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); } else { ObSqlString sql; uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id); @@ -378,32 +422,22 @@ int ObAllTenantInfoProxy::load_tenant_info(const uint64_t tenant_id, return ret; } -int ObAllTenantInfoProxy::update_tenant_recovery_status( - const uint64_t tenant_id, ObMySQLProxy *proxy, - ObTenantSwitchoverStatus status, const SCN &sync_scn, +int ObAllTenantInfoProxy::update_tenant_recovery_status_in_trans( + const uint64_t tenant_id, ObMySQLTransaction &trans, + const ObAllTenantInfo &old_tenant_info, const SCN &sync_scn, const SCN &replay_scn, const SCN &readable_scn) { int ret = OB_SUCCESS; const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id); ObSqlString sql; int64_t affected_rows = 0; - common::ObMySQLTransaction trans; - ObAllTenantInfo old_tenant_info; - ObTimeoutCtx ctx; if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || - !status.is_valid())) { + !old_tenant_info.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("tenant_info is invalid", KR(ret), K(tenant_id), K(status)); - } else if (OB_ISNULL(proxy)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("proxy is null", KR(ret), KP(proxy)); + LOG_WARN("tenant_info is invalid", KR(ret), K(tenant_id), K(old_tenant_info)); } else if (!is_user_tenant(tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("meta tenant no need init tenant info", KR(ret), K(tenant_id)); - } else if (OB_FAIL(trans.start(proxy, exec_tenant_id))) { - LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id)); - } else if (OB_FAIL(load_tenant_info(tenant_id, &trans, true, old_tenant_info))) { - LOG_WARN("failed to load all tenant info", KR(ret), K(tenant_id)); } else { SCN new_sync_scn = gen_new_sync_scn(old_tenant_info.get_sync_scn(), sync_scn, old_tenant_info.get_recovery_until_scn()); SCN new_replay_scn = gen_new_replayable_scn(old_tenant_info.get_replayable_scn(), replay_scn, new_sync_scn); @@ -413,19 +447,16 @@ int ObAllTenantInfoProxy::update_tenant_recovery_status( && old_tenant_info.get_replayable_scn() == new_replay_scn && old_tenant_info.get_standby_scn() == new_scn) { LOG_DEBUG("no need update", K(old_tenant_info), K(new_sync_scn), K(new_replay_scn), K(new_scn)); - } else if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) { - LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx)); } else if (OB_FAIL(sql.assign_fmt( "update %s set sync_scn = %ld, replayable_scn = %ld, " "readable_scn = %ld where tenant_id = %lu " - "and switchover_status = '%s' and readable_scn <= replayable_scn and " + "and readable_scn <= replayable_scn and " "replayable_scn <= sync_scn and sync_scn <= recovery_until_scn", OB_ALL_TENANT_INFO_TNAME, new_sync_scn.get_val_for_inner_table_field(), new_replay_scn.get_val_for_inner_table_field(), new_scn.get_val_for_inner_table_field(), - tenant_id, status.to_str()))) { - LOG_WARN("failed to assign sql", KR(ret), K(tenant_id), K(status), - K(sql)); + tenant_id))) { + LOG_WARN("failed to assign sql", KR(ret), K(tenant_id), K(sql)); } else if (OB_FAIL(trans.write(exec_tenant_id, sql.ptr(), affected_rows))) { LOG_WARN("failed to execute sql", KR(ret), K(exec_tenant_id), K(sql)); } else if (!is_single_row(affected_rows)) { @@ -433,17 +464,10 @@ int ObAllTenantInfoProxy::update_tenant_recovery_status( LOG_WARN("expect updating one row", KR(ret), K(affected_rows), K(sql)); } - LOG_TRACE("update_tenant_recovery_status", KR(ret), K(tenant_id), K(affected_rows), K(status), + LOG_TRACE("update_tenant_recovery_status", KR(ret), K(tenant_id), K(affected_rows), K(sql), K(old_tenant_info), K(new_sync_scn), K(new_replay_scn), K(new_scn), K(sync_scn), K(replay_scn), K(readable_scn)); } - if (trans.is_started()) { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { - LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); - ret = OB_SUCC(ret) ? tmp_ret : ret; - } - } return ret; } @@ -470,6 +494,7 @@ int ObAllTenantInfoProxy::fill_cell(common::sqlclient::ObMySQLResult *result, Ob SCN replay_scn; SCN sts_scn; SCN recovery_until_scn; + int64_t ls_id_value = DEFAULT_MAX_LS_ID; EXTRACT_VARCHAR_FIELD_MYSQL(*result, "tenant_role", tenant_role_str); EXTRACT_VARCHAR_FIELD_MYSQL(*result, "switchover_status", status_str); EXTRACT_INT_FIELD_MYSQL(*result, "tenant_id", tenant_id, uint64_t); @@ -477,6 +502,7 @@ int ObAllTenantInfoProxy::fill_cell(common::sqlclient::ObMySQLResult *result, Ob EXTRACT_UINT_FIELD_MYSQL(*result, "sync_scn", sync_scn_val, uint64_t); EXTRACT_UINT_FIELD_MYSQL(*result, "replayable_scn", replay_scn_val, uint64_t); EXTRACT_UINT_FIELD_MYSQL(*result, "readable_scn", sts_scn_val, uint64_t); + EXTRACT_INT_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result, "max_ls_id", ls_id_value, int64_t, true, true, DEFAULT_MAX_LS_ID); EXTRACT_UINT_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result, "recovery_until_scn", recovery_until_scn_val, uint64_t, false /* skip_null_error */, true /* skip_column_error */, OB_MAX_SCN_TS_NS); EXTRACT_VARCHAR_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result, "log_mode", log_mode_str, false /* skip_null_error */, true /* skip_column_error */, log_mode_default_value); @@ -498,15 +524,57 @@ int ObAllTenantInfoProxy::fill_cell(common::sqlclient::ObMySQLResult *result, Ob } else if (OB_FAIL(tenant_info.init( tenant_id, tmp_tenant_role, tmp_tenant_sw_status, switchover_epoch, - sync_scn, replay_scn, sts_scn, recovery_until_scn, tmp_log_mode))) { + sync_scn, replay_scn, sts_scn, recovery_until_scn, tmp_log_mode, ObLSID(ls_id_value)))) { LOG_WARN("failed to init tenant info", KR(ret), K(tenant_id), K(tmp_tenant_role), K(tenant_role_str), K(tmp_tenant_sw_status), K(status_str), K(switchover_epoch), K(sync_scn), K(recovery_until_scn), - K(log_mode_str), K(tmp_log_mode)); + K(log_mode_str), K(tmp_log_mode), K(ls_id_value)); } } return ret; } +int ObAllTenantInfoProxy::update_tenant_max_ls_id( + const uint64_t tenant_id, const share::ObLSID &max_ls_id, + ObMySQLTransaction &trans, const bool for_upgrade) +{ + int ret = OB_SUCCESS; + const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id); + ObSqlString sql; + int64_t affected_rows = 0; + int64_t ora_rowscn = 0;//no used + ObAllTenantInfo all_tenant_info; + + //update switchover epoch while role change + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !max_ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(max_ls_id)); + } else if (OB_FAIL(load_pure_tenant_info_(tenant_id, &trans, true, ora_rowscn, all_tenant_info))) { + LOG_WARN("failed to load all tenant info", KR(ret), K(tenant_id)); + } else if (DEFAULT_MAX_LS_ID == all_tenant_info.get_max_ls_id().id() && !for_upgrade) { + //while max_ls_id is zero, can not update tenant max ls id, except upgrade + } else if (max_ls_id.id() <= all_tenant_info.get_max_ls_id().id()) { + //nothing, ls create maybe concurrency + //upgrade maybe reentry, so max_ls_id maybe already setted + } else if (OB_FAIL(sql.assign_fmt( + "update %s set max_ls_id = %ld " + "where tenant_id = %lu and max_ls_id < %ld", + OB_ALL_TENANT_INFO_TNAME, + max_ls_id.id(), tenant_id, max_ls_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret), K(tenant_id), K(max_ls_id), K(sql)); + } else if (OB_FAIL(trans.write(exec_tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("failed to execute sql", KR(ret), K(exec_tenant_id), K(sql)); + } else if (0 == affected_rows) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("max ls id can not fallback", KR(ret), K(max_ls_id)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expect updating one row", KR(ret), K(affected_rows), K(sql)); + } + LOG_INFO("update max ls id", KR(ret), K(tenant_id), K(max_ls_id), K(sql)); + return ret; +} + int ObAllTenantInfoProxy::update_tenant_role( const uint64_t tenant_id, ObISQLClient *proxy, diff --git a/src/share/ob_tenant_info_proxy.h b/src/share/ob_tenant_info_proxy.h old mode 100644 new mode 100755 index a40ed62a0..52bbd0786 --- a/src/share/ob_tenant_info_proxy.h +++ b/src/share/ob_tenant_info_proxy.h @@ -31,6 +31,7 @@ namespace common { class ObMySQLProxy; class ObISQLClient; +class ObMySQLTransaction; namespace sqlclient { class ObMySQLResult; @@ -73,7 +74,8 @@ public: const SCN &replayable_scn = SCN::base_scn(), const SCN &standby_scn = SCN::base_scn(), const SCN &recovery_until_scn = SCN::base_scn(), - const ObArchiveMode &log_mode = NOARCHIVE_MODE); + const ObArchiveMode &log_mode = NOARCHIVE_MODE, + const share::ObLSID &max_ls_id = share::SYS_LS); ObAllTenantInfo &operator=(const ObAllTenantInfo &other); void assign(const ObAllTenantInfo &other); void reset(); @@ -118,6 +120,10 @@ IS_TENANT_STATUS(prepare_flashback_for_switch_to_primary) // Getter&Setter const ObTenantRole &get_tenant_role() const { return tenant_role_; } const ObTenantSwitchoverStatus &get_switchover_status() const { return switchover_status_; } + void set_max_ls_id(const share::ObLSID ls_id) + { + max_ls_id_ = ls_id; + } #define Property_declare_var(variable_type, variable_name)\ private:\ @@ -133,6 +139,7 @@ public:\ Property_declare_var(share::SCN, standby_scn) Property_declare_var(share::SCN, recovery_until_scn) Property_declare_var(ObArchiveMode, log_mode) + Property_declare_var(share::ObLSID, max_ls_id) #undef Property_declare_var private: ObTenantRole tenant_role_; @@ -146,6 +153,7 @@ public: virtual ~ObAllTenantInfoProxy(){} public: + static const int64_t DEFAULT_MAX_LS_ID = 0;//for upgrade /** * @description: init_tenant_info to inner table while create tenant * @param[in] tenant_info @@ -184,121 +192,149 @@ public: int64_t &ora_rowscn, ObAllTenantInfo &tenant_info); /** - * @description: update tenant recovery status + * @description: load tenant_info fro __all_tenant_info without fix max_ls_id * @param[in] tenant_id * @param[in] proxy - * @param[in] status: the target status while update recovery status - * @param[in] sync_scn : sync point - * @param[in] replay_scn : max replay point - * @param[in] reabable_scn : standby readable scn + * @param[out] tenant_info + * @param[out] max_ls_id of __all_tenant_info */ - static int update_tenant_recovery_status(const uint64_t tenant_id, - ObMySQLProxy *proxy, - ObTenantSwitchoverStatus status, - const SCN &sync_scn, - const SCN &replay_scn, - const SCN &reabable_scn); - /** - * @description: update tenant switchover status of __all_tenant_info - * @param[in] tenant_id : user tenant id - * @param[in] proxy - * @param[in] switchover_epoch, for operator concurrency - * @param[in] old_status : old_status of current, which must be match - * @param[in] status : target switchover status to be update - * return : - * OB_SUCCESS update tenant switchover status successfully - * OB_NEED_RETRY switchover_epoch or old_status not match, need retry - */ - static int update_tenant_switchover_status(const uint64_t tenant_id, ObISQLClient *proxy, - int64_t switchover_epoch, - const ObTenantSwitchoverStatus &old_status, - const ObTenantSwitchoverStatus &status); +private: + static int load_pure_tenant_info_(const uint64_t tenant_id, ObISQLClient *proxy, + const bool for_update, + int64_t &ora_rowscn, + ObAllTenantInfo &tenant_info); + public: + /** + * @description: update tenant recovery status + * @param[in] tenant_id + * @param[in] trans + * @param[in] old_tenant_info : tenant_info get from load for update + * @param[in] status: the target status while update recovery status + * @param[in] sync_scn : sync point + * @param[in] replay_scn : max replay point + * @param[in] reabable_scn : standby readable scn + */ + static int update_tenant_recovery_status_in_trans(const uint64_t tenant_id, + ObMySQLTransaction &trans, + const ObAllTenantInfo &old_tenant_info, + const SCN &sync_scn, + const SCN &replay_scn, + const SCN &reabable_scn); + /** + * @description: update tenant switchover status of __all_tenant_info + * @param[in] tenant_id : user tenant id + * @param[in] proxy + * @param[in] switchover_epoch, for operator concurrency + * @param[in] old_status : old_status of current, which must be match + * @param[in] status : target switchover status to be update + * return : + * OB_SUCCESS update tenant switchover status successfully + * OB_NEED_RETRY switchover_epoch or old_status not match, need retry + */ + static int update_tenant_switchover_status(const uint64_t tenant_id, ObISQLClient *proxy, + int64_t switchover_epoch, + const ObTenantSwitchoverStatus &old_status, + const ObTenantSwitchoverStatus &status); - /** - * @description: update tenant status in trans - * @param[in] tenant_id - * @param[in] trans - * @param[in] new_role : target tenant role to be update - * @param[in] status : target switchover status to be update - * @param[in] sync_scn - * @param[in] replayable_scn - * @param[in] readable_scn - * @param[in] recovery_until_scn - * return : - * OB_SUCCESS update tenant role successfully - */ - static int update_tenant_status( - const uint64_t tenant_id, - common::ObMySQLTransaction &trans, - const ObTenantRole new_role, - const ObTenantSwitchoverStatus &old_status, - const ObTenantSwitchoverStatus &new_status, - const share::SCN &sync_scn, - const share::SCN &replayable_scn, - const share::SCN &readable_scn, - const share::SCN &recovery_until_scn, - const int64_t old_switchover_epoch); + /** + * @description: update tenant status in trans + * @param[in] tenant_id + * @param[in] trans + * @param[in] new_role : target tenant role to be update + * @param[in] status : target switchover status to be update + * @param[in] sync_scn + * @param[in] replayable_scn + * @param[in] readable_scn + * @param[in] recovery_until_scn + * return : + * OB_SUCCESS update tenant role successfully + */ + static int update_tenant_status( + const uint64_t tenant_id, + common::ObMySQLTransaction &trans, + const ObTenantRole new_role, + const ObTenantSwitchoverStatus &old_status, + const ObTenantSwitchoverStatus &new_status, + const share::SCN &sync_scn, + const share::SCN &replayable_scn, + const share::SCN &readable_scn, + const share::SCN &recovery_until_scn, + const int64_t old_switchover_epoch); - /** - * @description: update tenant role of __all_tenant_info - * @param[in] tenant_id - * @param[in] proxy - * @param[in] old_switchover_epoch, for operator concurrency - * @param[in] new_role : target tenant role to be update - * @param[in] old_status : old switchover status - * @param[in] new_status : target switchover status to be update - * @param[out] new_switchover_epoch, for operator concurrency - * return : - * OB_SUCCESS update tenant role successfully - * OB_NEED_RETRY old_switchover_epoch not match, need retry - */ - static int update_tenant_role(const uint64_t tenant_id, ObISQLClient *proxy, - int64_t old_switchover_epoch, - const ObTenantRole &new_role, - const ObTenantSwitchoverStatus &old_status, - const ObTenantSwitchoverStatus &new_status, - int64_t &new_switchover_epoch); - static int fill_cell(common::sqlclient::ObMySQLResult *result, ObAllTenantInfo &tenant_info, int64_t &ora_rowscn); + /** + * @description: update tenant role of __all_tenant_info + * @param[in] tenant_id + * @param[in] proxy + * @param[in] old_switchover_epoch, for operator concurrency + * @param[in] new_role : target tenant role to be update + * @param[in] old_status : old switchover status + * @param[in] new_status : target switchover status to be update + * @param[out] new_switchover_epoch, for operator concurrency + * return : + * OB_SUCCESS update tenant role successfully + * OB_NEED_RETRY old_switchover_epoch not match, need retry + */ + static int update_tenant_role(const uint64_t tenant_id, ObISQLClient *proxy, + int64_t old_switchover_epoch, + const ObTenantRole &new_role, + const ObTenantSwitchoverStatus &old_status, + const ObTenantSwitchoverStatus &new_status, + int64_t &new_switchover_epoch); + static int fill_cell(common::sqlclient::ObMySQLResult *result, ObAllTenantInfo &tenant_info, int64_t &ora_rowscn); + /** + * @description: update tenant max ls id while create ls or upgrade, in upgrade from 4100 to 4200, + * create ls no need to update max ls id while max_ls_id is zero. after update max_ls_id in post_upgrade, + * max_ls_id can not be zero, create ls can update. + * @param[in] tenant_id + * @param[in] max_ls_id : max ls id + * @param[in] trans : must be in trans + * @param[in] for_upgrade : if for upgrade, must update max ls id + * return : + * OB_SUCCESS update tenant max ls id success + * OB_ERR_UNEXPECTED max ls id can not fallback, need retry + */ + static int update_tenant_max_ls_id(const uint64_t tenant_id, const share::ObLSID &max_ls_id, + ObMySQLTransaction &trans, const bool for_upgrade); - /** - * @description: update tenant recovery_until_scn in trans - * @param[in] tenant_id - * @param[in] trans - * @param[in] recovery_until_scn : target recovery_until_scn to be updated - * return : - * OB_SUCCESS update recovery_until_scn successfully - */ - static int update_tenant_recovery_until_scn( - const uint64_t tenant_id, - common::ObMySQLTransaction &trans, - const int64_t switchover_epoch, - const share::SCN &recovery_until_scn); + /** + * @description: update tenant recovery_until_scn in trans + * @param[in] tenant_id + * @param[in] trans + * @param[in] recovery_until_scn : target recovery_until_scn to be updated + * return : + * OB_SUCCESS update recovery_until_scn successfully + */ + static int update_tenant_recovery_until_scn( + const uint64_t tenant_id, + common::ObMySQLTransaction &trans, + const int64_t switchover_epoch, + const share::SCN &recovery_until_scn); - /** - * @description: update switchover epoch when entering and leaving normal switchover status - * @param[in] old_switchover_epoch - * @param[in] old_status old switchover status - * @param[in] new_status new switchover status - * @param[out] new_switchover_epoch - */ - static int get_new_switchover_epoch_( - const int64_t old_switchover_epoch, - const ObTenantSwitchoverStatus &old_status, - const ObTenantSwitchoverStatus &new_status, - int64_t &new_switchover_epoch); + /** + * @description: update switchover epoch when entering and leaving normal switchover status + * @param[in] old_switchover_epoch + * @param[in] old_status old switchover status + * @param[in] new_status new switchover status + * @param[out] new_switchover_epoch + */ + static int get_new_switchover_epoch_( + const int64_t old_switchover_epoch, + const ObTenantSwitchoverStatus &old_status, + const ObTenantSwitchoverStatus &new_status, + int64_t &new_switchover_epoch); - /** - * @description: update tenant log mode in normal switchover status - * @param[in] tenant_id - * @param[in] trans - * @param[in] old_log_mode old log mode - * @param[in] new_log_mode new log mode - */ - static int update_tenant_log_mode( - const uint64_t tenant_id, - ObISQLClient *proxy, - const ObArchiveMode &old_log_mode, - const ObArchiveMode &new_log_mode); + /** + * @description: update tenant log mode in normal switchover status + * @param[in] tenant_id + * @param[in] trans + * @param[in] old_log_mode old log mode + * @param[in] new_log_mode new log mode + */ + static int update_tenant_log_mode( + const uint64_t tenant_id, + ObISQLClient *proxy, + const ObArchiveMode &old_log_mode, + const ObArchiveMode &new_log_mode); }; } diff --git a/src/share/ob_thread_define.h b/src/share/ob_thread_define.h old mode 100644 new mode 100755 index 22a117316..14718bf9e --- a/src/share/ob_thread_define.h +++ b/src/share/ob_thread_define.h @@ -148,4 +148,8 @@ TG_DEF(IO_BENCHMARK, IO_BENCHMARK, THREAD_POOL, 1) TG_DEF(TIMEZONE_MGR, TimezoneMgr, TIMER) TG_DEF(MASTER_KEY_MGR, MasterKeyMgr, QUEUE_THREAD, 1, 100) TG_DEF(SRS_MGR, SrsMgr, TIMER, 128) +TG_DEF(InfoPoolResize, InfoPoolResize, TIMER) +TG_DEF(MinorScan, MinorScan, TIMER) +TG_DEF(MajorScan, MajorScan, TIMER) +TG_DEF(TenantTransferService, TransferSrv, REENTRANT_THREAD_POOL, ThreadCountPair(4 ,1)) #endif diff --git a/src/share/ob_unit_table_operator.cpp b/src/share/ob_unit_table_operator.cpp index 5f6acee27..64db0ca28 100644 --- a/src/share/ob_unit_table_operator.cpp +++ b/src/share/ob_unit_table_operator.cpp @@ -695,6 +695,43 @@ int ObUnitTableOperator::get_units_by_resource_pools( return ret; } +int ObUnitTableOperator::get_unit_groups_by_tenant(const uint64_t tenant_id, + common::ObIArray &unit_groups) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + ObSqlString sql; + ObTimeoutCtx ctx; + if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) { + LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx)); + } else if (OB_FAIL(sql.append_fmt("SELECT distinct unit_group_id, status from " + "%s where resource_pool_id in " + "(select resource_pool_id from %s where tenant_id = %lu) order by unit_group_id ", + OB_ALL_UNIT_TNAME, OB_ALL_RESOURCE_POOL_TNAME, tenant_id))) { + LOG_WARN("append_fmt failed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(read_unit_groups(sql, unit_groups))) { + LOG_WARN("failed to read unit group", KR(ret), K(sql)); + } else { + uint64_t last_unit_group_id = OB_INVALID_ID; + for (int64_t i = 0; OB_SUCC(ret) && i < unit_groups.count(); ++i) { + const uint64_t current_id = unit_groups.at(i).get_unit_group_id(); + if (OB_INVALID_ID == last_unit_group_id || last_unit_group_id != current_id) { + last_unit_group_id = current_id; + } else if (last_unit_group_id == current_id) { + //one ls group can not has different status + ret = OB_ERR_UNEXPECTED; + LOG_WARN("has unit group with different status", KR(ret), K(last_unit_group_id), + K(current_id), K(unit_groups)); + } + } + } + } + return ret; +} + int ObUnitTableOperator::get_units_by_tenant(const uint64_t tenant_id, common::ObIArray &units) const { @@ -768,6 +805,28 @@ int ObUnitTableOperator::str2zone_list(const char *str, return ret; } +int ObUnitTableOperator::read_unit_group(const ObMySQLResult &result, ObSimpleUnitGroup &unit_group) const +{ + int ret = OB_SUCCESS; + unit_group.reset(); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + ObString status_str; + uint64_t unit_group_id = OB_INVALID_ID; + EXTRACT_INT_FIELD_MYSQL(result, "unit_group_id", unit_group_id, uint64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(result, "status", status_str); + if (OB_FAIL(ret)) { + LOG_WARN("failed to get cell", KR(ret), K(unit_group_id), K(status_str)); + } else { + ObUnit::Status status = ObUnit::str_to_unit_status(status_str); + unit_group = ObSimpleUnitGroup(unit_group_id, status); + } + } + return ret; +} + int ObUnitTableOperator::read_unit(const ObMySQLResult &result, ObUnit &unit) const { int ret = OB_SUCCESS; @@ -798,14 +857,7 @@ int ObUnitTableOperator::read_unit(const ObMySQLResult &result, ObUnit &unit) co unit.server_.set_ip_addr(ip, static_cast(port)); unit.migrate_from_server_.set_ip_addr( migrate_from_svr_ip, static_cast(migrate_from_svr_port)); - if (0 == STRCMP(status, ObUnit::unit_status_strings[ObUnit::UNIT_STATUS_ACTIVE])) { - unit.status_ = ObUnit::UNIT_STATUS_ACTIVE; - } else if (0 == STRCMP(status, ObUnit::unit_status_strings[ObUnit::UNIT_STATUS_DELETING])) { - unit.status_ = ObUnit::UNIT_STATUS_DELETING; - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid unit status", K(ret)); - } + unit.status_ = ObUnit::str_to_unit_status(status); } return ret; } @@ -960,6 +1012,22 @@ int ObUnitTableOperator::read_units(ObSqlString &sql, return ret; } +int ObUnitTableOperator::read_unit_groups(ObSqlString &sql, + ObIArray &unit_groups) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(sql.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid sql", K(sql), KR(ret)); + } else { + READ_ITEMS(ObSimpleUnitGroup, unit_group); + } + return ret; +} + int ObUnitTableOperator::read_resource_pools(ObSqlString &sql, ObIArray &resource_pools) const { diff --git a/src/share/ob_unit_table_operator.h b/src/share/ob_unit_table_operator.h index a983957d5..59c727eb3 100644 --- a/src/share/ob_unit_table_operator.h +++ b/src/share/ob_unit_table_operator.h @@ -76,6 +76,9 @@ public: common::ObIArray &units); int get_units_by_tenant(const uint64_t tenant_id, common::ObIArray &units) const; + int get_unit_groups_by_tenant(const uint64_t tenant_id, + common::ObIArray &unit_groups) const; + private: static int zone_list2str(const common::ObIArray &zone_list, char *str, const int64_t buf_size); @@ -96,6 +99,8 @@ private: int read_tenant(const common::sqlclient::ObMySQLResult &result, uint64_t &tenant_id) const; int read_tenants(common::ObSqlString &sql, common::ObIArray &tenants) const; + int read_unit_group(const common::sqlclient::ObMySQLResult &result, ObSimpleUnitGroup &unit_group) const; + int read_unit_groups(common::ObSqlString &sql, common::ObIArray &unit_groups) const; private: bool inited_; common::ObMySQLProxy *proxy_; diff --git a/src/share/ob_upgrade_utils.cpp b/src/share/ob_upgrade_utils.cpp old mode 100644 new mode 100755 index 954b5c430..d7be2bb0f --- a/src/share/ob_upgrade_utils.cpp +++ b/src/share/ob_upgrade_utils.cpp @@ -22,6 +22,9 @@ #include "rootserver/ob_root_service.h" #include "sql/resolver/expr/ob_raw_expr_util.h" #include "share/ob_rpc_struct.h" +#include "share/ls/ob_ls_status_operator.h"//get max ls id +#include "share/ob_tenant_info_proxy.h"//update max ls id +#include "ob_upgrade_utils.h" namespace oceanbase { @@ -809,6 +812,8 @@ int ObUpgradeFor4100Processor::post_upgrade() LOG_WARN("fail to check inner stat", KR(ret)); } else if (OB_FAIL(recompile_all_views_and_synonyms(tenant_id))) { LOG_WARN("fail to init rewrite rule version", K(ret), K(tenant_id)); + } else if (OB_FAIL(post_upgrade_for_max_ls_id_())) {//TODO for 4200 upgrade + LOG_WARN("failed to update max ls id", KR(ret)); } return ret; } @@ -960,9 +965,40 @@ int ObUpgradeFor4100Processor::recompile_all_views_and_synonyms(const uint64_t t } return ret; } - /* =========== 4100 upgrade processor end ============= */ +int ObUpgradeFor4100Processor::post_upgrade_for_max_ls_id_() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(sql_proxy_) || !is_valid_tenant_id(tenant_id_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected", KR(ret), KP(sql_proxy_), K(tenant_id_)); + } else if (!is_user_tenant(tenant_id_)) { + LOG_INFO("meta and sys tenant no need to update max ls id", K(tenant_id_)); + } else { + common::ObMySQLTransaction trans; + share::ObLSStatusOperator ls_op; + ObLSID max_ls_id; + const uint64_t exec_tenant_id = ObLSLifeIAgent::get_exec_tenant_id(tenant_id_); + if (OB_FAIL(trans.start(sql_proxy_, exec_tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id), K(tenant_id_)); + } else if (OB_FAIL(ls_op.get_tenant_max_ls_id(tenant_id_, max_ls_id, trans))) { + LOG_WARN("failed to get tenant max ls id", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(ObAllTenantInfoProxy::update_tenant_max_ls_id(tenant_id_, max_ls_id, trans, true))) { + LOG_WARN("failed to update tenant max ls id", KR(ret), K(tenant_id_), K(max_ls_id)); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to commit trans", KR(ret), KR(tmp_ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + LOG_INFO("update tenant max ls id", KR(ret), K(tenant_id_), K(max_ls_id)); + } + return ret; +} + int ObUpgradeFor4200Processor::post_upgrade() { int ret = OB_SUCCESS; @@ -1088,6 +1124,8 @@ int ObUpgradeFor4200Processor::post_upgrade_for_heartbeat_and_server_zone_op_ser } /* =========== 4200 upgrade processor end ============= */ + + /* =========== special upgrade processor end ============= */ } // end share } // end oceanbase diff --git a/src/share/ob_upgrade_utils.h b/src/share/ob_upgrade_utils.h old mode 100644 new mode 100755 index 21f1dba02..cef7e79e9 --- a/src/share/ob_upgrade_utils.h +++ b/src/share/ob_upgrade_utils.h @@ -189,6 +189,8 @@ private: int post_upgrade_for_backup(); int init_rewrite_rule_version(const uint64_t tenant_id); static int recompile_all_views_and_synonyms(const uint64_t tenant_id); + //TODO upgrade for 4200 + int post_upgrade_for_max_ls_id_(); }; DEF_SIMPLE_UPGRARD_PROCESSER(4, 1, 0, 1) diff --git a/src/share/ob_zone_merge_table_operator.cpp b/src/share/ob_zone_merge_table_operator.cpp index 747c5f664..eec5e0fbe 100644 --- a/src/share/ob_zone_merge_table_operator.cpp +++ b/src/share/ob_zone_merge_table_operator.cpp @@ -112,6 +112,9 @@ int ObZoneMergeTableOperator::update_partial_zone_merge_info( if (it->is_scn_) { if (OB_FAIL(dml.add_uint64_column(it->name_, it->get_scn_val()))) { LOG_WARN("fail to add scn column", KR(ret), K(tenant_id), K(info), K(*it)); + } else if (0 == STRCMP(it->name_, "all_merged_scn")) { + // do not add extra condition for all_merged_scn + // } else if (dml.get_extra_condition().empty()) { if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s < %ld", it->name_, it->get_scn_val()))) { LOG_WARN("fail to assign extra_condition", KR(ret), K(tenant_id)); diff --git a/src/share/parameter/ob_parameter_seed.ipp b/src/share/parameter/ob_parameter_seed.ipp old mode 100644 new mode 100755 index c327e2962..7464ca136 --- a/src/share/parameter/ob_parameter_seed.ipp +++ b/src/share/parameter/ob_parameter_seed.ipp @@ -619,14 +619,20 @@ DEF_BOOL(enable_rereplication, OB_CLUSTER_PARAMETER, "True", "specifies whether the auto-replication is turned on. " "Value: True:turned on False: turned off", ObParameterAttr(Section::LOAD_BALANCE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); -DEF_BOOL(enable_rebalance, OB_CLUSTER_PARAMETER, "True", - "specifies whether the load-balancing is turned on. " +DEF_BOOL(enable_rebalance, OB_TENANT_PARAMETER, "True", + "specifies whether the tenant load-balancing is turned on. " "Value: True:turned on False: turned off", ObParameterAttr(Section::LOAD_BALANCE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); -DEF_TIME(balancer_idle_time, OB_CLUSTER_PARAMETER, "5m", "[10s,]", - "the time interval between the schedules of the load-balancing task. " +DEF_TIME(balancer_idle_time, OB_TENANT_PARAMETER, "10s", "[10s,]", + "the time interval between the schedules of the tenant load-balancing task. " "Range: [10s, +∞)", ObParameterAttr(Section::LOAD_BALANCE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +DEF_TIME(partition_balance_schedule_interval, OB_TENANT_PARAMETER, "2h", "[0s,]", + "the time interval between generate partition balance task. " + "The value should be no less than balancer_idle_time to enable partition balance. " + "Default value 2h and the value 0s means disable partition balance. " + "Range: [0s, +∞)", + ObParameterAttr(Section::LOAD_BALANCE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); DEF_INT(balancer_tolerance_percentage, OB_CLUSTER_PARAMETER, "10", "[1, 100)", "specifies the tolerance (in percentage) of the unbalance of the disk space utilization " "among all units. The average disk space utilization is calculated by dividing " @@ -749,7 +755,7 @@ DEF_CAP(_server_standby_fetch_log_bandwidth_limit, OB_CLUSTER_PARAMETER, "0MB", //// location cache config DEF_TIME(virtual_table_location_cache_expire_time, OB_CLUSTER_PARAMETER, "8s", "[1s,)", - "expiration time for virtual table location info in partiton location cache. " + "expiration time for virtual table location info in partition location cache. " "Range: [1s, +∞)", ObParameterAttr(Section::LOCATION_CACHE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); DEF_INT(location_refresh_thread_count, OB_CLUSTER_PARAMETER, "2", "(1,64]", @@ -789,6 +795,8 @@ DEF_INT(bf_cache_priority, OB_CLUSTER_PARAMETER, "1", "[1,)", "bf cache priority DEF_INT(bf_cache_miss_count_threshold, OB_CLUSTER_PARAMETER, "100", "[0,)", "bf cache miss count threshold, 0 means disable bf cache. Range:[0, )", ObParameterAttr(Section::CACHE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); DEF_INT(fuse_row_cache_priority, OB_CLUSTER_PARAMETER, "1", "[1,)", "fuse row cache priority. Range:[1, )", ObParameterAttr(Section::CACHE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +DEF_INT(storage_meta_cache_priority, OB_CLUSTER_PARAMETER, "10", "[1,)", "storage meta cache priority. Range:[1, )", + ObParameterAttr(Section::CACHE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); //background limit config DEF_TIME(_data_storage_io_timeout, OB_CLUSTER_PARAMETER, "10s", "[1s,600s]", @@ -956,10 +964,18 @@ ERRSIM_DEF_INT(errsim_tablet_batch_count, OB_CLUSTER_PARAMETER, "0", "[0,)", "batch tablet count when in errsim mode" "Range: [0,) in integer", ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +ERRSIM_DEF_INT(errsim_backup_ls_id, OB_CLUSTER_PARAMETER, "0", "[0,)", + "the ls id that backup want to insert error" + "Range: [0,) in integer", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); ERRSIM_DEF_INT(errsim_backup_tablet_id, OB_CLUSTER_PARAMETER, "0", "[0,)", "the tablet id that backup want to insert error" "Range: [0,) in integer", ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +ERRSIM_DEF_INT(errsim_transfer_ls_id, OB_CLUSTER_PARAMETER, "0", "[0,)", + "the ls id that transfer want to insert error" + "Range: [0,) in integer", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); ERRSIM_DEF_INT(skip_report_pg_backup_task_table_id, OB_CLUSTER_PARAMETER, "0", "[0,)", "skip_report_pg_backup_task table id" "Range: [0,) in integer", @@ -1398,6 +1414,41 @@ DEF_BOOL(_enable_tenant_leak_memory_protection, OB_CLUSTER_PARAMETER, "True", "p DEF_TIME(_advance_checkpoint_timeout, OB_CLUSTER_PARAMETER, "30m", "[10s,180m]", "the timeout for backup/migrate advance checkpoint Range: [10s,180m]", ObParameterAttr(Section::ROOT_SERVICE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); + +//transfer +DEF_TIME(_transfer_start_rpc_timeout, OB_CLUSTER_PARAMETER, "10s", "[1ms,600s]", + "transfer start status rpc check some status ready timeout, Range [1ms,600s]. " + "The default value is 10ms", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); + +DEF_TIME(_transfer_finish_trans_timeout, OB_CLUSTER_PARAMETER, "10s", "[1s,600s]", + "transfer finish transaction timeout, Range [1s,600s]. " + "The default value is 10s", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); + +DEF_TIME(_transfer_start_trans_timeout, OB_CLUSTER_PARAMETER, "10s", "[1ms,600s]", + "transfer start transaction timeout, Range [1ms,600s]. " + "The default value is 10s", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); + +DEF_INT(_transfer_start_retry_count, OB_CLUSTER_PARAMETER, "0", "[0,64]", + "the number of transfer start retry. Range: [0, 64] in integer", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::STATIC_EFFECTIVE)); + + +DEF_TIME(_transfer_service_wakeup_interval, OB_CLUSTER_PARAMETER, "5m", "[1s,5m]", + "transfer service wakeup interval in errsim mode" + "Range: [1s, 5m]", + ObParameterAttr(Section::ROOT_SERVICE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); + +DEF_TIME(_transfer_process_lock_tx_timeout, OB_TENANT_PARAMETER, "100s", "[30s,)", + "transaction timeout for locking and unlocking transfer task" + "Range: [30s, +∞)", + ObParameterAttr(Section::ROOT_SERVICE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); + + +// end of transfer + DEF_TIME(dump_data_dictionary_to_log_interval, OB_TENANT_PARAMETER, "24h", "(0s,]", "data dictionary dump to log(SYS LS) interval" "Range: (0s,+∞)", @@ -1428,6 +1479,12 @@ DEF_BOOL(enable_user_defined_rewrite_rules, OB_TENANT_PARAMETER, "False", DEF_TIME(_ob_plan_cache_auto_flush_interval, OB_CLUSTER_PARAMETER, "0s", "[0s,)", "time interval for auto periodic flush plan cache. Range: [0s, +∞)", ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +ERRSIM_DEF_INT(errsim_migration_ls_id, OB_CLUSTER_PARAMETER, "0", "[0,)", + "errsim migration ls id. Range: [0,) in integer", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +ERRSIM_DEF_STR(errsim_transfer_backfill_server_addr, OB_CLUSTER_PARAMETER, "", + "the server addr that transfer backfill forbid to execute to when in errsim mode", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); DEF_BOOL(_ob_enable_direct_load, OB_CLUSTER_PARAMETER, "True", "Enable or disable direct path load", ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); @@ -1455,6 +1512,13 @@ DEF_INT(observer_id, OB_CLUSTER_PARAMETER, "0", "[1, 18446744073709551615]", DEF_INT(_pipelined_table_function_memory_limit, OB_TENANT_PARAMETER, "524288000", "[1024,18446744073709551615]", "pipeline table function result set memory size limit. default 524288000 (500M), Range: [1024,18446744073709551615]", ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +DEF_BOOL(_enable_balance_kill_transaction, OB_TENANT_PARAMETER, "False", + "Specifies whether balance should actively kill transaction", + ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +DEF_TIME(_balance_kill_transaction_threshold, OB_TENANT_PARAMETER, "100ms", "[1ms, 60s]", + "the time given to the transaction to execute when do balance" + "before it will be killed. Range: [1ms, 60s]", + ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); DEF_BOOL(_enable_px_fast_reclaim, OB_CLUSTER_PARAMETER, "True", "Enable the fast reclaim function through PX tasks deteting for survival by detect manager. The default value is True.", ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); diff --git a/src/share/rc/ob_tenant_base.cpp b/src/share/rc/ob_tenant_base.cpp index 8d5aa6965..5dab8e980 100644 --- a/src/share/rc/ob_tenant_base.cpp +++ b/src/share/rc/ob_tenant_base.cpp @@ -17,6 +17,7 @@ #include "share/resource_manager/ob_cgroup_ctrl.h" #include "storage/ob_file_system_router.h" #include "share/rc/ob_tenant_module_init_ctx.h" +#include "observer/omt/ob_tenant_mtl_helper.h" namespace oceanbase { @@ -126,12 +127,15 @@ int ObTenantBase::create_mtl_module() } LOG_INFO("create_mtl_module", K(id_)); - #define CREATE_TMP(IDX) \ - if (OB_SUCC(ret)) { \ - if (nullptr == ObTenantBase::new_m##IDX##_func) { \ - } else if (OB_FAIL(ObTenantBase::new_m##IDX##_func(m##IDX##_))) { \ - LOG_WARN("m"#IDX"_ create failed", K(ret)); \ - } \ + #define CREATE_TMP(IDX) \ + if (OB_SUCC(ret)) { \ + void *mtl_ptr = nullptr; \ + if (nullptr == ObTenantBase::new_m##IDX##_func) { \ + } else if (OB_FAIL(ObTenantBase::new_m##IDX##_func(m##IDX##_))) { \ + LOG_WARN("mtl create failed", K(ret), "type", typeid(m##IDX##_).name()); \ + } else if (get_mtl_ptr(m##IDX##_, mtl_ptr)) { \ + LOG_INFO("finish create mtl"#IDX, "type", typeid(m##IDX##_).name(), KP(mtl_ptr)); \ + } \ } #define CREATE(UNUSED, IDX) CREATE_TMP(IDX) LST_DO2(CREATE, (), MTL_MEMBERS); @@ -147,15 +151,15 @@ int ObTenantBase::init_mtl_module() { int ret = OB_SUCCESS; LOG_INFO("init_mtl_module", K(id_)); - #define INIT_TMP(IDX) \ - if (OB_SUCC(ret)) { \ - int64_t start_time_us = ObTimeUtility::current_time(); \ - if (nullptr == ObTenantBase::init_m##IDX##_func) { \ - } else if (OB_FAIL(ObTenantBase::init_m##IDX##_func(m##IDX##_))) { \ - LOG_WARN("m"#IDX"_ init failed", K(ret)); \ - } \ - int64_t cost_time_us = ObTimeUtility::current_time() - start_time_us; \ - LOG_INFO("finish init mtl"#IDX, K(cost_time_us)); \ + #define INIT_TMP(IDX) \ + if (OB_SUCC(ret)) { \ + int64_t start_time_us = ObTimeUtility::current_time(); \ + if (nullptr == ObTenantBase::init_m##IDX##_func) { \ + } else if (OB_FAIL(ObTenantBase::init_m##IDX##_func(m##IDX##_))) { \ + LOG_WARN("mtl init failed", K(ret), "type", typeid(m##IDX##_).name()); \ + } \ + int64_t cost_time_us = ObTimeUtility::current_time() - start_time_us; \ + LOG_INFO("finish init mtl"#IDX, K(cost_time_us), "type", typeid(m##IDX##_).name()); \ } #define INIT(UNUSED, IDX) INIT_TMP(IDX) LST_DO2(INIT, (), MTL_MEMBERS); @@ -167,15 +171,15 @@ int ObTenantBase::start_mtl_module() int ret = OB_SUCCESS; LOG_INFO("start_mtl_module", K(id_)); - #define START_TMP(IDX) \ - if (OB_SUCC(ret)) { \ - int64_t start_time_us = ObTimeUtility::current_time(); \ - if (nullptr == ObTenantBase::start_m##IDX##_func) { \ - } else if (OB_FAIL(ObTenantBase::start_m##IDX##_func(m##IDX##_))) { \ - LOG_WARN("m"#IDX"_ start failed", K(ret)); \ - } \ - int64_t cost_time_us = ObTimeUtility::current_time() - start_time_us; \ - LOG_INFO("finish start mtl"#IDX, K(cost_time_us)); \ + #define START_TMP(IDX) \ + if (OB_SUCC(ret)) { \ + int64_t start_time_us = ObTimeUtility::current_time(); \ + if (nullptr == ObTenantBase::start_m##IDX##_func) { \ + } else if (OB_FAIL(ObTenantBase::start_m##IDX##_func(m##IDX##_))) { \ + LOG_WARN("mtl start failed", K(ret), "type", typeid(m##IDX##_).name()); \ + } \ + int64_t cost_time_us = ObTimeUtility::current_time() - start_time_us; \ + LOG_INFO("finish start mtl"#IDX, K(cost_time_us), "type", typeid(m##IDX##_).name()); \ } #define START(UNUSED, IDX) START_TMP(IDX) LST_DO2(START, (), MTL_MEMBERS); @@ -188,16 +192,16 @@ void ObTenantBase::stop_mtl_module() { LOG_INFO("stop_mtl_module", K(id_)); ObSEArray func_arr; -#define STOP_TMP(IDX) \ - if (ObTenantBase::stop_m##IDX##_func != nullptr) { \ - FuncWrapper fw; \ - fw.func_ = [this] () { \ - int64_t start_time_us = ObTimeUtility::current_time(); \ - this->stop_m##IDX##_func(this->m##IDX##_); \ - int64_t cost_time_us = ObTimeUtility::current_time() - start_time_us; \ - FLOG_INFO("finish stop mtl"#IDX, K(cost_time_us)); \ - }; \ - func_arr.push_back(fw); \ +#define STOP_TMP(IDX) \ + if (ObTenantBase::stop_m##IDX##_func != nullptr) { \ + FuncWrapper fw; \ + fw.func_ = [this] () { \ + int64_t start_time_us = ObTimeUtility::current_time(); \ + this->stop_m##IDX##_func(this->m##IDX##_); \ + int64_t cost_time_us = ObTimeUtility::current_time() - start_time_us; \ + FLOG_INFO("finish stop mtl"#IDX, K(cost_time_us), "type", typeid(this->m##IDX##_).name()); \ + }; \ + func_arr.push_back(fw); \ } #define STOP(UNUSED, IDX) STOP_TMP(IDX) LST_DO2(STOP, (), MTL_MEMBERS); @@ -211,16 +215,16 @@ void ObTenantBase::wait_mtl_module() { LOG_INFO("wait_mtl_module", K(id_)); ObSEArray func_arr; -#define WAIT_TMP(IDX) \ - if (ObTenantBase::wait_m##IDX##_func != nullptr) { \ - FuncWrapper fw; \ - fw.func_ = [this] () { \ - int64_t start_time_us = ObTimeUtility::current_time(); \ - this->wait_m##IDX##_func(this->m##IDX##_); \ - int64_t cost_time_us = ObTimeUtility::current_time() - start_time_us; \ - FLOG_INFO("finish wait mtl"#IDX, K(cost_time_us)); \ - }; \ - func_arr.push_back(fw); \ +#define WAIT_TMP(IDX) \ + if (ObTenantBase::wait_m##IDX##_func != nullptr) { \ + FuncWrapper fw; \ + fw.func_ = [this] () { \ + int64_t start_time_us = ObTimeUtility::current_time(); \ + this->wait_m##IDX##_func(this->m##IDX##_); \ + int64_t cost_time_us = ObTimeUtility::current_time() - start_time_us; \ + FLOG_INFO("finish wait mtl"#IDX, K(cost_time_us), "type", typeid(this->m##IDX##_).name()); \ + }; \ + func_arr.push_back(fw); \ } #define WAIT(UNUSED, IDX) WAIT_TMP(IDX) LST_DO2(WAIT, (), MTL_MEMBERS); @@ -241,20 +245,33 @@ void ObTenantBase::destroy() inited_ = false; } + void ObTenantBase::destroy_mtl_module() { LOG_INFO("destroy_mtl_module", K(id_)); ObSEArray func_arr; -#define DESTROY_TMP(IDX) \ - if (ObTenantBase::destroy_m##IDX##_func != nullptr) { \ - FuncWrapper fw; \ - fw.func_ = [this] () { \ - int64_t start_time_us = ObTimeUtility::current_time(); \ - this->destroy_m##IDX##_func(this->m##IDX##_); \ - int64_t cost_time_us = ObTimeUtility::current_time() - start_time_us; \ - FLOG_INFO("finish destroy mtl"#IDX, K(cost_time_us)); \ - }; \ - func_arr.push_back(fw); \ +#define DESTROY_TMP(IDX) \ + if (ObTenantBase::destroy_m##IDX##_func != nullptr) { \ + FuncWrapper fw; \ + fw.func_ = [this] () { \ + int ret = OB_SUCCESS; \ + void *mtl_ptr = nullptr; \ + if (get_mtl_ptr(this->m##IDX##_, mtl_ptr)) { \ + if (nullptr == mtl_ptr) { \ + LOG_WARN("mtl is nullptr before destroy", "type", typeid(this->m##IDX##_).name()); \ + } \ + } \ + int64_t start_time_us = ObTimeUtility::current_time(); \ + this->destroy_m##IDX##_func(this->m##IDX##_); \ + int64_t cost_time_us = ObTimeUtility::current_time() - start_time_us; \ + FLOG_INFO("finish destroy mtl"#IDX, K(cost_time_us), KP(mtl_ptr), "type", typeid(this->m##IDX##_).name()); \ + if (get_mtl_ptr(this->m##IDX##_, mtl_ptr)) { \ + if (nullptr != mtl_ptr) { \ + LOG_WARN("mtl is not nullptr after destroy", "type", typeid(this->m##IDX##_).name()); \ + } \ + } \ + }; \ + func_arr.push_back(fw); \ } #define DESTROY(UNUSED, IDX) DESTROY_TMP(IDX) LST_DO2(DESTROY, (), MTL_MEMBERS); diff --git a/src/share/rc/ob_tenant_base.h b/src/share/rc/ob_tenant_base.h old mode 100644 new mode 100755 index effcd1730..4f93aa9fa --- a/src/share/rc/ob_tenant_base.h +++ b/src/share/rc/ob_tenant_base.h @@ -56,7 +56,9 @@ namespace blocksstable { class ObSharedMacroBlockMgr; } namespace storage { - struct ObTenantStorageInfo; +namespace mds { +class ObTenantMdsService; +} class ObLSService; class ObAccessService; class ObTenantFreezer; @@ -67,7 +69,6 @@ namespace storage { class ObTenantFreezeInfoMgr; class ObStorageHAService; class ObStorageHAHandlerService; - class ObLSRestoreService; class ObTenantSSTableMergeInfoMgr; class ObTenantTabletStatMgr; namespace checkpoint { @@ -75,8 +76,11 @@ namespace storage { class ObTabletGCService; } class ObLobManager; + class ObTransferService; + class ObRebuildService; class ObTableScanIterator; -} +} // namespace storage + namespace transaction { class ObTenantWeakReadService; // 租户弱一致性读服务 class ObTransService; // 事务服务 @@ -85,6 +89,7 @@ namespace transaction { class ObStandbyTimestampService; class ObTimestampAccess; class ObTransIDService; + class ObUniqueIDService; class ObTxLoopWorker; class ObPartTransCtx; namespace tablelock { @@ -117,6 +122,7 @@ namespace compaction { class ObTenantCompactionProgressMgr; class ObServerCompactionEventHistory; + class ObScheduleSuspectInfoMgr; } namespace memtable { @@ -126,12 +132,20 @@ namespace rootserver { class ObPrimaryMajorFreezeService; class ObRestoreMajorFreezeService; - class ObTenantRecoveryReportor; class ObTenantInfoLoader; + class ObLSRecoveryReportor; class ObCreateStandbyFromNetActor; class ObPrimaryLSService; + class ObCommonLSService; class ObRestoreService; class ObRecoveryLSService; + class ObTenantTransferService; + class ObTenantBalanceService; + class ObBalanceTaskExecuteService; + class ObBackupTaskScheduler; + class ObBackupDataService; + class ObBackupCleanService; + class ObArchiveSchedulerService; class ObArbitrationService; class ObHeartbeatService; class ObStandbySchemaRefreshTrigger; @@ -164,6 +178,7 @@ class ObTestModule; class ObTenantDagScheduler; class ObTenantModuleInitCtx; class ObGlobalAutoIncService; +class ObDagWarningHistoryManager; namespace schema { class ObTenantSchemaService; @@ -185,6 +200,7 @@ using ObTableScanIteratorObjPool = common::ObServerObjectPool(buf); - io_info.callback_ = nullptr; - - ObIOHandle io_handle; - io_handle.reset(); - int io_errno = OB_SUCCESS; - const int64_t io_timeout_ms = GCONF._data_storage_io_timeout / 1000L; - if (OB_FAIL(ObIOManager::get_instance().aio_write(io_info, io_handle))) { - LOG_WARN("fail to aio_write", K(ret), K(io_info), K(io_timeout_ms)); - } else if(OB_FAIL(io_handle.wait(io_timeout_ms))) { - LOG_WARN("failed to wait for aio_write", K(ret), K(io_timeout_ms)); - } else if (OB_FAIL(io_handle.get_fs_errno(io_errno))) { - LOG_WARN("failed to get_fs_errno for aio_write", K(ret), K(io_errno)); - } else { - ret = io_errno; - } - } - return ret; -} -*/ int ObLogFileHandler::unlink(const char* file_path) { @@ -391,20 +334,34 @@ int ObLogFileHandler::normal_retry_write(void *buf, int64_t size, int64_t offset LOG_WARN("io fd is not normal file", K(ret), K_(io_fd)); } else { int64_t retry_cnt = 0; - int64_t write_size = 0; - const int64_t start_ts = ObTimeUtility::current_time(); - ATOMIC_STORE(&pwrite_ts_, start_ts); do { - if (OB_FAIL(THE_IO_DEVICE->pwrite(io_fd_, offset, size, buf, write_size))) { + ObIOInfo io_info; + io_info.flag_.set_write(); + io_info.tenant_id_ = tenant_id_; + io_info.fd_ = io_fd_; + io_info.offset_ = offset; + io_info.size_ = size; + io_info.flag_.set_group_id(THIS_WORKER.get_group_id()); + io_info.flag_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + io_info.buf_ = reinterpret_cast(buf); + io_info.callback_ = nullptr; + ObIOHandle io_handle; + const int64_t io_timeout_ms = GCONF._data_storage_io_timeout / 1000L; + if (OB_FAIL(ObIOManager::get_instance().aio_write(io_info, io_handle))) { + LOG_WARN("fail to aio_write", K(ret), K(io_info), K(io_timeout_ms)); + } else if(OB_FAIL(io_handle.wait(io_timeout_ms))) { + LOG_WARN("failed to wait for aio_write", K(ret), K(io_timeout_ms)); + } + + if (OB_FAIL(ret)) { retry_cnt ++; if (REACH_TIME_INTERVAL(LOG_INTERVAL_US)) { - LOG_WARN("fail to write", K(ret), KP(buf), K(size), K(offset), K(retry_cnt), K(write_size)); + LOG_WARN("fail to aio_write", K(ret), K(io_info), K(retry_cnt)); } else { ob_usleep(static_cast(SLEEP_TIME_US)); } } } while (OB_FAIL(ret)); - ATOMIC_STORE(&pwrite_ts_, 0); } return ret; diff --git a/src/share/redolog/ob_log_file_handler.h b/src/share/redolog/ob_log_file_handler.h index 0f27b411a..43e104391 100644 --- a/src/share/redolog/ob_log_file_handler.h +++ b/src/share/redolog/ob_log_file_handler.h @@ -82,7 +82,6 @@ public: int get_file_id_range(int64_t &min_file_id, int64_t &max_file_id); // file handler status - int64_t get_pwrite_ts() const { return ATOMIC_LOAD(&pwrite_ts_); }; static bool is_valid_file_id(int64_t file_id); static int open(const char *file_path, const int flags, const mode_t mode, ObIOFd &io_fd); @@ -93,9 +92,7 @@ private: int inner_close(const ObIOFd &io_fd); int inner_read(const ObIOFd &io_fd, void *buf, const int64_t size, const int64_t offset, int64_t &read_size, int64_t retry_cnt = ObLogDefinition::DEFAULT_IO_RETRY_CNT); - // int inner_write(const ObIOFd &io_fd, void *buf, const int64_t size, const int64_t offset); - // static int inner_write_impl(const ObIOFd &io_fd, void *buf, const int64_t size, - // const int64_t offset, const uint64_t tenant_id); + public: // helper function static int format_file_path(char *buf, const int64_t buf_size, @@ -130,7 +127,6 @@ private: ObLogFileGroup file_group_; int64_t file_size_; uint64_t tenant_id_; - volatile int64_t pwrite_ts_ CACHE_ALIGNED; }; OB_INLINE void ObNormalRetryWriteParam::destroy() diff --git a/src/share/restore/ob_log_restore_source_mgr.cpp b/src/share/restore/ob_log_restore_source_mgr.cpp index 6e470e6ba..660c4c1f5 100644 --- a/src/share/restore/ob_log_restore_source_mgr.cpp +++ b/src/share/restore/ob_log_restore_source_mgr.cpp @@ -14,7 +14,6 @@ #include "lib/restore/ob_storage.h" #include "lib/utility/ob_macro_utils.h" #include "share/backup/ob_backup_struct.h" -#include "share/ls/ob_ls_i_life_manager.h" // share::is_valid_scn #include "ob_log_restore_source_mgr.h" #include "lib/ob_define.h" #include "lib/ob_errno.h" diff --git a/src/share/restore/ob_ls_restore_status.cpp b/src/share/restore/ob_ls_restore_status.cpp index 7a7af8816..eb160e8fb 100644 --- a/src/share/restore/ob_ls_restore_status.cpp +++ b/src/share/restore/ob_ls_restore_status.cpp @@ -40,6 +40,8 @@ const char *ObLSRestoreStatus::get_restore_status_str(const ObLSRestoreStatus &s "WAIT_RESTORE_SYS_TABLETS", "RESTORE_TABLETS_META", "WAIT_RESTORE_TABLETS_META", + "RESTORE_TO_CONSISTENT_SCN", + "WAIT_RESTORE_TO_CONSISTENT_SCN", "QUICK_RESTORE", "WAIT_QUICK_RESTORE", "QUICK_RESTORE_FINISH", diff --git a/src/share/restore/ob_ls_restore_status.h b/src/share/restore/ob_ls_restore_status.h index d64958ffc..e678b6d5e 100644 --- a/src/share/restore/ob_ls_restore_status.h +++ b/src/share/restore/ob_ls_restore_status.h @@ -40,18 +40,22 @@ public: RESTORE_TABLETS_META = 4, // wait restore tablets meta WAIT_RESTORE_TABLETS_META = 5, + // replay log to consistent_scn + RESTORE_TO_CONSISTENT_SCN = 6, + // wait followers to replay log to consistent_scn + WAIT_RESTORE_TO_CONSISTENT_SCN = 7, // restore major sst meta, minor sst and clog - QUICK_RESTORE = 6, + QUICK_RESTORE = 8, // wait followers to do quick restore - WAIT_QUICK_RESTORE = 7, + WAIT_QUICK_RESTORE = 9, // finish quick restore, major macro blocks are in remote reference state - QUICK_RESTORE_FINISH = 8, + QUICK_RESTORE_FINISH = 10, // restore major macro blocks - RESTORE_MAJOR_DATA = 9, + RESTORE_MAJOR_DATA = 11, // wait followers to restore major macro blocks - WAIT_RESTORE_MAJOR_DATA = 10, + WAIT_RESTORE_MAJOR_DATA = 12, // restore failed - RESTORE_FAILED = 11, + RESTORE_FAILED = 13, LS_RESTORE_STATUS_MAX }; @@ -72,6 +76,8 @@ public: bool is_restore_none() const { return Status::RESTORE_NONE == status_; } bool is_restore_sys_tablets() const { return Status::RESTORE_SYS_TABLETS == status_; } bool is_restore_tablets_meta() const { return Status::RESTORE_TABLETS_META == status_; } + bool is_restore_to_consistent_scn() const { return Status::RESTORE_TO_CONSISTENT_SCN == status_; } + bool is_wait_restore_consistent_scn() const { return Status::WAIT_RESTORE_TO_CONSISTENT_SCN == status_; } bool is_wait_restore_sys_tablets() const { return Status::WAIT_RESTORE_SYS_TABLETS == status_; } bool is_wait_restore_tablets_meta() const { return Status::WAIT_RESTORE_TABLETS_META == status_; } bool is_wait_quick_restore() const { return Status::WAIT_QUICK_RESTORE == status_; } @@ -79,8 +85,14 @@ public: bool is_quick_restore_finish() const { return Status::QUICK_RESTORE_FINISH == status_;} bool is_restore_failed() const { return Status::RESTORE_FAILED == status_; } bool is_in_restore() const { return status_ != Status::RESTORE_NONE; } - bool is_wait_status() const { return is_wait_restore_sys_tablets() || is_wait_restore_tablets_meta() - || is_wait_quick_restore() || is_wait_restore_major_data(); } + bool is_wait_status() const + { + return is_wait_restore_sys_tablets() + || is_wait_restore_consistent_scn() + || is_wait_restore_tablets_meta() + || is_wait_quick_restore() + || is_wait_restore_major_data(); + } // enable sync and online ls restore handler in [RESTORE_START, RESTORE_SYS_TABLETS] or RESTORE_FAILED bool is_enable_for_restore() const @@ -88,10 +100,15 @@ public: return ((status_ >= Status::RESTORE_START && status_ <= Status::RESTORE_SYS_TABLETS) || status_ == Status::RESTORE_FAILED); } + // if restore status is not in [RESTORE_START, RESTORE_SYS_TABLETS], log_replay_service can replay log. // if restore status is not in [RESTORE_START, RESTORE_SYS_TABLETS] or restore_failed, log_replay_service can replay log. bool can_replay_log() const { return ! (status_ >= Status::RESTORE_START && status_ <= Status::RESTORE_SYS_TABLETS) && status_ != Status::RESTORE_FAILED; } - bool can_restore_log() const { return status_ == RESTORE_NONE || (status_ >= QUICK_RESTORE && status_ < RESTORE_FAILED); } + bool can_restore_log() const { return status_ == RESTORE_NONE || (status_ >= RESTORE_TO_CONSISTENT_SCN && status_ < RESTORE_FAILED); } + bool can_migrate() const + { + return !(status_ >= RESTORE_START && status_ <= WAIT_RESTORE_TO_CONSISTENT_SCN); + } Status get_status() const { return status_; } int set_status(int32_t status); diff --git a/src/share/restore/ob_physical_restore_info.cpp b/src/share/restore/ob_physical_restore_info.cpp index ecc69687c..f4c77c300 100644 --- a/src/share/restore/ob_physical_restore_info.cpp +++ b/src/share/restore/ob_physical_restore_info.cpp @@ -242,6 +242,7 @@ DEF_TO_STRING(ObPhysicalRestoreJob) K_(comment), K_(restore_start_ts), K_(restore_scn), + K_(consistent_scn), K_(post_data_version), K_(source_cluster_version), K_(source_data_version), @@ -279,6 +280,7 @@ int ObPhysicalRestoreJob::assign(const ObPhysicalRestoreJob &other) status_ = other.status_; restore_start_ts_ = other.restore_start_ts_; restore_scn_ = other.restore_scn_; + consistent_scn_ = other.consistent_scn_; post_data_version_ = other.post_data_version_; source_cluster_version_ = other.source_cluster_version_; source_data_version_ = other.source_data_version_; @@ -340,6 +342,7 @@ void ObPhysicalRestoreJob::reset() comment_.reset(); restore_start_ts_ = 0; restore_scn_ = SCN::min_scn(); + consistent_scn_ = SCN::min_scn(); post_data_version_ = 0; source_cluster_version_ = 0; source_data_version_ = 0; diff --git a/src/share/restore/ob_physical_restore_info.h b/src/share/restore/ob_physical_restore_info.h index 713c00209..bdfde3ac6 100644 --- a/src/share/restore/ob_physical_restore_info.h +++ b/src/share/restore/ob_physical_restore_info.h @@ -44,12 +44,13 @@ enum PhysicalRestoreStatus PHYSICAL_RESTORE_CREATE_TENANT = 0, // restore tenant schema PHYSICAL_RESTORE_PRE = 1, // set parameters PHYSICAL_RESTORE_CREATE_INIT_LS = 2, // create init ls - PHYSICAL_RESTORE_WAIT_LS = 3, // check all ls restore finish and sync ts is restore - PHYSICAL_RESTORE_POST_CHECK = 4, // check tenant is in restore, set tenant to normal - PHYSICAL_RESTORE_UPGRADE = 5, // upgrade post - PHYSICAL_RESTORE_SUCCESS = 6, // restore success - PHYSICAL_RESTORE_FAIL = 7, // restore fail - PHYSICAL_RESTORE_WAIT_TENANT_RESTORE_FINISH = 8, //sys tenant wait user tenant restore finish + PHYSICAL_RESTORE_WAIT_CONSISTENT_SCN = 3, // wait clog recover to consistent scn + PHYSICAL_RESTORE_WAIT_LS = 4, // check all ls restore finish and sync ts is restore + PHYSICAL_RESTORE_POST_CHECK = 5, // check tenant is in restore, set tenant to normal + PHYSICAL_RESTORE_UPGRADE = 6, // upgrade post + PHYSICAL_RESTORE_SUCCESS = 7, // restore success + PHYSICAL_RESTORE_FAIL = 8, // restore fail + PHYSICAL_RESTORE_WAIT_TENANT_RESTORE_FINISH = 9, //sys tenant wait user tenant restore finish PHYSICAL_RESTORE_MAX_STATUS }; @@ -160,6 +161,7 @@ public: Property_declare_int(int64_t, restore_start_ts) Property_declare_int(share::SCN, restore_scn) + Property_declare_int(share::SCN, consistent_scn) Property_declare_int(uint64_t, post_data_version) Property_declare_int(uint64_t, source_cluster_version) Property_declare_int(uint64_t, source_data_version) diff --git a/src/share/restore/ob_physical_restore_table_operator.cpp b/src/share/restore/ob_physical_restore_table_operator.cpp index 60d8323c5..fa5280100 100644 --- a/src/share/restore/ob_physical_restore_table_operator.cpp +++ b/src/share/restore/ob_physical_restore_table_operator.cpp @@ -22,6 +22,7 @@ #include "share/ob_cluster_version.h" #include "rootserver/ob_rs_job_table_operator.h" #include "share/backup/ob_backup_path.h" +#include "share/ls/ob_ls_info.h" #include using namespace oceanbase::common; @@ -47,6 +48,7 @@ static const char* phy_restore_status_str_array[PHYSICAL_RESTORE_MAX_STATUS] = { "CREATE_TENANT", "RESTORE_PRE", "RESTORE_CREATE_INIT_LS", + "PHYSICAL_RESTORE_WAIT_RESTORE_TO_CONSISTENT_SCN", "RESTORE_WAIT_LS", "POST_CHECK", "UPGRADE", @@ -211,14 +213,11 @@ int ObPhysicalRestoreTableOperator::fill_dml_splicer( ADD_COLUMN_MACRO_IN_TABLE_OPERATOR(job_info, comment); // restore_scn - if (OB_SUCC(ret)) { - ADD_COLUMN_WITH_UINT_VALUE(job_info, restore_scn, (job_info.get_restore_scn().get_val_for_inner_table_field())); - } + ADD_COLUMN_WITH_UINT_VALUE(job_info, restore_scn, (job_info.get_restore_scn().get_val_for_inner_table_field())); + // consistent_scn + ADD_COLUMN_WITH_UINT_VALUE(job_info, consistent_scn, (job_info.get_consistent_scn().get_val_for_inner_table_field())); //restore_type - if (OB_SUCC(ret)) { - ADD_COLUMN_WITH_VALUE(job_info, restore_type, (int64_t)(job_info.get_restore_type())); - } - // post_data_version + ADD_COLUMN_WITH_VALUE(job_info, restore_type, (int64_t)(job_info.get_restore_type())); if (OB_SUCC(ret)) { uint64_t post_data_version = job_info.get_post_data_version(); int64_t len = ObClusterVersion::print_version_str( @@ -486,6 +485,21 @@ int ObPhysicalRestoreTableOperator::retrieve_restore_option( } } } + + if (OB_SUCC(ret)) { + if (name == "consistent_scn") { + uint64_t current_value = share::OB_INVALID_SCN_VAL; + SCN consistent_scn; + if (OB_FAIL(retrieve_uint_value(result, current_value))) { + LOG_WARN("fail to retrive int value", K(ret), "column_name", "consistent_scn"); + } else if (OB_FAIL(consistent_scn.convert_for_inner_table_field(current_value))) { + LOG_WARN("fail to set restore scn", K(ret)); + } else { + (job).set_consistent_scn(consistent_scn); + } + } + } + RETRIEVE_STR_VALUE(restore_option, job); RETRIEVE_STR_VALUE(backup_dest, job); RETRIEVE_STR_VALUE(description, job); @@ -998,3 +1012,63 @@ int ObPhysicalRestoreTableOperator::get_restore_job_by_sql_( return ret; } +int ObPhysicalRestoreTableOperator::check_finish_restore_to_consistent_scn( + bool &is_finished, bool &is_success) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + const uint64_t exec_tenant_id = get_exec_tenant_id(tenant_id_); + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (is_sys_tenant(exec_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant id cannot be sys", KR(ret), K_(tenant_id)); + } else { + is_finished = true; + is_success = true; + SMART_VAR(common::ObMySQLProxy::MySQLResult, res) { + ObSqlString sql; + common::sqlclient::ObMySQLResult *result = NULL; + if (OB_FAIL(sql.assign_fmt("select a.ls_id, b.restore_status, b.replica_status from %s as a " + "left join %s as b on a.ls_id = b.ls_id", + OB_ALL_LS_STATUS_TNAME, OB_ALL_LS_META_TABLE_TNAME))) { + LOG_WARN("failed to assign sql", K(ret)); + } else if (OB_FAIL(sql_client_->read(res, exec_tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret), K(sql)); + } else { + int64_t ls_id = 0; + share::ObLSRestoreStatus ls_restore_status; + int32_t restore_status = -1; + while (OB_SUCC(ret) && OB_SUCC(result->next()) + && !(is_finished && !is_success)) { + EXTRACT_INT_FIELD_MYSQL(*result, "ls_id", ls_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "restore_status", restore_status, int32_t); + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ls_restore_status.set_status(restore_status))) { + LOG_WARN("failed to set status", KR(ret), K(restore_status)); + } else if (ls_restore_status.is_restore_failed()) { + //restore failed + is_finished = true; + is_success = false; + } else { + const ObLSRestoreStatus target_status(ObLSRestoreStatus::Status::WAIT_RESTORE_TO_CONSISTENT_SCN); + if (ls_restore_status.get_status() < target_status.get_status() + && !ls_restore_status.is_restore_none() + && is_finished && is_success) { + is_finished = false; + } + } + } // while + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + } + } + } + return ret; +} \ No newline at end of file diff --git a/src/share/restore/ob_physical_restore_table_operator.h b/src/share/restore/ob_physical_restore_table_operator.h index 8d4e956f4..5e6de3107 100644 --- a/src/share/restore/ob_physical_restore_table_operator.h +++ b/src/share/restore/ob_physical_restore_table_operator.h @@ -115,6 +115,14 @@ public: * */ int get_job_by_tenant_name(const ObString &tenant_name, ObPhysicalRestoreJob &job_info); + + /* + * description: check all ls has restored to consistent_scn + * @param[out] return true while restore has finished. + * @param[out] return success or failed while is finished. + * */ + int check_finish_restore_to_consistent_scn( + bool &is_finished, bool &is_success); public: static const char* get_physical_restore_mod_str(PhysicalRestoreMod mod); static const char* get_restore_status_str(PhysicalRestoreStatus status); diff --git a/src/share/restore/ob_restore_persist_helper.cpp b/src/share/restore/ob_restore_persist_helper.cpp index e250a6e40..7c1cf9d4a 100644 --- a/src/share/restore/ob_restore_persist_helper.cpp +++ b/src/share/restore/ob_restore_persist_helper.cpp @@ -562,7 +562,7 @@ int ObHisRestoreJobPersistInfo::fill_dml(ObDMLSqlSplicer &dml) const ADD_COMMON_COLUMN_DML_WITH_VALUE(status, status_str); ADD_LONG_STR_COLUMN_DML(description); - ADD_LONG_STR_COLUMN_DML(comment); + ADD_FIXED_STR_COLUMN_DML(comment); return ret; } diff --git a/src/share/restore/ob_restore_persist_helper.h b/src/share/restore/ob_restore_persist_helper.h index 81c0a9260..67743f167 100644 --- a/src/share/restore/ob_restore_persist_helper.h +++ b/src/share/restore/ob_restore_persist_helper.h @@ -21,6 +21,7 @@ #include "share/restore/ob_ls_restore_status.h" #include "share/restore/ob_restore_type.h" #include "share/scn.h" +#include "share/backup/ob_backup_struct.h" namespace oceanbase { @@ -229,7 +230,7 @@ struct ObLSRestoreProgressPersistInfo final : public ObIInnerTableRow int64_t total_bytes_; int64_t finish_bytes_; ObTaskId trace_id_; - common::ObSqlString comment_; + ObHAResultInfo::Comment comment_; int result_; ObLSRestoreProgressPersistInfo() { @@ -313,7 +314,7 @@ struct ObHisRestoreJobPersistInfo final : public ObIInnerTableRow int status_; LongString description_; - LongString comment_; + ObHAResultInfo::Comment comment_; ObHisRestoreJobPersistInfo() : key_() { initiator_job_id_ = -1; diff --git a/src/share/scheduler/ob_dag_scheduler.cpp b/src/share/scheduler/ob_dag_scheduler.cpp old mode 100644 new mode 100755 index 0aea9ac4d..b38e7dda2 --- a/src/share/scheduler/ob_dag_scheduler.cpp +++ b/src/share/scheduler/ob_dag_scheduler.cpp @@ -31,6 +31,7 @@ #include "storage/compaction/ob_tablet_merge_task.h" #include "storage/compaction/ob_compaction_diagnose.h" #include "storage/ddl/ob_complement_data_task.h" +#include "storage/multi_data_source/ob_mds_table_merge_dag.h" #include #include @@ -727,19 +728,20 @@ int64_t ObIDag::to_string(char *buf, const int64_t buf_len) const return pos; } -void ObIDag::gene_basic_warning_info(ObDagWarningInfo &info) -{ - info.dag_type_ = type_; - info.tenant_id_ = MTL_ID(); - info.gmt_create_ = info.gmt_modified_; -} - -void ObIDag::gene_warning_info(ObDagWarningInfo &info) +int ObIDag::gene_warning_info(ObDagWarningInfo &info, ObIAllocator &allocator) { + int ret = OB_SUCCESS; info.dag_ret_ = dag_ret_; info.task_id_ = id_; info.gmt_modified_ = ObTimeUtility::fast_current_time(); - fill_comment(info.warning_info_, OB_DAG_WARNING_INFO_LENGTH); + info.dag_type_ = type_; + info.tenant_id_ = MTL_ID(); + info.gmt_create_ = info.gmt_modified_; + info.dag_status_ = ObDagWarningInfo::ODS_WARNING; + if (OB_FAIL(fill_info_param(info.info_param_, allocator))) { + COMMON_LOG(WARN, "failed to fill info param into dag warning info", K(ret)); + } + return ret; } int ObIDag::reset_status_for_retry() @@ -838,6 +840,22 @@ int ObIDag::inner_add_child_without_inheritance(ObIDag &child) return ret; } +int ObIDag::fill_comment(char *buf, const int64_t buf_len) +{ + int ret = OB_SUCCESS; + MEMSET(buf, '\0', buf_len); + compaction::ObInfoParamBuffer allocator; + compaction::ObIBasicInfoParam *param = nullptr; + if (OB_FAIL(fill_info_param(param, allocator))) { + COMMON_LOG(WARN, "failed to fill info param", K(ret)); + } else if (OB_ISNULL(param)) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "param is null", K(ret)); + } else if (OB_FAIL(param->fill_comment(buf, buf_len))) { + COMMON_LOG(WARN, "failed to fill comment", K(ret)); + } + return ret; +} /*************************************ObIDagNet***********************************/ @@ -1104,10 +1122,9 @@ void ObIDag::gene_dag_info(ObDagInfo &info, const char *list_info) COMMON_LOG_RET(WARN, tmp_ret, "failed to fill dag key", K(tmp_ret)); } - if (OB_TMP_FAIL(fill_comment(info.comment_, OB_DAG_COMMET_LENGTH))) { - COMMON_LOG_RET(WARN, tmp_ret, "failed to fill dag comment", K(tmp_ret)); + if (OB_TMP_FAIL(fill_comment(info.comment_, sizeof(info.comment_)))) { + COMMON_LOG_RET(WARN, tmp_ret, "failed to fill comment"); } - info.comment_[strlen(info.comment_)] = ';'; ADD_TASK_INFO_PARAM(info.comment_, OB_DAG_COMMET_LENGTH, "check_can_schedule", check_can_schedule(), @@ -1129,10 +1146,6 @@ void ObIDag::gene_dag_info(ObDagInfo &info, const char *list_info) "indegree", cur_task->indegree_); cur_task = cur_task->get_next(); } // end while - } else { - if (OB_TMP_FAIL(fill_comment(info.comment_, OB_DAG_COMMET_LENGTH))) { - COMMON_LOG_RET(WARN, tmp_ret, "failed to fill dag comment", K(tmp_ret)); - } } if (OB_NOT_NULL(dag_net_)) { info.dag_net_type_ = dag_net_->get_type(); @@ -2169,10 +2182,19 @@ int ObTenantDagScheduler::check_ls_compaction_dag_exist(const ObLSID &ls_id, boo ObIDag *head = dag_list_[READY_DAG_LIST].get_head(ObIDag::MergeDagPrio[i]); ObIDag *cur = head->get_next(); while (head != cur) { - dag = static_cast(cur); - if (ls_id == dag->get_ctx().param_.ls_id_) { - exist = true; - break; + if (ObDagType::DAG_TYPE_MDS_TABLE_MERGE == cur->get_type()) { + // TODO (bowen.gbw) : make ObMdsTableMergeDag inherit from ObTabletMergeDag + const mds::ObMdsTableMergeDag *mds_dag = static_cast(cur); + if (ls_id == mds_dag->get_param().ls_id_) { + exist = true; + break; + } + } else { + dag = static_cast(cur); + if (ls_id == dag->get_ctx().param_.ls_id_) { + exist = true; + break; + } } cur = cur->get_next(); } @@ -2499,7 +2521,7 @@ int ObTenantDagScheduler::finish_dag_( LOG_INFO("dag finished", "dag_ret", dag.get_dag_ret(), "runtime", ObTimeUtility::fast_current_time() - dag.start_time_, K_(dag_cnt), K(dag_cnts_[dag.get_type()]), K(&dag), K(dag)); - if (OB_TMP_FAIL(ObDagWarningHistoryManager::get_instance().add_dag_warning_info(&dag))) { // ignore failure + if (OB_TMP_FAIL(MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag))) { // ignore failure COMMON_LOG(WARN, "failed to add dag warning info", K(tmp_ret), K(dag)); } if (OB_TMP_FAIL(ObSysTaskStatMgr::get_instance().del_task(dag.get_dag_id()))) { @@ -2630,8 +2652,11 @@ int ObTenantDagScheduler::sys_task_start(ObIDag *dag) sys_task_status.tenant_id_ = MTL_ID(); sys_task_status.task_type_ = OB_DAG_TYPES[dag->get_type()].sys_task_type_; + int tmp_ret = OB_SUCCESS; // allow comment truncation, no need to set ret - (void) dag->fill_comment(sys_task_status.comment_,sizeof(sys_task_status.comment_)); + if (OB_TMP_FAIL(dag->fill_comment(sys_task_status.comment_, sizeof(sys_task_status.comment_)))) { + COMMON_LOG(WARN, "failed to fill comment", K(ret)); + } if (OB_SUCCESS != (ret = ObSysTaskStatMgr::get_instance().add_task(sys_task_status))) { COMMON_LOG(WARN, "failed to add sys task", K(ret), K(sys_task_status)); } else if (OB_SUCCESS != (ret = dag->set_dag_id(sys_task_status.task_id_))) { // may generate task_id in ObSysTaskStatMgr::add_task @@ -2922,7 +2947,7 @@ int ObTenantDagScheduler::schedule_one(const int64_t priority) ++total_running_task_cnt_; running_workers_.add_last(worker, priority); if (task != NULL) { - COMMON_LOG(INFO, "schedule one task", KPC(task), "priority", OB_DAG_PRIOS[priority].dag_prio_str_, + COMMON_LOG(INFO, "schedule one task", KP(task), "priority", OB_DAG_PRIOS[priority].dag_prio_str_, "group id", worker->get_group_id(), K_(total_running_task_cnt), K(running_task_cnts_[priority]), K(low_limits_[priority]), K(up_limits_[priority]), KP(task->get_dag()->get_dag_net())); } @@ -3469,12 +3494,29 @@ int ObTenantDagScheduler::get_complement_data_dag_progress(const ObIDag *dag, return ret; } +// for unittest +int ObTenantDagScheduler::get_first_dag_net(ObIDagNet *&dag_net) +{ + int ret = OB_SUCCESS; + dag_net = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + COMMON_LOG(WARN, "ObDagScheduler is not inited", K(ret)); + } else { + ObMutexGuard guard(dag_net_map_lock_); + DagNetMap::iterator iter = dag_net_map_[RUNNING_DAG_NET_MAP].begin(); + if (iter != dag_net_map_[RUNNING_DAG_NET_MAP].end()) { + dag_net = iter->second; + } + } + return ret; +} + int ObFakeTask::process() { COMMON_LOG(INFO, "ObFakeTask process"); return OB_SUCCESS; } - } //namespace share } //namespace oceanbase diff --git a/src/share/scheduler/ob_dag_scheduler.h b/src/share/scheduler/ob_dag_scheduler.h index 7abb1f244..638bb677e 100644 --- a/src/share/scheduler/ob_dag_scheduler.h +++ b/src/share/scheduler/ob_dag_scheduler.h @@ -34,6 +34,7 @@ struct ObTabletCompactionProgress; struct ObDiagnoseTabletCompProgress; class ObMergeDagHash; struct ObTabletMergeDagParam; +struct ObIBasicInfoParam; } namespace share { @@ -90,40 +91,40 @@ public: enum ObITaskType { TASK_TYPE_UT = 0, - TASK_TYPE_MACROMERGE= 1, - TASK_TYPE_INDEX_FINISH= 2, - TASK_TYPE_MAIN_FINISH=3, - TASK_TYPE_MINOR_MERGE=4, - TASK_TYPE_INDEX_PERPARE=5, + TASK_TYPE_MACROMERGE = 1, + TASK_TYPE_INDEX_FINISH = 2, + TASK_TYPE_MAIN_FINISH = 3, + TASK_TYPE_MINOR_MERGE = 4, + TASK_TYPE_INDEX_PERPARE = 5, TASK_TYPE_INDEX_LOCAL_SORT = 6, TASK_TYPE_INDEX_MERGE = 7, - TASK_TYPE_NORMAL_MINOR_MERGE=8, - TASK_TYPE_BUILD_INDEX_NORMAL_MERGE=9, - TASK_TYPE_UNIQUE_INDEX_CHECKING=10, - TASK_TYPE_REPORT_INDEX_STATUS=11, - TASK_TYPE_MERGE_PREPARE_TASK=12, - TASK_TYPE_INDEX_MERGE_TO_LATEST_FINISH=13, - TASK_TYPE_COMPACT_TO_LASTEST=14, + TASK_TYPE_NORMAL_MINOR_MERGE = 8, + TASK_TYPE_BUILD_INDEX_NORMAL_MERGE = 9, + TASK_TYPE_UNIQUE_INDEX_CHECKING = 10, + TASK_TYPE_REPORT_INDEX_STATUS = 11, + TASK_TYPE_MERGE_PREPARE_TASK = 12, + TASK_TYPE_INDEX_MERGE_TO_LATEST_FINISH = 13, + TASK_TYPE_COMPACT_TO_LASTEST = 14, TASK_TYPE_SSTABLE_MERGE_PREPARE = 15, TASK_TYPE_SSTABLE_MERGE_FINISH = 16, - TASK_TYPE_SPLIT_PREPARE_TASK=17, - TASK_TYPE_SPLIT_TASK=18, - TASK_TYPE_SPLIT_FINISH_TASK=19, - TASK_TYPE_UNIQUE_CHECKING_PREPARE=20, - TASK_TYPE_SIMPLE_UNIQUE_CHECKING=21, + TASK_TYPE_SPLIT_PREPARE_TASK = 17, + TASK_TYPE_SPLIT_TASK = 18, + TASK_TYPE_SPLIT_FINISH_TASK = 19, + TASK_TYPE_UNIQUE_CHECKING_PREPARE = 20, + TASK_TYPE_SIMPLE_UNIQUE_CHECKING = 21, TASK_TYPE_MIGRATE_PREPARE = 22, TASK_TYPE_MIGRATE_COPY_LOGIC = 23, TASK_TYPE_MIGRATE_FINISH_LOGIC = 24, TASK_TYPE_MIGRATE_COPY_PHYSICAL = 25, TASK_TYPE_MIGRATE_FINISH_PHYSICAL = 26, TASK_TYPE_MIGRATE_FINISH = 27, - TASK_TYPE_FAKE = 28, - TASK_TYPE_MIGRATE_ENABLE_REPLAY = 29, + TASK_TYPE_FAKE = 28, + TASK_TYPE_MIGRATE_ENABLE_REPLAY = 29, TASK_TYPE_MAJOR_MERGE_FINISH = 30, TASK_TYPE_GROUP_MIGRATE = 31, TASK_TYPE_SQL_BUILD_INDEX = 32, // build index by sql plan. - TASK_TYPE_SERVER_PREPROCESS =33, - TASK_TYPE_FAST_RECOVERY =34, + TASK_TYPE_SERVER_PREPROCESS = 33, + TASK_TYPE_FAST_RECOVERY = 34, TASK_TYPE_MIGRATE_POST_PREPARE = 35, TASK_TYPE_FAST_MIGRATE_ASYNC_TASK = 36, TASK_TYPE_VALIDATE_BACKUP = 37, @@ -140,6 +141,9 @@ public: TASK_TYPE_BACKUP_CLEAN = 48, TASK_TYPE_DDL_KV_DUMP = 49, TASK_TYPE_DDL_KV_MERGE = 50, + TASK_TYPE_TRANSFER_BACKFILL_TX = 51, + TASK_TYPE_TRANSFER_REPLACE_TABLE = 52, + TASK_TYPE_MDS_TABLE_MERGE = 53, TASK_TYPE_MAX, }; @@ -287,8 +291,7 @@ public: lib::ObMutexGuard guard(lock_); return task_list_.get_size(); } - virtual void gene_basic_warning_info(ObDagWarningInfo &info); - virtual void gene_warning_info(ObDagWarningInfo &info); + virtual int gene_warning_info(ObDagWarningInfo &info, ObIAllocator &allocator); virtual bool ignore_warning() { return false; } virtual bool check_can_retry(); void set_max_retry_times(const uint32_t max_retry_times) @@ -335,6 +338,7 @@ public: virtual int generate_next_dag(ObIDag *&next_dag) { UNUSED(next_dag); return common::OB_ITER_END; } virtual int set_result(const int32_t result) { UNUSED(result); return common::OB_SUCCESS; } + int fill_comment(char *buf, const int64_t buf_len); virtual bool is_ha_dag() const { return false; } @@ -344,7 +348,7 @@ public: virtual bool operator == (const ObIDag &other) const = 0; virtual int64_t hash() const = 0; virtual int hash(uint64_t &hash_val) const { hash_val = hash(); return OB_SUCCESS; } - virtual int fill_comment(char *buf, const int64_t buf_len) const = 0; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const = 0; virtual int init_by_param(const ObIDagInitParam *param) { UNUSED(param); @@ -774,13 +778,12 @@ public: template int create_and_add_dag( const ObIDagInitParam *param, - T *&dag, const bool emergency = false, const bool check_size_overflow = true); template int alloc_dag(T *&dag); template - int create_and_add_dag_net(const ObIDagInitParam *param, T *&dag_net); + int create_and_add_dag_net(const ObIDagInitParam *param); void free_dag(ObIDag &dag, ObIDag *parent_dag = nullptr); template void free_dag_net(T *&dag_net); @@ -824,6 +827,8 @@ public: const ObDagId &dag_id, bool &exist); int cancel_dag_net(const ObDagId &dag_id); int get_complement_data_dag_progress(const ObIDag *dag, int64_t &row_scanned, int64_t &row_inserted); + // for unittest + int get_first_dag_net(ObIDagNet *&dag_net); private: typedef common::ObDList DagList; @@ -1033,13 +1038,12 @@ void ObTenantDagScheduler::free_dag_net(T *&dag_net) } } - template -int ObTenantDagScheduler::create_and_add_dag_net(const ObIDagInitParam *param, T *&dag_net) +int ObTenantDagScheduler::create_and_add_dag_net(const ObIDagInitParam *param) { int ret = common::OB_SUCCESS; void *buf = nullptr; - dag_net = nullptr; + T *dag_net = nullptr; if (IS_NOT_INIT) { ret = common::OB_NOT_INIT; @@ -1062,6 +1066,7 @@ int ObTenantDagScheduler::create_and_add_dag_net(const ObIDagInitParam *param, T COMMON_LOG(WARN, "failed to add dag_net", K(ret), KPC(dag_net)); } } else { + COMMON_LOG(INFO, "success to create and add dag_net", K(ret), KP(dag_net)); notify(); } } @@ -1091,11 +1096,11 @@ int ObTenantDagScheduler::create_dag( template int ObTenantDagScheduler::create_and_add_dag( const ObIDagInitParam *param, - T *&dag, const bool emergency/* = false*/, const bool check_size_overflow/* = true*/) { int ret = common::OB_SUCCESS; + T *dag = nullptr; if (OB_FAIL(create_dag(param, dag))) { COMMON_LOG(WARN, "failed to alloc dag", K(ret)); } else if (OB_FAIL(add_dag(dag, emergency, check_size_overflow))) { @@ -1103,6 +1108,7 @@ int ObTenantDagScheduler::create_and_add_dag( COMMON_LOG(WARN, "failed to add dag", K(ret), KPC(dag)); } } else { + COMMON_LOG(INFO, "success to create and add dag", K(ret), KP(dag)); scheduler_sync_.signal(); // wake up scheduler } if (OB_FAIL(ret) && nullptr != dag) { diff --git a/src/share/scheduler/ob_dag_scheduler_config.h b/src/share/scheduler/ob_dag_scheduler_config.h old mode 100644 new mode 100755 index e62eae44e..6adabb7a8 --- a/src/share/scheduler/ob_dag_scheduler_config.h +++ b/src/share/scheduler/ob_dag_scheduler_config.h @@ -19,6 +19,7 @@ DAG_SCHEDULER_DAG_NET_TYPE_DEF(DAG_NET_TYPE_TRANSFER, "DAG_NET_TRANSFER") DAG_SCHEDULER_DAG_NET_TYPE_DEF(DAG_NET_TYPE_BACKUP, "DAG_NET_BACKUP") DAG_SCHEDULER_DAG_NET_TYPE_DEF(DAG_NET_TYPE_RESTORE, "DAG_NET_RESTORE") DAG_SCHEDULER_DAG_NET_TYPE_DEF(DAG_NET_TYPE_BACKUP_CLEAN, "DAG_NET_TYPE_BACKUP_CLEAN") +DAG_SCHEDULER_DAG_NET_TYPE_DEF(DAG_NET_TRANSFER_BACKFILL_TX, "DAG_NET_TRANSFER_BACKFILL_TX") DAG_SCHEDULER_DAG_NET_TYPE_DEF(DAG_NET_TYPE_MAX, "DAG_NET_TYPE_MAX") #endif @@ -42,26 +43,69 @@ DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_MERGE_EXECUTE, ObDagPrio::DAG_PRIO_COMPACTIO DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_MAJOR_MERGE, ObDagPrio::DAG_PRIO_COMPACTION_LOW, ObSysTaskType::SSTABLE_MAJOR_MERGE_TASK, "MAJOR_MERGE", "COMPACTION") DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TX_TABLE_MERGE, ObDagPrio::DAG_PRIO_COMPACTION_HIGH, ObSysTaskType::SPECIAL_TABLE_MERGE_TASK, "TX_TABLE_MERGE", "COMPACTION") DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_WRITE_CKPT, ObDagPrio::DAG_PRIO_COMPACTION_LOW, ObSysTaskType::WRITE_CKPT_TASK, "WRITE_CKPT", "COMPACTION") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_MDS_TABLE_MERGE, ObDagPrio::DAG_PRIO_COMPACTION_MID, ObSysTaskType::MDS_TABLE_MERGE_TASK, "MDS_TABLE_MERGE", "COMPACTION") DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_DDL, ObDagPrio::DAG_PRIO_DDL, ObSysTaskType::DDL_TASK, "DDL", "DDL") DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_UNIQUE_CHECKING, ObDagPrio::DAG_PRIO_DDL, ObSysTaskType::DDL_TASK, "UNIQUE_CHECK", "DDL") DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_SQL_BUILD_INDEX, ObDagPrio::DAG_PRIO_DDL, ObSysTaskType::DDL_TASK, "SQL_BUILD_INDEX", "DDL") DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_DDL_KV_MERGE, ObDagPrio::DAG_PRIO_DDL_HIGH, ObSysTaskType::DDL_KV_MERGE_TASK, "DDL_KV_MERGE", "DDL") -DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_MIGRATE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "MIGRATE", "MIGRATE") +// DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_MIGRATE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "MIGRATE", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_INITIAL_COMPLETE_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "INITIAL_COMPLETE_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_START_COMPLETE_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "START_COMPLETE_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_FINISH_COMPLETE_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "FINISH_COMPLETE_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_INITIAL_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "INITIAL_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_START_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "START_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_SYS_TABLETS_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "SYS_TABLETS_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TABLET_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "TABLET_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_DATA_TABLETS_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "DATA_TABLETS_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TABLET_GROUP_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "TABLET_GROUP_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_MIGRATION_FINISH, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "MIGRATION_FINISH", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_INITIAL_PREPARE_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "INITIAL_PREPARE_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_START_PREPARE_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "START_PREPARE_MIGRATION", "MIGRATE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_FINISH_PREPARE_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "FINISH_PREPARE_MIGRATION", "MIGRATE") +// DAG_TYPE_MIGRATE END DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_FAST_MIGRATE, ObDagPrio::DAG_PRIO_HA_MID, ObSysTaskType::MIGRATION_TASK, "FAST_MIGRATE", "MIGRATE") DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_VALIDATE, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::MIGRATION_TASK, "VALIDATE", "MIGRATE") -DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKFILL_TX, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::BACKFILL_TX_TASK, "BACKFILL_TX", "BACKFILL_TX") -DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_TASK, "BACKUP", "BACKUP") +// DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKFILL_TX, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::BACKFILL_TX_TASK, "BACKFILL_TX", "BACKFILL_TX") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TABLET_BACKFILL_TX, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::BACKFILL_TX_TASK, "TABLET_BACKFILL_TX", "BACKFILL_TX") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_FINISH_BACKFILL_TX, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::BACKFILL_TX_TASK, "FINISH_BACKFILL_TX", "BACKFILL_TX") + +// DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_TASK, "BACKUP", "BACKUP") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP_META, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_TASK, "BACKUP_META", "BACKUP") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP_PREPARE, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_TASK, "BACKUP_PREPARE", "BACKUP") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP_FINISH, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_TASK, "BACKUP_FINISH", "BACKUP") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP_DATA, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_TASK, "BACKUP_DATA", "BACKUP") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_PREFETCH_BACKUP_INFO, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_TASK, "PREFETCH_BACKUP_INFO", "BACKUP") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP_INDEX_REBUILD, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_TASK, "BACKUP_INDEX_REBUILD", "BACKUP") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP_COMPLEMENT_LOG, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_TASK, "BACKUP_COMPLEMENT_LOG", "BACKUP") +// DAG_TYPE_BACKUP END DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP_BACKUPSET, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_BACKUPSET_TASK, "BACKUP_BACKUPSET", "BACKUP") DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP_ARCHIVELOG, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_ARCHIVELOG_TASK, "BACKUP_ARCHIVELOG", "BACKUP") -DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "RESTORE", "RESTORE") +// DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "RESTORE", "RESTORE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_INITIAL_LS_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "INITIAL_LS_RESTORE", "RESTORE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_START_LS_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "START_LS_RESTORE", "RESTORE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_SYS_TABLETS_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "SYS_TABLETS_RESTORE", "RESTORE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_DATA_TABLETS_META_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "DATA_TABLETS_META_RESTORE", "RESTORE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TABLET_GROUP_META_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "TABLET_GROUP_META_RESTORE", "RESTORE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_FINISH_LS_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "FINISH_LS_RESTORE", "RESTORE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_INITIAL_TABLET_GROUP_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "INITIAL_TABLET_GROUP_RESTORE", "RESTORE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_START_TABLET_GROUP_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "START_TABLET_GROUP_RESTORE", "RESTORE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_FINISH_TABLET_GROUP_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "FINISH_TABLET_GROUP_RESTORE", "RESTORE") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TABLET_RESTORE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::RESTORE_TASK, "TABLET_RESTORE", "RESTORE") +// DAG_TYPE_RESTORE END + DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_BACKUP_CLEAN, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::BACKUP_CLEAN_TASK, "BACKUP_CLEAN", "BACKUP_CLEAN") DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_REMOVE_MEMBER, ObDagPrio::DAG_PRIO_HA_MID, ObSysTaskType::REMOVE_MEMBER_TASK, "REMOVE_MEMBER", "REMOVE_MEMBER") +// DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TRANSFER, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::TRANSFER_TASK, "TRANSFER", "TRANSFER") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TRANSFER_BACKFILL_TX, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::TRANSFER_TASK, "TRANSFER_BACKFILL_TX", "TRANSFER") +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TRANSFER_REPLACE_TABLE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::TRANSFER_TASK, "TRANSFER_REPLACE_TABLE", "TRANSFER") +// DAG_TYPE_TRANSFER END + DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_MAX, ObDagPrio::DAG_PRIO_MAX, ObSysTaskType::MAX_SYS_TASK_TYPE, "DAG_TYPE_MAX", "INVALID") #endif diff --git a/src/share/scheduler/ob_dag_warning_history_mgr.cpp b/src/share/scheduler/ob_dag_warning_history_mgr.cpp index 59c6397a1..5a2e71715 100644 --- a/src/share/scheduler/ob_dag_warning_history_mgr.cpp +++ b/src/share/scheduler/ob_dag_warning_history_mgr.cpp @@ -40,7 +40,7 @@ const char * ObDagWarningInfo::get_dag_status_str(enum ObDagStatus status) } ObDagWarningInfo::ObDagWarningInfo() : - tenant_id_(0), + compaction::ObIDiagnoseInfo(), task_id_(), dag_type_(share::ObDagType::DAG_TYPE_MAX), dag_ret_(OB_SUCCESS), @@ -48,9 +48,8 @@ ObDagWarningInfo::ObDagWarningInfo() : gmt_create_(0), gmt_modified_(0), retry_cnt_(0), - warning_info_() + hash_(0) { - MEMSET(warning_info_, '\0', common::OB_DAG_WARNING_INFO_LENGTH); } ObDagWarningInfo::~ObDagWarningInfo() @@ -58,129 +57,85 @@ ObDagWarningInfo::~ObDagWarningInfo() reset(); } -bool ObDagWarningInfo::operator == (const ObDagWarningInfo &other) const +void ObDagWarningInfo::shallow_copy(ObIDiagnoseInfo *other) { - bool bret = false; - bret = tenant_id_ == other.tenant_id_ - && task_id_.equals(other.task_id_) - && dag_type_ == other.dag_type_ - && dag_ret_ == other.dag_ret_ - && dag_status_ == other.dag_status_ - && gmt_create_ == other.gmt_create_ - && gmt_modified_ == other.gmt_modified_ - && retry_cnt_ == other.retry_cnt_ - && 0 == strcmp(warning_info_, other.warning_info_); - return bret; + ObDagWarningInfo *info = nullptr; + if (OB_NOT_NULL(other) && OB_NOT_NULL(info = dynamic_cast(other))) { + tenant_id_ = info->tenant_id_; + task_id_ = info->task_id_; + dag_type_ = info->dag_type_; + dag_ret_ = info->dag_ret_; + dag_status_ = info->dag_status_; + gmt_create_ = info->gmt_create_; + gmt_modified_ = info->gmt_modified_; + retry_cnt_ = info->retry_cnt_; + hash_ = info->hash_; + } } -ObDagWarningInfo & ObDagWarningInfo::operator = (const ObDagWarningInfo &other) +void ObDagWarningInfo::update(ObIDiagnoseInfo *other) { - tenant_id_ = other.tenant_id_; - task_id_ = other.task_id_; - dag_type_ = other.dag_type_; - dag_ret_ = other.dag_ret_; - dag_status_ = other.dag_status_; - gmt_create_ = other.gmt_create_; - gmt_modified_ = other.gmt_modified_; - retry_cnt_ = other.retry_cnt_; - strncpy(warning_info_, other.warning_info_, strlen(other.warning_info_) + 1); - return *this; + ObDagWarningInfo *info = nullptr; + if (OB_NOT_NULL(other) && OB_NOT_NULL(info = dynamic_cast(other))) { + gmt_create_ = info->gmt_create_; + retry_cnt_ = info->retry_cnt_+1; + dag_status_ = ObDagWarningInfo::ODS_RETRYED; + } } +int64_t ObDagWarningInfo::get_hash() const +{ + return hash_; +} /* * ObDagWarningHistoryManager Func * */ +int ObDagWarningHistoryManager::mtl_init(ObDagWarningHistoryManager *&dag_warning_history) +{ + int64_t max_size = cal_max(); + return dag_warning_history->init(true, MTL_ID(), "DagWarnHis", INFO_PAGE_SIZE, max_size); +} + +int64_t ObDagWarningHistoryManager::cal_max() +{ + const uint64_t tenant_id = MTL_ID(); + int64_t max_size = std::min(lib::get_tenant_memory_limit(tenant_id) * MEMORY_PERCENTAGE / 100, + static_cast(POOL_MAX_SIZE)); + return max_size; +} + int ObDagWarningHistoryManager::add_dag_warning_info(share::ObIDag *dag) { int ret = OB_SUCCESS; - const int64_t key = dag->hash(); - common::SpinWLockGuard guard(lock_); - if (OB_SUCCESS == dag->get_dag_ret()) { // delete old item - if (OB_FAIL(del_with_no_lock(key))) { - if (OB_HASH_NOT_EXIST != ret) { - COMMON_LOG(WARN, "failed to del dag warning info", K(ret), K(key)); - } else { - ret = OB_SUCCESS; - } - } - } else if (!dag->ignore_warning()) { - ObDagWarningInfo *info = NULL; - if (OB_FAIL(get_with_no_lock(key, info)) || OB_ISNULL(info)) { - if (OB_HASH_NOT_EXIST == ret) {// first add - if (OB_FAIL(alloc_and_add_with_no_lock(key, info)) || OB_ISNULL(info)) { // alloc a node for key - if (OB_SIZE_OVERFLOW != ret) { - COMMON_LOG(WARN, "failed to alloc dag warning info", K(ret), K(key), K(info)); - } else { - ret = OB_SUCCESS; - } - } else { - dag->gene_warning_info(*info); - dag->gene_basic_warning_info(*info); // only once - info->dag_status_ = ObDagWarningInfo::ODS_WARNING; - } - } else { - COMMON_LOG(WARN, "failed to get dag warning info", K(ret), K(key), K(info)); - } - } else { // update - dag->gene_warning_info(*info); - info->retry_cnt_++; - info->dag_status_ = ObDagWarningInfo::ODS_RETRYED; - } - } - return ret; -} - -int ObDagWarningHistoryManager::get_info(const int64_t pos, ObDagWarningInfo &info) -{ - int ret = OB_SUCCESS; - common::SpinRLockGuard guard(lock_); - if (pos >= max_cnt_) { - ret = OB_ITER_END; - } else if (node_array_.is_empty(pos)) { - ret = OB_ENTRY_NOT_EXIST; - } else { - info = *(node_array_.at(pos)); - } - return ret; -} - -/* - * ObDagWarningInfoIterator Func - * */ - -int ObDagWarningInfoIterator::open(const int64_t tenant_id) -{ - int ret = OB_SUCCESS; - if (is_opened_) { - ret = OB_INIT_TWICE; - COMMON_LOG(WARN, "The ObDagWarnInfoIterator has been opened", K(ret)); - } else if (!::oceanbase::common::is_valid_tenant_id(tenant_id)) { - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "invalid argument", K(ret), K(tenant_id)); - } else { - tenant_id_ = tenant_id; - cur_idx_ = 0; - is_opened_ = true; - } - return ret; -} - -int ObDagWarningInfoIterator::get_next_info(ObDagWarningInfo &info) -{ - int ret = OB_SUCCESS; - if (!is_opened_) { + if (IS_NOT_INIT) { ret = OB_NOT_INIT; - COMMON_LOG(WARN, "not init", K(ret)); + COMMON_LOG(WARN, "ObDagWarningHistoryManager is not init", K(ret)); + } else if (OB_ISNULL(dag)) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "invalid argument", K(ret), K(dag)); } else { - do { - ret = ObDagWarningHistoryManager::get_instance().get_info(cur_idx_, info); - ++cur_idx_; - } while (OB_ENTRY_NOT_EXIST == ret - || (OB_SYS_TENANT_ID != tenant_id_ && info.tenant_id_ != tenant_id_)); + const int64_t key = dag->hash(); + if (OB_SUCCESS == dag->get_dag_ret()) { // delete old item + if (OB_FAIL(delete_info(key))) { + if (OB_HASH_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + COMMON_LOG(WARN, "failed to delete dag warning info when add info", K(ret)); + } + } + } else if (!dag->ignore_warning()) { + ObDagWarningInfo tmp_info; + tmp_info.hash_ = key; + compaction::ObInfoParamBuffer allocator; + if(OB_FAIL(dag->gene_warning_info(tmp_info, allocator))) { + COMMON_LOG(WARN, "failed to gene dag warning info", K(ret)); + } else if (OB_FAIL(alloc_and_add(key, &tmp_info))) { + COMMON_LOG(WARN, "failed to add dag warning info", K(ret)); + } + } } return ret; } - }//storage }//oceanbase diff --git a/src/share/scheduler/ob_dag_warning_history_mgr.h b/src/share/scheduler/ob_dag_warning_history_mgr.h old mode 100644 new mode 100755 index f6ccefb37..cdbefcd93 --- a/src/share/scheduler/ob_dag_warning_history_mgr.h +++ b/src/share/scheduler/ob_dag_warning_history_mgr.h @@ -20,66 +20,14 @@ #include "lib/ob_errno.h" #include "lib/hash/ob_hashmap.h" #include "share/scheduler/ob_dag_scheduler.h" +#include "storage/compaction/ob_compaction_diagnose.h" namespace oceanbase { namespace share { -template -class ObNodeArray -{ -public: - ObNodeArray(); - ~ObNodeArray(); - void destory(); - void clear(); - int init(const char *label, const int64_t max_cnt); - T* at(const int64_t idx); - int get_node(int64_t &idx); - int free_node(const int64_t idx); - bool is_empty(const int64_t idx) { return free_node_bitset_.has_member(idx); } - - bool is_inited_; - int64_t max_cnt_; - common::ObArenaAllocator allocator_; - common::ObBitSet free_node_bitset_; - T *array_; -}; - -template -class ObInfoManager -{ -public: - ObInfoManager(); - virtual ~ObInfoManager(); - - int init(const int64_t bucket_num, - const char *label, - const int64_t max_cnt); - void destroy(); - void clear(); - int get(const Key key, Value *&item); - int get_with_no_lock(const Key key, Value *&item); - int del_with_no_lock(const Key key); - int alloc_and_add_with_no_lock(const Key key, Value *&item); - int size() { return map_.size(); } - -private: - typedef common::hash::ObHashMap InfoMap; // Value of map: index in node_array_ - -protected: - common::SpinRWLock lock_; - int64_t max_cnt_; - ObNodeArray node_array_; - -private: - bool is_inited_; - InfoMap map_; -}; - - -struct ObDagWarningInfo +struct ObDagWarningInfo : public compaction::ObIDiagnoseInfo { public: enum ObDagStatus { @@ -96,12 +44,11 @@ public: ~ObDagWarningInfo(); OB_INLINE void reset(); TO_STRING_KV(K_(tenant_id), K_(task_id), K_(dag_type), K_(dag_ret), K_(dag_status), - K_(gmt_create), K_(gmt_modified), K_(retry_cnt), K_(warning_info)); - ObDagWarningInfo & operator = (const ObDagWarningInfo &other); -private: - bool operator == (const ObDagWarningInfo &other) const; // for unittest + K_(gmt_create), K_(gmt_modified), K_(retry_cnt)); + virtual void shallow_copy(ObIDiagnoseInfo *other) override; + virtual void update(ObIDiagnoseInfo *other) override; + virtual int64_t get_hash() const override; public: - int64_t tenant_id_; share::ObDagId task_id_; share::ObDagType::ObDagTypeEnum dag_type_; int64_t dag_ret_; @@ -109,7 +56,7 @@ public: int64_t gmt_create_; int64_t gmt_modified_; int64_t retry_cnt_; - char warning_info_[common::OB_DAG_WARNING_INFO_LENGTH]; + int64_t hash_; }; OB_INLINE void ObDagWarningInfo::reset() @@ -117,309 +64,126 @@ OB_INLINE void ObDagWarningInfo::reset() tenant_id_ = 0; task_id_.reset(); dag_type_ = share::ObDagType::DAG_TYPE_MAX; + info_param_ = NULL; dag_ret_ = OB_SUCCESS; dag_status_ = ODS_MAX; gmt_create_ = 0; gmt_modified_ = 0; retry_cnt_ = 0; - MEMSET(warning_info_, '\0', common::OB_DAG_WARNING_INFO_LENGTH); + hash_ = 0; } /* * ObDagWarningHistoryManager * */ -class ObDagWarningHistoryManager : public ObInfoManager{ +class ObDagWarningHistoryManager : public compaction::ObIDiagnoseInfoMgr { public: - ObDagWarningHistoryManager() {} - ~ObDagWarningHistoryManager() {} + static int mtl_init(ObDagWarningHistoryManager *&dag_warning_history); + static int64_t cal_max(); + ObDagWarningHistoryManager() + : compaction::ObIDiagnoseInfoMgr(), + buf_() + {} + ~ObDagWarningHistoryManager() { destroy(); } - static ObDagWarningHistoryManager &get_instance() { - static ObDagWarningHistoryManager instance_; - return instance_; + void destroy() { + ObIDiagnoseInfoMgr::destroy(); + COMMON_LOG(INFO, "ObDagWarningHistoryManager destroy finish"); } - - int init() - { - return ObInfoManager::init(BUCKET_NUM, "ObDagWarningHistory", DAG_WARNING_INFO_MAX_CNT); - } - int add_dag_warning_info(share::ObIDag *dag); - int get_info(const int64_t pos, ObDagWarningInfo &info); - int gc_info(); -private: - friend class ObDagWarningInfoIterator; -private: - static const int64_t BUCKET_NUM = 98317l; - static const int64_t DAG_WARNING_INFO_MAX_CNT = 100 * 1000; //10w -}; -/* - * ObDagWarningInfoIterator - * */ - -class ObDagWarningInfoIterator -{ public: - ObDagWarningInfoIterator() : - tenant_id_(OB_INVALID_TENANT_ID), - cur_idx_(0), - is_opened_(false) - { - } - virtual ~ObDagWarningInfoIterator() { reset(); } - int open(const int64_t tenant_id); - int get_next_info(ObDagWarningInfo &info); - void reset() - { - tenant_id_ = OB_INVALID_TENANT_ID; - cur_idx_ = 0; - is_opened_ = false; - } + static const int64_t MEMORY_PERCENTAGE = 1; // max size = tenant memory size * MEMORY_PERCENTAGE / 100 + static const int64_t POOL_MAX_SIZE = 64LL * 1024LL * 1024LL; // 64MB + private: - int64_t tenant_id_; - int64_t cur_idx_; - bool is_opened_; + char buf_[compaction::ObIBasicInfoParam::MAX_INFO_PARAM_SIZE]; }; -/* - * ObNodeArray Func - * */ +#define INFO_PARAM_STR_LENGTH(n) (n * compaction::OB_DIAGNOSE_INFO_PARAM_STR_LENGTH) -template -ObNodeArray::ObNodeArray() - : is_inited_(false), - max_cnt_(0), - allocator_(), - free_node_bitset_(), - array_(NULL) -{ -} - -template -ObNodeArray::~ObNodeArray() -{ -} - -template -void ObNodeArray::destory() -{ - max_cnt_ = 0; - free_node_bitset_.clear_all(); - allocator_.free(array_); - array_ = NULL; - allocator_.reset(); - is_inited_ = false; -} - -template -void ObNodeArray::clear() -{ - free_node_bitset_.set_all(); -} - -template -int ObNodeArray::init(const char *label, const int64_t max_cnt) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(free_node_bitset_.prepare_allocate(max_cnt))) { - COMMON_LOG(WARN, "failed to init bitset", K(ret), K(max_cnt)); - } else { - void * buf = NULL; - auto attr = SET_USE_500(label); - allocator_.set_attr(attr); - free_node_bitset_.set_attr(attr); - if (NULL == (buf = allocator_.alloc(sizeof(T) * max_cnt))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - COMMON_LOG(WARN, "failed to alloc info node", K(ret)); - } else { - array_ = new (buf) T[max_cnt]; - free_node_bitset_.set_all(); - max_cnt_ = max_cnt; - is_inited_ = true; - } +#define DEFINE_DAG_WARN_INFO_PARAM_ADD(n_int) \ + template \ + int ADD_DAG_WARN_INFO_PARAM(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator, \ + ObDagType::ObDagTypeEnum type, INFO_PARAM_INT##n_int) \ + { \ + int64_t __pos = 0; \ + int ret = OB_SUCCESS; \ + out_param = nullptr; \ + void *buf = nullptr; \ + compaction::ObDiagnoseInfoParam param; \ + compaction::ObDiagnoseInfoParam *info_param = nullptr; \ + if (OB_ISNULL(buf = allocator.alloc(param.get_deep_copy_size()))) { \ + ret = OB_ALLOCATE_MEMORY_FAILED; \ + COMMON_LOG(WARN, "failed to alloc info param", K(ret)); \ + } else if (OB_ISNULL(info_param = (new (buf) compaction::ObDiagnoseInfoParam()))) { \ + ret = OB_ERR_UNEXPECTED; \ + COMMON_LOG(WARN, "failed to new. info_param is null", K(ret)); \ + } else { \ + info_param->type_.dag_type_ = type; \ + info_param->struct_type_ = compaction::ObInfoParamStructType::DAG_WARNING_INFO_PARAM; \ + INT_TO_PARAM_##n_int \ + out_param = info_param; \ + } \ + return ret; \ } - return ret; -} -template -T* ObNodeArray::at(const int64_t idx) -{ - T *ret_ptr = NULL; - if (OB_UNLIKELY(!is_inited_)) { - COMMON_LOG_RET(WARN, OB_NOT_INIT, "ObNodeArray has not been inited"); - } else if (idx >= 0 && idx < max_cnt_) { - ret_ptr = &array_[idx]; +#define DEFINE_DAG_WARN_INFO_PARAM_ADD_EXTRA(n, n_int) \ + template \ + int ADD_DAG_WARN_INFO_PARAM(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator, \ + ObDagType::ObDagTypeEnum type, INFO_PARAM_INT##n_int, LOG_PARAMETER_KV##n) \ + { \ + int64_t __pos = 0; \ + int ret = OB_SUCCESS; \ + out_param = nullptr; \ + void *buf = nullptr; \ + compaction::ObDiagnoseInfoParam param; \ + compaction::ObDiagnoseInfoParam *info_param = nullptr; \ + if (OB_ISNULL(buf = allocator.alloc(param.get_deep_copy_size()))) { \ + ret = OB_ALLOCATE_MEMORY_FAILED; \ + COMMON_LOG(WARN, "failed to alloc info param", K(ret)); \ + } else if (OB_ISNULL(info_param = (new (buf) compaction::ObDiagnoseInfoParam()))) { \ + ret = OB_ERR_UNEXPECTED; \ + COMMON_LOG(WARN, "failed to new. info_param is null", K(ret)); \ + } else { \ + info_param->type_.dag_type_ = type; \ + info_param->struct_type_ = compaction::ObInfoParamStructType::DAG_WARNING_INFO_PARAM; \ + INT_TO_PARAM_##n_int \ + char *buf = info_param->comment_; \ + const int64_t buf_size = INFO_PARAM_STR_LENGTH(n); \ + SIMPLE_TO_STRING_##n \ + if (OB_FAIL(ret)) { \ + COMMON_LOG(WARN, "failed to fill parameter kv into info param", K(ret)); \ + ret = OB_SUCCESS; \ + } \ + if (__pos < buf_size) { \ + buf[__pos-1] = '\0'; \ + } else { \ + buf[__pos] = '\0'; \ + } \ + out_param = info_param; \ + } \ + return ret; \ } - return ret_ptr; -} -template -int ObNodeArray::get_node(int64_t &idx) -{ - int ret = OB_SUCCESS; - idx = -1; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - COMMON_LOG(WARN, "ObNodeArray has not been inited", K(ret)); - } else if (free_node_bitset_.is_empty()) { - ret = OB_SIZE_OVERFLOW; - if (REACH_TIME_INTERVAL(30 * 1000 * 1000)) { - COMMON_LOG(WARN, "info node is reach uplimits", K(ret), K(max_cnt_)); - } - } else if (OB_FAIL(free_node_bitset_.find_first(idx)) || idx < 0) { - COMMON_LOG(WARN, "failed to find free pos", K(ret), K(idx), K(max_cnt_)); - } else if (OB_FAIL(free_node_bitset_.del_member(idx))) { - COMMON_LOG(WARN, "failed to del bitset member", K(ret), K(idx)); - } - return ret; -} +DEFINE_DAG_WARN_INFO_PARAM_ADD(1) +DEFINE_DAG_WARN_INFO_PARAM_ADD(2) +DEFINE_DAG_WARN_INFO_PARAM_ADD(3) +DEFINE_DAG_WARN_INFO_PARAM_ADD(4) +DEFINE_DAG_WARN_INFO_PARAM_ADD(5) +DEFINE_DAG_WARN_INFO_PARAM_ADD(6) +DEFINE_DAG_WARN_INFO_PARAM_ADD(7) -template -int ObNodeArray::free_node(const int64_t idx) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - COMMON_LOG(WARN, "ObNodeArray has not been inited", K(ret)); - } else if (idx < 0 || idx >= max_cnt_) { - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "invalid index", K(ret), K(idx), K(max_cnt_)); - } else if (OB_FAIL(free_node_bitset_.add_member(idx))){ - COMMON_LOG(WARN, "failed to add bitset member", K(ret), K(idx)); - } else { - array_[idx].reset(); - } - return ret; -} - -/* - * ObInfoManager Func - * */ -template -ObInfoManager::ObInfoManager() : - lock_(common::ObLatchIds::INFO_MGR_LOCK), - max_cnt_(0), - node_array_(), - is_inited_(false), - map_() -{ -} - -template -ObInfoManager::~ObInfoManager() -{ - destroy(); -} - -template -int ObInfoManager:: init( - const int64_t bucket_num, - const char *label, - const int64_t max_cnt) -{ - int ret = OB_SUCCESS; - auto attr = SET_USE_500(label); - if (OB_FAIL(map_.create(bucket_num, attr))) { - COMMON_LOG(WARN, "failed to create map", K(ret), K(bucket_num), K(label)); - } else if (OB_FAIL(node_array_.init(label, max_cnt))) { - COMMON_LOG(WARN, "failed to init node array", K(ret), K(max_cnt), K(label)); - } else { - max_cnt_ = max_cnt; - is_inited_ = true; - } - return ret; -} - -template -void ObInfoManager::destroy() -{ - common::SpinWLockGuard guard(lock_); - max_cnt_ = 0; - map_.destroy(); - node_array_.destory(); - is_inited_ = false; -} - -template -void ObInfoManager:: clear() -{ - common::SpinWLockGuard guard(lock_); - map_.clear(); - node_array_.clear(); -} - -template -int ObInfoManager::get(const Key key, Value *&ptr) -{ - common::SpinRLockGuard guard(lock_); - return get_with_no_lock(key, ptr); -} - -template -int ObInfoManager::get_with_no_lock(const Key key, Value *&ptr) -{ - int ret = OB_SUCCESS; - int64_t node_index = -1; - ptr = NULL; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - COMMON_LOG(WARN, "ObInfoManager has not been inited", K(ret)); - } else if (OB_FAIL(map_.get_refactored(key, node_index))) { - if (OB_HASH_NOT_EXIST != ret) { - COMMON_LOG(WARN, "fail to get from map", K(ret), K(key)); - } - } else if (NULL == (ptr = node_array_.at(node_index))) { - ret = OB_ERR_UNEXPECTED; - COMMON_LOG(WARN, "failed to get from map", K(ret), K(node_index), K(ptr)); - } - return ret; -} - -template -int ObInfoManager::del_with_no_lock(const Key key) -{ - int ret = OB_SUCCESS; - int64_t node_index = -1; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - COMMON_LOG(WARN, "ObInfoManager has not been inited", K(ret)); - } else if (OB_FAIL(map_.get_refactored(key, node_index))) { - if (OB_HASH_NOT_EXIST != ret) { - COMMON_LOG(WARN, "fail to get from map", K(ret)); - } - } else if (OB_FAIL(map_.erase_refactored(key))) { - COMMON_LOG(WARN, "fail to erase from map", K(ret)); - } else if (OB_FAIL(node_array_.free_node(node_index))) { - COMMON_LOG(WARN, "fail to free node", K(ret), K(node_index)); - } - return ret; -} - -template -int ObInfoManager::alloc_and_add_with_no_lock(const Key key, Value *&ptr) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - COMMON_LOG(WARN, "ObInfoManager has not been inited", K(ret)); - } else { - int64_t node_idx = -1; - ptr = NULL; - if (OB_FAIL(node_array_.get_node(node_idx))) { - if (OB_SIZE_OVERFLOW != ret) { - COMMON_LOG(WARN, "fail to allocate memory", K(ret), K(sizeof(Value))); - } - } else if (NULL == (ptr = node_array_.at(node_idx))) { - ret = OB_ERR_UNEXPECTED; - COMMON_LOG(WARN, "fail to get node ptr from array", K(ret), K(node_idx)); - } else if (OB_FAIL(map_.set_refactored(key, node_idx))) { - COMMON_LOG(WARN, "fail to set to map", K(ret)); - } - } - return ret; -} +DEFINE_DAG_WARN_INFO_PARAM_ADD_EXTRA(1,1) +DEFINE_DAG_WARN_INFO_PARAM_ADD_EXTRA(1,2) +DEFINE_DAG_WARN_INFO_PARAM_ADD_EXTRA(1,3) +DEFINE_DAG_WARN_INFO_PARAM_ADD_EXTRA(1,4) +DEFINE_DAG_WARN_INFO_PARAM_ADD_EXTRA(2,2) +DEFINE_DAG_WARN_INFO_PARAM_ADD_EXTRA(2,3) +DEFINE_DAG_WARN_INFO_PARAM_ADD_EXTRA(3,3) +DEFINE_DAG_WARN_INFO_PARAM_ADD_EXTRA(3,4) }//storage }//oceanbase diff --git a/src/share/scheduler/ob_diagnose_config.h b/src/share/scheduler/ob_diagnose_config.h new file mode 100755 index 000000000..e26091127 --- /dev/null +++ b/src/share/scheduler/ob_diagnose_config.h @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2022 OceanBase + * OceanBase 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. + */ + +#ifdef SUSPECT_INFO_TYPE_DEF +SUSPECT_INFO_TYPE_DEF(SUSPECT_MEMTABLE_CANT_MINOR_MERGE) +SUSPECT_INFO_TYPE_DEF(SUSPECT_CANT_SCHEDULE_MINOR_MERGE) +SUSPECT_INFO_TYPE_DEF(SUSPECT_CANT_MAJOR_MERGE) +SUSPECT_INFO_TYPE_DEF(SUSPECT_SCHEDULE_MEDIUM_FAILED) +SUSPECT_INFO_TYPE_DEF(SUSPECT_SSTABLE_COUNT_NOT_SAFE) +SUSPECT_INFO_TYPE_DEF(SUSPECT_SUBMIT_LOG_FOR_FREEZE) +SUSPECT_INFO_TYPE_DEF(SUSPECT_REC_SCN_NOT_STABLE) +SUSPECT_INFO_TYPE_DEF(SUSPECT_NOT_READY_FOR_FLUSH) +SUSPECT_INFO_TYPE_DEF(SUSPECT_MEMTABLE_CANT_CREATE_DAG) +SUSPECT_INFO_TYPE_DEF(SUSPECT_INVALID_DATA_VERSION) +SUSPECT_INFO_TYPE_DEF(SUSPECT_FAILED_TO_REFRESH_LS_LOCALITY) +SUSPECT_INFO_TYPE_DEF(SUSPECT_LOCALITY_CHANGE) +SUSPECT_INFO_TYPE_DEF(SUSPECT_INFO_TYPE_MAX) +#endif + +#ifndef SRC_SHARE_SCHEDULER_OB_DIAGNOSE_CONFIG_H_ +#define SRC_SHARE_SCHEDULER_OB_DIAGNOSE_CONFIG_H_ + +#include "ob_dag_scheduler_config.h" + +namespace oceanbase +{ +namespace share +{ +static const int64_t DIAGNOSE_INFO_STR_FMT_MAX_NUM = 8; +struct ObDiagnoseInfoStruct { + int64_t int_size; + bool with_comment; + const char *info_str; + const char *info_str_fmt[DIAGNOSE_INFO_STR_FMT_MAX_NUM]; +}; + +enum ObSuspectInfoType +{ +#define SUSPECT_INFO_TYPE_DEF(suspect_info_type) suspect_info_type, +#include "ob_diagnose_config.h" +#undef SUSPECT_INFO_TYPE_DEF +}; + +static constexpr ObDiagnoseInfoStruct OB_SUSPECT_INFO_TYPES[] = { + {2, false, "memtable can not minor merge", {"memtable end_scn", "memtable timestamp"}}, + {3, false, "can't schedule minor merge", + {"min_snapshot_version", "max_snapshot_version", "mini_sstable_cnt"}}, + {3, false, "need major merge but can't merge now", + {"medium_snapshot", "is_tablet_data_status_complete", "max_serialized_medium_scn"}}, + {3, false, "schedule medium failed", + {"compaction_scn", "store_column_cnt", "error_code"}}, + {3, true, "sstable count is not safe", {"major_table_count", "minor_tables_count", "first_minor_start_scn"}}, + {2, false, "traverse_trans_to_submit_redo_log failed", {"ret", "fail_tx_id"}}, + {2, false, "memtable rec_scn not stable", {"rec_scn", "max_consequent_callbacked_scn"}}, + {5, false, "memtable not ready for flush", + {"is_frozen_memtable", "get_write_ref", "get_unsynced_cnt", "current_right_boundary", "get_end_scn"}}, + {3, false, "memtable can not create dag successfully", {"error_code", "has been ready for flush time", "read for flush time"}}, + {2, false, "invalid data version to schedule medium merge", {"curr_data_version", "target_data_version"}}, + {1, false, "refresh ls locality cache failed", {"errno"}}, + {1, true, "maybe bad case: locality change and leader change", {"leader_exist"}}, + {0, false, "", {}}, +}; + +static_assert(sizeof(OB_SUSPECT_INFO_TYPES) / sizeof(ObDiagnoseInfoStruct) == SUSPECT_INFO_TYPE_MAX + 1, "Not enough initializer"); + +static constexpr ObDiagnoseInfoStruct OB_DAG_WARNING_INFO_TYPES[] = { + {2, true, "DAG_MINI_MERGE", {"ls_id", "tablet_id"}}, + {2, true, "DAG_MINOR_MERGE", {"ls_id", "tablet_id"}}, + {2, true, "DAG_MAJOR_MERGE", {"ls_id", "tablet_id"}}, + {2, true, "DAG_TX_TABLE_MERGE", {"ls_id", "tablet_id"}}, + {0, false, "DAG_WRITE_CKPT", {}}, + {3, false, "DAG_TYPE_MDS_TABLE_MERGE", {"ls_id", "tablet_id", "flush_scn"}}, + + {7, false, "complement data task", + {"ls_id", "source_tablet_id", "dest_tablet_id", "data_table_id", "target_table_id", "schema_version", "snapshot_version"}}, + {2, false, "unique check task", {"tablet_id", "index_id"}}, + {0, false, "DAG_SQL_BUILD_INDEX", {}}, + {3, false, "ddl table merge task", {"ls_id", "tablet_id", "rec_scn"}}, + + {3, true, "DAG_INITIAL_COMPLETE_MIGRATION", {"tenant_id", "ls_id", "op_type"}}, + {3, true, "DAG_START_COMPLETE_MIGRATION", {"tenant_id", "ls_id", "op_type"}}, + {3, true, "DAG_FINISH_COMPLETE_MIGRATION", {"tenant_id", "ls_id", "op_type"}}, + {3, true, "DAG_INITIAL_MIGRATION", {"tenant_id", "ls_id", "op_type"}}, + {3, true, "DAG_START_MIGRATION", {"tenant_id", "ls_id", "op_type"}}, + {3, true, "DAG_SYS_TABLETS_MIGRATION", {"tenant_id", "ls_id", "op_type"}}, + {4, true, "DAG_TABLET_MIGRATION", {"tenant_id", "ls_id", "tablet_id", "op_type"}}, + {3, true, "DAG_DATA_TABLETS_MIGRATION", {"tenant_id", "ls_id", "op_type"}}, + {4, true, "DAG_TABLET_GROUP_MIGRATION", {"tenant_id", "ls_id", "first_tablet_id", "op_type"}}, + {3, true, "DAG_MIGRATION_FINISH", {"tenant_id", "ls_id", "op_type"}}, + {3, true, "DAG_INITIAL_PREPARE_MIGRATION", {"tenant_id", "ls_id", "op_type"}}, + {3, true, "DAG_START_PREPARE_MIGRATION", {"tenant_id", "ls_id", "op_type"}}, + {3, true, "DAG_FINISH_PREPARE_MIGRATION", {"tenant_id", "ls_id", "op_type"}}, + + {0, false, "DAG_FAST_MIGRATE", {}}, + {0, false, "DAG_VALIDATE", {}}, + + {2, true, "DAG_TABLET_BACKFILL_TX", {"ls_id", "tablet_id"}}, + {1, true, "DAG_FINISH_BACKFILL_TX", {"ls_id"}}, + + {1, false, "DAG_BACKUP_META", {"ls_id"}}, + {5, false, "DAG_BACKUP_PREPAER", {"tenant_id", "backup_set_id", "ls_id", "turn_id", "retry_id"}}, + {3, false, "DAG_BACKUP_FINISH", {"tenant_id", "backup_set_id", "ls_id"}}, + {7, false, "DAG_BACKUP_DATA", + {"tenant_id", "backup_set_id", "backup_data_type", "ls_id", "turn_id", "retry_id", "task_id"}}, + {7, false, "DAG_PREFETCH_BACKUP_INFO", + {"tenant_id", "backup_set_id", "backup_data_type", "ls_id", "turn_id", "retry_id", "task_id"}}, + {6, false, "DAG_BACKUP_INDEX_REBUILD", + {"tenant_id", "backup_set_id", "backup_data_type", "ls_id", "turn_id", "retry_id"}}, + {3, false, "DAG_BACKUP_COMPLEMENT_LOG", {"tenant_id", "backup_set_id", "ls_id"}}, + + {0, false, "DAG_BACKUP_BACKUPSET", {}}, + {0, false, "DAG_BACKUP_ARCHIVELOG", {}}, + + {2, true, "DAG_INITIAL_LS_RESTORE", {"ls_id", "is_leader"}}, + {2, true, "DAG_START_LS_RESTORE", {"ls_id", "is_leader"}}, + {2, true, "DAG_SYS_TABLETS_RESTORE", {"ls_id", "is_leader"}}, + {2, true, "DAG_DATA_TABLETS_META_RESTORE", {"ls_id", "is_leader"}}, + {3, true, "DAG_TABLET_GROUP_META_RESTORE", {"ls_id", "first_tablet_id", "is_leader"}}, + {2, true, "DAG_FINISH_LS_RESTORE", {"ls_id", "is_leader"}}, + {3, true, "DAG_INITIAL_TABLET_GROUP_RESTORE", {"ls_id", "first_tablet_id", "is_leader"}}, + {3, true, "DAG_START_TABLET_GROUP_RESTORE", {"ls_id", "first_tablet_id", "is_leader"}}, + {3, true, "DAG_FINISH_TABLET_GROUP_RESTORE", {"ls_id", "first_tablet_id", "is_leader"}}, + {3, true, "DAG_TABLET_RESTORE", {"ls_id", "tablet_id", "is_leader"}}, + + {4, true, "DAG_BACKUP_CLEAN", {"tenant_id", "task_id", "ls_id", "id"}}, + + {1, true, "DAG_REMOVE_MEMBER", {"ls_id"}}, + + {3, true, "DAG_TRANSFER_BACKFILL_TX", {"tenant_id", "ls_id", "start_scn"}}, + {2, true, "TRANSFER_REPLACE_TABLE", {"tenant_id", "ls_id"}}, + + {0, false, "", {}}, +}; + +static_assert(sizeof(OB_DAG_WARNING_INFO_TYPES) / sizeof(ObDiagnoseInfoStruct) == ObDagType::DAG_TYPE_MAX + 1, "Not enough initializer"); + +} // namespace share +} // namespace oceanbase +#endif diff --git a/src/share/scheduler/ob_sys_task_stat.cpp b/src/share/scheduler/ob_sys_task_stat.cpp index e708d9ea3..0515c26cc 100644 --- a/src/share/scheduler/ob_sys_task_stat.cpp +++ b/src/share/scheduler/ob_sys_task_stat.cpp @@ -35,7 +35,9 @@ const static char *ObSysTaskTypeStr[] = { "RESTORE", "BACKUP_CLEAN", "BACKFILL_TX", - "REMOVE_MEMBER" + "REMOVE_MEMBER", + "TRANSFER", + "MDS_TABLE_MERGE" }; const char *sys_task_type_to_str(const ObSysTaskType &type) diff --git a/src/share/scheduler/ob_sys_task_stat.h b/src/share/scheduler/ob_sys_task_stat.h index 75c150788..482ed179e 100644 --- a/src/share/scheduler/ob_sys_task_stat.h +++ b/src/share/scheduler/ob_sys_task_stat.h @@ -49,6 +49,8 @@ enum ObSysTaskType BACKUP_CLEAN_TASK, BACKFILL_TX_TASK, REMOVE_MEMBER_TASK, + TRANSFER_TASK, + MDS_TABLE_MERGE_TASK, MAX_SYS_TASK_TYPE }; diff --git a/src/share/schema/ob_part_mgr_util.h b/src/share/schema/ob_part_mgr_util.h index 36a7baa13..5b0fb8d8c 100644 --- a/src/share/schema/ob_part_mgr_util.h +++ b/src/share/schema/ob_part_mgr_util.h @@ -138,8 +138,8 @@ public: Info() : object_id_(common::OB_INVALID_ID), tablet_id_(common::ObTabletID::INVALID_TABLET_ID), - part_idx_(common::OB_INVALID_ID), - subpart_idx_(common::OB_INVALID_ID), + part_idx_(common::OB_INVALID_INDEX), + subpart_idx_(common::OB_INVALID_INDEX), part_(NULL), partition_(NULL) {} ~Info() {} diff --git a/src/share/schema/ob_schema_getter_guard.cpp b/src/share/schema/ob_schema_getter_guard.cpp index 8abddb415..174867e39 100644 --- a/src/share/schema/ob_schema_getter_guard.cpp +++ b/src/share/schema/ob_schema_getter_guard.cpp @@ -5355,6 +5355,38 @@ GET_SIMPLE_TABLE_SCHEMAS_IN_DST_SCHEMA_FUNC_DEFINE(database) GET_SIMPLE_TABLE_SCHEMAS_IN_DST_SCHEMA_FUNC_DEFINE(tablegroup) # undef GET_SIMPLE_TABLE_SCHEMAS_IN_DST_SCHEMA_FUNC_DEFINE +int ObSchemaGetterGuard::get_primary_table_schema_in_tablegroup( + const uint64_t tenant_id, + const uint64_t tablegroup_id, + const ObSimpleTableSchemaV2 *&primary_table_schema) +{ + int ret = OB_SUCCESS; + primary_table_schema = NULL; + const ObSchemaMgr *mgr = NULL; + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("inner stat error", KR(ret)); + } else if (OB_INVALID_ID == tenant_id + || OB_INVALID_ID == tablegroup_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tablegroup_id)); + } else if (OB_FAIL(check_tenant_schema_guard(tenant_id))) { + LOG_WARN("fail to check tenant schema guard", KR(ret), K(tenant_id), K_(tenant_id)); + } else if (OB_FAIL(get_schema_mgr(tenant_id, mgr))) { + if (OB_TENANT_NOT_EXIST == ret) { + ret = ignore_tenant_not_exist_error(tenant_id) ? OB_SUCCESS : ret; + } + if (OB_FAIL(ret)) { + LOG_WARN("fail to get schema mgr", KR(ret), K(tenant_id)); + } + } else if (OB_ISNULL(mgr)) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("get simple schema in lazy mode not supported", KR(ret), K(tenant_id)); + } else if (OB_FAIL(mgr->get_primary_table_schema_in_tablegroup(tenant_id, tablegroup_id, primary_table_schema))) { + LOG_WARN("get primary table schema in tablegroup failed", KR(ret), K(tenant_id), K(tablegroup_id)); + } + return ret; +} int ObSchemaGetterGuard::get_simple_tenant_schemas( ObIArray &tenant_schemas) const diff --git a/src/share/schema/ob_schema_getter_guard.h b/src/share/schema/ob_schema_getter_guard.h index e1342f248..3af007b36 100644 --- a/src/share/schema/ob_schema_getter_guard.h +++ b/src/share/schema/ob_schema_getter_guard.h @@ -267,6 +267,10 @@ public: int get_table_schemas_in_tablegroup(const uint64_t tenant_id, const uint64_t tablegroup_id, common::ObIArray &table_schemas); + int get_primary_table_schema_in_tablegroup(const uint64_t tenant_id, + const uint64_t tablegroup_id, + const ObSimpleTableSchemaV2 *&primary_table_schema); + int get_table_schemas_in_tablespace(const uint64_t tenant_id, const uint64_t tablespace_id, common::ObIArray &table_schemas); diff --git a/src/share/schema/ob_schema_mgr.cpp b/src/share/schema/ob_schema_mgr.cpp index d8ce1f3b1..28b08ab9c 100644 --- a/src/share/schema/ob_schema_mgr.cpp +++ b/src/share/schema/ob_schema_mgr.cpp @@ -380,6 +380,8 @@ ObSimpleTablegroupSchema &ObSimpleTablegroupSchema::operator =(const ObSimpleTab partition_schema_version_ = other.partition_schema_version_; if (OB_FAIL(deep_copy_str(other.tablegroup_name_, tablegroup_name_))) { LOG_WARN("Fail to deep copy tablegroup_name", K(ret)); + } else if (OB_FAIL(deep_copy_str(other.sharding_, sharding_))) { + LOG_WARN("Fail to deep copy sharding", K(ret)); } if (OB_FAIL(ret)) { error_ret_ = ret; @@ -398,7 +400,8 @@ bool ObSimpleTablegroupSchema::operator ==(const ObSimpleTablegroupSchema &other && schema_version_ == other.schema_version_ && tablegroup_name_ == other.tablegroup_name_ && partition_status_ == other.partition_status_ - && partition_schema_version_ == other.partition_schema_version_) { + && partition_schema_version_ == other.partition_schema_version_ + && sharding_ == other.sharding_) { ret = true; } @@ -414,6 +417,7 @@ void ObSimpleTablegroupSchema::reset() tablegroup_name_.reset(); partition_status_ = PARTITION_STATUS_ACTIVE; partition_schema_version_ = 0;// Issues left over from history, set to 0 + sharding_.reset(); } bool ObSimpleTablegroupSchema::is_valid() const @@ -434,6 +438,7 @@ int64_t ObSimpleTablegroupSchema::get_convert_size() const convert_size += sizeof(ObSimpleTablegroupSchema); convert_size += tablegroup_name_.length() + 1; + convert_size += sharding_.length() + 1; return convert_size; } @@ -829,7 +834,7 @@ int ObSchemaMgr::deep_copy(const ObSchemaMgr &other) const SCHEMA_TYPE *schema = *iter; \ if (OB_ISNULL(schema)) { \ ret = OB_ERR_UNEXPECTED; \ - LOG_WARN("NULL ptr", K(schema)); \ + LOG_WARN("NULL ptr", K(ret), KP(schema)); \ } else if (OB_FAIL(add_##SCHEMA(*schema))) { \ LOG_WARN("add "#SCHEMA" failed", K(ret), K(*schema)); \ } \ @@ -3777,7 +3782,7 @@ int ObSchemaMgr::get_available_tenant_ids(ObIArray &tenant_ids) const for (; OB_SUCC(ret) && iter != SCHEMA##_infos_.end() && !is_stop; iter++) { \ if (OB_ISNULL(schema = *iter)) { \ ret = OB_ERR_UNEXPECTED; \ - LOG_WARN("NULL ptr", K(schema), K(ret)); \ + LOG_WARN("NULL ptr", K(ret), KP(schema)); \ } else if (tenant_id != schema->get_tenant_id()) { \ is_stop = true; \ } else if (OB_FAIL(schema_array.push_back(schema))) { \ @@ -3826,7 +3831,7 @@ GET_SCHEMAS_IN_TENANT_FUNC_DEFINE(tablegroup, ObSimpleTablegroupSchema, ObTenant for (; OB_SUCC(ret) && iter != table_infos_.end() && !is_stop; iter++) { \ if (OB_ISNULL(schema = *iter)) { \ ret = OB_ERR_UNEXPECTED; \ - LOG_WARN("NULL ptr", K(schema), K(ret)); \ + LOG_WARN("NULL ptr", K(ret), KP(schema)); \ } else if (tenant_id != schema->get_tenant_id()) { \ is_stop = true; \ } else if (dst_schema_id == schema->get_##DST_SCHEMA##_id()) { \ @@ -3839,11 +3844,100 @@ GET_SCHEMAS_IN_TENANT_FUNC_DEFINE(tablegroup, ObSimpleTablegroupSchema, ObTenant return ret; \ } GET_TABLE_SCHEMAS_IN_DST_SCHEMA_FUNC_DEFINE(database); -GET_TABLE_SCHEMAS_IN_DST_SCHEMA_FUNC_DEFINE(tablegroup); +// GET_TABLE_SCHEMAS_IN_DST_SCHEMA_FUNC_DEFINE(tablegroup); GET_TABLE_SCHEMAS_IN_DST_SCHEMA_FUNC_DEFINE(tablespace); #undef GET_TABLE_SCHEMAS_IN_DST_SCHEMA_FUNC_DEFINE +int ObSchemaMgr::get_primary_table_schema_in_tablegroup( + const uint64_t tenant_id, + const uint64_t tablegroup_id, + const ObSimpleTableSchemaV2 *&primary_table_schema) const + { + int ret = OB_SUCCESS; + primary_table_schema = NULL; + if (OB_UNLIKELY(!check_inner_stat())) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id + || OB_INVALID_ID == tablegroup_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), + "tablegroup_id", tablegroup_id); + } else if (OB_UNLIKELY(tenant_id_ != tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_id not matched", KR(ret), K(tenant_id), K_(tenant_id)); + } else { + const ObSimpleTableSchemaV2 *schema = NULL; + ObTenantTableId tenant_table_id_lower(tenant_id, OB_MIN_ID); + ConstTableIterator iter = table_infos_.lower_bound(tenant_table_id_lower, + compare_with_tenant_table_id); + bool is_stop = false; + for (; OB_SUCC(ret) && iter != table_infos_.end() && !is_stop; iter++) { + if (OB_ISNULL(schema = *iter)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", KR(ret), KP(schema)); + } else if (OB_UNLIKELY(tenant_id != schema->get_tenant_id())) { + is_stop = true; + } else if (tablegroup_id == schema->get_tablegroup_id()) { + if (schema->is_user_table() + || schema->is_mysql_tmp_table() + || schema->is_sys_table()) { + primary_table_schema = schema; + is_stop = true; + } + } + } + } + return ret; + } + +int ObSchemaMgr::get_table_schemas_in_tablegroup( + const uint64_t tenant_id, + const uint64_t dst_schema_id, + ObIArray &schema_array) const +{ + int ret = OB_SUCCESS; + schema_array.reset(); + if (!check_inner_stat()) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_INVALID_ID == tenant_id + || OB_INVALID_ID == dst_schema_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), + "tablegroup_id", dst_schema_id); + } else if (OB_INVALID_TENANT_ID != tenant_id_ + && OB_SYS_TENANT_ID != tenant_id_ + && tenant_id_ != tenant_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_id not matched", K(ret), K(tenant_id), K_(tenant_id)); + } else { + const ObSimpleTableSchemaV2 *schema = NULL; + ObTenantTableId tenant_table_id_lower(tenant_id, OB_MIN_ID); + ConstTableIterator iter = table_infos_.lower_bound(tenant_table_id_lower, + compare_with_tenant_table_id); + bool is_stop = false; + for (; OB_SUCC(ret) && iter != table_infos_.end() && !is_stop; iter++) { + if (OB_ISNULL(schema = *iter)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", K(ret), KP(schema)); + } else if (tenant_id != schema->get_tenant_id()) { + is_stop = true; + } else if (dst_schema_id == schema->get_tablegroup_id()) { + if (schema->is_user_table() + || schema->is_mysql_tmp_table() + || schema->is_sys_table()) { + if (OB_FAIL(schema_array.push_back(schema))) { + LOG_WARN("failed to push back table schema", K(ret)); + } + } + } + } + } + return ret; +} + int ObSchemaMgr::get_table_schemas_in_tenant( const uint64_t tenant_id, ObIArray &schema_array) const @@ -3865,7 +3959,7 @@ int ObSchemaMgr::get_table_schemas_in_tenant( for (; OB_SUCC(ret) && iter != table_infos_.end() && !is_stop; iter++) { if (OB_ISNULL(schema = *iter)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("NULL ptr", K(schema), K(ret)); + LOG_WARN("NULL ptr", K(ret), KP(schema)); } else if (tenant_id != schema->get_tenant_id()) { is_stop = true; } else if (OB_FAIL(schema_array.push_back(schema))) { @@ -4056,7 +4150,7 @@ int ObSchemaMgr::del_schemas_in_tenant(const uint64_t tenant_id) for (; OB_SUCC(ret) && iter != SCHEMA##_infos_.end() && !is_stop; iter++) { \ if (OB_ISNULL(schema = *iter)) { \ ret = OB_ERR_UNEXPECTED; \ - LOG_WARN("NULL ptr", K(schema), K(ret)); \ + LOG_WARN("NULL ptr", K(ret), KP(schema)); \ } else if (tenant_id != schema->get_tenant_id()) { \ is_stop = true; \ } else if (OB_FAIL(schemas.push_back(schema))) { \ @@ -4828,7 +4922,7 @@ void ObSchemaMgr::dump() const iter != SCHEMA##_infos_.end(); iter++) { \ SCHEMA_TYPE *schema = *iter; \ if (NULL == schema) { \ - LOG_INFO("NULL ptr", K(schema)); \ + LOG_INFO("NULL ptr", KP(schema)); \ } else { \ LOG_INFO(#SCHEMA, K(*schema)); \ } \ diff --git a/src/share/schema/ob_schema_mgr.h b/src/share/schema/ob_schema_mgr.h index 27b367dbb..0147b398c 100644 --- a/src/share/schema/ob_schema_mgr.h +++ b/src/share/schema/ob_schema_mgr.h @@ -256,9 +256,10 @@ public: K_(schema_version), K_(tablegroup_name), K_(partition_status), - K_(partition_schema_version)); + K_(partition_schema_version), + K_(sharding)); virtual void reset(); - inline bool is_valid() const; + bool is_valid() const; inline int64_t get_convert_size() const; inline void set_tenant_id(const uint64_t tenant_id) { tenant_id_ = tenant_id; } inline uint64_t get_tenant_id() const { return tenant_id_; } @@ -270,6 +271,9 @@ public: { return deep_copy_str(tablegroup_name, tablegroup_name_); } inline const char *get_tablegroup_name_str() const { return extract_str(tablegroup_name_); } inline const common::ObString &get_tablegroup_name() const { return tablegroup_name_; } + inline int set_sharding(const common::ObString &sharding) + { return deep_copy_str(sharding, sharding_); } + inline const common::ObString &get_sharding() const { return sharding_; } inline ObTenantTablegroupId get_tenant_tablegroup_id() const { return ObTenantTablegroupId(tenant_id_, tablegroup_id_); } @@ -286,6 +290,10 @@ public: bool is_in_splitting() const { return partition_status_ == PARTITION_STATUS_LOGICAL_SPLITTING || partition_status_ == PARTITION_STATUS_PHYSICAL_SPLITTING; } bool has_self_partition() const { return false; } + + bool is_sharding_none() const { return sharding_ == OB_PARTITION_SHARDING_NONE; } + bool is_sharding_partition() const { return sharding_ == OB_PARTITION_SHARDING_PARTITION; } + bool is_sharding_adaptive() const { return sharding_ == OB_PARTITION_SHARDING_ADAPTIVE; } private: uint64_t tenant_id_; uint64_t tablegroup_id_; @@ -293,6 +301,7 @@ private: common::ObString tablegroup_name_; ObPartitionStatus partition_status_; int64_t partition_schema_version_; + common::ObString sharding_; }; template @@ -761,6 +770,10 @@ public: const uint64_t tenant_id, common::ObIArray &schema_array) const; #undef GET_TABLE_SCHEMAS_IN_DST_SCHEMA_FUNC_DECLARE + int get_primary_table_schema_in_tablegroup( + const uint64_t tenant_id, + const uint64_t tablegroup_id, + const ObSimpleTableSchemaV2 *&primary_table_schema) const; int check_database_exists_in_tablegroup( const uint64_t tenant_id, const uint64_t tablegroup_id, diff --git a/src/share/schema/ob_schema_mgr_cache.cpp b/src/share/schema/ob_schema_mgr_cache.cpp old mode 100644 new mode 100755 index d1148419d..67fb3f1e5 --- a/src/share/schema/ob_schema_mgr_cache.cpp +++ b/src/share/schema/ob_schema_mgr_cache.cpp @@ -376,6 +376,7 @@ static const char* ref_info_type_strs[] = { "SCHEMA_RECORDER", "SPI_RESULT_SET", "PL_PREPARE_RESULT", + "PARTITION_BALANCE", "MOD_MAX", }; diff --git a/src/share/schema/ob_schema_mgr_cache.h b/src/share/schema/ob_schema_mgr_cache.h old mode 100644 new mode 100755 index bde7669e0..d5a8fb2a7 --- a/src/share/schema/ob_schema_mgr_cache.h +++ b/src/share/schema/ob_schema_mgr_cache.h @@ -91,6 +91,7 @@ struct ObSchemaMgrItem MOD_SCHEMA_RECORDER = 28, MOD_SPI_RESULT_SET = 29, MOD_PL_PREPARE_RESULT = 30, + MOD_PARTITION_BALANCE = 31, MOD_MAX }; ObSchemaMgrItem() diff --git a/src/share/schema/ob_schema_printer.cpp b/src/share/schema/ob_schema_printer.cpp index a46979652..e27e65dfe 100644 --- a/src/share/schema/ob_schema_printer.cpp +++ b/src/share/schema/ob_schema_printer.cpp @@ -2644,8 +2644,6 @@ int ObSchemaPrinter::print_tablegroup_definition( SHARE_SCHEMA_LOG(WARN, "fail to print create tablegroup prefix", K(ret), K(tablegroup_schema->get_tablegroup_name())); } else if (OB_FAIL(print_tablegroup_definition_tablegroup_options(*tablegroup_schema, buf, buf_len, pos, agent_mode))) { SHARE_SCHEMA_LOG(WARN, "fail to print tablegroup options", K(ret), K(*tablegroup_schema)); - } else if (OB_FAIL(print_tablegroup_definition_partition_options(*tablegroup_schema, buf, buf_len, pos, agent_mode, tz_info))) { - SHARE_SCHEMA_LOG(WARN, "fail to print partition options", K(ret), K(*tablegroup_schema)); } SHARE_SCHEMA_LOG(DEBUG, "print tablegroup schema", K(ret), K(*tablegroup_schema)); return ret; @@ -2703,66 +2701,22 @@ int ObSchemaPrinter::print_tablegroup_definition_tablegroup_options( SHARE_SCHEMA_LOG(WARN, "fail to print tablegroup_id", K(ret), K(tablegroup_schema.get_tablegroup_id())); } } - return ret; -} - -int ObSchemaPrinter::print_tablegroup_definition_partition_options( - const ObTablegroupSchema &tablegroup_schema, - char* buf, - const int64_t& buf_len, - int64_t& pos, - bool agent_mode, - const ObTimeZoneInfo *tz_info) const -{ - int ret = OB_SUCCESS; - const uint64_t tablegroup_id = tablegroup_schema.get_tablegroup_id(); - if (tablegroup_id <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tablegroup_id is invalid", K(ret), K(tablegroup_id)); - } else if (is_sys_tablegroup_id(tablegroup_id)) { - // skip - } else if (PARTITION_LEVEL_ONE == tablegroup_schema.get_part_level() - || PARTITION_LEVEL_TWO == tablegroup_schema.get_part_level()) { - ObString disp_part_fun_expr_str; - ObSqlString disp_part_str; - bool is_subpart = false; - const ObPartitionSchema *partition_schema = &tablegroup_schema; - if (PARTITION_LEVEL_TWO == tablegroup_schema.get_part_level()) { - is_subpart = true; - } - if (OB_FAIL(databuff_printf(buf, buf_len, pos, "\n"))) { - SHARE_SCHEMA_LOG(WARN, "fail to print enter", K(ret)); - } else if (OB_FAIL(print_tablegroup_partition_func(tablegroup_schema, disp_part_str, is_subpart))) { - SHARE_SCHEMA_LOG(WARN, "failed to print part func", K(ret)); - } else if (FALSE_IT(disp_part_fun_expr_str = disp_part_str.string())) { - // will not reach here - } else if (OB_FAIL(databuff_printf(buf, buf_len, pos, " %.*s", - disp_part_fun_expr_str.length(), - disp_part_fun_expr_str.ptr()))) { - SHARE_SCHEMA_LOG(WARN, "fail to printf partition expr", K(ret), K(disp_part_fun_expr_str)); - } else if (is_subpart && partition_schema->sub_part_template_def_valid()) { - if (OB_FAIL(print_template_sub_partition_elements(partition_schema, buf, buf_len, pos, tz_info, true))) { - SHARE_SCHEMA_LOG(WARN, "fail to print sub partition elements", K(ret)); - } - } - - if (OB_SUCC(ret)) { - bool tablegroup_def = true; - bool print_sub_part_element = !partition_schema->sub_part_template_def_valid(); - if (tablegroup_schema.is_range_part()) { - if (OB_FAIL(print_range_partition_elements(partition_schema, buf, buf_len, pos, - print_sub_part_element, agent_mode, tablegroup_def, tz_info))) { - SHARE_SCHEMA_LOG(WARN, "fail to print partition elements", K(ret)); - } - } else if (tablegroup_schema.is_list_part()) { - if (OB_FAIL(print_list_partition_elements(partition_schema, buf, buf_len, pos, - print_sub_part_element, agent_mode, tablegroup_def, tz_info))) { - SHARE_SCHEMA_LOG(WARN, "fail to print partition elements", K(ret)); - } - } else if (is_hash_like_part(tablegroup_schema.get_part_option().get_part_func_type())) { - if (OB_FAIL(databuff_printf(buf, buf_len, pos, " partitions %ld\n", tablegroup_schema.get_first_part_num()))) { - SHARE_SCHEMA_LOG(WARN, "fail to printf partition number", K(ret), K(tablegroup_schema.get_first_part_num())); - } + if (OB_SUCC(ret)) { + bool is_oracle_mode = false; + uint64_t compat_version = OB_INVALID_VERSION; + uint64_t tenant_id = tablegroup_schema.get_tenant_id(); + if (OB_FAIL(tablegroup_schema.check_if_oracle_compat_mode(is_oracle_mode))) { + SHARE_SCHEMA_LOG(WARN, "fail to check oracle mode", KR(ret), K(tablegroup_id)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) { + LOG_WARN("get min data_version failed", K(ret), K(tenant_id)); + } else if (compat_version >= DATA_VERSION_4_2_0_0) { + const ObString sharding = tablegroup_schema.get_sharding(); + if (OB_FAIL(databuff_printf(buf, buf_len, pos, + is_oracle_mode + ? " SHARDING = \"%.*s\"" + : " SHARDING = %.*s", + sharding.length(), sharding.ptr()))) { + SHARE_SCHEMA_LOG(WARN, "fail to print tablegroup sharding", K(ret), K(tablegroup_schema.get_sharding())); } } } diff --git a/src/share/schema/ob_schema_printer.h b/src/share/schema/ob_schema_printer.h index 90feee5c7..1f63ec87d 100644 --- a/src/share/schema/ob_schema_printer.h +++ b/src/share/schema/ob_schema_printer.h @@ -320,13 +320,6 @@ public: const int64_t& buf_len, int64_t& pos, bool agent_mode = false) const; - int print_tablegroup_definition_partition_options( - const share::schema::ObTablegroupSchema &tablegroup_schema, - char* buf, - const int64_t& buf_len, - int64_t& pos, - bool agent_mode, - const common::ObTimeZoneInfo *tz_info) const; int print_tenant_definition(uint64_t tenant_id, common::ObMySQLProxy *sql_proxy, char* buf, diff --git a/src/share/schema/ob_schema_retrieve_utils.h b/src/share/schema/ob_schema_retrieve_utils.h index 867a2a32f..1569c6233 100644 --- a/src/share/schema/ob_schema_retrieve_utils.h +++ b/src/share/schema/ob_schema_retrieve_utils.h @@ -638,6 +638,12 @@ public: template static int cascaded_generated_column(TABLE_SCHEMA &table_schema); + + template + static int retrieve_table_latest_schema_versions( + T &result, + ObIArray &table_schema_versions); + private: template static bool compare_table_id(const T *table_schema, const uint64_t table_id); diff --git a/src/share/schema/ob_schema_retrieve_utils.ipp b/src/share/schema/ob_schema_retrieve_utils.ipp index bd862af97..3c5156cbb 100644 --- a/src/share/schema/ob_schema_retrieve_utils.ipp +++ b/src/share/schema/ob_schema_retrieve_utils.ipp @@ -1510,6 +1510,7 @@ int ObSchemaRetrieveUtils::fill_tablegroup_schema( int ret = common::OB_SUCCESS; tg_schema.reset(); is_deleted = false; + ObString sharding_default(OB_PARTITION_SHARDING_ADAPTIVE); tg_schema.set_tenant_id(tenant_id); EXTRACT_INT_FIELD_TO_CLASS_MYSQL_WITH_TENANT_ID(result, tablegroup_id, tg_schema, tenant_id); EXTRACT_INT_FIELD_MYSQL(result, "is_deleted", is_deleted, bool); @@ -1547,6 +1548,7 @@ int ObSchemaRetrieveUtils::fill_tablegroup_schema( tg_schema.get_sub_part_option().set_part_num(0); tg_schema.set_def_sub_part_num(0); } + EXTRACT_VARCHAR_FIELD_TO_CLASS_MYSQL_WITH_DEFAULT_VALUE(result, sharding, tg_schema, true, true, sharding_default); } SQL_LOG(DEBUG, "fill tablegroup schema", K(ret), K(tg_schema)); return ret; @@ -3970,6 +3972,7 @@ int ObSchemaRetrieveUtils::fill_tablegroup_schema( tablegroup_schema.reset(); is_deleted = false; tablegroup_schema.set_tenant_id(tenant_id); + ObString sharding_default(OB_PARTITION_SHARDING_ADAPTIVE); EXTRACT_INT_FIELD_TO_CLASS_MYSQL_WITH_TENANT_ID(result, tablegroup_id, tablegroup_schema, tenant_id); EXTRACT_INT_FIELD_MYSQL(result, "is_deleted", is_deleted, bool); if (!is_deleted) { @@ -3977,6 +3980,7 @@ int ObSchemaRetrieveUtils::fill_tablegroup_schema( EXTRACT_VARCHAR_FIELD_TO_CLASS_MYSQL(result, tablegroup_name, tablegroup_schema); EXTRACT_INT_FIELD_TO_CLASS_MYSQL_WITH_DEFAULT_VALUE(result, partition_status, tablegroup_schema, ObPartitionStatus, true, ObSchemaService::g_ignore_column_retrieve_error_, 0); EXTRACT_INT_FIELD_TO_CLASS_MYSQL_WITH_DEFAULT_VALUE(result, partition_schema_version, tablegroup_schema, int64_t, true, ObSchemaService::g_ignore_column_retrieve_error_, 0); + EXTRACT_VARCHAR_FIELD_TO_CLASS_MYSQL_WITH_DEFAULT_VALUE(result, sharding, tablegroup_schema, true, true, sharding_default); } return ret; } @@ -5321,6 +5325,38 @@ int ObSchemaRetrieveUtils::fill_object_id(const uint64_t tenant_id, T &result, return ret; } +template +int ObSchemaRetrieveUtils::retrieve_table_latest_schema_versions( + T &result, + ObIArray &table_schema_versions) +{ + int ret = common::OB_SUCCESS; + ObTableLatestSchemaVersion table_schema_version; + + while (OB_SUCC(ret) && OB_SUCC(result.next())) { + table_schema_version.reset(); + uint64_t table_id = common::OB_INVALID_ID; + int64_t schema_version = common::OB_INVALID_VERSION; + bool is_deleted = false; + + EXTRACT_INT_FIELD_MYSQL(result, "table_id", table_id, uint64_t); + EXTRACT_INT_FIELD_MYSQL(result, "schema_version", schema_version, int64_t); + EXTRACT_INT_FIELD_MYSQL(result, "is_deleted", is_deleted, bool); + + if (FAILEDx(table_schema_version.init(table_id, schema_version, is_deleted))) { + LOG_WARN("init failed", KR(ret), K(table_id), K(schema_version), K(is_deleted)); + } else if (OB_FAIL(table_schema_versions.push_back(table_schema_version))) { + LOG_WARN("push back failed", KR(ret), K(table_schema_version), K(table_schema_versions)); + } + } + if (ret == common::OB_ITER_END) { + ret = common::OB_SUCCESS; + } else { + SHARE_SCHEMA_LOG(WARN, "fail to get all table latest schema version", KR(ret)); + } + return ret; +} + } //end of namespace schema } //end of namespace share } //end of namespace oceanbase diff --git a/src/share/schema/ob_schema_service.cpp b/src/share/schema/ob_schema_service.cpp index 27de3f779..c53fa213f 100644 --- a/src/share/schema/ob_schema_service.cpp +++ b/src/share/schema/ob_schema_service.cpp @@ -513,23 +513,6 @@ int AlterTableSchema::assign(const ObTableSchema &src_schema) return ret; } -int AlterTableSchema::assign_tablegroup_partition(const ObTablegroupSchema &src_schema) -{ - int ret = OB_SUCCESS; - reset_partition_schema(); - ret = ObTableSchema::assign_tablegroup_partition(src_schema); - if (OB_FAIL(ret)) { - LOG_WARN("failed to assign table schema", K(ret)); - } else if (OB_FAIL(src_schema.get_split_rowkey().deep_copy(split_high_bound_val_, *get_allocator()))) { - LOG_WARN("failed to deep copy rowkey", K(ret), K(src_schema)); - } else if (OB_FAIL(deep_copy_str(src_schema.get_split_partition_name(), split_partition_name_))) { - LOG_WARN("failed to deep copy split partition name", K(ret), K(src_schema)); - } else if (OB_FAIL(src_schema.get_split_list_row_values().deep_copy(split_list_row_values_, *get_allocator()))) { - LOG_WARN("failed to deep copy list row values", K(ret), K(src_schema)); - } - return ret; -} - int AlterTableSchema::add_alter_column(const AlterColumnSchema &alter_column_schema, const bool need_allocate) { diff --git a/src/share/schema/ob_schema_service.h b/src/share/schema/ob_schema_service.h index ffcde8b69..839c07686 100644 --- a/src/share/schema/ob_schema_service.h +++ b/src/share/schema/ob_schema_service.h @@ -595,8 +595,6 @@ public: common::ObRowkey split_high_bound_val_; common::ObRowkey split_list_row_values_; int assign(const ObTableSchema &src_schema); - // In order to handle partition management operations at the tablegroup level - int assign_tablegroup_partition(const ObTablegroupSchema &src_schema); //virtual int add_partition(const ObPartition &part); //virtual int add_subpartition(const ObSubPartition &sub_part); //virtual int alloc_partition(const ObPartition *&partition); @@ -1079,6 +1077,12 @@ public: const uint64_t table_id, int64_t &last_schema_version) = 0; + virtual int get_table_latest_schema_versions( + common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const common::ObIArray &table_ids, + common::ObIArray &table_schema_versions) = 0; + // whether we can see the expected version or not // @return OB_SCHEMA_EAGAIN when not readable virtual int can_read_schema_version(const ObRefreshSchemaStatus &schema_status, int64_t expected_version) diff --git a/src/share/schema/ob_schema_service_sql_impl.cpp b/src/share/schema/ob_schema_service_sql_impl.cpp index 633796b96..de7123cba 100644 --- a/src/share/schema/ob_schema_service_sql_impl.cpp +++ b/src/share/schema/ob_schema_service_sql_impl.cpp @@ -5561,11 +5561,11 @@ int ObSchemaServiceSQLImpl::sort_table_partition_info( lib::CompatModeGuard g(is_oracle_mode ? lib::Worker::CompatMode::ORACLE : lib::Worker::CompatMode::MYSQL); - if (OB_FAIL(sort_partition_array(table_schema))) { + if (OB_FAIL(ObSchemaServiceSQLImpl::sort_partition_array(table_schema))) { LOG_WARN("failed to sort partition array", KR(ret), K(table_schema)); } else if (OB_FAIL(try_mock_partition_array(table_schema))) { LOG_WARN("fail to mock partition array", KR(ret), K(table_schema)); - } else if (OB_FAIL(sort_subpartition_array(table_schema))) { + } else if (OB_FAIL(ObSchemaServiceSQLImpl::sort_subpartition_array(table_schema))) { LOG_WARN("failed to sort subpartition array", KR(ret), K(table_schema)); } } @@ -5609,9 +5609,9 @@ int ObSchemaServiceSQLImpl::sort_tablegroup_partition_info(ObTablegroupSchema &t lib::CompatModeGuard g(is_oracle_mode ? lib::Worker::CompatMode::ORACLE : lib::Worker::CompatMode::MYSQL); - if (OB_FAIL(sort_partition_array(tablegroup_schema))) { + if (OB_FAIL(ObSchemaServiceSQLImpl::sort_partition_array(tablegroup_schema))) { LOG_WARN("failed to sort partition array", KR(ret), K(tablegroup_schema)); - } else if (OB_FAIL(sort_subpartition_array(tablegroup_schema))) { + } else if (OB_FAIL(ObSchemaServiceSQLImpl::sort_subpartition_array(tablegroup_schema))) { LOG_WARN("failed to sort subpartition array", KR(ret), K(tablegroup_schema)); } } @@ -8281,6 +8281,36 @@ int ObSchemaServiceSQLImpl::get_first_trans_end_schema_version( return ret; } +//just sort for table which is ready to add tablegroup +int ObSchemaServiceSQLImpl::sort_table_partition_info_v2( + ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + bool is_oracle_mode = false; + if (!table_schema.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table_schema", KR(ret), K(table_schema)); + } else if (OB_FAIL(table_schema.check_if_oracle_compat_mode(is_oracle_mode))) { + LOG_WARN("fail to check oracle mode", KR(ret), + "tenant_id", table_schema.get_tenant_id(), "table_id", table_schema.get_table_id()); + } else { + // Value comparsion is differ from mysql and oracle. eg: + // mysql: min < null < other < max + // oracle: min < other < null < max + // To make sorted result stable, compat guard should be used. + lib::CompatModeGuard g(is_oracle_mode ? + lib::Worker::CompatMode::ORACLE : + lib::Worker::CompatMode::MYSQL); + if (OB_FAIL(ObSchemaServiceSQLImpl::sort_partition_array(table_schema))) { + LOG_WARN("failed to sort partition array", KR(ret), K(table_schema)); + } else if (OB_FAIL(ObSchemaServiceSQLImpl::sort_subpartition_array(table_schema))) { + LOG_WARN("failed to sort subpartition array", KR(ret), K(table_schema)); + } + } + LOG_TRACE("fetch partition info", KR(ret), K(table_schema)); + return ret; +} + // link table. int ObSchemaServiceSQLImpl::get_link_table_schema(const ObDbLinkSchema *dblink_schema, @@ -8733,6 +8763,41 @@ int ObSchemaServiceSQLImpl::try_mock_link_table_column(ObTableSchema &table_sche return ret; } +int ObSchemaServiceSQLImpl::get_table_latest_schema_versions( + common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const common::ObIArray &table_ids, + common::ObIArray &table_schema_versions) +{ + int ret = OB_SUCCESS; + table_schema_versions.reset(); + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || table_ids.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(table_ids)); + } else if (OB_FAIL(table_schema_versions.reserve(table_ids.count()))) { + LOG_WARN("reserve failed", KR(ret), "count", table_ids.count()); + } else { + int64_t start_idx = 0; + int64_t end_idx = min(MAX_IN_QUERY_PER_TIME, table_ids.count()); + while (OB_SUCC(ret) && start_idx < end_idx) { + if (OB_FAIL(fetch_table_latest_schema_versions_( + sql_client, + tenant_id, + table_ids, + start_idx, + end_idx, + table_schema_versions))) { + LOG_WARN("fail to fetch table latest schema versions", + KR(ret), K(tenant_id), K(table_ids), K(start_idx), K(end_idx)); + } else { + start_idx = end_idx; + end_idx = min(start_idx + MAX_IN_QUERY_PER_TIME, table_ids.count()); + } + } + } + return ret; +} + // this timeout context will take effective when ObTimeoutCtx/THIS_WORKER.timeout is not set. int ObSchemaServiceSQLImpl::set_refresh_full_schema_timeout_ctx_( ObISQLClient &sql_client, @@ -8766,6 +8831,62 @@ int ObSchemaServiceSQLImpl::set_refresh_full_schema_timeout_ctx_( return ret; } +int ObSchemaServiceSQLImpl::fetch_table_latest_schema_versions_( + common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const common::ObIArray &table_ids, + const int64_t start_idx, + const int64_t end_idx, + common::ObIArray &table_schema_versions) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || table_ids.empty() + || start_idx < 0 + || start_idx >= end_idx + || end_idx > table_ids.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(table_ids), K(start_idx), K(end_idx)); + } else if (OB_FAIL(sql.append_fmt( + "SELECT table_id, schema_version, is_deleted FROM " + "(SELECT table_id, schema_version, is_deleted, " + "ROW_NUMBER() OVER (PARTITION BY table_id ORDER BY schema_version DESC) AS rn " + "FROM %s WHERE tenant_id = 0 AND table_id IN (", + OB_ALL_TABLE_HISTORY_TNAME))) { + LOG_WARN("append fmt failed", KR(ret), K(sql)); + } else { + for (int64_t idx = start_idx; OB_SUCC(ret) && (idx < end_idx); ++idx) { + const uint64_t table_id = table_ids.at(idx); + if (OB_UNLIKELY(OB_INVALID_ID == table_ids.at(idx))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table_id", KR(ret), K(table_id), K(table_ids)); + } else if (OB_FAIL(sql.append_fmt("%s%lu", start_idx == idx ? "" : ", ", table_id))) { + LOG_WARN("append fmt failed", KR(ret), K(idx), K(table_id), K(sql)); + } + } + if (FAILEDx(sql.append_fmt(")) WHERE rn = 1"))) { + LOG_WARN("append fmt failed", KR(ret), K(sql)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(sql_client.read(res, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get result", KR(ret)); + } else if (OB_FAIL(ObSchemaRetrieveUtils::retrieve_table_latest_schema_versions( + *result, + table_schema_versions))) { + LOG_WARN("retrieve table latest schema versions failed", + KR(ret), K(tenant_id), K(table_ids)); + } + } // end SMART_VAR + } + } + return ret; +} + int ObSchemaServiceSQLImpl::calc_refresh_full_schema_timeout_ctx_( ObISQLClient &sql_client, const uint64_t tenant_id, diff --git a/src/share/schema/ob_schema_service_sql_impl.h b/src/share/schema/ob_schema_service_sql_impl.h index 675bab572..eb20d6d4b 100644 --- a/src/share/schema/ob_schema_service_sql_impl.h +++ b/src/share/schema/ob_schema_service_sql_impl.h @@ -165,7 +165,6 @@ public: common::ObISQLClient &sql_client, common::ObIAllocator &allocator, ObTableSchema *&table_schema); - virtual int get_batch_table_schema(const ObRefreshSchemaStatus &schema_status, const int64_t schema_version, common::ObArray &table_ids, @@ -616,7 +615,16 @@ public: common::ObISQLClient &sql_client, const uint64_t tenant_id, int64_t &schema_version); + static int sort_table_partition_info_v2(ObTableSchema &table_schema); + // Get latest schema version from inner table for each table_id. + // The count of table_schema_versions may be less than the count of table_ids + // when table is deleted and the schema history is recycled. + virtual int get_table_latest_schema_versions( + common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const common::ObIArray &table_ids, + common::ObIArray &table_schema_versions); private: bool check_inner_stat(); int fetch_new_schema_id(const uint64_t tenant_id, const share::ObMaxIdType max_id_type, uint64_t &new_schema_id); @@ -925,11 +933,10 @@ private: int sort_tables_partition_info(const common::ObIArray &table_schema_array); template int sort_table_partition_info(SCHEMA &table_schema); - int sort_tablegroup_partition_info(ObTablegroupSchema &tablegroup_schema); - int sort_partition_array(ObPartitionSchema &partition_schema); - int sort_subpartition_array(ObPartitionSchema &partition_schema); + static int sort_partition_array(ObPartitionSchema &partition_schema); + static int sort_subpartition_array(ObPartitionSchema &partition_schema); template int try_mock_partition_array(SCHEMA &table_schema); @@ -976,6 +983,14 @@ private: const int64_t refreshed_schema_version, int64_t &schema_version); + int fetch_table_latest_schema_versions_( + common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const common::ObIArray &table_ids, + const int64_t start_idx, + const int64_t end_idx, + common::ObIArray &table_schema_versions); + int set_refresh_full_schema_timeout_ctx_( ObISQLClient &sql_client, const uint64_t tenant_id, diff --git a/src/share/schema/ob_schema_struct.cpp b/src/share/schema/ob_schema_struct.cpp index cf009c4b9..d2aece07a 100644 --- a/src/share/schema/ob_schema_struct.cpp +++ b/src/share/schema/ob_schema_struct.cpp @@ -1513,6 +1513,11 @@ int get_tenant_status(const ObString &str, ObTenantStatus &status) return ret; } +bool is_tenant_normal(ObTenantStatus &status) +{ + return TENANT_STATUS_NORMAL == status; +} + bool is_tenant_restore(ObTenantStatus &status) { return TENANT_STATUS_RESTORE == status || TENANT_STATUS_CREATING_STANDBY == status; @@ -4420,6 +4425,7 @@ ObTablegroupSchema::ObTablegroupSchema() schema_version_(OB_INVALID_VERSION), tablegroup_name_(), comment_(), + sharding_(), part_func_expr_num_(OB_INVALID_INDEX), sub_part_func_expr_num_(OB_INVALID_INDEX), split_partition_name_(), @@ -4436,6 +4442,7 @@ ObTablegroupSchema::ObTablegroupSchema(common::ObIAllocator *allocator) schema_version_(OB_INVALID_VERSION), tablegroup_name_(), comment_(), + sharding_(), part_func_expr_num_(OB_INVALID_INDEX), sub_part_func_expr_num_(OB_INVALID_INDEX), split_partition_name_(), @@ -4451,6 +4458,7 @@ ObTablegroupSchema::ObTablegroupSchema(const ObTablegroupSchema &other) schema_version_(OB_INVALID_VERSION), tablegroup_name_(), comment_(), + sharding_(), part_func_expr_num_(OB_INVALID_INDEX), sub_part_func_expr_num_(OB_INVALID_INDEX), split_partition_name_(), @@ -4504,6 +4512,8 @@ ObTablegroupSchema &ObTablegroupSchema::operator =(const ObTablegroupSchema &src LOG_WARN("Fail to deep copy comment, ", K(ret)); } else if (OB_FAIL(deep_copy_str(src_schema.split_partition_name_, split_partition_name_))) { LOG_WARN("fail to deep copy split partition name", K(ret)); + } else if (OB_FAIL(deep_copy_str(src_schema.sharding_, sharding_))) { + LOG_WARN("fail to deep copy split partition name", K(ret)); } else if (OB_FAIL(src_schema.split_high_bound_val_.deep_copy(split_high_bound_val_, *get_allocator()))) { LOG_WARN("fail to deep copy split row key", K(ret)); } else if (OB_FAIL(src_schema.split_list_row_values_.deep_copy(split_list_row_values_, *get_allocator()))) { @@ -4522,6 +4532,7 @@ int64_t ObTablegroupSchema::get_convert_size() const int64_t convert_size = sizeof(*this); convert_size += tablegroup_name_.length() + 1; convert_size += comment_.length() + 1; + convert_size += sharding_.length() + 1; convert_size += part_option_.get_convert_size() - sizeof(part_option_); convert_size += sub_part_option_.get_convert_size() - sizeof(sub_part_option_); convert_size += split_partition_name_.length() + 1; @@ -4554,6 +4565,7 @@ void ObTablegroupSchema::reset() split_partition_name_.reset(); split_high_bound_val_.reset(); split_list_row_values_.reset(); + sharding_.reset(); ObPartitionSchema::reset(); } @@ -4606,6 +4618,10 @@ OB_DEF_SERIALIZE(ObTablegroupSchema) } else { } } } + if (OB_SUCC(ret)) { + LST_DO_CODE(OB_UNIS_ENCODE, + sharding_); + } LOG_TRACE("serialize tablegroup schema", K(*this)); return ret; @@ -4643,6 +4659,8 @@ OB_DEF_SERIALIZE_SIZE(ObTablegroupSchema) LST_DO_CODE(OB_UNIS_ADD_LEN, sub_part_template_flags_); + LST_DO_CODE(OB_UNIS_ADD_LEN, + sharding_); return len; } @@ -4704,6 +4722,10 @@ OB_DEF_DESERIALIZE(ObTablegroupSchema) } } } + if (OB_SUCC(ret)) { + LST_DO_CODE(OB_UNIS_DECODE, + sharding_); + } LOG_WARN("serialize tablegroup schema", K(*this)); return ret; } @@ -4732,7 +4754,8 @@ int64_t ObTablegroupSchema::to_string(char *buf, const int64_t buf_len) const ObArrayWrap(hidden_partition_array_, hidden_partition_num_), K_(split_high_bound_val), K_(split_list_row_values), - K_(sub_part_template_flags)); + K_(sub_part_template_flags), + K_(sharding)); J_OBJ_END(); return pos; } @@ -13260,6 +13283,53 @@ OB_SERIALIZE_MEMBER(ObRlsContextSchema, context_name_, attribute_); +ObTableLatestSchemaVersion::ObTableLatestSchemaVersion() + : table_id_(OB_INVALID_ID), + schema_version_(OB_INVALID_VERSION), + is_deleted_(false) +{ +} + +void ObTableLatestSchemaVersion::reset() +{ + table_id_ = OB_INVALID_ID; + schema_version_ = OB_INVALID_VERSION; + is_deleted_ = false; +} + +int ObTableLatestSchemaVersion::init( + const uint64_t table_id, + const int64_t schema_version, + const bool is_deleted) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_ID == table_id || OB_INVALID_VERSION == schema_version)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(table_id), K(schema_version), K(is_deleted)); + } else { + table_id_ = table_id; + schema_version_ = schema_version; + is_deleted_ = is_deleted; + } + return ret; +} + +bool ObTableLatestSchemaVersion::is_valid() const +{ + return OB_INVALID_ID != table_id_ && OB_INVALID_VERSION != schema_version_; +} + +int ObTableLatestSchemaVersion::assign(const ObTableLatestSchemaVersion &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + table_id_ = other.table_id_; + schema_version_ = other.schema_version_; + is_deleted_ = other.is_deleted_; + } + return ret; +} + // // } //namespace schema diff --git a/src/share/schema/ob_schema_struct.h b/src/share/schema/ob_schema_struct.h old mode 100644 new mode 100755 index 4c6eef707..bde761840 --- a/src/share/schema/ob_schema_struct.h +++ b/src/share/schema/ob_schema_struct.h @@ -29,6 +29,8 @@ #include "share/ob_priv_common.h" #include "lib/worker.h" #include "objit/common/ob_item_type.h" +#include "lib/hash/ob_pointer_hashmap.h" +#include "lib/string/ob_sql_string.h" #ifdef __cplusplus extern "C" { @@ -509,6 +511,20 @@ inline bool is_index_local_storage(ObIndexType index_type) || INDEX_TYPE_SPATIAL_GLOBAL_LOCAL_STORAGE == index_type; } +inline bool is_aux_lob_table(const ObTableType &table_type) +{ + return AUX_LOB_META == table_type + || AUX_LOB_PIECE == table_type; +} + +inline bool is_related_table( + const ObTableType &table_type, + const ObIndexType &index_type) +{ + return is_index_local_storage(index_type) + || is_aux_lob_table(table_type); +} + inline bool index_has_tablet(const ObIndexType &index_type) { return INDEX_TYPE_NORMAL_LOCAL == index_type @@ -1425,6 +1441,7 @@ const char *ob_tenant_status_str(const ObTenantStatus); int get_tenant_status(const common::ObString &str, ObTenantStatus &status); bool is_tenant_restore(ObTenantStatus &status); +bool is_tenant_normal(ObTenantStatus &status); bool is_creating_standby_tenant_status(ObTenantStatus &status); class ObTenantSchema : public ObSchema { @@ -2514,6 +2531,7 @@ public: inline int set_tablegroup_name(const common::ObString &name) { return deep_copy_str(name, tablegroup_name_); } inline int set_table_name(const common::ObString &name) { return deep_copy_str(name, tablegroup_name_); } inline int set_comment(const common::ObString &comment) { return deep_copy_str(comment, comment_); } + inline int set_sharding(const common::ObString &sharding) { return deep_copy_str(sharding, sharding_); } inline int set_split_partition(const common::ObString &split_partition) { return deep_copy_str(split_partition, split_partition_name_); } inline int set_split_rowkey(const common::ObRowkey &rowkey) @@ -2527,6 +2545,7 @@ public: virtual uint64_t get_tablegroup_id() const override { return tablegroup_id_; } inline const char *get_tablegroup_name_str() const { return extract_str(tablegroup_name_); } inline const char *get_comment() const { return extract_str(comment_); } + inline const common::ObString &get_sharding() const { return sharding_; } inline const common::ObString &get_tablegroup_name() const { return tablegroup_name_; } inline const common::ObString &get_table_name() const { return tablegroup_name_; } virtual const char *get_entity_name() const override { return extract_str(tablegroup_name_); } @@ -2618,6 +2637,7 @@ private: int64_t schema_version_; common::ObString tablegroup_name_; common::ObString comment_; + common::ObString sharding_; //2.0 add int64_t part_func_expr_num_; int64_t sub_part_func_expr_num_; @@ -2674,7 +2694,8 @@ public: const PARTITION &l_part, const PARTITION &r_part, const ObPartitionFuncType part_type, - bool &is_equal); + bool &is_equal, + ObSqlString *user_error = NULL); static bool is_types_equal_for_partition_check( const bool is_oracle_mode, @@ -6300,13 +6321,24 @@ public: uint64_t constraint_id_; }; +#define ASSIGN_PARTITION_ERROR(ERROR_STRING, USER_ERROR) { \ + if (OB_SUCC(ret)) {\ + if (OB_NOT_NULL(ERROR_STRING)) { \ + if (OB_FAIL(ERROR_STRING->assign(USER_ERROR))) { \ + SHARE_SCHEMA_LOG(WARN, "fail to append user error", KR(ret));\ + }\ + }\ + }\ +}\ + template int ObPartitionUtils::check_partition_value( const bool is_oracle_mode, const PARTITION &l_part, const PARTITION &r_part, const ObPartitionFuncType part_type, - bool &is_equal) + bool &is_equal, + ObSqlString *user_error) { int ret = common::OB_SUCCESS; is_equal = true; @@ -6315,7 +6347,8 @@ int ObPartitionUtils::check_partition_value( } else if (is_range_part(part_type)) { if (l_part.get_high_bound_val().get_obj_cnt() != r_part.get_high_bound_val().get_obj_cnt()) { is_equal = false; - SHARE_SCHEMA_LOG(DEBUG, "fail to check partition value, value count not equal", + ASSIGN_PARTITION_ERROR(user_error, "range_part partition value count not equal"); + SHARE_SCHEMA_LOG(TRACE, "fail to check partition value, value count not equal", "left", l_part.get_high_bound_val(), "right", r_part.get_high_bound_val()); } else { @@ -6325,19 +6358,25 @@ int ObPartitionUtils::check_partition_value( // The obj comparison function does not require the same cs_level if (meta1.get_collation_type() == meta2.get_collation_type()) { is_equal = is_types_equal_for_partition_check(is_oracle_mode, meta1.get_type(), meta2.get_type()); + if (!is_equal) { + ASSIGN_PARTITION_ERROR(user_error, "range_part partition meta type not equal"); + SHARE_SCHEMA_LOG(TRACE, "fail to check partition values, value meta not equal", + "left", l_part.get_high_bound_val().get_obj_ptr()[i], + "right", r_part.get_high_bound_val().get_obj_ptr()[i], K(is_oracle_mode)); + } } else { is_equal = false; + ASSIGN_PARTITION_ERROR(user_error, "range_part partition collation type not matched"); SHARE_SCHEMA_LOG(TRACE, "collation type not matched", "left", meta1.get_collation_type(), "right", meta2.get_collation_type()); } - if (false == is_equal) { - SHARE_SCHEMA_LOG(DEBUG, "fail to check partition values, value meta not equal", - "left", l_part.get_high_bound_val().get_obj_ptr()[i], - "right", r_part.get_high_bound_val().get_obj_ptr()[i], K(is_oracle_mode)); + if (!is_equal) { + //do nothing } else if (0 != l_part.get_high_bound_val().get_obj_ptr()[i].compare(r_part.get_high_bound_val().get_obj_ptr()[i], - r_part.get_high_bound_val().get_obj_ptr()[i].get_collation_type())) { + r_part.get_high_bound_val().get_obj_ptr()[i].get_collation_type())) { is_equal = false; - SHARE_SCHEMA_LOG(DEBUG, "fail to check partition values, value not equal", + ASSIGN_PARTITION_ERROR(user_error, "range_part partition value not equal"); + SHARE_SCHEMA_LOG(TRACE, "fail to check partition values, value not equal", "left", l_part.get_high_bound_val().get_obj_ptr()[i], "right", r_part.get_high_bound_val().get_obj_ptr()[i]); } @@ -6348,6 +6387,7 @@ int ObPartitionUtils::check_partition_value( const common::ObIArray &r_list_values = r_part.get_list_row_values(); if (l_list_values.count() != r_list_values.count()) { is_equal = false; + ASSIGN_PARTITION_ERROR(user_error, "list_part partition value count not equal"); SHARE_SCHEMA_LOG(TRACE, "fail to check list_part partition value, value count not equal", "left", l_list_values, "right", r_list_values); @@ -6360,7 +6400,8 @@ int ObPartitionUtils::check_partition_value( // First check that the count and meta information are consistent; if (l_rowkey.get_count() != r_rowkey.get_count()) { is_equal = false; - SHARE_SCHEMA_LOG(DEBUG, "fail to check partition value, value count not equal", + ASSIGN_PARTITION_ERROR(user_error, "list_part partition value count not equal"); + SHARE_SCHEMA_LOG(TRACE, "fail to check partition value, value count not equal", "left", l_rowkey, "right", r_rowkey); } else { for (int64_t z = 0; z < l_rowkey.get_count() && is_equal; z++) { @@ -6369,15 +6410,17 @@ int ObPartitionUtils::check_partition_value( // The obj comparison function does not require the same cs_level if (meta1.get_collation_type() == meta2.get_collation_type()) { is_equal = is_types_equal_for_partition_check(is_oracle_mode, meta1.get_type(), meta2.get_type()); + if (!is_equal) { + ASSIGN_PARTITION_ERROR(user_error, "list_part partition meta type not equal"); + SHARE_SCHEMA_LOG(TRACE, "fail to check partition values, value meta not equal", + "left", l_rowkey.get_cell(z), "right", r_rowkey.get_cell(z)); + } } else { is_equal = false; + ASSIGN_PARTITION_ERROR(user_error, "list_part partition collation type not matched"); SHARE_SCHEMA_LOG(TRACE,"collation type not matched", "left", meta1.get_collation_type(), "right", meta2.get_collation_type()); } - if (false == is_equal) { - SHARE_SCHEMA_LOG(DEBUG, "fail to check partition values, value meta not equal", - "left", l_rowkey.get_cell(z), "right", r_rowkey.get_cell(z)); - } } } // Check whether the value of rowkey is the same; @@ -6387,7 +6430,8 @@ int ObPartitionUtils::check_partition_value( } //end for (int64_t j = 0 if (!find_equal_item) { is_equal = false; - SHARE_SCHEMA_LOG(TRACE,"fail to find equal item"); + ASSIGN_PARTITION_ERROR(user_error, "list_part partition value not equal"); + SHARE_SCHEMA_LOG(TRACE,"list_part partition value not equal"); } } //end for (int64_t i = 0; } @@ -8035,6 +8079,26 @@ private: common::ObString attribute_; }; +class ObTableLatestSchemaVersion +{ +public: + ObTableLatestSchemaVersion(); + virtual ~ObTableLatestSchemaVersion() {} + void reset(); + int init(const uint64_t table_id, const int64_t schema_version, const bool is_deleted); + bool is_valid() const; + int assign(const ObTableLatestSchemaVersion &other); + bool is_deleted() const { return is_deleted_; } + uint64_t get_table_id() const { return table_id_; } + int64_t get_schema_version() const { return schema_version_; } + + VIRTUAL_TO_STRING_KV(K_(table_id), K_(schema_version), K_(is_deleted)); +private: + uint64_t table_id_; + int64_t schema_version_; + bool is_deleted_; +}; + }//namespace schema }//namespace share }//namespace oceanbase diff --git a/src/share/schema/ob_schema_utils.cpp b/src/share/schema/ob_schema_utils.cpp index d217a6cb1..d0fa08e3f 100644 --- a/src/share/schema/ob_schema_utils.cpp +++ b/src/share/schema/ob_schema_utils.cpp @@ -480,6 +480,187 @@ int ObSchemaUtils::construct_inner_table_schemas( return ret; } +int ObSchemaUtils::batch_get_latest_table_schemas( + common::ObISQLClient &sql_client, + common::ObIAllocator &allocator, + const uint64_t tenant_id, + const common::ObIArray &table_ids, + common::ObIArray &table_schemas) +{ + int ret = OB_SUCCESS; + table_schemas.reset(); + ObSchemaService *schema_service = NULL; + ObArray table_schema_versions; + ObArray need_refresh_table_schema_keys; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || table_ids.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(table_ids)); + } else if (OB_ISNULL(GCTX.schema_service_) + || OB_ISNULL(schema_service = GCTX.schema_service_->get_schema_service())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("multiversion_schema_service or schema_service is null", KR(ret)); + } else if (OB_FAIL(schema_service->get_table_latest_schema_versions( + sql_client, + tenant_id, + table_ids, + table_schema_versions))) { + LOG_WARN("get table latest schema versions failed", KR(ret), K(tenant_id), K(table_ids)); + } else if (OB_FAIL(batch_get_table_schemas_from_cache_( + allocator, + tenant_id, + table_schema_versions, + need_refresh_table_schema_keys, + table_schemas))) { + LOG_WARN("batch get table schemas from cache failed", KR(ret), K(table_schema_versions)); + } else if (OB_FAIL(batch_get_table_schemas_from_inner_table_( + sql_client, + allocator, + tenant_id, + need_refresh_table_schema_keys, + table_schemas))) { + LOG_WARN("batch get table_schemas from inner table failed", KR(ret), K(need_refresh_table_schema_keys)); + } + // check table schema ptr + ARRAY_FOREACH(table_schemas, idx) { + const ObSimpleTableSchemaV2 *table_schema = table_schemas.at(idx); + if (OB_ISNULL(table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table_schema can't be null", KR(ret), K(idx), K(table_ids), K(table_schemas)); + } + } + return ret; +} + +int ObSchemaUtils::get_latest_table_schema( + common::ObISQLClient &sql_client, + common::ObIAllocator &allocator, + const uint64_t tenant_id, + const ObObjectID &table_id, + ObSimpleTableSchemaV2 *&table_schema) +{ + int ret = OB_SUCCESS; + table_schema = NULL; + ObSEArray table_ids; + ObSEArray table_schemas; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || OB_INVALID_ID == table_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(table_id)); + } else if (OB_FAIL(table_ids.push_back(table_id))) { + LOG_WARN("push back failed", KR(ret), K(table_id), K(table_ids)); + } else if (OB_FAIL(batch_get_latest_table_schemas( + sql_client, + allocator, + tenant_id, + table_ids, + table_schemas))) { + LOG_WARN("batch get latest table schema failed", KR(ret), K(table_id)); + } else if (table_schemas.empty()) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("table not exist when get latest table schema", KR(ret), K(table_id)); + } else if (OB_ISNULL(table_schemas.at(0))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table schema can not be null", KR(ret), K(table_id), K(table_schemas)); + } else { + table_schema = table_schemas.at(0); + } + return ret; +} + +int ObSchemaUtils::batch_get_table_schemas_from_cache_( + common::ObIAllocator &allocator, + const uint64_t tenant_id, + const ObIArray &table_schema_versions, + common::ObIArray &need_refresh_table_schema_keys, + common::ObIArray &table_schemas) +{ + int ret = OB_SUCCESS; + need_refresh_table_schema_keys.reset(); + table_schemas.reset(); + ObSchemaGetterGuard schema_guard; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("multiversion_schema_service is null", KR(ret)); + } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( + tenant_id, + schema_guard))) { + LOG_WARN("get schema guard failed", KR(ret), K(tenant_id)); + } else { + ARRAY_FOREACH(table_schema_versions, idx) { + const ObSimpleTableSchemaV2 *cached_table_schema = NULL; + ObSimpleTableSchemaV2 *new_table_schema = NULL; + const ObTableLatestSchemaVersion &table_schema_version = table_schema_versions.at(idx); + if (table_schema_version.is_deleted()) { + // skip + } else if (OB_FAIL(schema_guard.get_simple_table_schema( + tenant_id, + table_schema_version.get_table_id(), + cached_table_schema))) { + LOG_WARN("get simple table schema failed", KR(ret), K(tenant_id), K(table_schema_version)); + } else if (OB_ISNULL(cached_table_schema) + || (cached_table_schema->get_schema_version() < table_schema_version.get_schema_version())) { + // need fetch new table schema + SchemaKey table_schema_key; + table_schema_key.tenant_id_ = tenant_id; + table_schema_key.table_id_ = table_schema_version.get_table_id(); + if (OB_FAIL(need_refresh_table_schema_keys.push_back(table_schema_key))) { + LOG_WARN("push back failed", KR(ret), K(table_schema_version)); + } + } else if (OB_FAIL(alloc_schema(allocator, *cached_table_schema, new_table_schema))) { + LOG_WARN("fail to alloc schema", KR(ret), K(tenant_id), KPC(cached_table_schema)); + } else if (OB_FAIL(table_schemas.push_back(new_table_schema))) { + LOG_WARN("push back failed", KR(ret), KP(new_table_schema)); + } + } // end ARRAY_FOREACH + } + return ret; +} + +int ObSchemaUtils::batch_get_table_schemas_from_inner_table_( + common::ObISQLClient &sql_client, + common::ObIAllocator &allocator, + const uint64_t tenant_id, + common::ObArray &need_refresh_table_schema_keys, + common::ObIArray &table_schemas) +{ + int ret = OB_SUCCESS; + // do not reset table_schemas + ObSchemaService *schema_service = NULL; + ObRefreshSchemaStatus schema_status; + schema_status.tenant_id_ = tenant_id; + int64_t schema_version = INT64_MAX - 1; // get latest schema + ObArray schema_array; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.schema_service_) + || OB_ISNULL(schema_service = GCTX.schema_service_->get_schema_service())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("multiversion_schema_service or schema_service is null", KR(ret)); + } else if (need_refresh_table_schema_keys.empty()) { + // skip + } else if (OB_FAIL(schema_service->get_batch_tables( + schema_status, + sql_client, + schema_version, + need_refresh_table_schema_keys, + schema_array))) { + LOG_WARN("get batch tables failed", KR(ret), + K(schema_status), K(schema_version), K(need_refresh_table_schema_keys)); + } + ARRAY_FOREACH(schema_array, idx) { + const ObSimpleTableSchemaV2 &table_schema = schema_array.at(idx); + ObSimpleTableSchemaV2 *new_table_schema = NULL; + if (OB_FAIL(alloc_schema(allocator, table_schema, new_table_schema))) { + LOG_WARN("fail to alloc schema", KR(ret), K(table_schema)); + } else if (OB_FAIL(table_schemas.push_back(new_table_schema))) { + LOG_WARN("push back failed", KR(ret), KP(new_table_schema)); + } + } + return ret; +} } // end schema } // end share diff --git a/src/share/schema/ob_schema_utils.h b/src/share/schema/ob_schema_utils.h index 3da2b8bf4..80358dfee 100644 --- a/src/share/schema/ob_schema_utils.h +++ b/src/share/schema/ob_schema_utils.h @@ -26,6 +26,11 @@ namespace oceanbase { +namespace common +{ +class ObISQLClient; +} + namespace share { namespace schema @@ -33,6 +38,7 @@ namespace schema class ObTableSchema; class ObColumnSchemaV2; class ObServerSchemaService; +struct SchemaKey; class ObSchemaUtils { public: @@ -114,11 +120,56 @@ public: uint64_t tenant_id, uint64_t data_table_id, ObIArray &table_schemas); + // Optimized method to batch get latest table schemas from cache or inner_table automatically. + // + // @param[in] sql_client: ObISQLClient + // @param[in] allocator: allocator to manage memory of table schemas + // @param[in] tenant_id: target tenant_id + // @param[in] table_ids: target table_id array + // @param[out] table_schemas: array of ObSimpleTableSchemaV2 pointers + // (it's count may be smaller than table_ids when some tables not exist or been deleted) + // @return: OB_SUCCESS if success + static int batch_get_latest_table_schemas( + common::ObISQLClient &sql_client, + common::ObIAllocator &allocator, + const uint64_t tenant_id, + const common::ObIArray &table_ids, + common::ObIArray &table_schemas); + + // Optimized method to get latest table schema from cache or inner_table automatically. + // + // @param[in] sql_client: ObISQLClient + // @param[in] allocator: allocator to manage memory of table schema + // @param[in] tenant_id: target tenant_id + // @param[in] table_id: target table_id + // @param[out] table_schema: pointer of ObSimpleTableSchemaV2 (not null) + // @return: OB_SUCCESS if success + // OB_TABLE_NOT_EXIST if table not exist + static int get_latest_table_schema( + common::ObISQLClient &sql_client, + common::ObIAllocator &allocator, + const uint64_t tenant_id, + const ObObjectID &table_id, + ObSimpleTableSchemaV2 *&table_schema); private: static int get_tenant_variable(schema::ObSchemaGetterGuard &schema_guard, uint64_t tenant_id, share::ObSysVarClassType var_id, common::ObObj &value); + + static int batch_get_table_schemas_from_cache_( + common::ObIAllocator &allocator, + const uint64_t tenant_id, + const ObIArray &table_schema_versions, + common::ObIArray &need_refresh_table_schema_keys, + common::ObIArray &table_schemas); + static int batch_get_table_schemas_from_inner_table_( + common::ObISQLClient &sql_client, + common::ObIAllocator &allocator, + const uint64_t tenant_id, + common::ObArray &need_refresh_table_schema_keys, + common::ObIArray &table_schemas); + // disallow construct ObSchemaUtils() {} ~ObSchemaUtils() {} diff --git a/src/share/schema/ob_table_dml_param.cpp b/src/share/schema/ob_table_dml_param.cpp index 9628887fc..84b033178 100644 --- a/src/share/schema/ob_table_dml_param.cpp +++ b/src/share/schema/ob_table_dml_param.cpp @@ -165,7 +165,6 @@ int ObTableSchemaParam::convert(const ObTableSchema *schema) schema_rowkey_cnt, lib::is_oracle_mode(), tmp_col_descs, - false, &tmp_cols_index, &tmp_cols))) { LOG_WARN("Fail to init read info", K(ret)); diff --git a/src/share/schema/ob_table_param.cpp b/src/share/schema/ob_table_param.cpp index d7ef60311..9581d35fe 100644 --- a/src/share/schema/ob_table_param.cpp +++ b/src/share/schema/ob_table_param.cpp @@ -398,6 +398,19 @@ void ObColumnParam::reset() is_hidden_ = false; } +void ObColumnParam::destroy() +{ + if (orig_default_value_.need_deep_copy()) { + allocator_.free(orig_default_value_.get_deep_copy_obj_ptr()); + orig_default_value_.reset(); + } + if (cur_default_value_.need_deep_copy()) { + allocator_.free(cur_default_value_.get_deep_copy_obj_ptr()); + cur_default_value_.reset(); + } + ObColumnParam::reset(); +} + int ObColumnParam::deep_copy_obj(const ObObj &src, ObObj &dest) { int ret = OB_SUCCESS; @@ -933,7 +946,6 @@ int ObTableParam::construct_columns_and_projector( rowkey_count, force_mysql_mode ? false : lib::is_oracle_mode(), tmp_access_cols_desc, - false, &tmp_access_cols_index, &tmp_access_cols_param))) { LOG_WARN("fail to init main read info", K(ret)); @@ -1015,13 +1027,13 @@ int ObTableParam::convert(const ObTableSchema &table_schema, bool is_oracle_mode = false; if (OB_FAIL(construct_columns_and_projector(table_schema, access_column_ids, tsc_out_cols, force_mysql_mode))) { LOG_WARN("construct failed", K(ret)); - } else if (OB_FAIL(construct_pad_projector(main_read_info_.get_columns(), output_projector_, pad_col_projector_))) { + } else if (OB_FAIL(construct_pad_projector(*main_read_info_.get_columns(), output_projector_, pad_col_projector_))) { LOG_WARN("Fail to construct pad projector, ", K(ret)); } else if (OB_FAIL(table_schema.check_if_oracle_compat_mode(is_oracle_mode))) { LOG_WARN("fail to check oracle mode", KR(ret), K(table_schema)); } else if ((enable_lob_locator_v2_ || is_oracle_mode) && OB_FAIL(construct_lob_locator_param(table_schema, - main_read_info_.get_columns(), + *main_read_info_.get_columns(), output_projector_, use_lob_locator_, rowid_version_, diff --git a/src/share/schema/ob_table_param.h b/src/share/schema/ob_table_param.h index b5e8532c0..b8f195b0a 100644 --- a/src/share/schema/ob_table_param.h +++ b/src/share/schema/ob_table_param.h @@ -168,6 +168,7 @@ public: explicit ObColumnParam(common::ObIAllocator &allocator); virtual ~ObColumnParam(); virtual void reset(); + void destroy(); // free allocated memory private: ObColumnParam(); DISALLOW_COPY_AND_ASSIGN(ObColumnParam); diff --git a/src/share/schema/ob_table_schema.cpp b/src/share/schema/ob_table_schema.cpp index 9f934c305..4d98427e7 100644 --- a/src/share/schema/ob_table_schema.cpp +++ b/src/share/schema/ob_table_schema.cpp @@ -90,6 +90,16 @@ OB_SERIALIZE_MEMBER_SIMPLE(ObTableMode, common::ObString ObMergeSchema::EMPTY_STRING = common::ObString::make_string(""); +int ObMergeSchema::get_mulit_version_rowkey_column_ids(common::ObIArray &column_ids) const +{ + int ret = OB_SUCCESS; + if (OB_FAIL(get_rowkey_column_ids(column_ids))) { + SHARE_SCHEMA_LOG(WARN, "failed to add rowkey cols", K(ret)); + } else if (OB_FAIL(storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(column_ids))) { + SHARE_SCHEMA_LOG(WARN, "failed to add extra rowkey cols", K(ret)); + } + return ret; +} ObSimpleTableSchemaV2::ObSimpleTableSchemaV2() : ObPartitionSchema() { @@ -753,6 +763,161 @@ int ObSimpleTableSchemaV2::check_is_all_server_readonly_replica( return ret; } +#define ASSIGN_COMPARE_PARTITION_ERROR(ERROR_STRING, USER_ERROR) { \ + if (OB_SUCC(ret)) { \ + if (OB_NOT_NULL(ERROR_STRING)) { \ + if (OB_FAIL(ERROR_STRING->assign(USER_ERROR))) { \ + LOG_WARN("fail to assign user error", KR(ret));\ + }\ + }\ + }\ +}\ +// compare two table partition details +int ObSimpleTableSchemaV2::compare_partition_option(const schema::ObSimpleTableSchemaV2 &t1, + const schema::ObSimpleTableSchemaV2 &t2, + bool check_subpart, + bool &is_matched, + ObSqlString *user_error) +{ + int ret = OB_SUCCESS; + bool t1_oracle_mode = false; + bool t2_oracle_mode = false; + is_matched = true; + if (OB_FAIL(t1.check_if_oracle_compat_mode(t1_oracle_mode))) { + LOG_WARN("fail to get tenant mode", KR(ret), K(t1)); + } else if (OB_FAIL(t2.check_if_oracle_compat_mode(t2_oracle_mode))) { + LOG_WARN("fail to get tenant mode", KR(ret), K(t2)); + } else if (t1_oracle_mode != t2_oracle_mode) { + is_matched = false; + ASSIGN_COMPARE_PARTITION_ERROR(user_error, "table compatibilty mode not match") + } else { + const schema::ObPartitionOption &t1_part = t1.get_part_option(); + const schema::ObPartitionOption &t2_part = t2.get_part_option(); + schema::ObPartitionFuncType t1_part_func_type = t1_part.get_part_func_type(); + schema::ObPartitionFuncType t2_part_func_type = t2_part.get_part_func_type(); + + //non-partitioned table do not need to compare with partitioned table + if ((PARTITION_LEVEL_ZERO == t1.get_part_level() && PARTITION_LEVEL_ZERO != t2.get_part_level()) + || (PARTITION_LEVEL_ZERO != t1.get_part_level() && PARTITION_LEVEL_ZERO == t2.get_part_level())) { + is_matched = false; + LOG_WARN("not all tables are non-partitioned or partitioned", K(t1.get_part_level()), K(t2.get_part_level())); + ASSIGN_COMPARE_PARTITION_ERROR(user_error, "not all tables are non-partitioned or partitioned"); + } else if (PARTITION_LEVEL_ZERO == t1.get_part_level() + && PARTITION_LEVEL_ZERO == t2.get_part_level()) { + //both non-partition table is matched + } else if (t1_part_func_type != t2_part_func_type && (!::oceanbase::is_key_part(t1_part_func_type) || !::oceanbase::is_key_part(t2_part_func_type))) { + is_matched = false; + LOG_WARN("partition func type not matched", K(t1_part), K(t2_part)); + ASSIGN_COMPARE_PARTITION_ERROR(user_error, "partition func type not matched"); + } else if (schema::PARTITION_FUNC_TYPE_MAX == t1_part_func_type) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid part_func_type", KR(ret), K(t1_part_func_type), K(t2_part_func_type)); + } else if (t1.get_partition_num() != t1_part.get_part_num() + || t2.get_partition_num() != t2_part.get_part_num()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition num is not equal to part num", KR(ret), K(t1.get_partition_num()), K(t1_part.get_part_num()), + K(t2.get_partition_num()), K(t2_part.get_part_num())); + } else if (t1.get_partition_num() != t2.get_partition_num()) { + is_matched = false; + LOG_WARN("partition num is not equal", K(t1.get_partition_num()), K(t2.get_partition_num())); + ASSIGN_COMPARE_PARTITION_ERROR(user_error, "partition num not equal"); + } else if (::oceanbase::is_hash_part(t1_part_func_type) + || ::oceanbase::is_key_part(t1_part_func_type)) { + //level one is hash and key, just need to compare part num and part type + //do nothing + } else if (::oceanbase::is_range_part(t1_part_func_type) + || ::oceanbase::is_list_part(t1_part_func_type)) { + if (OB_ISNULL(t1.get_part_array()) + || OB_ISNULL(t2.get_part_array())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition_array is null", KR(ret), K(t1), K(t2)); + } else { + int64_t t1_part_num = t1.get_partition_num(); + for (int64_t i = 0; i < t1_part_num && is_matched && OB_SUCC(ret); i++) { + is_matched = false; + schema::ObPartition *table_part1 = t1.get_part_array()[i]; + schema::ObPartition *table_part2 = t2.get_part_array()[i]; + if (OB_ISNULL(table_part1) || OB_ISNULL(table_part2)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition is null", KR(ret), KP(table_part1), KP(table_part2)); + } else if (OB_FAIL(schema::ObPartitionUtils::check_partition_value( + t1_oracle_mode, *table_part1, *table_part2, t1_part_func_type, is_matched, user_error))) { + LOG_WARN("fail to check partition value", KR(ret), KPC(table_part1), KPC(table_part2), K(t1_part_func_type)); + } + } + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("invalid part func type", KR(ret), K(t1_part), K(t2_part)); + } + if (OB_SUCC(ret) && is_matched && check_subpart) { + if (t1.get_part_level() != t2.get_part_level()) { + is_matched = false; + LOG_WARN("two table part level is not equal"); + ASSIGN_COMPARE_PARTITION_ERROR(user_error, "part level is not equal"); + } else if (PARTITION_LEVEL_TWO != t1.get_part_level()) { + //don't have sub part, just skip + } else { + const schema::ObPartitionOption &t1_subpart = t1.get_sub_part_option(); + const schema::ObPartitionOption &t2_subpart = t2.get_sub_part_option(); + schema::ObPartitionFuncType t1_subpart_func_type = t1_subpart.get_part_func_type(); + schema::ObPartitionFuncType t2_subpart_func_type = t2_subpart.get_part_func_type(); + if (t1_subpart_func_type != t2_subpart_func_type + && (!::oceanbase::is_key_part(t1_subpart_func_type) || !::oceanbase::is_key_part(t2_subpart_func_type))) { + is_matched = false; + LOG_WARN("subpartition func type not matched", K(t1_subpart), K(t2_subpart)); + ASSIGN_COMPARE_PARTITION_ERROR(user_error, "subpartition func type not matched"); + } else if (schema::PARTITION_FUNC_TYPE_MAX == t1_subpart_func_type) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid part_func_type", KR(ret), K(t1_subpart_func_type), K(t2_subpart_func_type)); + } else { + const int64_t t1_level_one_part_num = t1.get_partition_num(); + for (int64_t i = 0; OB_SUCC(ret) && i < t1_level_one_part_num && is_matched; i++) { + schema::ObPartition *table_part1 = t1.get_part_array()[i]; + schema::ObPartition *table_part2 = t2.get_part_array()[i]; + if (OB_ISNULL(table_part1) || OB_ISNULL(table_part2)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition is null", KR(ret), KP(table_part1), KP(table_part2)); + } else if (table_part1->get_subpartition_num() != table_part1->get_sub_part_num() + || table_part2->get_subpartition_num() != table_part2->get_sub_part_num()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("subpartition num not equal", KR(ret), K(table_part1->get_subpartition_num()), K(table_part1->get_sub_part_num()), + K(table_part2->get_subpartition_num()), K(table_part2->get_sub_part_num())); + } else if (table_part1->get_subpartition_num() != table_part2->get_subpartition_num()) { + is_matched = false; + LOG_WARN("subpartition num is not equal", K(table_part1->get_subpartition_num()), K(table_part2->get_subpartition_num())); + ASSIGN_COMPARE_PARTITION_ERROR(user_error, "subpartition num not matched"); + } else if (::oceanbase::is_hash_part(t1_subpart_func_type) + || ::oceanbase::is_key_part(t1_subpart_func_type)) { + //level two is hash and key, just need to compare part num and part type + //do nothing + } else if (::oceanbase::is_range_part(t1_subpart_func_type) + || ::oceanbase::is_list_part(t1_subpart_func_type)) { + const int64_t t1_level_two_part_num = table_part1->get_subpartition_num(); + for (int64_t j = 0; OB_SUCC(ret) && j < t1_level_two_part_num && is_matched; j++) { + is_matched = false; + schema::ObSubPartition *table_subpart1 = table_part1->get_subpart_array()[j]; + schema::ObSubPartition *table_subpart2 = table_part2->get_subpart_array()[j]; + if (OB_ISNULL(table_subpart1) || OB_ISNULL(table_subpart2)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("subpartition is null", KR(ret), KP(table_subpart1), KP(table_subpart2)); + } else if (OB_FAIL(schema::ObPartitionUtils::check_partition_value( + t1_oracle_mode, *table_subpart1, *table_subpart2, t1_subpart_func_type, is_matched, user_error))) { + LOG_WARN("fail to check subpartition value", KR(ret), KPC(table_subpart1), KPC(table_subpart1), K(t1_subpart_func_type)); + } + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("invalid subpart func type", KR(ret), K(t1_subpart), K(t2_subpart)); + } + } + } + } + } + } + return ret; +} + int64_t ObSimpleTableSchemaV2::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; @@ -5126,10 +5291,8 @@ int ObTableSchema::get_multi_version_column_descs(common::ObIArray &c if (!is_valid()) { ret = OB_SCHEMA_ERROR; LOG_WARN("The ObTableSchema is invalid", K(ret)); - } else if (OB_FAIL(get_rowkey_column_ids(column_descs))) { // add rowkey columns + } else if (OB_FAIL(get_mulit_version_rowkey_column_ids(column_descs))) { // add rowkey columns LOG_WARN("Fail to get rowkey column descs", K(ret)); - } else if (OB_FAIL(storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(column_descs))) { - LOG_WARN("failed to add extra rowkey cols", K(ret)); } else if (OB_FAIL(get_column_ids_without_rowkey(column_descs, !is_storage_index_table()))) { //add other columns LOG_WARN("Fail to get column descs with out rowkey", K(ret)); } @@ -6516,90 +6679,6 @@ int ObTableSchema::check_auto_partition_valid() return ret; } -int ObTableSchema::assign_tablegroup_partition(const ObTablegroupSchema &tablegroup) -{ - int ret = OB_SUCCESS; - reset_partition_schema(); - part_level_ = tablegroup.get_part_level(); - sub_part_template_flags_ = tablegroup.get_sub_part_template_flags(); - - if (OB_SUCC(ret)) { - part_option_ = tablegroup.get_part_option(); - if (OB_FAIL(part_option_.get_err_ret())) { - LOG_WARN("fail to assign part_option", K(ret), - K_(part_option), K(tablegroup.get_part_option())); - } - } - - if (OB_SUCC(ret)) { - sub_part_option_ = tablegroup.get_sub_part_option(); - if (OB_FAIL(sub_part_option_.get_err_ret())) { - LOG_WARN("fail to assign sub_part_option", K(ret), - K_(sub_part_option), K(tablegroup.get_sub_part_option())); - } - } - - //partitions array - if (OB_SUCC(ret)) { - int64_t partition_num = tablegroup.get_partition_num(); - if (partition_num > 0) { - partition_array_ = static_cast(alloc(sizeof(ObPartition *) - * partition_num)); - if (OB_ISNULL(partition_array_)) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_ERROR("Fail to allocate memory for partition_array_", K(ret)); - } else if (OB_ISNULL(tablegroup.get_part_array())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablegroup.partition_array_ is null", K(ret)); - } else { - partition_array_capacity_ = partition_num; - } - } - ObPartition *partition = NULL; - for (int64_t i = 0; OB_SUCC(ret) && i < partition_num; i++) { - partition = tablegroup.get_part_array()[i]; - if (OB_ISNULL(partition)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("the partition is null", K(ret)); - } else if (OB_FAIL(add_partition(*partition))) { - LOG_WARN("Fail to add partition", K(ret)); - } - } - } - //subpartitions array - if (OB_SUCC(ret)) { - int64_t def_subpartition_num = tablegroup.get_def_subpartition_num(); - if (def_subpartition_num > 0) { - def_subpartition_array_ = static_cast( - alloc(sizeof(ObSubPartition *) * def_subpartition_num)); - if (OB_ISNULL(def_subpartition_array_)) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_ERROR("Fail to allocate memory for subpartition_array_", K(ret), K(def_subpartition_num)); - } else if (OB_ISNULL(tablegroup.get_def_subpart_array())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablegroup.def_subpartition_array_ is null", K(ret)); - } else { - def_subpartition_array_capacity_ = def_subpartition_num; - } - } - ObSubPartition *subpartition = NULL; - for (int64_t i = 0; OB_SUCC(ret) && i < def_subpartition_num; i++) { - subpartition = tablegroup.get_def_subpart_array()[i]; - if (OB_ISNULL(subpartition)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("the partition is null", K(ret)); - } else if (OB_FAIL(add_def_subpartition(*subpartition))) { - LOG_WARN("Fail to add partition", K(ret)); - } - } - } - - if (OB_FAIL(ret)) { - error_ret_ = ret; - } - return ret; -} - // Distinguish the following two scenarios: // 1. For non-partitioned tables, return 0 directly; // 2. For a partitioned table, and the first-level partition mode is key(), take the number of primary key columns; diff --git a/src/share/schema/ob_table_schema.h b/src/share/schema/ob_table_schema.h index 2ae0993da..17d395d6d 100644 --- a/src/share/schema/ob_table_schema.h +++ b/src/share/schema/ob_table_schema.h @@ -373,6 +373,7 @@ public: virtual inline bool is_primary_aux_vp_table() const { return false; } virtual inline bool is_primary_vp_table() const { return false; } virtual inline bool is_aux_vp_table() const { return false; } + virtual inline bool is_column_info_simplified() const { return false; } virtual inline bool is_storage_index_table() const = 0; virtual inline int64_t get_block_size() const { return INVAID_RET;} virtual inline const common::ObString &get_encrypt_key() const { return EMPTY_STRING; } @@ -433,6 +434,7 @@ public: UNUSED(column_ids); return common::OB_NOT_SUPPORTED; } + int get_mulit_version_rowkey_column_ids(common::ObIArray &column_ids) const; virtual int get_column_encodings(common::ObIArray &col_encodings) const { UNUSED(col_encodings); @@ -663,6 +665,11 @@ public: int check_is_all_server_readonly_replica( share::schema::ObSchemaGetterGuard &guard, bool &is) const; + static int compare_partition_option(const schema::ObSimpleTableSchemaV2 &t1, + const schema::ObSimpleTableSchemaV2 &t2, + bool check_subpart, + bool &is_matched, + ObSqlString *user_error = NULL); int check_if_tablet_exists(const common::ObTabletID &tablet_id, bool &exists) const; int add_simple_foreign_key_info(const uint64_t tenant_id, @@ -732,7 +739,7 @@ public: inline static bool is_aux_lob_meta_table(share::schema::ObTableType table_type) { return schema::ObTableType::AUX_LOB_META == table_type; } inline bool is_aux_lob_meta_table() const { return share::schema::ObTableType::AUX_LOB_META == table_type_; } - inline bool is_aux_lob_table() const { return is_aux_lob_meta_table() || is_aux_lob_piece_table(); } + inline bool is_aux_lob_table() const { return schema::is_aux_lob_table(table_type_); } inline bool is_aux_table() const { return share::schema::ObTableType::USER_INDEX == table_type_ || share::schema::ObTableType::AUX_VERTIAL_PARTITION_TABLE == table_type_ || share::schema::ObTableType::AUX_LOB_PIECE == table_type_ || share::schema::ObTableType::AUX_LOB_META == table_type_; } // Primary partition table judgment: still USER_TABLE, but data_table_id_ is the same as itself, // the default data_table_id_ is 0 @@ -811,7 +818,6 @@ public: inline bool has_rowid() const { return is_user_table() || is_tmp_table(); } DECLARE_VIRTUAL_TO_STRING; - protected: uint64_t tenant_id_; uint64_t table_id_; @@ -1282,8 +1288,6 @@ public: int get_subpart_ids(const int64_t part_id, common::ObIArray &subpart_ids) const; - int assign_tablegroup_partition(const ObTablegroupSchema &tablegroup); - virtual int calc_part_func_expr_num(int64_t &part_func_expr_num) const; virtual int calc_subpart_func_expr_num(int64_t &subpart_func_expr_num) const; int is_partition_key(uint64_t column_id, bool &result) const; @@ -1629,6 +1633,7 @@ private: inline bool ObSimpleTableSchemaV2::is_index_local_storage() const { return USER_INDEX == table_type_ + // && schema::is_index_local_storage(index_type_); TODO(wangzhennan.wzn): use is_index_local_storage later && (INDEX_TYPE_NORMAL_LOCAL == index_type_ || INDEX_TYPE_UNIQUE_LOCAL == index_type_ || INDEX_TYPE_NORMAL_GLOBAL_LOCAL_STORAGE == index_type_ diff --git a/src/share/schema/ob_table_sql_service.cpp b/src/share/schema/ob_table_sql_service.cpp index 3470e1120..4df0db532 100644 --- a/src/share/schema/ob_table_sql_service.cpp +++ b/src/share/schema/ob_table_sql_service.cpp @@ -30,7 +30,6 @@ #include "observer/ob_server_struct.h" #include "share/schema/ob_schema_getter_guard.h" #include "share/schema/ob_trigger_sql_service.h" -#include "share/backup/ob_backup_info_mgr.h" #include "rootserver/ob_root_service.h" #include "observer/omt/ob_tenant_timezone_mgr.h" #include "sql/ob_sql_utils.h" diff --git a/src/share/schema/ob_tablegroup_sql_service.cpp b/src/share/schema/ob_tablegroup_sql_service.cpp index 37a73b40d..8b9d60e59 100644 --- a/src/share/schema/ob_tablegroup_sql_service.cpp +++ b/src/share/schema/ob_tablegroup_sql_service.cpp @@ -48,18 +48,6 @@ int ObTablegroupSqlService::insert_tablegroup(const ObTablegroupSchema &tablegro if (OB_FAIL(add_tablegroup(sql_client, tablegroup_schema, only_history))) { LOG_WARN("fail to add tablegroup", K(ret)); } - // tablegroup_id is encoded to distinguish tablegroups created before and after ver 2.0. - // For tablegroup created before ver 2.0, it doesn't contain any schema of partitions. - if (OB_FAIL(ret)) { - // skip - } else if (!is_sys_tablegroup_id(tablegroup_schema.get_tablegroup_id())) { - // add partition info - const ObPartitionSchema *tg_schema = &tablegroup_schema; - ObAddPartInfoHelper part_helper(tg_schema, sql_client); - if (OB_FAIL(part_helper.add_partition_info())) { - LOG_WARN("add partition info failed", K(ret)); - } - } // log operations if (OB_SUCC(ret)) { @@ -94,6 +82,8 @@ int ObTablegroupSqlService::update_tablegroup(ObTablegroupSchema &new_schema, || OB_FAIL(dml.add_pk_column("tablegroup_id", ObSchemaUtils::get_extract_schema_id( exec_tenant_id, new_schema.get_tablegroup_id()))) || OB_FAIL(dml.add_column("comment", new_schema.get_comment())) + || OB_FAIL(dml.add_column("schema_version", new_schema.get_schema_version())) + || OB_FAIL(dml.add_column("sharding", new_schema.get_sharding())) || OB_FAIL(dml.add_column("tablegroup_name", ObHexEscapeSqlStr(new_schema.get_tablegroup_name_str())))) { LOG_WARN("fail to add pk column", K(ret), K(new_schema)); } @@ -232,176 +222,6 @@ int ObTablegroupSqlService::delete_tablegroup( return ret; } -int ObTablegroupSqlService::add_inc_part_info(ObISQLClient &sql_client, - const ObTablegroupSchema &ori_tablegroup, - const ObTablegroupSchema &inc_tablegroup, - const int64_t schema_version) -{ - int ret = OB_SUCCESS; - const uint64_t tablegroup_id = ori_tablegroup.get_tablegroup_id(); - if (schema_version <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("schema_version is invalid", K(ret), K(schema_version)); - } else if (OB_INVALID_ID == tablegroup_id - || is_sys_tablegroup_id(tablegroup_id)) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("tablegroup before ver2.0 add partition not supported", - K(ret), K(tablegroup_id)); - } else if (!ori_tablegroup.is_range_part() && !ori_tablegroup.is_list_part()) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("only support range/list", K(ret), K(tablegroup_id)); - } else { - const ObPartitionSchema *ori_tablegroup_schema = &ori_tablegroup; - const ObPartitionSchema *inc_tablegroup_schema = &inc_tablegroup; - ObAddIncPartHelper part_helper(ori_tablegroup_schema, inc_tablegroup_schema, - schema_version, sql_client); - if (OB_FAIL(part_helper.add_partition_info())) { - LOG_WARN("add partition info failed", K(ret), K(ori_tablegroup_schema), K(inc_tablegroup_schema)); - } - } - return ret; -} - -int ObTablegroupSqlService::drop_inc_part_info( - ObISQLClient &sql_client, - const ObTablegroupSchema &tablegroup_schema, - const ObTablegroupSchema &inc_tablegroup, - const int64_t schema_version) -{ - int ret = OB_SUCCESS; - const uint64_t tablegroup_id = tablegroup_schema.get_tablegroup_id(); - const uint64_t tenant_id = tablegroup_schema.get_tenant_id(); - const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id); - - if (OB_FAIL(ret)) { - } else if (schema_version <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("schema_version is invalid", K(ret), K(schema_version)); - } else if (OB_INVALID_ID == tablegroup_id - || is_sys_tablegroup_id(tablegroup_id)) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("tablegroup before ver2.0 add partition not supported", - K(ret), K(tablegroup_id)); - } else if (!tablegroup_schema.is_range_part() && !tablegroup_schema.is_list_part()) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("only support range/list", K(ret), K(tablegroup_id)); - } else { - int64_t tenant_id = tablegroup_schema.get_tenant_id(); - ObSqlString sql; - const int64_t inc_part_num = inc_tablegroup.get_part_option().get_part_num(); - ObPartition **part_array = inc_tablegroup.get_part_array(); - - // delete from __all_part - if (OB_FAIL(sql.assign_fmt("DELETE FROM %s WHERE tenant_id = %ld AND table_id=%lu AND (0 = 1", - OB_ALL_PART_TNAME, - ObSchemaUtils::get_extract_tenant_id(exec_tenant_id, tenant_id), - ObSchemaUtils::get_extract_schema_id(exec_tenant_id, tablegroup_schema.get_table_id())))) { - LOG_WARN("append_fmt failed", K(ret)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < inc_part_num; i++) { - if (OB_FAIL(sql.append_fmt(" OR part_id = %lu", - part_array[i]->get_part_id()))) { - LOG_WARN("append_fmt failed", K(ret)); - } - } - if (OB_SUCC(ret)) { - if (OB_FAIL(sql.append_fmt(" )"))) { - LOG_WARN("append_fmt failed", K(ret)); - } - } - - if (OB_SUCC(ret)) { - int64_t affected_rows = 0; - if (OB_FAIL(sql_client.write(exec_tenant_id, sql.ptr(), affected_rows))) { - LOG_WARN("fail to execute sql", K(tenant_id), K(sql), K(ret)); - } - } - - // insert into __all_part_history - if (OB_SUCC(ret)) { - const ObPartitionSchema *tablegroup_schema_ptr = &tablegroup_schema; - const ObPartitionSchema *inc_tablegroup_ptr = &inc_tablegroup; - ObDropIncPartHelper drop_part_helper(tablegroup_schema_ptr, - inc_tablegroup_ptr, - schema_version, - sql_client); - if (OB_FAIL(drop_part_helper.drop_partition_info())) { - LOG_WARN("drop increment partition info failed", K(tablegroup_schema), - K(inc_tablegroup), K(schema_version), K(ret)); - } - } - } - return ret; -} - -int ObTablegroupSqlService::update_partition_option(ObISQLClient &sql_client, - const ObTablegroupSchema &tablegroup, - const ObSchemaOperationType opt_type, - const ObString *ddl_stmt_str) -{ - int ret = OB_SUCCESS; - - const uint64_t tenant_id = tablegroup.get_tenant_id(); - const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id); - const uint64_t tablegroup_id = tablegroup.get_tablegroup_id(); - - const ObPartitionOption &part_option = tablegroup.get_part_option(); - const ObPartitionOption &sub_part_option = tablegroup.get_sub_part_option(); - ObDMLSqlSplicer dml; - ObDMLExecHelper exec(sql_client, exec_tenant_id); - int64_t affected_rows = 0; - if (OB_INVALID_ID == tablegroup_id - || is_sys_tablegroup_id(tablegroup_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tablegroup_id is invalid", KR(ret), K(tablegroup_id)); - } else if (OB_FAIL(dml.add_pk_column("tenant_id", ObSchemaUtils::get_extract_tenant_id( - exec_tenant_id, tenant_id))) - || OB_FAIL(dml.add_pk_column("tablegroup_id", ObSchemaUtils::get_extract_schema_id( - exec_tenant_id, tablegroup_id))) - || OB_FAIL(dml.add_column("part_level", tablegroup.get_part_level())) - || OB_FAIL(dml.add_column("part_func_type", part_option.get_part_func_type())) - || OB_FAIL(dml.add_column("part_func_expr_num", tablegroup.get_part_func_expr_num())) - || OB_FAIL(dml.add_column("part_num", part_option.get_part_num())) - || OB_FAIL(dml.add_column("sub_part_func_type", sub_part_option.get_part_func_type())) - || OB_FAIL(dml.add_column("sub_part_func_expr_num", tablegroup.get_sub_part_func_expr_num())) - || OB_FAIL(dml.add_column("sub_part_num", sub_part_option.get_part_num())) - || OB_FAIL(dml.add_column("schema_version", tablegroup.get_schema_version())) - || OB_FAIL(dml.add_column("partition_status", tablegroup.get_partition_status())) - || OB_FAIL(dml.add_column("partition_schema_version", tablegroup.get_partition_schema_version())) - || OB_FAIL(dml.add_gmt_create()) - || OB_FAIL(dml.add_gmt_modified())) { - LOG_WARN("add column failed", K(ret)); - } else if (OB_FAIL(exec.exec_update(OB_ALL_TABLEGROUP_TNAME, dml, affected_rows))) { - LOG_WARN("exec update failed", K(ret)); - } else if (affected_rows > 1) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error", K(affected_rows), K(ret)); - } - - // add tablegroup_history - const bool only_history = true; - if (OB_FAIL(ret)) { - // do nothing - } else if (OB_FAIL(add_tablegroup(sql_client, tablegroup, only_history))) { - LOG_WARN("fail to add tablegroup history", K(ret)); - } - - if (OB_SUCC(ret)) { - ObSchemaOperation opt; - opt.tenant_id_ = tablegroup.get_tenant_id(); - opt.database_id_ = 0; - opt.tablegroup_id_ = tablegroup.get_tablegroup_id(); - opt.table_id_ = 0; - opt.op_type_ = opt_type; - opt.schema_version_ = tablegroup.get_schema_version(); - opt.ddl_stmt_str_ = ddl_stmt_str ? *ddl_stmt_str : ObString(); - if (OB_FAIL(log_operation(opt, sql_client))) { - LOG_WARN("log operation failed", K(opt), K(ret)); - } - } - return ret; -} - int ObTablegroupSqlService::add_tablegroup( ObISQLClient &sql_client, const ObTablegroupSchema &tablegroup, @@ -450,77 +270,46 @@ int ObTablegroupSqlService::gen_tablegroup_dml( ret = OB_INVALID_ARGUMENT; LOG_WARN("tablegroup_schema is invalid, ", K(ret), K(tablegroup_schema)); } else { - const ObPartitionOption &part_option = tablegroup_schema.get_part_option(); - const ObPartitionOption &sub_part_option = tablegroup_schema.get_sub_part_option(); + uint64_t compat_version = OB_INVALID_VERSION; + uint64_t tenant_id = tablegroup_schema.get_tenant_id(); + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) { + LOG_WARN("get min data_version failed", KR(ret), K(tenant_id)); + } else if (compat_version < DATA_VERSION_4_2_0_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can not generate tablegroup dml while observer is upgrading", KR(ret), K(tenant_id)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "create/alter tablegroup when observer is upgrading"); + } else if (compat_version >= DATA_VERSION_4_2_0_0 && tablegroup_schema.get_sharding().empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablegroup schema sharding can not be empty when data version is greater than 4.2", KR(ret), K(tablegroup_schema)); + } else { + const ObPartitionOption &part_option = tablegroup_schema.get_part_option(); + const ObPartitionOption &sub_part_option = tablegroup_schema.get_sub_part_option(); - if (OB_FAIL(dml.add_pk_column("tenant_id", ObSchemaUtils::get_extract_tenant_id( - exec_tenant_id, tablegroup_schema.get_tenant_id()))) - || OB_FAIL(dml.add_pk_column("tablegroup_id", ObSchemaUtils::get_extract_schema_id( - exec_tenant_id, tablegroup_schema.get_tablegroup_id()))) - || OB_FAIL(dml.add_column("tablegroup_name", ObHexEscapeSqlStr(tablegroup_schema.get_tablegroup_name_str()))) - || OB_FAIL(dml.add_column("comment", tablegroup_schema.get_comment())) - || OB_FAIL(dml.add_column("part_level", tablegroup_schema.get_part_level())) - || OB_FAIL(dml.add_column("part_func_type", part_option.get_part_func_type())) - || OB_FAIL(dml.add_column("part_func_expr_num", tablegroup_schema.get_part_func_expr_num())) - || OB_FAIL(dml.add_column("part_num", part_option.get_part_num())) - || OB_FAIL(dml.add_column("sub_part_func_type", sub_part_option.get_part_func_type())) - || OB_FAIL(dml.add_column("sub_part_func_expr_num", tablegroup_schema.get_sub_part_func_expr_num())) - || OB_FAIL(dml.add_column("sub_part_num", sub_part_option.get_part_num())) - || OB_FAIL(dml.add_column("partition_status", tablegroup_schema.get_partition_status())) - || OB_FAIL(dml.add_column("partition_schema_version", tablegroup_schema.get_partition_schema_version())) - || OB_FAIL(dml.add_column("schema_version", tablegroup_schema.get_schema_version())) - || OB_FAIL(dml.add_column("sub_part_template_flags", tablegroup_schema.get_sub_part_template_flags())) - || OB_FAIL(dml.add_gmt_create()) - || OB_FAIL(dml.add_gmt_modified())) { - LOG_WARN("add column failed", K(ret)); + if (OB_FAIL(dml.add_pk_column("tenant_id", ObSchemaUtils::get_extract_tenant_id( + exec_tenant_id, tablegroup_schema.get_tenant_id()))) + || OB_FAIL(dml.add_pk_column("tablegroup_id", ObSchemaUtils::get_extract_schema_id( + exec_tenant_id, tablegroup_schema.get_tablegroup_id()))) + || OB_FAIL(dml.add_column("tablegroup_name", ObHexEscapeSqlStr(tablegroup_schema.get_tablegroup_name_str()))) + || OB_FAIL(dml.add_column("comment", tablegroup_schema.get_comment())) + || OB_FAIL(dml.add_column("part_level", tablegroup_schema.get_part_level())) + || OB_FAIL(dml.add_column("part_func_type", part_option.get_part_func_type())) + || OB_FAIL(dml.add_column("part_func_expr_num", tablegroup_schema.get_part_func_expr_num())) + || OB_FAIL(dml.add_column("part_num", part_option.get_part_num())) + || OB_FAIL(dml.add_column("sub_part_func_type", sub_part_option.get_part_func_type())) + || OB_FAIL(dml.add_column("sub_part_func_expr_num", tablegroup_schema.get_sub_part_func_expr_num())) + || OB_FAIL(dml.add_column("sub_part_num", sub_part_option.get_part_num())) + || OB_FAIL(dml.add_column("partition_status", tablegroup_schema.get_partition_status())) + || OB_FAIL(dml.add_column("partition_schema_version", tablegroup_schema.get_partition_schema_version())) + || OB_FAIL(dml.add_column("schema_version", tablegroup_schema.get_schema_version())) + || OB_FAIL(dml.add_column("sub_part_template_flags", tablegroup_schema.get_sub_part_template_flags())) + || OB_FAIL(dml.add_column("sharding", tablegroup_schema.get_sharding()))) { + LOG_WARN("add column failed", K(ret)); + } } } return ret; } -int ObTablegroupSqlService::update_tablegroup_schema_version( - ObISQLClient &sql_client, - const ObTablegroupSchema &tablegroup) -{ - int ret = OB_SUCCESS; - - const uint64_t tenant_id = tablegroup.get_tenant_id(); - const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id); - const uint64_t tablegroup_id = tablegroup.get_tablegroup_id(); - ObDMLSqlSplicer dml; - ObDMLExecHelper exec(sql_client, exec_tenant_id); - int64_t affected_rows = 0; - if (OB_INVALID_ID == tablegroup_id - || is_sys_tablegroup_id(tablegroup_id)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tablegroup_id is invalid", KR(ret), K(tablegroup_id)); - } else if (OB_FAIL(dml.add_pk_column("tenant_id", ObSchemaUtils::get_extract_tenant_id( - exec_tenant_id, tenant_id))) - || OB_FAIL(dml.add_pk_column("tablegroup_id", ObSchemaUtils::get_extract_schema_id( - exec_tenant_id, tablegroup_id))) - || OB_FAIL(dml.add_column("schema_version", tablegroup.get_schema_version())) - || OB_FAIL(dml.add_gmt_create()) - || OB_FAIL(dml.add_gmt_modified())) { - LOG_WARN("add column failed", K(ret)); - } else if (OB_FAIL(exec.exec_update(OB_ALL_TABLEGROUP_TNAME, dml, affected_rows))) { - LOG_WARN("exec update failed", K(ret)); - } else if (affected_rows > 1) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error", K(affected_rows), K(ret)); - } - - // add tablegroup_history - const bool only_history = true; - if (OB_FAIL(ret)) { - // do nothing - } else if (OB_FAIL(add_tablegroup(sql_client, tablegroup, only_history))) { - LOG_WARN("fail to add tablegroup history", K(ret)); - } - return ret; -} - } //end of schema } //end of share } //end of oceanbase - - diff --git a/src/share/schema/ob_tablegroup_sql_service.h b/src/share/schema/ob_tablegroup_sql_service.h index 1d332e558..215d9dd7f 100644 --- a/src/share/schema/ob_tablegroup_sql_service.h +++ b/src/share/schema/ob_tablegroup_sql_service.h @@ -41,22 +41,6 @@ public: virtual int update_tablegroup(ObTablegroupSchema &new_schema, common::ObISQLClient &sql_client, const common::ObString *ddl_stmt_str = NULL); - int add_inc_part_info(common::ObISQLClient &sql_client, - const ObTablegroupSchema &ori_tablegroup, - const ObTablegroupSchema &inc_tablegroup, - const int64_t schema_version); - - int drop_inc_part_info(common::ObISQLClient &sql_client, - const ObTablegroupSchema &ori_tablegroup, - const ObTablegroupSchema &inc_tablegroup, - const int64_t schema_version); - int update_tablegroup_schema_version( - common::ObISQLClient &sql_client, - const ObTablegroupSchema &tablegroup); - int update_partition_option(common::ObISQLClient &sql_client, - const ObTablegroupSchema &tablegroup, - const ObSchemaOperationType opt_type, - const common::ObString *ddl_stmt_str = NULL); private: int add_tablegroup(common::ObISQLClient &sql_client, const share::schema::ObTablegroupSchema &tablegroup, diff --git a/src/share/scn.h b/src/share/scn.h index a9a765b52..b515c0d7c 100644 --- a/src/share/scn.h +++ b/src/share/scn.h @@ -120,7 +120,7 @@ public: int64_t get_serialize_size(void) const; int to_yson(char *buf, const int64_t buf_len, int64_t &pos) const; - TO_STRING_KV(K_(val)); + TO_STRING_KV(K_(val), K_(v)); private: void transform_max_(); private: diff --git a/src/share/tablet/ob_tablet_info.cpp b/src/share/tablet/ob_tablet_info.cpp index 5f3051e48..79a43b0eb 100644 --- a/src/share/tablet/ob_tablet_info.cpp +++ b/src/share/tablet/ob_tablet_info.cpp @@ -299,18 +299,22 @@ int ObTabletInfo::find_replica_idx_(const ObTabletReplica &replica, int64_t &idx int ObTabletToLSInfo::init( const common::ObTabletID &tablet_id, const ObLSID &ls_id, - const uint64_t table_id) { + const uint64_t table_id, + const int64_t transfer_seq) { int ret = OB_SUCCESS; if (OB_UNLIKELY( !tablet_id.is_valid() || !ls_id.is_valid() - || OB_INVALID_ID == table_id)) { + || OB_INVALID_ID == table_id + || transfer_seq <= OB_INVALID_TRANSFER_SEQ)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("init with invalid argument", KR(ret), K(tablet_id), K(ls_id), K(table_id)); + LOG_WARN("init with invalid argument", + KR(ret), K(tablet_id), K(ls_id), K(table_id), K(transfer_seq)); } else { tablet_id_ = tablet_id; ls_id_ = ls_id; table_id_ = table_id; + transfer_seq_ = transfer_seq; } return ret; } @@ -322,6 +326,7 @@ int ObTabletToLSInfo::assign(const ObTabletToLSInfo &other) tablet_id_ = other.tablet_id_; ls_id_ = other.ls_id_; table_id_ = other.table_id_; + transfer_seq_ = other.transfer_seq_; } return ret; } diff --git a/src/share/tablet/ob_tablet_info.h b/src/share/tablet/ob_tablet_info.h index a69c343e8..26909f8ff 100644 --- a/src/share/tablet/ob_tablet_info.h +++ b/src/share/tablet/ob_tablet_info.h @@ -16,6 +16,7 @@ #include "common/ob_tablet_id.h" // ObTabletID #include "lib/net/ob_addr.h" // ObAddr #include "share/ob_ls_id.h" // ObLSID +#include "share/transfer/ob_transfer_info.h" // OB_INVALID_TRANSFER_SEQ namespace oceanbase { @@ -145,16 +146,18 @@ private: }; // ObTabletToLSInfo is used to store info for __all_tablet_to_ls. -// Structure: +// Structure: class ObTabletToLSInfo { public: - ObTabletToLSInfo() : tablet_id_(), ls_id_(), table_id_(OB_INVALID_ID) {} + ObTabletToLSInfo() + : tablet_id_(), ls_id_(), table_id_(OB_INVALID_ID), transfer_seq_(OB_INVALID_TRANSFER_SEQ) {} explicit ObTabletToLSInfo( const common::ObTabletID &tablet_id, const ObLSID &ls_id, - const uint64_t table_id) - : tablet_id_(tablet_id), ls_id_(ls_id), table_id_(table_id) + const uint64_t table_id, + const int64_t transfer_seq) + : tablet_id_(tablet_id), ls_id_(ls_id), table_id_(table_id), transfer_seq_(transfer_seq) { } ~ObTabletToLSInfo() { reset(); } @@ -163,32 +166,38 @@ public: tablet_id_.reset(); ls_id_.reset(); table_id_ = OB_INVALID_ID; + transfer_seq_ = OB_INVALID_TRANSFER_SEQ; } inline bool is_valid() const { return tablet_id_.is_valid() && ls_id_.is_valid() - && OB_INVALID_ID != table_id_; + && OB_INVALID_ID != table_id_ + && transfer_seq_ > OB_INVALID_TRANSFER_SEQ; } inline bool operator==(const ObTabletToLSInfo &other) const { - return other.tablet_id_ == tablet_id_ - && other.ls_id_ == ls_id_ - && other.table_id_ == table_id_; + return other.tablet_id_ == tablet_id_ + && other.ls_id_ == ls_id_ + && other.table_id_ == table_id_ + && other.transfer_seq_ == transfer_seq_; } inline const common::ObTabletID &get_tablet_id() const { return tablet_id_; } inline const ObLSID &get_ls_id() const { return ls_id_; } inline uint64_t get_table_id() const { return table_id_; } + inline int64_t get_transfer_seq() const { return transfer_seq_; } int init( const common::ObTabletID &tablet_id, const ObLSID &ls_id, - const uint64_t table_id); + const uint64_t table_id, + const int64_t transfer_seq); int assign(const ObTabletToLSInfo &other); - TO_STRING_KV(K_(tablet_id), K_(ls_id), K_(table_id)); + TO_STRING_KV(K_(tablet_id), K_(ls_id), K_(table_id), K_(transfer_seq)); private: common::ObTabletID tablet_id_; ObLSID ls_id_; uint64_t table_id_; + int64_t transfer_seq_; }; class ObTabletTablePair diff --git a/src/share/tablet/ob_tablet_table_iterator.h b/src/share/tablet/ob_tablet_table_iterator.h index 2285aa2dc..fb0464645 100644 --- a/src/share/tablet/ob_tablet_table_iterator.h +++ b/src/share/tablet/ob_tablet_table_iterator.h @@ -39,6 +39,7 @@ public: bool is_inited() const { return is_inited_; } int next(ObTabletInfo &tablet_info); ObTabletReplicaFilterHolder &get_filters() { return filters_; } + void set_batch_size(int64_t batch_size) {tablet_table_operator_.set_batch_size(batch_size);} private: int prefetch(); diff --git a/src/share/tablet/ob_tablet_table_operator.cpp b/src/share/tablet/ob_tablet_table_operator.cpp index 6cdcb5f71..3c562de99 100644 --- a/src/share/tablet/ob_tablet_table_operator.cpp +++ b/src/share/tablet/ob_tablet_table_operator.cpp @@ -13,7 +13,6 @@ #define USING_LOG_PREFIX SHARE #include "share/tablet/ob_tablet_table_operator.h" -#include "share/tablet/ob_tablet_info.h" // ObTabletReplica, ObTabletInfo #include "share/ob_errno.h" // KR(ret) #include "share/inner_table/ob_inner_table_schema.h" // OB_ALL_TABLET_META_TABLE_TNAME #include "share/ob_dml_sql_splicer.h" // ObDMLSqlSplicer @@ -30,7 +29,7 @@ using namespace common; namespace share { ObTabletTableOperator::ObTabletTableOperator() - : inited_(false), sql_proxy_(NULL) + : inited_(false), sql_proxy_(NULL), batch_size_(MAX_BATCH_COUNT) { } @@ -48,6 +47,7 @@ int ObTabletTableOperator::init(ObISQLClient &sql_proxy) } else { sql_proxy_ = &sql_proxy; inited_ = true; + batch_size_ = MAX_BATCH_COUNT; } return ret; } @@ -56,6 +56,7 @@ void ObTabletTableOperator::reset() { inited_ = false; sql_proxy_ = NULL; + batch_size_ = 0; } int ObTabletTableOperator::get( @@ -190,7 +191,7 @@ int ObTabletTableOperator::batch_get( LOG_WARN("fail to reserve tablet_infos", KR(ret), K(pairs_cnt)); } else { int64_t start_idx = 0; - int64_t end_idx = min(MAX_BATCH_COUNT, pairs_cnt); + int64_t end_idx = min(batch_size_, pairs_cnt); while (OB_SUCC(ret) && (start_idx < end_idx)) { if (OB_FAIL(inner_batch_get_by_sql_( *sql_proxy_, @@ -203,7 +204,7 @@ int ObTabletTableOperator::batch_get( KR(ret), K(tenant_id), K(tablet_ls_pairs), K(start_idx), K(end_idx)); } else { start_idx = end_idx; - end_idx = min(start_idx + MAX_BATCH_COUNT, pairs_cnt); + end_idx = min(start_idx + batch_size_, pairs_cnt); } } } @@ -463,13 +464,13 @@ int ObTabletTableOperator::batch_update( LOG_WARN("invalid argument", KR(ret), K(tenant_id), "replicas count", replicas.count()); } else { int64_t start_idx = 0; - int64_t end_idx = min(MAX_BATCH_COUNT, replicas.count()); + int64_t end_idx = min(batch_size_, replicas.count()); while (OB_SUCC(ret) && (start_idx < end_idx)) { if (OB_FAIL(inner_batch_update_by_sql_(tenant_id, replicas, start_idx, end_idx, sql_client))) { LOG_WARN("fail to inner batch update", KR(ret), K(tenant_id), K(replicas), K(start_idx)); } else { start_idx = end_idx; - end_idx = min(start_idx + MAX_BATCH_COUNT, replicas.count()); + end_idx = min(start_idx + batch_size_, replicas.count()); } } } @@ -629,13 +630,13 @@ int ObTabletTableOperator::batch_remove( LOG_WARN("invalid argument", KR(ret), K(tenant_id), "replicas count", replicas.count()); } else { int64_t start_idx = 0; - int64_t end_idx = min(MAX_BATCH_COUNT, replicas.count()); + int64_t end_idx = min(batch_size_, replicas.count()); while (OB_SUCC(ret) && (start_idx < end_idx)) { if (OB_FAIL(inner_batch_remove_by_sql_(tenant_id, replicas, start_idx, end_idx, sql_client))) { LOG_WARN("fail to inner batch remove", KR(ret), K(tenant_id), K(replicas), K(start_idx)); } else { start_idx = end_idx; - end_idx = min(start_idx + MAX_BATCH_COUNT, replicas.count()); + end_idx = min(start_idx + batch_size_, replicas.count()); } } } diff --git a/src/share/tablet/ob_tablet_table_operator.h b/src/share/tablet/ob_tablet_table_operator.h index 7aaa265ba..e6d0ee838 100644 --- a/src/share/tablet/ob_tablet_table_operator.h +++ b/src/share/tablet/ob_tablet_table_operator.h @@ -14,6 +14,7 @@ #define OCEANBASE_SHARE_OB_TABLET_TABLE_OPERATOR #include "lib/container/ob_iarray.h" //ObIArray +#include "share/tablet/ob_tablet_info.h" // ObTabletReplica, ObTabletInfo namespace oceanbase { @@ -31,8 +32,6 @@ class ObMySQLResult; } namespace share { -class ObTabletReplica; -class ObTabletInfo; class ObDMLSqlSplicer; class ObTabletLSPair; class ObLSID; @@ -50,6 +49,7 @@ public: virtual ~ObTabletTableOperator(); int init(common::ObISQLClient &sql_proxy_); void reset(); + void set_batch_size(int64_t batch_size) {batch_size_ = batch_size;} int get( const uint64_t tenant_id, const common::ObTabletID &tablet_id, @@ -177,6 +177,7 @@ private: const static int64_t MAX_BATCH_COUNT = 100; bool inited_; common::ObISQLClient *sql_proxy_; + int64_t batch_size_; }; } // end namespace share } // end namespace oceanbase diff --git a/src/share/tablet/ob_tablet_to_ls_iterator.cpp b/src/share/tablet/ob_tablet_to_ls_iterator.cpp index e52d5453e..4a3d68db3 100644 --- a/src/share/tablet/ob_tablet_to_ls_iterator.cpp +++ b/src/share/tablet/ob_tablet_to_ls_iterator.cpp @@ -23,15 +23,24 @@ ObTenantTabletToLSIterator::ObTenantTabletToLSIterator() : inited_(false), tenant_id_(OB_INVALID_TENANT_ID), inner_idx_(0), - tt_operator_(NULL), - inner_tablet_ls_pairs_() + ls_white_list_(), + inner_tablet_infos_(), + sql_proxy_(NULL) { } int ObTenantTabletToLSIterator::init( common::ObISQLClient &sql_proxy, - ObTabletToLSTableOperator &tt_operator, const uint64_t tenant_id) +{ + const ObArray ls_white_list; + return init(sql_proxy, tenant_id, ls_white_list); +} + +int ObTenantTabletToLSIterator::init( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const common::ObIArray &ls_white_list) { int ret = OB_SUCCESS; if (OB_UNLIKELY(inited_)) { @@ -40,16 +49,31 @@ int ObTenantTabletToLSIterator::init( } else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ls_white_list_.assign(ls_white_list))) { + LOG_WARN("assign LS white list fail", KR(ret), K(ls_white_list)); } else { sql_proxy_ = &sql_proxy; - tt_operator_ = &tt_operator; tenant_id_ = tenant_id; inited_ = true; } return ret; } -int ObTenantTabletToLSIterator::next(ObTabletLSPair &tablet_ls_pair) +int ObTenantTabletToLSIterator::next(ObTabletLSPair &pair) +{ + int ret = OB_SUCCESS; + ObTabletToLSInfo info; + if (OB_FAIL(next(info))) { + if (OB_ITER_END != ret) { + LOG_WARN("next tablet to LS info fail", KR(ret)); + } + } else if (OB_FAIL(pair.init(info.get_tablet_id(), info.get_ls_id()))) { + LOG_WARN("init ObTabletLSPair fail", KR(ret), K(info)); + } + return ret; +} + +int ObTenantTabletToLSIterator::next(ObTabletToLSInfo &info) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!inited_)) { @@ -59,8 +83,8 @@ int ObTenantTabletToLSIterator::next(ObTabletLSPair &tablet_ls_pair) ret = OB_ERR_UNEXPECTED; LOG_WARN("inner_idx_ can't be smaller than 0", KR(ret), K_(inner_idx)); } else { - tablet_ls_pair.reset(); - if (inner_idx_ >= inner_tablet_ls_pairs_.count()) { + info.reset(); + if (inner_idx_ >= inner_tablet_infos_.count()) { if (OB_FAIL(prefetch_())) { if (OB_UNLIKELY(OB_ITER_END != ret)) { LOG_WARN("fail to prfetch", KR(ret)); @@ -69,9 +93,9 @@ int ObTenantTabletToLSIterator::next(ObTabletLSPair &tablet_ls_pair) inner_idx_ = 0; } } - if (FAILEDx(tablet_ls_pair.assign(inner_tablet_ls_pairs_[inner_idx_]))) { - LOG_WARN("failed to assign tablet_ls_pair", - KR(ret), K_(inner_idx), K_(inner_tablet_ls_pairs)); + if (FAILEDx(info.assign(inner_tablet_infos_[inner_idx_]))) { + LOG_WARN("failed to assign tablet to ls info", + KR(ret), K_(inner_idx), K(inner_tablet_infos_[inner_idx_])); } else { ++inner_idx_; } @@ -82,26 +106,27 @@ int ObTenantTabletToLSIterator::next(ObTabletLSPair &tablet_ls_pair) int ObTenantTabletToLSIterator::prefetch_() { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!inited_) || OB_ISNULL(tt_operator_)) { + if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else { ObTabletID last_tablet_id; // start with INVALID_TABLET_ID = 0 - if (inner_tablet_ls_pairs_.count() > 0) { - const int64_t last_idx = inner_tablet_ls_pairs_.count() - 1; - last_tablet_id = inner_tablet_ls_pairs_.at(last_idx).get_tablet_id(); + if (inner_tablet_infos_.count() > 0) { + const int64_t last_idx = inner_tablet_infos_.count() - 1; + last_tablet_id = inner_tablet_infos_.at(last_idx).get_tablet_id(); } - inner_tablet_ls_pairs_.reset(); + inner_tablet_infos_.reset(); const int64_t range_size = GCONF.tablet_meta_table_scan_batch_count; - if (OB_FAIL(tt_operator_->range_get_tablet( + if (OB_FAIL(ObTabletToLSTableOperator::range_get_tablet_info( *sql_proxy_, tenant_id_, + ls_white_list_, last_tablet_id, range_size, - inner_tablet_ls_pairs_))) { + inner_tablet_infos_))) { LOG_WARN("fail to range get by operator", KR(ret), - K_(tenant_id), K(last_tablet_id), K(range_size), K_(inner_tablet_ls_pairs)); - } else if (inner_tablet_ls_pairs_.count() <= 0) { + K_(tenant_id), K_(ls_white_list), K(last_tablet_id), K(range_size), K(inner_tablet_infos_)); + } else if (inner_tablet_infos_.count() <= 0) { ret = OB_ITER_END; } } diff --git a/src/share/tablet/ob_tablet_to_ls_iterator.h b/src/share/tablet/ob_tablet_to_ls_iterator.h index 46317a30c..301e602d5 100644 --- a/src/share/tablet/ob_tablet_to_ls_iterator.h +++ b/src/share/tablet/ob_tablet_to_ls_iterator.h @@ -32,18 +32,25 @@ public: ObTenantTabletToLSIterator(); virtual ~ObTenantTabletToLSIterator() {} int init( - common::ObISQLClient &sql_proxy, - ObTabletToLSTableOperator &tt_operator, + common::ObISQLClient &sql_proxy, const uint64_t tenant_id); - int next(ObTabletLSPair &tablet_ls_pairs); + // init with LS white list + // ls_white_list: LS white list that only output tablets on the LS white list. + // If list is empty, it means ALL LS are in white list. + int init( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const common::ObIArray &ls_white_list); + int next(ObTabletLSPair &pair); + int next(ObTabletToLSInfo &info); private: int prefetch_(); bool inited_; uint64_t tenant_id_; int64_t inner_idx_; - ObTabletToLSTableOperator *tt_operator_; - common::ObArray inner_tablet_ls_pairs_; + common::ObSEArray ls_white_list_; + common::ObArray inner_tablet_infos_; common::ObISQLClient *sql_proxy_; }; diff --git a/src/share/tablet/ob_tablet_to_ls_operator.cpp b/src/share/tablet/ob_tablet_to_ls_operator.cpp index 853e07236..313faafaf 100644 --- a/src/share/tablet/ob_tablet_to_ls_operator.cpp +++ b/src/share/tablet/ob_tablet_to_ls_operator.cpp @@ -26,71 +26,176 @@ using namespace common; namespace share { +#define RANGE_GET(sql_proxy, tenant_id, ls_white_list, start_tablet_id, range_size, tablets) \ + do { \ + ObSqlString subsql; \ + ObSqlString sql; \ + if (OB_FAIL(ret)) { \ + } else if (OB_UNLIKELY(range_size <= 0)) { /* do not check start_tablet_id */ \ + ret = OB_INVALID_ARGUMENT; \ + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(range_size)); \ + } else if (OB_FAIL(construct_ls_white_list_where_sql_(ls_white_list, subsql))) { \ + LOG_WARN("construct sub sql string for LS white list fail", KR(ret), K(ls_white_list)); \ + } else if (OB_FAIL(sql.append_fmt( \ + "SELECT * FROM %s WHERE tablet_id > %lu %s ORDER BY tablet_id LIMIT %ld", \ + OB_ALL_TABLET_TO_LS_TNAME, \ + start_tablet_id.id(), \ + subsql.empty() ? "" : subsql.ptr(), \ + range_size))) { \ + LOG_WARN("fail to assign sql", KR(ret), K(sql), K(subsql), K(start_tablet_id)); \ + } else { \ + SMART_VAR(ObISQLClient::ReadResult, result) { \ + if (OB_FAIL(sql_proxy.read(result, tenant_id, sql.ptr()))) { \ + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); \ + } else if (OB_ISNULL(result.get_result())) { \ + ret = OB_ERR_UNEXPECTED; \ + LOG_WARN("get mysql result failed", KR(ret), K(sql)); \ + } else if (OB_FAIL(construct_results_(*result.get_result(), tenant_id, tablets))) { \ + LOG_WARN("construct tablet info failed", KR(ret), K(sql), K(tablets)); \ + } else if (OB_UNLIKELY(tablets.count() > range_size)) { \ + ret = OB_ERR_UNEXPECTED; \ + LOG_WARN("get too much tablets", KR(ret), K(sql), \ + K(range_size), "tablets count", tablets.count()); \ + } \ + } \ + } \ + } while (0) + +#define INNER_BATCH_GET(sql_proxy, tenant_id, tablet_ids, start_idx, end_idx, query_column_str, keep_order, results) \ + do { \ + if (OB_FAIL(ret)) { \ + } else if (OB_UNLIKELY( \ + !is_valid_tenant_id(tenant_id) \ + || tablet_ids.empty() \ + || start_idx < 0 \ + || start_idx >= end_idx \ + || end_idx > tablet_ids.count())) { \ + ret = OB_INVALID_ARGUMENT; \ + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(tablet_ids), K(start_idx), K(end_idx)); \ + } else { \ + SMART_VAR(ObISQLClient::ReadResult, result) { \ + ObSQLClientRetryWeak sql_client_retry_weak( \ + &sql_proxy, \ + false,/*did_use_retry*/ \ + tenant_id, \ + OB_ALL_TABLET_TO_LS_TID); \ + ObSqlString sql; \ + ObSqlString tablet_list; \ + for (int64_t idx = start_idx; OB_SUCC(ret) && (idx < end_idx); ++idx) { \ + const ObTabletID &tablet_id = tablet_ids.at(idx); \ + if (OB_UNLIKELY(!tablet_id.is_valid_with_tenant(tenant_id))) { \ + ret = OB_INVALID_ARGUMENT; \ + LOG_WARN("invalid tablet_id with tenant", KR(ret), K(tenant_id), K(tablet_id)); \ + } else if (OB_FAIL(tablet_list.append_fmt( \ + "%s%lu", \ + start_idx == idx ? "" : ",", \ + tablet_id.id()))) { \ + LOG_WARN("fail to assign sql", KR(ret), K(tenant_id), K(tablet_id)); \ + } \ + } \ + if (FAILEDx(sql.append_fmt( \ + "SELECT %s FROM %s WHERE tablet_id IN (", \ + query_column_str, \ + OB_ALL_TABLET_TO_LS_TNAME))) { \ + LOG_WARN("fail to assign sql", KR(ret), K(sql)); \ + } else if (OB_FAIL(sql.append(tablet_list.string()))) { \ + LOG_WARN("fail to assign sql", KR(ret), K(sql), K(tablet_list)); \ + } \ + if (OB_SUCC(ret) && keep_order) { \ + if (OB_FAIL(sql.append_fmt(") ORDER BY FIELD(tablet_id, "))) { \ + LOG_WARN("assign sql string failed", KR(ret), K(sql)); \ + } else if (OB_FAIL(sql.append(tablet_list.string()))) { \ + LOG_WARN("fail to assign sql", KR(ret), K(sql), K(tablet_list)); \ + } \ + } \ + if (FAILEDx(sql.append_fmt(")"))) { \ + LOG_WARN("fail to assign sql", KR(ret), K(sql)); \ + } else if (OB_FAIL(sql_client_retry_weak.read(result, tenant_id, sql.ptr()))) { \ + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); \ + } else if (OB_ISNULL(result.get_result())) { \ + ret = OB_ERR_UNEXPECTED; \ + LOG_WARN("get mysql result failed", KR(ret)); \ + } else if (OB_FAIL(construct_results_(*result.get_result(), tenant_id, results))) { \ + LOG_WARN("construct log stream info failed", KR(ret), K(results)); \ + } \ + } \ + } \ + } while(0) + +#define BATCH_GET(sql_proxy, tenant_id, tablet_ids, results) \ + do { \ + results.reset(); \ + if (OB_FAIL(ret)) { \ + } else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || tablet_ids.empty())) { \ + ret = OB_INVALID_ARGUMENT; \ + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tablet_ids)); \ + } else { \ + int64_t start_idx = 0; \ + int64_t end_idx = min(MAX_BATCH_COUNT, tablet_ids.count()); \ + while (OB_SUCC(ret) && start_idx < end_idx) { \ + if (OB_FAIL(inner_batch_get_( \ + sql_proxy, \ + tenant_id, \ + tablet_ids, \ + start_idx, \ + end_idx, \ + results))) { \ + LOG_WARN("fail to inner batch get by sql", \ + KR(ret), K(tenant_id), K(tablet_ids), K(start_idx), K(end_idx)); \ + } else { \ + start_idx = end_idx; \ + end_idx = min(start_idx + MAX_BATCH_COUNT, tablet_ids.count()); \ + } \ + } \ + } \ + } while(0) + int ObTabletToLSTableOperator::range_get_tablet( common::ObISQLClient &sql_proxy, const uint64_t tenant_id, const ObTabletID &start_tablet_id, const int64_t range_size, - ObIArray &tablet_ls_pairs) + common::ObIArray &tablet_ls_pairs) { int ret = OB_SUCCESS; - tablet_ls_pairs.reset(); - if (OB_UNLIKELY(range_size <= 0)) { // do not check start_tablet_id - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(range_size)); - } else { - SMART_VAR(ObISQLClient::ReadResult, result) { - ObSQLClientRetryWeak sql_client_retry_weak( - &sql_proxy, - tenant_id, - OB_ALL_TABLET_TO_LS_TID); - ObSqlString sql; - if (FAILEDx(sql.append_fmt( - "SELECT tablet_id, ls_id FROM %s WHERE tablet_id > %lu ORDER BY tablet_id LIMIT %ld", - OB_ALL_TABLET_TO_LS_TNAME, - start_tablet_id.id(), - range_size))) { - LOG_WARN("fail to assign sql", KR(ret), K(sql)); - } else if (OB_FAIL(sql_client_retry_weak.read(result, tenant_id, sql.ptr()))) { - LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); - } else if (OB_ISNULL(result.get_result())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get mysql result failed", KR(ret), K(sql)); - } else if (OB_FAIL(construct_tablet_ls_pairs_(*result.get_result(), tablet_ls_pairs))) { - LOG_WARN("construct tablet info failed", KR(ret), K(sql), K(tablet_ls_pairs)); - } else if (OB_UNLIKELY(tablet_ls_pairs.count() > range_size)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get too much tablets", KR(ret), K(sql), - K(range_size), "tablet_ls_pairs count", tablet_ls_pairs.count()); - } - } - } + const ObArray ls_white_list; + RANGE_GET(sql_proxy, tenant_id, ls_white_list, start_tablet_id, range_size, tablet_ls_pairs); return ret; } -int ObTabletToLSTableOperator::construct_tablet_ls_pairs_( - common::sqlclient::ObMySQLResult &res, - ObIArray &tablet_ls_pairs) +int ObTabletToLSTableOperator::range_get_tablet_info( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObIArray &ls_white_list, + const ObTabletID &start_tablet_id, + const int64_t range_size, + common::ObIArray &tablets) { int ret = OB_SUCCESS; - while (OB_SUCC(ret) && OB_SUCC(res.next())) { - int64_t tablet_id = ObTabletID::INVALID_TABLET_ID; - int64_t ls_id = ObLSID::INVALID_LS_ID; - if (OB_FAIL(res.get_int("tablet_id", tablet_id))) { - LOG_WARN("fail to get tablet_id from res", KR(ret)); - } else if (OB_FAIL(res.get_int("ls_id", ls_id))) { - LOG_WARN("fail to get ls_id from res", KR(ret)); - } else if (OB_FAIL(tablet_ls_pairs.push_back(ObTabletLSPair(tablet_id, ls_id)))) { - LOG_WARN("fail to push back", KR(ret), K(tablet_ls_pairs), K(tablet_id), K(ls_id)); - } - } - if (OB_ITER_END != ret) { - if (OB_UNLIKELY(OB_SUCCESS == ret)) { - ret = OB_ERR_UNEXPECTED; - } - LOG_WARN("fail to get next row to the end", KR(ret)); + RANGE_GET(sql_proxy, tenant_id, ls_white_list, start_tablet_id, range_size, tablets); + return ret; +} + +int ObTabletToLSTableOperator::construct_ls_white_list_where_sql_( + const ObIArray &ls_white_list, + ObSqlString &subsql) +{ + int ret = OB_SUCCESS; + const int64_t ls_cnt = ls_white_list.count(); + if (ls_cnt <= 0) { + // do nothing + } else if (OB_FAIL(subsql.assign_fmt(" and ls_id in ("))) { + LOG_WARN("assign string fail", KR(ret), K(subsql)); } else { - ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < ls_cnt; i++) { + const ObLSID &ls_id = ls_white_list.at(i); + const char *str = (i < ls_cnt - 1) ? "," : ")"; + + if (OB_FAIL(subsql.append_fmt("%ld%s", ls_id.id(), str))) { + LOG_WARN("append fmt for sql string fail", KR(ret), K(subsql), K(ls_id), K(str), K(i), + K(ls_cnt)); + } + } } return ret; } @@ -102,40 +207,18 @@ int ObTabletToLSTableOperator::batch_get_ls( ObIArray &ls_ids) { int ret = OB_SUCCESS; - ls_ids.reset(); - if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || tablet_ids.empty())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tablet_ids)); - } else { - int64_t start_idx = 0; - int64_t end_idx = min(MAX_BATCH_COUNT, tablet_ids.count()); - while (OB_SUCC(ret) && start_idx < end_idx) { - if (OB_FAIL(inner_batch_get_ls_by_sql_( - sql_proxy, - tenant_id, - tablet_ids, - start_idx, - end_idx, - ls_ids))) { - LOG_WARN("fail to inner batch get by sql", - KR(ret), K(tenant_id), K(tablet_ids), K(start_idx), K(end_idx)); - } else { - start_idx = end_idx; - end_idx = min(start_idx + MAX_BATCH_COUNT, tablet_ids.count()); - } - } - if (OB_SUCC(ret) && OB_UNLIKELY(ls_ids.count() != tablet_ids.count())) { - ret = OB_ITEM_NOT_MATCH; - LOG_WARN("count of ls_ids and tablet_ids do not match," - " there may be duplicates or nonexistent values in tablet_ids", - KR(ret), "tablet_ids count", tablet_ids.count(), "ls_ids count", ls_ids.count(), - K(tenant_id), K(tablet_ids), K(ls_ids)); - } + BATCH_GET(sql_proxy, tenant_id, tablet_ids, ls_ids); + if (OB_SUCC(ret) && OB_UNLIKELY(ls_ids.count() != tablet_ids.count())) { + ret = OB_ITEM_NOT_MATCH; + LOG_WARN("count of ls_ids and tablet_ids do not match," + " there may be duplicates or nonexistent values in tablet_ids", + KR(ret), "tablet_ids count", tablet_ids.count(), "ls_ids count", ls_ids.count(), + K(tenant_id), K(tablet_ids), K(ls_ids)); } return ret; } -int ObTabletToLSTableOperator::inner_batch_get_ls_by_sql_( +int ObTabletToLSTableOperator::inner_batch_get_( common::ObISQLClient &sql_proxy, const uint64_t tenant_id, const ObIArray &tablet_ids, @@ -144,63 +227,19 @@ int ObTabletToLSTableOperator::inner_batch_get_ls_by_sql_( ObIArray &ls_ids) { int ret = OB_SUCCESS; - if (OB_UNLIKELY( - OB_INVALID_TENANT_ID == tenant_id - || tablet_ids.empty() - || start_idx < 0 - || start_idx >= end_idx - || end_idx > tablet_ids.count())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tablet_ids), K(start_idx), K(end_idx)); - } else { - SMART_VAR(ObISQLClient::ReadResult, result) { - ObSQLClientRetryWeak sql_client_retry_weak( - &sql_proxy, - tenant_id, - OB_ALL_TABLET_TO_LS_TID); - ObSqlString sql; - ObSqlString tablet_list; - for (int64_t idx = start_idx; OB_SUCC(ret) && (idx < end_idx); ++idx) { - const ObTabletID &tablet_id = tablet_ids.at(idx); - if (OB_UNLIKELY(!tablet_id.is_valid_with_tenant(tenant_id))) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid tablet_id with tenant", KR(ret), K(tenant_id), K(tablet_id)); - } else if (OB_FAIL(tablet_list.append_fmt( - "%s %lu", - start_idx == idx ? "" : ",", - tablet_id.id()))) { - LOG_WARN("fail to assign sql", KR(ret), K(tenant_id), K(tablet_id)); - } - } - if (FAILEDx(sql.append_fmt( - "SELECT ls_id FROM %s WHERE tablet_id IN (", - OB_ALL_TABLET_TO_LS_TNAME))) { - LOG_WARN("fail to assign sql", KR(ret), K(sql)); - } else if (OB_FAIL(sql.append(tablet_list.string()))) { - LOG_WARN("fail to assign sql", KR(ret), K(sql), K(tablet_list)); - } else if (OB_FAIL(sql.append_fmt(") ORDER BY FIELD(tablet_id, "))) { - LOG_WARN("assign sql string failed", KR(ret), K(sql)); - } else if (OB_FAIL(sql.append(tablet_list.string()))) { - LOG_WARN("fail to assign sql", KR(ret), K(sql), K(tablet_list)); - } else if (OB_FAIL(sql.append_fmt(")"))) { - LOG_WARN("fail to assign sql", KR(ret), K(sql)); - } else if (OB_FAIL(sql_client_retry_weak.read(result, tenant_id, sql.ptr()))) { - LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); - } else if (OB_ISNULL(result.get_result())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get mysql result failed", KR(ret)); - } else if (OB_FAIL(construct_ls_ids_(*result.get_result(), ls_ids))) { - LOG_WARN("construct log stream info failed", KR(ret), K(ls_ids)); - } - } - } + const char *query_column_str = "ls_id"; + const bool keep_order = true; + INNER_BATCH_GET(sql_proxy, tenant_id, tablet_ids, start_idx, end_idx, + query_column_str, keep_order, ls_ids); return ret; } -int ObTabletToLSTableOperator::construct_ls_ids_( +int ObTabletToLSTableOperator::construct_results_( common::sqlclient::ObMySQLResult &res, + const uint64_t tenant_id, ObIArray &ls_ids) { + UNUSED(tenant_id); int ret = OB_SUCCESS; while (OB_SUCC(ret) && OB_SUCC(res.next())) { int64_t ls_id = ObLSID::INVALID_LS_ID; @@ -257,6 +296,7 @@ int ObTabletToLSTableOperator::inner_batch_update_by_sql_( const int64_t end_idx) { int ret = OB_SUCCESS; + uint64_t data_version = 0; if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || infos.empty() || start_idx < 0 @@ -264,6 +304,8 @@ int ObTabletToLSTableOperator::inner_batch_update_by_sql_( || end_idx > infos.count())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(infos), K(start_idx), K(end_idx)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, data_version))) { + LOG_WARN("fail to get min data version", KR(ret)); } else { ObSqlString sql; ObDMLSqlSplicer dml_splicer; @@ -273,9 +315,14 @@ int ObTabletToLSTableOperator::inner_batch_update_by_sql_( if (OB_UNLIKELY(!info.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid TabletToLSInfo", KR(ret), K(info)); + } else if (data_version < DATA_VERSION_4_2_0_0 && 0 != info.get_transfer_seq()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("update transfer_seq when data_version is less than 4.2.0.0 is not supported", KR(ret), K(info)); } else if (OB_FAIL(dml_splicer.add_pk_column("tablet_id", info.get_tablet_id().id())) || OB_FAIL(dml_splicer.add_column("ls_id", info.get_ls_id().id())) - || OB_FAIL(dml_splicer.add_column("table_id", info.get_table_id()))) { + || OB_FAIL(dml_splicer.add_column("table_id", info.get_table_id()) + || (data_version >= DATA_VERSION_4_2_0_0 + && OB_FAIL(dml_splicer.add_column("transfer_seq", info.get_transfer_seq()))))) { LOG_WARN("fail to add column", KR(ret), K(info)); } else if (OB_FAIL(dml_splicer.finish_row())) { LOG_WARN("fail to finish row", KR(ret)); @@ -366,5 +413,269 @@ int ObTabletToLSTableOperator::inner_batch_remove_by_sql_( return ret; } +int ObTabletToLSTableOperator::update_ls_id_and_transfer_seq( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTabletID &tablet_id, + const int64_t old_transfer_seq, + const ObLSID &old_ls_id, + const int64_t new_transfer_seq, + const ObLSID &new_ls_id) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || 0 > old_transfer_seq + || 0 > new_transfer_seq + || old_transfer_seq == new_transfer_seq + || !tablet_id.is_valid() + || !old_ls_id.is_valid() + || !new_ls_id.is_valid() + || old_ls_id == new_ls_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), + K(tablet_id), K(old_transfer_seq), K(new_transfer_seq), K(old_ls_id), K(new_ls_id)); + } else if (OB_FAIL(sql.append_fmt( + "UPDATE %s SET transfer_seq = %ld, ls_id = %ld " + "WHERE tablet_id = %lu AND transfer_seq = %ld AND ls_id = %ld", + OB_ALL_TABLET_TO_LS_TNAME, + new_transfer_seq, + new_ls_id.id(), + tablet_id.id(), + old_transfer_seq, + old_ls_id.id()))) { + LOG_WARN("fail to assign sql", KR(ret), K(sql), K(tenant_id), + K(tablet_id), K(old_ls_id), K(new_ls_id), K(old_transfer_seq), K(new_transfer_seq)); + } else { + int64_t affected_rows = 0; + if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("fail to write sql", KR(ret), K(sql), K(tenant_id)); + } else if (0 == affected_rows) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("no affected rows, the reason might be the tablet is not in the old ls, " + "or old_transfer_seq does not match the transfer sequence value " + "in table __all_tablet_to_ls.", + KR(ret), K(sql), K(tenant_id), K(affected_rows), K(tablet_id), + K(old_ls_id), K(new_ls_id), K(old_transfer_seq), K(new_transfer_seq)); + } else if (OB_UNLIKELY(1 != affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("The error should not occur", KR(ret), K(sql), + K(tenant_id), K(affected_rows), K(tablet_id), + K(old_ls_id), K(new_ls_id), K(old_transfer_seq), K(new_transfer_seq)); + } else { + LOG_TRACE("update ls_id and transfer_seq in table __all_tablet_to_ls successfully", + KR(ret), K(sql), K(tenant_id), K(affected_rows), K(tablet_id), + K(old_ls_id), K(new_ls_id), K(old_transfer_seq), K(new_transfer_seq)); + } + } + return ret; +} + +int ObTabletToLSTableOperator::batch_get( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObIArray &tablet_ids, + ObIArray &infos) +{ + int ret = OB_SUCCESS; + BATCH_GET(sql_proxy, tenant_id, tablet_ids, infos); + if (OB_SUCC(ret) && OB_UNLIKELY(infos.count() != tablet_ids.count())) { + ret = OB_ITEM_NOT_MATCH; + LOG_WARN("count of infos and tablet_ids do not match," + " there may be duplicates or nonexistent values in tablet_ids", + KR(ret), "tablet_ids count", tablet_ids.count(), "infos count", infos.count(), + K(tenant_id), K(tablet_ids), K(infos)); + } + return ret; +} + +int ObTabletToLSTableOperator::inner_batch_get_( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const int64_t start_idx, + const int64_t end_idx, + ObIArray &infos) +{ + int ret = OB_SUCCESS; + const char *query_column_str = "*"; + const bool keep_order = false; + INNER_BATCH_GET(sql_proxy, tenant_id, tablet_ids, start_idx, end_idx, + query_column_str, keep_order, infos); + return ret; +} + +int ObTabletToLSTableOperator::construct_results_( + common::sqlclient::ObMySQLResult &res, + const uint64_t tenant_id, + ObIArray &infos) +{ + UNUSED(tenant_id); + int ret = OB_SUCCESS; + while (OB_SUCC(ret) && OB_SUCC(res.next())) { + int64_t tablet_id = ObTabletID::INVALID_TABLET_ID; + int64_t ls_id = ObLSID::INVALID_LS_ID; + uint64_t table_id = OB_INVALID_ID; + int64_t transfer_seq = 0; + ObTabletToLSInfo info; + + EXTRACT_INT_FIELD_MYSQL(res, "tablet_id", tablet_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(res, "ls_id", ls_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(res, "table_id", table_id, uint64_t); + EXTRACT_INT_FIELD_MYSQL_WITH_DEFAULT_VALUE(res, "transfer_seq", transfer_seq, int64_t, + true/*skip_null_error*/, true/*skip_column_error*/, 0/*default value*/); + + if (FAILEDx(info.init(ObTabletID(tablet_id), ObLSID(ls_id), table_id, transfer_seq))) { + LOG_WARN("init failed", KR(ret), K(tablet_id), K(ls_id), K(table_id), K(transfer_seq)); + } else if (OB_FAIL(infos.push_back(info))) { + LOG_WARN("fail to push back", KR(ret), K(info)); + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + if (OB_SUCC(ret)) { + ret = OB_ERR_UNEXPECTED; + } + LOG_WARN("construct_results failed", KR(ret), K(infos)); + } + return ret; +} + +int ObTabletToLSTableOperator::construct_results_( + common::sqlclient::ObMySQLResult &res, + const uint64_t tenant_id, + ObIArray &pairs) +{ + UNUSED(tenant_id); + int ret = OB_SUCCESS; + while (OB_SUCC(ret) && OB_SUCC(res.next())) { + int64_t tablet_id = ObTabletID::INVALID_TABLET_ID; + int64_t ls_id = ObLSID::INVALID_LS_ID; + + EXTRACT_INT_FIELD_MYSQL(res, "tablet_id", tablet_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(res, "ls_id", ls_id, int64_t); + + if (FAILEDx(pairs.push_back(ObTabletLSPair(ObTabletID(tablet_id), ObLSID(ls_id))))) { + LOG_WARN("fail to push back", KR(ret), K(tablet_id), K(ls_id)); + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + if (OB_SUCC(ret)) { + ret = OB_ERR_UNEXPECTED; + } + LOG_WARN("construct results failed", KR(ret), K(pairs)); + } + return ret; +} + +int ObTabletToLSTableOperator::get_ls_by_tablet( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const common::ObTabletID &tablet_id, + ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ls_id.reset(); + ObSEArray tablet_ids; + ObSEArray ls_ids; + if (OB_UNLIKELY(!tablet_id.is_valid_with_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tablet_id)); + } else if (OB_FAIL(tablet_ids.push_back(tablet_id))) { + LOG_WARN("push back failed", KR(ret), K(tablet_id)); + } else { + int64_t start_idx = 0; + int64_t end_idx = 1; + if (OB_FAIL(inner_batch_get_( + sql_proxy, + tenant_id, + tablet_ids, + start_idx, + end_idx, + ls_ids))) { + LOG_WARN("fail to inner batch get by sql", + KR(ret), K(tenant_id), K(tablet_ids), K(start_idx), K(end_idx)); + } else if (ls_ids.empty()) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("tablet not found", KR(ret), K(tenant_id), K(tablet_id)); + } else if (1 != ls_ids.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get too much ls_ids", KR(ret), K(tenant_id), K(tablet_id), K(ls_ids)); + } else { + ls_id = ls_ids.at(0); + } + } + return ret; +} + +int ObTabletToLSTableOperator::batch_get_tablet_ls_cache( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const common::ObIArray &tablet_ids, + common::ObIArray &tablet_ls_caches) +{ + int ret = OB_SUCCESS; + BATCH_GET(sql_proxy, tenant_id, tablet_ids, tablet_ls_caches); + return ret; +} + +int ObTabletToLSTableOperator::inner_batch_get_( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const int64_t start_idx, + const int64_t end_idx, + common::ObIArray &tablet_ls_caches) +{ + int ret = OB_SUCCESS; + const char *query_column_str = "tablet_id, ls_id, ORA_ROWSCN"; + const bool keep_order = false; + INNER_BATCH_GET(sql_proxy, tenant_id, tablet_ids, start_idx, end_idx, + query_column_str, keep_order, tablet_ls_caches); + return ret; +} + +int ObTabletToLSTableOperator::construct_results_( + common::sqlclient::ObMySQLResult &res, + const uint64_t tenant_id, + common::ObIArray &tablet_ls_caches) +{ + int ret = OB_SUCCESS; + ObTabletLSCache tablet_ls_cache; + while (OB_SUCC(ret) && OB_SUCC(res.next())) { + tablet_ls_cache.reset(); + uint64_t tablet_id = ObTabletID::INVALID_TABLET_ID; + int64_t ls_id = ObLSID::INVALID_LS_ID; + int64_t row_scn = OB_MIN_SCN_TS_NS; + EXTRACT_INT_FIELD_MYSQL(res, "tablet_id", tablet_id, uint64_t); + EXTRACT_INT_FIELD_MYSQL(res, "ls_id", ls_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(res, "ORA_ROWSCN", row_scn, int64_t); + const int64_t now = ObTimeUtility::fast_current_time(); + if (FAILEDx(tablet_ls_cache.init( + tenant_id, + ObTabletID(tablet_id), + ObLSID(ls_id), + now, + row_scn))) { + LOG_WARN("init tablet_ls_cache failed", KR(ret), K(tenant_id), + K(tablet_id), K(ls_id), K(now), K(row_scn)); + } else if (OB_FAIL(tablet_ls_caches.push_back(tablet_ls_cache))) { + LOG_WARN("fail to push back", KR(ret), K(tablet_ls_cache)); + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + if (OB_SUCC(ret)) { + ret = OB_ERR_UNEXPECTED; + } + LOG_WARN("construct results failed", KR(ret), K(tablet_ls_caches)); + } + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/tablet/ob_tablet_to_ls_operator.h b/src/share/tablet/ob_tablet_to_ls_operator.h index a6049acdc..8fdf21682 100644 --- a/src/share/tablet/ob_tablet_to_ls_operator.h +++ b/src/share/tablet/ob_tablet_to_ls_operator.h @@ -13,8 +13,9 @@ #ifndef OCEANBASE_SHARE_OB_TABLET_TO_LS_OPERATOR #define OCEANBASE_SHARE_OB_TABLET_TO_LS_OPERATOR -#include "lib/container/ob_iarray.h" // ObIArray +#include "lib/container/ob_iarray.h" // ObIArray #include "share/tablet/ob_tablet_info.h" // ObTabletToLSInfo +#include "share/location_cache/ob_location_struct.h" // ObTabletLSCache namespace oceanbase { @@ -36,21 +37,37 @@ class ObTabletToLSTableOperator public: ObTabletToLSTableOperator() {} virtual ~ObTabletToLSTableOperator() {} - // Gets ObTabletIDs sequentially by range + // Get tablets sequentially by range // // @param [in] sql_proxy, ObMySQLProxy or ObMySQLTransaction // @param [in] tenant_id, tenant for query // @param [in] start_tablet_id, starting point of the range (not included in output!) // Usually start from 0. // @param [in] range_size, range size of the query - // @param [out] tablet_ls_pairs, sequential ObTabletLSPair in __all_tablet_to_ls + // @param [out] tablet_ls_pairs, sequential tablets' info in __all_tablet_to_ls // @return OB_SUCCESS if success static int range_get_tablet( common::ObISQLClient &sql_proxy, const uint64_t tenant_id, const ObTabletID &start_tablet_id, const int64_t range_size, - ObIArray &tablet_ls_pairs); + common::ObIArray &tablet_ls_pairs); + + // Get tablets sequentially by range + // + // Same function as the previous one, except that: + // 1. you can specify a list of LS whitelists to get the tables on the specified LS + // 2. you can get ObTabletToLSInfo instead of ObTabletLSPair + // + // @param [in] ls_white_list LS whitelist, empty means ALL LS in white list + static int range_get_tablet_info( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const common::ObIArray &ls_white_list, + const ObTabletID &start_tablet_id, + const int64_t range_size, + common::ObIArray &tablets); + // Gets ObLSIDs according to ObTableIDs // // @param [in] sql_proxy, ObMySQLProxy or ObMySQLTransaction @@ -59,7 +76,7 @@ public: // (should exist in __all_tablet_to_ls and have no duplicate values) // @param [out] ls_ids, ObLSIDs corresponding to tablet_ids (same order) // @return OB_SUCCESS if success; - // OB_NOT_SUPPORTED if tablet_ids have duplicates or + // OB_ITEM_NOT_MATCH if tablet_ids have duplicates or // tablet_id which is not recorded in __all_tablet_to_ls; // Other error according to unexpected situation static int batch_get_ls( @@ -87,20 +104,99 @@ public: common::ObISQLClient &sql_proxy, const uint64_t tenant_id, const ObIArray &tablet_ids); + // Transferring a given tablet from the old ls to the new ls needs to + // update ls_id and transfer_seq in table __all_tablet_to_ls. + // This function replaces the old ls id with the new ls id + // and updates the transfer sequence according to the given value. + // + // @param[in] sql_proxy sql client + // @param[in] tenant_id the given Tenant ID + // @param[in] tablet_id the given Tablet ID + // @param[in] old_transfer_seq old Transfer Sequence + // @param[in] old_ls_id old LS ID + // @param[in] new_transfer_seq new Transfer Sequence + // @param[in] new_ls_id new LS ID + // + // @ret OB_SUCCESS the updation is successful + // @ret OB_ENTRY_NOT_EXIST affected rows = 0, + // the reason might be the tablet is not in the old ls, + // or old_transfer_seq does not match the transfer sequence value + // in table __all_tablet_to_ls. + // @ret other error code failure + static int update_ls_id_and_transfer_seq( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTabletID &tablet_id, + const int64_t old_transfer_seq, + const ObLSID &old_ls_id, + const int64_t new_transfer_seq, + const ObLSID &new_ls_id); + // Get rows from __all_tablet_to_ls according to ObTableIDs + // + // @param [in] sql_proxy, ObMySQLProxy or ObMySQLTransaction + // @param [in] tenant_id, tenant for query + // @param [in] tablet_ids, ObTabletIDs for query + // (should exist in __all_tablet_to_ls and have no duplicate values) + // @param [out] infos, ObTabletToLSInfo corresponding to tablet_ids (same order) + // @return OB_SUCCESS if success; + // OB_ITEM_NOT_MATCH if tablet_ids have duplicates or nonexistent tablets; + // Other error according to unexpected situation + static int batch_get( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObIArray &tablet_ids, + ObIArray &infos); + // Get ls_id by tablet_id + // + // @param [in] sql_proxy, ObMySQLProxy or ObMySQLTransaction + // @param [in] tenant_id, tenant for query + // @param [in] tablet_id, target tablet_id + // @param [out] ls_id, ls_id which the tablet belongs to + // @return OB_SUCCESS if success; + // OB_ENTRY_NOT_EXIST if tablet_id not exist + // Other error according to unexpected situation + static int get_ls_by_tablet( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const common::ObTabletID &tablet_id, + ObLSID &ls_id); + // Batch get ObTabletLSCache for location_service + // + // @param [in] sql_proxy, ObMySQLProxy or ObMySQLTransaction + // @param [in] tenant_id, tenant for query + // @param [in] tablet_id, target tablet_id + // @param [out] tablet_ls_cache, ObTabletLSCache array + // @return OB_SUCCESS if success + static int batch_get_tablet_ls_cache( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const common::ObIArray &tablet_ids, + common::ObIArray &tablet_ls_caches); + + const static int64_t MAX_BATCH_COUNT = 200; private: - static int construct_tablet_ls_pairs_( - common::sqlclient::ObMySQLResult &res, - ObIArray &tablet_ls_pairs); - static int inner_batch_get_ls_by_sql_( + static int inner_batch_get_( common::ObISQLClient &sql_proxy, const uint64_t tenant_id, const ObIArray &tablet_ids, const int64_t start_idx, const int64_t end_idx, ObIArray &ls_ids); - static int construct_ls_ids_( - common::sqlclient::ObMySQLResult &res, - ObIArray &ls_ids); + static int inner_batch_get_( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const int64_t start_idx, + const int64_t end_idx, + ObIArray &infos); + static int inner_batch_get_( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const int64_t start_idx, + const int64_t end_idx, + common::ObIArray &tablet_ls_caches); + static int inner_batch_update_by_sql_( common::ObISQLClient &sql_proxy, const uint64_t tenant_id, @@ -113,8 +209,28 @@ private: const ObIArray &tablet_ids, const int64_t start_idx, const int64_t end_idx); - const static int64_t MAX_BATCH_COUNT = 200; + + static int construct_results_( + common::sqlclient::ObMySQLResult &res, + const uint64_t tenant_id, + ObIArray &ls_ids); + static int construct_results_( + common::sqlclient::ObMySQLResult &res, + const uint64_t tenant_id, + ObIArray &infos); + static int construct_results_( + common::sqlclient::ObMySQLResult &res, + const uint64_t tenant_id, + ObIArray &pairs); + static int construct_results_( + common::sqlclient::ObMySQLResult &res, + const uint64_t tenant_id, + common::ObIArray &tablet_ls_caches); + static int construct_ls_white_list_where_sql_( + const ObIArray &ls_white_list, + ObSqlString &subsql); }; + } // end namespace share } // end namespace oceanbase #endif diff --git a/src/share/tablet/ob_tenant_tablet_to_ls_map.cpp b/src/share/tablet/ob_tenant_tablet_to_ls_map.cpp new file mode 100644 index 000000000..971e18866 --- /dev/null +++ b/src/share/tablet/ob_tenant_tablet_to_ls_map.cpp @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE + +#include "common/ob_tablet_id.h" // ObTabletID +#include "lib/mysqlclient/ob_mysql_proxy.h" // ObMySQLProxy +#include "share/tablet/ob_tablet_info.h" // ObTabletLSPair +#include "share/tablet/ob_tablet_to_ls_iterator.h" // ObTenantTabletToLSIterator + +#include "share/tablet/ob_tenant_tablet_to_ls_map.h" + +namespace oceanbase +{ +namespace share +{ + +int ObTenantTabletToLSMap::build(const uint64_t tenant_id, + common::ObMySQLProxy &sql_proxy) +{ + int ret = OB_SUCCESS; + + ObTenantTabletToLSIterator iter; + if (OB_FAIL(iter.init(sql_proxy, tenant_id))) { + LOG_WARN("init iter fail", KR(ret), K(tenant_id)); + } else { + ObTabletLSPair tablet_ls_pair; + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.next(tablet_ls_pair))) { + if (OB_ITER_END != ret) { + LOG_WARN("iter next fail", KR(ret), K(tenant_id)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(map_.set_refactored(tablet_ls_pair.get_tablet_id(), tablet_ls_pair.get_ls_id()))) { + LOG_WARN("tablet_to_ls map set fail", KR(ret), K(tenant_id), K(tablet_ls_pair)); + } + } + } + + return ret; +} + + +} // end namespace share +} // end namespace oceanbase diff --git a/src/share/tablet/ob_tenant_tablet_to_ls_map.h b/src/share/tablet/ob_tenant_tablet_to_ls_map.h new file mode 100644 index 000000000..77b27235a --- /dev/null +++ b/src/share/tablet/ob_tenant_tablet_to_ls_map.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2021 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_TABLET_OB_TENANT_TABLET_TO_LS_MAP_H +#define OCEANBASE_SHARE_TABLET_OB_TENANT_TABLET_TO_LS_MAP_H + +#include "lib/alloc/alloc_struct.h" // ObLabel +#include "lib/hash/ob_hashmap.h" // ObHashMap +#include "share/ob_ls_id.h" // ObLSID + +namespace oceanbase +{ +namespace common +{ +class ObISQLClient; +class ObTabletID; +class ObMySQLProxy; +} +namespace share +{ +class ObTabletToLSTableOperator; + +typedef common::hash::ObHashMap ObTabletToLSMap; + +// Tenant all tablet to LS info +// It will build map in build() function. +class ObTenantTabletToLSMap final +{ +public: + ObTenantTabletToLSMap() : map_() {} + ~ObTenantTabletToLSMap() {} + + int init(const int64_t bucket_num = 4096, + const lib::ObLabel label = lib::ObLabel("TenantTabletToLSMap")) + { + return map_.create(bucket_num, label); + } + void destroy() { map_.destroy(); } + + int build(const uint64_t tenant_id, + common::ObMySQLProxy &sql_proxy); + + int clear() { return map_.clear(); } + + int get(const common::ObTabletID &tablet_id, ObLSID &ls_id) const + { + return map_.get_refactored(tablet_id, ls_id); + } + int64_t size() const { return map_.size(); } + +private: + ObTabletToLSMap map_; +}; + +} // end namespace share +} // end namespace oceanbase + +#endif // OCEANBASE_SHARE_TABLET_OB_TENANT_TABLET_TO_LS_MAP_H diff --git a/src/share/transfer/ob_transfer_info.cpp b/src/share/transfer/ob_transfer_info.cpp new file mode 100644 index 000000000..f4292c61a --- /dev/null +++ b/src/share/transfer/ob_transfer_info.cpp @@ -0,0 +1,751 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE +#include "share/transfer/ob_transfer_info.h" +#include "share/schema/ob_schema_struct.h" // ObBasePartition +#include "lib/profile/ob_trace_id.h" // TraceId +#include "storage/tablelock/ob_table_lock_rpc_struct.h" // ObLockObjRequest +#include "lib/mysqlclient/ob_mysql_transaction.h" // ObMysqlTransaction +#include "observer/ob_inner_sql_connection.h" // ObInnerSQLConnection +#include "share/ob_share_util.h" // ObShareUtil +#include "storage/tablelock/ob_lock_inner_connection_util.h" // ObInnerConnectionLockUtil + +using namespace oceanbase; +using namespace share; +using namespace common; +using namespace palf; +using namespace share::schema; +using namespace share; +using namespace transaction::tablelock; +using namespace observer; + +ObTransferStatus &ObTransferStatus::operator=(const ObTransferStatus &status) +{ + status_ = status.status_; + return *this; +} + +ObTransferStatus &ObTransferStatus::operator=(const STATUS &status) +{ + status_ = status; + return *this; +} + +const char *ObTransferStatus::str() const +{ + const char *str = "INVALID_STATUS"; + switch (status_) { + case INIT: { + str = "INIT"; + break; + } + case START: { + str = "START"; + break; + } + case DOING: { + str = "DOING"; + break; + } + case COMPLETED: { + str = "COMPLETED"; + break; + } + case ABORTED: { + str = "ABORTED"; + break; + } + case FAILED: { + str = "FAILED"; + break; + } + case CANCELED: { + str = "CANCELED"; + break; + } + default: { + str = "INVALID_STATUS"; + } + } + return str; +} + +int ObTransferStatus::parse_from_str(const ObString &str) +{ + int ret = OB_SUCCESS; + if (0 == str.case_compare("INIT")) { + status_ = INIT; + } else if (0 == str.case_compare("START")) { + status_ = START; + } else if (0 == str.case_compare("DOING")) { + status_ = DOING; + } else if (0 == str.case_compare("COMPLETED")) { + status_ = COMPLETED; + } else if (0 == str.case_compare("ABORTED")) { + status_ = ABORTED; + } else if (0 == str.case_compare("FAILED")) { + status_ = FAILED; + } else if (0 == str.case_compare("CANCELED")) { + status_ = CANCELED; + } else { + status_ = MAX_STATUS; + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid transfer status str", KR(ret), K(str)); + } + return ret; +} + +bool ObTransferStatus::is_finish_status() const +{ + return COMPLETED == status_ + || FAILED == status_ + || CANCELED == status_; +} + +int ObTransferStatusHelper::check_can_change_status( + const ObTransferStatus &old_status, + const ObTransferStatus &new_status, + bool &can_change) +{ + int ret = OB_SUCCESS; + can_change = false; + if (OB_UNLIKELY(!old_status.is_valid() || !new_status.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invlaid status", KR(ret), K(old_status), K(new_status)); + } else if (old_status == new_status) { + can_change = true; + } else { + switch(old_status) { + case ObTransferStatus::INIT: { + if (new_status == ObTransferStatus::START + || new_status == ObTransferStatus::CANCELED + || new_status == ObTransferStatus::COMPLETED) { + can_change = true; + } + break; + } + case ObTransferStatus::START: { + if (new_status == ObTransferStatus::DOING + || new_status == ObTransferStatus::ABORTED) { + can_change = true; + } + break; + } + case ObTransferStatus::DOING: { + if (new_status == ObTransferStatus::COMPLETED) { + can_change = true; + } + break; + } + case ObTransferStatus::ABORTED: { + if (new_status == ObTransferStatus::FAILED) { + can_change = true; + } + break; + } + default: { + can_change = false; + } + } + } + return ret; +} + +ObTransferTabletInfo::ObTransferTabletInfo() + : tablet_id_(), + transfer_seq_(OB_INVALID_TRANSFER_SEQ) +{ +} + +void ObTransferTabletInfo::reset() +{ + tablet_id_.reset(); + transfer_seq_ = OB_INVALID_TRANSFER_SEQ; +} + +int ObTransferTabletInfo::init( + const ObTabletID &tablet_id, + const int64_t transfer_seq) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!tablet_id.is_valid() || transfer_seq <= OB_INVALID_TRANSFER_SEQ)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tablet_id), K(transfer_seq)); + } else { + tablet_id_ = tablet_id; + transfer_seq_ = transfer_seq; + } + return ret; +} + +int ObTransferTabletInfo::parse_from_display_str(const common::ObString &str) +{ + int ret = OB_SUCCESS; + uint64_t tablet_id; + errno = 0; + if (OB_UNLIKELY(2 != sscanf(str.ptr(), "%lu:%ld", &tablet_id, &transfer_seq_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ObTransferTabletInfo str", KR(ret), K(str), K(errno), KERRMSG); + } else { + tablet_id_ = tablet_id; // ObTabletID <- uint64_t + } + return ret; +} + +int ObTransferTabletInfo::to_display_str(char *buf, const int64_t len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0 || pos < 0 || pos >= len || !is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), KP(buf), K(len), K(pos), KPC(this)); + } else if (OB_FAIL(databuff_printf(buf, len, pos, "%lu:%ld", tablet_id_.id(), transfer_seq_))) { + LOG_WARN("databuff_printf failed", KR(ret), K(len), K(pos), K(buf), KPC(this)); + } + return ret; +} + +bool ObTransferTabletInfo::operator==(const ObTransferTabletInfo &other) const +{ + return other.tablet_id_ == tablet_id_ + && other.transfer_seq_ == transfer_seq_; +} + +OB_SERIALIZE_MEMBER(ObTransferTabletInfo, tablet_id_, transfer_seq_); + +void ObTransferPartInfo::reset() +{ + table_id_ = OB_INVALID_ID; + part_object_id_ = OB_INVALID_ID; +} + +int ObTransferPartInfo::init(const ObObjectID &table_id, const ObObjectID &part_object_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_ID == table_id || OB_INVALID_ID == part_object_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid id", KR(ret), K(table_id), K(part_object_id)); + } else { + table_id_ = table_id; + part_object_id_ = part_object_id; + } + return ret; +} + +int ObTransferPartInfo::init(const schema::ObBasePartition &part_schema) +{ + int ret = OB_SUCCESS; + table_id_ = part_schema.get_table_id(); + part_object_id_ = part_schema.get_object_id(); + return ret; +} + +int ObTransferPartInfo::parse_from_display_str(const common::ObString &str) +{ + int ret = OB_SUCCESS; + errno = 0; + if (OB_UNLIKELY(2 != sscanf(str.ptr(), "%lu:%lu", &table_id_, &part_object_id_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ObTransferTabletInfo str", KR(ret), K(str), K(errno), KERRMSG); + } + return ret; +} + +int ObTransferPartInfo::to_display_str(char *buf, const int64_t len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0 || pos < 0 || pos >= len || !is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), KP(buf), K(len), K(pos), KPC(this)); + } else if (OB_FAIL(databuff_printf(buf, len, pos, "%lu:%lu", table_id_, part_object_id_))) { + LOG_WARN("databuff_printf failed", KR(ret), K(len), K(pos), K(buf), KPC(this)); + } + return ret; +} + +bool ObTransferPartInfo::operator==(const ObTransferPartInfo &other) const +{ + return other.table_id_ == table_id_ + && other.part_object_id_ == part_object_id_; +} + +int ObDisplayTabletID::parse_from_display_str(const common::ObString &str) +{ + int ret = OB_SUCCESS; + uint64_t tablet_id; + errno = 0; + if (OB_UNLIKELY(1 != sscanf(str.ptr(), "%lu", &tablet_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ObDisplayTabletID str", KR(ret), K(str), K(errno), KERRMSG); + } else { + tablet_id_ = tablet_id; // ObTabletID <- uint64_t + } + return ret; +} + +int ObDisplayTabletID::to_display_str(char *buf, const int64_t len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0 || pos < 0 || pos >= len || !is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), KP(buf), K(len), K(pos), KPC(this)); + } else if (OB_FAIL(databuff_printf(buf, len, pos, "%lu", tablet_id_.id()))) { + LOG_WARN("databuff_printf failed", KR(ret), K(len), K(pos), K(buf), KPC(this)); + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObDisplayTabletID, tablet_id_); + +static const char* TRANSFER_TASK_COMMENT_ARRAY[] = +{ + "",/*EMPTY_COMMENT*/ + "Wait for member list to be same", + "Task completed as no valid partition", + "Task canceled", + "Unable to process task due to transaction timeout", + "Unknow"/*MAX_COMMENT*/ +}; + +const char *oceanbase::share::transfer_task_comment_to_str(const ObTransferTaskComment &comment) +{ + STATIC_ASSERT(ARRAYSIZEOF(TRANSFER_TASK_COMMENT_ARRAY) == (int64_t)ObTransferTaskComment::MAX_COMMENT + 1, + "transfer task comment array size mismatch enum ObTransferTaskComment count"); + OB_ASSERT(comment >= 0 && comment <= ObTransferTaskComment::MAX_COMMENT); + return TRANSFER_TASK_COMMENT_ARRAY[comment]; +} + +ObTransferTaskComment oceanbase::share::str_to_transfer_task_comment(const common::ObString &str) +{ + ObTransferTaskComment comment = ObTransferTaskComment::MAX_COMMENT; + for (int64_t i = 0; i < ARRAYSIZEOF(TRANSFER_TASK_COMMENT_ARRAY); i++) { + if (0 == str.case_compare(TRANSFER_TASK_COMMENT_ARRAY[i])) { + comment = static_cast(i); + break; + } + } + return comment; +} + +int ObTransferTask::TaskStatus::init(const ObTransferTaskID task_id, const ObTransferStatus &status) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!task_id.is_valid()|| !status.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(task_id), K(status)); + } else { + task_id_ = task_id; + status_ = status; + } + return ret; +} + +void ObTransferTask::TaskStatus::reset() +{ + task_id_.reset(); + status_.reset(); +} + +ObTransferTask::TaskStatus &ObTransferTask::TaskStatus::operator=( + const TaskStatus &other) +{ + task_id_ = other.task_id_; + status_ = other.status_; + return *this; +} + +/////////////////////////////////////////////////////////////// + +ObTransferTask::ObTransferTask() + : task_id_(), + src_ls_(), + dest_ls_(), + part_list_(), + not_exist_part_list_(), + lock_conflict_part_list_(), + table_lock_tablet_list_(), + tablet_list_(), + start_scn_(), + finish_scn_(), + status_(), + trace_id_(), + result_(-1), + comment_(ObTransferTaskComment::EMPTY_COMMENT), + balance_task_id_(), + table_lock_owner_id_(OB_INVALID_INDEX) +{ +} + + +void ObTransferTask::reset() +{ + task_id_.reset(); + src_ls_.reset(); + dest_ls_.reset(); + part_list_.reset(); + not_exist_part_list_.reset(); + lock_conflict_part_list_.reset(); + table_lock_tablet_list_.reset(), + tablet_list_.reset(); + start_scn_.reset(); + finish_scn_.reset(); + status_.reset(); + trace_id_.reset(); + result_ = -1; + comment_ = ObTransferTaskComment::EMPTY_COMMENT; + balance_task_id_.reset(); + table_lock_owner_id_ = OB_INVALID_INDEX; +} + +// init by necessary info, other members take default values +int ObTransferTask::init( + const ObTransferTaskID task_id, + const ObLSID &src_ls, + const ObLSID &dest_ls, + const ObTransferPartList &part_list, + const ObTransferStatus &status, + const common::ObCurTraceId::TraceId &trace_id, + const ObBalanceTaskID balance_task_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!task_id.is_valid() + || !src_ls.is_valid() + || !dest_ls.is_valid() + || part_list.empty() + || !status.is_valid() + || trace_id.is_invalid() + || ! balance_task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid aruguments", KR(ret), K(task_id), K(src_ls), + K(dest_ls), K(part_list), K(status), K(trace_id), K(balance_task_id)); + } else { + reset(); + if (OB_FAIL(part_list_.assign(part_list))) { + LOG_WARN("fail to assign part_list", KR(ret), K(part_list)); + } else { + task_id_ = task_id; + src_ls_ = src_ls; + dest_ls_ = dest_ls; + status_ = status; + trace_id_ = trace_id; + balance_task_id_ = balance_task_id; + start_scn_.set_min(); + finish_scn_.set_min(); + } + } + return ret; +} + +// init all members +int ObTransferTask::init( + const ObTransferTaskID task_id, + const ObLSID &src_ls, + const ObLSID &dest_ls, + const ObString &part_list_str, + const ObString ¬_exist_part_list_str, + const ObString &lock_conflict_part_list_str, + const ObString &table_lock_tablet_list_str, + const ObString &tablet_list_str, + const share::SCN &start_scn, + const share::SCN &finish_scn, + const ObTransferStatus &status, + const common::ObCurTraceId::TraceId &trace_id, + const int result, + const ObTransferTaskComment &comment, + const ObBalanceTaskID balance_task_id, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!task_id.is_valid() + || !src_ls.is_valid() + || !dest_ls.is_valid() + || !status.is_valid() + || trace_id.is_invalid() + || ! balance_task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid aruguments", KR(ret), K(task_id), K(src_ls), + K(dest_ls), K(status), K(trace_id), K(balance_task_id)); + } else if (OB_FAIL(part_list_.parse_from_display_str(part_list_str))) { + LOG_WARN("fail to parse from string", KR(ret), K(part_list_str)); + } else if (OB_FAIL(not_exist_part_list_.parse_from_display_str( + not_exist_part_list_str))) { + LOG_WARN("fail to parse from string", KR(ret), K(not_exist_part_list_str)); + } else if (OB_FAIL(lock_conflict_part_list_.parse_from_display_str( + lock_conflict_part_list_str))) { + LOG_WARN("fail to parse from string", KR(ret), K(lock_conflict_part_list_str)); + } else if (OB_FAIL(table_lock_tablet_list_.parse_from_display_str(table_lock_tablet_list_str))) { + LOG_WARN("fail to parse from string", KR(ret), K(table_lock_tablet_list_str)); + } else if (OB_FAIL(tablet_list_.parse_from_display_str(tablet_list_str))) { + LOG_WARN("fail to parse from string", KR(ret), K(tablet_list_str)); + } else { + task_id_ = task_id; + src_ls_ = src_ls; + dest_ls_ = dest_ls; + start_scn_ = start_scn; + finish_scn_ = finish_scn; + status_ = status; + trace_id_ = trace_id; + result_ = result; + comment_ = comment; + balance_task_id_ = balance_task_id; + table_lock_owner_id_ = lock_owner_id; + } + return ret; +} + +int ObTransferTask::assign(const ObTransferTask &other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + // skip + } else if (OB_FAIL(part_list_.assign(other.part_list_))) { + LOG_WARN("fail to assign part_list", KR(ret), K(other)); + } else if (OB_FAIL(not_exist_part_list_.assign(other.not_exist_part_list_))) { + LOG_WARN("fail to assign not_exist_part_list", KR(ret), K(other)); + } else if (OB_FAIL(lock_conflict_part_list_.assign(other.lock_conflict_part_list_))) { + LOG_WARN("fail to assign lock_conflict_part_list", KR(ret), K(other)); + } else if (OB_FAIL(table_lock_tablet_list_.assign(other.table_lock_tablet_list_))) { + LOG_WARN("fail to assign table_lock_tablet_list", KR(ret), K(other)); + } else if (OB_FAIL(tablet_list_.assign(other.tablet_list_))) { + LOG_WARN("fail to assign tablet_list", KR(ret), K(other)); + } else { + task_id_ = other.task_id_; + src_ls_ = other.src_ls_; + dest_ls_ = other.dest_ls_; + start_scn_ = other.start_scn_; + finish_scn_ = other.finish_scn_; + status_ = other.status_; + trace_id_ = other.trace_id_; + result_ = other.result_; + comment_ = other.comment_; + balance_task_id_ = other.balance_task_id_; + table_lock_owner_id_ = other.table_lock_owner_id_; + } + return ret; +} + +bool ObTransferTask::is_valid() const +{ + return task_id_.is_valid() + && src_ls_.is_valid() + && dest_ls_.is_valid() + && status_.is_valid() + && !trace_id_.is_invalid() + && balance_task_id_.is_valid() + && (!part_list_.empty() + || !not_exist_part_list_.empty() + || !lock_conflict_part_list_.empty()); +} + + +ObTransferTaskInfo::ObTransferTaskInfo() + : tenant_id_(OB_INVALID_ID), + src_ls_id_(), + dest_ls_id_(), + task_id_(), + trace_id_(), + status_(), + table_lock_owner_id_(), + table_lock_tablet_list_(), + tablet_list_(), + start_scn_(), + finish_scn_(), + result_(OB_SUCCESS) +{ +} + +void ObTransferTaskInfo::reset() +{ + tenant_id_ = OB_INVALID_ID; + src_ls_id_.reset(); + dest_ls_id_.reset(); + task_id_.reset(); + trace_id_.reset(); + status_.reset(); + table_lock_owner_id_.reset(); + table_lock_tablet_list_.reset(); + tablet_list_.reset(); + start_scn_.reset(); + finish_scn_.reset(); + result_ = OB_SUCCESS; +} + +// table_lock_tablet_list_ may be empty +bool ObTransferTaskInfo::is_valid() const +{ + return tenant_id_ != OB_INVALID_ID + && src_ls_id_.is_valid() + && dest_ls_id_.is_valid() + && task_id_.is_valid() + && !trace_id_.is_invalid() + && status_.is_valid() + && table_lock_owner_id_.is_valid() + && !tablet_list_.empty(); +} + +int ObTransferTaskInfo::convert_from(const uint64_t tenant_id, const ObTransferTask &task) +{ + int ret = OB_SUCCESS; + if (!task.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", KR(ret), K(task)); + } else if (OB_FAIL(table_lock_tablet_list_.assign(task.get_table_lock_tablet_list()))) { + LOG_WARN("fail to assign table lock tablet list", KR(ret), K(task)); + } else if (OB_FAIL(tablet_list_.assign(task.get_tablet_list()))) { + LOG_WARN("fail to assign tablet list", KR(ret), K(task)); + } else { + tenant_id_ = tenant_id; + src_ls_id_ = task.get_src_ls(); + dest_ls_id_ = task.get_dest_ls(); + task_id_ = task.get_task_id(); + trace_id_ = task.get_trace_id(); + status_ = task.get_status(); + table_lock_owner_id_ = task.get_table_lock_owner_id(); + start_scn_ = task.get_start_scn(); + finish_scn_ = task.get_finish_scn(); + result_ = task.get_result(); + } + return ret; +} + +int ObTransferTaskInfo::assign(const ObTransferTaskInfo &task_info) +{ + int ret = OB_SUCCESS; + if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("assign transfer task info get invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(table_lock_tablet_list_.assign(task_info.table_lock_tablet_list_))) { + LOG_WARN("failed to assign table lock tablet list", K(ret), K(task_info)); + } else if (OB_FAIL(tablet_list_.assign(task_info.tablet_list_))) { + LOG_WARN("failed to assign tablet list", K(ret), K(task_info)); + } else { + tenant_id_ = task_info.tenant_id_; + src_ls_id_ = task_info.src_ls_id_; + dest_ls_id_ = task_info.dest_ls_id_; + task_id_ = task_info.task_id_; + trace_id_ = task_info.trace_id_; + status_ = task_info.status_; + table_lock_owner_id_ = task_info.table_lock_owner_id_; + start_scn_ = task_info.start_scn_; + finish_scn_ = task_info.finish_scn_; + result_ = task_info.result_; + } + return ret; +} + +int ObTransferLockUtil::lock_tablet_on_dest_ls_for_table_lock( + ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObLSID &dest_ls, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id, + const ObDisplayTabletList &table_lock_tablet_list) +{ + int ret = OB_SUCCESS; + if (table_lock_tablet_list.empty()) { + // skip + } else { + ObLockAloneTabletRequest lock_arg; + lock_arg.op_type_ = OUT_TRANS_LOCK; + if (OB_FAIL(process_table_lock_on_tablets_( + trans, + tenant_id, + dest_ls, + lock_owner_id, + table_lock_tablet_list, + lock_arg))) { + LOG_WARN("process table lock on tablets failed", KR(ret), + K(dest_ls), K(lock_owner_id), K(table_lock_tablet_list), K(lock_arg)); + } + } + return ret; +} + +int ObTransferLockUtil::unlock_tablet_on_src_ls_for_table_lock( + ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObLSID &src_ls, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id, + const ObDisplayTabletList &table_lock_tablet_list) +{ + int ret = OB_SUCCESS; + if (table_lock_tablet_list.empty()) { + // skip + } else { + ObUnLockAloneTabletRequest unlock_arg; + unlock_arg.op_type_ = OUT_TRANS_UNLOCK; + if (OB_FAIL(process_table_lock_on_tablets_( + trans, + tenant_id, + src_ls, + lock_owner_id, + table_lock_tablet_list, + unlock_arg))) { + LOG_WARN("process table lock on tablets failed", KR(ret), + K(src_ls), K(lock_owner_id), K(table_lock_tablet_list), K(unlock_arg)); + } + } + return ret; +} + +template +int ObTransferLockUtil::process_table_lock_on_tablets_( + ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObLSID &ls_id, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id, + const ObDisplayTabletList &table_lock_tablet_list, + LockArg &lock_arg) +{ + int ret = OB_SUCCESS; + lock_arg.tablet_ids_.reset(); + ObTimeoutCtx ctx; + ObInnerSQLConnection *conn = NULL; + const int64_t DEFAULT_TIMEOUT = GCONF.internal_sql_execute_timeout; + if (OB_UNLIKELY(!ls_id.is_valid_with_tenant(tenant_id) + || !lock_owner_id.is_valid() + || table_lock_tablet_list.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(ls_id), K(tenant_id), K(lock_owner_id), K(table_lock_tablet_list)); + } else if (OB_ISNULL(conn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("connection is null", KR(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, DEFAULT_TIMEOUT))) { + LOG_WARN("fail to set default_timeout_ctx", KR(ret)); + } else if (OB_FAIL(lock_arg.tablet_ids_.reserve(table_lock_tablet_list.count()))) { + LOG_WARN("reserve failed", KR(ret), "count", table_lock_tablet_list.count()); + } else { + lock_arg.lock_mode_ = ROW_SHARE; + lock_arg.timeout_us_ = ctx.get_timeout(); + lock_arg.ls_id_ = ls_id; + lock_arg.owner_id_ = lock_owner_id; + ARRAY_FOREACH(table_lock_tablet_list, idx) { + const ObTabletID &tablet_id = table_lock_tablet_list.at(idx).tablet_id(); + if (OB_FAIL(lock_arg.tablet_ids_.push_back(tablet_id))) { + LOG_WARN("push back failed", KR(ret), K(tablet_id)); + } + } + } + if (OB_FAIL(ret)) { + } else if (OUT_TRANS_LOCK == lock_arg.op_type_) { + if (OB_FAIL(ObInnerConnectionLockUtil::lock_tablet(tenant_id, lock_arg, conn))) { + LOG_WARN("lock tablet failed", KR(ret), K(tenant_id), K(lock_arg)); + } + } else if (OUT_TRANS_UNLOCK == lock_arg.op_type_) { + if (OB_FAIL(ObInnerConnectionLockUtil::unlock_tablet(tenant_id, lock_arg, conn))) { + LOG_WARN("unock tablet failed", KR(ret), K(tenant_id), K(lock_arg)); + } + } else { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid lock arg", KR(ret), K(lock_arg)); + } + return ret; +} \ No newline at end of file diff --git a/src/share/transfer/ob_transfer_info.h b/src/share/transfer/ob_transfer_info.h new file mode 100644 index 000000000..240b60ea6 --- /dev/null +++ b/src/share/transfer/ob_transfer_info.h @@ -0,0 +1,410 @@ +/** + * 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 OCENABASE_SHARE_OB_TRANSFER_INFO_H +#define OCENABASE_SHARE_OB_TRANSFER_INFO_H + +#include +#include "lib/utility/ob_print_utils.h" +#include "lib/string/ob_sql_string.h" // ObSqlString +#include "lib/utility/ob_unify_serialize.h" +#include "share/ob_ls_id.h" // ObLSID +#include "share/ob_define.h" +#include "share/ob_balance_define.h" // ObBalanceTaskID, ObTransferTaskID +#include "share/schema/ob_schema_struct.h" // ObTableType, ObIndexType +#include "share/ob_display_list.h" // ObDisplayList +#include "common/ob_tablet_id.h" // ObTabletID +#include "share/scn.h" // SCN +#include "storage/tablelock/ob_table_lock_common.h" // ObTableLockOwnerID + +namespace oceanbase +{ +namespace share +{ +namespace schema +{ + class ObBasePartition; +} + +static const int64_t OB_INVALID_TRANSFER_SEQ = -1; + +/////////////// ObTransferStatus /////////////// +struct ObTransferStatus final +{ +public: + enum STATUS : uint8_t + { + INIT = 0, + START = 1, + DOING = 2, + COMPLETED = 3, + FAILED = 4, + ABORTED = 5, + CANCELED = 6, + MAX_STATUS + }; +public: + ObTransferStatus() : status_(MAX_STATUS) {} + ~ObTransferStatus() = default; + explicit ObTransferStatus(const STATUS &status) : status_(status) {} + + STATUS status() const { return status_; } + operator STATUS() const { return status_; } + bool is_valid() const { return INIT <= status_ && status_ < MAX_STATUS; } + void reset() { status_ = MAX_STATUS; } + ObTransferStatus &operator=(const ObTransferStatus &status); + ObTransferStatus &operator=(const STATUS &status); + const char *str() const; + int parse_from_str(const ObString &str); + + bool is_init_status() const { return INIT == status_; } + bool is_start_status() const { return START == status_; } + bool is_doing_status() const { return DOING == status_; } + bool is_aborted_status() const { return ABORTED == status_; } + bool is_canceled_status() const { return CANCELED == status_; } + bool is_failed_status() const { return FAILED == status_; } + bool is_completed_status() const { return COMPLETED == status_; } + // CANCELED/FAILED/COMPLETED + bool is_finish_status() const; + bool operator ==(const ObTransferStatus &other) const { return status_ == other.status_; } + bool operator !=(const ObTransferStatus &other) const { return status_ != other.status_; } + + TO_STRING_KV(K_(status), "status", str()); +private: + STATUS status_; +}; + +struct ObTransferStatusHelper +{ + static int check_can_change_status( + const ObTransferStatus &old_status, + const ObTransferStatus &new_status, + bool &can_change); +}; + +/////////////// ObTransferTabletInfo /////////////// +// +// Represents a Tablet for Transfer +struct ObTransferTabletInfo final : public ObDisplayType +{ + OB_UNIS_VERSION(1); +public: + ObTransferTabletInfo(); + ~ObTransferTabletInfo() = default; + void reset(); + bool is_valid() const { return tablet_id_.is_valid() && transfer_seq_ > OB_INVALID_TRANSFER_SEQ; } + const ObTabletID &tablet_id() const { return tablet_id_; } + int64_t transfer_seq() const { return transfer_seq_; } + + // define init to avoid initializing variables separately + int init(const ObTabletID &tablet_id, const int64_t transfer_seq); + bool operator==(const ObTransferTabletInfo &other) const; + + ///////////////////////// display string related //////////////////////// + // "table_id:part_id" max length: 20 + 20 + ':' + '\0' + int64_t max_display_str_len() const { return 42; } + // parse from string "tablet_id:transfer_seq" + int parse_from_display_str(const common::ObString &str); + // generate string "tablet_id:transfer_seq" + int to_display_str(char *buf, const int64_t len, int64_t &pos) const; + + TO_STRING_KV(K_(tablet_id), K_(transfer_seq)); +public: + ObTabletID tablet_id_; + int64_t transfer_seq_; +}; + +typedef ObDisplayList ObTransferTabletList; + +/////////////// ObTransferPartInfo /////////////// +// +// Represents a partition participating in the Transfer +struct ObTransferPartInfo final : public ObDisplayType +{ + struct Compare final + { + public: + Compare() {} + ~Compare() {} + bool operator() (const ObTransferPartInfo &left, const ObTransferPartInfo &right) + { + return (left.table_id() == right.table_id()) + ? (left.part_object_id() < right.part_object_id()) + : (left.table_id() < right.table_id()); + } + }; + + ObTransferPartInfo() : table_id_(OB_INVALID_ID), part_object_id_(OB_INVALID_ID) {} + ObTransferPartInfo(const ObObjectID &table_id, const ObObjectID &part_object_id) : + table_id_(table_id), part_object_id_(part_object_id) {} + ~ObTransferPartInfo() = default; + void reset(); + bool is_valid() const { return OB_INVALID_ID != table_id_ && OB_INVALID_ID != part_object_id_; } + const ObObjectID &table_id() const { return table_id_; } + const ObObjectID &part_object_id() const { return part_object_id_; } + + // define init to avoid initializing variables separately + int init(const ObObjectID &table_id, const ObObjectID &part_object_id); + // init by partition schema + int init(const schema::ObBasePartition &part_schema); + + ///////////////////////// display string related //////////////////////// + // "table_id:part_id" max length: 20 + 20 + ':' + '\0' + int64_t max_display_str_len() const { return 42; } + // parse from string "table_id:part_id" + int parse_from_display_str(const common::ObString &str); + // generate string "table_id:part_id" + // NOTE: can not include commas ',' + int to_display_str(char *buf, const int64_t len, int64_t &pos) const; + + bool operator==(const ObTransferPartInfo &other) const; + + TO_STRING_KV(K_(table_id), K_(part_object_id)); +private: + ObObjectID table_id_; + ObObjectID part_object_id_; // It means part_id for level one partition or subpart_id for subpartition. +}; + +typedef ObDisplayList ObTransferPartList; + +struct ObDisplayTabletID final : public ObDisplayType +{ + OB_UNIS_VERSION(1); +public: + ObDisplayTabletID() : tablet_id_() {} + explicit ObDisplayTabletID(const ObTabletID &tablet_id) : tablet_id_(tablet_id) {} + ~ObDisplayTabletID() = default; + void reset() { tablet_id_.reset(); } + bool is_valid() const { return tablet_id_.is_valid(); } + const ObTabletID &tablet_id() const { return tablet_id_; } + + ///////////////////////// display string related //////////////////////// + // "tablet_id" max length: 20 + '\0' + int64_t max_display_str_len() const { return 21; } + // parse from string "tablet_id" + int parse_from_display_str(const common::ObString &str); + // generate string "tablet_id" + int to_display_str(char *buf, const int64_t len, int64_t &pos) const; + + bool operator==(const ObDisplayTabletID &other) const { return tablet_id_ == other.tablet_id_; }; + TO_STRING_KV(K_(tablet_id)); +private: + ObTabletID tablet_id_; +}; + +typedef ObDisplayList ObDisplayTabletList; + +/////////////// ObTransferTask related /////////////// +// used to display the task extra info in the comment column of __all_transfer_task +// when you add comment, you need to add corresponding string to TRANSFER_TASK_COMMENT_ARRAY[] +enum ObTransferTaskComment +{ + EMPTY_COMMENT = 0, + WAIT_FOR_MEMBER_LIST = 1, + TASK_COMPLETED_AS_NO_VALID_PARTITION = 2, + TASK_CANCELED = 3, + TRANSACTION_TIMEOUT = 4, + MAX_COMMENT +}; + +//for ObTransferTaskComment +const char *transfer_task_comment_to_str(const ObTransferTaskComment &comment); +ObTransferTaskComment str_to_transfer_task_comment(const common::ObString &str); + +// Represents a row in __all_transfer_task +class ObTransferTask +{ +public: + struct TaskStatus final + { + public: + TaskStatus() : task_id_(), status_() {} + ~TaskStatus() {} + int init(const ObTransferTaskID task_id, const ObTransferStatus &status); + void reset(); + TaskStatus &operator=(const TaskStatus &other); + bool is_valid() const { return task_id_.is_valid() && status_.is_valid(); } + const ObTransferTaskID &get_task_id() const { return task_id_; } + const ObTransferStatus &get_status() const { return status_; } + + TO_STRING_KV(K_(task_id), K_(status)); + private: + ObTransferTaskID task_id_; + ObTransferStatus status_; + }; + +public: + ObTransferTask(); + virtual ~ObTransferTask() {} + void reset(); + + // init by necessary info, other members take default values + int init( + const ObTransferTaskID task_id, + const ObLSID &src_ls, + const ObLSID &dest_ls, + const ObTransferPartList &part_list, + const ObTransferStatus &status, + const common::ObCurTraceId::TraceId &trace_id, + const ObBalanceTaskID balance_task_id); + + // init all members + int init( + const ObTransferTaskID task_id, + const ObLSID &src_ls, + const ObLSID &dest_ls, + const ObString &part_list_str, + const ObString ¬_exist_part_list_str, + const ObString &lock_conflict_part_list_str, + const ObString &table_lock_tablet_list_str, + const ObString &tablet_list_str, + const share::SCN &start_scn, + const share::SCN &finish_scn, + const ObTransferStatus &status, + const common::ObCurTraceId::TraceId &trace_id, + const int result, + const ObTransferTaskComment &comment, + const ObBalanceTaskID balance_task_id, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id); + + int assign(const ObTransferTask &other); + bool is_valid() const; + + void set_status(const ObTransferStatus &status) { status_ = status; } + void set_start_scn(const share::SCN &start_scn) { start_scn_ = start_scn; } + void set_finish_scn(const share::SCN &finish_scn) { finish_scn_ = finish_scn; } + void set_result(const int32_t result) { result_ = result; } + + ObTransferTaskID get_task_id() const { return task_id_; } + const ObLSID &get_src_ls() const { return src_ls_; } + const ObLSID &get_dest_ls() const { return dest_ls_; } + const ObTransferPartList &get_part_list() const { return part_list_; } + ObTransferPartList &get_part_list() { return part_list_; } + const ObTransferPartList &get_not_exist_part_list() const { return not_exist_part_list_; } + const ObTransferPartList &get_lock_conflict_part_list() const { return lock_conflict_part_list_; } + const ObDisplayTabletList &get_table_lock_tablet_list() const { return table_lock_tablet_list_; } + const ObTransferTabletList &get_tablet_list() const { return tablet_list_; } + ObTransferTabletList &get_tablet_list() { return tablet_list_; } + const share::SCN &get_start_scn() const { return start_scn_; } + const share::SCN &get_finish_scn() const { return finish_scn_; } + const ObTransferStatus &get_status() const { return status_; } + const common::ObCurTraceId::TraceId &get_trace_id() const { return trace_id_; } + int32_t get_result() const { return result_; } + const ObTransferTaskComment &get_comment() const { return comment_; } + ObBalanceTaskID get_balance_task_id() const { return balance_task_id_; } + const transaction::tablelock::ObTableLockOwnerID &get_table_lock_owner_id() const + { + return table_lock_owner_id_; + } + + TO_STRING_KV(K_(task_id), K_(src_ls), K_(dest_ls), K_(part_list), + K_(not_exist_part_list), K_(lock_conflict_part_list), K_(table_lock_tablet_list), K_(tablet_list), K_(start_scn), K_(finish_scn), + K_(status), K_(trace_id), K_(result), K_(comment), K_(balance_task_id), K_(table_lock_owner_id)); + +private: + ObTransferTaskID task_id_; + share::ObLSID src_ls_; + share::ObLSID dest_ls_; + ObTransferPartList part_list_; + ObTransferPartList not_exist_part_list_; + ObTransferPartList lock_conflict_part_list_; + ObDisplayTabletList table_lock_tablet_list_; + ObTransferTabletList tablet_list_; + share::SCN start_scn_; + share::SCN finish_scn_; + ObTransferStatus status_; + common::ObCurTraceId::TraceId trace_id_; + int32_t result_; + ObTransferTaskComment comment_; + ObBalanceTaskID balance_task_id_; + transaction::tablelock::ObTableLockOwnerID table_lock_owner_id_; +}; + +struct ObTransferTaskInfo final +{ + ObTransferTaskInfo(); + ~ObTransferTaskInfo() = default; + void reset(); + bool is_valid() const; + int convert_from(const uint64_t tenant_id, const ObTransferTask &task); + int assign(const ObTransferTaskInfo &task_info); + + TO_STRING_KV(K_(tenant_id), K_(src_ls_id), K_(dest_ls_id), K_(task_id), K_(trace_id), + K_(status), K_(table_lock_owner_id), K_(table_lock_tablet_list), K_(tablet_list), + K_(start_scn), K_(finish_scn), K_(result)); + + uint64_t tenant_id_; + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + ObTransferTaskID task_id_; + common::ObCurTraceId::TraceId trace_id_; + ObTransferStatus status_; + transaction::tablelock::ObTableLockOwnerID table_lock_owner_id_; + ObDisplayTabletList table_lock_tablet_list_; + ObArray tablet_list_; + share::SCN start_scn_; + share::SCN finish_scn_; + int32_t result_; + DISALLOW_COPY_AND_ASSIGN(ObTransferTaskInfo); +}; + +// remove discarded_list from original_list +template +static int remove_from_list(LIST &original_list, const LIST &discarded_list) +{ + int ret = OB_SUCCESS; + for(int64_t i = discarded_list.count() - 1; i >= 0 && OB_SUCC(ret); --i) { + for(int64_t j = original_list.count() - 1; j >= 0 && OB_SUCC(ret); --j) { + if (discarded_list.at(i) == original_list.at(j)) { + if (OB_FAIL(original_list.remove(j))) { + COMMON_LOG(WARN, "remove failed", KR(ret), K(i), K(j), K(discarded_list), K(original_list)); + } else { + break; + } + } + } + } + return ret; +} + +// part table lock on tablet needs to be moved from src_ls to dest_ls when tablets transfer +class ObTransferLockUtil +{ +public: + // Used to move part table lock on tablet. This function is called in transfer start transaction. + static int lock_tablet_on_dest_ls_for_table_lock( + ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObLSID &dest_ls, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id, + const ObDisplayTabletList &table_lock_tablet_list); + // Used to move part table lock on tablet. This function is called in transfer finish transaction. + static int unlock_tablet_on_src_ls_for_table_lock( + ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObLSID &src_ls, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id, + const ObDisplayTabletList &table_lock_tablet_list); +private: + template + static int process_table_lock_on_tablets_( + ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObLSID &ls_id, + const transaction::tablelock::ObTableLockOwnerID &lock_owner_id, + const ObDisplayTabletList &table_lock_tablet_list, + LockArg &lock_arg); +}; + +} // end namespace share +} // end namespace oceanbase +#endif diff --git a/src/share/transfer/ob_transfer_task_operator.cpp b/src/share/transfer/ob_transfer_task_operator.cpp new file mode 100644 index 000000000..d78793c08 --- /dev/null +++ b/src/share/transfer/ob_transfer_task_operator.cpp @@ -0,0 +1,988 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX SHARE + +#include "share/transfer/ob_transfer_task_operator.h" +#include "share/ob_dml_sql_splicer.h" // ObDMLSqlSplicer +#include "lib/mysqlclient/ob_mysql_proxy.h" // ObISqlClient, SMART_VAR +#include "share/inner_table/ob_inner_table_schema.h" // OB_ALL_TRANSFER_TASK_TNAME + +namespace oceanbase +{ +using namespace common; +using namespace palf; +using namespace transaction::tablelock; + +namespace share +{ +int ObTransferTaskOperator::get( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const bool for_update, + ObTransferTask &task) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || !task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task_id), K(for_update)); + } else { + ObSqlString sql; + SMART_VAR(ObISQLClient::ReadResult, result) { + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE task_id = %ld%s", + OB_ALL_TRANSFER_TASK_TNAME, task_id.id(), for_update ? " FOR UPDATE" : ""))) { + LOG_WARN("fail to assign sql", KR(ret), K(task_id), K(for_update)); + } else if (OB_FAIL(sql_proxy.read(result, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(construct_transfer_task_(*result.get_result(), task))) { + LOG_WARN("construct transfer task failed", KR(ret), K(tenant_id), K(task_id), K(sql), K(task)); + } + } + } + return ret; +} + +int ObTransferTaskOperator::get_task_with_time( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const bool for_update, + ObTransferTask &task, + int64_t &create_time, + int64_t &finish_time) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || !task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task_id), K(for_update)); + } else { + SMART_VAR(ObISQLClient::ReadResult, result) { + ObSqlString sql; + common::sqlclient::ObMySQLResult *res = NULL; + const bool with_time = true; + if (OB_FAIL(sql.assign_fmt("SELECT time_to_usec(gmt_create) AS create_time, " + "time_to_usec(gmt_modified) AS finish_time, * FROM %s WHERE task_id = %ld%s", + OB_ALL_TRANSFER_TASK_TNAME, task_id.id(), for_update ? " FOR UPDATE" : ""))) { + LOG_WARN("fail to assign sql", KR(ret), K(task_id), K(for_update)); + } else if (OB_FAIL(sql_proxy.read(result, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(res = result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(res->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + } else { + LOG_WARN("get next result failed", KR(ret), K(sql), K(tenant_id), K(task_id)); + } + } else if (OB_FAIL(parse_sql_result_(*res, with_time, task, create_time, finish_time))) { + LOG_WARN("parse sql result failed", KR(ret), K(tenant_id), K(task_id), K(task)); + } else if (OB_FAIL(res->next())) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("get next result failed", KR(ret), K(tenant_id), K(task_id)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("read more than one row", KR(ret), K(tenant_id), K(task_id)); + } + } // end SMART_VAR + } + return ret; +} + +int ObTransferTaskOperator::get_by_status( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferStatus &status, + common::ObIArray &tasks) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || !status.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(status)); + } else { + ObSqlString sql; + SMART_VAR(ObISQLClient::ReadResult, result) { + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE status = '%s'", + OB_ALL_TRANSFER_TASK_TNAME, status.str()))) { + LOG_WARN("fail to assign sql", KR(ret), K(status)); + } else if (OB_FAIL(sql_proxy.read(result, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(construct_transfer_tasks_(*result.get_result(), tasks))) { + LOG_WARN("construct transfer task failed", KR(ret), K(tenant_id), K(sql), K(tasks)); + } else if (tasks.empty()) { + ret = OB_ENTRY_NOT_EXIST; + LOG_TRACE("tasks in status not found", KR(ret), K(tenant_id), K(status), K(tasks)); + } + } + } + return ret; +} + +int ObTransferTaskOperator::get_all_task_status( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + common::ObIArray &task_status) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else { + ObSqlString sql; + SMART_VAR(ObISQLClient::ReadResult, result) { + if (OB_FAIL(sql.assign_fmt("SELECT task_id, status FROM %s", OB_ALL_TRANSFER_TASK_TNAME))) { + LOG_WARN("fail to assign sql", KR(ret), K(tenant_id)); + } else if (OB_FAIL(sql_proxy.read(result, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(construct_task_status_(*result.get_result(), task_status))) { + LOG_WARN("construct transfer task failed", KR(ret), K(tenant_id), K(sql), K(task_status)); + } else if (task_status.empty()) { + ret = OB_ENTRY_NOT_EXIST; + LOG_TRACE("no task in table", KR(ret), K(tenant_id), K(task_status)); + } + } + } + return ret; +} + +int ObTransferTaskOperator::get_by_dest_ls( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObLSID &dest_ls, + ObTransferTask &task) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || !dest_ls.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(dest_ls)); + } else { + ObSqlString sql; + SMART_VAR(ObISQLClient::ReadResult, result) { + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE dest_ls = %ld", + OB_ALL_TRANSFER_TASK_TNAME, dest_ls.id()))) { + LOG_WARN("fail to assign sql", KR(ret), K(dest_ls)); + } else if (OB_FAIL(sql_proxy.read(result, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(construct_transfer_task_(*result.get_result(), task))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("construct transfer task failed", KR(ret), K(tenant_id), K(dest_ls), K(sql)); + } else { + LOG_TRACE("dest ls transfer task not found", KR(ret), K(tenant_id), K(dest_ls)); + } + } + } + } + return ret; +} + +int ObTransferTaskOperator::fill_dml_splicer_( + ObDMLSqlSplicer &dml_splicer, + common::ObArenaAllocator &allocator, + const ObTransferTask &task) +{ + int ret = OB_SUCCESS; + char *trace_id = NULL; + ObString part_list_str; + ObString not_exist_part_list_str; + ObString lock_conflict_part_list_str; + ObString table_lock_tablet_list_str; + ObString tablet_list_str; + + if (OB_ISNULL(trace_id = static_cast(allocator.alloc(OB_MAX_TRACE_ID_BUFFER_SIZE)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", KR(ret), "length", OB_MAX_TRACE_ID_BUFFER_SIZE); + } else if (OB_FALSE_IT(task.get_trace_id().to_string(trace_id, OB_MAX_TRACE_ID_BUFFER_SIZE))) { + } else if (OB_FAIL(task.get_part_list().to_display_str(allocator, part_list_str))) { + LOG_WARN("transfer list to str failed", KR(ret), + "part_list", task.get_part_list(), K(part_list_str)); + } else if (OB_FAIL(task.get_not_exist_part_list().to_display_str( + allocator, + not_exist_part_list_str))) { + LOG_WARN("transfer list to str failed", KR(ret), "not_exist_part_list", + task.get_not_exist_part_list(), K(not_exist_part_list_str)); + } else if (OB_FAIL(task.get_lock_conflict_part_list().to_display_str( + allocator, + lock_conflict_part_list_str))) { + LOG_WARN("transfer list to str failed", KR(ret), "lock_conflict_part_list", + task.get_lock_conflict_part_list(), K(lock_conflict_part_list_str)); + } else if (OB_FAIL(task.get_table_lock_tablet_list().to_display_str( + allocator, + table_lock_tablet_list_str))) { + LOG_WARN("transfer list to str failed", KR(ret), "table_lock_tablet_list", + task.get_table_lock_tablet_list(), K(table_lock_tablet_list_str)); + } else if (OB_FAIL(task.get_tablet_list().to_display_str(allocator, tablet_list_str))) { + LOG_WARN("transfer list to str failed", KR(ret), "tablet_list", + task.get_tablet_list(), K(tablet_list_str)); + } + + if (FAILEDx(dml_splicer.add_pk_column("task_id", task.get_task_id().id())) + || OB_FAIL(dml_splicer.add_column("src_ls", task.get_src_ls().id())) + || OB_FAIL(dml_splicer.add_column("dest_ls", task.get_dest_ls().id())) + || OB_FAIL(dml_splicer.add_column("part_list", part_list_str)) + || OB_FAIL(dml_splicer.add_column("part_count", task.get_part_list().count())) + || OB_FAIL(dml_splicer.add_column("not_exist_part_list", not_exist_part_list_str)) + || OB_FAIL(dml_splicer.add_column("lock_conflict_part_list", lock_conflict_part_list_str)) + || OB_FAIL(dml_splicer.add_column("table_lock_tablet_list", table_lock_tablet_list_str)) + || OB_FAIL(dml_splicer.add_column("tablet_list", tablet_list_str)) + || OB_FAIL(dml_splicer.add_column("tablet_count", task.get_tablet_list().count())) + || OB_FAIL(dml_splicer.add_column("start_scn", task.get_start_scn().get_val_for_inner_table_field())) + || OB_FAIL(dml_splicer.add_column("finish_scn", task.get_finish_scn().get_val_for_inner_table_field())) + || OB_FAIL(dml_splicer.add_column("status", task.get_status().str())) + || OB_FAIL(dml_splicer.add_column("trace_id", trace_id)) + || OB_FAIL(dml_splicer.add_column("result", task.get_result())) + || OB_FAIL(dml_splicer.add_column("comment", transfer_task_comment_to_str(task.get_comment()))) + || OB_FAIL(dml_splicer.add_column("balance_task_id", task.get_balance_task_id().id())) + || OB_FAIL(dml_splicer.add_column("table_lock_owner_id", task.get_table_lock_owner_id().id()))) { + LOG_WARN("fail to add column", KR(ret), K(task)); + } + return ret; +} + +int ObTransferTaskOperator::insert( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTask &task) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || !task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task)); + } else { + ObSqlString sql; + ObDMLSqlSplicer dml_splicer; + int64_t affected_rows = 0; + ObArenaAllocator allocator; + if (OB_FAIL(fill_dml_splicer_(dml_splicer, allocator, task))) { + LOG_WARN("fail to fill dml splicer", KR(ret), K(tenant_id), K(task)); + } else if (OB_FAIL(dml_splicer.finish_row())) { + LOG_WARN("fail to finish row", KR(ret), K(tenant_id), K(task)); + } else if (OB_FAIL(dml_splicer.splice_insert_sql(OB_ALL_TRANSFER_TASK_TNAME, sql))) { + LOG_WARN("fail to splice insert sql", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + if (OB_ERR_PRIMARY_KEY_DUPLICATE == ret) { + ret = OB_ENTRY_EXIST; + } + LOG_WARN("fail to write sql", KR(ret), K(tenant_id), K(sql), K(affected_rows), K(task)); + } else { + LOG_INFO("insert transfer task success", K(tenant_id), K(affected_rows), K(task)); + } + } + return ret; +} + +int ObTransferTaskOperator::update_to_start_status( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const ObTransferPartList &new_part_list, + const ObTransferPartList &new_not_exist_part_list, + const ObTransferPartList &new_lock_conflict_part_list, + const ObDisplayTabletList &new_table_lock_tablet_list, + const ObTransferTabletList &new_tablet_list, + const ObTransferStatus &new_status, + const ObTableLockOwnerID &table_lock_owner_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || !task_id.is_valid() + || new_part_list.empty() + || new_tablet_list.empty() + || !table_lock_owner_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), + K(tenant_id), K(task_id), K(new_part_list), K(new_tablet_list), K(table_lock_owner_id)); + } else if (old_status.status() != ObTransferStatus::INIT + || new_status.status() != ObTransferStatus::START) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("status not match", KR(ret), + K(tenant_id), K(task_id), K(old_status), K(new_status)); + } else { + ObSqlString sql; + ObDMLSqlSplicer dml_splicer; + int64_t affected_rows = 0; + ObString part_list_str; + ObString not_exist_part_list_str; + ObString lock_conflict_part_list_str; + ObString table_lock_tablet_list_str; + ObString tablet_list_str; + ObArenaAllocator allocator; + + if (OB_FAIL(new_part_list.to_display_str(allocator, part_list_str))) { + LOG_WARN("transfer list to str failed", KR(ret), K(new_part_list), K(part_list_str)); + } else if (OB_FAIL(new_tablet_list.to_display_str(allocator, tablet_list_str))) { + LOG_WARN("transfer list to str failed", KR(ret), K(new_tablet_list), K(tablet_list_str)); + } else if (OB_FAIL(new_not_exist_part_list.to_display_str( + allocator, + not_exist_part_list_str))) { + LOG_WARN("transfer list to str failed", KR(ret), + K(new_not_exist_part_list), K(not_exist_part_list_str)); + } else if (OB_FAIL(new_lock_conflict_part_list.to_display_str( + allocator, + lock_conflict_part_list_str))) { + LOG_WARN("transfer list to str failed", KR(ret), + K(new_lock_conflict_part_list), K(lock_conflict_part_list_str)); + } else if (OB_FAIL(new_table_lock_tablet_list.to_display_str( + allocator, + table_lock_tablet_list_str))) { + LOG_WARN("transfer list to str failed", KR(ret), + K(new_table_lock_tablet_list), K(table_lock_tablet_list_str)); + } + + if (FAILEDx(dml_splicer.add_pk_column("task_id", task_id.id())) + || OB_FAIL(dml_splicer.add_column("part_list", part_list_str)) + || OB_FAIL(dml_splicer.add_column("part_count", new_part_list.count())) + || OB_FAIL(dml_splicer.add_column("not_exist_part_list", not_exist_part_list_str)) + || OB_FAIL(dml_splicer.add_column("lock_conflict_part_list", lock_conflict_part_list_str)) + || OB_FAIL(dml_splicer.add_column("table_lock_tablet_list", table_lock_tablet_list_str)) + || OB_FAIL(dml_splicer.add_column("tablet_list", tablet_list_str)) + || OB_FAIL(dml_splicer.add_column("tablet_count", new_tablet_list.count())) + || OB_FAIL(dml_splicer.add_column("status", new_status.str())) + || OB_FAIL(dml_splicer.add_column("comment", transfer_task_comment_to_str(ObTransferTaskComment::EMPTY_COMMENT))) // reset comment + || OB_FAIL(dml_splicer.add_column("table_lock_owner_id", table_lock_owner_id.id()))) { + LOG_WARN("fail to add column", KR(ret), K(tenant_id), K(task_id), K(part_list_str), + K(not_exist_part_list_str), K(lock_conflict_part_list_str), K(table_lock_tablet_list_str), + K(tablet_list_str), K(new_status), K(table_lock_owner_id)); + } else if (OB_FAIL(dml_splicer.finish_row())) { + LOG_WARN("fail to finish row", KR(ret), K(tenant_id), K(task_id)); + } else if (OB_FAIL(dml_splicer.splice_update_sql(OB_ALL_TRANSFER_TASK_TNAME, sql))) { + LOG_WARN("fail to splice update sql", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(sql.append_fmt(" AND status='%s'", old_status.str()))) { + LOG_WARN("fail to append fmt", KR(ret), K(tenant_id), K(sql), K(old_status)); + } else if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("fail to write sql", KR(ret), K(tenant_id), K(sql), K(affected_rows)); + } else if (OB_UNLIKELY(1 != affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("incorrect affected rows", KR(ret), K(tenant_id), K(affected_rows), K(sql)); + } else { + LOG_INFO("update transfer_task to start success", + K(tenant_id), K(task_id), K(affected_rows), K(sql)); + } + } + return ret; +} + +int ObTransferTaskOperator::finish_task( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const ObTransferStatus &new_status, + const int result, + const ObTransferTaskComment &comment) +{ + int ret = OB_SUCCESS; + bool can_change = false; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || !task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task_id)); + } else if (OB_UNLIKELY(!new_status.is_finish_status())) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("incorrect new status", KR(ret), K(tenant_id), K(task_id), K(new_status)); + } else if (OB_FAIL(ObTransferStatusHelper::check_can_change_status( + old_status, + new_status, + can_change))) { + LOG_WARN("fail to check can change status", KR(ret), + K(old_status), K(new_status), K(tenant_id), K(task_id)); + } else if (OB_UNLIKELY(!can_change)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("can not change status", KR(ret), + K(old_status), K(new_status), K(tenant_id), K(task_id)); + } else { + ObSqlString sql; + ObDMLSqlSplicer dml_splicer; + int64_t affected_rows = 0; + if (OB_FAIL(dml_splicer.add_pk_column("task_id", task_id.id())) + || OB_FAIL(dml_splicer.add_column("status", new_status.str()) + || OB_FAIL(dml_splicer.add_column("result", result)) + || OB_FAIL(dml_splicer.add_column("comment", transfer_task_comment_to_str(comment))))) { + LOG_WARN("fail to add column", KR(ret), + K(tenant_id), K(task_id), K(new_status), K(result), K(comment)); + } else if (OB_FAIL(dml_splicer.finish_row())) { + LOG_WARN("fail to finish row", KR(ret), K(tenant_id)); + } else if (OB_FAIL(dml_splicer.splice_update_sql(OB_ALL_TRANSFER_TASK_TNAME, sql))) { + LOG_WARN("fail to splice update sql", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(sql.append_fmt(" AND status='%s'", old_status.str()))) { + LOG_WARN("fail to append fmt", KR(ret), K(tenant_id), K(sql), K(old_status)); + } else if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("fail to write sql", KR(ret), K(tenant_id), K(sql), K(affected_rows)); + } else if (OB_UNLIKELY(1 != affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("incorrect affected rows", KR(ret), K(tenant_id), K(affected_rows), K(sql)); + } else { + LOG_INFO("finish transfer_task success", + K(tenant_id), K(task_id), K(affected_rows), K(sql)); + } + } + return ret; +} + +int ObTransferTaskOperator::finish_task_from_init( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const ObTransferPartList &new_part_list, + const ObTransferPartList &new_not_exist_part_list, + const ObTransferPartList &new_lock_conflict_part_list, + const ObTransferStatus &new_status, + const int result, + const ObTransferTaskComment &comment) +{ + int ret = OB_SUCCESS; + bool can_change = false; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || !task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task_id)); + } else if (old_status.status() != ObTransferStatus::INIT + && new_status.status() != ObTransferStatus::COMPLETED) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("status not match", KR(ret), + K(tenant_id), K(task_id), K(old_status), K(new_status)); + } else { + ObSqlString sql; + ObDMLSqlSplicer dml_splicer; + int64_t affected_rows = 0; + ObArenaAllocator allocator; + ObString part_list_str; + ObString not_exist_part_list_str; + ObString lock_conflict_part_list_str; + if (OB_FAIL(new_part_list.to_display_str(allocator, part_list_str))) { + LOG_WARN("transfer list to display str failed", + KR(ret), K(part_list_str), K(new_part_list)); + } else if (OB_FAIL(new_not_exist_part_list.to_display_str( + allocator, + not_exist_part_list_str))) { + LOG_WARN("transfer list to display str failed", KR(ret), + K(new_not_exist_part_list), K(not_exist_part_list_str)); + } else if (OB_FAIL(new_lock_conflict_part_list.to_display_str( + allocator, + lock_conflict_part_list_str))) { + LOG_WARN("transfer list to display str failed", KR(ret), + K(new_lock_conflict_part_list), K(lock_conflict_part_list_str)); + } else if (OB_FAIL(dml_splicer.add_pk_column("task_id", task_id.id())) + || OB_FAIL(dml_splicer.add_column("part_list", part_list_str)) + || OB_FAIL(dml_splicer.add_column("not_exist_part_list", not_exist_part_list_str)) + || OB_FAIL(dml_splicer.add_column("lock_conflict_part_list", lock_conflict_part_list_str)) + || OB_FAIL(dml_splicer.add_column("status", new_status.str())) + || OB_FAIL(dml_splicer.add_column("result", result)) + || OB_FAIL(dml_splicer.add_column("comment", transfer_task_comment_to_str(comment)))) { + LOG_WARN("fail to add column", KR(ret), + K(tenant_id), K(task_id), K(new_status), K(result), K(comment)); + } else if (OB_FAIL(dml_splicer.finish_row())) { + LOG_WARN("fail to finish row", KR(ret), K(tenant_id)); + } else if (OB_FAIL(dml_splicer.splice_update_sql(OB_ALL_TRANSFER_TASK_TNAME, sql))) { + LOG_WARN("fail to splice update sql", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(sql.append_fmt(" AND status='%s'", old_status.str()))) { + LOG_WARN("fail to append fmt", KR(ret), K(tenant_id), K(sql), K(old_status)); + } else if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("fail to write sql", KR(ret), K(tenant_id), K(sql), K(affected_rows)); + } else if (OB_UNLIKELY(1 != affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("incorrect affected rows", KR(ret), K(tenant_id), K(affected_rows), K(sql)); + } else { + LOG_INFO("finish transfer_task from init success", + K(tenant_id), K(task_id), K(affected_rows), K(sql)); + } + } + return ret; +} + +int ObTransferTaskOperator::remove( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = 0; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || !task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task_id)); + } else if (OB_FAIL(sql.assign_fmt("DELETE FROM %s WHERE task_id = %ld", + OB_ALL_TRANSFER_TASK_TNAME, task_id.id()))) { + LOG_WARN("fail to assign sql", KR(ret), K(tenant_id), K(task_id)); + } else if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("fail to write sql", KR(ret), K(tenant_id), K(sql), K(affected_rows)); + } else if (OB_UNLIKELY(0 == affected_rows)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("incorrect affected rows", KR(ret), K(tenant_id), K(task_id), K(affected_rows)); + } else if (OB_UNLIKELY(1 < affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("delete more than one row", KR(ret), K(tenant_id), K(affected_rows), K(sql)); + } else { + LOG_INFO("remove transfer_task success", K(tenant_id), K(task_id)); + } + return ret; +} + +int ObTransferTaskOperator::update_status_and_result( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const ObTransferStatus &new_status, + const int result) +{ + int ret = OB_SUCCESS; + bool can_change = false; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || !task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task_id)); + } else if (OB_FAIL(ObTransferStatusHelper::check_can_change_status( + old_status, + new_status, + can_change))) { + LOG_WARN("fail to check can change status", KR(ret), + K(old_status), K(new_status), K(tenant_id), K(task_id)); + } else if (OB_UNLIKELY(!can_change)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("can not change status", KR(ret), + K(old_status), K(new_status), K(tenant_id), K(task_id)); + } else { + ObSqlString sql; + ObDMLSqlSplicer dml_splicer; + int64_t affected_rows = 0; + if (OB_FAIL(dml_splicer.add_pk_column("task_id", task_id.id())) + || OB_FAIL(dml_splicer.add_column("status", new_status.str())) + || OB_FAIL(dml_splicer.add_column("result", result))) { + LOG_WARN("fail to add column", KR(ret), K(tenant_id), K(task_id), K(new_status)); + } else if (OB_FAIL(dml_splicer.finish_row())) { + LOG_WARN("fail to finish row", KR(ret)); + } else if (OB_FAIL(dml_splicer.splice_update_sql(OB_ALL_TRANSFER_TASK_TNAME, sql))) { + LOG_WARN("fail to splice update sql", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(sql.append_fmt(" AND status='%s'", old_status.str()))) { + LOG_WARN("fail to append fmt", KR(ret), K(tenant_id), K(sql), K(old_status)); + } else if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("fail to write sql", KR(ret), K(tenant_id), K(sql), K(affected_rows)); + } else if (OB_UNLIKELY(1 != affected_rows && 0 != affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("incorrect affected rows", + KR(ret), K(tenant_id), K(affected_rows), K(sql)); + } else { + LOG_INFO("update status success", K(tenant_id), K(task_id), + K(old_status), K(new_status), K(affected_rows)); + } + } + return ret; +} + +int ObTransferTaskOperator::update_start_scn( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const share::SCN &start_scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || !task_id.is_valid() + || !old_status.is_valid() + || !start_scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), + K(tenant_id), K(task_id), K(old_status), K(start_scn)); + } else { + ObSqlString sql; + ObDMLSqlSplicer dml_splicer; + int64_t affected_rows = 0; + + if (FAILEDx(dml_splicer.add_pk_column("task_id", task_id.id())) + || OB_FAIL(dml_splicer.add_column("start_scn", start_scn.get_val_for_inner_table_field()))) { + LOG_WARN("fail to add column", KR(ret), K(tenant_id), K(task_id), K(start_scn)); + } else if (OB_FAIL(dml_splicer.finish_row())) { + LOG_WARN("fail to finish row", K(tenant_id), KR(ret)); + } else if (OB_FAIL(dml_splicer.splice_update_sql(OB_ALL_TRANSFER_TASK_TNAME, sql))) { + LOG_WARN("fail to splice update sql", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(sql.append_fmt(" AND status='%s'", old_status.str()))) { + LOG_WARN("fail to append fmt", KR(ret), K(tenant_id), K(sql), K(old_status)); + } else if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("fail to write sql", KR(ret), K(tenant_id), K(sql), K(affected_rows)); + } else if (OB_UNLIKELY(1 != affected_rows && 0 != affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("incorrect affected rows", KR(ret), K(tenant_id), K(affected_rows), K(sql)); + } else { + LOG_INFO("update start_scn success", K(tenant_id), K(task_id), + K(old_status), K(start_scn), K(affected_rows)); + } + } + return ret; +} + +int ObTransferTaskOperator::update_finish_scn( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const share::SCN &finish_scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || !task_id.is_valid() + || !old_status.is_valid() + || !finish_scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), + K(tenant_id), K(task_id), K(old_status), K(finish_scn)); + } else { + ObSqlString sql; + ObDMLSqlSplicer dml_splicer; + int64_t affected_rows = 0; + + if (FAILEDx(dml_splicer.add_pk_column("task_id", task_id.id())) + || OB_FAIL(dml_splicer.add_column("finish_scn", finish_scn.get_val_for_inner_table_field()))) { + LOG_WARN("fail to add column", KR(ret), K(tenant_id), K(task_id), K(finish_scn)); + } else if (OB_FAIL(dml_splicer.finish_row())) { + LOG_WARN("fail to finish row", K(tenant_id), KR(ret)); + } else if (OB_FAIL(dml_splicer.splice_update_sql(OB_ALL_TRANSFER_TASK_TNAME, sql))) { + LOG_WARN("fail to splice update sql", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(sql.append_fmt(" AND status='%s'", old_status.str()))) { + LOG_WARN("fail to append fmt", KR(ret), K(tenant_id), K(sql), K(old_status)); + } else if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("fail to write sql", KR(ret), K(tenant_id), K(sql), K(affected_rows)); + } else if (OB_UNLIKELY(1 != affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("incorrect affected rows", KR(ret), K(tenant_id), K(affected_rows), K(sql)); + } else { + LOG_INFO("update finish_scn success", K(tenant_id), K(task_id), + K(old_status), K(finish_scn), K(affected_rows)); + } + } + return ret; +} + +int ObTransferTaskOperator::construct_transfer_tasks_( + common::sqlclient::ObMySQLResult &res, + ObIArray &tasks) +{ + int ret = OB_SUCCESS; + tasks.reset(); + const bool with_time = false; + int64_t create_time = OB_INVALID_TIMESTAMP; // unused + int64_t finish_time = OB_INVALID_TIMESTAMP; // unused + ObTransferTask task; + while (OB_SUCC(ret)) { + task.reset(); + if (OB_FAIL(res.next())) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("get next result failed", KR(ret)); + } + } else if (OB_FAIL(parse_sql_result_(res, with_time, task, create_time, finish_time))) { + LOG_WARN("parse sql result failed", KR(ret), K(task)); + } else if (OB_FAIL(tasks.push_back(task))) { + LOG_WARN("fail to push back", KR(ret), K(task), K(tasks)); + } + } // end while + return ret; +} + +int ObTransferTaskOperator::construct_transfer_task_( + common::sqlclient::ObMySQLResult &res, + ObTransferTask &task) +{ + int ret = OB_SUCCESS; + const bool with_time = false; + int64_t create_time = OB_INVALID_TIMESTAMP; // unused + int64_t finish_time = OB_INVALID_TIMESTAMP; // unused + if (OB_FAIL(res.next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + } else { + LOG_WARN("get next result failed", KR(ret)); + } + } else if (OB_FAIL(parse_sql_result_(res, with_time, task, create_time, finish_time))) { + LOG_WARN("parse sql result failed", KR(ret), K(task)); + } else if (OB_FAIL(res.next())) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("get next result failed", KR(ret), K(task)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("read more than one row", KR(ret), K(task)); + } + return ret; +} + +int ObTransferTaskOperator::parse_sql_result_( + common::sqlclient::ObMySQLResult &res, + const bool with_time, + ObTransferTask &task, + int64_t &create_time, + int64_t &finish_time) +{ + int ret = OB_SUCCESS; + task.reset(); + create_time = OB_INVALID_TIMESTAMP; + finish_time = OB_INVALID_TIMESTAMP; + int64_t task_id = ObTransferTaskID::INVALID_ID; + int64_t src_ls = ObLSID::INVALID_LS_ID; + int64_t dest_ls = ObLSID::INVALID_LS_ID; + ObString part_list_str; + ObString not_exist_part_list_str; + ObString lock_conflict_part_list_str; + ObString table_lock_tablet_list_str; + ObString tablet_list_str; + uint64_t start_scn_val = OB_INVALID_SCN_VAL; + uint64_t finish_scn_val = OB_INVALID_SCN_VAL; + ObString status_str; + char trace_id_buf[OB_MAX_TRACE_ID_BUFFER_SIZE] = ""; + int64_t real_length = 0; + int64_t result = -1; + ObString comment; + int64_t balance_task_id = ObBalanceTaskID::INVALID_ID; + int64_t table_lock_owner_id = ObTableLockOwnerID::INVALID_ID; + ObTransferStatus status; + SCN start_scn; + SCN finish_scn; + common::ObCurTraceId::TraceId trace_id; + + if (with_time) { + (void)GET_COL_IGNORE_NULL(res.get_int, "create_time", create_time); + (void)GET_COL_IGNORE_NULL(res.get_int, "finish_time", finish_time); + } + (void)GET_COL_IGNORE_NULL(res.get_int, "task_id", task_id); + (void)GET_COL_IGNORE_NULL(res.get_int, "src_ls", src_ls); + (void)GET_COL_IGNORE_NULL(res.get_int, "dest_ls", dest_ls); + (void)GET_COL_IGNORE_NULL(res.get_varchar, "part_list", part_list_str); + (void)GET_COL_IGNORE_NULL(res.get_varchar, "not_exist_part_list", not_exist_part_list_str); + (void)GET_COL_IGNORE_NULL(res.get_varchar, "lock_conflict_part_list", lock_conflict_part_list_str); + (void)GET_COL_IGNORE_NULL(res.get_varchar, "table_lock_tablet_list", table_lock_tablet_list_str); + (void)GET_COL_IGNORE_NULL(res.get_varchar, "tablet_list", tablet_list_str); + (void)GET_COL_IGNORE_NULL(res.get_uint, "start_scn", start_scn_val); + (void)GET_COL_IGNORE_NULL(res.get_uint, "finish_scn", finish_scn_val); + (void)GET_COL_IGNORE_NULL(res.get_varchar, "status", status_str); + (void)GET_COL_IGNORE_NULL(res.get_int, "result", result); + (void)GET_COL_IGNORE_NULL(res.get_varchar, "comment", comment); + (void)GET_COL_IGNORE_NULL(res.get_int, "balance_task_id", balance_task_id); + (void)GET_COL_IGNORE_NULL(res.get_int, "table_lock_owner_id", table_lock_owner_id); + EXTRACT_STRBUF_FIELD_MYSQL(res, "trace_id", trace_id_buf, OB_MAX_TRACE_ID_BUFFER_SIZE, real_length); + + if (OB_FAIL(ret)) { + } else if (start_scn_val != OB_INVALID_SCN_VAL + && OB_FAIL(start_scn.convert_for_inner_table_field(start_scn_val))) { + LOG_WARN("fail to convert for inner table field", KR(ret), K(start_scn_val)); + } else if (finish_scn_val != OB_INVALID_SCN_VAL + && OB_FAIL(finish_scn.convert_for_inner_table_field(finish_scn_val))) { + LOG_WARN("fail to convert for inner table field", KR(ret), K(finish_scn_val)); + } else if (OB_FAIL(trace_id.parse_from_buf(trace_id_buf))) { + LOG_WARN("failed to parse trace id from buf", KR(ret), K(trace_id_buf)); + } else if (OB_FAIL(status.parse_from_str(status_str))) { + LOG_WARN("fail to parse from str", KR(ret), K(status_str)); + } else if (OB_FAIL(task.init( + ObTransferTaskID(task_id), + ObLSID(src_ls), + ObLSID(dest_ls), + part_list_str, + not_exist_part_list_str, + lock_conflict_part_list_str, + table_lock_tablet_list_str, + tablet_list_str, + start_scn, + finish_scn, + status, + trace_id, + static_cast(result), + str_to_transfer_task_comment(comment), + ObBalanceTaskID(balance_task_id), + ObTableLockOwnerID(table_lock_owner_id)))) { + LOG_WARN("fail to init transfer task", KR(ret), K(task_id), K(src_ls), K(dest_ls), K(part_list_str), + K(not_exist_part_list_str), K(lock_conflict_part_list_str), K(table_lock_tablet_list_str), K(tablet_list_str), K(start_scn), + K(finish_scn), K(status), K(trace_id), K(result), K(comment), K(balance_task_id), K(table_lock_owner_id)); + } + + return ret; +} + +int ObTransferTaskOperator::construct_task_status_( + common::sqlclient::ObMySQLResult &res, + ObIArray &task_status) +{ + int ret = OB_SUCCESS; + task_status.reset(); + ObTransferTask::TaskStatus stat; + while (OB_SUCC(ret)) { + if (OB_FAIL(res.next())) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("get next result failed", KR(ret)); + } + } else { + stat.reset(); + int64_t task_id = ObTransferTaskID::INVALID_ID; + ObString status_str; + ObTransferStatus status; + + EXTRACT_INT_FIELD_MYSQL(res, "task_id", task_id, int64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(res, "status", status_str); + + if (FAILEDx(status.parse_from_str(status_str))) { + LOG_WARN("fail to parse from str", KR(ret), K(status_str)); + } else if (OB_FAIL(stat.init(ObTransferTaskID(task_id), status))) { + LOG_WARN("fail to init transfer task", KR(ret), K(task_id), K(status)); + } else if (OB_FAIL(task_status.push_back(stat))) { + LOG_WARN("fail to push back", KR(ret), K(stat), K(task_status)); + } + } + } // end while + return ret; +} + +int ObTransferTaskOperator::insert_history( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTask &task, + const int64_t create_time, + const int64_t finish_time) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || !task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task)); + } else { + ObSqlString sql; + ObDMLSqlSplicer dml_splicer; + int64_t affected_rows = 0; + ObArenaAllocator allocator; + + if (OB_FAIL(fill_dml_splicer_(dml_splicer, allocator, task))) { + LOG_WARN("fail to fill dml splicer", KR(ret), K(tenant_id), K(task)); + } else if (OB_FAIL(dml_splicer.add_time_column("create_time", create_time)) + || OB_FAIL(dml_splicer.add_time_column("finish_time", finish_time))) { + LOG_WARN("fail to add column", KR(ret), K(tenant_id), K(task), K(create_time), K(finish_time)); + } else if (OB_FAIL(dml_splicer.finish_row())) { + LOG_WARN("fail to finish row", KR(ret), K(tenant_id), K(task), K(create_time), K(finish_time)); + } else if (OB_FAIL(dml_splicer.splice_insert_sql(OB_ALL_TRANSFER_TASK_HISTORY_TNAME, sql))) { + LOG_WARN("fail to splice insert sql", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + if (OB_ERR_PRIMARY_KEY_DUPLICATE == ret) { + ret = OB_ENTRY_EXIST; + } + LOG_WARN("fail to write sql", KR(ret), K(tenant_id), K(sql), K(affected_rows), K(task)); + } else { + LOG_INFO("insert transfer task history success", + K(tenant_id), K(affected_rows), K(task), K(create_time), K(finish_time)); + } + } + return ret; +} + +int ObTransferTaskOperator::get_history_task( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + ObTransferTask &task, + int64_t &create_time, + int64_t &finish_time) +{ + int ret = OB_SUCCESS; + task.reset(); + create_time = OB_INVALID_TIMESTAMP; + finish_time = OB_INVALID_TIMESTAMP; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || !task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task_id)); + } else { + SMART_VAR(ObISQLClient::ReadResult, result) { + ObSqlString sql; + bool with_time = true; + common::sqlclient::ObMySQLResult *res = NULL; + if (OB_FAIL(sql.assign_fmt("SELECT time_to_usec(gmt_create) AS create_time, " + "time_to_usec(gmt_modified) AS finish_time, * FROM %s WHERE task_id = %ld", + OB_ALL_TRANSFER_TASK_HISTORY_TNAME, task_id.id()))) { + LOG_WARN("fail to assign sql", KR(ret), K(task_id)); + } else if (OB_FAIL(sql_proxy.read(result, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(res = result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(res->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("task not found", KR(ret), K(tenant_id), K(task_id)); + } else { + LOG_WARN("next failed", KR(ret), K(sql)); + } + } else if (OB_FAIL(parse_sql_result_(*res, with_time, task, create_time, finish_time))) { + LOG_WARN("parse sql result failed", KR(ret)); + } else { + LOG_TRACE("get history task status success", KR(ret), K(tenant_id), K(task_id), K(task)); + } + } + } + return ret; +} + +int ObTransferTaskOperator::update_comment( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferTaskComment &comment) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || !task_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(task_id), K(comment)); + } else { + ObSqlString sql; + ObDMLSqlSplicer dml_splicer; + int64_t affected_rows = 0; + + if (OB_FAIL(dml_splicer.add_pk_column("task_id", task_id.id())) + || OB_FAIL(dml_splicer.add_column("comment", transfer_task_comment_to_str(comment)))) { + LOG_WARN("fail to add column", KR(ret), K(tenant_id), K(task_id), K(comment)); + } else if (OB_FAIL(dml_splicer.finish_row())) { + LOG_WARN("fail to finish row", K(tenant_id), KR(ret)); + } else if (OB_FAIL(dml_splicer.splice_update_sql(OB_ALL_TRANSFER_TASK_TNAME, sql))) { + LOG_WARN("fail to splice update sql", KR(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(sql_proxy.write(tenant_id, sql.ptr(), affected_rows))) { + LOG_WARN("fail to write sql", KR(ret), K(tenant_id), K(sql), K(affected_rows)); + } else if (OB_UNLIKELY(1 != affected_rows && 0 != affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("incorrect affected rows", KR(ret), K(tenant_id), K(affected_rows), K(sql)); + } else { + LOG_INFO("update comment successfully", K(tenant_id), K(task_id), K(comment), K(affected_rows)); + } + } + return ret; +} + +} // end namespace share +} // end namespace oceanbase diff --git a/src/share/transfer/ob_transfer_task_operator.h b/src/share/transfer/ob_transfer_task_operator.h new file mode 100644 index 000000000..46213322b --- /dev/null +++ b/src/share/transfer/ob_transfer_task_operator.h @@ -0,0 +1,401 @@ +/** + * 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_OB_TRANSFER_TASK_OPERATOR +#define OCEANBASE_SHARE_OB_TRANSFER_TASK_OPERATOR + +#include "share/transfer/ob_transfer_info.h" + +namespace oceanbase +{ +namespace common +{ +class ObISQLClient; + +namespace sqlclient +{ +class ObMySQLResult; +} +} + +namespace share +{ +class ObDMLSqlSplicer; + +// operator for __all_transfer_task +class ObTransferTaskOperator final +{ +public: + ObTransferTaskOperator() {}; + virtual ~ObTransferTaskOperator() {}; + + /* + * get a transfer task by task_id + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: target task_id + * @param [in] for_update: select for update + * @param [out] task: transfer task + * @return + * - OB_ENTRY_NOT_EXIST: not found + * - OB_SUCCESS: successful + * - other: failed + */ + static int get( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const bool for_update, + ObTransferTask &task); + + /* + * get a transfer task by task_id with create_time and finish_time + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: target task_id + * @param [in] for_update: select for update + * @param [out] task: transfer task + * @param [out] create_time: transfer task create timestamp + * @param [out] finish_time: transfer task finish timestamp + * @return + * - OB_ENTRY_NOT_EXIST: not found + * - OB_SUCCESS: successful + * - other: failed + */ + static int get_task_with_time( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const bool for_update, + ObTransferTask &task, + int64_t &create_time, + int64_t &finish_time); + + /* + * get transfer tasks by status + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] status: transfer status + * @param [out] tasks: transfer tasks array + * @return + * - OB_ENTRY_NOT_EXIST: not found + * - OB_SUCCESS: successful + * - other: failed + */ + static int get_by_status( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferStatus &status, + common::ObIArray &tasks); + + /* + * get all task status + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [out] task_status: array of task status + * @return + * - OB_ENTRY_NOT_EXIST: not found + * - OB_SUCCESS: successful + * - other: failed + */ + static int get_all_task_status( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + common::ObIArray &task_status); + + /* + * get transfer task by dest ls (there is no more than 1 transfer task on a ls) + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] dest_ls: destination ls_id + * @param [out] task: transfer task + * @return + * - OB_ENTRY_NOT_EXIST: not found + * - OB_ERR_UNEXPECTED: more than 1 transfer task on a ls + * - OB_SUCCESS: successful + * - other: failed + */ + static int get_by_dest_ls( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObLSID &dest_ls, + ObTransferTask &task); + + /* + * insert task + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task: transfer task + * @return + * - OB_ENTRY_EXIST: duplicate insert + * - OB_SUCCESS: successful + * - other: failed + */ + static int insert( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTask &task); + + /* + * update transfer task from INIT to START + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: target task_id + * @param [in] old_status: old task status + * @param [in] new_part_list: part_list of start status transfer task + * @param [in] new_not_exist_part_list: partitions that not exist + * @param [in] new_lock_conflict_part_list: partitions that are in conflict when adding table lock or online ddl lock + * @param [in] new_table_lock_tablet_list: tablet list which add table lock successfully + * @param [in] new_tablet_list: new tablet_list + * @param [in] new_status: new task status + * @return + * - OB_STATE_NOT_MATCH: task not found or task status mismatch + * - OB_SUCCESS: successful + * - other: failed + */ + static int update_to_start_status( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const ObTransferPartList &new_part_list, + const ObTransferPartList &new_not_exist_part_list, + const ObTransferPartList &new_lock_conflict_part_list, + const ObDisplayTabletList &new_table_lock_tablet_list, + const ObTransferTabletList &new_tablet_list, + const ObTransferStatus &new_status, + const transaction::tablelock::ObTableLockOwnerID &table_lock_owner_id); + + /* + * finish task and update status to CANCELED/FAILED/COMPLETED + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: target task_id + * @param [in] old_status: old task status + * @param [in] new_status: new task status + * @param [in] result: return code for the transfer process + * @param [in] comment: information for task finish + * @return + * - OB_STATE_NOT_MATCH: task not found or task status mismatch + * - OB_SUCCESS: successful + * - other: failed + */ + static int finish_task( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const ObTransferStatus &new_status, + const int result, + const ObTransferTaskComment &comment); + + /* + * finish task from INIT status to COMPLETED when part_list is all unreachable + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: target task_id + * @param [in] old_status: old task status + * @param [in] new_part_list: part_list of the finished task + * @param [in] new_not_exist_part_list: partitions that not exist + * @param [in] new_lock_conflict_part_list: partitions that are in conflict when adding table lock or online ddl lock + * @param [in] new_status: new task status + * @param [in] result: return code for the transfer process + * @param [in] comment: information for task finish + * @return + * - OB_STATE_NOT_MATCH: task not found or task status mismatch + * - OB_SUCCESS: successful + * - other: failed + */ + static int finish_task_from_init( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const ObTransferPartList &new_part_list, + const ObTransferPartList &new_not_exist_part_list, + const ObTransferPartList &new_lock_conflict_part_list, + const ObTransferStatus &new_status, + const int result, + const ObTransferTaskComment &comment); + + /* + * remove task + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: target task_id + * @return + * - OB_ENTRY_NOT_EXIST: not found + * - OB_SUCCESS: successful + * - other: failed + */ + static int remove( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id); + + /* + * update task status and result + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: target task_id + * @param [in] old_status: old task status + * @param [in] new_status: new task status + * @param [in] result: task result + * @return + * - OB_STATE_NOT_MATCH: task not found or task status mismatch + * - OB_SUCCESS: successful + * - other: failed + */ + static int update_status_and_result( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const ObTransferStatus &new_status, + const int result); + + + /* + * update start_scn + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: target task_id + * @param [in] old_status: old task status + * @param [in] start_scn: start scn + * @return + * - OB_STATE_NOT_MATCH: task not found or task status mismatch + * - OB_SUCCESS: successful + * - other: failed + */ + static int update_start_scn( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferStatus &old_status, + const share::SCN &start_scn); + + /* + * update finish_scn + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: target task_id + * @param [in] old_status: old task status + * @param [in] finish_scn: finish scn + * @return + * - OB_STATE_NOT_MATCH: task not found or task status mismatch + * - OB_SUCCESS: successful + * - other: failed + */ + static int update_finish_scn( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID, + const ObTransferStatus &old_status, + const share::SCN &finish_scn); + + /* + * record transfer task in __all_transfer_task_history + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task: transfer task + * @param [in] create_time: transfer task create timestamp + * @param [in] finish_time: transfer task finish timestamp + * @return + * - OB_ENTRY_EXIST: duplicate insert + * - OB_SUCCESS: successful + * - other: failed + */ + static int insert_history( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTask &task, + const int64_t create_time, + const int64_t finish_time); + + /* + * get transfer task from __all_transfer_task_history + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: transfer task id + * @param [out] task: transfer task recorded in __all_transfer_task_history + * @param [out] create_time: create time of the transfer task + * @param [out] finish_time: finish time of the transfer task + * @return + * - OB_ENTRY_NOT_EXIST: not found + * - OB_SUCCESS: successful + * - other: failed + */ + static int get_history_task( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + ObTransferTask &task, + int64_t &create_time, + int64_t &finish_time); + + /* + * update comment in __all_transfer_task according to task_id + * + * @param [in] sql_proxy: sql client + * @param [in] tenant_id: target tenant_id + * @param [in] task_id: transfer task id + * @param [in] comment: comment for the task + * @return + * - OB_SUCCESS: successful + * - other: failed + */ + static int update_comment( + common::ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const ObTransferTaskID task_id, + const ObTransferTaskComment &comment); + +private: + static int construct_transfer_tasks_( + common::sqlclient::ObMySQLResult &res, + common::ObIArray &tasks); + static int construct_transfer_task_( + common::sqlclient::ObMySQLResult &res, + ObTransferTask &task); + static int parse_sql_result_( + common::sqlclient::ObMySQLResult &res, + const bool with_time, + ObTransferTask &task, + int64_t &create_time, + int64_t &finish_time); + static int construct_task_status_( + common::sqlclient::ObMySQLResult &res, + common::ObIArray &task_status); + static int fill_dml_splicer_( + ObDMLSqlSplicer &dml_splicer, + common::ObArenaAllocator &allocator, + const ObTransferTask &task); +}; + +} // end namespace share +} // end namespace oceanbase +#endif diff --git a/src/share/unit/ob_unit_info.cpp b/src/share/unit/ob_unit_info.cpp index b4c314785..5f48242c8 100644 --- a/src/share/unit/ob_unit_info.cpp +++ b/src/share/unit/ob_unit_info.cpp @@ -9,7 +9,7 @@ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ - +#define USING_LOG_PREFIX SHARE #include #include "ob_unit_info.h" @@ -24,6 +24,22 @@ const char *const ObUnit::unit_status_strings[ObUnit::UNIT_STATUS_MAX] = { "DELETING", }; +ObUnit::Status ObUnit::str_to_unit_status(const ObString &str) +{ + ObUnit::Status unit_status = UNIT_STATUS_MAX; + if (str.empty()) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "str is empty", K(str)); + } else { + for (int64_t i = 0; i < ARRAYSIZEOF(unit_status_strings); ++i) { + if (0 == str.case_compare(unit_status_strings[i])) { + unit_status = static_cast(i); + break; + } + } + } + return unit_status; +} + ObUnit::ObUnit() { reset(); diff --git a/src/share/unit/ob_unit_info.h b/src/share/unit/ob_unit_info.h index e8178ffdc..84db6cfd0 100644 --- a/src/share/unit/ob_unit_info.h +++ b/src/share/unit/ob_unit_info.h @@ -37,6 +37,7 @@ public: }; public: static const char *const unit_status_strings[UNIT_STATUS_MAX]; + static Status str_to_unit_status(const ObString &str); public: ObUnit(); ~ObUnit() {} @@ -88,6 +89,34 @@ private: DISALLOW_COPY_AND_ASSIGN(ObUnitInfo); }; +struct ObSimpleUnitGroup +{ +public: + ObSimpleUnitGroup(uint64_t unit_group_id, ObUnit::Status status) : unit_group_id_(unit_group_id), status_(status) {} + ObSimpleUnitGroup(){reset();} + ~ObSimpleUnitGroup() {} + void reset() + { + unit_group_id_ = OB_INVALID_ID; + status_ = ObUnit::UNIT_STATUS_MAX; + } + bool is_valid() const; + int assign(const ObSimpleUnitGroup &other) + { + unit_group_id_ = other.unit_group_id_; + status_ = other.status_; + return OB_SUCCESS; + } + bool is_active() const + { return ObUnit::UNIT_STATUS_ACTIVE == status_; } + uint64_t get_unit_group_id() const { return unit_group_id_; } + ObUnit::Status get_status() const { return status_; } + TO_STRING_KV(K_(unit_group_id), K_(status)); +private: + uint64_t unit_group_id_; + ObUnit::Status status_; +}; + }//end namespace share }//end namespace oceanbase diff --git a/src/sql/das/ob_das_context.cpp b/src/sql/das/ob_das_context.cpp index 7a3868714..78b62d098 100644 --- a/src/sql/das/ob_das_context.cpp +++ b/src/sql/das/ob_das_context.cpp @@ -443,31 +443,6 @@ int ObDASCtx::add_candi_table_loc(const ObDASTableLocMeta &loc_meta, return ret; } -bool ObDASCtx::has_same_lsid(ObLSID *lsid) -{ - bool bret = true; - ObLSID first_lsid; - FOREACH_X(table_node, table_locs_, bret) { - ObDASTableLoc *table_loc = *table_node; - for (DASTabletLocListIter tablet_node = table_loc->tablet_locs_begin(); - bret && tablet_node != table_loc->tablet_locs_end(); ++tablet_node) { - ObDASTabletLoc *tablet_loc = *tablet_node; - if (!first_lsid.is_valid()) { - first_lsid = tablet_loc->ls_id_; - } else if (first_lsid != tablet_loc->ls_id_) { - bret = false; - } - } - } - if (!first_lsid.is_valid()) { - bret = false; - } - if (bret && lsid != nullptr) { - *lsid = first_lsid; - } - return bret; -} - int ObDASCtx::get_all_lsid(share::ObLSArray &ls_ids) { int ret = OB_SUCCESS; diff --git a/src/sql/das/ob_das_context.h b/src/sql/das/ob_das_context.h index b0987b3fa..09025168d 100644 --- a/src/sql/das/ob_das_context.h +++ b/src/sql/das/ob_das_context.h @@ -70,6 +70,7 @@ public: ObDASTableLoc *get_table_loc_by_id(uint64_t table_loc_id, uint64_t ref_table_id); ObDASTableLoc *get_external_table_loc_by_id(uint64_t table_loc_id, uint64_t ref_table_id); DASTableLocList &get_table_loc_list() { return table_locs_; } + const DASTableLocList &get_table_loc_list() const { return table_locs_; } DASDelCtxList& get_das_del_ctx_list() {return del_ctx_list_;} DASTableLocList &get_external_table_loc_list() { return external_table_locs_; } int extended_tablet_loc(ObDASTableLoc &table_loc, @@ -85,7 +86,6 @@ public: int get_das_tablet_mapper(const uint64_t ref_table_id, ObDASTabletMapper &tablet_mapper, const DASTableIDArrayWrap *related_table_ids = nullptr); - bool has_same_lsid(share::ObLSID *lsid); int get_all_lsid(share::ObLSArray &ls_ids); int64_t get_related_tablet_cnt() const; void set_snapshot(const transaction::ObTxReadSnapshot &snapshot) { snapshot_ = snapshot; } diff --git a/src/sql/das/ob_das_location_router.cpp b/src/sql/das/ob_das_location_router.cpp old mode 100644 new mode 100755 index 3bbc86654..ce51839f7 --- a/src/sql/das/ob_das_location_router.cpp +++ b/src/sql/das/ob_das_location_router.cpp @@ -1147,9 +1147,27 @@ void ObDASLocationRouter::refresh_location_cache(bool is_nonblock, int err_no) || is_partition_change_error(err_no) || is_get_location_timeout_error(err_no) || is_server_down_error(err_no)) { - FOREACH(tmp_node, all_tablet_list_) { - ObTabletID tablet_id = *tmp_node; - refresh_location_cache(tablet_id, is_nonblock, err_no); + // Refresh tablet ls mapping and ls locations according to err_no. + // + // The timeout has been set inner the interface when renewing location synchronously. + // It will use the timeout of ObTimeoutCtx or THIS_WORKER if it has been set. + // Otherwise it uses GCONF.location_cache_refresh_sql_timeout. + // Timeout usage priority: ObTimeoutCtx > THIS_WORKER > GCONF + // + // all_tablet_list_ may contain duplicate tablet_id + int ret = OB_SUCCESS; + if (OB_ISNULL(GCTX.location_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("GCTX.location_service_ is null", KR(ret)); + } else if (OB_FAIL(GCTX.location_service_->batch_renew_tablet_locations( + MTL_ID(), + all_tablet_list_, + err_no, + is_nonblock))) { + LOG_WARN("batch renew tablet locations failed", KR(ret), + "tenant_id", MTL_ID(), K(err_no), K(is_nonblock), K_(all_tablet_list)); + } else { + LOG_INFO("LOCATION: refresh tablet location cache succ", K(err_no), K_(all_tablet_list)); } all_tablet_list_.clear(); } @@ -1161,19 +1179,22 @@ void ObDASLocationRouter::refresh_location_cache(const ObTabletID &tablet_id, int err_no) { int ret = OB_SUCCESS; - //try to refresh all tablet id, and ignore the tmp error - //all_tablet_list_ may contain duplicate tablet_id - if (is_nonblock) { - if (OB_FAIL(GCTX.location_service_->nonblock_renew(MTL_ID(), tablet_id))) { - LOG_WARN("LOCATION: fail to nonblock renew location cache", K(ret), K(tablet_id)); - } else { - LOG_INFO("LOCATION: nonblock renew success", K(tablet_id), K(err_no)); - } + // Refresh tablet ls mapping and ls location according to err_no. + // + // The timeout has been set inner the interface when renewing location synchronously. + // Timeout usage priority: ObTimeoutCtx > THIS_WORKER > GCONF.location_cache_refresh_sql_timeout. + if (OB_ISNULL(GCTX.location_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("GCTX.location_service_ is null", KR(ret)); + } else if (OB_FAIL(GCTX.location_service_->renew_tablet_location( + MTL_ID(), + tablet_id, + err_no, + is_nonblock))) { + LOG_WARN("renew tablet location failed", KR(ret), + "tenant_id", MTL_ID(), K(tablet_id), K(err_no), K(is_nonblock)); } else { - ObLSLocation dummy_loc; - if (OB_FAIL(block_renew_tablet_location(tablet_id, dummy_loc))) { - LOG_WARN("fail to renew tablet location", K(ret), K(tablet_id)); - } + LOG_INFO("LOCATION: refresh tablet location cache succ", K(err_no), K(tablet_id)); } } diff --git a/src/sql/engine/cmd/ob_alter_system_executor.cpp b/src/sql/engine/cmd/ob_alter_system_executor.cpp index 36da8868c..d18a64248 100644 --- a/src/sql/engine/cmd/ob_alter_system_executor.cpp +++ b/src/sql/engine/cmd/ob_alter_system_executor.cpp @@ -542,7 +542,7 @@ int ObFlushDagWarningsExecutor::execute(ObExecContext &ctx, ObFlushDagWarningsSt ret = OB_NOT_INIT; LOG_WARN("get task exec ctx error", K(ret), KP(task_exec_ctx)); } else { - share::ObDagWarningHistoryManager::get_instance().clear(); + MTL(ObDagWarningHistoryManager *)->clear(); } return ret; } @@ -2416,7 +2416,6 @@ int ObCheckpointSlogExecutor::execute(ObExecContext &ctx, ObCheckpointSlogStmt & obrpc::ObSrvRpcProxy *srv_rpc_proxy = NULL; const ObAddr server = stmt.server_; ObCheckpointSlogArg arg; - const int64_t TIMEOUT = 60 * 1000 * 1000; // 60s arg.tenant_id_ = stmt.tenant_id_; if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) { @@ -2425,7 +2424,7 @@ int ObCheckpointSlogExecutor::execute(ObExecContext &ctx, ObCheckpointSlogStmt & } else if (OB_ISNULL(srv_rpc_proxy = task_exec_ctx->get_srv_rpc())) { ret = OB_NOT_INIT; LOG_WARN("get srv rpc proxy failed"); - } else if (OB_FAIL(srv_rpc_proxy->to(server).timeout(TIMEOUT).checkpoint_slog(arg))) { + } else if (OB_FAIL(srv_rpc_proxy->to(server).timeout(THIS_WORKER.get_timeout_remain()).checkpoint_slog(arg))) { LOG_WARN("rpc proxy checkpoint slog failed", K(ret)); } @@ -2434,6 +2433,39 @@ int ObCheckpointSlogExecutor::execute(ObExecContext &ctx, ObCheckpointSlogStmt & return ret; } +int ObCancelRestoreExecutor::execute(ObExecContext &ctx, ObCancelRestoreStmt &stmt) +{ + int ret = OB_SUCCESS; + ObTaskExecutorCtx *task_exec_ctx = nullptr; + obrpc::ObCommonRpcProxy *common_rpc_proxy = nullptr; + ObSchemaGetterGuard guard; + const ObTenantSchema *tenant_schema = nullptr; + if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task exec ctx must not be null", K(ret)); + } else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("common rpc proxy must not be null", K(ret)); + } else if (OB_FAIL(GSCHEMASERVICE.get_tenant_schema_guard(OB_SYS_TENANT_ID, guard))) { + LOG_WARN("failed to get sys tenant schema guard", K(ret)); + } else if (OB_FAIL(guard.get_tenant_info(stmt.get_drop_tenant_arg().tenant_name_, tenant_schema))) { + LOG_WARN("failed to get tenant info", K(ret), K(stmt)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_USER_ERROR(OB_TENANT_NOT_EXIST, stmt.get_drop_tenant_arg().tenant_name_.length(), stmt.get_drop_tenant_arg().tenant_name_.ptr()); + LOG_WARN("tenant not exist", KR(ret), K(stmt)); + } else if (!tenant_schema->is_restore()) { + ret = OB_OP_NOT_ALLOW; + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "Cancel tenant not in restore is"); + LOG_WARN("Cancel tenant not in restore is not allowed", K(ret), K(stmt.get_drop_tenant_arg())); + } else if (OB_FAIL(common_rpc_proxy->drop_tenant(stmt.get_drop_tenant_arg()))) { + LOG_WARN("rpc proxy drop tenant failed", K(ret)); + } else { + LOG_INFO("[RESTORE]succeed to cancel restore tenant", K(stmt)); + } + return ret; +} + } // end namespace sql } // end namespace oceanbase diff --git a/src/sql/engine/cmd/ob_alter_system_executor.h b/src/sql/engine/cmd/ob_alter_system_executor.h index b000bf9bb..76b6462e0 100644 --- a/src/sql/engine/cmd/ob_alter_system_executor.h +++ b/src/sql/engine/cmd/ob_alter_system_executor.h @@ -117,6 +117,7 @@ DEF_SIMPLE_EXECUTOR(ObDropDisk); DEF_SIMPLE_EXECUTOR(ObArchiveLog); DEF_SIMPLE_EXECUTOR(ObBackupDatabase); +DEF_SIMPLE_EXECUTOR(ObCancelRestore); DEF_SIMPLE_EXECUTOR(ObBackupManage); DEF_SIMPLE_EXECUTOR(ObBackupClean); DEF_SIMPLE_EXECUTOR(ObDeletePolicy); diff --git a/src/sql/engine/cmd/ob_tablegroup_executor.cpp b/src/sql/engine/cmd/ob_tablegroup_executor.cpp index 6ad1c0336..c148265a9 100644 --- a/src/sql/engine/cmd/ob_tablegroup_executor.cpp +++ b/src/sql/engine/cmd/ob_tablegroup_executor.cpp @@ -114,8 +114,6 @@ int ObAlterTablegroupExecutor::execute(ObExecContext &ctx, ObAlterTablegroupStmt const_cast(alter_tablegroup_arg).ddl_stmt_str_ = first_stmt; } if (OB_FAIL(ret)) { - } else if (OB_FAIL(check_alter_partition(ctx, stmt, alter_tablegroup_arg))) { - LOG_WARN("check alter partition failed", K(ret)); } else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) { ret = OB_NOT_INIT; LOG_WARN("get task executor context failed"); @@ -129,75 +127,5 @@ int ObAlterTablegroupExecutor::execute(ObExecContext &ctx, ObAlterTablegroupStmt } return ret; } - -int ObAlterTablegroupExecutor::check_alter_partition(ObExecContext &ctx, - ObAlterTablegroupStmt &stmt, - const obrpc::ObAlterTablegroupArg &arg) -{ - int ret = OB_SUCCESS; - if (arg.is_alter_partitions()) { - const ObTablegroupSchema &tablegroup_schema = arg.alter_tablegroup_schema_; - if (arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::ADD_PARTITION) - || arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::PARTITIONED_TABLE) - || arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::REORGANIZE_PARTITION) - || arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::SPLIT_PARTITION)) { - ObPartition **partition_array = tablegroup_schema.get_part_array(); - int64_t real_part_num = tablegroup_schema.get_partition_num(); - const int64_t fun_expr_num = stmt.get_part_func_expr_num(); - if (arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::SPLIT_PARTITION)) { - real_part_num = tablegroup_schema.get_part_option().get_part_num(); - } - if (tablegroup_schema.is_range_part()) { - ObSEArray range_partition_obj; - ObIArray &range_values_exprs = stmt.get_part_values_exprs(); - if (OB_ISNULL(partition_array)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition_array is NULL", K(ret)); - } else if (OB_FAIL(ObPartitionExecutorUtils::cast_range_expr_to_obj( - ctx, - range_values_exprs, - fun_expr_num, - stmt::T_ALTER_TABLEGROUP, - false, //is_subpart - real_part_num, - partition_array, - NULL, - range_partition_obj))) { - LOG_WARN("partition_array is NULL", K(ret)); - } - } else if (tablegroup_schema.is_list_part()) { - if (OB_ISNULL(partition_array)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition_array is NULL", K(ret)); - } else if (OB_FAIL(ObPartitionExecutorUtils::cast_list_expr_to_obj(ctx, - stmt, - false, - partition_array, - NULL))) { - LOG_WARN("failed cast list to expr", K(ret)); - } - } else if (!arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::PARTITIONED_TABLE)) { - ret = OB_ERR_ONLY_ON_RANGE_LIST_PARTITION; - LOG_WARN("unexpected partition type", K(ret), - "partition type", tablegroup_schema.get_part_option().get_part_func_type()); - } - if (OB_FAIL(ret)) { - } else if (arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::SPLIT_PARTITION)) { - //由于split在不引起二义性的情况下,可以不指定high_value,part_num需要和实际range_value_expr对应 - //在解析完成后可以置为正确的partition_num - const_cast(tablegroup_schema).get_part_option().set_part_num( - tablegroup_schema.get_partition_num()); - } - } else if (arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::DROP_PARTITION)) { - // do-nothing - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("no operation", K(arg), K(ret)); - } - LOG_DEBUG("dump table schema", K(tablegroup_schema)); - } - - return ret; -} } // namespace sql } // namespace oceanbase diff --git a/src/sql/engine/cmd/ob_tablegroup_executor.h b/src/sql/engine/cmd/ob_tablegroup_executor.h index e1c639796..b02def12b 100644 --- a/src/sql/engine/cmd/ob_tablegroup_executor.h +++ b/src/sql/engine/cmd/ob_tablegroup_executor.h @@ -56,9 +56,6 @@ public: virtual ~ObAlterTablegroupExecutor() {} int execute(ObExecContext &ctx, ObAlterTablegroupStmt &stmt); private: - int check_alter_partition(ObExecContext &ctx, - ObAlterTablegroupStmt &stmt, - const obrpc::ObAlterTablegroupArg &arg); DISALLOW_COPY_AND_ASSIGN(ObAlterTablegroupExecutor); }; diff --git a/src/sql/engine/table/ob_table_scan_op.cpp b/src/sql/engine/table/ob_table_scan_op.cpp index 290afc5e5..9998c64fb 100644 --- a/src/sql/engine/table/ob_table_scan_op.cpp +++ b/src/sql/engine/table/ob_table_scan_op.cpp @@ -2498,10 +2498,13 @@ int ObTableScanOp::init_ddl_column_checksum() column_checksum_.set_allocator(&ctx_.get_allocator()); col_need_reshape_.set_allocator(&ctx_.get_allocator()); const ObSQLSessionInfo *session = nullptr; - const ObIArray &cols = MY_CTDEF.scan_ctdef_.table_param_.get_read_info().get_columns(); + const ObIArray *cols = MY_CTDEF.scan_ctdef_.table_param_.get_read_info().get_columns(); if (OB_ISNULL(session = ctx_.get_my_session())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid session", K(ret)); + } else if (OB_ISNULL(cols)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("col param array is unexpected null", K(ret),KP(cols)); } else if (MY_SPEC.output_.count() != MY_SPEC.ddl_output_cids_.count()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), K(MY_SPEC.output_), K(MY_CTDEF.scan_ctdef_.table_param_), K(MY_SPEC.ddl_output_cids_)); @@ -2518,8 +2521,8 @@ int ObTableScanOp::init_ddl_column_checksum() for (int64_t i = 0; OB_SUCC(ret) && i < MY_SPEC.ddl_output_cids_.count(); ++i) { bool found = false; bool need_reshape = false; - for (int64_t j = 0; OB_SUCC(ret) && !found && j < cols.count(); ++j) { - const ObColumnParam *col_param = cols.at(j); + for (int64_t j = 0; OB_SUCC(ret) && !found && j < cols->count(); ++j) { + const ObColumnParam *col_param = cols->at(j); if (OB_ISNULL(col_param)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid col param", K(ret)); diff --git a/src/sql/executor/ob_cmd_executor.cpp b/src/sql/executor/ob_cmd_executor.cpp index c0d005356..3edb96fdb 100644 --- a/src/sql/executor/ob_cmd_executor.cpp +++ b/src/sql/executor/ob_cmd_executor.cpp @@ -850,6 +850,10 @@ int ObCmdExecutor::execute(ObExecContext &ctx, ObICmd &cmd) DEFINE_EXECUTE_CMD(ObBackupDatabaseStmt, ObBackupDatabaseExecutor); break; } + case stmt::T_CANCEL_RESTORE: { + DEFINE_EXECUTE_CMD(ObCancelRestoreStmt, ObCancelRestoreExecutor); + break; + } case stmt::T_BACKUP_MANAGE: { DEFINE_EXECUTE_CMD(ObBackupManageStmt, ObBackupManageExecutor); break; diff --git a/src/sql/ob_sql_trans_control.cpp b/src/sql/ob_sql_trans_control.cpp index 20a2ab24f..b0aa68f14 100644 --- a/src/sql/ob_sql_trans_control.cpp +++ b/src/sql/ob_sql_trans_control.cpp @@ -37,6 +37,8 @@ #include "observer/ob_server.h" #include "storage/tx/wrs/ob_weak_read_util.h" //ObWeakReadUtil #include "storage/tx_storage/ob_ls_service.h" +#include "storage/ls/ob_ls_get_mod.h" +#include "storage/tablet/ob_tablet.h" #include "sql/das/ob_das_dml_ctx_define.h" #include "share/deadlock/ob_deadlock_detector_mgr.h" @@ -675,24 +677,32 @@ int ObSqlTransControl::stmt_setup_snapshot_(ObSQLSessionInfo *session, } else { auto &tx_desc = *session->get_tx_desc(); int64_t stmt_expire_ts = get_stmt_expire_ts(plan_ctx, *session); - share::ObLSID local_ls_id; - bool local_single_ls_plan = plan->is_local_plan() - && OB_PHY_PLAN_LOCAL == plan->get_location_type() - && das_ctx.has_same_lsid(&local_ls_id); - if (local_single_ls_plan) { - ret = txs->get_ls_read_snapshot(tx_desc, - session->get_tx_isolation(), - local_ls_id, - stmt_expire_ts, - snapshot); - } else { + share::ObLSID first_ls_id; + bool local_single_ls_plan = false; + const bool local_single_ls_plan_maybe = plan->is_local_plan() && + OB_PHY_PLAN_LOCAL == plan->get_location_type() && + !tx_desc.is_can_elr(); + if (local_single_ls_plan_maybe) { + if (OB_FAIL(get_first_lsid(das_ctx, first_ls_id))) { + } else if (!first_ls_id.is_valid()) { + // do nothing + } else if (OB_FAIL(txs->get_ls_read_snapshot(tx_desc, + session->get_tx_isolation(), + first_ls_id, + stmt_expire_ts, + snapshot))) { + } else { + local_single_ls_plan = has_same_lsid(das_ctx, snapshot.core_.version_, first_ls_id); + } + } + if (OB_SUCC(ret) && !local_single_ls_plan) { ret = txs->get_read_snapshot(tx_desc, session->get_tx_isolation(), stmt_expire_ts, snapshot); } if (OB_FAIL(ret)) { - LOG_WARN("fail to get snapshot", K(ret), K(local_ls_id), KPC(session)); + LOG_WARN("fail to get snapshot", K(ret), K(local_single_ls_plan), K(first_ls_id), KPC(session)); } } return ret; @@ -767,6 +777,76 @@ uint32_t ObSqlTransControl::get_real_session_id(ObSQLSessionInfo &session) return session.get_xid().empty() ? 0 : (session.get_proxy_sessid() != 0 ? session.get_proxy_sessid() : session.get_sessid()); } +int ObSqlTransControl::get_first_lsid(const ObDASCtx &das_ctx, share::ObLSID &first_lsid) +{ + int ret = OB_SUCCESS; + const DASTableLocList &table_locs = das_ctx.get_table_loc_list(); + if (!table_locs.empty()) { + const ObDASTableLoc *first_table_loc = table_locs.get_first(); + const DASTabletLocList &tablet_locs = first_table_loc->get_tablet_locs(); + if (!tablet_locs.empty()) { + const ObDASTabletLoc *tablet_loc = tablet_locs.get_first(); + first_lsid = tablet_loc->ls_id_; + } + } + return ret; +} + +bool ObSqlTransControl::has_same_lsid(const ObDASCtx &das_ctx, + const share::SCN &snapshot_version, + share::ObLSID &first_lsid) +{ + int ret = OB_SUCCESS; + bool bret = true; + ObLSHandle ls_handle; + const DASTableLocList &table_locs = das_ctx.get_table_loc_list(); + FOREACH_X(table_node, table_locs, bret) { + ObDASTableLoc *table_loc = *table_node; + for (DASTabletLocListIter tablet_node = table_loc->tablet_locs_begin(); + bret && tablet_node != table_loc->tablet_locs_end(); ++tablet_node) { + ObDASTabletLoc *tablet_loc = *tablet_node; + const ObTabletID tablet_id = tablet_loc->tablet_id_; + if (first_lsid != tablet_loc->ls_id_) { + bret = false; + } + if (bret && !ls_handle.is_valid()) { + ObLSService *ls_svr = NULL; + if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + bret = false; + } else if (OB_FAIL(ls_svr->get_ls(first_lsid, ls_handle, ObLSGetMod::TRANS_MOD))) { + bret = false; + } else { + // do nothing + } + } + if (bret) { + ObLS *ls = NULL; + ObLSTabletService *ls_tablet_service = NULL; + if (OB_ISNULL(ls = ls_handle.get_ls())) { + bret = false; + } else if (OB_ISNULL(ls_tablet_service = ls->get_tablet_svr())) { + bret = false; + } else { + ObTablet *tablet = NULL; + ObTabletHandle tablet_handle; + if (OB_FAIL(ls_tablet_service->get_tablet(tablet_id, tablet_handle, 100 * 1000))) { + bret = false; + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + bret = false; + } else if (!tablet->get_tablet_meta().transfer_info_.is_valid()) { + bret = false; + } else if (tablet->get_tablet_meta().transfer_info_.transfer_start_scn_ >= snapshot_version) { + bret = false; + } else { + // do nothing + } + } + } + } + } + return bret; +} + int ObSqlTransControl::start_hook_if_need_(ObSQLSessionInfo &session, transaction::ObTransService *txs, bool &start_hook) diff --git a/src/sql/ob_sql_trans_control.h b/src/sql/ob_sql_trans_control.h index 542ac0a35..2b588e073 100644 --- a/src/sql/ob_sql_trans_control.h +++ b/src/sql/ob_sql_trans_control.h @@ -254,6 +254,10 @@ private: transaction::ObTransService *txs, bool &start_hook); static uint32_t get_real_session_id(ObSQLSessionInfo &session); + static int get_first_lsid(const ObDASCtx &das_ctx, share::ObLSID &first_lsid); + static bool has_same_lsid(const ObDASCtx &das_ctx, + const share::SCN &snapshot_version, + share::ObLSID &first_lsid); public: /* * create a savepoint without name diff --git a/src/sql/optimizer/ob_phy_table_location_info.cpp b/src/sql/optimizer/ob_phy_table_location_info.cpp index 25394f684..ef5f625c7 100644 --- a/src/sql/optimizer/ob_phy_table_location_info.cpp +++ b/src/sql/optimizer/ob_phy_table_location_info.cpp @@ -333,7 +333,7 @@ int ObCandiTabletLoc::get_selected_replica(ObRoutePolicy::CandidateReplica &repl } int ObCandiTabletLoc::set_part_loc_with_only_readable_replica(const ObObjectID &partition_id, - const ObObjectID &first_level_part_id, + const ObObjectID &first_level_part_id, const common::ObTabletID &tablet_id, const ObLSLocation &partition_location) { @@ -343,7 +343,7 @@ int ObCandiTabletLoc::set_part_loc_with_only_readable_replica(const ObObjectID & LOG_ERROR("partition location has not been set yet, but replica idx has been selected", K(ret), K(*this), K(partition_location)); } else if (OB_FAIL(opt_tablet_loc_.assign_with_only_readable_replica(partition_id, - first_level_part_id, + first_level_part_id, tablet_id, partition_location))) { LOG_WARN("fail to assign partition location with only readable replica", diff --git a/src/sql/optimizer/ob_table_location.cpp b/src/sql/optimizer/ob_table_location.cpp index 9f7bd0915..100d0dbaa 100644 --- a/src/sql/optimizer/ob_table_location.cpp +++ b/src/sql/optimizer/ob_table_location.cpp @@ -1348,6 +1348,8 @@ int ObTableLocation::get_is_weak_read(const ObDMLStmt &dml_stmt, dml_stmt.get_query_ctx()->is_contain_select_for_update_ || dml_stmt.get_query_ctx()->is_contain_inner_table_) { is_weak_read = false; + } else if (!MTL_IS_PRIMARY_TENANT()) { + is_weak_read = true; } else { ObConsistencyLevel consistency_level = INVALID_CONSISTENCY; ObTxConsistencyType trans_consistency_type = ObTxConsistencyType::INVALID; diff --git a/src/sql/parser/non_reserved_keywords_mysql_mode.c b/src/sql/parser/non_reserved_keywords_mysql_mode.c index 909480845..db22315f8 100644 --- a/src/sql/parser/non_reserved_keywords_mysql_mode.c +++ b/src/sql/parser/non_reserved_keywords_mysql_mode.c @@ -745,6 +745,7 @@ static const NonReservedKeyword Mysql_none_reserved_keywords[] = {"statements", STATEMENTS}, {"statistics", STATISTICS}, {"binding", BINDING}, + {"sharding", SHARDING}, {"schema", SCHEMA}, {"schemas", SCHEMAS}, {"select", SELECT}, diff --git a/src/sql/parser/non_reserved_keywords_oracle_mode.c b/src/sql/parser/non_reserved_keywords_oracle_mode.c index efe235175..dad45752f 100644 --- a/src/sql/parser/non_reserved_keywords_oracle_mode.c +++ b/src/sql/parser/non_reserved_keywords_oracle_mode.c @@ -962,6 +962,7 @@ static const NonReservedKeyword Oracle_non_reserved_keywords[] = {"session_alias", SESSION_ALIAS}, {"session_user", SESSION_USER}, {"binding", BINDING}, + {"sharding", SHARDING}, {"set_master_cluster", SET_MASTER_CLUSTER}, {"set_slave_cluster", SET_SLAVE_CLUSTER}, {"set_tp", SET_TP}, diff --git a/src/sql/parser/sql_parser_mysql_mode.y b/src/sql/parser/sql_parser_mysql_mode.y index e3f1c8671..e18aeda58 100755 --- a/src/sql/parser/sql_parser_mysql_mode.y +++ b/src/sql/parser/sql_parser_mysql_mode.y @@ -250,7 +250,7 @@ END_P SET_VAR DELIMITER ARBITRATION ASCII AT AUTHORS AUTO AUTOEXTEND_SIZE AUTO_INCREMENT AUTO_INCREMENT_MODE AVG AVG_ROW_LENGTH ACTIVATE AVAILABILITY ARCHIVELOG AUDIT - BACKUP BACKUP_COPIES BALANCE BANDWIDTH BASE BASELINE BASELINE_ID BASIC BEGI BINDING BINLOG BIT BIT_AND + BACKUP BACKUP_COPIES BALANCE BANDWIDTH BASE BASELINE BASELINE_ID BASIC BEGI BINDING SHARDING BINLOG BIT BIT_AND BIT_OR BIT_XOR BLOCK BLOCK_INDEX BLOCK_SIZE BLOOM_FILTER BOOL BOOLEAN BOOTSTRAP BTREE BYTE BREADTH BUCKETS BISON_LIST BACKUPSET BACKED BACKUPPIECE BACKUP_BACKUP_DEST BACKUPROUND BADFILE @@ -7246,6 +7246,11 @@ TABLEGROUP_ID opt_equal_mark INTNUM (void)($2); malloc_non_terminal_node($$, result->malloc_pool_, T_TABLEGROUP_BINDING, 1, $3); } +| SHARDING opt_equal_mark STRING_VALUE +{ + (void)($2); + malloc_non_terminal_node($$, result->malloc_pool_, T_TABLEGROUP_SHARDING, 1, $3); +} | MAX_USED_PART_ID opt_equal_mark INTNUM { (void)($2); @@ -15221,6 +15226,11 @@ ALTER SYSTEM CANCEL BACKUP opt_backup_tenant_list malloc_non_terminal_node($$, result->malloc_pool_, T_BACKUP_MANAGE, 4, type, value, tenant, $5); } | +ALTER SYSTEM CANCEL RESTORE relation_name +{ + malloc_non_terminal_node($$, result->malloc_pool_, T_CANCEL_RESTORE, 1, $5); +} +| ALTER SYSTEM SUSPEND BACKUP { ParseNode *type = NULL; @@ -18009,6 +18019,7 @@ ACCOUNT | SET_MASTER_CLUSTER | SET_SLAVE_CLUSTER | SET_TP +| SHARDING | SHARE | SHUTDOWN | SIGNED diff --git a/src/sql/resolver/cmd/ob_alter_system_resolver.cpp b/src/sql/resolver/cmd/ob_alter_system_resolver.cpp index b556d9594..a4a768c71 100644 --- a/src/sql/resolver/cmd/ob_alter_system_resolver.cpp +++ b/src/sql/resolver/cmd/ob_alter_system_resolver.cpp @@ -18,7 +18,6 @@ #include "share/schema/ob_schema_getter_guard.h" #include "share/ob_locality_parser.h" #include "share/ob_time_utility2.h" -#include "share/backup/ob_log_archive_backup_info_mgr.h" #include "share/ob_encryption_util.h" #include "observer/ob_server_struct.h" #include "observer/omt/ob_tenant_config_mgr.h" @@ -2550,7 +2549,7 @@ int ObPhysicalRestoreTenantResolver::resolve(const ParseNode &parse_tree) stmt->set_is_preview(false); } else { if (T_TABLE_LIST == node->type_) { - // TODO table list restore not support, fix this 4.1 + // TODO table list restore not support, fix this 4.3 ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "table list restore is"); // store database_name/table_name with case sensitive. @@ -3793,6 +3792,45 @@ int ObBackupDatabaseResolver::resolve(const ParseNode &parse_tree) return ret; } +int ObCancelRestoreResolver::resolve(const ParseNode &parse_tree) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(T_CANCEL_RESTORE != parse_tree.type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("type is not T_CANCEL_RESTORE", "type", get_type_name(parse_tree.type_)); + } else if (OB_UNLIKELY(NULL == parse_tree.children_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("children should not be null", K(ret)); + } else if (OB_UNLIKELY(1 != parse_tree.num_child_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("children num not match", K(ret), "num_child", parse_tree.num_child_); + } else if (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_2_0_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("cancel restore is not supported under cluster version 4_2_0_0", K(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "cancel restore is"); + } else { + ObCancelRestoreStmt *stmt = NULL; + if (OB_ISNULL(stmt = create_stmt())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_ERROR("failed to create stmt", K(ret)); + } else if (OB_UNLIKELY(T_IDENT != parse_tree.children_[0]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid node", K(ret)); + } else { + ObString tenant_name; + tenant_name.assign_ptr(parse_tree.children_[0]->str_value_, parse_tree.children_[0]->str_len_); + stmt->get_drop_tenant_arg().exec_tenant_id_ = OB_SYS_TENANT_ID; + stmt->get_drop_tenant_arg().if_exist_ = false; + stmt->get_drop_tenant_arg().force_drop_ = true; + stmt->get_drop_tenant_arg().delay_to_drop_ = false; + stmt->get_drop_tenant_arg().open_recyclebin_ = false; + stmt->get_drop_tenant_arg().tenant_name_ = tenant_name; + stmt->get_drop_tenant_arg().drop_only_in_restore_ = true; + } + } + return ret; +} + int ObAlterSystemResolverUtil::get_tenant_ids(const ParseNode &t_node, ObIArray &tenant_ids) { int ret = OB_SUCCESS; diff --git a/src/sql/resolver/cmd/ob_alter_system_resolver.h b/src/sql/resolver/cmd/ob_alter_system_resolver.h index c66654fd3..b6e98391c 100644 --- a/src/sql/resolver/cmd/ob_alter_system_resolver.h +++ b/src/sql/resolver/cmd/ob_alter_system_resolver.h @@ -232,6 +232,7 @@ DEF_SIMPLE_CMD_RESOLVER(ObBackupKeyResolver); DEF_SIMPLE_CMD_RESOLVER(ObEnableSqlThrottleResolver); DEF_SIMPLE_CMD_RESOLVER(ObDisableSqlThrottleResolver); DEF_SIMPLE_CMD_RESOLVER(ObSetRegionBandwidthResolver); +DEF_SIMPLE_CMD_RESOLVER(ObCancelRestoreResolver); #undef DEF_SIMPLE_CMD_RESOLVER diff --git a/src/sql/resolver/cmd/ob_alter_system_stmt.h b/src/sql/resolver/cmd/ob_alter_system_stmt.h index 2da9e1903..ab7f92aa1 100644 --- a/src/sql/resolver/cmd/ob_alter_system_stmt.h +++ b/src/sql/resolver/cmd/ob_alter_system_stmt.h @@ -796,6 +796,19 @@ private: common::ObSArray backup_tenant_ids_; }; +class ObCancelRestoreStmt : public ObSystemCmdStmt +{ +public: + ObCancelRestoreStmt() + : ObSystemCmdStmt(stmt::T_CANCEL_RESTORE), + drop_tenant_arg_() {} + virtual ~ObCancelRestoreStmt() {} + obrpc::ObDropTenantArg &get_drop_tenant_arg() { return drop_tenant_arg_; } + TO_STRING_KV(N_STMT_TYPE, ((int)stmt_type_), K_(drop_tenant_arg)); +private: + obrpc::ObDropTenantArg drop_tenant_arg_; +}; + class ObBackupBackupsetStmt : public ObSystemCmdStmt { public: diff --git a/src/sql/resolver/cmd/ob_show_resolver.cpp b/src/sql/resolver/cmd/ob_show_resolver.cpp index c7fa1e5ba..ef929a396 100644 --- a/src/sql/resolver/cmd/ob_show_resolver.cpp +++ b/src/sql/resolver/cmd/ob_show_resolver.cpp @@ -1138,17 +1138,35 @@ int ObShowResolver::resolve(const ParseNode &parse_tree) ObSqlStrGenerator sql_gen; show_resv_ctx.condition_node_ = parse_tree.children_[0]; show_resv_ctx.stmt_type_ = stmt::T_SHOW_TABLEGROUPS; - GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TABLEGROUPS); - GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TABLEGROUPS, - REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), - REAL_NAME(OB_ALL_TABLEGROUP_TNAME, OB_ALL_VIRTUAL_TABLEGROUP_REAL_AGENT_ORA_TNAME), - REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), - REAL_NAME(table_name, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_TNAME), - is_oracle_mode ? real_tenant_id : sql_tenant_id, - REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), - REAL_NAME(OB_ALL_DATABASE_TNAME, OB_ALL_VIRTUAL_DATABASE_REAL_AGENT_ORA_TNAME), - is_oracle_mode ? real_tenant_id : sql_tenant_id, - is_oracle_mode ? real_tenant_id : sql_tenant_id); + uint64_t compat_version = OB_INVALID_VERSION; + + if (OB_FAIL(GET_MIN_DATA_VERSION(real_tenant_id, compat_version))) { + LOG_WARN("get min data_version failed", K(ret), K(real_tenant_id)); + } else if (compat_version < DATA_VERSION_4_2_0_0) { + GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TABLEGROUPS); + GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TABLEGROUPS, + REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), + REAL_NAME(OB_ALL_TABLEGROUP_TNAME, OB_ALL_VIRTUAL_TABLEGROUP_REAL_AGENT_ORA_TNAME), + REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), + REAL_NAME(table_name, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_TNAME), + is_oracle_mode ? real_tenant_id : sql_tenant_id, + REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), + REAL_NAME(OB_ALL_DATABASE_TNAME, OB_ALL_VIRTUAL_DATABASE_REAL_AGENT_ORA_TNAME), + is_oracle_mode ? real_tenant_id : sql_tenant_id, + is_oracle_mode ? real_tenant_id : sql_tenant_id); + } else { + GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TABLEGROUPS_V2); + GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TABLEGROUPS_V2, + REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), + REAL_NAME(OB_ALL_TABLEGROUP_TNAME, OB_ALL_VIRTUAL_TABLEGROUP_REAL_AGENT_ORA_TNAME), + REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), + REAL_NAME(table_name, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_TNAME), + is_oracle_mode ? real_tenant_id : sql_tenant_id, + REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), + REAL_NAME(OB_ALL_DATABASE_TNAME, OB_ALL_VIRTUAL_DATABASE_REAL_AGENT_ORA_TNAME), + is_oracle_mode ? real_tenant_id : sql_tenant_id, + is_oracle_mode ? real_tenant_id : sql_tenant_id); + } } }(); break; @@ -2691,6 +2709,19 @@ DEFINE_SHOW_CLAUSE_SET(SHOW_TABLEGROUPS, WHERE T1.TENANT_ID = %lu \ ORDER BY T1.TABLEGROUP_NAME, T2.TABLE_NAME", "Tablegroup_name"); +DEFINE_SHOW_CLAUSE_SET(SHOW_TABLEGROUPS_V2, + NULL, + "SELECT t1.Tablegroup_name AS Tablegroup_name, t2.Table_name AS Table_name, t3.Database_name AS Database_name, t1.Sharding AS Sharding \ + FROM %s.%s t1 LEFT JOIN %s.%s t2 ON (t1.tablegroup_id = t2.tablegroup_id and t2.tenant_id = %lu) \ + LEFT JOIN %s.%s t3 ON (t2.database_id = t3.database_id and t3.tenant_id = %lu) \ + WHERE t1.tenant_id = %lu AND t2.table_type in (0, 3, 6) \ + ORDER BY t1.tablegroup_name, t2.table_name", + "SELECT T1.TABLEGROUP_NAME AS \"TABLEGROUP_NAME\", T2.TABLE_NAME AS \"TABLE_NAME\", T3.DATABASE_NAME AS \"DATABASE_NAME\", t1.SHARDING AS \"SHARDING\" \ + FROM %s.%s T1 LEFT JOIN %s.%s T2 ON (T1.TABLEGROUP_ID = T2.TABLEGROUP_ID AND T2.TENANT_ID = %lu) \ + LEFT JOIN %s.%s T3 ON (T2.DATABASE_ID = T3.DATABASE_ID AND T3.TENANT_ID = %lu) \ + WHERE T1.TENANT_ID = %lu AND T2.TABLE_TYPE in (0, 3, 6) \ + ORDER BY T1.TABLEGROUP_NAME, T2.TABLE_NAME", + "Tablegroup_name"); DEFINE_SHOW_CLAUSE_SET(SHOW_VARIABLES, NULL, "SELECT variable_name AS `Variable_name`, value AS `Value` FROM %s.%s ORDER BY variable_name ASC", diff --git a/src/sql/resolver/cmd/ob_show_resolver.h b/src/sql/resolver/cmd/ob_show_resolver.h index c3f661308..c9f5a020c 100644 --- a/src/sql/resolver/cmd/ob_show_resolver.h +++ b/src/sql/resolver/cmd/ob_show_resolver.h @@ -99,6 +99,7 @@ struct ObShowResolver::ObShowSqlSet DECLARE_SHOW_CLAUSE_SET(SHOW_FULL_TABLES_LIKE); DECLARE_SHOW_CLAUSE_SET(SHOW_CHARSET); DECLARE_SHOW_CLAUSE_SET(SHOW_TABLEGROUPS); + DECLARE_SHOW_CLAUSE_SET(SHOW_TABLEGROUPS_V2); DECLARE_SHOW_CLAUSE_SET(SHOW_VARIABLES); DECLARE_SHOW_CLAUSE_SET(SHOW_GLOBAL_VARIABLES); DECLARE_SHOW_CLAUSE_SET(SHOW_COLUMNS); diff --git a/src/sql/resolver/ddl/ob_alter_table_resolver.cpp b/src/sql/resolver/ddl/ob_alter_table_resolver.cpp index 12c254c95..53fcbdc01 100644 --- a/src/sql/resolver/ddl/ob_alter_table_resolver.cpp +++ b/src/sql/resolver/ddl/ob_alter_table_resolver.cpp @@ -2754,7 +2754,7 @@ int ObAlterTableResolver::check_is_drop_primary_key(const ParseNode &node, if (OB_FAIL(ret)) { } else if (drop_pk_node_cnt <= 0) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("error unexpected, there is no drop primary key node", + LOG_WARN("error unexpected, there is no drop primary key node", K(ret), K(drop_pk_node_cnt), K(add_pk_node_cnt), K(other_action_cnt)); } else if (drop_pk_node_cnt == 1 && add_pk_node_cnt == 1 && other_action_cnt == 0) { // is modify primary key operation. @@ -2764,7 +2764,7 @@ int ObAlterTableResolver::check_is_drop_primary_key(const ParseNode &node, is_drop_primary_key = true; } else { ret = OB_NOT_SUPPORTED; - LOG_WARN("Multiple complex DDLs about primary key in single stmt is not supported now", + LOG_WARN("Multiple complex DDLs about primary key in single stmt is not supported now", K(ret), K(drop_pk_node_cnt), K(add_pk_node_cnt), K(other_action_cnt)); LOG_USER_ERROR(OB_NOT_SUPPORTED, "Multiple complex DDLs about primary in single stmt"); } @@ -4531,7 +4531,7 @@ int ObAlterTableResolver::resolve_alter_column(const ParseNode &node) return ret; } -// To check whether modify/change column is allowed, +// To check whether modify/change column is allowed, // should check it under main table schema and index table schemas. int ObAlterTableResolver::check_column_in_part_key(const ObTableSchema &table_schema, const ObColumnSchemaV2 &src_col_schema, @@ -4589,7 +4589,7 @@ int ObAlterTableResolver::check_column_in_part_key(const ObTableSchema &table_sc LOG_USER_ERROR(OB_OP_NOT_ALLOW, "alter part key of global index is"); } else if (OB_FAIL(check_alter_part_key_allowed(cur_table_schema, *column_schema, dst_col_schema))) { LOG_WARN("check alter partition key allowed failed", K(ret)); - } + } } } } @@ -4621,7 +4621,7 @@ int ObAlterTableResolver::alter_column_expr_in_part_expr( int ObAlterTableResolver::check_alter_part_key_allowed(const ObTableSchema &table_schema, const ObColumnSchemaV2 &src_col_schema, - const ObColumnSchemaV2 &dst_col_schema) + const ObColumnSchemaV2 &dst_col_schema) { int ret = OB_SUCCESS; const uint64_t table_id = table_schema.get_table_id(); @@ -4670,7 +4670,7 @@ int ObAlterTableResolver::check_alter_part_key_allowed(const ObTableSchema &tabl } OZ (part_expr->formalize(session_info_)); if (PARTITION_FUNC_TYPE_RANGE_COLUMNS == part_type || - PARTITION_FUNC_TYPE_LIST_COLUMNS == part_type || + PARTITION_FUNC_TYPE_LIST_COLUMNS == part_type || is_key_part(part_type)) { if (is_key_part(part_type) && part_expr->get_param_count() < 1) { ret = OB_ERR_UNEXPECTED; diff --git a/src/sql/resolver/ddl/ob_alter_tablegroup_resolver.cpp b/src/sql/resolver/ddl/ob_alter_tablegroup_resolver.cpp index affafd4dd..d0d5bd5c2 100644 --- a/src/sql/resolver/ddl/ob_alter_tablegroup_resolver.cpp +++ b/src/sql/resolver/ddl/ob_alter_tablegroup_resolver.cpp @@ -45,6 +45,15 @@ int ObAlterTablegroupResolver::resolve(const ParseNode &parser_tree) T_ALTER_TABLEGROUP != node->type_ || OB_ISNULL(node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("session_info_ is null or parser error", K(ret)); + } else { + uint64_t compat_version = OB_INVALID_VERSION; + uint64_t tenant_id = session_info_->get_effective_tenant_id(); + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) { + LOG_WARN("get min data_version failed", K(ret), K(tenant_id)); + } else if (compat_version < DATA_VERSION_4_2_0_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can not alter tablegroup while observer is upgrading", KR(ret), K(tenant_id)); + } } ObAlterTablegroupStmt *alter_tablegroup_stmt = NULL; if (OB_SUCC(ret)) { @@ -103,15 +112,10 @@ int ObAlterTablegroupResolver::resolve(const ParseNode &parser_tree) alter_tablegroup_stmt->set_alter_option_set(get_alter_option_bitset()); } } else if (T_ALTER_PARTITION_OPTION == node->children_[1]->type_) { - if (OB_FAIL(resolve_partition_options(*(node->children_[1])))) { - LOG_WARN("fail to resolve tablegroup partition option", K(ret)); - } else { - // partition_array是否序列化依赖part_level,由于resolver端不获取schema, - // 为避免序列化时丢失数据,可设置part_level为PARTITION_LEVEL_ONE - // (目前仅能动态增删一级range/range column分区) - alter_tablegroup_stmt->get_alter_tablegroup_arg() - .alter_tablegroup_schema_.set_part_level(PARTITION_LEVEL_ONE); - } + // ignore partition info after 4.2 + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported to alter tablegroup partition", KR(ret), K(alter_tablegroup_stmt->get_tablegroup_name())); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter tablegroup partition option"); } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid node type", K(ret), K(node->children_[1]->type_)); @@ -120,394 +124,5 @@ int ObAlterTablegroupResolver::resolve(const ParseNode &parser_tree) return ret; } -int ObAlterTablegroupResolver::resolve_partition_options(const ParseNode &node) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(T_ALTER_PARTITION_OPTION != node.type_ - || 0 >= node.num_child_ - || OB_ISNULL(node.children_) - || OB_ISNULL(node.children_[0]))) { - ret = OB_ERR_UNEXPECTED; - SQL_RESV_LOG(WARN, "invalid parse tree!", K(ret)); - } else if (OB_ISNULL(session_info_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("session info is null", K(ret)); - } else { - ObAlterTablegroupStmt *alter_tablegroup_stmt = get_alter_tablegroup_stmt(); - if (OB_SUCC(ret)) { - obrpc::ObAlterTablegroupArg &arg = alter_tablegroup_stmt->get_alter_tablegroup_arg(); - switch(node.children_[0]->type_) { - case T_ALTER_PARTITION_ADD: { - ParseNode *partition_node = node.children_[0]; - if (OB_FAIL(resolve_add_partition(*partition_node))) { - SQL_RESV_LOG(WARN, "Resolve add partition error!", K(ret)); - } else if (OB_FAIL(arg.alter_option_bitset_.add_member(obrpc::ObAlterTablegroupArg::ADD_PARTITION))) { - LOG_WARN("failed to add member", K(ret)); - } - break; - } - case T_ALTER_PARTITION_DROP: { - ParseNode *partition_node = node.children_[0]; - if (OB_FAIL(resolve_drop_partition(*partition_node))) { - SQL_RESV_LOG(WARN, "Resolve drop partition error!", K(ret)); - } else if (OB_FAIL(arg.alter_option_bitset_.add_member(obrpc::ObAlterTablegroupArg::DROP_PARTITION))) { - LOG_WARN("failed to add member", K(ret)); - } - break; - } - case T_ALTER_PARTITION_PARTITIONED: - { - ParseNode *partition_node = node.children_[0]; - bool enable_split_partition = false; - if (OB_ISNULL(partition_node) - || 1 != partition_node->num_child_ - || OB_ISNULL(partition_node->children_[0])) { - ret = OB_INVALID_ARGUMENT; - SQL_RESV_LOG(WARN, "invalid partition node", K(ret), K(partition_node)); - } else if (OB_FAIL(get_enable_split_partition(session_info_->get_effective_tenant_id(), - enable_split_partition))) { - LOG_WARN("failed to get enable split partition config", K(ret), - "tenant_id", session_info_->get_effective_tenant_id()); - } else if (!enable_split_partition) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("partitioned table not allow", K(ret)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "partition table"); - } else if (OB_FAIL(resolve_partition_table_option(alter_tablegroup_stmt, - partition_node->children_[0], - arg.alter_tablegroup_schema_))) { - LOG_WARN("fail to resolve partition node", K(ret), K(partition_node)); - } else if (OB_FAIL(arg.alter_option_bitset_.add_member(obrpc::ObAlterTablegroupArg::PARTITIONED_TABLE))) { - LOG_WARN("failed to add member", K(ret)); - } - break; - } - case T_ALTER_PARTITION_REORGANIZE: - { - ParseNode *partition_node = node.children_[0]; - bool enable_split_partition = false; - if (OB_ISNULL(partition_node) - || 2 != partition_node->num_child_ - || OB_ISNULL(partition_node->children_[0]) - || OB_ISNULL(partition_node->children_[1])) { - ret = OB_INVALID_ARGUMENT; - SQL_RESV_LOG(WARN, "invalid partition node", K(ret), K(partition_node)); - } else if (OB_FAIL(get_enable_split_partition(session_info_->get_effective_tenant_id(), - enable_split_partition))) { - LOG_WARN("failed to get enable split partition config", K(ret), - "tenant_id", session_info_->get_effective_tenant_id()); - } else if (!enable_split_partition) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("reorganize partition not allow", K(ret)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "reorganize partition"); - } else if (OB_FAIL(resolve_reorganize_partition(*partition_node))) { - LOG_WARN("failed to reorganize partition", K(ret)); - } else if (OB_FAIL(arg.alter_option_bitset_.add_member(obrpc::ObAlterTablegroupArg::REORGANIZE_PARTITION))) { - LOG_WARN("failed to add member", K(ret)); - } - break; - } - case T_ALTER_PARTITION_SPLIT: - { - ParseNode *partition_node = node.children_[0]; - bool enable_split_partition = false; - if (OB_ISNULL(partition_node) - || 2 != partition_node->num_child_ - || OB_ISNULL(partition_node->children_[0]) - || OB_ISNULL(partition_node->children_[1])) { - ret = OB_INVALID_ARGUMENT; - SQL_RESV_LOG(WARN, "invalid partition node", K(ret), K(partition_node)); - } else if (OB_FAIL(get_enable_split_partition(session_info_->get_effective_tenant_id(), - enable_split_partition))) { - LOG_WARN("failed to get enable split partition config", K(ret), - "tenant_id", session_info_->get_effective_tenant_id()); - } else if (!enable_split_partition) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("split partition not allow", K(ret)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "split partition"); - } else if (OB_FAIL(resolve_split_partition(*partition_node))) { - LOG_WARN("failed to reorganize partition", K(ret)); - } else if (OB_FAIL(arg.alter_option_bitset_.add_member(obrpc::ObAlterTablegroupArg::SPLIT_PARTITION))) { - LOG_WARN("failed to add member", K(ret)); - } - break; - } - default: { - ret = OB_ERR_UNEXPECTED; - SQL_RESV_LOG(WARN, "Unknown alter partition option %d!", - "option type", node.children_[0]->type_, K(ret)); - break; - } - } - } - } - return ret; -} - -int ObAlterTablegroupResolver::resolve_add_partition(const ParseNode &node) -{ - int ret = OB_SUCCESS; - int64_t expr_num = OB_INVALID_INDEX; - ParseNode *range_part_elements_node = NULL; - PartitionInfo part_info; - bool in_tablegroup = true; - ObAlterTablegroupStmt *alter_tablegroup_stmt = get_alter_tablegroup_stmt(); - const ObTablegroupSchema *tablegroup_schema = NULL; - if (OB_ISNULL(schema_checker_) - || OB_ISNULL(alter_tablegroup_stmt) - || OB_ISNULL(node.children_[0])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid schema, stmt or node ", K(ret), KP(schema_checker_), KP(alter_tablegroup_stmt), - "node", node.children_[0]); - } else if (OB_FAIL(schema_checker_->get_tablegroup_schema(session_info_->get_effective_tenant_id(), - alter_tablegroup_stmt->get_tablegroup_name(), - tablegroup_schema))) { - LOG_WARN("fail to get tablegroup schema", K(ret)); - } else if (OB_ISNULL(tablegroup_schema)) { - ret = OB_TABLEGROUP_NOT_EXIST; - LOG_WARN("invalid tablegroup schema", K(ret)); - } else if (OB_ISNULL(range_part_elements_node = node.children_[0]->children_[0])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("NULL ptr", K(ret)); - } else if (tablegroup_schema->is_range_part()) { - // resolver端放宽对value类型的检查,由rs端检查range分区的value是否为int - const ObPartitionFuncType part_type = ObPartitionFuncType::PARTITION_FUNC_TYPE_RANGE_COLUMNS; - // 此处expr_num由resolver解析所得,不代表tablegroup实际的expr_num - if (OB_FAIL(resolve_range_partition_elements(range_part_elements_node, - false, // is_subpartition - part_type, - part_info.range_value_exprs_, - part_info.parts_, - part_info.subparts_, - expr_num, - in_tablegroup))) { - LOG_WARN("resolve range partition elements fail", K(ret)); - } else if (OB_FAIL(alter_tablegroup_stmt->get_part_values_exprs().assign( - part_info.range_value_exprs_))) { - LOG_WARN("assign faield", K(ret)); - } - } else if (tablegroup_schema->is_list_part()) { - const ObPartitionFuncType part_type = ObPartitionFuncType::PARTITION_FUNC_TYPE_LIST_COLUMNS; - if (OB_FAIL(resolve_list_partition_elements(range_part_elements_node, - false, - part_type, - expr_num, - part_info.list_value_exprs_, - part_info.parts_, - part_info.subparts_, - in_tablegroup))) { - LOG_WARN("resolve list partition elememts fail", K(ret)); - } else if (OB_FAIL(alter_tablegroup_stmt->get_part_values_exprs().assign(part_info.list_value_exprs_))) { - LOG_WARN("assign list values failed", K(ret)); - } - } - if (OB_FAIL(ret)) { - - } else { - share::schema::ObPartition *part = NULL; - ObTablegroupSchema &alter_tablegroup_schema = - get_alter_tablegroup_stmt()->get_alter_tablegroup_arg().alter_tablegroup_schema_; - for (int64_t i = 0; OB_SUCC(ret) && i < part_info.parts_.count(); ++i) { - part = &(part_info.parts_.at(i)); - if (!part->get_part_name().empty()) { - if (OB_FAIL(alter_tablegroup_schema.check_part_name(*part))) { - LOG_WARN("check part name failed", K(ret)); - } - } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(alter_tablegroup_schema.add_partition(*part))) { - LOG_WARN("add partition failed", K(ret)); - } - } - if (OB_SUCC(ret)) { - alter_tablegroup_stmt->set_part_func_expr_num(expr_num); - alter_tablegroup_schema.get_part_option().set_part_func_type(tablegroup_schema->get_part_option().get_part_func_type()); - alter_tablegroup_schema.get_part_option().set_part_num(alter_tablegroup_schema.get_partition_num()); - } - } - return ret; -} - -int ObAlterTablegroupResolver::resolve_drop_partition(const ParseNode &node) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(node.children_) - || (T_ALTER_PARTITION_DROP != node.type_ - && T_ALTER_PARTITION_TRUNCATE != node.type_ )) { - ret = OB_ERR_UNEXPECTED; - SQL_RESV_LOG(WARN, "invalid parse tree", K(ret), "type", node.type_); - } else { - const ParseNode *name_list = node.children_[0]; - if (OB_ISNULL(name_list)) { - ret = OB_ERR_UNEXPECTED; - SQL_RESV_LOG(WARN, "invalid parse tree", K(ret)); - } else { - ObAlterTablegroupStmt *alter_tablegroup_stmt = get_alter_tablegroup_stmt(); - if (OB_ISNULL(alter_tablegroup_stmt)) { - ret = OB_ERR_UNEXPECTED; - SQL_RESV_LOG(WARN, "alter tablegroup stmt should not be null", K(ret)); - } - ObTablegroupSchema &alter_tablegroup_schema = - alter_tablegroup_stmt->get_alter_tablegroup_arg().alter_tablegroup_schema_; - for (int64_t i = 0; OB_SUCC(ret) && i < name_list->num_child_; ++i) { - ObPartition part; - ObString partition_name(static_cast(name_list->children_[i]->str_len_), - name_list->children_[i]->str_value_); - if (OB_FAIL(part.set_part_name(partition_name))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - SQL_RESV_LOG(ERROR, "set partition name failed", K(partition_name), K(ret)); - } else if (OB_FAIL(alter_tablegroup_schema.check_part_name(part))){ - SQL_RESV_LOG(WARN, "check part name failed!", K(part), K(ret)); - } else if (OB_FAIL(alter_tablegroup_schema.add_partition(part))){ - SQL_RESV_LOG(WARN, "add partition failed!", K(part), K(ret)); - } - } - } - } - return ret; -} - -int ObAlterTablegroupResolver::resolve_reorganize_partition(const ParseNode &node) -{ - int ret = OB_SUCCESS; - ObAlterTablegroupStmt *alter_tablegroup_stmt = get_alter_tablegroup_stmt(); - if (T_ALTER_PARTITION_REORGANIZE != node.type_ - || 2 != node.num_child_ - || OB_ISNULL(node.children_[0]) - || OB_ISNULL(node.children_[1]) - || OB_ISNULL(alter_tablegroup_stmt)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguement", K(ret), "children num", node.num_child_, - "children[0]", node.children_[0], "children[1]", node.children_[1]); - } else { - ObTablegroupSchema &alter_tablegroup_schema = alter_tablegroup_stmt->get_alter_tablegroup_arg().alter_tablegroup_schema_; - ParseNode *name_list = node.children_[1]; - if (OB_ISNULL(name_list)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(name_list)); - } else if (1 != name_list->num_child_) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("alter tablegroup reorganize multi partition not supported now", K(ret)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter tablegroup reorganize multiple partitions"); - } else if (OB_NOT_NULL(name_list->children_[0])) { - ObPartition part; - ObString partition_name(static_cast(name_list->children_[0]->str_len_), - name_list->children_[0]->str_value_); - if (OB_FAIL(alter_tablegroup_schema.set_split_partition(partition_name))) { - LOG_WARN("failed to set split partition name", K(ret)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("name list can not be null", K(ret), K(name_list)); - } - if (OB_FAIL(ret)) { - //nothing - } else if (OB_FAIL(resolve_add_partition(node))) { - LOG_WARN("failed resolve add partition", K(ret)); - } else if (1 == alter_tablegroup_schema.get_partition_num()) { - ret = OB_ERR_SPLIT_INTO_ONE_PARTITION; - LOG_USER_ERROR(OB_ERR_SPLIT_INTO_ONE_PARTITION); - LOG_WARN("can not split partition into one partition", K(ret), K(alter_tablegroup_schema)); - } - } - return ret; -} - -int ObAlterTablegroupResolver::resolve_split_partition(const ParseNode &node) -{ - int ret = OB_SUCCESS; - ObAlterTablegroupStmt *alter_tablegroup_stmt = get_alter_tablegroup_stmt(); - const ObTablegroupSchema *tablegroup_schema = NULL; - if (OB_ISNULL(schema_checker_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid schema check", K(ret)); - } else if (OB_FAIL(schema_checker_->get_tablegroup_schema(session_info_->get_effective_tenant_id(), - alter_tablegroup_stmt->get_tablegroup_name(), - tablegroup_schema))) { - LOG_WARN("fail to get tablegroup schema", K(ret)); - } else if (OB_ISNULL(tablegroup_schema)) { - ret = OB_TABLEGROUP_NOT_EXIST; - LOG_WARN("invalid tablegroup schema", K(ret)); - } else if (T_ALTER_PARTITION_SPLIT != node.type_ - || 2 != node.num_child_ - || OB_ISNULL(node.children_[0]) - || OB_ISNULL(node.children_[1]) - || T_SPLIT_ACTION != node.children_[1]->type_) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), "node_type", node.type_, - "node_num", node.num_child_); - } else if (OB_ISNULL(alter_tablegroup_stmt)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("alter table stmt should not be null", K(ret)); - } else { - ParseNode *name_list = node.children_[0]; - ObTablegroupSchema &alter_tablegroup_schema = - alter_tablegroup_stmt->get_alter_tablegroup_arg().alter_tablegroup_schema_; - if (OB_ISNULL(name_list)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret)); - } else { - ObString partition_name(static_cast(name_list->str_len_), - name_list->str_value_); - if (OB_FAIL(alter_tablegroup_schema.set_split_partition(partition_name))) { - LOG_WARN("failed to set split partition name", K(ret)); - } - } - - int64_t partition_count = OB_INVALID_COUNT; - int64_t expr_value_num = OB_INVALID_COUNT; - const ParseNode *split_node = node.children_[1]; - PartitionInfo part_info; - - if (OB_FAIL(ret)) { - //nothing - } else if (OB_ISNULL(split_node)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("split node is null", K(ret), K(split_node)); - } else if (OB_FAIL(check_split_type_valid(split_node, - tablegroup_schema->get_part_option().get_part_func_type()))) { - LOG_WARN("failed to check split type valid", K(ret), K(tablegroup_schema)); - } else if (OB_NOT_NULL(split_node->children_[AT_VALUES_NODE])) { - // split at [into ()] - partition_count = 1; - if (OB_FAIL(resolve_split_at_partition(alter_tablegroup_stmt, - split_node, - tablegroup_schema->get_part_option().get_part_func_type(), - part_info.part_func_exprs_, - alter_tablegroup_schema, - expr_value_num, - true))) { - LOG_WARN("failed to resolve split at partition", K(ret)); - } - } else if (OB_NOT_NULL(split_node->children_[PARTITION_DEFINE_NODE]) - && OB_NOT_NULL(split_node->children_[PARTITION_DEFINE_NODE]->children_[0])) { - // split into () - ParseNode *range_element_node = split_node->children_[PARTITION_DEFINE_NODE]->children_[0]; - if (OB_FAIL(resolve_split_into_partition(alter_tablegroup_stmt, - range_element_node, - tablegroup_schema->get_part_option().get_part_func_type(), - part_info.part_func_exprs_, - partition_count, - expr_value_num, - alter_tablegroup_schema, - true))) { - LOG_WARN("failed to resolve split at partition", K(ret)); - } - } else { - //不能即没有at也没有partition说明 - ret = OB_ERR_MISS_AT_VALUES; - LOG_WARN("miss at and less than values", K(ret)); - LOG_USER_ERROR(OB_ERR_MISS_AT_VALUES); - } - - if (OB_FAIL(ret)) { - } else { - alter_tablegroup_stmt->set_part_func_expr_num(expr_value_num); - alter_tablegroup_schema.get_part_option().set_part_func_type(tablegroup_schema->get_part_option().get_part_func_type()); - alter_tablegroup_schema.get_part_option().set_part_num(partition_count);//最后一个partition可能没有最大值,需要在rs端处理 - } - } - return ret; -} - } //namespace common } //namespace oceanbase diff --git a/src/sql/resolver/ddl/ob_alter_tablegroup_resolver.h b/src/sql/resolver/ddl/ob_alter_tablegroup_resolver.h index 63c9b5975..496faa0eb 100644 --- a/src/sql/resolver/ddl/ob_alter_tablegroup_resolver.h +++ b/src/sql/resolver/ddl/ob_alter_tablegroup_resolver.h @@ -31,11 +31,6 @@ public: ObAlterTablegroupStmt *get_alter_tablegroup_stmt() { return static_cast(stmt_); }; private: - int resolve_partition_options(const ParseNode &node); - int resolve_add_partition(const ParseNode &node); - int resolve_drop_partition(const ParseNode &node); - int resolve_reorganize_partition(const ParseNode &node); - int resolve_split_partition(const ParseNode &node); DISALLOW_COPY_AND_ASSIGN(ObAlterTablegroupResolver); }; diff --git a/src/sql/resolver/ddl/ob_alter_tablegroup_stmt.cpp b/src/sql/resolver/ddl/ob_alter_tablegroup_stmt.cpp index 08693e5ab..9b739c2a0 100644 --- a/src/sql/resolver/ddl/ob_alter_tablegroup_stmt.cpp +++ b/src/sql/resolver/ddl/ob_alter_tablegroup_stmt.cpp @@ -48,6 +48,12 @@ int ObAlterTablegroupStmt::set_locality(const common::ObString &locality) { return OB_SUCCESS; // ignore this (not support in 4.0) } + +int ObAlterTablegroupStmt::set_tablegroup_sharding(const common::ObString &sharding) +{ + return alter_tablegroup_arg_.alter_tablegroup_schema_.set_sharding(sharding); +} + } //namespace sql } //namespace oceanbase diff --git a/src/sql/resolver/ddl/ob_alter_tablegroup_stmt.h b/src/sql/resolver/ddl/ob_alter_tablegroup_stmt.h index ab85272bb..071024f0b 100644 --- a/src/sql/resolver/ddl/ob_alter_tablegroup_stmt.h +++ b/src/sql/resolver/ddl/ob_alter_tablegroup_stmt.h @@ -38,6 +38,7 @@ public: virtual obrpc::ObDDLArg &get_ddl_arg() { return alter_tablegroup_arg_; } virtual int set_primary_zone(const common::ObString &zone) override; virtual int set_locality(const common::ObString &locality) override; + virtual int set_tablegroup_sharding(const common::ObString &sharding) override; inline void set_alter_option_set(const common::ObBitSet<> &alter_option_set); bool is_alter_partition() const { return alter_tablegroup_arg_.is_alter_partitions(); } virtual int set_tablegroup_id(uint64_t tablegroup_id) override; diff --git a/src/sql/resolver/ddl/ob_create_tablegroup_resolver.cpp b/src/sql/resolver/ddl/ob_create_tablegroup_resolver.cpp index f581a0a51..f922aad6a 100644 --- a/src/sql/resolver/ddl/ob_create_tablegroup_resolver.cpp +++ b/src/sql/resolver/ddl/ob_create_tablegroup_resolver.cpp @@ -41,6 +41,15 @@ int ObCreateTablegroupResolver::resolve(const ParseNode &parse_tree) OB_ISNULL(node->children_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("session_info_ is null or parser is error", K(ret)); + } else { + uint64_t compat_version = OB_INVALID_VERSION; + uint64_t tenant_id = session_info_->get_effective_tenant_id(); + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) { + LOG_WARN("get min data_version failed", K(ret), K(tenant_id)); + } else if (compat_version < DATA_VERSION_4_2_0_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can not create tablegroup while observer is upgrading", KR(ret), K(tenant_id)); + } } ObString tablegroup_name; if (OB_SUCC(ret)) { @@ -99,14 +108,19 @@ int ObCreateTablegroupResolver::resolve(const ParseNode &parse_tree) if (OB_FAIL(ret)) { //nothing todo } else if (OB_NOT_NULL(node->children_[PARTITION_OPTION])) { + //ignore partition after 4.2 + LOG_USER_WARN(OB_NOT_SUPPORTED, "create tablegroup with partition"); + } + // set default sharding attribute + if (OB_SUCC(ret)) { ObTablegroupSchema &tablegroup_schema = create_tablegroup_stmt->get_create_tablegroup_arg().tablegroup_schema_; - if (OB_FAIL(resolve_partition_table_option(create_tablegroup_stmt, - node->children_[PARTITION_OPTION], - tablegroup_schema))) { - SQL_RESV_LOG(WARN, "resolve partition option failed", K(ret)); - } else {} //do nothing + ObString sharding_default(OB_PARTITION_SHARDING_ADAPTIVE); + if (tablegroup_schema.get_sharding().empty()) { + if (OB_FAIL(tablegroup_schema.set_sharding(sharding_default))) { + LOG_WARN("set_default_sharding fail", K(ret)); + } + } } SQL_RESV_LOG(INFO, "resolve create tablegroup finish", K(ret), K(tablegroup_name)); return ret; } - diff --git a/src/sql/resolver/ddl/ob_create_tablegroup_stmt.h b/src/sql/resolver/ddl/ob_create_tablegroup_stmt.h index e1c8bec28..4b1a69926 100644 --- a/src/sql/resolver/ddl/ob_create_tablegroup_stmt.h +++ b/src/sql/resolver/ddl/ob_create_tablegroup_stmt.h @@ -34,6 +34,7 @@ public: const common::ObString &get_tablegroup_name() const; virtual int set_primary_zone(const common::ObString &zone) override; virtual int set_locality(const common::ObString &locality) override; + virtual int set_tablegroup_sharding(const common::ObString &sharding) override; obrpc::ObCreateTablegroupArg &get_create_tablegroup_arg(); virtual obrpc::ObDDLArg &get_ddl_arg() { return create_tablegroup_arg_; } virtual int set_tablegroup_id(uint64_t tablegroup_id) override; @@ -65,6 +66,11 @@ inline int ObCreateTablegroupStmt::set_tablegroup_id( return ret; } +inline int ObCreateTablegroupStmt::set_tablegroup_sharding(const common::ObString &sharding) +{ + return create_tablegroup_arg_.tablegroup_schema_.set_sharding(sharding); +} + } //namespace sql } //namespace oceanase #endif //OCEANBASE_SQL_OB_CREATE_TABLEGROUP_STMT_ diff --git a/src/sql/resolver/ddl/ob_ddl_resolver.cpp b/src/sql/resolver/ddl/ob_ddl_resolver.cpp index dbd21aee8..aca6c2d1c 100644 --- a/src/sql/resolver/ddl/ob_ddl_resolver.cpp +++ b/src/sql/resolver/ddl/ob_ddl_resolver.cpp @@ -1952,7 +1952,7 @@ int ObDDLResolver::resolve_table_option(const ParseNode *option_node, const bool case T_TABLE_CHECKSUM: case T_DELAY_KEY_WRITE: case T_AVG_ROW_LENGTH: { - break; + break; } case T_EXTERNAL_FILE_LOCATION: { ParseNode *string_node = NULL; @@ -6226,7 +6226,7 @@ int ObDDLResolver::resolve_list_partition_elements(ParseNode *node, // 主要用于在 alter table 时检查需要修改的列是否为外键列 // 如果该列属于外键列,不允许修改外键列的类型 -int ObDDLResolver::check_column_in_foreign_key(const ObTableSchema &table_schema, +int ObDDLResolver::check_column_in_foreign_key(const ObTableSchema &table_schema, const ObString &column_name, const bool is_drop_column) { @@ -6250,10 +6250,10 @@ int ObDDLResolver::check_column_in_foreign_key(const ObTableSchema &table_schema } if (table_schema.get_table_id() == foreign_key_info.child_table_id_) { if (is_drop_column) { - // To be compatible with Mysql 5.6 and 8.0, follwing behavior on child table are allowed on OB 4.0: + // To be compatible with Mysql 5.6 and 8.0, follwing behavior on child table are allowed on OB 4.0: // 1. drop foreign key non-related columns and drop any foreign key in one sql; // 2. drop the foreign key and its' some/all related columns in one sql. - // Thus, RS should report OB_ERR_ALTER_COLUMN_FK if drop fk related column without drop this fk. + // Thus, RS should report OB_ERR_ALTER_COLUMN_FK if drop fk related column without drop this fk. } else { for (int64_t j = 0; OB_SUCC(ret) && j < foreign_key_info.child_column_ids_.count(); j++) { if (alter_column->get_column_id() == foreign_key_info.child_column_ids_.at(j)) { @@ -9145,10 +9145,10 @@ int ObDDLResolver::resolve_partition_hash_or_key( /* 4.1 检查interval_expr是否是立即数或者,1+1 不算 - 4.2 expr的类型是否和col匹配 否则 ORA-14752 + 4.2 expr的类型是否和col匹配 否则 ORA-14752 */ int ObDDLResolver::resolve_interval_node(ObResolverParams ¶ms, - ParseNode *interval_node, + ParseNode *interval_node, common::ColumnType &col_dt, int64_t precision, int64_t scale, @@ -9166,7 +9166,7 @@ int ObDDLResolver::resolve_interval_node(ObResolverParams ¶ms, ret = OB_ERR_INVALID_DATA_TYPE_INTERVAL_TABLE; } else { ObRawExpr *interval_value_expr = NULL; - OZ (ObResolverUtils::resolve_partition_range_value_expr(params, *expr_node, "interval_part", + OZ (ObResolverUtils::resolve_partition_range_value_expr(params, *expr_node, "interval_part", PARTITION_FUNC_TYPE_RANGE_COLUMNS, interval_value_expr, false, true)); if (ret == OB_ERR_PARTITION_FUNCTION_IS_NOT_ALLOWED) { @@ -9179,11 +9179,11 @@ int ObDDLResolver::resolve_interval_node(ObResolverParams ¶ms, common::ObObjType expr_type = interval_value_expr->get_data_type(); switch (col_dt) { case ObIntType: - case ObFloatType: + case ObFloatType: case ObDoubleType: case ObNumberFloatType: case ObNumberType: { - if (expr_type != ObIntType && expr_type != ObFloatType + if (expr_type != ObIntType && expr_type != ObFloatType && expr_type != ObNumberType && expr_type != ObDoubleType) { ret = OB_ERR_INTERVAL_EXPR_NOT_CORRECT_TYPE; LOG_WARN("fail to check interval expr datatype", K(expr_type), K(col_dt), K(ret)); @@ -9192,7 +9192,7 @@ int ObDDLResolver::resolve_interval_node(ObResolverParams ¶ms, acc.set_precision(precision); acc.set_scale(scale); interval_value_expr->set_accuracy(acc); - } + } if (OB_SUCC(ret)) { ParamStore dummy_params; ObRawExprFactory expr_factory(*(params.allocator_)); @@ -9225,7 +9225,7 @@ int ObDDLResolver::resolve_interval_node(ObResolverParams ¶ms, } break; } - case ObDateTimeType: + case ObDateTimeType: case ObTimestampNanoType: { if (expr_type != ObIntervalYMType && expr_type != ObIntervalDSType) { ret = OB_ERR_INTERVAL_EXPR_NOT_CORRECT_TYPE; @@ -9244,7 +9244,7 @@ int ObDDLResolver::resolve_interval_node(ObResolverParams ¶ms, interval_value_expr_out = interval_value_expr; } } - } + } return ret; } @@ -9259,13 +9259,13 @@ int ObDDLResolver::resolve_interval_expr_low(ObResolverParams ¶ms, const ObColumnSchemaV2 *col_schema = NULL; common::ColumnType col_dt = ObNullType; /* 1. interval 分区只支持一个分区键 否则 ORA-14750*/ - if (OB_SUCC(ret)) { + if (OB_SUCC(ret)) { if (table_schema.get_partition_key_column_num() > 1) { ret = OB_ERR_INTERVAL_CLAUSE_HAS_MORE_THAN_ONE_COLUMN; SQL_RESV_LOG(WARN, "interval clause has more then one column", K(ret)); } } - + /* 2. interval 分区列只支持数据类型: number, date, float, timestamp。 否则 ORA-14751 */ if (OB_SUCC(ret)) { uint64_t col_id = OB_INVALID_ID; @@ -9328,7 +9328,7 @@ int ObDDLResolver::resolve_interval_clause(ObPartitionedStmt *stmt, LOG_WARN("failed to resolve interval expr low", K(ret)); } else { stmt->set_interval_expr(interval_value); - } + } } return ret; } diff --git a/src/sql/resolver/ddl/ob_ddl_resolver.h b/src/sql/resolver/ddl/ob_ddl_resolver.h index 32ffa84c6..9d4c2ba0f 100644 --- a/src/sql/resolver/ddl/ob_ddl_resolver.h +++ b/src/sql/resolver/ddl/ob_ddl_resolver.h @@ -529,7 +529,7 @@ protected: common::ObSEArray &range_exprs); static int resolve_interval_node( ObResolverParams ¶ms, - ParseNode *interval_node, + ParseNode *interval_node, common::ColumnType &col_dt, int64_t precision, int64_t scale, @@ -585,7 +585,7 @@ protected: int resolve_enum_or_set_column( const ParseNode *type_node, share::schema::ObColumnSchemaV2 &column); - + static int is_gen_col_with_udf(const ObTableSchema &table_schema, const ObRawExpr *col_expr, bool &res); diff --git a/src/sql/resolver/ddl/ob_tablegroup_resolver.h b/src/sql/resolver/ddl/ob_tablegroup_resolver.h index 7a7584638..8ac4a97d6 100644 --- a/src/sql/resolver/ddl/ob_tablegroup_resolver.h +++ b/src/sql/resolver/ddl/ob_tablegroup_resolver.h @@ -12,6 +12,7 @@ #ifndef OCEANBASE_SQL_RESOLVE_OB_TABLEGROUP_RESOLVER_H #define OCEANBASE_SQL_RESOLVE_OB_TABLEGROUP_RESOLVER_H +#include "lib/ob_define.h" #include "sql/resolver/ob_stmt_resolver.h" #include "sql/resolver/ddl/ob_ddl_resolver.h" #include "share/ob_rpc_struct.h" @@ -94,6 +95,7 @@ int ObTableGroupResolver::resolve_tablegroup_option(T *stmt, ParseNode *node) } else { ParseNode *option_node = NULL; int32_t num = node->num_child_; + bool has_tablegroup_sharding_option = false; for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) { option_node = node->children_[i]; switch (option_node->type_) { @@ -203,6 +205,35 @@ int ObTableGroupResolver::resolve_tablegroup_option(T *stmt, ParseNode *node) } break; } + case T_TABLEGROUP_SHARDING: { + if (nullptr == option_node->children_ || option_node->num_child_ != 1) { + ret = OB_INVALID_ARGUMENT; + SQL_RESV_LOG(WARN, "invalid tablegroup sharding attribute", K(ret), + "num_child", option_node->num_child_); + } else if (OB_UNLIKELY(nullptr == option_node->children_[0])) { + ret = OB_ERR_UNEXPECTED; + SQL_RESV_LOG(WARN, "option_node child is null", K(ret)); + } else { + has_tablegroup_sharding_option = true; + int64_t sharding_length = option_node->children_[0]->str_len_; + const char *sharding_str = option_node->children_[0]->str_value_; + common::ObString tablegroup_sharding; + tablegroup_sharding.assign_ptr(sharding_str, static_cast(sharding_length)); + if (tablegroup_sharding != OB_PARTITION_SHARDING_NONE && tablegroup_sharding != OB_PARTITION_SHARDING_PARTITION + && tablegroup_sharding != OB_PARTITION_SHARDING_ADAPTIVE) { + ret = OB_INVALID_ARGUMENT; + SQL_RESV_LOG(WARN, "invalid tablegroup sharding attribute", K(ret), + "sharding", tablegroup_sharding); + LOG_USER_ERROR(OB_INVALID_ARGUMENT, "sharding"); + } else if (OB_FAIL(stmt->set_tablegroup_sharding(tablegroup_sharding))) { + SQL_LOG(WARN, "set_tablegroup_sharding", K(ret)); + } + } + if (OB_SUCC(ret) && OB_FAIL(alter_option_bitset_.add_member(obrpc::ObAlterTablegroupArg::SHARDING))) { + SQL_LOG(WARN, "fail to add member", K(ret)); + } + break; + } case T_MAX_USED_PART_ID: { // max_used_part_id is deprecated in 4.0, we just ignore and show warnings LOG_USER_WARN(OB_NOT_SUPPORTED, "max_used_part_id"); @@ -223,5 +254,3 @@ int ObTableGroupResolver::resolve_tablegroup_option(T *stmt, ParseNode *node) } //namespace sql } //namespace oceanbase #endif - - diff --git a/src/sql/resolver/ddl/ob_tablegroup_stmt.h b/src/sql/resolver/ddl/ob_tablegroup_stmt.h index e2ff3d6d3..ef0965e8d 100644 --- a/src/sql/resolver/ddl/ob_tablegroup_stmt.h +++ b/src/sql/resolver/ddl/ob_tablegroup_stmt.h @@ -41,6 +41,7 @@ public: virtual int set_primary_zone(const common::ObString &zone) = 0; virtual int set_locality(const common::ObString &locality) = 0; virtual int set_tablegroup_id(uint64_t tablegroup_id) = 0; + virtual int set_tablegroup_sharding(const common::ObString &sharding) = 0; int64_t get_part_func_expr_num() { return part_func_expr_num_; } void set_part_func_expr_num(int64_t expr_num) { part_func_expr_num_ = expr_num; } diff --git a/src/sql/resolver/ob_resolver.cpp b/src/sql/resolver/ob_resolver.cpp index ab9ea4b63..5d954f8ec 100644 --- a/src/sql/resolver/ob_resolver.cpp +++ b/src/sql/resolver/ob_resolver.cpp @@ -991,6 +991,10 @@ int ObResolver::resolve(IsPrepared if_prepared, const ParseNode &parse_tree, ObS REGISTER_STMT_RESOLVER(BackupDatabase); break; } + case T_CANCEL_RESTORE: { + REGISTER_STMT_RESOLVER(CancelRestore); + break; + } case T_BACKUP_KEY: { REGISTER_STMT_RESOLVER(BackupKey); break; diff --git a/src/sql/resolver/ob_schema_checker.cpp b/src/sql/resolver/ob_schema_checker.cpp index 4694891cb..3ca052f50 100644 --- a/src/sql/resolver/ob_schema_checker.cpp +++ b/src/sql/resolver/ob_schema_checker.cpp @@ -847,7 +847,7 @@ int ObSchemaChecker::get_table_schema(const uint64_t tenant_id, const uint64_t t LOG_WARN("schema checker is not inited", K(is_inited_), K(ret)); } else if (OB_UNLIKELY(OB_INVALID_ID == table_id)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(table_id), K(ret)); + LOG_WARN("invalid arguments", K(table_id), K(ret), K(lbt())); } else if (!is_link && OB_FAIL(get_table_schema_inner(tenant_id, table_id, table))) { LOG_WARN("get table schema failed", K(tenant_id), K(table_id), K(ret)); } else if (is_link && OB_FAIL(get_link_table_schema_inner(table_id, table))) { diff --git a/src/sql/resolver/ob_stmt_type.h b/src/sql/resolver/ob_stmt_type.h index a90560dcf..7d5683ecb 100644 --- a/src/sql/resolver/ob_stmt_type.h +++ b/src/sql/resolver/ob_stmt_type.h @@ -282,6 +282,7 @@ OB_STMT_TYPE_DEF_UNKNOWN_AT(T_REPLACE_ARBITRATION_SERVICE, get_sys_tenant_alter_ OB_STMT_TYPE_DEF_UNKNOWN_AT(T_SHOW_SEQUENCES, err_stmt_type_priv, 283) OB_STMT_TYPE_DEF_UNKNOWN_AT(T_BACKUP_KEY, get_sys_tenant_alter_system_priv, 284) OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CREATE_STANDBY_TENANT, get_sys_tenant_super_priv, 285) +OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CANCEL_RESTORE, get_sys_tenant_alter_system_priv, 286) OB_STMT_TYPE_DEF_UNKNOWN_AT(T_MAX, err_stmt_type_priv, 500) #endif diff --git a/src/storage/CMakeLists.txt b/src/storage/CMakeLists.txt old mode 100644 new mode 100755 index a3ed4b73f..dd4dfcbf2 --- a/src/storage/CMakeLists.txt +++ b/src/storage/CMakeLists.txt @@ -91,6 +91,10 @@ ob_set_subtarget(ob_storage blocksstable_encoding blocksstable/encoding/neon/ob_raw_decoder_neon.cpp ) +ob_set_subtarget(ob_storage blockstore + blockstore/ob_shared_block_reader_writer.cpp +) + ob_set_subtarget(ob_storage slog slog/ob_server_slog_writer.cpp slog/ob_storage_log_batch_header.cpp @@ -127,6 +131,7 @@ ob_set_subtarget(ob_storage high_availability high_availability/ob_storage_ha_service.cpp high_availability/ob_storage_ha_struct.cpp high_availability/ob_storage_ha_src_provider.cpp + high_availability/ob_transfer_backfill_tx.cpp high_availability/ob_transfer_handler.cpp high_availability/ob_storage_restore_struct.cpp high_availability/ob_tablet_group_restore.cpp @@ -140,8 +145,18 @@ ob_set_subtarget(ob_storage high_availability high_availability/ob_ls_remove_member_dag.cpp high_availability/ob_storage_ha_tablet_builder.cpp high_availability/ob_ls_rebuild_cb_impl.cpp + high_availability/ob_ls_member_list_service.cpp + high_availability/ob_ls_transfer_info.cpp high_availability/ob_tablet_ha_status.cpp high_availability/ob_storage_ha_utils.cpp + high_availability/ob_transfer_service.cpp + high_availability/ob_transfer_struct.cpp + high_availability/ob_finish_transfer.cpp + high_availability/ob_transfer_lock_info_operator.cpp + high_availability/ob_transfer_lock_utils.cpp + high_availability/ob_rebuild_service.cpp + high_availability/ob_tablet_transfer_info.cpp + high_availability/ob_ls_block_tx_service.cpp ) ob_set_subtarget(ob_storage restore @@ -152,7 +167,9 @@ ob_set_subtarget(ob_storage restore ob_set_subtarget(ob_storage backup backup/ob_backup_ctx.cpp + backup/ob_backup_data_store.cpp backup/ob_backup_factory.cpp + backup/ob_backup_file_writer_ctx.cpp backup/ob_backup_index_cache.cpp backup/ob_backup_iterator.cpp backup/ob_backup_index_merger.cpp @@ -170,9 +187,11 @@ ob_set_subtarget(ob_storage backup ) ob_set_subtarget(ob_storage tablet - tablet/ob_tablet.cpp + tablet/ob_full_tablet_creator.cpp tablet/ob_tablet_binding_helper.cpp + tablet/ob_tablet_binding_replay_executor.cpp tablet/ob_tablet_common.cpp + tablet/ob_tablet_complex_addr.cpp tablet/ob_tablet_create_delete_helper.cpp tablet/ob_tablet_create_sstable_param.cpp tablet/ob_tablet_ddl_info.cpp @@ -185,8 +204,27 @@ ob_set_subtarget(ob_storage tablet tablet/ob_tablet_slog_helper.cpp tablet/ob_tablet_status.cpp tablet/ob_tablet_table_store.cpp + tablet/ob_tablet_table_store_iterator.cpp tablet/ob_table_store_util.cpp tablet/ob_tablet_table_store_flag.cpp + tablet/ob_tablet_create_delete_mds_user_data.cpp + tablet/ob_tablet_create_mds_helper.cpp + tablet/ob_tablet_delete_mds_helper.cpp + tablet/ob_tablet_delete_replay_executor.cpp + tablet/ob_tablet_full_medium_info.cpp + tablet/ob_tablet_full_memory_mds_data.cpp + tablet/ob_tablet_mds_data.cpp + tablet/ob_tablet_mds_data_cache.cpp + tablet/ob_tablet_dumped_medium_info.cpp + tablet/ob_tablet_binding_info.cpp + tablet/ob_tablet_binding_mds_user_data.cpp + tablet/ob_tablet_mds_node_dump_operator.cpp + tablet/ob_tablet_start_transfer_mds_helper.cpp + tablet/ob_tablet_finish_transfer_mds_helper.cpp + tablet/ob_tablet_persister.cpp + tablet/ob_tablet_obj_load_helper.cpp + tablet/ob_tablet.cpp + tablet/ob_tablet_medium_info_reader.cpp ) ob_set_subtarget(ob_storage tx_wrs @@ -306,6 +344,7 @@ ob_set_subtarget(ob_storage tx_storage tx_storage/ob_tenant_freezer_rpc.cpp tx_storage/ob_tenant_memory_printer.cpp tx_storage/ob_tablet_gc_service.cpp + tx_storage/ob_empty_shell_task.cpp ) ob_set_subtarget(ob_storage tx_table @@ -319,6 +358,7 @@ ob_set_subtarget(ob_storage tx_table tx_table/ob_tx_data_table.cpp tx_table/ob_tx_table.cpp tx_table/ob_tx_table_define.cpp + tx_table/ob_tx_table_guards.cpp tx_table/ob_tx_table_interface.cpp tx_table/ob_tx_table_iterator.cpp ) @@ -328,7 +368,6 @@ ob_set_subtarget(ob_storage ls ls/ob_ls.cpp ls/ob_ls_ddl_log_handler.cpp ls/ob_ls_lock.cpp - ls/ob_ls_member_table.cpp ls/ob_ls_meta.cpp ls/ob_ls_meta_package.cpp ls/ob_ls_role_handler.cpp @@ -391,6 +430,8 @@ ob_set_subtarget(ob_storage ddl ddl/ob_tablet_barrier_log.cpp ddl/ob_tablet_ddl_kv.cpp ddl/ob_tablet_ddl_kv_mgr.cpp + ddl/ob_ddl_lock.cpp + ddl/ob_ddl_replay_executor.cpp ddl/ob_ddl_heart_beat_task.cpp ddl/ob_ddl_server_client.cpp ) @@ -425,7 +466,9 @@ ob_set_subtarget(ob_storage common ob_super_block_struct.cpp ob_sync_tablet_seq_clog.cpp ob_table_store_stat_mgr.cpp + ob_tablet_autoinc_seq_rpc_handler.cpp ob_value_row_iterator.cpp + ob_common_id_utils.cpp ob_tenant_tablet_stat_mgr.cpp ) @@ -439,6 +482,7 @@ ob_set_subtarget(ob_storage common_mixed meta_mem/ob_tablet_pointer.cpp meta_mem/ob_tenant_meta_mem_mgr.cpp meta_mem/ob_tenant_meta_obj_pool.cpp + meta_mem/ob_storage_meta_cache.cpp utl_file/ob_utl_file_handler.cpp ) @@ -453,6 +497,7 @@ ob_set_subtarget(ob_storage compaction compaction/ob_partition_merge_policy.cpp compaction/ob_partition_parallel_merge_ctx.cpp compaction/ob_tablet_merge_ctx.cpp + compaction/ob_tablet_merge_checker.cpp compaction/ob_tablet_merge_task.cpp compaction/ob_tx_table_merge_task.cpp compaction/ob_tenant_freeze_info_mgr.cpp @@ -504,10 +549,28 @@ ob_set_subtarget(ob_storage memtable_mvcc memtable/mvcc/ob_row_data.cpp ) +ob_set_subtarget(ob_storage multi_data_source + multi_data_source/buffer_ctx.cpp + multi_data_source/mds_ctx.cpp + multi_data_source/mds_node.cpp + multi_data_source/mds_table_mgr.cpp + multi_data_source/mds_table_base.cpp + multi_data_source/mds_writer.cpp + multi_data_source/mds_table_handler.cpp + multi_data_source/adapter_define/mds_dump_node.cpp + multi_data_source/runtime_utility/mds_tenant_service.cpp + multi_data_source/runtime_utility/mds_factory.cpp + multi_data_source/ob_mds_table_merge_dag.cpp + multi_data_source/ob_mds_table_merge_dag_param.cpp + multi_data_source/ob_mds_table_merge_task.cpp +) + ob_set_subtarget(ob_storage tablelock tablelock/ob_lock_memtable.cpp tablelock/ob_lock_memtable_mgr.cpp + tablelock/ob_lock_inner_connection_util.cpp tablelock/ob_lock_table.cpp + tablelock/ob_lock_utils.cpp tablelock/ob_mem_ctx_table_lock.cpp tablelock/ob_obj_lock.cpp tablelock/ob_table_lock_callback.cpp diff --git a/src/storage/access/ob_aggregated_store.cpp b/src/storage/access/ob_aggregated_store.cpp index fd926b6f5..7619085a3 100644 --- a/src/storage/access/ob_aggregated_store.cpp +++ b/src/storage/access/ob_aggregated_store.cpp @@ -638,7 +638,7 @@ int ObAggregatedStore::init(const ObTableAccessParam ¶m) } else if (OB_FAIL(check_agg_in_row_mode(param.iter_param_))) { LOG_WARN("Failed to check agg in row mode", K(ret)); } else if (agg_flat_row_mode_ && - OB_FAIL(row_buf_.init(*context_.stmt_allocator_, param.iter_param_.get_full_out_col_cnt()))) { + OB_FAIL(row_buf_.init(*context_.stmt_allocator_, param.iter_param_.get_max_out_col_cnt()))) { LOG_WARN("Fail to init datum row buf", K(ret)); } if (OB_FAIL(ret)) { @@ -652,7 +652,7 @@ int ObAggregatedStore::check_agg_in_row_mode(const ObTableIterParam &iter_param) int ret = OB_SUCCESS; int64_t agg_cnt = 0; ObAggCell *cell = nullptr; - const ObTableReadInfo *read_info = nullptr; + const ObITableReadInfo *read_info = nullptr; if (OB_ISNULL(read_info = iter_param.get_read_info())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected null read info", K(ret), K(iter_param)); diff --git a/src/storage/access/ob_block_sample_iterator.cpp b/src/storage/access/ob_block_sample_iterator.cpp index 860860463..b05c3499d 100644 --- a/src/storage/access/ob_block_sample_iterator.cpp +++ b/src/storage/access/ob_block_sample_iterator.cpp @@ -26,8 +26,7 @@ namespace storage */ ObBlockSampleSSTableEndkeyIterator::ObBlockSampleSSTableEndkeyIterator() - : sstable_meta_(nullptr), - macro_count_(0), + : macro_count_(0), micro_count_(0), curr_key_(), tree_cursor_(), @@ -50,7 +49,6 @@ ObBlockSampleSSTableEndkeyIterator::~ObBlockSampleSSTableEndkeyIterator() void ObBlockSampleSSTableEndkeyIterator::reset() { if (is_inited_) { - sstable_meta_ = nullptr; macro_count_ = 0; micro_count_ = 0; tree_cursor_.reset(); @@ -68,7 +66,7 @@ void ObBlockSampleSSTableEndkeyIterator::reset() int ObBlockSampleSSTableEndkeyIterator::open( const ObSSTable &sstable, const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse_scan) { @@ -80,13 +78,12 @@ int ObBlockSampleSSTableEndkeyIterator::open( } else if (OB_UNLIKELY(!sstable.is_valid() || !range.is_valid())) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid sstable", K(ret), K(sstable), K(range)); - } else if (sstable.get_meta().is_empty()) { + } else if (sstable.is_empty()) { is_iter_end_ = true; is_inited_ = true; - } else if (OB_FAIL(tree_cursor_.init(sstable, allocator, &index_read_info))) { + } else if (OB_FAIL(tree_cursor_.init(sstable, allocator, &rowkey_read_info))) { STORAGE_LOG(WARN, "Fail to init index tree cursor", K(ret), K(sstable)); } else { - sstable_meta_ = &sstable.get_meta(); sample_level_ = ObIndexBlockTreeCursor::LEAF; is_reverse_scan_ = is_reverse_scan; @@ -318,8 +315,8 @@ int ObBlockSampleRangeIterator::open( allocator_ = &allocator; sample_range_ = ⦥ is_reverse_scan_ = is_reverse_scan; - datum_utils_ = &get_table_param.tablet_iter_.tablet_handle_.get_obj()->get_full_read_info().get_datum_utils(); - schema_rowkey_column_count_ = get_table_param.tablet_iter_.tablet_handle_.get_obj()->get_full_read_info().get_schema_rowkey_count(); + datum_utils_ = &get_table_param.tablet_iter_.get_tablet()->get_rowkey_read_info().get_datum_utils(); + schema_rowkey_column_count_ = get_table_param.tablet_iter_.get_tablet()->get_rowkey_read_info().get_schema_rowkey_count(); endkey_comparor_.init(*datum_utils_, is_reverse_scan_); if (OB_FAIL(init_and_push_endkey_iterator(get_table_param))) { @@ -397,20 +394,20 @@ int ObBlockSampleRangeIterator::init_and_push_endkey_iterator(ObGetTableParam &g ObITable *table = nullptr; ObSSTable *sstable = nullptr; ObBlockSampleSSTableEndkeyIterator *iter = nullptr; - if (OB_FAIL(get_table_param.tablet_iter_.table_iter_.get_next(table))) { + if (OB_FAIL(get_table_param.tablet_iter_.table_iter()->get_next(table))) { if (OB_LIKELY(OB_ITER_END == ret)) { ret = OB_SUCCESS; break; } else { - STORAGE_LOG(WARN, "Fail to get next table iter", K(ret), K(get_table_param.tablet_iter_.table_iter_)); + STORAGE_LOG(WARN, "Fail to get next table iter", K(ret), K(get_table_param.tablet_iter_.table_iter())); } } else if (!table->is_sstable() || table->is_ddl_mem_sstable()) { } else if (OB_ISNULL(table) || OB_ISNULL(sample_range_) || OB_ISNULL(allocator_)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Unexpected null sstable", K(ret), KP(table), KP(sample_range_), KP(allocator_)); } else if (FALSE_IT(sstable = static_cast(table))) { - } else if (sstable->get_meta().is_empty()) { - STORAGE_LOG(DEBUG, "Skip empty sstable", KPC(sstable), K(sstable->get_meta())); + } else if (sstable->is_empty()) { + STORAGE_LOG(DEBUG, "Skip empty sstable", KPC(sstable)); } else if (OB_ISNULL(buf = allocator_->alloc(sizeof(ObBlockSampleSSTableEndkeyIterator)))) { ret = OB_ALLOCATE_MEMORY_FAILED; STORAGE_LOG(WARN, "Fail to allocate memory for ObBlockSampleSSTableEndkeyIterator", K(ret)); @@ -418,7 +415,7 @@ int ObBlockSampleRangeIterator::init_and_push_endkey_iterator(ObGetTableParam &g iter = new (buf) ObBlockSampleSSTableEndkeyIterator(); if (OB_FAIL(iter->open(*sstable, *sample_range_, - get_table_param.tablet_iter_.tablet_handle_.get_obj()->get_index_read_info(), + get_table_param.tablet_iter_.get_tablet()->get_rowkey_read_info(), *allocator_, is_reverse_scan_))) { STORAGE_LOG(WARN, "Fail to open ObBlockSampleSSTableEndkeyIterator", K(ret), KPC(sstable), KPC(sample_range_)); } else if (OB_FAIL(endkey_iters_.push_back(iter))) { @@ -436,7 +433,7 @@ int ObBlockSampleRangeIterator::init_and_push_endkey_iterator(ObGetTableParam &g } } if (OB_SUCC(ret)) { - get_table_param.tablet_iter_.table_iter_.resume(); + get_table_param.tablet_iter_.table_iter()->resume(); } return ret; @@ -656,7 +653,7 @@ int ObBlockSampleIterator::open(ObMultipleScanMerge &scan_merge, scan_merge_ = &scan_merge; has_opened_range_ = false; access_ctx_ = &access_ctx; - read_info_ = &get_table_param.tablet_iter_.tablet_handle_.get_obj()->get_full_read_info(); + read_info_ = &get_table_param.tablet_iter_.get_tablet()->get_rowkey_read_info(); } return ret; diff --git a/src/storage/access/ob_block_sample_iterator.h b/src/storage/access/ob_block_sample_iterator.h index 963862245..fc4e8481b 100644 --- a/src/storage/access/ob_block_sample_iterator.h +++ b/src/storage/access/ob_block_sample_iterator.h @@ -32,7 +32,7 @@ public: int open( const blocksstable::ObSSTable &sstable, const blocksstable::ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse_scan); int upgrade_to_macro(const blocksstable::ObDatumRange &range); @@ -53,7 +53,6 @@ private: int get_current_block_id(blocksstable::ObMicroBlockId µ_block_id); private: - const blocksstable::ObSSTableMeta *sstable_meta_; int64_t macro_count_; int64_t micro_count_; blocksstable::ObDatumRowkey curr_key_; @@ -162,7 +161,7 @@ private: int open_range(blocksstable::ObDatumRange &range); private: ObTableAccessContext *access_ctx_; - const ObTableReadInfo *read_info_; + const ObITableReadInfo *read_info_; ObMultipleScanMerge *scan_merge_; int64_t block_num_; common::ObArenaAllocator range_allocator_; diff --git a/src/storage/access/ob_dml_param.cpp b/src/storage/access/ob_dml_param.cpp old mode 100644 new mode 100755 index ae01ef077..0c5e7ebe3 --- a/src/storage/access/ob_dml_param.cpp +++ b/src/storage/access/ob_dml_param.cpp @@ -247,7 +247,10 @@ DEF_TO_STRING(ObDMLBaseParam) K_(prelock), KPC_(encrypt_meta), K_(is_batch_stmt), - K_(write_flag)); + K_(write_flag), + K_(spec_seq_no), + K_(snapshot), + K_(check_schema_version)); J_OBJ_END(); return pos; } diff --git a/src/storage/access/ob_dml_param.h b/src/storage/access/ob_dml_param.h old mode 100644 new mode 100755 index 31334defb..67659e967 --- a/src/storage/access/ob_dml_param.h +++ b/src/storage/access/ob_dml_param.h @@ -186,7 +186,8 @@ struct ObDMLBaseParam spec_seq_no_(-1), snapshot_(), direct_insert_task_id_(0), - write_flag_() + write_flag_(), + check_schema_version_(true) { } @@ -217,6 +218,7 @@ struct ObDMLBaseParam int64_t direct_insert_task_id_; // 0 means no direct insert // write flag for inner write processing concurrent_control::ObWriteFlag write_flag_; + bool check_schema_version_; bool is_valid() const { return (timeout_ > 0 && schema_version_ >= 0); } bool is_direct_insert() const { return (direct_insert_task_id_ > 0); } DECLARE_TO_STRING; diff --git a/src/storage/access/ob_fuse_row_cache_fetcher.cpp b/src/storage/access/ob_fuse_row_cache_fetcher.cpp index 3608d51fe..7c6d07e7d 100644 --- a/src/storage/access/ob_fuse_row_cache_fetcher.cpp +++ b/src/storage/access/ob_fuse_row_cache_fetcher.cpp @@ -26,7 +26,7 @@ ObFuseRowCacheFetcher::ObFuseRowCacheFetcher() } int ObFuseRowCacheFetcher::init(const ObTabletID &tablet_id, - const ObTableReadInfo *read_info, + const ObITableReadInfo *read_info, const int64_t tablet_version) { int ret = OB_SUCCESS; diff --git a/src/storage/access/ob_fuse_row_cache_fetcher.h b/src/storage/access/ob_fuse_row_cache_fetcher.h index 309ce71aa..415c24b33 100644 --- a/src/storage/access/ob_fuse_row_cache_fetcher.h +++ b/src/storage/access/ob_fuse_row_cache_fetcher.h @@ -29,13 +29,13 @@ class ObFuseRowCacheFetcher final public: ObFuseRowCacheFetcher(); ~ObFuseRowCacheFetcher() = default; - int init(const ObTabletID &tablet_id, const ObTableReadInfo *read_info, const int64_t tablet_version); + int init(const ObTabletID &tablet_id, const ObITableReadInfo *read_info, const int64_t tablet_version); int get_fuse_row_cache(const blocksstable::ObDatumRowkey &rowkey, blocksstable::ObFuseRowValueHandle &handle); int put_fuse_row_cache(const blocksstable::ObDatumRowkey &rowkey, blocksstable::ObDatumRow &row, const int64_t read_snapshot_version); private: bool is_inited_; ObTabletID tablet_id_; - const ObTableReadInfo *read_info_; + const ObITableReadInfo *read_info_; int64_t tablet_version_; }; diff --git a/src/storage/access/ob_index_sstable_estimator.cpp b/src/storage/access/ob_index_sstable_estimator.cpp index 2b4947211..c890191f1 100644 --- a/src/storage/access/ob_index_sstable_estimator.cpp +++ b/src/storage/access/ob_index_sstable_estimator.cpp @@ -66,7 +66,6 @@ ObIndexBlockScanEstimator::~ObIndexBlockScanEstimator() micro_handles_[i].reset(); } index_block_data_.reset(); - data_read_info_.reset(); index_block_row_scanner_.reset(); } @@ -80,17 +79,15 @@ int ObIndexBlockScanEstimator::estimate_row_count(ObPartitionEst &part_est) if (OB_UNLIKELY(!context_.is_valid())) { ret = common::OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "estimate context is not valid", K(ret), K(context_)); - } else if (OB_FAIL(construct_rowkey_read_info())) { - STORAGE_LOG(WARN, "Failed to init rowkey column info", K(ret)); } else if (OB_FAIL(index_block_row_scanner_.init( agg_projector, agg_column_schema, - &context_.tablet_handle_.get_obj()->get_index_read_info(), + context_.tablet_handle_.get_obj()->get_rowkey_read_info().get_datum_utils(), allocator_, context_.query_flag_, context_.sstable_.get_macro_offset()))) { STORAGE_LOG(WARN, "Failed to init index block row scanner", K(ret), K(agg_projector), K(agg_column_schema)); - } else if (OB_FAIL(context_.sstable_.get_index_tree_root(context_.tablet_handle_.get_obj()->get_index_read_info(), root_index_block_))) { + } else if (OB_FAIL(context_.sstable_.get_index_tree_root(root_index_block_))) { STORAGE_LOG(WARN, "Failed to get index tree root", K(ret)); } else if (OB_FAIL(cal_total_row_count(result))) { STORAGE_LOG(WARN, "Failed to get total_row_count_delta", K(ret), K(root_index_block_)); @@ -273,9 +270,7 @@ int ObIndexBlockScanEstimator::goto_next_level( } else { index_block_data_.reset(); index_block_row_scanner_.reuse(); - if (OB_FAIL(micro_handle.get_index_block_data( - context_.tablet_handle_.get_obj()->get_index_read_info(), - index_block_data_))) { + if (OB_FAIL(micro_handle.get_index_block_data(index_block_data_))) { STORAGE_LOG(WARN, "Failed to get index block data", K(ret), K(micro_handle)); } else if (OB_FAIL(index_block_row_scanner_.open( micro_index_info.get_macro_id(), index_block_data_, range, 0, true, true))) { @@ -300,8 +295,6 @@ int ObIndexBlockScanEstimator::prefetch_index_block_data( micro_index_info.get_macro_id(), micro_index_info, context_.query_flag_, - context_.tablet_handle_.get_obj()->get_full_read_info(), - context_.tablet_handle_, micro_handle.io_handle_))) { STORAGE_LOG(WARN, "Failed to prefetch data micro block", K(ret), K(micro_index_info)); } @@ -310,8 +303,6 @@ int ObIndexBlockScanEstimator::prefetch_index_block_data( micro_index_info.get_macro_id(), micro_index_info, context_.query_flag_, - context_.tablet_handle_.get_obj()->get_index_read_info(), - context_.tablet_handle_, micro_handle.io_handle_))) { STORAGE_LOG(WARN, "Failed to prefetch data micro block", K(ret), K(micro_index_info)); } @@ -341,14 +332,13 @@ int ObIndexBlockScanEstimator::estimate_data_block_row_count( if (OB_FAIL(micro_handle.get_data_block_data(macro_reader_, block_data))) { STORAGE_LOG(WARN, "Failed to get block data", K(ret), K(micro_handle)); } else if (OB_FAIL(block_scanner.estimate_row_count( - data_read_info_, + context_.tablet_handle_.get_obj()->get_rowkey_read_info(), block_data, range, consider_multi_version, est))) { if (OB_BEYOND_THE_RANGE != ret) { - STORAGE_LOG(WARN, "Failed to estimate row count", K(ret), - K(data_read_info_), K(block_data), K(range)); + STORAGE_LOG(WARN, "Failed to estimate row count", K(ret), K(block_data), K(range)); } else { ret = OB_ITER_END; } @@ -356,33 +346,5 @@ int ObIndexBlockScanEstimator::estimate_data_block_row_count( return ret; } -int ObIndexBlockScanEstimator::construct_rowkey_read_info() -{ - int ret = OB_SUCCESS; - common::ObSEArray data_cols; - if (OB_UNLIKELY(!context_.is_valid())) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "Unexpected index read info", K(ret), K_(context)); - } else { - const ObTableReadInfo &read_info = context_.tablet_handle_.get_obj()->get_full_read_info(); - int64_t schema_rowkey_cnt = read_info.get_schema_rowkey_count(); - const ObColDescIArray &cols = read_info.get_columns_desc(); - for (int64_t i = 0; OB_SUCC(ret) && i < schema_rowkey_cnt; i++) { - if (OB_FAIL(data_cols.push_back(cols.at(i)))) { - STORAGE_LOG(WARN, "Failed to push_back data_cols", K(ret), K(i)); - } - } - if (OB_SUCC(ret) && OB_FAIL(data_read_info_.init( - allocator_, - read_info.get_schema_column_count(), - schema_rowkey_cnt, - lib::is_oracle_mode(), - data_cols))) { - STORAGE_LOG(WARN, "Failed to init data_read_info", K(ret)); - } - } - return ret; -} - } } diff --git a/src/storage/access/ob_index_sstable_estimator.h b/src/storage/access/ob_index_sstable_estimator.h index 6fc4297ad..c0bf825ba 100644 --- a/src/storage/access/ob_index_sstable_estimator.h +++ b/src/storage/access/ob_index_sstable_estimator.h @@ -95,7 +95,6 @@ private: ObMicroBlockDataHandle µ_handle, bool consider_multi_version, ObPartitionEst &est); - int construct_rowkey_read_info(); ObMicroBlockDataHandle &get_read_handle() { return micro_handles_[level_++ % DEFAULT_GET_MICRO_DATA_HANDLE_CNT]; @@ -109,7 +108,6 @@ private: ObMicroBlockDataHandle micro_handles_[DEFAULT_GET_MICRO_DATA_HANDLE_CNT]; blocksstable::ObMicroBlockData index_block_data_; const ObIndexSSTableEstimateContext &context_; - ObTableReadInfo data_read_info_; common::ObArenaAllocator allocator_; }; diff --git a/src/storage/access/ob_index_tree_prefetcher.cpp b/src/storage/access/ob_index_tree_prefetcher.cpp old mode 100644 new mode 100755 index abe02cba4..a1deb0d54 --- a/src/storage/access/ob_index_tree_prefetcher.cpp +++ b/src/storage/access/ob_index_tree_prefetcher.cpp @@ -32,11 +32,12 @@ void ObIndexTreePrefetcher::reset() rescan_cnt_ = 0; data_version_ = 0; sstable_ = nullptr; + sstable_meta_handle_.reset(); data_block_cache_ = nullptr; index_block_cache_ = nullptr; iter_param_ = nullptr; access_ctx_ = nullptr; - index_read_info_ = nullptr; + datum_utils_ = nullptr; index_scanner_.reset(); for (int64_t i = 0; i < DEFAULT_GET_MICRO_DATA_HANDLE_CNT; ++i) { micro_handles_[i].reset(); @@ -47,7 +48,6 @@ void ObIndexTreePrefetcher::reset() void ObIndexTreePrefetcher::reuse() { index_scanner_.reset(); - index_read_info_ = nullptr; } int ObIndexTreePrefetcher::init( @@ -67,11 +67,13 @@ int ObIndexTreePrefetcher::init( LOG_WARN("Invalid argument to init ObStoreRowIterator", K(ret), K(iter_type)); } else if (OB_FAIL(micro_block_handle_mgr_.init(false, true, *access_ctx.stmt_allocator_))) { LOG_WARN("failed to init block handle mgr", K(ret)); + } else if (OB_FAIL(sstable.get_meta(sstable_meta_handle_))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); } else { sstable_ = &sstable; access_ctx_ = &access_ctx; iter_param_ = &iter_param; - index_read_info_ = iter_param.get_full_read_info()->get_index_read_info(); + datum_utils_ = &(iter_param.get_read_info()->get_datum_utils()); data_version_ = sstable_->get_data_version(); data_block_cache_ = &(OB_STORE_CACHE.get_block_cache()); index_block_cache_ = &(OB_STORE_CACHE.get_index_block_cache()); @@ -82,8 +84,8 @@ int ObIndexTreePrefetcher::init( int ObIndexTreePrefetcher::switch_context( const int iter_type, - const ObTableReadInfo &index_read_info, ObSSTable &sstable, + const ObStorageDatumUtils &datum_utils, ObTableAccessContext &access_ctx, const void *query_range) { @@ -95,10 +97,12 @@ int ObIndexTreePrefetcher::switch_context( } else if (OB_UNLIKELY(ObStoreRowIterator::IteratorSingleGet != iter_type)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument to init ObStoreRowIterator", K(ret), K(iter_type)); + } else if (OB_FAIL(sstable.get_meta(sstable_meta_handle_))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); } else { sstable_ = &sstable; + datum_utils_ = &datum_utils; access_ctx_ = &access_ctx; - index_read_info_ = &index_read_info; data_version_ = sstable_->get_data_version(); if (!is_rescan_) { is_rescan_ = true; @@ -149,7 +153,7 @@ int ObIndexTreePrefetcher::lookup_in_cache(ObSSTableReadHandle &read_handle) } else if (OB_UNLIKELY(!read_handle.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument", K(ret), K(read_handle)); - } else if (sstable_->get_meta().is_empty()) { + } else if (sstable_->is_empty()) { //empty sstable found = true; read_handle.row_state_ = ObSSTableRowState::NOT_EXIST; @@ -157,7 +161,7 @@ int ObIndexTreePrefetcher::lookup_in_cache(ObSSTableReadHandle &read_handle) if (OB_SUCC(ret) && !found && access_ctx_->enable_get_row_cache()) { ObRowCacheKey key(MTL_ID(), iter_param_->tablet_id_, *read_handle.rowkey_, - index_read_info_->get_datum_utils(), data_version_, sstable_->get_key().table_type_); + *datum_utils_, data_version_, sstable_->get_key().table_type_); if (OB_FAIL(ObStorageCacheSuite::get_instance().get_row_cache().get_row(key, read_handle.row_handle_))) { if (OB_UNLIKELY(OB_ENTRY_NOT_EXIST != ret)) { LOG_WARN("Fail to get row from row cache", K(ret), K(key)); @@ -191,7 +195,7 @@ int ObIndexTreePrefetcher::lookup_in_index_tree(ObSSTableReadHandle &read_handle } else if (OB_UNLIKELY(!read_handle.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument", K(ret), K(read_handle)); - } else if (OB_FAIL(sstable_->get_index_tree_root(*index_read_info_, index_block_))) { + } else if (OB_FAIL(sstable_->get_index_tree_root(index_block_))) { LOG_WARN("Fail to get index block root", K(ret)); } else if (OB_FAIL(init_index_scanner(index_scanner_))) { LOG_WARN("Fail to init index scanner", K(ret)); @@ -224,9 +228,7 @@ int ObIndexTreePrefetcher::lookup_in_index_tree(ObSSTableReadHandle &read_handle ++level; if (OB_FAIL(prefetch_block_data(index_block_info, curr_handle, false))) { LOG_WARN("Fail to prefetch block data", K(ret)); - } else if (OB_FAIL(curr_handle.get_index_block_data( - *index_read_info_, - index_block_))) { + } else if (OB_FAIL(curr_handle.get_index_block_data(index_block_))) { LOG_WARN("Fail to get index block data", K(ret), K(curr_handle)); } else if (OB_FAIL(index_scanner_.open( index_block_info.get_macro_id(), @@ -257,6 +259,21 @@ int ObIndexTreePrefetcher::lookup_in_index_tree(ObSSTableReadHandle &read_handle return ret; } +int ObIndexTreePrefetcher::init_index_scanner(ObIndexBlockRowScanner &index_scanner) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(index_scanner.init( + agg_projector_, + agg_column_schema_, + *datum_utils_, + *access_ctx_->stmt_allocator_, + access_ctx_->query_flag_, + sstable_->get_macro_offset()))) { + LOG_WARN("init index scanner fail", K(ret), KPC(sstable_)); + } + return ret; +} + int ObIndexTreePrefetcher::check_bloom_filter(const ObMicroIndexInfo &index_info, ObSSTableReadHandle &read_handle) { int ret = OB_SUCCESS; @@ -271,7 +288,7 @@ int ObIndexTreePrefetcher::check_bloom_filter(const ObMicroIndexInfo &index_info MTL_ID(), index_info.get_macro_id(), *read_handle.rowkey_, - index_read_info_->get_datum_utils(), + *datum_utils_, is_contain)))) { if (OB_UNLIKELY(OB_ENTRY_NOT_EXIST != temp_ret)) { LOG_WARN("Fail to check bloomfilter", K(temp_ret)); @@ -342,29 +359,21 @@ int ObIndexTreePrefetcher::prefetch_block_data( if (need_submit_io) { ObMacroBlockHandle macro_handle; if (is_data) { - const ObTableReadInfo *data_read_info = iter_param_->get_full_read_info(); - if (OB_ISNULL(data_read_info)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Unexpected null full_col_descs", K(ret), KPC_(iter_param)); - } else if (OB_FAIL(data_block_cache_->prefetch( + if (OB_FAIL(data_block_cache_->prefetch( tenant_id, macro_id, index_block_info, access_ctx_->query_flag_, - *data_read_info, - iter_param_->tablet_handle_, macro_handle))) { - LOG_WARN("Fail to prefetch micro block", K(ret), K(index_block_info), K(macro_handle), K(micro_handle), KPC(data_read_info)); + LOG_WARN("Fail to prefetch micro block", K(ret), K(index_block_info), K(macro_handle), K(micro_handle)); } } else if (OB_FAIL(index_block_cache_->prefetch( tenant_id, macro_id, index_block_info, access_ctx_->query_flag_, - *index_read_info_, - iter_param_->tablet_handle_, macro_handle))) { - LOG_WARN("Fail to prefetch micro block", K(ret), K(index_block_info), K(micro_handle), KPC_(index_read_info)); + LOG_WARN("Fail to prefetch micro block", K(ret), K(index_block_info), K(micro_handle)); } if (OB_SUCC(ret) && ObSSTableMicroBlockState::UNKNOWN_STATE == micro_handle.block_state_) { micro_handle.tenant_id_ = tenant_id; @@ -427,17 +436,19 @@ int ObIndexTreeMultiPrefetcher::init( } else if (OB_UNLIKELY(ObStoreRowIterator::IteratorMultiGet != iter_type)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument", K(ret), K(iter_type)); + } else if (OB_FAIL(sstable.get_meta(sstable_meta_handle_))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); } else { sstable_ = &sstable; access_ctx_ = &access_ctx; iter_param_ = &iter_param; - index_read_info_ = iter_param.get_full_read_info()->get_index_read_info(); - data_version_ = sstable_->get_data_version(); + data_version_ = sstable_->is_major_sstable() ? sstable_->get_snapshot_version() : sstable_->get_key().get_end_scn().get_val_for_tx(); data_block_cache_ = &(ObStorageCacheSuite::get_instance().get_block_cache()); index_block_cache_ = &(ObStorageCacheSuite::get_instance().get_index_block_cache()); ext_read_handles_.set_allocator(access_ctx.stmt_allocator_); rowkeys_ = static_cast *> (query_range); - index_tree_height_ = sstable_->get_meta().get_index_tree_height(); + index_tree_height_ = sstable_meta_handle_.get_sstable_meta().get_index_tree_height(); + datum_utils_ = &(iter_param.get_read_info()->get_datum_utils()); int32_t range_count = rowkeys_->count(); max_handle_prefetching_cnt_ = min(range_count, MAX_MULTIGET_MICRO_DATA_HANDLE_CNT); if (0 == range_count) { @@ -456,8 +467,8 @@ int ObIndexTreeMultiPrefetcher::init( int ObIndexTreeMultiPrefetcher::switch_context( const int iter_type, - const ObTableReadInfo &index_read_info, ObSSTable &sstable, + const ObStorageDatumUtils &datum_utils, ObTableAccessContext &access_ctx, const void *query_range) { @@ -469,13 +480,15 @@ int ObIndexTreeMultiPrefetcher::switch_context( } else if (OB_UNLIKELY(ObStoreRowIterator::IteratorMultiGet != iter_type)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument", K(ret), K(iter_type)); + } else if (OB_FAIL(sstable.get_meta(sstable_meta_handle_))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); } else { sstable_ = &sstable; access_ctx_ = &access_ctx; - data_version_ = sstable_->get_data_version(); + datum_utils_ = &datum_utils; + data_version_ = sstable_->is_major_sstable() ? sstable_->get_snapshot_version() : sstable_->get_key().get_end_scn().get_val_for_tx(); rowkeys_ = static_cast *> (query_range); - index_read_info_ = &index_read_info; - index_tree_height_ = sstable_->get_meta().get_index_tree_height(); + index_tree_height_ = sstable_meta_handle_.get_sstable_meta().get_index_tree_height(); max_handle_prefetching_cnt_ = min(rowkeys_->count(), MAX_MULTIGET_MICRO_DATA_HANDLE_CNT); if (OB_FAIL(ext_read_handles_.prepare_reallocate(max_handle_prefetching_cnt_))) { LOG_WARN("Fail to init read_handles", K(ret), K(max_handle_prefetching_cnt_)); @@ -495,7 +508,7 @@ int ObIndexTreeMultiPrefetcher::switch_context( } if (OB_SUCC(ret)) { if (index_scanner_.is_valid()) { - index_scanner_.switch_context(&index_read_info, sstable.get_macro_offset()); + index_scanner_.switch_context(sstable, datum_utils); } } } @@ -526,7 +539,7 @@ int ObIndexTreeMultiPrefetcher::multi_prefetch() if (OB_FAIL(lookup_in_cache(read_handle))) { LOG_WARN("Failed to lookup_in_cache", K(ret)); } else if (ObSSTableRowState::IN_BLOCK == read_handle.row_state_) { - if (OB_FAIL(sstable_->get_index_tree_root(*index_read_info_, index_block_))) { + if (OB_FAIL(sstable_->get_index_tree_root(index_block_))) { LOG_WARN("Fail to get index block root", K(ret)); } else if (!index_scanner_.is_valid() && OB_FAIL(init_index_scanner(index_scanner_))) { LOG_WARN("Fail to init index scanner", K(ret)); @@ -562,14 +575,14 @@ int ObIndexTreeMultiPrefetcher::multi_prefetch() //not in cache yet, stop this rowkey prefetching if it's not the rowkey to be feteched ret = OB_SUCCESS; if (is_rowkey_to_fetched) { - if (OB_FAIL(read_handle.micro_handle_->get_index_block_data(*index_read_info_, index_block_))) { + if (OB_FAIL(read_handle.micro_handle_->get_index_block_data(index_block_))) { LOG_WARN("Fail to get index block data", K(ret), KPC(read_handle.micro_handle_)); } } else { stop_prefetch = true; } } else if (FALSE_IT(read_handle.set_cur_micro_handle(next_handle))) { - } else if (OB_FAIL(read_handle.micro_handle_->get_cached_index_block_data(*index_read_info_, index_block_))) { + } else if (OB_FAIL(read_handle.micro_handle_->get_cached_index_block_data(index_block_))) { LOG_WARN("Fail to get cached index block data", K(ret), KPC(read_handle.micro_handle_)); } if (OB_SUCC(ret) && !stop_prefetch) { @@ -626,12 +639,12 @@ int ObIndexTreeMultiPrefetcher::drill_down( } else if (force_prefetch || ObSSTableMicroBlockState::IN_BLOCK_CACHE == next_handle.block_state_) { if (ObSSTableMicroBlockState::IN_BLOCK_CACHE == next_handle.block_state_) { LOG_DEBUG("cur handle is in cache", K(read_handle), K(index_block_info), K(next_handle)); - if (OB_FAIL(next_handle.get_cached_index_block_data(*index_read_info_, index_block_))) { + if (OB_FAIL(next_handle.get_cached_index_block_data(index_block_))) { LOG_WARN("Fail to get index block data", K(ret), K(next_handle)); } } else { LOG_DEBUG("cur handle is not in cache, force prefetch", K(read_handle), K(index_block_info), K(next_handle)); - if (OB_FAIL(next_handle.get_index_block_data(*index_read_info_, index_block_))) { + if (OB_FAIL(next_handle.get_index_block_data(index_block_))) { LOG_WARN("Fail to get index block data", K(ret), K(next_handle)); } } @@ -721,7 +734,7 @@ int ObIndexTreeMultiPassPrefetcher::i if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("ObIndexTreeMultiPassPrefetcher has been inited", K(ret)); - } else if (sstable.get_meta().is_empty()) { + } else if (sstable.is_empty()) { is_prefetch_end_ = true; is_inited_ = true; } else { @@ -731,7 +744,7 @@ int ObIndexTreeMultiPassPrefetcher::i tree_handles_.set_allocator(access_ctx.stmt_allocator_); read_handles_.set_allocator(access_ctx.stmt_allocator_); max_micro_handle_cnt_ = DEFAULT_SCAN_MICRO_DATA_HANDLE_CNT; - index_read_info_ = iter_param.get_full_read_info()->get_index_read_info(); + datum_utils_ = &(iter_param.get_read_info()->get_datum_utils()); bool is_multi_range = false; if (OB_FAIL(init_basic_info(iter_type, sstable, access_ctx, query_range, is_multi_range))) { LOG_WARN("Fail to init basic info", K(ret), K(access_ctx)); @@ -754,8 +767,8 @@ int ObIndexTreeMultiPassPrefetcher::i template int ObIndexTreeMultiPassPrefetcher::switch_context( const int iter_type, - const ObTableReadInfo &index_read_info, ObSSTable &sstable, + const ObStorageDatumUtils &datum_utils, ObTableAccessContext &access_ctx, const void *query_range) { @@ -764,7 +777,7 @@ int ObIndexTreeMultiPassPrefetcher::s if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); - } else if (sstable.get_meta().is_empty()) { + } else if (sstable.is_empty()) { is_prefetch_end_ = true; } else if (OB_FAIL(init_basic_info(iter_type, sstable, access_ctx, query_range, is_multi_range))) { LOG_WARN("Fail to init basic info", K(ret), K(access_ctx)); @@ -780,11 +793,10 @@ int ObIndexTreeMultiPassPrefetcher::s } } if (OB_SUCC(ret)) { - index_read_info_ = &index_read_info; + datum_utils_ = &datum_utils; for (int64_t level = 0; OB_SUCC(ret) && level < index_tree_height_; level++) { if (tree_handles_[level].index_scanner_.is_valid()) { - tree_handles_[level].index_scanner_.switch_context( - &index_read_info, sstable.get_macro_offset()); + tree_handles_[level].index_scanner_.switch_context(sstable, datum_utils); } else if (OB_FAIL(init_index_scanner(tree_handles_[level].index_scanner_))) { LOG_WARN("Fail to init index_scanner", K(ret), K(level)); } @@ -810,7 +822,6 @@ int ObIndexTreeMultiPassPrefetcher::i data_version_ = sstable_->get_data_version(); cur_level_ = 0; iter_type_ = iter_type; - index_tree_height_ = sstable_->get_meta().get_index_tree_height(); need_check_prefetch_depth_ = (ObStoreRowIterator::IteratorScan == iter_type || ObStoreRowIterator::IteratorMultiScan == iter_type) && iter_param_->limit_prefetch_ && @@ -853,6 +864,9 @@ int ObIndexTreeMultiPassPrefetcher::i LOG_WARN("invalid store iterator type", K(ret), K(iter_type)); } if (OB_FAIL(ret)) { + } else if (OB_FAIL(sstable.get_meta(sstable_meta_handle_))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); + } else if (FALSE_IT(index_tree_height_ = sstable_meta_handle_.get_sstable_meta().get_index_tree_height())) { } else if (1 >= index_tree_height_ || MAX_INDEX_TREE_HEIGHT < index_tree_height_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected index tree height", K(ret), K(index_tree_height_), K(MAX_INDEX_TREE_HEIGHT)); @@ -914,7 +928,6 @@ int ObIndexTreeMultiPassPrefetcher::p for (int16_t level = 1; OB_SUCC(ret) && level < border_level; level++) { if (tree_handles_[level].is_prefetch_end()) { } else if (OB_FAIL(tree_handles_[level].prefetch( - *index_read_info_, border_rowkey_, level, *this))) { @@ -946,7 +959,7 @@ int ObIndexTreeMultiPassPrefetcher::t if (OB_FAIL(lookup_in_cache(read_handle))) { LOG_WARN("Failed to lookup_in_cache", K(ret)); } else if (ObSSTableRowState::IN_BLOCK == read_handle.row_state_) { - if (OB_FAIL(sstable_->get_index_tree_root(*index_read_info_, index_block_))) { + if (OB_FAIL(sstable_->get_index_tree_root(index_block_))) { LOG_WARN("Fail to get index block root", K(ret)); } else if (OB_FAIL(tree_handle.index_scanner_.open( ObIndexBlockRowHeader::DEFAULT_IDX_ROW_MACRO_ID, @@ -961,7 +974,7 @@ int ObIndexTreeMultiPassPrefetcher::t } else { // scan read_handle.row_state_ = ObSSTableRowState::IN_BLOCK; - if (OB_FAIL(sstable_->get_index_tree_root(*index_read_info_, index_block_))) { + if (OB_FAIL(sstable_->get_index_tree_root(index_block_))) { LOG_WARN("Fail to get index tree root", K(ret)); } else if (OB_FAIL(tree_handle.index_scanner_.open( ObIndexBlockRowHeader::DEFAULT_IDX_ROW_MACRO_ID, @@ -1086,8 +1099,7 @@ int ObIndexTreeMultiPassPrefetcher::d } else { while (OB_SUCC(ret)) { if (index_tree_height_ - 1 == cur_level_) { - } else if (OB_FAIL(tree_handles_[cur_level_ + 1].forward(*index_read_info_, - border_rowkey_, + } else if (OB_FAIL(tree_handles_[cur_level_ + 1].forward(border_rowkey_, iter_param_->has_lob_column_out()))) { if (OB_UNLIKELY(OB_ITER_END != ret)) { LOG_WARN("fail to consume tree handle", K(ret), K(cur_level_), K(tree_handles_[cur_level_ + 1])); @@ -1252,7 +1264,7 @@ int ObIndexTreeMultiPassPrefetcher::c LOG_WARN("Invalid argument", K(ret), K(start_pos), K(end_pos)); } else if (!can_blockscan_) { } else { - const ObStorageDatumUtils &datum_utils = index_read_info_->get_datum_utils(); + const ObStorageDatumUtils &datum_utils = *datum_utils_; int64_t start_idx = start_pos % max_micro_handle_cnt_; int64_t end_idx = end_pos % max_micro_handle_cnt_; if (!is_reverse) { @@ -1416,10 +1428,8 @@ int ObIndexTreeMultiPassPrefetcher::c } //////////////////////////////////////// ObIndexTreeLevelHandle ////////////////////////////////////////////// - template int ObIndexTreeMultiPassPrefetcher::ObIndexTreeLevelHandle::prefetch( - const ObTableReadInfo &read_info, const ObDatumRowkey &border_rowkey, const int64_t level, ObIndexTreeMultiPassPrefetcher &prefetcher) @@ -1447,7 +1457,6 @@ int ObIndexTreeMultiPassPrefetcher::O int8_t prefetch_idx = (prefetch_idx_ + 1) % INDEX_TREE_PREFETCH_DEPTH; ObMicroIndexInfo &index_info = index_block_read_handles_[prefetch_idx].index_info_; if (OB_FAIL(parent.get_next_index_row( - read_info, border_rowkey, index_info, prefetcher.iter_param_->has_lob_column_out()))) { @@ -1490,7 +1499,6 @@ int ObIndexTreeMultiPassPrefetcher::O template int ObIndexTreeMultiPassPrefetcher::ObIndexTreeLevelHandle::forward( - const ObTableReadInfo &read_info, const ObDatumRowkey &border_rowkey, const bool has_lob_out) { @@ -1502,9 +1510,7 @@ int ObIndexTreeMultiPassPrefetcher::O index_scanner_.reuse(); int8_t fetch_idx = fetch_idx_ % INDEX_TREE_PREFETCH_DEPTH; ObMicroIndexInfo &index_info = index_block_read_handles_[fetch_idx].index_info_; - if (OB_FAIL(index_block_read_handles_[fetch_idx].data_handle_.get_index_block_data( - read_info, - index_block_))) { + if (OB_FAIL(index_block_read_handles_[fetch_idx].data_handle_.get_index_block_data(index_block_))) { LOG_WARN("Fail to get index block data", K(ret), KPC(this)); } else if (index_info.is_get()) { if (OB_FAIL(index_scanner_.open( diff --git a/src/storage/access/ob_index_tree_prefetcher.h b/src/storage/access/ob_index_tree_prefetcher.h index 33929e288..2454b9145 100644 --- a/src/storage/access/ob_index_tree_prefetcher.h +++ b/src/storage/access/ob_index_tree_prefetcher.h @@ -118,13 +118,14 @@ public: rescan_cnt_(0), data_version_(0), sstable_(nullptr), + sstable_meta_handle_(), data_block_cache_(nullptr), index_block_cache_(nullptr), micro_block_handle_mgr_(), index_block_(), iter_param_(nullptr), access_ctx_(nullptr), - index_read_info_(nullptr), + datum_utils_(nullptr), index_scanner_(), micro_handles_(), macro_id_() @@ -141,24 +142,15 @@ public: const void *query_range); virtual int switch_context( const int iter_type, - const ObTableReadInfo &index_read_info, ObSSTable &sstable, + const ObStorageDatumUtils &datum_utils, ObTableAccessContext &access_ctx, const void *query_range); int single_prefetch(ObSSTableReadHandle &read_handle); OB_INLINE bool is_valid() { return is_inited_; } VIRTUAL_TO_STRING_KV(K_(data_version), K_(index_scanner)); protected: - OB_INLINE int init_index_scanner(ObIndexBlockRowScanner &index_scanner) - { - return index_scanner.init( - agg_projector_, - agg_column_schema_, - index_read_info_, - *access_ctx_->stmt_allocator_, - access_ctx_->query_flag_, - sstable_->get_macro_offset()); - } + int init_index_scanner(ObIndexBlockRowScanner &index_scanner); int check_bloom_filter(const ObMicroIndexInfo &index_info, ObSSTableReadHandle &read_handle); int prefetch_block_data( ObMicroIndexInfo &index_block_info, @@ -179,13 +171,14 @@ protected: int64_t rescan_cnt_; int64_t data_version_; ObSSTable *sstable_; + ObSSTableMetaHandle sstable_meta_handle_; ObDataMicroBlockCache *data_block_cache_; ObIndexMicroBlockCache *index_block_cache_; ObMicroBlockHandleMgr micro_block_handle_mgr_; ObMicroBlockData index_block_; const ObTableIterParam *iter_param_; ObTableAccessContext *access_ctx_; - const ObTableReadInfo *index_read_info_; + const ObStorageDatumUtils *datum_utils_; common::ObFixedArray agg_projector_; common::ObFixedArray agg_column_schema_; static const int64_t DEFAULT_GET_MICRO_DATA_HANDLE_CNT = 2; @@ -268,8 +261,8 @@ public: const void *query_range) override; virtual int switch_context( const int iter_type, - const ObTableReadInfo &index_read_info, ObSSTable &sstable, + const ObStorageDatumUtils &datum_utils, ObTableAccessContext &access_ctx, const void *query_range) override; int multi_prefetch(); @@ -343,8 +336,8 @@ public: const void *query_range) override final; virtual int switch_context( const int iter_type, - const ObTableReadInfo &index_read_info, ObSSTable &sstable, + const ObStorageDatumUtils &datum_utils, ObTableAccessContext &access_ctx, const void *query_range) override final; int prefetch(); @@ -488,7 +481,6 @@ private: return ret; } OB_INLINE int get_next_index_row( - const ObTableReadInfo &read_info, const blocksstable::ObDatumRowkey &border_rowkey, ObMicroIndexInfo &block_info, const bool has_lob_out) @@ -499,7 +491,7 @@ private: if (OB_UNLIKELY(OB_ITER_END != ret)) { STORAGE_LOG(WARN, "Fail to get_next index row", K(ret), K_(index_scanner)); } else if (fetch_idx_ < prefetch_idx_) { - if (OB_FAIL(forward(read_info, border_rowkey, has_lob_out))) { + if (OB_FAIL(forward(border_rowkey, has_lob_out))) { STORAGE_LOG(WARN, "Fail to forward index tree handle", K(ret)); } } @@ -524,12 +516,10 @@ private: return index_block_read_handles_[fetch_idx_ % INDEX_TREE_PREFETCH_DEPTH]; } int prefetch( - const ObTableReadInfo &read_info, const blocksstable::ObDatumRowkey &border_rowkey, const int64_t level, ObIndexTreeMultiPassPrefetcher &prefetcher); int forward( - const ObTableReadInfo &read_info, const blocksstable::ObDatumRowkey &border_rowkey, const bool has_lob_out); OB_INLINE int check_blockscan(const blocksstable::ObDatumRowkey &border_rowkey) diff --git a/src/storage/access/ob_multiple_merge.cpp b/src/storage/access/ob_multiple_merge.cpp index 00811ea38..5fb661d9a 100644 --- a/src/storage/access/ob_multiple_merge.cpp +++ b/src/storage/access/ob_multiple_merge.cpp @@ -144,7 +144,7 @@ int ObMultipleMerge::init( unprojected_row_.count_ = 0; get_table_param_ = get_table_param; if (OB_SUCC(ret)) { - const ObTableReadInfo *read_info = access_param_->iter_param_.get_read_info(); + const ObITableReadInfo *read_info = access_param_->iter_param_.get_read_info(); if (OB_ISNULL(read_info)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Unexpected null read_info", K(ret)); @@ -228,7 +228,7 @@ int ObMultipleMerge::save_curr_rowkey() { int ret = OB_SUCCESS; // TODO remove this after delete store_rowkey from memtable - const ObColDescIArray *col_descs = nullptr; + const ObColDescIArray *rowkey_col_descs = nullptr; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; @@ -244,10 +244,10 @@ int ObMultipleMerge::save_curr_rowkey() STORAGE_LOG(WARN, "Failed to assign tmp rowkey", K(ret), K_(unprojected_row)); } else if (OB_FAIL(tmp_rowkey.deep_copy(curr_rowkey_, *access_ctx_->allocator_))) { STORAGE_LOG(WARN, "fail to deep copy rowkey", K(ret)); - } else if (OB_ISNULL(col_descs = access_param_->iter_param_.get_out_col_descs())) { + } else if (OB_ISNULL(rowkey_col_descs = access_param_->iter_param_.get_out_col_descs())) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(WARN, "Unexpected null out cols", K(ret)); - } else if (OB_FAIL(curr_rowkey_.prepare_memtable_readable(*col_descs, *access_ctx_->allocator_))) { + } else if (OB_FAIL(curr_rowkey_.prepare_memtable_readable(*rowkey_col_descs, *access_ctx_->allocator_))) { STORAGE_LOG(WARN, "Fail to transfer store rowkey", K(ret), K(curr_rowkey_)); } else { curr_scan_index_ = unprojected_row_.scan_index_; @@ -1114,35 +1114,31 @@ int ObMultipleMerge::prepare_read_tables(bool refresh) 0 != access_ctx_->trans_version_range_.base_version_)) { ret = OB_ERR_SYS; LOG_WARN("base version should be 0", K(ret), K(access_ctx_->trans_version_range_.base_version_)); - } else if (!refresh && get_table_param_.tablet_iter_.table_iter_.is_valid()) { - if (OB_FAIL(prepare_tables_from_iterator(get_table_param_.tablet_iter_.table_iter_))) { - LOG_WARN("prepare tables fail", K(ret), K(get_table_param_.tablet_iter_.table_iter_)); + } else if (!refresh && get_table_param_.tablet_iter_.table_iter()->is_valid()) { + if (OB_FAIL(prepare_tables_from_iterator(*get_table_param_.tablet_iter_.table_iter()))) { + LOG_WARN("prepare tables fail", K(ret), K(get_table_param_.tablet_iter_.table_iter())); } - } else if (OB_FAIL(FALSE_IT(get_table_param_.tablet_iter_.table_iter_.reset()))) { + } else if (OB_FAIL(FALSE_IT(get_table_param_.tablet_iter_.table_iter()->reset()))) { } else { - ObTabletHandle &tablet_handle = get_table_param_.tablet_iter_.tablet_handle_; - if (OB_UNLIKELY(!tablet_handle.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid tablet handle", K(ret), K_(get_table_param), KP_(access_param)); - } else if (OB_UNLIKELY(get_table_param_.frozen_version_ != -1)) { + if (OB_UNLIKELY(get_table_param_.frozen_version_ != -1)) { if (!get_table_param_.sample_info_.is_no_sample()) { ret = OB_NOT_SUPPORTED; LOG_WARN("sample query does not support frozen_version", K(ret), K_(get_table_param), KP_(access_param)); - } else if (OB_FAIL(tablet_handle.get_obj()->get_read_major_sstable(get_table_param_.frozen_version_, get_table_param_.tablet_iter_))) { + } else if (OB_FAIL(get_table_param_.tablet_iter_.refresh_read_tables_from_tablet( + get_table_param_.frozen_version_, false/*allow_not_ready*/, true/*major only*/))) { LOG_WARN("get table iterator fail", K(ret), K_(get_table_param), KP_(access_param)); } - } else if (OB_FAIL(tablet_handle.get_obj()->get_read_tables( + } else if (OB_FAIL(get_table_param_.tablet_iter_.refresh_read_tables_from_tablet( get_table_param_.sample_info_.is_no_sample() ? access_ctx_->store_ctx_->mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx() : INT64_MAX, - get_table_param_.tablet_iter_, false/*allow_not_ready*/))) { LOG_WARN("get table iterator fail", K(ret), K_(get_table_param), KP_(access_param)); } if (OB_SUCC(ret)) { - if (OB_FAIL(prepare_tables_from_iterator(get_table_param_.tablet_iter_.table_iter_, &get_table_param_.sample_info_))) { - LOG_WARN("failed to prepare tables from iter", K(ret), K(get_table_param_.tablet_iter_.table_iter_)); + if (OB_FAIL(prepare_tables_from_iterator(*get_table_param_.tablet_iter_.table_iter(), &get_table_param_.sample_info_))) { + LOG_WARN("failed to prepare tables from iter", K(ret), K(get_table_param_.tablet_iter_.table_iter())); } } } @@ -1252,12 +1248,11 @@ int ObMultipleMerge::refresh_tablet_iter() { int ret = OB_SUCCESS; ObLSHandle ls_handle; - ObTabletHandle &tablet_handle = get_table_param_.tablet_iter_.tablet_handle_; - if (OB_UNLIKELY(!tablet_handle.is_valid())) { + if (OB_UNLIKELY(!get_table_param_.tablet_iter_.is_valid())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet handle is invalid", K(ret), K(get_table_param_.tablet_iter_.tablet_handle_)); + LOG_WARN("tablet iter is invalid", K(ret), K(get_table_param_.tablet_iter_)); } else { - const common::ObTabletID tablet_id = tablet_handle.get_obj()->get_tablet_meta().tablet_id_; + const common::ObTabletID tablet_id = get_table_param_.tablet_iter_.get_tablet()->get_tablet_meta().tablet_id_; if (OB_FAIL(MTL(ObLSService*)->get_ls(access_ctx_->ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { LOG_WARN("failed to get ls", K(ret)); } else if (OB_ISNULL(ls_handle.get_ls())) { diff --git a/src/storage/access/ob_multiple_merge.h b/src/storage/access/ob_multiple_merge.h index ea03180e0..d7d0e4e87 100644 --- a/src/storage/access/ob_multiple_merge.h +++ b/src/storage/access/ob_multiple_merge.h @@ -161,7 +161,7 @@ private: OB_INLINE int ObMultipleMerge::check_need_refresh_table(bool &need_refresh) { int ret = OB_SUCCESS; - need_refresh = get_table_param_.tablet_iter_.table_iter_.check_store_expire(); + need_refresh = get_table_param_.tablet_iter_.table_iter()->check_store_expire(); #ifdef ERRSIM ret = OB_E(EventTable::EN_FORCE_REFRESH_TABLE) ret; if (OB_FAIL(ret)) { diff --git a/src/storage/access/ob_multiple_multi_scan_merge.cpp b/src/storage/access/ob_multiple_multi_scan_merge.cpp index 41c4b5842..c32d74ea0 100644 --- a/src/storage/access/ob_multiple_multi_scan_merge.cpp +++ b/src/storage/access/ob_multiple_multi_scan_merge.cpp @@ -66,7 +66,7 @@ int ObMultipleMultiScanMerge::open(const ObIArray &ranges) int ObMultipleMultiScanMerge::calc_scan_range() { int ret = OB_SUCCESS; - const ObTableReadInfo *read_info = nullptr; + const ObITableReadInfo *read_info = nullptr; if (!curr_rowkey_.is_valid()) { // no row has been iterated diff --git a/src/storage/access/ob_multiple_scan_merge.cpp b/src/storage/access/ob_multiple_scan_merge.cpp index 650f167b3..eaf41b486 100644 --- a/src/storage/access/ob_multiple_scan_merge.cpp +++ b/src/storage/access/ob_multiple_scan_merge.cpp @@ -69,7 +69,7 @@ int ObMultipleScanMerge::init( if (OB_FAIL(ObMultipleMerge::init(param, context, get_table_param))) { STORAGE_LOG(WARN, "failed to init ObMultipleMerge", K(ret), K(param), K(context), K(get_table_param)); } else { - const ObTableReadInfo *read_info = nullptr; + const ObITableReadInfo *read_info = nullptr; if (OB_ISNULL(read_info = access_param_->iter_param_.get_read_info())) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Failed to get out col descs", K(ret)); diff --git a/src/storage/access/ob_rows_info.cpp b/src/storage/access/ob_rows_info.cpp index 27136dafb..0b495197e 100644 --- a/src/storage/access/ob_rows_info.cpp +++ b/src/storage/access/ob_rows_info.cpp @@ -35,7 +35,7 @@ ObRowsInfo::ExistHelper::~ExistHelper() int ObRowsInfo::ExistHelper::init(const ObRelativeTable &table, ObStoreCtx &store_ctx, - const ObTableReadInfo &full_read_info, + const ObITableReadInfo &rowkey_read_info, ObStorageReserveAllocator &allocator) { int ret = OB_SUCCESS; @@ -61,8 +61,7 @@ int ObRowsInfo::ExistHelper::init(const ObRelativeTable &table, table_iter_param_.table_id_ = table.get_table_id(); table_iter_param_.tablet_id_ = table.get_tablet_id(); table_iter_param_.out_cols_project_ = NULL; - table_iter_param_.read_info_ = &full_read_info; - table_iter_param_.full_read_info_ = &full_read_info; + table_iter_param_.read_info_ = &rowkey_read_info; is_inited_ = true; } } @@ -95,17 +94,17 @@ ObRowsInfo::~ObRowsInfo() int ObRowsInfo::init( const ObRelativeTable &table, ObStoreCtx &store_ctx, - const ObTableReadInfo &full_read_info) + const ObITableReadInfo &rowkey_read_info) { int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; STORAGE_LOG(WARN, "ObRowsinfo init twice", K(ret)); - } else if (OB_FAIL(exist_helper_.init(table, store_ctx, full_read_info, scan_mem_allocator_))) { + } else if (OB_FAIL(exist_helper_.init(table, store_ctx, rowkey_read_info, scan_mem_allocator_))) { STORAGE_LOG(WARN, "Failed to init exist helper", K(ret)); } else { - datum_utils_ = &full_read_info.get_datum_utils(); + datum_utils_ = &rowkey_read_info.get_datum_utils(); table_id_ = table.get_table_id(); tablet_id_ = table.get_tablet_id(); rowkey_column_num_ = table.get_rowkey_column_num(); @@ -139,7 +138,7 @@ int ObRowsInfo::check_duplicate(ObStoreRow *rows, const int64_t row_count, ObRel STORAGE_LOG(WARN, "Invalid parameter", K(rows), K(row_count), K(ret)); } else { reuse(); - table.tablet_iter_.table_iter_.resume(); + table.tablet_iter_.table_iter()->resume(); rows_ = rows; } diff --git a/src/storage/access/ob_rows_info.h b/src/storage/access/ob_rows_info.h index 6937dff41..6f7c26ebd 100644 --- a/src/storage/access/ob_rows_info.h +++ b/src/storage/access/ob_rows_info.h @@ -34,7 +34,7 @@ public: int init( const ObRelativeTable &table, ObStoreCtx &store_ctx, - const ObTableReadInfo &full_read_info); + const ObITableReadInfo &rowkey_read_info); int check_duplicate(ObStoreRow *rows, const int64_t row_count, ObRelativeTable &table); const blocksstable::ObDatumRowkey& get_duplicate_rowkey() const { return min_key_; } blocksstable::ObDatumRowkey& get_duplicate_rowkey() { return min_key_; } @@ -53,13 +53,9 @@ public: int init( const ObRelativeTable &table, ObStoreCtx &store_ctx, - const ObTableReadInfo &full_read_info, + const ObITableReadInfo &rowkey_read_info, ObStorageReserveAllocator &allocator); OB_INLINE bool is_valid() const { return is_inited_; } - OB_INLINE ObStoreCtx &get_store_ctx() - { return *table_access_context_.store_ctx_; } - OB_INLINE const ObTableReadInfo *get_read_info() const - { return table_iter_param_.read_info_; } TO_STRING_KV(K_(table_iter_param), K_(table_access_context)); ObTableIterParam table_iter_param_; ObTableAccessContext table_access_context_; diff --git a/src/storage/access/ob_single_merge.cpp b/src/storage/access/ob_single_merge.cpp index 0557941c6..b347d32e5 100644 --- a/src/storage/access/ob_single_merge.cpp +++ b/src/storage/access/ob_single_merge.cpp @@ -45,7 +45,7 @@ int ObSingleMerge::open(const ObDatumRowkey &rowkey) ret = OB_NOT_INIT; LOG_WARN("ObSingleMerge has not been inited", K(ret), K_(get_table_param)); } else { - const ObTabletMeta &tablet_meta = get_table_param_.tablet_iter_.tablet_handle_.get_obj()->get_tablet_meta(); + const ObTabletMeta &tablet_meta = get_table_param_.tablet_iter_.get_tablet()->get_tablet_meta(); if (!full_row_.is_valid()) { if (OB_FAIL(full_row_.init(*access_ctx_->stmt_allocator_, access_param_->get_max_out_col_cnt()))) { STORAGE_LOG(WARN, "Failed to init datum row", K(ret)); @@ -235,7 +235,7 @@ int ObSingleMerge::get_and_fuse_cache_row(const int64_t read_snapshot_version, int ObSingleMerge::inner_get_next_row(ObDatumRow &row) { int ret = OB_SUCCESS; - const ObTableReadInfo *read_info = access_param_->iter_param_.get_read_info(); + const ObITableReadInfo *read_info = access_param_->iter_param_.get_read_info(); if (OB_ISNULL(read_info)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected null read_info", K(ret), KP(read_info)); @@ -244,7 +244,7 @@ int ObSingleMerge::inner_get_next_row(ObDatumRow &row) int64_t table_idx = -1; ObITable *table = nullptr; bool have_uncommited_row = false; - const ObTabletMeta &tablet_meta = get_table_param_.tablet_iter_.tablet_handle_.get_obj()->get_tablet_meta(); + const ObTabletMeta &tablet_meta = get_table_param_.tablet_iter_.get_tablet()->get_tablet_meta(); const int64_t read_snapshot_version = access_ctx_->trans_version_range_.snapshot_version_; const bool enable_fuse_row_cache = access_ctx_->use_fuse_row_cache_ && access_param_->iter_param_.enable_fuse_row_cache(access_ctx_->query_flag_) && @@ -310,9 +310,10 @@ int ObSingleMerge::inner_get_next_row(ObDatumRow &row) if (!full_row_.row_flag_.is_exist_without_delete()) { ret = OB_ITER_END; } else { - const common::ObIArray &cols_index = read_info->get_columns_index(); + const ObColumnIndexArray &cols_index = read_info->get_columns_index(); row.count_ = read_info->get_request_count(); - if (OB_FAIL(project_row(full_row_, enable_fuse_row_cache ? &cols_index : nullptr, 0/*range idx delta*/, row))) { + const ObIArray *projector = (cols_index.rowkey_mode_ || !enable_fuse_row_cache) ? nullptr : &cols_index.array_; + if (OB_FAIL(project_row(full_row_, projector, 0/*range idx delta*/, row))) { STORAGE_LOG(WARN, "fail to project row", K(ret), K(full_row_), K(cols_index)); } else { row.row_flag_ = full_row_.row_flag_; diff --git a/src/storage/access/ob_sstable_row_exister.cpp b/src/storage/access/ob_sstable_row_exister.cpp index 32d36431a..9e88b354c 100644 --- a/src/storage/access/ob_sstable_row_exister.cpp +++ b/src/storage/access/ob_sstable_row_exister.cpp @@ -116,7 +116,8 @@ int ObSSTableRowExister::exist_block_row(ObSSTableReadHandle &read_handle, ObDat } else { if (!found) { store_row.row_flag_.set_flag(ObDmlFlag::DF_NOT_EXIST); - if (!access_ctx_->query_flag_.is_index_back() && access_ctx_->query_flag_.is_use_bloomfilter_cache() && !sstable_->is_small_sstable()) { + if (!access_ctx_->query_flag_.is_index_back() && access_ctx_->query_flag_.is_use_bloomfilter_cache() + && !sstable_->is_small_sstable()) { (void) OB_STORE_CACHE.get_bf_cache().inc_empty_read( MTL_ID(), iter_param_->table_id_, diff --git a/src/storage/access/ob_sstable_row_getter.cpp b/src/storage/access/ob_sstable_row_getter.cpp index 0a884c281..50e7836ad 100644 --- a/src/storage/access/ob_sstable_row_getter.cpp +++ b/src/storage/access/ob_sstable_row_getter.cpp @@ -61,7 +61,6 @@ int ObSSTableRowGetter::inner_open( ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument to init ObSSTableRowGetter", K(ret), KP(query_range), KP(table)); } else { - const ObTableReadInfo *index_read_info = iter_param.get_full_read_info()->get_index_read_info(); sstable_ = static_cast(table); rowkey_ = static_cast(query_range); iter_param_ = &iter_param; @@ -74,11 +73,8 @@ int ObSSTableRowGetter::inner_open( type_, *sstable_, iter_param, access_ctx, query_range))) { LOG_WARN("fail to init prefetcher", K(ret)); } - } else if (OB_ISNULL(index_read_info)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Unexpected null index read info", K(ret), KP(index_read_info)); } else if (OB_FAIL(prefetcher_.switch_context( - type_, *index_read_info, *sstable_, access_ctx, query_range))) { + type_, *sstable_, iter_param.get_read_info()->get_datum_utils(), access_ctx, query_range))) { LOG_WARN("fail to switch context for prefetcher, ", K(ret)); } if (OB_SUCC(ret)) { diff --git a/src/storage/access/ob_sstable_row_multi_getter.cpp b/src/storage/access/ob_sstable_row_multi_getter.cpp index 8862a3ea4..c01a50ebd 100644 --- a/src/storage/access/ob_sstable_row_multi_getter.cpp +++ b/src/storage/access/ob_sstable_row_multi_getter.cpp @@ -55,7 +55,6 @@ int ObSSTableRowMultiGetter::inner_open( ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument to init ObSSTableRowMultiGetter", K(ret), KP(query_range), KP(table)); } else { - const ObTableReadInfo *index_read_info = iter_param.get_full_read_info()->get_index_read_info(); sstable_ = static_cast(table); iter_param_ = &iter_param; access_ctx_ = &access_ctx; @@ -64,11 +63,8 @@ int ObSSTableRowMultiGetter::inner_open( type_, *sstable_, iter_param, access_ctx, query_range))) { LOG_WARN("fail to init prefetcher, ", K(ret)); } - } else if (OB_ISNULL(index_read_info)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Unexpected null index read info", K(ret), KP(index_read_info)); } else if (OB_FAIL(prefetcher_.switch_context( - type_, *index_read_info, *sstable_, access_ctx, query_range))) { + type_, *sstable_, iter_param.get_read_info()->get_datum_utils(), access_ctx, query_range))) { LOG_WARN("fail to switch context for prefetcher, ", K(ret)); } if (OB_SUCC(ret)) { diff --git a/src/storage/access/ob_sstable_row_scanner.cpp b/src/storage/access/ob_sstable_row_scanner.cpp index aaa8808dc..4e2e14cfc 100644 --- a/src/storage/access/ob_sstable_row_scanner.cpp +++ b/src/storage/access/ob_sstable_row_scanner.cpp @@ -73,7 +73,6 @@ int ObSSTableRowScanner::inner_open( ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument to init ObSSTableRowScanner", K(ret), KP(query_range), KP(table)); } else { - const ObTableReadInfo *index_read_info = iter_param.get_full_read_info()->get_index_read_info(); sstable_ = static_cast(table); iter_param_ = &iter_param; access_ctx_ = &access_ctx; @@ -82,10 +81,8 @@ int ObSSTableRowScanner::inner_open( type_, *sstable_, iter_param, access_ctx, query_range))) { LOG_WARN("fail to init prefetcher, ", K(ret)); } - } else if (OB_ISNULL(index_read_info)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Unexpected null index read info", K(ret), KP(index_read_info)); - } else if (OB_FAIL(prefetcher_.switch_context(type_, *index_read_info, *sstable_, access_ctx, query_range))) { + } else if (OB_FAIL(prefetcher_.switch_context( + type_, *sstable_, iter_param.get_read_info()->get_datum_utils(), access_ctx, query_range))) { LOG_WARN("fail to switch context for prefetcher, ", K(ret)); } if (OB_SUCC(ret)) { diff --git a/src/storage/access/ob_sstable_row_whole_scanner.cpp b/src/storage/access/ob_sstable_row_whole_scanner.cpp index 76da6d8cf..1b0420d1a 100644 --- a/src/storage/access/ob_sstable_row_whole_scanner.cpp +++ b/src/storage/access/ob_sstable_row_whole_scanner.cpp @@ -171,7 +171,6 @@ int ObSSTableRowWholeScanner::inner_open( ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument", K(ret), KP(query_range), KP(table)); } else { - const ObTableReadInfo *index_read_info = iter_param.read_info_->get_index_read_info(); const ObDatumRange *range = reinterpret_cast(query_range); iter_param_ = &iter_param; access_ctx_ = &access_ctx; @@ -180,15 +179,12 @@ int ObSSTableRowWholeScanner::inner_open( cur_macro_cursor_ = 0; last_mvcc_row_already_output_ = true; - if (OB_ISNULL(index_read_info)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Unexpected null index read info", K(ret)); - } else if (OB_FAIL(init_micro_scanner(range))) { + if (OB_FAIL(init_micro_scanner(range))) { LOG_WARN("Failed to init micro scanner", K(ret)); } else if (OB_FAIL(macro_block_iter_.open( *sstable_, query_range_, - *index_read_info, + *iter_param.read_info_, *access_ctx.stmt_allocator_))) { LOG_WARN("Fail to open macro_block_iter ", K(ret)); } @@ -421,7 +417,7 @@ int ObSSTableRowWholeScanner::open_macro_block() scan_handle.macro_io_handle_.get_buffer(), scan_handle.macro_io_handle_.get_data_size(), query_range_, - *(iter_param_->read_info_->get_index_read_info()), + *(iter_param_->read_info_), scan_handle.is_left_border_, scan_handle.is_right_border_))) { LOG_WARN("failed to open micro block iter", K(ret), K(scan_handle.macro_io_handle_)); diff --git a/src/storage/access/ob_table_access_context.cpp b/src/storage/access/ob_table_access_context.cpp index 11ed340cf..0dcf3d121 100644 --- a/src/storage/access/ob_table_access_context.cpp +++ b/src/storage/access/ob_table_access_context.cpp @@ -31,7 +31,7 @@ int ObTableAccessContext::init_column_scale_info(ObTableScanParam &scan_param) ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Unexpected table parameter to init column scale info", K(ret), KPC(scan_param.table_param_)); } else { - const ObIArray *out_col_param = &scan_param.table_param_->get_read_info().get_columns(); + const ObIArray *out_col_param = scan_param.table_param_->get_read_info().get_columns(); const ObIArray *out_col_project = &scan_param.table_param_->get_output_projector(); for (int64_t i = 0; OB_SUCC(ret) && i < out_col_project->count(); ++i) { share::schema::ObColumnParam *col_param = NULL; diff --git a/src/storage/access/ob_table_access_param.cpp b/src/storage/access/ob_table_access_param.cpp index 38462e4d9..cf990b171 100644 --- a/src/storage/access/ob_table_access_param.cpp +++ b/src/storage/access/ob_table_access_param.cpp @@ -29,11 +29,10 @@ ObTableIterParam::ObTableIterParam() : table_id_(0), tablet_id_(), read_info_(nullptr), - full_read_info_(nullptr), + rowkey_read_info_(nullptr), out_cols_project_(NULL), agg_cols_project_(NULL), pushdown_filter_(nullptr), - tablet_handle_(), is_multi_version_minor_merge_(false), need_scn_(false), is_same_schema_column_(false), @@ -50,16 +49,14 @@ ObTableIterParam::ObTableIterParam() ObTableIterParam::~ObTableIterParam() { - tablet_handle_.reset(); } void ObTableIterParam::reset() { table_id_ = 0; tablet_id_.reset(); - tablet_handle_.reset(); read_info_ = nullptr; - full_read_info_ = nullptr; + rowkey_read_info_ = nullptr; out_cols_project_ = NULL; agg_cols_project_ = NULL; is_multi_version_minor_merge_ = false; @@ -80,24 +77,7 @@ bool ObTableIterParam::is_valid() const { return (OB_INVALID_ID != table_id_ || tablet_id_.is_valid()) // TODO: use tablet id replace table id && OB_NOT_NULL(read_info_) && read_info_->is_valid() - && (nullptr == full_read_info_ || full_read_info_->is_valid_full_read_info()); -} - -int ObTableIterParam::check_read_info_valid() -{ - int ret = OB_SUCCESS; - - if (nullptr != full_read_info_ && nullptr != read_info_) { - if (read_info_->is_oracle_mode() != full_read_info_->is_oracle_mode()) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "Unexpected compat mode", K(ret), K(lib::is_oracle_mode()), KPC(read_info_), KPC(full_read_info_)); - } else if (read_info_->get_schema_rowkey_count() != full_read_info_->get_schema_rowkey_count()) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "Unexpected rowkey count in read info", K(ret), KPC(read_info_), KPC(full_read_info_)); - } - } - - return ret; + && (nullptr == rowkey_read_info_ || rowkey_read_info_->is_valid()); } int ObTableIterParam::refresh_lob_column_out_status() @@ -119,8 +99,8 @@ int ObTableIterParam::refresh_lob_column_out_status() bool ObTableIterParam::enable_fuse_row_cache(const ObQueryFlag &query_flag) const { bool bret = is_x86() && query_flag.is_use_fuse_row_cache() && !query_flag.is_read_latest() && - nullptr != full_read_info_ && !need_scn_ && is_same_schema_column_ - && !has_virtual_columns_ && !has_lob_column_out_; + nullptr != rowkey_read_info_ && !need_scn_ && is_same_schema_column_ && + !has_virtual_columns_ && !has_lob_column_out_; return bret; } @@ -140,7 +120,7 @@ DEF_TO_STRING(ObTableIterParam) J_KV(K_(table_id), K_(tablet_id), KPC_(read_info), - KPC_(full_read_info), + KPC_(rowkey_read_info), KPC_(out_cols_project), KPC_(pushdown_filter), K_(is_multi_version_minor_merge), @@ -204,6 +184,7 @@ int ObTableAccessParam::init( iter_param_.table_id_ = table_param.get_table_id(); iter_param_.tablet_id_ = scan_param.tablet_id_; iter_param_.read_info_ = &table_param.get_read_info(); + iter_param_.rowkey_read_info_ = &tablet_handle.get_obj()->get_rowkey_read_info(); iter_param_.out_cols_project_ = &table_param.get_output_projector(); iter_param_.agg_cols_project_ = &table_param.get_aggregate_projector(); iter_param_.need_scn_ = scan_param.need_scn_; @@ -218,10 +199,8 @@ int ObTableAccessParam::init( row2exprs_projector_ = scan_param.row2exprs_projector_; output_sel_mask_ = &table_param.get_output_sel_mask(); - iter_param_.tablet_handle_ = tablet_handle; - iter_param_.full_read_info_ = &tablet_handle.get_obj()->get_full_read_info(); iter_param_.is_same_schema_column_ = - iter_param_.read_info_->get_schema_column_count() == iter_param_.full_read_info_->get_schema_column_count(); + iter_param_.read_info_->get_schema_column_count() == iter_param_.rowkey_read_info_->get_schema_column_count(); iter_param_.pd_storage_flag_ = scan_param.pd_storage_flag_; iter_param_.pushdown_filter_ = scan_param.pd_storage_filters_; @@ -240,9 +219,7 @@ int ObTableAccessParam::init( iter_param_.vectorized_enabled_ = nullptr != get_op() && get_op()->is_vectorized(); iter_param_.limit_prefetch_ = (nullptr == op_filters_ || op_filters_->empty()); - if (OB_FAIL(iter_param_.check_read_info_valid())) { - STORAGE_LOG(WARN, "Failed to check read info valdie", K(ret), K(iter_param_)); - } else if (OB_FAIL(iter_param_.refresh_lob_column_out_status())) { + if (OB_FAIL(iter_param_.refresh_lob_column_out_status())) { STORAGE_LOG(WARN, "Failed to refresh lob column out status", K(ret), K(iter_param_)); } else if (scan_param.use_index_skip_scan() && OB_FAIL(get_prefix_cnt_for_skip_scan(scan_param, iter_param_))) { @@ -278,7 +255,7 @@ int ObTableAccessParam::get_prefix_cnt_for_skip_scan(const ObTableScanParam &sca int ObTableAccessParam::init_merge_param( const uint64_t table_id, const common::ObTabletID &tablet_id, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, const bool is_multi_version_minor_merge) { int ret = OB_SUCCESS; @@ -291,21 +268,15 @@ int ObTableAccessParam::init_merge_param( iter_param_.tablet_id_ = tablet_id; iter_param_.is_multi_version_minor_merge_ = is_multi_version_minor_merge; iter_param_.read_info_ = &read_info; - iter_param_.full_read_info_ = &read_info; - if (OB_FAIL(iter_param_.check_read_info_valid())) { - STORAGE_LOG(WARN, "Failed to check read info valdie", K(ret), K(iter_param_)); - } else if (OB_FAIL(iter_param_.refresh_lob_column_out_status())) { - STORAGE_LOG(WARN, "Failed to refresh lob column out status", K(ret), K(iter_param_)); - } else { - is_inited_ = true; - } + iter_param_.rowkey_read_info_ = &read_info; + is_inited_ = true; } return ret; } int ObTableAccessParam::init_dml_access_param( const ObRelativeTable &table, - const ObTableReadInfo &full_read_info, + const ObITableReadInfo &rowkey_read_info, const share::schema::ObTableSchemaParam &schema_param, const ObIArray *out_cols_project) { @@ -318,9 +289,9 @@ int ObTableAccessParam::init_dml_access_param( iter_param_.table_id_ = table.get_table_id(); iter_param_.tablet_id_ = table.get_tablet_id(); iter_param_.read_info_ = &schema_param.get_read_info(); - iter_param_.full_read_info_ = &full_read_info; + iter_param_.rowkey_read_info_ = &rowkey_read_info; iter_param_.is_same_schema_column_ = - iter_param_.read_info_->get_schema_column_count() == iter_param_.full_read_info_->get_schema_column_count(); + iter_param_.read_info_->get_schema_column_count() == iter_param_.rowkey_read_info_->get_schema_column_count(); iter_param_.out_cols_project_ = out_cols_project; for (int64_t i = 0; i < schema_param.get_columns().count(); i++) { if (schema_param.get_columns().at(i)->is_virtual_gen_col()) { @@ -328,9 +299,7 @@ int ObTableAccessParam::init_dml_access_param( break; } } - if (OB_FAIL(iter_param_.check_read_info_valid())) { - STORAGE_LOG(WARN, "Failed to check read info valdie", K(ret), K(iter_param_)); - } else if (OB_FAIL(iter_param_.refresh_lob_column_out_status())) { + if (OB_FAIL(iter_param_.refresh_lob_column_out_status())) { STORAGE_LOG(WARN, "Failed to refresh lob column out status", K(ret), K(iter_param_)); } else { is_inited_ = true; @@ -363,7 +332,7 @@ int set_row_scn( { int ret = OB_SUCCESS; const ObColDescIArray *out_cols = nullptr; - const ObTableReadInfo *read_info = iter_param.get_read_info(); + const ObITableReadInfo *read_info = iter_param.get_read_info(); if (OB_UNLIKELY(nullptr == read_info)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected null read info", K(ret)); diff --git a/src/storage/access/ob_table_access_param.h b/src/storage/access/ob_table_access_param.h index 7e0a8b13a..2975441e4 100644 --- a/src/storage/access/ob_table_access_param.h +++ b/src/storage/access/ob_table_access_param.h @@ -82,36 +82,31 @@ public: virtual ~ObTableIterParam(); void reset(); bool is_valid() const; - int check_read_info_valid(); int refresh_lob_column_out_status(); bool enable_fuse_row_cache(const ObQueryFlag &query_flag) const; - const ObTableReadInfo *get_read_info(const bool is_get = false) const + const ObITableReadInfo *get_read_info(const bool is_get = false) const { - return (is_get) ? full_read_info_ : read_info_; - } - const ObTableReadInfo *get_full_read_info() const - { - return full_read_info_; + return is_get ? rowkey_read_info_ : read_info_; } OB_INLINE int64_t get_out_col_cnt() const { return read_info_ != nullptr ? read_info_->get_request_count() : 0; } + OB_INLINE int64_t get_full_out_col_cnt() const + { + return (rowkey_read_info_ != nullptr) ? rowkey_read_info_->get_request_count() : 0; + } OB_INLINE int64_t get_schema_rowkey_count() const { return (nullptr != read_info_) ? read_info_->get_schema_rowkey_count() : 0; } - OB_INLINE int64_t get_full_out_col_cnt() const - { - return (full_read_info_ != nullptr) ? full_read_info_->get_request_count() : 0; - } OB_INLINE int64_t get_max_out_col_cnt() const { return MAX(get_full_out_col_cnt(), get_out_col_cnt()); } OB_INLINE const ObIArray *get_col_params() const { - return (read_info_ != nullptr) ? &read_info_->get_columns() : nullptr; + return (read_info_ != nullptr) ? read_info_->get_columns() : nullptr; } OB_INLINE const ObColDescIArray *get_out_col_descs() const { @@ -148,13 +143,11 @@ public: public: uint64_t table_id_; common::ObTabletID tablet_id_; - const ObTableReadInfo *read_info_; - const ObTableReadInfo *full_read_info_; + const ObITableReadInfo *read_info_; + const ObITableReadInfo *rowkey_read_info_; const common::ObIArray *out_cols_project_; const common::ObIArray *agg_cols_project_; sql::ObPushdownFilterExecutor *pushdown_filter_; - // only used in io_callback for query, maybe invalid - ObTabletHandle tablet_handle_; // only used in ObMemTable bool is_multi_version_minor_merge_; bool need_scn_; @@ -193,11 +186,11 @@ public: // used for merge int init_merge_param(const uint64_t table_id, const common::ObTabletID &tablet_id, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, const bool is_multi_version_merge = false); // used for get unique index conflict row int init_dml_access_param(const ObRelativeTable &table, - const ObTableReadInfo &full_read_info, + const ObITableReadInfo &rowkey_read_info, const share::schema::ObTableSchemaParam &schema_param, const common::ObIArray *out_cols_project); int get_prefix_cnt_for_skip_scan(const ObTableScanParam &scan_param, ObTableIterParam &iter_param); diff --git a/src/storage/access/ob_table_estimator.cpp b/src/storage/access/ob_table_estimator.cpp index c64b3ce0c..90e19f6b7 100644 --- a/src/storage/access/ob_table_estimator.cpp +++ b/src/storage/access/ob_table_estimator.cpp @@ -102,11 +102,11 @@ int ObTableEstimator::estimate_multi_scan_row_count( { int ret = OB_SUCCESS; ObPartitionEst tmp_cost; - const ObTableReadInfo &full_read_info = base_input.tablet_handle_.get_obj()->get_full_read_info(); + const ObITableReadInfo &rowkey_read_info = base_input.tablet_handle_.get_obj()->get_rowkey_read_info(); for (int64_t i = 0; OB_SUCC(ret) && i < ranges.count(); ++i) { const ObDatumRange &range = ranges.at(i); bool is_single_rowkey = false; - if (OB_FAIL(range.is_single_rowkey(full_read_info.get_datum_utils(), is_single_rowkey))) { + if (OB_FAIL(range.is_single_rowkey(rowkey_read_info.get_datum_utils(), is_single_rowkey))) { STORAGE_LOG(WARN, "Failed to check range is single rowkey", K(ret), K(range)); } else if (is_single_rowkey) { // Back off to get mode if range contains single row key. diff --git a/src/storage/access/ob_table_read_info.cpp b/src/storage/access/ob_table_read_info.cpp index 28efa0a88..c869d44ff 100644 --- a/src/storage/access/ob_table_read_info.cpp +++ b/src/storage/access/ob_table_read_info.cpp @@ -15,38 +15,224 @@ #include "storage/ob_i_store.h" #include "storage/ob_storage_schema.h" #include "share/schema/ob_table_param.h" +#include "storage/blocksstable/ob_macro_block.h" +#include "share/ob_cluster_version.h" namespace oceanbase { using namespace common; namespace storage { - -ObTableReadInfo::~ObTableReadInfo() +/* + * ------------------------------- ObColumnIndexArray ------------------------------- + */ +int64_t ObColumnIndexArray::to_string(char *buf, const int64_t buf_len) const { - reset(); + int64_t pos = 0; + J_OBJ_START(); + J_KV(K_(rowkey_mode), K_(for_memtable)); + if (rowkey_mode_) { + J_COMMA(); + J_KV(K_(schema_rowkey_cnt), K_(column_cnt)); + } else { + J_COMMA(); + J_KV(K_(array)); + } + J_OBJ_END(); + return pos; } -void ObTableReadInfo::reset() +int ObColumnIndexArray::init(const int64_t count, const int64_t schema_rowkey_cnt, ObIAllocator &allocator) { - if (nullptr != allocator_ && nullptr != index_read_info_) { - index_read_info_->~ObTableReadInfo(); - allocator_->free(index_read_info_); + int ret = OB_SUCCESS; + if (rowkey_mode_) { + column_cnt_ = count; + schema_rowkey_cnt_ = schema_rowkey_cnt; + } else { + if (OB_FAIL(array_.init(count, allocator))) { + LOG_WARN("failed to init array", K(ret), K(count)); + } else if (OB_FAIL(array_.prepare_allocate(count))) { + LOG_WARN("failed to pre alloc array", K(ret), K(count)); + } } + return ret; +} + +int32_t ObColumnIndexArray::at(int64_t idx) const +{ + int32_t ret_val = 0; + const int32_t extra_rowkey_cnt = storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + if (rowkey_mode_) { + OB_ASSERT(idx >= 0 && idx < column_cnt_); + if (for_memtable_) { + if (idx < schema_rowkey_cnt_) { + ret_val = idx; + } else if (idx < schema_rowkey_cnt_ + extra_rowkey_cnt) { + ret_val = OB_INVALID_INDEX; + } else { + ret_val = idx - extra_rowkey_cnt; + } + } else { + ret_val = idx; + } + } else { + OB_ASSERT(idx >= 0 && idx < array_.count()); + ret_val = array_.at(idx); + } + return ret_val; +} + +int64_t ObColumnIndexArray::get_deep_copy_size() const +{ + return rowkey_mode_ ? 0 : array_.get_deep_copy_size(); +} + +int ObColumnIndexArray::deep_copy( + char *dst_buf, + const int64_t buf_size, + int64_t &pos, + ObColumnIndexArray &dst_array) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("cur column index array is invalid", K(ret), KPC(this)); + } else { + dst_array.version_ = version_; + dst_array.rowkey_mode_ = rowkey_mode_; + dst_array.for_memtable_ = for_memtable_; + dst_array.schema_rowkey_cnt_ = schema_rowkey_cnt_; + dst_array.column_cnt_ = column_cnt_; + if (!rowkey_mode_ && OB_FAIL(array_.deep_copy(dst_buf, buf_size, pos, dst_array.array_))) { + LOG_WARN("failed to deep copy", K(ret)); + } + } + return ret; +} + +int ObColumnIndexArray::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, + version_, + rowkey_mode_, + for_memtable_); + if (OB_FAIL(ret)) { + } else if (rowkey_mode_) { + LST_DO_CODE(OB_UNIS_ENCODE, schema_rowkey_cnt_, column_cnt_); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("for non-rowkey-mode, should not use serialize func", K(ret), K(rowkey_mode_)); + } + return ret; +} + +int ObColumnIndexArray::deserialize(const char *buf, const int64_t data_len, int64_t &pos, ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + reset(); + LST_DO_CODE(OB_UNIS_DECODE, + version_, + rowkey_mode_, + for_memtable_); + if (OB_FAIL(ret)) { + } else if (rowkey_mode_) { + LST_DO_CODE(OB_UNIS_DECODE, schema_rowkey_cnt_, column_cnt_); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("for non-rowkey-mode, should not use deserialize func", K(ret), K(rowkey_mode_)); + } + return ret; +} + +int64_t ObColumnIndexArray::get_serialize_size() const +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, + version_, + rowkey_mode_, + for_memtable_); + if (rowkey_mode_) { + LST_DO_CODE(OB_UNIS_ADD_LEN, schema_rowkey_cnt_, column_cnt_); + } else { + LOG_WARN_RET(OB_ERR_UNEXPECTED, "for non-rowkey-mode, should not use serialize func", K(rowkey_mode_)); + } + return len; +} + +/* + * ------------------------------- ObReadInfoStruct ------------------------------- + */ +void ObReadInfoStruct::reset() +{ + is_inited_ = false; + is_oracle_mode_ = false; allocator_ = nullptr; schema_column_count_ = 0; - trans_col_index_ = OB_INVALID_INDEX; - group_idx_col_index_ = OB_INVALID_INDEX; + compat_version_ = READ_INFO_VERSION_V1; + reserved_ = 0; schema_rowkey_cnt_ = 0; - seq_read_column_count_ = 0; - max_col_index_ = -1; - is_oracle_mode_ = false; - cols_param_.reset(); + rowkey_cnt_ = 0; cols_desc_.reset(); cols_index_.reset(); memtable_cols_index_.reset(); datum_utils_.reset(); - index_read_info_ = nullptr; +} + +void ObReadInfoStruct::init_basic_info(const int64_t schema_column_count, + const int64_t schema_rowkey_cnt, + const bool is_oracle_mode) { + schema_column_count_ = schema_column_count; + schema_rowkey_cnt_ = schema_rowkey_cnt; + rowkey_cnt_ = schema_rowkey_cnt + storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + is_oracle_mode_ = is_oracle_mode; +} + +int64_t ObReadInfoStruct::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + J_OBJ_START(); + J_KV(K_(is_inited), K_(compat_version), K_(is_oracle_mode), + K_(schema_column_count), + K_(schema_rowkey_cnt), + K_(rowkey_cnt), + K_(cols_index), + K_(cols_desc), + K_(datum_utils)); + J_OBJ_END(); + + return pos; +} + +int ObReadInfoStruct::init_compat_version() +{ + int ret = OB_SUCCESS; + uint64_t compat_version = 0; + if (OB_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), compat_version))) { + LOG_WARN("fail to get data version", K(ret)); + } else if (compat_version < DATA_VERSION_4_2_0_0) { + compat_version_ = READ_INFO_VERSION_V0; + } else { + compat_version_ = READ_INFO_VERSION_V1; + } + return ret; +} + +/* + * ------------------------------- ObTableReadInfo ------------------------------- + */ +ObTableReadInfo::ObTableReadInfo() + : ObReadInfoStruct(false/*rowkey_mode*/), + trans_col_index_(OB_INVALID_INDEX), + group_idx_col_index_(OB_INVALID_INDEX), + seq_read_column_count_(0), + max_col_index_(-1) +{ +} + +ObTableReadInfo::~ObTableReadInfo() +{ + reset(); } int ObTableReadInfo::init( @@ -55,15 +241,13 @@ int ObTableReadInfo::init( const int64_t schema_rowkey_cnt, const bool is_oracle_mode, const common::ObIArray &cols_desc, - const bool is_multi_version_full, const common::ObIArray *storage_cols_index, - const common::ObIArray *cols_param, - const bool is_index_read_info) + const common::ObIArray *cols_param) { int ret = OB_SUCCESS; const int64_t out_cols_cnt = cols_desc.count(); - if (OB_UNLIKELY(is_valid())) { + if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret), KPC(this)); } else if (OB_UNLIKELY(0 > schema_rowkey_cnt || @@ -73,36 +257,24 @@ int ObTableReadInfo::init( (nullptr != cols_param && cols_param->count() != cols_desc.count()))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument", K(ret), K(schema_rowkey_cnt), K(cols_desc.count()), KPC(storage_cols_index), KPC(cols_param)); + } else if (OB_FAIL(init_compat_version())) { // init compat verion + LOG_WARN("failed to init compat version", KR(ret)); } else { - int16_t extra_rowkey_cnt = storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); - cols_param_.set_allocator(&allocator); - cols_desc_.set_allocator(&allocator); - cols_index_.set_allocator(&allocator); - allocator_ = &allocator; - memtable_cols_index_.set_allocator(&allocator); - schema_column_count_ = schema_column_count; - schema_rowkey_cnt_ = schema_rowkey_cnt; - rowkey_cnt_ = schema_rowkey_cnt + extra_rowkey_cnt; - is_oracle_mode_ = is_oracle_mode; - int64_t trans_version_col_idx = ObMultiVersionRowkeyHelpper::get_trans_version_col_store_index( + const int64_t trans_version_col_idx = ObMultiVersionRowkeyHelpper::get_trans_version_col_store_index( schema_rowkey_cnt, true); - int64_t sql_sequence_col_idx = ObMultiVersionRowkeyHelpper::get_sql_sequence_col_store_index( + const int64_t sql_sequence_col_idx = ObMultiVersionRowkeyHelpper::get_sql_sequence_col_store_index( schema_rowkey_cnt, true); - if (OB_FAIL(cols_desc_.assign(cols_desc))) { - LOG_WARN("Fail to assign cols_desc", K(ret)); - } else if (nullptr != cols_param && - OB_FAIL(cols_param_.assign(*cols_param))) { + init_basic_info(schema_column_count, schema_rowkey_cnt, is_oracle_mode); // init basic info + if (OB_FAIL(ObReadInfoStruct::prepare_arrays(allocator, cols_desc, out_cols_cnt))) { + LOG_WARN("failed to prepare arrays", K(ret), K(out_cols_cnt)); + } else if (nullptr != cols_param && OB_FAIL(cols_param_.init_and_assign(*cols_param, allocator))) { LOG_WARN("Fail to assign cols_param", K(ret)); - } else if (OB_FAIL(cols_index_.prepare_allocate(out_cols_cnt))) { - LOG_WARN("Fail to init cols_index", K(ret), K(out_cols_cnt)); - } else if (OB_FAIL(memtable_cols_index_.prepare_allocate(out_cols_cnt))) { - LOG_WARN("Fail to init memtable_cols_index", K(ret), K(out_cols_cnt)); - } else if (OB_LIKELY(!is_multi_version_full)) { + } else { int32_t col_index = OB_INVALID_INDEX; for (int64_t i = 0; i < out_cols_cnt; i++) { col_index = (nullptr == storage_cols_index) ? i : storage_cols_index->at(i); //memtable do not involve the multi version column - memtable_cols_index_[i] = col_index; + memtable_cols_index_.array_[i] = col_index; if (i < schema_rowkey_cnt) { // continue } else if (OB_INVALID_INDEX == col_index) { @@ -118,105 +290,77 @@ int ObTableReadInfo::init( col_index = -1; } } else { - col_index = col_index + extra_rowkey_cnt; - } - cols_index_[i] = col_index; - } - } else { - trans_col_index_ = trans_version_col_idx; - for (int64_t i = 0; i < out_cols_cnt; i++) { - if (common::OB_HIDDEN_GROUP_IDX_COLUMN_ID == cols_desc.at(i).col_id_) { - group_idx_col_index_ = i; - cols_index_[i] = -1; - memtable_cols_index_[i] = -1; - } else { - cols_index_[i] = i; - if (i < schema_rowkey_cnt) { - memtable_cols_index_[i] = i; - } else if (i < rowkey_cnt_) { - memtable_cols_index_[i] = OB_INVALID_INDEX; - } else { - memtable_cols_index_[i] = i - extra_rowkey_cnt; - } + col_index = col_index + storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); } + cols_index_.array_[i] = col_index; } } } - if (OB_SUCC(ret)) { - seq_read_column_count_ = 0; - while (seq_read_column_count_ < cols_index_.count() && - cols_index_.at(seq_read_column_count_) == seq_read_column_count_) { - seq_read_column_count_++; - } - max_col_index_ = -1; - for (int64_t i = 0; i < cols_index_.count(); i++) { - if (cols_index_.at(i) > max_col_index_) { - max_col_index_ = cols_index_.at(i); - } else if (-1 == cols_index_.at(i)) { - max_col_index_ = INT64_MAX; - } - } - if (OB_FAIL(datum_utils_.init(cols_desc_, schema_rowkey_cnt, is_oracle_mode, allocator))) { - STORAGE_LOG(WARN, "Failed to init datum utils", K(ret), K(schema_rowkey_cnt), K(is_oracle_mode)); - } else if (is_index_read_info) { - // no need to build index_read_info_ - index_read_info_ = nullptr; - } else if (OB_FAIL(build_index_read_info(allocator, schema_rowkey_cnt, is_oracle_mode, cols_desc))) { - STORAGE_LOG(WARN, "Failed to build index read info", K(ret)); - } - } - return ret; -} - -int ObTableReadInfo::build_index_read_info( - common::ObIAllocator &allocator, - const int64_t schema_rowkey_cnt, - const bool is_oracle_mode, - const common::ObIArray &cols_desc) -{ - int ret = OB_SUCCESS; - ObSEArray idx_col_descs; - ObColDesc idx_col_desc; - idx_col_desc.col_type_.set_varbinary(); - idx_col_desc.col_id_ = OB_APP_MIN_COLUMN_ID + rowkey_cnt_; // todo: remove col id in col desc - idx_col_desc.col_order_ = common::ObOrderType::ASC; - if (OB_UNLIKELY(schema_rowkey_cnt > cols_desc.count())) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "Invalid cols desc", K(ret), K(schema_rowkey_cnt), K(cols_desc)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < schema_rowkey_cnt; ++i) { - if (OB_FAIL(idx_col_descs.push_back(cols_desc.at(i)))) { - STORAGE_LOG(WARN, "Failed to append rowkey col descs", K(ret), K(i), K(cols_desc)); - } + if (FAILEDx(init_datum_utils(allocator))) { + LOG_WARN("failed to init sequence read info & datum utils", K(ret)); } if (OB_FAIL(ret)) { - } else if (OB_FAIL(storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(idx_col_descs))) { - STORAGE_LOG(WARN, "Failed to add extra rowkey cols", K(ret)); - } else if (OB_FAIL(idx_col_descs.push_back(idx_col_desc))) { - STORAGE_LOG(WARN, "Failed to append index col desc", K(ret), K(idx_col_desc)); - } else if (OB_ISNULL(index_read_info_ - = static_cast(allocator.alloc(sizeof(ObTableReadInfo))))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - STORAGE_LOG(WARN, "Failed to alloc memory for index read info", K(ret), K(sizeof(ObTableReadInfo))); - } else if (OB_ISNULL(index_read_info_ = new (index_read_info_) ObTableReadInfo())) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "Unexpected null index read info", K(ret)); - } else if (OB_FAIL(index_read_info_->init( - allocator, - schema_rowkey_cnt + 1, - schema_rowkey_cnt, - is_oracle_mode, - idx_col_descs, - true, /* is_multi_version_full */ - nullptr, /* column index */ - nullptr, /* column param */ - true /* is_index_read_info */))) { - STORAGE_LOG(WARN, "Failed to build index read info in table read info", K(ret)); + reset(); + } else { + is_inited_ = true; } return ret; } +int ObReadInfoStruct::prepare_arrays( + common::ObIAllocator &allocator, + const common::ObIArray &cols_desc, + const int64_t out_cols_cnt) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(cols_desc_.init_and_assign(cols_desc, allocator))) { + LOG_WARN("Fail to assign cols_desc", K(ret)); + } else if (OB_FAIL(cols_index_.init(out_cols_cnt, schema_rowkey_cnt_, allocator))) { + LOG_WARN("Fail to init cols_index", K(ret), K(out_cols_cnt)); + } else if (OB_FAIL(memtable_cols_index_.init(out_cols_cnt, schema_rowkey_cnt_, allocator))) { + LOG_WARN("Fail to init memtable_cols_index", K(ret), K(out_cols_cnt)); + } + return ret; +} + +int ObTableReadInfo::init_datum_utils(common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + seq_read_column_count_ = 0; + while (seq_read_column_count_ < cols_index_.count() && + cols_index_.at(seq_read_column_count_) == seq_read_column_count_) { + seq_read_column_count_++; + } + max_col_index_ = -1; + for (int64_t i = 0; i < cols_index_.count(); i++) { + if (cols_index_.at(i) > max_col_index_) { + max_col_index_ = cols_index_.at(i); + } else if (-1 == cols_index_.at(i)) { + max_col_index_ = INT64_MAX; + } + } + if (OB_FAIL(datum_utils_.init(cols_desc_, schema_rowkey_cnt_, is_oracle_mode_, allocator))) { + STORAGE_LOG(WARN, "Failed to init datum utils", K(ret), K_(schema_rowkey_cnt), K_(is_oracle_mode)); + } + return ret; +} + +void ObTableReadInfo::reset() +{ + ObReadInfoStruct::reset(); + trans_col_index_ = OB_INVALID_INDEX; + group_idx_col_index_ = OB_INVALID_INDEX; + seq_read_column_count_ = 0; + max_col_index_ = -1; + cols_param_.reset(); + memtable_cols_index_.reset(); +} + +/* + be careful to deal with cols_index_/memtable_cols_index_ when (de)serialize + for compat, only serialize arrays +*/ int ObTableReadInfo::serialize( char *buf, const int64_t buf_len, @@ -225,7 +369,7 @@ int ObTableReadInfo::serialize( int ret = OB_SUCCESS; LST_DO_CODE(OB_UNIS_ENCODE, - schema_column_count_, + info_, schema_rowkey_cnt_, rowkey_cnt_, trans_col_index_, @@ -233,10 +377,9 @@ int ObTableReadInfo::serialize( seq_read_column_count_, is_oracle_mode_, cols_desc_, - cols_index_, - memtable_cols_index_); + cols_index_.array_, + memtable_cols_index_.array_); if (OB_SUCC(ret)) { - if (OB_FAIL(serialization::encode_vi64(buf, buf_len, pos, cols_param_.count()))) { LOG_WARN("Fail to encode column count", K(ret)); } @@ -260,25 +403,26 @@ int ObTableReadInfo::deserialize( int64_t &pos) { int ret = OB_SUCCESS; - reset(); - cols_desc_.set_allocator(&allocator); - cols_index_.set_allocator(&allocator); - memtable_cols_index_.set_allocator(&allocator); - cols_param_.set_allocator(&allocator); LST_DO_CODE(OB_UNIS_DECODE, - schema_column_count_, + info_, schema_rowkey_cnt_, rowkey_cnt_, trans_col_index_, group_idx_col_index_, seq_read_column_count_, - is_oracle_mode_, - cols_desc_, - cols_index_, - memtable_cols_index_); + is_oracle_mode_); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(cols_desc_.deserialize(buf, data_len, pos, allocator))) { + LOG_WARN("Fail to deserialize cols_desc", K(ret), K(data_len), K(pos)); + } else if (FALSE_IT(cols_index_.rowkey_mode_ = false)) { + } else if (OB_FAIL(cols_index_.array_.deserialize(buf, data_len, pos, allocator))) { + LOG_WARN("Fail to deserialize cols_index", K(ret), K(data_len), K(pos)); + } else if (FALSE_IT(memtable_cols_index_.rowkey_mode_ = false)) { + } else if (OB_FAIL(memtable_cols_index_.array_.deserialize(buf, data_len, pos, allocator))) { + LOG_WARN("Fail to deserialize memtable_cols_index_", K(ret), K(data_len), K(pos)); + } if (OB_SUCC(ret)) { - allocator_ = &allocator; int64_t column_param_cnt = 0; if (OB_FAIL(serialization::decode_vi64(buf, data_len, pos, &column_param_cnt))) { LOG_WARN("Fail to decode column count", K(ret)); @@ -305,7 +449,7 @@ int ObTableReadInfo::deserialize( LOG_WARN("Fail to add column", K(ret)); } } - if (OB_SUCC(ret) && OB_FAIL(cols_param_.assign(tmp_columns))) { + if (OB_SUCC(ret) && OB_FAIL(cols_param_.init_and_assign(tmp_columns, allocator))) { LOG_WARN("Fail to add columns", K(ret)); } } @@ -323,12 +467,15 @@ int ObTableReadInfo::deserialize( } if (OB_FAIL(datum_utils_.init(cols_desc_, schema_rowkey_cnt_, is_oracle_mode_, allocator))) { STORAGE_LOG(WARN, "Failed to init datum utils", K(ret), K_(schema_rowkey_cnt)); - } else if (OB_FAIL(build_index_read_info( - allocator, schema_rowkey_cnt_, is_oracle_mode_, cols_desc_))) { - STORAGE_LOG(WARN, "Failed to build index read info", K(ret)); + } else { + is_inited_ = true; } } + if (OB_FAIL(ret)) { + reset(); + } + return ret; } @@ -339,7 +486,7 @@ int64_t ObTableReadInfo::get_serialize_size() const int64_t len = 0; LST_DO_CODE(OB_UNIS_ADD_LEN, - schema_column_count_, + info_, schema_rowkey_cnt_, rowkey_cnt_, trans_col_index_, @@ -347,8 +494,8 @@ int64_t ObTableReadInfo::get_serialize_size() const seq_read_column_count_, is_oracle_mode_, cols_desc_, - cols_index_, - memtable_cols_index_); + cols_index_.array_, + memtable_cols_index_.array_); if (OB_SUCC(ret)) { len += serialization::encoded_length_vi64(cols_param_.count()); @@ -365,48 +512,6 @@ int64_t ObTableReadInfo::get_serialize_size() const return len; } -int ObTableReadInfo::assign( - common::ObIAllocator &allocator, - const ObTableReadInfo &read_info) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!read_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid argument", K(ret), K(read_info)); - } else { - reset(); - cols_desc_.set_allocator(&allocator); - cols_index_.set_allocator(&allocator); - memtable_cols_index_.set_allocator(&allocator); - cols_param_.set_allocator(&allocator); - allocator_ = &allocator; - schema_column_count_ = read_info.schema_column_count_; - schema_rowkey_cnt_ = read_info.schema_rowkey_cnt_; - rowkey_cnt_ = read_info.rowkey_cnt_; - trans_col_index_ = read_info.trans_col_index_; - group_idx_col_index_ = read_info.group_idx_col_index_; - seq_read_column_count_ = read_info.seq_read_column_count_; - max_col_index_ = read_info.max_col_index_; - is_oracle_mode_ = read_info.is_oracle_mode_; - if (OB_FAIL(cols_desc_.assign(read_info.cols_desc_))) { - LOG_WARN("Fail to assign cols_desc", K(ret), K(read_info)); - } else if (OB_FAIL(cols_index_.assign(read_info.cols_index_))) { - LOG_WARN("Fail to assign cols_index", K(ret), K(read_info)); - } else if (OB_FAIL(memtable_cols_index_.assign(read_info.memtable_cols_index_))) { - LOG_WARN("Fail to assign memtable_cols_index", K(ret), K(read_info)); - } else if (!read_info.cols_param_.empty() && - OB_FAIL(cols_param_.assign(read_info.cols_param_))) { - LOG_WARN("Fail to assign cols_param", K(ret), K(read_info)); - } else if (OB_FAIL(datum_utils_.init(cols_desc_, schema_rowkey_cnt_, is_oracle_mode_, allocator))) { - STORAGE_LOG(WARN, "Failed to init datum utils", K(ret), K_(schema_rowkey_cnt)); - } else if (OB_FAIL(build_index_read_info( - allocator, schema_rowkey_cnt_, is_oracle_mode_, cols_desc_))) { - STORAGE_LOG(WARN, "Failed to build index read info", K(ret)); - } - } - return ret; -} - int64_t ObTableReadInfo::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; @@ -424,12 +529,189 @@ int64_t ObTableReadInfo::to_string(char *buf, const int64_t buf_len) const K_(datum_utils), "cols_param", ObArrayWrap(0 == cols_param_.count() ? NULL : &cols_param_.at(0), - cols_param_.count()), - KPC_(index_read_info)); + cols_param_.count())); J_OBJ_END(); return pos; } +/* + * ------------------------------- ObRowkeyReadInfo ------------------------------- + */ +int ObRowkeyReadInfo::init( + common::ObIAllocator &allocator, + const int64_t schema_column_count, + const int64_t schema_rowkey_cnt, + const bool is_oracle_mode, + const common::ObIArray &rowkey_col_descs) +{ + int ret = OB_SUCCESS; + const int64_t extra_rowkey_col_cnt = storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + const int64_t out_cols_cnt = schema_column_count + extra_rowkey_col_cnt; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), KPC(this)); + } else if (OB_UNLIKELY(0 > schema_rowkey_cnt + || out_cols_cnt < schema_rowkey_cnt + || schema_column_count > OB_ROW_MAX_COLUMNS_COUNT + || schema_rowkey_cnt > schema_column_count)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid argument", K(ret), K(schema_rowkey_cnt), K(rowkey_col_descs.count()), K(out_cols_cnt), K(schema_column_count)); + } else if (OB_FAIL(init_compat_version())) { // init compat verion + LOG_WARN("failed to init compat version", KR(ret)); + } else { + init_basic_info(schema_column_count, schema_rowkey_cnt, is_oracle_mode); // init basic info + if (OB_FAIL(prepare_arrays(allocator, rowkey_col_descs, out_cols_cnt))) { + LOG_WARN("failed to prepare arrays", K(ret), K(out_cols_cnt)); + } else if (OB_FAIL(datum_utils_.init(cols_desc_, schema_rowkey_cnt_, is_oracle_mode_, allocator))) { + STORAGE_LOG(WARN, "Failed to init datum utils", K(ret), K_(schema_rowkey_cnt), K_(is_oracle_mode)); + } else { + is_inited_ = true; + } + } + if (OB_FAIL(ret)) { + reset(); + } + return ret; +} + +int ObRowkeyReadInfo::init( + common::ObIAllocator &allocator, + const blocksstable::ObDataStoreDesc &data_store_desc) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!data_store_desc.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("data store desc is invalid", K(ret), K(data_store_desc)); + } else if (OB_FAIL(ObRowkeyReadInfo::init( + allocator, + data_store_desc.row_column_count_ - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(), + data_store_desc.schema_rowkey_col_cnt_, + lib::is_oracle_mode(), + data_store_desc.is_major_merge() ? data_store_desc.get_full_stored_col_descs() : data_store_desc.get_rowkey_col_descs()))) { + LOG_WARN("failed to init full read info", K(ret), K(data_store_desc)); + } else { + LOG_TRACE("success to init full read info", K(ret), K(data_store_desc)); + } + return ret; +} + +int64_t ObRowkeyReadInfo::get_request_count() const +{ + return schema_column_count_ + storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); +} + +int64_t ObRowkeyReadInfo::get_deep_copy_size() const +{ + return sizeof(ObRowkeyReadInfo) + + cols_desc_.get_deep_copy_size() + + cols_index_.get_deep_copy_size() + + memtable_cols_index_.get_deep_copy_size() + + datum_utils_.get_deep_copy_size(); +} + +int ObRowkeyReadInfo::deep_copy(char *buf, const int64_t buf_len, ObRowkeyReadInfo *&value) const +{ + int ret = OB_SUCCESS; + const int64_t memory_size = get_deep_copy_size(); + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len < memory_size)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalue argument", K(ret), KP(buf), K(buf_len), K(memory_size)); + } else { + ObRowkeyReadInfo *dst_value = new (buf) ObRowkeyReadInfo(); + int64_t pos = sizeof(ObRowkeyReadInfo); + dst_value->info_ = info_; + dst_value->schema_rowkey_cnt_ = schema_rowkey_cnt_; + dst_value->rowkey_cnt_ = rowkey_cnt_; + dst_value->is_oracle_mode_ = is_oracle_mode_; + // can not deep copy cols param cuz ObColumnParam need an allocator on constructor for default value + if (OB_FAIL(cols_desc_.deep_copy(buf, buf_len, pos, dst_value->cols_desc_))) { + LOG_WARN("fail to deep copy cols_desc array", K(ret)); + } else if (OB_FAIL(cols_index_.deep_copy(buf, buf_len, pos, dst_value->cols_index_))) { + LOG_WARN("fail to deep copy cols_index array", K(ret)); + } else if (OB_FAIL(memtable_cols_index_.deep_copy(buf, buf_len, pos, dst_value->memtable_cols_index_))) { + LOG_WARN("fail to deep copy memtable_cols_index array", K(ret)); + } else if (OB_FAIL(dst_value->datum_utils_.init( + cols_desc_, schema_rowkey_cnt_, is_oracle_mode_, buf_len - pos, buf + pos))) { + LOG_WARN("fail to init datum utilities on fixed memory buf", K(ret)); + } else { + pos += datum_utils_.get_deep_copy_size(); + dst_value->is_inited_ = is_inited_; + value = dst_value; + } + } + return ret; +} + + +int ObRowkeyReadInfo::serialize( + char *buf, + const int64_t buf_len, + int64_t &pos) const +{ + int ret = OB_SUCCESS; + + LST_DO_CODE(OB_UNIS_ENCODE, + info_, + schema_rowkey_cnt_, + rowkey_cnt_, + is_oracle_mode_, + cols_desc_, + cols_index_, + memtable_cols_index_); + return ret; +} + +int ObRowkeyReadInfo::deserialize( + common::ObIAllocator &allocator, + const char *buf, + const int64_t data_len, + int64_t &pos) +{ + int ret = OB_SUCCESS; + reset(); + LST_DO_CODE(OB_UNIS_DECODE, + info_, + schema_rowkey_cnt_, + rowkey_cnt_, + is_oracle_mode_); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(cols_desc_.deserialize(buf, data_len, pos, allocator))) { + LOG_WARN("Fail to deserialize cols_desc", K(ret), K(data_len), K(pos)); + } else if (OB_FAIL(cols_index_.deserialize(buf, data_len, pos, allocator))) { + LOG_WARN("Fail to deserialize cols_index", K(ret), K(data_len), K(pos)); + } else if (OB_FAIL(memtable_cols_index_.deserialize(buf, data_len, pos, allocator))) { + LOG_WARN("Fail to deserialize memtable_cols_index", K(ret), K(data_len), K(pos)); + } + + if (OB_SUCC(ret) && cols_desc_.count() > 0) { + if (OB_FAIL(datum_utils_.init(cols_desc_, schema_rowkey_cnt_, is_oracle_mode_, allocator))) { + STORAGE_LOG(WARN, "Failed to init datum utils", K(ret), K_(schema_rowkey_cnt)); + } else { + is_inited_ = true; + } + } + if (OB_FAIL(ret)) { + reset(); + } + return ret; +} + +int64_t ObRowkeyReadInfo::get_serialize_size() const +{ + int ret = OB_SUCCESS; + int64_t len = 0; + + LST_DO_CODE(OB_UNIS_ADD_LEN, + info_, + schema_rowkey_cnt_, + rowkey_cnt_, + is_oracle_mode_, + cols_desc_, + cols_index_, + memtable_cols_index_); + return len; +} + } } diff --git a/src/storage/access/ob_table_read_info.h b/src/storage/access/ob_table_read_info.h index e8840d894..7e141dc93 100644 --- a/src/storage/access/ob_table_read_info.h +++ b/src/storage/access/ob_table_read_info.h @@ -13,7 +13,8 @@ #ifndef OB_STORAGE_ACCESS_TABLE_READ_INFO_H_ #define OB_STORAGE_ACCESS_TABLE_READ_INFO_H_ -#include "lib/container/ob_fixed_array.h" +#include "storage/meta_mem/ob_fixed_meta_obj_array.h" +#include "storage/meta_mem/ob_meta_obj_struct.h" #include "storage/blocksstable/ob_datum_row.h" namespace oceanbase { @@ -23,96 +24,247 @@ class ObColumnParam; class ObColDesc; } } +namespace blocksstable{ +struct ObDataStoreDesc; +} using namespace share::schema; namespace storage { class ObStorageSchema; -typedef common::ObFixedArray Columns; -typedef common::ObFixedArray ColumnsIndex; -typedef common::ObFixedArray ColDescArray; - -class ObTableReadInfo +typedef ObFixedMetaObjArray Columns; +typedef ObFixedMetaObjArray ColumnsIndex; +typedef ObFixedMetaObjArray ColDescArray; +/* + ObITableReadInfo: basic interface + --ObReadInfoStruct: basic struct, implement get* func + ----ObTableReadInfo: for access, may not get all column + ----ObRowkeyReadInfo: for compaction, get all column | for mid-index, get rowkey +*/ +struct ObColumnIndexArray { public: - ObTableReadInfo() - : allocator_(nullptr), + ObColumnIndexArray(const bool rowkey_mode = false, const bool for_memtable = false) + : version_(COLUMN_INDEX_ARRAY_VERSION), + rowkey_mode_(rowkey_mode), + for_memtable_(for_memtable), + reserved_(0), + schema_rowkey_cnt_(0), + column_cnt_(0), + array_() {} + ~ObColumnIndexArray() { reset(); } + void reset() + { + rowkey_mode_ = false; + for_memtable_ = false; + schema_rowkey_cnt_ = 0; + column_cnt_ = 0; + array_.reset(); + } + bool is_valid() const + { + return (rowkey_mode_ && column_cnt_ > schema_rowkey_cnt_ && schema_rowkey_cnt_ > 0) + || (!rowkey_mode_ && array_.count() > 0); + } + int init( + const int64_t count, + const int64_t schema_rowkey_cnt, + ObIAllocator &allocator); + + int32_t at(int64_t idx) const; + OB_INLINE int64_t count() const + { + int64_t ret_count = 0; + if (rowkey_mode_) { + ret_count = column_cnt_; + } else { + ret_count = array_.count(); + } + return ret_count; + } + + int64_t get_deep_copy_size() const; + int deep_copy( + char *dst_buf, + const int64_t buf_size, + int64_t &pos, + ObColumnIndexArray &dst_array) const; + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize(const char *buf, const int64_t data_len, int64_t &pos, common::ObIAllocator &allocator); + int64_t get_serialize_size() const; + DECLARE_TO_STRING; + + const static uint8_t COLUMN_INDEX_ARRAY_VERSION = 1; + uint8_t version_; + bool rowkey_mode_; + bool for_memtable_; + uint8_t reserved_; + uint32_t schema_rowkey_cnt_; + uint32_t column_cnt_; + ObFixedMetaObjArray array_; +}; +class ObITableReadInfo +{ +public: + ObITableReadInfo() = default; + virtual ~ObITableReadInfo() = default; + virtual bool is_oracle_mode() const = 0; + virtual int64_t get_schema_column_count() const = 0; + virtual int64_t get_seq_read_column_count() const = 0; + virtual int64_t get_request_count() const = 0; + virtual int64_t get_schema_rowkey_count() const = 0; + virtual int64_t get_rowkey_count() const = 0; + virtual int64_t get_group_idx_col_index() const = 0; + virtual int64_t get_max_col_index() const = 0; + virtual int64_t get_trans_col_index() const = 0; + virtual const common::ObIArray &get_columns_desc() const = 0; + virtual const ObColumnIndexArray &get_columns_index() const = 0; + virtual const ObColumnIndexArray &get_memtable_columns_index() const = 0; + virtual const blocksstable::ObStorageDatumUtils &get_datum_utils() const = 0; + virtual const common::ObIArray *get_columns() const = 0; + virtual bool is_valid() const = 0; + virtual void reset() = 0; + DECLARE_PURE_VIRTUAL_TO_STRING; +}; + +class ObReadInfoStruct : public ObITableReadInfo +{ +public: + ObReadInfoStruct(const bool rowkey_mode = false) + : ObITableReadInfo(), + is_inited_(false), + is_oracle_mode_(false), + allocator_(nullptr), schema_column_count_(0), + compat_version_(READ_INFO_VERSION_V1), + reserved_(0), schema_rowkey_cnt_(0), rowkey_cnt_(0), - trans_col_index_(OB_INVALID_INDEX), - group_idx_col_index_(OB_INVALID_INDEX), - seq_read_column_count_(0), - max_col_index_(-1), - is_oracle_mode_(false), - cols_param_(), cols_desc_(), - cols_index_(), - memtable_cols_index_(), - datum_utils_(), - index_read_info_(nullptr) + cols_index_(rowkey_mode, false/*for_memtable*/), + memtable_cols_index_(rowkey_mode, true/*for_memtable*/), + datum_utils_() {} + virtual ~ObReadInfoStruct() { reset(); } + virtual bool is_valid() const override + { + return is_inited_ + && schema_rowkey_cnt_ <= cols_desc_.count() + && 0 < cols_desc_.count() + && 0 < cols_index_.count() + && schema_rowkey_cnt_ <= schema_column_count_ + && datum_utils_.is_valid(); + } + virtual void reset() override; + + OB_INLINE virtual bool is_oracle_mode() const override { return is_oracle_mode_; } + OB_INLINE virtual int64_t get_schema_column_count() const override { return schema_column_count_; } + OB_INLINE virtual int64_t get_schema_rowkey_count() const override { return schema_rowkey_cnt_; } + OB_INLINE virtual int64_t get_rowkey_count() const override { return rowkey_cnt_; } + OB_INLINE virtual const common::ObIArray &get_columns_desc() const override + { return cols_desc_; } + OB_INLINE virtual int64_t get_request_count() const override + { return cols_desc_.count(); } + OB_INLINE virtual const ObColumnIndexArray &get_columns_index() const override + { return cols_index_; } + OB_INLINE virtual const ObColumnIndexArray &get_memtable_columns_index() const override + { return memtable_cols_index_; } + OB_INLINE virtual const blocksstable::ObStorageDatumUtils &get_datum_utils() const override { return datum_utils_; } + OB_INLINE virtual int64_t get_group_idx_col_index() const override + { + OB_ASSERT_MSG(false, "ObReadInfoStruct dose not promise group idx col index"); + return OB_INVALID_INDEX; + } + OB_INLINE virtual int64_t get_max_col_index() const override + { + OB_ASSERT_MSG(false, "ObReadInfoStruct dose not promise max col index"); + return OB_INVALID_INDEX; + } + OB_INLINE virtual int64_t get_trans_col_index() const override + { + OB_ASSERT_MSG(false, "ObReadInfoStruct dose not promise trans col index"); + return OB_INVALID_INDEX; + } + OB_INLINE virtual int64_t get_seq_read_column_count() const override + { + OB_ASSERT_MSG(false, "ObReadInfoStruct dose not promise seq read column count"); + return OB_INVALID_INDEX; + } + OB_INLINE virtual const common::ObIArray *get_columns() const override + { + OB_ASSERT_MSG(false, "ObReadInfoStruct dose not promise columns array"); + return nullptr; + } + DECLARE_TO_STRING; + void init_basic_info(const int64_t schema_column_count, + const int64_t schema_rowkey_cnt, + const bool is_oracle_mode); + int prepare_arrays(common::ObIAllocator &allocator, + const common::ObIArray &cols_desc, + const int64_t col_cnt); + int init_compat_version(); +protected: + const int64_t READ_INFO_VERSION_V0 = 0; + const int64_t READ_INFO_VERSION_V1 = 1; + bool is_inited_; + bool is_oracle_mode_; + ObIAllocator *allocator_; + // distinguish schema changed by schema column count + union { + uint64_t info_; + struct { + uint32_t schema_column_count_; + uint16_t compat_version_; + uint16_t reserved_; + }; + }; + int64_t schema_rowkey_cnt_; + int64_t rowkey_cnt_; + ColDescArray cols_desc_; // used in storage layer, won't serialize + ObColumnIndexArray cols_index_; // col index in sstable + ObColumnIndexArray memtable_cols_index_; // there is no multi verison rowkey col in memtable + blocksstable::ObStorageDatumUtils datum_utils_; +}; + +class ObTableReadInfo : public ObReadInfoStruct +{ +public: + ObTableReadInfo(); virtual ~ObTableReadInfo(); - void reset(); + virtual void reset() override; /* * schema_rowkey_cnt: schema row key count * cols_desc: access col descs - * is_multi_version_full: input is full multi version column descs, extra rowkeys included * storage_cols_index: access column store index in storage file row * cols_param: access column params - * index_read_info: pointer to index block read info if this is a full read info */ - int init( + virtual int init( common::ObIAllocator &allocator, const int64_t schema_column_count, const int64_t schema_rowkey_cnt, const bool is_oracle_mode, const common::ObIArray &cols_desc, - const bool is_multi_version_full = false, - const common::ObIArray *storage_cols_index = nullptr, - const common::ObIArray *cols_param = nullptr, - const bool is_index_read_info = false); - bool is_valid() const + const common::ObIArray *storage_cols_index, + const common::ObIArray *cols_param = nullptr); + virtual OB_INLINE bool is_valid() const override { - return schema_rowkey_cnt_ <= seq_read_column_count_ - && seq_read_column_count_ <= cols_desc_.count() - && 0 < cols_desc_.count() - && 0 < schema_column_count_ - && datum_utils_.is_valid() - && cols_desc_.count() == cols_index_.count(); + return ObReadInfoStruct::is_valid() + && cols_desc_.count() == cols_index_.count() + && schema_rowkey_cnt_ <= seq_read_column_count_ + && seq_read_column_count_ <= cols_desc_.count(); } - bool is_valid_full_read_info() const - { - return is_valid() - && nullptr != index_read_info_ - && index_read_info_->is_valid(); - } - OB_INLINE bool is_oracle_mode() const { return is_oracle_mode_; } - OB_INLINE int64_t get_schema_column_count() const - { return schema_column_count_; } - OB_INLINE int64_t get_trans_col_index() const + OB_INLINE virtual int64_t get_trans_col_index() const override { return trans_col_index_; } OB_INLINE int64_t get_group_idx_col_index() const { return group_idx_col_index_; } - OB_INLINE int64_t get_schema_rowkey_count() const - { return schema_rowkey_cnt_; } - OB_INLINE int64_t get_rowkey_count() const - { return rowkey_cnt_; } OB_INLINE int64_t get_seq_read_column_count() const { return seq_read_column_count_; } - OB_INLINE const common::ObIArray &get_columns() const - { return cols_param_; } - OB_INLINE const common::ObIArray &get_columns_desc() const - { return cols_desc_; } - OB_INLINE int64_t get_request_count() const + virtual const common::ObIArray *get_columns() const + { return &cols_param_; } + + // this func only called in query + OB_INLINE virtual int64_t get_request_count() const override { return cols_desc_.count(); } - OB_INLINE const common::ObIArray &get_columns_index() const - { return cols_index_; } - OB_INLINE const common::ObIArray &get_memtable_columns_index() const - { return memtable_cols_index_; } - OB_INLINE const blocksstable::ObStorageDatumUtils &get_datum_utils() const { return datum_utils_; } - OB_INLINE const ObTableReadInfo *get_index_read_info() const { return index_read_info_; } - OB_INLINE int64_t get_max_col_index() const { return max_col_index_; } - int assign(common::ObIAllocator &allocator, const ObTableReadInfo &read_info); + OB_INLINE virtual int64_t get_max_col_index() const override { return max_col_index_; } int deserialize( common::ObIAllocator &allocator, const char *buf, @@ -123,37 +275,56 @@ public: const int64_t buf_len, int64_t &pos) const; int64_t get_serialize_size() const; - DECLARE_TO_STRING; private: - int build_index_read_info( - common::ObIAllocator &allocator, - const int64_t schema_rowkey_cnt, - const bool is_oracle_mode, - const common::ObIArray &cols_desc); DISALLOW_COPY_AND_ASSIGN(ObTableReadInfo); + int init_datum_utils(common::ObIAllocator &allocator); private: - ObIAllocator *allocator_; // distinguish schema changed by schema column count - int64_t schema_column_count_; - int64_t schema_rowkey_cnt_; - int64_t rowkey_cnt_; int64_t trans_col_index_; int64_t group_idx_col_index_; // the count of common prefix between request columns and store columns int64_t seq_read_column_count_; int64_t max_col_index_; - bool is_oracle_mode_; Columns cols_param_; - ColDescArray cols_desc_; // used in storage layer, won't serialize - ColumnsIndex cols_index_; // there is no multi verison rowkey col in memtable, we need another col idx array - ColumnsIndex memtable_cols_index_; - blocksstable::ObStorageDatumUtils datum_utils_; - ObTableReadInfo *index_read_info_; // no need to serialize }; +class ObRowkeyReadInfo final : public ObReadInfoStruct +{ +public: + ObRowkeyReadInfo() : ObReadInfoStruct(true/*rowkey_mode*/) {} + virtual ~ObRowkeyReadInfo() {} + + int init( + common::ObIAllocator &allocator, + const int64_t schema_column_count, + const int64_t schema_rowkey_cnt, + const bool is_oracle_mode, + const common::ObIArray &rowkey_col_descs); + int init(common::ObIAllocator &allocator, + const blocksstable::ObDataStoreDesc &data_store_desc); + + OB_INLINE virtual int64_t get_seq_read_column_count() const override + { return get_request_count(); } + OB_INLINE virtual int64_t get_trans_col_index() const override + { return schema_rowkey_cnt_; } + virtual int64_t get_request_count() const override; + int deep_copy(char *buf, const int64_t buf_len, ObRowkeyReadInfo *&value) const; + int64_t get_deep_copy_size() const; + int deserialize( + common::ObIAllocator &allocator, + const char *buf, + const int64_t data_len, + int64_t &pos); + int serialize( + char *buf, + const int64_t buf_len, + int64_t &pos) const; + int64_t get_serialize_size() const; + DISALLOW_COPY_AND_ASSIGN(ObRowkeyReadInfo); +}; } } #endif //OB_STORAGE_ACCESS_TABLE_READ_INFO_H_ diff --git a/src/storage/access/ob_table_scan_iterator.cpp b/src/storage/access/ob_table_scan_iterator.cpp old mode 100644 new mode 100755 index bcc732ef7..fb23abc28 --- a/src/storage/access/ob_table_scan_iterator.cpp +++ b/src/storage/access/ob_table_scan_iterator.cpp @@ -220,8 +220,9 @@ int ObTableScanIterator::init(ObTableScanParam &scan_param, const ObTabletHandle STORAGE_LOG(WARN, "Failed to init table scan range", K(ret), K(scan_param)); } else { scan_param_ = &scan_param; - get_table_param_.tablet_iter_.tablet_handle_ = tablet_handle; - if (OB_FAIL(prepare_table_param(tablet_handle))) { + if (OB_FAIL(get_table_param_.tablet_iter_.set_tablet_handle(tablet_handle))) { + STORAGE_LOG(WARN, "Fail to set tablet handle to iter", K(ret)); + } else if (OB_FAIL(prepare_table_param(tablet_handle))) { STORAGE_LOG(WARN, "Fail to prepare table param, ", K(ret)); } else if (OB_FAIL(prepare_table_context())) { STORAGE_LOG(WARN, "Fail to prepare table ctx, ", K(ret)); @@ -251,8 +252,9 @@ int ObTableScanIterator::switch_param(ObTableScanParam &scan_param, const ObTabl STORAGE_LOG(WARN, "Failed to init table scan range", K(ret), K(scan_param)); } else { scan_param_ = &scan_param; - get_table_param_.tablet_iter_.tablet_handle_ = tablet_handle; - if (OB_FAIL(prepare_table_param(tablet_handle))) { + if (OB_FAIL(get_table_param_.tablet_iter_.set_tablet_handle(tablet_handle))) { + STORAGE_LOG(WARN, "Fail to set tablet handle to iter", K(ret)); + } else if (OB_FAIL(prepare_table_param(tablet_handle))) { STORAGE_LOG(WARN, "Fail to prepare table param, ", K(ret)); } else if (OB_FAIL(prepare_table_context())) { STORAGE_LOG(WARN, "Fail to prepare table ctx, ", K(ret)); @@ -374,9 +376,8 @@ int ObTableScanIterator::open_iter() if (scan_param_->sample_info_.is_block_sample()) { if (nullptr == scan_merge_ && OB_FAIL(init_scan_iter(scan_merge_))) { STORAGE_LOG(WARN, "Failed to init scanmerge", K(ret)); - } else if (OB_FAIL(get_table_param_.tablet_iter_.tablet_handle_.get_obj()->get_read_tables( + } else if (OB_FAIL(get_table_param_.tablet_iter_.refresh_read_tables_from_tablet( main_table_ctx_.store_ctx_->mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), - get_table_param_.tablet_iter_, false /*allow_not_ready*/ ))) { STORAGE_LOG(WARN, "Fail to read tables", K(ret)); } else if (!scan_param_->sample_info_.force_block_ && @@ -467,27 +468,36 @@ int ObTableScanIterator::can_retire_to_row_sample(bool &retire) int64_t sstable_row_count = 0; common::ObSEArray memtables; while (OB_SUCC(ret)) { + ObSSTableMetaHandle sst_meta_hdl; ObITable *table = nullptr; - if (OB_FAIL(get_table_param_.tablet_iter_.table_iter_.get_next(table))) { + if (OB_FAIL(get_table_param_.tablet_iter_.table_iter()->get_next(table))) { if (OB_LIKELY(OB_ITER_END == ret)) { ret = OB_SUCCESS; break; } else { - STORAGE_LOG(WARN, "Fail to get next table iter", K(ret), K(get_table_param_.tablet_iter_.table_iter_)); + STORAGE_LOG(WARN, "Fail to get next table iter", K(ret), K(get_table_param_.tablet_iter_.table_iter())); } } else if (table->is_memtable()) { memtables.push_back(table); } else if (table->is_sstable()) { - sstable_row_count += static_cast(table)->get_meta().get_basic_meta().row_count_; + if (OB_FAIL(static_cast(table)->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); + } else { + sstable_row_count += sst_meta_hdl.get_sstable_meta().get_row_count(); + } } } if (OB_FAIL(ret)) { - } else if (FALSE_IT(get_table_param_.tablet_iter_.table_iter_.resume())) { + } else if (FALSE_IT(get_table_param_.tablet_iter_.table_iter()->resume())) { } else if (memtables.count() > 0) { ObPartitionEst batch_est; ObSEArray est_records; - ObTableEstimateBaseInput base_input(scan_param_->scan_flag_, memtables.at(0)->get_key().tablet_id_.id(), - transaction::ObTransID(), memtables, get_table_param_.tablet_iter_.tablet_handle_); + ObTableEstimateBaseInput base_input( + scan_param_->scan_flag_, + memtables.at(0)->get_key().tablet_id_.id(), + transaction::ObTransID(), + memtables, + get_table_param_.tablet_iter_.get_tablet_handle()); if (OB_FAIL(ObTableEstimator::estimate_row_count_for_scan(base_input, table_scan_range_.get_ranges(), batch_est, est_records))) { STORAGE_LOG(WARN, "Failed to estimate row count for scan", K(ret), KPC(scan_param_), K(table_scan_range_)); } else { @@ -572,7 +582,7 @@ int ObTableScanIterator::check_ls_offline_after_read() auto &acc_ctx = ctx_guard_.get_store_ctx().mvcc_acc_ctx_; - if (acc_ctx.tx_table_guard_.check_ls_offline()) { + if (acc_ctx.tx_table_guards_.check_ls_offline()) { ret = OB_LS_OFFLINE; STORAGE_LOG(WARN, "ls offline during the read operation", K(ret), K(acc_ctx.snapshot_)); } diff --git a/src/storage/access/ob_vector_store.cpp b/src/storage/access/ob_vector_store.cpp index 62f0f62cb..6d2fdbbc8 100644 --- a/src/storage/access/ob_vector_store.cpp +++ b/src/storage/access/ob_vector_store.cpp @@ -89,7 +89,7 @@ int ObVectorStore::init(const ObTableAccessParam ¶m) LOG_WARN("Fail to init col params", K(ret)); } else if (OB_FAIL(map_types_.init(expr_count))) { LOG_WARN("Fail to init map types", K(ret)); - } else if (OB_FAIL(row_buf_.init(*context_.stmt_allocator_, param.iter_param_.get_full_out_col_cnt()))) { + } else if (OB_FAIL(row_buf_.init(*context_.stmt_allocator_, param.iter_param_.get_max_out_col_cnt()))) { LOG_WARN("Fail to init datum ro types", K(ret)); } for (int64_t i = 0; OB_SUCC(ret) && i < expr_count; i++) { diff --git a/src/storage/backup/ob_backup_ctx.cpp b/src/storage/backup/ob_backup_ctx.cpp old mode 100644 new mode 100755 index 2bf5c7be4..2c2a69708 --- a/src/storage/backup/ob_backup_ctx.cpp +++ b/src/storage/backup/ob_backup_ctx.cpp @@ -23,6 +23,7 @@ #include "share/backup/ob_backup_struct.h" #include "observer/ob_server_event_history_table_operator.h" #include "storage/blocksstable/ob_logic_macro_id.h" +#include "share/backup/ob_backup_data_table_operator.h" #include @@ -261,130 +262,6 @@ void ObSimpleBackupStatMgr::reset_stat_list_() } } -/* ObBackupFileWriteCtx */ - -ObBackupFileWriteCtx::ObBackupFileWriteCtx() - : is_inited_(false), - file_size_(0), - max_file_size_(0), - io_fd_(), - dev_handle_(NULL), - data_buffer_("BackupCtx"), - bandwidth_throttle_(NULL) -{} - -ObBackupFileWriteCtx::~ObBackupFileWriteCtx() -{} - -int ObBackupFileWriteCtx::open(const int64_t max_file_size, const common::ObIOFd &io_fd, - common::ObIODevice &dev_handle, common::ObInOutBandwidthThrottle &bandwidth_throttle) -{ - int ret = OB_SUCCESS; - if (IS_INIT) { - ret = OB_INIT_TWICE; - LOG_WARN("backup data ctx init twice", K(ret)); - } else if (max_file_size < 0 || !io_fd.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), K(max_file_size), K(io_fd)); - } else if (OB_FAIL(data_buffer_.ensure_space(OB_DEFAULT_MACRO_BLOCK_SIZE))) { - LOG_WARN("failed to ensure space", K(ret)); - } else { - file_size_ = 0; - max_file_size_ = max_file_size; - io_fd_ = io_fd; - dev_handle_ = &dev_handle; - bandwidth_throttle_ = &bandwidth_throttle; - is_inited_ = true; - } - return ret; -} - -int ObBackupFileWriteCtx::append_buffer(const blocksstable::ObBufferReader &buffer, const bool is_last_part) -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("file write ctx do not init", K(ret)); - } else if (!buffer.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), K(buffer)); - } else if (OB_FAIL(write_buffer_(buffer.data(), buffer.length(), is_last_part))) { - LOG_WARN("failed to write buffer", K(ret), K(buffer), K(is_last_part)); - } else { - LOG_DEBUG("append buffer to file write ctx", K(buffer)); - } - return ret; -} - -int ObBackupFileWriteCtx::close() -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("file write ctx do not init", K(ret)); - } else if (OB_FAIL(commit_file_())) { - LOG_WARN("failed to commit file", K(ret)); - } - return ret; -} - -int ObBackupFileWriteCtx::write_buffer_(const char *buf, const int64_t len, const bool is_last_part) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(buf) || len <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), K(buf), K(len)); - } else if (OB_FAIL(data_buffer_.write(buf, len))) { - LOG_WARN("failed to write file writer", K(ret), K(buf), K(len)); - } else if (OB_FAIL(flush_buffer_(is_last_part))) { - LOG_WARN("failed to flush buffer", K(ret), K(is_last_part)); - } - return ret; -} - -bool ObBackupFileWriteCtx::check_can_flush_(const bool is_last_part) const -{ - return is_last_part || data_buffer_.length() >= OB_MAX_BACKUP_MEM_BUF_LEN; -} - -int ObBackupFileWriteCtx::flush_buffer_(const bool is_last_part) -{ - int ret = OB_SUCCESS; - int64_t write_size = 0; - const int64_t offset = file_size_; - if (!check_can_flush_(is_last_part)) { - LOG_DEBUG("can not flush now", K(is_last_part), K(data_buffer_)); - } else if (OB_ISNULL(dev_handle_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("dev handle should not be null", K(ret)); - } else if (OB_FAIL(dev_handle_->pwrite(io_fd_, offset, data_buffer_.length(), data_buffer_.data(), write_size))) { - LOG_WARN("failed to write data buffer", K(ret), K(data_buffer_)); - } else if (data_buffer_.length() != write_size) { - ret = OB_IO_ERROR; - LOG_WARN("write length not equal buffer length", K(offset), K(data_buffer_.length()), K(write_size)); - } else { - file_size_ += write_size; - data_buffer_.reuse(); - } - return ret; -} - -int ObBackupFileWriteCtx::commit_file_() -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(dev_handle_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("dev handle should not be null", K(ret)); - } else if (OB_FAIL(flush_buffer_(true /*is_last_part*/))) { - LOG_WARN("failed to flush buffer", K(ret)); - } else if (OB_FAIL(dev_handle_->close(io_fd_))) { - LOG_WARN("failed to close file", K(ret), K_(io_fd)); - } else { - LOG_INFO("backup file write ctx commit file"); - } - return ret; -} - /* ObBackupDataCtx */ ObBackupDataCtx::ObBackupDataCtx() @@ -399,15 +276,14 @@ ObBackupDataCtx::ObBackupDataCtx() macro_index_buffer_node_(), meta_index_buffer_node_(), file_trailer_(), - tmp_buffer_("BackupCtx"), - bandwidth_throttle_(NULL) + tmp_buffer_("BackupDataCtx") {} ObBackupDataCtx::~ObBackupDataCtx() {} int ObBackupDataCtx::open(const ObLSBackupDataParam ¶m, const share::ObBackupDataType &backup_data_type, - const int64_t file_id, common::ObInOutBandwidthThrottle &bandwidth_throttle) + const int64_t file_id) { int ret = OB_SUCCESS; static const int64_t BUF_SIZE = 4 * 1024 * 1024; @@ -431,7 +307,6 @@ int ObBackupDataCtx::open(const ObLSBackupDataParam ¶m, const share::ObBacku file_id_ = file_id; file_offset_ = 0; backup_data_type_ = backup_data_type; - bandwidth_throttle_ = &bandwidth_throttle; is_inited_ = true; if (OB_FAIL(prepare_file_write_ctx_(param, backup_data_type, file_id))) { LOG_WARN("failed to prepare file write ctx", K(ret), K(param), K(backup_data_type), K(file_id)); @@ -543,14 +418,11 @@ int ObBackupDataCtx::prepare_file_write_ctx_( int ret = OB_SUCCESS; share::ObBackupPath backup_path; const int64_t data_file_size = get_data_file_size(); - if (OB_ISNULL(bandwidth_throttle_)) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("bandwidth_throttle is NULL", K(ret)); - } else if (OB_FAIL(get_macro_block_backup_path_(file_id, backup_path))) { + if (OB_FAIL(get_macro_block_backup_path_(file_id, backup_path))) { LOG_WARN("failed to get macro block backup path", K(ret), K(file_id)); } else if (OB_FAIL(open_file_writer_(backup_path))) { LOG_WARN("failed to open file writer", K(ret), K(backup_path)); - } else if (OB_FAIL(file_write_ctx_.open(data_file_size, io_fd_, *dev_handle_, *bandwidth_throttle_))) { + } else if (OB_FAIL(file_write_ctx_.open(data_file_size, io_fd_, *dev_handle_))) { LOG_WARN("failed to open file write ctx", K(ret), K(param), K(type), K(backup_path), K(data_file_size), K(file_id)); } return ret; @@ -952,7 +824,8 @@ ObLSBackupCtx::ObLSBackupCtx() backup_retry_ctx_(), sql_proxy_(NULL), rebuild_seq_(), - check_tablet_info_cost_time_() + check_tablet_info_cost_time_(), + backup_tx_table_filled_tx_scn_(share::SCN::min_scn()) {} ObLSBackupCtx::~ObLSBackupCtx() @@ -964,7 +837,7 @@ int ObLSBackupCtx::open( const ObLSBackupParam ¶m, const share::ObBackupDataType &backup_data_type, common::ObMySQLProxy &sql_proxy) { int ret = OB_SUCCESS; - ObArray tablet_list; + ObArray tablet_list; ObILSTabletIdReader *reader = NULL; if (IS_INIT) { ret = OB_INIT_TWICE; @@ -998,8 +871,8 @@ int ObLSBackupCtx::open( } else if (OB_FAIL(get_all_tablet_id_list_(reader, tablet_list))) { LOG_WARN("failed to get all tablet id list", K(ret)); } else if (tablet_list.empty()) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("no tablet in log stream", K(ret), K(param)); + ret = OB_NO_TABLET_NEED_BACKUP; + LOG_WARN("no tablet in log stream need to backup", K(ret), K(param)); } else if (OB_FAIL(seperate_tablet_id_list_(tablet_list, sys_tablet_id_list_, data_tablet_id_list_))) { LOG_WARN("failed to seperate tablet id list", K(ret), K(tablet_list)); } else if (OB_FAIL(recover_last_retry_ctx_())) { @@ -1549,10 +1422,11 @@ int ObLSBackupCtx::get_all_tablet_id_list_( int ret = OB_SUCCESS; const int64_t turn_id = param_.turn_id_; const share::ObLSID &ls_id = param_.ls_id_; + ObArray tablet_id_list; if (OB_ISNULL(reader)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream tablet id reader should not be null", K(ret)); - } else if (OB_FAIL(reader->get_tablet_id_list(turn_id, ls_id, tablet_list))) { + } else if (OB_FAIL(reader->get_tablet_id_list(backup_data_type_, turn_id, ls_id, tablet_list))) { LOG_WARN("failed to get all tablet id list", K(ret), K_(param)); } else { LOG_INFO("get all tablet id list", K_(param), K(tablet_list)); @@ -1561,7 +1435,8 @@ int ObLSBackupCtx::get_all_tablet_id_list_( } int ObLSBackupCtx::seperate_tablet_id_list_(const common::ObIArray &tablet_id_list, - common::ObIArray &sys_tablet_id_list, common::ObIArray &data_tablet_id_list) + common::ObIArray &sys_tablet_id_list, + common::ObIArray &data_tablet_id_list) { int ret = OB_SUCCESS; sys_tablet_id_list.reset(); @@ -1646,7 +1521,7 @@ int ObLSBackupCtx::check_need_skip_major_(const common::ObTabletID &tablet_id, b int ObLSBackupCtx::get_next_tablet_(common::ObTabletID &tablet_id) { int ret = OB_SUCCESS; - ObArray *list_ptr = backup_data_type_.is_sys_backup() ? &sys_tablet_id_list_ : &data_tablet_id_list_; + ObArray *list_ptr = backup_data_type_.is_sys_backup() ? &sys_tablet_id_list_ : &data_tablet_id_list_; if (OB_ISNULL(list_ptr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("list ptr should not be null", K(ret)); diff --git a/src/storage/backup/ob_backup_ctx.h b/src/storage/backup/ob_backup_ctx.h index 322bceaae..bc9c4893b 100644 --- a/src/storage/backup/ob_backup_ctx.h +++ b/src/storage/backup/ob_backup_ctx.h @@ -22,12 +22,13 @@ #include "lib/utility/utility.h" #include "share/ob_ls_id.h" #include "share/backup/ob_backup_path.h" -#include "storage/backup/ob_backup_reader.h" #include "storage/backup/ob_backup_data_struct.h" #include "storage/backup/ob_backup_tmp_file.h" #include "storage/backup/ob_backup_utils.h" #include "storage/blocksstable/ob_data_buffer.h" #include "storage/blocksstable/ob_logic_macro_id.h" +#include "storage/backup/ob_backup_file_writer_ctx.h" +#include "lib/oblog/ob_log_module.h" namespace oceanbase { namespace backup { @@ -95,7 +96,7 @@ int ObSimpleBackupStatMgr::get_missing_items_( missing.reset(); if (lhs.count() < rhs.count()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("count not expected", K(ret), K(lhs.count()), K(rhs.count())); + STORAGE_LOG(WARN, "count not expected", K(ret), K(lhs.count()), K(rhs.count())); } else { for (int64_t i = 0; OB_SUCC(ret) && i < lhs.count(); ++i) { bool exist = false; @@ -109,7 +110,7 @@ int ObSimpleBackupStatMgr::get_missing_items_( } if (OB_SUCC(ret) && !exist) { if (OB_FAIL(missing.push_back(lhs_item))) { - LOG_WARN("failed to push back", K(ret), K(lhs_item)); + STORAGE_LOG(WARN, "failed to push back", K(ret), K(lhs_item)); } } } @@ -123,51 +124,16 @@ int ObSimpleBackupStatMgr::print_missing_items_(const common::ObIArray &missi int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < missing.count(); ++i) { const T &item = missing.at(i); - LOG_ERROR("BACKUP ITEM IS MISSING", K_(tenant_id), K_(ls_id), K(item)); + STORAGE_LOG(ERROR, "BACKUP ITEM IS MISSING", K_(tenant_id), K_(ls_id), K(item)); } return ret; } -struct ObBackupFileWriteCtx { -public: - ObBackupFileWriteCtx(); - virtual ~ObBackupFileWriteCtx(); - int open(const int64_t max_file_size, const common::ObIOFd &io_fd, common::ObIODevice &device_handle, - common::ObInOutBandwidthThrottle &bandwidth_throttle); - bool is_opened() const - { - return is_inited_; - } - int append_buffer(const blocksstable::ObBufferReader &buffer, const bool is_last_part = false); - int64_t get_file_size() const - { - return file_size_; - } - int close(); - -private: - int write_buffer_(const char *buf, const int64_t len, const bool is_last_part); - bool check_can_flush_(const bool is_last_part) const; - int flush_buffer_(const bool is_last_part); - int commit_file_(); - -private: - bool is_inited_; - int64_t file_size_; - int64_t max_file_size_; - common::ObIOFd io_fd_; - common::ObIODevice *dev_handle_; - blocksstable::ObSelfBufferWriter data_buffer_; - common::ObInOutBandwidthThrottle *bandwidth_throttle_; - DISALLOW_COPY_AND_ASSIGN(ObBackupFileWriteCtx); -}; - struct ObBackupDataCtx { public: ObBackupDataCtx(); virtual ~ObBackupDataCtx(); - int open(const ObLSBackupDataParam ¶m, const share::ObBackupDataType &type, const int64_t file_id, - common::ObInOutBandwidthThrottle &bandwidth_throttle); + int open(const ObLSBackupDataParam ¶m, const share::ObBackupDataType &type, const int64_t file_id); int write_backup_file_header(const ObBackupFileHeader &file_header); int write_macro_block_data(const blocksstable::ObBufferReader ¯o_data, const blocksstable::ObLogicMacroBlockId &logic_id, ObBackupMacroBlockIndex ¯o_index); @@ -232,7 +198,6 @@ public: ObBackupIndexBufferNode meta_index_buffer_node_; ObBackupDataFileTrailer file_trailer_; blocksstable::ObSelfBufferWriter tmp_buffer_; - common::ObInOutBandwidthThrottle *bandwidth_throttle_; DISALLOW_COPY_AND_ASSIGN(ObBackupDataCtx); }; @@ -254,7 +219,7 @@ struct ObBackupRecoverRetryCtx { blocksstable::ObLogicMacroBlockId need_skip_logic_id_; common::ObArray reused_pair_list_; }; - +class ObILSTabletIdReader; struct ObLSBackupCtx { public: ObLSBackupCtx(); @@ -341,6 +306,7 @@ public: common::ObMySQLProxy *sql_proxy_; int64_t rebuild_seq_; // rebuild seq of backup ls meta int64_t check_tablet_info_cost_time_; + share::SCN backup_tx_table_filled_tx_scn_; DISALLOW_COPY_AND_ASSIGN(ObLSBackupCtx); }; diff --git a/src/share/backup/ob_backup_data_store.cpp b/src/storage/backup/ob_backup_data_store.cpp old mode 100644 new mode 100755 similarity index 90% rename from src/share/backup/ob_backup_data_store.cpp rename to src/storage/backup/ob_backup_data_store.cpp index fdd931480..1b118ffc1 --- a/src/share/backup/ob_backup_data_store.cpp +++ b/src/storage/backup/ob_backup_data_store.cpp @@ -11,8 +11,7 @@ */ #define USING_LOG_PREFIX SHARE -#include "share/backup/ob_backup_data_store.h" -#include "share/backup/ob_backup_lease_info_mgr.h" +#include "storage/backup/ob_backup_data_store.h" #include "share/backup/ob_backup_io_adapter.h" #include "lib/restore/ob_storage.h" #include "lib/oblog/ob_log_module.h" @@ -40,9 +39,9 @@ int ObBackupDataTabletToLSInfo::assign(const ObBackupDataTabletToLSInfo &that) int ret = OB_SUCCESS; if (!that.is_valid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret)); + LOG_WARN("invalid argument", K(ret), K(that)); } else if (OB_FAIL(tablet_id_list_.assign(that.tablet_id_list_))) { - LOG_WARN("fail to assign tabelt id", K(ret), K(that)); + LOG_WARN("fail to assign tablet id", K(ret), K(that)); } else { ls_id_ = that.ls_id_; } @@ -61,7 +60,7 @@ OB_SERIALIZE_MEMBER(ObBackupDataTabletToLSDesc, backup_scn_, tablet_to_ls_); bool ObBackupDataTabletToLSDesc::is_valid() const { - return backup_scn_.is_valid() && !tablet_to_ls_.empty(); + return true; } /* @@ -77,7 +76,8 @@ bool ObBackupDeletedTabletToLSDesc::is_valid() const /* *------------------------------ObExternTenantLocalityInfo---------------------------- */ -OB_SERIALIZE_MEMBER(ObExternTenantLocalityInfoDesc, tenant_id_, backup_set_id_, cluster_id_, compat_mode_, tenant_name_, cluster_name_, locality_, primary_zone_); +OB_SERIALIZE_MEMBER(ObExternTenantLocalityInfoDesc, tenant_id_, backup_set_id_, cluster_id_, compat_mode_, + tenant_name_, cluster_name_, locality_, primary_zone_, sys_time_zone_); bool ObExternTenantLocalityInfoDesc::is_valid() const { @@ -88,7 +88,8 @@ bool ObExternTenantLocalityInfoDesc::is_valid() const && !tenant_name_.is_empty() && !cluster_name_.is_empty() && !locality_.is_empty() - && !primary_zone_.is_empty(); + && !primary_zone_.is_empty() + && !sys_time_zone_.is_empty(); } /* @@ -297,7 +298,7 @@ int ObBackupDataStore::read_ls_attr_info(ObBackupDataLSAttrDesc &ls_info) int ret = OB_SUCCESS; share::ObBackupPath path; ObBackupPathString full_path; - share::ObExternBackupSetInfoDesc backup_set_info; + storage::ObExternBackupSetInfoDesc backup_set_info; if (!is_init()) { ret = OB_NOT_INIT; LOG_WARN("ObBackupDataStore not init", K(ret)); @@ -353,7 +354,7 @@ int ObBackupDataStore::write_ls_meta_infos(const ObBackupLSMetaInfosDesc &ls_met int ObBackupDataStore::read_ls_meta_infos(const ObLSID &ls_id, storage::ObLSMetaPackage &ls_meta_package) { int ret = OB_SUCCESS; - ObBackupLSMetaInfosDesc ls_meta_infos; + storage::ObBackupLSMetaInfosDesc ls_meta_infos; bool ls_exist = false; if (!is_init()) { ret = OB_NOT_INIT; @@ -400,8 +401,8 @@ int ObBackupDataStore::read_ls_meta_infos(ObBackupLSMetaInfosDesc &ls_meta_infos return ret; } - -int ObBackupDataStore::write_tablet_to_ls_info(const ObBackupDataTabletToLSDesc &tablet_to_ls_info, const int64_t turn_id) +int ObBackupDataStore::write_tablet_to_ls_info(const ObBackupDataTabletToLSDesc &tablet_to_ls_info, + const int64_t turn_id, const share::ObBackupDataType &type) { int ret = OB_SUCCESS; ObBackupPathString full_path; @@ -410,7 +411,7 @@ int ObBackupDataStore::write_tablet_to_ls_info(const ObBackupDataTabletToLSDesc if (!is_init()) { ret = OB_NOT_INIT; LOG_WARN("backup data extern mgr not init", K(ret)); - } else if (OB_FAIL(ObBackupPathUtil::get_backup_data_tablet_ls_info_path(backup_set_dest_, turn_id, path))) { + } else if (OB_FAIL(ObBackupPathUtil::get_backup_data_tablet_ls_info_path(backup_set_dest_, type, turn_id, path))) { LOG_WARN("fail to get path", K(ret)); } else if (OB_FAIL(full_path.assign(path.get_obstr()))) { LOG_WARN("fail to assign full path", K(ret)); @@ -421,49 +422,53 @@ int ObBackupDataStore::write_tablet_to_ls_info(const ObBackupDataTabletToLSDesc return ret; } -int ObBackupDataStore::write_tablet_to_ls_info(const ObBackupDataTabletToLSDesc &tablet_to_ls_info, const ObLSID &ls_id, - const int64_t turn_id, const int64_t retry_id) +int ObBackupDataStore::read_tablet_to_ls_info(const int64_t turn_id, const share::ObBackupDataType &type, + ObBackupDataTabletToLSDesc &tablet_to_ls_info) { int ret = OB_SUCCESS; - - ObBackupPathString full_path; share::ObBackupPath path; - + ObBackupPathString full_path; + share::ObBackupDataType tmp_type; + type.is_major_backup() ? tmp_type.set_major_data_backup() : tmp_type.set_minor_data_backup(); if (!is_init()) { ret = OB_NOT_INIT; - LOG_WARN("backup data extern mgr not init", K(ret)); - } else if (OB_FAIL(ObBackupPathUtil::get_ls_data_tablet_info_path(backup_set_dest_, ls_id, turn_id, retry_id, path))) { - LOG_WARN("fail to get path", K(ret)); + LOG_WARN("ObBackupDataStore not init", K(ret)); + } else if (type.is_sys_backup() && turn_id != 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid argument", K(ret), K(turn_id), K(type)); + } else if (OB_FAIL(ObBackupPathUtil::get_backup_data_tablet_ls_info_path(backup_set_dest_, tmp_type, turn_id, path))) { + LOG_WARN("fail to get tenant ls attr info path", K(ret)); } else if (OB_FAIL(full_path.assign(path.get_obstr()))) { LOG_WARN("fail to assign full path", K(ret)); - } else if (OB_FAIL(write_single_file(full_path, tablet_to_ls_info))) { - LOG_WARN("fail to write single file", K(ret)); - } - + } else if (OB_FAIL(read_single_file(full_path, tablet_to_ls_info))) { + LOG_WARN("failed to read single file", K(ret), K(full_path)); + } return ret; } -int ObBackupDataStore::read_tablet_to_ls_info( - const int64_t turn_id, - const ObLSID &ls_id, - ObIArray &tablet_ids) +int ObBackupDataStore::read_tablet_list(const share::ObBackupDataType &type, const int64_t turn_id, const ObLSID &ls_id, + ObIArray &tablet_ids) { int ret = OB_SUCCESS; - tablet_ids.reset(); - HEAP_VAR(ObBackupDataTabletToLSDesc, tablet_to_ls_info) { - if (OB_FAIL(read_tablet_to_ls_info(turn_id, tablet_to_ls_info))) { - LOG_WARN("failed to read tablet to ls info", K(ret)); - } else if (!tablet_to_ls_info.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid tablet to ls info", K(ret), K(tablet_to_ls_info)); - } else { - for (int i = 0; OB_SUCC(ret) && i < tablet_to_ls_info.tablet_to_ls_.count(); ++i) { - const ObBackupDataTabletToLSInfo &info = tablet_to_ls_info.tablet_to_ls_.at(i); - if (!info.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid tablet to ls info", K(ret), K(info)); - } else if (info.ls_id_ == ls_id && OB_FAIL(append(tablet_ids, info.tablet_id_list_))) { + share::ObBackupPath path; + ObBackupPathString full_path; + ObBackupDataTabletToLSDesc tablet_to_ls_info; + if (!is_init()) { + ret = OB_NOT_INIT; + LOG_WARN("ObBackupDataStore not init", K(ret)); + } else if (OB_FAIL(read_tablet_to_ls_info(turn_id, type, tablet_to_ls_info))) { + LOG_WARN("failed to read tablet to ls info", K(ret), K(turn_id), K(type)); + } else { + for (int i = 0; OB_SUCC(ret) && i < tablet_to_ls_info.tablet_to_ls_.count(); ++i) { + const ObBackupDataTabletToLSInfo &info = tablet_to_ls_info.tablet_to_ls_.at(i); + if (!info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tablet to ls info", K(ret), K(info)); + } else if (info.ls_id_ == ls_id) { + if (OB_FAIL(append(tablet_ids, info.tablet_id_list_))) { LOG_WARN("failed to append tablet ids", K(ret), K(info)); + } else { + break; } } } @@ -471,61 +476,24 @@ int ObBackupDataStore::read_tablet_to_ls_info( return ret; } -int ObBackupDataStore::read_tablet_to_ls_info(const int64_t turn_id, ObBackupDataTabletToLSDesc &tablet_to_ls_info) +int ObBackupDataStore::write_tenant_backup_set_infos(const ObTenantBackupSetInfosDesc &tenant_backup_set_infos) { int ret = OB_SUCCESS; - share::ObBackupPath path; - ObBackupPathString full_path; - if (!is_init()) { - ret = OB_NOT_INIT; - LOG_WARN("ObBackupDataStore not init", K(ret)); - } else if (OB_FAIL(ObBackupPathUtil::get_backup_data_tablet_ls_info_path(backup_set_dest_, turn_id, path))) { - LOG_WARN("fail to get tenant ls attr info path", K(ret)); - } else if (OB_FAIL(full_path.assign(path.get_obstr()))) { - LOG_WARN("fail to assign full path", K(ret)); - } else if (OB_FAIL(read_single_file(full_path, tablet_to_ls_info))) { - LOG_WARN("failed to read single file", K(ret), K(full_path)); - } - return ret; -} -int ObBackupDataStore::read_tablet_to_ls_info(const ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, - ObBackupDataTabletToLSDesc &tablet_to_ls_info) -{ - int ret = OB_SUCCESS; - - share::ObBackupPath path; - ObBackupPathString full_path; - int64_t retry_cnt = 0; - if (!is_init()) { - ret = OB_NOT_INIT; - LOG_WARN("ObBackupDataStore not init", K(ret)); - } else if (OB_FAIL(ObBackupPathUtil::get_ls_data_tablet_info_path(backup_set_dest_, ls_id, turn_id, retry_id, path))) { - LOG_WARN("fail to get tenant ls attr info path", K(ret)); - } else if (OB_FAIL(full_path.assign(path.get_obstr()))) { - LOG_WARN("fail to assign full path", K(ret)); - } else if (OB_FAIL(read_single_file(full_path, tablet_to_ls_info))) { - LOG_WARN("failed to read single file", K(ret), K(full_path)); - } - - return ret; -} - -int ObBackupDataStore::write_deleted_tablet_info(const ObBackupDeletedTabletToLSDesc &deleted_tablet_info) -{ - int ret = OB_SUCCESS; ObBackupPathString full_path; share::ObBackupPath path; + if (!is_init()) { ret = OB_NOT_INIT; LOG_WARN("backup data extern mgr not init", K(ret)); - } else if (OB_FAIL(ObBackupPathUtil::get_deleted_tablet_info_path(backup_set_dest_, path))) { + } else if (OB_FAIL(ObBackupPathUtil::get_tenant_backup_set_infos_path(backup_set_dest_, path))) { LOG_WARN("fail to get path", K(ret)); } else if (OB_FAIL(full_path.assign(path.get_obstr()))) { LOG_WARN("fail to assign full path", K(ret)); - } else if (OB_FAIL(write_single_file(full_path, deleted_tablet_info))) { + } else if (OB_FAIL(write_single_file(full_path, tenant_backup_set_infos))) { LOG_WARN("fail to write single file", K(ret)); } + return ret; } @@ -564,27 +532,6 @@ int ObBackupDataStore::read_deleted_tablet_info(const ObLSID &ls_id, ObIArray= 0; i--) { const share::ObBackupSetDesc &backup_set_desc = backup_set_desc_array.at(i); @@ -875,7 +822,7 @@ int ObBackupDataStore::do_get_backup_set_array_(const common::ObString &passwd_a const int64_t OB_BACKUP_MAX_BACKUP_SET_ID = 5000; ObBackupSetFilter::BackupSetMap backup_set_map; ObSArray backup_set_desc_array; - share::ObExternBackupSetInfoDesc backup_set_info; + storage::ObExternBackupSetInfoDesc backup_set_info; if (OB_FAIL(backup_set_map.create(OB_BACKUP_MAX_BACKUP_SET_ID, "backupSetMap"))) { LOG_WARN("fail to create backup set map", K(ret)); } else if (OB_FAIL(op.get_backup_set_array(backup_set_desc_array))) { @@ -884,8 +831,6 @@ int ObBackupDataStore::do_get_backup_set_array_(const common::ObString &passwd_a ObBackupSetDescComparator cmp; std::sort(backup_set_desc_array.begin(), backup_set_desc_array.end(), cmp); } - - // TODO: fix this when support inc backup set and full backup set can have different backup dest in 4.1 for (int64_t i = 0; OB_SUCC(ret) && i < backup_set_desc_array.count(); ++i) { const share::ObBackupSetDesc &backup_set_desc = backup_set_desc_array.at(i); @@ -998,17 +943,19 @@ int ObBackupDataStore::parse_backup_set_name( } int ObBackupDataStore::get_max_sys_ls_retry_id(const share::ObBackupPath &backup_path, - const ObLSID &ls_id, int64_t &retry_id) + const ObLSID &ls_id, const int64_t turn_id, int64_t &retry_id) { int ret = OB_SUCCESS; retry_id = -1; ObBackupIoAdapter util; ObArray d_entrys; - const char sys_data_prefix[OB_BACKUP_DIR_PREFIX_LENGTH] = "sys_data_turn_1_retry_"; + char sys_data_prefix[OB_BACKUP_DIR_PREFIX_LENGTH] = { 0 }; ObDirPrefixEntryNameFilter prefix_op(d_entrys); if (backup_path.is_empty() || !ls_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(backup_path), K(ls_id)); + } else if (OB_FAIL(databuff_printf(sys_data_prefix, OB_BACKUP_DIR_PREFIX_LENGTH, "sys_data_turn_%ld_retry_", turn_id))) { + LOG_WARN("failed to printf sys data prefix", K(ret)); } else if (OB_FAIL(prefix_op.init(sys_data_prefix, static_cast(strlen(sys_data_prefix))))) { LOG_WARN("failed to init dir prefix", K(ret), K(sys_data_prefix)); } else if (OB_FAIL(util.list_directories(backup_path.get_obstr(), backup_set_dest_.get_storage_info(), prefix_op))) { @@ -1079,3 +1026,28 @@ int ObBackupDataStore::extract_id_from_str(const common::ObString &file_name, co return ret; } + +int ObBackupDataStore::read_base_tablet_list(const share::ObLSID &ls_id, ObIArray &tablet_id_array) +{ + int ret = OB_SUCCESS; + backup::ObExternTabletMetaReader reader; + if (OB_FAIL(reader.init(backup_set_dest_, ls_id))) { + LOG_WARN("fail to init reader", K(ret), K(backup_set_dest_), K(ls_id)); + } else { + storage::ObMigrationTabletParam tablet_meta; + while (OB_SUCC(ret)) { + tablet_meta.reset(); + if (OB_FAIL(reader.get_next(tablet_meta))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get next tablet meta", K(ret)); + } + } else if (OB_FAIL(tablet_id_array.push_back(tablet_meta.tablet_id_))) { + LOG_WARN("failed to push backup tablet id", K(ret), K(tablet_meta)); + } + } + } + return ret; +} diff --git a/src/share/backup/ob_backup_data_store.h b/src/storage/backup/ob_backup_data_store.h old mode 100644 new mode 100755 similarity index 77% rename from src/share/backup/ob_backup_data_store.h rename to src/storage/backup/ob_backup_data_store.h index 1840693ea..486cf4b07 --- a/src/share/backup/ob_backup_data_store.h +++ b/src/storage/backup/ob_backup_data_store.h @@ -15,31 +15,15 @@ #include "share/ls/ob_ls_operator.h" #include "share/backup/ob_backup_path.h" -#include "share/backup/ob_backup_store.h" +#include "storage/backup/ob_backup_extern_info_mgr.h" #include "storage/ls/ob_ls_meta_package.h" +#include "storage/tablet/ob_tablet_meta.h" namespace oceanbase { -namespace share +namespace storage { -class ObExternBackupDataDesc : public ObIBackupSerializeProvider -{ -public: - explicit ObExternBackupDataDesc(uint16_t type, uint16_t version) - : type_(type), version_(version) {} - virtual ~ObExternBackupDataDesc() {} - - uint16_t get_data_type() const override { return type_; } - uint16_t get_data_version() const override { return version_; } - uint16_t get_compressor_type() const override { return ObCompressorType::NONE_COMPRESSOR; } - - VIRTUAL_TO_STRING_KV(K_(type), K_(version)); -private: - uint16_t type_; - uint16_t version_; -}; - /* ------------------------backup ls info------------------------- */ @@ -51,7 +35,7 @@ public: OB_UNIS_VERSION(1); public: ObBackupDataLSAttrDesc() - : ObExternBackupDataDesc(ObBackupFileType::BACKUP_LS_INFO, FILE_VERSION), + : ObExternBackupDataDesc(share::ObBackupFileType::BACKUP_LS_INFO, FILE_VERSION), backup_scn_(), ls_attr_array_() {} virtual ~ObBackupDataLSAttrDesc() {} @@ -59,8 +43,8 @@ public: bool is_valid() const override; INHERIT_TO_STRING_KV("ObExternBackupDataDesc", ObExternBackupDataDesc, K(backup_scn_), K_(ls_attr_array)); public: - SCN backup_scn_; - ObSArray ls_attr_array_; + share::SCN backup_scn_; + ObSArray ls_attr_array_; private: DISALLOW_COPY_AND_ASSIGN(ObBackupDataLSAttrDesc); }; @@ -78,8 +62,8 @@ public: bool is_valid() const; int assign(const ObBackupDataTabletToLSInfo &that); TO_STRING_KV(K_(ls_id), K_(tablet_id_list)); - ObLSID ls_id_; - ObSArray tablet_id_list_; + share::ObLSID ls_id_; + ObSArray tablet_id_list_; }; struct ObBackupDataTabletToLSDesc final : public ObExternBackupDataDesc @@ -89,15 +73,15 @@ public: OB_UNIS_VERSION(1); public: ObBackupDataTabletToLSDesc() - : ObExternBackupDataDesc(ObBackupFileType::BACKUP_TABLET_TO_LS_INFO, FILE_VERSION), - backup_scn_(), + : ObExternBackupDataDesc(share::ObBackupFileType::BACKUP_TABLET_TO_LS_INFO, FILE_VERSION), + backup_scn_(share::SCN::min_scn()), tablet_to_ls_() {} virtual ~ObBackupDataTabletToLSDesc() {} bool is_valid() const override; INHERIT_TO_STRING_KV("ObExternBackupDataDesc", ObExternBackupDataDesc, K_(backup_scn), K_(tablet_to_ls)); public: - SCN backup_scn_; + share::SCN backup_scn_; ObSArray tablet_to_ls_; private: DISALLOW_COPY_AND_ASSIGN(ObBackupDataTabletToLSDesc); @@ -129,7 +113,7 @@ public: OB_UNIS_VERSION(1); public: ObExternBackupSetPlaceholderDesc() - : ObExternBackupDataDesc(ObBackupFileType::BACKUP_TABLET_TO_LS_INFO, FILE_VERSION) {} + : ObExternBackupDataDesc(share::ObBackupFileType::BACKUP_TABLET_TO_LS_INFO, FILE_VERSION) {} virtual ~ObExternBackupSetPlaceholderDesc() {} bool is_valid() const override { return true; } @@ -142,11 +126,12 @@ public: using ClusterName = common::ObFixedLengthString; using Locality = common::ObFixedLengthString; using PrimaryZone = common::ObFixedLengthString; + using TimeZone = common::ObFixedLengthString; static const uint8_t FILE_VERSION = 1; OB_UNIS_VERSION(1); public: ObExternTenantLocalityInfoDesc() - : ObExternBackupDataDesc(ObBackupFileType::BACKUP_TENANT_LOCALITY_INFO, FILE_VERSION), + : ObExternBackupDataDesc(share::ObBackupFileType::BACKUP_TENANT_LOCALITY_INFO, FILE_VERSION), tenant_id_(OB_INVALID_TENANT_ID), backup_set_id_(0), cluster_id_(OB_INVALID_CLUSTER_ID), @@ -154,12 +139,13 @@ public: tenant_name_(), cluster_name_(), locality_(), - primary_zone_() {} + primary_zone_(), + sys_time_zone_() {} virtual ~ObExternTenantLocalityInfoDesc() {} bool is_valid() const override; INHERIT_TO_STRING_KV("ObExternBackupDataDesc", ObExternBackupDataDesc, K_(tenant_id), K_(backup_set_id), K_(cluster_id), - K_(compat_mode), K_(tenant_name), K_(cluster_name), K_(locality), K_(primary_zone)); + K_(compat_mode), K_(tenant_name), K_(cluster_name), K_(locality), K_(primary_zone), K_(sys_time_zone)); public: uint64_t tenant_id_; int64_t backup_set_id_; @@ -169,6 +155,7 @@ public: ClusterName cluster_name_; Locality locality_; PrimaryZone primary_zone_; + TimeZone sys_time_zone_; }; struct ObExternBackupSetInfoDesc final : public ObExternBackupDataDesc @@ -178,14 +165,14 @@ public: OB_UNIS_VERSION(1); public: ObExternBackupSetInfoDesc() - : ObExternBackupDataDesc(ObBackupFileType::BACKUP_SET_INFO, FILE_VERSION), + : ObExternBackupDataDesc(share::ObBackupFileType::BACKUP_SET_INFO, FILE_VERSION), backup_set_file_() {} virtual ~ObExternBackupSetInfoDesc() {} bool is_valid() const override; INHERIT_TO_STRING_KV("ObExternBackupDataDesc", ObExternBackupDataDesc, K_(backup_set_file)); public: - ObBackupSetFileDesc backup_set_file_; + share::ObBackupSetFileDesc backup_set_file_; }; struct ObExternTenantDiagnoseInfoDesc final : public ObExternBackupDataDesc @@ -195,7 +182,7 @@ public: OB_UNIS_VERSION(1); public: ObExternTenantDiagnoseInfoDesc() - : ObExternBackupDataDesc(ObBackupFileType::BACKUP_TENANT_DIAGNOSE_INFO, FILE_VERSION), + : ObExternBackupDataDesc(share::ObBackupFileType::BACKUP_TENANT_DIAGNOSE_INFO, FILE_VERSION), tenant_id_(OB_INVALID_TENANT_ID), tenant_locality_info_(), backup_set_file_() {} @@ -206,7 +193,7 @@ public: public: uint64_t tenant_id_; ObExternTenantLocalityInfoDesc tenant_locality_info_; - ObBackupSetFileDesc backup_set_file_; + share::ObBackupSetFileDesc backup_set_file_; }; struct ObTenantBackupSetInfosDesc final : public ObExternBackupDataDesc @@ -216,14 +203,14 @@ public: OB_UNIS_VERSION(1); public: ObTenantBackupSetInfosDesc() - : ObExternBackupDataDesc(ObBackupFileType::BACKUP_TENANT_SET_INFOS, FILE_VERSION), + : ObExternBackupDataDesc(share::ObBackupFileType::BACKUP_TENANT_SET_INFOS, FILE_VERSION), backup_set_infos_() {} virtual ~ObTenantBackupSetInfosDesc() {} bool is_valid() const override; TO_STRING_KV(K_(backup_set_infos)); public: - ObSArray backup_set_infos_; + ObSArray backup_set_infos_; private: DISALLOW_COPY_AND_ASSIGN(ObTenantBackupSetInfosDesc); }; @@ -235,7 +222,7 @@ public: OB_UNIS_VERSION(1); public: ObBackupLSMetaInfosDesc() - : ObExternBackupDataDesc(ObBackupFileType::BACKUP_LS_META_INFOS_FILE, FILE_VERSION), + : ObExternBackupDataDesc(share::ObBackupFileType::BACKUP_LS_META_INFOS_FILE, FILE_VERSION), ls_meta_packages_() {} virtual ~ObBackupLSMetaInfosDesc() {} bool is_valid() const override; @@ -256,7 +243,6 @@ public: ObBackupSetFilter() : backup_set_name_array_() {} ~ObBackupSetFilter() {} - void reset() { backup_set_name_array_.reuse(); } int get_backup_set_array(ObIArray &backup_set_array) const; int func(const dirent *entry) override; @@ -265,7 +251,7 @@ private: ObSArray backup_set_name_array_; }; -class ObBackupDataStore final : public ObBackupStore +class ObBackupDataStore final : public share::ObBackupStore { public: ObBackupDataStore(); @@ -275,25 +261,24 @@ public: int init(const share::ObBackupDest &backup_set_dest); int init(const share::ObBackupDest &backup_dest, const share::ObBackupSetDesc &backup_desc); const share::ObBackupSetDesc &get_backup_set_desc() const { return backup_desc_; } + const share::ObBackupDest &get_backup_set_dest() const { return backup_set_dest_; } int write_ls_attr(const int64_t turn_id, const ObBackupDataLSAttrDesc &ls_info); int read_ls_attr_info(ObBackupDataLSAttrDesc &ls_info); int read_ls_attr_info(const int64_t turn_id, ObBackupDataLSAttrDesc &ls_info); int write_ls_meta_infos(const ObBackupLSMetaInfosDesc &ls_meta_infos); - int read_ls_meta_infos(const ObLSID &ls_id, storage::ObLSMetaPackage &ls_meta_package); + // get the ObBackupLSMetaInfosDesc of target turn_id int read_ls_meta_infos(ObBackupLSMetaInfosDesc &ls_meta_infos); - + // get the ls_meta_infos of target turn_id and ls_id + int read_ls_meta_infos(const share::ObLSID &ls_id, storage::ObLSMetaPackage &ls_meta_package); // write and read tablet_to_ls_info - int write_tablet_to_ls_info(const ObBackupDataTabletToLSDesc &tablet_to_ls_info, const int64_t turn_id); - int write_tablet_to_ls_info(const ObBackupDataTabletToLSDesc &tablet_to_ls_info, const ObLSID &ls_id, - const int64_t turn_id, const int64_t retry_id); - int read_tablet_to_ls_info(const int64_t turn_id, const ObLSID &ls_id, ObIArray &tablet_ids); - int read_tablet_to_ls_info(const int64_t turn_id, ObBackupDataTabletToLSDesc &tablet_to_ls_info); - int read_tablet_to_ls_info(const ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, + int write_tablet_to_ls_info(const ObBackupDataTabletToLSDesc &tablet_to_ls_info, + const int64_t turn_id, const share::ObBackupDataType &type); + int read_tablet_to_ls_info(const int64_t turn_id, const share::ObBackupDataType &type, ObBackupDataTabletToLSDesc &tablet_to_ls_info); - // write and read deleted_tablet_info - int write_deleted_tablet_info(const ObBackupDeletedTabletToLSDesc &deleted_tablet_info); + int read_tablet_list(const share::ObBackupDataType &type, const int64_t turn_id, const share::ObLSID &ls_id, + ObIArray &tablet_ids); int read_deleted_tablet_info(const ObLSID &ls_id, ObIArray &deleted_tablet_ids); // write tenant backup set infos @@ -301,7 +286,7 @@ public: // write backup set place holder int write_backup_set_placeholder(const bool is_inner, const bool is_start, const bool is_succeed, - const SCN &replay_scn, const SCN &min_restore_scn); + const share::SCN &replay_scn, const share::SCN &min_restore_scn); // write and read tenant locality info int write_tenant_locality_info(const ObExternTenantLocalityInfoDesc &locality_info); @@ -315,13 +300,15 @@ public: int write_backup_set_info(const ObExternBackupSetInfoDesc &backup_set_info); int read_backup_set_info(ObExternBackupSetInfoDesc &backup_set_info); - int get_backup_set_array(const common::ObString &passwd_array, const SCN &restore_scn, - SCN &restore_start_scn, common::ObIArray &backup_set_list); + int get_backup_set_array(const common::ObString &passwd_array, const share::SCN &restore_scn, + share::SCN &restore_start_scn, common::ObIArray &backup_set_list); int get_max_backup_set_file_info(const common::ObString &passwd_array, ObBackupSetFileDesc &output_desc); - int get_max_sys_ls_retry_id(const share::ObBackupPath &backup_path, const ObLSID &ls_id, int64_t &retry_id); + int get_max_sys_ls_retry_id( + const share::ObBackupPath &backup_path, const share::ObLSID &ls_id, const int64_t turn_id, int64_t &retry_id); int write_root_key_info(const uint64_t tenant_id); int read_root_key_info(const uint64_t tenant_id); + int read_base_tablet_list(const share::ObLSID &ls_id, ObIArray &tablet_id_array); TO_STRING_KV(K_(backup_desc)); public: @@ -337,11 +324,11 @@ public: } }; private: - int do_get_backup_set_array_(const common::ObString &passwd_array, const SCN &restore_scn, + int do_get_backup_set_array_(const common::ObString &passwd_array, const share::SCN &restore_scn, const ObBackupSetFilter &op, common::ObIArray &tmp_backup_set_list, - int64_t &cur_max_backup_set_id, SCN &restore_start_scn); + int64_t &cur_max_backup_set_id, share::SCN &restore_start_scn); int get_backup_set_placeholder_path_(const bool is_inner, const bool is_start, const bool is_succeed, - const SCN &replay_scn, const SCN &min_restore_scn, share::ObBackupPath &path); + const share::SCN &replay_scn, const share::SCN &min_restore_scn, share::ObBackupPath &path); private: share::ObBackupSetDesc backup_desc_; share::ObBackupDest backup_set_dest_; diff --git a/src/storage/backup/ob_backup_data_struct.cpp b/src/storage/backup/ob_backup_data_struct.cpp old mode 100644 new mode 100755 index 5712c6b8c..8591cb9f2 --- a/src/storage/backup/ob_backup_data_struct.cpp +++ b/src/storage/backup/ob_backup_data_struct.cpp @@ -18,6 +18,7 @@ #include "lib/oblog/ob_log_module.h" #include "storage/backup/ob_backup_task.h" #include "storage/blocksstable/ob_logic_macro_id.h" +#include "share/location_cache/ob_location_service.h" #include "share/backup/ob_backup_struct.h" using namespace oceanbase::common; @@ -45,7 +46,7 @@ bool ObBackupJobDesc::operator==(const ObBackupJobDesc &other) const /* ObLSBackupParam */ ObLSBackupParam::ObLSBackupParam() - : task_id_(), backup_dest_(), tenant_id_(), dest_id_(0), backup_set_desc_(), ls_id_(), turn_id_(), retry_id_() + : job_id_(0), task_id_(0), backup_dest_(), tenant_id_(0), dest_id_(0), backup_set_desc_(), ls_id_(), turn_id_(0), retry_id_(0) {} ObLSBackupParam::~ObLSBackupParam() @@ -53,8 +54,8 @@ ObLSBackupParam::~ObLSBackupParam() bool ObLSBackupParam::is_valid() const { - return task_id_ > 0 && backup_dest_.is_valid() && OB_INVALID_ID != tenant_id_ && dest_id_ > 0 && backup_set_desc_.is_valid() && - ls_id_.is_valid() && turn_id_ >= 0 && retry_id_ >= 0; + return job_id_ > 0 && task_id_ > 0 && backup_dest_.is_valid() && OB_INVALID_ID != tenant_id_ && dest_id_ > 0 + && backup_set_desc_.is_valid() && ls_id_.is_valid() && turn_id_ >= 0 && retry_id_ >= 0; } int ObLSBackupParam::assign(const ObLSBackupParam ¶m) @@ -66,6 +67,7 @@ int ObLSBackupParam::assign(const ObLSBackupParam ¶m) } else if (OB_FAIL(backup_dest_.deep_copy(param.backup_dest_))) { LOG_WARN("failed to deep copy backup dest", K(ret)); } else { + job_id_ = param.job_id_; task_id_ = param.task_id_; tenant_id_ = param.tenant_id_; dest_id_ = param.dest_id_; @@ -1205,7 +1207,7 @@ void ObBackupLSTaskInfo::reset() /* ObBackupSkippedTablet */ ObBackupSkippedTablet::ObBackupSkippedTablet() - : task_id_(), tenant_id_(), turn_id_(), retry_id_(), tablet_id_(), ls_id_(), backup_set_id_(), skipped_type_() + : task_id_(), tenant_id_(), turn_id_(), retry_id_(), tablet_id_(), ls_id_(), backup_set_id_(), skipped_type_(), data_type_() {} ObBackupSkippedTablet::~ObBackupSkippedTablet() @@ -1213,13 +1215,14 @@ ObBackupSkippedTablet::~ObBackupSkippedTablet() bool ObBackupSkippedTablet::is_valid() const { - return task_id_ > 0 && OB_INVALID_ID != tenant_id_ && turn_id_ > 0 && retry_id_ >= 0 && tablet_id_.is_valid() && - ls_id_.is_valid() && backup_set_id_ > 0 && skipped_type_.is_valid(); + return task_id_ > 0 && OB_INVALID_ID != tenant_id_ && turn_id_ > 0 && retry_id_ >= 0 && tablet_id_.is_valid() + && ls_id_.is_valid() && backup_set_id_ > 0 && skipped_type_.is_valid() + && data_type_.is_valid(); } /* ObBackupReportCtx */ -ObBackupReportCtx::ObBackupReportCtx() : rs_mgr_(NULL), sql_proxy_(NULL), rs_rpc_proxy_(NULL) +ObBackupReportCtx::ObBackupReportCtx() : location_service_(NULL), sql_proxy_(NULL), rpc_proxy_(NULL) {} ObBackupReportCtx::~ObBackupReportCtx() @@ -1227,7 +1230,7 @@ ObBackupReportCtx::~ObBackupReportCtx() bool ObBackupReportCtx::is_valid() const { - return OB_NOT_NULL(rs_mgr_) && OB_NOT_NULL(sql_proxy_) && OB_NOT_NULL(rs_rpc_proxy_); + return OB_NOT_NULL(location_service_) && OB_NOT_NULL(sql_proxy_) && OB_NOT_NULL(rpc_proxy_); } } // namespace backup diff --git a/src/storage/backup/ob_backup_data_struct.h b/src/storage/backup/ob_backup_data_struct.h old mode 100644 new mode 100755 index e63d7dc11..8771d25ee --- a/src/storage/backup/ob_backup_data_struct.h +++ b/src/storage/backup/ob_backup_data_struct.h @@ -26,6 +26,10 @@ #include "storage/blocksstable/ob_logic_macro_id.h" namespace oceanbase { + +namespace share { +class ObLocationService; +} namespace backup { static const int64_t OB_DEFAULT_BACKUP_CONCURRENCY = 2; @@ -93,7 +97,9 @@ struct ObLSBackupParam { int convert_to(const ObBackupIndexLevel &index_level, const share::ObBackupDataType &backup_data_type, ObBackupIndexMergeParam &merge_param); int assign(const ObBackupIndexMergeParam ¶m); - TO_STRING_KV(K_(task_id), K_(backup_dest), K_(tenant_id), K_(dest_id), K_(backup_set_desc), K_(ls_id), K_(turn_id), K_(retry_id)); + TO_STRING_KV(K_(job_id), K_(task_id), K_(backup_dest), K_(tenant_id), K_(dest_id), K_(backup_set_desc), K_(ls_id), + K_(turn_id), K_(retry_id)); + int64_t job_id_; int64_t task_id_; share::ObBackupDest backup_dest_; uint64_t tenant_id_; @@ -666,7 +672,7 @@ struct ObBackupSkippedTablet { ~ObBackupSkippedTablet(); bool is_valid() const; TO_STRING_KV(K_(task_id), K_(tenant_id), K_(turn_id), K_(retry_id), K_(tablet_id), - K_(ls_id), K_(backup_set_id), K_(skipped_type)); + K_(ls_id), K_(backup_set_id), K_(skipped_type), K_(data_type)); int64_t task_id_; uint64_t tenant_id_; int64_t turn_id_; @@ -675,16 +681,18 @@ struct ObBackupSkippedTablet { share::ObLSID ls_id_; int64_t backup_set_id_; share::ObBackupSkippedType skipped_type_; + share::ObBackupDataType data_type_; }; struct ObBackupReportCtx final { ObBackupReportCtx(); ~ObBackupReportCtx(); bool is_valid() const; - TO_STRING_KV(KP_(rs_mgr), KP_(sql_proxy), KP_(rs_rpc_proxy)); - share::ObRsMgr *rs_mgr_; + TO_STRING_KV(KP_(location_service), KP_(sql_proxy), KP_(rpc_proxy)); + + share::ObLocationService *location_service_; common::ObMySQLProxy *sql_proxy_; - obrpc::ObCommonRpcProxy *rs_rpc_proxy_; + obrpc::ObSrvRpcProxy *rpc_proxy_; }; } // namespace backup diff --git a/src/storage/backup/ob_backup_extern_info_mgr.cpp b/src/storage/backup/ob_backup_extern_info_mgr.cpp index c3787746a..7cb3f470b 100644 --- a/src/storage/backup/ob_backup_extern_info_mgr.cpp +++ b/src/storage/backup/ob_backup_extern_info_mgr.cpp @@ -16,7 +16,8 @@ #include "common/ob_smart_var.h" #include "share/backup/ob_backup_io_adapter.h" #include "share/backup/ob_backup_path.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_restore_util.h" using namespace oceanbase::common; using namespace oceanbase::share; @@ -224,5 +225,629 @@ int ObExternLSMetaMgr::get_ls_meta_backup_path_(ObBackupPath &path) return ret; } +void ObTabletInfoTrailer::reset() +{ + file_id_ = 0; + tablet_cnt_ = 0; + offset_ = 0; + length_ = 0; +} + +int ObTabletInfoTrailer::assign(const ObTabletInfoTrailer &that) +{ + int ret = OB_SUCCESS; + if (!that.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(that)); + } else { + file_id_ = that.file_id_; + tablet_cnt_ = that.tablet_cnt_; + offset_ = that.offset_; + length_ = that.length_; + } + return ret; +} + +bool ObTabletInfoTrailer::is_valid() const +{ + return file_id_ >= 0 && tablet_cnt_ >= 0 && offset_ >= 0 && length_ >= 0; +} + +int ObTabletInfoTrailer::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + // custom serialization, the format is as following: + // | VER | LEN | Member1 | Member2 | ... | + int ret = OB_SUCCESS; + int64_t len = get_serialize_size(); + if (buf_len - pos < len) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("buf length not enough", K(ret), K(buf_len), K(pos), K(len)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, UNIS_VERSION))) { + LOG_WARN("failed to encode version", K(ret)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, len))) { + LOG_WARN("failed to encode len", K(ret)); + } else if (OB_FAIL(serialize_(buf, buf_len, pos))) { + LOG_WARN("failed to serialize_", K(ret)); + } + + return ret; +} + +int ObTabletInfoTrailer::deserialize(const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + int64_t ver = 0; + int64_t len = 0; + int64_t tmp_pos = pos; + if (OB_FAIL(serialization::decode_i64(buf, data_len, tmp_pos, &ver))) { + LOG_WARN("failed to decode version", K(ret)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, tmp_pos, &len))) { + LOG_WARN("failed to decode len", K(ret)); + } else if (ver != UNIS_VERSION) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("object version mismatch", K(ret), K(ver)); + } else if (data_len < len + pos) { + ret = OB_DESERIALIZE_ERROR; + LOG_WARN("buf length not enough", K(ret), K(len), K(pos), K(data_len)); + } else if (OB_FALSE_IT(pos = tmp_pos)) { + } else if (OB_FAIL(deserialize_(buf, data_len, pos))) { + LOG_WARN("failed to deserialize_", K(ret)); + } + + return ret; +} + +int64_t ObTabletInfoTrailer::get_serialize_size() const +{ + return sizeof(int64_t)/* VER */ + sizeof(int64_t)/* LEN */ + get_serialize_size_(); +} + +int ObTabletInfoTrailer::serialize_(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, file_id_))) { + LOG_WARN("failed to encode file_id", K(ret)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, tablet_cnt_))) { + LOG_WARN("failed to encode table_cnt", K(ret)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, offset_))) { + LOG_WARN("failed to encode offset", K(ret)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, length_))) { + LOG_WARN("failed to encode length", K(ret)); + } + return ret; +} + +int ObTabletInfoTrailer::deserialize_(const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &file_id_))) { + LOG_WARN("failed to decode file_id", K(ret)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &tablet_cnt_))) { + LOG_WARN("failed to decode tablet_cnt", K(ret)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &offset_))) { + LOG_WARN("failed to decode offset", K(ret)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &length_))) { + LOG_WARN("failed to decode length", K(ret)); + } + return ret; +} + +int64_t ObTabletInfoTrailer::get_serialize_size_() const +{ + return sizeof(file_id_) + sizeof(tablet_cnt_) + sizeof(offset_) + sizeof(length_); +} + +int ObExternTabletMetaWriter::init( + const share::ObBackupDest &backup_set_dest, const share::ObLSID &ls_id, + const int64_t turn_id, const int64_t retry_id) +{ + int ret = OB_SUCCESS; + const int64_t start_file_id = 1; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("tablet meta writer init twice", K(ret)); + } else if (!backup_set_dest.is_valid() || !ls_id.is_valid() || turn_id < 1 || retry_id < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(backup_set_dest), K(ls_id), K(turn_id), K(retry_id)); + } else if (OB_FAIL(backup_set_dest_.deep_copy(backup_set_dest))) { + LOG_WARN("failed to deep copy backup set dest", K(ret)); + } else if (OB_FAIL(tmp_buffer_.ensure_space(BUF_SIZE))) { + LOG_WARN("failed to ensure space", K(ret)); + } else { + ls_id_ = ls_id; + turn_id_ = turn_id; + retry_id_ = retry_id; + if (OB_FAIL(prepare_backup_file_(start_file_id))) { + LOG_WARN("failed to prepare backup file", K(ret), K(start_file_id)); + } else { + is_inited_ = true; + } + } + return ret; +} + +int ObExternTabletMetaWriter::prepare_backup_file_(const int64_t file_id) +{ + int ret = OB_SUCCESS; + share::ObBackupPath backup_path; + common::ObBackupIoAdapter util; + const ObStorageAccessType access_type = OB_STORAGE_ACCESS_RANDOMWRITER; + const int64_t data_file_size = get_data_file_size(); + if (OB_FAIL(ObBackupPathUtil::get_ls_data_tablet_info_path( + backup_set_dest_, ls_id_, turn_id_, retry_id_, file_id, backup_path))) { + LOG_WARN("failed to get ls data tablet info path", K(ret), K(backup_set_dest_), K(ls_id_), K(turn_id_), K(retry_id_)); + } else if (OB_FAIL(util.mk_parent_dir(backup_path.get_obstr(), backup_set_dest_.get_storage_info()))) { + LOG_WARN("failed to make parent dir", K(backup_path)); + } else if (OB_FAIL(util.open_with_access_type( + dev_handle_, io_fd_, backup_set_dest_.get_storage_info(), backup_path.get_obstr(), access_type))) { + LOG_WARN("failed to open with access type", K(ret), K(backup_set_dest_), K(backup_path)); + } else if (OB_FAIL(file_write_ctx_.open(data_file_size, io_fd_, *dev_handle_))) { + LOG_WARN("failed to open file write ctx", K(ret), K(backup_path), K(data_file_size), K(file_id)); + } else { + file_trailer_.reset(); + file_trailer_.file_id_ = file_id; + LOG_INFO("open file writer", K(ret), K(backup_path)); + } + return ret; +} + +int ObExternTabletMetaWriter::write_meta_data( + const blocksstable::ObBufferReader &meta_data, const common::ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tablet meta writer not inited", K(ret)); + } else if (!meta_data.is_valid() || !tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(meta_data), K(tablet_id)); + } else if (need_switch_file_(meta_data) && OB_FAIL(switch_file_())) { + LOG_WARN("failed to switch file", K(ret)); + } else if (OB_FAIL(write_meta_data_(meta_data, tablet_id))) { + LOG_WARN("failed to write meta data", K(ret), K(tablet_id)); + } else { + LOG_INFO("write meta data", K(meta_data), K(tablet_id)); + } + return ret; +} + +bool ObExternTabletMetaWriter::need_switch_file_(const blocksstable::ObBufferReader &buffer) +{ + const int64_t header_len = sizeof(ObBackupCommonHeader); + const int64_t align_size = common::upper_align(header_len + buffer.length(), DIO_READ_ALIGN_SIZE); + return file_trailer_.length_ + align_size + TRAILER_BUF > get_data_file_size(); +} + +int ObExternTabletMetaWriter::switch_file_() +{ + int ret = OB_SUCCESS; + int64_t next_file_id = file_trailer_.file_id_ + 1; + if (OB_FAIL(close())) { + LOG_WARN("failed to close", K(ret)); + } else if (OB_FAIL(prepare_backup_file_(next_file_id))) { + LOG_WARN("failed to prepare backup file", K(ret)); + } + return ret; +} + +int ObExternTabletMetaWriter::close() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tablet meta writer not inited", K(ret)); + } else if (OB_FAIL(flush_trailer_())) { + LOG_WARN("failed to flush trailer", K(ret)); + } else if (OB_FAIL(file_write_ctx_.close())) { + LOG_WARN("failed to close file writer", K(ret)); + } + return ret; +} + +int ObExternTabletMetaWriter::flush_trailer_() +{ + int ret = OB_SUCCESS; + tmp_buffer_.reuse(); + ObBackupSerializeHeaderWrapper serializer_wrapper(&file_trailer_); + int64_t pos = 0; + int64_t buf_len = serializer_wrapper.get_serialize_size(); + if (OB_FAIL(tmp_buffer_.advance_zero(buf_len))) { + LOG_WARN("failed to advance zero", K(ret)); + } else if (OB_FAIL(serializer_wrapper.serialize(tmp_buffer_.data(), tmp_buffer_.pos(), pos))) { + LOG_WARN("failed to serialize", K(ret), K(ret), K(tmp_buffer_)); + } else { + blocksstable::ObBufferReader buffer_reader(tmp_buffer_.data(), tmp_buffer_.length(), tmp_buffer_.length()); + if (OB_FAIL(file_write_ctx_.append_buffer(buffer_reader))) { + LOG_WARN("failed to append buffer", K(ret), K(buffer_reader)); + } else { + LOG_INFO("flush data file trailer", K(file_trailer_)); + } + } + return ret; +} + +int ObExternTabletMetaWriter::write_meta_data_( + const blocksstable::ObBufferReader &meta_data, const common::ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + const int64_t alignment = DIO_READ_ALIGN_SIZE; + const share::ObBackupFileType type = share::ObBackupFileType::BACKUP_TABLET_METAS_INFO; + if (OB_FAIL(write_data_align_(meta_data, type, alignment))) { + LOG_WARN("failed to write data align", K(ret), K(meta_data)); + } else { + int64_t length = 0; + blocksstable::ObBufferReader buffer_reader(tmp_buffer_.data(), tmp_buffer_.pos(), tmp_buffer_.pos()); + if (OB_FAIL(file_write_ctx_.append_buffer(buffer_reader))) { + LOG_WARN("failed to append buffer", K(ret), K(tmp_buffer_), K(buffer_reader)); + } else if (FALSE_IT(length = tmp_buffer_.pos())) { + } else { + file_trailer_.tablet_cnt_++; + file_trailer_.length_ += length; + } + } + return ret; +} + +int ObExternTabletMetaWriter::write_data_align_( + const blocksstable::ObBufferReader &buffer, const share::ObBackupFileType &type, const int64_t alignment) +{ + int ret = OB_SUCCESS; + tmp_buffer_.reuse(); + const int64_t header_len = sizeof(ObBackupCommonHeader); + const int64_t align_size = common::upper_align(header_len + buffer.length(), alignment); + const int64_t align_length = align_size - buffer.length() - header_len; + ObBackupCommonHeader *common_header = NULL; + if (!buffer.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(buffer)); + } else if (OB_FAIL(tmp_buffer_.advance_zero(header_len))) { + LOG_WARN("advance failed", K(ret), K(header_len)); + } else if (OB_FAIL(tmp_buffer_.write(buffer.data(), buffer.length()))) { + LOG_WARN("failed to write data", K(ret), K(buffer)); + } else if (OB_FAIL(tmp_buffer_.advance_zero(align_length))) { + LOG_WARN("failed to advance zero", K(ret), K(align_length)); + } else if (FALSE_IT(common_header = reinterpret_cast(tmp_buffer_.data()))) { + } else if (OB_FAIL(build_common_header(type, buffer.length(), align_length, common_header))) { + LOG_WARN("failed to build common header", K(ret), K(type), K(buffer), K(align_length)); + } else if (OB_FAIL(common_header->set_checksum(tmp_buffer_.data() + common_header->header_length_, buffer.length()))) { + LOG_WARN("failed to set common header checksum", K(ret), K(tmp_buffer_), K(buffer), K(*common_header)); + } + return ret; +} + +int ObExternTabletMetaReader::init(const share::ObBackupDest &backup_set_dest, const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("tablet meta reader init twice", K(ret), K(backup_set_dest), K(ls_id)); + } else if (OB_FAIL(backup_set_dest_.deep_copy(backup_set_dest))) { + LOG_WARN("failed to assign backup dest", K(ret)); + } else if (OB_FAIL(fill_tablet_info_trailer_(backup_set_dest, ls_id))) { + LOG_WARN("failed to fill tablet info trailer", K(ret), K(backup_set_dest), K(ls_id)); + } else { + ls_id_ = ls_id; + is_inited_ = true; + } + return ret; +} + +int ObExternTabletMetaReader::fill_tablet_info_trailer_(const share::ObBackupDest &backup_set_dest, const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ObExternBackupInfoIdGetter id_getter; + ObArray file_ids; + if (OB_FAIL(id_getter.init(backup_set_dest))) { + LOG_WARN("failed to init id getter", K(ret), K(backup_set_dest), K(ls_id)); + } else if (OB_FAIL(id_getter.get_max_turn_id_and_retry_id(ls_id, turn_id_, retry_id_))) { + LOG_WARN("failed to get max turn_id and retry_id", K(ret)); + } else if (OB_FAIL(id_getter.get_tablet_info_file_ids(ls_id, turn_id_, retry_id_, file_ids))) { + LOG_WARN("failed to get tablet info file ids", K(ret), K(turn_id_), K(retry_id_)); + } else { + ARRAY_FOREACH(file_ids, i) { + share::ObBackupPath path; + ObTabletInfoTrailer trailer; + if (OB_FAIL(ObBackupPathUtil::get_ls_data_tablet_info_path(backup_set_dest, ls_id, turn_id_, retry_id_, file_ids.at(i), path))) { + LOG_WARN("failed to get ls data tablet info path", K(ret), K(backup_set_dest_), K(ls_id_), K(turn_id_), K(retry_id_)); + } else if (OB_FAIL(read_file_trailer_(path.get_obstr(), backup_set_dest.get_storage_info(), trailer))) { + LOG_WARN("failed to read file trailer", K(ret), K(path)); + } else if (OB_FAIL(tablet_info_trailer_array_.push_back(trailer))) { + LOG_WARN("failed to push back trailer", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else { + cur_trailer_idx_ = 0; + cur_buf_offset_ = tablet_info_trailer_array_.at(cur_trailer_idx_).offset_; + cur_tablet_idx_ = 0; + LOG_INFO("fill tablet info trailer", K(tablet_info_trailer_array_)); + } + } + return ret; +} + +int ObExternTabletMetaReader::read_file_trailer_( + const common::ObString &path, const share::ObBackupStorageInfo *storage_info, ObTabletInfoTrailer &trailer) +{ + int ret = OB_SUCCESS; + ObBackupIoAdapter io_util; + bool exist = false; + int64_t file_length = 0; + char *buf = NULL; + ObArenaAllocator allocator; + ObTabletInfoTrailer tmp_trailer; + ObBackupSerializeHeaderWrapper serializer_wrapper(&tmp_trailer); + const int64_t trailer_len = serializer_wrapper.get_serialize_size(); + int64_t pos = 0; + if (OB_FAIL(io_util.is_exist(path, storage_info, exist))) { + LOG_WARN("failed to check file exist", K(ret), K(path), KP(storage_info)); + } else if (OB_UNLIKELY(!exist)) { + ret = OB_BACKUP_FILE_NOT_EXIST; + LOG_WARN("index file do not exist", K(ret), K(path)); + } else if (OB_FAIL(io_util.get_file_length(path, storage_info, file_length))) { + LOG_WARN("failed to get file length", K(ret), K(path), KP(storage_info)); + } else if (OB_UNLIKELY(file_length <= trailer_len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup index file too small", K(ret), K(file_length), K(trailer_len)); + } else if (OB_ISNULL(buf = static_cast(allocator.alloc(trailer_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret), K(trailer_len)); + } else if (OB_FAIL(ObLSBackupRestoreUtil::pread_file(path, storage_info, file_length - trailer_len, trailer_len, buf))) { + LOG_WARN("failed to pread file", K(ret), K(path), KP(storage_info), K(file_length), K(trailer_len)); + } else if (OB_FAIL(serializer_wrapper.deserialize(buf, trailer_len, pos))) { + LOG_WARN("failed to deserialize.", K(ret)); + } else if (OB_FAIL(trailer.assign(tmp_trailer))) { + LOG_WARN("failed to assign trailer", K(tmp_trailer)); + } else { + LOG_INFO("read trailer succeed", K(trailer)); + } + return ret; +} + +int ObExternTabletMetaReader::get_next(storage::ObMigrationTabletParam &tablet_meta) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tablet meta reader not init", K(ret)); + } else if (end_() && OB_FAIL(read_next_batch_())) { + LOG_WARN("failed to update inner array", K(ret)); + } else if (OB_FAIL(tablet_meta.assign(tablet_meta_array_.at(cur_tablet_idx_)))) { + LOG_WARN("failed to assign tablet meta", K(ret), K(cur_tablet_idx_), K(tablet_meta_array_)); + } else if (OB_FALSE_IT(cur_tablet_idx_++)) { + } + return ret; +} + +bool ObExternTabletMetaReader::end_() +{ + return tablet_meta_array_.count() == cur_tablet_idx_; +} + +int ObExternTabletMetaReader::read_next_batch_() +{ + int ret = OB_SUCCESS; + if (cur_buf_offset_ < tablet_info_trailer_array_.at(cur_trailer_idx_).length_) { + if (OB_FAIL(read_next_range_tablet_metas_())) { + LOG_WARN("failed to get next range tablet metas", K(ret), K(cur_buf_offset_), K(cur_trailer_idx_), K(tablet_info_trailer_array_)); + } + } else if (cur_trailer_idx_ < tablet_info_trailer_array_.count() - 1) { + cur_buf_offset_ = tablet_info_trailer_array_.at(++cur_trailer_idx_).offset_; + if (OB_FAIL(read_next_range_tablet_metas_())) { + LOG_WARN("failed to get next range tablet metas", K(ret), K(cur_buf_offset_), K(cur_trailer_idx_), K(tablet_info_trailer_array_)); + } + } else { + ret = OB_ITER_END; + LOG_INFO("iterate to the end", K(ret), + K(ls_id_), K(retry_id_), K(turn_id_), K(cur_buf_offset_), K(cur_trailer_idx_), K(tablet_info_trailer_array_), + K(cur_tablet_idx_), K(tablet_meta_array_)); + } + return ret; +} + +int ObExternTabletMetaReader::read_next_range_tablet_metas_() +{ + int ret = OB_SUCCESS; + share::ObBackupPath path; + char *buf = nullptr; + const int64_t DEFAULT_BUF_LEN = 2 * 1024 * 1024; // 2M + const int64_t buf_len = tablet_info_trailer_array_.at(cur_trailer_idx_).length_ - cur_buf_offset_ < DEFAULT_BUF_LEN ? + (tablet_info_trailer_array_.at(cur_trailer_idx_).length_ - cur_buf_offset_) : DEFAULT_BUF_LEN; + int64_t cur_total_len = 0; + common::ObArenaAllocator allocator(ObModIds::RESTORE); + const int64_t file_id = tablet_info_trailer_array_.at(cur_trailer_idx_).file_id_; + if (OB_ISNULL(buf = reinterpret_cast(allocator.alloc(buf_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc read buf", K(ret), K(buf_len)); + } else if (OB_FAIL(ObBackupPathUtil::get_ls_data_tablet_info_path(backup_set_dest_, ls_id_, turn_id_, retry_id_, file_id, path))) { + LOG_WARN("failed to get ls data tablet info path", K(ret), K(backup_set_dest_), K(ls_id_), K(turn_id_), K(retry_id_)); + } else if (OB_FAIL(ObLSBackupRestoreUtil::pread_file(path.get_obstr(), backup_set_dest_.get_storage_info(), cur_buf_offset_, buf_len, buf))) { + LOG_WARN("failed to pread buffer", K(ret), K(path), K(buf_len)); + } else { + storage::ObMigrationTabletParam tablet_meta; + ObArray cur_tablet_meta_array; + blocksstable::ObBufferReader buffer_reader(buf, buf_len); + // deserialize tablet meta one by one. + while(OB_SUCC(ret)) { + tablet_meta.reset(); + int64_t pos = 0; + const ObBackupCommonHeader *common_header = NULL; + if (buffer_reader.remain() == 0) { + cur_total_len = buffer_reader.capacity(); + LOG_INFO("read buf finish", K(cur_total_len), K(buffer_reader)); + break; + } else if (OB_FAIL(buffer_reader.get(common_header))) { + LOG_WARN("failed to get common_header", K(ret), K(path), K(buffer_reader)); + } else if (OB_ISNULL(common_header)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("common header is null", K(ret), K(path), K(buffer_reader)); + } else if (OB_FAIL(common_header->check_valid())) { + LOG_WARN("common_header is not valid", K(ret), K(path), K(buffer_reader)); + } else if (common_header->data_zlength_ > buffer_reader.remain()) { + cur_total_len = buffer_reader.pos() - sizeof(ObBackupCommonHeader); + LOG_INFO("buf not enough, wait later", K(cur_total_len), K(buffer_reader)); + break; + } else if (OB_FAIL(common_header->check_data_checksum(buffer_reader.current(), common_header->data_zlength_))) { + LOG_WARN("failed to check data checksum", K(ret), K(*common_header), K(path), K(buffer_reader)); + } else if (OB_FAIL(tablet_meta.deserialize(buffer_reader.current(), common_header->data_zlength_, pos))) { + LOG_WARN("failed to read data_header", K(ret), K(*common_header), K(path), K(buffer_reader)); + } else if (OB_FAIL(cur_tablet_meta_array.push_back(tablet_meta))) { + LOG_WARN("failed to push back tablet meta", K(ret)); + } else if (OB_FAIL(buffer_reader.advance(common_header->data_length_ + common_header->align_length_))) { + LOG_WARN("failed to advance buffer", K(ret)); + } else { + LOG_INFO("read tablet meta", K(path), K(tablet_meta)); + } + } + + if (OB_FAIL(ret)) { + } else { + tablet_meta_array_.reset(); + if (OB_FAIL(tablet_meta_array_.assign(cur_tablet_meta_array))) { + LOG_WARN("failed to assign tablet meta array", K(ret)); + } else { + cur_buf_offset_ += cur_total_len; + cur_tablet_idx_ = 0; + LOG_INFO("read range tablet metas", K(cur_tablet_idx_), K(tablet_meta_array_)); + } + } + } + return ret; +} + +int ObExternBackupInfoIdGetter::init(const share::ObBackupDest &backup_set_dest) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ls meta info id getter init twice", K(ret)); + } else if (!backup_set_dest.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(backup_set_dest), K(ls_id)); + } else if (OB_FAIL(backup_set_dest_.deep_copy(backup_set_dest))) { + LOG_WARN("failed to deep copy backup set dest", K(ret)); + } else { + is_inited_ = true; + } + return ret; +} + +int ObExternBackupInfoIdGetter::get_max_turn_id_and_retry_id(const share::ObLSID &ls_id, int64_t &turn_id, int64_t &retry_id) +{ + int ret = OB_SUCCESS; + ObBackupIoAdapter util; + ObLSMetaInfoDirFilter filter; + share::ObBackupPath backup_path; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("id getter not inited", K(ret)); + } else if (OB_FAIL(share::ObBackupPathUtil::get_ls_backup_dir_path(backup_set_dest_, ls_id, backup_path))) { + LOG_WARN("failed to get ls backup dier path", K(ret), K(backup_set_dest_), K(ls_id)); + } else if (OB_FAIL(util.list_directories(backup_path.get_obstr(), backup_set_dest_.get_storage_info(), filter))) { + LOG_WARN("failed to list directories", K(ret), K(backup_path), K(backup_set_dest_)); + } else if (filter.turn_id() <= 0 || filter.retry_id() < 0) { + ret = OB_BACKUP_FILE_NOT_EXIST; + LOG_WARN("invalid turn id and retry id, may not have meta info dir", K(ret), K(filter), K(backup_path)); + } else { + turn_id = filter.turn_id(); + retry_id = filter.retry_id(); + LOG_INFO("get max turn_id and retry_id", K(turn_id), K(retry_id), K(backup_path)); + } + return ret; +} + +int ObExternBackupInfoIdGetter::get_tablet_info_file_ids( + const share::ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, ObIArray &file_id_array) +{ + int ret = OB_SUCCESS; + ObBackupIoAdapter util; + ObLSTabletInfoIdFilter filter; + share::ObBackupPath backup_path; + file_id_array.reset(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("id getter not inited", K(ret)); + } else if (turn_id <= 0 || retry_id < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(turn_id), K(retry_id)); + } else if (OB_FAIL(share::ObBackupPathUtil::get_ls_backup_dir_path(backup_set_dest_, ls_id, backup_path))) { + LOG_WARN("failed to get ls backup dier path", K(ret), K(backup_set_dest_), K(ls_id)); + } else if (OB_FAIL(backup_path.join_meta_info_turn_and_retry(turn_id, retry_id))) { + LOG_WARN("failed to join meta info turn and retry", K(ret)); + } else if (OB_FAIL(filter.init())) { + LOG_WARN("failed to inited", K(ret)); + } else if (OB_FAIL(util.list_files(backup_path.get_obstr(), backup_set_dest_.get_storage_info(), filter))) { + LOG_WARN("failed to list directories", K(ret), K(backup_path), K(backup_set_dest_)); + } else if (OB_FAIL(filter.get_file_id_array(file_id_array))) { + LOG_WARN("failed to get file id array", K(ret)); + } else { + LOG_INFO("succeed get tablet info file ids", K(file_id_array)); + } + return ret; +} + +int ObExternBackupInfoIdGetter::ObLSMetaInfoDirFilter::func(const dirent *entry) +{ + int ret = OB_SUCCESS; + ObString dir_name(entry->d_name); + int64_t cur_turn_id = 0; + int64_t cur_retry_id = 0; + if (2 != sscanf(dir_name.ptr(), "meta_info_turn_%ld_retry_%ld", &cur_turn_id, &cur_retry_id)) { + } else if (cur_turn_id > turn_id_) { + turn_id_ = cur_turn_id; + retry_id_ = cur_retry_id; + } else if (cur_turn_id == turn_id_ && cur_retry_id > retry_id_) { + retry_id_ = cur_retry_id; + } + return ret; +} + +int ObExternBackupInfoIdGetter::ObLSTabletInfoIdFilter::init() +{ + int ret = OB_SUCCESS; + const int64_t default_bucket_num = 1024; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ObLSTabletInfoIdFilter init twice", K(ret)); + } else if (OB_FAIL(file_id_set_.create(default_bucket_num))) { + LOG_WARN("failed to create id set", K(ret), K(default_bucket_num)); + } else { + is_inited_ = true; + } + return ret; +} + +int ObExternBackupInfoIdGetter::ObLSTabletInfoIdFilter::func(const dirent *entry) +{ + int ret = OB_SUCCESS; + ObString file_name(entry->d_name); + int64_t file_id = 0; + if (1 != sscanf(file_name.ptr(), "tablet_info.%ld", &file_id)) { + } else if (file_id <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid file id", K(ret), K(file_id)); + } else if (OB_FAIL(file_id_set_.set_refactored(file_id, 0/*not cover exist object*/))) { + LOG_WARN("failed to set refactored", K(ret), K(file_id)); + } + return ret; +} + +int ObExternBackupInfoIdGetter::ObLSTabletInfoIdFilter::get_file_id_array(ObIArray &file_id_array) +{ + int ret = OB_SUCCESS; + if (file_id_set_.empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("file id must not be empty", K(ret)); + } else { + for (FileIdSet::const_iterator iter = file_id_set_.begin(); OB_SUCC(ret) && iter != file_id_set_.end(); iter++) { + if (OB_FAIL(file_id_array.push_back(iter->first))) { + LOG_WARN("failed to push backup", K(ret)); + } + } + } + return ret; +} + } // namespace backup } // namespace oceanbase diff --git a/src/storage/backup/ob_backup_extern_info_mgr.h b/src/storage/backup/ob_backup_extern_info_mgr.h index 1b79a69cf..f1d098491 100644 --- a/src/storage/backup/ob_backup_extern_info_mgr.h +++ b/src/storage/backup/ob_backup_extern_info_mgr.h @@ -15,12 +15,16 @@ #include "lib/container/ob_iarray.h" #include "share/ob_ls_id.h" #include "share/backup/ob_backup_path.h" +#include "share/backup/ob_backup_store.h" #include "storage/backup/ob_backup_data_struct.h" #include "storage/ls/ob_ls_meta_package.h" +#include "storage/tablet/ob_tablet_meta.h" +#include "storage/blocksstable/ob_data_buffer.h" +#include "storage/backup/ob_backup_ctx.h" #ifndef STORAGE_LOG_STREAM_BACKUP_EXTERN_INFO_MGR_H_ #define STORAGE_LOG_STREAM_BACKUP_EXTERN_INFO_MGR_H_ - +// TODO(chongrong.th) merge this file to ob_backup_data_store.h later. namespace oceanbase { namespace backup { @@ -60,6 +64,139 @@ private: DISALLOW_COPY_AND_ASSIGN(ObExternLSMetaMgr); }; +struct ObTabletInfoTrailer final : public ObExternBackupDataDesc +{ +public: + static const uint8_t FILE_VERSION = 1; + OB_UNIS_VERSION_V(1); +public: +ObTabletInfoTrailer(): + ObExternBackupDataDesc(share::ObBackupFileType::BACKUP_TABLET_METAS_INFO, FILE_VERSION), + file_id_(0), tablet_cnt_(0), offset_(0), length_(0) {} +virtual ~ObTabletInfoTrailer() {} + +void reset(); +bool is_valid() const override; +int assign(const ObTabletInfoTrailer &that); +TO_STRING_KV(K_(file_id), K_(tablet_cnt), K_(offset), K_(length)); + +int64_t file_id_; +int64_t tablet_cnt_; +int64_t offset_; +int64_t length_; +}; + +class ObExternTabletMetaWriter final +{ +public: + static const int64_t BUF_SIZE = 4 * 1024 * 1024; + static const int64_t TRAILER_BUF = 1024; + ObExternTabletMetaWriter(): is_inited_(false), backup_set_dest_(), ls_id_(), turn_id_(0), retry_id_(0), + io_fd_(0), dev_handle_(nullptr), file_write_ctx_(), file_trailer_(), tmp_buffer_("BackupExtInfo") {}; + ~ObExternTabletMetaWriter() {}; + int init(const share::ObBackupDest &backup_set_dest, const share::ObLSID &ls_id, + const int64_t turn_id, const int64_t retry_id); + int write_meta_data(const blocksstable::ObBufferReader &meta_data, const common::ObTabletID &tablet_id); + int close(); +private: + int write_meta_data_(const blocksstable::ObBufferReader &meta_data, const common::ObTabletID &tablet_id); + int prepare_backup_file_(const int64_t file_id); + int64_t get_data_file_size() const { return GCONF.backup_data_file_size; } + bool need_switch_file_(const blocksstable::ObBufferReader &buffer); + int switch_file_(); + int flush_trailer_(); + int write_data_align_( + const blocksstable::ObBufferReader &buffer, const share::ObBackupFileType &type, const int64_t alignment); +private: + bool is_inited_; + share::ObBackupDest backup_set_dest_; + share::ObLSID ls_id_; + int64_t turn_id_; + int64_t retry_id_; + common::ObIOFd io_fd_; + common::ObIODevice *dev_handle_; + ObBackupFileWriteCtx file_write_ctx_; + ObTabletInfoTrailer file_trailer_; + blocksstable::ObSelfBufferWriter tmp_buffer_; + DISALLOW_COPY_AND_ASSIGN(ObExternTabletMetaWriter); +}; + +class ObExternTabletMetaReader final +{ +public: + ObExternTabletMetaReader(): is_inited_(false), cur_tablet_idx_(-1), cur_trailer_idx_(-1), cur_buf_offset_(-1), + tablet_meta_array_(), tablet_info_trailer_array_() {} + ~ObExternTabletMetaReader() {}; + int init(const share::ObBackupDest &backup_set_dest, const share::ObLSID &ls_id); + int get_next(storage::ObMigrationTabletParam &tablet_meta); +private: + bool end_(); + int read_next_batch_(); + int read_next_range_tablet_metas_(); + int fill_tablet_info_trailer_(const share::ObBackupDest &backup_set_dest, const share::ObLSID &ls_id); + int read_file_trailer_(const common::ObString &path, const share::ObBackupStorageInfo *storage_info, ObTabletInfoTrailer &trailer); +private: + bool is_inited_; + share::ObLSID ls_id_; + int64_t cur_tablet_idx_; + int64_t cur_trailer_idx_; + int64_t cur_buf_offset_; + ObArray tablet_meta_array_; + ObArray tablet_info_trailer_array_; + int64_t retry_id_; + int64_t turn_id_; + share::ObBackupDest backup_set_dest_; + DISALLOW_COPY_AND_ASSIGN(ObExternTabletMetaReader); +}; + +class ObExternBackupInfoIdGetter final +{ +public: + class ObLSMetaInfoDirFilter final : public ObBaseDirEntryOperator + { + public: + public: + ObLSMetaInfoDirFilter(): turn_id_(0), retry_id_(0) {} + ~ObLSMetaInfoDirFilter() {} + int func(const dirent *entry) override; + const int64_t &turn_id() const { return turn_id_; } + const int64_t &retry_id() const { return retry_id_; } + TO_STRING_KV(K_(turn_id), K_(retry_id)); + private: + int64_t turn_id_; + int64_t retry_id_; + DISALLOW_COPY_AND_ASSIGN(ObLSMetaInfoDirFilter); + }; + + class ObLSTabletInfoIdFilter final : public ObBaseDirEntryOperator + { + public: + using FileIdSet = common::hash::ObHashSet; + public: + ObLSTabletInfoIdFilter(): is_inited_(false), file_id_set_() {} + ~ObLSTabletInfoIdFilter() {} + int init(); + int get_file_id_array(ObIArray &file_id_array); + int func(const dirent *entry) override; + private: + bool is_inited_; + FileIdSet file_id_set_; + DISALLOW_COPY_AND_ASSIGN(ObLSTabletInfoIdFilter); + }; + +public: + ObExternBackupInfoIdGetter(): is_inited_(false), backup_set_dest_() {} + ~ObExternBackupInfoIdGetter() {} + int init(const share::ObBackupDest &backup_set_dest); + int get_max_turn_id_and_retry_id(const share::ObLSID &ls_id, int64_t &turn_id, int64_t &retry_id); + int get_tablet_info_file_ids( + const share::ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, ObIArray &file_id_array); +private: + bool is_inited_; + share::ObBackupDest backup_set_dest_; + DISALLOW_COPY_AND_ASSIGN(ObExternBackupInfoIdGetter); +}; + } // namespace backup } // namespace oceanbase diff --git a/src/storage/backup/ob_backup_file_writer_ctx.cpp b/src/storage/backup/ob_backup_file_writer_ctx.cpp new file mode 100644 index 000000000..53c792d43 --- /dev/null +++ b/src/storage/backup/ob_backup_file_writer_ctx.cpp @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE +#include "ob_backup_file_writer_ctx.h" +#include "ob_backup_data_struct.h" +namespace oceanbase { + +namespace backup { + +/* ObBackupFileWriteCtx */ + +ObBackupFileWriteCtx::ObBackupFileWriteCtx() + : is_inited_(false), + file_size_(0), + max_file_size_(0), + io_fd_(), + dev_handle_(NULL), + data_buffer_("BackupFileWriteCtx") +{} + +ObBackupFileWriteCtx::~ObBackupFileWriteCtx() +{} + +int ObBackupFileWriteCtx::open(const int64_t max_file_size, const common::ObIOFd &io_fd, common::ObIODevice &dev_handle) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("backup data ctx init twice", K(ret)); + } else if (max_file_size < 0 || !io_fd.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(max_file_size), K(io_fd)); + } else if (OB_FAIL(data_buffer_.ensure_space(OB_DEFAULT_MACRO_BLOCK_SIZE))) { + LOG_WARN("failed to ensure space", K(ret)); + } else { + file_size_ = 0; + max_file_size_ = max_file_size; + io_fd_ = io_fd; + dev_handle_ = &dev_handle; + is_inited_ = true; + } + return ret; +} + +int ObBackupFileWriteCtx::append_buffer(const blocksstable::ObBufferReader &buffer, const bool is_last_part) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("file write ctx do not init", K(ret)); + } else if (!buffer.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(buffer)); + } else if (OB_FAIL(write_buffer_(buffer.data(), buffer.length(), is_last_part))) { + LOG_WARN("failed to write buffer", K(ret), K(buffer), K(is_last_part)); + } else { + LOG_DEBUG("append buffer to file write ctx", K(buffer)); + } + return ret; +} + +int ObBackupFileWriteCtx::close() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("file write ctx do not init", K(ret)); + } else if (OB_FAIL(commit_file_())) { + LOG_WARN("failed to commit file", K(ret)); + } else { + is_inited_ = false; + } + return ret; +} + +int ObBackupFileWriteCtx::write_buffer_(const char *buf, const int64_t len, const bool is_last_part) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || len <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(buf), K(len)); + } else if (OB_FAIL(data_buffer_.write(buf, len))) { + LOG_WARN("failed to write file writer", K(ret), K(buf), K(len)); + } else if (OB_FAIL(flush_buffer_(is_last_part))) { + LOG_WARN("failed to flush buffer", K(ret), K(is_last_part)); + } + return ret; +} + +bool ObBackupFileWriteCtx::check_can_flush_(const bool is_last_part) const +{ + return is_last_part || data_buffer_.length() >= OB_MAX_BACKUP_MEM_BUF_LEN; +} + +int ObBackupFileWriteCtx::flush_buffer_(const bool is_last_part) +{ + int ret = OB_SUCCESS; + int64_t write_size = 0; + const int64_t offset = file_size_; + if (!check_can_flush_(is_last_part)) { + LOG_DEBUG("can not flush now", K(is_last_part), K(data_buffer_)); + } else if (OB_ISNULL(dev_handle_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dev handle should not be null", K(ret)); + } else if (OB_FAIL(dev_handle_->pwrite(io_fd_, offset, data_buffer_.length(), data_buffer_.data(), write_size))) { + LOG_WARN("failed to write data buffer", K(ret), K(data_buffer_)); + } else if (data_buffer_.length() != write_size) { + ret = OB_IO_ERROR; + LOG_WARN("write length not equal buffer length", K(offset), K(data_buffer_.length()), K(write_size)); + } else { + file_size_ += write_size; + data_buffer_.reuse(); + } + return ret; +} + +int ObBackupFileWriteCtx::commit_file_() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(dev_handle_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dev handle should not be null", K(ret)); + } else if (OB_FAIL(flush_buffer_(true /*is_last_part*/))) { + LOG_WARN("failed to flush buffer", K(ret)); + } else if (OB_FAIL(dev_handle_->close(io_fd_))) { + LOG_WARN("failed to close file", K(ret), K_(io_fd)); + } else { + LOG_INFO("backup file write ctx commit file"); + } + return ret; +} + +} // namespace backup +} // namespace oceanbase diff --git a/src/storage/backup/ob_backup_file_writer_ctx.h b/src/storage/backup/ob_backup_file_writer_ctx.h new file mode 100644 index 000000000..bf69cecf3 --- /dev/null +++ b/src/storage/backup/ob_backup_file_writer_ctx.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2021 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 STORAGE_LOG_STREAM_BACKUP_FILE_WRITER_CTX_H_ +#define STORAGE_LOG_STREAM_BACKUP_FILE_WRITER_CTX_H_ +#include "common/storage/ob_io_device.h" +#include "storage/blocksstable/ob_data_buffer.h" +namespace oceanbase { + +namespace backup { + +struct ObBackupFileWriteCtx { +public: + ObBackupFileWriteCtx(); + virtual ~ObBackupFileWriteCtx(); + int open(const int64_t max_file_size, const common::ObIOFd &io_fd, common::ObIODevice &device_handle); + bool is_opened() const + { + return is_inited_; + } + int append_buffer(const blocksstable::ObBufferReader &buffer, const bool is_last_part = false); + int64_t get_file_size() const + { + return file_size_; + } + int close(); + +private: + int write_buffer_(const char *buf, const int64_t len, const bool is_last_part); + bool check_can_flush_(const bool is_last_part) const; + int flush_buffer_(const bool is_last_part); + int commit_file_(); + +private: + bool is_inited_; + int64_t file_size_; + int64_t max_file_size_; + common::ObIOFd io_fd_; + common::ObIODevice *dev_handle_; + blocksstable::ObSelfBufferWriter data_buffer_; + DISALLOW_COPY_AND_ASSIGN(ObBackupFileWriteCtx); +}; + +} // namespace backup +} // namespace oceanbase + +#endif diff --git a/src/storage/backup/ob_backup_handler.cpp b/src/storage/backup/ob_backup_handler.cpp index e6eb33359..4a6215b8f 100644 --- a/src/storage/backup/ob_backup_handler.cpp +++ b/src/storage/backup/ob_backup_handler.cpp @@ -31,10 +31,9 @@ int ObBackupHandler::schedule_backup_meta_dag(const ObBackupJobDesc &job_desc, c int ret = OB_SUCCESS; MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); ObBackupReportCtx report_ctx; - report_ctx.rs_mgr_ = GCTX.rs_mgr_; + report_ctx.location_service_ = GCTX.location_service_; report_ctx.sql_proxy_ = GCTX.sql_proxy_; - report_ctx.rs_rpc_proxy_ = GCTX.rs_rpc_proxy_; - ObLSBackupMetaDagNet *backup_dag_net = NULL; + report_ctx.rpc_proxy_ = GCTX.srv_rpc_proxy_; ObTenantDagScheduler *dag_scheduler = NULL; ObMySQLProxy *sql_proxy = GCTX.sql_proxy_; if (OB_ISNULL(sql_proxy) || !job_desc.is_valid() || !backup_dest.is_valid() || OB_INVALID_ID == tenant_id || @@ -65,14 +64,15 @@ int ObBackupHandler::schedule_backup_meta_dag(const ObBackupJobDesc &job_desc, c param.retry_id_ = retry_id; param.start_scn_ = start_scn; param.report_ctx_ = report_ctx; + param.backup_data_type_.set_sys_data_backup(); if (OB_FAIL(param.backup_dest_.deep_copy(backup_dest))) { LOG_WARN("failed to deep copy backup dest", K(ret), K(backup_dest)); } else if (OB_FAIL(ObBackupStorageInfoOperator::get_dest_id(*sql_proxy, tenant_id, backup_dest, param.dest_id_))) { LOG_WARN("failed to get dest id", K(ret), K(backup_dest)); - } else if (OB_FAIL(dag_scheduler->create_and_add_dag_net(¶m, backup_dag_net))) { + } else if (OB_FAIL(dag_scheduler->create_and_add_dag_net(¶m))) { LOG_WARN("failed to create log stream backup dag net", K(ret), K(param)); } else { - FLOG_INFO("success to create log stream backup dag net", K(ret), KP(backup_dag_net), K(param)); + FLOG_INFO("success to create log stream backup dag net", K(ret), K(param)); } } return ret; @@ -85,10 +85,9 @@ int ObBackupHandler::schedule_backup_data_dag(const ObBackupJobDesc &job_desc, c int ret = OB_SUCCESS; MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); ObBackupReportCtx report_ctx; - report_ctx.rs_mgr_ = GCTX.rs_mgr_; + report_ctx.location_service_ = GCTX.location_service_; report_ctx.sql_proxy_ = GCTX.sql_proxy_; - report_ctx.rs_rpc_proxy_ = GCTX.rs_rpc_proxy_; - ObLSBackupDataDagNet *backup_dag_net = NULL; + report_ctx.rpc_proxy_ = GCTX.srv_rpc_proxy_; ObTenantDagScheduler *dag_scheduler = NULL; ObMySQLProxy *sql_proxy = GCTX.sql_proxy_; if (OB_ISNULL(sql_proxy) || !job_desc.is_valid() || !backup_dest.is_valid() || OB_INVALID_ID == tenant_id @@ -121,10 +120,10 @@ int ObBackupHandler::schedule_backup_data_dag(const ObBackupJobDesc &job_desc, c LOG_WARN("failed to deep copy backup dest", K(ret), K(backup_dest)); } else if (OB_FAIL(ObBackupStorageInfoOperator::get_dest_id(*sql_proxy, tenant_id, backup_dest, param.dest_id_))) { LOG_WARN("failed to get dest id", K(ret), K(backup_dest)); - } else if (OB_FAIL(dag_scheduler->create_and_add_dag_net(¶m, backup_dag_net))) { + } else if (OB_FAIL(dag_scheduler->create_and_add_dag_net(¶m))) { LOG_WARN("failed to create log stream backup dag net", K(ret), K(param)); } else { - FLOG_INFO("success to create log stream backup dag net", K(ret), KP(backup_dag_net), K(param)); + FLOG_INFO("success to create log stream backup dag net", K(ret), K(param)); } } return ret; @@ -137,10 +136,9 @@ int ObBackupHandler::schedule_build_tenant_level_index_dag(const ObBackupJobDesc int ret = OB_SUCCESS; MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); ObBackupReportCtx report_ctx; - report_ctx.rs_mgr_ = GCTX.rs_mgr_; + report_ctx.location_service_ = GCTX.location_service_; report_ctx.sql_proxy_ = GCTX.sql_proxy_; - report_ctx.rs_rpc_proxy_ = GCTX.rs_rpc_proxy_; - ObBackupBuildTenantIndexDagNet *backup_dag_net = NULL; + report_ctx.rpc_proxy_ = GCTX.srv_rpc_proxy_; ObTenantDagScheduler *dag_scheduler = NULL; ObMySQLProxy *sql_proxy = GCTX.sql_proxy_; if (OB_ISNULL(sql_proxy) || !job_desc.is_valid() || !backup_dest.is_valid() || OB_INVALID_ID == tenant_id || @@ -173,10 +171,10 @@ int ObBackupHandler::schedule_build_tenant_level_index_dag(const ObBackupJobDesc LOG_WARN("failed to deep copy backup dest", K(ret), K(backup_dest)); } else if (OB_FAIL(ObBackupStorageInfoOperator::get_dest_id(*sql_proxy, tenant_id, backup_dest, param.dest_id_))) { LOG_WARN("failed to get dest id", K(ret), K(backup_dest)); - } else if (OB_FAIL(dag_scheduler->create_and_add_dag_net(¶m, backup_dag_net))) { + } else if (OB_FAIL(dag_scheduler->create_and_add_dag_net(¶m))) { LOG_WARN("failed to create log stream backup dag net", K(ret), K(param)); } else { - FLOG_INFO("success to create log stream backup dag net", K(ret), KP(backup_dag_net), K(param)); + FLOG_INFO("success to create log stream backup dag net", K(ret), K(param)); } } return ret; @@ -189,11 +187,10 @@ int ObBackupHandler::schedule_backup_complement_log_dag(const ObBackupJobDesc &j int ret = OB_SUCCESS; MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); ObBackupReportCtx report_ctx; - report_ctx.rs_mgr_ = GCTX.rs_mgr_; + report_ctx.location_service_ = GCTX.location_service_; report_ctx.sql_proxy_ = GCTX.sql_proxy_; - report_ctx.rs_rpc_proxy_ = GCTX.rs_rpc_proxy_; + report_ctx.rpc_proxy_ = GCTX.srv_rpc_proxy_; ObLSBackupDagNetInitParam param; - ObLSBackupComplementLogDagNet *backup_dag_net = NULL; ObTenantDagScheduler *dag_scheduler = NULL; ObMySQLProxy *sql_proxy = GCTX.sql_proxy_; if (OB_ISNULL(sql_proxy) ||!job_desc.is_valid() || !backup_dest.is_valid() || OB_INVALID_ID == tenant_id || @@ -228,10 +225,10 @@ int ObBackupHandler::schedule_backup_complement_log_dag(const ObBackupJobDesc &j LOG_WARN("failed to deep copy backup dest", K(ret), K(backup_dest)); } else if (OB_FAIL(ObBackupStorageInfoOperator::get_dest_id(*sql_proxy, tenant_id, backup_dest, param.dest_id_))) { LOG_WARN("failed to get dest id", K(ret), K(backup_dest)); - } else if (OB_FAIL(dag_scheduler->create_and_add_dag_net(¶m, backup_dag_net))) { + } else if (OB_FAIL(dag_scheduler->create_and_add_dag_net(¶m))) { LOG_WARN("failed to create log stream backup dag net", K(ret), K(param)); } else { - FLOG_INFO("success to create log stream backup dag net", K(ret), KP(backup_dag_net), K(param)); + FLOG_INFO("success to create log stream backup dag net", K(ret), K(param)); } } return ret; diff --git a/src/storage/backup/ob_backup_index_merger.cpp b/src/storage/backup/ob_backup_index_merger.cpp index e305d5491..72610546f 100644 --- a/src/storage/backup/ob_backup_index_merger.cpp +++ b/src/storage/backup/ob_backup_index_merger.cpp @@ -93,9 +93,9 @@ int ObBackupMacroIndexMajorFuser::fuse(MERGE_ITER_ARRAY &iter_array) int ret = OB_SUCCESS; if (iter_array.count() != 1) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("iter array count unexpected", K(ret)); + LOG_WARN("iter array count unexpected", K(ret), K(iter_array)); } else if (OB_FAIL(iter_array.at(0)->get_cur_index(result_))) { - LOG_WARN("failed to get cur index", K(ret)); + LOG_WARN("failed to get cur index", K(ret), K(iter_array)); } return ret; } @@ -537,8 +537,7 @@ ObIBackupIndexMerger::ObIBackupIndexMerger() io_fd_(), write_ctx_(), buffer_node_(), - sql_proxy_(NULL), - bandwidth_throttle_(NULL) + sql_proxy_(NULL) {} ObIBackupIndexMerger::~ObIBackupIndexMerger() @@ -574,11 +573,10 @@ int ObIBackupIndexMerger::open_file_writer_(const share::ObBackupPath &path, con return ret; } -int ObIBackupIndexMerger::prepare_file_write_ctx_( - common::ObInOutBandwidthThrottle &bandwidth_throttle, ObBackupFileWriteCtx &write_ctx) +int ObIBackupIndexMerger::prepare_file_write_ctx_(ObBackupFileWriteCtx &write_ctx) { int ret = OB_SUCCESS; - if (OB_FAIL(write_ctx.open(OB_MAX_BACKUP_FILE_SIZE, io_fd_, *dev_handle_, bandwidth_throttle))) { + if (OB_FAIL(write_ctx.open(OB_MAX_BACKUP_FILE_SIZE, io_fd_, *dev_handle_))) { LOG_WARN("failed to open backup file write ctx", K(ret)); } return ret; @@ -702,8 +700,7 @@ ObBackupMacroBlockIndexMerger::~ObBackupMacroBlockIndexMerger() reset(); } -int ObBackupMacroBlockIndexMerger::init(const ObBackupIndexMergeParam &merge_param, common::ObISQLClient &sql_proxy, - common::ObInOutBandwidthThrottle &bandwidth_throttle) +int ObBackupMacroBlockIndexMerger::init(const ObBackupIndexMergeParam &merge_param, common::ObISQLClient &sql_proxy) { int ret = OB_SUCCESS; const ObBackupBlockType block_type = BACKUP_BLOCK_MACRO_DATA; @@ -727,7 +724,6 @@ int ObBackupMacroBlockIndexMerger::init(const ObBackupIndexMergeParam &merge_par LOG_WARN("failed to assign param", K(ret), K(merge_param)); } else { sql_proxy_ = &sql_proxy; - bandwidth_throttle_ = &bandwidth_throttle; is_inited_ = true; } return ret; @@ -827,7 +823,7 @@ int ObBackupMacroBlockIndexMerger::prepare_merge_ctx_( LOG_WARN("failed to get output file path", K(ret), K(merge_param)); } else if (OB_FAIL(open_file_writer_(backup_path, merge_param.backup_dest_.get_storage_info()))) { LOG_WARN("failed to prepare file writer", K(ret), K(backup_path), K(merge_param)); - } else if (OB_FAIL(prepare_file_write_ctx_(*bandwidth_throttle_, write_ctx_))) { + } else if (OB_FAIL(prepare_file_write_ctx_(write_ctx_))) { LOG_WARN("failed to prepare file write ctx", K(ret)); } return ret; @@ -868,10 +864,12 @@ int ObBackupMacroBlockIndexMerger::prepare_prev_backup_set_index_iter_( const ObBackupIndexMergeParam &merge_param, common::ObISQLClient &sql_proxy, ObIMacroBlockIndexIterator *&iter) { int ret = OB_SUCCESS; + share::ObBackupSetFileDesc prev_backup_set_info; share::ObBackupSetDesc prev_backup_set_desc; ObBackupMacroRangeIndexIterator *tmp_iter = NULL; const ObBackupIndexIteratorType type = BACKUP_MACRO_RANGE_INDEX_ITERATOR; int64_t prev_tenant_index_retry_id = 0; + int64_t prev_tenant_index_turn_id = 0; if (!merge_param.backup_set_desc_.backup_type_.is_inc_backup()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("no need to prepare if not incremental", K(ret)); @@ -881,10 +879,18 @@ int ObBackupMacroBlockIndexMerger::prepare_prev_backup_set_index_iter_( LOG_WARN("failed to get backup index iterator", K(ret), K(type)); } else if (OB_FAIL(ObLSBackupOperator::get_prev_backup_set_desc(merge_param.tenant_id_, merge_param.backup_set_desc_.backup_set_id_, merge_param.dest_id_, - prev_backup_set_desc, + prev_backup_set_info, sql_proxy))) { LOG_WARN("failed to get prev backup set desc", K(ret), K(merge_param)); - } else if (OB_FAIL(get_prev_tenant_index_retry_id_(merge_param, prev_backup_set_desc, prev_tenant_index_retry_id))) { + } else if (OB_FALSE_IT(prev_backup_set_desc.backup_set_id_ = prev_backup_set_info.backup_set_id_)) { + } else if (OB_FALSE_IT(prev_backup_set_desc.backup_type_ = prev_backup_set_info.backup_type_)) { + } else if (OB_FALSE_IT(prev_tenant_index_turn_id = merge_param.backup_data_type_.is_major_backup() + ? prev_backup_set_info.major_turn_id_ + : prev_backup_set_info.minor_turn_id_)) { + } else if (OB_FAIL(get_prev_tenant_index_retry_id_(merge_param, + prev_backup_set_desc, + prev_tenant_index_turn_id, + prev_tenant_index_retry_id))) { LOG_WARN("failed to get prev tenant index retry id", K(ret), K(merge_param), K(prev_backup_set_desc)); } else if (OB_FAIL(tmp_iter->init(merge_param.task_id_, merge_param.backup_dest_, @@ -892,7 +898,7 @@ int ObBackupMacroBlockIndexMerger::prepare_prev_backup_set_index_iter_( prev_backup_set_desc, merge_param.ls_id_, merge_param.backup_data_type_, - merge_param.turn_id_, + prev_tenant_index_turn_id, prev_tenant_index_retry_id))) { LOG_WARN("failed to init backup macro range index iterator", K(ret), K(merge_param), K(prev_backup_set_desc), K(prev_tenant_index_retry_id)); } else { @@ -903,7 +909,7 @@ int ObBackupMacroBlockIndexMerger::prepare_prev_backup_set_index_iter_( } int ObBackupMacroBlockIndexMerger::get_prev_tenant_index_retry_id_(const ObBackupIndexMergeParam ¶m, - const share::ObBackupSetDesc &prev_backup_set_desc, int64_t &retry_id) + const share::ObBackupSetDesc &prev_backup_set_desc, const int64_t prev_turn_id, int64_t &retry_id) { int ret = OB_SUCCESS; const bool is_restore = false; @@ -911,8 +917,8 @@ int ObBackupMacroBlockIndexMerger::get_prev_tenant_index_retry_id_(const ObBacku const bool is_sec_meta = false; ObBackupTenantIndexRetryIDGetter retry_id_getter; if (OB_FAIL(retry_id_getter.init(param.backup_dest_, prev_backup_set_desc, - param.backup_data_type_, param.turn_id_, is_restore, is_macro_index, is_sec_meta))) { - LOG_WARN("failed to init retry id getter", K(ret), K(param)); + param.backup_data_type_, prev_turn_id, is_restore, is_macro_index, is_sec_meta))) { + LOG_WARN("failed to init retry id getter", K(ret), K(param), K(prev_turn_id)); } else if (OB_FAIL(retry_id_getter.get_max_retry_id(retry_id))) { LOG_WARN("failed to get max retry id", K(ret)); } @@ -1192,7 +1198,7 @@ ObBackupMetaIndexMerger::~ObBackupMetaIndexMerger() } int ObBackupMetaIndexMerger::init(const ObBackupIndexMergeParam &merge_param, const bool is_sec_meta, - common::ObISQLClient &sql_proxy, common::ObInOutBandwidthThrottle &bandwidth_throttle) + common::ObISQLClient &sql_proxy) { int ret = OB_SUCCESS; const ObBackupBlockType block_type = BACKUP_BLOCK_META_DATA; @@ -1216,7 +1222,6 @@ int ObBackupMetaIndexMerger::init(const ObBackupIndexMergeParam &merge_param, co LOG_WARN("failed to assign param", K(ret), K(merge_param)); } else { sql_proxy_ = &sql_proxy; - bandwidth_throttle_ = &bandwidth_throttle; is_inited_ = true; } return ret; @@ -1307,7 +1312,7 @@ int ObBackupMetaIndexMerger::prepare_merge_ctx_( LOG_WARN("failed to get output file path", K(ret), K(merge_param)); } else if (OB_FAIL(open_file_writer_(backup_path, merge_param.backup_dest_.get_storage_info()))) { LOG_WARN("failed to prepare file writer", K(ret), K(backup_path), K(merge_param)); - } else if (OB_FAIL(prepare_file_write_ctx_(*bandwidth_throttle_, write_ctx_))) { + } else if (OB_FAIL(prepare_file_write_ctx_(write_ctx_))) { LOG_WARN("failed to prepare file write ctx", K(ret)); } return ret; diff --git a/src/storage/backup/ob_backup_index_merger.h b/src/storage/backup/ob_backup_index_merger.h index a78b51edd..918b423d0 100644 --- a/src/storage/backup/ob_backup_index_merger.h +++ b/src/storage/backup/ob_backup_index_merger.h @@ -165,7 +165,7 @@ protected: virtual int get_all_retries_(const int64_t task_id, const uint64_t tenant_id, const share::ObBackupDataType &backup_data_type, const share::ObLSID &ls_id, common::ObISQLClient &sql_proxy, common::ObIArray &retry_list); int open_file_writer_(const share::ObBackupPath &backup_path, const share::ObBackupStorageInfo *storage_info); - int prepare_file_write_ctx_(common::ObInOutBandwidthThrottle &bandwidth_throttle, ObBackupFileWriteCtx &write_ctx); + int prepare_file_write_ctx_(ObBackupFileWriteCtx &write_ctx); template int encode_index_to_buffer_(const common::ObIArray &index_list, blocksstable::ObBufferWriter &buffer_writer); template @@ -189,7 +189,6 @@ protected: ObBackupFileWriteCtx write_ctx_; ObBackupIndexBufferNode buffer_node_; common::ObISQLClient *sql_proxy_; - common::ObInOutBandwidthThrottle *bandwidth_throttle_; DISALLOW_COPY_AND_ASSIGN(ObIBackupIndexMerger); }; @@ -197,8 +196,7 @@ class ObBackupMacroBlockIndexMerger : public ObIBackupIndexMerger { public: ObBackupMacroBlockIndexMerger(); virtual ~ObBackupMacroBlockIndexMerger(); - int init(const ObBackupIndexMergeParam &merge_param, common::ObISQLClient &sql_proxy, - common::ObInOutBandwidthThrottle &bandwidth_throttle); + int init(const ObBackupIndexMergeParam &merge_param, common::ObISQLClient &sql_proxy); void reset(); virtual int merge_index() override; @@ -214,7 +212,7 @@ private: int prepare_prev_backup_set_index_iter_( const ObBackupIndexMergeParam &merge_param, common::ObISQLClient &sql_proxy, ObIMacroBlockIndexIterator *&iter); int get_prev_tenant_index_retry_id_(const ObBackupIndexMergeParam &merge_param, - const share::ObBackupSetDesc &prev_backup_set_desc, int64_t &retry_id); + const share::ObBackupSetDesc &prev_backup_set_desc, const int64_t prev_turn_id, int64_t &retry_id); int get_unfinished_iters_(const MERGE_ITER_ARRAY &merge_iters, MERGE_ITER_ARRAY &unfinished_iters); int find_minimum_iters_(const MERGE_ITER_ARRAY &merge_iters, MERGE_ITER_ARRAY &min_iters); int prepare_merge_fuser_(ObIBackupMacroBlockIndexFuser *&fuser); @@ -245,8 +243,7 @@ class ObBackupMetaIndexMerger : public ObIBackupIndexMerger { public: ObBackupMetaIndexMerger(); virtual ~ObBackupMetaIndexMerger(); - int init(const ObBackupIndexMergeParam &merge_param, const bool is_sec_meta, common::ObISQLClient &sql_proxy, - common::ObInOutBandwidthThrottle &bandwidth_throttle); + int init(const ObBackupIndexMergeParam &merge_param, const bool is_sec_meta, common::ObISQLClient &sql_proxy); void reset(); virtual int merge_index() override; diff --git a/src/storage/backup/ob_backup_index_store.cpp b/src/storage/backup/ob_backup_index_store.cpp index ae085cec9..628c7cb35 100644 --- a/src/storage/backup/ob_backup_index_store.cpp +++ b/src/storage/backup/ob_backup_index_store.cpp @@ -939,6 +939,16 @@ int ObBackupMacroBlockIndexStore::get_macro_block_index_(const blocksstable::ObL LOG_WARN("no macro block index exist", K(ret), K(macro_id), K(range_index), K(index_list)); } } +#ifdef ERRSIM + if (macro_id.tablet_id_ == GCONF.errsim_backup_tablet_id) { + SERVER_EVENT_SYNC_ADD("backup_errsim", "get_macro_block_index", + "logic_id", macro_id, + "range_index", range_index, + "macro_index", macro_index, + "backup_path", backup_path, + "result", ret); + } +#endif return ret; } @@ -1090,14 +1100,17 @@ ObBackupMetaIndexStoreWrapper::~ObBackupMetaIndexStoreWrapper() {} int ObBackupMetaIndexStoreWrapper::init(const ObBackupRestoreMode &mode, const ObBackupIndexStoreParam ¶m, - const share::ObBackupDest &backup_dest, const share::ObBackupSetDesc &backup_set_desc, const bool is_sec_meta, - ObBackupIndexKVCache &index_kv_cache) + const share::ObBackupDest &backup_dest, const share::ObBackupSetFileDesc &backup_set_info, const bool is_sec_meta, + const bool init_sys_tablet_index_store, ObBackupIndexKVCache &index_kv_cache) { int ret = OB_SUCCESS; + share::ObBackupSetDesc backup_set_desc; if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("index store init twice", K(ret)); } else { + backup_set_desc.backup_set_id_ = backup_set_info.backup_set_id_; + backup_set_desc.backup_type_ = backup_set_info.backup_type_; ObBackupIndexStoreParam share_param = param; for (int64_t i = 0; OB_SUCC(ret) && i < ARRAY_SIZE; ++i) { ObBackupDataType backup_data_type; @@ -1105,13 +1118,19 @@ int ObBackupMetaIndexStoreWrapper::init(const ObBackupRestoreMode &mode, const O int64_t retry_id = 0; if (OB_FAIL(get_type_by_idx_(i, backup_data_type))) { LOG_WARN("failed to get type by idx", K(ret), K(i)); + } else if (backup_data_type.is_sys_backup() && !init_sys_tablet_index_store) { + continue; + } + if (OB_FAIL(ret)) { + } else if (backup_data_type.is_minor_backup() && OB_FALSE_IT(share_param.turn_id_ = backup_set_info.minor_turn_id_)) { + } else if (backup_data_type.is_major_backup() && OB_FALSE_IT(share_param.turn_id_ = backup_set_info.major_turn_id_)) { } else if (OB_FAIL(get_index_store_(backup_data_type, store))) { LOG_WARN("failed to get index store", K(ret), K(backup_data_type)); } else if (OB_ISNULL(store)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get index store", K(ret), K(backup_data_type)); } else if (!backup_data_type.is_sys_backup() && OB_FAIL(get_tenant_meta_index_retry_id_( - backup_dest, backup_data_type, param.turn_id_, is_sec_meta, retry_id))) { + backup_dest, backup_data_type, share_param.turn_id_, is_sec_meta, retry_id))) { LOG_WARN("failed to get tenant meta index retry id", K(ret)); } else { share_param.backup_data_type_ = backup_data_type; @@ -1372,13 +1391,16 @@ int ObBackupTenantIndexRetryIDGetter::get_ls_info_data_info_dir_path_(ObBackupPa int ret = OB_SUCCESS; backup_path.reset(); if (is_restore_) { - if (OB_FAIL(share::ObBackupPathUtil::get_ls_info_data_info_dir_path(backup_dest_, turn_id_, backup_path))) { - LOG_WARN("failed to get ls info data info dir path", K(ret), K_(backup_dest), K_(backup_set_desc), K_(turn_id)); + if (OB_FAIL(share::ObBackupPathUtil::get_ls_info_data_info_dir_path( + backup_dest_, backup_data_type_, turn_id_, backup_path))) { + LOG_WARN("failed to get ls info data info dir path", + K(ret), K_(backup_dest), K_(backup_data_type), K_(backup_set_desc), K_(turn_id)); } } else { if (OB_FAIL(share::ObBackupPathUtil::get_ls_info_data_info_dir_path( - backup_dest_, backup_set_desc_, turn_id_, backup_path))) { - LOG_WARN("failed to get ls info data info dir path", K(ret), K_(backup_dest), K_(backup_set_desc), K_(turn_id)); + backup_dest_, backup_set_desc_, backup_data_type_, turn_id_, backup_path))) { + LOG_WARN("failed to get ls info data info dir path", + K(ret), K_(backup_dest), K_(backup_set_desc), K_(backup_data_type), K_(turn_id)); } } return ret; diff --git a/src/storage/backup/ob_backup_index_store.h b/src/storage/backup/ob_backup_index_store.h index 04397a333..388cf4d50 100644 --- a/src/storage/backup/ob_backup_index_store.h +++ b/src/storage/backup/ob_backup_index_store.h @@ -205,8 +205,8 @@ public: ObBackupMetaIndexStoreWrapper(); virtual ~ObBackupMetaIndexStoreWrapper(); int init(const ObBackupRestoreMode &mode, const ObBackupIndexStoreParam ¶m, - const share::ObBackupDest &backup_dest, const share::ObBackupSetDesc &backup_set_desc, const bool is_sec_meta, - ObBackupIndexKVCache &index_kv_cache); + const share::ObBackupDest &backup_dest, const share::ObBackupSetFileDesc &backup_set_info, const bool is_sec_meta, + const bool init_sys_tablet_index_store, ObBackupIndexKVCache &index_kv_cache); int get_backup_meta_index(const share::ObBackupDataType &backup_data_type, const common::ObTabletID &tablet_id, const ObBackupMetaType &meta_type, ObBackupMetaIndex &meta_index); diff --git a/src/storage/backup/ob_backup_iterator.h b/src/storage/backup/ob_backup_iterator.h index fc8826219..425cdfb83 100644 --- a/src/storage/backup/ob_backup_iterator.h +++ b/src/storage/backup/ob_backup_iterator.h @@ -127,8 +127,9 @@ public: { return BACKUP_MACRO_BLOCK_INDEX_ITERATOR; } - TO_STRING_KV( - K_(backup_dest), K_(tenant_id), K_(backup_set_desc), K_(ls_id), "type", "backup macro block index iterator"); + TO_STRING_KV(K_(task_id), K_(backup_dest), K_(tenant_id), K_(backup_set_desc), K_(ls_id), K_(backup_data_type), + K_(turn_id), K_(retry_id), K_(cur_file_id), K_(file_id_list), K_(cur_idx), K(cur_index_list_.count()), K_(cur_index_list), + "type", "backup macro block index iterator"); private: bool need_fetch_new_() const; @@ -161,7 +162,7 @@ public: { return BACKUP_MACRO_RANGE_INDEX_ITERATOR; } - TO_STRING_KV(K_(backup_path), K_(tenant_id), K_(backup_set_desc), K_(ls_id), K_(cur_idx), K(cur_index_list_.count()), + TO_STRING_KV(K_(backup_path), K_(tenant_id), K_(backup_set_desc), K_(ls_id), K_(cur_idx), K_(cur_index_list), K(cur_index_list_.count()), "type", "backup_macro_range_index_iterator"); private: diff --git a/src/storage/backup/ob_backup_operator.cpp b/src/storage/backup/ob_backup_operator.cpp old mode 100644 new mode 100755 index d6e6cf030..bfe7de2bf --- a/src/storage/backup/ob_backup_operator.cpp +++ b/src/storage/backup/ob_backup_operator.cpp @@ -224,11 +224,10 @@ int ObLSBackupOperator::mark_ls_task_info_final(const int64_t task_id, const uin } int ObLSBackupOperator::get_prev_backup_set_desc(const uint64_t tenant_id, const int64_t backup_set_id, const int64_t dest_id, - ObBackupSetDesc &prev_backup_set_desc, common::ObISQLClient &sql_client) + share::ObBackupSetFileDesc &prev_desc, common::ObISQLClient &sql_client) { int ret = OB_SUCCESS; share::ObBackupSetFileDesc cur_desc; - share::ObBackupSetFileDesc prev_desc; const bool for_update = false; if (OB_FAIL(ObBackupSetFileOperator::get_backup_set_file( sql_client, for_update, backup_set_id, OB_START_INCARNATION, tenant_id, dest_id, cur_desc))) { @@ -244,9 +243,6 @@ int ObLSBackupOperator::get_prev_backup_set_desc(const uint64_t tenant_id, const dest_id, prev_desc))) { LOG_WARN("failed to get backup set", K(ret), K(cur_desc.prev_inc_backup_set_id_), K(tenant_id)); - } else { - prev_backup_set_desc.backup_set_id_ = prev_desc.backup_set_id_; - prev_backup_set_desc.backup_type_= prev_desc.backup_type_; } return ret; } @@ -330,8 +326,8 @@ int ObLSBackupOperator::report_tablet_skipped( LOG_WARN("get invalid args", K(ret), K(tenant_id), K(skipped_tablet)); } else if (OB_FAIL(fill_backup_skipped_tablet_(skipped_tablet, dml_splicer))) { LOG_WARN("failed to fill backup skipped tablet", K(ret), K(skipped_tablet)); - } else if (OB_FAIL(dml_splicer.splice_insert_update_sql(OB_ALL_BACKUP_SKIPPED_TABLET_TNAME, sql))) { - LOG_WARN("failed to splice insert update sql", K(ret), K(tenant_id), K(skipped_tablet), K(sql)); + } else if (OB_FAIL(dml_splicer.splice_insert_sql(OB_ALL_BACKUP_SKIPPED_TABLET_TNAME, sql))) { + LOG_WARN("failed to splice update sql", K(ret), K(sql)); } else if (OB_FAIL(sql_client.write(gen_meta_tenant_id(tenant_id), sql.ptr(), affected_rows))) { LOG_WARN("failed to execute sql", K(ret), K(sql)); } else { @@ -430,11 +426,12 @@ int ObLSBackupOperator::parse_ls_task_info_results_( int ObLSBackupOperator::fill_backup_skipped_tablet_(const ObBackupSkippedTablet &task_info, share::ObDMLSqlSplicer &dml) { int ret = OB_SUCCESS; + int turn_id = task_info.data_type_.is_minor_backup() ? task_info.turn_id_ : share::ObBackupSkipTabletAttr::BASE_MAJOR_TURN_ID + task_info.turn_id_; if (OB_FAIL(dml.add_pk_column("task_id", task_info.task_id_))) { LOG_WARN("failed to add pk column", K(task_info)); } else if (OB_FAIL(dml.add_pk_column("tenant_id", task_info.tenant_id_))) { LOG_WARN("failed to add pk column", K(task_info)); - } else if (OB_FAIL(dml.add_pk_column("turn_id", task_info.turn_id_))) { + } else if (OB_FAIL(dml.add_pk_column("turn_id", turn_id))) { LOG_WARN("failed to add pk column", K(task_info)); } else if (OB_FAIL(dml.add_pk_column("retry_id", task_info.retry_id_))) { LOG_WARN("failed to add pk column", K(task_info)); diff --git a/src/storage/backup/ob_backup_operator.h b/src/storage/backup/ob_backup_operator.h index 23b1996d5..5454c0185 100644 --- a/src/storage/backup/ob_backup_operator.h +++ b/src/storage/backup/ob_backup_operator.h @@ -42,7 +42,7 @@ public: common::ObISQLClient &sql_client); // __all_backup_set_files static int get_prev_backup_set_desc(const uint64_t tenant_id, const int64_t backup_set_id, const int64_t dest_id, - share::ObBackupSetDesc &backup_set_desc, common::ObISQLClient &sql_client); + share::ObBackupSetFileDesc &prev_desc, common::ObISQLClient &sql_client); // __all_backup_ls_task static int report_ls_task_finish(const uint64_t tenant_id, const int64_t task_id, const share::ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, const int64_t result, common::ObISQLClient &sql_client); diff --git a/src/storage/backup/ob_backup_reader.cpp b/src/storage/backup/ob_backup_reader.cpp index 06a223802..97c04ab13 100644 --- a/src/storage/backup/ob_backup_reader.cpp +++ b/src/storage/backup/ob_backup_reader.cpp @@ -64,16 +64,30 @@ int ObLSTabletIdReader::init(const share::ObBackupDest &backup_dest, const uint6 } int ObLSTabletIdReader::get_tablet_id_list( - const int64_t turn_id, const share::ObLSID &ls_id, common::ObIArray &tablet_list) + share::ObBackupDataType &backup_data_type, const int64_t turn_id, + const share::ObLSID &ls_id, common::ObIArray &tablet_list) { int ret = OB_SUCCESS; if (turn_id < 0 || !ls_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(turn_id), K(ls_id)); - } else if (OB_FAIL(store_.read_tablet_to_ls_info(turn_id, ls_id, tablet_list))) { - LOG_WARN("failed to read tablet to ls info", K(ret), K(turn_id), K(ls_id)); - } else { - LOG_INFO("get tablet id list", K(turn_id), K(ls_id), K(tablet_list)); + } else if (backup_data_type.is_sys_backup()) { + ObLS::ObLSInnerTabletIDIter tablet_iter; + ObTabletID tablet_id; + while (OB_SUCC(ret)) { + if (OB_FAIL(tablet_iter.get_next(tablet_id))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get next tablet id", K(ret)); + } + } else if (OB_FAIL(tablet_list.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret)); + } + } + } else if (OB_FAIL(store_.read_tablet_list(backup_data_type, turn_id, ls_id, tablet_list))) { + LOG_WARN("failed to read minor tablet to ls info", K(ret), K(turn_id), K(ls_id)); } return ret; } @@ -111,7 +125,7 @@ int ObTabletLogicMacroIdReader::init(const common::ObTabletID &tablet_id, const } else if (OB_FAIL(meta_iter_.open(datum_range_, ObMacroBlockMetaType::DATA_BLOCK_META, sstable, - tablet_handle.get_obj()->get_index_read_info(), + tablet_handle.get_obj()->get_rowkey_read_info(), allocator_))) { LOG_WARN("failed to open sec meta iterator", K(ret)); } else { @@ -537,7 +551,8 @@ int ObTabletMetaBackupReader::get_meta_data(blocksstable::ObBufferReader &buffer /* ObSSTableMetaBackupReader */ -ObSSTableMetaBackupReader::ObSSTableMetaBackupReader() : ObITabletMetaBackupReader(), sstable_array_(), buffer_writer_("BackupReader") +ObSSTableMetaBackupReader::ObSSTableMetaBackupReader() + : ObITabletMetaBackupReader(), sstable_array_(), buffer_writer_("BackupReader"), table_store_wrapper_() {} ObSSTableMetaBackupReader::~ObSSTableMetaBackupReader() @@ -558,9 +573,11 @@ int ObSSTableMetaBackupReader::init(const common::ObTabletID &tablet_id, backup_data_type_ = backup_data_type; tablet_handle_ = &tablet_handle; ObTablet &tablet = *tablet_handle_->get_obj(); - ObTabletTableStore &table_store = tablet.get_table_store(); - if (OB_FAIL(ObBackupUtils::get_sstables_by_data_type(tablet_handle, backup_data_type_, table_store, sstable_array_))) { - LOG_WARN("failed to get sstables by data type", K(ret), K(tablet_handle), K_(backup_data_type), K(table_store)); + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper_))) { + LOG_WARN("failed to fetch table store from tablet", K(ret)); + } else if (OB_FAIL(ObBackupUtils::get_sstables_by_data_type( + tablet_handle, backup_data_type_, *table_store_wrapper_.get_member(), sstable_array_))) { + LOG_WARN("failed to get sstables by data type", K(ret), K(tablet_handle), K_(backup_data_type)); } else { is_inited_ = true; } diff --git a/src/storage/backup/ob_backup_reader.h b/src/storage/backup/ob_backup_reader.h index e9c795287..dd9472737 100644 --- a/src/storage/backup/ob_backup_reader.h +++ b/src/storage/backup/ob_backup_reader.h @@ -17,13 +17,13 @@ #include "lib/lock/ob_spin_lock.h" #include "lib/hash/ob_cuckoo_hashmap.h" #include "share/ob_ls_id.h" -#include "share/backup/ob_backup_data_store.h" -#include "storage/backup/ob_backup_extern_info_mgr.h" +#include "storage/backup/ob_backup_data_store.h" #include "storage/backup/ob_backup_data_struct.h" #include "storage/blocksstable/ob_block_manager.h" #include "storage/blocksstable/ob_data_buffer.h" #include "storage/blocksstable/ob_sstable_meta.h" #include "storage/blocksstable/ob_sstable_sec_meta_iterator.h" +#include "storage/tablet/ob_tablet_member_wrapper.h" #include "storage/meta_mem/ob_tablet_handle.h" #include "storage/ob_i_table.h" #include "storage/blocksstable/ob_shared_macro_block_manager.h" @@ -45,7 +45,8 @@ public: virtual int init(const share::ObBackupDest &backup_dest, const uint64_t tenant_id, const share::ObBackupSetDesc &backup_set_desc, const share::ObLSID &ls_id) = 0; virtual int get_tablet_id_list( - const int64_t turn_id, const share::ObLSID &ls_id, common::ObIArray &tablet_id_list) = 0; + share::ObBackupDataType &backup_data_type, const int64_t turn_id, + const share::ObLSID &ls_id, common::ObIArray &tablet_id_list) = 0; virtual ObLSTabletIdReaderType get_type() const = 0; protected: @@ -62,7 +63,8 @@ public: int init(const share::ObBackupDest &backup_dest, const uint64_t tenant_id, const share::ObBackupSetDesc &backup_set_desc, const share::ObLSID &ls_id); virtual int get_tablet_id_list( - const int64_t turn_id, const share::ObLSID &ls_id, common::ObIArray &tablet_id_list) override; + share::ObBackupDataType &backup_data_type, const int64_t turn_id, + const share::ObLSID &ls_id, common::ObIArray &tablet_id_list) override; virtual ObLSTabletIdReaderType get_type() const override { return LS_TABLET_ID_READER; @@ -74,7 +76,7 @@ private: uint64_t tenant_id_; share::ObBackupSetDesc backup_set_desc_; share::ObLSID ls_id_; - share::ObBackupDataStore store_; + storage::ObBackupDataStore store_; DISALLOW_COPY_AND_ASSIGN(ObLSTabletIdReader); }; @@ -269,6 +271,7 @@ private: private: common::ObArray sstable_array_; blocksstable::ObSelfBufferWriter buffer_writer_; + ObTabletMemberWrapper table_store_wrapper_; DISALLOW_COPY_AND_ASSIGN(ObSSTableMetaBackupReader); }; diff --git a/src/storage/backup/ob_backup_restore_util.cpp b/src/storage/backup/ob_backup_restore_util.cpp index 55dcd457b..51c902f56 100644 --- a/src/storage/backup/ob_backup_restore_util.cpp +++ b/src/storage/backup/ob_backup_restore_util.cpp @@ -13,7 +13,7 @@ #define USING_LOG_PREFIX STORAGE #include "storage/backup/ob_backup_restore_util.h" #include "storage/blocksstable/ob_data_buffer.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" #include "share/backup/ob_backup_io_adapter.h" #include "share/io/ob_io_struct.h" #include "share/backup/ob_backup_store.h" diff --git a/src/storage/backup/ob_backup_task.cpp b/src/storage/backup/ob_backup_task.cpp old mode 100644 new mode 100755 index e5bc8298f..2a7903d38 --- a/src/storage/backup/ob_backup_task.cpp +++ b/src/storage/backup/ob_backup_task.cpp @@ -37,6 +37,7 @@ #include "storage/meta_mem/ob_tablet_handle.h" #include "logservice/archiveservice/ob_archive_file_utils.h" #include "share/ls/ob_ls_table_operator.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "storage/ob_storage_rpc.h" #include "storage/blocksstable/ob_logic_macro_id.h" #include "share/backup/ob_backup_struct.h" @@ -54,6 +55,22 @@ using namespace oceanbase::archive; namespace oceanbase { namespace backup { +#ifndef REPORT_TASK_RESULT +#define REPORT_TASK_RESULT(dag_id, result)\ + if (OB_SUCCESS != (tmp_ret = ObBackupUtils::report_task_result(param_.job_desc_.job_id_, \ + param_.job_desc_.task_id_, \ + param_.tenant_id_, \ + param_.ls_id_, \ + param_.turn_id_, \ + param_.retry_id_, \ + param_.job_desc_.trace_id_, \ + (dag_id), \ + (result), \ + report_ctx_))) { \ + LOG_WARN("failed to report task result", K(tmp_ret)); \ + } +#endif +ERRSIM_POINT_DEF(EN_LS_BACKUP_FAILED); static int get_ls_handle(const uint64_t tenant_id, const share::ObLSID &ls_id, storage::ObLSHandle &ls_handle) { @@ -209,6 +226,7 @@ int ObLSBackupDagNetInitParam::convert_to(ObLSBackupParam ¶m) } else if (OB_FAIL(param.backup_dest_.deep_copy(backup_dest_))) { LOG_WARN("failed to deep copy backup dest", K(ret), K_(backup_dest)); } else { + param.job_id_ = job_desc_.job_id_; param.task_id_ = job_desc_.task_id_; param.tenant_id_ = tenant_id_; param.backup_set_desc_ = backup_set_desc_; @@ -243,8 +261,8 @@ int ObLSBackupDagNetInitParam::convert_to(ObLSBackupDagInitParam &init_param) bool ObLSBackupDagNetInitParam::operator==(const ObLSBackupDagNetInitParam &other) const { return job_desc_ == other.job_desc_ && backup_dest_ == other.backup_dest_ && tenant_id_ == other.tenant_id_ && - backup_set_desc_ == other.backup_set_desc_ && ls_id_ == other.ls_id_ && turn_id_ == other.turn_id_ && - retry_id_ == other.retry_id_ && dest_id_ == other.dest_id_; + backup_set_desc_ == other.backup_set_desc_ && ls_id_ == other.ls_id_ && + turn_id_ == other.turn_id_ && retry_id_ == other.retry_id_ && dest_id_ == other.dest_id_; } /* ObLSBackupDagInitParam */ @@ -312,49 +330,23 @@ ObBackupDagNet::~ObBackupDagNet() /* ObLSBackupMetaDagNet */ ObLSBackupMetaDagNet::ObLSBackupMetaDagNet() - : ObBackupDagNet(ObBackupDagNetSubType::LOG_STREAM_BACKUP_META_DAG_NET), is_inited_(false), param_(), report_ctx_(), start_scn_() -{} + : ObLSBackupDataDagNet() +{ + sub_type_ = ObBackupDagNetSubType::LOG_STREAM_BACKUP_META_DAG_NET; +} ObLSBackupMetaDagNet::~ObLSBackupMetaDagNet() {} -int ObLSBackupMetaDagNet::init_by_param(const share::ObIDagInitParam *param) -{ - int ret = OB_SUCCESS; - ObLSBackupDagNetInitParam init_param; - if (IS_INIT) { - ret = OB_INIT_TWICE; - LOG_WARN("dag net init twice", K(ret)); - } else if (OB_ISNULL(param) || !param->is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), KP(param)); - } else if (OB_FAIL(init_param.assign(*(static_cast(param))))) { - LOG_WARN("failed to assign param", K(ret)); - } else if (OB_FAIL(this->set_dag_id(init_param.job_desc_.trace_id_))) { - LOG_WARN("failed to set dag id", K(ret), K(init_param)); - } else if (OB_FAIL(param_.backup_dest_.deep_copy(init_param.backup_dest_))) { - LOG_WARN("failed to deep copy backup dest", K(ret), K(init_param)); - } else { - param_.job_desc_ = init_param.job_desc_; - param_.tenant_id_ = init_param.tenant_id_; - param_.backup_set_desc_ = init_param.backup_set_desc_; - param_.ls_id_ = init_param.ls_id_; - param_.turn_id_ = init_param.turn_id_; - param_.retry_id_ = init_param.retry_id_; - param_.dest_id_ = init_param.dest_id_; - report_ctx_ = init_param.report_ctx_; - start_scn_ = init_param.start_scn_; - is_inited_ = true; - } - return ret; -} - int ObLSBackupMetaDagNet::start_running() { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + ObLSBackupDagInitParam init_param; ObLSBackupMetaDag *backup_meta_dag = NULL; + ObLSBackupPrepareDag *prepare_dag = NULL; + ObLSBackupFinishDag *finish_dag = NULL; ObTenantDagScheduler *dag_scheduler = NULL; if (IS_NOT_INIT) { ret = OB_NOT_INIT; @@ -364,14 +356,41 @@ int ObLSBackupMetaDagNet::start_running() } else if (OB_ISNULL(dag_scheduler = MTL(ObTenantDagScheduler *))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("dag scheduler must not be NULL", K(ret)); + } else if (param_.convert_to(init_param)) { + LOG_WARN("failed to convert to init param", K(ret)); + } else if (OB_FALSE_IT(init_param.backup_stage_ = start_stage_)) { + } else if (OB_FAIL(inner_init_before_run_())) { + LOG_WARN("failed to inner init before run", K(ret)); } else if (OB_FAIL(dag_scheduler->alloc_dag(backup_meta_dag))) { LOG_WARN("failed to alloc backup meta dag", K(ret)); - } else if (OB_FAIL(backup_meta_dag->init(start_scn_, param_, report_ctx_))) { + } else if (OB_FAIL(backup_meta_dag->init(param_.start_scn_, init_param, report_ctx_))) { LOG_WARN("failed to init backup meta dag", K(ret), K_(param)); } else if (OB_FAIL(backup_meta_dag->create_first_task())) { LOG_WARN("failed to create first task for child dag", K(ret), KPC(backup_meta_dag)); } else if (OB_FAIL(add_dag_into_dag_net(*backup_meta_dag))) { LOG_WARN("failed to add dag into dag net", K(ret), KPC(backup_meta_dag)); + } else if (OB_FAIL(dag_scheduler->alloc_dag(prepare_dag))) { + LOG_WARN("failed to alloc dag", K(ret)); + } else if (OB_FAIL(prepare_dag->init(init_param, + backup_data_type_, + report_ctx_, + ls_backup_ctx_, + *provider_, + task_mgr_, + *index_kv_cache_))) { + LOG_WARN("failed to init backup dag", K(ret), K(init_param)); + } else if (OB_FAIL(prepare_dag->create_first_task())) { + LOG_WARN("failed to create first task", K(ret)); + } else if (OB_FAIL(backup_meta_dag->add_child(*prepare_dag))) { + LOG_WARN("failed to add dag into dag_net", K(ret), KPC(prepare_dag)); + } else if (OB_FAIL(dag_scheduler->alloc_dag(finish_dag))) { + LOG_WARN("failed to create dag", K(ret)); + } else if (OB_FAIL(finish_dag->init(init_param, report_ctx_, ls_backup_ctx_, *index_kv_cache_))) { + LOG_WARN("failed to init finish dag", K(ret), K(init_param)); + } else if (OB_FAIL(finish_dag->create_first_task())) { + LOG_WARN("failed to create first task", K(ret)); + } else if (OB_FAIL(prepare_dag->add_child(*finish_dag))) { + LOG_WARN("failed to add child", K(ret), KPC(prepare_dag), KPC(finish_dag)); } else { #ifdef ERRSIM ret = OB_E(EventTable::EN_ADD_BACKUP_META_DAG_FAILED) OB_SUCCESS; @@ -379,18 +398,42 @@ int ObLSBackupMetaDagNet::start_running() SERVER_EVENT_SYNC_ADD("backup_errsim", "add_backup_meta_dag_failed"); } #endif - if (FAILEDx(dag_scheduler->add_dag(backup_meta_dag))) { - if (OB_EAGAIN != ret && OB_SIZE_OVERFLOW != ret) { - LOG_WARN("failed to add dag", K(ret), KPC(backup_meta_dag)); + if (FAILEDx(dag_scheduler->add_dag(finish_dag))) { + LOG_WARN("failed to add dag", K(ret), KP(finish_dag)); + } else if (OB_FAIL(dag_scheduler->add_dag(prepare_dag))) { + LOG_WARN("failed to add dag", K(ret), KP(prepare_dag)); + if (OB_TMP_FAIL(dag_scheduler->cancel_dag(finish_dag, prepare_dag))) { + LOG_ERROR("failed to cancel backup dag", K(tmp_ret), KP(dag_scheduler), KP(finish_dag)); } else { - LOG_WARN("may exist same dag", K(ret), KPC(backup_meta_dag)); + finish_dag = nullptr; + } + } else if (OB_FAIL(dag_scheduler->add_dag(backup_meta_dag))) { + LOG_WARN("failed to add dag", K(ret), KP(prepare_dag)); + if (OB_TMP_FAIL(dag_scheduler->cancel_dag(finish_dag, prepare_dag))) { + LOG_ERROR("failed to cancel backup dag", K(tmp_ret), KP(dag_scheduler), KP(finish_dag)); + } else { + finish_dag = nullptr; + } + if (OB_TMP_FAIL(dag_scheduler->cancel_dag(prepare_dag, backup_meta_dag))) { + LOG_ERROR("failed to cancel backup dag", K(tmp_ret), KP(dag_scheduler), KP(prepare_dag)); + } else { + prepare_dag = nullptr; } } } - if (OB_FAIL(ret) && OB_NOT_NULL(dag_scheduler) && OB_NOT_NULL(backup_meta_dag)) { dag_scheduler->free_dag(*backup_meta_dag); } + if (OB_FAIL(ret) && OB_NOT_NULL(dag_scheduler) && OB_NOT_NULL(prepare_dag)) { + dag_scheduler->free_dag(*prepare_dag); + } + if (OB_FAIL(ret) && OB_NOT_NULL(dag_scheduler) && OB_NOT_NULL(finish_dag)) { + dag_scheduler->free_dag(*finish_dag); + } + + if (OB_FAIL(ret)) { + REPORT_TASK_RESULT(this->get_dag_id(), ret); + } return ret; } @@ -433,20 +476,6 @@ bool ObLSBackupMetaDagNet::operator==(const share::ObIDagNet &other) const return bret; } -bool ObLSBackupMetaDagNet::is_valid() const -{ - return param_.is_valid() && start_scn_.is_valid(); -} - -int64_t ObLSBackupMetaDagNet::hash() const -{ - int64_t hash_value = 0; - const int64_t type = ObBackupDagNetSubType::LOG_STREAM_BACKUP_META_DAG_NET; - hash_value = common::murmurhash(&type, sizeof(type), hash_value); - hash_value = common::murmurhash(¶m_, sizeof(param_), hash_value); - return hash_value; -} - int ObLSBackupMetaDagNet::fill_comment(char *buf, const int64_t buf_len) const { int ret = OB_SUCCESS; @@ -634,6 +663,10 @@ int ObLSBackupDataDagNet::start_running() if (OB_FAIL(ret) && OB_NOT_NULL(scheduler) && OB_NOT_NULL(finish_dag)) { scheduler->free_dag(*finish_dag); } + + if (OB_FAIL(ret)) { + REPORT_TASK_RESULT(this->get_dag_id(), ret); + } return ret; } @@ -829,6 +862,10 @@ int ObBackupBuildTenantIndexDagNet::start_running() if (OB_FAIL(ret) && OB_NOT_NULL(dag_scheduler) && OB_NOT_NULL(rebuild_dag)) { dag_scheduler->free_dag(*rebuild_dag); } + + if (OB_FAIL(ret)) { + REPORT_TASK_RESULT(this->get_dag_id(), ret); + } return ret; } @@ -986,6 +1023,10 @@ int ObLSBackupComplementLogDagNet::start_running() if (OB_FAIL(ret) && OB_NOT_NULL(dag_scheduler) && OB_NOT_NULL(complement_dag)) { dag_scheduler->free_dag(*complement_dag); } + + if (OB_FAIL(ret)) { + REPORT_TASK_RESULT(this->get_dag_id(), ret); + } return ret; } @@ -1053,22 +1094,10 @@ int ObLSBackupComplementLogDagNet::fill_dag_net_key(char *buf, const int64_t buf return ret; } -/* ObBackupDag */ - -ObBackupDag::ObBackupDag(const ObBackupDagSubType &sub_type) - : ObIDag(ObDagType::DAG_TYPE_BACKUP), - sub_type_(sub_type) -{ -} - -ObBackupDag::~ObBackupDag() -{ -} - /* ObLSBackupMetaDag */ ObLSBackupMetaDag::ObLSBackupMetaDag() - : ObBackupDag(ObBackupDagSubType::LOG_STREAM_BACKUP_META_DAG), is_inited_(false), start_scn_(), param_(), report_ctx_() + : share::ObIDag(ObDagType::DAG_TYPE_BACKUP_META), is_inited_(false), start_scn_(), param_(), report_ctx_() {} ObLSBackupMetaDag::~ObLSBackupMetaDag() @@ -1121,25 +1150,21 @@ bool ObLSBackupMetaDag::operator==(const ObIDag &other) const } else if (get_type() != other.get_type()) { bret = false; } else { - const ObBackupDag &backup_dag = static_cast(other); - if (backup_dag.get_sub_type() != get_sub_type()) { - bret = false; - } else { - const ObLSBackupMetaDag &other_dag = static_cast(other); - bret = param_ == other_dag.param_; - } + const ObLSBackupMetaDag &other_dag = static_cast(other); + bret = param_ == other_dag.param_; } + return bret; } -int ObLSBackupMetaDag::fill_comment(char *buf, const int64_t buf_len) const +int ObLSBackupMetaDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; - if (OB_ISNULL(buf) || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), KP(buf), K(buf_len)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, "LS Backup Meta Dag: ls_id=%s", to_cstring(param_.ls_id_)))) { - LOG_WARN("failed to fill comment", K(ret), K_(param)); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls backup meta dag do not init", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), param_.ls_id_.id()))) { + LOG_WARN("failed to add dag warning info param", K(ret)); } return ret; } @@ -1167,7 +1192,7 @@ lib::Worker::CompatMode ObLSBackupMetaDag::get_compat_mode() const /* ObLSBackupPrepareDag */ ObLSBackupPrepareDag::ObLSBackupPrepareDag() - : ObBackupDag(ObBackupDagSubType::LOG_STREAM_BACKUP_PREPARE_DAG), + : share::ObIDag(ObDagType::DAG_TYPE_BACKUP_PREPARE), is_inited_(false), param_(), backup_data_type_(), @@ -1240,33 +1265,22 @@ bool ObLSBackupPrepareDag::operator==(const ObIDag &other) const } else if (get_type() != other.get_type()) { bret = false; } else { - const ObBackupDag &backup_dag = static_cast(other); - if (backup_dag.get_sub_type() != get_sub_type()) { - bret = false; - } else { - const ObLSBackupPrepareDag &other_dag = static_cast(other); - bret = param_ == other_dag.param_ && backup_data_type_ == other_dag.backup_data_type_; - } + const ObLSBackupPrepareDag &other_dag = static_cast(other); + bret = param_ == other_dag.param_ && backup_data_type_ == other_dag.backup_data_type_; } return bret; } -int ObLSBackupPrepareDag::fill_comment(char *buf, const int64_t buf_len) const +int ObLSBackupPrepareDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; - if (OB_ISNULL(buf) || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), KP(buf), K(buf_len)); - } else if (OB_FAIL(databuff_printf(buf, - buf_len, - "[BACKUP_PREPAER_DAG]: tenant_id=%lu, backup_set_id=%ld, ls_id=%ld, " - "turn_id=%ld, retry_id=%ld", - param_.tenant_id_, - param_.backup_set_desc_.backup_set_id_, - param_.ls_id_.id(), - param_.turn_id_, - param_.retry_id_))) { - LOG_WARN("failed to fill comment", K(ret), K_(param)); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls backup prepare dag do not init", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(param_.tenant_id_), param_.backup_set_desc_.backup_set_id_, + param_.ls_id_.id(), param_.turn_id_, param_.retry_id_))) { + LOG_WARN("failed to add dag warning info param", K(ret)); } return ret; } @@ -1283,7 +1297,7 @@ int ObLSBackupPrepareDag::fill_dag_key(char *buf, const int64_t buf_len) const int64_t ObLSBackupPrepareDag::hash() const { int64_t hash_value = 0; - const int64_t type = ObBackupDagSubType::LOG_STREAM_BACKUP_PREPARE_DAG; + const int64_t type = get_type(); hash_value = common::murmurhash(&type, sizeof(type), hash_value); hash_value = common::murmurhash(¶m_, sizeof(param_), hash_value); hash_value = common::murmurhash(&backup_data_type_, sizeof(backup_data_type_), hash_value); @@ -1332,7 +1346,7 @@ int ObLSBackupPrepareDag::get_concurrency_count_(const share::ObBackupDataType & /* ObLSBackupFinishDag */ ObLSBackupFinishDag::ObLSBackupFinishDag() - : ObBackupDag(ObBackupDagSubType::LOG_STREAM_BACKUP_FINISH_DAG), is_inited_(false), report_ctx_(), ls_backup_ctx_(NULL), index_kv_cache_(NULL) + : share::ObIDag(ObDagType::DAG_TYPE_BACKUP_FINISH), is_inited_(false), report_ctx_(), ls_backup_ctx_(NULL), index_kv_cache_(NULL) {} ObLSBackupFinishDag::~ObLSBackupFinishDag() @@ -1388,30 +1402,22 @@ bool ObLSBackupFinishDag::operator==(const ObIDag &other) const } else if (get_type() != other.get_type()) { bret = false; } else { - const ObBackupDag &backup_dag = static_cast(other); - if (backup_dag.get_sub_type() != get_sub_type()) { - bret = false; - } else { - const ObLSBackupFinishDag &other_dag = static_cast(other); - bret = param_ == other_dag.param_; - } + const ObLSBackupFinishDag &other_dag = static_cast(other); + bret = param_ == other_dag.param_; } return bret; } -int ObLSBackupFinishDag::fill_comment(char *buf, const int64_t buf_len) const +int ObLSBackupFinishDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; - if (OB_ISNULL(buf) || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), KP(buf), K(buf_len)); - } else if (OB_FAIL(databuff_printf(buf, - buf_len, - "[BACKUP_FINISH_DAG]: tenant_id=%lu, backup_set_id=%ld, ls_id=%ld", - param_.tenant_id_, - param_.backup_set_desc_.backup_set_id_, - param_.ls_id_.id()))) { - LOG_WARN("failed to fill comment", K(ret), K_(param)); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls backup finish dag do not init", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(param_.tenant_id_), + param_.backup_set_desc_.backup_set_id_, param_.ls_id_.id()))) { + LOG_WARN("failed to add dag warning info param", K(ret)); } return ret; } @@ -1428,7 +1434,7 @@ int ObLSBackupFinishDag::fill_dag_key(char *buf, const int64_t buf_len) const int64_t ObLSBackupFinishDag::hash() const { int64_t hash_value = 0; - const int64_t type = ObBackupDagSubType::LOG_STREAM_BACKUP_FINISH_DAG; + const int64_t type = get_type(); hash_value = common::murmurhash(&type, sizeof(type), hash_value); hash_value = common::murmurhash(¶m_, sizeof(param_), hash_value); return hash_value; @@ -1446,8 +1452,22 @@ lib::Worker::CompatMode ObLSBackupFinishDag::get_compat_mode() const /* ObLSBackupDataDag */ -ObLSBackupDataDag::ObLSBackupDataDag(const ObBackupDagSubType &sub_type) - : ObBackupDag(sub_type), +ObLSBackupDataDag::ObLSBackupDataDag() + : share::ObIDag(ObDagType::DAG_TYPE_BACKUP_DATA), + is_inited_(false), + task_id_(0), + param_(), + backup_data_type_(), + ls_backup_ctx_(NULL), + provider_(NULL), + task_mgr_(NULL), + index_kv_cache_(NULL), + report_ctx_(), + index_rebuild_dag_(NULL) +{} + +ObLSBackupDataDag::ObLSBackupDataDag(const share::ObDagType::ObDagTypeEnum type) + : share::ObIDag(type), is_inited_(false), task_id_(0), param_(), @@ -1457,7 +1477,6 @@ ObLSBackupDataDag::ObLSBackupDataDag(const ObBackupDagSubType &sub_type) task_mgr_(NULL), index_kv_cache_(NULL), report_ctx_(), - bandwidth_throttle_(), index_rebuild_dag_(NULL) {} @@ -1476,8 +1495,6 @@ int ObLSBackupDataDag::init(const int64_t task_id, const ObLSBackupDagInitParam } else if (!param.is_valid() || !report_ctx.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(param), K(report_ctx)); - } else if (OB_FAIL(bandwidth_throttle_.init(10))) { - LOG_WARN("failed to init bandwidth throttle", K(ret)); } else if (OB_FAIL(param_.assign(param))) { LOG_WARN("failed to assign param", K(ret), K(param)); } else { @@ -1513,7 +1530,6 @@ int ObLSBackupDataDag::create_first_task() backup_items_, param, report_ctx_, - bandwidth_throttle_, *ls_backup_ctx_, *provider_, *task_mgr_, @@ -1536,13 +1552,8 @@ bool ObLSBackupDataDag::operator==(const ObIDag &other) const } else if (get_type() != other.get_type()) { bret = false; } else { - const ObBackupDag &backup_dag = static_cast(other); - if (backup_dag.get_sub_type() != get_sub_type()) { - bret = false; - } else { - const ObLSBackupDataDag &other_dag = static_cast(other); - bret = param_ == other_dag.param_ && task_id_ == other_dag.task_id_ && backup_data_type_ == other_dag.backup_data_type_; - } + const ObLSBackupDataDag &other_dag = static_cast(other); + bret = param_ == other_dag.param_ && task_id_ == other_dag.task_id_ && backup_data_type_ == other_dag.backup_data_type_; } return bret; } @@ -1553,25 +1564,17 @@ int64_t ObLSBackupDataDag::hash() const return common::murmurhash(&ptr, sizeof(ptr), 0); } -int ObLSBackupDataDag::fill_comment(char *buf, const int64_t buf_len) const +int ObLSBackupDataDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; - if (OB_ISNULL(buf) || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), KP(buf), K(buf_len)); - } else if (OB_FAIL(databuff_printf(buf, - buf_len, - "[BACKUP_DATA_DAG]: tenant_id=%lu, backup_set_id=%ld, " - "backup_data_type=%u, ls_id=%ld, turn_id=%ld, " - "retry_id=%ld, task_id=%ld", - param_.tenant_id_, - param_.backup_set_desc_.backup_set_id_, - backup_data_type_.type_, - param_.ls_id_.id(), - param_.turn_id_, - param_.retry_id_, - task_id_))) { - LOG_WARN("failed to fill comment", K(ret), K_(param)); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls backup data dag do not init", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(param_.tenant_id_), param_.backup_set_desc_.backup_set_id_, + static_cast(backup_data_type_.type_), param_.ls_id_.id(), + param_.turn_id_, param_.retry_id_, task_id_))) { + LOG_WARN("failed to add dag warning info param", K(ret)); } return ret; } @@ -1593,7 +1596,7 @@ lib::Worker::CompatMode ObLSBackupDataDag::get_compat_mode() const /* ObPrefetchBackupInfoDag */ ObPrefetchBackupInfoDag::ObPrefetchBackupInfoDag() - : ObLSBackupDataDag(ObBackupDagSubType::LOG_STREAM_BACKUP_PREFETCH_DAG) + : ObLSBackupDataDag(ObDagType::DAG_TYPE_PREFETCH_BACKUP_INFO) {} ObPrefetchBackupInfoDag::~ObPrefetchBackupInfoDag() @@ -1607,13 +1610,8 @@ bool ObPrefetchBackupInfoDag::operator==(const ObIDag &other) const } else if (get_type() != other.get_type()) { bret = false; } else { - const ObBackupDag &backup_dag = static_cast(other); - if (backup_dag.get_sub_type() != get_sub_type()) { - bret = false; - } else { - const ObPrefetchBackupInfoDag &other_dag = static_cast(other); - bret = param_ == other_dag.param_ && task_id_ == other_dag.task_id_ && backup_data_type_ == other_dag.backup_data_type_; - } + const ObPrefetchBackupInfoDag &other_dag = static_cast(other); + bret = param_ == other_dag.param_ && task_id_ == other_dag.task_id_ && backup_data_type_ == other_dag.backup_data_type_; } return bret; } @@ -1650,29 +1648,6 @@ int ObPrefetchBackupInfoDag::create_first_task() return ret; } -int ObPrefetchBackupInfoDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(buf) || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), KP(buf), K(buf_len)); - } else if (OB_FAIL(databuff_printf(buf, - buf_len, - "[PREFETCH_BACKUP_INFO_DAG]: tenant_id=%lu, backup_set_id=%ld, " - "backup_data_type=%u, ls_id=%ld, turn_id=%ld, " - "retry_id=%ld, task_id=%ld", - param_.tenant_id_, - param_.backup_set_desc_.backup_set_id_, - backup_data_type_.type_, - param_.ls_id_.id(), - param_.turn_id_, - param_.retry_id_, - task_id_))) { - LOG_WARN("failed to fill comment", K(ret), K_(param)); - } - return ret; -} - int ObPrefetchBackupInfoDag::fill_dag_key(char *buf, const int64_t buf_len) const { int ret = OB_SUCCESS; @@ -1685,7 +1660,7 @@ int ObPrefetchBackupInfoDag::fill_dag_key(char *buf, const int64_t buf_len) cons /* ObLSBackupIndexRebuildDag */ ObLSBackupIndexRebuildDag::ObLSBackupIndexRebuildDag() - : ObBackupDag(ObBackupDagSubType::LOG_STREAM_BACKUP_BUILD_INDEX_DAG), + : share::ObIDag(ObDagType::DAG_TYPE_BACKUP_INDEX_REBUILD), is_inited_(false), report_ctx_(), param_(), @@ -1694,8 +1669,7 @@ ObLSBackupIndexRebuildDag::ObLSBackupIndexRebuildDag() ls_backup_ctx_(NULL), task_mgr_(NULL), provider_(NULL), - index_kv_cache_(NULL), - bandwidth_throttle_() + index_kv_cache_(NULL) {} ObLSBackupIndexRebuildDag::~ObLSBackupIndexRebuildDag() @@ -1710,8 +1684,6 @@ int ObLSBackupIndexRebuildDag::init(const ObLSBackupDagInitParam ¶m, if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("task init twice", K(ret)); - } else if (OB_FAIL(bandwidth_throttle_.init(10))) { - LOG_WARN("failed to init bandwidth throttle", K(ret)); } else if (OB_FAIL(param_.assign(param))) { LOG_WARN("failed to assign param", K(ret), K(param)); } else { @@ -1745,7 +1717,6 @@ int ObLSBackupIndexRebuildDag::create_first_task() provider_, task_mgr_, index_kv_cache_, - bandwidth_throttle_, report_ctx_))) { LOG_WARN("failed to init task", K(ret), K(param), K_(index_level)); } else if (OB_FAIL(add_task(*task))) { @@ -1756,24 +1727,17 @@ int ObLSBackupIndexRebuildDag::create_first_task() return ret; } -int ObLSBackupIndexRebuildDag::fill_comment(char *buf, const int64_t buf_len) const +int ObLSBackupIndexRebuildDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; - if (OB_ISNULL(buf) || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), KP(buf), K(buf_len)); - } else if (OB_FAIL(databuff_printf(buf, - buf_len, - "[BACKUP_INDEX_REBUILD_DAG]: tenant_id=%lu, backup_set_id=%ld, " - "backup_data_type=%u, ls_id=%ld, " - "turn_id=%ld, retry_id=%ld", - param_.tenant_id_, - param_.backup_set_desc_.backup_set_id_, - backup_data_type_.type_, - param_.ls_id_.id(), - param_.turn_id_, - param_.retry_id_))) { - LOG_WARN("failed to fill comment", K(ret), K_(param)); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls backup index rebuild dag do not init", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(param_.tenant_id_), param_.backup_set_desc_.backup_set_id_, + static_cast(backup_data_type_.type_), param_.ls_id_.id(), + param_.turn_id_, param_.retry_id_))) { + LOG_WARN("failed to add dag warning info param", K(ret)); } return ret; } @@ -1795,13 +1759,8 @@ bool ObLSBackupIndexRebuildDag::operator==(const ObIDag &other) const } else if (get_type() != other.get_type()) { bret = false; } else { - const ObBackupDag &backup_dag = static_cast(other); - if (backup_dag.get_sub_type() != get_sub_type()) { - bret = false; - } else { - const ObLSBackupIndexRebuildDag &dag = static_cast(other); - bret = dag.param_ == param_ && dag.index_level_ == index_level_ && dag.backup_data_type_ == backup_data_type_; - } + const ObLSBackupIndexRebuildDag &dag = static_cast(other); + bret = dag.param_ == param_ && dag.index_level_ == index_level_ && dag.backup_data_type_ == backup_data_type_; } return bret; } @@ -1844,7 +1803,7 @@ int ObLSBackupIndexRebuildDag::get_file_id_list_(common::ObIArray &file /* ObLSBackupComplementLogDag */ ObLSBackupComplementLogDag::ObLSBackupComplementLogDag() - : ObBackupDag(ObBackupDagSubType::LOG_STREAM_BACKUP_COMPLEMENT_LOG_DAG), + : share::ObIDag(ObDagType::DAG_TYPE_BACKUP_COMPLEMENT_LOG), is_inited_(false), job_desc_(), backup_dest_(), @@ -1918,20 +1877,17 @@ int ObLSBackupComplementLogDag::create_first_task() return ret; } -int ObLSBackupComplementLogDag::fill_comment(char *buf, const int64_t buf_len) const +int ObLSBackupComplementLogDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; - if (OB_ISNULL(buf) || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), KP(buf), K(buf_len)); - } else if (OB_FAIL(databuff_printf(buf, - buf_len, - "[BACKUP_COMPL_LOG_DAG]: tenant_id=%lu, backup_set_id=%ld, ls_id=%ld", - tenant_id_, - backup_set_desc_.backup_set_id_, - ls_id_.id()))) { - LOG_WARN("failed to fill comment", K(ret), K_(tenant_id), K_(backup_set_desc), K_(ls_id)); - }; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls backup complement log dag do not init", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(tenant_id_), backup_set_desc_.backup_set_id_, + ls_id_.id()))){ + LOG_WARN("failed to add dag warning info param", K(ret)); + } return ret; } @@ -1952,15 +1908,10 @@ bool ObLSBackupComplementLogDag::operator==(const ObIDag &other) const } else if (get_type() != other.get_type()) { bret = false; } else { - const ObBackupDag &backup_dag = static_cast(other); - if (backup_dag.get_sub_type() != get_sub_type()) { - bret = false; - } else { const ObLSBackupComplementLogDag &other_dag = static_cast(other); bret = job_desc_ == other_dag.job_desc_ && backup_dest_ == other_dag.backup_dest_ && tenant_id_ == other_dag.tenant_id_ && dest_id_ == other_dag.dest_id_ && backup_set_desc_ == other_dag.backup_set_desc_ && ls_id_ == other_dag.ls_id_; - } } return bret; } @@ -1968,7 +1919,7 @@ bool ObLSBackupComplementLogDag::operator==(const ObIDag &other) const int64_t ObLSBackupComplementLogDag::hash() const { int64_t hash_value = 0; - const int64_t type = ObBackupDagSubType::LOG_STREAM_BACKUP_COMPLEMENT_LOG_DAG; + const int64_t type = get_type(); hash_value = common::murmurhash(&job_desc_, sizeof(job_desc_), hash_value); hash_value = common::murmurhash(&tenant_id_, sizeof(tenant_id_), hash_value); hash_value = common::murmurhash(&backup_set_desc_, sizeof(backup_set_desc_), hash_value); @@ -1993,7 +1944,8 @@ ObPrefetchBackupInfoTask::ObPrefetchBackupInfoTask() provider_(NULL), task_mgr_(NULL), index_kv_cache_(NULL), - macro_index_store_(), + macro_index_store_for_inc_(), + macro_index_store_for_turn_(), index_rebuild_dag_(NULL) {} @@ -2021,36 +1973,12 @@ int ObPrefetchBackupInfoTask::init(const ObLSBackupDagInitParam ¶m, const sh task_mgr_ = &task_mgr; index_kv_cache_ = &index_kv_cache; index_rebuild_dag_ = index_rebuild_dag; - is_inited_ = true; - if (param.backup_set_desc_.backup_type_.is_inc_backup() && backup_data_type.is_major_backup()) { - ObBackupSetDesc prev_backup_set_desc; - const ObLSID ls_id(0); - ObBackupRestoreMode mode = BACKUP_MODE; - ObBackupIndexLevel index_level = BACKUP_INDEX_LEVEL_TENANT; - ObBackupIndexStoreParam index_store_param; - index_store_param.index_level_ = index_level; - index_store_param.tenant_id_ = param.tenant_id_; - index_store_param.backup_set_id_ = param.backup_set_desc_.backup_set_id_; - index_store_param.ls_id_ = param.ls_id_; - index_store_param.is_tenant_level_ = true; - index_store_param.backup_data_type_ = backup_data_type; - index_store_param.turn_id_ = param.turn_id_; - int64_t retry_id = 0; - if (OB_FAIL(get_prev_backup_set_desc_(param.tenant_id_, param.dest_id_, param.backup_set_desc_, prev_backup_set_desc))) { - LOG_WARN("failed to get prev backup set desc", K(ret), K(param)); - } else if (OB_FAIL(get_tenant_macro_index_retry_id_(param.backup_dest_, - prev_backup_set_desc, backup_data_type, param.turn_id_, retry_id))) { - LOG_WARN("failed to get retry id", K(ret), K(param), K(prev_backup_set_desc), K(backup_data_type)); - } else if (FALSE_IT(index_store_param.retry_id_ = retry_id)) { - // assign - } else if (OB_FAIL(macro_index_store_.init(mode, - index_store_param, - param.backup_dest_, - prev_backup_set_desc, - index_kv_cache, - *report_ctx.sql_proxy_))) { - LOG_WARN("failed to init macro index store", K(ret), K(param), K(prev_backup_set_desc), K(backup_data_type)); - } + if (OB_FAIL(inner_init_macro_index_store_for_inc_(param, backup_data_type, report_ctx))) { + LOG_WARN("failed to inner init macro index store for inc", K(ret)); + } else if (OB_FAIL(inner_init_macro_index_store_for_turn_(param, backup_data_type, report_ctx))) { + LOG_WARN("failed to inner init macro index store for turn", K(ret)); + } else { + is_inited_ = true; } } return ret; @@ -2095,23 +2023,91 @@ int ObPrefetchBackupInfoTask::process() need_report_error = is_set; } if (OB_NOT_NULL(ls_backup_ctx_) && need_report_error) { - if (OB_SUCCESS != (tmp_ret = ObBackupUtils::report_task_result(param_.job_desc_.job_id_, - param_.job_desc_.task_id_, - param_.tenant_id_, - param_.ls_id_, - param_.turn_id_, - param_.retry_id_, - param_.job_desc_.trace_id_, - ls_backup_ctx_->get_result_code(), - report_ctx_))) { - LOG_WARN("failed to report task result", K(tmp_ret)); - } else { - FLOG_INFO("report backup prefetch task", K_(param)); + REPORT_TASK_RESULT(this->get_dag()->get_dag_id(), ls_backup_ctx_->get_result_code()); + } + return ret; +} + +int ObPrefetchBackupInfoTask::setup_macro_index_store_(const ObLSBackupDagInitParam ¶m, const share::ObBackupDataType &backup_data_type, + const ObBackupSetDesc &backup_set_desc, const ObBackupReportCtx &report_ctx, ObBackupIndexStoreParam &index_store_param, + ObBackupMacroBlockIndexStore &index_store) +{ + int ret = OB_SUCCESS; + if (!param.is_valid() || !backup_data_type.is_valid() || !backup_set_desc.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(param), K(backup_data_type), K(backup_set_desc)); + } else { + ObBackupRestoreMode mode = BACKUP_MODE; + ObBackupIndexLevel index_level = BACKUP_INDEX_LEVEL_TENANT; + index_store_param.index_level_ = index_level; + index_store_param.tenant_id_ = param.tenant_id_; + index_store_param.backup_set_id_ = param.backup_set_desc_.backup_set_id_; + index_store_param.ls_id_ = param.ls_id_; + index_store_param.is_tenant_level_ = true; + index_store_param.backup_data_type_ = backup_data_type; + if (OB_FAIL(index_store.init(mode, index_store_param, param.backup_dest_, + backup_set_desc, *index_kv_cache_, *report_ctx.sql_proxy_))) { + LOG_WARN("failed to init macro index store", K(ret), K(param), K(index_store_param), K(backup_set_desc), K(backup_data_type)); } } return ret; } +int ObPrefetchBackupInfoTask::inner_init_macro_index_store_for_inc_(const ObLSBackupDagInitParam ¶m, + const share::ObBackupDataType &backup_data_type, const ObBackupReportCtx &report_ctx) +{ + int ret = OB_SUCCESS; + if (param.backup_set_desc_.backup_type_.is_inc_backup() && backup_data_type.is_major_backup()) { + share::ObBackupSetFileDesc prev_backup_set_info; + ObBackupSetDesc prev_backup_set_desc; + ObBackupIndexStoreParam index_store_param; + if (OB_FAIL(get_prev_backup_set_desc_(param.tenant_id_, param.dest_id_, param.backup_set_desc_, prev_backup_set_info))) { + LOG_WARN("failed to get prev backup set desc", K(ret), K(param)); + } else if (OB_FALSE_IT(prev_backup_set_desc.backup_set_id_ = prev_backup_set_info.backup_set_id_)) { + } else if (OB_FALSE_IT(prev_backup_set_desc.backup_type_ = prev_backup_set_info.backup_type_)) { + } else if (OB_FALSE_IT(index_store_param.turn_id_ = prev_backup_set_info.major_turn_id_)) { + } else if (OB_FAIL(get_tenant_macro_index_retry_id_(param.backup_dest_, + prev_backup_set_desc, backup_data_type, prev_backup_set_info.major_turn_id_, index_store_param.retry_id_))) { + LOG_WARN("failed to get retry id", K(ret), K(param), K(prev_backup_set_desc), K(backup_data_type)); + } else if (OB_FAIL(setup_macro_index_store_(param, backup_data_type, prev_backup_set_desc, report_ctx, index_store_param, macro_index_store_for_inc_))) { + LOG_WARN("failed to setup macro index store", K(ret)); + } else { + LOG_INFO("inner init macro index store for incremental backup", K(prev_backup_set_info), K(index_store_param), K(param)); + } + } + return ret; +} + +int ObPrefetchBackupInfoTask::inner_init_macro_index_store_for_turn_(const ObLSBackupDagInitParam ¶m, + const share::ObBackupDataType &backup_data_type, const ObBackupReportCtx &report_ctx) +{ + int ret = OB_SUCCESS; + if (backup_data_type.is_major_backup()) { + const ObBackupSetDesc &backup_set_desc = param.backup_set_desc_; + ObBackupIndexStoreParam index_store_param; + const int64_t cur_turn_id = param.turn_id_; + index_store_param.turn_id_ = get_prev_turn_id_(cur_turn_id); + if (0 == index_store_param.turn_id_) { + // no need init + } else if (OB_FAIL(get_tenant_macro_index_retry_id_(param.backup_dest_, + backup_set_desc, backup_data_type, index_store_param.turn_id_, index_store_param.retry_id_))) { + LOG_WARN("failed to get retry id", K(ret), K(param), K(backup_data_type)); + } else if (OB_FAIL(setup_macro_index_store_(param, backup_data_type, backup_set_desc, report_ctx, index_store_param, macro_index_store_for_turn_))) { + LOG_WARN("failed to setup macro index store", K(ret)); + } else { + LOG_INFO("inner init macro index store for change turn", K(cur_turn_id), K(index_store_param), K(param)); + } + } + return ret; +} + +int64_t ObPrefetchBackupInfoTask::get_prev_turn_id_(const int64_t cur_turn_id) +{ + const int64_t prev_turn_id = cur_turn_id - 1; + LOG_INFO("get prev turn id", K(cur_turn_id), K(prev_turn_id)); + return prev_turn_id; +} + int ObPrefetchBackupInfoTask::inner_process_() { int ret = OB_SUCCESS; @@ -2207,17 +2203,17 @@ int ObPrefetchBackupInfoTask::check_backup_items_valid_(const common::ObIArray &backup_items, const ObLSBackupDataParam ¶m, - const ObBackupReportCtx &report_ctx, common::ObInOutBandwidthThrottle &bandwidth_throttle, - ObLSBackupCtx &ls_backup_ctx, ObIBackupTabletProvider &provider, ObBackupMacroBlockTaskMgr &task_mgr, - ObBackupIndexKVCache &kv_cache, share::ObIDag *index_rebuild_dag) + const ObBackupReportCtx &report_ctx, ObLSBackupCtx &ls_backup_ctx, ObIBackupTabletProvider &provider, + ObBackupMacroBlockTaskMgr &task_mgr, ObBackupIndexKVCache &kv_cache, share::ObIDag *index_rebuild_dag) { int ret = OB_SUCCESS; if (IS_INIT) { @@ -2474,7 +2505,7 @@ int ObLSBackupDataTask::init(const int64_t task_id, const share::ObBackupDataTyp LOG_WARN("get invalid args", K(ret), K(task_id), K(param), K(report_ctx)); } else if (OB_FAIL(backup_items_.assign(backup_items))) { LOG_WARN("failed to assign", K(ret)); - } else if (OB_FAIL(backup_data_ctx_.open(param, backup_data_type, task_id, bandwidth_throttle))) { + } else if (OB_FAIL(backup_data_ctx_.open(param, backup_data_type, task_id))) { LOG_WARN("failed to open backup data ctx", K(ret), K(param), K(backup_data_type)); } else if (OB_FAIL(disk_checker_.init(ls_backup_ctx.get_tablet_holder()))) { LOG_WARN("failed to init disk checker", K(ret)); @@ -2486,7 +2517,6 @@ int ObLSBackupDataTask::init(const int64_t task_id, const share::ObBackupDataTyp backup_stat_.backup_set_id_ = param.backup_set_desc_.backup_set_id_; backup_stat_.file_id_ = task_id_; report_ctx_ = report_ctx; - bandwidth_throttle_ = &bandwidth_throttle; ls_backup_ctx_ = &ls_backup_ctx; backup_data_type_ = backup_data_type; provider_ = &provider; @@ -2580,19 +2610,7 @@ int ObLSBackupDataTask::process() } else { LOG_INFO("mark ls task info final", K(ret), K_(param), K_(task_id)); } - if (OB_TMP_FAIL(ObBackupUtils::report_task_result(param_.job_desc_.job_id_, - param_.job_desc_.task_id_, - param_.tenant_id_, - param_.ls_id_, - param_.turn_id_, - param_.retry_id_, - param_.job_desc_.trace_id_, - result, - report_ctx_))) { - LOG_WARN("failed to report task result", K(tmp_ret)); - } else { - FLOG_INFO("report backup data task", K(result), K_(param)); - } + REPORT_TASK_RESULT(this->get_dag()->get_dag_id(), result); } const int64_t cost_us = ObTimeUtility::current_time() - start_ts; record_server_event_(cost_us); @@ -2628,31 +2646,6 @@ int ObLSBackupDataTask::may_inject_simulated_error_() return ret; } -int ObLSBackupDataTask::report_tablet_skipped_(const common::ObTabletID &tablet_id, - const share::ObBackupSkippedType &skipped_type) -{ - int ret = OB_SUCCESS; - ObBackupSkippedTablet skipped_tablet; - skipped_tablet.task_id_ = param_.job_desc_.task_id_; - skipped_tablet.tenant_id_ = param_.tenant_id_; - skipped_tablet.turn_id_ = param_.turn_id_; - skipped_tablet.retry_id_ = param_.retry_id_; - skipped_tablet.tablet_id_ = tablet_id; - skipped_tablet.backup_set_id_ = param_.backup_set_desc_.backup_set_id_; - skipped_tablet.ls_id_ = param_.ls_id_; - skipped_tablet.skipped_type_ = skipped_type; - if (!skipped_tablet.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), K(skipped_tablet)); - } else if (OB_FAIL(ObLSBackupOperator::report_tablet_skipped( - param_.tenant_id_, skipped_tablet, *report_ctx_.sql_proxy_))) { - LOG_WARN("failed to report tablet skipped", K(ret), K_(param), K(tablet_id)); - } else { - FLOG_INFO("report tablet skipping", K(tablet_id), K(skipped_tablet)); - } - return ret; -} - int ObLSBackupDataTask::build_backup_file_header_(ObBackupFileHeader &file_header) { int ret = OB_SUCCESS; @@ -3094,6 +3087,15 @@ int ObLSBackupDataTask::write_macro_block_data_( } else if (OB_FAIL(backup_data_ctx_.write_macro_block_data(data, logic_id, macro_index))) { LOG_WARN("failed to write macro block data", K(ret), K(data), K(logic_id)); } else { +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("backup_errsim", "backup_macro_block", + "tenant_id", param_.tenant_id_, + "ls_id", param_.ls_id_, + "tablet_id", logic_id.tablet_id_, + "logic_id", logic_id, + "macro_index", macro_index, + "backup_data_type", backup_data_type_); +#endif LOG_INFO("write macro block data", K(data), K(logic_id), K(macro_index)); } return ret; @@ -3363,6 +3365,7 @@ int ObLSBackupDataTask::may_fill_reused_backup_items_( { int ret = OB_SUCCESS; ObTabletHandle tablet_handle; + ObTabletMemberWrapper table_store_wrapper; ObBackupDataType backup_data_type; backup_data_type.set_major_data_backup(); ObArray sstable_array; @@ -3378,8 +3381,10 @@ int ObLSBackupDataTask::may_fill_reused_backup_items_( // do nothing } else if (OB_FAIL(get_tablet_handle_(tablet_id, tablet_handle))) { LOG_WARN("failed to get tablet handle", K(ret), K(tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else if (OB_FAIL(ObBackupUtils::get_sstables_by_data_type(tablet_handle, - backup_data_type, tablet_handle.get_obj()->get_table_store(), sstable_array))) { + backup_data_type, *table_store_wrapper.get_member(), sstable_array))) { LOG_WARN("failed to get sstable by data type", K(ret), K(tablet_handle)); } else if (sstable_array.empty()) { // do nothing @@ -3490,8 +3495,11 @@ int ObLSBackupMetaTask::process() const share::ObLSID ls_id = param_.ls_id_; const int64_t retry_id = param_.retry_id_; storage::ObLS *ls = NULL; - ObBackupLSMetaInfo ls_meta_info; - common::ObArray tablet_id_list; +#ifdef ERRSIM + if (ls_id == ObLSID(1001)) { + DEBUG_SYNC(BEFORE_BACKUP_1001_META); + } +#endif if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("backup meta task do not init", K(ret)); @@ -3503,14 +3511,8 @@ int ObLSBackupMetaTask::process() LOG_WARN("failed to check ls validity", K(ret), K(tenant_id), K(ls_id)); } else if (OB_FAIL(advance_checkpoint_by_flush_(tenant_id, ls_id, start_scn))) { LOG_WARN("failed to advance checkpoint by flush", K(ret), K(tenant_id), K(ls_id), K(start_scn)); - } else if (OB_FAIL(get_backup_meta_ctx_(tenant_id, ls_id, ls_meta_info, tablet_id_list))) { + } else if (OB_FAIL(backup_ls_meta_and_tablet_metas_(tenant_id, ls_id))) { LOG_WARN("failed to get backup meta ctx", K(ret), K(tenant_id), K(ls_id)); - } else if (OB_FAIL(backup_ls_meta_package_(ls_meta_info))) { - LOG_WARN("failed to backup ls meta package", K(ret), KPC(ls)); - } else if (OB_FAIL(backup_ls_tablet_list_(start_scn, ls_id, tablet_id_list))) { - LOG_WARN("failed to backup tablet list", K(ret), K(start_scn), K(ls_id), K(tablet_id_list)); - } else { - LOG_INFO("backup ls meta", K(start_scn), K(tenant_id), K(ls_id), K(tablet_id_list), K(ls_meta_info)); } } } @@ -3528,13 +3530,8 @@ int ObLSBackupMetaTask::process() } } #endif - if (OB_SUCCESS != - (tmp_ret = ObBackupUtils::report_task_result( - param_.job_desc_.job_id_, param_.job_desc_.task_id_, param_.tenant_id_, param_.ls_id_, param_.turn_id_, - param_.retry_id_, param_.job_desc_.trace_id_, ret, report_ctx_))) { - LOG_WARN("failed to report task result", K(ret), K(tmp_ret), K_(param)); - } else { - FLOG_INFO("report backup meta task", K(ret), K_(param)); + if (OB_FAIL(ret)) { + REPORT_TASK_RESULT(this->get_dag()->get_dag_id(), ret); } return ret; } @@ -3557,29 +3554,96 @@ int ObLSBackupMetaTask::advance_checkpoint_by_flush_( return ret; } -int ObLSBackupMetaTask::get_backup_meta_ctx_(const uint64_t tenant_id, const share::ObLSID &ls_id, - ObBackupLSMetaInfo &ls_meta_info, common::ObArray &tablet_id_list) +int ObLSBackupMetaTask::backup_ls_meta_and_tablet_metas_(const uint64_t tenant_id, const share::ObLSID &ls_id) { int ret = OB_SUCCESS; - tablet_id_list.reset(); storage::ObLSHandle ls_handle; storage::ObLS *ls = NULL; - const bool check_archive = false; + ObBackupLSMetaInfo ls_meta_info; + ObExternTabletMetaWriter writer; + ObBackupDest backup_set_dest; + int64_t backup_tablet_count = 0; + + // save max tablet checkpoint scn of all the tablets belong to the same ls. + SCN max_tablet_checkpoint_scn; + max_tablet_checkpoint_scn.set_min(); + + // save ls meta + auto save_ls_meta_f = [&ls_meta_info, &max_tablet_checkpoint_scn](const ObLSMetaPackage &meta_package)->int { + int ret = OB_SUCCESS; + if (!meta_package.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls meta package is invalid", K(ret), K(meta_package)); + } else { + ls_meta_info.ls_meta_package_ = meta_package; + max_tablet_checkpoint_scn = MAX(max_tablet_checkpoint_scn, meta_package.ls_meta_.get_clog_checkpoint_scn()); + } + return ret; + }; + + // persist tablet meta + auto backup_tablet_meta_f = [&writer, &backup_tablet_count, &max_tablet_checkpoint_scn](const obrpc::ObCopyTabletInfo &tablet_info)->int { + int ret = OB_SUCCESS; + blocksstable::ObSelfBufferWriter buffer_writer("LSBackupMetaTask"); + blocksstable::ObBufferReader buffer_reader; + if (!tablet_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet meta is invalid", K(ret), K(tablet_info)); + } else if (OB_FAIL(buffer_writer.ensure_space(backup::OB_BACKUP_READ_BLOCK_SIZE))) { + LOG_WARN("failed to ensure space"); + } else if (OB_FAIL(buffer_writer.write_serialize(tablet_info.param_))) { + LOG_WARN("failed to writer", K(tablet_info)); + } else { + buffer_reader.assign(buffer_writer.data(), buffer_writer.length(), buffer_writer.length()); + if (OB_FAIL(writer.write_meta_data(buffer_reader, tablet_info.param_.tablet_id_))) { + LOG_WARN("failed to write meta data", K(ret), K(tablet_info)); + } else { + max_tablet_checkpoint_scn = MAX(max_tablet_checkpoint_scn, tablet_info.param_.get_max_tablet_checkpoint_scn()); + LOG_INFO("succeed backup tablet meta", "meta", tablet_info.param_); + } + } + + ++backup_tablet_count; + return ret; + }; + if (OB_FAIL(get_ls_handle(tenant_id, ls_id, ls_handle))) { LOG_WARN("failed to get ls", K(ret), K(tenant_id), K(ls_id)); } else if (OB_ISNULL(ls = ls_handle.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream not exist", K(ret), K(ls_id)); - } else if (OB_FAIL(ls->get_ls_meta_package_and_tablet_ids(check_archive, ls_meta_info.ls_meta_package_, tablet_id_list))) { - LOG_WARN("failed to get ls meta package", K(ret), K(tenant_id), K(ls_id)); - } else if (OB_FAIL(ls_meta_info.ls_meta_package_.ls_meta_.check_valid_for_backup())) { - LOG_WARN("failed to check valid for backup", K(ret), K(ls_meta_info)); + } else if (OB_FAIL(share::ObBackupPathUtil::construct_backup_set_dest(param_.backup_dest_, param_.backup_set_desc_, backup_set_dest))) { + LOG_WARN("failed to construct backup set dest", K(ret), K(param_)); + } else if (OB_FAIL(writer.init(backup_set_dest, param_.ls_id_, param_.turn_id_, param_.retry_id_))) { + LOG_WARN("failed to init tablet info writer", K(ret)); } else { - // the tablet ids return above is not sorted, and backup assumes - // the tablet id list is sorted, so we do a manual sort here - std::sort(tablet_id_list.begin(), tablet_id_list.end()); - LOG_INFO("get backup meta ctx", K(ls_meta_info), K(tablet_id_list)); + if (OB_FAIL(ls->get_ls_meta_package_and_tablet_metas( + false/* check_archive */, + save_ls_meta_f, + backup_tablet_meta_f))) { + LOG_WARN("failed to get ls meta package and tablet meta", K(ret), KPC(ls)); + } else if (OB_FAIL(backup_ls_meta_package_(ls_meta_info))) { + LOG_WARN("failed to backup ls meta package", K(ret), K(ls_meta_info)); + } else if (OB_FAIL(ObBackupLSTaskOperator::update_max_tablet_checkpoint_scn( + *report_ctx_.sql_proxy_, + param_.job_desc_.task_id_, + param_.tenant_id_, + param_.ls_id_, + max_tablet_checkpoint_scn))) { + LOG_WARN("failed to update max tablet checkpoint scn", K(ret), K(param_), K(max_tablet_checkpoint_scn)); + } else { + LOG_INFO("succeed backup ls meta and all tablet metas", K(ls_id), K(ls_meta_info), K(backup_tablet_count), K(max_tablet_checkpoint_scn)); + } + + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(writer.close())) { + if (OB_SUCC(ret)) { + ret = tmp_ret; + } + LOG_WARN("failed to close writer", K(ret), K(tmp_ret), K(ls_id)); + } } + return ret; } @@ -3602,45 +3666,6 @@ int ObLSBackupMetaTask::backup_ls_meta_package_(const ObBackupLSMetaInfo &ls_met return ret; } -int ObLSBackupMetaTask::backup_ls_tablet_list_( - const SCN &scn, const share::ObLSID &ls_id, const common::ObIArray &tablet_id_list) -{ - int ret = OB_SUCCESS; - share::ObBackupDataStore store; - const uint64_t tenant_id = param_.tenant_id_; - const int64_t turn_id = param_.turn_id_; - const int64_t retry_id = param_.retry_id_; - const ObBackupSetDesc backup_set_desc = param_.backup_set_desc_; - share::ObBackupDataTabletToLSDesc info; - if (OB_FAIL(store.init(param_.backup_dest_, backup_set_desc))) { - LOG_WARN("failed to init mgr", K(ret), K(param_.backup_dest_), K(tenant_id)); - } else if (OB_FAIL(build_backup_data_ls_tablet_desc_(ls_id, scn, tablet_id_list, info))) { - LOG_WARN("failed to build backup data ls tablet info", K(ret), K_(param)); - } else if (OB_FAIL(store.write_tablet_to_ls_info(info, ls_id, turn_id, retry_id))) { - LOG_WARN("failed to write tablet to ls info", K(ret), K(info), K(ls_id), K(turn_id)); - } - return ret; -} - -int ObLSBackupMetaTask::build_backup_data_ls_tablet_desc_(const share::ObLSID &ls_id, const SCN &scn, - const common::ObIArray &tablet_id_list, share::ObBackupDataTabletToLSDesc &desc) -{ - int ret = OB_SUCCESS; - ObBackupDataTabletToLSInfo info; - info.ls_id_ = ls_id; - if (!ls_id.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), K(ls_id), K(tablet_id_list)); - } else if (FALSE_IT(info.ls_id_ = ls_id)) { - } else if (OB_FAIL(info.tablet_id_list_.assign(tablet_id_list))) { - LOG_WARN("failed to assign list", K(ret), K(tablet_id_list)); - } else if (FALSE_IT(desc.backup_scn_ = scn)) { - } else if (OB_FAIL(desc.tablet_to_ls_.push_back(info))) { - LOG_WARN("failed to push back", K(ret), K(info)); - } - return ret; -} - /* ObLSBackupPrepareTask */ ObLSBackupPrepareTask::ObLSBackupPrepareTask() @@ -3700,7 +3725,7 @@ int ObLSBackupPrepareTask::process() LOG_WARN("prepare task do not init", K(ret)); } else if (OB_FAIL(may_need_advance_checkpoint_())) { LOG_WARN("may need advance checkpoint failed", K(ret), K_(param)); - } else if (OB_FAIL(check_tx_data_can_explain_user_data_())) { + } else if (OB_FAIL(prepare_backup_tx_table_filled_tx_scn_())) { LOG_WARN("failed to check tx data can explain user data", K(ret)); } else if (OB_FAIL(scheduler->alloc_dag(rebuild_dag))) { LOG_WARN("failed to alloc child dag", K(ret)); @@ -3831,40 +3856,64 @@ int ObLSBackupPrepareTask::process() need_report_error = is_set; } if (OB_NOT_NULL(ls_backup_ctx_) && need_report_error) { - const int64_t result = ls_backup_ctx_->get_result_code(); - if (OB_TMP_FAIL(ObBackupUtils::report_task_result(param_.job_desc_.job_id_, - param_.job_desc_.task_id_, - param_.tenant_id_, - param_.ls_id_, - param_.turn_id_, - param_.retry_id_, - param_.job_desc_.trace_id_, - result, - report_ctx_))) { - LOG_WARN("failed to report task result", K(tmp_ret)); - } else { - FLOG_INFO("report backup prepare task", K(result), K_(param)); - } + REPORT_TASK_RESULT(this->get_dag()->get_dag_id(), ls_backup_ctx_->get_result_code()); } return ret; } +int ObLSBackupPrepareTask::get_consistent_scn_(share::SCN &consistent_scn) const +{ + int ret = OB_SUCCESS; + ObBackupSetFileDesc backup_set_file; + if (backup_data_type_.is_sys_backup()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("need not get consistent scn during backup data of inner tablets", K(ret), K_(param), K_(backup_data_type)); + } else if (OB_FAIL(ObBackupSetFileOperator::get_backup_set_file( + *report_ctx_.sql_proxy_, + false/*for update*/, + param_.backup_set_desc_.backup_set_id_, + OB_START_INCARNATION, + param_.tenant_id_, + param_.dest_id_, + backup_set_file))) { + LOG_WARN("failed to get backup set", K(ret), K_(param), K_(backup_data_type)); + } else if (OB_FALSE_IT(consistent_scn = backup_set_file.consistent_scn_)) { + } else if (!consistent_scn.is_valid_and_not_min()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("consistent scn is not valid", K(ret), K_(param), K_(backup_data_type), K(backup_set_file)); + } + + return ret; +} + int ObLSBackupPrepareTask::may_need_advance_checkpoint_() { int ret = OB_SUCCESS; int64_t rebuild_seq = 0; SCN backup_clog_checkpoint_scn; const bool check_archive = false; + SCN consistent_scn; if (OB_ISNULL(ls_backup_ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls backup ctx should not be null", K(ret)); } else if (OB_FAIL(fetch_cur_ls_rebuild_seq_(rebuild_seq))) { LOG_WARN("failed to fetch cur ls rebuild seq", K(ret), K_(param)); - } else if (OB_FAIL(fetch_backup_ls_meta_(backup_clog_checkpoint_scn))) { - LOG_WARN("failed to fetch backup ls meta checkpoint ts", K(ret), K_(param)); } else if (FALSE_IT(ls_backup_ctx_->rebuild_seq_ = rebuild_seq)) { // assign rebuild seq + } else if (ls_backup_ctx_->backup_data_type_.is_sys_backup()) { + } else if (OB_FAIL(fetch_backup_ls_meta_(backup_clog_checkpoint_scn))) { + if (OB_ENTRY_NOT_EXIST == ret) { + // this ls may be created after backup ls meta. and some tablets transfer in this ls. + // we need to backup the tablets. but we didn't backup the ls meta. so we no need to advance checkpoint. + ret = OB_SUCCESS; + LOG_WARN("new created ls", K(ret), K_(param)); + } else { + LOG_WARN("failed to fetch backup ls meta checkpoint scn", K(ret), K_(param)); + } + } else if (!backup_data_type_.is_sys_backup() && OB_FAIL(get_consistent_scn_(consistent_scn))) { + LOG_WARN("failed to get consistent scn", K(ret), K_(param), K_(backup_data_type)); } else { + const SCN clog_checkpoint_scn = backup_data_type_.is_sys_backup() ? backup_clog_checkpoint_scn : consistent_scn; const uint64_t tenant_id = param_.tenant_id_; const share::ObLSID &ls_id = param_.ls_id_; MTL_SWITCH(tenant_id) { @@ -3880,12 +3929,12 @@ int ObLSBackupPrepareTask::may_need_advance_checkpoint_() LOG_WARN("failed to get ls meta", K(ret), K(tenant_id), K(ls_id)); } else if (OB_FAIL(cur_ls_meta.check_valid_for_backup())) { LOG_WARN("failed to check valid for backup", K(ret), K(cur_ls_meta)); - } else if (backup_clog_checkpoint_scn <= cur_ls_meta.get_clog_checkpoint_scn()) { - LOG_INFO("no need advance checkpoint", K_(param)); - } else if (OB_FAIL(advance_checkpoint_by_flush(tenant_id, ls_id, backup_clog_checkpoint_scn, ls))) { - LOG_WARN("failed to advance checkpoint by flush", K(ret), K(ls_id), K(backup_clog_checkpoint_scn)); + } else if (clog_checkpoint_scn <= cur_ls_meta.get_clog_checkpoint_scn()) { + LOG_INFO("no need advance checkpoint", K_(param), K_(backup_data_type), K(clog_checkpoint_scn)); + } else if (OB_FAIL(advance_checkpoint_by_flush(tenant_id, ls_id, clog_checkpoint_scn, ls))) { + LOG_WARN("failed to advance checkpoint by flush", K(ret), K(ls_id), K_(backup_data_type), K(clog_checkpoint_scn)); } else { - LOG_INFO("advance checkpint by flush", K_(param)); + LOG_INFO("advance checkpint by flush", K_(param), K_(backup_data_type), K(clog_checkpoint_scn)); } } } @@ -3922,7 +3971,8 @@ int ObLSBackupPrepareTask::fetch_backup_ls_meta_(share::SCN &clog_checkpoint_scn int ret = OB_SUCCESS; clog_checkpoint_scn.reset(); ObLSMetaPackage ls_meta_package; - share::ObBackupDataStore store; + storage::ObBackupDataStore store; + if (OB_FAIL(store.init(param_.backup_dest_, param_.backup_set_desc_))) { LOG_WARN("fail to init backup data store", K(ret)); } else if (OB_FAIL(store.read_ls_meta_infos(param_.ls_id_, ls_meta_package))) { @@ -3936,24 +3986,22 @@ int ObLSBackupPrepareTask::fetch_backup_ls_meta_(share::SCN &clog_checkpoint_scn return ret; } -int ObLSBackupPrepareTask::check_tx_data_can_explain_user_data_() +int ObLSBackupPrepareTask::prepare_backup_tx_table_filled_tx_scn_() { int ret = OB_SUCCESS; - SCN backup_filled_tx_scn = SCN::max_scn(); - SCN cur_min_filled_tx_scn = SCN::max_scn(); + bool created_after_backup = false; if (!backup_data_type_.is_minor_backup()) { // do nothing - } else if (OB_FAIL(get_backup_tx_data_table_filled_tx_scn_(backup_filled_tx_scn))) { - LOG_WARN("failed to get backup tx data table filled tx log ts", K(ret)); - } else if (OB_FAIL(get_cur_ls_min_filled_tx_scn_(cur_min_filled_tx_scn))) { - LOG_WARN("failed to get cur ls min end log ts in latest tablets", K(ret)); - } else { - if (cur_min_filled_tx_scn >= backup_filled_tx_scn) { - LOG_INFO("can backup replica", K(ret), K(cur_min_filled_tx_scn), K(backup_filled_tx_scn)); - } else { - ret = OB_REPLICA_CANNOT_BACKUP; - LOG_WARN("can not backup replica", K(ret), K(cur_min_filled_tx_scn), K(backup_filled_tx_scn)); - } + } else if (OB_FAIL(check_ls_created_after_backup_start_(param_.ls_id_, created_after_backup))) { + LOG_WARN("failed to check ls created after backup start", K(ret), K_(param)); + } else if (created_after_backup) { + LOG_INFO("ls is created after backup start and does not backup ls meta and inner tablet. no need to check tx data can explain user data", K(param_)); + SERVER_EVENT_ADD("backup_data", "ls_created_after_backup_start", + "tenant_id", param_.tenant_id_, + "job_id", param_.job_desc_.job_id_, + "ls_id", param_.ls_id_); + } else if (OB_FAIL(get_backup_tx_data_table_filled_tx_scn_(ls_backup_ctx_->backup_tx_table_filled_tx_scn_))) { + LOG_WARN("failed to get backup tx data table filled tx scn", K(ret)); } return ret; } @@ -3990,23 +4038,60 @@ int ObLSBackupPrepareTask::get_backup_tx_data_table_filled_tx_scn_(SCN &filled_t return ret; } -int ObLSBackupPrepareTask::get_sys_ls_retry_id_(int64_t &retry_id) +int ObLSBackupPrepareTask::get_sys_ls_turn_and_retry_id_(int64_t &turn_id, int64_t &retry_id) { int ret = OB_SUCCESS; retry_id = -1; ObBackupDataStore store; ObBackupPath backup_path; - if (OB_FAIL(store.init(param_.backup_dest_))) { + ObBackupSetTaskAttr task_attr; + turn_id = 0; + if (OB_FAIL(ObBackupTaskOperator::get_backup_task( + *report_ctx_.sql_proxy_, param_.job_desc_.job_id_, param_.tenant_id_, false, task_attr))) { + LOG_WARN("failed to get backup task", K(ret), K_(param)); + } else if (OB_FALSE_IT(turn_id = param_.ls_id_.is_sys_ls() ? 1 : task_attr.meta_turn_id_)) { + } else if (OB_FAIL(store.init(param_.backup_dest_))) { LOG_WARN("failed to init backup data store", K(ret), K_(param)); } else if (OB_FAIL(ObBackupPathUtil::get_ls_backup_dir_path( param_.backup_dest_, param_.backup_set_desc_, param_.ls_id_, backup_path))) { LOG_WARN("failed to get ls backup dir path", K(ret), K_(param)); - } else if (OB_FAIL(store.get_max_sys_ls_retry_id(backup_path, param_.ls_id_, retry_id))) { + } else if (OB_FAIL(store.get_max_sys_ls_retry_id(backup_path, param_.ls_id_, turn_id, retry_id))) { LOG_WARN("failed to get max sys retry id", K(ret), K(backup_path), K(param_)); } return ret; } +int ObLSBackupPrepareTask::check_ls_created_after_backup_start_(const ObLSID &ls_id, bool &created_after_backup) +{ + int ret = OB_SUCCESS; + ObBackupDataStore store; + ObBackupDataLSAttrDesc ls_info; + created_after_backup = true; + ObBackupSetTaskAttr task_attr; + common::ObMySQLProxy *sql_proxy = nullptr; + if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(ls_id)); + } else if (OB_ISNULL(sql_proxy = GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql prxoy must not be null", K(ret)); + } else if (OB_FAIL(ObBackupTaskOperator::get_backup_task( + *sql_proxy, param_.job_desc_.job_id_, param_.tenant_id_, false, task_attr))) { + LOG_WARN("failed to get backup task", K(ret), K_(param)); + } else if (OB_FAIL(store.init(param_.backup_dest_, param_.backup_set_desc_))) { + LOG_WARN("failed to init backup data source", K(ret), K_(param)); + } else if (OB_FAIL(store.read_ls_attr_info(task_attr.meta_turn_id_, ls_info))) { + LOG_WARN("failed to readd ls attr info", K(ret)); + } else { + ARRAY_FOREACH(ls_info.ls_attr_array_, i) { + if (ls_info.ls_attr_array_.at(i).get_ls_id() == ls_id) { + created_after_backup = false; + } + } + } + return ret; +} + int ObLSBackupPrepareTask::prepare_meta_index_store_(ObBackupMetaIndexStore &meta_index_store) { int ret = OB_SUCCESS; @@ -4014,9 +4099,10 @@ int ObLSBackupPrepareTask::prepare_meta_index_store_(ObBackupMetaIndexStore &met ObBackupIndexStoreParam index_store_param; const bool is_sec_meta = false; int64_t sys_retry_id = -1; - if (OB_FAIL(get_sys_ls_retry_id_(sys_retry_id))) { + int64_t sys_turn_id = 0; + if (OB_FAIL(get_sys_ls_turn_and_retry_id_(sys_turn_id, sys_retry_id))) { LOG_WARN("failed to get sys ls retry id", K(ret)); - } else if (OB_FAIL(prepare_meta_index_store_param_(sys_retry_id, index_store_param))) { + } else if (OB_FAIL(prepare_meta_index_store_param_(sys_turn_id, sys_retry_id, index_store_param))) { LOG_WARN("failed to preparep meta index store param", K(ret), K(sys_retry_id)); } else if (OB_FAIL(meta_index_store.init(mode, index_store_param, param_.backup_dest_, param_.backup_set_desc_, is_sec_meta, *index_kv_cache_))) { @@ -4026,7 +4112,7 @@ int ObLSBackupPrepareTask::prepare_meta_index_store_(ObBackupMetaIndexStore &met } int ObLSBackupPrepareTask::prepare_meta_index_store_param_( - const int64_t retry_id, ObBackupIndexStoreParam &index_param) + const int64_t turn_id, const int64_t retry_id, ObBackupIndexStoreParam &index_param) { int ret = OB_SUCCESS; if (retry_id < 0) { @@ -4039,7 +4125,7 @@ int ObLSBackupPrepareTask::prepare_meta_index_store_param_( index_param.ls_id_ = param_.ls_id_; index_param.is_tenant_level_ = false; index_param.backup_data_type_.set_sys_data_backup(); - index_param.turn_id_ = param_.turn_id_; + index_param.turn_id_ = turn_id; index_param.retry_id_ = retry_id; } return ret; @@ -4049,7 +4135,7 @@ int ObLSBackupPrepareTask::get_cur_ls_min_filled_tx_scn_(SCN &min_filled_tx_scn) { int ret = OB_SUCCESS; min_filled_tx_scn = SCN::max_scn(); - ObLSTabletIterator iterator(ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US); + ObLSTabletIterator iterator(ObMDSGetTabletMode::READ_WITHOUT_CHECK); storage::ObLSHandle ls_handle; storage::ObLS *ls = NULL; ObLSTabletService *ls_tablet_svr = NULL; @@ -4091,18 +4177,21 @@ int ObLSBackupPrepareTask::get_tablet_min_filled_tx_scn_( has_minor_sstable = false; min_filled_tx_scn = SCN::max_scn(); ObTablet *tablet = nullptr; + ObTabletMemberWrapper table_store_wrapper; if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet is nullptr.", K(ret), K(tablet_handle)); } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { // skip inner tablet + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - ObTabletTableStore &table_store = tablet->get_table_store(); - const ObSSTableArray &sstable_array = table_store.get_minor_sstables(); + const ObSSTableArray &sstable_array = table_store_wrapper.get_member()->get_minor_sstables(); has_minor_sstable = !sstable_array.empty(); for (int64_t i = 0; OB_SUCC(ret) && i < sstable_array.count(); ++i) { ObITable *table_ptr = sstable_array[i]; ObSSTable *sstable = NULL; + ObSSTableMetaHandle sst_meta_hdl; if (OB_ISNULL(table_ptr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table ptr should not be null", K(ret)); @@ -4110,9 +4199,11 @@ int ObLSBackupPrepareTask::get_tablet_min_filled_tx_scn_( ret = OB_ERR_UNEXPECTED; LOG_WARN("table ptr type not expectedd", K(ret)); } else if (FALSE_IT(sstable = static_cast(table_ptr))) { + } else if (OB_FAIL(sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta", K(ret)); } else { min_filled_tx_scn = std::min( - std::max(sstable->get_meta().get_basic_meta().filled_tx_scn_, sstable->get_end_scn()), min_filled_tx_scn); + std::max(sst_meta_hdl.get_sstable_meta().get_filled_tx_scn(), sstable->get_end_scn()), min_filled_tx_scn); } } } @@ -4130,7 +4221,6 @@ ObBackupIndexRebuildTask::ObBackupIndexRebuildTask() provider_(NULL), task_mgr_(NULL), index_kv_cache_(NULL), - bandwidth_throttle_(NULL), report_ctx_() {} @@ -4139,8 +4229,7 @@ ObBackupIndexRebuildTask::~ObBackupIndexRebuildTask() int ObBackupIndexRebuildTask::init(const ObLSBackupDataParam ¶m, const ObBackupIndexLevel &index_level, ObLSBackupCtx *ls_backup_ctx, ObIBackupTabletProvider *provider, ObBackupMacroBlockTaskMgr *task_mgr, - ObBackupIndexKVCache *index_kv_cache, common::ObInOutBandwidthThrottle &bandwidth_throttle, - const ObBackupReportCtx &report_ctx) + ObBackupIndexKVCache *index_kv_cache, const ObBackupReportCtx &report_ctx) { int ret = OB_SUCCESS; if (IS_INIT) { @@ -4159,7 +4248,6 @@ int ObBackupIndexRebuildTask::init(const ObLSBackupDataParam ¶m, const ObBac provider_ = provider; task_mgr_ = task_mgr; index_kv_cache_ = index_kv_cache; - bandwidth_throttle_ = &bandwidth_throttle; is_inited_ = true; } return ret; @@ -4216,19 +4304,7 @@ int ObBackupIndexRebuildTask::process() need_report_error = is_set; } if (0 == param_.ls_id_.id() || need_report_error) { - if (OB_SUCCESS != (tmp_ret = ObBackupUtils::report_task_result(param_.job_desc_.job_id_, - param_.job_desc_.task_id_, - param_.tenant_id_, - param_.ls_id_, - param_.turn_id_, - param_.retry_id_, - param_.job_desc_.trace_id_, - ret, - report_ctx_))) { - LOG_WARN("failed to report task result"); - } else { - FLOG_INFO("report backup index rebuild task", K_(param)); - } + REPORT_TASK_RESULT(this->get_dag()->get_dag_id(), ret); } const int64_t cost_us = ObTimeUtility::current_time() - start_ts; record_server_event_(cost_us); @@ -4291,7 +4367,7 @@ int ObBackupIndexRebuildTask::merge_macro_index_() ObBackupMacroBlockIndexMerger macro_index_merger; if (OB_FAIL(param_.convert_to(index_level_, merge_param))) { LOG_WARN("failed to convert param", K(ret), K_(param), K_(index_level)); - } else if (OB_FAIL(macro_index_merger.init(merge_param, *report_ctx_.sql_proxy_, *bandwidth_throttle_))) { + } else if (OB_FAIL(macro_index_merger.init(merge_param, *report_ctx_.sql_proxy_))) { LOG_WARN("failed to init index merger", K(ret), K(merge_param)); } else if (OB_FAIL(macro_index_merger.merge_index())) { LOG_WARN("failed to merge macro index", K(ret), K_(param)); @@ -4308,7 +4384,7 @@ int ObBackupIndexRebuildTask::merge_meta_index_(const bool is_sec_meta) ObBackupMetaIndexMerger meta_index_merger; if (OB_FAIL(param_.convert_to(index_level_, merge_param))) { LOG_WARN("failed to convert param", K(ret), K_(param), K_(index_level)); - } else if (OB_FAIL(meta_index_merger.init(merge_param, is_sec_meta, *report_ctx_.sql_proxy_, *bandwidth_throttle_))) { + } else if (OB_FAIL(meta_index_merger.init(merge_param, is_sec_meta, *report_ctx_.sql_proxy_))) { LOG_WARN("failed to init index merger", K(ret), K(merge_param)); } else if (OB_FAIL(meta_index_merger.merge_index())) { LOG_WARN("failed to merge meta index", K(ret), K_(param)); @@ -4351,7 +4427,7 @@ int ObBackupIndexRebuildTask::report_check_tablet_info_event_() if (0 != total_tablet_count) { avg_cost_time = total_cost_time / total_tablet_count; } - SERVER_EVENT_ADD("backup", "check_tablet_info", + SERVER_EVENT_ADD("backup_data", "check_tablet_info", "tenant_id", ls_backup_ctx_->param_.tenant_id_, "ls_id", ls_backup_ctx_->param_.ls_id_.id(), "total_cost_time_us", total_cost_time, @@ -4414,19 +4490,18 @@ int ObLSBackupFinishTask::process() } else if (FALSE_IT(ls_backup_ctx_->stat_mgr_.mark_end(ls_backup_ctx_->backup_data_type_))) { } else if (FALSE_IT(result = ls_backup_ctx_->get_result_code())) { } - if (OB_SUCCESS != (tmp_ret = ObBackupUtils::report_task_result(param_.job_desc_.job_id_, - param_.job_desc_.task_id_, - param_.tenant_id_, - param_.ls_id_, - param_.turn_id_, - param_.retry_id_, - param_.job_desc_.trace_id_, - result, - report_ctx_))) { - LOG_WARN("failed to report task result", K(ret)); - } else { - FLOG_INFO("report backup finish task", K_(param)); +#ifdef ERRSIM + if (ls_backup_ctx_->param_.ls_id_.id() == GCONF.errsim_backup_ls_id) { + ret = EN_LS_BACKUP_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + result = ret; + SERVER_EVENT_SYNC_ADD("backup_errsim", "backup_macro_block_failed", "ret", ret); + ret = OB_SUCCESS; + } } +#endif + REPORT_TASK_RESULT(this->get_dag()->get_dag_id(), result); + return ret; } @@ -4611,7 +4686,7 @@ int ObLSBackupComplementLogTask::process() #endif if (OB_SUCCESS != (tmp_ret = ObBackupUtils::report_task_result( job_desc_.job_id_, job_desc_.task_id_, tenant_id_, ls_id_, turn_id_, retry_id_, - job_desc_.trace_id_, ret, report_ctx_))) { + job_desc_.trace_id_, this->get_dag()->get_dag_id(), ret, report_ctx_))) { LOG_WARN("failed to report task result", K(tmp_ret), K_(job_desc), K_(tenant_id), K_(ls_id), K(ret)); } else { FLOG_INFO("report backup complement log task", K_(job_desc), K_(tenant_id), K_(ls_id)); diff --git a/src/storage/backup/ob_backup_task.h b/src/storage/backup/ob_backup_task.h index 079afa064..54694ec2b 100644 --- a/src/storage/backup/ob_backup_task.h +++ b/src/storage/backup/ob_backup_task.h @@ -30,8 +30,9 @@ #include "storage/backup/ob_backup_utils.h" #include "storage/blocksstable/ob_data_buffer.h" #include "storage/ls/ob_ls_tablet_service.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" #include "storage/blocksstable/ob_logic_macro_id.h" +#include "storage/backup/ob_backup_extern_info_mgr.h" #include "share/backup/ob_archive_store.h" namespace oceanbase { @@ -95,16 +96,6 @@ enum ObBackupDagNetSubType : int64_t { LOG_STREAM_BACKUP_COMPLEMENT_LOG_DAG_NET = 3, }; -enum ObBackupDagSubType : int64_t { - LOG_STREAM_BACKUP_META_DAG = 0, - LOG_STREAM_BACKUP_PREPARE_DAG = 1, - LOG_STREAM_BACKUP_PREFETCH_DAG = 2, - LOG_STREAM_BACKUP_DATA_DAG = 3, - LOG_STREAM_BACKUP_BUILD_INDEX_DAG = 4, - LOG_STREAM_BACKUP_COMPLEMENT_LOG_DAG = 5, - LOG_STREAM_BACKUP_FINISH_DAG = 6, -}; - class ObBackupDagNet : public share::ObIDagNet { public: @@ -118,27 +109,6 @@ protected: DISALLOW_COPY_AND_ASSIGN(ObBackupDagNet); }; -class ObLSBackupMetaDagNet : public ObBackupDagNet { -public: - ObLSBackupMetaDagNet(); - virtual ~ObLSBackupMetaDagNet(); - virtual int init_by_param(const share::ObIDagInitParam *param) override; - virtual int start_running() override; - virtual bool operator==(const share::ObIDagNet &other) const override; - virtual bool is_valid() const override; - virtual int64_t hash() const override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; - virtual int fill_dag_net_key(char *buf, const int64_t buf_len) const override; - INHERIT_TO_STRING_KV("ObIDagNet", share::ObIDagNet, K_(param)); - -private: - bool is_inited_; - ObLSBackupDagInitParam param_; - ObBackupReportCtx report_ctx_; - share::SCN start_scn_; - DISALLOW_COPY_AND_ASSIGN(ObLSBackupMetaDagNet); -}; - class ObLSBackupDataDagNet : public ObBackupDagNet { public: ObLSBackupDataDagNet(); @@ -160,14 +130,14 @@ public: } INHERIT_TO_STRING_KV("ObIDagNet", share::ObIDagNet, K_(param)); -private: +protected: int inner_init_before_run_(); int get_batch_size_(int64_t &batch_size); int prepare_backup_tablet_provider_(const ObLSBackupParam ¶m, const share::ObBackupDataType &backup_data_type, ObLSBackupCtx &ls_backup_ctx, ObBackupIndexKVCache &index_kv_cache, common::ObMySQLProxy &sql_proxy, ObIBackupTabletProvider *&provider); -private: +protected: bool is_inited_; ObLSBackupStage start_stage_; share::ObBackupDataType backup_data_type_; @@ -180,6 +150,18 @@ private: DISALLOW_COPY_AND_ASSIGN(ObLSBackupDataDagNet); }; +class ObLSBackupMetaDagNet : public ObLSBackupDataDagNet { +public: + ObLSBackupMetaDagNet(); + virtual ~ObLSBackupMetaDagNet(); + virtual int start_running() override; + virtual bool operator==(const share::ObIDagNet &other) const override; + virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_dag_net_key(char *buf, const int64_t buf_len) const override; + DISALLOW_COPY_AND_ASSIGN(ObLSBackupMetaDagNet); +}; + + class ObBackupBuildTenantIndexDagNet : public ObBackupDagNet { public: ObBackupBuildTenantIndexDagNet(); @@ -223,27 +205,15 @@ private: DISALLOW_COPY_AND_ASSIGN(ObLSBackupComplementLogDagNet); }; -class ObBackupDag : public share::ObIDag -{ -public: - explicit ObBackupDag(const ObBackupDagSubType &sub_type); - virtual ~ObBackupDag(); - virtual bool is_ha_dag() const override { return true; } - ObBackupDagSubType get_sub_type() const { return sub_type_; }; - INHERIT_TO_STRING_KV("ObIDag", ObIDag, K_(sub_type)); -protected: - ObBackupDagSubType sub_type_; - DISALLOW_COPY_AND_ASSIGN(ObBackupDag); -}; -class ObLSBackupMetaDag : public ObBackupDag { +class ObLSBackupMetaDag : public share::ObIDag { public: ObLSBackupMetaDag(); virtual ~ObLSBackupMetaDag(); int init(const share::SCN &start_scn, const ObLSBackupDagInitParam ¶m, const ObBackupReportCtx &report_ctx); virtual int create_first_task() override; virtual bool operator==(const ObIDag &other) const override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int64_t hash() const override; virtual lib::Worker::CompatMode get_compat_mode() const override; @@ -258,7 +228,7 @@ private: DISALLOW_COPY_AND_ASSIGN(ObLSBackupMetaDag); }; -class ObLSBackupPrepareDag : public ObBackupDag { +class ObLSBackupPrepareDag : public share::ObIDag { public: ObLSBackupPrepareDag(); virtual ~ObLSBackupPrepareDag(); @@ -267,7 +237,7 @@ public: ObBackupMacroBlockTaskMgr &task_mgr, ObBackupIndexKVCache &index_kv_cache); virtual int create_first_task() override; virtual bool operator==(const ObIDag &other) const override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int64_t hash() const override; virtual lib::Worker::CompatMode get_compat_mode() const override; @@ -289,7 +259,7 @@ private: DISALLOW_COPY_AND_ASSIGN(ObLSBackupPrepareDag); }; -class ObLSBackupFinishDag : public ObBackupDag { +class ObLSBackupFinishDag : public share::ObIDag { public: ObLSBackupFinishDag(); virtual ~ObLSBackupFinishDag(); @@ -297,7 +267,7 @@ public: ObBackupIndexKVCache &index_kv_cache); virtual int create_first_task() override; virtual bool operator==(const ObIDag &other) const override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int64_t hash() const override; virtual bool check_can_schedule() override; @@ -314,9 +284,10 @@ private: DISALLOW_COPY_AND_ASSIGN(ObLSBackupFinishDag); }; -class ObLSBackupDataDag : public ObBackupDag { +class ObLSBackupDataDag : public share::ObIDag { public: - ObLSBackupDataDag(const ObBackupDagSubType &sub_type = ObBackupDagSubType::LOG_STREAM_BACKUP_DATA_DAG); + ObLSBackupDataDag(); + ObLSBackupDataDag(const share::ObDagType::ObDagTypeEnum type); virtual ~ObLSBackupDataDag(); int init(const int64_t task_id, const ObLSBackupDagInitParam ¶m, const share::ObBackupDataType &backup_data_type, const ObBackupReportCtx &report_ctx, ObLSBackupCtx &ls_backup_ctx, ObIBackupTabletProvider &provider, @@ -325,7 +296,7 @@ public: virtual int create_first_task() override; virtual bool operator==(const ObIDag &other) const override; virtual int64_t hash() const override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual lib::Worker::CompatMode get_compat_mode() const override; virtual uint64_t get_consumer_group_id() const override { return consumer_group_id_; } @@ -342,7 +313,6 @@ protected: ObBackupIndexKVCache *index_kv_cache_; ObBackupReportCtx report_ctx_; ObArray backup_items_; - common::ObInOutBandwidthThrottle bandwidth_throttle_; share::ObIDag *index_rebuild_dag_; DISALLOW_COPY_AND_ASSIGN(ObLSBackupDataDag); }; @@ -354,14 +324,13 @@ public: virtual int create_first_task() override; virtual bool operator==(const ObIDag &other) const override; virtual int64_t hash() const override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; private: DISALLOW_COPY_AND_ASSIGN(ObPrefetchBackupInfoDag); }; -class ObLSBackupIndexRebuildDag : public ObBackupDag { +class ObLSBackupIndexRebuildDag : public share::ObIDag { public: ObLSBackupIndexRebuildDag(); virtual ~ObLSBackupIndexRebuildDag(); @@ -369,7 +338,7 @@ public: const ObBackupIndexLevel &index_level, const ObBackupReportCtx &report_ctx, ObBackupMacroBlockTaskMgr *task_mgr, ObIBackupTabletProvider *provider, ObBackupIndexKVCache *index_kv_cache, ObLSBackupCtx *ctx); virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual bool operator==(const ObIDag &other) const override; virtual int64_t hash() const override; @@ -389,11 +358,10 @@ private: ObBackupMacroBlockTaskMgr *task_mgr_; ObIBackupTabletProvider *provider_; ObBackupIndexKVCache *index_kv_cache_; - common::ObInOutBandwidthThrottle bandwidth_throttle_; DISALLOW_COPY_AND_ASSIGN(ObLSBackupIndexRebuildDag); }; -class ObLSBackupComplementLogDag : public ObBackupDag { +class ObLSBackupComplementLogDag : public share::ObIDag { public: ObLSBackupComplementLogDag(); virtual ~ObLSBackupComplementLogDag(); @@ -401,7 +369,7 @@ public: const int64_t dest_id, const share::ObBackupSetDesc &backup_set_desc, const share::ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, const share::SCN &start_scn, const share::SCN &end_scn, const ObBackupReportCtx &report_ctx); virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual bool operator==(const ObIDag &other) const override; virtual int64_t hash() const override; @@ -434,14 +402,8 @@ public: private: int advance_checkpoint_by_flush_(const uint64_t tenant_id, const share::ObLSID &ls_id, const share::SCN &start_scn); - int get_backup_meta_ctx_(const uint64_t tenant_id, const share::ObLSID &ls_id, - ObBackupLSMetaInfo &ls_meta_info, common::ObArray &tablet_id_list); + int backup_ls_meta_and_tablet_metas_(const uint64_t tenant_id, const share::ObLSID &ls_id); int backup_ls_meta_package_(const ObBackupLSMetaInfo &ls_meta_info); - int backup_ls_tablet_list_( - const share::SCN &scn, const share::ObLSID &ls, const common::ObIArray &tablet_id_list); - int build_backup_data_ls_tablet_desc_(const share::ObLSID &ls_id, const share::SCN &scn, - const common::ObIArray &tablet_id, share::ObBackupDataTabletToLSDesc &info); - private: bool is_inited_; @@ -461,14 +423,16 @@ public: virtual int process() override; private: + int get_consistent_scn_(share::SCN &consistent_scn) const; int may_need_advance_checkpoint_(); int fetch_cur_ls_rebuild_seq_(int64_t &rebuild_seq); int fetch_backup_ls_meta_(share::SCN &clog_checkpoint_scn); - int check_tx_data_can_explain_user_data_(); + int prepare_backup_tx_table_filled_tx_scn_(); + int check_ls_created_after_backup_start_(const ObLSID &ls_id, bool &created_after_backup); int get_backup_tx_data_table_filled_tx_scn_(share::SCN &filled_tx_scn); int prepare_meta_index_store_(ObBackupMetaIndexStore &meta_index_store); - int get_sys_ls_retry_id_(int64_t &retry_id); - int prepare_meta_index_store_param_(const int64_t retry_id, ObBackupIndexStoreParam ¶m); + int get_sys_ls_turn_and_retry_id_(int64_t &turn_id, int64_t &retry_id); + int prepare_meta_index_store_param_(const int64_t turn_id, const int64_t retry_id, ObBackupIndexStoreParam ¶m); int get_cur_ls_min_filled_tx_scn_(share::SCN &min_filled_tx_scn); int get_tablet_min_filled_tx_scn_(ObTabletHandle &tablet_handle, share::SCN &min_filled_tx_scn, bool &has_minor_sstable); @@ -496,10 +460,18 @@ public: virtual int process() override; private: + int setup_macro_index_store_(const ObLSBackupDagInitParam ¶m, + const share::ObBackupDataType &backup_data_type, const ObBackupSetDesc &backup_set_desc, + const ObBackupReportCtx &report_ctx, ObBackupIndexStoreParam &index_store_param, ObBackupMacroBlockIndexStore &index_store); + int inner_init_macro_index_store_for_inc_(const ObLSBackupDagInitParam ¶m, + const share::ObBackupDataType &backup_data_type, const ObBackupReportCtx &report_ctx); + int inner_init_macro_index_store_for_turn_(const ObLSBackupDagInitParam ¶m, + const share::ObBackupDataType &backup_data_type, const ObBackupReportCtx &report_ctx); + int64_t get_prev_turn_id_(const int64_t cur_turn_id); int inner_process_(); int check_backup_items_valid_(const common::ObIArray &items); int get_prev_backup_set_desc_(const uint64_t tenant_id, const int64_t dest_id, const share::ObBackupSetDesc &cur_backup_set_desc, - share::ObBackupSetDesc &prev_backup_set_desc); + share::ObBackupSetFileDesc &prev_backup_set_info); int get_tenant_macro_index_retry_id_(const share::ObBackupDest &backup_dest, const share::ObBackupSetDesc &prev_backup_set_desc, const share::ObBackupDataType &backup_data_type, const int64_t turn_id, int64_t &retry_id); int get_need_copy_item_list_(const common::ObIArray &list, @@ -507,6 +479,8 @@ private: common::ObIArray &no_need_copy_macro_index_list); int check_backup_item_need_copy_( const ObBackupProviderItem &item, bool &need_copy, ObBackupMacroBlockIndex ¯o_index); + int inner_check_backup_item_need_copy_when_change_turn_( + const ObBackupProviderItem &item, bool &need_copy, ObBackupMacroBlockIndex ¯o_index); int generate_next_prefetch_dag_(); int generate_backup_dag_(const int64_t task_id, const common::ObIArray &items); @@ -519,7 +493,8 @@ private: ObIBackupTabletProvider *provider_; ObBackupMacroBlockTaskMgr *task_mgr_; ObBackupIndexKVCache *index_kv_cache_; - ObBackupMacroBlockIndexStore macro_index_store_; + ObBackupMacroBlockIndexStore macro_index_store_for_inc_; + ObBackupMacroBlockIndexStore macro_index_store_for_turn_; share::ObIDag *index_rebuild_dag_; DISALLOW_COPY_AND_ASSIGN(ObPrefetchBackupInfoTask); }; @@ -530,15 +505,12 @@ public: virtual ~ObLSBackupDataTask(); int init(const int64_t task_id, const share::ObBackupDataType &backup_data_type, const common::ObIArray &backup_items, const ObLSBackupDataParam ¶m, - const ObBackupReportCtx &report_ctx, common::ObInOutBandwidthThrottle &bandwidth_throttle, - ObLSBackupCtx &ls_backup_ctx, ObIBackupTabletProvider &provider, ObBackupMacroBlockTaskMgr &task_mgr, - ObBackupIndexKVCache &kv_cache, share::ObIDag *index_rebuild_dag); + const ObBackupReportCtx &report_ctx, ObLSBackupCtx &ls_backup_ctx, ObIBackupTabletProvider &provider, + ObBackupMacroBlockTaskMgr &task_mgr, ObBackupIndexKVCache &kv_cache, share::ObIDag *index_rebuild_dag); virtual int process() override; private: int may_inject_simulated_error_(); - int report_tablet_skipped_(const common::ObTabletID &tablet_id, - const share::ObBackupSkippedType &skipped_type); private: int build_backup_file_header_(ObBackupFileHeader &file_header); @@ -595,7 +567,6 @@ private: ObBackupReportCtx report_ctx_; share::ObBackupDataType backup_data_type_; ObBackupDataCtx backup_data_ctx_; - common::ObInOutBandwidthThrottle *bandwidth_throttle_; ObLSBackupCtx *ls_backup_ctx_; ObIBackupTabletProvider *provider_; ObBackupMacroBlockTaskMgr *task_mgr_; @@ -614,7 +585,7 @@ public: virtual ~ObBackupIndexRebuildTask(); int init(const ObLSBackupDataParam ¶m, const ObBackupIndexLevel &index_level, ObLSBackupCtx *ls_backup_ctx, ObIBackupTabletProvider *provider, ObBackupMacroBlockTaskMgr *task_mgr, ObBackupIndexKVCache *kv_cache, - common::ObInOutBandwidthThrottle &bandwidth_throttle, const ObBackupReportCtx &report_ctx); + const ObBackupReportCtx &report_ctx); virtual int process() override; private: @@ -635,7 +606,6 @@ private: ObIBackupTabletProvider *provider_; ObBackupMacroBlockTaskMgr *task_mgr_; ObBackupIndexKVCache *index_kv_cache_; - common::ObInOutBandwidthThrottle *bandwidth_throttle_; ObBackupReportCtx report_ctx_; DISALLOW_COPY_AND_ASSIGN(ObBackupIndexRebuildTask); }; diff --git a/src/storage/backup/ob_backup_utils.cpp b/src/storage/backup/ob_backup_utils.cpp old mode 100644 new mode 100755 index 2e0b09450..b9ee3e403 --- a/src/storage/backup/ob_backup_utils.cpp +++ b/src/storage/backup/ob_backup_utils.cpp @@ -19,6 +19,7 @@ #include "lib/oblog/ob_log_module.h" #include "lib/time/ob_time_utility.h" #include "share/rc/ob_tenant_base.h" +#include "share/backup/ob_archive_struct.h" #include "storage/backup/ob_backup_factory.h" #include "storage/backup/ob_backup_operator.h" #include "storage/backup/ob_backup_reader.h" @@ -27,12 +28,15 @@ #include "storage/meta_mem/ob_tablet_handle.h" #include "storage/tablet/ob_tablet_meta.h" #include "storage/tablet/ob_tablet_table_store.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" #include "storage/tx_storage/ob_ls_map.h" #include "storage/tx_storage/ob_ls_service.h" #include "storage/high_availability/ob_storage_ha_utils.h" #include "observer/ob_server_event_history_table_operator.h" #include "share/scn.h" +#include "share/backup/ob_backup_data_table_operator.h" #include "storage/blocksstable/ob_logic_macro_id.h" +#include "storage/backup/ob_backup_data_store.h" #include @@ -47,9 +51,32 @@ namespace oceanbase { namespace backup { /* ObBackupUtils */ +int ObBackupUtils::calc_start_replay_scn( + const share::ObBackupSetTaskAttr &set_task_attr, + const storage::ObBackupLSMetaInfosDesc &ls_meta_infos, + const share::ObTenantArchiveRoundAttr &round_attr, + share::SCN &start_replay_scn) +{ + int ret = OB_SUCCESS; + SCN tmp_start_replay_scn = set_task_attr.start_scn_; + // To ensure that restore can be successfully initiated, + // we need to avoid clearing too many logs and the start_replay_scn less than the start_scn of the first piece. + // so we choose the minimum palf_base_info.prev_log_info_.scn firstly, to ensure keep enough logs. + // Then we choose the max(minimum palf_base_info.prev_log_info_.scn, round_attr.start_scn) as the start_replay_scn, + // to ensure the start_replay_scn is greater than the start scn of first piece + ARRAY_FOREACH_X(ls_meta_infos.ls_meta_packages_, i, cnt, OB_SUCC(ret)) { + const palf::PalfBaseInfo &palf_base_info = ls_meta_infos.ls_meta_packages_.at(i).palf_meta_; + tmp_start_replay_scn = SCN::min(tmp_start_replay_scn, palf_base_info.prev_log_info_.scn_); + } + if (OB_SUCC(ret)) { + start_replay_scn = SCN::max(tmp_start_replay_scn, round_attr.start_scn_); + LOG_INFO("calculate start replay scn finish", K(start_replay_scn), K(ls_meta_infos), K(round_attr)); + } + return ret; +} int ObBackupUtils::get_sstables_by_data_type(const storage::ObTabletHandle &tablet_handle, const share::ObBackupDataType &backup_data_type, - storage::ObTabletTableStore &tablet_table_store, common::ObIArray &sstable_array) + const storage::ObTabletTableStore &tablet_table_store, common::ObIArray &sstable_array) { int ret = OB_SUCCESS; sstable_array.reset(); @@ -57,8 +84,8 @@ int ObBackupUtils::get_sstables_by_data_type(const storage::ObTabletHandle &tabl ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(backup_data_type), K(tablet_table_store)); } else if (backup_data_type.is_sys_backup()) { - storage::ObSSTableArray *minor_sstable_array_ptr = NULL; - storage::ObSSTableArray *major_sstable_array_ptr = NULL; + const storage::ObSSTableArray *minor_sstable_array_ptr = NULL; + const storage::ObSSTableArray *major_sstable_array_ptr = NULL; minor_sstable_array_ptr = &tablet_table_store.get_minor_sstables(); major_sstable_array_ptr = &tablet_table_store.get_major_sstables(); ObArray minor_sstable_array; @@ -75,8 +102,8 @@ int ObBackupUtils::get_sstables_by_data_type(const storage::ObTabletHandle &tabl LOG_WARN("failed to append", K(ret), K(major_sstable_array)); } } else if (backup_data_type.is_minor_backup()) { - storage::ObSSTableArray *minor_sstable_array_ptr = NULL; - storage::ObSSTableArray *ddl_sstable_array_ptr = NULL; + const storage::ObSSTableArray *minor_sstable_array_ptr = NULL; + const storage::ObSSTableArray *ddl_sstable_array_ptr = NULL; minor_sstable_array_ptr = &tablet_table_store.get_minor_sstables(); ddl_sstable_array_ptr = &tablet_table_store.get_ddl_sstables(); ObArray minor_sstable_array; @@ -95,10 +122,13 @@ int ObBackupUtils::get_sstables_by_data_type(const storage::ObTabletHandle &tabl LOG_WARN("failed to append", K(ret), K(ddl_sstable_array)); } } else if (backup_data_type.is_major_backup()) { - storage::ObSSTableArray *major_sstable_array_ptr = NULL; + const storage::ObSSTableArray *major_sstable_array_ptr = NULL; major_sstable_array_ptr = &tablet_table_store.get_major_sstables(); ObITable *last_major_sstable_ptr = NULL; bool with_major_sstable = true; + common::ObArenaAllocator allocator; + compaction::ObMediumCompactionInfoList medium_info_list; + if (OB_ISNULL(last_major_sstable_ptr = major_sstable_array_ptr->get_boundary_table(true /*last*/))) { if (OB_FAIL(check_tablet_with_major_sstable(tablet_handle, with_major_sstable))) { LOG_WARN("failed to check tablet with major sstable", K(ret)); @@ -107,10 +137,12 @@ int ObBackupUtils::get_sstables_by_data_type(const storage::ObTabletHandle &tabl ret = OB_ERR_UNEXPECTED; LOG_WARN("last major sstable should not be null", K(ret), K(tablet_handle)); } - } else if (tablet_handle.get_obj()->get_medium_compaction_info_list().get_last_compaction_scn() > 0 - && tablet_handle.get_obj()->get_medium_compaction_info_list().get_last_compaction_scn() != last_major_sstable_ptr->get_snapshot_version()) { + } else if (OB_FAIL(tablet_handle.get_obj()->get_medium_info_list(allocator, medium_info_list))) { + LOG_WARN("failed to get mediumn info list", K(ret)); + } else if (medium_info_list.get_last_compaction_scn() > 0 + && medium_info_list.get_last_compaction_scn() != last_major_sstable_ptr->get_snapshot_version()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("medium list is invalid for last major sstable", K(ret), "medium_list", tablet_handle.get_obj()->get_medium_compaction_info_list(), + LOG_WARN("medium list is invalid for last major sstable", K(ret), K(medium_info_list), KPC(last_major_sstable_ptr), K(tablet_handle)); } else if (OB_FAIL(sstable_array.push_back(last_major_sstable_ptr))) { LOG_WARN("failed to push back", K(ret), KPC(last_major_sstable_ptr)); @@ -150,7 +182,7 @@ int ObBackupUtils::fetch_macro_block_logic_id_list(const storage::ObTabletHandle } else if (OB_FAIL(meta_iter.open(datum_range, ObMacroBlockMetaType::DATA_BLOCK_META, sstable, - tablet_handle.get_obj()->get_index_read_info(), + tablet_handle.get_obj()->get_rowkey_read_info(), allocator))) { LOG_WARN("failed to open sec meta iterator", K(ret)); } else { @@ -180,10 +212,10 @@ int ObBackupUtils::fetch_macro_block_logic_id_list(const storage::ObTabletHandle int ObBackupUtils::report_task_result(const int64_t job_id, const int64_t task_id, const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, const share::ObTaskId trace_id, - const int64_t result, ObBackupReportCtx &report_ctx) + const share::ObTaskId &dag_id, const int64_t result, ObBackupReportCtx &report_ctx) { int ret = OB_SUCCESS; - common::ObAddr rs_addr; + common::ObAddr leader_addr; obrpc::ObBackupTaskRes backup_ls_res; backup_ls_res.job_id_ = job_id; backup_ls_res.task_id_ = task_id; @@ -192,6 +224,9 @@ int ObBackupUtils::report_task_result(const int64_t job_id, const int64_t task_i backup_ls_res.ls_id_ = ls_id; backup_ls_res.result_ = result; backup_ls_res.trace_id_ = trace_id; + backup_ls_res.dag_id_ = dag_id; + const int64_t cluster_id = GCONF.cluster_id; + const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id); #ifdef ERRSIM ret = OB_E(EventTable::EN_BACKUP_META_REPORT_RESULT_FAILED) OB_SUCCESS; @@ -205,9 +240,10 @@ int ObBackupUtils::report_task_result(const int64_t job_id, const int64_t task_i || trace_id.is_invalid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(job_id), K(task_id), K(tenant_id), K(ls_id)); - } else if (OB_FAIL(report_ctx.rs_mgr_->get_master_root_server(rs_addr))) { - LOG_WARN("failed to get rootservice address", K(ret)); - } else if (OB_FAIL(report_ctx.rs_rpc_proxy_->to(rs_addr).backup_ls_data_res(backup_ls_res))) { + } else if (OB_FAIL(report_ctx.location_service_->get_leader_with_retry_until_timeout( + cluster_id, meta_tenant_id, ObLSID(ObLSID::SYS_LS_ID), leader_addr))) { + LOG_WARN("failed to get leader address", K(ret)); + } else if (OB_FAIL(report_ctx.rpc_proxy_->to(leader_addr).report_backup_over(backup_ls_res))) { LOG_WARN("failed to post backup ls data res", K(ret), K(backup_ls_res)); } else { SERVER_EVENT_ADD("backup_data", "report_result", @@ -352,9 +388,9 @@ int ObBackupUtils::check_ls_valid_for_backup(const uint64_t tenant_id, const sha } else if (OB_ISNULL(ls = handle.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream not exist", K(ret), K(ls_id)); - } else if (ls->is_stopped()) { + } else if (ls->is_stopped() || ls->is_offline()) { ret = OB_REPLICA_CANNOT_BACKUP; - LOG_WARN("ls has stopped, can not backup", K(ret), K(tenant_id), K(ls_id)); + LOG_WARN("ls has stopped or offline, can not backup", K(ret), K(tenant_id), K(ls_id)); } else if (OB_FAIL(ls->get_ls_meta(ls_meta))) { LOG_WARN("failed to get ls meta", K(ret), K(tenant_id), K(ls_id)); } else if (OB_FAIL(ls_meta.check_valid_for_backup())) { @@ -1649,6 +1685,9 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar total_count = 0; ObArray sstable_array; ObTabletHandle tablet_handle; + bool is_normal = false; + bool can_explain = false; + ObTabletMemberWrapper table_store_wrapper; if (OB_ISNULL(ls_backup_ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls backup ctx should not be null", K(ret)); @@ -1662,7 +1701,7 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar ObBackupSkippedType skipped_type(ObBackupSkippedType::MAX_TYPE); if (OB_FAIL(get_tablet_skipped_type_(param_.tenant_id_, ls_id, tablet_id, skipped_type))) { LOG_WARN("failed to get tablet skipped type", K(ret), K(param_), K(ls_id), K(tablet_id)); - } else if (OB_FAIL(report_tablet_skipped_(tablet_id, skipped_type))) { + } else if (OB_FAIL(report_tablet_skipped_(tablet_id, skipped_type, backup_data_type))) { LOG_WARN("failed to report tablet skipped", K(ret), K(tablet_id), K_(param), K(skipped_type)); } else { LOG_INFO("report tablet skipped", K(ret), K(tablet_id), K_(param), K(skipped_type)); @@ -1672,11 +1711,19 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar } } else if (OB_FAIL(check_tablet_continuity_(ls_id, tablet_id, tablet_handle))) { LOG_WARN("failed to check tablet continuity", K(ret), K(ls_id), K(tablet_id), K(tablet_handle)); + } else if (OB_FAIL(check_tx_data_can_explain_user_data_(tablet_handle, can_explain))) { + LOG_WARN("failed to check tx data can explain user data", K(ret), K(ls_id), K(tablet_id)); + } else if (!can_explain) { + ret = OB_REPLICA_CANNOT_BACKUP; + LOG_WARN("can not backup replica", K(ret), K(tablet_id), K(ls_id)); } else if (OB_FAIL(check_tablet_replica_validity_(tenant_id, ls_id, tablet_id, backup_data_type))) { LOG_WARN("failed to check tablet replica validity", K(ret), K(tenant_id), K(ls_id), K(tablet_id), K(backup_data_type)); } else if (OB_FAIL(hold_tablet_handle_(tablet_id, tablet_handle))) { LOG_WARN("failed to hold tablet handle", K(ret), K(tablet_id), K(tablet_handle)); - } else if (OB_FAIL(fetch_tablet_sstable_array_(tablet_id, tablet_handle, backup_data_type, sstable_array))) { + } else if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(fetch_tablet_sstable_array_( + tablet_id, tablet_handle, *table_store_wrapper.get_member(), backup_data_type, sstable_array))) { LOG_WARN("failed to fetch tablet sstable array", K(ret), K(tablet_id), K(tablet_handle), K(backup_data_type)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < sstable_array.count(); ++i) { @@ -1717,6 +1764,90 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar return ret; } +int ObBackupTabletProvider::check_tx_data_can_explain_user_data_( + const storage::ObTabletHandle &tablet_handle, + bool &can_explain) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + ObTabletMemberWrapper table_store_wrapper; + can_explain = true; + // Only backup minor needs to check whether tx data can explain user data. + // If tablet has no minor sstable, or has no uncommitted row in sstable, it's also no need to check tx_data. + // The condition that tx_data can explain user data is that tx_data_table's filled_tx_scn is less than the + // minimum tablet's minor sstable's filled_tx_scn. + // TODO(chongrong.th): But when transfer supports not killing transaction, minor sstable may have uncommitted rows and it's + // filled_tx_scn may less than tx_data_table's filled_tx_scn, which is a bad case. Fix this in future by handora.qc. + + if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is nullptr.", K(ret), K(tablet_handle)); + } else if (!ls_backup_ctx_->backup_data_type_.is_minor_backup()) { + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (table_store_wrapper.get_member()->get_minor_sstables().empty()) { + } else { + const ObSSTableArray &sstable_array = table_store_wrapper.get_member()->get_minor_sstables(); + share::SCN min_filled_tx_scn = SCN::max_scn(); + ARRAY_FOREACH(sstable_array, i) { + ObITable *table_ptr = sstable_array[i]; + ObSSTable *sstable = NULL; + ObSSTableMetaHandle sst_meta_hdl; + if (OB_ISNULL(table_ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table ptr should not be null", K(ret)); + } else if (!table_ptr->is_sstable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table ptr type not expectedd", K(ret)); + } else if (FALSE_IT(sstable = static_cast(table_ptr))) { + } else if (OB_FAIL(sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta", K(ret)); + } else if (!sst_meta_hdl.get_sstable_meta().contain_uncommitted_row()) { // just skip. + // ls inner tablet and tablet created by transfer after backfill has no uncommited row. + } else { + min_filled_tx_scn = std::min( + std::max(sst_meta_hdl.get_sstable_meta().get_filled_tx_scn(), sstable->get_end_scn()), min_filled_tx_scn); + } + } + if (OB_SUCC(ret)) { + can_explain = min_filled_tx_scn >= ls_backup_ctx_->backup_tx_table_filled_tx_scn_; + if (!can_explain) { + const ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; + LOG_WARN("tx data can't explain user data", + K(OB_REPLICA_CANNOT_BACKUP), K(can_explain), + K(tablet_id), K(min_filled_tx_scn), + "backup_tx_table_filled_tx_scn", ls_backup_ctx_->backup_tx_table_filled_tx_scn_); + } + } + } + return ret; +} + +int ObBackupTabletProvider::get_consistent_scn_(share::SCN &consistent_scn) const +{ + int ret = OB_SUCCESS; + ObBackupSetFileDesc backup_set_file; + if (backup_data_type_.is_sys_backup()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("need not get consistent scn during backup inner tablets", K(ret), K_(param), K_(backup_data_type)); + } else if (OB_FAIL(ObBackupSetFileOperator::get_backup_set_file( + *sql_proxy_, + false/*for update*/, + param_.backup_set_desc_.backup_set_id_, + OB_START_INCARNATION, + param_.tenant_id_, + param_.dest_id_, + backup_set_file))) { + LOG_WARN("failed to get backup set", K(ret), K_(param), K_(backup_data_type)); + } else if (OB_FALSE_IT(consistent_scn = backup_set_file.consistent_scn_)) { + } else if (!consistent_scn.is_valid_and_not_min()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("consistent scn is not valid", K(ret), K_(param), K_(backup_data_type), K(backup_set_file)); + } + + return ret; +} + int ObBackupTabletProvider::get_tablet_handle_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, ObTabletHandle &tablet_handle) { @@ -1734,7 +1865,6 @@ int ObBackupTabletProvider::get_tablet_handle_(const uint64_t tenant_id, const s ObLS *ls = NULL; ObLSHandle ls_handle; ObLSService *ls_svr = NULL; - const int64_t timeout_us = ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US; if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("MTL ObLSService is null", K(ret), K(tenant_id)); @@ -1745,13 +1875,31 @@ int ObBackupTabletProvider::get_tablet_handle_(const uint64_t tenant_id, const s LOG_WARN("LS is null", K(ret)); } else if (OB_FAIL(ObBackupUtils::check_ls_valid_for_backup(tenant_id, ls_id, rebuild_seq))) { LOG_WARN("failed to check ls valid for backup", K(ret), K(tenant_id), K(ls_id), K(rebuild_seq)); - } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, timeout_us))) { - LOG_WARN("failed to get tablet handle", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); - } else if (ObTabletStatus::MAX == tablet_handle.get_obj()->get_tablet_meta().tx_data_.tablet_status_) { - ret = OB_EAGAIN; - LOG_WARN("tablet meta still MAX, try later", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); - } else if (OB_FAIL(ObBackupUtils::check_ls_valid_for_backup(tenant_id, ls_id, rebuild_seq))) { - LOG_WARN("failed to check ls valid for backup", K(ret), K(tenant_id), K(ls_id), K(rebuild_seq)); + } else { + // sync wait transfer in tablet replace table finish + const int64_t ABS_TIMEOUT_TS = ObTimeUtil::current_time() + 5 * 60 * 1000 * 1000; //5min + while (OB_SUCC(ret)) { + tablet_handle.reset(); + if (ABS_TIMEOUT_TS < ObTimeUtil::current_time()) { + ret = OB_TIMEOUT; + LOG_WARN("backup get tablet handle timeout", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle))) {// read readble commited, only get NORMAL and TRANSFER IN tablet. + LOG_WARN("failed to get tablet handle", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(ObBackupUtils::check_ls_valid_for_backup(tenant_id, ls_id, rebuild_seq))) { + LOG_WARN("failed to check ls valid for backup", K(ret), K(tenant_id), K(ls_id), K(rebuild_seq)); + } else if (tablet_id.is_ls_inner_tablet()) { + // do nothing + // Data of inner tablets is backed up with meta at the same replica. And. + // the clog_checkpoint_scn < consistent_scn is allowed. + break; + } else if (tablet_handle.get_obj()->get_tablet_meta().has_transfer_table()) { + LOG_INFO("transfer table is not replaced", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); + usleep(100 * 1000); // wait 100ms + } else { + // TODO:(wangxiaohui.wxh): make sure clog checkpoint scn of tablet is over consistent_scn + break; + } + } } } } @@ -1807,7 +1955,7 @@ int ObBackupTabletProvider::get_tablet_skipped_type_(const uint64_t tenant_id, c ret = OB_REPLICA_CANNOT_BACKUP; LOG_WARN("ls has stopped, can not backup", K(ret), K(tenant_id), K(ls_id)); } else { - ret = OB_ERR_UNEXPECTED; + ret = OB_EAGAIN; LOG_WARN("tablet not exist, but __all_tablet_to_ls still exist", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); } @@ -1824,7 +1972,8 @@ int ObBackupTabletProvider::get_tablet_skipped_type_(const uint64_t tenant_id, c } int ObBackupTabletProvider::report_tablet_skipped_(const common::ObTabletID &tablet_id, - const share::ObBackupSkippedType &skipped_type) + const share::ObBackupSkippedType &skipped_type, + const share::ObBackupDataType &backup_data_type) { int ret = OB_SUCCESS; ObBackupSkippedTablet skipped_tablet; @@ -1836,6 +1985,7 @@ int ObBackupTabletProvider::report_tablet_skipped_(const common::ObTabletID &tab skipped_tablet.backup_set_id_ = param_.backup_set_desc_.backup_set_id_; skipped_tablet.ls_id_ = param_.ls_id_; skipped_tablet.skipped_type_ = skipped_type; + skipped_tablet.data_type_ = backup_data_type; if (!tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(tablet_id)); @@ -1866,22 +2016,18 @@ int ObBackupTabletProvider::hold_tablet_handle_( } int ObBackupTabletProvider::fetch_tablet_sstable_array_(const common::ObTabletID &tablet_id, - const storage::ObTabletHandle &tablet_handle, const share::ObBackupDataType &backup_data_type, - common::ObIArray &sstable_array) + const storage::ObTabletHandle &tablet_handle, const ObTabletTableStore &table_store, + const share::ObBackupDataType &backup_data_type, common::ObIArray &sstable_array) { int ret = OB_SUCCESS; sstable_array.reset(); if (!tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(tablet_id)); + } else if (OB_FAIL(ObBackupUtils::get_sstables_by_data_type(tablet_handle, backup_data_type, table_store, sstable_array))) { + LOG_WARN("failed to get sstables by data type", K(ret), K(tablet_handle), K(backup_data_type), K(table_store)); } else { - ObTablet &tablet = *tablet_handle.get_obj(); - ObTabletTableStore &table_store = tablet.get_table_store(); - if (OB_FAIL(ObBackupUtils::get_sstables_by_data_type(tablet_handle, backup_data_type, table_store, sstable_array))) { - LOG_WARN("failed to get sstables by data type", K(ret), K(tablet_handle), K(backup_data_type), K(table_store)); - } else { - LOG_INFO("fetch tablet sstable array", K(ret), K(tablet_id), K(backup_data_type), K(sstable_array)); - } + LOG_INFO("fetch tablet sstable array", K(ret), K(tablet_id), K(backup_data_type), K(sstable_array)); } return ret; } @@ -2082,6 +2228,21 @@ int ObBackupTabletProvider::inner_check_macro_block_need_skip_(const blocksstabl return ret; } +int ObBackupTabletProvider::check_tablet_status_(const storage::ObTabletHandle &tablet_handle, bool &is_normal) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = tablet_handle.get_obj(); + ObTabletCreateDeleteMdsUserData user_data; + is_normal = false; + if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet status", KPC(tablet)); + } else if (user_data.get_tablet_status() == ObTabletStatus::NORMAL) { + is_normal = true; + } + LOG_INFO("check tablet status", K(ret), "tablet_id", tablet->get_tablet_meta().tablet_id_, K(is_normal), K(user_data)); + return ret; +} + int ObBackupTabletProvider::check_tablet_continuity_(const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const storage::ObTabletHandle &tablet_handle) { @@ -2094,7 +2255,7 @@ int ObBackupTabletProvider::check_tablet_continuity_(const share::ObLSID &ls_id, share::ObBackupPath backup_path; if (!backup_data_type_.is_major_backup()) { // do nothing - } else if (OB_FAIL(build_meta_index_store_(backup_data_type))) { + } else if (OB_FAIL(build_tenant_meta_index_store_(backup_data_type))) { LOG_WARN("failed to init meta index store", K(ret)); } else if (OB_FAIL(meta_index_store_.get_backup_meta_index(tablet_id, meta_type, tablet_meta_index))) { LOG_WARN("failed to get backup meta index", K(ret), K(tablet_id)); @@ -2134,7 +2295,7 @@ int ObBackupTabletProvider::check_tablet_continuity_(const share::ObLSID &ls_id, return ret; } -int ObBackupTabletProvider::build_meta_index_store_(const share::ObBackupDataType &backup_data_type) +int ObBackupTabletProvider::build_tenant_meta_index_store_(const share::ObBackupDataType &backup_data_type) { int ret = OB_SUCCESS; ObBackupRestoreMode mode = BACKUP_MODE; @@ -2146,11 +2307,12 @@ int ObBackupTabletProvider::build_meta_index_store_(const share::ObBackupDataTyp index_store_param.ls_id_ = param_.ls_id_; index_store_param.is_tenant_level_ = true; index_store_param.backup_data_type_ = backup_data_type; - index_store_param.turn_id_ = param_.turn_id_; int64_t retry_id = 0; if (meta_index_store_.is_inited()) { // do nothing - } else if (OB_FAIL(get_tenant_meta_index_retry_id_(backup_data_type, retry_id))) { + } else if (OB_FAIL(get_tenant_meta_index_turn_id_(index_store_param.turn_id_))) { + LOG_WARN("failed to find meta index turn id", K(ret), K(backup_data_type)); + } else if (OB_FAIL(get_tenant_meta_index_retry_id_(backup_data_type, index_store_param.turn_id_, retry_id))) { LOG_WARN("failed to find meta index retry id", K(ret), K(backup_data_type)); } else if (FALSE_IT(index_store_param.retry_id_ = retry_id)) { // assign @@ -2165,8 +2327,20 @@ int ObBackupTabletProvider::build_meta_index_store_(const share::ObBackupDataTyp return ret; } +int ObBackupTabletProvider::get_tenant_meta_index_turn_id_(int64_t &turn_id) +{ + int ret = OB_SUCCESS; + ObBackupSetTaskAttr set_task_attr; + if (OB_FAIL(share::ObBackupTaskOperator::get_backup_task(*GCTX.sql_proxy_, param_.job_id_, param_.tenant_id_, false, set_task_attr))) { + LOG_WARN("failed to get backup task", K(ret)); + } else { + turn_id = set_task_attr.minor_turn_id_; + } + return ret; +} + int ObBackupTabletProvider::get_tenant_meta_index_retry_id_( - const share::ObBackupDataType &backup_data_type, int64_t &retry_id) + const share::ObBackupDataType &backup_data_type, const int64_t turn_id, int64_t &retry_id) { int ret = OB_SUCCESS; const bool is_restore = false; @@ -2174,8 +2348,8 @@ int ObBackupTabletProvider::get_tenant_meta_index_retry_id_( const bool is_sec_meta = false; ObBackupTenantIndexRetryIDGetter retry_id_getter; if (OB_FAIL(retry_id_getter.init(param_.backup_dest_, param_.backup_set_desc_, - backup_data_type, param_.turn_id_, is_restore, is_macro_index, is_sec_meta))) { - LOG_WARN("failed to init retry id getter", K(ret), K_(param)); + backup_data_type, turn_id, is_restore, is_macro_index, is_sec_meta))) { + LOG_WARN("failed to init retry id getter", K(ret), K(turn_id), K_(param)); } else if (OB_FAIL(retry_id_getter.get_max_retry_id(retry_id))) { LOG_WARN("failed to get max retry id", K(ret)); } diff --git a/src/storage/backup/ob_backup_utils.h b/src/storage/backup/ob_backup_utils.h old mode 100644 new mode 100755 index 3c6aeed27..4ba3c1b1e --- a/src/storage/backup/ob_backup_utils.h +++ b/src/storage/backup/ob_backup_utils.h @@ -30,6 +30,14 @@ #include "storage/blocksstable/ob_logic_macro_id.h" namespace oceanbase { +namespace storage +{ +struct ObBackupLSMetaInfosDesc; +} +namespace share +{ +class SCN; +} namespace backup { struct ObLSBackupCtx; @@ -39,15 +47,18 @@ class ObBackupMacroBlockIndexStore; class ObBackupUtils { public: static int get_sstables_by_data_type(const storage::ObTabletHandle &tablet_handle, const share::ObBackupDataType &backup_data_type, - storage::ObTabletTableStore &table_store, common::ObIArray &sstable_array); + const storage::ObTabletTableStore &table_store, common::ObIArray &sstable_array); static int check_tablet_with_major_sstable(const storage::ObTabletHandle &tablet_handle, bool &with_major); static int fetch_macro_block_logic_id_list(const storage::ObTabletHandle &tablet_handle, const blocksstable::ObSSTable &sstable, common::ObIArray &logic_id_list); static int report_task_result(const int64_t job_id, const int64_t task_id, const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t turn_id, const int64_t retry_id, const share::ObTaskId trace_id, - const int64_t result, ObBackupReportCtx &report_ctx); + const share::ObTaskId &dag_id, const int64_t result, ObBackupReportCtx &report_ctx); static int check_ls_validity(const uint64_t tenant_id, const share::ObLSID &ls_id); static int check_ls_valid_for_backup(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t local_rebuild_seq); + static int calc_start_replay_scn(const share::ObBackupSetTaskAttr &set_task_attr, + const storage::ObBackupLSMetaInfosDesc &ls_meta_infos, const share::ObTenantArchiveRoundAttr &round_attr, + share::SCN &start_replay_scn); private: static int check_tablet_minor_sstable_validity_(const storage::ObTabletHandle &tablet_handle, const common::ObIArray &minor_sstable_array); @@ -269,14 +280,19 @@ private: int prepare_batch_tablet_(const uint64_t tenant_id, const share::ObLSID &ls_id); int prepare_tablet_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const share::ObBackupDataType &backup_data_type, int64_t &count); + + // make sure clog checkpoint scn of the returned tablet is >= consistent_scn. int get_tablet_handle_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle); + int get_consistent_scn_(share::SCN &consistent_scn) const; + int report_tablet_skipped_(const common::ObTabletID &tablet_id, const share::ObBackupSkippedType &skipped_type, + const share::ObBackupDataType &backup_data_type); int get_tablet_skipped_type_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, share::ObBackupSkippedType &skipped_type); - int report_tablet_skipped_(const common::ObTabletID &tablet_id, const share::ObBackupSkippedType &skipped_type); int hold_tablet_handle_(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle); int fetch_tablet_sstable_array_(const common::ObTabletID &tablet_id, const storage::ObTabletHandle &tablet_handle, - const share::ObBackupDataType &backup_data_type, common::ObIArray &sstable_array); + const ObTabletTableStore &table_store, const share::ObBackupDataType &backup_data_type, + common::ObIArray &sstable_array); int prepare_tablet_logic_id_reader_(const common::ObTabletID &tablet_id, const storage::ObTabletHandle &tablet_handle, const storage::ObITable::TableKey &table_key, const blocksstable::ObSSTable &sstable, ObITabletLogicMacroIdReader *&reader); @@ -290,10 +306,14 @@ private: int check_macro_block_need_skip_(const blocksstable::ObLogicMacroBlockId &logic_id, bool &need_skip); int inner_check_macro_block_need_skip_(const blocksstable::ObLogicMacroBlockId &logic_id, const common::ObArray &reused_pair_list, bool &need_skip); + int check_tablet_status_(const storage::ObTabletHandle &tablet_handle, bool &is_normal); int check_tablet_continuity_(const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const storage::ObTabletHandle &tablet_handle); - int build_meta_index_store_(const share::ObBackupDataType &backup_data_type); - int get_tenant_meta_index_retry_id_(const share::ObBackupDataType &backup_data_type, int64_t &retry_id); + int check_tx_data_can_explain_user_data_(const storage::ObTabletHandle &tablet_handle, bool &can_explain); + int build_tenant_meta_index_store_(const share::ObBackupDataType &backup_data_type); + int get_tenant_meta_index_turn_id_(int64_t &turn_id); + int get_tenant_meta_index_retry_id_(const share::ObBackupDataType &backup_data_type, + const int64_t turn_id, int64_t &retry_id); int check_tablet_replica_validity_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const share::ObBackupDataType &backup_data_type); int compare_prev_item_(const ObBackupProviderItem &item); diff --git a/src/storage/backup/ob_ls_backup_clean_mgr.cpp b/src/storage/backup/ob_ls_backup_clean_mgr.cpp index feaec4149..711227dcf 100644 --- a/src/storage/backup/ob_ls_backup_clean_mgr.cpp +++ b/src/storage/backup/ob_ls_backup_clean_mgr.cpp @@ -12,7 +12,6 @@ #define USING_LOG_PREFIX STORAGE #include "ob_ls_backup_clean_mgr.h" -#include "share/backup/ob_log_archive_backup_info_mgr.h" #include "share/backup/ob_backup_clean_operator.h" #include "share/backup/ob_backup_data_table_operator.h" #include "share/backup/ob_backup_clean_operator.h" @@ -21,6 +20,8 @@ #include "share/backup/ob_backup_clean_util.h" #include "share/backup/ob_archive_path.h" #include "share/backup/ob_backup_connectivity.h" +#include "share/location_cache/ob_location_service.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" namespace oceanbase { @@ -32,7 +33,6 @@ int ObLSBackupCleanScheduler::schedule_backup_clean_dag(const obrpc::ObLSBackupC { int ret = OB_SUCCESS; ObLSBackupCleanDagNetInitParam param; - ObLSBackupCleanDagNet *clean_dag_net = nullptr; MTL_SWITCH(args.tenant_id_) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler *); if (OB_ISNULL(scheduler)) { @@ -40,7 +40,7 @@ int ObLSBackupCleanScheduler::schedule_backup_clean_dag(const obrpc::ObLSBackupC LOG_WARN("unexpected null MTL scheduler", K(ret), K(scheduler)); } else if (OB_FAIL(param.set(args))) { LOG_WARN("failed to set ls backup clean net init param",K(ret), K(args)); - } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m, clean_dag_net))) { + } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m))) { if (OB_TASK_EXIST == ret) { ret = OB_SUCCESS; LOG_INFO("[BACKUP_CLEAN]alreadly have log stream backup dag net in DagScheduler", K(ret)); @@ -289,20 +289,19 @@ ObLSBackupCleanDag::~ObLSBackupCleanDag() { } -int ObLSBackupCleanDag::fill_comment(char *buf, const int64_t buf_len) const +int ObLSBackupCleanDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("ls backup clean dag do not init", K(ret)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "tenant_id=%lu, task_id=%ld, ls_id=%ld, task_type=%s, id=%ld", - param_.tenant_id_, - param_.task_id_, - param_.ls_id_.id(), - share::ObBackupCleanTaskType::get_str(param_.task_type_), - param_.id_))) { - LOG_WARN("failed to fill comment", K(ret), K_(param)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(param_.tenant_id_), + static_cast(param_.task_id_), + param_.ls_id_.id(), + static_cast(param_.id_), + "task_type", share::ObBackupCleanTaskType::get_str(param_.task_type_)))) { + LOG_WARN("failed to add dag warning info param", K(ret)); } return ret; } @@ -488,7 +487,7 @@ int ObLSBackupCleanTask::process() int ObLSBackupCleanTask::post_rpc_result_(const int64_t result) { int ret = OB_SUCCESS; - common::ObAddr rs_addr; + common::ObAddr leader_addr; obrpc::ObBackupTaskRes clean_ls_res; clean_ls_res.job_id_ = job_id_; clean_ls_res.task_id_ = task_id_; @@ -497,12 +496,15 @@ int ObLSBackupCleanTask::post_rpc_result_(const int64_t result) clean_ls_res.ls_id_ = ls_id_; clean_ls_res.result_ = result; clean_ls_res.trace_id_ = trace_id_; - if (OB_ISNULL(GCTX.rs_rpc_proxy_) || OB_ISNULL(GCTX.rs_mgr_)) { + const int64_t cluster_id = GCONF.cluster_id; + const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id_); + if (OB_ISNULL(GCTX.srv_rpc_proxy_) || OB_ISNULL(GCTX.location_service_)) { ret = OB_ERR_SYS; LOG_WARN("rootserver rpc proxy or rs mgr must not be NULL", K(ret), K(GCTX)); - } else if (OB_FAIL(GCTX.rs_mgr_->get_master_root_server(rs_addr))) { - LOG_WARN("failed to get rootservice address", K(ret)); - } else if (OB_FAIL(GCTX.rs_rpc_proxy_->to(rs_addr).delete_backup_ls_task_res(clean_ls_res))) { + } else if (OB_FAIL(GCTX.location_service_->get_leader_with_retry_until_timeout( + cluster_id, meta_tenant_id, ObLSID(ObLSID::SYS_LS_ID), leader_addr))) { + LOG_WARN("failed to get leader address", K(ret)); + } else if (OB_FAIL(GCTX.srv_rpc_proxy_->to(leader_addr).report_backup_clean_over(clean_ls_res))) { LOG_WARN("failed to post backup ls data res", K(ret), K(clean_ls_res)); } else { LOG_INFO("[BACKUP_CLEAN] success finish task post rpc result", K(clean_ls_res)); diff --git a/src/storage/backup/ob_ls_backup_clean_mgr.h b/src/storage/backup/ob_ls_backup_clean_mgr.h index bac9a0bb3..e8c55a09c 100644 --- a/src/storage/backup/ob_ls_backup_clean_mgr.h +++ b/src/storage/backup/ob_ls_backup_clean_mgr.h @@ -95,7 +95,7 @@ public: virtual bool operator == (const ObIDag &other) const override; virtual int64_t hash() const override; virtual int init(share::ObIDagNet *dag_net); - virtual int fill_comment(char *buf, const int64_t buf_len) const; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual lib::Worker::CompatMode get_compat_mode() const override { return lib::Worker::CompatMode::MYSQL; } diff --git a/src/storage/blocksstable/encoding/ob_micro_block_decoder.cpp b/src/storage/blocksstable/encoding/ob_micro_block_decoder.cpp index d26dd23f3..39b0e588b 100644 --- a/src/storage/blocksstable/encoding/ob_micro_block_decoder.cpp +++ b/src/storage/blocksstable/encoding/ob_micro_block_decoder.cpp @@ -452,10 +452,7 @@ int ObIEncodeBlockReader::do_init( } else { request_cnt_ = request_cnt; - if (OB_FAIL(get_micro_metas(header_, col_header_, meta_data_, - block_data.get_buf(), block_data.get_buf_size()))) { - LOG_WARN("get micro block meta failed", K(ret), K(block_data), KPC(header_)); - } else if (nullptr == allocator_ && OB_ISNULL(allocator_ = get_decoder_allocator())) { + if (nullptr == allocator_ && OB_ISNULL(allocator_ = get_decoder_allocator())) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("get decoder allocator failed", K(ret)); } else if (OB_ISNULL(ctx_array_ = ObTLDecoderCtxArray::alloc())) { @@ -655,7 +652,7 @@ void ObEncodeBlockGetReader::reuse() int ObEncodeBlockGetReader::init_by_read_info( const ObMicroBlockData &block_data, - const ObTableReadInfo &read_info) + const ObITableReadInfo &read_info) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!block_data.is_valid() || @@ -666,17 +663,33 @@ int ObEncodeBlockGetReader::init_by_read_info( const int64_t request_cnt = read_info.get_request_count(); if (OB_FAIL(prepare(MTL_ID(), request_cnt))) { LOG_WARN("prepare fail", K(ret), K(request_cnt)); + } else if (OB_FAIL(get_micro_metas(header_, col_header_, meta_data_, + block_data.get_buf(), block_data.get_buf_size()))) { + LOG_WARN("get micro block meta failed", K(ret), K(block_data), KPC(header_)); + } else if (typeid(ObRowkeyReadInfo) == typeid(read_info)) { + ObObjMeta col_type; + int64_t i = 0; + for (; i < header_->column_count_; ++i) { + col_type.set_type(static_cast(col_header_[i].obj_type_)); + store_id_array_[i] = i; + column_type_array_[i] = col_type; + } + for (; i < request_cnt; ++i) { + col_type.set_type(ObNullType); + store_id_array_[i] = i; + column_type_array_[i] = col_type; + } } else { const ObColDescIArray &cols_desc = read_info.get_columns_desc(); - const common::ObIArray &cols_index = read_info.get_columns_index(); + const ObColumnIndexArray &cols_index = read_info.get_columns_index(); for (int64_t idx = 0; idx < request_cnt; idx++) { store_id_array_[idx] = cols_index.at(idx); column_type_array_[idx] = cols_desc.at(idx).col_type_; } + } - if (OB_FAIL(do_init(block_data, request_cnt))) { - LOG_WARN("failed to do init", K(ret), K(block_data), K(request_cnt)); - } + if (OB_SUCC(ret) && OB_FAIL(do_init(block_data, request_cnt))) { + LOG_WARN("failed to do init", K(ret), K(block_data), K(request_cnt)); } } return ret; @@ -685,7 +698,7 @@ int ObEncodeBlockGetReader::init_by_read_info( int ObEncodeBlockGetReader::get_row( const ObMicroBlockData &block_data, const ObDatumRowkey &rowkey, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, ObDatumRow &row) { int ret = OB_SUCCESS; @@ -826,7 +839,10 @@ int ObEncodeBlockGetReader::init_by_columns_desc( store_id_array_[idx] = idx; column_type_array_[idx] = cols_desc.at(idx).col_type_; } - if (OB_FAIL(do_init(block_data, request_cnt))) { + if (OB_FAIL(get_micro_metas(header_, col_header_, meta_data_, + block_data.get_buf(), block_data.get_buf_size()))) { + LOG_WARN("get micro block meta failed", K(ret), K(block_data), KPC(header_)); + } else if (OB_FAIL(do_init(block_data, request_cnt))) { LOG_WARN("failed to do init", K(ret), K(block_data), K(request_cnt)); } } @@ -836,7 +852,7 @@ int ObEncodeBlockGetReader::init_by_columns_desc( int ObEncodeBlockGetReader::exist_row( const ObMicroBlockData &block_data, const ObDatumRowkey &rowkey, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, bool &exist, bool &found) { @@ -886,15 +902,14 @@ ObMicroBlockDecoder::ObMicroBlockDecoder() row_index_(&var_row_index_), decoder_buf_(nullptr), decoders_(nullptr), - rowkey_decoder_(nullptr), need_release_decoders_(), need_release_decoder_cnt_(0), flat_row_reader_(), allocator_(nullptr), ctx_array_(nullptr), ctxs_(nullptr), - decoder_allocator_(SET_USE_500(ObModIds::OB_DECODER_CTX)), - buf_allocator_(SET_USE_500("OB_MICB_DECODER")) + decoder_allocator_(ObModIds::OB_DECODER_CTX, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()), + buf_allocator_("OB_MICB_DECODER", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()) { need_release_decoders_.set_allocator(&buf_allocator_); } @@ -1087,7 +1102,6 @@ void ObMicroBlockDecoder::inner_reset() free_decoders(); cached_decoder_ = NULL; header_ = NULL; - rowkey_decoder_ = decoders_; col_header_ = NULL; meta_data_ = NULL; row_data_ = NULL; @@ -1115,12 +1129,20 @@ void ObMicroBlockDecoder::reset() int ObMicroBlockDecoder::init_decoders() { int ret = OB_SUCCESS; - if (OB_UNLIKELY(NULL == read_info_ || NULL == header_ || NULL == col_header_ || - !read_info_->is_valid())) { + if (OB_UNLIKELY(NULL == header_ || NULL == col_header_ || + (NULL != read_info_ && !read_info_->is_valid()))) { ret = OB_INNER_STAT_ERROR; LOG_WARN("header should be set while init decoders", K(ret), KPC_(read_info), KP_(header), KP_(col_header)); + } else if (OB_FAIL(need_release_decoders_.reserve(request_cnt_ * 2))) { + LOG_WARN("fail to init release decoders", K(ret), K(request_cnt_)); + } else if (OB_ISNULL(decoder_buf_) && + OB_ISNULL(decoder_buf_ = buf_allocator_.alloc((request_cnt_) * sizeof(ObColumnDecoder)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc decoder_buf_ memory", K(ret)); } else { + decoders_ = reinterpret_cast(decoder_buf_); + // perfetch meta data /* const int64_t meta_len = row_data_ - meta_data_; @@ -1128,14 +1150,25 @@ int ObMicroBlockDecoder::init_decoders() __builtin_prefetch(meta_data_ + i); } */ - const common::ObIArray &cols_index = read_info_->get_columns_index(); - const ObColDescIArray &cols_desc = read_info_->get_columns_desc(); - for (int64_t i = 0; OB_SUCC(ret) && i < request_cnt_; ++i) { - if (OB_FAIL(add_decoder( - cols_index.at(i), - cols_desc.at(i).col_type_, - decoders_[i]))) { - LOG_WARN("add_decoder failed", K(ret), "request_idx", i); + if (OB_ISNULL(read_info_) || typeid(ObRowkeyReadInfo) == typeid(*read_info_)) { + ObObjMeta col_type; + const int64_t col_cnt = MIN(request_cnt_, header_->column_count_); + for (int64_t i = 0; OB_SUCC(ret) && i < col_cnt; ++i) { + col_type.set_type(static_cast(col_header_[i].obj_type_)); + if (OB_FAIL(add_decoder(i, col_type, decoders_[i]))) { + LOG_WARN("add_decoder failed", K(ret), K(i), K(col_type)); + } + } + } else { + const ObColumnIndexArray &cols_index = read_info_->get_columns_index(); + const ObColDescIArray &cols_desc = read_info_->get_columns_desc(); + for (int64_t i = 0; OB_SUCC(ret) && i < request_cnt_; ++i) { + if (OB_FAIL(add_decoder( + cols_index.at(i), + cols_desc.at(i).col_type_, + decoders_[i]))) { + LOG_WARN("add_decoder failed", K(ret), "request_idx", i); + } } } @@ -1216,7 +1249,7 @@ int ObMicroBlockDecoder::get_micro_metas( int ObMicroBlockDecoder::init( const ObMicroBlockData &block_data, - const ObTableReadInfo &read_info) + const ObITableReadInfo &read_info) { int ret = OB_SUCCESS; // can be init twice @@ -1234,52 +1267,42 @@ int ObMicroBlockDecoder::init( } } read_info_ = &read_info; + datum_utils_ = &(read_info_->get_datum_utils()); request_cnt_ = read_info.get_request_count(); - if (OB_FAIL(need_release_decoders_.reserve(request_cnt_ * 2))) { - LOG_WARN("fail to init release decoders", K(ret), K(request_cnt_)); - } else if (OB_ISNULL(decoder_buf_) && - OB_ISNULL(decoder_buf_ = buf_allocator_.alloc((request_cnt_) * sizeof(ObColumnDecoder)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc decoder_buf_ memory", K(ret)); - } else { - decoders_ = reinterpret_cast(decoder_buf_); - } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(do_init(block_data))) { + if (OB_FAIL(do_init(block_data))) { LOG_WARN("do init failed", K(ret)); - } else { - const int64_t schema_rowkey_cnt = read_info.get_schema_rowkey_count(); - const common::ObIArray &cols_index = read_info.get_columns_index(); - rowkey_decoder_ = reinterpret_cast(rowkey_decoder_buf_); - MEMSET(rowkey_decoder_, 0, sizeof(*rowkey_decoder_) * schema_rowkey_cnt); - for (int64_t i = 0; i < request_cnt_; i++) { - const int64_t idx = cols_index.at(i); - if (idx >= 0 && idx < schema_rowkey_cnt) { - rowkey_decoder_[idx] = decoders_[i]; - } - } - // use chk_cnt to decide if rowkey_decoder_[i] is NULL, - // because when creating bloom filte, request_cnt_ might less than rowkey_cnt_, - const int64_t chk_cnt = MIN(schema_rowkey_cnt, request_cnt_); - for (int64_t i = 0; OB_SUCC(ret) && i < chk_cnt; ++i) { - if (NULL == rowkey_decoder_[i].decoder_) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("rowkey column not exist in column map", K(ret), K(i)); - reset(); - } - } } } return ret; } +int ObMicroBlockDecoder::init( + const ObMicroBlockData &block_data, + const ObStorageDatumUtils *datum_utils) +{ + int ret = OB_SUCCESS; + // can be init twice + if (OB_UNLIKELY(block_data.get_buf_size() <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(block_data)); + } else { + if (is_inited_) { + reset(); + } + read_info_ = nullptr; + datum_utils_ = datum_utils; + if (OB_FAIL(do_init(block_data))) { + LOG_WARN("do init failed", K(ret)); + } + } + return ret; +} + + int ObMicroBlockDecoder::do_init(const ObMicroBlockData &block_data) { int ret = OB_SUCCESS; - if (OB_ISNULL(read_info_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument, column map should be set first", K(ret)); - } else if (OB_FAIL(get_micro_metas(header_, col_header_, meta_data_, + if (OB_FAIL(get_micro_metas(header_, col_header_, meta_data_, block_data.get_buf(), block_data.get_buf_size()))) { LOG_WARN("get micro block meta failed", K(ret), K(block_data)); } else if (OB_ISNULL(allocator_ = get_decoder_allocator())) { @@ -1292,6 +1315,11 @@ int ObMicroBlockDecoder::do_init(const ObMicroBlockData &block_data) ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("get decoder context array failed", K(ret)); } else { + if (NULL == read_info_) { + request_cnt_ = header_->column_count_; + } else { + request_cnt_ = read_info_->get_request_count(); + } row_count_ = header_->row_count_; row_data_ = block_data.get_buf() + header_->row_data_offset_; const int64_t row_data_len = block_data.get_buf_size() - header_->row_data_offset_; @@ -1414,7 +1442,7 @@ OB_INLINE int ObMicroBlockDecoder::get_row_impl(int64_t index, ObDatumRow &row) } else if (row.get_capacity() < request_cnt_) { ret = OB_BUF_NOT_ENOUGH; LOG_WARN("obj buf is not enough", K(ret), "expect_obj_count", request_cnt_, K(row)); - } else if (OB_FAIL(decode_cells(index, row_len, row_data, 0, request_cnt_, row.storage_datums_))) { + } else if (OB_FAIL(decode_cells(index, row_len, row_data, 0, MIN(request_cnt_, header_->column_count_), row.storage_datums_))) { LOG_WARN("decode cells failed", K(ret), K(index), K_(request_cnt)); } else { row.row_flag_.reset(); @@ -1546,12 +1574,12 @@ int ObMicroBlockDecoder::find_bound( if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not init"); - } else if (OB_UNLIKELY(!key.is_valid() || begin_idx < 0)) { + } else if (OB_UNLIKELY(!key.is_valid() || begin_idx < 0 || nullptr == datum_utils_)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(begin_idx), K_(row_count)); - } else if (key.get_datum_cnt() <= 0 || key.get_datum_cnt() > read_info_->get_rowkey_count()) { + LOG_WARN("invalid argument", K(ret), K(begin_idx), K_(row_count), KPC_(datum_utils)); + } else if (key.get_datum_cnt() <= 0 || key.get_datum_cnt() > datum_utils_->get_rowkey_count()) { ret = common::OB_INVALID_ARGUMENT; - LOG_WARN("invalid compare column count", K(ret), K(key.get_datum_cnt()), K(read_info_->get_rowkey_count())); + LOG_WARN("invalid compare column count", K(ret), K(key.get_datum_cnt()), K(datum_utils_->get_rowkey_count())); } else { EncodingCompareV2 encoding_compare(ret, equal, this); ObRowIndexIterator begin_iter(begin_idx); @@ -1616,24 +1644,25 @@ int ObMicroBlockDecoder::compare_rowkey(const ObDatumRowkey &rowkey, const int64 compare_result = 0; int64_t row_len = 0; const char *row_data = nullptr; - if (OB_UNLIKELY(index >= row_count_ || nullptr == read_info_)) { + if (OB_UNLIKELY(index >= row_count_ || nullptr == datum_utils_)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(index), K_(row_count), KPC_(read_info)); + LOG_WARN("invalid argument", K(ret), K(index), K_(row_count), KPC_(datum_utils)); } else if (OB_FAIL(row_index_->get(index, row_data, row_len))) { LOG_WARN("get row data failed", K(ret), K(index)); } else { - const ObStorageDatumUtils &datum_utils = read_info_->get_datum_utils(); + const ObStorageDatumUtils &datum_utils = *datum_utils_; ObBitStream bs(reinterpret_cast(const_cast(row_data)), row_len); int64_t compare_column_count = rowkey.get_datum_cnt(); if (OB_UNLIKELY(datum_utils.get_rowkey_count() < compare_column_count)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Unexpected datum utils to compare rowkey", K(ret), K(compare_column_count), K(datum_utils)); } else { - const ObColDescIArray &cols_desc = read_info_->get_columns_desc(); ObStorageDatum store_datum; ObObj store_obj; + ObObjMeta col_type; for (int64_t i = 0; OB_SUCC(ret) && i < compare_column_count && 0 == compare_result; ++i) { - store_obj.set_meta_type(cols_desc.at(i).col_type_); + col_type.set_type(static_cast(col_header_[i].obj_type_)); + store_obj.set_meta_type(col_type); if (OB_FAIL((decoders_ + i)->decode(store_obj, index, bs, row_data, row_len))) { LOG_WARN("fail to decode obj", K(ret), K(index), K(i)); } else if (OB_FAIL(store_datum.from_obj_enhance(store_obj))) { @@ -1659,24 +1688,25 @@ int ObMicroBlockDecoder::compare_rowkey(const ObDatumRange &range, const char *row_data = nullptr; const ObDatumRowkey &start_rowkey = range.get_start_key(); const ObDatumRowkey &end_rowkey = range.get_end_key(); - if (OB_UNLIKELY(index >= row_count_ || nullptr == read_info_)) { + if (OB_UNLIKELY(index >= row_count_ || nullptr == datum_utils_)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(index), K_(row_count), KPC_(read_info)); + LOG_WARN("invalid argument", K(ret), K(index), K_(row_count), KPC_(datum_utils)); } else if (OB_FAIL(row_index_->get(index, row_data, row_len))) { LOG_WARN("get row data failed", K(ret), K(index)); } else { - const ObStorageDatumUtils &datum_utils = read_info_->get_datum_utils(); + const ObStorageDatumUtils &datum_utils = *datum_utils_; ObBitStream bs(reinterpret_cast(const_cast(row_data)), row_len); int64_t compare_column_count = start_rowkey.get_datum_cnt(); if (OB_UNLIKELY(datum_utils.get_rowkey_count() < compare_column_count)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Unexpected datum utils to compare rowkey", K(ret), K(compare_column_count), K(datum_utils)); } else { - const ObColDescIArray &cols_desc = read_info_->get_columns_desc(); + ObObjMeta col_type; ObObj store_obj; ObStorageDatum store_datum; for (int64_t i = 0; OB_SUCC(ret) && i < compare_column_count && 0 == start_key_compare_result; ++i) { - store_obj.set_meta_type(cols_desc.at(i).col_type_); + col_type.set_type(static_cast(col_header_[i].obj_type_)); + store_obj.set_meta_type(col_type); if (OB_FAIL((decoders_ + i)->decode(store_obj, index, bs, row_data, row_len))) { LOG_WARN("fail to decode obj", K(ret), K(index), K(i)); } else if (OB_FAIL(store_datum.from_obj_enhance(store_obj))) { @@ -1732,24 +1762,19 @@ int ObMicroBlockDecoder::cache_decoders( char *buf, const int64_t size, const char *block, - const int64_t block_size, - const ObColDescIArray &full_schema_cols) + const int64_t block_size) { int ret = OB_SUCCESS; if (OB_UNLIKELY(nullptr == buf || size <= sizeof(ObBlockCachedDecoderHeader) || - nullptr == block || block_size <= 0 || 0 >= full_schema_cols.count())) { + nullptr == block || block_size <= 0)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(buf), K(size), - KP(block), K(block_size), K(full_schema_cols)); + LOG_WARN("invalid argument", K(ret), KP(buf), K(size), KP(block), K(block_size)); } else { const ObMicroBlockHeader *header = nullptr; const ObColumnHeader *col_header = nullptr; const char *meta_data = nullptr; if (OB_FAIL(get_micro_metas(header, col_header, meta_data, block, block_size))) { LOG_WARN("get micro block meta failed", K(ret), KP(block), K(block_size)); - } else if (OB_UNLIKELY(full_schema_cols.count() < header->column_count_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Unexpected full_schema_cols", K(ret), K(full_schema_cols), K(header->column_count_)); } else { MEMSET(buf, 0, size); ObBlockCachedDecoderHeader *h = reinterpret_cast(buf); diff --git a/src/storage/blocksstable/encoding/ob_micro_block_decoder.h b/src/storage/blocksstable/encoding/ob_micro_block_decoder.h index e7fd82a77..4e6f3898a 100644 --- a/src/storage/blocksstable/encoding/ob_micro_block_decoder.h +++ b/src/storage/blocksstable/encoding/ob_micro_block_decoder.h @@ -148,12 +148,12 @@ public: virtual int get_row( const ObMicroBlockData &block_data, const ObDatumRowkey &rowkey, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, ObDatumRow &row) final; virtual int exist_row( const ObMicroBlockData &block_data, const ObDatumRowkey &rowkey, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, bool &exist, bool &found); protected: @@ -165,7 +165,7 @@ protected: private: int init_by_read_info( const ObMicroBlockData &block_data, - const ObTableReadInfo &read_info); + const storage::ObITableReadInfo &read_info); int init_by_columns_desc( const ObMicroBlockData &block_data, const int64_t schema_rowkey_cnt, @@ -194,7 +194,12 @@ public: virtual void reset(); virtual int init( const ObMicroBlockData &block_data, - const ObTableReadInfo &read_info) override; + const storage::ObITableReadInfo &read_info) override; + //when there is not read_info in input parameters, it indicates reading all columns from all rows + //when the incoming datum_utils is nullptr, it indicates not calling locate_range or find_bound + virtual int init( + const ObMicroBlockData &block_data, + const ObStorageDatumUtils *datum_utils) override; virtual int get_row(const int64_t index, ObDatumRow &row) override; virtual int get_row_header( const int64_t row_idx, @@ -223,8 +228,7 @@ public: char *buf, const int64_t size, const char *block, - const int64_t block_size, - const ObColDescIArray &full_schema_cols); + const int64_t block_size); static int update_cached_decoders(char *cache, const int64_t cache_size, const char *old_block, const char *cur_block, const int64_t block_size); // Filter interface for filter pushdown @@ -345,9 +349,7 @@ private: const ObBlockCachedDecoderHeader *cached_decoder_; ObIRowIndex *row_index_; void *decoder_buf_; - char rowkey_decoder_buf_[sizeof(ObColumnDecoder) * common::OB_MAX_ROWKEY_COLUMN_NUMBER]; ObColumnDecoder *decoders_; - ObColumnDecoder *rowkey_decoder_; // array size is double of max_column_count, because we may need two decoders for one column, // e.g.: column equal encoding, one for column equal decoder and one for referenced column decoder. ObFixedArray need_release_decoders_; diff --git a/src/storage/blocksstable/ob_block_manager.cpp b/src/storage/blocksstable/ob_block_manager.cpp index acf3d1f03..cabd45c48 100644 --- a/src/storage/blocksstable/ob_block_manager.cpp +++ b/src/storage/blocksstable/ob_block_manager.cpp @@ -31,6 +31,7 @@ #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" #include "storage/ob_super_block_struct.h" #include "storage/slog/ob_storage_logger_manager.h" +#include "storage/blocksstable/ob_shared_macro_block_manager.h" using namespace oceanbase::common; using namespace oceanbase::common::hash; @@ -126,7 +127,9 @@ ObBlockManager::ObBlockManager() super_block_buf_holder_(), default_block_size_(0), mark_cost_time_(0), - sweep_cost_time_(0), hold_count_(0), + sweep_cost_time_(0), + reserved_count_(0), + hold_count_(0), pending_free_count_(0), disk_block_count_(0), start_time_(0), @@ -179,6 +182,7 @@ int ObBlockManager::init( MEMSET(used_macro_cnt_, 0, sizeof(used_macro_cnt_)); mark_cost_time_ = 0; sweep_cost_time_= 0; + reserved_count_ = 0; hold_count_ = 0; pending_free_count_ = 0; disk_block_count_ = 0; @@ -519,8 +523,8 @@ int ObBlockManager::get_macro_block_info(const MacroBlockId ¯o_id, //BUG, should not happen LOG_ERROR("fatal error, this block should be in block map", K(ret), K(macro_id)); } else { - macro_block_info.is_free_ = !(block_info.mem_ref_cnt_ > 0 || block_info.disk_ref_cnt_ > 0 ); - macro_block_info.ref_cnt_ = block_info.mem_ref_cnt_ + block_info.disk_ref_cnt_; + macro_block_info.is_free_ = 0 == block_info.ref_cnt_; + macro_block_info.ref_cnt_ = block_info.ref_cnt_; macro_block_info.access_time_ = block_info.last_write_time_; } return ret; @@ -546,7 +550,7 @@ int ObBlockManager::check_macro_block_free(const MacroBlockId ¯o_id, bool &i ret = OB_SUCCESS; } } else { - is_free = !(block_info.mem_ref_cnt_ > 0 || block_info.disk_ref_cnt_ > 0 ); + is_free = 0 == block_info.ref_cnt_; } return ret; } @@ -697,7 +701,7 @@ int ObBlockManager::inc_ref(const MacroBlockId ¯o_id) if (OB_SUCC(ret)) { block_info.access_time_ = ObTimeUtility::fast_current_time(); - block_info.mem_ref_cnt_++; + block_info.ref_cnt_++; if (OB_FAIL(block_map_.insert_or_update(macro_id, block_info))) { LOG_ERROR("update block info fail", K(ret), K(macro_id), K(block_info)); } else { @@ -723,13 +727,13 @@ int ObBlockManager::dec_ref(const MacroBlockId ¯o_id) ObBucketHashWLockGuard lock_guard(bucket_lock_, macro_id.hash()); if (OB_FAIL(block_map_.get(macro_id, block_info))) { LOG_ERROR("get block_info fail", K(ret), K(macro_id)); - } else if (OB_UNLIKELY(0 == block_info.mem_ref_cnt_)) { + } else if (OB_UNLIKELY(0 == block_info.ref_cnt_)) { //BUG, should not happen ret = OB_ERR_SYS; LOG_ERROR("fatal error, ref cnt must not less than 0", K(ret), K(macro_id), K(block_info)); } else { block_info.access_time_ = ObTimeUtility::fast_current_time(); - block_info.mem_ref_cnt_--; + block_info.ref_cnt_--; if (OB_FAIL(block_map_.insert_or_update(macro_id, block_info))) { LOG_ERROR("update block info fail", K(ret), K(macro_id), K(block_info)); } else { @@ -740,64 +744,6 @@ int ObBlockManager::dec_ref(const MacroBlockId ¯o_id) return ret; } -int ObBlockManager::inc_disk_ref(const MacroBlockId ¯o_id) -{ - int ret = OB_SUCCESS; - BlockInfo block_info; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_ERROR("not init", K(ret)); - } else if (OB_UNLIKELY(!macro_id.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_ERROR("invalid argument,", K(ret), K(macro_id)); - } else { - ObBucketHashWLockGuard lock_guard(bucket_lock_, macro_id.hash()); - if (OB_FAIL(block_map_.get(macro_id, block_info))) { - LOG_ERROR("get block_info fail", K(ret), K(macro_id)); - } else { - block_info.access_time_ = ObTimeUtility::fast_current_time(); - block_info.disk_ref_cnt_++; - if (OB_FAIL(block_map_.insert_or_update(macro_id, block_info))) { - LOG_ERROR("update block info fail", K(ret), K(macro_id), K(block_info)); - } else { - LOG_DEBUG("debug ref_cnt: inc_ref on disk", K(ret), K(macro_id), K(block_info), K(lbt())); - } - } - } - return ret; -} - -int ObBlockManager::dec_disk_ref(const MacroBlockId ¯o_id) -{ - int ret = OB_SUCCESS; - BlockInfo block_info; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_ERROR("not init", K(ret)); - } else if (OB_UNLIKELY(!macro_id.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_ERROR("invalid argument", K(ret), K(macro_id)); - } else { - ObBucketHashWLockGuard lock_guard(bucket_lock_, macro_id.hash()); - if (OB_FAIL(block_map_.get(macro_id, block_info))) { - LOG_ERROR("get block_info fail", K(ret), K(macro_id)); - } else if (OB_UNLIKELY(0 == block_info.disk_ref_cnt_)) { //BUG, should not happen - ret = OB_ERR_SYS; - LOG_ERROR("fatal error, ref cnt must not less than 0", K(ret), K(macro_id), K(block_info)); - } else { - block_info.access_time_ = ObTimeUtility::fast_current_time(); - block_info.disk_ref_cnt_--; - if (OB_FAIL(block_map_.insert_or_update(macro_id, block_info))) { - LOG_ERROR("update block info fail", K(ret), K(macro_id), K(block_info)); - } else { - LOG_DEBUG("debug ref_cnt: dec_ref in disk", K(ret), K(macro_id), K(block_info), K(lbt())); - } - } - } - return ret; -} int ObBlockManager::update_write_time(const MacroBlockId ¯o_id, const bool update_to_max_time) { @@ -837,26 +783,29 @@ int ObBlockManager::get_marker_status(ObMacroBlockMarkerStatus &status) return ret ; } -void ObBlockManager::update_marker_status() +void ObBlockManager::update_marker_status(const bool mark_finished) { SpinWLockGuard guard(marker_lock_); marker_status_.total_block_count_ = get_total_macro_block_count(); - marker_status_.reserved_block_count_ = io_device_->get_reserved_block_count(); + marker_status_.reserved_block_count_ = io_device_->get_reserved_block_count() + reserved_count_; marker_status_.linked_block_count_ = used_macro_cnt_[ObMacroBlockCommonHeader::LinkedBlock]; marker_status_.index_block_count_ = used_macro_cnt_[ObMacroBlockCommonHeader::SSTableIndex]; marker_status_.ids_block_count_ = used_macro_cnt_[ObMacroBlockCommonHeader::SSTableMacroID]; marker_status_.tmp_file_count_ = used_macro_cnt_[ObMacroBlockCommonHeader::TmpFileData]; marker_status_.data_block_count_ = used_macro_cnt_[ObMacroBlockCommonHeader::SSTableData]; + marker_status_.shared_data_block_count_ = used_macro_cnt_[ObMacroBlockCommonHeader::SharedSSTableData]; marker_status_.disk_block_count_ = disk_block_count_; marker_status_.bloomfiter_count_ = used_macro_cnt_[ObMacroBlockCommonHeader::BloomFilterData]; marker_status_.hold_count_ = hold_count_; marker_status_.pending_free_count_ = pending_free_count_; marker_status_.free_count_ = get_free_macro_block_count(); + marker_status_.shared_meta_block_count_ = used_macro_cnt_[ObMacroBlockCommonHeader::SharedMetaData]; marker_status_.mark_cost_time_ = mark_cost_time_; marker_status_.sweep_cost_time_ = sweep_cost_time_; marker_status_.start_time_ = start_time_; marker_status_.last_end_time_ = last_end_time_; marker_status_.hold_info_ = hold_info_; + marker_status_.mark_finished_ = mark_finished; } bool ObBlockManager::GetOldestHoldBlockFunctor::operator()( @@ -867,13 +816,13 @@ bool ObBlockManager::GetOldestHoldBlockFunctor::operator()( if (OB_HASH_EXIST == ret) { ret = OB_SUCCESS; } else if (OB_HASH_NOT_EXIST == ret) { - if (!(0 == value.mem_ref_cnt_ && 1 == value.disk_ref_cnt_) // not wash tablet block + // TODO zhouxinlan.zxl : add new solutions to find leaked macro blocks + if (0 != value.ref_cnt_ // not wash tablet block && (!oldest_hold_block_info_.macro_id_.is_valid() || value.access_time_ < oldest_hold_block_info_.last_access_time_)) { oldest_hold_block_info_.macro_id_ = key; oldest_hold_block_info_.last_access_time_ = value.access_time_; - oldest_hold_block_info_.mem_ref_cnt_ = value.mem_ref_cnt_; - oldest_hold_block_info_.disk_ref_cnt_ = value.disk_ref_cnt_; + oldest_hold_block_info_.ref_cnt_ = value.ref_cnt_; } ret = OB_SUCCESS; } else { @@ -888,11 +837,9 @@ bool ObBlockManager::GetPendingFreeBlockFunctor::operator()(const MacroBlockId & const BlockInfo &value) { int ret = OB_SUCCESS; - if (value.mem_ref_cnt_ > 0) { + if (value.ref_cnt_ > 0) { hold_count_++; - } else if (value.disk_ref_cnt_ > 0) { - disk_block_count_++; - } else if (OB_UNLIKELY(value.mem_ref_cnt_ < 0 || value.disk_ref_cnt_ < 0)) { + } else if (OB_UNLIKELY(value.ref_cnt_ < 0)) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("fatal error, macro block ref cnt less than 0", K(ret), K(key), K(value)); } else if (OB_FAIL(blk_map_.insert(key, true))) { @@ -906,7 +853,7 @@ bool ObBlockManager::GetAllMacroBlockIdFunctor::operator()(const MacroBlockId &k const BlockInfo &value) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(value.mem_ref_cnt_ < 0 || value.disk_ref_cnt_ < 0)) { + if (OB_UNLIKELY(value.ref_cnt_ < 0)) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("fatal error, macro block ref cnt less than 0", K(ret), K(key), K(value)); } else if (OB_FAIL(block_ids_.push_back(key))) { @@ -963,7 +910,7 @@ int ObBlockManager::do_sweep(MacroBlkIdMap &mark_info) io_fd.second_id_ = macro_id.second_id(); if (OB_FAIL(block_map_.get(macro_id, block_info))) { LOG_WARN("fail to get block info from block map", K(ret), K(macro_id)); - } else if (OB_UNLIKELY(block_info.mem_ref_cnt_ > 0 || block_info.disk_ref_cnt_ > 0)) { + } else if (OB_UNLIKELY(block_info.ref_cnt_ > 0)) { // skip using block. continue; } else if (OB_FAIL(block_map_.erase(macro_id))) { @@ -982,12 +929,17 @@ void ObBlockManager::mark_and_sweep() int ret = OB_SUCCESS; ObHashSet macro_id_set; MacroBlkIdMap mark_info; + bool mark_finished = true; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("block manager not init", K(ret)); } else if (!is_mark_sweep_enabled()) { LOG_INFO("mark and sweep is disabled, do not mark and sweep this round"); + } else if (!ObServerCheckpointSlogHandler::get_instance().is_started()) { + if (REACH_TIME_INTERVAL(10 * 1000 * 1000 /* 10s */)) { + LOG_WARN("slog replay hasn't finished, this task can't start", K(ret)); + } } else { set_mark_sweep_doing(); if (OB_FAIL(mark_info.init(ObModIds::OB_STORAGE_FILE_BLOCK_REF, OB_SERVER_TENANT_ID))) { @@ -997,7 +949,16 @@ void ObBlockManager::mark_and_sweep() } else { ATOMIC_SET(&start_time_, ObTimeUtility::fast_current_time()); if (OB_FAIL(mark_macro_blocks(mark_info, macro_id_set))) {//mark - LOG_WARN("fail to mark macro blocks", K(ret)); + if (OB_EAGAIN == ret) { + mark_finished = false; + ret = OB_SUCCESS; + // skip marking + } else { + LOG_WARN("fail to mark macro blocks", K(ret)); + } + } + if (OB_FAIL(ret)) { + // do nothing } else { pending_free_count_ += mark_info.count(); mark_cost_time_ = ObTimeUtility::fast_current_time() - start_time_; @@ -1008,13 +969,12 @@ void ObBlockManager::mark_and_sweep() last_end_time_ = ObTimeUtility::fast_current_time(); sweep_cost_time_ = last_end_time_ - start_time_ - mark_cost_time_; - ObMacroBlockMarkerStatus marker_status; GetOldestHoldBlockFunctor functor(macro_id_set, hold_info_); if (OB_FAIL(block_map_.for_each(functor))) { ret = functor.get_ret_code(); LOG_WARN("fail to get oldest hold block", K(ret)); } else { - update_marker_status(); + update_marker_status(mark_finished); FLOG_INFO("finish once mark and sweep", K(ret), K_(marker_status), "map_cnt", block_map_.count()); } } @@ -1028,6 +988,7 @@ void ObBlockManager::mark_and_sweep() void ObBlockManager::reset_mark_status() { MEMSET(used_macro_cnt_, 0, sizeof(used_macro_cnt_)); + reserved_count_ = 0; hold_count_ = 0; pending_free_count_ = 0; disk_block_count_ = 0; @@ -1063,9 +1024,17 @@ int ObBlockManager::mark_macro_blocks( omt->get_mtl_tenant_ids(mtl_tenant_ids); for (int64_t i = 0; OB_SUCC(ret) && i < mtl_tenant_ids.count(); i++) { const uint64_t tenant_id = mtl_tenant_ids.at(i); + MacroBlockId macro_id; MTL_SWITCH(tenant_id) { if (OB_FAIL(mark_tenant_blocks(mark_info, macro_id_set))) { LOG_WARN("fail to mark tenant blocks", K(ret), K(tenant_id)); + } else if (OB_FALSE_IT(MTL(ObSharedMacroBlockMgr*)->get_cur_shared_block(macro_id))) { + } else if (OB_FAIL(mark_held_shared_block(macro_id, mark_info, macro_id_set))) { + LOG_WARN("fail to mark shared block held by shared_macro_block_manager", K(ret), K(macro_id)); + } else if (OB_FALSE_IT( + MTL(ObTenantCheckpointSlogHandler*)->get_shared_block_reader_writer().get_cur_shared_block(macro_id))) { + } else if (OB_FAIL(mark_held_shared_block(macro_id, mark_info, macro_id_set))) { + LOG_WARN("fail to mark shared block held by shared_reader_writer", K(ret), K(macro_id)); } } } @@ -1073,6 +1042,30 @@ int ObBlockManager::mark_macro_blocks( return ret; } +int ObBlockManager::mark_held_shared_block( + const MacroBlockId ¯o_id, + MacroBlkIdMap &mark_info, + common::hash::ObHashSet ¯o_id_set) +{ + int ret = OB_SUCCESS; + + if (!macro_id.is_valid()) { + // no small sstable, skip the mark + } else if (OB_FAIL(update_mark_info(macro_id, mark_info))) { + LOG_WARN("fail to update mark info", K(ret), K(macro_id)); + } else if (OB_FAIL(macro_id_set.set_refactored(macro_id, 0 /*no override*/))) { + if (OB_HASH_EXIST != ret) { + LOG_WARN("fail to put macro id into set", K(ret), K(macro_id)); + } else { + ret = OB_SUCCESS; + } + } else { + hold_count_--; + reserved_count_++; + } + return ret; +} + int ObBlockManager::mark_tenant_blocks( MacroBlkIdMap &mark_info, common::hash::ObHashSet ¯o_id_set) @@ -1083,70 +1076,124 @@ int ObBlockManager::mark_tenant_blocks( if (OB_ISNULL(t3m) || OB_ISNULL(ckpt_hdl)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected error, t3m or ckpt hdl of mtl is nullptr", K(ret), KP(t3m), KP(ckpt_hdl)); - } else if (OB_FAIL(mark_tenant_meta_blocks(mark_info, macro_id_set, *ckpt_hdl))) { + } else if (OB_FAIL(mark_tenant_ckpt_blocks(mark_info, macro_id_set, *ckpt_hdl))) { LOG_WARN("fail to mark tenant meta blocks", K(ret)); } else { - ObTenantInMemoryTabletIterator tablet_iter(*t3m); + ObArenaAllocator iter_allocator("MarkIter", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); + ObTenantTabletIterator tablet_iter(*t3m, iter_allocator); ObTabletHandle handle; while (OB_SUCC(ret)) { - if (OB_FAIL(tablet_iter.get_next_tablet(handle))) { - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - break; - } else { - LOG_WARN("fail to get next in-memory tablet", K(ret)); + if (!continue_mark()) { + ret = OB_EAGAIN; + LOG_INFO("disk usage exceeds threshold, skip marking", K(io_device_->get_free_block_count()), + K(super_block_.get_total_macro_block_count())); + } else { + handle.reset(); + iter_allocator.reuse(); + if (OB_FAIL(tablet_iter.get_next_tablet(handle))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("fail to get next in-memory tablet", K(ret)); + } + } else if (OB_FAIL(mark_tablet_meta_blocks(mark_info, handle, macro_id_set))) { + LOG_WARN("fail to mark tablet meta blocks", K(ret)); + } else if (OB_FAIL(mark_sstable_blocks(mark_info, handle, macro_id_set))) { + LOG_WARN("fail to mark tablet blocks", K(ret)); } - } else if (OB_FAIL(mark_tablet_blocks(mark_info, handle, macro_id_set))) { - LOG_WARN("fail to mark tablet blocks", K(ret)); } } } return ret; } -int ObBlockManager::mark_tablet_blocks( +int ObBlockManager::mark_sstable_blocks( MacroBlkIdMap &mark_info, ObTabletHandle &handle, common::hash::ObHashSet ¯o_id_set) { int ret = OB_SUCCESS; - ObSEArray sstables; + ObTableStoreIterator table_store_iter(false, false); + ObArenaAllocator sstable_allocator("LoadSST", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); + ObSafeArenaAllocator safe_allocator(sstable_allocator); if (OB_UNLIKELY(!handle.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(handle)); - } else if (OB_FAIL(handle.get_obj()->get_all_sstables(sstables))) { + } else if (OB_FAIL(handle.get_obj()->get_all_sstables(table_store_iter))) { LOG_WARN("fail to get all sstables", K(ret)); } else { - for (int64_t idx = 0; OB_SUCC(ret) && idx < sstables.count(); ++idx) { - ObSSTable *sstable = static_cast(sstables.at(idx)); - if (OB_ISNULL(sstable)) { + while (OB_SUCC(ret)) { + safe_allocator.reuse(); + ObITable *table = nullptr; + ObSSTableMetaHandle sstable_meta_hdl; + ObSSTable *sstable = nullptr; + if (OB_FAIL(table_store_iter.get_next(table))) { + if (OB_UNLIKELY(OB_ITER_END == ret)) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("fail to get next table from iter", K(ret), K(table_store_iter)); + } + } else if (FALSE_IT(sstable = static_cast(table))) { + } else if (OB_ISNULL(sstable)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected error, sstable is nullptr", K(ret), KP(sstable)); + } else if (OB_FAIL(mark_sstable_meta_block(*sstable, mark_info, macro_id_set))) { + LOG_WARN("fail to mark sstable meta block", K(ret), KPC(sstable)); + } else if (OB_FAIL(sstable->get_meta(sstable_meta_hdl, &safe_allocator))) { + LOG_WARN("fail to get sstable meta", K(ret)); } else { - const ObSSTableMeta &meta = sstable->get_meta(); + const ObSSTableMeta &meta = sstable_meta_hdl.get_sstable_meta(); ObMacroBlockCommonHeader::MacroBlockType macro_type; macro_type = ObMacroBlockCommonHeader::MacroBlockType::SSTableData; - for (int64_t k = 0; OB_SUCC(ret) && k < meta.get_macro_info().get_data_block_ids().count(); ++k) { - const MacroBlockId ¯o_id = meta.get_macro_info().get_data_block_ids().at(k); - if (OB_FAIL(update_mark_info(macro_id, mark_info))) { - LOG_WARN("fail to update mark info", K(ret), K(idx), K(macro_id), K(k), KPC(sstable)); + ObMacroIdIterator iterator; + MacroBlockId macro_id; + if (OB_FAIL(meta.get_macro_info().get_data_block_iter(iterator))) { + LOG_WARN("fail to get data block iterator", K(ret), K(meta)); + } + while (OB_SUCC(ret)) { + if (OB_FAIL(iterator.get_next_macro_id(macro_id))) { + if (OB_ITER_END != ret) { + LOG_WARN("fail to get next macro id", K(ret), K(iterator)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(update_mark_info(macro_id, mark_info))) { + LOG_WARN("fail to update mark info", K(ret), K(macro_id), KPC(sstable)); } else if (OB_FAIL(macro_id_set.set_refactored(macro_id, 0 /*no override*/))) { if (OB_HASH_EXIST != ret) { - LOG_WARN("fail to put macro id into set", K(ret), K(macro_id), K(k)); + LOG_WARN("fail to put macro id into set", K(ret), K(macro_id)); } else { ret = OB_SUCCESS; } } else { + if (sstable->is_small_sstable()) { + macro_type = ObMacroBlockCommonHeader::MacroBlockType::SharedSSTableData; + } used_macro_cnt_[macro_type] ++; hold_count_--; } } - macro_type = ObMacroBlockCommonHeader::MacroBlockType::SSTableIndex; - for (int64_t j = 0; OB_SUCC(ret) && j < meta.get_macro_info().get_other_block_ids().count(); ++j) { - const MacroBlockId ¯o_id = meta.get_macro_info().get_other_block_ids().at(j); - if (OB_FAIL(update_mark_info(macro_id, mark_info))) { - LOG_ERROR("fail to update mark info", K(ret), K(idx), K(j), K(macro_id), KPC(sstable)); + if (OB_SUCC(ret)) { + macro_type = ObMacroBlockCommonHeader::MacroBlockType::SSTableIndex; + iterator.reset(); + if (OB_FAIL(meta.get_macro_info().get_other_block_iter(iterator))) { + LOG_WARN("fail to get other block iterator", K(ret), K(meta)); + } + } + while (OB_SUCC(ret)) { + if (OB_FAIL(iterator.get_next_macro_id(macro_id))) { + if (OB_ITER_END != ret) { + LOG_WARN("fail to get next macro id", K(ret), K(iterator)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(update_mark_info(macro_id, mark_info))) { + LOG_ERROR("fail to update mark info", K(ret), K(macro_id), KPC(sstable)); } else if (OB_FAIL(macro_id_set.set_refactored(macro_id))) { LOG_WARN("fail to put macro id into set", K(ret), K(macro_id)); } else { @@ -1154,11 +1201,23 @@ int ObBlockManager::mark_tablet_blocks( hold_count_--; } } - macro_type = ObMacroBlockCommonHeader::MacroBlockType::SSTableMacroID; - for (int64_t i = 0; OB_SUCC(ret) && i < meta.get_macro_info().get_linked_block_ids().count(); ++i) { - const MacroBlockId ¯o_id = meta.get_macro_info().get_linked_block_ids().at(i); - if (OB_FAIL(update_mark_info(macro_id, mark_info))) { - LOG_ERROR("fail to update mark info", K(ret), K(idx), K(i), K(macro_id), KPC(sstable)); + if (OB_SUCC(ret)) { + macro_type = ObMacroBlockCommonHeader::MacroBlockType::SSTableMacroID; + iterator.reset(); + if (OB_FAIL(meta.get_macro_info().get_linked_block_iter(iterator))) { + LOG_WARN("fail to get linked block iterator", K(ret), K(meta)); + } + } + while (OB_SUCC(ret)) { + if (OB_FAIL(iterator.get_next_macro_id(macro_id))) { + if (OB_ITER_END != ret) { + LOG_WARN("fail to get next macro id", K(ret), K(iterator)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(update_mark_info(macro_id, mark_info))) { + LOG_ERROR("fail to update mark info", K(ret), K(macro_id), KPC(sstable)); } else if (OB_FAIL(macro_id_set.set_refactored(macro_id))) { LOG_WARN("fail to put macro id into set", K(ret), K(macro_id)); } else { @@ -1172,7 +1231,65 @@ int ObBlockManager::mark_tablet_blocks( return ret; } -int ObBlockManager::mark_tenant_meta_blocks( +int ObBlockManager::mark_tablet_meta_blocks( + MacroBlkIdMap &mark_info, + storage::ObTabletHandle &handle, + common::hash::ObHashSet ¯o_id_set) +{ + int ret = OB_SUCCESS; + const ObTablet *tablet = handle.get_obj(); + ObSArray meta_ids; + if (OB_FAIL(tablet->get_tablet_meta_ids(meta_ids))) { + LOG_WARN("fail to get tablet meta block ids", K(ret), KPC(tablet)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < meta_ids.count(); i++) { + const MacroBlockId ¯o_id = meta_ids[i]; + if (OB_FAIL(update_mark_info(macro_id, mark_info))) { + LOG_WARN("fail to update mark info", K(ret), K(macro_id)); + } else if (OB_FAIL(macro_id_set.set_refactored(macro_id, 0 /* not overwrite */))) { + if (OB_HASH_EXIST != ret) { + LOG_WARN("fail to put macro id into set", K(ret), K(macro_id)); + } else { + ret = OB_SUCCESS; + } + } else { + used_macro_cnt_[ObMacroBlockCommonHeader::SharedMetaData]++; + hold_count_--; + } + } + } + return ret; +} + +int ObBlockManager::mark_sstable_meta_block( + const blocksstable::ObSSTable &sstable, + MacroBlkIdMap &mark_info, + common::hash::ObHashSet ¯o_id_set) +{ + int ret = OB_SUCCESS; + const ObMetaDiskAddr &addr = sstable.get_addr(); + MacroBlockId macro_id; + if (addr.is_block()) { + if (OB_UNLIKELY(!addr.is_valid())) { + LOG_WARN("sstable addr is invalid", K(ret), K(addr)); + } else if (FALSE_IT(macro_id = addr.block_id())) { + } else if (OB_FAIL(update_mark_info(macro_id, mark_info))) { + LOG_WARN("fail to update mark info", K(ret), K(addr), K(macro_id)); + } else if (OB_FAIL(macro_id_set.set_refactored(macro_id, 0 /* not overwrite */))) { + if (OB_HASH_EXIST != ret) { + LOG_WARN("fail to put macro id into set", K(ret), K(macro_id)); + } else { + ret = OB_SUCCESS; + } + } else { + used_macro_cnt_[ObMacroBlockCommonHeader::SharedMetaData]++; + hold_count_--; + } + } + return ret; +} + +int ObBlockManager::mark_tenant_ckpt_blocks( MacroBlkIdMap &mark_info, common::hash::ObHashSet ¯o_id_set, ObTenantCheckpointSlogHandler &hdl) @@ -1233,6 +1350,12 @@ int ObBlockManager::mark_server_meta_blocks( return ret; } +bool ObBlockManager::continue_mark() +{ + return (double) (io_device_->get_free_block_count()) + / (double) (super_block_.get_total_macro_block_count()) >= MARK_THRESHOLD; +} + int ObBlockManager::update_mark_info( const ObIArray ¯o_block_list, common::hash::ObHashSet ¯o_id_set, @@ -1267,7 +1390,7 @@ int ObBlockManager::update_mark_info(const MacroBlockId ¯o_id, } else { LOG_WARN("fail to get from block map", K(ret), K(macro_id)); } - } else if (OB_UNLIKELY(block_info.mem_ref_cnt_ < 0 || block_info.disk_ref_cnt_ < 0)) { + } else if (OB_UNLIKELY(block_info.ref_cnt_ < 0)) { LOG_ERROR("macro block should is using, ref cnt shouldn't be less than or equal to 0, " "fatal error", K(ret), K(macro_id), K(block_info)); } else if (OB_FAIL(mark_info.get(macro_id, can_free))) { @@ -1279,7 +1402,7 @@ int ObBlockManager::update_mark_info(const MacroBlockId ¯o_id, } else if (!can_free) { // do nothing. } else { - if (OB_UNLIKELY(0 == block_info.mem_ref_cnt_)) { + if (OB_UNLIKELY(0 == block_info.ref_cnt_)) { //BUG, should not happen LOG_ERROR("macro block is using, should not mark sweep, fatal error", K(ret), K(macro_id), K(block_info)); diff --git a/src/storage/blocksstable/ob_block_manager.h b/src/storage/blocksstable/ob_block_manager.h index 10924e50a..3fd9f1958 100644 --- a/src/storage/blocksstable/ob_block_manager.h +++ b/src/storage/blocksstable/ob_block_manager.h @@ -214,8 +214,6 @@ public: // reference count interfaces int inc_ref(const MacroBlockId ¯o_id); int dec_ref(const MacroBlockId ¯o_id); - int inc_disk_ref(const MacroBlockId ¯o_id); - int dec_disk_ref(const MacroBlockId ¯o_id); // If update_to_max_time is true, it means modify the last_write_time_ of the block to max, // which is used to skip the bad block inspection. int update_write_time(const MacroBlockId ¯o_id, const bool update_to_max_time = false); @@ -227,20 +225,20 @@ public: bool is_started() { return is_started_; } private: - struct BlockInfo { - int32_t mem_ref_cnt_; - int32_t disk_ref_cnt_; + struct BlockInfo + { + int64_t ref_cnt_; int64_t access_time_; int64_t last_write_time_; - BlockInfo() : mem_ref_cnt_(0), disk_ref_cnt_(0), access_time_(0), last_write_time_(INT64_MAX) {} + + BlockInfo() : ref_cnt_(0), access_time_(0), last_write_time_(INT64_MAX) {} void reset() { - mem_ref_cnt_ = 0; - disk_ref_cnt_ = 0; + ref_cnt_ = 0; access_time_ = 0; last_write_time_ = INT64_MAX; } - TO_STRING_KV(K_(mem_ref_cnt), K_(disk_ref_cnt), K_(access_time), K_(last_write_time)); + TO_STRING_KV(K_(ref_cnt), K_(access_time), K_(last_write_time)); }; class GetAllMacroBlockIdFunctor final @@ -259,6 +257,7 @@ private: }; private: + static constexpr double MARK_THRESHOLD = 0.2; static const int64_t SUPER_BLOCK_OFFSET = 0; static const int64_t DEFAULT_LOCK_BUCKET_COUNT = 2048; static const int64_t DEFAULT_PENDING_FREE_COUNT = 1024; @@ -338,14 +337,26 @@ private: int mark_macro_blocks( MacroBlkIdMap &mark_info, common::hash::ObHashSet ¯o_id_set); + int mark_held_shared_block( + const MacroBlockId ¯o_id, + MacroBlkIdMap &mark_info, + common::hash::ObHashSet ¯o_id_set); int mark_tenant_blocks( MacroBlkIdMap &mark_info, common::hash::ObHashSet ¯o_id_set); - int mark_tablet_blocks( + int mark_sstable_blocks( MacroBlkIdMap &mark_info, storage::ObTabletHandle &handle, common::hash::ObHashSet ¯o_id_set); - int mark_tenant_meta_blocks( + int mark_sstable_meta_block( + const blocksstable::ObSSTable &sstable, + MacroBlkIdMap &mark_info, + common::hash::ObHashSet ¯o_id_set); + int mark_tablet_meta_blocks( + MacroBlkIdMap &mark_info, + storage::ObTabletHandle &handle, + common::hash::ObHashSet ¯o_id_set); + int mark_tenant_ckpt_blocks( MacroBlkIdMap &mark_info, common::hash::ObHashSet ¯o_id_set, storage::ObTenantCheckpointSlogHandler &hdl); @@ -355,6 +366,7 @@ private: int mark_server_meta_blocks( MacroBlkIdMap &mark_info, common::hash::ObHashSet ¯o_id_set); + bool continue_mark(); int do_sweep(MacroBlkIdMap &mark_info); int update_mark_info( @@ -364,7 +376,7 @@ private: int update_mark_info( const MacroBlockId ¯o_id, MacroBlkIdMap &mark_info); - void update_marker_status(); + void update_marker_status(const bool mark_finished); void disable_mark_sweep() { ATOMIC_SET(&is_mark_sweep_enabled_, false); } void enable_mark_sweep() { ATOMIC_SET(&is_mark_sweep_enabled_, true); } bool is_mark_sweep_enabled() { return ATOMIC_LOAD(&is_mark_sweep_enabled_); } @@ -443,6 +455,7 @@ private: int64_t used_macro_cnt_[ObMacroBlockCommonHeader::MaxMacroType]; int64_t mark_cost_time_; int64_t sweep_cost_time_; + int64_t reserved_count_; int64_t hold_count_; int64_t pending_free_count_; int64_t disk_block_count_; diff --git a/src/storage/blocksstable/ob_block_sstable_struct.cpp b/src/storage/blocksstable/ob_block_sstable_struct.cpp index 898ce8ee4..e63a11965 100644 --- a/src/storage/blocksstable/ob_block_sstable_struct.cpp +++ b/src/storage/blocksstable/ob_block_sstable_struct.cpp @@ -481,8 +481,7 @@ OB_SERIALIZE_MEMBER(ObSSTablePair, data_version_, data_seq_); ObSimpleMacroBlockInfo::ObSimpleMacroBlockInfo() : macro_id_(), last_access_time_(INT64_MAX), - mem_ref_cnt_(0), - disk_ref_cnt_(0) + ref_cnt_(0) { } @@ -490,8 +489,7 @@ void ObSimpleMacroBlockInfo::reset() { macro_id_.reset(); last_access_time_ = INT64_MAX; - mem_ref_cnt_ = 0; - disk_ref_cnt_ = 0; + ref_cnt_ = 0; } ObMacroBlockMarkerStatus::ObMacroBlockMarkerStatus() @@ -500,6 +498,7 @@ ObMacroBlockMarkerStatus::ObMacroBlockMarkerStatus() linked_block_count_(0), tmp_file_count_(0), data_block_count_(0), + shared_data_block_count_(0), index_block_count_(0), ids_block_count_(0), disk_block_count_(0), @@ -507,10 +506,12 @@ ObMacroBlockMarkerStatus::ObMacroBlockMarkerStatus() hold_count_(0), pending_free_count_(0), free_count_(0), + shared_meta_block_count_(0), mark_cost_time_(0), sweep_cost_time_(0), start_time_(0), last_end_time_(0), + mark_finished_(false), hold_info_() { } @@ -544,6 +545,7 @@ void ObMacroBlockMarkerStatus::reuse() linked_block_count_ = 0; tmp_file_count_ = 0; data_block_count_ = 0; + shared_data_block_count_ = 0; index_block_count_ = 0; ids_block_count_ = 0; disk_block_count_ = 0; @@ -551,10 +553,12 @@ void ObMacroBlockMarkerStatus::reuse() hold_count_ = 0; pending_free_count_ = 0; free_count_ = 0; + shared_meta_block_count_ = 0; mark_cost_time_ = 0; sweep_cost_time_ = 0; start_time_ = 0; last_end_time_ = 0; + mark_finished_ = false; hold_info_.reset(); } diff --git a/src/storage/blocksstable/ob_block_sstable_struct.h b/src/storage/blocksstable/ob_block_sstable_struct.h index 532ce2fc9..c13f891d7 100644 --- a/src/storage/blocksstable/ob_block_sstable_struct.h +++ b/src/storage/blocksstable/ob_block_sstable_struct.h @@ -207,6 +207,7 @@ struct ObStorageEnv int64_t user_row_cache_priority_; int64_t fuse_row_cache_priority_; int64_t bf_cache_priority_; + int64_t storage_meta_cache_priority_; int64_t bf_cache_miss_count_threshold_; int64_t ethernet_speed_; @@ -232,6 +233,7 @@ struct ObStorageEnv K_(fuse_row_cache_priority), K_(bf_cache_priority), K_(bf_cache_miss_count_threshold), + K_(storage_meta_cache_priority), K_(ethernet_speed)); }; @@ -526,7 +528,7 @@ struct ObMicroBlockEncodingCtx int64_t micro_block_size_; int64_t rowkey_column_cnt_; int64_t column_cnt_; - common::ObIArray *col_descs_; + const common::ObIArray *col_descs_; ObMicroBlockEncoderOpt encoder_opt_; mutable int64_t estimate_block_size_; @@ -1004,7 +1006,7 @@ public: J_NAME("nothing"); } else { J_OBJ_START(); - J_KV(K_(macro_id), K_(last_access_time), K_(mem_ref_cnt), K_(disk_ref_cnt)); + J_KV(K_(macro_id), K_(last_access_time), K_(ref_cnt)); J_OBJ_END(); } return pos; @@ -1012,8 +1014,7 @@ public: public: MacroBlockId macro_id_; int64_t last_access_time_; - int32_t mem_ref_cnt_; - int32_t disk_ref_cnt_; + int64_t ref_cnt_; }; class ObMacroBlockMarkerStatus final @@ -1029,6 +1030,7 @@ public: K_(linked_block_count), K_(tmp_file_count), K_(data_block_count), + K_(shared_data_block_count), K_(index_block_count), K_(ids_block_count), K_(disk_block_count), @@ -1036,10 +1038,12 @@ public: K_(hold_count), K_(pending_free_count), K_(free_count), + K_(shared_meta_block_count), K_(mark_cost_time), K_(sweep_cost_time), KTIME_(start_time), KTIME_(last_end_time), + K_(mark_finished), K_(hold_info)); public: int64_t total_block_count_; @@ -1047,6 +1051,7 @@ public: int64_t linked_block_count_; int64_t tmp_file_count_; int64_t data_block_count_; + int64_t shared_data_block_count_; int64_t index_block_count_; int64_t ids_block_count_; int64_t disk_block_count_; @@ -1054,10 +1059,12 @@ public: int64_t hold_count_; int64_t pending_free_count_; int64_t free_count_; + int64_t shared_meta_block_count_; int64_t mark_cost_time_; int64_t sweep_cost_time_; int64_t start_time_; int64_t last_end_time_; + bool mark_finished_; ObSimpleMacroBlockInfo hold_info_; }; diff --git a/src/storage/blocksstable/ob_datum_row.cpp b/src/storage/blocksstable/ob_datum_row.cpp index 9dd7fa478..358c3d2eb 100644 --- a/src/storage/blocksstable/ob_datum_row.cpp +++ b/src/storage/blocksstable/ob_datum_row.cpp @@ -506,6 +506,9 @@ DEF_TO_STRING(ObDatumRow) K_(snapshot_version), K_(fast_filter_skipped), K_(have_uncommited_row), K_(group_idx), K_(count), K_(datum_buffer)); if (NULL != buf && buf_len >= 0) { if (NULL != storage_datums_) { + J_COMMA(); + J_NAME("datums"); + J_COLON(); J_ARRAY_START(); for (int64_t i = 0; i < count_; ++i) { databuff_printf(buf, buf_len, pos, "col_id=%ld:", i); @@ -563,7 +566,6 @@ ObStorageDatumUtils::ObStorageDatumUtils() cmp_funcs_(), hash_funcs_(), ext_hash_func_(), - allocator_(nullptr), is_oracle_mode_(false), is_inited_(false) {} @@ -576,7 +578,6 @@ int ObStorageDatumUtils::transform_multi_version_col_desc(const ObIArray &mv_col_descs) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(schema_rowkey_cnt > col_descs.count())) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid argument to transform mv col descs", K(ret), K(schema_rowkey_cnt), K(col_descs)); @@ -613,6 +614,7 @@ int ObStorageDatumUtils::init(const ObIArray &col_desc { int ret = OB_SUCCESS; ObSEArray mv_col_descs; + int64_t mv_rowkey_cnt = 0; if (IS_INIT) { ret = OB_INIT_TWICE; @@ -623,66 +625,103 @@ int ObStorageDatumUtils::init(const ObIArray &col_desc STORAGE_LOG(WARN, "Invalid argument to init storage datum utils", K(ret), K(col_descs), K(schema_rowkey_cnt)); } else if (OB_FAIL(transform_multi_version_col_desc(col_descs, schema_rowkey_cnt, mv_col_descs))) { STORAGE_LOG(WARN, "Failed to transform multi version col descs", K(ret)); - } else { - is_oracle_mode_ = is_oracle_mode; - cmp_funcs_.set_allocator(&allocator); - hash_funcs_.set_allocator(&allocator); - if (OB_FAIL(cmp_funcs_.reserve(mv_col_descs.count()))) { - STORAGE_LOG(WARN, "Failed to reserve cmp func array", K(ret)); - } else if (OB_FAIL(hash_funcs_.reserve(mv_col_descs.count()))) { - STORAGE_LOG(WARN, "Failed to reserve hash func array", K(ret)); - } else { - // support column order index until next task done - // - // we could use the cmp funcs in the basic funcs directlly - bool is_null_last = is_oracle_mode_; - ObCmpFunc cmp_func; - ObHashFunc hash_func; - for (int64_t i = 0; OB_SUCC(ret) && i < mv_col_descs.count(); i++) { - const share::schema::ObColDesc &col_desc = mv_col_descs.at(i); - //TODO @hanhui support desc rowkey - bool is_ascending = true || col_desc.col_order_ == ObOrderType::ASC; - bool has_lob_header = is_lob_storage(col_desc.col_type_.get_type()); - sql::ObExprBasicFuncs *basic_funcs = ObDatumFuncs::get_basic_func(col_desc.col_type_.get_type(), - col_desc.col_type_.get_collation_type(), - col_desc.col_type_.get_scale(), - is_oracle_mode, - has_lob_header); - if (OB_UNLIKELY(nullptr == basic_funcs - || nullptr == basic_funcs->null_last_cmp_ - || nullptr == basic_funcs->murmur_hash_)) { - ret = OB_ERR_SYS; - STORAGE_LOG(ERROR, "Unexpected null basic funcs", K(ret), K(col_desc)); - } else { - cmp_func.cmp_func_ = is_null_last ? basic_funcs->null_last_cmp_ : basic_funcs->null_first_cmp_; - hash_func.hash_func_ = basic_funcs->murmur_hash_; - if (OB_FAIL(hash_funcs_.push_back(hash_func))) { - STORAGE_LOG(WARN, "Failed to push back hash func", K(ret), K(i), K(col_desc)); - } else if (is_ascending) { - if (OB_FAIL(cmp_funcs_.push_back(ObStorageDatumCmpFunc(cmp_func)))) { - STORAGE_LOG(WARN, "Failed to push back cmp func", K(ret), K(i), K(col_desc)); - } - } else { - ret = OB_ERR_SYS; - STORAGE_LOG(WARN, "Unsupported desc column order", K(ret), K(col_desc), K(i)); - } - } - } - } - if (OB_SUCC(ret)) { - sql::ObExprBasicFuncs *basic_funcs = ObDatumFuncs::get_basic_func(ObExtendType, CS_TYPE_BINARY); - if (OB_UNLIKELY(nullptr == basic_funcs || nullptr == basic_funcs->murmur_hash_)) { - ret = OB_ERR_SYS; - STORAGE_LOG(ERROR, "Unexpected null basic funcs for extend type", K(ret)); - } else { - ext_hash_func_.hash_func_ = basic_funcs->murmur_hash_; - rowkey_cnt_ = schema_rowkey_cnt + storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); - col_cnt_ = mv_col_descs.count(); - allocator_ = &allocator; - is_inited_ = true; - } - } + } else if (FALSE_IT(mv_rowkey_cnt = schema_rowkey_cnt + storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt())) { + } else if (OB_FAIL(cmp_funcs_.init(mv_rowkey_cnt, allocator))) { + STORAGE_LOG(WARN, "Failed to reserve cmp func array", K(ret)); + } else if (OB_FAIL(hash_funcs_.init(mv_rowkey_cnt, allocator))) { + STORAGE_LOG(WARN, "Failed to reserve hash func array", K(ret)); + } else if (OB_FAIL(inner_init(mv_col_descs, mv_rowkey_cnt, is_oracle_mode))) { + STORAGE_LOG(WARN, "Failed to inner init datum utils", K(ret), K(mv_col_descs), K(mv_rowkey_cnt)); + } + return ret; +} + +int ObStorageDatumUtils::init(const common::ObIArray &col_descs, + const int64_t schema_rowkey_cnt, + const bool is_oracle_mode, + const int64_t arr_buf_len, + char *arr_buf) +{ + int ret = OB_SUCCESS; + ObSEArray mv_col_descs; + int64_t pos = 0; + int64_t mv_rowkey_cnt = 0; + + if (IS_INIT) { + ret = OB_INIT_TWICE; + STORAGE_LOG(WARN, "ObStorageDatumUtils init twice", K(ret), K(*this)); + } else if (OB_UNLIKELY(schema_rowkey_cnt < 0 || schema_rowkey_cnt > OB_MAX_ROWKEY_COLUMN_NUMBER + || schema_rowkey_cnt > col_descs.count())) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "Invalid argument to init storage datum utils", K(ret), K(col_descs), K(schema_rowkey_cnt)); + } else if (OB_FAIL(transform_multi_version_col_desc(col_descs, schema_rowkey_cnt, mv_col_descs))) { + STORAGE_LOG(WARN, "Failed to transform multi version col descs", K(ret)); + } else if (FALSE_IT(mv_rowkey_cnt = schema_rowkey_cnt + storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt())) { + } else if (OB_FAIL(cmp_funcs_.init(mv_rowkey_cnt, arr_buf_len, arr_buf, pos))) { + STORAGE_LOG(WARN, "Failed to init compare function array", K(ret)); + } else if (OB_FAIL(hash_funcs_.init(mv_rowkey_cnt, arr_buf_len, arr_buf, pos))) { + STORAGE_LOG(WARN, "Failed to init hash function array", K(ret)); + } else if (OB_FAIL(inner_init(mv_col_descs, mv_rowkey_cnt, is_oracle_mode))) { + STORAGE_LOG(WARN, "Failed to inner init datum utils", K(ret), K(mv_col_descs), K(mv_rowkey_cnt)); + } + return ret; +} + +int ObStorageDatumUtils::inner_init( + const common::ObIArray &mv_col_descs, + const int64_t mv_rowkey_col_cnt, + const bool is_oracle_mode) +{ + int ret = OB_SUCCESS; + is_oracle_mode_ = is_oracle_mode; + // support column order index until next task done + // + // we could use the cmp funcs in the basic funcs directlly + bool is_null_last = is_oracle_mode_; + ObCmpFunc cmp_func; + ObHashFunc hash_func; + for (int64_t i = 0; OB_SUCC(ret) && i < mv_rowkey_col_cnt; i++) { + const share::schema::ObColDesc &col_desc = mv_col_descs.at(i); + //TODO @hanhui support desc rowkey + bool is_ascending = true || col_desc.col_order_ == ObOrderType::ASC; + bool has_lob_header = is_lob_storage(col_desc.col_type_.get_type()); + sql::ObExprBasicFuncs *basic_funcs = ObDatumFuncs::get_basic_func(col_desc.col_type_.get_type(), + col_desc.col_type_.get_collation_type(), + col_desc.col_type_.get_scale(), + is_oracle_mode, + has_lob_header); + if (OB_UNLIKELY(nullptr == basic_funcs + || nullptr == basic_funcs->null_last_cmp_ + || nullptr == basic_funcs->murmur_hash_)) { + ret = OB_ERR_SYS; + STORAGE_LOG(ERROR, "Unexpected null basic funcs", K(ret), K(col_desc)); + } else { + cmp_func.cmp_func_ = is_null_last ? basic_funcs->null_last_cmp_ : basic_funcs->null_first_cmp_; + hash_func.hash_func_ = basic_funcs->murmur_hash_; + if (OB_FAIL(hash_funcs_.push_back(hash_func))) { + STORAGE_LOG(WARN, "Failed to push back hash func", K(ret), K(i), K(col_desc)); + } else if (is_ascending) { + if (OB_FAIL(cmp_funcs_.push_back(ObStorageDatumCmpFunc(cmp_func)))) { + STORAGE_LOG(WARN, "Failed to push back cmp func", K(ret), K(i), K(col_desc)); + } + } else { + ret = OB_ERR_SYS; + STORAGE_LOG(WARN, "Unsupported desc column order", K(ret), K(col_desc), K(i)); + } + } + } + if (OB_SUCC(ret)) { + sql::ObExprBasicFuncs *basic_funcs = ObDatumFuncs::get_basic_func(ObExtendType, CS_TYPE_BINARY); + if (OB_UNLIKELY(nullptr == basic_funcs || nullptr == basic_funcs->murmur_hash_)) { + ret = OB_ERR_SYS; + STORAGE_LOG(ERROR, "Unexpected null basic funcs for extend type", K(ret)); + } else { + ext_hash_func_.hash_func_ = basic_funcs->murmur_hash_; + rowkey_cnt_ = mv_rowkey_col_cnt; + col_cnt_ = mv_col_descs.count(); + is_inited_ = true; + } } return ret; @@ -694,11 +733,15 @@ void ObStorageDatumUtils::reset() col_cnt_ = 0; cmp_funcs_.reset(); hash_funcs_.reset(); - allocator_ = nullptr; ext_hash_func_.hash_func_ = nullptr; is_inited_ = false; } +int64_t ObStorageDatumUtils::get_deep_copy_size() const +{ + return cmp_funcs_.get_deep_copy_size() + hash_funcs_.get_deep_copy_size(); +} + int ObGhostRowUtil::is_ghost_row( const blocksstable::ObMultiVersionRowFlag &flag, bool &is_ghost_row) diff --git a/src/storage/blocksstable/ob_datum_row.h b/src/storage/blocksstable/ob_datum_row.h index af77a1d4a..03eb54819 100644 --- a/src/storage/blocksstable/ob_datum_row.h +++ b/src/storage/blocksstable/ob_datum_row.h @@ -17,6 +17,7 @@ #include "common/ob_tablet_id.h" #include "share/datum/ob_datum.h" #include "share/datum/ob_datum_funcs.h" +#include "storage/meta_mem/ob_fixed_meta_obj_array.h" #include "storage/tx/ob_trans_define.h" #include "common/row/ob_row.h" #include "storage/ob_storage_util.h" @@ -185,6 +186,16 @@ public: } OB_INLINE void format_str(char *str, int8_t len) const { return format_dml_str(whole_flag_, str, len); } + OB_INLINE int32_t get_delta() const + { + int32_t ret_val = 0; + if (is_extra_delete()) { + ret_val = -1; + } else if (is_insert()) { + ret_val = 1; + } + return ret_val; + } TO_STRING_KV("flag", get_dml_str(ObDmlFlag(flag_)), K_(flag_type)) ; private: @@ -387,7 +398,7 @@ public: /* *row estimate section */ - OB_INLINE int32_t get_delta() const; + OB_INLINE int32_t get_delta() const { return row_flag_.get_delta(); } DECLARE_TO_STRING; @@ -446,37 +457,52 @@ private: common::ObCmpFunc cmp_func_; }; -typedef common::ObFixedArray ObStoreCmpFuncs; +typedef storage::ObFixedMetaObjArray ObStoreCmpFuncs; +typedef storage::ObFixedMetaObjArray ObStoreHashFuncs; struct ObStorageDatumUtils { public: ObStorageDatumUtils(); ~ObStorageDatumUtils(); + // init with array memory from allocator int init(const common::ObIArray &col_descs, const int64_t schema_rowkey_cnt, const bool is_oracle_mode, common::ObIAllocator &allocator); + // init with array memory on fixed size memory buffer + int init(const common::ObIArray &col_descs, + const int64_t schema_rowkey_cnt, + const bool is_oracle_mode, + const int64_t arr_buf_len, + char *arr_buf); void reset(); - OB_INLINE bool is_valid() const { return is_inited_; } + OB_INLINE bool is_valid() const + { + return is_inited_ && cmp_funcs_.count() >= rowkey_cnt_ && hash_funcs_.count() >= rowkey_cnt_; + } OB_INLINE bool is_oracle_mode() const { return is_oracle_mode_; } OB_INLINE int64_t get_rowkey_count() const { return rowkey_cnt_; } OB_INLINE int64_t get_column_count() const { return col_cnt_; } OB_INLINE const ObStoreCmpFuncs &get_cmp_funcs() const { return cmp_funcs_; } - OB_INLINE const common::ObHashFuncs &get_hash_funcs() const { return hash_funcs_; } + OB_INLINE const ObStoreHashFuncs &get_hash_funcs() const { return hash_funcs_; } OB_INLINE const common::ObHashFunc &get_ext_hash_funcs() const { return ext_hash_func_; } - TO_STRING_KV(K_(is_oracle_mode), K_(rowkey_cnt), K_(col_cnt), KP_(allocator), K_(is_inited)); + int64_t get_deep_copy_size() const; + TO_STRING_KV(K_(is_oracle_mode), K_(rowkey_cnt), K_(col_cnt), K_(is_inited), K_(is_oracle_mode)); private: //TODO to be removed by @hanhui int transform_multi_version_col_desc(const common::ObIArray &col_descs, const int64_t schema_rowkey_cnt, common::ObIArray &mv_col_descs); + int inner_init( + const common::ObIArray &mv_col_descs, + const int64_t mv_rowkey_col_cnt, + const bool is_oracle_mode); private: - int32_t rowkey_cnt_; + int32_t rowkey_cnt_; // multi version rowkey int32_t col_cnt_; - ObStoreCmpFuncs cmp_funcs_; - common::ObHashFuncs hash_funcs_; + ObStoreCmpFuncs cmp_funcs_; // multi version rowkey cmp funcs + ObStoreHashFuncs hash_funcs_; // multi version rowkey cmp funcs common::ObHashFunc ext_hash_func_; - ObIAllocator *allocator_; bool is_oracle_mode_; bool is_inited_; DISALLOW_COPY_AND_ASSIGN(ObStorageDatumUtils); @@ -648,16 +674,6 @@ OB_INLINE bool ObStorageDatum::operator==(const common::ObObj &other) const return bret; } -OB_INLINE int32_t ObDatumRow::get_delta() const -{ - int32_t delta = 0; - if (row_flag_.is_extra_delete()) { - delta = -1; - } else if (row_flag_.is_insert()) { - delta = 1; - } - return delta; -} OB_INLINE int64_t ObStorageDatum::storage_to_string(char *buf, int64_t buf_len) const { int64_t pos = 0; diff --git a/src/storage/blocksstable/ob_datum_rowkey.cpp b/src/storage/blocksstable/ob_datum_rowkey.cpp index 117c93349..368d72652 100644 --- a/src/storage/blocksstable/ob_datum_rowkey.cpp +++ b/src/storage/blocksstable/ob_datum_rowkey.cpp @@ -188,6 +188,14 @@ DEF_TO_STRING(ObDatumRowkey) return pos; } +void ObDatumRowkey::destroy(ObIAllocator &allocator) +{ + if (OB_NOT_NULL(datums_)) { + allocator.free(datums_); + datums_ = nullptr; + } + reset(); +} // shallow copy the obj value int ObDatumRowkey::from_rowkey(const ObRowkey &rowkey, common::ObIAllocator &allocator) diff --git a/src/storage/blocksstable/ob_datum_rowkey.h b/src/storage/blocksstable/ob_datum_rowkey.h index a4ede7bc5..650180b0b 100644 --- a/src/storage/blocksstable/ob_datum_rowkey.h +++ b/src/storage/blocksstable/ob_datum_rowkey.h @@ -33,6 +33,7 @@ public: ObDatumRowkey(ObStorageDatumBuffer &datum_buffer); ~ObDatumRowkey() = default; OB_INLINE void reset() { MEMSET(this, 0, sizeof(ObDatumRowkey)); } + void destroy(ObIAllocator &allocator); OB_INLINE int assign(ObStorageDatum *datums, const int datum_cnt); OB_INLINE bool is_valid() const { return nullptr != datums_ && datum_cnt_ > 0; } OB_INLINE bool is_memtable_valid() const { return store_rowkey_.is_valid() && is_valid(); } diff --git a/src/storage/blocksstable/ob_imicro_block_reader.cpp b/src/storage/blocksstable/ob_imicro_block_reader.cpp index 1de610d27..cbad84be9 100644 --- a/src/storage/blocksstable/ob_imicro_block_reader.cpp +++ b/src/storage/blocksstable/ob_imicro_block_reader.cpp @@ -38,6 +38,9 @@ int ObIMicroBlockReader::locate_range( ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected row count", K(ret), K_(row_count)); } else if (0 == row_count_) { + } else if (OB_ISNULL(datum_utils_)){ + ret = OB_INVALID_ARGUMENT; + LOG_WARN("datum utils is null", K(ret), KP_(datum_utils)); } else { if (!is_left_border || range.get_start_key().is_min_rowkey()) { begin_idx = 0; @@ -62,7 +65,7 @@ int ObIMicroBlockReader::locate_range( ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected state", K(ret), K(end_key_begin_idx), K(end_key_end_idx), K(range)); } else { - const bool is_precise_rowkey = read_info_->get_rowkey_count() == range.get_end_key().get_datum_cnt(); + const bool is_precise_rowkey = datum_utils_->get_rowkey_count() == range.get_end_key().get_datum_cnt(); // we should use upper_bound if the range include endkey if (OB_FAIL(find_bound(range.get_end_key(), !range.get_border_flag().inclusive_end()/*lower_bound*/, diff --git a/src/storage/blocksstable/ob_imicro_block_reader.h b/src/storage/blocksstable/ob_imicro_block_reader.h index 8955921d2..17f63c90f 100644 --- a/src/storage/blocksstable/ob_imicro_block_reader.h +++ b/src/storage/blocksstable/ob_imicro_block_reader.h @@ -193,7 +193,7 @@ public: ObMicroBlockHeader header_; ObMicroBlockData data_; ObMicroBlockData payload_data_; - const ObTableReadInfo *read_info_; + const ObITableReadInfo *read_info_; const ObMicroIndexInfo *micro_index_info_; }; @@ -204,7 +204,8 @@ public: ObIMicroBlockReaderInfo() : is_inited_(false), row_count_(-1), - read_info_(nullptr) + read_info_(nullptr), + datum_utils_(nullptr) {} virtual ~ObIMicroBlockReaderInfo() { reset(); } OB_INLINE int64_t row_count() const { return row_count_; } @@ -212,12 +213,14 @@ public: { row_count_ = -1; read_info_ = nullptr; + datum_utils_ = nullptr; is_inited_ = false; } bool is_inited_; int64_t row_count_; - const ObTableReadInfo *read_info_; + const ObITableReadInfo *read_info_; + const ObStorageDatumUtils *datum_utils_; }; class ObIMicroBlockGetReader : public ObIMicroBlockReaderInfo @@ -231,12 +234,12 @@ public: virtual int get_row( const ObMicroBlockData &block_data, const ObDatumRowkey &rowkey, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, ObDatumRow &row) = 0; virtual int exist_row( const ObMicroBlockData &block_data, const ObDatumRowkey &rowkey, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, bool &exist, bool &found) = 0; protected: @@ -270,7 +273,12 @@ public: virtual void reset() { ObIMicroBlockReaderInfo::reset(); } virtual int init( const ObMicroBlockData &block_data, - const ObTableReadInfo &read_info) = 0; + const ObITableReadInfo &read_info) = 0; + //when there is not read_info in input parameters, it indicates reading all columns from all rows + //when the incoming datum_utils is nullptr, it indicates not calling locate_range or find_bound + virtual int init( + const ObMicroBlockData &block_data, + const ObStorageDatumUtils *datum_utils) = 0; virtual int get_row(const int64_t index, ObDatumRow &row) = 0; virtual int get_row_header( const int64_t row_idx, diff --git a/src/storage/blocksstable/ob_index_block_builder.cpp b/src/storage/blocksstable/ob_index_block_builder.cpp index 9608beed4..73276a6d0 100644 --- a/src/storage/blocksstable/ob_index_block_builder.cpp +++ b/src/storage/blocksstable/ob_index_block_builder.cpp @@ -69,7 +69,6 @@ ObSSTableMergeRes::ObSSTableMergeRes() data_checksum_(0), use_old_macro_block_count_(0), data_column_checksums_(), - data_default_column_rows_cnt_(), compressor_type_(ObCompressorType::INVALID_COMPRESSOR), encrypt_id_(0), master_key_id_(0), @@ -115,7 +114,6 @@ void ObSSTableMergeRes::reset() data_checksum_ = 0; use_old_macro_block_count_ = 0; data_column_checksums_.reset(); - data_default_column_rows_cnt_.reset(); compressor_type_ = ObCompressorType::INVALID_COMPRESSOR; encrypt_id_ = 0; master_key_id_ = 0; @@ -158,7 +156,6 @@ int ObSSTableMergeRes::assign(const ObSSTableMergeRes &src) data_checksum_ = src.data_checksum_; use_old_macro_block_count_ = src.use_old_macro_block_count_; data_column_checksums_ = src.data_column_checksums_; - data_default_column_rows_cnt_ = src.data_default_column_rows_cnt_; compressor_type_ = src.compressor_type_; encrypt_id_ = src.encrypt_id_; master_key_id_ = src.master_key_id_; @@ -219,84 +216,20 @@ int ObSSTableMergeRes::fill_column_checksum_for_empty_major( return ret; } -int ObSSTableMergeRes::fill_column_default_checksum_from_schema( - const ObStorageSchema *schema, - ObIArray &column_default_checksum) -{ - int ret = OB_SUCCESS; - common::ObArray meta_array; - if (OB_ISNULL(schema) || (OB_NOT_NULL(schema) && OB_UNLIKELY(!schema->is_valid()))) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid argument", K(ret), KPC(schema)); - } else if (OB_FAIL(schema->init_column_meta_array(meta_array))) { - STORAGE_LOG(WARN, "fail to init column meta array", K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < meta_array.count(); ++i) { - if (OB_FAIL(column_default_checksum.push_back(meta_array.at(i).column_default_checksum_))) { - STORAGE_LOG(WARN, "fail to push default checksum into array", K(ret), K(i), K(meta_array)); - } - } - } - return ret; -} - -int ObSSTableMergeRes::fill_column_checksum( - const ObStorageSchema *schema, - ObIArray &column_checksums) const -{ - int ret = OB_SUCCESS; - common::ObArray column_default_checksums; - if (OB_FAIL(fill_column_default_checksum_from_schema(schema, column_default_checksums))) { - STORAGE_LOG(WARN, "fail to fill column default checksum", K(ret), KPC(schema)); - } else if (OB_FAIL(fill_column_checksum(column_default_checksums, column_checksums))) { - STORAGE_LOG(WARN, "fail to fill column checksum", K(ret), K(column_default_checksums), KPC(schema)); - } - return ret; -} - -int ObSSTableMergeRes::fill_column_checksum( - const common::ObIArray &column_default_checksum, - common::ObIArray &column_checksums) const -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(column_default_checksum.empty() || column_default_checksum.count() < data_column_cnt_)) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid argument", K(ret), - K(column_default_checksum.count()), K(data_column_cnt_), K(column_default_checksum)); - } else { - if (OB_UNLIKELY(data_column_cnt_ != column_default_checksum.count())) { - STORAGE_LOG(INFO, "column default count doesn't equal to data column count in merge res", K(column_default_checksum.count()), K(data_column_cnt_)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < data_column_cnt_; ++i) { - const int64_t checksum = data_column_checksums_.at(i) + data_default_column_rows_cnt_.at(i) * column_default_checksum.at(i); - if (OB_FAIL(column_checksums.push_back(checksum))) { - STORAGE_LOG(WARN, "fail to push back column checksum", K(ret), K(i), K(checksum), - K(data_column_checksums_), K(data_default_column_rows_cnt_), K(column_default_checksum), K(data_column_cnt_)); - } - } - } - return ret; -} - int ObSSTableMergeRes::prepare_column_checksum_array(const int64_t data_column_cnt) { int ret = OB_SUCCESS; data_column_cnt_ = data_column_cnt; data_column_checksums_.reset(); - data_default_column_rows_cnt_.reset(); if (OB_UNLIKELY(0 == data_column_cnt)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "unexpected empty roots", K(ret)); } else if (OB_FAIL(data_column_checksums_.reserve(data_column_cnt))) { STORAGE_LOG(WARN, "failed to reserve data_column_checksums_", K(ret), K(data_column_cnt_)); - } else if (OB_FAIL(data_default_column_rows_cnt_.reserve(data_column_cnt))) { - STORAGE_LOG(WARN, "failed to reserve data_default_column_rows_cnt_", K(ret), K(data_column_cnt_)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < data_column_cnt; i++) { if (OB_FAIL(data_column_checksums_.push_back(0))) { STORAGE_LOG(WARN, "failed to push column checksum", K(ret)); - } else if (OB_FAIL(data_default_column_rows_cnt_.push_back(0))) { - STORAGE_LOG(WARN, "failed to push column checksum", K(ret)); } } } @@ -768,15 +701,23 @@ int ObSSTableIndexBuilder::accumulate_macro_column_checksum( // accumulate column checksum for sstable data block int ret = OB_SUCCESS; if (OB_UNLIKELY(!meta.is_valid() - || meta.get_meta_val().column_count_ > res.data_column_cnt_)) { + || meta.get_meta_val().column_count_ > res.data_column_cnt_ + || res.data_column_cnt_ > index_store_desc_.col_default_checksum_array_.count())) { ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid arguments", K(ret), K(meta), K_(res.data_column_cnt)); + STORAGE_LOG(WARN, "invalid arguments", K(ret), K(meta), K_(res.data_column_cnt), K_(index_store_desc)); + } else if (OB_UNLIKELY((index_store_desc_.is_major_merge() || index_store_desc_.is_meta_major_merge()) + && index_store_desc_.default_col_checksum_array_valid_ + && res.data_column_cnt_ > meta.get_meta_val().column_count_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "index store desc is invalid", K(ret), K_(index_store_desc), K(meta.get_meta_val().column_count_), + K(res.data_column_cnt_)); } else { for (int64_t i = 0; i < meta.get_meta_val().column_count_; ++i) { res.data_column_checksums_.at(i) += meta.val_.column_checksums_[i]; } for (int64_t i = meta.get_meta_val().column_count_; i < res.data_column_cnt_; ++i) { - res.data_default_column_rows_cnt_.at(i) += meta.val_.row_count_; + res.data_column_checksums_.at(i) += meta.val_.row_count_ + * index_store_desc_.col_default_checksum_array_.at(i); } } return ret; @@ -798,21 +739,18 @@ void ObSSTableIndexBuilder::clean_status() self_allocator_.reset(); } -int ObSSTableIndexBuilder::close(const int64_t column_cnt, ObSSTableMergeRes &res) +int ObSSTableIndexBuilder::close(ObSSTableMergeRes &res) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "invalid sstable builder", K(ret), K_(is_inited)); } else if (OB_UNLIKELY(is_closed_)) { - if (OB_UNLIKELY(column_cnt != res_.data_column_cnt_)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "cannot close builder with diff col cnt", K(ret), K(column_cnt), K_(res)); - } else if (OB_FAIL(res.assign(res_))) { + if (OB_FAIL(res.assign(res_))) { STORAGE_LOG(WARN, "fail to assign res", K(ret), K_(res)); } - } else if (OB_FAIL(res.prepare_column_checksum_array(column_cnt))) { - STORAGE_LOG(WARN, "fail to prepare column checksum array", K(ret), K(column_cnt)); + } else if (OB_FAIL(res.prepare_column_checksum_array(index_store_desc_.full_stored_col_cnt_))) { + STORAGE_LOG(WARN, "fail to prepare column checksum array", K(ret)); } else if (OB_FAIL(trim_empty_roots())) { STORAGE_LOG(WARN, "fail to trim empty roots", K(ret)); } else if (OB_UNLIKELY(roots_.empty())) { @@ -1141,8 +1079,7 @@ int ObBaseIndexBlockBuilder::init(ObDataStoreDesc &index_store_desc, index_store_desc_->row_column_count_ - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(), index_store_desc_->schema_rowkey_col_cnt_, lib::is_oracle_mode(), - index_store_desc_->col_desc_array_, - true))) { + index_store_desc_->get_rowkey_col_descs()))) { STORAGE_LOG(WARN, "Fail to init index read info", K(ret)); } else if (OB_FAIL(row_builder_.init(*index_store_desc_))) { STORAGE_LOG(WARN, "fail to init ObBaseIndexBlockBuilder", K(ret)); @@ -1150,7 +1087,7 @@ int ObBaseIndexBlockBuilder::init(ObDataStoreDesc &index_store_desc, STORAGE_LOG(WARN, "fail to build micro writer", K(ret)); } else { if (index_store_desc_->need_pre_warm_) { - index_block_pre_warmer_.init(idx_read_info_); + index_block_pre_warmer_.init(); } is_inited_ = true; } @@ -1265,7 +1202,7 @@ int ObBaseIndexBlockBuilder::close(ObIAllocator &allocator, ObIndexTreeInfo &tre } else if (OB_FAIL(micro_writer->build_micro_block_desc(micro_block_desc))) { STORAGE_LOG(WARN, "fail to build root block", K(ret)); } else if (FALSE_IT(micro_block_desc.last_rowkey_ = root_builder->last_rowkey_)) { - } else if (OB_UNLIKELY(micro_block_desc.get_block_size() >= ObMetaDiskAddr::ROOT_BLOCK_SIZE_LIMIT)) { + } else if (OB_UNLIKELY(micro_block_desc.get_block_size() >= ROOT_BLOCK_SIZE_LIMIT)) { if (index_block_pre_warmer_.is_valid() && OB_TMP_FAIL(index_block_pre_warmer_.reserve_kvpair(micro_block_desc, root_builder->level_+1))) { if (OB_BUF_NOT_ENOUGH != tmp_ret) { @@ -1640,13 +1577,7 @@ int ObDataIndexBlockBuilder::init( // since n-1 micro block should keep format same with data_blocks ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "expect row store type equal", K(ret), KPC(index_store_desc), K(data_store_desc)); - } else if (OB_FAIL(idx_read_info_.init( - *sstable_allocator_, - index_store_desc->row_column_count_ - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(), - index_store_desc->schema_rowkey_col_cnt_, - lib::is_oracle_mode(), - index_store_desc->col_desc_array_, - true))) { + } else if (OB_FAIL(idx_read_info_.init(*sstable_allocator_, *index_store_desc))) { STORAGE_LOG(WARN, "failed to init idx read info", KPC(index_store_desc), K(ret)); } else if (OB_FAIL(micro_helper_.open(*index_store_desc, idx_read_info_, *sstable_allocator_))) { STORAGE_LOG(WARN, "fail to open base writer", K(ret)); @@ -2154,7 +2085,7 @@ int ObMetaIndexBlockBuilder::close( STORAGE_LOG(WARN, "meta index builder is closed", K(ret), K(is_closed_)); } else if (OB_FAIL(build_micro_block(micro_block_desc))) { STORAGE_LOG(WARN, "fail to build micro block of meta", K(ret)); - } else if (row_count_ <= 0 && micro_block_desc.get_block_size() <= ObMetaDiskAddr::ROOT_BLOCK_SIZE_LIMIT) { + } else if (row_count_ <= 0 && micro_block_desc.get_block_size() <= ROOT_BLOCK_SIZE_LIMIT) { // meta block's size is smaller than ROOT_BLOCK_SIZE_LIMIT, all meta data will be stored in root if (OB_FAIL(ObBaseIndexBlockBuilder::close(*allocator_, tree_info))) { STORAGE_LOG(WARN, "fail to close index tree of meta", K(ret)); @@ -2356,7 +2287,6 @@ int ObIndexBlockRebuilder::inner_get_macro_meta( ObIMicroBlockReader *micro_reader; ObMicroBlockData micro_data; ObMicroBlockData meta_block; - ObTableReadInfo read_info; ObDatumRow datum_row; ObDataMacroBlockMeta tmp_macro_meta; ObDataMacroBlockMeta* tmp_meta_ptr = nullptr; @@ -2364,8 +2294,7 @@ int ObIndexBlockRebuilder::inner_get_macro_meta( if (OB_UNLIKELY(size <= 0 || !macro_id.is_valid()) || OB_ISNULL(buf)) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "invalid argument", K(ret), KP(buf), K(size), K(macro_id)); - } else if (OB_FAIL(get_meta_block_and_read_info(buf, size, allocator, macro_header, micro_data, - read_info))) { + } else if (OB_FAIL(get_meta_block(buf, size, allocator, macro_header, micro_data))) { STORAGE_LOG(WARN, "fail to get meta block and read info", K(ret), KP(buf), K(size)); } else if (OB_FAIL(reader.decrypt_and_decompress_data( macro_header, @@ -2383,10 +2312,10 @@ int ObIndexBlockRebuilder::inner_get_macro_meta( } else if (OB_FAIL(micro_reader_helper.get_reader(meta_block.get_store_type(), micro_reader))) { STORAGE_LOG(WARN, "fail to get micro reader by store type", K(ret), K(meta_block.get_store_type())); - } else if (OB_FAIL(micro_reader->init(meta_block, read_info))) { + } else if (OB_FAIL(micro_reader->init(meta_block, nullptr))) { STORAGE_LOG(WARN, "fail to init micro reader", K(ret)); - } else if (OB_FAIL(datum_row.init(allocator, read_info.get_request_count()))) { - STORAGE_LOG(WARN, "fail to init datum row", K(ret), K(read_info)); + } else if (OB_FAIL(datum_row.init(allocator, macro_header.fixed_header_.rowkey_column_count_ + 1))) { + STORAGE_LOG(WARN, "fail to init datum row", K(ret)); } else if (OB_FAIL(micro_reader->get_row(0, datum_row))) { STORAGE_LOG(WARN, "fail to get meta row", K(ret)); } else if (OB_FAIL(tmp_macro_meta.parse_row(datum_row))) { @@ -2435,13 +2364,12 @@ int ObIndexBlockRebuilder::append_macro_row( return ret; } -int ObIndexBlockRebuilder::get_meta_block_and_read_info( +int ObIndexBlockRebuilder::get_meta_block( const char *buf, const int64_t buf_size, common::ObIAllocator &allocator, ObSSTableMacroBlockHeader ¯o_header, - ObMicroBlockData &meta_block, - ObTableReadInfo &read_info) + ObMicroBlockData &meta_block) { int ret = OB_SUCCESS; int64_t pos = 0; @@ -2458,52 +2386,10 @@ int ObIndexBlockRebuilder::get_meta_block_and_read_info( } else if (OB_UNLIKELY(!macro_header.is_valid())) { ret = OB_INVALID_DATA; STORAGE_LOG(WARN, "invalid macro header", K(ret), K(macro_header)); - } else if (OB_FAIL(build_macro_meta_read_info(macro_header, allocator, read_info))) { - STORAGE_LOG(WARN, "fail to build macro meta read info", K(ret), K(macro_header)); } else { meta_block.get_buf() = buf + macro_header.fixed_header_.meta_block_offset_; meta_block.get_buf_size() = macro_header.fixed_header_.meta_block_size_; - STORAGE_LOG(DEBUG, "meta block and read info", K(read_info), K(macro_header)); - } - return ret; -} - -int ObIndexBlockRebuilder::build_macro_meta_read_info( - const ObSSTableMacroBlockHeader &header, - common::ObIAllocator &allocator, - ObTableReadInfo &read_info) -{ - int ret = OB_SUCCESS; - ObSEArray columns; - const int64_t column_cnt = header.fixed_header_.rowkey_column_count_; - const ObObjMeta *column_types = header.column_types_; - const common::ObOrderType *col_orders = header.column_orders_; - share::schema::ObColDesc col_desc; - for (int64_t i = 0; OB_SUCC(ret) && i < column_cnt; ++i) { - col_desc.col_id_ = 0; - col_desc.col_type_ = column_types[i]; - col_desc.col_order_ = col_orders[i]; - if (OB_FAIL(columns.push_back(col_desc))) { - STORAGE_LOG(WARN, "fail to push col desc to columns", K(ret)); - } - } - if (OB_SUCC(ret)) { - ObObjMeta meta; - meta.set_varchar(); - meta.set_collation_type(CS_TYPE_BINARY); - col_desc.col_id_ = static_cast(header.fixed_header_.column_count_ + OB_APP_MIN_COLUMN_ID); - col_desc.col_type_ = meta; - col_desc.col_order_ = DESC; - if (OB_FAIL(columns.push_back(col_desc))) { - STORAGE_LOG(WARN, "fail to push back last column for index", K(ret), K(col_desc)); - } else if (OB_FAIL(read_info.init(allocator, - header.fixed_header_.column_count_ - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(), - header.fixed_header_.rowkey_column_count_ - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(), - lib::is_oracle_mode(), - columns, - true))) { - STORAGE_LOG(WARN, "fail to init read info", K(ret), K(header), K(columns)); - } + STORAGE_LOG(DEBUG, "meta block and read info", K(macro_header)); } return ret; } diff --git a/src/storage/blocksstable/ob_index_block_builder.h b/src/storage/blocksstable/ob_index_block_builder.h index 8bdd1a759..1ac09261b 100644 --- a/src/storage/blocksstable/ob_index_block_builder.h +++ b/src/storage/blocksstable/ob_index_block_builder.h @@ -172,16 +172,7 @@ public: bool is_valid() const; void reset(); int assign(const ObSSTableMergeRes &src); - int fill_column_checksum( - const ObStorageSchema *schema, - common::ObIArray &column_checksums) const; - int fill_column_checksum( - const common::ObIArray &column_default_checksum, - common::ObIArray &column_checksums) const; int prepare_column_checksum_array(const int64_t data_column_cnt); - static int fill_column_default_checksum_from_schema( - const ObStorageSchema *schema, - common::ObIArray &column_default_checksum); static int fill_column_checksum_for_empty_major( const int64_t column_count, common::ObIArray &column_checksums); @@ -195,7 +186,7 @@ public: } TO_STRING_KV(K_(root_desc), K_(data_root_desc), K(data_block_ids_.count()), K(other_block_ids_.count()), K_(index_blocks_cnt), K_(data_blocks_cnt), K_(micro_block_cnt), - K_(data_column_cnt), K_(data_column_checksums), K_(data_default_column_rows_cnt), + K_(data_column_cnt), K_(data_column_checksums), K_(row_count), K_(max_merged_trans_version), K_(contain_uncommitted_row), K_(occupy_size), K_(original_size), K_(data_checksum), K_(use_old_macro_block_count), K_(compressor_type), K_(root_row_store_type), K_(nested_offset), K_(nested_size), @@ -217,7 +208,6 @@ public: int64_t data_checksum_; int64_t use_old_macro_block_count_; common::ObSEArray data_column_checksums_; - common::ObSEArray data_default_column_rows_cnt_; common::ObCompressorType compressor_type_; int64_t encrypt_id_; int64_t master_key_id_; @@ -267,10 +257,12 @@ private: int64_t calc_basic_micro_block_data_offset(const uint64_t column_cnt); protected: + static const int64_t ROOT_BLOCK_SIZE_LIMIT = 16 << 10; // 16KB + bool is_inited_; bool is_closed_; ObDataStoreDesc *index_store_desc_; - ObTableReadInfo idx_read_info_; + ObRowkeyReadInfo idx_read_info_; ObIndexBlockRowBuilder row_builder_; ObDatumRowkey last_rowkey_; common::ObArenaAllocator rowkey_allocator_; @@ -395,17 +387,12 @@ private: ObDataMacroBlockMeta *¯o_meta, int64_t &meta_block_offset, int64_t &meta_block_size); - static int get_meta_block_and_read_info( + static int get_meta_block( const char *buf, const int64_t buf_size, common::ObIAllocator &allocator, ObSSTableMacroBlockHeader &header, - ObMicroBlockData &meta_block, - ObTableReadInfo &read_info); - static int build_macro_meta_read_info( - const ObSSTableMacroBlockHeader &header, - common::ObIAllocator &allocator, - ObTableReadInfo &read_info); + ObMicroBlockData &meta_block); private: bool is_inited_; lib::ObMutex mutex_; @@ -447,7 +434,7 @@ public: ObIndexMicroBlockDesc *&root_micro_block_desc, ObMacroMetasArray *¯o_meta_list); int append_root(ObIndexMicroBlockDesc &root_micro_block_desc); - int close(const int64_t column_cnt, ObSSTableMergeRes &res); + int close(ObSSTableMergeRes &res); const ObDataStoreDesc &get_index_store_desc() const { return index_store_desc_; } TO_STRING_KV(K(roots_.count())); public: diff --git a/src/storage/blocksstable/ob_index_block_macro_iterator.cpp b/src/storage/blocksstable/ob_index_block_macro_iterator.cpp index 97607049b..31d0af6b9 100644 --- a/src/storage/blocksstable/ob_index_block_macro_iterator.cpp +++ b/src/storage/blocksstable/ob_index_block_macro_iterator.cpp @@ -18,7 +18,7 @@ using namespace storage; namespace blocksstable { ObIndexBlockMacroIterator::ObIndexBlockMacroIterator() - : sstable_(nullptr), index_read_info_(nullptr), iter_range_(nullptr), + : sstable_(nullptr), iter_range_(nullptr), tree_cursor_(), allocator_(nullptr), cur_idx_(-1), begin_(),end_(), curr_key_(), prev_key_(), curr_key_buf_(nullptr), prev_key_buf_(nullptr), micro_index_infos_(), @@ -32,7 +32,6 @@ ObIndexBlockMacroIterator::~ObIndexBlockMacroIterator() void ObIndexBlockMacroIterator::reset() { sstable_ = nullptr; - index_read_info_ = nullptr; iter_range_ = nullptr; if (need_record_micro_info_ && hold_item_.is_block_allocated_) { tree_cursor_.release_held_path_item(hold_item_); @@ -65,7 +64,7 @@ void ObIndexBlockMacroIterator::reset() { int ObIndexBlockMacroIterator::open( ObSSTable &sstable, const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse, const bool need_record_micro_info) { @@ -81,20 +80,19 @@ int ObIndexBlockMacroIterator::open( } else if (OB_UNLIKELY(!sstable.is_valid() || !range.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("SSTable is not valid", K(ret), K(sstable), K(range)); - } else if (sstable.get_meta().is_empty()) { + } else if (sstable.is_empty()) { is_iter_end_ = true; - } else if (OB_FAIL(sstable.get_last_rowkey(index_read_info, allocator, sstable_endkey))) { + } else if (OB_FAIL(sstable.get_last_rowkey(allocator, sstable_endkey))) { LOG_WARN("Fail to get last rowkey of sstable", K(ret)); } else if (OB_FAIL(sstable_endkey.compare( - range.get_start_key(), index_read_info.get_datum_utils(), cmp_ret))) { + range.get_start_key(), rowkey_read_info.get_datum_utils(), cmp_ret))) { LOG_WARN("Fail to compare sstable endkey and range start key", K(ret)); } else if (cmp_ret < 0 || (0 == cmp_ret && !range.get_border_flag().inclusive_start())) { is_iter_end_ = true; - } else if (OB_FAIL(tree_cursor_.init(sstable, allocator, &index_read_info))) { + } else if (OB_FAIL(tree_cursor_.init(sstable, allocator, &rowkey_read_info))) { LOG_WARN("Fail to init tree cursor", K(ret), K(sstable)); } else { - const int64_t schema_rowkey_cnt = sstable.get_meta().get_basic_meta().rowkey_column_count_ - - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + const int64_t schema_rowkey_cnt = rowkey_read_info.get_schema_rowkey_count(); const bool end_is_multi_version_rowkey = schema_rowkey_cnt < range.get_end_key().get_datum_cnt(); if (is_reverse) { if (OB_FAIL(locate_macro_block( @@ -153,7 +151,6 @@ int ObIndexBlockMacroIterator::open( if (OB_SUCC(ret) && !is_iter_end_) { sstable_ = &sstable; - index_read_info_ = &index_read_info; iter_range_ = ⦥ allocator_ = &allocator; is_reverse_scan_ = is_reverse; @@ -337,7 +334,7 @@ void ObDualMacroMetaIterator::reset() int ObDualMacroMetaIterator::open( ObSSTable &sstable, const ObDatumRange &query_range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse_scan, const bool need_record_micro_info) @@ -350,7 +347,7 @@ int ObDualMacroMetaIterator::open( } else if (OB_FAIL(macro_iter_.open( sstable, query_range, - index_read_info, + rowkey_read_info, allocator, is_reverse_scan, true /* need record micro index info */))) { @@ -359,7 +356,7 @@ int ObDualMacroMetaIterator::open( query_range, blocksstable::DATA_BLOCK_META, sstable, - index_read_info, + rowkey_read_info, allocator, is_reverse_scan))) { LOG_WARN("Fail to open secondary meta iterator", K(ret)); diff --git a/src/storage/blocksstable/ob_index_block_macro_iterator.h b/src/storage/blocksstable/ob_index_block_macro_iterator.h index 11bf23e11..43fb27059 100644 --- a/src/storage/blocksstable/ob_index_block_macro_iterator.h +++ b/src/storage/blocksstable/ob_index_block_macro_iterator.h @@ -70,7 +70,7 @@ public: virtual int open( ObSSTable &sstable, const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse = false, const bool need_record_micro_info = false) = 0; @@ -91,7 +91,7 @@ public: virtual int open( ObSSTable &sstable, const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse = false, const bool need_record_micro_info = false) override; @@ -120,7 +120,6 @@ private: private: const blocksstable::ObSSTable *sstable_; - const ObTableReadInfo *index_read_info_; const ObDatumRange *iter_range_; ObIndexBlockTreeCursor tree_cursor_; common::ObIAllocator *allocator_; // allocator for member struct and macro endkeys @@ -155,7 +154,7 @@ public: virtual int open( ObSSTable &sstable, const ObDatumRange &query_range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse_scan = false, const bool need_record_micro_info = false) override; diff --git a/src/storage/blocksstable/ob_index_block_row_scanner.cpp b/src/storage/blocksstable/ob_index_block_row_scanner.cpp index 07d7da1c7..e20115c35 100644 --- a/src/storage/blocksstable/ob_index_block_row_scanner.cpp +++ b/src/storage/blocksstable/ob_index_block_row_scanner.cpp @@ -51,7 +51,6 @@ ObIndexBlockDataTransformer::~ObIndexBlockDataTransformer() // Transform block data to look-up format and store in transform buffer int ObIndexBlockDataTransformer::transform( - const ObTableReadInfo &read_info, const ObMicroBlockData &block_data, char *transform_buf, int64_t buf_len) @@ -63,24 +62,19 @@ int ObIndexBlockDataTransformer::transform( ObDatumRow row; ObIMicroBlockReader *micro_reader = nullptr; ObIndexBlockDataHeader *idx_header = nullptr; - ObObjMeta *col_meta_array = nullptr; ObDatumRowkey *rowkey_arr = nullptr; ObStorageDatum *datum_buf = nullptr; char *data_buf = transform_buf; const ObMicroBlockHeader *micro_block_header = reinterpret_cast(block_data.get_buf()); - int64_t col_cnt = read_info.get_request_count(); - if (OB_UNLIKELY(!read_info.is_valid() - || !block_data.is_valid() - || !micro_block_header->is_valid() - || read_info.get_request_count() != micro_block_header->column_count_)) { + int64_t col_cnt = micro_block_header->rowkey_column_count_ + 1; + if (OB_UNLIKELY(!block_data.is_valid() || !micro_block_header->is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid argument", - K(ret), K(read_info), K(block_data), KPC(micro_block_header)); + LOG_WARN("Invalid argument", K(ret), K(block_data), KPC(micro_block_header)); } else if (OB_FAIL(get_reader(block_data.get_store_type(), micro_reader))) { LOG_WARN("Fail to set micro block reader", K(ret)); - } else if (OB_FAIL(micro_reader->init(block_data, read_info))) { - LOG_WARN("Fail to init micro block reader", K(ret), K(block_data), K(read_info)); + } else if (OB_FAIL(micro_reader->init(block_data, nullptr))) { + LOG_WARN("Fail to init micro block reader", K(ret), K(block_data)); } else if (OB_FAIL(micro_reader->get_row_count(row_cnt))) { LOG_WARN("Fail to get row count", K(ret)); } else if (FALSE_IT(size_required = get_transformed_block_mem_size(block_data))) { @@ -92,15 +86,10 @@ int ObIndexBlockDataTransformer::transform( } else { idx_header = reinterpret_cast(data_buf); data_buf += sizeof(ObIndexBlockDataHeader); - col_meta_array = reinterpret_cast(data_buf); - data_buf += sizeof(ObObjMeta) * col_cnt; rowkey_arr = reinterpret_cast(data_buf); data_buf += sizeof(ObDatumRowkey) * row_cnt; datum_buf = reinterpret_cast (data_buf); - const ObColDescIArray &col_descs = read_info.get_columns_desc(); - for (int64_t i = 0; OB_SUCC(ret) && i < col_cnt; ++i) { - col_meta_array[i] = col_descs.at(i).col_type_; - } + for (int64_t i = 0; OB_SUCC(ret) && i < row_cnt; ++i) { row.reuse(); if (OB_FAIL(micro_reader->get_row(i, row))) { @@ -119,7 +108,6 @@ int ObIndexBlockDataTransformer::transform( idx_header->row_cnt_ = row_cnt; idx_header->col_cnt_ = col_cnt; idx_header->rowkey_array_ = rowkey_arr; - idx_header->col_meta_array_ = col_meta_array; idx_header->datum_array_ = datum_buf; STORAGE_LOG(DEBUG, "chaser debug transfer index block", KPC(idx_header), K(block_data.get_store_type())); } @@ -144,31 +132,11 @@ int ObIndexBlockDataTransformer::update_index_block( || OB_ISNULL(micro_block_header) || OB_UNLIKELY(!micro_block_header->is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid src micro block data", K(ret), + LOG_WARN("Invalid src micro block data", K(ret), K(src_idx_header), KP(micro_data), K(micro_data_size), KP(transform_buf), K(buf_len)); } else { - ObArenaAllocator allocator; - ObTableReadInfo index_read_info; - ObSEArray index_col_desc; ObMicroBlockData target_block(micro_data, micro_data_size); - const int64_t schema_rowkey_cnt = - micro_block_header->rowkey_column_count_ - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); - if (OB_FAIL(index_col_desc.reserve(micro_block_header->column_count_))) { - LOG_WARN("Fail to reserve memory for col desc", K(ret)); - } - ObColDesc col_desc; - for (int64_t i = 0; OB_SUCC(ret) && i < micro_block_header->column_count_; ++i) { - col_desc.reset(); - col_desc.col_type_ = src_idx_header.col_meta_array_[i]; - if (OB_FAIL(index_col_desc.push_back(col_desc))) { - LOG_WARN("Fail to push col desc into array", K(ret)); - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(index_read_info.init(allocator, schema_rowkey_cnt + 1, schema_rowkey_cnt, lib::is_oracle_mode(), index_col_desc, true))) { - LOG_WARN("Fail to init column read info", K(ret), KPC(micro_block_header)); - } else if (OB_FAIL(transform(index_read_info, target_block, transform_buf, buf_len))) { + if (OB_FAIL(transform(target_block, transform_buf, buf_len))) { LOG_WARN("Fail to re transform index block data", K(ret)); } } @@ -181,7 +149,6 @@ int64_t ObIndexBlockDataTransformer::get_transformed_block_mem_size( { return sizeof(ObIndexBlockDataHeader) + row_cnt * sizeof(ObDatumRowkey) - + idx_col_cnt * sizeof(ObObjMeta) + row_cnt * sizeof(ObStorageDatum) * idx_col_cnt; } @@ -210,7 +177,7 @@ ObIndexBlockRowScanner::ObIndexBlockRowScanner() idx_data_header_(nullptr), macro_id_(), allocator_(nullptr), micro_reader_helper_(), micro_reader_(nullptr), block_meta_tree_(nullptr), datum_row_(nullptr), endkey_(), - idx_row_parser_(), index_read_info_(nullptr), + idx_row_parser_(), datum_utils_(nullptr), current_(ObIMicroBlockReaderInfo::INVALID_ROW_INDEX), start_(ObIMicroBlockReaderInfo::INVALID_ROW_INDEX), end_(ObIMicroBlockReaderInfo::INVALID_ROW_INDEX), @@ -247,7 +214,7 @@ void ObIndexBlockRowScanner::reset() } datum_row_ = nullptr; } - index_read_info_ = nullptr; + datum_utils_ = nullptr; current_ = ObIMicroBlockReaderInfo::INVALID_ROW_INDEX; start_ = ObIMicroBlockReaderInfo::INVALID_ROW_INDEX; end_ = ObIMicroBlockReaderInfo::INVALID_ROW_INDEX; @@ -265,7 +232,7 @@ void ObIndexBlockRowScanner::reset() int ObIndexBlockRowScanner::init( const ObIArray &agg_projector, const ObIArray &agg_column_schema, - const ObTableReadInfo *index_read_info, + const ObStorageDatumUtils &datum_utils, ObIAllocator &allocator, const common::ObQueryFlag &query_flag, const int64_t nested_offset) @@ -274,9 +241,9 @@ int ObIndexBlockRowScanner::init( if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("Already inited", K(ret)); - } else if (OB_UNLIKELY(agg_projector.count() != agg_column_schema.count() || nullptr == index_read_info)) { + } else if (OB_UNLIKELY(agg_projector.count() != agg_column_schema.count())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("Agg meta count not same", K(ret), K(agg_projector), K(agg_column_schema), KP(index_read_info)); + LOG_WARN("Agg meta count not same", K(ret), K(agg_projector), K(agg_column_schema)); } else if (OB_FAIL(micro_reader_helper_.init(allocator))) { LOG_WARN("Fail to init micro reader helper", K(ret)); } else { @@ -285,7 +252,7 @@ int ObIndexBlockRowScanner::init( allocator_ = &allocator; is_reverse_scan_ = query_flag.is_reverse_scan(); step_ = is_reverse_scan_ ? -1 : 1; - index_read_info_ = index_read_info; + datum_utils_ = &datum_utils; nested_offset_ = nested_offset; is_inited_ = true; } @@ -440,16 +407,17 @@ int ObIndexBlockRowScanner::check_blockscan( if (IndexFormat::RAW_DATA == index_format_) { ObDatumRowkey last_endkey; ObDatumRow tmp_datum_row; // Normally will use local datum buf, won't allocate memory - if (OB_FAIL(tmp_datum_row.init(index_read_info_->get_request_count()))) { + const int64_t request_cnt = datum_utils_->get_rowkey_count() + 1; + if (OB_FAIL(tmp_datum_row.init(request_cnt))) { LOG_WARN("Fail to init tmp_datum_row", K(ret)); } else if (OB_FAIL(micro_reader_->get_row(end_, tmp_datum_row))) { LOG_WARN("Fail to get last row of micro block", K(ret), K_(end)); - } else if (OB_FAIL(last_endkey.assign(tmp_datum_row.storage_datums_, index_read_info_->get_rowkey_count()))) { + } else if (OB_FAIL(last_endkey.assign(tmp_datum_row.storage_datums_, datum_utils_->get_rowkey_count()))) { LOG_WARN("Fail to assign storage datum to endkey", K(ret), K(tmp_datum_row)); - } else if (OB_FAIL(last_endkey.compare(rowkey, index_read_info_->get_datum_utils(), cmp_ret))) { + } else if (OB_FAIL(last_endkey.compare(rowkey, *datum_utils_, cmp_ret))) { LOG_WARN("Fail to compare rowkey", K(ret), K(last_endkey), K(rowkey)); } - } else if (OB_FAIL((idx_data_header_->rowkey_array_ + end_)->compare(rowkey, index_read_info_->get_datum_utils(), cmp_ret))) { + } else if (OB_FAIL((idx_data_header_->rowkey_array_ + end_)->compare(rowkey, *datum_utils_, cmp_ret))) { LOG_WARN("Fail to compare rowkey", K(ret), K(rowkey)); } @@ -471,12 +439,13 @@ int ObIndexBlockRowScanner::init_by_micro_data(const ObMicroBlockData &idx_block if (OB_FAIL(micro_reader_helper_.get_reader(idx_block_data.get_store_type(), micro_reader_))) { LOG_WARN("Fail to get micro block reader", K(ret), K(idx_block_data), K(idx_block_data.get_store_type())); - } else if (OB_FAIL(micro_reader_->init(idx_block_data, *index_read_info_))) { - LOG_WARN("Fail to init micro reader", K(ret), K(idx_block_data), KPC(index_read_info_)); + } else if (OB_FAIL(micro_reader_->init(idx_block_data, datum_utils_))) { + LOG_WARN("Fail to init micro reader", K(ret), K(idx_block_data)); } else if (OB_FAIL(init_datum_row())) { LOG_WARN("Fail to init datum row", K(ret)); } else { index_format_ = IndexFormat::RAW_DATA; + idx_data_header_ = nullptr; } } else { idx_data_header_ = reinterpret_cast(idx_block_data.get_extra_buf()); @@ -515,7 +484,7 @@ int ObIndexBlockRowScanner::locate_key(const ObDatumRowkey &rowkey) } LOG_TRACE("Binary search rowkey with micro reader", K(ret), K(range), K(begin_idx), K(rowkey)); } else if (IndexFormat::TRANSFORMED == index_format_) { - ObDatumComparor cmp(index_read_info_->get_datum_utils(), ret); + ObDatumComparor cmp(*datum_utils_, ret); const ObDatumRowkey *first = idx_data_header_->rowkey_array_; const ObDatumRowkey *last = idx_data_header_->rowkey_array_ + idx_data_header_->row_cnt_; const ObDatumRowkey *found = std::lower_bound(first, last, rowkey, cmp); @@ -538,13 +507,13 @@ int ObIndexBlockRowScanner::locate_key(const ObDatumRowkey &rowkey) ret = OB_ERR_UNEXPECTED; LOG_WARN("block meta tree is null", K(ret)); } else if (OB_FAIL(block_meta_tree_->locate_range(range, - index_read_info_->get_datum_utils(), + *datum_utils_, true,// is_left_border true,// is_right_border begin_idx, end_idx))) { if (OB_UNLIKELY(OB_BEYOND_THE_RANGE != ret)) { - LOG_WARN("locate rowkey failed", K(ret), K(range), KPC(index_read_info_)); + LOG_WARN("locate rowkey failed", K(ret), K(range)); } else { current_ = ObIMicroBlockReaderInfo::INVALID_ROW_INDEX; ret = OB_SUCCESS; // return OB_ITER_END on get_next() for get @@ -574,8 +543,8 @@ int ObIndexBlockRowScanner::locate_range( current_ = ObIMicroBlockReaderInfo::INVALID_ROW_INDEX; if (IndexFormat::TRANSFORMED == index_format_) { bool is_begin_equal = false; - ObDatumComparor lower_bound_cmp(index_read_info_->get_datum_utils(), ret); - ObDatumComparor upper_bound_cmp(index_read_info_->get_datum_utils(), ret, false, false); + ObDatumComparor lower_bound_cmp(*datum_utils_, ret); + ObDatumComparor upper_bound_cmp(*datum_utils_, ret, false, false); const ObDatumRowkey *first = idx_data_header_->rowkey_array_; const ObDatumRowkey *last = idx_data_header_->rowkey_array_ + idx_data_header_->row_cnt_; if (!is_left_border || range.get_start_key().is_min_rowkey()) { @@ -588,7 +557,7 @@ int ObIndexBlockRowScanner::locate_range( ret = OB_BEYOND_THE_RANGE; } else if (!range.get_border_flag().inclusive_start()) { bool is_equal = false; - if (OB_FAIL(start_found->equal(range.get_start_key(), index_read_info_->get_datum_utils(), is_equal))) { + if (OB_FAIL(start_found->equal(range.get_start_key(), *datum_utils_, is_equal))) { STORAGE_LOG(WARN, "Failed to check datum rowkey equal", K(ret), K(range), KPC(start_found)); } else if (is_equal) { ++start_found; @@ -645,12 +614,12 @@ int ObIndexBlockRowScanner::locate_range( ret = OB_ERR_UNEXPECTED; LOG_WARN("block meta tree is null", K(ret)); } else if (OB_FAIL(block_meta_tree_->locate_range(range, - index_read_info_->get_datum_utils(), + *datum_utils_, is_left_border, is_right_border, begin_idx, end_idx))) { - LOG_WARN("locate rowkey failed", K(ret), K(range), KPC(index_read_info_)); + LOG_WARN("locate rowkey failed", K(ret), K(range)); } } else { ret = OB_NOT_SUPPORTED; @@ -665,6 +634,12 @@ int ObIndexBlockRowScanner::locate_range( return ret; } +void ObIndexBlockRowScanner::switch_context(const ObSSTable &sstable, const ObStorageDatumUtils &datum_utils) +{ + nested_offset_ = sstable.get_macro_offset(); + datum_utils_ = &datum_utils; +} + int ObIndexBlockRowScanner::init_datum_row() { int ret = OB_SUCCESS; @@ -676,13 +651,14 @@ int ObIndexBlockRowScanner::init_datum_row() datum_row_ = nullptr; } if (nullptr == datum_row_) { + int64_t request_cnt = datum_utils_->get_rowkey_count() + 1; void *buf = nullptr; if (OB_ISNULL(buf = allocator_->alloc(sizeof(ObDatumRow)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("Fail to allocate memory for datum row", K(ret)); } else if (FALSE_IT(datum_row_ = new (buf) ObDatumRow())) { - } else if (OB_FAIL(datum_row_->init(*allocator_, index_read_info_->get_request_count()))) { - LOG_WARN("Fail to init datum row", K(ret), KPC(index_read_info_)); + } else if (OB_FAIL(datum_row_->init(*allocator_, request_cnt))) { + LOG_WARN("Fail to init datum row", K(ret), K(request_cnt)); } if (OB_FAIL(ret) && nullptr != buf) { @@ -697,7 +673,7 @@ int ObIndexBlockRowScanner::read_curr_idx_row(const ObIndexBlockRowHeader *&idx_ { int ret = OB_SUCCESS; idx_row_header = nullptr; - const int64_t rowkey_column_count = index_read_info_->get_rowkey_count(); + const int64_t rowkey_column_count = datum_utils_->get_rowkey_count(); if (IndexFormat::TRANSFORMED == index_format_) { const char *idx_data_buf = nullptr; if (OB_FAIL(idx_data_header_->get_index_data(current_, idx_data_buf))) { diff --git a/src/storage/blocksstable/ob_index_block_row_scanner.h b/src/storage/blocksstable/ob_index_block_row_scanner.h index 29f1952b6..2a9bb3fbd 100644 --- a/src/storage/blocksstable/ob_index_block_row_scanner.h +++ b/src/storage/blocksstable/ob_index_block_row_scanner.h @@ -38,15 +38,12 @@ struct ObIndexBlockDataHeader return row_cnt_ >= 0 && col_cnt_ > 0 && nullptr != rowkey_array_ - && nullptr != col_meta_array_ && nullptr != datum_array_; } int get_index_data(const int64_t row_idx, const char *&index_ptr) const; int64_t row_cnt_; int64_t col_cnt_; - // Array of column object types - const ObObjMeta *col_meta_array_; // Array of rowkeys in index block const ObDatumRowkey *rowkey_array_; // Array of deserialzed Object array @@ -62,7 +59,6 @@ public: ObIndexBlockDataTransformer(); virtual ~ObIndexBlockDataTransformer(); int transform( - const ObTableReadInfo &read_info, const ObMicroBlockData &block_data, char *transform_buf, int64_t buf_len); @@ -92,7 +88,7 @@ public: int init( const ObIArray &agg_projector, const ObIArray &agg_column_schema, - const storage::ObTableReadInfo *index_read_info, + const ObStorageDatumUtils &datum_utils, ObIAllocator &allocator, const common::ObQueryFlag &query_flag, const int64_t nested_offset); @@ -113,14 +109,11 @@ public: int get_index_row_count(int64_t &index_row_count) const; int check_blockscan(const ObDatumRowkey &rowkey, bool &can_blockscan); OB_INLINE bool is_valid() const { return is_inited_; } - OB_INLINE void switch_context(const ObTableReadInfo *index_read_info, const int64_t nested_offset) { - index_read_info_ = index_read_info; - nested_offset_ = nested_offset; - } + void switch_context(const ObSSTable &sstable, const ObStorageDatumUtils &datum_utils); TO_STRING_KV(K_(current), K_(start), K_(end), K_(step), K_(range_idx), K_(is_get), K_(is_reverse_scan), K_(is_left_border), K_(is_right_border), - K_(is_inited), K_(index_format), K_(macro_id), KPC_(idx_data_header), KPC_(index_read_info)); + K_(is_inited), K_(index_format), K_(macro_id), KPC_(idx_data_header), KPC_(datum_utils)); private: int init_by_micro_data(const ObMicroBlockData &idx_block_data); int locate_key(const ObDatumRowkey &rowkey); @@ -150,7 +143,7 @@ private: ObDatumRow *datum_row_; ObDatumRowkey endkey_; ObIndexBlockRowParser idx_row_parser_; - const ObTableReadInfo *index_read_info_; + const ObStorageDatumUtils *datum_utils_; int64_t current_; int64_t start_; // inclusive int64_t end_; // inclusive diff --git a/src/storage/blocksstable/ob_index_block_row_struct.cpp b/src/storage/blocksstable/ob_index_block_row_struct.cpp index 469788fba..baed9345f 100644 --- a/src/storage/blocksstable/ob_index_block_row_struct.cpp +++ b/src/storage/blocksstable/ob_index_block_row_struct.cpp @@ -133,8 +133,9 @@ int ObIndexBlockRowBuilder::init(const ObDataStoreDesc &desc) STORAGE_LOG(WARN, "Failed to init row", K(ret), K(desc.rowkey_column_count_)); } else { rowkey_column_count_ = desc.rowkey_column_count_; + const ObIArray &descs = desc.get_rowkey_col_descs(); for (int64_t i = 0; i < rowkey_column_count_; ++i) { - rowkey_column_types_[i] = desc.col_desc_array_.at(i).col_type_; + rowkey_column_types_[i] = descs.at(i).col_type_; } is_inited_ = true; } @@ -245,7 +246,7 @@ int ObIndexBlockRowBuilder::calc_data_size(const ObIndexBlockRowDesc &desc, int6 LOG_WARN("Invalid index block row description", K(ret), K(desc)); } else if (desc.is_secondary_meta_) { size = sizeof(ObIndexBlockRowHeader); - } else if (MAJOR_MERGE == desc.data_store_desc_->merge_type_) { + } else if (desc.data_store_desc_->is_major_merge()) { size = sizeof(ObIndexBlockRowHeader); // if (desc.is_pre_aggregated_) { // TODO: @saitong.zst Calculate aggregate size here @@ -292,7 +293,7 @@ int ObIndexBlockRowBuilder::append_header_and_meta(const ObIndexBlockRowDesc &de header_->is_data_block_ = desc.is_data_block_; header_->is_leaf_block_ = desc.is_macro_node_; header_->is_macro_node_ = desc.is_macro_node_; - header_->is_major_node_ = desc.data_store_desc_->merge_type_ == MAJOR_MERGE; + header_->is_major_node_ = desc.data_store_desc_->is_major_merge(); header_->has_string_out_row_ = desc.has_string_out_row_; header_->all_lob_in_row_ = !desc.has_lob_out_row_; // header_->is_pre_aggregated_ = diff --git a/src/storage/blocksstable/ob_index_block_tree_cursor.cpp b/src/storage/blocksstable/ob_index_block_tree_cursor.cpp old mode 100644 new mode 100755 index 4ad188210..743062da3 --- a/src/storage/blocksstable/ob_index_block_tree_cursor.cpp +++ b/src/storage/blocksstable/ob_index_block_tree_cursor.cpp @@ -258,9 +258,9 @@ int ObIndexBlockTreePath::PathItemStack::expand() ObIndexBlockTreeCursor::ObIndexBlockTreeCursor() : cursor_path_(), index_block_cache_(nullptr), reader_(nullptr), micro_reader_helper_(), - sstable_(nullptr), tenant_id_(OB_INVALID_TENANT_ID), rowkey_column_cnt_(0), + tenant_id_(OB_INVALID_TENANT_ID), rowkey_column_cnt_(0), curr_path_item_(), row_(), - idx_row_parser_(), read_info_(nullptr), is_inited_(false) {} + idx_row_parser_(), read_info_(nullptr), sstable_meta_handle_(), is_inited_(false) {} ObIndexBlockTreeCursor::~ObIndexBlockTreeCursor() { @@ -275,6 +275,7 @@ void ObIndexBlockTreeCursor::reset() micro_reader_helper_.reset(); reader_ = nullptr; read_info_ = nullptr; + sstable_meta_handle_.reset(); is_inited_ = false; } } @@ -282,7 +283,7 @@ void ObIndexBlockTreeCursor::reset() int ObIndexBlockTreeCursor::init( const ObSSTable &sstable, ObIAllocator &allocator, - const ObTableReadInfo *read_info, + const ObITableReadInfo *read_info, const TreeType tree_type) { int ret = OB_SUCCESS; @@ -298,22 +299,24 @@ int ObIndexBlockTreeCursor::init( LOG_WARN("Fail to init curr path item pointer", K(ret)); } else if (OB_FAIL(micro_reader_helper_.init(allocator))) { LOG_WARN("Fail to init micro reader helper", K(ret)); + } else if (OB_FAIL(sstable.get_meta(sstable_meta_handle_))) { + LOG_WARN("Fail to get sstable meta handle", K(ret)); } else { - sstable_ = &sstable; tenant_id_ = MTL_ID(); - const ObSSTableMeta &sstable_meta = sstable.get_meta(); ObRowStoreType root_row_store_type - = static_cast(sstable_meta.get_basic_meta().root_row_store_type_); + = static_cast(sstable_meta_handle_.get_sstable_meta().get_basic_meta().root_row_store_type_); curr_path_item_->row_store_type_ = root_row_store_type; read_info_ = read_info; - rowkey_column_cnt_ = read_info_->get_rowkey_count(); + rowkey_column_cnt_ = read_info_->get_schema_rowkey_count() + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); switch (tree_type) { case TreeType::INDEX_BLOCK: { - curr_path_item_->block_data_ = sstable_meta.get_root_info().get_block_data(); + curr_path_item_->block_data_ = + sstable_meta_handle_.get_sstable_meta().get_root_info().get_block_data(); break; } case TreeType::DATA_MACRO_META: { - curr_path_item_->block_data_ = sstable_meta.get_macro_info().get_macro_meta_data(); + curr_path_item_->block_data_ = + sstable_meta_handle_.get_sstable_meta().get_macro_info().get_macro_meta_data(); break; } default: { @@ -323,13 +326,15 @@ int ObIndexBlockTreeCursor::init( } if (OB_FAIL(ret)) { + } else if (FALSE_IT(root_row_store_type = curr_path_item_->block_data_.get_store_type())) { + } else if (FALSE_IT(curr_path_item_->row_store_type_ = root_row_store_type)) { } else if (OB_FAIL(row_.init(allocator, rowkey_column_cnt_ + 1))) { STORAGE_LOG(WARN, "Failed to init datum row", K(ret)); } else if (nullptr != curr_path_item_->block_data_.get_extra_buf()) { curr_path_item_->is_block_transformed_ = true; } else if (OB_FAIL(set_reader(root_row_store_type))) { LOG_WARN("Fail to set micro block reader", K(ret)); - } else if (OB_FAIL(reader_->init(curr_path_item_->block_data_, *read_info_))) { + } else if (OB_FAIL(reader_->init(curr_path_item_->block_data_, &(read_info_->get_datum_utils())))) { LOG_WARN("Fail to init micro block reader", K(ret)); } @@ -360,7 +365,7 @@ int ObIndexBlockTreeCursor::drill_down( } else if (OB_FAIL(drill_down(rowkey, depth, is_beyond_the_range))) { LOG_WARN("Fail to do lower bound drill down", K(ret)); } else if (FALSE_IT( - compare_schema_rowkey = rowkey.datum_cnt_ == sstable_->get_meta().get_schema_rowkey_column_count())) { + compare_schema_rowkey = rowkey.datum_cnt_ == read_info_->get_schema_rowkey_count())) { } else if (is_lower_bound || rowkey.is_min_rowkey() || rowkey.is_max_rowkey()) { } else { // move to upper bound @@ -416,7 +421,6 @@ int ObIndexBlockTreeCursor::drill_down( ret = OB_NOT_INIT; LOG_WARN("Tree cursor not inited", K(ret)); } else { - const ObSSTableMeta &sstable_meta = sstable_->get_meta(); switch (depth) { case ONE_LEVEL: { if (!cursor_path_.empty()) { @@ -429,7 +433,7 @@ int ObIndexBlockTreeCursor::drill_down( } else { curr_path_item_->is_root_micro_block_ = true; curr_path_item_->row_store_type_ - = static_cast(sstable_meta.get_basic_meta().root_row_store_type_); + = static_cast(sstable_meta_handle_.get_sstable_meta().get_basic_meta().root_row_store_type_); } if (OB_FAIL(ret)) { @@ -459,7 +463,7 @@ int ObIndexBlockTreeCursor::drill_down( } else { curr_path_item_->is_root_micro_block_ = true; curr_path_item_->row_store_type_ - = static_cast(sstable_meta.get_basic_meta().root_row_store_type_); + = static_cast(sstable_meta_handle_.get_sstable_meta().get_basic_meta().root_row_store_type_); } while (OB_SUCC(ret) && !reach_target_depth) { @@ -510,7 +514,7 @@ int ObIndexBlockTreeCursor::drill_down() } else if (OB_FAIL(set_reader(static_cast(new_row_store_type)))) { LOG_WARN("Fail to set row reader", K(ret), K(new_row_store_type)); } else if (OB_FAIL(reader_->init( - curr_path_item_->block_data_, *read_info_))) { + curr_path_item_->block_data_, &(read_info_->get_datum_utils())))) { LOG_WARN("Fail to get micro block buffer handle", K(ret)); } @@ -686,7 +690,7 @@ int ObIndexBlockTreeCursor::pull_up(const bool cascade, const bool is_reverse_sc } else if (OB_FAIL(set_reader(static_cast(curr_path_item_->row_store_type_)))) { LOG_WARN("Fail to set row reader", K(ret)); } else if (OB_FAIL(reader_->init( - curr_path_item_->block_data_, *read_info_))) { + curr_path_item_->block_data_, &(read_info_->get_datum_utils())))) { LOG_WARN("Fail to init micro block row reader", K(ret), KPC(curr_path_item_)); } else if (OB_FAIL(read_next_level_row(curr_path_item_->curr_row_idx_))) { LOG_WARN("Fail to read next level row", K(ret), KPC(curr_path_item_)); @@ -710,7 +714,7 @@ int ObIndexBlockTreeCursor::pull_up_to_root() } else if (OB_FAIL(set_reader(static_cast(curr_path_item_->row_store_type_)))) { LOG_WARN("Fail to set reader"); } else if (OB_FAIL(reader_->init( - curr_path_item_->block_data_, *read_info_))) { + curr_path_item_->block_data_, &(read_info_->get_datum_utils())))) { LOG_WARN("Fail to init reader", K(ret)); } return ret; @@ -882,7 +886,7 @@ int ObIndexBlockTreeCursor::get_current_endkey(ObDatumRowkey &endkey, const bool { int ret = OB_SUCCESS; const int64_t rowkey_datum_cnt = get_schema_rowkey ? - sstable_->get_meta().get_schema_rowkey_column_count() : rowkey_column_cnt_; + read_info_->get_schema_rowkey_count() : rowkey_column_cnt_; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("Fail to get current endkey", K(ret)); @@ -978,12 +982,14 @@ int ObIndexBlockTreeCursor::get_next_level_block( { int ret = OB_SUCCESS; int64_t absolute_offset = 0; + ObSSTableMetaHandle meta_handle; if (OB_UNLIKELY(!macro_block_id.is_valid() || !idx_row_header.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid macro block id or index block row data", K(ret), K(macro_block_id), K(idx_row_header)); } else { - absolute_offset = sstable_->get_macro_offset() + idx_row_header.get_block_offset(); + absolute_offset = sstable_meta_handle_.get_sstable_meta().get_macro_info().get_nested_offset() + + idx_row_header.get_block_offset(); } if (OB_FAIL(ret)) { diff --git a/src/storage/blocksstable/ob_index_block_tree_cursor.h b/src/storage/blocksstable/ob_index_block_tree_cursor.h index 614ab1cca..3c41bbe43 100644 --- a/src/storage/blocksstable/ob_index_block_tree_cursor.h +++ b/src/storage/blocksstable/ob_index_block_tree_cursor.h @@ -133,7 +133,7 @@ public: int init( const blocksstable::ObSSTable &sstable, ObIAllocator &allocator, - const ObTableReadInfo *read_info, + const ObITableReadInfo *read_info, const TreeType tree_type = TreeType::INDEX_BLOCK); // Interfaces to move cursor on index block tree @@ -150,7 +150,7 @@ public: int pull_up_to_root(); int move_forward(const bool is_reverse_scan); - TO_STRING_KV(K_(cursor_path), KP_(sstable), K_(curr_path_item)); + TO_STRING_KV(K_(cursor_path), K_(curr_path_item)); public: // Interfaces to get data on index tree via cursor int get_idx_parser(const ObIndexBlockRowParser *&parser); @@ -216,7 +216,6 @@ private: ObMicroBlockReaderHelper micro_reader_helper_; // Micro Block Cache Read/Prefetch - const blocksstable::ObSSTable *sstable_; int64_t tenant_id_; int64_t rowkey_column_cnt_; @@ -224,7 +223,8 @@ private: ObDatumRow row_; ObIndexBlockRowParser idx_row_parser_; - const ObTableReadInfo *read_info_; + const ObITableReadInfo *read_info_; + ObSSTableMetaHandle sstable_meta_handle_; bool is_inited_; }; diff --git a/src/storage/blocksstable/ob_macro_block.cpp b/src/storage/blocksstable/ob_macro_block.cpp index d0dd7e9ba..21898728f 100644 --- a/src/storage/blocksstable/ob_macro_block.cpp +++ b/src/storage/blocksstable/ob_macro_block.cpp @@ -42,6 +42,7 @@ namespace blocksstable */ ObDataStoreDesc::ObDataStoreDesc() : allocator_("OB_DATA_STORE_D"), + col_default_checksum_array_(allocator_), col_desc_array_(allocator_) { reset(); @@ -137,6 +138,12 @@ int ObDataStoreDesc::cal_row_store_type(const share::schema::ObMergeSchema &merg } else if (OB_FAIL(get_emergency_row_store_type())) { STORAGE_LOG(WARN, "Failed to check and get emergency row store type", K(ret)); } + + if (OB_SUCC(ret)) { + if (ObStoreFormat::is_row_store_type_with_encoding(row_store_type_)) { + encoder_opt_.set_store_type(row_store_type_); + } + } } return ret; @@ -149,6 +156,95 @@ int ObDataStoreDesc::init( const ObMergeType merge_type, const int64_t snapshot_version, const int64_t cluster_version) +{ + int ret = OB_SUCCESS; + if (!merge_schema.is_valid() || snapshot_version <= 0) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "arguments is invalid", K(ret), K(merge_schema), K(snapshot_version)); + } else if (OB_FAIL(inner_init(merge_schema, ls_id, tablet_id, merge_type, snapshot_version, cluster_version))) { + STORAGE_LOG(WARN, "failed to inner init data desc, ", K(ret)); + } else if (OB_FAIL(init_col_default_checksum_array(merge_schema, storage::is_major_merge_type(merge_type) || storage::is_meta_major_merge(merge_type) /*init_by_schema*/))) { + STORAGE_LOG(WARN, "failed to init col default checksum array", K(ret), K(merge_type), K(merge_schema)); + } else { + row_column_count_ = full_stored_col_cnt_; + const bool is_major = (storage::is_major_merge_type(merge_type) || storage::is_meta_major_merge(merge_type)); + if (is_major) { + if (OB_FAIL(col_desc_array_.init(row_column_count_))) { + STORAGE_LOG(WARN, "Failed to reserve column desc array", K(ret)); + } else if (OB_FAIL(merge_schema.get_multi_version_column_descs(col_desc_array_))) { + STORAGE_LOG(WARN, "Failed to generate multi version column ids", K(ret)); + } + } else { + if (OB_FAIL(col_desc_array_.init(rowkey_column_count_))) { + STORAGE_LOG(WARN, "fail to reserve column desc array", K(ret)); + } else if (OB_FAIL(merge_schema.get_mulit_version_rowkey_column_ids(col_desc_array_))) { + STORAGE_LOG(WARN, "fail to get rowkey column ids", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (FALSE_IT(fresh_col_meta())) { + } else if (OB_FAIL(datum_utils_.init(col_desc_array_, schema_rowkey_col_cnt_, lib::is_oracle_mode(), allocator_))) { + STORAGE_LOG(WARN, "Failed to init datum utils", K(ret)); + } else { + STORAGE_LOG(TRACE, "success to init data desc", K(ret), KPC(this), K(merge_schema), K(merge_type)); + } + } + return ret; +} + + +/* +* use storage schema to init ObDataStoreDesc +* all cells in col_default_checksum_array_ will assigned to 0 +* means all macro should contain all columns in schema +*/ +int ObDataStoreDesc::init_as_index( + const ObMergeSchema &merge_schema, + const share::ObLSID &ls_id, + const common::ObTabletID tablet_id, + const ObMergeType merge_type, + const int64_t snapshot_version, + const int64_t cluster_version) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(inner_init(merge_schema, ls_id, tablet_id, merge_type, snapshot_version, cluster_version))) { + STORAGE_LOG(WARN, "Fail to inner init data desc", K(ret)); + } else if (OB_FAIL(init_col_default_checksum_array(merge_schema, !merge_schema.is_column_info_simplified()))) { + STORAGE_LOG(WARN, "failed to init col default checksum array", K(ret), K(merge_type), K(merge_schema)); + } else { + row_column_count_ = rowkey_column_count_ + 1; + need_prebuild_bloomfilter_ = false; + if (OB_FAIL(col_desc_array_.init(row_column_count_))) { + STORAGE_LOG(WARN, "fail to reserve column desc array", K(ret)); + } else if (OB_FAIL(merge_schema.get_mulit_version_rowkey_column_ids(col_desc_array_))) { + STORAGE_LOG(WARN, "fail to get rowkey column ids", K(ret)); + } else if (OB_FAIL(datum_utils_.init(col_desc_array_, schema_rowkey_col_cnt_, lib::is_oracle_mode(), allocator_))) { + STORAGE_LOG(WARN, "Failed to init datum utils", K(ret)); + } else { + ObObjMeta meta; + meta.set_varchar(); + meta.set_collation_type(CS_TYPE_BINARY); + share::schema::ObColDesc col; + col.col_id_ = static_cast(row_column_count_ + OB_APP_MIN_COLUMN_ID); + col.col_type_ = meta; + col.col_order_ = DESC; + if (OB_FAIL(col_desc_array_.push_back(col))) { + STORAGE_LOG(WARN, "fail to push back last col for index", K(ret), K(col)); + } else { + STORAGE_LOG(INFO, "success to init data desc as index", K(ret), K(merge_schema), KPC(this)); + } + } + } + return ret; +} + +int ObDataStoreDesc::inner_init( + const ObMergeSchema &merge_schema, + const share::ObLSID &ls_id, + const common::ObTabletID tablet_id, + const ObMergeType merge_type, + const int64_t snapshot_version, + const int64_t cluster_version) { int ret = OB_SUCCESS; if (!merge_schema.is_valid() || snapshot_version <= 0) { @@ -156,108 +252,123 @@ int ObDataStoreDesc::init( STORAGE_LOG(WARN, "arguments is invalid", K(ret), K(merge_schema), K(snapshot_version)); } else { reset(); - const int64_t pct_free = merge_schema.get_pctfree(); - const bool is_major = (storage::is_major_merge_type(merge_type) || storage::is_meta_major_merge(merge_type)); - micro_block_size_ = merge_schema.get_block_size(); - macro_block_size_ = OB_SERVER_BLOCK_MGR.get_macro_block_size(); - if (pct_free >= 0 && pct_free <= 50) { - macro_store_size_ = macro_block_size_ * (100 - pct_free) / 100; - } else { - macro_store_size_ = macro_block_size_ * DEFAULT_RESERVE_PERCENT / 100; - } merge_type_ = merge_type; ls_id_ = ls_id; tablet_id_ = tablet_id; - schema_rowkey_col_cnt_ = merge_schema.get_rowkey_column_num(); - schema_version_ = merge_schema.get_schema_version(); - snapshot_version_ = snapshot_version; - sstable_index_builder_ = nullptr; - + const bool is_major = (storage::is_major_merge_type(merge_type) || storage::is_meta_major_merge(merge_type)); if (OB_FAIL(end_scn_.convert_for_tx(snapshot_version))) { // will update in ObPartitionMerger::open_macro_writer STORAGE_LOG(WARN, "fail to convert scn", K(ret), K(snapshot_version)); - } else if (OB_FAIL(merge_schema.get_store_column_count(row_column_count_, true))) { + } else if (OB_FAIL(cal_row_store_type(merge_schema, merge_type))) { + STORAGE_LOG(WARN, "Failed to make the row store type", K(ret)); + } else if (OB_FAIL(merge_schema.get_encryption_id(encrypt_id_))) { + STORAGE_LOG(WARN, "fail to get encrypt id from table schema", K(ret)); + } else if (OB_FAIL(merge_schema.get_store_column_count(full_stored_col_cnt_, true))) { STORAGE_LOG(WARN, "failed to get store column count", K(ret), K_(tablet_id)); } else { rowkey_column_count_ = merge_schema.get_rowkey_column_num() + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); - row_column_count_ += ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); - } - if (OB_SUCC(ret)) { - if (OB_FAIL(merge_schema.get_encryption_id(encrypt_id_))) { - STORAGE_LOG(WARN, "fail to get encrypt id from table schema", K(ret)); - } else if (merge_schema.need_encrypt() && merge_schema.get_encrypt_key_len() > 0) { + full_stored_col_cnt_ += ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + const int64_t pct_free = merge_schema.get_pctfree(); + + macro_block_size_ = OB_SERVER_BLOCK_MGR.get_macro_block_size(); + if (pct_free >= 0 && pct_free <= 50) { + macro_store_size_ = macro_block_size_ * (100 - pct_free) / 100; + } else { + macro_store_size_ = macro_block_size_ * DEFAULT_RESERVE_PERCENT / 100; + } + schema_rowkey_col_cnt_ = merge_schema.get_rowkey_column_num(); + schema_version_ = merge_schema.get_schema_version(); + snapshot_version_ = snapshot_version; + sstable_index_builder_ = nullptr; + micro_block_size_limit_ = macro_block_size_ + - ObMacroBlockCommonHeader::get_serialize_size() + - ObSSTableMacroBlockHeader::get_fixed_header_size() + - MIN_RESERVED_SIZE; + progressive_merge_round_ = merge_schema.get_progressive_merge_round(); + need_prebuild_bloomfilter_ = is_major ? false : merge_schema.is_use_bloomfilter(); + bloomfilter_rowkey_prefix_ = 0; + + if (is_major) { + uint64_t compat_version = 0; + int tmp_ret = OB_SUCCESS; + if (cluster_version > 0) { + major_working_cluster_version_ = cluster_version; + } else if (OB_TMP_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), compat_version))) { + STORAGE_LOG(WARN, "fail to get data version", K(tmp_ret)); + } else { + major_working_cluster_version_ = compat_version; + } + STORAGE_LOG(INFO, "success to set major working cluster version", K(tmp_ret), K(merge_type), K(cluster_version), K(major_working_cluster_version_)); + } + + compressor_type_ = merge_schema.get_compressor_type(); + if (!is_major && compressor_type_ != ObCompressorType::NONE_COMPRESSOR) { + compressor_type_ = DEFAULT_MINOR_COMPRESSOR_TYPE; + } + + if (merge_schema.need_encrypt() && merge_schema.get_encrypt_key_len() > 0) { master_key_id_ = merge_schema.get_master_key_id(); MEMCPY(encrypt_key_, merge_schema.get_encrypt_key().ptr(), merge_schema.get_encrypt_key().length()); } - } - if (OB_SUCC(ret)) { - compressor_type_ = merge_schema.get_compressor_type(); - if (OB_UNLIKELY(compressor_type_ == ObCompressorType::INVALID_COMPRESSOR)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "Unexpected compressor type", K(ret), K(merge_schema)); - } else if (!is_major && compressor_type_ != ObCompressorType::NONE_COMPRESSOR) { - compressor_type_ = DEFAULT_MINOR_COMPRESSOR_TYPE; - } - } - if (OB_SUCC(ret)) { - const ObMacroBlockCommonHeader common_header; - micro_block_size_limit_ = macro_block_size_ - - common_header.get_serialize_size() - - ObSSTableMacroBlockHeader::get_fixed_header_size() - - MIN_RESERVED_SIZE; - progressive_merge_round_ = merge_schema.get_progressive_merge_round(); - need_prebuild_bloomfilter_ = is_major_merge() ? false : merge_schema.is_use_bloomfilter(); - bloomfilter_rowkey_prefix_ = 0; - } - - // calc row_store_type and encoder opt - if (OB_FAIL(ret)) { - } else if (OB_FAIL(cal_row_store_type(merge_schema, merge_type))) { - STORAGE_LOG(WARN, "Failed to make the row store type", K(ret)); - } else if (encoding_enabled()) { - encoder_opt_.set_store_type(row_store_type_); - } - - if (OB_SUCC(ret) && is_major) { - uint64_t compat_version = 0; - int tmp_ret = OB_SUCCESS; - if (cluster_version > 0) { - major_working_cluster_version_ = cluster_version; - } else if (OB_TMP_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), compat_version))) { - STORAGE_LOG(WARN, "fail to get data version", K(tmp_ret)); + if (is_major && major_working_cluster_version_ <= DATA_VERSION_4_0_0_0) { + micro_block_size_ = merge_schema.get_block_size(); } else { - major_working_cluster_version_ = compat_version; - } - STORAGE_LOG(INFO, "success to set major working cluster version", K(tmp_ret), K(merge_type), K(cluster_version), K(major_working_cluster_version_)); - } - - if (OB_SUCC(ret)) { - bool need_build_hash_index = merge_schema.get_table_type() == USER_TABLE - && !is_major_merge(); - if (need_build_hash_index - && OB_FAIL(ObMicroBlockHashIndexBuilder::need_build_hash_index(merge_schema, need_build_hash_index))) { - STORAGE_LOG(WARN, "Failed to judge whether to build hash index", K(ret)); - need_build_hash_index_for_micro_block_ = false; - ret = OB_SUCCESS; - } else { - need_build_hash_index_for_micro_block_ = need_build_hash_index; + micro_block_size_ = MAX(merge_schema.get_block_size(), MIN_MICRO_BLOCK_SIZE); } } + } + return ret; +} - if (OB_FAIL(ret)) { - } else if (OB_FAIL(col_desc_array_.init(row_column_count_))) { - STORAGE_LOG(WARN, "Failed to reserve column desc array", K(ret)); - } else if (OB_FAIL(merge_schema.get_multi_version_column_descs(col_desc_array_))) { - STORAGE_LOG(WARN, "Failed to generate multi version column ids", K(ret)); - } else if (FALSE_IT(fresh_col_meta())) { - } else if (OB_FAIL(datum_utils_.init(col_desc_array_, schema_rowkey_col_cnt_, lib::is_oracle_mode(), allocator_))) { - STORAGE_LOG(WARN, "Failed to init datum utils", K(ret)); - } else if (is_major && major_working_cluster_version_ <= DATA_VERSION_4_0_0_0) { - micro_block_size_ = merge_schema.get_block_size(); +//fill default column checksum +int ObDataStoreDesc::init_col_default_checksum_array( + const share::schema::ObMergeSchema &merge_schema, + const bool init_by_schema) +{ + int ret = OB_SUCCESS; + if (init_by_schema) { + default_col_checksum_array_valid_ = true; + common::ObArray meta_array; + if (OB_FAIL(merge_schema.init_column_meta_array(meta_array))) { + STORAGE_LOG(WARN, "fail to init column meta array", K(ret)); + } else if (OB_FAIL(col_default_checksum_array_.init(meta_array.count()))) { + STORAGE_LOG(WARN, "fail to init column default checksum array", K(ret)); } else { - micro_block_size_ = MAX(merge_schema.get_block_size(), MIN_MICRO_BLOCK_SIZE); + for (int64_t i = 0; OB_SUCC(ret) && i < meta_array.count(); ++i) { + if (OB_FAIL(col_default_checksum_array_.push_back( + meta_array.at(i).column_default_checksum_))) { + STORAGE_LOG(WARN, "fail to push default checksum into array", K(ret), + K(i), K(meta_array)); + } + } + } + } else { + // for mini & minor, just push default_col_checksum=0 + default_col_checksum_array_valid_ = false; + const int64_t mv_full_col_count = merge_schema.get_column_count() + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + if (OB_FAIL(col_default_checksum_array_.init(mv_full_col_count))) { + STORAGE_LOG(WARN, "fail to init column default checksum array", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < mv_full_col_count; ++i) { + if (OB_FAIL(col_default_checksum_array_.push_back(0))) { + STORAGE_LOG(WARN, "fail to push default checksum into array", K(ret), + K(i), K(mv_full_col_count)); + } + } + } + + // init hash index + if (OB_SUCC(ret)) { + bool need_build_hash_index = merge_schema.get_table_type() == USER_TABLE && !is_major_merge(); + if (need_build_hash_index + && OB_FAIL(ObMicroBlockHashIndexBuilder::need_build_hash_index(merge_schema, need_build_hash_index))) { + STORAGE_LOG(WARN, "Failed to judge whether to build hash index", K(ret)); + need_build_hash_index_for_micro_block_ = false; + ret = OB_SUCCESS; + } else { + need_build_hash_index_for_micro_block_ = need_build_hash_index; } } return ret; @@ -312,6 +423,7 @@ void ObDataStoreDesc::reset() row_column_count_ = 0; rowkey_column_count_ = 0; schema_rowkey_col_cnt_ = 0; + full_stored_col_cnt_ = 0; row_store_type_ = ENCODING_ROW_STORE; need_build_hash_index_for_micro_block_ = false; encoder_opt_.reset(); @@ -332,7 +444,9 @@ void ObDataStoreDesc::reset() is_ddl_ = false; need_pre_warm_ = false; is_force_flat_store_type_ = false; + default_col_checksum_array_valid_ = false; col_desc_array_.reset(); + col_default_checksum_array_.reset(); datum_utils_.reset(); allocator_.reset(); } @@ -352,6 +466,7 @@ int ObDataStoreDesc::assign(const ObDataStoreDesc &desc) need_build_hash_index_for_micro_block_ = desc.need_build_hash_index_for_micro_block_; schema_version_ = desc.schema_version_; schema_rowkey_col_cnt_ = desc.schema_rowkey_col_cnt_; + full_stored_col_cnt_ = desc.full_stored_col_cnt_; encoder_opt_ = desc.encoder_opt_; merge_info_ = desc.merge_info_; merge_type_ = desc.merge_type_; @@ -368,12 +483,13 @@ int ObDataStoreDesc::assign(const ObDataStoreDesc &desc) need_pre_warm_ = desc.need_pre_warm_; is_force_flat_store_type_ = desc.is_force_flat_store_type_; col_desc_array_.reset(); + col_default_checksum_array_.reset(); datum_utils_.reset(); sstable_index_builder_ = desc.sstable_index_builder_; - if (OB_FAIL(col_desc_array_.init(row_column_count_))) { - STORAGE_LOG(WARN, "Failed to reserve column desc array", K(ret)); - } else if (OB_FAIL(col_desc_array_.assign(desc.col_desc_array_))) { + if (OB_FAIL(col_desc_array_.assign(desc.col_desc_array_))) { STORAGE_LOG(WARN, "Failed to assign column desc array", K(ret)); + } else if (OB_FAIL(col_default_checksum_array_.assign(desc.col_default_checksum_array_))) { + STORAGE_LOG(WARN, "Failed to assign col default checksum array, ", K(ret)); } else if (OB_FAIL(datum_utils_.init(col_desc_array_, schema_rowkey_col_cnt_, lib::is_oracle_mode(), allocator_))) { STORAGE_LOG(WARN, "Failed to init datum utils", K(ret)); } @@ -449,6 +565,9 @@ int ObMicroBlockCompressor::compress(const char *in, const int64_t in_size, cons if (is_none_) { out = in; out_size = in_size; + } else if (OB_ISNULL(compressor_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "compressor is unexpected null", K(ret), K_(compressor)); } else if (OB_FAIL(compressor_->get_max_overflow_size(in_size, max_overflow_size))) { STORAGE_LOG(WARN, "fail to get max_overflow_size, ", K(ret), K(in_size)); } else { @@ -531,7 +650,8 @@ int ObMacroBlock::init(ObDataStoreDesc &spec, const int64_t &cur_macro_seq) reuse(); spec_ = &spec; cur_macro_seq_ = cur_macro_seq; - data_base_offset_ = calc_basic_micro_block_data_offset(spec.row_column_count_); + data_base_offset_ = calc_basic_micro_block_data_offset( + spec.row_column_count_, spec.rowkey_column_count_, spec.get_fixed_header_version()); is_inited_ = true; return ret; } @@ -576,13 +696,14 @@ int64_t ObMacroBlock::get_remain_size() const { return remain_size; } -int64_t ObMacroBlock::calc_basic_micro_block_data_offset(const uint64_t column_cnt) +int64_t ObMacroBlock::calc_basic_micro_block_data_offset( + const int64_t column_cnt, + const int64_t rowkey_col_cnt, + const uint16_t fixed_header_version) { return sizeof(ObMacroBlockCommonHeader) + ObSSTableMacroBlockHeader::get_fixed_header_size() - + column_cnt * sizeof(ObObjMeta) /* ObObjMeta */ - + column_cnt * sizeof(ObOrderType) /* column orders */ - + column_cnt * sizeof(int64_t) /* column checksum */; + + ObSSTableMacroBlockHeader::get_variable_size_in_header(column_cnt, rowkey_col_cnt, fixed_header_version); } int ObMacroBlock::check_micro_block(const ObMicroBlockDesc µ_block_desc) const @@ -787,10 +908,10 @@ int ObMacroBlock::reserve_header(const ObDataStoreDesc &spec, const int64_t &cur if (OB_FAIL(data_.advance(common_header_size))) { STORAGE_LOG(WARN, "data buffer is not enough for common header.", K(ret), K(common_header_size)); } else { - const int64_t column_count = spec.row_column_count_; char *col_types_buf = data_.current() + macro_header_.get_fixed_header_size(); - char *col_orders_buf = col_types_buf + sizeof(ObObjMeta) * column_count; - char *col_checksum_buf = col_orders_buf + sizeof(ObOrderType) * column_count; + const int64_t col_type_array_cnt = spec.get_fixed_header_col_type_cnt(); + char *col_orders_buf = col_types_buf + sizeof(ObObjMeta) * col_type_array_cnt; + char *col_checksum_buf = col_orders_buf + sizeof(ObOrderType) * col_type_array_cnt; if (OB_FAIL(macro_header_.init(spec, reinterpret_cast(col_types_buf), reinterpret_cast(col_orders_buf), @@ -803,7 +924,8 @@ int ObMacroBlock::reserve_header(const ObDataStoreDesc &spec, const int64_t &cur if (OB_UNLIKELY(data_base_offset_ != expect_base_offset)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "expect equal", K(ret), K_(data_base_offset), K(expect_base_offset), - K_(macro_header), K(common_header_size), K(spec.row_column_count_)); + K_(macro_header), K(common_header_size), K(spec.row_column_count_), K(spec.rowkey_column_count_), + K(spec.get_fixed_header_version())); } else if (OB_FAIL(data_.advance(macro_header_.get_serialize_size()))) { STORAGE_LOG(WARN, "macro_block_header_size out of data buffer.", K(ret)); } diff --git a/src/storage/blocksstable/ob_macro_block.h b/src/storage/blocksstable/ob_macro_block.h index 6859db442..4c87101ea 100644 --- a/src/storage/blocksstable/ob_macro_block.h +++ b/src/storage/blocksstable/ob_macro_block.h @@ -54,11 +54,12 @@ struct ObDataStoreDesc int64_t micro_block_size_; int64_t micro_block_size_limit_; int64_t row_column_count_; - int64_t rowkey_column_count_; + int64_t rowkey_column_count_; // mv rowkey cnt ObRowStoreType row_store_type_; bool need_build_hash_index_for_micro_block_; int64_t schema_version_; int64_t schema_rowkey_col_cnt_; + int64_t full_stored_col_cnt_; // table stored column count including hidden columns ObMicroBlockEncoderOpt encoder_opt_; ObSSTableMergeInfo *merge_info_; storage::ObMergeType merge_type_; @@ -80,18 +81,27 @@ struct ObDataStoreDesc bool is_ddl_; bool need_pre_warm_; bool is_force_flat_store_type_; + bool default_col_checksum_array_valid_; common::ObArenaAllocator allocator_; - common::ObFixedArray col_desc_array_; + common::ObFixedArray col_default_checksum_array_; blocksstable::ObStorageDatumUtils datum_utils_; ObDataStoreDesc(); ~ObDataStoreDesc(); //ATTENSION!!! Only decreasing count of parameters is acceptable - int init(const share::schema::ObMergeSchema &schema, - const share::ObLSID &ls_id, - const common::ObTabletID tablet_id, - const storage::ObMergeType merge_type, - const int64_t snapshot_version = MIN_SSTABLE_SNAPSHOT_VERSION, - const int64_t cluster_version = 0); + int init( + const share::schema::ObMergeSchema &schema, + const share::ObLSID &ls_id, + const common::ObTabletID tablet_id, + const storage::ObMergeType merge_type, + const int64_t snapshot_version = MIN_SSTABLE_SNAPSHOT_VERSION, + const int64_t cluster_version = 0); + int init_as_index( + const share::schema::ObMergeSchema &schema, + const share::ObLSID &ls_id, + const common::ObTabletID tablet_id, + const storage::ObMergeType merge_type, + const int64_t snapshot_version = MIN_SSTABLE_SNAPSHOT_VERSION, + const int64_t cluster_version = 0); bool is_valid() const; void reset(); int assign(const ObDataStoreDesc &desc); @@ -109,13 +119,36 @@ struct ObDataStoreDesc { return (is_major_merge() || is_meta_major_merge()) ? snapshot_version_ : end_scn_.get_val_for_tx(); } + const common::ObIArray &get_rowkey_col_descs() const + { + return col_desc_array_; + } + const common::ObIArray &get_full_stored_col_descs() const + { + OB_ASSERT_MSG(is_major_merge(), "ObDataStoreDesc dose not promise a full stored col descs"); + return col_desc_array_; + } + bool use_old_version_macro_header() const + { + return is_major_merge() && major_working_cluster_version_ < DATA_VERSION_4_2_0_0; + } + int64_t get_fixed_header_version() const + { + return use_old_version_macro_header() ? ObSSTableMacroBlockHeader::SSTABLE_MACRO_BLOCK_HEADER_VERSION_V1 : ObSSTableMacroBlockHeader::SSTABLE_MACRO_BLOCK_HEADER_VERSION_V2; + } + int64_t get_fixed_header_col_type_cnt() const + { + return use_old_version_macro_header() ? row_column_count_ : rowkey_column_count_; + } TO_STRING_KV( K_(ls_id), K_(tablet_id), K_(micro_block_size), + K_(micro_block_size_limit), K_(row_column_count), K_(rowkey_column_count), K_(schema_rowkey_col_cnt), + K_(full_stored_col_cnt), K_(row_store_type), K_(encoder_opt), K_(compressor_type), @@ -132,15 +165,27 @@ struct ObDataStoreDesc K_(major_working_cluster_version), KP_(sstable_index_builder), K_(is_ddl), - K_(col_desc_array)); + K_(col_desc_array), + K_(col_default_checksum_array)); private: + int inner_init( + const share::schema::ObMergeSchema &schema, + const share::ObLSID &ls_id, + const common::ObTabletID tablet_id, + const storage::ObMergeType merge_type, + const int64_t snapshot_version, + const int64_t cluster_version); int cal_row_store_type( const share::schema::ObMergeSchema &schema, const storage::ObMergeType merge_type); int get_emergency_row_store_type(); void fresh_col_meta(); + int init_col_default_checksum_array( + const share::schema::ObMergeSchema &merge_schema, + const bool init_by_schema); private: + common::ObFixedArray col_desc_array_; DISALLOW_COPY_AND_ASSIGN(ObDataStoreDesc); }; @@ -198,7 +243,10 @@ public: { contain_uncommitted_row_ = true; } - static int64_t calc_basic_micro_block_data_offset(const uint64_t column_cnt); + static int64_t calc_basic_micro_block_data_offset( + const int64_t column_cnt, + const int64_t rowkey_col_cnt, + const uint16_t fixed_header_version); private: int inner_init(); int reserve_header(const ObDataStoreDesc &spec, const int64_t &cur_macro_seq); diff --git a/src/storage/blocksstable/ob_macro_block_bare_iterator.cpp b/src/storage/blocksstable/ob_macro_block_bare_iterator.cpp index 6b2d14c35..fb0ae1c99 100644 --- a/src/storage/blocksstable/ob_macro_block_bare_iterator.cpp +++ b/src/storage/blocksstable/ob_macro_block_bare_iterator.cpp @@ -108,7 +108,7 @@ int ObMicroBlockBareIterator::open( const char *macro_block_buf, const int64_t macro_block_buf_size, const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, const bool is_left_border, const bool is_right_border) { @@ -117,9 +117,9 @@ int ObMicroBlockBareIterator::open( ret = OB_INIT_TWICE; LOG_WARN("already inited", K(ret)); } else if (OB_ISNULL(macro_block_buf) - || OB_UNLIKELY(macro_block_buf_size <= 0 || !range.is_valid() || !index_read_info.is_valid())) { + || OB_UNLIKELY(macro_block_buf_size <= 0 || !range.is_valid() || !rowkey_read_info.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid macro block buf", KP(macro_block_buf), K(macro_block_buf_size), K(range), K(index_read_info)); + LOG_WARN("Invalid macro block buf", KP(macro_block_buf), K(macro_block_buf_size), K(range), K(rowkey_read_info)); } else if (OB_FAIL(common_header_.deserialize(macro_block_buf, macro_block_buf_size, read_pos_))) { LOG_WARN("Failed to deserialize macro header", K(ret), KP(macro_block_buf), K(macro_block_buf_size)); } else if (OB_FAIL(common_header_.check_integrity())) { @@ -144,8 +144,8 @@ int ObMicroBlockBareIterator::open( end_idx_ = macro_block_header_.fixed_header_.micro_block_count_ - 1; iter_idx_ = begin_idx_; is_inited_ = true; - } else if (OB_FAIL(locate_range(range, index_read_info, is_left_border, is_right_border))) { - LOG_WARN("fail to locate range for micro block", K(ret), K(range), K(index_read_info)); + } else if (OB_FAIL(locate_range(range, rowkey_read_info, is_left_border, is_right_border))) { + LOG_WARN("fail to locate range for micro block", K(ret), K(range), K(rowkey_read_info)); } else { is_inited_ = true; } @@ -270,7 +270,7 @@ int ObMicroBlockBareIterator::check_macro_block_data_integrity( int ObMicroBlockBareIterator::locate_range( const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, const bool is_left_border, const bool is_right_border) { @@ -284,8 +284,8 @@ int ObMicroBlockBareIterator::locate_range( } else if (OB_ISNULL(reader_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected null micro reader", K(ret)); - } else if (OB_FAIL(reader_->init(index_block, index_read_info))) { - LOG_WARN("Fail to init reader for index block", K(ret), K(index_block), K(index_read_info)); + } else if (OB_FAIL(reader_->init(index_block, &(rowkey_read_info.get_datum_utils())))) { + LOG_WARN("Fail to init reader for index block", K(ret), K(index_block), K(rowkey_read_info)); } else if (OB_FAIL(reader_->locate_range( range, is_left_border, is_right_border, begin_idx_, end_idx_, true))) { if (OB_UNLIKELY(OB_BEYOND_THE_RANGE != ret)) { @@ -380,6 +380,8 @@ int ObMacroBlockRowBareIterator::open( LOG_WARN("invalid macro header", K(ret), K(macro_header)); } else { const int64_t column_cnt = macro_header.fixed_header_.column_count_; + const int64_t schema_rowkey_cnt = macro_header.fixed_header_.rowkey_column_count_ + - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); column_types_ = macro_header.column_types_; column_checksums_ = macro_header.column_checksum_; if (OB_FAIL(row_.init(*allocator_, column_cnt))) { @@ -388,7 +390,8 @@ int ObMacroBlockRowBareIterator::open( ObSEArray columns; share::schema::ObColDesc col_desc; - for (int64_t i = 0; OB_SUCC(ret) && i < column_cnt; ++i) { + for (int64_t i = 0; OB_SUCC(ret) && i < macro_header.fixed_header_.get_col_type_array_cnt(); ++i) { + col_desc.col_id_ = common::OB_APP_MIN_COLUMN_ID + i; col_desc.col_type_ = column_types_[i]; if (OB_FAIL(columns.push_back(col_desc))) { LOG_WARN("Fail to push col desc to columns", K(ret)); @@ -397,13 +400,10 @@ int ObMacroBlockRowBareIterator::open( if (OB_FAIL(ret)) { } else if (OB_FAIL(col_read_info_.init(*allocator_, - macro_header.fixed_header_.column_count_ - - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(), - macro_header.fixed_header_.rowkey_column_count_ - - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(), + macro_header.fixed_header_.column_count_ - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(), + schema_rowkey_cnt, lib::is_oracle_mode(), - columns, - true))) { + columns))) { LOG_WARN("Fail to init column read info", K(ret), K(macro_header)); } else if (OB_FAIL(init_micro_reader(static_cast( macro_header.fixed_header_.row_store_type_)))) { @@ -460,9 +460,8 @@ int ObMacroBlockRowBareIterator::open_leaf_index_micro_block(const bool is_macro } else if (OB_UNLIKELY(!curr_micro_block_data_.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Read an invalid micro block data", K(ret)); - } else if (OB_FAIL(micro_reader_->init( - curr_micro_block_data_, *col_read_info_.get_index_read_info()))) { - LOG_WARN("Fail to init micro block reader", K(ret), K_(curr_micro_block_data), K_(col_read_info)); + } else if (OB_FAIL(micro_reader_->init(curr_micro_block_data_, nullptr))) { + LOG_WARN("Fail to init micro block reader", K(ret), K_(curr_micro_block_data)); } else if (OB_FAIL(micro_reader_->get_row_count(curr_block_row_cnt_))) { LOG_WARN("Fail to get micro block row count", K(ret)); } else { @@ -484,8 +483,8 @@ int ObMacroBlockRowBareIterator::open_next_micro_block() } else if (OB_UNLIKELY(!curr_micro_block_data_.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Read an invalid micro block data", K(ret)); - } else if (OB_FAIL(micro_reader_->init(curr_micro_block_data_, col_read_info_))) { - LOG_WARN("Fail to init micro block reader", K(ret), K_(curr_micro_block_data), K_(col_read_info)); + } else if (OB_FAIL(micro_reader_->init(curr_micro_block_data_, nullptr))) { + LOG_WARN("Fail to init micro block reader", K(ret), K_(curr_micro_block_data)); } else if (OB_FAIL(micro_reader_->get_row_count(curr_block_row_cnt_))) { LOG_WARN("Fail to get micro block row count", K(ret)); } else { diff --git a/src/storage/blocksstable/ob_macro_block_bare_iterator.h b/src/storage/blocksstable/ob_macro_block_bare_iterator.h index a819decea..fc45618c0 100644 --- a/src/storage/blocksstable/ob_macro_block_bare_iterator.h +++ b/src/storage/blocksstable/ob_macro_block_bare_iterator.h @@ -42,7 +42,7 @@ public: const char *macro_block_buf, const int64_t macro_block_buf_size, const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, const bool is_left_border, const bool is_right_border); int get_next_micro_block_data(ObMicroBlockData µ_block); @@ -59,7 +59,7 @@ private: int check_macro_block_data_integrity(const char *payload_buf, const int64_t payload_size); int locate_range( const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, const bool is_left_border, const bool is_right_border); int set_reader(const ObRowStoreType store_type); @@ -102,7 +102,7 @@ public: int get_macro_block_header(ObSSTableMacroBlockHeader ¯o_header); int get_curr_micro_block_data(const ObMicroBlockData *&block_data); int get_curr_micro_block_row_cnt(int64_t &row_count); - OB_INLINE const common::ObIArray &get_column_descs() const + OB_INLINE const common::ObIArray &get_rowkey_column_descs() const { return col_read_info_.get_columns_desc(); } int get_column_checksums(const int64_t *&column_checksums); private: @@ -112,7 +112,7 @@ private: ObMicroBlockBareIterator micro_iter_; const ObObjMeta *column_types_; const int64_t *column_checksums_; - ObTableReadInfo col_read_info_; + ObRowkeyReadInfo col_read_info_; common::ObIAllocator *allocator_; ObIMicroBlockReader *micro_reader_; ObMicroBlockData curr_micro_block_data_; diff --git a/src/storage/blocksstable/ob_macro_block_checker.cpp b/src/storage/blocksstable/ob_macro_block_checker.cpp index 4f2065a2f..90556d8d4 100644 --- a/src/storage/blocksstable/ob_macro_block_checker.cpp +++ b/src/storage/blocksstable/ob_macro_block_checker.cpp @@ -71,8 +71,6 @@ int ObSSTableMacroBlockChecker::check_logical_checksum( int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::OB_MACRO_BLOCK_CHECKER); ObSSTableMacroBlockHeader sstable_header; - ObSEArray columns; - ObTableReadInfo col_read_info; ObMicroBlockBareIterator micro_iter; const int64_t *column_checksum_in_header = nullptr; int64_t *column_checksum = nullptr; @@ -81,19 +79,12 @@ int ObSSTableMacroBlockChecker::check_logical_checksum( ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid argument", K(ret), KP(buf), K(buf_size), K(common_header)); } else if (OB_FAIL(get_sstable_header_and_column_checksum(buf, buf_size, sstable_header, - columns, column_checksum_in_header))) { + column_checksum_in_header))) { STORAGE_LOG(WARN, "fail to get sstable header and column checksum", K(ret), KP(buf), K(buf_size), K(common_header)); } else if (OB_ISNULL(column_checksum_in_header)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "column checksum in header should not be NULL", K(ret), KP(column_checksum_in_header)); - } else if (OB_FAIL(col_read_info.init(allocator, - sstable_header.fixed_header_.column_count_ - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(), - sstable_header.fixed_header_.rowkey_column_count_, - lib::is_oracle_mode(), - columns, - true))) { - STORAGE_LOG(WARN, "fail to init column read info", K(ret), K(sstable_header), K(columns)); } else if (OB_FAIL(micro_iter.open(buf, buf_size))) { STORAGE_LOG(WARN, "fail to init micro block iterator", K(ret)); } else if (OB_FAIL(datum_row.init(allocator, sstable_header.fixed_header_.column_count_))) { @@ -129,12 +120,10 @@ int ObSSTableMacroBlockChecker::check_logical_checksum( } else if (OB_FAIL(micro_reader_helper.get_reader(micro_data.get_store_type(), micro_reader))) { STORAGE_LOG(WARN, "fail to get micro reader by store type", K(ret), K(micro_data.get_store_type())); - } else if (OB_FAIL(micro_reader->init(micro_data, col_read_info))) { + } else if (OB_FAIL(micro_reader->init(micro_data, nullptr))) { STORAGE_LOG(WARN, "fail to init micro reader", K(ret)); - } else if (OB_FAIL(calc_micro_column_checksum(column_cnt, columns, *micro_reader, datum_row, - column_checksum))) { - STORAGE_LOG(WARN, "fail to accumulate micro column checksum", K(ret), K(column_cnt), - K(columns)); + } else if (OB_FAIL(calc_micro_column_checksum(*micro_reader, datum_row, column_checksum))) { + STORAGE_LOG(WARN, "fail to accumulate micro column checksum", K(ret), K(datum_row)); } } if (OB_ITER_END != ret) { @@ -154,30 +143,21 @@ int ObSSTableMacroBlockChecker::check_logical_checksum( } int ObSSTableMacroBlockChecker::calc_micro_column_checksum( - const int64_t column_cnt, - const common::ObIArray &out_cols, ObIMicroBlockReader &reader, ObDatumRow &datum_row, int64_t *column_checksum) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(column_cnt <= 0) || OB_ISNULL(column_checksum)) { + if (OB_ISNULL(column_checksum)) { ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid arguments", K(ret), KP(column_checksum), K(column_cnt)); + STORAGE_LOG(WARN, "invalid arguments", K(ret), KP(column_checksum)); } else { - ObStoreRow row; for (int64_t iter = 0; OB_SUCC(ret) && iter != reader.row_count(); ++iter) { if (OB_FAIL(reader.get_row(iter, datum_row))) { STORAGE_LOG(WARN, "fail to get row", K(ret), K(iter)); - } else if (OB_FAIL(datum_row.to_store_row(out_cols, row))) { - STORAGE_LOG(WARN, "fail to transfer datum row to store row", K(ret), K(datum_row)); - } else if (row.row_val_.count_ != column_cnt) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "error unexpected, row column count is invalid", K(ret), - K(row.row_val_.count_), K(column_cnt)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < column_cnt; ++i) { - column_checksum[i] += row.row_val_.cells_[i].checksum_v2(0); + for (int64_t i = 0; OB_SUCC(ret) && i < datum_row.count_; ++i) { + column_checksum[i] += datum_row.storage_datums_[i].checksum(0); } } } @@ -189,7 +169,6 @@ int ObSSTableMacroBlockChecker::get_sstable_header_and_column_checksum( const char *macro_block_buf, const int64_t macro_block_buf_size, ObSSTableMacroBlockHeader &header, - common::ObIArray &columns, const int64_t *&column_checksum) { int ret = OB_SUCCESS; @@ -201,19 +180,7 @@ int ObSSTableMacroBlockChecker::get_sstable_header_and_column_checksum( STORAGE_LOG(WARN, "fail to deserialize macro block header", K(ret), KP(macro_block_buf), K(macro_block_buf_size), K(pos)); } else { - const int64_t column_cnt = header.fixed_header_.column_count_; - const ObObjMeta *column_types = header.column_types_; - const common::ObOrderType *col_orders = header.column_orders_; column_checksum = header.column_checksum_; - share::schema::ObColDesc col_desc; - for (int64_t i = 0; OB_SUCC(ret) && i < column_cnt; ++i) { - col_desc.col_id_ = 0; - col_desc.col_type_ = column_types[i]; - col_desc.col_order_ = col_orders[i]; - if (OB_FAIL(columns.push_back(col_desc))) { - STORAGE_LOG(WARN, "fail to push col desc to columns", K(ret)); - } - } } return ret; } diff --git a/src/storage/blocksstable/ob_macro_block_checker.h b/src/storage/blocksstable/ob_macro_block_checker.h index cf82766c6..ed99bf853 100644 --- a/src/storage/blocksstable/ob_macro_block_checker.h +++ b/src/storage/blocksstable/ob_macro_block_checker.h @@ -48,8 +48,6 @@ private: const char *macro_block_buf, const int64_t macro_block_buf_size); static int calc_micro_column_checksum( - const int64_t column_cnt, - const common::ObIArray &out_cols, ObIMicroBlockReader &reader, ObDatumRow &datum_row, int64_t *column_checksum); @@ -61,7 +59,6 @@ private: const char *macro_block_buf, const int64_t macro_block_buf_size, ObSSTableMacroBlockHeader &header, - common::ObIArray &columns, const int64_t *&column_checksum); private: DISALLOW_COPY_AND_ASSIGN(ObSSTableMacroBlockChecker); diff --git a/src/storage/blocksstable/ob_macro_block_common_header.h b/src/storage/blocksstable/ob_macro_block_common_header.h index 2b8e39871..35a0fb857 100644 --- a/src/storage/blocksstable/ob_macro_block_common_header.h +++ b/src/storage/blocksstable/ob_macro_block_common_header.h @@ -42,6 +42,7 @@ public: SSTableIndex = 6, SSTableMacroMeta = 7, SharedSSTableData = 8, + SharedMetaData = 9, MaxMacroType, }; static_assert( @@ -67,7 +68,10 @@ public: bool is_bloom_filter_data_block() const { return MacroBlockType::BloomFilterData == attr_; } bool is_sstable_index_block() const { return MacroBlockType::SSTableIndex == attr_; } bool is_sstable_macro_meta_block() const { return MacroBlockType::SSTableMacroMeta == attr_; } - bool is_shared_macro_block() const { return MacroBlockType::SharedSSTableData == attr_; } + bool is_shared_macro_block() const + { + return MacroBlockType::SharedSSTableData == attr_ || MacroBlockType::SharedMetaData == attr_; + } int32_t get_header_size() const { return header_size_; } int32_t get_version() const { return version_; } int32_t get_magic() const { return magic_; } diff --git a/src/storage/blocksstable/ob_macro_block_reader.cpp b/src/storage/blocksstable/ob_macro_block_reader.cpp index 30c2f651b..4ee3ad21d 100644 --- a/src/storage/blocksstable/ob_macro_block_reader.cpp +++ b/src/storage/blocksstable/ob_macro_block_reader.cpp @@ -367,7 +367,7 @@ ObSSTableDataBlockReader::ObSSTableDataBlockReader() : data_(NULL), size_(0), common_header_(), macro_header_(), linked_header_(), bloomfilter_header_(NULL), column_types_(NULL), column_orders_(NULL), column_checksum_(NULL), macro_reader_(), allocator_(ObModIds::OB_CS_SSTABLE_READER), - hex_print_buf_(nullptr), is_trans_sstable_(false), is_inited_(false) + hex_print_buf_(nullptr), is_trans_sstable_(false), is_inited_(false), column_type_array_cnt_(0) { } @@ -405,6 +405,7 @@ int ObSSTableDataBlockReader::init(const char *data, const int64_t size, const b column_types_ = macro_header_.column_types_; column_orders_ = macro_header_.column_orders_; column_checksum_ = macro_header_.column_checksum_; + column_type_array_cnt_ = macro_header_.fixed_header_.get_col_type_array_cnt(); } break; } @@ -473,7 +474,7 @@ int ObSSTableDataBlockReader::dump(const uint64_t tablet_id, const int64_t scn) switch (common_header_.get_type()) { case ObMacroBlockCommonHeader::SSTableData: ObSSTablePrinter::print_macro_block_header(¯o_header_); - if (OB_FAIL(dump_column_info(macro_header_.fixed_header_.column_count_))) { + if (OB_FAIL(dump_column_info(macro_header_.fixed_header_.column_count_, macro_header_.fixed_header_.get_col_type_array_cnt()))) { LOG_WARN("Failed to dump column info", K(ret), K_(macro_header)); } else if (OB_FAIL(dump_sstable_macro_block(false))) { LOG_WARN("Failed to dump sstable macro block", K(ret)); @@ -490,7 +491,7 @@ int ObSSTableDataBlockReader::dump(const uint64_t tablet_id, const int64_t scn) break; case ObMacroBlockCommonHeader::SSTableIndex: ObSSTablePrinter::print_macro_block_header(¯o_header_); - if (OB_FAIL(dump_column_info(macro_header_.fixed_header_.column_count_))) { + if (OB_FAIL(dump_column_info(macro_header_.fixed_header_.column_count_, macro_header_.fixed_header_.column_count_))) { LOG_WARN("Failed to dump column info", K(ret), K_(macro_header)); } else if (OB_FAIL(dump_sstable_macro_block(true))) { LOG_WARN("Failed to dump sstable macro block", K(ret)); @@ -660,7 +661,7 @@ int ObSSTableDataBlockReader::dump_sstable_micro_data( ObSSTablePrinter::print_store_row_hex(row, column_types_, OB_DEFAULT_MACRO_BLOCK_SIZE, hex_print_buf_); } else { ObSSTablePrinter::print_store_row( - row, column_types_, block_header->rowkey_column_count_, is_index_block, is_trans_sstable_); + row, column_types_, column_type_array_cnt_, is_index_block, is_trans_sstable_); } if (is_index_block) { @@ -751,7 +752,7 @@ int ObSSTableDataBlockReader::dump_bloom_filter_data_block() return ret; } -int ObSSTableDataBlockReader::dump_column_info(const int64_t col_cnt) +int ObSSTableDataBlockReader::dump_column_info(const int64_t col_cnt, const int64_t type_array_col_cnt) { int ret = OB_SUCCESS; if (OB_UNLIKELY(col_cnt < 0) @@ -763,10 +764,15 @@ int ObSSTableDataBlockReader::dump_column_info(const int64_t col_cnt) KP_(column_types), KP_(column_orders), KP_(column_checksum)); } else if (col_cnt > 0) { ObSSTablePrinter::print_cols_info_start("column_index", "column_type", "column_order", "column_checksum", "collation_type"); - for (int64_t i = 0; i < col_cnt; ++i) { + int64_t i = 0; + for (; i < type_array_col_cnt; ++i) { ObSSTablePrinter::print_cols_info_line(i, column_types_[i].get_type(), column_orders_[i], column_checksum_[i], column_types_[i].get_collation_type()); } + for (; i < col_cnt; ++i) { + ObSSTablePrinter::print_cols_info_line(i, ObUnknownType, ASC, + column_checksum_[i], column_types_[i].get_collation_type()); + } ObSSTablePrinter::print_end_line(); } return ret; diff --git a/src/storage/blocksstable/ob_macro_block_reader.h b/src/storage/blocksstable/ob_macro_block_reader.h index 982a8e0a8..3b0219593 100644 --- a/src/storage/blocksstable/ob_macro_block_reader.h +++ b/src/storage/blocksstable/ob_macro_block_reader.h @@ -129,7 +129,7 @@ private: const bool is_index_block, ObMacroBlockRowBareIterator ¯o_bare_iter); int dump_sstable_micro_data(const ObMicroBlockData µ_data, const bool is_index_block); - int dump_column_info(const int64_t col_cnt); + int dump_column_info(const int64_t col_cnt, const int64_t type_array_col_cnt); bool check_need_print(const uint64_t tablet_id, const int64_t scn); private: // raw data @@ -151,6 +151,7 @@ private: char *hex_print_buf_; bool is_trans_sstable_; bool is_inited_; + int64_t column_type_array_cnt_; private: DISALLOW_COPY_AND_ASSIGN(ObSSTableDataBlockReader); }; diff --git a/src/storage/blocksstable/ob_macro_block_writer.cpp b/src/storage/blocksstable/ob_macro_block_writer.cpp old mode 100755 new mode 100644 index c131f17d0..1fd878548 --- a/src/storage/blocksstable/ob_macro_block_writer.cpp +++ b/src/storage/blocksstable/ob_macro_block_writer.cpp @@ -39,7 +39,6 @@ namespace blocksstable ObMicroBlockBufferHelper::ObMicroBlockBufferHelper() :data_store_desc_(nullptr), - read_info_(nullptr), micro_block_merge_verify_level_(0), compressor_(), encryption_(), @@ -50,7 +49,7 @@ ObMicroBlockBufferHelper::ObMicroBlockBufferHelper() int ObMicroBlockBufferHelper::open( ObDataStoreDesc &data_store_desc, - ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, common::ObIAllocator &allocator) { int ret = OB_SUCCESS; @@ -66,7 +65,6 @@ int ObMicroBlockBufferHelper::open( STORAGE_LOG(WARN, "Failed to init reader helper", K(ret)); } else { data_store_desc_ = &data_store_desc; - read_info_ = &read_info; micro_block_merge_verify_level_ = GCONF.micro_block_merge_verify_level; } return ret; @@ -75,7 +73,6 @@ int ObMicroBlockBufferHelper::open( void ObMicroBlockBufferHelper::reset() { data_store_desc_ = nullptr; - read_info_ = nullptr; micro_block_merge_verify_level_ = 0; compressor_.reset(); check_reader_helper_.reset(); @@ -203,9 +200,9 @@ int ObMicroBlockBufferHelper::prepare_micro_block_reader( } else if (OB_ISNULL(micro_reader)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "unexpected null micro reader", K(ret), KP(micro_reader)); - } else if (OB_FAIL(micro_reader->init(block_data, *read_info_))) { + } else if (OB_FAIL(micro_reader->init(block_data, nullptr))) { STORAGE_LOG(WARN, "failed to init micro block reader", - K(ret), K(block_data), KPC(header), KPC_(read_info)); + K(ret), K(block_data), KPC(header)); } return ret; } @@ -217,7 +214,6 @@ void ObMicroBlockBufferHelper::print_micro_block_row(ObIMicroBlockReader *micro_ ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "get_row failed", K(ret), K(micro_reader)); } else { - ObStoreRow store_row; int64_t new_checksum = 0; for (int64_t it = 0; OB_SUCC(ret) && it != micro_reader->row_count(); ++it) { if (OB_FAIL(micro_reader->get_row(it, check_datum_row_))) { @@ -225,11 +221,6 @@ void ObMicroBlockBufferHelper::print_micro_block_row(ObIMicroBlockReader *micro_ } else { new_checksum = ObIMicroBlockWriter::cal_row_checksum(check_datum_row_, new_checksum); FLOG_WARN("error micro block row", K(it), K_(check_datum_row), K(new_checksum)); - if (OB_FAIL(check_datum_row_.to_store_row(data_store_desc_->col_desc_array_, store_row))) { - STORAGE_LOG(WARN, "Failed to transfer datum row to store row", K(ret), K(check_datum_row_)); - } else { - FLOG_WARN("error micro block store_row", K(it), K(store_row)); - } } } } @@ -449,13 +440,7 @@ int ObMacroBlockWriter::open( micro_writer_, GCONF.micro_block_merge_verify_level))) { STORAGE_LOG(WARN, "fail to build micro writer", K(ret)); - } else if (OB_FAIL(read_info_.init( - allocator_, - data_store_desc.row_column_count_ - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(), - data_store_desc.schema_rowkey_col_cnt_, - lib::is_oracle_mode(), - data_store_desc.col_desc_array_, - true))) { + } else if (OB_FAIL(read_info_.init(allocator_, data_store_desc))) { STORAGE_LOG(WARN, "failed to init read info", K(data_store_desc), K(ret)); } else if (OB_FAIL(datum_row_.init(allocator_, read_info_.get_request_count()))) { STORAGE_LOG(WARN, "Failed to init datum row", K(ret), K_(read_info)); @@ -488,7 +473,7 @@ int ObMacroBlockWriter::open( if (OB_FAIL(sstable_index_builder->new_index_builder(builder_, data_store_desc, allocator_))) { STORAGE_LOG(WARN, "fail to alloc index builder", K(ret)); } else if (data_store_desc.need_pre_warm_) { - data_block_pre_warmer_.init(read_info_); + data_block_pre_warmer_.init(); } } else { builder_ = nullptr; @@ -518,9 +503,9 @@ int ObMacroBlockWriter::append_row(const ObDatumRow &row, const int64_t split_si const ObDatumRow *row_to_append = &row; bool is_need_set_micro_upper_bound = false; int64_t estimate_remain_size = 0; - if (NULL == data_store_desc_) { + if (nullptr == data_store_desc_) { ret = OB_NOT_INIT; - STORAGE_LOG(WARN, "The ObMacroBlockWriter has not been opened, ", K(ret)); + STORAGE_LOG(WARN, "The ObMacroBlockWriter has not been opened, ", K(ret), KP(data_store_desc_)); } else if (split_size < data_store_desc_->micro_block_size_) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "invalid split_size", K(ret), K(split_size)); @@ -1082,7 +1067,7 @@ int ObMacroBlockWriter::build_micro_block_desc_with_rewrite( if (OB_FAIL(macro_reader_.decrypt_and_decompress_data(micro_des_meta, micro_block.data_.get_buf(), micro_block.data_.get_buf_size(), decompressed_data.get_buf(), decompressed_data.get_buf_size(), is_compressed))) { LOG_WARN("fail to decrypt and decompress data", K(ret)); - } else if (OB_FAIL(reader->init(decompressed_data, *micro_block.read_info_))) { + } else if (OB_FAIL(reader->init(decompressed_data, nullptr))) { LOG_WARN("reader init failed", K(micro_block), K(ret)); } else if (OB_FAIL(save_last_key(micro_block.range_.get_end_key()))) { LOG_WARN("Fail to save last key, ", K(ret), K(micro_block.range_.get_end_key())); @@ -1412,7 +1397,7 @@ int ObMacroBlockWriter::merge_micro_block(const ObMicroBlock µ_block) if (OB_FAIL(macro_reader_.decrypt_and_decompress_data(micro_des_meta, micro_block.data_.get_buf(), micro_block.data_.get_buf_size(), decompressed_data.get_buf(), decompressed_data.get_buf_size(), is_compressed))) { STORAGE_LOG(WARN, "fail to decrypt and decompress data", K(ret)); - } else if (OB_FAIL(micro_reader->init(decompressed_data, *micro_block.read_info_))) { + } else if (OB_FAIL(micro_reader->init(decompressed_data, nullptr))) { STORAGE_LOG(WARN, "micro_block_reader init failed", K(micro_block), K(ret)); } else { for (int64_t it = 0; OB_SUCC(ret) && it != micro_reader->row_count(); ++it) { @@ -1500,7 +1485,7 @@ int ObMacroBlockWriter::build_micro_writer(ObDataStoreDesc *data_store_desc, encoding_ctx.micro_block_size_ = data_store_desc->micro_block_size_; encoding_ctx.column_cnt_ = data_store_desc->row_column_count_; encoding_ctx.rowkey_column_cnt_ = data_store_desc->rowkey_column_count_; - encoding_ctx.col_descs_ = &data_store_desc->col_desc_array_; + encoding_ctx.col_descs_ = &data_store_desc->get_full_stored_col_descs(); encoding_ctx.encoder_opt_ = data_store_desc->encoder_opt_; encoding_ctx.column_encodings_ = nullptr; encoding_ctx.major_working_cluster_version_ = data_store_desc->major_working_cluster_version_; @@ -1529,7 +1514,7 @@ int ObMacroBlockWriter::build_micro_writer(ObDataStoreDesc *data_store_desc, data_store_desc->micro_block_size_limit_, data_store_desc->rowkey_column_count_, data_store_desc->row_column_count_, - &data_store_desc->col_desc_array_, + &data_store_desc->get_rowkey_col_descs(), need_calc_column_chksum))) { STORAGE_LOG(WARN, "Fail to init micro block flat writer, ", K(ret)); } else { @@ -1630,7 +1615,8 @@ void ObMacroBlockWriter::dump_macro_block(ObMacroBlock ¯o_block) if (macro_block.is_dirty()) { const int64_t block_cnt = macro_block.get_micro_block_count(); const int64_t data_offset = - ObMacroBlock::calc_basic_micro_block_data_offset(data_store_desc_->row_column_count_); + ObMacroBlock::calc_basic_micro_block_data_offset( + data_store_desc_->row_column_count_, data_store_desc_->rowkey_column_count_, data_store_desc_->get_fixed_header_version()); const char *data_buf = macro_block.get_data_buf() + data_offset; const int64_t data_size = macro_block.get_data_size() - data_offset; int64_t pos = 0; diff --git a/src/storage/blocksstable/ob_macro_block_writer.h b/src/storage/blocksstable/ob_macro_block_writer.h index e3db41f6c..2972a99f0 100644 --- a/src/storage/blocksstable/ob_macro_block_writer.h +++ b/src/storage/blocksstable/ob_macro_block_writer.h @@ -57,7 +57,7 @@ public: ~ObMicroBlockBufferHelper() = default; int open( ObDataStoreDesc &data_store_desc, - ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, common::ObIAllocator &allocator); int compress_encrypt_micro_block(ObMicroBlockDesc µ_block_desc); int dump_micro_block_writer_buffer(const char *buf, const int64_t size); @@ -81,7 +81,6 @@ private: private: ObDataStoreDesc *data_store_desc_; - ObTableReadInfo *read_info_; int64_t micro_block_merge_verify_level_; ObMicroBlockCompressor compressor_; ObMicroBlockEncryption encryption_; @@ -205,7 +204,7 @@ private: ObMicroBlockReaderHelper reader_helper_; ObMicroBlockHashIndexBuilder hash_index_builder_; ObMicroBlockBufferHelper micro_helper_; - ObTableReadInfo read_info_; + ObRowkeyReadInfo read_info_; ObMacroBlock macro_blocks_[2]; ObMacroBloomFilterCacheWriter bf_cache_writer_[2];//associate with macro_blocks int64_t current_index_; diff --git a/src/storage/blocksstable/ob_micro_block_cache.cpp b/src/storage/blocksstable/ob_micro_block_cache.cpp old mode 100644 new mode 100755 index 7dc012f4f..893bb6d48 --- a/src/storage/blocksstable/ob_micro_block_cache.cpp +++ b/src/storage/blocksstable/ob_micro_block_cache.cpp @@ -304,13 +304,9 @@ ObIMicroBlockIOCallback::ObIMicroBlockIOCallback() : cache_(nullptr), put_size_stat_(nullptr), allocator_(nullptr), - io_buffer_(nullptr), - data_buffer_(nullptr), - read_info_(nullptr), tenant_id_(OB_INVALID_TENANT_ID), block_id_(), offset_(0), - size_(0), row_store_type_(MAX_ROW_STORE), block_des_meta_(), use_block_cache_(true), @@ -322,45 +318,12 @@ ObIMicroBlockIOCallback::ObIMicroBlockIOCallback() ObIMicroBlockIOCallback::~ObIMicroBlockIOCallback() { - if (OB_NOT_NULL(allocator_) && OB_NOT_NULL(io_buffer_)) { - allocator_->free(io_buffer_); - io_buffer_ = nullptr; - } -} -int ObIMicroBlockIOCallback::alloc_io_buf( - char *&io_buf, int64_t &align_size, int64_t &align_offset) -{ - int ret = OB_SUCCESS; - align_size = 0; - align_offset = 0; - common::align_offset_size(offset_, size_, align_offset, align_size); - if (OB_ISNULL(allocator_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Unexpected error, the allocator is NULL, ", KP_(allocator), K(ret)); - } else { - io_buffer_ = static_cast(allocator_->alloc(align_size + DIO_READ_ALIGN_SIZE)); - for (int64_t i = 1; OB_ISNULL(io_buffer_) && i <= ALLOC_BUF_RETRY_TIMES; i++) { - ob_usleep(ALLOC_BUF_RETRY_INTERVAL * i); - io_buffer_ = static_cast(allocator_->alloc(align_size + DIO_READ_ALIGN_SIZE)); - } - if (OB_NOT_NULL(io_buffer_)) { - io_buf = reinterpret_cast(upper_align(reinterpret_cast(io_buffer_), - DIO_READ_ALIGN_SIZE)); - data_buffer_ = io_buf + (offset_ - align_offset); - } else { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("Fail to allocate memory", - K(ret), K_(offset), K_(size), K(align_offset), K(align_size)); - } - } - - return ret; } int ObIMicroBlockIOCallback::process_block( ObMacroBlockReader *reader, - char *buffer, + const char *buffer, const int64_t offset, const int64_t size, const ObMicroBlockCacheValue *µ_block, @@ -380,7 +343,7 @@ int ObIMicroBlockIOCallback::process_block( } else if (OB_FAIL(header.check_and_get_record( buffer, size, MICRO_BLOCK_HEADER_MAGIC, payload_buf, payload_size))) { LOG_ERROR("Micro block data is corrupted", K(ret), K_(block_id), K(offset), - K(size), K_(tenant_id), KP(buffer), KP(io_buffer_), KP(data_buffer_), KP(this)); + K(size), K_(tenant_id), KP(buffer), KP(this)); } else { if (OB_UNLIKELY(!use_block_cache_)) { // Won't put in cache @@ -393,7 +356,7 @@ int ObIMicroBlockIOCallback::process_block( bool need_decoder = false; ObMicroBlockCacheKey key(tenant_id_, block_id_, offset, size); int64_t value_size = cache_->calc_value_size(block_size, row_store_type_, header.row_count_, - read_info_->get_request_count(), extra_size, need_decoder); + header.column_count_, extra_size, need_decoder); if (OB_FAIL(cache_->get_cache(kvcache))) { LOG_WARN("Fail to get kvcache", K(ret)); } else if (OB_UNLIKELY(OB_SUCCESS == (ret = kvcache->get(key, micro_block, cache_handle)))) { @@ -419,7 +382,7 @@ int ObIMicroBlockIOCallback::process_block( block_buf + pos, block_size - pos))) { LOG_WARN("Fail to decompress data with preallocated buffer", K(ret)); - } else if (need_write_extra_buf_ && OB_FAIL(cache_->write_extra_buf(*read_info_, block_buf, block_size, + } else if (need_write_extra_buf_ && OB_FAIL(cache_->write_extra_buf(block_buf, block_size, extra_size, block_buf + block_size, micro_data))) { LOG_WARN("Fail to writer extra buffer of block data", K(ret), K(header), KPC(cache_value)); } else if (FALSE_IT(micro_block = cache_value)) { @@ -454,7 +417,7 @@ int ObIMicroBlockIOCallback::process_block( int ObIMicroBlockIOCallback::read_block_and_copy( ObMacroBlockReader &reader, - char *buffer, + const char *buffer, const int64_t size, ObMicroBlockData &block_data, const ObMicroBlockCacheValue *µ_block, @@ -497,13 +460,9 @@ int ObIMicroBlockIOCallback::assign(const ObIMicroBlockIOCallback &other) cache_ = other.cache_; put_size_stat_ = other.put_size_stat_; allocator_ = other.allocator_; - io_buffer_ = other.io_buffer_; - data_buffer_ = other.data_buffer_; - read_info_ = other.read_info_; tenant_id_ = other.tenant_id_; block_id_ = other.block_id_; offset_ = other.offset_; - size_ = other.size_; row_store_type_ = other.row_store_type_; block_des_meta_ = other.block_des_meta_; use_block_cache_ = other.use_block_cache_; @@ -529,7 +488,6 @@ ObSingleMicroBlockIOCallback::~ObSingleMicroBlockIOCallback() allocator_->free(const_cast(micro_block_)); micro_block_ = nullptr; } - tablet_handle_.reset(); } int64_t ObSingleMicroBlockIOCallback::size() const @@ -537,26 +495,25 @@ int64_t ObSingleMicroBlockIOCallback::size() const return sizeof(*this); } -int ObSingleMicroBlockIOCallback::inner_process(const bool is_success) +int ObSingleMicroBlockIOCallback::inner_process(const char *data_buffer, const int64_t size) { int ret = OB_SUCCESS; if (OB_ISNULL(cache_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Invalid micro block cache callback, ", KP_(cache), K(ret)); - } else if (is_success) { + } else if (OB_UNLIKELY(size <= 0 || data_buffer == nullptr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid data buffer size", K(ret), K(size), KP(data_buffer)); + } else { ObMacroBlockReader *reader = nullptr; if (OB_ISNULL(reader = GET_TSI_MULT(ObMacroBlockReader, 1))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("Fail to allocate ObMacroBlockReader, ", K(ret)); - } else if (OB_FAIL(process_block(reader, data_buffer_, offset_, size_, micro_block_, cache_handle_))) { + } else if (OB_FAIL(process_block(reader, data_buffer, offset_, size, micro_block_, cache_handle_))) { LOG_WARN("process_block failed", K(ret)); } } - if (OB_NOT_NULL(allocator_) && OB_NOT_NULL(io_buffer_)) { - allocator_->free(io_buffer_); - io_buffer_ = nullptr; - } return ret; } @@ -578,7 +535,6 @@ int ObSingleMicroBlockIOCallback::inner_deep_copy( LOG_WARN("fail to assign callback", K(ret)); } else { pcallback->micro_block_ = micro_block_; - pcallback->tablet_handle_ = tablet_handle_; pcallback->cache_handle_ = cache_handle_; callback = pcallback; } @@ -595,7 +551,6 @@ const char *ObSingleMicroBlockIOCallback::get_data() return data; } - /*-----------------------------------ObMultiDataBlockIOCallback-----------------------------------*/ ObMultiDataBlockIOCallback::ObMultiDataBlockIOCallback() : ObIMicroBlockIOCallback(), @@ -615,13 +570,16 @@ int64_t ObMultiDataBlockIOCallback::size() const return sizeof(*this); } -int ObMultiDataBlockIOCallback::inner_process(const bool is_success) +int ObMultiDataBlockIOCallback::inner_process(const char *data_buffer, const int64_t size) { int ret = OB_SUCCESS; if (OB_ISNULL(cache_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Invalid micro block cache callback, ", KP_(cache), K(ret)); - } else if (is_success) { + } else if (OB_UNLIKELY(size <= 0 || data_buffer == nullptr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid data buffer size", K(ret), K(size), KP(data_buffer)); + } else { ObMacroBlockReader *reader = nullptr; if (OB_ISNULL(reader = GET_TSI_MULT(ObMacroBlockReader, 1))) { ret = OB_ALLOCATE_MEMORY_FAILED; @@ -636,7 +594,7 @@ int ObMultiDataBlockIOCallback::inner_process(const bool is_success) const int64_t data_offset = io_ctx_.micro_index_infos_[i].get_block_offset() - offset_; if (OB_FAIL(process_block( reader, - data_buffer_ + data_offset, + data_buffer + data_offset, offset_ + data_offset, data_size, io_result_.micro_blocks_[i], @@ -646,11 +604,6 @@ int ObMultiDataBlockIOCallback::inner_process(const bool is_success) } } - if (OB_NOT_NULL(allocator_) && OB_NOT_NULL(io_buffer_)) { - allocator_->free(io_buffer_); - io_buffer_ = nullptr; - } - if (OB_FAIL(ret)) { io_result_.ret_code_ = ret; } @@ -816,7 +769,6 @@ int ObIMicroBlockCache::get_cache_block( } int ObIMicroBlockCache::reserve_kvpair(const ObMicroBlockDesc µ_block_desc, - const ObTableReadInfo &read_info, ObKVCacheInstHandle &inst_handle, ObKVCacheHandle &cache_handle, ObKVCachePair *&kvpair, @@ -825,10 +777,10 @@ int ObIMicroBlockCache::reserve_kvpair(const ObMicroBlockDesc µ_block_desc, int ret = OB_SUCCESS; kvpair_size = 0; - if (OB_UNLIKELY(!micro_block_desc.is_valid() || !read_info.is_valid() || inst_handle.is_valid() + if (OB_UNLIKELY(!micro_block_desc.is_valid() || inst_handle.is_valid() || cache_handle.is_valid() || nullptr != kvpair)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid argument", K(ret), K(micro_block_desc), K(read_info), K(inst_handle), K(cache_handle), KP(kvpair)); + LOG_WARN("Invalid argument", K(ret), K(micro_block_desc), K(inst_handle), K(cache_handle), KP(kvpair)); } else { int64_t extra_size = 0; bool need_decoder = false; @@ -836,15 +788,14 @@ int ObIMicroBlockCache::reserve_kvpair(const ObMicroBlockDesc µ_block_desc, int64_t value_size = calc_value_size(block_size, static_cast(micro_block_desc.header_->row_store_type_), micro_block_desc.row_count_, - read_info.get_request_count(), + micro_block_desc.column_count_, extra_size, need_decoder); if (OB_FAIL(alloc_base_kvpair(micro_block_desc, sizeof(ObMicroBlockCacheKey), value_size, inst_handle, cache_handle, kvpair))) { LOG_WARN("Fail to alloc kvpair buf", K(ret)); } else if (!need_decoder) { - } else if (OB_FAIL(write_extra_buf(read_info, - reinterpret_cast(kvpair->value_) + sizeof(ObMicroBlockCacheValue), + } else if (OB_FAIL(write_extra_buf(reinterpret_cast(kvpair->value_) + sizeof(ObMicroBlockCacheValue), block_size, extra_size, reinterpret_cast(kvpair->value_) + sizeof(ObMicroBlockCacheValue) @@ -865,8 +816,6 @@ int ObIMicroBlockCache::prefetch( const MacroBlockId ¯o_id, const ObMicroIndexInfo& idx_row, const common::ObQueryFlag &flag, - const ObTableReadInfo &read_info, - const ObTabletHandle &tablet_handle, ObMacroBlockHandle ¯o_handle) { int ret = OB_SUCCESS; @@ -879,8 +828,6 @@ int ObIMicroBlockCache::prefetch( LOG_WARN("Invalid data index block row header ", K(ret), K(idx_row)); } else { ObSingleMicroBlockIOCallback callback; - callback.read_info_ = &read_info; - callback.tablet_handle_ = tablet_handle; callback.need_write_extra_buf_ = idx_header->is_data_index() && (!idx_header->is_data_block() || (ObStoreFormat::is_row_store_type_with_encoding(idx_header->get_row_store_type()))); @@ -916,7 +863,6 @@ int ObIMicroBlockCache::prefetch( callback.tenant_id_ = tenant_id; callback.block_id_ = macro_id; callback.offset_ = idx_row.get_block_offset(); - callback.size_ = idx_row.get_block_size(); callback.row_store_type_ = idx_row.get_row_store_type(); callback.block_des_meta_.compressor_type_ = idx_row_header->get_compressor_type(); callback.block_des_meta_.encrypt_id_ = idx_row_header->get_encrypt_id(); @@ -928,11 +874,8 @@ int ObIMicroBlockCache::prefetch( read_info.macro_block_id_ = macro_id; read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_DATA_READ); read_info.io_callback_ = &callback; - common::align_offset_size( - idx_row.get_block_offset(), - idx_row.get_block_size(), - read_info.offset_, - read_info.size_); + read_info.offset_ = idx_row.get_block_offset(); + read_info.size_ = idx_row.get_block_size(); if (OB_FAIL(ObBlockManager::async_read_block(read_info, macro_handle))) { STORAGE_LOG(WARN, "Fail to async read block, ", K(ret)); } else { @@ -969,14 +912,14 @@ int ObIMicroBlockCache::prefetch( callback.tenant_id_ = tenant_id; callback.block_id_ = macro_id; callback.offset_ = offset; - callback.size_ = size; callback.use_block_cache_ = flag.is_use_block_cache(); // fill read info ObMacroBlockReadInfo read_info; read_info.macro_block_id_ = macro_id; read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_DATA_READ); read_info.io_callback_ = &callback; - common::align_offset_size(offset, size, read_info.offset_, read_info.size_); + read_info.offset_ = offset; + read_info.size_ = size; if (OB_FAIL(ObBlockManager::async_read_block(read_info, macro_handle))) { STORAGE_LOG(WARN, "Fail to async read block, ", K(ret)); @@ -1050,7 +993,6 @@ int ObDataMicroBlockCache::prefetch( const MacroBlockId ¯o_id, const ObMultiBlockIOParam &io_param, const ObQueryFlag &flag, - const ObTableReadInfo &full_read_info, ObMacroBlockHandle ¯o_handle) { int ret = OB_SUCCESS; @@ -1060,7 +1002,6 @@ int ObDataMicroBlockCache::prefetch( LOG_WARN("Invalid input parameters", K(ret), K(tenant_id)); } else if (OB_FAIL(callback.set_io_ctx(io_param))) { LOG_WARN("Set io context failed", K(ret), K(io_param)); - } else if (FALSE_IT(callback.read_info_ = &full_read_info)) { } else if (OB_FAIL(ObIMicroBlockCache::prefetch( tenant_id, macro_id, io_param, flag, macro_handle, callback))) { LOG_WARN("Fail to prefetch multi data blocks", K(ret)); @@ -1071,12 +1012,11 @@ int ObDataMicroBlockCache::prefetch( int ObDataMicroBlockCache::load_block( const ObMicroBlockId µ_block_id, const ObMicroBlockDesMeta &des_meta, - const ObTableReadInfo *read_info, ObMacroBlockReader *macro_reader, ObMicroBlockData &block_data, ObIAllocator *allocator) { - UNUSEDx(read_info, allocator); + UNUSEDx(allocator); int ret = OB_SUCCESS; ObMacroBlockReadInfo macro_read_info; ObMacroBlockHandle macro_handle; @@ -1136,8 +1076,7 @@ int64_t ObDataMicroBlockCache::calc_value_size(const int64_t data_length, return value_size; } -int ObDataMicroBlockCache::write_extra_buf(const ObTableReadInfo &read_info, - const char *block_buf, +int ObDataMicroBlockCache::write_extra_buf(const char *block_buf, const int64_t block_size, const int64_t extra_size, char *extra_buf, @@ -1149,8 +1088,7 @@ int ObDataMicroBlockCache::write_extra_buf(const ObTableReadInfo &read_info, int64_t decoder_size = 0; if (OB_FAIL(ObMicroBlockDecoder::get_decoder_cache_size(block_buf, block_size, decoder_size))) { LOG_WARN("Fail to get decoder cache size", K(ret)); - } else if (OB_FAIL(ObMicroBlockDecoder::cache_decoders(extra_buf, decoder_size, block_buf, - block_size, read_info.get_columns_desc()))) { + } else if (OB_FAIL(ObMicroBlockDecoder::cache_decoders(extra_buf, decoder_size, block_buf, block_size))) { LOG_WARN("Fail to set cache decoder", K(ret)); } else { micro_data.get_extra_buf() = extra_buf; @@ -1184,7 +1122,6 @@ int ObIndexMicroBlockCache::init(const char *cache_name, const int64_t priority) int ObIndexMicroBlockCache::load_block( const ObMicroBlockId µ_block_id, const ObMicroBlockDesMeta &des_meta, - const ObTableReadInfo *read_info, ObMacroBlockReader *macro_reader, ObMicroBlockData &block_data, ObIAllocator *allocator) @@ -1197,11 +1134,9 @@ int ObIndexMicroBlockCache::load_block( ObMacroBlockReader inner_macro_reader; bool is_compressed = false; const bool need_deep_copy = true; - if (OB_UNLIKELY(!micro_block_id.is_valid()) - || OB_ISNULL(read_info) - || OB_ISNULL(allocator)) { + if (OB_UNLIKELY(!micro_block_id.is_valid()) || OB_ISNULL(allocator)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid argument", K(ret), K(micro_block_id), KP(read_info), KP(allocator)); + LOG_WARN("Invalid argument", K(ret), K(micro_block_id), KP(allocator)); } else { macro_read_info.macro_block_id_ = micro_block_id.macro_id_; macro_read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_DATA_READ); @@ -1220,7 +1155,7 @@ int ObIndexMicroBlockCache::load_block( if (OB_ISNULL(extra_buf = reinterpret_cast(allocator->alloc(extra_buf_size)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("Failed to alloc memory for transformed index block", K(ret)); - } else if (OB_FAIL(write_extra_buf(*read_info, nullptr, 0, extra_buf_size, extra_buf, block_data))) { + } else if (OB_FAIL(write_extra_buf( nullptr, 0, extra_buf_size, extra_buf, block_data))) { LOG_WARN("Failed to transform index block", K(ret)); } else { EVENT_INC(ObStatEventIds::IO_READ_PREFETCH_MICRO_COUNT); @@ -1249,8 +1184,7 @@ int64_t ObIndexMicroBlockCache::calc_value_size(const int64_t data_length, return sizeof(ObMicroBlockCacheValue) + data_length + extra_size; } -int ObIndexMicroBlockCache::write_extra_buf(const ObTableReadInfo &read_info, - const char *block_buf, +int ObIndexMicroBlockCache::write_extra_buf(const char *block_buf, const int64_t block_size, const int64_t extra_size, char *extra_buf, @@ -1260,7 +1194,11 @@ int ObIndexMicroBlockCache::write_extra_buf(const ObTableReadInfo &read_info, int ret = OB_SUCCESS; ObIndexBlockDataTransformer transformer; - if (OB_FAIL(transformer.transform(read_info, micro_data, extra_buf, extra_size))) { + + if (OB_UNLIKELY(!micro_data.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid argument", K(ret), K(micro_data)); + } else if (OB_FAIL(transformer.transform(micro_data, extra_buf, extra_size))) { LOG_WARN("Fail to transform index block data", K(ret)); } else { micro_data.extra_buf_ = extra_buf; diff --git a/src/storage/blocksstable/ob_micro_block_cache.h b/src/storage/blocksstable/ob_micro_block_cache.h index 7daeed397..cd49dda15 100644 --- a/src/storage/blocksstable/ob_micro_block_cache.h +++ b/src/storage/blocksstable/ob_micro_block_cache.h @@ -141,6 +141,8 @@ struct ObMultiBlockIOCtx class ObIPutSizeStat { public: + ObIPutSizeStat() {} + virtual ~ObIPutSizeStat() {} virtual int add_put_size(const int64_t put_size) = 0; }; @@ -150,13 +152,11 @@ class ObIMicroBlockIOCallback : public common::ObIOCallback public: ObIMicroBlockIOCallback(); virtual ~ObIMicroBlockIOCallback(); - virtual int alloc_io_buf(char *&io_buf, int64_t &io_buf_size, int64_t &aligned_offset); - VIRTUAL_TO_STRING_KV(KP_(io_buffer)); protected: friend class ObIMicroBlockCache; int process_block( ObMacroBlockReader *reader, - char *buffer, + const char *buffer, const int64_t offset, const int64_t size, const ObMicroBlockCacheValue *µ_block, @@ -165,7 +165,7 @@ protected: private: int read_block_and_copy( ObMacroBlockReader &reader, - char *buffer, + const char *buffer, const int64_t size, ObMicroBlockData &block_data, const ObMicroBlockCacheValue *µ_block, @@ -177,13 +177,9 @@ protected: ObIMicroBlockCache *cache_; ObIPutSizeStat *put_size_stat_; common::ObIAllocator *allocator_; - char *io_buffer_; - char *data_buffer_; - const ObTableReadInfo *read_info_; uint64_t tenant_id_; MacroBlockId block_id_; int64_t offset_; - int64_t size_; ObRowStoreType row_store_type_; ObMicroBlockDesMeta block_des_meta_; bool use_block_cache_; @@ -197,18 +193,16 @@ public: ObSingleMicroBlockIOCallback(); virtual ~ObSingleMicroBlockIOCallback(); virtual int64_t size() const; - virtual int inner_process(const bool is_success) override; + virtual int inner_process(const char *data_buffer, const int64_t size) override; virtual int inner_deep_copy( char *buf, const int64_t buf_len, ObIOCallback *&callback) const override; virtual const char *get_data() override; - INHERIT_TO_STRING_KV("ObIMicroBlockIOCallback", ObIMicroBlockIOCallback, KP_(micro_block), - K_(tablet_handle), K_(cache_handle), K_(need_write_extra_buf)); + TO_STRING_KV(KP_(micro_block), K_(cache_handle), K_(need_write_extra_buf), K_(offset)); private: friend class ObIMicroBlockCache; // Notice: lifetime shoule be longer than AIO or deep copy here const ObMicroBlockCacheValue *micro_block_; - ObTabletHandle tablet_handle_; common::ObKVCacheHandle cache_handle_; }; @@ -218,12 +212,12 @@ public: ObMultiDataBlockIOCallback(); virtual ~ObMultiDataBlockIOCallback(); virtual int64_t size() const; - virtual int inner_process(const bool is_success) override; + virtual int inner_process(const char *data_buffer, const int64_t size) override; virtual int inner_deep_copy( char *buf, const int64_t buf_len, ObIOCallback *&callback) const override; virtual const char *get_data() override; - INHERIT_TO_STRING_KV("ObIMicroBlockIOCallback", ObIMicroBlockIOCallback, K_(io_ctx)); + TO_STRING_KV(K_(io_ctx), K_(offset)); private: friend class ObDataMicroBlockCache; int set_io_ctx(const ObMultiBlockIOParam &io_param); @@ -231,7 +225,6 @@ private: int deep_copy_ctx(const ObMultiBlockIOCtx &io_ctx); int alloc_result(); void free_result(); - // Notice: lifetime shoule be longer than AIO or deep copy here ObMultiBlockIOCtx io_ctx_; ObMultiBlockIOResult io_result_; }; @@ -240,7 +233,8 @@ class ObIMicroBlockCache : public ObIPutSizeStat { public: typedef common::ObIKVCache BaseBlockCache; -public: + ObIMicroBlockCache() {} + virtual ~ObIMicroBlockCache() {} int get_cache_block( const uint64_t tenant_id, const MacroBlockId block_id, @@ -249,7 +243,6 @@ public: ObMicroBlockBufferHandle &handle); virtual int reserve_kvpair( const ObMicroBlockDesc µ_block_desc, - const ObTableReadInfo &read_info, ObKVCacheInstHandle &inst_handle, ObKVCacheHandle &cache_handle, ObKVCachePair *&kvpair, @@ -259,13 +252,10 @@ public: const MacroBlockId ¯o_id, const ObMicroIndexInfo& idx_row, const common::ObQueryFlag &flag, - const ObTableReadInfo &read_info, - const ObTabletHandle &tablet_handle, ObMacroBlockHandle ¯o_handle); virtual int load_block( const ObMicroBlockId µ_block_id, const ObMicroBlockDesMeta &des_meta, - const ObTableReadInfo *read_info, ObMacroBlockReader *macro_reader, ObMicroBlockData &block_data, ObIAllocator *allocator) = 0; @@ -274,7 +264,7 @@ public: virtual int get_allocator(common::ObIAllocator *&allocator) = 0; virtual int64_t calc_value_size(const int64_t data_length, const ObRowStoreType &type, const int64_t row_count, const int64_t request_count, int64_t &extra_size, bool &need_decoder) = 0; - virtual int write_extra_buf(const ObTableReadInfo &read_info, const char *block_buf, const int64_t block_size, + virtual int write_extra_buf(const char *block_buf, const int64_t block_size, const int64_t extra_size, char *extra_buf, ObMicroBlockData µ_data) = 0; virtual ObMicroBlockData::Type get_type() = 0; virtual int add_put_size(const int64_t put_size) override; @@ -312,12 +302,10 @@ public: const MacroBlockId ¯o_id, const ObMultiBlockIOParam &io_param, const ObQueryFlag &flag, - const ObTableReadInfo &full_read_info, ObMacroBlockHandle ¯o_handle); int load_block( const ObMicroBlockId µ_block_id, const ObMicroBlockDesMeta &des_meta, - const ObTableReadInfo *read_info, ObMacroBlockReader *macro_reader, ObMicroBlockData &block_data, ObIAllocator *allocator) override; @@ -325,7 +313,7 @@ public: virtual int get_allocator(common::ObIAllocator *&allocator) override; virtual int64_t calc_value_size(const int64_t data_length, const ObRowStoreType &type, const int64_t row_count, const int64_t request_count, int64_t &extra_size, bool &need_decoder); - virtual int write_extra_buf(const ObTableReadInfo &read_info, const char *block_buf, const int64_t block_size, + virtual int write_extra_buf(const char *block_buf, const int64_t block_size, const int64_t extra_size, char *extra_buf, ObMicroBlockData µ_data); virtual ObMicroBlockData::Type get_type() override; private: @@ -342,13 +330,12 @@ public: int load_block( const ObMicroBlockId µ_block_id, const ObMicroBlockDesMeta &des_meta, - const ObTableReadInfo *read_info, ObMacroBlockReader *macro_reader, ObMicroBlockData &block_data, ObIAllocator *allocator) override; virtual int64_t calc_value_size(const int64_t data_length, const ObRowStoreType &type, const int64_t row_count, const int64_t request_count, int64_t &extra_size, bool &need_decoder); - virtual int write_extra_buf(const ObTableReadInfo &read_info, const char *block_buf, const int64_t block_size, + virtual int write_extra_buf(const char *block_buf, const int64_t block_size, const int64_t extra_size, char *extra_buf, ObMicroBlockData µ_data); virtual ObMicroBlockData::Type get_type() override; }; diff --git a/src/storage/blocksstable/ob_micro_block_reader.cpp b/src/storage/blocksstable/ob_micro_block_reader.cpp index 75687024d..aa22bdcd9 100644 --- a/src/storage/blocksstable/ob_micro_block_reader.cpp +++ b/src/storage/blocksstable/ob_micro_block_reader.cpp @@ -35,13 +35,13 @@ public: ReaderType *reader, const char *data_begin, const int32_t *index_data, - const ObTableReadInfo *read_info) + const ObStorageDatumUtils *datum_utils) : ret_(ret), equal_(equal), reader_(reader), data_begin_(data_begin), index_data_(index_data), - read_info_(read_info) {} + datum_utils_(datum_utils) {} ~PreciseCompare() {} inline bool operator() (const int64_t row_idx, const ObDatumRowkey &rowkey) { @@ -61,11 +61,11 @@ private: // do nothing } else if (OB_FAIL(reader_->compare_meta_rowkey( rowkey, - *read_info_, + *datum_utils_, data_begin_ + index_data_[row_idx], index_data_[row_idx + 1] - index_data_[row_idx], compare_result))) { - LOG_WARN("fail to compare rowkey", K(ret), K(rowkey), KPC_(read_info)); + LOG_WARN("fail to compare rowkey", K(ret), K(rowkey), KPC_(datum_utils)); } else { bret = lower_bound ? compare_result < 0 : compare_result > 0; // binary search will keep searching after find the first equal item, @@ -83,7 +83,7 @@ private: ReaderType *reader_; const char *data_begin_; const int32_t *index_data_; - const ObTableReadInfo *read_info_; + const ObStorageDatumUtils *datum_utils_; }; ObIMicroBlockFlatReader::ObIMicroBlockFlatReader() @@ -115,7 +115,7 @@ int ObIMicroBlockFlatReader::find_bound_( const bool lower_bound, const int64_t begin_idx, const int64_t end_idx, - const ObTableReadInfo &read_info, + const ObStorageDatumUtils &datum_utils, int64_t &row_idx, bool &equal) { @@ -132,7 +132,7 @@ int ObIMicroBlockFlatReader::find_bound_( &flat_row_reader_, data_begin_, index_data_, - &read_info); + &datum_utils); ObRowIndexIterator begin_iter(begin_idx); ObRowIndexIterator end_iter(end_idx); ObRowIndexIterator found_iter; @@ -142,7 +142,7 @@ int ObIMicroBlockFlatReader::find_bound_( found_iter = std::upper_bound(begin_iter, end_iter, key, flat_compare); } if (OB_FAIL(ret)) { - LOG_WARN("fail to lower bound rowkey", K(ret), K(key), K(lower_bound), K(read_info)); + LOG_WARN("fail to lower bound rowkey", K(ret), K(key), K(lower_bound), K(datum_utils)); } else { row_idx = *found_iter; } @@ -171,7 +171,7 @@ int ObIMicroBlockFlatReader::init(const ObMicroBlockData &block_data) * */ int ObMicroBlockGetReader::inner_init( const ObMicroBlockData &block_data, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, const ObDatumRowkey &rowkey) { int ret = OB_SUCCESS; @@ -192,7 +192,7 @@ int ObMicroBlockGetReader::inner_init( int ObMicroBlockGetReader::get_row( const ObMicroBlockData &block_data, const ObDatumRowkey &rowkey, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, ObDatumRow &row) { int ret = OB_SUCCESS; @@ -221,7 +221,7 @@ int ObMicroBlockGetReader::get_row( int ObMicroBlockGetReader::exist_row( const ObMicroBlockData &block_data, const ObDatumRowkey &rowkey, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, bool &exist, bool &found) { @@ -261,7 +261,7 @@ int ObMicroBlockGetReader::locate_rowkey(const ObDatumRowkey &rowkey, int64_t &r } else if (need_binary_search) { bool is_equal = false; if (OB_FAIL(ObIMicroBlockFlatReader::find_bound_(rowkey, true/*lower_bound*/, 0, row_count_, - *read_info_, row_idx, is_equal))) { + read_info_->get_datum_utils(), row_idx, is_equal))) { LOG_WARN("fail to lower_bound rowkey", K(ret)); } else if (row_count_ == row_idx || !is_equal) { row_idx = ObIMicroBlockReaderInfo::INVALID_ROW_INDEX; @@ -306,7 +306,7 @@ int ObMicroBlockGetReader::locate_rowkey_fast_path(const ObDatumRowkey &rowkey, LOG_WARN("Unexpected row_idx", K(ret), K(tmp_row_idx), K(row_count_), K(rowkey), KPC_(read_info)); } else if (OB_FAIL(flat_row_reader_.compare_meta_rowkey( rowkey, - *read_info_, + read_info_->get_datum_utils(), data_begin_ + index_data_[tmp_row_idx], index_data_[tmp_row_idx + 1] - index_data_[tmp_row_idx], compare_result))) { @@ -341,7 +341,7 @@ void ObMicroBlockReader::reset() int ObMicroBlockReader::init( const ObMicroBlockData &block_data, - const ObTableReadInfo &read_info) + const ObITableReadInfo &read_info) { int ret = OB_SUCCESS; if (IS_INIT) { @@ -355,6 +355,7 @@ int ObMicroBlockReader::init( } else { row_count_ = header_->row_count_; read_info_ = &read_info; + datum_utils_ = &(read_info.get_datum_utils()); is_inited_ = true; } @@ -364,6 +365,30 @@ int ObMicroBlockReader::init( return ret; } +int ObMicroBlockReader::init( + const ObMicroBlockData &block_data, + const ObStorageDatumUtils *datum_utils) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + reset(); + } + if (OB_FAIL(ObIMicroBlockFlatReader::init(block_data))) { + LOG_WARN("fail to init, ", K(ret)); + } else { + row_count_ = header_->row_count_; + read_info_ = nullptr; + datum_utils_ = datum_utils; + is_inited_ = true; + } + + if (IS_NOT_INIT) { + reset(); + } + return ret; +} + + int ObMicroBlockReader::find_bound( const ObDatumRowkey &key, const bool lower_bound, @@ -375,19 +400,19 @@ int ObMicroBlockReader::find_bound( if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not init"); - } else if (OB_UNLIKELY(!key.is_valid() || begin_idx < 0 || nullptr == read_info_)) { + } else if (OB_UNLIKELY(!key.is_valid() || begin_idx < 0 || nullptr == datum_utils_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(key), K(begin_idx), K(row_count_), - KP_(data_begin), KP_(index_data), KP_(read_info)); + KP_(data_begin), KP_(index_data), KP_(datum_utils)); } else if (OB_FAIL(ObIMicroBlockFlatReader::find_bound_( key, lower_bound, begin_idx, row_count_, - *read_info_, + *datum_utils_, row_idx, equal))) { - LOG_WARN("failed to find bound", K(ret), K(lower_bound), K(begin_idx), K_(row_count), KPC_(read_info)); + LOG_WARN("failed to find bound", K(ret), K(lower_bound), K(begin_idx), K_(row_count), KPC_(datum_utils)); } return ret; } @@ -411,11 +436,10 @@ int ObMicroBlockReader::get_row(const int64_t index, ObDatumRow &row) ret = OB_NOT_INIT; LOG_WARN("should init reader first, ", K(ret)); } else if(OB_UNLIKELY(nullptr == header_ || - nullptr == read_info_ || index < 0 || index >= header_->row_count_ || !row.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(index), K(row), KPC_(header), KPC_(read_info)); + LOG_WARN("invalid argument", K(ret), K(index), K(row), KPC_(header)); } else if (OB_FAIL(flat_row_reader_.read_row( data_begin_ + index_data_[index], index_data_[index + 1] - index_data_[index], @@ -536,7 +560,7 @@ int ObMicroBlockReader::filter_pushdown_filter( const common::ObIArray &col_offsets = filter.get_col_offsets(); const sql::ColumnParamFixedArray &col_params = filter.get_col_params(); const common::ObIArray &default_datums = filter.get_default_datums(); - const common::ObIArray &cols_index = read_info_->get_columns_index(); + const ObColumnIndexArray &cols_index = read_info_->get_columns_index(); const ObColDescIArray &cols_desc = read_info_->get_columns_desc(); for (int64_t row_idx = pd_filter_info.start_; OB_SUCC(ret) && row_idx < pd_filter_info.end_; ++row_idx) { if (nullptr != parent && parent->can_skip_filter(row_idx)) { @@ -706,7 +730,7 @@ int ObMicroBlockReader::get_row_count( } else { count = 0; int64_t row_idx = common::OB_INVALID_INDEX; - const common::ObIArray &cols_index = read_info_->get_columns_index(); + const ObColumnIndexArray &cols_index = read_info_->get_columns_index(); int64_t col_idx = cols_index.at(col); ObStorageDatum datum; for (int64_t i = 0; OB_SUCC(ret) && i < row_cap; ++i) { @@ -743,7 +767,7 @@ int ObMicroBlockReader::get_min_or_max( LOG_WARN("Invalid argument", K(ret), KPC(header_), KPC_(read_info), K(row_cap), K(col)); } else { int64_t row_idx = common::OB_INVALID_INDEX; - const common::ObIArray &cols_index = read_info_->get_columns_index(); + const ObColumnIndexArray &cols_index = read_info_->get_columns_index(); int64_t col_idx = cols_index.at(col); ObStorageDatum datum; for (int64_t i = 0; OB_SUCC(ret) && i < row_cap; ++i) { diff --git a/src/storage/blocksstable/ob_micro_block_reader.h b/src/storage/blocksstable/ob_micro_block_reader.h index 1dec41dec..dfbad5f38 100644 --- a/src/storage/blocksstable/ob_micro_block_reader.h +++ b/src/storage/blocksstable/ob_micro_block_reader.h @@ -40,7 +40,7 @@ protected: const bool lower_bound, const int64_t begin_idx, const int64_t end_idx, - const ObTableReadInfo &read_info, + const ObStorageDatumUtils &datum_utils, int64_t &row_idx, bool &equal); OB_INLINE int init(const ObMicroBlockData &block_data); @@ -67,7 +67,12 @@ public: virtual void reset(); virtual int init( const ObMicroBlockData &block_data, - const ObTableReadInfo &read_info) override; + const ObITableReadInfo &read_info) override; + //when there is not read_info in input parameters, it indicates reading all columns from all rows + //when the incoming datum_utils is nullptr, it indicates not calling locate_range or find_bound + virtual int init( + const ObMicroBlockData &block_data, + const ObStorageDatumUtils *datum_utils) override; virtual int get_row(const int64_t index, ObDatumRow &row) override; virtual int get_row_header( const int64_t row_idx, @@ -148,18 +153,18 @@ public: virtual int get_row( const ObMicroBlockData &block_data, const ObDatumRowkey &rowkey, - const ObTableReadInfo &read_info, + const storage::ObITableReadInfo &read_info, ObDatumRow &row) final; virtual int exist_row( const ObMicroBlockData &block_data, const ObDatumRowkey &rowkey, - const ObTableReadInfo &read_info, + const storage::ObITableReadInfo &read_info, bool &exist, bool &found) final; int locate_rowkey(const ObDatumRowkey &rowkey, int64_t &row_idx); protected: int inner_init(const ObMicroBlockData &block_data, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, const ObDatumRowkey &rowkey); private: int locate_rowkey_fast_path(const ObDatumRowkey &rowkey, diff --git a/src/storage/blocksstable/ob_micro_block_row_exister.h b/src/storage/blocksstable/ob_micro_block_row_exister.h index f73563b2e..c88020543 100644 --- a/src/storage/blocksstable/ob_micro_block_row_exister.h +++ b/src/storage/blocksstable/ob_micro_block_row_exister.h @@ -34,7 +34,7 @@ public: bool &exist, bool &found); private: - const ObTableReadInfo *read_info_; + const ObITableReadInfo *read_info_; }; } diff --git a/src/storage/blocksstable/ob_micro_block_row_getter.cpp b/src/storage/blocksstable/ob_micro_block_row_getter.cpp index 772da2a98..2aabd2536 100644 --- a/src/storage/blocksstable/ob_micro_block_row_getter.cpp +++ b/src/storage/blocksstable/ob_micro_block_row_getter.cpp @@ -257,7 +257,9 @@ int ObMicroBlockRowGetter::get_block_row( if (store_row->row_flag_.is_not_exist()) { ++context_->table_store_stat_.get_row_.empty_read_cnt_; EVENT_INC(ObStatEventIds::GET_ROW_EMPTY_READ); - if (!context_->query_flag_.is_index_back() && context_->query_flag_.is_use_bloomfilter_cache() && !sstable_->is_small_sstable()) { + if (!context_->query_flag_.is_index_back() + && context_->query_flag_.is_use_bloomfilter_cache() + && !sstable_->is_small_sstable()) { (void) OB_STORE_CACHE.get_bf_cache().inc_empty_read( MTL_ID(), param_->table_id_, @@ -304,7 +306,7 @@ int ObMicroBlockRowGetter::get_cached_row( int ObMicroBlockRowGetter::project_cache_row(const ObRowCacheValue &value, ObDatumRow &row) { int ret = OB_SUCCESS; - const ObTableReadInfo *read_info = nullptr; + const ObITableReadInfo *read_info = nullptr; if (OB_ISNULL(read_info = param_->get_read_info())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("null read_info", K(ret), K_(param)); @@ -312,7 +314,7 @@ int ObMicroBlockRowGetter::project_cache_row(const ObRowCacheValue &value, ObDat LOG_WARN("fail to reserve memory for datum row", K(ret), K(read_info->get_request_count())); } else { const int64_t request_cnt = read_info->get_request_count(); - const ObIArray &cols_index = read_info->get_columns_index(); + const ObColumnIndexArray &cols_index = read_info->get_columns_index(); row.row_flag_ = value.get_flag(); row.count_ = read_info->get_request_count(); ObStorageDatum *const datums = value.get_datums(); @@ -402,7 +404,7 @@ int ObMicroBlockRowGetter::get_not_exist_row(const ObDatumRowkey &rowkey, const ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); } else { - const ObTableReadInfo *read_info = nullptr; + const ObITableReadInfo *read_info = nullptr; if (OB_ISNULL(read_info = param_->get_read_info())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("null read_info", K(ret), K_(param)); diff --git a/src/storage/blocksstable/ob_micro_block_row_getter.h b/src/storage/blocksstable/ob_micro_block_row_getter.h index cf451a882..b6f265cd7 100644 --- a/src/storage/blocksstable/ob_micro_block_row_getter.h +++ b/src/storage/blocksstable/ob_micro_block_row_getter.h @@ -80,7 +80,7 @@ private: const ObMicroBlockData &block_data, const ObDatumRow *&row); private: - const ObTableReadInfo *read_info_; + const ObITableReadInfo *read_info_; ObDatumRow row_; ObDatumRow cache_project_row_; }; diff --git a/src/storage/blocksstable/ob_micro_block_row_lock_checker.cpp b/src/storage/blocksstable/ob_micro_block_row_lock_checker.cpp old mode 100644 new mode 100755 index 843a15aa7..8057cda93 --- a/src/storage/blocksstable/ob_micro_block_row_lock_checker.cpp +++ b/src/storage/blocksstable/ob_micro_block_row_lock_checker.cpp @@ -64,14 +64,14 @@ int ObMicroBlockRowLockChecker::get_next_row(const ObDatumRow *&row) } else if (OB_FAIL(lock_state_->trans_version_.convert_for_tx(trans_version))) { LOG_ERROR("convert failed", K(ret), K(trans_version)); } else if (row_header->get_row_multi_version_flag().is_uncommitted_row()) { - ObTxTableGuard tx_table_guard = ctx.get_tx_table_guard(); + ObTxTableGuards tx_table_guards = ctx.get_tx_table_guards(); ObTxTable *tx_table = nullptr; int64 read_epoch = ObTxTable::INVALID_READ_EPOCH; - if (!tx_table_guard.is_valid()) { + if (!tx_table_guards.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("tx table guard is invalid", KR(ret), K(ctx)); - } else if (OB_FAIL(tx_table_guard.check_row_locked( - read_trans_id, row_header->get_trans_id(), sql_sequence, *lock_state_))) { + } else if (OB_FAIL(tx_table_guards.check_row_locked(read_trans_id, row_header->get_trans_id(), sql_sequence, + sstable_->get_end_scn(), *lock_state_))) { } else if (lock_state_->is_locked_) { lock_state_->lock_dml_flag_ = row_header->get_row_flag().get_dml_flag(); } diff --git a/src/storage/blocksstable/ob_micro_block_row_scanner.cpp b/src/storage/blocksstable/ob_micro_block_row_scanner.cpp index a283d48bd..1e1e21f69 100644 --- a/src/storage/blocksstable/ob_micro_block_row_scanner.cpp +++ b/src/storage/blocksstable/ob_micro_block_row_scanner.cpp @@ -110,7 +110,7 @@ int ObIMicroBlockRowScanner::init( if (NULL != reader_) { reader_->reset(); } - tx_table_guard_ = context.store_ctx_->mvcc_acc_ctx_.get_tx_table_guard(); + tx_table_guard_ = context.store_ctx_->mvcc_acc_ctx_.get_tx_table_guards(); LOG_DEBUG("init ObIMicroBlockRowScanner", K(context), KPC_(read_info), K(param)); } } @@ -154,7 +154,7 @@ int ObIMicroBlockRowScanner::switch_context( context_ = &context; sstable_ = sstable; use_fuse_row_cache_ = context.use_fuse_row_cache_; - tx_table_guard_ = context.store_ctx_->mvcc_acc_ctx_.get_tx_table_guard(); + tx_table_guard_ = context.store_ctx_->mvcc_acc_ctx_.get_tx_table_guards(); } return ret; @@ -271,6 +271,24 @@ int ObIMicroBlockRowScanner::inner_get_next_row(const ObDatumRow *&row) return ret; } +int ObIMicroBlockRowScanner::inner_get_row_header(const ObRowHeader *&row_header) +{ + int ret = OB_SUCCESS; + row_header = nullptr; + if (OB_FAIL(end_of_block())) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to judge end of block or not", K(ret)); + } + } else { + if (OB_FAIL(reader_->get_row_header(current_, row_header))) { + LOG_WARN("micro block reader fail to get row.", K(ret), K_(macro_id)); + } else { + current_ += step_; + } + } + return ret; +} + int ObIMicroBlockRowScanner::inner_get_next_row_blockscan(const ObDatumRow *&row) { int ret = OB_SUCCESS; @@ -568,7 +586,7 @@ int ObMicroBlockRowScanner::open( } int ObMicroBlockRowScanner::estimate_row_count( - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, const ObMicroBlockData &block_data, const ObDatumRange &range, bool consider_multi_version, @@ -582,16 +600,12 @@ int ObMicroBlockRowScanner::estimate_row_count( LOG_WARN("invalid argument", K(ret), KPC_(range), K(block_data)); } else if (OB_FAIL(set_reader(block_data.get_store_type()))) { LOG_WARN("failed to set reader", K(ret), K(block_data)); - } else if (OB_FAIL(reader_->init(block_data, read_info))) { + } else if (OB_FAIL(reader_->init(block_data, &read_info.get_datum_utils()))) { LOG_WARN("failed to init micro block reader", K(ret), K(block_data), K(read_info)); } else { is_inited_ = true; if (OB_FAIL(set_base_scan_param(true, true))) { LOG_WARN("failed to set base scan param", K(ret), K(range)); - } else if (row_.is_valid() && OB_FAIL(row_.reserve(max_col_count))) { - STORAGE_LOG(WARN, "Failed to reserve datum row", K(ret), K(max_col_count)); - } else if (!row_.is_valid() && OB_FAIL(row_.init(allocator_, max_col_count))) { - STORAGE_LOG(WARN, "Failed to init datum row", K(ret), K(max_col_count)); } } @@ -605,11 +619,11 @@ int ObMicroBlockRowScanner::estimate_row_count( est.logical_row_count_ = est.physical_row_count_; if (est.physical_row_count_ > 0 && consider_multi_version) { - const ObDatumRow *row; + const ObRowHeader *row_header; est.logical_row_count_ = 0; - while (OB_SUCC(inner_get_next_row(row))) { - if (row->mvcc_row_flag_.is_first_multi_version_row()) { - est.logical_row_count_ += row->get_delta(); + while (OB_SUCC(inner_get_row_header(row_header))) { + if (row_header->get_row_multi_version_flag().is_first_multi_version_row()) { + est.logical_row_count_ += row_header->get_row_flag().get_delta(); } } if (OB_ITER_END == ret || OB_BEYOND_THE_RANGE == ret) { @@ -1061,7 +1075,8 @@ int ObMultiVersionMicroBlockRowScanner::inner_inner_get_next_row( transaction::ObLockForReadArg lock_for_read_arg(acc_ctx, transaction::ObTransID(row_header->get_trans_id()), sql_sequence, - context_->query_flag_.read_latest_); + context_->query_flag_.read_latest_, + sstable_->get_end_scn()); if (OB_FAIL(lock_for_read(lock_for_read_arg, can_read, @@ -1076,12 +1091,13 @@ int ObMultiVersionMicroBlockRowScanner::inner_inner_get_next_row( ObStoreRowLockState lock_state; if (param_->is_for_foreign_check_ && OB_FAIL(ObRowConflictHandler::check_foreign_key_constraint_for_sstable( - acc_ctx.get_tx_table_guard(), + acc_ctx.get_tx_table_guards(), acc_ctx.get_tx_id(), transaction::ObTransID(row_header->get_trans_id()), sql_sequence, trans_version, snapshot_version, + sstable_->get_end_scn(), lock_state))) { if (OB_TRY_LOCK_ROW_CONFLICT == ret) { int tmp_ret = OB_SUCCESS; @@ -1096,7 +1112,8 @@ int ObMultiVersionMicroBlockRowScanner::inner_inner_get_next_row( lock_state, context_->tablet_id_, context_->ls_id_, - 0, 0 /* these two params get from mvcc_row, and for statistics, so we ignore them */); + 0, 0 /* these two params get from mvcc_row, and for statistics, so we ignore them */, + sstable_->get_end_scn()); } } } @@ -1329,8 +1346,10 @@ int ObMultiVersionMicroBlockRowScanner::lock_for_read( int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; SCN scn_trans_version = SCN::invalid_scn(); - if (OB_FAIL(tx_table_guard_.lock_for_read( - lock_for_read_arg, can_read, scn_trans_version, is_determined_state))) { + auto &tx_table_guards = context_->store_ctx_->mvcc_acc_ctx_.get_tx_table_guards(); + + if (OB_FAIL(tx_table_guards.lock_for_read(lock_for_read_arg, can_read, scn_trans_version, + is_determined_state))) { LOG_WARN("failed to check transaction status", K(ret)); } else { trans_version = scn_trans_version.get_val_for_tx(); @@ -2099,8 +2118,9 @@ int ObMultiVersionMicroBlockMinorMergeRowScanner::get_trans_state(const transact int ret = OB_SUCCESS; // get trans status & committed_trans_version_ SCN scn_commit_trans_version = SCN::max_scn(); - - if (OB_FAIL(tx_table_guard_.get_tx_state_with_scn(trans_id, context_->merge_scn_, state, scn_commit_trans_version))) { + auto &tx_table_guards = context_->store_ctx_->mvcc_acc_ctx_.get_tx_table_guards(); + if (OB_FAIL(tx_table_guards.get_tx_state_with_scn( + trans_id, context_->merge_scn_, state, scn_commit_trans_version))) { LOG_WARN("get transaction status failed", K(ret), K(trans_id), K(state)); } else { commit_trans_version = scn_commit_trans_version.get_val_for_tx(); @@ -2241,7 +2261,12 @@ int ObMultiVersionMicroBlockMinorMergeRowScanner::check_curr_row_can_read(const OB_SUCCESS == context_->trans_state_mgr_->get_trans_state(trans_id, sql_seq, trans_state)) { can_read = trans_state.can_read_; } else { - if (OB_FAIL(tx_table_guard_.check_sql_sequence_can_read(trans_id, sql_seq, can_read))) { + storage::ObTxTableGuards tx_table_guards = context_->store_ctx_->mvcc_acc_ctx_.get_tx_table_guards(); + if (OB_FAIL(tx_table_guards.check_sql_sequence_can_read( + trans_id, + sql_seq, + sstable_->get_end_scn(), + can_read))) { LOG_WARN("check sql sequence can read failed", K(ret), K(can_read), K(trans_id), K(sql_seq)); } else if (OB_NOT_NULL(context_->trans_state_mgr_) && OB_TMP_FAIL(context_->trans_state_mgr_->add_trans_state(trans_id, sql_seq, diff --git a/src/storage/blocksstable/ob_micro_block_row_scanner.h b/src/storage/blocksstable/ob_micro_block_row_scanner.h index 255f7c679..2cc0d2e5e 100644 --- a/src/storage/blocksstable/ob_micro_block_row_scanner.h +++ b/src/storage/blocksstable/ob_micro_block_row_scanner.h @@ -67,6 +67,7 @@ public: protected: virtual int inner_get_next_row(const ObDatumRow *&row); + int inner_get_row_header(const ObRowHeader *&row_header); int set_reader(const ObRowStoreType store_type); int set_base_scan_param(const bool is_left_bound_block, const bool is_right_bound_block); @@ -99,7 +100,7 @@ protected: int64_t step_; ObDatumRow row_; MacroBlockId macro_id_; - const ObTableReadInfo *read_info_; + const ObITableReadInfo *read_info_; const ObDatumRange *range_; const blocksstable::ObSSTable *sstable_; ObIMicroBlockReader *reader_; @@ -110,7 +111,7 @@ protected: ObIAllocator &allocator_; bool can_ignore_multi_version_; storage::ObBlockRowStore *block_row_store_; - storage::ObTxTableGuard tx_table_guard_; + storage::ObTxTableGuards tx_table_guard_; }; // major sstable micro block scanner for query and merge @@ -131,7 +132,7 @@ public: const bool is_left_border, const bool is_right_border) override final; int estimate_row_count( - const ObTableReadInfo &column_info, + const ObITableReadInfo &column_info, const ObMicroBlockData &block_data, const ObDatumRange &range, bool consider_multi_version, diff --git a/src/storage/blocksstable/ob_row_reader.cpp b/src/storage/blocksstable/ob_row_reader.cpp index 8eb2dfbb9..27a113b83 100644 --- a/src/storage/blocksstable/ob_row_reader.cpp +++ b/src/storage/blocksstable/ob_row_reader.cpp @@ -239,7 +239,7 @@ int ObClusterColumnReader::sequence_deep_copy_datums_of_sparse( } LOG_DEBUG("sequence_deep_copy_datums_of_sparse", K(col_idx), K(tmp_pos), K(next_pos), K(cell_end_pos_)); if (OB_FAIL(read_column_from_buf(tmp_pos, next_pos, special_val, datums[col_idx]))) { - LOG_WARN("failed to read column from buf", K(ret), K(tmp_pos), K(next_pos), K(special_val)); + LOG_WARN("failed to read column from buf", K(ret), K(tmp_pos), K(next_pos), K(special_val)); } } cur_idx_++; @@ -278,7 +278,7 @@ int ObClusterColumnReader::sequence_deep_copy_datums_of_dense(const int64_t star } LOG_DEBUG("sequence_deep_copy_datums_of_dense", K(cur_idx), K(tmp_pos), K(next_pos)); if (OB_FAIL(read_column_from_buf(tmp_pos, next_pos, special_val, datums[cur_idx]))) { - LOG_WARN("failed to read column from buf", K(ret), K(tmp_pos), K(next_pos), K(special_val)); + LOG_WARN("failed to read column from buf", K(ret), K(tmp_pos), K(next_pos), K(special_val)); } } } // end of for @@ -306,7 +306,7 @@ int ObClusterColumnReader::sequence_deep_copy_datums(const int64_t start_idx, Ob int ObClusterColumnReader::read_cell_with_bitmap( const int64_t start_idx, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, ObDatumRow &datum_row, memtable::ObNopBitMap &nop_bitmap) { @@ -316,7 +316,7 @@ int ObClusterColumnReader::read_cell_with_bitmap( LOG_WARN("cluster column reader is not init", K(ret)); } else { int64_t cur_idx = 0; - const common::ObIArray &cols_index = read_info.get_memtable_columns_index(); + const ObColumnIndexArray &cols_index = read_info.get_memtable_columns_index(); for (int i = 0; OB_SUCC(ret) && i < read_info.get_request_count(); ++i) { if (!nop_bitmap.test(i)) { // is_nop, read current cell @@ -352,7 +352,7 @@ int ObClusterColumnReader::read_cell_with_bitmap( } int ObClusterColumnReader::read_8_bytes_column( - const char *buf, + const char *buf, const int64_t buf_len, ObStorageDatum &datum) { @@ -364,13 +364,13 @@ int ObClusterColumnReader::read_8_bytes_column( } else { switch (buf_len) { case 1: - value = reinterpret_cast(buf)[0]; + value = reinterpret_cast(buf)[0]; break; case 2: - value = reinterpret_cast(buf)[0]; + value = reinterpret_cast(buf)[0]; break; case 4: - value = reinterpret_cast(buf)[0]; + value = reinterpret_cast(buf)[0]; break; default: ret = OB_NOT_SUPPORTED; @@ -378,10 +378,10 @@ int ObClusterColumnReader::read_8_bytes_column( } } if (OB_SUCC(ret)) { - datum.reuse(); + datum.reuse(); datum.set_uint(value); LOG_DEBUG("ObClusterColumnReader read 8 bytes column ", K(value)); - } + } return ret; } @@ -389,18 +389,18 @@ int ObClusterColumnReader::read_column_from_buf( const int64_t tmp_pos, const int64_t next_pos, const ObRowHeader::SPECIAL_VAL special_val, - ObStorageDatum &datum) + ObStorageDatum &datum) { int ret = OB_SUCCESS; - const char *buf = cluster_buf_ + tmp_pos; + const char *buf = cluster_buf_ + tmp_pos; const int64_t buf_len = next_pos - tmp_pos; if (special_val == ObRowHeader::VAL_ENCODING_NORMAL) { if (OB_FAIL(read_8_bytes_column(buf, buf_len, datum))) { - LOG_WARN("failed to decode 8 bytes column", K(ret), K(special_val), KP(buf), K(buf_len), KPC(this)); - } + LOG_WARN("failed to decode 8 bytes column", K(ret), K(special_val), KP(buf), K(buf_len), KPC(this)); + } } else if (OB_FAIL(datum.from_buf_enhance(buf, buf_len))) { LOG_WARN("failed to copy datum", K(ret), K(special_val), KP(buf), K(buf_len), KPC(this)); - } + } return ret; } @@ -425,7 +425,7 @@ int ObClusterColumnReader::read_datum(const int64_t column_idx, ObStorageDatum & next_pos = cell_end_pos_; } if (OB_FAIL(read_column_from_buf(tmp_pos, next_pos, special_val, datum))) { - LOG_WARN("failed to read column from buf", K(ret), KP(tmp_pos), K(next_pos), K(special_val)); + LOG_WARN("failed to read column from buf", K(ret), KP(tmp_pos), K(next_pos), K(special_val)); } } return ret; @@ -475,7 +475,7 @@ int ObRowReader::read_row_header( int ObRowReader::read_memtable_row( const char *row_buf, const int64_t row_len, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, ObDatumRow &datum_row, memtable::ObNopBitMap &nop_bitmap, bool &read_finished) @@ -489,7 +489,7 @@ int ObRowReader::read_memtable_row( } else { datum_row.count_ = read_info.get_request_count(); int64_t store_idx = 0; - const common::ObIArray &cols_index = read_info.get_memtable_columns_index(); + const ObColumnIndexArray &cols_index = read_info.get_memtable_columns_index(); for (int i = 0; OB_SUCC(ret) && i < read_info.get_request_count(); ++i) { if (!nop_bitmap.test(i)) { // is_nop, read current cell } else { @@ -593,7 +593,7 @@ int ObRowReader::analyze_info_and_init_reader(const int64_t cluster_idx) int ObRowReader::read_row( const char *row_buf, const int64_t row_len, - const ObTableReadInfo *read_info, + const ObITableReadInfo *read_info, ObDatumRow &datum_row) { int ret = OB_SUCCESS; @@ -632,7 +632,10 @@ int ObRowReader::read_row( } else { cluster_col_cnt = cluster_reader_.get_column_count(); for (int64_t i = 0; OB_SUCC(ret) && i < cluster_col_cnt && idx < seq_read_cnt; ++idx, ++i) { - if (i >= row_header_->get_column_count()) { // not exists + if (idx >= datum_row.count_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("idx is invalid", K(i), K(idx), K(seq_read_cnt), K(column_cnt), KPC(read_info)); + } else if (i >= row_header_->get_column_count()) { // not exists datum_row.storage_datums_[i].set_nop(); } else if (OB_FAIL(cluster_reader_.sequence_read_datum(i, datum_row.storage_datums_[idx]))) { LOG_WARN("Fail to read column", K(ret), K(idx)); @@ -647,7 +650,7 @@ int ObRowReader::read_row( if (nullptr != read_info) { int64_t store_idx = 0; - const common::ObIArray &cols_index = read_info->get_columns_index(); + const ObColumnIndexArray &cols_index = read_info->get_columns_index(); for (; OB_SUCC(ret) && idx < read_info->get_request_count(); ++idx) { // loop the ColumnIndex array store_idx = cols_index.at(idx); if (store_idx < 0 || store_idx >= row_header_->get_column_count()) { // not exists @@ -734,23 +737,22 @@ int ObRowReader::read_char( // called by ObIMicroBlockFlatReader::find_bound_::PreciseCompare int ObRowReader::compare_meta_rowkey( const ObDatumRowkey &rhs, - const ObTableReadInfo &read_info, + const ObStorageDatumUtils &datum_utils, const char *buf, const int64_t row_len, int32_t &cmp_result) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!rhs.is_valid() || !read_info.is_valid() || nullptr == buf || row_len <= 0)) { + if (OB_UNLIKELY(!rhs.is_valid() || !datum_utils.is_valid() || nullptr == buf || row_len <= 0)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid row header argument.", K(ret), K(read_info), + LOG_WARN("invalid row header argument.", K(ret), K(datum_utils), K(rhs), K(buf), K(row_len)); } else { cmp_result = 0; const int64_t compare_column_count = rhs.get_datum_cnt(); - const ObStorageDatumUtils &datum_utils = read_info.get_datum_utils(); if (OB_UNLIKELY(datum_utils.get_rowkey_count() < compare_column_count)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid argument to compare meta rowkey", K(ret), K(compare_column_count), K(rhs), K(read_info)); + LOG_WARN("Invalid argument to compare meta rowkey", K(ret), K(compare_column_count), K(rhs), K(datum_utils)); } else if (OB_FAIL(setup_row(buf, row_len))) { LOG_WARN("row reader fail to setup.", K(ret), K(OB_P(buf)), K(row_len)); } else if (OB_UNLIKELY(row_header_->get_rowkey_count() < compare_column_count)) { @@ -771,7 +773,7 @@ int ObRowReader::compare_meta_rowkey( OB_SUCC(ret) && cmp_result == 0 && i < cluster_col_cnt && idx < compare_column_count; ++idx, ++i) { if (OB_FAIL(cluster_reader_.sequence_read_datum(i, datum))) { - LOG_WARN("Fail to read column", K(ret), K(i), K(idx), K(read_info)); + LOG_WARN("Fail to read column", K(ret), K(i), K(idx), K(datum_utils)); } else if (OB_FAIL(datum_utils.get_cmp_funcs().at(idx).compare(datum, rhs.datums_[idx], cmp_result))) { STORAGE_LOG(WARN, "Failed to compare datums", K(ret), K(idx), K(datum), K(rhs.datums_[idx])); } diff --git a/src/storage/blocksstable/ob_row_reader.h b/src/storage/blocksstable/ob_row_reader.h index 1ba737466..d3803d6aa 100644 --- a/src/storage/blocksstable/ob_row_reader.h +++ b/src/storage/blocksstable/ob_row_reader.h @@ -62,7 +62,7 @@ public: int sequence_deep_copy_datums(const int64_t start_idx, ObStorageDatum *datum); int read_cell_with_bitmap( const int64_t start_idx, - const storage::ObTableReadInfo &read_info, + const storage::ObITableReadInfo &read_info, ObDatumRow &datum_row, memtable::ObNopBitMap &nop_bitmap); OB_INLINE int64_t get_sparse_col_idx(const int64_t column_idx); @@ -79,13 +79,13 @@ private: ObStorageDatum &datum); int read_column_from_buf( int64_t tmp_pos, - int64_t next_pos, + int64_t next_pos, const ObRowHeader::SPECIAL_VAL special_val, - ObStorageDatum &datum); + ObStorageDatum &datum); int read_datum(const int64_t column_idx, ObStorageDatum &datum); - OB_INLINE uint8_t read_special_value(const int64_t column_idx) + OB_INLINE uint8_t read_special_value(const int64_t column_idx) { - const int64_t index = column_idx >> 1; + const int64_t index = column_idx >> 1; const int64_t shift = (column_idx % 2) << 2; return (special_vals_[index] >> shift) & 0x0F; } @@ -118,13 +118,13 @@ public: int read_row( const char *row_buf, const int64_t row_len, - const storage::ObTableReadInfo *read_info, + const storage::ObITableReadInfo *read_info, ObDatumRow &datum_row); // only read cells where bitmap shows col_idx = TRUE int read_memtable_row( const char *row_buf, const int64_t row_len, - const storage::ObTableReadInfo &read_info, + const storage::ObITableReadInfo &read_info, ObDatumRow &datum_row, memtable::ObNopBitMap &nop_bitmap, bool &read_finished); @@ -137,7 +137,7 @@ public: ObStorageDatum &datum); int compare_meta_rowkey( const ObDatumRowkey &rhs, - const storage::ObTableReadInfo &read_info, + const blocksstable::ObStorageDatumUtils &datum_utils, const char *buf, const int64_t row_len, int32_t &cmp_result); diff --git a/src/storage/blocksstable/ob_shared_macro_block_manager.cpp b/src/storage/blocksstable/ob_shared_macro_block_manager.cpp old mode 100644 new mode 100755 index 6e12ef871..dec828465 --- a/src/storage/blocksstable/ob_shared_macro_block_manager.cpp +++ b/src/storage/blocksstable/ob_shared_macro_block_manager.cpp @@ -316,6 +316,12 @@ int64_t ObSharedMacroBlockMgr::get_shared_block_cnt() return count; } +void ObSharedMacroBlockMgr::get_cur_shared_block(MacroBlockId ¯o_id) +{ + lib::ObMutexGuard guard(mutex_); + macro_id = macro_handle_.get_macro_id(); +} + int ObSharedMacroBlockMgr::add_block(const MacroBlockId &block_id, const int64_t block_size) { int ret = OB_SUCCESS; @@ -450,6 +456,11 @@ int ObSharedMacroBlockMgr::defragment() } } + if (OB_ITER_END == ret || OB_SUCC(ret)) { + ret = OB_SUCCESS; + FLOG_INFO("successfully defragment data blocks", K(ret), K(rewrite_cnt), K(block_used_size_.count())); + } + if (nullptr != sstable_index_builder) { sstable_index_builder->~ObSSTableIndexBuilder(); task_allocator.free(sstable_index_builder); @@ -480,12 +491,17 @@ int ObSharedMacroBlockMgr::update_tablet( ObIndexBlockRebuilder &index_block_rebuilder) { int ret = OB_SUCCESS; - ObSArray table_handles; - ObTableHandleV2 sstable_handle; - ObSArray sstables; + common::ObArenaAllocator allocator("ShareBlkUpTab"); + ObSArray new_sstables; + ObTableStoreIterator table_store_iter; uint64_t data_version = 0; + const ObTabletMeta &tablet_meta = tablet_handle.get_obj()->get_tablet_meta(); + const share::ObLSID &ls_id = tablet_meta.ls_id_; + ObTabletHandle updated_tablet_handle; + ObMetaDiskAddr cur_addr; + const ObTabletMapKey key(ls_id, tablet_meta.tablet_id_); - if (OB_FAIL(tablet_handle.get_obj()->get_all_sstables(sstables))) { + if (OB_FAIL(tablet_handle.get_obj()->get_all_sstables(table_store_iter))) { LOG_WARN("fail to get sstables of this tablet", K(ret)); } else if (OB_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), data_version))) { if (OB_ENTRY_NOT_EXIST == ret) { @@ -494,82 +510,130 @@ int ObSharedMacroBlockMgr::update_tablet( LOG_WARN("fail to get data version", K(ret)); } } - for (int64_t i = 0; i < sstables.count() && OB_SUCC(ret); i++) { - const ObSSTable *sstable = static_cast(sstables.at(i)); - if (OB_ISNULL(sstable) || !sstable->is_valid()) { + while (OB_SUCC(ret)) { + ObITable *table = nullptr; + ObSSTableMetaHandle meta_handle; + const ObSSTable *sstable = nullptr; + if (OB_FAIL(table_store_iter.get_next(table))) { + if (OB_UNLIKELY(OB_ITER_END == ret)) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("fail to get next table from iter", K(ret), K(table_store_iter)); + } + } else if (FALSE_IT(sstable = static_cast(table))) { + } else if (OB_ISNULL(sstable) || !sstable->is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the sstable is null or invalid", K(ret)); + } else if (OB_FAIL(sstable->get_meta(meta_handle))) { + LOG_WARN("get meta handle fail", K(ret), KPC(sstable)); } else if (sstable->is_small_sstable()) { - const ObIArray &data_block_ids = sstable->get_meta().get_macro_info().get_data_block_ids(); - if (OB_UNLIKELY(1 != data_block_ids.count())) { + const int64_t data_block_count = meta_handle.get_sstable_meta().get_data_macro_block_count(); + ObMacroIdIterator id_iterator; + MacroBlockId macro_id; + if (OB_UNLIKELY(1 != data_block_count)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("this sstable is not small", K(ret), K(data_block_ids.count()), K(sstable->is_small_sstable())); - } else if (is_contain(macro_ids, data_block_ids.at(0))) { - if (OB_FAIL(rebuild_sstable( - *(tablet_handle.get_obj()), + LOG_WARN("this sstable is not small", K(ret), K(data_block_count)); + } else if (OB_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_data_block_iter(id_iterator))) { + LOG_WARN("get id iterator fail", K(ret)); + } else if (OB_FAIL(id_iterator.get_next_macro_id(macro_id))) { + LOG_WARN("get first id fail", K(ret)); + } else if (is_contain(macro_ids, macro_id)) { + void *buf = nullptr; + ObSSTable *new_sstable = nullptr; + if (!updated_tablet_handle.is_valid() // only get tablet for the first time + && OB_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, updated_tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_EAGAIN; + // tablet has been deleted, skip the defragmentation + } else { + LOG_WARN("fail to get tablet", K(ret), K(key)); + } + } else if (OB_FAIL(updated_tablet_handle.get_obj()->get_meta_disk_addr(cur_addr))) { + LOG_WARN("fail to get cur tablet addr", K(ret)); + } else if (OB_UNLIKELY(!tablet_handle.get_obj()->get_tablet_addr().is_equal_for_persistence(cur_addr))) { + ret = OB_EAGAIN; + // tablet has been changed, skip the defragmentation + } else if (OB_ISNULL(buf = allocator.alloc(sizeof(ObSSTable)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to acquire sstable object", K(ret)); + } else if (FALSE_IT(new_sstable = new (buf) ObSSTable())) { + } else if (OB_FAIL(rebuild_sstable( + allocator, + *(updated_tablet_handle.get_obj()), *sstable, data_version, sstable_index_builder, index_block_rebuilder, - sstable_handle))) { + *new_sstable))) { LOG_WARN("fail to rebuild sstable and update tablet", K(ret)); - } else if (OB_FAIL(table_handles.push_back(sstable_handle))) { - LOG_WARN("fail to push table handle to array", K(ret), K(sstable_handle)); + } else if (OB_FAIL(new_sstables.push_back(new_sstable))) { + LOG_WARN("fail to push table handle to array", K(ret), KPC(sstable)); } } } } - if (OB_SUCC(ret) && !table_handles.empty()) { - const ObTabletMeta &tablet_meta = tablet_handle.get_obj()->get_tablet_meta(); - const share::ObLSID &ls_id = tablet_meta.ls_id_; + if (OB_SUCC(ret) && !new_sstables.empty()) { ObLSService *ls_svr = MTL(ObLSService*); ObLSHandle ls_handle; if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { - LOG_WARN("fail to get ls handle", K(ret), K(ls_id)); + LOG_WARN("fail to get ls handle", K(ret), K(ls_id), KPC(tablet_handle.get_obj())); } else { const int64_t rebuild_seq = ls_handle.get_ls()->get_rebuild_seq(); if (OB_UNLIKELY(!ls_handle.is_valid())) { LOG_WARN("la handle is invalid", K(ret), K(ls_handle)); } else if (OB_FAIL(ls_handle.get_ls()->update_tablet_table_store( - rebuild_seq, tablet_handle, table_handles))) { - LOG_WARN("fail to replace small sstables in the tablet", K(ret), K(rebuild_seq), K(tablet_handle), K(table_handles)); + rebuild_seq, updated_tablet_handle, new_sstables))) { + LOG_WARN("fail to replace small sstables in the tablet", + K(ret), K(rebuild_seq), K(updated_tablet_handle), K(new_sstables)); } else { - rewrite_cnt += table_handles.count(); + rewrite_cnt += new_sstables.count(); } } } + if (!new_sstables.empty()) { + for (int64_t i = 0; i < new_sstables.count(); i++) { + ObITable *table = new_sstables[i]; + if (OB_LIKELY(nullptr != table)) { + table->~ObITable(); + } + } + } return ret; } int ObSharedMacroBlockMgr::rebuild_sstable( + common::ObArenaAllocator &allocator, const ObTablet &tablet, const ObSSTable &old_sstable, const uint64_t data_version, ObSSTableIndexBuilder &sstable_index_builder, ObIndexBlockRebuilder &index_block_rebuilder, - ObTableHandleV2 &table_handle) + ObSSTable &new_sstable) { int ret = OB_SUCCESS; ObDataStoreDesc data_desc; ObMergeType merge_type; sstable_index_builder.reset(); index_block_rebuilder.reset(); - table_handle.reset(); ObDataMacroBlockMeta data_macro_meta; ObMacroBlockHandle block_handle; ObBlockInfo block_info; ObMacroBlocksWriteCtx write_ctx; ObSSTableMergeRes res; - const int64_t column_count = old_sstable.get_meta().get_basic_meta().column_cnt_; + ObSSTableMetaHandle old_meta_handle; + ObSSTableMetaHandle new_meta_handle; - if (OB_FAIL(parse_merge_type(old_sstable, merge_type))) { + if (OB_FAIL(old_sstable.get_meta(old_meta_handle))) { + LOG_WARN("get meta handle fail", K(ret), K(old_sstable)); + } else if (OB_FAIL(parse_merge_type(old_sstable, merge_type))) { LOG_WARN("fail to parse merge type from old_sstable", K(ret)); } else if (OB_FAIL(prepare_data_desc( tablet, - old_sstable.get_meta().get_basic_meta(), + old_meta_handle.get_sstable_meta().get_basic_meta(), merge_type, tablet.get_snapshot_version(), data_version, @@ -589,92 +653,94 @@ int ObSharedMacroBlockMgr::rebuild_sstable( LOG_WARN("fail to append macro row", K(ret), K(block_info)); } else if (OB_FAIL(index_block_rebuilder.close())) { LOG_WARN("fail to close index block rebuilder", K(ret)); - } else if (OB_FAIL(sstable_index_builder.close(column_count, res))) { - LOG_WARN("fail to close sstable index builder", K(ret), K(column_count)); - } else if (OB_FAIL(create_new_sstable(res, tablet, old_sstable, block_info, table_handle))) { + } else if (OB_FAIL(sstable_index_builder.close(res))) { + LOG_WARN("fail to close sstable index builder", K(ret)); + } else if (OB_FAIL(create_new_sstable(allocator, res, old_sstable, block_info, new_sstable))) { LOG_WARN("fail to create new sstable", K(ret), K(tablet.get_tablet_meta()), K(old_sstable)); + } else if (OB_FAIL(new_sstable.set_upper_trans_version(old_sstable.get_upper_trans_version()))) { + LOG_WARN("fail to update upper trans version", K(ret), K(old_sstable.get_upper_trans_version())); + } else if (OB_FAIL(new_sstable.get_meta(new_meta_handle))) { + LOG_WARN("get meta handle fail", K(ret), K(new_sstable)); + } else if (OB_UNLIKELY(new_sstable.get_key() != old_sstable.get_key()) + || OB_FAIL(ObSSTableMetaChecker::check_sstable_meta_strict_equality( + old_meta_handle.get_sstable_meta(), new_meta_handle.get_sstable_meta()))) { + ret = OB_INVALID_DATA; + LOG_WARN("new sstable is not equal to old sstable", K(ret), K(new_sstable), K(old_sstable)); } else { - ObSSTable *new_sstable = nullptr; - if (OB_FAIL(table_handle.get_sstable(new_sstable))) { - LOG_WARN("fail to get new sstable", K(table_handle)); - } else if (OB_FAIL(new_sstable->set_upper_trans_version(old_sstable.get_meta().get_basic_meta().upper_trans_version_))) { - LOG_WARN("fail to update upper trans version", K(ret), K(old_sstable.get_meta().get_basic_meta().upper_trans_version_)); - } else if (OB_UNLIKELY(new_sstable->get_key() != old_sstable.get_key()) - || OB_FAIL(ObSSTableMetaChecker::check_sstable_meta_strict_equality(old_sstable.get_meta(), new_sstable->get_meta()))) { - ret = OB_INVALID_DATA; - LOG_WARN("new sstable is not equal to old sstable", K(ret), KPC(new_sstable), K(old_sstable)); - } else { - FLOG_INFO("successfully rebuild one sstable", K(ret), K(block_info), K(new_sstable->get_key()), K(new_sstable->get_meta())); - } + FLOG_INFO("successfully rebuild one sstable", K(ret), K(block_info), K(new_sstable.get_key())); } - return ret; } int ObSharedMacroBlockMgr::create_new_sstable( + common::ObArenaAllocator &allocator, const ObSSTableMergeRes &res, - const ObTablet &tablet, const ObSSTable &old_table, const ObBlockInfo &block_info, - ObTableHandleV2 &table_handle) const + ObSSTable &new_sstable) const { int ret = OB_SUCCESS; - const ObStorageSchema &storage_schema = tablet.get_storage_schema(); - const ObSSTableBasicMeta &basic_meta = old_table.get_meta().get_basic_meta(); - table_handle.reset(); ObTabletCreateSSTableParam param; + ObSSTableMetaHandle meta_handle; + if (OB_FAIL(old_table.get_meta(meta_handle))) { + LOG_WARN("get meta handle fail", K(ret), K(old_table)); + } else { + const ObSSTableBasicMeta &basic_meta = meta_handle.get_sstable_meta().get_basic_meta(); + param.filled_tx_scn_ = basic_meta.filled_tx_scn_; + param.ddl_scn_ = basic_meta.ddl_scn_; + param.table_key_ = old_table.get_key(); + param.sstable_logic_seq_ = meta_handle.get_sstable_meta().get_sstable_seq(); + param.table_mode_ = basic_meta.table_mode_; + param.index_type_ = static_cast(basic_meta.index_type_); + param.schema_version_ = basic_meta.schema_version_; + param.create_snapshot_version_ = basic_meta.create_snapshot_version_; + param.progressive_merge_round_ = basic_meta.progressive_merge_round_; + param.progressive_merge_step_ = basic_meta.progressive_merge_step_; + param.rowkey_column_cnt_ = basic_meta.rowkey_column_count_; + param.recycle_version_ = basic_meta.recycle_version_; + param.latest_row_store_type_ = basic_meta.latest_row_store_type_; + param.is_ready_for_read_ = true; - param.filled_tx_scn_ = basic_meta.filled_tx_scn_; - param.ddl_scn_ = basic_meta.ddl_scn_; - param.table_key_ = old_table.get_key(); - param.sstable_logic_seq_ = old_table.get_sstable_seq(); - param.table_mode_ = basic_meta.table_mode_; - param.index_type_ = static_cast(basic_meta.index_type_); - param.schema_version_ = basic_meta.schema_version_; - param.create_snapshot_version_ = basic_meta.create_snapshot_version_; - param.progressive_merge_round_ = basic_meta.progressive_merge_round_; - param.progressive_merge_step_ = basic_meta.progressive_merge_step_; - param.rowkey_column_cnt_ = basic_meta.rowkey_column_count_; - param.recycle_version_ = basic_meta.recycle_version_; - param.latest_row_store_type_ = basic_meta.latest_row_store_type_; - param.is_ready_for_read_ = true; + ObSSTableMergeRes::fill_addr_and_data(res.root_desc_, + param.root_block_addr_, param.root_block_data_); + ObSSTableMergeRes::fill_addr_and_data(res.data_root_desc_, + param.data_block_macro_meta_addr_, param.data_block_macro_meta_); + param.root_row_store_type_ = res.root_row_store_type_; + param.data_index_tree_height_ = res.root_desc_.height_; + param.index_blocks_cnt_ = res.index_blocks_cnt_; + param.data_blocks_cnt_ = res.data_blocks_cnt_; + param.micro_block_cnt_ = res.micro_block_cnt_; + param.use_old_macro_block_count_ = res.use_old_macro_block_count_; + param.row_count_ = res.row_count_; + param.column_cnt_ = res.data_column_cnt_; + param.data_checksum_ = res.data_checksum_; + param.occupy_size_ = res.occupy_size_; + param.original_size_ = res.original_size_; + param.max_merged_trans_version_ = res.max_merged_trans_version_; + param.contain_uncommitted_row_ = res.contain_uncommitted_row_; + param.compressor_type_ = res.compressor_type_; + param.encrypt_id_ = res.encrypt_id_; + param.master_key_id_ = res.master_key_id_; + param.data_block_ids_ = res.data_block_ids_; + param.is_meta_root_ = res.data_root_desc_.is_meta_root_; + param.nested_offset_ = block_info.nested_offset_; + param.nested_size_ = block_info.nested_size_; + param.other_block_ids_ = res.other_block_ids_; + MEMCPY(param.encrypt_key_, res.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); - ObSSTableMergeRes::fill_addr_and_data(res.root_desc_, - param.root_block_addr_, param.root_block_data_); - ObSSTableMergeRes::fill_addr_and_data(res.data_root_desc_, - param.data_block_macro_meta_addr_, param.data_block_macro_meta_); - param.root_row_store_type_ = res.root_row_store_type_; - param.data_index_tree_height_ = res.root_desc_.height_; - param.index_blocks_cnt_ = res.index_blocks_cnt_; - param.data_blocks_cnt_ = res.data_blocks_cnt_; - param.micro_block_cnt_ = res.micro_block_cnt_; - param.use_old_macro_block_count_ = res.use_old_macro_block_count_; - param.row_count_ = res.row_count_; - param.column_cnt_ = res.data_column_cnt_; - param.data_checksum_ = res.data_checksum_; - param.occupy_size_ = res.occupy_size_; - param.original_size_ = res.original_size_; - param.max_merged_trans_version_ = res.max_merged_trans_version_; - param.contain_uncommitted_row_ = res.contain_uncommitted_row_; - param.compressor_type_ = res.compressor_type_; - param.encrypt_id_ = res.encrypt_id_; - param.master_key_id_ = res.master_key_id_; - param.data_block_ids_ = res.data_block_ids_; - param.is_meta_root_ = res.data_root_desc_.is_meta_root_; - param.nested_offset_ = block_info.nested_offset_; - param.nested_size_ = block_info.nested_size_; - param.other_block_ids_ = res.other_block_ids_; - MEMCPY(param.encrypt_key_, res.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); - - if (param.table_key_.is_major_sstable()) { - if (OB_FAIL(res.fill_column_checksum(&storage_schema, param.column_checksums_))) { - LOG_WARN("fail to fill column checksum", K(ret), K(res)); + if (param.table_key_.is_major_sstable()) { + if (OB_FAIL(param.column_checksums_.assign(res.data_column_checksums_))) { + LOG_WARN("fail to fill column checksum", K(ret), K(res)); + } } } if (OB_FAIL(ret)) { // do nothing - } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, table_handle))) { - LOG_WARN("fail to create sstable", K(ret), K(param)); + } else if (OB_UNLIKELY(!param.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(param)); + } else if (OB_FAIL(new_sstable.init(param, &allocator))) { + LOG_WARN("failed to init sstable", K(ret), K(param)); } return ret; @@ -689,9 +755,13 @@ int ObSharedMacroBlockMgr::prepare_data_desc( ObDataStoreDesc &data_desc) const { int ret = OB_SUCCESS; + ObArenaAllocator tmp_arena("ShrBlkMgrTmp"); + const ObStorageSchema *storage_schema = nullptr; data_desc.reset(); - if (OB_FAIL(data_desc.init( - tablet.get_storage_schema(), + if (OB_FAIL(tablet.load_storage_schema(tmp_arena, storage_schema))) { + LOG_WARN("fail to load storage schema", K(ret), K(tablet)); + } else if (OB_FAIL(data_desc.init_as_index( + *storage_schema, tablet.get_tablet_meta().ls_id_, tablet.get_tablet_meta().tablet_id_, merge_type, @@ -708,28 +778,15 @@ int ObSharedMacroBlockMgr::prepare_data_desc( data_desc.encrypt_id_ = basic_meta.encrypt_id_; data_desc.encoder_opt_.set_store_type(basic_meta.root_row_store_type_); MEMCPY(data_desc.encrypt_key_, basic_meta.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); - data_desc.row_column_count_ = data_desc.rowkey_column_count_ + 1; - data_desc.col_desc_array_.reset(); - data_desc.need_prebuild_bloomfilter_ = false; - if (OB_FAIL(data_desc.col_desc_array_.init(data_desc.row_column_count_))) { - LOG_WARN("fail to reserve column desc array", K(ret)); - } else if (OB_FAIL(tablet.get_storage_schema().get_rowkey_column_ids(data_desc.col_desc_array_))) { - LOG_WARN("fail to get rowkey column ids", K(ret)); - } else if (OB_FAIL(storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(data_desc.col_desc_array_))) { - LOG_WARN("fail to add extra rowkey cols", K(ret)); - } else { - ObObjMeta meta; - meta.set_varchar(); - meta.set_collation_type(CS_TYPE_BINARY); - share::schema::ObColDesc col; - col.col_id_ = static_cast(data_desc.row_column_count_ + OB_APP_MIN_COLUMN_ID); - col.col_type_ = meta; - col.col_order_ = DESC; - if (OB_FAIL(data_desc.col_desc_array_.push_back(col))) { - LOG_WARN("fail to push back last col for index", K(ret), K(col)); - } + + // since the schema is always newer than the original sstable and new cols can only be added to the tail, + // it's safe to pop back the default checksum of new cols to keep the consistency of sstable_meta. + data_desc.full_stored_col_cnt_ = basic_meta.column_cnt_; + while(data_desc.col_default_checksum_array_.count() > basic_meta.column_cnt_) { + data_desc.col_default_checksum_array_.pop_back(); } } + ObTablet::free_storage_schema(tmp_arena, storage_schema); return ret; } @@ -775,16 +832,27 @@ int ObSharedMacroBlockMgr::read_sstable_block( { int ret = OB_SUCCESS; ObMacroBlockReadInfo read_info; - const ObSSTableMacroInfo ¯o_info = sstable.get_meta().get_macro_info(); - read_info.macro_block_id_ = macro_info.get_data_block_ids().at(0); - read_info.offset_ = macro_info.get_nested_offset(); - read_info.size_ = upper_align(macro_info.get_nested_size(), DIO_READ_ALIGN_SIZE); - read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_READ); + ObSSTableMetaHandle meta_handle; + ObMacroIdIterator id_iterator; + MacroBlockId macro_id; + + if (OB_FAIL(sstable.get_meta(meta_handle))) { + LOG_WARN("get meta handle fail", K(ret), K(sstable)); + } else if (OB_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_data_block_iter(id_iterator))) { + LOG_WARN("get id iterator fail", K(ret)); + } else if (OB_FAIL(id_iterator.get_next_macro_id(macro_id))) { + LOG_WARN("get first id fail", K(ret)); + } else { + read_info.macro_block_id_ = macro_id; + read_info.offset_ = sstable.get_macro_offset(); + read_info.size_ = upper_align(sstable.get_macro_read_size(), DIO_READ_ALIGN_SIZE); + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_READ); + } if (OB_FAIL(ObBlockManager::read_block(read_info, block_handle))) { LOG_WARN("fail to read block", K(ret), K(read_info)); } else if (OB_UNLIKELY(!block_handle.is_valid() - || macro_info.get_nested_size() != block_handle.get_data_size())) { + || sstable.get_macro_read_size() != block_handle.get_data_size())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("block handle is invalid", K(ret), K(block_handle)); } diff --git a/src/storage/blocksstable/ob_shared_macro_block_manager.h b/src/storage/blocksstable/ob_shared_macro_block_manager.h index caf61aa9d..37e278366 100644 --- a/src/storage/blocksstable/ob_shared_macro_block_manager.h +++ b/src/storage/blocksstable/ob_shared_macro_block_manager.h @@ -63,6 +63,7 @@ public: void stop(); void wait(); int64_t get_shared_block_cnt(); + void get_cur_shared_block(MacroBlockId ¯o_id); int write_block(const char* buf, const int64_t size, ObBlockInfo &block_info, ObMacroBlocksWriteCtx &write_ctx); int add_block(const MacroBlockId &block_id, const int64_t block_size); int free_block(const MacroBlockId &block_id, const int64_t block_size); @@ -137,12 +138,13 @@ private: ObSSTableIndexBuilder &sstable_index_builder, ObIndexBlockRebuilder &index_block_rebuilder); int rebuild_sstable( + common::ObArenaAllocator &allocator, const ObTablet &tablet, const ObSSTable &old_sstable, const uint64_t data_version, ObSSTableIndexBuilder &sstable_index_builder, ObIndexBlockRebuilder &index_block_rebuilder, - ObTableHandleV2 &table_handle); + ObSSTable &new_sstable); int prepare_data_desc( const ObTablet &tablet, const ObSSTableBasicMeta &basic_meta, @@ -158,11 +160,11 @@ private: const ObSSTable &sstable, ObMacroBlockHandle &block_handle); int create_new_sstable( + common::ObArenaAllocator &allocator, const ObSSTableMergeRes &res, - const ObTablet &tablet, const ObSSTable &old_table, const ObBlockInfo &block_info, - ObTableHandleV2 &table_handle) const; + ObSSTable &new_sstable) const; int parse_merge_type(const ObSSTable &sstable, ObMergeType &merge_type) const; int try_switch_macro_block(); int check_write_complete(const MacroBlockId ¯o_id, const int64_t macro_size); diff --git a/src/storage/blocksstable/ob_sstable.cpp b/src/storage/blocksstable/ob_sstable.cpp index 383ad2b07..ffb6aaef4 100644 --- a/src/storage/blocksstable/ob_sstable.cpp +++ b/src/storage/blocksstable/ob_sstable.cpp @@ -41,11 +41,35 @@ using namespace share; namespace blocksstable { +void ObSSTableMetaHandle::reset() +{ + handle_.reset(); + meta_ = nullptr; +} + +int ObSSTableMetaHandle::get_sstable_meta(const ObSSTableMeta *&sstable_meta) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(sstable_meta)) { + ret = OB_NOT_INIT; + LOG_WARN("sstable meta handle not inited", K(ret)); + } else { + sstable_meta = meta_; + } + return ret; +} + ObSSTable::ObSSTable() - : meta_(), + : addr_(), + upper_trans_version_(0), + max_merged_trans_version_(0), + data_macro_block_count_(0), + nested_size_(0), + nested_offset_(0), + contain_uncommitted_row_(false), valid_for_reading_(false), - hold_macro_ref_(false), - allocator_(nullptr) + is_tmp_sstable_(false), + meta_(nullptr) { #if defined(__x86_64__) static_assert(sizeof(ObSSTable) <= 1280, "The size of ObSSTable will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); @@ -57,9 +81,10 @@ ObSSTable::~ObSSTable() reset(); } -int ObSSTable::init(const ObTabletCreateSSTableParam ¶m, common::ObIAllocator *allocator) +int ObSSTable::init(const ObTabletCreateSSTableParam ¶m, common::ObArenaAllocator *allocator) { int ret = OB_SUCCESS; + bool inc_success = false; if (OB_UNLIKELY(valid_for_reading_)) { ret = OB_STATE_NOT_MATCH; LOG_WARN("this sstable can't be initialized", K(ret), K_(valid_for_reading)); @@ -68,19 +93,22 @@ int ObSSTable::init(const ObTabletCreateSSTableParam ¶m, common::ObIAllocato LOG_WARN("invalid argument", K(ret), K(param), KP(allocator)); } else if (OB_FAIL(ObITable::init(param.table_key_))) { LOG_WARN("fail to initialize ObITable", K(ret), "table_key", param.table_key_); - } else if (OB_FAIL(meta_.init(param, allocator))) { + } else if (OB_FAIL(init_sstable_meta(param, allocator))) { LOG_WARN("fail to initialize sstable meta", K(ret), K(param)); - } else if (OB_FAIL(add_macro_ref())) { - LOG_WARN("fail to add macro ref", K(ret)); - } else if (FALSE_IT(allocator_ = allocator)) { + } else if (FALSE_IT(addr_.set_mem_addr(0, sizeof(ObSSTable)))) { + } else if (OB_FAIL(inc_macro_ref(inc_success))) { + LOG_WARN("fail to add macro ref", K(ret), K(inc_success)); + } else if (FALSE_IT(meta_->macro_info_.dec_linked_block_ref_cnt())) { + } else if (FALSE_IT(is_tmp_sstable_ = true)) { } else if (param.is_ready_for_read_) { if (OB_FAIL(check_valid_for_reading())) { LOG_WARN("Failed to check state", K(ret)); } } - if (OB_UNLIKELY(!(SSTABLE_READY_FOR_READ == meta_.get_basic_meta().status_ - || SSTABLE_WRITE_BUILDING == meta_.get_basic_meta().status_))) { + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(!(SSTABLE_READY_FOR_READ == meta_->get_basic_meta().status_ + || SSTABLE_WRITE_BUILDING == meta_->get_basic_meta().status_))) { if (OB_SUCCESS == ret) { ret = OB_STATE_NOT_MATCH; } @@ -93,16 +121,24 @@ int ObSSTable::init(const ObTabletCreateSSTableParam ¶m, common::ObIAllocato void ObSSTable::reset() { - LOG_DEBUG("reset sstable.", KP(this), K(key_)); + FLOG_INFO("reset sstable.", KP(this), K(key_), K(is_tmp_sstable_)); // dec ref first, then reset sstable meta - if (hold_macro_ref_) { - dec_macro_ref(); - dec_used_size(); + if (is_tmp_sstable_) { + ObSSTable::dec_macro_ref(); } - meta_.reset(); + if (nullptr != meta_) { + meta_->reset(); + } + addr_.reset(); + upper_trans_version_ = 0; + max_merged_trans_version_ = 0; + data_macro_block_count_ = 0; + nested_size_ = 0; + nested_offset_ = 0; + contain_uncommitted_row_ = false; + meta_ = nullptr; valid_for_reading_ = false; - hold_macro_ref_ = false; - allocator_ = nullptr; + is_tmp_sstable_ = false; ObITable::reset(); } @@ -189,7 +225,7 @@ int ObSSTable::get( ObStoreRowIterator *row_getter = nullptr; if (is_multi_version_minor_sstable() && (context.is_multi_version_read(get_upper_trans_version()) - || meta_.contain_uncommitted_row())) { + || contain_uncommitted_row())) { ALLOCATE_TABLE_STORE_ROW_IETRATOR(context, ObSSTableMultiVersionRowGetter, row_getter); @@ -310,7 +346,7 @@ int ObSSTable::multi_get( ObStoreRowIterator *row_getter = nullptr; if (is_multi_version_minor_sstable() && (context.is_multi_version_read(get_upper_trans_version()) - || meta_.contain_uncommitted_row())) { + || contain_uncommitted_row())) { ALLOCATE_TABLE_STORE_ROW_IETRATOR(context, ObSSTableMultiVersionRowMultiGetter, row_getter); @@ -344,49 +380,31 @@ int ObSSTable::multi_get( return ret; } + int ObSSTable::exist( - ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &full_read_info, - const ObDatumRowkey &rowkey, + const ObTableIterParam ¶m, + ObTableAccessContext &context, + const blocksstable::ObDatumRowkey &rowkey, bool &is_exist, bool &has_found) { int ret = OB_SUCCESS; - ObArenaAllocator allocator(ObModIds::OB_STORE_ROW_EXISTER); if (OB_UNLIKELY(!is_valid())) { ret = OB_NOT_INIT; LOG_WARN("SSTable is not ready for accessing", K(ret), K_(valid_for_reading), K_(meta)); } else if (OB_UNLIKELY(!rowkey.is_valid() - || !ctx.is_valid() - || !full_read_info.is_valid_full_read_info())) { + || !param.is_valid() + || !context.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid arguments", K(ret), K(rowkey), K(ctx), K(full_read_info)); + LOG_WARN("Invalid arguments", K(ret), K(rowkey), K(param), K(context)); } else { - ObTableIterParam iter_param; - ObTableAccessContext access_context; - common::ObVersionRange trans_version_range; - common::ObQueryFlag query_flag; - - trans_version_range.base_version_ = 0; - trans_version_range.multi_version_start_ = 0; - trans_version_range.snapshot_version_ = EXIST_READ_SNAPSHOT_VERSION; - query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; - query_flag.read_latest_ = ObQueryFlag::OBSF_MASK_READ_LATEST; - iter_param.table_id_ = table_id; - iter_param.tablet_id_ = key_.tablet_id_; - iter_param.read_info_ = &full_read_info; - iter_param.full_read_info_ = &full_read_info; - const ObDatumRow *store_row = nullptr; ObStoreRowIterator *iter = nullptr; is_exist = false; has_found = false; - if (OB_FAIL(access_context.init(query_flag, ctx, allocator, trans_version_range))) { - LOG_WARN("Fail to init access context", K(ret), K_(key)); - } else if (OB_FAIL(build_exist_iterator(iter_param, rowkey, access_context, iter))) { + if (OB_FAIL(build_exist_iterator(param, rowkey, context, iter))) { LOG_WARN("Failed to build exist iterator", K(ret)); } else if (OB_FAIL(iter->get_next_row(store_row))) { if (OB_UNLIKELY(OB_ITER_END != ret)) { @@ -413,19 +431,20 @@ int ObSSTable::exist( } if (OB_NOT_NULL(iter)) { - ObTabletStat &stat = ctx.tablet_stat_; - stat.ls_id_ = ctx.ls_id_.id(); - stat.tablet_id_ = ctx.tablet_id_.id(); - stat.query_cnt_ = access_context.table_store_stat_.exist_row_.empty_read_cnt_ > 0; + ObTabletStat &stat = context.store_ctx_->tablet_stat_; + stat.ls_id_ = context.ls_id_.id(); + stat.tablet_id_ = context.tablet_id_.id(); + stat.query_cnt_ = context.table_store_stat_.exist_row_.empty_read_cnt_ > 0; iter->~ObStoreRowIterator(); - access_context.stmt_allocator_->free(iter); + context.stmt_allocator_->free(iter); } } return ret; } + int ObSSTable::exist(ObRowsInfo &rows_info, bool &is_exist, bool &all_rows_found) { int ret = OB_SUCCESS; @@ -433,21 +452,17 @@ int ObSSTable::exist(ObRowsInfo &rows_info, bool &is_exist, bool &all_rows_found is_exist = false; all_rows_found = false; const ObDatumRowkey *sstable_endkey = nullptr; - const ObTableReadInfo *index_read_info - = rows_info.exist_helper_.table_iter_param_.get_full_read_info()->get_index_read_info(); - if (OB_UNLIKELY(!rows_info.is_valid()) || OB_ISNULL(index_read_info)) { + if (OB_UNLIKELY(!rows_info.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid argument", K(ret), K(rows_info), KP(index_read_info)); + LOG_WARN("Invalid argument", K(ret), K(rows_info)); } else if (OB_UNLIKELY(rows_info.tablet_id_ != key_.tablet_id_)) { ret = OB_ERR_SYS; LOG_ERROR("Tablet id not match", K(ret), K_(key), K(rows_info)); - } else if (meta_.is_empty()) { + } else if (is_empty()) { // Skip } else if (rows_info.all_rows_found()) { all_rows_found = true; - } else if (OB_FAIL(get_last_rowkey( - *index_read_info, - sstable_endkey))) { + } else if (OB_FAIL(get_last_rowkey(sstable_endkey))) { LOG_WARN("Fail to get SSTable endkey", K(ret), K_(meta)); } else if (OB_ISNULL(sstable_endkey)) { ret = OB_ERR_UNEXPECTED; @@ -510,7 +525,7 @@ int ObSSTable::exist(ObRowsInfo &rows_info, bool &is_exist, bool &all_rows_found int ObSSTable::scan_macro_block( const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, ObIMacroBlockIterator *¯o_block_iter, const bool is_reverse_scan, @@ -545,7 +560,7 @@ int ObSSTable::scan_macro_block( if (OB_SUCC(ret)) { if (OB_FAIL(iter->open( - *this, range, index_read_info, allocator, is_reverse_scan, need_record_micro_info))) { + *this, range, rowkey_read_info, allocator, is_reverse_scan, need_record_micro_info))) { LOG_WARN("Fail to open macro block iter", K(ret)); } } @@ -565,7 +580,7 @@ int ObSSTable::scan_macro_block( int ObSSTable::scan_micro_block( const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, ObAllMicroBlockRangeIterator *µ_iter, const bool is_reverse_scan) @@ -582,7 +597,7 @@ int ObSSTable::scan_micro_block( } else if (OB_ISNULL(micro_iter = new (buf) ObAllMicroBlockRangeIterator)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Fail to construct micro block range iterator", K(ret)); - } else if (OB_FAIL(micro_iter->open(*this, range, index_read_info, allocator, is_reverse_scan))) { + } else if (OB_FAIL(micro_iter->open(*this, range, rowkey_read_info, allocator, is_reverse_scan))) { LOG_WARN("Fail to open micro block range iterator", K(ret)); } @@ -601,7 +616,7 @@ int ObSSTable::scan_micro_block( int ObSSTable::scan_secondary_meta( ObIAllocator &allocator, const ObDatumRange &query_range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, const blocksstable::ObMacroBlockMetaType meta_type, blocksstable::ObSSTableSecMetaIterator *&meta_iter, const bool is_reverse_scan, @@ -621,7 +636,7 @@ int ObSSTable::scan_secondary_meta( ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected null pointer of secondary meta iterator", K(ret)); } else if (OB_FAIL(iter->open( - query_range, meta_type, *this, index_read_info, allocator, is_reverse_scan, sample_step))) { + query_range, meta_type, *this, rowkey_read_info, allocator, is_reverse_scan, sample_step))) { LOG_WARN("Fail to open secondary meta iterator with range", K(ret), K(query_range), K(meta_type), K_(meta), K(is_reverse_scan), K(sample_step)); } else { @@ -657,30 +672,28 @@ int ObSSTable::bf_may_contain_rowkey(const ObDatumRowkey &rowkey, bool &contain) return ret; } -int ObSSTable::check_row_locked(ObStoreCtx &ctx, - const storage::ObTableReadInfo &full_read_info, - const ObDatumRowkey &rowkey, - ObStoreRowLockState &lock_state) + +int ObSSTable::check_row_locked( + const ObTableIterParam ¶m, + ObTableAccessContext &context, + const blocksstable::ObDatumRowkey &rowkey, + ObStoreRowLockState &lock_state) { int ret = OB_SUCCESS; void *buf = NULL; ObSSTableRowLockChecker *row_checker = NULL; - const int64_t read_snapshot = ctx.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(); ObArenaAllocator allocator(ObModIds::OB_STORE_ROW_LOCK_CHECKER); lock_state.trans_version_ = SCN::min_scn(); lock_state.is_locked_ = false; if (OB_UNLIKELY(!is_valid())) { ret = OB_NOT_INIT; - LOG_WARN("The SSTable has not been inited", K(ret), K_(valid_for_reading), K_(meta)); - } else if (OB_UNLIKELY(!full_read_info.is_valid_full_read_info())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid full read info", K(ret), K(full_read_info)); + LOG_WARN("The SSTable has not been inited", K(ret), K_(key), K_(valid_for_reading), KPC_(meta)); } else if (!is_multi_version_minor_sstable()) { // return false if not multi version minor sstable - } else if (get_upper_trans_version() <= read_snapshot) { + } else if (get_upper_trans_version() <= context.store_ctx_->mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx()) { // there is no lock at this sstable - if (!meta_.is_empty()) { + if (!is_empty()) { // skip reference upper_trans_version of empty_sstable, which may greater than real // committed transaction's version if (OB_FAIL(lock_state.trans_version_.convert_for_tx(get_upper_trans_version()))) { @@ -692,25 +705,9 @@ int ObSSTable::check_row_locked(ObStoreCtx &ctx, LOG_WARN("Fail to allocate memory", K(ret)); } else { row_checker = new (buf) ObSSTableRowLockChecker(); - ObTableIterParam iter_param; - ObTableAccessContext access_context; - common::ObVersionRange trans_version_range; - common::ObQueryFlag query_flag; - trans_version_range.base_version_ = 0; - trans_version_range.multi_version_start_ = 0; - trans_version_range.snapshot_version_ = read_snapshot; - query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; - iter_param.tablet_id_ = key_.tablet_id_; - iter_param.read_info_ = &full_read_info; - iter_param.full_read_info_ = &full_read_info; - - if (OB_FAIL(access_context.init(query_flag, ctx, allocator, - trans_version_range))) { - LOG_WARN("failed to init access context", K(ret), K(key_)); - } else if (OB_FAIL(row_checker->init(iter_param, access_context, this, &rowkey))) { - LOG_WARN("failed to open row locker", K(ret), K(iter_param), - K(access_context), K(rowkey)); + if (OB_FAIL(row_checker->init(param, context, this, &rowkey))) { + LOG_WARN("failed to open row locker", K(ret), K(param), K(context), K(rowkey)); } else if (OB_FAIL(row_checker->check_row_locked(lock_state))) { LOG_WARN("failed to check row lock checker"); } @@ -721,15 +718,31 @@ int ObSSTable::check_row_locked(ObStoreCtx &ctx, return ret; } + + int ObSSTable::set_upper_trans_version(const int64_t upper_trans_version) { int ret = OB_SUCCESS; - if (OB_FAIL(meta_.get_basic_meta().set_upper_trans_version( - MAX(upper_trans_version, get_max_merged_trans_version())))) { - LOG_WARN("fail to set upper trans version", K(ret), K(upper_trans_version), K(key_)); + + // only set once + if (INT64_MAX == upper_trans_version_ && INT64_MAX != upper_trans_version) { + const int64_t new_val = std::max(upper_trans_version, max_merged_trans_version_); + upper_trans_version_ = new_val; + } + + LOG_INFO("succeed to set upper trans version", K(key_), + K(upper_trans_version), K(upper_trans_version_)); + return ret; +} + +int ObSSTable::set_addr(const ObMetaDiskAddr &addr) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid meta disk address", K(ret), K(addr)); } else { - LOG_INFO("succeed to set upper trans version", K(key_), K(upper_trans_version), - K(meta_.get_basic_meta().upper_trans_version_)); + addr_ = addr; } return ret; } @@ -737,76 +750,26 @@ int ObSSTable::set_upper_trans_version(const int64_t upper_trans_version) int ObSSTable::get_frozen_schema_version(int64_t &schema_version) const { int ret = OB_SUCCESS; + ObSSTableMetaHandle meta_handle; if (OB_UNLIKELY(!is_valid())) { ret = OB_NOT_INIT; LOG_WARN("sstable is not initialized.", K(ret), K_(valid_for_reading), K_(meta)); + } else if (OB_FAIL(get_meta(meta_handle))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); } else { - schema_version = meta_.get_basic_meta().schema_version_; - } - return ret; -} - -int ObSSTable::set_status_for_read(const ObSSTableStatus status) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(SSTABLE_WRITE_BUILDING != meta_.get_basic_meta().status_)) { - ret = OB_STATE_NOT_MATCH; - LOG_WARN("sstable state is not match.", K(ret), K_(meta_.get_basic_meta().status)); - } else if (OB_UNLIKELY(SSTABLE_READY_FOR_READ != status - && SSTABLE_READY_FOR_REMOTE_PHYTSICAL_READ != status - && SSTABLE_READY_FOR_REMOTE_LOGICAL_READ != status)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(status)); - } else if (OB_FAIL(meta_.load_root_block_data())) { - LOG_WARN("fail to load root block data", K(ret)); - } else { - meta_.get_basic_meta().status_ = status; - if (OB_FAIL(check_valid_for_reading())) { - LOG_WARN("Failed to check state", K(ret)); - } - - if (OB_FAIL(ret)) { - meta_.get_basic_meta().status_ = SSTABLE_WRITE_BUILDING; - } + schema_version = meta_handle.get_sstable_meta().get_schema_version(); } return ret; } int ObSSTable::get_last_rowkey( - const ObTableReadInfo &index_read_info, - ObIAllocator &allocator, - ObStoreRowkey &endkey) -{ - int ret = OB_SUCCESS; - const ObDatumRowkey *datum_rowkey; - - if (OB_UNLIKELY(!index_read_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "Invalid index read info", K(ret), K(index_read_info)); - } else if (OB_FAIL(get_last_rowkey(index_read_info, datum_rowkey))) { - STORAGE_LOG(WARN, "Failed to get datum rowkey", K(ret)); - } else if (OB_ISNULL(datum_rowkey)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "Unexpected null datum rowkey", K(ret)); - } else { - const ObIArray &col_descs = index_read_info.get_columns_desc(); - if (OB_FAIL(datum_rowkey->to_store_rowkey(col_descs, allocator, endkey))) { - STORAGE_LOG(WARN, "Failed to transfer store rowkey", K(ret), KPC(datum_rowkey), K(col_descs)); - } - } - - return ret; -} - -int ObSSTable::get_last_rowkey( - const ObTableReadInfo &index_read_info, ObIAllocator &allocator, ObDatumRowkey &endkey) { int ret = OB_SUCCESS; const ObDatumRowkey *last_rowkey; - if (OB_FAIL(get_last_rowkey(index_read_info, last_rowkey))) { + if (OB_FAIL(get_last_rowkey(last_rowkey))) { STORAGE_LOG(WARN, "Failed to get datum rowkey", K(ret)); } else if (OB_ISNULL(last_rowkey)) { ret = OB_ERR_UNEXPECTED; @@ -818,17 +781,69 @@ int ObSSTable::get_last_rowkey( return ret; } +int ObSSTable::deep_copy(ObArenaAllocator &allocator, ObSSTable *&dst) const +{ + int ret = OB_SUCCESS; + const int64_t deep_copy_size = get_deep_copy_size(); + char *buf = nullptr; + ObIStorageMetaObj *meta_obj = nullptr; + if (OB_ISNULL(buf = static_cast(allocator.alloc(deep_copy_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for deep copy sstable", K(ret), K(deep_copy_size)); + } else if (OB_FAIL(deep_copy(buf, deep_copy_size, meta_obj))) { + LOG_WARN("fail to inner deep copy sstable", K(ret)); + } else { + dst = static_cast(meta_obj); + } + return ret; +} + +int ObSSTable::deep_copy(char *buf, const int64_t buf_len, ObIStorageMetaObj *&value) const +{ + int ret = OB_SUCCESS; + value = nullptr; + const int64_t deep_copy_size = get_deep_copy_size(); + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len < deep_copy_size)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(buf), K(buf_len), K(deep_copy_size)); + } else { + ObSSTable *pvalue = new (buf) ObSSTable(); + int64_t pos = sizeof(ObSSTable); + pvalue->key_ = key_; + pvalue->addr_ = addr_; + pvalue->upper_trans_version_ = upper_trans_version_; + pvalue->max_merged_trans_version_ = max_merged_trans_version_; + pvalue->data_macro_block_count_ = data_macro_block_count_; + pvalue->nested_size_ = nested_size_; + pvalue->nested_offset_ = nested_offset_; + pvalue->contain_uncommitted_row_ = contain_uncommitted_row_; + pvalue->is_tmp_sstable_ = false; + pvalue->valid_for_reading_ = valid_for_reading_; + if (is_loaded()) { + if (OB_FAIL(meta_->deep_copy(buf, buf_len, pos, pvalue->meta_))) { + LOG_WARN("fail to deep copy for tiny memory", K(ret), KP(buf), K(buf_len), K(pos), KPC(meta_)); + } + } + if (OB_SUCC(ret)) { + value = static_cast(pvalue); + LOG_DEBUG("succeed to deep copy sstable", K(ret), K(deep_copy_size), K(buf_len), K(pos), KPC(pvalue), KPC(this)); + } + } + return ret; +} + int ObSSTable::check_valid_for_reading() { int ret = OB_SUCCESS; valid_for_reading_ = key_.is_valid() - && meta_.is_valid() - && (SSTABLE_READY_FOR_READ == meta_.get_basic_meta().status_ - || SSTABLE_READY_FOR_REMOTE_PHYTSICAL_READ == meta_.get_basic_meta().status_ - || SSTABLE_READY_FOR_REMOTE_LOGICAL_READ == meta_.get_basic_meta().status_); + && nullptr != meta_ + && meta_->is_valid() + && (SSTABLE_READY_FOR_READ == meta_->get_basic_meta().status_ + || SSTABLE_READY_FOR_REMOTE_PHYTSICAL_READ == meta_->get_basic_meta().status_ + || SSTABLE_READY_FOR_REMOTE_LOGICAL_READ == meta_->get_basic_meta().status_); if (OB_UNLIKELY(!valid_for_reading_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("Unexpected state state", K(ret), K_(valid_for_reading), K(key_), K(meta_)); + LOG_WARN("Unexpected state state", K(ret), K_(valid_for_reading), K(key_), KPC(meta_)); } return ret; } @@ -836,327 +851,534 @@ int ObSSTable::check_valid_for_reading() int ObSSTable::serialize(char *buf, const int64_t buf_len, int64_t &pos) const { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_valid()) && SSTABLE_WRITE_BUILDING != meta_.get_basic_meta().status_) { + ObSSTableMetaHandle meta_handle; + if (OB_FAIL(get_meta(meta_handle))) { + LOG_WARN("fail to get sstable meta", K(ret)); + } else if (OB_UNLIKELY(!is_valid() + && SSTABLE_WRITE_BUILDING != meta_handle.get_sstable_meta().get_status())) { ret = OB_STATE_NOT_MATCH; - LOG_WARN("non-ready sstable for read can't be serialized.", K(ret), K_(valid_for_reading), K_(meta)); + LOG_WARN("non-ready sstable for read can't be serialized.", K(ret), K_(valid_for_reading), K(meta_handle)); } else if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("argument is invalid", K(ret), KP(buf), K(buf_len)); + } else if (OB_UNLIKELY(!addr_.is_valid() || (!addr_.is_memory() && !addr_.is_block()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sstable's addr_ is invalid", K(ret), K(addr_)); } else if (OB_FAIL(ObITable::serialize(buf, buf_len, pos))) { LOG_WARN("fail to serialize table key", K(ret), K(buf_len), K(pos)); - } else if (OB_FAIL(meta_.serialize(buf, buf_len, pos))) { - LOG_WARN("sstable meta fail to serialize.", K(ret), K(buf_len), K(pos)); } else { - LOG_DEBUG("succeed to serialize sstable", KPC(this)); + ObSSTable::StatusForSerialize status; + if (!addr_.is_memory()) { + status.set_with_fixed_struct(); + } else { + status.set_with_meta(); + } + OB_UNIS_ENCODE(status.pack_); + if (OB_FAIL(ret)) { + } else if (status.with_fixed_struct() && OB_FAIL(serialize_fixed_struct(buf, buf_len, pos))) { + LOG_WARN("fail to serialize fix sstable struct", K(ret), K(buf_len), K(pos)); + } else if (status.with_meta() && OB_FAIL(meta_->serialize(buf, buf_len, pos))) { + LOG_WARN("fail to serialize sstable meta", K(ret), K(buf_len), K(pos)); + } else { + LOG_INFO("succeed to serialize sstable", K(status.pack_), KPC(this)); + } } return ret; } -int ObSSTable::deserialize(common::ObIAllocator &allocator, +int ObSSTable::deserialize(common::ObArenaAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos) { int ret = OB_SUCCESS; - int64_t new_pos = pos; - if (OB_UNLIKELY(SSTABLE_NOT_INIT != meta_.get_basic_meta().status_)) { - ret = OB_STATE_NOT_MATCH; - LOG_WARN("this sstable can't be deserialized", K(ret), K_(meta_.get_basic_meta().status)); - } else if (OB_ISNULL(buf) || OB_UNLIKELY(data_len <= 0)) { + ObSSTable::StatusForSerialize status; + int64_t orig_pos = pos; + char *meta_buf = nullptr; + if (OB_ISNULL(buf) || OB_UNLIKELY(data_len <= 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("argument is invalid", K(ret), KP(buf), K(data_len)); - } else if (FALSE_IT(allocator_ = &allocator)) { - } else if (OB_FAIL(ObITable::deserialize(buf, data_len, new_pos))) { - LOG_WARN("failed to deserialize ObITable", K(ret), K(data_len), K(new_pos)); - } else if (OB_FAIL(meta_.deserialize(allocator_, buf, data_len, new_pos))) { - LOG_WARN("fail to deserialize sstable meta", K(ret), K(key_), K(data_len), K(new_pos)); - } else if (OB_UNLIKELY(!meta_.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sstable meta is not valid", K(ret), K_(meta)); + } else if (OB_FAIL(ObITable::deserialize(buf, data_len, pos))) { + LOG_WARN("failed to deserialize ObITable", K(ret), K(data_len), K(pos)); } else { - pos = new_pos; - LOG_DEBUG("succeed to deserialize sstable", KPC(this)); + // TODO: delete temporary compat here + int64_t compat_temp_pos = pos; + OB_UNIS_DECODE(status.pack_); + if (StatusForSerialize::COMPAT_MAGIC == status.compat_magic_ && 0 == status.reserved_) { + // serialized with new binary + } else { + // serialized with old binary, always deserialize sstable meta + pos = compat_temp_pos; + status.reset(); + status.set_with_meta(); + } + if (status.with_fixed_struct() && OB_FAIL(deserialize_fixed_struct(buf, data_len, pos))) { + LOG_WARN("failed to deserialize sstable object struct", K(ret)); + } else if (status.with_meta()) { + addr_.set_mem_addr(0, sizeof(ObSSTable)); + if (OB_ISNULL(meta_buf = static_cast(allocator.alloc(sizeof(ObSSTableMeta))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret)); + } else if (FALSE_IT(meta_ = new (meta_buf) ObSSTableMeta())) { + } else if (OB_FAIL(meta_->deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("fail to deserialize sstable meta", K(ret), K(key_), K(data_len), K(pos)); + } else if (OB_UNLIKELY(!meta_->is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sstable meta is not valid", K(ret), K_(meta)); + } else if (OB_FAIL(meta_->transform_root_block_data(allocator))) { + LOG_WARN("fail to transform root block data", K(ret)); + } else if (OB_FAIL(check_valid_for_reading())) { + LOG_WARN("fail to check valid for reading", K(ret)); + } else { + // for compat, remove later + upper_trans_version_ = meta_->get_upper_trans_version(); + max_merged_trans_version_ = meta_->get_max_merged_trans_version(); + data_macro_block_count_ = meta_->get_data_macro_block_count(); + contain_uncommitted_row_ = meta_->contain_uncommitted_row(); + nested_size_ = meta_->get_macro_info().get_nested_size(); + nested_offset_ = meta_->get_macro_info().get_nested_offset(); + } + } else { + valid_for_reading_ = key_.is_valid(); + } } - if (OB_FAIL(ret)) { - LOG_WARN("fail to deserialize sstable", K(ret), K(*this)); - reset(); - } - return ret; -} -int ObSSTable::deserialize_post_work() -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(hold_macro_ref_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("post work may be done", K(ret), KPC(this)); - } else if (OB_FAIL(add_macro_ref())) { - LOG_WARN("fail to add macro ref", K(ret)); - } else if (SSTABLE_WRITE_BUILDING != meta_.get_basic_meta().status_ && OB_FAIL(check_valid_for_reading())) { - LOG_WARN("fail to check state", K(ret)); + if (OB_SUCC(ret)) { + FLOG_INFO("succeed to deserialize sstable", K(status.pack_), KPC(this)); } else { - LOG_DEBUG("succeed to do post work for sstable deserialize", KPC(this)); + pos = orig_pos; + LOG_WARN("fail to deserialize sstable", K(ret), K(status.pack_), KPC(this)); + reset(); } return ret; } int64_t ObSSTable::get_serialize_size() const { - return ObITable::get_serialize_size() + meta_.get_serialize_size(); + int ret = OB_SUCCESS; + int64_t len = 0; // invalid + int64_t sstable_meta_serialize_size = 0; + int64_t fixed_struct_serialize_size = 0; + ObSSTable::StatusForSerialize status; + if (OB_UNLIKELY(!addr_.is_valid() || (!addr_.is_memory() && !addr_.is_block()))) { + len = -1; + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("sstable's addr_ is invalid", K(ret), K(addr_), KPC(this)); + } else if (!addr_.is_memory()) { + status.set_with_fixed_struct(); + fixed_struct_serialize_size = get_sstable_fix_serialize_size(); + } else { + status.set_with_meta(); + sstable_meta_serialize_size = meta_->get_serialize_size(); + } + if (OB_SUCC(ret)) { + OB_UNIS_ADD_LEN(status.pack_); + len += ObITable::get_serialize_size() + fixed_struct_serialize_size + sstable_meta_serialize_size; + } + return len; +} +int64_t ObSSTable::get_sstable_fix_serialize_payload_size() const +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, + addr_, + upper_trans_version_, + max_merged_trans_version_, + data_macro_block_count_, + nested_size_, + nested_offset_, + contain_uncommitted_row_); + return len; } -void ObSSTable::dec_macro_ref() +int64_t ObSSTable::get_sstable_fix_serialize_size() const +{ + int64_t len = 0; + int64_t payload_size = get_sstable_fix_serialize_payload_size(); + LST_DO_CODE(OB_UNIS_ADD_LEN, + SSTABLE_VERSION, + payload_size); + len += payload_size; + return len; +} + +int ObSSTable::serialize_fixed_struct(char *buf, const int64_t buf_len, int64_t &pos) const { int ret = OB_SUCCESS; - int64_t idx = 0; - for (; idx < meta_.get_macro_info().get_data_block_ids().count(); ++idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.get_macro_info().get_data_block_ids().at(idx); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { - LOG_ERROR("fail to dec data block ref cnt", K(ret), K(macro_id), K(idx)); + const int64_t len = get_sstable_fix_serialize_payload_size(); + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len < 0 || pos + len > buf_len)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(buf_len), K(len)); + } else { + LST_DO_CODE(OB_UNIS_ENCODE, + SSTABLE_VERSION, + len, + addr_, + upper_trans_version_, + max_merged_trans_version_, + data_macro_block_count_, + nested_size_, + nested_offset_, + contain_uncommitted_row_); + } + return ret; +} + +int ObSSTable::deserialize_fixed_struct(const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(data_len < 0 || data_len < pos)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret)); + } else { + int64_t len = 0; + int64_t version = 0; + OB_UNIS_DECODE(version); + OB_UNIS_DECODE(len); + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(version != SSTABLE_VERSION)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("sstable version not match", K(ret), K(version)); + } else if (OB_UNLIKELY(pos + len > data_len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("semi deserialize buffer not enough", K(ret), K(pos), K(len), K(data_len)); + } else { + LST_DO_CODE(OB_UNIS_DECODE, + addr_, + upper_trans_version_, + max_merged_trans_version_, + data_macro_block_count_, + nested_size_, + nested_offset_, + contain_uncommitted_row_); + if (OB_SUCC(ret)) { + valid_for_reading_ = key_.is_valid(); + } } } - for (idx = 0; idx < meta_.get_macro_info().get_other_block_ids().count(); ++idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.get_macro_info().get_other_block_ids().at(idx); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { - LOG_ERROR("fail to dec other block ref cnt", K(ret), K(macro_id), K(idx)); + return ret; +} + +int ObSSTable::assign_meta(ObSSTableMeta *meta) { + int ret = OB_SUCCESS; + if (OB_ISNULL(meta) || OB_UNLIKELY(!meta->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KPC(meta)); + } else if (OB_NOT_NULL(meta_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sstable meta already assigned", K(ret), KPC(this), KPC(meta)); + } else { + meta_ = meta; + if (OB_FAIL(check_valid_for_reading())) { + LOG_WARN("fail to check valid for reading", K(ret), KPC(this)); } } - for (idx = 0; idx < meta_.get_macro_info().get_linked_block_ids().count(); ++idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.get_macro_info().get_linked_block_ids().at(idx); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { - LOG_ERROR("fail to dec link block ref cnt", K(ret), K(macro_id), K(idx)); + return ret; +} + +void ObSSTable::inc_ref() +{ + if (is_tmp_sstable_) { + ObITable::inc_ref(); + } +} + +int64_t ObSSTable::dec_ref() +{ + int64_t cnt = -1; + if (is_tmp_sstable_) { + cnt = ObITable::dec_ref(); + } + return cnt; +} + +int64_t ObSSTable::get_ref() const +{ + int64_t cnt = 0; + if (is_tmp_sstable_) { + cnt = ObITable::get_ref(); + } + return cnt; +} + +void ObSSTable::dec_macro_ref() const +{ + int ret = OB_SUCCESS; + MacroBlockId macro_id; + ObMacroIdIterator iterator; + common::ObArenaAllocator tmp_allocator("CacheSST"); + ObSafeArenaAllocator safe_allocator(tmp_allocator); + ObSSTableMetaHandle meta_handle; + if (OB_FAIL(get_meta(meta_handle, &safe_allocator))) { + LOG_ERROR("fail to get sstable meta", K(ret)); + } else if (OB_UNLIKELY(!meta_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("meta handle is invalid", K(ret), K(meta_handle)); + } else { + if (OB_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_data_block_iter(iterator))) { + LOG_ERROR("fail to get data block iterator", K(ret), KPC(this)); + } else { + while (OB_SUCC(iterator.get_next_macro_id(macro_id))) { + if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to dec data block ref cnt", K(ret), K(macro_id)); + } else { + LOG_DEBUG("barry debug decrease data ref cnt", K(macro_id), KPC(this), K(lbt())); + } + } + } + iterator.reset(); + if (OB_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_other_block_iter(iterator))) { // ignore ret + LOG_ERROR("fail to get other block iterator", K(ret), KPC(this)); + } else { + while (OB_SUCC(iterator.get_next_macro_id(macro_id))) { + if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to dec other block ref cnt", K(ret), K(macro_id)); + } else { + LOG_DEBUG("barry debug decrease other ref cnt", K(macro_id), KPC(this), K(lbt())); + } + } + } + iterator.reset(); + if (OB_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_linked_block_iter(iterator))) { + LOG_ERROR("fail to get linked block iterator", K(ret), KPC(this)); + } else { + while (OB_SUCC(iterator.get_next_macro_id(macro_id))) { + if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to dec other block ref cnt", K(ret), K(macro_id)); + } else { + LOG_DEBUG("barry debug decrease link ref cnt", K(macro_id), KPC(this), K(lbt())); + } + } } } + if (OB_FAIL(dec_used_size())) {// ignore ret LOG_ERROR("fail to dec used size of shared block", K(ret)); } - hold_macro_ref_ = false; } -int ObSSTable::add_macro_ref() +int ObSSTable::inc_macro_ref(bool &inc_success) const { int ret = OB_SUCCESS; - int64_t i = 0; - int64_t j = 0; - int64_t k = 0; - while (OB_SUCC(ret) && i < meta_.get_macro_info().get_data_block_ids().count()) { - const MacroBlockId ¯o_id = meta_.get_macro_info().get_data_block_ids().at(i); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(macro_id))) { - LOG_ERROR("fail to inc data block ref cnt", K(ret), K(macro_id), K(i)); - } else { - ++i; - } - } - while (OB_SUCC(ret) && j < meta_.get_macro_info().get_other_block_ids().count()) { - const MacroBlockId ¯o_id = meta_.get_macro_info().get_other_block_ids().at(j); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(macro_id))) { - LOG_ERROR("fail to inc other block ref cnt", K(ret), K(macro_id), K(j)); - } else { - ++j; - } - } - while (OB_SUCC(ret) && k < meta_.get_macro_info().get_linked_block_ids().count()) { - const MacroBlockId ¯o_id = meta_.get_macro_info().get_linked_block_ids().at(k); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(macro_id))) { - LOG_ERROR("fail to inc link block ref cnt", K(ret), K(macro_id), K(k)); - } else { - ++k; - } - } - if (OB_SUCC(ret) && OB_FAIL(add_used_size())) { - LOG_ERROR("fail to add used size", K(ret)); - } - if (OB_FAIL(ret)) { - int tmp_ret = OB_SUCCESS; - int64_t idx = i - 1; - for (; idx >= 0; --idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.get_macro_info().get_data_block_ids().at(idx); - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = OB_SERVER_BLOCK_MGR.dec_ref(macro_id)))) { - LOG_ERROR("fail to dec data block ref cnt", K(ret), K(tmp_ret), K(macro_id)); - } - } - idx = j - 1; - for (; idx >= 0; --idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.get_macro_info().get_other_block_ids().at(idx); - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = OB_SERVER_BLOCK_MGR.dec_ref(macro_id)))) { - LOG_ERROR("fail to dec other block ref cnt", K(ret), K(tmp_ret), K(macro_id)); - } - } - idx = k - 1; - for (; idx >= 0; --idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.get_macro_info().get_linked_block_ids().at(idx); - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = OB_SERVER_BLOCK_MGR.dec_ref(macro_id)))) { - LOG_ERROR("fail to dec link block ref cnt", K(ret), K(tmp_ret), K(macro_id)); + inc_success = false; + MacroBlockId macro_id; + ObMacroIdIterator iter; + int64_t data_blk_cnt = 0; + int64_t other_blk_cnt = 0; + int64_t linked_blk_cnt = 0; + common::ObArenaAllocator tmp_allocator("CacheSST"); + ObSafeArenaAllocator safe_allocator(tmp_allocator); + ObSSTableMetaHandle meta_handle; + if (OB_FAIL(get_meta(meta_handle, &safe_allocator))) { + LOG_WARN("fail to get sstable meta", K(ret)); + } else if (OB_UNLIKELY(!meta_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("meta handle is invalid", K(ret), K(meta_handle)); + } else if (OB_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_data_block_iter(iter))) { + LOG_WARN("fail to get data block iterator", K(ret), KPC(this)); + } else if (OB_UNLIKELY(!iter.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the iter is invalid", K(ret), K(iter)); + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.get_next_macro_id(macro_id))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next macro id", K(ret), K(macro_id)); + } + } else if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(macro_id))) { + LOG_ERROR("fail to inc data block ref cnt", K(ret), K(macro_id)); + } else { + ++data_blk_cnt; } + LOG_DEBUG("barry debug increase data ref cnt", K(ret), K(macro_id), KPC(this), K(lbt())); } + iter.reset(); } + + if (OB_FAIL(ret) && OB_ITER_END != ret) { + } else if (OB_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_other_block_iter(iter))) { + LOG_WARN("fail to get other block iterator", K(ret), KPC(this)); + } else if (OB_UNLIKELY(!iter.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the iter is invalid", K(ret), K(iter)); + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.get_next_macro_id(macro_id))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next macro id", K(ret), K(macro_id)); + } + } else if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(macro_id))) { + LOG_ERROR("fail to inc other block ref cnt", K(ret), K(macro_id)); + } else { + ++other_blk_cnt; + } + LOG_DEBUG("barry debug increase other ref cnt", K(ret), K(macro_id), KPC(this), K(lbt())); + } + iter.reset(); + } + + if (OB_FAIL(ret) && OB_ITER_END != ret) { + } else if (OB_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_linked_block_iter(iter))) { + LOG_WARN("fail to get linked block iterator", K(ret), KPC(this)); + } else if (OB_UNLIKELY(!iter.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the iter is invalid", K(ret), K(iter)); + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.get_next_macro_id(macro_id))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next macro id", K(ret), K(macro_id)); + } + } else if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(macro_id))) { + LOG_ERROR("fail to inc linked block ref cnt", K(ret), K(macro_id)); + } else { + ++linked_blk_cnt; + } + LOG_DEBUG("barry debug increase link ref cnt", K(ret), K(macro_id), KPC(this), K(lbt())); + } + iter.reset(); + } + + if ((OB_SUCC(ret) || OB_LIKELY(OB_ITER_END == ret)) && OB_FAIL(add_used_size())) { + LOG_WARN("fail to add used size", K(ret)); + } + if (OB_SUCC(ret)) { - hold_macro_ref_ = true; - } - return ret; -} - -int ObSSTable::add_disk_ref() -{ - int ret = OB_SUCCESS; - int64_t i = 0; - int64_t j = 0; - int64_t k = 0; - while (OB_SUCC(ret) && i < meta_.get_macro_info().get_data_block_ids().count()) { - const MacroBlockId ¯o_id = meta_.get_macro_info().get_data_block_ids().at(i); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_disk_ref(macro_id))) { - LOG_ERROR("fail to inc data block disk ref cnt", K(ret), K(macro_id), K(i)); - } else { - ++i; - } - } - while (OB_SUCC(ret) && j < meta_.get_macro_info().get_other_block_ids().count()) { - const MacroBlockId ¯o_id = meta_.get_macro_info().get_other_block_ids().at(j); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_disk_ref(macro_id))) { - LOG_ERROR("fail to inc other block disk ref cnt", K(ret), K(macro_id), K(j)); - } else { - ++j; - } - } - while (OB_SUCC(ret) && k < meta_.get_macro_info().get_linked_block_ids().count()) { - const MacroBlockId ¯o_id = meta_.get_macro_info().get_linked_block_ids().at(k); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_disk_ref(macro_id))) { - LOG_ERROR("fail to inc linked block disk ref cnt", K(ret), K(k), K(macro_id)); - } else { - ++k; - } - } - if (OB_SUCC(ret) && OB_FAIL(add_used_size())) { - LOG_ERROR("fail to add used size", K(ret)); - } - if (OB_FAIL(ret)) { + inc_success = true; + } else if (meta_handle.is_valid()) { int tmp_ret = OB_SUCCESS; - int64_t idx = i - 1; - for (; idx >= 0; --idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.get_macro_info().get_data_block_ids().at(idx); - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = OB_SERVER_BLOCK_MGR.dec_disk_ref(macro_id)))) { - LOG_ERROR("fail to dec data block disk ref cnt", K(ret), K(tmp_ret), K(macro_id)); + if (OB_TMP_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_data_block_iter(iter))) { + LOG_ERROR("fail to get data block iterator", K(ret), KPC(this)); + } else { + for (int64_t i = data_blk_cnt; i > 0; --i) { // ignore ret + if (OB_TMP_FAIL(iter.get_next_macro_id(macro_id))) { + LOG_ERROR("fail to get next macro id", K(ret), K(iter)); + } else if (OB_TMP_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to dec data block ref cnt", K(ret), K(tmp_ret), K(macro_id)); + } else { + LOG_DEBUG("barry debug decrease data ref cnt", K(macro_id), KPC(this), K(lbt())); + } } + iter.reset(); } - idx = j - 1; - for (; idx >= 0; --idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.get_macro_info().get_other_block_ids().at(idx); - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = OB_SERVER_BLOCK_MGR.dec_disk_ref(macro_id)))) { - LOG_ERROR("fail to dec other block disk ref cnt", K(ret), K(tmp_ret), K(macro_id)); + if (OB_TMP_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_other_block_iter(iter))) { // ignore ret + LOG_ERROR("fail to get other block iterator", K(ret), KPC(this)); + } else { + for (int64_t i = other_blk_cnt; i > 0; --i) { // ignore ret + if (OB_TMP_FAIL(iter.get_next_macro_id(macro_id))) { + LOG_ERROR("fail to get next macro id", K(ret), K(iter)); + } else if (OB_TMP_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to dec other block ref cnt", K(ret), K(tmp_ret), K(macro_id)); + } else { + LOG_DEBUG("barry debug decrease other ref cnt", K(macro_id), KPC(this), K(lbt())); + } } + iter.reset(); } - idx = k - 1; - for (; idx >= 0; --idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.get_macro_info().get_linked_block_ids().at(idx); - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = OB_SERVER_BLOCK_MGR.dec_disk_ref(macro_id)))) { - LOG_ERROR("fail to dec linked block disk ref cnt", K(ret), K(tmp_ret), K(macro_id)); + if (OB_TMP_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_linked_block_iter(iter))) { + LOG_ERROR("fail to get linked block iterator", K(ret), KPC(this)); + } else { + for (int64_t i = linked_blk_cnt; i > 0; --i) { + if (OB_TMP_FAIL(iter.get_next_macro_id(macro_id))) { + LOG_ERROR("fail to get next macro id", K(ret), K(iter)); + } else if (OB_TMP_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to dec linked block ref cnt", K(ret), K(tmp_ret), K(macro_id)); + } else { + LOG_DEBUG("barry debug decrease link ref cnt", K(macro_id), KPC(this), K(lbt())); + } } + iter.reset(); } } + return ret; } -int ObSSTable::dec_disk_ref() +int ObSSTable::add_used_size() const { int ret = OB_SUCCESS; - int64_t i = 0; - int64_t j = 0; - int64_t k = 0; - while (OB_SUCC(ret) && i < meta_.macro_info_.data_block_ids_.count()) { - MacroBlockId ¯o_id = meta_.macro_info_.data_block_ids_.at(i); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_disk_ref(macro_id))) { - LOG_ERROR("fail to dec data block disk ref cnt", K(ret), K(macro_id), K(i)); - } else { - ++i; - } - } - while (OB_SUCC(ret) && j < meta_.macro_info_.other_block_ids_.count()) { - MacroBlockId ¯o_id = meta_.macro_info_.other_block_ids_.at(j); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_disk_ref(macro_id))) { - LOG_ERROR("fail to dec other block disk ref cnt", K(ret), K(macro_id), K(j)); - } else { - ++j; - } - } - while (OB_SUCC(ret) && k < meta_.macro_info_.linked_block_ids_.count()) { - MacroBlockId ¯o_id = meta_.macro_info_.linked_block_ids_.at(k); - if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_disk_ref(macro_id))) { - LOG_ERROR("fail to dec linked block disk ref cnt", K(ret), K(macro_id), K(k)); - } else { - ++k; - } - } - if (OB_SUCC(ret) && OB_FAIL(dec_used_size())) { - LOG_ERROR("fail to dec used size of shared block", K(ret)); - } - if (OB_FAIL(ret)) { - int tmp_ret = OB_SUCCESS; - int64_t idx = i - 1; - for (; idx >= 0; --idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.macro_info_.data_block_ids_.at(idx); - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = OB_SERVER_BLOCK_MGR.inc_disk_ref(macro_id)))) { - LOG_ERROR("fail to inc data block disk ref cnt", K(ret), K(tmp_ret), K(macro_id)); - } - } - idx = j - 1; - for (; idx >= 0; --idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.macro_info_.other_block_ids_.at(idx); - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = OB_SERVER_BLOCK_MGR.inc_disk_ref(macro_id)))) { - LOG_ERROR("fail to inc other block disk ref cnt", K(ret), K(tmp_ret), K(macro_id)); - } - } - idx = k - 1; - for (; idx >= 0; --idx) {// ignore ret - const MacroBlockId ¯o_id = meta_.macro_info_.linked_block_ids_.at(idx); - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = OB_SERVER_BLOCK_MGR.inc_disk_ref(macro_id)))) { - LOG_ERROR("fail to inc other block disk ref cnt", K(ret), K(tmp_ret), K(macro_id)); - } - } - } - return ret; -} + ObSSTableMetaHandle meta_handle; + ObMacroIdIterator id_iterator; + MacroBlockId macro_id; + ObSharedMacroBlockMgr *shared_block_mgr = MTL(ObSharedMacroBlockMgr*); -int ObSSTable::add_used_size() -{ - int ret = OB_SUCCESS; - if (is_small_sstable()) { - const ObSSTableMacroInfo ¯o_info = meta_.get_macro_info(); - const ObIArray &data_block_ids = macro_info.get_data_block_ids(); - ObSharedMacroBlockMgr *shared_block_mgr = MTL(ObSharedMacroBlockMgr*); - if (data_block_ids.count() == 0) { // skip - } else if (data_block_ids.count() != 1) { + if (OB_FAIL(get_meta(meta_handle))) { + LOG_WARN("get meta handle fail", K(ret), KPC(this)); + } else if (is_small_sstable()) { + const int64_t data_block_count = get_data_macro_block_count(); + if (data_block_count == 0) { // skip + } else if (data_block_count != 1) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected data block ids", K(ret), K(macro_info)); - } else if (OB_FAIL(shared_block_mgr->add_block( - data_block_ids.at(0), meta_.get_macro_info().get_nested_size()))) { - LOG_WARN("fail to add used size of shared block", K(ret), K_(meta)); + LOG_WARN("unexpected data block ids", K(ret), K(data_block_count)); + } else if (OB_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_data_block_iter(id_iterator))) { + LOG_WARN("get id iterator fail", K(ret)); + } else if (OB_FAIL(id_iterator.get_next_macro_id(macro_id))) { + LOG_WARN("get first id fail", K(ret)); + } else if (OB_FAIL(shared_block_mgr->add_block(macro_id, get_macro_read_size()))) { + LOG_WARN("fail to add used size of shared block", K(ret)); } } return ret; } -int ObSSTable::dec_used_size() +int ObSSTable::dec_used_size() const { int ret = OB_SUCCESS; - if (is_small_sstable()) { - const ObSSTableMacroInfo ¯o_info = meta_.get_macro_info(); - const ObIArray &data_block_ids = macro_info.get_data_block_ids(); - ObSharedMacroBlockMgr *shared_block_mgr = MTL(ObSharedMacroBlockMgr*); - if (data_block_ids.count() == 0) { // skip - } else if (data_block_ids.count() != 1) { + ObSSTableMetaHandle meta_handle; + ObMacroIdIterator id_iterator; + MacroBlockId macro_id; + ObSharedMacroBlockMgr *shared_block_mgr = MTL(ObSharedMacroBlockMgr*); + + if (OB_FAIL(get_meta(meta_handle))) { + LOG_WARN("get meta handle fail", K(ret), KPC(this)); + } else if (is_small_sstable()) { + const int64_t data_block_count = get_data_macro_block_count(); + if (data_block_count == 0) { // skip + } else if (data_block_count != 1) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected data block ids", K(ret), K(macro_info)); - } else if (OB_FAIL(shared_block_mgr->free_block( - data_block_ids.at(0), meta_.get_macro_info().get_nested_size()))) { - LOG_WARN("fail to dec used size of shared block", K(ret), K_(meta)); + LOG_WARN("unexpected data block ids", K(ret), K(data_block_count)); + } else if (OB_FAIL(meta_handle.get_sstable_meta().get_macro_info().get_data_block_iter(id_iterator))) { + LOG_WARN("get id iterator fail", K(ret)); + } else if (OB_FAIL(id_iterator.get_next_macro_id(macro_id))) { + LOG_WARN("get first id fail", K(ret)); + } else if (OB_FAIL(shared_block_mgr->free_block(macro_id, get_macro_read_size()))) { + LOG_WARN("fail to dec used size of shared block", K(ret), K(macro_id)); } } return ret; } -int ObSSTable::pre_transform_root_block(const ObTableReadInfo &index_read_info) + +int ObSSTable::get_index_tree_root( + blocksstable::ObMicroBlockData &index_data, + const bool need_transform) { - return meta_.transform_root_block_data(index_read_info); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_NOT_INIT; + LOG_WARN("The SSTable has not been inited", K(ret), K_(valid_for_reading), K_(meta)); + } else if (OB_UNLIKELY(is_empty())) { + index_data.reset(); + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("SSTable is empty", K(ret)); + } else if (OB_UNLIKELY(!is_loaded())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("can not get index tree rot from an unloaded sstable", K(ret)); + } else if (OB_UNLIKELY(!meta_->get_root_info().get_addr().is_valid() + || !meta_->get_root_info().get_block_data().is_valid())) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("meta isn't ready for read", K(ret), KPC(meta_)); + } else if (!need_transform || ObMicroBlockData::DDL_BLOCK_TREE == meta_->get_root_info().get_block_data().type_) { + // do not need transform + index_data = meta_->get_root_info().get_block_data(); + } else if (OB_NOT_NULL(meta_->get_root_info().get_block_data().get_extra_buf())) { + // block is already transformed + index_data = meta_->get_root_info().get_block_data(); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Shouldn't happen, transform has already been done in initialize,", K(ret), KPC(this)); + } + return ret; } int ObSSTable::build_exist_iterator( @@ -1166,7 +1388,7 @@ int ObSSTable::build_exist_iterator( ObStoreRowIterator *&iter) { int ret = OB_SUCCESS; - if (meta_.contain_uncommitted_row()) { + if (contain_uncommitted_row()) { if (OB_FAIL(get(iter_param, access_context, rowkey, iter))) { LOG_WARN("Failed to get row", K(ret), K(rowkey)); } @@ -1191,7 +1413,7 @@ int ObSSTable::build_exist_iterator( int ObSSTable::build_multi_exist_iterator(ObRowsInfo &rows_info, ObStoreRowIterator *&iter) { int ret = OB_SUCCESS; - if (meta_.contain_uncommitted_row()) { + if (contain_uncommitted_row()) { if (OB_FAIL(multi_get( rows_info.exist_helper_.table_iter_param_, rows_info.exist_helper_.table_access_context_, @@ -1219,16 +1441,14 @@ int ObSSTable::build_multi_exist_iterator(ObRowsInfo &rows_info, ObStoreRowItera return ret; } -int ObSSTable::get_last_rowkey( - const ObTableReadInfo &index_read_info, - const ObDatumRowkey *&sstable_endkey) +int ObSSTable::get_last_rowkey(const ObDatumRowkey *&sstable_endkey) { int ret = OB_SUCCESS; ObMicroBlockData root_block; const ObIndexBlockDataHeader *idx_data_header = nullptr; - if (meta_.is_empty()) { + if (is_empty()) { sstable_endkey = &ObDatumRowkey::MAX_ROWKEY; - } else if (OB_FAIL(get_index_tree_root(index_read_info, root_block))) { + } else if (OB_FAIL(get_index_tree_root(root_block))) { LOG_WARN("Fail to get index tree root", K(ret), K(root_block)); } else { if (ObMicroBlockData::DDL_BLOCK_TREE == root_block.type_) { @@ -1255,5 +1475,92 @@ int ObSSTable::get_last_rowkey( return ret; } +int ObSSTable::get_meta( + ObSSTableMetaHandle &meta_handle, + common::ObSafeArenaAllocator *allocator) const +{ + int ret = OB_SUCCESS; + meta_handle.reset(); + if (is_loaded()) { + if (OB_UNLIKELY(!meta_->is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid sstable meta pointer for in-memory sstable", K(ret), KPC(this)); + } else { + meta_handle.meta_ = meta_; + meta_handle.handle_.reset(); + } + } else if (OB_UNLIKELY(!addr_.is_valid() || !addr_.is_block())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid addr for get sstable from cache", K(ret), KPC(this)); + } else { + ObStorageMetaCache &meta_cache = OB_STORE_CACHE.get_storage_meta_cache(); + const ObStorageMetaValue *value = nullptr; + const ObSSTable *sstable_ptr = nullptr; + ObStorageMetaKey meta_key(MTL_ID(), addr_); + const bool bypass_cache = nullptr != allocator; + if (!bypass_cache) { + if (OB_FAIL(meta_cache.get_meta( + ObStorageMetaValue::MetaType::SSTABLE, + meta_key, + meta_handle.handle_, + nullptr))) { + LOG_WARN("fail to retrieve sstable meta from meta cache", K(ret), K(meta_key), KPC(this)); + } + } else if (OB_FAIL(meta_cache.bypass_get_meta(ObStorageMetaValue::MetaType::SSTABLE, + meta_key, + *allocator, + meta_handle.handle_))) { + LOG_WARN("fail to bypass cache get meta", K(ret), K(meta_key)); + } + if (FAILEDx(meta_handle.handle_.get_value(value))) { + LOG_WARN("fail to get value from meta handle", K(ret), KPC(this)); + } else if (OB_ISNULL(value)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null sstable cache value", K(ret), K(value), KPC(this)); + } else if (OB_FAIL(value->get_sstable(sstable_ptr))) { + LOG_WARN("fail to get sstable from meta cache value", K(ret), KPC(value), KPC(this)); + } else if (OB_ISNULL(sstable_ptr) + || OB_UNLIKELY(!sstable_ptr->is_valid()) + || OB_ISNULL(sstable_ptr->meta_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null sstable pointer", K(ret), KPC(sstable_ptr)); + } else { + meta_handle.meta_ = sstable_ptr->meta_; + } + } + return ret; +} + +int ObSSTable::init_sstable_meta( + const ObTabletCreateSSTableParam ¶m, + common::ObArenaAllocator *allocator) +{ + int ret = OB_SUCCESS; + if (OB_NOT_NULL(meta_)) { + ret = OB_INIT_TWICE; + LOG_WARN("sstable meta already exist", K(ret), KPC_(meta)); + } else { + char *buf = static_cast(allocator->alloc(sizeof(ObSSTableMeta))); + if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret)); + } else if (FALSE_IT(meta_ = new (buf) ObSSTableMeta())) { + } else if (OB_FAIL(meta_->init(param, *allocator))) { + LOG_WARN("fail to init sstable meta", K(ret)); + } else if (OB_FAIL(meta_->transform_root_block_data(*allocator))) { + LOG_WARN("fail to transform root block data", K(ret)); + } else { + upper_trans_version_ = meta_->get_upper_trans_version(); + max_merged_trans_version_ = meta_->get_max_merged_trans_version(); + data_macro_block_count_ = meta_->get_data_macro_block_count(); + contain_uncommitted_row_ = meta_->contain_uncommitted_row(); + nested_size_ = meta_->get_macro_info().get_nested_size(); + nested_offset_ = meta_->get_macro_info().get_nested_offset(); + } + } + return ret; +} + + } // namespace blocksstable } // namespace oceanbase diff --git a/src/storage/blocksstable/ob_sstable.h b/src/storage/blocksstable/ob_sstable.h index 4c623d3d8..d4dc4136c 100644 --- a/src/storage/blocksstable/ob_sstable.h +++ b/src/storage/blocksstable/ob_sstable.h @@ -13,6 +13,7 @@ #ifndef OCEANBASE_STORAGE_BLOCKSSTABLE_OB_SSTABLE_H #define OCEANBASE_STORAGE_BLOCKSSTABLE_OB_SSTABLE_H +#include "storage/meta_mem/ob_storage_meta_cache.h" #include "storage/blocksstable/ob_sstable_meta.h" #include "storage/blocksstable/ob_macro_block_meta.h" #include "share/scn.h" @@ -36,14 +37,43 @@ class ObSSTableSecMetaIterator; class ObIMacroBlockIterator; struct ObMacroBlocksWriteCtx; +class ObSSTableMetaHandle +{ + +public: + ObSSTableMetaHandle() : handle_(), meta_(nullptr) {} + ~ObSSTableMetaHandle() { reset(); } + + void reset(); + int get_sstable_meta(const ObSSTableMeta *&sstable_meta) const; + + OB_INLINE bool is_valid() { return nullptr != meta_ && meta_->is_valid(); } + OB_INLINE const ObSSTableMeta &get_sstable_meta() const + { + OB_ASSERT(nullptr != meta_); + return *meta_; + } + TO_STRING_KV(K_(handle), KPC_(meta)); +private: + friend class ObSSTable; + ObStorageMetaHandle handle_; + const ObSSTableMeta *meta_; +}; + // SSTable class after version 4.0 -class ObSSTable : public ObITable +class ObSSTable : public ObITable, public ObIStorageMetaObj { public: ObSSTable(); virtual ~ObSSTable(); - int init(const ObTabletCreateSSTableParam ¶m, common::ObIAllocator *allocator); + // From 4.2, the SSTable object reference count will be abandoned. Otherwise, when SSTable + // will be put in KVCACHE for only read, it will modify the cache memory. + virtual void inc_ref() override; + virtual int64_t dec_ref() override; + virtual int64_t get_ref() const override; + + int init(const ObTabletCreateSSTableParam ¶m, common::ObArenaAllocator *allocator); void reset(); // Query interfaces @@ -68,12 +98,11 @@ public: const common::ObIArray &rowkeys, ObStoreRowIterator *&row_iter) override; virtual int exist( - ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &full_read_info, - const ObDatumRowkey &rowkey, - bool &is_exist, - bool &has_found) override; + const ObTableIterParam ¶m, + ObTableAccessContext &context, + const blocksstable::ObDatumRowkey &rowkey, + bool &is_exist, + bool &has_found) override; virtual int exist( ObRowsInfo &rows_info, bool &is_exist, @@ -81,7 +110,7 @@ public: int scan_macro_block( const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, blocksstable::ObIMacroBlockIterator *¯o_block_iter, const bool is_reverse_scan = false, @@ -89,14 +118,14 @@ public: const bool need_scan_sec_meta = false); int scan_micro_block( const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, ObAllMicroBlockRangeIterator *µ_iter, const bool is_reverse_scan = false); int scan_secondary_meta( ObIAllocator &allocator, const ObDatumRange &query_range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, const blocksstable::ObMacroBlockMetaType meta_type, blocksstable::ObSSTableSecMetaIterator *&meta_iter, const bool is_reverse_scan = false, @@ -105,30 +134,36 @@ public: // For transaction int check_row_locked( - ObStoreCtx &ctx, - const storage::ObTableReadInfo &full_read_info, - const ObDatumRowkey &rowkey, + const ObTableIterParam ¶m, + ObTableAccessContext &context, + const blocksstable::ObDatumRowkey &rowkey, ObStoreRowLockState &lock_state); + int set_upper_trans_version(const int64_t upper_trans_version); virtual int64_t get_upper_trans_version() const override { - return meta_.basic_meta_.upper_trans_version_; + return upper_trans_version_; } virtual int64_t get_max_merged_trans_version() const override { - return meta_.basic_meta_.max_merged_trans_version_; + return max_merged_trans_version_; } - int64_t get_recycle_version() const + OB_INLINE bool contain_uncommitted_row() const { - return meta_.basic_meta_.recycle_version_; + return contain_uncommitted_row_; } - int16_t get_sstable_seq() const + bool is_empty() const { - return meta_.basic_meta_.sstable_logic_seq_; + return 0 == data_macro_block_count_; } - share::SCN get_filled_tx_scn() const + int set_addr(const ObMetaDiskAddr &addr); + OB_INLINE const ObMetaDiskAddr &get_addr() const { return addr_; } + OB_INLINE int64_t get_data_macro_block_count() const { return data_macro_block_count_; } + OB_INLINE int64_t get_macro_offset() const { return nested_offset_; } + OB_INLINE int64_t get_macro_read_size() const { return nested_size_; } + OB_INLINE bool is_small_sstable() const { - return meta_.basic_meta_.filled_tx_scn_; + return OB_DEFAULT_MACRO_BLOCK_SIZE != nested_size_ && 0 < nested_offset_; } int64_t get_data_version() const { @@ -137,36 +172,30 @@ public: get_key().get_end_scn().get_val_for_tx(); } virtual int get_frozen_schema_version(int64_t &schema_version) const override; - int add_disk_ref(); - int dec_disk_ref(); - int pre_transform_root_block(const ObTableReadInfo &index_read_info); - int set_status_for_read(const ObSSTableStatus status); - OB_INLINE int64_t get_macro_offset() const { return meta_.get_macro_info().get_nested_offset(); } + virtual int inc_macro_ref(bool &inc_success) const; + virtual void dec_macro_ref() const; OB_INLINE bool is_valid() const { return valid_for_reading_; } - OB_INLINE const blocksstable::ObSSTableMeta &get_meta() const { return meta_; } - OB_INLINE int64_t get_macro_read_size() const { return meta_.get_macro_info().get_nested_size(); } - OB_INLINE bool is_small_sstable() const { - return OB_DEFAULT_MACRO_BLOCK_SIZE > meta_.get_macro_info().get_nested_size() - && 0 < meta_.get_macro_info().get_nested_size(); } - OB_INLINE int get_index_tree_root( - const ObTableReadInfo &index_read_info, + OB_INLINE bool is_loaded() const { return nullptr != meta_; } + int get_meta(ObSSTableMetaHandle &meta_handle, common::ObSafeArenaAllocator *allocator = nullptr) const; + int set_status_for_read(const ObSSTableStatus status); + + // TODO: get_index_tree_root and get_last_rowkey now required sstable to be loaded + int get_index_tree_root( blocksstable::ObMicroBlockData &index_data, - const bool need_transform = true) - { - return meta_.get_index_tree_root(index_read_info, index_data, need_transform); - } + const bool need_transform = true); int get_last_rowkey( - const ObTableReadInfo &index_read_info, common::ObIAllocator &allocator, ObDatumRowkey &endkey); - //TODO do not use this func except @hanhui - int get_last_rowkey( - const ObTableReadInfo &index_read_info, - common::ObIAllocator &allocator, - common::ObStoreRowkey &endkey); - bool is_empty() const override + + int deep_copy(ObArenaAllocator &allocator, ObSSTable *&dst) const; + virtual int deep_copy(char *buf, const int64_t buf_len, ObIStorageMetaObj *&value) const override; + virtual int64_t get_deep_copy_size() const override { - return meta_.is_empty(); + int64_t size = sizeof(ObSSTable); + if (is_loaded()) { + size += sizeof(ObSSTableMeta) + meta_->get_variable_size(); + } + return size; } public: @@ -182,34 +211,77 @@ public: virtual int64_t get_serialize_size() const override; virtual int serialize(char *buf, const int64_t buf_len, int64_t &pos) const override; int deserialize( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos); - int deserialize_post_work(); + int deserialize_post_work( + common::ObIAllocator *allocator); + int assign_meta(ObSSTableMeta *dest); - INHERIT_TO_STRING_KV("ObITable", ObITable, KP(this), K_(meta), K_(valid_for_reading)); + INHERIT_TO_STRING_KV("ObITable", ObITable, KP(this), K_(addr), K_(upper_trans_version), + K_(max_merged_trans_version), K_(data_macro_block_count), K_(nested_size), + K_(nested_offset), K_(contain_uncommitted_row), KPC_(meta), K_(valid_for_reading)); private: int check_valid_for_reading(); - int add_macro_ref(); - int add_used_size(); - int dec_used_size(); + int add_used_size() const; + int dec_used_size() const; int build_exist_iterator( const ObTableIterParam &iter_param, const ObDatumRowkey &rowkey, ObTableAccessContext &access_context, ObStoreRowIterator *&iter); int build_multi_exist_iterator(ObRowsInfo &rows_info, ObStoreRowIterator *&iter); - void dec_macro_ref(); - int get_last_rowkey(const ObTableReadInfo &index_read_info, const ObDatumRowkey *&sstable_endkey); + int init_sstable_meta(const ObTabletCreateSSTableParam ¶m, common::ObArenaAllocator *allocator); + int get_last_rowkey(const ObDatumRowkey *&sstable_endkey); + int serialize_fixed_struct(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize_fixed_struct(const char *buf, const int64_t data_len, int64_t &pos); + int64_t get_sstable_fix_serialize_size() const; + int64_t get_sstable_fix_serialize_payload_size() const; +private: + static const int64_t SSTABLE_VERSION = 1; + struct StatusForSerialize + { + StatusForSerialize() + : with_fixed_struct_(0), + with_meta_(0), + reserved_(0), + compat_magic_(COMPAT_MAGIC) {} + OB_INLINE void reset() { new (this) StatusForSerialize(); } + OB_INLINE bool with_fixed_struct() { return 1 == with_fixed_struct_; } + OB_INLINE bool with_meta() { return 1 == with_meta_; } + OB_INLINE void set_with_fixed_struct() { with_fixed_struct_ = 1; } + OB_INLINE void set_with_meta() { with_meta_ = 1; } + static const int8_t COMPAT_MAGIC = 0x55; + union + { + uint16_t pack_; + struct + { + uint16_t with_fixed_struct_:1; + uint16_t with_meta_:1; + + uint16_t reserved_:6; + uint16_t compat_magic_:8; + }; + }; + }; protected: - blocksstable::ObSSTableMeta meta_; + ObMetaDiskAddr addr_; // serialized in table store + // serialized data cache + int64_t upper_trans_version_; + int64_t max_merged_trans_version_; + int64_t data_macro_block_count_; + int64_t nested_size_; + int64_t nested_offset_; + bool contain_uncommitted_row_; + // in-memory bool valid_for_reading_; - bool hold_macro_ref_; - common::ObIAllocator *allocator_; - + bool is_tmp_sstable_; + // serialized + blocksstable::ObSSTableMeta *meta_; DISALLOW_COPY_AND_ASSIGN(ObSSTable); }; diff --git a/src/storage/blocksstable/ob_sstable_macro_block_header.cpp b/src/storage/blocksstable/ob_sstable_macro_block_header.cpp index f182ddbf6..e7ad1e6cc 100644 --- a/src/storage/blocksstable/ob_sstable_macro_block_header.cpp +++ b/src/storage/blocksstable/ob_sstable_macro_block_header.cpp @@ -79,7 +79,7 @@ bool ObSSTableMacroBlockHeader::is_valid() const ObSSTableMacroBlockHeader::FixedHeader::FixedHeader() : header_size_(0), - version_(SSTABLE_MACRO_BLOCK_HEADER_VERSION_V1), + version_(SSTABLE_MACRO_BLOCK_HEADER_VERSION_V2), magic_(SSTABLE_MACRO_BLOCK_HEADER_MAGIC), tablet_id_(ObTabletID::INVALID_TABLET_ID), logical_version_(0), @@ -107,7 +107,8 @@ ObSSTableMacroBlockHeader::FixedHeader::FixedHeader() bool ObSSTableMacroBlockHeader::FixedHeader::is_valid() const { return header_size_ > 0 - && SSTABLE_MACRO_BLOCK_HEADER_VERSION_V1 == version_ + && SSTABLE_MACRO_BLOCK_HEADER_VERSION_V1 <= version_ + && SSTABLE_MACRO_BLOCK_HEADER_VERSION_V2 >= version_ && SSTABLE_MACRO_BLOCK_HEADER_MAGIC == magic_ && 0 != tablet_id_ && logical_version_ >= 0 @@ -128,7 +129,7 @@ bool ObSSTableMacroBlockHeader::FixedHeader::is_valid() const void ObSSTableMacroBlockHeader::FixedHeader::reset() { header_size_ = 0; - version_ = SSTABLE_MACRO_BLOCK_HEADER_VERSION_V1; + version_ = SSTABLE_MACRO_BLOCK_HEADER_VERSION_V2; magic_ = SSTABLE_MACRO_BLOCK_HEADER_MAGIC; tablet_id_ = ObTabletID::INVALID_TABLET_ID; logical_version_ = 0; @@ -168,18 +169,19 @@ int ObSSTableMacroBlockHeader::serialize(char *buf, const int64_t buf_len, int64 ret = OB_INVALID_ARGUMENT; LOG_WARN("macro block header is invalid", K(ret), K(*this)); } else { + const int64_t col_type_array_cnt = fixed_header_.get_col_type_array_cnt(); int64_t tmp_pos = pos; FixedHeader *fixed_header = reinterpret_cast(buf + tmp_pos); *fixed_header = fixed_header_; tmp_pos += get_fixed_header_size(); if (buf + tmp_pos != reinterpret_cast(column_types_)) { - MEMCPY(buf + tmp_pos, column_types_, fixed_header_.column_count_ * sizeof(ObObjMeta)); + MEMCPY(buf + tmp_pos, column_types_, col_type_array_cnt * sizeof(ObObjMeta)); } - tmp_pos += fixed_header_.column_count_ * sizeof(ObObjMeta); + tmp_pos += col_type_array_cnt * sizeof(ObObjMeta); if (buf + tmp_pos != reinterpret_cast(column_orders_)) { - MEMCPY(buf + tmp_pos, column_orders_, fixed_header_.column_count_ * sizeof(ObOrderType)); + MEMCPY(buf + tmp_pos, column_orders_, col_type_array_cnt * sizeof(ObOrderType)); } - tmp_pos += fixed_header_.column_count_ * sizeof(ObOrderType); + tmp_pos += col_type_array_cnt * sizeof(ObOrderType); if (buf + tmp_pos != reinterpret_cast(column_checksum_)) { MEMCPY(buf + tmp_pos, column_checksum_, fixed_header_.column_count_ * sizeof(int64_t)); } @@ -208,15 +210,16 @@ int ObSSTableMacroBlockHeader::deserialize(const char *buf, const int64_t data_l int64_t tmp_pos = pos; const FixedHeader *fixed_header = reinterpret_cast(buf + tmp_pos); fixed_header_ = *fixed_header; + const int64_t col_type_array_cnt = fixed_header_.get_col_type_array_cnt(); tmp_pos += get_fixed_header_size(); if (buf + tmp_pos != reinterpret_cast(column_types_)) { column_types_ = reinterpret_cast(const_cast(buf + tmp_pos)); } - tmp_pos += fixed_header_.column_count_ * sizeof(ObObjMeta); + tmp_pos += col_type_array_cnt * sizeof(ObObjMeta); if (buf + tmp_pos != reinterpret_cast(column_orders_)) { column_orders_ = reinterpret_cast(const_cast(buf + tmp_pos)); } - tmp_pos += fixed_header_.column_count_ * sizeof(ObOrderType); + tmp_pos += col_type_array_cnt * sizeof(ObOrderType); if (buf + tmp_pos != reinterpret_cast(column_checksum_)) { column_checksum_ = reinterpret_cast(const_cast(buf + tmp_pos)); } @@ -238,7 +241,8 @@ int ObSSTableMacroBlockHeader::deserialize(const char *buf, const int64_t data_l int64_t ObSSTableMacroBlockHeader::get_serialize_size() const { - return get_fixed_header_size() + get_variable_size_in_header(fixed_header_.column_count_); + return get_fixed_header_size() + get_variable_size_in_header( + fixed_header_.column_count_, fixed_header_.rowkey_column_count_, fixed_header_.version_); } int64_t ObSSTableMacroBlockHeader::get_fixed_header_size() @@ -246,10 +250,14 @@ int64_t ObSSTableMacroBlockHeader::get_fixed_header_size() return sizeof(FixedHeader); } -int64_t ObSSTableMacroBlockHeader::get_variable_size_in_header(const int64_t column_cnt) +int64_t ObSSTableMacroBlockHeader::get_variable_size_in_header( + const int64_t column_cnt, + const int64_t rowkey_col_cnt, + const uint16_t version) { - return column_cnt * sizeof(ObObjMeta) /* ObObjMeta */ - + column_cnt * sizeof(ObOrderType) /* column orders */ + const int64_t col_type_array_cnt = SSTABLE_MACRO_BLOCK_HEADER_VERSION_V2 == version ? rowkey_col_cnt : column_cnt; + return col_type_array_cnt * sizeof(ObObjMeta) /* ObObjMeta */ + + col_type_array_cnt * sizeof(ObOrderType) /* column orders */ + column_cnt * sizeof(int64_t) /* column checksum */; } @@ -270,8 +278,9 @@ int ObSSTableMacroBlockHeader::init( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), K(desc), KP(col_types), KP(col_orders), KP(col_checksum)); } else { + fixed_header_.version_ = desc.get_fixed_header_version(); fixed_header_.header_size_ = static_cast(get_fixed_header_size() - + get_variable_size_in_header(desc.row_column_count_)); + + get_variable_size_in_header(desc.row_column_count_, desc.rowkey_column_count_, fixed_header_.version_)); fixed_header_.tablet_id_ = desc.tablet_id_.id(); fixed_header_.logical_version_ = desc.get_logical_version(); fixed_header_.column_count_ = static_cast(desc.row_column_count_); @@ -287,9 +296,18 @@ int ObSSTableMacroBlockHeader::init( column_types_ = col_types; column_orders_ = col_orders; column_checksum_ = col_checksum; - for (int64_t i = 0; i < fixed_header_.column_count_; ++i) { - column_types_[i] = desc.col_desc_array_.at(i).col_type_; - column_orders_[i] = desc.col_desc_array_.at(i).col_order_; + + + const ObIArray &col_descs = desc.is_major_merge() ? desc.get_full_stored_col_descs() :desc.get_rowkey_col_descs(); + const int64_t col_descs_cnt = fixed_header_.get_col_type_array_cnt(); + if (OB_UNLIKELY(col_descs_cnt > col_descs.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("col desc array is unexpected invalid", K(ret), K(col_descs_cnt), K(desc)); + } else { + for (int64_t i = 0; i < col_descs_cnt; ++i) { + column_types_[i] = col_descs.at(i).col_type_; + column_orders_[i] = col_descs.at(i).col_order_; + } } //for compatibility, fill 0 to checksum and this will be serialized to disk for (int i = 0; i < fixed_header_.column_count_; i++) { @@ -300,6 +318,7 @@ int ObSSTableMacroBlockHeader::init( if (OB_UNLIKELY(!is_inited_)) { reset(); } + return ret; } diff --git a/src/storage/blocksstable/ob_sstable_macro_block_header.h b/src/storage/blocksstable/ob_sstable_macro_block_header.h index 70a11b50a..e9fc211f3 100644 --- a/src/storage/blocksstable/ob_sstable_macro_block_header.h +++ b/src/storage/blocksstable/ob_sstable_macro_block_header.h @@ -34,12 +34,16 @@ private: ~FixedHeader() = default; bool is_valid() const; void reset(); + int64_t get_col_type_array_cnt() const + { + return SSTABLE_MACRO_BLOCK_HEADER_VERSION_V2 == version_ ? rowkey_column_count_ : column_count_; + } TO_STRING_KV(K_(header_size), K_(version), K_(magic), K_(tablet_id), K_(logical_version), K_(data_seq), K_(column_count), K_(rowkey_column_count), K_(row_store_type), K_(row_count), K_(occupy_size), K_(micro_block_count), K_(micro_block_data_offset),K_(micro_block_data_size), K_(idx_block_offset), K_(idx_block_size), K_(meta_block_offset), K_(meta_block_size), K_(data_checksum), K_(compressor_type), K_(encrypt_id), - K_(master_key_id), KPHEX_(encrypt_key, sizeof(encrypt_key_))); + K_(master_key_id), KPHEX_(encrypt_key, sizeof(encrypt_key_)), "col_type_array_cnt", get_col_type_array_cnt()); public: uint32_t header_size_; uint16_t version_; @@ -80,12 +84,22 @@ public: static int64_t get_fixed_header_size(); void reset(); int64_t to_string(char* buf, const int64_t buf_len) const; -private: + bool with_full_col_type_array() const { + return SSTABLE_MACRO_BLOCK_HEADER_VERSION_V1 == fixed_header_.version_; + } + static int64_t get_variable_size_in_header( + const int64_t column_cnt, + const int64_t rowkey_col_cnt, + const uint16_t version); +public: static const uint16_t SSTABLE_MACRO_BLOCK_HEADER_VERSION_V1 = 1; + static const uint16_t SSTABLE_MACRO_BLOCK_HEADER_VERSION_V2 = 2; // only store rowkey type/order +private: static const uint16_t SSTABLE_MACRO_BLOCK_HEADER_MAGIC = 1007; - static int64_t get_variable_size_in_header(const int64_t column_cnt); public: FixedHeader fixed_header_; + // only store rowkey in column_types_ & orders_ after 4.1 in mini/minor macros + // use fixed_header_.get_col_type_array_cnt() to get actual array cnt common::ObObjMeta *column_types_; common::ObOrderType *column_orders_; int64_t *column_checksum_; diff --git a/src/storage/blocksstable/ob_sstable_meta.cpp b/src/storage/blocksstable/ob_sstable_meta.cpp index 0e58dadf4..dcc930379 100644 --- a/src/storage/blocksstable/ob_sstable_meta.cpp +++ b/src/storage/blocksstable/ob_sstable_meta.cpp @@ -73,6 +73,8 @@ bool ObSSTableBasicMeta::operator!=(const ObSSTableBasicMeta &other) const } bool ObSSTableBasicMeta::operator==(const ObSSTableBasicMeta &other) const { + // don't need to compare upper_trans_version, because meta's upper_trans_version + // may be different from sstable shell's return version_ == other.version_ && length_ == other.length_ && row_count_ == other.row_count_ @@ -91,7 +93,6 @@ bool ObSSTableBasicMeta::operator==(const ObSSTableBasicMeta &other) const && create_snapshot_version_ == other.create_snapshot_version_ && progressive_merge_round_ == other.progressive_merge_round_ && progressive_merge_step_ == other.progressive_merge_step_ - && upper_trans_version_ == other.upper_trans_version_ && max_merged_trans_version_ == other.max_merged_trans_version_ && recycle_version_ == other.recycle_version_ && ddl_scn_ == other.ddl_scn_ @@ -368,13 +369,12 @@ int ObSSTableBasicMeta::set_upper_trans_version(const int64_t upper_trans_versio //================================== ObSSTableMeta ================================== ObSSTableMeta::ObSSTableMeta() - : is_inited_(false), - allocator_(nullptr), - lock_(), - basic_meta_(), - column_checksums_(), + : basic_meta_(), data_root_info_(), - macro_info_() + macro_info_(), + column_checksums_(nullptr), + column_checksum_count_(0), + is_inited_(false) { } @@ -383,7 +383,7 @@ ObSSTableMeta::~ObSSTableMeta() reset(); } -int ObSSTableMeta::load_root_block_data() +int ObSSTableMeta::load_root_block_data(common::ObArenaAllocator &allocator) { int ret = OB_SUCCESS; ObMicroBlockDesMeta des_meta(basic_meta_.compressor_type_, basic_meta_.encrypt_id_, @@ -391,71 +391,33 @@ int ObSSTableMeta::load_root_block_data() if (OB_UNLIKELY(SSTABLE_WRITE_BUILDING != basic_meta_.status_)) { ret = OB_STATE_NOT_MATCH; LOG_WARN("state is not match.", K(ret), K_(basic_meta_.status)); - } else if (OB_FAIL(data_root_info_.load_root_block_data(des_meta))) { + } else if (OB_FAIL(data_root_info_.load_root_block_data(allocator, des_meta))) { LOG_WARN("fail to load root block data for data root info", K(ret), K(data_root_info_)); - } else if (OB_FAIL(macro_info_.load_root_block_data(des_meta))) { + } else if (OB_FAIL(macro_info_.load_root_block_data(allocator, des_meta))) { LOG_WARN("fail to load root block data for macro info", K(ret), K(macro_info_)); } return ret; } -int ObSSTableMeta::get_index_tree_root( - const ObTableReadInfo &index_read_info, - blocksstable::ObMicroBlockData &index_data, - const bool need_transform) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("SSTable isn't initialized", K(ret)); - } else if (OB_UNLIKELY(is_empty())) { - index_data.reset(); - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("SSTable is empty", K(ret)); - } else if (OB_UNLIKELY(!data_root_info_.get_addr().is_valid() - || !data_root_info_.get_block_data().is_valid())) { - ret = OB_STATE_NOT_MATCH; - LOG_WARN("meta isn't ready for read", K(ret), K_(data_root_info)); - } else if (!need_transform) { - // do not need transform - index_data = data_root_info_.get_block_data(); - } else if (OB_NOT_NULL(data_root_info_.get_block_data().get_extra_buf())) { - // block is already transformed - index_data = data_root_info_.get_block_data(); - } else if (OB_FAIL(transform_root_block_data(index_read_info))) { - LOG_WARN("fail to transform index tree root block data", K(ret), K(index_read_info), KPC(this)); - } else { - index_data = data_root_info_.get_block_data(); - } - return ret; -} - -int ObSSTableMeta::transform_root_block_data(const ObTableReadInfo &read_info) -{ - TCWLockGuard guard(lock_); - return data_root_info_.transform_root_block_data(read_info); -} - void ObSSTableMeta::reset() { data_root_info_.reset(); macro_info_.reset(); basic_meta_.reset(); - column_checksums_.reset(); - allocator_ = nullptr; + column_checksums_ = nullptr; + column_checksum_count_ = 0; is_inited_ = false; } int ObSSTableMeta::init_base_meta( const ObTabletCreateSSTableParam ¶m, - common::ObIAllocator *allocator) + common::ObArenaAllocator &allocator) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!param.is_valid()) || OB_ISNULL(allocator)) { + if (OB_UNLIKELY(!param.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(param), KP(allocator)); + LOG_WARN("invalid argument", K(ret), K(param)); } else { - allocator_ = allocator; basic_meta_.status_ = SSTABLE_INIT; basic_meta_.row_count_ = param.row_count_; basic_meta_.occupy_size_ = param.occupy_size_; @@ -490,20 +452,22 @@ int ObSSTableMeta::init_base_meta( basic_meta_.master_key_id_ = param.master_key_id_; MEMCPY(basic_meta_.encrypt_key_, param.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); basic_meta_.length_ = basic_meta_.get_serialize_size(); - if (OB_FAIL(prepare_column_checksum(param.column_checksums_))) { + if (OB_FAIL(prepare_column_checksum(param.column_checksums_, allocator))) { LOG_WARN("fail to prepare column checksum", K(ret), K(param)); } } return ret; } -int ObSSTableMeta::init_data_index_tree_info(const storage::ObTabletCreateSSTableParam ¶m) +int ObSSTableMeta::init_data_index_tree_info( + const storage::ObTabletCreateSSTableParam ¶m, + common::ObArenaAllocator &allocator) { int ret = OB_SUCCESS; - if (OB_ISNULL(allocator_) && OB_UNLIKELY(!param.is_valid())) { + if (OB_UNLIKELY(!param.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid param", K(ret), K(param), KP(allocator_)); - } else if (OB_FAIL(data_root_info_.init_root_block_info(allocator_, param.root_block_addr_, + LOG_WARN("invalid param", K(ret), K(param)); + } else if (OB_FAIL(data_root_info_.init_root_block_info(allocator, param.root_block_addr_, param.root_block_data_))) { LOG_WARN("fail to init data root info", K(ret), K(param)); } else { @@ -512,17 +476,22 @@ int ObSSTableMeta::init_data_index_tree_info(const storage::ObTabletCreateSSTabl return ret; } -int ObSSTableMeta::prepare_column_checksum(const common::ObIArray &column_checksums) +int ObSSTableMeta::prepare_column_checksum( + const common::ObIArray &column_checksums, + common::ObArenaAllocator &allocator) { int ret = OB_SUCCESS; - column_checksums_.set_allocator(allocator_); - if (OB_FAIL(column_checksums_.reserve(column_checksums.count()))) { - LOG_WARN("fail to reserve column checksums array", K(ret), "count", column_checksums.count()); + const int64_t count = column_checksums.count(); + if (OB_UNLIKELY(nullptr != column_checksums_)) { + ret = OB_INIT_TWICE; + LOG_WARN("column checksum isn't empty, cannot initialize twice", K(ret), KP(column_checksums_)); + } else if (count > 0 && OB_ISNULL(column_checksums_ = static_cast(allocator.alloc(sizeof(int64_t) * count)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate column checksum memory", K(ret), K(count)); } else { + column_checksum_count_ = column_checksums.count(); for (int64_t i = 0; OB_SUCC(ret) && i < column_checksums.count(); ++i) { - if (OB_FAIL(column_checksums_.push_back(column_checksums.at(i)))) { - LOG_WARN("fail to push back column checksum", K(ret), K(i)); - } + column_checksums_[i] = column_checksums.at(i); } } return ret; @@ -532,31 +501,30 @@ bool ObSSTableMeta::check_meta() const { return basic_meta_.is_valid() && data_root_info_.is_valid() - && macro_info_.is_valid() - && nullptr != allocator_; + && macro_info_.is_valid(); } int ObSSTableMeta::init( const ObTabletCreateSSTableParam ¶m, - common::ObIAllocator *allocator) + common::ObArenaAllocator &allocator) { int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("cannot initialize twice", K(ret)); - } else if (OB_UNLIKELY(!param.is_valid()) || OB_ISNULL(allocator)) { + } else if (OB_UNLIKELY(!param.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(param), KP(allocator)); + LOG_WARN("invalid arguments", K(ret), K(param)); } else if (OB_FAIL(init_base_meta(param, allocator))) { - LOG_WARN("fail to init basic meta", K(ret), K(param), KP(allocator)); - } else if (OB_FAIL(init_data_index_tree_info(param))) { - LOG_WARN("fail to init data index tree info", K(ret), K(param), KP(allocator)); + LOG_WARN("fail to init basic meta", K(ret), K(param)); + } else if (OB_FAIL(init_data_index_tree_info(param, allocator))) { + LOG_WARN("fail to init data index tree info", K(ret), K(param)); } else if (OB_UNLIKELY(SSTABLE_WRITE_BUILDING != basic_meta_.status_)) { ret = OB_STATE_NOT_MATCH; LOG_WARN("sstable state is not match.", K(ret), K(basic_meta_.status_)); } else if (OB_FAIL(macro_info_.init_macro_info(allocator, param))) { - LOG_WARN("fail to init macro info", K(ret), K(param), KP(allocator)); - } else if (OB_FAIL(load_root_block_data())) { + LOG_WARN("fail to init macro info", K(ret), K(param)); + } else if (OB_FAIL(load_root_block_data(allocator))) { LOG_WARN("fail to load root block data", K(ret), K(param)); } else if (OB_UNLIKELY(!check_meta())) { ret = OB_ERR_UNEXPECTED; @@ -602,18 +570,20 @@ int ObSSTableMeta::serialize_(char *buf, const int64_t buf_len, int64_t &pos) co int ret = OB_SUCCESS; if (OB_FAIL(basic_meta_.serialize(buf, buf_len, pos))) { LOG_WARN("fail to serialize basic meta", K(ret), KP(buf), K(buf_len), K(pos), K_(basic_meta)); - } else if (OB_FAIL(column_checksums_.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize column checksums", K(ret), KP(buf), K(buf_len), K(pos)); - } else if (OB_FAIL(data_root_info_.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize data root info", K(ret), K(buf_len), K(pos), K(data_root_info_)); - } else if (OB_FAIL(macro_info_.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize macro info", K(ret), K(buf_len), K(pos), K(macro_info_)); + } else { + OB_UNIS_ENCODE_ARRAY(column_checksums_, column_checksum_count_); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(data_root_info_.serialize(buf, buf_len, pos))) { + LOG_WARN("fail to serialize data root info", K(ret), K(buf_len), K(pos), K(data_root_info_)); + } else if (OB_FAIL(macro_info_.serialize(buf, buf_len, pos))) { + LOG_WARN("fail to serialize macro info", K(ret), K(buf_len), K(pos), K(macro_info_)); + } } return ret; } int ObSSTableMeta::deserialize( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos) @@ -625,9 +595,9 @@ int ObSSTableMeta::deserialize( if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("cannot deserialize inited sstable meta", K(ret), K_(is_inited)); - } else if (OB_ISNULL(allocator) || OB_ISNULL(buf) || OB_UNLIKELY(data_len <= 0 || pos < 0)) { + } else if (OB_ISNULL(buf) || OB_UNLIKELY(data_len <= 0 || pos < 0)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(allocator), KP(buf), K(data_len), K(pos)); + LOG_WARN("invalid argument", K(ret), KP(buf), K(data_len), K(pos)); } else { OB_UNIS_DECODE(version); OB_UNIS_DECODE(len); @@ -636,7 +606,7 @@ int ObSSTableMeta::deserialize( ret = OB_NOT_SUPPORTED; LOG_WARN("object version mismatch", K(ret), K(version)); } else if (OB_FAIL(deserialize_(allocator, buf + pos, data_len, tmp_pos))) { - LOG_WARN("fail to deserialize_", K(ret), KP(allocator), K(data_len), K(tmp_pos), K(pos)); + LOG_WARN("fail to deserialize_", K(ret), K(data_len), K(tmp_pos), K(pos)); } else if (OB_UNLIKELY(len != tmp_pos)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected error, serialize may have bug", K(ret), K(len), K(tmp_pos), KPC(this)); @@ -652,19 +622,25 @@ int ObSSTableMeta::deserialize( } int ObSSTableMeta::deserialize_( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos) { int ret = OB_SUCCESS; - allocator_ = allocator; - column_checksums_.set_allocator(allocator); if (OB_FAIL(basic_meta_.deserialize(buf, data_len, pos))) { LOG_WARN("fail to deserialize basic meta", K(ret), KP(buf), K(data_len), K(pos)); - } else if (OB_FAIL(column_checksums_.deserialize(buf, data_len, pos))) { - LOG_WARN("fail to deserialize column checksums", K(ret), KP(buf), K(data_len), K(pos)); } else { + OB_UNIS_DECODE(column_checksum_count_); + if (OB_FAIL(ret)) { + } else if (column_checksum_count_ > 0 && OB_ISNULL(column_checksums_ = static_cast(allocator.alloc(sizeof(int64_t) * column_checksum_count_)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate column checksum memory", K(ret), K(column_checksum_count_)); + } else { + OB_UNIS_DECODE_ARRAY(column_checksums_, column_checksum_count_); + } + } + if (OB_SUCC(ret)) { ObMicroBlockDesMeta des_meta(basic_meta_.compressor_type_, basic_meta_.encrypt_id_, basic_meta_.master_key_id_, basic_meta_.encrypt_key_); if (OB_FAIL(data_root_info_.deserialize(allocator, des_meta, buf, data_len, pos))) { @@ -691,12 +667,51 @@ int64_t ObSSTableMeta::get_serialize_size_() const int64_t len = 0; MacroBlockId id_map_entry_id; len += basic_meta_.get_serialize_size(); - len += column_checksums_.get_serialize_size(); + OB_UNIS_ADD_LEN_ARRAY(column_checksums_, column_checksum_count_); len += data_root_info_.get_serialize_size(); len += macro_info_.get_serialize_size(); return len; } +int64_t ObSSTableMeta::get_variable_size() const +{ + return sizeof(int64_t) * column_checksum_count_ // column checksums + + data_root_info_.get_variable_size() + + macro_info_.get_variable_size(); +} + +int ObSSTableMeta::deep_copy( + char *buf, + const int64_t buf_len, + int64_t &pos, + ObSSTableMeta *&dest) const +{ + int ret = OB_SUCCESS; + int64_t tmp_pos = pos; + const int64_t deep_size = get_deep_copy_size(); + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len < deep_size + pos)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(buf), K(buf_len), K(deep_size), K(pos)); + } else { + char *meta_buf = buf + pos; + dest = new (meta_buf) ObSSTableMeta(); + pos += sizeof(ObSSTableMeta); + dest->basic_meta_ = basic_meta_; + dest->column_checksum_count_ = column_checksum_count_; + dest->column_checksums_ = reinterpret_cast(buf + pos); + MEMCPY(dest->column_checksums_, column_checksums_, sizeof(int64_t) * column_checksum_count_); + pos += sizeof(int64_t) * column_checksum_count_; + if (OB_FAIL(data_root_info_.deep_copy(buf, buf_len, pos, dest->data_root_info_))) { + LOG_WARN("fail to deep copy data root info", K(ret), KP(buf), K(buf_len), K(pos), K(data_root_info_)); + } else if (OB_FAIL(macro_info_.deep_copy(buf, buf_len, pos, dest->macro_info_))) { + LOG_WARN("fail to deep copy macro info", K(ret), KP(buf), K(buf_len), K(pos), K(macro_info_)); + } else { + dest->is_inited_ = is_inited_; + } + } + return ret; +} + //================================== ObMigrationSSTableParam ================================== ObMigrationSSTableParam::ObMigrationSSTableParam() : basic_meta_(), @@ -868,10 +883,15 @@ int ObSSTableMetaChecker::check_sstable_meta_strict_equality( if (!old_sstable_meta.is_valid() || !new_sstable_meta.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("old sstable meta or new sstable meta is invalid", K(ret)); - } else if (OB_UNLIKELY(old_sstable_meta.get_basic_meta() != new_sstable_meta.get_basic_meta() - || !is_array_equal(old_sstable_meta.get_col_checksum(), new_sstable_meta.get_col_checksum()))) { + } else if (OB_UNLIKELY(old_sstable_meta.get_basic_meta() != new_sstable_meta.get_basic_meta())) { ret = OB_INVALID_DATA; - LOG_WARN("new sstable meta is not equal to old sstable meta", K(ret)); + LOG_WARN("new sstable basic meta is not equal to old one", K(ret)); + } else if (OB_UNLIKELY(old_sstable_meta.get_col_checksum_cnt() != new_sstable_meta.get_col_checksum_cnt())) { + ret = OB_INVALID_DATA; + LOG_WARN("new sstable column checksum count is not equal to old one", K(ret)); + } else if (OB_UNLIKELY(0 != MEMCMP(old_sstable_meta.get_col_checksum(), new_sstable_meta.get_col_checksum(), old_sstable_meta.get_col_checksum_cnt()))) { + ret = OB_INVALID_DATA; + LOG_WARN("new sstable column checksum is not equal to one", K(ret)); } return ret; @@ -888,8 +908,8 @@ int ObSSTableMetaChecker::check_sstable_meta( LOG_WARN("old sstable meta or new sstable meta is invalid", K(ret), K(old_sstable_meta), K(new_sstable_meta)); } else if (OB_FAIL(check_sstable_basic_meta_(old_sstable_meta.get_basic_meta(), new_sstable_meta.get_basic_meta()))) { LOG_WARN("failed to check sstable basic meta", K(ret), K(old_sstable_meta), K(new_sstable_meta)); - // TODO replace check_sstable_column_checksum_ with is_array_equal - } else if (OB_FAIL(check_sstable_column_checksum_(old_sstable_meta.get_col_checksum(), new_sstable_meta.get_col_checksum()))) { + } else if (OB_FAIL(check_sstable_column_checksum_(old_sstable_meta.get_col_checksum(), old_sstable_meta.get_col_checksum_cnt(), + new_sstable_meta.get_col_checksum(), new_sstable_meta.get_col_checksum_cnt()))) { LOG_WARN("failed to check sstable column checksum", K(ret), K(old_sstable_meta), K(new_sstable_meta)); } return ret; @@ -905,8 +925,6 @@ int ObSSTableMetaChecker::check_sstable_meta( LOG_WARN("migration param or new sstable meta is invalid", K(ret), K(migration_param), K(new_sstable_meta)); } else if (OB_FAIL(check_sstable_basic_meta_(migration_param.basic_meta_, new_sstable_meta.get_basic_meta()))) { LOG_WARN("failed to check sstable basic meta", K(ret), K(migration_param), K(new_sstable_meta)); - } else if (OB_FAIL(check_sstable_column_checksum_(migration_param.column_checksums_, new_sstable_meta.get_col_checksum()))) { - LOG_WARN("failed to check sstable column checksum", K(ret), K(migration_param), K(new_sstable_meta)); } return ret; } @@ -946,17 +964,19 @@ int ObSSTableMetaChecker::check_sstable_basic_meta_( } int ObSSTableMetaChecker::check_sstable_column_checksum_( - const common::ObIArray &old_column_checksum, - const common::ObIArray &new_column_checksum) + const int64_t *old_column_checksum, + const int64_t old_column_count, + const int64_t *new_column_checksum, + const int64_t new_column_count) { int ret = OB_SUCCESS; - if (old_column_checksum.count() != new_column_checksum.count()) { + if (old_column_count != new_column_count) { ret = OB_INVALID_DATA; LOG_WARN("col_checksum_ not match", K(ret), K(old_column_checksum), K(new_column_checksum)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < old_column_checksum.count(); ++i) { - const int64_t &old_col_checksum = old_column_checksum.at(i); - const int64_t &new_col_checksum = new_column_checksum.at(i); + for (int64_t i = 0; OB_SUCC(ret) && i < old_column_count; ++i) { + const int64_t &old_col_checksum = old_column_checksum[i]; + const int64_t &new_col_checksum = new_column_checksum[i]; if (old_col_checksum != new_col_checksum) { ret = OB_INVALID_DATA; LOG_WARN("column checksum not match", K(ret), K(i), K(old_col_checksum), K(new_col_checksum)); @@ -966,6 +986,27 @@ int ObSSTableMetaChecker::check_sstable_column_checksum_( return ret; } +int ObSSTableMetaChecker::check_sstable_column_checksum_( + const common::ObIArray &old_column_checksum, + const int64_t *new_column_checksum, + const int64_t new_column_count) +{ + int ret = OB_SUCCESS; + if (old_column_checksum.count() != new_column_count) { + ret = OB_INVALID_DATA; + LOG_WARN("col_checksum_ not match", K(ret), K(old_column_checksum), K(new_column_checksum)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < old_column_checksum.count(); ++i) { + const int64_t &old_col_checksum = old_column_checksum.at(i); + const int64_t &new_col_checksum = new_column_checksum[i]; + if (old_col_checksum != new_col_checksum) { + ret = OB_INVALID_DATA; + LOG_WARN("column checksum not match", K(ret), K(i), K(old_col_checksum), K(new_col_checksum)); + } + } + } + return ret; +} } // namespace blocksstable } // namespace oceanbase diff --git a/src/storage/blocksstable/ob_sstable_meta.h b/src/storage/blocksstable/ob_sstable_meta.h index 51c9b00df..9347ff721 100644 --- a/src/storage/blocksstable/ob_sstable_meta.h +++ b/src/storage/blocksstable/ob_sstable_meta.h @@ -62,6 +62,7 @@ public: OB_INLINE share::SCN get_filled_tx_scn() const { return filled_tx_scn_; } OB_INLINE int16_t get_data_index_tree_height() const { return data_index_tree_height_; } OB_INLINE int64_t get_recycle_version() const { return recycle_version_; } + OB_INLINE int16_t get_sstable_seq() const { return sstable_logic_seq_; } int decode_for_compat(const char *buf, const int64_t data_len, int64_t &pos); int set_upper_trans_version(const int64_t upper_trans_version); @@ -112,7 +113,7 @@ public: int64_t upper_trans_version_; // major/meta major: snapshot version; others: max commit version int64_t max_merged_trans_version_; - // recycle_version only avaliable for minor sstable, recored recycled multi version start + // recycle_version only available for minor sstable, recored recycled multi version start int64_t recycle_version_; share::SCN ddl_scn_; // only used in DDL SSTable, all MB in DDL SSTable should have the same scn(start_scn) share::SCN filled_tx_scn_; // only for rebuild @@ -135,7 +136,7 @@ class ObSSTableMeta final public: ObSSTableMeta(); ~ObSSTableMeta(); - int init(const storage::ObTabletCreateSSTableParam ¶m, common::ObIAllocator *allocator); + int init(const storage::ObTabletCreateSSTableParam ¶m, common::ObArenaAllocator &allocator); void reset(); OB_INLINE bool is_valid() const { return is_inited_; } OB_INLINE bool contain_uncommitted_row() const { return basic_meta_.contain_uncommitted_row_; } @@ -144,8 +145,9 @@ public: } OB_INLINE ObSSTableBasicMeta &get_basic_meta() { return basic_meta_; } OB_INLINE const ObSSTableBasicMeta &get_basic_meta() const { return basic_meta_; } - OB_INLINE const common::ObIArray &get_col_checksum() const { return column_checksums_; } - OB_INLINE int64_t get_row_count() const { return basic_meta_.row_count_; } + OB_INLINE int64_t get_col_checksum_cnt() const { return column_checksum_count_; } + OB_INLINE int64_t *get_col_checksum() const { return column_checksums_; } + OB_INLINE int64_t get_data_checksum() const { return basic_meta_.data_checksum_; } OB_INLINE int64_t get_rowkey_column_count() const { return basic_meta_.rowkey_column_count_; } OB_INLINE int64_t get_column_count() const { return basic_meta_.column_cnt_; } OB_INLINE int64_t get_schema_rowkey_column_count() const @@ -158,31 +160,94 @@ public: } OB_INLINE int16_t get_index_tree_height() const { return basic_meta_.data_index_tree_height_; } + OB_INLINE ObSSTableStatus get_status() const + { + return static_cast(basic_meta_.status_); + } + OB_INLINE int64_t get_occupy_size() const { return basic_meta_.occupy_size_; } + OB_INLINE int64_t get_row_count() const { return basic_meta_.row_count_; } + OB_INLINE int64_t get_data_micro_block_count() const + { + return basic_meta_.get_data_micro_block_count(); + } + // FIXME: do we really need all these get_xxx_macro_block_count() interfaces? + OB_INLINE int64_t get_data_macro_block_count() const + { + return basic_meta_.get_data_macro_block_count(); + } + OB_INLINE int64_t get_index_macro_block_count() const + { + return basic_meta_.get_index_macro_block_count(); + } + OB_INLINE int64_t get_linked_macro_block_count() const + { + return macro_info_.get_linked_block_count(); + } + OB_INLINE int64_t get_total_use_old_macro_block_count() const + { + return basic_meta_.get_total_use_old_macro_block_count(); + } + OB_INLINE int64_t get_total_macro_block_count() const + { + return basic_meta_.get_total_macro_block_count(); + } + OB_INLINE int64_t get_upper_trans_version() const + { + return basic_meta_.get_upper_trans_version(); + } + OB_INLINE int64_t get_max_merged_trans_version() const + { + return basic_meta_.get_max_merged_trans_version(); + } + OB_INLINE int64_t get_create_snapshot_version() const + { + return basic_meta_.get_create_snapshot_version(); + } + OB_INLINE share::SCN get_ddl_scn() const { return basic_meta_.get_ddl_scn(); } + OB_INLINE share::SCN get_filled_tx_scn() const { return basic_meta_.get_filled_tx_scn(); } + OB_INLINE int16_t get_data_index_tree_height() const { return basic_meta_.get_data_index_tree_height(); } + OB_INLINE int64_t get_recycle_version() const { return basic_meta_.get_recycle_version(); } + OB_INLINE int16_t get_sstable_seq() const { return basic_meta_.get_sstable_seq(); } + OB_INLINE int64_t get_schema_version() const { return basic_meta_.schema_version_; } + OB_INLINE int64_t get_progressive_merge_round() const { return basic_meta_.progressive_merge_round_; } + OB_INLINE int64_t get_progressive_merge_step() const { return basic_meta_.progressive_merge_step_; } OB_INLINE const ObRootBlockInfo &get_root_info() const { return data_root_info_; } OB_INLINE const ObSSTableMacroInfo &get_macro_info() const { return macro_info_; } - int get_index_tree_root( - const ObTableReadInfo &index_read_info, - blocksstable::ObMicroBlockData &index_data, - const bool need_transform); - int load_root_block_data(); //TODO:@jinzhu remove me after using kv cache. + int load_root_block_data(common::ObArenaAllocator &allocator); //TODO:@jinzhu remove me after using kv cache. + inline int transform_root_block_data(common::ObArenaAllocator &allocator) + { + return data_root_info_.transform_root_block_data(allocator); + } int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; int deserialize( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos); int64_t get_serialize_size() const; - TO_STRING_KV(K_(basic_meta), K(column_checksums_.count()), - K_(data_root_info), K_(macro_info), KP_(allocator), K_(column_checksums)); + int64_t get_variable_size() const; + inline int64_t get_deep_copy_size() const + { + return sizeof(ObSSTableMeta) + get_variable_size(); + } + int deep_copy( + char *buf, + const int64_t buf_len, + int64_t &pos, + ObSSTableMeta *&dest) const; + TO_STRING_KV(K_(basic_meta), KP_(column_checksums), K_(column_checksum_count), K_(data_root_info), K_(macro_info)); private: bool check_meta() const; - int init_base_meta(const ObTabletCreateSSTableParam ¶m, common::ObIAllocator *allocator); - int init_data_index_tree_info(const storage::ObTabletCreateSSTableParam ¶m); - int prepare_column_checksum(const common::ObIArray &column_checksums); - int transform_root_block_data(const ObTableReadInfo &read_info); + int init_base_meta(const ObTabletCreateSSTableParam ¶m, common::ObArenaAllocator &allocator); + int init_data_index_tree_info( + const storage::ObTabletCreateSSTableParam ¶m, + common::ObArenaAllocator &allocator); + int prepare_column_checksum( + const common::ObIArray &column_checksums, + common::ObArenaAllocator &allocator); int serialize_(char *buf, const int64_t buf_len, int64_t &pos) const; int deserialize_( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos); @@ -190,15 +255,14 @@ private: private: friend class ObSSTable; static const int64_t SSTABLE_META_VERSION = 1; - typedef common::ObFixedArray ColChecksumArray; private: - bool is_inited_; - common::ObIAllocator *allocator_; - common::TCRWLock lock_; ObSSTableBasicMeta basic_meta_; - ColChecksumArray column_checksums_; ObRootBlockInfo data_root_info_; ObSSTableMacroInfo macro_info_; + int64_t *column_checksums_; + int64_t column_checksum_count_; + // The following fields don't to persist + bool is_inited_; DISALLOW_COPY_AND_ASSIGN(ObSSTableMeta); }; @@ -242,9 +306,15 @@ private: static int check_sstable_basic_meta_( const ObSSTableBasicMeta &old_sstable_basic_meta, const ObSSTableBasicMeta &new_sstable_basic_meta); + static int check_sstable_column_checksum_( + const int64_t *old_column_checksum, + const int64_t old_column_count, + const int64_t *new_column_checksum, + const int64_t new_column_count); static int check_sstable_column_checksum_( const common::ObIArray &old_column_checksum, - const common::ObIArray &new_column_checksum); + const int64_t *new_column_checksum, + const int64_t new_column_count); }; diff --git a/src/storage/blocksstable/ob_sstable_meta_info.cpp b/src/storage/blocksstable/ob_sstable_meta_info.cpp index eee13307a..3621d2105 100644 --- a/src/storage/blocksstable/ob_sstable_meta_info.cpp +++ b/src/storage/blocksstable/ob_sstable_meta_info.cpp @@ -12,6 +12,7 @@ #define USING_LOG_PREFIX STORAGE +#include "lib/allocator/ob_allocator.h" #include "storage/blocksstable/ob_sstable_meta_info.h" #include "storage/blocksstable/ob_macro_block_reader.h" #include "storage/blocksstable/ob_block_manager.h" @@ -23,10 +24,10 @@ namespace oceanbase { namespace blocksstable { + ObRootBlockInfo::ObRootBlockInfo() : addr_(), - block_data_(), - block_data_allocator_(nullptr) + block_data_() { } @@ -43,16 +44,7 @@ bool ObRootBlockInfo::is_valid() const void ObRootBlockInfo::reset() { - if (ObMicroBlockData::INDEX_BLOCK == block_data_.type_) { - if (OB_NOT_NULL(block_data_.buf_) && OB_NOT_NULL(block_data_allocator_)) { - block_data_allocator_->free(static_cast(const_cast(block_data_.buf_))); - } - if (OB_NOT_NULL(block_data_.extra_buf_) && OB_NOT_NULL(block_data_allocator_)) { - block_data_allocator_->free(static_cast(const_cast(block_data_.extra_buf_))); - } - } block_data_.reset(); - block_data_allocator_ = nullptr; addr_.reset(); } @@ -81,7 +73,7 @@ int ObRootBlockInfo::serialize(char *buf, const int64_t buf_len, int64_t &pos) c } int ObRootBlockInfo::deserialize( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const ObMicroBlockDesMeta &des_meta, const char *buf, const int64_t data_len, @@ -91,13 +83,12 @@ int ObRootBlockInfo::deserialize( int64_t tmp_pos = 0; int64_t len = 0; int64_t version = 0; - if (OB_ISNULL(allocator) - || OB_UNLIKELY(!des_meta.is_valid()) + if (OB_UNLIKELY(!des_meta.is_valid()) || OB_ISNULL(buf) || OB_UNLIKELY(data_len <= 0) || OB_UNLIKELY(pos < 0)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(allocator), K(des_meta), KP(buf), K(data_len), K(pos)); + LOG_WARN("invalid argument", K(ret), K(des_meta), KP(buf), K(data_len), K(pos)); } else { OB_UNIS_DECODE(version); OB_UNIS_DECODE(len); @@ -106,7 +97,7 @@ int ObRootBlockInfo::deserialize( ret = OB_NOT_SUPPORTED; LOG_WARN("object version mismatch", K(ret), K(version)); } else if (OB_FAIL(deserialize_(allocator, des_meta, buf + pos, data_len, tmp_pos))) { - LOG_WARN("fail to deserialize address and load", K(ret), KP(allocator), K(des_meta), KP(buf), + LOG_WARN("fail to deserialize address and load", K(ret), K(des_meta), KP(buf), K(data_len), K(pos)); } else if (OB_UNLIKELY(len != tmp_pos)) { ret = OB_ERR_UNEXPECTED; @@ -139,7 +130,7 @@ int64_t ObRootBlockInfo::get_serialize_size_() const } int ObRootBlockInfo::init_root_block_info( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const ObMetaDiskAddr &addr, const ObMicroBlockData &block_data) { @@ -149,12 +140,10 @@ int ObRootBlockInfo::init_root_block_info( int64_t offset = 0; if (OB_UNLIKELY(!addr.is_valid()) || OB_UNLIKELY(!addr.is_memory() && !addr.is_block() && !addr.is_none()) - || (OB_UNLIKELY(addr.is_memory()) && OB_ISNULL(block_data.buf_)) - || OB_ISNULL(allocator)) { + || (OB_UNLIKELY(addr.is_memory()) && OB_ISNULL(block_data.buf_))) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(addr), K(block_data), KP(allocator)); + LOG_WARN("invalid argument", K(ret), K(addr), K(block_data)); } else if (FALSE_IT(addr_ = addr)) { - } else if (FALSE_IT(block_data_allocator_ = allocator)) { } else if (!addr.is_memory()) { block_data_.type_ = ObMicroBlockData::INDEX_BLOCK; } else if (OB_FAIL(addr.get_mem_addr(offset, size))) { @@ -163,34 +152,33 @@ int ObRootBlockInfo::init_root_block_info( LOG_DEBUG("block data type", K(block_data.type_)); if (ObMicroBlockData::DDL_BLOCK_TREE == block_data.type_) { block_data_ = block_data; + } else if (size > 0 && OB_ISNULL(dst_buf = static_cast(allocator.alloc(size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc buf", K(ret), K(size)); } else { - if (OB_ISNULL(dst_buf = static_cast(allocator->alloc(size)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc buf", K(ret), K(size)); - } else { - MEMCPY(dst_buf, block_data.buf_, size); - block_data_.buf_ = dst_buf; - block_data_.size_ = size; - block_data_.type_ = ObMicroBlockData::INDEX_BLOCK; - } + MEMCPY(dst_buf, block_data.buf_, size); + block_data_.buf_ = dst_buf; + block_data_.size_ = size; + block_data_.type_ = ObMicroBlockData::INDEX_BLOCK; } } if (OB_FAIL(ret)) { if (OB_NOT_NULL(dst_buf)) { - allocator->free(dst_buf); + allocator.free(dst_buf); } } return ret; } -int ObRootBlockInfo::load_root_block_data(const ObMicroBlockDesMeta &des_meta) +int ObRootBlockInfo::load_root_block_data( + common::ObArenaAllocator &allocator, + const ObMicroBlockDesMeta &des_meta) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!des_meta.is_valid()) - || OB_UNLIKELY(!addr_.is_valid()) - || OB_ISNULL(block_data_allocator_)) { + || OB_UNLIKELY(!addr_.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(des_meta), K(addr_), KP(block_data_allocator_)); + LOG_WARN("invalid argument", K(ret), K(des_meta), K(addr_)); } else if (addr_.is_block()) { char *dst_buf = nullptr; ObMacroBlockReader reader; @@ -202,9 +190,8 @@ int ObRootBlockInfo::load_root_block_data(const ObMicroBlockDesMeta &des_meta) } else if (OB_FAIL(read_block_data(addr_, dst_buf, addr_.size()))) { LOG_WARN("fail to read block data", K(ret), K(addr_)); } else if (OB_FAIL(reader.decrypt_and_decompress_data(des_meta, dst_buf, addr_.size(), - block_data_.buf_, block_data_.size_, is_compressed, true, block_data_allocator_))) { - LOG_WARN("fail to decrypt and decomp block", K(ret), K(des_meta), K(addr_), - K_(block_data), KP(block_data_allocator_)); + block_data_.buf_, block_data_.size_, is_compressed, true, &allocator))) { + LOG_WARN("fail to decrypt and decomp block", K(ret), K(des_meta), K(addr_), K_(block_data)); } else { block_data_.type_ = ObMicroBlockData::INDEX_BLOCK; } @@ -216,35 +203,30 @@ int ObRootBlockInfo::load_root_block_data(const ObMicroBlockDesMeta &des_meta) return ret; } -int ObRootBlockInfo::transform_root_block_data(const ObTableReadInfo &read_info) +int ObRootBlockInfo::transform_root_block_data(common::ObArenaAllocator &allocator) { int ret = OB_SUCCESS; if (ObMicroBlockData::INDEX_BLOCK == block_data_.type_ && OB_ISNULL(block_data_.get_extra_buf()) && OB_NOT_NULL(block_data_.get_buf())) { ObIndexBlockDataTransformer transformer; - if (OB_UNLIKELY(!read_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid read_info", K(ret)); + char *extra_buf = nullptr; + int64_t extra_size = ObIndexBlockDataTransformer::get_transformed_block_mem_size(block_data_); + if (extra_size > 0 && OB_ISNULL(extra_buf = static_cast(allocator.alloc(extra_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory", K(ret), K(extra_size)); + } else if (OB_FAIL(transformer.transform(block_data_, extra_buf, extra_size))) { + LOG_WARN("Fail to transform root block to memory format", K(ret), + K(block_data_), KP(extra_buf), K(extra_size)); } else { - char *extra_buf = nullptr; - int64_t extra_size = ObIndexBlockDataTransformer::get_transformed_block_mem_size(block_data_); - if (OB_ISNULL(extra_buf = static_cast(block_data_allocator_->alloc(extra_size)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("Allocate root block memory format failed", K(ret), K(extra_size)); - } else if (OB_FAIL(transformer.transform(read_info, block_data_, extra_buf, extra_size))) { - LOG_WARN("Fail to transform root block to memory format", K(ret), K(read_info), - K(block_data_), KP(extra_buf), K(extra_size)); - } else { - block_data_.get_extra_buf() = extra_buf; - block_data_.get_extra_size() = extra_size; - block_data_.type_ = ObMicroBlockData::INDEX_BLOCK; - } - if (OB_FAIL(ret) && OB_NOT_NULL(extra_buf)) { - block_data_allocator_->free(extra_buf); - } else { - LOG_DEBUG("succeed to transform root block data", K(addr_), K(read_info)); - } + block_data_.get_extra_buf() = extra_buf; + block_data_.get_extra_size() = extra_size; + block_data_.type_ = ObMicroBlockData::INDEX_BLOCK; + } + if (OB_FAIL(ret) && OB_NOT_NULL(extra_buf)) { + allocator.free(extra_buf); + } else { + LOG_DEBUG("succeed to transform root block data", K(addr_), KPC(this)); } } return ret; @@ -306,7 +288,7 @@ int ObRootBlockInfo::serialize_( } int ObRootBlockInfo::deserialize_( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const ObMicroBlockDesMeta &des_meta, const char *buf, const int64_t data_len, @@ -315,13 +297,11 @@ int ObRootBlockInfo::deserialize_( int ret = OB_SUCCESS; char *data_buf = nullptr; int64_t block_size = 0; - block_data_allocator_ = allocator; - if (OB_ISNULL(allocator) - || OB_ISNULL(buf) + if (OB_ISNULL(buf) || OB_UNLIKELY(!des_meta.is_valid()) || OB_UNLIKELY(pos >= data_len)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(allocator), KP(buf), K(des_meta), K(data_len), K(pos)); + LOG_WARN("invalid argument", K(ret), KP(buf), K(des_meta), K(data_len), K(pos)); } else if (OB_FAIL(addr_.deserialize(buf, data_len, pos))) { LOG_WARN("fail to deserialize address", K(ret), KP(buf), K(data_len), K(pos)); } else if (OB_UNLIKELY(!addr_.is_valid()) @@ -330,7 +310,7 @@ int ObRootBlockInfo::deserialize_( LOG_WARN("invalid address", K(ret), K(addr_)); } else if (addr_.is_none()) { // do nothing - } else if (OB_ISNULL(data_buf = static_cast(allocator->alloc(addr_.size())))) { + } else if (addr_.size() > 0 && OB_ISNULL(data_buf = static_cast(allocator.alloc(addr_.size())))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc data buffer", K(ret), K(addr_)); } else if (addr_.is_block()) { @@ -341,10 +321,10 @@ int ObRootBlockInfo::deserialize_( if (OB_FAIL(read_block_data(addr_, data_buf, addr_.size()))) { LOG_WARN("fail to read block data", K(ret), K(addr_)); } else if (OB_FAIL(reader.decrypt_and_decompress_data(des_meta, data_buf, addr_.size(), - decomp_buf, decomp_size, is_compressed, true, allocator))) { + decomp_buf, decomp_size, is_compressed, true, &allocator))) { LOG_WARN("fail to decrypt and decomp block", K(ret), K(des_meta), KP(data_buf), K_(addr)); } else { - allocator->free(data_buf); + allocator.free(data_buf); data_buf = const_cast(decomp_buf); block_size = decomp_size; } @@ -357,8 +337,8 @@ int ObRootBlockInfo::deserialize_( pos += addr_.size(); } if (OB_FAIL(ret)) { - if (OB_NOT_NULL(data_buf) && OB_NOT_NULL(allocator)) { - allocator->free(data_buf); + if (OB_NOT_NULL(data_buf)) { + allocator.free(data_buf); data_buf = nullptr; } } else { @@ -369,11 +349,145 @@ int ObRootBlockInfo::deserialize_( return ret; } +int ObRootBlockInfo::deep_copy( + char *buf, + const int64_t buf_len, + int64_t &pos, + ObRootBlockInfo &dest) const +{ + int ret = OB_SUCCESS; + int64_t tmp_pos = pos; + const int64_t variable_size = get_variable_size(); + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len < variable_size + pos)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(buf), K(buf_len), K(variable_size), K(pos)); + } else { + dest.addr_ = addr_; + if (OB_NOT_NULL(block_data_.buf_)) { + MEMCPY(buf + pos, block_data_.buf_, block_data_.size_); + dest.block_data_.buf_ = buf + pos; + dest.block_data_.size_ = block_data_.size_; + pos += block_data_.size_; + } + if (OB_NOT_NULL(block_data_.extra_buf_)) { + const ObIndexBlockDataHeader *src_idx_header + = reinterpret_cast(block_data_.get_extra_buf()); + ObIndexBlockDataTransformer transformer; + if (OB_FAIL(transformer.update_index_block(*src_idx_header, + dest.block_data_.buf_, + block_data_.get_buf_size(), + buf + pos, + block_data_.get_extra_size()))) { + LOG_WARN("fail to update transformed index block", K(ret)); + } else { + dest.block_data_.extra_buf_ = buf + pos; + dest.block_data_.extra_size_ = block_data_.extra_size_; + pos += block_data_.extra_size_; + } + } + dest.block_data_.type_ = block_data_.type_; + } + return ret; +} + +ObMacroIdIterator::ObMacroIdIterator() + : value_ptr_(nullptr), + pos_(0), + count_(0), + is_inited_(false), + allocator_("MacroIdIter") +{ +} + +int ObMacroIdIterator::init(const Type type, const MacroBlockId &entry_id, const int64_t pos) +{ + int ret = OB_SUCCESS; + MacroBlockId *data_blk_ids = nullptr; + int64_t data_blk_cnt = 0; + MacroBlockId *other_blk_ids = nullptr; + int64_t other_blk_cnt = 0; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_UNLIKELY(type >= Type::MAX || !entry_id.is_valid() || pos < 0 || count_ < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(type), K(entry_id), K(pos), K(count_)); + } else if (OB_FAIL(ObSSTableMacroInfo::read_block_ids(entry_id, allocator_, data_blk_ids, + data_blk_cnt, other_blk_ids, other_blk_cnt))) { + LOG_WARN("fail to read block ids", K(ret), K(entry_id)); + } else { + if (Type::DATA_BLOCK == type) { + value_ptr_ = data_blk_ids; + count_ = data_blk_cnt; + } else if (Type::OTHER_BLOCK == type) { + value_ptr_ = other_blk_ids; + count_ = other_blk_cnt; + } + pos_ = pos; + is_inited_ = true; + } + if (OB_UNLIKELY(!is_inited_)) { + reset(); + } + return ret; +} + +int ObMacroIdIterator::init(MacroBlockId *ptr, const int64_t count, const int64_t pos) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_UNLIKELY(pos < 0 || count < 0 || pos > count)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(ptr), K(count), K(pos)); + } else { + value_ptr_ = ptr; + pos_ = pos; + count_ = count; + is_inited_ = true; + } + if (OB_UNLIKELY(!is_inited_)) { + reset(); + } + return ret; +} + +void ObMacroIdIterator::reset() +{ + value_ptr_ = nullptr; + pos_ = 0; + count_ = 0; + is_inited_ = false; +} + +int ObMacroIdIterator::get_next_macro_id(MacroBlockId ¯o_id) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (0 == count_) { + ret = OB_ITER_END; + } else if (OB_UNLIKELY(!is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KPC(this)); + } else if (pos_ < count_) { + macro_id = value_ptr_[pos_++]; + } else { + ret = OB_ITER_END; + } + return ret; +} + ObSSTableMacroInfo::ObSSTableMacroInfo() : macro_meta_info_(), - data_block_ids_(), - other_block_ids_(), - linked_block_ids_(), + data_block_ids_(nullptr), + other_block_ids_(nullptr), + linked_block_ids_(nullptr), + data_block_count_(0), + other_block_count_(0), + linked_block_count_(0), entry_id_(), is_meta_root_(false), nested_offset_(0), @@ -387,35 +501,56 @@ ObSSTableMacroInfo::~ObSSTableMacroInfo() } int ObSSTableMacroInfo::init_macro_info( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const storage::ObTabletCreateSSTableParam ¶m) { int ret = OB_SUCCESS; - if (OB_ISNULL(allocator) && OB_UNLIKELY(!param.is_valid())) { + if (OB_UNLIKELY(!param.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid param", K(ret), K(param), KP(allocator)); + LOG_WARN("invalid param", K(ret), K(param)); } else if (OB_FAIL(macro_meta_info_.init_root_block_info(allocator, param.data_block_macro_meta_addr_, param.data_block_macro_meta_))) { LOG_WARN("fail to init macro meta info", K(ret), K(param)); + } else if (FALSE_IT(data_block_count_ = param.data_block_ids_.count())) { + } else if (FALSE_IT(other_block_count_ = param.other_block_ids_.count())) { + } else if (data_block_count_ + other_block_count_ >= BLOCK_CNT_THRESHOLD) { + if (OB_FAIL(persist_block_ids(param.data_block_ids_, param.other_block_ids_, allocator))) { + LOG_WARN("fail to persist block ids", K(ret), K(param)); + } + } else if (param.data_block_ids_.count() > 0 + && OB_ISNULL(data_block_ids_ = static_cast(allocator.alloc( + sizeof(MacroBlockId) * param.data_block_ids_.count())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory", K(ret), K(param.data_block_ids_.count())); + } else if (param.other_block_ids_.count() >0 + && OB_ISNULL(other_block_ids_ = static_cast(allocator.alloc( + sizeof(MacroBlockId) * param.other_block_ids_.count())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory", K(ret), K(param.other_block_ids_.count())); + } else { + entry_id_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK; + for (int64_t i = 0; OB_SUCC(ret) && i < param.data_block_ids_.count(); ++i) { + new (data_block_ids_ + i) MacroBlockId(param.data_block_ids_.at(i)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < param.other_block_ids_.count(); ++i) { + new (other_block_ids_ + i) MacroBlockId(param.other_block_ids_.at(i)); + } + } + if (OB_FAIL(ret)) { + reset(); } else { is_meta_root_ = param.is_meta_root_; nested_offset_ = param.nested_offset_; nested_size_ = 0 == param.nested_size_ ? OB_DEFAULT_MACRO_BLOCK_SIZE : param.nested_size_; - data_block_ids_.set_allocator(allocator); - other_block_ids_.set_allocator(allocator); - linked_block_ids_.set_allocator(allocator); - if (OB_FAIL(data_block_ids_.assign(param.data_block_ids_))) { - LOG_WARN("fail to assign data block ids array", K(ret), K(param)); - } else if (OB_FAIL(other_block_ids_.assign(param.other_block_ids_))) { - LOG_WARN("fail to assign other block ids array", K(ret), K(param)); - } } return ret; } -int ObSSTableMacroInfo::load_root_block_data(const ObMicroBlockDesMeta &des_meta) +int ObSSTableMacroInfo::load_root_block_data( + common::ObArenaAllocator &allocator, + const ObMicroBlockDesMeta &des_meta) { - return macro_meta_info_.load_root_block_data(des_meta); + return macro_meta_info_.load_root_block_data(allocator, des_meta); } bool ObSSTableMacroInfo::is_valid() const @@ -426,9 +561,27 @@ bool ObSSTableMacroInfo::is_valid() const void ObSSTableMacroInfo::reset() { macro_meta_info_.reset(); - data_block_ids_.reset(); - other_block_ids_.reset(); - linked_block_ids_.reset(); + if (nullptr != data_block_ids_) { + for (int64_t i = 0; i < data_block_count_; i++) { + data_block_ids_[i].~MacroBlockId(); + } + data_block_ids_ = nullptr; + } + data_block_count_ = 0; + if (nullptr != other_block_ids_) { + for (int64_t i = 0; i < other_block_count_; i++) { + other_block_ids_[i].~MacroBlockId(); + } + other_block_ids_ = nullptr; + } + other_block_count_ = 0; + if (nullptr != linked_block_ids_) { + for (int64_t i = 0; i < linked_block_count_; i++) { + linked_block_ids_[i].~MacroBlockId(); + } + linked_block_ids_ = nullptr; + } + linked_block_count_ = 0; entry_id_.reset(); is_meta_root_ = false; nested_offset_ = 0; @@ -462,38 +615,13 @@ int ObSSTableMacroInfo::serialize(char *buf, const int64_t buf_len, int64_t &pos int ObSSTableMacroInfo::serialize_(char *buf, const int64_t buf_len, int64_t &pos) const { int ret = OB_SUCCESS; - // NOTE: - // - This is not good code, but it has to be done because block list needs to be persisted. - ObSSTableMacroInfo* ptr = const_cast(this); - ObLinkedMacroBlockItemWriter block_writer; - const int64_t data_blk_cnt = data_block_ids_.count(); - const int64_t other_blk_cnt = other_block_ids_.count(); - if (OB_FAIL(macro_meta_info_.serialize(buf, buf_len, pos))) { LOG_WARN("fail to serialize root block info", K(ret), K(buf_len), K(pos), K_(macro_meta_info)); - } else if (data_blk_cnt + other_blk_cnt >= BLOCK_CNT_THRESHOLD) { - if (linked_block_ids_.count() > 0) { - // nothing to do - } else if (OB_FAIL(write_block_ids(block_writer, - ptr->entry_id_))) { - LOG_WARN("fail to write other block ids", K(ret), K(buf_len), K(pos), K(data_block_ids_), K(other_block_ids_)); - } else if (OB_FAIL(save_linked_block_list(block_writer.get_meta_block_list(), - ptr->linked_block_ids_))) { - LOG_WARN("fail to save linked block ids", K(ret), K(buf_len), K(pos), K_(linked_block_ids)); - } - if (OB_SUCC(ret)) { - if (OB_FAIL(entry_id_.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize data block ids' entry", K(ret), K(buf_len), K(pos), K_(entry_id)); - } - } - } else { - if (OB_FAIL(ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize empty entry_id_", K(ret), K(buf_len), K(pos)); - } else if (OB_FAIL(data_block_ids_.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize data id array", K(ret), K(data_block_ids_), K(buf_len), K(pos)); - } else if (OB_FAIL(other_block_ids_.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize other id array", K(ret), K(other_block_ids_), K(buf_len), K(pos)); - } + } else if (OB_FAIL(entry_id_.serialize(buf, buf_len, pos))) { + LOG_WARN("fail to serialize data block ids' entry", K(ret), K(buf_len), K(pos), K_(entry_id)); + } else if (ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK == entry_id_){ + OB_UNIS_ENCODE_ARRAY(data_block_ids_, data_block_count_); + OB_UNIS_ENCODE_ARRAY(other_block_ids_, other_block_count_); } if (OB_FAIL(ret)) { // do nothing @@ -508,41 +636,96 @@ int ObSSTableMacroInfo::serialize_(char *buf, const int64_t buf_len, int64_t &po return ret; } -int ObSSTableMacroInfo::save_linked_block_list( - const common::ObIArray &list, - common::ObIArray &linked_list) const +int ObSSTableMacroInfo::persist_block_ids( + const common::ObIArray &data_ids, + const common::ObIArray &other_ids, + common::ObArenaAllocator &allocator) { int ret = OB_SUCCESS; - const int64_t ids_cnt = list.count(); - if (OB_FAIL(linked_list.reserve(ids_cnt))) { - LOG_WARN("fail to reserve linked block ids", K(ret), K(ids_cnt)); + ObLinkedMacroBlockItemWriter block_writer; + if (OB_FAIL(write_block_ids(data_ids, other_ids, block_writer, entry_id_))) { + LOG_WARN("fail to write other block ids", K(ret)); + } else if (OB_FAIL(save_linked_block_list(block_writer.get_meta_block_list(), allocator))) { + LOG_WARN("fail to save linked block ids", K(ret)); + } else if (OB_FAIL(inc_linked_block_ref_cnt(allocator))) { + LOG_WARN("fail to increase linked block ref cnt", K(ret)); + } + return ret; +} + +void ObSSTableMacroInfo::dec_linked_block_ref_cnt() +{ + int ret = OB_SUCCESS; + int64_t idx = 0; + if (0 == linked_block_count_) { + // skip the decrease + } else if (OB_ISNULL(linked_block_ids_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("linked_block_ids is null, but linked_block_count_ is not 0", K(linked_block_count_)); } else { - int64_t idx = 0; - while (OB_SUCC(ret) && idx < list.count()) { - const MacroBlockId ¯o_id = list.at(idx); - if (OB_FAIL(linked_list.push_back(macro_id))) { - LOG_WARN("fail to push back macro id", K(ret), K(idx), K(macro_id), K(list)); - } else if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(macro_id))) { - LOG_WARN("fail to inc macro block ref cnt", K(ret), K(idx), K(macro_id)); - } else { - ++idx; + for (; idx < linked_block_count_; idx++) { + const MacroBlockId ¯o_id = linked_block_ids_[idx]; + if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to decrease macro block ref cnt", K(ret), K(macro_id)); } } + } +} + +int ObSSTableMacroInfo::inc_linked_block_ref_cnt(common::ObArenaAllocator &allocator) +{ + int ret = OB_SUCCESS; + int64_t idx = 0; + if (0 == linked_block_count_) { + // skip the decrease + } else if (OB_ISNULL(linked_block_ids_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("linked_block_ids is null, but linked_block_count_ is not 0", K(linked_block_count_)); + } else { + for (; OB_SUCC(ret) && idx < linked_block_count_; idx++) { + const MacroBlockId ¯o_id = linked_block_ids_[idx]; + if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(macro_id))) { + LOG_WARN("fail to increase macro block ref cnt", K(ret), K(macro_id)); + } + } + if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; - for (int64_t j = 0; j < idx; ++j) { // ignore ret on purpose - const MacroBlockId ¯o_id = list.at(j); - if (OB_SUCCESS != (tmp_ret = OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { - LOG_ERROR("fail to dec macro block ref cnt", K(ret), K(tmp_ret), K(j), K(macro_id)); + for (int64_t i = 0; i < idx; i++) { + const MacroBlockId ¯o_id = linked_block_ids_[idx]; + if (OB_TMP_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to decrease macro block ref cnt", K(tmp_ret), K(macro_id)); } } + allocator.free(linked_block_ids_); + linked_block_ids_ = nullptr; } } return ret; } +int ObSSTableMacroInfo::save_linked_block_list( + const common::ObIArray &list, + common::ObArenaAllocator &allocator) +{ + int ret = OB_SUCCESS; + const int64_t ids_cnt = list.count(); + if (ids_cnt > 0 && OB_ISNULL(linked_block_ids_ = static_cast(allocator.alloc( + sizeof(MacroBlockId) * ids_cnt)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory", K(ret), K(ids_cnt)); + } else { + int64_t idx = 0; + for (int64_t idx = 0; idx < ids_cnt; ++idx) { + new (linked_block_ids_ + idx) MacroBlockId(list.at(idx)); + } + linked_block_count_ = ids_cnt; + } + return ret; +} + int ObSSTableMacroInfo::deserialize( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const ObMicroBlockDesMeta &des_meta, const char *buf, const int64_t data_len, @@ -552,13 +735,12 @@ int ObSSTableMacroInfo::deserialize( int64_t tmp_pos = 0; int64_t len = 0; int64_t version = 0; - if (OB_ISNULL(allocator) - || OB_UNLIKELY(!des_meta.is_valid()) + if (OB_UNLIKELY(!des_meta.is_valid()) || OB_ISNULL(buf) || OB_UNLIKELY(data_len <= 0) || OB_UNLIKELY(pos < 0)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(allocator), K(des_meta), KP(buf), K(data_len), K(pos)); + LOG_WARN("invalid argument", K(ret), K(des_meta), KP(buf), K(data_len), K(pos)); } else { OB_UNIS_DECODE(version); OB_UNIS_DECODE(len); @@ -570,7 +752,7 @@ int ObSSTableMacroInfo::deserialize( ret = OB_ERR_UNEXPECTED; LOG_WARN("payload is out of the buf's boundary", K(ret), K(data_len), K(pos), K(len)); } else if (OB_FAIL(deserialize_(allocator, des_meta, buf + pos, len, tmp_pos))) { - LOG_WARN("fail to deserialize_", K(ret), KP(allocator), K(des_meta), KP(buf), K(len), K(tmp_pos)); + LOG_WARN("fail to deserialize_", K(ret), K(des_meta), KP(buf), K(len), K(tmp_pos)); } else if (OB_UNLIKELY(len != tmp_pos)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected error, serialize may have bug", K(ret), K(len), K(tmp_pos), K(*this)); @@ -582,15 +764,13 @@ int ObSSTableMacroInfo::deserialize( } int ObSSTableMacroInfo::deserialize_( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const ObMicroBlockDesMeta &des_meta, const char *buf, const int64_t data_len, int64_t &pos) { int ret = OB_SUCCESS; - data_block_ids_.set_allocator(allocator); - other_block_ids_.set_allocator(allocator); nested_size_ = OB_DEFAULT_MACRO_BLOCK_SIZE; if (OB_FAIL(macro_meta_info_.deserialize(allocator, des_meta, buf, data_len, pos))) { @@ -598,17 +778,31 @@ int ObSSTableMacroInfo::deserialize_( } else if (OB_FAIL(entry_id_.deserialize(buf, data_len, pos))) { LOG_WARN("fail to deserialize entry block macro id", K(ret), KP(buf), K(data_len), K(pos)); } else if (ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK != entry_id_) { - linked_block_ids_.set_allocator(allocator); ObLinkedMacroBlockItemReader block_reader; - if (OB_FAIL(read_block_ids(block_reader))) { - LOG_WARN("fail to read data block ids", K(ret)); - } else if (OB_FAIL(linked_block_ids_.assign(block_reader.get_meta_block_list()))) { + ObMetaDiskAddr addr; + char *reader_buf = nullptr; + int64_t pos = 0; + int64_t reader_len = 0; + if (OB_FAIL(block_reader.init(entry_id_))) { + LOG_WARN("fail to initialize reader", K(ret), K(entry_id_)); + } else if (OB_FAIL(block_reader.get_next_item(reader_buf, reader_len, addr))) {// read data ids + LOG_WARN("fail to get next item", K(ret), K(reader_len), K(addr)); + } else if (OB_FAIL(serialization::decode(reader_buf, reader_len, pos, data_block_count_))) { + LOG_WARN("fail to deserialize data block ids", K(ret)); + } else if (OB_FAIL(block_reader.get_next_item(reader_buf, reader_len, addr))) {// read other ids + LOG_WARN("fail to get next item", K(ret), K(reader_len), K(addr)); + } else if (FALSE_IT(pos = 0)) { + } else if (OB_FAIL(serialization::decode(reader_buf, reader_len, pos, other_block_count_))) { + LOG_WARN("fail to deserialize other block ids", K(ret)); + } else if (OB_FAIL(save_linked_block_list(block_reader.get_meta_block_list(), allocator))) { LOG_WARN("fail to save linked block ids", K(ret), K_(linked_block_ids)); } } else { - if (pos < data_len && OB_FAIL(data_block_ids_.deserialize(buf, data_len, pos))) { + if (pos < data_len && OB_FAIL(deserialize_block_ids(allocator, buf, data_len, pos, + data_block_ids_, data_block_count_))) { LOG_WARN("fail to deserialize data block ids", K(ret), KP(buf), K(data_len), K(pos)); - } else if (pos < data_len && OB_FAIL(other_block_ids_.deserialize(buf, data_len, pos))) { + } else if (pos < data_len && OB_FAIL(deserialize_block_ids(allocator, buf, data_len, pos, + other_block_ids_, other_block_count_))) { LOG_WARN("fail to deserialize other block ids", K(ret), KP(buf), K(data_len), K(pos)); } } @@ -625,28 +819,53 @@ int ObSSTableMacroInfo::deserialize_( return ret; } -int ObSSTableMacroInfo::read_block_ids(storage::ObLinkedMacroBlockItemReader &reader) +int ObSSTableMacroInfo::read_block_ids( + const MacroBlockId &entry_id, + common::ObArenaAllocator &allocator, + MacroBlockId *&data_blk_ids, + int64_t &data_blk_cnt, + MacroBlockId *&other_blk_ids, + int64_t &other_blk_cnt) { int ret = OB_SUCCESS; - if (OB_FAIL(reader.init(entry_id_))) { - LOG_WARN("fail to initialize reader", K(ret), K(ret)); - } else { - ObMetaDiskAddr addr; - char *reader_buf = nullptr; - int64_t reader_len = 0; - int64_t reader_pos = 0; - if (OB_FAIL(reader.get_next_item(reader_buf, reader_len, addr))) { - LOG_WARN("fail to get next item", K(ret), K(reader_len), K(addr)); - } else if (OB_FAIL(data_block_ids_.deserialize(reader_buf, reader_len, reader_pos))) { - LOG_WARN("fail to deserialize data block id array", K(ret), K(reader_len), K(reader_pos)); - } else if (OB_FAIL(reader.get_next_item(reader_buf, reader_len, addr))) { - LOG_WARN("fail to get next item", K(ret), K(reader_len), K(addr)); - } else if (FALSE_IT(reader_pos = 0)) { - } else if (OB_FAIL(other_block_ids_.deserialize(reader_buf, reader_len, reader_pos))) { - LOG_WARN("fail to deserialize other block id array", K(ret), K(reader_len), K(reader_pos)); - } + ObLinkedMacroBlockItemReader block_reader; + if (OB_UNLIKELY(!entry_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(entry_id)); + } else if (OB_FAIL(block_reader.init(entry_id))) { + LOG_WARN("fail to initialize reader", K(ret), K(entry_id)); + } else if (OB_FAIL(read_block_ids(allocator, block_reader, data_blk_ids, data_blk_cnt, + other_blk_ids, other_blk_cnt))) { + LOG_WARN("fail to read block ids", K(ret), K(entry_id), K(data_blk_cnt), K(other_blk_cnt)); } + return ret; +} +int ObSSTableMacroInfo::read_block_ids( + common::ObArenaAllocator &allocator, + storage::ObLinkedMacroBlockItemReader &reader, + MacroBlockId *&data_block_ids, + int64_t &data_block_count, + MacroBlockId *&other_block_ids, + int64_t &other_block_count) +{ + int ret = OB_SUCCESS; + ObMetaDiskAddr addr; + char *reader_buf = nullptr; + int64_t reader_len = 0; + int64_t reader_pos = 0; + if (OB_FAIL(reader.get_next_item(reader_buf, reader_len, addr))) { + LOG_WARN("fail to get next item", K(ret), K(reader_len), K(addr)); + } else if (OB_FAIL(deserialize_block_ids(allocator, reader_buf, reader_len, reader_pos, + data_block_ids, data_block_count))) { + LOG_WARN("fail to deserialize data block id array", K(ret), K(reader_len), K(reader_pos)); + } else if (OB_FAIL(reader.get_next_item(reader_buf, reader_len, addr))) { + LOG_WARN("fail to get next item", K(ret), K(reader_len), K(addr)); + } else if (FALSE_IT(reader_pos = 0)) { + } else if (OB_FAIL(deserialize_block_ids(allocator, reader_buf, reader_len, reader_pos, + other_block_ids, other_block_count))) { + LOG_WARN("fail to deserialize other block id array", K(ret), K(reader_len), K(reader_pos)); + } return ret; } @@ -660,15 +879,40 @@ int64_t ObSSTableMacroInfo::get_serialize_size() const return len; } +int ObSSTableMacroInfo::get_data_block_iter(ObMacroIdIterator &iterator) const +{ + int ret = OB_SUCCESS; + if (ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK == entry_id_) { + if (OB_FAIL(iterator.init(data_block_ids_, data_block_count_))) { + LOG_WARN("fail to init data block iterator", K(ret), K(data_block_count_)); + } + } else if (OB_FAIL(iterator.init(ObMacroIdIterator::DATA_BLOCK, entry_id_))) { + LOG_WARN("fail to init data block iterator", K(ret), K(entry_id_)); + } + return ret; +} + +int ObSSTableMacroInfo::get_other_block_iter(ObMacroIdIterator &iterator) const +{ + int ret = OB_SUCCESS; + if (ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK == entry_id_) { + if (OB_FAIL(iterator.init(other_block_ids_, other_block_count_))) { + LOG_WARN("fail to init other block iterator", K(ret), K(other_block_count_)); + } + } else if (OB_FAIL(iterator.init(ObMacroIdIterator::OTHER_BLOCK, entry_id_))) { + LOG_WARN("fail to init other block iterator", K(ret), K(entry_id_)); + } + return ret; +} + int64_t ObSSTableMacroInfo::get_serialize_size_() const { int64_t len = 0; - MacroBlockId dummy_id; len += macro_meta_info_.get_serialize_size(); - len += dummy_id.get_serialize_size(); - if (data_block_ids_.count() + other_block_ids_.count() < BLOCK_CNT_THRESHOLD) { - len += data_block_ids_.get_serialize_size(); - len += other_block_ids_.get_serialize_size(); + len += entry_id_.get_serialize_size(); + if (ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK == entry_id_) { + OB_UNIS_ADD_LEN_ARRAY(data_block_ids_, data_block_count_); + OB_UNIS_ADD_LEN_ARRAY(other_block_ids_, other_block_count_); } len += serialization::encoded_length_bool(is_meta_root_); len += serialization::encoded_length_i64(nested_offset_); @@ -681,33 +925,40 @@ DEF_TO_STRING(ObSSTableMacroInfo) int64_t pos = 0; J_OBJ_START(); J_KV(K_(macro_meta_info), - K(data_block_ids_.count()), - K(other_block_ids_.count()), - K(linked_block_ids_.count()), - K(is_meta_root_), - K(nested_offset_), - K(nested_size_)); + K_(data_block_count), + K_(other_block_count), + K_(linked_block_count), + KP_(data_block_ids), + KP_(other_block_ids), + KP_(linked_block_ids), + K_(entry_id), + K_(is_meta_root), + K_(nested_offset), + K_(nested_size)); J_OBJ_END(); return pos; } int ObSSTableMacroInfo::write_block_ids( + const common::ObIArray &data_ids, + const common::ObIArray &other_ids, storage::ObLinkedMacroBlockItemWriter &writer, MacroBlockId &entry_id) const { int ret = OB_SUCCESS; const bool need_disk_addr = false; - const int64_t data_blk_cnt = data_block_ids_.count(); - const int64_t other_blk_cnt = other_block_ids_.count(); + const int64_t data_blk_cnt = data_ids.count(); + const int64_t other_blk_cnt = other_ids.count(); if (OB_UNLIKELY(0 == data_blk_cnt && 0 == other_blk_cnt)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("data_blk_cnt and other_blk_cnt shouldn't be both 0", K(ret), K(data_blk_cnt), K(other_blk_cnt)); + LOG_WARN("data_blk_cnt and other_blk_cnt shouldn't be both 0", K(ret), K(data_blk_cnt), + K(other_blk_cnt)); } else if (OB_FAIL(writer.init(need_disk_addr))) { LOG_WARN("fail to initialize item writer", K(ret), K(need_disk_addr)); - } else if (OB_FAIL(flush_ids(data_block_ids_, writer))) { - LOG_WARN("fail to flush data block ids", K(data_block_ids_), K(data_blk_cnt)); - } else if (OB_FAIL(flush_ids(other_block_ids_, writer))) { - LOG_WARN("fail to flush other block ids", K(other_block_ids_), K(data_blk_cnt)); + } else if (OB_FAIL(flush_ids(data_ids, writer))) { + LOG_WARN("fail to flush data block ids", K(ret), K(data_blk_cnt)); + } else if (OB_FAIL(flush_ids(other_ids, writer))) { + LOG_WARN("fail to flush other block ids", KP(ret), K(other_blk_cnt)); } else if (OB_FAIL(writer.close())) { LOG_WARN("fail to close block id writer", K(ret)); } else { @@ -718,28 +969,107 @@ int ObSSTableMacroInfo::write_block_ids( } int ObSSTableMacroInfo::flush_ids( - const MacroIdFixedList &blk_ids, - storage::ObLinkedMacroBlockItemWriter &writer) const + const common::ObIArray &blk_ids, + storage::ObLinkedMacroBlockItemWriter &writer) { int ret = OB_SUCCESS; - const int64_t buf_len = blk_ids.get_serialize_size(); + const int64_t buf_len = serialize_size_of_block_ids(blk_ids.get_data(), blk_ids.count()); const ObMemAttr attr(MTL_ID(), ObModIds::OB_BUFFER); int64_t pos = 0; char *buf = nullptr; - if (OB_ISNULL(buf = static_cast(ob_malloc(buf_len, attr)))) { ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to allocate memory for wirter buf", K(ret), K(buf_len)); - } else if (OB_FAIL(blk_ids.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize id array", K(ret), K(blk_ids), K(buf_len), K(pos)); - } else if (OB_FAIL(writer.write_item(buf, buf_len))) { - LOG_WARN("fail to write block ids", K(ret), KP(buf), K(buf_len)); + LOG_WARN("fail to allocate memory for writer buf", K(ret), K(buf_len)); + } else { + OB_UNIS_ENCODE_ARRAY(blk_ids.get_data(), blk_ids.count()); + if (OB_SUCC(ret)) { + if (OB_FAIL(writer.write_item(buf, buf_len))) { + LOG_WARN("fail to write block ids", K(ret), KP(buf), K(buf_len)); + } + } } if (OB_NOT_NULL(buf)) { ob_free(buf); buf = nullptr; } + return ret; +} +int ObSSTableMacroInfo::deserialize_block_ids( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t data_len, + int64_t &pos, + MacroBlockId *&blk_ids, + int64_t &blk_cnt) +{ + int ret = OB_SUCCESS; + int64_t count = 0; + OB_UNIS_DECODE(count); + if (OB_UNLIKELY(nullptr != blk_ids && 0 != blk_cnt)) { + ret = OB_INIT_TWICE; + LOG_WARN("block id may be initialized", K(ret), KP(blk_ids), K(blk_cnt)); + } else { + if (count > 0 && OB_ISNULL(blk_ids = static_cast(allocator.alloc(sizeof(MacroBlockId) * count)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate block id", K(ret), K(count)); + } else { + OB_UNIS_DECODE_ARRAY(blk_ids, count); + } + if (OB_FAIL(ret) && OB_NOT_NULL(blk_ids)) { + allocator.free(blk_ids); + blk_ids = nullptr; + } else { + blk_cnt = count; + } + } + return ret; +} + +int ObSSTableMacroInfo::deep_copy( + char *buf, + const int64_t buf_len, + int64_t &pos, + ObSSTableMacroInfo &dest) const +{ + int ret = OB_SUCCESS; + int64_t tmp_pos = pos; + const int64_t deep_size = get_variable_size(); + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len < deep_size + pos)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(buf), K(buf_len), K(deep_size), K(pos)); + } else if (OB_FAIL(macro_meta_info_.deep_copy(buf, buf_len, pos, dest.macro_meta_info_))) { + LOG_WARN("fail to deep copy macro meta info", K(ret), KP(buf), K(buf_len), K(pos)); + } else { + if (OB_NOT_NULL(data_block_ids_)) { + dest.data_block_ids_ = reinterpret_cast(buf + pos); + MEMCPY(dest.data_block_ids_, data_block_ids_, sizeof(MacroBlockId) * data_block_count_); + pos += sizeof(MacroBlockId) * data_block_count_; + } else { + dest.data_block_ids_ = nullptr; + } + dest.data_block_count_ = data_block_count_; + if (OB_NOT_NULL(other_block_ids_)) { + dest.other_block_ids_ = reinterpret_cast(buf + pos); + MEMCPY(dest.other_block_ids_, other_block_ids_, sizeof(MacroBlockId) * other_block_count_); + pos += sizeof(MacroBlockId) * other_block_count_; + } else { + dest.other_block_ids_ = nullptr; + } + dest.other_block_count_ = other_block_count_; + if (OB_NOT_NULL(linked_block_ids_)) { + dest.linked_block_ids_ = reinterpret_cast(buf + pos); + MEMCPY(dest.linked_block_ids_, linked_block_ids_, sizeof(MacroBlockId) * linked_block_count_); + pos += sizeof(MacroBlockId) * linked_block_count_; + } else { + dest.linked_block_ids_ = nullptr; + } + dest.linked_block_count_ = linked_block_count_; + dest.entry_id_ = entry_id_; + dest.is_meta_root_ = is_meta_root_; + dest.nested_offset_ = nested_offset_; + dest.nested_size_ = nested_size_; + } return ret; } diff --git a/src/storage/blocksstable/ob_sstable_meta_info.h b/src/storage/blocksstable/ob_sstable_meta_info.h index 27adad57d..2ad6cc476 100644 --- a/src/storage/blocksstable/ob_sstable_meta_info.h +++ b/src/storage/blocksstable/ob_sstable_meta_info.h @@ -14,6 +14,7 @@ #define OCEANBASE_STORAGE_BLOCKSSTABLE_OB_SSTABLE_META_INFO_H_ #include "lib/utility/ob_unify_serialize.h" +#include "lib/container/ob_iarray.h" #include "storage/meta_mem/ob_meta_obj_struct.h" #include "storage/tablet/ob_tablet_create_sstable_param.h" #include "storage/blocksstable/ob_block_sstable_struct.h" @@ -28,6 +29,7 @@ class ObLinkedMacroBlockItemWriter; } namespace blocksstable { + class ObRootBlockInfo final { public: @@ -37,21 +39,33 @@ public: void reset(); int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; int deserialize( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const ObMicroBlockDesMeta &des_meta, const char *buf, const int64_t data_len, int64_t &pos); int64_t get_serialize_size() const; int init_root_block_info( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const storage::ObMetaDiskAddr &addr, const ObMicroBlockData &block_data); - int load_root_block_data(const ObMicroBlockDesMeta &des_meta); - int transform_root_block_data(const ObTableReadInfo &read_info); + int load_root_block_data( + common::ObArenaAllocator &allocator, + const ObMicroBlockDesMeta &des_meta); + int transform_root_block_data(common::ObArenaAllocator &allocator); + int deep_copy( + char *buf, + const int64_t buf_len, + int64_t &pos, + ObRootBlockInfo &other) const; + OB_INLINE int64_t get_variable_size() const + { + return block_data_.total_size(); + } OB_INLINE const storage::ObMetaDiskAddr &get_addr() const { return addr_; } OB_INLINE const ObMicroBlockData &get_block_data() const { return block_data_; } - TO_STRING_KV(K_(addr), K_(block_data), KP_(block_data_allocator)); + + TO_STRING_KV(K_(addr), K_(block_data)); private: static const int64_t ROOT_BLOCK_INFO_VERSION = 1; static int read_block_data( @@ -60,37 +74,59 @@ private: const int64_t buf_len); int serialize_(char *buf, const int64_t buf_len, int64_t &pos) const; int deserialize_( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const ObMicroBlockDesMeta &des_meta, const char *buf, const int64_t data_len, int64_t &pos); int64_t get_serialize_size_() const; - -protected: +private: storage::ObMetaDiskAddr addr_; ObMicroBlockData block_data_; -private: - common::ObIAllocator *block_data_allocator_; DISALLOW_COPY_AND_ASSIGN(ObRootBlockInfo); }; +class ObMacroIdIterator final +{ +public: + enum Type : uint8_t + { + DATA_BLOCK = 0, + OTHER_BLOCK = 1, + MAX = 4, + }; + ObMacroIdIterator(); + ~ObMacroIdIterator() { reset(); } + bool is_valid() const { return is_inited_ && count_ >= 0; } + int init(const Type type, const MacroBlockId &entry_id, const int64_t pos = 0); + int init(MacroBlockId *ptr, const int64_t count, const int64_t pos = 0); + void reset(); + int get_next_macro_id(MacroBlockId ¯o_id); + TO_STRING_KV(K_(value_ptr), K_(pos), K_(count), K_(is_inited)); +private: + MacroBlockId *value_ptr_; + int64_t pos_; + int64_t count_; + bool is_inited_; + common::ObArenaAllocator allocator_; +}; + class ObSSTableMacroInfo final { -public: - typedef common::ObFixedArray MacroIdFixedList; public: ObSSTableMacroInfo(); ~ObSSTableMacroInfo(); int init_macro_info( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const storage::ObTabletCreateSSTableParam ¶m); - int load_root_block_data(const ObMicroBlockDesMeta &des_meta); + int load_root_block_data( + common::ObArenaAllocator &allocator, + const ObMicroBlockDesMeta &des_meta); bool is_valid() const; void reset(); int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; int deserialize( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const ObMicroBlockDesMeta &des_meta, const char *buf, const int64_t data_len, @@ -104,17 +140,14 @@ public: { return macro_meta_info_.get_block_data(); } - OB_INLINE const common::ObIArray &get_data_block_ids() const + OB_INLINE int64_t get_data_block_count() const { return data_block_count_; } + OB_INLINE int64_t get_other_block_count() const { return other_block_count_; } + OB_INLINE int64_t get_linked_block_count() const { return linked_block_count_; } + int get_data_block_iter(ObMacroIdIterator &iterator) const; + int get_other_block_iter(ObMacroIdIterator &iterator) const; + OB_INLINE int get_linked_block_iter(ObMacroIdIterator &iterator) const { - return data_block_ids_; - } - OB_INLINE const common::ObIArray &get_other_block_ids() const - { - return other_block_ids_; - } - OB_INLINE const common::ObIArray &get_linked_block_ids() const - { - return linked_block_ids_; + return iterator.init(linked_block_ids_, linked_block_count_); } OB_INLINE bool is_meta_root() const { @@ -122,8 +155,27 @@ public: } OB_INLINE int64_t get_total_block_cnt() const { - return data_block_ids_.count() + other_block_ids_.count() + linked_block_ids_.count(); + return data_block_count_ + other_block_count_ + linked_block_count_; } + OB_INLINE int64_t get_variable_size() const + { + int64_t blk_ids_cnt = 0; + if (OB_NOT_NULL(data_block_ids_)) { + blk_ids_cnt += data_block_count_; + } + if (OB_NOT_NULL(other_block_ids_)) { + blk_ids_cnt += other_block_count_; + } + if (OB_NOT_NULL(linked_block_ids_)) { + blk_ids_cnt += linked_block_count_; + } + return macro_meta_info_.get_variable_size() + sizeof(MacroBlockId) * blk_ids_cnt; + } + int deep_copy( + char *buf, + const int64_t buf_len, + int64_t &pos, + ObSSTableMacroInfo &dest) const; OB_INLINE int64_t get_nested_offset() const { return nested_offset_; @@ -132,26 +184,62 @@ public: { return nested_size_; } + static int read_block_ids( + const MacroBlockId &entry_id, + common::ObArenaAllocator &allocator, + MacroBlockId *&data_block_ids, + int64_t &data_block_count, + MacroBlockId *&other_block_ids, + int64_t &other_block_count); DECLARE_TO_STRING; private: int serialize_(char *buf, const int64_t buf_len, int64_t &pos) const; int deserialize_( - common::ObIAllocator *allocator, + common::ObArenaAllocator &allocator, const ObMicroBlockDesMeta &des_meta, const char *buf, const int64_t data_len, int64_t &pos); int64_t get_serialize_size_() const; - int read_block_ids(storage::ObLinkedMacroBlockItemReader &reader); + static int read_block_ids( + common::ObArenaAllocator &allocator, + storage::ObLinkedMacroBlockItemReader &reader, + MacroBlockId *&data_block_ids, + int64_t &data_block_count, + MacroBlockId *&other_block_ids, + int64_t &other_block_count); + int persist_block_ids( + const common::ObIArray &data_ids, + const common::ObIArray &other_ids, + common::ObArenaAllocator &allocator); int write_block_ids( + const common::ObIArray &data_ids, + const common::ObIArray &other_ids, storage::ObLinkedMacroBlockItemWriter &writer, MacroBlockId &entry_id) const; - int flush_ids( - const MacroIdFixedList &blk_ids, - storage::ObLinkedMacroBlockItemWriter &writer) const; + static int flush_ids( + const common::ObIArray &blk_ids, + storage::ObLinkedMacroBlockItemWriter &writer); int save_linked_block_list( const common::ObIArray &list, - common::ObIArray &linked_list) const; + common::ObArenaAllocator &allocator); + int inc_linked_block_ref_cnt(common::ObArenaAllocator &allocator); + void dec_linked_block_ref_cnt(); + static int deserialize_block_ids( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t data_len, + int64_t &pos, + MacroBlockId *&blk_ids, + int64_t &blk_cnt); + static int64_t serialize_size_of_block_ids( + const MacroBlockId *blk_ids, + const int64_t blk_cnt) + { + int64_t len = 0; + OB_UNIS_ADD_LEN_ARRAY(blk_ids, blk_cnt); + return len; + } private: friend class ObSSTable; @@ -160,9 +248,12 @@ private: static const int64_t BLOCK_CNT_THRESHOLD = 15000; // 15000 ids, represents 30G data + metadata private: ObRootBlockInfo macro_meta_info_; - MacroIdFixedList data_block_ids_; - MacroIdFixedList other_block_ids_; - MacroIdFixedList linked_block_ids_; + MacroBlockId *data_block_ids_; + MacroBlockId *other_block_ids_; + MacroBlockId *linked_block_ids_; + int64_t data_block_count_; + int64_t other_block_count_; + int64_t linked_block_count_; MacroBlockId entry_id_; bool is_meta_root_; int64_t nested_offset_; diff --git a/src/storage/blocksstable/ob_sstable_printer.cpp b/src/storage/blocksstable/ob_sstable_printer.cpp index 506f1ca24..f09dc9666 100644 --- a/src/storage/blocksstable/ob_sstable_printer.cpp +++ b/src/storage/blocksstable/ob_sstable_printer.cpp @@ -253,6 +253,11 @@ void ObSSTablePrinter::print_cell(const ObObj &cell) P_VALUE_STR_B(to_cstring(cell)); } +void ObSSTablePrinter::print_cell(const ObStorageDatum &datum) +{ + P_VALUE_STR_B(to_cstring(datum)); +} + void ObSSTablePrinter::print_common_header(const ObMacroBlockCommonHeader *common_header) { print_title("Common Header"); @@ -479,7 +484,7 @@ void ObSSTablePrinter::print_bloom_filter_micro_block(const char* micro_block_bu void ObSSTablePrinter::print_store_row( const ObDatumRow *row, const ObObjMeta *obj_metas, - const int64_t rowkey_column_cnt, + const int64_t type_array_column_cnt, const bool is_index_block, const bool is_trans_sstable) { @@ -522,11 +527,8 @@ void ObSSTablePrinter::print_store_row( } } else { ObObj obj; - for (int64_t i = 0; i < row->get_column_count(); ++i) { + for (int64_t i = 0; i < type_array_column_cnt; ++i) { ObObjMeta column_meta = obj_metas[i]; - if (is_index_block && i == rowkey_column_cnt) { - column_meta.set_varbinary(); - } if (OB_FAIL(row->storage_datums_[i].to_obj_enhance(obj, column_meta))) { STORAGE_LOG(WARN, "Fail to transform storage datum to obj", K(ret), K(i), K(column_meta), KPC(row)); @@ -534,6 +536,20 @@ void ObSSTablePrinter::print_store_row( print_cell(obj); } } + for (int64_t i = type_array_column_cnt; i < row->get_column_count(); ++i) { + if (is_index_block && i == type_array_column_cnt) { + ObObjMeta column_meta; + column_meta.set_varbinary(); + if (OB_FAIL(row->storage_datums_[i].to_obj_enhance(obj, column_meta))) { + STORAGE_LOG(WARN, "Fail to transform storage datum to obj", K(ret), K(i), K(column_meta), + KPC(row)); + } else { + print_cell(obj); + } + } else { + print_cell(row->storage_datums_[i]); + } + } } P_END(); } diff --git a/src/storage/blocksstable/ob_sstable_printer.h b/src/storage/blocksstable/ob_sstable_printer.h index 89c36e566..00a1844a6 100644 --- a/src/storage/blocksstable/ob_sstable_printer.h +++ b/src/storage/blocksstable/ob_sstable_printer.h @@ -52,6 +52,7 @@ public: static void print_line(const char *name, const char *value, const int64_t level = 1); static void print_row_title(const blocksstable::ObDatumRow *row, const int64_t row_index); static void print_cell(const common::ObObj &cell); + static void print_cell(const blocksstable::ObStorageDatum &datum); static void print_end_line(const int64_t level = 1); static void print_cols_info_start(const char *n1, const char *n2, const char *n3, const char *n4, const char *n5); static void print_cols_info_line(const int32_t &v1, const common::ObObjType v2, const common::ObOrderType v3, const int64_t &v4, const int64_t & v5); @@ -68,7 +69,7 @@ public: static void print_store_row( const blocksstable::ObDatumRow *row, const ObObjMeta *obj_metas, - const int64_t rowkey_column_cnt, + const int64_t type_array_column_cnt, const bool is_index_block, const bool is_trans_sstable); static void print_store_row_hex(const blocksstable::ObDatumRow *row, const ObObjMeta *obj_metas, const int64_t buf_size, char *hex_print_buf); diff --git a/src/storage/blocksstable/ob_sstable_sec_meta_iterator.cpp b/src/storage/blocksstable/ob_sstable_sec_meta_iterator.cpp index 5abdaf90f..eef994742 100644 --- a/src/storage/blocksstable/ob_sstable_sec_meta_iterator.cpp +++ b/src/storage/blocksstable/ob_sstable_sec_meta_iterator.cpp @@ -25,20 +25,20 @@ namespace blocksstable { ObSSTableSecMetaIterator::ObSSTableSecMetaIterator() - : sstable_meta_(nullptr), index_read_info_(nullptr), tenant_id_(OB_INVALID_TENANT_ID), + : tenant_id_(OB_INVALID_TENANT_ID), rowkey_read_info_(nullptr), sstable_meta_hdl_(), prefetch_flag_(), idx_cursor_(), macro_reader_(), block_cache_(nullptr), micro_reader_(nullptr), micro_reader_helper_(), block_meta_tree_(nullptr), query_range_(nullptr), start_bound_micro_block_(), end_bound_micro_block_(), micro_handles_(), row_(), curr_handle_idx_(0), prefetch_handle_idx_(0), prev_block_row_cnt_(0), curr_block_start_idx_(0), curr_block_end_idx_(0), curr_block_idx_(0), step_cnt_(0), - is_reverse_scan_(false), is_prefetch_end_(false), + row_store_type_(ObRowStoreType::MAX_ROW_STORE), is_reverse_scan_(false), is_prefetch_end_(false), is_range_end_key_multi_version_(false), is_inited_(false) {} void ObSSTableSecMetaIterator::reset() { - sstable_meta_ = nullptr; - index_read_info_ = nullptr; + rowkey_read_info_ = nullptr; tenant_id_ = OB_INVALID_TENANT_ID; + sstable_meta_hdl_.reset(); prefetch_flag_.reset(); idx_cursor_.reset(); block_cache_ = nullptr; @@ -54,6 +54,7 @@ void ObSSTableSecMetaIterator::reset() curr_block_end_idx_ = 0; curr_block_idx_ = 0; step_cnt_ = 0; + row_store_type_ = ObRowStoreType::MAX_ROW_STORE; is_reverse_scan_ = false; is_prefetch_end_ = false; is_range_end_key_multi_version_ = false; @@ -64,7 +65,7 @@ int ObSSTableSecMetaIterator::open( const ObDatumRange &query_range, const ObMacroBlockMetaType meta_type, const ObSSTable &sstable, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse_scan, const int64_t sample_step) @@ -80,31 +81,32 @@ int ObSSTableSecMetaIterator::open( ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument to open sstable secondary meta iterator", K(ret), K(query_range), K(sstable), K(meta_type)); - } else if (is_sstable_meta_empty(meta_type, sstable.get_meta())) { + } else if (sstable.is_empty()) { set_iter_end(); is_inited_ = true; LOG_DEBUG("Empty sstable secondary meta", K(ret), K(meta_type), K(sstable)); + } else if (OB_FAIL(sstable.get_meta(sstable_meta_hdl_))) { + LOG_WARN("get meta handle fail", K(ret), K(sstable)); } else { - sstable_meta_ = &sstable.get_meta(); - index_read_info_ = &index_read_info; + rowkey_read_info_ = &rowkey_read_info; tenant_id_ = MTL_ID(); prefetch_flag_.set_not_use_block_cache(); query_range_ = &query_range; is_reverse_scan_ = is_reverse_scan; block_cache_ = &ObStorageCacheSuite::get_instance().get_block_cache(); - is_meta_root = sstable_meta_->get_macro_info().is_meta_root(); + is_meta_root = sstable_meta_hdl_.get_sstable_meta().get_macro_info().is_meta_root(); } if (OB_FAIL(ret) || is_prefetch_end_) { } else if (sstable.is_ddl_mem_sstable()) { - const ObMicroBlockData &root_block = sstable.get_meta().get_root_info().get_block_data(); + const ObMicroBlockData &root_block = sstable_meta_hdl_.get_sstable_meta().get_root_info().get_block_data(); if (ObMicroBlockData::DDL_BLOCK_TREE != root_block.type_ || nullptr == root_block.buf_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("block type is not ddl block tree", K(ret), K(root_block)); } else { block_meta_tree_ = reinterpret_cast(const_cast(root_block.buf_)); if (OB_FAIL(block_meta_tree_->locate_range(query_range, - index_read_info.get_datum_utils(), + rowkey_read_info.get_datum_utils(), true, //is_left_border true, //is_right_border, curr_block_start_idx_, @@ -117,19 +119,21 @@ int ObSSTableSecMetaIterator::open( is_inited_ = true; } } - } else if (OB_FAIL(idx_cursor_.init(sstable, allocator, index_read_info_, + } else if (OB_FAIL(idx_cursor_.init(sstable, allocator, rowkey_read_info_, get_index_tree_type_map()[meta_type]))) { LOG_WARN("Fail to init index block tree cursor", K(ret), K(meta_type)); - } else if (OB_FAIL(init_micro_reader( - static_cast(sstable.get_meta().get_basic_meta().root_row_store_type_), - allocator))) { - LOG_WARN("Fail to get root row store type", K(ret), K(sstable)); + } else if (OB_FAIL(micro_reader_helper_.init(allocator))) { + LOG_WARN("Fail to init micro reader helper", K(ret), K(sstable)); } else { - const int64_t schema_rowkey_cnt = sstable.get_meta().get_basic_meta().rowkey_column_count_ - - ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + const int64_t schema_rowkey_cnt = rowkey_read_info.get_schema_rowkey_count(); + is_range_end_key_multi_version_ = schema_rowkey_cnt < query_range.get_end_key().get_datum_cnt(); } + + const int64_t request_col_cnt = rowkey_read_info.get_schema_rowkey_count() + + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt() + 1; + if (OB_SUCC(ret) && !is_prefetch_end_ && !is_meta_root) { bool start_key_beyond_range = false; bool end_key_beyond_range = false; @@ -176,7 +180,7 @@ int ObSSTableSecMetaIterator::open( is_inited_ = true; } else if (!is_meta_root && OB_FAIL(prefetch_micro_block(1 /* fetch first micro block */))) { LOG_WARN("Fail to prefetch next micro block", K(ret), K_(is_prefetch_end)); - } else if (OB_FAIL(row_.init(allocator, index_read_info_->get_request_count()))) { + } else if (OB_FAIL(row_.init(allocator, request_col_cnt))) { STORAGE_LOG(WARN, "Failed to init datum row", K(ret)); } else { if (sample_step != 0) { @@ -201,6 +205,7 @@ int ObSSTableSecMetaIterator::open( int ObSSTableSecMetaIterator::get_next(ObDataMacroBlockMeta ¯o_meta) { int ret = OB_SUCCESS; + MacroBlockId macro_id; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("Secondary meta iterator not inited", K(ret)); @@ -217,8 +222,8 @@ int ObSSTableSecMetaIterator::get_next(ObDataMacroBlockMeta ¯o_meta) if (is_prefetch_end_ && is_handle_buffer_empty()) { ret = OB_ITER_END; } else { - const bool is_data_block = sstable_meta_->get_macro_info().is_meta_root(); - if (!is_data_block && OB_FAIL(open_next_micro_block())) { + const bool is_data_block = sstable_meta_hdl_.get_sstable_meta().get_macro_info().is_meta_root(); + if (!is_data_block && OB_FAIL(open_next_micro_block(macro_id))) { if (OB_UNLIKELY(OB_ITER_END != ret)) { LOG_WARN("Fail to open next micro block", K(ret)); } @@ -233,9 +238,12 @@ int ObSSTableSecMetaIterator::get_next(ObDataMacroBlockMeta ¯o_meta) } else if (OB_FAIL(macro_meta.parse_row(row_))) { LOG_WARN("Fail to parse macro meta", K(ret)); } else { - const ObSSTableMacroInfo ¯o_info = sstable_meta_->get_macro_info(); - if (!macro_info.is_meta_root() && 0 == macro_info.get_other_block_ids().count()) { - macro_meta.val_.macro_id_ = macro_info.get_data_block_ids().at(0); + const ObSSTableMacroInfo ¯o_info = sstable_meta_hdl_.get_sstable_meta().get_macro_info(); + if (!macro_info.is_meta_root() && 0 == macro_info.get_other_block_count()) { + // this means macro meta root block is larger than 16KB but read from the end of data block + // So the macro id parsed from macro meta is empty, which actually should be same to the + // data block id read in open_next_micro_block + macro_meta.val_.macro_id_ = macro_id; } curr_block_idx_ += step_cnt_; macro_meta.nested_size_ = macro_info.get_nested_size(); @@ -245,15 +253,6 @@ int ObSSTableSecMetaIterator::get_next(ObDataMacroBlockMeta ¯o_meta) return ret; } -bool ObSSTableSecMetaIterator::is_sstable_meta_empty( - const ObMacroBlockMetaType meta_type, - const ObSSTableMeta &sstable_meta) -{ - const bool is_empty = sstable_meta.is_empty(); - const bool is_data_macro_meta_empty = sstable_meta.get_macro_info().get_macro_meta_addr().is_none(); - return is_empty - || (ObMacroBlockMetaType::DATA_BLOCK_META == meta_type && is_data_macro_meta_empty); -} void ObSSTableSecMetaIterator::set_iter_end() { @@ -265,19 +264,6 @@ void ObSSTableSecMetaIterator::set_iter_end() curr_handle_idx_ = 0; } -int ObSSTableSecMetaIterator::init_micro_reader( - const ObRowStoreType row_store_type, - ObIAllocator &allocator) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(micro_reader_helper_.init(allocator))) { - LOG_WARN("Failed to init micro reader helper", K(ret)); - } else if (OB_FAIL(micro_reader_helper_.get_reader(row_store_type, micro_reader_))) { - LOG_WARN("Failed to get micro block reader", K(ret), K(row_store_type)); - } - return ret; -} - int ObSSTableSecMetaIterator::locate_bound_micro_block( const ObDatumRowkey &rowkey, const bool lower_bound, @@ -309,9 +295,10 @@ int ObSSTableSecMetaIterator::locate_bound_micro_block( return ret; } -int ObSSTableSecMetaIterator::open_next_micro_block() +int ObSSTableSecMetaIterator::open_next_micro_block(MacroBlockId ¯o_id) { int ret = OB_SUCCESS; + macro_id.reset(); int64_t row_cnt = 0; int64_t begin_idx = 0; int64_t end_idx = 0; @@ -324,12 +311,15 @@ int ObSSTableSecMetaIterator::open_next_micro_block() } else if (OB_UNLIKELY(!micro_data.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid micro block data", K(ret), K(micro_data)); - } else if (OB_FAIL(micro_reader_->init(micro_data, *index_read_info_))) { + } else if (OB_FAIL(micro_reader_helper_.get_reader(micro_data.get_store_type(), micro_reader_))) { + LOG_WARN("fail to get micro block reader", K(ret), K(micro_data.get_store_type())); + } else if (OB_FAIL(micro_reader_->init(micro_data, &(rowkey_read_info_->get_datum_utils())))) { LOG_WARN("Fail to init micro block reader", K(ret)); } else if (OB_FAIL(micro_reader_->get_row_count(row_cnt))) { LOG_WARN("Fail to get end index", K(ret)); } else { end_idx = row_cnt; + macro_id = micro_handle.macro_block_id_; ObMicroBlockId block_id( micro_handle.macro_block_id_, micro_handle.micro_info_.offset_, @@ -366,14 +356,16 @@ int ObSSTableSecMetaIterator::open_next_micro_block() int ObSSTableSecMetaIterator::open_meta_root_block() { int ret = OB_SUCCESS; - const ObMicroBlockData µ_data = sstable_meta_->get_macro_info().get_macro_meta_data(); + const ObMicroBlockData µ_data = sstable_meta_hdl_.get_sstable_meta().get_macro_info().get_macro_meta_data(); int64_t row_cnt = 0; int64_t begin_idx = 0; int64_t end_idx = 0; if (OB_UNLIKELY(!micro_data.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid micro block data", K(ret), K(micro_data)); - } else if (OB_FAIL(micro_reader_->init(micro_data, *index_read_info_))) { + } else if (OB_FAIL(micro_reader_helper_.get_reader(micro_data.get_store_type(), micro_reader_))) { + LOG_WARN("fail to get micro block reader", K(ret), K(micro_data.get_store_type())); + } else if (OB_FAIL(micro_reader_->init(micro_data, &(rowkey_read_info_->get_datum_utils())))) { LOG_WARN("Fail to init micro block reader", K(ret)); } else if (OB_FAIL(micro_reader_->get_row_count(row_cnt))) { LOG_WARN("Fail to get end index", K(ret)); @@ -501,7 +493,7 @@ int ObSSTableSecMetaIterator::get_micro_block( int ret = OB_SUCCESS; data_handle.reset(); ObTabletHandle tablet_handle; - const int64_t nested_offset = sstable_meta_->get_macro_info().get_nested_offset(); + const int64_t nested_offset = sstable_meta_hdl_.get_sstable_meta().get_macro_info().get_nested_offset(); if (OB_UNLIKELY(!macro_id.is_valid() || !idx_row_header.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid parameters to locate micro block", K(ret), K(macro_id), K(idx_row_header)); @@ -528,8 +520,6 @@ int ObSSTableSecMetaIterator::get_micro_block( macro_id, idx_info, prefetch_flag_, - *index_read_info_, - tablet_handle, data_handle.io_handle_))) { LOG_WARN("Fail to prefetch with async io", K(ret)); } else { diff --git a/src/storage/blocksstable/ob_sstable_sec_meta_iterator.h b/src/storage/blocksstable/ob_sstable_sec_meta_iterator.h index a27749b50..62c39a853 100644 --- a/src/storage/blocksstable/ob_sstable_sec_meta_iterator.h +++ b/src/storage/blocksstable/ob_sstable_sec_meta_iterator.h @@ -35,7 +35,7 @@ public: const ObDatumRange &query_range, const ObMacroBlockMetaType meta_type, const ObSSTable &sstable, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse_scan = false, const int64_t sample_step = 0); @@ -43,12 +43,9 @@ public: TO_STRING_KV(K_(is_reverse_scan), K_(is_inited), K_(start_bound_micro_block), K_(end_bound_micro_block), K_(idx_cursor), K_(curr_handle_idx), K_(prefetch_handle_idx), K_(prev_block_row_cnt), K_(curr_block_start_idx), K_(curr_block_end_idx), K_(curr_block_idx), - K_(step_cnt), K_(is_prefetch_end), KPC_(query_range), KPC_(index_read_info)); + K_(step_cnt), K_(is_prefetch_end), KPC_(query_range), KPC_(rowkey_read_info)); private: - static bool is_sstable_meta_empty( - const ObMacroBlockMetaType meta_type, - const ObSSTableMeta &sstable_meta); void set_iter_end(); int adjust_index(const int64_t begin_idx, const int64_t end_idx, const int64_t row_cnt); int init_micro_reader(const ObRowStoreType row_store_type, ObIAllocator &allocator); @@ -70,7 +67,7 @@ private: ObMicroBlockId &bound_block, bool &is_beyond_range); int prefetch_micro_block(int64_t prefetch_depth); - int open_next_micro_block(); + int open_next_micro_block(MacroBlockId ¯o_id); int open_meta_root_block(); // TODO: opt with prefetch @@ -81,9 +78,9 @@ private: private: static const int32_t HANDLE_BUFFER_SIZE = 16; static const int32_t MAX_SECONDAY_META_COLUMN_COUNT = OB_MAX_ROWKEY_COLUMN_NUMBER + 3; - const ObSSTableMeta *sstable_meta_; - const ObTableReadInfo *index_read_info_; int64_t tenant_id_; + const ObITableReadInfo *rowkey_read_info_; + ObSSTableMetaHandle sstable_meta_hdl_; common::ObQueryFlag prefetch_flag_; ObIndexBlockTreeCursor idx_cursor_; ObMacroBlockReader macro_reader_; @@ -103,6 +100,7 @@ private: int64_t curr_block_end_idx_; int64_t curr_block_idx_; int64_t step_cnt_; + ObRowStoreType row_store_type_; bool is_reverse_scan_; bool is_prefetch_end_; bool is_range_end_key_multi_version_; diff --git a/src/storage/blocksstable/ob_storage_cache_suite.cpp b/src/storage/blocksstable/ob_storage_cache_suite.cpp index c2fbe6f17..d56992ea5 100644 --- a/src/storage/blocksstable/ob_storage_cache_suite.cpp +++ b/src/storage/blocksstable/ob_storage_cache_suite.cpp @@ -24,6 +24,7 @@ ObStorageCacheSuite::ObStorageCacheSuite() user_row_cache_(), bf_cache_(), fuse_row_cache_(), + storage_meta_cache_(), is_inited_(false) { } @@ -45,7 +46,8 @@ int ObStorageCacheSuite::init( const int64_t user_row_cache_priority, const int64_t fuse_row_cache_priority, const int64_t bf_cache_priority, - const int64_t bf_cache_miss_count_threshold) + const int64_t bf_cache_miss_count_threshold, + const int64_t storage_meta_cache_priority) { int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { @@ -63,6 +65,8 @@ int ObStorageCacheSuite::init( STORAGE_LOG(ERROR, "failed to set bf_cache_miss_count_threshold", K(ret)); } else if (OB_FAIL(fuse_row_cache_.init("fuse_row_cache", fuse_row_cache_priority))) { STORAGE_LOG(ERROR, "fail to init fuse row cache", K(ret)); + } else if (OB_FAIL(storage_meta_cache_.init("storage_meta_cache", storage_meta_cache_priority))) { + STORAGE_LOG(ERROR, "fail to init storage meta cache", K(ret), K(storage_meta_cache_priority)); } else { is_inited_ = true; } @@ -79,7 +83,8 @@ int ObStorageCacheSuite::reset_priority( const int64_t user_block_cache_priority, const int64_t user_row_cache_priority, const int64_t fuse_row_cache_priority, - const int64_t bf_cache_priority) + const int64_t bf_cache_priority, + const int64_t storage_meta_cache_priority) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { @@ -95,6 +100,8 @@ int ObStorageCacheSuite::reset_priority( STORAGE_LOG(ERROR, "set priority for bloom filter cache failed, ", K(ret)); } else if (OB_FAIL(fuse_row_cache_.set_priority(fuse_row_cache_priority))) { STORAGE_LOG(ERROR, "fail to set priority for fuse row cache", K(ret)); + } else if (OB_FAIL(storage_meta_cache_.set_priority(storage_meta_cache_priority))) { + STORAGE_LOG(ERROR, "fail to set priority for storage cache", K(ret), K(storage_meta_cache_priority)); } return ret; } @@ -115,6 +122,7 @@ void ObStorageCacheSuite::destroy() user_row_cache_.destroy(); bf_cache_.destroy(); fuse_row_cache_.destroy(); + storage_meta_cache_.destory(); is_inited_ = false; } diff --git a/src/storage/blocksstable/ob_storage_cache_suite.h b/src/storage/blocksstable/ob_storage_cache_suite.h index 65da457fa..6f6d1178f 100644 --- a/src/storage/blocksstable/ob_storage_cache_suite.h +++ b/src/storage/blocksstable/ob_storage_cache_suite.h @@ -13,6 +13,7 @@ #ifndef __OCEANBASE_BLOCKSSTABLE_STORAGE_CACHE_SUITE_H__ #define __OCEANBASE_BLOCKSSTABLE_STORAGE_CACHE_SUITE_H__ +#include "storage/meta_mem/ob_storage_meta_cache.h" #include "share/schema/ob_table_schema.h" #include "ob_micro_block_cache.h" #include "ob_row_cache.h" @@ -36,19 +37,22 @@ public: const int64_t user_row_cache_priority, const int64_t fuse_row_cache_priority, const int64_t bf_cache_priority, - const int64_t bf_cache_miss_count_threshold); + const int64_t bf_cache_miss_count_threshold, + const int64_t storage_meta_cache_priority); int reset_priority( const int64_t index_block_cache_priority, const int64_t user_block_cache_priority, const int64_t user_row_cache_priority, const int64_t fuse_row_cache_priority, - const int64_t bf_cache_priority); + const int64_t bf_cache_priority, + const int64_t storage_meta_cache_priority); int set_bf_cache_miss_count_threshold(const int64_t bf_cache_miss_count_threshold); ObDataMicroBlockCache &get_block_cache() { return user_block_cache_; } ObIndexMicroBlockCache &get_index_block_cache() { return index_block_cache_; } ObRowCache &get_row_cache() { return user_row_cache_; } ObBloomFilterCache &get_bf_cache() { return bf_cache_; } ObFuseRowCache &get_fuse_row_cache() { return fuse_row_cache_; } + ObStorageMetaCache &get_storage_meta_cache() { return storage_meta_cache_; } void destroy(); inline bool is_inited() const { return is_inited_; } TO_STRING_KV(K(is_inited_)); @@ -60,6 +64,7 @@ private: ObRowCache user_row_cache_; ObBloomFilterCache bf_cache_; ObFuseRowCache fuse_row_cache_; + ObStorageMetaCache storage_meta_cache_; bool is_inited_; private: DISALLOW_COPY_AND_ASSIGN(ObStorageCacheSuite); diff --git a/src/storage/blocksstable/ob_tmp_file_cache.cpp b/src/storage/blocksstable/ob_tmp_file_cache.cpp index 0eb85afea..2c6ac7676 100644 --- a/src/storage/blocksstable/ob_tmp_file_cache.cpp +++ b/src/storage/blocksstable/ob_tmp_file_cache.cpp @@ -217,43 +217,20 @@ int ObTmpPageCache::get_cache_page(const ObTmpPageCacheKey &key, ObTmpPageValueH } ObTmpPageCache::ObITmpPageIOCallback::ObITmpPageIOCallback() - : cache_(NULL), allocator_(NULL), offset_(0), buf_size_(0), io_buf_(NULL), - io_buf_size_(0), data_buf_(NULL) + : cache_(NULL), allocator_(NULL), offset_(0), buf_size_(0), data_buf_(NULL) { static_assert(sizeof(*this) <= CALLBACK_BUF_SIZE, "IOCallback buf size not enough"); } ObTmpPageCache::ObITmpPageIOCallback::~ObITmpPageIOCallback() { - if (NULL != allocator_ && NULL != io_buf_) { - allocator_->free(io_buf_); - io_buf_ = NULL; + if (NULL != allocator_ && NULL != data_buf_) { + allocator_->free(data_buf_); data_buf_ = NULL; allocator_ = NULL; } } -int ObTmpPageCache::ObITmpPageIOCallback::alloc_io_buf( - char *&io_buf, int64_t &io_buf_size, int64_t &aligned_offset) -{ - int ret = OB_SUCCESS; - io_buf_size = 0; - aligned_offset = 0; - common::align_offset_size(offset_, buf_size_, aligned_offset, io_buf_size); - io_buf_size_ = io_buf_size + DIO_READ_ALIGN_SIZE; - if (OB_ISNULL(allocator_)) { - ret = OB_INVALID_DATA; - STORAGE_LOG(WARN, "Invalid data, the allocator is NULL, ", K(ret)); - } else if (OB_UNLIKELY(NULL == (io_buf_ = (char*) (allocator_->alloc(io_buf_size_))))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - STORAGE_LOG(ERROR, "Fail to allocate memory, ", K(ret)); - } else { - io_buf = upper_align_buf(io_buf_, DIO_READ_ALIGN_SIZE); - data_buf_ = io_buf + (offset_ - aligned_offset); - } - return ret; -} - int ObTmpPageCache::ObITmpPageIOCallback::process_page( const ObTmpPageCacheKey &key, const ObTmpPageCacheValue &value) { @@ -275,23 +252,30 @@ ObTmpPageCache::ObTmpPageIOCallback::ObTmpPageIOCallback() ObTmpPageCache::ObTmpPageIOCallback::~ObTmpPageIOCallback() { + } -int ObTmpPageCache::ObTmpPageIOCallback::inner_process(const bool is_success) +int ObTmpPageCache::ObTmpPageIOCallback::inner_process(const char *data_buffer, const int64_t size) { int ret = OB_SUCCESS; - if (OB_ISNULL(cache_)) { + if (OB_ISNULL(cache_) || OB_ISNULL(allocator_)) { ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "Invalid tmp page cache callback, ", KP_(cache), K(ret)); - } else if (is_success) { - ObTmpPageCacheValue value(const_cast(get_data())); + STORAGE_LOG(WARN, "Invalid tmp page cache callback or allocator", KP_(cache), KP_(allocator), K(ret)); + } else if (OB_UNLIKELY(size <= 0 || data_buffer == nullptr)) { + ret = OB_INVALID_DATA; + STORAGE_LOG(WARN, "invalid data buffer size", K(ret), K(size), KP(data_buffer)); + } else if (OB_UNLIKELY(NULL == (data_buf_ = (char*) (allocator_->alloc(size))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "Fail to allocate memory, ", K(ret), K(size)); + } else { + MEMCPY(data_buf_, data_buffer, size); + ObTmpPageCacheValue value(data_buf_); if (OB_FAIL(process_page(key_, value))) { STORAGE_LOG(WARN, "fail to process tmp page cache in callback", K(ret)); } } - if (OB_FAIL(ret) && NULL != allocator_ && NULL != io_buf_) { - allocator_->free(io_buf_); - io_buf_ = NULL; + if (OB_FAIL(ret) && NULL != allocator_ && NULL != data_buf_) { + allocator_->free(data_buf_); data_buf_ = NULL; } return ret; @@ -337,28 +321,33 @@ ObTmpPageCache::ObTmpMultiPageIOCallback::~ObTmpMultiPageIOCallback() page_io_infos_.~ObIArray(); } -int ObTmpPageCache::ObTmpMultiPageIOCallback::inner_process(const bool is_success) +int ObTmpPageCache::ObTmpMultiPageIOCallback::inner_process(const char *data_buffer, const int64_t size) { int ret = OB_SUCCESS; - if (OB_ISNULL(cache_)) { + if (OB_ISNULL(cache_) || OB_ISNULL(allocator_)) { ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "Invalid tmp page cache callback, ", KP_(cache), K(ret)); - } else if (is_success) { - char *buf = const_cast(get_data()); + STORAGE_LOG(WARN, "Invalid tmp page cache callbackor allocator", KP_(cache), KP_(allocator), K(ret)); + } else if (OB_UNLIKELY(size <= 0 || data_buffer == nullptr)) { + ret = OB_INVALID_DATA; + STORAGE_LOG(WARN, "invalid data buffer size", K(ret), K(size), KP(data_buffer)); + } else if (OB_UNLIKELY(NULL == (data_buf_ = (char*) (allocator_->alloc(size))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "Fail to allocate memory, ", K(ret), K(size)); + } else { + MEMCPY(data_buf_, data_buffer, size); for (int32_t i = 0; OB_SUCC(ret) && i < page_io_infos_.count(); i++) { - int64_t offset = page_io_infos_.at(i).key_.get_page_id() + int64_t cur_offset = page_io_infos_.at(i).key_.get_page_id() * ObTmpMacroBlock::get_default_page_size() - offset_; - offset += ObTmpMacroBlock::get_header_padding(); - ObTmpPageCacheValue value(buf + offset); + cur_offset += ObTmpMacroBlock::get_header_padding(); + ObTmpPageCacheValue value(data_buf_ + cur_offset); if (OB_FAIL(process_page(page_io_infos_.at(i).key_, value))) { STORAGE_LOG(WARN, "fail to process tmp page cache in callback", K(ret)); } } page_io_infos_.reset(); } - if (OB_FAIL(ret) && NULL != allocator_ && NULL != io_buf_) { - allocator_->free(io_buf_); - io_buf_ = NULL; + if (OB_FAIL(ret) && NULL != allocator_ && NULL != data_buf_) { + allocator_->free(data_buf_); data_buf_ = NULL; } return ret; @@ -406,9 +395,10 @@ int ObTmpPageCache::read_io(const ObTmpBlockIOInfo &io_info, ObITmpPageIOCallbac read_info.io_desc_ = io_info.io_desc_; read_info.macro_block_id_ = io_info.macro_block_id_; read_info.io_callback_ = &callback; - common::align_offset_size(io_info.offset_, io_info.size_, read_info.offset_, read_info.size_); + read_info.offset_ = io_info.offset_; + read_info.size_ = io_info.size_; if (OB_FAIL(ObBlockManager::async_read_block(read_info, handle))) { - STORAGE_LOG(WARN, "fail to async read block", K(ret)); + STORAGE_LOG(WARN, "fail to async read block", K(ret), K(read_info)); } return ret; } diff --git a/src/storage/blocksstable/ob_tmp_file_cache.h b/src/storage/blocksstable/ob_tmp_file_cache.h index 7f9c728b2..3d53f8d0f 100644 --- a/src/storage/blocksstable/ob_tmp_file_cache.h +++ b/src/storage/blocksstable/ob_tmp_file_cache.h @@ -124,8 +124,6 @@ public: public: ObITmpPageIOCallback(); virtual ~ObITmpPageIOCallback(); - virtual int alloc_io_buf(char *&io_buf, int64_t &io_buf_size, - int64_t &aligned_offset) override; protected: friend class ObTmpPageCache; virtual int process_page(const ObTmpPageCacheKey &key, const ObTmpPageCacheValue &value); @@ -135,8 +133,6 @@ public: common::ObIAllocator *allocator_; int64_t offset_; // offset in block int64_t buf_size_; // read size in block - char *io_buf_; // for io assign - int64_t io_buf_size_; char *data_buf_; // actual data buffer }; class ObTmpPageIOCallback final : public ObITmpPageIOCallback @@ -145,7 +141,7 @@ public: ObTmpPageIOCallback(); ~ObTmpPageIOCallback(); int64_t size() const override; - int inner_process(const bool is_success) override; + int inner_process(const char *data_buffer, const int64_t size) override; int inner_deep_copy(char *buf, const int64_t buf_len, ObIOCallback *&callback) const override; const char *get_data() override; TO_STRING_KV(KP_(data_buf)); @@ -159,7 +155,7 @@ public: ObTmpMultiPageIOCallback(); ~ObTmpMultiPageIOCallback(); int64_t size() const override; - int inner_process(const bool is_success) override; + int inner_process(const char *data_buffer, const int64_t size) override; int inner_deep_copy(char *buf, const int64_t buf_len, ObIOCallback *&callback) const override; const char *get_data() override; TO_STRING_KV(KP_(data_buf)); diff --git a/src/storage/blockstore/ob_shared_block_reader_writer.cpp b/src/storage/blockstore/ob_shared_block_reader_writer.cpp new file mode 100644 index 000000000..cdf049896 --- /dev/null +++ b/src/storage/blockstore/ob_shared_block_reader_writer.cpp @@ -0,0 +1,852 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX STORAGE +#include "storage/blockstore/ob_shared_block_reader_writer.h" +#include "storage/blocksstable/ob_block_manager.h" + +namespace oceanbase +{ +using namespace blocksstable; +namespace storage +{ + +ObSharedBlockWriteInfo::ObSharedBlockWriteInfo() + : buffer_(nullptr), + offset_(0), + size_(0), + io_desc_(), + io_callback_(nullptr) +{ +} + +bool ObSharedBlockWriteInfo::is_valid() const +{ + return nullptr != buffer_ && size_ > 0 && io_desc_.is_valid(); +} + +void ObSharedBlockWriteInfo::reset() +{ + buffer_ = nullptr; + offset_ = 0; + size_ = 0; + io_desc_.reset(); + io_callback_ = nullptr; +} + +ObSharedBlockWriteInfo& ObSharedBlockWriteInfo::operator=(const ObSharedBlockWriteInfo &other) +{ + if (this != &other) { + buffer_ = other.buffer_; + offset_ = other.offset_; + size_ = other.size_; + io_desc_ = other.io_desc_; + io_callback_ = other.io_callback_; + } + return *this; +} + +bool ObSharedBlockReadInfo::is_valid() const +{ + return addr_.is_valid() && io_desc_.is_valid(); +} + +//=================================== ObSharedBlocksWriteCtx ============================= +bool ObSharedBlocksWriteCtx::is_valid() const +{ + return addr_.is_valid() && addr_.is_block() && block_ids_.count() > 0; +} +ObSharedBlocksWriteCtx::~ObSharedBlocksWriteCtx() +{ + clear(); +} + +ObSharedBlocksWriteCtx::ObSharedBlocksWriteCtx(const ObSharedBlocksWriteCtx &other) +{ + *this = other; +} +void ObSharedBlocksWriteCtx::clear() +{ + int ret = OB_SUCCESS; + if (OB_SUCC(ret)) { + for (int64_t i = 0; i < block_ids_.count(); ++i) { + if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(block_ids_.at(i)))) { + LOG_ERROR("Fail to dec macro block ref cnt", K(ret), K(block_ids_.count()), K(i), + "macro id", block_ids_.at(i)); + } + abort_unless(OB_SUCCESS == ret); + } + } + block_ids_.reset(); + addr_.reset(); +} +int ObSharedBlocksWriteCtx::set_addr(const ObMetaDiskAddr &addr) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!addr.is_valid() || !addr.is_block())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid addr", K(ret), K(addr)); + } else { + addr_ = addr; + } + return ret; +} + +int ObSharedBlocksWriteCtx::add_block_id(const blocksstable::MacroBlockId &block_id) +{ + int ret = OB_SUCCESS; + const int64_t cnt = block_ids_.count(); + if (OB_UNLIKELY(!block_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid block id", K(ret), K(block_id)); + } else if (cnt > 0 && block_id == block_ids_.at(cnt - 1)) { + // skip, link handle uses one write_ctx to record all blocks' id sequentially + } else if (OB_FAIL(block_ids_.push_back(block_id))) { + LOG_WARN("Fail to push back block id", K(ret), K(block_id)); + } else if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(block_id))) { + block_ids_.pop_back(); + LOG_ERROR("Fail to inc macro block ref cnt", K(ret)); + } + return ret; +} + +ObSharedBlocksWriteCtx &ObSharedBlocksWriteCtx::operator=(const ObSharedBlocksWriteCtx &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + clear(); + if (OB_FAIL(set_addr(other.addr_))) { + LOG_WARN("Fail to set add", K(ret), K(other)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < other.block_ids_.count(); ++i) { + if (OB_FAIL(add_block_id(other.block_ids_.at(i)))) { + LOG_WARN("Fail to add block id", K(ret), K(other)); + } + } + } + } + return *this; +} + +//=================================== ObSharedBlockHeader ============================= +DEFINE_GET_SERIALIZE_SIZE(ObSharedBlockHeader) +{ + return sizeof(ObSharedBlockHeader); +} + +DEFINE_SERIALIZE(ObSharedBlockHeader) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0 || pos < 0 || pos + get_serialize_size() < buf_len)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(buf), K(buf_len), K(pos)); + } else if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("data block meta value is invalid", K(ret), KPC(this)); + } else { + ObSharedBlockHeader *header = reinterpret_cast(buf + pos); + *header = *this; + pos += get_serialize_size(); + } + return ret; +} + +DEFINE_DESERIALIZE(ObSharedBlockHeader) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(data_len <= 0 || pos < 0 || pos + sizeof(ObSharedBlockHeader) < data_len)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(buf), K(data_len), K(pos)); + } else { + const ObSharedBlockHeader *header = reinterpret_cast(buf + pos); + *this = *header; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("data block meta value is invalid", K(ret), KPC(this)); + } else { + pos += get_serialize_size(); + } + } + return ret; +} + +bool ObSharedBlockHeader::is_valid() const +{ + return OB_LINKED_BLOCK_HEADER_MAGIC == magic_ + && OB_LINKED_BLOCK_HEADER_VERSION == version_ + && cur_block_idx_ <= total_block_cnt_ + && total_block_cnt_ == 1 + && get_serialize_size() == header_size_ + && DEFAULT_MACRO_ID == next_macro_id_; +} + + +//=================================== ObSharedBlockWriteHandle ============================= + +void ObSharedBlockBaseHandle::reset() +{ + macro_handles_.reset(); + addrs_.reset(); +} + +int ObSharedBlockBaseHandle::wait() +{ + int ret = OB_SUCCESS; + const int64_t io_timeout_ms = std::max(GCONF._data_storage_io_timeout / 1000, DEFAULT_IO_WAIT_TIME_MS); + for (int64_t i = 0; OB_SUCC(ret) && i < macro_handles_.count(); ++i) { + ObMacroBlockHandle macro_handle = macro_handles_.at(i); + if (OB_UNLIKELY(!macro_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Unexpected invalid macro handle", K(ret), K(i), K(macro_handle), KPC(this)); + } else if (OB_FAIL(macro_handle.wait(io_timeout_ms))) { + LOG_WARN("Failt to wait macro handle finish", K(ret), K(macro_handle), K(io_timeout_ms)); + } + } + return ret; +} + +int ObSharedBlockBaseHandle::add_macro_handle(const ObMacroBlockHandle ¯o_handle) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!macro_handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(macro_handle)); + } else if (OB_FAIL(macro_handles_.push_back(macro_handle))) { + LOG_WARN("Fail to push back macro handle", K(ret)); + } + return ret; +} + +int ObSharedBlockBaseHandle::add_meta_addr(const ObMetaDiskAddr &addr) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!addr.is_valid() || !addr.is_block())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(addr)); + } else if (OB_FAIL(addrs_.push_back(addr))) { + LOG_WARN("Fail to push back macro handle", K(ret)); + } + return ret; +} + + +bool ObSharedBlockWriteHandle::is_valid() const +{ + return macro_handles_.count() > 0 && addrs_.count() == 1; +} + +bool ObSharedBlockReadHandle::is_valid() const +{ + return macro_handles_.count() > 0 && addrs_.count() == 1; +} + +ObSharedBlockReadHandle::ObSharedBlockReadHandle(const ObSharedBlockReadHandle &other) +{ + *this = other; +} + +ObSharedBlockReadHandle &ObSharedBlockReadHandle::operator=(const ObSharedBlockReadHandle &other) +{ + if (&other != this) { + addrs_ = other.addrs_; + macro_handles_ = other.macro_handles_; + } + return *this; +} + +int ObSharedBlockReadHandle::wait() +{ + // TODO(zhuixin.gsy) use timeout_ms to wait + int ret = OB_SUCCESS; + if (OB_FAIL(ObSharedBlockBaseHandle::wait())) { + LOG_WARN("Fail to wait io finish", K(ret)); + } + return ret; +} + +int ObSharedBlockReadHandle::get_data(ObIAllocator &allocator, char *&buf, int64_t &buf_len) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObSharedBlockBaseHandle::wait())) { + LOG_WARN("Fail to wait io finish", K(ret)); + } else { + ObMacroBlockHandle ¯o_handle = macro_handles_.at(0); + const char *data_buf = macro_handle.get_buffer(); + const int64_t data_size = macro_handle.get_data_size(); + int64_t header_size = 0; + if (OB_FAIL(verify_checksum(data_buf, data_size, header_size, buf_len))) { + LOG_WARN("fail to verify checksum", K(ret), KP(data_buf), K(data_size), K(header_size), K(buf_len)); + } else if (OB_ISNULL(buf = static_cast(allocator.alloc(buf_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc buf", K(ret), K(buf_len)); + } else { + MEMCPY(buf, data_buf + header_size, buf_len); + } + } + return ret; +} + +int ObSharedBlockReadHandle::parse_data( + const char *data_buf, + const int64_t data_size, + char *&buf, + int64_t &buf_len) +{ + int ret = OB_SUCCESS; + int64_t header_size = 0; + if (OB_FAIL(verify_checksum(data_buf, data_size, header_size, buf_len))) { + LOG_WARN("fail to verify checksum", K(ret), KP(data_buf), K(data_size), K(header_size), K(buf_len)); + } else { + buf = const_cast(data_buf) + header_size; + } + return ret; +} + +int ObSharedBlockReadHandle::verify_checksum( + const char *data_buf, + const int64_t data_size, + int64_t &header_size, + int64_t &buf_len) +{ + int ret = OB_SUCCESS; + if (data_size < sizeof(ObSharedBlockHeader)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Unexpected data size", K(ret), K(data_size)); + } else { + const ObSharedBlockHeader *header = reinterpret_cast(data_buf); + int64_t checksum = 0; + if (OB_UNLIKELY(!header->is_valid() + || data_size < header->header_size_ + header->data_size_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Unexpected header", K(ret), KPC(header), K(data_size)); + } else if (OB_UNLIKELY(header->checksum_ + != (checksum = ob_crc64_sse42(data_buf + header->header_size_, header->data_size_)))) { + ret = OB_CHECKSUM_ERROR; + LOG_WARN("Checksum error", K(ret), K(checksum), KPC(header)); + } else { + header_size = header->header_size_; + buf_len = header->data_size_; + } + LOG_DEBUG("zhuixin debug read shared block", K(ret), KPC(header)); + } + return ret; +} + +int ObSharedBlockWriteHandle::get_write_ctx(ObSharedBlocksWriteCtx &write_ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Unexpected invalid shared handle", K(ret), KPC(this)); + } else if (OB_FAIL(wait())) { + LOG_WARN("Fail to wait io finish", K(ret), KPC(this)); + } else if (OB_FAIL(write_ctx.set_addr(addrs_.at(0)))) { + LOG_WARN("Fail to set addr", K(ret), K(addrs_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < macro_handles_.count(); ++i) { + if (OB_FAIL(write_ctx.add_block_id(macro_handles_.at(i).get_macro_id()))) { + LOG_WARN("Fail to add block id", K(ret), K(i), K(macro_handles_.at(i))); + } + } + } + return ret; +} + +void ObSharedBlockBatchHandle::reset() +{ + write_ctxs_.reset(); + ObSharedBlockBaseHandle::reset(); +} +bool ObSharedBlockBatchHandle::is_valid() const +{ + return macro_handles_.count() > 0 && addrs_.count() > 0 + && write_ctxs_.count() == addrs_.count(); +} + +int ObSharedBlockBatchHandle::batch_get_write_ctx(ObIArray &write_ctxs) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Unexpected invalid batch handle", K(ret), KPC(this)); + } else if (OB_FAIL(wait())) { + LOG_WARN("Fail to wait io finish", K(ret), KPC(this)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < write_ctxs_.count(); ++i) { + if (OB_UNLIKELY(!write_ctxs_.at(i).is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Unexpected write ctx", K(ret), K(i), K(write_ctxs_.at(i))); + } else if (OB_FAIL(write_ctxs.push_back(write_ctxs_.at(i)))) { + LOG_WARN("Fail to add meta disk addr", K(ret), K(write_ctxs_.at(i))); + } + } + } + return ret; +} + +void ObSharedBlockLinkHandle::reset() +{ + write_ctx_.clear(); + ObSharedBlockBaseHandle::reset(); +} + +bool ObSharedBlockLinkHandle::is_valid() const +{ + return macro_handles_.count() > 0 && addrs_.count() == 1; // only record last addr +} + +int ObSharedBlockLinkHandle::get_write_ctx(ObSharedBlocksWriteCtx &write_ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Unexpected invalid batch handle", K(ret), KPC(this)); + } else if (OB_FAIL(wait())) { + LOG_WARN("Fail to wait io finish", K(ret), KPC(this)); + } else { + write_ctx = write_ctx_; + } + return ret; +} + +int ObSharedBlockLinkIter::init(const ObMetaDiskAddr &head) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("Init twice", K(ret)); + } else if (OB_UNLIKELY(!head.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid meta disk addr", K(ret), K(head)); + } else { + head_ = head; + cur_ = head; + is_inited_ = true; + } + return ret; +} + +int ObSharedBlockLinkIter::get_next(ObIAllocator &allocator, char *&buf, int64_t &buf_len) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("Not init", K(ret), KPC(this)); + } else if (cur_.is_none()) { + ret = OB_ITER_END; + } else { + ObSharedBlockReadInfo read_info; + ObSharedBlockReadHandle block_handle; + read_info.addr_ = cur_; + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_DATA_READ); + if (OB_FAIL(ObSharedBlockReaderWriter::async_read(read_info, block_handle))) { + LOG_WARN("Fail to read block", K(ret), K(read_info)); + } else if (OB_FAIL(block_handle.wait())) { + LOG_WARN("Fail to wait read io finish", K(ret), K(block_handle)); + } else if (OB_FAIL(block_handle.get_data(allocator, buf, buf_len))) { + LOG_WARN("Fail to get data", K(ret), K(block_handle)); + } else { + ObMacroBlockHandle ¯o_handle = block_handle.macro_handles_.at(0); + const ObSharedBlockHeader *header = + reinterpret_cast(macro_handle.get_buffer()); + cur_ = header->prev_addr_; + LOG_DEBUG("zhuixin debug get next link block", K(ret), K(head_), K(cur_), KPC(header)); + } + } + return ret; +} + + +//=================================== ObSharedBlockReaderWriter ============================= +const MacroBlockId ObSharedBlockHeader::DEFAULT_MACRO_ID(0, MacroBlockId::AUTONOMIC_BLOCK_INDEX, 0); +ObSharedBlockReaderWriter::ObSharedBlockReaderWriter() + : mutex_(), data_("SharedBlockRW"), macro_handle_(), offset_(0), align_offset_(0), write_align_size_(0), + hanging_(false), need_align_(false), need_cross_(false), + is_inited_(false) +{} + +ObSharedBlockReaderWriter::~ObSharedBlockReaderWriter() +{ + reset(); +} + +int ObSharedBlockReaderWriter::init( + const bool need_align, + const bool need_cross) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("Init twice", K(ret)); + } else if (!need_align || need_cross) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("Not supported", K(ret), K(need_align), K(need_cross)); + } else if (OB_FAIL(data_.ensure_space(DEFAULT_MACRO_BLOCK_SIZE))) { + LOG_WARN("Fail to ensure space", K(ret)); + } else { + offset_ = 0; + align_offset_ = 0; + write_align_size_ = DIO_READ_ALIGN_SIZE; // 4K + hanging_ = false; + need_align_ = need_align; + need_cross_ = need_cross; + if (OB_FAIL(reserve_header())) { + LOG_WARN("fail to reserve header when init", K(ret)); + } else { + is_inited_ = true; + } + } + return ret; +} +void ObSharedBlockReaderWriter::reset() +{ + data_.reset(); + macro_handle_.reset(); + offset_ = 0; + align_offset_ = 0; + write_align_size_ = 0; + hanging_ = false; + need_align_ = false; + need_cross_ = false; + is_inited_ = false; +} +int ObSharedBlockReaderWriter::async_write( + const ObSharedBlockWriteInfo &write_info, + ObSharedBlockWriteHandle &block_handle) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(mutex_); + ObSharedBlocksWriteCtx write_ctx; + ObSharedBlockWriteArgs write_args; + write_args.need_align_ = need_align_; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("Not init", K(ret)); + } else if (OB_FAIL(inner_async_write(write_info, write_args, block_handle, write_ctx))) { + LOG_WARN("Fail to inner async write block", K(ret), K(write_info), K(write_args)); + } + return ret; +} + +int ObSharedBlockReaderWriter::async_batch_write( + const ObIArray &write_infos, + ObSharedBlockBatchHandle &block_handle) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("Not init", K(ret)); + } else { + lib::ObMutexGuard guard(mutex_); + ObSharedBlockWriteArgs write_args; + ObSharedBlocksWriteCtx write_ctx; + for (int64_t i = 0; OB_SUCC(ret) && i < write_infos.count(); ++i) { + // only the last need flush and align + write_args.need_flush_ = (i == write_infos.count() - 1); + write_args.need_align_ = (i == write_infos.count() - 1) ? need_align_ : false; + write_ctx.clear(); + if (OB_FAIL(inner_async_write(write_infos.at(i), write_args, block_handle, write_ctx))) { + LOG_WARN("Fail to async write block", K(ret), K(i), K(write_infos.at(i)), K(write_args)); + } else if (OB_FAIL(block_handle.write_ctxs_.push_back(write_ctx))) { + LOG_WARN("Fail to add write ctx", K(ret), K(write_ctx)); + } + } + } + return ret; +} + +int ObSharedBlockReaderWriter::async_link_write( + const ObSharedBlockWriteInfo &write_info, + ObSharedBlockLinkHandle &block_handle) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(mutex_); + ObSharedBlockWriteArgs write_args; + ObSharedBlocksWriteCtx write_ctx; + write_args.need_flush_ = true; + write_args.need_align_ = need_align_; + write_args.is_linked_ = true; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("Not init", K(ret)); + } else if (OB_FAIL(block_handle.wait())) { + LOG_WARN("Fail to wait other blocks finish", K(ret), K(block_handle)); + } else if (OB_FAIL(inner_async_write(write_info, write_args, block_handle, write_ctx))) { + LOG_WARN("Fail to inner async write block", K(ret), K(write_info), K(write_args)); + } else if (OB_FAIL(block_handle.write_ctx_.set_addr(write_ctx.addr_))) { + LOG_WARN("Fail to set addr to write ctx", K(ret), K(write_ctx)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < write_ctx.block_ids_.count(); ++i) { + if (OB_FAIL(block_handle.write_ctx_.add_block_id(write_ctx.block_ids_.at(i)))) { + LOG_WARN("Fail to add block id", K(ret), K(write_ctx)); + } + } + } + return ret; +} + +int ObSharedBlockReaderWriter::inner_async_write( + const ObSharedBlockWriteInfo &write_info, + const ObSharedBlockWriteArgs &write_args, + ObSharedBlockBaseHandle &block_handle, + ObSharedBlocksWriteCtx &write_ctx) +{ + int ret = OB_SUCCESS; + if (need_cross_ && OB_FAIL(write_cross_block(write_info, write_args, block_handle))) { + LOG_WARN("Fail to write cross block", K(ret), K(write_info)); + } else if (OB_FAIL(write_block(write_info, write_args, block_handle, write_ctx))) { + LOG_WARN("Fail to write block", K(ret), K(write_info)); + } + return ret; +} + +int ObSharedBlockReaderWriter::reserve_header() +{ + int ret = OB_SUCCESS; + ObMacroBlockCommonHeader common_header; + common_header.reset(); + common_header.set_attr(ObMacroBlockCommonHeader::MacroBlockType::SharedMetaData); + if (OB_UNLIKELY(offset_ > 0 || align_offset_ > 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to reserve header", K(ret), K_(offset), K_(align_offset)); + } else if (OB_FAIL(common_header.build_serialized_header(data_.current(), common_header.get_serialize_size()))) { + LOG_WARN("fail to write common header", K(ret), K(common_header)); + } else if (OB_FAIL(data_.advance(common_header.get_serialize_size()))) { + LOG_WARN("Fail to advance size", K(ret), K(common_header)); + } else { + offset_ = common_header.get_serialize_size(); + hanging_ = true; + } + + if (OB_FAIL(ret)) { // recover from failure + offset_ = 0; + hanging_ = false; + data_.reuse(); + } + return ret; +} + +int ObSharedBlockReaderWriter::switch_block(ObMacroBlockHandle ¯o_handle) +{ + int ret = OB_SUCCESS; + macro_handle.reset(); + if (hanging_) { + ObMacroBlockWriteInfo macro_info; + macro_info.buffer_ = data_.data() + align_offset_; + macro_info.offset_ = align_offset_; + macro_info.size_ = upper_align(offset_ - align_offset_, write_align_size_); + macro_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + // io_callback + // do not use macro_handle_ to write, since it will be reset if failed + macro_handle = macro_handle_; + if (OB_FAIL(macro_handle.async_write(macro_info))) { + LOG_WARN("Fail to async write block", K(ret), K(macro_info)); + } + } + if (OB_SUCC(ret)) { + hanging_ = false; + data_.reuse(); + macro_handle_.reset(); + offset_ = 0; + align_offset_ = 0; + if (OB_FAIL(OB_SERVER_BLOCK_MGR.alloc_block(macro_handle_))) { + LOG_WARN("fail to alloc block for new macro block", K(ret)); + } else if (OB_FAIL(reserve_header())) { + LOG_WARN("fail to reserve header after switch block", K(ret)); + } + } + return ret; +} + +int ObSharedBlockReaderWriter::calc_store_size( + const ObSharedBlockHeader &header, + const bool need_align, + int64_t &store_size, + int64_t &align_store_size) +{ + int ret = OB_SUCCESS; + store_size = 0; + align_store_size = 0; + store_size = header.header_size_ + header.data_size_; + const int64_t next_align_offset = upper_align(offset_ + store_size, write_align_size_); + align_store_size = next_align_offset - align_offset_; + if (need_align) { + store_size = next_align_offset - offset_; + } + if (OB_UNLIKELY(store_size > DEFAULT_MACRO_BLOCK_SIZE)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("Not supported block size", K(ret), K(header), K_(offset), K_(align_offset), K(store_size)); + } + return ret; +} + +int ObSharedBlockReaderWriter::inner_write_block( + const ObSharedBlockHeader &header, + const char *buf, + const int64_t &size, + ObSharedBlockBaseHandle &block_handle, + const bool need_flush, + const bool need_align) +{ + int ret = OB_SUCCESS; + ObMacroBlockHandle macro_handle; + ObMetaDiskAddr addr; + const int64_t blk_size = header.header_size_ + header.data_size_; + int64_t store_size = 0, align_store_size = 0; + if (OB_FAIL(calc_store_size(header, need_align, store_size, align_store_size))) { + LOG_WARN("fail to calc store size", K(ret)); + } else if (!macro_handle_.get_macro_id().is_valid() + && OB_FAIL(OB_SERVER_BLOCK_MGR.alloc_block(macro_handle_))) { + LOG_WARN("fail to alloc block for new macro block", K(ret)); + } else if (store_size + offset_ > DEFAULT_MACRO_BLOCK_SIZE) { + if (OB_FAIL(switch_block(macro_handle))) { + LOG_WARN("Fail to switch new block", K(ret)); + } else if (macro_handle.is_valid() && OB_FAIL(block_handle.add_macro_handle(macro_handle))) { + LOG_WARN("Fail to flush last macro block", K(ret), K(macro_handle)); + } else if (OB_FAIL(calc_store_size(header, need_align, store_size, align_store_size))) { + LOG_WARN("fail to calc store size", K(ret)); + } + } + + if (OB_SUCC(ret)) { + macro_handle.reset(); + int64_t pos = 0; + if (OB_FAIL(header.serialize(data_.current(), header.header_size_, pos))) { + LOG_WARN("Fail to serialize header", K(ret), K(header)); + } else { + MEMCPY(data_.current() + pos, buf, size); + ObMacroBlockWriteInfo macro_info; + macro_info.buffer_ = data_.data() + align_offset_; + macro_info.offset_ = align_offset_; + macro_info.size_ = align_store_size; + macro_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + // io_callback + if (OB_FAIL(data_.advance(store_size))) { + LOG_WARN("Fail to advance size", K(ret), K(store_size)); + } else if (OB_FAIL(addr.set_block_addr(macro_handle_.get_macro_id(), + offset_, + blk_size))) { + LOG_WARN("Fail to set block addr", K(ret)); + } else if (OB_FAIL(block_handle.add_meta_addr(addr))) { + LOG_WARN("Fail to add meta addr", K(ret), K(addr)); + } else { + offset_ += store_size; + } + if (OB_SUCC(ret) && need_flush) { + macro_handle = macro_handle_; + if (OB_FAIL(macro_handle.async_write(macro_info))) { + LOG_WARN("Fail to async write block", K(ret), K(macro_info)); + } else if (OB_FAIL(block_handle.add_macro_handle(macro_handle))) { + LOG_WARN("Fail to add macro handle", K(ret), K(macro_handle), K(addr)); + } else { + hanging_ = false; + align_offset_ = lower_align(offset_, write_align_size_); + } + } else if (!need_flush) { + hanging_ = true; + } + LOG_DEBUG("zhuixin debug inner write block", K(ret), K(header), K(size), K(need_flush), + K(need_align), K(store_size), K(align_store_size), K(offset_), K(align_offset_), + K(hanging_), K(addr), K(macro_handle)); + } + } + return ret; +} + +void ObSharedBlockReaderWriter::get_cur_shared_block(blocksstable::MacroBlockId ¯o_id) +{ + lib::ObMutexGuard guard(mutex_); + macro_id = macro_handle_.get_macro_id(); +} + +int ObSharedBlockReaderWriter::write_block( + const ObSharedBlockWriteInfo &write_info, + const ObSharedBlockWriteArgs &write_args, + ObSharedBlockBaseHandle &block_handle, + ObSharedBlocksWriteCtx &write_ctx) +{ + int ret = OB_SUCCESS; + ObMetaDiskAddr prev_addr; + prev_addr.set_none_addr(); + if (OB_UNLIKELY(!write_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid shared block write info", K(ret), K(write_info)); + } else if (write_args.is_linked_ && block_handle.addrs_.count() > 0) { + prev_addr = block_handle.addrs_.at(0); + block_handle.reset(); // clear prev blocks info + } + if (OB_SUCC(ret)) { + ObSharedBlockHeader header; + header.cur_block_idx_ = 1; + header.total_block_cnt_ = 1; + header.header_size_ = header.get_serialize_size(); + header.data_size_ = write_info.size_; + header.checksum_ = ob_crc64_sse42(write_info.buffer_, write_info.size_); + header.next_macro_id_ = ObSharedBlockHeader::DEFAULT_MACRO_ID; + header.prev_addr_ = prev_addr; + if (OB_FAIL(inner_write_block(header, write_info.buffer_, write_info.size_, + block_handle, write_args.need_flush_, write_args.need_align_))) { + LOG_WARN("Fail to write block", K(ret), K(write_info), K(write_args)); + } else { + const int64_t cnt = block_handle.addrs_.count(); + const ObMetaDiskAddr &addr = block_handle.addrs_.at(cnt - 1); + if (OB_FAIL(write_ctx.set_addr(addr))) { + LOG_WARN("Fail to add addr to write ctx", K(ret), K(addr)); + } else if (OB_FAIL(write_ctx.add_block_id(addr.block_id()))) { + LOG_WARN("Fail to add block id to write ctx", K(ret), K(addr)); + } + } + } + return ret; +} + +int ObSharedBlockReaderWriter::write_cross_block( + const ObSharedBlockWriteInfo &write_info, + const ObSharedBlockWriteArgs &write_args, + ObSharedBlockBaseHandle &block_handle) +{ + UNUSED(write_info); + UNUSED(write_args); + UNUSED(block_handle); + return OB_NOT_SUPPORTED; +} + +int ObSharedBlockReaderWriter::async_read( + const ObSharedBlockReadInfo &read_info, + ObSharedBlockReadHandle &block_handle) +{ + int ret = OB_SUCCESS; + ObMacroBlockReadInfo macro_read_info; + ObMacroBlockHandle macro_handle; + macro_read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_READ); + macro_read_info.io_callback_ = read_info.io_callback_; + if (OB_UNLIKELY(!read_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid shared block read info", K(ret), K(read_info)); + } else if (OB_FAIL(read_info.addr_.get_block_addr( + macro_read_info.macro_block_id_, + macro_read_info.offset_, + macro_read_info.size_))) { + LOG_WARN("Fail to get block addr", K(ret), K(read_info)); + } else if (OB_FAIL(macro_handle.async_read(macro_read_info))) { + LOG_WARN("Fail to async read block", K(ret), K(macro_read_info)); + } else if (OB_FAIL(block_handle.add_macro_handle(macro_handle))) { + LOG_WARN("Fail to add macro handle", K(ret), K(macro_read_info)); + } else if (OB_FAIL(block_handle.add_meta_addr(read_info.addr_))) { + LOG_WARN("Fail to add meta addr", K(ret)); + } + return ret; +} + + +} // end namespace storage +} // end namespace oceanbase diff --git a/src/storage/blockstore/ob_shared_block_reader_writer.h b/src/storage/blockstore/ob_shared_block_reader_writer.h new file mode 100644 index 000000000..32f9c32ed --- /dev/null +++ b/src/storage/blockstore/ob_shared_block_reader_writer.h @@ -0,0 +1,296 @@ +/** + * 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 OB_STORAGE_SLOG_SHARED_BLOCK_READER_WRITER_H +#define OB_STORAGE_SLOG_SHARED_BLOCK_READER_WRITER_H + +#include "storage/meta_mem/ob_meta_obj_struct.h" +#include "storage/blocksstable/ob_macro_block_handle.h" +#include "storage/blocksstable/ob_macro_block_id.h" +#include "storage/blocksstable/ob_data_buffer.h" + +namespace oceanbase +{ +namespace storage +{ +struct ObSharedBlockWriteInfo final +{ +public: + ObSharedBlockWriteInfo(); + ~ObSharedBlockWriteInfo() = default; + ObSharedBlockWriteInfo &operator=(const ObSharedBlockWriteInfo &other); + bool is_valid() const; + void reset(); + TO_STRING_KV(KP_(buffer), K_(offset), K_(size), K_(io_desc), K_(io_callback)); +public: + const char *buffer_; + int64_t offset_; + int64_t size_; + common::ObIOFlag io_desc_; + common::ObIOCallback *io_callback_; +}; + +struct ObSharedBlockReadInfo final +{ +public: + ObSharedBlockReadInfo() + : addr_(), io_desc_(), io_callback_(nullptr) + {} + ~ObSharedBlockReadInfo() = default; + bool is_valid() const; + TO_STRING_KV(K_(addr), K_(io_desc), K_(io_callback)); +public: + ObMetaDiskAddr addr_; + common::ObIOFlag io_desc_; + common::ObIOCallback *io_callback_; + DISALLOW_COPY_AND_ASSIGN(ObSharedBlockReadInfo); +}; + +struct ObSharedBlocksWriteCtx final +{ +public: + ObSharedBlocksWriteCtx() + : addr_(), block_ids_() + {} + ~ObSharedBlocksWriteCtx(); + ObSharedBlocksWriteCtx(const ObSharedBlocksWriteCtx &other); + bool is_valid() const; + int set_addr(const ObMetaDiskAddr &addr); // overwrite + int add_block_id(const blocksstable::MacroBlockId &block_id); // distinct + void clear(); + ObSharedBlocksWriteCtx &operator=(const ObSharedBlocksWriteCtx &other); + TO_STRING_KV(K_(addr), K_(block_ids)); +public: + ObMetaDiskAddr addr_; + ObArray block_ids_; +}; + +struct ObSharedBlockHeader final +{ + static const uint16_t OB_LINKED_BLOCK_HEADER_MAGIC = 1386; + static const uint16_t OB_LINKED_BLOCK_HEADER_VERSION = 1; + static const blocksstable::MacroBlockId DEFAULT_MACRO_ID; // -1 + OB_UNIS_VERSION(1); +public: + ObSharedBlockHeader() + : magic_(OB_LINKED_BLOCK_HEADER_MAGIC), version_(OB_LINKED_BLOCK_HEADER_VERSION), + cur_block_idx_(0), total_block_cnt_(0), header_size_(0), data_size_(0), + checksum_(0), next_macro_id_(DEFAULT_MACRO_ID) + { + prev_addr_.set_none_addr(); + } + ~ObSharedBlockHeader() = default; + bool is_valid() const; + TO_STRING_KV(K_(magic), K_(version), K_(header_size), K_(data_size), + K_(cur_block_idx), K_(total_block_cnt), K_(checksum), + K_(next_macro_id), K_(prev_addr)); +public: + uint16_t magic_; + uint16_t version_; + uint16_t cur_block_idx_; + uint16_t total_block_cnt_; + int32_t header_size_; + int32_t data_size_; + int64_t checksum_; + blocksstable::MacroBlockId next_macro_id_; // -1 indicates end + ObMetaDiskAddr prev_addr_; +}; + +class ObSharedBlockBaseHandle +{ + friend class ObSharedBlockReaderWriter; + friend class ObSharedBlockLinkIter; +public: + ObSharedBlockBaseHandle() + : macro_handles_(), addrs_() + {} + virtual ~ObSharedBlockBaseHandle() = default; + void reset(); + TO_STRING_KV(K(addrs_.count()), K(macro_handles_.count()), K_(addrs), K_(macro_handles)); +protected: + int wait(); + int add_macro_handle(const blocksstable::ObMacroBlockHandle ¯o_handle); + int add_meta_addr(const ObMetaDiskAddr &addr); +protected: + ObSEArray macro_handles_; + ObSEArray addrs_; + DISALLOW_COPY_AND_ASSIGN(ObSharedBlockBaseHandle); +}; + + +class ObSharedBlockReadHandle final : public ObSharedBlockBaseHandle +{ + friend class ObSharedBlockReaderWriter; +public: + ObSharedBlockReadHandle() = default; + ~ObSharedBlockReadHandle() = default; + ObSharedBlockReadHandle(const ObSharedBlockReadHandle &other); + ObSharedBlockReadHandle &operator=(const ObSharedBlockReadHandle &other); + bool is_valid() const; + int wait(); + int get_data(ObIAllocator &allocator, char *&buf, int64_t &buf_len); + +public: + static int parse_data( + const char *data_buf, + const int64_t data_size, + char *&buf, + int64_t &buf_len); + +private: + static int verify_checksum( + const char *data_buf, + const int64_t data_size, + int64_t &header_size, + int64_t &buf_len); +}; + +class ObSharedBlockWriteHandle final : public ObSharedBlockBaseHandle +{ + friend class ObSharedBlockReaderWriter; +public: + ObSharedBlockWriteHandle() = default; + ~ObSharedBlockWriteHandle() = default; + bool is_valid() const; + int get_write_ctx(ObSharedBlocksWriteCtx &write_ctx); + DISALLOW_COPY_AND_ASSIGN(ObSharedBlockWriteHandle); +}; + +class ObSharedBlockBatchHandle final : public ObSharedBlockBaseHandle +{ + friend class ObSharedBlockReaderWriter; +public: + ObSharedBlockBatchHandle() = default; + ~ObSharedBlockBatchHandle() = default; + void reset(); + bool is_valid() const; + int batch_get_write_ctx(ObIArray &write_ctxs); + INHERIT_TO_STRING_KV("ObSharedBlockBaseHandle", ObSharedBlockBaseHandle, K_(write_ctxs)); +protected: + ObArray write_ctxs_; +private: + DISALLOW_COPY_AND_ASSIGN(ObSharedBlockBatchHandle); +}; +class ObSharedBlockLinkHandle final : public ObSharedBlockBaseHandle +{ + friend class ObSharedBlockReaderWriter; +public: + ObSharedBlockLinkHandle() = default; + ~ObSharedBlockLinkHandle() = default; + void reset(); + bool is_valid() const; + int get_write_ctx(ObSharedBlocksWriteCtx &write_ctx); // always get prev block + INHERIT_TO_STRING_KV("ObSharedBlockBaseHandle", ObSharedBlockBaseHandle, K_(write_ctx)); +protected: + ObSharedBlocksWriteCtx write_ctx_; +private: + DISALLOW_COPY_AND_ASSIGN(ObSharedBlockLinkHandle); +}; + +class ObSharedBlockLinkIter final +{ +public: + ObSharedBlockLinkIter() + : head_(), cur_(), is_inited_(false) + {} + ~ObSharedBlockLinkIter() = default; + int init(const ObMetaDiskAddr &head); + int get_next(ObIAllocator &allocator, char *&buf, int64_t &buf_len); + TO_STRING_KV(K_(head), K_(cur), K_(is_inited)); +private: + ObMetaDiskAddr head_; + ObMetaDiskAddr cur_; + bool is_inited_; +}; + +class ObSharedBlockReaderWriter final +{ +private: + struct ObSharedBlockWriteArgs; +public: + ObSharedBlockReaderWriter(); + ~ObSharedBlockReaderWriter(); + int init( + const bool need_align = true, + const bool need_cross = false); + void reset(); + void get_cur_shared_block(blocksstable::MacroBlockId ¯o_id); + static int async_read(const ObSharedBlockReadInfo &read_info, ObSharedBlockReadHandle &block_handle); + int async_write( + const ObSharedBlockWriteInfo &write_info, + ObSharedBlockWriteHandle &block_handle); + int async_batch_write( + const ObIArray &write_infos, + ObSharedBlockBatchHandle &block_handle); + int async_link_write( + const ObSharedBlockWriteInfo &write_infos, + ObSharedBlockLinkHandle &block_handle); +private: + int inner_async_write( + const ObSharedBlockWriteInfo &write_info, + const ObSharedBlockWriteArgs &write_args, + ObSharedBlockBaseHandle &block_handle, + ObSharedBlocksWriteCtx &write_ctx); + int write_block( + const ObSharedBlockWriteInfo &write_info, + const ObSharedBlockWriteArgs &write_args, + ObSharedBlockBaseHandle &block_handle, + ObSharedBlocksWriteCtx &write_ctx); // not cross + int write_cross_block( + const ObSharedBlockWriteInfo &write_info, + const ObSharedBlockWriteArgs &write_args, + ObSharedBlockBaseHandle &block_handle); // cross + int calc_store_size( + const ObSharedBlockHeader &header, + const bool need_align, + int64_t &store_size, + int64_t &align_store_size); + int inner_write_block( + const ObSharedBlockHeader &header, + const char *buf, + const int64_t &size, + ObSharedBlockBaseHandle &block_handle, + const bool need_flush = true, + const bool need_align = true); + int switch_block(blocksstable::ObMacroBlockHandle ¯o_handle); + int reserve_header(); +private: +struct ObSharedBlockWriteArgs final +{ +public: + ObSharedBlockWriteArgs() + : need_flush_(true), need_align_(true), is_linked_(false) + {} + ~ObSharedBlockWriteArgs() = default; + TO_STRING_KV(K_(need_flush), K_(need_align), K_(is_linked)); + bool need_flush_; + bool need_align_; + bool is_linked_; +}; +private: + lib::ObMutex mutex_; + blocksstable::ObSelfBufferWriter data_; + blocksstable::ObMacroBlockHandle macro_handle_; + int64_t offset_; + int64_t align_offset_; + int64_t write_align_size_; + bool hanging_; + bool need_align_; + bool need_cross_; + bool is_inited_; + DISALLOW_COPY_AND_ASSIGN(ObSharedBlockReaderWriter); +}; + +} // end namespace storage +} // end namespace oceanbase + +#endif // OB_STORAGE_SLOG_SHARED_BLOCK_READER_WRITER_H diff --git a/src/storage/checkpoint/ob_common_checkpoint.h b/src/storage/checkpoint/ob_common_checkpoint.h index daa4e15f8..c902fd7f9 100644 --- a/src/storage/checkpoint/ob_common_checkpoint.h +++ b/src/storage/checkpoint/ob_common_checkpoint.h @@ -28,19 +28,14 @@ namespace checkpoint enum ObCommonCheckpointType { INVALID_BASE_TYPE = 0, - - TX_CTX_MEMTABLE_TYPE = 1, - - TX_DATA_MEMTABLE_TYPE = 2, - - LOCK_MEMTABLE_TYPE = 3, - - DATA_CHECKPOINT_TYPE = 4, - + TX_CTX_MEMTABLE_TYPE, + TX_DATA_MEMTABLE_TYPE, + LOCK_MEMTABLE_TYPE, + MDS_TABLE_TYPE, + DATA_CHECKPOINT_TYPE, // for unittest - TEST_COMMON_CHECKPOINT = 5, - - MAX_BASE_TYPE = 6, + TEST_COMMON_CHECKPOINT, + MAX_BASE_TYPE }; static inline @@ -57,6 +52,8 @@ int common_checkpoint_type_to_string(const ObCommonCheckpointType common_checkpo strncpy(str ,"TX_DATA_MEMTABLE_TYPE", str_len); } else if (common_checkpoint_type == LOCK_MEMTABLE_TYPE) { strncpy(str ,"LOCK_MEMTABLE_TYPE", str_len); + } else if (common_checkpoint_type == MDS_TABLE_TYPE) { + strncpy(str, "MDS_TABLE_TYPE", str_len); } else { ret = OB_INVALID_ARGUMENT; } diff --git a/src/storage/checkpoint/ob_data_checkpoint.cpp b/src/storage/checkpoint/ob_data_checkpoint.cpp index 2efac54ad..62f532a8f 100644 --- a/src/storage/checkpoint/ob_data_checkpoint.cpp +++ b/src/storage/checkpoint/ob_data_checkpoint.cpp @@ -617,7 +617,7 @@ int ObDataCheckpoint::traversal_flush_() // based on the order of rec_scn. So we should can simply use a small // number for flush tasks. const int MAX_DATA_CHECKPOINT_FLUSH_COUNT = 10000; - ObSEArray flush_tasks; + ObSEArray flush_tasks; { ObSpinLockGuard guard(lock_); @@ -635,9 +635,10 @@ int ObDataCheckpoint::traversal_flush_() && MAX_DATA_CHECKPOINT_FLUSH_COUNT >= flush_tasks.count()) { ObFreezeCheckpoint *ob_freeze_checkpoint = iterator.get_next(); memtable::ObMemtable *memtable = static_cast(ob_freeze_checkpoint); - ObTableHandleV2 handle(memtable, t3m, ObITable::TableType::DATA_MEMTABLE); - if (!memtable->get_is_flushed() - && OB_FAIL(flush_tasks.push_back(handle))) { + ObTableHandleV2 handle; + if (OB_FAIL(handle.set_table(memtable, t3m, ObITable::TableType::DATA_MEMTABLE))) { + STORAGE_LOG(WARN, "set table handle fail", K(ret), KPC(memtable)); + } else if (!memtable->get_is_flushed() && OB_FAIL(flush_tasks.push_back(handle))) { TRANS_LOG(WARN, "add table to flush tasks failed", KPC(memtable)); } } diff --git a/src/storage/compaction/ob_compaction_diagnose.cpp b/src/storage/compaction/ob_compaction_diagnose.cpp old mode 100644 new mode 100755 index 9ec0de498..b10cf47a7 --- a/src/storage/compaction/ob_compaction_diagnose.cpp +++ b/src/storage/compaction/ob_compaction_diagnose.cpp @@ -36,7 +36,9 @@ using namespace share; namespace compaction { - +/* + * ObScheduleSuspectInfo implement + * */ int64_t ObScheduleSuspectInfo::hash() const { int64_t hash_value = ObMergeDagHash::inner_hash(); @@ -55,17 +57,6 @@ bool ObScheduleSuspectInfo::is_valid() const return bret; } -ObScheduleSuspectInfo & ObScheduleSuspectInfo::operator = (const ObScheduleSuspectInfo &other) -{ - tenant_id_ = other.tenant_id_; - merge_type_ = other.merge_type_; - ls_id_ = other.ls_id_; - tablet_id_ = other.tablet_id_; - add_time_ = other.add_time_; - strncpy(suspect_info_, other.suspect_info_, strlen(other.suspect_info_)); - return *this; -} - int64_t ObScheduleSuspectInfo::gen_hash(int64_t tenant_id, int64_t dag_hash) { int64_t hash_value = dag_hash; @@ -73,37 +64,416 @@ int64_t ObScheduleSuspectInfo::gen_hash(int64_t tenant_id, int64_t dag_hash) return hash_value; } -ObScheduleSuspectInfoMgr::ObScheduleSuspectInfoMgr() - : is_inited_(false), - allocator_(SET_USE_500("scheSuspectInfo")), - lock_(common::ObLatchIds::INFO_MGR_LOCK) +void ObScheduleSuspectInfo::shallow_copy(ObIDiagnoseInfo *other) { + ObScheduleSuspectInfo *info = nullptr; + if (OB_NOT_NULL(other) && OB_NOT_NULL(info = dynamic_cast(other))) { + merge_type_ = info->merge_type_; + ls_id_ = info->ls_id_; + tablet_id_ = info->tablet_id_; + tenant_id_ = info->tenant_id_; + add_time_ = info->add_time_; + hash_ = info->hash_; + } } -int ObScheduleSuspectInfoMgr::init() +int64_t ObScheduleSuspectInfo::get_add_time() const +{ + return add_time_; +} + +int64_t ObScheduleSuspectInfo::get_hash() const +{ + return hash_; +} + +/* + * ObIDiagnoseInfoIter implement + * */ +int ObIDiagnoseInfoMgr::Iterator::open(const uint64_t version, ObIDiagnoseInfo *current_info, ObIDiagnoseInfoMgr *info_pool) { int ret = OB_SUCCESS; - if (OB_FAIL(info_map_.create(SUSPECT_INFO_BUCKET_NUM, SET_USE_500("scheSuspectInfo")))) { - COMMON_LOG(WARN, "failed to create dap map", K(ret)); + if (is_opened_) { + ret = OB_OPEN_TWICE; + STORAGE_LOG(WARN, "iterator is opened", K(ret)); + } else if (OB_ISNULL(current_info) || OB_ISNULL(info_pool)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), KP(current_info), KP(info_pool)); } else { - is_inited_ = true; + version_ = version; + current_info_ = current_info; + info_pool_ = info_pool; + seq_num_ = 1; // header + is_opened_ = true; } return ret; } -void ObScheduleSuspectInfoMgr::destroy() +int ObIDiagnoseInfoMgr::Iterator::get_next(ObIDiagnoseInfo *out_info, char *buf, const int64_t buf_len) +{ + int ret = OB_SUCCESS; + if (!is_opened_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ObIDiagnoseInfoIter is not init", K(ret)); + } else if (OB_ISNULL(out_info)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(out_info)); + } else { + common::SpinRLockGuard RLockGuard(info_pool_->rwlock_); + while (OB_SUCC(next())) { + // (current_info_->seq_num_ <= seq_num_) means info has been visited + if (current_info_->seq_num_ > seq_num_ && !current_info_->is_deleted()) { + seq_num_ = current_info_->seq_num_; + out_info->shallow_copy(current_info_); + if (OB_ISNULL(buf)) { + // do nothing // allow + } else if (OB_NOT_NULL(current_info_->info_param_)) { + if (OB_FAIL(current_info_->info_param_->fill_comment(buf, buf_len))) { + STORAGE_LOG(WARN, "failed to fill comment from info param", K(ret)); + } + } + break; + } + } + } + return ret; +} + +int ObIDiagnoseInfoMgr::Iterator::next() +{ + int ret = OB_SUCCESS; + if (version_ < info_pool_->version_) { + // version changed, which means some infos have been purged, the current_info_ maybe invalid ptr + version_ = info_pool_->version_; + current_info_ = info_pool_->info_list_.get_header(); + } else if (version_ > info_pool_->version_) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "Unexpected version value", K(ret), "iter_version", version_, + "pool_version", info_pool_->version_); + } + if (OB_SUCC(ret)) { + if (OB_ISNULL(current_info_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "Unexpect value", K(ret), K(current_info_)); + } else if (0 == seq_num_) { + // guarantee idempotency + ret = OB_ITER_END; + } else if (OB_ISNULL(current_info_ = current_info_->get_next())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "failed to next", K(ret), K(current_info_)); + } else if (current_info_ == info_pool_->info_list_.get_header()) { + // to ignore the version_ changing + ret = OB_ITER_END; + seq_num_ = 0; // tail + } + } + return ret; +} +/* + * ObIDiagnoseInfoMgr implement + * */ +int ObIDiagnoseInfoMgr::init(bool with_map, + const uint64_t tenant_id, + const char* basic_label, + const int64_t page_size, + int64_t max_size) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + STORAGE_LOG(WARN, "ObIDiagnoseInfoMgr has already been initiated", K(ret)); + } else if (OB_INVALID_TENANT_ID == tenant_id || OB_ISNULL(basic_label)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(basic_label)); + } else { + (void)snprintf(pool_label_, sizeof(pool_label_), "%s%s", basic_label, "Mgr"); + page_size_ = std::max(page_size, static_cast(INFO_PAGE_SIZE_LIMIT)); + max_size = upper_align(max_size, page_size_); + if (OB_FAIL(allocator_.init(ObMallocAllocator::get_instance(), + page_size, + lib::ObMemAttr(tenant_id, pool_label_), + 0, + max_size, + max_size))) { + STORAGE_LOG(WARN, "failed to init allocator", K(ret)); + } else if (with_map) { + (void)snprintf(bucket_label_, sizeof(bucket_label_), "%s%s", basic_label, "Bkt"); + (void)snprintf(node_label_, sizeof(node_label_), "%s%s", basic_label, "Node"); + if (OB_FAIL(info_map_.create(INFO_BUCKET_LIMIT, bucket_label_, node_label_, tenant_id))) { + STORAGE_LOG(WARN, "failed to create dap map", K(ret)); + } + } + } + if (OB_SUCC(ret)) { + version_ = 1; + seq_num_ = 1; + is_inited_ = true; + } else { + destroy(); + } + return ret; +} + +void ObIDiagnoseInfoMgr::destroy() +{ + if (IS_INIT) { + common::SpinWLockGuard guard(lock_); + common::SpinWLockGuard WLockGuard(rwlock_); + clear_with_no_lock(); + if (info_map_.created()) { + info_map_.destroy(); + } + allocator_.reset(); + is_inited_ = false; + } +} + +void ObIDiagnoseInfoMgr::clear() +{ + if (IS_INIT) { + common::SpinWLockGuard guard(lock_); + common::SpinWLockGuard WLockGuard(rwlock_); + clear_with_no_lock(); + } +} + +void ObIDiagnoseInfoMgr::clear_with_no_lock() +{ + if (info_map_.created()) { + info_map_.clear(); + } + DLIST_FOREACH_REMOVESAFE_NORET(iter, info_list_) { + info_list_.remove(iter); + if (allocator_.is_inited()) { + iter->destroy(allocator_); + } + } + info_list_.clear(); + version_ = 1; + seq_num_ = 1; +} + +int ObIDiagnoseInfoMgr::size() { common::SpinWLockGuard guard(lock_); - if (info_map_.created()) { - auto free_map_entry = [this](common::hash::HashMapPair &entry) { - ObScheduleSuspectInfo *info = entry.second; - info->~ObScheduleSuspectInfo(); - allocator_.free((void *)info); - return OB_SUCCESS; - }; - info_map_.foreach_refactored(free_map_entry); - info_map_.destroy(); + return info_list_.get_size(); +} + +int ObIDiagnoseInfoMgr::get_with_param(const int64_t key, ObIDiagnoseInfo *out_info, ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ObIDiagnoseInfoMgr is not init", K(ret)); + } else if (OB_ISNULL(out_info)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(out_info)); + } else { + common::SpinWLockGuard guard(lock_); + ObIDiagnoseInfo *info = NULL; + if (OB_FAIL(get_with_no_lock(key, info))) { + if (OB_HASH_NOT_EXIST != ret) { + STORAGE_LOG(WARN, "failed to get info from map", K(ret), K(key)); + } + } else { + out_info->shallow_copy(info); + if (OB_FAIL(info->info_param_->deep_copy(allocator, out_info->info_param_))) { + STORAGE_LOG(WARN, "failed to deep copy info param", K(ret)); + } + } } + return ret; +} + +int ObIDiagnoseInfoMgr::delete_info(const int64_t key) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ObIDiagnoseInfoMgr is not init", K(ret)); + } else { + common::SpinWLockGuard guard(lock_); + if (OB_FAIL(del_with_no_lock(key, nullptr))) { + if (OB_HASH_NOT_EXIST != ret) { + STORAGE_LOG(WARN, "failed to delete info", K(ret)); + } + } + } + return ret; +} + +int ObIDiagnoseInfoMgr::set_max(const int64_t size) +{ + int ret = OB_SUCCESS; + int64_t max_size = upper_align(size, page_size_); + common::SpinWLockGuard guard(lock_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ObIDiagnoseInfoMgr is not init", K(ret)); + } else if (OB_FAIL(allocator_.set_max(max_size, true))) { + STORAGE_LOG(WARN, "failed to set max", K(ret), "new max_size", max_size, + "old max_size", allocator_.get_max()); + } else if (allocator_.total() <= allocator_.get_max()) { + } else if (OB_FAIL(purge_with_rw_lock())) { + STORAGE_LOG(WARN, "failed to purge info when resize", K(ret)); + } + return ret; +} + +int ObIDiagnoseInfoMgr::gc_info() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ObIDiagnoseInfoMgr is not init", K(ret)); + } else { + common::SpinWLockGuard guard(lock_); + if ((allocator_.used() * 1.0) / allocator_.get_max() >= (GC_HIGH_PERCENTAGE * 1.0 / 100)) { + if (OB_FAIL(purge_with_rw_lock())) { + STORAGE_LOG(WARN, "failed to purge cuz gc_info", K(ret)); + } + } + } + return ret; +} + +int ObIDiagnoseInfoMgr::open_iter(Iterator &iter) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ObIDiagnoseInfoMgr is not init", K(ret)); + } else { + common::SpinRLockGuard guard(rwlock_); + if (OB_FAIL(iter.open(version_, info_list_.get_header(), this))) { + STORAGE_LOG(WARN, "failed to open iter", K(ret)); + } + } + return ret; +} + +int ObIDiagnoseInfoMgr::add_with_no_lock(const int64_t key, ObIDiagnoseInfo *info) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(info)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret)); + } else if (!info_list_.add_last(info)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "failed to add into info list", K(ret)); + } else if (info_map_.created()) { + if (OB_FAIL(info_map_.set_refactored(key, info))) { + STORAGE_LOG(WARN, "failed to set info into map", K(ret), K(key)); + } + } + + if (OB_SUCC(ret)) { + info->seq_num_ = ++seq_num_; + } else if (OB_NOT_NULL(info)) { + info->destroy(allocator_); + info = nullptr; + } + return ret; +} + +int ObIDiagnoseInfoMgr::del_with_no_lock(const int64_t key, ObIDiagnoseInfo *info) +{ + int ret = OB_SUCCESS; + if (info_map_.created()) { + ObIDiagnoseInfo *old_info = nullptr; + if (OB_FAIL(info_map_.get_refactored(key, old_info))) { + if (OB_HASH_NOT_EXIST != ret) { + STORAGE_LOG(WARN, "failed to get info from map", K(ret), K(key), K(old_info)); + } + } else if (OB_FAIL(info_map_.erase_refactored(key))) { + STORAGE_LOG(WARN, "failed to erase info from map", K(ret), K(key)); + } + if (OB_SUCC(ret) && OB_NOT_NULL(old_info)) { + old_info->set_deleted(); + if (OB_NOT_NULL(info)) { + info->update(old_info); + } + } + } else { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "info map is not created", K(ret)); + } + return ret; +} + +int ObIDiagnoseInfoMgr::get_with_no_lock(const int64_t key, ObIDiagnoseInfo *&info) +{ + int ret = OB_SUCCESS; + info = NULL; + if (info_map_.created()) { + if (OB_FAIL(info_map_.get_refactored(key, info))) { + if (OB_HASH_NOT_EXIST != ret) { + STORAGE_LOG(WARN, "failed to get info from map", K(ret), K(key)); + } + } + } else { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "info map is not created", K(ret)); + } + return ret; +} + +int ObIDiagnoseInfoMgr::purge_with_rw_lock(bool batch_purge) +{ + int ret = OB_SUCCESS; + int64_t purge_count = 0; + common::SpinWLockGuard WLockGuard(rwlock_); + int batch_size = info_list_.get_size() / MAX_ALLOC_RETRY_TIMES; + batch_size = std::max(batch_size, 10); + DLIST_FOREACH_REMOVESAFE(iter, info_list_) { + if (info_map_.created() && !iter->is_deleted()) { + if (OB_FAIL(info_map_.erase_refactored(iter->get_hash()))) { + STORAGE_LOG(WARN, "failed to erase from map", K(ret), "hash_key", iter->get_hash(), + "is_deleted", iter->is_deleted(), "seq_num", iter->seq_num_); + } + } + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(OB_ISNULL(info_list_.remove(iter)))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "failed to remove info from list", K(ret)); + // unexpected + ob_abort(); + } + iter->destroy(allocator_); + iter = nullptr; + ++purge_count; + } + + if (batch_purge && purge_count == batch_size) { + break; + } else if (!batch_purge && allocator_.total() <= allocator_.get_max() && + ((allocator_.used() * 1.0) / allocator_.get_max()) <= (GC_LOW_PERCENTAGE * 1.0 / 100)) { + break; + } + } + + if (OB_SUCC(ret)) { + STORAGE_LOG(INFO, "success to purge", K(ret), K(batch_purge), "max_size", allocator_.get_max(), + "used_size", allocator_.used(), "total_size", allocator_.total(), K(purge_count)); + } + ++version_; + return ret; +} +/* + * ObScheduleSuspectInfoMgr implement + * */ +int ObScheduleSuspectInfoMgr::mtl_init(ObScheduleSuspectInfoMgr *&schedule_suspect_info) +{ + int64_t max_size = cal_max(); + return schedule_suspect_info->init(true, MTL_ID(), "SuspectInfo", INFO_PAGE_SIZE, max_size); +} + +int64_t ObScheduleSuspectInfoMgr::cal_max() +{ + const uint64_t tenant_id = MTL_ID(); + int64_t max_size = std::min(static_cast(lib::get_tenant_memory_limit(tenant_id) * MEMORY_PERCENTAGE / 100), + static_cast(POOL_MAX_SIZE)); + return max_size; } int ObScheduleSuspectInfoMgr::add_suspect_info(const int64_t key, ObScheduleSuspectInfo &input_info) @@ -112,120 +482,14 @@ int ObScheduleSuspectInfoMgr::add_suspect_info(const int64_t key, ObScheduleSusp if (IS_NOT_INIT) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "ObScheduleSuspectInfoMgr is not init", K(ret)); - } else { - ObScheduleSuspectInfo *info = NULL; - common::SpinWLockGuard guard(lock_); - if (OB_FAIL(info_map_.get_refactored(key, info))) { - if (OB_HASH_NOT_EXIST == ret && info_map_.size() < SUSPECT_INFO_LIMIT) { // first add - void * buf = nullptr; - if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObScheduleSuspectInfo)))) { - ret = common::OB_ALLOCATE_MEMORY_FAILED; - COMMON_LOG(WARN, "failed to alloc dag", K(ret)); - } else { - info = new (buf) ObScheduleSuspectInfo(); - *info = input_info; - if (OB_FAIL(info_map_.set_refactored(key, info))) { - STORAGE_LOG(WARN, "failed to set suspect info", K(ret), K(key), K(info)); - allocator_.free(info); - info = nullptr; - } - } - } else { - STORAGE_LOG(WARN, "failed to get suspect info", K(ret), K(key), K(info)); - } - } else { // update - *info = input_info; - } + } else if (OB_ISNULL(input_info.info_param_)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument. info param is null", K(ret)); + } else if (OB_FAIL((alloc_and_add(key, &input_info)))) { + STORAGE_LOG(WARN, "failed to alloc and add suspect info", K(ret)); } return ret; } - -int ObScheduleSuspectInfoMgr::get_suspect_info(const int64_t key, ObScheduleSuspectInfo &ret_info) -{ - int ret = OB_SUCCESS; - ObScheduleSuspectInfo *info = NULL; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - STORAGE_LOG(WARN, "ObScheduleSuspectInfoMgr is not init", K(ret)); - } else { - common::SpinRLockGuard guard(lock_); - if (OB_FAIL(info_map_.get_refactored(key, info))) { - if (OB_HASH_NOT_EXIST != ret) { - STORAGE_LOG(WARN, "failed to get schedule suspect info", K(ret), K(key), K(info)); - } - } else { - ret_info = *info; - } - } - return ret; -} - -int ObScheduleSuspectInfoMgr::del_suspect_info(const int64_t key) -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - STORAGE_LOG(WARN, "ObScheduleSuspectInfoMgr is not init", K(ret)); - } else { - ObScheduleSuspectInfo *info = nullptr; - { - common::SpinWLockGuard guard(lock_); - if (OB_FAIL(info_map_.get_refactored(key, info))) { - if (OB_HASH_NOT_EXIST != ret) { - STORAGE_LOG(WARN, "failed to get schedule suspect info", K(ret), K(key), K(info)); - } - } else if (OB_FAIL(info_map_.erase_refactored(key))) { - if (OB_HASH_NOT_EXIST != ret) { - STORAGE_LOG(WARN, "failed to get schedule suspect info", K(ret), K(key)); - } - } - } - if (OB_SUCC(ret) && OB_NOT_NULL(info)) { - allocator_.free(info); - info = nullptr; - } - } - return ret; -} - -int ObScheduleSuspectInfoMgr::gc_info() -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - STORAGE_LOG(WARN, "ObScheduleSuspectInfoMgr is not init", K(ret)); - } else { - int tmp_ret = OB_SUCCESS; - int64_t gc_cnt = 0; - ObScheduleSuspectInfo *info = nullptr; - ObSEArray remove_info_keys; - const int64_t gc_time = ObTimeUtility::fast_current_time() - GC_INFO_TIME_LIMIT; - common::SpinWLockGuard guard(lock_); - for (InfoMap::iterator iter = info_map_.begin(); iter != info_map_.end(); ++iter) { - if (OB_NOT_NULL(info = iter->second)) { - if (info->add_time_ < gc_time && OB_TMP_FAIL(remove_info_keys.push_back(iter->first))) { - LOG_WARN("failed to push back remove info key", K(tmp_ret), K(iter->first)); - } - } - } - for (int64_t i = 0; i < remove_info_keys.count(); ++i) { - if (OB_TMP_FAIL(info_map_.get_refactored(remove_info_keys.at(i), info))) { - LOG_WARN("failed to get from map", K(tmp_ret), K(remove_info_keys.at(i))); - } else if (OB_NOT_NULL(info)) { - if (OB_TMP_FAIL(info_map_.erase_refactored(remove_info_keys.at(i)))) { - LOG_WARN("failed to erase from map", K(tmp_ret), K(remove_info_keys.at(i))); - } else { - gc_cnt++; - allocator_.free(info); - info = nullptr; - } - } - } - STORAGE_LOG(INFO, "gc schedule suspect info", K(gc_time), K(gc_cnt), "rest_cnt", info_map_.size()); - } - return ret; -} - /* * ObCompactionDiagnose implement * */ @@ -271,7 +535,7 @@ int ObCompactionDiagnoseMgr::init(ObCompactionDiagnoseInfo *info_array, const in int ret = OB_SUCCESS; if (OB_UNLIKELY(nullptr == info_array || max_cnt <= 0)) { ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "invalid argument", K(ret), K(info_array), K(max_cnt)); + STORAGE_LOG(WARN, "invalid argument", K(ret), K(info_array), K(max_cnt)); } else { info_array_ = info_array; max_cnt_ = max_cnt; @@ -362,7 +626,9 @@ int ObCompactionDiagnoseMgr::get_suspect_info( const ObMergeType merge_type, const ObLSID &ls_id, const ObTabletID &tablet_id, - ObScheduleSuspectInfo &ret_info) + ObScheduleSuspectInfo &ret_info, + char *buf, + const int64_t buf_len) { int ret = OB_SUCCESS; ObScheduleSuspectInfo input_info; @@ -370,12 +636,15 @@ int ObCompactionDiagnoseMgr::get_suspect_info( input_info.merge_type_ = merge_type; input_info.ls_id_ = ls_id; input_info.tablet_id_ = tablet_id; - if (OB_FAIL(ObScheduleSuspectInfoMgr::get_instance().get_suspect_info(input_info.hash(), ret_info))) { + ObInfoParamBuffer allocator; + if (OB_FAIL(MTL(ObScheduleSuspectInfoMgr *)->get_with_param(input_info.hash(), &ret_info, allocator))) { if (OB_HASH_NOT_EXIST != ret) { LOG_WARN("failed to get suspect info", K(ret), K(input_info)); } } else if (ret_info.add_time_ + SUSPECT_INFO_WARNING_THRESHOLD < ObTimeUtility::fast_current_time()) { - ret = OB_ENTRY_NOT_EXIST; + ret = OB_HASH_NOT_EXIST; + } else if (OB_FAIL(ret_info.info_param_->fill_comment(buf, buf_len))) { + STORAGE_LOG(WARN, "failed to fill comment from info param", K(ret)); } return ret; } @@ -386,7 +655,8 @@ int ObCompactionDiagnoseMgr::diagnose_ls_merge( { int ret = OB_SUCCESS; ObScheduleSuspectInfo ret_info; - if (OB_FAIL(get_suspect_info(merge_type, ls_id, ObTabletID(INT64_MAX), ret_info))) { + char tmp_str[common::OB_DIAGNOSE_INFO_LENGTH] = "\0"; + if (OB_FAIL(get_suspect_info(merge_type, ls_id, ObTabletID(INT64_MAX), ret_info, tmp_str, sizeof(tmp_str)))) { if (OB_HASH_NOT_EXIST != ret) { LOG_WARN("failed get ls merge suspect info", K(ret), K(ls_id)); } @@ -399,7 +669,7 @@ int ObCompactionDiagnoseMgr::diagnose_ls_merge( ObTabletID(INT64_MAX), ObCompactionDiagnoseInfo::DIA_STATUS_FAILED, ret_info.add_time_, - "schedule_suspect_info", ret_info.suspect_info_); + "schedule_suspect_info", tmp_str); } return ret; } @@ -450,7 +720,8 @@ int ObCompactionDiagnoseMgr::diagnose_tenant_tablet() // check tenant suspect info if (diagnose_major_flag) { ObScheduleSuspectInfo ret_info; - if (OB_TMP_FAIL(get_suspect_info(MEDIUM_MERGE, share::ObLSID(INT64_MAX), ObTabletID(INT64_MAX), ret_info))) { + char tmp_str[common::OB_DIAGNOSE_INFO_LENGTH] = "\0"; + if (OB_TMP_FAIL(get_suspect_info(MEDIUM_MERGE, share::ObLSID(INT64_MAX), ObTabletID(INT64_MAX), ret_info, tmp_str, sizeof(tmp_str)))) { if (OB_HASH_NOT_EXIST != tmp_ret) { LOG_WARN("failed get tenant merge suspect info", K(tmp_ret)); } @@ -463,7 +734,20 @@ int ObCompactionDiagnoseMgr::diagnose_tenant_tablet() ObTabletID(INT64_MAX), ObCompactionDiagnoseInfo::DIA_STATUS_FAILED, ret_info.add_time_, - "schedule_suspect_info", ret_info.suspect_info_); + "schedule_suspect_info", tmp_str); + } + if ((!scheduler->could_major_merge_start() || !scheduler->could_schedule_medium()) + && can_add_diagnose_info()) { + SET_DIAGNOSE_INFO( + info_array_[idx_++], + MEDIUM_MERGE, + MTL_ID(), + share::ObLSID(INT64_MAX), + ObTabletID(INT64_MAX), + ObCompactionDiagnoseInfo::DIA_STATUS_NOT_SCHEDULE, + ObTimeUtility::fast_current_time(), + "could_major_merge", scheduler->could_major_merge_start(), + "could_schedule_medium", scheduler->could_schedule_medium()); } } @@ -497,28 +781,28 @@ int ObCompactionDiagnoseMgr::diagnose_tenant_tablet() // check weak read ts if (diagnose_major_flag && !weak_read_ts_ready - && can_add_diagnose_info()) { - SET_DIAGNOSE_INFO( - info_array_[idx_++], - MEDIUM_MERGE, - MTL_ID(), - ls_id, - ObTabletID(INT64_MAX), - ObCompactionDiagnoseInfo::DIA_STATUS_FAILED, - ObTimeUtility::fast_current_time(), - "weak read ts is not ready, compaction_scn", - compaction_scn); + && can_add_diagnose_info() + && OB_TMP_FAIL(SET_DIAGNOSE_INFO( + info_array_[idx_++], + MEDIUM_MERGE, + MTL_ID(), + ls_id, + ObTabletID(INT64_MAX), + ObCompactionDiagnoseInfo::DIA_STATUS_FAILED, + ObTimeUtility::fast_current_time(), + "weak read ts is not ready, compaction_scn", + compaction_scn))) { + LOG_WARN("failed to add dignose info about weak read ts", K(tmp_ret), K(compaction_scn)); } // check ls suspect info for memtable freezing if (OB_TMP_FAIL(diagnose_ls_merge(MINI_MERGE, ls_id))) { LOG_WARN("failed to diagnose about memtable freezing", K(tmp_ret)); } - // check ls locality change and leader change if (is_leader && OB_TMP_FAIL(diagnose_ls_merge(MEDIUM_MERGE, ls_id))) { LOG_WARN("failed to diagnose about ls locality change", K(tmp_ret)); } - ObLSTabletIterator tablet_iter(ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US); + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); ObLSVTInfo ls_info; if (OB_FAIL(ls->get_ls_info(ls_info))) { LOG_WARN("failed to get ls info", K(ret), K(ls)); @@ -569,7 +853,7 @@ int ObCompactionDiagnoseMgr::diagnose_tenant_tablet() (void)abnormal_ls_id.push_back(ls->get_ls_id()); } } // end of while - if (diagnose_major_flag && tenant_major_finish && can_add_diagnose_info()) { + if (OB_SUCC(ret) && diagnose_major_flag && tenant_major_finish && can_add_diagnose_info()) { ObCompactionDiagnoseInfo &info = info_array_[idx_++]; SET_DIAGNOSE_INFO( info, @@ -702,17 +986,20 @@ int ObCompactionDiagnoseMgr::diagnose_tablet_mini_merge( { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; - ObTabletTableStore &table_store = tablet.get_table_store(); const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; ObITable *first_frozen_memtable = nullptr; - if (OB_FAIL(table_store.get_first_frozen_memtable(first_frozen_memtable))) { + ObTabletMemberWrapper table_store_wrapper; + + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->get_first_frozen_memtable(first_frozen_memtable))) { LOG_WARN("Fail to get sstables", K(ret)); } else if (nullptr != first_frozen_memtable) { // have frozen memtable bool diagnose_flag = false; ObSSTable *latest_sstable = nullptr; memtable::ObIMemtable *frozen_memtable = static_cast(first_frozen_memtable); - if (OB_ISNULL(latest_sstable = - static_cast(table_store.get_minor_sstables().get_boundary_table(true/*last*/)))) { + if (OB_ISNULL(latest_sstable = static_cast( + table_store_wrapper.get_member()->get_minor_sstables().get_boundary_table(true/*last*/)))) { diagnose_flag = true; } else { if (latest_sstable->get_end_scn() < frozen_memtable->get_end_scn() @@ -731,17 +1018,19 @@ int ObCompactionDiagnoseMgr::diagnose_tablet_mini_merge( } } else { // mini compaction finish, but memtable have not release ObScheduleSuspectInfo ret_info; - if (OB_SUCC(get_suspect_info(MINI_MERGE, ls_id, tablet_id, ret_info)) - && can_add_diagnose_info()) { - SET_DIAGNOSE_INFO( - info_array_[idx_++], - MINI_MERGE, - MTL_ID(), - ls_id, - tablet_id, - ObCompactionDiagnoseInfo::DIA_STATUS_FAILED, - ret_info.add_time_, - "schedule_suspect_info", ret_info.suspect_info_); + char tmp_str[common::OB_DIAGNOSE_INFO_LENGTH] = "\0"; + if (OB_SUCC(get_suspect_info(MINI_MERGE, ls_id, tablet_id, ret_info, tmp_str, sizeof(tmp_str))) + && can_add_diagnose_info() + && OB_TMP_FAIL(SET_DIAGNOSE_INFO( + info_array_[idx_++], + MINI_MERGE, + MTL_ID(), + ls_id, + tablet_id, + ObCompactionDiagnoseInfo::DIA_STATUS_FAILED, + ret_info.add_time_, + "schedule_suspect_info", tmp_str))) { + LOG_WARN("failed to add dignose info about memtable release", K(tmp_ret), K(tmp_str)); } } } @@ -752,13 +1041,18 @@ int ObCompactionDiagnoseMgr::diagnose_tablet_minor_merge(const ObLSID &ls_id, Ob { int ret = OB_SUCCESS; int64_t minor_compact_trigger = ObPartitionMergePolicy::DEFAULT_MINOR_COMPACT_TRIGGER; + ObTabletMemberWrapper table_store_wrapper; + { omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID())); if (tenant_config.is_valid()) { minor_compact_trigger = tenant_config->minor_compact_trigger; } } - if (tablet.get_table_store().get_minor_sstables().count() >= minor_compact_trigger) { + + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (table_store_wrapper.get_member()->get_minor_sstables().count() >= minor_compact_trigger) { ObTabletMergeExecuteDag dag; if (OB_FAIL(diagnose_tablet_merge( dag, @@ -780,13 +1074,19 @@ int ObCompactionDiagnoseMgr::diagnose_tablet_medium_merge( const storage::ObMergeType merge_type = MEDIUM_MERGE; const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; const int64_t max_serialized_medium_scn = tablet.get_tablet_meta().max_serialized_medium_scn_; - ObITable *last_major = tablet.get_table_store().get_major_sstables().get_boundary_table(true/*last*/); + ObITable *last_major_sstable = nullptr; int64_t max_sync_medium_scn = 0; + ObTabletMemberWrapper table_store_wrapper; + ObArenaAllocator allocator; + const compaction::ObMediumCompactionInfoList *medium_list = nullptr; - if (OB_ISNULL(last_major)) { + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_ISNULL(last_major_sstable = + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/))) { } else if (OB_FAIL(tablet.get_max_sync_medium_scn(max_sync_medium_scn))){ LOG_WARN("failed to get max sync medium scn", K(ret), K(ls_id), K(tablet_id)); - } else if (max_sync_medium_scn > last_major->get_snapshot_version()) { + } else if (max_sync_medium_scn > last_major_sstable->get_snapshot_version()) { if (tablet.get_snapshot_version() < max_sync_medium_scn) { // wait mini compaction or tablet freeze if (ObTimeUtility::fast_current_time() > max_sync_medium_scn + WAIT_MEDIUM_SCHEDULE_INTERVAL * 2 && can_add_diagnose_info() @@ -811,7 +1111,7 @@ int ObCompactionDiagnoseMgr::diagnose_tablet_medium_merge( ls_id, tablet_id, max_sync_medium_scn))) { - LOG_WARN("diagnose failed", K(ret), K(ls_id), K(tablet_id), KPC(last_major)); + LOG_WARN("diagnose failed", K(ret), K(ls_id), K(tablet_id), KPC(last_major_sstable)); } } } @@ -826,18 +1126,24 @@ int ObCompactionDiagnoseMgr::diagnose_tablet_major_merge( { int ret = OB_SUCCESS; tablet_major_finish = true; - const ObTabletTableStore &table_store = tablet.get_table_store(); const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; const ObMergeType merge_type = MEDIUM_MERGE; int64_t max_sync_medium_scn = 0; - ObSSTable *latest_major_sstable = static_cast( - table_store.get_major_sstables().get_boundary_table(true/*last*/)); + ObTabletMemberWrapper table_store_wrapper; if (OB_UNLIKELY(compaction_scn <= 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(compaction_scn)); + } else if (tablet.get_tablet_meta().has_transfer_table()) { + if (REACH_TENANT_TIME_INTERVAL(30 * 1000L * 1000L/*30s*/)) { + LOG_INFO("The tablet in the transfer process does not do major_merge", "tablet_id", tablet.get_tablet_meta().tablet_id_); + } } else if (OB_FAIL(tablet.get_max_sync_medium_scn(max_sync_medium_scn))) { LOG_WARN("failed to get max sync medium snapshot", K(ret), K(tablet_id)); + } else if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { + ObSSTable *latest_major_sstable = static_cast( + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/)); int tmp_ret = OB_SUCCESS; if (nullptr == latest_major_sstable || latest_major_sstable->get_snapshot_version() < compaction_scn) { @@ -917,18 +1223,24 @@ int ObCompactionDiagnoseMgr::get_suspect_and_warning_info( const ObMergeType merge_type, const ObLSID ls_id, const ObTabletID tablet_id, - ObScheduleSuspectInfo &info) + ObScheduleSuspectInfo &info, + char *buf, + const int64_t buf_len) { int ret = OB_SUCCESS; - ObDagWarningInfo *warning_info = nullptr; + ObDagWarningInfo warning_info; bool add_schedule_info = false; - if (OB_FAIL(ObScheduleSuspectInfoMgr::get_instance().get_suspect_info( - ObScheduleSuspectInfo::gen_hash(MTL_ID(), dag.hash()), info))) { + ObInfoParamBuffer allocator; + if (OB_FAIL(MTL(ObScheduleSuspectInfoMgr *)->get_with_param(ObScheduleSuspectInfo::gen_hash(MTL_ID(), dag.hash()), &info, allocator))) { if (OB_HASH_NOT_EXIST != ret) { LOG_WARN("failed to get suspect info", K(ret), K(ls_id), K(tablet_id)); } else { // no schedule suspect info - if (OB_FAIL(share::ObDagWarningHistoryManager::get_instance().get(dag.hash(), warning_info))) { + info.info_param_ = nullptr; + allocator.reuse(); + char tmp_str[common::OB_DAG_WARNING_INFO_LENGTH] = "\0"; + if (OB_FAIL(MTL(ObDagWarningHistoryManager *)->get_with_param( + dag.hash(), &warning_info, allocator))) { // check __all_virtual_dag_warning_history if (OB_HASH_NOT_EXIST != ret) { LOG_WARN("failed to get dag warning info", K(ret), K(ls_id), K(tablet_id)); @@ -936,22 +1248,27 @@ int ObCompactionDiagnoseMgr::get_suspect_and_warning_info( ret = OB_SUCCESS; LOG_DEBUG("may wait for schedule", K(ret), K(ls_id), K(tablet_id)); } - } else if (can_add_diagnose_info() - && OB_FAIL(SET_DIAGNOSE_INFO( + } else if (can_add_diagnose_info()) { + if (OB_FAIL(warning_info.info_param_->fill_comment(tmp_str, sizeof(tmp_str)))) { + STORAGE_LOG(WARN, "failed to fill comment from info param", K(ret)); + }else if (OB_FAIL(SET_DIAGNOSE_INFO( info_array_[idx_++], merge_type, MTL_ID(), ls_id, tablet_id, ObCompactionDiagnoseInfo::DIA_STATUS_FAILED, - warning_info->gmt_create_, - "error_no", warning_info->dag_ret_, - "last_error_time", warning_info->gmt_modified_, - "error_trace", warning_info->task_id_, - "warning", warning_info->warning_info_))) { - LOG_WARN("failed to add diagnose info", K(ret), K(ls_id), K(tablet_id), KPC(warning_info)); + warning_info.gmt_create_, + "error_no", warning_info.dag_ret_, + "last_error_time", warning_info.gmt_modified_, + "error_trace", warning_info.task_id_, + "warning", tmp_str))) { + LOG_WARN("failed to add diagnose info", K(ret), K(ls_id), K(tablet_id)); + } } } + } else if (OB_FAIL(info.info_param_->fill_comment(buf, buf_len))) { + STORAGE_LOG(WARN, "failed to fill comment from info param", K(ret)); } return ret; } @@ -967,7 +1284,8 @@ int ObCompactionDiagnoseMgr::diagnose_no_dag( ObScheduleSuspectInfo info; bool add_schedule_info = false; - if (OB_FAIL(get_suspect_and_warning_info(dag, merge_type, ls_id, tablet_id, info))) { + char tmp_str[common::OB_DIAGNOSE_INFO_LENGTH] = "\0"; + if (OB_FAIL(get_suspect_and_warning_info(dag, merge_type, ls_id, tablet_id, info, tmp_str, sizeof(tmp_str)))) { LOG_WARN("failed to get suspect and warning info", K(ret), K(ls_id), K(tablet_id)); } else if (!info.is_valid()) { // do nothing @@ -1009,8 +1327,8 @@ int ObCompactionDiagnoseMgr::diagnose_no_dag( add_schedule_info = true; } - if (OB_SUCC(ret) && add_schedule_info && can_add_diagnose_info() - && OB_FAIL(SET_DIAGNOSE_INFO( + if (OB_SUCC(ret) && add_schedule_info && can_add_diagnose_info()) { + if (OB_FAIL(SET_DIAGNOSE_INFO( info_array_[idx_++], merge_type, MTL_ID(), @@ -1018,8 +1336,9 @@ int ObCompactionDiagnoseMgr::diagnose_no_dag( tablet_id, ObCompactionDiagnoseInfo::DIA_STATUS_NOT_SCHEDULE, info.add_time_, - "schedule_suspect_info", info.suspect_info_))) { - LOG_WARN("failed to add diagnose info", K(ret), K(ls_id), K(tablet_id), K(info)); + "schedule_suspect_info", tmp_str))) { + LOG_WARN("failed to add diagnose info", K(ret), K(ls_id), K(tablet_id), K(info)); + } } return ret; } @@ -1055,7 +1374,7 @@ int ObCompactionDiagnoseIterator::get_diagnose_info(const int64_t tenant_id) void * buf = nullptr; if (NULL == (buf = allocator_.alloc(sizeof(ObCompactionDiagnoseInfo) * MAX_DIAGNOSE_INFO_CNT))) { ret = common::OB_ALLOCATE_MEMORY_FAILED; - COMMON_LOG(WARN, "failed to alloc info array", K(ret)); + STORAGE_LOG(WARN, "failed to alloc info array", K(ret)); } else if (FALSE_IT(info_array_ = new (buf) ObCompactionDiagnoseInfo[MAX_DIAGNOSE_INFO_CNT])) { } else if (OB_FAIL(diagnose_mgr.init(info_array_, MAX_DIAGNOSE_INFO_CNT))) { LOG_WARN("failed to init diagnose info mgr", K(ret)); diff --git a/src/storage/compaction/ob_compaction_diagnose.h b/src/storage/compaction/ob_compaction_diagnose.h old mode 100644 new mode 100755 index 58b0f5b79..5fd96f417 --- a/src/storage/compaction/ob_compaction_diagnose.h +++ b/src/storage/compaction/ob_compaction_diagnose.h @@ -15,6 +15,8 @@ #include "storage/ob_i_store.h" #include "ob_tablet_merge_task.h" +#include "lib/list/ob_dlist.h" +#include "share/scheduler/ob_diagnose_config.h" namespace oceanbase { @@ -30,59 +32,335 @@ using namespace storage; using namespace share; namespace compaction { +class ObIDiagnoseInfoMgr; struct ObDiagnoseTabletCompProgress; -struct ObScheduleSuspectInfo : public common::ObDLinkBase, public ObMergeDagHash +enum ObInfoParamStructType { + SUSPECT_INFO_PARAM = 0, + DAG_WARNING_INFO_PARAM, + INFO_PARAM_TYPE_MAX +}; + +struct ObInfoParamStruct { + int max_type_; + const share::ObDiagnoseInfoStruct *info_type; +}; + +static constexpr ObInfoParamStruct OB_DIAGNOSE_INFO_PARAMS[] = { + {share::ObSuspectInfoType::SUSPECT_INFO_TYPE_MAX, share::OB_SUSPECT_INFO_TYPES}, + {ObDagType::ObDagTypeEnum::DAG_TYPE_MAX, share::OB_DAG_WARNING_INFO_TYPES}, +}; + +union ObInfoParamType{ + share::ObSuspectInfoType suspect_type_; + ObDagType::ObDagTypeEnum dag_type_; +}; + +struct ObIBasicInfoParam +{ + ObIBasicInfoParam() + : type_(), + struct_type_(INFO_PARAM_TYPE_MAX) + {} + virtual void destroy() = 0; + virtual int64_t get_deep_copy_size() const = 0; + + virtual int fill_comment(char *buf, const int64_t buf_len) const = 0; + virtual int deep_copy(ObIAllocator &allocator, ObIBasicInfoParam *&out_param) const = 0; + + static const int64_t MAX_INFO_PARAM_SIZE = 256; + + ObInfoParamType type_; + ObInfoParamStructType struct_type_; +}; + +static const int64_t OB_DIAGNOSE_INFO_PARAM_STR_LENGTH = 64; +template +struct ObDiagnoseInfoParam : public ObIBasicInfoParam +{ + ObDiagnoseInfoParam() + : ObIBasicInfoParam() + { + MEMSET(param_int_, 0, int_size * sizeof(int64_t)); + MEMSET(comment_, 0, str_size); + } + virtual void destroy() override; + virtual int64_t get_deep_copy_size() const override; + virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int deep_copy(ObIAllocator &allocator, ObIBasicInfoParam *&out_param) const override; + + int64_t param_int_[int_size]; + char comment_[str_size]; +}; + +struct ObIDiagnoseInfo : public common::ObDLinkBase { + ObIDiagnoseInfo() + : is_deleted_(false), + seq_num_(0), + tenant_id_(OB_INVALID_ID), + info_param_(nullptr) + {} + virtual void destroy(ObIAllocator &allocator) + { + if (OB_NOT_NULL(info_param_)) { + info_param_->destroy(); + allocator.free(info_param_); + info_param_ = nullptr; + } + allocator.free(this); + } + virtual void shallow_copy(ObIDiagnoseInfo *other) = 0; + virtual void update(ObIDiagnoseInfo *other) {} + virtual int64_t get_add_time() const { return INT_MAX64; } + virtual int64_t get_hash() const { return 0; } + template + int deep_copy(ObIAllocator &allocator, T *&out_info); + bool is_deleted() const { return ATOMIC_LOAD(&is_deleted_); } + void set_deleted() { ATOMIC_SET(&is_deleted_, true); } + // for iterator + bool is_deleted_; + uint64_t seq_num_; + uint64_t tenant_id_; + // + ObIBasicInfoParam *info_param_; +}; + +/* ObIDiagnoseInfo func */ +template +int ObIDiagnoseInfo::deep_copy(ObIAllocator &allocator, T *&out_info) +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + out_info = nullptr; + if(OB_ISNULL(buf = allocator.alloc(sizeof(T)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + } else { + T *info = nullptr; + if (OB_ISNULL(info = new (buf) T())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "new diagnose info is nullptr", K(ret)); + } else if (OB_NOT_NULL(info_param_)) { + if (OB_FAIL(info_param_->deep_copy(allocator, info->info_param_))){ + STORAGE_LOG(WARN, "fail to deep copy info param", K(ret)); + } + } + + if (OB_SUCC(ret)) { + info->shallow_copy(this); + out_info = info; + } else if (OB_NOT_NULL(info)) { + info->destroy(allocator); + info = nullptr; + } else { + allocator.free(buf); + } + } + return ret; +} + +struct ObScheduleSuspectInfo : public ObIDiagnoseInfo, public ObMergeDagHash { ObScheduleSuspectInfo() - : ObMergeDagHash(), - tenant_id_(OB_INVALID_ID), + : ObIDiagnoseInfo(), + ObMergeDagHash(), add_time_(0), - suspect_info_("\0") + hash_(0) {} int64_t hash() const; bool is_valid() const; - ObScheduleSuspectInfo & operator = (const ObScheduleSuspectInfo &other); + virtual void shallow_copy(ObIDiagnoseInfo *other) override; + virtual int64_t get_add_time() const override; + virtual int64_t get_hash() const override; static int64_t gen_hash(int64_t tenant_id, int64_t dag_hash); - TO_STRING_KV(K_(tenant_id), K_(merge_type), K_(ls_id), K_(tablet_id), K_(add_time), K_(suspect_info)); - int64_t tenant_id_; + TO_STRING_KV(K_(tenant_id), K_(merge_type), K_(ls_id), K_(tablet_id), K_(add_time), K_(hash)); + int64_t add_time_; - char suspect_info_[common::OB_DIAGNOSE_INFO_LENGTH]; + int64_t hash_; }; -class ObScheduleSuspectInfoMgr { +class ObIDiagnoseInfoMgr { public: - ObScheduleSuspectInfoMgr(); - ~ObScheduleSuspectInfoMgr() { destroy(); } + struct Iterator { + Iterator() + : is_opened_(false), + version_(0), + seq_num_(0), + current_info_(nullptr) + {} + virtual ~Iterator() { reset(); } + void reset() + { + is_opened_ = false; + version_ = 0; + seq_num_ = 0; + current_info_ = nullptr; + } + bool is_opened() const { return is_opened_; } - static ObScheduleSuspectInfoMgr &get_instance() { - static ObScheduleSuspectInfoMgr instance_; - return instance_; + int open(const uint64_t version, ObIDiagnoseInfo *current_info, ObIDiagnoseInfoMgr *info_pool); + int get_next(ObIDiagnoseInfo *out_info, char *buf, const int64_t buf_len); + + private: + int next(); + public: + bool is_opened_; + uint64_t version_; + uint64_t seq_num_; + ObIDiagnoseInfo *current_info_; + ObIDiagnoseInfoMgr *info_pool_; + }; + + ObIDiagnoseInfoMgr() + : is_inited_(false), + page_size_(0), + version_(0), + seq_num_(0), + pool_label_(), + bucket_label_(), + node_label_(), + lock_(common::ObLatchIds::INFO_MGR_LOCK), + rwlock_(common::ObLatchIds::INFO_MGR_LOCK), + allocator_(), + info_list_() + { + MEMSET(pool_label_, '\0', sizeof(pool_label_)); + MEMSET(bucket_label_, '\0', sizeof(bucket_label_)); + MEMSET(node_label_, '\0', sizeof(node_label_)); } + virtual ~ObIDiagnoseInfoMgr() { destroy(); } + + int init(bool with_map, + const uint64_t tenant_id, + const char* basic_label, + const int64_t page_size=INFO_PAGE_SIZE, + int64_t max_size=INFO_MAX_SIZE); - int init(); void destroy(); + void clear(); + void clear_with_no_lock(); + int size(); - int add_suspect_info(const int64_t key_value, ObScheduleSuspectInfo &info); - int get_suspect_info(const int64_t key_value, ObScheduleSuspectInfo &info); - int del_suspect_info(const int64_t key_value); + template + int alloc_and_add(const int64_t key, T *input_info); + int get_with_param(const int64_t key, ObIDiagnoseInfo *out_info, ObIAllocator &allocator); + int delete_info(const int64_t key); + + int set_max(const int64_t size); int gc_info(); + int open_iter(Iterator &iter); + private: - static const int64_t SUSPECT_INFO_BUCKET_NUM = 1000; - static const int64_t SUSPECT_INFO_LIMIT = 10000; - static const int64_t GC_INFO_TIME_LIMIT = 1L * 60 * 60 * 1000 * 1000L; // 1hr - typedef common::hash::ObHashMap InfoMap; + int add_with_no_lock(const int64_t key, ObIDiagnoseInfo *info); + // info may update based on old_info // allow info is null + int del_with_no_lock(const int64_t key, ObIDiagnoseInfo *info); + int get_with_no_lock(const int64_t key, ObIDiagnoseInfo *&info); + int purge_with_rw_lock(bool batch_purge = false); + +public: + static const int64_t MAX_ALLOC_RETRY_TIMES = 10; + static const int64_t GC_HIGH_PERCENTAGE = 80; // GC_HIGH_PERCENTAGE/100 + static const int64_t GC_LOW_PERCENTAGE = 40; // GC_LOW_PERCENTAGE/100 + static const int64_t INFO_BUCKET_LIMIT = 1000; + static const int64_t INFO_PAGE_SIZE = (1 << 16); // 64KB + static const int64_t INFO_PAGE_SIZE_LIMIT = (1 << 11); // 2KB + static const int64_t INFO_IDLE_SIZE = 16LL * 1024LL * 1024LL; // 16MB + static const int64_t INFO_MAX_SIZE = 16LL * 1024LL * 1024LL; // 16MB // lowest + typedef common::hash::ObHashMap InfoMap; + typedef common::ObDList InfoList; + + + +protected: + bool is_inited_; + int64_t page_size_; + uint64_t version_; // locked by rwlock_ + uint64_t seq_num_; // locked by lock_ + char pool_label_[lib::AOBJECT_LABEL_SIZE + 1]; + char bucket_label_[lib::AOBJECT_LABEL_SIZE + 1]; + char node_label_[lib::AOBJECT_LABEL_SIZE + 1]; + common::SpinRWLock lock_; + common::SpinRWLock rwlock_; + ObFIFOAllocator allocator_; + InfoList info_list_; + InfoMap info_map_; +}; + +template +int ObIDiagnoseInfoMgr::alloc_and_add(const int64_t key, T *input_info) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ObIDiagnoseInfoMgr is not init", K(ret)); + } else if (OB_ISNULL(input_info)) { + ret = OB_INVALID_ARGUMENT; + } else { + T *info = NULL; + common::SpinWLockGuard guard(lock_); + if (info_map_.created()) { + if (OB_FAIL(del_with_no_lock(key, input_info))) { + if (OB_HASH_NOT_EXIST != ret) { + STORAGE_LOG(WARN, "failed to del old info", K(ret), K(key)); + } + } + } + + if (OB_HASH_NOT_EXIST == ret || OB_SUCC(ret)) { + ret = OB_SUCCESS; + int64_t retry_nums = MAX_ALLOC_RETRY_TIMES; + while (OB_SUCC(ret) && retry_nums-- && + OB_ALLOCATE_MEMORY_FAILED == input_info->deep_copy(allocator_, info)) { + // retry + ret = purge_with_rw_lock(true); + } + if (OB_FAIL(ret)) { + STORAGE_LOG(WARN, "failed to add info into pool", K(ret), K(key)); + } else if (OB_FAIL(add_with_no_lock(key, info))) { + STORAGE_LOG(WARN, "failed to add info into pool", K(ret), K(key)); + } + } + } + return ret; +} + +class ObScheduleSuspectInfoMgr : public ObIDiagnoseInfoMgr { +public: + static int mtl_init(ObScheduleSuspectInfoMgr *&schedule_suspect_info); + static int64_t cal_max(); + ObScheduleSuspectInfoMgr() + : ObIDiagnoseInfoMgr() + {} + ~ObScheduleSuspectInfoMgr() { destroy(); } + + void destroy() { + ObIDiagnoseInfoMgr::destroy(); + STORAGE_LOG(INFO, "ObScheduleSuspectInfoMgr destroy finish"); + } + int add_suspect_info(const int64_t key_value, ObScheduleSuspectInfo &info); public: static const int64_t EXTRA_INFO_LEN = 900; + static constexpr double MEMORY_PERCENTAGE = 0.5; // max size = tenant memory size * MEMORY_PERCENTAGE / 100 + static const int64_t POOL_MAX_SIZE = 48LL * 1024LL * 1024LL; // 48MB +}; -private: - bool is_inited_; - common::DefaultPageAllocator allocator_; - common::SpinRWLock lock_; - InfoMap info_map_; +class ObInfoParamBuffer : public ObDataBuffer +{ +public: + ObInfoParamBuffer() + : ObDataBuffer(buff, sizeof(buff)) + {} + virtual ~ObInfoParamBuffer() {} + + void reuse() + { + reset(); + (void)set_data(buff, sizeof(buff)); + } +protected: + char buff[ObIBasicInfoParam::MAX_INFO_PARAM_SIZE]; }; struct ObCompactionDiagnoseInfo @@ -161,14 +439,19 @@ private: const ObMergeType merge_type, const ObLSID ls_id, const ObTabletID tablet_id, - ObScheduleSuspectInfo &info); + ObScheduleSuspectInfo &info, + char *buf, + const int64_t buf_len); + int diagnose_medium_scn_table(const int64_t compaction_scn); OB_INLINE bool can_add_diagnose_info() { return idx_ < max_cnt_; } int get_suspect_info( const ObMergeType merge_type, const ObLSID &ls_id, const ObTabletID &tablet_id, - ObScheduleSuspectInfo &ret_info); + ObScheduleSuspectInfo &ret_info, + char *buf, + const int64_t buf_len); int check_if_need_diagnose(rootserver::ObMajorFreezeService *&major_freeze_service, bool &need_diagnose) const; int do_tenant_major_merge_diagnose(rootserver::ObMajorFreezeService *major_freeze_service); @@ -219,8 +502,8 @@ private: dag_hash.tablet_id_ = tablet_id; \ int64_t tenant_id = MTL_ID(); \ int64_t hash_value = ObScheduleSuspectInfo::gen_hash(tenant_id, dag_hash.inner_hash()); \ - if (OB_TMP_FAIL(ObScheduleSuspectInfoMgr::get_instance().del_suspect_info(hash_value))) { \ - if (OB_HASH_NOT_EXIST != tmp_ret) { \ + if (OB_TMP_FAIL(MTL(ObScheduleSuspectInfoMgr *)->delete_info(hash_value))) { \ + if (OB_HASH_NOT_EXIST != ret) { \ STORAGE_LOG(WARN, "failed to add suspect info", K(tmp_ret), K(dag_hash), K(tenant_id)); \ } else { \ tmp_ret = OB_SUCCESS; \ @@ -230,38 +513,6 @@ private: } \ } -#define DEFINE_SUSPECT_PRINT_KV(n) \ - template \ - int ADD_SUSPECT_INFO(storage::ObMergeType type, const ObLSID ls_id, \ - const ObTabletID tablet_id, \ - const char *info_string, LOG_PARAMETER_KV##n) \ - { \ - int64_t __pos = 0; \ - int ret = OB_SUCCESS; \ - compaction::ObScheduleSuspectInfo info; \ - info.tenant_id_ = MTL_ID(); \ - info.merge_type_ = type; \ - info.ls_id_ = ls_id; \ - info.tablet_id_ = tablet_id; \ - info.add_time_ = ObTimeUtility::fast_current_time(); \ - char *buf = info.suspect_info_; \ - const int64_t buf_size = ::oceanbase::common::OB_DIAGNOSE_INFO_LENGTH; \ - if (strlen(info_string) < buf_size) { \ - strncpy(buf, info_string, strlen(info_string)); \ - } \ - __pos += strlen(info_string); \ - if (__pos > 0 && __pos < buf_size) { \ - buf[__pos++] = '.'; \ - } \ - SIMPLE_TO_STRING_##n \ - if (OB_FAIL(ObScheduleSuspectInfoMgr::get_instance().add_suspect_info(info.hash(), info))) { \ - STORAGE_LOG(WARN, "failed to add suspect info", K(ret), K(info)); \ - } else { \ - STORAGE_LOG(DEBUG, "success to add suspect info", K(ret), K(info)); \ - } \ - return ret; \ - } - #define DEFINE_DIAGNOSE_PRINT_KV(n) \ template \ int SET_DIAGNOSE_INFO(ObCompactionDiagnoseInfo &diagnose_info, storage::ObMergeType type, \ @@ -281,8 +532,12 @@ private: char *buf = diagnose_info.diagnose_info_; \ const int64_t buf_size = ::oceanbase::common::OB_DIAGNOSE_INFO_LENGTH; \ SIMPLE_TO_STRING_##n \ - buf[__pos] = '\0'; \ - return ret; \ + if (__pos < buf_size) { \ + buf[__pos-1] = '\0'; \ + } else { \ + buf[__pos] = '\0'; \ + } \ + return ret; \ } #define DEFINE_COMPACITON_INFO_ADD_KV(n) \ @@ -298,54 +553,43 @@ private: buf[__pos] = '\0'; \ } -#define SIMPLE_TO_STRING_1 \ +#define SIMPLE_TO_STRING(n) \ if (OB_FAIL(ret)) { \ - } else if (OB_FAIL(::oceanbase::common::logdata_print_key_obj(buf, buf_size - 1, __pos, key1, false, obj1))) { \ + } else if (OB_FAIL(::oceanbase::common::logdata_print_key_obj(buf, buf_size - 1, __pos, key##n, false, obj##n))) { \ } else if (__pos + 1 >= buf_size) { \ } else { \ - buf[__pos++] = ','; \ + buf[__pos++] = ','; \ } +#define SIMPLE_TO_STRING_1 SIMPLE_TO_STRING(1) + #define SIMPLE_TO_STRING_2 \ SIMPLE_TO_STRING_1 \ - if (OB_FAIL(ret)) { \ - } else if (OB_FAIL(::oceanbase::common::logdata_print_key_obj(buf, buf_size - 1, __pos, key2, false, obj2))) { \ - } else if (__pos + 1 >= buf_size) { \ - } else { \ - buf[__pos++] = ','; \ - } + SIMPLE_TO_STRING(2) #define SIMPLE_TO_STRING_3 \ SIMPLE_TO_STRING_2 \ - if (OB_FAIL(ret)) { \ - } else if (OB_FAIL(::oceanbase::common::logdata_print_key_obj(buf, buf_size - 1, __pos, key3, false, obj3))) { \ - } else if (__pos + 1 >= buf_size) { \ - } else { \ - buf[__pos++] = ','; \ - } + SIMPLE_TO_STRING(3) + #define SIMPLE_TO_STRING_4 \ SIMPLE_TO_STRING_3 \ - if (OB_FAIL(ret)) { \ - } else if (OB_FAIL(::oceanbase::common::logdata_print_key_obj(buf, buf_size - 1, __pos, key4, false, obj4))) { \ - } else if (__pos + 1 >= buf_size) { \ - } else { \ - buf[__pos++] = ','; \ - } + SIMPLE_TO_STRING(4) #define SIMPLE_TO_STRING_5 \ SIMPLE_TO_STRING_4 \ - if (OB_FAIL(ret)) { \ - } else if (OB_FAIL(::oceanbase::common::logdata_print_key_obj(buf, buf_size - 1, __pos, key5, false, obj5))) { \ - } else if (__pos + 1 >= buf_size) { \ - } else { \ - buf[__pos++] = ','; \ - } + SIMPLE_TO_STRING(5) -DEFINE_SUSPECT_PRINT_KV(1) -DEFINE_SUSPECT_PRINT_KV(2) -DEFINE_SUSPECT_PRINT_KV(3) -DEFINE_SUSPECT_PRINT_KV(4) -DEFINE_SUSPECT_PRINT_KV(5) +#define SIMPLE_TO_STRING_6 \ + SIMPLE_TO_STRING_5 \ + SIMPLE_TO_STRING(6) + +#define SIMPLE_TO_STRING_7 \ + SIMPLE_TO_STRING_6 \ + SIMPLE_TO_STRING(7) + +#define SIMPLE_TO_STRING_8 \ + SIMPLE_TO_STRING_7 \ + SIMPLE_TO_STRING(8) DEFINE_DIAGNOSE_PRINT_KV(1) DEFINE_DIAGNOSE_PRINT_KV(2) @@ -358,7 +602,193 @@ DEFINE_COMPACITON_INFO_ADD_KV(2) DEFINE_COMPACITON_INFO_ADD_KV(3) DEFINE_COMPACITON_INFO_ADD_KV(4) DEFINE_COMPACITON_INFO_ADD_KV(5) +DEFINE_COMPACITON_INFO_ADD_KV(6) +DEFINE_COMPACITON_INFO_ADD_KV(7) +DEFINE_COMPACITON_INFO_ADD_KV(8) +#define INFO_PARAM_INT(n) T param_int##n +#define INFO_PARAM_INT0 +#define INFO_PARAM_INT1 INFO_PARAM_INT(1) +#define INFO_PARAM_INT2 INFO_PARAM_INT1, INFO_PARAM_INT(2) +#define INFO_PARAM_INT3 INFO_PARAM_INT2, INFO_PARAM_INT(3) +#define INFO_PARAM_INT4 INFO_PARAM_INT3, INFO_PARAM_INT(4) +#define INFO_PARAM_INT5 INFO_PARAM_INT4, INFO_PARAM_INT(5) +#define INFO_PARAM_INT6 INFO_PARAM_INT5, INFO_PARAM_INT(6) +#define INFO_PARAM_INT7 INFO_PARAM_INT6, INFO_PARAM_INT(7) + +#define INT_TO_PARAM_1 \ + info_param->param_int_[0] = param_int1; + +#define INT_TO_PARAM_2 \ + INT_TO_PARAM_1 \ + info_param->param_int_[1] = param_int2; + +#define INT_TO_PARAM_3 \ + INT_TO_PARAM_2 \ + info_param->param_int_[2] = param_int3; + +#define INT_TO_PARAM_4 \ + INT_TO_PARAM_3 \ + info_param->param_int_[3] = param_int4; + +#define INT_TO_PARAM_5 \ + INT_TO_PARAM_4 \ + info_param->param_int_[4] = param_int5; + +#define INT_TO_PARAM_6 \ + INT_TO_PARAM_5 \ + info_param->param_int_[5] = param_int6; + +#define INT_TO_PARAM_7 \ + INT_TO_PARAM_6 \ + info_param->param_int_[6] = param_int7; + +#define DEFINE_SUSPECT_INFO_ADD(n_int) \ + template \ + int ADD_SUSPECT_INFO(storage::ObMergeType type, const ObLSID ls_id, \ + const ObTabletID tablet_id, ObSuspectInfoType info_type, \ + INFO_PARAM_INT##n_int) \ + { \ + int64_t __pos = 0; \ + int ret = OB_SUCCESS; \ + compaction::ObScheduleSuspectInfo info; \ + info.tenant_id_ = MTL_ID(); \ + info.merge_type_ = type; \ + info.ls_id_ = ls_id; \ + info.tablet_id_ = tablet_id; \ + info.add_time_ = ObTimeUtility::fast_current_time(); \ + info.hash_ = info.hash(); \ + ObDiagnoseInfoParam param; \ + ObDiagnoseInfoParam *info_param = ¶m; \ + info_param->type_.suspect_type_ = info_type; \ + info_param->struct_type_ = ObInfoParamStructType::SUSPECT_INFO_PARAM; \ + INT_TO_PARAM_##n_int \ + info.info_param_ = info_param; \ + if (OB_FAIL(MTL(ObScheduleSuspectInfoMgr *)->add_suspect_info(info.hash(), info))) { \ + STORAGE_LOG(WARN, "failed to add suspect info", K(ret), K(info)); \ + } else { \ + STORAGE_LOG(DEBUG, "success to add suspect info", K(ret), K(info)); \ + } \ + return ret; \ + } + +#define DEFINE_SUSPECT_INFO_ADD_EXTRA(n, n_int) \ + template \ + int ADD_SUSPECT_INFO(storage::ObMergeType type, const ObLSID ls_id, \ + const ObTabletID tablet_id, ObSuspectInfoType info_type, \ + INFO_PARAM_INT##n_int, LOG_PARAMETER_KV##n) \ + { \ + int64_t __pos = 0; \ + int ret = OB_SUCCESS; \ + compaction::ObScheduleSuspectInfo info; \ + info.tenant_id_ = MTL_ID(); \ + info.merge_type_ = type; \ + info.ls_id_ = ls_id; \ + info.tablet_id_ = tablet_id; \ + info.add_time_ = ObTimeUtility::fast_current_time(); \ + info.hash_ = info.hash(); \ + ObDiagnoseInfoParam param; \ + ObDiagnoseInfoParam *info_param = ¶m; \ + INT_TO_PARAM_##n_int \ + info_param->type_.suspect_type_ = info_type; \ + info_param->struct_type_ = ObInfoParamStructType::SUSPECT_INFO_PARAM; \ + char *buf = info_param->comment_; \ + const int64_t buf_size = OB_DIAGNOSE_INFO_PARAM_STR_LENGTH; \ + SIMPLE_TO_STRING_##n \ + info.info_param_ = info_param; \ + if (OB_FAIL(ret)) { \ + STORAGE_LOG(WARN, "fail to fill parameter kv into info param", K(ret)); \ + } else if (OB_FAIL(MTL(ObScheduleSuspectInfoMgr *)->add_suspect_info(info.hash(), info))) { \ + STORAGE_LOG(WARN, "failed to add suspect info", K(ret), K(info)); \ + } else { \ + STORAGE_LOG(DEBUG, "success to add suspect info", K(ret), K(info)); \ + } \ + return ret; \ + } + +DEFINE_SUSPECT_INFO_ADD(1) +DEFINE_SUSPECT_INFO_ADD(2) +DEFINE_SUSPECT_INFO_ADD(3) +DEFINE_SUSPECT_INFO_ADD(4) +DEFINE_SUSPECT_INFO_ADD(5) + +DEFINE_SUSPECT_INFO_ADD_EXTRA(1, 1) +DEFINE_SUSPECT_INFO_ADD_EXTRA(1, 3) +// ObDiagnoseInfoParam func +template +void ObDiagnoseInfoParam::destroy() +{ + MEMSET(param_int_, 0, int_size * sizeof(int64_t)); + MEMSET(comment_, 0, str_size); +} + +template +int64_t ObDiagnoseInfoParam::get_deep_copy_size() const +{ + return sizeof(*this); +} + +template +int ObDiagnoseInfoParam::fill_comment(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + int type = ObDagType::ObDagTypeEnum::DAG_TYPE_MAX; + if (OB_ISNULL(buf)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), KP(buf)); + } else if (INFO_PARAM_TYPE_MAX <= struct_type_) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "unexpected struct_type", K(ret), K_(struct_type)); + } else if (FALSE_IT(type = (SUSPECT_INFO_PARAM == struct_type_ ? type_.suspect_type_ : type_.dag_type_))) { + } else if (OB_DIAGNOSE_INFO_PARAMS[struct_type_].max_type_ <= type) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "unexpected type", K(ret), K(type), K(OB_DIAGNOSE_INFO_PARAMS[struct_type_].max_type_)); + } else if (OB_DIAGNOSE_INFO_PARAMS[struct_type_].info_type[type].int_size != int_size) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "unexpected int size", K(ret), K_(struct_type), K(type), K(int_size), + K(OB_DIAGNOSE_INFO_PARAMS[struct_type_].info_type[type].int_size)); + } else { + ADD_COMPACTION_INFO_PARAM(buf, buf_len, + "info", OB_DIAGNOSE_INFO_PARAMS[struct_type_].info_type[type].info_str); + for (int i = 0; i < int_size; i++) { + ADD_COMPACTION_INFO_PARAM(buf, buf_len, + OB_DIAGNOSE_INFO_PARAMS[struct_type_].info_type[type].info_str_fmt[i], param_int_[i]); + } + if (OB_DIAGNOSE_INFO_PARAMS[struct_type_].info_type[type].with_comment) { + ADD_COMPACTION_INFO_PARAM(buf, buf_len, "extra_info", comment_); + } + } + return ret; +} + +template +int ObDiagnoseInfoParam::deep_copy(ObIAllocator &allocator, ObIBasicInfoParam *&out_param) const +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + out_param = nullptr; + if (OB_ISNULL(buf = allocator.alloc(get_deep_copy_size()))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "fail to alloc memory", K(ret)); + } else { + ObDiagnoseInfoParam *info_param = nullptr; + if (OB_ISNULL(info_param = (new (buf) ObDiagnoseInfoParam()))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "info_param is nullptr", K(ret)); + } else { + info_param->type_ = type_; + info_param->struct_type_ = struct_type_; + MEMCPY(info_param->param_int_, param_int_, int_size * sizeof(int64_t)); + MEMCPY(info_param->comment_, comment_, str_size); + } + if (OB_SUCC(ret)) { + out_param = info_param; + } else { + allocator.free(buf); + } + } + return ret; +} }//compaction }//oceanbase diff --git a/src/storage/compaction/ob_compaction_util.h b/src/storage/compaction/ob_compaction_util.h index dc603aba1..a0a59b8bd 100644 --- a/src/storage/compaction/ob_compaction_util.h +++ b/src/storage/compaction/ob_compaction_util.h @@ -55,7 +55,8 @@ inline bool is_multi_version_merge(const ObMergeType &merge_type) { return MINOR_MERGE == merge_type || MINI_MERGE == merge_type - || HISTORY_MINOR_MERGE == merge_type; + || HISTORY_MINOR_MERGE == merge_type + || BACKFILL_TX_MERGE == merge_type; } inline bool is_history_minor_merge(const ObMergeType &merge_type) { diff --git a/src/storage/compaction/ob_index_block_micro_iterator.cpp b/src/storage/compaction/ob_index_block_micro_iterator.cpp index 90637ec4f..4a4e6dab1 100644 --- a/src/storage/compaction/ob_index_block_micro_iterator.cpp +++ b/src/storage/compaction/ob_index_block_micro_iterator.cpp @@ -150,7 +150,7 @@ void ObIndexBlockMicroIterator::reset() int ObIndexBlockMicroIterator::init( const blocksstable::ObDatumRange &range, - const ObTableReadInfo &table_read_info, + const ObITableReadInfo &table_read_info, const blocksstable::MacroBlockId ¯o_id, const common::ObIArray µ_block_infos, const common::ObIArray &endkeys, diff --git a/src/storage/compaction/ob_index_block_micro_iterator.h b/src/storage/compaction/ob_index_block_micro_iterator.h index a57ee4aeb..3f09ceae4 100644 --- a/src/storage/compaction/ob_index_block_micro_iterator.h +++ b/src/storage/compaction/ob_index_block_micro_iterator.h @@ -72,7 +72,7 @@ public: int init( const blocksstable::ObDatumRange &range, - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, const blocksstable::MacroBlockId ¯o_id, const common::ObIArray µ_block_infos, const common::ObIArray &endkeys, diff --git a/src/storage/compaction/ob_medium_compaction_func.cpp b/src/storage/compaction/ob_medium_compaction_func.cpp old mode 100644 new mode 100755 index 313f7851d..72da8cc0e --- a/src/storage/compaction/ob_medium_compaction_func.cpp +++ b/src/storage/compaction/ob_medium_compaction_func.cpp @@ -25,6 +25,7 @@ #include "lib/utility/ob_tracepoint.h" #include "storage/ob_partition_range_spliter.h" #include "storage/compaction/ob_compaction_diagnose.h" +#include "storage/tablet/ob_tablet_medium_info_reader.h" namespace oceanbase { @@ -103,15 +104,28 @@ int ObMediumCompactionScheduleFunc::choose_major_snapshot( ObTenantFreezeInfoMgr::FreezeInfo freeze_info; int64_t schedule_snapshot = 0; const int64_t scheduler_frozen_version = MTL(ObTenantTabletScheduler*)->get_frozen_version(); - const ObMediumCompactionInfoList &medium_list = tablet.get_medium_compaction_info_list(); - ObITable *last_major = tablet.get_table_store().get_major_sstables().get_boundary_table(true/*last*/); + ObTabletMemberWrapper table_store_wrapper; + ObSSTable *last_major = nullptr; + int64_t last_sstable_schema_version = 0; bool schedule_with_newer_info = false; - - if (OB_ISNULL(last_major)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("major sstable is unexpected null", K(ret), KPC(last_major)); + ObMultiVersionSchemaService *schema_service = nullptr; + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("load medium info list fail", K(ret), K(tablet)); } else { - schedule_snapshot = last_major->get_snapshot_version(); + last_major = static_cast(table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/)); + if (OB_ISNULL(last_major)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("major sstable is unexpected null", K(ret), KPC(last_major)); + } else if (OB_FAIL(last_major->get_frozen_schema_version(last_sstable_schema_version))) { + LOG_WARN("failed to get frozen schema version", KR(ret), KPC(last_major)); + } else { + schedule_snapshot = last_major->get_snapshot_version(); + } + } + + if (OB_SUCC(ret) && OB_ISNULL(schema_service = MTL(ObTenantSchemaService *)->get_schema_service())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get schema service from MTL", K(ret)); } while (OB_SUCC(ret)) { if (OB_FAIL(MTL_CALL_FREEZE_INFO_MGR(get_freeze_info_behind_snapshot_version, schedule_snapshot, freeze_info))) { @@ -123,8 +137,12 @@ int ObMediumCompactionScheduleFunc::choose_major_snapshot( } else if (OB_UNLIKELY(freeze_info.schema_version <= 0)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("schema version is invalid", K(ret), K(ls_id), K(tablet_id), K(freeze_info)); - } else if (OB_FAIL(ObMediumCompactionScheduleFunc::get_table_schema_to_merge( - tablet, freeze_info.schema_version, allocator, medium_info))) { + } else if (OB_UNLIKELY(freeze_info.schema_version < last_sstable_schema_version)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("schema version in freeze info is less than last sstable", K(ret), K(ls_id), K(tablet_id), + K(freeze_info), K(last_sstable_schema_version)); + } else if (OB_FAIL(get_table_schema_to_merge( + *schema_service, tablet, freeze_info.schema_version, allocator, medium_info))) { if (OB_TABLE_IS_DELETED == ret) { // do nothing, end loop } else if (OB_ERR_SCHEMA_HISTORY_EMPTY == ret) { @@ -138,9 +156,10 @@ int ObMediumCompactionScheduleFunc::choose_major_snapshot( } else { LOG_WARN("failed to get table schema", K(ret), K(ls_id), K(tablet_id), K(medium_info)); } - } else { // success to get table schema + } + if (OB_SUCC(ret)) { // success to get table schema if (schedule_with_newer_info) { - LOG_INFO("schedule with newer freeze info", K(ret), K(ls_id), K(tablet_id), K(freeze_info)); + FLOG_INFO("schedule with newer freeze info", K(ret), K(ls_id), K(tablet_id), K(freeze_info)); } break; } @@ -154,7 +173,8 @@ int ObMediumCompactionScheduleFunc::choose_major_snapshot( LOG_WARN("failed get result for major", K(ret), K(medium_info)); } else { LOG_TRACE("choose_major_snapshot", K(ret), "ls_id", ls.get_ls_id(), - "tablet_id", tablet.get_tablet_meta().tablet_id_, K(medium_info), K(freeze_info), K(result)); + "tablet_id", tablet.get_tablet_meta().tablet_id_, K(medium_info), K(freeze_info), K(result), + K(last_sstable_schema_version)); } } return ret; @@ -184,7 +204,7 @@ int ObMediumCompactionScheduleFunc::get_status_from_inner_table( return ret; } -// cal this func with PLAF LEADER ROLE && wait_check_medium_scn_ = 0 +// cal this func with PLAF LEADER ROLE && last_medium_scn_ = 0 int ObMediumCompactionScheduleFunc::schedule_next_medium_for_leader( const int64_t major_snapshot, ObTenantTabletScheduler::ObScheduleStatistics &schedule_stat) @@ -223,36 +243,45 @@ int ObMediumCompactionScheduleFunc::schedule_next_medium_primary_cluster( // check last medium type, select inner table for last major bool schedule_medium_flag = false; int64_t max_sync_medium_scn = 0; + const bool is_major = 0 != schedule_major_snapshot; ObITable *last_major = nullptr; ObTablet *tablet = nullptr; - const bool is_major = 0 != schedule_major_snapshot; + ObTabletMemberWrapper table_store_wrapper; + if (OB_UNLIKELY(!tablet_handle_.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid tablet_handle", K(ret), K(tablet_handle_)); } else if (FALSE_IT(tablet = tablet_handle_.get_obj())) { - } else { - const ObMediumCompactionInfoList &medium_list = tablet->get_medium_compaction_info_list(); - if (OB_ISNULL(last_major = tablet->get_table_store().get_major_sstables().get_boundary_table(true/*last*/))) { - // no major, do nothing - } else if (!medium_list.could_schedule_next_round()) { // check serialized list - // do nothing - } else if (OB_FAIL(tablet->get_max_sync_medium_scn(max_sync_medium_scn))) { // check info in memory - LOG_WARN("failed to get max sync medium scn", K(ret), K(max_sync_medium_scn)); - } else if (is_major && schedule_major_snapshot > max_sync_medium_scn) { - schedule_medium_flag = true; - } else if (nullptr != last_major && last_major->get_snapshot_version() < max_sync_medium_scn) { - // do nothing - } else if (OB_FAIL(ObAdaptiveMergePolicy::get_adaptive_merge_reason(*tablet, adaptive_merge_reason))) { - if (OB_HASH_NOT_EXIST != ret) { - LOG_WARN("failed to get meta merge priority", K(ret), KPC(this)); - } else { - ret = OB_SUCCESS; - } - } else if (adaptive_merge_reason > ObAdaptiveMergePolicy::AdaptiveMergeReason::NONE) { - schedule_medium_flag = true; + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_ISNULL(last_major = + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/))) { + // no major, do nothing + } else if (nullptr == medium_info_list_ + && OB_FAIL(tablet->read_medium_info_list(allocator_, medium_info_list_))) { + LOG_WARN("failed to read medium info list", K(ret), KPC(tablet)); + } else if (OB_ISNULL(medium_info_list_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("medium info list is unexpected null", K(ret), KPC(this), KPC_(medium_info_list)); + } else if (!medium_info_list_->could_schedule_next_round()) { // check serialized list + // do nothing + } else if (OB_FAIL(tablet->get_max_sync_medium_scn(max_sync_medium_scn))) { // check info in memory + LOG_WARN("failed to get max sync medium scn", K(ret), K(max_sync_medium_scn)); + } else if (is_major && schedule_major_snapshot > max_sync_medium_scn) { + schedule_medium_flag = true; + } else if (nullptr != last_major && last_major->get_snapshot_version() < max_sync_medium_scn) { + // do nothing + } else if (OB_FAIL(ObAdaptiveMergePolicy::get_adaptive_merge_reason(*tablet, adaptive_merge_reason))) { + if (OB_HASH_NOT_EXIST != ret) { + LOG_WARN("failed to get meta merge priority", K(ret), KPC(this)); + } else { + ret = OB_SUCCESS; } - LOG_TRACE("schedule next medium in primary cluster", K(ret), KPC(this), K(schedule_medium_flag), - K(schedule_major_snapshot), K(adaptive_merge_reason), KPC(last_major), K(medium_list), K(max_sync_medium_scn)); + } else if (adaptive_merge_reason > ObAdaptiveMergePolicy::AdaptiveMergeReason::NONE) { + schedule_medium_flag = true; + } + LOG_TRACE("schedule next medium in primary cluster", K(ret), KPC(this), K(schedule_medium_flag), + K(schedule_major_snapshot), K(adaptive_merge_reason), KPC(last_major), KPC_(medium_info_list), K(max_sync_medium_scn)); #ifdef ERRSIM if (OB_SUCC(ret)) { if (tablet->get_tablet_meta().tablet_id_.id() > ObTabletID::MIN_USER_TABLET_ID) { @@ -267,22 +296,21 @@ int ObMediumCompactionScheduleFunc::schedule_next_medium_primary_cluster( } #endif - if (OB_FAIL(ret) || !schedule_medium_flag) { - } else if (ObMediumCompactionInfo::MAJOR_COMPACTION == medium_list.get_last_compaction_type()) { - // for normal medium, checksum error happened, wait_check_medium_scn_ will never = 0 - // for major, need select inner_table to check RS status - if (OB_FAIL(get_status_from_inner_table(ls_.get_ls_id(), tablet->get_tablet_meta().tablet_id_, ret_info))) { - LOG_WARN("failed to get status from inner tablet", K(ret), KPC(this)); - } else if (ret_info.could_schedule_next_round(medium_list.get_last_compaction_scn())) { - LOG_INFO("success to check RS major checksum validation finished", K(ret), KPC(this), K(ret_info)); - ret = decide_medium_snapshot(is_major); - } else { - ++schedule_stat.wait_rs_validate_cnt_; - LOG_DEBUG("cannot schedule next round merge now", K(ret), K(ret_info), K(medium_list), KPC(tablet)); - } + if (OB_FAIL(ret) || !schedule_medium_flag) { + } else if (ObMediumCompactionInfo::MAJOR_COMPACTION == medium_info_list_->get_last_compaction_type()) { + // for normal medium, checksum error happened, wait_check_medium_scn_ will never = 0 + // for major, need select inner_table to check RS status + if (OB_FAIL(get_status_from_inner_table(ls_.get_ls_id(), tablet->get_tablet_meta().tablet_id_, ret_info))) { + LOG_WARN("failed to get status from inner tablet", K(ret), KPC(this)); + } else if (ret_info.could_schedule_next_round(medium_info_list_->get_last_compaction_scn())) { + LOG_INFO("success to check RS major checksum validation finished", K(ret), KPC(this), K(ret_info)); + ret = decide_medium_snapshot(is_major); } else { - ret = decide_medium_snapshot(is_major, adaptive_merge_reason); + ++schedule_stat.wait_rs_validate_cnt_; + LOG_DEBUG("cannot schedule next round merge now", K(ret), K(ret_info), KPC_(medium_info_list), KPC(tablet)); } + } else { + ret = decide_medium_snapshot(is_major, adaptive_merge_reason); } return ret; @@ -296,24 +324,68 @@ int ObMediumCompactionScheduleFunc::get_max_reserved_snapshot(int64_t &max_reser int64_t max_merged_snapshot = 0; int64_t min_reserved_snapshot = INT64_MAX; ObTablet *tablet = nullptr; + ObTabletMemberWrapper wrapper; if (OB_UNLIKELY(!tablet_handle_.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid tablet_handle", K(ret), K(tablet_handle_)); } else if (FALSE_IT(tablet = tablet_handle_.get_obj())) { + } else if (OB_FAIL(tablet->fetch_table_store(wrapper))) { + LOG_WARN("fetch table store fail", K(ret), KPC(tablet)); + } else if (0 == wrapper.get_member()->get_major_sstables().count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("major sstable should not be empty", K(ret), KPC(tablet)); + } else if (0 == ls_.get_min_reserved_snapshot()) { + ret = OB_NO_NEED_MERGE; + // not sync reserved snapshot yet, should not schedule now + } else if (FALSE_IT(max_merged_snapshot = wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/)->get_snapshot_version())) { + } else if (OB_FAIL(MTL(ObTenantFreezeInfoMgr*)->get_min_reserved_snapshot( + tablet->get_tablet_meta().tablet_id_, max_merged_snapshot, min_reserved_snapshot))) { + LOG_WARN("failed to get multi version from freeze info mgr", K(ret), K(table_id)); } else { - const ObTabletTableStore &table_store = tablet->get_table_store(); - if (0 == table_store.get_major_sstables().count()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("major sstable should not be empty", K(ret), K(tablet)); - } else if (0 == ls_.get_min_reserved_snapshot()) { - ret = OB_NO_NEED_MERGE; - // not sync reserved snapshot yet, should not schedule now - } else if (FALSE_IT(max_merged_snapshot = table_store.get_major_sstables().get_boundary_table(true/*last*/)->get_snapshot_version())) { - } else if (OB_FAIL(MTL(ObTenantFreezeInfoMgr*)->get_min_reserved_snapshot( - tablet->get_tablet_meta().tablet_id_, max_merged_snapshot, min_reserved_snapshot))) { - LOG_WARN("failed to get multi version from freeze info mgr", K(ret), K(table_id)); + max_reserved_snapshot = MAX(ls_.get_min_reserved_snapshot(), min_reserved_snapshot); + } + return ret; +} + +int ObMediumCompactionScheduleFunc::choose_new_medium_snapshot( + const int64_t max_reserved_snapshot, + ObMediumCompactionInfo &medium_info, + ObGetMergeTablesResult &result) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = tablet_handle_.get_obj(); + int64_t snapshot_gc_ts = 0; + if (medium_info.medium_snapshot_ == tablet->get_snapshot_version() // no uncommitted sstable + && weak_read_ts_ + DEFAULT_SCHEDULE_MEDIUM_INTERVAL < ObTimeUtility::current_time_ns()) { + snapshot_gc_ts = MTL(ObTenantFreezeInfoMgr *)->get_snapshot_gc_ts(); + // data before weak_read_ts & latest storage schema on memtable is match for schedule medium + medium_info.medium_snapshot_ = MIN(weak_read_ts_, snapshot_gc_ts); + } + if (medium_info.medium_snapshot_ < max_reserved_snapshot) { + ret = OB_NO_NEED_MERGE; + } else { + LOG_INFO("use weak_read_ts to schedule medium", K(ret), KPC(this), + K(medium_info), K(max_reserved_snapshot), K_(weak_read_ts), K(snapshot_gc_ts)); + } + if (OB_SUCC(ret)) { // update schema version for cur medium scn + ObSEArray memtables; + if (OB_FAIL(tablet->get_memtables(memtables, true/*need_active*/))) { + LOG_WARN("failed to get memtables", KR(ret), KPC(tablet)); } else { - max_reserved_snapshot = MAX(ls_.get_min_reserved_snapshot(), min_reserved_snapshot); + int64_t max_schema_version_on_memtable = 0; + int64_t unused_max_column_cnt_on_memtable = 0; + for (int64_t idx = 0; OB_SUCC(ret) && idx < memtables.count(); ++idx) { + memtable::ObMemtable *memtable = static_cast(memtables.at(idx)); + if (OB_FAIL(memtable->get_schema_info( + max_schema_version_on_memtable, unused_max_column_cnt_on_memtable))) { + LOG_WARN("failed to get schema info from memtable", KR(ret), KPC(memtable)); + } + } + if (OB_SUCC(ret)) { + result.schema_version_ = MAX(max_schema_version_on_memtable, result.schema_version_); + LOG_INFO("chosen new medium snapshot", K(ret), KPC(this), + K(medium_info), K(max_reserved_snapshot), K(result), K(max_schema_version_on_memtable)); + } } } return ret; @@ -349,6 +421,11 @@ int ObMediumCompactionScheduleFunc::decide_medium_snapshot( ObGetMergeTablesResult result; ObMediumCompactionInfo medium_info; medium_info.data_version_ = compat_version; + if (medium_info.data_version_ < DATA_VERSION_4_2_0_0) { + medium_info.medium_compat_version_ = ObMediumCompactionInfo::MEIDUM_COMPAT_VERSION; + } else { + medium_info.medium_compat_version_ = ObMediumCompactionInfo::MEIDUM_COMPAT_VERSION_V2; + } if (OB_FAIL(choose_medium_scn[is_major](ls_, *tablet, merge_reason, allocator_, medium_info, result))) { if (OB_NO_NEED_MERGE != ret) { @@ -362,26 +439,20 @@ int ObMediumCompactionScheduleFunc::decide_medium_snapshot( LOG_WARN("failed to get multi_version_start", K(ret), KPC(this)); } else if (medium_info.medium_snapshot_ < max_reserved_snapshot) { // chosen medium snapshot is far too old - LOG_INFO("chosen medium snapshot is invalid for multi_version_start", K(ret), KPC(this), - K(medium_info), K(max_reserved_snapshot)); - const share::SCN &weak_read_ts = ls_.get_ls_wrs_handler()->get_ls_weak_read_ts(); - if (medium_info.medium_snapshot_ == tablet->get_snapshot_version() // no uncommitted sstable - && weak_read_ts.get_val_for_tx() <= max_reserved_snapshot - && weak_read_ts.get_val_for_tx() + DEFAULT_SCHEDULE_MEDIUM_INTERVAL < ObTimeUtility::current_time_ns()) { - const int64_t snapshot_gc_ts = MTL(ObTenantFreezeInfoMgr*)->get_snapshot_gc_ts(); - medium_info.medium_snapshot_ = MAX(max_reserved_snapshot, MIN(weak_read_ts.get_val_for_tx(), snapshot_gc_ts)); - LOG_INFO("use weak_read_ts to schedule medium", K(ret), KPC(this), - K(medium_info), K(max_reserved_snapshot), K(weak_read_ts), K(snapshot_gc_ts)); - } else { - ret = OB_NO_NEED_MERGE; + if (OB_FAIL(choose_new_medium_snapshot(max_reserved_snapshot, medium_info, result))) { + LOG_WARN("failed to choose new medium snapshot", KR(ret), K(medium_info)); } } + if (OB_SUCC(ret) && !is_major) { const int64_t current_time = ObTimeUtility::current_time_ns(); if (max_reserved_snapshot < current_time) { const int64_t time_interval = (current_time - max_reserved_snapshot) / 2; - ObSSTable *table = static_cast(tablet->get_table_store().get_major_sstables().get_boundary_table(true/*last*/)); - if (OB_ISNULL(table)) { + ObSSTable *table = nullptr; + ObTabletMemberWrapper table_store_wrapper; + if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_ISNULL(table = static_cast(table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true /*last*/)))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table is unexpected null", K(ret), KP(table)); } else if (table->get_snapshot_version() + time_interval > medium_info.medium_snapshot_) { @@ -396,10 +467,10 @@ int ObMediumCompactionScheduleFunc::decide_medium_snapshot( ret = OB_E(EventTable::EN_SCHEDULE_MEDIUM_COMPACTION) ret; LOG_INFO("errsim", K(ret), KPC(this)); if (OB_FAIL(ret)) { - const share::SCN &weak_read_ts = ls_.get_ls_wrs_handler()->get_ls_weak_read_ts(); const int64_t snapshot_gc_ts = MTL(ObTenantFreezeInfoMgr*)->get_snapshot_gc_ts(); - medium_info.medium_snapshot_ = MAX(max_reserved_snapshot, MIN(weak_read_ts.get_val_for_tx(), snapshot_gc_ts)); - if (medium_info.medium_snapshot_ > max_sync_medium_scn) { + medium_info.medium_snapshot_ = MIN(weak_read_ts_, snapshot_gc_ts); + if (medium_info.medium_snapshot_ > max_sync_medium_scn + && medium_info.medium_snapshot_ >= max_reserved_snapshot) { FLOG_INFO("set schedule medium with errsim", KPC(this)); ret = OB_SUCCESS; } @@ -407,33 +478,35 @@ int ObMediumCompactionScheduleFunc::decide_medium_snapshot( } } #endif - if (FAILEDx(prepare_medium_info(result, medium_info))) { - if (OB_TABLE_IS_DELETED == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to prepare medium info", K(ret), K(result), K(tablet->get_storage_schema())); - } - } else if (OB_FAIL(submit_medium_clog(medium_info))) { - LOG_WARN("failed to submit medium clog and update inner table", K(ret), KPC(this)); - } else if (OB_TMP_FAIL(ls_.tablet_freeze(tablet_id, true/*is_sync*/))) { - // need to freeze memtable with MediumCompactionInfo - LOG_WARN("failed to freeze tablet", K(tmp_ret), KPC(this)); + if (FAILEDx(prepare_medium_info(result, medium_info))) { + if (OB_TABLE_IS_DELETED == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to prepare medium info", K(ret), K(result)); } - // delete tablet_id in ObLSReservedSnapshotMgr even if submit clog or update inner table failed - if (OB_TMP_FAIL(ls_.del_dependent_medium_tablet(tablet_id))) { - LOG_ERROR("failed to delete dependent medium tablet", K(tmp_ret), KPC(this)); - ob_abort(); - } - ret = OB_NO_NEED_MERGE == ret ? OB_SUCCESS : ret; - if (OB_FAIL(ret)) { - // add schedule suspect info - ADD_SUSPECT_INFO(MEDIUM_MERGE, ls_.get_ls_id(), tablet_id, - "schedule medium failed", - "compaction_scn", medium_info.medium_snapshot_, - "schema_version", medium_info.storage_schema_.schema_version_, - "error_no", ret); + } else if (OB_FAIL(submit_medium_clog(medium_info))) { + LOG_WARN("failed to submit medium clog and update inner table", K(ret), KPC(this)); + } else if (OB_TMP_FAIL(ls_.tablet_freeze(tablet_id, true/*is_sync*/))) { + // need to freeze memtable with MediumCompactionInfo + LOG_WARN("failed to freeze tablet", K(tmp_ret), KPC(this)); + } + // delete tablet_id in ObLSReservedSnapshotMgr even if submit clog or update inner table failed + if (OB_TMP_FAIL(ls_.del_dependent_medium_tablet(tablet_id))) { + LOG_ERROR("failed to delete dependent medium tablet", K(tmp_ret), KPC(this)); + ob_abort(); + } + ret = OB_NO_NEED_MERGE == ret ? OB_SUCCESS : ret; + if (OB_FAIL(ret)) { + // add schedule suspect info + if (OB_TMP_FAIL(ADD_SUSPECT_INFO(MEDIUM_MERGE, ls_.get_ls_id(), tablet_id, + ObSuspectInfoType::SUSPECT_SCHEDULE_MEDIUM_FAILED, + medium_info.medium_snapshot_, + medium_info.storage_schema_.store_column_cnt_, + static_cast(ret)))) { + LOG_WARN("failed to add suspect info", K(tmp_ret)); } } + } } return ret; } @@ -443,32 +516,40 @@ int ObMediumCompactionScheduleFunc::init_parallel_range( ObMediumCompactionInfo &medium_info) { int ret = OB_SUCCESS; + ObSSTableMetaHandle meta_handle; + int64_t expected_task_count = 0; + const int64_t tablet_size = medium_info.storage_schema_.get_tablet_size(); + const ObSSTable *first_sstable = static_cast(result.handle_.get_table(0)); ObTablet *tablet = nullptr; if (OB_UNLIKELY(!tablet_handle_.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid tablet_handle", K(ret), K(tablet_handle_)); } else if (FALSE_IT(tablet = tablet_handle_.get_obj())) { + } else if (OB_ISNULL(first_sstable)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sstable is unexpected null", K(ret), K(result)); + } else if (OB_FAIL(first_sstable->get_meta(meta_handle))) { + LOG_WARN("first sstable get meta fail", K(ret), KPC(first_sstable)); } else { - int64_t expected_task_count = 0; - const int64_t tablet_size = medium_info.storage_schema_.get_tablet_size(); - const ObSSTable *first_sstable = static_cast(result.handle_.get_table(0)); - if (OB_ISNULL(first_sstable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sstable is unexpected null", K(ret), K(tablet)); - } else { - const int64_t macro_block_cnt = first_sstable->get_meta().get_macro_info().get_data_block_ids().count(); - int64_t inc_row_cnt = 0; - for (int64_t i = 0; i < result.handle_.get_count(); ++i) { - inc_row_cnt += static_cast(result.handle_.get_table(i))->get_meta().get_row_count(); + const int64_t macro_block_cnt = first_sstable->get_data_macro_block_count(); + int64_t inc_row_cnt = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < result.handle_.get_count(); ++i) { + ObSSTableMetaHandle inc_handle; + if (OB_FAIL(static_cast(result.handle_.get_table(i))->get_meta(inc_handle))) { + LOG_WARN("sstable get meta fail", K(ret)); + } else { + inc_row_cnt += inc_handle.get_sstable_meta().get_row_count(); } - if ((0 == macro_block_cnt && inc_row_cnt > SCHEDULE_RANGE_ROW_COUNT_THRESHOLD) - || (first_sstable->get_meta().get_row_count() >= SCHEDULE_RANGE_ROW_COUNT_THRESHOLD - && inc_row_cnt >= first_sstable->get_meta().get_row_count() * SCHEDULE_RANGE_INC_ROW_COUNT_PERCENRAGE_THRESHOLD)) { - if (OB_FAIL(ObParallelMergeCtx::get_concurrent_cnt(tablet_size, macro_block_cnt, expected_task_count))) { - STORAGE_LOG(WARN, "failed to get concurrent cnt", K(ret), K(tablet_size), K(expected_task_count), - KPC(first_sstable)); - } + } + + if (OB_FAIL(ret)) { + } else if ((0 == macro_block_cnt && inc_row_cnt > SCHEDULE_RANGE_ROW_COUNT_THRESHOLD) + || (meta_handle.get_sstable_meta().get_row_count() >= SCHEDULE_RANGE_ROW_COUNT_THRESHOLD + && inc_row_cnt >= meta_handle.get_sstable_meta().get_row_count() * SCHEDULE_RANGE_INC_ROW_COUNT_PERCENRAGE_THRESHOLD)) { + if (OB_FAIL(ObParallelMergeCtx::get_concurrent_cnt(tablet_size, macro_block_cnt, expected_task_count))) { + STORAGE_LOG(WARN, "failed to get concurrent cnt", K(ret), K(tablet_size), K(expected_task_count), + KPC(first_sstable), K(meta_handle)); } } @@ -491,7 +572,7 @@ int ObMediumCompactionScheduleFunc::init_parallel_range( } else if (OB_FAIL(range_spliter.get_split_multi_ranges( input_range_array, expected_task_count, - tablet->get_index_read_info(), + tablet->get_rowkey_read_info(), table_iter, allocator_, range_array))) { @@ -511,22 +592,25 @@ int ObMediumCompactionScheduleFunc::get_result_for_major( { int ret = OB_SUCCESS; ObSSTable *base_table = nullptr; - const ObTabletTableStore &table_store = tablet.get_table_store(); + ObTabletMemberWrapper table_store_wrapper; - if (OB_UNLIKELY(!medium_info.is_valid() || !table_store.is_valid())) { + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_UNLIKELY(!table_store_wrapper.get_member()->is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid argument", K(ret), K(medium_info), K(table_store)); - } else if (OB_ISNULL(base_table = static_cast(table_store.get_major_sstables().get_boundary_table(true/*last*/)))) { + LOG_WARN("get invalid argument", K(ret), K(medium_info), KPC(table_store_wrapper.get_member())); + } else if (OB_ISNULL(base_table = static_cast( + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/)))) { ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("major sstable not exist", K(ret), K(table_store)); + LOG_WARN("major sstable not exist", K(ret), KPC(table_store_wrapper.get_member())); } else if (base_table->get_snapshot_version() >= medium_info.medium_snapshot_) { ret = OB_NO_NEED_MERGE; - } else if (OB_FAIL(result.handle_.add_table(base_table))) { + } else if (OB_FAIL(result.handle_.add_sstable(base_table, table_store_wrapper.get_meta_handle()))) { LOG_WARN("failed to add table into iterator", K(ret), KP(base_table)); } else { - const ObSSTableArray &minor_tables = table_store.get_minor_sstables(); + const ObSSTableArray &minor_tables = table_store_wrapper.get_member()->get_minor_sstables(); bool start_add_table_flag = false; - for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.count_; ++i) { + for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.count(); ++i) { if (OB_ISNULL(minor_tables[i])) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("table must not null", K(ret), K(i), K(minor_tables)); @@ -535,7 +619,7 @@ int ObMediumCompactionScheduleFunc::get_result_for_major( start_add_table_flag = true; } if (OB_SUCC(ret) && start_add_table_flag) { - if (OB_FAIL(result.handle_.add_table(minor_tables[i]))) { + if (OB_FAIL(result.handle_.add_sstable(minor_tables[i], table_store_wrapper.get_meta_handle()))) { LOG_WARN("failed to add table", K(ret)); } } @@ -565,46 +649,57 @@ int ObMediumCompactionScheduleFunc::prepare_medium_info( ObMediumCompactionInfo &medium_info) { int ret = OB_SUCCESS; + const ObStorageSchema *storage_schema = nullptr; ObTablet *tablet = nullptr; + ObTableStoreIterator table_iter; + medium_info.cluster_id_ = GCONF.cluster_id; + // get table schema if (OB_UNLIKELY(!tablet_handle_.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid tablet_handle", K(ret), K(tablet_handle_)); } else if (FALSE_IT(tablet = tablet_handle_.get_obj())) { - } else { - ObTableStoreIterator table_iter; - medium_info.cluster_id_ = GCONF.cluster_id; // set cluster id - - if (medium_info.is_medium_compaction()) { - ObStorageSchema tmp_storage_schema; - bool use_storage_schema_on_tablet = true; - if (medium_info.medium_snapshot_ > tablet->get_snapshot_version()) { - ObSEArray memtables; - if (OB_FAIL(tablet->get_memtables(memtables, true/*need_active*/))) { - LOG_WARN("failed to get memtables", K(ret), KPC(this)); - } else if (OB_FAIL(ObMediumCompactionScheduleFunc::get_latest_storage_schema_from_memtable( - allocator_, memtables, tmp_storage_schema))) { - if (OB_ENTRY_NOT_EXIST == ret) { - ret = OB_SUCCESS; // clear errno - } else { - LOG_WARN("failed to get storage schema from memtable", K(ret)); - } - } else { - use_storage_schema_on_tablet = false; - } + } else if (0 == result.schema_version_) { // not formal schema version + ret = OB_NO_NEED_MERGE; + } else if (medium_info.is_medium_compaction()) { + const uint64_t tenant_id = MTL_ID(); + ObMultiVersionSchemaService *schema_service = nullptr; + if (OB_ISNULL(schema_service = MTL(ObTenantSchemaService *)->get_schema_service())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get schema service from MTL", K(ret)); + } else if (FALSE_IT(medium_info.storage_schema_.reset())) { + } else if (OB_FAIL(get_table_schema_to_merge(*schema_service, *tablet, result.schema_version_, allocator_, medium_info))) { + // for major compaction, storage schema is inited in choose_major_snapshot + if (OB_TABLE_IS_DELETED != ret) { + LOG_WARN("failed to get table schema", KR(ret), KPC(this), K(medium_info)); } - - if (FAILEDx(medium_info.save_storage_schema( - allocator_, - use_storage_schema_on_tablet ? tablet->get_storage_schema() : tmp_storage_schema))) { - LOG_WARN("failed to save storage schema", K(ret), K(use_storage_schema_on_tablet), K(tmp_storage_schema)); - } - } - if (FAILEDx(init_parallel_range(result, medium_info))) { - LOG_WARN("failed to init parallel range", K(ret), K(medium_info)); + } else if (OB_UNLIKELY(result.handle_.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is invalid empty", KR(ret), KPC(this), K(result)); } else { - LOG_INFO("success to prepare medium info", K(ret), K(medium_info)); + ObSSTable *base_table = static_cast(result.handle_.get_table(0)); + ObSSTableMetaHandle sstable_meta_hdl; + int64_t schema_col_cnt = 0; + if (OB_FAIL(base_table->get_meta(sstable_meta_hdl))) { + LOG_WARN("failed to get base table meta", KR(ret)); + } else if (OB_FAIL(medium_info.storage_schema_.get_stored_column_count_in_sstable(schema_col_cnt))) { + LOG_WARN("failed to get store column count", KR(ret), K(medium_info)); + } else if (OB_UNLIKELY(sstable_meta_hdl.get_sstable_meta().get_column_count() > schema_col_cnt)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("medium column cnt is less than last major sstable", KR(ret), K(schema_col_cnt), K(sstable_meta_hdl)); + } } } + if (FAILEDx(init_parallel_range(result, medium_info))) { + LOG_WARN("failed to init parallel range", K(ret), K(medium_info)); + } else if (OB_UNLIKELY(result.handle_.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table handle in result is empty", KR(ret), K(result)); + } else { + medium_info.last_medium_snapshot_ = result.handle_.get_table(0)->get_snapshot_version(); + } + if (OB_SUCC(ret)) { + LOG_INFO("success to prepare medium info", K(ret), K(medium_info)); + } return ret; } @@ -636,6 +731,7 @@ int ObMediumCompactionScheduleFunc::get_table_id( } int ObMediumCompactionScheduleFunc::get_table_schema_to_merge( + ObMultiVersionSchemaService &schema_service, const ObTablet &tablet, const int64_t schema_version, ObIAllocator &allocator, @@ -645,18 +741,14 @@ int ObMediumCompactionScheduleFunc::get_table_schema_to_merge( const uint64_t tenant_id = MTL_ID(); const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; uint64_t table_id = OB_INVALID_ID; - ObMultiVersionSchemaService *schema_service = nullptr; schema::ObSchemaGetterGuard schema_guard; const ObTableSchema *table_schema = nullptr; int64_t save_schema_version = schema_version; - if (OB_ISNULL(schema_service = MTL(ObTenantSchemaService *)->get_schema_service())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get schema service from MTL", K(ret)); - } else if (OB_FAIL(get_table_id(*schema_service, tablet_id, schema_version, table_id))) { + if (OB_FAIL(get_table_id(schema_service, tablet_id, schema_version, table_id))) { if (OB_TABLE_IS_DELETED != ret) { LOG_WARN("failed to get table id", K(ret), K(tablet_id)); } - } else if (OB_FAIL(schema_service->retry_get_schema_guard(tenant_id, + } else if (OB_FAIL(schema_service.retry_get_schema_guard(tenant_id, schema_version, table_id, schema_guard, @@ -695,13 +787,15 @@ int ObMediumCompactionScheduleFunc::get_table_schema_to_merge( } } #endif + // for old version medium info, need generate old version schema if (FAILEDx(medium_info.storage_schema_.init( - allocator, - *table_schema, - tablet.get_tablet_meta().compat_mode_))) { + allocator, *table_schema, tablet.get_tablet_meta().compat_mode_, false/*skip_column_info*/, + ObMediumCompactionInfo::MEIDUM_COMPAT_VERSION_V2 == medium_info.medium_compat_version_ + ? ObStorageSchema::STORAGE_SCHEMA_VERSION_V2 + : ObStorageSchema::STORAGE_SCHEMA_VERSION))) { LOG_WARN("failed to init storage schema", K(ret), K(schema_version)); } else { - FLOG_INFO("get schema to merge", K(table_id), K(schema_version), K(save_schema_version), + LOG_TRACE("get schema to merge", K(table_id), K(schema_version), K(save_schema_version), K(*reinterpret_cast(table_schema))); } return ret; @@ -863,16 +957,22 @@ int ObMediumCompactionScheduleFunc::check_medium_finish(const ObLSLocality &ls_l { int ret = OB_SUCCESS; ObTablet *tablet = nullptr; + const ObLSID &ls_id = ls_.get_ls_id(); + bool merge_finish = false; + if (OB_UNLIKELY(!tablet_handle_.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid tablet_handle", K(ret), K(tablet_handle_)); } else if (FALSE_IT(tablet = tablet_handle_.get_obj())) { + } else if (nullptr == medium_info_list_ + && OB_FAIL(tablet->read_medium_info_list(allocator_, medium_info_list_))) { + LOG_WARN("failed to read medium info list", K(ret), KPC(tablet)); + } else if (OB_ISNULL(medium_info_list_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("medium info list is unexpected null", K(ret), KPC(this), KPC_(medium_info_list)); } else { - const ObLSID &ls_id = ls_.get_ls_id(); const ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; - const int64_t wait_check_medium_scn = tablet->get_medium_compaction_info_list().get_wait_check_medium_scn(); - bool merge_finish = false; - + const int64_t wait_check_medium_scn = medium_info_list_->get_wait_check_medium_scn(); if (0 == wait_check_medium_scn) { // do nothing } else if (OB_FAIL(check_medium_meta_table(wait_check_medium_scn, ls_id, tablet_id, ls_locality, merge_finish))) { @@ -882,8 +982,8 @@ int ObMediumCompactionScheduleFunc::check_medium_finish(const ObLSLocality &ls_l } else if (OB_FAIL(check_medium_checksum_table(wait_check_medium_scn, ls_id, tablet_id))) { // check checksum LOG_WARN("failed to check checksum", K(ret), K(wait_check_medium_scn), KPC(this)); } else { - const ObMediumCompactionInfo::ObCompactionType compaction_type = tablet->get_medium_compaction_info_list().get_last_compaction_type(); - FLOG_INFO("check medium compaction info", K(ret), K(ls_id), K(tablet_id), K(compaction_type)); + const ObMediumCompactionInfo::ObCompactionType compaction_type = medium_info_list_->get_last_compaction_type(); + LOG_INFO("check medium compaction info", K(ret), K(ls_id), K(tablet_id), K(compaction_type), K(wait_check_medium_scn)); // clear wait_check_medium_scn on Tablet ObTabletHandle new_handle; @@ -909,6 +1009,7 @@ int ObMediumCompactionScheduleFunc::schedule_tablet_medium_merge( const bool scheduler_called) { int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; #ifdef ERRSIM ret = OB_E(EventTable::EN_MEDIUM_CREATE_DAG) ret; if (OB_FAIL(ret)) { @@ -916,52 +1017,59 @@ int ObMediumCompactionScheduleFunc::schedule_tablet_medium_merge( return ret; } #endif - - if (MTL(ObTenantTabletScheduler *)->could_major_merge_start()) { - const ObMediumCompactionInfoList &medium_list = tablet.get_medium_compaction_info_list(); - const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; - const ObLSID &ls_id = ls.get_ls_id(); - ObITable *last_major = tablet.get_table_store().get_major_sstables().get_boundary_table(true/*last*/); - - bool schedule_flag = false; - if (OB_ISNULL(last_major)) { - // do nothing - } else if (ObMediumCompactionInfo::MAJOR_COMPACTION == medium_list.get_last_compaction_type() - && !MTL_IS_PRIMARY_TENANT()) { // for STANDBY/RESTORE TENANT - ObTabletCompactionScnInfo ret_info; - // for standby/restore tenant, need select inner_table to check RS status before schedule new round - if (!scheduler_called) { // should not visit inner table, wait for scheduler loop - } else if (OB_FAIL(get_status_from_inner_table(ls_id, tablet_id, ret_info))) { - LOG_WARN("failed to get status from inner tablet", K(ret), K(ls_id), K(tablet_id)); - } else if (ret_info.could_schedule_next_round(medium_list.get_last_compaction_scn())) { - LOG_INFO("success to check RS major checksum validation finished", K(ret), K(ls_id), K(tablet_id)); - schedule_flag = true; - } + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("failed to fetch table store", K(ret), K(tablet)); } else { - schedule_flag = true; - } - - if (OB_SUCC(ret) && schedule_flag) { - int64_t major_frozen_snapshot = 0 == input_major_snapshot ? MTL(ObTenantTabletScheduler *)->get_frozen_version() : input_major_snapshot; - ObMediumCompactionInfo::ObCompactionType compaction_type = ObMediumCompactionInfo::COMPACTION_TYPE_MAX; - int64_t schedule_scn = 0; - bool need_merge = false; - - (void)tablet.get_medium_compaction_info_list().get_schedule_scn(major_frozen_snapshot, schedule_scn, compaction_type); - - LOG_DEBUG("schedule_tablet_medium_merge", K(schedule_scn), K(major_frozen_snapshot), K(scheduler_called), K(ls_id), K(tablet_id)); - if (0 == schedule_scn - && 0 == tablet.get_medium_compaction_info_list().size() // serialized medium list is empty - && scheduler_called - && OB_FAIL(get_schedule_medium_from_memtable(tablet, major_frozen_snapshot, schedule_scn, compaction_type))) { - LOG_WARN("failed to get schedule medium scn from memtables", K(ret)); - } else if (schedule_scn > 0) { - if (OB_FAIL(check_need_merge_and_schedule(ls, tablet, schedule_scn, compaction_type))) { + ObITable *last_major = table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/); + if (MTL(ObTenantTabletScheduler *)->could_major_merge_start() && OB_NOT_NULL(last_major)) { + ObArenaAllocator temp_allocator("GetMediumInfo", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); // for load medium info + const int64_t last_major_snapshot = last_major->get_snapshot_version(); + const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; + const ObLSID &ls_id = ls.get_ls_id(); + const int64_t major_frozen_snapshot = 0 == input_major_snapshot ? MTL(ObTenantTabletScheduler *)->get_frozen_version() : input_major_snapshot; + ObMediumCompactionInfo::ObCompactionType compaction_type = ObMediumCompactionInfo::COMPACTION_TYPE_MAX; + int64_t schedule_scn = 0; + { + storage::ObTabletMediumInfoReader reader(tablet); + ObMediumCompactionInfoKey key; + ObMediumCompactionInfo medium_info; + if (OB_FAIL(reader.init(temp_allocator))) { + LOG_WARN("failed to init medium info reader", K(ret)); + } else { + // TODO(@bowen.gbw): remove this debug log later + LOG_INFO("schedule tablet medium merge", K(ret), K(schedule_scn), K(major_frozen_snapshot), K(ls_id), K(tablet_id)); + while (OB_SUCC(ret)) { + if (OB_FAIL(reader.get_next_medium_info(temp_allocator, key, medium_info))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get medium info", K(ret)); + } + } else if (key.get_medium_snapshot() <= last_major_snapshot) { + // finished, this medium info could recycle + } else { + if (medium_info.is_medium_compaction() || medium_info.medium_snapshot_ <= major_frozen_snapshot) { + schedule_scn = medium_info.medium_snapshot_; + compaction_type = (ObMediumCompactionInfo::ObCompactionType)medium_info.compaction_type_; + LOG_TRACE("set schedule scn and compaction type", K(ret), K(ls_id), K(tablet_id), + K(schedule_scn), K(compaction_type), K(major_frozen_snapshot)); + } + break; // break when met one undo medium info + } + if (OB_SUCC(ret)) { + LOG_DEBUG("iter read medium info", K(ret), K(ls_id), K(tablet_id), K(medium_info)); + } + medium_info.reset(); + } // end of while + } + }// to make reader destruct to release mds unit lock + if (OB_FAIL(ret)) { + } else if (schedule_scn > 0 && OB_FAIL(check_need_merge_and_schedule(ls, tablet, schedule_scn, compaction_type))) { LOG_WARN("failed to check medium merge", K(ret), K(ls_id), K(tablet_id), K(schedule_scn)); } } } - } return ret; } @@ -982,50 +1090,6 @@ int ObMediumCompactionScheduleFunc::get_palf_role(const ObLSID &ls_id, ObRole &r return ret; } -int ObMediumCompactionScheduleFunc::get_schedule_medium_from_memtable( - ObTablet &tablet, - const int64_t major_frozen_snapshot, - int64_t &schedule_medium_scn, - ObMediumCompactionInfo::ObCompactionType &compaction_type) -{ - int ret = OB_SUCCESS; - schedule_medium_scn = 0; - compaction_type = ObMediumCompactionInfo::COMPACTION_TYPE_MAX; - - ObITable *last_major = tablet.get_table_store().get_major_sstables().get_boundary_table(true/*last*/); - if (OB_NOT_NULL(last_major)) { - ObArenaAllocator tmp_allocator; - ObMediumCompactionInfoList tmp_medium_list; - const int64_t last_major_snapshot = last_major->get_snapshot_version(); - ObSEArray memtables; - if (OB_FAIL(tablet.get_memtables(memtables, true/*need_active*/))) { - LOG_WARN("failed to get memtables", K(ret), "tablet_id", tablet.get_tablet_meta().tablet_id_); - } else if (memtables.empty()) { - // do nothing - } else if (OB_FAIL(get_medium_info_list_from_memtable(tmp_allocator, memtables, tmp_medium_list))) { - LOG_WARN("failed to get medium info list from memtable", K(ret)); - } else if (!tmp_medium_list.is_empty()) { - const ObMediumCompactionInfo *info_in_list = nullptr; - DLIST_FOREACH_X(info, tmp_medium_list.get_list(), OB_SUCC(ret)) { - if (OB_UNLIKELY(memtable::MultiSourceDataUnitType::MEDIUM_COMPACTION_INFO != info->type())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("return info is invalid", K(ret), KPC(info)); - } else if (FALSE_IT(info_in_list = static_cast(info))) { - } else if (info_in_list->medium_snapshot_ <= last_major_snapshot) { - // finished, this medium info could recycle - } else { - if (info_in_list->is_medium_compaction() || info_in_list->medium_snapshot_ <= major_frozen_snapshot) { - schedule_medium_scn = info_in_list->medium_snapshot_; - compaction_type = (ObMediumCompactionInfo::ObCompactionType)info_in_list->compaction_type_; - } - break; // found one unfinish medium info, loop end - } - } - } - } - return ret; -} - int ObMediumCompactionScheduleFunc::check_need_merge_and_schedule( ObLS &ls, ObTablet &tablet, @@ -1052,7 +1116,6 @@ int ObMediumCompactionScheduleFunc::check_need_merge_and_schedule( need_force_freeze))) { // check merge finish LOG_WARN("failed to check medium merge", K(ret), K(ls_id), K(tablet_id)); } else if (need_merge && can_merge) { - const ObMediumCompactionInfo *medium_info = nullptr; if (OB_TMP_FAIL(ObTenantTabletScheduler::schedule_merge_dag( ls.get_ls_id(), tablet_id, @@ -1074,78 +1137,5 @@ int ObMediumCompactionScheduleFunc::check_need_merge_and_schedule( return ret; } -int ObMediumCompactionScheduleFunc::get_latest_storage_schema_from_memtable( - ObIAllocator &allocator, - const ObIArray &memtables, - ObStorageSchema &storage_schema) -{ - int ret = OB_SUCCESS; - ObITable *table = nullptr; - memtable::ObMemtable * memtable = nullptr; - bool found = false; - for (int64_t i = memtables.count() - 1; OB_SUCC(ret) && i >= 0; --i) { - if (OB_ISNULL(table = memtables.at(i))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table in tables_handle is invalid", K(ret), KPC(table)); - } else if (OB_ISNULL(memtable = dynamic_cast(table))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table pointer does not point to a ObMemtable object", KPC(table)); - } else if (OB_FAIL(memtable->get_multi_source_data_unit(&storage_schema, &allocator))) { - if (OB_ENTRY_NOT_EXIST == ret) { - ret = OB_SUCCESS; // clear OB_ENTRY_NOT_EXIST - } else { - LOG_WARN("failed to get storage schema from memtable", K(ret), KPC(table)); - } - } else { - found = true; - break; - } - } // end for - if (OB_SUCC(ret) && !found) { - ret = OB_ENTRY_NOT_EXIST; - } - return ret; -} - -// make sure only data tablet could schedule this func -int ObMediumCompactionScheduleFunc::get_medium_info_list_from_memtable( - ObIAllocator &allocator, - const ObIArray &memtables, - ObMediumCompactionInfoList &medium_list) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(medium_list.init(allocator))) { - LOG_WARN("failed to init merge list", K(ret)); - } - ObITable *table = nullptr; - memtable::ObMemtable *memtable = nullptr; - compaction::ObMediumCompactionInfo useless_medium_info; - memtable::ObMultiSourceData::ObIMultiSourceDataUnitList dst_list; - for (int64_t i = 0; OB_SUCC(ret) && i < memtables.count(); ++i) { - dst_list.reset(); - if (OB_ISNULL(table = memtables.at(i))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table in tables_handle is invalid", K(ret), KPC(table)); - } else if (OB_ISNULL(memtable = dynamic_cast(table))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table pointer does not point to a ObMemtable object", KPC(table)); - } else if (OB_FAIL(memtable->get_multi_source_data_unit_list(&useless_medium_info, dst_list, &allocator))) { - LOG_WARN("failed to get medium info from memtable", K(ret), KPC(table)); - } else { - ObMediumCompactionInfo *info_in_list = nullptr; - DLIST_FOREACH_X(info, dst_list, OB_SUCC(ret)) { - if (OB_UNLIKELY(memtable::MultiSourceDataUnitType::MEDIUM_COMPACTION_INFO != info->type())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("return info is invalid", K(ret), KPC(info)); - } else if (FALSE_IT(info_in_list = static_cast(info))) { - } else if (OB_FAIL(medium_list.add_medium_compaction_info(*info_in_list))) { - LOG_WARN("failed to add medium compaction info", K(ret), KPC(info_in_list)); - } - } - } - } // end of for - return ret; -} - } //namespace compaction } // namespace oceanbase diff --git a/src/storage/compaction/ob_medium_compaction_func.h b/src/storage/compaction/ob_medium_compaction_func.h old mode 100644 new mode 100755 index d375edef1..6043b1d26 --- a/src/storage/compaction/ob_medium_compaction_func.h +++ b/src/storage/compaction/ob_medium_compaction_func.h @@ -25,10 +25,12 @@ namespace compaction class ObMediumCompactionScheduleFunc { public: - ObMediumCompactionScheduleFunc(ObLS &ls, ObTabletHandle &tablet_handle) + ObMediumCompactionScheduleFunc(ObLS &ls, ObTabletHandle &tablet_handle, const SCN &weak_read_ts) : allocator_("MediumSchedule"), ls_(ls), tablet_handle_(tablet_handle), + weak_read_ts_(weak_read_ts.get_val_for_tx()), + medium_info_list_(nullptr), filters_inited_(false), filters_() {} @@ -39,16 +41,9 @@ public: ObTablet &tablet, const int64_t major_frozen_scn = 0, const bool scheduler_called = false); - static int get_latest_storage_schema_from_memtable( - ObIAllocator &allocator, - const ObIArray &memtables, - ObStorageSchema &storage_schema); - static int get_medium_info_list_from_memtable( - ObIAllocator &allocator, - const ObIArray &memtables, - ObMediumCompactionInfoList &medium_list); static int get_palf_role(const share::ObLSID &ls_id, ObRole &role); static int get_table_schema_to_merge( + ObMultiVersionSchemaService &schema_service, const ObTablet &tablet, const int64_t schema_version, ObIAllocator &allocator, @@ -114,13 +109,11 @@ protected: const int64_t schedule_scn, const ObMediumCompactionInfo::ObCompactionType compaction_type); int schedule_next_medium_primary_cluster(const int64_t major_snapshot, ObTenantTabletScheduler::ObScheduleStatistics &schedule_stat); - + int choose_new_medium_snapshot( + const int64_t max_reserved_snapshot, + ObMediumCompactionInfo &medium_info, + ObGetMergeTablesResult &result); int get_max_reserved_snapshot(int64_t &max_reserved_snapshot); - static int get_schedule_medium_from_memtable( - ObTablet &tablet, - const int64_t major_frozen_snapshot, - int64_t &schedule_medium_scn, - ObMediumCompactionInfo::ObCompactionType &compaction_type); static int get_table_id( ObMultiVersionSchemaService &schema_service, const ObTabletID &tablet_id, @@ -128,8 +121,8 @@ protected: uint64_t &table_id); static const int64_t DEFAULT_SYNC_SCHEMA_CLOG_TIMEOUT = 1000L * 1000L; // 1s static const int64_t DEFAULT_SCHEDULE_MEDIUM_INTERVAL = 60L * 1000L * 1000L; // 60s - static const int64_t SCHEDULE_RANGE_INC_ROW_COUNT_PERCENRAGE_THRESHOLD = 10L; - static const int64_t SCHEDULE_RANGE_ROW_COUNT_THRESHOLD = 1000 *1000L; // 100w + static constexpr double SCHEDULE_RANGE_INC_ROW_COUNT_PERCENRAGE_THRESHOLD = 0.2; + static const int64_t SCHEDULE_RANGE_ROW_COUNT_THRESHOLD = 1000 * 1000L; // 100w static const int64_t MEDIUM_FUNC_CNT = 2; typedef int (*ChooseMediumScn)( ObLS &ls, @@ -144,6 +137,8 @@ private: ObArenaAllocator allocator_; ObLS &ls_; ObTabletHandle tablet_handle_; + int64_t weak_read_ts_; + const compaction::ObMediumCompactionInfoList *medium_info_list_; bool filters_inited_; share::ObTabletReplicaFilterHolder filters_; }; diff --git a/src/storage/compaction/ob_medium_compaction_info.cpp b/src/storage/compaction/ob_medium_compaction_info.cpp index 14b320533..923aa6158 100644 --- a/src/storage/compaction/ob_medium_compaction_info.cpp +++ b/src/storage/compaction/ob_medium_compaction_info.cpp @@ -12,10 +12,12 @@ #define USING_LOG_PREFIX STORAGE #include "storage/compaction/ob_medium_compaction_info.h" +#include "storage/compaction/ob_partition_merge_policy.h" namespace oceanbase { using namespace storage; +using namespace blocksstable; namespace compaction { @@ -24,20 +26,30 @@ namespace compaction * ObParallelMergeInfo * */ +template +void ObParallelMergeInfo::destroy(T *&array) +{ + if (nullptr != array && nullptr != allocator_) { + for (int i = 0; i < list_size_; ++i) { + array[i].destroy(*allocator_); + } + allocator_->free(array); + array = nullptr; + } +} + void ObParallelMergeInfo::destroy() { - if (list_size_ > 0 && nullptr != parallel_end_key_list_ && nullptr != allocator_) { - for (int i = 0; i < list_size_; ++i) { - parallel_end_key_list_[i].destroy(*allocator_); - } + if (list_size_ > 0) { + destroy(parallel_store_rowkey_list_); + destroy(parallel_datum_rowkey_list_); list_size_ = 0; - allocator_->free(parallel_end_key_list_); - parallel_end_key_list_ = nullptr; - allocator_ = nullptr; } + allocator_ = nullptr; parallel_info_ = 0; } +// CAREFUL! parallel_info_ contains list_size, no need serialize array count of rowkey list int ObParallelMergeInfo::serialize(char *buf, const int64_t buf_len, int64_t &pos) const { int ret = OB_SUCCESS; @@ -50,15 +62,36 @@ int ObParallelMergeInfo::serialize(char *buf, const int64_t buf_len, int64_t &po } else { LST_DO_CODE(OB_UNIS_ENCODE, parallel_info_); - for (int i = 0; OB_SUCC(ret) && i < list_size_; ++i) { - if (OB_FAIL(parallel_end_key_list_[i].serialize(buf, buf_len, pos))) { - LOG_WARN("failed to encode concurrent cnt", K(ret), K(i), K(list_size_), K(parallel_end_key_list_[i])); + if (PARALLEL_INFO_VERSION_V0 == compat_) { + for (int i = 0; OB_SUCC(ret) && i < list_size_; ++i) { + if (OB_FAIL(parallel_store_rowkey_list_[i].serialize(buf, buf_len, pos))) { + LOG_WARN("failed to encode concurrent cnt", K(ret), K(i), K(list_size_), K(parallel_store_rowkey_list_[i])); + } } + } else if (PARALLEL_INFO_VERSION_V1 == compat_) { + for (int i = 0; OB_SUCC(ret) && i < list_size_; ++i) { + if (OB_FAIL(parallel_datum_rowkey_list_[i].serialize(buf, buf_len, pos))) { + LOG_WARN("failed to encode concurrent cnt", K(ret), K(i), K(list_size_), K(parallel_datum_rowkey_list_[i])); + } + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid compat version", KR(ret), K_(compat)); } } return ret; } +#define ALLOC_ROWKEY_ARRAY(array_ptr, T) \ + void *alloc_buf = nullptr; \ + if (OB_ISNULL(alloc_buf = allocator.alloc(sizeof(T) * list_size_))) { \ + ret = OB_ALLOCATE_MEMORY_FAILED; \ + LOG_WARN("failed to alloc rowkey array", K(ret), K(list_size_)); \ + } else { \ + array_ptr = new(alloc_buf) T[list_size_]; \ + } + +// CAREFUL! parallel_info_ contains list_size, no need deserialize array count of rowkey list int ObParallelMergeInfo::deserialize( common::ObIAllocator &allocator, const char *buf, @@ -77,17 +110,30 @@ int ObParallelMergeInfo::deserialize( LOG_WARN("list size is invalid", K(ret), K(list_size_)); } else { allocator_ = &allocator; - void *alloc_buf = nullptr; - if (OB_ISNULL(alloc_buf = allocator.alloc(sizeof(ObStoreRowkey) * list_size_))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("failed to alloc store rowkey array", K(ret), K(list_size_)); + if (OB_FAIL(ret)) { + } else if (PARALLEL_INFO_VERSION_V0 == compat_) { + ALLOC_ROWKEY_ARRAY(parallel_store_rowkey_list_, ObStoreRowkey); + for (int i = 0; OB_SUCC(ret) && i < list_size_; ++i) { + // need to deserialize StoreRowkey + if (OB_FAIL(parallel_store_rowkey_list_[i].deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("failed to encode concurrent cnt", K(ret), K(i), K(list_size_), K(data_len), K(pos)); + } + } // end of for + } else if (PARALLEL_INFO_VERSION_V1 == compat_) { + ALLOC_ROWKEY_ARRAY(parallel_datum_rowkey_list_, ObDatumRowkey); + ObDatumRowkey tmp_datum_rowkey; + ObStorageDatum datums[OB_INNER_MAX_ROWKEY_COLUMN_NUMBER]; + tmp_datum_rowkey.assign(datums, OB_INNER_MAX_ROWKEY_COLUMN_NUMBER); + for (int i = 0; OB_SUCC(ret) && i < list_size_; ++i) { + if (OB_FAIL(tmp_datum_rowkey.deserialize(buf, data_len, pos))) { + LOG_WARN("failed to decode datum rowkey", K(ret), K(i), K(list_size_), K(data_len), K(pos)); + } else if (tmp_datum_rowkey.deep_copy(parallel_datum_rowkey_list_[i] /*dst*/, allocator)) { + LOG_WARN("failed to deep copy datum rowkey", KR(ret), K(i), K(tmp_datum_rowkey)); + } + } // end of for } else { - parallel_end_key_list_ = new(alloc_buf) ObStoreRowkey[list_size_]; - } - for (int i = 0; OB_SUCC(ret) && i < list_size_; ++i) { - if (OB_FAIL(parallel_end_key_list_[i].deserialize(allocator, buf, data_len, pos))) { - LOG_WARN("failed to encode concurrent cnt", K(ret), K(i), K(list_size_), K(data_len), K(pos)); - } + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid compat version", KR(ret), K_(compat)); } if (OB_FAIL(ret)) { destroy(); // free parallel_end_key_list_ in destroy @@ -97,13 +143,20 @@ int ObParallelMergeInfo::deserialize( return ret; } +// CAREFUL! parallel_info_ contains list_size, no need serialize array count of rowkey list int64_t ObParallelMergeInfo::get_serialize_size() const { int64_t len = 0; if (list_size_ > 0) { len += serialization::encoded_length_vi32(parallel_info_); - for (int i = 0; i < list_size_; ++i) { - len += parallel_end_key_list_[i].get_serialize_size(); + if (PARALLEL_INFO_VERSION_V0 == compat_) { + for (int i = 0; i < list_size_; ++i) { + len += parallel_store_rowkey_list_[i].get_serialize_size(); + } + } else if (PARALLEL_INFO_VERSION_V1 == compat_) { + for (int i = 0; i < list_size_; ++i) { + len += parallel_datum_rowkey_list_[i].get_serialize_size(); + } } } return len; @@ -114,8 +167,9 @@ int ObParallelMergeInfo::generate_from_range_array( ObArrayArray ¶l_range) { int ret = OB_SUCCESS; - void *buf = nullptr; - if (OB_UNLIKELY(0 != list_size_ || nullptr != parallel_end_key_list_)) { + if (OB_UNLIKELY(0 != list_size_ + || nullptr != parallel_store_rowkey_list_ + || nullptr != parallel_datum_rowkey_list_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("parallel merge info is not empty", K(ret), KPC(this)); } else { @@ -125,26 +179,20 @@ int ObParallelMergeInfo::generate_from_range_array( } if (sum_range_cnt <= VALID_CONCURRENT_CNT || sum_range_cnt > UINT8_MAX) { // do nothing - } else if (FALSE_IT(list_size_ = sum_range_cnt - 1)) { - } else if (OB_ISNULL(buf = allocator.alloc(sizeof(ObStoreRowkey) * list_size_))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("failed to allocate", K(ret), K(paral_range)); } else { + list_size_ = sum_range_cnt - 1; allocator_ = &allocator; - parallel_end_key_list_ = new(buf) ObStoreRowkey[list_size_]; - int64_t cnt = 0; - for (int64_t i = 0; OB_SUCC(ret) && i < paral_range.count() && cnt < list_size_; ++i) { - const ObIArray &range_array = paral_range.at(i); - for (int64_t j = 0; OB_SUCC(ret) && j < range_array.count() && cnt < list_size_; ++j) { - if (OB_FAIL(range_array.at(j).get_end_key().deep_copy(parallel_end_key_list_[cnt++], allocator))) { - LOG_WARN("failed to deep copy end key", K(ret), K(i), K(range_array), K(j), K(cnt)); - } - } - } // end of loop array + uint64_t compat_version = 0; + if (OB_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), compat_version))) { + LOG_WARN("fail to get data version", K(ret)); + } else if (compat_version < DATA_VERSION_4_2_0_0) { // sync store_rowkey_list + ret = generate_store_rowkey_list(allocator, paral_range); + } else { // sync datum_rowkey_list + ret = generate_datum_rowkey_list(allocator, paral_range); + } } } LOG_DEBUG("parallel range info", K(ret), KPC(this), K(paral_range), K(paral_range.count()), K(paral_range.at(0))); - if (OB_FAIL(ret)) { destroy(); } else if (get_serialize_size() > MAX_PARALLEL_RANGE_SERIALIZE_LEN) { @@ -155,6 +203,57 @@ int ObParallelMergeInfo::generate_from_range_array( return ret; } +int ObParallelMergeInfo::generate_datum_rowkey_list( + ObIAllocator &allocator, + ObArrayArray ¶l_range) +{ + int ret = OB_SUCCESS; + compat_ = PARALLEL_INFO_VERSION_V1; + ALLOC_ROWKEY_ARRAY(parallel_datum_rowkey_list_, ObDatumRowkey); + int64_t cnt = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < paral_range.count() && cnt < list_size_; ++i) { + const ObIArray &range_array = paral_range.at(i); + for (int64_t j = 0; OB_SUCC(ret) && j < range_array.count() && cnt < list_size_; ++j) { + if (OB_FAIL(parallel_datum_rowkey_list_[cnt++].from_rowkey(range_array.at(j).get_end_key().get_rowkey(), allocator))) { + LOG_WARN("failed to deep copy end key", K(ret), K(j), "src_key", range_array.at(j).get_end_key()); + } + } + } // end of loop array + return ret; +} + +int ObParallelMergeInfo::generate_store_rowkey_list( + ObIAllocator &allocator, + ObArrayArray ¶l_range) +{ + int ret = OB_SUCCESS; + compat_ = PARALLEL_INFO_VERSION_V0; + ALLOC_ROWKEY_ARRAY(parallel_store_rowkey_list_, ObStoreRowkey); + int64_t cnt = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < paral_range.count() && cnt < list_size_; ++i) { + const ObIArray &range_array = paral_range.at(i); + for (int64_t j = 0; OB_SUCC(ret) && j < range_array.count() && cnt < list_size_; ++j) { + if (OB_FAIL(range_array.at(j).get_end_key().deep_copy(parallel_store_rowkey_list_[cnt++]/*dst*/, allocator))) { + LOG_WARN("failed to deep copy end key", K(ret), K(j), "src_key", range_array.at(j).get_end_key()); + } + } + } // end of loop array + return ret; +} + +template +int ObParallelMergeInfo::deep_copy_list(common::ObIAllocator &allocator, const T *src, T *&dst) +{ + int ret = OB_SUCCESS; + ALLOC_ROWKEY_ARRAY(dst, T); + for (int i = 0; OB_SUCC(ret) && i < list_size_; ++i) { + if (OB_FAIL(src[i].deep_copy(dst[i], allocator))) { + LOG_WARN("failed to deep copy end key", K(ret), K(i), K(src[i])); + } + } + return ret; +} + int ObParallelMergeInfo::init( common::ObIAllocator &allocator, const ObParallelMergeInfo &other) @@ -164,46 +263,71 @@ int ObParallelMergeInfo::init( ret = OB_INVALID_ARGUMENT; LOG_WARN("other parallel info is invalid", K(ret), K(other)); } else { + compat_ = other.compat_; list_size_ = other.list_size_; allocator_ = &allocator; if (list_size_ > 0) { - void *buf = nullptr; - if (OB_ISNULL(buf = allocator.alloc(sizeof(ObStoreRowkey) * list_size_))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("failed to allocate", K(ret), K(other)); - } else { - parallel_end_key_list_ = new (buf) ObStoreRowkey[list_size_]; - for (int i = 0; OB_SUCC(ret) && i < list_size_; ++i) { - if (OB_FAIL(other.parallel_end_key_list_[i].deep_copy(parallel_end_key_list_[i], allocator))) { - LOG_WARN("failed to deep copy end key", K(ret), K(i), K(other.parallel_end_key_list_[i])); - } - } - if (OB_FAIL(ret)) { - destroy(); - } - } // else + if (PARALLEL_INFO_VERSION_V0 == compat_) { + ret = deep_copy_list(allocator, other.parallel_store_rowkey_list_, parallel_store_rowkey_list_); + } else if (PARALLEL_INFO_VERSION_V1 == compat_) { + ret = deep_copy_list(allocator, other.parallel_datum_rowkey_list_, parallel_datum_rowkey_list_); + } + if (OB_FAIL(ret)) { + destroy(); + } } } return ret; } +int ObParallelMergeInfo::deep_copy_datum_rowkey( + const int64_t idx, + ObIAllocator &input_allocator, + blocksstable::ObDatumRowkey &rowkey) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(idx < 0 || idx >= list_size_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid idx", KR(ret), K(idx), K_(list_size)); + } else if (PARALLEL_INFO_VERSION_V0 == compat_) { + if (OB_FAIL(rowkey.from_rowkey(parallel_store_rowkey_list_[idx].get_rowkey()/*src*/, input_allocator))) { + STORAGE_LOG(WARN, "failed to deep copy end key", K(ret), K(idx), K(parallel_store_rowkey_list_[idx])); + } + } else if (PARALLEL_INFO_VERSION_V1 == compat_ + && OB_FAIL(parallel_datum_rowkey_list_[idx].deep_copy(rowkey/*dst*/, input_allocator))) { + STORAGE_LOG(WARN, "failed to deep copy end key", K(ret), K(idx), K(parallel_datum_rowkey_list_[idx])); + } + return ret; +} + int64_t ObParallelMergeInfo::to_string(char* buf, const int64_t buf_len) const { int64_t pos = 0; if (OB_ISNULL(buf) || buf_len <= 0) { } else { J_OBJ_START(); - J_KV(K_(list_size)); + J_KV(K_(list_size), K_(compat)); J_COMMA(); - for (int i = 0; i < list_size_; ++i) { - J_KV(K(i), "key", parallel_end_key_list_[i]); - J_COMMA(); + if (PARALLEL_INFO_VERSION_V0 == compat_) { + for (int i = 0; i < list_size_; ++i) { + J_KV(K(i), "key", parallel_store_rowkey_list_[i]); + J_COMMA(); + } + } else if (PARALLEL_INFO_VERSION_V1 == compat_) { + for (int i = 0; i < list_size_; ++i) { + J_KV(K(i), "key", parallel_datum_rowkey_list_[i]); + J_COMMA(); + } } J_OBJ_END(); } return pos; } +OB_SERIALIZE_MEMBER_SIMPLE( + ObMediumCompactionInfoKey, + medium_snapshot_); + /* * ObMediumCompactionInfo * */ @@ -224,8 +348,7 @@ const char *ObMediumCompactionInfo::get_compaction_type_str(enum ObCompactionTyp } ObMediumCompactionInfo::ObMediumCompactionInfo() - : ObIMultiSourceDataUnit(), - medium_compat_version_(MEIDUM_COMPAT_VERSION), + : medium_compat_version_(MEIDUM_COMPAT_VERSION_V2), compaction_type_(COMPACTION_TYPE_MAX), contain_parallel_range_(false), medium_merge_reason_(ObAdaptiveMergePolicy::NONE), @@ -233,6 +356,7 @@ ObMediumCompactionInfo::ObMediumCompactionInfo() cluster_id_(0), data_version_(0), medium_snapshot_(0), + last_medium_snapshot_(0), storage_schema_(), parallel_merge_info_() { @@ -244,6 +368,12 @@ ObMediumCompactionInfo::~ObMediumCompactionInfo() reset(); } +int ObMediumCompactionInfo::assign(ObIAllocator &allocator, + const ObMediumCompactionInfo &medium_info) +{ + return init(allocator, medium_info); +} + int ObMediumCompactionInfo::init( ObIAllocator &allocator, const ObMediumCompactionInfo &medium_info) @@ -260,6 +390,7 @@ int ObMediumCompactionInfo::init( info_ = medium_info.info_; cluster_id_ = medium_info.cluster_id_; medium_snapshot_ = medium_info.medium_snapshot_; + last_medium_snapshot_ = medium_info.last_medium_snapshot_; data_version_ = medium_info.data_version_; } return ret; @@ -271,7 +402,9 @@ bool ObMediumCompactionInfo::is_valid() const && medium_snapshot_ > 0 && data_version_ > 0 && storage_schema_.is_valid() - && parallel_merge_info_.is_valid(); + && parallel_merge_info_.is_valid() + && (MEIDUM_COMPAT_VERSION == medium_compat_version_ + || (MEIDUM_COMPAT_VERSION_V2 == medium_compat_version_ && last_medium_snapshot_ != 0)); } void ObMediumCompactionInfo::reset() @@ -281,40 +414,12 @@ void ObMediumCompactionInfo::reset() compaction_type_ = COMPACTION_TYPE_MAX; cluster_id_ = 0; medium_snapshot_ = 0; + last_medium_snapshot_ = 0; data_version_ = 0; storage_schema_.reset(); parallel_merge_info_.destroy(); } -int ObMediumCompactionInfo::deep_copy(const ObIMultiSourceDataUnit *src, ObIAllocator *allocator) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(nullptr == src || nullptr == allocator)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(src), KP(allocator)); - } else if (OB_UNLIKELY(memtable::MultiSourceDataUnitType::MEDIUM_COMPACTION_INFO != src->type())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), "type", src->type(), KP(allocator)); - } else { - ret = init(*allocator, *static_cast(src)); - } - return ret; -} - -int ObMediumCompactionInfo::save_storage_schema( - ObIAllocator &allocator, - const storage::ObStorageSchema &storage_schema) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!storage_schema.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(storage_schema)); - } else if (OB_FAIL(storage_schema_.init(allocator, storage_schema))) { - LOG_WARN("failed to init storage schema", K(ret), K(storage_schema)); - } - return ret; -} - int ObMediumCompactionInfo::gene_parallel_info( ObIAllocator &allocator, ObArrayArray ¶l_range) @@ -327,7 +432,7 @@ int ObMediumCompactionInfo::gene_parallel_info( } else { ret = OB_SUCCESS; } - } else if (parallel_merge_info_.list_size_ > 0) { + } else if (parallel_merge_info_.get_size() > 0) { contain_parallel_range_ = true; LOG_INFO("success to gene parallel info", K(ret), K(contain_parallel_range_), K(parallel_merge_info_)); } @@ -348,11 +453,16 @@ int ObMediumCompactionInfo::serialize(char *buf, const int64_t buf_len, int64_t medium_snapshot_, data_version_, storage_schema_); - if (contain_parallel_range_) { + if (OB_SUCC(ret) && contain_parallel_range_) { LST_DO_CODE( OB_UNIS_ENCODE, parallel_merge_info_); } + if (OB_SUCC(ret) && MEIDUM_COMPAT_VERSION_V2 == medium_compat_version_) { + LST_DO_CODE( + OB_UNIS_ENCODE, + last_medium_snapshot_); + } LOG_DEBUG("ObMediumCompactionInfo::serialize", K(ret), K(buf), K(buf_len), K(pos)); } return ret; @@ -376,7 +486,7 @@ int ObMediumCompactionInfo::deserialize( data_version_); if (OB_FAIL(ret)) { } else if (OB_FAIL(storage_schema_.deserialize(allocator, buf, data_len, pos))) { - LOG_WARN("failed to deserialize storage schema", K(ret)); + LOG_WARN("failed to deserialize storage schema", K(ret), K(buf), K(data_len), K(pos)); } else if (contain_parallel_range_) { if (OB_FAIL(parallel_merge_info_.deserialize(allocator, buf, data_len, pos))) { LOG_WARN("failed to deserialize parallel merge info", K(ret), K(buf), K(data_len), K(pos)); @@ -385,6 +495,11 @@ int ObMediumCompactionInfo::deserialize( clear_parallel_range(); LOG_DEBUG("ObMediumCompactionInfo::deserialize", K(ret), K(buf), K(data_len), K(pos)); } + if (OB_SUCC(ret) && MEIDUM_COMPAT_VERSION_V2 == medium_compat_version_) { + LST_DO_CODE( + OB_UNIS_DECODE, + last_medium_snapshot_); + } } return ret; } @@ -402,6 +517,11 @@ int64_t ObMediumCompactionInfo::get_serialize_size() const if (contain_parallel_range_) { LST_DO_CODE(OB_UNIS_ADD_LEN, parallel_merge_info_); } + if (MEIDUM_COMPAT_VERSION_V2 == medium_compat_version_) { + LST_DO_CODE( + OB_UNIS_ADD_LEN, + last_medium_snapshot_); + } return len; } @@ -412,5 +532,21 @@ void ObMediumCompactionInfo::gene_info( K(medium_snapshot_), K_(parallel_merge_info)); } +int64_t ObMediumCompactionInfo::to_string(char* buf, const int64_t buf_len) const +{ + int64_t pos = 0; + if (OB_ISNULL(buf) || buf_len <= 0) { + } else { + J_OBJ_START(); + J_KV(K_(cluster_id), K_(medium_compat_version), K_(data_version), + "compaction_type", ObMediumCompactionInfo::get_compaction_type_str((ObCompactionType)compaction_type_), + "medium_merge_reason", ObAdaptiveMergePolicy::merge_reason_to_str(medium_merge_reason_), K_(cluster_id), + K_(medium_snapshot), K_(last_medium_snapshot), K_(storage_schema), + K_(contain_parallel_range), K_(parallel_merge_info)); + J_OBJ_END(); + } + return pos; +} + } //namespace compaction } // namespace oceanbase diff --git a/src/storage/compaction/ob_medium_compaction_info.h b/src/storage/compaction/ob_medium_compaction_info.h old mode 100644 new mode 100755 index 18058e104..d0edaf41f --- a/src/storage/compaction/ob_medium_compaction_info.h +++ b/src/storage/compaction/ob_medium_compaction_info.h @@ -15,7 +15,6 @@ #include "storage/ob_storage_schema.h" #include "lib/container/ob_array_array.h" -#include "storage/compaction/ob_partition_merge_policy.h" #include "observer/ob_server_struct.h" namespace oceanbase @@ -26,23 +25,38 @@ class ObTablet; } namespace compaction { - struct ObParallelMergeInfo { public: ObParallelMergeInfo() - : parallel_info_(0), - parallel_end_key_list_(nullptr), + : compat_(PARALLEL_INFO_VERSION_V1), + list_size_(0), + reserved_(0), + parallel_store_rowkey_list_(nullptr), + parallel_datum_rowkey_list_(nullptr), allocator_(nullptr) {} ~ObParallelMergeInfo() { destroy(); } // attention!!! use destroy to free memory int init(common::ObIAllocator &allocator, const ObParallelMergeInfo &other); void destroy(); + void clear() + { + list_size_ = 0; + parallel_store_rowkey_list_ = nullptr; + parallel_datum_rowkey_list_ = nullptr; + } + int64_t get_size() const { return list_size_; } bool is_valid() const { - return list_size_ == 0 || nullptr != parallel_end_key_list_; + return list_size_ == 0 + || (PARALLEL_INFO_VERSION_V0 == compat_ && nullptr != parallel_store_rowkey_list_) + || (PARALLEL_INFO_VERSION_V1 == compat_ && nullptr != parallel_datum_rowkey_list_); } + template + int deep_copy_list(common::ObIAllocator &allocator, const T *src, T *&dst); + template + void destroy(T *&array); // serialize & deserialize int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; int deserialize( @@ -51,14 +65,26 @@ public: const int64_t data_len, int64_t &pos); int64_t get_serialize_size() const; - int generate_from_range_array( ObIAllocator &allocator, common::ObArrayArray ¶l_range); - + int deep_copy_datum_rowkey( + const int64_t idx, + ObIAllocator &allocator, + blocksstable::ObDatumRowkey &rowkey) const; +public: int64_t to_string(char* buf, const int64_t buf_len) const; static const int64_t MAX_PARALLEL_RANGE_SERIALIZE_LEN = 1 * 1024 * 1024; static const int64_t VALID_CONCURRENT_CNT = 1; + static const int64_t PARALLEL_INFO_VERSION_V0 = 0; // StoreRowkey + static const int64_t PARALLEL_INFO_VERSION_V1 = 1; // DatumRowkey +private: + int generate_datum_rowkey_list( + ObIAllocator &allocator, + ObArrayArray ¶l_range); + int generate_store_rowkey_list( + ObIAllocator &allocator, + ObArrayArray ¶l_range); union { uint32_t parallel_info_; @@ -68,12 +94,76 @@ public: uint32_t reserved_ : 20; }; }; - ObStoreRowkey *parallel_end_key_list_; // concurrent_cnt - 1 - + // concurrent_cnt - 1; valid when compat_ = PARALLEL_INFO_VERSION_V0 + ObStoreRowkey *parallel_store_rowkey_list_; + // concurrent_cnt - 1; valid when compat_ = PARALLEL_INFO_VERSION_V1 + blocksstable::ObDatumRowkey *parallel_datum_rowkey_list_; ObIAllocator *allocator_; }; -struct ObMediumCompactionInfo final : public memtable::ObIMultiSourceDataUnit + +struct ObMediumCompactionInfoKey final +{ +public: + OB_UNIS_VERSION(1); +public: + ObMediumCompactionInfoKey() + : medium_snapshot_(0) + {} + ObMediumCompactionInfoKey(const ObMediumCompactionInfoKey &other) + : medium_snapshot_(other.medium_snapshot_) + {} + ObMediumCompactionInfoKey(const int64_t medium_snapshot) + : medium_snapshot_(medium_snapshot) + {} + ObMediumCompactionInfoKey &operator=(const ObMediumCompactionInfoKey &other) + { + medium_snapshot_ = other.medium_snapshot_; + return *this; + } + ~ObMediumCompactionInfoKey() = default; + + void reset() { medium_snapshot_ = 0; } + bool is_valid() const { return medium_snapshot_ > 0; } + ObMediumCompactionInfoKey &operator=(const int64_t medium_snapshot) + { + medium_snapshot_ = medium_snapshot; + return *this; + } + + bool operator<(const ObMediumCompactionInfoKey& rhs) const + { + return medium_snapshot_ < rhs.medium_snapshot_; + } + bool operator<=(const ObMediumCompactionInfoKey& rhs) const + { + return medium_snapshot_ <= rhs.medium_snapshot_; + } + bool operator>(const ObMediumCompactionInfoKey& rhs) const + { + return medium_snapshot_ > rhs.medium_snapshot_; + } + bool operator>=(const ObMediumCompactionInfoKey& rhs) const + { + return medium_snapshot_ >= rhs.medium_snapshot_; + } + bool operator==(const ObMediumCompactionInfoKey& rhs) const + { + return medium_snapshot_ == rhs.medium_snapshot_; + } + bool operator!=(const ObMediumCompactionInfoKey& rhs) const + { + return medium_snapshot_ != rhs.medium_snapshot_; + } + int64_t get_medium_snapshot() const { return medium_snapshot_; } + void set_medium_snapshot(const int64_t medium_snapshot) { medium_snapshot_ = medium_snapshot; } + + TO_STRING_KV(K_(medium_snapshot)); +private: + int64_t medium_snapshot_; +}; + +struct ObMediumCompactionInfo final : public common::ObDLinkBase { public: enum ObCompactionType @@ -82,14 +172,14 @@ public: MAJOR_COMPACTION = 1, COMPACTION_TYPE_MAX, }; - const static char *ObCompactionTypeStr[]; - const static char *get_compaction_type_str(enum ObCompactionType type); + static const char *ObCompactionTypeStr[]; + static const char *get_compaction_type_str(enum ObCompactionType type); public: ObMediumCompactionInfo(); - virtual ~ObMediumCompactionInfo(); + ~ObMediumCompactionInfo(); + int assign(ObIAllocator &allocator, const ObMediumCompactionInfo &medium_info); int init(ObIAllocator &allocator, const ObMediumCompactionInfo &medium_info); - int save_storage_schema(ObIAllocator &allocator, const storage::ObStorageSchema &storage_schema); int gene_parallel_info( ObIAllocator &allocator, common::ObArrayArray ¶l_range); @@ -98,26 +188,14 @@ public: static inline bool is_major_compaction(const ObCompactionType type) { return MAJOR_COMPACTION == type; } inline bool is_major_compaction() const { return is_major_compaction((ObCompactionType)compaction_type_); } inline bool is_medium_compaction() const { return is_medium_compaction((ObCompactionType)compaction_type_); } - inline void clear_parallel_range() + void clear_parallel_range() { - parallel_merge_info_.list_size_ = 0; - parallel_merge_info_.parallel_end_key_list_ = nullptr; + parallel_merge_info_.clear(); contain_parallel_range_ = false; } - - // ObIMultiSourceDataUnit section - virtual int deep_copy(const ObIMultiSourceDataUnit *src, ObIAllocator *allocator) override; - virtual void reset() override; - virtual bool is_valid() const override; - virtual inline int64_t get_data_size() const override { return sizeof(ObMediumCompactionInfo); } - virtual inline memtable::MultiSourceDataUnitType type() const override - { - return memtable::MultiSourceDataUnitType::MEDIUM_COMPACTION_INFO; - } - virtual int64_t get_version() const override { return medium_snapshot_; } - virtual bool is_save_last() const override { return false; } + void reset(); + bool is_valid() const; bool from_cur_cluster() const { return cluster_id_ == GCONF.cluster_id; } - // serialize & deserialize int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; int deserialize( @@ -128,13 +206,10 @@ public: int64_t get_serialize_size() const; void gene_info(char* buf, const int64_t buf_len, int64_t &pos) const; - TO_STRING_KV(K_(cluster_id), K_(medium_compat_version), K_(data_version), - "compaction_type", ObMediumCompactionInfo::get_compaction_type_str((ObCompactionType)compaction_type_), - "medium_merge_reason", ObAdaptiveMergePolicy::merge_reason_to_str(medium_merge_reason_), K_(cluster_id), - K_(medium_snapshot), K_(storage_schema), - K_(contain_parallel_range), K_(parallel_merge_info)); + int64_t to_string(char* buf, const int64_t buf_len) const; public: static const int64_t MEIDUM_COMPAT_VERSION = 1; + static const int64_t MEIDUM_COMPAT_VERSION_V2 = 2; private: static const int32_t SCS_ONE_BIT = 1; @@ -155,6 +230,7 @@ public: uint64_t cluster_id_; // for backup database to throw MEDIUM_COMPACTION clog uint64_t data_version_; int64_t medium_snapshot_; + int64_t last_medium_snapshot_; storage::ObStorageSchema storage_schema_; ObParallelMergeInfo parallel_merge_info_; }; diff --git a/src/storage/compaction/ob_medium_compaction_mgr.cpp b/src/storage/compaction/ob_medium_compaction_mgr.cpp index 21cca1a53..b6eef58cf 100644 --- a/src/storage/compaction/ob_medium_compaction_mgr.cpp +++ b/src/storage/compaction/ob_medium_compaction_mgr.cpp @@ -11,10 +11,15 @@ */ #define USING_LOG_PREFIX STORAGE + #include "storage/compaction/ob_medium_compaction_mgr.h" #include "storage/tablet/ob_tablet_meta.h" #include "storage/tablet/ob_tablet.h" #include "logservice/ob_log_base_header.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/multi_data_source/mds_writer.h" +#include "src/storage/tx/ob_trans_define.h" +#include "storage/tablet/ob_tablet_service_clog_replay_executor.h" namespace oceanbase { @@ -22,6 +27,66 @@ using namespace storage; namespace compaction { +class ObTabletMediumClogReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObTabletMediumClogReplayExecutor(ObMediumCompactionInfo &medium_info); + int init(const share::SCN &scn); +protected: + bool is_replay_update_user_data_() const override + { + return false; + } + int do_replay_(ObTabletHandle &tablet_handle) override; + virtual bool is_replay_update_mds_table_() const override + { + return true; + } +private: + ObMediumCompactionInfo &medium_info_; + share::SCN scn_; +}; + +ObTabletMediumClogReplayExecutor::ObTabletMediumClogReplayExecutor( + ObMediumCompactionInfo &medium_info) + : medium_info_(medium_info), + scn_() +{ +} + +int ObTabletMediumClogReplayExecutor::init(const share::SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!medium_info_.is_valid() || !scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(medium_info_), K(scn)); + } else { + scn_ = scn; + is_inited_ = true; + } + return ret; +} + +int ObTabletMediumClogReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + mds::MdsCtx mds_ctx{mds::MdsWriter(mds::WriterType::MEDIUM_INFO)}; + if (OB_FAIL(replay_to_mds_table_( + tablet_handle, + ObMediumCompactionInfoKey(medium_info_.medium_snapshot_), + medium_info_, + mds_ctx, + scn_))) { + LOG_WARN("failed to replay to tablet", K(ret)); + } else { + mds_ctx.single_log_commit(scn_, scn_); + } + return ret; +} + /* * ObTabletMediumCompactionInfoRecorder * */ @@ -34,10 +99,11 @@ ObTabletMediumCompactionInfoRecorder::ObTabletMediumCompactionInfoRecorder() tablet_id_(), tablet_handle_ptr_(nullptr), medium_info_(nullptr), - allocator_(nullptr) + allocator_(nullptr), + mds_ctx_(nullptr) { #if defined(__x86_64__) - STATIC_ASSERT(sizeof(ObTabletMediumCompactionInfoRecorder) <= 96, "size of medium recorder is oversize"); + STATIC_ASSERT(sizeof(ObTabletMediumCompactionInfoRecorder) <= 104, "size of medium recorder is oversize"); #endif } @@ -84,7 +150,7 @@ int ObTabletMediumCompactionInfoRecorder::init( ls_id_ = ls_id; tablet_id_ = tablet_id; is_inited_ = true; - LOG_INFO("success to init", K(ret), K_(ls_id), K_(tablet_id), K(max_saved_version)); + LOG_INFO("success to init medium clog recorder", K(ret), K_(ls_id), K_(tablet_id), K(max_saved_version)); } return ret; } @@ -124,6 +190,7 @@ void ObTabletMediumCompactionInfoRecorder::free_allocated_info() allocator_->free(logcb_ptr_); logcb_ptr_ = nullptr; tablet_handle_ptr_ = nullptr; + mds_ctx_ = nullptr; } allocator_ = nullptr; } @@ -144,9 +211,9 @@ int ObTabletMediumCompactionInfoRecorder::replay_medium_compaction_log( ret = OB_NOT_SUPPORTED; LOG_WARN("not support to replay medium compaction clog", K(ret), K_(tablet_id)); } else if (OB_FAIL(serialization::decode_i64(buf, size, pos, &update_version))) { - LOG_WARN("fail to deserialize table_version", K(ret), K_(tablet_id)); + LOG_WARN("fail to deserialize table_version", K(ret), K_(ls_id), K_(tablet_id)); } else if (OB_FAIL(ObIStorageClogRecorder::replay_clog(update_version, scn, buf, size, pos))) { - LOG_WARN("failed to replay clog", K(ret), K(scn), K_(tablet_id), K(update_version)); + LOG_WARN("failed to replay clog", K(ret), K(scn), K_(ls_id), K_(tablet_id), K(update_version)); } return ret; } @@ -163,21 +230,27 @@ int ObTabletMediumCompactionInfoRecorder::inner_replay_clog( ObArenaAllocator tmp_allocator; ObMediumCompactionInfo replay_medium_info; ObTabletHandle tmp_tablet_handle; - if (OB_FAIL(replay_get_tablet_handle(ls_id_, tablet_id_, scn, tmp_tablet_handle))) { - LOG_WARN("failed to get tablet handle", K(ret), K_(ls_id), K_(tablet_id), K(scn)); - } else if (OB_FAIL(replay_medium_info.deserialize(tmp_allocator, buf, size, pos))) { + if (OB_FAIL(replay_medium_info.deserialize(tmp_allocator, buf, size, pos))) { LOG_WARN("failed to deserialize medium compaction info", K(ret)); } else if (!replay_medium_info.from_cur_cluster() && replay_medium_info.is_medium_compaction()) { // throw medium compaction clog from other cluster - } else if (FALSE_IT(replay_medium_info.set_sync_finish(true))) { - } else if (OB_FAIL(tmp_tablet_handle.get_obj()->save_multi_source_data_unit(&replay_medium_info, - scn, true/*for replay*/, memtable::MemtableRefOp::NONE))) { - LOG_WARN("failed to save medium info", K(ret), K_(tablet_id), K(replay_medium_info)); - } else { - tmp_tablet_handle.reset(); - FLOG_INFO("success to save medium info", K(ret), K_(ls_id), K_(tablet_id), K(replay_medium_info), K(max_saved_version_)); + } else { // new mds path + ObTabletMediumClogReplayExecutor replay_executor(replay_medium_info); + if (OB_FAIL(replay_executor.init(scn))) { + LOG_WARN("failed to init replay executor", K(ret), K(scn)); + } else if (OB_FAIL(replay_executor.execute(scn, ls_id_, tablet_id_))) { + if (OB_TABLET_NOT_EXIST == ret || OB_NO_NEED_UPDATE == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to replay medium info", K(ret), K(replay_medium_info)); + } + } else { + FLOG_INFO("success to save medium info", K(ret), K_(tablet_id), K_(ls_id), K(replay_medium_info), K(max_saved_version_)); + } } + + tmp_tablet_handle.reset(); return ret; } @@ -190,10 +263,10 @@ int ObTabletMediumCompactionInfoRecorder::sync_clog_succ_for_leader(const int64_ } else if (OB_UNLIKELY(medium_info_->medium_snapshot_ != update_version)) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("medium snapshot not match", K(ret), KPC(medium_info_), K(update_version)); - } else if (OB_FAIL(dec_ref_on_memtable(true/*sync_finish*/))) { + } else if (OB_FAIL(submit_trans_on_mds_table(true/*is_commit*/))) { LOG_WARN("failed to dec ref on memtable", K(ret), K_(tablet_id), KPC(medium_info_)); } else { - FLOG_INFO("success to save medium info", K(ret), K_(ls_id), K_(tablet_id), KPC(medium_info_), + FLOG_INFO("success to save medium info for leader", K(ret), K_(ls_id), K_(tablet_id), KPC(medium_info_), K(max_saved_version_), K_(clog_scn)); } return ret; @@ -201,24 +274,23 @@ int ObTabletMediumCompactionInfoRecorder::sync_clog_succ_for_leader(const int64_ void ObTabletMediumCompactionInfoRecorder::sync_clog_failed_for_leader() { - dec_ref_on_memtable(false/*sync_finish*/); + submit_trans_on_mds_table(false/*is_commit*/); } -int ObTabletMediumCompactionInfoRecorder::dec_ref_on_memtable(const bool sync_finish) +int ObTabletMediumCompactionInfoRecorder::submit_trans_on_mds_table(const bool is_commit) { int ret = OB_SUCCESS; if (OB_UNLIKELY(nullptr == medium_info_ || nullptr == tablet_handle_ptr_ - || !tablet_handle_ptr_->is_valid())) { + || !tablet_handle_ptr_->is_valid() + || nullptr == mds_ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("medium info or tablet handle is unexpected null", K(ret), K_(ls_id), K_(tablet_id), - KP_(medium_info), K_(tablet_handle_ptr)); + KP_(medium_info), K_(tablet_handle_ptr), KPC_(mds_ctx)); + } else if (is_commit) { + mds_ctx_->single_log_commit(clog_scn_, clog_scn_); } else { - medium_info_->set_sync_finish(sync_finish); - if (OB_FAIL(tablet_handle_ptr_->get_obj()->save_multi_source_data_unit(medium_info_, clog_scn_, - false/*for_replay*/, memtable::MemtableRefOp::DEC_REF, true/*is_callback*/))) { - LOG_WARN("failed to save medium info", K(ret), K_(tablet_id), K(medium_info_)); - } + mds_ctx_->single_log_abort(); } return ret; } @@ -248,7 +320,7 @@ int ObTabletMediumCompactionInfoRecorder::prepare_struct_in_lock( + tablet_id_.get_serialize_size() + serialization::encoded_length_i64(medium_info_->medium_snapshot_) + medium_info_->get_serialize_size(); - const int64_t alloc_buf_size = buf_len + sizeof(ObTabletHandle) + sizeof(ObStorageCLogCb); + const int64_t alloc_buf_size = buf_len + sizeof(ObTabletHandle) + sizeof(ObStorageCLogCb) + sizeof(mds::MdsCtx); if (OB_UNLIKELY(nullptr == medium_info_ || nullptr == allocator)) { ret = OB_ERR_UNEXPECTED; @@ -265,6 +337,8 @@ int ObTabletMediumCompactionInfoRecorder::prepare_struct_in_lock( alloc_buf_offset += sizeof(ObStorageCLogCb); tablet_handle_ptr_ = new (buf + alloc_buf_offset) ObTabletHandle(); alloc_buf_offset += sizeof(ObTabletHandle); + mds_ctx_ = new(buf + alloc_buf_offset) mds::MdsCtx(mds::MdsWriter(mds::WriterType::MEDIUM_INFO)); + alloc_buf_offset += sizeof(mds::MdsCtx); alloc_clog_buf = static_cast(buf) + alloc_buf_offset; } @@ -303,15 +377,15 @@ int ObTabletMediumCompactionInfoRecorder::submit_log( ret = OB_ERR_UNEXPECTED; LOG_WARN("log handler or medium info is null", K(ret), KP(medium_info_), KP(clog_buf), K(clog_len), K(tablet_handle_ptr_)); - } else if (FALSE_IT(medium_info_->set_sync_finish(false))) { - } else if (OB_FAIL(tablet_handle_ptr_->get_obj()->save_multi_source_data_unit( - medium_info_, share::SCN::max_scn(), - false/*for_replay*/, memtable::MemtableRefOp::INC_REF))) { - LOG_WARN("failed to save medium info", K_(tablet_id), KPC(medium_info_)); + } else if (OB_FAIL(tablet_handle_ptr_->get_obj()->set( + ObMediumCompactionInfoKey(medium_info_->medium_snapshot_), + *medium_info_, + *mds_ctx_))) { + LOG_WARN("failed to save medium info on mds table", K(ret), K_(tablet_id), KPC(medium_info_)); } else if (OB_FAIL(write_clog(clog_buf, clog_len))) { LOG_WARN("fail to submit log", K(ret), K_(tablet_id), K(medium_info_)); int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(dec_ref_on_memtable(false))) { + if (OB_TMP_FAIL(submit_trans_on_mds_table(false))) { LOG_ERROR("failed to dec ref on memtable", K(tmp_ret), K_(ls_id), K_(tablet_id)); } } else { @@ -326,8 +400,6 @@ int ObTabletMediumCompactionInfoRecorder::submit_log( * ObMediumCompactionInfoList * */ -const int64_t ObMediumCompactionInfoList::MAX_SERIALIZE_SIZE; - ObMediumCompactionInfoList::ObMediumCompactionInfoList() : is_inited_(false), allocator_(nullptr), @@ -358,93 +430,87 @@ int ObMediumCompactionInfoList::init(common::ObIAllocator &allocator) return ret; } -// MINI: other_list is from memtable -// MIGRATE: other_list is from migrate_src -// finish_medium_scn = last_major_scn -// init_by_ha = true: need force set wait_check = finish_scn -// if wait_check=0 after restore, report_scn don't will be updated by leader -int ObMediumCompactionInfoList::init(common::ObIAllocator &allocator, - const ObMediumCompactionInfoList *old_list, - const ObMediumCompactionInfoList *other_list, - const int64_t finish_medium_scn/*= 0*/, - const ObMergeType merge_type/*= MERGE_TYPE_MAX*/) +int ObMediumCompactionInfoList::init( + common::ObIAllocator &allocator, + const ObMediumCompactionInfoList *input_list) { int ret = OB_SUCCESS; if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret)); - } else if (OB_UNLIKELY(nullptr == old_list && nullptr != other_list)) { + } else if (OB_ISNULL(input_list)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(merge_type), KPC(old_list), KPC(other_list)); - } else if (FALSE_IT(allocator_ = &allocator)) { - } else if (nullptr != old_list && OB_FAIL(append_list_with_deep_copy(finish_medium_scn, *old_list))) { - LOG_WARN("failed to deep copy list", K(ret), K(old_list)); - } else if (nullptr != other_list && OB_FAIL(append_list_with_deep_copy(finish_medium_scn, *other_list))) { - LOG_WARN("failed to deep copy list", K(ret), K(other_list)); - } else if (is_major_merge_type(merge_type)) { // update list after major_type_merge - last_compaction_type_ = is_major_merge(merge_type) ? ObMediumCompactionInfo::MAJOR_COMPACTION : ObMediumCompactionInfo::MEDIUM_COMPACTION; - last_medium_scn_ = finish_medium_scn; - wait_check_flag_ = true; - } else { // update info with newest list - const ObMediumCompactionInfoList *update_list = old_list; - if (OB_NOT_NULL(other_list) - && OB_NOT_NULL(old_list) - && other_list->last_medium_scn_ > old_list->last_medium_scn_) { // compare get newer list - update_list = other_list; - } - if (OB_NOT_NULL(update_list)) { - set_basic_info(*update_list); - } - } - if (OB_SUCC(ret)) { + LOG_WARN("invalid argument", K(ret), KPC(input_list)); + } else { + allocator_ = &allocator; + set_basic_info(*input_list); compat_ = MEDIUM_LIST_VERSION; is_inited_ = true; - if (medium_info_list_.get_size() > 0 || wait_check_flag_) { - LOG_INFO("success to init list", K(ret), KPC(this), KPC(old_list), K(finish_medium_scn), - "merge_type", merge_type_to_str(merge_type)); - if (last_medium_scn_ > 0 && last_medium_scn_ < finish_medium_scn) { // only print log - LOG_WARN("medium list record old info", KPC(this), KPC(old_list), K(finish_medium_scn)); - } - } - } else if (OB_UNLIKELY(!is_inited_)) { - reset(); } return ret; } -int ObMediumCompactionInfoList::init_after_check_finish( - ObIAllocator &allocator, - const ObMediumCompactionInfoList &old_list) // list from old_tablet +int ObMediumCompactionInfoList::init( + common::ObIAllocator &allocator, + const ObTaletExtraMediumInfo &extra_medium_info, + const ObTabletDumpedMediumInfo &medium_info_list) { int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; + if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret)); - } else if (OB_UNLIKELY(!old_list.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(old_list)); - } else if (FALSE_IT(allocator_ = &allocator)) { - } else if (OB_FAIL(append_list_with_deep_copy(last_medium_scn_, old_list))) { - LOG_WARN("failed to deep copy list", K(ret), K(last_medium_scn_)); } else { - last_compaction_type_ = old_list.last_compaction_type_; - last_medium_scn_ = old_list.last_medium_scn_; - wait_check_flag_ = false; // update after check finished, should reset wait_check_medium_scn - compat_ = MEDIUM_LIST_VERSION; - is_inited_ = true; - LOG_INFO("success to init list", K(ret), KPC(this), K(old_list)); - } - if (OB_UNLIKELY(!is_inited_)) { - reset(); + allocator_ = &allocator; + const common::ObIArray &array = medium_info_list.medium_info_list_; + for (int64_t i = 0; OB_SUCC(ret) && i < array.count(); ++i) { + const ObMediumCompactionInfo *src_medium_info = array.at(i); + if (OB_ISNULL(src_medium_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, medium info is null", K(ret), K(i), KP(src_medium_info)); + } else { + ObMediumCompactionInfo *medium_info = nullptr; + void *buffer = allocator.alloc(sizeof(ObMediumCompactionInfo)); + if (OB_ISNULL(buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to allocate memory", K(ret), "size", sizeof(ObMediumCompactionInfo)); + } else { + medium_info = new (buffer) ObMediumCompactionInfo(); + if (OB_FAIL(medium_info->init(allocator, *src_medium_info))) { + LOG_WARN("failed to copy medium info", K(ret), KPC(src_medium_info)); + } else if (OB_UNLIKELY(!medium_info_list_.add_last(medium_info))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to add last", K(ret), KPC(medium_info)); + } + + if (OB_FAIL(ret)) { + if (OB_NOT_NULL(medium_info)) { + medium_info->~ObMediumCompactionInfo(); + allocator.free(medium_info); + } + } + } + } + } + + if (OB_FAIL(ret)) { + reset(); + } else { + compat_ = MEDIUM_LIST_VERSION; + last_compaction_type_ = extra_medium_info.last_compaction_type_; + last_medium_scn_ = extra_medium_info.last_medium_scn_; + wait_check_flag_ = extra_medium_info.wait_check_flag_; + is_inited_ = true; + } } + return ret; } void ObMediumCompactionInfoList::reset_list() { DLIST_REMOVE_ALL_NORET(info, medium_info_list_) { - static_cast(info)->~ObMediumCompactionInfo(); + info->~ObMediumCompactionInfo(); allocator_->free(info); } medium_info_list_.reset(); @@ -461,101 +527,6 @@ void ObMediumCompactionInfoList::reset() allocator_ = nullptr; } -int ObMediumCompactionInfoList::add_medium_compaction_info(const ObMediumCompactionInfo &input_info) -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("list is not init", K(ret)); - } else if (OB_FAIL(inner_deep_copy_node(input_info))) { - LOG_WARN("failed to init medium info", K(ret), K(input_info)); - } - return ret; -} - -int ObMediumCompactionInfoList::get_specified_scn_info( - const int64_t snapshot, - const ObMediumCompactionInfo *&ret_info) const -{ - ret_info = nullptr; - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("list is not init", K(ret)); - } else if (OB_UNLIKELY(snapshot <= 0)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(snapshot)); - } else if (snapshot <= get_max_medium_snapshot() && medium_info_list_.get_size() > 0) { - const ObMediumCompactionInfo *first_info = static_cast(medium_info_list_.get_first()); - if (OB_UNLIKELY(!first_info->is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("invalid medium info", K(ret), KPC(first_info)); - } else if (OB_UNLIKELY(first_info->medium_snapshot_ < snapshot)) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("exist medium info which may not scheduled", K(ret), KPC(first_info), K(snapshot)); - } else if (first_info->medium_snapshot_ == snapshot) { - ret_info = first_info; - } - } - if (OB_SUCC(ret) && nullptr == ret_info) { - ret = OB_ENTRY_NOT_EXIST; - } - return ret; -} - -void ObMediumCompactionInfoList::get_schedule_scn( - const int64_t major_compaction_scn, - int64_t &schedule_scn, - ObMediumCompactionInfo::ObCompactionType &compaction_type) const -{ - schedule_scn = 0; - compaction_type = ObMediumCompactionInfo::COMPACTION_TYPE_MAX; - if (size() > 0) { - const ObMediumCompactionInfo *first_medium_info = get_first_medium_info(); - if (first_medium_info->is_medium_compaction() - || (first_medium_info->is_major_compaction() && major_compaction_scn >= first_medium_info->medium_snapshot_)) { - // for standby cluster, receive several medium info, only schedule what scheduler have received - schedule_scn = first_medium_info->medium_snapshot_; - compaction_type = (ObMediumCompactionInfo::ObCompactionType)first_medium_info->compaction_type_; - } - } -} - -int ObMediumCompactionInfoList::inner_deep_copy_node( - const ObMediumCompactionInfo &input_info) -{ - int ret = OB_SUCCESS; - ObMediumCompactionInfo *new_info = nullptr; - void *alloc_buf = nullptr; - - if (get_max_medium_snapshot() >= input_info.medium_snapshot_) { - // do nothing - } else if (OB_ISNULL(alloc_buf = allocator_->alloc(sizeof(ObMediumCompactionInfo)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("failed to alloc memory", K(ret)); - } else if (FALSE_IT(new_info = new (alloc_buf) ObMediumCompactionInfo())) { - } else if (OB_FAIL(new_info->init(*allocator_, input_info))) { - LOG_WARN("failed to init medium info", K(ret), K(input_info)); - } else if (OB_UNLIKELY(!medium_info_list_.add_last(new_info))) { - ret = OB_ERR_SYS; - LOG_WARN("failed to add into medium info list", K(ret), KPC(new_info)); - } else if (OB_UNLIKELY(!inner_is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("medium info list is invalid", K(ret), KPC(this)); - medium_info_list_.remove(new_info); - } else { - LOG_TRACE("success to deep copy append medium info", K(ret), KPC(new_info)); - } - - if (OB_FAIL(ret) && nullptr != new_info) { - new_info->~ObMediumCompactionInfo(); - allocator_->free(new_info); - new_info = nullptr; - } - return ret; -} - int ObMediumCompactionInfoList::serialize(char *buf, const int64_t buf_len, int64_t &pos) const { int ret = OB_SUCCESS; diff --git a/src/storage/compaction/ob_medium_compaction_mgr.h b/src/storage/compaction/ob_medium_compaction_mgr.h index 78f74fd8c..373f84ead 100644 --- a/src/storage/compaction/ob_medium_compaction_mgr.h +++ b/src/storage/compaction/ob_medium_compaction_mgr.h @@ -25,6 +25,8 @@ namespace oceanbase namespace storage { class ObTablet; +class ObTaletExtraMediumInfo; +class ObTabletDumpedMediumInfo; } namespace compaction { @@ -45,7 +47,6 @@ public: int submit_medium_compaction_info(ObMediumCompactionInfo &medium_info, ObIAllocator &allocator); // follower int replay_medium_compaction_log(const share::SCN &scn, const char *buf, const int64_t size, int64_t &pos); - private: virtual int inner_replay_clog( const int64_t update_version, @@ -69,7 +70,8 @@ private: free_allocated_info(); } void free_allocated_info(); - OB_INLINE int dec_ref_on_memtable(const bool sync_finish); + OB_INLINE int submit_trans_on_mds_table(const bool is_commit); + private: bool is_inited_; bool ignore_medium_; @@ -78,28 +80,27 @@ private: storage::ObTabletHandle *tablet_handle_ptr_; ObMediumCompactionInfo *medium_info_; common::ObIAllocator *allocator_; + mds::MdsCtx *mds_ctx_; }; -class ObMediumCompactionInfoList +class ObMediumCompactionInfoList final { public: ObMediumCompactionInfoList(); ~ObMediumCompactionInfoList(); - typedef memtable::ObIMultiSourceDataUnit BasicNode; - typedef common::ObDList MediumInfoList; + typedef common::ObDList MediumInfoList; int init(common::ObIAllocator &allocator); - int init(common::ObIAllocator &allocator, - const ObMediumCompactionInfoList *old_list, - const ObMediumCompactionInfoList *dump_list = nullptr, - const int64_t finish_medium_scn = 0, - const ObMergeType merge_type = MERGE_TYPE_MAX); + int init( + common::ObIAllocator &allocator, + const ObMediumCompactionInfoList *input_list); - int init_after_check_finish( - ObIAllocator &allocator, - const ObMediumCompactionInfoList &old_list); + int init( + common::ObIAllocator &allocator, + const ObTaletExtraMediumInfo &extra_medium_info, + const ObTabletDumpedMediumInfo &medium_info_list); void reset(); OB_INLINE bool is_empty() const { return 0 == medium_info_list_.get_size(); } @@ -107,11 +108,8 @@ public: OB_INLINE bool is_valid() const { - return is_inited_ && inner_is_valid(); + return inner_is_valid(); } - - int add_medium_compaction_info(const ObMediumCompactionInfo &input_info); - OB_INLINE const MediumInfoList &get_list() const { return medium_info_list_; } OB_INLINE int64_t get_wait_check_medium_scn() const { return wait_check_flag_ ? last_medium_scn_ : 0; } OB_INLINE bool need_check_finish() const { return wait_check_flag_; } @@ -128,25 +126,9 @@ public: { return last_medium_scn_; } - void get_schedule_scn( - const int64_t major_compaction_scn, - int64_t &schedule_scn, - ObMediumCompactionInfo::ObCompactionType &compaction_type) const; - - int get_specified_scn_info( - const int64_t snapshot, - const ObMediumCompactionInfo *&compaction_info) const; - OB_INLINE int64_t get_max_medium_snapshot() const + OB_INLINE uint64_t get_union_info() const { - return is_empty() ? 0 : static_cast(medium_info_list_.get_last())->medium_snapshot_; - } - OB_INLINE int64_t get_min_medium_snapshot() const - { - return is_empty() ? -1 : static_cast(medium_info_list_.get_first())->medium_snapshot_; - } - const ObMediumCompactionInfo *get_first_medium_info() const - { - return is_empty() ? nullptr : static_cast(medium_info_list_.get_first()); + return info_; } // serialize & deserialize @@ -170,30 +152,15 @@ private: return last_compaction_type_ < ObMediumCompactionInfo::COMPACTION_TYPE_MAX && last_medium_scn_ >= 0 && size() >= 0; } - OB_INLINE int append_list_with_deep_copy( - const int64_t finish_scn, - const ObMediumCompactionInfoList &input_list) - { - int ret = OB_SUCCESS; - DLIST_FOREACH_X(input_info, input_list.medium_info_list_, OB_SUCC(ret)) { - const ObMediumCompactionInfo *medium_info = static_cast(input_info); - if (medium_info->medium_snapshot_ > finish_scn) { - ret = inner_deep_copy_node(*medium_info); - } - } - return ret; - } - int inner_deep_copy_node(const ObMediumCompactionInfo &medium_info); + OB_INLINE void set_basic_info(const ObMediumCompactionInfoList &input_list) { last_compaction_type_ = input_list.last_compaction_type_; last_medium_scn_ = input_list.last_medium_scn_; wait_check_flag_ = input_list.wait_check_flag_; } - private: static const int64_t MEDIUM_LIST_VERSION = 1; - static const int64_t MAX_SERIALIZE_SIZE = 2; static const int32_t MEDIUM_LIST_INFO_RESERVED_BITS = 51; private: @@ -212,7 +179,7 @@ private: }; int64_t last_medium_scn_; - MediumInfoList medium_info_list_; + MediumInfoList medium_info_list_; // need for compat, will not store any MediumCompactionInfo after 4.2 }; } // namespace compaction diff --git a/src/storage/compaction/ob_partition_merge_fuser.cpp b/src/storage/compaction/ob_partition_merge_fuser.cpp index ea1dab2a6..1c0a31782 100644 --- a/src/storage/compaction/ob_partition_merge_fuser.cpp +++ b/src/storage/compaction/ob_partition_merge_fuser.cpp @@ -47,8 +47,7 @@ void ObIPartitionMergeFuser::reset() bool ObIPartitionMergeFuser::is_valid() const { - return (is_inited_ && schema_rowkey_column_cnt_ > 0 && column_cnt_ > 0 - && multi_version_column_ids_.count() > 0); + return (is_inited_ && schema_rowkey_column_cnt_ > 0 && column_cnt_ > 0); } int ObIPartitionMergeFuser::calc_column_checksum(const bool rewrite) @@ -67,8 +66,6 @@ int ObIPartitionMergeFuser::init(const ObMergeParameter &merge_param) STORAGE_LOG(WARN, "ObIPartitionMergeFuser init twice", K(ret)); } else if (OB_FAIL(check_merge_param(merge_param))) { STORAGE_LOG(WARN, "Invalid argument to init ObIPartitionMergeFuser", K(merge_param), K(ret)); - } else if (OB_FAIL(merge_param.merge_schema_->get_multi_version_column_descs(multi_version_column_ids_))) { - STORAGE_LOG(WARN, "Failed to get column ids", K(ret)); } else if (OB_FAIL(inner_init(merge_param))) { STORAGE_LOG(WARN, "Failed to inner init", K(ret), K(*this)); } else if (OB_FAIL(base_init(merge_param))) { @@ -153,6 +150,11 @@ void ObMajorPartitionMergeFuser::reset() ObIPartitionMergeFuser::reset(); } +bool ObMajorPartitionMergeFuser::is_valid() const +{ + return ObIPartitionMergeFuser::is_valid() && multi_version_column_ids_.count() > 0; +} + int ObMajorPartitionMergeFuser::inner_check_merge_param(const ObMergeParameter &merge_param) { int ret = OB_SUCCESS; @@ -181,6 +183,8 @@ int ObMajorPartitionMergeFuser::inner_init(const ObMergeParameter &merge_param) if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; STORAGE_LOG(WARN, "ObIPartitionMergeFuser init twice", K(ret)); + } else if (OB_FAIL(merge_param.merge_schema_->get_multi_version_column_descs(multi_version_column_ids_))) { + STORAGE_LOG(WARN, "Failed to get column ids", K(ret)); } else if (OB_FAIL(default_row_.init(allocator_, multi_version_column_ids_.count()))) { STORAGE_LOG(WARN, "Failed to init datum row", K(ret)); } else if (OB_FAIL(merge_param.merge_schema_->get_orig_default_row(multi_version_column_ids_, default_row_))) { @@ -367,7 +371,7 @@ void ObMinorPartitionMergeFuser::reset() bool ObMinorPartitionMergeFuser::is_valid() const { - return ObIPartitionMergeFuser::is_valid() && multi_version_rowkey_column_cnt_ > 0 && multi_version_column_ids_.count() > 0; + return ObIPartitionMergeFuser::is_valid() && multi_version_rowkey_column_cnt_ > 0 && multi_version_column_ids_.count() == multi_version_rowkey_column_cnt_; } int ObMinorPartitionMergeFuser::inner_check_merge_param(const ObMergeParameter &merge_param) @@ -393,14 +397,17 @@ int ObMinorPartitionMergeFuser::inner_check_merge_param(const ObMergeParameter & int ObMinorPartitionMergeFuser::inner_init(const ObMergeParameter &merge_param) { int ret = OB_SUCCESS; - + int64_t column_cnt = 0; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; STORAGE_LOG(WARN, "ObIPartitionMergeFuser init twice", K(ret)); + } else if (OB_FAIL(merge_param.merge_schema_->get_mulit_version_rowkey_column_ids(multi_version_column_ids_))) { + STORAGE_LOG(WARN, "Failed to get column ids", K(ret)); + } else if (OB_FAIL(merge_param.merge_schema_->get_store_column_count(column_cnt, true/*full_col*/))) { + STORAGE_LOG(WARN, "failed to get store column count", K(ret), K(merge_param.merge_schema_)); } else { - column_cnt_ = multi_version_column_ids_.count(); - multi_version_rowkey_column_cnt_ = merge_param.merge_schema_->get_rowkey_column_num() - + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + column_cnt_ = column_cnt + storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + multi_version_rowkey_column_cnt_ = multi_version_column_ids_.count(); } return ret; diff --git a/src/storage/compaction/ob_partition_merge_fuser.h b/src/storage/compaction/ob_partition_merge_fuser.h index 842f56fcd..abb63605a 100644 --- a/src/storage/compaction/ob_partition_merge_fuser.h +++ b/src/storage/compaction/ob_partition_merge_fuser.h @@ -77,6 +77,8 @@ protected: blocksstable::ObDatumRow result_row_; storage::ObNopPos nop_pos_; common::ObArenaAllocator allocator_; + // for major: store all columns' description + // for mini & minor: store multi_version rowkey column description common::ObArray multi_version_column_ids_; bool is_inited_; int64_t purged_count_; @@ -92,6 +94,7 @@ public: {} virtual ~ObMajorPartitionMergeFuser(); virtual void reset() override; + virtual bool is_valid() const override; virtual int fuse_row(MERGE_ITER_ARRAY ¯o_row_iters) override; virtual const char *get_fuser_name() const override { return "ObMajorPartitionMergeFuser"; } INHERIT_TO_STRING_KV("ObIPartitionMergeFuser", ObIPartitionMergeFuser, K_(default_row)); diff --git a/src/storage/compaction/ob_partition_merge_iter.cpp b/src/storage/compaction/ob_partition_merge_iter.cpp index 04fae6695..b82e4c665 100644 --- a/src/storage/compaction/ob_partition_merge_iter.cpp +++ b/src/storage/compaction/ob_partition_merge_iter.cpp @@ -93,16 +93,18 @@ int ObPartitionMergeIter::init_query_base_params(const ObMergeParameter &merge_p int ret = OB_SUCCESS; ObSSTable *sstable = nullptr; SCN snapshot_version; + int64_t schema_stored_col_cnt = 0; if (OB_UNLIKELY(nullptr == column_ids_ || nullptr == table_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected null column_ids", K(ret), KPC(this)); + } else if (OB_FAIL(merge_param.merge_schema_->get_store_column_count(schema_stored_col_cnt, true/*full_col*/))) { + LOG_WARN("failed to get storage count", K(ret), KPC(merge_param.merge_schema_)); } else if (OB_FAIL(read_info_.init( allocator_, - merge_param.merge_schema_->get_column_count(), + schema_stored_col_cnt, schema_rowkey_column_cnt_, lib::is_oracle_mode(), - *column_ids_, - true))) { + *column_ids_))) { LOG_WARN("Fail to init read_info", K(ret)); } else if (OB_FAIL(access_param_.init_merge_param(tablet_id_.id(), tablet_id_, read_info_, is_multi_version_merge(merge_param.merge_type_)))) { @@ -128,8 +130,9 @@ int ObPartitionMergeIter::init_query_base_params(const ObMergeParameter &merge_p LOG_WARN("Failed to init table access context", K(ret), K(query_flag)); } else { access_context_.trans_state_mgr_ = merge_param.trans_state_mgr_; - // always use end_scn for safety - access_context_.merge_scn_ = merge_param.scn_range_.end_scn_; + // 1.normal minor merge merge scn equal to end scn + // 2.backfill may merge scn is bigger than end scn + access_context_.merge_scn_ = merge_param.merge_scn_; } } return ret; @@ -429,12 +432,12 @@ int ObPartitionMacroMergeIter::inner_init(const ObMergeParameter &merge_param) void *buf = nullptr; ObSSTable *sstable = static_cast(table_); - const ObTableReadInfo *index_read_info = merge_param.full_read_info_->get_index_read_info(); - if (OB_ISNULL(index_read_info)) { + const ObITableReadInfo *rowkey_read_info_ = merge_param.rowkey_read_info_; + if (OB_ISNULL(rowkey_read_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected null index read info", K(ret)); } else if (OB_FAIL(sstable->scan_macro_block( - merge_range_, *index_read_info, stmt_allocator_, macro_block_iter_, false, true, true))) { + merge_range_, *rowkey_read_info_, stmt_allocator_, macro_block_iter_, false, true, true))) { LOG_WARN("Fail to scan macro block", K(ret)); } else if (OB_ISNULL(buf = stmt_allocator_.alloc(sizeof(ObSSTableRowWholeScanner)))) { ret = OB_ALLOCATE_MEMORY_FAILED; @@ -502,7 +505,7 @@ int ObPartitionMacroMergeIter::exist(const ObDatumRow *row, bool &is_exist) ObDatumRowkey rowkey; if (OB_FAIL(rowkey.assign(row->storage_datums_, schema_rowkey_column_cnt_))) { STORAGE_LOG(WARN, "Failed to assign rowkey", K(ret), KPC(row), K_(schema_rowkey_column_cnt)); - } else if (OB_FAIL(table_->exist(store_ctx_, tablet_id_.id(), read_info_, rowkey, is_exist, has_found))) { + } else if (OB_FAIL(table_->exist(access_param_.iter_param_, access_context_, rowkey, is_exist, has_found))) { LOG_WARN("Failed to check row if exist", K(ret), KPC(row)); } } @@ -1318,8 +1321,8 @@ int ObPartitionMinorMacroMergeIter::inner_init(const ObMergeParameter &merge_par { int ret = OB_SUCCESS; void *buf = nullptr; - const ObTableReadInfo *index_read_info = merge_param.full_read_info_->get_index_read_info(); - if (OB_ISNULL(index_read_info)) { + const ObITableReadInfo *rowkey_read_info_ = merge_param.rowkey_read_info_; + if (OB_ISNULL(rowkey_read_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected null index read info", K(ret)); } else if (OB_FAIL(common_minor_inner_init(merge_param))) { @@ -1337,13 +1340,13 @@ int ObPartitionMinorMacroMergeIter::inner_init(const ObMergeParameter &merge_par ObSSTable *sstable = static_cast(table_); if (OB_FAIL(sstable->scan_macro_block( merge_range_, - *index_read_info, + *rowkey_read_info_, stmt_allocator_, macro_block_iter_, false, /* reverse scan */ false, /* need micro info */ true /* need secondary meta */))) { - LOG_WARN("Fail to scan macro block", K(ret), KPC(merge_param.full_read_info_)); + LOG_WARN("Fail to scan macro block", K(ret)); } } diff --git a/src/storage/compaction/ob_partition_merge_iter.h b/src/storage/compaction/ob_partition_merge_iter.h index d45cc10e7..a80bb0918 100644 --- a/src/storage/compaction/ob_partition_merge_iter.h +++ b/src/storage/compaction/ob_partition_merge_iter.h @@ -99,7 +99,7 @@ public: return bret; } int check_merge_range_cross(ObDatumRange &data_range, bool &range_cross); - OB_INLINE const ObTableReadInfo &get_read_info() const{ return read_info_; } + OB_INLINE const ObITableReadInfo &get_read_info() const{ return read_info_; } VIRTUAL_TO_STRING_KV(K_(tablet_id), K_(iter_end), K_(schema_rowkey_column_cnt), K_(schema_version), K_(merge_range), KPC(curr_row_), K_(store_ctx), KPC(row_iter_), K_(iter_row_count), K_(is_inited), @@ -117,7 +117,8 @@ protected: int64_t schema_version_; ObRowStoreType row_store_type_; blocksstable::ObDatumRange merge_range_; - // only major merge use column_ids + // major: column_ids contains all stored column + // mini & minor: only mv rowkey column const common::ObIArray *column_ids_; storage::ObITable *table_; storage::ObStoreCtx store_ctx_; @@ -134,7 +135,7 @@ protected: common::ObArenaAllocator allocator_; // not only stmt allocator, also reserve memory for iters internal use common::ObArenaAllocator stmt_allocator_; - ObTableReadInfo read_info_; + ObRowkeyReadInfo read_info_; bool is_inited_; bool is_rowkey_first_row_reused_; bool is_rowkey_shadow_row_reused_; diff --git a/src/storage/compaction/ob_partition_merge_policy.cpp b/src/storage/compaction/ob_partition_merge_policy.cpp old mode 100644 new mode 100755 index 1c054927e..ae7746c3c --- a/src/storage/compaction/ob_partition_merge_policy.cpp +++ b/src/storage/compaction/ob_partition_merge_policy.cpp @@ -84,21 +84,26 @@ int ObPartitionMergePolicy::get_medium_merge_tables( { int ret = OB_SUCCESS; ObSSTable *base_table = nullptr; - const ObTabletTableStore &table_store = tablet.get_table_store(); result.reset(); result.merge_version_ = param.merge_version_; result.suggest_merge_type_ = param.merge_type_; + ObTabletMemberWrapper table_store_wrapper; DEBUG_SYNC(BEFORE_GET_MAJOR_MGERGE_TABLES); - - if (OB_UNLIKELY(!table_store.is_valid() || !param.is_valid() || !is_major_merge_type(param.merge_type_))) { + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_UNLIKELY( + !table_store_wrapper.get_member()->is_valid() + || !param.is_valid() + || !is_major_merge_type(param.merge_type_))) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid argument", K(ret), K(table_store), K(param)); - } else if (OB_ISNULL(base_table = static_cast(table_store.get_major_sstables().get_boundary_table(true/*last*/)))) { + LOG_WARN("get invalid argument", K(ret), KPC(table_store_wrapper.get_member()), K(param)); + } else if (OB_ISNULL(base_table = static_cast( + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/)))) { ret = OB_ENTRY_NOT_EXIST; - LOG_ERROR("major sstable not exist", K(ret), K(table_store)); + LOG_ERROR("major sstable not exist", K(ret), KPC(table_store_wrapper.get_member())); } else if (OB_FAIL(base_table->get_frozen_schema_version(result.base_schema_version_))) { LOG_WARN("failed to get frozen schema version", K(ret)); - } else if (OB_FAIL(result.handle_.add_table(base_table))) { + } else if (OB_FAIL(result.handle_.add_sstable(base_table, table_store_wrapper.get_meta_handle()))) { LOG_WARN("failed to add base_table to result", K(ret)); } else if (base_table->get_snapshot_version() >= param.merge_version_) { ret = OB_NO_NEED_MERGE; @@ -110,9 +115,9 @@ int ObPartitionMergePolicy::get_medium_merge_tables( ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet haven't kept medium snapshot", K(ret), K(tablet), K(param)); } else { - const ObSSTableArray &minor_tables = table_store.get_minor_sstables(); + const ObSSTableArray &minor_tables = table_store_wrapper.get_member()->get_minor_sstables(); bool start_add_table_flag = false; - for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.count_; ++i) { + for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.count(); ++i) { if (OB_ISNULL(minor_tables[i])) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("table must not null", K(ret), K(i), K(minor_tables)); @@ -121,7 +126,7 @@ int ObPartitionMergePolicy::get_medium_merge_tables( start_add_table_flag = true; } if (OB_SUCC(ret) && start_add_table_flag) { - if (OB_FAIL(result.handle_.add_table(minor_tables[i]))) { + if (OB_FAIL(result.handle_.add_sstable(minor_tables[i], table_store_wrapper.get_meta_handle()))) { LOG_WARN("failed to add table", K(ret)); } } @@ -139,11 +144,14 @@ int ObPartitionMergePolicy::get_medium_merge_tables( result.version_range_.base_version_ = base_table->get_upper_trans_version(); result.version_range_.multi_version_start_ = tablet.get_multi_version_start(); result.version_range_.snapshot_version_ = param.merge_version_; + ObSSTableMetaHandle sstable_meta_hdl; if (OB_FAIL(get_multi_version_start(param.merge_type_, ls, tablet, result.version_range_))) { LOG_WARN("failed to get multi version_start", K(ret)); + } else if (OB_FAIL(base_table->get_meta(sstable_meta_hdl))) { + LOG_WARN("failed to get base table meta", K(ret)); } else { result.read_base_version_ = base_table->get_snapshot_version(); - result.create_snapshot_version_ = base_table->get_meta().get_basic_meta().create_snapshot_version_; + result.create_snapshot_version_ = sstable_meta_hdl.get_sstable_meta().get_basic_meta().create_snapshot_version_; } } return ret; @@ -160,29 +168,30 @@ int ObPartitionMergePolicy::get_mini_merge_tables( ObTenantFreezeInfoMgr::NeighbourFreezeInfo freeze_info; int64_t merge_inc_base_version = tablet.get_snapshot_version(); const ObMergeType merge_type = param.merge_type_; - const ObTabletTableStore &table_store = tablet.get_table_store(); ObSEArray memtable_handles; result.reset(); + ObTabletMemberWrapper table_store_wrapper; DEBUG_SYNC(BEFORE_GET_MINOR_MGERGE_TABLES); - - if (MINI_MERGE != merge_type) { + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_UNLIKELY(MINI_MERGE != merge_type)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(merge_type)); - } else if (OB_UNLIKELY(nullptr == tablet.get_memtable_mgr() || !table_store.is_valid())) { + } else if (OB_UNLIKELY(nullptr == tablet.get_memtable_mgr() || !table_store_wrapper.get_member()->is_valid())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected null memtable mgr from tablet or invalid table store", K(ret), K(tablet), K(table_store)); - } else if (table_store.get_minor_sstables().count() >= MAX_SSTABLE_CNT_IN_STORAGE) { + LOG_WARN("get unexpected null memtable mgr from tablet or invalid table store", K(ret), K(tablet), K(table_store_wrapper)); + } else if (table_store_wrapper.get_member()->get_minor_sstables().count() >= MAX_SSTABLE_CNT_IN_STORAGE) { ret = OB_SIZE_OVERFLOW; LOG_ERROR("Too many sstables, delay mini merge until sstable count falls below MAX_SSTABLE_CNT", - K(ret), K(table_store), K(tablet)); + K(ret), K(table_store_wrapper), K(tablet)); // add compaction diagnose info ObPartitionMergePolicy::diagnose_table_count_unsafe(MINI_MERGE, tablet); } else if (OB_FAIL(tablet.get_memtable_mgr()->get_all_memtables(memtable_handles))) { LOG_WARN("failed to get all memtables from memtable mgr", K(ret)); } else if (OB_FAIL(get_neighbour_freeze_info(merge_inc_base_version, - table_store.get_major_sstables().get_boundary_table(true), + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true), freeze_info))) { - LOG_WARN("failed to get next major freeze", K(ret), K(merge_inc_base_version), K(table_store)); + LOG_WARN("failed to get next major freeze", K(ret), K(merge_inc_base_version), K(table_store_wrapper)); } else if (OB_FAIL(find_mini_merge_tables(param, freeze_info, ls, tablet, memtable_handles, result))) { if (OB_NO_NEED_MERGE != ret) { LOG_WARN("failed to find mini merge tables", K(ret), K(freeze_info)); @@ -250,7 +259,7 @@ int ObPartitionMergePolicy::find_mini_merge_tables( } if (OB_SUCC(ret)) { - if (OB_FAIL(result.handle_.add_table(memtable))) { + if (OB_FAIL(result.handle_.add_memtable(memtable))) { LOG_WARN("Failed to add memtable", KPC(memtable), K(ret)); } else { // update end_scn/snapshot_version @@ -307,20 +316,30 @@ int ObPartitionMergePolicy::deal_with_minor_result( LOG_WARN("failed to check continues", K(ret), K(result)); } else if (OB_FAIL(get_multi_version_start(merge_type, ls, tablet, result.version_range_))) { LOG_WARN("failed to get kept multi_version_start", K(ret), K(merge_type), K(tablet)); + } else if (OB_FAIL(tablet.get_schema_version_from_storage_schema(result.schema_version_))) { + LOG_WARN("failed to get schema version from storage schema", K(ret)); } else { - result.schema_version_ = tablet.get_storage_schema().schema_version_; - if (MINI_MERGE == merge_type) { + if (tablet.is_ls_inner_tablet()) { + // do nothing + result.base_schema_version_ = result.schema_version_; + } else if (MINI_MERGE == merge_type) { ObITable *table = NULL; result.base_schema_version_ = result.schema_version_; + int64_t max_schema_version_on_memtable = 0; + int64_t unused_max_column_cnt_on_memtable = 0; for (int64_t i = 0; OB_SUCC(ret) && i < result.handle_.get_count(); ++i) { if (OB_ISNULL(table = result.handle_.get_table(i)) || !table->is_memtable()) { ret = OB_ERR_SYS; LOG_ERROR("get unexpected table", KPC(table), K(ret)); - } else { - result.schema_version_ = MAX(result.schema_version_, reinterpret_cast(table)->get_max_schema_version()); + } else if (OB_FAIL(reinterpret_cast(table)->get_schema_info( + max_schema_version_on_memtable, unused_max_column_cnt_on_memtable))) { + LOG_WARN("failed to get schema info from memtable", KR(ret), KPC(table)); } } - } else { + if (OB_SUCC(ret)) { + result.schema_version_ = MAX(result.schema_version_, max_schema_version_on_memtable); + } + } else { // for minor if (OB_FAIL(result.handle_.get_table(0)->get_frozen_schema_version(result.base_schema_version_))) { LOG_WARN("failed to get frozen schema version", K(ret), K(result)); } @@ -328,9 +347,8 @@ int ObPartitionMergePolicy::deal_with_minor_result( if (OB_SUCC(ret)) { result.version_range_.base_version_ = 0; if (OB_SUCC(ret) && !is_mini_merge(merge_type)) { - const ObTabletTableStore &table_store = tablet.get_table_store(); - if (OB_FAIL(table_store.get_recycle_version(result.version_range_.multi_version_start_, result.version_range_.base_version_))) { - LOG_WARN("Fail to get table store recycle version", K(ret), K(result.version_range_), K(table_store)); + if (OB_FAIL(tablet.get_recycle_version(result.version_range_.multi_version_start_, result.version_range_.base_version_))) { + LOG_WARN("Fail to get table store recycle version", K(ret), K(result.version_range_), K(tablet)); } } } @@ -358,7 +376,9 @@ int ObPartitionMergePolicy::get_minor_merge_tables( } else if (tablet.is_ls_inner_tablet()) { min_snapshot_version = 0; max_snapshot_version = INT64_MAX; - } else if (OB_FAIL(get_boundary_snapshot_version(tablet, min_snapshot_version, max_snapshot_version))) { + } else if (OB_FAIL(get_boundary_snapshot_version( + tablet, min_snapshot_version, max_snapshot_version, + true /*check_table_cnt*/, true /*is_multi_version_merge*/))) { LOG_WARN("fail to calculate boundary version", K(ret)); } @@ -381,27 +401,31 @@ int ObPartitionMergePolicy::get_boundary_snapshot_version( const ObTablet &tablet, int64_t &min_snapshot, int64_t &max_snapshot, - const bool check_table_cnt) + const bool check_table_cnt, + const bool is_multi_version_merge) { int ret = OB_SUCCESS; int64_t merge_inc_base_version = tablet.get_snapshot_version(); ObTenantFreezeInfoMgr::NeighbourFreezeInfo freeze_info; - const ObTabletTableStore &table_store = tablet.get_table_store(); - ObITable *last_major_table = table_store.get_major_sstables().get_boundary_table(true); + ObTabletMemberWrapper table_store_wrapper; + ObITable *last_major_table = nullptr; if (OB_UNLIKELY(tablet.is_ls_inner_tablet())) { ret = OB_NOT_SUPPORTED; LOG_WARN("not supported for special tablet", K(ret), K(tablet)); - } else if (OB_UNLIKELY(!table_store.is_valid())) { + } else if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_UNLIKELY(!table_store_wrapper.get_member()->is_valid())) { ret = OB_ERR_SYS; - LOG_WARN("table store not valid", K(ret), K(table_store)); + LOG_WARN("table store not valid", K(ret), K(table_store_wrapper)); + } else if (FALSE_IT(last_major_table = table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true))) { } else if (OB_FAIL(get_neighbour_freeze_info(merge_inc_base_version, last_major_table, freeze_info))) { - LOG_WARN("failed to get freeze info", K(ret), K(merge_inc_base_version), K(table_store)); - } else if (check_table_cnt && table_store.get_table_count() >= OB_UNSAFE_TABLE_CNT) { + LOG_WARN("failed to get freeze info", K(ret), K(merge_inc_base_version), K(table_store_wrapper)); + } else if (check_table_cnt && table_store_wrapper.get_member()->get_table_count() >= OB_UNSAFE_TABLE_CNT) { max_snapshot = INT64_MAX; - if (table_store.get_table_count() >= OB_EMERGENCY_TABLE_CNT) { + if (table_store_wrapper.get_member()->get_table_count() >= OB_EMERGENCY_TABLE_CNT) { min_snapshot = 0; } else if (OB_NOT_NULL(last_major_table)) { min_snapshot = last_major_table->get_snapshot_version(); @@ -412,17 +436,20 @@ int ObPartitionMergePolicy::get_boundary_snapshot_version( } else { min_snapshot = freeze_info.prev.freeze_version; } - max_snapshot = freeze_info.next.freeze_version; + if (INT64_MAX == freeze_info.next.freeze_version && is_multi_version_merge) { + max_snapshot = MTL(ObTenantFreezeInfoMgr*)->get_snapshot_gc_ts(); + } else { + max_snapshot = freeze_info.next.freeze_version; + } int64_t max_medium_scn = 0; - if (OB_FAIL(tablet.get_max_medium_snapshot(max_medium_scn))) { - LOG_WARN("failed to get medium from memtables", K(ret)); + if (OB_FAIL(tablet.get_max_sync_medium_scn(max_medium_scn))) { + LOG_WARN("failed to get max medium snapshot", K(ret), K(tablet)); } else { min_snapshot = max(min_snapshot, max_medium_scn); } - LOG_DEBUG("get boundary snapshot", K(ret), "tablet_id", tablet.get_tablet_meta().tablet_id_, K(table_store), K(min_snapshot), K(max_snapshot), - K(tablet.get_medium_compaction_info_list()), K(max_medium_scn), KPC(last_major_table), - K(freeze_info)); + LOG_DEBUG("get boundary snapshot", K(ret), "tablet_id", tablet.get_tablet_meta().tablet_id_, K(table_store_wrapper), + K(min_snapshot), K(max_snapshot), K(max_medium_scn), KPC(last_major_table), K(freeze_info)); } return ret; } @@ -437,15 +464,17 @@ int ObPartitionMergePolicy::find_minor_merge_tables( { int ret = OB_SUCCESS; result.reset_handle_and_range(); - const ObTabletTableStore &table_store = tablet.get_table_store(); - ObTablesHandleArray minor_tables; + ObTableStoreIterator minor_table_iter; int64_t minor_compact_trigger = DEFAULT_MINOR_COMPACT_TRIGGER; + ObTabletMemberWrapper table_store_wrapper; - if (OB_UNLIKELY(!table_store.is_valid())) { + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_UNLIKELY(!table_store_wrapper.get_member()->is_valid())) { ret = OB_ERR_SYS; - LOG_WARN("unexpected table store", K(ret), K(table_store)); - } else if (OB_FAIL(table_store.get_mini_minor_sstables(minor_tables))) { - LOG_WARN("failed to get mini minor sstables", K(ret), K(table_store)); + LOG_WARN("unexpected table store", K(ret), K(table_store_wrapper)); + } else if (OB_FAIL(tablet.get_mini_minor_sstables(minor_table_iter))) { + LOG_WARN("failed to get mini minor sstables", K(ret)); } else { ObSSTable *table = nullptr; bool found_greater = false; @@ -456,31 +485,38 @@ int ObPartitionMergePolicy::find_minor_merge_tables( } } - ObSEArray minor_merge_candidates; - for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.get_count(); ++i) { - if (OB_ISNULL(table = static_cast(minor_tables.get_table(i)))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table must not null", K(ret), K(i), K(table_store)); + ObTablesHandleArray minor_merge_candidates; + while (OB_SUCC(ret)) { + ObTableHandleV2 cur_table_handle; + if (OB_FAIL(minor_table_iter.get_next(cur_table_handle))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next table", K(ret)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(cur_table_handle.get_sstable(table))) { + LOG_WARN("failed to get sstable from handle", K(ret), K(cur_table_handle)); } else if (!found_greater && table->get_upper_trans_version() <= min_snapshot_version) { continue; } else { found_greater = true; - if (0 == minor_merge_candidates.count()) { + if (0 == minor_merge_candidates.get_count()) { } else if (is_history_minor_merge(param.merge_type_) && table->get_upper_trans_version() > max_snapshot_version) { break; - } else if (table_store.get_table_count() < OB_UNSAFE_TABLE_CNT && + } else if (table_store_wrapper.get_member()->get_table_count() < OB_UNSAFE_TABLE_CNT && table->get_max_merged_trans_version() > max_snapshot_version) { LOG_INFO("max_snapshot_version reached, stop find more tables", K(param), K(max_snapshot_version), KPC(table)); break; } - if (OB_FAIL(minor_merge_candidates.push_back(table))) { + if (OB_FAIL(minor_merge_candidates.add_table(cur_table_handle))) { LOG_WARN("failed to add table", K(ret)); } } } int64_t left_border = 0; - int64_t right_border = minor_merge_candidates.count(); + int64_t right_border = minor_merge_candidates.get_count(); if (OB_FAIL(ret)) { } else if (MINOR_MERGE != param.merge_type_) { } else if (OB_FAIL(refine_minor_merge_tables(tablet, minor_merge_candidates, left_border, right_border))) { @@ -488,19 +524,22 @@ int ObPartitionMergePolicy::find_minor_merge_tables( } for (int64_t i = left_border; OB_SUCC(ret) && i < right_border; ++i) { - ObSSTable *table = minor_merge_candidates.at(i); - if (result.handle_.get_count() > 0 && result.scn_range_.end_scn_ < table->get_start_scn()) { + ObTableHandleV2 tmp_table_handle; + if (OB_FAIL(minor_merge_candidates.get_table(i, tmp_table_handle))) { + LOG_WARN("failed to get table handle from array", K(ret), K(tmp_table_handle)); + } else if (result.handle_.get_count() > 0 + && result.scn_range_.end_scn_ < tmp_table_handle.get_table()->get_start_scn()) { LOG_INFO("log ts not continues, reset previous minor merge tables", - "last_end_log_ts", result.scn_range_.end_scn_, KPC(table)); + "last_end_log_ts", result.scn_range_.end_scn_, K(tmp_table_handle)); result.reset_handle_and_range(); } - if (OB_FAIL(result.handle_.add_table(table))) { + if (OB_FAIL(result.handle_.add_table(tmp_table_handle))) { LOG_WARN("Failed to add table", K(ret), KPC(table)); } else { if (1 == result.handle_.get_count()) { - result.scn_range_.start_scn_ = table->get_start_scn(); + result.scn_range_.start_scn_ = tmp_table_handle.get_table()->get_start_scn(); } - result.scn_range_.end_scn_ = table->get_end_scn(); + result.scn_range_.end_scn_ = tmp_table_handle.get_table()->get_end_scn(); } } } @@ -516,44 +555,51 @@ int ObPartitionMergePolicy::find_minor_merge_tables( if (OB_FAIL(deal_with_minor_result(param.merge_type_, ls, tablet, result))) { LOG_WARN("Failed to deal with minor merge result", K(ret), K(param), K(result)); } else { - FLOG_INFO("succeed to get minor merge tables", K(min_snapshot_version), K(max_snapshot_version), + LOG_TRACE("succeed to get minor merge tables", K(min_snapshot_version), K(max_snapshot_version), K(result), K(tablet)); } } - } else if (OB_NO_NEED_MERGE == ret && table_store.get_minor_sstables().count() >= DIAGNOSE_TABLE_CNT_IN_STORAGE) { - ADD_SUSPECT_INFO(MINOR_MERGE, - tablet.get_tablet_meta().ls_id_, - tablet.get_tablet_meta().tablet_id_, - "can't schedule minor merge.", - K(min_snapshot_version), K(max_snapshot_version), - "mini_sstable_cnt", table_store.get_minor_sstables().count()); + } else if (OB_NO_NEED_MERGE == ret + && table_store_wrapper.get_member()->get_minor_sstables().count() >= DIAGNOSE_TABLE_CNT_IN_STORAGE) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(ADD_SUSPECT_INFO(MINOR_MERGE, + tablet.get_tablet_meta().ls_id_, + tablet.get_tablet_meta().tablet_id_, + ObSuspectInfoType::SUSPECT_CANT_SCHEDULE_MINOR_MERGE, + min_snapshot_version, max_snapshot_version, table_store_wrapper.get_member()->get_minor_sstables().count()))) { + LOG_WARN("failed to add suspect info", K(tmp_ret)); + } } return ret; } int ObPartitionMergePolicy::refine_minor_merge_tables( const ObTablet &tablet, - const ObIArray &merge_tables, + const ObTablesHandleArray &merge_tables, int64_t &left_border, int64_t &right_border) { int ret = OB_SUCCESS; const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; - ObITable *meta_table = tablet.get_table_store().get_extend_sstable(ObTabletTableStore::META_MAJOR); + ObITable *meta_table = nullptr; int64_t covered_by_meta_table_cnt = 0; left_border = 0; - right_border = merge_tables.count(); + right_border = merge_tables.get_count(); - if (tablet_id.is_special_merge_tablet()) { - } else if (merge_tables.count() < 2 || nullptr == meta_table) { + ObTabletMemberWrapper table_store_wrapper; + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (FALSE_IT(meta_table = table_store_wrapper.get_member()->get_meta_major_sstable())) { + } else if (tablet_id.is_special_merge_tablet()) { + } else if (merge_tables.get_count() < 2 || nullptr == meta_table) { // do nothing } else { // no need meta merge, but exist meta_sstable - for (int64_t i = 0; OB_SUCC(ret) && i < merge_tables.count(); ++i) { - if (OB_ISNULL(merge_tables.at(i))) { + for (int64_t i = 0; OB_SUCC(ret) && i < merge_tables.get_count(); ++i) { + if (OB_ISNULL(merge_tables.get_table(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null table", K(ret), K(i), K(merge_tables)); - } else if (merge_tables.at(i)->get_upper_trans_version() > meta_table->get_snapshot_version()) { + } else if (merge_tables.get_table(i)->get_upper_trans_version() > meta_table->get_snapshot_version()) { break; } else { ++covered_by_meta_table_cnt; @@ -562,7 +608,7 @@ int ObPartitionMergePolicy::refine_minor_merge_tables( } if (OB_FAIL(ret)) { - } else if (covered_by_meta_table_cnt * 2 >= merge_tables.count()) { + } else if (covered_by_meta_table_cnt * 2 >= merge_tables.get_count()) { right_border = covered_by_meta_table_cnt; } else { left_border = covered_by_meta_table_cnt; @@ -602,22 +648,24 @@ int ObPartitionMergePolicy::deal_hist_minor_merge( int64_t &max_snapshot_version) { int ret = OB_SUCCESS; - const ObTabletTableStore &table_store = tablet.get_table_store(); const int64_t hist_threshold = cal_hist_minor_merge_threshold(); ObITable *first_major_table = nullptr; max_snapshot_version = 0; + ObTabletMemberWrapper table_store_wrapper; - if (!table_store.is_valid()) { + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_UNLIKELY(!table_store_wrapper.get_member()->is_valid())) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("get unexpected invalid table store", K(ret), K(table_store)); - } else if (table_store.get_minor_sstables().count_ < hist_threshold) { + LOG_ERROR("get unexpected invalid table store", K(ret), K(table_store_wrapper)); + } else if (table_store_wrapper.get_member()->get_minor_sstables().count() < hist_threshold) { ret = OB_NO_NEED_MERGE; - } else if (OB_ISNULL(first_major_table = table_store.get_major_sstables().get_boundary_table(false))) { + } else if (OB_ISNULL(first_major_table = table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(false))) { // index table during building, need compat with continuous multi version if (0 == (max_snapshot_version = MTL(ObTenantFreezeInfoMgr*)->get_latest_frozen_version())) { // no freeze info found, wait normal mini minor to free sstable ret = OB_NO_NEED_MERGE; - LOG_WARN("No freeze range to do hist minor merge for buiding index", K(ret), K(table_store)); + LOG_WARN("No freeze range to do hist minor merge for buiding index", K(ret), K(table_store_wrapper)); } } else { ObTenantFreezeInfoMgr::NeighbourFreezeInfo freeze_info; @@ -637,16 +685,18 @@ int ObPartitionMergePolicy::deal_hist_minor_merge( } else { int64_t table_cnt = 0; int64_t min_minor_version = 0; - int64_t max_minor_version = 0; - if (OB_FAIL(get_boundary_snapshot_version(tablet, min_minor_version, max_minor_version))) { + int64_t unused_max_minor_version = 0; + if (OB_FAIL(get_boundary_snapshot_version( + tablet, min_minor_version, unused_max_minor_version, + true /*check_table_cnt*/, true /*is_multi_version_merge*/))) { LOG_WARN("fail to calculate boundary version", K(ret)); } else { ObSSTable *table = nullptr; - const ObSSTableArray &minor_tables = table_store.get_minor_sstables(); - for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.count_; ++i) { + const ObSSTableArray &minor_tables = table_store_wrapper.get_member()->get_minor_sstables(); + for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.count(); ++i) { if (OB_ISNULL(table = static_cast(minor_tables[i]))) { ret = OB_ERR_SYS; - LOG_ERROR("table must not null", K(ret), K(i), K(table_store)); + LOG_ERROR("table must not null", K(ret), K(i), K(table_store_wrapper)); } else if (table->get_upper_trans_version() <= min_minor_version) { table_cnt++; } else { @@ -704,16 +754,6 @@ int ObPartitionMergePolicy::diagnose_table_count_unsafe( int tmp_ret = OB_SUCCESS; const int64_t buf_len = ObScheduleSuspectInfoMgr::EXTRA_INFO_LEN; char tmp_str[buf_len] = "\0"; - const ObStorageSchema &storage_schema = tablet.get_storage_schema(); - const ObTabletTableStore &table_store = tablet.get_table_store(); - const ObSSTableArray &major_tables = table_store.get_major_sstables(); - const ObSSTableArray &minor_tables = table_store.get_minor_sstables(); - - // add sstable info - const int64_t major_table_count = major_tables.count_; - const int64_t minor_table_count = minor_tables.count_; - ADD_COMPACTION_INFO_PARAM(tmp_str, buf_len, K(major_table_count), K(minor_table_count)); - if (OB_TMP_FAIL(ObCompactionDiagnoseMgr::check_system_compaction_config(tmp_str, buf_len))) { LOG_WARN("failed to check system compaction config", K(tmp_ret), K(tmp_str)); } @@ -723,33 +763,48 @@ int ObPartitionMergePolicy::diagnose_table_count_unsafe( const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; int64_t min_reserved_snapshot = 0; int64_t min_merged_snapshot = INT64_MAX; + int64_t first_minor_start_scn = 0; ObString snapshot_from_str; - const ObSSTable *major_sstable = static_cast(major_tables.get_boundary_table(false/*last*/)); - if (OB_ISNULL(major_sstable)) { - const ObSSTable *minor_sstable = static_cast(minor_tables.get_boundary_table(false/*last*/)); - ADD_COMPACTION_INFO_PARAM(tmp_str, buf_len, "no major sstable. first_minor_start_scn = ", minor_sstable->get_start_scn()); - } else if (FALSE_IT(min_merged_snapshot = major_sstable->get_snapshot_version())) { - } else if (OB_FAIL(MTL_CALL_FREEZE_INFO_MGR(diagnose_min_reserved_snapshot, - tablet_id, - min_merged_snapshot, - min_reserved_snapshot, - snapshot_from_str))) { - LOG_WARN("failed to get min reserved snapshot", K(ret), K(tablet_id)); - } else if (snapshot_from_str.length() > 0) { - ADD_COMPACTION_INFO_PARAM(tmp_str, buf_len, "snapstho_type", snapshot_from_str, K(min_reserved_snapshot)); + ObTabletMemberWrapper table_store_wrapper; + + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else { + const ObSSTableArray &major_tables = table_store_wrapper.get_member()->get_major_sstables(); + const ObSSTableArray &minor_tables = table_store_wrapper.get_member()->get_minor_sstables(); + // add sstable info + const int64_t major_table_count = major_tables.count(); + const int64_t minor_table_count = minor_tables.count(); + ADD_COMPACTION_INFO_PARAM(tmp_str, buf_len, K(major_table_count), K(minor_table_count)); + const ObSSTable *major_sstable = static_cast(major_tables.get_boundary_table(false/*last*/)); + if (OB_ISNULL(major_sstable)) { + const ObSSTable *minor_sstable = static_cast(minor_tables.get_boundary_table(false/*last*/)); + first_minor_start_scn = minor_sstable->get_start_scn().get_val_for_tx(); + } else if (FALSE_IT(min_merged_snapshot = major_sstable->get_snapshot_version())) { + } else if (OB_FAIL(MTL_CALL_FREEZE_INFO_MGR(diagnose_min_reserved_snapshot, + tablet_id, + min_merged_snapshot, + min_reserved_snapshot, + snapshot_from_str))) { + LOG_WARN("failed to get min reserved snapshot", K(ret), K(tablet_id)); + } else if (snapshot_from_str.length() > 0) { + ADD_COMPACTION_INFO_PARAM(tmp_str, buf_len, "snapstho_type", snapshot_from_str, K(min_reserved_snapshot)); + } + + // check have minor merge DAG + if (OB_TMP_FAIL(diagnose_minor_dag(MINOR_MERGE, ls_id, tablet_id, tmp_str, buf_len))) { + LOG_WARN("failed to diagnose minor dag", K(tmp_ret), K(ls_id), K(tablet_id), K(tmp_str)); + } + if (OB_TMP_FAIL(diagnose_minor_dag(HISTORY_MINOR_MERGE, ls_id, tablet_id, tmp_str, buf_len))) { + LOG_WARN("failed to diagnose history minor dag", K(tmp_ret), K(ls_id), K(tablet_id), K(tmp_str)); + } + + if (OB_TMP_FAIL(ADD_SUSPECT_INFO(MINI_MERGE, ls_id, tablet_id, ObSuspectInfoType::SUSPECT_SSTABLE_COUNT_NOT_SAFE, + major_table_count, minor_table_count, first_minor_start_scn, "extra_info", tmp_str))) { + LOG_WARN("failed to add suspect info", K(tmp_ret)); + } } - // check have minor merge DAG - if (OB_TMP_FAIL(diagnose_minor_dag(MINOR_MERGE, ls_id, tablet_id, tmp_str, buf_len))) { - LOG_WARN("failed to diagnose minor dag", K(tmp_ret), K(ls_id), K(tablet_id), K(tmp_str)); - } - if (OB_TMP_FAIL(diagnose_minor_dag(HISTORY_MINOR_MERGE, ls_id, tablet_id, tmp_str, buf_len))) { - LOG_WARN("failed to diagnose history minor dag", K(tmp_ret), K(ls_id), K(tablet_id), K(tmp_str)); - } - - // add suspect info - ADD_SUSPECT_INFO(merge_type, ls_id, tablet_id, - "sstable count is not safe", "extra_info", tmp_str); return ret; } @@ -759,27 +814,30 @@ int ObPartitionMergePolicy::refine_mini_merge_result( { int ret = OB_SUCCESS; ObITable *last_table = nullptr; - const ObTabletTableStore &table_store = tablet.get_table_store(); + ObTabletMemberWrapper table_store_wrapper; - if (OB_UNLIKELY(!table_store.is_valid())) { + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_UNLIKELY(!table_store_wrapper.get_member()->is_valid())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("Table store not valid", K(ret), K(table_store)); - } else if (OB_ISNULL(last_table = table_store.get_minor_sstables().get_boundary_table(true/*last*/))) { + LOG_WARN("Table store not valid", K(ret), K(table_store_wrapper)); + } else if (OB_ISNULL(last_table = + table_store_wrapper.get_member()->get_minor_sstables().get_boundary_table(true/*last*/))) { // no minor sstable, skip to cut memtable's boundary } else if (result.scn_range_.start_scn_ > last_table->get_end_scn()) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("Unexpected uncontinuous scn_range in mini merge", - K(ret), K(result), KPC(last_table), K(table_store), K(tablet)); + K(ret), K(result), KPC(last_table), K(table_store_wrapper), K(tablet)); } else if (result.scn_range_.start_scn_ < last_table->get_end_scn() && !tablet.get_tablet_meta().tablet_id_.is_special_merge_tablet()) { // fix start_scn to make scn_range continuous in migrate phase for issue 42832934 if (result.scn_range_.end_scn_ <= last_table->get_end_scn()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("No need mini merge memtable which is covered by existing sstable", - K(ret), K(result), KPC(last_table), K(table_store), K(tablet)); + K(ret), K(result), KPC(last_table), K(table_store_wrapper), K(tablet)); } else { result.scn_range_.start_scn_ = last_table->get_end_scn(); - FLOG_INFO("Fix mini merge result scn range", K(ret), K(result), KPC(last_table), K(table_store), K(tablet)); + FLOG_INFO("Fix mini merge result scn range", K(ret), K(result), KPC(last_table), K(table_store_wrapper), K(tablet)); } } return ret; @@ -801,31 +859,37 @@ int ObPartitionMergePolicy::refine_minor_merge_result( } else if (0 == minor_compact_trigger || result.handle_.get_count() >= OB_UNSAFE_TABLE_CNT) { // no refine } else { - ObSEArray mini_tables; + ObTablesHandleArray mini_tables; ObITable *table = NULL; ObSSTable *sstable = NULL; int64_t large_sstable_cnt = 0; int64_t large_sstable_row_cnt = 0; int64_t mini_sstable_row_cnt = 0; for (int64_t i = 0; OB_SUCC(ret) && i < result.handle_.get_count(); ++i) { - if (OB_ISNULL(table = result.handle_.get_table(i)) || !table->is_minor_sstable()) { + ObSSTableMetaHandle sstable_meta_hdl; + ObTableHandleV2 tmp_table_handle; + if (OB_FAIL(result.handle_.get_table(i, tmp_table_handle))) { + LOG_WARN("failed to get table from handles array", K(ret), K(i)); + } else if (OB_ISNULL(table = tmp_table_handle.get_table()) || !table->is_minor_sstable()) { ret = OB_ERR_SYS; LOG_ERROR("get unexpected table", KP(table), K(ret)); } else if (FALSE_IT(sstable = reinterpret_cast(table))) { + } else if (OB_FAIL(sstable->get_meta(sstable_meta_hdl))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); } else { - if (sstable->get_meta().get_basic_meta().row_count_ > OB_LARGE_MINOR_SSTABLE_ROW_COUNT) { // large sstable + if (sstable_meta_hdl.get_sstable_meta().get_basic_meta().row_count_ > OB_LARGE_MINOR_SSTABLE_ROW_COUNT) { // large sstable ++large_sstable_cnt; - large_sstable_row_cnt += sstable->get_meta().get_basic_meta().row_count_; - if (mini_tables.count() > minor_compact_trigger) { + large_sstable_row_cnt += sstable_meta_hdl.get_sstable_meta().get_basic_meta().row_count_; + if (mini_tables.get_count() > minor_compact_trigger) { break; } else { mini_tables.reset(); continue; } } else { - mini_sstable_row_cnt += sstable->get_meta().get_basic_meta().row_count_; + mini_sstable_row_cnt += sstable_meta_hdl.get_sstable_meta().get_basic_meta().row_count_; } - if (OB_FAIL(mini_tables.push_back(table))) { + if (OB_FAIL(mini_tables.add_table(tmp_table_handle))) { LOG_WARN("Failed to push mini minor table into array", K(ret)); } } @@ -840,24 +904,27 @@ int ObPartitionMergePolicy::refine_minor_merge_result( } if (OB_FAIL(ret)) { } else if (large_sstable_cnt > 1 - || mini_tables.count() <= minor_compact_trigger + || mini_tables.get_count() <= minor_compact_trigger || mini_sstable_row_cnt > (large_sstable_row_cnt * size_amplification_factor / 100)) { // no refine, use current result to compaction - } else if (mini_tables.count() != result.handle_.get_count()) { + } else if (mini_tables.get_count() != result.handle_.get_count()) { // reset the merge result, mini sstable merge into a new mini sstable result.reset_handle_and_range(); - for (int64_t i = 0; OB_SUCC(ret) && i < mini_tables.count(); i++) { - ObITable *table = mini_tables.at(i); - if (OB_UNLIKELY(0 != i && table->get_start_scn() != result.scn_range_.end_scn_)) { + for (int64_t i = 0; OB_SUCC(ret) && i < mini_tables.get_count(); i++) { + ObTableHandleV2 tmp_table_handle; + if (OB_FAIL(result.handle_.get_table(i, tmp_table_handle))) { + LOG_WARN("failed to get table from handles array", K(ret), K(i)); + } else if (OB_UNLIKELY(0 != i + && tmp_table_handle.get_table()->get_start_scn() != result.scn_range_.end_scn_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexepcted table array", K(ret), K(i), KPC(table), K(mini_tables)); - } else if (OB_FAIL(result.handle_.add_table(table))) { - LOG_WARN("Failed to add table to minor merge result", KPC(table), K(ret)); + LOG_WARN("unexepcted table array", K(ret), K(i), K(tmp_table_handle), K(mini_tables)); + } else if (OB_FAIL(result.handle_.add_table(tmp_table_handle))) { + LOG_WARN("Failed to add table to minor merge result", K(tmp_table_handle), K(ret)); } else { if (1 == result.handle_.get_count()) { - result.scn_range_.start_scn_ = table->get_start_scn(); + result.scn_range_.start_scn_ = tmp_table_handle.get_table()->get_start_scn(); } - result.scn_range_.end_scn_ = table->get_end_scn(); + result.scn_range_.end_scn_ = tmp_table_handle.get_table()->get_end_scn(); } } if (OB_SUCC(ret)) { @@ -881,10 +948,15 @@ int ObPartitionMergePolicy::check_need_medium_merge( need_merge = false; can_merge = false; const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; - ObTabletTableStore &table_store = tablet.get_table_store(); - ObITable *last_major = table_store.get_major_sstables().get_boundary_table(true/*last*/); - const bool is_tablet_data_status_complete = tablet.get_tablet_meta().ha_status_.is_data_status_complete(); - if (nullptr == last_major) { + ObITable *last_major = nullptr; + const bool is_tablet_data_status_complete = tablet.is_data_complete(); + ObTabletMemberWrapper table_store_wrapper; + + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (FALSE_IT(last_major = + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/))) { + } else if (nullptr == last_major) { // no major, no medium } else { need_merge = last_major->get_snapshot_version() < medium_snapshot; @@ -921,10 +993,16 @@ int ObPartitionMergePolicy::check_need_medium_merge( if (need_merge && !can_merge && REACH_TENANT_TIME_INTERVAL(60L * 1000L * 1000L)) { LOG_INFO("check_need_medium_merge", K(ret), "ls_id", tablet.get_tablet_meta().ls_id_, K(tablet_id), K(need_merge), K(can_merge), K(medium_snapshot), K(is_tablet_data_status_complete)); - ADD_SUSPECT_INFO(MAJOR_MERGE, tablet.get_tablet_meta().ls_id_, tablet_id, - "need major merge but can't merge now", - K(medium_snapshot), K(is_tablet_data_status_complete), K(need_force_freeze), - "max_serialized_medium_scn", tablet.get_tablet_meta().max_serialized_medium_scn_); + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(ADD_SUSPECT_INFO(MAJOR_MERGE, + tablet.get_tablet_meta().ls_id_, + tablet_id, + ObSuspectInfoType::SUSPECT_CANT_MAJOR_MERGE, + medium_snapshot, static_cast(is_tablet_data_status_complete), + static_cast(need_force_freeze), + tablet.get_tablet_meta().max_serialized_medium_scn_))) { + LOG_WARN("failed to add suspect info", K(tmp_ret)); + } } return ret; } @@ -979,23 +1057,23 @@ int ObPartitionMergePolicy::get_multi_version_start( } -int add_table_with_check(ObGetMergeTablesResult &result, ObITable *table) +int add_table_with_check(ObGetMergeTablesResult &result, ObTableHandleV2 &table_handle) { int ret = OB_SUCCESS; - if (OB_ISNULL(table)) { + if (OB_UNLIKELY(!table_handle.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(table)); + LOG_WARN("invalid argument", K(ret), K(table_handle)); } else if (OB_UNLIKELY(!result.handle_.empty() - && table->get_start_scn() > result.scn_range_.end_scn_)) { + && table_handle.get_table()->get_start_scn() > result.scn_range_.end_scn_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("log ts range is not continues", K(ret), K(result), KPC(table)); - } else if (OB_FAIL(result.handle_.add_table(table))) { - LOG_WARN("failed to add table", K(ret), KPC(table)); + LOG_WARN("log ts range is not continues", K(ret), K(result), K(table_handle)); + } else if (OB_FAIL(result.handle_.add_table(table_handle))) { + LOG_WARN("failed to add table", K(ret), K(table_handle)); } else { if (1 == result.handle_.get_count()) { - result.scn_range_.start_scn_ = table->get_start_scn(); + result.scn_range_.start_scn_ = table_handle.get_table()->get_start_scn(); } - result.scn_range_.end_scn_ = table->get_end_scn(); + result.scn_range_.end_scn_ = table_handle.get_table()->get_end_scn(); } return ret; } @@ -1020,13 +1098,13 @@ int ObPartitionMergePolicy::generate_input_result_array( } else if (OB_FAIL(tmp_result.copy_basic_info(input_result))) { LOG_WARN("failed to copy basic info", K(ret), K(input_result)); } else { - const ObIArray &table_array = input_result.handle_.get_tables(); - ObITable *table = nullptr; - for (int64_t idx = 0; OB_SUCC(ret) && idx < table_array.count(); ++idx) { - if (OB_ISNULL(table = table_array.at(idx))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table is unexpected null", K(ret), K(idx), K(table_array)); - } else if (minor_range_mgr.in_execute_range(table)) { + const ObTablesHandleArray &table_array = input_result.handle_; + ObTableHandleV2 tmp_table_handle; + for (int64_t idx = 0; OB_SUCC(ret) && idx < table_array.get_count(); ++idx) { + tmp_table_handle.reset(); + if (OB_FAIL(table_array.get_table(idx, tmp_table_handle))) { + LOG_WARN("fail to get table handle from table handle array", K(ret), K(idx), K(table_array)); + } else if (minor_range_mgr.in_execute_range(tmp_table_handle.get_table())) { if (tmp_result.handle_.get_count() < 2) { } else if (OB_FAIL(input_result_array.push_back(tmp_result))) { LOG_WARN("failed to add tmp result", K(ret), K(tmp_result)); @@ -1035,8 +1113,8 @@ int ObPartitionMergePolicy::generate_input_result_array( } tmp_result.handle_.reset(); tmp_result.scn_range_.reset(); - } else if (OB_FAIL(add_table_with_check(tmp_result, table))) { - LOG_WARN("failed to add table into result", K(ret), K(tmp_result), KPC(table)); + } else if (OB_FAIL(add_table_with_check(tmp_result, tmp_table_handle))) { + LOG_WARN("failed to add table into result", K(ret), K(tmp_result), K(tmp_table_handle)); } } @@ -1069,20 +1147,20 @@ int ObPartitionMergePolicy::split_parallel_minor_range( } else { const int64_t parallel_dag_cnt = MAX(1, input_table_cnt / OB_MINOR_PARALLEL_SSTABLE_CNT_IN_DAG); const int64_t parallel_table_cnt = input_table_cnt / parallel_dag_cnt; - const ObIArray &table_array = input_result.handle_.get_tables(); - ObITable *table = nullptr; + const ObTablesHandleArray &table_array = input_result.handle_; + ObTableHandleV2 tmp_table_handle; int64_t start = 0; int64_t end = 0; for (int64_t seq = 0; OB_SUCC(ret) && seq < parallel_dag_cnt; ++seq) { start = parallel_table_cnt * seq; - end = (parallel_dag_cnt - 1 == seq) ? table_array.count() : end + parallel_table_cnt; + end = (parallel_dag_cnt - 1 == seq) ? table_array.get_count() : end + parallel_table_cnt; for (int64_t i = start; OB_SUCC(ret) && i < end; ++i) { - if (OB_ISNULL(table = table_array.at(i))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table is unexpected null", K(ret), K(i), K(table_array)); - } else if (OB_FAIL(add_table_with_check(tmp_result, table))) { - LOG_WARN("failed to add table into result", K(ret), K(tmp_result), KPC(table)); + tmp_table_handle.reset(); + if (OB_FAIL(table_array.get_table(i, tmp_table_handle))) { + LOG_WARN("fail to get table handle from tables handel array", K(ret), K(i), K(table_array)); + } else if (OB_FAIL(add_table_with_check(tmp_result, tmp_table_handle))) { + LOG_WARN("failed to add table into result", K(ret), K(tmp_result), K(tmp_table_handle)); } } if (OB_FAIL(ret)) { @@ -1234,13 +1312,14 @@ int ObAdaptiveMergePolicy::get_meta_merge_tables( { int ret = OB_SUCCESS; const ObMergeType merge_type = param.merge_type_; - const ObTabletTableStore &table_store = tablet.get_table_store(); - const ObStorageSchema &storage_schema = tablet.get_storage_schema(); result.reset(); + ObTabletMemberWrapper table_store_wrapper; - if (OB_UNLIKELY(!table_store.is_valid())) { + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_UNLIKELY(!table_store_wrapper.get_member()->is_valid())) { ret = OB_ERR_SYS; - LOG_WARN("table store not valid", K(ret), K(table_store)); + LOG_WARN("table store not valid", K(ret), K(table_store_wrapper)); } else if (OB_UNLIKELY(META_MAJOR_MERGE != merge_type)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(merge_type)); @@ -1250,7 +1329,8 @@ int ObAdaptiveMergePolicy::get_meta_merge_tables( } } else if (OB_FAIL(result.handle_.check_continues(nullptr))) { LOG_WARN("failed to check continues", K(ret), K(result)); - } else if (FALSE_IT(result.schema_version_ = storage_schema.schema_version_)) { + } else if (OB_FAIL(tablet.get_schema_version_from_storage_schema(result.schema_version_))) { + LOG_WARN("failed to ge schema version from storage schema", K(ret)); } else if (FALSE_IT(result.suggest_merge_type_ = META_MAJOR_MERGE)) { } else if (FALSE_IT(result.version_range_.snapshot_version_ = MIN(tablet.get_snapshot_version(), result.version_range_.snapshot_version_))) { @@ -1261,7 +1341,7 @@ int ObAdaptiveMergePolicy::get_meta_merge_tables( } else if (OB_FAIL(result.handle_.get_table(0)->get_frozen_schema_version(result.base_schema_version_))) { LOG_WARN("failed to get frozen schema version", K(ret), K(result)); } else { - FLOG_INFO("succeed to get meta major merge tables", K(result), K(table_store)); + FLOG_INFO("succeed to get meta major merge tables", K(result), K(table_store_wrapper)); } return ret; } @@ -1276,51 +1356,81 @@ int ObAdaptiveMergePolicy::find_meta_major_tables( int64_t base_row_cnt = 0; int64_t inc_row_cnt = 0; int64_t tx_determ_table_cnt = 0; - const ObTabletTableStore &table_store = tablet.get_table_store(); - ObITable *last_major = table_store.get_major_sstables().get_boundary_table(true); - ObITable *last_minor = table_store.get_minor_sstables().get_boundary_table(true); - ObITable *base_table = table_store.get_extend_sstable(ObTabletTableStore::META_MAJOR); - const ObSSTableArray &minor_tables = table_store.get_minor_sstables(); + ObSSTableMetaHandle meta_handle; + ObTabletMemberWrapper table_store_wrapper; - if (!table_store.is_valid()) { + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (!table_store_wrapper.get_member()->is_valid()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("ObTabletTableStore is not valid", K(ret), K(table_store)); - } else if (nullptr == last_minor || nullptr == last_major) { - ret = OB_NO_NEED_MERGE; - LOG_WARN("no minor/major sstable to do meta major merge", K(ret), KPC(last_minor), KPC(last_major)); - } else if (OB_FAIL(ObPartitionMergePolicy::get_boundary_snapshot_version( - tablet, min_snapshot, max_snapshot, false/*check_table_cnt*/))) { - if (OB_NO_NEED_MERGE != ret) { - LOG_WARN("Failed to find meta merge base table", K(ret), KPC(last_major), KPC(last_major), KPC(base_table)); - } - } else if (FALSE_IT(base_table = nullptr == base_table ? last_major : base_table)) { - } else if (base_table->get_snapshot_version() < min_snapshot || max_snapshot != INT64_MAX) { - // max_snapshot == INT64_MAX means there's no next freeze_info - ret = OB_NO_NEED_MERGE; - LOG_DEBUG("no need meta merge when the tablet is doing major merge", K(ret), K(min_snapshot), K(max_snapshot), KPC(base_table)); - } else if (OB_FAIL(add_meta_merge_result(base_table, result, true/*update_snapshot*/))) { - LOG_WARN("failed to add base table to meta merge result", K(ret), KPC(base_table), K(result)); + LOG_WARN("ObTabletTableStore is not valid", K(ret), K(table_store_wrapper)); } else { - ++tx_determ_table_cnt; // inc for base_table - bool found_undeterm_table = false; - base_row_cnt = static_cast(base_table)->get_meta().get_row_count(); - ObITable *table = nullptr; - for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.count(); ++i) { - if (OB_ISNULL(table = minor_tables[i]) || !table->is_multi_version_minor_sstable()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected table", K(ret), K(i), K(table_store)); - } else if (table->get_upper_trans_version() <= base_table->get_snapshot_version()) { - // skip minor sstable which has been merged - continue; - } else if (!found_undeterm_table && table->is_trans_state_deterministic()) { - ++tx_determ_table_cnt; - inc_row_cnt += static_cast(table)->get_meta().get_row_count(); - } else { - found_undeterm_table = true; + ObITable *last_major = table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true); + ObITable *last_minor = table_store_wrapper.get_member()->get_minor_sstables().get_boundary_table(true); + ObITable *base_table = table_store_wrapper.get_member()->get_meta_major_sstable(); + const ObSSTableArray &minor_tables = table_store_wrapper.get_member()->get_minor_sstables(); + if (nullptr == last_minor || nullptr == last_major) { + ret = OB_NO_NEED_MERGE; + LOG_WARN("no minor/major sstable to do meta major merge", K(ret), KPC(last_minor), KPC(last_major)); + } else if (OB_FAIL(ObPartitionMergePolicy::get_boundary_snapshot_version( + tablet, min_snapshot, max_snapshot, + false/*check_table_cnt*/, false/*is_multi_version_merge*/))) { + if (OB_NO_NEED_MERGE != ret) { + LOG_WARN("Failed to find meta merge base table", K(ret), KPC(last_major), KPC(last_major), KPC(base_table)); } + } else if (FALSE_IT(base_table = nullptr == base_table ? last_major : base_table)) { + } else if (OB_ISNULL(base_table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("base table is unexpected null", K(ret), KP(base_table)); + } else if (base_table->get_snapshot_version() < min_snapshot || max_snapshot != INT64_MAX) { + // max_snapshot == INT64_MAX means there's no next freeze_info + ret = OB_NO_NEED_MERGE; + LOG_DEBUG("no need meta merge when the tablet is doing major merge", K(ret), K(min_snapshot), K(max_snapshot), KPC(base_table)); + } else if (OB_FAIL(add_meta_merge_result( + base_table, table_store_wrapper.get_meta_handle(), result, true/*update_snapshot*/))) { + LOG_WARN("failed to add base table to meta merge result", K(ret), KPC(base_table), K(result)); + } else if (OB_FAIL(static_cast(base_table)->get_meta(meta_handle))) { + LOG_WARN("failed to base table meta", K(ret), KPC(base_table)); + } else { + ++tx_determ_table_cnt; // inc for base_table + bool found_undeterm_table = false; + base_row_cnt = meta_handle.get_sstable_meta().get_row_count(); + ObITable *table = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.count(); ++i) { + if (OB_ISNULL(table = minor_tables[i]) || !table->is_multi_version_minor_sstable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected table", K(ret), K(i), K(table_store_wrapper)); + } else if (table->get_upper_trans_version() <= base_table->get_snapshot_version()) { + // skip minor sstable which has been merged + continue; + } else if (!found_undeterm_table && table->is_trans_state_deterministic()) { + ++tx_determ_table_cnt; + ObSSTableMetaHandle inc_handle; + if (OB_FAIL(static_cast(table)->get_meta(inc_handle))) { + LOG_WARN("failed to inc table meta", K(ret), KPC(table)); + } else { + inc_row_cnt += inc_handle.get_sstable_meta().get_row_count(); + } + } else { + found_undeterm_table = true; + } - if (FAILEDx(add_meta_merge_result(table, result, !found_undeterm_table))) { - LOG_WARN("failed to add minor table to meta merge result", K(ret)); + if (FAILEDx(add_meta_merge_result( + table, table_store_wrapper.get_meta_handle(), result, !found_undeterm_table))) { + LOG_WARN("failed to add minor table to meta merge result", K(ret)); + } + } // end of for + if (OB_FAIL(ret)) { + } else if (tx_determ_table_cnt < 2) { + ret = OB_NO_NEED_MERGE; + LOG_INFO("no enough table for meta merge", K(ret), K(result), K(table_store_wrapper)); + } else if (inc_row_cnt < TRANS_STATE_DETERM_ROW_CNT_THRESHOLD + || inc_row_cnt < INC_ROW_COUNT_PERCENTAGE_THRESHOLD * base_row_cnt) { + ret = OB_NO_NEED_MERGE; + LOG_INFO("found sstable could merge is not enough", K(ret), K(inc_row_cnt), K(base_row_cnt)); + } else if (result.version_range_.snapshot_version_ < tablet.get_multi_version_start()) { + ret = OB_NO_NEED_MERGE; + LOG_INFO("chosen snapshot is abandoned", K(ret), K(result), K(tablet.get_multi_version_start())); } } // end of for @@ -1328,7 +1438,7 @@ int ObAdaptiveMergePolicy::find_meta_major_tables( } else if (tx_determ_table_cnt < 2) { ret = OB_NO_NEED_MERGE; if (REACH_TENANT_TIME_INTERVAL(60 * 1000 * 1000/*60s*/)) { - LOG_INFO("no enough table for meta merge", K(ret), K(result), K(table_store)); + LOG_INFO("no enough table for meta merge", K(ret), K(result), K(table_store_wrapper)); } } else if (inc_row_cnt < TRANS_STATE_DETERM_ROW_CNT_THRESHOLD || inc_row_cnt < INC_ROW_COUNT_PERCENTAGE_THRESHOLD * base_row_cnt) { @@ -1396,21 +1506,27 @@ int ObAdaptiveMergePolicy::find_base_table_and_inc_version( int ObAdaptiveMergePolicy::add_meta_merge_result( ObITable *table, + const ObStorageMetaHandle &table_meta_handle, ObGetMergeTablesResult &result, const bool update_snapshot_flag) { int ret = OB_SUCCESS; + ObSSTableMetaHandle meta_handle; if (OB_ISNULL(table)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid argument", K(ret), KPC(table)); - } else if (OB_FAIL(result.handle_.add_table(table))) { + } else if (OB_FAIL(result.handle_.add_sstable(table, table_meta_handle))) { LOG_WARN("failed to add table", K(ret), KPC(table)); } else if (table->is_meta_major_sstable() || table->is_major_sstable()) { - result.version_range_.base_version_ = 0; - result.version_range_.multi_version_start_ = table->get_snapshot_version(); - result.version_range_.snapshot_version_ = table->get_snapshot_version(); - result.create_snapshot_version_ = static_cast(table)->get_meta().get_basic_meta().create_snapshot_version_; + if (OB_FAIL(static_cast(table)->get_meta(meta_handle))) { + LOG_WARN("faile to get sstable meta", K(ret), KPC(table)); + } else { + result.version_range_.base_version_ = 0; + result.version_range_.multi_version_start_ = table->get_snapshot_version(); + result.version_range_.snapshot_version_ = table->get_snapshot_version(); + result.create_snapshot_version_ = meta_handle.get_sstable_meta().get_basic_meta().create_snapshot_version_; + } } else if (update_snapshot_flag) { int64_t max_snapshot = MAX(result.version_range_.snapshot_version_, table->get_max_merged_trans_version()); result.version_range_.multi_version_start_ = max_snapshot; @@ -1470,17 +1586,32 @@ int ObAdaptiveMergePolicy::check_inc_sstable_row_cnt_percentage( int ret = OB_SUCCESS; const ObLSID &ls_id = tablet.get_tablet_meta().ls_id_; const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; - ObSSTable *last_major = static_cast(tablet.get_table_store().get_major_sstables().get_boundary_table(true)); - int64_t base_row_count = nullptr != last_major ? last_major->get_meta().get_basic_meta().row_count_ : 0; + ObSSTable *last_major = nullptr; + int64_t base_row_count = 0; int64_t inc_row_count = 0; - const ObSSTableArray &minor_sstables = tablet.get_table_store().get_minor_sstables(); ObSSTable *sstable = nullptr; - for (int i = 0; OB_SUCC(ret) && i < minor_sstables.count(); ++i) { - if (OB_ISNULL(sstable = static_cast(minor_sstables.get_table(i)))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sstable is null", K(ret), K(i)); - } else { - inc_row_count += sstable->get_meta().get_basic_meta().row_count_; + ObSSTableMetaHandle major_meta_hdl; + ObTabletMemberWrapper table_store_wrapper; + + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (FALSE_IT(last_major = static_cast( + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true)))) { + } else if (nullptr != last_major && OB_FAIL(last_major->get_meta(major_meta_hdl))) { + LOG_WARN("fail to get major meta", K(ret), KPC(last_major)); + } else { + base_row_count = major_meta_hdl.get_sstable_meta().get_row_count(); + const ObSSTableArray &minor_sstables = table_store_wrapper.get_member()->get_minor_sstables(); + for (int i = 0; OB_SUCC(ret) && i < minor_sstables.count(); ++i) { + ObSSTableMetaHandle inc_meta_hdl; + if (OB_ISNULL(sstable = minor_sstables.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sstable is null", K(ret), K(i)); + } else if (OB_FAIL(sstable->get_meta(inc_meta_hdl))) { + LOG_WARN("fail to get sstable meta", K(ret), KPC(sstable)); + } else { + inc_row_count += inc_meta_hdl.get_sstable_meta().get_row_count(); + } } } if ((inc_row_count > INC_ROW_COUNT_THRESHOLD) || diff --git a/src/storage/compaction/ob_partition_merge_policy.h b/src/storage/compaction/ob_partition_merge_policy.h index 443a6756a..abfd4f27f 100644 --- a/src/storage/compaction/ob_partition_merge_policy.h +++ b/src/storage/compaction/ob_partition_merge_policy.h @@ -30,6 +30,7 @@ class ObTablesHandleArray; class ObStorageSchema; struct ObTabletStatAnalyzer; struct ObTableHandleV2; +struct ObStorageMetaHandle; class ObLS; class ObTableStoreIterator; } @@ -87,7 +88,8 @@ public: const ObTablet &tablet, int64_t &min_snapshot, int64_t &max_snapshot, - const bool check_table_cnt = true); + const bool check_table_cnt, + const bool is_multi_version_merge); static int diagnose_table_count_unsafe( const storage::ObMergeType merge_type, @@ -118,7 +120,7 @@ private: static int refine_minor_merge_tables( const ObTablet &tablet, - const common::ObIArray &merge_tables, + const ObTablesHandleArray &merge_tables, int64_t &left_border, int64_t &right_border); @@ -239,6 +241,7 @@ private: storage::ObITable *&meta_base_table, int64_t &merge_inc_version); static int add_meta_merge_result(storage::ObITable *table, + const storage::ObStorageMetaHandle &table_meta_handle, storage::ObGetMergeTablesResult &result, const bool update_snapshot_flag); private: diff --git a/src/storage/compaction/ob_partition_merge_progress.cpp b/src/storage/compaction/ob_partition_merge_progress.cpp index fbc74ab61..da2c7579b 100644 --- a/src/storage/compaction/ob_partition_merge_progress.cpp +++ b/src/storage/compaction/ob_partition_merge_progress.cpp @@ -32,7 +32,6 @@ namespace compaction ObPartitionMergeProgress::ObPartitionMergeProgress(common::ObIAllocator &allocator) : allocator_(allocator), - read_info_(nullptr), merge_dag_(nullptr), scanned_row_cnt_arr_(nullptr), output_block_cnt_arr_(nullptr), @@ -91,7 +90,7 @@ int64_t ObPartitionMergeProgress::to_string(char *buf, const int64_t buf_len) co return pos; } -int ObPartitionMergeProgress::init(ObTabletMergeCtx *ctx, const ObTableReadInfo &read_info) +int ObPartitionMergeProgress::init(ObTabletMergeCtx *ctx) { int ret = OB_SUCCESS; int64_t *buf = NULL; @@ -118,7 +117,6 @@ int ObPartitionMergeProgress::init(ObTabletMergeCtx *ctx, const ObTableReadInfo concurrent_cnt_ = concurrent_cnt; merge_dag_ = merge_dag; - read_info_ = &read_info; if (OB_FAIL(estimate(ctx))) { LOG_WARN("failed to estimate unit count", K(ret), K(ctx)); @@ -136,9 +134,11 @@ int ObPartitionMergeProgress::estimate(ObTabletMergeCtx *ctx) ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid arguments", K(ret), K(ctx)); } else { - const ObIArray &tables = ctx->tables_handle_.get_tables(); + ObSEArray tables; int64_t old_major_data_size = 0; - if (OB_UNLIKELY(0 == tables.count() || NULL == tables.at(0))) { + if (OB_FAIL(ctx->tables_handle_.get_tables(tables))) { + LOG_WARN("failed to get tables", K(ret), K(tables)); + } else if (OB_UNLIKELY(0 == tables.count() || NULL == tables.at(0))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected tables", K(ret), K(tables)); } else if (is_mini_merge(ctx->param_.merge_type_)) { // only mini merge use estimate row interface @@ -175,24 +175,24 @@ int ObPartitionMergeProgress::estimate(ObTabletMergeCtx *ctx) } } else { int64_t total_macro_block_cnt = 0; - ObSSTable *table = nullptr; + const ObITable *table = nullptr; for (int64_t i = 0; OB_SUCC(ret) && i < tables.count(); ++i) { - if (OB_UNLIKELY(nullptr == tables.at(i) || !tables.at(i)->is_sstable())) { + ObSSTableMetaHandle sst_meta_hdl; + if (OB_ISNULL(table = tables.at(i)) || OB_UNLIKELY(!tables.at(i)->is_sstable())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected table", K(ret), K(i), KPC(tables.at(i))); + LOG_WARN("get unexpected null table", K(ret), K(i), KPC(table), K(tables)); + } else if (static_cast(table)->is_empty()) { + LOG_DEBUG("table is empty, skip it", K(i), KPC(static_cast(table))); + continue; + } else if (OB_FAIL(static_cast(table)->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); } else { - table = static_cast(tables.at(i)); - const ObSSTableBasicMeta &meta = table->get_meta().get_basic_meta(); - if (meta.get_total_macro_block_count() <= 0) { - LOG_DEBUG("table is empty, skip it", K(i), KPC(static_cast(table))); - continue; - } else { - total_macro_block_cnt += meta.get_total_macro_block_count() - meta.get_total_use_old_macro_block_count(); - estimate_row_cnt_ += meta.row_count_; - estimate_occupy_size_ += meta.occupy_size_; - if (table->is_major_sstable()) { - old_major_data_size = meta.occupy_size_; - } + total_macro_block_cnt += (sst_meta_hdl.get_sstable_meta().get_total_macro_block_count() + - sst_meta_hdl.get_sstable_meta().get_total_use_old_macro_block_count()); + estimate_row_cnt_ += sst_meta_hdl.get_sstable_meta().get_row_count(); + estimate_occupy_size_ += sst_meta_hdl.get_sstable_meta().get_occupy_size(); + if (table->is_major_sstable()) { + old_major_data_size = sst_meta_hdl.get_sstable_meta().get_occupy_size(); } } } diff --git a/src/storage/compaction/ob_partition_merge_progress.h b/src/storage/compaction/ob_partition_merge_progress.h old mode 100644 new mode 100755 index 8fac2f603..152d3d8fe --- a/src/storage/compaction/ob_partition_merge_progress.h +++ b/src/storage/compaction/ob_partition_merge_progress.h @@ -36,7 +36,7 @@ public: virtual ~ObPartitionMergeProgress(); void reset(); OB_INLINE bool is_inited() const { return is_inited_; } - int init(ObTabletMergeCtx *ctx, const storage::ObTableReadInfo &read_info); + int init(ObTabletMergeCtx *ctx); virtual int update_merge_progress(const int64_t idx, const int64_t scanned_row_count, const int64_t output_block_cnt); virtual int finish_merge_progress(const int64_t output_cnt); int update_merge_info(storage::ObSSTableMergeInfo &merge_info); @@ -59,7 +59,6 @@ protected: protected: common::ObIAllocator &allocator_; - const storage::ObTableReadInfo *read_info_; ObTabletMergeDag *merge_dag_; int64_t *scanned_row_cnt_arr_; int64_t *output_block_cnt_arr_; diff --git a/src/storage/compaction/ob_partition_merger.cpp b/src/storage/compaction/ob_partition_merger.cpp index 79f80b035..0a9fc1403 100644 --- a/src/storage/compaction/ob_partition_merger.cpp +++ b/src/storage/compaction/ob_partition_merger.cpp @@ -124,7 +124,7 @@ int ObPartitionMerger::open_macro_writer(ObMergeParameter &merge_param) } else if (OB_UNLIKELY(!merge_param.is_valid())) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid merge parameter", K(ret), K(merge_param)); - } else if (OB_ISNULL(table = merge_ctx_->tables_handle_.get_tables().at(0))) { + } else if (OB_ISNULL(table = merge_ctx_->tables_handle_.get_table(0))) { ret = OB_ERR_SYS; STORAGE_LOG(WARN, "sstable is null", K(ret)); } else if (!table->is_sstable() && is_major_merge_type(merge_ctx_->param_.merge_type_)) { @@ -397,7 +397,7 @@ int ObPartitionMerger::get_macro_block_count_to_rewrite(const ObMergeParameter & check_macro_need_merge_ = true; if (merge_ctx_->is_full_merge_ || merge_ctx_->tables_handle_.get_count() == 0) { // minor merge and full merge no need to calculate rewrite block cnt - } else if (!merge_ctx_->tables_handle_.get_tables().at(0)->is_sstable()) { + } else if (OB_UNLIKELY(!merge_ctx_->tables_handle_.get_table(0)->is_sstable())) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(ERROR, "Unexpected first table for major merge", K(ret), K(merge_ctx_->tables_handle_)); } else { @@ -407,7 +407,7 @@ int ObPartitionMerger::get_macro_block_count_to_rewrite(const ObMergeParameter & const int64_t progressive_merge_num = merge_ctx_->progressive_merge_num_; const bool need_calc_progressive_merge = is_major_merge_type(merge_param.merge_type_) && merge_ctx_->progressive_merge_step_ < progressive_merge_num; const bool need_check_macro_merge = !is_major_merge_type(merge_param.merge_type_) || data_store_desc_.major_working_cluster_version_ >= DATA_VERSION_4_1_0_0; - if (OB_ISNULL(first_sstable = static_cast(merge_ctx_->tables_handle_.get_tables().at(0)))) { + if (OB_ISNULL(first_sstable = static_cast(merge_ctx_->tables_handle_.get_table(0)))) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Unexpected null first sstable", K(ret), K(merge_ctx_->tables_handle_)); } else if (need_calc_progressive_merge || need_check_macro_merge) { @@ -416,7 +416,7 @@ int ObPartitionMerger::get_macro_block_count_to_rewrite(const ObMergeParameter & if (OB_FAIL(first_sstable->scan_secondary_meta( allocator_, merge_param.merge_range_, - merge_ctx_->tablet_handle_.get_obj()->get_index_read_info(), + merge_ctx_->tablet_handle_.get_obj()->get_rowkey_read_info(), blocksstable::DATA_BLOCK_META, sec_meta_iter))) { LOG_WARN("Fail to scan secondary meta", K(ret), K(merge_param.merge_range_)); @@ -781,7 +781,7 @@ int ObPartitionMajorMerger::rewrite_macro_block(MERGE_ITER_ARRAY &minimum_iters) } else { STORAGE_LOG(DEBUG, "Rewrite macro block", KPC(iter)); curr_macro_id = curr_macro->macro_block_id_; - // TODO maybe we need use macro_block_ctx to decide wheather the result row came from the same macro block + // TODO maybe we need use macro_block_ctx to decide whether the result row came from the same macro block while (OB_SUCC(ret) && !iter->is_iter_end() && iter->is_macro_block_opened()) { if (OB_FAIL(merge_same_rowkey_iters(minimum_iters))) { STORAGE_LOG(WARN, "failed to merge_same_rowkey_iters", K(ret), K(minimum_iters)); @@ -1684,8 +1684,11 @@ int ObPartitionMergeDumper::judge_disk_free_space(const char *dir_name, ObITable if (OB_FAIL(FileDirectoryUtils::get_disk_space(dir_name, total_space, free_space))) { STORAGE_LOG(WARN, "Failed to get disk space ", K(ret), K(dir_name)); } else if (table->is_sstable()) { - if (free_space - - static_cast(table)->get_meta().get_basic_meta().get_total_macro_block_count() * + ObSSTableMetaHandle sst_meta_hdl; + if (OB_FAIL(static_cast(table)->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); + } else if (free_space + - sst_meta_hdl.get_sstable_meta().get_total_macro_block_count() * OB_DEFAULT_MACRO_BLOCK_SIZE < ObPartitionMergeDumper::DUMP_TABLE_DISK_FREE_PERCENTAGE * total_space) { ret = OB_SERVER_OUTOF_DISK_SPACE; @@ -1744,13 +1747,12 @@ void ObPartitionMergeDumper::print_error_info(const int err_no, } } // dump all sstables in this merge - ObIArray &tables = ctx.tables_handle_.get_tables(); char file_name[OB_MAX_FILE_NAME_LENGTH]; lib::ObMutexGuard guard(ObPartitionMergeDumper::lock); - for (int idx = 0; OB_SUCC(ret) && idx < tables.count(); ++idx) { - ObITable *table = tables.at(idx); + for (int idx = 0; OB_SUCC(ret) && idx < ctx.tables_handle_.get_count(); ++idx) { + ObITable *table = ctx.tables_handle_.get_table(idx); if (OB_ISNULL(table)) { - STORAGE_LOG(WARN, "The store is NULL", K(idx), K(tables)); + STORAGE_LOG(WARN, "The store is NULL", K(idx), K(ctx.tables_handle_)); } else if (OB_FAIL(compaction::ObPartitionMergeDumper::judge_disk_free_space(dump_table_dir, table))) { if (OB_SERVER_OUTOF_DISK_SPACE != ret) { diff --git a/src/storage/compaction/ob_partition_parallel_merge_ctx.cpp b/src/storage/compaction/ob_partition_parallel_merge_ctx.cpp index a7bedfe02..56a9f75a4 100644 --- a/src/storage/compaction/ob_partition_parallel_merge_ctx.cpp +++ b/src/storage/compaction/ob_partition_parallel_merge_ctx.cpp @@ -81,9 +81,12 @@ int ObParallelMergeCtx::init(compaction::ObTabletMergeCtx &merge_ctx) int64_t tablet_size = merge_ctx.get_schema()->get_tablet_size(); bool enable_parallel_minor_merge = false; { - omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID())); - if (tenant_config.is_valid()) { - enable_parallel_minor_merge = tenant_config->_enable_parallel_minor_merge; + // TODO(yangyi.yyy): backfill tx merge do not allow parallel minor merge + if (!is_backfill_tx_merge(merge_ctx.param_.merge_type_)) { + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID())); + if (tenant_config.is_valid()) { + enable_parallel_minor_merge = tenant_config->_enable_parallel_minor_merge; + } } } if (enable_parallel_minor_merge && tablet_size > 0 && is_mini_merge(merge_ctx.param_.merge_type_)) { @@ -121,23 +124,29 @@ int ObParallelMergeCtx::init(const compaction::ObMediumCompactionInfo &medium_in ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid argument to init parallel merge", K(ret), K(medium_info)); } else { - const compaction::ObParallelMergeInfo ¶l_info = medium_info.parallel_merge_info_; - range_array_.reset(); - ObDatumRange schema_rowkey_range; ObDatumRange multi_version_range; - schema_rowkey_range.start_key_.set_min_rowkey(); - schema_rowkey_range.end_key_.set_min_rowkey(); - schema_rowkey_range.set_left_open(); - schema_rowkey_range.set_right_closed(); - for (int i = 0; OB_SUCC(ret) && i < paral_info.list_size_ + 1; ++i) { + const compaction::ObParallelMergeInfo ¶l_info = medium_info.parallel_merge_info_; + if (OB_UNLIKELY(!paral_info.is_valid())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "parallel info is invalid", KR(ret), K(paral_info)); + } else { + range_array_.reset(); + + schema_rowkey_range.start_key_.set_min_rowkey(); + schema_rowkey_range.end_key_.set_min_rowkey(); + schema_rowkey_range.set_left_open(); + schema_rowkey_range.set_right_closed(); + } + + for (int i = 0; OB_SUCC(ret) && i < paral_info.get_size() + 1; ++i) { if (i > 0 && OB_FAIL(schema_rowkey_range.end_key_.deep_copy(schema_rowkey_range.start_key_, allocator_))) { // end_key -> start_key STORAGE_LOG(WARN, "failed to deep copy start key", K(ret), K(i), K(medium_info)); - } else if (i < paral_info.list_size_) { - if (OB_FAIL(schema_rowkey_range.end_key_.from_rowkey(paral_info.parallel_end_key_list_[i].get_rowkey(), allocator_))) { + } else if (i < paral_info.get_size()) { + if (OB_FAIL(paral_info.deep_copy_datum_rowkey(i/*idx*/, allocator_, schema_rowkey_range.end_key_))) { STORAGE_LOG(WARN, "failed to deep copy end key", K(ret), K(i), K(medium_info)); } - } else { // i == paral_info.list_size_ + } else { // i == paral_info.get_size() schema_rowkey_range.end_key_.set_max_rowkey(); } multi_version_range.reset(); @@ -148,7 +157,7 @@ int ObParallelMergeCtx::init(const compaction::ObMediumCompactionInfo &medium_in } } if (OB_SUCC(ret)) { - concurrent_cnt_ = paral_info.list_size_ + 1; + concurrent_cnt_ = paral_info.get_size() + 1; parallel_type_ = PARALLEL_MAJOR; is_inited_ = true; STORAGE_LOG(INFO, "success to init parallel merge ctx", KPC(this)); @@ -217,7 +226,7 @@ int ObParallelMergeCtx::init_parallel_major_merge(compaction::ObTabletMergeCtx & } else { const int64_t tablet_size = merge_ctx.get_schema()->get_tablet_size(); const ObSSTable *first_sstable = static_cast(first_table); - const int64_t macro_block_cnt = first_sstable->get_meta().get_macro_info().get_data_block_ids().count(); + const int64_t macro_block_cnt = first_sstable->get_data_macro_block_count(); if (OB_FAIL(get_concurrent_cnt(tablet_size, macro_block_cnt, concurrent_cnt_))) { STORAGE_LOG(WARN, "failed to get concurrent cnt", K(ret), K(tablet_size), K(concurrent_cnt_), KPC(first_sstable)); @@ -226,7 +235,7 @@ int ObParallelMergeCtx::init_parallel_major_merge(compaction::ObTabletMergeCtx & STORAGE_LOG(WARN, "failed to init serial merge", K(ret), KPC(first_sstable)); } } else if (OB_FAIL(get_major_parallel_ranges( - first_sstable, tablet_size, merge_ctx.tablet_handle_.get_obj()->get_index_read_info()))) { + first_sstable, tablet_size, merge_ctx.tablet_handle_.get_obj()->get_rowkey_read_info()))) { STORAGE_LOG(WARN, "Failed to get concurrent cnt from first sstable", K(ret), K(tablet_size), K_(concurrent_cnt)); } else { @@ -304,7 +313,7 @@ int ObParallelMergeCtx::init_parallel_mini_minor_merge(compaction::ObTabletMerge ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid argument to init parallel mini minor merge", K(ret), K(merge_ctx)); } else { - const ObTableReadInfo &index_read_info = merge_ctx.tablet_handle_.get_obj()->get_index_read_info(); + const ObITableReadInfo &rowkey_read_info = merge_ctx.tablet_handle_.get_obj()->get_rowkey_read_info(); const int64_t tablet_size = merge_ctx.get_schema()->get_tablet_size(); ObRangeSplitInfo range_info; ObSEArray tables; @@ -321,7 +330,7 @@ int ObParallelMergeCtx::init_parallel_mini_minor_merge(compaction::ObTabletMerge STORAGE_LOG(WARN, "Unexpected tables handle for mini minor merge", K(ret), K(merge_ctx.tables_handle_)); } - } else if (OB_FAIL(range_spliter.get_range_split_info(tables, index_read_info, whole_range, range_info))) { + } else if (OB_FAIL(range_spliter.get_range_split_info(tables, rowkey_read_info, whole_range, range_info))) { STORAGE_LOG(WARN, "Failed to init range spliter", K(ret)); } else if (OB_FAIL(calc_mini_minor_parallel_degree(tablet_size, range_info.total_size_, tables.count(), range_info.parallel_target_count_))) { @@ -411,7 +420,7 @@ int ObParallelMergeCtx::get_concurrent_cnt( int ObParallelMergeCtx::get_major_parallel_ranges( const blocksstable::ObSSTable *first_major_sstable, const int64_t tablet_size, - const ObTableReadInfo &index_read_info) + const ObITableReadInfo &rowkey_read_info) { int ret = OB_SUCCESS; int64_t macro_block_cnt = 0; @@ -422,9 +431,10 @@ int ObParallelMergeCtx::get_major_parallel_ranges( ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "concurrent cnt is invalid", K(ret), K_(concurrent_cnt)); } else { - const int64_t macro_block_cnt = first_major_sstable->get_meta().get_macro_info().get_data_block_ids().count(); + const int64_t macro_block_cnt = first_major_sstable->get_data_macro_block_count(); const int64_t macro_block_cnt_per_range = (macro_block_cnt + concurrent_cnt_ - 1) / concurrent_cnt_; + ObSSTableMetaHandle sstable_meta_handle; ObDatumRowkeyHelper rowkey_helper; ObDatumRowkey macro_endkey; ObDatumRowkey multi_version_endkey; @@ -436,11 +446,14 @@ int ObParallelMergeCtx::get_major_parallel_ranges( blocksstable::ObDataMacroBlockMeta blk_meta; blocksstable::ObSSTableSecMetaIterator *meta_iter = nullptr; ObDatumRange query_range; - int64_t schema_rowkey_cnt = first_major_sstable->get_meta().get_schema_rowkey_column_count(); + int64_t schema_rowkey_cnt = 0; query_range.set_whole_range(); if (OB_FAIL(first_major_sstable->scan_secondary_meta(allocator_, query_range, - index_read_info, DATA_BLOCK_META, meta_iter))) { + rowkey_read_info, DATA_BLOCK_META, meta_iter))) { STORAGE_LOG(WARN, "Failed to scan secondary meta", KR(ret), KPC(this)); + } else if (OB_FAIL(first_major_sstable->get_meta(sstable_meta_handle))) { + STORAGE_LOG(WARN, "failed to get sstable meta handle", K(ret)); + } else if (FALSE_IT(schema_rowkey_cnt = sstable_meta_handle.get_sstable_meta().get_schema_rowkey_column_count())) { } else if (OB_FAIL(rowkey_helper.reserve(schema_rowkey_cnt + 1))) { STORAGE_LOG(WARN, "Failed to ", K(ret), K(schema_rowkey_cnt)); } else if (OB_FAIL(multi_version_endkey.assign(rowkey_helper.get_datums(), schema_rowkey_cnt + 1))) { diff --git a/src/storage/compaction/ob_partition_parallel_merge_ctx.h b/src/storage/compaction/ob_partition_parallel_merge_ctx.h index 3a97b536c..5225f1533 100644 --- a/src/storage/compaction/ob_partition_parallel_merge_ctx.h +++ b/src/storage/compaction/ob_partition_parallel_merge_ctx.h @@ -76,7 +76,7 @@ private: int get_major_parallel_ranges( const blocksstable::ObSSTable *first_major_sstable, const int64_t tablet_size, - const ObTableReadInfo &index_read_info); + const ObITableReadInfo &rowkey_read_info); private: ParallelMergeType parallel_type_; common::ObSEArray range_array_; diff --git a/src/storage/compaction/ob_partition_rows_merger.cpp b/src/storage/compaction/ob_partition_rows_merger.cpp index c4a0a2d87..8f3eaeb8f 100644 --- a/src/storage/compaction/ob_partition_rows_merger.cpp +++ b/src/storage/compaction/ob_partition_rows_merger.cpp @@ -591,6 +591,7 @@ int ObPartitionMergeHelper::init_merge_iters(const ObIPartitionMergeFuser &fuser ObITable *table = nullptr; ObSSTable *sstable = nullptr; ObPartitionMergeIter *merge_iter = nullptr; + bool is_small_sstable = false; for (int64_t i = table_cnt - 1; OB_SUCC(ret) && i >= 0; i--) { if (OB_ISNULL(table = merge_param.tables_handle_->get_table(i))) { @@ -599,15 +600,21 @@ int ObPartitionMergeHelper::init_merge_iters(const ObIPartitionMergeFuser &fuser } else if (OB_UNLIKELY(table->is_remote_logical_minor_sstable())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected remote minor sstable", K(ret), KP(sstable)); - } else if (FALSE_IT(sstable = static_cast(table))) { - } else if (table->is_sstable() && - sstable->get_meta().get_basic_meta().get_data_macro_block_count() <= 0) { - // do nothing. don't need to construct iter for empty sstable - FLOG_INFO("table is empty, need not create iter", K(i), KPC(sstable), K(sstable->get_meta())); - continue; - } else if (OB_ISNULL(merge_iter = alloc_merge_iter(merge_param, 0 == i, table->is_sstable() && sstable->is_small_sstable()))) { + } else if (table->is_sstable()) { + sstable = static_cast(table); + if (sstable->get_data_macro_block_count() <= 0) { + // do nothing. don't need to construct iter for empty sstable + FLOG_INFO("table is empty, need not create iter", K(i), KPC(sstable)); + continue; + } else { + is_small_sstable = sstable->is_small_sstable(); + } + } + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(merge_iter = alloc_merge_iter(merge_param, 0 == i, table->is_sstable() + && is_small_sstable))) { ret = OB_ALLOCATE_MEMORY_FAILED; - STORAGE_LOG(WARN, "Failed to alloc memory for merge iter", K(ret)); + STORAGE_LOG(WARN, "Failed to alloc memory for merge iter", K(ret), K(is_small_sstable)); } else if (OB_FAIL(merge_iter->init(merge_param, fuser.get_multi_version_column_ids(), row_store_type, i))) { diff --git a/src/storage/compaction/ob_schedule_dag_func.cpp b/src/storage/compaction/ob_schedule_dag_func.cpp index d2ff49ccb..a01fbbcae 100644 --- a/src/storage/compaction/ob_schedule_dag_func.cpp +++ b/src/storage/compaction/ob_schedule_dag_func.cpp @@ -11,12 +11,14 @@ */ #define USING_LOG_PREFIX STORAGE_COMPACTION -#include "ob_schedule_dag_func.h" +#include "storage/compaction/ob_schedule_dag_func.h" +#include "lib/oblog/ob_log_module.h" #include "share/scheduler/ob_dag_scheduler.h" #include "storage/ddl/ob_ddl_merge_task.h" #include "storage/compaction/ob_tablet_merge_task.h" #include "storage/compaction/ob_tx_table_merge_task.h" -#include "lib/oblog/ob_log_module.h" +#include "storage/multi_data_source/ob_mds_table_merge_dag.h" +#include "storage/multi_data_source/ob_mds_table_merge_dag_param.h" namespace oceanbase { @@ -28,13 +30,12 @@ namespace compaction #define CREATE_DAG(T) \ { \ - T *dag = nullptr; \ - if (OB_FAIL(MTL(ObTenantDagScheduler*)->create_and_add_dag(¶m, dag, is_emergency))) { \ + if (OB_FAIL(MTL(ObTenantDagScheduler*)->create_and_add_dag(¶m, is_emergency))) { \ if (OB_SIZE_OVERFLOW != ret && OB_EAGAIN != ret) { \ LOG_WARN("failed to create merge dag", K(ret), K(param)); \ } \ } else { \ - LOG_DEBUG("success to schedule tablet merge dag", K(ret), K(param), K(*dag)); \ + LOG_DEBUG("success to schedule tablet merge dag", K(ret), K(param)); \ } \ } @@ -71,5 +72,14 @@ int ObScheduleDagFunc::schedule_ddl_table_merge_dag( return ret; } +int ObScheduleDagFunc::schedule_mds_table_merge_dag( + storage::mds::ObMdsTableMergeDagParam ¶m, + const bool is_emergency) +{ + int ret = OB_SUCCESS; + CREATE_DAG(storage::mds::ObMdsTableMergeDag); + return ret; +} + } // namespace compaction } // namespace oceanbase diff --git a/src/storage/compaction/ob_schedule_dag_func.h b/src/storage/compaction/ob_schedule_dag_func.h index 9498f4152..5e730e16d 100644 --- a/src/storage/compaction/ob_schedule_dag_func.h +++ b/src/storage/compaction/ob_schedule_dag_func.h @@ -17,6 +17,10 @@ namespace oceanbase { namespace storage { +namespace mds +{ +class ObMdsTableMergeDagParam; +} struct ObDDLTableMergeDagParam; } @@ -36,6 +40,9 @@ public: static int schedule_ddl_table_merge_dag( storage::ObDDLTableMergeDagParam ¶m, const bool is_emergency = false); + static int schedule_mds_table_merge_dag( + storage::mds::ObMdsTableMergeDagParam ¶m, + const bool is_emergency = false); }; } diff --git a/src/storage/compaction/ob_sstable_merge_info_mgr.cpp b/src/storage/compaction/ob_sstable_merge_info_mgr.cpp old mode 100644 new mode 100755 index 30c987af5..f4701f8b5 --- a/src/storage/compaction/ob_sstable_merge_info_mgr.cpp +++ b/src/storage/compaction/ob_sstable_merge_info_mgr.cpp @@ -14,6 +14,7 @@ #include "ob_sstable_merge_info_mgr.h" #include "lib/utility/ob_print_utils.h" #include "storage/ob_sstable_struct.h" +#include "storage/compaction/ob_compaction_diagnose.h" #include "share/config/ob_server_config.h" #include "observer/omt/ob_multi_tenant.h" #include "observer/ob_server_struct.h" @@ -23,135 +24,13 @@ namespace oceanbase using namespace common; namespace storage { -/** - * ------------------------------------------------------------------ObSSTableMergeInfoIter------------------------------------------------------------- - */ -ObSSTableMergeInfoIterator::ObSSTableMergeInfoIterator() - : all_tenants_(NULL/*allocator*/, ObModIds::OB_TENANT_ID_LIST), - tenant_idx_(0), - cur_tenant_id_(OB_INVALID_TENANT_ID), - major_info_idx_(0), - major_info_cnt_(0), - minor_info_idx_(0), - minor_info_cnt_(0), - is_opened_(false) -{ -} - -ObSSTableMergeInfoIterator::~ObSSTableMergeInfoIterator() -{ -} - -int ObSSTableMergeInfoIterator::open(const int64_t tenant_id) -{ - int ret = OB_SUCCESS; - MAKE_TENANT_SWITCH_SCOPE_GUARD(unused_tenant_guard); - if (is_opened_) { - ret = OB_INIT_TWICE; - STORAGE_LOG(WARN, "The ObSSTableMergeInfoIterator has been opened", K(ret)); - } else if (!::is_valid_tenant_id(tenant_id)) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id)); - } else if (OB_SYS_TENANT_ID != tenant_id) { - all_tenants_.push_back(tenant_id); - } else { - GCTX.omt_->get_tenant_ids(all_tenants_); - } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(next_tenant(unused_tenant_guard))) { - if (OB_ITER_END != ret) { - STORAGE_LOG(WARN, "Fail to init tenant iterator", K(ret), K_(minor_info_idx)); - } - } else { - is_opened_ = true; - major_info_idx_ = 0; - minor_info_idx_ = 0; - } - return ret; -} - -int ObSSTableMergeInfoIterator::next_tenant(share::ObTenantSwitchGuard &tenant_guard) -{ - int ret = OB_SUCCESS; - while (OB_SUCC(ret)) { - if (tenant_idx_ >= all_tenants_.size()) { - ret = OB_ITER_END; - } else if (FALSE_IT(cur_tenant_id_ = all_tenants_[tenant_idx_++])) { - } else if (is_virtual_tenant_id(cur_tenant_id_)) { - // skip virtual tenant - } else if (OB_FAIL(tenant_guard.switch_to(cur_tenant_id_))) { - if (OB_TENANT_NOT_IN_SERVER != ret) { - STORAGE_LOG(WARN, "switch tenant failed", K(ret), K(cur_tenant_id_)); - } else { - ret = OB_SUCCESS; - continue; - } - } else { - major_info_idx_ = 0; - minor_info_idx_ = 0; - major_info_cnt_ = MTL(storage::ObTenantSSTableMergeInfoMgr *)->get_major_info_array_cnt(); - minor_info_cnt_ = MTL(storage::ObTenantSSTableMergeInfoMgr *)->get_minor_info_array_cnt(); - break; - } - } - return ret; -} - -int ObSSTableMergeInfoIterator::get_next_merge_info(ObSSTableMergeInfo &merge_info) -{ - int ret = OB_SUCCESS; - MAKE_TENANT_SWITCH_SCOPE_GUARD(tenant_guard); - - if (!is_opened_) { - ret = OB_NOT_INIT; - STORAGE_LOG(WARN, "The ObSSTableMergeInfoIterator has not been inited", K(ret)); - } else if (OB_FAIL(tenant_guard.switch_to(cur_tenant_id_))) { - STORAGE_LOG(WARN, "switch tenant failed", K(ret), K(cur_tenant_id_)); - } - while (OB_SUCC(ret)) { - if (major_info_idx_ < major_info_cnt_) { - if (OB_FAIL(MTL(ObTenantSSTableMergeInfoMgr *)->get_major_info(major_info_idx_, merge_info))) { - STORAGE_LOG(WARN, "Fail to get merge info", K(ret), K_(major_info_idx)); - } else { - major_info_idx_++; - break; - } - } else if (minor_info_idx_ < minor_info_cnt_) { - if (OB_FAIL(MTL(ObTenantSSTableMergeInfoMgr *)->get_minor_info(minor_info_idx_, merge_info))) { - STORAGE_LOG(WARN, "Fail to get merge info", K(ret), K_(minor_info_idx)); - } else { - minor_info_idx_++; - break; - } - } else if (OB_FAIL(next_tenant(tenant_guard))) { - if (OB_ITER_END != ret) { - STORAGE_LOG(WARN, "Fail to next tenant", K(ret), K_(minor_info_idx)); - } - } - } // end of while - return ret; -} - -void ObSSTableMergeInfoIterator::reset() -{ - all_tenants_.reset(); - tenant_idx_ = 0; - cur_tenant_id_ = OB_INVALID_TENANT_ID; - major_info_idx_ = 0; - major_info_cnt_ = 0; - minor_info_idx_ = 0; - minor_info_cnt_ = 0; - is_opened_ = false; -} - /** * ------------------------------------------------------------------ObTenantSSTableMergeInfoMgr--------------------------------------------------------------- */ ObTenantSSTableMergeInfoMgr::ObTenantSSTableMergeInfoMgr() : is_inited_(false), - allocator_(SET_USE_UNEXPECTED_500(ObModIds::OB_SSTABLE_MERGE_INFO), OB_MALLOC_BIG_BLOCK_SIZE), - major_merge_infos_(allocator_), - minor_merge_infos_(allocator_) + major_info_pool_(), + minor_info_pool_() { } @@ -166,30 +45,55 @@ int ObTenantSSTableMergeInfoMgr::mtl_init(ObTenantSSTableMergeInfoMgr *&sstable_ return sstable_merge_info->init(); } -int ObTenantSSTableMergeInfoMgr::init(const int64_t memory_limit) +int64_t ObTenantSSTableMergeInfoMgr::cal_max() +{ + const uint64_t tenant_id = MTL_ID(); + int64_t max_size = std::min(lib::get_tenant_memory_limit(tenant_id) * MEMORY_PERCENTAGE / 100, + static_cast(POOL_MAX_SIZE)); + return max_size; +} + +int ObTenantSSTableMergeInfoMgr::get_next_info(compaction::ObIDiagnoseInfoMgr::Iterator &major_iter, + compaction::ObIDiagnoseInfoMgr::Iterator &minor_iter, + ObSSTableMergeInfo &info, char *buf, const int64_t buf_len) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(major_iter.get_next(&info, buf, buf_len))) { + if (OB_ITER_END == ret) { + if (OB_FAIL(minor_iter.get_next(&info, buf, buf_len))) { + if (OB_ITER_END != ret) { + STORAGE_LOG(WARN, "failed to get next minor sstable merge info", K(ret)); + } + } + } else { + STORAGE_LOG(WARN, "failed to get next major sstable merge info", K(ret)); + } + } + return ret; +} + +int ObTenantSSTableMergeInfoMgr::init(const int64_t page_size) { int ret = OB_SUCCESS; if (IS_INIT) { ret = OB_INIT_TWICE; - STORAGE_LOG(WARN, "ObSSTableMergeInfo has already been initiated", K(ret)); - } else if (OB_UNLIKELY(memory_limit <= 0)) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "Invalid argument", K(ret), K(memory_limit)); + STORAGE_LOG(WARN, "ObTenantSSTableMergeInfoMgr has already been initiated", K(ret)); } else { - void *buf = NULL; - int64_t max_info_cnt = min(GMEMCONF.get_server_memory_limit(), memory_limit) / (sizeof(ObSSTableMergeInfo)); - if (max_info_cnt < 2) { - max_info_cnt = 2; - } - - const int64_t info_max_cnt = MAX(max_info_cnt / 2, 1); - if (OB_FAIL(major_merge_infos_.init(info_max_cnt))) { - STORAGE_LOG(WARN, "Fail to init major merge infos", K(ret), K(info_max_cnt)); - } else if (OB_FAIL(minor_merge_infos_.init(info_max_cnt))) { - STORAGE_LOG(WARN, "Fail to alloc minor merge infos", K(ret), K(info_max_cnt)); + int64_t max_size = cal_max(); + if (OB_FAIL(major_info_pool_.init(false, + MTL_ID(), + "MajorMerge", + page_size, + max_size * (100 - MINOR_MEMORY_PERCENTAGE) / 100))) { + STORAGE_LOG(WARN, "failed to init major info pool", K(ret)); + } else if (OB_FAIL(minor_info_pool_.init(false, + MTL_ID(), + "MinorMerge", + page_size, + max_size * MINOR_MEMORY_PERCENTAGE / 100))) { + STORAGE_LOG(WARN, "failed to init minor info pool", K(ret)); } else { is_inited_ = true; - STORAGE_LOG(INFO, "Success to init ObTenantSSTableMergeInfoMgr", K(info_max_cnt)); } } @@ -201,60 +105,87 @@ int ObTenantSSTableMergeInfoMgr::init(const int64_t memory_limit) void ObTenantSSTableMergeInfoMgr::destroy() { - major_merge_infos_.destroy(); - minor_merge_infos_.destroy(); - allocator_.reset(); - is_inited_ = false; - STORAGE_LOG(INFO, "ObTenantSSTableMergeInfoMgr is destroyed"); + if (IS_INIT) { + major_info_pool_.destroy(); + minor_info_pool_.destroy(); + is_inited_ =false; + STORAGE_LOG(INFO, "ObTenantSSTableMergeInfoMgr destroy finish"); + } } -int ObTenantSSTableMergeInfoMgr::add_sstable_merge_info(ObSSTableMergeInfo &merge_info) +int ObTenantSSTableMergeInfoMgr::open_iter(compaction::ObIDiagnoseInfoMgr::Iterator &major_iter, + compaction::ObIDiagnoseInfoMgr::Iterator &minor_iter) { int ret = OB_SUCCESS; - if (IS_NOT_INIT) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "ObTenantSSTableMergeInfoMgr is not initialized", K(ret)); - } else if (OB_UNLIKELY(!merge_info.is_valid())) { + } else if (OB_FAIL(major_info_pool_.open_iter(major_iter))) { + STORAGE_LOG(WARN, "failed to open major iter", K(ret)); + } else if (OB_FAIL(minor_info_pool_.open_iter(minor_iter))) { + STORAGE_LOG(WARN, "failed to open minor iter", K(ret)); + } + return ret; +} + +int ObTenantSSTableMergeInfoMgr::set_max(int64_t max_size) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ObTenantSSTableMergeInfoMgr is not init", K(ret)); + } else if (OB_FAIL(major_info_pool_.set_max(max_size * (100 - MINOR_MEMORY_PERCENTAGE) / 100))) { + STORAGE_LOG(WARN, "failed to resize major info pool", K(ret), "max_size", + max_size * (100 - MINOR_MEMORY_PERCENTAGE) / 100); + } else if (OB_FAIL(minor_info_pool_.set_max(max_size * MINOR_MEMORY_PERCENTAGE / 100))) { + STORAGE_LOG(WARN, "failed to resize minor info pool", K(ret), "max_size", + max_size * MINOR_MEMORY_PERCENTAGE / 100); + } + return ret; +} + +int ObTenantSSTableMergeInfoMgr::gc_info() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ObTenantSSTableMergeInfoMgr is not init", K(ret)); + } else if (OB_FAIL(major_info_pool_.gc_info())) { + STORAGE_LOG(WARN, "failed to gc major info pool", K(ret)); + } else if (OB_FAIL(minor_info_pool_.gc_info())) { + STORAGE_LOG(WARN, "failed to gc minor info pool", K(ret)); + } + return ret; +} + +int ObTenantSSTableMergeInfoMgr::size() +{ + int size = 0; + if (IS_INIT) { + size = minor_info_pool_.size() + major_info_pool_.size(); + } + return size; +} + +int ObTenantSSTableMergeInfoMgr::add_sstable_merge_info(ObSSTableMergeInfo &input_info) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ObTenantSSTableMergeInfoMgr is not initialized", K(ret)); + } else if (OB_UNLIKELY(!input_info.is_valid())) { ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "merge info is invalid", K(ret), K(merge_info)); - } else if (merge_info.is_major_merge_type()) { - if (OB_FAIL(major_merge_infos_.add(merge_info))) { - STORAGE_LOG(WARN, "Fail to add into major merge info manager", K(ret), K(merge_info)); + STORAGE_LOG(WARN, "invalid argument", K(ret), K(input_info)); + } else { + compaction::ObIDiagnoseInfoMgr *info_pool = &minor_info_pool_; + if (input_info.is_major_merge_type()) { + info_pool = &major_info_pool_; + } + if (OB_FAIL(info_pool->alloc_and_add(0, &input_info))) { + STORAGE_LOG(WARN, "failed to add sstable merge info", K(ret), K(input_info)); } - } else if (OB_FAIL(minor_merge_infos_.add(merge_info))) { - STORAGE_LOG(WARN, "Fail to add into minor merge info manager", K(ret), K(merge_info)); - } - if (OB_SUCC(ret)) { - LOG_INFO("success to add into merge info manager", K(ret), K(merge_info)); - } - - return ret; -} - -int ObTenantSSTableMergeInfoMgr::get_major_info(const int64_t idx, ObSSTableMergeInfo &merge_info) -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - STORAGE_LOG(WARN, "The ObTenantSSTableMergeInfoMgr has not been inited", K(ret)); - } else if (OB_FAIL(major_merge_infos_.get(idx, merge_info))) { - STORAGE_LOG(WARN, "failed to get info", K(ret), K(idx)); } return ret; } - -int ObTenantSSTableMergeInfoMgr::get_minor_info(const int64_t idx, ObSSTableMergeInfo &merge_info) -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - STORAGE_LOG(WARN, "The ObTenantSSTableMergeInfoMgr has not been inited", K(ret)); - } else if (OB_FAIL(minor_merge_infos_.get(idx, merge_info))) { - STORAGE_LOG(WARN, "failed to get info", K(ret), K(idx)); - } - return ret; -} - }//storage }//oceanbase diff --git a/src/storage/compaction/ob_sstable_merge_info_mgr.h b/src/storage/compaction/ob_sstable_merge_info_mgr.h index c5a2cd7be..841280efa 100644 --- a/src/storage/compaction/ob_sstable_merge_info_mgr.h +++ b/src/storage/compaction/ob_sstable_merge_info_mgr.h @@ -26,51 +26,39 @@ namespace oceanbase namespace storage { -class ObSSTableMergeInfoIterator -{ -public: - ObSSTableMergeInfoIterator(); - virtual ~ObSSTableMergeInfoIterator(); - int open(const int64_t tenant_id); - int get_next_merge_info(ObSSTableMergeInfo &merge_info); - void reset(); -private: - int next_tenant(share::ObTenantSwitchGuard &tenant_guard); -private: - omt::TenantIdList all_tenants_; - int64_t tenant_idx_; - int64_t cur_tenant_id_; - int64_t major_info_idx_; - int64_t major_info_cnt_; - int64_t minor_info_idx_; - int64_t minor_info_cnt_; - bool is_opened_; -}; - class ObTenantSSTableMergeInfoMgr { public: static int mtl_init(ObTenantSSTableMergeInfoMgr *&sstable_merge_info); + static int64_t cal_max(); + static int get_next_info(compaction::ObIDiagnoseInfoMgr::Iterator &major_iter, + compaction::ObIDiagnoseInfoMgr::Iterator &minor_iter, + ObSSTableMergeInfo &info, char *buf, const int64_t buf_len); // TODO need init memory limit with tenant config - int init(const int64_t memory_limit = MERGE_INFO_MEMORY_LIMIT); - int add_sstable_merge_info(ObSSTableMergeInfo &merge_info); ObTenantSSTableMergeInfoMgr(); virtual ~ObTenantSSTableMergeInfoMgr(); + int init(const int64_t page_size=compaction::ObIDiagnoseInfoMgr::INFO_PAGE_SIZE); + int add_sstable_merge_info(ObSSTableMergeInfo &input_info); void destroy(); + int open_iter(compaction::ObIDiagnoseInfoMgr::Iterator &major_iter, + compaction::ObIDiagnoseInfoMgr::Iterator &minor_iter); + + int set_max(int64_t max_size); + int gc_info(); + + // for unittest + int size(); + +public: + static const int64_t MEMORY_PERCENTAGE = 2; // max size = tenant memory size * MEMORY_PERCENTAGE / 100 + static const int64_t MINOR_MEMORY_PERCENTAGE = 75; + static const int64_t POOL_MAX_SIZE = 256LL * 1024LL * 1024LL; // 256MB - int get_major_info(const int64_t idx, ObSSTableMergeInfo &merge_info); - int get_minor_info(const int64_t idx, ObSSTableMergeInfo &merge_info); - int get_major_info_array_cnt() const { return major_merge_infos_.size(); } - int get_minor_info_array_cnt() const { return minor_merge_infos_.size(); } private: - void release_info(ObSSTableMergeInfo &merge_info); - static const int64_t MERGE_INFO_MEMORY_LIMIT = 64LL * 1024LL * 1024LL; //64MB bool is_inited_; - common::ObArenaAllocator allocator_; - compaction::ObInfoRingArray major_merge_infos_; - compaction::ObInfoRingArray minor_merge_infos_; + compaction::ObIDiagnoseInfoMgr major_info_pool_; + compaction::ObIDiagnoseInfoMgr minor_info_pool_; DISALLOW_COPY_AND_ASSIGN(ObTenantSSTableMergeInfoMgr); - }; }//storage diff --git a/src/storage/compaction/ob_tablet_merge_checker.cpp b/src/storage/compaction/ob_tablet_merge_checker.cpp new file mode 100644 index 000000000..45a925aa4 --- /dev/null +++ b/src/storage/compaction/ob_tablet_merge_checker.cpp @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2021 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 "storage/compaction/ob_tablet_merge_checker.h" +#include "lib/oblog/ob_log.h" +#include "lib/ob_errno.h" +#include "storage/compaction/ob_compaction_util.h" +#include "storage/tablet/ob_tablet.h" + +#define USING_LOG_PREFIX STORAGE_COMPACTION + +using namespace oceanbase::common; +using namespace oceanbase::storage; + +namespace oceanbase +{ +namespace compaction +{ +int ObTabletMergeChecker::check_need_merge(const ObMergeType merge_type, const ObTablet &tablet) +{ + int ret = OB_SUCCESS; + bool need_merge = true; + + if (OB_UNLIKELY(merge_type <= ObMergeType::INVALID_MERGE_TYPE + || merge_type >= ObMergeType::MERGE_TYPE_MAX)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("merge type is invalid", K(ret), "merge_type", merge_type_to_str(merge_type)); + } else if (!is_minor_merge(merge_type) + && !is_mini_merge(merge_type) + && !is_major_merge(merge_type) + && !is_medium_merge(merge_type)) { + need_merge = true; + } else { + const share::ObLSID &ls_id = tablet.get_tablet_meta().ls_id_; + const common::ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; + bool is_empty_shell = tablet.is_empty_shell(); + if (is_minor_merge(merge_type) || is_mini_merge(merge_type)) { + need_merge = !is_empty_shell; + } else if (is_major_merge(merge_type) || is_medium_merge(merge_type)) { + need_merge = tablet.is_data_complete(); + } + + if (OB_FAIL(ret)) { + } else if (!need_merge) { + ret = OB_NO_NEED_MERGE; + LOG_INFO("tablet has no need to merge", K(ret), K(ls_id), K(tablet_id), + "merge_type", merge_type_to_str(merge_type)); + } + } + + return ret; +} +} // namespace compaction +} // namespace oceanbase diff --git a/src/storage/compaction/ob_tablet_merge_checker.h b/src/storage/compaction/ob_tablet_merge_checker.h new file mode 100644 index 000000000..1e88ec06b --- /dev/null +++ b/src/storage/compaction/ob_tablet_merge_checker.h @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2021 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 STORAGE_COMPACTION_OB_TABLET_MERGE_CHECKER_H_ +#define STORAGE_COMPACTION_OB_TABLET_MERGE_CHECKER_H_ + +#include "storage/compaction/ob_compaction_util.h" + +namespace oceanbase +{ +namespace storage +{ +class ObTablet; +} + +namespace compaction +{ +class ObTabletMergeChecker +{ +public: + static int check_need_merge(const storage::ObMergeType merge_type, const storage::ObTablet &tablet); +}; +} // namespace compaction +} // namespace oceanbase + +#endif // STORAGE_COMPACTION_OB_TABLET_MERGE_CHECKER_H_ diff --git a/src/storage/compaction/ob_tablet_merge_ctx.cpp b/src/storage/compaction/ob_tablet_merge_ctx.cpp old mode 100644 new mode 100755 index 2f00e5114..4576cee72 --- a/src/storage/compaction/ob_tablet_merge_ctx.cpp +++ b/src/storage/compaction/ob_tablet_merge_ctx.cpp @@ -26,6 +26,7 @@ #include "storage/compaction/ob_medium_compaction_mgr.h" #include "storage/compaction/ob_medium_compaction_func.h" #include "src/storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "src/storage/tablet/ob_tablet_medium_info_reader.h" namespace oceanbase { @@ -248,7 +249,7 @@ int ObTabletMergeInfo::build_create_sstable_param(const ObTabletMergeCtx &ctx, param.ddl_scn_.set_min(); MEMCPY(param.encrypt_key_, res.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); if (is_major_merge_type(ctx.param_.merge_type_)) { - if (FAILEDx(res.fill_column_checksum(ctx.get_schema(), param.column_checksums_))) { + if (OB_FAIL(param.column_checksums_.assign(res.data_column_checksums_))) { LOG_WARN("fail to fill column checksum", K(ret), K(res)); } } @@ -281,12 +282,15 @@ int ObTabletMergeInfo::record_start_tx_scn_for_tx_data(const ObTabletMergeCtx &c } else if (is_minor_merge(ctx.param_.merge_type_)) { // when this merge is MINOR_MERGE, use max_filtered_end_scn in filter if filtered some tx data ObTransStatusFilter *compaction_filter_ = (ObTransStatusFilter*)ctx.compaction_filter_; + ObSSTableMetaHandle sstable_meta_hdl; ObSSTable *oldest_tx_data_sstable = static_cast(ctx.tables_handle_.get_table(0)); if (OB_ISNULL(oldest_tx_data_sstable)) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("tx data sstable is unexpected nullptr", KR(ret)); + } else if (OB_FAIL(oldest_tx_data_sstable->get_meta(sstable_meta_hdl))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); } else { - param.filled_tx_scn_ = oldest_tx_data_sstable->get_filled_tx_scn(); + param.filled_tx_scn_ = sstable_meta_hdl.get_sstable_meta().get_filled_tx_scn(); if (OB_NOT_NULL(compaction_filter_)) { // if compaction_filter is valid, update filled_tx_log_ts if recycled some tx data @@ -319,33 +323,25 @@ int ObTabletMergeInfo::create_sstable(ObTabletMergeCtx &ctx) ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid merge ctx", K(ret), K(ctx)); } else { - int64_t column_count; - if (OB_FAIL(ctx.get_schema()->get_store_column_count( - column_count, is_multi_version_merge(ctx.param_.merge_type_)))) { - LOG_WARN("fail to get store column count", K(ret), K(ctx)); - } else { - SMART_VARS_2((ObSSTableMergeRes, res), (ObTabletCreateSSTableParam, param)) { - column_count += ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); - if (OB_ISNULL(index_builder_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null index builder", K(ret)); - } else if (OB_FAIL(index_builder_->close(column_count, res))) { - LOG_WARN("fail to close index builder", K(ret), K(column_count)); - } else if (OB_FAIL(build_create_sstable_param(ctx, res, bloomfilter_block_id_, param))) { - LOG_WARN("fail to build create sstable param", K(ret)); - } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, ctx.merged_table_handle_))) { - LOG_WARN("fail to create sstable", K(ret), K(param)); - } else { + SMART_VARS_2((ObSSTableMergeRes, res), (ObTabletCreateSSTableParam, param)) { + if (OB_ISNULL(index_builder_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null index builder", K(ret)); + } else if (OB_FAIL(index_builder_->close(res))) { + LOG_WARN("fail to close index builder", K(ret)); + } else if (OB_FAIL(build_create_sstable_param(ctx, res, bloomfilter_block_id_, param))) { + LOG_WARN("fail to build create sstable param", K(ret)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, ctx.allocator_, ctx.merged_sstable_))) { + LOG_WARN("fail to create sstable", K(ret), K(param)); + } else { + ObSSTableMergeInfo &sstable_merge_info = ctx.merge_info_.get_sstable_merge_info(); + sstable_merge_info.compaction_scn_ = ctx.get_compaction_scn(); + (void)ctx.generate_participant_table_info(sstable_merge_info.participant_table_info_); + (void)ctx.generate_macro_id_list(sstable_merge_info.macro_id_list_, sizeof(sstable_merge_info.macro_id_list_)); - ObSSTableMergeInfo &sstable_merge_info = ctx.merge_info_.get_sstable_merge_info(); - sstable_merge_info.compaction_scn_ = ctx.get_compaction_scn(); - (void)ctx.generate_participant_table_info(sstable_merge_info.participant_table_str_, sizeof(sstable_merge_info.participant_table_str_)); - (void)ctx.generate_macro_id_list(sstable_merge_info.macro_id_list_, sizeof(sstable_merge_info.macro_id_list_)); - - FLOG_INFO("succeed to merge sstable", K(param), - "table_key", ctx.merged_table_handle_.get_table()->get_key(), - "sstable_merge_info", sstable_merge_info); - } + FLOG_INFO("succeed to merge sstable", K(param), + "table_key", ctx.merged_sstable_.get_key(), + "sstable_merge_info", sstable_merge_info); } } } @@ -490,18 +486,17 @@ ObCompactionTimeGuard & ObCompactionTimeGuard::operator=(const ObCompactionTimeG * ----------------------------------------------ObTabletMergeCtx-------------------------------------------------- */ -ObSchemaMergeCtx::ObSchemaMergeCtx(ObIAllocator &allocator) +ObSchemaMergeCtx::ObSchemaMergeCtx(ObArenaAllocator &allocator) : allocator_(allocator), base_schema_version_(0), schema_version_(0), - allocated_storage_schema_(false), storage_schema_(nullptr) { } ObTabletMergeCtx::ObTabletMergeCtx( ObTabletMergeDagParam ¶m, - common::ObIAllocator &allocator) + common::ObArenaAllocator &allocator) : param_(param), allocator_(allocator), sstable_version_range_(), @@ -509,7 +504,7 @@ ObTabletMergeCtx::ObTabletMergeCtx( merge_scn_(), create_snapshot_version_(0), tables_handle_(), - merged_table_handle_(), + merged_sstable_(), schema_ctx_(allocator), is_full_merge_(false), is_tenant_major_merge_(false), @@ -530,7 +525,6 @@ ObTabletMergeCtx::ObTabletMergeCtx( time_guard_(), rebuild_seq_(-1), data_version_(0), - merge_list_(), tnode_stat_() { merge_scn_.set_max(); @@ -553,6 +547,13 @@ void ObTabletMergeCtx::destroy() allocator_.free(compaction_filter_); compaction_filter_ = nullptr; } + if (OB_NOT_NULL(schema_ctx_.storage_schema_)) { + schema_ctx_.storage_schema_->~ObStorageSchema(); + schema_ctx_.storage_schema_ = nullptr; + + // TODO(@lixia.yq): ensure that the buffer corresponding to storage schema is always allocated by ObArenaAllocator + // otherwise there will be memory leak here. + } tables_handle_.reset(); tablet_handle_.reset(); } @@ -650,15 +651,9 @@ int ObTabletMergeCtx::get_merge_range(int64_t parallel_idx, ObDatumRange &merge_ int ObTabletMergeCtx::inner_init_for_medium() { int ret = OB_SUCCESS; - ObGetMergeTablesParam get_merge_table_param; + const ObMediumCompactionInfo *medium_info = nullptr; ObGetMergeTablesResult get_merge_table_result; - get_merge_table_param.merge_type_ = param_.merge_type_; - get_merge_table_param.merge_version_ = param_.merge_version_; - if (OB_FAIL(ObPartitionMergePolicy::get_merge_tables[param_.merge_type_]( - get_merge_table_param, - *ls_handle_.get_ls(), - *tablet_handle_.get_obj(), - get_merge_table_result))) { + if (OB_FAIL(get_merge_tables(get_merge_table_result))) { if (OB_NO_NEED_MERGE != ret) { LOG_WARN("failed to get merge tables", K(ret), KPC(this), K(get_merge_table_result)); } @@ -680,55 +675,113 @@ int ObTabletMergeCtx::inner_init_for_medium() return ret; } +int ObTabletMergeCtx::get_merge_tables(ObGetMergeTablesResult &get_merge_table_result) +{ + int ret = OB_SUCCESS; + ObGetMergeTablesParam get_merge_table_param; + get_merge_table_param.merge_type_ = param_.merge_type_; + get_merge_table_param.merge_version_ = param_.merge_version_; + if (OB_FAIL(ObPartitionMergePolicy::get_merge_tables[param_.merge_type_]( + get_merge_table_param, + *ls_handle_.get_ls(), + *tablet_handle_.get_obj(), + get_merge_table_result))) { + if (OB_NO_NEED_MERGE != ret) { + LOG_WARN("failed to get merge tables", K(ret), KPC(this), K(get_merge_table_result)); + } + } + return ret; +} + int ObTabletMergeCtx::init_get_medium_compaction_info( const int64_t medium_snapshot, ObGetMergeTablesResult &get_merge_table_result) { int ret = OB_SUCCESS; ObTablet *tablet = tablet_handle_.get_obj(); - const ObMediumCompactionInfoList &medium_list = tablet->get_medium_compaction_info_list(); - const bool medium_in_storage = medium_snapshot <= tablet->get_tablet_meta().max_serialized_medium_scn_; + ObArenaAllocator temp_allocator("GetMediumInfo", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); // for load medium info ObMediumCompactionInfo medium_info; - const ObMediumCompactionInfo *medium_info_ptr = &medium_info; - if (OB_UNLIKELY(!medium_list.is_valid())) { + ObMediumCompactionInfoKey medium_info_key(medium_snapshot); + storage::ObTabletMediumInfoReader medium_info_reader(*tablet); + if (OB_FAIL(medium_info_reader.init(temp_allocator))) { + LOG_WARN("failed to init medium info reader", K(ret), KPC(this)); + } else if (OB_FAIL(medium_info_reader.get_specified_medium_info(temp_allocator, medium_info_key, medium_info))) { + LOG_WARN("failed to get specified scn info", K(ret), K(medium_snapshot)); + } else if (OB_UNLIKELY(!medium_info.is_valid())) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("medium compaction mgr is invalid", K(ret), KPC(this), K(medium_list)); - } else if (medium_in_storage && OB_FAIL(medium_list.get_specified_scn_info(medium_snapshot, medium_info_ptr))) { - LOG_WARN("failed to get medium info from mgr", K(ret), K(medium_snapshot), K(medium_list)); - } else if (!medium_in_storage && OB_FAIL(get_specified_medium_compaction_info_from_memtable(allocator_, medium_snapshot, medium_info))) { - LOG_WARN("failed to get medium info from memtable", K(ret), K(medium_snapshot)); - } else if (OB_UNLIKELY(nullptr == medium_info_ptr || !medium_info_ptr->is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("medium compaction info is invalid", K(ret), KPC(this), K(medium_list), KPC(medium_info_ptr)); - } else if (medium_info_ptr->contain_parallel_range_ + LOG_WARN("medium info is invalid", KR(ret), K(medium_info)); + } else if (medium_info.contain_parallel_range_ && !parallel_merge_ctx_.is_valid() - && OB_FAIL(parallel_merge_ctx_.init(*medium_info_ptr))) { // may init twice after swap tablet - LOG_WARN("failed to init parallel merge ctx", K(ret), KPC(medium_info_ptr)); + && OB_FAIL(parallel_merge_ctx_.init(medium_info))) { // may init twice after swap tablet + LOG_WARN("failed to init parallel merge ctx", K(ret), K(medium_info)); } else { void *buf = nullptr; - if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObStorageSchema)))) { + if (OB_NOT_NULL(schema_ctx_.storage_schema_)) { + // do nothing + } else if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObStorageSchema)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("failed to alloc storage schema", K(ret)); } else { ObStorageSchema *storage_schema = nullptr; storage_schema = new(buf) ObStorageSchema(); - schema_ctx_.storage_schema_ = storage_schema; - schema_ctx_.allocated_storage_schema_ = true; - if (OB_FAIL(storage_schema->init(allocator_, medium_info_ptr->storage_schema_))) { - LOG_WARN("failed to init storage schema from current medium info", K(ret), KPC(medium_info_ptr)); + if (OB_FAIL(storage_schema->init(allocator_, medium_info.storage_schema_))) { + LOG_WARN("failed to init storage schema from current medium info", K(ret), K(medium_info)); + } else { + schema_ctx_.storage_schema_ = storage_schema; } } if (OB_FAIL(ret)) { - } else if (tablet_handle_.get_obj()->get_multi_version_start() > medium_snapshot) { + } else if (OB_UNLIKELY(tablet_handle_.get_obj()->get_multi_version_start() > medium_snapshot)) { ret = OB_SNAPSHOT_DISCARDED; LOG_ERROR("multi version data is discarded, should not compaction now", K(ret), K(param_), K(medium_snapshot)); } } - if (OB_SUCC(ret)) { - get_merge_table_result.schema_version_ = medium_info_ptr->storage_schema_.schema_version_; - data_version_ = medium_info_ptr->data_version_; - is_tenant_major_merge_ = medium_info_ptr->is_major_compaction(); + if (FAILEDx(check_medium_info_and_last_major(medium_info, get_merge_table_result))) { + LOG_WARN("failed to check medium info and last major sstable", KR(ret), K(medium_info), K(get_merge_table_result)); + } else { + get_merge_table_result.schema_version_ = medium_info.storage_schema_.schema_version_; + data_version_ = medium_info.data_version_; + is_tenant_major_merge_ = medium_info.is_major_compaction(); + } + return ret; +} + +int ObTabletMergeCtx::check_medium_info_and_last_major( + const ObMediumCompactionInfo &medium_info, + const ObGetMergeTablesResult &get_merge_table_result) const +{ + int ret = OB_SUCCESS; + if (ObMediumCompactionInfo::MEIDUM_COMPAT_VERSION_V2 == medium_info.medium_compat_version_) { + if (medium_info.from_cur_cluster()) { + if (OB_UNLIKELY(medium_info.last_medium_snapshot_ + != get_merge_table_result.handle_.get_table(0)->get_snapshot_version())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("last medium snapshot in medium info is not equal to last " + "major sstable, medium info may lost", + KR(ret), K(medium_info), K(get_merge_table_result)); + } + } else { // check next freeze info in inner_table & medium_info + const int64_t last_major_sstable_snapshot = + get_merge_table_result.handle_.get_table(0)->get_snapshot_version(); + ObTenantFreezeInfoMgr::FreezeInfo freeze_info; + if (OB_FAIL(MTL_CALL_FREEZE_INFO_MGR( + get_freeze_info_behind_snapshot_version, + last_major_sstable_snapshot, freeze_info))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("failed to get freeze info", K(ret), + K(last_major_sstable_snapshot), KPC(this)); + } else { + ret = OB_EAGAIN; + LOG_WARN("next freeze info is not exist yet, need to check after refresh freeze info", + KR(ret), K(medium_info), K(get_merge_table_result)); + } + } else if (OB_UNLIKELY(freeze_info.freeze_version != medium_info.medium_snapshot_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("next freeze info is not equal to last major sstable, medium info may lost", + KR(ret), "freeze_version", freeze_info.freeze_version, K(medium_info), K(get_merge_table_result)); + } + } } return ret; } @@ -784,7 +837,7 @@ int ObTabletMergeCtx::inner_init_for_mini(bool &skip_rest_operation) int ObTabletMergeCtx::get_schema_and_gene_from_result(const ObGetMergeTablesResult &get_merge_table_result) { int ret = OB_SUCCESS; - if (OB_FAIL(get_storage_schema_to_merge(get_merge_table_result.handle_, true/*get_schema_on_memtable*/))) { + if (OB_FAIL(get_storage_schema_to_merge(get_merge_table_result.handle_))) { LOG_WARN("failed to get storage schema to merge", K(ret), KPC(this)); } else if (OB_FAIL(get_basic_info_from_result(get_merge_table_result))) { LOG_WARN("failed to set basic info to ctx", K(ret), K(get_merge_table_result), KPC(this)); @@ -802,20 +855,26 @@ int ObTabletMergeCtx::get_schema_and_gene_from_result(const ObGetMergeTablesResu int ObTabletMergeCtx::update_tablet_or_release_memtable(const ObGetMergeTablesResult &get_merge_table_result) { int ret = OB_SUCCESS; + int64_t old_storage_schema_version = 0; ObTablet *old_tablet = tablet_handle_.get_obj(); // check whether snapshot is updated or have storage_schema bool update_table_store_flag = false; + ObArenaAllocator temp_allocator("DirUpdateTablet", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); + const ObStorageSchema *schema_on_tablet = nullptr; + if (OB_UNLIKELY(!is_mini_merge(param_.merge_type_))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("can only update tablet in mini merge", K(ret), KPC(this)); - } else if (OB_FAIL(get_storage_schema_to_merge(get_merge_table_result.handle_, true/*get_schema_on_memtable*/))) { + } else if (OB_FAIL(get_storage_schema_to_merge(get_merge_table_result.handle_))) { LOG_WARN("failed to get storage schema", K(ret), K(get_merge_table_result)); } else if (OB_ISNULL(schema_ctx_.storage_schema_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("storage schema is unexpected null", K(ret), KPC(this)); - } else if (schema_ctx_.storage_schema_->get_schema_version() > old_tablet->get_storage_schema().get_schema_version()) { + } else if (OB_FAIL(old_tablet->load_storage_schema(temp_allocator, schema_on_tablet))) { + LOG_WARN("failed to load storage schema", K(ret), KPC(old_tablet)); + } else if (OB_UNLIKELY(schema_on_tablet->compare_schema_newer(*schema_ctx_.storage_schema_))) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("can't have larger storage schema", K(ret), K(schema_ctx_.storage_schema_), K(old_tablet->get_storage_schema())); + LOG_WARN("schema on memtable is newer", K(ret), K(schema_ctx_.storage_schema_), KPC(schema_on_tablet)); } else if (OB_UNLIKELY(get_merge_table_result.scn_range_.end_scn_ > old_tablet->get_tablet_meta().clog_checkpoint_scn_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("can't have larger end_log_ts", K(ret), K(get_merge_table_result), K(old_tablet->get_tablet_meta())); @@ -833,6 +892,7 @@ int ObTabletMergeCtx::update_tablet_or_release_memtable(const ObGetMergeTablesRe } else { LOG_INFO("success to release memtable", K(ret), K_(param), K(release_memtable_scn)); } + ObTablet::free_storage_schema(temp_allocator, schema_on_tablet); return ret; } @@ -843,9 +903,8 @@ int ObTabletMergeCtx::update_tablet_directly(const ObGetMergeTablesResult &get_m scn_range_ = get_merge_table_result.scn_range_; - ObTableHandleV2 empty_table_handle; ObUpdateTableStoreParam param( - empty_table_handle, + nullptr/*sstable*/, get_merge_table_result.version_range_.snapshot_version_, get_merge_table_result.version_range_.multi_version_start_, schema_ctx_.storage_schema_, @@ -862,8 +921,7 @@ int ObTabletMergeCtx::update_tablet_directly(const ObGetMergeTablesResult &get_m LOG_WARN("failed to assgin table handle", K(ret)); } else { merge_info_.get_sstable_merge_info().merge_finish_time_ = common::ObTimeUtility::fast_current_time(); - (void)generate_participant_table_info(merge_info_.get_sstable_merge_info().participant_table_str_, - sizeof(merge_info_.get_sstable_merge_info().participant_table_str_)); + (void)generate_participant_table_info(merge_info_.get_sstable_merge_info().participant_table_info_); (void)merge_dag_->get_ctx().collect_running_info(); if (OB_TMP_FAIL(ObMediumCompactionScheduleFunc::schedule_tablet_medium_merge( @@ -909,7 +967,13 @@ int ObTabletMergeCtx::get_basic_info_from_result( ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "unexpected table type", K(ret), KPC(table), K(tables_handle_)); } else { - sstable_logic_seq_ = MIN(ObMacroDataSeq::MAX_SSTABLE_SEQ, static_cast(table)->get_sstable_seq() + 1); + const ObSSTable *sstable = static_cast(table); + ObSSTableMetaHandle meta_handle; + if (OB_FAIL(sstable->get_meta(meta_handle))) { + LOG_WARN("get meta handle fail", K(ret), KPC(sstable)); + } else { + sstable_logic_seq_ = MIN(ObMacroDataSeq::MAX_SSTABLE_SEQ, meta_handle.get_sstable_meta().get_sstable_seq()+ 1); + } } schema_ctx_.base_schema_version_ = get_merge_table_result.base_schema_version_; @@ -942,6 +1006,8 @@ int ObTabletMergeCtx::cal_major_merge_param(const ObGetMergeTablesResult &get_me int ret = OB_SUCCESS; ObSSTable *base_table = nullptr; bool is_schema_changed = false; + int64_t full_stored_col_cnt = 0; + ObSSTableMetaHandle sstable_meta_hdl; read_base_version_ = get_merge_table_result.read_base_version_; param_.merge_version_ = get_merge_table_result.merge_version_; @@ -951,18 +1017,29 @@ int ObTabletMergeCtx::cal_major_merge_param(const ObGetMergeTablesResult &get_me || (!base_table->is_major_sstable() && !base_table->is_meta_major_sstable())) { ret = OB_ENTRY_NOT_EXIST; LOG_WARN("base table must be major or meta major", K(ret), K(tables_handle_)); + } else if (OB_FAIL(base_table->get_meta(sstable_meta_hdl))) { + LOG_WARN("fail to get sstable meta", K(ret), KPC(base_table)); + } else if (OB_FAIL(get_schema()->get_stored_column_count_in_sstable(full_stored_col_cnt))) { + LOG_WARN("failed to get stored column count in sstable", K(ret), KPC(get_schema())); + } else if (OB_UNLIKELY(sstable_meta_hdl.get_sstable_meta().get_column_count() > full_stored_col_cnt)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("stored col cnt in curr schema is less than old major sstable", K(ret), + "col_cnt_in_sstable", sstable_meta_hdl.get_sstable_meta().get_column_count(), + "col_cnt_in_schema", full_stored_col_cnt, + K(sstable_meta_hdl), KPC(this)); } else { if (1 == get_schema()->get_progressive_merge_num()) { is_full_merge_ = true; } else { is_full_merge_ = false; } - const ObSSTableBasicMeta &base_meta = base_table->get_meta().get_basic_meta(); - if (base_table->get_meta().get_column_count() != get_schema()->get_column_count() + + const ObSSTableBasicMeta &base_meta = sstable_meta_hdl.get_sstable_meta().get_basic_meta(); + if (sstable_meta_hdl.get_sstable_meta().get_column_count() != full_stored_col_cnt || base_meta.compressor_type_ != get_schema()->get_compressor_type() || (ObRowStoreType::DUMMY_ROW_STORE != base_meta.latest_row_store_type_ && base_meta.latest_row_store_type_ != get_schema()->row_store_type_)) { - is_schema_changed = true; + is_schema_changed = true; // used to change merge_level, merge_round is from schema } const int64_t meta_progressive_merge_round = base_meta.progressive_merge_round_; @@ -985,7 +1062,7 @@ int ObTabletMergeCtx::cal_major_merge_param(const ObGetMergeTablesResult &get_me } FLOG_INFO("Calc progressive param", K(is_schema_changed), K(progressive_merge_num_), K(progressive_merge_round_), K(meta_progressive_merge_round), K(progressive_merge_step_), - K(is_full_merge_)); + K(is_full_merge_), K(full_stored_col_cnt), K(sstable_meta_hdl.get_sstable_meta().get_column_count())); } if (OB_SUCC(ret)) { @@ -1012,125 +1089,73 @@ int ObTabletMergeCtx::init_merge_info() return ret; } -int ObTabletMergeCtx::get_medium_compaction_info_to_store() -{ - int ret = OB_SUCCESS; - if (is_mini_merge(param_.merge_type_)) { - ObSEArray memtables; - if (OB_FAIL(tables_handle_.get_tables(memtables))) { - LOG_WARN("failed to get tables", K(ret), K(memtables)); - } else if (OB_FAIL(ObMediumCompactionScheduleFunc::get_medium_info_list_from_memtable( - allocator_, memtables, merge_list_))) { - LOG_WARN("failed to get medium info list from memtable", K(ret)); - } else if (merge_list_.size() > 0) { - LOG_INFO("success get medium info list", "ls_id", param_.ls_id_, - "tablet_id", param_.tablet_id_, K(merge_list_)); - } - } - return ret; -} -int ObTabletMergeCtx::get_specified_medium_compaction_info_from_memtable( - ObIAllocator &allocator, - const int64_t medium_snapshot, - ObMediumCompactionInfo &medium_info) -{ - int ret = OB_SUCCESS; - ObArenaAllocator tmp_allocator; - ObSEArray memtables; - ObMediumCompactionInfoList tmp_medium_list; - if (OB_FAIL(tablet_handle_.get_obj()->get_memtables(memtables, true/*need_active*/))) { - LOG_WARN("failed to get memtables", K(ret), K(param_)); - } else if (memtables.empty()) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("no memtable", K(ret), K(memtables), K(param_)); - } else if (OB_FAIL(ObMediumCompactionScheduleFunc::get_medium_info_list_from_memtable( - tmp_allocator, memtables, tmp_medium_list))) { - LOG_WARN("failed to get medium info list from memtable", K(ret)); - } else if (tmp_medium_list.is_empty()) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("have memtables, but medium list is empty", K(ret), K(memtables), K(tmp_medium_list)); - } else { - const ObMediumCompactionInfo *info_in_list = nullptr; - DLIST_FOREACH_X(info, tmp_medium_list.get_list(), OB_SUCC(ret)) { - if (OB_UNLIKELY(memtable::MultiSourceDataUnitType::MEDIUM_COMPACTION_INFO != info->type())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("return info is invalid", K(ret), KPC(info)); - } else if (FALSE_IT(info_in_list = static_cast(info))) { - } else if (medium_snapshot < info_in_list->medium_snapshot_) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("not found specified medium info in medium list", K(ret), K(param_), K(memtables), K(tmp_medium_list)); - } else if (medium_snapshot == info_in_list->medium_snapshot_) { - if (OB_FAIL(medium_info.init(allocator, *info_in_list))) { - LOG_WARN("failed to init medium info", K(ret)); - } - break; - } - } - if (OB_SUCC(ret) && medium_info.is_valid()) { - LOG_INFO("success get medium info", "ls_id", param_.ls_id_, - "tablet_id", param_.tablet_id_, K(medium_info)); - } - } - return ret; -} - -int ObTabletMergeCtx::get_storage_schema_to_merge( - const ObTablesHandleArray &merge_tables_handle, - const bool get_schema_on_memtable) +int ObTabletMergeCtx::get_storage_schema_to_merge(const ObTablesHandleArray &merge_tables_handle) { int ret = OB_SUCCESS; const ObMergeType &merge_type = param_.merge_type_; - ObStorageSchema *storage_schema = nullptr; + const ObStorageSchema *schema_on_tablet = nullptr; + int64_t max_column_cnt_in_memtable = 0; + int64_t max_schema_version_in_memtable = 0; + int64_t column_cnt_in_schema = 0; + bool use_schema_on_tablet = true; // for minor & tx_mini, use storage schema on tablet - bool get_storage_schema_flag = true; - if (is_mini_merge(merge_type) && get_schema_on_memtable) { - void *buf = nullptr; - ObSEArray memtables; - - if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObStorageSchema)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("failed to alloc storage schema", K(ret)); - } else { - storage_schema = new(buf) ObStorageSchema(); - } - - if (FAILEDx(merge_tables_handle.get_tables(memtables))) { - LOG_WARN("failed to get tables", K(ret), K(memtables)); - } else if (OB_FAIL(ObMediumCompactionScheduleFunc::get_latest_storage_schema_from_memtable( - allocator_, memtables, *storage_schema))) { - if (OB_ENTRY_NOT_EXIST == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get storage schema on memtable", K(ret), K_(param)); + if (OB_FAIL(tablet_handle_.get_obj()->load_storage_schema(allocator_, schema_on_tablet))) { + LOG_WARN("failed to load storage schema", K(ret), K_(tablet_handle)); + } else if (is_mini_merge(merge_type) && !param_.tablet_id_.is_ls_inner_tablet()) { + ObITable *table = nullptr; + memtable::ObMemtable *memtable = nullptr; + for (int i = merge_tables_handle.get_count() - 1; OB_SUCC(ret) && i >= 0; --i) { + if (OB_ISNULL(table = merge_tables_handle.get_table(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table in tables_handle is invalid", K(ret), KPC(table)); + } else if (OB_ISNULL(memtable = dynamic_cast(table))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table pointer does not point to a ObMemtable object", KPC(table)); + } else if (OB_FAIL(memtable->get_schema_info( + max_schema_version_in_memtable, max_column_cnt_in_memtable))) { + LOG_WARN("failed to get schema info from memtable", KR(ret), KPC(memtable)); } - } else { - get_storage_schema_flag = false; - } + } // end of for - // free alloced storage schema - if ((OB_FAIL(ret) || get_storage_schema_flag) && nullptr != storage_schema) { - storage_schema->~ObStorageSchema(); - allocator_.free(storage_schema); - storage_schema = nullptr; + if (FAILEDx(schema_on_tablet->get_store_column_count(column_cnt_in_schema, true/*full_col*/))) { + LOG_WARN("failed to get store column count", K(ret), K(column_cnt_in_schema)); + } else if (max_column_cnt_in_memtable > column_cnt_in_schema + || max_schema_version_in_memtable > schema_on_tablet->get_schema_version()) { + // need alloc new storage schema & set column cnt + void *buf = nullptr; + if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObStorageSchema)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc storage schema", K(ret)); + } else { + ObStorageSchema *storage_schema = new(buf) ObStorageSchema(); + if (OB_FAIL(storage_schema->init(allocator_, *schema_on_tablet, true/*column_info_simplified*/))) { + LOG_WARN("failed to init storage schema", K(ret), K(schema_on_tablet)); + allocator_.free(storage_schema); + storage_schema = nullptr; + } else { + // only update column cnt by memtable, use schema version on tablet_schema + storage_schema->column_cnt_ = MAX(storage_schema->column_cnt_, max_column_cnt_in_memtable); + storage_schema->store_column_cnt_ = MAX(column_cnt_in_schema, max_column_cnt_in_memtable); + storage_schema->schema_version_ = MAX(max_schema_version_in_memtable, schema_on_tablet->get_schema_version()); + schema_ctx_.storage_schema_ = storage_schema; + use_schema_on_tablet = false; + } + } } } - if (OB_FAIL(ret)) { - } else if (get_storage_schema_flag) { - schema_ctx_.storage_schema_ = &tablet_handle_.get_obj()->get_storage_schema(); - } else { - OB_ASSERT(nullptr != storage_schema); - schema_ctx_.storage_schema_ = storage_schema; - schema_ctx_.allocated_storage_schema_ = true; - } - if (OB_SUCC(ret)) { - OB_ASSERT(nullptr != schema_ctx_.storage_schema_); + if (use_schema_on_tablet) { + schema_ctx_.storage_schema_ = schema_on_tablet; + } schema_ctx_.schema_version_ = schema_ctx_.storage_schema_->get_schema_version(); - FLOG_INFO("get storage schema to merge", "ls_id", param_.ls_id_, - "tablet_id", param_.tablet_id_, K_(schema_ctx), K(get_storage_schema_flag), - K(get_schema_on_memtable)); + FLOG_INFO("get storage schema to merge", K_(param), K_(schema_ctx), K(use_schema_on_tablet), + K(max_column_cnt_in_memtable), K(max_schema_version_in_memtable)); + if (!use_schema_on_tablet) { + // destroy loaded schema memory after print log + ObTablet::free_storage_schema(allocator_, schema_on_tablet); + } } return ret; } @@ -1142,42 +1167,15 @@ int ObTabletMergeCtx::prepare_index_tree() if (OB_UNLIKELY(!is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid merge ctx", K(ret), KPC(this)); - } else if (OB_FAIL(desc.init(*get_schema(), + } else if (OB_FAIL(desc.init_as_index(*get_schema(), param_.ls_id_, param_.tablet_id_, param_.merge_type_, sstable_version_range_.snapshot_version_, data_version_))) { LOG_WARN("failed to init index store desc", K(ret), KPC(this)); - } else { - // TODO(zhuixin.gsy) modify index_desc.init to avoid reset col_desc_array_ - desc.row_column_count_ = desc.rowkey_column_count_ + 1; - desc.col_desc_array_.reset(); - desc.need_prebuild_bloomfilter_ = false; - if (OB_FAIL(desc.col_desc_array_.init(desc.row_column_count_))) { - LOG_WARN("failed to reserve column desc array", K(ret)); - } else if (OB_FAIL(get_schema()->get_rowkey_column_ids(desc.col_desc_array_))) { - LOG_WARN("failed to get rowkey column ids", K(ret)); - } else if (OB_FAIL(ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(desc.col_desc_array_))) { - LOG_WARN("failed to get extra rowkey column ids", K(ret)); - } else { - ObObjMeta meta; - meta.set_varchar(); - meta.set_collation_type(CS_TYPE_BINARY); - share::schema::ObColDesc col; - col.col_id_ = static_cast(desc.row_column_count_ + OB_APP_MIN_COLUMN_ID); - col.col_type_ = meta; - col.col_order_ = DESC; - - if (OB_FAIL(desc.col_desc_array_.push_back(col))) { - LOG_WARN("failed to push back last col for index", K(ret), K(col)); - } - } - } - if (OB_SUCC(ret)) { - if (OB_FAIL(merge_info_.prepare_index_builder(desc))) { - LOG_WARN("failed to prepare index builder", K(ret), K(desc)); - } + } else if (OB_FAIL(merge_info_.prepare_index_builder(desc))) { + LOG_WARN("failed to prepare index builder", K(ret), K(desc)); } return ret; } @@ -1186,8 +1184,7 @@ int ObTabletMergeCtx::prepare_merge_progress() { int ret = OB_SUCCESS; if (OB_NOT_NULL(merge_progress_)) { - const ObTableReadInfo &read_info = tablet_handle_.get_obj()->get_full_read_info(); - if (OB_FAIL(merge_progress_->init(this, read_info))) { + if (OB_FAIL(merge_progress_->init(this))) { merge_progress_->reset(); LOG_WARN("failed to init merge progress", K(ret)); } else { @@ -1197,7 +1194,16 @@ int ObTabletMergeCtx::prepare_merge_progress() return ret; } -int ObTabletMergeCtx::try_swap_tablet_handle(const ObTablesHandleArray &tables_handle) +bool ObTabletMergeCtx::need_swap_tablet(const ObTablet &tablet, + const int64_t row_count, + const int64_t macro_count) +{ + return tablet.get_memtable_mgr()->has_memtable() + && (row_count >= LARGE_VOLUME_DATA_ROW_COUNT_THREASHOLD + || macro_count >= LARGE_VOLUME_DATA_MACRO_COUNT_THREASHOLD); +} + +int ObTabletMergeCtx::try_swap_tablet_handle() { int ret = OB_SUCCESS; // check need swap tablet when compaction @@ -1205,53 +1211,54 @@ int ObTabletMergeCtx::try_swap_tablet_handle(const ObTablesHandleArray &tables_h ret = OB_NOT_SUPPORTED; LOG_WARN("mini merge not support swap tablet", K(ret), K_(param)); } else { + ObTablesHandleArray &tables_handle = tables_handle_; int64_t row_count = 0; int64_t macro_count = 0; - const ObSSTable *table = nullptr; - for (int64_t i = 0; i < tables_handle_.get_count(); ++i) { - table = static_cast(tables_handle_.get_table(i)); - row_count += table->get_meta().get_row_count(); - macro_count += table->get_meta().get_basic_meta().get_data_macro_block_count(); - } - if (tablet_handle_.get_obj()->get_table_store().get_memtables_count() > 0 - && (row_count >= LARGE_VOLUME_DATA_ROW_COUNT_THREASHOLD - || macro_count >= LARGE_VOLUME_DATA_MACRO_COUNT_THREASHOLD)) { - ObTabletHandle alloc_handle; + const ObSSTable *sstable = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && i < tables_handle_.get_count(); ++i) { + sstable = static_cast(tables_handle_.get_table(i)); + ObSSTableMetaHandle meta_handle; + if (OB_FAIL(sstable->get_meta(meta_handle))) { + LOG_WARN("get sstable meta handle fail", K(ret)); + } else { + row_count += meta_handle.get_sstable_meta().get_row_count(); + macro_count += meta_handle.get_sstable_meta().get_data_macro_block_count(); + } + } // end of for + if (need_swap_tablet(*tablet_handle_.get_obj(), row_count, macro_count)) { + tables_handle_.reset(); // clear tables array const ObTabletMapKey key(param_.ls_id_, param_.tablet_id_); if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->get_tablet_with_allocator( - WashTabletPriority::WTP_HIGH, key, allocator_, alloc_handle, true/*force_alloc_new*/))) { + WashTabletPriority::WTP_LOW, key, allocator_, tablet_handle_, true/*force_alloc_new*/))) { LOG_WARN("failed to get alloc tablet handle", K(ret), K(key)); + } else if (OB_FAIL(inner_init_for_medium())) { + LOG_WARN("failed to init for medium", K(ret), K(param_)); + } else if (OB_FAIL(tablet_handle_.get_obj()->clear_memtables_on_table_store())) { + LOG_WARN("failed to clear memtables on table_store", K(ret), K(param_)); } else { - tablet_handle_ = alloc_handle; - if (OB_FAIL(alloc_handle.get_obj()->clear_memtables_on_table_store())) { - LOG_WARN("failed to clear memtables on table_store", K(ret), K(param_)); - } else { - LOG_INFO("success to swap tablet handle", K(ret), K(macro_count), K(row_count), K(tablet_handle_.get_obj()->get_table_store())); - } + LOG_INFO("success to swap tablet handle", K(ret), K(tablet_handle_), K(tables_handle_)); } } } return ret; } -int ObTabletMergeCtx::generate_participant_table_info(char *buf, const int64_t buf_len) const +int ObTabletMergeCtx::generate_participant_table_info(PartTableInfo &info) const { int ret = OB_SUCCESS; - if (is_major_merge_type(param_.merge_type_)) { - ADD_COMPACTION_INFO_PARAM(buf, buf_len, - "table_cnt", tables_handle_.get_count(), - "[MAJOR]scn", tables_handle_.get_table(0)->get_snapshot_version()); + info.is_major_merge_ = is_major_merge_type(param_.merge_type_); + if (info.is_major_merge_) { + info.table_cnt_ = static_cast(tables_handle_.get_count()); + info.snapshot_version_ = tables_handle_.get_table(0)->get_snapshot_version(); if (tables_handle_.get_count() > 1) { - ADD_COMPACTION_INFO_PARAM(buf, buf_len, - "[MINI]start_scn", tables_handle_.get_table(1)->get_start_scn().get_val_for_tx(), - "end_scn", tables_handle_.get_table(tables_handle_.get_count() - 1)->get_end_scn().get_val_for_tx()); + info.start_scn_ = tables_handle_.get_table(1)->get_start_scn().get_val_for_tx(); + info.end_scn_ = tables_handle_.get_table(tables_handle_.get_count() - 1)->get_end_scn().get_val_for_tx(); } } else { if (tables_handle_.get_count() > 0) { - ADD_COMPACTION_INFO_PARAM(buf, buf_len, - "table_cnt", tables_handle_.get_count(), - "start_scn", tables_handle_.get_table(0)->get_start_scn().get_val_for_tx(), - "end_scn", tables_handle_.get_table(tables_handle_.get_count() - 1)->get_end_scn().get_val_for_tx()); + info.table_cnt_ = static_cast(tables_handle_.get_count()); + info.start_scn_ = tables_handle_.get_table(0)->get_start_scn().get_val_for_tx(); + info.end_scn_ = tables_handle_.get_table(tables_handle_.get_count() - 1)->get_end_scn().get_val_for_tx(); } } return ret; @@ -1260,20 +1267,25 @@ int ObTabletMergeCtx::generate_participant_table_info(char *buf, const int64_t b int ObTabletMergeCtx::generate_macro_id_list(char *buf, const int64_t buf_len) const { int ret = OB_SUCCESS; + ObMacroIdIterator iter; const ObSSTable *new_table = nullptr; - if (OB_FAIL(merged_table_handle_.get_sstable(new_table))) { - LOG_WARN("failed to get sstable", K(ret), K(merged_table_handle_)); + ObSSTableMetaHandle sst_meta_hdl; + if (OB_FAIL(merged_sstable_.get_meta(sst_meta_hdl))) { + LOG_WARN("failed to get sstable meta", K(ret)); + } else if (OB_FAIL(sst_meta_hdl.get_sstable_meta().get_macro_info().get_data_block_iter(iter))) { + LOG_WARN("fail to get data block iterator", K(ret), K(merged_sstable_)); } else { MEMSET(buf, '\0', buf_len); int pret = 0; - const common::ObIArray ¯o_list = new_table->get_meta().get_macro_info().get_data_block_ids(); + const int64_t macro_count = sst_meta_hdl.get_sstable_meta().get_data_macro_block_count(); int64_t remain_len = buf_len; - if (macro_list.count() < 40) { - for (int i = 0; OB_SUCC(ret) && i < macro_list.count(); ++i) { + if (macro_count < 40) { + MacroBlockId macro_id; + for (int64_t i = 0; OB_SUCC(ret) && OB_SUCC(iter.get_next_macro_id(macro_id)); ++i) { if (0 == i) { - pret = snprintf(buf + strlen(buf), remain_len, "%ld", macro_list.at(i).second_id()); + pret = snprintf(buf + strlen(buf), remain_len, "%ld", macro_id.second_id()); } else { - pret = snprintf(buf + strlen(buf), remain_len, ",%ld", macro_list.at(i).second_id()); + pret = snprintf(buf + strlen(buf), remain_len, ",%ld", macro_id.second_id()); } if (pret < 0 || pret > remain_len) { ret = OB_BUF_NOT_ENOUGH; @@ -1286,45 +1298,13 @@ int ObTabletMergeCtx::generate_macro_id_list(char *buf, const int64_t buf_len) c return ret; } -int serialize_medium_list( - const char *list_name, - const compaction::ObMediumCompactionInfoList &medium_list, - ObSSTableMergeInfo &sstable_merge_info, - int64_t &pos) -{ - int ret = OB_SUCCESS; - if (medium_list.get_list().get_size() > 0) { - common::databuff_printf(sstable_merge_info.comment_, sizeof(sstable_merge_info.comment_), pos, - "%s:{cnt=%d;", list_name, medium_list.get_list().get_size()); - DLIST_FOREACH_NORET(info, medium_list.get_list()) { - const compaction::ObMediumCompactionInfo *medium_info = static_cast(info); - common::databuff_printf(sstable_merge_info.comment_, sizeof(sstable_merge_info.comment_), pos, - "%ld,", medium_info->medium_snapshot_); - if (medium_info->medium_merge_reason_ > ObAdaptiveMergePolicy::AdaptiveMergeReason::NONE) { - common::databuff_printf(sstable_merge_info.comment_, sizeof(sstable_merge_info.comment_), pos, - "merge_reason=%s,", ObAdaptiveMergePolicy::merge_reason_to_str(medium_info->medium_merge_reason_)); - } - } - if (pos > 0) { - pos --; - } - common::databuff_printf(sstable_merge_info.comment_, sizeof(sstable_merge_info.comment_), pos, "}|"); - } - return ret; -} - void ObTabletMergeCtx::collect_running_info() { int tmp_ret = OB_SUCCESS; - ObDagWarningInfo *warning_info = nullptr; + ObDagWarningInfo warning_info; ObSSTableMergeInfo &sstable_merge_info = merge_info_.get_sstable_merge_info(); sstable_merge_info.dag_id_ = merge_dag_->get_dag_id(); - // collect medium info dump msg - int64_t pos = 0; - serialize_medium_list("new_medium_list", merge_list_, sstable_merge_info, pos); - serialize_medium_list("serialize_medium_list", tablet_handle_.get_obj()->get_medium_compaction_info_list(), sstable_merge_info, pos); - ADD_COMPACTION_INFO_PARAM(sstable_merge_info.comment_, sizeof(sstable_merge_info.comment_), "time_guard", time_guard_); @@ -1335,27 +1315,31 @@ void ObTabletMergeCtx::collect_running_info() sstable_merge_info.new_flush_data_rate_ = (int)(((float)sstable_merge_info.new_flush_occupy_size_/ 1024) / ((float)exe_ts / 1_s)); } - if (OB_SUCCESS == share::ObDagWarningHistoryManager::get_instance().get(dag_key, warning_info)) { - // have failed before - ADD_COMPACTION_INFO_PARAM(sstable_merge_info.comment_, sizeof(sstable_merge_info.comment_), - "latest_error_code", warning_info->dag_ret_, - "latest_error_trace", warning_info->task_id_, - "retry_cnt", warning_info->retry_cnt_); + ObInfoParamBuffer info_buffer; + if (OB_SUCCESS == MTL(ObDagWarningHistoryManager *)->get_with_param(dag_key, &warning_info, info_buffer)) { + sstable_merge_info.dag_ret_ = warning_info.dag_ret_; + sstable_merge_info.task_id_ = warning_info.task_id_; + sstable_merge_info.retry_cnt_ = warning_info.retry_cnt_; + warning_info.info_param_ = nullptr; } ObScheduleSuspectInfo ret_info; int64_t suspect_info_hash = ObScheduleSuspectInfo::gen_hash(MTL_ID(), dag_key); - if (OB_SUCCESS == ObScheduleSuspectInfoMgr::get_instance().get_suspect_info(suspect_info_hash, ret_info)) { - ADD_COMPACTION_INFO_PARAM(sstable_merge_info.comment_, sizeof(sstable_merge_info.comment_), - "add_timestamp", ret_info.add_time_, - "suspect_schedule_info", ret_info.suspect_info_); - (void)ObScheduleSuspectInfoMgr::get_instance().del_suspect_info(suspect_info_hash); + info_buffer.reuse(); + if (OB_SUCCESS == MTL(compaction::ObScheduleSuspectInfoMgr *)->get_with_param(suspect_info_hash, &ret_info, info_buffer)) { + sstable_merge_info.add_time_ = ret_info.add_time_; + sstable_merge_info.info_param_ = ret_info.info_param_; + if (OB_TMP_FAIL(MTL(compaction::ObScheduleSuspectInfoMgr *)->delete_info(suspect_info_hash))) { + LOG_WARN_RET(tmp_ret, "failed to delete old suspect info ", K(tmp_ret), K(sstable_merge_info)); + } } if (OB_TMP_FAIL(MTL(storage::ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(sstable_merge_info))) { LOG_WARN_RET(tmp_ret, "failed to add sstable merge info ", K(tmp_ret), K(sstable_merge_info)); } + sstable_merge_info.info_param_ = nullptr; } + } // namespace compaction } // namespace oceanbase diff --git a/src/storage/compaction/ob_tablet_merge_ctx.h b/src/storage/compaction/ob_tablet_merge_ctx.h old mode 100644 new mode 100755 index 6a20edf20..e6e9c7cbb --- a/src/storage/compaction/ob_tablet_merge_ctx.h +++ b/src/storage/compaction/ob_tablet_merge_ctx.h @@ -84,26 +84,21 @@ private: struct ObSchemaMergeCtx { - ObSchemaMergeCtx(ObIAllocator &allocator); + ObSchemaMergeCtx(ObArenaAllocator &allocator); ~ObSchemaMergeCtx() { destroy(); } OB_INLINE void destroy() { - if (allocated_storage_schema_ && nullptr != storage_schema_) { + if (nullptr != storage_schema_) { storage_schema_->~ObStorageSchema(); - allocator_.free((void *)storage_schema_); - allocated_storage_schema_ = false; storage_schema_ = nullptr; } } - int deep_copy(const ObSchemaMergeCtx &input_ctx); - - common::ObIAllocator &allocator_; + common::ObArenaAllocator &allocator_; int64_t base_schema_version_; int64_t schema_version_; - bool allocated_storage_schema_; const ObStorageSchema *storage_schema_; // schema for all merge TO_STRING_KV(K_(base_schema_version), K_(schema_version), KPC_(storage_schema)); @@ -155,7 +150,7 @@ private: struct ObTabletMergeCtx { - ObTabletMergeCtx(ObTabletMergeDagParam ¶m, common::ObIAllocator &allocator); + ObTabletMergeCtx(ObTabletMergeDagParam ¶m, common::ObArenaAllocator &allocator); virtual ~ObTabletMergeCtx(); void destroy(); virtual bool is_valid() const; @@ -175,19 +170,19 @@ struct ObTabletMergeCtx ObMediumCompactionInfo &info); int get_schema_and_gene_from_result(const ObGetMergeTablesResult &get_merge_table_result); int get_storage_schema_and_gene_from_result(const ObGetMergeTablesResult &get_merge_table_result); - int get_storage_schema_to_merge(const ObTablesHandleArray &merge_tables_handle, const bool get_schema_on_memtable = true); + int get_storage_schema_to_merge(const ObTablesHandleArray &merge_tables_handle); + int get_max_data_scn(const ObTablesHandleArray &merge_tables_handle); + int try_swap_tablet_handle(); - int try_swap_tablet_handle(const ObTablesHandleArray &tables_handle); -public: int get_medium_compaction_info_to_store(); - + static bool need_swap_tablet(const ObTablet &tablet, const int64_t row_count, const int64_t macro_count); int get_basic_info_from_result(const ObGetMergeTablesResult &get_merge_table_result); int cal_minor_merge_param(); int cal_major_merge_param(const ObGetMergeTablesResult &get_merge_table_result); int init_merge_info(); int prepare_index_tree(); int prepare_merge_progress(); - int generate_participant_table_info(char *buf, const int64_t buf_len) const; + int generate_participant_table_info(PartTableInfo &info) const; int generate_macro_id_list(char *buf, const int64_t buf_len) const; void collect_running_info(); int update_tablet_directly(const ObGetMergeTablesResult &get_merge_table_result); @@ -202,13 +197,17 @@ public: is_multi_version_merge(param_.merge_type_) ? scn_range_.end_scn_.get_val_for_tx() : sstable_version_range_.snapshot_version_; } + int get_merge_tables(ObGetMergeTablesResult &get_merge_table_result); + int check_medium_info_and_last_major( + const ObMediumCompactionInfo &medium_info, + const ObGetMergeTablesResult &get_merge_table_result) const; typedef common::ObSEArray MinorParallelResultArray; static const int64_t LARGE_VOLUME_DATA_ROW_COUNT_THREASHOLD = 1000L * 1000L; // 100w static const int64_t LARGE_VOLUME_DATA_MACRO_COUNT_THREASHOLD = 300L; // 1. init in dag ObTabletMergeDagParam ¶m_; - common::ObIAllocator &allocator_; + common::ObArenaAllocator &allocator_; // 2. filled in ObPartitionStore::get_merge_tables ObVersionRange sstable_version_range_;// version range for new sstable @@ -217,7 +216,7 @@ public: int64_t create_snapshot_version_; storage::ObTablesHandleArray tables_handle_; - storage::ObTableHandleV2 merged_table_handle_; + blocksstable::ObSSTable merged_sstable_; // 3. filled in ObTabletMergeCtx::get_schemas_to_merge ObSchemaMergeCtx schema_ctx_; @@ -252,7 +251,6 @@ public: ObCompactionTimeGuard time_guard_; int64_t rebuild_seq_; uint64_t data_version_; - ObMediumCompactionInfoList merge_list_; ObTransNodeDMLStat tnode_stat_; // collect trans node dml stat on memtable, only worked in mini compaction. TO_STRING_KV(K_(param), K_(sstable_version_range), K_(create_snapshot_version), @@ -266,7 +264,7 @@ public: K_(scn_range), K_(merge_scn), K_(read_base_version), K_(ls_handle), K_(tablet_handle), KPC_(merge_progress), - KPC_(compaction_filter), K_(time_guard), K_(rebuild_seq), K_(data_version), K_(merge_list)); + KPC_(compaction_filter), K_(time_guard), K_(rebuild_seq), K_(data_version)); private: DISALLOW_COPY_AND_ASSIGN(ObTabletMergeCtx); }; diff --git a/src/storage/compaction/ob_tablet_merge_task.cpp b/src/storage/compaction/ob_tablet_merge_task.cpp old mode 100644 new mode 100755 index eb933576e..ff97002fe --- a/src/storage/compaction/ob_tablet_merge_task.cpp +++ b/src/storage/compaction/ob_tablet_merge_task.cpp @@ -36,8 +36,11 @@ #include "storage/access/ob_index_sstable_estimator.h" #include "ob_medium_compaction_func.h" #include "storage/compaction/ob_tenant_tablet_scheduler.h" +#include "storage/compaction/ob_tablet_merge_checker.h" #include "share/ob_get_compat_mode.h" #include "share/ob_tablet_meta_table_compaction_operator.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" +#include "src/storage/meta_mem/ob_tenant_meta_mem_mgr.h" #include "share/resource_manager/ob_cgroup_ctrl.h" namespace oceanbase @@ -55,7 +58,8 @@ bool is_merge_dag(ObDagType::ObDagTypeEnum dag_type) return dag_type == ObDagType::DAG_TYPE_MAJOR_MERGE || dag_type == ObDagType::DAG_TYPE_MERGE_EXECUTE || dag_type == ObDagType::DAG_TYPE_MINI_MERGE - || dag_type == ObDagType::DAG_TYPE_TX_TABLE_MERGE; + || dag_type == ObDagType::DAG_TYPE_TX_TABLE_MERGE + || dag_type == ObDagType::DAG_TYPE_MDS_TABLE_MERGE; } /* @@ -73,9 +77,10 @@ ObMergeParameter::ObMergeParameter() sstable_logic_seq_(0), version_range_(), scn_range_(), - full_read_info_(nullptr), + rowkey_read_info_(nullptr), is_full_merge_(false), - trans_state_mgr_(nullptr) + trans_state_mgr_(nullptr), + merge_scn_() { } @@ -86,8 +91,10 @@ bool ObMergeParameter::is_valid() const && tables_handle_ != nullptr && sstable_logic_seq_ >= 0 && !tables_handle_->empty() + && nullptr != rowkey_read_info_ && merge_type_ > INVALID_MERGE_TYPE - && merge_type_ < MERGE_TYPE_MAX; + && merge_type_ < MERGE_TYPE_MAX + && merge_scn_.is_valid(); } void ObMergeParameter::reset() @@ -105,12 +112,13 @@ void ObMergeParameter::reset() scn_range_.reset(); is_full_merge_ = false; trans_state_mgr_ = nullptr; + rowkey_read_info_ = nullptr; + merge_scn_.reset(); } int ObMergeParameter::init(compaction::ObTabletMergeCtx &merge_ctx, const int64_t idx) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!merge_ctx.is_valid() || idx < 0 || idx >= merge_ctx.get_concurrent_cnt())) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid argument to assign merge parameter", K(merge_ctx), K(idx), K(ret)); @@ -140,9 +148,19 @@ int ObMergeParameter::init(compaction::ObTabletMergeCtx &merge_ctx, const int64_ } scn_range_ = merge_ctx.scn_range_; is_full_merge_ = merge_ctx.is_full_merge_; - full_read_info_ = &(merge_ctx.tablet_handle_.get_obj()->get_full_read_info()); - } + rowkey_read_info_ = &(merge_ctx.tablet_handle_.get_obj()->get_rowkey_read_info()); + merge_scn_ = merge_ctx.merge_scn_; + if (merge_scn_ > scn_range_.end_scn_) { + if (ObMergeType::BACKFILL_TX_MERGE != merge_type_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("merge scn is bigger than scn range but merge type is not backfill, unexpected", + K(ret), K(merge_scn_), K(scn_range_), K(merge_type_)); + } else { + FLOG_INFO("set backfill merge scn", K(merge_scn_), K(scn_range_), K(merge_type_)); + } + } + } return ret; } @@ -153,6 +171,7 @@ int ObMergeParameter::init(compaction::ObTabletMergeCtx &merge_ctx, const int64_ ObTabletMergeDagParam::ObTabletMergeDagParam() : for_diagnose_(false), is_tenant_major_merge_(false), + need_swap_tablet_flag_(false), merge_type_(INVALID_MERGE_TYPE), merge_version_(0), ls_id_(), @@ -167,6 +186,7 @@ ObTabletMergeDagParam::ObTabletMergeDagParam( const ObTabletID &tablet_id) : for_diagnose_(false), is_tenant_major_merge_(false), + need_swap_tablet_flag_(false), merge_type_(merge_type), merge_version_(0), ls_id_(ls_id), @@ -231,20 +251,28 @@ int ObBasicTabletMergeDag::get_tablet_and_compat_mode() // can't get tablet_handle now! because this func is called in create dag, // the last compaction dag is not finished yet, tablet is in old version ObTabletHandle tmp_tablet_handle; + ObTabletMemberWrapper table_store_wrapper; if (OB_FAIL(ret)) { } else if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id_, ctx_->ls_handle_, ObLSGetMod::STORAGE_MOD))) { LOG_WARN("failed to get log stream", K(ret), K(ls_id_)); } else if (OB_FAIL(ctx_->ls_handle_.get_ls()->get_tablet_svr()->get_tablet( tablet_id_, tmp_tablet_handle, - 0/*timeout_us*/))) { + 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("failed to get tablet", K(ret), K(ls_id_), K(tablet_id_)); + } else if (OB_FAIL(ObTabletMergeChecker::check_need_merge(ctx_->param_.merge_type_, *tmp_tablet_handle.get_obj()))) { + if (OB_NO_NEED_MERGE != ret) { + LOG_WARN("failed to check need merge", K(ret)); + } + } else if (OB_FAIL(tmp_tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("failed to fetch table store", K(ret), K(ls_id_), K(tablet_id_)); } else { compat_mode_ = tmp_tablet_handle.get_obj()->get_tablet_meta().compat_mode_; } if (OB_SUCC(ret) && is_mini_merge(merge_type_)) { - int64_t inc_sstable_cnt = tmp_tablet_handle.get_obj()->get_table_store().get_minor_sstables().count() + 1/*major table*/; + int64_t inc_sstable_cnt = table_store_wrapper.get_member()->get_minor_sstables().count() + 1/*major table*/; bool is_exist = false; if (OB_FAIL(MTL(ObTenantDagScheduler *)->check_dag_exist(this, is_exist))) { LOG_WARN("failed to check dag exist", K(ret), K_(param)); @@ -366,16 +394,21 @@ int64_t ObBasicTabletMergeDag::hash() const return inner_hash(); } -int ObBasicTabletMergeDag::fill_comment(char *buf, const int64_t buf_len) const +int ObBasicTabletMergeDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; - const char *merge_type = merge_type_to_str(merge_type_); - - if (OB_FAIL(databuff_printf(buf, buf_len, "%s dag: ls_id=%ld tablet_id=%ld", - merge_type, ls_id_.id(), tablet_id_.id()))) { - LOG_WARN("failed to fill comment", K(ret), K(ctx_)); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls basic table merge dag do not init", K(ret)); + } else { + const char *merge_type = merge_type_to_str(merge_type_); + if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + ls_id_.id(), + static_cast(tablet_id_.id()), + "merge_type", merge_type))) { + LOG_WARN("failed to fill info param", K(ret)); + } } - return ret; } @@ -600,7 +633,7 @@ int ObTabletMergeExecuteDag::direct_init_ctx( LOG_WARN("failed to alloc merge ctx", K(ret)); } else if (FALSE_IT(ctx_->ls_handle_ = ls_handle)) { // assign ls_handle } else if (FALSE_IT(ctx_->rebuild_seq_ = ls_handle.get_ls()->get_rebuild_seq())) { - } else if (OB_FAIL(create_first_task(result))) { + } else if (OB_FAIL(create_first_task(result, param.need_swap_tablet_flag_))) { LOG_WARN("failed to create first task", K(ret), K(result)); } else { is_inited_ = true; @@ -611,13 +644,14 @@ int ObTabletMergeExecuteDag::direct_init_ctx( } template int ObTabletMergeExecuteDag::create_first_task( - const ObGetMergeTablesResult &result) + const ObGetMergeTablesResult &result, + const bool need_swap_tablet_flag) { int ret = OB_SUCCESS; T *task = nullptr; if (OB_FAIL(alloc_task(task))) { STORAGE_LOG(WARN, "fail to alloc task", K(ret)); - } else if (OB_FAIL(task->init(result, *ctx_))) { + } else if (OB_FAIL(task->init(result, *ctx_, need_swap_tablet_flag))) { STORAGE_LOG(WARN, "failed to init prepare_task", K(ret)); } else if (OB_FAIL(add_task(*task))) { STORAGE_LOG(WARN, "fail to add task", K(ret), K_(ls_id), K_(tablet_id), K_(ctx)); @@ -625,16 +659,19 @@ int ObTabletMergeExecuteDag::create_first_task( return ret; } -int ObTabletMergeExecuteDag::create_first_task(const ObGetMergeTablesResult &result) +int ObTabletMergeExecuteDag::create_first_task( + const ObGetMergeTablesResult &result, + const bool need_swap_tablet_flag) { - return create_first_task(result); + return create_first_task(result, need_swap_tablet_flag); } ObTabletMergeExecutePrepareTask::ObTabletMergeExecutePrepareTask() : ObITask(ObITask::TASK_TYPE_SSTABLE_MERGE_PREPARE), is_inited_(false), + need_swap_tablet_flag_(false), ctx_(nullptr), - result_() + table_key_array_() {} ObTabletMergeExecutePrepareTask::~ObTabletMergeExecutePrepareTask() @@ -642,7 +679,8 @@ ObTabletMergeExecutePrepareTask::~ObTabletMergeExecutePrepareTask() int ObTabletMergeExecutePrepareTask::init( const ObGetMergeTablesResult &result, - ObTabletMergeCtx &ctx) + ObTabletMergeCtx &ctx, + const bool need_swap_tablet_flag) { int ret = OB_SUCCESS; if (IS_INIT) { @@ -651,7 +689,16 @@ int ObTabletMergeExecutePrepareTask::init( } else if (OB_FAIL(result_.assign(result))) { LOG_WARN("failed to assgin result", K(ret), K(result)); } else { + for (int64_t i = 0; OB_SUCC(ret) && i < result.handle_.get_count(); ++i) { + if (OB_FAIL(table_key_array_.push_back(result.handle_.get_table(i)->get_key()))) { + LOG_WARN("failed to push back key", K(ret)); + } + } + } + if (OB_SUCC(ret)) { ctx_ = &ctx; + result_.handle_.reset(); // clear tables handle, get sstable when execute after get tablet_handle + need_swap_tablet_flag_ = need_swap_tablet_flag; is_inited_ = true; } return ret; @@ -666,13 +713,8 @@ int ObTabletMergeExecutePrepareTask::process() } else if (OB_ISNULL(ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ctx is unexpected null", K(ret), K(ctx_)); - } else if (OB_FAIL(ctx_->ls_handle_.get_ls()->get_tablet( - ctx_->param_.tablet_id_, - ctx_->tablet_handle_, - storage::ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { - LOG_WARN("failed to get tablet", K(ret), K(ctx_->param_)); - } else if (OB_FAIL(ctx_->try_swap_tablet_handle(result_.handle_))) { // swap tablet before get schema ptr from tablet - LOG_WARN("failed to try swap tablet handle", K(ret)); + } else if (OB_FAIL(get_tablet_and_result())) { + LOG_WARN("failed to get tablet and result", K(ret)); } else if (OB_FAIL(ctx_->get_schema_and_gene_from_result(result_))) { LOG_WARN("failed to get schema and generage from result", K(ret), K_(result)); } else if (OB_FAIL(ctx_->init_merge_info())) { @@ -699,6 +741,68 @@ int ObTabletMergeExecutePrepareTask::process() return ret; } +int ObTabletMergeExecutePrepareTask::get_tablet_and_result() +{ + int ret = OB_SUCCESS; + if (need_swap_tablet_flag_) { + const ObTabletMapKey key(ctx_->param_.ls_id_, ctx_->param_.tablet_id_); + if (OB_FAIL(MTL(ObTenantMetaMemMgr *)->get_tablet_with_allocator( + WashTabletPriority::WTP_LOW, key, ctx_->allocator_, + ctx_->tablet_handle_, true /*force_alloc_new*/))) { + LOG_WARN("failed to get alloc tablet handle", K(ret), K(key)); + } else if (OB_FAIL(ctx_->tablet_handle_.get_obj()->clear_memtables_on_table_store())) { + LOG_WARN("failed to clear memtables on table_store", K(ret), K(ctx_->tablet_handle_)); + } + } else if (OB_FAIL(ctx_->ls_handle_.get_ls()->get_tablet( + ctx_->param_.tablet_id_, + ctx_->tablet_handle_, + 0, + storage::ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(ctx_->param_)); + } else if (OB_FAIL(ObTabletMergeChecker::check_need_merge(ctx_->param_.merge_type_, *ctx_->tablet_handle_.get_obj()))) { + if (OB_NO_NEED_MERGE != ret) { + LOG_WARN("failed to check need merge", K(ret)); + } + } + if (FAILEDx(get_result_by_table_key())) { + if (OB_NO_NEED_MERGE != ret) { + LOG_WARN("failed to get result by table key", K(ret)); + } + } + return ret; +} + +int ObTabletMergeExecutePrepareTask::get_result_by_table_key() +{ + int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + if (OB_FAIL(ctx_->tablet_handle_.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_UNLIKELY(!table_store_wrapper.get_member()->is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet store is invalid", K(ret), KPC(table_store_wrapper.get_member())); + } else { + ObITable *table = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && i < table_key_array_.count(); ++i) { + const ObITable::TableKey &table_key = table_key_array_.at(i); + if (OB_FAIL(table_store_wrapper.get_member()->get_table(table_key, table))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_NO_NEED_MERGE; + } else { + LOG_WARN("failed to get table from new table_store", K(ret)); + } + } else if (OB_FAIL(result_.handle_.add_sstable(table, table_store_wrapper.get_meta_handle()))) { + LOG_WARN("failed to add sstable into result", K(ret), KPC(table)); + } + } // end of for + if (OB_SUCC(ret) && result_.handle_.get_count() != table_key_array_.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected tables from current tablet", K(ret), K(table_key_array_), K(ctx_->tables_handle_)); + } + } + return ret; +} + int ObTxTableMergeExecutePrepareTask::prepare_compaction_filter() { int ret = OB_SUCCESS; @@ -742,9 +846,9 @@ int ObTxTableMergeExecutePrepareTask::prepare_compaction_filter() return ret; } -int ObTxTableMinorExecuteDag::create_first_task(const ObGetMergeTablesResult &result) +int ObTxTableMinorExecuteDag::create_first_task(const ObGetMergeTablesResult &result, const bool need_swap_tablet_flag) { - return ObTabletMergeExecuteDag::create_first_task(result); + return ObTabletMergeExecuteDag::create_first_task(result, need_swap_tablet_flag); } bool ObTabletMergeExecuteDag::operator == (const ObIDag &other) const @@ -816,6 +920,7 @@ int ObTabletMergePrepareTask::process() bool skip_rest_operation = false; DEBUG_SYNC(MERGE_PARTITION_TASK); + DEBUG_SYNC(AFTER_EMPTY_SHELL_TABLET_CREATE); if (IS_NOT_INIT) { ret = OB_NOT_INIT; @@ -838,8 +943,13 @@ int ObTabletMergePrepareTask::process() } else if (OB_FAIL(ctx->ls_handle_.get_ls()->get_tablet( ctx->param_.tablet_id_, ctx->tablet_handle_, - storage::ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + 0, + storage::ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("failed to get tablet", K(ret), K(ctx->param_)); + } else if (OB_FAIL(ObTabletMergeChecker::check_need_merge(ctx->param_.merge_type_, *ctx->tablet_handle_.get_obj()))) { + if (OB_NO_NEED_MERGE != ret) { + LOG_WARN("failed to check need merge", K(ret)); + } } else if (FALSE_IT(ctx->rebuild_seq_ = ctx->ls_handle_.get_ls()->get_rebuild_seq())) { } else if (OB_FAIL(build_merge_ctx(skip_rest_operation))) { if (OB_NO_NEED_MERGE != ret) { @@ -848,8 +958,8 @@ int ObTabletMergePrepareTask::process() } if (OB_FAIL(ret) || skip_rest_operation) { - } else if (!is_mini_merge(ctx->param_.merge_type_) - && OB_FAIL(ctx->try_swap_tablet_handle(ctx->tables_handle_))) { + } else if (is_major_merge_type(ctx->param_.merge_type_) + && OB_FAIL(ctx->try_swap_tablet_handle())) { LOG_WARN("failed to try swap tablet handle", K(ret)); } else if (OB_FAIL(ObBasicTabletMergeDag::generate_merge_task( *merge_dag_, *ctx, this))) { @@ -931,6 +1041,7 @@ int ObTabletMergePrepareTask::build_merge_ctx(bool &skip_rest_operation) } if (OB_FAIL(ret) || skip_rest_operation) { + } else if (FALSE_IT(ctx.merge_scn_ = ctx.scn_range_.end_scn_)) { } else if (OB_FAIL(ctx.init_merge_info())) { LOG_WARN("fail to init merge info", K(ret), K(tablet_id), K(ctx)); } else if (OB_FAIL(ctx.prepare_index_tree())) { @@ -1014,21 +1125,16 @@ int ObTabletMergeFinishTask::init() return ret; } -int ObTabletMergeFinishTask::create_sstable_after_merge(ObSSTable *&sstable) +int ObTabletMergeFinishTask::create_sstable_after_merge() { int ret = OB_SUCCESS; ObTabletMergeCtx &ctx = merge_dag_->get_ctx(); - if (ctx.merged_table_handle_.is_valid()) { + if (ctx.merged_sstable_.is_valid()) { if (OB_UNLIKELY(!is_major_merge_type(ctx.param_.merge_type_))) { ret = OB_ERR_SYS; LOG_ERROR("Unxpected valid merged table handle with other merge", K(ret), K(ctx)); - } else if (OB_FAIL(ctx.merged_table_handle_.get_sstable(sstable))) { - LOG_WARN("failed to get sstable", K(ret), KP(sstable)); - } else if (OB_ISNULL(sstable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sstable should not be NULL", K(ret), KP(sstable)); } - } else if (OB_FAIL(get_merged_sstable(ctx, sstable))) { + } else if (OB_FAIL(get_merged_sstable(ctx))) { LOG_WARN("failed to finish_merge_sstable", K(ret)); } return ret; @@ -1038,7 +1144,6 @@ int ObTabletMergeFinishTask::process() { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; - ObSSTable *sstable = NULL; ObTaskController::get().switch_task(share::ObTaskType::DATA_MAINTAIN); DEBUG_SYNC(MERGE_PARTITION_FINISH_TASK); @@ -1052,7 +1157,7 @@ int ObTabletMergeFinishTask::process() ObTabletID &tablet_id = ctx.param_.tablet_id_; ctx.time_guard_.click(ObCompactionTimeGuard::EXECUTE); - if (OB_FAIL(create_sstable_after_merge(sstable))) { + if (OB_FAIL(create_sstable_after_merge())) { LOG_WARN("failed to create sstable after merge", K(ret), K(tablet_id)); } else if (FALSE_IT(ctx.time_guard_.click(ObCompactionTimeGuard::CREATE_SSTABLE))) { } else if (OB_FAIL(add_sstable_for_merge(ctx))) { @@ -1077,9 +1182,11 @@ int ObTabletMergeFinishTask::process() *ctx.merge_progress_))) { STORAGE_LOG(WARN, "fail to analyze merge info", K(tmp_ret)); } - - if (OB_TMP_FAIL(ctx.merge_progress_->finish_merge_progress( - sstable->get_meta().get_basic_meta().get_total_macro_block_count()))) { + ObSSTableMetaHandle sst_meta_hdl; + if (OB_TMP_FAIL(ctx.merged_sstable_.get_meta(sst_meta_hdl))) { + STORAGE_LOG(WARN, "fail to get sstable meta handle", K(tmp_ret)); + } else if (OB_TMP_FAIL(ctx.merge_progress_->finish_merge_progress( + sst_meta_hdl.get_sstable_meta().get_total_macro_block_count()))) { STORAGE_LOG(WARN, "fail to update final merge progress", K(tmp_ret)); } } @@ -1087,22 +1194,22 @@ int ObTabletMergeFinishTask::process() if (NULL != merge_dag_) { + ObTabletMergeCtx &ctx = merge_dag_->get_ctx(); if (OB_FAIL(ret)) { - ObTabletMergeCtx &ctx = merge_dag_->get_ctx(); FLOG_WARN("sstable merge finish", K(ret), K(ctx), "task", *(static_cast(this))); } else { - merge_dag_->get_ctx().time_guard_.click(ObCompactionTimeGuard::DAG_FINISH); - (void)merge_dag_->get_ctx().collect_running_info(); + ctx.time_guard_.click(ObCompactionTimeGuard::DAG_FINISH); + (void)ctx.collect_running_info(); // ATTENTION! Critical diagnostic log, DO NOT CHANGE!!! - FLOG_INFO("sstable merge finish", K(ret), "merge_info", merge_dag_->get_ctx().get_merge_info(), - KPC(sstable), "compat_mode", merge_dag_->get_compat_mode(), K(merge_dag_->get_ctx().time_guard_)); + FLOG_INFO("sstable merge finish", K(ret), "merge_info", ctx.get_merge_info(), + K(ctx.merged_sstable_), "compat_mode", merge_dag_->get_compat_mode(), K(ctx.time_guard_)); } } return ret; } -int ObTabletMergeFinishTask::get_merged_sstable(ObTabletMergeCtx &ctx, ObSSTable *&sstable) +int ObTabletMergeFinishTask::get_merged_sstable(ObTabletMergeCtx &ctx) { int ret = OB_SUCCESS; @@ -1117,8 +1224,6 @@ int ObTabletMergeFinishTask::get_merged_sstable(ObTabletMergeCtx &ctx, ObSSTable if (OB_FAIL(ctx.merge_info_.create_sstable(ctx))) { LOG_WARN("fail to create sstable", K(ret), K(ctx)); - } else if (OB_FAIL(ctx.merged_table_handle_.get_sstable(sstable))) { - LOG_WARN("failed to get sstable after merge", K(ret)); } } return ret; @@ -1133,18 +1238,11 @@ int ObTabletMergeFinishTask::add_sstable_for_merge(ObTabletMergeCtx &ctx) if (OB_UNLIKELY(!ctx.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected error of merge ctx", K(ctx)); - } else if (is_mini_merge(merge_type) && !ctx.param_.tablet_id_.is_special_merge_tablet()) { - // if only one medium compaction info need store, just use ObUpdateTableStoreParam - // OR need to read from inner table to decide what need to keep after release memtable - if (OB_FAIL(ctx.get_medium_compaction_info_to_store())) { - LOG_WARN("failed to get medium compaction info", K(ret), K(ctx)); - } - } - - if (OB_SUCC(ret)) { - SCN clog_checkpoint_scn = is_mini_merge(merge_type) ? ctx.merged_table_handle_.get_table()->get_end_scn() : SCN::min_scn(); + } else { + SCN clog_checkpoint_scn = is_mini_merge(merge_type) ? ctx.merged_sstable_.get_end_scn() : SCN::min_scn(); // means finish current major/medium compaction - ObUpdateTableStoreParam param(ctx.merged_table_handle_, + ObArenaAllocator allocator; + ObUpdateTableStoreParam param(&(ctx.merged_sstable_), ctx.sstable_version_range_.snapshot_version_, ctx.sstable_version_range_.multi_version_start_, ctx.schema_ctx_.storage_schema_, @@ -1153,7 +1251,6 @@ int ObTabletMergeFinishTask::add_sstable_for_merge(ObTabletMergeCtx &ctx) clog_checkpoint_scn, is_minor_merge(ctx.param_.merge_type_)/*need_check_sstable*/, false/*allow_duplicate_sstable*/, - &ctx.merge_list_, ctx.param_.get_merge_type()); ObTablet *old_tablet = ctx.tablet_handle_.get_obj(); ObTabletHandle new_tablet_handle; @@ -1161,7 +1258,7 @@ int ObTabletMergeFinishTask::add_sstable_for_merge(ObTabletMergeCtx &ctx) param.multi_version_start_ = 1; } // for mini merge, read all msd from frozen memtable - if (is_mini_merge(merge_type) && OB_FAIL(read_msd_from_memtable(ctx, param))) { + if (is_mini_merge(merge_type) && OB_FAIL(read_msd_from_memtable(ctx, param, allocator))) { LOG_WARN("failed to read msd from memtable", K(ret), K(ctx)); } else if (OB_FAIL(ctx.ls_handle_.get_ls()->update_tablet_table_store( ctx.param_.tablet_id_, param, new_tablet_handle))) { @@ -1227,15 +1324,18 @@ int ObTabletMergeFinishTask::try_report_tablet_stat_after_mini(ObTabletMergeCtx return ret; } -int ObTabletMergeFinishTask::read_msd_from_memtable(ObTabletMergeCtx &ctx, ObUpdateTableStoreParam ¶m) +int ObTabletMergeFinishTask::read_msd_from_memtable( + ObTabletMergeCtx &ctx, + ObUpdateTableStoreParam ¶m, + ObArenaAllocator &allocator) { int ret = OB_SUCCESS; - if (OB_FAIL(traverse_all_memtables(ctx, ¶m.tx_data_, MultiSourceDataUnitType::TABLET_TX_DATA))) { + if (OB_FAIL(traverse_all_memtables(ctx, ¶m.tx_data_, MultiSourceDataUnitType::TABLET_TX_DATA, allocator))) { LOG_WARN("failed to read tx data from memtables", K(ret)); - } else if (OB_FAIL(traverse_all_memtables(ctx, ¶m.binding_info_, MultiSourceDataUnitType::TABLET_BINDING_INFO))) { + } else if (OB_FAIL(traverse_all_memtables(ctx, ¶m.binding_info_, MultiSourceDataUnitType::TABLET_BINDING_INFO, allocator))) { LOG_WARN("failed to read tx data from memtables", K(ret)); - } else if (OB_FAIL(traverse_all_memtables(ctx, ¶m.auto_inc_seq_, MultiSourceDataUnitType::TABLET_SEQ))) { + } else if (OB_FAIL(traverse_all_memtables(ctx, ¶m.autoinc_seq_, MultiSourceDataUnitType::TABLET_SEQ, allocator))) { LOG_WARN("failed to read tx data from memtables", K(ret)); } else { LOG_INFO("succeeded to read msd from memtable", K(ret), @@ -1243,7 +1343,7 @@ int ObTabletMergeFinishTask::read_msd_from_memtable(ObTabletMergeCtx &ctx, ObUpd "tablet_id", ctx.param_.tablet_id_, "tx_data", param.tx_data_, "binding_info", param.binding_info_, - "auto_inc_seq", param.auto_inc_seq_); + "autoinc_seq", param.autoinc_seq_); } return ret; @@ -1252,10 +1352,10 @@ int ObTabletMergeFinishTask::read_msd_from_memtable(ObTabletMergeCtx &ctx, ObUpd int ObTabletMergeFinishTask::traverse_all_memtables( ObTabletMergeCtx &ctx, ObIMultiSourceDataUnit *msd, - const MultiSourceDataUnitType &type) + const MultiSourceDataUnitType &type, + ObArenaAllocator &allocator) { int ret = OB_SUCCESS; - ObIArray &tables = ctx.tables_handle_.get_tables(); ObITable *table = nullptr; ObMemtable *memtable = nullptr; @@ -1264,20 +1364,20 @@ int ObTabletMergeFinishTask::traverse_all_memtables( LOG_WARN("invalid args", K(ret)); } - for (int64_t i = tables.count() - 1; OB_SUCC(ret) && i >= 0; --i) { - if (OB_ISNULL(table = tables.at(i))) { + for (int64_t i = ctx.tables_handle_.get_count() - 1; OB_SUCC(ret) && i >= 0; --i) { + if (OB_ISNULL(table = ctx.tables_handle_.get_table(i))) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("table is null", K(ret), K(tables), KP(table)); + LOG_WARN("table is null", K(ret), K(ctx.tables_handle_), KP(table)); } else if (OB_UNLIKELY(!table->is_memtable())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("table is not memtable", K(ret), K(tables), KPC(table)); + LOG_WARN("table is not memtable", K(ret), K(ctx.tables_handle_), KPC(table)); } else if (OB_UNLIKELY(!table->is_frozen_memtable())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("table is not frozen memtable", K(ret), K(tables), KPC(table)); + LOG_WARN("table is not frozen memtable", K(ret), K(ctx.tables_handle_), KPC(table)); } else if (table->is_data_memtable()) { memtable = static_cast(table); if (memtable->has_multi_source_data_unit(type)) { - if (OB_FAIL(memtable->get_multi_source_data_unit(msd, nullptr/*allocator*/))) { + if (OB_FAIL(memtable->get_multi_source_data_unit(msd, &allocator))) { LOG_WARN("failed to get msd from memtable", K(ret), K(type)); } else { // succeeded to get msd, just break diff --git a/src/storage/compaction/ob_tablet_merge_task.h b/src/storage/compaction/ob_tablet_merge_task.h index 43f47adc2..6b3c7596c 100644 --- a/src/storage/compaction/ob_tablet_merge_task.h +++ b/src/storage/compaction/ob_tablet_merge_task.h @@ -72,12 +72,16 @@ struct ObMergeParameter { int16_t sstable_logic_seq_; ObVersionRange version_range_; share::ObScnRange scn_range_; - const ObTableReadInfo *full_read_info_; // full read info of old tablet + const ObITableReadInfo *rowkey_read_info_; bool is_full_merge_; // full merge or increment merge, duplicated with merge_level compaction::ObCachedTransStateMgr *trans_state_mgr_; + share::SCN merge_scn_; + OB_INLINE bool is_major_merge() const { return storage::is_major_merge(merge_type_); } + OB_INLINE bool is_mini_merge() const { return storage::is_mini_merge(merge_type_); } + OB_INLINE bool need_checksum() const { return storage::is_major_merge(merge_type_); } TO_STRING_KV(KPC_(tables_handle), K_(merge_type), K_(merge_level), KP_(merge_schema), - K_(merge_range), K_(version_range), K_(scn_range), K_(is_full_merge)); + K_(merge_range), K_(version_range), K_(scn_range), K_(is_full_merge), K_(merge_scn)); private: DISALLOW_COPY_AND_ASSIGN(ObMergeParameter); }; @@ -95,10 +99,12 @@ struct ObTabletMergeDagParam : public share::ObIDagInitParam return is_tenant_major_merge_ ? MAJOR_MERGE : merge_type_; } - TO_STRING_KV("merge_type",merge_type_to_str(merge_type_), K_(merge_version), K_(ls_id), K_(tablet_id), KP(report_), K_(for_diagnose), K_(is_tenant_major_merge)); + TO_STRING_KV("merge_type",merge_type_to_str(merge_type_), K_(merge_version), K_(ls_id), K_(tablet_id), + KP(report_), K_(for_diagnose), K_(is_tenant_major_merge), K_(need_swap_tablet_flag)); bool for_diagnose_; bool is_tenant_major_merge_; + bool need_swap_tablet_flag_; storage::ObMergeType merge_type_; int64_t merge_version_; share::ObLSID ls_id_; @@ -159,16 +165,22 @@ public: virtual int process() override; private: - int create_sstable_after_merge(blocksstable::ObSSTable *&sstable); - int get_merged_sstable(); + int create_sstable_after_merge(); int check_data_checksum(); int check_empty_merge_valid(ObTabletMergeCtx &ctx); - int get_merged_sstable(ObTabletMergeCtx &ctx, blocksstable::ObSSTable *&sstable); + int get_merged_sstable(ObTabletMergeCtx &ctx); int add_sstable_for_merge(ObTabletMergeCtx &ctx); int try_schedule_compaction_after_mini(ObTabletMergeCtx &ctx, storage::ObTabletHandle &tablet_handle); int try_report_tablet_stat_after_mini(ObTabletMergeCtx &ctx); - int read_msd_from_memtable(ObTabletMergeCtx &ctx, storage::ObUpdateTableStoreParam ¶m); - int traverse_all_memtables(ObTabletMergeCtx &ctx, memtable::ObIMultiSourceDataUnit *msd, const memtable::MultiSourceDataUnitType &type); + int read_msd_from_memtable( + ObTabletMergeCtx &ctx, + storage::ObUpdateTableStoreParam ¶m, + ObArenaAllocator &allocator); + int traverse_all_memtables( + ObTabletMergeCtx &ctx, + memtable::ObIMultiSourceDataUnit *msd, + const memtable::MultiSourceDataUnitType &type, + ObArenaAllocator &allocator); private: bool is_inited_; ObBasicTabletMergeDag *merge_dag_; @@ -204,7 +216,7 @@ public: ObTabletMergeDagParam &get_param() { return param_; } virtual bool operator == (const ObIDag &other) const override; virtual int64_t hash() const override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual bool ignore_warning() override { @@ -281,14 +293,19 @@ class ObTabletMergeExecutePrepareTask: public share::ObITask public: ObTabletMergeExecutePrepareTask(); virtual ~ObTabletMergeExecutePrepareTask(); - int init(const ObGetMergeTablesResult &result, ObTabletMergeCtx &ctx); + int init(const ObGetMergeTablesResult &result, ObTabletMergeCtx &ctx, const bool need_swap_tablet_flag); virtual int process() override; protected: virtual int prepare_compaction_filter() { return OB_SUCCESS; } + int get_tablet_and_result(); + int get_result_by_table_key(); + const static int64_t TABLET_KEY_ARRAY_CNT = 20; bool is_inited_; + bool need_swap_tablet_flag_; ObTabletMergeCtx *ctx_; ObGetMergeTablesResult result_; + ObSEArray table_key_array_; }; // for minor merge @@ -310,7 +327,7 @@ public: const ObGetMergeTablesResult &result, storage::ObLSHandle &ls_handle); template - int create_first_task(const ObGetMergeTablesResult &result); + int create_first_task(const ObGetMergeTablesResult &result, const bool need_swap_tablet_flag); virtual bool operator == (const ObIDag &other) const override; const share::ObScnRange& get_merge_range() const { return merge_scn_range_; } @@ -318,7 +335,7 @@ public: private: int prepare_compaction(const ObGetMergeTablesResult &result); virtual int prepare_compaction_filter() { return OB_SUCCESS; } - virtual int create_first_task(const ObGetMergeTablesResult &result); + virtual int create_first_task(const ObGetMergeTablesResult &result, const bool need_swap_tablet_flag); DISALLOW_COPY_AND_ASSIGN(ObTabletMergeExecuteDag); share::ObScnRange merge_scn_range_; @@ -332,7 +349,7 @@ public: {} virtual ~ObTxTableMinorExecuteDag() = default; private: - virtual int create_first_task(const ObGetMergeTablesResult &result) override; + virtual int create_first_task(const ObGetMergeTablesResult &result, const bool need_swap_tablet_flag) override; DISALLOW_COPY_AND_ASSIGN(ObTxTableMinorExecuteDag); ObTransStatusFilter compaction_filter_; }; diff --git a/src/storage/compaction/ob_tenant_compaction_progress.cpp b/src/storage/compaction/ob_tenant_compaction_progress.cpp index 2ada26fa6..d1b6c9eaa 100644 --- a/src/storage/compaction/ob_tenant_compaction_progress.cpp +++ b/src/storage/compaction/ob_tenant_compaction_progress.cpp @@ -174,12 +174,13 @@ int ObTenantCompactionProgressMgr::loop_major_sstable_( } else if (ls->is_deleted()) { // do nothing } else { - ObLSTabletIterator tablet_iter(ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US); + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); const ObLSID &ls_id = ls->get_ls_id(); if (OB_FAIL(ls->get_tablet_svr()->build_tablet_iter(tablet_iter))) { LOG_WARN("failed to build ls tablet iter", K(ret), K(ls)); } else { ObTabletHandle tablet_handle; + ObTabletMemberWrapper table_store_wrapper; int tmp_ret = OB_SUCCESS; while (OB_SUCC(ret)) { // loop all tablets in ls if (OB_FAIL(tablet_iter.get_next_tablet(tablet_handle))) { @@ -193,14 +194,21 @@ int ObTenantCompactionProgressMgr::loop_major_sstable_( ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid tablet handle", K(ret), K(ls_id), K(tablet_handle)); } else if (!tablet_handle.get_obj()->get_tablet_meta().tablet_id_.is_special_merge_tablet()) { - ObSSTable *sstable = static_cast( - tablet_handle.get_obj()->get_table_store().get_major_sstables().get_boundary_table(true/*last*/)); - if (nullptr == sstable) { + ObSSTable *sstable = nullptr; + if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("faile to fetch table store", K(ret)); + } else if (OB_ISNULL(sstable = static_cast( + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/)))) { // do nothing } else if ((equal_flag && sstable->get_snapshot_version() == merge_snapshot_version) || (!equal_flag && sstable->get_snapshot_version() < merge_snapshot_version)) { - size += sstable->get_meta().get_basic_meta().get_total_macro_block_count() * DEFAULT_MACRO_BLOCK_SIZE; ++cnt; + ObSSTableMetaHandle sst_meta_hdl; + if (OB_FAIL(sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); + } else { + size += sst_meta_hdl.get_sstable_meta().get_total_macro_block_count() * DEFAULT_MACRO_BLOCK_SIZE; + } } } } // end of while diff --git a/src/storage/compaction/ob_tenant_freeze_info_mgr.cpp b/src/storage/compaction/ob_tenant_freeze_info_mgr.cpp index 708e20770..337596b63 100644 --- a/src/storage/compaction/ob_tenant_freeze_info_mgr.cpp +++ b/src/storage/compaction/ob_tenant_freeze_info_mgr.cpp @@ -24,7 +24,6 @@ #include "share/schema/ob_multi_version_schema_service.h" #include "share/schema/ob_schema_getter_guard.h" #include "share/schema/ob_tenant_schema_service.h" -#include "share/backup/ob_backup_info_mgr.h" #include "observer/ob_server_struct.h" #include "share/schema/ob_tenant_schema_service.h" #include "share/system_variable/ob_system_variable_alias.h" @@ -36,6 +35,7 @@ #include "storage/concurrency_control/ob_multi_version_garbage_collector.h" #include "storage/tx_storage/ob_ls_map.h" #include "storage/tx_storage/ob_ls_service.h" +#include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" namespace oceanbase { @@ -961,11 +961,17 @@ int ObTenantFreezeInfoMgr::ReloadTask::try_update_info() void ObTenantFreezeInfoMgr::ReloadTask::runTimerTask() { int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(refresh_merge_info())) { - LOG_WARN_RET(tmp_ret, "fail to refresh merge info", KR(tmp_ret)); - } - if (OB_TMP_FAIL(try_update_info())) { - LOG_WARN_RET(tmp_ret, "fail to try update info", KR(tmp_ret)); + if (!ObServerCheckpointSlogHandler::get_instance().is_started()) { + if (REACH_TIME_INTERVAL(10 * 1000 * 1000 /* 10s */)) { + LOG_WARN_RET(tmp_ret, "slog replay hasn't finished, this task can't start"); + } + } else { + if (OB_TMP_FAIL(refresh_merge_info())) { + LOG_WARN_RET(tmp_ret, "fail to refresh merge info", KR(tmp_ret)); + } + if (OB_TMP_FAIL(try_update_info())) { + LOG_WARN_RET(tmp_ret, "fail to try update info", KR(tmp_ret)); + } } } diff --git a/src/storage/compaction/ob_tenant_tablet_scheduler.cpp b/src/storage/compaction/ob_tenant_tablet_scheduler.cpp index 7e66bba6e..da4c057fd 100755 --- a/src/storage/compaction/ob_tenant_tablet_scheduler.cpp +++ b/src/storage/compaction/ob_tenant_tablet_scheduler.cpp @@ -33,10 +33,14 @@ #include "ob_server_compaction_event_history.h" #include "storage/compaction/ob_tenant_freeze_info_mgr.h" #include "storage/compaction/ob_medium_compaction_func.h" +#include "storage/compaction/ob_tablet_merge_checker.h" #include "storage/compaction/ob_tenant_compaction_progress.h" #include "storage/compaction/ob_server_compaction_event_history.h" #include "share/scn.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" +#include "storage/compaction/ob_sstable_merge_info_mgr.h" #include "storage/ddl/ob_ddl_merge_task.h" +#include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" namespace oceanbase { @@ -119,11 +123,17 @@ void ObTenantTabletScheduler::MergeLoopTask::runTimerTask() int ret = OB_SUCCESS; int64_t cost_ts = ObTimeUtility::fast_current_time(); ObCurTraceId::init(GCONF.self_addr_); - if (OB_FAIL(MTL(ObTenantTabletScheduler *)->schedule_all_tablets_minor())) { - LOG_WARN("Fail to merge all partition", K(ret)); + if (!ObServerCheckpointSlogHandler::get_instance().is_started()) { + if (REACH_TIME_INTERVAL(10 * 1000 * 1000 /* 10s */)) { + LOG_WARN("slog replay hasn't finished, this task can't start", K(ret)); + } + } else { + if (OB_FAIL(MTL(ObTenantTabletScheduler *)->schedule_all_tablets_minor())) { + LOG_WARN("Fail to merge all partition", K(ret)); + } + cost_ts = ObTimeUtility::fast_current_time() - cost_ts; + LOG_INFO("MergeLoopTask", K(cost_ts)); } - cost_ts = ObTimeUtility::fast_current_time() - cost_ts; - LOG_INFO("MergeLoopTask", K(cost_ts)); } void ObTenantTabletScheduler::MediumLoopTask::runTimerTask() @@ -131,26 +141,52 @@ void ObTenantTabletScheduler::MediumLoopTask::runTimerTask() int ret = OB_SUCCESS; int64_t cost_ts = ObTimeUtility::fast_current_time(); ObCurTraceId::init(GCONF.self_addr_); - if (OB_FAIL(MTL(ObTenantTabletScheduler *)->schedule_all_tablets_medium())) { - LOG_WARN("Fail to merge all partition", K(ret)); + if (!ObServerCheckpointSlogHandler::get_instance().is_started()) { + if (REACH_TIME_INTERVAL(10 * 1000 * 1000 /* 10s */)) { + LOG_WARN("slog replay hasn't finished, this task can't start", K(ret)); + } + } else { + if (OB_FAIL(MTL(ObTenantTabletScheduler *)->schedule_all_tablets_medium())) { + LOG_WARN("Fail to merge all partition", K(ret)); + } + cost_ts = ObTimeUtility::fast_current_time() - cost_ts; + LOG_INFO("MediumLoopTask", K(cost_ts)); } - cost_ts = ObTimeUtility::fast_current_time() - cost_ts; - LOG_INFO("MediumLoopTask", K(cost_ts)); } void ObTenantTabletScheduler::SSTableGCTask::runTimerTask() { int ret = OB_SUCCESS; - // use tenant config to loop minor && medium task - MTL(ObTenantTabletScheduler *)->reload_tenant_config(); + if (!ObServerCheckpointSlogHandler::get_instance().is_started()) { + if (REACH_TIME_INTERVAL(10 * 1000 * 1000 /* 10s */)) { + LOG_WARN("slog replay hasn't finished, this task can't start", K(ret)); + } + } else { + // use tenant config to loop minor && medium task + MTL(ObTenantTabletScheduler *)->reload_tenant_config(); + int64_t cost_ts = ObTimeUtility::fast_current_time(); + ObCurTraceId::init(GCONF.self_addr_); + if (OB_FAIL(MTL(ObTenantTabletScheduler *)->update_upper_trans_version_and_gc_sstable())) { + LOG_WARN("Fail to update upper_trans_version and gc sstable", K(ret)); + } + cost_ts = ObTimeUtility::fast_current_time() - cost_ts; + LOG_INFO("SSTableGCTask", K(cost_ts)); + } +} + +void ObTenantTabletScheduler::InfoPoolResizeTask::runTimerTask() +{ + int ret = OB_SUCCESS; int64_t cost_ts = ObTimeUtility::fast_current_time(); - ObCurTraceId::init(GCONF.self_addr_); - if (OB_FAIL(MTL(ObTenantTabletScheduler *)->update_upper_trans_version_and_gc_sstable())) { - LOG_WARN("Fail to update upper_trans_version and gc sstable", K(ret)); + if (OB_FAIL(MTL(ObTenantTabletScheduler *)->set_max())) { + LOG_WARN("Fail to resize info pool", K(ret)); + } + if (OB_FAIL(MTL(ObTenantTabletScheduler *)->gc_info())) { + LOG_WARN("Fail to gc info", K(ret)); } cost_ts = ObTimeUtility::fast_current_time() - cost_ts; - LOG_INFO("SSTableGCTask", K(cost_ts)); + LOG_INFO("InfoPoolResizeTask", K(cost_ts)); } constexpr ObMergeType ObTenantTabletScheduler::MERGE_TYPES[]; @@ -162,6 +198,7 @@ ObTenantTabletScheduler::ObTenantTabletScheduler() merge_loop_tg_id_(0), medium_loop_tg_id_(0), sstable_gc_tg_id_(0), + info_pool_resize_tg_id_(0), schedule_interval_(0), bf_queue_(), frozen_version_lock_(), @@ -172,11 +209,14 @@ ObTenantTabletScheduler::ObTenantTabletScheduler() merge_loop_task_(), medium_loop_task_(), sstable_gc_task_(), + info_pool_resize_task_(), fast_freeze_checker_(), enable_adaptive_compaction_(false), minor_ls_tablet_iter_(false/*is_major*/), medium_ls_tablet_iter_(true/*is_major*/), error_tablet_cnt_(0), + allow_schedule_medium_lock_(), + allow_schedule_medium_flag_(true), ls_locality_cache_() { STATIC_ASSERT(static_cast(NO_MAJOR_MERGE_TYPE_CNT) == ARRAYSIZEOF(MERGE_TYPES), "merge type array len is mismatch"); @@ -194,6 +234,7 @@ void ObTenantTabletScheduler::destroy() TG_DESTROY(merge_loop_tg_id_); TG_DESTROY(medium_loop_tg_id_); TG_DESTROY(sstable_gc_tg_id_); + TG_DESTROY(info_pool_resize_tg_id_); bf_queue_.destroy(); frozen_version_ = 0; merged_version_ = 0; @@ -202,6 +243,7 @@ void ObTenantTabletScheduler::destroy() merge_loop_tg_id_ = 0; medium_loop_tg_id_ = 0; sstable_gc_tg_id_ = 0; + info_pool_resize_tg_id_ = 0; schedule_interval_ = 0; minor_ls_tablet_iter_.reset(); medium_ls_tablet_iter_.reset(); @@ -271,6 +313,12 @@ int ObTenantTabletScheduler::start() LOG_WARN("failed to start sstable gc thread", K(ret)); } else if (OB_FAIL(TG_SCHEDULE(sstable_gc_tg_id_, sstable_gc_task_, SSTABLE_GC_INTERVAL, repeat))) { LOG_WARN("Fail to schedule sstable gc task", K(ret)); + } else if (OB_FAIL(TG_CREATE_TENANT(lib::TGDefIDs::InfoPoolResize, info_pool_resize_tg_id_))) { + LOG_WARN("failed to create info pool resize thread", K(ret)); + } else if (OB_FAIL(TG_START(info_pool_resize_tg_id_))) { + LOG_WARN("failed to start info pool resize thread", K(ret)); + } else if (OB_FAIL(TG_SCHEDULE(info_pool_resize_tg_id_, info_pool_resize_task_, INFO_POOL_RESIZE_INTERVAL, repeat))) { + LOG_WARN("Fail to schedule info pool resize task", K(ret)); } return ret; } @@ -316,6 +364,7 @@ void ObTenantTabletScheduler::stop() TG_STOP(merge_loop_tg_id_); TG_STOP(medium_loop_tg_id_); TG_STOP(sstable_gc_tg_id_); + TG_STOP(info_pool_resize_tg_id_); stop_major_merge(); } @@ -324,6 +373,7 @@ void ObTenantTabletScheduler::wait() TG_WAIT(merge_loop_tg_id_); TG_WAIT(medium_loop_tg_id_); TG_WAIT(sstable_gc_tg_id_); + TG_WAIT(info_pool_resize_tg_id_); } int ObTenantTabletScheduler::try_remove_old_table(ObLS &ls) @@ -332,7 +382,7 @@ int ObTenantTabletScheduler::try_remove_old_table(ObLS &ls) const uint64_t tenant_id = MTL_ID(); const share::ObLSID &ls_id = ls.get_ls_id(); // only need NORMAL tablet here - ObLSTabletIterator tablet_iter(ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US); + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_ALL_COMMITED); if (OB_FAIL(ls.build_tablet_iter(tablet_iter))) { LOG_WARN("failed to build ls tablet iter", K(ret), K(ls)); @@ -364,16 +414,22 @@ int ObTenantTabletScheduler::try_remove_old_table(ObLS &ls) } else if (OB_TMP_FAIL(tablet->check_need_remove_old_table(multi_version_start, need_remove))) { LOG_WARN("failed to check need remove old store", K(tmp_ret), K(multi_version_start), K(tablet_id)); } else if (need_remove) { - const ObStorageSchema &storage_schema = tablet->get_storage_schema(); - const int64_t rebuild_seq = ls.get_rebuild_seq(); - ObUpdateTableStoreParam param(tablet->get_snapshot_version(), multi_version_start, &storage_schema, rebuild_seq); - ObTabletHandle new_tablet_handle; // no use here - if (OB_TMP_FAIL(ls.update_tablet_table_store(tablet_id, param, new_tablet_handle))) { - LOG_WARN("failed to update table store", K(tmp_ret), K(param), K(tenant_id), K(ls_id), K(tablet_id)); + ObArenaAllocator tmp_arena("RmOldTblTmp"); + const ObStorageSchema *storage_schema = nullptr; + if (OB_TMP_FAIL(tablet->load_storage_schema(tmp_arena, storage_schema))) { + LOG_WARN("failed to load storage schema", K(tmp_ret), K(tablet)); } else { - FLOG_INFO("success to remove old table in table store", K(tmp_ret), K(tenant_id), K(ls_id), - K(tablet_id), K(multi_version_start), KPC(tablet)); + const int64_t rebuild_seq = ls.get_rebuild_seq(); + ObUpdateTableStoreParam param(tablet->get_snapshot_version(), multi_version_start, storage_schema, rebuild_seq); + ObTabletHandle new_tablet_handle; // no use here + if (OB_TMP_FAIL(ls.update_tablet_table_store(tablet_id, param, new_tablet_handle))) { + LOG_WARN("failed to update table store", K(tmp_ret), K(param), K(tenant_id), K(ls_id), K(tablet_id)); + } else { + FLOG_INFO("success to remove old table in table store", K(tmp_ret), K(tenant_id), K(ls_id), + K(tablet_id), K(multi_version_start), KPC(tablet)); + } } + ObTablet::free_storage_schema(tmp_arena, storage_schema); } } } @@ -467,6 +523,38 @@ int ObTenantTabletScheduler::check_ls_compaction_finish(const share::ObLSID &ls_ return ret; } +int ObTenantTabletScheduler::gc_info() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("The ObTenantTabletScheduler has not been inited", K(ret)); + } else if (OB_FAIL(MTL(ObScheduleSuspectInfoMgr *)->gc_info())) { + LOG_WARN("failed to gc in ObScheduleSuspectInfoMgr", K(ret)); + } else if (OB_FAIL(MTL(ObDagWarningHistoryManager *)->gc_info())) { + LOG_WARN("failed to gc in ObDagWarningHistoryManager", K(ret)); + } else if (OB_FAIL(MTL(ObTenantSSTableMergeInfoMgr *)->gc_info())) { + LOG_WARN("failed to gc in ObTenantSSTableMergeInfoMgr", K(ret)); + } + return ret; +} + +int ObTenantTabletScheduler::set_max() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("The ObTenantTabletScheduler has not been inited", K(ret)); + } else if (OB_FAIL(MTL(ObScheduleSuspectInfoMgr *)->set_max(ObScheduleSuspectInfoMgr::cal_max()))) { + LOG_WARN("failed to set_max int ObScheduleSuspectInfoMgr", K(ret)); + } else if (OB_FAIL(MTL(ObDagWarningHistoryManager *)->set_max(ObDagWarningHistoryManager::cal_max()))) { + LOG_WARN("failed to set_max in ObDagWarningHistoryManager", K(ret)); + } else if (OB_FAIL(MTL(ObTenantSSTableMergeInfoMgr *)->set_max(ObTenantSSTableMergeInfoMgr::cal_max()))) { + LOG_WARN("failed to set_max int ObTenantSSTableMergeInfoMgr", K(ret)); + } + return ret; +} + int ObTenantTabletScheduler::schedule_build_bloomfilter( const uint64_t table_id, const blocksstable::MacroBlockId ¯o_id, @@ -584,6 +672,18 @@ void ObTenantTabletScheduler::resume_major_merge() } } +void ObTenantTabletScheduler::stop_schedule_medium() +{ + obsys::ObWLockGuard lock_guard(allow_schedule_medium_lock_); + allow_schedule_medium_flag_ = false; +} + +void ObTenantTabletScheduler::resume_schedule_medium() +{ + obsys::ObWLockGuard lock_guard(allow_schedule_medium_lock_); + allow_schedule_medium_flag_ = true; +} + int64_t ObTenantTabletScheduler::get_frozen_version() const { obsys::ObRLockGuard frozen_version_guard(frozen_version_lock_); @@ -610,9 +710,13 @@ int ObTenantTabletScheduler::check_ls_state(ObLS &ls, bool &need_merge) int ret = OB_SUCCESS; need_merge = false; if (ls.is_deleted()) { - LOG_INFO("ls is deleted", K(ret), K(ls)); + if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INVERVAL)) { + LOG_INFO("ls is deleted", K(ret), K(ls)); + } } else if (ls.is_offline()) { - LOG_INFO("ls is offline", K(ret), K(ls)); + if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INVERVAL)) { + LOG_INFO("ls is offline", K(ret), K(ls)); + } } else { need_merge = true; } @@ -657,14 +761,20 @@ int ObTenantTabletScheduler::schedule_tablet_meta_major_merge( ObGetMergeTablesParam param; ObGetMergeTablesResult result; - const ObTabletTableStore &table_store = tablet_handle.get_obj()->get_table_store(); - ObITable *last_major = table_store.get_major_sstables().get_boundary_table(true/*last*/); + ObTabletMemberWrapper table_store_wrapper; + ObITable *last_major = nullptr; ObAdaptiveMergePolicy::AdaptiveMergeReason adaptive_merge_reason = ObAdaptiveMergePolicy::AdaptiveMergeReason::NONE; int64_t max_sync_medium_scn = 0; - - if (OB_FAIL(tablet_handle.get_obj()->get_max_sync_medium_scn(max_sync_medium_scn))) { + ObArenaAllocator allocator; + const compaction::ObMediumCompactionInfoList *medium_list = nullptr; + if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (FALSE_IT(last_major = table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/))) { + } else if (OB_FAIL(tablet_handle.get_obj()->get_max_sync_medium_scn(max_sync_medium_scn))) { LOG_WARN("failed to get max sync medium snapshot", K(ret), K(ls_id), K(tablet_id)); - } else if (tablet_handle.get_obj()->get_medium_compaction_info_list().size() > 0 + } else if (OB_FAIL(tablet_handle.get_obj()->read_medium_info_list(allocator, medium_list))) { + LOG_WARN("failed to read medium info list", K(ret), K(tablet_id)); + } else if ((nullptr != medium_list && medium_list->size() > 0) || nullptr == last_major || max_sync_medium_scn > last_major->get_snapshot_version()) { // do nothing @@ -778,6 +888,10 @@ int ObTenantTabletScheduler::schedule_tablet_ddl_major_merge(ObTabletHandle &tab if (!tablet_handle.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(tablet_handle)); + } else if (tablet_handle.get_obj()->get_tablet_meta().has_transfer_table()) { + if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INVERVAL)) { + LOG_INFO("The tablet in the transfer process does not do ddl major_merge", K(tablet_handle)); + } } else if (OB_FAIL(tablet_handle.get_obj()->get_ddl_kv_mgr(kv_mgr_handle))) { if (OB_ENTRY_NOT_EXIST != ret) { LOG_WARN("get ddl kv mgr failed", K(ret), K(tablet_handle)); @@ -844,7 +958,7 @@ int ObTenantTabletScheduler::schedule_ls_minor_merge( int64_t &schedule_tablet_cnt) { int ret = OB_SUCCESS; - ObLSTabletIterator tablet_iter(ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US); + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_ALL_COMMITED); bool need_merge = false; bool need_fast_freeze = false; ObLS &ls = *ls_handle.get_ls(); @@ -874,6 +988,10 @@ int ObTenantTabletScheduler::schedule_ls_minor_merge( LOG_WARN("invalid tablet handle", K(ret), K(ls_id), K(tablet_handle)); } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { } else if (FALSE_IT(tablet_id = tablet->get_tablet_meta().tablet_id_)) { + } else if (OB_FAIL(ObTabletMergeChecker::check_need_merge(ObMergeType::MINOR_MERGE, *tablet))) { + if (OB_NO_NEED_MERGE != ret) { + LOG_WARN("failed to check need merge", K(ret)); + } } else if (tablet_id.is_special_merge_tablet()) { // schedule minor merge for special tablet if (tablet_id.is_mini_and_minor_merge_tablet() @@ -946,6 +1064,7 @@ int ObTenantTabletScheduler::schedule_ls_medium_merge( ObTabletID tablet_id; ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; + ObTabletMemberWrapper table_store_wrapper; int tmp_ret = OB_SUCCESS; bool is_leader = false; bool could_major_merge = false; @@ -972,8 +1091,13 @@ int ObTenantTabletScheduler::schedule_ls_medium_merge( } else if (ls_locality.is_valid()) { if (!ls_locality.check_exist(GCTX.self_addr())) { locality_bad_case = true; + const int64_t buf_len = ObScheduleSuspectInfoMgr::EXTRA_INFO_LEN; + char tmp_str[buf_len] = "\0"; + ADD_COMPACTION_INFO_PARAM(tmp_str, buf_len, "leader_addr", GCTX.self_addr(), K(ls_locality)); ADD_SUSPECT_INFO(MEDIUM_MERGE, ls_id, ObTabletID(INT64_MAX), - "maybe bad case: ls leader is not in ls locality", "leader_addr", GCTX.self_addr(), K(ls_locality)); + ObSuspectInfoType::SUSPECT_LOCALITY_CHANGE, static_cast(0), "locality", tmp_str); + } else { + DEL_SUSPECT_INFO(MEDIUM_MERGE, ls_id, ObTabletID(INT64_MAX)); } } } @@ -984,6 +1108,14 @@ int ObTenantTabletScheduler::schedule_ls_medium_merge( if (!locality_bad_case) { DEL_SUSPECT_INFO(MEDIUM_MERGE, ls_id, ObTabletID(INT64_MAX)); } + { // start of RLock + // RLock to avoid changing allow_schedule_medium_flag_ when schedule current tablet + obsys::ObRLockGuard lock_guard(allow_schedule_medium_lock_); + if (!allow_schedule_medium_flag_) { // not allow schedule medium + if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INVERVAL)) { + LOG_INFO("tenant is blocking schedule medium", KR(ret), K(MTL_ID()), K(ls_id), K_(allow_schedule_medium_flag)); + } + } bool enable_adaptive_compaction = enable_adaptive_compaction_; ObTenantSysStat cur_sys_stat; @@ -998,6 +1130,8 @@ int ObTenantTabletScheduler::schedule_ls_medium_merge( while (OB_SUCC(ret) && schedule_tablet_cnt < SCHEDULE_TABLET_BATCH_CNT) { // loop all tablet in ls bool tablet_merge_finish = false; + // ATTENTION!!! load weak ts before get tablet + const share::SCN &weak_read_ts = ls.get_ls_wrs_handler()->get_ls_weak_read_ts(); if (OB_FAIL(medium_ls_tablet_iter_.get_next_tablet(ls_handle, tablet_handle))) { if (OB_ITER_END == ret) { ret = OB_SUCCESS; @@ -1009,15 +1143,23 @@ int ObTenantTabletScheduler::schedule_ls_medium_merge( ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid tablet handle", K(ret), K(ls_id), K(tablet_handle)); } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { + } else if (OB_FAIL(ObTabletMergeChecker::check_need_merge(ObMergeType::MEDIUM_MERGE, *tablet))) { + if (OB_NO_NEED_MERGE != ret) { + LOG_WARN("failed to check need merge", K(ret)); + } } else if (FALSE_IT(tablet_id = tablet->get_tablet_meta().tablet_id_)) { } else if (tablet_id.is_special_merge_tablet()) { // data tablet // do nothing } else { ++schedule_tablet_cnt; // inc tablet cnt - ObMediumCompactionScheduleFunc func(ls, tablet_handle); - ObITable *latest_major = tablet->get_table_store().get_major_sstables().get_boundary_table(true/*last*/); - if (OB_NOT_NULL(latest_major) && latest_major->get_snapshot_version() >= merge_version) { + ObMediumCompactionScheduleFunc func(ls, tablet_handle, weak_read_ts); + ObITable *latest_major = nullptr; + if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (FALSE_IT(latest_major = + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/))) { + } else if (OB_NOT_NULL(latest_major) && latest_major->get_snapshot_version() >= merge_version) { tablet_merge_finish = true; schedule_stats_.finish_cnt_++; @@ -1029,21 +1171,25 @@ int ObTenantTabletScheduler::schedule_ls_medium_merge( } } } + ObArenaAllocator allocator; + const compaction::ObMediumCompactionInfoList *medium_list = nullptr; LOG_DEBUG("schedule tablet medium", K(ret), K(ls_id), K(tablet_id), K(tablet_merge_finish), KPC(latest_major), K(merge_version), K(role), K(is_leader)); bool could_schedule_next_medium = true; bool check_medium_finish = false; + ObTabletHandle new_handle; if (!is_leader || OB_ISNULL(latest_major)) { // follower or no major: do nothing could_schedule_next_medium = false; - } else if (tablet->get_medium_compaction_info_list().need_check_finish()) { // need check finished - ObTabletHandle new_handle; + } else if (OB_FAIL(tablet_handle.get_obj()->read_medium_info_list(allocator, medium_list))) { + LOG_WARN("failed to read medium info list", K(ret), K(tablet_id)); + } else if (medium_list->need_check_finish()) { // need check finished if (OB_TMP_FAIL(func.check_medium_finish(ls_locality))) { LOG_WARN("failed to check medium finish", K(tmp_ret), K(ls_id), K(tablet_id)); } else if (FALSE_IT(check_medium_finish = true)) { } else if (FALSE_IT(func.get_tablet_handle(new_handle))) { } else if (ObTimeUtility::fast_current_time() * 1000 < - tablet->get_medium_compaction_info_list().get_wait_check_medium_scn() + WAIT_MEDIUM_CHECK_THRESHOLD) { + medium_list->get_wait_check_medium_scn() + WAIT_MEDIUM_CHECK_THRESHOLD) { // need wait 10 mins before schedule meta major } else if (enable_adaptive_compaction && OB_TMP_FAIL(schedule_tablet_meta_major_merge(ls_handle, new_handle))) { if (OB_SIZE_OVERFLOW != tmp_ret && OB_EAGAIN != tmp_ret) { @@ -1052,12 +1198,18 @@ int ObTenantTabletScheduler::schedule_ls_medium_merge( } } if (could_schedule_next_medium && could_major_merge - && (!tablet_merge_finish || enable_adaptive_compaction || check_medium_finish) - && OB_TMP_FAIL(func.schedule_next_medium_for_leader( - tablet_merge_finish ? 0 : merge_version, schedule_stats_))) { // schedule another round - LOG_WARN("failed to schedule next medium", K(tmp_ret), K(ls_id), K(tablet_id)); - } else { - schedule_stats_.schedule_cnt_++; + && (!tablet_merge_finish || enable_adaptive_compaction_ || check_medium_finish) + && allow_schedule_medium_flag_) { + if (OB_TMP_FAIL(func.schedule_next_medium_for_leader( + tablet_merge_finish ? 0 : merge_version, schedule_stats_))) { // schedule another round + if (OB_NOT_MASTER == tmp_ret) { + is_leader = false; + } else { + LOG_WARN("failed to schedule next medium", K(tmp_ret), K(ls_id), K(tablet_id)); + } + } else { + schedule_stats_.schedule_cnt_++; + } } if (could_major_merge && OB_TMP_FAIL(ObMediumCompactionScheduleFunc::schedule_tablet_medium_merge( @@ -1072,6 +1224,7 @@ int ObTenantTabletScheduler::schedule_ls_medium_merge( medium_ls_tablet_iter_.update_merge_finish(tablet_merge_finish); } } // end of while + } // end of RLock allow_schedule_medium_lock_ } // else return ret; } @@ -1090,9 +1243,10 @@ int ObTenantTabletScheduler::schedule_all_tablets_medium() // do nothing, should not loop tablets if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INVERVAL)) { LOG_INFO("compat_version is smaller than DATA_VERSION_4_1_0_0, cannot schedule medium", K(compat_version)); - ADD_SUSPECT_INFO(MEDIUM_MERGE, share::ObLSID(INT64_MAX), ObTabletID(INT64_MAX), - "invalid data version to schedule all tablets medium", - K(compat_version), "DATA_VERSION_4_1_0_0", DATA_VERSION_4_1_0_0); + if (OB_TMP_FAIL(ADD_SUSPECT_INFO(MEDIUM_MERGE, share::ObLSID(INT64_MAX), ObTabletID(INT64_MAX), + ObSuspectInfoType::SUSPECT_INVALID_DATA_VERSION, compat_version, DATA_VERSION_4_1_0_0))) { + LOG_WARN("failed to add suspect info", K(tmp_ret)); + } } } else if (!medium_ls_tablet_iter_.is_valid() && OB_FAIL(medium_ls_tablet_iter_.build_iter())) { LOG_WARN("failed to init iterator", K(ret)); @@ -1121,7 +1275,7 @@ int ObTenantTabletScheduler::schedule_all_tablets_medium() if (OB_TMP_FAIL(ls_locality_cache_.refresh_ls_locality())) { LOG_WARN("failed to refresh ls locality", K(tmp_ret)); ADD_SUSPECT_INFO(MEDIUM_MERGE, share::ObLSID(INT64_MAX), ObTabletID(INT64_MAX), - "refresh ls locality cache failed", "errno", tmp_ret); + ObSuspectInfoType::SUSPECT_FAILED_TO_REFRESH_LS_LOCALITY, tmp_ret); } } #ifdef ERRSIM @@ -1364,7 +1518,7 @@ int ObCompactionScheduleIterator::get_next_tablet( ret = OB_ITER_END; } else { const common::ObTabletID &tablet_id = tablet_ids_.at(tablet_idx_); - if (OB_FAIL(ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, tablet_handle, timeout_us_))) { + if (OB_FAIL(ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, tablet_handle, timeout_us_, ObMDSGetTabletMode::READ_ALL_COMMITED))) { if (OB_TABLET_NOT_EXIST == ret) { tablet_idx_++; } else { diff --git a/src/storage/compaction/ob_tenant_tablet_scheduler.h b/src/storage/compaction/ob_tenant_tablet_scheduler.h old mode 100644 new mode 100755 index e3c56f265..653e5c8f7 --- a/src/storage/compaction/ob_tenant_tablet_scheduler.h +++ b/src/storage/compaction/ob_tenant_tablet_scheduler.h @@ -63,7 +63,7 @@ public: ObCompactionScheduleIterator( const bool is_major, ObLSGetMod mod = ObLSGetMod::STORAGE_MOD, - const int64_t timeout_us = ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US) + const int64_t timeout_us = 0) : mod_(mod), is_major_(is_major), scan_finish_(false), @@ -172,7 +172,9 @@ public: void stop_major_merge(); void resume_major_merge(); OB_INLINE bool could_major_merge_start() const { return major_merge_status_; } - + void stop_schedule_medium(); // may block for waiting lock + void resume_schedule_medium(); + OB_INLINE bool could_schedule_medium() const { return allow_schedule_medium_flag_; } int64_t get_frozen_version() const; int64_t get_merged_version() const { return merged_version_; } int64_t get_inner_table_merged_scn() const { return ATOMIC_LOAD(&inner_table_merged_scn_); } @@ -184,9 +186,11 @@ public: int schedule_merge(const int64_t broadcast_version); int update_upper_trans_version_and_gc_sstable(); int check_ls_compaction_finish(const share::ObLSID &ls_id); - int schedule_all_tablets_minor(); + int gc_info(); + int set_max(); + // Schedule an async task to build bloomfilter for the given macro block. // The bloomfilter build task will be ignored if a same build task exists in the queue. int schedule_build_bloomfilter( @@ -263,6 +267,13 @@ private: virtual ~MediumLoopTask() = default; virtual void runTimerTask() override; }; + class InfoPoolResizeTask : public common::ObTimerTask + { + public: + InfoPoolResizeTask() = default; + virtual ~InfoPoolResizeTask() = default; + virtual void runTimerTask() override; + }; public: static const int64_t INIT_COMPACTION_SCN = 1; typedef common::ObSEArray MinorParallelResultArray; @@ -280,6 +291,7 @@ private: static constexpr ObMergeType MERGE_TYPES[] = { MINOR_MERGE, HISTORY_MINOR_MERGE}; static const int64_t SSTABLE_GC_INTERVAL = 30 * 1000 * 1000L; // 30s + static const int64_t INFO_POOL_RESIZE_INTERVAL = 30 * 1000 * 1000L; // 30s static const int64_t DEFAULT_HASH_MAP_BUCKET_CNT = 1009; static const int64_t DEFAULT_COMPACTION_SCHEDULE_INTERVAL = 30 * 1000 * 1000L; // 30s static const int64_t CHECK_WEAK_READ_TS_SCHEDULE_INTERVAL = 10 * 1000 * 1000L; // 10s @@ -296,6 +308,7 @@ private: int merge_loop_tg_id_; // thread int medium_loop_tg_id_; // thread int sstable_gc_tg_id_; // thread + int info_pool_resize_tg_id_; // thread int64_t schedule_interval_; common::ObDedupQueue bf_queue_; @@ -305,13 +318,16 @@ private: int64_t inner_table_merged_scn_; ObScheduleStatistics schedule_stats_; MergeLoopTask merge_loop_task_; - MediumLoopTask medium_loop_task_; +MediumLoopTask medium_loop_task_; SSTableGCTask sstable_gc_task_; + InfoPoolResizeTask info_pool_resize_task_; ObFastFreezeChecker fast_freeze_checker_; bool enable_adaptive_compaction_; ObCompactionScheduleIterator minor_ls_tablet_iter_; ObCompactionScheduleIterator medium_ls_tablet_iter_; int64_t error_tablet_cnt_; // for diagnose + mutable obsys::ObRWLock allow_schedule_medium_lock_; + mutable bool allow_schedule_medium_flag_; compaction::ObStorageLocalityCache ls_locality_cache_; }; diff --git a/src/storage/compaction/ob_tx_table_merge_task.cpp b/src/storage/compaction/ob_tx_table_merge_task.cpp index 61095f184..a8a24e327 100755 --- a/src/storage/compaction/ob_tx_table_merge_task.cpp +++ b/src/storage/compaction/ob_tx_table_merge_task.cpp @@ -110,11 +110,11 @@ int ObTxTableMergePrepareTask::pre_process_tx_data_table_merge_(ObTabletMergeCtx int ret = OB_SUCCESS; if (is_mini_merge(ctx.param_.merge_type_)) { - common::ObIArray &tables = ctx.tables_handle_.get_tables(); - for (int i = 0; OB_SUCC(ret) && i < tables.count(); i++) { - if (OB_FAIL(static_cast(tables.at(i))->pre_process_for_merge())) { + for (int i = 0; OB_SUCC(ret) && i < ctx.tables_handle_.get_count(); i++) { + ObITable *table = ctx.tables_handle_.get_table(i); + if (OB_FAIL(static_cast(table)->pre_process_for_merge())) { LOG_WARN("do pre process for tx data table merge failed.", K(ret), K(ctx.param_), - KPC(tables.at(i))); + KPC(table)); } } } @@ -150,7 +150,7 @@ int ObTxTableMergePrepareTask::inner_init_ctx(ObTabletMergeCtx &ctx, bool &skip_ } } else if (OB_FAIL(ctx.get_basic_info_from_result(get_merge_table_result))) { LOG_WARN("failed to set basic info to ctx", K(ret), K(get_merge_table_result), K(ctx)); - } else if (OB_FAIL(ctx.get_storage_schema_to_merge(get_merge_table_result.handle_, false/*get_schema_on_memtable*/))) { + } else if (OB_FAIL(ctx.get_storage_schema_to_merge(get_merge_table_result.handle_))) { LOG_WARN("failed to get storage schema", K(ret), K(get_merge_table_result), K(ctx)); } else if (LS_TX_DATA_TABLET == ctx.param_.tablet_id_ && OB_FAIL(pre_process_tx_data_table_merge_(ctx))) { diff --git a/src/storage/ddl/ob_build_index_task.cpp b/src/storage/ddl/ob_build_index_task.cpp index 9b5b8a163..5ac1564fc 100644 --- a/src/storage/ddl/ob_build_index_task.cpp +++ b/src/storage/ddl/ob_build_index_task.cpp @@ -19,6 +19,7 @@ #include "share/ob_get_compat_mode.h" #include "share/ob_ddl_task_executor.h" #include "share/schema/ob_tenant_schema_service.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "storage/compaction/ob_column_checksum_calculator.h" #include "storage/ddl/ob_ddl_redo_log_writer.h" #include "storage/ddl/ob_complement_data_task.h" @@ -610,6 +611,8 @@ int ObUniqueIndexChecker::wait_trans_end(ObIDag *dag) return ret; } +/* ObUniqueCheckingDag */ + ObUniqueCheckingDag::ObUniqueCheckingDag() : ObIDag(ObDagType::DAG_TYPE_UNIQUE_CHECKING), is_inited_(false), tenant_id_(OB_INVALID_TENANT_ID), tablet_id_(), is_scan_index_(false), schema_guard_(share::schema::ObSchemaMgrItem::MOD_UNIQ_CHECK), index_schema_(nullptr), data_table_schema_(nullptr), callback_(nullptr), @@ -745,7 +748,7 @@ int ObUniqueCheckingDag::alloc_global_index_task_callback( ObModIds::OB_CS_BUILD_INDEX))) { ret = OB_ALLOCATE_MEMORY_FAILED; STORAGE_LOG(WARN, "fail to allocate memory", K(ret)); - } else if (OB_ISNULL(callback = new (buf) ObGlobalUniqueIndexCallback(tablet_id, index_id, data_table_id, schema_version, task_id))) { + } else if (OB_ISNULL(callback = new (buf) ObGlobalUniqueIndexCallback(tenant_id_, tablet_id, index_id, data_table_id, schema_version, task_id))) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "fail to placement new local index callback", K(ret)); } else { @@ -768,20 +771,19 @@ int64_t ObUniqueCheckingDag::hash() const return hash_val; } -int ObUniqueCheckingDag::fill_comment(char *buf, const int64_t buf_len) const +int ObUniqueCheckingDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; int64_t index_id = 0; if (NULL != index_schema_) { index_id = index_schema_->get_table_id(); } - if (!is_inited_) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "not inited", K(ret)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, "unique check task: tablet_id=%s index_id=%ld", - to_cstring(tablet_id_), index_id))) { - STORAGE_LOG(WARN, "failed to fill comment", K(ret), K(tablet_id_), K(index_id)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(tablet_id_.id()), index_id))) { + STORAGE_LOG(WARN, "failed to fill info param", K(ret)); } return ret; } @@ -974,8 +976,8 @@ int ObSimpleUniqueCheckingTask::process() } ObGlobalUniqueIndexCallback::ObGlobalUniqueIndexCallback( - const common::ObTabletID &tablet_id, const uint64_t index_id, const uint64_t data_table_id, const int64_t schema_version, const int64_t task_id) - : tablet_id_(tablet_id), index_id_(index_id), data_table_id_(data_table_id), schema_version_(schema_version), task_id_(task_id) + const uint64_t tenant_id, const common::ObTabletID &tablet_id, const uint64_t index_id, const uint64_t data_table_id, const int64_t schema_version, const int64_t task_id) + : tenant_id_(tenant_id), tablet_id_(tablet_id), index_id_(index_id), data_table_id_(data_table_id), schema_version_(schema_version), task_id_(task_id) { } @@ -990,6 +992,7 @@ int ObGlobalUniqueIndexCallback::operator()(const int ret_code) arg.source_table_id_ = data_table_id_; arg.schema_version_ = schema_version_; arg.task_id_ = task_id_; + arg.tenant_id_ = tenant_id_; #ifdef ERRSIM if (OB_SUCC(ret)) { ret = OB_E(EventTable::EN_DDL_REPORT_REPLICA_BUILD_STATUS_FAIL) OB_SUCCESS; diff --git a/src/storage/ddl/ob_build_index_task.h b/src/storage/ddl/ob_build_index_task.h index beb636948..e61a6ed78 100644 --- a/src/storage/ddl/ob_build_index_task.h +++ b/src/storage/ddl/ob_build_index_task.h @@ -125,10 +125,11 @@ public: class ObGlobalUniqueIndexCallback : public ObIUniqueCheckingCompleteCallback { public: - ObGlobalUniqueIndexCallback(const common::ObTabletID &tablet_id, const uint64_t index_id, + ObGlobalUniqueIndexCallback(const uint64_t tenant_id, const common::ObTabletID &tablet_id, const uint64_t index_id, const uint64_t data_table_id, const int64_t schema_version, const int64_t task_id); int operator()(const int ret_code) override; private: + uint64_t tenant_id_; common::ObTabletID tablet_id_; uint64_t index_id_; uint64_t data_table_id_; @@ -179,8 +180,8 @@ public: common::ObTabletID get_tablet_id() const { return tablet_id_; } uint64_t get_tenant_id() const { return tenant_id_; } share::ObLSID get_ls_id() const { return ls_id_; } + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual bool ignore_warning() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual lib::Worker::CompatMode get_compat_mode() const override { return compat_mode_; } diff --git a/src/storage/ddl/ob_complement_data_task.cpp b/src/storage/ddl/ob_complement_data_task.cpp old mode 100644 new mode 100755 index d86948853..3a85255ed --- a/src/storage/ddl/ob_complement_data_task.cpp +++ b/src/storage/ddl/ob_complement_data_task.cpp @@ -23,6 +23,7 @@ #include "share/schema/ob_table_dml_param.h" #include "sql/engine/px/ob_granule_util.h" #include "sql/ob_sql_utils.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "storage/access/ob_multiple_scan_merge.h" #include "storage/blocksstable/ob_index_block_builder.h" #include "storage/compaction/ob_column_checksum_calculator.h" @@ -169,7 +170,7 @@ int ObComplementDataParam::split_task_ranges( ret = OB_EAGAIN; } } else if (OB_FALSE_IT(total_size = total_size / 1024 / 1024 /* Byte -> MB */)) { - } else if (OB_FAIL(ObGranuleUtil::compute_total_task_count(params, + } else if (OB_FAIL(ObGranuleUtil::compute_total_task_count(params, total_size, expected_task_count))) { LOG_WARN("compute total task count failed", K(ret)); @@ -184,7 +185,7 @@ int ObComplementDataParam::split_task_ranges( } } else if (multi_range_split_array.count() <= 0) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected range split arr", K(ret), K(total_size), K(hint_parallelism), + LOG_WARN("unexpected range split arr", K(ret), K(total_size), K(hint_parallelism), K(expected_task_count), K(params), K(multi_range_split_array)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < multi_range_split_array.count(); i++) { @@ -226,13 +227,14 @@ int ObComplementDataContext::init(const ObComplementDataParam ¶m, const ObDa int ret = OB_SUCCESS; void *builder_buf = nullptr; const ObSSTable *first_major_sstable = nullptr; + ObTabletMemberWrapper table_store_wrapper; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("ObComplementDataContext has already been inited", K(ret)); } else if (OB_UNLIKELY(!param.is_valid() || !desc.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), K(param), K(desc)); - } else if (OB_FAIL(ObTabletDDLUtil::check_and_get_major_sstable(param.ls_id_, param.dest_tablet_id_, first_major_sstable))) { + } else if (OB_FAIL(ObTabletDDLUtil::check_and_get_major_sstable(param.ls_id_, param.dest_tablet_id_, first_major_sstable, table_store_wrapper))) { LOG_WARN("check if major sstable exist failed", K(ret), K(param)); } else if (OB_FAIL(data_sstable_redo_writer_.init(param.ls_id_, param.dest_tablet_id_))) { @@ -411,39 +413,13 @@ int ObComplementDataDag::prepare_context() } else if (OB_ISNULL(hidden_table_schema)) { ret = OB_TABLE_NOT_EXIST; LOG_WARN("hidden table schema not exist", K(ret), K(param_)); - } else if (OB_FAIL(data_desc.init(*hidden_table_schema, + } else if (OB_FAIL(data_desc.init_as_index(*hidden_table_schema, param_.ls_id_, param_.dest_tablet_id_, MAJOR_MERGE, param_.snapshot_version_, param_.data_format_version_))) { LOG_WARN("fail to init data desc", K(ret)); - } else { - data_desc.row_column_count_ = data_desc.rowkey_column_count_ + 1; - data_desc.col_desc_array_.reset(); - data_desc.need_prebuild_bloomfilter_ = false; - data_desc.is_ddl_ = true; - if (OB_FAIL(data_desc.col_desc_array_.init(data_desc.row_column_count_))) { - LOG_WARN("failed to reserve column desc array", K(ret)); - } else if (OB_FAIL(hidden_table_schema->get_rowkey_column_ids(data_desc.col_desc_array_))) { - LOG_WARN("failed to get rowkey column ids", K(ret)); - } else if (OB_FAIL(storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(data_desc.col_desc_array_))) { - LOG_WARN("failed to add extra rowkey cols", K(ret)); - } else { - ObObjMeta meta; - meta.set_varchar(); - meta.set_collation_type(CS_TYPE_BINARY); - share::schema::ObColDesc col; - col.col_id_ = static_cast(data_desc.row_column_count_ + OB_APP_MIN_COLUMN_ID); - col.col_type_ = meta; - col.col_order_ = DESC; - if (OB_FAIL(data_desc.col_desc_array_.push_back(col))) { - LOG_WARN("failed to push back last col for index", K(ret), K(col)); - } - } - } - - if (OB_FAIL(ret)) { } else if (OB_FAIL(context_.init(param_, data_desc))) { LOG_WARN("fail to init context", K(ret), K(param_), K(data_desc)); } @@ -533,18 +509,20 @@ int ObComplementDataDag::report_replica_build_status() return ret; } -int ObComplementDataDag::fill_comment(char *buf, const int64_t buf_len) const +int ObComplementDataDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObComplementDataDag has not been initialized", K(ret)); - } else if (OB_UNLIKELY(!param_.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid param", K(ret), K(param_)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, "complement data task: logstream_id=%ld, source_tablet_id=%ld, dest_tablet_id=%ld, data_table_id=%ld, target_table_id=%ld, schema_version=%ld, snapshot_version=%ld", - param_.ls_id_.id(), param_.source_tablet_id_.id(), param_.dest_tablet_id_.id(), param_.source_table_id_, param_.dest_table_id_, param_.schema_version_, param_.snapshot_version_))) { - LOG_WARN("fail to fill comment", K(ret), K(param_)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + param_.ls_id_.id(), + static_cast(param_.source_tablet_id_.id()), + static_cast(param_.dest_tablet_id_.id()), + static_cast(param_.source_table_id_), + static_cast(param_.dest_table_id_), + param_.schema_version_, param_.snapshot_version_))) { + LOG_WARN("failed to fill info param", K(ret)); } return ret; } @@ -969,7 +947,9 @@ int ObComplementWriteTask::append_row(ObLocalScan &local_scan) { int ret = OB_SUCCESS; ObDataStoreDesc data_desc; - HEAP_VAR(ObMacroBlockWriter, writer) { + HEAP_VARS_3((ObMacroBlockWriter, writer), + (ObSchemaGetterGuard, schema_guard), + (ObRelativeTable, relative_table)) { ObArray report_col_checksums; ObArray report_col_ids; ObDDLSSTableRedoWriter sstable_redo_writer; @@ -1001,7 +981,6 @@ int ObComplementWriteTask::append_row(ObLocalScan &local_scan) } else if (OB_FAIL(macro_start_seq.set_parallel_degree(task_id_))) { LOG_WARN("set parallel degree failed", K(ret), K(task_id_)); } else { - ObSchemaGetterGuard schema_guard; const ObTableSchema *hidden_table_schema = nullptr; if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard( param_->tenant_id_, schema_guard, param_->schema_version_))) { @@ -1041,7 +1020,6 @@ int ObComplementWriteTask::append_row(ObLocalScan &local_scan) rowkey_column_cnt = hidden_table_schema->get_rowkey_column_num(); } - ObRelativeTable relative_table; ObTableSchemaParam schema_param(allocator); // Hack to prevent row reshaping from converting empty string to null. // @@ -1060,10 +1038,10 @@ int ObComplementWriteTask::append_row(ObLocalScan &local_scan) } else if (OB_FAIL(relative_table.init(&schema_param, param_->dest_tablet_id_))) { LOG_WARN("fail to init relative_table", K(ret), K(schema_param), K(param_->dest_tablet_id_)); } else if (OB_FAIL(ObRowReshapeUtil::malloc_rows_reshape_if_need( - allocator, data_desc.col_desc_array_, 1, relative_table, sql_mode_for_ddl_reshape, reshape_ptr))) { + allocator, data_desc.get_full_stored_col_descs(), 1, relative_table, sql_mode_for_ddl_reshape, reshape_ptr))) { LOG_WARN("failed to malloc row reshape", K(ret)); - } else if (OB_FAIL(datum_row.init(allocator, data_desc.col_desc_array_.count()))) { - LOG_WARN("failed to init datum row", K(ret), K(data_desc.col_desc_array_)); + } else if (OB_FAIL(datum_row.init(allocator, data_desc.get_full_stored_col_descs().count()))) { + LOG_WARN("failed to init datum row", K(ret), K(data_desc.get_full_stored_col_descs())); } } @@ -1095,9 +1073,9 @@ int ObComplementWriteTask::append_row(ObLocalScan &local_scan) // do nothing } else if (OB_FAIL(add_extra_rowkey(rowkey_column_cnt, extra_rowkey_cnt, *tmp_row))) { LOG_WARN("fail to add extra rowkey", K(ret)); - } else if (OB_FAIL(write_row_.to_store_row(data_desc.col_desc_array_, tmp_store_row))) { + } else if (OB_FAIL(write_row_.to_store_row(data_desc.get_full_stored_col_descs(), tmp_store_row))) { } else if (OB_FAIL(ObRowReshapeUtil::reshape_table_rows( - &tmp_store_row.row_val_, reshape_ptr, data_desc.col_desc_array_.count(), &reshaped_row, 1, sql_mode_for_ddl_reshape))) { + &tmp_store_row.row_val_, reshape_ptr, data_desc.get_full_stored_col_descs().count(), &reshaped_row, 1, sql_mode_for_ddl_reshape))) { LOG_WARN("failed to malloc and reshape row", K(ret)); } else if (OB_FAIL(datum_row.from_store_row(reshaped_row))) { STORAGE_LOG(WARN, "Failed to transfer store row ", K(ret), K(reshaped_row)); @@ -1116,7 +1094,7 @@ int ObComplementWriteTask::append_row(ObLocalScan &local_scan) } else if (OB_ISNULL(checksum_calculator = local_scan.get_checksum_calculator())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("checksum calculator is nullptr", K(ret), KP(checksum_calculator)); - } else if (OB_FAIL(checksum_calculator->calc_column_checksum(data_desc.col_desc_array_, &write_row_, nullptr, nullptr))) { + } else if (OB_FAIL(checksum_calculator->calc_column_checksum(data_desc.get_full_stored_col_descs(), &write_row_, nullptr, nullptr))) { LOG_WARN("fail to calc column checksum", K(ret), K(write_row_)); } else { t3 = ObTimeUtility::current_time(); @@ -1205,28 +1183,37 @@ int ObComplementMergeTask::process() } else if (OB_FAIL(guard.switch_to(param_->tenant_id_))) { LOG_WARN("switch to tenant failed", K(ret), K(param_->tenant_id_)); } else if (context_->is_major_sstable_exist_) { + ObTabletMemberWrapper table_store_wrapper; + const ObSSTable *first_major_sstable = nullptr; + ObSSTableMetaHandle sst_meta_hdl; if (OB_FAIL(MTL(ObLSService *)->get_ls(param_->ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) { LOG_WARN("failed to get log stream", K(ret), K(*param_)); } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, param_->dest_tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), K(*param_)); } else if (OB_ISNULL(tablet_handle.get_obj())) { ret = OB_ERR_SYS; LOG_WARN("tablet handle is null", K(ret), K(*param_)); + } else if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - const ObSSTable *first_major_sstable = static_cast( - tablet_handle.get_obj()->get_table_store().get_major_sstables().get_boundary_table(false/*first*/)); + const ObSSTable *first_major_sstable = static_cast( + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(false/*first*/)); + ObSSTableMetaHandle sst_meta_hdl; if (OB_ISNULL(first_major_sstable)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected error, major sstable shoud not be null", K(ret), K(*param_)); + } else if (OB_FAIL(first_major_sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); } else if (OB_FAIL(ObTabletDDLUtil::report_ddl_checksum(param_->ls_id_, param_->dest_tablet_id_, param_->dest_table_id_, 1 /* execution_id */, param_->task_id_, - first_major_sstable->get_meta().get_col_checksum()))) { + sst_meta_hdl.get_sstable_meta().get_col_checksum(), + sst_meta_hdl.get_sstable_meta().get_col_checksum_cnt()))) { LOG_WARN("report ddl column checksum failed", K(ret), K(*param_)); } else if (OB_FAIL(GCTX.ob_service_->submit_tablet_update_task(param_->tenant_id_, param_->ls_id_, param_->dest_tablet_id_))) { LOG_WARN("fail to submit tablet update task", K(ret), K(*param_)); @@ -1441,10 +1428,9 @@ int ObLocalScan::table_scan( transaction::ObTxDesc *tx_desc) { int ret = OB_SUCCESS; - const ObTableReadInfo &full_read_info = table_iter.tablet_handle_.get_obj()->get_full_read_info(); if (OB_FAIL(construct_column_schema(data_table_schema))) { LOG_WARN("fail to construct column schema", K(ret), K(col_params_)); - } else if (OB_FAIL(construct_access_param(data_table_schema, tablet_id, full_read_info))) { + } else if (OB_FAIL(construct_access_param(data_table_schema, tablet_id))) { LOG_WARN("fail to construct access param", K(ret), K(col_params_)); } else if (OB_FAIL(construct_range_ctx(query_flag, ls_id, tx_desc))) { LOG_WARN("fail to construct range ctx", K(ret), K(query_flag)); @@ -1503,8 +1489,7 @@ int ObLocalScan::construct_column_schema(const ObTableSchema &data_table_schema) //construct table access param int ObLocalScan::construct_access_param( const ObTableSchema &data_table_schema, - const ObTabletID &tablet_id, - const ObTableReadInfo &full_read_info) + const ObTabletID &tablet_id) { int ret = OB_SUCCESS; read_info_.reset(); @@ -1544,7 +1529,6 @@ int ObLocalScan::construct_access_param( data_table_schema.get_rowkey_column_num(), is_oracle_mode, extended_gc_.extended_col_ids_, // TODO @yiren, remove column id. - false /*is_multi_version_full*/, &cols_index, &col_params_))) { LOG_WARN("fail to init read info", K(ret)); @@ -1555,7 +1539,6 @@ int ObLocalScan::construct_access_param( access_param_.iter_param_.table_id_ = data_table_schema.get_table_id(); access_param_.iter_param_.out_cols_project_ = &output_projector; access_param_.iter_param_.read_info_ = &read_info_; - access_param_.iter_param_.full_read_info_ = &full_read_info; if (OB_FAIL(access_param_.iter_param_.refresh_lob_column_out_status())) { STORAGE_LOG(WARN, "Failed to refresh lob column", K(ret), K(access_param_.iter_param_)); } else { diff --git a/src/storage/ddl/ob_complement_data_task.h b/src/storage/ddl/ob_complement_data_task.h index 8eedeb669..20d0bdd43 100644 --- a/src/storage/ddl/ob_complement_data_task.h +++ b/src/storage/ddl/ob_complement_data_task.h @@ -146,7 +146,8 @@ public: ObComplementDataParam &get_param() { return param_; } ObComplementDataContext &get_context() { return context_; } void handle_init_failed_ret_code(int ret) { context_.complement_data_ret_ = ret; } - int fill_comment(char *buf, const int64_t buf_len) const override; + int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; + int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual lib::Worker::CompatMode get_compat_mode() const override { return param_.compat_mode_; } @@ -277,8 +278,7 @@ private: const share::schema::ObTableSchema &data_table_schema); int construct_access_param( const share::schema::ObTableSchema &data_table_schema, - const ObTabletID &tablet_id, - const ObTableReadInfo &full_read_info); + const ObTabletID &tablet_id); int construct_range_ctx(common::ObQueryFlag &query_flag, const share::ObLSID &ls_id, transaction::ObTxDesc *tx_desc); int construct_multiple_scan_merge(ObTablet &tablet, blocksstable::ObDatumRange &range); int construct_multiple_scan_merge( diff --git a/src/storage/ddl/ob_ddl_lock.cpp b/src/storage/ddl/ob_ddl_lock.cpp new file mode 100644 index 000000000..d814bd7d6 --- /dev/null +++ b/src/storage/ddl/ob_ddl_lock.cpp @@ -0,0 +1,750 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "share/tablet/ob_tablet_to_ls_operator.h" +#include "share/ob_ddl_common.h" +#include "observer/ob_inner_sql_connection.h" +#include "storage/ddl/ob_ddl_lock.h" +#include "storage/tablelock/ob_table_lock_rpc_struct.h" +#include "storage/tablelock/ob_lock_inner_connection_util.h" +#include "storage/tablelock/ob_lock_utils.h" + +using namespace oceanbase::transaction::tablelock; +using oceanbase::share::schema::ObTableSchema; +using oceanbase::observer::ObInnerSQLConnection; + +namespace oceanbase +{ +namespace storage +{ + +bool ObDDLLock::need_lock(const ObTableSchema &table_schema) +{ + const int64_t table_id = table_schema.get_table_id(); + return table_schema.is_user_table() + || table_schema.is_tmp_table() + || ObInnerTableLockUtil::in_inner_table_lock_white_list(table_id); +}; + +int ObDDLLock::lock_for_add_drop_index_in_trans( + const ObTableSchema &data_table_schema, + const ObTableSchema &index_schema, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = index_schema.get_tenant_id(); + const uint64_t data_table_id = data_table_schema.get_table_id(); + const uint64_t index_table_id = index_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + ObSEArray data_tablet_ids; + ObInnerSQLConnection *iconn = nullptr; + if (data_table_schema.is_user_hidden_table()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lock for rebuild hidden table index", K(ret)); + } else if (!need_lock(data_table_schema)) { + LOG_INFO("skip ddl lock", K(data_table_id)); + } else if (OB_FAIL(data_table_schema.get_tablet_ids(data_tablet_ids))) { + LOG_WARN("failed to get data tablet ids", K(ret)); + } else if (OB_FAIL(lock_table_lock_in_trans(tenant_id, data_table_id, data_tablet_ids, ROW_SHARE, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (index_schema.is_storage_local_index_table()) { + if (OB_FAIL(ObOnlineDDLLock::lock_table_in_trans(tenant_id, data_table_id, ROW_EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_tablets_in_trans(tenant_id, data_tablet_ids, ROW_EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock data table tablet", K(ret)); + } + } else { + if (OB_FAIL(ObOnlineDDLLock::lock_table_in_trans(tenant_id, data_table_id, ROW_SHARE, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table_in_trans(tenant_id, index_table_id, EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock index table", K(ret)); + } + } + ret = share::ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; + return ret; +} + +int ObDDLLock::lock_for_add_drop_index( + const ObTableSchema &data_table_schema, + const ObIArray *del_data_tablet_ids, + const ObTableSchema &index_schema, + const ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = index_schema.get_tenant_id(); + const uint64_t data_table_id = data_table_schema.get_table_id(); + const uint64_t index_table_id = index_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + ObSEArray data_tablet_ids; + ObInnerSQLConnection *iconn = nullptr; + if (data_table_schema.is_user_hidden_table()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lock for rebuild hidden table index", K(ret)); + } else if (!need_lock(data_table_schema)) { + LOG_INFO("skip ddl lock", K(data_table_id)); + } else { + if (OB_FAIL(data_table_schema.get_tablet_ids(data_tablet_ids))) { + LOG_WARN("failed to get data tablet ids", K(ret)); + } else if (nullptr != del_data_tablet_ids) { + ObArray tmp_tablet_ids; + if (OB_FAIL(get_difference(data_tablet_ids, *del_data_tablet_ids, tmp_tablet_ids))) { + LOG_WARN("failed to get diff tablet ids", K(ret)); + } else if (OB_FAIL(data_tablet_ids.assign(tmp_tablet_ids))) { + LOG_WARN("failed to assign data tablet ids", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (index_schema.is_storage_local_index_table()) { + if (OB_FAIL(lock_table_lock(tenant_id, data_table_id, data_tablet_ids, ROW_SHARE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table(tenant_id, data_table_id, ROW_EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_tablets(tenant_id, data_tablet_ids, ROW_EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock data table tablet", K(ret)); + } else if (OB_FAIL(check_tablet_in_same_ls(data_table_schema, index_schema, trans))) { + LOG_WARN("failed to check tablet in same ls", K(ret)); + } + } else { + if (OB_FAIL(ObOnlineDDLLock::lock_tablets(tenant_id, data_tablet_ids, ROW_EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock data table tablet", K(ret)); + } else if (OB_FAIL(lock_table_lock(tenant_id, data_table_id, data_tablet_ids, ROW_SHARE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table(tenant_id, data_table_id, ROW_SHARE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table(tenant_id, index_table_id, EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock index table", K(ret)); + } + } + } + ret = share::ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; + return ret; +} + +int ObDDLLock::unlock_for_add_drop_index( + const ObTableSchema &data_table_schema, + const ObTableSchema &index_schema, + const ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = index_schema.get_tenant_id(); + const uint64_t data_table_id = data_table_schema.get_table_id(); + const uint64_t index_table_id = index_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + ObSEArray data_tablet_ids; + bool some_lock_not_exist = false; + if (!need_lock(data_table_schema) || data_table_schema.is_user_hidden_table()) { + LOG_INFO("skip ddl lock", K(data_table_id)); + } else if (OB_FAIL(data_table_schema.get_tablet_ids(data_tablet_ids))) { + LOG_WARN("failed to get data tablet ids", K(ret)); + } else if (OB_FAIL(unlock_table_lock(tenant_id, data_table_id, data_tablet_ids, ROW_SHARE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to unlock data table", K(ret)); + } else if (index_schema.is_storage_local_index_table()) { + if (OB_FAIL(ObOnlineDDLLock::unlock_table(tenant_id, data_table_id, ROW_EXCLUSIVE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to unlock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_tablets(tenant_id, data_tablet_ids, ROW_EXCLUSIVE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to unlock data table", K(ret)); + } + } else { + if (OB_FAIL(ObOnlineDDLLock::unlock_table(tenant_id, data_table_id, ROW_SHARE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to unlock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_table(tenant_id, index_table_id, EXCLUSIVE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to unlock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_tablets(tenant_id, data_tablet_ids, ROW_EXCLUSIVE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to lock data table tablet", K(ret)); + } + } + return ret; +} + +int ObDDLLock::lock_for_add_lob_in_trans( + const ObTableSchema &data_table_schema, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = data_table_schema.get_tenant_id(); + const uint64_t data_table_id = data_table_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + ObSEArray data_tablet_ids; + if (!need_lock(data_table_schema)) { + LOG_INFO("skip ddl lock", K(data_table_id)); + } else if (OB_FAIL(data_table_schema.get_tablet_ids(data_tablet_ids))) { + LOG_WARN("failed to get tablet ids", K(ret)); + } else if (OB_FAIL(lock_table_lock_in_trans(tenant_id, data_table_id, data_tablet_ids, ROW_EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock tablet", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table_in_trans(tenant_id, data_table_id, ROW_EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_tablets_in_trans(tenant_id, data_tablet_ids, ROW_EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock data table tablets", K(ret)); + } + ret = share::ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; + return ret; +} + +int ObDDLLock::lock_for_add_partition_in_trans( + const ObTableSchema &table_schema, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const uint64_t table_id = table_schema.get_table_id(); + const ObArray no_tablet_ids; + const int64_t timeout_us = DEFAULT_TIMEOUT; + if (table_schema.is_global_index_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to add partition to global index", K(ret)); + } else if (need_lock(table_schema)) { + if (OB_FAIL(lock_table_lock_in_trans(tenant_id, table_id, no_tablet_ids, ROW_EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table_in_trans(tenant_id, table_id, SHARE, timeout_us, trans))) { + LOG_WARN("failed to lock ddl table", K(ret)); + } + } else { + LOG_INFO("skip ddl lock", K(ret), K(table_id)); + } + ret = share::ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; + return ret; +} + +int ObDDLLock::lock_for_drop_partition_in_trans( + const ObTableSchema &table_schema, + const ObIArray &del_tablet_ids, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const uint64_t table_id = table_schema.get_table_id(); + const uint64_t data_table_id = table_schema.get_data_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + if (table_schema.is_global_index_table()) { + ObArray no_tablet_ids; + if (OB_FAIL(lock_table_lock_in_trans(tenant_id, data_table_id, no_tablet_ids, SHARE, timeout_us, trans))) { + LOG_WARN("failed to lock table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table_in_trans(tenant_id, table_id, SHARE, timeout_us, trans))) { + LOG_WARN("failed to lock ddl table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_tablets_in_trans(tenant_id, del_tablet_ids, EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock ddl table", K(ret)); + } + } else if (need_lock(table_schema)) { + if (OB_FAIL(lock_table_lock_in_trans(tenant_id, table_id, del_tablet_ids, EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock table", K(ret)); + } + } else { + LOG_INFO("skip ddl lock", K(ret), K(table_id)); + } + ret = share::ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; + return ret; +} + +int ObDDLLock::lock_for_common_ddl_in_trans(const ObTableSchema &table_schema, ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const uint64_t table_id = table_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + ObSEArray tablet_ids; + if (!need_lock(table_schema)) { + LOG_INFO("skip ddl lock for non-user table", K(table_schema.get_table_id())); + } else if (OB_FAIL(table_schema.get_tablet_ids(tablet_ids))) { + LOG_WARN("failed to get tablet ids", K(ret)); + } else if (OB_FAIL(lock_table_lock_in_trans(tenant_id, table_id, tablet_ids, ROW_EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table_in_trans(tenant_id, table_id, ROW_SHARE, timeout_us, trans))) { + LOG_WARN("failed to lock ddl table", K(ret)); + } + ret = share::ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; + return ret; +} + +int ObDDLLock::lock_for_common_ddl( + const ObTableSchema &table_schema, + const ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const uint64_t table_id = table_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + ObArray no_tablet_ids; + if (!need_lock(table_schema)) { + LOG_INFO("skip ddl lock for non-user table", K(table_schema.get_table_id())); + } else if (OB_FAIL(lock_table_lock(tenant_id, table_id, no_tablet_ids, ROW_EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table(tenant_id, table_id, ROW_SHARE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock ddl table", K(ret)); + } + ret = share::ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; + return ret; +} + +int ObDDLLock::unlock_for_common_ddl( + const ObTableSchema &table_schema, + const ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const uint64_t table_id = table_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + ObArray no_tablet_ids; + bool some_lock_not_exist = false; + if (!need_lock(table_schema)) { + LOG_INFO("skip ddl lock for non-user table", K(table_schema.get_table_id())); + } else if (OB_FAIL(unlock_table_lock(tenant_id, table_id, no_tablet_ids, ROW_EXCLUSIVE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to unlock table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_table(tenant_id, table_id, ROW_SHARE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to unlock ddl table", K(ret)); + } + return ret; +} + +int ObDDLLock::lock_for_offline_ddl( + const ObTableSchema &table_schema, + const ObTableSchema *hidden_table_schema_to_check_bind, + const ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const uint64_t table_id = table_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + ObSEArray no_tablet_ids; + if (!need_lock(table_schema)) { + LOG_INFO("skip ddl lock for non-user table", K(table_id)); + } else if (OB_FAIL(lock_table_lock(tenant_id, table_id, no_tablet_ids, EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock table lock", K(ret)); + } else if (nullptr != hidden_table_schema_to_check_bind) { + if (OB_FAIL(check_tablet_in_same_ls(table_schema, *hidden_table_schema_to_check_bind, trans))) { + LOG_WARN("failed to check tablet in same ls", K(ret)); + } + } + ret = share::ObDDLUtil::is_table_lock_retry_ret_code(ret) ? OB_EAGAIN : ret; + return ret; +} + +int ObDDLLock::unlock_for_offline_ddl( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const int64_t timeout_us = DEFAULT_TIMEOUT; + bool some_lock_not_exist = false; + ObSEArray no_tablet_ids; + if (OB_FAIL(unlock_table_lock(tenant_id, table_id, no_tablet_ids, EXCLUSIVE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to lock table lock", K(ret)); + } + return ret; +} + +int ObDDLLock::lock_table_lock_in_trans( + const uint64_t tenant_id, + const uint64_t table_id, + const ObIArray &tablet_ids, + const ObTableLockMode lock_mode, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *iconn = nullptr; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } else if (tablet_ids.empty()) { + if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(tenant_id, table_id, lock_mode, timeout_us, iconn))) { + LOG_WARN("failed to lock table", K(ret)); + } + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); i++) { + if (OB_FAIL(ObInnerConnectionLockUtil::lock_tablet(tenant_id, table_id, tablet_ids.at(i), lock_mode, timeout_us, iconn))) { + LOG_WARN("failed to lock tablet", K(ret)); + } + } + } + return ret; +} + +int ObDDLLock::lock_table_lock( + const uint64_t tenant_id, + const uint64_t table_id, + const ObIArray &tablet_ids, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *iconn = nullptr; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } else if (tablet_ids.empty()) { + ObLockTableRequest arg; + arg.table_id_ = table_id; + arg.owner_id_ = lock_owner; + arg.lock_mode_ = lock_mode; + arg.op_type_ = ObTableLockOpType::OUT_TRANS_LOCK; + arg.timeout_us_ = timeout_us; + if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(tenant_id, arg, iconn))) { + LOG_WARN("failed to lock table", K(ret)); + } + } else { + ObLockTabletRequest arg; + arg.table_id_ = table_id; + arg.owner_id_ = lock_owner; + arg.lock_mode_ = lock_mode; + arg.op_type_ = ObTableLockOpType::OUT_TRANS_LOCK; + arg.timeout_us_ = timeout_us; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); i++) { + arg.tablet_id_ = tablet_ids.at(i); + if (OB_FAIL(ObInnerConnectionLockUtil::lock_tablet(tenant_id, arg, iconn))) { + LOG_WARN("failed to lock tablet", K(ret)); + } + } + } + return ret; +} + +int ObDDLLock::unlock_table_lock( + const uint64_t tenant_id, + const uint64_t table_id, + const ObIArray &tablet_ids, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans, + bool &some_lock_not_exist) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *iconn = nullptr; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } else if (tablet_ids.empty()) { + ObUnLockTableRequest arg; + arg.table_id_ = table_id; + arg.owner_id_ = lock_owner; + arg.lock_mode_ = lock_mode; + arg.op_type_ = ObTableLockOpType::OUT_TRANS_UNLOCK; + arg.timeout_us_ = timeout_us; + if (OB_FAIL(ObInnerConnectionLockUtil::unlock_table(tenant_id, arg, iconn))) { + if (OB_OBJ_LOCK_NOT_EXIST == ret) { + ret = OB_SUCCESS; + some_lock_not_exist = true; + LOG_INFO("table lock already unlocked", K(ret), K(arg)); + } else { + LOG_WARN("failed to unlock table", K(ret)); + } + } + } else { + ObUnLockTabletRequest arg; + arg.table_id_ = table_id; + arg.owner_id_ = lock_owner; + arg.lock_mode_ = lock_mode; + arg.op_type_ = ObTableLockOpType::OUT_TRANS_UNLOCK; + arg.timeout_us_ = timeout_us; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); i++) { + arg.tablet_id_ = tablet_ids.at(i); + if (OB_FAIL(ObInnerConnectionLockUtil::unlock_tablet(tenant_id, arg, iconn))) { + if (OB_OBJ_LOCK_NOT_EXIST == ret) { + ret = OB_SUCCESS; + some_lock_not_exist = true; + LOG_INFO("tablet lock already unlocked", K(ret), K(arg)); + } else { + LOG_WARN("failed to unlock tablet", K(ret)); + } + } + } + } + return ret; +} + +int ObDDLLock::check_tablet_in_same_ls( + const ObTableSchema &lhs_schema, + const ObTableSchema &rhs_schema, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = lhs_schema.get_tenant_id(); + ObSArray lhs_tablet_ids; + ObSArray rhs_tablet_ids; + ObSArray lhs_ls_ids; + ObSArray rhs_ls_ids; + if (OB_UNLIKELY(tenant_id != rhs_schema.get_tenant_id())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant id not match", K(ret)); + } else if (OB_FAIL(lhs_schema.get_tablet_ids(lhs_tablet_ids))) { + LOG_WARN("failed to get orig tablet ids", K(ret)); + } else if (OB_FAIL(rhs_schema.get_tablet_ids(rhs_tablet_ids))) { + LOG_WARN("failed to get index tablet ids", K(ret)); + } else if (OB_FAIL(share::ObTabletToLSTableOperator::batch_get_ls(trans, tenant_id, lhs_tablet_ids, lhs_ls_ids))) { + LOG_WARN("failed to get data tablet ls", K(ret)); + } else if (OB_FAIL(share::ObTabletToLSTableOperator::batch_get_ls(trans, tenant_id, rhs_tablet_ids, rhs_ls_ids))) { + LOG_WARN("failed to get data tablet ls", K(ret)); + } else if (!is_array_equal(lhs_ls_ids, rhs_ls_ids)) { + ret = OB_EAGAIN; + LOG_WARN("tablet not in same ls", K(ret), K(lhs_ls_ids), K(rhs_ls_ids)); + } + return ret; +} + +int ObOnlineDDLLock::lock_for_transfer_in_trans( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTabletID &tablet_id, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObSEArray tablet_ids; + if (OB_FAIL(tablet_ids.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table_in_trans(tenant_id, table_id, ROW_SHARE, timeout_us, trans))) { + LOG_WARN("failed to lock table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_tablets_in_trans(tenant_id, tablet_ids, EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock tablet", K(ret)); + } + return ret; +} + +int ObOnlineDDLLock::lock_for_transfer( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTabletID &tablet_id, + const ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObSEArray tablet_ids; + if (OB_FAIL(tablet_ids.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_table(tenant_id, table_id, ROW_SHARE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_tablets(tenant_id, tablet_ids, EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock tablet", K(ret)); + } + return ret; +} + +int ObOnlineDDLLock::unlock_for_transfer( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTabletID &tablet_id, + const ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + bool some_lock_not_exist = false; + ObSEArray tablet_ids; + if (OB_FAIL(tablet_ids.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_table(tenant_id, table_id, ROW_SHARE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to unlock ddl table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_tablets(tenant_id, tablet_ids, EXCLUSIVE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to unlock ddl tablet", K(ret)); + } + + if (OB_SUCC(ret) && some_lock_not_exist) { + ret = OB_OBJ_LOCK_NOT_EXIST; + } + return ret; +} + +int ObOnlineDDLLock::lock_table_in_trans( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTableLockMode lock_mode, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *iconn = nullptr; + ObLockObjRequest arg; + arg.obj_type_ = ObLockOBJType::OBJ_TYPE_ONLINE_DDL_TABLE; + arg.obj_id_ = table_id; + arg.timeout_us_ = timeout_us; + arg.op_type_ = ObTableLockOpType::IN_TRANS_COMMON_LOCK; + arg.lock_mode_ = lock_mode; + arg.owner_id_ = 0; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } else if (OB_FAIL(ObInnerConnectionLockUtil::lock_obj(tenant_id, arg, iconn))) { + LOG_WARN("failed to lock online ddl table in trans", K(ret)); + } + return ret; +} + +// TODO(lihongqin.lhq): batch rpc +int ObOnlineDDLLock::lock_tablets_in_trans( + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const ObTableLockMode lock_mode, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *iconn = nullptr; + ObLockObjRequest arg; + arg.obj_type_ = ObLockOBJType::OBJ_TYPE_ONLINE_DDL_TABLET; + arg.timeout_us_ = timeout_us; + arg.op_type_ = ObTableLockOpType::IN_TRANS_COMMON_LOCK; + arg.lock_mode_ = lock_mode; + arg.owner_id_ = 0; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); i++) { + arg.obj_id_ = tablet_ids.at(i).id(); + if (OB_FAIL(ObInnerConnectionLockUtil::lock_obj(tenant_id, arg, iconn))) { + LOG_WARN("failed to lock online ddl tablet in trans", K(ret)); + } + } + return ret; +} + +int ObOnlineDDLLock::lock_table( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *iconn = nullptr; + ObLockObjRequest arg; + arg.obj_type_ = ObLockOBJType::OBJ_TYPE_ONLINE_DDL_TABLE; + arg.obj_id_ = table_id; + arg.timeout_us_ = timeout_us; + arg.op_type_ = ObTableLockOpType::OUT_TRANS_LOCK; + arg.lock_mode_ = lock_mode; + arg.owner_id_ = lock_owner; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } else if (OB_FAIL(ObInnerConnectionLockUtil::lock_obj(tenant_id, arg, iconn))) { + LOG_WARN("failed to lock online ddl table", K(ret)); + } + return ret; +} + +// TODO(lihongqin.lhq): batch rpc +int ObOnlineDDLLock::lock_tablets( + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *iconn = nullptr; + ObLockObjRequest arg; + arg.obj_type_ = ObLockOBJType::OBJ_TYPE_ONLINE_DDL_TABLET; + arg.timeout_us_ = timeout_us; + arg.op_type_ = ObTableLockOpType::OUT_TRANS_LOCK; + arg.lock_mode_ = lock_mode; + arg.owner_id_ = lock_owner; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); i++) { + arg.obj_id_ = tablet_ids.at(i).id(); + if (OB_FAIL(ObInnerConnectionLockUtil::lock_obj(tenant_id, arg, iconn))) { + LOG_WARN("failed to lock online ddl tablet", K(ret)); + } + } + return ret; +} + +int ObOnlineDDLLock::unlock_table( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans, + bool &some_lock_not_exist) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *iconn = nullptr; + ObLockObjRequest arg; + arg.obj_type_ = ObLockOBJType::OBJ_TYPE_ONLINE_DDL_TABLE; + arg.obj_id_ = table_id; + arg.timeout_us_ = timeout_us; + arg.op_type_ = ObTableLockOpType::OUT_TRANS_UNLOCK; + arg.lock_mode_ = lock_mode; + arg.owner_id_ = lock_owner; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } else if (OB_FAIL(ObInnerConnectionLockUtil::unlock_obj(tenant_id, arg, iconn))) { + if (OB_OBJ_LOCK_NOT_EXIST == ret) { + ret = OB_SUCCESS; + some_lock_not_exist = true; + LOG_INFO("online ddl table already unlocked", K(ret), K(arg)); + } else { + LOG_WARN("failed to lock online ddl table", K(ret), K(arg)); + } + } + return ret; +} + +// TODO(lihongqin.lhq): batch rpc +int ObOnlineDDLLock::unlock_tablets( + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans, + bool &some_lock_not_exist) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *iconn = nullptr; + ObLockObjRequest arg; + arg.obj_type_ = ObLockOBJType::OBJ_TYPE_ONLINE_DDL_TABLET; + arg.timeout_us_ = timeout_us; + arg.op_type_ = ObTableLockOpType::OUT_TRANS_UNLOCK; + arg.lock_mode_ = lock_mode; + arg.owner_id_ = lock_owner; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); i++) { + arg.obj_id_ = tablet_ids.at(i).id(); + if (OB_FAIL(ObInnerConnectionLockUtil::unlock_obj(tenant_id, arg, iconn))) { + if (OB_OBJ_LOCK_NOT_EXIST == ret) { + ret = OB_SUCCESS; + some_lock_not_exist = true; + LOG_WARN("online ddl tablet already unlocked", K(ret), K(arg)); + } else { + LOG_WARN("failed to unlock online ddl tablet", K(ret), K(arg)); + } + } + } + return ret; +} + +} +} diff --git a/src/storage/ddl/ob_ddl_lock.h b/src/storage/ddl/ob_ddl_lock.h new file mode 100644 index 000000000..72d7261d8 --- /dev/null +++ b/src/storage/ddl/ob_ddl_lock.h @@ -0,0 +1,211 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_DDL_LOCK_H_ +#define OCEANBASE_STORAGE_OB_DDL_LOCK_H_ + +#include "lib/mysqlclient/ob_mysql_transaction.h" +#include "share/schema/ob_table_schema.h" +#include "observer/ob_inner_sql_connection.h" + +namespace oceanbase +{ +namespace storage +{ + +// handle both table lock and online ddl lock for ddl +class ObDDLLock { +public: + static bool need_lock(const share::schema::ObTableSchema &table_schema); + + static int lock_for_add_drop_index_in_trans( + const share::schema::ObTableSchema &data_table_schema, + const share::schema::ObTableSchema &index_schema, + ObMySQLTransaction &trans); + static int lock_for_add_drop_index( + const share::schema::ObTableSchema &data_table_schema, + const common::ObIArray *del_data_tablet_ids, + const share::schema::ObTableSchema &index_schema, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans); + static int unlock_for_add_drop_index( + const share::schema::ObTableSchema &data_table_schema, + const share::schema::ObTableSchema &index_schema, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans); + + static int lock_for_add_lob_in_trans( + const share::schema::ObTableSchema &data_table_schema, + ObMySQLTransaction &trans); + + static int lock_for_add_partition_in_trans( + const share::schema::ObTableSchema &table_schema, + ObMySQLTransaction &trans); + + static int lock_for_drop_partition_in_trans( + const share::schema::ObTableSchema &table_schema, + const ObIArray &del_tablet_ids, + ObMySQLTransaction &trans); + + static int lock_for_common_ddl_in_trans(const share::schema::ObTableSchema &table_schema, ObMySQLTransaction &trans); + static int lock_for_common_ddl( + const share::schema::ObTableSchema &table_schema, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans); + static int unlock_for_common_ddl( + const share::schema::ObTableSchema &table_schema, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans); + + static int lock_for_offline_ddl( + const share::schema::ObTableSchema &table_schema, + const share::schema::ObTableSchema *hidden_table_schema_to_check_bind, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans); + static int unlock_for_offline_ddl( + const uint64_t tenant_id, + const uint64_t table_id, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans); + +private: + static int lock_table_lock_in_trans( + const uint64_t tenant_id, + const uint64_t table_id, + const ObIArray &tablet_ids, + const transaction::tablelock::ObTableLockMode lock_mode, + const int64_t timeout_us, + ObMySQLTransaction &trans); + static int lock_table_lock( + const uint64_t tenant_id, + const uint64_t table_id, + const ObIArray &tablet_ids, + const transaction::tablelock::ObTableLockMode lock_mode, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans); + static int unlock_table_lock( + const uint64_t tenant_id, + const uint64_t table_id, + const ObIArray &tablet_ids, + const transaction::tablelock::ObTableLockMode lock_mode, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans, + bool &some_lock_not_exist); + static int check_tablet_in_same_ls( + const share::schema::ObTableSchema &lhs_schema, + const share::schema::ObTableSchema &rhs_schema, + ObMySQLTransaction &trans); + static constexpr int64_t DEFAULT_TIMEOUT = 0; +}; + +class ObOnlineDDLLock { +public: + /* + * acquire online ddl lock for transfer and release after trans end + * + * @return + * - OB_SUCCESS: successful + * - OB_TRY_LOCK_ROW_CONFLICT: failed and guarantee not locked + * - other: unknown, transaction must abort + */ + static int lock_for_transfer_in_trans( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTabletID &tablet_id, + const int64_t timeout_us, + ObMySQLTransaction &trans); + + /* + * acquire online ddl lock for transfer + * + * @return + * - OB_SUCCESS: successful + * - other: unknown, transaction must be abort + */ + static int lock_for_transfer( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTabletID &tablet_id, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans); + + /* + * release online ddl lock for transfer + * + * @return + * - OB_SUCCESS: all locks are unlocked here + * - OB_OBJ_LOCK_NOT_EXIST: at least one lock is not locked, others are unlocked here + * - other: unknown, transaction must be abort + */ + static int unlock_for_transfer( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTabletID &tablet_id, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans); + + static int lock_table_in_trans( + const uint64_t tenant_id, + const uint64_t table_id, + const transaction::tablelock::ObTableLockMode lock_mode, + const int64_t timeout_us, + ObMySQLTransaction &trans); + + static int lock_tablets_in_trans( + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const transaction::tablelock::ObTableLockMode lock_mode, + const int64_t timeout_us, + ObMySQLTransaction &trans); + + static int lock_table( + const uint64_t tenant_id, + const uint64_t table_id, + const transaction::tablelock::ObTableLockMode lock_mode, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans); + + static int lock_tablets( + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const transaction::tablelock::ObTableLockMode lock_mode, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans); + + static int unlock_table( + const uint64_t tenant_id, + const uint64_t table_id, + const transaction::tablelock::ObTableLockMode lock_mode, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans, + bool &some_lock_not_exist); + + static int unlock_tablets( + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const transaction::tablelock::ObTableLockMode lock_mode, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans, + bool &some_lock_not_exist); +}; + +} // namespace storage +} // namespace oceanbase +#endif diff --git a/src/storage/ddl/ob_ddl_merge_task.cpp b/src/storage/ddl/ob_ddl_merge_task.cpp old mode 100644 new mode 100755 index ebfc6e5b2..80aa58ede --- a/src/storage/ddl/ob_ddl_merge_task.cpp +++ b/src/storage/ddl/ob_ddl_merge_task.cpp @@ -18,6 +18,7 @@ #include "share/ob_get_compat_mode.h" #include "share/schema/ob_table_schema.h" #include "share/schema/ob_multi_version_schema_service.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "storage/blocksstable/ob_index_block_builder.h" #include "storage/blocksstable/ob_sstable_sec_meta_iterator.h" #include "storage/ddl/ob_tablet_ddl_kv_mgr.h" @@ -73,14 +74,13 @@ int ObDDLTableMergeDag::init_by_param(const share::ObIDagInitParam *param) } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, ddl_param_.tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_ALL_COMMITED))) { LOG_WARN("failed to get tablet", K(ret), K(ddl_param_)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet is null", K(ret), K(ddl_param_)); } else { - const ObStorageSchema &storage_schema = tablet->get_storage_schema(); - compat_mode_ = static_cast(storage_schema.compat_mode_); + compat_mode_ = tablet->get_tablet_meta().compat_mode_; is_inited_ = true; } } @@ -101,7 +101,7 @@ int ObDDLTableMergeDag::create_first_task() } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, ddl_param_.tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_ALL_COMMITED))) { LOG_WARN("get tablet failed", K(ret), K(ddl_param_)); } else if (OB_FAIL(tablet_handle.get_obj()->get_ddl_kv_mgr(ddl_kv_mgr_handle))) { if (OB_ENTRY_NOT_EXIST == ret) { @@ -176,12 +176,17 @@ int64_t ObDDLTableMergeDag::hash() const return ddl_param_.tablet_id_.hash(); } -int ObDDLTableMergeDag::fill_comment(char *buf, const int64_t buf_len) const +int ObDDLTableMergeDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; - if (OB_FAIL(databuff_printf(buf, buf_len, "ddl table merge task, logstream_id=%ld tablet_id=%ld rec_scn=%lu", - ddl_param_.ls_id_.id(), ddl_param_.tablet_id_.id(), ddl_param_.rec_scn_.get_val_for_inner_table_field()))) { - LOG_WARN("fill comment for ddl table merge dag failed", K(ret), K(ddl_param_)); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObDDLTableMergeDag has not been initialized", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + ddl_param_.ls_id_.id(), + static_cast(ddl_param_.tablet_id_.id()), + static_cast(ddl_param_.rec_scn_.get_val_for_inner_table_field())))) { + LOG_WARN("failed to fill info param", K(ret)); } return ret; } @@ -189,7 +194,7 @@ int ObDDLTableMergeDag::fill_comment(char *buf, const int64_t buf_len) const int ObDDLTableMergeDag::fill_dag_key(char *buf, const int64_t buf_len) const { int ret = OB_SUCCESS; - if (OB_FAIL(databuff_printf(buf, buf_len, "ddl table merge task: logstream_id=%ld tablet_id=%ld rec_scn=%lu", + if (OB_FAIL(databuff_printf(buf, buf_len, "ddl table merge task: ls_id=%ld, tablet_id=%ld, rec_scn=%lu", ddl_param_.ls_id_.id(), ddl_param_.tablet_id_.id(), ddl_param_.rec_scn_.get_val_for_inner_table_field()))) { LOG_WARN("fill dag key for ddl table merge dag failed", K(ret), K(ddl_param_)); } @@ -252,7 +257,7 @@ int ObDDLTableDumpTask::process() } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_ALL_COMMITED))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id_)); } else if (OB_FAIL(tablet_handle.get_obj()->get_ddl_kv_mgr(ddl_kv_mgr_handle))) { if (OB_ENTRY_NOT_EXIST == ret) { @@ -327,8 +332,11 @@ int ObDDLTableMergeTask::process() ObTabletHandle tablet_handle; ObDDLKvMgrHandle ddl_kv_mgr_handle; ObLSHandle ls_handle; - ObTablesHandleArray ddl_sstable_handles; + ObTableStoreIterator ddl_table_iter; + ObTabletMemberWrapper table_store_wrapper; const uint64_t tenant_id = MTL_ID(); + common::ObArenaAllocator allocator("DDLMergeTask"); + ObSSTable compact_sstable; ObSSTable *sstable = nullptr; bool skip_major_process = false; if (OB_UNLIKELY(!is_inited_)) { @@ -339,7 +347,7 @@ int ObDDLTableMergeTask::process() } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, merge_param_.tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_ALL_COMMITED))) { LOG_WARN("failed to get tablet", K(ret), K(merge_param_)); } else if (OB_FAIL(tablet_handle.get_obj()->get_ddl_kv_mgr(ddl_kv_mgr_handle))) { if (OB_ENTRY_NOT_EXIST == ret) { @@ -348,9 +356,9 @@ int ObDDLTableMergeTask::process() } else { LOG_WARN("get ddl kv mgr failed", K(ret), K(merge_param_)); } - } else if (OB_FAIL(tablet_handle.get_obj()->get_ddl_sstable_handles(ddl_sstable_handles))) { + } else if (OB_FAIL(tablet_handle.get_obj()->get_ddl_sstables(ddl_table_iter))) { LOG_WARN("get ddl sstable handles failed", K(ret)); - } else if (ddl_sstable_handles.get_count() >= MAX_DDL_SSTABLE || merge_param_.is_commit_) { + } else if (ddl_table_iter.count() >= MAX_DDL_SSTABLE || merge_param_.is_commit_) { DEBUG_SYNC(BEFORE_DDL_TABLE_MERGE_TASK); #ifdef ERRSIM static int64_t counter = 0; @@ -361,14 +369,19 @@ int ObDDLTableMergeTask::process() #endif ObTabletDDLParam ddl_param; - ObTableHandleV2 table_handle; bool is_data_complete = false; const ObSSTable *first_major_sstable = nullptr; - if (OB_FAIL(ObTabletDDLUtil::check_and_get_major_sstable(merge_param_.ls_id_, merge_param_.tablet_id_, first_major_sstable))) { + if (OB_FAIL(ObTabletDDLUtil::check_and_get_major_sstable( + merge_param_.ls_id_, merge_param_.tablet_id_, first_major_sstable, table_store_wrapper))) { LOG_WARN("check if major sstable exist failed", K(ret)); } else if (nullptr != first_major_sstable) { LOG_INFO("major sstable has been created before", K(merge_param_), K(ddl_param.table_key_)); - sstable = static_cast(tablet_handle.get_obj()->get_table_store().get_major_sstables().get_boundary_table(false/*first*/)); + if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("failed to fetch table store", K(ret)); + } else { + sstable = static_cast( + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(false/*first*/)); + } } else if (tablet_handle.get_obj()->get_tablet_meta().table_store_flag_.with_major_sstable()) { skip_major_process = true; LOG_INFO("tablet me says with major but no major, meaning its a migrated deleted tablet, skip"); @@ -380,15 +393,16 @@ int ObDDLTableMergeTask::process() } else if (merge_param_.start_scn_ > SCN::min_scn() && merge_param_.start_scn_ < ddl_param.start_scn_) { ret = OB_TASK_EXPIRED; LOG_INFO("ddl merge task expired, do nothing", K(merge_param_), "new_start_scn", ddl_param.start_scn_); - } else if (OB_FAIL(ObTabletDDLUtil::compact_ddl_sstable(ddl_sstable_handles, - tablet_handle.get_obj()->get_index_read_info(), + } else if (OB_FAIL(ObTabletDDLUtil::compact_ddl_sstable(ddl_table_iter, + tablet_handle.get_obj()->get_rowkey_read_info(), merge_param_.is_commit_, merge_param_.rec_scn_, ddl_param, - table_handle))) { + allocator, + compact_sstable))) { LOG_WARN("compact sstables failed", K(ret)); } else { - sstable = static_cast(table_handle.get_table()); + sstable = &compact_sstable; } if (OB_SUCC(ret) && merge_param_.rec_scn_.is_valid_and_not_min()) { @@ -421,40 +435,52 @@ int ObDDLTableMergeTask::process() } // the input ddl sstable is sorted with start_scn -int ObTabletDDLUtil::check_data_integrity(const ObTablesHandleArray &ddl_sstables, +int ObTabletDDLUtil::check_data_integrity(ObTableStoreIterator &ddl_sstable_iter, const SCN &start_scn, const SCN &prepare_scn, bool &is_data_complete) { int ret = OB_SUCCESS; is_data_complete = false; - if (OB_UNLIKELY(!start_scn.is_valid_and_not_min() || !prepare_scn.is_valid_and_not_min() || prepare_scn <= start_scn)) { + if (OB_UNLIKELY(!start_scn.is_valid_and_not_min() || !prepare_scn.is_valid_and_not_min() + || prepare_scn <= start_scn)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(ddl_sstables.get_count()), K(start_scn), K(prepare_scn)); - } else if (ddl_sstables.empty()) { + LOG_WARN("invalid argument", K(ret), K(ddl_sstable_iter.count()), K(start_scn), K(prepare_scn)); + } else if (0 == ddl_sstable_iter.count()) { is_data_complete = false; } else { - const ObSSTable *first_ddl_sstable = static_cast(ddl_sstables.get_tables().at(0)); - const ObSSTable *last_ddl_sstable = static_cast(ddl_sstables.get_tables().at(ddl_sstables.get_count() - 1)); - if (first_ddl_sstable->get_start_scn() != SCN::scn_dec(start_scn)) { + ObITable *first_ddl_sstable = nullptr; + ObITable *last_ddl_sstable = nullptr; + if (OB_FAIL(ddl_sstable_iter.get_boundary_table(false, first_ddl_sstable))) { + LOG_WARN("fail to get first ddl sstable", K(ret)); + } else if (OB_FAIL(ddl_sstable_iter.get_boundary_table(true, last_ddl_sstable))) { + LOG_WARN("fail to get last ddl sstable", K(ret)); + } else if (first_ddl_sstable->get_start_scn() != SCN::scn_dec(start_scn)) { LOG_INFO("start log ts not match", K(first_ddl_sstable->get_key()), K(start_scn)); } else if (last_ddl_sstable->get_end_scn() != prepare_scn) { LOG_INFO("prepare log ts not match", K(last_ddl_sstable->get_key()), K(prepare_scn)); + } else if (1 == ddl_sstable_iter.count()) { + // Only one ddl table, skip + is_data_complete = true; } else { is_data_complete = true; SCN last_end_scn = first_ddl_sstable->get_end_scn(); - for (int64_t i = 1; OB_SUCC(ret) && i < ddl_sstables.get_count(); ++i) { - const ObSSTable *cur_ddl_sstable = static_cast(ddl_sstables.get_tables().at(i)); - if (cur_ddl_sstable->get_start_scn() < last_end_scn) { - last_end_scn = SCN::max(last_end_scn, cur_ddl_sstable->get_end_scn()); - } else if (cur_ddl_sstable->get_start_scn() == last_end_scn) { + ObITable *cur_ddl_sstable = nullptr; + while (OB_SUCC(ddl_sstable_iter.get_next(cur_ddl_sstable))) { + if (OB_ISNULL(cur_ddl_sstable) || OB_UNLIKELY(!cur_ddl_sstable->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, table is nullptr", K(ret), KPC(cur_ddl_sstable)); + } else if (cur_ddl_sstable->get_start_scn() <= last_end_scn) { last_end_scn = SCN::max(last_end_scn, cur_ddl_sstable->get_end_scn()); } else { is_data_complete = false; - LOG_INFO("ddl sstable not continue", K(i), K(cur_ddl_sstable->get_key()), K(last_end_scn)); + LOG_INFO("ddl sstable not continue", K(cur_ddl_sstable->get_key()), K(last_end_scn)); break; } } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } } } return ret; @@ -494,6 +520,8 @@ int ObTabletDDLUtil::prepare_index_data_desc(const share::ObLSID &ls_id, ObLSService *ls_service = MTL(ObLSService *); ObLSHandle ls_handle; ObTabletHandle tablet_handle; + ObArenaAllocator tmp_arena("DDLIdxDescTmp"); + const ObStorageSchema *storage_schema = nullptr; if (OB_UNLIKELY(!ls_id.is_valid() || !tablet_id.is_valid() || snapshot_version <= 0 || data_format_version < 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(data_format_version)); @@ -505,61 +533,66 @@ int ObTabletDDLUtil::prepare_index_data_desc(const share::ObLSID &ls_id, } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, tablet_id, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_ALL_COMMITED))) { LOG_WARN("get tablet failed", K(ret)); - } else if (OB_FAIL(data_desc.init(tablet_handle.get_obj()->get_storage_schema(), + } else if (OB_FAIL(tablet_handle.get_obj()->load_storage_schema(tmp_arena, storage_schema))) { + LOG_WARN("fail to get storage schema", K(ret)); + } else if (OB_FAIL(data_desc.init_as_index(*storage_schema, ls_id, tablet_id, MAJOR_MERGE, snapshot_version, data_format_version))) { + // use storage schema to init ObDataStoreDesc + // all cols' default checksum will assigned to 0 + // means all macro should contain all columns in schema LOG_WARN("init data store desc failed", K(ret), K(tablet_id)); } else { if (nullptr != first_ddl_sstable) { // use the param in first ddl sstable, which persist the param when ddl start - const ObSSTableBasicMeta &basic_meta = first_ddl_sstable->get_meta().get_basic_meta(); - data_desc.row_store_type_ = basic_meta.root_row_store_type_; - data_desc.compressor_type_ = basic_meta.compressor_type_; - data_desc.master_key_id_ = basic_meta.master_key_id_; - data_desc.encrypt_id_ = basic_meta.encrypt_id_; - data_desc.encoder_opt_.set_store_type(basic_meta.root_row_store_type_); - MEMCPY(data_desc.encrypt_key_, basic_meta.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); - data_desc.need_prebuild_bloomfilter_ = false; + ObSSTableMetaHandle meta_handle; + if (OB_FAIL(first_ddl_sstable->get_meta(meta_handle))) { + LOG_WARN("get sstable meta handle fail", K(ret), KPC(first_ddl_sstable)); + } else { + const ObSSTableBasicMeta &basic_meta = meta_handle.get_sstable_meta().get_basic_meta(); + data_desc.row_store_type_ = basic_meta.root_row_store_type_; + data_desc.compressor_type_ = basic_meta.compressor_type_; + data_desc.master_key_id_ = basic_meta.master_key_id_; + data_desc.encrypt_id_ = basic_meta.encrypt_id_; + data_desc.encoder_opt_.set_store_type(basic_meta.root_row_store_type_); + MEMCPY(data_desc.encrypt_key_, basic_meta.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); + data_desc.need_prebuild_bloomfilter_ = false; + + data_desc.full_stored_col_cnt_ = basic_meta.column_cnt_; + while (data_desc.col_default_checksum_array_.count() > basic_meta.column_cnt_) { + data_desc.col_default_checksum_array_.pop_back(); + } + } + } else { + int64_t column_count = 0; + if (OB_FAIL(storage_schema->get_stored_column_count_in_sstable(column_count))) { + LOG_WARN("fail to get stored column count in sstable", K(ret)); + } else { + data_desc.full_stored_col_cnt_ = column_count; + while (data_desc.col_default_checksum_array_.count() > column_count) { + data_desc.col_default_checksum_array_.pop_back(); + } + } + } data_desc.is_ddl_ = true; - data_desc.row_column_count_ = data_desc.rowkey_column_count_ + 1; - // prepare col_desc_array for index block and macro meta block - data_desc.col_desc_array_.reset(); - if (OB_FAIL(data_desc.col_desc_array_.init(data_desc.row_column_count_))) { - LOG_WARN("failed to reserve column desc array", K(ret)); - } else if (OB_FAIL(tablet_handle.get_obj()->get_storage_schema().get_rowkey_column_ids(data_desc.col_desc_array_))) { - LOG_WARN("failed to get rowkey column ids", K(ret)); - } else if (OB_FAIL(storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(data_desc.col_desc_array_))) { - LOG_WARN("failed to add extra rowkey cols", K(ret)); - } else { - // column desc for the column of index info - ObObjMeta meta; - meta.set_varchar(); - meta.set_collation_type(CS_TYPE_BINARY); - share::schema::ObColDesc col; - col.col_id_ = static_cast(data_desc.row_column_count_ + OB_APP_MIN_COLUMN_ID); - col.col_type_ = meta; - col.col_order_ = DESC; - if (OB_FAIL(data_desc.col_desc_array_.push_back(col))) { - LOG_WARN("failed to push back last col for index", K(ret), K(col)); - } - } } + ObTablet::free_storage_schema(tmp_arena, storage_schema); return ret; } int ObTabletDDLUtil::create_ddl_sstable(const ObTabletDDLParam &ddl_param, const ObIArray &meta_array, const ObSSTable *first_ddl_sstable, - ObTableHandleV2 &table_handle) + common::ObArenaAllocator &allocator, + blocksstable::ObSSTable &sstable) { int ret = OB_SUCCESS; - table_handle.reset(); ObArenaAllocator arena("DdlCreateSST", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); void *buf = nullptr; ObSSTableIndexBuilder *sstable_index_builder = nullptr; @@ -601,7 +634,7 @@ int ObTabletDDLUtil::create_ddl_sstable(const ObTabletDDLParam &ddl_param, if (OB_SUCC(ret)) { if (OB_FAIL(index_block_rebuilder->close())) { LOG_WARN("close index block rebuilder failed", K(ret)); - } else if (OB_FAIL(ObTabletDDLUtil::create_ddl_sstable(sstable_index_builder, ddl_param, first_ddl_sstable, table_handle))) { + } else if (OB_FAIL(ObTabletDDLUtil::create_ddl_sstable(sstable_index_builder, ddl_param, first_ddl_sstable, allocator, sstable))) { LOG_WARN("create ddl sstable failed", K(ret), K(ddl_param)); } } @@ -621,13 +654,15 @@ int ObTabletDDLUtil::create_ddl_sstable(const ObTabletDDLParam &ddl_param, int ObTabletDDLUtil::create_ddl_sstable(ObSSTableIndexBuilder *sstable_index_builder, const ObTabletDDLParam &ddl_param, const ObSSTable *first_ddl_sstable, - ObTableHandleV2 &table_handle) + common::ObArenaAllocator &allocator, + blocksstable::ObSSTable &sstable) { int ret = OB_SUCCESS; - table_handle.reset(); ObLSService *ls_service = MTL(ObLSService *); ObLSHandle ls_handle; ObTabletHandle tablet_handle; + ObArenaAllocator tmp_arena("CreateDDLSstTmp"); + const ObStorageSchema *storage_schema = nullptr; SMART_VAR(ObSSTableMergeRes, res) { if (OB_UNLIKELY(nullptr == sstable_index_builder || !ddl_param.is_valid())) { ret = OB_INVALID_ARGUMENT; @@ -640,30 +675,31 @@ int ObTabletDDLUtil::create_ddl_sstable(ObSSTableIndexBuilder *sstable_index_bui } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, ddl_param.table_key_.tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_ALL_COMMITED))) { LOG_WARN("get tablet failed", K(ret), K(ddl_param)); + } else if (OB_FAIL(tablet_handle.get_obj()->load_storage_schema(tmp_arena, storage_schema))) { + LOG_WARN("failed to load storage schema", K(ret), K(tablet_handle)); } else { - const ObStorageSchema &storage_schema = tablet_handle.get_obj()->get_storage_schema(); int64_t column_count = 0; - share::schema::ObTableMode table_mode = storage_schema.get_table_mode_struct(); - share::schema::ObIndexType index_type = storage_schema.get_index_type(); - int64_t rowkey_column_cnt = storage_schema.get_rowkey_column_num() + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); - int64_t schema_version = storage_schema.get_schema_version(); - common::ObRowStoreType row_store_type = storage_schema.get_row_store_type(); + share::schema::ObTableMode table_mode = storage_schema->get_table_mode_struct(); + share::schema::ObIndexType index_type = storage_schema->get_index_type(); + int64_t rowkey_column_cnt = storage_schema->get_rowkey_column_num() + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + common::ObRowStoreType row_store_type = storage_schema->get_row_store_type(); if (nullptr != first_ddl_sstable) { - column_count = first_ddl_sstable->get_meta().get_basic_meta().column_cnt_; - table_mode = first_ddl_sstable->get_meta().get_basic_meta().table_mode_; - index_type = static_cast(first_ddl_sstable->get_meta().get_basic_meta().index_type_); - rowkey_column_cnt = first_ddl_sstable->get_meta().get_basic_meta().rowkey_column_count_; - schema_version = first_ddl_sstable->get_meta().get_basic_meta().schema_version_; - row_store_type = first_ddl_sstable->get_meta().get_basic_meta().latest_row_store_type_; - } else { - if (OB_FAIL(storage_schema.get_stored_column_count_in_sstable(column_count))) { - LOG_WARN("fail to get stored column count in sstable", K(ret)); + ObSSTableMetaHandle meta_handle; + if (OB_FAIL(first_ddl_sstable->get_meta(meta_handle))) { + LOG_WARN("get sstable meta handle fail", K(ret), KPC(first_ddl_sstable)); + } else { + column_count = meta_handle.get_sstable_meta().get_column_count(); + table_mode = meta_handle.get_sstable_meta().get_basic_meta().table_mode_; + index_type = static_cast(meta_handle.get_sstable_meta().get_basic_meta().index_type_); + rowkey_column_cnt = meta_handle.get_sstable_meta().get_basic_meta().rowkey_column_count_; + row_store_type = meta_handle.get_sstable_meta().get_basic_meta().latest_row_store_type_; } + } else if (OB_FAIL(storage_schema->get_stored_column_count_in_sstable(column_count))) { + LOG_WARN("fail to get stored column count in sstable", K(ret)); } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(sstable_index_builder->close(column_count, res))) { + if (FAILEDx(sstable_index_builder->close(res))) { LOG_WARN("close sstable index builder close failed", K(ret)); } else if (OB_UNLIKELY((ddl_param.table_key_.is_major_sstable() || ddl_param.table_key_.is_ddl_sstable()) && @@ -673,12 +709,13 @@ int ObTabletDDLUtil::create_ddl_sstable(ObSSTableIndexBuilder *sstable_index_bui LOG_WARN("max_merged_trans_version_ in res is different from ddl snapshot version", K(ret), K(res), K(ddl_param)); } else { + const int64_t create_schema_version_on_tablet = tablet_handle.get_obj()->get_tablet_meta().create_schema_version_; ObTabletCreateSSTableParam param; param.table_key_ = ddl_param.table_key_; param.table_mode_ = table_mode; param.index_type_ = index_type; param.rowkey_column_cnt_ = rowkey_column_cnt; - param.schema_version_ = schema_version; + param.schema_version_ = create_schema_version_on_tablet; param.latest_row_store_type_ = row_store_type; param.create_snapshot_version_ = ddl_param.snapshot_version_; param.ddl_scn_ = ddl_param.start_scn_; @@ -709,43 +746,48 @@ int ObTabletDDLUtil::create_ddl_sstable(ObSSTableIndexBuilder *sstable_index_bui param.other_block_ids_ = res.other_block_ids_; MEMCPY(param.encrypt_key_, res.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); - if (OB_FAIL(res.fill_column_checksum(&storage_schema, param.column_checksums_))) { + if (OB_FAIL(param.column_checksums_.assign(res.data_column_checksums_))) { LOG_WARN("fail to fill column checksum for empty major", K(ret), K(param)); - } else { - for (int64_t i = param.column_checksums_.count(); OB_SUCC(ret) && i > column_count; --i) { - param.column_checksums_.pop_back(); - } - } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, table_handle))) { + } else if (OB_UNLIKELY(param.column_checksums_.count() != column_count)) { + // we have corrected the col_default_checksum_array_ in prepare_index_data_desc + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected column checksums", K(ret), K(column_count), K(param)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, allocator, sstable))) { LOG_WARN("create sstable failed", K(ret), K(param)); } else { - LOG_INFO("create ddl sstable success", K(ddl_param), K(table_handle)); + LOG_INFO("create ddl sstable success", K(ddl_param), K(sstable), + "create_schema_version", create_schema_version_on_tablet); } } } + ObTablet::free_storage_schema(tmp_arena, storage_schema); } return ret; } int ObTabletDDLUtil::update_ddl_table_store(const ObTabletDDLParam &ddl_param, - const ObTableHandleV2 &table_handle) + common::ObArenaAllocator &allocator, + blocksstable::ObSSTable &sstable) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!ddl_param.is_valid() || !table_handle.is_valid())) { + if (OB_UNLIKELY(!ddl_param.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(ddl_param), K(table_handle)); + LOG_WARN("invalid argument", K(ret), K(ddl_param)); } else { ObLSService *ls_service = MTL(ObLSService *); ObLSHandle ls_handle; ObTabletHandle tablet_handle; + ObArenaAllocator allocator; + const ObStorageSchema *tablet_storage_schema = nullptr; if (OB_FAIL(ls_service->get_ls(ddl_param.ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) { LOG_WARN("get ls failed", K(ret), K(ddl_param)); } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, ddl_param.table_key_.tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_ALL_COMMITED))) { LOG_WARN("get tablet failed", K(ret), K(ddl_param)); + } else if (OB_FAIL(tablet_handle.get_obj()->load_storage_schema(allocator, tablet_storage_schema))) { + LOG_WARN("fail to load storage schema failed", K(ret)); } else { const bool is_major_sstable = ddl_param.table_key_.is_major_sstable(); const int64_t rebuild_seq = ls_handle.get_ls()->get_rebuild_seq(); @@ -754,68 +796,109 @@ int ObTabletDDLUtil::update_ddl_table_store(const ObTabletDDLParam &ddl_param, const int64_t multi_version_start = is_major_sstable ? max(ddl_param.snapshot_version_, tablet_handle.get_obj()->get_multi_version_start()) : 0; ObTabletHandle new_tablet_handle; - ObUpdateTableStoreParam table_store_param(table_handle, + ObUpdateTableStoreParam table_store_param(&sstable, snapshot_version, multi_version_start, rebuild_seq, - &tablet_handle.get_obj()->get_storage_schema(), + tablet_storage_schema, is_major_sstable, // update_with_major_flag - is_major_sstable); // need report checksum + /*DDL does not have verification between replicas, + So using medium merge to force verification between replicas*/ + MEDIUM_MERGE, + is_major_sstable// need report checksum + ); table_store_param.ddl_info_.keep_old_ddl_sstable_ = !is_major_sstable; table_store_param.ddl_info_.data_format_version_ = ddl_param.data_format_version_; table_store_param.ddl_info_.ddl_commit_scn_ = ddl_param.commit_scn_; if (OB_FAIL(ls_handle.get_ls()->update_tablet_table_store(ddl_param.table_key_.get_tablet_id(), table_store_param, new_tablet_handle))) { LOG_WARN("failed to update tablet table store", K(ret), K(ddl_param.table_key_), K(table_store_param)); } else { - LOG_INFO("ddl update table store success", K(ddl_param), K(table_store_param), K(table_handle)); + LOG_INFO("ddl update table store success", K(ddl_param), K(table_store_param), K(sstable)); } } + ObTablet::free_storage_schema(allocator, tablet_storage_schema); } return ret; } -int ObTabletDDLUtil::compact_ddl_sstable(const ObTablesHandleArray &ddl_sstables, - const ObTableReadInfo &read_info, +int ObTabletDDLUtil::compact_ddl_sstable(ObTableStoreIterator &ddl_sstable_iter, + const ObITableReadInfo &read_info, const bool is_commit, const share::SCN &rec_scn, ObTabletDDLParam &ddl_param, - ObTableHandleV2 &table_handle) + common::ObArenaAllocator &allocator, + blocksstable::ObSSTable &sstable) { int ret = OB_SUCCESS; - table_handle.reset(); ObArenaAllocator arena; ObBlockMetaTree meta_tree; ObArray sorted_metas; bool is_data_complete = false; + ObITable *first_ddl_sstable = nullptr; + ObITable *last_ddl_sstable = nullptr; + SCN sstable_end_scn = SCN::max_scn(); + if (OB_UNLIKELY(!ddl_param.is_valid() || (is_commit && !rec_scn.is_valid_and_not_min()))) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(ddl_param), K(ddl_sstables.get_count()), K(is_commit), K(rec_scn)); - } else if (OB_FAIL(ObTabletDDLUtil::check_data_integrity(ddl_sstables, + LOG_WARN("invalid argument", K(ret), K(ddl_param), K(is_commit), K(rec_scn)); + } else if (ddl_sstable_iter.count() > 0) { + if (OB_FAIL(ddl_sstable_iter.get_boundary_table(false/*is_last*/, first_ddl_sstable))) { + LOG_WARN("failed to get boundary table", K(ret)); + } else if (OB_ISNULL(first_ddl_sstable)) { + ret = OB_ERR_SYS; + LOG_ERROR("first_ddl_sstable must not null", K(ret)); + } else if (OB_FAIL(ddl_sstable_iter.get_boundary_table(true/*is_last*/, last_ddl_sstable))) { + LOG_WARN("failed to get boundary table", K(ret)); + } else if (OB_ISNULL(last_ddl_sstable)) { + ret = OB_ERR_SYS; + LOG_ERROR("last_ddl_sstable must not null", K(ret)); + } else { + sstable_end_scn = last_ddl_sstable->get_end_scn(); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObTabletDDLUtil::check_data_integrity(ddl_sstable_iter, ddl_param.start_scn_, - is_commit ? rec_scn : ddl_sstables.get_table(ddl_sstables.get_count() - 1)->get_end_scn(), + is_commit ? rec_scn : sstable_end_scn, is_data_complete))) { - LOG_WARN("check ddl sstable integrity failed", K(ret), K(ddl_sstables), K(ddl_param)); + LOG_WARN("check ddl sstable integrity failed", K(ret), K(ddl_sstable_iter), K(ddl_param)); } else if (!is_data_complete) { ret = OB_EAGAIN; if (TC_REACH_TIME_INTERVAL(10L * 1000L * 1000L)) { - LOG_WARN("current ddl sstables not contain all data", K(ddl_sstables), K(ddl_param)); + LOG_WARN("current ddl sstables not contain all data", K(ddl_sstable_iter), K(ddl_param)); } } else if (OB_FAIL(meta_tree.init(ddl_param.ls_id_, ddl_param.table_key_, ddl_param.start_scn_, ddl_param.data_format_version_))) { LOG_WARN("init meta tree failed", K(ret), K(ddl_param)); + } else if (FALSE_IT(ddl_sstable_iter.resume())) { } else { ObDatumRowkey last_rowkey; SMART_VAR(ObSSTableSecMetaIterator, meta_iter) { ObDatumRange query_range; query_range.set_whole_range(); ObDataMacroBlockMeta data_macro_meta; - for (int64_t i = 0; OB_SUCC(ret) && i < ddl_sstables.get_count(); ++i) { - const ObSSTable *cur_sstable = static_cast(ddl_sstables.get_table(i)); + while (OB_SUCC(ret)) { + ObITable *table = nullptr; + const ObSSTable *cur_sstable = nullptr; meta_iter.reset(); - if (OB_FAIL(meta_iter.open(query_range, - ObMacroBlockMetaType::DATA_BLOCK_META, - *cur_sstable, - read_info, - arena))) { + if (OB_FAIL(ddl_sstable_iter.get_next(table))) { + if (OB_ITER_END != ret) { + LOG_WARN("get next ddl sstable failed", K(ret)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, table is nullptr", K(ret), KPC(table)); + } else { + cur_sstable = static_cast(table); + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(meta_iter.open(query_range, + ObMacroBlockMetaType::DATA_BLOCK_META, + *cur_sstable, + read_info, + arena))) { LOG_WARN("sstable secondary meta iterator open failed", K(ret)); } else { while (OB_SUCC(ret)) { @@ -844,9 +927,9 @@ int ObTabletDDLUtil::compact_ddl_sstable(const ObTablesHandleArray &ddl_sstables } } } - LOG_INFO("append meta tree finished", K(ret), K(i), - "data_macro_block_cnt_in_sstable", cur_sstable->get_meta().get_basic_meta().get_data_macro_block_count(), - K(meta_tree.get_macro_block_cnt())); + LOG_INFO("append meta tree finished", K(ret), + // "data_macro_block_cnt_in_sstable", cur_sstable->get_meta().get_basic_meta().get_data_macro_block_count(), + K(meta_tree.get_macro_block_cnt())); #ifdef ERRSIM if (OB_SUCC(ret) && ddl_param.table_key_.is_major_sstable()) { ret = OB_E(EventTable::EN_DDL_COMPACT_FAIL) OB_SUCCESS; @@ -860,15 +943,15 @@ int ObTabletDDLUtil::compact_ddl_sstable(const ObTablesHandleArray &ddl_sstables } } // close - if (OB_SUCC(ret)) { + if (OB_SUCC(ret) && is_data_complete) { if (is_commit) { ddl_param.table_key_.table_type_ = ObITable::TableType::MAJOR_SSTABLE; ddl_param.table_key_.version_range_.base_version_ = 0; ddl_param.table_key_.version_range_.snapshot_version_ = ddl_param.snapshot_version_; } else { ddl_param.table_key_.table_type_ = ObITable::TableType::DDL_DUMP_SSTABLE; - ddl_param.table_key_.scn_range_.start_scn_ = ddl_sstables.get_table(0)->get_start_scn(); - ddl_param.table_key_.scn_range_.end_scn_ = ddl_sstables.get_table(ddl_sstables.get_count() - 1)->get_end_scn(); + ddl_param.table_key_.scn_range_.start_scn_ = first_ddl_sstable->get_start_scn(); + ddl_param.table_key_.scn_range_.end_scn_ = last_ddl_sstable->get_end_scn(); } if (OB_FAIL(meta_tree.build_sorted_rowkeys())) { LOG_WARN("build sorted rowkey failed", K(ret)); @@ -876,10 +959,11 @@ int ObTabletDDLUtil::compact_ddl_sstable(const ObTablesHandleArray &ddl_sstables LOG_WARN("get sorted metas failed", K(ret)); } else if (OB_FAIL(create_ddl_sstable(ddl_param, sorted_metas, - static_cast(ddl_sstables.get_table(0)), - table_handle))) { + static_cast(first_ddl_sstable), + allocator, + sstable))) { LOG_WARN("create ddl sstable failed", K(ret)); - } else if (OB_FAIL(update_ddl_table_store(ddl_param, table_handle))) { + } else if (OB_FAIL(update_ddl_table_store(ddl_param, allocator, sstable))) { LOG_WARN("update ddl table store failed", K(ret)); } else { LOG_INFO("compact ddl sstable success", K(ddl_param)); @@ -893,7 +977,8 @@ int ObTabletDDLUtil::report_ddl_checksum(const share::ObLSID &ls_id, const uint64_t table_id, const int64_t execution_id, const int64_t ddl_task_id, - const ObIArray &column_checksums) + const int64_t *column_checksums, + const int64_t column_count) { int ret = OB_SUCCESS; ObMySQLProxy *sql_proxy = GCTX.sql_proxy_; @@ -921,12 +1006,12 @@ int ObTabletDDLUtil::report_ddl_checksum(const share::ObLSID &ls_id, ObArray ddl_checksum_items; if (OB_FAIL(table_schema->get_multi_version_column_descs(column_ids))) { LOG_WARN("fail to get column ids", K(ret), K(ls_id), K(tablet_id)); - } else if (OB_UNLIKELY(column_checksums.count() > column_ids.count())) { + } else if (OB_UNLIKELY(column_count > column_ids.count())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect error, column checksums count larger than column ids count", K(ret), - K(ls_id), K(tablet_id), K(column_checksums.count()), K(column_ids.count())); + K(ls_id), K(tablet_id), K(column_count), K(column_ids.count())); } - for (int64_t i = 0; OB_SUCC(ret) && i < column_checksums.count(); ++i) { + for (int64_t i = 0; OB_SUCC(ret) && i < column_count; ++i) { share::ObDDLChecksumItem item; item.execution_id_ = execution_id; item.tenant_id_ = tenant_id; @@ -934,7 +1019,7 @@ int ObTabletDDLUtil::report_ddl_checksum(const share::ObLSID &ls_id, item.ddl_task_id_ = ddl_task_id; item.column_id_ = column_ids.at(i).col_id_; item.task_id_ = tablet_id.id(); - item.checksum_ = column_checksums.at(i); + item.checksum_ = column_checksums[i]; #ifdef ERRSIM if (OB_SUCC(ret)) { ret = OB_E(EventTable::EN_HIDDEN_CHECKSUM_DDL_TASK) OB_SUCCESS; @@ -972,7 +1057,8 @@ int ObTabletDDLUtil::report_ddl_checksum(const share::ObLSID &ls_id, int ObTabletDDLUtil::check_and_get_major_sstable(const share::ObLSID &ls_id, const ObTabletID &tablet_id, - const ObSSTable *&first_major_sstable) + const blocksstable::ObSSTable *&first_major_sstable, + ObTabletMemberWrapper &table_store_wrapper) { int ret = OB_SUCCESS; ObLSHandle ls_handle; @@ -986,14 +1072,16 @@ int ObTabletDDLUtil::check_and_get_major_sstable(const share::ObLSID &ls_id, } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, tablet_id, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_ALL_COMMITED))) { LOG_WARN("get tablet handle failed", K(ret), K(ls_id), K(tablet_id)); } else if (OB_UNLIKELY(nullptr == tablet_handle.get_obj())) { ret = OB_ERR_SYS; LOG_WARN("tablet handle is null", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { first_major_sstable = static_cast( - tablet_handle.get_obj()->get_table_store().get_major_sstables().get_boundary_table(false/*first*/)); + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(false/*first*/)); } return ret; } diff --git a/src/storage/ddl/ob_ddl_merge_task.h b/src/storage/ddl/ob_ddl_merge_task.h old mode 100644 new mode 100755 index 0f4758ced..563d3c448 --- a/src/storage/ddl/ob_ddl_merge_task.h +++ b/src/storage/ddl/ob_ddl_merge_task.h @@ -72,7 +72,8 @@ public: public: virtual bool operator == (const ObIDag &other) const override; virtual int64_t hash() const override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; + virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual bool ignore_warning() override; virtual lib::Worker::CompatMode get_compat_mode() const override @@ -150,34 +151,39 @@ public: static int create_ddl_sstable(const ObTabletDDLParam &ddl_param, const ObIArray &meta_array, const blocksstable::ObSSTable *first_ddl_sstable, - ObTableHandleV2 &table_handle); + common::ObArenaAllocator &allocator, + blocksstable::ObSSTable &sstable); static int create_ddl_sstable(blocksstable::ObSSTableIndexBuilder *sstable_index_builder, const ObTabletDDLParam &ddl_param, const blocksstable::ObSSTable *first_ddl_sstable, - ObTableHandleV2 &table_handle); + common::ObArenaAllocator &allocator, + blocksstable::ObSSTable &sstable); static int update_ddl_table_store(const ObTabletDDLParam &ddl_param, - const ObTableHandleV2 &table_handle); + common::ObArenaAllocator &allocator, + blocksstable::ObSSTable &sstable); - static int compact_ddl_sstable(const ObTablesHandleArray &ddl_sstables, - const ObTableReadInfo &read_info, + static int compact_ddl_sstable(ObTableStoreIterator &ddl_sstable_iter, + const ObITableReadInfo &read_info, const bool is_commit, const share::SCN &rec_scn, ObTabletDDLParam &ddl_param, - ObTableHandleV2 &table_handle); + common::ObArenaAllocator &allocator, + blocksstable::ObSSTable &sstable); static int report_ddl_checksum(const share::ObLSID &ls_id, const ObTabletID &tablet_id, const uint64_t table_id, const int64_t execution_id, const int64_t ddl_task_id, - const ObIArray &column_checksums); + const int64_t *column_checksums, + const int64_t column_count); static int check_and_get_major_sstable(const share::ObLSID &ls_id, const ObTabletID &tablet_id, - const blocksstable::ObSSTable *&first_major_sstable); - - static int check_data_integrity(const ObTablesHandleArray &ddl_sstables, + const blocksstable::ObSSTable *&first_major_sstable, + ObTabletMemberWrapper &table_store_wrapper); + static int check_data_integrity(ObTableStoreIterator &ddl_sstable_iter, const share::SCN &start_scn, const share::SCN &prepare_scn, bool &is_data_complete); diff --git a/src/storage/ddl/ob_ddl_redo_log_replayer.cpp b/src/storage/ddl/ob_ddl_redo_log_replayer.cpp old mode 100644 new mode 100755 index 5d5c39e68..6e2ed8578 --- a/src/storage/ddl/ob_ddl_redo_log_replayer.cpp +++ b/src/storage/ddl/ob_ddl_redo_log_replayer.cpp @@ -15,6 +15,7 @@ #include "ob_ddl_redo_log_replayer.h" #include "storage/ddl/ob_ddl_clog.h" #include "storage/ddl/ob_ddl_merge_task.h" +#include "storage/ddl/ob_ddl_replay_executor.h" #include "storage/ls/ob_ls.h" #include "storage/compaction/ob_schedule_dag_func.h" #include "storage/ddl/ob_tablet_ddl_kv_mgr.h" @@ -57,207 +58,68 @@ int ObDDLRedoLogReplayer::init(ObLS *ls) int ObDDLRedoLogReplayer::replay_start(const ObDDLStartLog &log, const SCN &scn) { int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObITable::TableKey table_key = log.get_table_key(); - ObDDLKvMgrHandle ddl_kv_mgr_handle; - bool need_replay = true; + ObDDLStartReplayExecutor replay_executor; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObDDLRedoLogReplayer has not been inited", K(ret)); - } else if (OB_UNLIKELY(!log.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(log)); - } else if (OB_FAIL(check_need_replay_ddl_log(table_key, scn, scn, need_replay, tablet_handle))) { - if (OB_EAGAIN != ret) { - LOG_WARN("fail to check need replay ddl log", K(ret), K(table_key), K(scn)); + } else if (OB_FAIL(replay_executor.init(ls_, log, scn))) { + LOG_WARN("failed to init ddl start log replay executor", K(ret)); + } else if (OB_FAIL(replay_executor.execute(scn, ls_->get_ls_id(), log.get_table_key().tablet_id_))) { + if (OB_NO_NEED_UPDATE == ret) { + ret = OB_SUCCESS; + } else if (OB_EAGAIN != ret) { + LOG_WARN("failed to replay", K(ret), K(log), K(scn)); } - } else if (!need_replay) { - // do nothing - } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("need replay but tablet handle is invalid", K(ret), K(need_replay), K(tablet_handle)); - } else if (OB_FAIL(tablet_handle.get_obj()->get_ddl_kv_mgr(ddl_kv_mgr_handle, true/*try_create*/))) { - LOG_WARN("create ddl kv mgr failed", K(ret), K(table_key), K(log), K(scn)); - } else if (OB_FAIL(ddl_kv_mgr_handle.get_obj()->ddl_start(*tablet_handle.get_obj(), - table_key, - scn, - log.get_data_format_version(), - log.get_execution_id(), - SCN::min_scn()/*checkpoint_scn*/))) { - if (OB_TASK_EXPIRED != ret) { - LOG_WARN("start ddl log failed", K(ret), K(log), K(scn)); - } else { - ret = OB_SUCCESS; // ignored expired ddl start log - } - } else { - LOG_INFO("succeed to replay ddl start log", K(ret), K(log), K(scn)); } - LOG_INFO("finish replay ddl start log", K(ret), K(need_replay), K(log), K(scn)); + return ret; } int ObDDLRedoLogReplayer::replay_redo(const ObDDLRedoLog &log, const SCN &scn) { int ret = OB_SUCCESS; - const ObDDLMacroBlockRedoInfo &redo_info = log.get_redo_info(); - const ObITable::TableKey table_key = redo_info.table_key_; - bool need_replay = true; - ObTabletHandle tablet_handle; - ObDDLKV *ddl_kv = nullptr; + ObDDLRedoReplayExecutor replay_executor; DEBUG_SYNC(BEFORE_REPLAY_DDL_MACRO_BLOCK); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObDDLRedoLogReplayer has not been inited", K(ret)); - } else if (OB_UNLIKELY(!log.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(log)); - } else if (OB_FAIL(check_need_replay_ddl_log(table_key, redo_info.start_scn_, scn, need_replay, tablet_handle))) { - if (OB_EAGAIN != ret) { - LOG_WARN("fail to check need replay ddl log", K(ret), K(table_key), K(scn)); - } - } else if (!need_replay) { - // do nothing - } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("need replay but tablet handle is invalid", K(ret), K(need_replay), K(tablet_handle)); - } else { - ObMacroBlockWriteInfo write_info; - ObMacroBlockHandle macro_handle; - write_info.buffer_ = redo_info.data_buffer_.ptr(); - write_info.size_= redo_info.data_buffer_.length(); - write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); - const int64_t io_timeout_ms = max(DDL_FLUSH_MACRO_BLOCK_TIMEOUT / 1000L, GCONF._data_storage_io_timeout / 1000L); - ObDDLMacroBlock macro_block; - if (OB_FAIL(ObBlockManager::async_write_block(write_info, macro_handle))) { - LOG_WARN("fail to async write block", K(ret), K(write_info), K(macro_handle)); - } else if (OB_FAIL(macro_handle.wait(io_timeout_ms))) { - LOG_WARN("fail to wait macro block io finish", K(ret)); - } else if (OB_FAIL(macro_block.block_handle_.set_block_id(macro_handle.get_macro_id()))) { - LOG_WARN("set macro block id failed", K(ret), K(macro_handle.get_macro_id())); - } else { - macro_block.block_type_ = redo_info.block_type_; - macro_block.logic_id_ = redo_info.logic_id_; - macro_block.scn_ = scn; - macro_block.buf_ = redo_info.data_buffer_.ptr(); - macro_block.size_ = redo_info.data_buffer_.length(); - macro_block.ddl_start_scn_ = redo_info.start_scn_; - if (OB_FAIL(ObDDLKVPendingGuard::set_macro_block(tablet_handle.get_obj(), macro_block))) { - LOG_WARN("set macro block into ddl kv failed", K(ret), K(tablet_handle), K(macro_block)); - } + } else if (OB_FAIL(replay_executor.init(ls_, log, scn))) { + LOG_WARN("failed to init ddl redo log replay executor", K(ret)); + } else if (OB_FAIL(replay_executor.execute(scn, ls_->get_ls_id(), log.get_redo_info().table_key_.tablet_id_))) { + if (OB_NO_NEED_UPDATE == ret) { + ret = OB_SUCCESS; + } else if (OB_EAGAIN != ret) { + LOG_WARN("failed to replay", K(ret), K(log), K(scn)); } } - LOG_INFO("finish replay ddl redo log", K(ret), K(need_replay), K(log)); + return ret; } int ObDDLRedoLogReplayer::replay_commit(const ObDDLCommitLog &log, const SCN &scn) { int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObITable::TableKey table_key = log.get_table_key(); - ObDDLKvMgrHandle ddl_kv_mgr_handle; - ObDDLKV *ddl_kv = nullptr; - bool need_replay = true; + ObDDLCommitReplayExecutor replay_executor; DEBUG_SYNC(BEFORE_REPLAY_DDL_PREPRARE); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObDDLRedoLogReplayer has not been inited", K(ret)); - } else if (OB_UNLIKELY(!log.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(log)); - } else if (OB_FAIL(check_need_replay_ddl_log(table_key, log.get_start_scn(), scn, need_replay, tablet_handle))) { - if (OB_EAGAIN != ret) { - LOG_WARN("fail to check need replay ddl log", K(ret), K(table_key), K(scn), K(log)); + } else if (OB_FAIL(replay_executor.init(ls_, log, scn))) { + LOG_WARN("failed to init ddl commit log replay executor", K(ret)); + } else if (OB_FAIL(replay_executor.execute(scn, ls_->get_ls_id(), log.get_table_key().tablet_id_))) { + if (OB_NO_NEED_UPDATE == ret || OB_TASK_EXPIRED == ret) { + ret = OB_SUCCESS; + } else if (OB_EAGAIN != ret) { + LOG_WARN("failed to replay ddl commit log", K(ret), K(scn), K(log), K(ls_->get_ls_id())); } - } else if (!need_replay) { - // do nothing - } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("need replay but tablet handle is invalid", K(ret), K(need_replay), K(tablet_handle), K(log), K(scn)); - } else if (OB_FAIL(tablet_handle.get_obj()->get_ddl_kv_mgr(ddl_kv_mgr_handle))) { - LOG_WARN("get ddl kv mgr failed", K(ret), K(log), K(scn)); - } else if (OB_FAIL(ddl_kv_mgr_handle.get_obj()->set_commit_scn(scn))) { - LOG_WARN("failed to start prepare", K(ret), K(log), K(scn)); - } else if (OB_FAIL(ddl_kv_mgr_handle.get_obj()->ddl_commit(log.get_start_scn(), scn))) { - if (OB_TABLET_NOT_EXIST == ret || OB_TASK_EXPIRED == ret) { - ret = OB_SUCCESS; // exit when tablet not exist or task expired - } else { - LOG_WARN("replay ddl commit log failed", K(ret), K(log), K(scn)); - } - } else { - LOG_INFO("replay ddl commit log success", K(ret), K(log), K(scn)); } - LOG_INFO("finish replay ddl commit log", K(ret), K(need_replay), K(log), K(scn)); return ret; } -int ObDDLRedoLogReplayer::check_need_replay_ddl_log(const ObITable::TableKey &table_key, - const SCN &ddl_start_scn, - const SCN &scn, - bool &need_replay, - ObTabletHandle &tablet_handle) -{ - int ret = OB_SUCCESS; - need_replay = true; - ObTableHandleV2 table_handle; - ObSSTable *sstable = nullptr; - ObTablet *tablet = nullptr; - ObSSTableArray major_sstables; - ObDDLKvMgrHandle ddl_kv_mgr_handle; - ObMigrationStatus migration_status; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (OB_FAIL(ls_->get_ls_meta().get_migration_status(migration_status))) { - LOG_WARN("get migration status failed", K(ret), KPC(ls_)); - } else if (ObMigrationStatus::OB_MIGRATION_STATUS_ADD_FAIL == migration_status - || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_FAIL == migration_status) { - need_replay = false; - LOG_INFO("ls migration failed, so ddl log skip replay", "ls_id", ls_->get_ls_id(), "tablet_id", table_key.tablet_id_, K(migration_status)); - } else if (OB_FAIL(ls_->get_tablet(table_key.tablet_id_, tablet_handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { - if (OB_TABLET_NOT_EXIST == ret) { - // we are sure that tablet does not exist, so we have no need to replay - need_replay = false; - LOG_INFO("tablet not exist, so ddl log skip replay", "ls_id", ls_->get_ls_id(), "tablet_id", table_key.tablet_id_); - ret = OB_SUCCESS; - } else { - LOG_WARN("fail to get tablet", K(ret), "tablet_id", table_key.tablet_id_, K(scn)); - } - } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet is null", K(ret), K(tablet_handle)); - } else if (tablet->get_tablet_meta().ha_status_.is_expected_status_deleted()) { - need_replay = false; - if (REACH_COUNT_INTERVAL(1000L)) { - LOG_INFO("no need to replay ddl log, because tablet will be deleted", - K(table_key), "tablet_meta", tablet->get_tablet_meta()); - } - } else if (scn <= tablet->get_tablet_meta().ddl_checkpoint_scn_) { - need_replay = false; - if (REACH_COUNT_INTERVAL(1000L)) { - LOG_INFO("no need to replay ddl log, because the log ts is less than the ddl checkpoint ts", - K(table_key), K(scn), "ddl_checkpoint_ts", tablet->get_tablet_meta().ddl_checkpoint_scn_); - } - } else if (OB_FAIL(tablet->get_ddl_kv_mgr(ddl_kv_mgr_handle))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("get ddl kv manager failed", K(ret), K(table_key)); - } else { - need_replay = (ddl_start_scn == scn); // only replay start log if ddl kv mgr is null - ret = OB_SUCCESS; - } - } else if (ddl_start_scn < ddl_kv_mgr_handle.get_obj()->get_start_scn()) { - need_replay = false; - if (REACH_COUNT_INTERVAL(1000L)) { - LOG_INFO("no need to replay ddl log, because the ddl start log ts is less than the value in ddl kv manager", - K(table_key), K(ddl_start_scn), "ddl_start_scn_in_ddl_kv_mgr", ddl_kv_mgr_handle.get_obj()->get_start_scn()); - } - } - return ret; -} void ObDDLRedoLogReplayer::destroy() { diff --git a/src/storage/ddl/ob_ddl_redo_log_replayer.h b/src/storage/ddl/ob_ddl_redo_log_replayer.h index e20f6e0cb..c298bbf2e 100644 --- a/src/storage/ddl/ob_ddl_redo_log_replayer.h +++ b/src/storage/ddl/ob_ddl_redo_log_replayer.h @@ -36,11 +36,7 @@ public: int replay_commit(const ObDDLCommitLog &log, const share::SCN &scn); private: void destroy(); - int check_need_replay_ddl_log(const ObITable::TableKey &table_key, - const share::SCN &ddl_start_scn, - const share::SCN &scn, - bool &need_replay, - ObTabletHandle &tablet_handle); + private: static const int64_t TOTAL_LIMIT = 10 * 1024 * 1024 * 1024L; static const int64_t HOLD_LIMIT = 10 * 1024 * 1024 * 1024L; diff --git a/src/storage/ddl/ob_ddl_redo_log_writer.cpp b/src/storage/ddl/ob_ddl_redo_log_writer.cpp old mode 100644 new mode 100755 index 0804febf8..ed8bc4a48 --- a/src/storage/ddl/ob_ddl_redo_log_writer.cpp +++ b/src/storage/ddl/ob_ddl_redo_log_writer.cpp @@ -1160,7 +1160,7 @@ int ObDDLSSTableRedoWriter::start_ddl_redo(const ObITable::TableKey &table_key, } else if (OB_ISNULL(ls = ls_handle.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("ls should not be null", K(ret), K(table_key)); - } else if (OB_FAIL(ls->get_tablet(tablet_id_, tablet_handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls->get_tablet(tablet_id_, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), K(ls_id_), K(tablet_id_)); } else if (OB_FAIL(tablet_handle.get_obj()->get_ddl_kv_mgr(ddl_kv_mgr_handle, true/*try_create*/))) { LOG_WARN("create ddl kv mgr failed", K(ret)); @@ -1242,17 +1242,24 @@ int ObDDLSSTableRedoWriter::end_ddl_redo_and_create_ddl_sstable( } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, tablet_id, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), K(ls_id), K(tablet_id)); } else if (OB_ISNULL(tablet_handle.get_obj())) { ret = OB_ERR_SYS; LOG_WARN("tablet handle is null", K(ret), K(ls_id), K(tablet_id)); } else { - ObSSTable *first_major_sstable = static_cast( - tablet_handle.get_obj()->get_table_store().get_major_sstables().get_boundary_table(false/*first*/)); - if (OB_ISNULL(first_major_sstable)) { + ObTabletMemberWrapper table_store_wrapper; + ObSSTableMetaHandle sst_meta_hdl; + const ObSSTable *first_major_sstable = nullptr; + if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FALSE_IT(first_major_sstable = static_cast( + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(false/*first*/)))) { + } else if (OB_ISNULL(first_major_sstable)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("no major after wait merge success", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(first_major_sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); } else if (OB_UNLIKELY(first_major_sstable->get_key() != table_key)) { ret = OB_SNAPSHOT_DISCARDED; LOG_WARN("ddl major sstable dropped, snapshot holding may have bug", K(ret), KPC(first_major_sstable), K(table_key), K(tablet_id), K(execution_id), K(ddl_task_id)); @@ -1263,7 +1270,8 @@ int ObDDLSSTableRedoWriter::end_ddl_redo_and_create_ddl_sstable( table_id, execution_id, ddl_task_id, - first_major_sstable->get_meta().get_col_checksum()))) { + sst_meta_hdl.get_sstable_meta().get_col_checksum(), + sst_meta_hdl.get_sstable_meta().get_col_checksum_cnt()))) { LOG_WARN("report ddl column checksum failed", K(ret), K(ls_id), K(tablet_id), K(execution_id), K(ddl_task_id)); } else { break; @@ -1529,7 +1537,7 @@ int ObDDLRedoLogWriterCallback::init(const ObDDLMacroBlockType block_type, } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, ddl_kv_mgr_handle.get_obj()->get_tablet_id(), tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), KPC(ddl_kv_mgr_handle.get_obj())); } else { block_type_ = block_type; diff --git a/src/storage/ddl/ob_ddl_replay_executor.cpp b/src/storage/ddl/ob_ddl_replay_executor.cpp new file mode 100755 index 000000000..2ea59746a --- /dev/null +++ b/src/storage/ddl/ob_ddl_replay_executor.cpp @@ -0,0 +1,329 @@ +/** + * Copyright (c) 2023 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "ob_ddl_replay_executor.h" +#include "storage/ddl/ob_ddl_clog.h" +#include "storage/ddl/ob_ddl_merge_task.h" +#include "storage/ls/ob_ls.h" +#include "storage/compaction/ob_schedule_dag_func.h" +#include "storage/ddl/ob_tablet_ddl_kv_mgr.h" + +using namespace oceanbase::common; +using namespace oceanbase::lib; +using namespace oceanbase::blocksstable; +using namespace oceanbase::storage; +using namespace oceanbase::share; + +ObDDLReplayExecutor::ObDDLReplayExecutor() + : logservice::ObTabletReplayExecutor(), ls_(nullptr), scn_() +{} + +int ObDDLReplayExecutor::check_need_replay_ddl_log_( + const ObTabletHandle &tablet_handle, + const share::SCN &ddl_start_scn, + const share::SCN &scn, + bool &need_replay) const +{ + int ret = OB_SUCCESS; + need_replay = true; + ObTablet *tablet = nullptr; + ObDDLKvMgrHandle ddl_kv_mgr_handle; + ObMigrationStatus migration_status; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(ls_->get_ls_meta().get_migration_status(migration_status))) { + LOG_WARN("get migration status failed", K(ret), KPC(ls_)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_ADD_FAIL == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_FAIL == migration_status) { + need_replay = false; + LOG_INFO("ls migration failed, so ddl log skip replay", "ls_id", ls_->get_ls_id(), K(tablet_handle), K(migration_status)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(tablet_handle)); + } else if (tablet->get_tablet_meta().ha_status_.is_expected_status_deleted()) { + need_replay = false; + if (REACH_COUNT_INTERVAL(1000L)) { + LOG_INFO("no need to replay ddl log, because tablet will be deleted", + K(tablet_handle), "tablet_meta", tablet->get_tablet_meta()); + } + } else if (scn <= tablet->get_tablet_meta().ddl_checkpoint_scn_) { + need_replay = false; + if (REACH_COUNT_INTERVAL(1000L)) { + LOG_INFO("no need to replay ddl log, because the log ts is less than the ddl checkpoint ts", + K(tablet_handle), K(scn), "ddl_checkpoint_ts", tablet->get_tablet_meta().ddl_checkpoint_scn_); + } + } else if (OB_FAIL(tablet->get_ddl_kv_mgr(ddl_kv_mgr_handle))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("get ddl kv manager failed", K(ret), K(tablet_handle)); + } else { + need_replay = (ddl_start_scn == scn); // only replay start log if ddl kv mgr is null + ret = OB_SUCCESS; + } + } else if (ddl_start_scn < ddl_kv_mgr_handle.get_obj()->get_start_scn()) { + need_replay = false; + if (REACH_COUNT_INTERVAL(1000L)) { + LOG_INFO("no need to replay ddl log, because the ddl start log ts is less than the value in ddl kv manager", + K(tablet_handle), K(ddl_start_scn), "ddl_start_scn_in_ddl_kv_mgr", ddl_kv_mgr_handle.get_obj()->get_start_scn()); + } + } + return ret; +} + + +// ObDDLStartReplayExecutor +ObDDLStartReplayExecutor::ObDDLStartReplayExecutor() + : ObDDLReplayExecutor(), log_(nullptr) +{ + +} + +int ObDDLStartReplayExecutor::init( + ObLS *ls, + const ObDDLStartLog &log, + const SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret), K_(is_inited)); + } else if (OB_ISNULL(ls) + || OB_UNLIKELY(!log.is_valid()) + || OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", KP(ls), K(log), K(scn), K(ret)); + } else { + ls_ = ls; + log_ = &log; + scn_ = scn; + is_inited_ = true; + } + + return ret; +} + +int ObDDLStartReplayExecutor::do_replay_(ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + ObITable::TableKey table_key = log_->get_table_key(); + ObDDLKvMgrHandle ddl_kv_mgr_handle; + bool need_replay = true; + if (OB_FAIL(check_need_replay_ddl_log_(handle, scn_, scn_, need_replay))) { + if (OB_EAGAIN != ret) { + LOG_WARN("fail to check need replay ddl log", K(ret), K(handle), K(scn_)); + } + } else if (!need_replay) { + ret = OB_NO_NEED_UPDATE; + LOG_WARN("skip replay ddl start", K(ret), "ls_id", ls_->get_ls_id(), K(handle)); + } else if (OB_FAIL(handle.get_obj()->get_ddl_kv_mgr(ddl_kv_mgr_handle, true/*try_create*/))) { + LOG_WARN("create ddl kv mgr failed", K(ret), K(handle), KPC_(log), K_(scn)); + } else if (OB_FAIL(ddl_kv_mgr_handle.get_obj()->ddl_start(*handle.get_obj(), + table_key, + scn_, + log_->get_data_format_version(), + log_->get_execution_id(), + SCN::min_scn()/*checkpoint_scn*/))) { + if (OB_TASK_EXPIRED != ret) { + LOG_WARN("start ddl log failed", K(ret), KPC_(log), K_(scn)); + } else { + ret = OB_SUCCESS; // ignored expired ddl start log + } + } else { + LOG_INFO("succeed to replay ddl start log", K(ret), KPC_(log), K_(scn)); + } + LOG_INFO("finish replay ddl start log", K(ret), K(need_replay), KPC_(log), K_(scn)); + return ret; +} + + +// ObDDLRedoReplayExecutor +ObDDLRedoReplayExecutor::ObDDLRedoReplayExecutor() + : ObDDLReplayExecutor(), log_(nullptr) +{ + +} + +int ObDDLRedoReplayExecutor::init( + ObLS *ls, + const ObDDLRedoLog &log, + const SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret), K_(is_inited)); + } else if (OB_ISNULL(ls) + || OB_UNLIKELY(!log.is_valid()) + || OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", KP(ls), K(log), K(scn), K(ret)); + } else { + ls_ = ls; + log_ = &log; + scn_ = scn; + is_inited_ = true; + } + + return ret; +} + +int ObDDLRedoReplayExecutor::do_replay_(ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + const ObDDLMacroBlockRedoInfo &redo_info = log_->get_redo_info(); + bool need_replay = true; + ObTabletMemberWrapper table_store_wrapper; + + if (OB_FAIL(check_need_replay_ddl_log_(handle, redo_info.start_scn_, scn_, need_replay))) { + if (OB_EAGAIN != ret) { + LOG_WARN("fail to check need replay ddl log", K(ret), K(handle), K_(scn)); + } + } else if (!need_replay) { + ret = OB_NO_NEED_UPDATE; + LOG_WARN("skip replay ddl redo", K(ret), "ls_id", ls_->get_ls_id(), K(handle)); + } else if (OB_UNLIKELY(!handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("need replay but tablet handle is invalid", K(ret), K(need_replay), K(handle)); + } else if (OB_FAIL(handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else { + ObMacroBlockWriteInfo write_info; + ObMacroBlockHandle macro_handle; + write_info.buffer_ = redo_info.data_buffer_.ptr(); + write_info.size_= redo_info.data_buffer_.length(); + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + const int64_t io_timeout_ms = max(DDL_FLUSH_MACRO_BLOCK_TIMEOUT / 1000L, GCONF._data_storage_io_timeout / 1000L); + ObDDLMacroBlock macro_block; + if (OB_FAIL(ObBlockManager::async_write_block(write_info, macro_handle))) { + LOG_WARN("fail to async write block", K(ret), K(write_info), K(macro_handle)); + } else if (OB_FAIL(macro_handle.wait(io_timeout_ms))) { + LOG_WARN("fail to wait macro block io finish", K(ret)); + } else if (OB_FAIL(macro_block.block_handle_.set_block_id(macro_handle.get_macro_id()))) { + LOG_WARN("set macro block id failed", K(ret), K(macro_handle.get_macro_id())); + } else { + macro_block.block_type_ = redo_info.block_type_; + macro_block.logic_id_ = redo_info.logic_id_; + macro_block.scn_ = scn_; + macro_block.buf_ = redo_info.data_buffer_.ptr(); + macro_block.size_ = redo_info.data_buffer_.length(); + macro_block.ddl_start_scn_ = redo_info.start_scn_; + if (OB_FAIL(ObDDLKVPendingGuard::set_macro_block(handle.get_obj(), macro_block))) { + LOG_WARN("set macro block into ddl kv failed", K(ret), K(handle), K(macro_block)); + } + } + } + LOG_INFO("finish replay ddl redo log", K(ret), K(need_replay), KPC_(log)); + return ret; +} + +// ObDDLCommitReplayExecutor +ObDDLCommitReplayExecutor::ObDDLCommitReplayExecutor() + : ObDDLReplayExecutor(), log_(nullptr) +{ + +} + +int ObDDLCommitReplayExecutor::init( + ObLS *ls, + const ObDDLCommitLog &log, + const SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret), K_(is_inited)); + } else if (OB_ISNULL(ls) + || OB_UNLIKELY(!log.is_valid()) + || OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", KP(ls), K(log), K(scn), K(ret)); + } else { + ls_ = ls; + log_ = &log; + scn_ = scn; + is_inited_ = true; + } + + return ret; +} + +int ObDDLCommitReplayExecutor::do_replay_(ObTabletHandle &handle) //TODO(jianyun.sjy): check it +{ + int ret = OB_SUCCESS; + ObDDLKvMgrHandle ddl_kv_mgr_handle; + bool need_replay = true; + + if (OB_FAIL(check_need_replay_ddl_log_(handle, log_->get_start_scn(), scn_, need_replay))) { + if (OB_EAGAIN != ret) { + LOG_WARN("fail to check need replay ddl log", K(ret), K(handle), K_(scn), KPC_(log)); + } + } else if (!need_replay) { + ret = OB_NO_NEED_UPDATE; + LOG_WARN("skip replay ddl commit", K(ret), "ls_id", ls_->get_ls_id(), K(handle)); + } else if (OB_FAIL(handle.get_obj()->get_ddl_kv_mgr(ddl_kv_mgr_handle))) { + LOG_WARN("get ddl kv mgr failed", K(ret), K_(scn), KPC_(log)); + } else if (OB_FAIL(ddl_kv_mgr_handle.get_obj()->set_commit_scn(scn_))) { + LOG_WARN("failed to start prepare", K(ret), KPC_(log), K_(scn)); + } else if (OB_FAIL(ddl_kv_mgr_handle.get_obj()->ddl_commit(log_->get_start_scn(), scn_))) { + if (OB_TABLET_NOT_EXIST == ret || OB_TASK_EXPIRED == ret) { + ret = OB_SUCCESS; // exit when tablet not exist or task expired + } else { + LOG_WARN("replay ddl commit log failed", K(ret), KPC_(log), K_(scn)); + } + } else { + LOG_INFO("replay ddl commit log success", K(ret), KPC_(log), K_(scn)); + } + LOG_INFO("finish replay ddl commit log", K(ret), K(need_replay), K_(scn), KPC_(log)); + return ret; +} + + +// ObSchemaChangeReplayExecutor +ObSchemaChangeReplayExecutor::ObSchemaChangeReplayExecutor() + : logservice::ObTabletReplayExecutor(), log_(nullptr), scn_() +{ + +} + +int ObSchemaChangeReplayExecutor::init( + const ObTabletSchemaVersionChangeLog &log, + const SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!log.is_valid()) + || OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(log), K(scn), K(ret)); + } else { + log_ = &log; + scn_ = scn; + is_inited_ = true; + } + + return ret; +} + +int ObSchemaChangeReplayExecutor::do_replay_(ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(handle.get_obj()->replay_schema_version_change_log(log_->get_schema_version()))) { + LOG_WARN("fail to replay schema version change log", K(ret), KPC_(log)); + } else { + LOG_INFO("replay tablet schema version change log success", KPC_(log), K_(scn)); + } + return ret; +} diff --git a/src/storage/ddl/ob_ddl_replay_executor.h b/src/storage/ddl/ob_ddl_replay_executor.h new file mode 100644 index 000000000..f9107dcac --- /dev/null +++ b/src/storage/ddl/ob_ddl_replay_executor.h @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2023 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_STORAGE_OB_DDL_REPLAY_EXECUTOR_H +#define OCEANBASE_STORAGE_OB_DDL_REPLAY_EXECUTOR_H + +#include "common/ob_tablet_id.h" +#include "logservice/replayservice/ob_tablet_replay_executor.h" +#include "storage/ddl/ob_ddl_clog.h" +#include "storage/ddl/ob_ddl_struct.h" +#include "storage/blocksstable/ob_block_sstable_struct.h" + +namespace oceanbase +{ +namespace storage +{ +class ObLS; +class ObTabletHandle; + +class ObDDLReplayExecutor : public logservice::ObTabletReplayExecutor +{ +public: + + ObDDLReplayExecutor(); + +protected: + bool is_replay_update_user_data_() const override final + { + return false; + } + + int check_need_replay_ddl_log_( + const ObTabletHandle &tablet_handle, + const share::SCN &ddl_start_scn, + const share::SCN &scn, + bool &need_replay) const; + + virtual bool is_replay_update_mds_table_() const override + { + return false; + } + +protected: + ObLS *ls_; + common::ObTabletID tablet_id_; + share::SCN scn_; +}; + + +class ObDDLStartReplayExecutor final : public ObDDLReplayExecutor +{ +public: + ObDDLStartReplayExecutor(); + + int init( + ObLS *ls, + const ObDDLStartLog &log, + const share::SCN &scn); + +protected: + // replay to the tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + int do_replay_(ObTabletHandle &handle) override; + +private: + const ObDDLStartLog *log_; +}; + + +class ObDDLRedoReplayExecutor final : public ObDDLReplayExecutor +{ +public: + ObDDLRedoReplayExecutor(); + + int init( + ObLS *ls, + const ObDDLRedoLog &log, + const share::SCN &scn); + +protected: + // replay to the tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + int do_replay_(ObTabletHandle &handle) override; + +private: + const ObDDLRedoLog *log_; +}; + + +class ObDDLCommitReplayExecutor final : public ObDDLReplayExecutor +{ +public: + ObDDLCommitReplayExecutor(); + + int init( + ObLS *ls, + const ObDDLCommitLog &log, + const share::SCN &scn); + +protected: + // replay to the tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return OB_TASK_EXPIRED, ddl task expired. + // @return other error codes, failed to replay. + int do_replay_(ObTabletHandle &handle) override; + +private: + const ObDDLCommitLog *log_; +}; + + +class ObSchemaChangeReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObSchemaChangeReplayExecutor(); + + int init( + const ObTabletSchemaVersionChangeLog &log, + const share::SCN &scn); + +protected: + bool is_replay_update_user_data_() const override + { + return false; + } + + // replay to the tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return OB_TASK_EXPIRED, ddl task expired. + // @return other error codes, failed to replay. + int do_replay_(ObTabletHandle &handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return false; + } + +private: + const ObTabletSchemaVersionChangeLog *log_; + share::SCN scn_; +}; + + +} // end namespace storage +} // end namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_DDL_REDO_LOG_REPLAYER_H diff --git a/src/storage/ddl/ob_ddl_server_client.cpp b/src/storage/ddl/ob_ddl_server_client.cpp index b36edd012..29699812c 100644 --- a/src/storage/ddl/ob_ddl_server_client.cpp +++ b/src/storage/ddl/ob_ddl_server_client.cpp @@ -31,6 +31,7 @@ namespace storage int ObDDLServerClient::create_hidden_table(const obrpc::ObCreateHiddenTableArg &arg, obrpc::ObCreateHiddenTableRes &res, int64_t &snapshot_version, sql::ObSQLSessionInfo &session) { int ret = OB_SUCCESS; + const int64_t retry_interval = 100 * 1000L; obrpc::ObCommonRpcProxy *common_rpc_proxy = GCTX.rs_rpc_proxy_; if (OB_UNLIKELY(!arg.is_valid())) { ret = OB_INVALID_ARGUMENT; @@ -38,8 +39,23 @@ int ObDDLServerClient::create_hidden_table(const obrpc::ObCreateHiddenTableArg & } else if (OB_ISNULL(common_rpc_proxy)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("common rpc proxy is null", K(ret)); - } else if (OB_FAIL(common_rpc_proxy->timeout(GCONF._ob_ddl_timeout).create_hidden_table(arg, res))) { - LOG_WARN("failed to create hidden table", KR(ret), K(arg)); + } + + while (OB_SUCC(ret)) { + if (OB_FAIL(common_rpc_proxy->timeout(GCONF._ob_ddl_timeout).create_hidden_table(arg, res))) { + LOG_WARN("failed to create hidden table", KR(ret), K(arg)); + } else { + break; + } + if (OB_FAIL(ret) && (OB_EAGAIN == ret || OB_TRANS_KILLED == ret)) { + ob_usleep(retry_interval); + if (OB_FAIL(THIS_WORKER.check_status())) { // overwrite ret + LOG_WARN("failed to check status", K(ret)); + } + } + } + + if (OB_FAIL(ret)) { } else if (OB_FAIL(OB_DDL_HEART_BEAT_TASK_CONTAINER.set_register_task_id(res.task_id_, res.tenant_id_))) { LOG_WARN("failed to set register task id", K(ret), K(res)); } diff --git a/src/storage/ddl/ob_direct_insert_sstable_ctx.cpp b/src/storage/ddl/ob_direct_insert_sstable_ctx.cpp old mode 100644 new mode 100755 index 266dc652a..1347bf084 --- a/src/storage/ddl/ob_direct_insert_sstable_ctx.cpp +++ b/src/storage/ddl/ob_direct_insert_sstable_ctx.cpp @@ -269,7 +269,7 @@ int ObSSTableInsertSliceWriter::init(const ObSSTableInsertSliceParam &slice_para } } if (OB_SUCC(ret)) { - const ObColDescIArray &col_descs = data_desc_.col_desc_array_; + const ObColDescIArray &col_descs = data_desc_.get_full_stored_col_descs(); ObTableSchemaParam schema_param(allocator_); ObRelativeTable relative_table; // Hack to prevent row reshaping from converting empty string to null. @@ -295,7 +295,7 @@ int ObSSTableInsertSliceWriter::init(const ObSSTableInsertSliceParam &slice_para ls_id_ = slice_param.ls_id_; rowkey_column_num_ = table_schema->get_rowkey_column_num(); is_index_table_ = table_schema->is_index_table(); - col_descs_ = &data_desc_.col_desc_array_; + col_descs_ = &data_desc_.get_full_stored_col_descs(); snapshot_version_ = slice_param.snapshot_version_; sql_mode_for_ddl_reshape_ = sql_mode_for_ddl_reshape; store_row_.flag_.set_flag(ObDmlFlag::DF_INSERT); @@ -700,7 +700,7 @@ int ObSSTableInsertTabletContext::prepare_index_builder_if_need(const ObTableSch } else if (OB_ISNULL(ls_handle_.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls is null", K(ret)); - } else if (OB_FAIL(data_desc.init(table_schema, + } else if (OB_FAIL(data_desc.init_as_index(table_schema, ls_handle_.get_ls()->get_ls_id(), build_param_.tablet_id_, // TODO(shuangcan): confirm this build_param_.write_major_ ? storage::MAJOR_MERGE : storage::MINOR_MERGE, @@ -708,51 +708,27 @@ int ObSSTableInsertTabletContext::prepare_index_builder_if_need(const ObTableSch build_param_.data_format_version_))) { LOG_WARN("fail to init data desc", K(ret)); } else { - data_desc.row_column_count_ = data_desc.rowkey_column_count_ + 1; - data_desc.col_desc_array_.reset(); - data_desc.need_prebuild_bloomfilter_ = false; + void *builder_buf = nullptr; data_desc.is_ddl_ = true; - if (OB_FAIL(data_desc.col_desc_array_.init(data_desc.row_column_count_))) { - LOG_WARN("failed to reserve column desc array", K(ret)); - } else if (OB_FAIL(table_schema.get_rowkey_column_ids(data_desc.col_desc_array_))) { - LOG_WARN("failed to get rowkey column ids", K(ret)); - } else if (OB_FAIL(storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(data_desc.col_desc_array_))) { - LOG_WARN("failed to add extra rowkey cols", K(ret)); - } else { - ObObjMeta meta; - meta.set_varchar(); - meta.set_collation_type(CS_TYPE_BINARY); - share::schema::ObColDesc col; - col.col_id_ = static_cast(data_desc.row_column_count_ + OB_APP_MIN_COLUMN_ID); - col.col_type_ = meta; - col.col_order_ = DESC; - void *builder_buf = nullptr; - if (OB_FAIL(data_desc.col_desc_array_.push_back(col))) { - LOG_WARN("failed to push back last col for index", K(ret), K(col)); - } else if (OB_UNLIKELY(!data_desc.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid data store desc", K(ret), K(data_desc)); - } else if (OB_ISNULL(builder_buf = allocator_.alloc(sizeof(ObSSTableIndexBuilder)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("failed to alloc memory", K(ret)); - } else if (OB_ISNULL(index_builder_ = new (builder_buf) ObSSTableIndexBuilder())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to new ObSSTableIndexBuilder", K(ret)); - } else if (OB_FAIL(index_builder_->init(data_desc, - nullptr, // macro block flush callback - ObSSTableIndexBuilder::DISABLE))) { - LOG_WARN("failed to init index builder", K(ret), K(data_desc)); + if (OB_ISNULL(builder_buf = allocator_.alloc(sizeof(ObSSTableIndexBuilder)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret)); + } else if (OB_ISNULL(index_builder_ = new (builder_buf) ObSSTableIndexBuilder())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to new ObSSTableIndexBuilder", K(ret)); + } else if (OB_FAIL(index_builder_->init(data_desc))) { + LOG_WARN("failed to init index builder", K(ret), K(data_desc)); + } + + if (OB_FAIL(ret)) { + if (nullptr != index_builder_) { + index_builder_->~ObSSTableIndexBuilder(); + index_builder_ = nullptr; } - if (OB_FAIL(ret)) { - if (nullptr != index_builder_) { - index_builder_->~ObSSTableIndexBuilder(); - index_builder_ = nullptr; - } - if (nullptr != builder_buf) { - allocator_.free(builder_buf); - builder_buf = nullptr; - } + if (nullptr != builder_buf) { + allocator_.free(builder_buf); + builder_buf = nullptr; } } } @@ -831,6 +807,7 @@ public: { int ret = ret_code_; // for LOG_WARN if (OB_LIKELY(OB_SUCCESS == ret_code_) && OB_SUCCESS != (ret_code_ = tablet_ids_.push_back(entry.first))) { + ret = ret_code_; LOG_WARN("push back tablet id failed", K(ret_code_), K(entry.first)); } return ret_code_; diff --git a/src/storage/ddl/ob_tablet_ddl_kv.cpp b/src/storage/ddl/ob_tablet_ddl_kv.cpp old mode 100644 new mode 100755 index b82aefa4f..9d91eded5 --- a/src/storage/ddl/ob_tablet_ddl_kv.cpp +++ b/src/storage/ddl/ob_tablet_ddl_kv.cpp @@ -87,6 +87,8 @@ int ObDDLKV::init_sstable_param(const share::ObLSID &ls_id, ObLSService *ls_service = MTL(ObLSService *); ObLSHandle ls_handle; ObTabletHandle tablet_handle; + const ObStorageSchema *storage_schema_ptr = nullptr; + ObArenaAllocator allocator; if (OB_UNLIKELY(!ls_id.is_valid() || !table_key.is_valid() || !ddl_start_scn.is_valid_and_not_min())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(ls_id), K(table_key), K(ddl_start_scn)); @@ -95,11 +97,13 @@ int ObDDLKV::init_sstable_param(const share::ObLSID &ls_id, } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, table_key.tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet failed", K(ret)); + } else if (OB_FAIL(tablet_handle.get_obj()->load_storage_schema(allocator, storage_schema_ptr))) { + LOG_WARN("load storage schema fail", K(ret), K(table_key)); } else { int64_t column_count = 0; - const ObStorageSchema &storage_schema = tablet_handle.get_obj()->get_storage_schema(); + const ObStorageSchema &storage_schema = *storage_schema_ptr; const int64_t root_block_size = sizeof(ObBlockMetaTree); const ObDataStoreDesc &data_desc = block_meta_tree_.get_data_desc(); if (OB_FAIL(storage_schema.get_stored_column_count_in_sstable(column_count))) { @@ -151,6 +155,7 @@ int ObDDLKV::init_sstable_param(const share::ObLSID &ls_id, } } } + ObTablet::free_storage_schema(allocator, storage_schema_ptr); return ret; } @@ -588,12 +593,15 @@ int ObDDLKV::insert_block_meta_tree(const ObDDLMacroHandle ¯o_handle, blocks LOG_WARN("insert macro block failed", K(ret), K(macro_handle), KPC(data_macro_meta)); } else { const ObDataBlockMetaVal &meta_val = data_macro_meta->get_meta_val(); - meta_.get_basic_meta().data_macro_block_count_ += 1; - meta_.get_basic_meta().data_micro_block_count_ += meta_val.micro_block_count_; - meta_.get_basic_meta().row_count_ += meta_val.row_count_; - meta_.get_basic_meta().data_checksum_ = ob_crc64_sse42(meta_.get_basic_meta().data_checksum_, &meta_val.data_checksum_, sizeof(meta_val.data_checksum_)); - meta_.get_basic_meta().occupy_size_ += meta_val.occupy_size_; - meta_.get_basic_meta().original_size_ += meta_val.original_size_; + meta_->get_basic_meta().data_macro_block_count_ += 1; + data_macro_block_count_ = meta_->get_basic_meta().data_macro_block_count_; + meta_->get_basic_meta().data_micro_block_count_ += meta_val.micro_block_count_; + meta_->get_basic_meta().max_merged_trans_version_ = max(meta_->get_basic_meta().max_merged_trans_version_, meta_val.max_merged_trans_version_); + max_merged_trans_version_ = meta_->get_basic_meta().max_merged_trans_version_ ; + meta_->get_basic_meta().row_count_ += meta_val.row_count_; + meta_->get_basic_meta().data_checksum_ = ob_crc64_sse42(meta_->get_basic_meta().data_checksum_, &meta_val.data_checksum_, sizeof(meta_val.data_checksum_)); + meta_->get_basic_meta().occupy_size_ += meta_val.occupy_size_; + meta_->get_basic_meta().original_size_ += meta_val.original_size_; } return ret; } @@ -626,7 +634,7 @@ int ObDDLKV::freeze(const SCN &freeze_scn) return ret; } -int ObDDLKV::prepare_sstable() +int ObDDLKV::prepare_sstable(const bool need_check/*=true*/) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { @@ -635,11 +643,12 @@ int ObDDLKV::prepare_sstable() } else if (!is_freezed()) { ret = OB_STATE_NOT_MATCH; LOG_WARN("ddl kv not freezed", K(ret), K(*this)); - } else if (OB_FAIL(wait_pending())) { + } else if (need_check && OB_FAIL(wait_pending())) { if (OB_EAGAIN != ret) { LOG_WARN("wait pending failed", K(ret)); } - } else { + } + if (OB_SUCC(ret)) { TCWLockGuard guard(lock_); if (OB_FAIL(block_meta_tree_.build_sorted_rowkeys())) { LOG_WARN("build sorted keys failed", K(ret), K(block_meta_tree_)); @@ -666,7 +675,8 @@ int ObDDLKV::close() } else if (OB_FAIL(block_meta_tree_.get_sorted_meta_array(meta_array))) { LOG_WARN("get sorted meta array failed", K(ret)); } else { - ObTableHandleV2 table_handle; + ObArenaAllocator allocator("DDLUpTabStore"); + ObSSTable sstable; ObTabletDDLParam ddl_param; ddl_param.tenant_id_ = MTL_ID(); ddl_param.ls_id_ = ls_id_; @@ -677,10 +687,10 @@ int ObDDLKV::close() ddl_param.start_scn_ = ddl_start_scn_; ddl_param.snapshot_version_ = snapshot_version_; ddl_param.data_format_version_ = data_format_version_; - if (OB_FAIL(ObTabletDDLUtil::create_ddl_sstable(ddl_param, meta_array, nullptr/*first_ddl_sstable*/, table_handle))) { + if (OB_FAIL(ObTabletDDLUtil::create_ddl_sstable(ddl_param, meta_array, nullptr/*first_ddl_sstable*/, allocator, sstable))) { LOG_WARN("create ddl sstable failed", K(ret), K(ddl_param)); - } else if (OB_FAIL(ObTabletDDLUtil::update_ddl_table_store(ddl_param, table_handle))) { - LOG_WARN("update ddl table store failed", K(ret), K(ddl_param), K(table_handle)); + } else if (OB_FAIL(ObTabletDDLUtil::update_ddl_table_store(ddl_param, allocator, sstable))) { + LOG_WARN("update ddl table store failed", K(ret), K(ddl_param), K(sstable)); } else { is_closed_ = true; LOG_INFO("ddl kv closed success", K(*this)); diff --git a/src/storage/ddl/ob_tablet_ddl_kv.h b/src/storage/ddl/ob_tablet_ddl_kv.h index d0ef32821..c630b0d3a 100644 --- a/src/storage/ddl/ob_tablet_ddl_kv.h +++ b/src/storage/ddl/ob_tablet_ddl_kv.h @@ -112,6 +112,9 @@ class ObDDLKV : public blocksstable::ObSSTable public: ObDDLKV(); virtual ~ObDDLKV(); + virtual void inc_ref() override { ATOMIC_AAF(&ref_cnt_, 1); } + virtual int64_t dec_ref() override { return ATOMIC_SAF(&ref_cnt_, 1 /* just sub 1 */); } + virtual int64_t get_ref() const override { return ObITable::get_ref(); } int init(const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const share::SCN &ddl_start_scn, @@ -124,7 +127,7 @@ public: int freeze(const share::SCN &freeze_scn); bool is_freezed() const { return ATOMIC_LOAD(&is_freezed_); } int close(); - int prepare_sstable(); + int prepare_sstable(const bool need_check = true); bool is_closed() const { return is_closed_; } share::SCN get_min_scn() const { return min_scn_; } share::SCN get_freeze_scn() const { return freeze_scn_; } diff --git a/src/storage/ddl/ob_tablet_ddl_kv_mgr.cpp b/src/storage/ddl/ob_tablet_ddl_kv_mgr.cpp index 3587a5102..c3771fe16 100644 --- a/src/storage/ddl/ob_tablet_ddl_kv_mgr.cpp +++ b/src/storage/ddl/ob_tablet_ddl_kv_mgr.cpp @@ -332,7 +332,8 @@ int ObTabletDDLKvMgr::get_rec_scn(SCN &rec_scn) LOG_WARN("failed to get log stream", K(ret), K(ls_id_)); } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObTabletCommon::DEFAULT_GET_TABLET_NO_WAIT, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), K(ls_id_), K(tablet_id_)); } @@ -395,7 +396,8 @@ int ObTabletDDLKvMgr::set_commit_scn(const SCN &commit_scn) LOG_WARN("failed to get log stream", K(ret), K(ls_id_)); } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), K(ls_id_), K(tablet_id_)); } else { ObLatchWGuard guard(lock_, ObLatchIds::TABLET_DDL_KV_MGR_LOCK); @@ -562,7 +564,8 @@ int ObTabletDDLKvMgr::online() LOG_WARN("failed to get log stream", K(ret), K(ls_id_)); } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), K(ls_id_), K(tablet_id_)); } else if (OB_FAIL(cleanup())) { LOG_WARN("failed to cleanup ddl kv mgr", K(ret), KPC(tablet_handle.get_obj())); @@ -607,7 +610,8 @@ int ObTabletDDLKvMgr::register_to_tablet(const SCN &ddl_start_scn, ObDDLKvMgrHan LOG_WARN("failed to get log stream", K(ret), K(ls_id_)); } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), K(ls_id_), K(tablet_id_)); } else { ObLatchWGuard guard(lock_, ObLatchIds::TABLET_DDL_KV_MGR_LOCK); @@ -646,7 +650,8 @@ int ObTabletDDLKvMgr::unregister_from_tablet(const SCN &ddl_start_scn, ObDDLKvMg LOG_WARN("failed to get log stream", K(ret), K(ls_id_)); } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), K(ls_id_), K(tablet_id_)); } else { ObLatchWGuard guard(lock_, ObLatchIds::TABLET_DDL_KV_MGR_LOCK); @@ -708,6 +713,8 @@ int ObTabletDDLKvMgr::update_tablet(const SCN &start_scn, const int64_t snapshot int ret = OB_SUCCESS; ObLSHandle ls_handle; ObTabletHandle tablet_handle; + ObArenaAllocator tmp_arena("DDLUpdateTblTmp"); + const ObStorageSchema *storage_schema = nullptr; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); @@ -719,15 +726,18 @@ int ObTabletDDLKvMgr::update_tablet(const SCN &start_scn, const int64_t snapshot } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), K(ls_id_), K(tablet_id_)); + } else if (OB_FAIL(tablet_handle.get_obj()->load_storage_schema(tmp_arena, storage_schema))) { + LOG_WARN("failed to load storage schema", K(ret), K(tablet_handle)); } else { - ObTableHandleV2 table_handle; // empty + ObSSTable sstable; const int64_t rebuild_seq = ls_handle.get_ls()->get_rebuild_seq(); ObTabletHandle new_tablet_handle; + ObUpdateTableStoreParam param(tablet_handle.get_obj()->get_snapshot_version(), ObVersionRange::MIN_VERSION, // multi_version_start - &tablet_handle.get_obj()->get_storage_schema(), + storage_schema, rebuild_seq); param.ddl_info_.keep_old_ddl_sstable_ = false; param.ddl_info_.ddl_start_scn_ = start_scn; @@ -735,22 +745,22 @@ int ObTabletDDLKvMgr::update_tablet(const SCN &start_scn, const int64_t snapshot param.ddl_info_.ddl_checkpoint_scn_ = ddl_checkpoint_scn; param.ddl_info_.ddl_execution_id_ = execution_id_; param.ddl_info_.data_format_version_ = data_format_version_; - if (OB_FAIL(create_empty_ddl_sstable(table_handle))) { + if (OB_FAIL(create_empty_ddl_sstable(tmp_arena, sstable))) { LOG_WARN("create empty ddl sstable failed", K(ret)); - } else if (FALSE_IT(param.table_handle_ = table_handle)) { + } else if (FALSE_IT(param.sstable_ = &sstable)) { } else if (OB_FAIL(ls_handle.get_ls()->update_tablet_table_store(tablet_id_, param, new_tablet_handle))) { LOG_WARN("failed to update tablet table store", K(ret), K(ls_id_), K(tablet_id_), K(param)); } else { LOG_INFO("update tablet success", K(ls_id_), K(tablet_id_), K(param), K(start_scn), K(snapshot_version), K(ddl_checkpoint_scn)); } } + ObTablet::free_storage_schema(tmp_arena, storage_schema); return ret; } -int ObTabletDDLKvMgr::create_empty_ddl_sstable(ObTableHandleV2 &table_handle) +int ObTabletDDLKvMgr::create_empty_ddl_sstable(common::ObArenaAllocator &allocator, blocksstable::ObSSTable &sstable) { int ret = OB_SUCCESS; - table_handle.reset(); ObTabletDDLParam ddl_param; if (OB_FAIL(get_ddl_param(ddl_param))) { LOG_WARN("get ddl param failed", K(ret)); @@ -759,7 +769,7 @@ int ObTabletDDLKvMgr::create_empty_ddl_sstable(ObTableHandleV2 &table_handle) ddl_param.table_key_.scn_range_.start_scn_ = SCN::scn_dec(start_scn_); ddl_param.table_key_.scn_range_.end_scn_ = start_scn_; ObArray empty_meta_array; - if (OB_FAIL(ObTabletDDLUtil::create_ddl_sstable(ddl_param, empty_meta_array, nullptr/*first_ddl_sstable*/, table_handle))) { + if (OB_FAIL(ObTabletDDLUtil::create_ddl_sstable(ddl_param, empty_meta_array, nullptr/*first_ddl_sstable*/, allocator, sstable))) { LOG_WARN("create empty ddl sstable failed", K(ret)); } } @@ -771,6 +781,8 @@ int ObTabletDDLKvMgr::update_ddl_major_sstable() int ret = OB_SUCCESS; ObLSHandle ls_handle; ObTabletHandle tablet_handle; + ObArenaAllocator allocator; + const ObStorageSchema *storage_schema = nullptr; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); @@ -779,13 +791,15 @@ int ObTabletDDLKvMgr::update_ddl_major_sstable() } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("get tablet handle failed", K(ret), K(ls_id_), K(tablet_id_)); + } else if (OB_FAIL(tablet_handle.get_obj()->load_storage_schema(allocator, storage_schema))) { + LOG_WARN("load storage schema failed", K(ret), K(ls_id_), K(tablet_id_)); } else { ObTabletHandle new_tablet_handle; ObUpdateTableStoreParam param(tablet_handle.get_obj()->get_snapshot_version(), ObVersionRange::MIN_VERSION, // multi_version_start - &tablet_handle.get_obj()->get_storage_schema(), + storage_schema, ls_handle.get_ls()->get_rebuild_seq()); param.ddl_info_.keep_old_ddl_sstable_ = true; param.ddl_info_.ddl_commit_scn_ = commit_scn_; @@ -793,6 +807,7 @@ int ObTabletDDLKvMgr::update_ddl_major_sstable() LOG_WARN("failed to update tablet table store", K(ret), K(ls_id_), K(tablet_id_), K(param)); } } + ObTablet::free_storage_schema(allocator, storage_schema); return ret; } diff --git a/src/storage/ddl/ob_tablet_ddl_kv_mgr.h b/src/storage/ddl/ob_tablet_ddl_kv_mgr.h index 83a7e65e6..304cd2e23 100644 --- a/src/storage/ddl/ob_tablet_ddl_kv_mgr.h +++ b/src/storage/ddl/ob_tablet_ddl_kv_mgr.h @@ -93,13 +93,13 @@ private: int get_ddl_kvs_unlock(const bool frozen_only, ObTablesHandleArray &kv_handle_array); int64_t get_count_nolock() const; int update_ddl_major_sstable(); - int create_empty_ddl_sstable(ObTableHandleV2 &table_handle); + int create_empty_ddl_sstable(common::ObArenaAllocator &allocator, blocksstable::ObSSTable &sstable); void cleanup_unlock(); void destroy(); bool is_commit_success_unlock() const; public: static const int64_t MAX_DDL_KV_CNT_IN_STORAGE = 16; - static const int64_t TRY_LOCK_TIMEOUT = 1 * 1000000; // 1s + static const int64_t TRY_LOCK_TIMEOUT = 10 * 1000000; // 10s private: bool is_inited_; share::SCN success_start_scn_; diff --git a/src/storage/direct_load/ob_direct_load_io_callback.cpp b/src/storage/direct_load/ob_direct_load_io_callback.cpp index 28ec38086..597dd04ce 100644 --- a/src/storage/direct_load/ob_direct_load_io_callback.cpp +++ b/src/storage/direct_load/ob_direct_load_io_callback.cpp @@ -17,45 +17,37 @@ namespace storage using namespace common; ObDirectLoadIOCallback::ObDirectLoadIOCallback(uint64_t tenant_id) - : tenant_id_(tenant_id), io_buf_(nullptr), data_buf_(nullptr) + : tenant_id_(tenant_id), data_buf_(nullptr) { } ObDirectLoadIOCallback::~ObDirectLoadIOCallback() { - if (nullptr != io_buf_) { - ob_free_align(io_buf_); - io_buf_ = nullptr; + if (nullptr != data_buf_) { + ob_free(data_buf_); + data_buf_ = nullptr; } - data_buf_ = nullptr; } -int ObDirectLoadIOCallback::alloc_io_buf(char *&io_buf, int64_t &size, int64_t &offset) +int ObDirectLoadIOCallback::inner_process(const char *data_buffer, const int64_t size) { int ret = OB_SUCCESS; - const int64_t aligned_offset = lower_align(offset, DIO_READ_ALIGN_SIZE); - const int64_t aligned_size = upper_align(size + offset - aligned_offset, DIO_READ_ALIGN_SIZE); - ObMemAttr attr; - attr.tenant_id_ = tenant_id_; - attr.label_ = ObModIds::OB_SQL_LOAD_DATA; - if (OB_ISNULL(io_buf_ = - static_cast(ob_malloc_align(DIO_READ_ALIGN_SIZE, aligned_size, attr)))) { + if (OB_UNLIKELY(size <= 0 || data_buffer == nullptr)) { + ret = OB_INVALID_DATA; + LOG_WARN("invalid data buffer size", K(ret), K(size), KP(data_buffer)); + } else if (OB_ISNULL(data_buf_ = static_cast(ob_malloc(size, "LoadIO")))) { ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to allocate memory", KR(ret), K(aligned_size)); + LOG_WARN("Fail to allocate memory, ", K(ret)); } else { - data_buf_ = io_buf_ + (offset - aligned_offset); - io_buf = io_buf_; - size = aligned_size; - offset = aligned_offset; + MEMCPY(data_buf_, data_buffer, size); + } + if (OB_FAIL(ret) && nullptr != data_buf_) { + ob_free(data_buf_); + data_buf_ = nullptr; } return ret; } -int ObDirectLoadIOCallback::inner_process(const bool is_success) -{ - return OB_SUCCESS; -} - int ObDirectLoadIOCallback::inner_deep_copy(char *buf, const int64_t buf_len, ObIOCallback *&copied_callback) const { diff --git a/src/storage/direct_load/ob_direct_load_io_callback.h b/src/storage/direct_load/ob_direct_load_io_callback.h index cd5e85bd3..50bebfd74 100644 --- a/src/storage/direct_load/ob_direct_load_io_callback.h +++ b/src/storage/direct_load/ob_direct_load_io_callback.h @@ -18,16 +18,14 @@ public: virtual ~ObDirectLoadIOCallback(); const char *get_data() override { return data_buf_; } int64_t size() const override { return sizeof(*this); } - int alloc_io_buf(char *&io_buf, int64_t &size, int64_t &offset) override; void set_tenant_id(uint64_t tenant_id) { tenant_id_ = tenant_id; } - TO_STRING_KV(K_(io_buf), K_(data_buf)); + TO_STRING_KV(K_(data_buf)); protected: - int inner_process(const bool is_success) override; + int inner_process(const char *data_buffer, const int64_t size) override; int inner_deep_copy(char *buf, const int64_t buf_len, ObIOCallback *&copied_callback) const override; private: uint64_t tenant_id_; - char *io_buf_; char *data_buf_; }; diff --git a/src/storage/direct_load/ob_direct_load_origin_table.cpp b/src/storage/direct_load/ob_direct_load_origin_table.cpp old mode 100644 new mode 100755 index 8010b9a44..0ee37f717 --- a/src/storage/direct_load/ob_direct_load_origin_table.cpp +++ b/src/storage/direct_load/ob_direct_load_origin_table.cpp @@ -105,15 +105,15 @@ int ObDirectLoadOriginTable::prepare_tables() int ret = OB_SUCCESS; ObITable *table = nullptr; ObSSTable *major_sstable = nullptr; - ObTabletTableIterator tablet_table_iter; - tablet_table_iter.tablet_handle_ = tablet_handle_; - if (OB_FAIL(tablet_handle_.get_obj()->get_read_tables(INT64_MAX, tablet_table_iter, - false /*allow_not_ready*/))) { + table_iter_.reset(); + if (OB_FAIL(table_iter_.set_tablet_handle(tablet_handle_))) { + LOG_WARN("Failed to set tablet handle to tablet table iter", K(ret)); + } else if (OB_FAIL(table_iter_.refresh_read_tables_from_tablet(INT64_MAX, false /*allow_not_ready*/))) { LOG_WARN("fail to get read tables", KR(ret), K(tablet_handle_)); } // find major sstable while (OB_SUCC(ret)) { - if (OB_FAIL(tablet_table_iter.table_iter_.get_next(table))) { + if (OB_FAIL(table_iter_.table_iter()->get_next(table))) { if (OB_UNLIKELY(OB_ITER_END != ret)) { LOG_WARN("fail to get next table", KR(ret)); } else { @@ -134,8 +134,6 @@ int ObDirectLoadOriginTable::prepare_tables() if (OB_ISNULL(major_sstable)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected not found major sstable", KR(ret), KPC(table)); - } else if (OB_FAIL(table_iter_.copy(tablet_table_iter.table_iter_))) { - LOG_WARN("fail to copy table iter", KR(ret)); } else { major_sstable_ = major_sstable; } @@ -250,8 +248,9 @@ int ObDirectLoadOriginTableScanner::init_table_access_param() } } if (OB_SUCC(ret)) { + //TODO(jianming.cjq): check init_dml_access_param if (OB_FAIL(table_access_param_.init_dml_access_param(relative_table, - origin_table_->get_tablet_handle().get_obj()->get_full_read_info(), + origin_table_->get_tablet_handle().get_obj()->get_rowkey_read_info(), schema_param_, &col_ids_))) { LOG_WARN("fail to init merge param", KR(ret)); @@ -297,8 +296,9 @@ int ObDirectLoadOriginTableScanner::init_table_access_ctx() int ObDirectLoadOriginTableScanner::init_get_table_param() { int ret = OB_SUCCESS; - get_table_param_.tablet_iter_.tablet_handle_ = origin_table_->get_tablet_handle(); - if (OB_FAIL(get_table_param_.tablet_iter_.table_iter_.copy(origin_table_->get_table_iter()))) { + if (OB_FAIL(get_table_param_.tablet_iter_.set_tablet_handle(origin_table_->get_tablet_handle()))) { + LOG_WARN("Failed to set tablet handle to tablet table iter", K(ret)); + } else if (OB_FAIL(get_table_param_.tablet_iter_.refresh_read_tables_from_tablet(INT64_MAX, false /*allow_not_ready*/))) { LOG_WARN("fail to copy table iter", KR(ret)); } return ret; diff --git a/src/storage/direct_load/ob_direct_load_origin_table.h b/src/storage/direct_load/ob_direct_load_origin_table.h old mode 100644 new mode 100755 index 1583c1903..00ab58fae --- a/src/storage/direct_load/ob_direct_load_origin_table.h +++ b/src/storage/direct_load/ob_direct_load_origin_table.h @@ -49,7 +49,7 @@ public: bool is_valid() const { return is_inited_; } const ObDirectLoadOriginTableMeta &get_meta() const {return meta_; } const ObTabletHandle &get_tablet_handle() const { return tablet_handle_; } - const ObTableStoreIterator &get_table_iter() const { return table_iter_; } + const ObTableStoreIterator &get_table_iter() const { return *(table_iter_.table_iter()); } blocksstable::ObSSTable *get_major_sstable() const { return major_sstable_; } TO_STRING_KV(K_(meta), K_(tablet_handle), K_(table_iter), KP_(major_sstable)); private: @@ -57,7 +57,7 @@ private: private: ObDirectLoadOriginTableMeta meta_; ObTabletHandle tablet_handle_; - ObTableStoreIterator table_iter_; + ObTabletTableIterator table_iter_; blocksstable::ObSSTable *major_sstable_; bool is_inited_; }; @@ -89,4 +89,4 @@ private: }; } // namespace storage -} // namespace oceanbase \ No newline at end of file +} // namespace oceanbase diff --git a/src/storage/direct_load/ob_direct_load_range_splitter.cpp b/src/storage/direct_load/ob_direct_load_range_splitter.cpp index bb033370b..b7d795413 100644 --- a/src/storage/direct_load/ob_direct_load_range_splitter.cpp +++ b/src/storage/direct_load/ob_direct_load_range_splitter.cpp @@ -67,7 +67,7 @@ int ObDirectLoadRangeSplitUtils::construct_rowkey_iter( int ObDirectLoadRangeSplitUtils::construct_rowkey_iter( ObSSTable *sstable, const ObDatumRange &scan_range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, ObIAllocator &allocator, ObIDirectLoadDatumRowkeyIterator *&rowkey_iter) { @@ -478,14 +478,14 @@ int ObDirectLoadMergeRangeSplitter::construct_origin_table_rowkey_iter( ObIDirectLoadDatumRowkeyIterator *rowkey_iter = nullptr; if (OB_FAIL(ObDirectLoadRangeSplitUtils::construct_rowkey_iter( origin_table->get_major_sstable(), scan_range_, - origin_table->get_tablet_handle().get_obj()->get_index_read_info(), allocator_, + origin_table->get_tablet_handle().get_obj()->get_rowkey_read_info(), allocator_, rowkey_iter))) { LOG_WARN("fail to construct rowkey iter", KR(ret)); } else if (OB_FAIL(rowkey_iters_.push_back(rowkey_iter))) { LOG_WARN("fail to push back rowkey iter", KR(ret)); } else { total_block_count_ += - origin_table->get_major_sstable()->get_meta().get_basic_meta().data_macro_block_count_; + origin_table->get_major_sstable()->get_data_macro_block_count(); } return ret; } @@ -595,14 +595,14 @@ int ObDirectLoadMultipleMergeTabletRangeSplitter::construct_origin_table_rowkey_ ObIDirectLoadDatumRowkeyIterator *rowkey_iter = nullptr; if (OB_FAIL(ObDirectLoadRangeSplitUtils::construct_rowkey_iter( origin_table->get_major_sstable(), scan_range_, - origin_table->get_tablet_handle().get_obj()->get_index_read_info(), allocator_, + origin_table->get_tablet_handle().get_obj()->get_rowkey_read_info(), allocator_, rowkey_iter))) { LOG_WARN("fail to construct rowkey iter", KR(ret)); } else if (OB_FAIL(rowkey_iters_.push_back(rowkey_iter))) { LOG_WARN("fail to push back rowkey iter", KR(ret)); } else { total_block_count_ += - origin_table->get_major_sstable()->get_meta().get_basic_meta().data_macro_block_count_; + origin_table->get_major_sstable()->get_data_macro_block_count(); } return ret; } @@ -791,7 +791,7 @@ int ObDirectLoadMultipleMergeRangeSplitter::get_rowkeys_by_origin( scan_range.set_whole_range(); if (OB_FAIL(ObDirectLoadRangeSplitUtils::construct_rowkey_iter( origin_table->get_major_sstable(), scan_range, - origin_table->get_tablet_handle().get_obj()->get_index_read_info(), allocator, + origin_table->get_tablet_handle().get_obj()->get_rowkey_read_info(), allocator, rowkey_iter))) { LOG_WARN("fail to construct rowkey iter", KR(ret)); } else { diff --git a/src/storage/direct_load/ob_direct_load_range_splitter.h b/src/storage/direct_load/ob_direct_load_range_splitter.h index 845517583..c53778de8 100644 --- a/src/storage/direct_load/ob_direct_load_range_splitter.h +++ b/src/storage/direct_load/ob_direct_load_range_splitter.h @@ -18,7 +18,7 @@ class ObSSTable; namespace storage { class ObDirectLoadTableDataDesc; -class ObTableReadInfo; +class ObITableReadInfo; class ObDirectLoadOriginTable; class ObDirectLoadSSTable; class ObDirectLoadMultipleSSTable; @@ -30,7 +30,7 @@ public: ObIDirectLoadDatumRowkeyIterator *&rowkey_iter); static int construct_rowkey_iter(blocksstable::ObSSTable *sstable, const blocksstable::ObDatumRange &scan_range, - const ObTableReadInfo &index_read_info, + const storage::ObITableReadInfo &index_read_info, common::ObIAllocator &allocator, ObIDirectLoadDatumRowkeyIterator *&rowkey_iter); static int construct_rowkey_iter(ObDirectLoadMultipleSSTable *sstable, diff --git a/src/storage/high_availability/ob_finish_transfer.cpp b/src/storage/high_availability/ob_finish_transfer.cpp new file mode 100644 index 000000000..9a6b37b34 --- /dev/null +++ b/src/storage/high_availability/ob_finish_transfer.cpp @@ -0,0 +1,1103 @@ +/** + * 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. + */ +#define USING_LOG_PREFIX STORAGE +#include "share/ob_rs_mgr.h" +#include "share/ob_rpc_struct.h" +#include "ob_storage_ha_utils.h" +#include "logservice/ob_log_service.h" +#include "storage/tx/ob_multi_data_source.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/tablet/ob_tablet.h" +#include "share/transfer/ob_transfer_task_operator.h" +#include "storage/high_availability/ob_finish_transfer.h" +#include "storage/high_availability/ob_transfer_service.h" +#include "storage/high_availability/ob_transfer_lock_utils.h" +#include "storage/tablet/ob_tablet.h" + +using namespace oceanbase::common; +using namespace oceanbase::share; +using namespace oceanbase::observer; +using namespace oceanbase::transaction; + +namespace oceanbase { +namespace storage { + +//errsim def +ERRSIM_POINT_DEF(EN_DOING_UNLOCK_TRANSFER_MEMBER_LIST_FAILED); +ERRSIM_POINT_DEF(EN_DOING_LOCK_TRANSFER_TASK_FAILED); +ERRSIM_POINT_DEF(EN_DOING_LOCK_MEMBER_LIST_FAILED); +ERRSIM_POINT_DEF(EN_FINISH_TRANSFER_IN_FAILED); +ERRSIM_POINT_DEF(EN_DOING_WAIT_ALL_DEST_TABLET_NORAML); +ERRSIM_POINT_DEF(EN_FINISH_TRANSFER_OUT_FAILED); +ERRSIM_POINT_DEF(EN_DOING_UPDATE_TRANSFER_TASK_FAILED); +ERRSIM_POINT_DEF(EN_DOING_COMMIT_TRANS_FAILED); + +ObTxFinishTransfer::ObTxFinishTransfer() + : is_inited_(false), + task_id_(), + tenant_id_(OB_INVALID_ID), + src_ls_id_(), + dest_ls_id_(), + mutex_(), + cond_(), + sql_proxy_(NULL) +{} + +ObTxFinishTransfer::~ObTxFinishTransfer() +{} + +int ObTxFinishTransfer::init(const ObTransferTaskID &task_id, const uint64_t tenant_id, const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, common::ObMySQLProxy &sql_proxy) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("finish transfer do not init", K(ret)); + } else if (!task_id.is_valid() || OB_INVALID_ID == tenant_id || !src_ls_id.is_valid() || !dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(task_id), K(tenant_id), K(src_ls_id), K(dest_ls_id)); + } else if (OB_FAIL(cond_.init(ObWaitEventIds::STORAGE_HA_FINISH_TRANSFER))) { + LOG_WARN("failed to init condition", K(ret)); + } else { + task_id_ = task_id; + tenant_id_ = tenant_id; + src_ls_id_ = src_ls_id; + dest_ls_id_ = dest_ls_id; + sql_proxy_ = &sql_proxy; + is_inited_ = true; + } + return ret; +} + +int ObTxFinishTransfer::process() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tx finish transfer do not init", K(ret)); + } else if (OB_FAIL(do_tx_transfer_doing_(task_id_, tenant_id_, src_ls_id_, dest_ls_id_))) { + LOG_WARN("failed to do tx transfer doing", K(ret), K_(task_id), K_(tenant_id), K_(src_ls_id), K_(dest_ls_id)); + } else { + LOG_INFO("process tx finish transfer", K_(task_id), K_(tenant_id), K_(src_ls_id), K_(dest_ls_id)); + } + return ret; +} + +int ObTxFinishTransfer::do_tx_transfer_doing_(const ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObMySQLTransaction trans; + ObArray tablet_list; + ObMemberList member_list; + int64_t quorum = 0; + observer::ObInnerSQLConnection *conn = NULL; + SCN start_scn; + SCN finish_scn; + bool is_majority_passed = false; + share::ObRsMgr *rs_mgr = GCTX.rs_mgr_; + obrpc::ObSrvRpcProxy *svr_rpc_proxy = GCTX.srv_rpc_proxy_; + int64_t result = OB_SUCCESS; + common::ObArray member_addr_list; + bool majority_backfilled = false; + ObLSLocation ls_location; + bool is_leader = false; + bool is_ready = false; + ObTransferService *transfer_service = NULL; + const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; + ObLSHandle ls_handle; + ObDisplayTabletList table_lock_tablet_list; + transaction::tablelock::ObTableLockOwnerID lock_owner_id; + ObTimeoutCtx timeout_ctx; + if (!task_id.is_valid() || OB_INVALID_ID == tenant_id || !src_ls_id.is_valid() || !dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(task_id), K(tenant_id), K(src_ls_id), K(dest_ls_id)); + } else if (OB_ISNULL(transfer_service = MTL_WITH_CHECK_TENANT(ObTransferService *, tenant_id))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer service is NULL", K(ret), K(tenant_id)); + } else if (OB_FAIL(check_self_ls_leader_(dest_ls_id, is_leader))) { + LOG_WARN("failed to check self ls leader", K(ret), K(dest_ls_id)); + } else if (!is_leader) { + ret = OB_IS_CHANGING_LEADER; + LOG_WARN("self is not leader of dest ls", K(ret), K(dest_ls_id)); + } else if (OB_FAIL(get_ls_member_list_(tenant_id, dest_ls_id, member_list))) { + LOG_WARN("failed to get ls member list", K(ret), K(tenant_id), K(dest_ls_id)); + } // TODO(yangyi.yyy): get member list and check self is leader together + // 1. Release the locking relationship of the member list of dest_ls and src_ls + // (the interface for binding and releasing the locking relationship needs to have the ability to re-entrant) + else if (OB_FAIL(unlock_src_and_dest_ls_member_list_(tenant_id, src_ls_id, dest_ls_id, member_list))) { + LOG_WARN("failed to unlock src and dest ls member list", K(ret), K(tenant_id), K(src_ls_id), K(dest_ls_id)); + } + // get tablet info list from inner table + else if (OB_FAIL(get_transfer_tablet_info_from_inner_table_( + task_id, tenant_id, tablet_list, start_scn, table_lock_tablet_list, lock_owner_id))) { + LOG_WARN("failed to get transfer tablet list", K(ret), K(task_id), K(tenant_id)); + } else if (OB_FAIL(get_transfer_quorum_(member_list, quorum))) { + LOG_WARN("failed to get transfer quorum", K(ret), K(member_list)); + } + // precheck if majority ls logical table replaced + else if (OB_FAIL(check_ls_logical_table_replaced( + tenant_id, dest_ls_id, member_list, tablet_list, quorum, is_ready))) { + LOG_WARN("wait all ls replica logical table replaced failed", + K(ret), + K(tenant_id), + K(dest_ls_id), + K(member_list), + K(quorum)); + } else if (!is_ready) { + LOG_INFO("transfer in tablet not ready", K(ret), K(tenant_id), K(dest_ls_id)); + transfer_service->wakeup(); + } else if (OB_FAIL(get_ls_handle_(tenant_id, dest_ls_id_, ls_handle))) { + LOG_WARN("failed to get ls handle", K(ret)); + } else { + const ObTransferLockStatus lock_status(ObTransferLockStatus::DOING); +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "BEFORE_TRANSFER_DOING_START_TRANS"); +#endif + DEBUG_SYNC(SWITCH_LEADER_BEFORE_TRANSFER_DOING_START_TRANS); + ObTimeoutCtx timeout_ctx; + // 2. The leader of dest_ls starts a transaction TRANS_TRANSFER_FINISH + if (FAILEDx(start_trans_(tenant_id, trans, timeout_ctx))) { + LOG_WARN("failed to start trans", K(ret), K(tenant_id)); + } else { +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "AFTER_TRANSFER_DOING_START_TRANS"); +#endif + DEBUG_SYNC(SWITCH_LEADER_AFTER_TRANSFER_DOING_START_TRANS); + if (FAILEDx(select_transfer_task_for_update_(task_id, trans))) { + LOG_WARN("failed to select for update", K(ret), K(task_id)); + } + // 3. The dest_ls leader checks whether the transfer tablet corresponding to the src_ls copy corresponding to the + // majority replica has been backfilled. Here, try to ensure that it is all completed, and then start the second + // step. Only if the threshold is exceeded will there be a majority. + // a) This step needs to first lock the member list of dest_ls + // b) The dest_ls leader checks whether the majority has completed backfilling + // c) Unlock the member list of dest_ls This step and the migration still need to be mutually exclusive, + // because there may be dest_leader checking that the majority meets + // the conditions. After unlocking the member list, a copy is migrated in. This copy replaces one of the + // majority, resulting in a majority If the dispatch does not meet the conditions, the following chapters on + // transfer and migration will discuss + else if (OB_FAIL(lock_ls_member_list_(tenant_id, dest_ls_id, member_list, lock_status))) { + LOG_WARN("failed to lock ls member list", K(ret), K(tenant_id), K(dest_ls_id), K(member_list)); + } else if (OB_FAIL(check_ls_logical_table_replaced( + tenant_id, dest_ls_id, member_list, tablet_list, quorum, is_ready))) { + LOG_WARN("wait all ls replica logical table replaced failed", + K(ret), + K(tenant_id), + K(dest_ls_id), + K(member_list), + K(quorum)); + } else if (!is_ready) { + LOG_INFO("transfer in tablet not ready", K(ret), K(tenant_id), K(dest_ls_id)); + transfer_service->wakeup(); + } else { + // 4. The leader node of dest_ls registers the multi-source transaction + // ObInnerSQLConnection->register_multi_source_data, and the type is TX_FINISH_TRANSFER_IN (two-way barrier) + // The content of the log is src_ls_id, dest_ls_id, tablet_list. This step requires forcibly flushing the redo + // log. The purpose of flushing redo here is to obtain finish_scn and check whether the dest_ls log playback is + // new enough for src_ls. + // a) When the leader of dest_ls receives the resgister_succ, it checks that its replay scn is greater than + // start_scn, and has completed the replacement of the logical table. + // b) When the leader and follower of dest_ls receive the on_redo stage, + // they record the scn returned by on_redo as finish_scn. Check that your replay scn is greater than + // start_scn, and the replacement of the logical table has been completed. If it has been completed, + // change the ObTabletStatus of transfer_tablets to NORMAL. If it is not completed, the playback of + // ob_redo needs to be stuck. + if (OB_ISNULL(conn = dynamic_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("conn_ is NULL", K(ret)); + } else if (OB_FAIL(do_tx_finish_transfer_in_( + task_id, tenant_id, src_ls_id, dest_ls_id, start_scn, tablet_list, conn))) { + LOG_WARN("failed to do tx finish transfer in", + K(ret), + K(task_id), + K(tenant_id), + K(src_ls_id), + K(dest_ls_id), + K(tablet_list)); + } + #ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "BETWEEN_REGISTER_FINISH_TRANSFER_IN_AND_OUT"); + #endif + DEBUG_SYNC(SWITCH_LEADER_BETWEEN_FINISH_TRANSFER_IN_AND_OUT); + // 5. The leader of dest ls checks that majority ls replia satisfies the finish_scn of the playback + // (the step of non-multi-source transaction, only the leader of dest ls does). + // Abort is required if no majority replays to finish_scn beyond the threshold. + // Here, the leader of dest_ls checks the destination of the majority to be more secure, and if the + // FINISH_TRANSFER step fails, it will not affect the reading and writing of dest_ls, but the main switch will + // have an impact, so here we will also guarantee all within a certain threshold. Copy, after a certain threshold + // is exceeded, the majority is guaranteed; here, the transfer seq at the log stream level also needs to be + // incremented (in TX_START_TRASNFER_IN) + if (FAILEDx(wait_transfer_tablet_status_normal_(tenant_id, dest_ls_id, tablet_list, start_scn, timeout_ctx, finish_scn))) { + LOG_WARN("failed to wait tablet status normal", K(ret), K(tenant_id), K(dest_ls_id), K(tablet_list)); + } else if (OB_FAIL(member_list.get_addr_array(member_addr_list))) { + LOG_WARN("failed to get addr array", K(ret), K(member_list)); + } else if (OB_FAIL(wait_all_ls_replica_replay_scn_(task_id, tenant_id, dest_ls_id, + member_addr_list, finish_scn, quorum, timeout_ctx, is_majority_passed))) { + LOG_WARN("failed to check ls replica replay scn", + K(ret), + K(tenant_id), + K(dest_ls_id), + K(member_addr_list), + K(finish_scn)); + } else if (!is_majority_passed) { + ret = OB_TIMEOUT; + LOG_WARN("majority replay scn not passed", K(ret)); + } + // 6. The leader of dest_ls registers a multi-source transaction, + // and the type is TX_FINISH_TRANSFER_OUT. The contents of the log are src_ls_id, dest_ls_id, finish_scn, and + // tablet_id_list. + // a) When the leader and follower of src_ls receive on_redo, change the ObTabletStatus of transfer_tablets to + // TRANFER_OUT_DELETED (the status may share DELETED) + if (FAILEDx( + do_tx_finish_transfer_out_(task_id, tenant_id, src_ls_id, dest_ls_id, finish_scn, tablet_list, conn))) { + LOG_WARN("failed to do tx finish transfer out", + K(ret), + K(task_id), + K(tenant_id), + K(src_ls_id), + K(dest_ls_id), + K(finish_scn)); + } + // 7. Update __all_transfer_task according to the result of transaction execution. + // If successful, push __all_transfer_task to FINISH state, + // otherwise keep the status of __all_transfer_task as DOING + else if (OB_FAIL(update_transfer_task_result_(task_id, tenant_id, finish_scn, OB_SUCCESS, trans))) { + LOG_WARN("failed to update transfer status", K(ret), K(task_id), K(tenant_id), K(finish_scn)); + } + // 8. unlock table lock on src ls for tablet (must be successful) + else if (OB_FAIL(ObTransferLockUtil::unlock_tablet_on_src_ls_for_table_lock( + trans, tenant_id, src_ls_id, lock_owner_id, table_lock_tablet_list))) { + LOG_WARN("failed to unlock tablet on src ls for table lock", KR(ret), + K(tenant_id), K(src_ls_id), K(lock_owner_id), K(table_lock_tablet_list)); + } + // 9. unlock member list + else if (OB_FAIL( + unlock_ls_member_list_(tenant_id, dest_ls_id, member_list, lock_status, CONFIG_CHANGE_TIMEOUT))) { + LOG_WARN("failed to unlock ls member list", K(ret), K(tenant_id), K(dest_ls_id), K(member_list)); + } + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_DOING_COMMIT_TRANS_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_DOING_COMMIT_TRANS_FAILED", K(ret)); + } + } +#endif + DEBUG_SYNC(BEFORE_DOING_TRANSFER_COMMIT); + // 10. LOG_COMMIT_FINISH + bool is_commit = OB_SUCCESS == ret; + if (OB_TMP_FAIL(commit_trans_(is_commit, trans))) { + if (OB_SUCCESS == ret) { + ret = tmp_ret; + } + } + // 11. After the dest_ls leader succeeds, + // it will report the corresponding results to RS. + // This step does not guarantee success. + if (OB_TMP_FAIL(report_result_(task_id, result, svr_rpc_proxy))) { + LOG_WARN("failed to report rpc result", K(ret), K(task_id), KP(rs_mgr), KP(svr_rpc_proxy)); + } + } + } + } + return ret; +} + +int ObTxFinishTransfer::unlock_src_and_dest_ls_member_list_(const uint64_t tenant_id, const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, common::ObMemberList &member_list) +{ + int ret = OB_SUCCESS; + bool is_same = false; + const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; + const int64_t lock_timeout = CONFIG_CHANGE_TIMEOUT; + bool same_member_list = true; + const ObTransferLockStatus status(ObTransferLockStatus::START); + if (!src_ls_id.is_valid() || !dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(src_ls_id), K(dest_ls_id)); + } else if (OB_FAIL(unlock_ls_member_list_(tenant_id, src_ls_id, member_list, status, lock_timeout))) { + LOG_WARN("failed to unlock ls member list", K(ret), K(tenant_id), K(src_ls_id), K(dest_ls_id)); + } else if (OB_FAIL(unlock_ls_member_list_(tenant_id, dest_ls_id, member_list, status, lock_timeout))) { + LOG_WARN("failed to unlock ls member list", K(ret), K(tenant_id), K(src_ls_id), K(dest_ls_id)); + } else { + LOG_INFO( + "[TRANSFER] unlock src and dest ls member list", K(tenant_id), K(src_ls_id), K(dest_ls_id), K(member_list)); + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_DOING_UNLOCK_TRANSFER_MEMBER_LIST_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_DOING_UNLOCK_TRANSFER_MEMBER_LIST_FAILED", K(ret)); + } + } +#endif + + } + UNUSEDx(member_list); + return ret; +} + +int ObTxFinishTransfer::get_transfer_tablet_info_from_inner_table_( + const ObTransferTaskID &task_id, + const uint64_t tenant_id, + common::ObArray &tablet_list, + SCN &start_scn, + ObDisplayTabletList &table_lock_tablet_list, + transaction::tablelock::ObTableLockOwnerID &lock_owner_id) +{ + int ret = OB_SUCCESS; + tablet_list.reset(); + table_lock_tablet_list.reset(); + lock_owner_id.reset(); + const bool for_update = false; + ObTransferTask transfer_task; + if (!task_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(task_id)); + } else if (OB_FAIL(ObTransferTaskOperator::get(*sql_proxy_, tenant_id, task_id, for_update, transfer_task))) { + LOG_WARN("failed to get transfer task", K(ret), K(tenant_id), K(task_id)); + } else if (OB_FAIL(tablet_list.assign(transfer_task.get_tablet_list()))) { + LOG_WARN("failed to assign tablet_list", KR(ret), K(transfer_task)); + } else if (OB_FAIL(table_lock_tablet_list.assign(transfer_task.get_table_lock_tablet_list()))) { + LOG_WARN("failed to assign table_lock_tablet_list", KR(ret), K(transfer_task)); + } else { + start_scn = transfer_task.get_start_scn(); + lock_owner_id = transfer_task.get_table_lock_owner_id(); + LOG_INFO("get transfer info from inner table", K(task_id), K(tenant_id), + K(transfer_task), K(tablet_list), K(table_lock_tablet_list), K(lock_owner_id)); + } + return ret; +} + +int ObTxFinishTransfer::wait_transfer_tablet_status_normal_( + const uint64_t tenant_id, const share::ObLSID &ls_id, + const common::ObArray &tablet_list, + const share::SCN &start_scn, + ObTimeoutCtx &timeout_ctx, + share::SCN &finish_scn) +{ + int ret = OB_SUCCESS; + int64_t begin_us = ObTimeUtility::current_time(); + const int64_t CHECK_TABLET_STATUS_INTERVAL = 100_ms; + if (OB_INVALID_ID == tenant_id || !ls_id.is_valid() || tablet_list.empty() || !start_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer tablet status normal get invalid argument", K(ret), K(tenant_id), K(ls_id), K(tablet_list), K(start_scn)); + } else { + while (OB_SUCC(ret)) { + bool is_ready = false; + if (timeout_ctx.is_timeouted()) { + ret = OB_TIMEOUT; + LOG_WARN("already timeout", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(check_transfer_tablet_status_normal_(tenant_id, ls_id, tablet_list, start_scn, is_ready, finish_scn))) { + LOG_WARN("failed to check transfer tablet status normal", K(ret), K(tenant_id), K(tablet_list)); + } else if (is_ready) { + LOG_INFO("tablet is ready", K(tenant_id), K(ls_id), K(tablet_list)); + break; + } else { + ob_usleep(CHECK_TABLET_STATUS_INTERVAL); + } + } + } + return ret; +} + +int ObTxFinishTransfer::check_transfer_tablet_status_normal_( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const common::ObArray &tablet_list, + const share::SCN &start_scn, + bool &is_ready, + share::SCN &finish_scn) +{ + int ret = OB_SUCCESS; + is_ready = true; + storage::ObLS *ls = NULL; + storage::ObLSHandle ls_handle; + finish_scn.reset(); + + if (OB_FAIL(get_ls_handle_(tenant_id, ls_id, ls_handle))) { + LOG_WARN("failed to get ls handle", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream not exist", K(ret), K(ls_id)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_list.count(); ++i) { + ObTabletHandle tablet_handle; + ObTablet *tablet = NULL; + ObTabletCreateDeleteMdsUserData user_data; + const ObTransferTabletInfo &tablet_info = tablet_list.at(i); + const common::ObTabletID &tablet_id = tablet_info.tablet_id_; + if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, tablet_handle, user_data))) { + LOG_WARN("failed to get tablet status", K(ret), K(tablet_id), K(tablet_handle)); + } else if (ObTabletStatus::NORMAL != user_data.tablet_status_) { + if (ObTabletStatus::TRANSFER_IN != user_data.tablet_status_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet status is not expected", K(ret), K(tablet_info), K(user_data)); + } else { + is_ready = false; + LOG_INFO("tablet is not ready, need retry", K(tablet_info)); + break; + } + } else if (user_data.transfer_scn_ < start_scn) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("finish scn should not smaller than start scn", K(ret), K(tablet_id), K(start_scn), K(user_data)); + } else if (user_data.transfer_scn_ > start_scn) { + if (0 == i) { + finish_scn = user_data.transfer_scn_; + } else if (finish_scn != user_data.transfer_scn_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet finish scn is not same, unexpected", K(ret), K(tablet_id), + K(start_scn), K(finish_scn), K(user_data)); + } + } else { + is_ready = false; + LOG_INFO("tablet is not ready, need retry", K(tablet_info)); + break; + } + } + } + return ret; +} + +int ObTxFinishTransfer::check_ls_logical_table_replaced(const uint64_t tenant_id, + const share::ObLSID &dest_ls_id, const common::ObMemberList &member_list, + const common::ObArray &tablet_list, const int64_t quorum, bool &all_backfilled) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + bool is_leader = false; + const int64_t cluster_id = GCONF.cluster_id; + ObLSLocation ls_location; + ObArray addr_array; + if (OB_FAIL(check_self_ls_leader_(dest_ls_id, is_leader))) { + LOG_WARN("failed to check self ls leader", K(ret), K(dest_ls_id)); + } else if (!is_leader) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("self is not leader", K(ret), K(dest_ls_id)); + } else if (OB_FAIL(member_list.get_addr_array(addr_array))) { + LOG_WARN("failed to get addr array", K(ret), K(member_list)); + } else if (OB_FAIL(inner_check_ls_logical_table_replaced_( + tenant_id, dest_ls_id, addr_array, tablet_list, quorum, all_backfilled))) { + LOG_WARN("failed to inner check majority backfilled", K(ret), K(tenant_id), K(dest_ls_id), K(addr_array)); + } else { + LOG_INFO("check ls logical table replace", K(tenant_id), K(dest_ls_id), K(addr_array), K(tablet_list), K(quorum), K(all_backfilled)); + } + return ret; +} + +int ObTxFinishTransfer::inner_check_ls_logical_table_replaced_(const uint64_t tenant_id, + const share::ObLSID &dest_ls_id, const common::ObArray &member_addr_list, + const common::ObArray &tablet_list, const int64_t quorum, bool &all_backfilled) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + int64_t cur_quorum = 0; + const int64_t cluster_id = GCONF.cluster_id; + FOREACH_X(location, member_addr_list, OB_SUCC(ret)) + { + if (OB_ISNULL(location)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("location should not be null", K(ret)); + } else { + const common::ObAddr &server = *location; + bool backfill_completed = false; + if (OB_FAIL(post_check_logical_table_replaced_request_( + cluster_id, server, tenant_id, dest_ls_id, tablet_list, backfill_completed))) { + LOG_WARN("failed to check criteria", K(ret), K(cluster_id), K(tenant_id), K(dest_ls_id), K(server)); + } else if (!backfill_completed) { + LOG_INFO("server has not finish backfill", K(tenant_id), K(dest_ls_id), K(quorum), K(member_addr_list), K(server)); + } else { + cur_quorum++; + LOG_INFO("server has replayed passed finish scn", K(ret), K(server)); + } + } + } + if (OB_SUCC(ret)) { + all_backfilled = cur_quorum == quorum; + } + return ret; +} + +int ObTxFinishTransfer::do_tx_finish_transfer_in_(const ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id, const SCN &start_scn, + const common::ObArray &tablet_list, observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + bool force_flush_redo = true; + bool is_leader = false; + char *buf = NULL; + int64_t buf_len = 0; + const transaction::ObTxDataSourceType type = transaction::ObTxDataSourceType::FINISH_TRANSFER_IN; + ObTXFinishTransferInInfo finish_transfer_in_info; + ObArenaAllocator allocator; + ObRegisterMdsFlag flag; + flag.need_flush_redo_instantly_ = true; + if (OB_ISNULL(conn)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("conn should not be null", K(ret)); + } else if (OB_FAIL(build_tx_finish_transfer_in_info_( + src_ls_id, dest_ls_id, start_scn, tablet_list, finish_transfer_in_info))) { + LOG_WARN("failed to build tx finish transfer in info", + K(ret), + K(src_ls_id), + K(dest_ls_id), + K(start_scn), + K(tablet_list)); + } else if (OB_FAIL(construct_multi_data_source_buf_(finish_transfer_in_info, allocator, buf, buf_len))) { + LOG_WARN("failed to construct multi data source buf", K(ret), K(finish_transfer_in_info)); + } else if (OB_FAIL(conn->register_multi_data_source(tenant_id, dest_ls_id, type, buf, buf_len, flag))) { + LOG_WARN("failed to register multi data source", K(ret), K(tenant_id), K(dest_ls_id), K(type)); + } else { +#ifdef ERRSIM + ObTransferEventRecorder::record_transfer_task_event(task_id, "TX_FINISH_TRANSFER_IN", src_ls_id, dest_ls_id); +#endif + LOG_INFO("register multi data source for finish transfer in", K(task_id), K(src_ls_id), K(dest_ls_id)); + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_FINISH_TRANSFER_IN_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_FINISH_TRANSFER_IN_FAILED", K(ret)); + } + } +#endif + } + return ret; +} + +int ObTxFinishTransfer::do_tx_finish_transfer_out_(const ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id, const share::SCN &finish_scn, + const common::ObArray &tablet_list, observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + bool force_flush_redo = true; + bool is_leader = false; + char *buf = NULL; + int64_t buf_len = 0; + const transaction::ObTxDataSourceType type = transaction::ObTxDataSourceType::FINISH_TRANSFER_OUT; + ObTXFinishTransferOutInfo finish_transfer_out_info; + ObArenaAllocator allocator; + ObRegisterMdsFlag flag; + flag.need_flush_redo_instantly_ = false; + flag.mds_base_scn_ = finish_scn; + + if (OB_ISNULL(conn)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("conn should not be null", K(ret)); + } else if (OB_FAIL(build_tx_finish_transfer_out_info_( + src_ls_id, dest_ls_id, finish_scn, tablet_list, finish_transfer_out_info))) { + LOG_WARN("failed to build tx finish transfer out info", + K(ret), + K(src_ls_id), + K(dest_ls_id), + K(finish_scn), + K(tablet_list)); + } else if (OB_FAIL(construct_multi_data_source_buf_(finish_transfer_out_info, allocator, buf, buf_len))) { + LOG_WARN("failed to construct multi data source buf", K(ret), K(finish_transfer_out_info)); + } else if (OB_FAIL(conn->register_multi_data_source(tenant_id, src_ls_id, type, buf, buf_len, flag))) { + LOG_WARN("failed to register multi data source", K(ret), K(tenant_id)); + } else { +#ifdef ERRSIM + ObTransferEventRecorder::record_transfer_task_event(task_id, "TX_FINISH_TRANSFER_OUT", src_ls_id, dest_ls_id); +#endif + LOG_INFO("[TRANSFER] register multi data source for finish transfer out", K(task_id), K(src_ls_id), K(dest_ls_id)); + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_FINISH_TRANSFER_OUT_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_FINISH_TRANSFER_OUT_FAILED", K(ret)); + } + } +#endif + + DEBUG_SYNC(AFTER_FINISH_TRANSFER_OUT); + } + return ret; +} + +int ObTxFinishTransfer::wait_all_ls_replica_replay_scn_(const ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &ls_id, const common::ObArray &member_addr_list, const share::SCN &finish_scn, + const int64_t quorum, ObTimeoutCtx &timeout_ctx, bool &check_passed) +{ + int ret = OB_SUCCESS; + while (OB_SUCC(ret)) { + check_passed = false; + if (timeout_ctx.is_timeouted()) { + ret = OB_TIMEOUT; + LOG_WARN("some ls replay not finished", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(check_all_ls_replica_replay_scn_( + task_id, tenant_id, ls_id, member_addr_list, finish_scn, quorum, check_passed))) { + LOG_WARN("failed to check all ls replica replay scn", + K(ret), + K(tenant_id), + K(member_addr_list), + K(ls_id), + K(quorum)); + } else if (check_passed) { + LOG_INFO("all ls has passed ls replica replay scn", K(tenant_id), K(ls_id)); + break; + } else { + ob_usleep(DEFAULT_WAIT_INTERVAL_US); + } + } + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_DOING_WAIT_ALL_DEST_TABLET_NORAML ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_DOING_WAIT_ALL_DEST_TABLET_NORAML", K(ret)); + } + } +#endif + + DEBUG_SYNC(AFTER_DOING_TRANSFER_WAIT_REPLAY_SCN); + + return ret; +} + +int ObTxFinishTransfer::check_all_ls_replica_replay_scn_(const ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &ls_id, const common::ObArray &member_addr_list, const share::SCN &finish_scn, + const int64_t quorum, bool &meet_criteria) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + int64_t cur_quorum = 0; + FOREACH_X(location, member_addr_list, OB_SUCC(ret)) + { + if (OB_ISNULL(location)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("location should not be null", K(ret)); + } else { + const common::ObAddr &server = *location; + bool passed_finish_scn = false; + if (OB_FAIL(inner_check_ls_replay_scn_(task_id, tenant_id, ls_id, server, finish_scn, passed_finish_scn))) { + LOG_WARN("failed to check criteria", K(ret), K(task_id), K(tenant_id), K(ls_id), K(server)); + } else if (!passed_finish_scn) { + LOG_INFO("server has not passed finish scn", K(task_id), K(tenant_id), K(server), K(finish_scn)); + } else { + cur_quorum++; + LOG_INFO("server has replayed passed finish scn", K(ret), K(server)); + } + } + } + if (OB_SUCC(ret)) { + meet_criteria = cur_quorum == quorum ; + } + return ret; +} + +int ObTxFinishTransfer::inner_check_ls_replay_scn_(const ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &ls_id, const common::ObAddr &addr, const SCN &finish_scn, bool &passed_scn) +{ + int ret = OB_SUCCESS; + passed_scn = false; + const int64_t cluster_id = GCONF.cluster_id; + SCN tmp_finish_scn; + if (OB_FAIL(fetch_ls_replay_scn_(task_id, cluster_id, addr, tenant_id, ls_id, tmp_finish_scn))) { + LOG_WARN("failed to fetch finish scn for transfer", K(ret), K(task_id), K(tenant_id), K(ls_id)); + } else { + passed_scn = tmp_finish_scn >= finish_scn; + LOG_INFO("check ls replay scn", K(passed_scn), K(tmp_finish_scn), K(finish_scn)); + } + return ret; +} + +int ObTxFinishTransfer::get_ls_handle_( + const uint64_t tenant_id, const share::ObLSID &ls_id, storage::ObLSHandle &ls_handle) +{ + int ret = OB_SUCCESS; + ls_handle.reset(); + ObLSService *ls_service = NULL; + if (OB_INVALID_ID == tenant_id || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_ISNULL(ls_service = MTL_WITH_CHECK_TENANT(ObLSService *, tenant_id))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream service is NULL", K(ret), K(tenant_id)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get log stream", K(ret), K(tenant_id), K(ls_id)); + } + return ret; +} + +int ObTxFinishTransfer::get_ls_member_list_( + const uint64_t tenant_id, const share::ObLSID &ls_id, common::ObMemberList &member_list) +{ + int ret = OB_SUCCESS; + storage::ObLS *ls = NULL; + storage::ObLSHandle ls_handle; + int64_t quorum = 0; + bool is_leader = false; + if (OB_FAIL(get_ls_handle_(tenant_id, ls_id, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream not exist", K(ret), K(ls_id)); + } else if (OB_FAIL(check_self_ls_leader_(ls_id, is_leader))) { + LOG_WARN("failed to check self ls leader", K(ret), K(ls_id)); + } else if (!is_leader) { + ret = OB_IS_CHANGING_LEADER; + LOG_WARN("self is not leader", K(ret), K(ls_id)); + } else if (OB_FAIL(ls->get_paxos_member_list(member_list, quorum))) { + LOG_WARN("failed to get paxos member list", K(ret)); + } else if (OB_FAIL(check_self_ls_leader_(ls_id, is_leader))) { + LOG_WARN("failed to check self ls leader", K(ret), K(ls_id)); + } else if (!is_leader) { + ret = OB_IS_CHANGING_LEADER; + LOG_WARN("self is not leader", K(ret), K(ls_id)); + } else { + LOG_INFO("get ls member list", K(tenant_id), K(ls_id), K(member_list)); + } + return ret; +} + +// TODO(yangyi.yyy): impl later +// extract common function later +int ObTxFinishTransfer::check_same_member_list_( + const uint64_t tenant_id, const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id, bool &same_member_list) +{ + int ret = OB_SUCCESS; + UNUSEDx(tenant_id, src_ls_id, dest_ls_id, same_member_list); + return ret; +} + +int ObTxFinishTransfer::unlock_ls_member_list_(const uint64_t tenant_id, const share::ObLSID &ls_id, + const common::ObMemberList &member_list, const ObTransferLockStatus &status, const int64_t lock_timeout) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObMemberListLockUtils::unlock_ls_member_list( + tenant_id, ls_id, task_id_.id(), member_list, status, *sql_proxy_))) { + LOG_WARN("failed to unlock ls member list", K(ret), K(tenant_id), K(ls_id), K_(task_id), K(status)); + } + return ret; +} + +int ObTxFinishTransfer::lock_ls_member_list_(const uint64_t tenant_id, const share::ObLSID &ls_id, + const common::ObMemberList &member_list, const ObTransferLockStatus &status) +{ + int ret = OB_SUCCESS; + storage::ObLS *ls = NULL; + storage::ObLSHandle ls_handle; + if (OB_FAIL(get_ls_handle_(tenant_id, ls_id, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream not exist", K(ret), K(ls_id)); + } else if (OB_FAIL(ObMemberListLockUtils::lock_ls_member_list( + tenant_id, ls_id, task_id_.id(), member_list, status, ls, *sql_proxy_))) { + LOG_WARN("failed to unlock ls member list", K(ret), K(ls_id), K(member_list), KPC(ls)); + } else { +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_DOING_LOCK_MEMBER_LIST_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_DOING_LOCK_MEMBER_LIST_FAILED", K(ret)); + } + } +#endif + + DEBUG_SYNC(AFTER_DOING_TRANSFER_LOCK_MEMBER_LIST); + } + return ret; +} + +int ObTxFinishTransfer::build_tx_finish_transfer_in_info_(const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, const share::SCN &start_scn, + const common::ObArray &tablet_list, ObTXFinishTransferInInfo &transfer_in_info) +{ + int ret = OB_SUCCESS; + transfer_in_info.reset(); + if (!src_ls_id.is_valid() || !dest_ls_id.is_valid() || !start_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(src_ls_id), K(dest_ls_id)); + } else { + transfer_in_info.src_ls_id_ = src_ls_id; + transfer_in_info.dest_ls_id_ = dest_ls_id; + transfer_in_info.start_scn_ = start_scn; + if (OB_FAIL(transfer_in_info.tablet_list_.assign(tablet_list))) { + LOG_WARN("failed to assign tablet list", K(ret), K(tablet_list)); + } + } + return ret; +} + +int ObTxFinishTransfer::build_tx_finish_transfer_out_info_(const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, const share::SCN &finish_scn, + const common::ObArray &tablet_list, ObTXFinishTransferOutInfo &transfer_out_info) +{ + int ret = OB_SUCCESS; + transfer_out_info.reset(); + if (!src_ls_id.is_valid() || !dest_ls_id.is_valid() || !finish_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(src_ls_id), K(dest_ls_id)); + } else { + transfer_out_info.src_ls_id_ = src_ls_id; + transfer_out_info.dest_ls_id_ = dest_ls_id; + transfer_out_info.finish_scn_ = finish_scn; + if (OB_FAIL(transfer_out_info.tablet_list_.assign(tablet_list))) { + LOG_WARN("failed to assign tablet list", K(ret), K(tablet_list)); + } + } + return ret; +} + +template +int ObTxFinishTransfer::construct_multi_data_source_buf_( + const TransferInfo &transfer_info, common::ObIAllocator &allocator, char *&buf, int64_t &buf_len) +{ + int ret = OB_SUCCESS; + buf = NULL; + int64_t pos = 0; + buf_len = transfer_info.get_serialize_size(); + if (!transfer_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(transfer_info)); + } else if (OB_ISNULL(buf = static_cast(allocator.alloc(buf_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret), K(buf_len)); + } else if (OB_FAIL(transfer_info.serialize(buf, buf_len, pos))) { + LOG_WARN("failed to serialize", K(ret), K(transfer_info)); + } + return ret; +} + +int ObTxFinishTransfer::update_transfer_task_result_(const ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::SCN &finish_scn, const int64_t result, ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (!task_id.is_valid() || OB_INVALID_ID == tenant_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(task_id), K(tenant_id)); + } else { + ObTransferTask transfer_task; + const bool for_update = true; + ObTransferStatus next_status; + next_status = OB_SUCCESS == result ? ObTransferStatus::COMPLETED : ObTransferStatus::DOING; + if (OB_FAIL(ObTransferTaskOperator::get(trans, tenant_id, task_id, for_update, transfer_task))) { + LOG_WARN("failed to get transfer task", K(ret), K(task_id), K(tenant_id)); + } else if (transfer_task.get_start_scn() >= finish_scn) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("finish scn not expected", K(ret), K(transfer_task), K(finish_scn)); + } else if (OB_FAIL(ObTransferTaskOperator::update_finish_scn( + trans, tenant_id, task_id, transfer_task.get_status(), finish_scn))) { + LOG_WARN("failed to update finish scn", K(ret), K(tenant_id), K(task_id), K(finish_scn)); + } else if (OB_FAIL(ObTransferTaskOperator::finish_task( + trans, tenant_id, task_id, transfer_task.get_status(), next_status, result, ObTransferTaskComment::EMPTY_COMMENT))) { + LOG_WARN("failed to finish task", K(ret), K(tenant_id), K(task_id)); + } +#ifdef ERRSIM + ObTransferEventRecorder::record_advance_transfer_status_event( + tenant_id, task_id, src_ls_id_, dest_ls_id_, next_status, result); +#endif + LOG_INFO("update transfer task result", K(ret), K(task_id), K(tenant_id), K(result), K(finish_scn)); + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_DOING_UPDATE_TRANSFER_TASK_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_DOING_UPDATE_TRANSFER_TASK_FAILED", K(ret)); + } + } +#endif + } + return ret; +} + +int ObTxFinishTransfer::report_result_( + const ObTransferTaskID &task_id, const int64_t result, obrpc::ObSrvRpcProxy *rpc_proxy) +{ + int ret = OB_SUCCESS; + ObAddr leader_addr; + int64_t retry_count = 0; + const int64_t MAX_RETRY_TIMES = 3; + const int64_t REPORT_RETRY_INTERVAL_MS = 100 * 1000; // 100ms + ObFinishTransferTaskArg finish_task_arg; + const uint64_t tenant_id = MTL_ID(); + const share::ObLSID &sys_ls_id = share::SYS_LS; + + if (OB_FAIL(finish_task_arg.init(tenant_id, task_id))) { + LOG_WARN("failed to init finish task arg", K(ret), K(tenant_id), K(task_id)); + } else { + while (retry_count++ < MAX_RETRY_TIMES) { + if (OB_FAIL(ObStorageHAUtils::get_ls_leader(tenant_id, sys_ls_id, leader_addr))) { + LOG_WARN("failed to get ls leader", K(ret), K(tenant_id)); + } else if (OB_FAIL(rpc_proxy->to(leader_addr).by(tenant_id).finish_transfer_task(finish_task_arg))) { + LOG_WARN("failed to report finish transfer task", K(ret), K(leader_addr), K(tenant_id), K(finish_task_arg)); + } + if (OB_SUCC(ret)) { + break; + } else { + ob_usleep(REPORT_RETRY_INTERVAL_MS); + } + } + } + return ret; +} + +int ObTxFinishTransfer::fetch_ls_replay_scn_(const ObTransferTaskID &task_id, const int64_t cluster_id, + const common::ObAddr &server_addr, const uint64_t tenant_id, const share::ObLSID &ls_id, share::SCN &finish_scn) +{ + int ret = OB_SUCCESS; + ObLSService *ls_service = NULL; + storage::ObStorageRpc *storage_rpc = NULL; + storage::ObStorageHASrcInfo src_info; + src_info.src_addr_ = server_addr; + src_info.cluster_id_ = GCONF.cluster_id; + if (!src_info.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(src_info), K(ls_id)); + } else if (OB_ISNULL(ls_service = MTL_WITH_CHECK_TENANT(ObLSService *, tenant_id))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream service is NULL", K(ret)); + } else if (OB_ISNULL(storage_rpc = ls_service->get_storage_rpc())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage rpc proxy is NULL", K(ret)); + } else if (OB_FAIL(storage_rpc->fetch_ls_replay_scn(tenant_id, src_info, ls_id, finish_scn))) { + LOG_WARN("failed to fetch ls replay scn", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } else { + LOG_INFO("fetch ls replay scn", K(tenant_id), K(src_info), K(ls_id)); + } + return ret; +} + +int ObTxFinishTransfer::post_check_logical_table_replaced_request_(const int64_t cluster_id, + const common::ObAddr &server_addr, const uint64_t tenant_id, const share::ObLSID &dest_ls_id, + const common::ObIArray &tablet_list, bool &replace_finished) +{ + int ret = OB_SUCCESS; + replace_finished = false; + ObLSService *ls_service = NULL; + storage::ObStorageRpc *storage_rpc = NULL; + storage::ObStorageHASrcInfo src_info; + src_info.src_addr_ = server_addr; + src_info.cluster_id_ = GCONF.cluster_id; + if (!src_info.is_valid() || !dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(src_info), K(dest_ls_id)); + } else if (OB_ISNULL(ls_service = MTL_WITH_CHECK_TENANT(ObLSService *, tenant_id))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream service is NULL", K(ret)); + } else if (OB_ISNULL(storage_rpc = ls_service->get_storage_rpc())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage rpc proxy is NULL", K(ret)); + } else if (OB_FAIL(storage_rpc->check_tablets_logical_table_replaced( + tenant_id, src_info, dest_ls_id, tablet_list, replace_finished))) { + LOG_WARN( + "failed to post transfer backfill finished", K(ret), K(tenant_id), K(src_info), K(dest_ls_id), K(tablet_list)); + } else { + LOG_INFO("check logical table replaced completed", K(tenant_id), K(src_info), K(dest_ls_id), K(replace_finished)); + } + return ret; +} + +int ObTxFinishTransfer::check_self_ls_leader_(const share::ObLSID &ls_id, bool &is_leader) +{ + int ret = OB_SUCCESS; + logservice::ObLogService *log_service = nullptr; + ObRole role = ObRole::INVALID_ROLE; + int64_t proposal_id = 0; + is_leader = false; + if (OB_ISNULL(log_service = MTL(logservice::ObLogService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log service should not be NULL", K(ret), KP(log_service)); + } else if (OB_FAIL(log_service->get_palf_role(ls_id, role, proposal_id))) { + LOG_WARN("failed to get role", K(ret), K(ls_id)); + } else if (is_strong_leader(role)) { + is_leader = true; + } else { + is_leader = false; + } + return ret; +} + +int ObTxFinishTransfer::start_trans_( + const uint64_t tenant_id, + ObMySQLTransaction &trans, + ObTimeoutCtx &timeout_ctx) +{ + int ret = OB_SUCCESS; + const int64_t MAX_EXECUTE_TIMEOUT_US = GCONF._transfer_finish_trans_timeout; //default 10s + int64_t stmt_timeout = MAX_EXECUTE_TIMEOUT_US; + + if (OB_FAIL(timeout_ctx.set_trx_timeout_us(stmt_timeout))) { + LOG_WARN("fail to set trx timeout", K(ret), K(stmt_timeout)); + } else if (OB_FAIL(timeout_ctx.set_timeout(stmt_timeout))) { + LOG_WARN("set timeout context failed", K(ret)); + } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id))) { + LOG_WARN("failed to start trans", K(ret), K(tenant_id)); + } else { + LOG_INFO("start trans", K(tenant_id)); + } + return ret; +} + +int ObTxFinishTransfer::commit_trans_(const bool is_commit, ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(trans.end(is_commit))) { + LOG_WARN("end transaction failed", K(ret)); + } else { + LOG_INFO("commit trans", K(is_commit)); + } + return ret; +} + +int ObTxFinishTransfer::get_transfer_quorum_(const ObMemberList &member_list, int64_t &quorum) +{ + int ret = OB_SUCCESS; + if (!member_list.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(member_list)); + } else { + quorum = member_list.get_member_number(); + LOG_INFO("get transfer quorum", K(member_list), K(quorum)); + } + return ret; +} + +int ObTxFinishTransfer::select_transfer_task_for_update_(const ObTransferTaskID &task_id, ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + const bool for_update = true; + ObTransferTask task; + if (!task_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid arg", K(ret), K(task_id)); + } else if (OB_FAIL(ObTransferTaskOperator::get(trans, tenant_id, task_id, for_update, task))) { + LOG_WARN("failed to get transfer task", K(ret), K(tenant_id), K(task_id)); + } else if (!task.get_status().is_doing_status()) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("transfer task status is not doing", K(ret), K(task)); + } else { + LOG_INFO("select for update", K(task_id), K(task)); +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_DOING_LOCK_TRANSFER_TASK_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_DOING_LOCK_TRANSFER_TASK_FAILED", K(ret)); + } + } +#endif + + } + return ret; +} + +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/high_availability/ob_finish_transfer.h b/src/storage/high_availability/ob_finish_transfer.h new file mode 100644 index 000000000..d7fe12299 --- /dev/null +++ b/src/storage/high_availability/ob_finish_transfer.h @@ -0,0 +1,298 @@ +/** + * 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 OCEABASE_STORAGE_FINISH_TRANSFER_H_ +#define OCEABASE_STORAGE_FINISH_TRANSFER_H_ + +#include "storage/ls/ob_ls.h" +#include "common/ob_member_list.h" +#include "logservice/ob_log_handler.h" +#include "observer/ob_inner_sql_connection.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "lib/net/ob_addr.h" +#include "lib/lock/ob_mutex.h" +#include "lib/lock/ob_thread_cond.h" +#include "share/transfer/ob_transfer_info.h" +#include "share/ob_balance_define.h" + +namespace oceanbase { +namespace storage { + +struct ObLockOwner {}; + +class ObTxFinishTransfer { +public: + ObTxFinishTransfer(); + virtual ~ObTxFinishTransfer(); + int init(const share::ObTransferTaskID &task_id, const uint64_t tenant_id, const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, common::ObMySQLProxy &sql_proxy); + int process(); + +private: + int do_tx_transfer_doing_(const share::ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id); + + // unlock both src and dest ls member list + // @param[in]: tenant_id + // @param[in]: src_ls_id + // @param[in]: dest_ls_id + // @param[out]: member list + int unlock_src_and_dest_ls_member_list_(const uint64_t tenant_id, const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, common::ObMemberList &member_list); + + // get transfer tablet list from inner table + // @param[in]: task_id + // @param[in]: tenant_id + // @param[out]: tablet info list + // @param[out]: start scn + // @param[out]: table lock tablet list + // @param[out]: lock owner id + int get_transfer_tablet_info_from_inner_table_( + const ObTransferTaskID &task_id, + const uint64_t tenant_id, + common::ObArray &tablet_list, + SCN &start_scn, + ObDisplayTabletList &table_lock_tablet_list, + transaction::tablelock::ObTableLockOwnerID &lock_owner_id); + + int wait_transfer_tablet_status_normal_(const uint64_t tenant_id, const share::ObLSID &ls_id, + const common::ObArray &tablet_list, const share::SCN &start_scn, + ObTimeoutCtx &timeout_ctx, share::SCN &finish_scn); + + int check_transfer_tablet_status_normal_(const uint64_t tenant_id, const share::ObLSID &ls_id, + const common::ObArray &tablet_list, const share::SCN &start_scn, + bool &is_ready, share::SCN &finish_scn); + + // check ls backfilled + // @param[in]: tenant_id + // @param[in]: ls_id + // @param[in]: member_list + // @param[in]: tablet_list + // @param[in]: quorum + // @param[in]: majority_backfilled + int check_ls_logical_table_replaced(const uint64_t tenant_id, const share::ObLSID &dest_ls_id, + const common::ObMemberList &member_list, const common::ObArray &tablet_list, + const int64_t quorum, bool &all_backfilled); + + // inner check ls logical table replaced + // @param[in]: tenant_id + // @param[in]: dest_ls_id + // @param[in]: member_addr_list + // @param[in]: tablet_list + // @param[in]: quorum + int inner_check_ls_logical_table_replaced_(const uint64_t tenant_id, const share::ObLSID &dest_ls_id, + const common::ObArray &member_addr_list, + const common::ObArray &tablet_list, const int64_t quorum, bool &all_backfilled); + + // wait until all ls replay scn satisfy + // @param[in]: tenant_id + // @param[in]: ls_id + // @param[in]: member_list + // @param[in]: tablet_list + // @param[in]: quorum + // @param[in]: timeout_ctx + int wait_all_ls_replica_replay_scn_(const share::ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &ls_id, const common::ObArray &member_addr_list, const share::SCN &finish_scn, + const int64_t quorum, ObTimeoutCtx &timeout_ctx, bool &check_passed); + + // check ls replica match scn + // @param[in]: task_id + // @param[in]: tenant_id + // @param[in]: ls_id + // @param[in]: server addr + // @param[in]: dest_ls_scn + // @param[in]: current scn + // @param[bool]: check passed + int check_all_ls_replica_replay_scn_(const share::ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &ls_id, const common::ObArray &member_addr_list, const share::SCN &finish_scn, + const int64_t quorum, bool &check_passed); + + // param[in]: tenant_id, + // param[in]: ls_id + // param[in]: server addr + // param[in]: finish_scn + // param[out]: is the check passed + int inner_check_ls_replay_scn_(const share::ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &ls_id, const common::ObAddr &addr, const share::SCN &finish_scn, bool &passed_scn); + +private: + /* helper functions */ + + // get ls member list + // @param[in]: tenant_id + // @param[in]: ls_id + // @param[out]: ls handle + int get_ls_handle_(const uint64_t tenant_id, const share::ObLSID &ls_id, storage::ObLSHandle &ls_handle); + + // get ls member list + // @param[in]: tenant_id + // @param[in]: ls_id + // @param[in]: member_list + int get_ls_member_list_(const uint64_t tenant_id, const share::ObLSID &ls_id, common::ObMemberList &member_list); + + // check src ls and dest ls has same member list + // @param[in]: tenant_id + // @param[in]: src_ls_id + // @param[in]: dest_ls_id + // @param[out]: same member list + int check_same_member_list_(const uint64_t tenant_id, const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id, + bool &same_member_list); + + // unlock ls member list + // @param[in]: tenant_id + // @param[in]: ls_id + // @param[in]: member_list + // @param[in]: lock timeout + // @param[in]: lock_owner + int unlock_ls_member_list_(const uint64_t tenant_id, const share::ObLSID &ls_id, + const common::ObMemberList &member_list, const ObTransferLockStatus &status, const int64_t lock_timeout); + + // lock ls member list + // @param[in]: tenant_id + // @param[in]: ls_id + // @param[in]: member_list + int lock_ls_member_list_(const uint64_t tenant_id, const share::ObLSID &ls_id, + const common::ObMemberList &member_list, const ObTransferLockStatus &status); + + // @param[in]: src_ls_id + // @param[in]: dest_ls_id + // @param[in]: start_scn + // @param[in]: tablet_list + // @param[out]: transfer_out_info + int build_tx_finish_transfer_in_info_(const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id, + const share::SCN &start_scn, const common::ObArray &tablet_list, + ObTXFinishTransferInInfo &transfer_out_info); + + // build tx finish transfer out info + // @param[in]: src_ls_id + // @param[in]: dest_ls_id + // @param[in]: finish_scn + // @param[in]: tablet_list + // @param[out]: transfer_out_info + int build_tx_finish_transfer_out_info_(const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id, + const share::SCN &finish_scn, const common::ObArray &tablet_list, + ObTXFinishTransferOutInfo &transfer_out_info); + + // construct multi data source buf + // @param[in]: finish transfer info + // @param[in]: allocator + // @param[out]: buf + // @param[out]: buf_len + template + int construct_multi_data_source_buf_( + const TransferInfo &transfer_info, common::ObIAllocator &allocator, char *&buf, int64_t &buf_len); + + // update transfer task result + // @param[in]: task_id + // @param[in]: tenant_id + // @param[in]: finish_scn + // @param[in]: result + // @param[in]: transaction + int update_transfer_task_result_(const share::ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::SCN &finish_scn, const int64_t result, ObMySQLTransaction &trans); + + // report result through rpc + // @param[in]: task_id + // @param[in]: result + // @param[in]: rs rpc proxy + int report_result_(const share::ObTransferTaskID &task_id, const int64_t result, obrpc::ObSrvRpcProxy *rs_rpc_proxy); + +private: + /*rpc section*/ + int fetch_ls_replay_scn_(const share::ObTransferTaskID &task_id, const int64_t cluster_id, + const common::ObAddr &server_addr, const uint64_t tenant_id, const share::ObLSID &ls_id, share::SCN &finish_scn); + + // post check if logical sstable has been replaced + // @param[in]: cluster_id + // @param[in]: server_addr + // @param[in]: tenant_id + // @param[in]: ls_id + // @param[out] backfill completed + int post_check_logical_table_replaced_request_(const int64_t cluster_id, const common::ObAddr &server_addr, + const uint64_t tenant_id, const share::ObLSID &dest_ls_id, + const common::ObIArray &tablet_list, bool &backfill_completed); + + // check self is leader + // @param[in]: ls_id + // @param[out]: is_leader + int check_self_ls_leader_(const share::ObLSID &ls_id, bool &ls_leader); + + // The leader node of dest_ls registers the multi-source transaction + // ObInnerSQLConnection->register_multi_source_data, + // and the type is TX_FINISH_TRANSFER_IN (two-way barrier). + // The content of the log is src_ls_id, dest_ls_id, tablet_list. + // This step requires forcibly flushing the redo log. + // The purpose of brushing redo here is to obtain finish_scn and + // check whether the dest_ls log playback is new enough for src_ls. + + // TX_FINISH_TRANSFER_IN + // @param[in]: task_id, the task id of transfer task + // @param[in]: tenant id + // @param[in]: src ls id + // @param[in]: dest ls id + // @param[in]: start_scn + // @param[in]: transfer tablet list + // @param[in]: observer connection + int do_tx_finish_transfer_in_(const share::ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id, const share::SCN &start_scn, + const common::ObArray &tablet_list, observer::ObInnerSQLConnection *conn); + + // The leader of dest_ls registers a multi-source transaction, + // and the type is TX_FINISH_TRANSFER_OUT + // The contents of the log are src_ls_id, dest_ls_id, and finish_scn. + + // TX_FINISH_TRANSFER_OUT + // @param[in]: task_id + // @param[in]: tenant_id + // @param[in]: src_ls_id + // @param[in]: dest_ls_id + // @param[in]: finish_scn + // @param[in]: observer connection + int do_tx_finish_transfer_out_(const share::ObTransferTaskID &task_id, const uint64_t tenant_id, + const share::ObLSID &src_ls_id, const share::ObLSID &dest_ls_id, const share::SCN &finish_scn, + const common::ObArray &tablet_list, observer::ObInnerSQLConnection *conn); + + // start a transaction + // @param[in]: tenant + // @param[in]: mysql transaction + // @param[in]: timeout ctx + int start_trans_(const uint64_t tenant_id, ObMySQLTransaction &trans, ObTimeoutCtx &timeout_ctx); + + // commit a transaction + int commit_trans_(const bool is_commit, ObMySQLTransaction &trans); + + int get_transfer_quorum_(const ObMemberList &member_list, int64_t &quorum); + + // lock transfer task while doing + // @param[in]: task_id + // @param[in]: trans + int select_transfer_task_for_update_(const share::ObTransferTaskID &task_id, ObMySQLTransaction &trans); + +private: + static const int64_t DEFAULT_WAIT_INTERVAL_US = 10 * 1000; // 10ms + +private: + bool is_inited_; + share::ObTransferTaskID task_id_; + uint64_t tenant_id_; + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + mutable lib::ObMutex mutex_; + common::ObThreadCond cond_; + common::ObMySQLProxy *sql_proxy_; + DISALLOW_COPY_AND_ASSIGN(ObTxFinishTransfer); +}; + +} // namespace storage +} // namespace oceanbase + +#endif diff --git a/src/storage/high_availability/ob_ls_block_tx_service.cpp b/src/storage/high_availability/ob_ls_block_tx_service.cpp new file mode 100644 index 000000000..f48d46e92 --- /dev/null +++ b/src/storage/high_availability/ob_ls_block_tx_service.cpp @@ -0,0 +1,242 @@ +/** + * Copyright (c) 2021 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 "share/scn.h" +#include "storage/ls/ob_ls.h" +#include "logservice/ob_log_service.h" +#include "storage/high_availability/ob_ls_block_tx_service.h" +#include "observer/ob_server_event_history_table_operator.h" + +namespace oceanbase +{ +namespace storage +{ + +ObLSBlockTxService::ObLSBlockTxService() + : is_inited_(false), + mutex_(), + cur_seq_(SCN::min_scn()), + ls_(NULL) +{ +} + +ObLSBlockTxService::~ObLSBlockTxService() +{ +} + +int ObLSBlockTxService::init(storage::ObLS *ls) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + STORAGE_LOG(WARN, "block tx service is inited", K(ret), KP(ls)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), KP(ls)); + } else { + ls_ = ls; + cur_seq_.set_min(); + is_inited_ = true; + STORAGE_LOG(INFO, "success to init block tx service", K(ret), KP(ls), "ls_id", ls_->get_ls_id(), KP(this)); + } + return ret; +} + +void ObLSBlockTxService::destroy() +{ + is_inited_ = false; + cur_seq_.reset(); + ls_ = NULL; +} + +void ObLSBlockTxService::switch_to_follower_forcedly() +{ + ObMutexGuard mutex_guard(mutex_); + ls_->get_tx_svr()->unblock_normal(); + STORAGE_LOG(INFO, "[BLOCK_TX]switch to follower finish"); +} + +// TODO(yangyi.yyy): switch to leader should fetch new gts +int ObLSBlockTxService::switch_to_leader() +{ + ObMutexGuard mutex_guard(mutex_); + ls_->get_tx_svr()->unblock_normal(); + cur_seq_.set_min(); + STORAGE_LOG(INFO, "[BLOCK_TX]switch to leader finish"); + return OB_SUCCESS; +} + +int ObLSBlockTxService::switch_to_follower_gracefully() +{ + ObMutexGuard mutex_guard(mutex_); + ls_->get_tx_svr()->unblock_normal(); + STORAGE_LOG(INFO, "[BLOCK_TX]switch to follower gracefully"); + return OB_SUCCESS; +} + +int ObLSBlockTxService::resume_leader() +{ + ObMutexGuard mutex_guard(mutex_); + STORAGE_LOG(INFO, "[BLOCK_TX]resume leader finish"); + return OB_SUCCESS; +} + +int ObLSBlockTxService::replay( + const void *buffer, + const int64_t nbytes, + const palf::LSN &lsn, + const share::SCN &scn) +{ + UNUSEDx(buffer, nbytes, lsn, scn); + return OB_SUCCESS; +} + +int ObLSBlockTxService::flush(share::SCN &scn) +{ + UNUSED(scn); + return OB_SUCCESS; +} + +int ObLSBlockTxService::ha_block_tx(const share::SCN &new_seq) +{ + int ret = OB_SUCCESS; + ObMutexGuard mutex_guard(mutex_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ls is not inited", K(ret)); + } else if (OB_FAIL(check_is_leader_())) { + STORAGE_LOG(WARN, "failed to check is leader", K(ret)); + } else if (OB_FAIL(check_seq_(new_seq))) { + STORAGE_LOG(WARN, "failed to check seq", K(ret)); + } else if (OB_FAIL(ls_->get_tx_svr()->block_normal())) { + STORAGE_LOG(WARN, "failed to block tx", K(ret)); + } else { + SERVER_EVENT_ADD("transfer", "ha_block_tx", + "tenant_id", MTL_ID(), + "ls_id", ls_->get_ls_id(), + "cur_seq", new_seq, + "prev_seq", cur_seq_); + update_seq_(new_seq); + STORAGE_LOG(INFO, "success to block tx", K(ret), KPC_(ls), K(new_seq)); + } + return ret; +} + +int ObLSBlockTxService::ha_kill_tx(const share::SCN &new_seq) +{ + int ret = OB_SUCCESS; + ObMutexGuard mutex_guard(mutex_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ls is not inited", K(ret)); + } else if (OB_FAIL(check_is_leader_())) { + STORAGE_LOG(WARN, "failed to check is leader", K(ret)); + } else if (OB_FAIL(check_seq_(new_seq))) { + STORAGE_LOG(WARN, "failed to check seq", K(ret)); + } else if (OB_FAIL(ls_->kill_all_tx(true/*gracefully*/))) { + STORAGE_LOG(WARN, "failed to kill all tx", K(ret), KPC_(ls)); + } else { + SERVER_EVENT_ADD("transfer", "ha_kill_tx", + "tenant_id", MTL_ID(), + "ls_id", ls_->get_ls_id(), + "cur_seq", new_seq, + "prev_seq", cur_seq_); + update_seq_(new_seq); + STORAGE_LOG(INFO, "success to kill all tx", K(ret), KPC_(ls), K(new_seq)); + } + return ret; +} + +int ObLSBlockTxService::ha_unblock_tx(const share::SCN &new_seq) +{ + int ret = OB_SUCCESS; + ObMutexGuard mutex_guard(mutex_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ls is not inited", K(ret)); + } else if (OB_FAIL(check_is_leader_())) { + STORAGE_LOG(WARN, "failed to check is leader", K(ret)); + } else if (OB_FAIL(check_seq_(new_seq))) { + STORAGE_LOG(WARN, "failed to check seq", K(ret)); + } else if (OB_FAIL(ls_->get_tx_svr()->unblock_normal())) { + if (OB_STATE_NOT_MATCH == ret) { + ret = OB_SUCCESS; + STORAGE_LOG(INFO, "transfer already unblock", KPC_(ls), K(new_seq)); + } else { + STORAGE_LOG(WARN, "failed to unblock normal", K(ret), K(new_seq)); + } + } else { + SERVER_EVENT_ADD("transfer", "ha_unblock_tx", + "tenant_id", MTL_ID(), + "ls_id", ls_->get_ls_id(), + "cur_seq", new_seq, + "prev_seq", cur_seq_); + update_seq_(new_seq); + STORAGE_LOG(INFO, "success to unblock tx", K(ret), KPC_(ls), K(new_seq)); + } + return ret; +} + +int ObLSBlockTxService::check_is_leader_() +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLSService *ls_srv = NULL; + ObLS *ls = NULL; + logservice::ObLogService *log_service = nullptr; + ObRole role; + int64_t proposal_id = 0; + if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls srv should not be NULL", K(ret), KP(ls_srv)); + } else if (OB_ISNULL(log_service = MTL(logservice::ObLogService*))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "log service should not be NULL", K(ret), KP(log_service)); + } else if (OB_FAIL(log_service->get_palf_role(ls_->get_ls_id(), role, proposal_id))) { + STORAGE_LOG(WARN, "failed to get role", K(ret)); + } else if (!is_strong_leader(role)) { + ret = OB_NOT_MASTER; + STORAGE_LOG(WARN, "ls is not leader, can not block tx", K(ret), K(role)); + } + return ret; +} + +int ObLSBlockTxService::check_seq_(const share::SCN &new_seq) +{ + int ret = OB_SUCCESS; + if (cur_seq_.is_min()) { + // do not check + } else if (new_seq < cur_seq_) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "seq is too old", K(ret), K(new_seq), K(cur_seq_)); + } + STORAGE_LOG(INFO, "compare seq", K(ret), K(new_seq), K(cur_seq_)); + return ret; +} + +int ObLSBlockTxService::update_seq_(const share::SCN &new_seq) +{ + int ret = OB_SUCCESS; + if (!new_seq.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "seq is not valid", K(ret), K(new_seq), K(cur_seq_)); + } else if (new_seq <= cur_seq_) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "seq is too old", K(ret), K(new_seq), K(cur_seq_)); + } else { + cur_seq_ = new_seq; + } + return ret; +} + +} +} diff --git a/src/storage/high_availability/ob_ls_block_tx_service.h b/src/storage/high_availability/ob_ls_block_tx_service.h new file mode 100644 index 000000000..0d4d3885b --- /dev/null +++ b/src/storage/high_availability/ob_ls_block_tx_service.h @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2021 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_STORAGE_LS_BLOCK_TX_SERVICE_ +#define OCEANBASE_STORAGE_LS_BLOCK_TX_SERVICE_ + +#include "lib/lock/ob_mutex.h" + +namespace oceanbase +{ +namespace storage +{ + +class ObLSBlockTxService : public logservice::ObIReplaySubHandler, + public logservice::ObIRoleChangeSubHandler, + public logservice::ObICheckpointSubHandler +{ +public: + ObLSBlockTxService(); + virtual ~ObLSBlockTxService(); + int init(storage::ObLS *ls); + void destroy(); + virtual void switch_to_follower_forcedly() override; + virtual int switch_to_leader() override; + virtual int switch_to_follower_gracefully() override; + virtual int resume_leader() override; + virtual int replay(const void *buffer, + const int64_t nbytes, + const palf::LSN &lsn, + const share::SCN &scn) override final; + virtual share::SCN get_rec_scn() override final { return share::SCN::max_scn(); } + virtual int flush(share::SCN &scn) override final; + +public: + int ha_block_tx(const share::SCN &new_seq); + int ha_kill_tx(const share::SCN &new_seq); + int ha_unblock_tx(const share::SCN &new_seq); + +private: + int check_is_leader_(); + int check_seq_(const share::SCN &seq); + int update_seq_(const share::SCN &seq); +private: + bool is_inited_; + ObMutex mutex_; + share::SCN cur_seq_; + storage::ObLS *ls_; + DISALLOW_COPY_AND_ASSIGN(ObLSBlockTxService); +}; + +} +} +#endif diff --git a/src/storage/high_availability/ob_ls_complete_migration.cpp b/src/storage/high_availability/ob_ls_complete_migration.cpp index 9bd63201f..d6431056a 100644 --- a/src/storage/high_availability/ob_ls_complete_migration.cpp +++ b/src/storage/high_availability/ob_ls_complete_migration.cpp @@ -14,11 +14,15 @@ #include "ob_ls_complete_migration.h" #include "observer/ob_server.h" #include "share/rc/ob_tenant_base.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "logservice/ob_log_service.h" #include "observer/ob_server_event_history_table_operator.h" #include "storage/tablet/ob_tablet_iterator.h" +#include "ob_storage_ha_utils.h" #include "storage/tablet/ob_tablet.h" - +#include "ob_storage_ha_utils.h" +#include "storage/high_availability/ob_transfer_service.h" +#include "storage/high_availability/ob_rebuild_service.h" using namespace oceanbase; using namespace common; @@ -32,7 +36,8 @@ ObLSCompleteMigrationCtx::ObLSCompleteMigrationCtx() arg_(), task_id_(), start_ts_(0), - finish_ts_(0) + finish_ts_(0), + rebuild_seq_(0) { } @@ -317,6 +322,8 @@ int ObLSCompleteMigrationDagNet::update_migration_status_(ObLS *ls) ObTenantDagScheduler *scheduler = nullptr; int32_t result = OB_SUCCESS; + DEBUG_SYNC(BEFORE_COMPLETE_MIGRATION_UPDATE_STATUS); + if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("migration dag net do not init", K(ret)); @@ -330,6 +337,7 @@ int ObLSCompleteMigrationDagNet::update_migration_status_(ObLS *ls) while (!is_finish) { ObMigrationStatus current_migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; ObMigrationStatus new_migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + bool is_ls_deleted = true; if (ls->is_stopped()) { ret = OB_NOT_RUNNING; @@ -340,20 +348,24 @@ int ObLSCompleteMigrationDagNet::update_migration_status_(ObLS *ls) LOG_WARN("tenant dag scheduler has set stop, stop migration dag net", K(ret), K(ctx_)); break; } else { - // TODO: muwei should not do this before ls create finished. if (OB_FAIL(ls->get_migration_status(current_migration_status))) { LOG_WARN("failed to get migration status", K(ret), K(ctx_)); } else if (OB_FAIL(ctx_.get_result(result))) { LOG_WARN("failed to get result", K(ret), K(ctx_)); } else if (ctx_.is_failed()) { + bool is_in_member_list = false; if (ObMigrationOpType::REBUILD_LS_OP == ctx_.arg_.type_) { - if (ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD != current_migration_status) { + if (ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD != current_migration_status + && ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD_WAIT != current_migration_status) { ret = OB_ERR_UNEXPECTED; LOG_WARN("migration status is unexpected", K(ret), K(current_migration_status), K(ctx_)); - } else if (OB_NO_NEED_REBUILD == result) { - new_migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_NONE; - } else { - new_migration_status = current_migration_status; + } else if (OB_FAIL(ObStorageHADagUtils::check_self_in_member_list(ls->get_ls_id(), is_in_member_list))) { + LOG_WARN("failed to check self in member list", K(ret), K(ctx_)); + } else if (OB_FAIL(ObStorageHAUtils::check_ls_deleted(ls->get_ls_id(), is_ls_deleted))) { + LOG_WARN("failed to get ls status from inner table", K(ret), KPC(ls)); + } else if (OB_FAIL(ObMigrationStatusHelper::trans_rebuild_fail_status( + current_migration_status, is_in_member_list, is_ls_deleted, new_migration_status))) { + LOG_WARN("failed to trans rebuild fail status", K(ret), K(ctx_)); } } else if (OB_FAIL(ObMigrationStatusHelper::trans_fail_status(current_migration_status, new_migration_status))) { LOG_WARN("failed to trans fail status", K(ret), K(current_migration_status), K(new_migration_status)); @@ -363,12 +375,13 @@ int ObLSCompleteMigrationDagNet::update_migration_status_(ObLS *ls) } if (OB_FAIL(ret)) { - //TODO(muwei): no need clear } else if (ObMigrationOpType::REBUILD_LS_OP == ctx_.arg_.type_ && ObMigrationStatus::OB_MIGRATION_STATUS_NONE == new_migration_status && OB_FAIL(ls->clear_saved_info())) { LOG_WARN("failed to clear ls saved info", K(ret), KPC(ls)); } else if (OB_FAIL(ls->set_migration_status(new_migration_status, ctx_.rebuild_seq_))) { LOG_WARN("failed to set migration status", K(ret), K(current_migration_status), K(new_migration_status), K(ctx_)); + } else if (OB_FAIL(ObStorageHAUtils::report_ls_meta_table(ctx_.tenant_id_, ls->get_ls_id(), new_migration_status))) { + LOG_WARN("failed to report ls meta table", K(ret), K(ctx_)); } else { is_finish = true; } @@ -398,8 +411,8 @@ int ObLSCompleteMigrationDagNet::deal_with_cancel() } /******************ObCompleteMigrationDag*********************/ -ObCompleteMigrationDag::ObCompleteMigrationDag(const ObStorageHADagType sub_type) - : ObStorageHADag(ObDagType::DAG_TYPE_MIGRATE, sub_type) +ObCompleteMigrationDag::ObCompleteMigrationDag(const share::ObDagType::ObDagTypeEnum &dag_type) + : ObStorageHADag(dag_type) { } @@ -416,9 +429,7 @@ bool ObCompleteMigrationDag::operator == (const ObIDag &other) const is_same = false; } else { const ObStorageHADag &ha_dag = static_cast(other); - if (ha_dag.get_sub_type() != sub_type_) { - is_same = false; - } else if (OB_ISNULL(ha_dag_net_ctx_) || OB_ISNULL(ha_dag.get_ha_dag_net_ctx())) { + if (OB_ISNULL(ha_dag_net_ctx_) || OB_ISNULL(ha_dag.get_ha_dag_net_ctx())) { is_same = false; LOG_ERROR_RET(OB_ERR_UNEXPECTED, "complete migration ctx should not be NULL", KP(ha_dag_net_ctx_), KP(ha_dag.get_ha_dag_net_ctx())); } else if (ha_dag_net_ctx_->get_dag_net_ctx_type() != ha_dag.get_ha_dag_net_ctx()->get_dag_net_ctx_type()) { @@ -448,12 +459,30 @@ int64_t ObCompleteMigrationDag::hash() const ObLSCompleteMigrationCtx *self_ctx = static_cast(ha_dag_net_ctx_); hash_value = common::murmurhash( &self_ctx->arg_.ls_id_, sizeof(self_ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } +int ObCompleteMigrationDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + ObLSCompleteMigrationCtx *ctx = nullptr; + + if (FALSE_IT(ctx = static_cast(ha_dag_net_ctx_))) { + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(ctx->tenant_id_), ctx->arg_.ls_id_.id(), + static_cast(ctx->arg_.type_), + "dag_net_task_id", to_cstring(ctx->task_id_), + "src", to_cstring(ctx->arg_.src_.get_server()), + "dest", to_cstring(ctx->arg_.dst_.get_server())))) { + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} + int ObCompleteMigrationDag::prepare_ctx(share::ObIDagNet *dag_net) { int ret = OB_SUCCESS; @@ -479,7 +508,7 @@ int ObCompleteMigrationDag::prepare_ctx(share::ObIDagNet *dag_net) /******************ObInitialCompleteMigrationDag*********************/ ObInitialCompleteMigrationDag::ObInitialCompleteMigrationDag() - : ObCompleteMigrationDag(ObStorageHADagType::INITIAL_COMPLETE_MIGRATION_DAG), + : ObCompleteMigrationDag(share::ObDagType::DAG_TYPE_INITIAL_COMPLETE_MIGRATION), is_inited_(false) { } @@ -544,29 +573,6 @@ int ObInitialCompleteMigrationDag::create_first_task() return ret; } -int ObInitialCompleteMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - int64_t pos = 0; - ObLSCompleteMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("initial complete migration dag do not init", K(ret)); - } else if (NULL == buf || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid args", K(ret), KP(buf), K(buf_len)); - } else if (FALSE_IT(ctx = static_cast(ha_dag_net_ctx_))) { - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObInitialCompleteMigrationDag : dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, " - "src = %s, dest = %s", to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), - ObMigrationOpType::get_str(ctx->arg_.type_), to_cstring(ctx->arg_.src_.get_server()), - to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObInitialCompleteMigrationTask*********************/ ObInitialCompleteMigrationTask::ObInitialCompleteMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -720,7 +726,7 @@ int ObInitialCompleteMigrationTask::generate_migration_dags_() scheduler->free_dag(*finish_complete_dag, initial_complete_migration_dag); finish_complete_dag = nullptr; } - if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, true /*allow_retry*/))) { + if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, true /*allow_retry*/, this->get_dag()->get_type()))) { LOG_WARN("failed to set complete migration result", K(ret), K(tmp_ret), K(*ctx_)); } } @@ -730,7 +736,7 @@ int ObInitialCompleteMigrationTask::generate_migration_dags_() /******************ObStartCompleteMigrationDag*********************/ ObStartCompleteMigrationDag::ObStartCompleteMigrationDag() - : ObCompleteMigrationDag(ObStorageHADagType::START_COMPLETE_MIGRATION_DAG), + : ObCompleteMigrationDag(share::ObDagType::DAG_TYPE_START_COMPLETE_MIGRATION), is_inited_(false) { } @@ -796,36 +802,13 @@ int ObStartCompleteMigrationDag::create_first_task() return ret; } -int ObStartCompleteMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - int64_t pos = 0; - ObLSCompleteMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("start complete migration dag do not init", K(ret)); - } else if (NULL == buf || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid args", K(ret), KP(buf), K(buf_len)); - } else if (FALSE_IT(ctx = static_cast(ha_dag_net_ctx_))) { - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObStartCompleteMigrationDag : dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, " - "src = %s, dest = %s", to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), - ObMigrationOpType::get_str(ctx->arg_.type_), to_cstring(ctx->arg_.src_.get_server()), - to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObStartCompleteMigrationTask*********************/ ObStartCompleteMigrationTask::ObStartCompleteMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), is_inited_(false), ls_handle_(), ctx_(nullptr), - log_sync_scn_(SCN::min_scn()), + log_sync_lsn_(0), max_minor_end_scn_(SCN::min_scn()) { } @@ -873,10 +856,14 @@ int ObStartCompleteMigrationTask::process() LOG_WARN("start complete migration task do not init", K(ret)); } else if (ctx_->is_failed()) { //do nothing + } else if (OB_FAIL(update_ls_migration_status_wait_())) { + LOG_WARN("failed to update ls migration wait", K(ret), KPC(ctx_)); } else if (OB_FAIL(wait_log_sync_())) { LOG_WARN("failed wait log sync", K(ret), KPC(ctx_)); } else if (OB_FAIL(wait_log_replay_sync_())) { LOG_WARN("failed to wait log replay sync", K(ret), KPC(ctx_)); + } else if (OB_FAIL(wait_transfer_table_replace_())) { + LOG_WARN("failed to wait transfer table replace", K(ret), KPC(ctx_)); } else if (OB_FAIL(check_all_tablet_ready_())) { LOG_WARN("failed to check all tablet ready", K(ret), KPC(ctx_)); } else if (OB_FAIL(wait_trans_tablet_explain_data_())) { @@ -885,7 +872,7 @@ int ObStartCompleteMigrationTask::process() LOG_WARN("failed to wait log replay to max minor end scn", K(ret), KPC(ctx_)); } else if (OB_FAIL(update_ls_migration_status_hold_())) { LOG_WARN("failed to update ls migration status hold", K(ret), KPC(ctx_)); - } else if (OB_FAIL(change_member_list_())) { + } else if (OB_FAIL(change_member_list_with_retry_())) { LOG_WARN("failed to change member list", K(ret), KPC(ctx_)); } if (OB_SUCCESS != (tmp_ret = record_server_event_())) { @@ -907,9 +894,8 @@ int ObStartCompleteMigrationTask::wait_log_sync_() ObLS *ls = nullptr; bool is_log_sync = false; bool is_need_rebuild = false; - bool is_cancel = false; - SCN last_end_scn; - SCN current_end_scn; + palf::LSN last_end_lsn(0); + palf::LSN current_end_lsn(0); const int64_t OB_CHECK_LOG_SYNC_INTERVAL = 200 * 1000; // 200ms const int64_t CLOG_IN_SYNC_DELAY_TIMEOUT = 30 * 60 * 1000 * 1000; // 30 min bool need_wait = true; @@ -925,29 +911,26 @@ int ObStartCompleteMigrationTask::wait_log_sync_() } else if (!need_wait) { FLOG_INFO("no need wait log sync", KPC(ctx_)); } else { +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("storage_ha", "wait_log_sync", + "tenant_id", ctx_->tenant_id_, + "ls_id", ls->get_ls_id().id()); +#endif + DEBUG_SYNC(BEFORE_WAIT_LOG_SYNC); const int64_t wait_replay_start_ts = ObTimeUtility::current_time(); int64_t current_ts = 0; int64_t last_wait_replay_ts = ObTimeUtility::current_time(); while (OB_SUCC(ret) && !is_log_sync) { - if (ctx_->is_failed()) { - ret = OB_CANCELED; - STORAGE_LOG(WARN, "group task has error, cancel subtask", K(ret)); - } else if (ls->is_stopped()) { - ret = OB_NOT_RUNNING; - LOG_WARN("ls is not running, stop migration dag net", K(ret), K(ctx_)); - } else if (OB_FAIL(SYS_TASK_STATUS_MGR.is_task_cancel(get_dag()->get_dag_id(), is_cancel))) { - STORAGE_LOG(ERROR, "failed to check is task canceled", K(ret), K(*this)); - } else if (is_cancel) { - ret = OB_CANCELED; - STORAGE_LOG(WARN, "task is cancelled", K(ret), K(*this)); + if (OB_FAIL(check_ls_and_task_status_(ls))) { + LOG_WARN("failed to check ls and task status", K(ret), KPC(ctx_)); } else if (OB_FAIL(ls->is_in_sync(is_log_sync, is_need_rebuild))) { LOG_WARN("failed to check is in sync", K(ret), KPC(ctx_)); } if (OB_FAIL(ret)) { } else if (is_log_sync) { - if (OB_FAIL(ls->get_end_scn(log_sync_scn_))) { - LOG_WARN("failed to get end scn", K(ret), KPC(ctx_)); + if (OB_FAIL(ls->get_end_lsn(log_sync_lsn_))) { + LOG_WARN("failed to get end lsn", K(ret), KPC(ctx_)); } else { const int64_t cost_ts = ObTimeUtility::current_time() - wait_replay_start_ts; LOG_INFO("log is sync, stop wait_log_sync", "arg", ctx_->arg_, K(cost_ts)); @@ -956,7 +939,7 @@ int ObStartCompleteMigrationTask::wait_log_sync_() const int64_t cost_ts = ObTimeUtility::current_time() - wait_replay_start_ts; ret = OB_LOG_NOT_SYNC; LOG_WARN("log is not sync", K(ret), KPC(ctx_), K(cost_ts)); - } else if (OB_FAIL(ls->get_end_scn(current_end_scn))) { + } else if (OB_FAIL(ls->get_end_lsn(current_end_lsn))) { LOG_WARN("failed to get end scn", K(ret), KPC(ctx_)); } else { bool is_timeout = false; @@ -964,27 +947,27 @@ int ObStartCompleteMigrationTask::wait_log_sync_() LOG_INFO("log is not sync, retry next loop", "arg", ctx_->arg_); } - if (current_end_scn == last_end_scn) { + if (current_end_lsn == last_end_lsn) { const int64_t current_ts = ObTimeUtility::current_time(); if ((current_ts - last_wait_replay_ts) > CLOG_IN_SYNC_DELAY_TIMEOUT) { is_timeout = true; } if (is_timeout) { - if (OB_FAIL(ctx_->set_result(OB_LOG_NOT_SYNC, true /*allow_retry*/))) { + if (OB_FAIL(ctx_->set_result(OB_LOG_NOT_SYNC, true /*allow_retry*/, this->get_dag()->get_type()))) { LOG_WARN("failed to set result", K(ret), KPC(ctx_)); } else { ret = OB_LOG_NOT_SYNC; STORAGE_LOG(WARN, "failed to check log replay sync. timeout, stop migration task", K(ret), K(*ctx_), K(CLOG_IN_SYNC_DELAY_TIMEOUT), K(wait_replay_start_ts), - K(current_ts), K(current_end_scn)); + K(current_ts), K(current_end_lsn)); } } - } else if (last_end_scn > current_end_scn) { + } else if (last_end_lsn > current_end_lsn) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("last end log ts should not smaller than current end log ts", K(ret), K(last_end_scn), K(current_end_scn)); + LOG_WARN("last end log ts should not smaller than current end log ts", K(ret), K(last_end_lsn), K(current_end_lsn)); } else { - last_end_scn = current_end_scn; + last_end_lsn = current_end_lsn; last_wait_replay_ts = ObTimeUtility::current_time(); } @@ -1007,17 +990,29 @@ int ObStartCompleteMigrationTask::wait_log_replay_sync_() int ret = OB_SUCCESS; ObLS *ls = nullptr; logservice::ObLogService *log_service = nullptr; + logservice::ObLogReplayService *log_replay_service = nullptr; + ObRebuildService *rebuild_service = nullptr; bool wait_log_replay_success = false; - bool is_cancel = false; SCN current_replay_scn; SCN last_replay_scn; const int64_t OB_CHECK_LOG_REPLAY_INTERVAL = 200 * 1000; // 200ms - const int64_t CLOG_IN_REPLAY_DELAY_TIMEOUT = 30 * 60 * 1000 * 1000L; // 30 min + const int64_t CLOG_IN_REPLAY_DELAY_TIMEOUT = 10 * 60 * 1000 * 1000L; // 10 min + //TODO(muwei.ym) MAKE THIS TIME PARAM as hide configuration iterms bool need_wait = false; + bool is_done = false; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("start complete migration task do not init", K(ret)); + } else if (OB_ISNULL(log_service = (MTL(logservice::ObLogService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log service should not be NULL", K(ret), KP(log_replay_service)); + } else if (OB_ISNULL(rebuild_service = (MTL(ObRebuildService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rebuild service should not be NULL", K(ret), KP(rebuild_service)); + } else if (OB_ISNULL(log_replay_service = log_service->get_log_replay_service())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls replay service should not be NULL", K(ret), KP(log_replay_service)); } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls should not be NULL", K(ret), KP(ls), KPC(ctx_)); @@ -1026,34 +1021,43 @@ int ObStartCompleteMigrationTask::wait_log_replay_sync_() } else if (!need_wait) { FLOG_INFO("no need wait replay log sync", KPC(ctx_)); } else { +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("storage_ha", "wait_log_replay_sync", + "tenant_id", ctx_->tenant_id_, + "ls_id", ls->get_ls_id().id()); +#endif + DEBUG_SYNC(BEFORE_WAIT_LOG_REPLAY_SYNC); const int64_t wait_replay_start_ts = ObTimeUtility::current_time(); int64_t last_replay_ts = 0; int64_t current_ts = 0; + bool need_rebuild = false; while (OB_SUCC(ret) && !wait_log_replay_success) { - if (ctx_->is_failed()) { - ret = OB_CANCELED; - STORAGE_LOG(WARN, "group task has error, cancel subtask", K(ret)); - } else if (ls->is_stopped()) { - ret = OB_NOT_RUNNING; - LOG_WARN("ls is not running, stop migration dag net", K(ret), K(ctx_)); - } else if (OB_FAIL(SYS_TASK_STATUS_MGR.is_task_cancel(get_dag()->get_dag_id(), is_cancel))) { - STORAGE_LOG(ERROR, "failed to check is task canceled", K(ret), K(*this)); - } else if (is_cancel) { - ret = OB_CANCELED; - STORAGE_LOG(WARN, "task is cancelled", K(ret), K(*this)); - } else if (OB_FAIL(ls->get_max_decided_scn(current_replay_scn))) { - LOG_WARN("failed to get current replay log ts", K(ret), KPC(ctx_)); - } else if (current_replay_scn.convert_to_ts() + IS_REPLAY_DONE_THRESHOLD_US >= log_sync_scn_.convert_to_ts()) { + if (OB_FAIL(check_ls_and_task_status_(ls))) { + LOG_WARN("failed to check ls and task status", K(ret), KPC(ctx_)); + } else if (OB_FAIL(rebuild_service->check_ls_need_rebuild(ls->get_ls_id(), need_rebuild))) { + LOG_WARN("failed to check ls need rebuild", K(ret), KPC(ls)); + } else if (need_rebuild) { + if (OB_FAIL(ctx_->set_result(OB_LS_NEED_REBUILD, false /*allow_retry*/))) { + LOG_WARN("failed to set result", K(ret), KPC(ctx_)); + } else { + ret = OB_LS_NEED_REBUILD; + LOG_WARN("ls need rebuild", K(ret), KPC(ls)); + } + } else if (OB_FAIL(log_replay_service->is_replay_done(ls->get_ls_id(), log_sync_lsn_, is_done))) { + LOG_WARN("failed to check is replay done", K(ret), KPC(ls), K(log_sync_lsn_)); + } else if (is_done) { wait_log_replay_success = true; const int64_t cost_ts = ObTimeUtility::current_time() - wait_replay_start_ts; LOG_INFO("wait replay log ts ns success, stop wait", "arg", ctx_->arg_, K(cost_ts)); + } else if (OB_FAIL(ls->get_max_decided_scn(current_replay_scn))) { + LOG_WARN("failed to get current replay log ts", K(ret), KPC(ctx_)); } else { current_ts = ObTimeUtility::current_time(); bool is_timeout = false; if (REACH_TENANT_TIME_INTERVAL(60 * 1000 * 1000)) { LOG_INFO("replay log is not sync, retry next loop", "arg", ctx_->arg_, "current_replay_scn", current_replay_scn, - "log_sync_scn", log_sync_scn_); + "log_sync_lsn", log_sync_lsn_); } if (current_replay_scn == last_replay_scn) { @@ -1061,7 +1065,7 @@ int ObStartCompleteMigrationTask::wait_log_replay_sync_() is_timeout = true; } if (is_timeout) { - if (OB_FAIL(ctx_->set_result(OB_WAIT_REPLAY_TIMEOUT, true /*allow_retry*/))) { + if (OB_FAIL(ctx_->set_result(OB_WAIT_REPLAY_TIMEOUT, true /*allow_retry*/, this->get_dag()->get_type()))) { LOG_WARN("failed to set result", K(ret), KPC(ctx_)); } else { ret = OB_WAIT_REPLAY_TIMEOUT; @@ -1094,6 +1098,47 @@ int ObStartCompleteMigrationTask::wait_log_replay_sync_() return ret; } +int ObStartCompleteMigrationTask::wait_transfer_table_replace_() +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + const int64_t check_all_tablet_start_ts = ObTimeUtility::current_time(); + const bool need_initial_state = false; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("start complete migration task do not init", K(ret)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to change member list", K(ret), KP(ls)); + } else { + SERVER_EVENT_ADD("storage_ha", "wait_transfer_table_replace", + "tenant_id", ctx_->tenant_id_, + "ls_id", ls->get_ls_id().id()); + ObHALSTabletIDIterator iter(ls->get_ls_id(), need_initial_state); + ObTabletID tablet_id; + if (OB_FAIL(ls->get_tablet_svr()->build_tablet_iter(iter))) { + LOG_WARN("failed to build tablet iter", K(ret), KPC(ctx_)); + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.get_next_tablet_id(tablet_id))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get tablet id", K(ret)); + } + } else if (OB_FAIL(check_tablet_transfer_table_ready_(tablet_id, ls))) { + LOG_WARN("failed to check tablet ready", K(ret), K(tablet_id), KPC(ls)); + } + } + LOG_INFO("check all tablet transfer table ready finish", K(ret), "ls_id", ctx_->arg_.ls_id_, + "cost ts", ObTimeUtility::current_time() - check_all_tablet_start_ts); + } + } + return ret; +} + int ObStartCompleteMigrationTask::wait_trans_tablet_explain_data_() { int ret = OB_SUCCESS; @@ -1107,7 +1152,56 @@ int ObStartCompleteMigrationTask::wait_trans_tablet_explain_data_() ret = OB_ERR_UNEXPECTED; LOG_WARN("ls should not be NULL", K(ret), KPC(ctx_)); } else { - //TODO(muwei.ym) wait log replay to max tablet minor sstable log ts + //TODO(muwei.ym) wait log replay to max tablet minor sstable log ts in 4.3 + } + return ret; +} + +int ObStartCompleteMigrationTask::change_member_list_with_retry_() +{ + //change to HOLD status do not allow failed + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + static const int64_t CHANGE_MEMBER_LIST_RETRY_INTERVAL = 2_s; + int64_t retry_times = 0; + bool is_in_member_list = false; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("start complete migration task do not init", K(ret)); + } else { + while (retry_times < OB_MAX_RETRY_TIMES) { + if (retry_times >= 1) { + LOG_WARN("retry change member list", K(retry_times)); + } + + if (OB_FAIL(change_member_list_())) { + LOG_WARN("failed to change member list", K(ret), K(retry_times)); + } else { + break; + } + + if (OB_FAIL(ret)) { + //overwrite ret + if (OB_FAIL(ObStorageHADagUtils::check_self_in_member_list(ctx_->arg_.ls_id_, is_in_member_list))) { + LOG_WARN("failed to check self in member list", K(ret), KPC(ctx_)); + } else if (is_in_member_list) { + break; + } else { + ret = OB_EAGAIN; + LOG_WARN("self ls is not in member list, need retry", K(ret), "ls_id", ctx_->arg_.ls_id_); + } + } + + if (OB_FAIL(ret)) { + retry_times++; + ob_usleep(CHANGE_MEMBER_LIST_RETRY_INTERVAL); + } + } + if (OB_FAIL(ret)) { + if (OB_SUCCESS != (tmp_ret = ctx_->set_result(OB_MEMBER_CHANGE_FAILED, false /*need retry*/, this->get_dag()->get_type()))) { + LOG_WARN("failed to set result", K(tmp_ret), K(ret)); + } + } } return ret; } @@ -1118,6 +1212,8 @@ int ObStartCompleteMigrationTask::change_member_list_() ObLS *ls = nullptr; DEBUG_SYNC(MEMBERLIST_CHANGE_MEMBER); const int64_t start_ts = ObTimeUtility::current_time(); + common::ObAddr leader_addr; + share::SCN ls_transfer_scn; if (!is_inited_) { ret = OB_NOT_INIT; @@ -1128,12 +1224,16 @@ int ObStartCompleteMigrationTask::change_member_list_() } else if (ObMigrationOpType::ADD_LS_OP != ctx_->arg_.type_ && ObMigrationOpType::MIGRATE_LS_OP != ctx_->arg_.type_) { //do nothing + } else if (OB_FAIL(ObStorageHAUtils::get_ls_leader(ctx_->tenant_id_, ctx_->arg_.ls_id_, leader_addr))) { + LOG_WARN("failed to get ls leader", K(ret), KPC(ctx_)); + } else if (OB_FAIL(OB_FAIL(get_ls_transfer_scn_(ls, ls_transfer_scn)))) { + LOG_WARN("failed to get ls transfer scn", K(ret), KP(ls)); } else { if (ObMigrationOpType::ADD_LS_OP == ctx_->arg_.type_) { const int64_t change_member_list_timeout_us = GCONF.sys_bkgd_migration_change_member_list_timeout; if (REPLICA_TYPE_FULL == ctx_->arg_.dst_.get_replica_type()) { - if (OB_FAIL(ls->add_member(ctx_->arg_.dst_, ctx_->arg_.paxos_replica_number_, change_member_list_timeout_us))) { - LOG_WARN("failed to add member", K(ret), KPC(ctx_)); + if (OB_FAIL(add_member_(leader_addr, ls_transfer_scn))) { + LOG_WARN("failed to add member", K(ret), K(leader_addr), K(ls_transfer_scn)); } } else { // R-replica @@ -1144,12 +1244,13 @@ int ObStartCompleteMigrationTask::change_member_list_() } else if (ObMigrationOpType::MIGRATE_LS_OP == ctx_->arg_.type_) { const int64_t change_member_list_timeout_us = GCONF.sys_bkgd_migration_change_member_list_timeout; if (REPLICA_TYPE_FULL == ctx_->arg_.dst_.get_replica_type()) { - if (OB_FAIL(ls->replace_member(ctx_->arg_.dst_, ctx_->arg_.src_, change_member_list_timeout_us))) { - LOG_WARN("failed to replace member", K(ret), KPC(ctx_)); + if (OB_FAIL(replace_member_(leader_addr, ls_transfer_scn))) { + LOG_WARN("failed to replace member", K(ret), K(leader_addr), K(ls_transfer_scn)); } } else { // R-replica - if (OB_FAIL(ls->replace_learner(ctx_->arg_.dst_, ctx_->arg_.src_, change_member_list_timeout_us))) { + if (OB_FAIL(ls->replace_learner(ctx_->arg_.dst_, ctx_->arg_.src_, + change_member_list_timeout_us))) { LOG_WARN("failed to replace_learner", K(ret), KPC(ctx_)); } } @@ -1166,6 +1267,62 @@ int ObStartCompleteMigrationTask::change_member_list_() return ret; } +int ObStartCompleteMigrationTask::get_ls_transfer_scn_(ObLS *ls, share::SCN &transfer_scn) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret)); + } else if (OB_FAIL(ls->get_transfer_scn(transfer_scn))) { + LOG_WARN("failed to get transfer scn", K(ret), KP(ls)); + } + return ret; +} + +int ObStartCompleteMigrationTask::add_member_(const common::ObAddr &leader_addr, const share::SCN &ls_transfer_scn) +{ + int ret = OB_SUCCESS; + ObLSService *ls_svr = NULL; + ObStorageRpc *storage_rpc = NULL; + ObStorageHASrcInfo src_info; + src_info.cluster_id_ = GCONF.cluster_id; + src_info.src_addr_ = leader_addr; + const int64_t timeout = GCONF.sys_bkgd_migration_change_member_list_timeout; + if (OB_ISNULL(ls_svr = (MTL(ObLSService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), KP(ls_svr)); + } else if (OB_ISNULL(storage_rpc = ls_svr->get_storage_rpc())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage rpc should not be NULL", K(ret), KP(storage_rpc)); + } else if (OB_FAIL(storage_rpc->add_member(ctx_->tenant_id_, src_info, ctx_->arg_.ls_id_, ctx_->arg_.dst_, + ctx_->arg_.paxos_replica_number_, ls_transfer_scn, timeout))) { + LOG_WARN("failed to add member", K(ret), KPC(ctx_)); + } + return ret; +} + +int ObStartCompleteMigrationTask::replace_member_(const common::ObAddr &leader_addr, const share::SCN &ls_transfer_scn) +{ + int ret = OB_SUCCESS; + ObLSService *ls_svr = NULL; + ObStorageRpc *storage_rpc = NULL; + ObStorageHASrcInfo src_info; + src_info.cluster_id_ = GCONF.cluster_id; + src_info.src_addr_ = leader_addr; + const int64_t timeout = GCONF.sys_bkgd_migration_change_member_list_timeout; + if (OB_ISNULL(ls_svr = (MTL(ObLSService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), KP(ls_svr)); + } else if (OB_ISNULL(storage_rpc = ls_svr->get_storage_rpc())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage rpc should not be NULL", K(ret), KP(storage_rpc)); + } else if (OB_FAIL(storage_rpc->replace_member(ctx_->tenant_id_, src_info, ctx_->arg_.ls_id_, ctx_->arg_.dst_, + ctx_->arg_.src_, ls_transfer_scn, timeout))) { + LOG_WARN("failed to replace member", K(ret), KPC(ctx_)); + } + return ret; +} + int ObStartCompleteMigrationTask::check_need_wait_( ObLS *ls, bool &need_wait) @@ -1199,6 +1356,40 @@ int ObStartCompleteMigrationTask::check_need_wait_( return ret; } +int ObStartCompleteMigrationTask::update_ls_migration_status_wait_() +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + ObMigrationStatus wait_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("start complete migration task do not init", K(ret)); + } else if (ObMigrationOpType::MIGRATE_LS_OP != ctx_->arg_.type_ + && ObMigrationOpType::ADD_LS_OP != ctx_->arg_.type_ + && ObMigrationOpType::REBUILD_LS_OP != ctx_->arg_.type_) { + ret = OB_ERR_SYS; + LOG_WARN("no other type should update migration status wait", K(ret), KPC(ctx_)); + } else if (OB_FAIL(ObMigrationOpType::get_ls_wait_status(ctx_->arg_.type_, wait_status))) { + LOG_WARN("failed to get ls wait status", K(ret)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to change member list", K(ret), KP(ls)); + } else if (OB_FAIL(ls->set_migration_status(wait_status, ctx_->rebuild_seq_))) { + LOG_WARN("failed to set migration status", K(ret), KPC(ls)); + } else { +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("storage_ha", "update_ls_migration_status_wait", + "tenant_id", ctx_->tenant_id_, + "ls_id", ctx_->arg_.ls_id_.id(), + "src", ctx_->arg_.src_.get_server(), + "dst", ctx_->arg_.dst_.get_server(), + "task_id", ctx_->task_id_); +#endif + } + return ret; +} + int ObStartCompleteMigrationTask::update_ls_migration_status_hold_() { int ret = OB_SUCCESS; @@ -1272,9 +1463,9 @@ int ObStartCompleteMigrationTask::check_tablet_ready_( ObLS *ls) { int ret = OB_SUCCESS; - const int64_t timeout_us = ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US; - const int64_t OB_CHECK_TABLET_READY_INTERVAL = 200 * 1000; // 200ms - const int64_t OB_CHECK_TABLET_READY_TIMEOUT = 30 * 60 * 1000 * 1000L; // 30 min + const ObMDSGetTabletMode read_mode = ObMDSGetTabletMode::READ_WITHOUT_CHECK; + const int64_t OB_CHECK_TABLET_READY_INTERVAL = 200_ms; + const int64_t OB_CHECK_TABLET_READY_TIMEOUT = 30_min; if (!is_inited_) { ret = OB_NOT_INIT; @@ -1284,20 +1475,14 @@ int ObStartCompleteMigrationTask::check_tablet_ready_( LOG_WARN("check tablet ready get invalid argument", K(ret), K(tablet_id), KP(ls)); } else { const int64_t wait_tablet_start_ts = ObTimeUtility::current_time(); - bool is_cancel = false; while (OB_SUCC(ret)) { ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; - if (ls->is_stopped()) { - ret = OB_NOT_RUNNING; - LOG_WARN("ls is not running, stop migration dag net", K(ret), K(ctx_)); - } else if (OB_FAIL(SYS_TASK_STATUS_MGR.is_task_cancel(get_dag()->get_dag_id(), is_cancel))) { - STORAGE_LOG(ERROR, "failed to check is task canceled", K(ret), K(*this)); - } else if (is_cancel) { - ret = OB_CANCELED; - STORAGE_LOG(WARN, "task is cancelled", K(ret), K(*this)); - } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, timeout_us))) { + + if (OB_FAIL(check_ls_and_task_status_(ls))) { + LOG_WARN("failed to check ls and task status", K(ret), KPC(ctx_)); + } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, 0, read_mode))) { if (OB_TABLET_NOT_EXIST == ret) { ret = OB_SUCCESS; break; @@ -1307,26 +1492,38 @@ int ObStartCompleteMigrationTask::check_tablet_ready_( } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_handle), K(tablet_id)); + } else if (tablet->is_empty_shell()) { + max_minor_end_scn_ = MAX(max_minor_end_scn_, tablet->get_tablet_meta().get_max_replayed_scn()); + break; } else if (tablet->get_tablet_meta().ha_status_.is_data_status_complete() || !tablet->get_tablet_meta().ha_status_.is_restore_status_full()) { - ObSSTableArray &minor_sstables = tablet->get_table_store().get_minor_sstables(); - if (minor_sstables.empty()) { - max_minor_end_scn_ = MAX(max_minor_end_scn_, tablet->get_tablet_meta().clog_checkpoint_scn_); + ObTabletMemberWrapper table_store_wrapper; + if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - max_minor_end_scn_ = MAX(max_minor_end_scn_, minor_sstables.array_[minor_sstables.count() - 1]->get_end_scn()); + const ObSSTableArray &minor_sstables = table_store_wrapper.get_member()->get_minor_sstables(); + if (minor_sstables.empty()) { + max_minor_end_scn_ = MAX(max_minor_end_scn_, tablet->get_tablet_meta().get_max_replayed_scn()); + } else { + max_minor_end_scn_ = MAX3(max_minor_end_scn_, + minor_sstables.get_boundary_table(true)->get_end_scn(), + tablet->get_tablet_meta().get_max_replayed_scn()); + } } break; } else { const int64_t current_ts = ObTimeUtility::current_time(); if (REACH_TENANT_TIME_INTERVAL(60 * 1000 * 1000)) { LOG_INFO("tablet not ready, retry next loop", "arg", ctx_->arg_, "tablet_id", tablet_id, + "ha_status", tablet->get_tablet_meta().ha_status_, "wait_tablet_start_ts", wait_tablet_start_ts, "current_ts", current_ts); } if (current_ts - wait_tablet_start_ts < OB_CHECK_TABLET_READY_TIMEOUT) { } else { - if (OB_FAIL(ctx_->set_result(OB_WAIT_TABLET_READY_TIMEOUT, true /*allow_retry*/))) { + if (OB_FAIL(ctx_->set_result(OB_WAIT_TABLET_READY_TIMEOUT, true /*allow_retry*/, + this->get_dag()->get_type()))) { LOG_WARN("failed to set result", K(ret), KPC(ctx_)); } else { ret = OB_WAIT_TABLET_READY_TIMEOUT; @@ -1345,12 +1542,145 @@ int ObStartCompleteMigrationTask::check_tablet_ready_( return ret; } +int ObStartCompleteMigrationTask::check_tablet_transfer_table_ready_( + const common::ObTabletID &tablet_id, + ObLS *ls) +{ + int ret = OB_SUCCESS; + const int64_t OB_CHECK_TABLET_READY_INTERVAL = 200_ms; + const int64_t OB_CHECK_TABLET_READY_TIMEOUT = 30_min; + ObTransferService *transfer_service = nullptr; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("start complete migration task do not init", K(ret)); + } else if (!tablet_id.is_valid() || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check tablet ready get invalid argument", K(ret), K(tablet_id), KP(ls)); + } else if (OB_ISNULL(transfer_service = MTL(ObTransferService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer service should not be NULL", K(ret), KP(transfer_service)); + } else { + const int64_t wait_tablet_start_ts = ObTimeUtility::current_time(); + bool need_check_again = false; + + while (OB_SUCC(ret)) { + if (OB_FAIL(check_ls_and_task_status_(ls))) { + LOG_WARN("failed to check ls and task status", K(ret), KPC(ctx_)); + } else if (OB_FAIL(inner_check_tablet_transfer_table_ready_(tablet_id, ls, need_check_again))) { + LOG_WARN("failed to inner check tablet transfer table ready", K(ret), K(tablet_id), KP(ls)); + } else if (!need_check_again) { + break; + } else { + LOG_INFO("tablet has transfer table", K(ret), K(tablet_id), "ls_id", ls->get_ls_id()); + const int64_t current_ts = ObTimeUtility::current_time(); + transfer_service->wakeup(); + if (current_ts - wait_tablet_start_ts < OB_CHECK_TABLET_READY_TIMEOUT) { + } else { + if (OB_FAIL(ctx_->set_result(OB_WAIT_TABLET_READY_TIMEOUT, true /*allow_retry*/, + this->get_dag()->get_type()))) { + LOG_WARN("failed to set result", K(ret), KPC(ctx_)); + } else { + ret = OB_WAIT_TABLET_READY_TIMEOUT; + STORAGE_LOG(WARN, "failed to check tablet ready, timeout, stop migration task", + K(ret), K(*ctx_), K(tablet_id), KPC(ls), K(current_ts), K(wait_tablet_start_ts)); + } + } + + if (OB_SUCC(ret)) { + ob_usleep(OB_CHECK_TABLET_READY_INTERVAL); + } + } + } + } + return ret; +} + +int ObStartCompleteMigrationTask::inner_check_tablet_transfer_table_ready_( + const common::ObTabletID &tablet_id, + ObLS *ls, + bool &need_check_again) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + need_check_again = true; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + const ObMDSGetTabletMode read_mode = ObMDSGetTabletMode::READ_WITHOUT_CHECK; + bool can_skip = true; + ObTabletCreateDeleteMdsUserData user_data; + ObLSService *ls_service = nullptr; + ObLSHandle src_ls_handle; + ObLS *src_ls = nullptr; + SCN scn; + ObTabletHandle src_tablet_handle; + + if (!tablet_id.is_valid() || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(tablet_id), KP(ls)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + need_check_again = false; + } else { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_handle), K(tablet_id)); + } else if (tablet->is_empty_shell()) { + need_check_again = false; + } else if (!tablet->get_tablet_meta().has_transfer_table()) { + LOG_INFO("tablet do not has transfer table", K(ret), K(tablet_id), "ls_id", ls->get_ls_id()); + need_check_again = false; + } else if (OB_FAIL(ls_service->get_ls(tablet->get_tablet_meta().transfer_info_.ls_id_, src_ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get transfer src ls", K(ret), KPC(tablet)); + if (OB_LS_NOT_EXIST == ret) { + if (OB_SUCCESS != (tmp_ret = ctx_->set_result(OB_TRANSFER_SRC_LS_NOT_EXIST, true /*allow_retry*/))) { + LOG_WARN("failed to set result", K(ret), K(tmp_ret), KPC(ctx_)); + } + } + } else if (OB_ISNULL(src_ls = src_ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src ls should not be NULL", K(ret), KPC(tablet), KP(src_ls)); + } else if (OB_FAIL(src_ls->get_max_decided_scn(scn))) { + LOG_WARN("failed to get max decided scn", K(ret), KPC(src_ls)); + } else if (scn <= tablet->get_tablet_meta().transfer_info_.transfer_start_scn_) { + need_check_again = true; + if (REACH_TENANT_TIME_INTERVAL(5 * 1000 * 1000/*5s*/)) { + LOG_INFO("need to wait for the max_decided_scn to be greater than transfer_start_scn", K(tablet_id), K(scn), + "transfer_start_scn", tablet->get_tablet_meta().transfer_info_.transfer_start_scn_, + "ls_id", tablet->get_tablet_meta().transfer_info_.ls_id_); + } + } else if (OB_FAIL(src_ls->ha_get_tablet(tablet_id, src_tablet_handle))) { + LOG_WARN("failed to get transfer src tablet", K(ret), K(tablet_id)); + if (OB_TABLET_NOT_EXIST == ret) { + if (OB_SUCCESS != (tmp_ret = ctx_->set_result(OB_TRANSFER_SRC_TABLET_NOT_EXIST, true /*allow_retry*/))) { + LOG_WARN("failed to set result", K(ret), K(tmp_ret), KPC(ctx_)); + } + } + } else { + need_check_again = true; +#ifdef ERRSIM + if (REACH_TENANT_TIME_INTERVAL(10 * 1000 * 1000)) { + SERVER_EVENT_ADD("TRANSFER", "still_has_transfer_table", + "ls_id", ls->get_ls_id(), + "tablet_id", tablet_id.id(), + "has_transfer_table", tablet->get_tablet_meta().has_transfer_table()); + } +#endif + } + return ret; +} + int ObStartCompleteMigrationTask::wait_log_replay_to_max_minor_end_scn_() { int ret = OB_SUCCESS; ObLSHandle ls_handle; ObLS *ls = nullptr; - bool is_cancel = false; bool need_wait = true; SCN current_replay_scn = share::SCN::min_scn(); const int64_t OB_WAIT_LOG_REPLAY_INTERVAL = 200 * 1000; // 200ms @@ -1371,17 +1701,8 @@ int ObStartCompleteMigrationTask::wait_log_replay_to_max_minor_end_scn_() } else { const int64_t wait_replay_start_ts = ObTimeUtility::current_time(); while (OB_SUCC(ret)) { - if (ctx_->is_failed()) { - ret = OB_CANCELED; - STORAGE_LOG(WARN, "ls migration task is failed, cancel wait ls check point ts push", K(ret)); - } else if (ls->is_stopped()) { - ret = OB_NOT_RUNNING; - LOG_WARN("ls is not running, stop migration dag net", K(ret), K(ctx_)); - } else if (OB_FAIL(SYS_TASK_STATUS_MGR.is_task_cancel(get_dag()->get_dag_id(), is_cancel))) { - STORAGE_LOG(ERROR, "failed to check is task canceled", K(ret), K(*this)); - } else if (is_cancel) { - ret = OB_CANCELED; - STORAGE_LOG(WARN, "task is cancelled", K(ret), K(*this)); + if (OB_FAIL(check_ls_and_task_status_(ls))) { + LOG_WARN("failed to check ls and task status", K(ret), KPC(ctx_)); } else if (OB_FAIL(ls->get_max_decided_scn(current_replay_scn))) { LOG_WARN("failed to get current replay log ts", K(ret), KPC(ctx_)); } else if (current_replay_scn >= max_minor_end_scn_) { @@ -1399,7 +1720,8 @@ int ObStartCompleteMigrationTask::wait_log_replay_to_max_minor_end_scn_() if (current_ts - wait_replay_start_ts < OB_WAIT_LOG_REPLAY_TIMEOUT) { } else { - if (OB_FAIL(ctx_->set_result(OB_WAIT_REPLAY_TIMEOUT, true /*allow_retry*/))) { + if (OB_FAIL(ctx_->set_result(OB_WAIT_REPLAY_TIMEOUT, true /*allow_retry*/, + this->get_dag()->get_type()))) { LOG_WARN("failed to set result", K(ret), KPC(ctx_)); } else { ret = OB_WAIT_REPLAY_TIMEOUT; @@ -1417,6 +1739,36 @@ int ObStartCompleteMigrationTask::wait_log_replay_to_max_minor_end_scn_() return ret; } +int ObStartCompleteMigrationTask::check_ls_and_task_status_( + ObLS *ls) +{ + int ret = OB_SUCCESS; + bool is_cancel = false; + bool is_ls_deleted = true; + + if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check ls and task status get invalid argument", K(ret), KP(ls)); + } else if (ctx_->is_failed()) { + ret = OB_CANCELED; + STORAGE_LOG(WARN, "ls migration task is failed", K(ret), KPC(ctx_)); + } else if (ls->is_stopped()) { + ret = OB_NOT_RUNNING; + LOG_WARN("ls is not running, stop migration dag net", K(ret), KPC(ctx_)); + } else if (OB_FAIL(SYS_TASK_STATUS_MGR.is_task_cancel(get_dag()->get_dag_id(), is_cancel))) { + STORAGE_LOG(ERROR, "failed to check is task canceled", K(ret), K(*this)); + } else if (is_cancel) { + ret = OB_CANCELED; + STORAGE_LOG(WARN, "task is cancelled", K(ret), K(*this)); + } else if (OB_FAIL(ObStorageHAUtils::check_ls_deleted(ls->get_ls_id(), is_ls_deleted))) { + LOG_WARN("failed to get ls status from inner table", K(ret)); + } else if (is_ls_deleted) { + ret = OB_CANCELED; + LOG_WARN("ls will be removed, no need run migration", K(ret), KPC(ls), K(is_ls_deleted)); + } + return ret; +} + int ObStartCompleteMigrationTask::record_server_event_() { int ret = OB_SUCCESS; @@ -1438,7 +1790,7 @@ int ObStartCompleteMigrationTask::record_server_event_() /******************ObFinishCompleteMigrationDag*********************/ ObFinishCompleteMigrationDag::ObFinishCompleteMigrationDag() - : ObCompleteMigrationDag(ObStorageHADagType::FINISH_COMPLETE_MIGRATION_DAG), + : ObCompleteMigrationDag(share::ObDagType::DAG_TYPE_FINISH_COMPLETE_MIGRATION), is_inited_(false) { } @@ -1504,29 +1856,6 @@ int ObFinishCompleteMigrationDag::create_first_task() return ret; } -int ObFinishCompleteMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - int64_t pos = 0; - ObLSCompleteMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("finish complete migration dag do not init", K(ret)); - } else if (NULL == buf || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid args", K(ret), KP(buf), K(buf_len)); - } else if (FALSE_IT(ctx = static_cast(ha_dag_net_ctx_))) { - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObFinishCompleteMigrationDag : dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, " - "src = %s, dest = %s", to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), - ObMigrationOpType::get_str(ctx->arg_.type_), to_cstring(ctx->arg_.src_.get_server()), - to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObFinishCompleteMigrationTask*********************/ ObFinishCompleteMigrationTask::ObFinishCompleteMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -1587,13 +1916,11 @@ int ObFinishCompleteMigrationTask::process() LOG_WARN("failed to generate prepare initial dag", K(ret), KPC(ctx_)); } } - } else if (OB_FAIL(try_enable_vote_())) { - LOG_WARN("failed to try enable vote", K(ret), KPC(ctx_)); } - if (OB_FAIL(ret)) { const bool need_retry = false; - if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, need_retry))) { + if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, need_retry, + this->get_dag()->get_type()))) { LOG_WARN("failed to set result", K(ret), K(ret), K(tmp_ret), KPC(ctx_)); } } @@ -1650,55 +1977,6 @@ int ObFinishCompleteMigrationTask::generate_prepare_initial_dag_() return ret; } -int ObFinishCompleteMigrationTask::try_enable_vote_() -{ - int ret = OB_SUCCESS; - ObLS *ls = nullptr; - ObLSHandle ls_handle; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("finish complete migration task do not init", K(ret)); - } else if (ObMigrationOpType::REBUILD_LS_OP != ctx_->arg_.type_) { - //do nothing - } else { - if (OB_FAIL(ObStorageHADagUtils::get_ls(ctx_->arg_.ls_id_, ls_handle))) { - LOG_WARN("failed to get ls", K(ret), K(ctx_)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_SYS; - LOG_ERROR("ls should not be NULL", K(ret), KPC(ctx_)); - } - - #ifdef ERRSIM - if (OB_SUCC(ret)) { - ret = OB_E(EventTable::EN_MIGRATION_ENABLE_VOTE_FAILED) OB_SUCCESS; - if (OB_FAIL(ret)) { - STORAGE_LOG(ERROR, "fake EN_MIGRATION_ENABLE_VOTE_FAILED", K(ret)); - } - } - #endif - - if (OB_FAIL(ret)) { - } else if (OB_ISNULL(ls)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls should not be null", K(ret)); - } else if (OB_FAIL(ls->enable_vote())) { - LOG_WARN("failed to enable vote", K(ret), KPC(ctx_)); - } else { - LOG_INFO("succeed enable vote", KPC(ctx_)); - #ifdef ERRSIM - if (OB_SUCC(ret)) { - ret = OB_E(EventTable::EN_MIGRATION_ENABLE_VOTE_RETRY) OB_SUCCESS; - if (OB_FAIL(ret)) { - STORAGE_LOG(ERROR, "fake EN_MIGRATION_ENABLE_VOTE_RETRY", K(ret)); - } - } - #endif - } - } - return ret; -} - int ObFinishCompleteMigrationTask::record_server_event_() { int ret = OB_SUCCESS; diff --git a/src/storage/high_availability/ob_ls_complete_migration.h b/src/storage/high_availability/ob_ls_complete_migration.h index cb2ada945..0a51d3a6b 100644 --- a/src/storage/high_availability/ob_ls_complete_migration.h +++ b/src/storage/high_availability/ob_ls_complete_migration.h @@ -18,6 +18,7 @@ #include "ob_storage_ha_struct.h" #include "storage/tx_storage/ob_ls_service.h" #include "ob_storage_ha_dag.h" +#include "logservice/palf/lsn.h" namespace oceanbase { @@ -104,10 +105,11 @@ private: class ObCompleteMigrationDag : public ObStorageHADag { public: - explicit ObCompleteMigrationDag(const ObStorageHADagType sub_type); + explicit ObCompleteMigrationDag(const share::ObDagType::ObDagTypeEnum &dag_type); virtual ~ObCompleteMigrationDag(); virtual bool operator == (const share::ObIDag &other) const override; virtual int64_t hash() const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; int prepare_ctx(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObIDag", ObStorageHADag, KP(this)); @@ -122,8 +124,6 @@ public: virtual ~ObInitialCompleteMigrationDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; - int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObCompleteMigrationDag", ObCompleteMigrationDag, KP(this)); protected: @@ -156,8 +156,6 @@ public: virtual ~ObStartCompleteMigrationDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; - int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObCompleteMigrationDag", ObCompleteMigrationDag, KP(this)); protected: @@ -176,17 +174,38 @@ public: private: int wait_log_sync_(); int wait_log_replay_sync_(); + int wait_transfer_table_replace_(); int wait_trans_tablet_explain_data_(); + int change_member_list_with_retry_(); int change_member_list_(); + int get_ls_transfer_scn_( + ObLS *ls, + share::SCN &transfer_scn); + int add_member_( + const common::ObAddr &leader_addr, + const share::SCN &ls_transfer_scn); + int replace_member_( + const common::ObAddr &leader_addr, + const share::SCN &ls_transfer_scn); int check_need_wait_( ObLS *ls, bool &need_wait); + int update_ls_migration_status_wait_(); int update_ls_migration_status_hold_(); int check_all_tablet_ready_(); int check_tablet_ready_( const common::ObTabletID &tablet_id, ObLS *ls); + int check_tablet_transfer_table_ready_( + const common::ObTabletID &tablet_id, + ObLS *ls); + int inner_check_tablet_transfer_table_ready_( + const common::ObTabletID &tablet_id, + ObLS *ls, + bool &need_skip); int wait_log_replay_to_max_minor_end_scn_(); + int check_ls_and_task_status_( + ObLS *ls); int record_server_event_(); private: @@ -194,7 +213,7 @@ private: bool is_inited_; ObLSHandle ls_handle_; ObLSCompleteMigrationCtx *ctx_; - share::SCN log_sync_scn_; + palf::LSN log_sync_lsn_; share::SCN max_minor_end_scn_; DISALLOW_COPY_AND_ASSIGN(ObStartCompleteMigrationTask); }; @@ -206,8 +225,6 @@ public: virtual ~ObFinishCompleteMigrationDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; - int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObCompleteMigrationDag", ObCompleteMigrationDag, KP(this)); protected: @@ -225,7 +242,6 @@ public: VIRTUAL_TO_STRING_KV(K("ObFinishCompleteMigrationTask"), KP(this), KPC(ctx_)); private: int generate_prepare_initial_dag_(); - int try_enable_vote_(); int record_server_event_(); private: diff --git a/src/storage/high_availability/ob_ls_member_list_service.cpp b/src/storage/high_availability/ob_ls_member_list_service.cpp new file mode 100644 index 000000000..fba539e4b --- /dev/null +++ b/src/storage/high_availability/ob_ls_member_list_service.cpp @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2021 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 "storage/ls/ob_ls.h" +#include "storage/high_availability/ob_ls_member_list_service.h" + +namespace oceanbase +{ +namespace storage +{ + +ObLSMemberListService::ObLSMemberListService() + : is_inited_(false), + ls_(NULL), + log_handler_(NULL) +{ +} + +ObLSMemberListService::~ObLSMemberListService() +{ +} + +int ObLSMemberListService::init(storage::ObLS *ls, logservice::ObLogHandler *log_handler) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + STORAGE_LOG(WARN, "member list service is inited", K(ret), KP(ls)); + } else if (OB_UNLIKELY(nullptr == ls || nullptr == log_handler)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), KP(ls), KP(log_handler)); + } else { + ls_ = ls; + log_handler_ = log_handler; + is_inited_ = true; + STORAGE_LOG(INFO, "success to init member list service", K(ret), KP(ls), "ls_id", ls_->get_ls_id(), KP(this)); + } + return ret; +} + +void ObLSMemberListService::destroy() +{ + is_inited_ = false; + ls_ = nullptr; + log_handler_ = nullptr; +} + +int ObLSMemberListService::add_member( + const common::ObMember &member, + const int64_t paxos_replica_num, + const share::SCN &transfer_scn, + const int64_t add_member_timeout_us) +{ + int ret = OB_SUCCESS; + palf::LogConfigVersion config_version; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ls is not inited", K(ret)); + } else if (OB_FAIL(log_handler_->get_leader_config_version(config_version))) { + STORAGE_LOG(WARN, "failed to get config version", K(ret)); + } else if (OB_FAIL(check_ls_transfer_scn_(transfer_scn))) { + STORAGE_LOG(WARN, "failed to check ls transfer scn", K(ret)); + } else if (OB_FAIL(log_handler_->add_member(member, paxos_replica_num, config_version, add_member_timeout_us))) { + STORAGE_LOG(WARN, "failed to add member", K(ret)); + } else { + STORAGE_LOG(INFO, "add member success", K(ret), K(member), K(paxos_replica_num), K(config_version)); + } + return ret; +} + +int ObLSMemberListService::replace_member( + const common::ObMember &added_member, + const common::ObMember &removed_member, + const share::SCN &transfer_scn, + const int64_t replace_member_timeout_us) +{ + int ret = OB_SUCCESS; + palf::LogConfigVersion config_version; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ls is not inited", K(ret)); + } else if (OB_FAIL(log_handler_->get_leader_config_version(config_version))) { + STORAGE_LOG(WARN, "failed to get config version", K(ret)); + } else if (OB_FAIL(check_ls_transfer_scn_(transfer_scn))) { + STORAGE_LOG(WARN, "failed to check ls transfer scn", K(ret)); + } else if (OB_FAIL(log_handler_->replace_member(added_member, removed_member, config_version, replace_member_timeout_us))) { + STORAGE_LOG(WARN, "failed to add member", K(ret)); + } else { + STORAGE_LOG(INFO, "replace member success", K(ret)); + } + return ret; +} + +int ObLSMemberListService::switch_learner_to_acceptor( + const common::ObMember &learner, + const int64_t paxos_replica_num, + const share::SCN &transfer_scn, + const int64_t timeout_us) +{ + int ret = OB_SUCCESS; + palf::LogConfigVersion config_version; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "ls is not inited", K(ret)); + } else if (OB_FAIL(log_handler_->get_leader_config_version(config_version))) { + STORAGE_LOG(WARN, "failed to get config version", K(ret)); + } else if (OB_FAIL(check_ls_transfer_scn_(transfer_scn))) { + STORAGE_LOG(WARN, "failed to check ls transfer scn", K(ret)); + } else if (OB_FAIL(log_handler_->switch_learner_to_acceptor( + learner, paxos_replica_num, config_version, timeout_us))) { + STORAGE_LOG(WARN, "failed to switch learner to acceptor", K(ret)); + } else { + STORAGE_LOG(INFO, "switch learner to acceptor success", K(ret)); + } + return ret; +} + +// TODO(yangyi.yyy): how to check standby transfer scn +int ObLSMemberListService::check_ls_transfer_scn_(const share::SCN &transfer_scn) +{ + int ret = OB_SUCCESS; + share::SCN local_transfer_scn; + if (OB_ISNULL(ls_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls should not be null", K(ret), KP_(ls)); + } else if (OB_FAIL(ls_->get_transfer_scn(local_transfer_scn))) { + STORAGE_LOG(WARN, "failed to get transfer scn", K(ret), KP_(ls)); + } else if (transfer_scn < local_transfer_scn) { + ret = OB_LS_TRANSFER_SCN_TOO_SMALL; + STORAGE_LOG(WARN, "transfer scn is less than local transfer scn", K(ret), K(transfer_scn)); + } else { + STORAGE_LOG(INFO, "check ls transfer scn", KPC_(ls), K(transfer_scn), K(local_transfer_scn)); + } + return ret; +} + +} +} diff --git a/src/storage/high_availability/ob_ls_member_list_service.h b/src/storage/high_availability/ob_ls_member_list_service.h new file mode 100644 index 000000000..47c78bea5 --- /dev/null +++ b/src/storage/high_availability/ob_ls_member_list_service.h @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2021 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_STORAGE_LS_MEMBER_LIST_SERVICE_ +#define OCEANBASE_STORAGE_LS_MEMBER_LIST_SERVICE_ + +#include "logservice/ob_log_handler.h" +#include "common/ob_member.h" + +namespace oceanbase +{ +namespace storage +{ + +class ObLSMemberListService final +{ +public: + ObLSMemberListService(); + virtual ~ObLSMemberListService(); + int init(storage::ObLS *ls, logservice::ObLogHandler *log_handler); + void destroy(); + +public: + int add_member(const common::ObMember &member, + const int64_t paxos_replica_num, + const share::SCN &transfer_scn, + const int64_t add_member_timeout_us); + int replace_member(const common::ObMember &added_member, + const common::ObMember &removed_member, + const share::SCN &transfer_scn, + const int64_t replace_member_timeout_us); + int switch_learner_to_acceptor(const common::ObMember &learner, + const int64_t paxos_replica_num, + const share::SCN &transfer_scn, + const int64_t timeout_us); + +private: + int check_ls_transfer_scn_(const share::SCN &transfer_scn); +private: + bool is_inited_; + storage::ObLS *ls_; + logservice::ObLogHandler *log_handler_; + DISALLOW_COPY_AND_ASSIGN(ObLSMemberListService); +}; + +} +} +#endif diff --git a/src/storage/high_availability/ob_ls_migration.cpp b/src/storage/high_availability/ob_ls_migration.cpp index eb6f86382..fbd0eb44f 100644 --- a/src/storage/high_availability/ob_ls_migration.cpp +++ b/src/storage/high_availability/ob_ls_migration.cpp @@ -15,6 +15,7 @@ #include "observer/ob_server.h" #include "ob_physical_copy_task.h" #include "share/rc/ob_tenant_base.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "storage/tablet/ob_tablet_common.h" #include "storage/tx_storage/ob_ls_service.h" #include "logservice/ob_log_service.h" @@ -26,6 +27,7 @@ #include "ob_storage_ha_utils.h" #include "storage/tablet/ob_tablet.h" #include "share/ls/ob_ls_table_operator.h" +#include "ob_rebuild_service.h" namespace oceanbase { @@ -80,6 +82,7 @@ void ObMigrationCtx::reset() tablet_group_mgr_.reuse(); ObIHADagNetCtx::reset(); check_tablet_info_cost_time_ = 0; + tablet_simple_info_map_.reuse(); } int ObMigrationCtx::fill_comment(char *buf, const int64_t buf_len) const @@ -123,6 +126,7 @@ void ObMigrationCtx::reuse() tablet_group_mgr_.reuse(); ObIHADagNetCtx::reuse(); check_tablet_info_cost_time_ = 0; + tablet_simple_info_map_.reuse(); } /******************ObCopyTabletCtx*********************/ @@ -251,6 +255,7 @@ int ObMigrationDagNet::init_by_param(const ObIDagInitParam *param) { int ret = OB_SUCCESS; const ObMigrationDagNetInitParam* init_param = static_cast(param); + const int64_t MAX_BUCKET_NUM = 8192; if (is_inited_) { ret = OB_INIT_TWICE; LOG_WARN("migration dag net is init twice", K(ret)); @@ -265,6 +270,8 @@ int ObMigrationDagNet::init_by_param(const ObIDagInitParam *param) LOG_WARN("failed to init ha table key mgr", K(ret), KPC(init_param)); } else if (OB_FAIL(ctx_->tablet_group_mgr_.init())) { LOG_WARN("failed to init tablet group mgr", K(ret), KPC(init_param)); + } else if (OB_FAIL(ctx_->tablet_simple_info_map_.create(MAX_BUCKET_NUM, "DataHATask"))) { + LOG_WARN("failed to create tablet simple info map", K(ret)); } else { ctx_->tenant_id_ = MTL_ID(); ctx_->arg_ = init_param->arg_; @@ -431,8 +438,8 @@ int ObMigrationDagNet::deal_with_cancel() } /******************ObMigrationDag*********************/ -ObMigrationDag::ObMigrationDag(const ObStorageHADagType sub_type) - : ObStorageHADag(ObDagType::DAG_TYPE_MIGRATE, sub_type) +ObMigrationDag::ObMigrationDag(const share::ObDagType::ObDagTypeEnum &dag_type) + : ObStorageHADag(dag_type) { } @@ -440,9 +447,28 @@ ObMigrationDag::~ObMigrationDag() { } +int ObMigrationDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + ObMigrationCtx *ctx = nullptr; + + if (OB_ISNULL(ctx = get_migration_ctx())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("migration dag migration ctx should not be NULL", K(ret), KP(ctx)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(ctx->tenant_id_), ctx->arg_.ls_id_.id(), + static_cast(ctx->arg_.type_), + "dag_net_task_id", to_cstring(ctx->task_id_), + "src", to_cstring(ctx->arg_.src_.get_server()), + "dest", to_cstring(ctx->arg_.dst_.get_server())))) { + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} + /******************ObInitialMigrationDag*********************/ ObInitialMigrationDag::ObInitialMigrationDag() - : ObMigrationDag(ObStorageHADagType::INITIAL_MIGRATION_DAG), + : ObMigrationDag(ObDagType::DAG_TYPE_INITIAL_MIGRATION), is_inited_(false) { } @@ -463,9 +489,7 @@ bool ObInitialMigrationDag::operator == (const ObIDag &other) const } else { const ObMigrationDag &other_dag = static_cast(other); ctx = get_migration_ctx(); - if (other_dag.get_sub_type() != sub_type_) { - is_same = false; - } else if (OB_ISNULL(ctx) || OB_ISNULL(other_dag.get_migration_ctx())) { + if (OB_ISNULL(ctx) || OB_ISNULL(other_dag.get_migration_ctx())) { is_same = false; LOG_ERROR_RET(OB_INVALID_ARGUMENT, "migration ctx should not be NULL", KP(ctx), KP(other_dag.get_migration_ctx())); } else if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { @@ -487,8 +511,9 @@ int64_t ObInitialMigrationDag::hash() const } else { hash_value = common::murmurhash( &ctx->arg_.ls_id_, sizeof(ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } @@ -557,26 +582,6 @@ int ObInitialMigrationDag::create_first_task() return ret; } -int ObInitialMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("initial migration dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_migration_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("inital migration dag migration ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObInitialMigrationDag : dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, src = %s, dest = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), ObMigrationOpType::get_str(ctx->arg_.type_), - to_cstring(ctx->arg_.src_.get_server()), to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObInitialMigrationTask*********************/ ObInitialMigrationTask::ObInitialMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -627,6 +632,20 @@ int ObInitialMigrationTask::process() { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("storage_ha", "before_prepare_migration_task"); + DEBUG_SYNC(BEFORE_PREPARE_MIGRATION_TASK); +#endif + +#ifdef ERRSIM + const int64_t errsim_migration_ls_id = GCONF.errsim_migration_ls_id; + if (!is_meta_tenant(ctx_->tenant_id_) && errsim_migration_ls_id == ctx_->arg_.ls_id_.id()) { + SERVER_EVENT_SYNC_ADD("storage_ha", "errsim_before_initial_migration", + "tenant_id", ctx_->tenant_id_, + "ls_id", errsim_migration_ls_id); + DEBUG_SYNC(BEFORE_INITIAL_MIGRATION_TASK); + } +#endif if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("initial migration task do not init", K(ret)); @@ -724,7 +743,8 @@ int ObInitialMigrationTask::generate_migration_dags_() migration_finish_dag = nullptr; } const bool need_retry = true; - if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, need_retry))) { + if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, need_retry, + this->get_dag()->get_type()))) { LOG_WARN("failed to set migration result", K(ret), K(tmp_ret), K(*ctx_)); } } @@ -752,7 +772,7 @@ int ObInitialMigrationTask::record_server_event_() /******************ObStartMigrationDag*********************/ ObStartMigrationDag::ObStartMigrationDag() - : ObMigrationDag(ObStorageHADagType::START_MIGRATION_DAG), + : ObMigrationDag(ObDagType::DAG_TYPE_START_MIGRATION), is_inited_(false) { } @@ -771,9 +791,7 @@ bool ObStartMigrationDag::operator == (const ObIDag &other) const } else { const ObMigrationDag &other_dag = static_cast(other); ObMigrationCtx *ctx = get_migration_ctx(); - if (other_dag.get_sub_type() != sub_type_) { - is_same = false; - } else if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { + if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { if (ctx->arg_.ls_id_ != other_dag.get_migration_ctx()->arg_.ls_id_) { is_same = false; } @@ -790,8 +808,9 @@ int64_t ObStartMigrationDag::hash() const if (NULL != ctx) { hash_value = common::murmurhash( &ctx->arg_.ls_id_, sizeof(ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } @@ -860,26 +879,6 @@ int ObStartMigrationDag::create_first_task() return ret; } -int ObStartMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("start migration dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_migration_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("migration ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObStartMigrationDag : dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, src = %s, dest = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), ObMigrationOpType::get_str(ctx->arg_.type_), - to_cstring(ctx->arg_.src_.get_server()), to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObStartMigrationTask*********************/ ObStartMigrationTask::ObStartMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -929,7 +928,6 @@ int ObStartMigrationTask::process() int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; bool need_copy_data = false; - bool need_generate_dag = false; if (!is_inited_) { ret = OB_NOT_INIT; @@ -948,12 +946,8 @@ int ObStartMigrationTask::process() LOG_WARN("failed to report ls meta table", K(ret), KPC(ctx_)); } else if (OB_FAIL(choose_src_())) { LOG_WARN("failed to choose src", K(ret), KPC(ctx_)); - } else if (OB_FAIL(update_ls_())) { - LOG_WARN("failed to update_ls_", K(ret), KPC(ctx_)); - } else if (OB_FAIL(deal_local_restore_ls_(need_generate_dag))) { - LOG_WARN("failed to deal local restore ls", K(ret), KPC(ctx_)); - } else if (!need_generate_dag) { - //do nothing + } else if (OB_FAIL(build_ls_())) { + LOG_WARN("failed to build ls", K(ret), KPC(ctx_)); } else { #ifdef ERRSIM if (OB_SUCC(ret)) { @@ -1059,18 +1053,20 @@ int ObStartMigrationTask::deal_with_local_ls_() LOG_WARN("leader cannot as add, migrate, change dst", K(ret), K(role), "myaddr", MYADDR, "arg", ctx_->arg_); } - } else if (ObMigrationOpType::REBUILD_LS_OP == ctx_->arg_.type_ - && OB_FAIL(ls->disable_vote(true/*need_check*/))) { - LOG_WARN("failed to disable vote", K(ret), KPC(ctx_)); - if (OB_OP_NOT_ALLOW == ret) { - if (ls->is_offline() && OB_FAIL(ls->online())) { - LOG_WARN("failed to online ls", K(ret), KPC(ctx_)); - } else { - ret = OB_NO_NEED_REBUILD; - } - } } else if (OB_FAIL(ls->offline())) { LOG_WARN("failed to disable log", K(ret), KPC(ctx_)); + } else if (ObMigrationOpType::REBUILD_LS_OP == ctx_->arg_.type_) { + if (OB_FAIL(ls->set_ls_rebuild())) { + LOG_WARN("failed to set ls rebuild", K(ret), KPC(ctx_)); + } + } else { + ObRebuildService *rebuild_service = nullptr; + if (OB_ISNULL(rebuild_service = MTL(ObRebuildService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rebuild service should not be NULL", K(ret), KP(rebuild_service)); + } else if (OB_FAIL(rebuild_service->remove_rebuild_ls(ctx_->arg_.ls_id_))) { + LOG_WARN("failed to remove rebuild ls", K(ret), KPC(ctx_)); + } } if (OB_FAIL(ret) || OB_ISNULL(ls)) { @@ -1098,30 +1094,21 @@ int ObStartMigrationTask::deal_with_local_ls_() int ObStartMigrationTask::report_ls_meta_table_() { int ret = OB_SUCCESS; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("start migration task do not init", K(ret)); } else if (OB_ISNULL(ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ctx should not be null", K(ret)); - } else if (ObMigrationOpType::ADD_LS_OP != ctx_->arg_.type_ - && ObMigrationOpType::MIGRATE_LS_OP != ctx_->arg_.type_) { - // do nothing + } else if (OB_FAIL(ObMigrationStatusHelper::trans_migration_op( + ctx_->arg_.type_, migration_status))) { + LOG_WARN("failed to trans migration op", K(ret), K(ctx_)); } else { const uint64_t tenant_id = ctx_->tenant_id_; const share::ObLSID &ls_id = ctx_->arg_.ls_id_; - ObLSReplica ls_replica; - share::ObLSTableOperator *lst_operator = GCTX.lst_operator_; - const bool inner_table_only = false; - if (OB_FAIL(GCTX.ob_service_->fill_ls_replica(tenant_id, ls_id, ls_replica))) { - LOG_WARN("failed to fill ls replica", K(ret), K(tenant_id), K(ls_id)); - } else if (OB_FAIL(lst_operator->update(ls_replica, inner_table_only))) { - LOG_WARN("failed to update ls meta table", K(ret), K(ls_replica)); - } else { - SERVER_EVENT_ADD("storage_ha", "report_ls_meta_table", - "tenant_id", tenant_id, - "ls_id", ls_id); - LOG_INFO("report ls meta table", K(ls_replica)); + if (OB_FAIL(ObStorageHAUtils::report_ls_meta_table(tenant_id, ls_id, migration_status))) { + LOG_WARN("failed to report ls meta table", K(ret), K(tenant_id), K(ls_id)); } } DEBUG_SYNC(AFTER_MIGRATION_REPORT_LS_META_TABLE); @@ -1176,7 +1163,8 @@ int ObStartMigrationTask::choose_src_() SERVER_EVENT_ADD("storage_ha", "after_choose_src", "tenant_id", ctx_->tenant_id_, "ls_id", ctx_->arg_.ls_id_.id(), - "local_rebuild_seq", ctx_->local_rebuild_seq_); + "local_rebuild_seq", ctx_->local_rebuild_seq_, + "transfer_scn", ctx_->src_ls_meta_package_.ls_meta_.get_transfer_scn()); DEBUG_SYNC(ALTER_LS_CHOOSE_SRC); } #endif @@ -1423,38 +1411,91 @@ int ObStartMigrationTask::check_ls_need_copy_data_(bool &need_copy) return ret; } -int ObStartMigrationTask::deal_local_restore_ls_(bool &need_generate_dag) +int ObStartMigrationTask::check_before_ls_migrate_(const ObLSMeta &ls_meta) { int ret = OB_SUCCESS; - need_generate_dag = true; - ObLSHandle ls_handle; - ObLS *ls = nullptr; ObLSRestoreStatus ls_restore_status; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("start migration task do not init", K(ret)); + } else if (OB_FAIL(ls_meta.get_restore_status(ls_restore_status))) { + LOG_WARN("failed to get restore status", K(ret), KPC(ctx_)); + } else if (ls_restore_status.is_restore_failed()) { + ret = OB_LS_RESTORE_FAILED; + LOG_WARN("ls restore failed, cannot migrate", K(ret), KPC(ctx_), K(ls_restore_status)); + } else if (!ls_restore_status.can_migrate()) { + ret = OB_SRC_DO_NOT_ALLOWED_MIGRATE; + LOG_WARN("src ls is in restore status, cannot migrate, wait later", K(ret), K(ls_restore_status)); + } + return ret; +} + +int ObStartMigrationTask::build_ls_() +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + ObCopyLSViewInfoObReader *ob_reader = nullptr; + obrpc::ObCopyLSViewArg arg; + arg.tenant_id_ = ctx_->tenant_id_; + arg.ls_id_ = ctx_->arg_.ls_id_; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("start migration task do not init", K(ret)); + } else if (FALSE_IT(buf = ob_malloc(sizeof(ObCopyLSViewInfoObReader), "CopyLSViewRead"))) { + } else if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret)); + } else if (FALSE_IT(ob_reader = new (buf) ObCopyLSViewInfoObReader())) { + } else if (OB_FAIL(ob_reader->init(ctx_->minor_src_, arg, *svr_rpc_proxy_, *bandwidth_throttle_))) { + LOG_WARN("failed to init tablet ob reader", K(ret), KPC(ctx_), K(arg)); + } else if (OB_FAIL(ob_reader->get_ls_meta(ctx_->src_ls_meta_package_))) { + LOG_WARN("fail to read ls meta infos", K(ret)); + } else if (OB_FAIL(check_before_ls_migrate_(ctx_->src_ls_meta_package_.ls_meta_))) { + LOG_WARN("failed to check before ls migrate", K(ret), KPC(ctx_)); + } else if (OB_FAIL(update_ls_())) { + LOG_WARN("failed to update local ls", K(ret), KPC(ctx_)); + } else if (OB_FAIL(create_all_tablets_(ob_reader))) { + LOG_WARN("failed to create all tablets", K(ret), KPC(ctx_)); + } + + if (OB_NOT_NULL(ob_reader)) { + ob_reader->~ObCopyLSViewInfoObReader(); + ob_free(ob_reader); + ob_reader = nullptr; + } + return ret; +} + +int ObStartMigrationTask::create_all_tablets_( + ObCopyLSViewInfoObReader *ob_reader) +{ + int ret = OB_SUCCESS; + ObStorageHATabletsBuilder ha_tablets_builder; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObArray tablet_id_array; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("start migration task do not init", K(ret)); + } else if (OB_ISNULL(ob_reader)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("create all tablets get ivnalid argument", K(ret)); } else if (OB_FAIL(ObStorageHADagUtils::get_ls(ctx_->arg_.ls_id_, ls_handle))) { LOG_WARN("failed to get ls", K(ret), KPC(ctx_)); } else if (OB_ISNULL(ls = ls_handle.get_ls())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls should not be NULL", K(ret), KPC(ctx_)); - } else if (OB_FAIL(ls->get_restore_status(ls_restore_status))) { - LOG_WARN("failed to get restore status", K(ret), KPC(ctx_)); - } else if (ls_restore_status.is_restore_failed()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls restore status is not expected", K(ret), KPC(ctx_), KPC(ls), K(ls_restore_status)); - } else if (ls_restore_status.is_restore_start()) { - ret = OB_SRC_DO_NOT_ALLOWED_MIGRATE; - LOG_WARN("src ls is in restore start, wait later", K(ret), KPC(ls)); - } else if (ls_restore_status.is_restore_sys_tablets()) { - need_generate_dag = false; - if (OB_FAIL(ls->enable_for_restore())) { - LOG_WARN("failed to enable for restore", K(ret)); - } else { - LOG_INFO("ls restore status is in restore start or in restore sys tablets, no need generate dag", - K(ls_restore_status), "ls_id", ctx_->arg_.ls_id_); - } + LOG_WARN("ls should not be NULL", K(ret), KP(ls), KPC(ctx_)); + } else if (OB_FAIL(ObLSMigrationUtils::init_ha_tablets_builder( + ctx_->tenant_id_, tablet_id_array, ctx_->minor_src_, ctx_->local_rebuild_seq_, ctx_->arg_.type_, + ls, &ctx_->ha_table_info_mgr_, ha_tablets_builder))) { + LOG_WARN("failed to init ha tablets builder", K(ret), KPC(ctx_)); + } else if (OB_FAIL(ha_tablets_builder.create_all_tablets(ob_reader, + ctx_->sys_tablet_id_array_, ctx_->data_tablet_id_array_, + ctx_->tablet_simple_info_map_))) { + LOG_WARN("failed to create all tablets", K(ret), KPC(ctx_)); } return ret; } @@ -1480,7 +1521,7 @@ int ObStartMigrationTask::record_server_event_() /******************ObSysTabletsMigrationDag*********************/ ObSysTabletsMigrationDag::ObSysTabletsMigrationDag() - : ObMigrationDag(ObStorageHADagType::SYS_TABLETS_MIGRATION_DAG), + : ObMigrationDag(ObDagType::DAG_TYPE_SYS_TABLETS_MIGRATION), is_inited_(false) { } @@ -1499,9 +1540,7 @@ bool ObSysTabletsMigrationDag::operator == (const ObIDag &other) const } else { const ObMigrationDag &other_dag = static_cast(other); ObMigrationCtx *ctx = get_migration_ctx(); - if (other_dag.get_sub_type() != sub_type_) { - is_same = false; - } else if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { + if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { if (ctx->arg_.ls_id_ != other_dag.get_migration_ctx()->arg_.ls_id_) { is_same = false; } @@ -1518,8 +1557,9 @@ int64_t ObSysTabletsMigrationDag::hash() const if (NULL != ctx) { hash_value = common::murmurhash( &ctx->arg_.ls_id_, sizeof(ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } @@ -1588,26 +1628,6 @@ int ObSysTabletsMigrationDag::create_first_task() return ret; } -int ObSysTabletsMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("sys tablets migration dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_migration_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("migration ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObSysTabletsMigrationDag : dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, src = %s, dest = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), ObMigrationOpType::get_str(ctx->arg_.type_), - to_cstring(ctx->arg_.src_.get_server()), to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObSysTabletsMigrationTask*********************/ ObSysTabletsMigrationTask::ObSysTabletsMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -1654,7 +1674,7 @@ int ObSysTabletsMigrationTask::init() } else if (OB_FAIL(ObLSMigrationUtils::init_ha_tablets_builder( ctx_->tenant_id_, ctx_->sys_tablet_id_array_, ctx_->minor_src_, ctx_->local_rebuild_seq_, ctx_->arg_.type_, ls_handle_.get_ls(), &ctx_->ha_table_info_mgr_, ha_tablets_builder_))) { - LOG_WARN("failed to init ha tabelts builder", K(ret), KPC(ctx_)); + LOG_WARN("failed to init ha tablets builder", K(ret), KPC(ctx_)); } else { is_inited_ = true; LOG_INFO("succeed init sys tablets migration task", "ls id", ctx_->arg_.ls_id_, @@ -1673,8 +1693,6 @@ int ObSysTabletsMigrationTask::process() LOG_WARN("sys tablets migration task do not init", K(ret)); } else if (ctx_->is_failed()) { //do nothing - } else if (OB_FAIL(create_or_update_tablets_())) { - LOG_WARN("failed to create or update tablets", K(ret), K(*ctx_)); } else if (OB_FAIL(build_tablets_sstable_info_())) { LOG_WARN("failed to build tablets sstable info", K(ret), K(*ctx_)); } else { @@ -1704,18 +1722,6 @@ int ObSysTabletsMigrationTask::process() return ret; } -int ObSysTabletsMigrationTask::create_or_update_tablets_() -{ - int ret = OB_SUCCESS; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("sys tablets migration task do not init", K(ret)); - } else if (OB_FAIL(ha_tablets_builder_.create_or_update_tablets())) { - LOG_WARN("failed to create or update tablets", K(ret), KPC(ctx_)); - } - return ret; -} - int ObSysTabletsMigrationTask::build_tablets_sstable_info_() { int ret = OB_SUCCESS; @@ -1732,14 +1738,19 @@ int ObSysTabletsMigrationTask::generate_sys_tablet_migartion_dag_() { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; - ObArray tablet_migration_dag_array; + ObArray tablet_migration_dag_array; ObTenantDagScheduler *scheduler = nullptr; ObIDagNet *dag_net = nullptr; ObSysTabletsMigrationDag *sys_tablets_migration_dag = nullptr; + ObLS *ls = nullptr; + ObIDag *parent = nullptr; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("sys tablets migration task do not init", K(ret)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); } else if (OB_ISNULL(sys_tablets_migration_dag = static_cast(this->get_dag()))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sys tablets migration dag should not be NULL", K(ret), KP(sys_tablets_migration_dag)); @@ -1749,14 +1760,21 @@ int ObSysTabletsMigrationTask::generate_sys_tablet_migartion_dag_() } else if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret)); + } else if (OB_FALSE_IT(parent = this->get_dag())) { + } else if (OB_FAIL(tablet_migration_dag_array.push_back(parent))) { + LOG_WARN("failed to push sys_tablets_migration_dag into array", K(ret), K(*ctx_)); } else { - ObIDag *parent = this->get_dag(); for (int64_t i = 0; OB_SUCC(ret) && i < ctx_->sys_tablet_id_array_.count(); ++i) { const ObTabletID &tablet_id = ctx_->sys_tablet_id_array_.at(i); ObTabletMigrationDag *tablet_migration_dag = nullptr; - if (OB_FAIL(scheduler->alloc_dag(tablet_migration_dag))) { + ObTabletHandle tablet_handle; + if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_FAIL(scheduler->alloc_dag(tablet_migration_dag))) { LOG_WARN("failed to alloc tablet migration dag ", K(ret)); - } else if (OB_FAIL(tablet_migration_dag->init(tablet_id, dag_net))) { + } else if (OB_FAIL(tablet_migration_dag_array.push_back(tablet_migration_dag))) { + LOG_WARN("failed to push tablet migration dag into array", K(ret), K(*ctx_)); + } else if (OB_FAIL(tablet_migration_dag->init(tablet_id, tablet_handle, dag_net))) { LOG_WARN("failed to init tablet migration dag", K(ret), K(*ctx_)); } else if (OB_FAIL(parent->add_child(*tablet_migration_dag))) { LOG_WARN("failed to add child dag", K(ret), K(*ctx_)); @@ -1768,30 +1786,37 @@ int ObSysTabletsMigrationTask::generate_sys_tablet_migartion_dag_() LOG_WARN("Fail to add task", K(ret)); ret = OB_EAGAIN; } - } else if (OB_FAIL(tablet_migration_dag_array.push_back(tablet_migration_dag))) { - LOG_WARN("failed to push tablet migration dag into array", K(ret), K(*ctx_)); } else { + LOG_INFO("succeed to schedule tablet migration dag", KPC(tablet_migration_dag)); parent = tablet_migration_dag; - LOG_INFO("succeed to schedule tablet migration dag", K(*tablet_migration_dag)); + tablet_migration_dag = nullptr; } - if (OB_FAIL(ret)) { - if (OB_NOT_NULL(tablet_migration_dag)) { - scheduler->free_dag(*tablet_migration_dag, sys_tablets_migration_dag); - tablet_migration_dag = nullptr; + if (OB_FAIL(ret) && OB_NOT_NULL(tablet_migration_dag)) { + // tablet_migration_dag_array is not empty. + ObIDag *last = tablet_migration_dag_array.at(tablet_migration_dag_array.count() - 1); + if (last == tablet_migration_dag) { + tablet_migration_dag_array.pop_back(); + last = tablet_migration_dag_array.at(tablet_migration_dag_array.count() - 1); } - for (int64_t i = 0; i < tablet_migration_dag_array.count(); ++i) { - ObTabletMigrationDag *dag = tablet_migration_dag_array.at(i); - if (OB_SUCCESS != (tmp_ret = scheduler->cancel_dag(dag, sys_tablets_migration_dag))) { - LOG_WARN("failed to cancel ha dag", K(tmp_ret), KPC(sys_tablets_migration_dag)); - } else { - dag = nullptr; - } - } - tablet_migration_dag_array.reset(); + scheduler->free_dag(*tablet_migration_dag, last); + tablet_migration_dag = nullptr; } } + + // Cancel all dags from back to front, except the first dag which is 'sys_tablets_migration_dag'. + if (OB_FAIL(ret)) { + // The i-th dag is the parent dag of (i+1)-th dag. + for (int64_t child_idx = tablet_migration_dag_array.count() - 1; child_idx > 0; child_idx--) { + if (OB_TMP_FAIL(scheduler->cancel_dag( + tablet_migration_dag_array.at(child_idx), + tablet_migration_dag_array.at(child_idx - 1)))) { + LOG_WARN("failed to cancel inner tablet migration dag", K(tmp_ret), K(child_idx)); + } + } + tablet_migration_dag_array.reset(); + } } return ret; } @@ -1817,7 +1842,7 @@ int ObSysTabletsMigrationTask::record_server_event_() /******************ObTabletMigrationDag*********************/ ObTabletMigrationDag::ObTabletMigrationDag() - : ObMigrationDag(ObStorageHADagType::TBALET_MIGRATION_DAG), + : ObMigrationDag(ObDagType::DAG_TYPE_TABLET_MIGRATION), is_inited_(false), ls_handle_(), copy_tablet_ctx_(), @@ -1846,9 +1871,7 @@ bool ObTabletMigrationDag::operator == (const ObIDag &other) const } else { const ObMigrationDag &other_dag = static_cast(other); ObMigrationCtx *ctx = get_migration_ctx(); - if (other_dag.get_sub_type() != sub_type_) { - is_same = false; - } else if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { + if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { if (ctx->arg_.ls_id_ != other_dag.get_migration_ctx()->arg_.ls_id_) { is_same = false; } else { @@ -1872,8 +1895,9 @@ int64_t ObTabletMigrationDag::hash() const &ctx->arg_.ls_id_, sizeof(ctx->arg_.ls_id_), hash_value); hash_value = common::murmurhash( ©_tablet_ctx_.tablet_id_, sizeof(copy_tablet_ctx_.tablet_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } @@ -1900,6 +1924,7 @@ int ObTabletMigrationDag::fill_dag_key(char *buf, const int64_t buf_len) const int ObTabletMigrationDag::init( const common::ObTabletID &tablet_id, + ObTabletHandle &tablet_handle, ObIDagNet *dag_net, ObHATabletGroupCtx *tablet_group_ctx) { @@ -1926,14 +1951,11 @@ int ObTabletMigrationDag::init( } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream should not be NULL", K(ret), K(tablet_id)); - } else if (OB_FAIL(ls->get_tablet(tablet_id, copy_tablet_ctx_.tablet_handle_, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); - //TODO(muwei.ym) here tablet may relay remove tablet log, need deal with it } else if (OB_FAIL(ctx->ha_table_info_mgr_.check_copy_tablet_exist(tablet_id, is_exist))) { LOG_WARN("failed to check copy tablet exist", K(ret), K(tablet_id)); } else if (FALSE_IT(status = is_exist ? ObCopyTabletStatus::TABLET_EXIST : ObCopyTabletStatus::TABLET_NOT_EXIST)) { } else if (FALSE_IT(copy_tablet_ctx_.tablet_id_ = tablet_id)) { + } else if (FALSE_IT(copy_tablet_ctx_.tablet_handle_ = tablet_handle)) { } else if (OB_FAIL(copy_tablet_ctx_.set_copy_tablet_status(status))) { LOG_WARN("failed to set copy tablet status", K(ret), K(status), K(tablet_id)); } else if (FALSE_IT(ha_dag_net_ctx_ = ctx)) { @@ -1965,23 +1987,25 @@ int ObTabletMigrationDag::create_first_task() return ret; } -int ObTabletMigrationDag::fill_comment(char *buf, const int64_t buf_len) const +int ObTabletMigrationDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; ObMigrationCtx *ctx = nullptr; if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("sys tablets migration dag do not init", K(ret)); + LOG_WARN("Tablet migration dag do not init", K(ret)); } else if (OB_ISNULL(ctx = get_migration_ctx())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("migration ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObTabletMigrationDag: dag_net_task_id = %s, tenant_id = %s, ls_id = %s, tablet_id = %s, migration_type = %s, " - "src = %s, dest = %s", to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), - to_cstring(copy_tablet_ctx_.tablet_id_), ObMigrationOpType::get_str(ctx->arg_.type_), - to_cstring(ctx->arg_.src_.get_server()), to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); + LOG_WARN("Tablet migration dag migration ctx should not be NULL", K(ret), KP(ctx)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(ctx->tenant_id_), ctx->arg_.ls_id_.id(), + static_cast(copy_tablet_ctx_.tablet_id_.id()), + static_cast(ctx->arg_.type_), + "dag_net_task_id", to_cstring(ctx->task_id_), + "src", to_cstring(ctx->arg_.src_.get_server()), + "dest", to_cstring(ctx->arg_.dst_.get_server())))) { + LOG_WARN("failed to fill info param", K(ret)); } return ret; } @@ -2012,6 +2036,7 @@ int ObTabletMigrationDag::generate_next_dag(share::ObIDag *&dag) ObDagId dag_id; const int64_t start_ts = ObTimeUtil::current_time(); ObMigrationCtx *ctx = nullptr; + ObLS *ls = nullptr; if (!is_inited_) { ret = OB_NOT_INIT; @@ -2028,8 +2053,12 @@ int ObTabletMigrationDag::generate_next_dag(share::ObIDag *&dag) LOG_WARN("failed to get result", K(tmp_ret), KPC(ctx)); ret = tmp_ret; } + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KPC(ctx)); } else { while (OB_SUCC(ret)) { + ObTabletHandle tablet_handle; if (OB_FAIL(tablet_group_ctx_->get_next_tablet_id(tablet_id))) { if (OB_ITER_END == ret) { //do nothing @@ -2043,19 +2072,17 @@ int ObTabletMigrationDag::generate_next_dag(share::ObIDag *&dag) } else if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret)); + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } } else if (OB_FAIL(scheduler->alloc_dag(tablet_migration_dag))) { LOG_WARN("failed to alloc tablet migration dag", K(ret)); } else { - if (OB_FAIL(tablet_migration_dag->init(tablet_id, dag_net, tablet_group_ctx_))) { - if (OB_TABLET_NOT_EXIST == ret) { - //overwrite ret - LOG_INFO("tablet is deleted, skip migration", K(tablet_id)); - scheduler->free_dag(*tablet_migration_dag); - tablet_migration_dag = nullptr; - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to init tablet migration migration dag", K(ret), K(tablet_id)); - } + if (OB_FAIL(tablet_migration_dag->init(tablet_id, tablet_handle, dag_net, tablet_group_ctx_))) { + LOG_WARN("failed to init tablet migration migration dag", K(ret), K(tablet_id)); } else if (FALSE_IT(dag_id.init(MYADDR))) { } else if (OB_FAIL(tablet_migration_dag->set_dag_id(dag_id))) { LOG_WARN("failed to set dag id", K(ret), K(tablet_id)); @@ -2077,7 +2104,7 @@ int ObTabletMigrationDag::generate_next_dag(share::ObIDag *&dag) if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; const bool need_retry = false; - if (need_set_failed_result && OB_SUCCESS != (tmp_ret = ha_dag_net_ctx_->set_result(ret, need_retry))) { + if (need_set_failed_result && OB_SUCCESS != (tmp_ret = ha_dag_net_ctx_->set_result(ret, need_retry, get_type()))) { LOG_WARN("failed to set result", K(ret), KPC(ha_dag_net_ctx_)); } } @@ -2135,8 +2162,7 @@ int ObTabletMigrationDag::inner_reset_status_for_retry() if (OB_ISNULL(ls = ls_handle_.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls should not be NULL", K(ret), K(copy_tablet_ctx_)); - } else if (OB_FAIL(ls->get_tablet(copy_tablet_ctx_.tablet_id_, copy_tablet_ctx_.tablet_handle_, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls->ha_get_tablet(copy_tablet_ctx_.tablet_id_, copy_tablet_ctx_.tablet_handle_))) { if (OB_TABLET_NOT_EXIST == ret) { ret = OB_SUCCESS; const ObCopyTabletStatus::STATUS status = ObCopyTabletStatus::TABLET_NOT_EXIST; @@ -2389,11 +2415,12 @@ int ObTabletMigrationTask::generate_physical_copy_task_( { int ret = OB_SUCCESS; ObPhysicalCopyTask *copy_task = NULL; - ObPhysicalCopyFinishTask *finish_task = NULL; + ObSSTableCopyFinishTask *finish_task = NULL; const int64_t task_idx = 0; ObLS *ls = nullptr; ObPhysicalCopyTaskInitParam init_param; ObTabletMigrationDag *tablet_migration_dag = nullptr; + bool is_tablet_exist = true; if (!is_inited_) { ret = OB_NOT_INIT; @@ -2406,52 +2433,60 @@ int ObTabletMigrationTask::generate_physical_copy_task_( } else if (FALSE_IT(tablet_migration_dag = static_cast(dag_))) { } else if (OB_FAIL(tablet_migration_dag->get_ls(ls))) { LOG_WARN("failed to get ls", K(ret), KPC(ctx_)); - } else if (FALSE_IT(init_param.tenant_id_ = ctx_->tenant_id_)) { - } else if (FALSE_IT(init_param.ls_id_ = ctx_->arg_.ls_id_)) { - } else if (FALSE_IT(init_param.tablet_id_ = copy_tablet_ctx_->tablet_id_)) { - } else if (FALSE_IT(init_param.src_info_ = src_info)) { - } else if (FALSE_IT(init_param.tablet_copy_finish_task_ = tablet_copy_finish_task)) { - } else if (FALSE_IT(init_param.ls_ = ls)) { - } else if (FALSE_IT(init_param.need_check_seq_ = true)) { - } else if (FALSE_IT(init_param.ls_rebuild_seq_ = ctx_->local_rebuild_seq_)) { - } else if (OB_FAIL(ctx_->ha_table_info_mgr_.get_table_info(copy_tablet_ctx_->tablet_id_, copy_table_key, init_param.sstable_param_))) { - LOG_WARN("failed to get table info", K(ret), KPC(copy_tablet_ctx_), K(copy_table_key)); - } else if (OB_FAIL(copy_sstable_info_mgr_.get_copy_sstable_maro_range_info(copy_table_key, init_param.sstable_macro_range_info_))) { - LOG_WARN("failed to get copy sstable macro range info", K(ret), K(copy_table_key)); - } else if (!init_param.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("physical copy task init param not valid", K(ret), K(init_param), KPC(ctx_)); - } else if (OB_FAIL(dag_->alloc_task(finish_task))) { - LOG_WARN("failed to alloc finish task", K(ret)); - } else if (OB_FAIL(finish_task->init(init_param))) { - LOG_WARN("failed to init finish task", K(ret), K(copy_table_key), K(*ctx_)); - } else if (OB_FAIL(finish_task->add_child(*child_task))) { - LOG_WARN("failed to add child", K(ret)); - } else if (init_param.sstable_macro_range_info_.copy_macro_range_array_.count() > 0) { - // parent->copy->finish->child - if (OB_FAIL(dag_->alloc_task(copy_task))) { - LOG_WARN("failed to alloc copy task", K(ret)); - } else if (OB_FAIL(copy_task->init(finish_task->get_copy_ctx(), finish_task))) { - LOG_WARN("failed to init copy task", K(ret)); - } else if (OB_FAIL(parent_task->add_child(*copy_task))) { - LOG_WARN("failed to add child copy task", K(ret)); - } else if (OB_FAIL(copy_task->add_child(*finish_task))) { - LOG_WARN("failed to add child finish task", K(ret)); - } else if (OB_FAIL(dag_->add_task(*copy_task))) { - LOG_WARN("failed to add copy task to dag", K(ret)); + } else if (OB_FAIL(copy_sstable_info_mgr_.check_src_tablet_exist(is_tablet_exist))) { + LOG_WARN("failed to check src tablet exist", K(ret), K(copy_table_key)); + } else if (!is_tablet_exist) { + if (OB_FAIL(tablet_copy_finish_task->set_tablet_status(ObCopyTabletStatus::TABLET_NOT_EXIST))) { + LOG_WARN("failed to set tablet status", K(ret), K(copy_table_key), KPC(copy_tablet_ctx_)); } } else { - if (OB_FAIL(parent_task->add_child(*finish_task))) { - LOG_WARN("failed to add child finish_task for parent", K(ret)); - } - } - - if (OB_SUCC(ret)) { - if (OB_FAIL(dag_->add_task(*finish_task))) { - LOG_WARN("failed to add finish task to dag", K(ret)); + if (FALSE_IT(init_param.tenant_id_ = ctx_->tenant_id_)) { + } else if (FALSE_IT(init_param.ls_id_ = ctx_->arg_.ls_id_)) { + } else if (FALSE_IT(init_param.tablet_id_ = copy_tablet_ctx_->tablet_id_)) { + } else if (FALSE_IT(init_param.src_info_ = src_info)) { + } else if (FALSE_IT(init_param.tablet_copy_finish_task_ = tablet_copy_finish_task)) { + } else if (FALSE_IT(init_param.ls_ = ls)) { + } else if (FALSE_IT(init_param.need_check_seq_ = true)) { + } else if (FALSE_IT(init_param.ls_rebuild_seq_ = ctx_->local_rebuild_seq_)) { + } else if (OB_FAIL(ctx_->ha_table_info_mgr_.get_table_info(copy_tablet_ctx_->tablet_id_, copy_table_key, init_param.sstable_param_))) { + LOG_WARN("failed to get table info", K(ret), KPC(copy_tablet_ctx_), K(copy_table_key)); + } else if (OB_FAIL(copy_sstable_info_mgr_.get_copy_sstable_maro_range_info(copy_table_key, init_param.sstable_macro_range_info_))) { + LOG_WARN("failed to get copy sstable macro range info", K(ret), K(copy_table_key)); + } else if (!init_param.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("physical copy task init param not valid", K(ret), K(init_param), KPC(ctx_)); + } else if (OB_FAIL(dag_->alloc_task(finish_task))) { + LOG_WARN("failed to alloc finish task", K(ret)); + } else if (OB_FAIL(finish_task->init(init_param))) { + LOG_WARN("failed to init finish task", K(ret), K(copy_table_key), K(*ctx_)); + } else if (OB_FAIL(finish_task->add_child(*child_task))) { + LOG_WARN("failed to add child", K(ret)); + } else if (init_param.sstable_macro_range_info_.copy_macro_range_array_.count() > 0) { + // parent->copy->finish->child + if (OB_FAIL(dag_->alloc_task(copy_task))) { + LOG_WARN("failed to alloc copy task", K(ret)); + } else if (OB_FAIL(copy_task->init(finish_task->get_copy_ctx(), finish_task))) { + LOG_WARN("failed to init copy task", K(ret)); + } else if (OB_FAIL(parent_task->add_child(*copy_task))) { + LOG_WARN("failed to add child copy task", K(ret)); + } else if (OB_FAIL(copy_task->add_child(*finish_task))) { + LOG_WARN("failed to add child finish task", K(ret)); + } else if (OB_FAIL(dag_->add_task(*copy_task))) { + LOG_WARN("failed to add copy task to dag", K(ret)); + } } else { - FLOG_INFO("succeed to generate physical copy task", - K(copy_table_key), K(src_info), KPC(copy_task), KPC(finish_task)); + if (OB_FAIL(parent_task->add_child(*finish_task))) { + LOG_WARN("failed to add child finish_task for parent", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(dag_->add_task(*finish_task))) { + LOG_WARN("failed to add finish task to dag", K(ret)); + } else { + FLOG_INFO("succeed to generate physical copy task", + K(copy_table_key), K(src_info), KPC(copy_task), KPC(finish_task)); + } } } return ret; @@ -2571,6 +2606,8 @@ int ObTabletMigrationTask::generate_tablet_copy_finish_task_( LOG_WARN("failed to get src tablet meta", K(ret), KPC(copy_tablet_ctx_)); } else if (OB_FAIL(tablet_copy_finish_task->init(copy_tablet_ctx_->tablet_id_, ls, reporter, restore_action, src_tablet_meta))) { LOG_WARN("failed to init tablet copy finish task", K(ret), KPC(ctx_), KPC(copy_tablet_ctx_)); + } else { + LOG_INFO("generate tablet copy finish task", "ls_id", ls->get_ls_id().id(), "tablet_id", copy_tablet_ctx_->tablet_id_); } return ret; } @@ -2578,17 +2615,34 @@ int ObTabletMigrationTask::generate_tablet_copy_finish_task_( int ObTabletMigrationTask::record_server_event_(const int64_t cost_us, const int64_t result) { int ret = OB_SUCCESS; + const ObMigrationTabletParam *src_tablet_meta = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + ObLS *ls = nullptr; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletMigrationDag *tablet_migration_dag = nullptr; if (OB_ISNULL(ctx_) || OB_ISNULL(copy_tablet_ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ctx should not be null", K(ret), KPC_(ctx), KPC_(copy_tablet_ctx)); + } else if (FALSE_IT(tablet_migration_dag = static_cast(dag_))) { + } else if (OB_FAIL(tablet_migration_dag->get_ls(ls))) { + LOG_WARN("failed to get ls", K(ret), KPC(ctx_)); + } else if (OB_FAIL(ls->ha_get_tablet(copy_tablet_ctx_->tablet_id_, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet)); } else { + const char *tablet_status = ObTabletStatus::get_str(user_data.tablet_status_); SERVER_EVENT_ADD("storage_ha", "tablet_migration_task", "tenant_id", ctx_->tenant_id_, "ls_id", ctx_->arg_.ls_id_.id(), "src", ctx_->arg_.src_.get_server(), "dst", ctx_->arg_.dst_.get_server(), "tablet_id", copy_tablet_ctx_->tablet_id_.id(), - "cost_us", cost_us, ObMigrationOpType::get_str(ctx_->arg_.type_)); + "tablet_status", tablet_status); } return ret; } @@ -2625,7 +2679,7 @@ int ObTabletMigrationTask::try_update_tablet_() } else if (OB_FAIL(ObLSMigrationUtils::init_ha_tablets_builder( ctx_->tenant_id_, tablet_id_array, ctx_->minor_src_, ctx_->local_rebuild_seq_, ctx_->arg_.type_, ls, &ctx_->ha_table_info_mgr_, ha_tablets_builder))) { - LOG_WARN("failed to init ha tabelts builder", K(ret), KPC(ctx_)); + LOG_WARN("failed to init ha tablets builder", K(ret), KPC(ctx_)); } else { //Here inner tablet copy data before clog replay, and now just create a new tablet to replace it. //Data tablet copy data during clog replay, so the data tablet can only be updated. @@ -2731,7 +2785,7 @@ int ObTabletMigrationTask::check_tablet_replica_validity_(const common::ObTablet /******************ObDataTabletsMigrationDag*********************/ ObDataTabletsMigrationDag::ObDataTabletsMigrationDag() - : ObMigrationDag(ObStorageHADagType::DATA_TABLETS_MIGRATION_DAG), + : ObMigrationDag(ObDagType::DAG_TYPE_DATA_TABLETS_MIGRATION), is_inited_(false) { } @@ -2750,9 +2804,7 @@ bool ObDataTabletsMigrationDag::operator == (const ObIDag &other) const } else { const ObMigrationDag &other_dag = static_cast(other); ObMigrationCtx *ctx = get_migration_ctx(); - if (other_dag.get_sub_type() != sub_type_) { - is_same = false; - } else if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { + if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { if (ctx->arg_.ls_id_ != other_dag.get_migration_ctx()->arg_.ls_id_) { is_same = false; } @@ -2769,8 +2821,9 @@ int64_t ObDataTabletsMigrationDag::hash() const if (NULL != ctx) { hash_value = common::murmurhash( &ctx->arg_.ls_id_, sizeof(ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } @@ -2839,26 +2892,6 @@ int ObDataTabletsMigrationDag::create_first_task() return ret; } -int ObDataTabletsMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("sys tablets migration dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_migration_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("migration ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObDataTabletsMigrationDag: dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, src = %s, dest = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), ObMigrationOpType::get_str(ctx->arg_.type_), - to_cstring(ctx->arg_.src_.get_server()), to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObDataTabletsMigrationTask*********************/ ObDataTabletsMigrationTask::ObDataTabletsMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -2901,7 +2934,7 @@ int ObDataTabletsMigrationTask::init() LOG_WARN("data tablets migration dag get unexpected child node", K(ret), K(child_node_array)); } else { ObMigrationDag *child_dag = static_cast(child_node_array.at(0)); - if (ObStorageHADagType::FINISH_MIGRATION_DAG != child_dag->get_sub_type()) { + if (ObDagType::DAG_TYPE_MIGRATION_FINISH != child_dag->get_type()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("migrtion dag type is unexpected", K(ret), K(*child_dag)); } else { @@ -2916,7 +2949,7 @@ int ObDataTabletsMigrationTask::init() } else if (OB_FAIL(ObLSMigrationUtils::init_ha_tablets_builder( ctx_->tenant_id_, ctx_->data_tablet_id_array_, ctx_->minor_src_, ctx_->local_rebuild_seq_, ctx_->arg_.type_, ls_handle_.get_ls(), &ctx_->ha_table_info_mgr_, ha_tablets_builder_))) { - LOG_WARN("failed to init ha tabelts builder", K(ret), KPC(ctx_)); + LOG_WARN("failed to init ha tablets builder", K(ret), KPC(ctx_)); } else { is_inited_ = true; LOG_INFO("succeed init data tablets migration task", "ls id", ctx_->arg_.ls_id_, @@ -2945,12 +2978,10 @@ int ObDataTabletsMigrationTask::process() LOG_WARN("data tablets migration task do not init", K(ret)); } else if (ctx_->is_failed()) { //do nothing - } else if (OB_FAIL(create_or_update_tablets_())) { - LOG_WARN("failed to create or update tablets", K(ret), K(*ctx_)); } else if (OB_FAIL(try_remove_unneeded_tablets_())) { LOG_WARN("failed to try remove unneeded tablets", K(ret), KPC(ctx_)); } else if (OB_FAIL(ls_online_())) { - LOG_WARN("failed to start realy log", K(ret), K(*ctx_)); + LOG_WARN("failed to start replay log", K(ret), K(*ctx_)); } else if (OB_FAIL(build_tablet_group_info_())) { LOG_WARN("failed to build tablet group info", K(ret), KPC(ctx_)); } else { @@ -2996,24 +3027,6 @@ int ObDataTabletsMigrationTask::process() return ret; } -int ObDataTabletsMigrationTask::create_or_update_tablets_() -{ - int ret = OB_SUCCESS; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("data tablets migration task do not init", K(ret)); - } else if (ctx_->data_tablet_id_array_.empty()) { - LOG_INFO("data tablet is is empty, no need create or update", KPC(ctx_)); - } else { - DEBUG_SYNC(BEFORE_MIGRATION_FETCH_TABLET_INFO); - if (OB_FAIL(ha_tablets_builder_.create_or_update_tablets())) { - LOG_WARN("failed to create or update tablets", K(ret), KPC(ctx_)); - } - } - return ret; -} - int ObDataTabletsMigrationTask::ls_online_() { int ret = OB_SUCCESS; @@ -3077,7 +3090,7 @@ int ObDataTabletsMigrationTask::build_tablet_group_info_() } else { ctx_->tablet_group_mgr_.reuse(); const hash::ObHashMap &tablet_simple_info_map = - ha_tablets_builder_.get_tablets_simple_info_map(); + ctx_->tablet_simple_info_map_; for (int64_t i = 0; OB_SUCC(ret) && i < ctx_->data_tablet_id_array_.count(); ++i) { tablet_simple_info.reset(); @@ -3261,8 +3274,6 @@ int ObDataTabletsMigrationTask::try_remove_unneeded_tablets_() ctx_->sys_tablet_id_array_.count() + ctx_->data_tablet_id_array_.count()))) { } else if (OB_FAIL(tablet_id_set.create(bucket_num))) { LOG_WARN("failed to create tablet id set", K(ret), KPC(ctx_)); - } else if (OB_FAIL(ha_tablets_builder_.get_src_deleted_tablet_list(tablet_id_array))) { - LOG_WARN("failed to get src deleted tablet list", K(ret), KPC(ctx_)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < ctx_->sys_tablet_id_array_.count(); ++i) { const ObTabletID &tablet_id = ctx_->sys_tablet_id_array_.at(i); @@ -3361,7 +3372,7 @@ int ObDataTabletsMigrationTask::record_server_event_() /******************ObTabletGroupMigrationDag*********************/ ObTabletGroupMigrationDag::ObTabletGroupMigrationDag() - : ObMigrationDag(ObStorageHADagType::TABLET_GROUP_MIGRATION_DAG), + : ObMigrationDag(ObDagType::DAG_TYPE_TABLET_GROUP_MIGRATION), is_inited_(false), tablet_id_array_(), finish_dag_(nullptr), @@ -3383,9 +3394,7 @@ bool ObTabletGroupMigrationDag::operator == (const ObIDag &other) const } else { const ObMigrationDag &other_dag = static_cast(other); ObMigrationCtx *ctx = get_migration_ctx(); - if (other_dag.get_sub_type() != sub_type_) { - is_same = false; - } else if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { + if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { if (ctx->arg_.ls_id_ != other_dag.get_migration_ctx()->arg_.ls_id_) { is_same = false; } else { @@ -3412,8 +3421,9 @@ int64_t ObTabletGroupMigrationDag::hash() const if (NULL != ctx) { hash_value = common::murmurhash( &ctx->arg_.ls_id_, sizeof(ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); for (int64_t i = 0; i < tablet_id_array_.count(); ++i) { hash_value = common::murmurhash( &tablet_id_array_.at(i), sizeof(tablet_id_array_.at(i)), hash_value); @@ -3494,27 +3504,6 @@ int ObTabletGroupMigrationDag::create_first_task() return ret; } -int ObTabletGroupMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("tablet group migration dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_migration_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("migration ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObTabletGroupMigrationDag : dag_net_task_id = %s, tenant_id = %s, ls_id = %s, first_tablet_id = %s, migration_type = %s, " - "src = %s, dest = %s", to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), - to_cstring(tablet_id_array_.at(0)), ObMigrationOpType::get_str(ctx->arg_.type_), - to_cstring(ctx->arg_.src_.get_server()), to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - int ObTabletGroupMigrationDag::generate_next_dag(share::ObIDag *&dag) { int ret = OB_SUCCESS; @@ -3529,7 +3518,6 @@ int ObTabletGroupMigrationDag::generate_next_dag(share::ObIDag *&dag) ObArray tablet_id_array; ObDagId dag_id; const int64_t start_ts = ObTimeUtil::current_time(); - if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet group migration dag do not init", K(ret)); @@ -3577,7 +3565,7 @@ int ObTabletGroupMigrationDag::generate_next_dag(share::ObIDag *&dag) if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; const bool need_retry = false; - if (need_set_failed_result && OB_SUCCESS != (tmp_ret = ha_dag_net_ctx_->set_result(ret, need_retry))) { + if (need_set_failed_result && OB_SUCCESS != (tmp_ret = ha_dag_net_ctx_->set_result(ret, need_retry, get_type()))) { LOG_WARN("failed to set result", K(ret), KPC(ha_dag_net_ctx_)); } } @@ -3590,6 +3578,29 @@ int ObTabletGroupMigrationDag::generate_next_dag(share::ObIDag *&dag) return ret; } + +int ObTabletGroupMigrationDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + ObMigrationCtx *ctx = nullptr; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet group migration dag do not init", K(ret)); + } else if (OB_ISNULL(ctx = get_migration_ctx())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet group migration dag migration ctx should not be NULL", K(ret), KP(ctx)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(ctx->tenant_id_), ctx->arg_.ls_id_.id(), + static_cast(tablet_id_array_.at(0).id()), + static_cast(ctx->arg_.type_), + "dag_net_task_id", to_cstring(ctx->task_id_), + "src", to_cstring(ctx->arg_.src_.get_server()), + "dest", to_cstring(ctx->arg_.dst_.get_server())))) { + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} + /******************ObTabletGroupMigrationTask*********************/ ObTabletGroupMigrationTask::ObTabletGroupMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -3648,7 +3659,7 @@ int ObTabletGroupMigrationTask::init( } else if (OB_FAIL(ObLSMigrationUtils::init_ha_tablets_builder( ctx_->tenant_id_, tablet_id_array, ctx_->minor_src_, ctx_->local_rebuild_seq_, ctx_->arg_.type_, ls_handle_.get_ls(), &ctx_->ha_table_info_mgr_, ha_tablets_builder_))) { - LOG_WARN("failed to init ha tabelts builder", K(ret), KPC(ctx_)); + LOG_WARN("failed to init ha tablets builder", K(ret), KPC(ctx_)); } else { is_inited_ = true; LOG_INFO("succeed init tablet group migration task", "ls id", ctx_->arg_.ls_id_, @@ -3709,6 +3720,7 @@ int ObTabletGroupMigrationTask::generate_tablet_migration_dag_() ObIDagNet *dag_net = nullptr; ObTabletGroupMigrationDag *tablet_group_migration_dag = nullptr; ObTabletMigrationDag *tablet_migration_dag = nullptr; + ObLS *ls = nullptr; DEBUG_SYNC(BEFORE_TABLET_MIGRATION_GENERATE_NEXT_DAG); @@ -3724,11 +3736,15 @@ int ObTabletGroupMigrationTask::generate_tablet_migration_dag_() } else if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); } else { ObIDag *parent = this->get_dag(); ObTabletID tablet_id; //generate next_day can execute successful generation only if the first dag is successfully generated while (OB_SUCC(ret)) { + ObTabletHandle tablet_handle; if (OB_FAIL(tablet_group_ctx_->get_next_tablet_id(tablet_id))) { if (OB_ITER_END == ret) { ret = OB_SUCCESS; @@ -3736,18 +3752,16 @@ int ObTabletGroupMigrationTask::generate_tablet_migration_dag_() } else { LOG_WARN("failed to get next tablet id", K(ret), KPC(ctx_)); } - } else if (OB_FAIL(scheduler->alloc_dag(tablet_migration_dag))) { - LOG_WARN("failed to alloc tablet migration dag ", K(ret)); - } else if (OB_FAIL(tablet_migration_dag->init(tablet_id, dag_net, tablet_group_ctx_))) { + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { if (OB_TABLET_NOT_EXIST == ret) { - //overwrite ret - LOG_INFO("tablet is deleted, skip migration", K(tablet_id)); - scheduler->free_dag(*tablet_migration_dag); - tablet_migration_dag = nullptr; ret = OB_SUCCESS; } else { - LOG_WARN("failed to init tablet migration migration dag", K(ret), K(*ctx_)); + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); } + } else if (OB_FAIL(scheduler->alloc_dag(tablet_migration_dag))) { + LOG_WARN("failed to alloc tablet migration dag ", K(ret)); + } else if (OB_FAIL(tablet_migration_dag->init(tablet_id, tablet_handle, dag_net, tablet_group_ctx_))) { + LOG_WARN("failed to init tablet migration migration dag", K(ret), K(*ctx_)); } else if (OB_FAIL(dag_net->add_dag_into_dag_net(*tablet_migration_dag))) { LOG_WARN("failed to add dag into dag net", K(ret), K(*ctx_)); } else if (OB_FAIL(parent->add_child_without_inheritance(*tablet_migration_dag))) { @@ -3763,7 +3777,7 @@ int ObTabletGroupMigrationTask::generate_tablet_migration_dag_() ret = OB_EAGAIN; } } else { - LOG_INFO("succeed to schedule tablet migration dag", K(*tablet_migration_dag)); + LOG_INFO("succeed to schedule tablet migration dag", K(*tablet_migration_dag), K(tablet_id)); break; } } @@ -3867,7 +3881,7 @@ int ObTabletGroupMigrationTask::record_server_event_() /******************ObMigrationFinishDag*********************/ ObMigrationFinishDag::ObMigrationFinishDag() - : ObMigrationDag(ObStorageHADagType::FINISH_MIGRATION_DAG), + : ObMigrationDag(ObDagType::DAG_TYPE_MIGRATION_FINISH), is_inited_(false) { } @@ -3886,9 +3900,7 @@ bool ObMigrationFinishDag::operator == (const ObIDag &other) const } else { const ObMigrationDag &other_dag = static_cast(other); ObMigrationCtx *ctx = get_migration_ctx(); - if (other_dag.get_sub_type() != sub_type_) { - is_same = false; - } else if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { + if (NULL != ctx && NULL != other_dag.get_migration_ctx()) { if (ctx->arg_.ls_id_ != other_dag.get_migration_ctx()->arg_.ls_id_) { is_same = false; } @@ -3905,8 +3917,9 @@ int64_t ObMigrationFinishDag::hash() const if (NULL != ctx) { hash_value = common::murmurhash( &ctx->arg_.ls_id_, sizeof(ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } @@ -3974,26 +3987,6 @@ int ObMigrationFinishDag::create_first_task() return ret; } -int ObMigrationFinishDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("migration finish dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_migration_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("migration ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObMigrationFinishDag: dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, src = %s, dest = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), ObMigrationOpType::get_str(ctx->arg_.type_), - to_cstring(ctx->arg_.src_.get_server()), to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObMigrationFinishTask*********************/ ObMigrationFinishTask::ObMigrationFinishTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -4054,7 +4047,6 @@ int ObMigrationFinishTask::process() } } } else { - //TODO(muwei.ym) //1. deal with error condition, need retry } if (OB_SUCCESS != (tmp_ret = record_server_event_())) { LOG_WARN("failed to record server event", K(tmp_ret), K(ret)); diff --git a/src/storage/high_availability/ob_ls_migration.h b/src/storage/high_availability/ob_ls_migration.h index 4419ec6ab..4d2b78c3c 100644 --- a/src/storage/high_availability/ob_ls_migration.h +++ b/src/storage/high_availability/ob_ls_migration.h @@ -43,7 +43,8 @@ public: void reset(); void reuse(); - +public: + typedef hash::ObHashMap CopyTabletSimpleInfoMap; public: uint64_t tenant_id_; ObMigrationOpArg arg_; @@ -61,6 +62,7 @@ public: ObStorageHATableInfoMgr ha_table_info_mgr_; ObHATabletGroupMgr tablet_group_mgr_; int64_t check_tablet_info_cost_time_; + CopyTabletSimpleInfoMap tablet_simple_info_map_; INHERIT_TO_STRING_KV( "ObIHADagNetCtx", ObIHADagNetCtx, @@ -158,8 +160,9 @@ private: class ObMigrationDag : public ObStorageHADag { public: - explicit ObMigrationDag(const ObStorageHADagType sub_type); + explicit ObMigrationDag(const share::ObDagType::ObDagTypeEnum &dag_type); virtual ~ObMigrationDag(); + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; ObMigrationCtx *get_migration_ctx() const { return static_cast(ha_dag_net_ctx_); } INHERIT_TO_STRING_KV("ObStorageHADag", ObStorageHADag, KP(this)); @@ -175,7 +178,6 @@ public: virtual int64_t hash() const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObMigrationDag", ObMigrationDag, KP(this)); @@ -214,7 +216,6 @@ public: virtual int64_t hash() const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObMigrationDag", ObMigrationDag, KP(this)); @@ -243,7 +244,9 @@ private: int try_remove_member_list_(); int get_tablet_id_array_(common::ObIArray &tablet_id_array); int check_ls_need_copy_data_(bool &need_copy); - int deal_local_restore_ls_(bool &need_generate_dag); + int check_before_ls_migrate_(const ObLSMeta &ls_meta); + int build_ls_(); + int create_all_tablets_(ObCopyLSViewInfoObReader *ob_reader); int record_server_event_(); private: @@ -264,7 +267,6 @@ public: virtual int64_t hash() const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObMigrationDag", ObMigrationDag, KP(this)); @@ -282,7 +284,6 @@ public: virtual int process() override; VIRTUAL_TO_STRING_KV(K("ObSysTabletsMigrationTask"), KP(this), KPC(ctx_)); private: - int create_or_update_tablets_(); int build_tablets_sstable_info_(); int generate_sys_tablet_migartion_dag_(); int record_server_event_(); @@ -307,12 +308,12 @@ public: virtual int64_t hash() const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; virtual int inner_reset_status_for_retry() override; virtual int generate_next_dag(share::ObIDag *&dag); - + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; int init( const common::ObTabletID &tablet_id, + ObTabletHandle &tablet_handle, share::ObIDagNet *dag_net, ObHATabletGroupCtx *tablet_group_ctx = nullptr); int get_ls(ObLS *&ls); @@ -391,7 +392,6 @@ public: virtual int64_t hash() const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObMigrationDag", ObMigrationDag, KP(this)); @@ -410,7 +410,6 @@ public: virtual int process() override; VIRTUAL_TO_STRING_KV(K("ObDataTabletsMigrationTask"), KP(this), KPC(ctx_)); private: - int create_or_update_tablets_(); int ls_online_(); int generate_tablet_group_migration_dag_(); int generate_tablet_group_dag_( @@ -445,9 +444,8 @@ public: virtual int64_t hash() const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; virtual int generate_next_dag(share::ObIDag *&dag); - + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; int init( const common::ObIArray &tablet_id_array, share::ObIDagNet *dag_net, @@ -504,7 +502,6 @@ public: virtual int64_t hash() const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObMigrationDag", ObMigrationDag, KP(this)); diff --git a/src/storage/high_availability/ob_ls_migration_handler.cpp b/src/storage/high_availability/ob_ls_migration_handler.cpp old mode 100644 new mode 100755 index dd2b871d2..616aa3e03 --- a/src/storage/high_availability/ob_ls_migration_handler.cpp +++ b/src/storage/high_availability/ob_ls_migration_handler.cpp @@ -18,6 +18,7 @@ #include "ob_storage_ha_service.h" #include "share/ls/ob_ls_table_operator.h" #include "observer/ob_server_event_history_table_operator.h" +#include "ob_rebuild_service.h" #include "observer/omt/ob_tenant.h" namespace oceanbase @@ -562,56 +563,35 @@ int ObLSMigrationHandler::do_init_status_() LOG_WARN("failed to get migration status", K(ret), KPC(ls_)); } else if (OB_FAIL(check_task_list_empty_(is_empty))) { LOG_WARN("failed to check task list empty", K(ret), KPC(ls_)); - } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE == migration_status) { - //do nothing - } else if (ObMigrationStatus::OB_MIGRATION_STATUS_ADD_FAIL == migration_status - || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_FAIL == migration_status) { - if (is_empty) { + } else if (is_empty) { + if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD == migration_status) { //do nothing - } else { + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_ADD_FAIL != migration_status + && ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_FAIL != migration_status) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls migration handler in init status but ls migration status is in failed status", K(ret), K(is_empty), K(migration_status), KPC(ls_)); } } else { - if (ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD == migration_status) { - new_status = ObLSMigrationHandlerStatus::PREPARE_LS; - if (!is_empty) { - } else { - if (OB_FAIL(build_rebuild_task_())) { - LOG_WARN("failed to build rebuild task", K(ret), KPC(ls_)); - can_switch_next_stage = false; - reuse_(); - } else { - is_empty = false; - } - } - } else if (is_empty) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is in migration but do not has task", K(ret), K(migration_status), KPC(ls_)); + new_status = ObLSMigrationHandlerStatus::PREPARE_LS; + ObLSMigrationTask task; + if (OB_FAIL(check_before_do_task_())) { + LOG_WARN("failed to check before do task", K(ret), KPC(ls_)); + } else if (OB_FAIL(change_status_(new_status))) { + LOG_WARN("failed to change status", K(ret), K(new_status), KPC(ls_)); + } else if (OB_FAIL(get_ls_migration_task_(task))) { + LOG_WARN("failed to get ls migration task", K(ret), KPC(ls_)); } else { - new_status = ObLSMigrationHandlerStatus::PREPARE_LS; - } - - if (OB_SUCC(ret)) { - ObLSMigrationTask task; - if (OB_FAIL(check_before_do_task_())) { - LOG_WARN("failed to check before do task", K(ret), KPC(ls_)); - } else if (OB_FAIL(change_status_(new_status))) { - LOG_WARN("failed to change status", K(ret), K(new_status), KPC(ls_)); - } else if (OB_FAIL(get_ls_migration_task_(task))) { - LOG_WARN("failed to get ls migration task", K(ret), KPC(ls_)); - } else { - SERVER_EVENT_ADD("storage_ha", "ls_ha_start", - "tenant_id", ls_->get_tenant_id(), - "ls_id", ls_->get_ls_id().id(), - "src", task.arg_.data_src_.get_server(), - "dst", task.arg_.dst_.get_server(), - "task_id", task.task_id_, - "is_failed", OB_SUCCESS, - ObMigrationOpType::get_str(task.arg_.type_)); - wakeup_(); - } + SERVER_EVENT_ADD("storage_ha", "ls_ha_start", + "tenant_id", ls_->get_tenant_id(), + "ls_id", ls_->get_ls_id().id(), + "src", task.arg_.data_src_.get_server(), + "dst", task.arg_.dst_.get_server(), + "task_id", task.task_id_, + "is_failed", OB_SUCCESS, + ObMigrationOpType::get_str(task.arg_.type_)); + wakeup_(); } } } @@ -729,7 +709,6 @@ int ObLSMigrationHandler::do_finish_status_() return ret; } - int ObLSMigrationHandler::generate_build_ls_dag_net_() { int ret = OB_SUCCESS; @@ -743,20 +722,12 @@ int ObLSMigrationHandler::generate_build_ls_dag_net_() } else if (!ls_migration_task.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls migration task is not valid", K(ret), K(ls_migration_task), KPC(ls_)); - } else if (OB_FAIL(check_migration_concurrency_limit_())) { - LOG_WARN("failed to check migration concurrency limit", K(ret), K(ls_migration_task), KPC(ls_)); } else if (OB_FAIL(schedule_build_ls_dag_net_(ls_migration_task))) { LOG_WARN("failed to schedule build ls dag net", K(ret), K(ls_migration_task), KPC(ls_)); } return ret; } -int ObLSMigrationHandler::check_migration_concurrency_limit_() -{ - // FIXME: @muwei.ym, remove this functions - return OB_SUCCESS; -} - int ObLSMigrationHandler::schedule_build_ls_dag_net_( const ObLSMigrationTask &task) { @@ -769,7 +740,6 @@ int ObLSMigrationHandler::schedule_build_ls_dag_net_( LOG_WARN("schedule build ls dag net get invalid argument", K(ret), K(task)); } else { ObTenantDagScheduler *scheduler = nullptr; - ObMigrationDagNet *migration_dag_net = nullptr; ObMigrationDagNetInitParam param; param.arg_ = task.arg_; param.task_id_ = task.task_id_; @@ -781,10 +751,10 @@ int ObLSMigrationHandler::schedule_build_ls_dag_net_( if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret), KP(scheduler)); - } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m, migration_dag_net))) { + } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m))) { LOG_WARN("failed to create and add migration dag net", K(ret), K(task), KPC(ls_)); } else { - LOG_INFO("success to create migration dag net", K(ret), K(task), KP(migration_dag_net)); + LOG_INFO("success to create migration dag net", K(ret), K(task)); } } return ret; @@ -803,8 +773,6 @@ int ObLSMigrationHandler::generate_prepare_ls_dag_net_() } else if (!ls_migration_task.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls migration task is not valid", K(ret), K(ls_migration_task), KPC(ls_)); - } else if (OB_FAIL(check_migration_concurrency_limit_())) { - LOG_WARN("failed to check migration concurrency limit", K(ret), K(ls_migration_task), KPC(ls_)); } else if (OB_FAIL(schedule_prepare_ls_dag_net_(ls_migration_task))) { LOG_WARN("failed to schedule prepare ls dag net", K(ret), K(ls_migration_task), KPC(ls_)); } @@ -823,7 +791,6 @@ int ObLSMigrationHandler::schedule_prepare_ls_dag_net_( LOG_WARN("schedule prepare ls dag net get invalid argument", K(ret), K(task)); } else { ObTenantDagScheduler *scheduler = nullptr; - ObLSPrepareMigrationDagNet *ls_prepare_migration_dag_net = nullptr; ObLSPrepareMigrationParam param; param.arg_ = task.arg_; param.task_id_ = task.task_id_; @@ -831,10 +798,10 @@ int ObLSMigrationHandler::schedule_prepare_ls_dag_net_( if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret), KP(scheduler)); - } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m, ls_prepare_migration_dag_net))) { + } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m))) { LOG_WARN("failed to create and add migration dag net", K(ret), K(task), KPC(ls_)); } else { - LOG_INFO("success to create ls prepare migration dag net", K(ret), K(task), KP(ls_prepare_migration_dag_net)); + LOG_INFO("success to create ls prepare migration dag net", K(ret), K(task)); } } return ret; @@ -853,8 +820,6 @@ int ObLSMigrationHandler::generate_complete_ls_dag_net_() } else if (!ls_migration_task.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls migration task is not valid", K(ret), K(ls_migration_task), KPC(ls_)); - } else if (OB_FAIL(check_migration_concurrency_limit_())) { - LOG_WARN("failed to check migration concurrency limit", K(ret), K(ls_migration_task), KPC(ls_)); } else if (OB_FAIL(schedule_complete_ls_dag_net_(ls_migration_task))) { LOG_WARN("failed to schedule complete ls dag net", K(ret), K(ls_migration_task), KPC(ls_)); } @@ -875,7 +840,6 @@ int ObLSMigrationHandler::schedule_complete_ls_dag_net_( } else { int32_t result = OB_SUCCESS; ObTenantDagScheduler *scheduler = nullptr; - ObLSCompleteMigrationDagNet *ls_complete_migration_dag_net = nullptr; ObLSCompleteMigrationParam param; param.arg_ = task.arg_; param.task_id_ = task.task_id_; @@ -887,11 +851,10 @@ int ObLSMigrationHandler::schedule_complete_ls_dag_net_( } else if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret), KP(scheduler)); - } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m, ls_complete_migration_dag_net))) { + } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m))) { LOG_WARN("failed to create and add migration dag net", K(ret), K(task), KPC(ls_)); } else { - LOG_INFO("success to create ls complete migration dag net", K(ret), K(task), - KP(ls_complete_migration_dag_net), K(param)); + LOG_INFO("success to create ls complete migration dag net", K(ret), K(task), K(param)); } } return ret; @@ -914,8 +877,8 @@ int ObLSMigrationHandler::report_result_() LOG_WARN("failed to report meta table", K(ret), K(task), KPC(ls_)); } - if (OB_SUCCESS != (tmp_ret = report_to_rs_())) { - LOG_WARN("failed to report to rs", K(ret), K(task), KPC(ls_)); + if (OB_SUCCESS != (tmp_ret = inner_report_result_(task))) { + LOG_WARN("failed to do inner report result", K(ret), K(task), KPC(ls_)); } } return ret; @@ -940,6 +903,49 @@ int ObLSMigrationHandler::report_meta_table_() return ret; } +int ObLSMigrationHandler::inner_report_result_( + const ObLSMigrationTask &task) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls migration handler do not init", K(ret)); + } else if (!task.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("inner report result get invalid argument", K(ret), K(task)); + } else if (ObMigrationOpType::REBUILD_LS_OP == task.arg_.type_) { + if (OB_FAIL(report_to_rebuild_service_())) { + LOG_WARN("failed to report to rebuild service", K(ret), K(task)); + } + } else { + if (OB_FAIL(report_to_rs_())) { + LOG_WARN("failed to report to rs", K(ret), KPC(ls_)); + } + } + return ret; +} + +int ObLSMigrationHandler::report_to_rebuild_service_() +{ + int ret = OB_SUCCESS; + ObRebuildService *rebuild_service = MTL(ObRebuildService*); + ObLSMigrationTask task; + int32_t result = OB_SUCCESS; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls migration handler do not init", K(ret)); + } else if (OB_ISNULL(rebuild_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rebuild service should not be NULL", K(ret), KP(rebuild_service)); + } else if (OB_FAIL(get_result_(result))) { + LOG_WARN("failed to get ls migration result", K(ret), KPC(ls_), K(task)); + } else if (OB_FAIL(rebuild_service->finish_rebuild_ls(ls_->get_ls_id(), result))) { + LOG_WARN("failed to finish rebuild ls", K(ret), KPC(ls_), K(result)); + } + return ret; +} + int ObLSMigrationHandler::report_to_rs_() { int ret = OB_SUCCESS; @@ -1004,7 +1010,7 @@ int ObLSMigrationHandler::check_can_skip_prepare_status_(bool &can_skip) // LOG_WARN("failed to get ls migration task", K(ret), KPC(ls_)); //} else if (ObMigrationOpType::REBUILD_LS_OP == task.arg_.type_) { // can_skip = false; - // TODO(muwei.ym) Open IT in 4.1 and the condition should change to migration status rebuild flag setted. + // TODO(muwei.ym) Open IT in 4.3 and the condition should change to migration status rebuild flag setted. } else { can_skip = true; } @@ -1078,70 +1084,6 @@ int ObLSMigrationHandler::get_ls_required_size_( return ret; } -int ObLSMigrationHandler::build_rebuild_task_() -{ - int ret = OB_SUCCESS; - const int64_t timestamp = 0; - common::ObMemberList member_list; - int64_t paxos_replica_num = 0; - ObLSInfo ls_info; - int64_t cluster_id = GCONF.cluster_id; - uint64_t tenant_id = MTL_ID(); - ObAddr leader_addr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("ls migration handler do not init", K(ret)); - } else if (OB_FAIL(ls_->get_paxos_member_list(member_list, paxos_replica_num))) { - LOG_WARN("failed to get paxos member list", K(ret), KPC(ls_)); - } else if (OB_FAIL(get_ls_info_(cluster_id, tenant_id, ls_->get_ls_id(), ls_info))) { - LOG_WARN("failed to get ls info", K(ret), K(cluster_id), K(tenant_id), KPC(ls_)); - } else { - //TODO(muwei.ym) do not use leader as src - const ObLSInfo::ReplicaArray &replica_array = ls_info.get_replicas(); - for (int64_t i = 0; OB_SUCC(ret) && i < replica_array.count(); ++i) { - const ObLSReplica &replica = replica_array.at(i); - if (replica.is_strong_leader()) { - leader_addr = replica.get_server(); - break; - } - } - } - -#ifdef ERRSIM - if (OB_SUCC(ret)) { - ret = OB_E(EventTable::EN_GENERATE_REBUILD_TASK_FAILED) OB_SUCCESS; - if (OB_FAIL(ret)) { - STORAGE_LOG(ERROR, "fake EN_GENERATE_REBUILD_TASK_FAILED", K(ret)); - } - } -#endif - - if (OB_FAIL(ret)) { - } else { - ObTaskId task_id; - task_id.init(GCONF.self_addr_); - // TODO: muwei make sure this is right - ObReplicaMember dst_replica_member(GCONF.self_addr_, timestamp, REPLICA_TYPE_FULL); - ObReplicaMember src_replica_member(leader_addr, timestamp, REPLICA_TYPE_FULL); - ObMigrationOpArg arg; - arg.cluster_id_ = GCONF.cluster_id; - arg.data_src_ = src_replica_member; - arg.dst_ = dst_replica_member; - arg.ls_id_ = ls_->get_ls_id(); - arg.priority_ = ObMigrationOpPriority::PRIO_MID; - arg.paxos_replica_number_ = paxos_replica_num; - arg.src_ = src_replica_member; - arg.type_ = ObMigrationOpType::REBUILD_LS_OP; - - if (OB_FAIL(add_ls_migration_task(task_id, arg))) { - LOG_WARN("failed to add ls migration task", K(ret), K(task_id), K(arg)); - } - } - - return ret; -} - int ObLSMigrationHandler::get_ls_info_( const int64_t cluster_id, const uint64_t tenant_id, diff --git a/src/storage/high_availability/ob_ls_migration_handler.h b/src/storage/high_availability/ob_ls_migration_handler.h index 7d0c53d4c..679a3ecd1 100644 --- a/src/storage/high_availability/ob_ls_migration_handler.h +++ b/src/storage/high_availability/ob_ls_migration_handler.h @@ -106,7 +106,6 @@ private: int do_finish_status_(); int generate_build_ls_dag_net_(); - int check_migration_concurrency_limit_(); int schedule_build_ls_dag_net_( const ObLSMigrationTask &task); int generate_prepare_ls_dag_net_(); @@ -124,8 +123,8 @@ private: int get_ls_required_size_( const ObMigrationOpArg &arg, int64_t &required_size); - - int build_rebuild_task_(); + int inner_report_result_(const ObLSMigrationTask &task); + int report_to_rebuild_service_(); int get_ls_info_( const int64_t cluster_id, const uint64_t tenant_id, diff --git a/src/storage/high_availability/ob_ls_prepare_migration.cpp b/src/storage/high_availability/ob_ls_prepare_migration.cpp old mode 100644 new mode 100755 index 70670aa1a..93de75df1 --- a/src/storage/high_availability/ob_ls_prepare_migration.cpp +++ b/src/storage/high_availability/ob_ls_prepare_migration.cpp @@ -14,9 +14,12 @@ #include "ob_ls_prepare_migration.h" #include "observer/ob_server.h" #include "share/rc/ob_tenant_base.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "logservice/ob_log_service.h" #include "storage/tablet/ob_tablet_iterator.h" +#include "ob_transfer_service.h" #include "storage/tablet/ob_tablet.h" +#include "ob_rebuild_service.h" using namespace oceanbase; using namespace common; @@ -199,6 +202,7 @@ bool ObLSPrepareMigrationDagNet::operator == (const ObIDagNet &other) const } else { const ObLSPrepareMigrationDagNet &other_dag_net = static_cast(other); if (!is_valid() || !other_dag_net.is_valid()) { + is_same = false; LOG_ERROR_RET(OB_INVALID_ERROR, "ls prepare migration dag net is invalid", K(*this), K(other)); } else if (ctx_.arg_.ls_id_ != other_dag_net.get_ls_id()) { is_same = false; @@ -303,8 +307,8 @@ int ObLSPrepareMigrationDagNet::deal_with_cancel() } /******************ObPrepareMigrationDag*********************/ -ObPrepareMigrationDag::ObPrepareMigrationDag(const ObStorageHADagType sub_type) - : ObStorageHADag(ObDagType::DAG_TYPE_MIGRATE, sub_type) +ObPrepareMigrationDag::ObPrepareMigrationDag(const share::ObDagType::ObDagTypeEnum &dag_type) + : ObStorageHADag(dag_type) { } @@ -321,9 +325,7 @@ bool ObPrepareMigrationDag::operator == (const ObIDag &other) const is_same = false; } else { const ObStorageHADag &ha_dag = static_cast(other); - if (ha_dag.get_sub_type() != sub_type_) { - is_same = false; - } else if (OB_ISNULL(ha_dag_net_ctx_) || OB_ISNULL(ha_dag.get_ha_dag_net_ctx())) { + if (OB_ISNULL(ha_dag_net_ctx_) || OB_ISNULL(ha_dag.get_ha_dag_net_ctx())) { is_same = false; LOG_ERROR_RET(OB_INVALID_ARGUMENT, "prepare migration ctx should not be NULL", KP(ha_dag_net_ctx_), KP(ha_dag.get_ha_dag_net_ctx())); } else if (ha_dag_net_ctx_->get_dag_net_ctx_type() != ha_dag.get_ha_dag_net_ctx()->get_dag_net_ctx_type()) { @@ -353,12 +355,30 @@ int64_t ObPrepareMigrationDag::hash() const ObLSPrepareMigrationCtx *self_ctx = static_cast(ha_dag_net_ctx_); hash_value = common::murmurhash( &self_ctx->arg_.ls_id_, sizeof(self_ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } +int ObPrepareMigrationDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + ObLSPrepareMigrationCtx *ctx = nullptr; + + if (FALSE_IT(ctx = static_cast(ha_dag_net_ctx_))) { + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(ctx->tenant_id_), ctx->arg_.ls_id_.id(), + static_cast(ctx->arg_.type_), + "dag_net_task_id", to_cstring(ctx->task_id_), + "src", to_cstring(ctx->arg_.src_.get_server()), + "dest", to_cstring(ctx->arg_.dst_.get_server())))) { + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} + int ObPrepareMigrationDag::prepare_ctx(share::ObIDagNet *dag_net) { int ret = OB_SUCCESS; @@ -382,10 +402,9 @@ int ObPrepareMigrationDag::prepare_ctx(share::ObIDagNet *dag_net) return ret; } - /******************ObInitialPrepareMigrationDag*********************/ ObInitialPrepareMigrationDag::ObInitialPrepareMigrationDag() - : ObPrepareMigrationDag(ObStorageHADagType::INITIAL_PREPARE_MIGRATION_DAG), + : ObPrepareMigrationDag(ObDagType::DAG_TYPE_INITIAL_PREPARE_MIGRATION), is_inited_(false) { } @@ -450,29 +469,6 @@ int ObInitialPrepareMigrationDag::create_first_task() return ret; } -int ObInitialPrepareMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - int64_t pos = 0; - ObLSPrepareMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("initial prepare migration dag do not init", K(ret)); - } else if (NULL == buf || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid args", K(ret), KP(buf), K(buf_len)); - } else if (FALSE_IT(ctx = static_cast(ha_dag_net_ctx_))) { - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObInitialPrepareMigrationDag : dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, " - "src = %s, dest = %s", to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), - to_cstring(ctx->arg_.ls_id_), ObMigrationOpType::get_str(ctx->arg_.type_), - to_cstring(ctx->arg_.src_.get_server()), to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObInitialMigrationTask*********************/ ObInitialPrepareMigrationTask::ObInitialPrepareMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -601,7 +597,7 @@ int ObInitialPrepareMigrationTask::generate_migration_dags_() scheduler->free_dag(*finish_prepare_dag, initial_prepare_migration_dag); finish_prepare_dag = nullptr; } - if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, true /*allow_retry*/))) { + if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, true /*allow_retry*/, this->get_dag()->get_type()))) { LOG_WARN("failed to set ls prepare migration result", K(ret), K(tmp_ret), K(*ctx_)); } } @@ -611,7 +607,7 @@ int ObInitialPrepareMigrationTask::generate_migration_dags_() /******************ObStartPrepareMigrationDag*********************/ ObStartPrepareMigrationDag::ObStartPrepareMigrationDag() - : ObPrepareMigrationDag(ObStorageHADagType::START_PREPARE_MIGRATION_DAG), + : ObPrepareMigrationDag(ObDagType::DAG_TYPE_START_PREPARE_MIGRATION), is_inited_(false) { } @@ -678,28 +674,6 @@ int ObStartPrepareMigrationDag::create_first_task() return ret; } -int ObStartPrepareMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - int64_t pos = 0; - ObLSPrepareMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("start prepare migration dag do not init", K(ret)); - } else if (NULL == buf || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid args", K(ret), KP(buf), K(buf_len)); - } else if (FALSE_IT(ctx = static_cast(ha_dag_net_ctx_))) { - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObStartPrepareMigrationDag : dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, src = %s, dest = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), ObMigrationOpType::get_str(ctx->arg_.type_), - to_cstring(ctx->arg_.src_.get_server()), to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObStartPrepareMigrationTask*********************/ ObStartPrepareMigrationTask::ObStartPrepareMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -748,12 +722,16 @@ int ObStartPrepareMigrationTask::process() //do nothing } else if (OB_FAIL(deal_with_local_ls_())) { LOG_WARN("failed to deal with local ls", K(ret), K(*ctx_)); + } else if (OB_FAIL(wait_transfer_tablets_ready_())) { + LOG_WARN("failed to wait transfer tablets ready", K(ret), KPC(ctx_)); } else if (OB_FAIL(wait_log_replay_sync_())) { LOG_WARN("failed to wait log replay sync", K(ret), KPC(ctx_)); } else if (OB_FAIL(remove_local_incomplete_tablets_())) { LOG_WARN("failed to remove local incomplete tablets", K(ret), KPC(ctx_)); } else if (OB_FAIL(wait_ls_checkpoint_scn_push_())) { LOG_WARN("failed to wait ls checkpoint ts push", K(ret), KPC(ctx_)); + } else if (OB_FAIL(prepare_backfill_tx_tablets_())) { + LOG_WARN("failed to prepare backfill tx tablets", K(ret), KPC(ctx_)); } else if (OB_FAIL(generate_prepare_migration_dags_())) { LOG_WARN("failed to generate prepare migration dags", K(ret), KPC(ctx_)); } @@ -884,7 +862,7 @@ int ObStartPrepareMigrationTask::wait_log_replay_sync_() } if (is_timeout) { - if (OB_FAIL(ctx_->set_result(OB_TIMEOUT, true /*allow_retry*/))) { + if (OB_FAIL(ctx_->set_result(OB_TIMEOUT, true /*allow_retry*/, this->get_dag()->get_type()))) { LOG_WARN("failed to set result", K(ret), KPC(ctx_)); } else { ret = OB_TIMEOUT; @@ -917,6 +895,51 @@ int ObStartPrepareMigrationTask::wait_log_replay_sync_() return ret; } +int ObStartPrepareMigrationTask::prepare_backfill_tx_tablets_() +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); + share::ObTaskId task_id = ctx_->task_id_; + share::ObLSID ls_id = ctx_->arg_.ls_id_; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else if (OB_FAIL(ls->build_tablet_iter(tablet_iter))) { + LOG_WARN("failed to build ls tablet iter", K(ret)); + } else { + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + while (OB_SUCC(ret)) { + tablet_handle.reset(); + tablet = nullptr; + if (OB_FAIL(tablet_iter.get_next_tablet(tablet_handle))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get tablet", K(ret), K(ls_id)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); + } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { + //do nothing + } else if (OB_FAIL(ctx_->tablet_id_array_.push_back(tablet->get_tablet_meta().tablet_id_))) { + LOG_WARN("failed to push tablet id into array", K(ret), KPC(tablet), K(ls_id)); + } + } + } + return ret; +} + int ObStartPrepareMigrationTask::generate_prepare_migration_dags_() { int ret = OB_SUCCESS; @@ -953,7 +976,7 @@ int ObStartPrepareMigrationTask::generate_prepare_migration_dags_() } else { if (OB_FAIL(scheduler->alloc_dag(finish_backfill_tx_dag))) { LOG_WARN("failed to alloc finish backfill tx migration dag ", K(ret)); - } else if (OB_FAIL(finish_backfill_tx_dag->init(ctx_->task_id_, ctx_->arg_.ls_id_, ctx_->log_sync_scn_, ctx_))) { + } else if (OB_FAIL(finish_backfill_tx_dag->init(ctx_->task_id_, ctx_->arg_.ls_id_, ctx_->log_sync_scn_, ctx_->tablet_id_array_, ctx_))) { LOG_WARN("failed to init data tablets migration dag", K(ret), K(*ctx_)); } else if (OB_ISNULL(backfill_tx_ctx = finish_backfill_tx_dag->get_backfill_tx_ctx())) { ret = OB_ERR_UNEXPECTED; @@ -1102,7 +1125,7 @@ int ObStartPrepareMigrationTask::remove_local_incomplete_tablets_() int ret = OB_SUCCESS; ObLSHandle ls_handle; ObLS *ls = nullptr; - ObLSTabletIterator tablet_iterator; + ObLSTabletIterator tablet_iterator(ObMDSGetTabletMode::READ_WITHOUT_CHECK); ObArray remove_tablet_ids; if (!is_inited_) { @@ -1159,13 +1182,186 @@ int ObStartPrepareMigrationTask::remove_local_incomplete_tablets_() } #endif + return ret; +} +int ObStartPrepareMigrationTask::wait_transfer_tablets_ready_() +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObLSTabletIterator tablet_iterator(ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ObTabletCreateDeleteMdsUserData user_data; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("start prepare migration task do not init", K(ret)); + } else if (OB_FAIL(ObStorageHADagUtils::get_ls(ctx_->arg_.ls_id_, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), KPC(ctx_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), KPC(ctx_)); + } else if (OB_FAIL(ls->build_tablet_iter(tablet_iterator))) { + LOG_WARN("failed to build ls tablet iter", K(ret), KPC(ctx_)); + } else { + while (OB_SUCC(ret)) { + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + user_data.reset(); + if (OB_FAIL(tablet_iterator.get_next_tablet(tablet_handle))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get next tablet", K(ret), KPC(ctx_)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_handle)); + } else if (!tablet->get_tablet_meta().ha_status_.is_data_status_complete()) { + //do nothing + } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { + //do nothing + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(tablet)); + } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ + && ObTabletStatus::TRANSFER_OUT_DELETED != user_data.tablet_status_) { + //do nothing + } else if (OB_FAIL(wait_transfer_out_tablet_ready_(ls, tablet))) { + LOG_WARN("failed to wait transfer out tablet ready", K(ret), KPC(tablet)); + } + } + } + return ret; +} + +int ObStartPrepareMigrationTask::wait_transfer_out_tablet_ready_( + ObLS *ls, + ObTablet *tablet) +{ + int ret = OB_SUCCESS; + ObTabletCreateDeleteMdsUserData user_data; + bool is_cancel = false; + ObLSHandle dest_ls_handle; + ObLS *dest_ls = nullptr; + ObTabletHandle dest_tablet_handle; + ObTablet *dest_tablet = nullptr; + ObTabletCreateDeleteMdsUserData dest_user_data; + ObTransferService *transfer_service = nullptr; + const int64_t MAX_WAIT_TRANSFER_IN_TABLET_READY = 30 *60 * 1000 * 1000L; //30min + const int64_t MAX_SLEEP_INTERVAL_MS = 100* 1000; //100ms + SCN current_replay_scn; + ObMigrationStatus status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("start prepare migration task do not init", K(ret)); + } else if (OB_ISNULL(transfer_service = (MTL(ObTransferService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer service should not be NULL", K(ret), KP(transfer_service)); + } else if (OB_ISNULL(tablet) || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait transfer out tablet ready get invalid argument", K(ret), KP(tablet), KP(ls)); + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(tablet)); + } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ + && ObTabletStatus::TRANSFER_OUT_DELETED != user_data.tablet_status_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet status is unexpected", K(ret), K(user_data), KPC(tablet)); + } else { + const int64_t wait_transfer_tablet_ready_ts = ObTimeUtility::current_time(); + while (OB_SUCC(ret)) { + if (ctx_->is_failed()) { + ret = OB_CANCELED; + STORAGE_LOG(WARN, "ls migration task is failed, cancel wait ls check point ts push", K(ret)); + } else if (ls->is_stopped()) { + ret = OB_NOT_RUNNING; + LOG_WARN("ls is not running, stop migration dag net", K(ret), K(ctx_)); + } else if (OB_FAIL(SYS_TASK_STATUS_MGR.is_task_cancel(get_dag()->get_dag_id(), is_cancel))) { + STORAGE_LOG(ERROR, "failed to check is task canceled", K(ret), K(*this)); + } else if (is_cancel) { + ret = OB_CANCELED; + STORAGE_LOG(WARN, "task is cancelled", K(ret), K(*this)); + } else if (OB_FAIL(ObStorageHADagUtils::get_ls(user_data.transfer_ls_id_, dest_ls_handle))) { + if (OB_LS_NOT_EXIST == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get ls", K(ret), K(user_data)); + } + } else if (OB_ISNULL(dest_ls = dest_ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(dest_ls), K(user_data)); + } else if (OB_FAIL(dest_ls->get_migration_status(status))) { + LOG_WARN("failed to get dest ls migration status", K(ret), K(user_data), KPC(dest_ls)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != status + && ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD_WAIT != status + && ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_WAIT != status + && ObMigrationStatus::OB_MIGRATION_STATUS_ADD_WAIT != status) { + if (ObMigrationStatus::OB_MIGRATION_STATUS_ADD_FAIL == status + || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_FAIL == status + || ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD_FAIL == status) { + LOG_INFO("dest ls is in migration failed status, no need wait", K(ret), K(status), KPC(dest_ls)); + break; + } + } else if (OB_FAIL(dest_ls->get_max_decided_scn(current_replay_scn))) { + LOG_WARN("failed to get current replay log scn", K(ret), KPC(ctx_)); + } else if (current_replay_scn < user_data.transfer_scn_) { + ObRebuildService *rebuild_service = nullptr; + bool need_rebuild = false; + if (OB_ISNULL(rebuild_service = MTL(ObRebuildService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rebuild service should not be NULL", K(ret), KP(rebuild_service)); + } else if (OB_FAIL(rebuild_service->check_ls_need_rebuild(dest_ls->get_ls_id(), need_rebuild))) { + LOG_WARN("failed to to check dest ls need rebuild", K(ret), KPC(dest_ls)); + } else if (need_rebuild) { + LOG_INFO("dest ls need rebuild, no need wait", K(ret), KPC(dest_ls)); + break; + } + } else if (OB_FAIL(dest_ls->get_tablet(tablet->get_tablet_meta().tablet_id_, dest_tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get tablet", K(ret), KPC(tablet)); + } + } else if (OB_ISNULL(dest_tablet = dest_tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(dest_tablet)); + } else if ((ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD_WAIT == status + || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_WAIT == status + || ObMigrationStatus::OB_MIGRATION_STATUS_ADD_WAIT == status) + && dest_tablet->get_tablet_meta().has_transfer_table()) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, dest_tablet, dest_user_data))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(dest_tablet)); + } else if (ObTabletStatus::TRANSFER_IN != dest_user_data.tablet_status_ + || dest_tablet->get_tablet_meta().transfer_info_.transfer_seq_ != tablet->get_tablet_meta().transfer_info_.transfer_seq_ + 1 + || !dest_tablet->get_tablet_meta().has_transfer_table()) { + break; + } else { + transfer_service->wakeup(); + } + + if (OB_SUCC(ret)) { + const int64_t current_ts = ObTimeUtility::current_time(); + if (current_ts - wait_transfer_tablet_ready_ts >= MAX_WAIT_TRANSFER_IN_TABLET_READY) { + ret = OB_TIMEOUT; + LOG_WARN("wait transfer in tablet ready time out", + "dest_ls_id", user_data.transfer_ls_id_, "dest user data", dest_user_data); + } else { + LOG_INFO("wait transfer in tablet ready", "dest user data", dest_user_data, + KPC(dest_tablet)); + ob_usleep(MAX_SLEEP_INTERVAL_MS); + } + } + } + } return ret; } /******************ObFinishPrepareMigrationDag*********************/ ObFinishPrepareMigrationDag::ObFinishPrepareMigrationDag() - : ObPrepareMigrationDag(ObStorageHADagType::FINISH_PREPARE_MIGRATION_DAG), + : ObPrepareMigrationDag(ObDagType::DAG_TYPE_FINISH_PREPARE_MIGRATION), is_inited_(false) { } @@ -1232,29 +1428,6 @@ int ObFinishPrepareMigrationDag::create_first_task() return ret; } -int ObFinishPrepareMigrationDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - int64_t pos = 0; - ObLSPrepareMigrationCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("finish prepare migration dag do not init", K(ret)); - } else if (NULL == buf || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid args", K(ret), KP(buf), K(buf_len)); - } else if (FALSE_IT(ctx = static_cast(ha_dag_net_ctx_))) { - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObFinishPrepareMigrationDag : dag_net_task_id = %s, tenant_id = %s, ls_id = %s, migration_type = %s, " - "src = %s, dest = %s", to_cstring(ctx->task_id_), to_cstring(ctx->tenant_id_), to_cstring(ctx->arg_.ls_id_), - ObMigrationOpType::get_str(ctx->arg_.type_), to_cstring(ctx->arg_.src_.get_server()), - to_cstring(ctx->arg_.dst_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObFinishPrepareMigrationTask*********************/ ObFinishPrepareMigrationTask::ObFinishPrepareMigrationTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), diff --git a/src/storage/high_availability/ob_ls_prepare_migration.h b/src/storage/high_availability/ob_ls_prepare_migration.h index 082634596..936f14cff 100644 --- a/src/storage/high_availability/ob_ls_prepare_migration.h +++ b/src/storage/high_availability/ob_ls_prepare_migration.h @@ -43,6 +43,7 @@ public: int64_t start_ts_; int64_t finish_ts_; share::SCN log_sync_scn_; + ObArray tablet_id_array_; INHERIT_TO_STRING_KV( "ObIHADagNetCtx", ObIHADagNetCtx, @@ -51,7 +52,8 @@ public: K_(task_id), K_(start_ts), K_(finish_ts), - K_(log_sync_scn)); + K_(log_sync_scn), + K_(tablet_id_array)); private: DISALLOW_COPY_AND_ASSIGN(ObLSPrepareMigrationCtx); }; @@ -99,10 +101,11 @@ private: class ObPrepareMigrationDag : public ObStorageHADag { public: - explicit ObPrepareMigrationDag(const ObStorageHADagType sub_type); + explicit ObPrepareMigrationDag(const share::ObDagType::ObDagTypeEnum &dag_type); virtual ~ObPrepareMigrationDag(); virtual bool operator == (const share::ObIDag &other) const override; virtual int64_t hash() const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; int prepare_ctx(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObStorageHADag", ObStorageHADag, KP(this)); @@ -117,7 +120,7 @@ public: virtual ~ObInitialPrepareMigrationDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObPrepareMigrationDag", ObPrepareMigrationDag, KP(this)); @@ -150,7 +153,6 @@ public: virtual ~ObStartPrepareMigrationDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObPrepareMigrationDag", ObPrepareMigrationDag, KP(this)); @@ -174,6 +176,10 @@ private: int wait_ls_checkpoint_scn_push_(); int generate_prepare_migration_dags_(); int remove_local_incomplete_tablets_(); + int prepare_backfill_tx_tablets_(); + int wait_transfer_tablets_ready_(); + int wait_transfer_out_tablet_ready_( + ObLS *ls, ObTablet *tablet); private: bool is_inited_; @@ -188,7 +194,6 @@ public: virtual ~ObFinishPrepareMigrationDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObPrepareMigrationDag", ObPrepareMigrationDag, KP(this)); diff --git a/src/storage/high_availability/ob_ls_rebuild_cb_impl.cpp b/src/storage/high_availability/ob_ls_rebuild_cb_impl.cpp index 2a93a90b9..1f797f5af 100644 --- a/src/storage/high_availability/ob_ls_rebuild_cb_impl.cpp +++ b/src/storage/high_availability/ob_ls_rebuild_cb_impl.cpp @@ -12,7 +12,7 @@ #define USING_LOG_PREFIX STORAGE #include "ob_ls_rebuild_cb_impl.h" -#include "ob_storage_ha_service.h" +#include "ob_rebuild_service.h" #include "share/ls/ob_ls_table_operator.h" #include "observer/ob_server_event_history_table_operator.h" #include "logservice/ob_log_service.h" @@ -80,12 +80,7 @@ int ObLSRebuildCbImpl::on_rebuild( } else if (OB_FAIL(check_ls_in_rebuild_status_(is_ls_in_rebuild))) { LOG_WARN("failed to check ls in rebuild status", K(ret), K(ls_id), KPC(ls_)); } else if (is_ls_in_rebuild) { - wakeup_ha_service_(); - } else if (OB_FAIL(check_need_rebuild_(lsn, need_rebuild))) { - LOG_WARN("failed to check need rebuild", K(ret), K(ls_id)); - } else if (!need_rebuild) { - ret = OB_NO_NEED_REBUILD; - LOG_WARN("ls no need rebuild", K(ret), K(lsn), KPC(ls_)); + wakeup_rebuild_service_(); } else if (OB_FAIL(execute_rebuild_())) { LOG_WARN("failed to execute rebuild", K(ret), K(lsn), KPC(ls_)); } else { @@ -102,68 +97,19 @@ int ObLSRebuildCbImpl::check_ls_in_rebuild_status_( { int ret = OB_SUCCESS; is_ls_in_rebuild = false; - ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + ObLSRebuildInfo rebuild_info; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("ls rebuild cb impl do not init", K(ret)); - } else if (OB_FAIL(ls_->get_migration_status(migration_status))) { - LOG_WARN("failed to get ls migration status", K(ret), KPC(ls_)); - } else if (ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD == migration_status) { + } else if (OB_FAIL(ls_->get_rebuild_info(rebuild_info))) { + LOG_WARN("failed to get rebuild info", K(ret), KPC(ls_)); + } else if (!rebuild_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rebuild info is invalid", K(ret), KPC(ls_)); + } else if (rebuild_info.is_in_rebuild()) { is_ls_in_rebuild = true; - LOG_INFO("ls is already in rebuild status", K(ret), K(migration_status), KPC(ls_)); - } - return ret; -} - -int ObLSRebuildCbImpl::check_need_rebuild_( - const palf::LSN &lsn, - bool &need_rebuild) -{ - int ret = OB_SUCCESS; - ObLSInfo ls_info; - int64_t cluster_id = GCONF.cluster_id; - uint64_t tenant_id = MTL_ID(); - ObAddr leader_addr; - need_rebuild = false; - share::ObLocationService *location_service = nullptr; - ObStorageHASrcInfo src_info; - obrpc::ObFetchLSMemberListInfo member_info; - const bool force_renew = true; - src_info.cluster_id_ = cluster_id; - ObRole role; - int64_t proposal_id = 0; - logservice::ObLogService *log_service = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("ls rebuild cb impl do not init", K(ret)); - } else if (OB_ISNULL(log_service = MTL(logservice::ObLogService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("log service should not be NULL", K(ret), KP(log_service)); - } else if (OB_FAIL(log_service->get_palf_role(ls_->get_ls_id(), role, proposal_id))) { - LOG_WARN("failed to get role", K(ret), KPC(ls_)); - } else if (is_strong_leader(role)) { - need_rebuild = false; - LOG_INFO("replica is leader, can not rebuild", KPC(ls_)); - } else if (OB_ISNULL(location_service = GCTX.location_service_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("location service should not be NULL", K(ret), KP(location_service)); - } else if (OB_FAIL(location_service->get_leader(src_info.cluster_id_, tenant_id, ls_->get_ls_id(), force_renew, src_info.src_addr_))) { - LOG_WARN("fail to get ls leader server", K(ret), K(tenant_id), KPC(ls_)); - //for rebuild without leader exist - ret = OB_SUCCESS; - } else if (OB_FAIL(storage_rpc_->post_ls_member_list_request(tenant_id, src_info, ls_->get_ls_id(), member_info))) { - LOG_WARN("failed to get ls member info", K(ret), KPC(ls_)); - } else if (!member_info.member_list_.contains(GCONF.self_addr_)) { - ret = OB_WORKING_PARTITION_NOT_EXIST; - LOG_WARN("can not rebuild, it is not normal ls", K(ret), KPC(ls_)); - } - - if (OB_FAIL(ret)) { - } else { - //TODO(muwei.ym) send rpc to check member list lsn - need_rebuild = true; + LOG_INFO("ls is already in rebuild status", K(ret), K(rebuild_info), KPC(ls_)); } return ret; } @@ -171,28 +117,34 @@ int ObLSRebuildCbImpl::check_need_rebuild_( int ObLSRebuildCbImpl::execute_rebuild_() { int ret = OB_SUCCESS; + ObRebuildService *rebuild_service = nullptr; + const ObLSRebuildType rebuild_type(ObLSRebuildType::CLOG); + if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("ls rebuild cb impl do not init", K(ret)); - } else if (OB_FAIL(ls_->set_ls_rebuild())) { - LOG_WARN("failed to set ls rebuild", K(ret)); + } else if (OB_ISNULL(rebuild_service = (MTL(ObRebuildService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rebuild service not be NULL", K(ret), KP(rebuild_service)); + } else if (OB_FAIL(rebuild_service->add_rebuild_ls(ls_->get_ls_id(), rebuild_type))) { + LOG_WARN("failed to add rebuild ls", K(ret), KPC(ls_), K(rebuild_type)); } else { LOG_INFO("succeed execute rebuild", KPC(ls_)); - wakeup_ha_service_(); + wakeup_rebuild_service_(); } return ret; } -void ObLSRebuildCbImpl::wakeup_ha_service_() +void ObLSRebuildCbImpl::wakeup_rebuild_service_() { int ret = OB_SUCCESS; - ObStorageHAService *ha_service = nullptr; + ObRebuildService *rebuild_service = nullptr; - if (OB_ISNULL(ha_service = (MTL(ObStorageHAService *)))) { + if (OB_ISNULL(rebuild_service = (MTL(ObRebuildService *)))) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls service should not be NULL", K(ret), KP(ha_service)); + LOG_WARN("rebuild service not be NULL", K(ret), KP(rebuild_service)); } else { - ha_service->wakeup(); + rebuild_service->wakeup(); } } diff --git a/src/storage/high_availability/ob_ls_rebuild_cb_impl.h b/src/storage/high_availability/ob_ls_rebuild_cb_impl.h index f5be247b7..5918dc680 100644 --- a/src/storage/high_availability/ob_ls_rebuild_cb_impl.h +++ b/src/storage/high_availability/ob_ls_rebuild_cb_impl.h @@ -40,11 +40,8 @@ public: void destroy(); private: int check_ls_in_rebuild_status_(bool &is_ls_in_rebuild); - int check_need_rebuild_( - const palf::LSN &lsn, - bool &need_rebuild); int execute_rebuild_(); - void wakeup_ha_service_(); + void wakeup_rebuild_service_(); private: bool is_inited_; ObLS *ls_; diff --git a/src/storage/high_availability/ob_ls_remove_member_dag.cpp b/src/storage/high_availability/ob_ls_remove_member_dag.cpp index 712aabb32..fc7b6ce67 100644 --- a/src/storage/high_availability/ob_ls_remove_member_dag.cpp +++ b/src/storage/high_availability/ob_ls_remove_member_dag.cpp @@ -14,10 +14,12 @@ #include "ob_ls_remove_member_dag.h" #include "observer/ob_server.h" #include "share/rc/ob_tenant_base.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "storage/tx_storage/ob_ls_handle.h" #include "storage/tx_storage/ob_ls_service.h" #include "logservice/ob_log_service.h" #include "lib/hash/ob_hashset.h" +#include "storage/high_availability/ob_storage_ha_utils.h" using namespace oceanbase; using namespace share; @@ -124,15 +126,16 @@ int64_t ObLSRemoveMemberDag::hash() const return hash_value; } -int ObLSRemoveMemberDag::fill_comment(char *buf, const int64_t buf_len) const +int ObLSRemoveMemberDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("ls remove member dag do not init", K(ret)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, "ls remove member dag: ls_id = %s, remove_member = %s", - to_cstring(ctx_.arg_.ls_id_) ,to_cstring(ctx_.arg_.remove_member_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), K(ctx_)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + ctx_.arg_.ls_id_.id(), + "remove_member", to_cstring(ctx_.arg_.remove_member_.get_server())))) { + LOG_WARN("failed to fill info param", K(ret)); } return ret; } @@ -353,6 +356,7 @@ int ObLSRemoveMemberTask::transform_member_(ObLS *ls) const int64_t change_member_list_timeout_us = GCONF.sys_bkgd_migration_change_member_list_timeout; const ObReplicaType &src_type = ctx_->arg_.src_.get_replica_type(); const ObReplicaType &dest_type = ctx_->arg_.dest_.get_replica_type(); + palf::LogConfigVersion config_version; if (!ctx_->arg_.type_.is_transform_member()) { ret = OB_ERR_UNEXPECTED; @@ -364,9 +368,7 @@ int ObLSRemoveMemberTask::transform_member_(ObLS *ls) LOG_WARN("failed to switch acceptor to learner", KR(ret), KPC(ctx_)); } } else if (ObReplicaTypeCheck::is_readonly_replica(src_type) && ObReplicaTypeCheck::is_full_replica(dest_type)) { - //R -> F - //TODO(muwei.ym) need consider add F to member list with TRANSFER - if (OB_FAIL(ls->switch_learner_to_acceptor(ctx_->arg_.src_, ctx_->arg_.new_paxos_replica_number_, change_member_list_timeout_us))) { + if (OB_FAIL(switch_learner_to_acceptor_(ls))) { LOG_WARN("failed to switch learner to acceptor", KR(ret), KPC(ctx_)); } } else { @@ -377,6 +379,33 @@ int ObLSRemoveMemberTask::transform_member_(ObLS *ls) return ret; } +int ObLSRemoveMemberTask::switch_learner_to_acceptor_(ObLS *ls) +{ + int ret = OB_SUCCESS; + ObLSService *ls_svr = NULL; + ObStorageRpc *storage_rpc = NULL; + ObStorageHASrcInfo src_info; + src_info.cluster_id_ = GCONF.cluster_id; + share::SCN ls_transfer_scn; + const uint64_t tenant_id = ctx_->arg_.tenant_id_; + const int64_t timeout = GCONF.sys_bkgd_migration_change_member_list_timeout; + if (OB_ISNULL(ls_svr = (MTL(ObLSService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), KP(ls_svr)); + } else if (OB_FAIL(ls->get_transfer_scn(ls_transfer_scn))) { + LOG_WARN("failed to get transfer scn", K(ret), KP(ls)); + } else if (OB_FAIL(ObStorageHAUtils::get_ls_leader(tenant_id, ctx_->arg_.ls_id_, src_info.src_addr_))) { + LOG_WARN("failed to get ls leader", K(ret), KPC(ctx_)); + } else if (OB_ISNULL(storage_rpc = ls_svr->get_storage_rpc())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage rpc should not be NULL", K(ret), KP(storage_rpc)); + } else if (OB_FAIL(storage_rpc->switch_learner_to_acceptor(tenant_id, src_info, ctx_->arg_.ls_id_, ctx_->arg_.src_, + ctx_->arg_.new_paxos_replica_number_, ls_transfer_scn, timeout))) { + LOG_WARN("failed to switch learner to acceptor", K(ret), KPC(ctx_)); + } + return ret; +} + int ObLSRemoveMemberTask::report_to_rs_() { int ret = OB_SUCCESS; @@ -397,6 +426,7 @@ int ObLSRemoveMemberTask::report_to_rs_() res.task_id_ = ctx_->arg_.task_id_; res.tenant_id_ = ctx_->arg_.tenant_id_; res.ls_id_ = ctx_->arg_.ls_id_; + res.result_ = ctx_->result_; while (retry_count++ < MAX_RETRY_TIMES) { if (OB_FAIL(rs_mgr->get_master_root_server(rs_addr))) { STORAGE_LOG(WARN, "get master root service failed", K(ret)); diff --git a/src/storage/high_availability/ob_ls_remove_member_dag.h b/src/storage/high_availability/ob_ls_remove_member_dag.h index cca55d76f..b2fca3fc2 100644 --- a/src/storage/high_availability/ob_ls_remove_member_dag.h +++ b/src/storage/high_availability/ob_ls_remove_member_dag.h @@ -70,7 +70,7 @@ public: ObLSRemoveMemberCtx *get_ctx() { return &ctx_; } virtual bool operator == (const ObIDag &other) const override; virtual int64_t hash() const override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int64_t to_string(char* buf, const int64_t buf_len) const override; virtual lib::Worker::CompatMode get_compat_mode() const override { return lib::Worker::CompatMode::MYSQL; } @@ -97,6 +97,7 @@ private: int remove_member_(ObLS *ls); int modify_member_number_(ObLS *ls); int transform_member_(ObLS *ls); + int switch_learner_to_acceptor_(ObLS *ls); int report_to_rs_(); private: diff --git a/src/storage/high_availability/ob_ls_restore.cpp b/src/storage/high_availability/ob_ls_restore.cpp index fde35a4de..4e727b5c2 100644 --- a/src/storage/high_availability/ob_ls_restore.cpp +++ b/src/storage/high_availability/ob_ls_restore.cpp @@ -15,8 +15,12 @@ #include "observer/ob_server.h" #include "ob_physical_copy_task.h" #include "share/rc/ob_tenant_base.h" -#include "share/backup/ob_backup_data_store.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" +#include "storage/backup/ob_backup_data_store.h" #include "storage/tx_storage/ob_ls_service.h" +#include "storage/high_availability/ob_storage_ha_reader.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "storage/tablet/ob_tablet.h" namespace oceanbase { @@ -171,7 +175,6 @@ int ObLSRestoreDagNet::init_by_param(const ObIDagInitParam *param) const ObLSRestoreDagNetInitParam *init_param = static_cast(param); const int64_t priority = 1; char buf[OB_MAX_BACKUP_DEST_LENGTH] = { 0 }; - ObBackupSetDesc backup_set_desc; if (is_inited_) { ret = OB_INIT_TWICE; LOG_WARN("ls restore dag net is init twice", K(ret)); @@ -181,9 +184,9 @@ int ObLSRestoreDagNet::init_by_param(const ObIDagInitParam *param) } else if (init_param->arg_.is_leader_) { const backup::ObBackupRestoreMode mode = backup::ObBackupRestoreMode::RESTORE_MODE; const backup::ObBackupIndexLevel index_level = backup::ObBackupIndexLevel::BACKUP_INDEX_LEVEL_LOG_STREAM; - share::ObExternBackupSetInfoDesc backup_set_file_desc; + storage::ObExternBackupSetInfoDesc backup_set_file_desc; backup::ObBackupIndexStoreParam index_store_param; - share::ObBackupDataStore store; + storage::ObBackupDataStore store; int64_t retry_id = 0; if (OB_FAIL(store.init(init_param->arg_.restore_base_info_.backup_dest_))) { LOG_WARN("fail to init mgr", K(ret)); @@ -198,15 +201,14 @@ int ObLSRestoreDagNet::init_by_param(const ObIDagInitParam *param) index_store_param.ls_id_ = init_param->arg_.ls_id_; index_store_param.is_tenant_level_ = false; index_store_param.backup_data_type_ = data_type; - index_store_param.turn_id_ = backup_set_file_desc.backup_set_file_.data_turn_id_; - backup_set_desc.backup_set_id_ = backup_set_file_desc.backup_set_file_.backup_set_id_; - backup_set_desc.backup_type_.type_ = backup_set_file_desc.backup_set_file_.backup_type_.type_; + index_store_param.turn_id_ = init_param->arg_.ls_id_.is_sys_ls() ? + 1/*sys ls only has one turn*/ : backup_set_file_desc.backup_set_file_.meta_turn_id_; ObBackupPath backup_path; if (OB_FAIL(ObBackupPathUtil::get_ls_backup_dir_path( init_param->arg_.restore_base_info_.backup_dest_, init_param->arg_.ls_id_, backup_path))) { LOG_WARN("failed to get ls backup dir path", K(ret), KPC(init_param)); - } else if (OB_FAIL(store.get_max_sys_ls_retry_id(backup_path, init_param->arg_.ls_id_, retry_id))) { + } else if (OB_FAIL(store.get_max_sys_ls_retry_id(backup_path, init_param->arg_.ls_id_, index_store_param.turn_id_, retry_id))) { LOG_WARN("failed to get max sys retry id", K(ret), K(backup_path), KPC(init_param)); } else { index_store_param.retry_id_ = retry_id; @@ -218,11 +220,11 @@ int ObLSRestoreDagNet::init_by_param(const ObIDagInitParam *param) if (OB_FAIL(ret)) { } else if (OB_FAIL(meta_index_store_.init(mode, index_store_param, init_param->arg_.restore_base_info_.backup_dest_, - backup_set_desc, false/*is_sec_meta*/, OB_BACKUP_INDEX_CACHE))) { + backup_set_file_desc.backup_set_file_, false/*is_sec_meta*/, true/*init sys tablet index store*/, OB_BACKUP_INDEX_CACHE))) { LOG_WARN("failed to init meta index store", K(ret), KPC(init_param)); } else if (OB_FAIL(second_meta_index_store_.init(mode, index_store_param, init_param->arg_.restore_base_info_.backup_dest_, - backup_set_desc, true/*is_sec_meta*/, OB_BACKUP_INDEX_CACHE))) { + backup_set_file_desc.backup_set_file_, true/*is_sec_meta*/, true/*init sys tablet index store*/, OB_BACKUP_INDEX_CACHE))) { LOG_WARN("failed to init macro index store", K(ret), KPC(init_param)); } } @@ -399,6 +401,7 @@ int ObLSRestoreDagNet::report_result_() { int ret = OB_SUCCESS; int32_t result = OB_SUCCESS; + share::ObTaskId failed_task_id; ObLSHandle ls_handle; ObLS *ls = nullptr; ObArray succeed_tablet_array; @@ -415,11 +418,11 @@ int ObLSRestoreDagNet::report_result_() LOG_WARN("ls should not be NULL", K(ret), KPC(ctx_)); } else if (OB_FAIL(ctx_->get_result(result))) { LOG_WARN("failed to get ls restore ctx result", K(ret), KPC(ctx_)); + } else if (OB_FAIL(ctx_->get_first_failed_task_id(failed_task_id))) { + LOG_WARN("failed to get ls restore failed task id", K(ret), KPC(ctx_)); } else if (OB_FAIL(ls->get_ls_restore_handler()->handle_execute_over( - ctx_->task_id_, succeed_tablet_array, failed_tablet_array, ctx_->arg_.ls_id_, result))) { - LOG_WARN("failed to handle execute oever ls restore result", K(ret), KPC(ctx_)); - } else { - //TODO(muwei.ym) FIX IT //1.report meta table //2.report to scheduler thread + OB_SUCCESS == result ? ctx_->task_id_ : failed_task_id, succeed_tablet_array, failed_tablet_array, ctx_->arg_.ls_id_, result))) { + LOG_WARN("failed to handle execute over ls restore result", K(ret), KPC(ctx_)); } return ret; } @@ -440,8 +443,8 @@ int ObLSRestoreDagNet::deal_with_cancel() } /******************ObLSRestoreDag*********************/ -ObLSRestoreDag::ObLSRestoreDag(const ObStorageHADagType sub_type) - : ObStorageHADag(ObDagType::DAG_TYPE_RESTORE, sub_type) +ObLSRestoreDag::ObLSRestoreDag(const share::ObDagType::ObDagTypeEnum &dag_type) + : ObStorageHADag(dag_type) { } @@ -460,9 +463,7 @@ bool ObLSRestoreDag::operator == (const ObIDag &other) const const ObLSRestoreDag &other_dag = static_cast(other); ObLSRestoreCtx *ctx = get_ctx(); - if (other_dag.get_sub_type() != sub_type_) { - is_same = false; - } else if (OB_ISNULL(ctx) || OB_ISNULL(other_dag.get_ctx())) { + if (OB_ISNULL(ctx) || OB_ISNULL(other_dag.get_ctx())) { is_same = false; LOG_ERROR_RET(OB_INVALID_ARGUMENT, "ls restore ctx should not be NULL", KP(ctx), KP(other_dag.get_ctx())); } else if (NULL != ctx && NULL != other_dag.get_ctx()) { @@ -484,15 +485,34 @@ int64_t ObLSRestoreDag::hash() const } else { hash_value = common::murmurhash( &ctx->arg_.ls_id_, sizeof(ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } +int ObLSRestoreDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + ObLSRestoreCtx *ctx = nullptr; + + if (OB_ISNULL(ctx = get_ctx())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls restore ctx should not be NULL", K(ret), KP(ctx)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + ctx->arg_.ls_id_.id(), + static_cast(ctx->arg_.is_leader_), + "dag_net_task_id", to_cstring(ctx->task_id_), + "src", to_cstring(ctx->arg_.src_.get_server())))) { + LOG_WARN("failed to fill info param", K(ret), KP(ctx)); + } + return ret; +} + /******************ObInitialLSRestoreDag*********************/ ObInitialLSRestoreDag::ObInitialLSRestoreDag() - : ObLSRestoreDag(ObStorageHADagType::INITIAL_LS_RESTORE_DAG), + : ObLSRestoreDag(ObDagType::DAG_TYPE_INITIAL_LS_RESTORE), is_inited_(false) { } @@ -564,26 +584,6 @@ int ObInitialLSRestoreDag::create_first_task() return ret; } -int ObInitialLSRestoreDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObLSRestoreCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("initial ls restore dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls restore ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObInitialLSRestoreDag : dag_net_task_id = %s, ls_id = %s, is_leader = %s, src = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->arg_.ls_id_), to_cstring(ctx->arg_.is_leader_), - to_cstring(ctx->arg_.src_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObLSRestoreInitTask*********************/ ObInitialLSRestoreTask::ObInitialLSRestoreTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -715,7 +715,7 @@ int ObInitialLSRestoreTask::generate_ls_restore_dags_() start_ls_restore_dag = nullptr; } const bool need_retry = true; - if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, need_retry))) { + if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, need_retry, this->get_dag()->get_type()))) { LOG_WARN("failed to set ls restore result", K(ret), K(tmp_ret), K(*ctx_)); } } @@ -725,7 +725,7 @@ int ObInitialLSRestoreTask::generate_ls_restore_dags_() /******************ObStartLSRestoreDag*********************/ ObStartLSRestoreDag::ObStartLSRestoreDag() - : ObLSRestoreDag(ObStorageHADagType::START_LS_RESTORE_DAG), + : ObLSRestoreDag(ObDagType::DAG_TYPE_START_LS_RESTORE), is_inited_(false) { } @@ -797,26 +797,6 @@ int ObStartLSRestoreDag::create_first_task() return ret; } -int ObStartLSRestoreDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObLSRestoreCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("start ls restore dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls restore ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObStartLSRestoreDag : dag_net_task_id = %s, ls_id = %s, is_leader = %s, src = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->arg_.ls_id_), to_cstring(ctx->arg_.is_leader_), - to_cstring(ctx->arg_.src_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObStartLSRestoreTask*********************/ ObStartLSRestoreTask::ObStartLSRestoreTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -870,11 +850,9 @@ int ObStartLSRestoreTask::process() } else if (ctx_->is_failed()) { //do nothing } else if (OB_FAIL(deal_with_local_ls_())) { - LOG_WARN("failed to deal with local ls", K(ret), K(*ctx_)); - } else if (OB_FAIL(choose_src_())) { - LOG_WARN("failed to choose src", K(ret), K(*ctx_)); - } else if (OB_FAIL(update_ls_meta_())) { - LOG_WARN("failed to update_ls_meta_", K(ret), K(*ctx_)); + LOG_WARN("failed to deal with local ls", K(ret), KPC_(ctx)); + } else if (OB_FAIL(update_ls_meta_and_create_all_tablets_())) { + LOG_WARN("failed to update ls meta and create all tablets", K(ret), KPC_(ctx)); } else if (OB_FAIL(generate_tablets_restore_dag_())) { LOG_WARN("failed to generate tablets retore dag", K(ret), K(*ctx_)); } @@ -882,7 +860,7 @@ int ObStartLSRestoreTask::process() if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; if (OB_SUCCESS != (tmp_ret = ObStorageHADagUtils::deal_with_fo(ret, this->get_dag()))) { - LOG_WARN("failed to deal with fo", K(ret), K(tmp_ret), K(*ctx_)); + LOG_WARN("failed to deal with fo", K(ret), K(tmp_ret), KPC_(ctx)); } } @@ -913,129 +891,176 @@ int ObStartLSRestoreTask::deal_with_local_ls_() } else if (ObLSRestoreStatus::RESTORE_SYS_TABLETS != restore_status) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls restore status is unexpected", K(ret), K(restore_status)); - } else { - //TODO(muwei.ym) //1.check ls log is in disable status } } return ret; } -int ObStartLSRestoreTask::choose_src_() +int ObStartLSRestoreTask::alloc_copy_ls_view_reader_(ObICopyLSViewInfoReader *&reader) { int ret = OB_SUCCESS; + reader = nullptr; + void *buf = nullptr; - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("start ls restore task do not init", K(ret)); - } else { - if (ctx_->arg_.is_leader_) { - if (OB_FAIL(choose_leader_src_())) { - LOG_WARN("failed to choose leader src", K(ret), KPC(ctx_)); - } + if (ctx_->arg_.is_leader_) { + ObCopyLSViewInfoRestoreReader *restore_reader = nullptr; + if (FALSE_IT(buf = mtl_malloc(sizeof(ObCopyLSViewInfoRestoreReader), "CpLSViewRestore"))) { + } else if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret)); + } else if (FALSE_IT(restore_reader = new (buf) ObCopyLSViewInfoRestoreReader())) { + } else if (OB_FAIL(restore_reader->init(ctx_->arg_.ls_id_, ctx_->arg_.restore_base_info_))) { + LOG_WARN("failed to init tablet restore reader", K(ret), KPC(ctx_)); } else { - if (OB_FAIL(choose_follower_src_())) { - LOG_WARN("failed to choose follower src", K(ret), KPC(ctx_)); - } + reader = restore_reader; + restore_reader = nullptr; } - FLOG_INFO("choose restore src", "is_leader", - ctx_->arg_.is_leader_, "src_ls_meta", ctx_->src_ls_meta_package_, - "sys_tablet_id", ctx_->sys_tablet_id_array_, "data_tablet_id", ctx_->data_tablet_id_array_); - } - return ret; -} -int ObStartLSRestoreTask::choose_follower_src_() -{ - int ret = OB_SUCCESS; - obrpc::ObCopyLSInfo ls_info; - ObLSRestoreStatus ls_restore_status; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("start ls restore task do not init", K(ret)); - } else if (ctx_->arg_.is_leader_) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("choose follower src get invalid argument", K(ret), KPC(ctx_)); + if (OB_NOT_NULL(restore_reader)) { + restore_reader->~ObCopyLSViewInfoRestoreReader(); + mtl_free(restore_reader); + restore_reader = nullptr; + } } else { + ObCopyLSViewInfoObReader *ob_reader = nullptr; + ObStorageHASrcInfo src_info; src_info.src_addr_ = ctx_->arg_.src_.get_server(); src_info.cluster_id_ = GCONF.cluster_id; - if (OB_FAIL(storage_rpc_->post_ls_info_request( - ctx_->arg_.tenant_id_, src_info, ctx_->arg_.ls_id_, ls_info))) { - LOG_WARN("fail to post fetch partition info request", K(ret), K(src_info), "arg", ctx_->arg_); - } else if (OB_FAIL(ls_info.ls_meta_package_.ls_meta_.get_restore_status(ls_restore_status))) { - LOG_WARN("failed to get restore status", K(ret), K(ls_info)); - } else if (!ls_restore_status.is_wait_restore_sys_tablets()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("src ls restore status is unexpected", K(ret), K(ls_info), KPC(ctx_)); - } else { - ctx_->src_ = src_info; - ctx_->src_ls_meta_package_ = ls_info.ls_meta_package_; - ctx_->need_check_seq_ = true; - ctx_->ls_rebuild_seq_ = ls_info.ls_meta_package_.ls_meta_.get_rebuild_seq(); - if (OB_FAIL(generate_tablet_id_array_(ls_info.tablet_id_array_))) { - LOG_WARN("failed to generate tablet id array", K(ret), K(ls_info)); - } + obrpc::ObCopyLSViewArg arg; + arg.tenant_id_ = ctx_->arg_.tenant_id_; + arg.ls_id_ = ctx_->arg_.ls_id_; + if (FALSE_IT(buf = mtl_malloc(sizeof(ObCopyLSViewInfoObReader), "CpLSViewRead"))) { + } else if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret)); + } else if (FALSE_IT(ob_reader = new (buf) ObCopyLSViewInfoObReader())) { + } else if (OB_FAIL(ob_reader->init(src_info, arg, *svr_rpc_proxy_, *bandwidth_throttle_))) { + LOG_WARN("failed to init tablet restore reader", K(ret), K(src_info), K(arg)); + } else { + reader = ob_reader; + ob_reader = nullptr; + ctx_->src_ = src_info; + } + + if (OB_NOT_NULL(ob_reader)) { + ob_reader->~ObCopyLSViewInfoObReader(); + mtl_free(ob_reader); + ob_reader = nullptr; } } return ret; } -int ObStartLSRestoreTask::choose_leader_src_() +void ObStartLSRestoreTask::free_copy_ls_view_reader_(ObICopyLSViewInfoReader *&reader) +{ + if (OB_NOT_NULL(reader)) { + reader->~ObICopyLSViewInfoReader(); + ob_free(reader); + reader = nullptr; + } +} + +int ObStartLSRestoreTask::create_tablet_( + const ObMigrationTabletParam &tablet_meta, + ObLS *ls) { int ret = OB_SUCCESS; - ObArray tablet_id_array; - ObArray deleted_tablet_id_array; - ObArray need_schedule_tablet_id_array; - ObMigrationStatus migration_status; - ObLSRestoreStatus restore_status; - share::ObBackupDataStore store; - share::ObExternBackupSetInfoDesc backup_set_info; - int64_t turn_id = 1; // for restore, read all tablet from turn 1 - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("start ls restore task do not init", K(ret)); - } else if (!ctx_->arg_.is_leader_) { + ObTablesHandleArray remote_table; + ObBatchUpdateTableStoreParam param; + + if (!tablet_meta.is_valid() || OB_ISNULL(ls)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("choose leader src get invalid argument", K(ret), KPC(ctx_)); + LOG_WARN("create tablet get invalid argument", K(ret), K(tablet_meta), KP(ls)); + } else if (OB_FAIL(ls->rebuild_create_tablet(tablet_meta, false /*keep old*/))) { + LOG_WARN("failed to create tablet", K(ret), K(tablet_meta)); } else { + LOG_INFO("succeed to create tablet and table store", KPC(ls), K(tablet_meta), K(remote_table)); + } + + return ret; +} + +void ObStartLSRestoreTask::set_tablet_to_restore(ObMigrationTabletParam &tablet_meta) +{ + tablet_meta.ha_status_.set_restore_status(ObTabletRestoreStatus::PENDING); + tablet_meta.ha_status_.set_data_status(ObTabletDataStatus::INCOMPLETE); +} + +int ObStartLSRestoreTask::update_ls_meta_and_create_all_tablets_() +{ + int ret = OB_SUCCESS; + ObICopyLSViewInfoReader *reader = nullptr; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + ObLSHandle ls_handle; + if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ctx_->arg_.ls_id_, ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("fail to get ls handle", K(ret), "ls_id", ctx_->arg_.ls_id_); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), K(ls_handle)); + } else if (OB_FAIL(alloc_copy_ls_view_reader_(reader))) { + LOG_WARN("failed to alloc copy ls view reader", K(ret)); + } else { + ObMigrationStatus migration_status; + ObLSRestoreStatus restore_status; + obrpc::ObCopyTabletInfo tablet_info; HEAP_VAR(ObLSMetaPackage, ls_meta_package) { - if (OB_FAIL(store.init(ctx_->arg_.restore_base_info_.backup_dest_))) { - LOG_WARN("fail to init backup extern mgr", K(ret), KPC(ctx_)); - } else if (OB_FAIL(store.read_ls_meta_infos(ctx_->arg_.ls_id_, ls_meta_package))) { - LOG_WARN("fail to read ls meta infos", K(ret), "ls_id", ctx_->arg_.ls_id_); + if (OB_FAIL(reader->get_ls_meta(ls_meta_package))) { + LOG_WARN("fail to read ls meta infos", K(ret)); } else if (OB_FAIL(ls_meta_package.ls_meta_.get_migration_status(migration_status))) { LOG_WARN("failed to get migration status", K(ret), K(ls_meta_package)); } else if (OB_FAIL(ls_meta_package.ls_meta_.get_restore_status(restore_status))) { LOG_WARN("failed to get restore status", K(ret), K(ls_meta_package)); - } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status || ObLSRestoreStatus::RESTORE_NONE != restore_status) { + } else if (ctx_->arg_.is_leader_ + && (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status + || ObLSRestoreStatus::RESTORE_NONE != restore_status)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls restore get unexpected migration status or restore status", K(ret), K(migration_status), + LOG_WARN("leader ls restore get unexpected migration status or restore status", K(ret), K(migration_status), K(restore_status), K(ls_meta_package)); - } else if (OB_FAIL(store.read_tablet_to_ls_info( - turn_id, - ctx_->arg_.ls_id_, - tablet_id_array))) { - LOG_WARN("failed to read tablet to ls info", K(ret), KPC(ctx_)); - } else if (OB_FAIL(store.read_deleted_tablet_info( - ctx_->arg_.ls_id_, - deleted_tablet_id_array))) { - LOG_WARN("failed to read deleted tablet info", K(ret), KPC(ctx_)); - } else if (OB_FAIL(get_difference(tablet_id_array, deleted_tablet_id_array, need_schedule_tablet_id_array))) { - LOG_WARN("failed to get difference", K(ret), K(tablet_id_array), K(deleted_tablet_id_array)); + } else if (!ctx_->arg_.is_leader_ + && !restore_status.is_wait_restore_sys_tablets()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("follower ls restore get unexpected restore status", K(ret), K(restore_status), K(ls_meta_package)); + } else if (OB_FAIL(ls->update_ls_meta(false/*don't update restore status*/, + ls_meta_package.ls_meta_))) { + LOG_WARN("fail to update ls meta", K(ret), KPC(ls), K(ls_meta_package)); } else { - FLOG_INFO("succeed get backup ls meta info and tablet id array", K(ls_meta_package), K(tablet_id_array)); + LOG_INFO("update ls meta succeed", KPC(ls), K(ls_meta_package)); ctx_->src_ls_meta_package_ = ls_meta_package; - ctx_->need_check_seq_ = false; - ctx_->ls_rebuild_seq_ = -1; - if (OB_FAIL(generate_tablet_id_array_(need_schedule_tablet_id_array))) { - LOG_WARN("failed to generate tablet id array", K(ret), K(ls_meta_package), K(need_schedule_tablet_id_array)); - } else { - LOG_INFO("get deleted tablet ids", KPC(ctx_), K(deleted_tablet_id_array)); + ctx_->need_check_seq_ = ctx_->arg_.is_leader_ ? false : true; + ctx_->ls_rebuild_seq_ = ctx_->arg_.is_leader_ ? -1 : ls_meta_package.ls_meta_.get_rebuild_seq(); + ctx_->sys_tablet_id_array_.reset(); + int64_t tablet_cnt = 0; + // create all tablets on the log stream + while (OB_SUCC(ret)) { + tablet_info.reset(); + if (OB_FAIL(reader->get_next_tablet_info(tablet_info))) { + if (OB_ITER_END == ret) { + LOG_INFO("update ls meta and create all tablets succeed", KPC_(ctx), K(tablet_cnt)); + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get next tablet meta", K(ret)); + } + } else if (tablet_info.param_.tablet_id_.is_ls_inner_tablet() + && OB_FAIL(ctx_->sys_tablet_id_array_.push_back(tablet_info.param_.tablet_id_))) { + LOG_WARN("failed to push sys tablet id into array", K(ret), "array count", ctx_->sys_tablet_id_array_.count()); + } else if (!tablet_info.param_.is_empty_shell() && OB_FALSE_IT(set_tablet_to_restore(tablet_info.param_))) { + } else if (OB_FAIL(create_tablet_(tablet_info.param_, ls))) { + LOG_WARN("failed to create tablet", K(ret)); + } else { + ++tablet_cnt; + } } } } + + free_copy_ls_view_reader_(reader); } return ret; } @@ -1094,11 +1119,10 @@ int ObStartLSRestoreTask::update_ls_meta_() int ObStartLSRestoreTask::generate_tablets_restore_dag_() { - //TODO(muwei.y) It is same with other generate dag, can it be using same function? + //TODO(muwei.y) It is same with other generate dag, can it be using same function in 4.3 int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; ObSysTabletsRestoreDag *sys_tablets_restore_dag = nullptr; - ObDataTabletsMetaRestoreDag *data_tablets_meta_restore_dag = nullptr; ObTenantDagScheduler *scheduler = nullptr; ObIDagNet *dag_net = nullptr; ObStartLSRestoreDag *start_ls_restore_dag = nullptr; @@ -1118,50 +1142,24 @@ int ObStartLSRestoreTask::generate_tablets_restore_dag_() } else { if (OB_FAIL(scheduler->alloc_dag(sys_tablets_restore_dag))) { LOG_WARN("failed to alloc sys tablets restore dag ", K(ret)); - } else if (OB_FAIL(scheduler->alloc_dag(data_tablets_meta_restore_dag))) { - LOG_WARN("failed to alloc data tablets meta restore dag ", K(ret)); } else if (OB_FAIL(sys_tablets_restore_dag->init(dag_net))) { LOG_WARN("failed to init sys tablets restore dag", K(ret), K(*ctx_)); - } else if (OB_FAIL(data_tablets_meta_restore_dag->init(dag_net))) { - LOG_WARN("failed to init data tablets meta restore dag", K(ret), K(*ctx_)); } else if (OB_FAIL(this->get_dag()->add_child(*sys_tablets_restore_dag))) { LOG_WARN("failed to add sys tablets restore dag as chilid", K(ret), K(*ctx_)); } else if (OB_FAIL(sys_tablets_restore_dag->create_first_task())) { LOG_WARN("failed to create first task", K(ret)); - } else if (OB_FAIL(sys_tablets_restore_dag->add_child(*data_tablets_meta_restore_dag))) { - LOG_WARN("failed to add child dag", K(ret), K(*ctx_)); - } else if (OB_FAIL(data_tablets_meta_restore_dag->create_first_task())) { - LOG_WARN("failed to create first task", K(ret)); } else if (OB_FAIL(scheduler->add_dag(sys_tablets_restore_dag))) { LOG_WARN("failed to add sys tablets restore dag", K(ret), K(*sys_tablets_restore_dag)); if (OB_SIZE_OVERFLOW != ret && OB_EAGAIN != ret) { LOG_WARN("Fail to add task", K(ret)); ret = OB_EAGAIN; } - } else if (OB_FAIL(scheduler->add_dag(data_tablets_meta_restore_dag))) { - LOG_WARN("failed to add data tablets meta restore dag", K(ret), K(*data_tablets_meta_restore_dag)); - if (OB_SIZE_OVERFLOW != ret && OB_EAGAIN != ret) { - LOG_WARN("Fail to add task", K(ret)); - ret = OB_EAGAIN; - } - if (OB_SUCCESS != (tmp_ret = scheduler->cancel_dag(sys_tablets_restore_dag, start_ls_restore_dag))) { - LOG_WARN("failed to cancel ha dag", K(tmp_ret), KPC(start_ls_restore_dag)); - } else { - sys_tablets_restore_dag = nullptr; - } } else { - LOG_INFO("succeed to schedule sys tablets restore dag and data tablets meta restore dag", - K(*sys_tablets_restore_dag), K(*data_tablets_meta_restore_dag)); + LOG_INFO("succeed to schedule sys tablets restore dag", K(*sys_tablets_restore_dag)); sys_tablets_restore_dag = nullptr; - data_tablets_meta_restore_dag = nullptr; } if (OB_FAIL(ret)) { - if (OB_NOT_NULL(scheduler) && OB_NOT_NULL(data_tablets_meta_restore_dag)) { - scheduler->free_dag(*data_tablets_meta_restore_dag, start_ls_restore_dag); - data_tablets_meta_restore_dag = nullptr; - } - if (OB_NOT_NULL(scheduler) && OB_NOT_NULL(sys_tablets_restore_dag)) { scheduler->free_dag(*sys_tablets_restore_dag, start_ls_restore_dag); sys_tablets_restore_dag = nullptr; @@ -1173,7 +1171,7 @@ int ObStartLSRestoreTask::generate_tablets_restore_dag_() /******************ObSysTabletsRestoreDag*********************/ ObSysTabletsRestoreDag::ObSysTabletsRestoreDag() - : ObLSRestoreDag(ObStorageHADagType::SYS_TABLETS_RETORE_DAG), + : ObLSRestoreDag(ObDagType::DAG_TYPE_SYS_TABLETS_RESTORE), is_inited_(false) { } @@ -1245,26 +1243,6 @@ int ObSysTabletsRestoreDag::create_first_task() return ret; } -int ObSysTabletsRestoreDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObLSRestoreCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("sys tablets restore dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls restore ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObSysTabletsRestoreDag : dag_net_task_id = %s, ls_id = %s, is_leader = %s, src = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->arg_.ls_id_), to_cstring(ctx->arg_.is_leader_), - to_cstring(ctx->arg_.src_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObSysTabletsRestoreTask*********************/ ObSysTabletsRestoreTask::ObSysTabletsRestoreTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -1353,10 +1331,10 @@ int ObSysTabletsRestoreTask::process() return ret; } +//TODO(zeyong) check need to create or update anyway int ObSysTabletsRestoreTask::create_or_update_tablets_() { int ret = OB_SUCCESS; - if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("sys tablets restore task do not init", K(ret)); @@ -1383,11 +1361,12 @@ int ObSysTabletsRestoreTask::generate_sys_tablet_restore_dag_() { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; - ObArray tablet_restore_dag_array; + ObArray tablet_restore_dag_array; ObTenantDagScheduler *scheduler = nullptr; ObIDagNet *dag_net = nullptr; const ObTabletRestoreAction::ACTION action = ObTabletRestoreAction::RESTORE_ALL; ObSysTabletsRestoreDag *sys_tablets_restore_dag = nullptr; + ObIDag *parent = nullptr; if (!is_inited_) { ret = OB_NOT_INIT; @@ -1401,8 +1380,10 @@ int ObSysTabletsRestoreTask::generate_sys_tablet_restore_dag_() } else if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret)); + } else if (OB_FALSE_IT(parent = this->get_dag())) { + } else if (OB_FAIL(tablet_restore_dag_array.push_back(parent))) { + LOG_WARN("failed to push sys_tablets_restore_dag into array", K(ret), K(*ctx_)); } else { - ObIDag *parent = this->get_dag(); for (int64_t i = 0; OB_SUCC(ret) && i < ctx_->sys_tablet_id_array_.count(); ++i) { const ObTabletID &tablet_id = ctx_->sys_tablet_id_array_.at(i); ObTabletRestoreDag *tablet_restore_dag = nullptr; @@ -1423,6 +1404,8 @@ int ObSysTabletsRestoreTask::generate_sys_tablet_restore_dag_() LOG_WARN("init tablet restore param is invalid", K(ret), K(param), KPC(ctx_)); } else if (OB_FAIL(scheduler->alloc_dag(tablet_restore_dag))) { LOG_WARN("failed to alloc tablet restore dag", K(ret)); + } else if (OB_FAIL(tablet_restore_dag_array.push_back(tablet_restore_dag))) { + LOG_WARN("failed to push tablet restore dag into array", K(ret), K(*ctx_)); } else if (OB_FAIL(tablet_restore_dag->init(param))) { LOG_WARN("failed to init tablet restore dag", K(ret), K(*ctx_), K(param)); } else if (OB_FAIL(parent->add_child(*tablet_restore_dag))) { @@ -1435,32 +1418,33 @@ int ObSysTabletsRestoreTask::generate_sys_tablet_restore_dag_() LOG_WARN("Fail to add task", K(ret)); ret = OB_EAGAIN; } - } else if (OB_FAIL(tablet_restore_dag_array.push_back(tablet_restore_dag))) { - LOG_WARN("failed to push tablet restore dag into array", K(ret), K(*ctx_)); } else { + LOG_INFO("succeed to schedule tablet restore dag", KPC(tablet_restore_dag)); parent = tablet_restore_dag; - LOG_INFO("succeed to schedule tablet restore dag", K(*tablet_restore_dag)); + tablet_restore_dag = nullptr; } - if (OB_FAIL(ret)) { - if (OB_NOT_NULL(tablet_restore_dag)) { - if (OB_SUCCESS != (tmp_ret = scheduler->cancel_dag(tablet_restore_dag, sys_tablets_restore_dag))) { - LOG_WARN("failed to cancel ha dag", K(tmp_ret), KPC(tablet_restore_dag)); - scheduler->free_dag(*tablet_restore_dag, sys_tablets_restore_dag); - tmp_ret = OB_SUCCESS; - } - tablet_restore_dag = nullptr; + if (OB_FAIL(ret) && OB_NOT_NULL(tablet_restore_dag)) { + // tablet_restore_dag_array is not empty. + ObIDag *last = tablet_restore_dag_array.at(tablet_restore_dag_array.count() - 1); + if (last == tablet_restore_dag) { + tablet_restore_dag_array.pop_back(); + last = tablet_restore_dag_array.at(tablet_restore_dag_array.count() - 1); } + + scheduler->free_dag(*tablet_restore_dag, last); + tablet_restore_dag = nullptr; } } + // Cancel all dags from back to front, except the first dag which is 'sys_tablets_restore_dag'. if (OB_FAIL(ret)) { - for (int64_t i = 0; i < tablet_restore_dag_array.count(); ++i) { - ObTabletRestoreDag *dag = tablet_restore_dag_array.at(i); - if (OB_SUCCESS != (tmp_ret = scheduler->cancel_dag(dag, sys_tablets_restore_dag))) { - LOG_WARN("failed to cancel ha dag", K(tmp_ret), KPC(sys_tablets_restore_dag)); - } else { - dag = nullptr; + // The i-th dag is the parent dag of (i+1)-th dag. + for (int64_t child_idx = tablet_restore_dag_array.count() - 1; child_idx > 0; child_idx--) { + if (OB_TMP_FAIL(scheduler->cancel_dag( + tablet_restore_dag_array.at(child_idx), + tablet_restore_dag_array.at(child_idx - 1)))) { + LOG_WARN("failed to cancel inner tablet restore dag", K(tmp_ret), K(child_idx)); } } tablet_restore_dag_array.reset(); @@ -1471,7 +1455,7 @@ int ObSysTabletsRestoreTask::generate_sys_tablet_restore_dag_() /******************ObDataTabletsMetaRestoreDag*********************/ ObDataTabletsMetaRestoreDag::ObDataTabletsMetaRestoreDag() - : ObLSRestoreDag(ObStorageHADagType::DATA_TABLETS_META_RESTORE_DAG), + : ObLSRestoreDag(ObDagType::DAG_TYPE_DATA_TABLETS_META_RESTORE), is_inited_(false) { } @@ -1543,26 +1527,6 @@ int ObDataTabletsMetaRestoreDag::create_first_task() return ret; } -int ObDataTabletsMetaRestoreDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObLSRestoreCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("data tablets restore dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls restore ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObDataTabletsMetaRestoreDag : dag_net_task_id = %s, ls_id = %s, is_leader = %s, src = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->arg_.ls_id_), to_cstring(ctx->arg_.is_leader_), - to_cstring(ctx->arg_.src_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObDataTabletsMetaRestoreTask*********************/ ObDataTabletsMetaRestoreTask::ObDataTabletsMetaRestoreTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -1603,7 +1567,7 @@ int ObDataTabletsMetaRestoreTask::init() LOG_WARN("data tablets meta restore dag get unexpected child node", K(ret), K(child_node_array)); } else { ObLSRestoreDag *child_dag = static_cast(child_node_array.at(0)); - if (ObStorageHADagType::FINISH_LS_RESTORE_DAG != child_dag->get_sub_type()) { + if (ObDagType::DAG_TYPE_FINISH_LS_RESTORE != child_dag->get_type()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls restore dag type is unexpected", K(ret), K(*child_dag)); } else { @@ -1750,7 +1714,7 @@ int ObDataTabletsMetaRestoreTask::generate_tablet_group_dag_() /******************ObTabletGroupMetaRestoreDag*********************/ ObTabletGroupMetaRestoreDag::ObTabletGroupMetaRestoreDag() - : ObLSRestoreDag(ObStorageHADagType::TABLET_GROUP_META_RETORE_DAG), + : ObLSRestoreDag(ObDagType::DAG_TYPE_TABLET_GROUP_META_RESTORE), is_inited_(false), tablet_id_array_(), finish_dag_(nullptr) @@ -1780,8 +1744,9 @@ int64_t ObTabletGroupMetaRestoreDag::hash() const if (NULL != ctx) { hash_value = common::murmurhash( &ctx->arg_.ls_id_, sizeof(ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); for (int64_t i = 0; i < tablet_id_array_.count(); ++i) { hash_value = common::murmurhash( &tablet_id_array_.at(i), sizeof(tablet_id_array_.at(i)), hash_value); @@ -1862,26 +1827,6 @@ int ObTabletGroupMetaRestoreDag::create_first_task() return ret; } -int ObTabletGroupMetaRestoreDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObLSRestoreCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("tablet group meta restore dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls restore ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObDataTabletsMetaRestoreDag : dag_net_task_id = %s, ls_id = %s, first_tablet_id = %s, is_leader = %s, src = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->arg_.ls_id_), to_cstring(tablet_id_array_.at(0)), - to_cstring(ctx->arg_.is_leader_), to_cstring(ctx->arg_.src_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - int ObTabletGroupMetaRestoreDag::generate_next_dag(share::ObIDag *&dag) { int ret = OB_SUCCESS; @@ -1943,13 +1888,33 @@ int ObTabletGroupMetaRestoreDag::generate_next_dag(share::ObIDag *&dag) if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; const bool need_retry = false; - if (need_set_failed_result && OB_SUCCESS != (tmp_ret = ha_dag_net_ctx_->set_result(ret, need_retry))) { + if (need_set_failed_result && OB_SUCCESS != (tmp_ret = ha_dag_net_ctx_->set_result(ret, need_retry, get_type()))) { LOG_WARN("failed to set result", K(ret), KPC(ha_dag_net_ctx_)); } } return ret; } +int ObTabletGroupMetaRestoreDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + ObLSRestoreCtx *ctx = nullptr; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet group meta restore dag do not init", K(ret)); + } else if (OB_ISNULL(ctx = get_ctx())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls restore ctx should not be NULL", K(ret), KP(ctx)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + ctx->arg_.ls_id_.id(), + static_cast(tablet_id_array_.at(0).id()), + static_cast(ctx->arg_.is_leader_), + "dag_net_task_id", to_cstring(ctx->task_id_), + "src", to_cstring(ctx->arg_.src_.get_server())))) { + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} /******************ObTabletGroupMetaRestoreTask*********************/ ObTabletGroupMetaRestoreTask::ObTabletGroupMetaRestoreTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -2080,16 +2045,42 @@ int ObTabletGroupMetaRestoreTask::create_or_update_tablet_( param.compat_mode_ = compat_mode; param.multi_version_start_ = 0; param.snapshot_version_ = 0; - param.tx_data_.tablet_status_ = ObTabletStatus::NORMAL; - if (OB_FAIL(param.ha_status_.set_restore_status(restore_status))) { + ObTabletCreateDeleteMdsUserData user_data; + user_data.tablet_status_ = ObTabletStatus::NORMAL; + + const int64_t length = user_data.get_serialize_size(); + char *buffer = static_cast(param.allocator_.alloc(length)); + int64_t pos = 0; + if (OB_ISNULL(buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret), K(length)); + } else if (OB_FAIL(user_data.serialize(buffer, length, pos))) { + LOG_WARN("failed to serialize", K(ret)); + } else { + mds::MdsDumpNode &node = param.mds_data_.tablet_status_committed_kv_.v_; + node.allocator_ = ¶m.allocator_; + node.user_data_.assign(buffer, length); + } + + if (OB_FAIL(ret)) { + if (nullptr != buffer) { + param.allocator_.free(buffer); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(param.transfer_info_.init())) { + LOG_WARN("failed to init transfer info", K(ret), K(param)); + } else if (OB_FAIL(param.ha_status_.set_restore_status(restore_status))) { LOG_WARN("failed to set restore status", K(ret), K(restore_status)); } else if (OB_FAIL(param.ha_status_.set_data_status(data_status))) { LOG_WARN("failed to set data status", K(ret), K(data_status)); } else if (OB_FAIL(ObMigrationTabletParam::construct_placeholder_storage_schema_and_medium( param.allocator_, param.storage_schema_, - param.medium_info_list_))) { + param.medium_info_list_, + param.mds_data_))) { LOG_WARN("failed to construct placeholder storage schema"); } else if (!param.is_valid()) { ret = OB_INVALID_ARGUMENT; @@ -2098,12 +2089,13 @@ int ObTabletGroupMetaRestoreTask::create_or_update_tablet_( LOG_WARN("failed to create or update tablet", K(ret), K(param)); } } + return ret; } /******************ObFinishLSRestoreDag*********************/ ObFinishLSRestoreDag::ObFinishLSRestoreDag() - : ObLSRestoreDag(ObStorageHADagType::FINISH_LS_RESTORE_DAG), + : ObLSRestoreDag(ObDagType::DAG_TYPE_FINISH_LS_RESTORE), is_inited_(false) { } @@ -2175,27 +2167,6 @@ int ObFinishLSRestoreDag::create_first_task() return ret; } -int ObFinishLSRestoreDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObLSRestoreCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("finish ls restore dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls restore ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObDataTabletsMetaRestoreDag : dag_net_task_id = %s, ls_id = %s, is_leader = %s, src = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->arg_.ls_id_), - to_cstring(ctx->arg_.is_leader_), to_cstring(ctx->arg_.src_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - - /******************ObFinishLSRestoreTask*********************/ ObFinishLSRestoreTask::ObFinishLSRestoreTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), diff --git a/src/storage/high_availability/ob_ls_restore.h b/src/storage/high_availability/ob_ls_restore.h index 848e1aaa2..d5f0f6d97 100644 --- a/src/storage/high_availability/ob_ls_restore.h +++ b/src/storage/high_availability/ob_ls_restore.h @@ -129,11 +129,12 @@ private: class ObLSRestoreDag : public ObStorageHADag { public: - explicit ObLSRestoreDag(const ObStorageHADagType sub_type); + explicit ObLSRestoreDag(const share::ObDagType::ObDagTypeEnum &dag_type); virtual ~ObLSRestoreDag(); ObLSRestoreCtx *get_ctx() const { return static_cast(ha_dag_net_ctx_); } virtual bool operator == (const share::ObIDag &other) const override; virtual int64_t hash() const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; INHERIT_TO_STRING_KV("ObStorageHADag", ObStorageHADag, KP(this)) DISALLOW_COPY_AND_ASSIGN(ObLSRestoreDag); @@ -146,7 +147,6 @@ public: virtual ~ObInitialLSRestoreDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObLSRestoreDag", ObLSRestoreDag, KP(this)); @@ -182,7 +182,6 @@ public: virtual ~ObStartLSRestoreDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObLSRestoreDag", ObLSRestoreDag, KP(this)); @@ -191,6 +190,7 @@ protected: DISALLOW_COPY_AND_ASSIGN(ObStartLSRestoreDag); }; +class ObICopyLSViewInfoReader; class ObStartLSRestoreTask : public share::ObITask { public: @@ -203,9 +203,14 @@ private: int deal_with_local_ls_(); int update_ls_meta_(); int generate_tablets_restore_dag_(); - int choose_src_(); - int choose_leader_src_(); - int choose_follower_src_(); + + int update_ls_meta_and_create_all_tablets_(); + int create_tablet_( + const ObMigrationTabletParam &tablet_meta, + ObLS *ls); + void set_tablet_to_restore(ObMigrationTabletParam &tablet_meta); + int alloc_copy_ls_view_reader_(ObICopyLSViewInfoReader *&reader); + void free_copy_ls_view_reader_(ObICopyLSViewInfoReader *&reader); int generate_tablet_id_array_( const ObIArray &tablet_id_array); private: @@ -224,7 +229,6 @@ public: virtual ~ObSysTabletsRestoreDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObLSRestoreDag", ObLSRestoreDag, KP(this)); @@ -266,7 +270,6 @@ public: virtual ~ObDataTabletsMetaRestoreDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObLSRestoreDag", ObLSRestoreDag, KP(this), KPC(ha_dag_net_ctx_)); @@ -308,8 +311,8 @@ public: virtual int64_t hash() const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; virtual int generate_next_dag(share::ObIDag *&dag); + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; int init( const common::ObIArray &tablet_id_array, @@ -354,7 +357,6 @@ public: virtual ~ObFinishLSRestoreDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObLSRestoreDag", ObLSRestoreDag, KP(this), KPC(ha_dag_net_ctx_)); diff --git a/src/storage/high_availability/ob_ls_transfer_info.cpp b/src/storage/high_availability/ob_ls_transfer_info.cpp new file mode 100644 index 000000000..b66c96497 --- /dev/null +++ b/src/storage/high_availability/ob_ls_transfer_info.cpp @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE +#include "ob_ls_transfer_info.h" + +using namespace oceanbase; +using namespace share; +using namespace storage; + + +ObLSTransferInfo::ObLSTransferInfo() + : ls_id_(TRANSFER_INIT_LS_ID), + transfer_start_scn_(share::SCN::invalid_scn()) +{ +} + +int ObLSTransferInfo::init( + const share::ObLSID &ls_id, + const share::SCN &transfer_start_scn) +{ + int ret = OB_SUCCESS; + if (!ls_id.is_valid() || !transfer_start_scn.is_valid_and_not_min()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("init transfer info get invalid agument", K(ret), K(ls_id), K(transfer_start_scn)); + } else { + ls_id_ = ls_id; + transfer_start_scn_ = transfer_start_scn; + } + return ret; +} + +void ObLSTransferInfo::reset() +{ + ls_id_.reset(); + transfer_start_scn_.reset(); +} + +bool ObLSTransferInfo::is_valid() const +{ + return ls_id_.is_valid() + && transfer_start_scn_.is_valid(); +} + +bool ObLSTransferInfo::already_enable_replay() const +{ + return !is_valid(); +} diff --git a/src/storage/high_availability/ob_ls_transfer_info.h b/src/storage/high_availability/ob_ls_transfer_info.h new file mode 100644 index 000000000..64c6f32d2 --- /dev/null +++ b/src/storage/high_availability/ob_ls_transfer_info.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2021 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 OCEABASE_STORAGE_LS_TRANSFER_INFO_ +#define OCEABASE_STORAGE_LS_TRANSFER_INFO_ + +#include "share/ob_define.h" +#include "lib/utility/ob_unify_serialize.h" +#include "share/scn.h" + +namespace oceanbase +{ +namespace storage +{ + +struct ObLSTransferInfo final +{ + OB_UNIS_VERSION(1); +public: + ObLSTransferInfo(); + ~ObLSTransferInfo() = default; + int init( + const share::ObLSID &ls_id, + const share::SCN &transfer_start_scn); + void reset(); + bool is_valid() const; + bool already_enable_replay() const; + + TO_STRING_KV(K_(ls_id), K_(transfer_start_scn)); +public: + share::ObLSID ls_id_; + share::SCN transfer_start_scn_; +private: + static const int64_t TRANSFER_INIT_LS_ID = 0; +}; + + +} +} +#endif diff --git a/src/storage/high_availability/ob_physical_copy_task.cpp b/src/storage/high_availability/ob_physical_copy_task.cpp index aab8390cb..36db30162 100644 --- a/src/storage/high_availability/ob_physical_copy_task.cpp +++ b/src/storage/high_availability/ob_physical_copy_task.cpp @@ -28,7 +28,8 @@ namespace storage /******************ObPhysicalCopyCtx*********************/ ObPhysicalCopyCtx::ObPhysicalCopyCtx() - : tenant_id_(OB_INVALID_ID), + : lock_(), + tenant_id_(OB_INVALID_ID), ls_id_(), tablet_id_(), src_info_(), @@ -36,6 +37,7 @@ ObPhysicalCopyCtx::ObPhysicalCopyCtx() svr_rpc_proxy_(nullptr), is_leader_restore_(false), restore_base_info_(nullptr), + meta_index_store_(nullptr), second_meta_index_store_(nullptr), ha_dag_(nullptr), sstable_index_builder_(nullptr), @@ -97,6 +99,7 @@ ObPhysicalCopyTaskInitParam::ObPhysicalCopyTaskInitParam() ls_(nullptr), is_leader_restore_(false), restore_base_info_(nullptr), + meta_index_store_(nullptr), second_meta_index_store_(nullptr), need_check_seq_(false), ls_rebuild_seq_(-1) @@ -160,7 +163,7 @@ ObPhysicalCopyTask::~ObPhysicalCopyTask() int ObPhysicalCopyTask::init( ObPhysicalCopyCtx *copy_ctx, - ObPhysicalCopyFinishTask *finish_task) + ObSSTableCopyFinishTask *finish_task) { int ret = OB_SUCCESS; if (is_inited_) { @@ -179,7 +182,7 @@ int ObPhysicalCopyTask::init( return ret; } -int ObPhysicalCopyTask::build_macro_block_copy_info_(ObPhysicalCopyFinishTask *finish_task) +int ObPhysicalCopyTask::build_macro_block_copy_info_(ObSSTableCopyFinishTask *finish_task) { int ret = OB_SUCCESS; @@ -204,12 +207,20 @@ int ObPhysicalCopyTask::process() ObMacroBlocksWriteCtx copied_ctx; int64_t copy_count = 0; int64_t reuse_count = 0; + ObCopyTabletStatus::STATUS status = ObCopyTabletStatus::MAX_STATUS; + ObTabletCopyFinishTask *tablet_finish_task = nullptr; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("physical copy task do not init", K(ret)); } else if (copy_ctx_->ha_dag_->get_ha_dag_net_ctx()->is_failed()) { FLOG_INFO("ha dag net is already failed, skip physical copy task", KPC(copy_ctx_)); + } else if (OB_FAIL(finish_task_->get_tablet_finish_task(tablet_finish_task))) { + LOG_WARN("failed to get tablet finish task", K(ret), KPC(copy_ctx_)); + } else if (OB_FAIL(tablet_finish_task->get_tablet_status(status))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(copy_ctx_)); + } else if (ObCopyTabletStatus::TABLET_NOT_EXIST == status) { + FLOG_INFO("tablet is not exist in src, skip physical copy task", KPC(copy_ctx_)); } else { if (copy_ctx_->tablet_id_.is_inner_tablet() || copy_ctx_->tablet_id_.is_ls_inner_tablet()) { } else { @@ -227,10 +238,21 @@ int ObPhysicalCopyTask::process() } LOG_INFO("physical copy task finish", K(ret), KPC(copy_macro_range_info_), KPC(copy_ctx_)); } + if (OB_SUCCESS != (tmp_ret = record_server_event_())) { LOG_WARN("failed to record server event", K(tmp_ret), K(ret)); } + if (OB_FAIL(ret)) { + if (OB_TABLET_NOT_EXIST == ret) { + //overwrite ret + status = ObCopyTabletStatus::TABLET_NOT_EXIST; + if (OB_FAIL(tablet_finish_task->set_tablet_status(status))) { + LOG_WARN("failed to set copy tablet status", K(ret), K(status), KPC(copy_ctx_)); + } + } + } + if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; if (OB_SUCCESS != (tmp_ret = ObStorageHADagUtils::deal_with_fo(ret, copy_ctx_->ha_dag_))) { @@ -263,9 +285,13 @@ int ObPhysicalCopyTask::fetch_macro_block_with_retry_( } if (OB_FAIL(ret)) { - copied_ctx.clear(); - retry_times++; - ob_usleep(OB_FETCH_MAJOR_BLOCK_RETRY_INTERVAL); + if (OB_TABLET_NOT_EXIST == ret) { + break; + } else { + copied_ctx.clear(); + retry_times++; + ob_usleep(OB_FETCH_MAJOR_BLOCK_RETRY_INTERVAL); + } } } } @@ -516,6 +542,9 @@ int ObPhysicalCopyTask::build_copy_macro_block_reader_init_param_( if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("physical copy task do not init", K(ret)); + } else if (OB_ISNULL(finish_task_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("finish task should not be null", K(ret)); } else { init_param.tenant_id_ = copy_ctx_->tenant_id_; init_param.ls_id_ = copy_ctx_->ls_id_; @@ -531,6 +560,7 @@ int ObPhysicalCopyTask::build_copy_macro_block_reader_init_param_( init_param.copy_macro_range_info_ = copy_macro_range_info_; init_param.need_check_seq_ = copy_ctx_->need_check_seq_; init_param.ls_rebuild_seq_ = copy_ctx_->ls_rebuild_seq_; + init_param.backfill_tx_scn_ = finish_task_->get_sstable_param()->basic_meta_.filled_tx_scn_; if (!init_param.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("copy macro block reader init param is invalid", K(ret), K(init_param)); @@ -558,8 +588,8 @@ int ObPhysicalCopyTask::record_server_event_() return ret; } -/******************ObPhysicalCopyFinishTask*********************/ -ObPhysicalCopyFinishTask::ObPhysicalCopyFinishTask() +/******************ObSSTableCopyFinishTask*********************/ +ObSSTableCopyFinishTask::ObSSTableCopyFinishTask() : ObITask(TASK_TYPE_MIGRATE_FINISH_PHYSICAL), is_inited_(false), copy_ctx_(), @@ -575,14 +605,14 @@ ObPhysicalCopyFinishTask::ObPhysicalCopyFinishTask() { } -ObPhysicalCopyFinishTask::~ObPhysicalCopyFinishTask() +ObSSTableCopyFinishTask::~ObSSTableCopyFinishTask() { if (OB_NOT_NULL(restore_macro_block_id_mgr_)) { ob_delete(restore_macro_block_id_mgr_); } } -int ObPhysicalCopyFinishTask::init( +int ObSSTableCopyFinishTask::init( const ObPhysicalCopyTaskInitParam &init_param) { int ret = OB_SUCCESS; @@ -593,7 +623,7 @@ int ObPhysicalCopyFinishTask::init( if (is_inited_) { ret = OB_INIT_TWICE; - LOG_WARN("physical copy finish task init twice", K(ret)); + LOG_WARN("sstable copy finish task init twice", K(ret)); } else if (!init_param.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("physical copy finish task init get invalid argument", K(ret), K(init_param)); @@ -641,7 +671,7 @@ int ObPhysicalCopyFinishTask::init( return ret; } -int ObPhysicalCopyFinishTask::get_macro_block_copy_info( +int ObSSTableCopyFinishTask::get_macro_block_copy_info( ObITable::TableKey ©_table_key, const ObCopyMacroRangeInfo *©_macro_range_info) { @@ -652,7 +682,7 @@ int ObPhysicalCopyFinishTask::get_macro_block_copy_info( ObMigrationFakeBlockID block_id; if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("physical copy finish task do not init", K(ret)); + LOG_WARN("sstable copy finish task do not init", K(ret)); } else { common::SpinWLockGuard guard(lock_); if (macro_range_info_index_ == sstable_macro_range_info_.copy_macro_range_array_.count()) { @@ -668,15 +698,21 @@ int ObPhysicalCopyFinishTask::get_macro_block_copy_info( return ret; } -int ObPhysicalCopyFinishTask::process() +int ObSSTableCopyFinishTask::process() { int ret = OB_SUCCESS; + ObCopyTabletStatus::STATUS status = ObCopyTabletStatus::MAX_STATUS; int tmp_ret = OB_SUCCESS; + if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("physical copy finish task do not init", K(ret)); + LOG_WARN("sstable copy finish task do not init", K(ret)); } else if (copy_ctx_.ha_dag_->get_ha_dag_net_ctx()->is_failed()) { FLOG_INFO("ha dag net is already failed, skip physical copy finish task", K(copy_ctx_)); + } else if (OB_FAIL(tablet_copy_finish_task_->get_tablet_status(status))) { + LOG_WARN("failed to get tablet status", K(ret), K(copy_ctx_)); + } else if (ObCopyTabletStatus::TABLET_NOT_EXIST == status) { + //do nothing } else if (OB_FAIL(create_sstable_())) { LOG_WARN("failed to create sstable", K(ret), K(copy_ctx_)); } else if (OB_FAIL(check_sstable_valid_())) { @@ -685,6 +721,16 @@ int ObPhysicalCopyFinishTask::process() LOG_INFO("succeed physical copy finish", K(copy_ctx_)); } + if (OB_FAIL(ret)) { + if (OB_TABLET_NOT_EXIST == ret) { + //overwrite ret + status = ObCopyTabletStatus::TABLET_NOT_EXIST; + if (OB_FAIL(tablet_copy_finish_task_->set_tablet_status(status))) { + LOG_WARN("failed to set copy tablet status", K(ret), K(copy_ctx_)); + } + } + } + if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; if (OB_SUCCESS != (tmp_ret = ObStorageHADagUtils::deal_with_fo(ret, copy_ctx_.ha_dag_))) { @@ -694,13 +740,13 @@ int ObPhysicalCopyFinishTask::process() return ret; } -int ObPhysicalCopyFinishTask::check_is_iter_end(bool &is_iter_end) +int ObSSTableCopyFinishTask::check_is_iter_end(bool &is_iter_end) { int ret = OB_SUCCESS; is_iter_end = false; if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("physical copy finish task do not init", K(ret)); + LOG_WARN("sstable copy finish task do not init", K(ret)); } else { common::SpinRLockGuard guard(lock_); if (macro_range_info_index_ == sstable_macro_range_info_.copy_macro_range_array_.count()) { @@ -712,7 +758,7 @@ int ObPhysicalCopyFinishTask::check_is_iter_end(bool &is_iter_end) return ret; } -int ObPhysicalCopyFinishTask::prepare_data_store_desc_( +int ObSSTableCopyFinishTask::prepare_data_store_desc_( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const ObMigrationSSTableParam *sstable_param, @@ -721,55 +767,51 @@ int ObPhysicalCopyFinishTask::prepare_data_store_desc_( { int ret = OB_SUCCESS; desc.reset(); - ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; ObMergeType merge_type; + ObArenaAllocator allocator; + const ObStorageSchema *storage_schema = nullptr; + ObTabletHandle tablet_handle; if (!tablet_id.is_valid() || cluster_version < 0 || OB_ISNULL(sstable_param)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("prepare sstable index builder get invalid argument", K(ret), K(tablet_id), K(cluster_version), KP(sstable_param)); } else if (OB_FAIL(get_merge_type_(sstable_param, merge_type))) { LOG_WARN("failed to get merge type", K(ret), KPC(sstable_param)); - } else if (OB_FAIL(ls_->get_tablet(tablet_id, tablet_handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_FAIL(ls_->ha_get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to do ha get tablet", K(ret), K(tablet_id)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), K(tablet_id)); - } else if (OB_FAIL(desc.init(tablet->get_storage_schema(), + } else if (OB_FAIL(tablet->load_storage_schema(allocator, storage_schema))) { + LOG_WARN("fail to load storage schema failed", K(ret)); + } else if (OB_FAIL(desc.init_as_index(*storage_schema, ls_id, tablet_id, merge_type, - tablet->get_snapshot_version(), - cluster_version))) { + tablet->get_snapshot_version()))) { LOG_WARN("failed to init index store desc", K(ret), K(tablet_id), K(merge_type), KPC(sstable_param)); } else { - const ObStorageSchema &storage_schema = tablet->get_storage_schema(); - desc.row_column_count_ = desc.rowkey_column_count_ + 1; - desc.col_desc_array_.reset(); - desc.need_prebuild_bloomfilter_ = false; - if (OB_FAIL(desc.col_desc_array_.init(desc.row_column_count_))) { - LOG_WARN("failed to reserve column desc array", K(ret)); - } else if (OB_FAIL(storage_schema.get_rowkey_column_ids(desc.col_desc_array_))) { - LOG_WARN("failed to get rowkey column ids", K(ret)); - } else if (OB_FAIL(ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(desc.col_desc_array_))) { - LOG_WARN("failed to get extra rowkey column ids", K(ret)); + /* Since the storage_schema of migration maybe newer or older than the original sstable, + we always use the col_cnt in sstable_param to re-generate sstable for dst. + Besides, we fill default chksum array with zeros since there's no need to recalculate*/ + desc.full_stored_col_cnt_ = sstable_param->basic_meta_.column_cnt_; + desc.col_default_checksum_array_.reset(); + if (OB_FAIL(desc.col_default_checksum_array_.init(desc.full_stored_col_cnt_))) { + LOG_WARN("fail to init col default chksum array", K(ret)); } else { - ObObjMeta meta; - meta.set_varchar(); - meta.set_collation_type(CS_TYPE_BINARY); - share::schema::ObColDesc col; - col.col_id_ = static_cast(desc.row_column_count_ + OB_APP_MIN_COLUMN_ID); - col.col_type_ = meta; - col.col_order_ = DESC; - if (OB_FAIL(desc.col_desc_array_.push_back(col))) { - LOG_WARN("failed to push back last col for index", K(ret), K(col)); + for (int64_t i = 0; OB_SUCC(ret) && i < desc.full_stored_col_cnt_; ++i) { + if (OB_FAIL(desc.col_default_checksum_array_.push_back(0))) { + LOG_WARN("fail to push default checksum", K(ret), K(i), K(desc)); + } } } } + ObTablet::free_storage_schema(allocator, storage_schema); return ret; } -int ObPhysicalCopyFinishTask::get_cluster_version_( +int ObSSTableCopyFinishTask::get_cluster_version_( const ObPhysicalCopyTaskInitParam &init_param, int64_t &cluster_version) { @@ -794,7 +836,7 @@ int ObPhysicalCopyFinishTask::get_cluster_version_( return ret; } -int ObPhysicalCopyFinishTask::prepare_sstable_index_builder_( +int ObSSTableCopyFinishTask::prepare_sstable_index_builder_( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const ObMigrationSSTableParam *sstable_param, @@ -822,7 +864,7 @@ int ObPhysicalCopyFinishTask::prepare_sstable_index_builder_( return ret; } -int ObPhysicalCopyFinishTask::get_merge_type_( +int ObSSTableCopyFinishTask::get_merge_type_( const ObMigrationSSTableParam *sstable_param, ObMergeType &merge_type) { @@ -845,12 +887,12 @@ int ObPhysicalCopyFinishTask::get_merge_type_( return ret; } -int ObPhysicalCopyFinishTask::create_sstable_() +int ObSSTableCopyFinishTask::create_sstable_() { int ret = OB_SUCCESS; if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("physical copy finish task do not init", K(ret)); + LOG_WARN("sstable copy finish task do not init", K(ret)); } else if (0 == sstable_param_->basic_meta_.data_macro_block_count_) { //create empty sstable if (OB_FAIL(create_empty_sstable_())) { @@ -864,7 +906,7 @@ int ObPhysicalCopyFinishTask::create_sstable_() return ret; } -int ObPhysicalCopyFinishTask::create_empty_sstable_() +int ObSSTableCopyFinishTask::create_empty_sstable_() { int ret = OB_SUCCESS; ObTableHandleV2 table_handle; @@ -872,10 +914,11 @@ int ObPhysicalCopyFinishTask::create_empty_sstable_() if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("physical copy finish task do not init", K(ret)); + LOG_WARN("sstable copy finish task do not init", K(ret)); } else if (OB_FAIL(build_create_sstable_param_(param))) { LOG_WARN("failed to build create sstable param", K(ret)); - } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, table_handle))) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable_for_migrate(param, + tablet_copy_finish_task_->get_allocator(), table_handle))) { LOG_WARN("failed to create sstable", K(ret), K(param), K(copy_ctx_)); } else if (OB_FAIL(tablet_copy_finish_task_->add_sstable(table_handle))) { LOG_WARN("failed to add table handle", K(ret), K(table_handle), K(copy_ctx_)); @@ -883,7 +926,7 @@ int ObPhysicalCopyFinishTask::create_empty_sstable_() return ret; } -int ObPhysicalCopyFinishTask::create_sstable_with_index_builder_() +int ObSSTableCopyFinishTask::create_sstable_with_index_builder_() { int ret = OB_SUCCESS; ObTabletHandle tablet_handle; @@ -895,24 +938,23 @@ int ObPhysicalCopyFinishTask::create_sstable_with_index_builder_() if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("physical copy finish task do not init", K(ret)); + LOG_WARN("sstable copy finish task do not init", K(ret)); } else { SMART_VAR(ObTabletCreateSSTableParam, param) { //TODO(lingchuan) column_count should not be in parameters if (OB_FAIL(get_merge_type_(sstable_param_, merge_type))) { LOG_WARN("failed to get merge type", K(ret), K(copy_ctx_)); - } else if (OB_FAIL(ls_->get_tablet(copy_ctx_.tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls_->ha_get_tablet(copy_ctx_.tablet_id_, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(copy_ctx_)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), K(copy_ctx_)); - } else if (FALSE_IT(column_count = sstable_param_->basic_meta_.column_cnt_)) { - } else if (OB_FAIL(sstable_index_builder_.close(column_count, res))) { - LOG_WARN("failed to close sstable index builder", K(ret), K(column_count), K(copy_ctx_)); + } else if (OB_FAIL(sstable_index_builder_.close(res))) { + LOG_WARN("failed to close sstable index builder", K(ret), K(copy_ctx_)); } else if (OB_FAIL(build_create_sstable_param_(tablet, res, param))) { LOG_WARN("failed to build create sstable param", K(ret), K(copy_ctx_)); - } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, table_handle))) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable_for_migrate(param, + tablet_copy_finish_task_->get_allocator(), table_handle))) { LOG_WARN("failed to create sstable", K(ret), K(copy_ctx_), KPC(sstable_param_)); } else if (OB_FAIL(tablet_copy_finish_task_->add_sstable(table_handle))) { LOG_WARN("failed to add table handle", K(ret), K(table_handle), K(copy_ctx_)); @@ -922,7 +964,8 @@ int ObPhysicalCopyFinishTask::create_sstable_with_index_builder_() return ret; } -int ObPhysicalCopyFinishTask::build_create_sstable_param_( + +int ObSSTableCopyFinishTask::build_create_sstable_param_( ObTablet *tablet, const blocksstable::ObSSTableMergeRes &res, ObTabletCreateSSTableParam ¶m) @@ -931,12 +974,11 @@ int ObPhysicalCopyFinishTask::build_create_sstable_param_( int ret = OB_SUCCESS; if (!is_inited_) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("physical copy finish task do not init", K(ret)); + LOG_WARN("sstable copy finish task do not init", K(ret)); } else if (OB_UNLIKELY(OB_ISNULL(tablet) || !res.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("build create sstable param get invalid argument", K(ret), KP(tablet), K(res)); } else { - const ObStorageSchema &storage_schema = tablet->get_storage_schema(); param.table_key_ = sstable_param_->table_key_; param.sstable_logic_seq_ = sstable_param_->basic_meta_.sstable_logic_seq_; param.schema_version_ = sstable_param_->basic_meta_.schema_version_; @@ -975,17 +1017,14 @@ int ObPhysicalCopyFinishTask::build_create_sstable_param_( param.rowkey_column_cnt_ = sstable_param_->basic_meta_.rowkey_column_count_; param.ddl_scn_ = sstable_param_->basic_meta_.ddl_scn_; MEMCPY(param.encrypt_key_, res.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); - if (param.table_key_.is_major_sstable() || param.table_key_.is_ddl_dump_sstable()) { - if (OB_FAIL(res.fill_column_checksum(sstable_param_->column_default_checksums_, - param.column_checksums_))) { - LOG_WARN("fail to fill column checksum", K(ret), K(res)); - } + if (OB_FAIL(param.column_checksums_.assign(sstable_param_->column_checksums_))) { + LOG_WARN("fail to fill column checksum", K(ret), KPC_(sstable_param)); } } return ret; } -int ObPhysicalCopyFinishTask::build_create_sstable_param_( +int ObSSTableCopyFinishTask::build_create_sstable_param_( ObTabletCreateSSTableParam ¶m) { //TODO(lingchuan) this param maker ObTablet class will be better to be safeguard @@ -993,7 +1032,7 @@ int ObPhysicalCopyFinishTask::build_create_sstable_param_( int ret = OB_SUCCESS; if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("phyiscal copy finish task do not init", K(ret)); + LOG_WARN("sstable copy finish task do not init", K(ret)); } else if (0 != sstable_param_->basic_meta_.data_macro_block_count_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sstable param has data macro block, can not build sstable from basic meta", K(ret), KPC(sstable_param_)); @@ -1036,7 +1075,7 @@ int ObPhysicalCopyFinishTask::build_create_sstable_param_( return ret; } -int ObPhysicalCopyFinishTask::build_restore_macro_block_id_mgr_( +int ObSSTableCopyFinishTask::build_restore_macro_block_id_mgr_( const ObPhysicalCopyTaskInitParam &init_param) { int ret = OB_SUCCESS; @@ -1050,7 +1089,7 @@ int ObPhysicalCopyFinishTask::build_restore_macro_block_id_mgr_( ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("failed to alloc memory", K(ret), KP(buf)); } else if (FALSE_IT(restore_macro_block_id_mgr = new(buf) ObRestoreMacroBlockIdMgr())) { - } else if (OB_FAIL(restore_macro_block_id_mgr->init(init_param.ls_id_, init_param.tablet_id_, + } else if (OB_FAIL(restore_macro_block_id_mgr->init(init_param.tablet_id_, init_param.sstable_macro_range_info_.copy_table_key_, *init_param.restore_base_info_, *init_param.second_meta_index_store_))) { STORAGE_LOG(WARN, "failed to init restore macro block id mgr", K(ret), K(init_param)); @@ -1075,15 +1114,16 @@ int ObPhysicalCopyFinishTask::build_restore_macro_block_id_mgr_( return ret; } -int ObPhysicalCopyFinishTask::check_sstable_valid_() +int ObSSTableCopyFinishTask::check_sstable_valid_() { int ret = OB_SUCCESS; ObTableHandleV2 table_handle; + ObSSTableMetaHandle sst_meta_hdl; ObSSTable *sstable = nullptr; if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("phyiscal copy finish task do not init", K(ret)); + LOG_WARN("sstable copy finish task do not init", K(ret)); } else if (OB_FAIL(tablet_copy_finish_task_->get_sstable(sstable_param_->table_key_, table_handle))) { LOG_WARN("failed to get sstable", K(ret), KPC(sstable_param_)); } else if (OB_FAIL(table_handle.get_sstable(sstable))) { @@ -1091,13 +1131,15 @@ int ObPhysicalCopyFinishTask::check_sstable_valid_() } else if (OB_ISNULL(sstable)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sstable should not be NULL", K(ret), KP(sstable), KPC(sstable_param_)); - } else if (OB_FAIL(check_sstable_meta_(*sstable_param_, sstable->get_meta()))) { + } else if (OB_FAIL(sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); + } else if (OB_FAIL(check_sstable_meta_(*sstable_param_, sst_meta_hdl.get_sstable_meta()))) { LOG_WARN("failed to check sstable meta", K(ret), KPC(sstable), KPC(sstable_param_)); } return ret; } -int ObPhysicalCopyFinishTask::check_sstable_meta_( +int ObSSTableCopyFinishTask::check_sstable_meta_( const ObMigrationSSTableParam &src_meta, const ObSSTableMeta &write_meta) { @@ -1105,7 +1147,7 @@ int ObPhysicalCopyFinishTask::check_sstable_meta_( if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("phyiscal copy finish task do not init", K(ret)); + LOG_WARN("sstable copy finish task do not init", K(ret)); } else if (!src_meta.is_valid() || !write_meta.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("check sstable meta get invalid argument", K(ret), K(src_meta), K(write_meta)); @@ -1115,6 +1157,20 @@ int ObPhysicalCopyFinishTask::check_sstable_meta_( return ret; } +int ObSSTableCopyFinishTask::get_tablet_finish_task(ObTabletCopyFinishTask *&finish_task) +{ + int ret = OB_SUCCESS; + finish_task = 0; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("sstable copy finish task do not init", K(ret)); + } else { + finish_task = tablet_copy_finish_task_; + } + return ret; +} + /******************ObTabletCopyFinishTask*********************/ ObTabletCopyFinishTask::ObTabletCopyFinishTask() : ObITask(TASK_TYPE_MIGRATE_FINISH_PHYSICAL), @@ -1124,11 +1180,13 @@ ObTabletCopyFinishTask::ObTabletCopyFinishTask() ls_(nullptr), reporter_(nullptr), ha_dag_(nullptr), + arena_allocator_("TabCopyFinish"), minor_tables_handle_(), ddl_tables_handle_(), major_tables_handle_(), restore_action_(ObTabletRestoreAction::MAX), - src_tablet_meta_(nullptr) + src_tablet_meta_(nullptr), + status_(ObCopyTabletStatus::MAX_STATUS) { } @@ -1160,6 +1218,7 @@ int ObTabletCopyFinishTask::init( ha_dag_ = static_cast(this->get_dag()); restore_action_ = restore_action; src_tablet_meta_ = src_tablet_meta; + status_ = ObCopyTabletStatus::TABLET_EXIST; is_inited_ = true; } return ret; @@ -1169,11 +1228,17 @@ int ObTabletCopyFinishTask::process() { int ret = OB_SUCCESS; bool only_contain_major = false; + ObCopyTabletStatus::STATUS status = ObCopyTabletStatus::MAX_STATUS; + if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet copy finish task do not init", K(ret)); } else if (ha_dag_->get_ha_dag_net_ctx()->is_failed()) { FLOG_INFO("ha dag net is already failed, skip physical copy finish task", K(tablet_id_), KPC(ha_dag_)); + } else if (OB_FAIL(get_tablet_status(status))) { + LOG_WARN("failed to get tablet status", K(ret), K(tablet_id_)); + } else if (ObCopyTabletStatus::TABLET_NOT_EXIST == status) { + FLOG_INFO("copy tablet from src do not exist, skip copy finish task", K(tablet_id_), K(status)); } else if (OB_FAIL(create_new_table_store_with_major_())) { LOG_WARN("failed to create new table store with major", K(ret), K_(tablet_id)); } else if (OB_FAIL(create_new_table_store_with_ddl_())) { @@ -1188,6 +1253,21 @@ int ObTabletCopyFinishTask::process() LOG_WARN("failed to update tablet data status", K(ret), K(tablet_id_)); } + if (OB_FAIL(ret)) { + if (OB_TABLET_NOT_EXIST == ret) { + FLOG_INFO("tablet is not exist, skip copy tablet", K(tablet_id_)); + //overwrite ret + ret = OB_SUCCESS; + } + } + + SERVER_EVENT_ADD("storage_ha", "tablet_copy_finish_task", + "tenant_id", MTL_ID(), + "ls_id", ls_->get_ls_id().id(), + "tablet_id", tablet_id_.id(), + "ret", ret, + "result", ha_dag_->get_ha_dag_net_ctx()->is_failed()); + if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; if (OB_SUCCESS != (tmp_ret = ObStorageHADagUtils::deal_with_fo(ret, ha_dag_))) { @@ -1238,17 +1318,13 @@ int ObTabletCopyFinishTask::get_sstable( } else if (OB_FAIL(get_tables_handle_ptr_(table_key, tables_handle_ptr))) { LOG_WARN("failed to get tables handle ptr", K(ret), K(table_key)); } else { + ObTableHandleV2 tmp_table_handle; for (int64_t i = 0; OB_SUCC(ret) && i < tables_handle_ptr->get_count() && !found; ++i) { - ObITable *table = tables_handle_ptr->get_table(i); - if (OB_ISNULL(table)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table should not be NULL", K(ret), KP(table)); - } else if (table->get_key() == table_key) { - if (OB_FAIL(table_handle.set_table(table, meta_mem_mgr, table_key.table_type_))) { - LOG_WARN("failed to set table", K(ret), KPC(table), K(table_key)); - } else { - found = true; - } + if (OB_FAIL(tables_handle_ptr->get_table(i, tmp_table_handle))) { + LOG_WARN("failed to get table handle", K(ret), K(i)); + } else if (tmp_table_handle.get_table()->get_key() == table_key) { + table_handle = tmp_table_handle; + found = true; } } @@ -1312,14 +1388,14 @@ int ObTabletCopyFinishTask::update_tablet_data_status_() int ret = OB_SUCCESS; ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; + ObTabletMemberWrapper table_store_wrapper; const ObTabletDataStatus::STATUS data_status = ObTabletDataStatus::COMPLETE; bool is_logical_sstable_exist = false; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet copy finish task do not init", K(ret)); - } else if (OB_FAIL(ls_->get_tablet(tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls_->ha_get_tablet(tablet_id_, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id_)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; @@ -1330,15 +1406,18 @@ int ObTabletCopyFinishTask::update_tablet_data_status_() } else if (tablet->get_tablet_meta().ha_status_.is_data_status_complete()) { //do nothing } else if (OB_FAIL(ObStorageHATabletBuilderUtil::check_remote_logical_sstable_exist(tablet, is_logical_sstable_exist))) { - LOG_WARN("failedto check remote logical sstable exist", K(ret), KPC(tablet)); + LOG_WARN("failed to check remote logical sstable exist", K(ret), KPC(tablet)); } else if (is_logical_sstable_exist && tablet->get_tablet_meta().ha_status_.is_restore_status_full()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet still has remote logical sstable, unexpected !!!", K(ret), KPC(tablet)); + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - const ObSSTableArray &major_sstables = tablet->get_table_store().get_major_sstables(); + const ObSSTableArray &major_sstables = table_store_wrapper.get_member()->get_major_sstables(); if (OB_SUCC(ret) && tablet->get_tablet_meta().table_store_flag_.with_major_sstable() && tablet->get_tablet_meta().ha_status_.is_restore_status_full() + && !tablet->get_tablet_meta().has_transfer_table() && major_sstables.empty()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should has major sstable, unexpected", K(ret), KPC(tablet), K(major_sstables)); @@ -1358,6 +1437,8 @@ int ObTabletCopyFinishTask::update_tablet_data_status_() LOG_INFO("tablet is in restore status, do not update data stauts is full", K(ret), K(tablet_id_)); } else if (OB_FAIL(ls_->update_tablet_ha_data_status(tablet_id_, data_status))) { LOG_WARN("[HA]failed to update tablet ha data status", K(ret), K(tablet_id_), K(data_status)); + } else { + LOG_INFO("update tablet ha data status", K_(tablet_id), K(data_status)); } } @@ -1408,8 +1489,7 @@ int ObTabletCopyFinishTask::trim_tablet_() if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet copy finish task do not init", K(ret)); - } else if (OB_FAIL(ls_->get_tablet(tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls_->ha_get_tablet(tablet_id_, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id_)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; @@ -1421,17 +1501,33 @@ int ObTabletCopyFinishTask::trim_tablet_() return ret; } +int ObTabletCopyFinishTask::set_tablet_status(const ObCopyTabletStatus::STATUS &status) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet copy finish task do not init", K(ret)); + } else if (!ObCopyTabletStatus::is_valid(status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("set tablet status get invalid argument", K(ret), K(status)); + } else { + common::SpinWLockGuard guard(lock_); + status_ = status; + } + return ret; +} + int ObTabletCopyFinishTask::check_tablet_valid_() { int ret = OB_SUCCESS; ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; - const int64_t timeout_us = ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet finish restore task do not init", K(ret)); - } else if (OB_FAIL(ls_->get_tablet(tablet_id_, tablet_handle, timeout_us))) { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id_), K(timeout_us)); + } else if (OB_FAIL(ls_->get_tablet(tablet_id_, tablet_handle, + ObTabletCommon::DEFAULT_GET_TABLET_NO_WAIT, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id_)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_id_)); @@ -1441,6 +1537,20 @@ int ObTabletCopyFinishTask::check_tablet_valid_() return ret; } +int ObTabletCopyFinishTask::get_tablet_status(ObCopyTabletStatus::STATUS &status) +{ + int ret = OB_SUCCESS; + status = ObCopyTabletStatus::MAX_STATUS; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet copy finish task do not init", K(ret)); + } else { + common::SpinRLockGuard guard(lock_); + status = status_; + } + return ret; +} + } } diff --git a/src/storage/high_availability/ob_physical_copy_task.h b/src/storage/high_availability/ob_physical_copy_task.h index 15d6d1506..806a5fa26 100644 --- a/src/storage/high_availability/ob_physical_copy_task.h +++ b/src/storage/high_availability/ob_physical_copy_task.h @@ -40,10 +40,12 @@ struct ObPhysicalCopyCtx virtual ~ObPhysicalCopyCtx(); bool is_valid() const; void reset(); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(tablet_id), K_(src_info), KP_(bandwidth_throttle), KP_(svr_rpc_proxy), K_(is_leader_restore), KP_(restore_base_info), KP_(meta_index_store), KP_(second_meta_index_store), KP_(ha_dag), - KP_(sstable_index_builder), KP_(restore_macro_block_id_mgr)); + KP_(sstable_index_builder), KP_(restore_macro_block_id_mgr), K_(need_check_seq), K_(ls_rebuild_seq)); + common::SpinRWLock lock_; uint64_t tenant_id_; share::ObLSID ls_id_; common::ObTabletID tablet_id_; @@ -90,7 +92,7 @@ struct ObPhysicalCopyTaskInitParam final DISALLOW_COPY_AND_ASSIGN(ObPhysicalCopyTaskInitParam); }; -class ObPhysicalCopyFinishTask; +class ObSSTableCopyFinishTask; class ObPhysicalCopyTask : public share::ObITask { public: @@ -98,7 +100,7 @@ public: virtual ~ObPhysicalCopyTask(); int init( ObPhysicalCopyCtx *copy_ctx, - ObPhysicalCopyFinishTask *finish_task); + ObSSTableCopyFinishTask *finish_task); virtual int process() override; virtual int generate_next_task(ObITask *&next_task) override; VIRTUAL_TO_STRING_KV(K("ObPhysicalCopyFinishTask"), KP(this), KPC(copy_ctx_)); @@ -108,7 +110,7 @@ private: int fetch_macro_block_( const int64_t retry_times, ObMacroBlocksWriteCtx &copied_ctx); - int build_macro_block_copy_info_(ObPhysicalCopyFinishTask *finish_task); + int build_macro_block_copy_info_(ObSSTableCopyFinishTask *finish_task); int get_macro_block_reader_( ObICopyMacroBlockReader *&reader); int get_macro_block_ob_reader_( @@ -132,28 +134,29 @@ private: static const int64_t OB_FETCH_MAJOR_BLOCK_RETRY_INTERVAL = 1 * 1000 * 1000L;// 1s bool is_inited_; ObPhysicalCopyCtx *copy_ctx_; - ObPhysicalCopyFinishTask *finish_task_; + ObSSTableCopyFinishTask *finish_task_; ObITable::TableKey copy_table_key_; const ObCopyMacroRangeInfo *copy_macro_range_info_; - DISALLOW_COPY_AND_ASSIGN(ObPhysicalCopyTask); }; -class ObPhysicalCopyFinishTask : public share::ObITask +class ObSSTableCopyFinishTask : public share::ObITask { public: - ObPhysicalCopyFinishTask(); - virtual ~ObPhysicalCopyFinishTask(); + ObSSTableCopyFinishTask(); + virtual ~ObSSTableCopyFinishTask(); int init( const ObPhysicalCopyTaskInitParam &init_param); virtual int process() override; ObPhysicalCopyCtx *get_copy_ctx() { return ©_ctx_; } + const ObMigrationSSTableParam *get_sstable_param() { return sstable_param_; } int get_macro_block_copy_info( ObITable::TableKey ©_table_key, const ObCopyMacroRangeInfo *©_macro_range_info); int check_is_iter_end(bool &is_end); + int get_tablet_finish_task(ObTabletCopyFinishTask *&finish_task); - VIRTUAL_TO_STRING_KV(K("ObPhysicalCopyFinishTask"), KP(this), K(copy_ctx_)); + VIRTUAL_TO_STRING_KV(K("ObSSTableCopyFinishTask"), KP(this), K(copy_ctx_)); private: int get_cluster_version_( @@ -202,7 +205,7 @@ private: ObLSTabletService *tablet_service_; ObSSTableIndexBuilder sstable_index_builder_; ObRestoreMacroBlockIdMgr *restore_macro_block_id_mgr_; - DISALLOW_COPY_AND_ASSIGN(ObPhysicalCopyFinishTask); + DISALLOW_COPY_AND_ASSIGN(ObSSTableCopyFinishTask); }; class ObTabletCopyFinishTask : public share::ObITask @@ -222,6 +225,10 @@ public: int get_sstable( const ObITable::TableKey &table_key, ObTableHandleV2 &table_handle); + common::ObArenaAllocator &get_allocator() { return arena_allocator_; } // TODO: @jinzhu remove me later. + int set_tablet_status(const ObCopyTabletStatus::STATUS &status); + int get_tablet_status(ObCopyTabletStatus::STATUS &status); + private: int create_new_table_store_with_major_(); int create_new_table_store_with_ddl_(); @@ -241,11 +248,13 @@ private: ObLS *ls_; observer::ObIMetaReport *reporter_; ObStorageHADag *ha_dag_; + common::ObArenaAllocator arena_allocator_; ObTablesHandleArray minor_tables_handle_; ObTablesHandleArray ddl_tables_handle_; ObTablesHandleArray major_tables_handle_; ObTabletRestoreAction::ACTION restore_action_; const ObMigrationTabletParam *src_tablet_meta_; + storage::ObCopyTabletStatus::STATUS status_; DISALLOW_COPY_AND_ASSIGN(ObTabletCopyFinishTask); }; diff --git a/src/storage/high_availability/ob_rebuild_service.cpp b/src/storage/high_availability/ob_rebuild_service.cpp new file mode 100644 index 000000000..7d3a1913c --- /dev/null +++ b/src/storage/high_availability/ob_rebuild_service.cpp @@ -0,0 +1,1098 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE +#include "ob_rebuild_service.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "share/ls/ob_ls_table_operator.h" +#include "lib/utility/ob_tracepoint.h" +#include "rootserver/ob_rs_event_history_table_operator.h" +#include "observer/ob_server.h" +#include "logservice/ob_log_service.h" + +using namespace oceanbase; +using namespace share; +using namespace storage; + +ObLSRebuildCtx::ObLSRebuildCtx() + : ls_id_(), + type_(), + task_id_() +{ +} + +void ObLSRebuildCtx::reset() +{ + ls_id_.reset(); + type_ = ObLSRebuildType::MAX; + task_id_.reset(); +} + +bool ObLSRebuildCtx::is_valid() const +{ + return ls_id_.is_valid() + && type_.is_valid() + && !task_id_.is_invalid(); +} + +int ObLSRebuildInfoHelper::get_next_rebuild_info( + const ObLSRebuildInfo &curr_info, + const ObLSRebuildType &rebuild_type, + const int32_t result, + ObLSRebuildInfo &next_info) +{ + int ret = OB_SUCCESS; + next_info.reset(); + + if (!curr_info.is_valid() || !rebuild_type.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get next change status get invalid argument", K(ret), K(curr_info), K(rebuild_type)); + } else { + switch (curr_info.status_) { + case ObLSRebuildStatus::NONE: { + if (OB_SUCCESS == result) { + next_info.status_ = ObLSRebuildStatus::INIT; + next_info.type_ = rebuild_type; + } else { + next_info = curr_info; + } + break; + } + case ObLSRebuildStatus::INIT: { + if (OB_SUCCESS == result) { + next_info.status_ = ObLSRebuildStatus::DOING; + next_info.type_ = rebuild_type; + } else { + next_info.status_ = ObLSRebuildStatus::CLEANUP; + next_info.type_ = rebuild_type; + } + break; + } + case ObLSRebuildStatus::DOING: { + if (OB_SUCCESS == result) { + next_info.status_ = ObLSRebuildStatus::CLEANUP; + next_info.type_ = rebuild_type; + } else { + next_info.status_ = ObLSRebuildStatus::DOING; + next_info.type_ = rebuild_type; + } + break; + } + case ObLSRebuildStatus::CLEANUP: { + if (OB_SUCCESS == result) { + next_info.status_ = ObLSRebuildStatus::NONE; + next_info.type_ = ObLSRebuildType::NONE; + } else { + next_info.status_ = ObLSRebuildStatus::CLEANUP; + next_info.type_ = rebuild_type; + } + break; + } + default: { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid curr info for fail", K(ret), K(curr_info)); + } + } + } + return ret; +} + +int ObLSRebuildInfoHelper::check_can_change_info( + const ObLSRebuildInfo &old_info, + const ObLSRebuildInfo &new_info, + bool &can_change) +{ + int ret = OB_SUCCESS; + can_change = false; + if (!old_info.is_valid() || !new_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check can change status get invalid argument", K(ret), K(old_info), K(new_info)); + }else { + switch (old_info.status_) { + case ObLSRebuildStatus::NONE: { + if (ObLSRebuildStatus::NONE == new_info.status_ + || ObLSRebuildStatus::INIT == new_info.status_) { + can_change = true; + } + break; + } + case ObLSRebuildStatus::INIT: { + if (ObLSRebuildStatus::INIT == new_info.status_ + || ObLSRebuildStatus::DOING == new_info.status_ + || ObLSRebuildStatus::CLEANUP == new_info.status_) { + can_change = true; + } + break; + } + case ObLSRebuildStatus::DOING: { + if (ObLSRebuildStatus::DOING == new_info.status_ + || ObLSRebuildStatus::CLEANUP == new_info.status_) { + can_change = true; + } + break; + } + case ObLSRebuildStatus::CLEANUP : { + if (ObLSRebuildStatus::CLEANUP == new_info.status_ + || ObLSRebuildStatus::NONE == new_info.status_) { + can_change = true; + } + break; + } + default: { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid old info for fail", K(ret), K(old_info), K(new_info)); + } + } + } + return ret; +} + + +ObRebuildService::ObRebuildService() + : is_inited_(false), + thread_cond_(), + wakeup_cnt_(0), + ls_service_(nullptr), + lock_(), + rebuild_ctx_map_() +{ +} + +ObRebuildService::~ObRebuildService() +{ +} + +int ObRebuildService::mtl_init(ObRebuildService *&rebuild_service) +{ + int ret = OB_SUCCESS; + ObLSService *ls_service = nullptr; + + if (OB_ISNULL(ls_service = (MTL(ObLSService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), KP(ls_service)); + } else if (OB_FAIL(rebuild_service->init(ls_service))) { + LOG_WARN("failed to init rebuild service", K(ret), KP(ls_service)); + } + return ret; +} + +int ObRebuildService::init( + ObLSService *ls_service) +{ + int ret = OB_SUCCESS; + common::SpinWLockGuard guard(lock_); + + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("rebuild service is aleady init", K(ret)); + } else if (OB_ISNULL(ls_service)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("init rebuild service get invalid argument", K(ret), KP(ls_service)); + } else if (OB_FAIL(thread_cond_.init(ObWaitEventIds::HA_SERVICE_COND_WAIT))) { + LOG_WARN("failed to init ha service thread cond", K(ret)); + } else if (OB_FAIL(rebuild_ctx_map_.create(MAX_BUCKET_NUM, "RebuildCtx"))) { + LOG_WARN("failed to create rebuild ctx map", K(ret)); + } else { + lib::ThreadPool::set_run_wrapper(MTL_CTX()); + ls_service_ = ls_service; + is_inited_ = true; + } + return ret; +} + +int ObRebuildService::add_rebuild_ls( + const ObLSID &ls_id, + const ObLSRebuildType &rebuild_type) +{ + int ret = OB_SUCCESS; + ObLSRebuildCtx rebuild_ctx; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else if (!ls_id.is_valid() || !rebuild_type.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("add rebuild ls get invalid argument", K(ret), K(ls_id), K(rebuild_type)); + } else { + common::SpinWLockGuard guard(lock_); + int hash_ret = rebuild_ctx_map_.get_refactored(ls_id, rebuild_ctx); + if (OB_SUCCESS == hash_ret) { + wakeup(); + } else if (OB_HASH_NOT_EXIST == hash_ret) { + rebuild_ctx.ls_id_ = ls_id; + rebuild_ctx.type_ = rebuild_type; + rebuild_ctx.task_id_.init(GCONF.self_addr_); + if (OB_FAIL(rebuild_ctx_map_.set_refactored(ls_id, rebuild_ctx))) { + LOG_WARN("failed to set rebuild ctx", K(ret), K(rebuild_ctx)); + } else { + wakeup(); + FLOG_INFO("succeed add rebuild ls", K(ls_id), K(rebuild_ctx)); + } + } else { + ret = hash_ret; + LOG_WARN("failed to add rebuild ls", K(ret), K(ls_id), K(rebuild_type)); + } + } + return ret; +} + +int ObRebuildService::inner_remove_rebuild_ls_( + const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + common::SpinWLockGuard guard(lock_); + if (OB_FAIL(rebuild_ctx_map_.erase_refactored(ls_id))) { + if (OB_HASH_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to erase rebuild ls", K(ret), K(ls_id)); + } + } + + if (OB_SUCC(ret)) { + FLOG_INFO("succeed remove rebuild ls", K(ls_id)); + } + return ret; +} + +int ObRebuildService::finish_rebuild_ls( + const share::ObLSID &ls_id, + const int32_t result) +{ + int ret = OB_SUCCESS; + ObLSRebuildMgr ls_rebuild_mgr; + ObLSRebuildCtx rebuild_ctx; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("remove rebuild ls get invalid argument", K(ret), K(ls_id)); + } else { + common::SpinWLockGuard guard(lock_); + if (OB_FAIL(rebuild_ctx_map_.get_refactored(ls_id, rebuild_ctx))) { + LOG_WARN("failed to get rebuild ctx", K(ret), K(ls_id)); + } else if (OB_FAIL(ls_rebuild_mgr.init(rebuild_ctx, ls_service_))) { + LOG_WARN("failed to init ls rebuild mgr", K(ret), K(ls_id), K(rebuild_ctx)); + } else if (OB_FAIL(ls_rebuild_mgr.finish_ls_rebuild(result))) { + LOG_WARN("failed to finish ls rebuild", K(ret), K(ls_id), K(result), K(rebuild_ctx)); + } + } + return ret; +} + +int ObRebuildService::check_ls_need_rebuild( + const share::ObLSID &ls_id, + bool &need_rebuild) +{ + int ret = OB_SUCCESS; + int hash_ret = OB_SUCCESS; + ObLSRebuildCtx rebuild_ctx; + need_rebuild = false; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("remove rebuild ls get invalid argument", K(ret), K(ls_id)); + } else { + common::SpinRLockGuard guard(lock_); + if (OB_FAIL(rebuild_ctx_map_.get_refactored(ls_id, rebuild_ctx))) { + if (OB_HASH_NOT_EXIST == ret) { + need_rebuild = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get rebuild ctx", K(ret), K(ls_id)); + } + } else { + need_rebuild = true; + } + } + return ret; +} + +int ObRebuildService::remove_rebuild_ls( + const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("remove rebuild ls get invalid argument", K(ret), K(ls_id)); + } else { + common::SpinWLockGuard guard(lock_); + if (OB_FAIL(rebuild_ctx_map_.erase_refactored(ls_id))) { + if (OB_HASH_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to erase rebuild ls", K(ret), K(ls_id)); + } + } + } + return ret; +} + +void ObRebuildService::wakeup() +{ + ObThreadCondGuard cond_guard(thread_cond_); + wakeup_cnt_++; + thread_cond_.signal(); +} + +void ObRebuildService::destroy() +{ + if (is_inited_) { + COMMON_LOG(INFO, "ObRebuildService starts to destroy"); + thread_cond_.destroy(); + wakeup_cnt_ = 0; + rebuild_ctx_map_.destroy(); + is_inited_ = false; + COMMON_LOG(INFO, "ObRebuildService destroyed"); + } +} + +void ObRebuildService::stop() +{ + if (is_inited_) { + COMMON_LOG(INFO, "ObRebuildService starts to stop"); + ThreadPool::stop(); + wakeup(); + COMMON_LOG(INFO, "ObRebuildService stopped"); + } +} + +void ObRebuildService::wait() +{ + if (is_inited_) { + COMMON_LOG(INFO, "ObRebuildService starts to wait"); + ThreadPool::wait(); + COMMON_LOG(INFO, "ObRebuildService finish to wait"); + } +} + +int ObRebuildService::start() +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else { + if (OB_FAIL(lib::ThreadPool::start())) { + COMMON_LOG(WARN, "ObRebuildService start thread failed", K(ret)); + } else { + COMMON_LOG(INFO, "ObRebuildService start"); + } + } + return ret; +} + +void ObRebuildService::run1() +{ + int ret = OB_SUCCESS; + lib::set_thread_name("RebuildService"); + + while (!has_set_stop()) { + if (observer::ObServiceStatus::SS_SERVING != GCTX.status_) { + ret = OB_SERVER_IS_INIT; + LOG_WARN("server is not serving", K(ret), K(GCTX.status_)); + } else if (OB_FAIL(build_rebuild_ctx_map_())) { + LOG_WARN("failed to build rebuild ctx map", K(ret)); + } else if (OB_FAIL(build_ls_rebuild_info_())) { + LOG_WARN("failed to build ls rebuild info", K(ret)); + } else if (OB_FAIL(scheduler_rebuild_mgr_())) { + LOG_WARN("failed to do scheduler rebuild mgr", K(ret)); + } else if (OB_FAIL(check_rebuild_ctx_map_())) { + LOG_WARN("failed to check rebuild ctx map", K(ret)); + } + + ObThreadCondGuard guard(thread_cond_); + if (has_set_stop() || wakeup_cnt_ > 0) { + wakeup_cnt_ = 0; + } else { + int64_t wait_time_ms = SCHEDULER_WAIT_TIME_MS; + if (OB_SERVER_IS_INIT == ret) { + wait_time_ms = WAIT_SERVER_IN_SERVICE_TIME_MS; + } + thread_cond_.wait(wait_time_ms); + } + } +} + +int ObRebuildService::build_rebuild_ctx_map_() +{ + int ret = OB_SUCCESS; + common::ObSharedGuard ls_iter_guard; + ObLSIterator *ls_iter = nullptr; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else if (OB_FAIL(ls_service_->get_ls_iter(ls_iter_guard, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls iter", K(ret)); + } else if (OB_ISNULL(ls_iter = ls_iter_guard.get_ptr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls iter should not be NULL", K(ret)); + } else { + common::SpinWLockGuard guard(lock_); + while (OB_SUCC(ret)) { + ObLS *ls = nullptr; + ObLSRebuildInfo rebuild_info; + ObLSRebuildCtx rebuild_ctx; + int hash_ret = OB_SUCCESS; + if (OB_FAIL(ls_iter->get_next(ls))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } + } else if (OB_ISNULL(ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); + } else if (OB_FAIL(ls->get_rebuild_info(rebuild_info))) { + LOG_WARN("failed to get rebuild info", K(ret), KPC(ls)); + } else if (!rebuild_info.is_in_rebuild()) { + //do nothing + } else if (FALSE_IT(hash_ret = rebuild_ctx_map_.get_refactored(ls->get_ls_id(), rebuild_ctx))) { + } else if (OB_SUCCESS == hash_ret) { + //do nothing + } else if (OB_HASH_NOT_EXIST == hash_ret) { + rebuild_ctx.ls_id_ = ls->get_ls_id(); + rebuild_ctx.type_ = rebuild_info.type_; + rebuild_ctx.task_id_.init(GCONF.self_addr_); + if (OB_FAIL(rebuild_ctx_map_.set_refactored(ls->get_ls_id(), rebuild_ctx))) { + LOG_WARN("failed to set rebuild ctx", K(ret), KPC(ls), K(rebuild_info)); + } + } else { + ret = hash_ret; + LOG_WARN("failed to get ls rebuild ctx", K(ret), KPC(ls)); + } + } + } + return ret; +} + +int ObRebuildService::scheduler_rebuild_mgr_() +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObArray rebuild_ctx_array; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else if (OB_FAIL(get_ls_rebuild_ctx_array_(rebuild_ctx_array))) { + LOG_WARN("failed to get ls rebuild ctx array", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < rebuild_ctx_array.count(); ++i) { + const ObLSRebuildCtx &rebuild_ctx = rebuild_ctx_array.at(i); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObLSRebuildInfo rebuild_info; + if (OB_FAIL(ls_service_->get_ls(rebuild_ctx.ls_id_, ls_handle, ObLSGetMod::HA_MOD))) { + if (OB_LS_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get ls", K(ret), K(rebuild_ctx)); + } + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), K(rebuild_ctx)); + } else if (OB_FAIL(ls->get_rebuild_info(rebuild_info))) { + LOG_WARN("failed to get rebuild info", K(ret), KPC(ls)); + } else if (!rebuild_info.is_in_rebuild()) { + //do nothing + } else if (OB_SUCCESS != (tmp_ret = do_rebuild_mgr_(rebuild_ctx))) { + LOG_WARN("failed to do rebuild mgr", K(tmp_ret), K(rebuild_ctx)); + } + } + } + return ret; +} + +int ObRebuildService::do_rebuild_mgr_(const ObLSRebuildCtx &rebuild_ctx) +{ + int ret = OB_SUCCESS; + ObLSRebuildMgr ls_rebuild_mgr; + LOG_INFO("start do rebuild mgr", K(rebuild_ctx)); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else if (!rebuild_ctx.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("do rebuild mgr get invalid argument", K(ret), K(rebuild_ctx)); + } else if (OB_FAIL(ls_rebuild_mgr.init(rebuild_ctx, ls_service_))) { + LOG_WARN("failed to ini ls rebuild mgr", K(ret), K(rebuild_ctx)); + } else if (OB_FAIL(ls_rebuild_mgr.process())) { + LOG_WARN("failed to do ls rebuld mgr", K(ret), K(rebuild_ctx)); + } + return ret; +} + +int ObRebuildService::check_rebuild_ctx_map_() +{ + int ret = OB_SUCCESS; + ObArray ls_id_array; + ObArray rebuild_ctx_array; + ObMigrationStatus status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else if (OB_FAIL(get_ls_rebuild_ctx_array_(rebuild_ctx_array))) { + LOG_WARN("failed to get ls rebuild ctx array", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < rebuild_ctx_array.count(); ++i) { + const ObLSRebuildCtx &rebuild_ctx = rebuild_ctx_array.at(i); + const ObLSID &ls_id = rebuild_ctx.ls_id_; + bool is_exist = false; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObLSRebuildInfo rebuild_info; + bool in_final_state = false; + if (OB_FAIL(ls_service_->get_ls(ls_id, ls_handle, ObLSGetMod::HA_MOD))) { + if (OB_LS_NOT_EXIST == ret) { + ret = OB_SUCCESS; + if (OB_FAIL(ls_id_array.push_back(ls_id))) { + LOG_WARN("failed to push ls id into array", K(ret), K(ls_id)); + } + } else { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); + } else if (OB_FAIL(ls->get_rebuild_info(rebuild_info))) { + LOG_WARN("failed to get ls rebuild info", K(ret), KPC(ls), K(ls_id)); + } else if (OB_FAIL(ls->get_migration_status(status))) { + LOG_WARN("failed to get migration status", K(ret), KPC(ls), K(ls_id)); + } else if (OB_FAIL(ObMigrationStatusHelper::check_migration_in_final_state(status, in_final_state))) { + LOG_WARN("failed to check migration status in final state", K(ret), K(status), KPC(ls)); + } else if (rebuild_info.is_in_rebuild() || !in_final_state) { + //do nohting + } else if (OB_FAIL(ls_id_array.push_back(ls_id))) { + LOG_WARN("failed to push ls id into array", K(ret), K(ls_id)); + } + } + + if (OB_SUCC(ret)) { + for (int64_t i = 0; OB_SUCC(ret) && i < ls_id_array.count(); ++i) { + const ObLSID &ls_id = ls_id_array.at(i); + if (OB_FAIL(inner_remove_rebuild_ls_(ls_id))) { + LOG_WARN("failed to inner remove rebuild ls", K(ret), K(ls_id)); + } + } + } + } + return ret; +} + +int ObRebuildService::get_ls_rebuild_ctx_array_( + common::ObIArray &rebuild_ctx_array) +{ + int ret = OB_SUCCESS; + rebuild_ctx_array.reset(); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else { + common::SpinRLockGuard guard(lock_); + for (LSRebuildCtxMap::iterator iter = rebuild_ctx_map_.begin(); OB_SUCC(ret) && iter != rebuild_ctx_map_.end(); ++iter) { + const ObLSRebuildCtx &rebuild_ctx = iter->second; + if (OB_FAIL(rebuild_ctx_array.push_back(rebuild_ctx))) { + LOG_WARN("failed to push rebuild ctx into array", K(ret), K(rebuild_ctx)); + } + } + } + return ret; +} + +int ObRebuildService::build_ls_rebuild_info_() +{ + int ret = OB_SUCCESS; + ObArray rebuild_ctx_array; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else if (OB_FAIL(get_ls_rebuild_ctx_array_(rebuild_ctx_array))) { + LOG_WARN("failed to get ls rebuild ctx array", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < rebuild_ctx_array.count(); ++i) { + const ObLSRebuildCtx &rebuild_ctx = rebuild_ctx_array.at(i); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObLSRebuildInfo rebuild_info; + ObMigrationStatus status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + bool can_rebuild = false; + if (OB_FAIL(ls_service_->get_ls(rebuild_ctx.ls_id_, ls_handle, ObLSGetMod::HA_MOD))) { + if (OB_LS_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get ls", K(ret), K(rebuild_ctx)); + } + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(rebuild_ctx)); + } else if (OB_FAIL(ls->get_migration_status(status))) { + LOG_WARN("failed to get ls migration status", K(ret), KPC(ls)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != status + && ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD != status) { + FLOG_INFO("ls migration status is not none or rebuild, skip it", K(ret), KPC(ls)); + } else if (OB_FAIL(ls->get_rebuild_info(rebuild_info))) { + LOG_WARN("failed to get ls rebuild info", K(ret), KPC(ls), K(rebuild_ctx)); + } else if (rebuild_info.is_in_rebuild()) { + //do nothing + } else if (OB_FAIL(check_can_rebuild_(rebuild_ctx, ls, can_rebuild))) { + LOG_WARN("failed to check can rebuild", K(ret), KPC(ls)); + } else if (!can_rebuild) { + LOG_INFO("ls cannot rebuild", K(ret), KPC(ls)); + } else { + rebuild_info.status_ = ObLSRebuildStatus::INIT; + rebuild_info.type_ = rebuild_ctx.type_; + if (OB_FAIL(ls->set_rebuild_info(rebuild_info))) { + LOG_WARN("failed to set rebuild info", K(ret), K(rebuild_info), K(rebuild_ctx), KPC(ls)); + } + } + } + } + return ret; +} + +int ObRebuildService::check_can_rebuild_( + const ObLSRebuildCtx &rebuild_ctx, + ObLS *ls, + bool &can_rebuild) +{ + int ret = OB_SUCCESS; + can_rebuild = false; + logservice::ObLogService *log_service = nullptr; + ObRole role; + int64_t proposal_id = 0; + share::ObAllTenantInfo tenant_info; + const uint64_t tenant_id = MTL_ID(); + common::ObMemberList member_list; + int64_t paxos_replica_num = 0; + const ObAddr &self_addr = GCONF.self_addr_; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rebuild service do not init", K(ret)); + } else if (!rebuild_ctx.is_valid() || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls should not be NULL", K(ret), K(rebuild_ctx), KP(ls)); + } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, GCTX.sql_proxy_, false/*for update*/, tenant_info))) { + LOG_WARN("failed to get tenant info", K(ret), K(tenant_id)); + } else if (OB_FAIL(ls->get_log_handler()->get_paxos_member_list(member_list, paxos_replica_num))) { + LOG_WARN("failed to get paxos member list and learner list", K(ret), KPC(ls)); + } else if (ObLSRebuildType::TRANSFER == rebuild_ctx.type_ + && tenant_info.is_primary() && member_list.contains(self_addr)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls cannot do rebuild", K(ret), K(rebuild_ctx), K(tenant_info), K(member_list)); + } else if (OB_ISNULL(log_service = MTL(logservice::ObLogService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log service should not be NULL", K(ret), KP(log_service)); + } else if (OB_FAIL(log_service->get_palf_role(ls->get_ls_id(), role, proposal_id))) { + LOG_WARN("failed to get role", K(ret), KPC(ls)); + } else if (is_strong_leader(role)) { + can_rebuild = false; + FLOG_INFO("leader cannot rebuild", KPC(ls)); + } else { + can_rebuild = true; + } + return ret; +} + + +ObLSRebuildMgr::ObLSRebuildMgr() + : is_inited_(false), + rebuild_ctx_() +{ +} + +ObLSRebuildMgr::~ObLSRebuildMgr() +{ +} + +int ObLSRebuildMgr::init( + const ObLSRebuildCtx &rebuild_ctx, + ObLSService *ls_service) +{ + int ret = OB_SUCCESS; + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("ls rebuild mgr init twice", K(ret)); + } else if (!rebuild_ctx.is_valid() || OB_ISNULL(ls_service)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("init ls rebuild mgr get invalid argument", K(ret), K(rebuild_ctx), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(rebuild_ctx.ls_id_, ls_handle_, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(rebuild_ctx)); + } else { + rebuild_ctx_ = rebuild_ctx; + is_inited_ = true; + } + return ret; +} + +int ObLSRebuildMgr::process() +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + ObLSRebuildInfo rebuild_info; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls rebuild mgr do not init", K(ret)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), K(rebuild_ctx_)); + } else if (OB_FAIL(ls->get_rebuild_info(rebuild_info))) { + LOG_WARN("failed to get rebuild info", K(ret), K(rebuild_info)); + } else { + switch (rebuild_info.status_) { + case ObLSRebuildStatus::NONE: { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("in ls rebuld mgr rebuild info should not be NULL", K(ret), K(rebuild_info)); + break; + } + case ObLSRebuildStatus::INIT : { + if (OB_FAIL(do_with_init_status_(rebuild_info))) { + LOG_WARN("failed to do with init status", K(ret), K(rebuild_info)); + } + break; + } + case ObLSRebuildStatus::DOING : { + if (OB_FAIL(do_with_doing_status_(rebuild_info))) { + LOG_WARN("failed to do with aborted status", K(ret), K(rebuild_info)); + } + break; + } + case ObLSRebuildStatus::CLEANUP : { + if (OB_FAIL(do_with_cleanup_status_(rebuild_info))) { + LOG_WARN("failed to do with cleanup status", K(ret), K(rebuild_info)); + } + break; + } + default: { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid cur status for fail", K(ret), K(rebuild_info)); + } + } + } + return ret; +} + +int ObLSRebuildMgr::finish_ls_rebuild( + const int32_t result) +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + ObLSRebuildInfo rebuild_info; + int32_t tmp_result = result; + const uint64_t tenant_id = MTL_ID(); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls rebuild mgr do not init", K(ret)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); + } else if (OB_FAIL(ls->get_rebuild_info(rebuild_info))) { + LOG_WARN("failed to get ls rebuild info", K(ret), KPC(ls)); + } else if (ObLSRebuildStatus::DOING != rebuild_info.status_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls rebuild info is unexpected", K(ret), KPC(ls), K(rebuild_info)); + } else if (OB_FAIL(switch_next_status_(rebuild_info, tmp_result))) { + LOG_WARN("failed to switch next status", K(ret), K(rebuild_info), KPC(ls)); + } + return ret; +} + +int ObLSRebuildMgr::do_with_init_status_(const ObLSRebuildInfo &rebuild_info) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObLS *ls = nullptr; + const uint64_t tenant_id = MTL_ID(); + const bool need_check_log_missing = ObLSRebuildType::CLOG == rebuild_info.type_ ? true : false; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls rebuild mgr do not init", K(ret)); + } else if (!rebuild_info.is_valid() || ObLSRebuildStatus::INIT != rebuild_info.status_) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("do with none status get invalid argument", K(ret), K(rebuild_info)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(rebuild_info)); + } else { + ROOTSERVICE_EVENT_ADD("disaster_recovery", "start_rebuild_ls_replica", + "tenant_id", tenant_id, + "ls_id", rebuild_ctx_.ls_id_, + "task_id", rebuild_ctx_.task_id_, + "source", MYADDR, + "destination", MYADDR, + "comment", ""); + + if (OB_FAIL(ls->disable_vote(need_check_log_missing))) { + LOG_WARN("failed to disable vote", K(ret), KPC(ls), K(rebuild_info)); + } else if (OB_FAIL(switch_next_status_(rebuild_info, ret))) { + LOG_WARN("failed to switch next status", K(ret), K(rebuild_info)); + if (OB_SUCCESS != (tmp_ret = ls->enable_vote())) { + LOG_ERROR("failed to enable vote", K(tmp_ret), K(ret), K(rebuild_info), K(rebuild_ctx_)); + } + } + } + return ret; +} + +int ObLSRebuildMgr::do_with_doing_status_(const ObLSRebuildInfo &rebuild_info) +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + bool is_exist = false; + LOG_INFO("start do with doing status", K(rebuild_info), K(rebuild_ctx_)); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls rebuild mgr do not init", K(ret), K(rebuild_info)); + } else if (!rebuild_info.is_valid() || ObLSRebuildStatus::DOING != rebuild_info.status_) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("do with none status get invalid argument", K(ret), K(rebuild_info)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(rebuild_ctx_), K(rebuild_info)); + } else if (OB_FAIL(ls->get_ls_migration_handler()->check_task_exist(rebuild_ctx_.task_id_, is_exist))) { + LOG_WARN("failed to check task exist", K(ret), K(rebuild_ctx_)); + } else if (is_exist) { + LOG_INFO("rebuild task is already exist", K(ret), K(rebuild_ctx_)); + } else if (OB_FAIL(generate_rebuild_task_())) { + LOG_WARN("failed to generate rebuild task", K(ret), K(rebuild_ctx_)); + } + return ret; +} + +int ObLSRebuildMgr::do_with_cleanup_status_( + const ObLSRebuildInfo &rebuild_info) +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + int32_t tmp_result = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + LOG_INFO("start do with cleanup status", K(rebuild_info), K(rebuild_ctx_)); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls rebuild mgr do not init", K(ret), K(rebuild_info)); + } else if (!rebuild_info.is_valid() || ObLSRebuildStatus::CLEANUP != rebuild_info.status_) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("do with none status get invalid argument", K(ret), K(rebuild_info)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(rebuild_ctx_), K(rebuild_info)); + } else { + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = OB_E(EventTable::EN_MIGRATION_ENABLE_VOTE_FAILED) OB_SUCCESS; + if (OB_FAIL(ret)) { + tmp_result = ret; + ret = OB_SUCCESS; + STORAGE_LOG(ERROR, "fake EN_MIGRATION_ENABLE_VOTE_FAILED", K(ret)); + } + } +#endif + + if (OB_SUCCESS == tmp_result && OB_FAIL(ls->enable_vote())) { + LOG_WARN("failed to enable vote", K(ret), KPC(ls), K(rebuild_info)); + } else { + LOG_INFO("succeed enable vote", KPC(ls), K(rebuild_info)); + #ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = OB_E(EventTable::EN_MIGRATION_ENABLE_VOTE_RETRY) OB_SUCCESS; + if (OB_FAIL(ret)) { + tmp_result = ret; + ret = OB_SUCCESS; + STORAGE_LOG(ERROR, "fake EN_MIGRATION_ENABLE_VOTE_RETRY", K(ret)); + } + } + #endif + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(switch_next_status_(rebuild_info, tmp_result))) { + LOG_WARN("failed to switch next status", K(ret), K(rebuild_info), KPC(ls)); + } else { + ROOTSERVICE_EVENT_ADD("disaster_recovery", "finish_rebuild_ls_replica", + "tenant_id", tenant_id, + "ls_id", rebuild_ctx_.ls_id_, + "task_id", rebuild_ctx_.task_id_, + "source", MYADDR, + "destination", MYADDR, + "comment", tmp_result); + } + } + return ret; +} + +int ObLSRebuildMgr::switch_next_status_( + const ObLSRebuildInfo &curr_rebuild_info, + const int32_t result) +{ + int ret = OB_SUCCESS; + ObLSRebuildInfo next_rebuild_info; + bool can_change = false; + ObRebuildService *rebuild_service = MTL(ObRebuildService*); + ObLS *ls = nullptr; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls rebuild mgr do not init", K(ret)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(rebuild_ctx_)); + } else if (OB_ISNULL(rebuild_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("storage ha handler service should not be NULL", K(ret), KP(rebuild_service)); + } else if (!curr_rebuild_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("switch next status get invalid argument", K(ret), K(curr_rebuild_info)); + } else { + if (OB_FAIL(ObLSRebuildInfoHelper::get_next_rebuild_info(curr_rebuild_info, rebuild_ctx_.type_, result, next_rebuild_info))) { + LOG_WARN("failed to get next change status", K(ret), K(curr_rebuild_info), K(result), K(rebuild_ctx_)); + } else if (OB_FAIL(ObLSRebuildInfoHelper::check_can_change_info(curr_rebuild_info, next_rebuild_info, can_change))) { + LOG_WARN("failed to check can change status", K(ret), K(curr_rebuild_info), K(next_rebuild_info), K(rebuild_ctx_)); + } else if (!can_change) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("can not change ls migration handler status", K(ret), K(curr_rebuild_info), K(next_rebuild_info), K(rebuild_ctx_)); + } else if (OB_FAIL(ls->set_rebuild_info(next_rebuild_info))) { + LOG_WARN("failed to set rebuild info", K(ret), K(next_rebuild_info)); + } else { + FLOG_INFO("update rebuild info", K(curr_rebuild_info), K(next_rebuild_info)); + } + wakeup_(); + } + return ret; +} + +void ObLSRebuildMgr::wakeup_() +{ + int ret = OB_SUCCESS; + ObRebuildService *rebuild_service = MTL(ObRebuildService*); + if (OB_ISNULL(rebuild_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("storage ha handler service should not be NULL", K(ret), KP(rebuild_service)); + } else { + rebuild_service->wakeup(); + } +} + +int ObLSRebuildMgr::generate_rebuild_task_() +{ + int ret = OB_SUCCESS; + const int64_t timestamp = 0; + common::ObMemberList member_list; + int64_t paxos_replica_num = 0; + ObLSInfo ls_info; + int64_t cluster_id = GCONF.cluster_id; + uint64_t tenant_id = MTL_ID(); + ObAddr leader_addr; + ObLS *ls = nullptr; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls rebuild mgr do not init", K(ret)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(rebuild_ctx_)); + } else { + if (OB_FAIL(ls->get_paxos_member_list(member_list, paxos_replica_num))) { + LOG_WARN("failed to get paxos member list", K(ret), KPC(ls)); + } else if (OB_FAIL(get_ls_info_(cluster_id, tenant_id, ls->get_ls_id(), ls_info))) { + LOG_WARN("failed to get ls info", K(ret), K(cluster_id), K(tenant_id), KPC(ls)); + //overwrite ret + if (OB_FAIL(ls->get_log_handler()->get_election_leader(leader_addr))) { + LOG_WARN("failed to get election leader", K(ret), KPC(ls), K(tenant_id)); + } + } else { + //TODO(muwei.ym) do not use leader as src in 4.3 + const ObLSInfo::ReplicaArray &replica_array = ls_info.get_replicas(); + for (int64_t i = 0; OB_SUCC(ret) && i < replica_array.count(); ++i) { + const ObLSReplica &replica = replica_array.at(i); + if (replica.is_strong_leader()) { + leader_addr = replica.get_server(); + break; + } + } + } + + #ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = OB_E(EventTable::EN_GENERATE_REBUILD_TASK_FAILED) OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_GENERATE_REBUILD_TASK_FAILED", K(ret)); + } + } + #endif + + if (OB_FAIL(ret)) { + } else { + ObTaskId task_id; + task_id.init(GCONF.self_addr_); + ObReplicaMember dst_replica_member(GCONF.self_addr_, timestamp); + ObReplicaMember src_replica_member(leader_addr, timestamp); + ObMigrationOpArg arg; + arg.cluster_id_ = GCONF.cluster_id; + arg.data_src_ = src_replica_member; + arg.dst_ = dst_replica_member; + arg.ls_id_ = ls->get_ls_id(); + arg.priority_ = ObMigrationOpPriority::PRIO_MID; + arg.paxos_replica_number_ = paxos_replica_num; + arg.src_ = src_replica_member; + arg.type_ = ObMigrationOpType::REBUILD_LS_OP; + + if (OB_FAIL(ls->get_ls_migration_handler()->add_ls_migration_task(rebuild_ctx_.task_id_, arg))) { + LOG_WARN("failed to add ls migration task", K(ret), K(arg), KPC(ls)); + } + } + } + return ret; +} + +int ObLSRebuildMgr::get_ls_info_( + const int64_t cluster_id, + const uint64_t tenant_id, + const share::ObLSID &ls_id, + share::ObLSInfo &ls_info) +{ + int ret = OB_SUCCESS; + ls_info.reset(); + share::ObLSTableOperator *lst_operator = GCTX.lst_operator_; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls rebuild mgr do not init", K(ret)); + } else if (cluster_id < 0 || OB_INVALID_ID == tenant_id || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get ls info get invalid argument", K(ret), K(cluster_id), K(tenant_id), K(ls_id)); + } else if (nullptr == lst_operator) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lst_operator ptr is null", K(ret)); + } else if (OB_FAIL(lst_operator->get(cluster_id, tenant_id, + ls_id, share::ObLSTable::DEFAULT_MODE, ls_info))) { + LOG_WARN("failed to get log stream info", K(ret), K(cluster_id), K(tenant_id), K(ls_id)); + } + return ret; +} diff --git a/src/storage/high_availability/ob_rebuild_service.h b/src/storage/high_availability/ob_rebuild_service.h new file mode 100644 index 000000000..34960f646 --- /dev/null +++ b/src/storage/high_availability/ob_rebuild_service.h @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2021 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 OCEABASE_STORAGE_REBUILD_SERVICE_ +#define OCEABASE_STORAGE_REBUILD_SERVICE_ + +#include "lib/thread/thread_pool.h" +#include "lib/thread/ob_reentrant_thread.h" +#include "lib/thread/ob_thread_name.h" +#include "lib/lock/ob_thread_cond.h" +#include "lib/container/ob_se_array.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "share/scn.h" +#include "ob_storage_ha_struct.h" +#include "lib/hash/ob_hashmap.h" + +namespace oceanbase +{ +namespace storage +{ + +struct ObLSRebuildCtx final +{ + ObLSRebuildCtx(); + ~ObLSRebuildCtx() = default; + void reset(); + bool is_valid() const; + + TO_STRING_KV(K_(ls_id), K_(type), K_(task_id)); + share::ObLSID ls_id_; + ObLSRebuildType type_; + share::ObTaskId task_id_; +}; + +struct ObLSRebuildInfoHelper +{ +public: + static int check_can_change_info( + const ObLSRebuildInfo &old_info, + const ObLSRebuildInfo &new_info, + bool &can_change); + static int get_next_rebuild_info( + const ObLSRebuildInfo &curr_info, + const ObLSRebuildType &rebuild_type, + const int32_t result, + ObLSRebuildInfo &next_info); +}; + +class ObRebuildService : public lib::ThreadPool +{ +public: + ObRebuildService(); + virtual ~ObRebuildService(); + static int mtl_init(ObRebuildService *&rebuild_service); + + int init(ObLSService *ls_service); + void destroy(); + void run1() final; + void wakeup(); + void stop(); + void wait(); + int start(); + int add_rebuild_ls( + const share::ObLSID &ls_id, + const ObLSRebuildType &rebuild_type); + int finish_rebuild_ls( + const share::ObLSID &ls_id, + const int32_t result); + int check_ls_need_rebuild( + const share::ObLSID &ls_id, + bool &need_rebuild); + int remove_rebuild_ls( + const share::ObLSID &ls_id); +private: + int build_rebuild_ctx_map_(); + int scheduler_rebuild_mgr_(); + int do_rebuild_mgr_(const ObLSRebuildCtx &rebuild_ctx); + int inner_remove_rebuild_ls_( + const share::ObLSID &ls_id); + int check_rebuild_ctx_map_(); + int get_ls_rebuild_ctx_array_(common::ObIArray &rebuild_ctx_array); + int build_ls_rebuild_info_(); + int check_can_rebuild_( + const ObLSRebuildCtx &rebuild_ctx, + ObLS *ls, + bool &can_rebuild); + +private: + static const int64_t SCHEDULER_WAIT_TIME_MS = 5 * 60 * 1000L; // 5min + static const int64_t WAIT_SERVER_IN_SERVICE_TIME_MS = 1000; //1s + static const int64_t MAX_BUCKET_NUM = 128; + typedef common::hash::ObHashMap LSRebuildCtxMap; + + bool is_inited_; + common::ObThreadCond thread_cond_; + int64_t wakeup_cnt_; + ObLSService *ls_service_; + common::SpinRWLock lock_; + LSRebuildCtxMap rebuild_ctx_map_; + DISALLOW_COPY_AND_ASSIGN(ObRebuildService); +}; + +class ObLSRebuildMgr final +{ +public: + ObLSRebuildMgr(); + ~ObLSRebuildMgr(); + int init( + const ObLSRebuildCtx &rebuild_ctx, + ObLSService *ls_service); + int process(); + int finish_ls_rebuild(const int32_t result); + +private: + void wakeup_(); + int do_with_init_status_(const ObLSRebuildInfo &rebuild_info); + int do_with_doing_status_(const ObLSRebuildInfo &rebuild_info); + int do_with_cleanup_status_(const ObLSRebuildInfo &rebuild_info); + + int switch_next_status_( + const ObLSRebuildInfo &curr_rebuild_info, + const int32_t result); + int generate_rebuild_task_(); + int get_ls_info_( + const int64_t cluster_id, + const uint64_t tenant_id, + const share::ObLSID &ls_id, + share::ObLSInfo &ls_info); + +private: + bool is_inited_; + ObLSRebuildCtx rebuild_ctx_; + ObLSHandle ls_handle_; + DISALLOW_COPY_AND_ASSIGN(ObLSRebuildMgr); +}; + + +} +} +#endif diff --git a/src/storage/high_availability/ob_storage_ha_dag.cpp b/src/storage/high_availability/ob_storage_ha_dag.cpp old mode 100644 new mode 100755 index 4257fbd97..147d4c6b2 --- a/src/storage/high_availability/ob_storage_ha_dag.cpp +++ b/src/storage/high_availability/ob_storage_ha_dag.cpp @@ -16,6 +16,7 @@ #include "share/rc/ob_tenant_base.h" #include "share/scn.h" #include "observer/ob_server_event_history_table_operator.h" +#include "storage/tx_storage/ob_ls_service.h" #include "storage/tablet/ob_tablet.h" namespace oceanbase @@ -40,10 +41,12 @@ ObStorageHAResultMgr::~ObStorageHAResultMgr() int ObStorageHAResultMgr::set_result( const int32_t result, - const bool allow_retry) + const bool allow_retry, + const enum ObDagType::ObDagTypeEnum type) { int ret = OB_SUCCESS; common::SpinWLockGuard guard(lock_); + const uint64_t tenant_id = MTL_ID(); if (OB_SUCCESS == result_ && OB_SUCCESS != result) { result_ = result; allow_retry_ = allow_retry; @@ -51,10 +54,12 @@ int ObStorageHAResultMgr::set_result( LOG_WARN("failed to push trace id into array", K(ret)); } else { SERVER_EVENT_ADD("storage_ha", "set_first_result", + "tenant_id", tenant_id, "result", result, "allow_retry", allow_retry, "retry_count", retry_count_, - "failed_task_id", to_cstring(failed_task_id_list_)); + "failed_task_id", to_cstring(failed_task_id_list_), + "dag_type", OB_DAG_TYPES[type].dag_type_str_); FLOG_INFO("set first result", K(result), K(allow_retry), K(retry_count_), K(failed_task_id_list_)); } } @@ -93,6 +98,24 @@ int ObStorageHAResultMgr::check_allow_retry(bool &allow_retry) return ret; } +int ObStorageHAResultMgr::get_first_failed_task_id(share::ObTaskId &task_id) +{ + int ret = OB_SUCCESS; + common::SpinRLockGuard guard(lock_); + if (OB_SUCCESS != result_) { + ARRAY_FOREACH(failed_task_id_list_, i) { + task_id.set(failed_task_id_list_.at(i)); + break; + } + + if (task_id.is_invalid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get first failed task id", K(ret)); + } + } + return ret; +} + void ObStorageHAResultMgr::reuse() { common::SpinWLockGuard guard(lock_); @@ -129,13 +152,14 @@ ObIHADagNetCtx::~ObIHADagNetCtx() int ObIHADagNetCtx::set_result( const int32_t result, - const bool need_retry) + const bool need_retry, + const enum share::ObDagType::ObDagTypeEnum type) { int ret = OB_SUCCESS; if (!is_valid()) { - ret = OB_NOT_INIT; + ret = OB_INVALID_ARGUMENT; LOG_WARN("ha dag net ctx is not init", K(ret), K(*this)); - } else if (OB_FAIL(result_mgr_.set_result(result, need_retry))) { + } else if (OB_FAIL(result_mgr_.set_result(result, need_retry, type))) { LOG_WARN("failed to set result", K(ret), K(result), K(*this)); } return ret; @@ -151,8 +175,8 @@ int ObIHADagNetCtx::check_allow_retry(bool &allow_retry) int ret = OB_SUCCESS; allow_retry = false; if (!is_valid()) { - ret = OB_NOT_INIT; - LOG_WARN("ha dag net ctx do not init", K(ret), K(*this)); + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ha dag net ctx is invalid", K(ret), K(*this)); } else if (OB_FAIL(result_mgr_.check_allow_retry(allow_retry))) { LOG_WARN("failed to check need retry", K(ret), K(*this)); } @@ -164,14 +188,27 @@ int ObIHADagNetCtx::get_result(int32_t &result) int ret = OB_SUCCESS; result = OB_SUCCESS; if (!is_valid()) { - ret = OB_NOT_INIT; - LOG_WARN("ha dag net ctx do not init", K(ret), K(*this)); + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ha dag net ctx is invalid", K(ret), K(*this)); } else if (OB_FAIL(result_mgr_.get_result(result))) { LOG_WARN("failed to get result", K(ret), K(*this)); } return ret; } +int ObIHADagNetCtx::get_first_failed_task_id(share::ObTaskId &task_id) +{ + int ret = OB_SUCCESS; + task_id.reset(); + if (!is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ha dag net ctx is invalid", K(ret), K(*this)); + } else if (OB_FAIL(result_mgr_.get_first_failed_task_id(task_id))) { + LOG_WARN("failed to get result", K(ret), K(*this)); + } + return ret; +} + void ObIHADagNetCtx::reuse() { result_mgr_.reuse(); @@ -189,8 +226,8 @@ int ObIHADagNetCtx::check_is_in_retry(bool &is_in_retry) int32_t retry_count = 0; if (!is_valid()) { - ret = OB_NOT_INIT; - LOG_WARN("ha dag net ctx do not init", K(ret), K(*this)); + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ha dag net ctx is invalid", K(ret), K(*this)); } else if (OB_FAIL(result_mgr_.get_retry_count(retry_count))) { LOG_WARN("failed to get result", K(ret), K(*this)); } else { @@ -205,8 +242,8 @@ int ObIHADagNetCtx::get_retry_count(int32_t &retry_count) retry_count = 0; if (!is_valid()) { - ret = OB_NOT_INIT; - LOG_WARN("ha dag net ctx do not init", K(ret), K(*this)); + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ha dag net ctx is invalid", K(ret), K(*this)); } else if (OB_FAIL(result_mgr_.get_retry_count(retry_count))) { LOG_WARN("failed to get result", K(ret), K(*this)); } @@ -215,11 +252,9 @@ int ObIHADagNetCtx::get_retry_count(int32_t &retry_count) /******************ObStorageHADag*********************/ ObStorageHADag::ObStorageHADag( - const share::ObDagType::ObDagTypeEnum &dag_type, - const ObStorageHADagType sub_type) + const share::ObDagType::ObDagTypeEnum &dag_type) : ObIDag(dag_type), ha_dag_net_ctx_(), - sub_type_(sub_type), result_mgr_(), compat_mode_(lib::Worker::CompatMode::MYSQL) { @@ -267,7 +302,8 @@ bool ObStorageHADag::check_can_retry() int ObStorageHADag::set_result( const int32_t result, - const bool allow_retry) + const bool allow_retry, + const enum share::ObDagType::ObDagTypeEnum type) { int ret = OB_SUCCESS; if (OB_ISNULL(ha_dag_net_ctx_)) { @@ -275,7 +311,7 @@ int ObStorageHADag::set_result( LOG_WARN("storage ha dag do not init", K(ret), KP(ha_dag_net_ctx_)); } else if (OB_SUCCESS == result) { //do nothing - } else if (OB_FAIL(result_mgr_.set_result(result, allow_retry))) { + } else if (OB_FAIL(result_mgr_.set_result(result, allow_retry, type))) { LOG_WARN("failed to set result", K(ret), K(result), KPC(ha_dag_net_ctx_)); } return ret; @@ -302,9 +338,9 @@ int ObStorageHADag::report_result() if (OB_FAIL(ret)) { } else if (OB_SUCCESS == result) { //do nothing - } else if (OB_FAIL(ha_dag_net_ctx_->set_result(result, true /*allow_retry*/))) { + } else if (OB_FAIL(ha_dag_net_ctx_->set_result(result, true /*allow_retry*/, get_type()))) { LOG_WARN("failed to set ha dag net ctx result", K(ret), KPC(ha_dag_net_ctx_)); - } + } return ret; } @@ -337,14 +373,16 @@ int ObStorageHADagUtils::deal_with_fo( if (OB_SUCCESS == err || OB_ISNULL(dag)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("deal with fo get invalid argument", K(ret), K(err), KP(dag)); - } else if (ObDagType::DAG_TYPE_MIGRATE != dag->get_type() && ObDagType::DAG_TYPE_RESTORE != dag->get_type() - && ObDagType::DAG_TYPE_BACKFILL_TX != dag->get_type()) { + } else if (0 != STRCMP(OB_DAG_TYPES[dag->get_type()].dag_module_str_, "MIGRATE") + && 0 != STRCMP(OB_DAG_TYPES[dag->get_type()].dag_module_str_, "RESTORE") + && 0 != STRCMP(OB_DAG_TYPES[dag->get_type()].dag_module_str_, "BACKFILL_TX") + && 0 != STRCMP(OB_DAG_TYPES[dag->get_type()].dag_module_str_, "TRANSFER")) { ret = OB_ERR_UNEXPECTED; LOG_WARN("dag type is unexpected", K(ret), KPC(dag)); } else if (OB_ISNULL(ha_dag = static_cast(dag))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ha dag should not be NULL", K(ret), KPC(ha_dag)); - } else if (OB_FAIL(ha_dag->set_result(err, allow_retry))) { + } else if (OB_FAIL(ha_dag->set_result(err, allow_retry, dag->get_type()))) { LOG_WARN("failed to set result", K(ret), K(err)); } return ret; @@ -371,6 +409,46 @@ int ObStorageHADagUtils::get_ls(const share::ObLSID &ls_id, ObLSHandle &ls_handl return ret; } +int ObStorageHADagUtils::check_self_in_member_list( + const share::ObLSID &ls_id, + bool &is_in_member_list) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + logservice::ObLogHandler *log_handler = NULL; + common::ObMemberList member_list; + common::GlobalLearnerList learner_list; + int64_t paxos_replica_num = 0; + const ObAddr &self_addr = GCONF.self_addr_; + is_in_member_list = false; + + if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check self in member list get invalid argument", K(ret), K(ls_id)); + } else if (OB_FAIL(ObStorageHADagUtils::get_ls(ls_id, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else if (OB_ISNULL(log_handler = ls->get_log_handler())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log handler should not be NULL", K(ret)); + } else if (OB_FAIL(log_handler->get_paxos_member_list(member_list, paxos_replica_num))) { + LOG_WARN("failed to get paxos member list", K(ret)); + } else if (member_list.contains(self_addr)) { + is_in_member_list = true; + } else if (OB_FAIL(log_handler->get_global_learner_list(learner_list))) { + LOG_WARN("failed to get learner member list", K(ret)); + } else if (learner_list.contains(self_addr)) { + is_in_member_list = true; + } else { + is_in_member_list = false; + LOG_INFO("self is not in member list", K(ret), K(member_list), K(learner_list), K(self_addr), K(ls_id)); + } + return ret; +} + /******************ObHATabletGroupCtx*********************/ ObHATabletGroupCtx::ObHATabletGroupCtx() : is_inited_(false), @@ -588,8 +666,10 @@ int ObStorageHATaskUtils::check_major_sstable_need_copy_( { int ret = OB_SUCCESS; ObTablet *tablet = nullptr; - ObTableHandleV2 table_handle; const ObSSTable *sstable = nullptr; + ObITable *table = nullptr; + ObTabletMemberWrapper table_store_wrapper; + ObSSTableMetaHandle sst_meta_hdl; if (!param.table_key_.is_major_sstable()) { ret = OB_INVALID_ARGUMENT; @@ -597,20 +677,20 @@ int ObStorageHATaskUtils::check_major_sstable_need_copy_( } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), K(param), K(tablet_handle)); + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - const ObSSTableArray &major_sstable_array = tablet->get_table_store().get_major_sstables(); + const ObSSTableArray &major_sstable_array = table_store_wrapper.get_member()->get_major_sstables(); if (major_sstable_array.empty()) { need_copy = true; - } else if (OB_FAIL(major_sstable_array.get_table(param.table_key_, table_handle))) { + } else if (OB_FAIL(major_sstable_array.get_table(param.table_key_, table))) { LOG_WARN("failed to get table", K(ret), K(param), K(major_sstable_array)); - } else if (!table_handle.is_valid()) { + } else if (nullptr == table) { need_copy = true; - } else if (OB_FAIL(table_handle.get_sstable(sstable))) { - LOG_WARN("failed to get sstable", K(ret), K(param), K(table_handle)); - } else if (OB_ISNULL(sstable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sstable should not be NULL", K(ret), K(table_handle), K(param)); - } else if (OB_FAIL(ObSSTableMetaChecker::check_sstable_meta(param, sstable->get_meta()))) { + } else if (FALSE_IT(sstable = static_cast(table))) { + } else if (OB_FAIL(sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); + } else if (OB_FAIL(ObSSTableMetaChecker::check_sstable_meta(param, sst_meta_hdl.get_sstable_meta()))) { LOG_WARN("failed to check sstable meta", K(ret), K(param), KPC(sstable)); } else { need_copy = false; @@ -626,9 +706,8 @@ int ObStorageHATaskUtils::check_minor_sstable_need_copy_( { int ret = OB_SUCCESS; ObTablet *tablet = nullptr; - ObTableHandleV2 table_handle; const ObSSTable *sstable = nullptr; - ObTablesHandleArray tables_handle_array; + ObTableStoreIterator minor_table_iter; if (!param.table_key_.is_minor_sstable()) { ret = OB_INVALID_ARGUMENT; @@ -636,23 +715,29 @@ int ObStorageHATaskUtils::check_minor_sstable_need_copy_( } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), K(param), K(tablet_handle)); - } else if (OB_FAIL(tablet->get_table_store().get_mini_minor_sstables(tables_handle_array))) { + } else if (OB_FAIL(tablet->get_mini_minor_sstables(minor_table_iter))) { LOG_WARN("failed to get tables handle array", K(ret), K(param)); - } else if (tables_handle_array.empty()) { + } else if (0 == minor_table_iter.count()) { need_copy = true; } else { - const ObIArray &minor_sstables = tables_handle_array.get_tables(); bool found = false; - for (int64_t i = 0; i < minor_sstables.count() && OB_SUCC(ret) && !found; ++i) { - const ObITable *table = minor_sstables.at(i); - if (OB_ISNULL(table)) { + + while (OB_SUCC(ret)) { + ObITable *table = nullptr; + if (OB_FAIL(minor_table_iter.get_next(table))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to iterate minor tables", K(ret)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("minor sstable should not be NULL", K(ret), KP(table), K(minor_sstables)); + LOG_WARN("minor sstable should not be NULL", K(ret), KP(table), K(minor_table_iter)); } else if (table->get_key() == param.table_key_) { - const ObSSTable *sstable = static_cast(table); found = true; need_copy = true; - //TODO(muwei.ym) Fix it in 4.1. + //TODO(muwei.ym) Fix it in 4.3 //Need copy should be false and reuse local minor sstable. } } @@ -671,9 +756,10 @@ int ObStorageHATaskUtils::check_ddl_sstable_need_copy_( { int ret = OB_SUCCESS; ObTablet *tablet = nullptr; - ObTableHandleV2 table_handle; + ObITable *table = nullptr; const ObSSTable *sstable = nullptr; - ObTablesHandleArray tables_handle_array; + ObTabletMemberWrapper table_store_wrapper; + ObSSTableMetaHandle sst_meta_hdl; if (!param.table_key_.is_ddl_dump_sstable()) { ret = OB_INVALID_ARGUMENT; @@ -681,31 +767,31 @@ int ObStorageHATaskUtils::check_ddl_sstable_need_copy_( } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), K(param), K(tablet_handle)); + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - const ObSSTableArray &ddl_sstable_array = tablet->get_table_store().get_ddl_sstables(); - const ObSSTableArray &major_sstable_array = tablet->get_table_store().get_major_sstables(); + const ObSSTableArray &ddl_sstable_array = table_store_wrapper.get_member()->get_ddl_sstables(); + const ObSSTableArray &major_sstable_array = table_store_wrapper.get_member()->get_major_sstables(); if (!major_sstable_array.empty()) { need_copy = false; } else if (ddl_sstable_array.empty()) { need_copy = true; - } else if (OB_FAIL(ddl_sstable_array.get_table(param.table_key_, table_handle))) { + } else if (OB_FAIL(ddl_sstable_array.get_table(param.table_key_, table))) { LOG_WARN("failed to get table", K(ret), K(param), K(ddl_sstable_array)); - } else if (!table_handle.is_valid()) { - const SCN start_scn = ddl_sstable_array.get_table(0)->get_start_scn(); - const SCN end_scn = ddl_sstable_array.get_table(ddl_sstable_array.count() - 1)->get_end_scn(); + } else if (nullptr == table) { + const SCN start_scn = ddl_sstable_array.get_boundary_table(false)->get_start_scn(); + const SCN end_scn = ddl_sstable_array.get_boundary_table(true)->get_end_scn(); if (param.table_key_.scn_range_.start_scn_ >= start_scn && param.table_key_.scn_range_.end_scn_ <= end_scn) { need_copy = false; } else { need_copy = true; } - } else if (OB_FAIL(table_handle.get_sstable(sstable))) { - LOG_WARN("failed to get sstable", K(ret), K(param), K(table_handle)); - } else if (OB_ISNULL(sstable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sstable should not be NULL", K(ret), K(table_handle), K(param)); - } else if (OB_FAIL(ObSSTableMetaChecker::check_sstable_meta(param, sstable->get_meta()))) { + } else if (FALSE_IT(sstable = static_cast(table))) { + } else if (OB_FAIL(sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); + } else if (OB_FAIL(ObSSTableMetaChecker::check_sstable_meta(param, sst_meta_hdl.get_sstable_meta()))) { LOG_WARN("failed to check sstable meta", K(ret), K(param), KPC(sstable)); } else { need_copy = false; diff --git a/src/storage/high_availability/ob_storage_ha_dag.h b/src/storage/high_availability/ob_storage_ha_dag.h index 70670867c..80aa5834a 100644 --- a/src/storage/high_availability/ob_storage_ha_dag.h +++ b/src/storage/high_availability/ob_storage_ha_dag.h @@ -16,72 +16,27 @@ #include "share/scheduler/ob_dag_scheduler.h" #include "storage/ob_storage_rpc.h" #include "ob_storage_ha_struct.h" -#include "storage/tx_storage/ob_ls_service.h" #include "ob_storage_restore_struct.h" -#include "ob_storage_ha_reader.h" namespace oceanbase { namespace storage { -enum class ObStorageHADagType : uint64_t -{ - /*ObLSPrepareMigration*/ - INITIAL_PREPARE_MIGRATION_DAG = 0, - START_PREPARE_MIGRATION_DAG = 1, - TABLET_BACKFILL_TX_MIGRATION_DAG = 2, - FINISH_BACKFILL_TX_MIGRATION_DAG = 3, - FINISH_PREPARE_MIGRATION_DAG = 4, - - /*ObLSMigration*/ - INITIAL_MIGRATION_DAG = 5, - START_MIGRATION_DAG = 6, - SYS_TABLETS_MIGRATION_DAG = 7, - DATA_TABLETS_MIGRATION_DAG = 8, - TABLET_GROUP_MIGRATION_DAG = 9, - TBALET_MIGRATION_DAG = 10, - FINISH_MIGRATION_DAG = 11, - - /*ObLSCompleteMigration*/ - INITIAL_COMPLETE_MIGRATION_DAG = 12, - START_COMPLETE_MIGRATION_DAG = 13, - FINISH_COMPLETE_MIGRATION_DAG = 14, - - /*ObLSRestore*/ - INITIAL_LS_RESTORE_DAG = 15, - START_LS_RESTORE_DAG = 16, - SYS_TABLETS_RETORE_DAG = 17, - DATA_TABLETS_META_RESTORE_DAG = 18, - TABLET_GROUP_META_RETORE_DAG = 19, - FINISH_LS_RESTORE_DAG = 20, - - /*ObTabletGroupRestore*/ - INITIAL_TABLET_GROUP_RESTORE_DAG = 21, - START_TABLET_GROUP_RESTORE_DAG = 22, - TABLET_GROUP_RESTORE_DAG = 23, - FINISH_TABELT_GROUP_RESTORE_DAG = 24, - TABLET_RESTORE_DAG = 25, - - /*ObTabletBackfillTX*/ - TABLET_BACKFILL_TX_DAG = 26, - FINISH_BACKFILL_TX_DAG = 27, - - MAX_TYPE, -}; - struct ObStorageHAResultMgr final { public: ObStorageHAResultMgr(); ~ObStorageHAResultMgr(); int get_result(int32_t &result); - int set_result(const int32_t result, const bool allow_retry); + int set_result(const int32_t result, const bool allow_retry, + const enum share::ObDagType::ObDagTypeEnum type = ObDagType::DAG_TYPE_MAX); bool is_failed() const; int check_allow_retry(bool &allow_retry); void reuse(); void reset(); int get_retry_count(int32_t &retry_count); + int get_first_failed_task_id(share::ObTaskId &task_id); TO_STRING_KV(K_(result), K_(retry_count), K_(allow_retry), K_(failed_task_id_list)); private: @@ -106,6 +61,7 @@ public: LS_RESTORE = 3, TABLET_GROUP_RESTORE = 4, BACKFILL_TX = 5, + TRANSFER_BACKFILL_TX = 6, MAX }; @@ -114,7 +70,8 @@ public: virtual int fill_comment(char *buf, const int64_t buf_len) const = 0; virtual DagNetCtxType get_dag_net_ctx_type() = 0; virtual bool is_valid() const = 0; - int set_result(const int32_t result, const bool need_retry); + int set_result(const int32_t result, const bool need_retry, + const enum share::ObDagType::ObDagTypeEnum type = ObDagType::DAG_TYPE_MAX); bool is_failed() const; virtual int check_allow_retry(bool &allow_retry); int get_result(int32_t &result); @@ -122,6 +79,7 @@ public: void reset(); int check_is_in_retry(bool &is_in_retry); int get_retry_count(int32_t &retry_count); + int get_first_failed_task_id(share::ObTaskId &task_id); VIRTUAL_TO_STRING_KV(K("ObIHADagNetCtx"), K_(result_mgr)); private: @@ -133,28 +91,25 @@ private: class ObStorageHADag : public share::ObIDag { public: - explicit ObStorageHADag( - const share::ObDagType::ObDagTypeEnum &dag_type, - const ObStorageHADagType sub_type); + explicit ObStorageHADag(const share::ObDagType::ObDagTypeEnum &dag_type); virtual ~ObStorageHADag(); virtual int inner_reset_status_for_retry(); virtual bool check_can_retry(); int check_is_in_retry(bool &is_in_retry); - int set_result(const int32_t result, const bool allow_retry = true); + int set_result(const int32_t result, const bool allow_retry = true, + const enum share::ObDagType::ObDagTypeEnum type = ObDagType::DAG_TYPE_MAX); virtual int report_result(); virtual lib::Worker::CompatMode get_compat_mode() const override { return compat_mode_; } virtual uint64_t get_consumer_group_id() const override { return consumer_group_id_; } - ObStorageHADagType get_sub_type() const { return sub_type_; } ObIHADagNetCtx *get_ha_dag_net_ctx() const { return ha_dag_net_ctx_; } virtual bool is_ha_dag() const override { return true; } - INHERIT_TO_STRING_KV("ObIDag", ObIDag, KPC_(ha_dag_net_ctx), K_(sub_type), K_(result_mgr)); + INHERIT_TO_STRING_KV("ObIDag", ObIDag, KPC_(ha_dag_net_ctx), K_(result_mgr)); protected: ObIHADagNetCtx *ha_dag_net_ctx_; - ObStorageHADagType sub_type_; ObStorageHAResultMgr result_mgr_; lib::Worker::CompatMode compat_mode_; DISALLOW_COPY_AND_ASSIGN(ObStorageHADag); @@ -170,6 +125,9 @@ public: static int get_ls( const share::ObLSID &ls_id, ObLSHandle &ls_handle); + static int check_self_in_member_list( + const share::ObLSID &ls_id, + bool &is_in_member_list); }; class ObHATabletGroupCtx diff --git a/src/storage/high_availability/ob_storage_ha_reader.cpp b/src/storage/high_availability/ob_storage_ha_reader.cpp index fedf3371c..36c976b11 100644 --- a/src/storage/high_availability/ob_storage_ha_reader.cpp +++ b/src/storage/high_availability/ob_storage_ha_reader.cpp @@ -19,6 +19,7 @@ #include "storage/blocksstable/ob_logic_macro_id.h" #include "storage/tablet/ob_tablet.h" #include "storage/high_availability/ob_storage_ha_utils.h" +#include "storage/tablet/ob_tablet_iterator.h" namespace oceanbase { @@ -98,7 +99,8 @@ ObCopyMacroBlockReaderInitParam::ObCopyMacroBlockReaderInitParam() second_meta_index_store_(nullptr), restore_macro_block_id_mgr_(nullptr), need_check_seq_(false), - ls_rebuild_seq_(-1) + ls_rebuild_seq_(-1), + backfill_tx_scn_() { } @@ -113,7 +115,8 @@ bool ObCopyMacroBlockReaderInitParam::is_valid() const && ((need_check_seq_ && ls_rebuild_seq_ >= 0) || !need_check_seq_); if (bool_ret) { if (!is_leader_restore_) { - bool_ret = src_info_.is_valid() && OB_NOT_NULL(bandwidth_throttle_) && OB_NOT_NULL(svr_rpc_proxy_); + bool_ret = src_info_.is_valid() && OB_NOT_NULL(bandwidth_throttle_) && OB_NOT_NULL(svr_rpc_proxy_) + && backfill_tx_scn_.is_valid(); } else if (OB_ISNULL(restore_base_info_) || OB_ISNULL(meta_index_store_) || OB_ISNULL(second_meta_index_store_) @@ -140,6 +143,7 @@ void ObCopyMacroBlockReaderInitParam::reset() restore_macro_block_id_mgr_ = nullptr; need_check_seq_ = false; ls_rebuild_seq_ = -1; + backfill_tx_scn_.reset(); } int ObCopyMacroBlockReaderInitParam::assign(const ObCopyMacroBlockReaderInitParam ¶m) @@ -163,6 +167,7 @@ int ObCopyMacroBlockReaderInitParam::assign(const ObCopyMacroBlockReaderInitPara copy_macro_range_info_ = param.copy_macro_range_info_; need_check_seq_ = param.need_check_seq_; ls_rebuild_seq_ = param.ls_rebuild_seq_; + backfill_tx_scn_ = param.backfill_tx_scn_; } return ret; } @@ -212,8 +217,7 @@ int ObCopyMacroBlockObReader::init( arg.tenant_id_ = param.tenant_id_; arg.ls_id_ = param.ls_id_; arg.table_key_ = param.table_key_; - //TODO(yanfeng) fix backfill tx log ts and data version - arg.backfill_tx_scn_.set_min(); + arg.backfill_tx_scn_ = param.backfill_tx_scn_; arg.data_version_ = 0; arg.need_check_seq_ = param.need_check_seq_; arg.ls_rebuild_seq_ = param.ls_rebuild_seq_; @@ -565,7 +569,6 @@ ObCopyMacroBlockObProducer::ObCopyMacroBlockObProducer() tablet_handle_(), sstable_handle_(), sstable_(nullptr), - meta_(nullptr), datum_range_(), allocator_("CopyMacroBlock"), second_meta_iterator_() @@ -595,6 +598,8 @@ int ObCopyMacroBlockObProducer::init( ObTablet* tablet = nullptr; const bool is_reverse_scan = false; MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + ObSSTableMetaHandle meta_handle; + common::ObSafeArenaAllocator allocator(allocator_); if (is_inited_) { ret = OB_INIT_TWICE; @@ -614,36 +619,37 @@ int ObCopyMacroBlockObProducer::init( } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream should not be NULL", KR(ret), K(tenant_id), K(ls_id), KPC(ls)); - } else if (OB_FAIL(ls->get_tablet(table_key.get_tablet_id(), tablet_handle_, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls->ha_get_tablet(table_key.get_tablet_id(), tablet_handle_))) { LOG_WARN("failed to get tablet handle", K(ret), K(table_key), K(ls_id)); } else if (OB_UNLIKELY(nullptr == (tablet = tablet_handle_.get_obj()))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet not be NULL", KR(ret), K(tenant_id), K(ls_id), KPC(tablet)); - } else if (OB_FAIL(tablet->get_table_store().get_table(table_key, sstable_handle_))) { + } else if (OB_FAIL(tablet->get_table(table_key, sstable_handle_))) { LOG_WARN("failed to get table", K(ret), K(table_key)); if (OB_ENTRY_NOT_EXIST == ret) { ret = OB_SSTABLE_NOT_EXIST; } } else if (OB_FAIL(sstable_handle_.get_sstable(sstable_))) { LOG_WARN("failed to get sstable", K(ret), K(table_key)); + } else if (OB_FAIL(sstable_->get_meta(meta_handle, &allocator))) { + LOG_WARN("failed to get sstable meta", K(ret), K(table_key)); + } else if (backfill_tx_scn != meta_handle.get_sstable_meta().get_basic_meta().filled_tx_scn_) { + ret = OB_SSTABLE_NOT_EXIST; + LOG_WARN("sstable has been changed", K(ret), K(table_key), K(backfill_tx_scn), KPC(sstable_)); } else if (OB_FAIL(copy_macro_range_info_.assign(copy_macro_range_info))) { LOG_WARN("failed to copy macro range info", K(ret), K(table_key), K(copy_macro_range_info)); } else { - //TODO(yanfeng) check backfill tx log ts is same - datum_range_.set_start_key(copy_macro_range_info_.start_macro_block_end_key_); datum_range_.end_key_.set_max_rowkey(); datum_range_.set_left_closed(); datum_range_.set_right_open(); if (OB_FAIL(second_meta_iterator_.open(datum_range_, blocksstable::DATA_BLOCK_META, - *sstable_, tablet->get_index_read_info(), allocator_, is_reverse_scan))) { + *sstable_, tablet->get_rowkey_read_info(), allocator_, is_reverse_scan))) { LOG_WARN("failed to open second meta iterator", K(ret), K(ls_id), K(table_key), K(copy_macro_range_info)); } else { data_version_ = data_version; macro_idx_ = -1; handle_idx_ = 0; - meta_ = &sstable_->get_meta(); is_inited_ = true; LOG_INFO("succeed to init macro block producer", K(table_key), K(data_version), K(backfill_tx_scn), K(copy_macro_range_info)); @@ -884,6 +890,8 @@ int ObCopyTabletInfoRestoreReader::fetch_tablet_info(obrpc::ObCopyTabletInfo &ta ? share::ObBackupDataType::BACKUP_SYS : share::ObBackupDataType::BACKUP_MINOR)) { } else { const common::ObTabletID &tablet_id = tablet_id_array_.at(tablet_id_index_); + tablet_info.tablet_id_ = tablet_id; + tablet_info.version_ = 0; // for restore this is invalid #ifdef ERRSIM if (!tablet_id.is_ls_inner_tablet() && tablet_id_array_.count() > 10 && 5 == tablet_id_index_) { ret = OB_E(EventTable::EN_RESTORE_FETCH_TABLET_INFO) OB_SUCCESS; @@ -892,8 +900,13 @@ int ObCopyTabletInfoRestoreReader::fetch_tablet_info(obrpc::ObCopyTabletInfo &ta #endif if (OB_FAIL(ret)) { // do nothing - } else if (OB_FAIL(meta_index_store_->get_backup_meta_index(data_type, tablet_id, tablet_meta_type, tablet_meta_index))) { + } else if (OB_FAIL(meta_index_store_->get_backup_meta_index(data_type, tablet_id, tablet_meta_type, tablet_meta_index)) + && OB_ENTRY_NOT_EXIST != ret) { LOG_WARN("failed to get backup meta index", K(ret), K(tablet_id), KPC(restore_base_info_)); + } else if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + tablet_info.status_ = ObCopyTabletStatus::TABLET_NOT_EXIST; + LOG_INFO("tablet not exist", K(tablet_id)); } else if (OB_FAIL(share::ObBackupPathUtil::get_macro_block_backup_path(restore_base_info_->backup_dest_, tablet_meta_index.ls_id_, data_type, tablet_meta_index.turn_id_, tablet_meta_index.retry_id_, tablet_meta_index.file_id_, tablet_meta_backup_path))) { @@ -910,8 +923,6 @@ int ObCopyTabletInfoRestoreReader::fetch_tablet_info(obrpc::ObCopyTabletInfo &ta } else { tablet_info.data_size_ = 0; tablet_info.status_ = ObCopyTabletStatus::TABLET_EXIST; - tablet_info.tablet_id_ = backup_tablet_meta.tablet_id_; - tablet_info.version_ = 0; // for restore this is invalid if (OB_FAIL(tablet_info.param_.ha_status_.set_restore_status(restore_status))) { LOG_WARN("failed to set restore status", K(ret), K(restore_status)); } else if (OB_FAIL(tablet_info.param_.ha_status_.set_data_status(data_status))) { @@ -919,11 +930,11 @@ int ObCopyTabletInfoRestoreReader::fetch_tablet_info(obrpc::ObCopyTabletInfo &ta } else if (!tablet_info.is_valid()) { ret = OB_ERR_SYS; LOG_ERROR("invalid tablet info", K(ret), K(tablet_info), K(backup_tablet_meta)); - } else { - tablet_id_index_++; } LOG_INFO("succeed to get tablet meta", K(backup_tablet_meta), K(tablet_info)); } + + ++tablet_id_index_; } return ret; } @@ -981,7 +992,6 @@ int ObCopyTabletInfoObProducer::get_next_tablet_info(obrpc::ObCopyTabletInfo &ta ObLS *ls = nullptr; ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; - const int64_t timeout_us = ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US; if (!is_inited_) { ret = OB_NOT_INIT; @@ -990,20 +1000,22 @@ int ObCopyTabletInfoObProducer::get_next_tablet_info(obrpc::ObCopyTabletInfo &ta ret = OB_ITER_END; } else { const ObTabletID &tablet_id = tablet_id_array_.at(tablet_index_); + tablet_info.tablet_id_ = tablet_id; if (OB_ISNULL(ls = ls_handle_.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream should not be NULL", K(ret), KP(ls)); - } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, timeout_us))) { + } else if (OB_FAIL(ObStorageHAUtils::get_server_version(tablet_info.version_))) { + LOG_WARN("failed to get server version", K(ret), K(tablet_info)); + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle)) + && OB_TABLET_NOT_EXIST != ret) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id), K(tablet_handle)); - if (OB_TABLET_NOT_EXIST == ret) { - //overwrite ret - if (OB_FAIL(build_deleted_tablet_info_(ls->get_ls_id(), tablet_id, tablet_info))) { - LOG_WARN("failed to build delete tablet info", K(ret), KPC(ls), K(tablet_id)); - } else { - tablet_index_++; - } + } else if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + tablet_info.status_ = ObCopyTabletStatus::TABLET_NOT_EXIST; + if (OB_FAIL(tablet_info.param_.build_deleted_tablet_info(ls->get_ls_id(), tablet_id))) { + LOG_WARN("failed to build deleted tablet info", K(ret), K(tablet_id)); } else { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id), K(tablet_handle)); + LOG_INFO("tablet not exist, build deleted tablet info", K(tablet_id)); } } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; @@ -1012,61 +1024,11 @@ int ObCopyTabletInfoObProducer::get_next_tablet_info(obrpc::ObCopyTabletInfo &ta LOG_WARN("failed to build migration tablet param", K(ret), K(tablet_id)); } else if (OB_FAIL(tablet->get_ha_sstable_size(tablet_info.data_size_))) { LOG_WARN("failed to get sstable size", K(ret), K(tablet_id)); - } else if (OB_FAIL(ObStorageHAUtils::get_server_version(tablet_info.version_))) { - LOG_WARN("failed to get server version", K(ret), K(tablet_info)); } else { - tablet_info.tablet_id_ = tablet_id; tablet_info.status_ = ObCopyTabletStatus::TABLET_EXIST; - tablet_index_++; LOG_INFO("succeed get copy tablet info", K(tablet_info), K(tablet_index_)); } - } - return ret; -} - -int ObCopyTabletInfoObProducer::build_deleted_tablet_info_( - const share::ObLSID &ls_id, - const ObTabletID &tablet_id, - obrpc::ObCopyTabletInfo &tablet_info) -{ - int ret = OB_SUCCESS; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("copy tablet info ob producer do not init", K(ret)); - } else if (OB_FAIL(ObStorageHAUtils::get_server_version(tablet_info.version_))) { - LOG_WARN("failed to get server version", K(ret)); - } else { - const ObTabletRestoreStatus::STATUS restore_status = ObTabletRestoreStatus::FULL; - const ObTabletDataStatus::STATUS data_status = ObTabletDataStatus::COMPLETE; - tablet_info.tablet_id_ = tablet_id; - tablet_info.status_ = ObCopyTabletStatus::TABLET_NOT_EXIST; - tablet_info.param_.ls_id_ = ls_id; - tablet_info.param_.tablet_id_ = tablet_id; - tablet_info.param_.data_tablet_id_ = tablet_id; - tablet_info.param_.create_scn_ = ObTabletMeta::INIT_CREATE_SCN; - tablet_info.param_.start_scn_ = ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN; - tablet_info.param_.clog_checkpoint_scn_ = ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN; - tablet_info.param_.compat_mode_ = lib::Worker::get_compatibility_mode(); - tablet_info.param_.multi_version_start_ = 0; - tablet_info.param_.snapshot_version_ = 0; - tablet_info.param_.tx_data_.tablet_status_ = ObTabletStatus::DELETED; - tablet_info.param_.tx_data_.tx_id_ = ObTabletCommon::FINAL_TX_ID; - tablet_info.param_.tx_data_.tx_scn_ = SCN::min_scn(); - - if (OB_FAIL(tablet_info.param_.ha_status_.set_restore_status(restore_status))) { - LOG_WARN("failed to set restore status", K(ret), K(restore_status)); - } else if (OB_FAIL(tablet_info.param_.ha_status_.set_data_status(data_status))) { - LOG_WARN("failed to set data status", K(ret), K(data_status)); - } else if (OB_FAIL(ObMigrationTabletParam::construct_placeholder_storage_schema_and_medium( - tablet_info.param_.allocator_, - tablet_info.param_.storage_schema_, - tablet_info.param_.medium_info_list_))) { - LOG_WARN("failed to construct placeholder storage schema"); - } else if (!tablet_info.param_.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("create tablet param is invalid", K(ret), K(tablet_info)); - } + tablet_index_++; } return ret; } @@ -1400,15 +1362,21 @@ int ObCopySSTableInfoRestoreReader::get_next_tablet_sstable_header( ret = OB_ERR_UNEXPECTED; LOG_WARN("sstable iter do not reach end, unexpected", K(ret), K(tablet_index_)); } else if (FALSE_IT(tablet_id = tablet_id_array_.at(tablet_index_))) { + } else if (FALSE_IT(copy_header.tablet_id_ = tablet_id)) { + } else if (OB_FAIL(get_backup_tablet_meta_(tablet_id, copy_header))) { + LOG_WARN("failed to get tablet meta", K(ret), K(tablet_id)); + } else if (ObCopyTabletStatus::TABLET_NOT_EXIST == copy_header.status_) { + sstable_index_ = 0; + is_sstable_iter_end_ = true; + copy_header.sstable_count_ = 0; + // TODO(wangxiaohui.wxh): to correct the version + copy_header.version_ = 0; // restore version is not valid + tablet_index_++; } else if (OB_FAIL(get_backup_sstable_metas_(tablet_id))) { LOG_WARN("failed to get backup sstable metas", K(ret), K(tablet_id), KPC(restore_base_info_)); - } else if (OB_FAIL(get_tablet_meta_(tablet_id, copy_header.tablet_meta_))) { - LOG_WARN("failed to get tablet meta", K(ret), K(tablet_id)); } else { sstable_index_ = 0; - is_sstable_iter_end_ = false; - copy_header.tablet_id_ = tablet_id; - copy_header.status_ = ObCopyTabletStatus::TABLET_EXIST; + is_sstable_iter_end_ = backup_sstable_meta_array_.count() > 0 ? false : true; copy_header.sstable_count_ = backup_sstable_meta_array_.count(); copy_header.version_ = 0; // restore version is not valid tablet_index_++; @@ -1416,85 +1384,84 @@ int ObCopySSTableInfoRestoreReader::get_next_tablet_sstable_header( return ret; } -int ObCopySSTableInfoRestoreReader::get_tablet_meta_( + +int ObCopySSTableInfoRestoreReader::get_backup_tablet_meta_( const common::ObTabletID &tablet_id, - ObMigrationTabletParam &tablet_meta) + obrpc::ObCopyTabletSSTableHeader ©_header) { int ret = OB_SUCCESS; ObLS *ls = nullptr; - ObTabletHandle tablet_handle; - ObTablet *tablet = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("copy sstable info restore reader do not init", K(ret)); - } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls should not be NULL", K(ret), KP(ls)); - } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); - } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_id)); - } else if (OB_FAIL(tablet->build_migration_tablet_param(tablet_meta))) { - LOG_WARN("failed to build migration tablet param", K(ret), K(tablet_id)); - } else if (OB_FAIL(update_tablet_meta_if_restore_major_(tablet_id, tablet_handle, tablet_meta))) { - LOG_WARN("may update tablet meta failed", K(ret), K(tablet_id)); - } - return ret; -} - -int ObCopySSTableInfoRestoreReader::update_tablet_meta_if_restore_major_( - const common::ObTabletID &tablet_id, - ObTabletHandle &tablet_handle, - ObMigrationTabletParam &tablet_meta) -{ - int ret = OB_SUCCESS; - if (ObTabletRestoreAction::is_restore_major(restore_action_)) { - bool need_update_storage_schema = false; - backup::ObBackupTabletMeta backup_tablet_meta; - if (OB_FAIL(get_backup_major_tablet_meta_(tablet_id, backup_tablet_meta))) { - LOG_WARN("failed to get major tablet storage schema", K(ret), K(tablet_id)); - } else if (OB_FAIL(tablet_meta.assign(backup_tablet_meta.tablet_meta_))) { - LOG_WARN("failed to assign tablet meta", K(ret), K(backup_tablet_meta)); - } - } - return ret; -} - -int ObCopySSTableInfoRestoreReader::get_backup_major_tablet_meta_( - const common::ObTabletID &tablet_id, - backup::ObBackupTabletMeta &tablet_meta) -{ - int ret = OB_SUCCESS; + ObTabletHandle local_tablet_handle; + ObTablet *local_tablet = nullptr; backup::ObBackupMetaIndex tablet_meta_index; share::ObBackupPath backup_path; + if (OB_ISNULL(restore_base_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get invalid args", K(ret), KP(restore_base_info_)); + } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, local_tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_ISNULL(local_tablet = local_tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(local_tablet), K(tablet_id)); } else { const ObBackupDest &backup_dest = restore_base_info_->backup_dest_; const share::ObBackupStorageInfo *storage_info = backup_dest.get_storage_info(); - if (OB_FAIL(fetch_backup_major_tablet_meta_index_(tablet_id, tablet_meta_index))) { - LOG_WARN("failed to fetch backup tablet meta index", K(ret), K(tablet_id)); - } else if (OB_FAIL(get_backup_tablet_meta_backup_path_(backup_dest, tablet_meta_index, backup_path))) { + ObBackupDataType backup_data_type; + if (tablet_id.is_ls_inner_tablet()) { + backup_data_type.set_sys_data_backup(); + } else if (ObTabletRestoreAction::is_restore_major(restore_action_)) { + backup_data_type.set_major_data_backup(); + } else { + backup_data_type.set_minor_data_backup(); + } + backup::ObBackupTabletMeta backup_tablet_meta; + if (OB_FAIL(fetch_backup_tablet_meta_index_(tablet_id, backup_data_type, tablet_meta_index)) + && OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("failed to fetch backup tablet meta index", K(ret), K(tablet_id), K(backup_data_type)); + } else if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + copy_header.status_ = ObCopyTabletStatus::TABLET_NOT_EXIST; + LOG_INFO("tablet not exist", K(tablet_id), K(backup_data_type)); + } else if (OB_FAIL(get_backup_tablet_meta_backup_path_(backup_dest, backup_data_type, tablet_meta_index, backup_path))) { LOG_WARN("failed to get tablet backup path", K(ret), K(backup_dest), K(tablet_meta_index)); - } else if (OB_FAIL(read_backup_major_tablet_meta_(backup_path, storage_info, tablet_meta_index, tablet_meta))) { + } else if (OB_FAIL(read_backup_tablet_meta_(backup_path, storage_info, backup_data_type, tablet_meta_index, backup_tablet_meta))) { LOG_WARN("failed to read backup major tablet meta", K(ret), K(backup_path), K(tablet_meta_index)); + } else if (!backup_tablet_meta.is_valid() + || !backup_tablet_meta.tablet_meta_.ha_status_.is_none()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backup tablet meta is invalid", K(ret), K(tablet_id), K(backup_data_type), K(backup_tablet_meta)); + } else if (!ObTabletRestoreAction::is_restore_major(restore_action_) + && local_tablet->get_tablet_meta().transfer_info_.transfer_seq_ != backup_tablet_meta.tablet_meta_.transfer_info_.transfer_seq_) { + // If transfer seq of backup tablet is not equal to local tablet, + // treat it as tablet not exist when restore minor. But, transfer seq + // should not be compared when restore major. + copy_header.status_ = ObCopyTabletStatus::TABLET_NOT_EXIST; + LOG_INFO("tablet not exist as transfer seq is not equal", + K(tablet_id), + K(backup_data_type), + "local tablet meta", local_tablet->get_tablet_meta(), + "backup tablet meta", backup_tablet_meta.tablet_meta_); + } else if (OB_FAIL(copy_header.tablet_meta_.assign(backup_tablet_meta.tablet_meta_))) { + LOG_WARN("failed to assign tablet meta", K(ret), K(backup_tablet_meta)); + } else { + copy_header.status_ = ObCopyTabletStatus::TABLET_EXIST; + LOG_INFO("succeed get backup tablet meta", K(tablet_id), K(backup_data_type), "meta", copy_header.tablet_meta_); } } return ret; } -int ObCopySSTableInfoRestoreReader::fetch_backup_major_tablet_meta_index_( +int ObCopySSTableInfoRestoreReader::fetch_backup_tablet_meta_index_( const common::ObTabletID &tablet_id, + const share::ObBackupDataType &backup_data_type, backup::ObBackupMetaIndex &meta_index) { int ret = OB_SUCCESS; meta_index.reset(); - ObBackupDataType backup_data_type; - backup_data_type.set_major_data_backup(); backup::ObBackupMetaType meta_type = backup::ObBackupMetaType::BACKUP_TABLET_META; if (!tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; @@ -1503,47 +1470,48 @@ int ObCopySSTableInfoRestoreReader::fetch_backup_major_tablet_meta_index_( ret = OB_ERR_UNEXPECTED; LOG_WARN("should not be null", K(ret)); } else if (OB_FAIL(meta_index_store_->get_backup_meta_index( - backup_data_type, tablet_id, meta_type, meta_index))) { - LOG_WARN("failed to get meta index", K(ret), K(tablet_id)); + backup_data_type, + tablet_id, + meta_type, + meta_index))) { + LOG_WARN("failed to get meta index", K(ret), K(tablet_id), K(backup_data_type)); } else { - LOG_INFO("get backup meta index", K(meta_index)); + LOG_INFO("get backup meta index", K(tablet_id), K(backup_data_type), K(meta_index)); } return ret; } int ObCopySSTableInfoRestoreReader::get_backup_tablet_meta_backup_path_( const share::ObBackupDest &backup_dest, + const share::ObBackupDataType &backup_data_type, const backup::ObBackupMetaIndex &meta_index, ObBackupPath &backup_path) { int ret = OB_SUCCESS; - ObBackupDataType backup_data_type; - backup_data_type.set_major_data_backup(); if (!backup_dest.is_valid() || !meta_index.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(meta_index), K(backup_dest)); } else if (OB_FAIL(ObBackupPathUtil::get_macro_block_backup_path(backup_dest, meta_index.ls_id_, backup_data_type, meta_index.turn_id_, meta_index.retry_id_, meta_index.file_id_, backup_path))) { - LOG_WARN("failed to get macro block backup path", K(ret), K(meta_index)); + LOG_WARN("failed to get macro block backup path", K(ret), K(backup_data_type), K(meta_index)); } else { - LOG_INFO("get macro block backup path", K(backup_path), K(meta_index)); + LOG_INFO("get macro block backup path", K(backup_data_type), K(backup_path), K(meta_index)); } return ret; } -int ObCopySSTableInfoRestoreReader::read_backup_major_tablet_meta_( +int ObCopySSTableInfoRestoreReader::read_backup_tablet_meta_( const share::ObBackupPath &backup_path, const share::ObBackupStorageInfo *storage_info, + const share::ObBackupDataType &backup_data_type, const backup::ObBackupMetaIndex &meta_index, backup::ObBackupTabletMeta &tablet_meta) { int ret = OB_SUCCESS; - share::ObBackupDataType backup_data_type; - backup_data_type.set_major_data_backup(); if (OB_FAIL(backup::ObLSBackupRestoreUtil::read_tablet_meta( backup_path.get_obstr(), storage_info, backup_data_type, meta_index, tablet_meta))) { - LOG_WARN("failed to read tablet meta", K(ret), K(backup_path), K(meta_index)); + LOG_WARN("failed to read tablet meta", K(ret), K(backup_path), K(meta_index), K(backup_data_type)); } return ret; } @@ -1556,11 +1524,17 @@ int ObCopySSTableInfoRestoreReader::compare_storage_schema_( { int ret = OB_SUCCESS; need_update = false; - const int64_t old_storage_schema_version = tablet_handle.get_obj()->get_storage_schema().schema_version_; - const int64_t new_storage_schema_version = tablet_meta.tablet_meta_.storage_schema_.schema_version_; - if (new_storage_schema_version > old_storage_schema_version) { + int64_t old_storage_schema_stored_col_cnt = 0; + const int64_t new_storage_schema_stored_col_cnt = tablet_meta.tablet_meta_.storage_schema_.store_column_cnt_; + ObArenaAllocator temp_allocator("RestoreReader", MTL_ID()); + const ObStorageSchema *schema_on_tablet = nullptr; + + if (OB_FAIL(tablet_handle.get_obj()->load_storage_schema(temp_allocator, schema_on_tablet))) { + LOG_WARN("failed to load storage schema", K(ret), K(tablet_handle)); + } else if (FALSE_IT(old_storage_schema_stored_col_cnt = schema_on_tablet->store_column_cnt_)) { + } else if (tablet_meta.tablet_meta_.storage_schema_.compare_schema_newer(*schema_on_tablet)) { // schema_on_tablet is newer need_update = true; - LOG_INFO("storage schema version", K(old_storage_schema_version), K(new_storage_schema_version), K(tablet_id)); + LOG_INFO("storage schema stored cnt compare", K(old_storage_schema_stored_col_cnt), K(new_storage_schema_stored_col_cnt), K(tablet_id)); #ifdef ERRSIM const int64_t old_multi_version_start = tablet_handle.get_obj()->get_multi_version_start(); const int64_t old_snapshot_version = tablet_handle.get_obj()->get_snapshot_version(); @@ -1568,13 +1542,14 @@ int ObCopySSTableInfoRestoreReader::compare_storage_schema_( const int64_t new_snapshot_version = tablet_meta.tablet_meta_.snapshot_version_; SERVER_EVENT_SYNC_ADD("storage_ha", "need_update_tablet_schema", "tablet_id", tablet_id.id(), - "old_storage_schema_version", old_storage_schema_version, - "new_storage_schema_version", new_storage_schema_version, + "old_storage_stored_col_cnt", old_storage_schema_stored_col_cnt, + "new_storage_stored_col_cnt", new_storage_schema_stored_col_cnt, "old_snapshot_version", old_snapshot_version, "new_snapshot_version", new_snapshot_version, "new_mult_version_start", new_multi_version_sstart); #endif } + ObTablet::free_storage_schema(temp_allocator, schema_on_tablet); return ret; } @@ -1601,7 +1576,7 @@ int ObCopyTabletsSSTableInfoObProducer::init( if (is_inited_) { ret = OB_INIT_TWICE; LOG_WARN("copy tablets sstable info ob producer init twice", K(ret)); - } else if (OB_INVALID_ID == tenant_id || !ls_id.is_valid() || tablet_sstable_info_array.empty()) { + } else if (OB_INVALID_ID == tenant_id || !ls_id.is_valid() || tablet_sstable_info_array.count() < 0) { ret = OB_INVALID_ARGUMENT; LOG_WARN("copy sstable info ob producer init get invalid argument", K(ret), K(tenant_id), K(ls_id)); } else if (tenant_id != MTL_ID()) { @@ -1666,8 +1641,7 @@ int ObCopySSTableInfoObProducer::init( ret = OB_INVALID_ARGUMENT; LOG_WARN("copy sstable info ob producer init get invalid argument", K(ret), K(tablet_sstable_info), KP(ls)); - } else if (OB_FAIL(ls->get_tablet(tablet_sstable_info.tablet_id_, tablet_handle_, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls->ha_get_tablet(tablet_sstable_info.tablet_id_, tablet_handle_))) { if (OB_TABLET_NOT_EXIST == ret) { status_ = ObCopyTabletStatus::TABLET_NOT_EXIST; ret = OB_SUCCESS; @@ -1678,9 +1652,9 @@ int ObCopySSTableInfoObProducer::init( ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), K(tablet_sstable_info)); } else if (!tablet_sstable_info.minor_sstable_scn_range_.is_empty() - && tablet->get_tablet_meta().start_scn_ > tablet_sstable_info.minor_sstable_scn_range_.start_scn_) { + && tablet->get_tablet_meta().clog_checkpoint_scn_ < tablet_sstable_info.minor_sstable_scn_range_.end_scn_) { ret = OB_SSTABLE_NOT_EXIST; - LOG_WARN("src tablet start clog ts is bigger than dest needed log ts", + LOG_WARN("src tablet clog_checkpoint_scn is smaller than dest needed log ts", K(ret), K(tablet_sstable_info), KPC(tablet)); } else if (!tablet_sstable_info.ddl_sstable_scn_range_.is_empty()) { if (tablet->get_tablet_meta().get_ddl_sstable_start_scn() < tablet_sstable_info.ddl_sstable_scn_range_.start_scn_) { @@ -1819,22 +1793,19 @@ int ObCopySSTableInfoObProducer::get_copy_sstable_count_(int64_t &sstable_count) { int ret = OB_SUCCESS; sstable_count = 0; - ObTableStoreIterator tmp_iterator; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("copy sstable info ob producer do not init", K(ret)); } else if (0 == iter_.count()) { sstable_count = 0; - } else if (OB_FAIL(tmp_iterator.copy(iter_))) { - LOG_WARN("failed to copy sstable iter", K(ret)); } else { while (OB_SUCC(ret)) { ObITable *table = nullptr; ObSSTable *sstable = nullptr; bool need_copy_sstable = false; - if (OB_FAIL(tmp_iterator.get_next(table))) { + if (OB_FAIL(iter_.get_next(table))) { if (OB_ITER_END != ret) { LOG_WARN("failed to get next table", K(ret), K(tablet_sstable_info_)); } else { @@ -1854,6 +1825,7 @@ int ObCopySSTableInfoObProducer::get_copy_sstable_count_(int64_t &sstable_count) sstable_count++; } } + iter_.resume(); } return ret; } @@ -1910,43 +1882,17 @@ int ObCopySSTableInfoObProducer::get_tablet_meta_(ObMigrationTabletParam &tablet return ret; } -//TODO(muwei.ym) This code will not been needed in 4.2 int ObCopySSTableInfoObProducer::fake_deleted_tablet_meta_( ObMigrationTabletParam &tablet_meta) { int ret = OB_SUCCESS; tablet_meta.reset(); - const ObTabletRestoreStatus::STATUS restore_status = ObTabletRestoreStatus::FULL; - const ObTabletDataStatus::STATUS data_status = ObTabletDataStatus::COMPLETE; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("copy sstable info ob producer do not init", K(ret)); - } else { - tablet_meta.ls_id_ = ls_id_; - tablet_meta.tablet_id_ = tablet_sstable_info_.tablet_id_; - tablet_meta.data_tablet_id_ = tablet_sstable_info_.tablet_id_; - tablet_meta.create_scn_ = ObTabletMeta::INIT_CREATE_SCN; - tablet_meta.start_scn_ = ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN; - tablet_meta.clog_checkpoint_scn_.set_max(); - tablet_meta.compat_mode_ = lib::Worker::get_compatibility_mode(); - tablet_meta.multi_version_start_ = 0; - tablet_meta.snapshot_version_ = 0; - tablet_meta.tx_data_.tablet_status_ = ObTabletStatus::DELETED; - - if (OB_FAIL(tablet_meta.ha_status_.set_restore_status(restore_status))) { - LOG_WARN("failed to set restore status", K(ret), K(restore_status)); - } else if (OB_FAIL(tablet_meta.ha_status_.set_data_status(data_status))) { - LOG_WARN("failed to set data status", K(ret), K(data_status)); - } else if (OB_FAIL(ObMigrationTabletParam::construct_placeholder_storage_schema_and_medium( - tablet_meta.allocator_, - tablet_meta.storage_schema_, - tablet_meta.medium_info_list_))) { - LOG_WARN("failed to construct placeholder storage schema"); - } else if (!tablet_meta.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("create deleted tablet meta is invalid", K(ret), K(tablet_meta)); - } + } else if (OB_FAIL(tablet_meta.build_deleted_tablet_info(ls_id_, tablet_sstable_info_.tablet_id_))) { + LOG_WARN("failed to build deleted tablet info", K(ret), K(ls_id_), K(tablet_sstable_info_)); } return ret; } @@ -2129,7 +2075,7 @@ int ObCopySSTableMacroRestoreReader::get_next_sstable_range_info_( LOG_WARN("get next sstable range info get invalid argument", K(ret), K(table_key)); } else { SMART_VAR(ObRestoreMacroBlockIdMgr, restore_block_id_mgr) { - if (OB_FAIL(restore_block_id_mgr.init(rpc_arg_.ls_id_, rpc_arg_.tablet_id_, table_key, *restore_base_info_, *second_meta_index_store_))) { + if (OB_FAIL(restore_block_id_mgr.init(rpc_arg_.tablet_id_, table_key, *restore_base_info_, *second_meta_index_store_))) { LOG_WARN("failed to init restore block id mgr", K(ret), K(rpc_arg_), K(table_key)); } else if (OB_FAIL(restore_block_id_mgr.get_restore_macro_block_id_array(block_id_array))) { LOG_WARN("failed to get restore macro block id array", K(ret), K(rpc_arg_), K(table_key)); @@ -2227,7 +2173,7 @@ int ObCopySSTableMacroObProducer::init( } else if (OB_UNLIKELY(nullptr == (ls = ls_handle_.get_ls()))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream should not be NULL", KR(ret), K(tenant_id), K(ls_id)); - } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle_, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle_))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); } else if (OB_FAIL(copy_table_key_array_.assign(copy_table_key_array))) { LOG_WARN("failed to assign sstable array", K(ret), K(tenant_id), K(ls_id), K(tablet_id), K(copy_table_key_array)); @@ -2278,7 +2224,7 @@ int ObCopySSTableMacroObProducer::get_next_sstable_macro_range_info_( } else if (OB_ISNULL(tablet = tablet_handle_.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), K(copy_table_key)); - } else if (OB_FAIL(tablet->get_table_store().get_table(copy_table_key, table_handle))) { + } else if (OB_FAIL(tablet->get_table(copy_table_key, table_handle))) { LOG_WARN("failed to get table handle", K(ret), K(copy_table_key)); if (OB_ENTRY_NOT_EXIST == ret) { ret = OB_SSTABLE_NOT_EXIST; @@ -2287,7 +2233,7 @@ int ObCopySSTableMacroObProducer::get_next_sstable_macro_range_info_( LOG_WARN("failed to get sstable", K(ret), K(copy_table_key)); } else { macro_range_info_header.copy_table_key_ = copy_table_key; - const int64_t macro_block_count = sstable->get_meta().get_basic_meta().data_macro_block_count_; + const int64_t macro_block_count = sstable->get_data_macro_block_count(); if (0 == macro_block_count) { macro_range_info_header.macro_range_count_ = 0; } else { @@ -2347,12 +2293,12 @@ int ObCopySSTableMacroRangeObProducer::init( } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream should not be NULL", KR(ret), K(tenant_id), K(ls_id)); - } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle_, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle_))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); } else if (OB_ISNULL(tablet = tablet_handle_.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tenant_id), K(ls_id), K(tablet_id), K(header)); - } else if (OB_FAIL(tablet->get_table_store().get_table(header.copy_table_key_, table_handle_))) { + } else if (OB_FAIL(tablet->get_table(header.copy_table_key_, table_handle_))) { LOG_WARN("failed to get table", K(ret), K(tablet_id), K(header)); if (OB_ENTRY_NOT_EXIST == ret) { ret = OB_SSTABLE_NOT_EXIST; @@ -2361,7 +2307,7 @@ int ObCopySSTableMacroRangeObProducer::init( LOG_WARN("failed to get sstable", K(ret), K(header), K(tablet_id), K(ls_id)); } else if (FALSE_IT(datum_range_.set_whole_range())) { } else if (OB_FAIL(second_meta_iterator_.open(datum_range_, blocksstable::DATA_BLOCK_META, - *sstable, tablet->get_index_read_info(), allocator_, is_reverse_scan))) { + *sstable, tablet->get_rowkey_read_info(), allocator_, is_reverse_scan))) { LOG_WARN("failed to open second meta iterator", K(ret), K(header), K(tablet_id)); } else { table_key_ = header.copy_table_key_; @@ -2435,6 +2381,340 @@ int ObCopySSTableMacroRangeObProducer::get_next_macro_range_info( } -} +ObCopyTransferTabletInfoObReader::ObCopyTransferTabletInfoObReader() + : is_inited_(false), + rpc_reader_() +{ } +ObCopyTransferTabletInfoObReader::~ObCopyTransferTabletInfoObReader() +{ +} + +int ObCopyTransferTabletInfoObReader::init( + const ObStorageHASrcInfo &src_info, + const obrpc::ObTransferTabletInfoArg &rpc_arg, + obrpc::ObStorageRpcProxy &srv_rpc_proxy, + common::ObInOutBandwidthThrottle &bandwidth_throttle) +{ + int ret = OB_SUCCESS; + const int64_t FETCH_TABLET_INFO_TIMEOUT = GCONF._transfer_start_rpc_timeout; //default 10ms + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("can not init twice", K(ret)); + } else if (OB_UNLIKELY(!src_info.is_valid()) + || OB_UNLIKELY(!rpc_arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(src_info), K(rpc_arg)); + } else if (OB_FAIL(rpc_reader_.init(bandwidth_throttle))) { + LOG_WARN("fail to init tablet info rpc reader", K(ret)); + } else if (OB_FAIL(srv_rpc_proxy.to(src_info.src_addr_).by(OB_DATA_TENANT_ID).timeout(FETCH_TABLET_INFO_TIMEOUT).dst_cluster_id(src_info.cluster_id_) + .ratelimit(true).bg_flow(obrpc::ObRpcProxy::BACKGROUND_FLOW) + .fetch_transfer_tablet_info(rpc_arg, rpc_reader_.get_rpc_buffer(), rpc_reader_.get_handle()))) { + LOG_WARN("failed to send fetch tablet info rpc", K(ret), K(src_info), K(rpc_arg)); + } else { + is_inited_ = true; + LOG_INFO("[TRANSFER] succeed to init copy transfer tablet info reader", K(src_info), K(rpc_arg)); + } + + return ret; +} + +int ObCopyTransferTabletInfoObReader::fetch_tablet_info(obrpc::ObCopyTabletInfo &tablet_info) +{ + int ret = OB_SUCCESS; + tablet_info.reset(); + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("pg base data meta ob reader do not init", K(ret)); + } else if (OB_FAIL(rpc_reader_.fetch_and_decode(tablet_info))) { + if (OB_ITER_END != ret) { + LOG_WARN("fail to fetch and decode partition meta info", K(ret)); + } + } else if (!tablet_info.is_valid()) { + ret = OB_ERR_SYS; + LOG_ERROR("invalid tablet info", K(ret), K(tablet_info)); + } + return ret; +} + +ObCopyTransferTabletInfoObProducer::ObCopyTransferTabletInfoObProducer() + : is_inited_(false), + tablet_list_(), + tablet_index_(0), + ls_handle_() +{ +} + +ObCopyTransferTabletInfoObProducer::~ObCopyTransferTabletInfoObProducer() +{ +} + + +int ObCopyTransferTabletInfoObProducer::init( + const uint64_t tenant_id, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const common::ObIArray &tablet_list) +{ + int ret = OB_SUCCESS; + ObLSService *ls_service = nullptr; + + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("copy transfer table info ob producer init twice", K(ret)); + } else if (OB_INVALID_ID == tenant_id || !src_ls_id.is_valid() || tablet_list.empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("copy transfer tablet info ob producer init get invalid argument", K(ret), K(tenant_id), + K(src_ls_id), K(tablet_list)); + } else if (tenant_id != MTL_ID()) { + LOG_WARN("tenant is not match", K(ret), K(tenant_id)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(src_ls_id, ls_handle_, ObLSGetMod::HA_MOD))) { + LOG_WARN("fail to get log stream", KR(ret), K(tenant_id), K(src_ls_id)); + } else if (OB_UNLIKELY(nullptr == (ls_handle_.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", KR(ret), K(tenant_id), K(src_ls_id)); + } else if (OB_FAIL(tablet_list_.assign(tablet_list))) { + LOG_WARN("failed to assign list", K(ret), K(tenant_id), K(src_ls_id), K(tablet_list)); + } else { + src_ls_id_ = src_ls_id; + dest_ls_id_ = dest_ls_id; + is_inited_ = true; + } + return ret; +} + +int ObCopyTransferTabletInfoObProducer::get_next_tablet_info( + obrpc::ObCopyTabletInfo &tablet_info) +{ + int ret = OB_SUCCESS; + tablet_info.reset(); + ObLS *ls = nullptr; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletTxMultiSourceDataUnit tx_data; + ObArray memtables; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("copy tablet info ob producer do not init", K(ret)); + } else if (tablet_index_ == tablet_list_.count()) { + ret = OB_ITER_END; + } else { + const ObTransferTabletInfo &transfer_tablet_info = tablet_list_.at(tablet_index_); + if (OB_ISNULL(ls = ls_handle_.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", K(ret), KP(ls)); + } else if (OB_FAIL(ls->ha_get_tablet(transfer_tablet_info.tablet_id_, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(transfer_tablet_info), K(tablet_handle)); + } else if (OB_FAIL(get_next_tablet_info_(transfer_tablet_info, tablet_handle, tablet_info))) { + LOG_WARN("failed to get next tablet info ", K(ret), K(transfer_tablet_info), K(tablet_handle)); + } else if (OB_FAIL(ObStorageHAUtils::get_server_version(tablet_info.version_))) { + LOG_WARN("failed to get server version", K(ret)); + } else { + tablet_info.tablet_id_ = transfer_tablet_info.tablet_id_; + tablet_info.status_ = ObCopyTabletStatus::TABLET_EXIST; + tablet_index_++; + LOG_INFO("[TRANSFER] succeed get copy tablet info", K(tablet_info), K(transfer_tablet_info), K(tablet_index_)); + } + } + return ret; +} + +int ObCopyTransferTabletInfoObProducer::get_next_tablet_info_( + const ObTransferTabletInfo &transfer_tablet_info, + ObTabletHandle &tablet_handle, + obrpc::ObCopyTabletInfo &tablet_info) +{ + int ret = OB_SUCCESS; + tablet_info.reset(); + ObTabletCreateDeleteMdsUserData user_data; + ObTablet *tablet = nullptr; + bool unused_committed_flag = false; + + if (!transfer_tablet_info.is_valid() || !tablet_handle.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get next tablet info get invalid argument", K(ret), K(transfer_tablet_info), K(tablet_handle)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(transfer_tablet_info)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_latest_tablet_status(user_data, unused_committed_flag))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet), K(tablet_info)); + } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet status is unexpected", K(ret), KPC(tablet), K(transfer_tablet_info), K(user_data)); + } else if (transfer_tablet_info.transfer_seq_ != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet transfer seq is unexpected", K(ret), KPC(tablet), K(transfer_tablet_info)); + } else if (OB_FAIL(tablet->build_transfer_tablet_param(dest_ls_id_, tablet_info.param_))) { + LOG_WARN("failed to build transfer tablet param", K(ret), K(transfer_tablet_info)); + } else if (OB_FAIL(tablet->get_ha_sstable_size(tablet_info.data_size_))) { + LOG_WARN("failed to get sstable size", K(ret), K(transfer_tablet_info)); + } + return ret; +} + + +// ObCopyLSViewInfoObReader +ObCopyLSViewInfoObReader::ObCopyLSViewInfoObReader() + : is_inited_(false), + rpc_reader_(), + allocator_("CPLSVObReader") +{ +} + +int ObCopyLSViewInfoObReader::init( + const ObStorageHASrcInfo &src_info, + const obrpc::ObCopyLSViewArg &rpc_arg, + obrpc::ObStorageRpcProxy &srv_rpc_proxy, + common::ObInOutBandwidthThrottle &bandwidth_throttle) +{ + int ret = OB_SUCCESS; + + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("can not init twice", K(ret)); + } else if (OB_UNLIKELY(!src_info.is_valid()) + || OB_UNLIKELY(!rpc_arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(src_info), K(rpc_arg)); + } else if (OB_FAIL(rpc_reader_.init(bandwidth_throttle))) { + LOG_WARN("fail to init tablet info rpc reader", K(ret)); + } else if (OB_FAIL(srv_rpc_proxy.to(src_info.src_addr_).by(OB_DATA_TENANT_ID) + .timeout(FETCH_LS_VIEW_INFO_TIMEOUT).dst_cluster_id(src_info.cluster_id_) + .ratelimit(true).bg_flow(obrpc::ObRpcProxy::BACKGROUND_FLOW) + .fetch_ls_view(rpc_arg, rpc_reader_.get_rpc_buffer(), rpc_reader_.get_handle()))) { + LOG_WARN("failed to send fetch ls view info rpc", K(ret), K(src_info), K(rpc_arg)); + } else if (OB_FAIL(rpc_reader_.fetch_and_decode(ls_meta_))) { + LOG_WARN("fail to fetch and decode ls meta", K(ret)); + } else if (!ls_meta_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid ls meta", K(ret), K_(ls_meta)); + } else { + is_inited_ = true; + LOG_INFO("succeed to init fetch ls view info reader", K(src_info), K(rpc_arg)); + } + return ret; +} + +int ObCopyLSViewInfoObReader::get_ls_meta( + ObLSMetaPackage &ls_meta) +{ + int ret = OB_SUCCESS; + ls_meta.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObCopyLSViewInfoObReader not init", K(ret)); + } else { + ls_meta = ls_meta_; + } + + return ret; +} + +int ObCopyLSViewInfoObReader::get_next_tablet_info( + obrpc::ObCopyTabletInfo &tablet_info) +{ + int ret = OB_SUCCESS; + tablet_info.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObCopyLSViewInfoObReader not init", K(ret)); + } else if (OB_FAIL(rpc_reader_.fetch_and_decode(tablet_info))) { + if (OB_ITER_END == ret) { + //do nothing + } else { + LOG_WARN("fail to fetch and decode tablet meta", K(ret)); + } + } else if (!tablet_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tablet meta", K(ret), K(tablet_info)); + } + + return ret; +} + + +ObCopyLSViewInfoRestoreReader::ObCopyLSViewInfoRestoreReader() + : is_inited_(false), + ls_id_(), + restore_base_info_(nullptr), + reader_() +{ +} + +int ObCopyLSViewInfoRestoreReader::init( + const share::ObLSID &ls_id, + const ObRestoreBaseInfo &restore_base_info) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("can not init twice", K(ret)); + } else if (OB_UNLIKELY(!ls_id.is_valid()) + || OB_UNLIKELY(!restore_base_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(ls_id), K(restore_base_info)); + } else if (OB_FAIL(reader_.init(restore_base_info.backup_dest_, ls_id))) { + LOG_WARN("fail to init reader", K(ret), K(restore_base_info), K(ls_id)); + } else { + ls_id_ = ls_id; + restore_base_info_ = &restore_base_info; + is_inited_ = true; + LOG_INFO("succeed to init copy ls view info restore reader", K(ls_id), K(restore_base_info)); + } + return ret; +} + +int ObCopyLSViewInfoRestoreReader::get_ls_meta( + ObLSMetaPackage &ls_meta) +{ + int ret = OB_SUCCESS; + ObBackupDataStore store; + ls_meta.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObCopyLSViewInfoRestoreReader not init", K(ret)); + } else if (OB_FAIL(store.init(restore_base_info_->backup_dest_))) { + LOG_WARN("fail to init backup data store", K(ret), KPC_(restore_base_info)); + } else if (OB_FAIL(store.read_ls_meta_infos(ls_id_, ls_meta))) { + LOG_WARN("fail to read ls meta info", K(ret), K_(ls_id)); + } else { + LOG_INFO("read ls meta info", K_(ls_id), K(ls_meta)); + } + + return ret; +} + +int ObCopyLSViewInfoRestoreReader::get_next_tablet_info( + obrpc::ObCopyTabletInfo &tablet_info) +{ + int ret = OB_SUCCESS; + tablet_info.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObCopyLSViewInfoRestoreReader not init", K(ret)); + } else if (OB_FAIL(reader_.get_next(tablet_info.param_))) { + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next tablet meta", K(ret)); + } + } else { + tablet_info.data_size_ = 0; + tablet_info.status_ = ObCopyTabletStatus::TABLET_EXIST; + tablet_info.tablet_id_ = tablet_info.param_.tablet_id_; + tablet_info.version_ = 0; + } + + return ret; +} +} +} diff --git a/src/storage/high_availability/ob_storage_ha_reader.h b/src/storage/high_availability/ob_storage_ha_reader.h index 26f4a32c4..0120042c4 100644 --- a/src/storage/high_availability/ob_storage_ha_reader.h +++ b/src/storage/high_availability/ob_storage_ha_reader.h @@ -16,6 +16,7 @@ #include "storage/meta_mem/ob_tablet_handle.h" #include "share/ob_define.h" #include "lib/utility/ob_macro_utils.h" +#include "lib/function/ob_function.h" #include "rpc/obrpc/ob_rpc_packet.h" #include "ob_storage_ha_struct.h" #include "storage/blocksstable/ob_block_manager.h" @@ -25,6 +26,7 @@ #include "ob_storage_restore_struct.h" #include "storage/blocksstable/ob_sstable_sec_meta_iterator.h" #include "storage/tx_storage/ob_ls_handle.h" +#include "storage/backup/ob_backup_data_store.h" namespace oceanbase { @@ -77,6 +79,7 @@ struct ObCopyMacroBlockReaderInitParam final ObRestoreMacroBlockIdMgr *restore_macro_block_id_mgr_; bool need_check_seq_; int64_t ls_rebuild_seq_; + share::SCN backfill_tx_scn_; private: DISALLOW_COPY_AND_ASSIGN(ObCopyMacroBlockReaderInitParam); @@ -193,7 +196,6 @@ private: ObTabletHandle tablet_handle_; ObTableHandleV2 sstable_handle_; const ObSSTable *sstable_; - const ObSSTableMeta *meta_; ObDatumRange datum_range_; common::ObArenaAllocator allocator_; ObSSTableSecMetaIterator second_meta_iterator_; @@ -267,11 +269,6 @@ public: const common::ObIArray &tablet_id_array); int get_next_tablet_info(obrpc::ObCopyTabletInfo &tablet_info); -private: - int build_deleted_tablet_info_( - const share::ObLSID &ls_id, - const ObTabletID &tablet_id, - obrpc::ObCopyTabletInfo &tablet_info); private: bool is_inited_; ObArray tablet_id_array_; @@ -361,26 +358,22 @@ private: common::ObIArray &backup_sstable_meta_array); int set_backup_sstable_meta_array_( const common::ObIArray &backup_sstable_meta_array); - int get_tablet_meta_( + int get_backup_tablet_meta_( const common::ObTabletID &tablet_id, - ObMigrationTabletParam &tablet_meta); - int update_tablet_meta_if_restore_major_( - const common::ObTabletID &tablet_id, - ObTabletHandle &tablet_handle, - ObMigrationTabletParam &tablet_meta); - int get_backup_major_tablet_meta_( - const common::ObTabletID &tablet_id, - backup::ObBackupTabletMeta &tablet_meta); - int fetch_backup_major_tablet_meta_index_( + obrpc::ObCopyTabletSSTableHeader ©_header); + int fetch_backup_tablet_meta_index_( const common::ObTabletID &tablet_id, + const share::ObBackupDataType &backup_data_type, backup::ObBackupMetaIndex &meta_index); int get_backup_tablet_meta_backup_path_( const share::ObBackupDest &backup_dest, + const share::ObBackupDataType &backup_data_type, const backup::ObBackupMetaIndex &meta_index, share::ObBackupPath &backup_path); - int read_backup_major_tablet_meta_( + int read_backup_tablet_meta_( const share::ObBackupPath &backup_path, const share::ObBackupStorageInfo *storage_info, + const share::ObBackupDataType &backup_data_type, const backup::ObBackupMetaIndex &meta_index, backup::ObBackupTabletMeta &tablet_meta); int compare_storage_schema_( @@ -599,6 +592,130 @@ private: DISALLOW_COPY_AND_ASSIGN(ObCopySSTableMacroRangeObProducer); }; +class ObCopyTransferTabletInfoObReader +{ +public: + ObCopyTransferTabletInfoObReader(); + virtual ~ObCopyTransferTabletInfoObReader(); + int init( + const ObStorageHASrcInfo &src_info, + const obrpc::ObTransferTabletInfoArg &rpc_arg, + obrpc::ObStorageRpcProxy &srv_rpc_proxy, + common::ObInOutBandwidthThrottle &bandwidth_throttle); + int fetch_tablet_info(obrpc::ObCopyTabletInfo &tablet_info); +private: + bool is_inited_; + ObStorageStreamRpcReader rpc_reader_; + DISALLOW_COPY_AND_ASSIGN(ObCopyTransferTabletInfoObReader); +}; + +class ObCopyTransferTabletInfoObProducer +{ +public: + ObCopyTransferTabletInfoObProducer(); + virtual ~ObCopyTransferTabletInfoObProducer(); + int init( + const uint64_t tenant_id, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const common::ObIArray &tablet_list); + int get_next_tablet_info(obrpc::ObCopyTabletInfo &tablet_info); +private: + int get_next_tablet_info_( + const share::ObTransferTabletInfo &transfer_tablet_info, + ObTabletHandle &tablet_handle, + obrpc::ObCopyTabletInfo &tablet_info); +private: + bool is_inited_; + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + ObArray tablet_list_; + int64_t tablet_index_; + ObLSHandle ls_handle_; + DISALLOW_COPY_AND_ASSIGN(ObCopyTransferTabletInfoObProducer); +}; + +class ObICopyLSViewInfoReader +{ +public: + enum Type { + COPY_LS_ALL_VIEW_OB_READER = 0, + COPY_LS_ALL_VIEW_RESTORE_READER = 1, + MAX_TYPE + }; + ObICopyLSViewInfoReader() {} + virtual ~ObICopyLSViewInfoReader() {} + virtual int get_ls_meta( + ObLSMetaPackage &ls_meta) = 0; + virtual int get_next_tablet_info( + obrpc::ObCopyTabletInfo &tablet_info) = 0; + virtual Type get_type() const = 0; +private: + DISALLOW_COPY_AND_ASSIGN(ObICopyLSViewInfoReader); +}; + + +class ObCopyLSViewInfoObReader final : public ObICopyLSViewInfoReader +{ +public: + ObCopyLSViewInfoObReader(); + virtual ~ObCopyLSViewInfoObReader() {} + + int init( + const ObStorageHASrcInfo &src_info, + const obrpc::ObCopyLSViewArg &rpc_arg, + obrpc::ObStorageRpcProxy &srv_rpc_proxy, + common::ObInOutBandwidthThrottle &bandwidth_throttle); + + Type get_type() const override + { + return COPY_LS_ALL_VIEW_OB_READER; + } + + int get_ls_meta( + ObLSMetaPackage &ls_meta) override; + + int get_next_tablet_info( + obrpc::ObCopyTabletInfo &tablet_info) override; + +private: + static const int64_t FETCH_LS_VIEW_INFO_TIMEOUT = 10 * 60 * 1000 * 1000; // 10min // TODO(chongrong.th) change timeout to 1min later, + bool is_inited_; + ObLSMetaPackage ls_meta_; + ObStorageStreamRpcReader rpc_reader_; + common::ObArenaAllocator allocator_; + DISALLOW_COPY_AND_ASSIGN(ObCopyLSViewInfoObReader); +}; + + +class ObCopyLSViewInfoRestoreReader final : public ObICopyLSViewInfoReader +{ +public: + ObCopyLSViewInfoRestoreReader(); + virtual ~ObCopyLSViewInfoRestoreReader() {} + int init( + const share::ObLSID &ls_id, + const ObRestoreBaseInfo &restore_base_info); + + Type get_type() const override + { + return COPY_LS_ALL_VIEW_RESTORE_READER; + } + + int get_ls_meta( + ObLSMetaPackage &ls_meta) override; + + int get_next_tablet_info( + obrpc::ObCopyTabletInfo &tablet_info) override; + +private: + bool is_inited_; + share::ObLSID ls_id_; + const ObRestoreBaseInfo *restore_base_info_; + backup::ObExternTabletMetaReader reader_; + + DISALLOW_COPY_AND_ASSIGN(ObCopyLSViewInfoRestoreReader); +}; } } diff --git a/src/storage/high_availability/ob_storage_ha_src_provider.cpp b/src/storage/high_availability/ob_storage_ha_src_provider.cpp old mode 100644 new mode 100755 index d0d078b17..75fed57c7 --- a/src/storage/high_availability/ob_storage_ha_src_provider.cpp +++ b/src/storage/high_availability/ob_storage_ha_src_provider.cpp @@ -12,8 +12,11 @@ #define USING_LOG_PREFIX STORAGE #include "ob_storage_ha_src_provider.h" +#include "ob_storage_ha_utils.h" #include "share/location_cache/ob_location_service.h" #include "observer/ob_server_event_history_table_operator.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" #include "storage/high_availability/ob_storage_ha_utils.h" namespace oceanbase { @@ -98,41 +101,12 @@ int ObStorageHASrcProvider::choose_ob_src(const share::ObLSID &ls_id, const SCN int ObStorageHASrcProvider::get_ls_leader_(const uint64_t tenant_id, const share::ObLSID &ls_id, common::ObAddr &leader) { int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - static const int64_t DEFAULT_CHECK_LS_LEADER_TIMEOUT = 1 * 60 * 1000 * 1000L; // 1min - const int64_t cluster_id = GCONF.cluster_id; - if (OB_ISNULL(GCTX.location_service_)) { - ret = OB_NOT_INIT; - LOG_WARN("location cache is NULL", K(ret)); - } else if (OB_INVALID_ID == tenant_id || !ls_id.is_valid()) { + leader.reset(); + if (OB_INVALID_ID == tenant_id || !ls_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(tenant_id), K(ls_id)); - } else { - uint32_t renew_count = 0; - const uint32_t max_renew_count = 10; - const int64_t retry_us = 200 * 1000; - const int64_t start_ts = ObTimeUtility::current_time(); - do { - if (OB_FAIL(GCTX.location_service_->nonblock_get_leader(cluster_id, tenant_id, ls_id, leader))) { - if (OB_LS_LOCATION_NOT_EXIST == ret && renew_count++ < max_renew_count) { // retry ten times - LOG_WARN("failed to get location and force renew", K(ret), K(tenant_id), K(ls_id), K(cluster_id)); - if (OB_SUCCESS != (tmp_ret = GCTX.location_service_->nonblock_renew(cluster_id, tenant_id, ls_id))) { - LOG_WARN("failed to nonblock renew from location cache", K(tmp_ret), K(ls_id), K(cluster_id)); - } else if (ObTimeUtility::current_time() - start_ts > DEFAULT_CHECK_LS_LEADER_TIMEOUT) { - renew_count = max_renew_count; - } else { - ob_usleep(retry_us); - } - } - } else { - LOG_INFO("get ls leader", K(tenant_id), K(ls_id), K(leader), K(cluster_id)); - } - } while (OB_LS_LOCATION_NOT_EXIST == ret && renew_count < max_renew_count); - - if (OB_SUCC(ret) && !leader.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("leader addr is invalid", K(ret), K(tenant_id), K(ls_id), K(leader), K(cluster_id)); - } + } else if (OB_FAIL(ObStorageHAUtils::get_ls_leader(tenant_id, ls_id, leader))) { + LOG_WARN("failed to get ls leader", K(ret), K(tenant_id), K(ls_id)); } return ret; } @@ -142,22 +116,14 @@ int ObStorageHASrcProvider::fetch_ls_member_list_(const uint64_t tenant_id, cons { int ret = OB_SUCCESS; addr_list.reset(); - ObStorageHASrcInfo src_info; - src_info.src_addr_ = leader_addr; - src_info.cluster_id_ = GCONF.cluster_id; - obrpc::ObFetchLSMemberListInfo member_info; if (OB_ISNULL(storage_rpc_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("storage rpc should not be null", K(ret)); } else if (OB_INVALID_ID == tenant_id || !ls_id.is_valid() || !leader_addr.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(tenant_id), K(ls_id), K(leader_addr)); - } else if (OB_FAIL(storage_rpc_->post_ls_member_list_request(tenant_id, src_info, ls_id, member_info))) { - LOG_WARN("failed to post ls member list request", K(ret), K(tenant_id), K(src_info), K(ls_id)); - } else if (OB_FAIL(member_info.member_list_.get_addr_array(addr_list))) { - LOG_WARN("failed to get addr array", K(ret), K(member_info)); - } else { - FLOG_INFO("fetch ls member list", K(tenant_id), K(ls_id), K(leader_addr), K(member_info)); + } else if (OB_FAIL(get_ls_member_list_(tenant_id, ls_id, leader_addr, addr_list))) { + LOG_WARN("failed to get ls member list", K(ret), K(tenant_id), K(ls_id), K(leader_addr)); } return ret; } @@ -189,7 +155,7 @@ int ObStorageHASrcProvider::inner_choose_ob_src_(const uint64_t tenant_id, const int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; int64_t choose_member_idx = -1; - SCN max_clog_checkpoint_scn; + SCN max_clog_checkpoint_scn = SCN::min_scn(); for (int64_t i = 0; OB_SUCC(ret) && i < addr_list.count(); ++i) { const common::ObAddr &addr = addr_list.at(i); obrpc::ObFetchLSMetaInfoResp ls_info; @@ -204,7 +170,6 @@ int ObStorageHASrcProvider::inner_choose_ob_src_(const uint64_t tenant_id, const } else { LOG_WARN("failed to check version", K(ret), K(tenant_id), K(ls_id), K(ls_info)); } - // TODO: muwei make sure this is right } else if (!ObReplicaTypeCheck::is_full_replica(REPLICA_TYPE_FULL)) { LOG_INFO("do not choose this src", K(tenant_id), K(ls_id), K(addr), K(ls_info)); } else if (local_clog_checkpoint_scn > ls_info.ls_meta_package_.ls_meta_.get_clog_checkpoint_scn()) { @@ -223,6 +188,10 @@ int ObStorageHASrcProvider::inner_choose_ob_src_(const uint64_t tenant_id, const if (ls_info.ls_meta_package_.ls_meta_.get_clog_checkpoint_scn() > max_clog_checkpoint_scn) { max_clog_checkpoint_scn = ls_info.ls_meta_package_.ls_meta_.get_clog_checkpoint_scn(); choose_member_idx = i; + } else if (ls_info.ls_meta_package_.ls_meta_.get_clog_checkpoint_scn() == max_clog_checkpoint_scn + && !ls_info.has_transfer_table_) { + max_clog_checkpoint_scn = ls_info.ls_meta_package_.ls_meta_.get_clog_checkpoint_scn(); + choose_member_idx = i; } } } @@ -237,5 +206,52 @@ int ObStorageHASrcProvider::inner_choose_ob_src_(const uint64_t tenant_id, const return ret; } +int ObStorageHASrcProvider::get_ls_member_list_( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const common::ObAddr &leader_addr, + common::ObIArray &addr_list) +{ + int ret = OB_SUCCESS; + addr_list.reset(); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObStorageHASrcInfo src_info; + src_info.src_addr_ = leader_addr; + src_info.cluster_id_ = GCONF.cluster_id; + obrpc::ObFetchLSMemberListInfo member_info; + ObLSService *ls_service = nullptr; + + if (OB_INVALID_ID == tenant_id || !ls_id.is_valid() || !leader_addr.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get ls member list get invalid argument", K(ret), K(tenant_id), K(ls_id), K(leader_addr)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("fail to get log stream", KR(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(storage_rpc_->post_ls_member_list_request(tenant_id, src_info, ls_id, member_info))) { + LOG_WARN("failed to post ls member list request", K(ret), K(tenant_id), K(src_info), K(ls_id)); + //overwrite ret + member_info.reset(); + if (OB_FAIL(ls->get_log_handler()->get_election_leader(src_info.src_addr_))) { + LOG_WARN("failed to get election leader", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(storage_rpc_->post_ls_member_list_request(tenant_id, src_info, ls_id, member_info))) { + LOG_WARN("failed to post ls member list request", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(member_info.member_list_.get_addr_array(addr_list))) { + LOG_WARN("failed to get addr array", K(ret), K(member_info)); + } else { + FLOG_INFO("fetch ls member list", K(tenant_id), K(ls_id), K(src_info), K(member_info)); + } + return ret; +} + } // namespace storage } // namespace oceanbase diff --git a/src/storage/high_availability/ob_storage_ha_src_provider.h b/src/storage/high_availability/ob_storage_ha_src_provider.h index 49c9c8c03..18fbbe086 100644 --- a/src/storage/high_availability/ob_storage_ha_src_provider.h +++ b/src/storage/high_availability/ob_storage_ha_src_provider.h @@ -37,6 +37,8 @@ private: common::ObAddr &choosen_src_addr); int fetch_ls_meta_info_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObAddr &member_addr, obrpc::ObFetchLSMetaInfoResp &ls_meta_info); + int get_ls_member_list_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObAddr &leader_addr, + common::ObIArray &addr_list); private: bool is_inited_; diff --git a/src/storage/high_availability/ob_storage_ha_struct.cpp b/src/storage/high_availability/ob_storage_ha_struct.cpp index 9c4f273c9..d58cc00a0 100644 --- a/src/storage/high_availability/ob_storage_ha_struct.cpp +++ b/src/storage/high_availability/ob_storage_ha_struct.cpp @@ -15,6 +15,10 @@ #include "storage/ls/ob_ls_meta_package.h" #include "storage/tx_storage/ob_ls_handle.h" #include "storage/tx_storage/ob_ls_service.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_common.h" +#include "storage/tablet/ob_tablet_iterator.h" +#include "storage/ls/ob_ls_tablet_service.h" namespace oceanbase { @@ -67,13 +71,34 @@ bool ObMigrationOpType::need_keep_old_tablet(const TYPE &type) ret = OB_INVALID_ARGUMENT; LOG_WARN("check need keep old tablet get invaid argument", K(ret), K(type)); } else if (ObMigrationOpType::REBUILD_LS_OP == type || ObMigrationOpType::CHANGE_LS_OP == type) { - bool_ret = true; + // TODO(yangyi.yyy): fix in 5.0: open this restriction if support tablet link + bool_ret = false; } else { bool_ret = false; } return bool_ret; } +int ObMigrationOpType::get_ls_wait_status(const TYPE &type, ObMigrationStatus &wait_status) +{ + int ret = OB_SUCCESS; + wait_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + if (!is_valid(type)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invaid argument", K(ret), K(type)); + } else if (ObMigrationOpType::MIGRATE_LS_OP == type) { + wait_status = ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_WAIT; + } else if (ObMigrationOpType::ADD_LS_OP == type) { + wait_status = ObMigrationStatus::OB_MIGRATION_STATUS_ADD_WAIT; + } else if (ObMigrationOpType::REBUILD_LS_OP == type) { + wait_status = ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD_WAIT; + } else { + ret = OB_ERR_UNDEFINED; + LOG_WARN("type is not valid", K(type)); + } + return ret; +} + /******************ObMigrationStatusHelper*********************/ int ObMigrationStatusHelper::trans_migration_op( const ObMigrationOpType::TYPE &op_type, ObMigrationStatus &migration_status) @@ -147,10 +172,6 @@ int ObMigrationStatusHelper::trans_fail_status(const ObMigrationStatus &cur_stat fail_status = OB_MIGRATION_STATUS_MIGRATE_FAIL; break; } - case OB_MIGRATION_STATUS_REBUILD: { - fail_status = OB_MIGRATION_STATUS_REBUILD; - break; - } case OB_MIGRATION_STATUS_CHANGE: { fail_status = OB_MIGRATION_STATUS_NONE; break; @@ -164,6 +185,15 @@ int ObMigrationStatusHelper::trans_fail_status(const ObMigrationStatus &cur_stat fail_status = OB_MIGRATION_STATUS_NONE; break; } + case OB_MIGRATION_STATUS_MIGRATE_WAIT : { + fail_status = OB_MIGRATION_STATUS_MIGRATE_FAIL; + break; + } + case OB_MIGRATION_STATUS_ADD_WAIT : { + fail_status = OB_MIGRATION_STATUS_ADD_FAIL; + break; + } + //rebuild and rebuild_wait need use trans_rebuild_fail_status interface default: { ret = OB_INVALID_ARGUMENT; LOG_ERROR("invalid cur status for fail", K(ret), K(cur_status)); @@ -213,6 +243,22 @@ int ObMigrationStatusHelper::trans_reboot_status(const ObMigrationStatus &cur_st reboot_status = OB_MIGRATION_STATUS_NONE; break; } + case OB_MIGRATION_STATUS_MIGRATE_WAIT : { + reboot_status = OB_MIGRATION_STATUS_MIGRATE_FAIL; + break; + } + case OB_MIGRATION_STATUS_ADD_WAIT : { + reboot_status = OB_MIGRATION_STATUS_ADD_FAIL; + break; + } + case OB_MIGRATION_STATUS_REBUILD_WAIT: { + reboot_status = OB_MIGRATION_STATUS_REBUILD; + break; + } + case OB_MIGRATION_STATUS_REBUILD_FAIL : { + reboot_status = OB_MIGRATION_STATUS_REBUILD_FAIL; + break; + } default: { ret = OB_INVALID_ARGUMENT; LOG_ERROR("invalid cur status for fail", K(ret), K(cur_status)); @@ -242,19 +288,134 @@ bool ObMigrationStatusHelper::check_can_restore(const ObMigrationStatus &cur_sta return OB_MIGRATION_STATUS_NONE == cur_status; } -bool ObMigrationStatusHelper::check_allow_gc(const ObMigrationStatus &cur_status) +int ObMigrationStatusHelper::check_transfer_dest_ls_status_( + const ObLSID &transfer_ls_id, + bool &allow_gc) { - bool allow_gc = true; - - if (OB_MIGRATION_STATUS_ADD == cur_status - || OB_MIGRATION_STATUS_MIGRATE == cur_status - || OB_MIGRATION_STATUS_REBUILD == cur_status - || OB_MIGRATION_STATUS_CHANGE == cur_status - || OB_MIGRATION_STATUS_RESTORE_STANDBY == cur_status - || OB_MIGRATION_STATUS_HOLD == cur_status) { + int ret = OB_SUCCESS; + ObLSService *ls_service = nullptr; + ObLS *dest_ls = nullptr; + ObLSHandle ls_handle; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + if (!transfer_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls id is invalid", K(ret), K(transfer_ls_id)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(transfer_ls_id, ls_handle, ObLSGetMod::HA_MOD))) { + if (OB_LS_NOT_EXIST == ret) { + LOG_INFO("transfer dest ls not exist", K(ret), K(transfer_ls_id)); + allow_gc = true; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get ls", K(ret), K(transfer_ls_id)); + } + } else if (OB_ISNULL(dest_ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(dest_ls), K(transfer_ls_id)); + } else if (OB_FAIL(dest_ls->get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), KPC(dest_ls)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_WAIT == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_ADD_WAIT == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD_WAIT == migration_status) { allow_gc = false; } + return ret; +} +int ObMigrationStatusHelper::check_ls_transfer_tablet_(const share::ObLSID &ls_id, bool &allow_gc) +{ + int ret = OB_SUCCESS; + allow_gc = false; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + ObLSHandle ls_handle; + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ObInnerLSStatus create_status; + if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls id is invalid", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { + LOG_WARN("get ls failed", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls not exist", K(ret), K(ls_id)); + } else if (FALSE_IT(create_status = ls->get_ls_meta().get_ls_create_status())) { + } else if (ObInnerLSStatus::COMMITTED != create_status) { + allow_gc = true; + } else if (OB_FAIL(ls->get_tablet_svr()->build_tablet_iter(tablet_iter))) { + LOG_WARN( "failed to build ls tablet iter", KR(ret)); + } else { + ObTabletHandle tablet_handle; + ObTablet *tablet = NULL; + ObTabletCreateDeleteMdsUserData user_data; + while (OB_SUCC(ret)) { + if (OB_FAIL(tablet_iter.get_next_tablet(tablet_handle))) { + if (OB_ITER_END == ret) { + allow_gc = true; + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get tablet", KR(ret), K(tablet_handle), K(ls_id)); + } + } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tablet handle", KR(ret), K(tablet_handle), K(ls_id)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is NULL", KR(ret), K(ls_id)); + } else if (tablet->is_ls_inner_tablet()) { + // do nothing + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + if (OB_EMPTY_RESULT == ret) { + LOG_INFO("tablet_status is null, ls is allowed to be GC", KR(ret), "tablet_id", tablet->get_tablet_meta().tablet_id_, K(ls_id)); + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get latest tablet status", K(ret), KP(tablet), K(ls_id)); + } + } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ + && ObTabletStatus::TRANSFER_OUT_DELETED != user_data.tablet_status_) { + // do nothing + } else if (OB_FAIL(check_transfer_dest_ls_status_(user_data.transfer_ls_id_, allow_gc))) { + LOG_WARN("failed to check ls transfer tablet", K(ret), K(ls), K(user_data)); + } else if (!allow_gc) { + LOG_INFO("The ls is not allowed to be GC because it is also dependent on other ls", K(user_data), + K(ls_id), "tablet_id", tablet->get_tablet_meta().tablet_id_); + break; + } + } + } + return ret; +} + +int ObMigrationStatusHelper::check_allow_gc(const share::ObLSID &ls_id, const ObMigrationStatus &cur_status, bool &allow_gc) +{ + int ret = OB_SUCCESS; + allow_gc = false; + if (check_allow_gc_abandoned_ls(cur_status)) { + allow_gc = true; + } else if (OB_MIGRATION_STATUS_NONE != cur_status) { + allow_gc = false; + } else if (OB_FAIL(check_ls_transfer_tablet_(ls_id, allow_gc))) { + LOG_WARN("failed to check ls transfer tablet", K(ret), K(ls_id)); + } else { + } + return ret; +} + +bool ObMigrationStatusHelper::check_allow_gc_abandoned_ls(const ObMigrationStatus &cur_status) +{ + bool allow_gc = false; + if (OB_MIGRATION_STATUS_ADD_FAIL == cur_status + || OB_MIGRATION_STATUS_MIGRATE_FAIL == cur_status + || OB_MIGRATION_STATUS_REBUILD_FAIL == cur_status) { + allow_gc = true; + } return allow_gc; } @@ -291,9 +452,9 @@ int ObMigrationStatusHelper::check_can_change_status( break; } case OB_MIGRATION_STATUS_ADD: { - if (OB_MIGRATION_STATUS_HOLD == change_status - || OB_MIGRATION_STATUS_ADD == change_status - || OB_MIGRATION_STATUS_ADD_FAIL == change_status) { + if (OB_MIGRATION_STATUS_ADD == change_status + || OB_MIGRATION_STATUS_ADD_FAIL == change_status + || OB_MIGRATION_STATUS_ADD_WAIT == change_status) { can_change = true; } break; @@ -305,9 +466,9 @@ int ObMigrationStatusHelper::check_can_change_status( break; } case OB_MIGRATION_STATUS_MIGRATE: { - if (OB_MIGRATION_STATUS_HOLD == change_status - || OB_MIGRATION_STATUS_MIGRATE == change_status - || OB_MIGRATION_STATUS_MIGRATE_FAIL == change_status) { + if (OB_MIGRATION_STATUS_MIGRATE == change_status + || OB_MIGRATION_STATUS_MIGRATE_FAIL == change_status + || OB_MIGRATION_STATUS_MIGRATE_WAIT == change_status) { can_change = true; } break; @@ -320,7 +481,8 @@ int ObMigrationStatusHelper::check_can_change_status( } case OB_MIGRATION_STATUS_REBUILD: { if (OB_MIGRATION_STATUS_NONE == change_status - || OB_MIGRATION_STATUS_REBUILD == change_status) { + || OB_MIGRATION_STATUS_REBUILD == change_status + || OB_MIGRATION_STATUS_REBUILD_WAIT == change_status) { can_change = true; } break; @@ -348,6 +510,34 @@ int ObMigrationStatusHelper::check_can_change_status( } break; } + case OB_MIGRATION_STATUS_MIGRATE_WAIT: { + if (OB_MIGRATION_STATUS_HOLD == change_status + || OB_MIGRATION_STATUS_MIGRATE_FAIL == change_status) { + can_change = true; + } + break; + } + case OB_MIGRATION_STATUS_ADD_WAIT: { + if (OB_MIGRATION_STATUS_HOLD == change_status + || OB_MIGRATION_STATUS_ADD_FAIL == change_status) { + can_change = true; + } + break; + } + case OB_MIGRATION_STATUS_REBUILD_WAIT: { + if (OB_MIGRATION_STATUS_NONE == change_status + || OB_MIGRATION_STATUS_REBUILD_WAIT == change_status + || OB_MIGRATION_STATUS_REBUILD == change_status) { + can_change = true; + } + break; + } + case OB_MIGRATION_STATUS_REBUILD_FAIL: { + if (OB_MIGRATION_STATUS_REBUILD_FAIL == change_status) { + can_change = true; + } + break; + } default: { ret = OB_INVALID_ARGUMENT; LOG_ERROR("invalid cur status for fail", K(ret), K(cur_status)); @@ -363,6 +553,47 @@ bool ObMigrationStatusHelper::is_valid(const ObMigrationStatus &status) && status < ObMigrationStatus::OB_MIGRATION_STATUS_MAX; } +int ObMigrationStatusHelper::trans_rebuild_fail_status( + const ObMigrationStatus &cur_status, + const bool is_in_member_list, + const bool is_ls_deleted, + ObMigrationStatus &fail_status) +{ + int ret = OB_SUCCESS; + fail_status = OB_MIGRATION_STATUS_MAX; + + if (OB_MIGRATION_STATUS_REBUILD != cur_status && OB_MIGRATION_STATUS_REBUILD_WAIT != cur_status) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(cur_status)); + } else if (!is_in_member_list || is_ls_deleted) { + fail_status = OB_MIGRATION_STATUS_REBUILD_FAIL; + } else { + fail_status = OB_MIGRATION_STATUS_REBUILD; + } + return ret; +} + +int ObMigrationStatusHelper::check_migration_in_final_state( + const ObMigrationStatus &status, + bool &in_final_state) +{ + int ret = OB_SUCCESS; + in_final_state = false; + + if (!is_valid(status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check migration in final state get invalid argument", K(ret), K(status)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE == status + || ObMigrationStatus::OB_MIGRATION_STATUS_ADD_FAIL == status + || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_FAIL == status + || ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD_FAIL == status) { + in_final_state = true; + } else { + in_final_state = false; + } + return ret; +} + /******************ObMigrationOpArg*********************/ ObMigrationOpArg::ObMigrationOpArg() : ls_id_(), @@ -420,7 +651,6 @@ bool ObTabletsTransferArg::is_valid() const void ObTabletsTransferArg::reset() { - //TODO(muwei.ym) fix tenant id tenant_id_ = OB_INVALID_ID; ls_id_.reset(); src_.reset(); @@ -564,7 +794,9 @@ bool ObMigrationUtils::is_need_retry_error(const int err) case OB_CHECKSUM_ERROR : case OB_DDL_SSTABLE_RANGE_CROSS : case OB_TENANT_NOT_EXIST : - case OB_NO_NEED_REBUILD : + case OB_TRANSFER_SYS_ERROR : + case OB_INVALID_TABLE_STORE : + case OB_UNEXPECTED_TABLET_STATUS : bret = false; break; default: @@ -770,6 +1002,138 @@ int ObCopySSTableMacroRangeInfo::assign(const ObCopySSTableMacroRangeInfo &sstab return ret; } +/******************ObLSRebuildStatus*********************/ +ObLSRebuildStatus::ObLSRebuildStatus() + : status_(NONE) +{ +} + +ObLSRebuildStatus::ObLSRebuildStatus(const STATUS &status) + : status_(status) +{ +} + +ObLSRebuildStatus &ObLSRebuildStatus::operator=(const ObLSRebuildStatus &status) +{ + if (this != &status) { + status_ = status.status_; + } + return *this; +} + +ObLSRebuildStatus &ObLSRebuildStatus::operator=(const STATUS &status) +{ + status_ = status; + return *this; +} + +void ObLSRebuildStatus::reset() +{ + status_ = MAX; +} + +bool ObLSRebuildStatus::is_valid() const +{ + return status_ >= NONE && status_ < MAX; +} + +int ObLSRebuildStatus::set_status(int32_t status) +{ + int ret = OB_SUCCESS; + if (status < NONE|| status >= MAX) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid status", K(ret), K(status)); + } else { + status_ = static_cast(status); + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObLSRebuildStatus, status_); + +/******************ObLSRebuildType*********************/ +ObLSRebuildType::ObLSRebuildType() + : type_(NONE) +{ +} + +ObLSRebuildType::ObLSRebuildType(const TYPE &type) + : type_(type) +{ +} + +ObLSRebuildType &ObLSRebuildType::operator=(const ObLSRebuildType &type) +{ + if (this != &type) { + type_ = type.type_; + } + return *this; +} + +ObLSRebuildType &ObLSRebuildType::operator=(const TYPE &type) +{ + type_ = type; + return *this; +} + +void ObLSRebuildType::reset() +{ + type_ = MAX; +} + +bool ObLSRebuildType::is_valid() const +{ + return type_ >= NONE && type_ < MAX; +} + +int ObLSRebuildType::set_type(int32_t type) +{ + int ret = OB_SUCCESS; + if (type < NONE|| type >= MAX) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid type", K(ret), K(type)); + } else { + type_ = static_cast(type); + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObLSRebuildType, type_); + +/******************ObLSRebuildInfo*********************/ +ObLSRebuildInfo::ObLSRebuildInfo() + : status_(), + type_() +{ +} + +void ObLSRebuildInfo::reset() +{ + status_.reset(); + type_.reset(); +} + +bool ObLSRebuildInfo::is_valid() const +{ + return status_.is_valid() + && type_.is_valid() + && ((ObLSRebuildStatus::NONE == status_ && ObLSRebuildType::NONE == type_) + || (ObLSRebuildStatus::NONE != status_ && ObLSRebuildType::NONE != type_)); +} + +bool ObLSRebuildInfo::is_in_rebuild() const +{ + return ObLSRebuildStatus::NONE != status_; +} + +bool ObLSRebuildInfo::operator ==(const ObLSRebuildInfo &other) const +{ + return status_ == other.status_ + && type_ == other.type_; +} + +OB_SERIALIZE_MEMBER(ObLSRebuildInfo, status_, type_); + } } diff --git a/src/storage/high_availability/ob_storage_ha_struct.h b/src/storage/high_availability/ob_storage_ha_struct.h index a53095569..95d54da3e 100644 --- a/src/storage/high_availability/ob_storage_ha_struct.h +++ b/src/storage/high_availability/ob_storage_ha_struct.h @@ -22,6 +22,7 @@ #include "storage/blocksstable/ob_macro_block_meta_mgr.h" #include "storage/blocksstable/ob_datum_rowkey.h" #include "storage/blocksstable/ob_logic_macro_id.h" +#include "share/ls/ob_ls_i_life_manager.h" namespace oceanbase @@ -37,10 +38,13 @@ enum ObMigrationStatus OB_MIGRATION_STATUS_MIGRATE = 3, OB_MIGRATION_STATUS_MIGRATE_FAIL = 4, OB_MIGRATION_STATUS_REBUILD = 5, -// OB_MIGRATION_STATUS_REBUILD_FAIL = 6, not used yet + OB_MIGRATION_STATUS_REBUILD_FAIL = 6, OB_MIGRATION_STATUS_CHANGE = 7, OB_MIGRATION_STATUS_RESTORE_STANDBY = 8, OB_MIGRATION_STATUS_HOLD = 9, + OB_MIGRATION_STATUS_MIGRATE_WAIT = 10, + OB_MIGRATION_STATUS_ADD_WAIT = 11, + OB_MIGRATION_STATUS_REBUILD_WAIT = 12, OB_MIGRATION_STATUS_MAX, }; @@ -60,6 +64,7 @@ struct ObMigrationOpType static TYPE get_type(const char *type_str); static OB_INLINE bool is_valid(const TYPE &type) { return type >= 0 && type < MAX_LS_OP; } static bool need_keep_old_tablet(const TYPE &type); + static int get_ls_wait_status(const TYPE &type, ObMigrationStatus &wait_status); }; struct ObMigrationStatusHelper @@ -70,13 +75,26 @@ public: static int trans_reboot_status(const ObMigrationStatus &cur_status, ObMigrationStatus &reboot_status); static bool check_can_election(const ObMigrationStatus &cur_status); static bool check_can_restore(const ObMigrationStatus &cur_status); - static bool check_allow_gc(const ObMigrationStatus &cur_status); + static int check_allow_gc(const share::ObLSID &ls_id, const ObMigrationStatus &cur_status, bool &allow_gc); + // Check the migration status. The LS in the XXX_FAIL state is considered to be an abandoned LS, which can be judged to be directly GC when restarting + static bool check_allow_gc_abandoned_ls(const ObMigrationStatus &cur_status); static bool check_can_migrate_out(const ObMigrationStatus &cur_status); static int check_can_change_status( const ObMigrationStatus &cur_status, const ObMigrationStatus &change_status, bool &can_change); static bool is_valid(const ObMigrationStatus &status); + static int trans_rebuild_fail_status( + const ObMigrationStatus &cur_status, + const bool is_in_member_list, + const bool is_ls_deleted, + ObMigrationStatus &fail_status); + static int check_migration_in_final_state( + const ObMigrationStatus &status, + bool &in_final_state); +private: + static int check_ls_transfer_tablet_(const share::ObLSID &ls_id, bool &allow_gc); + static int check_transfer_dest_ls_status_(const share::ObLSID &transfer_ls_id, bool &allow_gc); }; enum ObMigrationOpPriority @@ -288,6 +306,84 @@ public: DISALLOW_COPY_AND_ASSIGN(ObCopySSTableMacroRangeInfo); }; +class ObLSRebuildStatus final +{ + OB_UNIS_VERSION(1); +public: + enum STATUS : uint8_t + { + NONE = 0, + INIT = 1, + DOING = 2, + CLEANUP = 3, + MAX + }; +public: + ObLSRebuildStatus(); + ~ObLSRebuildStatus() = default; + explicit ObLSRebuildStatus(const STATUS &status); + ObLSRebuildStatus &operator=(const ObLSRebuildStatus &status); + ObLSRebuildStatus &operator=(const STATUS &status); + bool operator ==(const ObLSRebuildStatus &other) const { return status_ == other.status_; } + bool operator !=(const ObLSRebuildStatus &other) const { return status_ != other.status_; } + operator STATUS() const { return status_; } + bool is_valid() const; + STATUS get_status() const { return status_; } + int set_status(int32_t status); + void reset(); + TO_STRING_KV(K_(status)); + +private: + STATUS status_; +}; + +class ObLSRebuildType final +{ + OB_UNIS_VERSION(1); +public: + enum TYPE : uint8_t + { + NONE = 0, + CLOG = 1, + TRANSFER = 2, + MAX + }; + +public: + ObLSRebuildType(); + ~ObLSRebuildType() = default; + explicit ObLSRebuildType(const TYPE &type); + ObLSRebuildType &operator=(const ObLSRebuildType &type); + ObLSRebuildType &operator=(const TYPE &status); + bool operator ==(const ObLSRebuildType &other) const { return type_ == other.type_; } + bool operator !=(const ObLSRebuildType &other) const { return type_ != other.type_; } + operator TYPE() const { return type_; } + bool is_valid() const; + TYPE get_type() const { return type_; } + int set_type(int32_t type); + void reset(); + + TO_STRING_KV(K_(type)); +private: + TYPE type_; +}; + +struct ObLSRebuildInfo final +{ + OB_UNIS_VERSION(1); +public: + ObLSRebuildInfo(); + ~ObLSRebuildInfo() = default; + void reset(); + bool is_valid() const; + bool is_in_rebuild() const; + bool operator ==(const ObLSRebuildInfo &other) const; + + TO_STRING_KV(K_(status), K_(type)); + ObLSRebuildStatus status_; + ObLSRebuildType type_; +}; + } diff --git a/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp b/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp old mode 100644 new mode 100755 index 0ad93fbfb..eccd5ae5a --- a/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp +++ b/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp @@ -116,9 +116,7 @@ int ObStorageHATabletsBuilderParam::assign(const ObStorageHATabletsBuilderParam /******************ObStorageHATabletsBuilder*********************/ ObStorageHATabletsBuilder::ObStorageHATabletsBuilder() : is_inited_(false), - param_(), - tablet_simple_info_map_(), - deleted_tablet_id_list_() + param_() { } @@ -141,8 +139,6 @@ int ObStorageHATabletsBuilder::init(const ObStorageHATabletsBuilderParam ¶m) } else if (OB_FAIL(param_.assign(param))) { LOG_WARN("failed to assign storage ha tablets builder param", K(ret), K(param)); } else if (FALSE_IT(bucket_num = std::max(MAX_BUCKET_NUM, param.tablet_id_array_.count()))) { - } else if (OB_FAIL(tablet_simple_info_map_.create(bucket_num, "DataHATask"))) { - LOG_WARN("failed to create tablet status info map", K(ret)); } else { is_inited_ = true; } @@ -155,7 +151,6 @@ int ObStorageHATabletsBuilder::create_or_update_tablets() ObLS *ls = nullptr; ObICopyTabletInfoReader *reader = nullptr; obrpc::ObCopyTabletInfo tablet_info; - ObCopyTabletSimpleInfo tablet_simple_info; const int overwrite = 1; if (!is_inited_) { @@ -169,7 +164,6 @@ int ObStorageHATabletsBuilder::create_or_update_tablets() } else { while (OB_SUCC(ret)) { tablet_info.reset(); - tablet_simple_info.reset(); if (OB_FAIL(reader->fetch_tablet_info(tablet_info))) { if (OB_ITER_END == ret) { ret = OB_SUCCESS; @@ -177,17 +171,84 @@ int ObStorageHATabletsBuilder::create_or_update_tablets() } else { LOG_WARN("failed to fetch tablet info", K(ret)); } - } else if (ObCopyTabletStatus::TABLET_NOT_EXIST == tablet_info.status_) { - if (OB_FAIL(deleted_tablet_id_list_.push_back(tablet_info.tablet_id_))) { - LOG_WARN("failed to push deleted tablet id into array", K(ret), K(tablet_info)); - } + } else if (OB_FAIL(modified_tablet_info_(tablet_info))) { + LOG_WARN("failed to modified tablet info", K(ret), K(tablet_info)); } else if (OB_FAIL(create_or_update_tablet_(tablet_info, ls))) { LOG_WARN("failed to create or update tablet", K(ret), K(tablet_info)); + } +#ifdef ERRSIM + if (OB_SUCC(ret)) { + if (GCONF.errsim_migration_tablet_id == tablet_info.tablet_id_.id()) { + SERVER_EVENT_SYNC_ADD("storage_ha", "after_migration_fetch_tablet_info", + "tablet_id", tablet_info.tablet_id_); + DEBUG_SYNC(AFTER_MIGRATION_FETCH_TABLET_INFO); + } + } +#endif + } + } + + if (OB_NOT_NULL(reader)) { + free_tablet_info_reader_(reader); + } + + return ret; +} + +int ObStorageHATabletsBuilder::create_all_tablets( + ObICopyLSViewInfoReader *reader, + common::ObIArray &sys_tablet_id_list, + common::ObIArray &data_tablet_id_list, + CopyTabletSimpleInfoMap &simple_info_map) +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + obrpc::ObCopyTabletInfo tablet_info; + ObCopyTabletSimpleInfo tablet_simple_info; + const int overwrite = 1; + sys_tablet_id_list.reset(); + data_tablet_id_list.reset(); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("storage ha tablets builder do not init", K(ret)); + } else if (OB_ISNULL(reader)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("create all tablets get invalid argument", K(ret), KP(reader)); + } else if (OB_ISNULL(ls = param_.ls_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", K(ret), KP(ls), K(param_)); + } else { + while (OB_SUCC(ret)) { + tablet_info.reset(); + tablet_simple_info.reset(); + if (OB_FAIL(reader->get_next_tablet_info(tablet_info))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to fetch tablet info", K(ret)); + } + } else if (OB_FAIL(modified_tablet_info_(tablet_info))) { + LOG_WARN("failed to modified tablet info", K(ret), K(tablet_info)); + } else if (OB_FAIL(create_or_update_tablet_(tablet_info, ls))) { + LOG_WARN("failed to create or update tablet", K(ret), K(tablet_info)); + } else if (tablet_info.tablet_id_.is_ls_inner_tablet()) { + if (OB_FAIL(sys_tablet_id_list.push_back(tablet_info.tablet_id_))) { + LOG_WARN("failed to push tablet id into array", K(ret), K(tablet_info)); + } + } else { + if (OB_FAIL(data_tablet_id_list.push_back(tablet_info.tablet_id_))) { + LOG_WARN("failed to push tablet id into data tablet id list", K(ret), K(tablet_info)); + } + } + + if (OB_FAIL(ret)) { } else { tablet_simple_info.tablet_id_ = tablet_info.tablet_id_; tablet_simple_info.status_ = tablet_info.status_; tablet_simple_info.data_size_ = tablet_info.data_size_; - if (OB_FAIL(tablet_simple_info_map_.set_refactored(tablet_info.tablet_id_, tablet_simple_info, overwrite))) { + if (OB_FAIL(simple_info_map.set_refactored(tablet_info.tablet_id_, tablet_simple_info, overwrite))) { LOG_WARN("failed to set tablet status info into map", K(ret), K(tablet_simple_info), K(tablet_info)); } } @@ -202,6 +263,85 @@ int ObStorageHATabletsBuilder::create_or_update_tablets() #endif } } + return ret; +} + + +int ObStorageHATabletsBuilder::update_pending_tablets_with_remote() +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + ObICopyTabletInfoReader *reader = nullptr; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("storage ha tablets builder do not init", K(ret)); + } else if (OB_ISNULL(ls = param_.ls_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", K(ret), KP(ls), K(param_)); + } else if (OB_FAIL(get_tablet_info_reader_(reader))) { + LOG_WARN("failed to get tablet info reader", K(ret), K(param_)); + } else { + obrpc::ObCopyTabletInfo tablet_info; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + while (OB_SUCC(ret)) { + tablet_info.reset(); + if (OB_FAIL(reader->fetch_tablet_info(tablet_info))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to fetch tablet info", K(ret)); + } + break; + } + + const ObTabletID tablet_id = tablet_info.tablet_id_; + if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_id)); + } else if (!tablet->get_tablet_meta().ha_status_.is_restore_status_pending()) { + // has been renewed before, skip. + LOG_INFO("local tablet is not PENDING, skip it", K(tablet_id), + "ha_status", tablet->get_tablet_meta().ha_status_); + continue; + } else if (ObCopyTabletStatus::TABLET_EXIST == tablet_info.status_) { + if (tablet_info.param_.ha_status_.is_restore_status_pending()) { + // This may happen when leader switch. The old leader sent the restored + // tablet id to follower. Then, the follower will try to restore these meta. + // However, the meta from new leader is still PENDING. + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("remote tablet is PENDING", K(ret), K(tablet_info)); + } else if (tablet->get_tablet_meta().transfer_info_.transfer_seq_ != tablet_info.param_.transfer_info_.transfer_seq_) { + // If remote tablet's transfer sequence is not equal with + // local tablet, it is also considered as same as the indicated + // tablet is not exist. + LOG_INFO("transfer sequence not equal, reset tablet not exist", K(tablet_id), + "remote_transfer_info", tablet_info.param_.transfer_info_, + "local_transfer_info", tablet->get_tablet_meta().transfer_info_); + tablet_info.status_ = ObCopyTabletStatus::TABLET_NOT_EXIST; + } + } + + + if (OB_FAIL(ret)) { + } else if (ObCopyTabletStatus::TABLET_NOT_EXIST == tablet_info.status_) { + // If remote tablet is not exist, update local tablet from PENDING to + // UNDEFINED. + if (OB_FAIL(ls->update_tablet_restore_status(tablet_info.tablet_id_, ObTabletRestoreStatus::STATUS::UNDEFINED))) { + LOG_WARN("failed to update tablet restore status to UNDEFINED", K(ret), K(tablet_info)); + } else { + LOG_INFO("update tablet restore status to UNDEFINED", K(tablet_info)); + } + } else if (OB_FAIL(create_or_update_tablet_(tablet_info, ls))) { + LOG_WARN("failed to create or update tablet", K(ret), K(tablet_info)); + } else { + LOG_INFO("success to replace PENDING tablet with a newer meta", K(tablet_id)); + } + } + } if (OB_NOT_NULL(reader)) { free_tablet_info_reader_(reader); @@ -320,13 +460,12 @@ int ObStorageHATabletsBuilder::create_or_update_tablet_( ObLS *ls) { int ret = OB_SUCCESS; - //TODO(muwei.ym) set keep old true when rebuild reuse minor sstable. - //const bool keep_old = param_.need_keep_old_tablet_; - const bool keep_old = false; + const bool keep_old = param_.need_keep_old_tablet_; + ObArenaAllocator allocator("HATabBuilder"); + ObTabletHandle local_tablet_hdl; ObTablesHandleArray major_tables; ObTablesHandleArray remote_logical_table; ObBatchUpdateTableStoreParam param; - ObArenaAllocator allocator; ObStorageSchema storage_schema; compaction::ObMediumCompactionInfoList medium_info_list; @@ -339,27 +478,33 @@ int ObStorageHATabletsBuilder::create_or_update_tablet_( } else if (ObCopyTabletStatus::TABLET_NOT_EXIST == tablet_info.status_ && tablet_info.tablet_id_.is_ls_inner_tablet()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sys tablet should exist", K(ret), K(tablet_info)); - } else if (OB_FAIL(hold_local_reuse_sstable_(tablet_info.tablet_id_, major_tables, storage_schema, medium_info_list, allocator))) { + } else if (OB_FAIL(hold_local_reuse_sstable_(tablet_info.tablet_id_, local_tablet_hdl, major_tables, storage_schema, medium_info_list, allocator))) { LOG_WARN("failed to hold local reuse sstable", K(ret), K(tablet_info)); } else if (OB_FAIL(ls->rebuild_create_tablet(tablet_info.param_, keep_old))) { LOG_WARN("failed to create or update tablet", K(ret), K(tablet_info)); - } else if (OB_FAIL(create_tablet_remote_logical_sstable_(tablet_info.tablet_id_, remote_logical_table))) { - LOG_WARN("failed to create tablet remote logical sstable", K(ret), K(tablet_info)); - } else if (remote_logical_table.empty()) { - //do nothing - } else if (OB_FAIL(param.tables_handle_.assign(remote_logical_table))) { - LOG_WARN("failed to assign tables handle", K(ret), K(remote_logical_table), K(tablet_info)); - } else if (FALSE_IT(param.tablet_meta_ = &tablet_info.param_)) { - } else if (FALSE_IT(param.rebuild_seq_ = ls->get_rebuild_seq())) { - } else if (OB_FAIL(ls->build_ha_tablet_new_table_store(tablet_info.tablet_id_, param))) { - LOG_WARN("failed to build ha tablet new table store", K(ret), K(remote_logical_table), K(tablet_info)); - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(create_tablet_with_major_sstables_(ls, tablet_info, major_tables, storage_schema, medium_info_list))) { - LOG_WARN("failed to crete tablet with major sstables", K(ret), KPC(ls), K(tablet_info), K(major_tables)); + } else if (tablet_info.param_.is_empty_shell() || tablet_info.param_.ha_status_.is_restore_status_undefined()) { + // empty shell or UNDEFINED tablet does not need to create remote logical sstable. } else { - LOG_INFO("succeed build ha table new table store", K(tablet_info), K(remote_logical_table)); + if (OB_FAIL(create_tablet_remote_logical_sstable_(allocator, tablet_info.tablet_id_, remote_logical_table))) { + LOG_WARN("failed to create tablet remote logical sstable", K(ret), K(tablet_info)); + } else if (remote_logical_table.empty()) { + //do nothing + } else if (OB_FAIL(param.tables_handle_.assign(remote_logical_table))) { + LOG_WARN("failed to assign tables handle", K(ret), K(remote_logical_table), K(tablet_info)); + } else if (FALSE_IT(param.tablet_meta_ = &tablet_info.param_)) { + } else if (FALSE_IT(param.rebuild_seq_ = ls->get_rebuild_seq())) { + } else if (OB_FAIL(ls->build_ha_tablet_new_table_store(tablet_info.tablet_id_, param))) { + LOG_WARN("failed to build ha tablet new table store", K(ret), K(remote_logical_table), K(tablet_info)); + } + + if (OB_FAIL(ret)) { + } else if (tablet_info.param_.transfer_info_.has_transfer_table_) { + //do nothing + } else if (OB_FAIL(create_tablet_with_major_sstables_(ls, tablet_info, major_tables, storage_schema, medium_info_list))) { + LOG_WARN("failed to crete tablet with major sstables", K(ret), KPC(ls), K(tablet_info), K(major_tables)); + } else { + LOG_INFO("succeed build ha table new table store", K(tablet_info), K(remote_logical_table)); + } } return ret; } @@ -371,6 +516,7 @@ int ObStorageHATabletsBuilder::build_tablets_sstable_info() obrpc::ObCopyTabletSSTableInfo sstable_info; obrpc::ObCopyTabletSSTableHeader copy_header; ObLS *ls = nullptr; + ObArray tablet_handle_array; if (!is_inited_) { ret = OB_NOT_INIT; @@ -378,7 +524,9 @@ int ObStorageHATabletsBuilder::build_tablets_sstable_info() } else if (OB_ISNULL(ls = param_.ls_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream should not be NULL", K(ret), KP(ls)); - } else if (OB_FAIL(get_tablets_sstable_reader_(reader))) { + } else if (OB_FAIL(hold_local_tablet_(tablet_handle_array))) { + LOG_WARN("failed to hold local tablet", K(ret), KP(ls)); + } else if (OB_FAIL(get_tablets_sstable_reader_(tablet_handle_array, reader))) { LOG_WARN("failed to get tablets sstable reader", K(ret), K(param_)); } else { while (OB_SUCC(ret)) { @@ -440,6 +588,7 @@ int ObStorageHATabletsBuilder::build_tablets_sstable_info_( } int ObStorageHATabletsBuilder::get_tablets_sstable_reader_( + const common::ObIArray &tablet_handle_array, ObICopySSTableInfoReader *&reader) { int ret = OB_SUCCESS; @@ -448,23 +597,26 @@ int ObStorageHATabletsBuilder::get_tablets_sstable_reader_( ret = OB_NOT_INIT; LOG_WARN("storage ha tablets builder do not init", K(ret)); } else if (param_.is_leader_restore_) { - if (OB_FAIL(get_tablets_sstable_restore_reader_(reader))) { + if (OB_FAIL(get_tablets_sstable_restore_reader_(tablet_handle_array ,reader))) { LOG_WARN("failed to get tablets sstable restore reader", K(ret), K(param_)); } } else { - if (OB_FAIL(get_tablets_sstable_ob_reader_(reader))) { + if (OB_FAIL(get_tablets_sstable_ob_reader_(tablet_handle_array, reader))) { LOG_WARN("failed to get tablets sstable ob reader", K(ret), K(param_)); } } return ret; } -int ObStorageHATabletsBuilder::get_tablets_sstable_restore_reader_(ObICopySSTableInfoReader *&reader) +int ObStorageHATabletsBuilder::get_tablets_sstable_restore_reader_( + const common::ObIArray &tablet_handle_array, + ObICopySSTableInfoReader *&reader) { int ret = OB_SUCCESS; reader = nullptr; void *buf = nullptr; ObCopySSTableInfoRestoreReader *restore_reader = nullptr; + ObArray tablet_id_array; if (!is_inited_) { ret = OB_NOT_INIT; @@ -478,10 +630,23 @@ int ObStorageHATabletsBuilder::get_tablets_sstable_restore_reader_(ObICopySSTabl LOG_WARN("failed to alloc memory", K(ret), KP(buf)); } else if (FALSE_IT(restore_reader = new (buf) ObCopySSTableInfoRestoreReader())) { } else if (FALSE_IT(reader = restore_reader)) { - } else if (OB_FAIL(restore_reader->init(param_.ls_->get_ls_id(), - *param_.restore_base_info_, param_.restore_action_, - param_.tablet_id_array_, *param_.meta_index_store_))) { - LOG_WARN("failed to init restore reader", K(ret), K(param_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_handle_array.count(); ++i) { + const ObTabletHandle &tablet_handle = tablet_handle_array.at(i); + if (!tablet_handle.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet handle should be valid", K(ret), K(tablet_handle)); + } else if (OB_FAIL(tablet_id_array.push_back(tablet_handle.get_obj()->get_tablet_meta().tablet_id_))) { + LOG_WARN("failed to push tablet id into array", K(ret), K(tablet_handle)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(restore_reader->init(param_.ls_->get_ls_id(), + *param_.restore_base_info_, param_.restore_action_, + tablet_id_array, *param_.meta_index_store_))) { + LOG_WARN("failed to init restore reader", K(ret), K(param_)); + } } if (OB_FAIL(ret)) { @@ -493,6 +658,7 @@ int ObStorageHATabletsBuilder::get_tablets_sstable_restore_reader_(ObICopySSTabl } int ObStorageHATabletsBuilder::get_tablets_sstable_ob_reader_( + const common::ObIArray &tablet_handle_array, ObICopySSTableInfoReader *&reader) { int ret = OB_SUCCESS; @@ -510,7 +676,7 @@ int ObStorageHATabletsBuilder::get_tablets_sstable_ob_reader_( LOG_WARN("failed to alloc memory", K(ret), KP(buf)); } else if (FALSE_IT(ob_reader = new (buf) ObCopySSTableInfoObReader())) { } else if (FALSE_IT(reader = ob_reader)) { - } else if (OB_FAIL(build_copy_tablets_sstable_info_arg_(arg))) { + } else if (OB_FAIL(build_copy_tablets_sstable_info_arg_(tablet_handle_array, arg))) { LOG_WARN("failed to build copy tablets sstable info arg", K(ret), K(arg)); } else if (OB_FAIL(ob_reader->init(param_.src_info_, arg, *param_.svr_rpc_proxy_, *param_.bandwidth_throttle_))) { LOG_WARN("failed to init copy tablet info ob reader", K(ret), K(param_)); @@ -536,6 +702,7 @@ void ObStorageHATabletsBuilder::free_sstable_info_reader_( } int ObStorageHATabletsBuilder::build_copy_tablets_sstable_info_arg_( + const common::ObIArray &tablet_handle_array, obrpc::ObCopyTabletsSSTableInfoArg &arg) { int ret = OB_SUCCESS; @@ -554,11 +721,11 @@ int ObStorageHATabletsBuilder::build_copy_tablets_sstable_info_arg_( arg.ls_rebuild_seq_ = param_.local_rebuild_seq_; arg.ls_id_ = param_.ls_->get_ls_id(); arg.need_check_seq_ = param_.need_check_seq_; - for (int64_t i = 0; OB_SUCC(ret) && i < param_.tablet_id_array_.count(); ++i) { - const ObTabletID &tablet_id = param_.tablet_id_array_.at(i); + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_handle_array.count(); ++i) { + const ObTabletHandle &tablet_handle = tablet_handle_array.at(i); ObCopyTabletSSTableInfoArg sstable_info_arg; - if (OB_FAIL(build_copy_tablet_sstable_info_arg_(tablet_id, sstable_info_arg))) { - LOG_WARN("failed to build copy tablet sstable info arg", K(ret), K(tablet_id), K(param_)); + if (OB_FAIL(build_copy_tablet_sstable_info_arg_(tablet_handle, sstable_info_arg))) { + LOG_WARN("failed to build copy tablet sstable info arg", K(ret), K(tablet_handle), K(param_)); } else if (OB_FAIL(arg.tablet_sstable_info_arg_list_.push_back(sstable_info_arg))) { LOG_WARN("failed to push sstable info arg into array", K(ret), K(sstable_info_arg), K(param_)); } @@ -568,14 +735,15 @@ int ObStorageHATabletsBuilder::build_copy_tablets_sstable_info_arg_( } int ObStorageHATabletsBuilder::build_copy_tablet_sstable_info_arg_( - const common::ObTabletID &tablet_id, + const ObTabletHandle &tablet_handle, obrpc::ObCopyTabletSSTableInfoArg &arg) { int ret = OB_SUCCESS; ObLS *ls = nullptr; - ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; + ObTabletMemberWrapper table_store_wrapper; arg.reset(); + ObTabletID tablet_id; #ifdef ERRSIM const int64_t errsim_tablet_id = GCONF.errsim_migration_tablet_id; @@ -589,23 +757,23 @@ int ObStorageHATabletsBuilder::build_copy_tablet_sstable_info_arg_( if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("storage ha tablets builder do not init", K(ret)); - } else if (!tablet_id.is_valid()) { + } else if (!tablet_handle.is_valid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("build copy tablet sstable info arg get invalid argument", K(ret), K(tablet_id)); + LOG_WARN("build copy tablet sstable info arg get invalid argument", K(ret), K(tablet_handle)); } else if (OB_ISNULL(ls = param_.ls_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(tablet_id)); - } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet should not be NULL", K(ret), K(tablet_id)); + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_handle)); + } else if (FALSE_IT(tablet_id = tablet->get_tablet_meta().tablet_id_)) { + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { arg.tablet_id_ = tablet_id; - const ObSSTableArray &major_sstable_array = tablet->get_table_store().get_major_sstables(); - const ObSSTableArray &minor_sstable_array = tablet->get_table_store().get_minor_sstables(); - const ObSSTableArray &ddl_sstable_array = tablet->get_table_store().get_ddl_sstables(); + const ObSSTableArray &major_sstable_array = table_store_wrapper.get_member()->get_major_sstables(); + const ObSSTableArray &minor_sstable_array = table_store_wrapper.get_member()->get_minor_sstables(); + const ObSSTableArray &ddl_sstable_array = table_store_wrapper.get_member()->get_ddl_sstables(); //major if (OB_SUCC(ret)) { @@ -616,7 +784,7 @@ int ObStorageHATabletsBuilder::build_copy_tablet_sstable_info_arg_( //minor if (OB_SUCC(ret)) { - if (OB_FAIL(get_remote_logical_minor_scn_range_(minor_sstable_array, arg.minor_sstable_scn_range_))) { + if (OB_FAIL(get_remote_logical_minor_scn_range_(minor_sstable_array, tablet, arg.minor_sstable_scn_range_))) { LOG_WARN("failed to get sstable max end log ts", K(ret), K(tablet_id), K(param_)); } } @@ -681,6 +849,7 @@ int ObStorageHATabletsBuilder::get_major_sstable_max_snapshot_( int ObStorageHATabletsBuilder::get_remote_logical_minor_scn_range_( const ObSSTableArray &minor_sstable_array, + ObTablet *tablet, ObScnRange &scn_range) { int ret = OB_SUCCESS; @@ -692,6 +861,13 @@ int ObStorageHATabletsBuilder::get_remote_logical_minor_scn_range_( if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("storage ha tables builder do not init", K(ret)); + } else if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get remote logical minor scn range get invalid argument", K(ret), KP(tablet)); + } else if (tablet->get_tablet_meta().has_transfer_table()) { + //transfer tablet should copy whole sstable from src; + scn_range.start_scn_ = ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN; + scn_range.end_scn_.set_max(); } else if (minor_sstable_array.count() > 0 && OB_FAIL(minor_sstable_array.get_all_tables(sstables))) { LOG_WARN("failed to get all tables", K(ret), K(param_)); } else { @@ -805,6 +981,7 @@ int ObStorageHATabletsBuilder::get_ddl_sstable_min_start_scn_( int ObStorageHATabletsBuilder::hold_local_reuse_sstable_( const common::ObTabletID &tablet_id, + ObTabletHandle &local_tablet_hdl, ObTablesHandleArray &tables_handle, ObStorageSchema &storage_schema, compaction::ObMediumCompactionInfoList &medium_info_list, @@ -812,25 +989,26 @@ int ObStorageHATabletsBuilder::hold_local_reuse_sstable_( { int ret = OB_SUCCESS; tables_handle.reset(); - ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; - + ObArenaAllocator arena_allocator; + const ObStorageSchema *tablet_storage_schema = nullptr; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("storage ha tablets builder do not init", K(ret)); } else if (!tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("hold local reuse sstable get invalid argument", K(ret), K(tablet_id)); - } else if (OB_FAIL(param_.ls_->get_tablet(tablet_id, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(param_.ls_->ha_get_tablet(tablet_id, local_tablet_hdl))) { if (OB_TABLET_NOT_EXIST == ret) { ret = OB_SUCCESS; } else { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); } - } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + } else if (OB_ISNULL(tablet = local_tablet_hdl.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), K(tablet_id), KP(tablet)); + } else if (OB_FAIL(tablet->load_storage_schema(arena_allocator, tablet_storage_schema))) { + LOG_WARN("fail to load storage schema failed", K(ret)); } else { while (OB_SUCC(ret)) { if (tablet->get_tablet_meta().has_next_tablet_) { @@ -842,21 +1020,13 @@ int ObStorageHATabletsBuilder::hold_local_reuse_sstable_( } else if (OB_FAIL(hold_local_complete_tablet_sstable_(tablet, tables_handle))) { LOG_WARN("failed to hold local complete tablet sstable", K(ret), KP(tablet)); } else { - if (!storage_schema.is_inited() - || storage_schema.get_schema_version() < tablet->get_storage_schema().get_schema_version()) { + if (!storage_schema.is_valid() + || storage_schema.compare_schema_newer(*tablet_storage_schema)) { storage_schema.reset(); - if (OB_FAIL(storage_schema.init(allocator, tablet->get_storage_schema()))) { + if (OB_FAIL(storage_schema.init(allocator, *tablet_storage_schema))) { LOG_WARN("failed to init storage schema", K(ret), KPC(tablet)); } } - if (OB_SUCC(ret) - && (!medium_info_list.is_valid() - || medium_info_list.get_last_compaction_scn() < tablet->get_medium_compaction_info_list().get_last_compaction_scn())) { - medium_info_list.reset(); - if (OB_FAIL(medium_info_list.init(allocator, &tablet->get_medium_compaction_info_list()))) { - LOG_WARN("failed to init medium info list", K(ret), K(tablet->get_medium_compaction_info_list())); - } - } } if (OB_FAIL(ret)) { @@ -871,6 +1041,7 @@ int ObStorageHATabletsBuilder::hold_local_reuse_sstable_( } } // end of while } + ObTablet::free_storage_schema(arena_allocator, tablet_storage_schema); return ret; } @@ -879,6 +1050,7 @@ int ObStorageHATabletsBuilder::hold_local_complete_tablet_sstable_( ObTablesHandleArray &tables_handle) { int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; if (!is_inited_) { ret = OB_NOT_INIT; @@ -888,10 +1060,12 @@ int ObStorageHATabletsBuilder::hold_local_complete_tablet_sstable_( LOG_WARN("hold local complete tablet sstable get invalid argument", K(ret)); } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { LOG_INFO("ls inner tablet do not reuse any sstable", K(ret), KPC(tablet)); + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - const ObSSTableArray &major_sstable = tablet->get_table_store().get_major_sstables(); + const ObSSTableArray &major_sstable = table_store_wrapper.get_member()->get_major_sstables(); for (int64_t i = 0; OB_SUCC(ret) && i < major_sstable.count(); ++i) { - ObITable *table = major_sstable.get_table(i); + ObITable *table = major_sstable.at(i); bool is_exist = false; if (OB_ISNULL(table) || !table->is_major_sstable()) { @@ -910,7 +1084,7 @@ int ObStorageHATabletsBuilder::hold_local_complete_tablet_sstable_( } if (OB_SUCC(ret)) { - if (!is_exist && OB_FAIL(tables_handle.add_table(table))) { + if (!is_exist && OB_FAIL(tables_handle.add_sstable(table, table_store_wrapper.get_meta_handle()))) { LOG_WARN("failed to add table into tables handle", K(ret), KPC(tablet)); } } @@ -942,6 +1116,7 @@ int ObStorageHATabletsBuilder::remove_uncomplete_tablet_( } int ObStorageHATabletsBuilder::create_tablet_remote_logical_sstable_( + common::ObArenaAllocator &allocator, const common::ObTabletID &tablet_id, ObTablesHandleArray &tables_handle) { @@ -955,16 +1130,17 @@ int ObStorageHATabletsBuilder::create_tablet_remote_logical_sstable_( if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("storage ha tabelts builder do not init", K(ret)); + LOG_WARN("storage ha tablets builder do not init", K(ret)); } else if (!tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("create tablet remote logical sstable get invalid argument", K(ret), K(tablet_id)); - } else if (OB_FAIL(param_.ls_->get_tablet(tablet_id, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(param_.ls_->ha_get_tablet(tablet_id, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_id)); + } else if (tablet->get_tablet_meta().has_transfer_table()) { + LOG_INFO("has transfer table do not create remote logical table", K(tablet_id)); } else if (FALSE_IT(start_scn = tablet->get_tablet_meta().start_scn_)) { } else if (FALSE_IT(end_scn = tablet->get_tablet_meta().clog_checkpoint_scn_)) { } else if (start_scn > end_scn) { @@ -979,7 +1155,7 @@ int ObStorageHATabletsBuilder::create_tablet_remote_logical_sstable_( if (start_scn >= end_scn|| end_scn == ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN) { LOG_INFO("local tablet sstable is continue with memtable, no need create remote logical sstable", K(tablet_id), K(minor_tables), K(start_scn), K(start_scn)); - } else if (OB_FAIL(create_remote_logical_sstable_(tablet_id, start_scn, end_scn, tablet, table_handle))) { + } else if (OB_FAIL(create_remote_logical_sstable_(allocator, tablet_id, start_scn, end_scn, tablet, table_handle))) { LOG_WARN("failed to create remote logical sstable", K(ret), K(tablet_id), K(start_scn), K(end_scn), KPC(tablet)); } else if (OB_FAIL(tables_handle.add_table(table_handle))) { LOG_WARN("failed to add table handle into tables handle", K(ret), K(table_handle), K(tables_handle)); @@ -989,6 +1165,7 @@ int ObStorageHATabletsBuilder::create_tablet_remote_logical_sstable_( } int ObStorageHATabletsBuilder::create_remote_logical_sstable_( + common::ObArenaAllocator &arena_allocator, const common::ObTabletID &tablet_id, const SCN start_scn, const SCN end_scn, @@ -997,21 +1174,32 @@ int ObStorageHATabletsBuilder::create_remote_logical_sstable_( { int ret = OB_SUCCESS; ObTabletCreateSSTableParam create_sstable_param; - + void *buf = nullptr; + ObSSTable *sstable = nullptr; + ObArenaAllocator allocator; + const ObStorageSchema *storage_schema = nullptr; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("storage ha tablets builder do not init", K(ret)); } else if (!tablet_id.is_valid() || OB_ISNULL(tablet) || !start_scn.is_valid() || !end_scn.is_valid() || start_scn == end_scn) { ret = OB_INVALID_ARGUMENT; LOG_WARN("create remote logical sstable get invalid argument", K(ret), KPC(tablet), K(start_scn), K(end_scn)); - } else if (OB_FAIL(build_remote_logical_sstable_param_(start_scn, end_scn, tablet->get_storage_schema(), + } else if (OB_FAIL(tablet->load_storage_schema(allocator, storage_schema))) { + LOG_WARN("fail to load storage schema failed", K(ret)); + } else if (OB_FAIL(build_remote_logical_sstable_param_(start_scn, end_scn, *storage_schema, tablet_id, create_sstable_param))) { LOG_WARN("failed to build remote logical sstable param", K(ret), K(tablet_id), K(start_scn), K(end_scn)); - } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(create_sstable_param, table_handle))) { + } else if (OB_ISNULL(buf = arena_allocator.alloc(sizeof(ObSSTable)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate sstable", K(ret)); + } else if (FALSE_IT(sstable = new (buf) ObSSTable())) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(create_sstable_param, arena_allocator, *sstable))) { LOG_WARN("failed to create sstable", K(ret), K(create_sstable_param), K(tablet_id)); } else { + table_handle.set_sstable(sstable, &arena_allocator); LOG_INFO("succeed to create remote logical sstable", K(tablet_id), K(table_handle), KPC(tablet)); } + ObTablet::free_storage_schema(allocator, storage_schema); return ret; } @@ -1129,8 +1317,7 @@ int ObStorageHATabletsBuilder::update_local_tablet_( LOG_WARN("tablet should not be inner tablet, can not update", K(ret), K(tablet_info)); } else if (ObCopyTabletStatus::TABLET_NOT_EXIST == tablet_info.status_) { //do nothing - } else if (OB_FAIL(ls->get_tablet(tablet_info.tablet_id_, tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls->ha_get_tablet(tablet_info.tablet_id_, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_info)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; @@ -1151,6 +1338,28 @@ int ObStorageHATabletsBuilder::update_local_tablet_( return ret; } +int ObStorageHATabletsBuilder::modified_tablet_info_( + obrpc::ObCopyTabletInfo &tablet_info) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("storage ha tablets builder do not init", K(ret)); + } else if (!tablet_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("modified tablet info get invalid argument", K(ret), K(tablet_info)); + } else if (tablet_info.param_.is_empty_shell()) { + // do nothing + } else if (tablet_info.param_.ha_status_.is_restore_status_full() + && !tablet_info.param_.ha_status_.is_data_status_complete()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet info ha status is unexpected", K(ret), K(tablet_info)); + } else if (OB_FAIL(tablet_info.param_.ha_status_.set_data_status(ObTabletDataStatus::INCOMPLETE))) { + LOG_WARN("failed to set data status", K(ret), K(tablet_info)); + } + return ret; +} + int ObStorageHATabletsBuilder::create_tablet_with_major_sstables_( ObLS *ls, const obrpc::ObCopyTabletInfo &tablet_info, @@ -1171,17 +1380,33 @@ int ObStorageHATabletsBuilder::create_tablet_with_major_sstables_( return ret; } -int ObStorageHATabletsBuilder::get_src_deleted_tablet_list( - common::ObIArray &tablet_id_list) +int ObStorageHATabletsBuilder::hold_local_tablet_( + common::ObIArray &tablet_handle_array) { int ret = OB_SUCCESS; - tablet_id_list.reset(); + ObLS *ls = nullptr; + tablet_handle_array.reset(); if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("storage ha tablets builder do not init", K(ret)); - } else if (OB_FAIL(tablet_id_list.assign(deleted_tablet_id_list_))) { - LOG_WARN("failed to assign tablet id list", K(ret), K(deleted_tablet_id_list_)); + } else if (OB_ISNULL(ls = param_.ls_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", K(ret), KP(ls), K(param_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < param_.tablet_id_array_.count(); ++i) { + const ObTabletID &tablet_id = param_.tablet_id_array_.at(i); + ObTabletHandle tablet_handle; + if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } + } else if (OB_FAIL(tablet_handle_array.push_back(tablet_handle))) { + LOG_WARN("failed to push tablet handle into array", K(ret), K(tablet_handle)); + } + } } return ret; } @@ -1511,7 +1736,7 @@ int ObStorageHATableInfoMgr::init_tablet_info( LOG_WARN("failed to alloc memory", K(ret), KP(buf)); } else if (FALSE_IT(tablet_table_info_mgr = new (buf) ObStorageHATabletTableInfoMgr())) { } else if (OB_FAIL(tablet_table_info_mgr->init(copy_header.tablet_id_, copy_header.status_, copy_header.tablet_meta_))) { - LOG_WARN("failed to init tabelt table key mgr", K(ret), K(copy_header)); + LOG_WARN("failed to init tablet table key mgr", K(ret), K(copy_header)); } else if (OB_FAIL(table_info_mgr_map_.set_refactored(copy_header.tablet_id_, tablet_table_info_mgr))) { LOG_WARN("failed to set tablet table key mgr into map", K(ret), K(copy_header)); } @@ -1695,7 +1920,8 @@ ObStorageHACopySSTableInfoMgr::ObStorageHACopySSTableInfoMgr() : is_inited_(false), param_(), allocator_("HACopySSTMgr"), - macro_range_info_map_() + macro_range_info_map_(), + status_(ObCopyTabletStatus::TABLET_EXIST) { } @@ -1753,7 +1979,13 @@ int ObStorageHACopySSTableInfoMgr::build_sstable_macro_range_info_map_() } else if (param_.copy_table_key_array_.empty()) { LOG_INFO("tablet do not has any sstable", K(ret), K(param_)); } else if (OB_FAIL(get_sstable_macro_range_info_reader_(reader))) { - LOG_WARN("failed to get sstable macro range info reader", K(ret), K(param_)); + if (OB_TABLET_NOT_EXIST == ret) { + LOG_INFO("src tablet do not exist", K(param_)); + status_ = ObCopyTabletStatus::TABLET_NOT_EXIST; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get sstable macro range info reader", K(ret), K(param_)); + } } else { while (OB_SUCC(ret)) { sstable_macro_range_info.reset(); @@ -1950,6 +2182,18 @@ int ObStorageHACopySSTableInfoMgr::get_copy_sstable_maro_range_info( return ret; } +int ObStorageHACopySSTableInfoMgr::check_src_tablet_exist(bool &is_exist) +{ + int ret = OB_SUCCESS; + is_exist = true; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("storage ha copy sstable info mgr do not init", K(ret)); + } else { + is_exist = ObCopyTabletStatus::TABLET_EXIST == status_; + } + return ret; +} /******************ObStorageHATabletBuilderUtil*********************/ @@ -1959,7 +2203,7 @@ int ObStorageHATabletBuilderUtil::get_tablet_( ObTabletHandle &tablet_handle) { int ret = OB_SUCCESS; - if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id), KPC(ls)); } return ret; @@ -1991,7 +2235,9 @@ int ObStorageHATabletBuilderUtil::build_tablet_with_major_tables( } else if (OB_FAIL(ObTableStoreUtil::sort_major_tables(major_table_array))) { LOG_WARN("failed to sort mjaor tables", K(ret)); } else { + ObTableHandleV2 major_table_handle; for (int64_t i = 0; OB_SUCC(ret) && i < major_table_array.count(); ++i) { + major_table_handle.reset(); ObITable *table_ptr = major_table_array.at(i); if (OB_ISNULL(table_ptr)) { ret = OB_ERR_UNEXPECTED; @@ -1999,8 +2245,10 @@ int ObStorageHATabletBuilderUtil::build_tablet_with_major_tables( } else if (!table_ptr->is_major_sstable()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table ptr is not major", K(ret), KPC(table_ptr)); - } else if (OB_FAIL(inner_update_tablet_table_store_with_major_(multi_version_start, ls, - tablet, table_ptr, storage_schema, medium_info_list))) { + } else if (OB_FAIL(major_tables.get_table(table_ptr->get_key(), major_table_handle))) { + LOG_WARN("fail to get table handle from array by table key", K(ret), KPC(table_ptr), K(major_tables)); + } else if (OB_FAIL(inner_update_tablet_table_store_with_major_(multi_version_start, major_table_handle, + ls, tablet, storage_schema))) { LOG_WARN("failed to update tablet table store", K(ret), K(tablet_id), KPC(table_ptr)); } } @@ -2016,13 +2264,16 @@ int ObStorageHATabletBuilderUtil::calc_multi_version_start_with_major_( int ret = OB_SUCCESS; multi_version_start = 0; int64_t tmp_multi_version_start = INT64_MAX; + ObTabletMemberWrapper table_store_wrapper; if (OB_ISNULL(tablet)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("calc multi version start with major get invalid argument", K(ret), KP(tablet)); + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - const ObSSTableArray &local_major_tables = tablet->get_table_store().get_major_sstables(); + const ObSSTableArray &local_major_tables = table_store_wrapper.get_member()->get_major_sstables(); for (int64_t i = 0; OB_SUCC(ret) && i < local_major_tables.count(); ++i) { - const ObITable *table = local_major_tables.get_table(i); + const ObITable *table = local_major_tables.at(i); if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table should not be NULL", K(ret), KP(table), KPC(tablet)); @@ -2054,32 +2305,33 @@ int ObStorageHATabletBuilderUtil::calc_multi_version_start_with_major_( int ObStorageHATabletBuilderUtil::inner_update_tablet_table_store_with_major_( const int64_t multi_version_start, + const ObTableHandleV2 &table_handle, ObLS *ls, ObTablet *tablet, - ObITable *table, - const ObStorageSchema &storage_schema, - const compaction::ObMediumCompactionInfoList &medium_info_list) + const ObStorageSchema &storage_schema) { int ret = OB_SUCCESS; ObTabletHandle tablet_handle; - ObTableHandleV2 table_handle_v2; SCN tablet_snapshot_version; ObTenantMetaMemMgr *meta_mem_mgr = nullptr; - if (multi_version_start < 0 || OB_ISNULL(tablet) || OB_ISNULL(table) || OB_ISNULL(ls)) { + ObArenaAllocator allocator; + const ObStorageSchema *tablet_storage_schema = nullptr; + if (multi_version_start < 0 || OB_ISNULL(tablet) || OB_ISNULL(ls) || !table_handle.is_valid()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("table ptr should not be null", K(ret), K(multi_version_start), KP(tablet), KP(table), KP(ls)); + LOG_WARN("table ptr should not be null", K(ret), K(multi_version_start), KP(tablet), K(table_handle), KP(ls)); } else if (OB_ISNULL(meta_mem_mgr = MTL(ObTenantMetaMemMgr *))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get meta mem mgr from MTL", K(ret)); - } else if (OB_FAIL(table_handle_v2.set_table(table, meta_mem_mgr, table->get_key().table_type_))) { - LOG_WARN("failed to set table handle v2", K(ret), KPC(table)); } else if (OB_FAIL(tablet->get_snapshot_version(tablet_snapshot_version))) { LOG_WARN("failed to get_snapshot_version", K(ret)); + } else if (OB_FAIL(tablet->load_storage_schema(allocator, tablet_storage_schema))) { + LOG_WARN("fail to load storage schema failed", K(ret)); } else { const ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; + const ObITable *table = table_handle.get_table(); const int64_t update_snapshot_version = MAX(tablet->get_snapshot_version(), table->get_key().get_snapshot_version()); const int64_t update_multi_version_start = MAX(tablet->get_multi_version_start(), multi_version_start); - ObUpdateTableStoreParam param(table_handle_v2, + ObUpdateTableStoreParam param(static_cast(table), update_snapshot_version, update_multi_version_start, &storage_schema, @@ -2088,13 +2340,12 @@ int ObStorageHATabletBuilderUtil::inner_update_tablet_table_store_with_major_( SCN::min_scn()/*clog_checkpoint_scn*/, true/*need_check_sstable*/, true/*allow_duplicate_sstable*/, - &medium_info_list, ObMergeType::MEDIUM_MERGE/*merge_type*/); - if (tablet->get_storage_schema().get_version() < storage_schema.get_version()) { + if (tablet_storage_schema->get_version() < storage_schema.get_version()) { SERVER_EVENT_ADD("storage_ha", "schema_change_need_merge_tablet_meta", "tenant_id", MTL_ID(), "tablet_id", tablet_id.id(), - "old_schema_version", tablet->get_storage_schema().get_version(), + "old_schema_version", tablet_storage_schema->get_version(), "new_schema_version", storage_schema.get_version()); } #ifdef ERRSIM @@ -2109,6 +2360,7 @@ int ObStorageHATabletBuilderUtil::inner_update_tablet_table_store_with_major_( LOG_WARN("failed to build ha tablet new table store", K(ret), KPC(tablet), K(param)); } } + ObTablet::free_storage_schema(allocator, tablet_storage_schema); return ret; } @@ -2122,6 +2374,7 @@ int ObStorageHATabletBuilderUtil::build_table_with_minor_tables( ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; const bool need_tablet_meta_merge = true; + const bool update_ddl_sstable = false; if (OB_ISNULL(ls) || !tablet_id.is_valid() || OB_ISNULL(src_tablet_meta)) { ret = OB_INVALID_ARGUMENT; @@ -2129,7 +2382,8 @@ int ObStorageHATabletBuilderUtil::build_table_with_minor_tables( } else if (OB_FAIL(get_tablet_(tablet_id, ls, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id), KPC(ls)); } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_FAIL(inner_update_tablet_table_store_with_minor_(ls, tablet, need_tablet_meta_merge, src_tablet_meta, minor_tables))) { + } else if (OB_FAIL(inner_update_tablet_table_store_with_minor_(ls, tablet, need_tablet_meta_merge, + src_tablet_meta, minor_tables, update_ddl_sstable))) { LOG_WARN("failed to update tablet table store with minor", K(ret)); } return ret; @@ -2145,6 +2399,7 @@ int ObStorageHATabletBuilderUtil::build_table_with_ddl_tables( ObTablet *tablet = nullptr; const bool need_tablet_meta_merge = false; const ObMigrationTabletParam *src_tablet_meta = nullptr; + const bool update_ddl_sstable = true; if (OB_ISNULL(ls) || !tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; @@ -2152,7 +2407,8 @@ int ObStorageHATabletBuilderUtil::build_table_with_ddl_tables( } else if (OB_FAIL(get_tablet_(tablet_id, ls, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id), KPC(ls)); } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_FAIL(inner_update_tablet_table_store_with_minor_(ls, tablet, need_tablet_meta_merge, src_tablet_meta, ddl_tables))) { + } else if (OB_FAIL(inner_update_tablet_table_store_with_minor_(ls, tablet, need_tablet_meta_merge, + src_tablet_meta, ddl_tables, update_ddl_sstable))) { LOG_WARN("failed to update tablet table store with minor", K(ret)); } return ret; @@ -2163,7 +2419,8 @@ int ObStorageHATabletBuilderUtil::inner_update_tablet_table_store_with_minor_( ObTablet *tablet, const bool &need_tablet_meta_merge, const ObMigrationTabletParam *src_tablet_meta, - const ObTablesHandleArray &tables_handle) + const ObTablesHandleArray &tables_handle, + const bool update_ddl_sstable) { int ret = OB_SUCCESS; ObBatchUpdateTableStoreParam update_table_store_param; @@ -2179,13 +2436,12 @@ int ObStorageHATabletBuilderUtil::inner_update_tablet_table_store_with_minor_( const ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; update_table_store_param.tablet_meta_ = need_merge ? src_tablet_meta : nullptr; update_table_store_param.rebuild_seq_ = ls->get_rebuild_seq(); + update_table_store_param.update_ddl_sstable_ = update_ddl_sstable; - if (tables_handle.empty()) { - //do nothing - } else if (OB_FAIL(update_table_store_param.tables_handle_.assign(tables_handle))) { + if (OB_FAIL(update_table_store_param.tables_handle_.assign(tables_handle))) { LOG_WARN("failed to assign tables handle", K(ret), K(tables_handle)); } else if (OB_FAIL(ls->build_ha_tablet_new_table_store(tablet_id, update_table_store_param))) { - LOG_WARN("failed to build ha tablet new table store", K(ret), K(tablet_id), KPC(src_tablet_meta), K(update_table_store_param)); + LOG_WARN("failed to build ha tablet new table store", K(ret), K(tablet_id), KPC(tablet), KPC(src_tablet_meta), K(update_table_store_param)); } } return ret; @@ -2202,6 +2458,11 @@ int ObStorageHATabletBuilderUtil::check_need_merge_tablet_meta_( if (OB_ISNULL(tablet) || OB_ISNULL(src_tablet_meta)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("check need merge tablet meta get invalid argument", K(ret), KP(tablet), KP(src_tablet_meta)); + } else if (tablet->get_tablet_meta().has_transfer_table()) { + // If transfer table exist, no remote logical table will be created. And, the replaced transfer table + // must be included in the minor tables. The transfer table info of local tablet need to be cleared by + // merging tablet meta. + need_merge = true; } else if (tablet->get_tablet_meta().clog_checkpoint_scn_ >= src_tablet_meta->clog_checkpoint_scn_) { need_merge = false; } else if (OB_FAIL(check_remote_logical_sstable_exist(tablet, is_exist))) { @@ -2220,14 +2481,17 @@ int ObStorageHATabletBuilderUtil::check_remote_logical_sstable_exist( { int ret = OB_SUCCESS; is_exist = false; + ObTabletMemberWrapper table_store_wrapper; if (OB_ISNULL(tablet)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("check remote logical sstable exist get invalid argument", K(ret), KP(tablet)); + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - const ObSSTableArray &minor_sstables = tablet->get_table_store().get_minor_sstables(); + const ObSSTableArray &minor_sstables = table_store_wrapper.get_member()->get_minor_sstables(); for (int64_t i = 0; OB_SUCC(ret) && i < minor_sstables.count(); ++i) { - const ObITable *table = minor_sstables.array_[i]; + const ObITable *table = minor_sstables.at(i); if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("minor sstable should not be NULL", K(ret), KP(table)); diff --git a/src/storage/high_availability/ob_storage_ha_tablet_builder.h b/src/storage/high_availability/ob_storage_ha_tablet_builder.h index 0610f944d..e900822d7 100644 --- a/src/storage/high_availability/ob_storage_ha_tablet_builder.h +++ b/src/storage/high_availability/ob_storage_ha_tablet_builder.h @@ -69,11 +69,20 @@ public: ObStorageHATabletsBuilder(); virtual ~ObStorageHATabletsBuilder(); int init(const ObStorageHATabletsBuilderParam ¶m); + // Create all tablets with remote tablet meta. int create_or_update_tablets(); + int create_all_tablets( + ObICopyLSViewInfoReader *reader, + common::ObIArray &sys_tablet_id_list, + common::ObIArray &data_tablet_id_list, + CopyTabletSimpleInfoMap &simple_info_map); + // Restore PENDING tablets meta. PENDING tablets will be exist at restore phase RESTORE_SYS_TABLETS, + // RESTORE_TO_CONSISTENT_SCN, or QUICK_RESTORE. Leader gets the meta from backup, follower gets it from leader. + // If that tablet meta identified uniquely by transfer sequence exists, replace and update the restore status to EMPTY. + // Otherwise, just update it to UNDEFINED. + int update_pending_tablets_with_remote(); int build_tablets_sstable_info(); int update_local_tablets(); - const CopyTabletSimpleInfoMap &get_tablets_simple_info_map() { return tablet_simple_info_map_ ; } - int get_src_deleted_tablet_list(common::ObIArray &tablet_id_list); private: int get_tablet_info_reader_(ObICopyTabletInfoReader *&reader); @@ -83,22 +92,31 @@ private: int create_or_update_tablet_( const obrpc::ObCopyTabletInfo &tablet_info, ObLS *ls); - int get_tablets_sstable_reader_(ObICopySSTableInfoReader *&reader); + int get_tablets_sstable_reader_( + const common::ObIArray &tablet_handle_array, + ObICopySSTableInfoReader *&reader); int build_tablets_sstable_info_( const obrpc::ObCopyTabletSSTableInfo &sstable_info); - int get_tablets_sstable_restore_reader_(ObICopySSTableInfoReader *&reader); - int get_tablets_sstable_ob_reader_(ObICopySSTableInfoReader *&reader); + int get_tablets_sstable_restore_reader_( + const common::ObIArray &tablet_handle_array, + ObICopySSTableInfoReader *&reader); + int get_tablets_sstable_ob_reader_( + const common::ObIArray &tablet_handle_array, + ObICopySSTableInfoReader *&reader); void free_sstable_info_reader_(ObICopySSTableInfoReader *&reader); - int build_copy_tablets_sstable_info_arg_(obrpc::ObCopyTabletsSSTableInfoArg &arg); + int build_copy_tablets_sstable_info_arg_( + const common::ObIArray &tablet_handle_array, + obrpc::ObCopyTabletsSSTableInfoArg &arg); int build_copy_tablet_sstable_info_arg_( - const common::ObTabletID &tablet_id, + const ObTabletHandle &tablet_handle, obrpc::ObCopyTabletSSTableInfoArg &arg); int get_major_sstable_max_snapshot_( const ObSSTableArray &major_sstable_array, int64_t &max_snapshot_version); int get_remote_logical_minor_scn_range_( const ObSSTableArray &minor_sstable_array, + ObTablet *tablet, share::ObScnRange &scn_range); int get_need_copy_ddl_sstable_range_( const ObTablet *tablet, @@ -109,6 +127,7 @@ private: share::SCN &max_start_scn); int hold_local_reuse_sstable_( const common::ObTabletID &tablet_id, + ObTabletHandle &local_tablet_hdl, ObTablesHandleArray &tables_handle, ObStorageSchema &storage_schema, compaction::ObMediumCompactionInfoList &medium_info_list, @@ -119,9 +138,11 @@ private: int remove_uncomplete_tablet_( const common::ObTabletID &tablet_id); int create_tablet_remote_logical_sstable_( + common::ObArenaAllocator &allocator, const common::ObTabletID &tablet_id, ObTablesHandleArray &tables_handle); int create_remote_logical_sstable_( + common::ObArenaAllocator &allocator, const common::ObTabletID &tablet_id, const share::SCN start_scn, const share::SCN end_scn, @@ -139,17 +160,20 @@ private: int create_tablet_remote_logical_sstable_( ObTablet *tablet, ObTablesHandleArray &tables_handle); + int modified_tablet_info_( + obrpc::ObCopyTabletInfo &tablet_info); + int create_tablet_with_major_sstables_( ObLS *ls, const obrpc::ObCopyTabletInfo &tablet_info, const ObTablesHandleArray &major_tables, const ObStorageSchema &storage_schema, const compaction::ObMediumCompactionInfoList &medium_info_list); + int hold_local_tablet_( + common::ObIArray &tablet_handle_array); private: bool is_inited_; ObStorageHATabletsBuilderParam param_; - CopyTabletSimpleInfoMap tablet_simple_info_map_; - ObArray deleted_tablet_id_list_; DISALLOW_COPY_AND_ASSIGN(ObStorageHATabletsBuilder); }; @@ -256,6 +280,7 @@ public: int get_copy_sstable_maro_range_info( const ObITable::TableKey ©_table_key, ObCopySSTableMacroRangeInfo ©_sstable_macro_range_info); + int check_src_tablet_exist(bool &is_exist); private: int build_sstable_macro_range_info_map_(); int get_sstable_macro_range_info_reader_(ObICopySSTableMacroInfoReader *&reader); @@ -270,7 +295,7 @@ private: ObStorageHACopySSTableParam param_; ObArenaAllocator allocator_; CopySSTableMacroRangeInfoMap macro_range_info_map_; - + storage::ObCopyTabletStatus::STATUS status_; DISALLOW_COPY_AND_ASSIGN(ObStorageHACopySSTableInfoMgr); }; @@ -306,17 +331,17 @@ private: int64_t &multi_version_start); static int inner_update_tablet_table_store_with_major_( const int64_t multi_version_start, + const ObTableHandleV2 &table_handle, ObLS *ls, ObTablet *tablet, - ObITable *table, - const ObStorageSchema &storage_schema, - const compaction::ObMediumCompactionInfoList &medium_info_list); + const ObStorageSchema &storage_schema); static int inner_update_tablet_table_store_with_minor_( ObLS *ls, ObTablet *tablet, const bool &need_tablet_meta_merge, const ObMigrationTabletParam *src_tablet_meta, - const ObTablesHandleArray &tables_handle); + const ObTablesHandleArray &tables_handle, + const bool update_ddl_sstable); static int check_need_merge_tablet_meta_( const ObMigrationTabletParam *src_tablet_meta, ObTablet *tablet, diff --git a/src/storage/high_availability/ob_storage_ha_utils.cpp b/src/storage/high_availability/ob_storage_ha_utils.cpp index 3da847796..ae08946d3 100644 --- a/src/storage/high_availability/ob_storage_ha_utils.cpp +++ b/src/storage/high_availability/ob_storage_ha_utils.cpp @@ -11,13 +11,25 @@ #define USING_LOG_PREFIX STORAGE #include "ob_storage_ha_utils.h" +#include "observer/ob_server_struct.h" +#include "share/config/ob_server_config.h" +#include "share/location_cache/ob_location_service.h" #include "share/ob_zone_merge_info.h" #include "share/tablet/ob_tablet_table_operator.h" #include "share/ob_global_merge_table_operator.h" #include "share/ob_tablet_replica_checksum_operator.h" #include "share/scn.h" +#include "share/ls/ob_ls_info.h" +#include "ob_storage_ha_struct.h" +#include "share/ls/ob_ls_table_operator.h" +#include "observer/ob_server_event_history_table_operator.h" +#include "observer/ob_server_struct.h" +#include "observer/ob_service.h" #include "share/ob_version.h" #include "share/ob_cluster_version.h" +#include "storage/ob_storage_rpc.h" +#include "storage/tx/ob_ts_mgr.h" +#include "storage/tx_storage/ob_ls_service.h" using namespace oceanbase::share; @@ -26,6 +38,48 @@ namespace oceanbase namespace storage { +int ObStorageHAUtils::get_ls_leader(const uint64_t tenant_id, const share::ObLSID &ls_id, common::ObAddr &leader) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + static const int64_t DEFAULT_CHECK_LS_LEADER_TIMEOUT = 1 * 60 * 1000 * 1000L; // 1min + const int64_t cluster_id = GCONF.cluster_id; + if (OB_ISNULL(GCTX.location_service_)) { + ret = OB_NOT_INIT; + LOG_WARN("location cache is NULL", K(ret)); + } else if (OB_INVALID_ID == tenant_id || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(tenant_id), K(ls_id)); + } else { + uint32_t renew_count = 0; + const uint32_t max_renew_count = 10; + const int64_t retry_us = 200 * 1000; + const int64_t start_ts = ObTimeUtility::current_time(); + do { + if (OB_FAIL(GCTX.location_service_->nonblock_get_leader(cluster_id, tenant_id, ls_id, leader))) { + if (OB_LS_LOCATION_NOT_EXIST == ret && renew_count++ < max_renew_count) { // retry ten times + LOG_WARN("failed to get location and force renew", K(ret), K(tenant_id), K(ls_id), K(cluster_id)); + if (OB_SUCCESS != (tmp_ret = GCTX.location_service_->nonblock_renew(cluster_id, tenant_id, ls_id))) { + LOG_WARN("failed to nonblock renew from location cache", K(tmp_ret), K(ls_id), K(cluster_id)); + } else if (ObTimeUtility::current_time() - start_ts > DEFAULT_CHECK_LS_LEADER_TIMEOUT) { + renew_count = max_renew_count; + } else { + ob_usleep(retry_us); + } + } + } else { + LOG_INFO("get ls leader", K(tenant_id), K(ls_id), K(leader), K(cluster_id)); + } + } while (OB_LS_LOCATION_NOT_EXIST == ret && renew_count < max_renew_count); + + if (OB_SUCC(ret) && !leader.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("leader addr is invalid", K(ret), K(tenant_id), K(ls_id), K(leader), K(cluster_id)); + } + } + return ret; +} + int ObStorageHAUtils::check_tablet_replica_validity(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObAddr &src_addr, const common::ObTabletID &tablet_id, common::ObISQLClient &sql_client) { @@ -74,6 +128,27 @@ int ObStorageHAUtils::check_server_version(const uint64_t server_version) return ret; } +int ObStorageHAUtils::report_ls_meta_table(const uint64_t tenant_id, const share::ObLSID &ls_id, + const storage::ObMigrationStatus &migration_status) +{ + int ret = OB_SUCCESS; + share::ObLSReplica ls_replica; + share::ObLSTableOperator *lst_operator = GCTX.lst_operator_; + const bool inner_table_only = false; + if (OB_FAIL(GCTX.ob_service_->fill_ls_replica(tenant_id, ls_id, ls_replica))) { + LOG_WARN("failed to fill ls replica", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(lst_operator->update(ls_replica, inner_table_only))) { + LOG_WARN("failed to update ls meta table", K(ret), K(ls_replica)); + } else { + SERVER_EVENT_ADD("storage_ha", "report_ls_meta_table", + "tenant_id", tenant_id, + "ls_id", ls_id, + "migration_status", migration_status); + LOG_INFO("report ls meta table", K(ls_replica)); + } + return ret; +} + int ObStorageHAUtils::check_merge_error_(const uint64_t tenant_id, common::ObISQLClient &sql_client) { int ret = OB_SUCCESS; @@ -138,5 +213,162 @@ int ObStorageHAUtils::check_tablet_replica_checksum_(const uint64_t tenant_id, c return ret; } +int ObStorageHAUtils::check_ls_deleted( + const share::ObLSID &ls_id, + bool &is_deleted) +{ + int ret = OB_SUCCESS; + const int64_t tenant_id = MTL_ID(); + ObLSExistState state = ObLSExistState::MAX_STATE; + is_deleted = false; + + // sys tenant should always return LS_NORMAL + if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get ls status from inner table get invalid argument", K(ret), K(ls_id)); + } else if (OB_FAIL(ObLocationService::check_ls_exist(tenant_id, ls_id, state))) { + LOG_WARN("failed to check ls exist", K(ret), K(tenant_id), K(ls_id)); + } else if (state.is_deleted()) { + is_deleted = true; + } else { + is_deleted = false; + } + return ret; +} + + +bool ObTransferUtils::is_need_retry_error(const int err) +{ + bool bool_ret = false; + //white list + switch (err) { + //Has active trans need retry + case OB_TRANSFER_MEMBER_LIST_NOT_SAME: + case OB_PARTITION_NOT_LEADER: + case OB_TRANS_TIMEOUT: + bool_ret = true; + break; + default: + break; + } + return bool_ret; +} + +int ObTransferUtils::block_tx(const uint64_t tenant_id, const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ObLSService *ls_svr = NULL; + common::ObAddr leader_addr; + ObStorageHASrcInfo src_info; + ObStorageRpc *storage_rpc = NULL; + share::SCN gts; + if (OB_ISNULL(ls_svr = (MTL(ObLSService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), KP(ls_svr)); + } else if (OB_ISNULL(storage_rpc = ls_svr->get_storage_rpc())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage rpc should not be NULL", K(ret), KP(storage_rpc)); + } else if (OB_FAIL(ObStorageHAUtils::get_ls_leader(tenant_id, ls_id, leader_addr))) { + LOG_WARN("failed to get ls leader", K(ret), K(tenant_id)); + } else if (OB_FAIL(get_gts(tenant_id, gts))) { + LOG_WARN("failed to get gts", K(ret), K(tenant_id)); + } else { + src_info.src_addr_ = leader_addr; + src_info.cluster_id_ = GCONF.cluster_id; + if (OB_FAIL(storage_rpc->block_tx(tenant_id, src_info, ls_id, gts))) { + LOG_WARN("failed to block tx", K(ret), K(tenant_id), K(src_info), K(ls_id), K(gts)); + } + } + return ret; +} + +// TODO(yangyi.yyy): get gts before block and kill tx, unblock no need get gts +int ObTransferUtils::kill_tx(const uint64_t tenant_id, const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ObLSService *ls_svr = NULL; + common::ObAddr leader_addr; + ObStorageHASrcInfo src_info; + ObStorageRpc *storage_rpc = NULL; + share::SCN gts; + if (OB_ISNULL(ls_svr = (MTL(ObLSService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), KP(ls_svr)); + } else if (OB_ISNULL(storage_rpc = ls_svr->get_storage_rpc())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage rpc should not be NULL", K(ret), KP(storage_rpc)); + } else if (OB_FAIL(ObStorageHAUtils::get_ls_leader(tenant_id, ls_id, leader_addr))) { + LOG_WARN("failed to get ls leader", K(ret), K(tenant_id)); + } else if (OB_FAIL(get_gts(tenant_id, gts))) { + LOG_WARN("failed to get gts", K(ret), K(tenant_id)); + } else { + src_info.src_addr_ = leader_addr; + src_info.cluster_id_ = GCONF.cluster_id; + if (OB_FAIL(storage_rpc->kill_tx(tenant_id, src_info, ls_id, gts))) { + LOG_WARN("failed to block tx", K(ret), K(tenant_id), K(src_info), K(ls_id), K(gts)); + } + } + return ret; +} + +int ObTransferUtils::unblock_tx(const uint64_t tenant_id, const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ObLSService *ls_svr = NULL; + common::ObAddr leader_addr; + ObStorageHASrcInfo src_info; + ObStorageRpc *storage_rpc = NULL; + share::SCN gts; + + if (OB_ISNULL(ls_svr = (MTL(ObLSService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), KP(ls_svr)); + } else if (OB_ISNULL(storage_rpc = ls_svr->get_storage_rpc())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage rpc should not be NULL", K(ret), KP(storage_rpc)); + } else if (OB_FAIL(ObStorageHAUtils::get_ls_leader(tenant_id, ls_id, leader_addr))) { + LOG_WARN("failed to get ls leader", K(ret), K(tenant_id)); + } else if (OB_FAIL(get_gts(tenant_id, gts))) { + LOG_WARN("failed to get gts", K(ret), K(tenant_id)); + } else { + src_info.src_addr_ = leader_addr; + src_info.cluster_id_ = GCONF.cluster_id; + if (OB_FAIL(storage_rpc->unblock_tx(tenant_id, src_info, ls_id, gts))) { + LOG_WARN("failed to block tx", K(ret), K(tenant_id), K(src_info), K(ls_id), K(gts)); + } + } + return ret; +} + +int ObTransferUtils::get_gts(const uint64_t tenant_id, SCN >s) +{ + int ret = OB_SUCCESS; + if (OB_INVALID_TENANT_ID == tenant_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant id is invalid", K(ret), K(tenant_id)); + } else { + ret = OB_EAGAIN; + const transaction::MonotonicTs stc = transaction::MonotonicTs::current_time(); + transaction::MonotonicTs unused_ts(0); + const int64_t start_time = ObTimeUtility::fast_current_time(); + const int64_t TIMEOUT = 10 * 1000 * 1000; //10s + while (OB_EAGAIN == ret) { + if (ObTimeUtility::fast_current_time() - start_time > TIMEOUT) { + ret = OB_TIMEOUT; + LOG_WARN("get gts timeout", KR(ret), K(start_time), K(TIMEOUT)); + } else if (OB_FAIL(OB_TS_MGR.get_gts(tenant_id, stc, NULL, gts, unused_ts))) { + if (OB_EAGAIN != ret) { + LOG_WARN("failed to get gts", KR(ret), K(tenant_id)); + } else { + // waiting 10ms + ob_usleep(10L * 1000L); + } + } + } + } + LOG_INFO("get tenant gts", KR(ret), K(tenant_id), K(gts)); + return ret; +} + } // end namespace storage } // end namespace oceanbase diff --git a/src/storage/high_availability/ob_storage_ha_utils.h b/src/storage/high_availability/ob_storage_ha_utils.h index a4a85a0da..5b0cddf26 100644 --- a/src/storage/high_availability/ob_storage_ha_utils.h +++ b/src/storage/high_availability/ob_storage_ha_utils.h @@ -13,6 +13,7 @@ #include "share/ob_ls_id.h" #include "common/ob_tablet_id.h" #include "lib/mysqlclient/ob_isql_client.h" +#include "ob_storage_ha_struct.h" namespace oceanbase { @@ -26,10 +27,16 @@ namespace storage class ObStorageHAUtils { public: + static int get_ls_leader(const uint64_t tenant_id, const share::ObLSID &ls_id, common::ObAddr &leader_addr); static int check_tablet_replica_validity(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObAddr &addr, const common::ObTabletID &tablet_id, common::ObISQLClient &sql_client); + static int report_ls_meta_table(const uint64_t tenant_id, const share::ObLSID &ls_id, + const storage::ObMigrationStatus &migration_status); static int get_server_version(uint64_t &server_version); static int check_server_version(const uint64_t server_version); + static int check_ls_deleted( + const share::ObLSID &ls_id, + bool &is_deleted); private: static int check_merge_error_(const uint64_t tenant_id, common::ObISQLClient &sql_client); @@ -40,6 +47,15 @@ private: const share::ObLSID &ls_id, const share::SCN &compaction_scn, common::ObISQLClient &sql_client); }; +struct ObTransferUtils +{ + static bool is_need_retry_error(const int err); + static int block_tx(const uint64_t tenant_id, const share::ObLSID &ls_id); + static int kill_tx(const uint64_t tenant_id, const share::ObLSID &ls_id); + static int unblock_tx(const uint64_t tenant_id, const share::ObLSID &ls_id); + static int get_gts(const uint64_t tenant_id, share::SCN >s); +}; + } // end namespace storage } // end namespace oceanbase diff --git a/src/storage/high_availability/ob_storage_restore_struct.cpp b/src/storage/high_availability/ob_storage_restore_struct.cpp index 2e6a3cf1f..521d4401d 100644 --- a/src/storage/high_availability/ob_storage_restore_struct.cpp +++ b/src/storage/high_availability/ob_storage_restore_struct.cpp @@ -13,7 +13,7 @@ #define USING_LOG_PREFIX STORAGE #include "ob_storage_restore_struct.h" #include "storage/restore/ob_ls_restore_args.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" #include "storage/blocksstable/ob_logic_macro_id.h" namespace oceanbase { @@ -416,7 +416,6 @@ ObRestoreMacroBlockIdMgr::~ObRestoreMacroBlockIdMgr() } int ObRestoreMacroBlockIdMgr::init( - const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const ObITable::TableKey &table_key, const ObRestoreBaseInfo &restore_base_info, @@ -427,12 +426,12 @@ int ObRestoreMacroBlockIdMgr::init( if (is_inited_) { ret = OB_INIT_TWICE; LOG_WARN("restore macro block id mgr init tiwce", K(ret)); - } else if (!ls_id.is_valid() || !tablet_id.is_valid() || !table_key.is_valid() || !restore_base_info.is_valid()) { + } else if (!tablet_id.is_valid() || !table_key.is_valid() || !restore_base_info.is_valid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("restore macro block id mgr init get invalid argument", K(ret), K(ls_id), K(tablet_id), + LOG_WARN("restore macro block id mgr init get invalid argument", K(ret), K(tablet_id), K(table_key), K(restore_base_info)); - } else if (OB_FAIL(inner_init_(ls_id, tablet_id, table_key, restore_base_info, second_meta_index_store))) { - LOG_WARN("failed to inner init restore macro block id mar", K(ret), K(ls_id), K(tablet_id), K(table_key)); + } else if (OB_FAIL(inner_init_(tablet_id, table_key, restore_base_info, second_meta_index_store))) { + LOG_WARN("failed to inner init restore macro block id mar", K(ret), K(tablet_id), K(table_key)); } else { table_key_ = table_key; is_inited_ = true; @@ -441,7 +440,6 @@ int ObRestoreMacroBlockIdMgr::init( } int ObRestoreMacroBlockIdMgr::inner_init_( - const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const ObITable::TableKey &table_key, const ObRestoreBaseInfo &restore_base_info, @@ -459,15 +457,15 @@ int ObRestoreMacroBlockIdMgr::inner_init_( if (OB_FAIL(ObRestoreUtils::get_backup_data_type(table_key, data_type))) { LOG_WARN("failed to get backup data type", K(ret), K(table_key)); } else if (OB_FAIL(second_meta_index_store.get_backup_meta_index(data_type, tablet_id, meta_type, meta_index))) { - LOG_WARN("failed to get backup meta index", K(ret), K(ls_id), K(tablet_id), K(table_key), K(meta_type)); + LOG_WARN("failed to get backup meta index", K(ret), K(tablet_id), K(table_key), K(meta_type)); } else { SMART_VARS_2((share::ObBackupPath, backup_path), (backup::ObBackupMacroBlockIDMappingsMeta, macro_block_id_map)) { if (OB_FAIL(share::ObBackupPathUtil::get_macro_block_backup_path(restore_base_info.backup_dest_, - ls_id, data_type, meta_index.turn_id_, meta_index.retry_id_, meta_index.file_id_, backup_path))) { - LOG_WARN("failed to get macro block index", K(ret), K(table_key), K(ls_id), K(tablet_id), K(restore_base_info)); + meta_index.ls_id_, data_type, meta_index.turn_id_, meta_index.retry_id_, meta_index.file_id_, backup_path))) { + LOG_WARN("failed to get macro block index", K(ret), K(table_key), K(tablet_id), K(restore_base_info), K(meta_index)); } else if (OB_FAIL(backup::ObLSBackupRestoreUtil::read_macro_block_id_mapping_metas(backup_path.get_obstr(), restore_base_info.backup_dest_.get_storage_info(), meta_index, macro_block_id_map))) { - LOG_WARN("failed to read macro block data", K(ret), K(table_key), K(ls_id), K(tablet_id), K(restore_base_info)); + LOG_WARN("failed to read macro block data", K(ret), K(table_key), K(tablet_id), K(restore_base_info)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < macro_block_id_map.sstable_count_; ++i) { const backup::ObBackupMacroBlockIDMapping &id_mapping = macro_block_id_map.id_map_list_[i]; @@ -480,7 +478,7 @@ int ObRestoreMacroBlockIdMgr::inner_init_( if (OB_FAIL(block_id_array_.push_back(block_id))) { LOG_WARN("failed to push block id into array", K(ret), K(block_id)); } else { - LOG_DEBUG("push back block id", K(ls_id), K(tablet_id), K(table_key), K(pair), K(block_id)); + LOG_DEBUG("push back block id", K(tablet_id), K(table_key), K(pair), K(block_id)); } } diff --git a/src/storage/high_availability/ob_storage_restore_struct.h b/src/storage/high_availability/ob_storage_restore_struct.h index 95ab55c19..d44b5506a 100644 --- a/src/storage/high_availability/ob_storage_restore_struct.h +++ b/src/storage/high_availability/ob_storage_restore_struct.h @@ -174,7 +174,6 @@ public: ObRestoreMacroBlockIdMgr(); virtual ~ObRestoreMacroBlockIdMgr(); int init( - const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const ObITable::TableKey &table_key, const ObRestoreBaseInfo &restore_base_info, @@ -191,7 +190,6 @@ public: private: int inner_init_( - const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const ObITable::TableKey &table_key, const ObRestoreBaseInfo &restore_base_info, diff --git a/src/storage/high_availability/ob_tablet_backfill_tx.cpp b/src/storage/high_availability/ob_tablet_backfill_tx.cpp index a1b5acfe4..00fb8a20e 100644 --- a/src/storage/high_availability/ob_tablet_backfill_tx.cpp +++ b/src/storage/high_availability/ob_tablet_backfill_tx.cpp @@ -14,6 +14,7 @@ #include "ob_tablet_backfill_tx.h" #include "observer/ob_server.h" #include "share/rc/ob_tenant_base.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "storage/ob_storage_struct.h" #include "storage/tablet/ob_tablet_iterator.h" #include "storage/tablet/ob_tablet.h" @@ -182,7 +183,7 @@ int64_t ObBackfillTXCtx::hash() const /******************ObTabletBackfillTXDag*********************/ ObTabletBackfillTXDag::ObTabletBackfillTXDag() - : ObStorageHADag(ObDagType::DAG_TYPE_BACKFILL_TX, ObStorageHADagType::TABLET_BACKFILL_TX_DAG), + : ObStorageHADag(ObDagType::DAG_TYPE_TABLET_BACKFILL_TX), is_inited_(false), dag_net_id_(), ls_id_(), @@ -196,20 +197,16 @@ ObTabletBackfillTXDag::~ObTabletBackfillTXDag() { } -int ObTabletBackfillTXDag::fill_comment(char *buf, const int64_t buf_len) const +int ObTabletBackfillTXDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; - int64_t pos = 0; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet backfill tx dag do not init", K(ret)); - } else if (NULL == buf || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid args", K(ret), KP(buf), K(buf_len)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, pos, "tablet backfill tx : dag_net_id = %s, " - "ls_id = %s, tablet_id = %s", - to_cstring(dag_net_id_), to_cstring(ls_id_), to_cstring(tablet_id_)))) { - LOG_WARN("failed to set comment", K(ret), K(buf), K(pos), K(buf_len)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + ls_id_.id(), static_cast(tablet_id_.id()), + "dag_net_id", to_cstring(dag_net_id_)))){ + LOG_WARN("failed to fill info param", K(ret)); } return ret; } @@ -236,17 +233,13 @@ bool ObTabletBackfillTXDag::operator == (const ObIDag &other) const } else if (get_type() != other.get_type()) { is_same = false; } else { - const ObStorageHADag &ha_dag = static_cast(other); - if (ha_dag.get_sub_type() != sub_type_) { + const ObTabletBackfillTXDag &tablet_backfill_tx_dag = static_cast(other); + if (tablet_backfill_tx_dag.ls_id_ != ls_id_ || tablet_backfill_tx_dag.tablet_id_ != tablet_id_) { is_same = false; } else { - const ObTabletBackfillTXDag &tablet_backfill_tx_dag = static_cast(other); - if (tablet_backfill_tx_dag.ls_id_ != ls_id_ || tablet_backfill_tx_dag.tablet_id_ != tablet_id_) { - is_same = false; - } else { - is_same = true; - } + is_same = true; } + } return is_same; } @@ -263,8 +256,9 @@ int64_t ObTabletBackfillTXDag::hash() const &ls_id_, sizeof(ls_id_), hash_value); hash_value = common::murmurhash( &tablet_id_, sizeof(tablet_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } @@ -297,7 +291,7 @@ int ObTabletBackfillTXDag::init( } else if (OB_ISNULL(ls = ls_handle.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); - } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle_, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle_))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); } else { dag_net_id_ = dag_net_id; @@ -380,7 +374,7 @@ int ObTabletBackfillTXDag::generate_next_dag(share::ObIDag *&dag) if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; const bool need_retry = false; - if (need_set_failed_result && OB_SUCCESS != (tmp_ret = ha_dag_net_ctx_->set_result(ret, need_retry))) { + if (need_set_failed_result && OB_SUCCESS != (tmp_ret = ha_dag_net_ctx_->set_result(ret, need_retry, get_type()))) { LOG_WARN("failed to set result", K(ret), KPC(ha_dag_net_ctx_), K(ls_id_), K(tablet_id_)); } } @@ -478,7 +472,7 @@ int ObTabletBackfillTXTask::generate_backfill_tx_task_() ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; ObFinishTabletBackfillTXTask *finish_backfill_tx_task = nullptr; - ObArray minor_tables; + ObArray table_array; if (!is_inited_) { ret = OB_NOT_INIT; @@ -493,9 +487,9 @@ int ObTabletBackfillTXTask::generate_backfill_tx_task_() } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); - } else if (OB_FAIL(tablet->get_table_store().get_minor_sstables().get_all_tables(minor_tables))) { - LOG_WARN("failed to get minor tables", K(ret), KPC(ha_dag_net_ctx_), K(ls_id_), K(tablet_id_)); - } else if (OB_FAIL(generate_table_backfill_tx_task_(finish_backfill_tx_task, minor_tables))) { + } else if (OB_FAIL(get_all_backfill_tx_tables_(tablet, table_array))) { + LOG_WARN("get all backfill tx tabels", K(ret), KPC(tablet)); + } else if (OB_FAIL(generate_table_backfill_tx_task_(finish_backfill_tx_task, table_array))) { LOG_WARN("failed to generate minor sstables backfill tx task", K(ret), K(ls_id_), K(tablet_id_)); } else if (OB_FAIL(dag_->add_task(*finish_backfill_tx_task))) { LOG_WARN("failed to add copy task to dag", K(ret)); @@ -503,14 +497,181 @@ int ObTabletBackfillTXTask::generate_backfill_tx_task_() return ret; } +int ObTabletBackfillTXTask::get_all_backfill_tx_tables_( + ObTablet *tablet, + common::ObIArray &table_array) +{ + int ret = OB_SUCCESS; + table_array.reset(); + ObArray minor_sstables; + ObArray memtables; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet backfill tx task do not init", K(ret)); + } else if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get all backfll tx tables get invalid argument", K(ret), KP(tablet)); + } else if (OB_FAIL(get_backfill_tx_minor_sstables_(tablet, minor_sstables))) { + LOG_WARN("failed to get backfill tx minor sstables", K(ret), KPC(tablet)); + } else if (OB_FAIL(get_backfill_tx_memtables_(tablet, memtables))) { + LOG_WARN("failed to get backfill tx memtables", K(ret), KPC(tablet)); + } else if (0 != memtables.count()) { + // The dump of the memtable needs to start with a smaller start_scn + if (OB_FAIL(append(table_array, memtables))) { + LOG_WARN("failed to append memtables", K(ret), KPC(tablet), K(memtables)); + } + } else { + // The backfill of sstable needs to start with a larger start_scn + if (OB_FAIL(ObTableStoreUtil::reverse_sort_minor_table_handles(minor_sstables))) { + LOG_WARN("failed to sort minor tables", K(ret)); + } else if (OB_FAIL(append(table_array, minor_sstables))) { + LOG_WARN("failed to append minor sstables", K(ret), KPC(tablet), K(minor_sstables)); + } + } + return ret; +} + +int ObTabletBackfillTXTask::get_backfill_tx_memtables_( + ObTablet *tablet, + common::ObIArray &table_array) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObArray memtables; + const int64_t OB_CHECK_MEMTABLE_INTERVAL = 200 * 1000; // 200ms + const int64_t OB_WAIT_MEMTABLE_READY_TIMEOUT = 30 * 60 * 1000 * 1000L; // 30 min + table_array.reset(); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet backfill tx task do not init", K(ret)); + } else if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get backfll tx memtables get invalid argument", K(ret), KP(tablet)); + } else if (OB_FAIL(ObStorageHADagUtils::get_ls(ls_id_, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id_), KPC(tablet)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), K(ls_id_)); + } else { + const int64_t wait_memtable_start_ts = ObTimeUtility::current_time(); + int64_t current_ts = 0; + while (OB_SUCC(ret)) { + memtables.reset(); + table_array.reset(); + bool is_memtable_ready = true; + ObIMemtableMgr *memtable_mgr = nullptr; + if (OB_ISNULL(memtable_mgr = tablet->get_memtable_mgr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable mgr should not be NULL", K(ret), KP(memtable_mgr)); + } else if (OB_FAIL(memtable_mgr->get_all_memtables(memtables))) { + LOG_WARN("failed to get all memtables", K(ret), KPC(tablet)); + } else if (memtables.empty()) { + break; + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < memtables.count(); ++i) { + ObITable *table = memtables.at(i).get_table(); + memtable::ObMemtable *memtable = static_cast(table); + if (OB_ISNULL(table) || !table->is_memtable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table should not be NULL or table type is unexpected", K(ret), KP(table)); + } else if (table->get_start_scn() >= backfill_tx_ctx_->log_sync_scn_ + && memtable->not_empty() + && !memtable->get_rec_scn().is_max()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable start log ts is bigger than log sync scn but not empty", K(ret), KPC(memtable), KPC_(backfill_tx_ctx)); + } else if (!table->is_frozen_memtable()) { + is_memtable_ready = false; + if (OB_FAIL(ls->tablet_freeze(tablet_id_))) { + if (OB_EAGAIN == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to force tablet freeze", K(ret), K(tablet_id_), KPC(table)); + } + } else { + break; + } + } else if (!memtable->is_can_flush()) { + is_memtable_ready = false; + } else if (table->get_start_scn() >= backfill_tx_ctx_->log_sync_scn_ && table->get_scn_range().is_empty()) { + // do nothing + } else if (OB_FAIL(table_array.push_back(memtables.at(i)))) { + LOG_WARN("failed to push table into array", K(ret), KPC(table)); + } + } + + if (OB_SUCC(ret)) { + if (is_memtable_ready) { + break; + } else { + const int64_t current_ts = ObTimeUtility::current_time(); + if (REACH_TENANT_TIME_INTERVAL(60 * 1000 * 1000)) { + LOG_INFO("tablet not ready, retry next loop", "tablet_id", tablet_id_, + "wait_tablet_start_ts", wait_memtable_start_ts, + "current_ts", current_ts); + } + + if (current_ts - wait_memtable_start_ts < OB_WAIT_MEMTABLE_READY_TIMEOUT) { + } else { + ret = OB_TIMEOUT; + STORAGE_LOG(WARN, "failed to check tablet memtable ready, timeout, stop backfill", + K(ret), KPC(tablet), K(current_ts), + K(wait_memtable_start_ts)); + } + + if (OB_SUCC(ret)) { + ob_usleep(OB_CHECK_MEMTABLE_INTERVAL); + } + } + } + } + } + } + return ret; +} + +int ObTabletBackfillTXTask::get_backfill_tx_minor_sstables_( + ObTablet *tablet, + common::ObIArray &minor_sstables) +{ + int ret = OB_SUCCESS; + ObTableStoreIterator minor_table_iter; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet backfill tx task do not init", K(ret)); + } else if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get backfll tx memtables get invalid argument", K(ret), KP(tablet)); + } else if (OB_FAIL(tablet->get_mini_minor_sstables(minor_table_iter))) { + LOG_WARN("failed to get mini minor sstables", K(ret)); + } else { + while (OB_SUCC(ret)) { + ObTableHandleV2 table_handle; + if (OB_FAIL(minor_table_iter.get_next(table_handle))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next table", K(ret)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(minor_sstables.push_back(table_handle))) { + LOG_WARN("failed to push table handle into array", K(ret), KPC(tablet), K(table_handle)); + } + } + } + return ret; +} + int ObTabletBackfillTXTask::generate_table_backfill_tx_task_( ObFinishTabletBackfillTXTask *finish_backfill_tx_task, - common::ObIArray &table_array) + common::ObIArray &table_array) { int ret = OB_SUCCESS; ObTabletBackfillTXDag *tablet_backfill_tx_dag = nullptr; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); ObTabletHandle tablet_handle; + ObTabletTableBackfillTXTask *pre_table_backfill_task = nullptr; if (!is_inited_) { ret = OB_NOT_INIT; @@ -524,32 +685,53 @@ int ObTabletBackfillTXTask::generate_table_backfill_tx_task_( LOG_WARN("failed to get tablet handler", K(ret), KPC(ha_dag_net_ctx_), K(ls_id_), K(tablet_id_)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < table_array.count(); ++i) { - ObITable *table = table_array.at(i); + ObITable *table = table_array.at(i).get_table(); ObSSTable *sstable = nullptr; + ObSSTableMetaHandle sst_meta_hdl; ObTabletTableBackfillTXTask *table_backfill_tx_task = nullptr; - ObTableHandleV2 table_handle(table, t3m, ObITable::TableType::MAJOR_SSTABLE); - - if (OB_ISNULL(table) || !table->is_minor_sstable() || table->is_remote_logical_minor_sstable()) { + bool is_add_task = false; + if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table should not be NULL or table type is unexpected", K(ret), KPC(table)); + } else if (table->is_data_memtable()) { + is_add_task = true; + } else if (!table->is_minor_sstable() || table->is_remote_logical_minor_sstable()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table should not be NULL or table type is unexpected", K(ret), KPC(table)); } else if (FALSE_IT(sstable = static_cast(table))) { - } else if (!sstable->get_meta().get_basic_meta().contain_uncommitted_row_ - || sstable->get_meta().get_basic_meta().filled_tx_scn_ >= backfill_tx_ctx_->log_sync_scn_) { + } else if (OB_FAIL(sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); + } else if (!sstable->contain_uncommitted_row() + || (!sst_meta_hdl.get_sstable_meta().get_filled_tx_scn().is_max() + && sst_meta_hdl.get_sstable_meta().get_filled_tx_scn() >= backfill_tx_ctx_->log_sync_scn_)) { FLOG_INFO("sstable do not contain uncommitted row, no need backfill tx", KPC(sstable), "log sync scn", backfill_tx_ctx_->log_sync_scn_); - } else if (OB_FAIL(tablet_backfill_tx_dag->alloc_task(table_backfill_tx_task))) { - LOG_WARN("failed to alloc table backfill tx task", K(ret), KPC(ha_dag_net_ctx_), K(ls_id_), K(tablet_id_)); - } else if (OB_FAIL(table_backfill_tx_task->init(ls_id_, tablet_id_, tablet_handle, table_handle))) { - LOG_WARN("failed to init table backfill tx task", K(ret), K(ls_id_), K(tablet_id_)); - } else if (OB_FAIL(this->add_child(*table_backfill_tx_task))) { - LOG_WARN("failed to add table backfill tx task as child", K(ret), K(ls_id_), K(tablet_id_), KPC(table)); - } else if (OB_FAIL(table_backfill_tx_task->add_child(*finish_backfill_tx_task))) { - LOG_WARN("failed to add finish backfill tx task as child", K(ret), K(ls_id_), K(tablet_id_), KPC(table)); - } else if (OB_FAIL(dag_->add_task(*table_backfill_tx_task))) { - LOG_WARN("failed to add table backfill tx task", K(ret), K(ls_id_), K(tablet_id_)); + } else { + is_add_task = true; } - if (OB_SUCC(ret)) { - LOG_INFO("generate table backup fill", KPC(sstable), K(i), "log_sync_scn", backfill_tx_ctx_->log_sync_scn_); + if (OB_SUCC(ret) && is_add_task) { + if (OB_FAIL(tablet_backfill_tx_dag->alloc_task(table_backfill_tx_task))) { + LOG_WARN("failed to alloc table backfill tx task", K(ret), KPC(ha_dag_net_ctx_), K(ls_id_), K(tablet_id_)); + } else if (OB_FAIL(table_backfill_tx_task->init(ls_id_, tablet_id_, tablet_handle, table_array.at(i)))) { + LOG_WARN("failed to init table backfill tx task", K(ret), K(ls_id_), K(tablet_id_)); + } else if (OB_ISNULL(pre_table_backfill_task)) { + if (OB_FAIL(this->add_child(*table_backfill_tx_task))) { + LOG_WARN("failed to add table backfill tx task as child", K(ret), K(ls_id_), K(tablet_id_), KPC(table)); + } + } else { + if (OB_FAIL(pre_table_backfill_task->add_child(*table_backfill_tx_task))) { + LOG_WARN("failed to add table backfill tx task as child", K(ret), K(ls_id_), K(tablet_id_), KPC(table), KPC(pre_table_backfill_task)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(table_backfill_tx_task->add_child(*finish_backfill_tx_task))) { + LOG_WARN("failed to add finish backfill tx task as child", K(ret), K(ls_id_), K(tablet_id_), KPC(table)); + } else if (OB_FAIL(dag_->add_task(*table_backfill_tx_task))) { + LOG_WARN("failed to add table backfill tx task", K(ret), K(ls_id_), K(tablet_id_)); + } else { + pre_table_backfill_task = table_backfill_tx_task; + LOG_INFO("generate table backfill TX", KPC(table), K(i), KPC(table_backfill_tx_task)); + } } } } @@ -614,16 +796,27 @@ int ObTabletTableBackfillTXTask::process() { int ret = OB_SUCCESS; LOG_INFO("start do tablet table backfill tx task", K(ls_id_), K(tablet_id_), K(table_handle_)); + bool need_merge = true; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet table backfill tx task do not init", K(ret)); + } else if (ha_dag_net_ctx_->is_failed()) { + LOG_INFO("ctx already failed", KPC(ha_dag_net_ctx_)); + } else if (OB_FAIL(check_need_merge_(need_merge))) { + LOG_WARN("failed to check need merge", K(ret)); + } else if (!need_merge) { + LOG_INFO("tablet table no need merge", K(ret), K_(tablet_handle)); } else if (OB_FAIL(prepare_merge_ctx_())) { LOG_WARN("failed to prepare merge ctx", K(ret), KPC(this)); } else if (OB_FAIL(tablet_merge_ctx_.prepare_index_tree())) { LOG_WARN("failed to prepare index tree", K(ret), KPC(this)); } else if (OB_FAIL(do_backfill_tx_())) { - LOG_WARN("failed to do backfill tx", K(ret), KPC(this)); + if (OB_NO_NEED_MERGE == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to do backfill tx", K(ret), KPC(this)); + } } if (OB_FAIL(ret)) { @@ -643,7 +836,6 @@ int ObTabletTableBackfillTXTask::prepare_merge_ctx_() { int ret = OB_SUCCESS; ObLSService *ls_service = nullptr; - if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet table backfill tx task do not init", K(ret)); @@ -655,22 +847,23 @@ int ObTabletTableBackfillTXTask::prepare_merge_ctx_() } else { // init tablet merge dag param tablet_merge_ctx_.param_.ls_id_ = ls_id_; - tablet_merge_ctx_.param_.merge_type_ = ObMergeType::BACKFILL_TX_MERGE; + tablet_merge_ctx_.param_.merge_type_ = table_handle_.get_table()->is_memtable() ? ObMergeType::MINI_MERGE : ObMergeType::BACKFILL_TX_MERGE; tablet_merge_ctx_.param_.report_ = nullptr; tablet_merge_ctx_.param_.tablet_id_ = tablet_id_; // init version range and sstable tablet_merge_ctx_.tablet_handle_ = tablet_handle_; tablet_merge_ctx_.sstable_version_range_.multi_version_start_ = tablet_handle_.get_obj()->get_multi_version_start(); - tablet_merge_ctx_.sstable_version_range_.snapshot_version_ = tablet_handle_.get_obj()->get_snapshot_version(); + tablet_merge_ctx_.sstable_version_range_.snapshot_version_ = table_handle_.get_table()->is_memtable() ? + static_cast(table_handle_.get_table())->get_snapshot_version() : tablet_handle_.get_obj()->get_snapshot_version(); tablet_merge_ctx_.scn_range_ = table_handle_.get_table()->get_key().scn_range_; - tablet_merge_ctx_.merge_scn_ = backfill_tx_ctx_->log_sync_scn_; + // TODO(wenjinyu.wjy) waiting to kill transaction + tablet_merge_ctx_.merge_scn_ = table_handle_.get_table()->is_memtable() ? table_handle_.get_table()->get_key().scn_range_.end_scn_ : backfill_tx_ctx_->log_sync_scn_; tablet_merge_ctx_.create_snapshot_version_ = 0; tablet_merge_ctx_.schedule_major_ = false; if (OB_FAIL(tablet_merge_ctx_.tables_handle_.add_table(table_handle_))) { LOG_WARN("failed to add table into tables handle", K(ret), K(table_handle_)); - } else if (OB_FAIL(tablet_merge_ctx_.get_storage_schema_to_merge(tablet_merge_ctx_.tables_handle_, - true/*get_schema_on_memtable*/))) { + } else if (OB_FAIL(tablet_merge_ctx_.get_storage_schema_to_merge(tablet_merge_ctx_.tables_handle_))) { LOG_ERROR("Fail to get storage schema", K(ret), K(tablet_merge_ctx_)); } else { //get_basic_info_from_result result @@ -687,6 +880,21 @@ int ObTabletTableBackfillTXTask::prepare_merge_ctx_() return ret; } +int ObTabletTableBackfillTXTask::check_need_merge_(bool &need_merge) +{ + int ret = OB_SUCCESS; + need_merge = true; + if (!table_handle_.get_table()->is_memtable()) { + // do nothing + } else if (!table_handle_.get_table()->get_key().scn_range_.is_empty()) { + // do nothing + } else { + need_merge = false; + } + return ret; +} + +// TODO(muwei.ym) Reuse a set of logic with the existing dump process, do not directly call the merge_partition interface in 4.3 int ObTabletTableBackfillTXTask::do_backfill_tx_() { int ret = OB_SUCCESS; @@ -702,7 +910,7 @@ int ObTabletTableBackfillTXTask::do_backfill_tx_() } else if (OB_FAIL(update_merge_sstable_())) { LOG_WARN("failed to update merge sstable", K(ret), K(tablet_merge_ctx_)); } else { - FLOG_INFO("merge backfill tx task finish", "task", *this); + FLOG_INFO("merge backfill tx task finish", "task", *this, K(table_handle_), K(tablet_merge_ctx_)); } if (OB_NOT_NULL(merger_)) { @@ -731,7 +939,6 @@ int ObTabletTableBackfillTXTask::update_merge_sstable_() { int ret = OB_SUCCESS; ObLS *ls = nullptr; - if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet table backfill tx task do not init", K(ret)); @@ -741,17 +948,88 @@ int ObTabletTableBackfillTXTask::update_merge_sstable_() } else if (OB_FAIL(tablet_merge_ctx_.merge_info_.create_sstable(tablet_merge_ctx_))) { LOG_WARN("fail to create sstable", K(ret), K(tablet_merge_ctx_)); } else { + ObTabletHandle new_tablet_handle; const int64_t rebuild_seq = ls->get_rebuild_seq(); - ObUpdateTableStoreParam param(tablet_merge_ctx_.merged_table_handle_, + ObUpdateTableStoreParam param(&(tablet_merge_ctx_.merged_sstable_), tablet_merge_ctx_.sstable_version_range_.snapshot_version_, tablet_merge_ctx_.sstable_version_range_.multi_version_start_, tablet_merge_ctx_.schema_ctx_.storage_schema_, rebuild_seq, - is_major_merge_type(tablet_merge_ctx_.param_.merge_type_)); - ObTabletHandle new_tablet_handle; - if (OB_FAIL(ls->update_tablet_table_store( + is_major_merge_type(tablet_merge_ctx_.param_.merge_type_), + tablet_merge_ctx_.merged_sstable_.get_end_scn()); + + if (ObMergeType::MINI_MERGE == tablet_merge_ctx_.param_.merge_type_ ) { + if (OB_FAIL(read_msd_from_memtable_(param))) { + LOG_WARN("failed to read msd from memtable", K(ret), K(tablet_merge_ctx_)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ls->update_tablet_table_store( tablet_id_, param, new_tablet_handle))) { LOG_WARN("failed to update tablet table store", K(ret), K(param)); + } else if (is_mini_merge(tablet_merge_ctx_.param_.merge_type_)) { + if (OB_FAIL(new_tablet_handle.get_obj()->release_memtables(tablet_merge_ctx_.scn_range_.end_scn_))) { + LOG_WARN("failed to release memtable", K(ret), "end_scn", tablet_merge_ctx_.scn_range_.end_scn_); + } + } + } + return ret; +} + + +int ObTabletTableBackfillTXTask::read_msd_from_memtable_(ObUpdateTableStoreParam ¶m) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(traverse_frozen_memtable_(memtable::MultiSourceDataUnitType::TABLET_TX_DATA, ¶m.tx_data_))) { + LOG_WARN("failed to read tx data from memtable", K(ret)); + } else if (OB_FAIL(traverse_frozen_memtable_(memtable::MultiSourceDataUnitType::TABLET_BINDING_INFO, ¶m.binding_info_))) { + LOG_WARN("failed to read binding info from memtable", K(ret)); + } else if (OB_FAIL(traverse_frozen_memtable_(memtable::MultiSourceDataUnitType::TABLET_SEQ, ¶m.autoinc_seq_))) { + LOG_WARN("failed to read tablet seq from memtable", K(ret)); + } else { + LOG_INFO("succeeded to read msd from memtable", K(ret), + "ls_id", tablet_merge_ctx_.param_.ls_id_, + "tablet_id", tablet_merge_ctx_.param_.tablet_id_, + "tx_data", param.tx_data_, + "binding_info", param.binding_info_, + "auto_inc_seq", param.autoinc_seq_); + } + return ret; +} + +int ObTabletTableBackfillTXTask::traverse_frozen_memtable_( + const memtable::MultiSourceDataUnitType &type, + memtable::ObIMultiSourceDataUnit *msd) +{ + int ret = OB_SUCCESS; + ObITable *table = nullptr; + memtable::ObMemtable *memtable = nullptr; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet table backfill tx task do not init", K(ret)); + } else if (OB_ISNULL(msd)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret)); + } else if (!table_handle_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet handle is invalid", K(ret), K(tablet_merge_ctx_), K(table_handle_)); + } else if (OB_ISNULL(table = table_handle_.get_table())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table should not be NULL or table type is unexpected", K(ret), K(tablet_merge_ctx_)); + } else if (table->is_data_memtable()) { + memtable = static_cast(table); + if (!memtable->is_frozen_memtable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable should be frozen memtable", K(ret), KPC(memtable)); + } else if (memtable->has_multi_source_data_unit(type)) { + if (OB_FAIL(memtable->get_multi_source_data_unit(msd, nullptr/*allocator*/))) { + LOG_WARN("failed to get msd from memtable", K(ret), K(type)); + } + } else { + LOG_INFO("memtable do not has multi source data unit", KPC(memtable), K(type)); } } return ret; @@ -801,7 +1079,7 @@ int ObFinishTabletBackfillTXTask::process() ret = OB_NOT_INIT; LOG_WARN("finish tablet backfill tx task do not init", K(ret)); } else if (ha_dag_net_ctx_->is_failed()) { - //do nothing + LOG_INFO("ctx already failed", KPC(ha_dag_net_ctx_)); } else { } @@ -820,8 +1098,7 @@ int ObFinishTabletBackfillTXTask::process() /******************ObFinishBackfillTXDag*********************/ ObFinishBackfillTXDag::ObFinishBackfillTXDag() - : ObStorageHADag( - ObDagType::DAG_TYPE_BACKFILL_TX, ObStorageHADagType::FINISH_BACKFILL_TX_DAG), + : ObStorageHADag(ObDagType::DAG_TYPE_FINISH_BACKFILL_TX), is_inited_(false), backfill_tx_ctx_() { @@ -831,19 +1108,16 @@ ObFinishBackfillTXDag::~ObFinishBackfillTXDag() { } -int ObFinishBackfillTXDag::fill_comment(char *buf, const int64_t buf_len) const +int ObFinishBackfillTXDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; - int64_t pos = 0; if (!is_inited_) { ret = OB_NOT_INIT; - LOG_WARN("finish backfill tx dag do not init", K(ret)); - } else if (NULL == buf || buf_len <= 0) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid args", K(ret), KP(buf), K(buf_len)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, pos, "finish backfill tx : dag_net_id = %s, ls_id = %s", - to_cstring(backfill_tx_ctx_.task_id_), to_cstring(backfill_tx_ctx_.ls_id_)))) { - LOG_WARN("failed to set comment", K(ret), K(buf), K(pos), K(buf_len)); + LOG_WARN("tablet backfill tx dag do not init", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + backfill_tx_ctx_.ls_id_.id(), + "dag_net_id", to_cstring(backfill_tx_ctx_.task_id_)))) { + LOG_WARN("failed to fill info param", K(ret)); } return ret; } @@ -870,14 +1144,9 @@ bool ObFinishBackfillTXDag::operator == (const ObIDag &other) const } else if (get_type() != other.get_type()) { is_same = false; } else { - const ObStorageHADag &ha_dag = static_cast(other); - if (ha_dag.get_sub_type() != sub_type_) { - is_same = false; - } else { - const ObFinishBackfillTXDag &finish_backfill_tx_dag = static_cast(other); - if (OB_FAIL(backfill_tx_ctx_.check_is_same(finish_backfill_tx_dag.backfill_tx_ctx_, is_same))) { - LOG_WARN("failed to check is same", K(ret), K(*this)); - } + const ObFinishBackfillTXDag &finish_backfill_tx_dag = static_cast(other); + if (OB_FAIL(backfill_tx_ctx_.check_is_same(finish_backfill_tx_dag.backfill_tx_ctx_, is_same))) { + LOG_WARN("failed to check is same", K(ret), K(*this)); } } return is_same; @@ -892,8 +1161,9 @@ int64_t ObFinishBackfillTXDag::hash() const LOG_WARN("tablet backfill tx dag do not init", K(ret)); } else { hash_value += backfill_tx_ctx_.hash(); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); } return hash_value; } @@ -901,7 +1171,8 @@ int64_t ObFinishBackfillTXDag::hash() const int ObFinishBackfillTXDag::init( const share::ObTaskId &task_id, const share::ObLSID &ls_id, - const SCN log_sync_scn, + const SCN &log_sync_scn, + ObArray &tablet_id_array, ObIHADagNetCtx *ha_dag_net_ctx) { int ret = OB_SUCCESS; @@ -912,8 +1183,8 @@ int ObFinishBackfillTXDag::init( } else if (task_id.is_invalid() || !ls_id.is_valid() || !log_sync_scn.is_valid() || OB_ISNULL(ha_dag_net_ctx)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("init finish backfill tx dag get invalid argument", K(ret), K(task_id), K(ls_id), K(log_sync_scn) ,KP(ha_dag_net_ctx)); - } else if (OB_FAIL(prepare_backfill_tx_ctx_(task_id, ls_id, log_sync_scn))) { - LOG_WARN("failed to prepare backfill tx ctx", K(ret), K(task_id), K(ls_id)); + } else if (OB_FAIL(backfill_tx_ctx_.build_backfill_tx_ctx(task_id, ls_id, log_sync_scn, tablet_id_array))) { + LOG_WARN("failed to build backfill tx ctx", K(ret), K(tablet_id_array)); } else { ha_dag_net_ctx_ = ha_dag_net_ctx; is_inited_ = true; @@ -921,58 +1192,6 @@ int ObFinishBackfillTXDag::init( return ret; } -int ObFinishBackfillTXDag::prepare_backfill_tx_ctx_( - const share::ObTaskId &task_id, - const share::ObLSID &ls_id, - const SCN log_sync_scn) -{ - int ret = OB_SUCCESS; - ObLS *ls = nullptr; - ObLSTabletIterator tablet_iter; - ObArray tablet_id_array; - ObLSService *ls_service = nullptr; - ObLSHandle ls_handle; - if (OB_ISNULL(ls_service = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); - } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::HA_MOD))) { - LOG_WARN("failed to get ls", K(ret), K(ls_id)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); - } else if (OB_FAIL(ls->build_tablet_iter(tablet_iter))) { - LOG_WARN("failed to build ls tablet iter", K(ret)); - } else { - ObTabletHandle tablet_handle; - ObTablet *tablet = nullptr; - while (OB_SUCC(ret)) { - tablet_handle.reset(); - tablet = nullptr; - if (OB_FAIL(tablet_iter.get_next_tablet(tablet_handle))) { - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - break; - } else { - LOG_WARN("failed to get tablet", K(ret), K(ls_id)); - } - } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); - } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { - //do nothing - } else if (OB_FAIL(tablet_id_array.push_back(tablet->get_tablet_meta().tablet_id_))) { - LOG_WARN("failed to push tablet id into array", K(ret), KPC(tablet), K(ls_id)); - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(backfill_tx_ctx_.build_backfill_tx_ctx(task_id, ls_id, log_sync_scn, tablet_id_array))) { - LOG_WARN("failed to build backfill tx ctx", K(ret), K(tablet_id_array)); - } - } - return ret; -} - int ObFinishBackfillTXDag::create_first_task() { int ret = OB_SUCCESS; @@ -1034,9 +1253,9 @@ int ObFinishBackfillTXTask::process() ret = OB_NOT_INIT; LOG_WARN("finish backfill tx migration task do not init", K(ret)); } else if (ha_dag_net_ctx_->is_failed()) { - //do nothing + LOG_INFO("ctx already failed", KPC(ha_dag_net_ctx_)); } else { - //TODO(muwei.ym) FIX IT later ObFinishBackfillTXTask::process + //TODO(muwei.ym) FIX IT later ObFinishBackfillTXTask::process in 4.3 } if (OB_FAIL(ret)) { diff --git a/src/storage/high_availability/ob_tablet_backfill_tx.h b/src/storage/high_availability/ob_tablet_backfill_tx.h index da9ba2ba6..c442407e7 100644 --- a/src/storage/high_availability/ob_tablet_backfill_tx.h +++ b/src/storage/high_availability/ob_tablet_backfill_tx.h @@ -19,6 +19,7 @@ #include "storage/tx_storage/ob_ls_service.h" #include "ob_storage_ha_dag.h" #include "storage/compaction/ob_tablet_merge_ctx.h" +#include "storage/memtable/ob_multi_source_data.h" namespace oceanbase { @@ -69,7 +70,7 @@ class ObTabletBackfillTXDag : public ObStorageHADag public: ObTabletBackfillTXDag(); virtual ~ObTabletBackfillTXDag(); - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; virtual bool operator == (const share::ObIDag &other) const override; @@ -106,13 +107,21 @@ public: const share::ObLSID &ls_id, const common::ObTabletID &tablet_id); virtual int process() override; - VIRTUAL_TO_STRING_KV(K("ObTabletBackfillTXTask"), KP(this), KPC(ha_dag_net_ctx_)); + VIRTUAL_TO_STRING_KV(K("ObTabletBackfillTXTask"), KP(this), KPC(ha_dag_net_ctx_), K_(tablet_id)); private: int generate_backfill_tx_task_(); int generate_table_backfill_tx_task_( ObFinishTabletBackfillTXTask *finish_tablet_backfill_tx_task, - common::ObIArray &table_array); - + common::ObIArray &table_array); + int get_backfill_tx_memtables_( + ObTablet *tablet, + common::ObIArray &table_array); + int get_backfill_tx_minor_sstables_( + ObTablet *tablet, + common::ObIArray &minor_sstables); + int get_all_backfill_tx_tables_( + ObTablet *tablet, + common::ObIArray &table_array); private: bool is_inited_; ObBackfillTXCtx *backfill_tx_ctx_; @@ -136,9 +145,14 @@ public: VIRTUAL_TO_STRING_KV(K("ObTabletBackfillTXTask"), KP(this), KPC(ha_dag_net_ctx_)); private: int prepare_merge_ctx_(); + int check_need_merge_(bool &need_merge); int do_backfill_tx_(); int prepare_partition_merge_(); int update_merge_sstable_(); + int read_msd_from_memtable_(ObUpdateTableStoreParam ¶m); + int traverse_frozen_memtable_( + const memtable::MultiSourceDataUnitType &type, + memtable::ObIMultiSourceDataUnit *msd); private: bool is_inited_; @@ -179,7 +193,7 @@ class ObFinishBackfillTXDag : public ObStorageHADag public: ObFinishBackfillTXDag(); virtual ~ObFinishBackfillTXDag(); - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual bool operator == (const share::ObIDag &other) const override; virtual int64_t hash() const override; @@ -188,15 +202,11 @@ public: int init( const share::ObTaskId &task_id, const share::ObLSID &ls_id, - const share::SCN log_sync_scn, + const share::SCN &log_sync_scn, + ObArray &tablet_id_array, ObIHADagNetCtx *ha_dag_net_ctx); ObBackfillTXCtx *get_backfill_tx_ctx() { return &backfill_tx_ctx_; } INHERIT_TO_STRING_KV("ObStorageHADag", ObStorageHADag, KP(this)); -protected: - int prepare_backfill_tx_ctx_( - const share::ObTaskId &task_id, - const share::ObLSID &ls_id, - const share::SCN log_sync_scn); protected: bool is_inited_; diff --git a/src/storage/high_availability/ob_tablet_group_restore.cpp b/src/storage/high_availability/ob_tablet_group_restore.cpp index 263b3f2d6..99d6fbe88 100644 --- a/src/storage/high_availability/ob_tablet_group_restore.cpp +++ b/src/storage/high_availability/ob_tablet_group_restore.cpp @@ -15,9 +15,10 @@ #include "observer/ob_server.h" #include "ob_physical_copy_task.h" #include "share/rc/ob_tenant_base.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" #include "storage/tx_storage/ob_ls_service.h" #include "ob_ls_restore.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" #include "observer/ob_server_event_history_table_operator.h" #include "storage/tablet/ob_tablet.h" @@ -253,7 +254,6 @@ int ObTabletGroupRestoreDagNet::init_by_param(const ObIDagInitParam *param) int ret = OB_SUCCESS; const ObTGRDagNetInitParam* init_param = static_cast(param); const int64_t priority = 1; - ObBackupSetDesc backup_set_desc; if (is_inited_) { ret = OB_INIT_TWICE; LOG_WARN("tablet group restore dag net is init twice", K(ret)); @@ -263,9 +263,9 @@ int ObTabletGroupRestoreDagNet::init_by_param(const ObIDagInitParam *param) } else if (init_param->arg_.is_leader_) { const backup::ObBackupRestoreMode mode = backup::ObBackupRestoreMode::RESTORE_MODE; const backup::ObBackupIndexLevel index_level = backup::ObBackupIndexLevel::BACKUP_INDEX_LEVEL_LOG_STREAM; - share::ObExternBackupSetInfoDesc backup_set_file_desc; + storage::ObExternBackupSetInfoDesc backup_set_file_desc; backup::ObBackupIndexStoreParam index_store_param; - share::ObBackupDataStore store; + storage::ObBackupDataStore store; if (OB_FAIL(store.init(init_param->arg_.restore_base_info_.backup_dest_))) { LOG_WARN("fail to init mgr", K(ret)); } else if (OB_FAIL(store.read_backup_set_info(backup_set_file_desc))) { @@ -280,30 +280,22 @@ int ObTabletGroupRestoreDagNet::init_by_param(const ObIDagInitParam *param) index_store_param.is_tenant_level_ = true; index_store_param.backup_data_type_ = data_type; index_store_param.turn_id_ = backup_set_file_desc.backup_set_file_.data_turn_id_; - backup_set_desc.backup_set_id_ = backup_set_file_desc.backup_set_file_.backup_set_id_; - backup_set_desc.backup_type_.type_ = backup_set_file_desc.backup_set_file_.backup_type_.type_; - int64_t retry_id = 0; - ObBackupPath backup_path; - if (OB_FAIL(ObBackupPathUtil::get_ls_backup_dir_path( - init_param->arg_.restore_base_info_.backup_dest_, init_param->arg_.ls_id_, backup_path))) { - LOG_WARN("failed to get ls backup dir path", K(ret), KPC(init_param)); - } else if (OB_FAIL(store.get_max_sys_ls_retry_id(backup_path, init_param->arg_.ls_id_, retry_id))) { - LOG_WARN("failed to get max sys retry id", K(ret), K(backup_path), KPC(init_param)); - } else { - index_store_param.retry_id_ = retry_id; - LOG_INFO("get max sys ls retry id", "arg", init_param->arg_, K(retry_id)); - } + index_store_param.retry_id_ = 0; // unused retry id. } share::ObBackupDest dest; + // if the ls is new created, there are no ls sys tablet index backup. + // because no sys tablet index backup exist, it will failed to init sys tablet index store. + // on the other hand, ls which has sys tablet backup is restore sys tablet finish in restore sys status. + // so it's no need to init sys tablet index store here. if (OB_FAIL(ret)) { } else if (OB_FAIL(meta_index_store_.init(mode, index_store_param, init_param->arg_.restore_base_info_.backup_dest_, - backup_set_desc, false/*is_sec_meta*/, OB_BACKUP_INDEX_CACHE))) { + backup_set_file_desc.backup_set_file_, false/*is_sec_meta*/, false/*not init sys tablet index store*/, OB_BACKUP_INDEX_CACHE))) { LOG_WARN("failed to init meta index store", K(ret), KPC(init_param)); } else if (OB_FAIL(second_meta_index_store_.init(mode, index_store_param, init_param->arg_.restore_base_info_.backup_dest_, - backup_set_desc, true/*is_sec_meta*/, OB_BACKUP_INDEX_CACHE))) { + backup_set_file_desc.backup_set_file_, true/*is_sec_meta*/, false/*not init sys tablet index store*/, OB_BACKUP_INDEX_CACHE))) { LOG_WARN("failed to init macro index store", K(ret), KPC(init_param)); } } @@ -474,6 +466,7 @@ int ObTabletGroupRestoreDagNet::report_result_() { int ret = OB_SUCCESS; int32_t result = OB_SUCCESS; + share::ObTaskId failed_task_id; ObLSService *ls_service = nullptr; ObLS *ls = nullptr; ObLSHandle ls_handle; @@ -493,11 +486,11 @@ int ObTabletGroupRestoreDagNet::report_result_() LOG_WARN("ls should not be NULL", K(ret), KP(ls), KPC(ctx_)); } else if (OB_FAIL(ctx_->get_result(result))) { LOG_WARN("failed to get tablet group restore ctx result", K(ret), KPC(ctx_)); + } else if (OB_FAIL(ctx_->get_first_failed_task_id(failed_task_id))) { + LOG_WARN("failed to get tablet group restore failed task id", K(ret), KPC(ctx_)); } else if (OB_FAIL(ls->get_ls_restore_handler()->handle_execute_over( - ctx_->task_id_, succeed_tablet_array, failed_tablet_array, ctx_->arg_.ls_id_, result))) { + OB_SUCCESS == result ? ctx_->task_id_ : failed_task_id, succeed_tablet_array, failed_tablet_array, ctx_->arg_.ls_id_, result))) { LOG_WARN("failed to handle execute over tablet group restotre", K(ret), KPC(ctx_)); - } else { - //TODO(muwei.ym) : 1.report meta table 2.report scheduler } return ret; } @@ -518,8 +511,8 @@ int ObTabletGroupRestoreDagNet::deal_with_cancel() } /******************ObTabletGroupRestoreDag*********************/ -ObTabletGroupRestoreDag::ObTabletGroupRestoreDag(const ObStorageHADagType sub_type) - : ObStorageHADag(ObDagType::DAG_TYPE_RESTORE, sub_type) +ObTabletGroupRestoreDag::ObTabletGroupRestoreDag(const share::ObDagType::ObDagTypeEnum &dag_type) + : ObStorageHADag(dag_type) { } @@ -553,8 +546,9 @@ int64_t ObTabletGroupRestoreDag::hash() const } else { hash_value = common::murmurhash( &ctx->arg_.ls_id_, sizeof(ctx->arg_.ls_id_), hash_value); + ObDagType::ObDagTypeEnum dag_type = get_type(); hash_value = common::murmurhash( - &sub_type_, sizeof(sub_type_), hash_value); + &dag_type, sizeof(dag_type), hash_value); for (int64_t i = 0; i < ctx->arg_.tablet_id_array_.count(); ++i) { hash_value = common::murmurhash(&ctx->arg_.tablet_id_array_.at(i), sizeof(ctx->arg_.tablet_id_array_.at(i)), hash_value); @@ -563,9 +557,27 @@ int64_t ObTabletGroupRestoreDag::hash() const return hash_value; } +int ObTabletGroupRestoreDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + ObTabletGroupRestoreCtx *ctx = nullptr; + if (OB_ISNULL(ctx = get_ctx())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet group restore ctx should not be NULL", K(ret), KP(ctx)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + ctx->arg_.ls_id_.id(), + static_cast(ctx->arg_.tablet_id_array_.at(0).id()), + static_cast(ctx->arg_.is_leader_), + "dag_net_task_id", to_cstring(ctx->task_id_), + "src", to_cstring(ctx->arg_.src_.get_server())))){ + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} + /******************ObInitialTabletGroupRestoreDag*********************/ ObInitialTabletGroupRestoreDag::ObInitialTabletGroupRestoreDag() - : ObTabletGroupRestoreDag(ObStorageHADagType::INITIAL_TABLET_GROUP_RESTORE_DAG), + : ObTabletGroupRestoreDag(ObDagType::DAG_TYPE_INITIAL_TABLET_GROUP_RESTORE), is_inited_(false) { } @@ -638,26 +650,6 @@ int ObInitialTabletGroupRestoreDag::create_first_task() return ret; } -int ObInitialTabletGroupRestoreDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObTabletGroupRestoreCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("initial tablet group restore restore dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet group restore ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObInitialTabletGroupRestoreDag : dag_net_task_id = %s, ls_id = %s, first_tablet_id = %s, is_leader = %s, src = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->arg_.ls_id_), to_cstring(ctx->arg_.tablet_id_array_.at(0)), - to_cstring(ctx->arg_.is_leader_), to_cstring(ctx->arg_.src_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObInitialTabletGroupRestoreTask*********************/ ObInitialTabletGroupRestoreTask::ObInitialTabletGroupRestoreTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -709,7 +701,6 @@ int ObInitialTabletGroupRestoreTask::init() second_meta_index_store_ = restore_dag_net->get_second_meta_index_store(); if (OB_FAIL(ls_service->get_ls(ctx_->arg_.ls_id_, ls_handle_, ObLSGetMod::HA_MOD))) { - //TODO(muwei.ym) ls may removed, so need check ls is removed status LOG_WARN("failed to get ls", K(ret), KPC(ctx_)); } else { is_inited_ = true; @@ -737,7 +728,7 @@ int ObInitialTabletGroupRestoreTask::process() LOG_WARN("failed to choose src", K(ret), KPC(ctx_)); } else if (OB_FAIL(init_ha_tablets_builder_())) { LOG_WARN("failed to init ha tablets builder", K(ret), KPC(ctx_)); - } else if (OB_FAIL(create_or_update_tablets_())) { + } else if (OB_FAIL(renew_tablets_meta_())) { LOG_WARN("failed to create or update tablets", K(ret), KPC(ctx_)); } else if (ObTabletRestoreAction::is_restore_tablet_meta(ctx_->arg_.action_)) { LOG_INFO("only restore tablet meta, skip generate tablet restore dags", KPC(ctx_)); @@ -779,8 +770,9 @@ int ObInitialTabletGroupRestoreTask::check_local_ls_restore_status_() } else { if (OB_FAIL(ls->get_restore_status(ls_restore_status))) { LOG_WARN("failed to get restore status", K(ret), KPC(ctx_)); - } else if (!ls_restore_status.is_restore_tablets_meta() && !ls_restore_status.is_quick_restore() - && !ls_restore_status.is_restore_major_data()) { + } else if (!ls_restore_status.is_restore_tablets_meta() + && !ls_restore_status.is_quick_restore() + && !ls_restore_status.is_restore_major_data()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls restore status is unexpected", K(ret), K(ls_restore_status), KPC(ctx_)); } @@ -796,7 +788,7 @@ int ObInitialTabletGroupRestoreTask::check_local_tablets_restore_status_() ObTablet *tablet = nullptr; ObTabletRestoreStatus::STATUS action_restore_status = ObTabletRestoreStatus::RESTORE_STATUS_MAX; ObTabletRestoreStatus::STATUS tablet_restore_status = ObTabletRestoreStatus::RESTORE_STATUS_MAX; - const int64_t timeout_us = ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US; + const ObMDSGetTabletMode timeout_us = ObMDSGetTabletMode::READ_WITHOUT_CHECK; ObInitialTabletGroupRestoreDag *dag = nullptr; if (!is_inited_) { @@ -817,8 +809,12 @@ int ObInitialTabletGroupRestoreTask::check_local_tablets_restore_status_() for (int64_t i = 0; OB_SUCC(ret) && i < ctx_->arg_.tablet_id_array_.count(); ++i) { const ObTabletID &tablet_id = ctx_->arg_.tablet_id_array_.at(i); ObTabletHandle tablet_handle; - if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, timeout_us))) { + if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle)) + && OB_TABLET_NOT_EXIST != ret) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id), KPC(ctx_), K(timeout_us)); + } else if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_WARN("tablet not exist, skip restore", K(tablet_id)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), KPC(ctx_)); @@ -870,7 +866,7 @@ int ObInitialTabletGroupRestoreTask::choose_follower_src_() { int ret = OB_SUCCESS; const uint64_t tenant_id = MTL_ID(); - obrpc::ObCopyLSInfo ls_info; + obrpc::ObFetchLSMetaInfoResp ls_info; ObLSRestoreStatus ls_restore_status; if (!is_inited_) { @@ -883,9 +879,9 @@ int ObInitialTabletGroupRestoreTask::choose_follower_src_() ObStorageHASrcInfo src_info; src_info.src_addr_ = ctx_->arg_.src_.get_server(); src_info.cluster_id_ = GCONF.cluster_id; - if (OB_FAIL(storage_rpc_->post_ls_info_request( + if (OB_FAIL(storage_rpc_->post_ls_meta_info_request( tenant_id, src_info, ctx_->arg_.ls_id_, ls_info))) { - LOG_WARN("fail to post fetch partition info request", K(ret), K(src_info), "arg", ctx_->arg_); + LOG_WARN("fail to post fetch ls meta info request", K(ret), K(src_info), "arg", ctx_->arg_); } else if (OB_FAIL(ls_info.ls_meta_package_.ls_meta_.get_restore_status(ls_restore_status))) { LOG_WARN("failed to get restore status", K(ret), K(ls_info)); } else { @@ -911,8 +907,8 @@ int ObInitialTabletGroupRestoreTask::choose_leader_src_() } else { ctx_->need_check_seq_ = false; ctx_->ls_rebuild_seq_ = -1; - //TODO(muwei.ym) using restore reader get ls info - //TOOD(muwei.ym) use more ls info to check src + //TODO(muwei.ym) using restore reader get ls info in 4.3 + //TOOD(muwei.ym) use more ls info to check src in 4.3 } return ret; } @@ -984,7 +980,7 @@ int ObInitialTabletGroupRestoreTask::generate_tablet_restore_dags_() finish_restore_dag = nullptr; } const bool need_retry = true; - if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, need_retry))) { + if (OB_SUCCESS != (tmp_ret = ctx_->set_result(ret, need_retry, this->get_dag()->get_type()))) { LOG_WARN("failed to set restore result", K(ret), K(tmp_ret), K(*ctx_)); } } @@ -992,17 +988,21 @@ int ObInitialTabletGroupRestoreTask::generate_tablet_restore_dags_() return ret; } -int ObInitialTabletGroupRestoreTask::create_or_update_tablets_() +int ObInitialTabletGroupRestoreTask::renew_tablets_meta_() { + // Tablets are first created using tablets' meta which are backed up + // at phase BACKUP_META. These tablets' meta are relatively older than + // them backed up at phase BACKUP_DATA_MINOR. So we renew it. int ret = OB_SUCCESS; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("initial tablet group restore task do not init", K(ret)); - } else if (!ObTabletRestoreAction::is_restore_tablet_meta(ctx_->arg_.action_) && !ObTabletRestoreAction::is_restore_all(ctx_->arg_.action_)) { + } else if (!ObTabletRestoreAction::is_restore_tablet_meta(ctx_->arg_.action_) + && !ObTabletRestoreAction::is_restore_all(ctx_->arg_.action_)) { //do nothing - } else if (OB_FAIL(ha_tablets_builder_.create_or_update_tablets())) { - LOG_WARN("failed to create or update tablets", K(ret), KPC(ctx_)); + } else if (OB_FAIL(ha_tablets_builder_.update_pending_tablets_with_remote())) { + LOG_WARN("failed to update_pending_tablets_with_remote", K(ret), KPC_(ctx)); } return ret; } @@ -1058,7 +1058,7 @@ int ObInitialTabletGroupRestoreTask::record_server_event_() /******************ObStartTabletGroupRestoreDag*********************/ ObStartTabletGroupRestoreDag::ObStartTabletGroupRestoreDag() - : ObTabletGroupRestoreDag(ObStorageHADagType::START_TABLET_GROUP_RESTORE_DAG), + : ObTabletGroupRestoreDag(ObDagType::DAG_TYPE_START_TABLET_GROUP_RESTORE), is_inited_(false), finish_dag_(nullptr) { @@ -1134,26 +1134,6 @@ int ObStartTabletGroupRestoreDag::create_first_task() return ret; } -int ObStartTabletGroupRestoreDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObTabletGroupRestoreCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("start tablet group restore restore dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet group restore ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObInitialTabletGroupRestoreDag : dag_net_task_id = %s, ls_id = %s, first_tablet_id = %s, is_leader = %s, src = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->arg_.ls_id_), to_cstring(ctx->arg_.tablet_id_array_.at(0)), - to_cstring(ctx->arg_.is_leader_), to_cstring(ctx->arg_.src_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObStartTabletGroupRestoreTask*********************/ ObStartTabletGroupRestoreTask::ObStartTabletGroupRestoreTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -1208,7 +1188,6 @@ int ObStartTabletGroupRestoreTask::init( second_meta_index_store_ = restore_dag_net->get_second_meta_index_store(); finish_dag_ = finish_dag; if (OB_FAIL(ls_service->get_ls(ctx_->arg_.ls_id_, ls_handle_, ObLSGetMod::HA_MOD))) { - //TODO(muwei.ym) ls may removed, so need check ls is removed status LOG_WARN("failed to get ls", K(ret), KPC(ctx_)); } else if (OB_FAIL(ObTabletGroupRestoreUtils::init_ha_tablets_builder( ctx_->arg_.tenant_id_, ctx_->tablet_id_array_, ctx_->arg_.is_leader_, @@ -1278,64 +1257,75 @@ int ObStartTabletGroupRestoreTask::generate_tablet_restore_dag_() } else if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret)); - } else if (OB_FAIL(ctx_->tablet_group_ctx_.get_next_tablet_id(tablet_id))) { - LOG_WARN("failed to get next tablet id", K(ret), KPC(ctx_)); } else { - ObIDag *parent = this->get_dag(); - ObTabletRestoreDag *tablet_restore_dag = nullptr; - ObInitTabletRestoreParam param; - param.tenant_id_ = ctx_->arg_.tenant_id_; - param.ls_id_ = ctx_->arg_.ls_id_; - param.tablet_id_ = tablet_id; - param.ha_dag_net_ctx_ = ctx_; - param.is_leader_ = ctx_->arg_.is_leader_; - param.action_ = ctx_->arg_.action_; - param.ha_table_info_mgr_ = &ctx_->ha_table_info_mgr_; - param.restore_base_info_ = &ctx_->arg_.restore_base_info_; - param.meta_index_store_ = meta_index_store_; - param.second_meta_index_store_ = second_meta_index_store_; - param.tablet_group_ctx_ = &ctx_->tablet_group_ctx_; - param.need_check_seq_ = ctx_->need_check_seq_; - param.ls_rebuild_seq_ = ctx_->ls_rebuild_seq_; + while (OB_SUCC(ret)) { + if (OB_FAIL(ctx_->tablet_group_ctx_.get_next_tablet_id(tablet_id))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + LOG_INFO("no tablets need restore", KPC(ctx_)); + } else { + LOG_WARN("failed to get next tablet id", K(ret), KPC(ctx_)); + } + break; + } - if (!param.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("init tablet restore param not valid", K(ret), K(param), KPC(ctx_)); - } else if (OB_FAIL(scheduler->alloc_dag(tablet_restore_dag))) { - LOG_WARN("failed to alloc tablet restore dag ", K(ret)); - } else if (OB_FAIL(tablet_restore_dag->init(param))) { - if (OB_TABLET_NOT_EXIST == ret) { - //overwrite ret - LOG_INFO("tablet is deleted, skip restore", K(tablet_id), K(param)); - scheduler->free_dag(*tablet_restore_dag); - tablet_restore_dag = nullptr; - ret = OB_SUCCESS; + ObIDag *parent = this->get_dag(); + ObTabletRestoreDag *tablet_restore_dag = nullptr; + ObInitTabletRestoreParam param; + param.tenant_id_ = ctx_->arg_.tenant_id_; + param.ls_id_ = ctx_->arg_.ls_id_; + param.tablet_id_ = tablet_id; + param.ha_dag_net_ctx_ = ctx_; + param.is_leader_ = ctx_->arg_.is_leader_; + param.action_ = ctx_->arg_.action_; + param.ha_table_info_mgr_ = &ctx_->ha_table_info_mgr_; + param.restore_base_info_ = &ctx_->arg_.restore_base_info_; + param.meta_index_store_ = meta_index_store_; + param.second_meta_index_store_ = second_meta_index_store_; + param.tablet_group_ctx_ = &ctx_->tablet_group_ctx_; + param.need_check_seq_ = ctx_->need_check_seq_; + param.ls_rebuild_seq_ = ctx_->ls_rebuild_seq_; + + if (!param.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("init tablet restore param not valid", K(ret), K(param), KPC(ctx_)); + } else if (OB_FAIL(scheduler->alloc_dag(tablet_restore_dag))) { + LOG_WARN("failed to alloc tablet restore dag ", K(ret)); + } else if (OB_FAIL(tablet_restore_dag->init(param))) { + if (OB_TABLET_NOT_EXIST == ret) { + //overwrite ret + LOG_INFO("tablet is deleted, skip restore", K(tablet_id), K(param)); + scheduler->free_dag(*tablet_restore_dag); + tablet_restore_dag = nullptr; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to init tablet restore dag", K(ret), K(*ctx_)); + } + } else if (OB_FAIL(dag_net->add_dag_into_dag_net(*tablet_restore_dag))) { + LOG_WARN("failed to add dag into dag net", K(ret), K(*ctx_)); + } else if (OB_FAIL(parent->add_child_without_inheritance(*tablet_restore_dag))) { + LOG_WARN("failed to add child dag", K(ret), K(*ctx_)); + } else if (OB_FAIL(tablet_restore_dag->create_first_task())) { + LOG_WARN("failed to create first task", K(ret), K(*ctx_)); + } else if (OB_FAIL(tablet_restore_dag->add_child_without_inheritance(*finish_dag_))) { + LOG_WARN("failed to add finish dag as child", K(ret), K(*ctx_)); + } else if (OB_FAIL(scheduler->add_dag(tablet_restore_dag))) { + LOG_WARN("failed to add tablet restore dag", K(ret), K(*tablet_restore_dag)); + if (OB_SIZE_OVERFLOW != ret && OB_EAGAIN != ret) { + LOG_WARN("Fail to add task", K(ret)); + ret = OB_EAGAIN; + } } else { - LOG_WARN("failed to init tablet restore dag", K(ret), K(*ctx_)); - } - } else if (OB_FAIL(dag_net->add_dag_into_dag_net(*tablet_restore_dag))) { - LOG_WARN("failed to add dag into dag net", K(ret), K(*ctx_)); - } else if (OB_FAIL(parent->add_child_without_inheritance(*tablet_restore_dag))) { - LOG_WARN("failed to add child dag", K(ret), K(*ctx_)); - } else if (OB_FAIL(tablet_restore_dag->create_first_task())) { - LOG_WARN("failed to create first task", K(ret), K(*ctx_)); - } else if (OB_FAIL(tablet_restore_dag->add_child_without_inheritance(*finish_dag_))) { - LOG_WARN("failed to add finish dag as child", K(ret), K(*ctx_)); - } else if (OB_FAIL(scheduler->add_dag(tablet_restore_dag))) { - LOG_WARN("failed to add tablet restore dag", K(ret), K(*tablet_restore_dag)); - if (OB_SIZE_OVERFLOW != ret && OB_EAGAIN != ret) { - LOG_WARN("Fail to add task", K(ret)); - ret = OB_EAGAIN; - } - } else { - LOG_INFO("succeed to schedule tablet restore dag", K(*tablet_restore_dag)); - tablet_restore_dag = nullptr; - } - - if (OB_FAIL(ret)) { - if (OB_NOT_NULL(tablet_restore_dag)) { - scheduler->free_dag(*tablet_restore_dag, start_tablet_group_restore_dag); + LOG_INFO("succeed to schedule tablet restore dag", K(*tablet_restore_dag)); tablet_restore_dag = nullptr; + break; + } + + if (OB_FAIL(ret)) { + if (OB_NOT_NULL(tablet_restore_dag)) { + scheduler->free_dag(*tablet_restore_dag, start_tablet_group_restore_dag); + tablet_restore_dag = nullptr; + } } } } @@ -1403,7 +1393,7 @@ int ObStartTabletGroupRestoreTask::record_server_event_() /******************ObFinishTabletGroupRestoreDag*********************/ ObFinishTabletGroupRestoreDag::ObFinishTabletGroupRestoreDag() - : ObTabletGroupRestoreDag(ObStorageHADagType::FINISH_TABELT_GROUP_RESTORE_DAG), + : ObTabletGroupRestoreDag(ObDagType::DAG_TYPE_FINISH_TABLET_GROUP_RESTORE), is_inited_(false) { } @@ -1476,26 +1466,6 @@ int ObFinishTabletGroupRestoreDag::create_first_task() return ret; } -int ObFinishTabletGroupRestoreDag::fill_comment(char *buf, const int64_t buf_len) const -{ - int ret = OB_SUCCESS; - ObTabletGroupRestoreCtx *ctx = nullptr; - - if (!is_inited_) { - ret = OB_NOT_INIT; - LOG_WARN("finish tablet group restore restore dag do not init", K(ret)); - } else if (OB_ISNULL(ctx = get_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet group restore ctx should not be NULL", K(ret), KP(ctx)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObInitialTabletGroupRestoreDag : dag_net_task_id = %s, ls_id = %s, first_tablet_id = %s, is_leader = %s, src = %s", - to_cstring(ctx->task_id_), to_cstring(ctx->arg_.ls_id_), to_cstring(ctx->arg_.tablet_id_array_.at(0)), - to_cstring(ctx->arg_.is_leader_), to_cstring(ctx->arg_.src_.get_server())))) { - LOG_WARN("failed to fill comment", K(ret), KPC(ctx)); - } - return ret; -} - /******************ObFinishTabletGroupRestoreTask*********************/ ObFinishTabletGroupRestoreTask::ObFinishTabletGroupRestoreTask() : ObITask(TASK_TYPE_MIGRATE_PREPARE), @@ -1561,7 +1531,7 @@ int ObFinishTabletGroupRestoreTask::process() LOG_WARN("failed to get retry count", K(ret), KPC(ctx_)); } else if (0 != retry_count) { //do nothing - } else if (OB_FAIL(ctx_->set_result(error_code, true/*allow retry*/))) { + } else if (OB_FAIL(ctx_->set_result(error_code, true/*allow retry*/, this->get_dag()->get_type()))) { LOG_WARN("failed to set result", K(ret), K(error_code), KPC(ctx_)); } } @@ -1709,7 +1679,7 @@ bool ObInitTabletRestoreParam::is_valid() const /******************ObTabletRestoreDag*********************/ ObTabletRestoreDag::ObTabletRestoreDag() - : ObStorageHADag(ObDagType::DAG_TYPE_RESTORE, ObStorageHADagType::TABLET_RESTORE_DAG), + : ObStorageHADag(ObDagType::DAG_TYPE_TABLET_RESTORE), is_inited_(false), tablet_restore_ctx_(), bandwidth_throttle_(nullptr), @@ -1797,21 +1767,21 @@ int ObTabletRestoreDag::get_dag_net_task_id_(share::ObTaskId &task_id) const return ret; } -int ObTabletRestoreDag::fill_comment(char *buf, const int64_t buf_len) const +int ObTabletRestoreDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const { int ret = OB_SUCCESS; share::ObTaskId task_id; - if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet restore dag do not init", K(ret)); } else if (OB_FAIL(get_dag_net_task_id_(task_id))) { LOG_WARN("failed to get dag net task id", K(ret)); - } else if (OB_FAIL(databuff_printf(buf, buf_len, - "ObTabletRestoreDag : dag_net_task_id = %s, ls_id = %s, tablet_id = %s, is_leader = %s", - to_cstring(task_id), to_cstring(tablet_restore_ctx_.ls_id_), to_cstring(tablet_restore_ctx_.tablet_id_), - to_cstring(tablet_restore_ctx_.is_leader_)))) { - LOG_WARN("failed to fill comment", K(ret), K(tablet_restore_ctx_)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + tablet_restore_ctx_.ls_id_.id(), + static_cast(tablet_restore_ctx_.tablet_id_.id()), + static_cast(tablet_restore_ctx_.is_leader_), + "dag_net_task_id", to_cstring(task_id)))) { + LOG_WARN("failed to fill info param", K(ret)); } return ret; } @@ -1823,7 +1793,6 @@ int ObTabletRestoreDag::init( ObLSService *ls_service = nullptr; ObLS *ls = nullptr; ObCopyTabletStatus::STATUS status = ObCopyTabletStatus::MAX_STATUS; - const int64_t timeout_us = ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US; bool is_exist = false; if (is_inited_) { @@ -1840,10 +1809,8 @@ int ObTabletRestoreDag::init( } else if (OB_ISNULL(ls = ls_handle_.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls should not be NULL", K(ret), K(param)); - } else if (OB_FAIL(ls->get_tablet(param.tablet_id_, - tablet_restore_ctx_.tablet_handle_, timeout_us))) { - LOG_WARN("failed to get tablet", K(ret), K(param), K(timeout_us)); - //TODO(muwei.ym) here tablet may relay remove tablet log, need deal with it + } else if (OB_FAIL(ls->ha_get_tablet(param.tablet_id_, tablet_restore_ctx_.tablet_handle_))) { + LOG_WARN("failed to get tablet", K(ret), K(param)); } else if (OB_FAIL(param.ha_table_info_mgr_->check_copy_tablet_exist(param.tablet_id_, is_exist))) { LOG_WARN("failed to check copy tablet exist", K(ret), K(param)); } else if (FALSE_IT(status = is_exist ? ObCopyTabletStatus::TABLET_EXIST : ObCopyTabletStatus::TABLET_NOT_EXIST)) { @@ -1932,8 +1899,7 @@ int ObTabletRestoreDag::inner_reset_status_for_retry() if (OB_ISNULL(ls = ls_handle_.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls should not be NULL", K(ret), K(tablet_restore_ctx_)); - } else if (OB_FAIL(ls->get_tablet(tablet_restore_ctx_.tablet_id_, tablet_restore_ctx_.tablet_handle_, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls->ha_get_tablet(tablet_restore_ctx_.tablet_id_, tablet_restore_ctx_.tablet_handle_))) { if (OB_TABLET_NOT_EXIST == ret) { ret = OB_SUCCESS; const ObCopyTabletStatus::STATUS status = ObCopyTabletStatus::TABLET_NOT_EXIST; @@ -2039,7 +2005,7 @@ int ObTabletRestoreDag::generate_next_dag(share::ObIDag *&dag) if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; const bool need_retry = false; - if (need_set_failed_result && OB_SUCCESS != (tmp_ret = ha_dag_net_ctx_->set_result(ret, need_retry))) { + if (need_set_failed_result && OB_SUCCESS != (tmp_ret = ha_dag_net_ctx_->set_result(ret, need_retry, get_type()))) { LOG_WARN("failed to set result", K(ret), KPC(ha_dag_net_ctx_)); } } @@ -2115,7 +2081,7 @@ int ObTabletRestoreTask::process() LOG_WARN("failed to get copy tablet status", K(ret), KPC(tablet_restore_ctx_)); } else if (ObCopyTabletStatus::TABLET_NOT_EXIST == status) { FLOG_INFO("copy tablet is not exist, skip copy it", KPC(tablet_restore_ctx_)); - if (OB_FAIL(update_ha_expected_status_(status))) { + if (OB_FAIL(update_ha_status_(status))) { LOG_WARN("failed to update ha expected status", K(ret), KPC(tablet_restore_ctx_)); } } else if (OB_FAIL(build_copy_table_key_info_())) { @@ -2129,6 +2095,18 @@ int ObTabletRestoreTask::process() if (OB_SUCCESS != (tmp_ret = record_server_event_())) { LOG_WARN("failed to record server event", K(tmp_ret)); } +#ifdef ERRSIM + if (OB_SUCC(ret) && !tablet_restore_ctx_->is_leader_ + && ObTabletRestoreAction::is_restore_minor(tablet_restore_ctx_->action_) + && tablet_restore_ctx_->ls_id_.is_user_ls()) { + SERVER_EVENT_SYNC_ADD("storage_ha", "follower_restore_major_errsim", "tablet_id", tablet_restore_ctx_->tablet_id_.id()); + DEBUG_SYNC(AFTER_RESTORE_TABLET_TASK); + ret = OB_E(EventTable::EN_RESTORE_TABLET_TASK_FAILED) OB_SUCCESS; + if (OB_FAIL(ret)) { + LOG_WARN("failed to do restore tablet task.", K(ret)); + } + } +#endif if (OB_FAIL(ret)) { if (OB_SUCCESS != (tmp_ret = ObStorageHADagUtils::deal_with_fo(ret, this->get_dag()))) { @@ -2171,8 +2149,7 @@ int ObTabletRestoreTask::generate_minor_restore_tasks_( { int ret = OB_SUCCESS; ObTablet *tablet = nullptr; - ObTableStoreIterator table_iter; - bool is_ready_for_read = true; + bool is_remote_sstable_exist = true; if (!is_inited_) { ret = OB_NOT_INIT; @@ -2180,9 +2157,17 @@ int ObTabletRestoreTask::generate_minor_restore_tasks_( } else if (OB_ISNULL(tablet_copy_finish_task) || OB_ISNULL(parent_task)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("generate minor task get invalid argument", K(ret), KP(tablet_copy_finish_task), KP(parent_task)); + } else if (OB_ISNULL(tablet = tablet_restore_ctx_->tablet_handle_.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), KPC(ha_dag_net_ctx_), KPC(tablet_restore_ctx_)); } else if (!ObTabletRestoreAction::is_restore_minor(tablet_restore_ctx_->action_) && !ObTabletRestoreAction::is_restore_all(tablet_restore_ctx_->action_)) { - LOG_INFO("tablet not restore minor or restore all, skip minor restore tasks", K(ret), + LOG_INFO("tablet not restore minor or restore all, skip minor restore tasks", + KPC(ha_dag_net_ctx_), KPC(tablet_restore_ctx_)); + } else if (OB_FAIL(ObStorageHATabletBuilderUtil::check_remote_logical_sstable_exist(tablet, is_remote_sstable_exist))) { + LOG_WARN("failed to check remote logical sstable exist", K(ret), KPC(ha_dag_net_ctx_), KPC(tablet_restore_ctx_)); + } else if (!is_remote_sstable_exist && !tablet->get_tablet_meta().has_transfer_table()) { + LOG_INFO("neither remote logical sstable nor transfer table exist, skip minor restore tasks", KPC(ha_dag_net_ctx_), KPC(tablet_restore_ctx_)); } else if (OB_FAIL(generate_restore_task_(ObITable::is_minor_sstable, tablet_copy_finish_task, parent_task))) { LOG_WARN("failed to generate minor restore task", K(ret), KPC(ha_dag_net_ctx_), KPC(tablet_restore_ctx_)); @@ -2212,7 +2197,7 @@ int ObTabletRestoreTask::generate_major_restore_tasks_( return ret; } -//TODO(muwei.ym) reconsider ddl sstable +//TODO(muwei.ym) reconsider ddl sstable in 4.3 int ObTabletRestoreTask::generate_ddl_restore_tasks_( ObTabletCopyFinishTask *tablet_copy_finish_task, share::ObITask *&parent_task) @@ -2242,7 +2227,7 @@ int ObTabletRestoreTask::generate_physical_restore_task_( { int ret = OB_SUCCESS; ObPhysicalCopyTask *copy_task = NULL; - ObPhysicalCopyFinishTask *finish_task = NULL; + ObSSTableCopyFinishTask *finish_task = NULL; const int64_t task_idx = 0; ObPhysicalCopyTaskInitParam init_param; @@ -2552,7 +2537,7 @@ int ObTabletRestoreTask::try_update_tablet_() return ret; } -int ObTabletRestoreTask::update_ha_expected_status_( +int ObTabletRestoreTask::update_ha_status_( const ObCopyTabletStatus::STATUS &status) { int ret = OB_SUCCESS; @@ -2565,13 +2550,23 @@ int ObTabletRestoreTask::update_ha_expected_status_( LOG_WARN("update ha meta status get invalid argument", K(ret), K(status)); } else { const ObTabletExpectedStatus::STATUS expected_status = ObTabletExpectedStatus::DELETED; + const ObTabletRestoreStatus::STATUS restore_status = ObTabletRestoreStatus::UNDEFINED; if (OB_FAIL(ls_->get_tablet_svr()->update_tablet_ha_expected_status(tablet_restore_ctx_->tablet_id_, expected_status))) { if (OB_TABLET_NOT_EXIST == ret) { - LOG_INFO("restore tablet maybe deleted, skip it", K(ret), KPC(tablet_restore_ctx_)); + LOG_INFO("restore tablet maybe deleted, skip update expected status to DELETED", K(ret), KPC(tablet_restore_ctx_)); ret = OB_SUCCESS; } else { - LOG_WARN("failed to update tablet ha expected status", K(ret), K(expected_status), KPC(tablet_restore_ctx_)); + LOG_WARN("failed to update expected status to DELETED", K(ret), K(expected_status), KPC(tablet_restore_ctx_)); } + } else if (OB_FAIL(ls_->update_tablet_restore_status(tablet_restore_ctx_->tablet_id_, restore_status))) { + if (OB_TABLET_NOT_EXIST == ret) { + LOG_INFO("restore tablet maybe deleted, skip update restore status to UNDEFINED", K(ret), KPC(tablet_restore_ctx_)); + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to update restore status to UNDEFINED", K(ret), K(restore_status), KPC(tablet_restore_ctx_)); + } + } else { + LOG_INFO("remote tablet is not exist, update expected status to DELETED, and restore status to UNDEFINED", KPC(tablet_restore_ctx_)); } } return ret; @@ -2637,7 +2632,10 @@ int ObTabletRestoreTask::check_src_sstable_exist_() } } else if (ObTabletRestoreAction::is_restore_major(tablet_restore_ctx_->action_)) { if (!is_major_sstable_exist && tablet->get_tablet_meta().table_store_flag_.with_major_sstable()) { - if (tablet->get_table_store().get_major_sstables().empty()) { + ObTabletMemberWrapper table_store_wrapper; + if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (table_store_wrapper.get_member()->get_major_sstables().empty()) { ret = OB_SSTABLE_NOT_EXIST; LOG_WARN("src restore sstable do not exist", K(ret), K(copy_table_key_array_), KPC(tablet_restore_ctx_)); } @@ -2736,7 +2734,7 @@ int ObTabletFinishRestoreTask::update_data_status_() int ret = OB_SUCCESS; ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; - const int64_t timeout_us = ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US; + ObTabletMemberWrapper table_store_wrapper; if (!is_inited_) { ret = OB_NOT_INIT; @@ -2744,14 +2742,16 @@ int ObTabletFinishRestoreTask::update_data_status_() } else if (!ObTabletRestoreAction::is_restore_all(tablet_restore_ctx_->action_) && !ObTabletRestoreAction::is_restore_major(tablet_restore_ctx_->action_)) { //do nothing - } else if (OB_FAIL(ls_->get_tablet(tablet_restore_ctx_->tablet_id_, tablet_handle, timeout_us))) { - LOG_WARN("failed to get tablet", K(ret), KPC(tablet_restore_ctx_), K(timeout_us)); + } else if (OB_FAIL(ls_->ha_get_tablet(tablet_restore_ctx_->tablet_id_, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), KPC(tablet_restore_ctx_)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), KPC(tablet_restore_ctx_)); + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - const ObSSTableArray &minor_sstables = tablet->get_table_store().get_minor_sstables(); - const ObSSTableArray &major_sstables = tablet->get_table_store().get_major_sstables(); + const ObSSTableArray &minor_sstables = table_store_wrapper.get_member()->get_minor_sstables(); + const ObSSTableArray &major_sstables = table_store_wrapper.get_member()->get_major_sstables(); for (int64_t i = 0; OB_SUCC(ret) && i < minor_sstables.count(); ++i) { const ObITable *table = minor_sstables[i]; if (table->is_remote_logical_minor_sstable()) { @@ -2803,12 +2803,11 @@ int ObTabletFinishRestoreTask::check_tablet_valid_() int ret = OB_SUCCESS; ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; - const int64_t timeout_us = ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US; if (!is_inited_) { ret = OB_NOT_INIT; LOG_WARN("tablet finish restore task do not init", K(ret)); - } else if (OB_FAIL(ls_->get_tablet(tablet_restore_ctx_->tablet_id_, tablet_handle, timeout_us))) { - LOG_WARN("failed to get tablet", K(ret), KPC(tablet_restore_ctx_), K(timeout_us)); + } else if (OB_FAIL(ls_->ha_get_tablet(tablet_restore_ctx_->tablet_id_, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), KPC(tablet_restore_ctx_)); } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), KPC(tablet_restore_ctx_)); @@ -2860,7 +2859,7 @@ int ObTabletGroupRestoreUtils::init_ha_tablets_builder( || !ObTabletRestoreAction::is_valid(restore_action) || OB_ISNULL(ha_table_info_mgr)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("init ha tablets builder get unexpected error", K(ret), KP(tenant_id), + LOG_WARN("init ha tablets builder get unexpected error", K(ret), K(tenant_id), K(tablet_id_array), KP(ls), K(src_info), K(is_leader_restore), KP(restore_base_info), KP(meta_index_store), KP(ha_table_info_mgr)); } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { diff --git a/src/storage/high_availability/ob_tablet_group_restore.h b/src/storage/high_availability/ob_tablet_group_restore.h index e0e198896..c629e579a 100644 --- a/src/storage/high_availability/ob_tablet_group_restore.h +++ b/src/storage/high_availability/ob_tablet_group_restore.h @@ -175,10 +175,11 @@ private: class ObTabletGroupRestoreDag : public ObStorageHADag { public: - explicit ObTabletGroupRestoreDag(const ObStorageHADagType sub_type); + explicit ObTabletGroupRestoreDag(const share::ObDagType::ObDagTypeEnum &dag_type); virtual ~ObTabletGroupRestoreDag(); virtual bool operator == (const share::ObIDag &other) const override; virtual int64_t hash() const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; ObTabletGroupRestoreCtx *get_ctx() const { return static_cast(ha_dag_net_ctx_); } INHERIT_TO_STRING_KV("ObStorageHADag", ObStorageHADag, KP(this)); @@ -193,8 +194,6 @@ public: virtual ~ObInitialTabletGroupRestoreDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; - int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObTabletGroupRestoreDag", ObTabletGroupRestoreDag, KP(this)); protected: @@ -217,7 +216,7 @@ private: int choose_leader_src_(); int choose_follower_src_(); int generate_tablet_restore_dags_(); - int create_or_update_tablets_(); + int renew_tablets_meta_(); int init_ha_tablets_builder_(); int build_tablet_group_ctx_(); int record_server_event_(); @@ -243,8 +242,6 @@ public: virtual ~ObStartTabletGroupRestoreDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; - int init(share::ObIDagNet *dag_net, share::ObIDag *finish_dag); INHERIT_TO_STRING_KV("ObTabletGroupRestoreDag", ObTabletGroupRestoreDag, KP(this)); protected: @@ -289,8 +286,6 @@ public: virtual ~ObFinishTabletGroupRestoreDag(); virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; - int init(share::ObIDagNet *dag_net); INHERIT_TO_STRING_KV("ObTabletGroupRestoreDag", ObTabletGroupRestoreDag, KP(this)); protected: @@ -361,7 +356,7 @@ public: virtual int64_t hash() const override; virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; virtual int create_first_task() override; - virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; virtual int inner_reset_status_for_retry() override; virtual int generate_next_dag(share::ObIDag *&dag); @@ -424,7 +419,7 @@ private: int generate_tablet_copy_finish_task_( ObTabletCopyFinishTask *&tablet_copy_finish_task); int try_update_tablet_(); - int update_ha_expected_status_(const ObCopyTabletStatus::STATUS &status); + int update_ha_status_(const ObCopyTabletStatus::STATUS &status); int check_need_copy_sstable_( const ObITable::TableKey &table_key, bool &need_copy); diff --git a/src/storage/high_availability/ob_tablet_ha_status.cpp b/src/storage/high_availability/ob_tablet_ha_status.cpp index 3801f95ae..0e867d3ae 100644 --- a/src/storage/high_availability/ob_tablet_ha_status.cpp +++ b/src/storage/high_availability/ob_tablet_ha_status.cpp @@ -58,7 +58,8 @@ int ObTabletRestoreStatus::check_can_change_status( case ObTabletRestoreStatus::EMPTY: { if (ObTabletRestoreStatus::MINOR_AND_MAJOR_META == change_status || ObTabletRestoreStatus::FULL == change_status - || ObTabletRestoreStatus::EMPTY == change_status) { + || ObTabletRestoreStatus::EMPTY == change_status + || ObTabletRestoreStatus::UNDEFINED == change_status) { can_change = true; } break; @@ -71,7 +72,8 @@ int ObTabletRestoreStatus::check_can_change_status( break; } case ObTabletRestoreStatus::FULL: { - if (ObTabletRestoreStatus::FULL == change_status) { + if (ObTabletRestoreStatus::FULL == change_status + || ObTabletRestoreStatus::EMPTY == change_status) { can_change = true; } break; diff --git a/src/storage/high_availability/ob_tablet_ha_status.h b/src/storage/high_availability/ob_tablet_ha_status.h index 29a9124dd..d5f3d1791 100644 --- a/src/storage/high_availability/ob_tablet_ha_status.h +++ b/src/storage/high_availability/ob_tablet_ha_status.h @@ -107,6 +107,10 @@ public: bool is_none() const { return is_data_status_complete() && is_restore_status_full(); } bool is_data_status_complete() const { return ObTabletDataStatus::is_complete(data_status_); } bool is_restore_status_full() const { return ObTabletRestoreStatus::is_full(restore_status_); } + bool is_restore_status_pending() const { return ObTabletRestoreStatus::is_pending(restore_status_); } + bool is_restore_status_undefined() const { return ObTabletRestoreStatus::is_undefined(restore_status_); } + bool is_restore_status_empty() const { return ObTabletRestoreStatus::is_empty(restore_status_); } + bool is_restore_status_minor_and_major_meta() const { return ObTabletRestoreStatus::is_minor_and_major_meta(restore_status_); } bool is_expected_status_normal() const { return ObTabletExpectedStatus::is_normal(expected_status_); } bool is_expected_status_deleted() const { return ObTabletExpectedStatus::is_deleted(expected_status_); } @@ -118,7 +122,6 @@ public: int get_expected_status(ObTabletExpectedStatus::STATUS &expected_status) const; int init_status(); int init_status_for_ha(const ObTabletHAStatus &ha_status); - bool is_restore_status_pending() const { return ObTabletRestoreStatus::is_pending(restore_status_); } bool is_valid_for_backup() const { return ObTabletDataStatus::is_complete(data_status_) && ObTabletRestoreStatus::is_full(restore_status_); } TO_STRING_KV(K_(restore_status), K_(data_status), K_(expected_status), K_(reserved)); diff --git a/src/storage/high_availability/ob_tablet_transfer_info.cpp b/src/storage/high_availability/ob_tablet_transfer_info.cpp new file mode 100644 index 000000000..aabb0ed47 --- /dev/null +++ b/src/storage/high_availability/ob_tablet_transfer_info.cpp @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE +#include "ob_tablet_transfer_info.h" + +using namespace oceanbase; +using namespace share; +using namespace storage; + + +ObTabletTransferInfo::ObTabletTransferInfo() + : ls_id_(), + transfer_start_scn_(), + transfer_seq_(-1), + has_transfer_table_(false) +{ +} + +int ObTabletTransferInfo::init() +{ + int ret = OB_SUCCESS; + ls_id_ = TRANSFER_INIT_LS_ID; + transfer_start_scn_.set_min(); + transfer_seq_ = 0; + has_transfer_table_ = false; + return ret; +} + +int ObTabletTransferInfo::init( + const share::ObLSID &ls_id, + const share::SCN &transfer_start_scn, + const int64_t transfer_seq) +{ + int ret = OB_SUCCESS; + if (!ls_id.is_valid() || !transfer_start_scn.is_valid_and_not_min() || transfer_seq < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("init transfer info get invalid agument", K(ret), K(ls_id), K(transfer_start_scn), K(transfer_seq)); + } else { + ls_id_ = ls_id; + transfer_start_scn_ = transfer_start_scn; + transfer_seq_ = transfer_seq; + has_transfer_table_ = true; + } + return ret; +} + +void ObTabletTransferInfo::reset() +{ + ls_id_.reset(); + transfer_start_scn_.reset(); + transfer_seq_ = -1; + has_transfer_table_ = false; +} + +bool ObTabletTransferInfo::is_valid() const +{ + return ls_id_.is_valid() + && transfer_start_scn_.is_valid() + && transfer_seq_ >= 0; +} + +bool ObTabletTransferInfo::has_transfer_table() const +{ + return has_transfer_table_; +} + +void ObTabletTransferInfo::reset_transfer_table() +{ + has_transfer_table_ = false; + //transfer seq, ls id, transfer start scn will not change +} + +OB_SERIALIZE_MEMBER(ObTabletTransferInfo, ls_id_, transfer_start_scn_, transfer_seq_, has_transfer_table_); diff --git a/src/storage/high_availability/ob_tablet_transfer_info.h b/src/storage/high_availability/ob_tablet_transfer_info.h new file mode 100644 index 000000000..b09346682 --- /dev/null +++ b/src/storage/high_availability/ob_tablet_transfer_info.h @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2021 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 OCEABASE_STORAGE_TABLET_TRANSFER_INFO_ +#define OCEABASE_STORAGE_TABLET_TRANSFER_INFO_ + +#include "share/ob_define.h" +#include "lib/utility/ob_unify_serialize.h" +#include "share/scn.h" + +namespace oceanbase +{ +namespace storage +{ + +struct ObTabletTransferInfo final +{ + OB_UNIS_VERSION(1); +public: + ObTabletTransferInfo(); + ~ObTabletTransferInfo() = default; + int init(); + int init( + const share::ObLSID &ls_id, + const share::SCN &transfer_start_scn, + const int64_t transfer_seq); + void reset(); + bool is_valid() const; + bool has_transfer_table() const; + void reset_transfer_table(); + + TO_STRING_KV(K_(ls_id), K_(transfer_start_scn), K_(transfer_seq), K_(has_transfer_table)); +public: + share::ObLSID ls_id_; + share::SCN transfer_start_scn_; + int64_t transfer_seq_; + bool has_transfer_table_; +private: + static const int64_t TRANSFER_INIT_LS_ID = 0; +}; + + +} +} +#endif diff --git a/src/storage/high_availability/ob_transfer_backfill_tx.cpp b/src/storage/high_availability/ob_transfer_backfill_tx.cpp new file mode 100644 index 000000000..6b6a09e76 --- /dev/null +++ b/src/storage/high_availability/ob_transfer_backfill_tx.cpp @@ -0,0 +1,1700 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX STORAGE +#include "ob_transfer_backfill_tx.h" +#include "storage/tablet/ob_tablet_iterator.h" +#include "storage/tablet/ob_tablet.h" +#include "logservice/ob_log_service.h" +#include "share/rc/ob_tenant_base.h" +#include "ob_tablet_backfill_tx.h" +#include "share/scheduler/ob_dag_scheduler.h" +#include "ob_transfer_service.h" +#include "observer/ob_server_event_history_table_operator.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" +#include "share/ob_debug_sync_point.h" +#include "lib/utility/ob_tracepoint.h" +#include "storage/tablet/ob_tablet.h" + +namespace oceanbase +{ +using namespace share; +namespace storage +{ + +ObTransferWorkerMgr::ObTransferWorkerMgr() + : is_inited_(false), + tenant_id_(OB_INVALID_TENANT_ID), + task_id_(), + dest_ls_(NULL) +{ +} + +ObTransferWorkerMgr::~ObTransferWorkerMgr() +{ +} + +int ObTransferWorkerMgr::init(ObLS *dest_ls) +{ + int ret = OB_SUCCESS; + bool is_exist = false; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_ISNULL(dest_ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls is nullptr", K(ret)); + } else { + share::ObTaskId task_id; + task_id.init(GCONF.self_addr_); + task_id_ = task_id; + tenant_id_ = MTL_ID(); + dest_ls_ = dest_ls; + is_inited_ = true; + } + return ret; +} + +void ObTransferWorkerMgr::update_task_id_() +{ + task_id_.reset(); + task_id_.init(GCONF.self_addr_); +} +int ObTransferWorkerMgr::get_need_backfill_tx_tablets_(ObTransferBackfillTXParam ¶m) +{ + int ret = OB_SUCCESS; + int64_t start_time = common::ObTimeUtility::current_time(); + param.reset(); + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); + share::ObLSID src_ls_id; + SCN transfer_scn; + SCN src_max_backfill_scn; + src_max_backfill_scn.set_min(); + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + bool in_migration = false; + ObLSRestoreStatus restore_status; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer work not init", K(ret)); + } else if (OB_FAIL(dest_ls_->build_tablet_iter(tablet_iter))) { + LOG_WARN("failed to build ls tablet iter", K(ret)); + } else if (OB_FAIL(dest_ls_->get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), KPC(dest_ls_)); + } else if (FALSE_IT(in_migration = ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status)) { + } else if (OB_FAIL(dest_ls_->get_restore_status(restore_status))) { + LOG_WARN("failed to get restore status", K(ret), KPC_(dest_ls)); + } else if (restore_status.is_restore_to_consistent_scn()) { + LOG_INFO("[TRANSFER_BACKFILL]ls is in RESTORE_TO_CONSISTENT_SCN, skip backfill", KPC_(dest_ls)); + } else { + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + ObTabletHAStatus src_tablet_ha_status; + while (OB_SUCC(ret)) { + tablet_handle.reset(); + user_data.reset(); + tablet = nullptr; + bool is_ready = false; + if (OB_FAIL(tablet_iter.get_next_tablet(tablet_handle))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get tablet", K(ret), KPC(dest_ls_)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); + } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { + //do nothing + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + if (OB_EMPTY_RESULT == ret || OB_ERR_SHARED_LOCK_CONFLICT == ret) { // needs to delete this judgment after ObLSTabletIterator optimization + LOG_INFO("committed tablet_status does not exist", K(ret), "tablet_id", tablet->get_tablet_meta().tablet_id_); + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet status", K(ret), KPC(tablet)); + } + } else if (ObTabletStatus::TRANSFER_IN != user_data.tablet_status_ && !in_migration) { + // do nothing + } else if (!tablet->get_tablet_meta().has_transfer_table()) { + // do nothing + } else if (!tablet->get_tablet_meta().ha_status_.is_restore_status_full()) { + // Restore status is FULL when the tablet is created by transfer in. It can + // turn into one of the following status. + // 1. FULL if not in restore; + // 2. EMPTY if the transfer table cannot be replaced with source tablet, may be source tablet is UNDEFINED; + // 3. MINOR_AND_MAJOR_META with no transfer table if in restore and source tablet only has minor tables. + // Here, the restore status must be EMPTY. The transfer table should be replaced by physical restore. + LOG_INFO("[TRANSFER_BACKFILL]skip tablet which restore status is not full.", + "tablet_id", tablet->get_tablet_meta().tablet_id_, + "ha_status", tablet->get_tablet_meta().ha_status_); + } else if (!tablet->get_tablet_meta().transfer_info_.ls_id_.is_valid() + || !tablet->get_tablet_meta().transfer_info_.transfer_start_scn_.is_valid()) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("transfer_ls_id_ or transfer_scn_ are invalid", K(ret), "transfer_info", tablet->get_tablet_meta().transfer_info_, + K(in_migration), K(migration_status)); + } else if (OB_FAIL(check_source_tablet_ready_(tablet->get_tablet_meta().transfer_info_.ls_id_, + tablet->get_tablet_meta().tablet_id_, + tablet->get_tablet_meta().transfer_info_, + is_ready, + src_tablet_ha_status))) { + LOG_WARN("fail to check source tablet ready", K(ret), "transfer_info", tablet->get_tablet_meta().transfer_info_, + "tablet_id", tablet->get_tablet_meta().tablet_id_); + } else if (!is_ready) { + LOG_INFO("[TRANSFER_BACKFILL]skip tablet which is not ready.", + "tablet_id", tablet->get_tablet_meta().tablet_id_); + } else if (src_tablet_ha_status.is_restore_status_undefined()) { + // If source tablet is UNDEFINED, directly set dest tablet EMPTY, but keep + // transfer table. Then the restore handler will schedule it to restore minor + // without creating remote logical table. + if (OB_FAIL(dest_ls_->update_tablet_restore_status(tablet->get_tablet_meta().tablet_id_, + ObTabletRestoreStatus::EMPTY))) { + LOG_WARN("fail to set empty", K(ret), KPC(tablet)); + } else { + dest_ls_->get_ls_restore_handler()->try_record_one_tablet_to_restore(tablet->get_tablet_meta().tablet_id_); + LOG_INFO("[TRANSFER_BACKFILL]direct set tablet EMPTY if source tablet is UNDEFINED.", + "tablet_meta", tablet->get_tablet_meta()); + } + } else { +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "get_need_backfil_tx_tablets", + "src_ls_id", tablet->get_tablet_meta().transfer_info_.ls_id_.id(), + "dest_ls_id", dest_ls_->get_ls_id().id(), + "tablet_id", tablet->get_tablet_meta().tablet_id_, + "has_transfer_table", tablet->get_tablet_meta().has_transfer_table()); +#endif + if (OB_FAIL(param.tablet_ids_.push_back(tablet->get_tablet_meta().tablet_id_))) { + LOG_WARN("failed to push tablet id into array", K(ret), KPC(tablet)); + } else if (src_ls_id.is_valid() && transfer_scn.is_valid()) { + if (in_migration) { + //migration will has multi transfer task tablets. + if (src_ls_id != tablet->get_tablet_meta().transfer_info_.ls_id_ + || transfer_scn != tablet->get_tablet_meta().transfer_info_.transfer_start_scn_) { + param.tablet_ids_.pop_back(); + } + } else if (src_ls_id != tablet->get_tablet_meta().transfer_info_.ls_id_ + || transfer_scn != tablet->get_tablet_meta().transfer_info_.transfer_start_scn_) { + // Only one transfer task is allowed to execute at the same time, verify that the transferred tablets parameter are the same. + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("transfer task is not unique", K(ret), K(src_ls_id), K(transfer_scn), KPC(tablet)); + } + } else { + src_ls_id = tablet->get_tablet_meta().transfer_info_.ls_id_; + transfer_scn = tablet->get_tablet_meta().transfer_info_.transfer_start_scn_; + } + } + } + + if (OB_SUCC(ret)) { + param.src_ls_id_ = src_ls_id; + param.backfill_scn_ = std::max(src_max_backfill_scn, transfer_scn); + param.tenant_id_ = tenant_id_; + param.task_id_ = task_id_; + param.dest_ls_id_ = dest_ls_->get_ls_id(); + const int64_t cost_time = common::ObTimeUtility::current_time() - start_time; + LOG_INFO("statistics the time that get needed to backfill tablets", "ls id", param.dest_ls_id_, K(cost_time)); + } + } + return ret; +} + +int ObTransferWorkerMgr::check_source_tablet_ready_( + const share::ObLSID &ls_id, + const ObTabletID &tablet_id, + const ObTabletTransferInfo &transfer_info, + bool &is_ready, + ObTabletHAStatus &ha_status/* source tablet ha status */) const +{ + int ret = OB_SUCCESS; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + SCN max_decided_scn; + ObTabletCreateDeleteMdsUserData user_data; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + + is_ready = false; + if (!ls_id.is_valid() || !tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::HA_MOD))) { + if (OB_LS_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("[TRANSFER_BACKFILL]source ls not exist", K(ls_id), K(tablet_id)); + } else { + LOG_WARN("failed to get ls", K(ret), K(ls_id), K(tablet_id)); + } + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else if (OB_FAIL(ls->get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), KPC(ls)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status) { + LOG_INFO("[TRANSFER_BACKFILL]source ls is not in migration none", K(ls_id), K(migration_status)); + } else if (OB_FAIL(ls->get_max_decided_scn(max_decided_scn))) { + LOG_WARN("failed to get source ls max decided scn", K(ret), KPC(ls)); + } else if (max_decided_scn < transfer_info.transfer_start_scn_) { + LOG_INFO("[TRANSFER_BACKFILL]src ls max decided scn is smaller than transfer start scn, need wait", K(ls_id), K(tablet_id), K(max_decided_scn), K(transfer_info)); + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + LOG_INFO("[TRANSFER_BACKFILL]source tablet not exist", K(ls_id), K(tablet_id)); + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(ls_id), K(tablet_id)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + LOG_WARN("failed to get tablet status", K(ret), K(ls_id), KPC(tablet)); + } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ + && ObTabletStatus::TRANSFER_OUT_DELETED != user_data.tablet_status_ ) { + // wait source tablet transfer start commit + LOG_INFO("[TRANSFER_BACKFILL]source tablet is not ready", K(tablet_id), "tablet_status", user_data.tablet_status_, K(ls_id)); + } else if (tablet->get_tablet_meta().transfer_info_.transfer_seq_ != transfer_info.transfer_seq_ - 1) { + LOG_INFO("[TRANSFER_BACKFILL]source tablet transfer seq is unexpected, need rebuild", K(ls_id), K(tablet_id), + "src transfer info", tablet->get_tablet_meta().transfer_info_, + "dest transfer info", transfer_info); + } else { + ha_status = tablet->get_tablet_meta().ha_status_; + if (ha_status.is_restore_status_minor_and_major_meta() + || ha_status.is_restore_status_full() + || ha_status.is_restore_status_undefined()) { + is_ready = true; + LOG_INFO("[TRANSFER_BACKFILL]source tablet is ready", K(ls_id), K(tablet_id), K(ha_status)); + } else { + LOG_INFO("[TRANSFER_BACKFILL]source tablet is not ready", K(ls_id), K(tablet_id), K(ha_status)); +#ifdef ERRSIM + SERVER_EVENT_ADD("transfer", "backfill_tx_with_restoring_tablet", "tablet_id", tablet->get_tablet_meta().tablet_id_); +#endif + } + } + return ret; +} + +int ObTransferWorkerMgr::process() +{ + int ret = OB_SUCCESS; + bool is_exist = false; + ObTransferBackfillTXParam param; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer work not init", K(ret)); + } else if (OB_FAIL(check_task_exist_(task_id_, is_exist))) { + LOG_WARN("failed to check task exist", K(ret), "ls_id", dest_ls_->get_ls_id(), K(*this)); + } else if (is_exist) { + // only one transfer backfill tx task is allowed to execute at a time + LOG_INFO("[TRANSFER_BACKFILL]transfer backfill tx task exist", "ls_id", dest_ls_->get_ls_id(), K(*this)); + } else { + update_task_id_(); + if (OB_FAIL(get_need_backfill_tx_tablets_(param))) { + LOG_WARN("failed to get need backfill tx tablets", K(ret), "ls_id", dest_ls_->get_ls_id(), K(*this)); + } else if (param.tablet_ids_.empty()) { + // There are no tablets that require backfill transactions + } else if (OB_FAIL(do_transfer_backfill_tx_(param))) { + LOG_WARN("failed to do transfer backfill tx", K(ret), K(param)); + } + } + + return ret; +} + +int ObTransferWorkerMgr::check_task_exist_( + const share::ObTaskId &task_id, + bool &is_exist) +{ + int ret = OB_SUCCESS; + is_exist = false; + share::ObTenantDagScheduler *scheduler = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer worker do not init", K(ret)); + } else if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret)); + } else if (OB_FAIL(scheduler->check_dag_net_exist(task_id, is_exist))) { + LOG_WARN("failed to check dag net exist", K(ret), K(task_id)); + } else { +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = OB_E(EventTable::EN_CHECK_TRANSFER_TASK_EXSIT) OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_CHECK_TRANSFER_TASK_EXSIT", K(ret)); + is_exist = true; + ret = OB_SUCCESS; + } + } +#endif + + } + return ret; +} + +ERRSIM_POINT_DEF(EN_ERRSIM_ALLOW_TRANSFER_BACKFILL_TX); + +int ObTransferWorkerMgr::do_transfer_backfill_tx_(const ObTransferBackfillTXParam ¶m) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer worker do not init", K(ret)); + } else if (!param.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("transfer backfill tx parameter is invalid", K(ret), K(param)); + } else { + DEBUG_SYNC(TRANSFER_BACKFILL_TX_BEFORE); +#ifdef ERRSIM + common::ObAddr addr; + ret = EN_ERRSIM_ALLOW_TRANSFER_BACKFILL_TX ? : OB_SUCCESS; + char errsim_server_addr[OB_MAX_SERVER_ADDR_SIZE] = ""; + if (OB_FAIL(GCONF.errsim_transfer_backfill_server_addr.copy(errsim_server_addr, sizeof(errsim_server_addr)))) { + LOG_WARN("failed to copy errrsim transfer backfill server addr", K(ret)); + } else if (0 == strlen(errsim_server_addr)) { + // do nothing + } else if (OB_FAIL(addr.parse_from_string(errsim_server_addr))) { + LOG_WARN("failed to parse from string", K(ret), K(errsim_server_addr)); + } else if (GCTX.self_addr() == addr) { + ret = OB_EAGAIN; + LOG_WARN("errsim forbid execute transfer backfill", K(ret), K(addr)); + } +#endif + share::ObTenantDagScheduler *scheduler = nullptr; + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret), KP(scheduler)); + } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m))) { + LOG_WARN("failed to create and add transfer backfill tx dag net", K(ret), K(param)); + } else { + LOG_INFO("[TRANSFER_BACKFILL]success to create transfer backfill tx dag net", K(ret), K(param)); + } + } + return ret; +} + + +/******************ObTransferBackfillTXCtx*********************/ +ObTransferBackfillTXCtx::ObTransferBackfillTXCtx() + : ObIHADagNetCtx(), + tenant_id_(OB_INVALID_TENANT_ID), + task_id_(), + src_ls_id_(), + dest_ls_id_(), + backfill_scn_(), + tablet_ids_() +{ +} + +ObTransferBackfillTXCtx::~ObTransferBackfillTXCtx() +{ +} + +bool ObTransferBackfillTXCtx::is_valid() const +{ + return OB_INVALID_TENANT_ID != tenant_id_ + && !task_id_.is_invalid() + && src_ls_id_.is_valid() + && dest_ls_id_.is_valid() + && backfill_scn_.is_valid() + && !tablet_ids_.empty(); +} + +void ObTransferBackfillTXCtx::reset() +{ + tenant_id_ = OB_INVALID_TENANT_ID; + task_id_.reset(); + src_ls_id_.reset(); + dest_ls_id_.reset(); + backfill_scn_.reset(); + tablet_ids_.reset(); + ObIHADagNetCtx::reset(); +} + +int ObTransferBackfillTXCtx::fill_comment(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + + if (!is_valid()) { + ret = OB_NOT_INIT; + LOG_WARN("transfer backfill TX ctx do not init", K(ret)); + } else if (NULL == buf || buf_len <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(buf), K(buf_len)); + } else if (OB_FAIL(databuff_printf(buf, buf_len, pos, "transfer backfill TX :tenant_id = %s, task_id = %s, " + "src_ls_id = %s, dest_ls_id = %s, transfer_scn = %s", to_cstring(tenant_id_), + to_cstring(task_id_), to_cstring(src_ls_id_), to_cstring(dest_ls_id_), to_cstring(backfill_scn_)))) { + LOG_WARN("failed to set comment", K(ret), K(buf), K(pos), K(buf_len)); + } + return ret; +} + +void ObTransferBackfillTXCtx::reuse() +{ + ObIHADagNetCtx::reuse(); + backfill_scn_.reset(); + tablet_ids_.reset(); +} + +/******************ObTransferBackfillTXParam*********************/ +ObTransferBackfillTXParam::ObTransferBackfillTXParam() + : tenant_id_(OB_INVALID_TENANT_ID), + task_id_(), + src_ls_id_(), + dest_ls_id_(), + backfill_scn_(), + tablet_ids_() +{ +} + +bool ObTransferBackfillTXParam::is_valid() const +{ + return OB_INVALID_TENANT_ID != tenant_id_ + && src_ls_id_.is_valid() + && dest_ls_id_.is_valid() + && !task_id_.is_invalid() + && backfill_scn_.is_valid() + && !tablet_ids_.empty(); +} + +void ObTransferBackfillTXParam::reset() +{ + tenant_id_ = OB_INVALID_TENANT_ID; + task_id_.reset(); + src_ls_id_.reset(); + dest_ls_id_.reset(); + backfill_scn_.reset(); + tablet_ids_.reset(); +} + +/******************ObTransferBackfillTXDagNet*********************/ +ObTransferBackfillTXDagNet::ObTransferBackfillTXDagNet() + : ObIDagNet(ObDagNetType::DAG_NET_TRANSFER_BACKFILL_TX), + is_inited_(false), + ctx_() +{ +} + +ObTransferBackfillTXDagNet::~ObTransferBackfillTXDagNet() +{ +} + +int ObTransferBackfillTXDagNet::init_by_param(const ObIDagInitParam *param) +{ + int ret = OB_SUCCESS; + const ObTransferBackfillTXParam* init_param = static_cast(param); + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("transfer backfill tx dag net is init twice", K(ret)); + } else if (OB_ISNULL(param) || !param->is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("param is null or invalid", K(ret), KPC(init_param)); + } else if (OB_FAIL(this->set_dag_id(init_param->task_id_))) { + LOG_WARN("failed to set dag id", K(ret), KPC(init_param)); + } else if (OB_FAIL(ctx_.tablet_ids_.assign(init_param->tablet_ids_))) { + LOG_WARN("failed to set transfer tablet list", K(ret), KPC(init_param)); + } else { + ctx_.tenant_id_ = init_param->tenant_id_; + ctx_.task_id_ = init_param->task_id_; + ctx_.src_ls_id_ = init_param->src_ls_id_; + ctx_.dest_ls_id_ = init_param->dest_ls_id_; + ctx_.backfill_scn_ = init_param->backfill_scn_; + is_inited_ = true; + } + return ret; +} + +bool ObTransferBackfillTXDagNet::is_valid() const +{ + return ctx_.is_valid(); +} + +int ObTransferBackfillTXDagNet::start_running() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer backfill tx dag net do not init", K(ret)); + } else if (OB_FAIL(start_running_for_backfill_())) { + LOG_WARN("failed to start running for transfer backfill tx", K(ret)); + } + + return ret; +} + +int ObTransferBackfillTXDagNet::start_running_for_backfill_() +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObStartTransferBackfillTXDag *backfill_tx_dag = nullptr; + ObTransferReplaceTableDag *replace_logical_dag = nullptr; + share::ObTenantDagScheduler *scheduler = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer backfill tx dag net do not init", K(ret)); + } else if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret)); + } else if (OB_FAIL(scheduler->alloc_dag(backfill_tx_dag))) { + LOG_WARN("failed to alloc transfer backfill tx dag ", K(ret)); + } else if (OB_FAIL(scheduler->alloc_dag(replace_logical_dag))) { + LOG_WARN("failed to alloc replace logical dag ", K(ret)); + } else if (OB_FAIL(backfill_tx_dag->init(this))) { + LOG_WARN("failed to init transfer backfill tx dag", K(ret)); + } else if (OB_FAIL(add_dag_into_dag_net(*backfill_tx_dag))) { + LOG_WARN("failed to add transfer backfill tx dag into dag net", K(ret)); + } else if (OB_FAIL(backfill_tx_dag->create_first_task())) { + LOG_WARN("failed to create transfer backfill tx first task", K(ret)); + } else if (OB_FAIL(replace_logical_dag->init(this))) { + LOG_WARN("failed to init replace logical dag", K(ret)); + } else if (OB_FAIL(backfill_tx_dag->add_child(*replace_logical_dag))) { + LOG_WARN("failed to add child into transfer backfill tx", K(ret)); + } else if (OB_FAIL(replace_logical_dag->create_first_task())) { + LOG_WARN("failed to create replace logical first task", K(ret)); + } else if (OB_FAIL(scheduler->add_dag(replace_logical_dag))) { + LOG_WARN("failed to add transfer backfill tx dag into scheduer", K(ret), K(*replace_logical_dag)); + if (OB_SIZE_OVERFLOW != ret && OB_EAGAIN != ret) { + LOG_WARN("Fail to add task", K(ret)); + ret = OB_EAGAIN; + } + } else if (OB_FAIL(scheduler->add_dag(backfill_tx_dag))) { + LOG_WARN("failed to add backfill dag", K(ret), K(*backfill_tx_dag)); + if (OB_SIZE_OVERFLOW != ret && OB_EAGAIN != ret) { + LOG_WARN("Fail to add task", K(ret)); + ret = OB_EAGAIN; + } + if (OB_NOT_NULL(replace_logical_dag)) { + if (OB_SUCCESS != (tmp_ret = scheduler->cancel_dag(replace_logical_dag, backfill_tx_dag))) { + LOG_WARN("failed to cancel replace logical dag", K(tmp_ret), KPC(backfill_tx_dag)); + } else { + replace_logical_dag = nullptr; + } + } + } else { + FLOG_INFO("[TRANSFER_BACKFILL]succeed to schedule transfer backfill tx dag", K(*backfill_tx_dag), K(*replace_logical_dag)); + backfill_tx_dag = nullptr; + replace_logical_dag = nullptr; + } + + + if (OB_NOT_NULL(backfill_tx_dag) && OB_NOT_NULL(scheduler)) { + if (OB_SUCCESS != (tmp_ret = erase_dag_from_dag_net(*backfill_tx_dag))) { + LOG_WARN("failed to erase dag from dag net", K(tmp_ret), KPC(backfill_tx_dag)); + } + scheduler->free_dag(*backfill_tx_dag); + backfill_tx_dag = nullptr; + } + + if (OB_NOT_NULL(replace_logical_dag) && OB_NOT_NULL(scheduler)) { + scheduler->free_dag(*replace_logical_dag); + replace_logical_dag = nullptr; + } + + return ret; +} + +bool ObTransferBackfillTXDagNet::operator == (const ObIDagNet &other) const +{ + bool is_same = true; + if (this == &other) { + // same + } else if (this->get_type() != other.get_type()) { + is_same = false; + } else { + const ObTransferBackfillTXDagNet &other_dag_net = static_cast(other); + if (!is_valid() || !other_dag_net.is_valid()) { + is_same = false; + LOG_ERROR_RET(OB_ERR_SYS, "transfer backfill tx dag net is invalid", K(*this), K(other)); + } else if (ctx_.tenant_id_ != other_dag_net.ctx_.tenant_id_ + || ctx_.dest_ls_id_ != other_dag_net.ctx_.dest_ls_id_) { + is_same = false; + } + } + return is_same; +} + +int64_t ObTransferBackfillTXDagNet::hash() const +{ + int64_t hash_value = 0; + + const int64_t type = ObDagNetType::DAG_NET_TRANSFER_BACKFILL_TX; + hash_value = common::murmurhash(&type, sizeof(type), hash_value); + hash_value = common::murmurhash(&ctx_.tenant_id_, sizeof(ctx_.tenant_id_), hash_value); + hash_value += ctx_.dest_ls_id_.hash(); + + return hash_value; +} + +int ObTransferBackfillTXDagNet::fill_comment(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + const int64_t MAX_TRACE_ID_LENGTH = 64; + char task_id_str[MAX_TRACE_ID_LENGTH] = { 0 }; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer backfill tx dag net do not init ", K(ret)); + } else if (OB_FAIL(ctx_.task_id_.to_string(task_id_str, MAX_TRACE_ID_LENGTH))) { + LOG_WARN("failed to trace task id to string", K(ret), K(ctx_)); + } else if (OB_FAIL(databuff_printf(buf, buf_len, + "ObTransferBackfillTXDagNet: tenant_id=%s, src_ls_id=%s, dest_ls_id=%s, trace_id=%s, start_scn=%s", + to_cstring(ctx_.tenant_id_), to_cstring(ctx_.src_ls_id_), to_cstring(ctx_.dest_ls_id_), + task_id_str, to_cstring(ctx_.backfill_scn_)))) { + LOG_WARN("failed to fill comment", K(ret), K(ctx_)); + } + return ret; +} + +int ObTransferBackfillTXDagNet::fill_dag_net_key(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer backfill tx dag net do not init", K(ret)); + } else if (OB_FAIL(databuff_printf(buf, buf_len, + "ObTransferBackfillTXDagNet: tenant_id=%s, src_ls_id = %s, dest_ls_id = %s, task_id=%s, start_scn=%s", + to_cstring(ctx_.tenant_id_), to_cstring(ctx_.src_ls_id_), to_cstring(ctx_.dest_ls_id_), + to_cstring(ctx_.task_id_),to_cstring(ctx_.backfill_scn_)))) { + LOG_WARN("failed to fill comment", K(ret), K(ctx_)); + } + return ret; +} + +int ObTransferBackfillTXDagNet::clear_dag_net_ctx() +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObTransferService *transfer_service = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer backfill tx dag net do not init", K(ret)); + } else if (OB_ISNULL(transfer_service = (MTL(ObTransferService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer service should not be NULL", K(ret), KP(transfer_service)); + } else { + transfer_service->wakeup(); + } + return ret; +} + +/******************ObBaseTransferBackfillTXDag*********************/ +ObBaseTransferBackfillTXDag::ObBaseTransferBackfillTXDag(const share::ObDagType::ObDagTypeEnum &dag_type) + : ObStorageHADag(dag_type) +{ +} + +ObBaseTransferBackfillTXDag::~ObBaseTransferBackfillTXDag() +{ +} + +int ObBaseTransferBackfillTXDag::prepare_ctx(share::ObIDagNet *dag_net) +{ + int ret = OB_SUCCESS; + ObTransferBackfillTXDagNet *backfill_dag_net = nullptr; + ObTransferBackfillTXCtx *self_ctx = nullptr; + + if (OB_ISNULL(dag_net)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag net should not be NULL", K(ret), KP(dag_net)); + } else if (ObDagNetType::DAG_NET_TRANSFER_BACKFILL_TX != dag_net->get_type()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag net type is unexpected", K(ret), KPC(dag_net)); + } else if (FALSE_IT(backfill_dag_net = static_cast(dag_net))) { + } else if (FALSE_IT(self_ctx = backfill_dag_net->get_ctx())) { + } else if (OB_ISNULL(self_ctx)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer backfill tx dag net ctx should not be NULL", K(ret), KP(self_ctx)); + } else { + ha_dag_net_ctx_ = self_ctx; + } + return ret; +} + +bool ObBaseTransferBackfillTXDag::operator == (const ObIDag &other) const +{ + bool is_same = true; + if (this == &other) { + // same + } else if (get_type() != other.get_type()) { + is_same = false; + } else { + const ObStorageHADag &ha_dag = static_cast(other); + if (OB_ISNULL(ha_dag_net_ctx_) || OB_ISNULL(ha_dag.get_ha_dag_net_ctx())) { + is_same = false; + LOG_ERROR_RET(OB_INVALID_ARGUMENT, "transfer backfill tx ctx should not be NULL", KP(ha_dag_net_ctx_), KP(ha_dag.get_ha_dag_net_ctx())); + } else if (ha_dag_net_ctx_->get_dag_net_ctx_type() != ha_dag.get_ha_dag_net_ctx()->get_dag_net_ctx_type()) { + is_same = false; + } else { + ObTransferBackfillTXCtx *self_ctx = static_cast(ha_dag_net_ctx_); + ObTransferBackfillTXCtx *other_ctx = static_cast(ha_dag.get_ha_dag_net_ctx()); + if (self_ctx->tenant_id_ != other_ctx->tenant_id_ + || self_ctx->dest_ls_id_ != other_ctx->dest_ls_id_) { + is_same = false; + } + } + } + return is_same; +} + +int64_t ObBaseTransferBackfillTXDag::hash() const +{ + int ret = OB_SUCCESS; + int64_t hash_value = 0; + if (OB_ISNULL(ha_dag_net_ctx_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("transfer backfill tx ctx should not be NULL", KP(ha_dag_net_ctx_)); + } else if (ObIHADagNetCtx::TRANSFER_BACKFILL_TX != ha_dag_net_ctx_->get_dag_net_ctx_type()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ha dag net ctx type is unexpected", K(ret), KPC(ha_dag_net_ctx_)); + } else { + ObTransferBackfillTXCtx *self_ctx = static_cast(ha_dag_net_ctx_); + ObDagType::ObDagTypeEnum dag_type = get_type(); + hash_value = common::murmurhash(&dag_type, sizeof(dag_type), hash_value); + hash_value = common::murmurhash(&self_ctx->tenant_id_, sizeof(self_ctx->tenant_id_), hash_value); + hash_value += self_ctx->dest_ls_id_.hash(); + } + return hash_value; +} + +/*****************************************************************/ +ObStartTransferBackfillTXDag::ObStartTransferBackfillTXDag() + : ObBaseTransferBackfillTXDag(ObDagType::DAG_TYPE_TRANSFER_BACKFILL_TX), + is_inited_(false) +{ +} + +ObStartTransferBackfillTXDag::~ObStartTransferBackfillTXDag() +{ +} + +int ObStartTransferBackfillTXDag::fill_dag_key(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + ObTransferBackfillTXCtx *self_ctx = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("start backfill tx dag do not init", K(ret)); + } else if (ObIHADagNetCtx::TRANSFER_BACKFILL_TX != ha_dag_net_ctx_->get_dag_net_ctx_type()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ha dag net ctx type is unexpected", K(ret), KPC(ha_dag_net_ctx_)); + } else if (FALSE_IT(self_ctx = static_cast(ha_dag_net_ctx_))) { + } else if (OB_FAIL(databuff_printf(buf, buf_len, + "ObStartTransferBackfillTXDag: tenant_id=%s, ls_id=%s, task_id=%s, start_scn=%s", + to_cstring(self_ctx->tenant_id_), to_cstring(self_ctx->src_ls_id_), + to_cstring(self_ctx->task_id_),to_cstring(self_ctx->backfill_scn_)))) { + LOG_WARN("failed to fill comment", K(ret), K(*self_ctx)); + } + return ret; +} + +int ObStartTransferBackfillTXDag::init(ObIDagNet *dag_net) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("start transfer backfill tx dag init twice", K(ret)); + } else if (OB_ISNULL(dag_net)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("dag_net is NULL", K(ret)); + } else if (OB_FAIL(prepare_ctx(dag_net))) { + LOG_WARN("failed to prepare ctx", K(ret)); + } else { + is_inited_ = true; + } + return ret; +} + +int ObStartTransferBackfillTXDag::create_first_task() +{ + int ret = OB_SUCCESS; + ObStartTransferBackfillTXTask *task = NULL; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("start transfer backfill tx dag do not init", K(ret)); + } else if (OB_FAIL(alloc_task(task))) { + LOG_WARN("Fail to alloc task", K(ret)); + } else if (OB_FAIL(task->init())) { + LOG_WARN("failed to init start backfill tx task", K(ret), KPC(ha_dag_net_ctx_)); + } else if (OB_FAIL(add_task(*task))) { + LOG_WARN("fail to add ObStartTransferBackfillTXTask", K(ret)); + } else { + LOG_INFO("[TRANSFER_BACKFILL]success to create first ObStartTransferBackfillTXTask", K(ret), KPC(this)); + } + return ret; +} + +int ObStartTransferBackfillTXDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + ObTransferBackfillTXCtx *ctx = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("start transfer backfill tx dag do not init", K(ret)); + } else if (FALSE_IT(ctx = static_cast(ha_dag_net_ctx_))) { + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(ctx->tenant_id_), + ctx->src_ls_id_.id(), + static_cast(ctx->backfill_scn_.get_val_for_inner_table_field()), + "dag_net_task_id", to_cstring(ctx->task_id_)))){ + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} + +/******************ObStartTransferBackfillTXTask*********************/ +ObStartTransferBackfillTXTask::ObStartTransferBackfillTXTask() + : ObITask(TASK_TYPE_TRANSFER_BACKFILL_TX), + is_inited_(false), + ctx_(nullptr), + dag_net_(nullptr) +{ +} + +ObStartTransferBackfillTXTask::~ObStartTransferBackfillTXTask() +{ +} + +int ObStartTransferBackfillTXTask::init() +{ + int ret = OB_SUCCESS; + ObIDagNet *dag_net = nullptr; + ObTransferBackfillTXDagNet *backfill_dag_net = nullptr; + + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("start transfer backfill tx task init twice", K(ret)); + } else if (FALSE_IT(dag_net = this->get_dag()->get_dag_net())) { + } else if (OB_ISNULL(dag_net)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag net should not be NULL", K(ret), KP(dag_net)); + } else if (ObDagNetType::DAG_NET_TRANSFER_BACKFILL_TX != dag_net->get_type()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag net type is unexpected", K(ret), KPC(dag_net)); + } else if (FALSE_IT(backfill_dag_net = static_cast(dag_net))) { + } else { + ctx_ = backfill_dag_net->get_ctx(); + is_inited_ = true; + LOG_INFO("[TRANSFER_BACKFILL]succeed init transfer backfill tx task", "ls id", ctx_->src_ls_id_, + "dag_id", *ObCurTraceId::get_trace_id(), "dag_net_id", ctx_->task_id_); + } + return ret; +} + + +int ObStartTransferBackfillTXTask::process() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("start transfer backfill tx task do not init", K(ret)); + } else if (ctx_->is_failed()) { + //do nothing + } else if (OB_FAIL(generate_transfer_backfill_tx_dags_())) { + LOG_WARN("failed to generate transfer backfill tx dags", K(ret), KPC(ctx_)); + } + + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = ObStorageHADagUtils::deal_with_fo(ret, this->get_dag()))) { + LOG_WARN("failed to deal with fo", K(ret), K(tmp_ret), KPC(ctx_)); + } + } + return ret; +} + +int ObStartTransferBackfillTXTask::generate_transfer_backfill_tx_dags_() +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObTabletBackfillTXDag *tablet_backfill_tx_dag = nullptr; + ObFinishBackfillTXDag *finish_backfill_tx_dag = nullptr; + ObTenantDagScheduler *scheduler = nullptr; + ObIDagNet *dag_net = nullptr; + ObBackfillTXCtx *backfill_tx_ctx = nullptr; + ObTabletID tablet_id; + ObStartTransferBackfillTXDag *backfill_tx_dag = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("start transfer backfill tx task do not init", K(ret)); + } else if (!(ObDagType::DAG_TYPE_TRANSFER_BACKFILL_TX <= this->get_dag()->get_type() + && ObDagType::DAG_TYPE_TRANSFER_REPLACE_TABLE >= this->get_dag()->get_type())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag type is not match", K(ret), KP(this->get_dag())); + } else if (OB_ISNULL(backfill_tx_dag = static_cast(this->get_dag()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("start transfer backfill tx dag should not be NULL", K(ret), KP(backfill_tx_dag)); + } else if (OB_ISNULL(dag_net = backfill_tx_dag->get_dag_net())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag net should not be NULL", K(ret), KP(dag_net)); + } else if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret)); + } else { + if (OB_FAIL(scheduler->alloc_dag(finish_backfill_tx_dag))) { + LOG_WARN("failed to alloc finish backfill tx transfer dag ", K(ret)); + } else if (OB_FAIL(finish_backfill_tx_dag->init(ctx_->task_id_, ctx_->src_ls_id_, ctx_->backfill_scn_, ctx_->tablet_ids_, ctx_))) { + LOG_WARN("failed to init data tablets transfer dag", K(ret), K(*ctx_)); + } else if (OB_ISNULL(backfill_tx_ctx = finish_backfill_tx_dag->get_backfill_tx_ctx())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("backfill tx ctx should not be NULL", K(ret), KP(backfill_tx_ctx)); + } else if (backfill_tx_ctx->is_empty()) { + if (OB_FAIL(this->get_dag()->add_child(*finish_backfill_tx_dag))) { + LOG_WARN("failed to add finish backfill tx dag as chilid", K(ret), K(*ctx_)); + } + } else { + if (OB_FAIL(backfill_tx_ctx->get_tablet_id(tablet_id))) { + LOG_WARN("failed to get tablet id", K(ret), KPC(ctx_)); + } else if (OB_FAIL(scheduler->alloc_dag(tablet_backfill_tx_dag))) { + LOG_WARN("failed to alloc tablet backfill tx dag ", K(ret)); + } else if (OB_FAIL(tablet_backfill_tx_dag->init(ctx_->task_id_, ctx_->src_ls_id_, tablet_id, ctx_, backfill_tx_ctx))) { + LOG_WARN("failed to init tablet backfill tx dag", K(ret), K(*ctx_)); + } else if (OB_FAIL(this->get_dag()->add_child(*tablet_backfill_tx_dag))) { + LOG_WARN("failed to add tablet backfill tx dag as chilid", K(ret), K(*ctx_)); + } else if (OB_FAIL(tablet_backfill_tx_dag->create_first_task())) { + LOG_WARN("failed to create first task", K(ret)); + } else if (OB_FAIL(tablet_backfill_tx_dag->add_child(*finish_backfill_tx_dag))) { + LOG_WARN("failed to add child dag", K(ret), K(*ctx_)); + } else if (OB_FAIL(scheduler->add_dag(tablet_backfill_tx_dag))) { + LOG_WARN("failed to add tablet backfill tx dag", K(ret), K(*tablet_backfill_tx_dag)); + if (OB_SIZE_OVERFLOW != ret && OB_EAGAIN != ret) { + LOG_WARN("Fail to add task", K(ret)); + ret = OB_EAGAIN; + } + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(finish_backfill_tx_dag->create_first_task())) { + LOG_WARN("failed to create first task", K(ret)); + } else if (OB_FAIL(scheduler->add_dag(finish_backfill_tx_dag))) { + LOG_WARN("failed to add finish backfill tx dag", K(ret), K(*finish_backfill_tx_dag)); + if (OB_SIZE_OVERFLOW != ret && OB_EAGAIN != ret) { + LOG_WARN("Fail to add task", K(ret)); + ret = OB_EAGAIN; + } + + if (OB_NOT_NULL(tablet_backfill_tx_dag)) { + if (OB_SUCCESS != (tmp_ret = scheduler->cancel_dag(tablet_backfill_tx_dag, backfill_tx_dag))) { + LOG_WARN("failed to cancel tablet backfill tx dag", K(tmp_ret), KPC(backfill_tx_dag)); + } else { + tablet_backfill_tx_dag = nullptr; + } + } + } else { + LOG_INFO("[TRANSFER_BACKFILL]succeed to schedule tablet backfill tx dag and finish backfill tx dag", + KPC(tablet_backfill_tx_dag), KPC(finish_backfill_tx_dag)); + tablet_backfill_tx_dag = nullptr; + finish_backfill_tx_dag = nullptr; + } + + if (OB_FAIL(ret)) { + if (OB_NOT_NULL(tablet_backfill_tx_dag)) { + scheduler->free_dag(*tablet_backfill_tx_dag, backfill_tx_dag); + tablet_backfill_tx_dag = nullptr; + } + + if (OB_NOT_NULL(finish_backfill_tx_dag)) { + scheduler->free_dag(*finish_backfill_tx_dag, backfill_tx_dag); + finish_backfill_tx_dag = nullptr; + } + } + } + return ret; +} + +/*****************ObTransferReplaceTableDag***********************/ +ObTransferReplaceTableDag::ObTransferReplaceTableDag() + : ObBaseTransferBackfillTXDag(ObDagType::DAG_TYPE_TRANSFER_REPLACE_TABLE), + is_inited_(false) +{ +} + +ObTransferReplaceTableDag::~ObTransferReplaceTableDag() +{ +} + +int ObTransferReplaceTableDag::fill_dag_key(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + ObTransferBackfillTXCtx *self_ctx = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer replace tables dag do not init", K(ret)); + } else if (ObIHADagNetCtx::TRANSFER_BACKFILL_TX != ha_dag_net_ctx_->get_dag_net_ctx_type()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ha dag net ctx type is unexpected", K(ret), KPC(ha_dag_net_ctx_)); + } else if (FALSE_IT(self_ctx = static_cast(ha_dag_net_ctx_))) { + } else if (OB_FAIL(databuff_printf(buf, buf_len, + "ObTransferReplaceTableDag: ls_id = %s", + to_cstring(self_ctx->dest_ls_id_)))) { + LOG_WARN("failed to fill comment", K(ret), K(*self_ctx)); + } + return ret; +} + +int ObTransferReplaceTableDag::init(ObIDagNet *dag_net) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("transfer replace tables dag init twice", K(ret)); + } else if (OB_ISNULL(dag_net)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("dag net is NULL", K(ret)); + } else if (OB_FAIL(prepare_ctx(dag_net))) { + LOG_WARN("failed to prepare ctx", K(ret)); + } else { + is_inited_ = true; + } + return ret; +} + +int ObTransferReplaceTableDag::create_first_task() +{ + int ret = OB_SUCCESS; + ObTransferReplaceTableTask *task = NULL; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer replace tables dag do not init", K(ret)); + } else if (OB_FAIL(alloc_task(task))) { + LOG_WARN("Fail to alloc task", K(ret)); + } else if (OB_FAIL(task->init())) { + LOG_WARN("failed to init transfer replace tables task", K(ret), KPC(ha_dag_net_ctx_)); + } else if (OB_FAIL(add_task(*task))) { + LOG_WARN("fail to add ObTransferReplaceTableTask", K(ret)); + } else { + LOG_INFO("[TRANSFER_BACKFILL]success to create first ObTransferReplaceTableTask", K(ret), KPC(this)); + } + return ret; +} + +int ObTransferReplaceTableDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + ObTransferBackfillTXCtx *ctx = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("start transfer backfill tx dag do not init", K(ret)); + } else if (FALSE_IT(ctx = static_cast(ha_dag_net_ctx_))) { + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(ctx->tenant_id_), + ctx->dest_ls_id_.id(), + "dag_net_task_id", to_cstring(ctx->task_id_)))){ + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} + +bool ObTransferReplaceTableDag::check_can_retry() +{ + return false; +} + +/******************ObTransferReplaceTableTask*********************/ +ObTransferReplaceTableTask::ObTransferReplaceTableTask() + : ObITask(TASK_TYPE_TRANSFER_REPLACE_TABLE), + is_inited_(false), + ctx_(nullptr) +{ +} + +ObTransferReplaceTableTask::~ObTransferReplaceTableTask() +{ +} + +int ObTransferReplaceTableTask::init() +{ + int ret = OB_SUCCESS; + ObIDagNet *dag_net = nullptr; + ObTransferBackfillTXDagNet *backfill_dag_net = nullptr; + + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("transfer replace tables task init twice", K(ret)); + } else if (FALSE_IT(dag_net = this->get_dag()->get_dag_net())) { + } else if (OB_ISNULL(dag_net)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag net should not be NULL", K(ret), KP(dag_net)); + } else if (ObDagNetType::DAG_NET_TRANSFER_BACKFILL_TX != dag_net->get_type()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag net type is unexpected", K(ret), KPC(dag_net)); + } else if (FALSE_IT(backfill_dag_net = static_cast(dag_net))) { + } else { + ctx_ = backfill_dag_net->get_ctx(); + is_inited_ = true; + LOG_INFO("[TRANSFER_BACKFILL]succeed init transfer replace tables task", "ls id", ctx_->dest_ls_id_, + "dag_id", *ObCurTraceId::get_trace_id(), "dag_net_id", ctx_->task_id_); + } + return ret; +} +int ObTransferReplaceTableTask::check_src_memtable_is_empty_( + ObTablet *tablet, + const share::SCN &transfer_scn) +{ + int ret = OB_SUCCESS; + ObArray memtables; + ObIMemtableMgr *memtable_mgr = nullptr; + if (OB_ISNULL(tablet) || !transfer_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet should not be nullptr.", KR(ret), K(transfer_scn), KPC(this)); + } else if (OB_ISNULL(memtable_mgr = tablet->get_memtable_mgr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable mgr should not be NULL", K(ret), KP(memtable_mgr)); + } else if (OB_FAIL(memtable_mgr->get_all_memtables(memtables))) { + LOG_WARN("failed to get all memtables", K(ret), KPC(tablet)); + } else if (!memtables.empty()) { + for (int64_t i = 0; OB_SUCC(ret) && i < memtables.count(); ++i) { + ObITable *table = memtables.at(i).get_table(); + memtable::ObMemtable *memtable = static_cast(table); + if (OB_ISNULL(table) || !table->is_memtable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table should not be NULL or table type is unexpected", K(ret), KP(table)); + } else if (memtable->is_active_memtable()) { + if (memtable->not_empty()) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("memtable should not be active", K(ret), KPC_(ctx), + KPC(memtable), "transfer meta", tablet->get_tablet_meta()); + } + } else if (!memtable->get_key().scn_range_.is_empty()) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("The range of the memtable is not empty", K(ret), KPC(memtable)); + } else if (memtable->not_empty() + && memtable->get_start_scn() >= transfer_scn) { + LOG_ERROR("There have been transactions in memtable but no data", K(OB_TRANSFER_SYS_ERROR), KPC_(ctx), KPC(memtable)); + } + } + } + + return ret; +} + +int ObTransferReplaceTableTask::check_source_minor_end_scn_( + const ObTabletMemberWrapper &wrapper, + const ObTablet *dest_tablet, + bool &need_fill_minor) +{ + int ret = OB_SUCCESS; + + need_fill_minor = false; + + if (!wrapper.is_valid() || OB_ISNULL(dest_tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wrapper is invalid or tablet be nullptr.", KR(ret), K(wrapper), KPC(this)); + } else { + const ObTabletTableStore &table_store = *(wrapper.get_member()); + ObITable *last_minor_mini_sstable = table_store.get_minor_sstables().get_boundary_table(true /*is_last*/); + + if (OB_ISNULL(last_minor_mini_sstable)) { + LOG_INFO("[TRANSFER_BACKFILL]minor sstable no exists", K(ret), KPC(this), K(table_store)); + } else if (!last_minor_mini_sstable->is_minor_sstable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("last sstable type is incorrect", K(ret), KPC(last_minor_mini_sstable)); + } else if (last_minor_mini_sstable->get_end_scn() < dest_tablet->get_tablet_meta().transfer_info_.transfer_start_scn_) { + need_fill_minor = true; + LOG_INFO("[TRANSFER_BACKFILL]need fill empty minor sstable", "end scn", last_minor_mini_sstable->get_end_scn(), + "transfer info", dest_tablet->get_tablet_meta().transfer_info_); + } else if (last_minor_mini_sstable->get_start_scn() >= dest_tablet->get_tablet_meta().transfer_info_.transfer_start_scn_) { + ObSSTable *sstable = static_cast(last_minor_mini_sstable); + if (!sstable->is_empty()) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("last sstable start scn is bigger than transfer start scn", K(ret), KPC(last_minor_mini_sstable), + "transfer info", dest_tablet->get_tablet_meta().transfer_info_); + } + } else if (last_minor_mini_sstable->get_end_scn() > dest_tablet->get_tablet_meta().transfer_info_.transfer_start_scn_) { + // After adding transfer_freeze_flag_, it can ensure that start is less than transfer_start_scn's sstable, + // and end_scn will not be greater than transfer_start_scn + LOG_ERROR("last sstable end scn is bigger than transfer start scn", K(OB_TRANSFER_SYS_ERROR), KPC(last_minor_mini_sstable), + "transfer info", dest_tablet->get_tablet_meta().transfer_info_); + } + } + return ret; +} + +int ObTransferReplaceTableTask::check_major_sstable_( + const ObTablet *tablet, + const ObTabletMemberWrapper &table_store_wrapper) +{ + int ret = OB_SUCCESS; + ObTableStoreIterator ddl_iter; + if (OB_ISNULL(tablet) || !table_store_wrapper.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("argumemt is invalid", K(ret), KP(tablet), K(table_store_wrapper)); + } else if (!table_store_wrapper.get_member()->get_major_sstables().empty()) { + // do nothing + } else if (OB_FAIL(tablet->get_ddl_sstables(ddl_iter))) { + LOG_WARN("failed to get ddl sstable", K(ret)); + } else if (ddl_iter.is_valid()) { + ret = OB_EAGAIN; + LOG_WARN("wait for ddl sstable to merge to generate major sstable", K(ret), K(ddl_iter)); + } else if (tablet->get_tablet_meta().ha_status_.is_restore_status_full()) { + ret = OB_INVALID_TABLE_STORE; + LOG_ERROR("neither major sstable nor ddl sstable exists", K(ret), K(ddl_iter)); + } + + return ret; +} + +int ObTransferReplaceTableTask::get_all_sstable_handles_( + const ObTablet *tablet, + const ObTabletMemberWrapper &wrapper, + ObTableStoreIterator &sstable_iter, + ObTablesHandleArray &sstable_handles) +{ + int ret = OB_SUCCESS; + ObTableHandleV2 table_handle; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer replace tables task do not init", K(ret)); + } else if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet should not be nullptr", K(ret)); + } else if (tablet->get_tablet_meta().ha_status_.is_restore_status_undefined() + || tablet->get_tablet_meta().ha_status_.is_restore_status_pending() + || tablet->get_tablet_meta().ha_status_.is_restore_status_empty()) { + ret = OB_ERR_UNEXPECTED;; + LOG_WARN("tablet data is incomplete, replacement should not be performed", K(ret), KP(tablet)); + } else if (OB_FAIL(check_major_sstable_(tablet, wrapper))) { + LOG_WARN("failed check major sstable", K(ret), KP(tablet)); + } else if (OB_FAIL(wrapper.get_member()->get_all_sstable(sstable_iter))) { + LOG_WARN("get all sstable fail", K(ret)); + } else { + while (OB_SUCC(ret) && OB_SUCC(sstable_iter.get_next(table_handle))) { + if (OB_UNLIKELY(!table_handle.is_valid() || !table_handle.get_table()->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, table is nullptr", K(ret), K(table_handle)); + } else if (OB_FAIL(sstable_handles.add_table(table_handle))) { + LOG_WARN("fail to fill sstable write info", K(ret), K(table_handle)); + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + } + return ret; +} + +// when the end_scn of the last minor sstable is less than transfer_start_scn, +// it need to fill in an empty minor to ensure the continuity of the sstable +int ObTransferReplaceTableTask::fill_empty_minor_sstable( + ObTablet *tablet, + bool need_fill_minor, + const share::SCN &end_scn, + const ObTabletMemberWrapper &wrapper, + common::ObArenaAllocator &table_allocator, + ObTablesHandleArray &tables_handle) +{ + int ret = OB_SUCCESS; + ObArenaAllocator allocator; + const ObStorageSchema *tablet_storage_schema = nullptr; + ObTableHandleV2 empty_minor_table_handle; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer replace tables task do not init", K(ret)); + } else if (!need_fill_minor) { + // do nothing + } else if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet is null", K(ret)); + } else { + const ObTabletTableStore &table_store = *(wrapper.get_member()); + ObITable *last_minor_mini_sstable = table_store.get_minor_sstables().get_boundary_table(true /*is_last*/); + share::SCN start_scn; + if (OB_ISNULL(last_minor_mini_sstable)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("minor sstable is not exit, no need backfill", K(ret)); + } else { + start_scn = last_minor_mini_sstable->get_end_scn(); + if (start_scn >= end_scn) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("start scn is bigger or equal than end scn", K(ret), K(start_scn), K(end_scn)); + } else if (OB_FAIL(tablet->load_storage_schema(allocator, tablet_storage_schema))) { + LOG_WARN("fail to load storage schema failed", K(ret)); + } else if (OB_FAIL(ObTXTransferUtils::create_empty_minor_sstable(tablet->get_tablet_meta().tablet_id_, start_scn, end_scn, + *tablet_storage_schema, table_allocator, empty_minor_table_handle))) { + LOG_WARN("failed to create empty minor sstable", K(ret), K(start_scn), K(end_scn)); + } else if (OB_FAIL(tables_handle.add_table(empty_minor_table_handle))) { + LOG_WARN("failed to add table", K(ret), K(empty_minor_table_handle)); + } else { + LOG_INFO("[TRANSFER_BACKFILL]succ fill empty minor sstable", K(ret), "tablet_id", tablet->get_tablet_meta().tablet_id_, + K(empty_minor_table_handle), K(start_scn), K(end_scn)); + } + ObTablet::free_storage_schema(allocator, tablet_storage_schema); + } + } + return ret; +} + +int ObTransferReplaceTableTask::get_source_tablet_tables_( + const ObTablet *dest_tablet, + const common::ObTabletID &tablet_id, + ObTableStoreIterator &sstable_iter, + ObTabletHandle &tablet_handle, + ObTabletHAStatus &ha_status, + common::ObArenaAllocator &allocator, + ObTablesHandleArray &tables_handle) +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + ObTablet *tablet = nullptr; + tables_handle.reset(); + ObTabletCreateDeleteMdsUserData src_user_data; + ObTabletCreateDeleteMdsUserData dest_user_data; + int64_t src_transfer_seq = 0; + int64_t dest_transfer_seq = 0; + bool need_backill = false; + share::SCN transfer_scn; + ObTabletMemberWrapper wrapper; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer replace tables task do not init", K(ret)); + } else if (OB_ISNULL(dest_tablet) || !tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet id is invalid", K(ret), K(tablet_id)); + } else if (FALSE_IT(transfer_scn = dest_tablet->get_tablet_meta().transfer_info_.transfer_start_scn_)) { + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ctx_->src_ls_id_, ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls", K(ret), "ls_id", ctx_->src_ls_id_); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), "ls_id", ctx_->src_ls_id_); + } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KPC(tablet)); + } else if (tablet->is_empty_shell()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer src tablet should not be empty shell", K(ret), KPC(tablet), "ls_id", ctx_->src_ls_id_); + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet_handle, src_user_data))) { + LOG_WARN("failed to get src user data", K(ret), K(tablet_handle), KPC(tablet)); + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, dest_tablet, dest_user_data))) { + LOG_WARN("failed to get src user data", K(ret), K(tablet_handle), KPC(tablet)); + } else if (FALSE_IT(src_transfer_seq = tablet->get_tablet_meta().transfer_info_.transfer_seq_)) { + } else if (FALSE_IT(dest_transfer_seq = dest_tablet->get_tablet_meta().transfer_info_.transfer_seq_)) { + } else if (src_transfer_seq > dest_transfer_seq) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("src tablet transfer_seq is not match dest tablet transfer_seq", K(ret), + KPC(tablet), KPC(dest_tablet), K(src_user_data), K(dest_user_data), K(src_transfer_seq), K(dest_transfer_seq)); + } else if (src_transfer_seq + 1 != dest_transfer_seq) { + ret = OB_EAGAIN; + LOG_WARN("need to wait for source LS replay", K(ret), KPC(tablet), + K(src_user_data), K(dest_user_data), K(src_transfer_seq), K(dest_transfer_seq)); + } else if (ObTabletStatus::TRANSFER_OUT != src_user_data.tablet_status_ + && ObTabletStatus::TRANSFER_OUT_DELETED != src_user_data.tablet_status_) { + ret = OB_UNEXPECTED_TABLET_STATUS; + LOG_WARN("tablet status should be TRANSFER_OUT or TRANSFER_OUT_DELETED", K(ret), KPC(tablet), K(src_user_data)); + } else if (FALSE_IT(ha_status = tablet->get_tablet_meta().ha_status_)) { + } else if (OB_FAIL(tablet->fetch_table_store(wrapper))) { + LOG_WARN("fetch table store fail", K(ret), KP(tablet)); + } else if (OB_FAIL(check_src_memtable_is_empty_(tablet, transfer_scn))) { + LOG_WARN("failed to check src memtable", K(ret), KPC(tablet)); + } else if (OB_FAIL(check_source_minor_end_scn_(wrapper, dest_tablet, need_backill))) { + LOG_WARN("fail to check source max end scn from tablet", K(ret), KPC(tablet)); + } else if (OB_FAIL(get_all_sstable_handles_(tablet, wrapper, sstable_iter, tables_handle))) { + LOG_WARN("failed to get all sstable handles", K(ret), KPC(tablet)); + } else if (OB_FAIL(fill_empty_minor_sstable(tablet, need_backill, + dest_tablet->get_tablet_meta().transfer_info_.transfer_start_scn_, wrapper, allocator, tables_handle))) { + LOG_WARN("failed to check src minor sstables", K(ret), KPC(tablet)); + } else if (OB_FAIL(check_src_tablet_sstables_(tablet, tables_handle))) { + LOG_WARN("failed to check src minor sstables", K(ret), KPC(tablet)); + } + return ret; +} + +int ObTransferReplaceTableTask::check_src_tablet_sstables_( + const ObTablet *tablet, + ObTablesHandleArray &tables_handle) +{ + int ret = OB_SUCCESS; + bool has_major_sstable = false; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("replace logical table task do not init", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tables_handle.get_count(); ++i) { + ObITable *table = tables_handle.get_table(i); + ObSSTable *sstable = nullptr; + if (OB_ISNULL(table) || !table->is_sstable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table should not be NULL or table type is unexpected", K(ret), KP(table)); + } else if (table->is_major_sstable()) { + has_major_sstable = true; + } else if (!table->is_minor_sstable()) { + //do nothing + } else { + sstable = static_cast(table); + if (sstable->contain_uncommitted_row()) { + if (table->get_end_scn() >= ctx_->backfill_scn_) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("src minor still has uncommitted row, unexpected", K(ret), KPC(sstable), KPC(ctx_)); + } else { + ret = OB_EAGAIN; + LOG_WARN("sstable has not yet backfilled transactions", K(ret), KPC(sstable), KPC(ctx_)); + } + } + } + } + if (OB_SUCC(ret)) { + if (tablet->get_tablet_meta().ha_status_.is_restore_status_full() && !has_major_sstable) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("major sstable is not exist ", K(ret), K(tables_handle)); + } + } + } + return ret; +} + +int ObTransferReplaceTableTask::check_tablet_after_replace_(ObLS *ls, const common::ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletMemberWrapper wrapper; + if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KPC(tablet)); + } else if (OB_FAIL(tablet->fetch_table_store(wrapper))) { + LOG_WARN("fetch table store fail", K(ret), KPC(tablet)); + } else if (tablet->get_tablet_meta().ha_status_.is_restore_status_full() + && wrapper.get_member()->get_major_sstables().empty()) { + // TODO(wangxiaohui.wxh), consider index tablet, major is generated when replay commit log. + // In case of restore, if restore status is FULL, major sstable must be exist after replace. + ret = OB_INVALID_TABLE_STORE; + LOG_WARN("tablet should be exist major sstable", K(ret), KPC(tablet)); + } else if (tablet->get_tablet_meta().has_transfer_table()) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_WARN("replace should be exist transfer table", K(ret), K(tablet->get_tablet_meta())); + } + + return ret; +} + +int ObTransferReplaceTableTask::transfer_replace_tables_( + ObLS *ls, + const common::ObTabletID &tablet_id, + const ObTablet *tablet) +{ + int ret = OB_SUCCESS; + common::ObArenaAllocator allocator("TransferTmpTab"); + ObMigrationStatus migration_status; + ObTabletMemberWrapper dest_wrapper; + ObTabletCreateDeleteMdsUserData user_data; + ObTabletHandle src_tablet_handle; + ObTableStoreIterator src_sstable_iter; + ObMigrationTabletParam mig_param; + ObBatchUpdateTableStoreParam param; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer replace tables task do not init", K(ret)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls should not be nullptr", K(ret)); + } else if (OB_FAIL(ls->get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), KPC(ls)); + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(ls)); + } else if (OB_FAIL(tablet->fetch_table_store(dest_wrapper))) { + LOG_WARN("failed to fetch table store", K(ret), KPC(tablet)); + } else if (!tablet->get_tablet_meta().has_transfer_table()) { + if (dest_wrapper.get_member()->get_major_sstables().empty()) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("There is no transfer table, but the tablet does not exist major sstable", + K(ret), K(user_data), "tablet_meta", tablet->get_tablet_meta()); + } else { + LOG_INFO("tablet already complete replace", K(ret), K(user_data), "tablet_meta", tablet->get_tablet_meta()); + } + } else if (!dest_wrapper.get_member()->get_major_sstables().empty()) { + ret = OB_INVALID_TABLE_STORE; + LOG_WARN("tablet should not exist major sstable", K(ret), KPC(tablet)); + } else if (OB_FAIL(get_source_tablet_tables_(tablet, tablet_id, src_sstable_iter, src_tablet_handle, param.ha_status_, allocator, param.tables_handle_))) { + LOG_WARN("failed to get source tablet tables", K(ret), K(tablet_id)); + } else if (OB_FAIL(build_migration_param_(tablet, src_tablet_handle, mig_param))) { + LOG_WARN("failed to build migration param", K(ret), KPC(tablet)); + } else { + param.rebuild_seq_ = ls->get_rebuild_seq(); + param.is_transfer_replace_ = true; + param.tablet_meta_ = &mig_param; + +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "TRANSFER_REPLACE_TABLE_WITH_LOG_REPLAY_SKIP_CHECK", + "dest_ls_id", ls->get_ls_id(), + "migration_status", migration_status, + "tablet_id", tablet_id.id(), + "tablet_status", ObTabletStatus::get_str(user_data.tablet_status_), + "has_transfer_table", tablet->get_tablet_meta().has_transfer_table()); +#endif + + if (FAILEDx(ls->build_ha_tablet_new_table_store(tablet_id, param))) { + LOG_WARN("failed to build ha tablet new table store", K(ret), K(param), K(tablet_id)); + } else if (OB_FAIL(check_tablet_after_replace_(ls, tablet_id))) { + LOG_WARN("failed to check tablet after replace", K(ret), K(param), K(tablet_id)); + } else { + LOG_INFO("[TRANSFER_BACKFILL]succ transfer replace tables", K(ret), K(param), K(tablet_id), KPC_(ctx)); + } +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "AFTER_TRANSFER_DUMP_MDS_TABLE"); +#endif + DEBUG_SYNC(AFTER_TRANSFER_DUMP_MDS_TABLE); + } + + return ret; +} + +int ObTransferReplaceTableTask::do_replace_logical_tables_(ObLS *ls) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + DEBUG_SYNC(TRANSFER_REPLACE_TABLE_BEFORE); + if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls is nullptr", K(ret)); + } else { + for (int i = 0; OB_SUCC(ret) && i < ctx_->tablet_ids_.count(); i++) { + user_data.reset(); + const common::ObTabletID tablet_id = ctx_->tablet_ids_.at(i); + bool in_migration = false; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + if (OB_FAIL(ls->get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), KPC(ls)); + } else if (FALSE_IT(in_migration = ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status)) { + } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KPC(tablet)); + } else if (tablet_id.is_ls_inner_tablet()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("inner tablet cannot transfer", KR(ret), K(tablet_id), KPC(this)); + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + LOG_WARN("failed to get tablet status", K(ret), K(tablet_handle)); + } else if (ObTabletStatus::TRANSFER_IN != user_data.tablet_status_ && !in_migration) { + ret = OB_UNEXPECTED_TABLET_STATUS; + LOG_WARN("tablet status should be TRANSFER_IN", K(ret), K(user_data), K(in_migration), KPC(tablet), KPC(ls)); + } else if (OB_FAIL(transfer_replace_tables_(ls, tablet_id, tablet))) { + LOG_WARN("failed to transfer replace tables", K(ret), K(tablet_id), KPC(ls), KPC(tablet), KPC(ctx_)); + } else { +#ifdef ERRSIM + SERVER_EVENT_ADD("TRANSFER", "REPLACE_LOGICAL_TABLE", + "task_id", ctx_->task_id_, + "tenant_id", ctx_->tenant_id_, + "src_ls_id", ctx_->src_ls_id_.id(), + "dest_ls_id", ctx_->dest_ls_id_.id(), + "tablet_id", tablet_id.id()); +#endif + } + } + } + return ret; +} + +int ObTransferReplaceTableTask::process() +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObLS *ls = nullptr; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer replace tables task do not init", K(ret)); + } else if (ctx_->is_failed()) { + LOG_INFO("[TRANSFER_BACKFILL]ctx already failed", KPC(ctx_), "tablet_list", ctx_->tablet_ids_); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ctx_->dest_ls_id_, ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls", K(ret), KPC(ctx_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), KPC(ctx_)); + } else if (OB_FAIL(do_replace_logical_tables_(ls))) { + LOG_WARN("failed to repalce logical tables", K(ret), KP(ls), KPC(ctx_), "tablet_list", ctx_->tablet_ids_); + } else { + LOG_INFO("[TRANSFER_BACKFILL]complete transfer replace task", K(ret), KPC(ctx_), "tablet_list", ctx_->tablet_ids_); + } + + if (OB_FAIL(ret)) { + if (OB_SUCCESS != (tmp_ret = ObStorageHADagUtils::deal_with_fo(ret, this->get_dag()))) { + LOG_WARN("failed to deal with fo", K(ret), K(tmp_ret), KPC(ctx_)); + } + } + return ret; +} + +int ObTransferReplaceTableTask::build_migration_param_( + const ObTablet *tablet, + ObTabletHandle &src_tablet_handle, + ObMigrationTabletParam ¶m) +{ + int ret = OB_SUCCESS; + param.reset(); + ObTablet *src_tablet = nullptr; + ObArenaAllocator allocator; + const ObStorageSchema *src_storage_schema = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer replace tables task do not init", K(ret)); + } else if (OB_ISNULL(tablet) || !src_tablet_handle.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("build migration param get invalid argument", K(ret), KP(tablet), K(src_tablet_handle)); + } else if (OB_FAIL(tablet->build_migration_tablet_param(param))) { + LOG_WARN("failed to build migration tablet param", K(ret), KPC(tablet)); + } else if (OB_ISNULL(src_tablet = src_tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src tablet should not be NULL", K(ret), KP(src_tablet)); + } else { + param.mds_data_.reset(); + param.storage_schema_.reset(); + param.snapshot_version_ = src_tablet->get_tablet_meta().snapshot_version_; + param.multi_version_start_ = src_tablet->get_tablet_meta().multi_version_start_; + + if (OB_FAIL(src_tablet->get_fused_medium_info_list(param.allocator_, param.mds_data_))) { + LOG_WARN("failed to init mds data", K(ret), K(param)); + } else if (OB_FAIL(src_tablet->load_storage_schema(allocator, src_storage_schema))) { + LOG_WARN("failed to load storage schema", K(ret), KPC(tablet)); + } else if (OB_FAIL(param.storage_schema_.assign(param.allocator_, *src_storage_schema))) { + LOG_WARN("failed to assign src storage schema", K(ret), KPC(src_storage_schema)); + } else { + LOG_INFO("[TRANSFER_BACKFILL]succeed build transfer replace task migration param", K(param)); + } + } + return ret; +} + + +} +} diff --git a/src/storage/high_availability/ob_transfer_backfill_tx.h b/src/storage/high_availability/ob_transfer_backfill_tx.h new file mode 100644 index 000000000..698029cd9 --- /dev/null +++ b/src/storage/high_availability/ob_transfer_backfill_tx.h @@ -0,0 +1,245 @@ +/** + * 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 OCEABASE_STORAGE_TRANSFER_BACKFILL_TX_ +#define OCEABASE_STORAGE_TRANSFER_BACKFILL_TX_ + +#include "ob_storage_ha_struct.h" +#include "ob_storage_ha_dag.h" +#include "share/scn.h" + +namespace oceanbase +{ +namespace storage +{ + +struct ObTransferBackfillTXParam: public share::ObIDagInitParam +{ +public: + ObTransferBackfillTXParam(); + virtual ~ObTransferBackfillTXParam() {} + virtual bool is_valid() const override; + void reset(); + VIRTUAL_TO_STRING_KV(K_(task_id), K_(src_ls_id), K_(dest_ls_id), K_(backfill_scn), K_(tablet_ids)); + uint64_t tenant_id_; + share::ObTaskId task_id_; + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + share::SCN backfill_scn_; + ObArray tablet_ids_; +}; + +class ObTransferWorkerMgr final +{ +public: + ObTransferWorkerMgr(); + ~ObTransferWorkerMgr(); + int init(ObLS *dest_ls); + int process(); + TO_STRING_KV(K_(is_inited), K_(tenant_id), K_(task_id), KP_(dest_ls)); +private: + int check_task_exist_(const share::ObTaskId &task_id, bool &is_exist); + void update_task_id_(); + int do_transfer_backfill_tx_(const ObTransferBackfillTXParam ¶m); + int get_need_backfill_tx_tablets_(ObTransferBackfillTXParam ¶m); + // Only the minor data is exist and transfer start commit, then the tablet can do backfill. + int check_source_tablet_ready_( + const share::ObLSID &ls_id, + const ObTabletID &tablet_id, + const ObTabletTransferInfo &transfer_info, + bool &is_ready, + ObTabletHAStatus &ha_status /* source tablet ha status */) const; +private: + bool is_inited_; + uint64_t tenant_id_; + share::ObTaskId task_id_; + ObLS *dest_ls_; +private: + DISALLOW_COPY_AND_ASSIGN(ObTransferWorkerMgr); +}; + +struct ObTransferBackfillTXCtx : public ObIHADagNetCtx +{ +public: + ObTransferBackfillTXCtx(); + virtual ~ObTransferBackfillTXCtx(); + void reset(); + void reuse(); + virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual bool is_valid() const; + virtual DagNetCtxType get_dag_net_ctx_type() { return ObIHADagNetCtx::TRANSFER_BACKFILL_TX; } +public: + uint64_t tenant_id_; + share::ObTaskId task_id_; + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + share::SCN backfill_scn_; + ObArray tablet_ids_; + INHERIT_TO_STRING_KV( + "ObIHADagNetCtx", ObIHADagNetCtx, + K_(tenant_id), + K_(task_id), + K_(src_ls_id), + K_(backfill_scn)); +private: + DISALLOW_COPY_AND_ASSIGN(ObTransferBackfillTXCtx); +}; + +class ObTransferBackfillTXDagNet: public share::ObIDagNet +{ +public: + ObTransferBackfillTXDagNet(); + virtual ~ObTransferBackfillTXDagNet(); + virtual int init_by_param(const share::ObIDagInitParam *param) override; + + virtual bool is_valid() const override; + virtual int start_running() override; + virtual bool operator == (const share::ObIDagNet &other) const override; + virtual int64_t hash() const override; + virtual int fill_comment(char *buf, const int64_t buf_len) const override; + virtual int fill_dag_net_key(char *buf, const int64_t buf_len) const override; + virtual int clear_dag_net_ctx(); + + ObTransferBackfillTXCtx *get_ctx() { return &ctx_; } + const share::ObLSID &get_ls_id() const { return ctx_.src_ls_id_; } + const share::SCN &get_backfill_scn() const { return ctx_.backfill_scn_; } + INHERIT_TO_STRING_KV("ObIDagNet", share::ObIDagNet, K_(ctx)); +private: + int start_running_for_backfill_(); + +private: + bool is_inited_; + ObTransferBackfillTXCtx ctx_; + DISALLOW_COPY_AND_ASSIGN(ObTransferBackfillTXDagNet); +}; + + +class ObBaseTransferBackfillTXDag : public ObStorageHADag +{ +public: + explicit ObBaseTransferBackfillTXDag(const share::ObDagType::ObDagTypeEnum &dag_type); + virtual ~ObBaseTransferBackfillTXDag(); + virtual bool operator == (const share::ObIDag &other) const override; + virtual int64_t hash() const override; + int prepare_ctx(share::ObIDagNet *dag_net); + + INHERIT_TO_STRING_KV("ObStorageHADag", ObStorageHADag, KP(this)); +private: + DISALLOW_COPY_AND_ASSIGN(ObBaseTransferBackfillTXDag); +}; + +class ObStartTransferBackfillTXDag : public ObBaseTransferBackfillTXDag +{ +public: + ObStartTransferBackfillTXDag(); + virtual ~ObStartTransferBackfillTXDag(); + virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; + virtual int create_first_task() override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; + int init(share::ObIDagNet *dag_net); + INHERIT_TO_STRING_KV("ObStorageHADag", ObStorageHADag, KP(this)); +protected: + bool is_inited_; + DISALLOW_COPY_AND_ASSIGN(ObStartTransferBackfillTXDag); +}; + +class ObStartTransferBackfillTXTask : public share::ObITask +{ +public: + ObStartTransferBackfillTXTask(); + virtual ~ObStartTransferBackfillTXTask(); + int init(); + virtual int process() override; + VIRTUAL_TO_STRING_KV(K("ObStartTransferBackfillTXTask"), KP(this), KPC(ctx_)); +private: + int generate_transfer_backfill_tx_dags_(); + +private: + bool is_inited_; + ObTransferBackfillTXCtx *ctx_; + share::ObIDagNet *dag_net_; + DISALLOW_COPY_AND_ASSIGN(ObStartTransferBackfillTXTask); +}; + +class ObTransferReplaceTableDag : public ObBaseTransferBackfillTXDag +{ +public: + ObTransferReplaceTableDag(); + virtual ~ObTransferReplaceTableDag(); + virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; + virtual int create_first_task() override; + virtual bool check_can_retry(); + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; + int init(share::ObIDagNet *dag_net); + INHERIT_TO_STRING_KV("ObStorageHADag", ObStorageHADag, KP(this)); +protected: + bool is_inited_; + DISALLOW_COPY_AND_ASSIGN(ObTransferReplaceTableDag); +}; + +class ObTransferReplaceTableTask : public share::ObITask +{ +public: + ObTransferReplaceTableTask(); + virtual ~ObTransferReplaceTableTask(); + int init(); + virtual int process() override; + VIRTUAL_TO_STRING_KV(K("ObTransferReplaceTableTask"), KP(this), KPC(ctx_)); +private: + int do_replace_logical_tables_(ObLS *ls); + int transfer_replace_tables_( + ObLS *ls, + const common::ObTabletID &tablet_id, + const ObTablet *tablet); + int get_source_tablet_tables_( + const ObTablet *dest_tablet, + const common::ObTabletID &tablet_id, + ObTableStoreIterator &sstable_iter, + ObTabletHandle &tablet_handle, + ObTabletHAStatus &ha_status, + common::ObArenaAllocator &allocator, + ObTablesHandleArray &tables_handle); + int get_all_sstable_handles_( + const ObTablet *tablet, + const ObTabletMemberWrapper &wrapper, + ObTableStoreIterator &sstable_iter, + ObTablesHandleArray &sstable_handles); + int check_src_tablet_sstables_(const ObTablet *tablet, ObTablesHandleArray &tables_handle); + int check_source_minor_end_scn_( + const ObTabletMemberWrapper &wrapper, + const ObTablet *dest_tablet, + bool &need_fill_minor); + int check_tablet_after_replace_(ObLS *ls, const common::ObTabletID &tablet_id); + int fill_empty_minor_sstable( + ObTablet *tablet, + bool need_fill_minor, + const share::SCN &end_scn, + const ObTabletMemberWrapper &wrapper, + common::ObArenaAllocator &allocator, + ObTablesHandleArray &tables_handle); + int check_src_memtable_is_empty_(ObTablet *tablet, const share::SCN &transfer_scn); + int build_migration_param_( + const ObTablet *tablet, + ObTabletHandle &src_tablet_handle, + ObMigrationTabletParam ¶m); + int check_major_sstable_( + const ObTablet *tablet, + const ObTabletMemberWrapper &table_store_wrapper); +private: + bool is_inited_; + ObTransferBackfillTXCtx *ctx_; + DISALLOW_COPY_AND_ASSIGN(ObTransferReplaceTableTask); +}; + +} +} +#endif diff --git a/src/storage/high_availability/ob_transfer_handler.cpp b/src/storage/high_availability/ob_transfer_handler.cpp index 7d2bc2ed2..154cfe2c7 100644 --- a/src/storage/high_availability/ob_transfer_handler.cpp +++ b/src/storage/high_availability/ob_transfer_handler.cpp @@ -12,12 +12,1689 @@ #define USING_LOG_PREFIX STORAGE #include "ob_transfer_handler.h" +#include "ob_transfer_service.h" +#include "logservice/ob_log_service.h" +#include "ob_storage_ha_reader.h" +#include "ob_finish_transfer.h" +#include "storage/tx/ob_multi_data_source.h" +#include "share/transfer/ob_transfer_task_operator.h" +#include "share/tablet/ob_tablet_to_ls_operator.h" +#include "ob_transfer_lock_info_operator.h" +#include "ob_transfer_lock_utils.h" +#include "lib/utility/ob_tracepoint.h" +#include "observer/ob_server_event_history_table_operator.h" +#include "ob_storage_ha_utils.h" + +using namespace oceanbase::transaction; +using namespace oceanbase::share; namespace oceanbase { namespace storage { +//errsim def +ERRSIM_POINT_DEF(EN_START_TRANS_FAILED); +ERRSIM_POINT_DEF(EN_LOCK_TRANSFER_TASK_FAILED); +ERRSIM_POINT_DEF(EN_LOCK_TRANSFER_MEMBER_LIST_FAILED); +ERRSIM_POINT_DEF(EN_TRANSFER_CHECK_MEMBER_LIST_NOT_SAME); +ERRSIM_POINT_DEF(EN_CHECK_START_TRANSFER_STATUS_FAILED); +ERRSIM_POINT_DEF(EN_CHECK_ACTIVE_TRANS_FAILED); +ERRSIM_POINT_DEF(EN_START_TRANSFER_OUT_FAILED); +ERRSIM_POINT_DEF(EN_GET_TRANSFER_START_SCN_FAILED); +ERRSIM_POINT_DEF(EN_WAIT_SRC_REPALY_TO_START_SCN_FAILED); +ERRSIM_POINT_DEF(EN_GET_TRANSFER_TABLET_META_FAILED); +ERRSIM_POINT_DEF(EN_START_TRANSFER_IN_FAILED); +ERRSIM_POINT_DEF(EN_UPDATE_ALL_TABLET_TO_LS_FAILED); +ERRSIM_POINT_DEF(EN_UPDATE_TRANSFER_TASK_FAILED); +ERRSIM_POINT_DEF(EN_START_CAN_NOT_RETRY); + +ObTransferHandler::ObTransferHandler() + : is_inited_(false), + ls_(nullptr), + bandwidth_throttle_(nullptr), + svr_rpc_proxy_(nullptr), + storage_rpc_(nullptr), + sql_proxy_(nullptr), + retry_count_(0), + transfer_worker_mgr_() +{ +} + +ObTransferHandler::~ObTransferHandler() +{ +} + +int ObTransferHandler::init( + ObLS *ls, + common::ObInOutBandwidthThrottle *bandwidth_throttle, + obrpc::ObStorageRpcProxy *svr_rpc_proxy, + storage::ObStorageRpc *storage_rpc, + common::ObMySQLProxy *sql_proxy) +{ + int ret = OB_SUCCESS; + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("transfer handler init twice", K(ret)); + } else if (OB_ISNULL(ls) || OB_ISNULL(bandwidth_throttle) || OB_ISNULL(svr_rpc_proxy) + || OB_ISNULL(storage_rpc) || OB_ISNULL(sql_proxy)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("init transfer handler get inavlid argument", K(ret), KP(ls), KP(bandwidth_throttle), + KP(svr_rpc_proxy), KP(storage_rpc), KP(sql_proxy)); + } else if (OB_FAIL(transfer_worker_mgr_.init(ls))) { + LOG_WARN("failed to init transfer worker manager", K(ret), KP(ls)); + } else { + ls_ = ls; + bandwidth_throttle_ = bandwidth_throttle; + svr_rpc_proxy_ = svr_rpc_proxy; + storage_rpc_ = storage_rpc; + sql_proxy_ = sql_proxy; + is_inited_ = true; + } + return ret; +} + +void ObTransferHandler::wakeup_() +{ + int ret = OB_SUCCESS; + ObTransferService *transfer_service = MTL(ObTransferService*); + if (OB_ISNULL(transfer_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("transfer service should not be NULL", K(ret), KP(transfer_service)); + } else { + transfer_service->wakeup(); + } +} + +int ObTransferHandler::get_transfer_task_(ObTransferTaskInfo &task_info) +{ + int ret = OB_SUCCESS; + task_info.reset(); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (OB_FAIL(get_transfer_task_from_inner_table_(task_info))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("failed to get transfer task from inner table", K(ret), KPC(ls_)); + } + } else if (!task_info.status_.is_start_status() && !task_info.status_.is_doing_status() + && !task_info.status_.is_aborted_status()) { + ret = OB_ENTRY_NOT_EXIST; + } + return ret; +} + +int ObTransferHandler::get_transfer_task_from_inner_table_( + const ObTransferTaskID &task_id, + const bool for_update, + common::ObISQLClient &trans, + share::ObTransferTaskInfo &task_info) +{ + int ret = OB_SUCCESS; + task_info.reset(); + const uint64_t tenant_id = MTL_ID(); + ObTransferTask task; + if (! task_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid arg", K(ret), K(task_id)); + } else if (OB_FAIL(ObTransferTaskOperator::get(trans, tenant_id, task_id, for_update, task))) { + LOG_WARN("failed to get transfer task", K(ret), K(tenant_id), K(task_id)); + } else if (OB_FAIL(task_info.convert_from(tenant_id, task))) { + LOG_WARN("failed to convert from transfer task", K(ret), K(task)); + } else { + LOG_INFO("get transfer task from inner table", K(task_info)); + } + return ret; +} + +int ObTransferHandler::get_transfer_task_from_inner_table_( + share::ObTransferTaskInfo &task_info) +{ + int ret = OB_SUCCESS; + task_info.reset(); + const uint64_t tenant_id = MTL_ID(); + const bool for_update = false; + ObTransferTask task; + const ObLSID &dest_ls_id = ls_->get_ls_id(); + + if (OB_FAIL(ObTransferTaskOperator::get_by_dest_ls(*sql_proxy_, tenant_id, dest_ls_id, task))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("failed to get transfer task", K(ret), K(tenant_id), K(dest_ls_id)); + } + } else if (OB_FAIL(task_info.convert_from(tenant_id, task))) { + LOG_WARN("failed to convert from transfer task", K(ret), K(task)); + } else { + LOG_INFO("get transfer task from inner table", K(task_info)); + } + return ret; +} + +void ObTransferHandler::destroy() +{ + if (is_inited_) { + ls_ = nullptr; + bandwidth_throttle_ = nullptr; + svr_rpc_proxy_ = nullptr; + storage_rpc_ = nullptr; + sql_proxy_ = nullptr; + is_inited_ = false; + } +} + +void ObTransferHandler::switch_to_follower_forcedly() +{ + LOG_INFO("[TRANSFER]switch to follower finish"); +} + +int ObTransferHandler::switch_to_leader() +{ + int ret = OB_SUCCESS; + wakeup_(); + LOG_INFO("[TRANSFER]switch to leader finish"); + return ret; +} + +int ObTransferHandler::switch_to_follower_gracefully() +{ + LOG_INFO("[TRANSFER]switch to follower gracefully"); + return OB_SUCCESS; +} + +int ObTransferHandler::resume_leader() +{ + int ret = OB_SUCCESS; + wakeup_(); + LOG_INFO("[TRANSFER]resume leader finish"); + return ret; +} + +int ObTransferHandler::replay( + const void *buffer, + const int64_t nbytes, + const palf::LSN &lsn, + const share::SCN &scn) +{ + UNUSED(buffer); + UNUSED(nbytes); + UNUSED(lsn); + UNUSED(scn); + return OB_SUCCESS; +} + +int ObTransferHandler::flush(share::SCN &scn) +{ + UNUSED(scn); + return OB_SUCCESS; +} + +int ObTransferHandler::process() +{ + int ret = OB_SUCCESS; + ObCurTraceId::init(GCONF.self_addr_); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (OB_FAIL(do_leader_transfer_())) { + LOG_WARN("failed to do leader transfer", K(ret)); + } else if (OB_FAIL(do_worker_transfer_())) { + LOG_WARN("failed to do worker transfer", K(ret)); + } + return ret; +} + +int ObTransferHandler::do_leader_transfer_() +{ + int ret = OB_SUCCESS; + bool is_leader = false; + ObTransferTaskInfo task_info; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (OB_FAIL(check_self_is_leader_(is_leader))) { + LOG_WARN("failed to check self is leader", K(ret), KPC(ls_)); + } else if (!is_leader) { + //need retry by dest_ls new leader + } else if (OB_FAIL(get_transfer_task_(task_info))) { + if (OB_ENTRY_NOT_EXIST == ret || OB_TABLET_NOT_EXIST == ret || OB_TABLE_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get transfer task", K(ret), KPC(ls_)); + } + } else { + ObCurTraceId::set(task_info.trace_id_); + + switch (task_info.status_) { + case ObTransferStatus::START: { + if (OB_FAIL(do_with_start_status_(task_info))) { + LOG_WARN("failed to do with start status", K(ret), K(task_info)); + } + break; + } + case ObTransferStatus::DOING : { + if (OB_FAIL(do_with_doing_status_(task_info))) { + LOG_WARN("failed to do with doing status", K(ret), K(task_info)); + } + break; + } + case ObTransferStatus::ABORTED : { + if (OB_FAIL(do_with_aborted_status_(task_info))) { + LOG_WARN("failed to do with aborted status", K(ret), K(task_info)); + } + break; + } + default: { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid cur status for fail", K(ret), K(task_info)); + } + } + } + return ret; +} + +int ObTransferHandler::check_self_is_leader_(bool &is_leader) +{ + int ret = OB_SUCCESS; + logservice::ObLogService *log_service = nullptr; + ObRole role = ObRole::INVALID_ROLE; + int64_t proposal_id = 0; + share::ObAllTenantInfo tenant_info; + const uint64_t tenant_id = MTL_ID(); + is_leader = false; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, sql_proxy_, false/*for update*/, tenant_info))) { + LOG_WARN("failed to get tenant info", K(ret), K(tenant_id)); + } else if (!tenant_info.is_primary()) { + is_leader = false; + } else if (OB_ISNULL(log_service = MTL(logservice::ObLogService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log service should not be NULL", K(ret), KP(log_service)); + } else if (OB_FAIL(log_service->get_palf_role(ls_->get_ls_id(), role, proposal_id))) { + LOG_WARN("failed to get role", K(ret), KPC(ls_)); + } else if (is_strong_leader(role)) { + is_leader = true; + } else { + is_leader = false; + } + return ret; +} + +int ObTransferHandler::do_with_start_status_(const share::ObTransferTaskInfo &task_info) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + const int64_t start_ts = ObTimeUtil::current_time(); + LOG_INFO("[TRANSFER] start do with start status", K(task_info)); + + ObTimeoutCtx timeout_ctx; + ObMySQLTransaction trans; + bool enable_kill_trx = false; + int64_t kill_trx_threshold = 0; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("do with start status get invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(start_trans_(timeout_ctx, trans))) { + LOG_WARN("failed to start trans", K(ret), K(task_info)); + } else { +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_START_TRANS_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_START_TRANS_FAILED", K(ret)); + SERVER_EVENT_SYNC_ADD("TRANSFER", "START_TRANS_FAILED"); + } + } +#endif + if (FAILEDx(lock_transfer_task_(task_info, trans))) { + LOG_WARN("failed to lock transfer task", K(ret), K(task_info)); + } else { +#ifdef ERRSIM + ObTransferEventRecorder::record_transfer_task_event( + task_info.task_id_, "START_TRANSFER_TRANS", task_info.src_ls_id_, task_info.dest_ls_id_); +#endif + DEBUG_SYNC(START_TRANSFER_TRANS); + } + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID())); + if (tenant_config.is_valid()) { + enable_kill_trx = tenant_config->_enable_balance_kill_transaction; + kill_trx_threshold = tenant_config->_balance_kill_transaction_threshold; + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(lock_src_and_dest_ls_member_list_(task_info, task_info.src_ls_id_, task_info.dest_ls_id_))) { + LOG_WARN("failed to lock src and dest ls member list", K(ret), K(task_info)); + } else if (!enable_kill_trx && OB_FAIL(check_src_ls_has_active_trans_(task_info.src_ls_id_))) { + LOG_WARN("failed to check src ls active trans", K(ret), K(task_info)); + } else if (OB_FAIL(block_and_kill_tx_(task_info, enable_kill_trx, kill_trx_threshold, timeout_ctx))) { + LOG_WARN("failed to block and kill tx", K(ret), K(task_info)); + } else if (OB_FAIL(reset_timeout_for_trans_(timeout_ctx))) { + LOG_WARN("failed to reset timeout for trans", K(ret)); + } else if (OB_FAIL(check_start_status_transfer_tablets_(task_info))) { + LOG_WARN("failed to check start status transfer tablets", K(ret), K(task_info)); + } else if (OB_FAIL(do_trans_transfer_start_(task_info, timeout_ctx, trans))) { + LOG_WARN("failed to do trans transfer start", K(ret), K(task_info)); + } + if (OB_TMP_FAIL(commit_trans_(ret, trans))) { + LOG_WARN("failed to commit trans", K(tmp_ret), K(ret)); + if (OB_SUCCESS == ret) { + ret = tmp_ret; + } + } + } + + if (OB_FAIL(ret)) { + if (can_retry_(task_info, ret)) { + LOG_INFO("transfer task can retry", K(ret), K(task_info)); + if (OB_TMP_FAIL(unblock_tx_(task_info.tenant_id_, task_info.src_ls_id_))) { + LOG_WARN("failed to unblock tx", K(ret)); + } else if (OB_TMP_FAIL(unlock_src_and_dest_ls_member_list_(task_info))) { + LOG_WARN("failed to unlock src and dest ls member list", K(tmp_ret), K(ret), K(task_info)); + } + ob_usleep(INTERVAL_US); + } else if (OB_SUCCESS != (tmp_ret = update_transfer_status_aborted_(task_info, ret))) { + LOG_WARN("failed to update transfer status aborted", K(tmp_ret), K(task_info)); + } + } else { + if (OB_FAIL(report_to_meta_table_(task_info))) { + LOG_WARN("failed to report to meta table", K(ret), K(task_info)); + } + } + wakeup_(); + LOG_INFO("[TRANSFER] finish do with start status", K(ret), K(task_info), "cost_ts", ObTimeUtil::current_time() - start_ts); + return ret; +} + +int ObTransferHandler::lock_src_and_dest_ls_member_list_( + const share::ObTransferTaskInfo &task_info, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id) +{ + int ret = OB_SUCCESS; + bool is_same = false; + const int64_t start_ts = ObTimeUtil::current_time(); + LOG_INFO("[TRANSFER] start lock src and dest ls member list", K(src_ls_id), K(dest_ls_id)); +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "before_lock_member_list", + "tenant_id", task_info.tenant_id_, + "task_id", task_info.task_id_.id(), + "src_ls_id", src_ls_id.id(), + "dest_ls_id", dest_ls_id.id()); +#endif + DEBUG_SYNC(BEFORE_TRANSFER_START_LOCK_MEMBER_LIST); + ObMemberList member_list; + ObArray lock_ls_list; + const ObTransferLockStatus status(ObTransferLockStatus::START); + const uint64_t tenant_id = task_info.tenant_id_; + const int64_t task_id = task_info.task_id_.id(); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!src_ls_id.is_valid() || !dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("lock src and dest ls member list get invalid argument", K(ret), + K(src_ls_id), K(dest_ls_id)); + } else if (OB_FAIL(check_ls_member_list_same_(src_ls_id, dest_ls_id, member_list, is_same))) { + LOG_WARN("failed to check ls member listsame", K(ret), K(src_ls_id), K(dest_ls_id)); + } else if (!is_same) { + ret = OB_TRANSFER_MEMBER_LIST_NOT_SAME; + LOG_WARN("src ls and dest ls member list is not same", K(ret), K(src_ls_id), K(dest_ls_id)); + } else if (OB_FAIL(lock_ls_list.push_back(src_ls_id))) { + LOG_WARN("failed to push back", K(ret), K(src_ls_id)); + } else if (OB_FAIL(lock_ls_list.push_back(dest_ls_id))) { + LOG_WARN("failed to push back", K(ret), K(dest_ls_id)); + } else if (OB_FAIL(ObMemberListLockUtils::batch_lock_ls_member_list(tenant_id, task_id, + lock_ls_list, member_list, status, *sql_proxy_))) { + LOG_WARN("failed to batch lock ls member list", K(ret)); + } else if (OB_FAIL(check_ls_member_list_same_(src_ls_id, dest_ls_id, member_list, is_same))) { + LOG_WARN("failed to check ls member listsame", K(ret), K(src_ls_id), K(dest_ls_id)); + } else if (!is_same) { + ret = OB_TRANSFER_MEMBER_LIST_NOT_SAME; + LOG_WARN("src ls and dest ls member list is not same", K(ret), K(src_ls_id), K(dest_ls_id)); + } else { +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_LOCK_TRANSFER_MEMBER_LIST_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_LOCK_TRANSFER_MEMBER_LIST_FAILED", K(ret)); + } + } +#endif + } + LOG_INFO("[TRANSFER] finish lock src and dest ls member list", K(src_ls_id), K(dest_ls_id), "cost_ts", + ObTimeUtil::current_time() - start_ts); +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "after_lock_member_list", + "tenant_id", task_info.tenant_id_, + "task_id", task_info.task_id_.id(), + "src_ls_id", src_ls_id.id(), + "dest_ls_id", dest_ls_id.id(), + "member_list_is_same", is_same); +#endif + DEBUG_SYNC(AFTER_TRANSFER_START_LOCK_MEMBER_LIST); + + return ret; +} + +int ObTransferHandler::reset_timeout_for_trans_(ObTimeoutCtx &timeout_ctx) +{ + int ret = OB_SUCCESS; + const int64_t MAX_EXECUTE_TIMEOUT_US = GCONF._transfer_start_trans_timeout; //default 1s + int64_t stmt_timeout = MAX_EXECUTE_TIMEOUT_US; + if (OB_FAIL(timeout_ctx.set_trx_timeout_us(stmt_timeout))) { + LOG_WARN("fail to set trx timeout", K(ret), K(stmt_timeout)); + } else if (OB_FAIL(timeout_ctx.set_timeout(stmt_timeout))) { + LOG_WARN("set timeout context failed", K(ret)); + } + return ret; +} + +int ObTransferHandler::unlock_src_and_dest_ls_member_list_( + const share::ObTransferTaskInfo &task_info) +{ + int ret = OB_SUCCESS; + ObMemberList fake_member_list; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("unlock src and dest ls member list get invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(inner_unlock_ls_member_list_(task_info, task_info.src_ls_id_, fake_member_list))) { + LOG_WARN("failed to inner unlock ls member list", K(ret), K(task_info)); + } else if (OB_FAIL(inner_unlock_ls_member_list_(task_info, task_info.dest_ls_id_, fake_member_list))) { + LOG_WARN("failed to inner unlock ls member list", K(ret), K(task_info)); + } + return ret; +} + +int ObTransferHandler::inner_unlock_ls_member_list_( + const share::ObTransferTaskInfo &task_info, + const share::ObLSID &ls_id, + const common::ObMemberList &member_list) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = task_info.tenant_id_; + const int64_t task_id = task_info.task_id_.id(); + const ObTransferLockStatus status(ObTransferLockStatus::START); + if (OB_FAIL(ObMemberListLockUtils::unlock_ls_member_list( + tenant_id, ls_id, task_id, member_list, status, *sql_proxy_))) { + LOG_WARN("failed to lock ls member list", K(ret), K(task_info), K(ls_id), K(member_list)); + } + return ret; +} + + +int ObTransferHandler::check_ls_member_list_same_( + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + common::ObMemberList &member_list, + bool &is_same) +{ + int ret = OB_SUCCESS; + is_same = false; + common::ObMemberList dest_ls_member_list; + common::ObMemberList src_ls_member_list; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!src_ls_id.is_valid() || !dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check ls memebr list same get invalid argument", K(ret), K(src_ls_id), K(dest_ls_id)); + } else if (OB_FAIL(get_ls_member_list_(dest_ls_id, dest_ls_member_list))) { + LOG_WARN("failed to get dest ls member list", K(ret), KPC(ls_)); + } else if (OB_FAIL(get_ls_member_list_(src_ls_id, src_ls_member_list))) { + LOG_WARN("failed to get src ls member list", K(ret), K(src_ls_id)); + } else if (dest_ls_member_list.get_member_number() != src_ls_member_list.get_member_number()) { + is_same = false; + LOG_INFO("dest ls memebr list is not same with src ls member list", K(ret), K(src_ls_member_list), K(dest_ls_member_list)); + } else { + is_same = true; + for (int64_t i = 0; OB_SUCC(ret) && i < dest_ls_member_list.get_member_number() && is_same; ++i) { + ObMember member; + if (OB_FAIL(dest_ls_member_list.get_member_by_index(i, member))) { + LOG_WARN("failed to get member info", K(ret), K(i), K(dest_ls_member_list)); + } else if (!src_ls_member_list.contains(member.get_server())) { + is_same = false; + LOG_INFO("member list not same", K(src_ls_id), K(dest_ls_id), K(member), K(dest_ls_member_list), K(src_ls_member_list)); + } + } + } + if (OB_SUCC(ret) && is_same) { + if (OB_FAIL(member_list.deep_copy(src_ls_member_list))) { + LOG_WARN("failed to deep copy", K(ret), K(src_ls_member_list)); + } + } else { + LOG_WARN("member list not same", K(src_ls_id), K(dest_ls_id), K(src_ls_member_list), K(dest_ls_member_list)); + } +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_TRANSFER_CHECK_MEMBER_LIST_NOT_SAME ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + LOG_WARN("failed to check member list not same", K(ret), K(src_ls_id), K(dest_ls_id), K(src_ls_member_list), K(dest_ls_member_list)); + } + } +#endif + return ret; +} + +int ObTransferHandler::get_ls_member_list_( + const share::ObLSID &ls_id, + common::ObMemberList &member_list) +{ + int ret = OB_SUCCESS; + int64_t cluster_id = GCONF.cluster_id; + uint64_t tenant_id = MTL_ID(); + ObStorageHASrcInfo src_info; + obrpc::ObFetchLSMemberListInfo member_info; + src_info.cluster_id_ = cluster_id; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get src ls member list get invalid argument", K(ret), K(ls_id)); + } else if (OB_FAIL(get_ls_leader_(ls_id, src_info.src_addr_))) { + LOG_WARN("failed to get src ls leaer", K(ret), K(ls_id)); + } else if (OB_FAIL(storage_rpc_->post_ls_member_list_request(tenant_id, src_info, ls_id, member_info))) { + LOG_WARN("failed to get ls member info", K(ret), KPC(ls_)); + } else if (member_info.member_list_.get_member_number() <= 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("member list number is unexpected", K(ret), K(member_info), K(ls_id)); + } else if (OB_FAIL(member_list.deep_copy(member_info.member_list_))) { + LOG_WARN("failed to copy member list", K(ret), KPC(ls_)); + } + return ret; +} + +int ObTransferHandler::check_src_ls_has_active_trans_( + const share::ObLSID &src_ls_id, + const int64_t expected_active_trans_count) +{ + int ret = OB_SUCCESS; + int64_t active_trans_count = 0; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!src_ls_id.is_valid() || expected_active_trans_count < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check src ls active trans get invalid argument", K(ret), K(src_ls_id), K(expected_active_trans_count)); + } else if (OB_FAIL(get_ls_active_trans_count_(src_ls_id, active_trans_count))) { + LOG_WARN("failed to get ls active trans count"); + } else if (active_trans_count > expected_active_trans_count) { + ret = OB_TRANSFER_DETECT_ACTIVE_TRANS; + LOG_WARN("src ls has unexpected active trans count", K(ret), K(active_trans_count), + K(expected_active_trans_count), K(src_ls_id)); + } else { +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_CHECK_ACTIVE_TRANS_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_CHECK_ACTIVE_TRANS_FAILED", K(ret)); + } + } +#endif + LOG_INFO("get active trans count", K(src_ls_id), K(active_trans_count)); + } + return ret; +} + +int ObTransferHandler::get_ls_active_trans_count_( + const share::ObLSID &src_ls_id, + int64_t &active_trans_count) +{ + int ret = OB_SUCCESS; + active_trans_count = 0; + int64_t cluster_id = GCONF.cluster_id; + uint64_t tenant_id = MTL_ID(); + ObStorageHASrcInfo src_info; + src_info.cluster_id_ = cluster_id; + if (OB_FAIL(get_ls_leader_(src_ls_id, src_info.src_addr_))) { + LOG_WARN("failed to get src ls leader", K(ret), K(src_ls_id)); + } else if (OB_FAIL(storage_rpc_->get_ls_active_trans_count(tenant_id, src_info, src_ls_id, active_trans_count))) { + LOG_WARN("failed to get ls active trans count", K(ret), K(src_ls_id), K(src_info)); + } else { + LOG_INFO("get ls active trans count", K(tenant_id), K(src_ls_id), K(active_trans_count)); + } + return ret; +} + +int ObTransferHandler::check_start_status_transfer_tablets_( + const share::ObTransferTaskInfo &task_info) +{ + int ret = OB_SUCCESS; + common::ObMemberList member_list; + ObArray member_addr_list; + const int64_t cluster_id = GCONF.cluster_id; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check start status src ls info get invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(get_ls_member_list_(task_info.dest_ls_id_, member_list))) { + LOG_WARN("failed to get dest ls member list", K(ret), KPC(ls_)); + } else if (OB_FAIL(member_list.get_addr_array(member_addr_list))) { + LOG_WARN("failed to get addr array", K(ret), K(task_info), K(member_list)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < member_addr_list.count(); ++i) { + const ObAddr &addr = member_addr_list.at(i); + ObStorageHASrcInfo src_info; + src_info.src_addr_ = addr; + src_info.cluster_id_ = cluster_id; + if (OB_FAIL(storage_rpc_->check_start_transfer_tablets(task_info.tenant_id_, + src_info, task_info.src_ls_id_, task_info.dest_ls_id_, task_info.tablet_list_))) { + LOG_WARN("failed to check src transfer tablets", K(ret), K(task_info), K(src_info)); + } + } + } + + if (OB_FAIL(ret)) { + } else { +#ifdef ERRSIM + ObTransferEventRecorder::record_transfer_task_event( + task_info.task_id_, "BEFORE_START_TRANSFER_TRANS", task_info.src_ls_id_, task_info.dest_ls_id_); +#endif + DEBUG_SYNC(BEFORE_START_TRANSFER_TRANS); + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_CHECK_START_TRANSFER_STATUS_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_CHECK_START_TRANSFER_STATUS_FAILED", K(ret)); + } + } +#endif + + } + return ret; +} + +int ObTransferHandler::get_ls_leader_( + const share::ObLSID &ls_id, + common::ObAddr &addr) +{ + int ret = OB_SUCCESS; + const int64_t cluster_id = GCONF.cluster_id; + const uint64_t tenant_id = MTL_ID(); + share::ObLocationService *location_service = nullptr; + const bool force_renew = true; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get ls leader get invalid argument", K(ret), K(ls_id)); + } else if (OB_ISNULL(location_service = GCTX.location_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("location service should not be NULL", K(ret), KP(location_service)); + } else if (OB_FAIL(location_service->get_leader(cluster_id, tenant_id, ls_id, force_renew, addr))) { + LOG_WARN("fail to get ls leader server", K(ret), K(tenant_id), KPC(ls_)); + } + return ret; +} + +int ObTransferHandler::do_trans_transfer_start_( + const share::ObTransferTaskInfo &task_info, + ObTimeoutCtx &timeout_ctx, + ObMySQLTransaction &trans) +{ + LOG_INFO("[TRANSFER] start do trans transfer start", K(task_info)); + int ret = OB_SUCCESS; + SCN start_scn; + ObArray tablet_meta_list; + const share::ObTransferStatus next_status(ObTransferStatus::DOING); + const int64_t start_ts = ObTimeUtil::current_time(); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("do trans transfer start get invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(do_tx_start_transfer_out_(task_info, trans))) { + LOG_WARN("failed to do tx start transfer out", K(ret), K(task_info)); + } else if (OB_FAIL(get_start_transfer_out_scn_(task_info, timeout_ctx, start_scn))) { + LOG_WARN("failed to get start transfer out log ts", K(ret), K(task_info)); + } else if (OB_FAIL(check_src_ls_has_active_trans_(task_info.src_ls_id_, 1/*transfer out trans*/))) { + LOG_WARN("failed to check src ls has active trans", K(ret), K(task_info)); + } else if (OB_FAIL(unblock_tx_(task_info.tenant_id_, task_info.src_ls_id_))) { + LOG_WARN("failed to unblock tx", K(ret), K(task_info)); + } else if (OB_FAIL(wait_src_ls_replay_to_start_scn_(task_info, start_scn, timeout_ctx))) { + LOG_WARN("failed to wait src ls replay to start scn", K(ret), K(task_info)); + } else if (OB_FAIL(get_transfer_tablets_meta_(task_info, tablet_meta_list))) { + LOG_WARN("failed to get transfer tablets meta", K(ret), K(task_info)); + } else if (OB_FAIL(do_tx_start_transfer_in_(task_info, start_scn, tablet_meta_list, timeout_ctx, trans))) { + LOG_WARN("failed to do tx start transfer in", K(ret), K(task_info), K(start_scn), K(tablet_meta_list)); + } else if (OB_FAIL(update_all_tablet_to_ls_(task_info, trans))) { + LOG_WARN("failed to update all tablet to ls", K(ret), K(task_info)); + } else if (OB_FAIL(lock_tablet_on_dest_ls_for_table_lock_(task_info, trans))) { + LOG_WARN("failed to lock tablet on dest ls for table lock", KR(ret), K(task_info)); + } else if (OB_FAIL(update_transfer_status_(task_info, next_status, start_scn, OB_SUCCESS, trans))) { + LOG_WARN("failed to update transfer status", K(ret), K(task_info)); + } + + LOG_INFO("[TRANSFER] finish do trans transfer start", K(task_info), "cost_ts", ObTimeUtil::current_time() - start_ts); + return ret; +} + +int ObTransferHandler::start_trans_( + ObTimeoutCtx &timeout_ctx, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const int64_t MAX_EXECUTE_TIMEOUT_US = GCONF._transfer_start_trans_timeout; //default 1s + int64_t stmt_timeout = MAX_EXECUTE_TIMEOUT_US; + const uint64_t tenant_id = MTL_ID(); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (OB_FAIL(timeout_ctx.set_trx_timeout_us(stmt_timeout))) { + LOG_WARN("fail to set trx timeout", K(ret), K(stmt_timeout)); + } else if (OB_FAIL(timeout_ctx.set_timeout(stmt_timeout))) { + LOG_WARN("set timeout context failed", K(ret)); + } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id))) { + LOG_WARN("failed to start trans", K(ret)); + } + return ret; +} + +int ObTransferHandler::commit_trans_( + const int32_t &result, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else { + tmp_ret = trans.end(OB_SUCC(result)); + if (OB_SUCCESS != tmp_ret) { + LOG_WARN("end transaction failed", K(tmp_ret), K(ret)); + ret = OB_SUCCESS == ret ? tmp_ret : ret; + } + } + return ret; +} + +int ObTransferHandler::lock_transfer_task_( + const share::ObTransferTaskInfo &task_info, + common::ObISQLClient &trans) +{ + int ret = OB_SUCCESS; + const bool for_update = true; + ObTransferTaskInfo table_task_info; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("lock transfer task get invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(get_transfer_task_from_inner_table_(task_info.task_id_, for_update, trans, table_task_info))) { + LOG_WARN("failed to get transfer task from inner table", K(ret), K(task_info)); + } else if (task_info.task_id_ != table_task_info.task_id_ + || task_info.status_ != table_task_info.status_ + || task_info.dest_ls_id_ != table_task_info.dest_ls_id_ + || task_info.src_ls_id_ != table_task_info.src_ls_id_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer task info in not same with inner table", K(ret), K(task_info), K(table_task_info)); + } else { +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_LOCK_TRANSFER_TASK_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_LOCK_TRANSFER_TASK_FAILED", K(ret)); + } + } +#endif + } + return ret; +} + +int ObTransferHandler::do_tx_start_transfer_out_( + const share::ObTransferTaskInfo &task_info, + common::ObMySQLTransaction &trans) +{ + LOG_INFO("start do tx start transfer out", K(task_info)); + int ret = OB_SUCCESS; + observer::ObInnerSQLConnection *conn = NULL; + ObTXStartTransferOutInfo start_transfer_out_info; + ObArenaAllocator allocator; + SCN dest_base_scn; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("do tx start transfer out get invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(ls_->get_log_handler()->get_max_scn(dest_base_scn))) { + LOG_WARN("failed to get max scn", K(ret), K(task_info)); + } else if (OB_ISNULL(conn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("conn_ is NULL", KR(ret)); + } else { + start_transfer_out_info.src_ls_id_ = task_info.src_ls_id_; + start_transfer_out_info.dest_ls_id_ = task_info.dest_ls_id_; + if (OB_FAIL(start_transfer_out_info.tablet_list_.assign(task_info.tablet_list_))) { + LOG_WARN("failed to assign transfer tablet list", K(ret), K(task_info)); + } else { + int64_t buf_len = start_transfer_out_info.get_serialize_size(); + int64_t pos = 0; + char *buf = (char*)allocator.alloc(buf_len); + ObRegisterMdsFlag flag; + flag.need_flush_redo_instantly_ = true; + flag.mds_base_scn_ = dest_base_scn; + if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail alloc memory", KR(ret)); + } else if (OB_FAIL(start_transfer_out_info.serialize(buf, buf_len, pos))) { + LOG_WARN("fail to serialize start transfer out info", KR(ret), K(start_transfer_out_info)); + } else if (OB_FAIL(conn->register_multi_data_source(task_info.tenant_id_, task_info.src_ls_id_, + transaction::ObTxDataSourceType::START_TRANSFER_OUT, buf, buf_len, flag))) { + LOG_WARN("failed to register multi data source", K(ret), K(task_info)); + } +#ifdef ERRSIM + ObTransferEventRecorder::record_transfer_task_event( + task_info.task_id_, "TX_START_TRANSFER_OUT", task_info.src_ls_id_, task_info.dest_ls_id_); +#endif + } + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_START_TRANSFER_OUT_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_START_TRANSFER_OUT_FAILED", K(ret)); + } + } +#endif + + DEBUG_SYNC(AFTER_START_TRANSFER_OUT); + + } + return ret; +} + +int ObTransferHandler::get_start_transfer_out_scn_( + const share::ObTransferTaskInfo &task_info, + ObTimeoutCtx &timeout_ctx, + share::SCN &start_scn) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObAddr src_ls_leader; + start_scn.set_min(); + const int64_t OB_CHECK_START_SCN_READY_INTERVAL = 1 * 1000; //1ms + const int64_t OB_GET_SRC_LS_LEADER_INTERVAL = 2 * 1000 ; //2ms + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get start transfer out scn invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(get_ls_leader_(task_info.src_ls_id_, src_ls_leader))) { + LOG_WARN("failed to get src ls leader", K(ret), K(task_info)); + } else { + while (OB_SUCC(ret)) { + if (timeout_ctx.is_timeouted()) { + ret = OB_TIMEOUT; + LOG_WARN("already timeout", K(ret), K(task_info)); + break; + } else { + ObStorageHASrcInfo src_info; + src_info.cluster_id_ = GCONF.cluster_id; + src_info.src_addr_ = src_ls_leader; + if (OB_FAIL(storage_rpc_->get_transfer_start_scn(task_info.tenant_id_, src_info, + task_info.src_ls_id_, task_info.tablet_list_, start_scn))) { + LOG_WARN("failed to get transfer start scn", K(ret), K(task_info)); + } + } + + if (OB_SUCC(ret)) { + if (start_scn.is_min()) {// min means no start scn found + ob_usleep(OB_CHECK_START_SCN_READY_INTERVAL); + if (REACH_TENANT_TIME_INTERVAL(OB_GET_SRC_LS_LEADER_INTERVAL)) { + //TODO(muwwei.ym) Here get leader will return 4012, need check with yanmu + if (OB_FAIL(get_ls_leader_(task_info.src_ls_id_, src_ls_leader))) { + LOG_WARN("failed to get src ls leader", K(ret), K(task_info)); + } + } + } else { + break; + } + } + + if (OB_FAIL(ret)) { + //TODO(muwei.ym) need check can retry + ret = OB_SUCCESS; + } + } + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_GET_TRANSFER_START_SCN_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_GET_TRANSFER_START_SCN_FAILED", K(ret)); + } + } +#endif + + DEBUG_SYNC(AFTER_START_TRANSFER_GET_START_SCN); + + } + return ret; +} + +int ObTransferHandler::wait_src_ls_replay_to_start_scn_( + const share::ObTransferTaskInfo &task_info, + const share::SCN &start_scn, + ObTimeoutCtx &timeout_ctx) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + + const int64_t cluster_id = GCONF.cluster_id; + const uint64_t tenant_id = MTL_ID(); + const int64_t OB_CHECK_START_SCN_READY_INTERVAL = 200 * 1000; //200ms + bool is_all_replica_reach = false; + bool is_is_majority_reach = false; + hash::ObHashSet replica_addr_set; + common::ObMemberList member_list; + ObArray member_addr_list; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid() || !start_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("wait src ls replay to start scn get invalid argument", K(ret), K(task_info), K(start_scn)); + } else if (OB_FAIL(replica_addr_set.create(OB_DEFAULT_REPLICA_NUM))) { + LOG_WARN("failed to create replica addr set", K(ret), K(task_info)); + } else if (OB_FAIL(get_ls_member_list_(task_info.dest_ls_id_, member_list))) { + LOG_WARN("failed to get dest ls member list", K(ret), K(task_info)); + } else if (OB_FAIL(member_list.get_addr_array(member_addr_list))) { + LOG_WARN("failed to get addr array", K(ret), K(task_info), K(member_list)); + } else { + + while (OB_SUCC(ret)) { + int64_t replica_count = 0; + if (timeout_ctx.is_timeouted()) { + ret = OB_TIMEOUT; + LOG_WARN("already timeout", K(ret), K(task_info)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < member_addr_list.count(); ++i) { + const ObAddr &replica_addr = member_addr_list.at(i); + const int32_t hash_ret = replica_addr_set.exist_refactored(replica_addr); + SCN replica_scn; + if (OB_HASH_EXIST == hash_ret) { + replica_count++; + } else if (OB_HASH_NOT_EXIST) { + ObStorageHASrcInfo src_info; + src_info.cluster_id_ = cluster_id; + src_info.src_addr_ = replica_addr; + if (OB_SUCCESS != (tmp_ret = storage_rpc_->get_transfer_start_scn(task_info.tenant_id_, src_info, + task_info.src_ls_id_, task_info.tablet_list_, replica_scn))) { + LOG_WARN("failed to get transfer start scn", K(tmp_ret), K(task_info)); + } else if (replica_scn >= start_scn) { + if (OB_FAIL(replica_addr_set.set_refactored(replica_addr))) { + LOG_WARN("failed to set replica into hash set", K(ret), K(replica_addr)); + } else { + replica_count++; + } + } + } else { + ret = OB_SUCC(hash_ret) ? OB_ERR_UNEXPECTED : hash_ret; + LOG_WARN("failed to get replica server from hash set", K(ret), K(task_info)); + } + } + } + + if (OB_SUCC(ret)) { + if (replica_count == member_addr_list.count()) { + FLOG_INFO("[TRANSFER] src ls all replicas replay reach start_scn", "src_ls", task_info.src_ls_id_, + K(start_scn), K(member_addr_list)); + break; + } + } + + if (OB_FAIL(ret)) { + //TODO(muwei.ym) need retry + } + + if (OB_SUCC(ret)) { + ob_usleep(OB_CHECK_START_SCN_READY_INTERVAL); + } + } + } + + DEBUG_SYNC(AFTER_START_TRANSFER_WAIT_REPLAY_TO_START_SCN); +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_WAIT_SRC_REPALY_TO_START_SCN_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_WAIT_SRC_REPALY_TO_START_SCN_FAILED", K(ret)); + } + } +#endif + + return ret; +} + +int ObTransferHandler::get_transfer_tablets_meta_( + const share::ObTransferTaskInfo &task_info, + common::ObIArray &tablet_meta_list) +{ + int ret = OB_SUCCESS; + tablet_meta_list.reset(); + const int64_t cluster_id = GCONF.cluster_id; + const uint64_t tenant_id = MTL_ID(); + ObCopyTransferTabletInfoObReader *ob_reader = nullptr; + void *buf = nullptr; + obrpc::ObTransferTabletInfoArg rpc_arg; + ObStorageHASrcInfo src_info; + src_info.cluster_id_ = cluster_id; + obrpc::ObCopyTabletInfo tablet_info; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get transfer tablets meta get invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(get_ls_leader_(task_info.src_ls_id_, src_info.src_addr_))) { + LOG_WARN("failed to get src ls leader", K(ret), K(task_info)); + } else if (FALSE_IT(buf = ob_malloc(sizeof(ObCopyTransferTabletInfoObReader), "TabletObReader"))) { + } else if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret), KP(buf)); + } else if (FALSE_IT(ob_reader = new (buf) ObCopyTransferTabletInfoObReader())) { + } else if (OB_FAIL(rpc_arg.tablet_list_.assign(task_info.tablet_list_))) { + LOG_WARN("failed to assign tablet list", K(ret), K(task_info)); + } else { + rpc_arg.tenant_id_ = task_info.tenant_id_; + rpc_arg.src_ls_id_ = task_info.src_ls_id_; + rpc_arg.dest_ls_id_ = task_info.dest_ls_id_; + if (OB_FAIL(ob_reader->init(src_info, rpc_arg, *svr_rpc_proxy_, *bandwidth_throttle_))) { + LOG_WARN("failed to init copy transfer tablet info ob reader", K(ret), K(rpc_arg)); + } else { + while (OB_SUCC(ret)) { + tablet_info.reset(); + if (OB_FAIL(ob_reader->fetch_tablet_info(tablet_info))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to fetch tablet info", K(ret)); + } + } else if (OB_FAIL(tablet_meta_list.push_back(tablet_info.param_))) { + LOG_WARN("failed to push tablet info into array", K(ret), K(tablet_info)); + } + + } + } + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_GET_TRANSFER_TABLET_META_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_GET_TRANSFER_TABLET_META_FAILED", K(ret)); + } + } +#endif + } + + if (OB_NOT_NULL(ob_reader)) { + ob_reader->~ObCopyTransferTabletInfoObReader(); + ob_free(ob_reader); + ob_reader = nullptr; + } + + DEBUG_SYNC(AFTER_START_TRANSFER_GET_TABLET_META); + + return ret; +} + +int ObTransferHandler::do_tx_start_transfer_in_( + const share::ObTransferTaskInfo &task_info, + const SCN &start_scn, + const common::ObIArray &tablet_meta_list, + ObTimeoutCtx &timeout_ctx, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const int64_t MAX_BUF_LEN = 1.5 * 1024 * 1024; // 1.5M + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid() || tablet_meta_list.empty() || !start_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("do tx start transfer in get invalid argument", K(ret), K(task_info), + K(tablet_meta_list), K(start_scn)); + } else { + int64_t index = 0; + ObTXStartTransferInInfo start_transfer_in_info; + while (OB_SUCC(ret) && index < tablet_meta_list.count()) { + start_transfer_in_info.reset(); + start_transfer_in_info.src_ls_id_ = task_info.src_ls_id_; + start_transfer_in_info.dest_ls_id_ = task_info.dest_ls_id_; + start_transfer_in_info.start_scn_ = start_scn; + + if (timeout_ctx.is_timeouted()) { + ret = OB_TIMEOUT; + LOG_WARN("already timeout", K(ret), K(task_info)); + } + + for (int64_t i = index; i < tablet_meta_list.count() && OB_SUCC(ret); ++i, ++index) { + const ObMigrationTabletParam &tablet_meta = tablet_meta_list.at(i); + if (start_transfer_in_info.get_serialize_size() + tablet_meta.get_serialize_size() > MAX_BUF_LEN) { + if (OB_FAIL(inner_tx_start_transfer_in_(task_info, start_transfer_in_info, trans))) { + LOG_WARN("failed to do inner tx start transfer in", K(ret), K(task_info), K(start_transfer_in_info)); + } else { + start_transfer_in_info.reset(); + break; + } + } else if (OB_FAIL(start_transfer_in_info.tablet_meta_list_.push_back(tablet_meta))) { + LOG_WARN("failed to push tablet meta into list", K(ret), K(tablet_meta)); + } + } + + if (OB_SUCC(ret) && !start_transfer_in_info.tablet_meta_list_.empty()) { + if (OB_FAIL(inner_tx_start_transfer_in_(task_info, start_transfer_in_info, trans))) { + LOG_WARN("failed to do inner tx start transfer in", K(ret), K(task_info), K(start_transfer_in_info)); + } + } +#ifdef ERRSIM + ObTransferEventRecorder::record_transfer_task_event( + task_info.task_id_, "TX_START_TRANSFER_IN", task_info.src_ls_id_, task_info.dest_ls_id_); +#endif + } + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_START_TRANSFER_IN_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_START_TRANSFER_IN_FAILED", K(ret)); + } + } +#endif + + DEBUG_SYNC(AFTER_START_TRANSFER_IN); + + } + return ret; +} + +int ObTransferHandler::inner_tx_start_transfer_in_( + const share::ObTransferTaskInfo &task_info, + const ObTXStartTransferInInfo &start_transfer_in_info, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObArenaAllocator allocator; + observer::ObInnerSQLConnection *conn = NULL; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid() || !start_transfer_in_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("inner tx start transfer in get invalid argument", K(ret), K(task_info), K(start_transfer_in_info)); + } else if (OB_ISNULL(conn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("conn_ is NULL", KR(ret)); + } else { + int64_t buf_len = start_transfer_in_info.get_serialize_size(); + int64_t pos = 0; + char *buf = (char*)allocator.alloc(buf_len); + ObRegisterMdsFlag flag; + flag.need_flush_redo_instantly_ = false; + flag.mds_base_scn_ = start_transfer_in_info.start_scn_; + +#ifdef ERRSIM + flag.need_flush_redo_instantly_ = true; +#endif + if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail alloc memory", KR(ret)); + } else if (OB_FAIL(start_transfer_in_info.serialize(buf, buf_len, pos))) { + LOG_WARN("fail to serialize start transfer out info", KR(ret), K(start_transfer_in_info)); + } else if (OB_FAIL(conn->register_multi_data_source(task_info.tenant_id_, task_info.dest_ls_id_, + transaction::ObTxDataSourceType::START_TRANSFER_IN, buf, buf_len, flag))) { + LOG_WARN("failed to register multi data source", K(ret), K(start_transfer_in_info)); + } + } + return ret; +} + +int ObTransferHandler::update_all_tablet_to_ls_( + const share::ObTransferTaskInfo &task_info, + common::ObISQLClient &trans) +{ + int ret = OB_SUCCESS; +#ifdef ERRSIM + SERVER_EVENT_ADD("TRANSFER", "BEFORE_TRANSFER_UPDATE_TABLET_TO_LS"); +#endif + DEBUG_SYNC(BEFORE_TRANSFER_UPDATE_TABLET_TO_LS); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("update all tablet to ls get invalid argument", K(ret), K(task_info)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < task_info.tablet_list_.count(); ++i) { + const ObTransferTabletInfo &tablet_info = task_info.tablet_list_.at(i); + if (OB_FAIL(ObTabletToLSTableOperator::update_ls_id_and_transfer_seq(trans, task_info.tenant_id_, + tablet_info.tablet_id_, tablet_info.transfer_seq_, task_info.src_ls_id_, + tablet_info.transfer_seq_ + 1, task_info.dest_ls_id_))) { + LOG_WARN("failed to update ls id and transfer seq", K(ret), K(tablet_info), K(task_info)); + } + } + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_UPDATE_ALL_TABLET_TO_LS_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_UPDATE_ALL_TABLET_TO_LS_FAILED", K(ret)); + } + } +#endif + + DEBUG_SYNC(AFTER_UPDATE_TABLET_TO_LS); + + } + return ret; +} + +int ObTransferHandler::lock_tablet_on_dest_ls_for_table_lock_( + const share::ObTransferTaskInfo &task_info, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", KR(ret)); + } else if (OB_UNLIKELY(!task_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("update all tablet to ls get invalid argument", KR(ret), K(task_info)); + } else if (OB_FAIL(ObTransferLockUtil::lock_tablet_on_dest_ls_for_table_lock( + trans, + task_info.tenant_id_, + task_info.dest_ls_id_, + task_info.table_lock_owner_id_, + task_info.table_lock_tablet_list_))) { + LOG_WARN("failed to lock tablet on dest ls for table lock", KR(ret), K(task_info)); + } + return ret; +} + +int ObTransferHandler::update_transfer_status_( + const share::ObTransferTaskInfo &task_info, + const share::ObTransferStatus &next_status, + const SCN &start_scn, + const int32_t result, + common::ObISQLClient &trans) +{ + int ret = OB_SUCCESS; + ObTransferTask transfer_task; + const bool for_update = true; + const uint64_t tenant_id = task_info.tenant_id_; + const ObTransferTaskID task_id = task_info.task_id_; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid() || !next_status.is_valid()) { + LOG_WARN("update transfer status get invalid argument", K(ret), K(task_info), K(next_status)); + } else { + if (OB_FAIL(ObTransferTaskOperator::get(trans, tenant_id, task_id, for_update, transfer_task))) { + LOG_WARN("failed to get transfer task", K(ret), K(task_id), K(tenant_id)); + } else if (task_info.status_ != transfer_task.get_status() + || task_info.src_ls_id_ != transfer_task.get_src_ls() + || task_info.dest_ls_id_ != transfer_task.get_dest_ls()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task info in not equal to inner table transfer task, unexpected", K(ret), + K(task_info), K(transfer_task)); + } else if (start_scn.is_valid() && OB_FAIL(ObTransferTaskOperator::update_start_scn( + trans, tenant_id, task_id, transfer_task.get_status(), start_scn))) { + LOG_WARN("failed to update finish scn", K(ret), K(tenant_id), K(task_id), K(start_scn)); + } else if (OB_FAIL(ObTransferTaskOperator::update_status_and_result( + trans, tenant_id, task_id, transfer_task.get_status(), next_status, result))) { + LOG_WARN("failed to finish task", K(ret), K(tenant_id), K(task_id)); + } else { +#ifdef ERRSIM + ObTransferEventRecorder::record_advance_transfer_status_event( + task_info.tenant_id_, task_info.task_id_, task_info.src_ls_id_, + task_info.dest_ls_id_, next_status, result); +#endif + LOG_INFO("[TRANSFER] set next status", K(start_scn), K(task_info), K(next_status), K(result)); + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_UPDATE_TRANSFER_TASK_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_UPDATE_TRANSFER_TASK_FAILED", K(ret)); + } + } +#endif + } + } + return ret; +} + +int ObTransferHandler::update_transfer_status_aborted_( + const share::ObTransferTaskInfo &task_info, + const int32_t result) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + const share::ObTransferStatus next_status(ObTransferStatus::ABORTED); + ObTimeoutCtx timeout_ctx; + ObMySQLTransaction trans; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + LOG_WARN("update transfer status aborted get invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(start_trans_(timeout_ctx, trans))) { + LOG_WARN("failed to start trans", K(ret), K(task_info)); + } else { + const SCN scn = task_info.start_scn_; + if (OB_FAIL(lock_transfer_task_(task_info, trans))) { + LOG_WARN("failed to lock transfer task", K(ret), K(task_info)); + } else if (OB_FAIL(update_transfer_status_(task_info, next_status, scn, result, trans))) { + LOG_WARN("failed to update transfer status", K(ret), K(task_info), K(next_status)); + } + + if (OB_TMP_FAIL(commit_trans_(ret, trans))) { + LOG_WARN("failed to commit trans", K(tmp_ret), K(ret)); + if (OB_SUCCESS == ret) { + ret = tmp_ret; + } + } + } + return ret; +} + +bool ObTransferHandler::can_retry_( + const share::ObTransferTaskInfo &task_info, + const int32_t result) +{ + bool bool_ret = false; + const int64_t MAX_TRANSFER_START_RETRY_COUNT = GCONF._transfer_start_retry_count; + if (!task_info.is_valid()) { + bool_ret = false; + } else if (ObTransferStatus::DOING == task_info.status_) { + bool_ret = true; + retry_count_++; + } else if (ObTransferStatus::START == task_info.status_) { + if (ObTransferUtils::is_need_retry_error(result) && retry_count_ < MAX_TRANSFER_START_RETRY_COUNT) { + retry_count_++; + bool_ret = true; + } else { + bool_ret = false; + } + +#ifdef ERRSIM + if (!bool_ret) { + //do nothing + } else { + bool_ret = EN_START_CAN_NOT_RETRY ? false: true; + } +#endif + } else if (ObTransferStatus::ABORTED == task_info.status_) { + bool_ret = true; + retry_count_++; + } else { + bool_ret = false; + } + return bool_ret; +} + +// TODO(yangyi.yyy): Found a problem that only the leader reports the tablet meta table here. However, +// this is not correct. Every replica needs to be reported, otherwise the __all_tablet_meta_table will not be updated. +// WILL FIX THIS LATER +int ObTransferHandler::report_to_meta_table_( + const share::ObTransferTaskInfo &task_info) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + observer::ObIMetaReport *reporter = GCTX.ob_service_; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + LOG_WARN("reoirt to meta table get invalid argument", K(ret), K(task_info)); + } else if (OB_ISNULL(reporter)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("meta report shuold not be NULL", K(ret), KP(reporter)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < task_info.tablet_list_.count(); ++i) { + const ObTransferTabletInfo &tablet_info = task_info.tablet_list_.at(i); + if (OB_SUCCESS != (tmp_ret = reporter->submit_tablet_update_task( + task_info.tenant_id_, task_info.dest_ls_id_, tablet_info.tablet_id_))) { + LOG_WARN("failed to submit tablet update task", K(ret), K(tablet_info), K(task_info)); + } + } + } + return ret; +} + +int ObTransferHandler::do_with_doing_status_(const share::ObTransferTaskInfo &task_info) +{ + int ret = OB_SUCCESS; + ObTxFinishTransfer finish_transfer; + const ObTransferTaskID task_id = task_info.task_id_; + const uint64_t tenant_id = task_info.tenant_id_; + const share::ObLSID &src_ls_id = task_info.src_ls_id_; + const share::ObLSID &dest_ls_id = task_info.dest_ls_id_; + + if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get ls leader get invalid argument", K(ret), K(task_info)); + } else if (OB_FAIL(finish_transfer.init( + task_id, tenant_id, src_ls_id, dest_ls_id, *sql_proxy_))) { + LOG_INFO("[TRANSFER] do with doing status", K(task_info)); + } else if (OB_FAIL(finish_transfer.process())) { + LOG_WARN("failed to process", K(ret)); + } + + if (OB_FAIL(ret)) { + if (can_retry_(task_info, ret)) { + LOG_INFO("transfer task can retry", K(ret), K(task_info)); + ob_usleep(INTERVAL_US); + wakeup_(); + } + } + return ret; +} + +int ObTransferHandler::do_with_aborted_status_( + const share::ObTransferTaskInfo &task_info) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + const share::ObTransferStatus next_status(ObTransferStatus::FAILED); + ObTimeoutCtx timeout_ctx; + ObMySQLTransaction trans; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (!task_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get ls leader get invalid argument", K(ret), K(task_info)); + } else { + if (OB_FAIL(start_trans_(timeout_ctx, trans))) { + LOG_WARN("failed to start trans", K(ret), K(task_info)); + } else { + const SCN scn = task_info.start_scn_; + const int32_t result = task_info.result_; + if (OB_FAIL(lock_transfer_task_(task_info, trans))) { + LOG_WARN("failed to lock transfer task", K(ret), K(task_info)); + } else if (OB_FAIL(update_transfer_status_(task_info, next_status, scn, result, trans))) { + LOG_WARN("failed to update transfer status", K(ret), K(task_info), K(next_status)); + } else if (OB_FAIL(unblock_tx_(task_info.tenant_id_, task_info.src_ls_id_))) { + LOG_WARN("failed to unblock tx", K(ret), K(task_info)); + } else if (OB_FAIL(unlock_src_and_dest_ls_member_list_(task_info))) { + LOG_WARN("failed to unlock src and dest ls member list", K(ret), K(task_info)); + } + + if (OB_TMP_FAIL(commit_trans_(ret, trans))) { + LOG_WARN("failed to commit trans", K(tmp_ret), K(ret)); + if (OB_SUCCESS == ret) { + ret = tmp_ret; + } + } + } + } + + if (OB_FAIL(ret)) { + if (can_retry_(task_info, ret)) { + LOG_INFO("transfer task can retry", K(ret), K(task_info)); + ob_usleep(INTERVAL_US); + } + } + return ret; +} + +int ObTransferHandler::do_worker_transfer_() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("transfer handler do not init", K(ret)); + } else if (OB_FAIL(transfer_worker_mgr_.process())) { + LOG_WARN("failed to process transfer backfill TX or replace logical table", K(ret)); + } else { + LOG_INFO("do worker transfer", KPC(ls_)); + } + return ret; +} + +int ObTransferHandler::block_and_kill_tx_( + const share::ObTransferTaskInfo &task_info, + const bool enable_kill_trx, + const int64_t kill_trx_threshold, + ObTimeoutCtx &timeout_ctx) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = task_info.tenant_id_; + const share::ObLSID &src_ls_id = task_info.src_ls_id_; + if (OB_FAIL(block_tx_(tenant_id, src_ls_id))) { + LOG_WARN("failed to block tx", K(ret), K(task_info)); + } else if (!enable_kill_trx) { + LOG_INFO("transfer no need kill tx", K(task_info)); + } else if (OB_FAIL(check_for_kill_(tenant_id, src_ls_id, kill_trx_threshold, false/*is_after_kill*/, timeout_ctx))) { + LOG_WARN("failed to check before kill", K(ret)); + } else if (OB_FAIL(kill_tx_(tenant_id, src_ls_id))) { + LOG_WARN("failed to kill tx", K(ret)); + } else if (OB_FAIL(check_for_kill_(tenant_id, src_ls_id, kill_trx_threshold, true/*is_after_kill*/, timeout_ctx))) { + LOG_WARN("failed to check after kill", K(ret)); + } +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "AFTER_TRANSFER_BLOCK_AND_KILL_TX"); +#endif + DEBUG_SYNC(AFTER_TRANSFER_BLOCK_AND_KILL_TX); + return ret; +} + +int ObTransferHandler::check_for_kill_( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const int64_t timeout, + const bool is_after_kill, + ObTimeoutCtx &timeout_ctx) +{ + int ret = OB_SUCCESS; + static const int64_t CHECK_INTERVAL = 10_ms; + const int64_t start_ts = ObTimeUtility::current_time(); + do { + const int64_t cur_ts = ObTimeUtility::current_time(); + int64_t active_trans_count = 0; + if (timeout_ctx.is_timeouted()) { + ret = OB_TIMEOUT; + LOG_WARN("trans ctx already timeout", K(ret)); + } else if (cur_ts - start_ts > timeout) { + if (is_after_kill) { + ret = OB_TIMEOUT; + LOG_WARN("check active trans after kill timeout", K(cur_ts), K(start_ts)); + } else { + break; + } + } else if (OB_ISNULL(ls_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be null", K(ret)); + } else if (ls_->is_stopped()) { + ret = OB_NOT_RUNNING; + LOG_WARN("ls is not running, stop checking", K(ret)); + } else if (OB_FAIL(get_ls_active_trans_count_(ls_id, active_trans_count))) { + LOG_WARN("failed to get src ls has active trans", K(ret)); + } else if (0 != active_trans_count) { + LOG_INFO("still has active trans", K(tenant_id), K(ls_id), K(active_trans_count)); + } else { + break; + } + ob_usleep(CHECK_INTERVAL); + } while (OB_SUCC(ret)); + return ret; +} + +int ObTransferHandler::block_tx_( + const uint64_t tenant_id, + const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObTransferUtils::block_tx(tenant_id, ls_id))) { + LOG_WARN("failed to block tx", K(ret), K(tenant_id), K(ls_id)); + } + return ret; +} + +int ObTransferHandler::kill_tx_( + const uint64_t tenant_id, + const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObTransferUtils::kill_tx(tenant_id, ls_id))) { + LOG_WARN("failed to kill tx", K(ret), K(tenant_id), K(ls_id)); + } + return ret; +} + +int ObTransferHandler::unblock_tx_( + const uint64_t tenant_id, + const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObTransferUtils::unblock_tx(tenant_id, ls_id))) { + LOG_WARN("failed to unblock tx", K(ret), K(tenant_id), K(ls_id)); + } +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "AFTER_TRANSFER_UNBLOCK_TX"); +#endif + DEBUG_SYNC(AFTER_TRANSFER_UNBLOCK_TX); + return ret; +} + } } diff --git a/src/storage/high_availability/ob_transfer_handler.h b/src/storage/high_availability/ob_transfer_handler.h index 9a50bd5a5..0d549dc99 100644 --- a/src/storage/high_availability/ob_transfer_handler.h +++ b/src/storage/high_availability/ob_transfer_handler.h @@ -15,87 +15,207 @@ #include "ob_storage_ha_struct.h" #include "share/ob_define.h" +#include "share/ob_ls_id.h" +#include "share/ob_balance_define.h" // share::ObTransferTaskID +#include "common/ob_member.h" +#include "common/ob_tablet_id.h" +#include "lib/container/ob_array.h" +#include "ob_storage_ha_struct.h" +#include "share/ob_common_rpc_proxy.h" +#include "observer/ob_rpc_processor_simple.h" +#include "share/scheduler/ob_dag_scheduler.h" +#include "storage/ob_storage_rpc.h" +#include "share/transfer/ob_transfer_info.h" +#include "observer/ob_inner_sql_connection.h" +#include "ob_transfer_struct.h" +#include "ob_transfer_backfill_tx.h" +#include "lib/thread/thread_mgr_interface.h" +#include "logservice/ob_log_base_type.h" namespace oceanbase { namespace storage { -enum ObTransferStatus -{ - TRANSFER_NONE = 0, - TRANSFER_DATA_COPY_ITERM1 = 1, - TRANSFER_DATA_COPY_ITERM2 = 2, - TRANFER_FAIL = 3, - MAX, -}; - -struct ObTabletTransferInfo -{ - ObTabletTransferInfo(); - virtual ~ObTabletTransferInfo() = default; - int update_snapshot_log_ts(); - void reset(); - bool is_valid() const; - - VIRTUAL_TO_STRING_KV(K_(tablet_id), K_(snapshot_log_ts), K_(status)); - - common::ObTabletID tablet_id_; - int64_t snapshot_log_ts_; - ObTransferStatus status_; -}; - -struct ObTablesTransferTask -{ - ObTablesTransferTask(); - virtual ~ObTablesTransferTask(); - bool is_valid() const; - void reset(); - VIRTUAL_TO_STRING_KV(K_(tablet_transfer_info_array), K_(src_ls_id), K_(dst_ls_id), K_(task_id)); - - ObArray tablet_transfer_info_array_; - int result_; - share::ObLSID src_ls_id_; - share::ObLSID dst_ls_id_; - share::ObTaskId task_id_; -}; - - -class ObTransferHandler +class ObTransferHandler : public ObIHAHandler, + public logservice::ObIReplaySubHandler, + public logservice::ObIRoleChangeSubHandler, + public logservice::ObICheckpointSubHandler { public: ObTransferHandler(); virtual ~ObTransferHandler(); - int init(); + int init( + ObLS *ls, + common::ObInOutBandwidthThrottle *bandwidth_throttle, + obrpc::ObStorageRpcProxy *svr_rpc_proxy, + storage::ObStorageRpc *storage_rpc, + common::ObMySQLProxy *sql_proxy); virtual int process(); - int add_tablets(); - int add_tablets_for_relay(); - int check_task_exist(const share::ObTaskId &task_id, bool &is_exist); + void destroy(); + virtual void switch_to_follower_forcedly() override; + virtual int switch_to_leader() override; + virtual int switch_to_follower_gracefully() override; + virtual int resume_leader() override; + + // transfer handler no need to use the above func + virtual int replay(const void *buffer, + const int64_t nbytes, + const palf::LSN &lsn, + const share::SCN &scn) override final; + virtual share::SCN get_rec_scn() override final { return share::SCN::max_scn(); } + virtual int flush(share::SCN &scn) override final; + private: - int try_transfer_in_start_(); - int generate_tablet_task_(); - int create_tablets_(); - int scheduler_tablets_task_(); - int do_with_trans_status_(const ObTablesTransferTask &transfer_task); - int do_data_copy_item1_(); - int do_data_copy_item2_(); - int change_transfer_status_(); - int get_tablets_effective_member_(); - int genreate_tablet_task_info_(); - int do_check_follower_finish_(); - int transfer_in_(); - int transfer_in_finish_(); - int transfer_in_abort_(); - int transfer_out_(); - int transfer_out_finish_(); + int get_transfer_task_(share::ObTransferTaskInfo &task_info); + int get_transfer_task_from_inner_table_( + const share::ObTransferTaskID &task_id, + const bool for_update, + common::ObISQLClient &trans, + share::ObTransferTaskInfo &task_info); + int get_transfer_task_from_inner_table_( + share::ObTransferTaskInfo &task_info); + void wakeup_(); + + int do_leader_transfer_(); + int do_worker_transfer_(); + int get_transfer_task_(); + int block_and_kill_all_tx_if_need_(const share::ObTransferTaskInfo &task_info); + int do_with_start_status_(const share::ObTransferTaskInfo &task_info); + int do_with_doing_status_(const share::ObTransferTaskInfo &task_info); + int do_with_aborted_status_(const share::ObTransferTaskInfo &task_info); + int check_self_is_leader_(bool &is_leader); + int lock_src_and_dest_ls_member_list_( + const share::ObTransferTaskInfo &task_info, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls); + int unlock_src_and_dest_ls_member_list_( + const share::ObTransferTaskInfo &task_info); + int reset_timeout_for_trans_(ObTimeoutCtx &timeout_ctx); + int inner_lock_ls_member_list_( + const share::ObTransferTaskInfo &task_info, + const share::ObLSID &ls_id, + const common::ObMemberList &member_list); + int inner_unlock_ls_member_list_( + const share::ObTransferTaskInfo &task_info, + const share::ObLSID &ls_id, + const common::ObMemberList &member_list); + int insert_lock_info_(const share::ObTransferTaskInfo &task_info); + int check_ls_member_list_same_( + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls, + common::ObMemberList &member_list, + bool &is_same); + int get_ls_member_list_( + const share::ObLSID &ls_id, + common::ObMemberList &member_list); + int check_src_ls_has_active_trans_( + const share::ObLSID &src_ls_id, + const int64_t expected_active_trans_count = 0); + int get_ls_active_trans_count_( + const share::ObLSID &ls_id, + int64_t &active_trans_count); + int check_start_status_transfer_tablets_( + const share::ObTransferTaskInfo &task_info); + int get_ls_leader_( + const share::ObLSID &ls_id, + common::ObAddr &addr); + int do_trans_transfer_start_( + const share::ObTransferTaskInfo &task_info, + ObTimeoutCtx &timeout_ctx, + ObMySQLTransaction &trans); + int start_trans_( + ObTimeoutCtx &timeout_ctx, + ObMySQLTransaction &trans); + int commit_trans_( + const int32_t &result, + ObMySQLTransaction &trans); + + int do_tx_start_transfer_out_( + const share::ObTransferTaskInfo &task_info, + common::ObMySQLTransaction &trans); + int lock_transfer_task_( + const share::ObTransferTaskInfo &task_info, + common::ObISQLClient &trans); + int get_start_transfer_out_scn_( + const share::ObTransferTaskInfo &task_info, + ObTimeoutCtx &timeout_ctx, + share::SCN &start_scn); + int wait_src_ls_replay_to_start_scn_( + const share::ObTransferTaskInfo &task_info, + const share::SCN &start_scn, + ObTimeoutCtx &timeout_ctx); + int get_transfer_tablets_meta_( + const share::ObTransferTaskInfo &task_info, + common::ObIArray ¶ms); + int do_tx_start_transfer_in_( + const share::ObTransferTaskInfo &task_info, + const share::SCN &start_scn, + const common::ObIArray ¶ms, + ObTimeoutCtx &timeout_ctx, + common::ObMySQLTransaction &trans); + int inner_tx_start_transfer_in_( + const share::ObTransferTaskInfo &task_info, + const ObTXStartTransferInInfo &start_transfer_in_info, + common::ObMySQLTransaction &trans); + int update_all_tablet_to_ls_( + const share::ObTransferTaskInfo &task_info, + common::ObISQLClient &trans); + int lock_tablet_on_dest_ls_for_table_lock_( + const share::ObTransferTaskInfo &task_info, + common::ObMySQLTransaction &trans); + int update_transfer_status_( + const share::ObTransferTaskInfo &task_info, + const share::ObTransferStatus &next_status, + const share::SCN &start_scn, + const int32_t result, + common::ObISQLClient &trans); + int update_transfer_status_aborted_( + const share::ObTransferTaskInfo &task_info, + const int32_t result); + bool can_retry_( + const share::ObTransferTaskInfo &task_info, + const int32_t result); + int report_to_meta_table_( + const share::ObTransferTaskInfo &task_info); + int block_and_kill_tx_( + const share::ObTransferTaskInfo &task_info, + const bool enable_kill_trx, + const int64_t kill_trx_threshold, + ObTimeoutCtx &timeout_ctx); + int block_tx_( + const uint64_t tenant_id, + const share::ObLSID &ls_id); + int check_for_kill_( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const int64_t timeout, + const bool is_after_kill, + ObTimeoutCtx &timeout_ctx); + int kill_tx_( + const uint64_t tenant_id, + const share::ObLSID &ls_id); + int unblock_tx_( + const uint64_t tenant_id, + const share::ObLSID &ls_id); + int get_gts_( + const uint64_t tenant_id, + const share::ObLSID &ls_id); +private: + static const int64_t INTERVAL_US = 1 * 1000 * 1000; //1s + static const int64_t KILL_TX_MAX_RETRY_TIMES = 3; private: bool is_inited_; -// common::SpinRWLock lock_; not used yet - ObSEArray tablets_transfer_array_; + ObLS *ls_; + common::ObInOutBandwidthThrottle *bandwidth_throttle_; + obrpc::ObStorageRpcProxy *svr_rpc_proxy_; + storage::ObStorageRpc *storage_rpc_; + common::ObMySQLProxy *sql_proxy_; + + int64_t retry_count_; + ObTransferWorkerMgr transfer_worker_mgr_; DISALLOW_COPY_AND_ASSIGN(ObTransferHandler); }; - - } } #endif diff --git a/src/storage/high_availability/ob_transfer_lock_info_operator.cpp b/src/storage/high_availability/ob_transfer_lock_info_operator.cpp new file mode 100644 index 000000000..d6d1d44a6 --- /dev/null +++ b/src/storage/high_availability/ob_transfer_lock_info_operator.cpp @@ -0,0 +1,225 @@ +/** + * 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. + */ +#define USING_LOG_PREFIX STORAGE + +#include "ob_transfer_lock_info_operator.h" +#include "share/ob_dml_sql_splicer.h" +#include "lib/mysqlclient/ob_mysql_proxy.h" +#include "share/inner_table/ob_inner_table_schema.h" +#include "observer/omt/ob_tenant_timezone_mgr.h" // for OTTZ_MGR.get_tenant_tz +#include "observer/ob_server_event_history_table_operator.h" +#include "storage/ob_common_id_utils.h" + +using namespace oceanbase::common; +using namespace oceanbase::share; + +namespace oceanbase { +namespace storage { + +/* ObTransferLockInfoOperator */ + +int ObTransferLockInfoOperator::insert(const ObTransferTaskLockInfo &lock_info, common::ObISQLClient &sql_proxy) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = lock_info.tenant_id_; + if (!lock_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(lock_info)); + } else { + ObSqlString sql; + ObDMLSqlSplicer dml_splicer; + int64_t affected_rows = 0; + if (OB_FAIL(fill_dml_splicer_(lock_info, dml_splicer))) { + LOG_WARN("failed to fill dml splicer", K(ret), K(tenant_id), K(lock_info)); + } else if (OB_FAIL(dml_splicer.finish_row())) { + LOG_WARN("failed to finish row", K(ret), K(tenant_id), K(lock_info)); + } else if (OB_FAIL(dml_splicer.splice_insert_sql(OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TNAME, sql))) { + LOG_WARN("failed to splice insert sql", K(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(sql_proxy.write(gen_meta_tenant_id(tenant_id), sql.ptr(), affected_rows))) { + if (OB_ERR_PRIMARY_KEY_DUPLICATE == ret) { + ret = OB_ENTRY_EXIST; + } else { + LOG_WARN("fail to write sql", K(ret), K(tenant_id), K(sql), K(affected_rows)); + } + } else { +#ifdef ERRSIM + SERVER_EVENT_ADD("TRANSFER_LOCK", "INSERT_LOCK_INFO", + "tenant_id", lock_info.tenant_id_, + "ls_id", lock_info.ls_id_.id(), + "task_id", lock_info.task_id_, + "status", lock_info.status_.str(), + "lock_owner", lock_info.lock_owner_, + "sql", sql); +#endif + LOG_INFO("insert transfer lock info success", K(tenant_id), K(sql), K(affected_rows)); + } + } + return ret; +} + +int ObTransferLockInfoOperator::remove(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const ObTransferLockStatus &status, common::ObISQLClient &sql_proxy) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t affected_rows = 0; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(task_id)); + } else if (OB_FAIL(sql.assign_fmt("DELETE FROM %s WHERE tenant_id = %lu and ls_id = %ld" + " and task_id = %ld and status = '%s'", + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TNAME, + tenant_id, + ls_id.id(), + task_id, + status.str()))) { + LOG_WARN("failed to assign sql", K(ret), K(tenant_id), K(ls_id), K(task_id), K(status)); + } else if (OB_FAIL(sql_proxy.write(gen_meta_tenant_id(tenant_id), sql.ptr(), affected_rows))) { + LOG_WARN("failed to write sql", K(ret), K(tenant_id), K(sql), K(affected_rows)); + } else if (OB_UNLIKELY(0 == affected_rows)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("incorrect affected rows", K(ret), K(tenant_id), K(task_id), K(affected_rows)); + } else if (OB_UNLIKELY(1 < affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("delete more than one row", K(ret), K(tenant_id), K(affected_rows), K(sql)); + } else { +#ifdef ERRSIM + SERVER_EVENT_ADD("TRANSFER_LOCK", "REMOVE_LOCK_INFO", + "tenant_id", tenant_id, + "ls_id", ls_id.id(), + "task_id", task_id, + "status", status.str(), + "sql", sql); +#endif + LOG_INFO("remove lock info success", K(tenant_id), K(ls_id), K(sql)); + } + return ret; +} + +int ObTransferLockInfoOperator::get(const ObTransferLockInfoRowKey &row_key, const int64_t task_id, + const ObTransferLockStatus &status, const bool for_update, ObTransferTaskLockInfo &lock_info, + common::ObISQLClient &sql_proxy) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = row_key.tenant_id_; + if (OB_UNLIKELY(!row_key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(task_id), K(for_update)); + } else { + ObSqlString sql; + SMART_VAR(ObISQLClient::ReadResult, result) + { + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %lu and ls_id = %ld" + " and task_id = %ld and status = '%s' %s", + OB_ALL_LS_TRANSFER_MEMBER_LIST_LOCK_INFO_TNAME, + row_key.tenant_id_, + row_key.ls_id_.id(), + task_id, + status.str(), + for_update ? " FOR UPDATE" : ""))) { + LOG_WARN("fail to assign sql", K(ret), K(tenant_id), K(row_key), K(task_id), K(status), K(for_update)); + } else if (OB_FAIL(sql_proxy.read(result, gen_meta_tenant_id(tenant_id), sql.ptr()))) { + LOG_WARN("execute sql failed", K(ret), K(tenant_id), K(sql)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", K(ret), K(tenant_id), K(sql)); + } else if (OB_FAIL(construct_result_(*result.get_result(), lock_info))) { + LOG_WARN("construct transfer task failed", K(ret), K(tenant_id), K(row_key), K(sql)); + } else { + LOG_INFO("get lock info success", K(tenant_id), K(row_key), K(task_id), K(status), K(row_key), K(sql)); + } + } + } + return ret; +} + +int ObTransferLockInfoOperator::fill_dml_splicer_(const ObTransferTaskLockInfo &lock_info, ObDMLSqlSplicer &dml_splicer) +{ + int ret = OB_SUCCESS; + if (!lock_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(lock_info)); + } else if (OB_FAIL(dml_splicer.add_pk_column("tenant_id", lock_info.tenant_id_)) || + OB_FAIL(dml_splicer.add_pk_column("ls_id", lock_info.ls_id_.id())) || + OB_FAIL(dml_splicer.add_column("task_id", lock_info.task_id_)) || + OB_FAIL(dml_splicer.add_column("status", lock_info.status_.str())) || + OB_FAIL(dml_splicer.add_column("lock_owner", lock_info.lock_owner_)) || + OB_FAIL(dml_splicer.add_column("comment", lock_info.comment_.string()))) { + LOG_WARN("fail to add column", K(ret), K(lock_info)); + } + return ret; +} + +int ObTransferLockInfoOperator::construct_result_( + common::sqlclient::ObMySQLResult &res, ObTransferTaskLockInfo &lock_info) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(res.next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + } else { + LOG_WARN("get next result failed", K(ret)); + } + } else if (OB_FAIL(parse_sql_result_(res, lock_info))) { + LOG_WARN("parse sql result failed", K(ret)); + } else if (OB_FAIL(res.next())) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("get next result failed", K(ret)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("read more than one row", K(ret)); + } + return ret; +} + +int ObTransferLockInfoOperator::parse_sql_result_( + common::sqlclient::ObMySQLResult &res, ObTransferTaskLockInfo &lock_info) +{ + int ret = OB_SUCCESS; + lock_info.reset(); + int64_t create_time = OB_INVALID_TIMESTAMP; + int64_t finish_time = OB_INVALID_TIMESTAMP; + int64_t tenant_id = 0; + int64_t ls_id; + int64_t task_id = 0; + ObString status_str; + int64_t lock_owner = 0; + ObString comment; + ObTransferLockStatus status; + { + ObTimeZoneInfoWrap tz_info_wrap; + ObTZMapWrap tz_map_wrap; + OZ(OTTZ_MGR.get_tenant_tz(tenant_id, tz_map_wrap)); + tz_info_wrap.set_tz_info_map(tz_map_wrap.get_tz_map()); + (void)GET_COL_IGNORE_NULL(res.get_timestamp, "gmt_create", tz_info_wrap.get_time_zone_info(), create_time); + (void)GET_COL_IGNORE_NULL(res.get_timestamp, "gmt_modified", tz_info_wrap.get_time_zone_info(), finish_time); + } + (void)GET_COL_IGNORE_NULL(res.get_int, "tenant_id", tenant_id); + (void)GET_COL_IGNORE_NULL(res.get_int, "ls_id", ls_id); + (void)GET_COL_IGNORE_NULL(res.get_int, "task_id", task_id); + (void)GET_COL_IGNORE_NULL(res.get_varchar, "status", status_str); + (void)GET_COL_IGNORE_NULL(res.get_int, "lock_owner", lock_owner); + (void)GET_COL_IGNORE_NULL(res.get_varchar, "comment", comment); + + if (OB_FAIL(status.parse_from_str(status_str))) { + LOG_WARN("failed to parse from str", K(ret), K(status_str)); + } else if (FAILEDx(lock_info.set(tenant_id, ObLSID(ls_id), task_id, status, lock_owner, comment))) { + LOG_WARN("failed to set lock info", K(ret), K(ls_id), K(task_id), K(status), K(lock_owner), K(comment)); + } + return ret; +} + +} // namespace storage +} // namespace oceanbase \ No newline at end of file diff --git a/src/storage/high_availability/ob_transfer_lock_info_operator.h b/src/storage/high_availability/ob_transfer_lock_info_operator.h new file mode 100644 index 000000000..774c19bed --- /dev/null +++ b/src/storage/high_availability/ob_transfer_lock_info_operator.h @@ -0,0 +1,46 @@ + +/** + * 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_OB_TRANSFER_TASK_LOCK_INFO_OPERATOR_H +#define OCEANBASE_OB_TRANSFER_TASK_LOCK_INFO_OPERATOR_H + +#include "share/ob_dml_sql_splicer.h" +#include "share/ob_ls_id.h" +#include "lib/string/ob_sql_string.h" +#include "lib/mysqlclient/ob_mysql_result.h" +#include "ob_transfer_struct.h" + +namespace oceanbase { +namespace storage { + +class ObTransferLockInfoOperator final { +public: + ObTransferLockInfoOperator() = default; + ~ObTransferLockInfoOperator() = default; + + static int insert(const ObTransferTaskLockInfo &lock_info, common::ObISQLClient &sql_proxy); + static int remove(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const ObTransferLockStatus &status, common::ObISQLClient &sql_proxy); + static int get(const ObTransferLockInfoRowKey &row_key, const int64_t task_id, const ObTransferLockStatus &status, + const bool for_update, ObTransferTaskLockInfo &lock_info, common::ObISQLClient &sql_proxy); + +private: + static int fill_dml_splicer_(const ObTransferTaskLockInfo &lock_info, share::ObDMLSqlSplicer &dml_splicer); + static int construct_result_(common::sqlclient::ObMySQLResult &res, ObTransferTaskLockInfo &lock_info); + static int parse_sql_result_(common::sqlclient::ObMySQLResult &res, ObTransferTaskLockInfo &lock_info); +}; + +} // namespace storage +} // namespace oceanbase + +#endif \ No newline at end of file diff --git a/src/storage/high_availability/ob_transfer_lock_utils.cpp b/src/storage/high_availability/ob_transfer_lock_utils.cpp new file mode 100644 index 000000000..c6d91d699 --- /dev/null +++ b/src/storage/high_availability/ob_transfer_lock_utils.cpp @@ -0,0 +1,511 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "ob_transfer_lock_utils.h" +#include "ob_transfer_lock_info_operator.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "share/ob_max_id_fetcher.h" +#include "storage/ob_common_id_utils.h" +#include "share/ob_common_id.h" +#include "observer/ob_server_event_history_table_operator.h" + +using namespace oceanbase::share; +using namespace oceanbase::common; + +namespace oceanbase { +namespace storage { + +ERRSIM_POINT_DEF(EN_START_UNLOCK_CONFIG_CHANGE_SUCC_AND_REMOVE_INNER_TABLE_FAILED); +ERRSIM_POINT_DEF(EN_DOING_UNLOCK_CONFIG_CHANGE_SUCC_AND_REMOVE_INNER_TABLE_FAILED); + +static int get_ls_handle(const uint64_t tenant_id, const share::ObLSID &ls_id, storage::ObLSHandle &ls_handle) +{ + int ret = OB_SUCCESS; + ls_handle.reset(); + ObLSService *ls_service = NULL; + if (OB_INVALID_ID == tenant_id || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_ISNULL(ls_service = MTL_WITH_CHECK_TENANT(ObLSService *, tenant_id))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream service is NULL", K(ret), K(tenant_id)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get log stream", K(ret), K(tenant_id), K(ls_id)); + } + return ret; +} + +int ObMemberListLockUtils::batch_lock_ls_member_list(const uint64_t tenant_id, const int64_t task_id, + const common::ObArray &lock_ls_list, const common::ObMemberList &member_list, + const ObTransferLockStatus &status, common::ObMySQLProxy &sql_proxy) +{ + int ret = OB_SUCCESS; + ObArray sorted_ls_list; + if (OB_FAIL(sorted_ls_list.assign(lock_ls_list))) { + LOG_WARN("failed to assign ls list", K(ret)); + } else { + std::sort(sorted_ls_list.begin(), sorted_ls_list.end()); + for (int64_t i = 0; OB_SUCC(ret) && i < sorted_ls_list.count(); ++i) { + const share::ObLSID &ls_id = sorted_ls_list.at(i); + ObLSService *ls_srv = NULL; + ObLSHandle ls_handle; + ObLS *ls = NULL; + if (OB_ISNULL(ls_srv = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls srv should not be NULL", K(ret), KP(ls_srv)); + } else if (OB_FAIL(ls_srv->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_ERROR("ls_srv->get_ls() fail", KR(ret)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); + } else if (OB_FAIL(lock_ls_member_list(tenant_id, ls_id, task_id, member_list, status, ls, sql_proxy))) { + LOG_WARN("failed to lock ls member list", K(ret), K(ls_id), K(member_list)); + } + } + } + return ret; +} + +int ObMemberListLockUtils::lock_ls_member_list(const uint64_t tenant_id, const share::ObLSID &ls_id, + const int64_t task_id, const common::ObMemberList &member_list, const ObTransferLockStatus &status, ObLS *ls, + common::ObMySQLProxy &sql_proxy) +{ + int ret = OB_SUCCESS; + int64_t lock_owner = -1; + int64_t real_lock_owner = -1; + ObSqlString member_list_str; + const int64_t lock_timeout = CONFIG_CHANGE_TIMEOUT; + if (OB_ISNULL(ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be null", K(ret), KP(ls)); + } else if (!ls_id.is_valid() || !member_list.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(ls_id)); + } else if (OB_FAIL(unlock_ls_member_list(tenant_id, ls_id, task_id, member_list, status, sql_proxy))) { + LOG_WARN("failed to unlock ls member list", K(ret)); + } else if (OB_FAIL(get_lock_owner(tenant_id, ls_id, task_id, status, sql_proxy, lock_owner))) { + LOG_WARN("failed to get lock owner", K(ret), K(tenant_id), K(ls_id), K(task_id), K(status)); + } else if (OB_FAIL(get_member_list_str(member_list, member_list_str))) { + LOG_WARN("failed to get member list str", K(ret), K(member_list)); + } else if (OB_FAIL( + insert_lock_info(tenant_id, ls_id, task_id, status, lock_owner, member_list_str.ptr(), real_lock_owner, sql_proxy))) { + LOG_WARN("failed to insert lock info", K(ret), K(ls_id), K(task_id)); + } else { +#ifdef ERRSIM + if (GCONF.errsim_transfer_ls_id == ls_id.id()) { + SERVER_EVENT_SYNC_ADD("transfer", "BETWEEN_INSERT_LOCK_INFO_AND_TRY_LOCK_CONFIG_CHANGE"); + DEBUG_SYNC(BETWEEN_INSERT_LOCK_INFO_AND_TRY_LOCK_CONFIG_CHANGE); + } +#endif + ObTransferTaskLockInfo lock_info; + int64_t palf_lock_owner = -1; + bool palf_is_locked = false; + bool need_lock_palf = false; + if (OB_FAIL(lock_info.set(tenant_id, ls_id, task_id, status, real_lock_owner, member_list_str.ptr()))) { + LOG_WARN("failed to set lock info", K(ret), K(tenant_id), K(ls_id), K(task_id), K(status), K(real_lock_owner)); + } else if (OB_FAIL(ls->get_config_change_lock_stat(palf_lock_owner, palf_is_locked))) { + LOG_WARN("failed to get config change lock stat", K(ret), KPC(ls), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(check_lock_status_(palf_is_locked, palf_lock_owner, real_lock_owner, need_lock_palf))) { + LOG_WARN("failed to check lock status", K(ret), K(palf_is_locked), K(palf_lock_owner), K(real_lock_owner)); + } else if (need_lock_palf && OB_FAIL(try_lock_config_change(lock_info, lock_timeout, ls))) { + LOG_WARN("failed to try lock config config", + K(ret), + K(tenant_id), + K(ls_id), + K(palf_lock_owner), + K(palf_is_locked), + K(lock_owner), + K(lock_info)); + } else { + LOG_INFO("lock ls member list", K(lock_info), K(palf_lock_owner), K(palf_is_locked), K(real_lock_owner)); + } + } + + return ret; +} + +int ObMemberListLockUtils::unlock_ls_member_list(const uint64_t tenant_id, const share::ObLSID &ls_id, + const int64_t task_id, const common::ObMemberList &member_list, const ObTransferLockStatus &status, + common::ObMySQLProxy &sql_proxy) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + const int64_t lock_timeout = CONFIG_CHANGE_TIMEOUT; + if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(ls_id), K(member_list)); + } else { + ObMySQLTransaction trans; + ObTransferLockInfoRowKey row_key; + const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id); + row_key.tenant_id_ = tenant_id; + row_key.ls_id_ = ls_id; + if (OB_FAIL(trans.start(&sql_proxy, meta_tenant_id))) { + LOG_WARN("failed to start trans", K(ret), K(meta_tenant_id)); + } else { + int64_t lock_owner = -1; + ObTransferTaskLockInfo lock_info; + const bool for_update = true; + bool palf_is_locked = false; + int64_t palf_lock_owner = -1; + bool need_unlock = true; + bool need_relock_before_unlock = false; + storage::ObLSHandle ls_handle; + storage::ObLS *ls = NULL; + + if (OB_FAIL(ObTransferLockInfoOperator::get(row_key, task_id, status, for_update, lock_info, trans))) { + if (OB_ENTRY_NOT_EXIST == ret) { // palf need to be unlocked + ret = OB_SUCCESS; + LOG_INFO("member list already unlocked", + K(tenant_id), + K(row_key), + K(task_id), + K(status), + K(palf_lock_owner), + K(palf_is_locked)); + } else { + LOG_WARN("failed to get lock info", K(ret), K(tenant_id), K(row_key)); + } + } else if (OB_FAIL(get_ls_handle(tenant_id, ls_id, ls_handle))) { + LOG_WARN("failed to get ls handle", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be null", K(ret)); + } else if (OB_FAIL(ls->get_config_change_lock_stat(palf_lock_owner, palf_is_locked))) { + LOG_WARN("failed to get config change lock stat", K(ret)); + } else if (OB_FAIL(check_unlock_status_(palf_is_locked, palf_lock_owner, lock_info.lock_owner_, + need_unlock, need_relock_before_unlock))) { + LOG_WARN("failed to check unlock status", K(ret), K(palf_is_locked), K(palf_lock_owner), K(lock_info)); + } else if (FALSE_IT(lock_owner = lock_info.lock_owner_)) { + // assign lock owner + } else if (need_relock_before_unlock && OB_FAIL(relock_before_unlock_(lock_info, palf_lock_owner, lock_timeout, ls))) { + LOG_WARN("failed to relock config change", K(ret), K(lock_info), K(palf_lock_owner), KPC(ls)); + } else if (need_unlock && OB_FAIL(unlock_config_change(lock_info, lock_timeout, ls))) { + LOG_WARN("failed to get paxos member list", K(ret), K(lock_info)); + } else if (OB_FAIL(ObTransferLockInfoOperator::remove(tenant_id, ls_id, task_id, status, trans))) { + LOG_WARN("failed to update lock info", K(ret), K(row_key), K(lock_info), K(palf_lock_owner), K(palf_is_locked)); + } else { +#ifdef ERRSIM + if (OB_SUCC(ret)) { + if (ObTransferLockStatus::START == status.get_status()) { + ret = EN_START_UNLOCK_CONFIG_CHANGE_SUCC_AND_REMOVE_INNER_TABLE_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_START_UNLOCK_CONFIG_CHANGE_SUCC_AND_REMOVE_INNER_TABLE_FAILED", K(ret)); + } + } + if (ObTransferLockStatus::DOING == status.get_status()) { + ret = EN_DOING_UNLOCK_CONFIG_CHANGE_SUCC_AND_REMOVE_INNER_TABLE_FAILED ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_DOING_UNLOCK_CONFIG_CHANGE_SUCC_AND_REMOVE_INNER_TABLE_FAILED", K(ret)); + } + } + if (OB_FAIL(ret)) { + SERVER_EVENT_SYNC_ADD("TRANSFER", "UNLOCK_CONFIG_CHANGE_SUCC_AND_REMOVE_INNER_TABLE_FAILED", + "status", status, + "result", ret); + } + } +#endif + LOG_INFO("unlock ls member list", + K(palf_lock_owner), + K(lock_owner), + K(lock_info), + K(tenant_id), + K(ls_id), + K(member_list)); + } + + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("failed to end trans", K(tmp_ret), K(ret)); + } + } + } + return ret; +} + +int ObMemberListLockUtils::try_lock_config_change( + const ObTransferTaskLockInfo &lock_info, const int64_t lock_timeout, ObLS *ls) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be null", K(ret), KP(ls)); + } else if (!lock_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(lock_info)); + } else if (OB_FAIL(ls->try_lock_config_change(lock_info.lock_owner_, lock_timeout))) { + LOG_WARN("failed to try lock config config", K(ret), K(lock_info)); + } else { +#ifdef ERRSIM + SERVER_EVENT_ADD("TRANSFER_LOCK", "LOCK_CONFIG_CHANGE", + "tenant_id", lock_info.tenant_id_, + "ls_id", lock_info.ls_id_.id(), + "task_id", lock_info.task_id_, + "status", lock_info.status_.str(), + "lock_owner", lock_info.lock_owner_, + "lock_member_list", lock_info.comment_); +#endif + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(ObMemberListLockUtils::record_config_change_lock_stat(lock_info, ls))) { + LOG_WARN("failed to get config change lock stat", K(ret), K(lock_info)); + } + } + return ret; +} + +int ObMemberListLockUtils::record_config_change_lock_stat(const ObTransferTaskLockInfo &lock_info, ObLS *ls) +{ + int ret = OB_SUCCESS; + int64_t palf_lock_owner = -1; + bool is_locked = false; + if (OB_ISNULL(ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be null", K(ret), KP(ls)); + } else if (!lock_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(lock_info)); + } else if (OB_FAIL(ls->get_config_change_lock_stat(palf_lock_owner, is_locked))) { + LOG_WARN("failed to get config change lock stat", K(ret), K(lock_info)); + } else { +#ifdef ERRSIM + SERVER_EVENT_ADD("TRANSFER_LOCK", "GET_CONFIG_CHANGE_LOCK_STAT", + "tenant_id", lock_info.tenant_id_, + "ls_id", lock_info.ls_id_.id(), + "task_id", lock_info.task_id_, + "status", lock_info.status_.str(), + "palf_lock_owner", palf_lock_owner, + "is_locked", is_locked); +#endif + } + return ret; +} + +int ObMemberListLockUtils::unlock_config_change( + const ObTransferTaskLockInfo &lock_info, const int64_t lock_timeout, ObLS *ls) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be null", K(ret), KP(ls)); + } else if (!lock_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(lock_info)); + } else if (OB_FAIL(ls->unlock_config_change(lock_info.lock_owner_, lock_timeout))) { + LOG_WARN("failed to unlock config config", K(ret), K(lock_info)); + } else { +#ifdef ERRSIM + SERVER_EVENT_ADD("TRANSFER_LOCK", "UNLOCK_CONFIG_CHANGE", + "tenant_id", lock_info.tenant_id_, + "ls_id", lock_info.ls_id_.id(), + "task_id", lock_info.task_id_, + "status", lock_info.status_.str(), + "lock_owner", lock_info.lock_owner_, + "unlock_member_list", lock_info.comment_); +#endif + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(ObMemberListLockUtils::record_config_change_lock_stat(lock_info, ls))) { + LOG_WARN("failed to get config change lock stat", K(ret), K(lock_info)); + } + } + return ret; +} + +/* ObMemberListLockUtils */ + +int ObMemberListLockUtils::get_lock_owner(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const ObTransferLockStatus &status, common::ObMySQLProxy &proxy, int64_t &lock_owner) +{ + int ret = OB_SUCCESS; + share::ObCommonID common_id; + const ObMaxIdType id_type = ObMaxIdType::OB_MAX_USED_LOCK_OWNER_ID_TYPE; + const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id); + if (!is_valid_tenant_id(tenant_id) || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant id not valid", K(ret), K(tenant_id)); + } else if (OB_FAIL(ObCommonIDUtils::gen_monotonic_id(meta_tenant_id, id_type, proxy, common_id))) { + LOG_WARN("failed to gen monotonic id", K(ret), K(meta_tenant_id)); + } else { + lock_owner = common_id.id(); + LOG_INFO("get lock owner", K(tenant_id), K(lock_owner), K(common_id)); +#ifdef ERRSIM + SERVER_EVENT_ADD("TRANSFER_LOCK", "GET_LOCK_OWNER", + "tenant_id", tenant_id, + "ls_id", ls_id.id(), + "task_id", task_id, + "status", status.str(), + "lock_owner", lock_owner); +#endif + } + return ret; +} + +int ObMemberListLockUtils::get_member_list_str( + const common::ObMemberList &member_list, ObSqlString &member_list_str) +{ + int ret = OB_SUCCESS; + ObLSReplica::MemberList ls_member_list; + if (!member_list.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(member_list)); + } else if (OB_FAIL(share::ObLSReplica::transform_ob_member_list(member_list, ls_member_list))) { + LOG_WARN("failed to transform ob member list", K(ret), K(member_list)); + } else if (OB_FAIL(share::ObLSReplica::member_list2text(ls_member_list, member_list_str))) { + LOG_WARN("failed to member list to text", K(ret), K(ls_member_list)); + } + return ret; +} + +int ObMemberListLockUtils::insert_lock_info(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const ObTransferLockStatus &status, const int64_t lock_owner, const common::ObString &comment, + int64_t &real_lock_owner, common::ObISQLClient &sql_proxy) +{ + int ret = OB_SUCCESS; + real_lock_owner = -1; + ObTransferTaskLockInfo lock_info; + if (OB_FAIL(lock_info.set(tenant_id, ls_id, task_id, status, lock_owner, comment))) { + LOG_WARN("failed to set lock info", K(ret), K(tenant_id), K(ls_id), K(status), K(real_lock_owner)); + } else if (OB_FAIL(ObTransferLockInfoOperator::insert(lock_info, sql_proxy))) { + if (OB_ENTRY_EXIST == ret) { + ret = OB_SUCCESS; + ObTransferTaskLockInfo tmp_lock_info; + if (OB_FAIL(get_lock_info(tenant_id, ls_id, task_id, status, tmp_lock_info, sql_proxy))) { + LOG_WARN("failed to get lock info", K(ret), K(ls_id)); + } else { + real_lock_owner = tmp_lock_info.lock_owner_; + LOG_INFO("lock info already exist", K(ret), K(real_lock_owner), K(lock_owner)); + } + } else { + LOG_WARN("failed to insert lock info", K(ret), K(ls_id)); + } + } else { + real_lock_owner = lock_owner; + } + return ret; +} + +int ObMemberListLockUtils::get_lock_info(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const ObTransferLockStatus &status, ObTransferTaskLockInfo &lock_info, common::ObISQLClient &sql_proxy) +{ + int ret = OB_SUCCESS; + lock_info.reset(); + const bool for_update = false; + ObTransferLockInfoRowKey row_key; + row_key.tenant_id_ = tenant_id; + row_key.ls_id_ = ls_id; + if (!row_key.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(row_key)); + } else if (OB_FAIL(ObTransferLockInfoOperator::get(row_key, task_id, status, for_update, lock_info, sql_proxy))) { + LOG_WARN("failed to get lock info", K(ret), K(row_key), K(task_id), K(status)); + } + return ret; +} + +int ObMemberListLockUtils::check_lock_status_( + const bool palf_is_locked, const int64_t palf_lock_owner, const int64_t inner_table_lock_owner, bool &need_lock) +{ + int ret = OB_SUCCESS; + need_lock = false; + // Checking the status of a lock on a palf and an inner table, If the palf is not locked and the palf lock owner is + // greater than the inner table lock owner, we need to report an error, else we need to lock palf + if (!palf_is_locked) { + if (palf_lock_owner == inner_table_lock_owner) { + // This code block handles the scenario where the PALF unlock operation of the member list was successful, + // but the inner table removal failed. If the transfer thread attempts to retry the process, + // it may result in the palf lock owner being the same as the inner table lock owner. + // In this case, we only log an error for notification purposes. + need_lock = true; + LOG_ERROR("palf lock owner equal to inner table lock owner, please check condition"); + } else if (palf_lock_owner > inner_table_lock_owner) { + ret = OB_ERR_UNEXPECTED_LOCK_OWNER; + LOG_WARN("palf lock owner can not be greater than or equal to inner table lock owner", + K(ret), + K(palf_lock_owner), + K(inner_table_lock_owner)); + } else { + need_lock = true; + } + } else { + // If the palf is locked and the palf lock owner is not the same as the inner table lock owner, it need to report an + // error code. + if (palf_lock_owner != inner_table_lock_owner) { + ret = OB_ERR_UNEXPECTED_LOCK_OWNER; + LOG_WARN("palf lock owner and inner table not same", K(ret), K(palf_lock_owner), K(inner_table_lock_owner)); + } else { + need_lock = false; + } + } + return ret; +} + +int ObMemberListLockUtils::check_unlock_status_( + const bool palf_is_locked, const int64_t palf_lock_owner, const int64_t inner_table_lock_owner, + bool &need_unlock, bool &need_relock_before_unlock) +{ + int ret = OB_SUCCESS; + need_unlock = true; + need_relock_before_unlock = false; + if (!palf_is_locked) { + // If the unlock_config_change operation has been executed before, + // but the timeout is returned, the bottom layer may have been unlocked, and the row record in the internal table + // has not been deleted. Therefore, when the lock owner of the palf record is greater than the lock owner of the + // internal table, an error needs to be reported at this time. + if (palf_lock_owner > inner_table_lock_owner) { + ret = OB_ERR_UNEXPECTED_LOCK_OWNER; + LOG_WARN("palf is not locked, and lock owner not match", K(ret), K(palf_lock_owner), K(inner_table_lock_owner)); + } else if (palf_lock_owner == inner_table_lock_owner) { + need_relock_before_unlock = false; + need_unlock = false; + } else { + LOG_INFO("palf lock owner is smaller than inner table lock owner, need relock before unlock", K(palf_lock_owner), K(inner_table_lock_owner)); + need_relock_before_unlock = true; + need_unlock = true; + } + } else { + // If the PALF layer has not been unlocked, if the lock owner recorded in the palf layer is different from the + // lock owner recorded in the internal table, an error will be reported, otherwise it can be unlocked + if (palf_lock_owner != inner_table_lock_owner) { + ret = OB_ERR_UNEXPECTED_LOCK_OWNER; + LOG_WARN("palf lock owner not match", K(ret), K(palf_lock_owner), K(inner_table_lock_owner)); + } else { + need_unlock = true; + } + } + return ret; +} + +int ObMemberListLockUtils::relock_before_unlock_(const ObTransferTaskLockInfo &lock_info, + const int64_t palf_lock_owner, const int64_t lock_timeout, ObLS *ls) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(try_lock_config_change(lock_info, lock_timeout, ls))) { + LOG_WARN("failed to try lock config change", K(ret), K(lock_info)); + } else { + LOG_WARN("relock before unlock", K(ret), K(lock_info), KPC(ls)); + } +#ifdef ERRSIM + SERVER_EVENT_ADD("TRANSFER_LOCK", "RELOCK_BEFORE_UNLOCK", + "tenant_id", lock_info.tenant_id_, + "ls_id", lock_info.ls_id_, + "status", lock_info.status_, + "inner_table_lock_owner", lock_info.lock_owner_, + "palf_lock_owner", palf_lock_owner, + "result", ret); +#endif + return ret; +} + +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/high_availability/ob_transfer_lock_utils.h b/src/storage/high_availability/ob_transfer_lock_utils.h new file mode 100644 index 000000000..7b2f1dbb8 --- /dev/null +++ b/src/storage/high_availability/ob_transfer_lock_utils.h @@ -0,0 +1,72 @@ +/** + * 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_OB_TRANSFER_LOCK_UTILS +#define OCEANBASE_OB_TRANSFER_LOCK_UTILS + +#include "share/transfer/ob_transfer_info.h" +#include "share/ob_ls_id.h" +#include "common/ob_member_list.h" +#include "ob_transfer_lock_info_operator.h" +#include "storage/ls/ob_ls.h" + +namespace oceanbase { +namespace storage { + +class ObMemberListLockUtils { +public: + /* member list*/ + static int batch_lock_ls_member_list(const uint64_t tenant_id, const int64_t task_id, + const common::ObArray &lock_ls_list, const common::ObMemberList &member_list, + const ObTransferLockStatus &status, common::ObMySQLProxy &sql_proxy); + static int lock_ls_member_list(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const common::ObMemberList &member_list, const ObTransferLockStatus &status, ObLS *ls, + common::ObMySQLProxy &sql_proxy); + static int unlock_ls_member_list(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const common::ObMemberList &member_list, const ObTransferLockStatus &status, common::ObMySQLProxy &sql_proxy); + +private: + /* sql operator */ + static int insert_lock_info(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const ObTransferLockStatus &status, const int64_t lock_owner, const common::ObString &comment, + int64_t &real_lock_owner, common::ObISQLClient &sql_proxy); + static int get_lock_info(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const ObTransferLockStatus &status, ObTransferTaskLockInfo &lock_info, common::ObISQLClient &sql_proxy); + +private: + /* monotonic id*/ + static int get_lock_owner(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const ObTransferLockStatus &status, common::ObMySQLProxy &sql_proxy, int64_t &lock_owner); + static int get_member_list_str(const common::ObMemberList &member_list, ObSqlString &member_list_str); + +private: + /* palf lock config*/ + static int try_lock_config_change(const ObTransferTaskLockInfo &lock_info, const int64_t lock_timeout, ObLS *ls); + static int record_config_change_lock_stat(const ObTransferTaskLockInfo &lock_info, ObLS *ls); + static int unlock_config_change(const ObTransferTaskLockInfo &lock_info, const int64_t lock_timeout, ObLS *ls); + +private: + static int check_lock_status_( + const bool palf_is_locked, const int64_t palf_lock_owner, const int64_t inner_table_lock_owner, bool &need_lock); + static int check_unlock_status_(const bool palf_is_locked, const int64_t palf_lock_owner, + const int64_t inner_table_lock_owner, bool &need_unlock, bool &need_relock_before_unlock); + static int relock_before_unlock_(const ObTransferTaskLockInfo &lock_info, const int64_t palf_lock_owner, + const int64_t lock_timeout, ObLS *ls); + +private: + static const int64_t CONFIG_CHANGE_TIMEOUT = 10 * 1000 * 1000L; // 10s +}; + +} // namespace storage +} // namespace oceanbase + +#endif diff --git a/src/storage/high_availability/ob_transfer_service.cpp b/src/storage/high_availability/ob_transfer_service.cpp new file mode 100644 index 000000000..5eca5c1d5 --- /dev/null +++ b/src/storage/high_availability/ob_transfer_service.cpp @@ -0,0 +1,229 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX STORAGE +#include "ob_transfer_service.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "observer/ob_server_struct.h" + +namespace oceanbase +{ +namespace storage +{ + +ObTransferService::ObTransferService() + : is_inited_(false), + thread_cond_(), + wakeup_cnt_(0), + ls_service_(nullptr) +{ +} + +ObTransferService::~ObTransferService() +{ +} + +int ObTransferService::mtl_init(ObTransferService *&transfer_service) +{ + int ret = OB_SUCCESS; + ObLSService *ls_service = nullptr; + + if (OB_ISNULL(ls_service = (MTL(ObLSService *)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), KP(ls_service)); + } else if (OB_FAIL(transfer_service->init(ls_service))) { + LOG_WARN("failed to init transfer service", K(ret), KP(ls_service)); + } + return ret; +} + +int ObTransferService::init( + ObLSService *ls_service) +{ + int ret = OB_SUCCESS; + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("transfer service is aleady init", K(ret)); + } else if (OB_ISNULL(ls_service)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("init high avaiable handler mgr get invalid argument", K(ret), KP(ls_service)); + } else if (OB_FAIL(thread_cond_.init(ObWaitEventIds::HA_SERVICE_COND_WAIT))) { + LOG_WARN("failed to init ha service thread cond", K(ret)); + } else { + lib::ThreadPool::set_run_wrapper(MTL_CTX()); + ls_service_ = ls_service; + is_inited_ = true; + } + return ret; +} + +void ObTransferService::wakeup() +{ + ObThreadCondGuard cond_guard(thread_cond_); + wakeup_cnt_++; + thread_cond_.signal(); +} + +void ObTransferService::destroy() +{ + if (is_inited_) { + COMMON_LOG(INFO, "ObTransferService starts to destroy"); + thread_cond_.destroy(); + wakeup_cnt_ = 0; + is_inited_ = false; + COMMON_LOG(INFO, "ObTransferService destroyed"); + } +} + +void ObTransferService::stop() +{ + if (is_inited_) { + COMMON_LOG(INFO, "ObTransferService starts to stop"); + ThreadPool::stop(); + wakeup(); + COMMON_LOG(INFO, "ObTransferService stopped"); + } +} + +void ObTransferService::wait() +{ + if (is_inited_) { + COMMON_LOG(INFO, "ObTransferService starts to wait"); + ThreadPool::wait(); + COMMON_LOG(INFO, "ObTransferService finish to wait"); + } +} + +int ObTransferService::start() +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer service do not init", K(ret)); + } else { + if (OB_FAIL(lib::ThreadPool::start())) { + COMMON_LOG(WARN, "ObTransferService start thread failed", K(ret)); + } else { + COMMON_LOG(INFO, "ObTransferService start"); + } + } + return ret; +} + +void ObTransferService::run1() +{ + int ret = OB_SUCCESS; + lib::set_thread_name("TransferService"); + + while (!has_set_stop()) { + ls_id_array_.reset(); + if (observer::ObServiceStatus::SS_SERVING != GCTX.status_) { + ret = OB_SERVER_IS_INIT; + LOG_WARN("server is not serving", K(ret), K(GCTX.status_)); + } else if (OB_FAIL(get_ls_id_array_())) { + LOG_WARN("failed to get ls id array", K(ret)); + } else if (OB_FAIL(scheduler_transfer_handler_())) { + LOG_WARN("failed to do scheduler transfer handler", K(ret)); + } + + ObThreadCondGuard guard(thread_cond_); + if (has_set_stop() || wakeup_cnt_ > 0) { + wakeup_cnt_ = 0; + } else { + int64_t wait_time_ms = GCONF._transfer_service_wakeup_interval / 1000; + thread_cond_.wait(wait_time_ms); + } + } +} + +int ObTransferService::get_ls_id_array_() +{ + int ret = OB_SUCCESS; + ls_id_array_.reset(); + common::ObSharedGuard ls_iter_guard; + ObLSIterator *ls_iter = nullptr; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer service do not init", K(ret)); + } else if (OB_FAIL(ls_service_->get_ls_iter(ls_iter_guard, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls iter", K(ret)); + } else if (OB_ISNULL(ls_iter = ls_iter_guard.get_ptr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls iter should not be NULL", K(ret)); + } else { + while (OB_SUCC(ret)) { + ObLS *ls = nullptr; + if (OB_FAIL(ls_iter->get_next(ls))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } + } else if (OB_ISNULL(ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); + } else if (OB_FAIL(ls_id_array_.push_back(ls->get_ls_id()))) { + LOG_WARN("failed to push ls id into array", K(ret), KPC(ls)); + } + } + } + return ret; +} + +int ObTransferService::scheduler_transfer_handler_() +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer service do not init", K(ret)); + } else { + LOG_INFO("start do transfer handler", K(ls_id_array_)); + + for (int64_t i = 0; OB_SUCC(ret) && i < ls_id_array_.count(); ++i) { + const share::ObLSID &ls_id = ls_id_array_.at(i); + if (OB_SUCCESS != (tmp_ret = do_transfer_handler_(ls_id))) { + //The purpose of using tmp_ret here is to not block the scheduling of other ls afterward + LOG_WARN("failed to do ha handler", K(tmp_ret), K(ls_id)); + } + } + } + return ret; +} + +int ObTransferService::do_transfer_handler_(const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("transfer service do not init", K(ret)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("do ha handler get invalid argument", K(ret), K(ls_id)); + } else if (OB_FAIL(ls_service_->get_ls(ls_id, ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else if (OB_FAIL(ls->get_transfer_handler()->process())) { + LOG_WARN("failed to process transfer", K(ret), KP(ls)); + } else { + LOG_INFO("[TRANSFER] transfer handler process", K(ret), K(ls_id)); + } + return ret; +} + + +} +} diff --git a/src/storage/high_availability/ob_transfer_service.h b/src/storage/high_availability/ob_transfer_service.h new file mode 100644 index 000000000..2c5b0bb34 --- /dev/null +++ b/src/storage/high_availability/ob_transfer_service.h @@ -0,0 +1,63 @@ +/** + * 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 OCEABASE_STORAGE_TRANSFER_SERVICE_ +#define OCEABASE_STORAGE_TRANSFER_SERVICE_ + +#include "lib/thread/thread_pool.h" +#include "lib/thread/ob_reentrant_thread.h" +#include "lib/thread/ob_thread_name.h" +#include "lib/lock/ob_thread_cond.h" +#include "lib/container/ob_se_array.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "share/scn.h" + +namespace oceanbase +{ +namespace storage +{ +class ObTransferService : public lib::ThreadPool +{ +public: + ObTransferService(); + virtual ~ObTransferService(); + static int mtl_init(ObTransferService *&transfer_service); + + int init(ObLSService *ls_service); + void destroy(); + void run1() final; + void wakeup(); + void stop(); + void wait(); + int start(); + +private: + int get_ls_id_array_(); + int scheduler_transfer_handler_(); + int do_transfer_handler_(const share::ObLSID &ls_id); + +private: + static const int64_t SCHEDULER_WAIT_TIME_MS = 5 * 60 * 1000L; // 5min + bool is_inited_; + common::ObThreadCond thread_cond_; + int64_t wakeup_cnt_; + ObLSService *ls_service_; + ObArray ls_id_array_; + + DISALLOW_COPY_AND_ASSIGN(ObTransferService); +}; + + + +} +} +#endif diff --git a/src/storage/high_availability/ob_transfer_struct.cpp b/src/storage/high_availability/ob_transfer_struct.cpp new file mode 100644 index 000000000..3a4be1963 --- /dev/null +++ b/src/storage/high_availability/ob_transfer_struct.cpp @@ -0,0 +1,557 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX STORAGE +#include "ob_transfer_struct.h" +#include "observer/ob_server_event_history_table_operator.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "src/storage/tablet/ob_tablet_meta.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "storage/ls/ob_ls.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/high_availability/ob_storage_ha_utils.h" +#include "storage/tx/ob_ts_mgr.h" + +using namespace oceanbase; +using namespace share; +using namespace storage; + + +ObTXStartTransferOutInfo::ObTXStartTransferOutInfo() + : src_ls_id_(), + dest_ls_id_(), + tablet_list_() +{ +} + +void ObTXStartTransferOutInfo::reset() +{ + src_ls_id_.reset(); + dest_ls_id_.reset(); + tablet_list_.reset(); +} + +bool ObTXStartTransferOutInfo::is_valid() const +{ + return src_ls_id_.is_valid() + && dest_ls_id_.is_valid() + && !tablet_list_.empty(); +} + +int ObTXStartTransferOutInfo::assign(const ObTXStartTransferOutInfo &start_transfer_out_info) +{ + int ret = OB_SUCCESS; + if (!start_transfer_out_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("assign start transfer out info get invalid argument", K(ret), K(start_transfer_out_info)); + } else if (OB_FAIL(tablet_list_.assign(start_transfer_out_info.tablet_list_))) { + LOG_WARN("failed to assign start transfer out info", K(ret), K(start_transfer_out_info)); + } else { + src_ls_id_ = start_transfer_out_info.src_ls_id_; + dest_ls_id_ = start_transfer_out_info.dest_ls_id_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObTXStartTransferOutInfo, src_ls_id_, dest_ls_id_, tablet_list_); + + +ObTXStartTransferInInfo::ObTXStartTransferInInfo() + : src_ls_id_(), + dest_ls_id_(), + start_scn_(), + tablet_meta_list_() +{ +} + +void ObTXStartTransferInInfo::reset() +{ + src_ls_id_.reset(); + dest_ls_id_.reset(); + start_scn_.reset(); + tablet_meta_list_.reset(); +} + +bool ObTXStartTransferInInfo::is_valid() const +{ + return src_ls_id_.is_valid() + && dest_ls_id_.is_valid() + && start_scn_.is_valid() + && !tablet_meta_list_.empty(); +} + +int ObTXStartTransferInInfo::assign(const ObTXStartTransferInInfo &start_transfer_in_info) +{ + int ret = OB_SUCCESS; + if (!start_transfer_in_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("assign start transfer in info get invalid argument", K(ret), K(start_transfer_in_info)); + } else if (OB_FAIL(tablet_meta_list_.assign(start_transfer_in_info.tablet_meta_list_))) { + LOG_WARN("failed to assign start transfer out info", K(ret), K(start_transfer_in_info)); + } else { + src_ls_id_ = start_transfer_in_info.src_ls_id_; + dest_ls_id_ = start_transfer_in_info.dest_ls_id_; + start_scn_ = start_transfer_in_info.start_scn_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObTXStartTransferInInfo, src_ls_id_, dest_ls_id_, start_scn_, tablet_meta_list_); + +/* ObTXFinishTransferInInfo */ + +OB_SERIALIZE_MEMBER(ObTXFinishTransferInInfo, src_ls_id_, dest_ls_id_, start_scn_, tablet_list_); +ObTXFinishTransferInInfo::ObTXFinishTransferInInfo() + : src_ls_id_(), + dest_ls_id_(), + start_scn_(), + tablet_list_() +{ +} + +void ObTXFinishTransferInInfo::reset() +{ + src_ls_id_.reset(); + dest_ls_id_.reset(); + start_scn_.reset(); + tablet_list_.reset(); +} + +bool ObTXFinishTransferInInfo::is_valid() const +{ + return src_ls_id_.is_valid() + && dest_ls_id_.is_valid() + && start_scn_.is_valid() + && !tablet_list_.empty(); +} + +int ObTXFinishTransferInInfo::assign(const ObTXFinishTransferInInfo &finish_transfer_in_info) +{ + int ret = OB_SUCCESS; + if (!finish_transfer_in_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("assign finish transfer in info get invalid argument", K(ret), K(finish_transfer_in_info)); + } else if (OB_FAIL(tablet_list_.assign(finish_transfer_in_info.tablet_list_))) { + LOG_WARN("failed to assign finish transfer in info", K(ret), K(finish_transfer_in_info)); + } else { + src_ls_id_ = finish_transfer_in_info.src_ls_id_; + dest_ls_id_ = finish_transfer_in_info.dest_ls_id_; + start_scn_ = finish_transfer_in_info.start_scn_; + } + return ret; +} + +/* ObTXFinishTransferOutInfo */ +OB_SERIALIZE_MEMBER(ObTXFinishTransferOutInfo, src_ls_id_, dest_ls_id_, finish_scn_, tablet_list_); +ObTXFinishTransferOutInfo::ObTXFinishTransferOutInfo() + : src_ls_id_(), + dest_ls_id_(), + finish_scn_(), + tablet_list_() +{ +} +void ObTXFinishTransferOutInfo::reset() +{ + src_ls_id_.reset(); + dest_ls_id_.reset(); + finish_scn_.reset(); + tablet_list_.reset(); +} +bool ObTXFinishTransferOutInfo::is_valid() const +{ + return src_ls_id_.is_valid() + && dest_ls_id_.is_valid() + && finish_scn_.is_valid() + && !tablet_list_.empty(); +} + +int ObTXFinishTransferOutInfo::assign(const ObTXFinishTransferOutInfo &finish_transfer_out_info) +{ + int ret = OB_SUCCESS; + if (!finish_transfer_out_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("assign finish transfer out info get invalid argument", K(ret), K(finish_transfer_out_info)); + } else if (OB_FAIL(tablet_list_.assign(finish_transfer_out_info.tablet_list_))) { + LOG_WARN("failed to assign finish transfer out info", K(ret), K(finish_transfer_out_info)); + } else { + src_ls_id_ = finish_transfer_out_info.src_ls_id_; + dest_ls_id_ = finish_transfer_out_info.dest_ls_id_; + finish_scn_ = finish_transfer_out_info.finish_scn_; + } + return ret; +} + +void ObTransferEventRecorder::record_transfer_task_event( + const share::ObTransferTaskID &task_id, + const char *event_name, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id) +{ + SERVER_EVENT_ADD("TRANSFER", "REGISTER_MULTI_DATA_SOURCE", + "event", event_name, + "task_id", task_id, + "src_ls_id", src_ls_id.id(), + "dest_ls_id", dest_ls_id.id()); +} + +void ObTransferEventRecorder::record_ls_transfer_event( + const char *event_name, + const transaction::NotifyType &type, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const bool for_replay, + const share::SCN &scn, + const int64_t result) +{ + const char *type_str = NULL; + if (transaction::NotifyType::REGISTER_SUCC == type) { + type_str = "REGISTER_SUCC"; + } else if (transaction::NotifyType::ON_REDO == type) { + type_str = "ON_REDO"; + } else if (transaction::NotifyType::ON_COMMIT == type) { + type_str = "ON_COMMIT"; + } else if (transaction::NotifyType::ON_ABORT == type) { + type_str = "ON_ABORT"; + } else if (transaction::NotifyType::TX_END == type) { + type_str = "TX_END"; + } else if (transaction::NotifyType::ON_PREPARE == type) { + type_str = "ON_PREPARE"; + } else { + type_str = "UNKNOWN"; + } + SERVER_EVENT_ADD("TRANSFER", event_name, + "TYPE", type_str, + "src_ls_id", src_ls_id.id(), + "dest_ls_id", dest_ls_id.id(), + "for_replay", for_replay, + "scn", scn.get_val_for_inner_table_field(), + "result", result); +} + +void ObTransferEventRecorder::record_tablet_transfer_event( + const char *event_name, + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id, + const int64_t transfer_seq, + const ObTabletStatus &tablet_status, + const int64_t result) +{ + SERVER_EVENT_ADD("TRANSFER", "TABLET_STATUS_CHANGE", + "event_name", event_name, + "tablet_status", ObTabletStatus::get_str(tablet_status), + "ls_id", ls_id.id(), + "tablet_id", tablet_id.id(), + "transfer_seq", transfer_seq, + "result", result); +} + +void ObTransferEventRecorder::record_advance_transfer_status_event( + const uint64_t tenant_id, + const share::ObTransferTaskID &task_id, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const share::ObTransferStatus &next_status, + const int64_t result) +{ + SERVER_EVENT_ADD("TRANSFER", "UPDATE_TRANSFER_STATUS", + "tenant_id", tenant_id, + "task_id", task_id.id(), + "src_ls_id", src_ls_id.id(), + "dest_ls_id", dest_ls_id.id(), + "next_status", next_status.str(), + "result", result); +} + +int ObTXTransferUtils::get_tablet_status( + const bool get_commit, + ObTabletHandle &tablet_handle, + ObTabletCreateDeleteMdsUserData &user_data) +{ + int ret = OB_SUCCESS; + user_data.reset(); + ObTablet *tablet = nullptr; + + if (!tablet_handle.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get tablet status get invalid argument", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_handle)); + } else if (OB_FAIL(get_tablet_status_(get_commit, tablet, user_data))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(tablet)); + } + return ret; +} + +int ObTXTransferUtils::get_tablet_status( + const bool get_commit, + const ObTablet *tablet, + ObTabletCreateDeleteMdsUserData &user_data) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get tablet status get invalid argument", K(ret), KP(tablet)); + } else if (OB_FAIL(get_tablet_status_(get_commit, tablet, user_data))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(tablet)); + } + return ret; +} + +int ObTXTransferUtils::get_tablet_status_( + const bool get_commit, + const ObTablet *tablet, + ObTabletCreateDeleteMdsUserData &user_data) +{ + int ret = OB_SUCCESS; + bool unused_committed_flag = false; + if (get_commit) { + if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet), K(user_data)); + } + } else { + if (OB_FAIL(tablet->ObITabletMdsInterface::get_latest_tablet_status(user_data, unused_committed_flag))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet), K(user_data)); + } + } + return ret; +} + +// TODO(wenjinyu.wjy) It needs to be added to trigger the tablet freezing operation +int ObTXTransferUtils::set_tablet_freeze_flag(const share::ObLSID &ls_id, ObTablet *tablet) +{ + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObIMemtableMgr *memtable_mgr = nullptr; + ObArray memtables; + ObTabletID tablet_id = tablet->get_tablet_meta().tablet_id_; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + SCN weak_read_scn; + + if (OB_ISNULL(tablet) ) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), KP(tablet)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); + } else if (FALSE_IT(weak_read_scn = ls->get_ls_wrs_handler()->get_ls_weak_read_ts())) { + } else if (!weak_read_scn.is_valid() + || ObScnRange::MAX_SCN == weak_read_scn) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("weak read scn is invalid", K(ret), K(ls_id), K(weak_read_scn)); + } else if (ObScnRange::MIN_SCN == weak_read_scn) { + ret = OB_EAGAIN; + LOG_WARN("weak read service not inited, need to wait for weak read scn to advance", K(ret), K(ls_id), K(weak_read_scn)); + } else if (OB_ISNULL(memtable_mgr = tablet->get_memtable_mgr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable mgr should not be NULL", K(ret), KP(memtable_mgr)); + } else if (CLICK_FAIL(memtable_mgr->get_all_memtables(memtables))) { + LOG_WARN("failed to get all memtables", K(ret), K(tablet_id)); + } else { + CLICK(); + for (int64_t i = 0; OB_SUCC(ret) && i < memtables.count(); ++i) { + ObITable *table = memtables.at(i).get_table(); + if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table in tables_handle is invalid", K(ret), KP(table)); + } else { + memtable::ObMemtable *memtable = static_cast(table); + if (memtable->is_active_memtable()) { + memtable->set_transfer_freeze(weak_read_scn); + } + } + } + if (OB_SUCC(ret)) { + LOG_INFO("succ set transfer freeze", K(tablet_id), K(ls_id)); + } + } + + return ret; +} + +int ObTXTransferUtils::create_empty_minor_sstable( + const common::ObTabletID &tablet_id, + const SCN start_scn, + const SCN end_scn, + const ObStorageSchema &table_schema, + common::ObArenaAllocator &allocator, + ObTableHandleV2 &table_handle) +{ + int ret = OB_SUCCESS; + ObTabletCreateSSTableParam create_sstable_param; + + if (!tablet_id.is_valid() || !table_schema.is_valid() || !start_scn.is_valid() || !end_scn.is_valid() || start_scn == end_scn) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("create empty minor sstable get invalid argument", K(ret), K(table_schema), K(tablet_id), K(start_scn), K(end_scn)); + } else if (OB_FAIL(build_empty_minor_sstable_param_(start_scn, end_scn, table_schema, + tablet_id, create_sstable_param))) { + LOG_WARN("failed to build empty minor sstable param", K(ret), K(tablet_id), K(start_scn), K(end_scn)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable_for_migrate(create_sstable_param, allocator, table_handle))) { + LOG_WARN("failed to create minor sstable", K(ret), K(create_sstable_param), K(tablet_id)); + } else { + LOG_INFO("succeed to create empty minor sstable", K(tablet_id), K(table_handle), K(start_scn), K(end_scn)); + } + return ret; +} + +int ObTXTransferUtils::build_empty_minor_sstable_param_( + const SCN start_scn, + const SCN end_scn, + const ObStorageSchema &table_schema, + const common::ObTabletID &tablet_id, + ObTabletCreateSSTableParam ¶m) +{ + int ret = OB_SUCCESS; + + if (!start_scn.is_valid() || !end_scn.is_valid() || start_scn == end_scn + || !table_schema.is_valid() || !tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("build empty minor sstable param get invalid argument", K(ret), K(table_schema), K(tablet_id), K(start_scn), K(end_scn)); + }else if (OB_FAIL(table_schema.get_encryption_id(param.encrypt_id_))) { + LOG_WARN("fail to get encryption id", K(ret), K(table_schema)); + } else { + param.master_key_id_ = table_schema.get_master_key_id(); + MEMCPY(param.encrypt_key_, table_schema.get_encrypt_key_str(), table_schema.get_encrypt_key_len()); + const int64_t multi_version_col_cnt = ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + param.table_key_.table_type_ = ObITable::TableType::MINOR_SSTABLE; + param.table_key_.tablet_id_ = tablet_id; + param.table_key_.scn_range_.start_scn_ = start_scn; + param.table_key_.scn_range_.end_scn_ = end_scn; + param.max_merged_trans_version_ = INT64_MAX; //Set max merged trans version avoild sstable recycle; + + param.schema_version_ = table_schema.get_schema_version(); + param.create_snapshot_version_ = 0; + param.progressive_merge_round_ = table_schema.get_progressive_merge_round(); + param.progressive_merge_step_ = 0; + + param.table_mode_ = table_schema.get_table_mode_struct(); + param.index_type_ = table_schema.get_index_type(); + param.rowkey_column_cnt_ = table_schema.get_rowkey_column_num() + + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + param.root_block_addr_.set_none_addr(); + param.data_block_macro_meta_addr_.set_none_addr(); + param.root_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + param.latest_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + param.data_index_tree_height_ = 0; + param.index_blocks_cnt_ = 0; + param.data_blocks_cnt_ = 0; + param.micro_block_cnt_ = 0; + param.use_old_macro_block_count_ = 0; + param.column_cnt_ = table_schema.get_column_count() + multi_version_col_cnt; + param.data_checksum_ = 0; + param.occupy_size_ = 0; + param.ddl_scn_.set_min(); + param.filled_tx_scn_.set_min(); + param.original_size_ = 0; + param.compressor_type_ = ObCompressorType::NONE_COMPRESSOR; + + if (!param.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid param", K(ret), K(param)); + } + } + return ret; +} + +/* ObTransferLockStatus */ + + +const char *ObTransferLockStatus::str() const +{ + const char *str = "INVALID_STATUS"; + switch (status_) { + case START: { + str = "START"; + break; + } + case DOING: { + str = "DOING"; + break; + } + default: { + str = "INVALID_STATUS"; + } + } + return str; +} + +int ObTransferLockStatus::parse_from_str(const ObString &str) +{ + int ret = OB_SUCCESS; + if (0 == str.case_compare("START")) { + status_ = START; + } else if (0 == str.case_compare("DOING")) { + status_ = DOING; + } else { + status_ = MAX_STATUS; + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid transfer status str", KR(ret), K(str)); + } + return ret; +} + +/* ObTransferLockInfoRowKey */ + +ObTransferLockInfoRowKey::ObTransferLockInfoRowKey() : tenant_id_(), ls_id_() +{} + +bool ObTransferLockInfoRowKey::is_valid() const +{ + return ls_id_.is_valid(); +} + +/* ObTransferTaskLockInfo */ + +ObTransferTaskLockInfo::ObTransferTaskLockInfo() + : tenant_id_(), ls_id_(), task_id_(), status_(), lock_owner_(), comment_() +{} + +void ObTransferTaskLockInfo::reset() +{ + tenant_id_ = OB_INVALID_ID; + ls_id_.reset(); + task_id_ = 0; + status_.reset(); + lock_owner_ = 0; + comment_.reset(); +} + +bool ObTransferTaskLockInfo::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ && ls_id_.is_valid() && task_id_ >= 0 && status_.is_valid() + && lock_owner_ > 0; +} +int ObTransferTaskLockInfo::set(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, + const ObTransferLockStatus &status, const int64_t lock_owner, const common::ObString &comment) +{ + int ret = OB_SUCCESS; + if (OB_INVALID_ID == tenant_id || task_id < 0 || !ls_id.is_valid() || !status.is_valid() || lock_owner <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(tenant_id), K(ls_id), K(task_id), K(status), K(lock_owner)); + } else if (OB_FAIL(comment_.assign(comment))) { + LOG_WARN("failed to assign comment", K(ret), K(comment)); + } else { + tenant_id_ = tenant_id; + ls_id_ = ls_id; + task_id_ = task_id; + status_ = status; + lock_owner_ = lock_owner; + } + return ret; +} diff --git a/src/storage/high_availability/ob_transfer_struct.h b/src/storage/high_availability/ob_transfer_struct.h new file mode 100644 index 000000000..a055aa454 --- /dev/null +++ b/src/storage/high_availability/ob_transfer_struct.h @@ -0,0 +1,222 @@ +/** + * 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 OCEABASE_STORAGE_TRANSFER_STRUCT_ +#define OCEABASE_STORAGE_TRANSFER_STRUCT_ + +#include "share/ob_define.h" +#include "lib/utility/ob_unify_serialize.h" +#include "share/transfer/ob_transfer_info.h" +#include "share/ob_balance_define.h" +#include "share/scn.h" +#include "storage/memtable/ob_memtable.h" +#include "storage/tablet/ob_tablet_meta.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" + +namespace oceanbase +{ +namespace storage +{ + +struct ObTXStartTransferOutInfo final +{ + OB_UNIS_VERSION(1); +public: + ObTXStartTransferOutInfo(); + ~ObTXStartTransferOutInfo() = default; + void reset(); + bool is_valid() const; + int assign(const ObTXStartTransferOutInfo &start_transfer_out_info); + + TO_STRING_KV(K_(src_ls_id), K_(dest_ls_id), K_(tablet_list)); + + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + common::ObSArray tablet_list_; + DISALLOW_COPY_AND_ASSIGN(ObTXStartTransferOutInfo); +}; + +struct ObTXStartTransferInInfo final +{ + OB_UNIS_VERSION(1); +public: + ObTXStartTransferInInfo(); + ~ObTXStartTransferInInfo() = default; + void reset(); + bool is_valid() const; + int assign(const ObTXStartTransferInInfo &start_transfer_in_info); + + TO_STRING_KV(K_(src_ls_id), K_(dest_ls_id), K_(start_scn), K_(tablet_meta_list)); + + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + share::SCN start_scn_; + common::ObSArray tablet_meta_list_; + DISALLOW_COPY_AND_ASSIGN(ObTXStartTransferInInfo); +}; + +struct ObTXFinishTransferOutInfo final +{ + OB_UNIS_VERSION(1); +public: + ObTXFinishTransferOutInfo(); + ~ObTXFinishTransferOutInfo() = default; + void reset(); + bool is_valid() const; + int assign(const ObTXFinishTransferOutInfo &finish_transfer_out_info); + + TO_STRING_KV(K_(src_ls_id), K_(dest_ls_id), K_(finish_scn), K_(tablet_list)); + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + share::SCN finish_scn_; + common::ObSArray tablet_list_; + DISALLOW_COPY_AND_ASSIGN(ObTXFinishTransferOutInfo); +}; + +struct ObTXFinishTransferInInfo final +{ + OB_UNIS_VERSION(1); +public: + ObTXFinishTransferInInfo(); + ~ObTXFinishTransferInInfo() = default; + void reset(); + bool is_valid() const; + int assign(const ObTXFinishTransferInInfo &finish_transfer_in_info); + + TO_STRING_KV(K_(src_ls_id), K_(dest_ls_id), K_(start_scn), K_(tablet_list)); + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + share::SCN start_scn_; + common::ObSArray tablet_list_; + DISALLOW_COPY_AND_ASSIGN(ObTXFinishTransferInInfo); +}; + +struct ObTransferEventRecorder final +{ + static void record_transfer_task_event( + const share::ObTransferTaskID &task_id, + const char *event_name, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id); + static void record_ls_transfer_event( + const char *event_name, + const transaction::NotifyType &type, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const bool for_replay, + const share::SCN &scn, + const int64_t result); + static void record_tablet_transfer_event( + const char *event_name, + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id, + const int64_t transfer_seq, + const ObTabletStatus &tablet_status, + const int64_t result); + static void record_advance_transfer_status_event( + const uint64_t tenant_id, + const share::ObTransferTaskID &task_id, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const share::ObTransferStatus &next_status, + const int64_t result); +}; + +struct ObTXTransferUtils +{ + static int get_tablet_status( + const bool get_commit, + ObTabletHandle &tablet_handle, + ObTabletCreateDeleteMdsUserData &user_data); + static int get_tablet_status( + const bool get_commit, + const ObTablet *tablet, + ObTabletCreateDeleteMdsUserData &user_data); + static int create_empty_minor_sstable( + const common::ObTabletID &tablet_id, + const share::SCN start_scn, + const share::SCN end_scn, + const ObStorageSchema &table_schema, + common::ObArenaAllocator &allocator, + ObTableHandleV2 &table_handle); + static int set_tablet_freeze_flag(const share::ObLSID &ls_id, ObTablet *tablet); + +private: + static int get_tablet_status_( + const bool get_commit, + const ObTablet *tablet, + ObTabletCreateDeleteMdsUserData &user_data); + static int build_empty_minor_sstable_param_( + const share::SCN start_scn, + const share::SCN end_scn, + const ObStorageSchema &table_schema, + const common::ObTabletID &tablet_id, + ObTabletCreateSSTableParam ¶m); +}; + +struct ObTransferLockStatus final +{ +public: + enum STATUS : uint8_t + { + START = 0, + DOING = 1, + MAX_STATUS + }; +public: + ObTransferLockStatus() : status_(MAX_STATUS) {} + ~ObTransferLockStatus() = default; + explicit ObTransferLockStatus(const STATUS &status) : status_(status) {} + + bool is_valid() const { return START <= status_ && status_ < MAX_STATUS; } + void reset() { status_ = MAX_STATUS; } + const char *str() const; + int parse_from_str(const ObString &str); + STATUS get_status() const { return status_; } + + TO_STRING_KV(K_(status), "status", str()); +private: + STATUS status_; +}; + +struct ObTransferLockInfoRowKey final { +public: + ObTransferLockInfoRowKey(); + ~ObTransferLockInfoRowKey() = default; + bool is_valid() const; + TO_STRING_KV(K_(tenant_id), K_(ls_id)); + uint64_t tenant_id_; + share::ObLSID ls_id_; +}; + +struct ObTransferTaskLockInfo final { +public: + ObTransferTaskLockInfo(); + ~ObTransferTaskLockInfo() = default; + void reset(); + bool is_valid() const; + int set(const uint64_t tenant_id, const share::ObLSID &ls_id, const int64_t task_id, const ObTransferLockStatus &status, + const int64_t lock_owner, const common::ObString &comment); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(task_id), K_(status), K_(lock_owner), K_(comment)); + +public: + uint64_t tenant_id_; + share::ObLSID ls_id_; + int64_t task_id_; + ObTransferLockStatus status_; + int64_t lock_owner_; + ObSqlString comment_; +}; + +} +} +#endif diff --git a/src/storage/lob/ob_lob_persistent_adaptor.cpp b/src/storage/lob/ob_lob_persistent_adaptor.cpp index fc3af9e8e..8b7eb0012 100644 --- a/src/storage/lob/ob_lob_persistent_adaptor.cpp +++ b/src/storage/lob/ob_lob_persistent_adaptor.cpp @@ -78,12 +78,11 @@ int ObPersistentLobApator::scan_lob_meta( uint64_t tenant_id = MTL_ID(); // 2. prepare tablet scan param scan_param.tablet_id_ = lob_meta_tablet.get_obj()->get_tablet_meta().tablet_id_; + scan_param.schema_version_ = lob_meta_tablet.get_obj()->get_tablet_meta().max_sync_storage_schema_version_; const uint64_t table_id = 0; scan_param.table_param_ = param.meta_tablet_param_; if (OB_FAIL(build_common_scan_param(param, table_id, ObLobMetaUtil::LOB_META_COLUMN_CNT, scan_param))) { LOG_WARN("build common scan param failed.", K(ret)); - } else if (OB_FAIL(lob_meta_tablet.get_obj()->get_schema_version_from_storage_schema(scan_param.schema_version_))) { - LOG_WARN("get lob meta storage schema version failed.", K(ret)); } else if (OB_FAIL(prepare_table_param(param, scan_param, true))) { LOG_WARN("prepare lob meta table param failed.", K(ret)); } else { @@ -153,13 +152,12 @@ int ObPersistentLobApator::get_lob_data( ObTableScanParam scan_param; scan_param.table_param_ = param.piece_tablet_param_; scan_param.tablet_id_ = lob_piece_tablet.get_obj()->get_tablet_meta().tablet_id_; + scan_param.schema_version_ = lob_piece_tablet.get_obj()->get_tablet_meta().max_sync_storage_schema_version_; const uint64_t table_id = 0; bool tmp_scan_backward = param.scan_backward_; param.scan_backward_ = false; if (OB_FAIL(build_common_scan_param(param, table_id, ObLobPieceUtil::LOB_PIECE_COLUMN_CNT, scan_param))) { LOG_WARN("build common scan param failed.", K(ret)); - } else if (OB_FAIL(lob_piece_tablet.get_obj()->get_schema_version_from_storage_schema(scan_param.schema_version_))) { - LOG_WARN("get lob meta storage schema version failed.", K(ret)); } else if (OB_FAIL(prepare_table_param(param, scan_param, false))) { LOG_WARN("prepare lob meta table param failed.", K(ret)); } else { @@ -313,6 +311,7 @@ int ObPersistentLobApator::build_lob_meta_table_dml( dml_base_param.sql_mode_ = SMO_DEFAULT; dml_base_param.encrypt_meta_ = &dml_base_param.encrypt_meta_legacy_; dml_base_param.snapshot_ = param.snapshot_; + dml_base_param.check_schema_version_ = false; // lob tablet should not check schema version if (param.seq_no_st_ != -1) { if (param.used_seq_cnt_ < param.total_seq_cnt_) { dml_base_param.spec_seq_no_ = param.seq_no_st_ + param.used_seq_cnt_; @@ -342,7 +341,7 @@ int ObPersistentLobApator::build_lob_meta_table_dml( if (OB_FAIL(get_lob_tablet_schema(tenant_id, true, *table_schema, dml_base_param.tenant_schema_version_))) { LOG_WARN("failed get lob tablet schema.", K(ret)); } else { - dml_base_param.schema_version_ = lob_meta_tablet.get_obj()->get_storage_schema().get_schema_version(); + dml_base_param.schema_version_ = lob_meta_tablet.get_obj()->get_tablet_meta().max_sync_storage_schema_version_; } } else { /** @@ -626,7 +625,7 @@ int ObPersistentLobApator::build_lob_piece_table_dml( if (OB_FAIL(get_lob_tablet_schema(tenant_id, false, *table_schema, dml_base_param.tenant_schema_version_))) { LOG_WARN("failed get lob tablet schema.", K(ret)); } else { - dml_base_param.schema_version_ = lob_piece_tablet.get_obj()->get_storage_schema().get_schema_version(); + dml_base_param.schema_version_ = lob_piece_tablet.get_obj()->get_tablet_meta().max_sync_storage_schema_version_; } } else { /** @@ -852,8 +851,6 @@ int ObPersistentLobApator::build_common_scan_param( // sessions scan_param.snapshot_ = param.snapshot_; scan_param.sql_mode_ = param.sql_mode_; - // shcema version - scan_param.schema_version_ = -1; // common set scan_param.allocator_ = param.allocator_; scan_param.for_update_ = false; @@ -896,10 +893,10 @@ int ObPersistentLobApator::get_lob_tablets( ObTabletHandle &lob_piece_tablet) { int ret = OB_SUCCESS; - ObTabletBindingInfo ddl_data; + ObTabletBindingMdsUserData ddl_data; if (OB_FAIL(inner_get_tablet(ls_id, data_tablet_id, data_tablet))) { LOG_WARN("failed to get data tablet", K(ret), K(ls_id), K(data_tablet_id)); - } else if (OB_FAIL(data_tablet.get_obj()->get_ddl_data(ddl_data))) { + } else if (OB_FAIL(data_tablet.get_obj()->ObITabletMdsInterface::get_ddl_data(share::SCN::max_scn(), ddl_data))) { LOG_WARN("failed to get ddl data from tablet", K(ret), K(data_tablet)); } else { const common::ObTabletID &lob_meta_tablet_id = ddl_data.lob_meta_tablet_id_; diff --git a/src/storage/ls/ob_freezer.cpp b/src/storage/ls/ob_freezer.cpp index bd2b98e38..4c3fc1fc1 100644 --- a/src/storage/ls/ob_freezer.cpp +++ b/src/storage/ls/ob_freezer.cpp @@ -652,14 +652,14 @@ int ObFreezer::freeze_normal_tablet_(const ObTabletID &tablet_id, ObFuture ret = OB_NOT_INIT; TRANS_LOG(WARN, "[Freezer] not inited", K(ret), K(ls_id), K(tablet_id)); } else if (OB_UNLIKELY(!enable_)) { + ret = OB_NOT_RUNNING; LOG_WARN("freezer is offline, can not freeze now", K(ret), K(ls_id)); } else if (OB_FAIL(guard.try_set_tablet_freeze_begin())) { // no need freeze now, a ls freeze is running or will be running ret = OB_SUCCESS; - FLOG_INFO("[Freezer] ls freeze is running, no need freeze again", K(ret), K(ls_id), K(tablet_id)); + LOG_INFO("[Freezer] ls freeze is running, no need freeze again", K(ret), K(ls_id), K(tablet_id)); } else if (OB_FAIL(set_freeze_flag_without_inc_freeze_clock())) { - ret = OB_SUCCESS; - FLOG_INFO("[Freezer] freeze is running", K(ret), K(ls_id), K(tablet_id)); + LOG_INFO("[Freezer] freeze is running", K(ret), K(ls_id), K(tablet_id)); } else { // succeed to set freeze flag if (OB_FAIL(get_ls_weak_read_scn(freeze_snapshot_version))) { @@ -679,8 +679,8 @@ int ObFreezer::freeze_normal_tablet_(const ObTabletID &tablet_id, ObFuture false/*is_force*/))) { TRANS_LOG(WARN, "[Freezer] fail to begin_set_freeze_stat", K(ret), K(ls_id)); } else if (OB_FAIL(get_ls_tablet_svr()->get_tablet(tablet_id, - handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + handle, 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { TRANS_LOG(WARN, "[Freezer] fail to get tablet", K(ret), K(ls_id), K(tablet_id)); stat_.add_diagnose_info("fail to get tablet"); } else if (FALSE_IT(tablet = handle.get_obj())) { @@ -765,8 +765,8 @@ int ObFreezer::force_tablet_freeze(const ObTabletID &tablet_id) true/*is_force*/))) { TRANS_LOG(WARN, "[Freezer] fail to begin_set_freeze_stat", K(ret), K(ls_id)); } else if (OB_FAIL(get_ls_tablet_svr()->get_tablet(tablet_id, - handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + handle, 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { TRANS_LOG(WARN, "[Freezer] fail to get tablet for freeze", K(ret), K(ls_id), K(tablet_id)); stat_.add_diagnose_info("fail to get tablet"); } else if (FALSE_IT(tablet = handle.get_obj())) { @@ -927,8 +927,8 @@ int ObFreezer::tablet_freeze_for_replace_tablet_meta(const ObTabletID &tablet_id false/*is_force*/))) { TRANS_LOG(WARN, "[Freezer] fail to begin_set_freeze_stat", K(ret), K(ls_id)); } else if (OB_FAIL(get_ls_tablet_svr()->get_tablet(tablet_id, - handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + handle, 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { TRANS_LOG(WARN, "[Freezer] fail to get tablet", K(ret), K(ls_id), K(tablet_id)); stat_.add_diagnose_info("fail to get tablet"); } else if (FALSE_IT(tablet = handle.get_obj())) { @@ -1051,7 +1051,8 @@ int ObFreezer::batch_tablet_freeze_(const ObIArray &tablet_ids, ObFu ObTabletMemtableMgr *memtable_mgr = nullptr; if (OB_FAIL(get_ls_tablet_svr()->get_tablet(tablet_id, handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObTabletCommon::DEFAULT_GET_TABLET_NO_WAIT, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { TRANS_LOG(WARN, "[Freezer] fail to get tablet", K(ret), K(ls_id), K(tablet_id)); stat_.add_diagnose_info("fail to get tablet"); } else if (FALSE_IT(tablet = handle.get_obj())) { @@ -1228,12 +1229,13 @@ int ObFreezer::submit_log_for_freeze() if (TC_REACH_TIME_INTERVAL(5 * 1000 * 1000)) { TRANS_LOG(WARN, "[Freezer] failed to traverse trans ctx to submit redo log", K(ret), K(ls_id), K(cost_time), K(fail_tx_id)); - ADD_SUSPECT_INFO(MINI_MERGE, - ls_id, tablet_id, - "traverse_trans_to_submit_redo_log failed", - K(ret), - K(fail_tx_id)); stat_.add_diagnose_info("traverse_trans_to_submit_redo_log failed"); + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(ADD_SUSPECT_INFO(MINI_MERGE, + ls_id, tablet_id, ObSuspectInfoType::SUSPECT_SUBMIT_LOG_FOR_FREEZE, + static_cast(ret), fail_tx_id.get_id()))) { + TRANS_LOG(WARN, "failed to add suspect info", K(tmp_ret)); + } } } } @@ -1383,9 +1385,8 @@ int ObFreezer::create_memtable_if_no_active_memtable(ObTablet *tablet) if (OB_FAIL(ret)) { } else if (OB_NOT_NULL(last_frozen_memtable)) { schema_version = last_frozen_memtable->get_max_schema_version(); - } else if (OB_FAIL(tablet->get_schema_version_from_storage_schema(schema_version))) { - LOG_WARN("[Freezer] failed to get schema version", K(ret), K(ls_id), K(tablet_id)); } else { + schema_version = tablet->get_tablet_meta().max_sync_storage_schema_version_; //do nothing } // create new memtable @@ -1438,8 +1439,7 @@ int ObFreezer::set_freeze_flag_without_inc_freeze_clock() do { old_v = ATOMIC_LOAD(&freeze_flag_); if (is_freeze(old_v)) { - ret = OB_ENTRY_EXIST; - TRANS_LOG(WARN, "[Freezer] freeze is running!", K(ret), K(ls_id)); + ret = OB_EAGAIN; break; } new_v = old_v | (1 << 31); @@ -1461,7 +1461,7 @@ int ObFreezer::set_freeze_flag() do { old_v = ATOMIC_LOAD(&freeze_flag_); if (is_freeze(old_v)) { - ret = OB_ENTRY_EXIST; + ret = OB_EAGAIN; TRANS_LOG(WARN, "[Freezer] freeze is running!", K(ret), K(ls_id)); break; } @@ -1622,7 +1622,7 @@ int ObFreezer::get_newest_clog_checkpoint_scn(const ObTabletID &tablet_id, ret = OB_NOT_INIT; TRANS_LOG(WARN, "[Freezer] not inited", K(ret)); } else if (OB_FAIL(get_ls_tablet_svr()->get_tablet(tablet_id, - handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { TRANS_LOG(WARN, "[Freezer] fail to get tablet", K(ret), K(ls_id), K(tablet_id)); } else { clog_checkpoint_scn = handle.get_obj()->get_tablet_meta().clog_checkpoint_scn_; @@ -1645,7 +1645,7 @@ int ObFreezer::get_newest_snapshot_version(const ObTabletID &tablet_id, ret = OB_NOT_INIT; TRANS_LOG(WARN, "[Freezer] not inited", K(ret)); } else if (OB_FAIL(get_ls_tablet_svr()->get_tablet(tablet_id, - handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { TRANS_LOG(WARN, "[Freezer] fail to get tablet", K(ret), K(ls_id), K(tablet_id)); } else if (OB_FAIL(snapshot_version.convert_for_tx(handle.get_obj()->get_snapshot_version()))) { TRANS_LOG(WARN, "[Freezer] fail to convert from ts", K(ret), K(ls_id), K(tablet_id)); diff --git a/src/storage/ls/ob_ls.cpp b/src/storage/ls/ob_ls.cpp old mode 100644 new mode 100755 index 94120e3b5..fb380bea4 --- a/src/storage/ls/ob_ls.cpp +++ b/src/storage/ls/ob_ls.cpp @@ -13,39 +13,52 @@ #define USING_LOG_PREFIX STORAGE #include "lib/utility/utility.h" -#include "share/ob_tenant_info_proxy.h" -#include "storage/ls/ob_ls.h" -#include "share/leak_checker/obj_leak_checker.h" -#include "share/ob_ls_id.h" -#include "share/ob_global_autoinc_service.h" #include "logservice/ob_garbage_collector.h" #include "logservice/ob_log_base_type.h" #include "logservice/ob_log_service.h" #include "logservice/archiveservice/ob_archive_service.h" #include "logservice/data_dictionary/ob_data_dict_service.h" -#include "storage/tx/ob_trans_service.h" +#include "observer/net/ob_ingress_bw_alloc_service.h" +#include "observer/ob_srv_network_frame.h" #include "observer/report/ob_i_meta_report.h" +#include "rootserver/freeze/ob_major_freeze_service.h" +#include "rootserver/backup/ob_backup_task_scheduler.h" +#include "rootserver/backup/ob_backup_service.h" +#include "rootserver/backup/ob_archive_scheduler_service.h" +#include "rootserver/ob_balance_task_execute_service.h" +#include "rootserver/ob_common_ls_service.h" +#include "rootserver/ob_create_standby_from_net_actor.h" +#include "rootserver/ob_heartbeat_service.h" +#include "rootserver/ob_primary_ls_service.h" +#include "rootserver/ob_recovery_ls_service.h" +#include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService +#include "rootserver/ob_tenant_balance_service.h" +#include "rootserver/restore/ob_restore_scheduler.h" +#include "share/ob_tenant_info_proxy.h" +#include "share/leak_checker/obj_leak_checker.h" +#include "share/ob_ls_id.h" +#include "share/ob_global_autoinc_service.h" +#include "sql/das/ob_das_id_service.h" #include "storage/compaction/ob_tenant_tablet_scheduler.h" -#include "storage/tx/ob_tx_log_adapter.h" -#include "storage/tx_table/ob_tx_table.h" +#include "storage/ls/ob_ls.h" #include "storage/slog/ob_storage_log.h" #include "storage/slog/ob_storage_logger.h" #include "storage/slog/ob_storage_log_struct.h" +#include "storage/tablet/ob_tablet.h" #include "storage/tablet/ob_tablet_create_delete_helper.h" #include "storage/tablet/ob_tablet_iterator.h" +#include "storage/tx/ob_standby_timestamp_service.h" #include "storage/tx/ob_timestamp_service.h" #include "storage/tx/ob_trans_id_service.h" -#include "storage/tx/ob_standby_timestamp_service.h" -#include "rootserver/freeze/ob_major_freeze_service.h" -#include "rootserver/ob_primary_ls_service.h" -#include "rootserver/ob_recovery_ls_service.h" -#include "rootserver/ob_create_standby_from_net_actor.h" -#include "rootserver/restore/ob_restore_scheduler.h" -#include "observer/net/ob_ingress_bw_alloc_service.h" -#include "observer/ob_srv_network_frame.h" -#include "rootserver/ob_heartbeat_service.h" -#include "sql/das/ob_das_id_service.h" -#include "storage/tablet/ob_tablet.h" +#include "storage/tx/ob_trans_service.h" +#include "storage/tx/ob_tx_log_adapter.h" +#include "storage/tx_table/ob_tx_table.h" +#include "storage/meta_mem/ob_meta_obj_struct.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/meta_mem/ob_tablet_map_key.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/tablet/ob_tablet_multi_source_data.h" +#include "storage/high_availability/ob_rebuild_service.h" namespace oceanbase { @@ -56,6 +69,9 @@ using namespace transaction; namespace storage { using namespace checkpoint; +using namespace mds; + +const share::SCN ObLS::LS_INNER_TABLET_FROZEN_SCN = share::SCN::base_scn(); const uint64_t ObLS::INNER_TABLET_ID_LIST[TOTAL_INNER_TABLET_NUM] = { common::ObTabletID::LS_TX_CTX_TABLET_ID, @@ -75,7 +91,8 @@ ObLS::ObLS() is_stopped_(false), is_offlined_(false), ls_meta_(), - rs_reporter_(nullptr) + rs_reporter_(nullptr), + startup_transfer_info_() {} ObLS::~ObLS() @@ -157,7 +174,12 @@ int ObLS::init(const share::ObLSID &ls_id, ls_service->get_storage_rpc_proxy(), ls_service->get_storage_rpc()))) { LOG_WARN("failed to init ls rebuild cb impl", K(ret)); } else if (OB_FAIL(tablet_gc_handler_.init(this))) { - LOG_WARN("init tablet gc handler", K(ret)); + LOG_WARN("failed to init tablet gc handler", K(ret)); + } else if (OB_FAIL(tablet_empty_shell_handler_.init(this))) { + LOG_WARN("failed to init tablet_empty_shell_handler", K(ret)); + } else if (OB_FAIL(transfer_handler_.init(this, GCTX.bandwidth_throttle_, + ls_service->get_storage_rpc_proxy(), ls_service->get_storage_rpc(), GCTX.sql_proxy_))) { + LOG_WARN("failed to init transfer handler", K(ret)); } else if (OB_FAIL(reserved_snapshot_mgr_.init(tenant_id, this, &log_handler_))) { LOG_WARN("failed to init reserved snapshot mgr", K(ret), K(ls_id)); } else if (OB_FAIL(reserved_snapshot_clog_handler_.init(this))) { @@ -166,6 +188,10 @@ int ObLS::init(const share::ObLSID &ls_id, LOG_WARN("failed to init medium compaction clog handler", K(ret), K(ls_id)); } else if (OB_FAIL(ls_recovery_stat_handler_.init(tenant_id, this))) { LOG_WARN("ls_recovery_stat_handler_ init failed", KR(ret)); + } else if (OB_FAIL(member_list_service_.init(this, &log_handler_))) { + LOG_WARN("failed to init member list service", K(ret)); + } else if (OB_FAIL(block_tx_service_.init(this))) { + LOG_WARN("failed to init block tx service", K(ret)); } else { REGISTER_TO_LOGSERVICE(logservice::TRANS_SERVICE_LOG_BASE_TYPE, &ls_tx_svr_); REGISTER_TO_LOGSERVICE(logservice::STORAGE_SCHEMA_LOG_BASE_TYPE, &ls_tablet_svr_); @@ -176,6 +202,8 @@ int ObLS::init(const share::ObLSID &ls_id, REGISTER_TO_LOGSERVICE(logservice::OBJ_LOCK_GARBAGE_COLLECT_SERVICE_LOG_BASE_TYPE, &lock_table_); REGISTER_TO_LOGSERVICE(logservice::RESERVED_SNAPSHOT_LOG_BASE_TYPE, &reserved_snapshot_clog_handler_); REGISTER_TO_LOGSERVICE(logservice::MEDIUM_COMPACTION_LOG_BASE_TYPE, &medium_compaction_clog_handler_); + REGISTER_TO_LOGSERVICE(logservice::TRANSFER_HANDLER_LOG_BASE_TYPE, &transfer_handler_); + REGISTER_TO_LOGSERVICE(logservice::LS_BLOCK_TX_SERVICE_LOG_BASE_TYPE, &block_tx_service_); if (ls_id == IDS_LS) { REGISTER_TO_LOGSERVICE(logservice::TIMESTAMP_LOG_BASE_TYPE, MTL(transaction::ObTimestampService *)); @@ -199,10 +227,37 @@ int ObLS::init(const share::ObLSID &ls_id, REGISTER_TO_LOGSERVICE(logservice::GAIS_LOG_BASE_TYPE, MTL(share::ObGlobalAutoIncService *)); MTL(share::ObGlobalAutoIncService *)->set_cache_ls(this); } + if (OB_SUCC(ret) && ls_id.is_sys_ls() && (is_meta_tenant(tenant_id) || is_sys_tenant(tenant_id))) { + REGISTER_TO_LOGSERVICE(logservice::BACKUP_TASK_SCHEDULER_LOG_BASE_TYPE, MTL(rootserver::ObBackupTaskScheduler *)); + REGISTER_TO_LOGSERVICE(logservice::BACKUP_DATA_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObBackupDataService *)); + REGISTER_TO_LOGSERVICE(logservice::BACKUP_CLEAN_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObBackupCleanService *)); + REGISTER_TO_LOGSERVICE(logservice::BACKUP_ARCHIVE_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObArchiveSchedulerService *)); + } if (OB_SUCC(ret) && ls_id.is_sys_ls()) { - //meta tenant need create thread for ls manager - REGISTER_TO_LOGSERVICE(logservice::PRIMARY_LS_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObPrimaryLSService *)); - LOG_INFO("primary ls manager registre to logservice success"); + if (is_user_tenant(tenant_id)) { + //user + REGISTER_TO_LOGSERVICE(logservice::PRIMARY_LS_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObPrimaryLSService *)); + LOG_INFO("primary ls manager register to logservice success"); + REGISTER_TO_RESTORESERVICE(logservice::RECOVERY_LS_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObRecoveryLSService *)); + LOG_INFO("recovery ls manager register to restoreservice success"); + REGISTER_TO_LOGSERVICE(logservice::TENANT_TRANSFER_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObTenantTransferService *)); + LOG_INFO("tenant transfer service registre to logservice success"); + //only user tenant need balance + REGISTER_TO_LOGSERVICE(logservice::TENANT_BALANCE_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObTenantBalanceService *)); + LOG_INFO("tenant balance service register to logservice success"); + //only user tenant need balance + REGISTER_TO_LOGSERVICE(logservice::BALANCE_EXECUTE_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObBalanceTaskExecuteService *)); + LOG_INFO("balance execute service register to logservice success"); + + } else { + //meta and sys + REGISTER_TO_LOGSERVICE(logservice::COMMON_LS_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObCommonLSService *)); + LOG_INFO("common ls manager register to logservice success"); + //sys and meta tenant + REGISTER_TO_LOGSERVICE(logservice::RESTORE_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObRestoreService *)); + LOG_INFO("restore service register to logservice success"); + //only meta + } } if (OB_SUCC(ret) && is_user_tenant(tenant_id) && ls_id.is_sys_ls()) { @@ -413,18 +468,15 @@ bool ObLS::is_need_gc() const bool bool_ret = false; ObMigrationStatus migration_status; ObInnerLSStatus create_status = ls_meta_.get_ls_create_status(); - - if (OB_FAIL(ls_meta_.get_migration_status(migration_status))) { + if (ObInnerLSStatus::CREATING == create_status || ObInnerLSStatus::REMOVED == create_status) { + bool_ret = true; + } else if (OB_FAIL(ls_meta_.get_migration_status(migration_status))) { LOG_WARN("get migration status failed", K(ret), K(ls_meta_.ls_id_)); + } else if (ObMigrationStatusHelper::check_allow_gc_abandoned_ls(migration_status)) { + bool_ret = true; } - - bool_ret = (OB_FAIL(ret) || - (ObInnerLSStatus::CREATING == create_status) || - (ObInnerLSStatus::REMOVED == create_status) || - (OB_MIGRATION_STATUS_NONE != migration_status && - ObMigrationStatusHelper::check_allow_gc(migration_status))); if (bool_ret) { - FLOG_INFO("ls need gc", K(ret), K(ls_meta_), K(migration_status)); + FLOG_INFO("ls need gc", K(bool_ret), K(create_status), K(migration_status)); } return bool_ret; } @@ -492,6 +544,7 @@ int ObLS::stop() int ObLS::stop_() { int ret = OB_SUCCESS; + tx_table_.stop(); ls_restore_handler_.stop(); keep_alive_ls_handler_.stop(); @@ -506,8 +559,14 @@ int ObLS::stop_() is_stopped_ = true; if (OB_SUCC(ret)) { + ObRebuildService *rebuild_service = nullptr; if (OB_FAIL(prepare_for_safe_destroy_())) { LOG_WARN("fail to prepare_for_safe_destroy", K(ret)); + } else if (OB_ISNULL(rebuild_service = MTL(ObRebuildService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rebuild service should not be NULL", K(ret), KP(rebuild_service)); + } else if (OB_FAIL(rebuild_service->remove_rebuild_ls(get_ls_id()))) { + LOG_WARN("failed to remove rebuild ls", K(ret), KPC(this)); } else { LOG_INFO("stop_ls finish", KR(ret), KPC(this)); } @@ -654,6 +713,9 @@ void ObLS::destroy() UNREGISTER_FROM_LOGSERVICE(logservice::OBJ_LOCK_GARBAGE_COLLECT_SERVICE_LOG_BASE_TYPE, &lock_table_); UNREGISTER_FROM_LOGSERVICE(logservice::RESERVED_SNAPSHOT_LOG_BASE_TYPE, &reserved_snapshot_clog_handler_); UNREGISTER_FROM_LOGSERVICE(logservice::MEDIUM_COMPACTION_LOG_BASE_TYPE, &medium_compaction_clog_handler_); + UNREGISTER_FROM_LOGSERVICE(logservice::TRANSFER_HANDLER_LOG_BASE_TYPE, &transfer_handler_); + UNREGISTER_FROM_LOGSERVICE(logservice::LS_BLOCK_TX_SERVICE_LOG_BASE_TYPE, &block_tx_service_); + if (ls_meta_.ls_id_ == IDS_LS) { MTL(transaction::ObTransIDService *)->reset_ls(); MTL(transaction::ObTimestampService *)->reset_ls(); @@ -672,13 +734,45 @@ void ObLS::destroy() rootserver::ObPrimaryMajorFreezeService *primary_major_freeze_service = MTL(rootserver::ObPrimaryMajorFreezeService *); UNREGISTER_FROM_LOGSERVICE(logservice::MAJOR_FREEZE_LOG_BASE_TYPE, primary_major_freeze_service); } - if (ls_meta_.ls_id_ == GAIS_LS && OB_SUCC(ret)) { + if (ls_meta_.ls_id_ == GAIS_LS) { UNREGISTER_FROM_LOGSERVICE(logservice::GAIS_LOG_BASE_TYPE, MTL(share::ObGlobalAutoIncService *)); MTL(share::ObGlobalAutoIncService *)->set_cache_ls(nullptr); } - if (OB_SUCC(ret) && ls_meta_.ls_id_.is_sys_ls()) { - rootserver::ObPrimaryLSService* ls_service = MTL(rootserver::ObPrimaryLSService*); - UNREGISTER_FROM_LOGSERVICE(logservice::PRIMARY_LS_SERVICE_LOG_BASE_TYPE, ls_service); + if (ls_meta_.ls_id_.is_sys_ls()) { + if (is_user_tenant(MTL_ID())) { + rootserver::ObPrimaryLSService* ls_service = MTL(rootserver::ObPrimaryLSService*); + UNREGISTER_FROM_LOGSERVICE(logservice::PRIMARY_LS_SERVICE_LOG_BASE_TYPE, ls_service); + rootserver::ObRecoveryLSService* recovery_ls_service = MTL(rootserver::ObRecoveryLSService*); + UNREGISTER_FROM_RESTORESERVICE(logservice::RECOVERY_LS_SERVICE_LOG_BASE_TYPE, recovery_ls_service); + rootserver::ObTenantTransferService * transfer_service = MTL(rootserver::ObTenantTransferService*); + UNREGISTER_FROM_LOGSERVICE(logservice::TENANT_TRANSFER_SERVICE_LOG_BASE_TYPE, transfer_service); + rootserver::ObTenantBalanceService* balance_service = MTL(rootserver::ObTenantBalanceService*); + UNREGISTER_FROM_LOGSERVICE(logservice::TENANT_BALANCE_SERVICE_LOG_BASE_TYPE, balance_service); + rootserver::ObBalanceTaskExecuteService* balance_execute_service = MTL(rootserver::ObBalanceTaskExecuteService*); + UNREGISTER_FROM_LOGSERVICE(logservice::BALANCE_EXECUTE_SERVICE_LOG_BASE_TYPE, balance_execute_service); + + } else { + rootserver::ObCommonLSService *ls_service = MTL(rootserver::ObCommonLSService*); + UNREGISTER_FROM_LOGSERVICE(logservice::COMMON_LS_SERVICE_LOG_BASE_TYPE, ls_service); + rootserver::ObRestoreService * restore_service = MTL(rootserver::ObRestoreService*); + UNREGISTER_FROM_LOGSERVICE(logservice::RESTORE_SERVICE_LOG_BASE_TYPE, restore_service); + } + } + + if (ls_meta_.ls_id_.is_sys_ls() && !is_user_tenant(MTL_ID())) { + rootserver::ObBackupTaskScheduler* backup_task_scheduler = MTL(rootserver::ObBackupTaskScheduler*); + UNREGISTER_FROM_LOGSERVICE(logservice::BACKUP_TASK_SCHEDULER_LOG_BASE_TYPE, backup_task_scheduler); + rootserver::ObBackupDataService* backup_data_service = MTL(rootserver::ObBackupDataService*); + UNREGISTER_FROM_LOGSERVICE(logservice::BACKUP_DATA_SERVICE_LOG_BASE_TYPE, backup_data_service); + rootserver::ObBackupCleanService* backup_clean_service = MTL(rootserver::ObBackupCleanService*); + UNREGISTER_FROM_LOGSERVICE(logservice::BACKUP_CLEAN_SERVICE_LOG_BASE_TYPE, backup_clean_service); + rootserver::ObArchiveSchedulerService* backup_archive_service = MTL(rootserver::ObArchiveSchedulerService*); + UNREGISTER_FROM_LOGSERVICE(logservice::BACKUP_ARCHIVE_SERVICE_LOG_BASE_TYPE, backup_archive_service); + } + + + if (is_user_tenant(MTL_ID()) && ls_meta_.ls_id_.is_sys_ls()) { + UNREGISTER_FROM_LOGSERVICE(logservice::DATA_DICT_LOG_BASE_TYPE, MTL(datadict::ObDataDictService *)); } if (OB_SUCC(ret) && is_user_tenant(MTL_ID()) && ls_meta_.ls_id_.is_sys_ls()) { @@ -704,6 +798,7 @@ void ObLS::destroy() rootserver::ObIngressBWAllocService *ingress_service = GCTX.net_frame_->get_ingress_service(); UNREGISTER_FROM_LOGSERVICE(logservice::NET_ENDPOINT_INGRESS_LOG_BASE_TYPE, ingress_service); } + tx_table_.destroy(); lock_table_.destroy(); ls_tablet_svr_.destroy(); @@ -730,13 +825,18 @@ void ObLS::destroy() ls_migration_handler_.destroy(); ls_remove_member_handler_.destroy(); tablet_gc_handler_.reset(); + tablet_empty_shell_handler_.reset(); + transfer_handler_.destroy(); reserved_snapshot_mgr_.destroy(); reserved_snapshot_clog_handler_.reset(); medium_compaction_clog_handler_.reset(); ls_recovery_stat_handler_.reset(); + member_list_service_.destroy(); + block_tx_service_.destroy(); rs_reporter_ = nullptr; is_inited_ = false; tenant_id_ = OB_INVALID_TENANT_ID; + startup_transfer_info_.reset(); } int ObLS::offline_tx_() @@ -767,6 +867,7 @@ int ObLS::offline_() { int ret = OB_SUCCESS; // only follower can do this. + if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("ls is not inited", K(ret)); @@ -798,6 +899,8 @@ int ObLS::offline_() LOG_WARN("tablet service offline failed", K(ret), K(ls_meta_)); } else if (OB_FAIL(tablet_gc_handler_.offline())) { LOG_WARN("tablet gc handler offline failed", K(ret), K(ls_meta_)); + } else if (OB_FAIL(tablet_empty_shell_handler_.offline())) { + LOG_WARN("tablet_empty_shell_handler failed", K(ret), K(ls_meta_)); } else { // do nothing } @@ -907,6 +1010,7 @@ int ObLS::online() LOG_WARN("ls restore handler online failed", K(ret)); } else if (FALSE_IT(checkpoint_executor_.online())) { } else if (FALSE_IT(tablet_gc_handler_.online())) { + } else if (FALSE_IT(tablet_empty_shell_handler_.online())) { } else { is_offlined_ = false; // do nothing @@ -939,6 +1043,7 @@ int ObLS::get_ls_meta_package(const bool check_archive, ObLSMetaPackage &meta_pa palf::LSN begin_lsn; palf::LSN archive_lsn; SCN unused_archive_scn; + const int64_t cost_time = 10 * 1000 * 1000; // 10s bool archive_force = false; bool archive_ignore = false; const ObLSID &id = get_ls_id(); @@ -948,6 +1053,8 @@ int ObLS::get_ls_meta_package(const bool check_archive, ObLSMetaPackage &meta_pa } else { meta_package.ls_meta_ = ls_meta_; palf::LSN curr_lsn = meta_package.ls_meta_.get_clog_base_lsn(); + ObTimeGuard time_guard("get_ls_meta_package", cost_time); + time_guard.click(); if (! check_archive) { LOG_TRACE("no need check archive", K(id), K(check_archive)); } else if (OB_FAIL(MTL(archive::ObArchiveService*)->get_ls_archive_progress( @@ -963,12 +1070,13 @@ int ObLS::get_ls_meta_package(const bool check_archive, ObLSMetaPackage &meta_pa ret = OB_CLOG_RECYCLE_BEFORE_ARCHIVE; LOG_WARN("log recycled before archive", K(ret), K(archive_lsn), K(begin_lsn), K(archive_ignore)); } - + time_guard.click(); if (OB_SUCC(ret) && OB_FAIL(log_handler_.get_palf_base_info(curr_lsn, meta_package.palf_meta_))) { LOG_WARN("get palf base info failed", K(ret), K(id), K(curr_lsn), K(archive_force), K(archive_ignore), K(archive_lsn), K_(ls_meta)); } + time_guard.click(); if (OB_SUCC(ret) && OB_FAIL(dup_table_ls_handler_.get_dup_table_ls_meta(meta_package.dup_ls_meta_))) { LOG_WARN("get dup table ls meta failed", K(ret), K(id), K(meta_package.dup_ls_meta_)); @@ -1114,6 +1222,7 @@ int ObLS::get_ls_info(ObLSVTInfo &ls_info) ls_info.checkpoint_lsn_ = ls_meta_.get_clog_base_lsn().val_; ls_info.rebuild_seq_ = ls_meta_.get_rebuild_seq(); ls_info.tablet_change_checkpoint_scn_ = ls_meta_.get_tablet_change_checkpoint_scn(); + ls_info.transfer_scn_ = ls_meta_.get_transfer_scn(); } return ret; } @@ -1219,7 +1328,7 @@ int ObLS::update_tablet_table_store( int ObLS::update_tablet_table_store( const int64_t rebuild_seq, const ObTabletHandle &old_tablet_handle, - const ObIArray &table_handles) + const ObIArray &tables) { int ret = OB_SUCCESS; const int64_t read_lock = LSLOCKLOGMETA; @@ -1228,16 +1337,16 @@ int ObLS::update_tablet_table_store( if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("ls hasn't been inited", K(ret)); - } else if (OB_UNLIKELY(!old_tablet_handle.is_valid() || 0 == table_handles.count())) { + } else if (OB_UNLIKELY(!old_tablet_handle.is_valid() || 0 == tables.count())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(old_tablet_handle), K(table_handles)); + LOG_WARN("invalid argument", K(old_tablet_handle), K(tables)); } else { const int64_t seq = ls_meta_.get_rebuild_seq(); if (rebuild_seq != seq) { ret = OB_EAGAIN; LOG_WARN("rebuild seq has changed, retry", K(ret), K(seq), K(rebuild_seq)); - } else if (OB_FAIL(ls_tablet_svr_.update_tablet_table_store(old_tablet_handle, table_handles))) { - LOG_WARN("fail to replace small sstables in the tablet", K(ret), K(old_tablet_handle), K(table_handles)); + } else if (OB_FAIL(ls_tablet_svr_.update_tablet_table_store(old_tablet_handle, tables))) { + LOG_WARN("fail to replace small sstables in the tablet", K(ret), K(old_tablet_handle), K(tables)); } } return ret; @@ -1314,15 +1423,15 @@ int ObLS::finish_slog_replay() return ret; } -int ObLS::replay_get_tablet(const common::ObTabletID &tablet_id, +int ObLS::replay_get_tablet_no_check(const common::ObTabletID &tablet_id, const SCN &scn, ObTabletHandle &handle) const { int ret = OB_SUCCESS; const ObTabletMapKey key(ls_meta_.ls_id_, tablet_id); const SCN tablet_change_checkpoint_scn = ls_meta_.get_tablet_change_checkpoint_scn(); - ObTabletHandle tablet_handle; SCN max_scn; + ObTabletHandle tablet_handle; if (IS_NOT_INIT) { ret = OB_NOT_INIT; @@ -1335,6 +1444,7 @@ int ObLS::replay_get_tablet(const common::ObTabletID &tablet_id, LOG_WARN("failed to get tablet", K(ret), K(key)); } else if (scn <= tablet_change_checkpoint_scn) { LOG_WARN("tablet already gc", K(ret), K(key), K(scn), K(tablet_change_checkpoint_scn)); + ret = OB_OBSOLETE_CLOG_NEED_SKIP; } else if (OB_FAIL(MTL(ObLogService*)->get_log_replay_service()->get_max_replayed_scn(ls_meta_.ls_id_, max_scn))) { LOG_WARN("failed to get_max_replayed_scn", KR(ret), K_(ls_meta), K(scn), K(tablet_id)); } @@ -1353,28 +1463,66 @@ int ObLS::replay_get_tablet(const common::ObTabletID &tablet_id, LOG_INFO("tablet does not exist, but need retry", KR(ret), K(key), K(scn), K(tablet_change_checkpoint_scn), K(max_scn)); } else { LOG_INFO("tablet already gc, but scn is more than tablet_change_checkpoint_scn", KR(ret), K(key), K(scn), K(tablet_change_checkpoint_scn), K(max_scn)); + ret = OB_OBSOLETE_CLOG_NEED_SKIP; } } } - if (OB_FAIL(ret)) { + if (OB_SUCC(ret)) { + handle = tablet_handle; + } + + return ret; +} + +int ObLS::replay_get_tablet(const common::ObTabletID &tablet_id, + const SCN &scn, + ObTabletHandle &handle) const +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ls is not inited", KR(ret)); + } else if (OB_FAIL(replay_get_tablet_no_check(tablet_id, scn, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id), K(ls_meta_.ls_id_)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_id), K(scn)); } else { - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data, false/*check_valid*/))) { - LOG_WARN("failed to get tablet tx data", KR(ret), K(tablet_handle)); - } else if (ObTabletStatus::CREATING == tx_data.tablet_status_) { - ret = OB_EAGAIN; - LOG_INFO("tablet is CREATING, need retry", KR(ret), K(key), K(tx_data), K(scn)); - } else if (ObTabletStatus::NORMAL == tx_data.tablet_status_) { + ObTabletStatus::Status tablet_status = ObTabletStatus::MAX; + ObTabletCreateDeleteMdsUserData data; + bool is_commited = false; + if (tablet_id.is_ls_inner_tablet()) { // do nothing - } else if (ObTabletStatus::DELETING == tx_data.tablet_status_) { - LOG_INFO("tablet is DELETING, just continue", KR(ret), K(key), K(tx_data), K(scn)); - } else if (ObTabletStatus::DELETED == tx_data.tablet_status_) { - ret = OB_TABLET_NOT_EXIST; - LOG_INFO("tablet is already deleted", KR(ret), K(key), K(tx_data), K(scn)); + } else if (tablet->get_clog_checkpoint_scn() >= scn) { + ret = OB_OBSOLETE_CLOG_NEED_SKIP; + LOG_WARN("replay scn is smaller than tablet clog checkpoint scn, need skip", K(ret), KPC(tablet), K(scn)); + } else if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_latest_tablet_status(data, is_commited))) { + if (OB_EMPTY_RESULT == ret) { + LOG_WARN("rewrite errcode to EAGAIN", KR(ret), K(tablet_id), K(ls_meta_.ls_id_)); + ret = OB_EAGAIN; + } else { + LOG_WARN("failed to get CreateDeleteMdsUserData", KR(ret), K(tablet_id), K(ls_meta_.ls_id_)); + } + } else if (FALSE_IT(tablet_status = data.get_tablet_status())) { + } else if (tablet->is_empty_shell()) { + if (ObTabletStatus::DELETED != tablet_status + && ObTabletStatus::TRANSFER_OUT_DELETED != tablet_status) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tablet is empty shell but tablet status is not deleted or transfer out deleted", + KR(ret), K(tablet_id), K(ls_meta_.ls_id_), K(scn), K(tablet_status)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tablet is already be empty shell but still has data clog", KR(ret), K(tablet_id), K(ls_meta_.ls_id_), K(scn)); + } } else { - ret = OB_EAGAIN; - LOG_INFO("tablet may be in creating procedure", KR(ret), K(key), K(tx_data), K(scn)); + //There will be cases when the mds has been persisted but the clog_checkpoint_scn is still relatively small. + //There is no problem with primary database, but for the standby database, the read timestamp of tenant's + //standby machine is relatively small but no valid data can be read because the data is filtered when skip + //ObTabletStatus::DELETED == tablet_status or ObTabletStatus::TRANSFER_OUT_DELETED == tablet_status } } @@ -1579,6 +1727,63 @@ int ObLS::get_ls_meta_package_and_tablet_ids(const bool check_archive, return ret; } + +int ObLS::get_ls_meta_package_and_tablet_metas( + const bool check_archive, + const HandleLSMetaFunc &handle_ls_meta_f, + const ObLSTabletService::HandleTabletMetaFunc &handle_tablet_meta_f) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ls is not inited", K(ret)); + } else if (OB_UNLIKELY(is_stopped_)) { + ret = OB_NOT_RUNNING; + LOG_WARN("ls stopped", K(ret), K_(ls_meta)); + } else { + // TODO(wangxiaohui.wxh) consider the ls is offline meanwhile. + // disable gc while get all tablet meta + tablet_gc_handler_.disable_gc(); + ObLSMetaPackage meta_package; + if (OB_FAIL(get_ls_meta_package(check_archive, meta_package))) { + LOG_WARN("failed to get ls meta package", K(ret), K_(ls_meta)); + } else if (OB_FAIL(handle_ls_meta_f(meta_package))) { + LOG_WARN("failed to handle ls meta", K(ret), K_(ls_meta), K(meta_package)); + } else if (OB_FAIL(ls_tablet_svr_.ha_scan_all_tablets(handle_tablet_meta_f))) { + LOG_WARN("failed to scan all tablets", K(ret), K_(ls_meta)); + } + + tablet_gc_handler_.enable_gc(); + } + + return ret; +} + + + + +int ObLS::get_transfer_scn(share::SCN &scn) +{ + int ret = OB_SUCCESS; + share::SCN max_tablet_scn; + max_tablet_scn.set_min(); + int64_t read_lock = LSLOCKLOGMETA; + int64_t write_lock = 0; + ObLSLockGuard lock_myself(this, lock_, read_lock, write_lock); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ls is not inited", K(ret)); + } else if (OB_UNLIKELY(is_stopped_)) { + ret = OB_NOT_RUNNING; + LOG_WARN("ls stopped", K(ret), K_(ls_meta)); + } else if (OB_FAIL(ls_tablet_svr_.get_max_tablet_transfer_scn(max_tablet_scn))) { + LOG_WARN("failed to get max tablet transfer scn", K(ret), K_(ls_meta)); + } else { + scn = MAX(max_tablet_scn, ls_meta_.get_transfer_scn()); + } + return ret; +} + int ObLS::disable_sync() { int ret = OB_SUCCESS; @@ -1612,6 +1817,35 @@ int ObLS::enable_replay() return ret; } +int ObLS::check_can_replay_clog(bool &can_replay) +{ + int ret = OB_SUCCESS; + share::ObLSRestoreStatus restore_status; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + can_replay = true; + if (is_need_gc()) { + // this ls will be gc later, should not enable replay + can_replay = false; + } else if (OB_FAIL(get_migration_status(migration_status))) { + LOG_WARN("failed to get ls migration status", K(ret)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD == migration_status) { + // ls will online in rebuild process, ls online will enable clog replay + can_replay = false; + LOG_INFO("ls is in rebuild process, cannot replay clog", "ls_id", get_ls_id(), K(migration_status)); + } else if (OB_FAIL(get_restore_status(restore_status))) { + LOG_WARN("fail to get ls restore status", K(ret)); + } else if (!restore_status.can_replay_log()) { + // while downtime, if ls's restore status is in [restore_start, wait_restore_tablet_meta], clog can't replay + can_replay = false; + LOG_INFO("restore status not as expected, can not replay clog", "ls_id", get_ls_id(), K(restore_status)); + } else if (startup_transfer_info_.is_valid()) { + // There is a tablet has_transfer_table=true in the log stream, clog can't replay + can_replay = false; + LOG_INFO("ls not enable clog replay, need to wait for dependency to be removed", "ls_id", get_ls_id(), K_(startup_transfer_info)); + } + return ret; +} + int ObLS::enable_replay_without_lock() { int ret = OB_SUCCESS; @@ -1711,7 +1945,7 @@ int ObLS::try_update_uppder_trans_version() ret = OB_NOT_RUNNING; LOG_WARN("ls stopped", K(ret), K_(ls_meta)); } else { - ObLSTabletIterator tablet_iter(ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US); + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_ALL_COMMITED); ObTabletHandle tablet_handle; bool is_updated = false; ObMigrationStatus migration_status; @@ -1745,30 +1979,6 @@ int ObLS::try_update_uppder_trans_version() return ret; } -int ObLS::set_tablet_change_checkpoint_scn(const SCN &scn) -{ - int ret = OB_SUCCESS; - int64_t read_lock = 0; - int64_t write_lock = LSLOCKLOGMETA; - const bool try_lock = true; // the upper layer should deal with try lock fail. - ObLSLockGuard lock_myself(this, lock_, read_lock, write_lock, try_lock); - if (!lock_myself.locked()) { - ret = OB_EAGAIN; - LOG_WARN("try lock failed, please retry later", K(ret), K(ls_meta_)); - } else if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("ls is not inited", K(ret), K(ls_meta_)); - } else if (OB_UNLIKELY(is_stopped_)) { - ret = OB_NOT_RUNNING; - LOG_WARN("ls stopped", K(ret), K_(ls_meta)); - } else if (OB_FAIL(ls_meta_.set_tablet_change_checkpoint_scn(scn))) { - LOG_WARN("fail to set tablet_change_checkpoint_ts", K(ret), K(scn), K_(ls_meta)); - } else { - // do nothing - } - return ret; -} - int ObLS::update_ls_meta(const bool update_restore_status, const ObLSMeta &src_ls_meta) { @@ -1831,6 +2041,21 @@ int ObLS::diagnose(DiagnoseInfo &info) const return ret; } +int ObLS::inc_update_transfer_scn(const share::SCN &transfer_scn) +{ + int ret = OB_SUCCESS; + int64_t read_lock = LSLOCKLS; + int64_t write_lock = LSLOCKLOGMETA; + ObLSLockGuard lock_myself(this, lock_, read_lock, write_lock); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ls_meta_.inc_update_transfer_scn(transfer_scn))) { + LOG_WARN("fail to set transfer scn", K(ret), K(transfer_scn), K_(ls_meta)); + } else { + // do nothing + } + return ret; +} + int ObLS::set_migration_status( const ObMigrationStatus &migration_status, const int64_t rebuild_seq, diff --git a/src/storage/ls/ob_ls.h b/src/storage/ls/ob_ls.h old mode 100644 new mode 100755 index 246429dc0..5d0e974b8 --- a/src/storage/ls/ob_ls.h +++ b/src/storage/ls/ob_ls.h @@ -47,7 +47,6 @@ #include "logservice/restoreservice/ob_log_restore_handler.h" // ObLogRestoreHandler #include "logservice/ob_log_handler.h" #include "logservice/restoreservice/ob_log_restore_handler.h" // ObLogRestoreHandler -#include "storage/ls/ob_ls_member_table.h" #include "storage/ls/ob_ls_meta_package.h" #include "storage/ls/ob_ls_get_mod.h" #include "storage/tablelock/ob_lock_table.h" @@ -58,7 +57,12 @@ #include "storage/high_availability/ob_ls_remove_member_handler.h" #include "storage/high_availability/ob_ls_rebuild_cb_impl.h" #include "storage/tx_storage/ob_tablet_gc_service.h" +#include "storage/tx_storage/ob_empty_shell_task.h" +#include "storage/high_availability/ob_transfer_handler.h" #include "rootserver/ob_ls_recovery_stat_handler.h" //ObLSRecoveryStatHandler +#include "storage/high_availability/ob_ls_member_list_service.h" +#include "storage/high_availability/ob_ls_block_tx_service.h" +#include "storage/high_availability/ob_ls_transfer_info.h" namespace oceanbase { @@ -73,7 +77,6 @@ class SCN; namespace storage { -const static int64_t LS_INNER_TABLET_FROZEN_TIMESTAMP = 1; struct ObLSVTInfo { @@ -89,6 +92,7 @@ struct ObLSVTInfo int64_t checkpoint_lsn_; int64_t rebuild_seq_; share::SCN tablet_change_checkpoint_scn_; + share::SCN transfer_scn_; }; // 诊断虚表统计信息 @@ -147,6 +151,7 @@ public: public: static constexpr int64_t TOTAL_INNER_TABLET_NUM = 3; static const uint64_t INNER_TABLET_ID_LIST[TOTAL_INNER_TABLET_NUM]; + static const share::SCN LS_INNER_TABLET_FROZEN_SCN; public: class ObLSInnerTabletIDIter { @@ -208,11 +213,16 @@ public: logservice::ObGCHandler *get_gc_handler() { return &gc_handler_; } //migration handler ObLSMigrationHandler *get_ls_migration_handler() { return &ls_migration_handler_; } + //migration handler + ObTransferHandler *get_transfer_handler() { return &transfer_handler_; } + ObLSTransferInfo &get_ls_startup_transfer_info() { return startup_transfer_info_; } //remove member handler ObLSRemoveMemberHandler *get_ls_remove_member_handler() { return &ls_remove_member_handler_; } checkpoint::ObTabletGCHandler *get_tablet_gc_handler() { return &tablet_gc_handler_; } + ObLSMemberListService *get_member_list_service() { return &member_list_service_; } + checkpoint::ObTabletEmptyShellHandler *get_tablet_empty_shell_handler() { return &tablet_empty_shell_handler_; } // make sure the schema version does not back off. int save_base_schema_version(); @@ -296,12 +306,18 @@ public: int replay_get_tablet(const common::ObTabletID &tablet_id, const share::SCN &scn, ObTabletHandle &handle) const; + // get tablet but don't check user_data while replaying clog, because user_data may not exist. + int replay_get_tablet_no_check( + const common::ObTabletID &tablet_id, + const SCN &scn, + ObTabletHandle &tablet_handle) const; int flush_if_need(const bool need_flush); int try_sync_reserved_snapshot(const int64_t new_reserved_snapshot, const bool update_flag); bool is_stopped() const { return is_stopped_; } + int check_can_replay_clog(bool &can_replay); - TO_STRING_KV(K_(ls_meta), K_(log_handler), K_(restore_handler), K_(is_inited), K_(tablet_gc_handler)); + TO_STRING_KV(K_(ls_meta), K_(log_handler), K_(restore_handler), K_(is_inited), K_(tablet_gc_handler), K_(startup_transfer_info)); private: int ls_init_for_dup_table_(); int ls_destory_for_dup_table_(); @@ -323,6 +339,7 @@ public: // const int64_t limited_id, // const int64_t latest_log_ts, // const bool write_slog); + int get_transfer_scn(share::SCN &scn); DELEGATE_WITH_RET(ls_meta_, update_id_meta, int); int set_ls_rebuild(); // protect in ls lock @@ -341,7 +358,7 @@ public: DELEGATE_WITH_RET(ls_meta_, clear_saved_info, int); CONST_DELEGATE_WITH_RET(ls_meta_, get_rebuild_seq, int64_t); CONST_DELEGATE_WITH_RET(ls_meta_, get_tablet_change_checkpoint_scn, share::SCN); - + DELEGATE_WITH_RET(ls_meta_, set_tablet_change_checkpoint_scn, int); int set_restore_status( const share::ObLSRestoreStatus &restore_status, const int64_t rebuild_seq); @@ -378,9 +395,8 @@ public: // @param [in] replayable point // int get_ls_replayable_point(int64_t &replayable_point); DELEGATE_WITH_RET(ls_meta_, get_ls_replayable_point, int); - // set tablet_change_checkpoint_scn, add write lock of LSLOCKLOGMETA. - // @param [in] scn - int set_tablet_change_checkpoint_scn(const share::SCN &scn); + int inc_update_transfer_scn(const share::SCN &transfer_scn); + int set_transfer_scn(const share::SCN &transfer_scn); // get ls_meta_package and unsorted tablet_ids, add read lock of LSLOCKLOGMETA. // @param [in] check_archive if need check archive, for backup task is false, migration/rebuild is true // @param [out] meta_package @@ -389,32 +405,41 @@ public: ObLSMetaPackage &meta_package, common::ObIArray &tablet_ids); DELEGATE_WITH_RET(ls_meta_, get_migration_and_restore_status, int); + DELEGATE_WITH_RET(ls_meta_, set_rebuild_info, int); + DELEGATE_WITH_RET(ls_meta_, get_rebuild_info, int); + + + // get ls_meta_package and sorted tablet_metas for backup. tablet gc is forbidden meanwhile. + // @param [in] check_archive if need check archive, migration/rebuild is true + // @param [in] handle_ls_meta_f, ls meta callback, will be first called. + // @param [in] handle_tablet_meta_f, tablet meta callback + typedef common::ObFunction HandleLSMetaFunc; + int get_ls_meta_package_and_tablet_metas( + const bool check_archive, + const HandleLSMetaFunc &handle_ls_meta_f, + const ObLSTabletService::HandleTabletMetaFunc &handle_tablet_meta_f); // ObLSTabletService interface: - // create tablets in a ls - // @param [in] arg, all the create parameters needed. - // @param [in] is_replay, whether write log or not. - // int batch_create_tablets( - // const obrpc::ObBatchCreateTabletArg &arg, - // const bool is_replay = false); - DELEGATE_WITH_RET(ls_tablet_svr_, batch_create_tablets, int); - // remove tablets - // @param [in] arg, all the remove parameters needed. - // @param [in] is_replay, whether write log or not. - // int batch_remove_tablets( - // const obrpc::ObBatchRemoveTabletArg &arg, - // const bool is_replay = false); - DELEGATE_WITH_RET(ls_tablet_svr_, batch_remove_tablets, int); + // ObLSTabletService interface: + // update tablet by checkpoint + // @param [in] key, key of tablet that will be updated + // @param [in] new_addr, new addr of the tablet + // @param [out] new_handle, new tablet handle + DELEGATE_WITH_RET(ls_tablet_svr_, update_tablet_checkpoint, int); // get a tablet handle // @param [in] tablet_id, the tablet needed // @param [out] handle, store the tablet and inc ref. // @param [in] timeout_us, timeout(mircosecond) for get tablet - // int get_tablet( - // const ObTabletID &tablet_id, - // ObTabletHandle &handle, - // const int64_t timeout_us); - DELEGATE_WITH_RET(ls_tablet_svr_, get_tablet, int); - // get ls tablet iterator + // @param [in] mode, read mds tablet isolation level + int get_tablet( + const common::ObTabletID &tablet_id, + ObTabletHandle &handle, + const int64_t timeout_us = ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US, + const ObMDSGetTabletMode mode = ObMDSGetTabletMode::READ_READABLE_COMMITED) + { + return ls_tablet_svr_.get_tablet(tablet_id, handle, timeout_us, mode); + } + // get ls tablet iterator // @param [out] iterator, ls tablet iterator to iterate all tablets in ls // int build_tablet_iter(ObLSTabletIterator &iter); // int build_tablet_iter(ObLSTabletIDIterator &iter); @@ -432,14 +457,42 @@ public: // @param [in] tbalet_ids ObIArray // @param [out] null // int remote_tablets( - // const common::ObIArray &tablet_id_array); + // const common::ObIArray &tablet_id_array); DELEGATE_WITH_RET(ls_tablet_svr_, remove_tablets, int); + // create_ls_inner_tablet + // @param [in] ls_id + // @param [in] tablet_id + // @param [in] memstore_version + // @param [in] frozen_timestamp + // @param [in] table_schema + // @param [in] compat_mode + // @param [in] create_scn + // int create_ls_inner_tablet( + // const share::ObLSID &ls_id, + // const common::ObTabletID &tablet_id, + // const int64_t frozen_timestamp, + // const share::schema::ObTableSchema &table_schema, + // const lib::Worker::CompatMode &compat_mode, + // const share::SCN &create_scn); + DELEGATE_WITH_RET(ls_tablet_svr_, create_ls_inner_tablet, int); + // remove_ls_inner_tablet + // @param [in] ls_id + // @param [in] tablet_id + // int remove_ls_inner_tablet( + // const share::ObLSID &ls_id, + // const common::ObTabletID &tablet_id); + DELEGATE_WITH_RET(ls_tablet_svr_, remove_ls_inner_tablet, int); DELEGATE_WITH_RET(ls_tablet_svr_, rebuild_create_tablet, int); DELEGATE_WITH_RET(ls_tablet_svr_, update_tablet_ha_data_status, int); + DELEGATE_WITH_RET(ls_tablet_svr_, ha_get_tablet, int); DELEGATE_WITH_RET(ls_tablet_svr_, update_tablet_restore_status, int); DELEGATE_WITH_RET(ls_tablet_svr_, create_or_update_migration_tablet, int); + DELEGATE_WITH_RET(ls_tablet_svr_, flush_mds_table, int); DELEGATE_WITH_RET(ls_tablet_svr_, enable_to_read, void); DELEGATE_WITH_RET(ls_tablet_svr_, disable_to_read, void); + DELEGATE_WITH_RET(ls_tablet_svr_, get_max_tablet_transfer_scn, int); + DELEGATE_WITH_RET(ls_tablet_svr_, get_tablet_with_timeout, int); + DELEGATE_WITH_RET(ls_tablet_svr_, get_mds_table_mgr, int); // ObLockTable interface: // check whether the lock op is conflict with exist lock. @@ -523,6 +576,12 @@ public: // int get_ls_replica_readable_scn(share::SCN &readable_scn) DELEGATE_WITH_RET(ls_recovery_stat_handler_, get_ls_replica_readable_scn, int); + // get ls level recovery_stat by LS leader. + // If follower LS replica call this function, it will return OB_NOT_MASTER. + // @param[out] ls_recovery_stat + // int get_ls_replica_readable_scn(share::SCN &readable_scn) + DELEGATE_WITH_RET(ls_recovery_stat_handler_, get_ls_level_recovery_stat, int); + // disable clog sync. // with ls read lock and log write lock. int disable_sync(); @@ -562,19 +621,25 @@ public: // @param[in] need_check. // @param[out] null. DELEGATE_WITH_RET(log_handler_, disable_vote, int); - DELEGATE_WITH_RET(log_handler_, add_member, int); DELEGATE_WITH_RET(log_handler_, remove_member, int); - DELEGATE_WITH_RET(log_handler_, add_learner, int); DELEGATE_WITH_RET(log_handler_, remove_learner, int); - DELEGATE_WITH_RET(log_handler_, replace_learner, int); - DELEGATE_WITH_RET(log_handler_, replace_member, int); DELEGATE_WITH_RET(log_handler_, is_in_sync, int); DELEGATE_WITH_RET(log_handler_, get_end_scn, int); DELEGATE_WITH_RET(log_handler_, disable_sync, int); DELEGATE_WITH_RET(log_handler_, change_replica_num, int); DELEGATE_WITH_RET(log_handler_, get_end_lsn, int); + DELEGATE_WITH_RET(log_handler_, try_lock_config_change, int); + DELEGATE_WITH_RET(log_handler_, unlock_config_change, int); + DELEGATE_WITH_RET(log_handler_, get_config_change_lock_stat, int); DELEGATE_WITH_RET(log_handler_, switch_acceptor_to_learner, int); - DELEGATE_WITH_RET(log_handler_, switch_learner_to_acceptor, int); + DELEGATE_WITH_RET(member_list_service_, switch_learner_to_acceptor, int); + DELEGATE_WITH_RET(member_list_service_, add_member, int); + DELEGATE_WITH_RET(member_list_service_, replace_member, int); + DELEGATE_WITH_RET(log_handler_, add_learner, int); //TODO(yanfeng): fix it + DELEGATE_WITH_RET(log_handler_, replace_learner, int); //TODO(yanfeng): fix it + DELEGATE_WITH_RET(block_tx_service_, ha_block_tx, int); + DELEGATE_WITH_RET(block_tx_service_, ha_kill_tx, int); + DELEGATE_WITH_RET(block_tx_service_, ha_unblock_tx, int); // Create a TxCtx whose tx_id is specified // @param [in] tx_id: transaction ID @@ -652,6 +717,8 @@ public: // int iterate_tx_obj_lock_op(ObLockOpIterator &iter) const; CONST_DELEGATE_WITH_RET(ls_tx_svr_, iterate_tx_obj_lock_op, int); + DELEGATE_WITH_RET(ls_tx_svr_, get_tx_ctx_count, int); + DELEGATE_WITH_RET(ls_tx_svr_, get_active_tx_count, int); //dup table ls meta interface CONST_DELEGATE_WITH_RET(dup_table_ls_handler_, get_dup_table_ls_meta, int); DELEGATE_WITH_RET(dup_table_ls_handler_, set_dup_table_ls_meta, int); @@ -713,7 +780,7 @@ public: int update_tablet_table_store( const int64_t rebuild_seq, const ObTabletHandle &old_tablet_handle, - const ObIArray &table_handles); + const ObIArray &tables); int build_ha_tablet_new_table_store( const ObTabletID &tablet_id, const ObBatchUpdateTableStoreParam ¶m); @@ -781,11 +848,15 @@ private: ObLSRebuildCbImpl ls_rebuild_cb_impl_; // for tablet gc checkpoint::ObTabletGCHandler tablet_gc_handler_; + // for update tablet to empty shell + checkpoint::ObTabletEmptyShellHandler tablet_empty_shell_handler_; // record reserved snapshot ObLSReservedSnapshotMgr reserved_snapshot_mgr_; ObLSResvSnapClogHandler reserved_snapshot_clog_handler_; ObMediumCompactionClogHandler medium_compaction_clog_handler_; rootserver::ObLSRecoveryStatHandler ls_recovery_stat_handler_; + ObLSMemberListService member_list_service_; + ObLSBlockTxService block_tx_service_; private: bool is_inited_; uint64_t tenant_id_; @@ -796,6 +867,11 @@ private: ObLSLock lock_; common::ObMultiModRefMgr ref_mgr_; logservice::coordinator::ElectionPriorityImpl election_priority_; + //for transfer + ObTransferHandler transfer_handler_; + // Record the dependent transfer information when restarting + ObLSTransferInfo startup_transfer_info_; + }; } diff --git a/src/storage/ls/ob_ls_ddl_log_handler.cpp b/src/storage/ls/ob_ls_ddl_log_handler.cpp index c1424b0a1..e85a5a3ce 100644 --- a/src/storage/ls/ob_ls_ddl_log_handler.cpp +++ b/src/storage/ls/ob_ls_ddl_log_handler.cpp @@ -19,6 +19,7 @@ #include "storage/compaction/ob_schedule_dag_func.h" #include "storage/tablet/ob_tablet_iterator.h" #include "storage/ddl/ob_tablet_ddl_kv_mgr.h" +#include "storage/ddl/ob_ddl_replay_executor.h" #include "logservice/ob_log_base_header.h" #include "share/scn.h" @@ -83,7 +84,7 @@ int ObLSDDLLogHandler::online() ret = OB_NOT_INIT; LOG_WARN("ddl log handler not init", K(ret)); } else { - ObLSTabletIterator tablet_iter(ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US); + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); if (OB_FAIL(ls_->get_tablet_svr()->build_tablet_iter(tablet_iter))) { LOG_WARN("failed to build ls tablet iter", K(ret), K(ls_)); } else { @@ -211,7 +212,7 @@ int ObLSDDLLogHandler::resume_leader() int ObLSDDLLogHandler::flush(SCN &rec_scn) { int ret = OB_SUCCESS; - ObLSTabletIterator tablet_iter(ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US); + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); if (OB_FAIL(ls_->get_tablet_svr()->build_tablet_iter(tablet_iter))) { LOG_WARN("failed to build ls tablet iter", K(ret), K(ls_)); } else { @@ -259,7 +260,7 @@ int ObLSDDLLogHandler::flush(SCN &rec_scn) SCN ObLSDDLLogHandler::get_rec_scn() { int ret = OB_SUCCESS; - ObLSTabletIterator tablet_iter(ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US); + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); SCN rec_scn = SCN::max_scn(); bool has_ddl_kv = false; if (OB_FAIL(ls_->get_tablet_svr()->build_tablet_iter(tablet_iter))) { @@ -333,16 +334,21 @@ int ObLSDDLLogHandler::replay_ddl_tablet_schema_version_change_log_(const char * { int ret = OB_SUCCESS; ObTabletSchemaVersionChangeLog log; - ObTabletHandle tablet_handle; + ObSchemaChangeReplayExecutor replay_executor; + if (OB_FAIL(log.deserialize(log_buf, buf_size, pos))) { LOG_WARN("fail to deserialize source barrier log", K(ret)); - } else if (OB_FAIL(ls_->get_tablet(log.get_tablet_id(), tablet_handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { - if (OB_TABLET_NOT_EXIST != ret) { - LOG_WARN("fail to get tablet", K(ret), "tablet_id", log.get_tablet_id()); + } else if (OB_FAIL(replay_executor.init(log, log_scn))) { + LOG_WARN("failed to init tablet schema version change log replay executor", K(ret)); + } else if (OB_FAIL(replay_executor.execute(log_scn, ls_->get_ls_id(), log.get_tablet_id()))) { + if (OB_NO_NEED_UPDATE == ret) { + LOG_WARN("no need replay tablet schema version change log", K(ret), K(log), K(log_scn)); + ret = OB_SUCCESS; + } else if (OB_EAGAIN != ret) { + LOG_WARN("failed to replay", K(ret), K(log), K(log_scn)); } - } else if (OB_FAIL(tablet_handle.get_obj()->replay_schema_version_change_log(log.get_schema_version()))) { - LOG_WARN("fail to replay schema version change log", K(ret), K(log)); } + return ret; } diff --git a/src/storage/ls/ob_ls_get_mod.h b/src/storage/ls/ob_ls_get_mod.h old mode 100644 new mode 100755 index 2577ff431..c488a6ee8 --- a/src/storage/ls/ob_ls_get_mod.h +++ b/src/storage/ls/ob_ls_get_mod.h @@ -40,7 +40,8 @@ enum class ObLSGetMod : int DATA_DICT_MOD = 17, DATA_MEMTABLE_MOD = 18, MULTI_VERSION_GARBAGE_COLLOECTOR_MOD = 19, - TOTAL_MAX_MOD = 20, + MDS_TABLE_MOD = 20, + TOTAL_MAX_MOD = 21, }; } diff --git a/src/storage/ls/ob_ls_member_table.cpp b/src/storage/ls/ob_ls_member_table.cpp deleted file mode 100644 index ed96e3463..000000000 --- a/src/storage/ls/ob_ls_member_table.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/** - * Copyright (c) 2021 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. - */ - -#define USING_LOG_PREFIX STORAGE -#include "storage/ls/ob_ls.h" -#include "share/ob_ls_id.h" -#include "storage/ls/ob_ls_member_table.h" -#include "share/schema/ob_table_schema.h" -#include "storage/meta_mem/ob_tablet_handle.h" -#include "storage/tx_storage/ob_access_service.h" -#include "storage/tx_storage/ob_ls_service.h" - -namespace oceanbase -{ -namespace storage -{ -using namespace common; -using namespace storage; -using namespace transaction; -using namespace memtable; -using namespace share; -using namespace share::schema; - -int ObLSMemberTable::handle_create_tablet_notify(const NotifyType type, - const char *buf, - const int64_t len, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - obrpc::ObBatchCreateTabletArg create_arg; - int64_t new_pos = 0; - - TRANS_LOG(INFO, "do_handle_create_tablet_notify ", K(type), K(len), K(trans_flags)); - - if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), KP(buf), K(len)); - } else if (OB_FAIL(create_arg.deserialize(buf, len, new_pos))) { - TRANS_LOG(WARN, "deserialize failed for ls_member trans", - KR(ret), K(type), K(trans_flags.for_replay_)); - } else { - switch (type) { - case NotifyType::REGISTER_SUCC: { - ret = prepare_create_tablets(create_arg, trans_flags); - break; - } - case NotifyType::ON_REDO: { - ret = on_redo_create_tablets(create_arg, trans_flags); - break; - } - case NotifyType::ON_COMMIT: - case NotifyType::ON_ABORT: { - bool commit = (type == NotifyType::ON_COMMIT) ? true: false; - ret = on_commit_create_tablets(&create_arg, trans_flags, commit); - break; - } - case NotifyType::TX_END: { - ret = on_tx_end_create_tablets(create_arg, trans_flags); - break; - } - default: { - break; - } - } - - if (OB_FAIL(ret)) { - LOG_WARN("failed to create tablet", KR(ret), K(type), K(create_arg)); - } - } - return ret; -} - -int ObLSMemberTable::prepare_create_tablets(const obrpc::ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - LOG_INFO("prepare_create_tablets ", K(arg), K(trans_flags)); - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - ObLS *ls = NULL; - ObLSTabletService *tablet_svr; - ObLSService* ls_srv = nullptr; - if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("MTL(ObLSService*) fail, MTL not init?", KR(ret)); - } else if (OB_FAIL(ls_srv->get_ls(arg.id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { - LOG_WARN("ls_srv->get_ls() fail", KR(ret)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); - } else if (trans_flags.for_replay_ - && trans_flags.scn_ <= ls->get_tablet_change_checkpoint_scn()) { - LOG_INFO("replay skip for create tablet", KR(ret), K(trans_flags), K(arg), K(ls->get_ls_meta())); - } else if (OB_ISNULL(tablet_svr = ls->get_tablet_svr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet_svr is NULL", KR(ret), K(ls)); - } else if (OB_FAIL(tablet_svr->on_prepare_create_tablets(arg, trans_flags))) { - LOG_WARN("fail to create tablet", KR(ret), K(arg), K(trans_flags)); - } - if (OB_FAIL(ret)) { - LOG_WARN("ls_member redo create failed, which is not allowed", - KR(ret), K(arg), K(trans_flags), K(arg.id_)); - } - return ret; -} - -int ObLSMemberTable::on_redo_create_tablets(const obrpc::ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - LOG_INFO("on_redo_create_tablets ", K(arg), K(trans_flags)); - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - ObLS *ls = NULL; - ObLSTabletService *tablet_svr; - ObLSService* ls_srv = nullptr; - if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("MTL(ObLSService*) fail, MTL not init?", KR(ret)); - } else if (OB_FAIL(ls_srv->get_ls(arg.id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { - LOG_ERROR("ls_srv->get_ls() fail", KR(ret)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); - } else if (trans_flags.for_replay_ ) { - LOG_INFO("replay skip for create tablet", KR(ret), K(trans_flags), K(arg), K(ls->get_ls_meta())); - } else if (OB_ISNULL(tablet_svr = ls->get_tablet_svr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet_svr is NULL", KR(ret), K(ls)); - } else if (OB_FAIL(tablet_svr->on_redo_create_tablets(arg, trans_flags))) { - LOG_WARN("fail to on_redo_create_tablets", KR(ret), K(arg), K(trans_flags)); - } - if (OB_FAIL(ret)) { - LOG_WARN("ls_member redo create failed, which is not allowed", - KR(ret), K(arg), K(trans_flags), K(arg.id_)); - } - return ret; -} - -int ObLSMemberTable::on_commit_create_tablets(const obrpc::ObBatchCreateTabletArg *arg, - const ObMulSourceDataNotifyArg &trans_flags, - bool commit) -{ - LOG_INFO("on_commit_create_tablets ", KPC(arg), K(trans_flags), - K(commit)); - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - ObLS *ls = NULL; - ObLSTabletService *tablet_svr; - ObLSService* ls_srv = nullptr; - if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("MTL(ObLSService*) fail, MTL not init?", KR(ret)); - } else if (OB_FAIL(ls_srv->get_ls(arg->id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { - LOG_ERROR("ls_srv->get_ls() fail", KR(ret)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); - } else if (trans_flags.for_replay_ - && trans_flags.scn_ <= ls->get_tablet_change_checkpoint_scn()) { - LOG_INFO("replay skip for create tablet", KR(ret), K(trans_flags), K(arg), K(ls->get_ls_meta())); - } else if (OB_ISNULL(tablet_svr = ls->get_tablet_svr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet_svr is NULL", KR(ret), K(ls)); - } else if (commit) { - if (OB_FAIL(tablet_svr->on_commit_create_tablets(*arg, trans_flags))) { - LOG_WARN("fail to on_commit_create_tablets", KR(ret), KPC(arg), K(trans_flags)); - } else { - ls->get_tablet_gc_handler()->set_tablet_persist_trigger(); - } - } else if (!commit) { - if (OB_FAIL(tablet_svr->on_abort_create_tablets(*arg, trans_flags))) { - LOG_WARN("fail to on_abort_create_tablets", KR(ret), KPC(arg), K(trans_flags)); - } else { - ls->get_tablet_gc_handler()->set_tablet_gc_trigger(); - } - } - if (OB_FAIL(ret)) { - LOG_WARN("ls_member commit create failed, which is not allowed", - KR(ret), KPC(arg), K(trans_flags)); - } - return ret; -} - -int ObLSMemberTable::on_tx_end_create_tablets(const obrpc::ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - LOG_INFO("tx_end_create_tablets ", K(arg), K(trans_flags)); - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - ObLS *ls = NULL; - ObLSTabletService *tablet_svr; - ObLSService* ls_srv = nullptr; - if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("MTL(ObLSService*) fail, MTL not init?", KR(ret)); - } else if (OB_FAIL(ls_srv->get_ls(arg.id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { - LOG_ERROR("ls_srv->get_ls() fail", KR(ret)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); - } else if (!trans_flags.is_redo_submitted()) { - LOG_INFO("replay skip for create tablet", KR(ret), K(trans_flags), K(arg), K(ls->get_ls_meta())); - } else if (OB_ISNULL(tablet_svr = ls->get_tablet_svr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet_svr is NULL", KR(ret), K(ls)); - } else if (OB_FAIL(tablet_svr->on_tx_end_create_tablets(arg, trans_flags))) { - LOG_WARN("fail to on_tx_end_create_tablets", KR(ret), K(arg), K(trans_flags)); - } - return ret; -} - -int ObLSMemberTable::handle_remove_tablet_notify(const NotifyType type, - const char *buf, - const int64_t len, - const ObMulSourceDataNotifyArg & trans_flags) -{ - int ret = OB_SUCCESS; - obrpc::ObBatchRemoveTabletArg remove_arg; - int64_t new_pos = 0; - - TRANS_LOG(INFO, "do_handle_remove_tablet_notify ", K(type), K(len), K(trans_flags)); - - if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), KP(buf), K(len)); - } else if (OB_FAIL(remove_arg.deserialize(buf, len, new_pos))) { - TRANS_LOG(WARN, "deserialize failed for ls_member trans", - KR(ret), K(type), K(trans_flags)); - } else { - switch (type) { - case NotifyType::REGISTER_SUCC: { - ret = prepare_remove_tablets(remove_arg, trans_flags); - break; - } - case NotifyType::ON_REDO: { - ret = on_redo_remove_tablets(remove_arg, trans_flags); - break; - } - case NotifyType::ON_COMMIT: - case NotifyType::ON_ABORT: { - bool commit = (type == NotifyType::ON_COMMIT) ? true: false; - ret = on_commit_remove_tablets(&remove_arg, trans_flags, commit); - break; - } - case NotifyType::TX_END: { - ret = on_tx_end_remove_tablets(remove_arg, trans_flags); - break; - } - default: { - break; - } - } - if (OB_FAIL(ret)) { - LOG_WARN("failed to remove tablet", KR(ret), K(type), K(remove_arg)); - } - } - return ret; -} - -int ObLSMemberTable::prepare_remove_tablets(const obrpc::ObBatchRemoveTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - LOG_INFO("prepare_remove_tablets ", K(arg), K(trans_flags)); - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - ObLS *ls = NULL; - ObLSTabletService *tablet_svr; - ObLSService* ls_srv = nullptr; - if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("MTL(ObLSService*) fail, MTL not init?", KR(ret)); - } else if (OB_FAIL(ls_srv->get_ls(arg.id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { - LOG_WARN("ls_srv->get_ls() fail", KR(ret)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); - } else if (trans_flags.for_replay_ // dropping tablet triggers dumpping memtable - && trans_flags.scn_ <= ls->get_tablet_change_checkpoint_scn()) { - LOG_INFO("replay skip for remove tablet", KR(ret), K(trans_flags), K(arg), K(ls->get_ls_meta())); - } else if (OB_ISNULL(tablet_svr = ls->get_tablet_svr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet_svr is NULL", KR(ret), K(ls)); - } else if (OB_FAIL(tablet_svr->on_prepare_remove_tablets(arg, trans_flags))) { - LOG_WARN("fail to remove tablet", KR(ret), K(arg), K(trans_flags)); - } - if (OB_FAIL(ret)) { - LOG_WARN("ls_member prepare remove failed, which is not allowed", - KR(ret), K(arg), K(trans_flags), K(arg.id_)); - } - return ret; -} - -int ObLSMemberTable::on_redo_remove_tablets(const obrpc::ObBatchRemoveTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - LOG_INFO("on_redo_remove_tablets ", K(arg), K(trans_flags)); - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - ObLS *ls = NULL; - ObLSTabletService *tablet_svr; - ObLSService* ls_srv = nullptr; - if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("MTL(ObLSService*) fail, MTL not init?", KR(ret)); - } else if (OB_FAIL(ls_srv->get_ls(arg.id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { - LOG_ERROR("ls_srv->get_ls() fail", KR(ret)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); - } else if (trans_flags.for_replay_) { - LOG_INFO("replay skip for remove tablet", KR(ret), K(trans_flags), K(arg), K(ls->get_ls_meta())); - } else if (OB_ISNULL(tablet_svr = ls->get_tablet_svr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet_svr is NULL", KR(ret), K(ls)); - } else if (OB_FAIL(tablet_svr->on_redo_remove_tablets(arg, trans_flags))) { - LOG_WARN("fail to on_redo_remove_tablets", KR(ret), K(arg), K(trans_flags)); - } - if (OB_FAIL(ret)) { - LOG_WARN("ls_member redo remove failed, which is not allowed", - KR(ret), K(arg), K(trans_flags), K(arg.id_)); - } - return ret; -} - -int ObLSMemberTable::on_commit_remove_tablets(const obrpc::ObBatchRemoveTabletArg *arg, - const ObMulSourceDataNotifyArg &trans_flags, - bool commit) -{ - LOG_INFO("on_commit_remove_tablets ", K(trans_flags), K(commit), KPC(arg)); - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - ObLS *ls = NULL; - ObLSTabletService *tablet_svr; - ObLSService* ls_srv = nullptr; - if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("MTL(ObLSService*) fail, MTL not init?", KR(ret)); - } else if (OB_FAIL(ls_srv->get_ls(arg->id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { - LOG_ERROR("ls_srv->get_ls() fail", KR(ret)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); - } else if (trans_flags.for_replay_ - && trans_flags.scn_ <= ls->get_tablet_change_checkpoint_scn()) { - LOG_INFO("replay skip for remove tablet", KR(ret), K(trans_flags), K(arg), K(ls->get_ls_meta())); - } else if (OB_ISNULL(tablet_svr = ls->get_tablet_svr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet_svr is NULL", KR(ret), K(ls)); - } else if (commit) { - if (OB_FAIL(tablet_svr->on_commit_remove_tablets(*arg, trans_flags))) { - LOG_WARN("fail to on_commit_remove_tablets", KR(ret), KPC(arg), K(trans_flags)); - } else { - ls->get_tablet_gc_handler()->set_tablet_gc_trigger(); - } - } else if (OB_FAIL(tablet_svr->on_abort_remove_tablets(*arg, trans_flags))) { - LOG_WARN("fail to on_abort_remove_tablets", KR(ret), KPC(arg), K(trans_flags)); - } - if (OB_FAIL(ret)) { - LOG_WARN("ls_member commit remove failed, which is not allowed", - KR(ret), KPC(arg), K(trans_flags)); - } - return ret; -} - -int ObLSMemberTable::on_tx_end_remove_tablets(const obrpc::ObBatchRemoveTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - LOG_INFO("tx_end_remove_tablets ", K(trans_flags), K(arg)); - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - ObLS *ls = NULL; - ObLSTabletService *tablet_svr; - ObLSService* ls_srv = nullptr; - if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("MTL(ObLSService*) fail, MTL not init?", KR(ret)); - } else if (OB_FAIL(ls_srv->get_ls(arg.id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { - LOG_ERROR("ls_srv->get_ls() fail", KR(ret)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); - } else if (!trans_flags.is_redo_submitted()) { - LOG_INFO("replay skip for remove tablet", KR(ret), K(trans_flags), K(arg), K(ls->get_ls_meta())); - } else if (OB_ISNULL(tablet_svr = ls->get_tablet_svr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet_svr is NULL", KR(ret), K(ls)); - } else if (OB_FAIL(tablet_svr->on_tx_end_remove_tablets(arg, trans_flags))) { - LOG_WARN("fail to on_tx_end_remove_tablets", KR(ret), K(arg), K(trans_flags)); - } - return ret; -} - -} // storage -} // oceanbase - diff --git a/src/storage/ls/ob_ls_member_table.h b/src/storage/ls/ob_ls_member_table.h deleted file mode 100644 index 2af5ae27b..000000000 --- a/src/storage/ls/ob_ls_member_table.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright (c) 2021 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_STORAGE_OB_LS_MEMBER_TABLE_H -#define OCEANBASE_STORAGE_OB_LS_MEMBER_TABLE_H - -#include "share/schema/ob_table_schema.h" -#include "storage/tx/ob_multi_data_source.h" -#include "share/ob_rpc_struct.h" - -namespace oceanbase -{ -namespace storage -{ -class ObLS; -class ObLSMemberMemtableMgr; -class ObLSMemberTransRequest; - -class ObLSMemberTable -{ -public: - static int handle_create_tablet_notify(const transaction::NotifyType type, - const char *buf, const int64_t len, - const transaction::ObMulSourceDataNotifyArg & trans_flags); - static int handle_remove_tablet_notify(const transaction::NotifyType type, - const char *buf, const int64_t len, - const transaction::ObMulSourceDataNotifyArg & trans_flags); -private: - // Below functions are for multi-source trans support - static int prepare_create_tablets(const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int on_redo_create_tablets(const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int on_commit_create_tablets(const obrpc::ObBatchCreateTabletArg *arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags, - bool commit); - static int on_tx_end_create_tablets(const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int prepare_remove_tablets(const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int on_redo_remove_tablets(const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int on_commit_remove_tablets(const obrpc::ObBatchRemoveTabletArg *arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags, - bool commit); - static int on_tx_end_remove_tablets(const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - -}; - -} // namespace storage -} // namespace oceanbase - -#endif /* !OCEANBASE_STORAGE_OB_LS_MEMBER_TABLE_H */ diff --git a/src/storage/ls/ob_ls_meta.cpp b/src/storage/ls/ob_ls_meta.cpp index 2d5530618..331e6924d 100644 --- a/src/storage/ls/ob_ls_meta.cpp +++ b/src/storage/ls/ob_ls_meta.cpp @@ -60,7 +60,9 @@ ObLSMeta::ObLSMeta() replayable_point_(), tablet_change_checkpoint_scn_(SCN::min_scn()), all_id_meta_(), - saved_info_() + saved_info_(), + transfer_scn_(SCN::min_scn()), + rebuild_info_() { } @@ -79,7 +81,9 @@ ObLSMeta::ObLSMeta(const ObLSMeta &ls_meta) restore_status_(ls_meta.restore_status_), replayable_point_(ls_meta.replayable_point_), tablet_change_checkpoint_scn_(ls_meta.tablet_change_checkpoint_scn_), - saved_info_(ls_meta.saved_info_) + saved_info_(ls_meta.saved_info_), + transfer_scn_(ls_meta.transfer_scn_), + rebuild_info_(ls_meta.rebuild_info_) { all_id_meta_.update_all_id_meta(ls_meta.all_id_meta_); } @@ -115,6 +119,8 @@ ObLSMeta &ObLSMeta::operator=(const ObLSMeta &other) tablet_change_checkpoint_scn_ = other.tablet_change_checkpoint_scn_; all_id_meta_.update_all_id_meta(other.all_id_meta_); saved_info_ = other.saved_info_; + transfer_scn_ = other.transfer_scn_; + rebuild_info_ = other.rebuild_info_; } return *this; } @@ -135,6 +141,8 @@ void ObLSMeta::reset() replayable_point_.reset(); tablet_change_checkpoint_scn_ = SCN::min_scn(); saved_info_.reset(); + transfer_scn_ = SCN::min_scn(); + rebuild_info_.reset(); } LSN &ObLSMeta::get_clog_base_lsn() @@ -198,6 +206,8 @@ int ObLSMeta::set_tablet_change_checkpoint_scn(const SCN &tablet_change_checkpoi if (OB_FAIL(write_slog_(tmp))) { LOG_WARN("clog_checkpoint write slog failed", K(ret)); } else { + LOG_INFO("update tablet change checkpoint scn", K(tenant_id_), K(ls_id_), + "old_scn", tablet_change_checkpoint_scn_, "new_scn", tablet_change_checkpoint_scn); tablet_change_checkpoint_scn_ = tablet_change_checkpoint_scn; } } @@ -205,6 +215,33 @@ int ObLSMeta::set_tablet_change_checkpoint_scn(const SCN &tablet_change_checkpoi return ret; } +share::SCN ObLSMeta::get_transfer_scn() const +{ + ObSpinLockTimeGuard guard(lock_); + return transfer_scn_; +} + +int ObLSMeta::inc_update_transfer_scn(const share::SCN &transfer_scn) +{ + ObSpinLockTimeGuard guard(lock_); + int ret = OB_SUCCESS; + if (OB_FAIL(check_can_update_())) { + LOG_WARN("ls meta cannot update", K(ret), K(*this)); + } else if (transfer_scn_ > transfer_scn) { + LOG_INFO("transfer scn is small", K_(tenant_id), K_(ls_id), K(transfer_scn), K_(transfer_scn)); + } else { + ObLSMeta tmp(*this); + tmp.transfer_scn_ = transfer_scn; + + if (OB_FAIL(write_slog_(tmp))) { + LOG_WARN("clog_checkpoint write slog failed", K(ret), K(*this)); + } else { + transfer_scn_ = transfer_scn; + } + } + return ret; +} + bool ObLSMeta::is_valid() const { return is_valid_id(tenant_id_) @@ -424,15 +461,17 @@ int ObLSMeta::update_ls_meta( tmp.clog_checkpoint_scn_ = src_ls_meta.clog_checkpoint_scn_; tmp.replayable_point_ = src_ls_meta.replayable_point_; tmp.tablet_change_checkpoint_scn_ = src_ls_meta.tablet_change_checkpoint_scn_; + tmp.transfer_scn_ = src_ls_meta.transfer_scn_; tmp.rebuild_seq_++; if (update_restore_status) { tmp.restore_status_ = ls_restore_status; } tmp.gc_state_ = src_ls_meta.gc_state_; + tmp.offline_scn_ = src_ls_meta.offline_scn_; guard.click(); tmp.all_id_meta_.update_all_id_meta(src_ls_meta.all_id_meta_); if (tmp.clog_checkpoint_scn_ < clog_checkpoint_scn_) { - // TODO: now do not allow clog checkpoint ts rollback, may support it in 4.1 + // TODO: now do not allow clog checkpoint ts rollback, may support it in 4.3 ret = OB_ERR_UNEXPECTED; LOG_WARN("do not allow clog checkpoint ts rollback", K(ret), K(src_ls_meta), KPC(this)); } else if (OB_FAIL(write_slog_(tmp))) { @@ -446,6 +485,8 @@ int ObLSMeta::update_ls_meta( all_id_meta_.update_all_id_meta(src_ls_meta.all_id_meta_); rebuild_seq_ = tmp.rebuild_seq_; gc_state_ = tmp.gc_state_; + offline_scn_ = src_ls_meta.offline_scn_; + transfer_scn_ = src_ls_meta.transfer_scn_; if (update_restore_status) { restore_status_ = ls_restore_status; } @@ -464,6 +505,8 @@ int ObLSMeta::set_ls_rebuild() ObSpinLockTimeGuard guard(lock_); if (OB_FAIL(check_can_update_())) { LOG_WARN("ls meta cannot update", K(ret), K(*this)); + } else if (change_status == migration_status_) { + //do nothing } else { ObLSMeta tmp(*this); if (OB_FAIL(ObMigrationStatusHelper::check_can_change_status(tmp.migration_status_, change_status, can_change))) { @@ -607,6 +650,7 @@ int ObLSMeta::init( migration_status_ = migration_status; gc_state_ = LSGCState::NORMAL; restore_status_ = restore_status; + transfer_scn_ = SCN::min_scn(); } return ret; } @@ -684,6 +728,43 @@ int ObLSMeta::get_migration_and_restore_status( return ret; } +int ObLSMeta::set_rebuild_info(const ObLSRebuildInfo &rebuild_info) +{ + int ret = OB_SUCCESS; + ObSpinLockTimeGuard guard(lock_); + if (OB_FAIL(check_can_update_())) { + LOG_WARN("ls meta cannot update", K(ret), K(*this)); + } else if (!rebuild_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid rebuild info", K(ret), K(rebuild_info_), K(rebuild_info)); + } else if (rebuild_info_ == rebuild_info) { + //do nothing + } else { + ObLSMeta tmp(*this); + tmp.rebuild_info_ = rebuild_info; + if (OB_FAIL(write_slog_(tmp))) { + LOG_WARN("rebuild_info write slog failed", K(ret)); + } else { + rebuild_info_ = rebuild_info; + } + } + return ret; +} + +int ObLSMeta::get_rebuild_info(ObLSRebuildInfo &rebuild_info) const +{ + int ret = OB_SUCCESS; + ObSpinLockTimeGuard guard(lock_); + if (!is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls meta is not valid, cannot get rebuild info", K(ret), K(*this)); + } else { + rebuild_info = rebuild_info_; + } + return ret; +} + + ObLSMeta::ObSpinLockTimeGuard::ObSpinLockTimeGuard(common::ObSpinLock &lock, const int64_t warn_threshold) : time_guard_("ls_meta", warn_threshold), @@ -692,6 +773,7 @@ ObLSMeta::ObSpinLockTimeGuard::ObSpinLockTimeGuard(common::ObSpinLock &lock, time_guard_.click("after lock"); } +// add field should also consider ObLSMeta::update_ls_meta function OB_SERIALIZE_MEMBER(ObLSMeta, tenant_id_, ls_id_, @@ -707,7 +789,9 @@ OB_SERIALIZE_MEMBER(ObLSMeta, replayable_point_, tablet_change_checkpoint_scn_, all_id_meta_, - saved_info_); + saved_info_, + transfer_scn_, + rebuild_info_); } } diff --git a/src/storage/ls/ob_ls_meta.h b/src/storage/ls/ob_ls_meta.h index ce56fd5e8..7a50508f7 100644 --- a/src/storage/ls/ob_ls_meta.h +++ b/src/storage/ls/ob_ls_meta.h @@ -79,6 +79,8 @@ public: int check_valid_for_backup() const; share::SCN get_tablet_change_checkpoint_scn() const; int set_tablet_change_checkpoint_scn(const share::SCN &tablet_change_checkpoint_scn); + share::SCN get_transfer_scn() const; + int inc_update_transfer_scn(const share::SCN &transfer_scn); int update_id_meta(const int64_t service_type, const int64_t limited_id, const share::SCN &latest_scn, @@ -91,6 +93,8 @@ public: int get_migration_and_restore_status( ObMigrationStatus &migration_status, share::ObLSRestoreStatus &ls_restore_status); + int set_rebuild_info(const ObLSRebuildInfo &rebuild_info); + int get_rebuild_info(ObLSRebuildInfo &rebuild_info) const; int init( const uint64_t tenant_id, @@ -116,7 +120,7 @@ public: K_(clog_checkpoint_scn), K_(clog_base_lsn), K_(rebuild_seq), K_(migration_status), K(gc_state_), K(offline_scn_), K_(restore_status), K_(replayable_point), K_(tablet_change_checkpoint_scn), - K_(all_id_meta)); + K_(all_id_meta), K_(transfer_scn), K_(rebuild_info)); private: int check_can_update_(); public: @@ -150,6 +154,8 @@ private: share::SCN tablet_change_checkpoint_scn_; transaction::ObAllIDMeta all_id_meta_; ObLSSavedInfo saved_info_; + share::SCN transfer_scn_; + ObLSRebuildInfo rebuild_info_; }; } // namespace storage diff --git a/src/storage/ls/ob_ls_meta_package.cpp b/src/storage/ls/ob_ls_meta_package.cpp index e15f0b326..e772f9dab 100644 --- a/src/storage/ls/ob_ls_meta_package.cpp +++ b/src/storage/ls/ob_ls_meta_package.cpp @@ -29,14 +29,17 @@ ObLSMetaPackage::ObLSMetaPackage() } ObLSMetaPackage::ObLSMetaPackage(const ObLSMetaPackage &other) - : ls_meta_(other.ls_meta_), - palf_meta_(other.palf_meta_) + : ls_meta_(other.ls_meta_), palf_meta_(other.palf_meta_) { int ret = OB_SUCCESS; if (OB_FAIL(dup_ls_meta_.copy(other.dup_ls_meta_))) { ret = OB_ERR_UNEXPECTED; DUP_TABLE_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "copy dup ls meta failed", K(dup_ls_meta_), K(other.dup_ls_meta_)) + } else if (!dup_ls_meta_.is_valid()) { + dup_ls_meta_.ls_id_ = ls_meta_.ls_id_; + DUP_TABLE_LOG_RET(INFO, OB_SUCCESS, "copy a old version dup ls meta without ls_id_", KPC(this), + K(other.dup_ls_meta_)) } } @@ -50,6 +53,10 @@ ObLSMetaPackage &ObLSMetaPackage::operator=(const ObLSMetaPackage &other) ret = OB_ERR_UNEXPECTED; DUP_TABLE_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "copy dup ls meta failed", K(dup_ls_meta_), K(other.dup_ls_meta_)) + } else if (!dup_ls_meta_.is_valid()) { + dup_ls_meta_.ls_id_ = ls_meta_.ls_id_; + DUP_TABLE_LOG_RET(INFO, OB_SUCCESS, "copy a old version dup ls meta without ls_id_", + KPC(this), K(other.dup_ls_meta_)) } } return *this; diff --git a/src/storage/ls/ob_ls_storage_clog_handler.cpp b/src/storage/ls/ob_ls_storage_clog_handler.cpp index 17937c594..3d3549c4f 100644 --- a/src/storage/ls/ob_ls_storage_clog_handler.cpp +++ b/src/storage/ls/ob_ls_storage_clog_handler.cpp @@ -113,8 +113,8 @@ int ObMediumCompactionClogHandler::inner_replay( } else if (OB_FAIL(tablet_id.deserialize(buffer, buffer_size, new_pos))) { LOG_WARN("fail to deserialize tablet id", K(ret), K(buffer_size), K(pos), K(tablet_id)); } else if (OB_FAIL(ls_->replay_get_tablet(tablet_id, scn, handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - LOG_INFO("tablet not exist", K(ret), K(tablet_id)); + if (OB_OBSOLETE_CLOG_NEED_SKIP == ret) { + LOG_INFO("clog is obsolete, should skip replay", K(ret), K(tablet_id)); ret = OB_SUCCESS; } else { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); diff --git a/src/storage/ls/ob_ls_sync_tablet_seq_handler.cpp b/src/storage/ls/ob_ls_sync_tablet_seq_handler.cpp index 4349e5fc9..96060f2b9 100644 --- a/src/storage/ls/ob_ls_sync_tablet_seq_handler.cpp +++ b/src/storage/ls/ob_ls_sync_tablet_seq_handler.cpp @@ -14,6 +14,7 @@ #include "storage/ls/ob_ls_sync_tablet_seq_handler.h" #include "storage/ls/ob_ls.h" #include "storage/ob_sync_tablet_seq_clog.h" +#include "storage/ob_tablet_autoinc_seq_rpc_handler.h" #include "logservice/ob_log_base_header.h" #include "share/scn.h" #include "lib/oblog/ob_log_module.h" @@ -21,8 +22,10 @@ namespace oceanbase { + using namespace palf; using namespace share; + namespace storage { diff --git a/src/storage/ls/ob_ls_sync_tablet_seq_handler.h b/src/storage/ls/ob_ls_sync_tablet_seq_handler.h index aee26f1c7..9bebe62d3 100644 --- a/src/storage/ls/ob_ls_sync_tablet_seq_handler.h +++ b/src/storage/ls/ob_ls_sync_tablet_seq_handler.h @@ -13,14 +13,13 @@ #ifndef OCEANBASE_STORAGE_LS_SYNC_TABLET_SEQ_HANDLER_ #define OCEANBASE_STORAGE_LS_SYNC_TABLET_SEQ_HANDLER_ +#include "common/ob_tablet_id.h" +#include "share/scn.h" #include "logservice/ob_log_base_type.h" namespace oceanbase { -namespace share -{ -class SCN; -} + namespace storage { class ObLS; diff --git a/src/storage/ls/ob_ls_tablet_service.cpp b/src/storage/ls/ob_ls_tablet_service.cpp old mode 100644 new mode 100755 index 875181193..884c1bca2 --- a/src/storage/ls/ob_ls_tablet_service.cpp +++ b/src/storage/ls/ob_ls_tablet_service.cpp @@ -24,7 +24,6 @@ #include "share/scn.h" #include "observer/report/ob_i_meta_report.h" #include "share/ob_disk_usage_table_operator.h" -#include "share/ob_rpc_struct.h" #include "share/rc/ob_tenant_base.h" #include "share/schema/ob_table_param.h" #include "share/schema/ob_table_dml_param.h" @@ -54,9 +53,11 @@ #include "storage/tablet/ob_tablet_binding_helper.h" #include "storage/tablet/ob_tablet_create_delete_helper.h" #include "storage/tablet/ob_tablet_create_sstable_param.h" +#include "storage/tablet/ob_tablet_persister.h" #include "storage/tablet/ob_tablet_service_clog_replay_executor.h" #include "storage/tablet/ob_tablet_status.h" #include "storage/tablet/ob_tablet_slog_helper.h" +#include "storage/tablet/ob_tablet_persister.h" #include "storage/tx/ob_trans_define.h" #include "storage/tx/ob_trans_part_ctx.h" #include "storage/tx_storage/ob_ls_service.h" @@ -71,9 +72,11 @@ #include "observer/table_load/ob_table_load_service.h" #include "observer/table_load/ob_table_load_store.h" #include "observer/ob_server_event_history_table_operator.h" +#include "storage/high_availability/ob_storage_ha_utils.h" using namespace oceanbase::share; using namespace oceanbase::common; +using namespace oceanbase::transaction; using namespace oceanbase::blocksstable; using namespace oceanbase::observer; @@ -81,11 +84,14 @@ namespace oceanbase { namespace storage { +using namespace mds; + ObLSTabletService::ObLSTabletService() : ls_(nullptr), tx_data_memtable_mgr_(), tx_ctx_memtable_mgr_(), lock_memtable_mgr_(), + mds_table_mgr_(), tablet_id_set_(), bucket_lock_(), rs_reporter_(nullptr), @@ -117,6 +123,8 @@ int ObLSTabletService::init( LOG_WARN("failed to init bucket lock", K(ret)); } else if (OB_FAIL(set_allow_to_read_(ls))) { LOG_WARN("failed to set allow to read", K(ret)); + } else if (OB_FAIL(mds_table_mgr_.init(ls))) { + LOG_WARN("fail to init mds table mgr", KR(ret)); } else { ls_ = ls; rs_reporter_ = rs_reporter; @@ -138,6 +146,7 @@ void ObLSTabletService::destroy() tx_data_memtable_mgr_.destroy(); tx_ctx_memtable_mgr_.destroy(); lock_memtable_mgr_.destroy(); + mds_table_mgr_.destroy(); bucket_lock_.destroy(); rs_reporter_ = nullptr; ls_= nullptr; @@ -164,7 +173,7 @@ int ObLSTabletService::offline() ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); } else { - DestroyMemtableAndMemberOperator clean_mem_op(this); + DestroyMemtableAndMemberAndMdsTableOperator clean_mem_op(this); if (OB_FAIL(tablet_id_set_.foreach(clean_mem_op))) { LOG_WARN("fail to clean memtables", K(ret), K(clean_mem_op.cur_tablet_id_)); } @@ -185,14 +194,29 @@ int ObLSTabletService::replay( { int ret = OB_SUCCESS; int64_t pos = 0; + logservice::ObLogBaseHeader base_header; + common::ObTabletID tablet_id; const char *log_buf = static_cast(buffer); - + ObTabletServiceClogReplayExecutor replayer_executor; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(ObTabletServiceClogReplayExecutor::execute(ls_, log_buf, nbytes, - pos, lsn, scn))) { - LOG_WARN("replay tablet log error", K(ret), K(lsn), K(scn)); + } else if (OB_FAIL(base_header.deserialize(log_buf, nbytes, pos))) { + LOG_WARN("log base header deserialize error", K(ret)); + } else if (logservice::ObLogBaseType::STORAGE_SCHEMA_LOG_BASE_TYPE != base_header.get_log_type()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("log type not supported", K(ret), "log_type", base_header.get_log_type()); + } else if (OB_FAIL(tablet_id.deserialize(log_buf, nbytes, pos))) { + LOG_WARN("fail to deserialize tablet id", K(ret), KP(log_buf), K(nbytes), K(pos)); + } else if (OB_FAIL(replayer_executor.init(log_buf, nbytes, pos, scn))) { + LOG_WARN("failed to init replayer", K(ret), KP(log_buf), K(nbytes), K(pos), K(lsn), K(scn)); + } else if (OB_FAIL(replayer_executor.execute(scn, ls_->get_ls_id(), tablet_id))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; // TODO (bowen.gbw): unify multi data replay logic + LOG_INFO("tablet does not exist, skip", K(ret), K(replayer_executor)); + } else { + LOG_WARN("failed to replay", K(ret), K(replayer_executor)); + } } return ret; @@ -257,8 +281,8 @@ int ObLSTabletService::safe_to_destroy(bool &is_safe) int ret = OB_SUCCESS; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); bool all_table_released = false; + bool all_tablet_released = false; is_safe = true; - if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); @@ -266,17 +290,27 @@ int ObLSTabletService::safe_to_destroy(bool &is_safe) int64_t tx_data_memtable_mgr_ref = tx_data_memtable_mgr_.get_ref(); int64_t tx_ctx_memtable_mgr_ref = tx_ctx_memtable_mgr_.get_ref(); int64_t lock_memtable_mgr_ref = lock_memtable_mgr_.get_ref(); + int64_t mds_table_mgr_ref = mds_table_mgr_.get_ref(); if (0 != tx_data_memtable_mgr_ref || 0 != tx_ctx_memtable_mgr_ref - || 0 != lock_memtable_mgr_ref) { + || 0 != lock_memtable_mgr_ref || 0 != mds_table_mgr_ref) { if (REACH_TIME_INTERVAL(60L * 1000000)) { // 60s - LOG_INFO("inner tablet memtable mgr can't destroy", K(tx_data_memtable_mgr_ref), - K(tx_ctx_memtable_mgr_ref), K(lock_memtable_mgr_ref)); + LOG_WARN("inner tablet memtable mgr can't destroy", K(tx_data_memtable_mgr_ref), + K(tx_ctx_memtable_mgr_ref), K(lock_memtable_mgr_ref), K(mds_table_mgr_ref)); } is_safe = false; } else { tx_data_memtable_mgr_.destroy(); tx_ctx_memtable_mgr_.destroy(); lock_memtable_mgr_.destroy(); + mds_table_mgr_.destroy(); + } + if (is_safe) { + if (OB_FAIL(t3m->gc_tablets_in_queue(all_tablet_released))) { + LOG_WARN("failed to check all tablet released", K(ret)); + is_safe = false; + } else { + is_safe = all_tablet_released; + } } if (is_safe) { if (OB_FAIL(t3m->gc_tables_in_queue(all_table_released))) { @@ -291,182 +325,6 @@ int ObLSTabletService::safe_to_destroy(bool &is_safe) return ret; } -int ObLSTabletService::batch_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const SCN &create_scn, - const bool is_replay_clog) -{ - ALLOW_NEXT_LOG(); - LOG_INFO("batch create tablet", K(arg), K(is_replay_clog)); - int ret = OB_SUCCESS; - ObTimeGuard time_guard("CreateTablets", 3000000/*3 seconds*/); - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!arg.is_valid()) - || OB_UNLIKELY(!create_scn.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(arg), K(create_scn)); - } else if (OB_UNLIKELY(arg.id_ != ls_->get_ls_id())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls id does not equal", K(ret), - "arg ls id", arg.id_, - "ls id", ls_->get_ls_id()); - } else { - NonLockedHashSet data_tablet_id_set; - NonLockedHashSet existed_tablet_id_set; - - if (OB_FAIL(data_tablet_id_set.create(arg.tablets_.count()))) { - LOG_WARN("failed to init data tablet id set", K(ret), K(arg)); - } else if (OB_FAIL(existed_tablet_id_set.create(arg.get_tablet_count()))) { - LOG_WARN("failed to init existed tablet id set", K(ret), K(arg)); - } else if (OB_FAIL(verify_tablets(arg, existed_tablet_id_set))) { - LOG_WARN("failed to verify tablets", K(ret), K(arg)); - } else if (!is_replay_clog && existed_tablet_id_set.size() > 0) { - // NOT in clog replay procedure, existed tablet id is NOT allowed - ret = OB_TABLET_EXIST; - LOG_WARN("tablet already exists", K(ret), K(arg), K(existed_tablet_id_set)); - } else if (is_replay_clog && existed_tablet_id_set.size() > 0) { - time_guard.click("Verify"); - // in clog replay procedure and tablet id exists - // we should build new arg to do batch create tablets - obrpc::ObBatchCreateTabletArg new_arg; - if (OB_FAIL(build_batch_create_tablet_arg(arg, existed_tablet_id_set, new_arg))) { - LOG_WARN("failed to build new batch create tablet arg", K(ret), - K(arg), K(existed_tablet_id_set)); - } else if (new_arg.get_tablet_count() == 0) { - // all tablet ids exist, no need to create, do nothing - } else if (OB_UNLIKELY(!new_arg.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("new arg is invalid", K(ret), K(new_arg)); - } else if (FALSE_IT(time_guard.click("BuildArg"))) { - } else if (OB_FAIL(do_batch_create_tablets(new_arg, create_scn, is_replay_clog, time_guard, data_tablet_id_set))) { - LOG_WARN("failed to do batch create tablets", K(ret), K(create_scn), K(new_arg), K(is_replay_clog)); - } - } else { - if (OB_FAIL(do_batch_create_tablets(arg, create_scn, is_replay_clog, time_guard, data_tablet_id_set))) { - LOG_WARN("failed to do batch create tablets", K(ret), K(arg), K(create_scn), K(is_replay_clog)); - } - } - } - - return ret; -} - -int ObLSTabletService::do_batch_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const SCN &create_scn, - const bool is_replay_clog, - common::ObTimeGuard &time_guard, - NonLockedHashSet &data_tablet_id_set) -{ - UNUSED(is_replay_clog); - int ret = OB_SUCCESS; - const share::ObLSID &ls_id = arg.id_; - ObSArray tablet_handles; - - if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(arg)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const obrpc::ObCreateTabletInfo &info = arg.tablets_[i]; - if (OB_FAIL(create_tablet(ls_id, arg, create_scn, info, tablet_handles, data_tablet_id_set))) { - LOG_WARN("failed to create tablet", K(ret), K(create_scn), K(info), K(i)); - } - } - time_guard.click("CreTablet"); - - if (OB_FAIL(ret)) { - } else { - // bucket lock, protect write slog and concurrent tablet CAS operation - ObSArray all_tablet_id_hash_array; - ObMultiBucketLockGuard lock_guard(bucket_lock_, true/*is_write_lock*/); - if (OB_FAIL(get_all_tablet_id_hash_array(arg, all_tablet_id_hash_array))) { - LOG_WARN("failed to get all tablet id array", K(ret), K(arg)); - } else if (OB_FAIL(lock_guard.lock_multi_buckets(all_tablet_id_hash_array))) { - LOG_WARN("failed to lock multi buckets", K(ret)); - } - time_guard.click("Lock"); - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(add_batch_tablets(ls_id, data_tablet_id_set, tablet_handles))) { - LOG_ERROR("fatal error, failed to add batch tablets", K(ret), K(tablet_handles), K(lbt())); - ob_usleep(1000 * 1000); - ob_abort(); - } - time_guard.click("WrSlog"); - } - - if (OB_FAIL(ret)) { - // remove tablets just created - int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(post_handle_batch_create_tablets(arg))) { - LOG_ERROR("fatal error, failed to remove redundant tablets", K(tmp_ret), K(arg), K(lbt())); - ob_usleep(1000 * 1000); - ob_abort(); // remove redundant tablets should never fail - } - } - } - - return ret; -} - -int ObLSTabletService::batch_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const bool is_replay_clog) -{ - LOG_INFO("batch remove tablet", K(arg), K(is_replay_clog)); - int ret = OB_SUCCESS; - const uint64_t tenant_id = MTL_ID(); - ObStorageLogger *slogger = MTL(ObStorageLogger*); - ObSArray all_tablet_id_hash_array; - common::ObLinearHashMap delete_tablet_infos; - ObTimeGuard time_guard("RemoveTablets", 3000000/*3 seconds*/); - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(arg)); - } else if (OB_UNLIKELY(arg.id_ != ls_->get_ls_id())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("log stream id does not equal", K(ret), - "arg ls id", arg.id_, - "log stream id", ls_->get_ls_id()); - } else if (OB_FAIL(delete_tablet_infos.init("tablet info", tenant_id))) { - LOG_WARN("failed to init hash map", K(ret), K(tenant_id)); - } else if (OB_FAIL(parse_and_verify_delete_tablet_info(arg, delete_tablet_infos))) { - LOG_WARN("failed to parse and verify delete tablet info", K(ret), K(arg)); - } else if (OB_FAIL(get_all_tablet_id_hash_array(delete_tablet_infos, all_tablet_id_hash_array))) { - LOG_WARN("failed to get all tablet id array", K(ret)); - } else { - time_guard.click("Prepare"); - HashMapTabletDeleteFunctor functor(ls_); - ObMultiBucketLockGuard lock_guard(bucket_lock_, true/*is_write_lock*/); - if (OB_UNLIKELY(all_tablet_id_hash_array.empty())) { - LOG_INFO("all tablets have been removed, do nothing", K(arg)); - } else if (OB_FAIL(lock_guard.lock_multi_buckets(all_tablet_id_hash_array))) { - LOG_WARN("failed to lock multi buckets", K(ret)); - } else if (FALSE_IT(time_guard.click("Lock"))) { - } else if (OB_FAIL(delete_tablet_infos.for_each(functor))) { - LOG_WARN("failed to iterate hash map", K(ret)); - } else if (FALSE_IT(time_guard.click("Collect"))) { - } else if (OB_FAIL(slogger->write_log(functor.get_slog_params()))) { - LOG_WARN("failed to write slog for remove tablets", K(ret), K(functor)); - } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(handle_remove_tablets(functor.get_slog_params(), delete_tablet_infos))) { - LOG_ERROR("failed to handle remove tablets", K(ret), K(functor), K(lbt())); - ob_usleep(1000 * 1000); - ob_abort(); - } else if (FALSE_IT(time_guard.click("Execute"))) { - } - } - return ret; -} - int ObLSTabletService::delete_all_tablets() { int ret = OB_SUCCESS; @@ -485,7 +343,7 @@ int ObLSTabletService::delete_all_tablets() } else { for (int64_t i = 0; OB_SUCC(ret) && i < tablet_id_array.count(); ++i) { const ObTabletID &tablet_id = tablet_id_array.at(i); - if (OB_FAIL(do_remove_tablet(ls_id, tablet_id))) { + if (OB_FAIL(inner_remove_tablet(ls_id, tablet_id))) { LOG_ERROR("failed to do remove tablet", K(ret), K(ls_id), K(tablet_id)); ob_usleep(1000 * 1000); ob_abort(); @@ -502,6 +360,50 @@ int ObLSTabletService::delete_all_tablets() return ret; } +int ObLSTabletService::remove_tablet(const ObTabletHandle& tablet_handle) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tablet", K(ret), K(tablet_handle)); + } else { + const ObTablet &target_tablet = *(tablet_handle.get_obj()); + const ObLSID ls_id = ls_->get_ls_id(); + const ObTabletID tablet_id = target_tablet.get_tablet_meta().tablet_id_; + const ObTabletMapKey key(ls_id, tablet_id); + ObTabletHandle cur_tablet_handle; + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + + if (OB_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, cur_tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("tablet does not exist, maybe already deleted", K(ret), K(key)); + } else { + LOG_WARN("failed to get tablet", K(ret), K(key)); + } + } else if (&target_tablet != cur_tablet_handle.get_obj()) { + ret = OB_EAGAIN; + LOG_INFO("tablet object has been changed, need retry", K(ret), K(key), K(target_tablet), KPC(cur_tablet_handle.get_obj())); + } else { + if (OB_FAIL(ObTabletSlogHelper::write_remove_tablet_slog(ls_id, tablet_id))) { + LOG_WARN("failed to write remove tablet slog", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->wait_release_memtables())) { + LOG_ERROR("failed to release memtables", K(ret), K(tablet_id)); + } else if (OB_FAIL(inner_remove_tablet(ls_id, tablet_id))) { + LOG_ERROR("failed to do remove tablet", K(ret), K(ls_id), K(tablet_id)); + ob_usleep(1000 * 1000); + ob_abort(); + } else { + report_tablet_to_rs(tablet_id); + } + } + } + return ret; +} + int ObLSTabletService::remove_tablets(const common::ObIArray &tablet_id_array) { int ret = OB_SUCCESS; @@ -559,7 +461,7 @@ int ObLSTabletService::remove_tablets(const common::ObIArray } else if (OB_FAIL(tablet_handle.get_obj()->get_meta_disk_addr(tablet_addr))) { LOG_WARN("failed to get tablet addr", K(ret), K(key)); } else if (!tablet_addr.is_disked()) { - if (OB_FAIL(do_remove_tablet(ls_id, tablet_id))) { + if (OB_FAIL(inner_remove_tablet(ls_id, tablet_id))) { LOG_WARN("failed to remove non disked tablet from memory", K(ret), K(key)); } else { FLOG_INFO("succeeded to remove non disked tablet from memory", K(ret), K(key)); @@ -579,7 +481,7 @@ int ObLSTabletService::remove_tablets(const common::ObIArray time_guard.click("WrSlog"); for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { const ObTabletID &tablet_id = tablet_ids.at(i); - if (OB_FAIL(do_remove_tablet(ls_id, tablet_id))) { + if (OB_FAIL(inner_remove_tablet(ls_id, tablet_id))) { LOG_ERROR("failed to do remove tablet", K(ret), K(ls_id), K(tablet_id)); ob_usleep(1000 * 1000); ob_abort(); @@ -597,8 +499,20 @@ int ObLSTabletService::remove_tablets(const common::ObIArray return ret; } +int ObLSTabletService::do_remove_tablet(const ObTabletMapKey &key) +{ + int ret = OB_SUCCESS; + ObTimeGuard time_guard("RmTabletLock", 1000000/*1 seconds*/); + ObBucketHashWLockGuard lock_guard(bucket_lock_, key.tablet_id_.hash()); + time_guard.click("Lock"); + if (OB_FAIL(inner_remove_tablet(key.ls_id_, key.tablet_id_))) { + LOG_WARN("fail to remove tablet with lock", K(ret), K(key)); + } + return ret; +} + // TODO(yunshan.tys) cope with failure of deleting tablet (tablet hasn't been loaded from disk) -int ObLSTabletService::do_remove_tablet( +int ObLSTabletService::inner_remove_tablet( const share::ObLSID &ls_id, const ObTabletID &tablet_id) { @@ -634,22 +548,25 @@ int ObLSTabletService::do_remove_tablet( int ObLSTabletService::get_tablet( const ObTabletID &tablet_id, ObTabletHandle &handle, - const int64_t timeout_us) + const int64_t timeout_us, + const ObMDSGetTabletMode mode) { int ret = OB_SUCCESS; + const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); } else if (OB_UNLIKELY(!tablet_id.is_valid() - || timeout_us < ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US)) { + || mode < ObMDSGetTabletMode::READ_ALL_COMMITED)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tablet_id), K(timeout_us)); - } else if (OB_FAIL(check_and_get_tablet(tablet_id, handle, timeout_us))) { + LOG_WARN("invalid args", K(ret), K(tablet_id), K(mode)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::check_and_get_tablet(key, handle, timeout_us, mode, + ObTransVersion::MAX_TRANS_VERSION))) { if (OB_TABLET_NOT_EXIST == ret) { - LOG_DEBUG("failed to check and get tablet", K(ret), K(tablet_id), K(timeout_us)); + LOG_DEBUG("failed to check and get tablet", K(ret), K(key), K(timeout_us), K(mode)); } else { - LOG_WARN("failed to check and get tablet", K(ret), K(tablet_id), K(timeout_us)); + LOG_WARN("failed to check and get tablet", K(ret), K(key), K(timeout_us), K(mode)); } } @@ -676,38 +593,6 @@ int ObLSTabletService::get_tablet_addr(const ObTabletMapKey &key, ObMetaDiskAddr return ret; } -int ObLSTabletService::replay_update_storage_schema( - const share::SCN &scn, - const char *buf, - const int64_t buf_size, - const int64_t pos) -{ - int ret = OB_SUCCESS; - ObTabletID tablet_id; - ObTabletHandle handle; - int64_t new_pos = pos; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (OB_UNLIKELY(buf_size <= pos || pos < 0 || buf_size <= 0)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(buf_size), K(pos)); - } else if (OB_FAIL(tablet_id.deserialize(buf, buf_size, new_pos))) { - LOG_WARN("fail to deserialize tablet id", K(ret), K(buf_size), K(pos), K(tablet_id)); - } else if (OB_FAIL(direct_get_tablet(tablet_id, handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - LOG_INFO("tablet not exist", K(ret), K(tablet_id)); - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); - } - } else if (OB_FAIL(handle.get_obj()->replay_update_storage_schema(scn, buf, buf_size, new_pos))) { - LOG_WARN("update tablet storage schema fail", K(ret), K(tablet_id), K(buf_size), K(new_pos)); - } - return ret; -} - int ObLSTabletService::replay_medium_compaction_clog( const share::SCN &scn, const char *buf, @@ -734,6 +619,8 @@ int ObLSTabletService::replay_medium_compaction_clog( } else { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); } + } else if (handle.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", handle.get_obj()); } else if (OB_FAIL(handle.get_obj()->replay_medium_compaction_clog(scn, buf, buf_size, new_pos))) { LOG_WARN("update tablet storage schema fail", K(ret), K(tablet_id), K(buf_size), K(new_pos)); } @@ -764,58 +651,18 @@ int ObLSTabletService::replay_update_reserved_snapshot( return ret; } -/** -int ObLSTabletService::report_update_tablet( - const ObTabletHandle *old_tablet_handle, - const ObTabletHandle *new_tablet_handle) +void ObLSTabletService::report_tablet_to_rs(const common::ObTabletID &tablet_id) { int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + const share::ObLSID &ls_id = ls_->get_ls_id(); - int64_t data_size_before = 0; - int64_t used_size_before = 0; - int64_t data_size_after = 0; - int64_t used_size_after = 0; - ObDiskReportFileType file_type; - - if (OB_UNLIKELY(nullptr == old_tablet_handle && nullptr == new_tablet_handle)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(old_tablet_handle), KP(new_tablet_handle)); - } else { - do { - if (nullptr != old_tablet_handle && old_tablet_handle->is_valid() && - OB_FAIL(old_tablet_handle->get_obj()->get_sstables_size(data_size_before, used_size_before))) { - if (OB_ALLOCATE_MEMORY_FAILED == ret) { - ret = OB_EAGAIN; - LOG_WARN("fail to allocate memory, retry", K(ret)); - } else { - LOG_WARN("failed to get old tablet's disk usage", K(ret), K(data_size_before), K(used_size_before)); - } - } else if (nullptr != new_tablet_handle && new_tablet_handle->is_valid() && - OB_FAIL(new_tablet_handle->get_obj()->get_sstables_size(data_size_after, used_size_after))) { - if (OB_ALLOCATE_MEMORY_FAILED == ret) { - ret = OB_EAGAIN; - LOG_WARN("fail to allocate memory, retry", K(ret)); - } else { - LOG_WARN("failed to get new tablet's disk usage", K(ret), K(data_size_after), K(used_size_after)); - } - } else { - if (nullptr != old_tablet_handle) { - parse_file_type(*old_tablet_handle, file_type); - } else { - parse_file_type(*new_tablet_handle, file_type); - } - if (OB_FAIL(disk_reporter_->set_tenant_data_usage(data_size_before, used_size_before, - data_size_after, used_size_after, file_type))) { - LOG_WARN("failed to set tenant's data usage", K(ret), K(data_size_before), K(used_size_before), - K(data_size_after), K(used_size_after), K(file_type)); - } - } - } while (OB_EAGAIN == ret); + if (tablet_id.is_ls_inner_tablet()) { + // no need to report for ls inner tablet + } else if (OB_FAIL(rs_reporter_->submit_tablet_update_task(tenant_id, ls_id, tablet_id))) { + LOG_WARN("failed to report tablet info", KR(ret), K(tenant_id), K(ls_id), K(tablet_id)); } - - return ret; } -*/ void ObLSTabletService::report_tablet_to_rs( const common::ObIArray &tablet_id_array) @@ -836,11 +683,10 @@ void ObLSTabletService::report_tablet_to_rs( } } -int ObLSTabletService::table_scan(ObTableScanIterator &iter, ObTableScanParam ¶m) +int ObLSTabletService::table_scan(ObTabletHandle &tablet_handle, ObTableScanIterator &iter, ObTableScanParam ¶m) { int ret = OB_SUCCESS; NG_TRACE(S_table_scan_begin); - ObTabletHandle data_tablet; AllowToReadMgr::AllowToReadInfo read_info; if (OB_UNLIKELY(!is_inited_)) { @@ -852,9 +698,7 @@ int ObLSTabletService::table_scan(ObTableScanIterator &iter, ObTableScanParam &p LOG_WARN("ls is not allow to read", K(ret), KPC(ls_)); } else if (OB_FAIL(prepare_scan_table_param(param, *(MTL(ObTenantSchemaService*)->get_schema_service())))) { LOG_WARN("failed to prepare scan table param", K(ret), K(param)); - } else if (OB_FAIL(get_tablet_with_timeout(param.tablet_id_, data_tablet, param.timeout_))) { - LOG_WARN("failed to check and get tablet", K(ret), K(param)); - } else if (OB_FAIL(inner_table_scan(data_tablet, iter, param))) { + } else if (OB_FAIL(inner_table_scan(tablet_handle, iter, param))) { LOG_WARN("failed to do table scan", K(ret), KP(&iter), K(param)); } else { bool is_same = false; @@ -869,11 +713,10 @@ int ObLSTabletService::table_scan(ObTableScanIterator &iter, ObTableScanParam &p return ret; } -int ObLSTabletService::table_rescan(ObTableScanParam ¶m, ObNewRowIterator *result) +int ObLSTabletService::table_rescan(ObTabletHandle &tablet_handle, ObTableScanParam ¶m, ObNewRowIterator *result) { int ret = OB_SUCCESS; NG_TRACE(S_table_rescan_begin); - ObTabletHandle data_tablet; AllowToReadMgr::AllowToReadInfo read_info; if (OB_UNLIKELY(!is_inited_)) { @@ -890,9 +733,7 @@ int ObLSTabletService::table_rescan(ObTableScanParam ¶m, ObNewRowIterator *r LOG_WARN("failed to prepare scan table param", K(ret), K(result), K(param)); } else { ObTableScanIterator *iter = static_cast(result); - if (OB_FAIL(get_tablet_with_timeout(param.tablet_id_, data_tablet, param.timeout_))) { - LOG_WARN("failed to check and get tablet", K(ret), K(param)); - } else if (OB_FAIL(inner_table_scan(data_tablet, *iter, param))) { + if (OB_FAIL(inner_table_scan(tablet_handle, *iter, param))) { LOG_WARN("failed to do table scan", K(ret), K(result), K(param)); } } @@ -912,18 +753,12 @@ int ObLSTabletService::table_rescan(ObTableScanParam ¶m, ObNewRowIterator *r int ObLSTabletService::refresh_tablet_addr( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, - const ObMetaDiskAddr &new_addr, ObTabletHandle &tablet_handle) { int ret = OB_SUCCESS; const ObTabletMapKey key(ls_id, tablet_id); ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - if (OB_UNLIKELY(!new_addr.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(new_addr)); - } - while (OB_SUCC(ret)) { ret = tablet_id_set_.set(tablet_id); if (OB_SUCC(ret)) { @@ -940,39 +775,8 @@ int ObLSTabletService::refresh_tablet_addr( } if (OB_FAIL(ret)) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, new_addr, tablet_handle, tablet_handle))) { - LOG_WARN("failed to add tablet to meta mem mgr", K(ret), K(key), K(new_addr), K(tablet_handle)); - } - - return ret; -} - -int ObLSTabletService::update_tablet_object_and_addr( - ObTabletHandle &new_tablet_handle, - const ObMetaDiskAddr &new_addr) -{ - int ret = OB_SUCCESS; - const uint64_t tenant_id = MTL_ID(); - share::ObLSID ls_id; - common::ObTabletID tablet_id; - ObTabletHandle old_tablet_handle; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - - if (OB_UNLIKELY(!new_tablet_handle.is_valid()) - || OB_UNLIKELY(!new_addr.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(new_tablet_handle), K(new_addr)); - } else if (FALSE_IT(ls_id = new_tablet_handle.get_obj()->tablet_meta_.ls_id_)) { - // do nothing - } else if (FALSE_IT(tablet_id = new_tablet_handle.get_obj()->tablet_meta_.tablet_id_)) { - // do nothing - } else if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_handle))) { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); - } else if (OB_FAIL(t3m->compare_and_swap_tablet(ObTabletMapKey(ls_id, tablet_id), - new_addr, old_tablet_handle, new_tablet_handle))) { - LOG_WARN("failed to compare and swap tablet", K(ret), K(ls_id), K(tablet_id), K(new_addr)); - } else { - FLOG_INFO("succeeded to update tablet object and addr", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, tablet_handle))) { + LOG_WARN("failed to add tablet to meta mem mgr", K(ret), K(key), K(tablet_handle)); } return ret; @@ -982,30 +786,37 @@ int ObLSTabletService::trim_old_tablets(const ObTabletID &tablet_id) { int ret = OB_SUCCESS; ObTabletHandle tablet_handle_head; - ObIAllocator &allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); ObTimeGuard time_guard("ObLSTabletService::trim_old_tablets", 1 * 1000 * 1000); ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); time_guard.click("Lock"); if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle_head))) { LOG_WARN("failed to check and get tablet", K(ret), K(tablet_id)); - } else if (FALSE_IT(time_guard.click("GetTablet"))) { + } else if (tablet_handle_head.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", tablet_handle_head.get_obj()); } else if (OB_UNLIKELY(!tablet_handle_head.get_obj()->get_tablet_meta().has_next_tablet_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("doesn't have old tablet", K(ret), "tablet_meta", tablet_handle_head.get_obj()->get_tablet_meta()); } else { + time_guard.click("GetTablet"); ObTablet *tablet_head = tablet_handle_head.get_obj(); + ObTabletHandle new_tablet_handle; + ObLSID ls_id = tablet_head->get_tablet_meta().ls_id_; tablet_head->trim_tablet_list(); ObMetaDiskAddr disk_addr; const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); - if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(tablet_handle_head, disk_addr))) { - LOG_WARN("failed to write update tablet slog", K(ret), K(tablet_handle_head), K(disk_addr)); + if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tablet_head, new_tablet_handle))) { + LOG_WARN("fail to persist and transfor tablet", K(ret), KPC(tablet_head), K(new_tablet_handle)); + } else if (FALSE_IT(time_guard.click("Persist"))) { + } else if (FALSE_IT(disk_addr = new_tablet_handle.get_obj()->get_tablet_addr())) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr))) { + LOG_WARN("failed to write update tablet slog", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->compare_and_swap_tablet(key, - disk_addr, tablet_handle_head, tablet_handle_head))) { - LOG_ERROR("failed to compare and swap tablet", K(key), K(disk_addr), K(lbt())); + } else if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->compare_and_swap_tablet( + key, tablet_handle_head, new_tablet_handle))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(tablet_handle_head), K(new_tablet_handle)); ob_usleep(1000 * 1000); ob_abort(); } else { @@ -1027,6 +838,8 @@ int ObLSTabletService::rollback_rebuild_tablet(const ObTabletID &tablet_id) if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle_head))) { LOG_WARN("failed to check and get tablet", K(ret), K(tablet_id)); + } else if (tablet_handle_head.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", tablet_handle_head.get_obj()); } else { time_guard.click("GetTablet"); @@ -1035,15 +848,23 @@ int ObLSTabletService::rollback_rebuild_tablet(const ObTabletID &tablet_id) ObMetaObj meta_obj; tablet_head->get_next_tablet_guard().get_obj(meta_obj); next_tablet_handle.set_obj(meta_obj); - ObMetaDiskAddr disk_addr; + next_tablet_handle.set_wash_priority(WashTabletPriority::WTP_LOW); const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); + ObMetaDiskAddr disk_addr; + ObTabletHandle new_tablet_handle; - if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(next_tablet_handle, disk_addr))) { - LOG_WARN("failed to write update tablet slog", K(ret), K(next_tablet_handle), K(disk_addr)); + if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet( + *next_tablet_handle.get_obj(), new_tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), K(next_tablet_handle), K(new_tablet_handle)); + } else if (FALSE_IT(time_guard.click("Persist"))) { + } else if (FALSE_IT(disk_addr = new_tablet_handle.get_obj()->get_tablet_addr())) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog( + key.ls_id_, tablet_id, disk_addr))) { + LOG_WARN("failed to write update tablet slog", K(ret), K(key), K(disk_addr)); } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->compare_and_swap_tablet(key, - disk_addr, tablet_handle_head, next_tablet_handle))) { - LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(disk_addr), K(lbt())); + } else if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->compare_and_swap_tablet( + key, tablet_handle_head, new_tablet_handle))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(tablet_handle_head), K(new_tablet_handle)); ob_usleep(1000 * 1000); ob_abort(); } else { @@ -1057,49 +878,52 @@ int ObLSTabletService::rollback_rebuild_tablet(const ObTabletID &tablet_id) int ObLSTabletService::rebuild_tablet_with_old( const ObMigrationTabletParam &mig_tablet_param, - ObMetaObjGuard &tablet_guard) + ObTabletHandle &tablet_guard) { int ret = OB_SUCCESS; - ObTabletHandle new_tablet_handle; - ObTablet *new_tablet = nullptr; + ObTimeGuard time_guard("ObLSTabletService::rebuild_tablet_with_old", 1 * 1000 * 1000); + common::ObArenaAllocator allocator("RebuildTablet"); + ObTabletHandle old_tablet_hdl; + ObTabletHandle tmp_tablet_hdl; + ObTabletHandle new_tablet_hdl; + ObTablet *tmp_tablet = nullptr; ObFreezer *freezer = ls_->get_freezer(); ObMetaDiskAddr disk_addr; - ObTabletHandle old_tablet_handle; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); const common::ObTabletID &tablet_id = mig_tablet_param.tablet_id_; const share::ObLSID &ls_id = mig_tablet_param.ls_id_; const ObTabletMapKey key(ls_id, tablet_id); - ObTimeGuard time_guard("ObLSTabletService::create_memtable", 1 * 1000 * 1000); - ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); - time_guard.click("Lock"); - - if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_handle))) { + if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_hdl))) { LOG_WARN("failed to get tablet", K(ret), K(key)); } else if (FALSE_IT(time_guard.click("GetTablet"))) { - } else if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet(key, new_tablet_handle, true/*only acquire*/))) { - LOG_WARN("failed to acquire tablet", K(ret), K(key)); - } else if (FALSE_IT(new_tablet = new_tablet_handle.get_obj())) { - } else if (OB_FAIL(new_tablet->init(mig_tablet_param, true/*is_update*/, freezer))) { + } else if (old_tablet_hdl.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", old_tablet_hdl.get_obj()); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator, tmp_tablet_hdl))) { + LOG_WARN("fail to acquire temporary tablet", K(ret), K(key)); + } else if (FALSE_IT(tmp_tablet = tmp_tablet_hdl.get_obj())) { + } else if (OB_FAIL(tmp_tablet->init(allocator, mig_tablet_param, true/*is_update*/, freezer))) { LOG_WARN("failed to init tablet", K(ret), K(mig_tablet_param)); + } else if (FALSE_IT(tmp_tablet->set_next_tablet_guard(tablet_guard))) { } else if (FALSE_IT(time_guard.click("InitTablet"))) { - } else if (FALSE_IT(new_tablet->set_next_tablet_guard(tablet_guard))) { - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(new_tablet_handle, disk_addr))) { - LOG_WARN("failed to write update tablet slog", K(ret), K(new_tablet_handle), K(disk_addr)); + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tmp_tablet, new_tablet_hdl))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tmp_tablet), K(new_tablet_hdl)); + } else if (FALSE_IT(time_guard.click("Persist"))) { + } else if (FALSE_IT(disk_addr = new_tablet_hdl.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr))) { + LOG_WARN("fail to write update tablet slog", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, disk_addr, - old_tablet_handle, new_tablet_handle))) { - LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(disk_addr)); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_tablet_hdl, new_tablet_hdl))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(old_tablet_hdl), K(new_tablet_hdl)); ob_usleep(1000 * 1000); ob_abort(); - } else if (OB_FAIL(new_tablet->start_ddl_if_need())) { + } else if (OB_FAIL(new_tablet_hdl.get_obj()->start_ddl_if_need())) { LOG_WARN("start ddl if need failed", K(ret), K(key)); } else { time_guard.click("CASwap"); LOG_INFO("rebuild tablet with old succeed", K(ret), K(key), K(disk_addr)); } - return ret; } @@ -1107,38 +931,40 @@ int ObLSTabletService::migrate_update_tablet( const ObMigrationTabletParam &mig_tablet_param) { int ret = OB_SUCCESS; + ObTimeGuard time_guard("ObLSTabletService::migrate_update_tablet", 1 * 1000 * 1000); + common::ObArenaAllocator allocator("MigUpTab"); const common::ObTabletID &tablet_id = mig_tablet_param.tablet_id_; const share::ObLSID &ls_id = mig_tablet_param.ls_id_; const ObTabletMapKey key(mig_tablet_param.ls_id_, mig_tablet_param.tablet_id_); - ObTabletHandle new_tablet_handle; + ObTabletHandle old_tablet_hdl; + ObTabletHandle tmp_tablet_hdl; + ObTabletHandle new_tablet_hdl; ObTablet *new_tablet = nullptr; ObMetaDiskAddr disk_addr; ObFreezer *freezer = ls_->get_freezer(); - ObTabletHandle old_tablet_handle; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - ObTimeGuard time_guard("ObLSTabletService::migrate_update_tablet", 1 * 1000 * 1000); - ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); - time_guard.click("Lock"); - - if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_handle))) { + if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_hdl))) { LOG_WARN("failed to get tablet", K(ret), K(key)); } else if (FALSE_IT(time_guard.click("GetTablet"))) { - } else if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet(key, new_tablet_handle, true/*only acquire*/))) { - LOG_WARN("failed to acquire tablet", K(ret), K(key)); - } else if (FALSE_IT(new_tablet = new_tablet_handle.get_obj())) { - } else if (OB_FAIL(new_tablet->init(mig_tablet_param, true/*is_update*/, freezer))) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator, tmp_tablet_hdl))) { + LOG_WARN("fail to acquire temporary tablet", K(ret), K(key)); + } else if (FALSE_IT(new_tablet = tmp_tablet_hdl.get_obj())) { + } else if (OB_FAIL(new_tablet->init(allocator, mig_tablet_param, true/*is_update*/, freezer))) { LOG_WARN("failed to init tablet", K(ret), K(mig_tablet_param)); } else if (FALSE_IT(time_guard.click("InitTablet"))) { - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(new_tablet_handle, disk_addr))) { - LOG_WARN("failed to write update tablet slog", K(ret), K(new_tablet_handle), K(disk_addr)); + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*new_tablet, new_tablet_hdl))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(new_tablet), K(new_tablet_hdl)); + } else if (FALSE_IT(time_guard.click("Persist"))) { + } else if (FALSE_IT(disk_addr = new_tablet_hdl.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr))) { + LOG_WARN("fail to write update tablet slog", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, disk_addr, - old_tablet_handle, new_tablet_handle))) { - LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(disk_addr)); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_tablet_hdl, new_tablet_hdl))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(old_tablet_hdl), K(new_tablet_hdl)); ob_usleep(1000 * 1000); ob_abort(); - } else if (OB_FAIL(new_tablet->start_ddl_if_need())) { + } else if (OB_FAIL(new_tablet_hdl.get_obj()->start_ddl_if_need())) { LOG_WARN("start ddl if need failed", K(ret)); } else { time_guard.click("CASwap"); @@ -1153,36 +979,34 @@ int ObLSTabletService::migrate_create_tablet( ObTabletHandle &handle) { int ret = OB_SUCCESS; + ObTimeGuard time_guard("ObLSTabletService::migrate_create_tablet", 1 * 1000 * 1000); + common::ObArenaAllocator allocator("MigCreateTab"); const share::ObLSID &ls_id = mig_tablet_param.ls_id_; const common::ObTabletID &tablet_id = mig_tablet_param.tablet_id_; const ObTabletMapKey key(ls_id, tablet_id); ObFreezer *freezer = ls_->get_freezer(); + ObTabletHandle tmp_tablet_hdl; ObTabletHandle tablet_handle; - ObTablet *tablet = nullptr; ObMetaDiskAddr disk_addr; - ObTimeGuard time_guard("ObLSTabletService::migrate_update_tablet", 1 * 1000 * 1000); - ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); - time_guard.click("Lock"); - - if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet(key, tablet_handle))) { - LOG_WARN("failed to acquire tablet", K(ret), K(key)); - } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_FAIL(tablet->init(mig_tablet_param, false/*is_update*/, freezer))) { - LOG_WARN("failed to init tablet", K(ret), K(mig_tablet_param)); + if (OB_FAIL(ObTabletCreateDeleteHelper::create_tmp_tablet(key, allocator, tmp_tablet_hdl))) { + LOG_WARN("fail to create temporary tablet", K(ret), K(key)); + } else if (OB_FAIL(tmp_tablet_hdl.get_obj()->init(allocator, mig_tablet_param, false/*is_update*/, freezer))) { + LOG_WARN("fail to init tablet", K(ret), K(mig_tablet_param)); } else if (FALSE_IT(time_guard.click("InitTablet"))) { - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(tablet_handle, disk_addr))) { - LOG_WARN("failed to write create tablet slog", K(ret), K(tablet_handle), K(disk_addr)); + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tmp_tablet_hdl.get_obj(), tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), K(tmp_tablet_hdl), K(tablet_handle)); + } else if (FALSE_IT(time_guard.click("Persist"))) { + } else if (FALSE_IT(disk_addr = tablet_handle.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr))) { + LOG_WARN("fail to write update tablet slog", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(refresh_tablet_addr(ls_id, tablet_id, disk_addr, tablet_handle))) { - LOG_WARN("failed to refresh tablet addr", K(ret), K(ls_id), K(tablet_id), K(disk_addr), K(lbt())); + } else if (OB_FAIL(refresh_tablet_addr(ls_id, tablet_id, tablet_handle))) { + LOG_WARN("failed to refresh tablet addr", K(ret), K(ls_id), K(tablet_id), K(lbt())); ob_usleep(1000 * 1000); ob_abort(); - } else if (FALSE_IT(time_guard.click("RefreshAddr"))) { - } else if (OB_FAIL(tablet->start_ddl_if_need())) { + } else if (OB_FAIL(tablet_handle.get_obj()->start_ddl_if_need())) { LOG_WARN("start ddl if need failed", K(ret)); - } else if (OB_FAIL(try_pin_tablet_if_needed(tablet_handle))) { - LOG_WARN("failed to try pin tablet", K(ret), K(ls_id), K(tablet_id)); } else { LOG_INFO("migrate create tablet succeed", K(ret), K(key), K(disk_addr)); } @@ -1197,7 +1021,7 @@ int ObLSTabletService::migrate_create_tablet( LOG_ERROR("fail to erase tablet id from set", K(tmp_ret), K(tablet_id)); } } - if (OB_TMP_FAIL(t3m->del_tablet(key))) { + if (OB_TMP_FAIL(inner_remove_tablet(key.ls_id_, key.tablet_id_))) { LOG_WARN("fail to erase tablet from meta memory manager", K(tmp_ret), K(key)); } } @@ -1205,18 +1029,98 @@ int ObLSTabletService::migrate_create_tablet( return ret; } -int ObLSTabletService::update_tablet_table_store( - const ObTabletHandle &old_tablet_handle, - const ObIArray &table_handles) +int ObLSTabletService::refresh_memtable_for_ckpt( + const ObMetaDiskAddr &old_addr, + const ObMetaDiskAddr &cur_addr, + ObTabletHandle &new_tablet_handle) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!old_addr.is_equal_for_persistence(cur_addr))) { + ret = OB_NOT_THE_OBJECT; + LOG_WARN("the old tablet has been replaced", K(ret), K(old_addr), K(cur_addr)); + } else if (OB_UNLIKELY(old_addr != cur_addr)) { + // memtables were updated + if (OB_FAIL(new_tablet_handle.get_obj()->refresh_memtable_and_update_seq(cur_addr.seq()))) { + LOG_WARN("fail to pull newest memtables", K(ret), K(old_addr), K(cur_addr), K(new_tablet_handle)); + } + } + return ret; +} + +int ObLSTabletService::update_tablet_checkpoint( + const ObTabletMapKey &key, + const ObMetaDiskAddr &old_addr, + const ObMetaDiskAddr &new_addr, + const bool is_replay_old, + ObTabletHandle &new_handle) { int ret = OB_SUCCESS; + ObTimeGuard time_guard("UpdateTabletCKPT", 3000000/*3 seconds*/); if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("ls tablet svr hasn't been inited", K(ret)); - } else if (OB_UNLIKELY(!old_tablet_handle.is_valid() || 0 == table_handles.count())) { + } else if (OB_UNLIKELY(!key.is_valid() + || !old_addr.is_valid() + || !new_addr.is_valid() + || !new_addr.is_block() + || (!is_replay_old && !new_handle.is_valid()))) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("old tablet handle is invalid", K(ret), K(old_tablet_handle), K(table_handles.count())); + LOG_WARN("invalid argument", K(ret), K(key), K(new_addr), K(new_handle)); + } else { + common::ObArenaAllocator allocator("CKPTUpdate"); + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTabletHandle tablet_handle; + ObMetaDiskAddr addr; + ObBucketHashWLockGuard lock_guard(bucket_lock_, key.tablet_id_.hash()); + time_guard.click("Lock"); + if (OB_FAIL(t3m->get_tablet_addr(key, addr))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_TABLET_NOT_EXIST; + } + LOG_WARN("fail to get old tablet addr", K(ret), K(key)); + } else if (!is_replay_old) { + if (OB_FAIL(t3m->get_tablet(WashTabletPriority::WTP_LOW, key, tablet_handle))) { + LOG_WARN("fail to get tablet", K(ret), K(key)); + } else if (FALSE_IT(time_guard.click("GetOld"))) { + } else if (OB_FAIL(refresh_memtable_for_ckpt(old_addr, addr, new_handle))) { + LOG_WARN("fail to update tablet", K(ret), K(old_addr), K(addr), K(new_handle)); + } else if (FALSE_IT(time_guard.click("UpdateTablet"))) { + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, new_handle))) { + LOG_WARN("fail to compare and swap tablet", K(ret), K(tablet_handle), K(new_handle)); + } + } else { + time_guard.click("GetOld"); + if (OB_UNLIKELY(addr != old_addr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the old tablet has been replaced, which is not allowed during upgrade", + K(ret), K(addr), K(old_addr)); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_addr, new_addr))) { + LOG_WARN("fail to compare and swap tablet", K(ret), K(old_addr), K(new_addr)); + } + } + + if (OB_SUCC(ret)) { + time_guard.click("CASwap"); + FLOG_INFO("succeeded to update tablet ckpt", K(key), K(old_addr), K(new_addr), + K(is_replay_old)); + } + } + return ret; +} + +int ObLSTabletService::update_tablet_table_store( + const ObTabletHandle &old_tablet_handle, + const ObIArray &tables) +{ + int ret = OB_SUCCESS; + common::ObArenaAllocator allocator; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ls tablet svr hasn't been inited", K(ret)); + } else if (OB_UNLIKELY(!old_tablet_handle.is_valid() || 0 == tables.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("old tablet handle is invalid", K(ret), K(old_tablet_handle), K(tables.count())); } else { ObTablet *old_tablet = old_tablet_handle.get_obj(); const common::ObTabletID &tablet_id = old_tablet->get_tablet_meta().tablet_id_; @@ -1237,35 +1141,37 @@ int ObLSTabletService::update_tablet_table_store( } else if (tablet_handle.get_obj() != old_tablet) { ret = OB_EAGAIN; LOG_WARN("tablet has changed, skip it", K(ret), K(tablet_handle), K(old_tablet_handle)); + } else if (old_tablet->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", old_tablet); } else { time_guard.click("GetTablet"); - - ObTabletHandle new_tablet_handle; - ObTablet *new_tablet = nullptr; + ObTabletHandle tmp_tablet_hdl; + ObTabletHandle new_tablet_hdl; + ObTablet *tmp_tablet = nullptr; const share::ObLSID &ls_id = ls_->get_ls_id(); const ObTabletMapKey key(ls_id, tablet_id); - const ObTabletTxMultiSourceDataUnit &tx_data = old_tablet->tablet_meta_.tx_data_; - const ObTabletBindingInfo &ddl_data = old_tablet->tablet_meta_.ddl_data_; - const ObTabletAutoincSeq &autoinc_seq = old_tablet->tablet_meta_.autoinc_seq_; ObMetaDiskAddr disk_addr; - if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet(key, new_tablet_handle))) { - LOG_WARN("fail to acquire tablet", K(ret), K(key)); - } else if (FALSE_IT(new_tablet = new_tablet_handle.get_obj())) { - } else if (OB_FAIL(new_tablet->init(table_handles, *old_tablet, tx_data, ddl_data, autoinc_seq))) { - LOG_WARN("fail to init new tablet", K(ret), KPC(old_tablet), K(tx_data), K(ddl_data), K(autoinc_seq)); + if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator, tmp_tablet_hdl))) { + LOG_WARN("fail to acquire temporary tablet", K(ret), K(key)); + } else if (FALSE_IT(tmp_tablet = tmp_tablet_hdl.get_obj())) { + } else if (OB_FAIL(tmp_tablet->init(allocator, tables, *old_tablet))) { + LOG_WARN("fail to init new tablet", K(ret), KPC(old_tablet)); } else if (FALSE_IT(time_guard.click("InitTablet"))) { - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(new_tablet_handle, disk_addr))) { - LOG_WARN("fail to write update tablet slog", K(ret), K(new_tablet_handle), K(disk_addr)); + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tmp_tablet, new_tablet_hdl))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tmp_tablet), K(new_tablet_hdl)); + } else if (FALSE_IT(disk_addr = new_tablet_hdl.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr))) { + LOG_WARN("fail to write update tablet slog", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, disk_addr, old_tablet_handle, new_tablet_handle))) { - LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(disk_addr), K(old_tablet_handle), K(lbt())); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_tablet_handle, new_tablet_hdl))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(old_tablet_handle), K(new_tablet_hdl)); ob_usleep(1000 * 1000); ob_abort(); } else { time_guard.click("CASwap"); LOG_INFO("succeeded to build new tablet", K(ret), K(disk_addr), - K(new_tablet_handle), KPC(new_tablet_handle.get_obj())); + K(new_tablet_hdl), KPC(new_tablet_hdl.get_obj())); } } } @@ -1278,11 +1184,12 @@ int ObLSTabletService::update_tablet_table_store( ObTabletHandle &handle) { int ret = OB_SUCCESS; + common::ObArenaAllocator allocator; const share::ObLSID &ls_id = ls_->get_ls_id(); const ObTabletMapKey key(ls_id, tablet_id); - ObTabletHandle old_tablet_handle; - ObTabletHandle new_tablet_handle; - ObTablet *new_tablet = nullptr; + ObTabletHandle old_tablet_hdl; + ObTabletHandle tmp_tablet_hdl; + ObTabletHandle new_tablet_hdl; ObTimeGuard time_guard("ObLSTabletService::UpdateTableStore", 1 * 1000 * 1000); if (IS_NOT_INIT) { @@ -1291,44 +1198,44 @@ int ObLSTabletService::update_tablet_table_store( } else if (OB_UNLIKELY(!tablet_id.is_valid() || !param.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(tablet_id), K(param)); - } else if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet(key, new_tablet_handle, true/*only acquire*/))) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator, tmp_tablet_hdl))) { if (OB_ENTRY_NOT_EXIST == ret) { ret = OB_TABLET_NOT_EXIST; } else { - LOG_WARN("failed to acquire tablet", K(ret), K(key)); + LOG_WARN("fail to acquire temporary tablet", K(ret), K(key)); } } else { - new_tablet = new_tablet_handle.get_obj(); + ObTablet *tmp_tablet = tmp_tablet_hdl.get_obj(); time_guard.click("Acquire"); ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); time_guard.click("Lock"); - if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_handle))) { + if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_hdl))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (old_tablet_hdl.get_obj()->is_empty_shell()) { + handle = old_tablet_hdl; + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", old_tablet_hdl.get_obj()); } else { time_guard.click("GetTablet"); ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - ObTablet *old_tablet = old_tablet_handle.get_obj(); - const ObTabletTxMultiSourceDataUnit *tx_data = nullptr; - const ObTabletBindingInfo *binding_info = nullptr; - const ObTabletAutoincSeq *auto_inc_seq = nullptr; + ObTablet *old_tablet = old_tablet_hdl.get_obj(); ObMetaDiskAddr disk_addr; - - if (OB_FAIL(choose_msd(param, *old_tablet, tx_data, binding_info, auto_inc_seq))) { - LOG_WARN("failed to choose msd", K(ret), K(param), KPC(old_tablet)); - } else if (OB_FAIL(new_tablet->init(param, *old_tablet, *tx_data, *binding_info, *auto_inc_seq))) { - LOG_WARN("failed to init tablet", K(ret), K(param), KPC(old_tablet), KPC(tx_data), KPC(binding_info), KPC(auto_inc_seq)); + if (OB_FAIL(tmp_tablet->init(allocator, param, *old_tablet))) { + LOG_WARN("failed to init tablet", K(ret), K(param), KPC(old_tablet)); } else if (FALSE_IT(time_guard.click("InitNew"))) { - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(new_tablet_handle, disk_addr))) { - LOG_WARN("fail to write update tablet slog", K(ret), K(new_tablet_handle), K(disk_addr)); + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tmp_tablet, new_tablet_hdl))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tmp_tablet), K(new_tablet_hdl)); + } else if (FALSE_IT(disk_addr = new_tablet_hdl.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr))) { + LOG_WARN("fail to write update tablet slog", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, disk_addr, old_tablet_handle, new_tablet_handle))) { - LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(disk_addr), K(old_tablet_handle), K(lbt())); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_tablet_hdl, new_tablet_hdl))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(old_tablet_hdl), K(new_tablet_hdl)); ob_usleep(1000 * 1000); ob_abort(); } else if (FALSE_IT(time_guard.click("CASwap"))) { } else { - handle = new_tablet_handle; + handle = new_tablet_hdl; LOG_INFO("succeeded to build new tablet", K(ret), K(key), K(disk_addr), K(param), K(handle)); } } @@ -1336,11 +1243,164 @@ int ObLSTabletService::update_tablet_table_store( return ret; } +int ObLSTabletService::update_tablet_mstx( + const ObTabletMapKey &key, + const ObMetaDiskAddr &old_addr, + const ObTabletHandle &old_tablet_handle, + ObTabletHandle &new_tablet_handle) +{ + int ret = OB_SUCCESS; + ObTablet *new_tablet = nullptr; + ObMetaDiskAddr new_addr; + + ObTimeGuard time_guard("ObLSTabletService::update_tablet_mstx", 1 * 1000 * 1000); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!key.is_valid() + || !old_addr.is_valid() + || !old_tablet_handle.is_valid() + || !new_tablet_handle.is_valid() + || !(new_tablet = new_tablet_handle.get_obj())->is_valid() + || !(new_addr = new_tablet->get_tablet_addr()).is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(key), K(old_addr), K(old_tablet_handle), + K(new_tablet_handle), KPC(new_tablet), K(new_addr)); + } else { + ObMetaDiskAddr addr; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + + + ObBucketHashWLockGuard lock_guard(bucket_lock_, key.tablet_id_.hash()); + time_guard.click("Lock"); + ObTabletHandle curr_tablet_handle; + if (OB_FAIL(direct_get_tablet(key.tablet_id_, curr_tablet_handle))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; // deleted, skip + } else { + LOG_WARN("fail to get tablet", K(ret), K(key)); + } + } else if (curr_tablet_handle.get_obj() != old_tablet_handle.get_obj()) { + // we could never persist this tablet, skip this + LOG_INFO("tablet has been changed", K(ret), K(key), K(old_addr), K(old_tablet_handle), K(curr_tablet_handle)); + } else if (FALSE_IT(addr = curr_tablet_handle.get_obj()->get_tablet_addr())) { + } else if (old_addr != addr) { /* the same full tablet obj with different memtables will hit this */ + // Let this updating fail and throw tablet back to the persist queue. + // It will be tackled correctly in the next round because its address will be compared + // again in ObFullTabletCreator::persist_tablet() + ret = common::OB_NOT_THE_OBJECT; + LOG_WARN("old address has changed, skip update", K(ret), K(key), K(addr), K(old_addr)); + } else { + time_guard.click("GetOld"); + if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(key.ls_id_, key.tablet_id_, new_addr))) { + LOG_WARN("fail to write update tablet slog", K(ret), K(key), K(new_addr)); + } else if (FALSE_IT(time_guard.click("WrSlog"))) { + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_tablet_handle, new_tablet_handle))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(old_tablet_handle), K(new_tablet_handle)); + ob_usleep(1000 * 1000); + ob_abort(); + } else if (FALSE_IT(time_guard.click("CASwap"))) { + } else { + FLOG_INFO("succeeded to update tablet mstx", K(ret), + K(key), K(old_addr), K(old_tablet_handle), K(new_addr), K(new_tablet_handle)); + } + } + } + return ret; +} + +int ObLSTabletService::update_tablet_to_empty_shell(const common::ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + const share::ObLSID &ls_id = ls_->get_ls_id(); + const ObTabletMapKey key(ls_id, tablet_id); + ObTabletHandle new_tablet_hdl; + ObTimeGuard time_guard("UpdateTabletToEmptyShell", 3 * 1000 * 1000/*3 seconds*/); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ls tablet svr hasn't been inited", K(ret)); + } else if (OB_UNLIKELY(!tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(tablet_id)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::prepare_create_msd_tablet())) { + LOG_WARN("fail to prepare create msd tablet", K(ret)); + } else if (FALSE_IT(time_guard.click("PreFinish"))) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_msd_tablet(key, new_tablet_hdl))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_TABLET_NOT_EXIST; + } else { + LOG_WARN("fail to acquire temporary tablet", K(ret), K(key)); + } + } else { + time_guard.click("Acquire"); + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + time_guard.click("Lock"); + if (OB_FAIL(no_lock_update_tablet_to_empty_shell(key, new_tablet_hdl))) { + LOG_WARN("failed to do no lock update tablet to empty shell", K(ret), K(key)); + } else { + time_guard.click("Update"); + } + } + + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(!new_tablet_hdl.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid new tablet hdl", K(ret), K(tablet_id), K(new_tablet_hdl)); + } else if (new_tablet_hdl.get_obj()->is_valid() /* tablet may not init if empty shell exists */ + && OB_FAIL(ObTabletCreateDeleteHelper::push_msd_tablet_to_queue(new_tablet_hdl))) { + LOG_WARN("failed to push msd tablet to queue", K(ret), K(new_tablet_hdl)); + } + } + return ret; +} + +int ObLSTabletService::no_lock_update_tablet_to_empty_shell( + const ObTabletMapKey &key, + ObTabletHandle &new_tablet_handle) +{ + int ret = OB_SUCCESS; + ObTabletHandle old_tablet_handle; + const common::ObTabletID &tablet_id = key.tablet_id_; + ObTimeGuard time_guard("NoLockUpdateTabletToEmptyShell", 2 * 1000 * 1000/*2 seconds*/); + + if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (old_tablet_handle.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", old_tablet_handle.get_obj()); + } else { + time_guard.click("GetOld"); + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTablet *old_tablet = old_tablet_handle.get_obj(); + ObTablet *new_tablet = new_tablet_handle.get_obj(); + ObMetaDiskAddr disk_addr; + if (OB_FAIL(new_tablet->init_empty_shell(*new_tablet_handle.get_allocator(), *old_tablet))) { + LOG_WARN("failed to init tablet", K(ret), KPC(old_tablet)); + } else if (FALSE_IT(time_guard.click("InitNew"))) { + } else if (OB_FAIL(ObTabletSlogHelper::write_empty_shell_tablet_slog(new_tablet, disk_addr))) { + LOG_WARN("fail to write emtpy shell tablet slog", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); + } else if (FALSE_IT(new_tablet->tablet_addr_ = disk_addr)) { + } else if (FALSE_IT(time_guard.click("WrSlog"))) { + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_tablet_handle, new_tablet_handle))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(old_tablet_handle), K(new_tablet_handle)); + ob_usleep(1000 * 1000); + ob_abort(); + } else { + ls_->get_tablet_gc_handler()->set_tablet_gc_trigger(); + time_guard.click("CASwap"); + LOG_INFO("succeeded to build empty shell tablet", K(ret), K(key), K(disk_addr)); + } + } + + return ret; +} + int ObLSTabletService::update_medium_compaction_info( const common::ObTabletID &tablet_id, ObTabletHandle &handle) { int ret = OB_SUCCESS; + common::ObArenaAllocator allocator; ObTabletHandle old_tablet_handle; ObTimeGuard time_guard("ObLSTabletService::update_medium_compaction_info", 1 * 1000 * 1000); ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); @@ -1354,63 +1414,106 @@ int ObLSTabletService::update_medium_compaction_info( LOG_WARN("invalid args", K(ret), K(tablet_id)); } else if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_handle))) { LOG_WARN("failed to check and get tablet", K(ret), K(tablet_id)); + } else if (old_tablet_handle.get_obj()->is_empty_shell()) { + handle = old_tablet_handle; + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", old_tablet_handle.get_obj()); } else { time_guard.click("GetTablet"); - - ObTabletHandle new_tablet_handle; - ObTablet *new_tablet = nullptr; + ObTabletHandle tmp_tablet_hdl; + ObTabletHandle new_tablet_hdl; + ObTablet *tmp_tablet = nullptr; ObTablet *old_tablet = old_tablet_handle.get_obj(); const share::ObLSID &ls_id = ls_->get_ls_id(); const ObTabletMapKey key(ls_id, tablet_id); ObMetaDiskAddr disk_addr; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet(key, new_tablet_handle, true/*only acquire*/))) { + if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator, tmp_tablet_hdl))) { if (OB_ENTRY_NOT_EXIST == ret) { ret = OB_TABLET_NOT_EXIST; } else { LOG_WARN("failed to acquire tablet", K(ret), K(key)); } - } else if (FALSE_IT(new_tablet = new_tablet_handle.get_obj())) { - } else if (OB_FAIL(new_tablet->init_with_update_medium_info(*old_tablet))) { + } else if (FALSE_IT(tmp_tablet = tmp_tablet_hdl.get_obj())) { + } else if (OB_FAIL(tmp_tablet->init_with_update_medium_info(allocator, *old_tablet))) { LOG_WARN("failed to init tablet", K(ret), KPC(old_tablet)); } else if (FALSE_IT(time_guard.click("InitNew"))) { - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(new_tablet_handle, disk_addr))) { - LOG_WARN("fail to write update tablet slog", K(ret), K(new_tablet_handle), K(disk_addr)); + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tmp_tablet, new_tablet_hdl))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tmp_tablet), K(new_tablet_hdl)); + } else if (FALSE_IT(disk_addr = new_tablet_hdl.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr))) { + LOG_WARN("fail to write update tablet slog", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, - disk_addr, old_tablet_handle, new_tablet_handle))) { - LOG_WARN("failed to compare and swap tablet", K(ret), K(key), K(disk_addr), K(old_tablet_handle)); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_tablet_handle, new_tablet_hdl))) { + LOG_WARN("failed to compare and swap tablet", K(ret), K(key), K(old_tablet_handle), K(new_tablet_hdl)); + } else if (FALSE_IT(time_guard.click("CASwap"))) { } else { - time_guard.click("CASwap"); - handle = new_tablet_handle; + handle = new_tablet_hdl; } } - return ret; } -int ObLSTabletService::choose_msd( - const ObUpdateTableStoreParam ¶m, - const ObTablet &old_tablet, - const ObTabletTxMultiSourceDataUnit *&tx_data, - const ObTabletBindingInfo *&binding_info, - const share::ObTabletAutoincSeq *&auto_inc_seq) +int ObLSTabletService::build_new_tablet_from_mds_table( + const common::ObTabletID &tablet_id, + const share::SCN &flush_scn) { int ret = OB_SUCCESS; - const ObTabletMeta &old_tablet_meta = old_tablet.get_tablet_meta(); - tx_data = ¶m.tx_data_; - binding_info = ¶m.binding_info_; - auto_inc_seq = ¶m.auto_inc_seq_; + common::ObArenaAllocator allocator("BuildMSD"); + const share::ObLSID &ls_id = ls_->get_ls_id(); + const ObTabletMapKey key(ls_id, tablet_id); + ObTabletHandle old_tablet_handle; + ObTabletHandle tmp_tablet_hdl; + ObTabletHandle new_tablet_handle; + ObTimeGuard time_guard("MdsDump", 3 * 1000 * 1000/*3 seconds*/); - if (!tx_data->is_valid()) { - tx_data = &old_tablet_meta.tx_data_; - } - if (!binding_info->is_valid()) { - binding_info = &old_tablet_meta.ddl_data_; - } - if (!auto_inc_seq->is_valid()) { - auto_inc_seq = &old_tablet_meta.autoinc_seq_; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(tablet_id)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator, tmp_tablet_hdl))) { + LOG_WARN("failed to acquire tablet", K(ret), K(key)); + } else { + ObTablet *tmp_tablet = tmp_tablet_hdl.get_obj(); + time_guard.click("Acquire"); + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + time_guard.click("Lock"); + + if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (old_tablet_handle.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip mds table dump operation", K(ret), + "old_tablet", *old_tablet_handle.get_obj()); + } else { + time_guard.click("GetOld"); + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTablet *old_tablet = old_tablet_handle.get_obj(); + ObMetaDiskAddr disk_addr; + ObArenaAllocator arena_allocator("mds_reader"); + ObTabletMdsData mds_data; + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(old_tablet->read_mds_table(arena_allocator, mds_data, true))) { + LOG_WARN("failed to read mds table", K(ret)); + } else if (OB_FAIL(tmp_tablet->init(allocator, *old_tablet, flush_scn, mds_data, old_tablet->mds_data_))) { + LOG_WARN("failed to init tablet", K(ret), KPC(old_tablet), K(flush_scn)); + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tmp_tablet, new_tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tmp_tablet), K(new_tablet_handle)); + } else if (FALSE_IT(disk_addr = new_tablet_handle.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr))) { + LOG_WARN("fail to write update tablet slog", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); + } else if (FALSE_IT(time_guard.click("WrSlog"))) { + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_tablet_handle, new_tablet_handle))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(disk_addr), K(old_tablet_handle)); + ob_usleep(1000 * 1000); + ob_abort(); + } else { + time_guard.click("CASwap"); + LOG_INFO("succeeded to build new tablet", K(ret), K(disk_addr), K(new_tablet_handle), K(mds_data)); + } + } } return ret; @@ -1432,6 +1535,8 @@ int ObLSTabletService::update_tablet_report_status(const common::ObTabletID &tab LOG_WARN("invalid args", K(ret), K(tablet_id)); } else if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (tablet_handle.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", tablet_handle.get_obj()); } else { time_guard.click("GetTablet"); @@ -1439,14 +1544,19 @@ int ObLSTabletService::update_tablet_report_status(const common::ObTabletID &tab ObMetaDiskAddr disk_addr; const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); ObTablet *tablet = tablet_handle.get_obj(); + ObTabletHandle new_tablet_handle; + if (tablet->tablet_meta_.report_status_.need_report()) { tablet->tablet_meta_.report_status_.cur_report_version_ = tablet->tablet_meta_.report_status_.merge_snapshot_version_; - if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(tablet_handle, disk_addr))) { - LOG_WARN("failed to write update tablet slog", K(ret), K(tablet_handle), K(disk_addr)); + if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tablet), K(new_tablet_handle)); + } else if (FALSE_IT(time_guard.click("Persist"))) { + } else if (FALSE_IT(disk_addr = new_tablet_handle.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(key.ls_id_, tablet_id, disk_addr))) { + LOG_WARN("failed to write update tablet slog", K(ret), K(key), K(disk_addr)); } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, - disk_addr, tablet_handle, tablet_handle))) { - LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(disk_addr), K(lbt())); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, new_tablet_handle))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(tablet_handle), K(new_tablet_handle)); ob_usleep(1000 * 1000); ob_abort(); } else { @@ -1481,6 +1591,8 @@ int ObLSTabletService::update_tablet_restore_status( LOG_WARN("invalid args", K(ret), K(tablet_id), K(restore_status)); } else if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (tablet_handle.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", tablet_handle.get_obj()); } else { time_guard.click("GetTablet"); @@ -1488,6 +1600,8 @@ int ObLSTabletService::update_tablet_restore_status( ObMetaDiskAddr disk_addr; const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); ObTablet *tablet = tablet_handle.get_obj(); + ObTabletHandle new_tablet_handle; + if (OB_FAIL(tablet->tablet_meta_.ha_status_.get_restore_status(current_status))) { LOG_WARN("failed to get restore status", K(ret), KPC(tablet)); } else if (OB_FAIL(ObTabletRestoreStatus::check_can_change_status(current_status, restore_status, can_change))) { @@ -1497,24 +1611,32 @@ int ObLSTabletService::update_tablet_restore_status( LOG_WARN("can not change restore status", K(ret), K(current_status), K(restore_status), KPC(tablet)); } else if (OB_FAIL(tablet->tablet_meta_.ha_status_.set_restore_status(restore_status))) { LOG_WARN("failed to set restore status", K(ret), K(restore_status), KPC(tablet)); - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(tablet_handle, disk_addr))) { - LOG_WARN("failed to write update tablet slog", K(ret), K(tablet_handle), K(disk_addr)); - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = tablet->tablet_meta_.ha_status_.set_restore_status(current_status))) { - LOG_WARN("failed to set restore status", K(tmp_ret), K(current_status), KPC(tablet)); - ob_abort(); - } - } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, - disk_addr, tablet_handle, tablet_handle))) { - LOG_ERROR("failed to compare and swap tablet", K(key), K(disk_addr)); - ob_abort(); + } else if (restore_status == ObTabletRestoreStatus::UNDEFINED + && OB_FALSE_IT((void)tablet->tablet_meta_.reset_transfer_table())) { } else { - time_guard.click("CASwap"); - LOG_INFO("succeeded to build new tablet", K(ret), K(key), K(disk_addr), K(restore_status), K(tablet_handle)); + if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tablet), K(new_tablet_handle)); + } else if (FALSE_IT(time_guard.click("Persist"))) { + } else if (FALSE_IT(disk_addr = new_tablet_handle.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(key.ls_id_, tablet_id, disk_addr))) { + LOG_WARN("failed to write update tablet slog", K(ret), K(key), K(disk_addr)); + } else if (FALSE_IT(time_guard.click("WrSlog"))) { + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, new_tablet_handle))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(tablet_handle), K(new_tablet_handle)); + ob_abort(); + } else { + time_guard.click("CASwap"); + LOG_INFO("succeeded to build new tablet", K(ret), K(key), K(disk_addr), K(restore_status), K(tablet_handle)); + } + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = tablet->tablet_meta_.ha_status_.set_restore_status(current_status))) { + LOG_WARN("failed to set restore status", K(tmp_ret), K(current_status), KPC(tablet)); + ob_abort(); + } + } } } - return ret; } @@ -1542,6 +1664,8 @@ int ObLSTabletService::update_tablet_ha_data_status( LOG_WARN("invalid args", K(ret), K(tablet_id), K(data_status)); } else if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (tablet_handle.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", tablet_handle.get_obj()); } else { time_guard.click("GetTablet"); @@ -1549,6 +1673,7 @@ int ObLSTabletService::update_tablet_ha_data_status( ObMetaDiskAddr disk_addr; const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); ObTablet *tablet = tablet_handle.get_obj(); + ObTabletHandle new_tablet_handle; if (OB_FAIL(tablet->tablet_meta_.ha_status_.get_data_status(current_status))) { LOG_WARN("failed to get data status", K(ret), KPC(tablet)); @@ -1561,24 +1686,31 @@ int ObLSTabletService::update_tablet_ha_data_status( LOG_INFO("data status is same, skip update", K(tablet_id), K(current_status), K(data_status)); } else if (OB_FAIL(tablet->tablet_meta_.ha_status_.set_data_status(data_status))) { LOG_WARN("failed to set data status", K(ret), KPC(tablet), K(data_status)); - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(tablet_handle, disk_addr))) { - LOG_WARN("failed to write update tablet slog", K(ret), K(tablet_handle), K(disk_addr)); - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = tablet->tablet_meta_.ha_status_.set_data_status(current_status))) { - LOG_WARN("failed to set data status", K(tmp_ret), K(current_status), KPC(tablet)); - ob_abort(); - } - } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, disk_addr, tablet_handle, tablet_handle))) { - LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(disk_addr), K(lbt())); - ob_usleep(1000 * 1000); - ob_abort(); } else { - time_guard.click("CASwap"); - LOG_INFO("succeeded to build new tablet", K(ret), K(key), K(disk_addr), K(data_status), K(tablet_handle)); + if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tablet), K(new_tablet_handle)); + } else if (FALSE_IT(time_guard.click("Persist"))) { + } else if (FALSE_IT(disk_addr = new_tablet_handle.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(key.ls_id_, tablet_id, disk_addr))) { + LOG_WARN("failed to write update tablet slog", K(ret), K(tablet_handle), K(disk_addr)); + } else if (FALSE_IT(time_guard.click("WrSlog"))) { + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, new_tablet_handle))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(tablet_handle), K(new_tablet_handle)); + ob_usleep(1000 * 1000); + ob_abort(); + } else { + time_guard.click("CASwap"); + LOG_INFO("succeeded to update tablet ha data status", K(ret), K(key), K(disk_addr), K(data_status), K(tablet_handle)); + } + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = tablet->tablet_meta_.ha_status_.set_data_status(current_status))) { + LOG_WARN("failed to set data status", K(tmp_ret), K(current_status), KPC(tablet)); + ob_abort(); + } + } } } - return ret; } @@ -1606,6 +1738,8 @@ int ObLSTabletService::update_tablet_ha_expected_status( LOG_WARN("invalid args", K(ret), K(tablet_id), K(expected_status)); } else if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (tablet_handle.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", tablet_handle.get_obj()); } else { time_guard.click("GetTablet"); @@ -1613,6 +1747,7 @@ int ObLSTabletService::update_tablet_ha_expected_status( ObMetaDiskAddr disk_addr; const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); ObTablet *tablet = tablet_handle.get_obj(); + ObTabletHandle new_tablet_handle; if (OB_FAIL(tablet->tablet_meta_.ha_status_.get_expected_status(current_status))) { LOG_WARN("failed to get data status", K(ret), KPC(tablet)); @@ -1627,85 +1762,47 @@ int ObLSTabletService::update_tablet_ha_expected_status( } else { if (OB_FAIL(tablet->tablet_meta_.ha_status_.set_expected_status(expected_status))) { LOG_WARN("failed to set ha meta status", K(ret), KPC(tablet), K(expected_status)); - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(tablet_handle, disk_addr))) { - LOG_WARN("failed to write update tablet slog", K(ret), K(tablet_handle), K(disk_addr)); - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = tablet->tablet_meta_.ha_status_.set_expected_status(current_status))) { - LOG_WARN("failed to set expected status", K(tmp_ret), K(current_status), KPC(tablet)); - ob_abort(); - } - } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, disk_addr, tablet_handle, tablet_handle))) { - LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(disk_addr), K(lbt())); - usleep(1000 * 1000); - ob_abort(); } else { - time_guard.click("CASwap"); - LOG_INFO("succeeded to update tablet meta status", K(ret), K(key), K(disk_addr), K(expected_status), KPC(tablet)); + if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tablet), K(new_tablet_handle)); + } else if (FALSE_IT(disk_addr = new_tablet_handle.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(key.ls_id_, tablet_id, disk_addr))) { + LOG_WARN("failed to write update tablet slog", K(ret), K(tablet_handle), K(disk_addr)); + } else if (FALSE_IT(time_guard.click("WrSlog"))) { + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, new_tablet_handle))) { + LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(tablet_handle), K(new_tablet_handle)); + usleep(1000 * 1000); + ob_abort(); + } else { + time_guard.click("CASwap"); + LOG_INFO("succeeded to update tablet meta status", K(ret), K(key), K(disk_addr), K(expected_status), KPC(tablet)); + } + + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = tablet->tablet_meta_.ha_status_.set_expected_status(current_status))) { + LOG_WARN("failed to set expected status", K(tmp_ret), K(current_status), KPC(tablet)); + ob_abort(); + } + } } } } return ret; } -int ObLSTabletService::handle_remove_tablets( - const common::ObIArray &slog_params, - const common::ObLinearHashMap &delete_tablet_infos) -{ - int ret = OB_SUCCESS; - const int32_t put_tablet_cmd = ObIRedoModule::gen_cmd(ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, - ObRedoLogSubType::OB_REDO_LOG_PUT_TABLET); - const int32_t delete_tablet_cmd = ObIRedoModule::gen_cmd(ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, - ObRedoLogSubType::OB_REDO_LOG_DELETE_TABLET); - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - - for (int64_t i = 0; OB_SUCC(ret) && i < slog_params.count(); ++i) { - const ObStorageLogParam &slog_param = slog_params.at(i); - if (OB_UNLIKELY(!slog_param.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("slog entry is null", K(ret), K(slog_param)); - } else if (slog_param.cmd_ == put_tablet_cmd) { - const ObMetaDiskAddr &disk_addr = slog_param.disk_addr_; - const ObCreateTabletLog *slog = static_cast(slog_param.data_); - const common::ObTabletID &tablet_id = slog->tablet_->get_tablet_meta().tablet_id_; - ObTabletMapKey key(ls_->get_ls_id(), tablet_id); - DeleteTabletInfo info; - if (OB_FAIL(delete_tablet_infos.get(tablet_id, info))) { - LOG_WARN("failed to get info from hash map", K(ret)); - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, disk_addr, - info.old_data_tablet_handle_, info.new_data_tablet_handle_))) { - LOG_WARN("failed to compare and swap tablet", K(ret), K(key), K(disk_addr), - "old_data_tablet_handle", info.old_data_tablet_handle_, - "new_data_tablet_handle", info.new_data_tablet_handle_); - } - } else if (slog_param.cmd_ == delete_tablet_cmd) { - const ObDeleteTabletLog *slog = static_cast(slog_param.data_); - const share::ObLSID &ls_id = slog->ls_id_; - const common::ObTabletID &tablet_id = slog->tablet_id_; - if (OB_FAIL(do_remove_tablet(ls_id, tablet_id))) { - LOG_ERROR("failed to remove tablet", K(ret), K(ls_id), K(tablet_id), K(i)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected slog param cmd type", K(ret), K(slog_param)); - } - } - - return ret; -} - int ObLSTabletService::replay_create_tablet( const ObMetaDiskAddr &disk_addr, const char *buf, const int64_t buf_len, - const ObTabletID &tablet_id) + const ObTabletID &tablet_id, + ObTabletTransferInfo &tablet_transfer_info) { int ret = OB_SUCCESS; bool b_exist = false; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); ObFreezer *freezer = ls_->get_freezer(); const ObLSID &ls_id = ls_->get_ls_id(); - common::ObIAllocator &allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); - if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); @@ -1715,100 +1812,59 @@ int ObLSTabletService::replay_create_tablet( ret = OB_ERR_UNEXPECTED; LOG_ERROR("restart replay tablet should not exist", K(ret), K(ls_id), K(tablet_id)); } else { - const ObTabletMapKey key(ls_id, tablet_id); - ObTabletHandle new_tablet_handle; - ObTablet *new_tablet = nullptr; - int64_t pos = 0; ObTimeGuard time_guard("ObLSTabletService::replay_create_tablet", 1 * 1000 * 1000); + common::ObArenaAllocator allocator("ReplayCreate"); + const ObTabletMapKey key(ls_id, tablet_id); + ObTabletHandle tablet_hdl; + ObTablet *tablet = nullptr; + int64_t pos = 0; + ObMetaDiskAddr old_addr; ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); time_guard.click("Lock"); - - if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet(key, new_tablet_handle))) { - LOG_WARN("fail to acquire tablet", K(ret), K(key)); - } else if (FALSE_IT(new_tablet = new_tablet_handle.get_obj())) { - // do nothing - } else if (OB_FAIL(new_tablet->deserialize(allocator, buf, buf_len, pos))) { + if (OB_FAIL(ObTabletCreateDeleteHelper::create_tmp_tablet(key, allocator, tablet_hdl))) { + LOG_WARN("fail to create temporary tablet", K(ret), K(key)); + } else if (FALSE_IT(tablet = tablet_hdl.get_obj())) { + } else if (FALSE_IT(tablet->tablet_addr_ = disk_addr)) { + } else if (OB_FAIL(t3m->get_tablet_addr(key, old_addr))) { + LOG_WARN("fail to get tablet addr", K(ret), K(key)); + } else if (OB_FAIL(tablet->deserialize(allocator, buf, buf_len, pos))) { LOG_WARN("fail to deserialize tablet", K(ret), K(buf), K(buf_len), K(pos)); } else if (FALSE_IT(time_guard.click("Deserialize"))) { - } else if (OB_FAIL(new_tablet->init_shared_params(ls_id, tablet_id, - new_tablet->get_tablet_meta().max_sync_storage_schema_version_, - new_tablet->get_tablet_meta().max_serialized_medium_scn_, - new_tablet->get_tablet_meta().compat_mode_, - freezer))) { + } else if (OB_FAIL(tablet->init_shared_params(ls_id, + tablet_id, + tablet->get_tablet_meta().max_sync_storage_schema_version_, + tablet->get_tablet_meta().max_serialized_medium_scn_, + tablet->get_tablet_meta().compat_mode_, + freezer))) { LOG_WARN("failed to init shared params", K(ret), K(ls_id), K(tablet_id)); - } else if (OB_FAIL(refresh_tablet_addr(ls_id, tablet_id, disk_addr, new_tablet_handle))) { - LOG_WARN("failed to refresh tablet addr", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); - } else if (FALSE_IT(time_guard.click("RefreshAddr"))) { - } else if (OB_FAIL(new_tablet->start_ddl_if_need())) { + } else if (OB_FAIL(tablet_id_set_.set(tablet_id))) { + LOG_WARN("fail to set tablet id set", K(ret), K(tablet_id)); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_addr, disk_addr))) { + LOG_WARN("fail to compare and swap tablat in t3m", K(ret), K(key), K(old_addr), K(disk_addr)); + } else if (FALSE_IT(time_guard.click("CASwap"))) { + } else if (OB_FAIL(tablet->check_and_set_initial_state())) { + LOG_WARN("fail to check and set initial state", K(ret), K(key)); + } else if (OB_FAIL(tablet->start_ddl_if_need())) { LOG_WARN("start ddl if need failed", K(ret)); - } else if (OB_FAIL(try_pin_tablet_if_needed(new_tablet_handle))) { - LOG_WARN("failed to try pin tablet", K(ret), K(ls_id), K(tablet_id)); - } else { - FLOG_INFO("succeeded to create tablet for replay slog", K(ret), K(ls_id), K(tablet_id), K(new_tablet_handle)); + } else if (OB_FAIL(tablet->inc_macro_ref_cnt())) { + LOG_WARN("fail to increase macro blocks' ref cnt for meta and data", K(ret)); } - if (OB_FAIL(ret) && !b_exist) { + if (OB_SUCC(ret)) { + tablet_transfer_info = tablet->get_tablet_meta().transfer_info_; + FLOG_INFO("succeeded to create tablet for replay slog", K(ret), K(ls_id), K(tablet_id), KPC(tablet)); + } else { int tmp_ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); if (OB_TMP_FAIL(tablet_id_set_.erase(tablet_id))) { - if (OB_HASH_NOT_EXIST != tmp_ret) { + if (OB_HASH_NOT_EXIST != ret) { LOG_ERROR("fail to erase tablet id from set", K(tmp_ret), K(tablet_id)); } } - if (OB_TMP_FAIL(t3m->del_tablet(key))) { + if (OB_TMP_FAIL(inner_remove_tablet(key.ls_id_, key.tablet_id_))) { LOG_WARN("fail to erase tablet from meta memory manager", K(tmp_ret), K(key)); } } } - - return ret; -} - -int ObLSTabletService::try_pin_tablet_if_needed(const ObTabletHandle &tablet_handle) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - ObTablet *tablet = tablet_handle.get_obj(); - ObTabletTxMultiSourceDataUnit tx_data; - bool exist_on_memtable = false; - - if (OB_ISNULL(tablet)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, tablet is null", K(ret), K(tablet_handle)); - } else if (OB_FAIL(tablet->inner_get_tx_data(tx_data, exist_on_memtable))) { - LOG_WARN("failed to get tx data", K(ret), KPC(tablet)); - } else if (!tx_data.is_valid()) { - // tablet is not valid, do nothing - } else if (!tx_data.is_in_tx()) { - // tablet not in tx, do nothing - } else { - const ObLSID &ls_id = tablet->get_tablet_meta().ls_id_; - const ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; - const ObTabletMapKey key(ls_id, tablet_id); - if (OB_FAIL(t3m->insert_pinned_tablet(key))) { - LOG_WARN("failed to insert pinned tablet", K(ret), K(key)); - } - } - - return ret; -} - -int ObLSTabletService::check_and_get_tablet( - const common::ObTabletID &tablet_id, - ObTabletHandle &handle, - const int64_t timeout_us) -{ - int ret = OB_SUCCESS; - const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); - - if (OB_FAIL(ObTabletCreateDeleteHelper::check_and_get_tablet(key, handle, timeout_us))) { - if (OB_TABLET_NOT_EXIST == ret) { - LOG_DEBUG("failed to check and get tablet", K(ret), K(key), K(timeout_us)); - } else { - LOG_WARN("failed to check and get tablet", K(ret), K(key), K(timeout_us)); - } - } - return ret; } @@ -1816,41 +1872,29 @@ int ObLSTabletService::get_tablet_with_timeout( const common::ObTabletID &tablet_id, ObTabletHandle &handle, const int64_t retry_timeout_us, - const int64_t get_timeout_us) + const ObMDSGetTabletMode mode, + const share::SCN &snapshot) { int ret = OB_SUCCESS; const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); - int64_t check_timeout_us = get_timeout_us; - const int64_t timeout_step_us = 100 * 1000; // 100 ms + const int64_t timeout_step_us = 10 * 1000 * 1000; // 10s + const int64_t snapshot_version = snapshot.get_val_for_tx(); if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); } else if (OB_UNLIKELY(!tablet_id.is_valid() - || get_timeout_us < ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US)) { + || mode < ObMDSGetTabletMode::READ_ALL_COMMITED)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tablet_id), K(get_timeout_us)); - } else if (ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US != get_timeout_us - && ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US != get_timeout_us) { - check_timeout_us = MIN(retry_timeout_us - ObTimeUtil::current_time(), timeout_step_us); - if (check_timeout_us <= 0) { - ret = OB_TIMEOUT; - LOG_WARN("get tablet timeout", K(ret), K(retry_timeout_us), K(ObTimeUtil::current_time()), K(get_timeout_us)); + LOG_WARN("invalid args", K(ret), K(tablet_id), K(mode)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::check_and_get_tablet(key, handle, timeout_step_us, mode, snapshot_version))) { + while (OB_ALLOCATE_MEMORY_FAILED == ret && ObClockGenerator::getClock() < retry_timeout_us) { + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, handle, timeout_step_us, mode, snapshot_version); + } + if (OB_ALLOCATE_MEMORY_FAILED == ret) { + ret = OB_TIMEOUT; + LOG_WARN("get tablet timeout", K(ret), K(retry_timeout_us), K(ObTimeUtil::current_time()), K(mode)); } - } - - // Because ObTabletStatusChecker doesn't refresh tablet when memstore retired. The on demand refresh is - // executed by caller. From 4.2 after adapt to new MDS, ObTabletStatusChecker can be removed. - if (OB_SUCC(ret)) { - do { - if (OB_FAIL(ObTabletCreateDeleteHelper::check_and_get_tablet(key, handle, check_timeout_us))) { - if (OB_ALLOCATE_MEMORY_FAILED == ret || OB_TIMEOUT == ret) { - ret = OB_TIMEOUT; - } else { - LOG_WARN("fail to check and get tablet", K(ret), K(key), K(check_timeout_us)); - } - } - } while (OB_TIMEOUT == ret && retry_timeout_us > ObTimeUtil::current_time()); } return ret; } @@ -1873,46 +1917,49 @@ int ObLSTabletService::inner_table_scan( ObTableScanParam ¶m) { // NOTICE: ObTableScanParam for_update_ param is ignored here, - // upper layer will handle it, so here for_update_ is always false - int ret = OB_SUCCESS; - ObStoreCtx &store_ctx = iter.get_ctx_guard().get_store_ctx(); - int64_t data_max_schema_version = 0; - bool is_bounded_staleness_read = (NULL == param.trans_desc_) - ? false - : param.snapshot_.is_weak_read(); + // upper layer will handle it, so here for_update_ is always false + int ret = OB_SUCCESS; + ObStoreCtx &store_ctx = iter.get_ctx_guard().get_store_ctx(); + int64_t data_max_schema_version = 0; + bool is_bounded_staleness_read = (NULL == param.trans_desc_) + ? false + : param.snapshot_.is_weak_read(); + if (OB_UNLIKELY(!tablet_handle.is_valid()) || OB_UNLIKELY(!param.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(tablet_handle), K(param)); + } else if (is_bounded_staleness_read + && OB_FAIL(tablet_handle.get_obj()->get_max_schema_version(data_max_schema_version))) { + LOG_WARN("failed to get max schema version", K(ret), K(param)); + } else if (is_bounded_staleness_read + && OB_FAIL(tablet_handle.get_obj()->check_schema_version_for_bounded_staleness_read( + param.schema_version_, data_max_schema_version, param.index_id_))) { + //check schema_version with ref_table_id, because schema_version of scan_param is from ref table + LOG_WARN("check schema version for bounded staleness read fail", K(ret), K(param)); + //need to get store ctx of PG, cur_key_ saves the real partition + } else if (param.fb_snapshot_.is_min()) { + ret = OB_SNAPSHOT_DISCARDED; + } else { + const int64_t snapshot_version = store_ctx.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(); + const int64_t current_time = ObClockGenerator::getClock(); + const int64_t timeout = param.timeout_ - current_time; + if (OB_UNLIKELY(timeout <= 0)) { + ret = OB_TIMEOUT; + LOG_WARN("table scan timeout", K(ret), K(current_time), "table_scan_param_timeout", param.timeout_); + } else if (OB_FAIL(tablet_handle.get_obj()->check_snapshot_readable_with_cache(snapshot_version, timeout))) { + LOG_WARN("failed to check snapshot readable", K(ret), K(snapshot_version), K(timeout)); + } else if (param.need_switch_param_) { + if (OB_FAIL(iter.switch_param(param, tablet_handle))) { + LOG_WARN("failed to init table scan iterator, ", K(ret)); + } + } else if (OB_FAIL(iter.init(param, tablet_handle))) { + LOG_WARN("failed to init table scan iterator, ", K(ret)); + } + } - if (OB_UNLIKELY(!tablet_handle.is_valid()) || OB_UNLIKELY(!param.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tablet_handle), K(param)); - } else if (is_bounded_staleness_read - && OB_FAIL(tablet_handle.get_obj()->get_max_schema_version(data_max_schema_version))) { - LOG_WARN("failed to get max schema version", K(ret), K(param)); - } else if (is_bounded_staleness_read - && OB_FAIL(tablet_handle.get_obj()->check_schema_version_for_bounded_staleness_read( - param.schema_version_, data_max_schema_version, param.index_id_))) { - //check schema_version with ref_table_id, because schema_version of scan_param is from ref table - LOG_WARN("check schema version for bounded staleness read fail", K(ret), K(param)); - //need to get store ctx of PG, cur_key_ saves the real partition - } else if (param.fb_snapshot_.is_min()) { - ret = OB_SNAPSHOT_DISCARDED; - } else if (OB_FAIL(ObTabletBindingHelper::check_snapshot_readable( - tablet_handle, - store_ctx.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx()))) { - LOG_WARN("failed to check snapshot readable", K(ret)); - } else { - if (param.need_switch_param_) { - if (OB_FAIL(iter.switch_param(param, tablet_handle))) { - LOG_WARN("failed to init table scan iterator, ", K(ret)); - } - } else if (OB_FAIL(iter.init(param, tablet_handle))) { - LOG_WARN("failed to init table scan iterator, ", K(ret)); - } - } - - if (OB_FAIL(ret)) { - LOG_WARN("failed to do table scan", K(ret), K(param), K(*this), - K(data_max_schema_version)); - } + if (OB_FAIL(ret)) { + LOG_WARN("failed to do table scan", K(ret), K(param), K(*this), + K(data_max_schema_version)); + } return ret; } @@ -1936,58 +1983,108 @@ int ObLSTabletService::has_tablet( int ObLSTabletService::create_tablet( const share::ObLSID &ls_id, - const obrpc::ObBatchCreateTabletArg &arg, - const SCN &create_scn, - const obrpc::ObCreateTabletInfo &info, - common::ObIArray &tablet_handle_array, - NonLockedHashSet &data_tablet_id_set) + const common::ObTabletID &tablet_id, + const common::ObTabletID &data_tablet_id, + const share::SCN &create_scn, + const int64_t snapshot_version, + const share::schema::ObTableSchema &table_schema, + const lib::Worker::CompatMode &compat_mode, + ObTabletHandle &tablet_handle) { int ret = OB_SUCCESS; - const common::ObTabletID &data_tablet_id = info.data_tablet_id_; - const common::ObSArray &tablet_ids = info.tablet_ids_; + common::ObArenaAllocator tmp_allocator("CreateTab"); + common::ObArenaAllocator *allocator = nullptr; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + const ObTabletMapKey key(ls_id, tablet_id); + ObTablet *tablet = nullptr; + blocksstable::ObSSTable new_sstable; + blocksstable::ObSSTable *sstable = nullptr; + ObTabletCreateSSTableParam param; + ObTablet *tmp_tablet = nullptr; + ObFreezer *freezer = ls_->get_freezer(); + bool need_create_empty_major_sstable = false; + ObTabletTableStoreFlag table_store_flag; + table_store_flag.set_with_major_sstable(); + tablet_handle.reset(); - if (OB_UNLIKELY(!info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid create tablet info", K(ret), K(info)); - } else if (tablet_ids.count() == 1 && common::is_contain(tablet_ids, data_tablet_id)) { - // only data tablet. - if (OB_FAIL(build_single_data_tablet(ls_id, arg, create_scn, info, tablet_handle_array))) { - LOG_WARN("failed to build single data tablet", K(ret), K(ls_id), K(arg), K(create_scn), K(info)); + if (OB_FAIL(ObTabletCreateDeleteHelper::prepare_create_msd_tablet())) { + LOG_WARN("fail to prepare create msd tablet", K(ret)); + } + + { + ObBucketHashWLockGuard lock_guard(bucket_lock_, key.tablet_id_.hash()); + if (FAILEDx(ObTabletCreateDeleteHelper::create_msd_tablet(key, tablet_handle))) { + LOG_WARN("failed to create msd tablet", K(ret), K(key)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj()) + || OB_ISNULL(allocator = tablet_handle.get_allocator())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("new tablet is null", K(ret), KP(tablet), KP(allocator), K(tablet_handle)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::check_need_create_empty_major_sstable( + table_schema, need_create_empty_major_sstable))) { + LOG_WARN("failed to check need create sstable", K(ret)); + } else if (!need_create_empty_major_sstable) { + table_store_flag.set_without_major_sstable(); + LOG_INFO("no need to create sstable", K(ls_id), K(tablet_id), K(table_schema)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::build_create_sstable_param(table_schema, tablet_id, snapshot_version, param))) { + LOG_WARN("failed to build create sstable param", K(ret), K(tablet_id), + K(table_schema), K(snapshot_version), K(param)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, tmp_allocator, new_sstable))) { + LOG_WARN("failed to create sstable", K(ret), K(param)); + } else { + sstable = &new_sstable; } - } else { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid create tablet info", K(ret), K(info)); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(tablet->init(*allocator, ls_id, tablet_id, data_tablet_id, create_scn, snapshot_version, + table_schema, compat_mode, table_store_flag, sstable, freezer))) { + LOG_WARN("failed to init tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), + K(create_scn), K(snapshot_version), K(table_schema), K(compat_mode), K(table_store_flag)); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, tablet_handle))) { + LOG_WARN("failed to compare and swap tablet", K(ret), K(key), K(tablet_handle)); + } else if (OB_FAIL(tablet_id_set_.set(tablet_id))) { + LOG_WARN("fail to insert tablet id", K(ret), K(ls_id), K(tablet_id)); + } else { + report_tablet_to_rs(tablet_id); + } + } + + if (FAILEDx(ObTabletCreateDeleteHelper::push_msd_tablet_to_queue(tablet_handle))) { + LOG_WARN("failed to push msd tablet to queue", K(ret), K(tablet_handle)); } return ret; } -int ObLSTabletService::do_create_tablet( +int ObLSTabletService::create_inner_tablet( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const common::ObTabletID &data_tablet_id, - const common::ObIArray &index_tablet_array, - const SCN &create_scn, - const SCN &snapshot_version, + const share::SCN &create_scn, + const int64_t snapshot_version, const share::schema::ObTableSchema &table_schema, const lib::Worker::CompatMode &compat_mode, - const common::ObTabletID &lob_meta_tablet_id, - const common::ObTabletID &lob_piece_tablet_id, ObTabletHandle &tablet_handle) { int ret = OB_SUCCESS; + common::ObArenaAllocator allocator("LSCreateTab"); ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); const ObTabletMapKey key(ls_id, tablet_id); - ObTableHandleV2 table_handle; + ObSSTable new_sstable; + ObSSTable *sstable = nullptr; ObTabletCreateSSTableParam param; + ObTablet *tmp_tablet = nullptr; ObFreezer *freezer = ls_->get_freezer(); bool need_create_empty_major_sstable = false; ObTabletTableStoreFlag table_store_flag; table_store_flag.set_with_major_sstable(); - ObTabletHandle handle; + ObTabletHandle tmp_tablet_hdl; + ObMetaDiskAddr disk_addr; - if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet(key, handle))) { - LOG_WARN("failed to acquire tablet", K(ret), K(key)); + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + if (OB_FAIL(ObTabletCreateDeleteHelper::create_tmp_tablet(key, allocator, tmp_tablet_hdl))) { + LOG_WARN("failed to create temporary tablet", K(ret), K(key)); + } else if (OB_ISNULL(tmp_tablet = tmp_tablet_hdl.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("new tablet is null", K(ret), KPC(tmp_tablet), K(tmp_tablet_hdl)); } else if (OB_FAIL(ObTabletCreateDeleteHelper::check_need_create_empty_major_sstable( table_schema, need_create_empty_major_sstable))) { LOG_WARN("failed to check need create sstable", K(ret)); @@ -1995,213 +2092,201 @@ int ObLSTabletService::do_create_tablet( table_store_flag.set_without_major_sstable(); LOG_INFO("no need to create sstable", K(ls_id), K(tablet_id), K(table_schema)); } else if (OB_FAIL(ObTabletCreateDeleteHelper::build_create_sstable_param( - table_schema, tablet_id, snapshot_version.get_val_for_tx(), param))) { + table_schema, tablet_id, snapshot_version, param))) { LOG_WARN("failed to build create sstable param", K(ret), K(tablet_id), K(table_schema), K(snapshot_version), K(param)); - } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, table_handle))) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, allocator, new_sstable))) { LOG_WARN("failed to create sstable", K(ret), K(param)); + } else { + sstable = &new_sstable; } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(handle.get_obj()->init(ls_id, tablet_id, data_tablet_id, lob_meta_tablet_id, lob_piece_tablet_id, - create_scn, snapshot_version.get_val_for_tx(), table_schema, compat_mode, table_store_flag, table_handle, freezer))) { - LOG_WARN("failed to init tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), K(index_tablet_array), + } else if (OB_FAIL(tmp_tablet->init(allocator, ls_id, tablet_id, data_tablet_id, create_scn, snapshot_version, + table_schema, compat_mode, table_store_flag, sstable, freezer))) { + LOG_WARN("failed to init tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), K(create_scn), K(snapshot_version), K(table_schema), K(compat_mode), K(table_store_flag)); int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(t3m->del_tablet(key))) { + if (OB_TMP_FAIL(inner_remove_tablet(ls_id, tablet_id))) { LOG_ERROR("failed to delete tablet from t3m", K(ret), K(key), K(lbt())); ob_usleep(1000 * 1000); ob_abort(); } + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tmp_tablet, tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), K(tmp_tablet_hdl), K(tablet_handle)); + } else if (FALSE_IT(disk_addr = tablet_handle.get_obj()->get_tablet_addr())) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr))) { + LOG_WARN("failed to write update tablet slog", K(ret), K(tablet_handle)); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, tablet_handle))) { + LOG_WARN("failed to add tablet to meta mem mgr", K(ret), K(key), K(tablet_handle)); + } else if (OB_FAIL(tablet_id_set_.set(tablet_id))) { + LOG_ERROR("fail to set tablet id set", K(ret), K(tablet_id), K(lbt())); + ob_usleep(1000 * 1000); + ob_abort(); } else { - tablet_handle = handle; + LOG_INFO("create inner tablet success", K(key), K(disk_addr)); } - return ret; } -int ObLSTabletService::build_single_data_tablet( +int ObLSTabletService::create_transfer_in_tablet( const share::ObLSID &ls_id, - const obrpc::ObBatchCreateTabletArg &arg, - const SCN &create_scn, - const obrpc::ObCreateTabletInfo &info, - common::ObIArray &tablet_handle_array) -{ - int ret = OB_SUCCESS; - const common::ObTabletID &data_tablet_id = info.data_tablet_id_; - const common::ObSArray &tablet_ids = info.tablet_ids_; - const common::ObSArray &table_schemas = arg.table_schemas_; - const lib::Worker::CompatMode &compat_mode = info.compat_mode_; - common::ObSArray empty_array; - ObTabletHandle tablet_handle; - common::ObTabletID empty_tablet_id; - int64_t index = -1; - - if (OB_FAIL(get_tablet_schema_index(data_tablet_id, tablet_ids, index))) { - LOG_WARN("failed to get tablet schema index in array", K(ret), K(data_tablet_id)); - } else if (OB_UNLIKELY(index < 0)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, table schema index is invalid", K(ret), K(data_tablet_id), K(index)); - } else if (OB_FAIL(do_create_tablet(ls_id, data_tablet_id, data_tablet_id, empty_array, - create_scn, arg.major_frozen_scn_, table_schemas[info.table_schema_index_[index]], - compat_mode, empty_tablet_id, empty_tablet_id, tablet_handle))) { - LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(data_tablet_id), - K(create_scn), K(arg), K(compat_mode)); - } else if (OB_FAIL(tablet_handle_array.push_back(tablet_handle))) { - LOG_WARN("failed to insert tablet handle into array", K(ret), K(tablet_handle)); - } - - return ret; -} - -int ObLSTabletService::build_batch_create_tablet_arg( - const obrpc::ObBatchCreateTabletArg &old_arg, - const NonLockedHashSet &existed_tablet_id_set, - obrpc::ObBatchCreateTabletArg &new_arg) -{ - int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - const common::ObSArray &old_info_array = old_arg.tablets_; - - for (int64_t i = 0; OB_SUCC(ret) && i < old_info_array.count(); ++i) { - const obrpc::ObCreateTabletInfo &old_info = old_info_array[i]; - const common::ObSArray &old_tablet_id_array = old_info.tablet_ids_; - ObCreateTabletInfo new_info; - new_info.data_tablet_id_ = old_info.data_tablet_id_; - new_info.compat_mode_ = old_info.compat_mode_; - - for (int64_t j = 0; OB_SUCC(ret) && j < old_tablet_id_array.count(); ++j) { - const common::ObTabletID &old_tablet_id = old_tablet_id_array[j]; - tmp_ret = existed_tablet_id_set.exist_refactored(old_tablet_id); - if (OB_HASH_EXIST == tmp_ret) { - LOG_INFO("tablet id exists, should skip", K(old_tablet_id)); - } else if (OB_HASH_NOT_EXIST == tmp_ret) { - const int64_t old_table_schema_index = old_info.table_schema_index_[j]; - if (OB_FAIL(new_info.tablet_ids_.push_back(old_tablet_id))) { - LOG_WARN("failed to push back old tablet id", K(ret), K(old_tablet_id)); - } else if (OB_FAIL(new_info.table_schema_index_.push_back(old_table_schema_index))) { - LOG_WARN("failed to push back table schema index", K(ret), K(old_tablet_id)); - } - } else { - ret = tmp_ret; - LOG_WARN("unexpected error when checking old tablet id", K(ret), K(old_tablet_id)); - } - } - - if (OB_FAIL(ret)) { // do nothing - } else if (new_info.get_tablet_count() > 0) { - if (OB_FAIL(new_arg.tablets_.push_back(new_info))) { - LOG_WARN("failed to push back tablet info", K(ret), K(new_info)); - } - } else { - LOG_INFO("skip create tablet info", K(old_info)); - } - } - - // copy other members in arg - if (OB_FAIL(ret)) { // do nothing - } else { - new_arg.id_ = old_arg.id_; - new_arg.major_frozen_scn_ = old_arg.major_frozen_scn_; - - if (new_arg.get_tablet_count() > 0 && OB_FAIL(new_arg.table_schemas_.assign(old_arg.table_schemas_))) { - LOG_WARN("failed to assign table schemas", K(ret), K(old_arg)); - } - } - - return ret; -} - -int ObLSTabletService::add_batch_tablets( - const share::ObLSID &ls_id, - const NonLockedHashSet &data_tablet_id_set, - common::ObIArray &tablet_handle_array) -{ - int ret = OB_SUCCESS; - - const ObTablet* tablet = nullptr; - ObSArray disk_addr_arr; - const int64_t tablet_count = tablet_handle_array.count(); - - if (OB_FAIL(disk_addr_arr.reserve(tablet_count))) { - LOG_WARN("fail to reserve memory for disk_addr_array", K(ret), K(tablet_count)); - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(tablet_handle_array, disk_addr_arr))) { - LOG_WARN("fail to write slog", K(ret), K(ls_id)); - } - - int tmp_ret = OB_SUCCESS; - common::ObTabletID tablet_id; - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_count; ++i) { - const ObMetaDiskAddr &new_addr = disk_addr_arr[i]; - ObTabletHandle &tablet_handle = tablet_handle_array.at(i); - if (OB_ISNULL(tablet = tablet_handle.get_obj())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet is null", K(ret), K(tablet_handle)); - } else if (FALSE_IT(tablet_id = tablet->tablet_meta_.tablet_id_)) { - } else if (FALSE_IT(tmp_ret = data_tablet_id_set.exist_refactored(tablet_id))) { - } else if (OB_UNLIKELY(OB_HASH_EXIST != tmp_ret && OB_HASH_NOT_EXIST != tmp_ret)) { - ret = tmp_ret; - LOG_WARN("failed to check tablet id existence", K(ret), K(tablet_id)); - } else if ((OB_HASH_EXIST == tmp_ret) - && OB_FAIL(update_tablet_object_and_addr(tablet_handle, new_addr))) { - LOG_WARN("failed to update tablet object and addr", K(ret), K(tablet_handle), K(new_addr)); - } else if ((OB_HASH_NOT_EXIST == tmp_ret) - && OB_FAIL(refresh_tablet_addr(ls_id, tablet_id, new_addr, tablet_handle))) { - LOG_WARN("failed to refresh tablet addr", K(ret), K(ls_id), K(tablet_id), K(new_addr)); - } else { - FLOG_INFO("succeeded to add tablet", K(ret), K(tmp_ret), K(ls_id), K(tablet_id), - K(tablet_handle), K(new_addr), K(tablet_count)); - } - if (OB_FAIL(ret)) { - LOG_ERROR("failed to modify memory after writing slog", K(ret), K(lbt())); - ob_usleep(1000 * 1000); - ob_abort(); - } - } - - return ret; -} - -int ObLSTabletService::post_handle_batch_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg) + const ObMigrationTabletParam &tablet_meta, + ObTabletHandle &tablet_handle) { int ret = OB_SUCCESS; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - ObTabletMapKey key; - key.ls_id_ = arg.id_; + const ObTabletMapKey key(ls_id, tablet_meta.tablet_id_); + ObTablet *tablet = nullptr; + ObFreezer *freezer = ls_->get_freezer(); + common::ObArenaAllocator *allocator = nullptr; + ObTabletHandle old_tablet_hdl; - if (OB_UNLIKELY(!arg.is_valid())) { + LOG_INFO("prepare to init transfer in tablet", K(ret), K(ls_id), K(tablet_meta)); + ObTimeGuard time_guard("CreateTransferIn", 3000000/*3 seconds*/); + + bool cover_empty_shell = false; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls tablet service do not init", K(ret)); + } else if (!ls_id.is_valid() || !tablet_meta.is_valid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(arg)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const obrpc::ObCreateTabletInfo &info = arg.tablets_[i]; - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - const common::ObTabletID &tablet_id = info.tablet_ids_[j]; - key.tablet_id_ = tablet_id; - if (OB_FAIL(tablet_id_set_.erase(tablet_id))) { - if (OB_HASH_NOT_EXIST == ret) { - // tablet id does not exist in hash set - ret = OB_SUCCESS; - } else { - LOG_WARN("fail to erase tablet id from set", K(ret), K(tablet_id)); - } - } + LOG_WARN("create transfer in tablet get invalid argument", K(ret), K(ls_id), K(tablet_meta)); + } else if (OB_FAIL(direct_get_tablet(tablet_meta.tablet_id_, old_tablet_hdl))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_DEBUG("tablet not exist", K(ret), K(tablet_meta.tablet_id_)); + } else { + LOG_WARN("fail to get tablet", K(ret), K(tablet_meta.tablet_id_)); + } + } else if (!old_tablet_hdl.get_obj()->is_empty_shell()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("old tablet is not empty shell", K(ret), K(old_tablet_hdl)); + } else if (FALSE_IT(cover_empty_shell = true)) { + // Called in mds trans callback, slog won't be written. + } else if (OB_FAIL(do_remove_tablet(key))) { + LOG_WARN("failed to remove tablet", K(ret), K(key)); + } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(t3m->del_tablet(key))) { - if (OB_HASH_NOT_EXIST == ret) { - // key does not exist in hash map - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to delete tablet", K(ret), K(key)); - } - } + time_guard.click("Prepare"); + if (FAILEDx(ObTabletCreateDeleteHelper::prepare_create_msd_tablet())) { + LOG_WARN("failed to prepare create msd tablet", K(ret)); + } + + { + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_meta.tablet_id_.hash()); + time_guard.click("Lock"); + if (FAILEDx(ObTabletCreateDeleteHelper::create_msd_tablet(key, tablet_handle))) { + LOG_WARN("failed to create msd tablet", K(ret), K(key)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj()) + || OB_ISNULL(allocator = tablet_handle.get_allocator())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("new tablet is null", K(ret), KP(tablet), KP(allocator), K(tablet_handle)); + } else if (OB_FAIL(tablet->init(*allocator, tablet_meta, false/*is_update*/, freezer))) { + LOG_WARN("failed to init tablet", K(ret), K(ls_id), K(tablet_meta)); + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, tablet_handle))) { + LOG_WARN("failed to compare and swap tablet", K(ret), K(key), K(tablet_handle)); + } else if (OB_FAIL(tablet_id_set_.set(tablet_meta.tablet_id_))) { + LOG_WARN("fail to insert tablet id", K(ret), K(ls_id), K(tablet_meta)); + } else { + LOG_INFO("create transfer in tablet", K(ls_id), K(key), K(tablet_meta), K(cover_empty_shell)); + time_guard.click("Swap"); + } + } + + if (FAILEDx(ObTabletCreateDeleteHelper::push_msd_tablet_to_queue(tablet_handle))) { + LOG_WARN("failed to push msd tablet to queue", K(ret), K(tablet_handle)); + } + + return ret; +} + +int ObLSTabletService::create_empty_shell_tablet( + const ObMigrationTabletParam ¶m, + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + const share::ObLSID &ls_id = param.ls_id_; + const common::ObTabletID &tablet_id = param.tablet_id_; + const ObTabletMapKey key(ls_id, tablet_id); + ObTabletHandle old_tablet_hdl; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ls tablet svr hasn't been inited", K(ret)); + } else if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(key)); + } else if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_hdl))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_DEBUG("tablet not exist", K(ret), K(tablet_id)); + } else { + LOG_WARN("fail to get tablet", K(ret), K(tablet_id)); + } + } else if (OB_FAIL(remove_tablet(old_tablet_hdl))) { + LOG_WARN("failed to remove tablet", K(ret), K(key)); + } + + if (FAILEDx(ObTabletCreateDeleteHelper::prepare_create_msd_tablet())) { + LOG_WARN("fail to prepare create msd tablet", K(ret)); + } else { + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); // must lock after prepare + if (OB_FAIL(ObTabletCreateDeleteHelper::create_msd_tablet(key, tablet_handle))) { + LOG_WARN("fail to create msd tablet", K(ret), K(key)); + } else { + ObFreezer *freezer = ls_->get_freezer(); + ObTablet *new_tablet = tablet_handle.get_obj(); + ObMetaDiskAddr disk_addr; + if (OB_FAIL(new_tablet->init(*tablet_handle.get_allocator(), param, false/*is_update*/, freezer))) { + LOG_WARN("failed to init tablet", K(ret), K(param)); + } else if (OB_FAIL(ObTabletSlogHelper::write_empty_shell_tablet_slog(new_tablet, disk_addr))) { + LOG_WARN("fail to write update tablet slog", K(ret), K(ls_id), K(tablet_id)); + } else if (FALSE_IT(new_tablet->tablet_addr_ = disk_addr)) { + } else if (OB_FAIL(refresh_tablet_addr(ls_id, tablet_id, tablet_handle))) { + LOG_WARN("failed to refresh tablet addr", K(ret), K(ls_id), K(tablet_id), K(lbt())); + ob_usleep(1000 * 1000); + ob_abort(); + } else { + ls_->get_tablet_gc_handler()->set_tablet_gc_trigger(); + LOG_INFO("succeeded to create empty shell tablet", K(ret), K(key), K(param)); } } } + if (FAILEDx(ObTabletCreateDeleteHelper::push_msd_tablet_to_queue(tablet_handle))) { + LOG_WARN("fail to push msd tablet to queue", K(ret), K(tablet_handle)); + } + + return ret; +} + +int ObLSTabletService::rollback_tablet( + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObTabletMapKey key(ls_id, tablet_id); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("ls tablet service do not init", K(ret)); + } else if (!ls_id.is_valid() || !tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("rollback tablet get invalid argument", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(do_remove_tablet(key))) { + LOG_WARN("failed to delete tablet", K(ret), K(key)); + } else if (OB_FAIL(tablet_id_set_.erase(key.tablet_id_))) { + if (OB_HASH_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_DEBUG("tablet id does not exist, maybe has not been inserted yet", K(ret), K(key)); + } else { + //the caller checks abort if is required. + LOG_WARN("failed to erase tablet id", K(ret), K(key)); + } + } return ret; } @@ -2209,11 +2294,17 @@ int ObLSTabletService::create_memtable( const common::ObTabletID &tablet_id, const int64_t schema_version, const bool for_replay, - const SCN clog_checkpoint_scn) + const share::SCN clog_checkpoint_scn) { int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTabletHandle old_tablet_handle; + const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); + ObTabletHandle new_tablet_handle; + ObTabletMemberWrapper table_store; + ObTabletMemberWrapper autoinc_seq; + ObTimeGuard time_guard("ObLSTabletService::create_memtable", 10 * 1000); - ObTabletHandle handle; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); @@ -2225,23 +2316,41 @@ int ObLSTabletService::create_memtable( // during tablet creating new memtable and put it into table store. ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); time_guard.click("Lock"); - if (OB_FAIL(direct_get_tablet(tablet_id, handle))) { + if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_handle))) { LOG_WARN("fail to get tablet", K(ret), K(tablet_id)); - } else if (FALSE_IT(time_guard.click("get tablet"))) { - } else if (OB_UNLIKELY(!handle.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, invalid tablet handle", K(ret), K(handle)); - } else if (OB_FAIL(handle.get_obj()->create_memtable(schema_version, clog_checkpoint_scn, for_replay))) { - if (OB_MINOR_FREEZE_NOT_ALLOW != ret) { - LOG_WARN("fail to create memtable", K(ret), K(handle), K(schema_version), K(tablet_id)); - } + } else if (old_tablet_handle.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", old_tablet_handle.get_obj()); } else { - time_guard.click("tablet create_memtable"); + time_guard.click("get tablet"); + ObTablet &old_tablet = *(old_tablet_handle.get_obj()); + if (OB_FAIL(old_tablet.create_memtable(schema_version, clog_checkpoint_scn, for_replay))) { + if (OB_MINOR_FREEZE_NOT_ALLOW != ret) { + LOG_WARN("fail to create memtable", K(ret), K(new_tablet_handle), K(schema_version), K(tablet_id)); + } + } else if (FALSE_IT(time_guard.click("create memtable"))) { + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_tablet_handle, old_tablet_handle))) { + LOG_WARN("fail to compare and swap tablet", K(ret), K(key), K(old_tablet_handle)); + } } } return ret; } +int ObLSTabletService::check_allow_to_read() +{ + int ret = OB_SUCCESS; + AllowToReadMgr::AllowToReadInfo read_info; + allow_to_read_mgr_.load_allow_to_read_info(read_info); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (!read_info.allow_to_read()) { + ret = OB_REPLICA_NOT_READABLE; + LOG_WARN("ls is not allow to read", K(ret), KPC(ls_)); + } + return ret; +} + int ObLSTabletService::get_read_tables( const common::ObTabletID &tablet_id, const int64_t snapshot_version, @@ -2252,6 +2361,8 @@ int ObLSTabletService::get_read_tables( ObTabletHandle &handle = iter.tablet_handle_; iter.reset(); AllowToReadMgr::AllowToReadInfo read_info; + ObTabletMapKey key; + key.tablet_id_ = tablet_id; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -2263,8 +2374,14 @@ int ObLSTabletService::get_read_tables( } else if (!read_info.allow_to_read()) { ret = OB_REPLICA_NOT_READABLE; LOG_WARN("ls is not allow to read", K(ret), KPC(ls_)); - } else if (OB_FAIL(check_and_get_tablet(tablet_id, handle))) { - LOG_WARN("fail to check and get tablet", K(ret), K(tablet_id)); + } else if (FALSE_IT(key.ls_id_ = ls_->get_ls_id())) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::check_and_get_tablet(key, handle, + ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US, + ObMDSGetTabletMode::READ_READABLE_COMMITED, + snapshot_version))) { + if (OB_TABLET_NOT_EXIST != ret) { + LOG_WARN("fail to check and get tablet", K(ret), K(key), K(snapshot_version)); + } } else if (OB_UNLIKELY(!handle.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected error, invalid tablet handle", K(ret), K(handle)); @@ -2283,6 +2400,133 @@ int ObLSTabletService::get_read_tables( return ret; } +int ObLSTabletService::set_tablet_status( + const common::ObTabletID &tablet_id, + const ObTabletCreateDeleteMdsUserData &tablet_status, + mds::MdsCtx &ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!tablet_id.is_valid() || !tablet_status.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(tablet_id), K(tablet_status)); + } else { + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + ObTabletHandle tablet_handle; + if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_EAGAIN; + LOG_WARN("this tablet has been deleted, skip it", K(ret), K(tablet_id)); + } else { + LOG_WARN("fail to get tablet", K(ret)); + } + } else if (OB_FAIL(tablet_handle.get_obj()->set_tablet_status(tablet_status, ctx))) { + LOG_WARN("fail to set tablet status", K(ret), K(tablet_id), K(tablet_status)); + } else { + LOG_INFO("succeeded to set tablet status", K(ret), K(tablet_id), K(tablet_status)); + } + } + return ret; +} + +int ObLSTabletService::replay_set_tablet_status( + const common::ObTabletID &tablet_id, + const share::SCN &scn, + const ObTabletCreateDeleteMdsUserData &tablet_status, + mds::MdsCtx &ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!tablet_id.is_valid() || !tablet_status.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(tablet_id), K(tablet_status)); + } else { + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + ObTabletHandle tablet_handle; + if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_EAGAIN; + LOG_WARN("this tablet has been deleted, skip it", K(ret), K(tablet_id)); + } else { + LOG_WARN("fail to get tablet", K(ret)); + } + } else if (OB_FAIL(tablet_handle.get_obj()->replay_set_tablet_status(scn, tablet_status, ctx))) { + LOG_WARN("fail to replay set tablet status", K(ret), K(tablet_id), K(scn), K(tablet_status)); + } else { + LOG_INFO("succeeded to replay set tablet status", K(ret), K(tablet_id), K(scn), K(tablet_status)); + } + } + return ret; +} + +int ObLSTabletService::set_ddl_info( + const common::ObTabletID &tablet_id, + const ObTabletBindingMdsUserData &ddl_data, + mds::MdsCtx &ctx, + const int64_t timeout_us) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(tablet_id), K(ddl_data)); + } else { + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + ObTabletHandle tablet_handle; + if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_EAGAIN; + LOG_WARN("this tablet has been deleted, skip it", K(ret), K(tablet_id)); + } else { + LOG_WARN("fail to get tablet", K(ret)); + } + } else if (OB_FAIL(tablet_handle.get_obj()->set_ddl_info(ddl_data, ctx, timeout_us))) { + LOG_WARN("fail to set ddl info", K(ret), K(tablet_id), K(ddl_data), K(timeout_us)); + } else { + LOG_INFO("succeeded to set ddl info", K(ret), K(tablet_id), K(ddl_data), K(timeout_us)); + } + } + return ret; +} + +int ObLSTabletService::replay_set_ddl_info( + const common::ObTabletID &tablet_id, + const share::SCN &scn, + const ObTabletBindingMdsUserData &ddl_data, + mds::MdsCtx &ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(tablet_id), K(ddl_data)); + } else { + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + ObTabletHandle tablet_handle; + if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_EAGAIN; + LOG_WARN("this tablet has been deleted, skip it", K(ret), K(tablet_id)); + } else { + LOG_WARN("fail to get tablet", K(ret)); + } + } else if (OB_FAIL(tablet_handle.get_obj()->replay_set_ddl_info(scn, ddl_data, ctx))) { + LOG_WARN("fail to set ddl info", K(ret), K(tablet_id), K(ddl_data), K(scn)); + } else { + LOG_INFO("succeeded to set ddl info", K(ret), K(tablet_id), K(ddl_data), K(scn)); + } + } + return ret; +} + int ObLSTabletService::build_create_sstable_param_for_migration( const blocksstable::ObMigrationSSTableParam &mig_param, ObTabletCreateSSTableParam ¶m) @@ -2329,117 +2573,8 @@ int ObLSTabletService::build_create_sstable_param_for_migration( return ret; } -int ObLSTabletService::get_tablet_schema_index( - const common::ObTabletID &tablet_id, - const common::ObIArray &table_ids, - int64_t &index) -{ - int ret = OB_SUCCESS; - bool match = false; - - for (int64_t i = 0; !match && i < table_ids.count(); ++i) { - if (table_ids.at(i) == tablet_id) { - index = i; - match = true; - } - } - - if (!match) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("cannot find target tablet id in array", K(ret), K(tablet_id)); - } - - return ret; -} - -int ObLSTabletService::get_all_tablet_id_hash_array( - const obrpc::ObBatchCreateTabletArg &arg, - common::ObIArray &all_tablet_id_hash_array) -{ - int ret = OB_SUCCESS; - - for (int i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const obrpc::ObCreateTabletInfo &info = arg.tablets_[i]; - if (OB_FAIL(all_tablet_id_hash_array.push_back(info.data_tablet_id_.hash()))) { - LOG_WARN("failed to push back data tablet id", K(ret), - "data tablet id", info.data_tablet_id_); - } else { - // don't worry about duplicate data tablet id in arg, - // ObMultiBucketLockGuard will try to push the array into set to remove duplicate elements, - // and then sort the array to avoid possible dead lock - const common::ObSArray &tablet_ids = info.tablet_ids_; - for (int64_t j = 0; OB_SUCC(ret) && j < tablet_ids.count(); ++j) { - const common::ObTabletID &tablet_id = tablet_ids[j]; - if (OB_FAIL(all_tablet_id_hash_array.push_back(tablet_id.hash()))) { - LOG_WARN("failed to push back tablet id", K(ret), K(tablet_id)); - } - } - } - } - - return ret; -} - -int ObLSTabletService::parse_and_verify_delete_tablet_info( - const obrpc::ObBatchRemoveTabletArg &arg, - common::ObLinearHashMap &delete_tablet_infos) -{ - int ret = OB_SUCCESS; - const common::ObSArray &tablet_ids = arg.tablet_ids_; - bool b_exist = true; - ObTabletHandle tablet_handle; - - for (int64_t i = 0; i < tablet_ids.count(); ++i) { - const common::ObTabletID &tablet_id = tablet_ids.at(i); - if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - b_exist = false; - ret = OB_SUCCESS; - FLOG_INFO("tablet does not exist", K(ret), K(tablet_id)); - } else { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); - } - } else { - b_exist = true; - } - - if (OB_SUCC(ret) && b_exist) { - if (tablet_handle.get_obj()->is_data_tablet()) { - // delete data tablet and all local index tablets - DeleteTabletInfo info; - info.delete_data_tablet_ = true; - info.old_data_tablet_handle_ = tablet_handle; - if (OB_FAIL(delete_tablet_infos.insert(tablet_id, info))) { - LOG_WARN("failed to insert into hash map", K(ret), K(tablet_id)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, tablet handle is invalid", K(ret), K(tablet_handle)); - } - } - } - - return ret; -} - -int ObLSTabletService::get_all_tablet_id_hash_array( - common::ObLinearHashMap &delete_tablet_infos, - common::ObIArray &all_tablet_id_hash_array) -{ - int ret = OB_SUCCESS; - HashMapTabletGetFunctor functor(all_tablet_id_hash_array); - - // don't worry about duplicate data tablet id in arg, - // ObMultiBucketLockGuard will try to push the array into set to remove duplicate elements, - // and then sort the array to avoid possible dead lock - if (OB_FAIL(delete_tablet_infos.for_each(functor))) { - LOG_WARN("failed to iterate hash map to get all tablet id", K(ret)); - } - - return ret; -} - int ObLSTabletService::insert_rows( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const common::ObIArray &column_ids, @@ -2448,7 +2583,6 @@ int ObLSTabletService::insert_rows( { int ret = OB_SUCCESS; NG_TRACE(S_insert_rows_begin); - ObTabletHandle tablet_handle; int64_t afct_num = 0; int64_t dup_num = 0; ObTimeGuard timeguard(__func__, 3 * 1000 * 1000); @@ -2463,9 +2597,6 @@ int ObLSTabletService::insert_rows( || OB_ISNULL(row_iter)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(ctx), K(dml_param), K(column_ids), KP(row_iter)); - } else if (OB_FAIL(get_tablet_with_timeout( - ctx.tablet_id_, tablet_handle, dml_param.timeout_))) { - LOG_WARN("failed to check and get tablet", K(ret), K(ctx.tablet_id_)); } else if (dml_param.is_direct_insert()) { // direct-insert mode const ObTableSchemaParam::Columns &columns = dml_param.table_param_->get_data_table().get_columns(); bool is_heap_table = columns.at(0)->is_hidden(); @@ -2509,7 +2640,7 @@ int ObLSTabletService::insert_rows( } else if (!rows_info.is_inited() && OB_FAIL(rows_info.init(data_table, ctx, - tablet_handle.get_obj()->get_full_read_info()))) { + tablet_handle.get_obj()->get_rowkey_read_info()))) { LOG_WARN("Failed to init rows info", K(ret), K(data_table)); } else if (1 == row_count) { tbl_rows = &reserved_row; @@ -2619,6 +2750,7 @@ int ObLSTabletService::direct_insert_rows( } int ObLSTabletService::insert_row( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const common::ObIArray &column_ids, @@ -2630,7 +2762,6 @@ int ObLSTabletService::insert_row( { int ret = OB_SUCCESS; const ObTabletID &data_tablet_id = ctx.tablet_id_; - ObTabletHandle tablet_handle; ObTimeGuard timeguard(__func__, 3 * 1000 * 1000); if (OB_UNLIKELY(!is_inited_)) { @@ -2645,9 +2776,6 @@ int ObLSTabletService::insert_row( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(ctx), K(dml_param), K(column_ids), K(duplicated_column_ids), K(row), K(flag)); - } else if (OB_FAIL(get_tablet_with_timeout( - ctx.tablet_id_, tablet_handle, dml_param.timeout_))) { - LOG_WARN("failed to check and get tablet", K(ret), K(ctx.tablet_id_)); } else { ObArenaAllocator lob_allocator(ObModIds::OB_LOB_ACCESS_BUFFER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); ObDMLRunningCtx run_ctx(ctx, @@ -2705,6 +2833,7 @@ bool is_lob_update(ObDMLRunningCtx &run_ctx, const ObIArray &update_idx } int ObLSTabletService::update_rows( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const ObIArray &column_ids, @@ -2715,7 +2844,6 @@ int ObLSTabletService::update_rows( int ret = OB_SUCCESS; NG_TRACE(S_update_rows_begin); const ObTabletID &data_tablet_id = ctx.tablet_id_; - ObTabletHandle tablet_handle; int64_t afct_num = 0; int64_t dup_num = 0; int64_t got_row_count = 0; @@ -2733,9 +2861,6 @@ int ObLSTabletService::update_rows( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(ctx), K(dml_param), K(column_ids), K(updated_column_ids), KP(row_iter)); - } else if (OB_FAIL(get_tablet_with_timeout( - ctx.tablet_id_, tablet_handle, dml_param.timeout_))) { - LOG_WARN("failed to check and get tablet", K(ret), K(ctx.tablet_id_)); } else { timeguard.click("Get"); ObArenaAllocator lob_allocator(ObModIds::OB_LOB_ACCESS_BUFFER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); @@ -2880,6 +3005,7 @@ int ObLSTabletService::update_rows( } int ObLSTabletService::put_rows( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const ObIArray &column_ids, @@ -2888,7 +3014,6 @@ int ObLSTabletService::put_rows( { int ret = OB_SUCCESS; const ObTabletID &data_tablet_id = ctx.tablet_id_; - ObTabletHandle tablet_handle; int64_t afct_num = 0; ObTimeGuard timeguard(__func__, 3 * 1000 * 1000); @@ -2902,9 +3027,6 @@ int ObLSTabletService::put_rows( || OB_ISNULL(row_iter)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(ctx), K(dml_param), K(column_ids), KP(row_iter)); - } else if (OB_FAIL(get_tablet_with_timeout( - ctx.tablet_id_, tablet_handle, dml_param.timeout_))) { - LOG_WARN("failed to check and get tablet", K(ret), K(ctx.tablet_id_)); } else { ObArenaAllocator lob_allocator(ObModIds::OB_LOB_ACCESS_BUFFER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); ObDMLRunningCtx run_ctx(ctx, @@ -2952,6 +3074,7 @@ int ObLSTabletService::put_rows( } int ObLSTabletService::delete_rows( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const ObIArray &column_ids, @@ -2961,7 +3084,6 @@ int ObLSTabletService::delete_rows( int ret = OB_SUCCESS; NG_TRACE(S_delete_rows_begin); const ObTabletID &data_tablet_id = ctx.tablet_id_; - ObTabletHandle tablet_handle; ObRowReshape *row_reshape = nullptr; int64_t afct_num = 0; ObTimeGuard timeguard(__func__, 3 * 1000 * 1000); @@ -2974,9 +3096,6 @@ int ObLSTabletService::delete_rows( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(dml_param), K(column_ids), KP(row_iter), K(ctx)); - } else if (OB_FAIL(get_tablet_with_timeout( - ctx.tablet_id_, tablet_handle, dml_param.timeout_))) { - LOG_WARN("failed to check and get tablet", K(ret), K(ctx.tablet_id_)); } else { ObArenaAllocator lob_allocator(ObModIds::OB_LOB_ACCESS_BUFFER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); ObDMLRunningCtx run_ctx(ctx, @@ -3019,6 +3138,7 @@ int ObLSTabletService::delete_rows( } int ObLSTabletService::lock_rows( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const int64_t abs_lock_timeout, @@ -3032,7 +3152,6 @@ int ObLSTabletService::lock_rows( int ret = OB_SUCCESS; const ObTabletID &data_tablet_id = ctx.tablet_id_; ObTimeGuard timeguard(__func__, 3 * 1000 * 1000); - ObTabletHandle tablet_handle; int64_t afct_num = 0; ObColDescArray col_desc; common::ObSEArray column_ids; @@ -3046,9 +3165,6 @@ int ObLSTabletService::lock_rows( || OB_ISNULL(row_iter))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(ctx), K(dml_param), KPC(row_iter)); - } else if (OB_FAIL(get_tablet_with_timeout( - ctx.tablet_id_, tablet_handle, dml_param.timeout_))) { - LOG_WARN("failed to check and get tablet", K(ret), K(ctx.tablet_id_)); } else { timeguard.click("Get"); ObDMLRunningCtx run_ctx(ctx, @@ -3103,6 +3219,7 @@ int ObLSTabletService::lock_rows( } int ObLSTabletService::lock_row( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const int64_t abs_lock_timeout, @@ -3114,7 +3231,6 @@ int ObLSTabletService::lock_row( int ret = OB_SUCCESS; const ObTabletID &data_tablet_id = ctx.tablet_id_; ObTimeGuard timeguard(__func__, 3 * 1000 * 1000); - ObTabletHandle tablet_handle; int64_t afct_num = 0; ObColDescArray col_desc; @@ -3124,9 +3240,6 @@ int ObLSTabletService::lock_row( } else if (OB_UNLIKELY(!ctx.is_valid() || !dml_param.is_valid() || !row.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(ctx), K(dml_param), K(row)); - } else if (OB_FAIL(get_tablet_with_timeout( - ctx.tablet_id_, tablet_handle, dml_param.timeout_))) { - LOG_WARN("failed to check and get tablet", K(ret), K(ctx.tablet_id_)); } else { ObDMLRunningCtx run_ctx(ctx, dml_param, @@ -3162,7 +3275,6 @@ int ObLSTabletService::trim_rebuild_tablet( const bool is_rollback) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); @@ -3192,6 +3304,7 @@ int ObLSTabletService::create_or_update_migration_tablet( const common::ObTabletID &tablet_id = mig_tablet_param.tablet_id_; ObTabletHandle tablet_handle; bool b_exist = false; + const bool need_create_msd_tablet = mig_tablet_param.is_empty_shell(); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -3199,18 +3312,26 @@ int ObLSTabletService::create_or_update_migration_tablet( } else if (OB_UNLIKELY(is_stopped_)) { ret = OB_NOT_RUNNING; LOG_WARN("tablet service stopped", K(ret)); - } else if (OB_UNLIKELY(!mig_tablet_param.is_valid()) - || OB_UNLIKELY(ls_id != ls_->get_ls_id())) { + } else if (!mig_tablet_param.is_empty_shell() + && (OB_UNLIKELY(!mig_tablet_param.is_valid()) + || OB_UNLIKELY(ls_id != ls_->get_ls_id()))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(mig_tablet_param), K_(ls)); - } else if (OB_FAIL(has_tablet(ls_id, tablet_id, b_exist))) { - LOG_WARN("failed to check tablet existence", K(ls_id), K(tablet_id)); - } else if (b_exist - && OB_FAIL(migrate_update_tablet(mig_tablet_param))) { - LOG_WARN("failed to update tablet meta", K(ret), K(tablet_id), K(mig_tablet_param)); - } else if (!b_exist - && OB_FAIL(migrate_create_tablet(mig_tablet_param, tablet_handle))) { - LOG_WARN("failed to migrate create tablet", K(ret), K(mig_tablet_param)); + } else if (need_create_msd_tablet) { + if (OB_FAIL(create_empty_shell_tablet(mig_tablet_param, tablet_handle))) { + LOG_WARN("failed to create empty shell tablet", K(ret), K(tablet_id), K(mig_tablet_param)); + } + } else { + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + if (OB_FAIL(has_tablet(ls_id, tablet_id, b_exist))) { + LOG_WARN("failed to check tablet existence", K(ls_id), K(tablet_id)); + } else if (b_exist + && OB_FAIL(migrate_update_tablet(mig_tablet_param))) { + LOG_WARN("failed to update tablet meta", K(ret), K(tablet_id), K(mig_tablet_param)); + } else if (!b_exist + && OB_FAIL(migrate_create_tablet(mig_tablet_param, tablet_handle))) { + LOG_WARN("failed to migrate create tablet", K(ret), K(mig_tablet_param)); + } } return ret; @@ -3223,7 +3344,9 @@ int ObLSTabletService::rebuild_create_tablet( int ret = OB_SUCCESS; const share::ObLSID &ls_id = mig_tablet_param.ls_id_; const common::ObTabletID &tablet_id = mig_tablet_param.tablet_id_; + const ObTabletMapKey key(ls_id, tablet_id); bool b_exist = false; + const bool need_create_msd_tablet = mig_tablet_param.is_empty_shell() && !keep_old; ObTabletHandle new_tablet_handle; ObTabletHandle old_tablet_handle; @@ -3237,114 +3360,39 @@ int ObLSTabletService::rebuild_create_tablet( || OB_UNLIKELY(ls_id != ls_->get_ls_id())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(mig_tablet_param), K_(ls)); - } else if (OB_FAIL(has_tablet(ls_id, tablet_id, b_exist))) { - LOG_WARN("fail to check tablet existence", K(ls_id), K(tablet_id)); - } else if (!b_exist && - OB_FAIL(migrate_create_tablet(mig_tablet_param, new_tablet_handle))) { - LOG_WARN("failed to rebuild create tablet", K(ret), K(tablet_id), K(mig_tablet_param)); - } else if (b_exist && !keep_old && - OB_FAIL(migrate_update_tablet(mig_tablet_param))) { - LOG_WARN("failed to rebuild create tablet", K(ret), K(tablet_id), K(mig_tablet_param)); - } else if (b_exist && keep_old) { - if (OB_FAIL(check_and_get_tablet(tablet_id, old_tablet_handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { - LOG_WARN("failed to check and get tablet", K(ret), K(tablet_id)); - } else if (OB_UNLIKELY(old_tablet_handle.get_obj()->get_tablet_meta().has_next_tablet_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("number of nodes on list exceeds 2", K(ret)); - } else if (OB_FAIL(rebuild_tablet_with_old(mig_tablet_param, old_tablet_handle))) { - LOG_WARN("failed to rebuild tablet and maintain linked list", K(ret), K(tablet_id)); - } - } - - return ret; -} - -int ObLSTabletService::create_migration_sstable( - const blocksstable::ObMigrationSSTableParam &mig_sstable_param, - const ObSSTableStatus status, - ObTableHandleV2 &table_handle) -{ - int ret = OB_SUCCESS; - ObTabletCreateSSTableParam create_param; - ObTabletHandle tablet_handle; - - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!mig_sstable_param.is_valid() - || (ObSSTableStatus::SSTABLE_READY_FOR_REMOTE_LOGICAL_READ != status - && ObSSTableStatus::SSTABLE_READY_FOR_REMOTE_PHYTSICAL_READ != status - && ObSSTableStatus::SSTABLE_WRITE_BUILDING != status))) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(mig_sstable_param), K(status)); - } else if (OB_FAIL(build_create_sstable_param_for_migration(mig_sstable_param, create_param))) { - LOG_WARN("fail to build create sstable param", K(ret), K(mig_sstable_param)); - } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(create_param, table_handle))) { - LOG_WARN("fail to create sstable", K(ret), K(create_param)); - } else if (ObSSTableStatus::SSTABLE_WRITE_BUILDING != status) { - ObSSTable *sstable = nullptr; - if (OB_FAIL(table_handle.get_sstable(sstable))) { - LOG_WARN("fail to get sstable", K(ret), KP(sstable)); - } else if (OB_ISNULL(sstable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, sstable is nullptr", K(ret), KP(sstable)); - } else if (OB_FAIL(sstable->set_status_for_read(status))) { - LOG_WARN("fail to set status for sstable", K(ret), K(status), KPC(sstable)); - } - } - return ret; -} - -int ObLSTabletService::finish_copy_migration_sstable( - const ObTabletID &tablet_id, - const ObITable::TableKey &sstable_key) -{ - int ret = OB_SUCCESS; - const ObTabletMapKey key(ls_->get_ls_id(), tablet_id); - ObMetaDiskAddr disk_addr; - ObTabletHandle tablet_handle; - ObTableHandleV2 sstable_handle; - ObSSTable *sstable = nullptr; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - - ObTimeGuard time_guard("ObLSTabletService::finish_copy_migration_sstable", 1 * 1000 * 1000); - ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); - time_guard.click("Lock"); - - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(is_stopped_)) { - ret = OB_NOT_RUNNING; - LOG_WARN("tablet service stopped", K(ret)); - } else if (OB_UNLIKELY(!tablet_id.is_valid() || !sstable_key.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(tablet_id), K(sstable_key)); - } else if (OB_FAIL(check_and_get_tablet(tablet_id, tablet_handle))) { - LOG_WARN("fail to check and get tablet", K(ret), K(tablet_id)); - } else if (FALSE_IT(time_guard.click("GetTablet"))) { - } else if (OB_FAIL(tablet_handle.get_obj()->get_table_store().get_table( - sstable_key, sstable_handle))) { - LOG_WARN("fail to get sstable", K(ret), K(tablet_id), K(sstable_key)); - } else if (OB_FAIL(sstable_handle.get_sstable(sstable))) { - LOG_WARN("fail to get sstable", K(ret), KP(sstable)); - } else if (OB_ISNULL(sstable)) { + } else if (OB_UNLIKELY(mig_tablet_param.is_empty_shell() && keep_old)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, sstable is nullptr", K(ret), KP(sstable)); - } else if (OB_FAIL(sstable->set_status_for_read(ObSSTableStatus::SSTABLE_READY_FOR_READ))) { - LOG_WARN("fail to set status for sstable", K(ret), KPC(sstable)); - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(tablet_handle, disk_addr))) { - LOG_WARN("fail to write update tablet slog", K(ret), K(tablet_handle), K(disk_addr)); - } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, disk_addr, - tablet_handle, tablet_handle))) { - LOG_ERROR("failed to create tablet", K(ret), K(key), K(disk_addr), K(tablet_handle), K(lbt())); - ob_usleep(1000 * 1000); - ob_abort(); + LOG_WARN("unexpected error, rebuild create an empty shell tablet, but still need the old tablet", K(ret), + K(mig_tablet_param), K(keep_old)); + } else if (need_create_msd_tablet) { + if (OB_FAIL(create_empty_shell_tablet(mig_tablet_param, new_tablet_handle))) { + LOG_WARN("failed to create empty shell tablet", K(ret), K(tablet_id), K(mig_tablet_param)); + } } else { - time_guard.click("CASwap"); - LOG_INFO("copy migration sstable succeed", K(ret), K(key), K(disk_addr)); + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + if (OB_FAIL(has_tablet(ls_id, tablet_id, b_exist))) { + LOG_WARN("fail to check tablet existence", K(ls_id), K(tablet_id)); + } else if (!b_exist && + OB_FAIL(migrate_create_tablet(mig_tablet_param, new_tablet_handle))) { + LOG_WARN("failed to rebuild create tablet", K(ret), K(tablet_id), K(mig_tablet_param)); + } else if (b_exist && !keep_old && + OB_FAIL(migrate_update_tablet(mig_tablet_param))) { + LOG_WARN("failed to rebuild create tablet", K(ret), K(tablet_id), K(mig_tablet_param)); + } else if (b_exist && keep_old) { + if (OB_FAIL(ObTabletCreateDeleteHelper::check_and_get_tablet(key, old_tablet_handle, + ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US, + ObMDSGetTabletMode::READ_WITHOUT_CHECK, + ObTransVersion::MAX_TRANS_VERSION))) { + LOG_WARN("failed to check and get tablet", K(ret), K(key)); + } else if (OB_UNLIKELY(old_tablet_handle.get_obj()->get_tablet_meta().has_next_tablet_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("number of nodes on list exceeds 2", K(ret)); + } else if (OB_FAIL(rebuild_tablet_with_old(mig_tablet_param, old_tablet_handle))) { + LOG_WARN("failed to rebuild tablet and maintain linked list", K(ret), K(tablet_id)); + } + } } + return ret; } @@ -3353,12 +3401,9 @@ int ObLSTabletService::build_ha_tablet_new_table_store( const ObBatchUpdateTableStoreParam ¶m) { int ret = OB_SUCCESS; + ObArenaAllocator allocator("BuildHaTab"); ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); ObMetaDiskAddr disk_addr; - ObFreezer *freezer = nullptr; - memtable::ObIMemtable *imemtable = nullptr; - ObTableHandleV2 memtable_handle; - bool is_tablet_freeze = false; ObTimeGuard time_guard("ObLSTabletService::build_ha_tablet_new_table_store", 1 * 1000 * 1000); if (IS_NOT_INIT) { @@ -3370,11 +3415,9 @@ int ObLSTabletService::build_ha_tablet_new_table_store( } else if (OB_UNLIKELY(!tablet_id.is_valid() || !param.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(tablet_id), K(param)); - } else if (OB_ISNULL(freezer = ls_->get_freezer())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("freezer should not be NULL", K(ret), KP(freezer), KPC(ls_)); } else { ObTabletHandle old_tablet_handle; + ObTabletHandle tmp_tablet_handle; ObTabletHandle new_tablet_handle; ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); @@ -3382,89 +3425,30 @@ int ObLSTabletService::build_ha_tablet_new_table_store( if (OB_FAIL(direct_get_tablet(tablet_id, old_tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (old_tablet_handle.get_obj()->is_empty_shell()) { + LOG_INFO("old tablet is empty shell tablet, should skip this operation", K(ret), "old_tablet", old_tablet_handle.get_obj()); } else { time_guard.click("GetTablet"); ObTablet *old_tablet = old_tablet_handle.get_obj(); - ObTablet *new_tablet = nullptr; + ObTablet *tmp_tablet = nullptr; const share::ObLSID &ls_id = ls_->get_ls_id(); const ObTabletMapKey key(ls_id, tablet_id); - ObTabletTxMultiSourceDataUnit tx_data; - ObTabletBindingInfo ddl_data; - ObTabletAutoincSeq autoinc_seq; - //In order to merge tablet meta - //it is necessary to make the left side of the newly created memtable start from clog_checkpinoit_ts - //the new memtable can be stuck during the creation of the tablet, it is safe here - // try tablet freeze - if (!tablet_id.is_ls_inner_tablet()) { - if (nullptr != param.tablet_meta_ - && old_tablet->get_clog_checkpoint_scn() < param.tablet_meta_->clog_checkpoint_scn_) { - if (OB_FAIL(freezer->tablet_freeze_for_replace_tablet_meta(tablet_id, memtable_handle))) { - LOG_WARN("failed to freeze tablet", K(ret), K(tablet_id), KPC(old_tablet)); - } else { - is_tablet_freeze = true; - } - time_guard.click("TabletFreeze"); - } - - if (OB_FAIL(ret)) { - } else if (!is_tablet_freeze) { - } else if (!memtable_handle.is_valid()) { - } else if (OB_FAIL(memtable_handle.get_memtable(imemtable))) { - LOG_WARN("failed to get memtable", K(ret), K(tablet_id)); - } else { - memtable::ObMemtable *memtable = static_cast(imemtable); - if (OB_FAIL(memtable->resolve_right_boundary_for_migration())) { - LOG_WARN("failed to resolve right boundary", K(ret), K(tablet_id)); - } - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(old_tablet->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data from old tablet", K(ret), K(tablet_id)); - } else if (OB_FAIL(old_tablet->get_ddl_data(ddl_data))) { - LOG_WARN("failed to get tx data from old tablet", K(ret), K(tablet_id)); - } else if (OB_FAIL(old_tablet->get_latest_autoinc_seq(autoinc_seq))) { - LOG_WARN("failed to get autoinc seq from old tablet", K(ret)); - } else if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet(key, new_tablet_handle, true/*only acquire*/))) { + if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator, tmp_tablet_handle))) { LOG_WARN("failed to acquire tablet", K(ret), K(key)); - } else if (FALSE_IT(new_tablet = new_tablet_handle.get_obj())) { - } else if (OB_FAIL(new_tablet->init(param, *old_tablet, tx_data, ddl_data, autoinc_seq))) { + } else if (FALSE_IT(tmp_tablet = tmp_tablet_handle.get_obj())) { + } else if (OB_FAIL(tmp_tablet->init(allocator, param, *old_tablet))) { LOG_WARN("failed to init tablet", K(ret), KPC(old_tablet)); } else if (FALSE_IT(time_guard.click("InitTablet"))) { - } else { - common::ObSArray memtables; - const SCN &clog_checkpoint_scn = new_tablet->get_clog_checkpoint_scn(); - int64_t snapshot_version = new_tablet->get_snapshot_version(); - if (OB_FAIL(new_tablet->get_memtables(memtables, true/*need_active*/))) { - LOG_WARN("failed to get memtables", K(ret), K(key)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < memtables.count(); ++i) { - const memtable::ObMemtable *memtable = static_cast(memtables.at(i)); - if (OB_UNLIKELY(memtable->get_end_scn() < clog_checkpoint_scn)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("memtable end log ts is smaller than clog checkpoint ts", K(ret), - "end_scn", memtable->get_end_scn(), K(clog_checkpoint_scn)); - } else if (memtable->get_end_scn() == clog_checkpoint_scn) { - if (memtable->get_snapshot_version() <= snapshot_version) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("memtable snapshot version is no bigger than tablet snapshot version", K(ret), - "memtable_snapshot_version", memtable->get_snapshot_version(), K(snapshot_version)); - } - } - } - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(new_tablet_handle, disk_addr))) { - LOG_WARN("fail to write update tablet slog", K(ret), K(new_tablet_handle), K(disk_addr)); + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tmp_tablet, new_tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tmp_tablet), K(new_tablet_handle)); + } else if (FALSE_IT(time_guard.click("Persist"))) { + } else if (FALSE_IT(disk_addr = new_tablet_handle.get_obj()->tablet_addr_)) { + } else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(ls_id, tablet_id, disk_addr))) { + LOG_WARN("fail to write update tablet slog", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); } else if (FALSE_IT(time_guard.click("WrSlog"))) { - } else if (OB_FAIL(old_tablet->set_memtable_clog_checkpoint_scn(param.tablet_meta_))) { - LOG_WARN("failed to set memtable clog checkpoint ts", K(ret), KPC(old_tablet), K(param)); - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, disk_addr, old_tablet_handle, new_tablet_handle))) { + } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, old_tablet_handle, new_tablet_handle))) { LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(disk_addr)); ob_usleep(1000 * 1000); ob_abort(); @@ -3474,88 +3458,6 @@ int ObLSTabletService::build_ha_tablet_new_table_store( } } } - - if (is_tablet_freeze) { - int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(freezer->handle_frozen_memtable_for_replace_tablet_meta(tablet_id, memtable_handle))) { - LOG_WARN("failed to handle_frozen_memtable_for_replace_tablet_meta", K(tmp_ret), K(tablet_id), K(param)); - ret = OB_SUCC(ret) ? tmp_ret : ret; - } - } - - // check time guard - const int64_t cost_time = time_guard.get_diff(); - if (cost_time > 10 * 1000 * 1000) { - LOG_WARN("build ha new table store costs too much time", K(ret), K(tablet_id), K(cost_time), K(time_guard), K(lbt())); - } - - return ret; -} - -int ObLSTabletService::verify_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - NonLockedHashSet &existed_tablet_id_set) -{ - int ret = OB_SUCCESS; - const share::ObLSID &ls_id = arg.id_; - bool b_exist = true; - ObTabletHandle tablet_handle; - - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &tablet_arg = arg.tablets_[i]; - const common::ObSArray &tablet_ids = tablet_arg.tablet_ids_; - const common::ObTabletID &data_tablet_id = tablet_arg.data_tablet_id_; - bool is_pure_index = true; - bool is_data_tablet_exist = true; - for (int64_t k = 0; is_pure_index && k < tablet_ids.count(); ++k) { - if (tablet_ids[k] == data_tablet_id) { - is_pure_index = false; - } - } - - if (is_pure_index) { - ObTabletHandle data_tablet_handle; - if (OB_FAIL(direct_get_tablet(data_tablet_id, data_tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - is_data_tablet_exist = false; - ret = OB_SUCCESS; - // TODO (bowen.gbw): data tablet might be removed when replaying index tablet creation - // so that we should skip such clog to avoid replaying failure. - // Temp fix: consider those index tablets as existed ones and skip in replaying - // Final solution: Multi Data Source Transaction - FLOG_INFO("data tablet does not exist, need skip create pure index tablets", K(ret), K(data_tablet_id)); - } else { - LOG_WARN("failed to get tablet", K(ret), K(data_tablet_id)); - } - } - } - - for (int64_t j = 0; OB_SUCC(ret) && j < tablet_ids.count(); ++j) { - const common::ObTabletID &tablet_id = tablet_ids[j]; - if (is_pure_index && !is_data_tablet_exist) { - b_exist = true; - } else if (OB_FAIL(direct_get_tablet(tablet_id, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - b_exist = false; - ret = OB_SUCCESS; - LOG_INFO("tablet does not exist", K(ret), K(tablet_id)); - } else { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); - } - } else { - b_exist = true; - } - - if (OB_SUCC(ret) && b_exist) { - FLOG_INFO("tablet already exists", K(ls_id), K(tablet_id)); - - if (OB_FAIL(existed_tablet_id_set.set_refactored(tablet_id))) { - LOG_WARN("failed to insert into hash set", K(ret), K(tablet_id)); - } - } - } - } - return ret; } @@ -3573,7 +3475,7 @@ int ObLSTabletService::need_check_old_row_legitimacy(ObDMLRunningCtx &run_ctx, LOG_WARN("check has udf column failed", K(ret)); } else if (need_check) { is_udf = true; - ObTableStoreIterator &table_iter = data_table.tablet_iter_.table_iter_; + ObTableStoreIterator &table_iter = *data_table.tablet_iter_.table_iter(); while (OB_SUCC(ret) && !need_check) { ObITable *table_ptr = nullptr; if (OB_FAIL(table_iter.get_next(table_ptr))) { @@ -3721,6 +3623,10 @@ int ObLSTabletService::check_old_row_legitimacy( } else if (OB_TMP_FAIL(check_real_leader_for_4377_(run_ctx.store_ctx_.ls_id_))) { ret = tmp_ret; LOG_WARN("check real leader for 4377 found exception", K(ret), K(old_row), K(data_table)); + } else if (OB_TMP_FAIL(check_need_rollback_in_transfer_for_4377_(run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_, + data_tablet_handle))) { + ret = tmp_ret; + LOG_WARN("check need rollback in transfer for 4377 found exception", K(ret), K(old_row), K(data_table)); } else { ObString func_name = ObString::make_string("check_old_row_legitimacy"); LOG_USER_ERROR(OB_ERR_DEFENSIVE_CHECK, func_name.length(), func_name.ptr()); @@ -3935,30 +3841,14 @@ int ObLSTabletService::check_lob_tablet_valid(ObTabletHandle &data_tablet) { int ret = OB_SUCCESS; bool is_valid_aux_lob_table = false; - ObTabletBindingInfo ddl_data; - if (OB_FAIL(data_tablet.get_obj()->get_ddl_data(ddl_data))) { + ObTabletBindingMdsUserData ddl_data; + if (OB_FAIL(data_tablet.get_obj()->ObITabletMdsInterface::get_ddl_data(share::SCN::max_scn(), ddl_data))) { LOG_WARN("failed to get ddl data from tablet", K(ret), K(data_tablet)); } else { is_valid_aux_lob_table = ddl_data.lob_meta_tablet_id_.is_valid() && ddl_data.lob_piece_tablet_id_.is_valid(); if (!is_valid_aux_lob_table) { - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(data_tablet.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("fail to get tx data", K(ret), K(data_tablet)); - } else if (tx_data.is_in_tx()) { - ret = OB_SCHEMA_EAGAIN; - LOG_WARN("do retry for data tablet is in tx, maybe wait for lob tablet finish", K(ret), K(ddl_data)); - } else { - // maybe has committed, refresh binding info and check once - if (OB_FAIL(data_tablet.get_obj()->get_ddl_data(ddl_data))) { - LOG_WARN("failed to get ddl data from tablet", K(ret), K(data_tablet)); - } else { - is_valid_aux_lob_table = ddl_data.lob_meta_tablet_id_.is_valid() && ddl_data.lob_piece_tablet_id_.is_valid(); - if (!is_valid_aux_lob_table) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("aux lob table must valid when lob column exist", K(ret), K(ddl_data)); - } - } - } + ret = OB_ERR_UNEXPECTED; + LOG_WARN("aux lob table must valid when lob column exist", K(ret), K(ddl_data)); } } return ret; @@ -4315,7 +4205,6 @@ int ObLSTabletService::process_lob_row( } if (is_update) { if (!check_lob) { - ObTabletBindingInfo ddl_data; if (OB_FAIL(check_lob_tablet_valid(tablet_handle))) { LOG_WARN("failed to check_lob_tablet_valid", K(ret), K(tablet_handle)); } else { @@ -4879,15 +4768,8 @@ int ObLSTabletService::check_row_locked_by_myself( ObStorageTableGuard guard(tablet, store_ctx, true); if (OB_FAIL(guard.refresh_and_protect_table(relative_table))) { LOG_WARN("fail to protect table", K(ret), K(tablet_handle)); - } else { - memtable::ObMemtable *write_memtable = nullptr; - const uint64_t table_id = relative_table.get_table_id(); - if (OB_FAIL(tablet->prepare_memtable(relative_table, store_ctx, write_memtable))) { - LOG_WARN("prepare write memtable fail", K(ret), K(relative_table)); - } else if (OB_FAIL(write_memtable->check_row_locked_by_myself( - store_ctx, table_id, tablet->get_full_read_info(), rowkey, locked))) { - LOG_WARN("failed to lock write memtable", K(ret), K(table_id), K(rowkey)); - } + } else if (OB_FAIL(tablet->check_row_locked_by_myself(relative_table, store_ctx, rowkey, locked))) { + LOG_WARN("fail to check row locked, ", K(ret), K(rowkey)); } } @@ -5413,8 +5295,8 @@ void ObLSTabletService::dump_diag_info_for_old_row_loss( ObDatumRowkey datum_rowkey; ObDatumRowkeyHelper rowkey_helper(allocator); const int64_t schema_rowkey_cnt = data_table.get_rowkey_column_num(); - ObTableStoreIterator &table_iter = data_table.tablet_iter_.table_iter_; - const ObTableReadInfo &full_read_info = data_table.tablet_iter_.tablet_handle_.get_obj()->get_full_read_info(); + ObTableStoreIterator &table_iter = *data_table.tablet_iter_.table_iter(); + const ObITableReadInfo &rowkey_read_info = data_table.tablet_iter_.get_tablet()->get_rowkey_read_info(); ObQueryFlag query_flag(ObQueryFlag::Forward, false, /*is daily merge scan*/ false, /*is read multiple macro block*/ @@ -5427,7 +5309,7 @@ void ObLSTabletService::dump_diag_info_for_old_row_loss( trans_version_rang.multi_version_start_ = 0; trans_version_rang.snapshot_version_ = store_ctx.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(); - for (int64_t i = 0; OB_SUCC(ret) && i < full_read_info.get_request_count(); i++) { + for (int64_t i = 0; OB_SUCC(ret) && i < rowkey_read_info.get_schema_rowkey_count(); i++) { if (OB_FAIL(out_col_pros.push_back(i))) { STORAGE_LOG(WARN, "Failed to push back col project", K(ret), K(i)); } @@ -5443,11 +5325,9 @@ void ObLSTabletService::dump_diag_info_for_old_row_loss( } else { access_param.is_inited_ = true; access_param.iter_param_.table_id_ = data_table.get_table_id(); - access_param.iter_param_.tablet_id_ = data_table.tablet_iter_.tablet_handle_.get_obj()->get_tablet_meta().tablet_id_; - access_param.iter_param_.read_info_ = &full_read_info; - access_param.iter_param_.full_read_info_ = &full_read_info; - access_param.iter_param_.out_cols_project_ = &out_col_pros;; - access_param.iter_param_.tablet_handle_ = data_table.tablet_iter_.tablet_handle_; + access_param.iter_param_.tablet_id_ = data_table.tablet_iter_.get_tablet()->get_tablet_meta().tablet_id_; + access_param.iter_param_.read_info_ = &rowkey_read_info; + access_param.iter_param_.out_cols_project_ = &out_col_pros; ObStoreRowIterator *getter = nullptr; ObITable *table = nullptr; @@ -5552,16 +5432,40 @@ int ObLSTabletService::prepare_dml_running_ctx( return ret; } -int ObLSTabletService::get_ls_min_end_scn_in_old_tablets(SCN &end_scn) + +int ObLSTabletService::get_ls_min_end_scn( + SCN &min_end_scn_from_latest_tablets, SCN &min_end_scn_from_old_tablets) { int ret = OB_SUCCESS; const ObLSID &ls_id = ls_->get_ls_id(); ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObSArray tablet_ids; + GetAllTabletIDOperator op(tablet_ids, true/*except_ls_inner_tablet*/); + min_end_scn_from_latest_tablets.set_max(); + min_end_scn_from_old_tablets.set_max(); if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(t3m->get_min_end_scn_for_ls(ls_id, end_scn))) { - LOG_WARN("fail to get ls min end log ts in all of old tablets", K(ret), K(ls_id)); + } else if (OB_FAIL(tablet_id_set_.foreach(op))) { + STORAGE_LOG(WARN, "fail to get all tablet ids from set", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { + ObTabletMapKey key(ls_id, tablet_ids.at(i)); + SCN min_end_scn_from_latest = SCN::max_scn(); + SCN min_end_scn_from_old = SCN::max_scn(); + if (OB_FAIL(t3m->get_min_end_scn_for_ls(key, + min_end_scn_from_latest, + min_end_scn_from_old))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to get min end scn", K(ret), K(key)); + } else { + ret = OB_SUCCESS; + } + } else { + min_end_scn_from_latest_tablets = MIN(min_end_scn_from_latest_tablets, min_end_scn_from_latest); + min_end_scn_from_old_tablets = MIN(min_end_scn_from_old_tablets, min_end_scn_from_old); + } + } } return ret; } @@ -5584,8 +5488,8 @@ int ObLSTabletService::get_multi_ranges_cost( ObPartitionMultiRangeSpliter spliter; if (OB_FAIL(spliter.get_multi_range_size( ranges, - iter.tablet_handle_.get_obj()->get_index_read_info(), - iter.table_iter_, + iter.get_tablet()->get_rowkey_read_info(), + *iter.table_iter(), total_size))) { LOG_WARN("fail to get multi ranges cost", K(ret), K(ranges)); } @@ -5614,8 +5518,8 @@ int ObLSTabletService::split_multi_ranges( if (OB_FAIL(spliter.get_split_multi_ranges( ranges, expected_task_count, - iter.tablet_handle_.get_obj()->get_index_read_info(), - iter.table_iter_, + iter.get_tablet()->get_rowkey_read_info(), + *iter.table_iter(), allocator, multi_range_split_array))) { LOG_WARN("fail to get splitted ranges", K(ret), K(ranges), K(expected_task_count)); @@ -5652,17 +5556,17 @@ int ObLSTabletService::estimate_row_count( } else { while(OB_SUCC(ret)) { ObITable *table = nullptr; - if (OB_FAIL(tablet_iter.table_iter_.get_next(table))) { + if (OB_FAIL(tablet_iter.table_iter()->get_next(table))) { if (OB_ITER_END != ret) { - LOG_WARN("failed to get next table", K(ret), K(tablet_iter.table_iter_)); + LOG_WARN("failed to get next table", K(ret), K(tablet_iter.table_iter())); } else { ret = OB_SUCCESS; break; } } else if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("table shoud not be null", K(ret), K(tablet_iter.table_iter_)); - } else if (table->is_sstable() && static_cast(table)->get_meta().is_empty()) { + LOG_WARN("table shoud not be null", K(ret), K(tablet_iter.table_iter())); + } else if (table->is_sstable() && static_cast(table)->is_empty()) { LOG_DEBUG("cur sstable is empty", K(ret), K(*table)); continue; } else if (OB_FAIL(tables.push_back(table))) { @@ -5671,7 +5575,7 @@ int ObLSTabletService::estimate_row_count( } } if (OB_SUCC(ret) && tables.count() > 0) { - ObTableEstimateBaseInput base_input(param.scan_flag_, param.index_id_, param.tx_id_, tables, tablet_iter.tablet_handle_); + ObTableEstimateBaseInput base_input(param.scan_flag_, param.index_id_, param.tx_id_, tables, tablet_iter.get_tablet_handle()); if (scan_range.is_get()) { if (OB_FAIL(ObTableEstimator::estimate_row_count_for_get(base_input, scan_range.get_rowkeys(), batch_est))) { LOG_WARN("failed to estimate row count", K(ret), K(param), K(scan_range)); @@ -5714,7 +5618,8 @@ int ObLSTabletService::estimate_block_count( int64_t total_row_count = 0; while (OB_SUCC(ret)) { - if (OB_FAIL(tablet_iter.table_iter_.get_next(table))) { + ObSSTableMetaHandle sst_meta_hdl; + if (OB_FAIL(tablet_iter.table_iter()->get_next(table))) { if (OB_ITER_END != ret) { LOG_WARN("failed to get next tables", K(ret)); } else { @@ -5723,16 +5628,19 @@ int ObLSTabletService::estimate_block_count( } } else if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected null table", K(ret), K(tablet_iter.table_iter_)); + LOG_WARN("get unexpected null table", K(ret), K(tablet_iter.table_iter())); } else if (!table->is_sstable()) { break; + } else if (FALSE_IT(sstable = static_cast(table))) { + } else if (OB_FAIL(sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); } else { sstable = static_cast(table); - macro_block_count += sstable->get_meta().get_basic_meta().get_data_macro_block_count(); - micro_block_count += sstable->get_meta().get_basic_meta().get_data_micro_block_count(); - total_row_count += sstable->get_meta().get_row_count(); + macro_block_count += sstable->get_data_macro_block_count(); + micro_block_count += sst_meta_hdl.get_sstable_meta().get_data_micro_block_count(); + total_row_count += sst_meta_hdl.get_sstable_meta().get_row_count(); if (sample_table_cnt++ < total_sample_table_cnt) { - sampled_table_row_cnt += sstable->get_meta().get_row_count(); + sampled_table_row_cnt += sst_meta_hdl.get_sstable_meta().get_row_count(); } } } @@ -5757,6 +5665,12 @@ int ObLSTabletService::get_lock_memtable_mgr(ObMemtableMgrHandle &mgr_handle) return mgr_handle.set_memtable_mgr(&lock_memtable_mgr_); } +int ObLSTabletService::get_mds_table_mgr(mds::MdsTableMgrHandle &mgr_handle) +{ + mgr_handle.reset(); + return mgr_handle.set_mds_table_mgr(&mds_table_mgr_); +} + int ObLSTabletService::get_bf_optimal_prefix(int64_t &prefix) { int ret = OB_SUCCESS; @@ -5764,206 +5678,30 @@ int ObLSTabletService::get_bf_optimal_prefix(int64_t &prefix) return ret; } -int ObLSTabletService::on_prepare_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - ObTabletCreateDeleteHelper helper(*ls_, tablet_id_set_); - if (OB_FAIL(helper.prepare_create_tablets(arg, trans_flags))) { - LOG_WARN("failed to prepare create tablets", K(ret), K(arg), K(trans_flags)); - } - } - return ret; -} - -int ObLSTabletService::on_redo_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - ObTabletCreateDeleteHelper helper(*ls_, tablet_id_set_); - if (OB_FAIL(helper.redo_create_tablets(arg, trans_flags))) { - LOG_WARN("failed to redo create tablets", K(ret), K(arg), K(trans_flags)); - } - } - return ret; -} - -int ObLSTabletService::on_commit_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - common::ObSArray tablet_id_array; - ObTabletCreateDeleteHelper helper(*ls_, tablet_id_set_); - if (OB_FAIL(helper.commit_create_tablets(arg, trans_flags, tablet_id_array))) { - LOG_WARN("failed to commit create tablets", K(ret), K(trans_flags)); - } else { - report_tablet_to_rs(tablet_id_array); - } - } - return ret; -} - -int ObLSTabletService::on_tx_end_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - ObTabletCreateDeleteHelper helper(*ls_, tablet_id_set_); - if (OB_FAIL(helper.tx_end_create_tablets(arg, trans_flags))) { - LOG_WARN("failed to tx end create tablets", K(ret), K(trans_flags)); - } - } - return ret; -} - -int ObLSTabletService::on_abort_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - ObTabletCreateDeleteHelper helper(*ls_, tablet_id_set_); - if (OB_FAIL(helper.abort_create_tablets(arg, trans_flags))) { - LOG_WARN("failed to abort create tablets", K(ret), K(trans_flags)); - } - } - return ret; -} - -int ObLSTabletService::on_prepare_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - ObTabletCreateDeleteHelper helper(*ls_, tablet_id_set_); - if (OB_FAIL(helper.prepare_remove_tablets(arg, trans_flags))) { - LOG_WARN("failed to prepare remove tablets", K(ret), K(arg), K(trans_flags)); - } - } - return ret; -} - -int ObLSTabletService::on_redo_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - ObTabletCreateDeleteHelper helper(*ls_, tablet_id_set_); - if (OB_FAIL(helper.redo_remove_tablets(arg, trans_flags))) { - LOG_WARN("failed to redo remove tablets", K(ret), K(arg), K(trans_flags)); - } - } - return ret; -} - -int ObLSTabletService::on_commit_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - ObTabletCreateDeleteHelper helper(*ls_, tablet_id_set_); - if (OB_FAIL(helper.commit_remove_tablets(arg, trans_flags))) { - LOG_WARN("failed to commit remove tablets", K(ret), K(trans_flags)); - } - } - return ret; -} - -int ObLSTabletService::on_tx_end_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - ObTabletCreateDeleteHelper helper(*ls_, tablet_id_set_); - if (OB_FAIL(helper.tx_end_remove_tablets(arg, trans_flags))) { - LOG_WARN("failed to tx end remove tablets", K(ret), K(trans_flags)); - } - } - return ret; -} - -int ObLSTabletService::on_abort_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - ObTabletCreateDeleteHelper helper(*ls_, tablet_id_set_); - if (OB_FAIL(helper.abort_remove_tablets(arg, trans_flags))) { - LOG_WARN("failed to abort remove tablets", K(ret), K(trans_flags)); - } - } - return ret; -} - int ObLSTabletService::create_ls_inner_tablet( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, - const int64_t memstore_version, const SCN &major_frozen_scn, const share::schema::ObTableSchema &table_schema, const lib::Worker::CompatMode &compat_mode, const SCN &create_scn) { int ret = OB_SUCCESS; - const int64_t data_version = ObVersion(memstore_version - 1, 0); - const common::ObSArray empty_index_tablet_array; bool b_exist = false; ObTabletHandle tablet_handle; common::ObTabletID empty_tablet_id; - ObMetaDiskAddr disk_addr; // no use + ObMetaDiskAddr disk_addr; + const int64_t snapshot_version = major_frozen_scn.get_val_for_tx(); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); } else if (OB_UNLIKELY(!ls_id.is_valid()) || OB_UNLIKELY(!tablet_id.is_valid()) - || OB_UNLIKELY(OB_INVALID_VERSION == memstore_version) || OB_UNLIKELY(!major_frozen_scn.is_valid()) || OB_UNLIKELY(!table_schema.is_valid()) || OB_UNLIKELY(lib::Worker::CompatMode::INVALID == compat_mode) - /*|| OB_UNLIKELY(create_scn <= OB_INVALID_TIMESTAMP)*/) { + || OB_UNLIKELY(!create_scn.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(ls_id), K(tablet_id), K(major_frozen_scn), K(table_schema), K(compat_mode), K(create_scn)); @@ -5978,16 +5716,10 @@ int ObLSTabletService::create_ls_inner_tablet( } else if (OB_UNLIKELY(b_exist)) { ret = OB_TABLET_EXIST; LOG_WARN("tablet already exists", K(ret), K(ls_id), K(tablet_id)); - } else if (OB_FAIL(do_create_tablet(ls_id, tablet_id, tablet_id/*data_tablet_id*/, empty_index_tablet_array, - create_scn, major_frozen_scn, table_schema, compat_mode, empty_tablet_id, empty_tablet_id, tablet_handle))) { + } else if (OB_FAIL(create_inner_tablet(ls_id, tablet_id, tablet_id/*data_tablet_id*/, + create_scn, snapshot_version, table_schema, compat_mode, tablet_handle))) { LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(tablet_id), K(create_scn), K(major_frozen_scn), K(table_schema), K(compat_mode)); - } else if (OB_FAIL(ObTabletSlogHelper::write_create_tablet_slog(tablet_handle, disk_addr))) { - LOG_WARN("failed to write create tablet slog", K(ret), K(tablet_handle)); - } else if (OB_FAIL(tablet_id_set_.set(tablet_id))) { - LOG_ERROR("fail to set tablet id set", K(ret), K(tablet_id), K(lbt())); - ob_usleep(1000 * 1000); - ob_abort(); } return ret; @@ -5998,6 +5730,7 @@ int ObLSTabletService::remove_ls_inner_tablet( const common::ObTabletID &tablet_id) { int ret = OB_SUCCESS; + common::ObSEArray tablet_id_array; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -6009,7 +5742,7 @@ int ObLSTabletService::remove_ls_inner_tablet( } else if (OB_UNLIKELY(ls_id != ls_->get_ls_id())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls id is unexpected", K(ret), "arg_ls_id", ls_id, "ls_id", ls_->get_ls_id()); - } else if (OB_FAIL(do_remove_tablet(ls_id, tablet_id))) { + } else if (OB_FAIL(do_remove_tablet(ObTabletMapKey(ls_id, tablet_id)))) { LOG_WARN("failed to remove tablet", K(ret), K(ls_id), K(tablet_id)); } @@ -6030,7 +5763,6 @@ int ObLSTabletService::build_tablet_iter(ObLSTabletIterator &iter) ret = OB_ERR_UNEXPECTED; LOG_WARN("iter is invalid", K(ret), K(iter)); } - if (OB_FAIL(ret)) { iter.reset(); } @@ -6057,6 +5789,23 @@ int ObLSTabletService::build_tablet_iter(ObHALSTabletIDIterator &iter) return ret; } +int ObLSTabletService::build_tablet_iter(ObHALSTabletIterator &iter) +{ + int ret = common::OB_SUCCESS; + iter.ls_tablet_service_ = this; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(build_tablet_iter(iter.tablet_id_iter_))) { + STORAGE_LOG(WARN, "fail to build ha tablet id iterator", K(ret)); + } + + if (OB_FAIL(ret)) { + iter.reset(); + } + return ret; +} + int ObLSTabletService::set_allow_to_read_(ObLS *ls) { int ret = OB_SUCCESS; @@ -6091,142 +5840,6 @@ void ObLSTabletService::disable_to_read() allow_to_read_mgr_.disable_to_read(); } - -ObLSTabletService::DeleteTabletInfo::DeleteTabletInfo() - : delete_data_tablet_(false), - old_data_tablet_handle_(), - new_data_tablet_handle_(), - delete_index_tablet_ids_() -{ -} - -ObLSTabletService::DeleteTabletInfo::DeleteTabletInfo(const ObLSTabletService::DeleteTabletInfo &other) - : delete_data_tablet_(other.delete_data_tablet_), - old_data_tablet_handle_(other.old_data_tablet_handle_), - new_data_tablet_handle_(other.new_data_tablet_handle_), - delete_index_tablet_ids_(other.delete_index_tablet_ids_) -{ -} - -ObLSTabletService::DeleteTabletInfo &ObLSTabletService::DeleteTabletInfo::operator=( - const ObLSTabletService::DeleteTabletInfo &other) -{ - if (this != &other) { - delete_data_tablet_ = other.delete_data_tablet_; - old_data_tablet_handle_ = other.old_data_tablet_handle_; - new_data_tablet_handle_ = other.new_data_tablet_handle_; - delete_index_tablet_ids_ = other.delete_index_tablet_ids_; - } - return *this; -} - -ObLSTabletService::HashMapTabletDeleteFunctor::HashMapTabletDeleteFunctor(ObLS *ls) - : ls_(ls), - slog_params_() -{ -} - -ObLSTabletService::HashMapTabletDeleteFunctor::~HashMapTabletDeleteFunctor() -{ - destroy(); -} - -void ObLSTabletService::HashMapTabletDeleteFunctor::destroy() -{ - for (int64_t i = 0; i < slog_params_.count(); i++) { - ObIBaseStorageLogEntry *data = slog_params_.at(i).data_; - if (nullptr != data) { - OB_DELETE(ObIBaseStorageLogEntry, "", data); - data = nullptr; - } - } -} - -bool ObLSTabletService::HashMapTabletDeleteFunctor::operator()( - const common::ObTabletID &tablet_id, - ObLSTabletService::DeleteTabletInfo &info) -{ - bool b_ret = true; - int ret = OB_SUCCESS; - - if (info.delete_data_tablet_ - && OB_FAIL(handle_remove_data_tablet(info.old_data_tablet_handle_, info.delete_index_tablet_ids_))) { - // delete data tablet and all index tablets - LOG_WARN("failed to handle remove data tablet", K(ret)); - } else if (!info.delete_data_tablet_) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("failed to handle alter index tablet", K(ret)); - } - - if (OB_FAIL(ret)) { - b_ret = false; - } - - return b_ret; -} - -int ObLSTabletService::HashMapTabletDeleteFunctor::handle_remove_data_tablet( - ObTabletHandle &data_tablet_handle, - const common::ObIArray &delete_index_tablet_ids) -{ - int ret = OB_SUCCESS; - const int32_t delete_tablet_cmd = ObIRedoModule::gen_cmd(ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, - ObRedoLogSubType::OB_REDO_LOG_DELETE_TABLET); - const share::ObLSID &ls_id = data_tablet_handle.get_obj()->get_tablet_meta().ls_id_; - const common::ObTabletID &data_tablet_id = data_tablet_handle.get_obj()->get_tablet_meta().tablet_id_; - - // delete local index tablet - for (int64_t i = 0; OB_SUCC(ret) && i < delete_index_tablet_ids.count(); ++i) { - const common::ObTabletID &index_tablet_id = delete_index_tablet_ids.at(i); - ObDeleteTabletLog *slog_entry = OB_NEW(ObDeleteTabletLog, "delete tablet", ls_id, index_tablet_id); - ObStorageLogParam slog_param; - slog_param.cmd_ = delete_tablet_cmd; - slog_param.data_ = slog_entry; - if (OB_FAIL(slog_params_.push_back(slog_param))) { - LOG_WARN("failed to push back index tablet slog param", K(ret), K(slog_param)); - } - } - - // delete data tablet - if (OB_SUCC(ret)) { - ObStorageLogParam slog_param; - slog_param.cmd_ = delete_tablet_cmd; - slog_param.data_ = OB_NEW(ObDeleteTabletLog, "delete tablet", ls_id, data_tablet_id); - if (OB_FAIL(slog_params_.push_back(slog_param))) { - LOG_WARN("failed to push back data tablet slog param", K(ret), K(slog_param)); - } - } - - return ret; -} - -bool ObLSTabletService::HashMapTabletGetFunctor::operator()( - const common::ObTabletID &tablet_id, - ObLSTabletService::DeleteTabletInfo &info) -{ - bool b_ret = true; - int ret = OB_SUCCESS; - common::ObIArray &index_tablet_ids = info.delete_index_tablet_ids_; - - // always push back data tablet id - if (OB_FAIL(tablet_id_hash_array_.push_back(tablet_id.hash()))) { - LOG_WARN("failed to push back data tablet id", K(ret), K(tablet_id)); - } - - for (int64_t i = 0; OB_SUCC(ret) && i < index_tablet_ids.count(); ++i) { - const common::ObTabletID &index_tablet_id = index_tablet_ids.at(i); - if (OB_FAIL(tablet_id_hash_array_.push_back(tablet_id.hash()))) { - LOG_WARN("failed to push back index tablet id", K(ret), K(tablet_id)); - } - } - - if (OB_FAIL(ret)) { - b_ret = false; - } - - return b_ret; -} - int ObLSTabletService::GetAllTabletIDOperator::operator()(const common::ObTabletID &tablet_id) { int ret = OB_SUCCESS; @@ -6241,7 +5854,7 @@ int ObLSTabletService::GetAllTabletIDOperator::operator()(const common::ObTablet return ret; } -int ObLSTabletService::DestroyMemtableAndMemberOperator::operator()(const common::ObTabletID &tablet_id) +int ObLSTabletService::DestroyMemtableAndMemberAndMdsTableOperator::operator()(const common::ObTabletID &tablet_id) { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; @@ -6252,9 +5865,8 @@ int ObLSTabletService::DestroyMemtableAndMemberOperator::operator()(const common OB_ISNULL(tablet_svr_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), K(tablet_id), K(tablet_svr_)); - } else if (OB_FAIL(tablet_svr_->get_tablet(tablet_id, - handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(tablet_svr_->get_tablet(tablet_id, handle, 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { if (OB_TABLET_NOT_EXIST == ret) { LOG_WARN("failed to get tablet, skip clean memtable", K(ret), K(tablet_id)); ret = OB_SUCCESS; @@ -6263,6 +5875,8 @@ int ObLSTabletService::DestroyMemtableAndMemberOperator::operator()(const common } } else if (OB_FAIL(handle.get_obj()->release_memtables())) { LOG_WARN("failed to release memtables", K(tenant_id), K(tablet_id)); + } else if (OB_FAIL(handle.get_obj()->forcely_release_all_mds_nodes("OFFLINE"))) { + LOG_WARN("failed to release mds_table", K(tenant_id), K(tablet_id)); } else if (!tablet_id.is_ls_inner_tablet() && OB_FAIL(handle.get_obj()->reset_storage_related_member())) { LOG_WARN("failed to destroy storage related member", K(ret), K(tenant_id), K(tablet_id)); } @@ -6282,7 +5896,8 @@ int ObLSTabletService::SetMemtableFrozenOperator::operator()(const common::ObTab LOG_WARN("invalid arguments", K(ret), K(tablet_id), K(tablet_svr_)); } else if (OB_FAIL(tablet_svr_->get_tablet(tablet_id, handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + ObTabletCommon::DEFAULT_GET_TABLET_NO_WAIT, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { if (OB_TABLET_NOT_EXIST == ret) { LOG_WARN("failed to get tablet, skip set memtable frozen", K(ret), K(tablet_id)); ret = OB_SUCCESS; @@ -6351,6 +5966,67 @@ int ObLSTabletService::get_all_tablet_ids( return ret; } +int ObLSTabletService::flush_mds_table(int64_t recycle_scn) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ls tablet service is not init", KR(ret), KPC(this)); + } else if (OB_FAIL(mds_table_mgr_.flush(SCN::max_scn(), true))) { + LOG_WARN("flush mds table failed", KR(ret), KPC(this)); + } + LOG_INFO("finish flush mds table", KR(ret), K(recycle_scn)); + return ret; +} + +int ObLSTabletService::get_max_tablet_transfer_scn(share::SCN &transfer_scn) +{ + int ret = OB_SUCCESS; + const bool need_initial_state = false; + ObHALSTabletIDIterator iter(ls_->get_ls_id(), need_initial_state); + share::SCN max_transfer_scn = share::SCN::min_scn(); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(build_tablet_iter(iter))) { + LOG_WARN("failed to build tablet iter", K(ret), KPC(this)); + } else { + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + common::ObTabletID tablet_id; + ObTabletMapKey key; + key.ls_id_ = ls_->get_ls_id(); + ObTabletCreateDeleteMdsUserData mds_data; + ObTabletHandle tablet_handle; + const WashTabletPriority priority = WashTabletPriority::WTP_LOW; + while (OB_SUCC(ret)) { + mds_data.reset(); + if (OB_FAIL(iter.get_next_tablet_id(tablet_id))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get tablet id", K(ret)); + } + } else if (OB_FALSE_IT(key.tablet_id_ = tablet_id)) { + } else if (OB_FAIL(t3m->get_tablet(priority, key, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(key)); + } else if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_tablet_status( + share::SCN::max_scn(), mds_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get mds table", KR(ret), K(tablet_handle)); + } else if (share::SCN::invalid_scn() == mds_data.transfer_scn_) { + // do nothing + } else { + transfer_scn = mds_data.transfer_scn_; + max_transfer_scn = MAX(transfer_scn, max_transfer_scn); + } + } + if (OB_SUCC(ret)) { + transfer_scn = max_transfer_scn; + } + } + return ret; +} + int ObLSTabletService::set_frozen_for_all_memtables() { int ret = OB_SUCCESS; @@ -6366,6 +6042,72 @@ int ObLSTabletService::set_frozen_for_all_memtables() return ret; } +int ObLSTabletService::ha_scan_all_tablets(const HandleTabletMetaFunc &handle_tablet_meta_f) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else { + ObHALSTabletIterator iterator(ls_->get_ls_id(), false/* need_initial_state */); + if (OB_FAIL(build_tablet_iter(iterator))) { + LOG_WARN("fail to build tablet iterator", K(ret), KPC(this)); + } else { + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + obrpc::ObCopyTabletInfo tablet_info; + + while (OB_SUCC(ret)) { + tablet_info.reset(); + if (OB_FAIL(iterator.get_next_tablet(tablet_handle))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get tablet", K(ret)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is nullptr", K(ret), K(tablet_handle)); + } else if (OB_FAIL(tablet->build_migration_tablet_param(tablet_info.param_))) { + LOG_WARN("failed to build migration tablet param", K(ret)); + } else if (OB_FAIL(tablet->get_ha_sstable_size(tablet_info.data_size_))) { + LOG_WARN("failed to get sstable size", K(ret), KPC(tablet)); + } else if (OB_FAIL(ObStorageHAUtils::get_server_version(tablet_info.version_))) { + LOG_WARN("failed to get server version", K(ret), K(tablet_info)); + } else { + tablet_info.tablet_id_ = tablet->get_tablet_meta().tablet_id_; + tablet_info.status_ = ObCopyTabletStatus::TABLET_EXIST; + if (OB_FAIL(handle_tablet_meta_f(tablet_info))) { + LOG_WARN("fail to handle tablet meta", K(ret), K(tablet_info)); + } + } + } + } + } + + return ret; +} + +int ObLSTabletService::ha_get_tablet( + const common::ObTabletID &tablet_id, + ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + bool is_empty_shell = false; + ObTablet *tablet = nullptr; + if (OB_FAIL(direct_get_tablet(tablet_id, handle))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_ISNULL(tablet = handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_id)); + } else if (tablet->is_empty_shell()) { + // treat empty shell as tablet not exist. + ret = OB_TABLET_NOT_EXIST; + } + return ret; +} int ObLSTabletService::check_real_leader_for_4377_(const ObLSID ls_id) { int ret = OB_SUCCESS; @@ -6395,5 +6137,58 @@ int ObLSTabletService::check_real_leader_for_4377_(const ObLSID ls_id) return ret; } +int ObLSTabletService::check_need_rollback_in_transfer_for_4377_(const transaction::ObTxDesc *tx_desc, + ObTabletHandle &data_tablet_handle) +{ + int ret = OB_SUCCESS; + ObTabletCreateDeleteMdsUserData user_data; + bool unused_committed_flag = false; + + if (OB_ISNULL(tx_desc)) { + LOG_WARN("tx_desc is null when check 4377", K(ret)); + } else if (OB_FAIL(data_tablet_handle.get_obj()->ObITabletMdsInterface::get_latest_tablet_status( + user_data, unused_committed_flag))) { + LOG_WARN("can not get the tablet status from ObITabletMdsInterface", K(ret)); + } else { + // ObTabletStatus tablet_status = user_data.tablet_status_; + // CASE 1: tablet_status_ == NORMAL, means there's no transfer in progress right now. + // If there's valid transfer_scn_, which means transfer has finished, we should check + // whether the transaction started before transfer to avoid throwing incorrect 4377 + // error. Otherwise, it's a normal case of 4377 check because no transfer has happened, + // and we should still throw 4377 error. + // + // CASE 2: tablet_status_ == TRANSFER_OUT, means it's in transfer out progress. + // CASE 2.1: transfer_scn_ is invalid, the transfer_scn_ is not backfilled, we still + // read from origin tablet, if there's inconsistent, it should throw 4377 error + // CASE 2.2: transfer_scn_ is valid, the transfer_scn_ is backfilled, it means that + // tablet has started to transfer out. If it's the first transfer, we should + // throw 4377 erorr, otherwise we should compare the transfer_scn_ with the tx_scn, + // and decide to rollback the transaction or throw 4377 error. + // However, we can not be sure about whether this transfer out is the first transfer or not. + // So we consider all the transfer out status as not the first transfer here, to avoid + // throwing the incorrect 4377 error. + // + // CASE 3: tablet_status_ == TRANSFER_IN, means it's in transfer in progress, and + // the transfer out progress must have been finished. We can compare the transfer_scn_ + // with the tx_scn directly because there should be valid transfer_scn_. + // + // Above all, we do not need to consider the status of tablet. + if (user_data.transfer_scn_.is_valid()) { + if (user_data.transfer_scn_.convert_to_ts() > tx_desc->get_active_ts()) { + // TODO(yangyifei.yyf): active_ts is set by ObClockGenerator::get_clock, it's not a GTS. + // And transfer_scn is set by redo_scn, it's incorrect to compare it with active_ts. + // We should adjust this judgment later. + ret = OB_TRANS_NEED_ROLLBACK; + LOG_WARN("maybe meet transfer during kill tx, which can cause 4377 error, so we will rollback it", + K(tx_desc), + K(user_data)); + } + } else { + // There's no transfer after trans begin, still throw 4377 error + } + } + return ret; +} + } // namespace storage } // namespace oceanbase diff --git a/src/storage/ls/ob_ls_tablet_service.h b/src/storage/ls/ob_ls_tablet_service.h old mode 100644 new mode 100755 index 853e07979..9085a063a --- a/src/storage/ls/ob_ls_tablet_service.h +++ b/src/storage/ls/ob_ls_tablet_service.h @@ -17,11 +17,9 @@ #include "common/ob_tablet_id.h" #include "lib/container/ob_array_serialization.h" #include "lib/container/ob_iarray.h" -#include "lib/hash/ob_hashset.h" #include "lib/lock/ob_bucket_lock.h" #include "logservice/ob_log_base_type.h" #include "logservice/palf/palf_callback.h" -#include "share/ob_rpc_struct.h" #include "share/schema/ob_table_schema.h" #include "storage/ob_dml_common.h" #include "storage/slog/ob_storage_log.h" @@ -34,6 +32,7 @@ #include "storage/tablet/ob_tablet_memtable_mgr.h" #include "storage/tablet/ob_tablet_id_set.h" #include "storage/lob/ob_lob_manager.h" +#include "storage/multi_data_source/mds_table_mgr.h" namespace oceanbase { @@ -41,13 +40,6 @@ namespace observer { class ObIMetaReport; } -namespace obrpc -{ -struct ObCreateTabletInfo; -struct ObBatchCreateTabletArg; -struct ObBatchRemoveTabletArg; -} - namespace common { class ObRowStore; @@ -84,6 +76,7 @@ class ObTableScanIterator; class ObSingleRowGetter; class ObLSTabletIterator; class ObHALSTabletIDIterator; +class ObHALSTabletIterator; class ObTabletMapKey; struct ObStorageLogParam; struct ObTabletCreateSSTableParam; @@ -91,6 +84,7 @@ struct ObUpdateTableStoreParam; class ObTabletTxMultiSourceDataUnit; struct ObMigrationTabletParam; class ObTableScanRange; +class ObTabletCreateDeleteMdsUserData; class ObLSTabletService : public logservice::ObIReplaySubHandler, @@ -172,19 +166,11 @@ private: public: int prepare_for_safe_destroy(); int safe_to_destroy(bool &is_safe); - // tablet operation - int batch_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const share::SCN &create_scn, - const bool is_replay_clog = false); - int batch_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const bool is_replay_clog = false); + // tablet operation int create_ls_inner_tablet( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, - const int64_t memstore_version, const share::SCN &frozen_timestamp, const share::schema::ObTableSchema &table_schema, const lib::Worker::CompatMode &compat_mode, @@ -193,62 +179,48 @@ public: const share::ObLSID &ls_id, const common::ObTabletID &tablet_id); - // TODO: after this call back interfaces ready, - // batch create/remove interfaces should be private - int on_prepare_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int on_redo_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int on_commit_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int on_tx_end_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int on_abort_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int on_prepare_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int on_redo_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int on_commit_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int on_tx_end_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int on_abort_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); + int create_tablet( + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id, + const common::ObTabletID &data_tablet_id, + const share::SCN &create_scn, + const int64_t snapshot_version, + const share::schema::ObTableSchema &table_schema, + const lib::Worker::CompatMode &compat_mode, + ObTabletHandle &tablet_handle); + int create_transfer_in_tablet( + const share::ObLSID &ls_id, + const ObMigrationTabletParam &tablet_meta, + ObTabletHandle &tablet_handle); + int rollback_tablet( + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id); int get_tablet( const common::ObTabletID &tablet_id, ObTabletHandle &handle, - const int64_t timeout_us = ObTabletCommon::DEFAULT_GET_TABLET_TIMEOUT_US); + const int64_t timeout_us = ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US * 10, + const ObMDSGetTabletMode mode = ObMDSGetTabletMode::READ_READABLE_COMMITED); int get_tablet_with_timeout( const common::ObTabletID &tablet_id, ObTabletHandle &handle, const int64_t retry_timeout_us, - const int64_t get_timeout_us = ObTabletCommon::DEFAULT_GET_TABLET_TIMEOUT_US); + const ObMDSGetTabletMode mode = ObMDSGetTabletMode::READ_READABLE_COMMITED, + const share::SCN &snapshot = share::SCN::max_scn()); + int remove_tablets(const common::ObIArray &tablet_id_array); - int get_ls_min_end_scn_in_old_tablets(share::SCN &end_scn); + // Exactly deletion compared with input tablets + int remove_tablet(const ObTabletHandle& tablet_handle); + int get_ls_min_end_scn( + share::SCN &min_end_scn_from_latest_tablets, + share::SCN &min_end_scn_from_old_tablets); int get_tx_data_memtable_mgr(ObMemtableMgrHandle &mgr_handle); int get_tx_ctx_memtable_mgr(ObMemtableMgrHandle &mgr_handle); int get_lock_memtable_mgr(ObMemtableMgrHandle &mgr_handle); + int get_mds_table_mgr(mds::MdsTableMgrHandle &mgr_handle); int get_bf_optimal_prefix(int64_t &prefix); int64_t get_tablet_count() const; - // clog replay - int replay_update_storage_schema( - const share::SCN &scn, - const char *buf, - const int64_t buf_size, - const int64_t pos); int replay_medium_compaction_clog( const share::SCN &scn, const char *buf, @@ -261,6 +233,12 @@ public: const int64_t pos); // update tablet + int update_tablet_checkpoint( + const ObTabletMapKey &key, + const ObMetaDiskAddr &old_addr, + const ObMetaDiskAddr &new_addr, + const bool is_replay_old, + ObTabletHandle &new_handle); int update_tablet_table_store( const common::ObTabletID &tablet_id, const ObUpdateTableStoreParam ¶m, @@ -270,7 +248,10 @@ public: ObTabletHandle &handle); int update_tablet_table_store( // only for small sstables defragmentation const ObTabletHandle &old_tablet_handle, - const ObIArray &table_handles); + const ObIArray &tables); + int build_new_tablet_from_mds_table( + const common::ObTabletID &tablet_id, + const share::SCN &flush_scn); int update_tablet_report_status(const common::ObTabletID &tablet_id); int update_tablet_restore_status( const common::ObTabletID &tablet_id, @@ -281,14 +262,23 @@ public: int update_tablet_ha_expected_status( const common::ObTabletID &tablet_id, const ObTabletExpectedStatus::STATUS &expected_status); + // Get tablet handle but ignore empty shell. Return OB_TABLET_NOT_EXIST if it is empty shell. + int ha_get_tablet( + const common::ObTabletID &tablet_id, + ObTabletHandle &handle); + int update_tablet_mstx( + const ObTabletMapKey &key, + const ObMetaDiskAddr &old_addr, + const ObTabletHandle &old_tablet_handle, + ObTabletHandle &new_tablet_handle); + int update_tablet_to_empty_shell(const common::ObTabletID &tablet_id); int replay_create_tablet( const ObMetaDiskAddr &disk_addr, const char *buf, const int64_t buf_len, - const ObTabletID &tablet_id); - int do_remove_tablet( - const share::ObLSID &ls_id, - const common::ObTabletID &tablet_id); + const ObTabletID &tablet_id, + ObTabletTransferInfo &tablet_transfer_info); + int do_remove_tablet(const ObTabletMapKey &key); int create_memtable( const common::ObTabletID &tablet_id, @@ -300,21 +290,45 @@ public: const int64_t snapshot_version, ObTabletTableIterator &iter, const bool allow_no_ready_read = false); + int check_allow_to_read(); + int set_tablet_status( + const common::ObTabletID &tablet_id, + const ObTabletCreateDeleteMdsUserData &tablet_status, + mds::MdsCtx &ctx); + int replay_set_tablet_status( + const common::ObTabletID &tablet_id, + const share::SCN &scn, + const ObTabletCreateDeleteMdsUserData &tablet_status, + mds::MdsCtx &ctx); + int set_ddl_info( + const common::ObTabletID &tablet_id, + const ObTabletBindingMdsUserData &ddl_info, + mds::MdsCtx &ctx, + const int64_t timeout_us); + int replay_set_ddl_info( + const common::ObTabletID &tablet_id, + const share::SCN &scn, + const ObTabletBindingMdsUserData &ddl_info, + mds::MdsCtx &ctx); // DAS interface int table_scan( + ObTabletHandle &tablet_handle, ObTableScanIterator &iter, ObTableScanParam ¶m); int table_rescan( + ObTabletHandle &tablet_handle, ObTableScanParam ¶m, common::ObNewRowIterator *result); int insert_rows( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const common::ObIArray &column_ids, common::ObNewRowIterator *row_iter, int64_t &affected_rows); int insert_row( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const common::ObIArray &column_ids, @@ -324,6 +338,7 @@ public: int64_t &affected_rows, common::ObNewRowIterator *&duplicated_rows); int update_rows( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const ObIArray &column_ids, @@ -331,18 +346,21 @@ public: ObNewRowIterator *row_iter, int64_t &affected_rows); int put_rows( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const ObIArray &column_ids, ObNewRowIterator *row_iter, int64_t &affected_rows); // for htable, insert or update int delete_rows( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const ObIArray &column_ids, ObNewRowIterator *row_iter, int64_t &affected_rows); int lock_rows( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const int64_t abs_lock_timeout, @@ -351,6 +369,7 @@ public: ObNewRowIterator *row_iter, int64_t &affected_rows); int lock_row( + ObTabletHandle &tablet_handle, ObStoreCtx &ctx, const ObDMLBaseParam &dml_param, const int64_t abs_lock_timeout, @@ -381,8 +400,11 @@ public: // iterator int build_tablet_iter(ObLSTabletIterator &iter); int build_tablet_iter(ObHALSTabletIDIterator &iter); + int build_tablet_iter(ObHALSTabletIterator &iter); // migration section + typedef common::ObFunction HandleTabletMetaFunc; + int ha_scan_all_tablets(const HandleTabletMetaFunc &handle_tablet_meta_f); int trim_rebuild_tablet( const ObTabletID &tablet_id, const bool is_rollback = false); @@ -392,11 +414,6 @@ public: int create_or_update_migration_tablet( const ObMigrationTabletParam &mig_tablet_param, const bool is_transfer); - int create_migration_sstable( - const blocksstable::ObMigrationSSTableParam &mig_sstable_param, - const ObSSTableStatus status, - ObTableHandleV2 &table_handle); - int finish_copy_migration_sstable(const ObTabletID &tablet_id, const ObITable::TableKey &sstable_key); int build_ha_tablet_new_table_store( const ObTabletID &tablet_id, const ObBatchUpdateTableStoreParam ¶m); @@ -404,6 +421,8 @@ public: void disable_to_read(); int get_all_tablet_ids(const bool except_ls_inner_tablet, common::ObIArray &tablet_id_array); + int flush_mds_table(int64_t recycle_scn); + int get_max_tablet_transfer_scn(share::SCN &transfer_scn); protected: virtual int prepare_dml_running_ctx( const common::ObIArray *column_ids, @@ -412,56 +431,6 @@ protected: ObDMLRunningCtx &run_ctx); private: typedef ObSEArray UpdateIndexArray; - typedef common::hash::ObHashSet NonLockedHashSet; - struct DeleteTabletInfo - { - public: - DeleteTabletInfo(); - ~DeleteTabletInfo() = default; - DeleteTabletInfo(const DeleteTabletInfo &other); - DeleteTabletInfo &operator=(const DeleteTabletInfo &other); - - void reset() - { - delete_data_tablet_ = false; - old_data_tablet_handle_.reset(); - new_data_tablet_handle_.reset(); - delete_index_tablet_ids_.reset(); - } - public: - bool delete_data_tablet_; - ObTabletHandle old_data_tablet_handle_; - ObTabletHandle new_data_tablet_handle_; - common::ObSArray delete_index_tablet_ids_; - }; - struct HashMapTabletDeleteFunctor - { - public: - HashMapTabletDeleteFunctor(ObLS *ls); - ~HashMapTabletDeleteFunctor(); - void destroy(); - public: - bool operator()(const common::ObTabletID &tablet_id, DeleteTabletInfo &info); - common::ObIArray &get_slog_params() { return slog_params_; } - - TO_STRING_KV(K_(slog_params)); - private: - int handle_remove_data_tablet( - ObTabletHandle &data_tablet_handle, - const common::ObIArray &delete_index_tablet_ids); - private: - ObLS *ls_; - common::ObSArray slog_params_; - }; - struct HashMapTabletGetFunctor - { - public: - HashMapTabletGetFunctor(common::ObIArray &tablet_id_hash_array) : tablet_id_hash_array_(tablet_id_hash_array) {} - public: - bool operator()(const common::ObTabletID &tablet_id, DeleteTabletInfo &info); - private: - common::ObIArray &tablet_id_hash_array_; - }; class GetAllTabletIDOperator final { public: @@ -474,12 +443,12 @@ private: bool except_ls_inner_tablet_; common::ObIArray &tablet_ids_; }; - class DestroyMemtableAndMemberOperator final + class DestroyMemtableAndMemberAndMdsTableOperator final { public: - DestroyMemtableAndMemberOperator(ObLSTabletService *tablet_svr) + DestroyMemtableAndMemberAndMdsTableOperator(ObLSTabletService *tablet_svr) : tablet_svr_(tablet_svr) {} - ~DestroyMemtableAndMemberOperator() = default; + ~DestroyMemtableAndMemberAndMdsTableOperator() = default; int operator()(const common::ObTabletID &tablet_id); common::ObTabletID cur_tablet_id_; ObLSTabletService *tablet_svr_; @@ -495,15 +464,13 @@ private: ObLSTabletService *tablet_svr_; }; private: + static int refresh_memtable_for_ckpt( + const ObMetaDiskAddr &old_addr, + const ObMetaDiskAddr &cur_addr, + ObTabletHandle &new_tablet_handle); + void report_tablet_to_rs(const common::ObTabletID &tablet_id); void report_tablet_to_rs(const common::ObIArray &tablet_id_array); - int handle_remove_tablets( - const common::ObIArray &slog_params, - const common::ObLinearHashMap &delete_tablet_infos); - int check_and_get_tablet( - const common::ObTabletID &tablet_id, - ObTabletHandle &handle, - const int64_t timeout_us = ObTabletCommon::DEFAULT_GET_TABLET_TIMEOUT_US); int direct_get_tablet( const common::ObTabletID &tablet_id, ObTabletHandle &handle); @@ -516,102 +483,39 @@ private: const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, bool &b_exist); - int create_tablet( - const share::ObLSID &ls_id, - const obrpc::ObBatchCreateTabletArg &arg, - const share::SCN &create_scn, - const obrpc::ObCreateTabletInfo &info, - common::ObIArray &tablet_handle_array, - NonLockedHashSet &data_tablet_id_set); - int do_create_tablet( + int create_inner_tablet( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const common::ObTabletID &data_tablet_id, - const common::ObIArray &index_tablet_array, const share::SCN &create_scn, - const share::SCN &snapshot_version, + const int64_t snapshot_version, const share::schema::ObTableSchema &table_schema, const lib::Worker::CompatMode &compat_mode, - const common::ObTabletID &lob_meta_tablet_id, - const common::ObTabletID &lob_piece_tablet_id, ObTabletHandle &tablet_handle); - int build_single_data_tablet( - const share::ObLSID &ls_id, - const obrpc::ObBatchCreateTabletArg &arg, - const share::SCN &create_scn, - const obrpc::ObCreateTabletInfo &info, - common::ObIArray &tablet_handle_array); - static int build_batch_create_tablet_arg( - const obrpc::ObBatchCreateTabletArg &old_arg, - const NonLockedHashSet &existed_tablet_id_set, - obrpc::ObBatchCreateTabletArg &new_arg); - int add_batch_tablets( - const share::ObLSID &ls_id, - const NonLockedHashSet &data_tablet_id_set, - common::ObIArray &tablet_handle_array); - int do_batch_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const share::SCN &create_scn, - const bool is_replay_clog, - common::ObTimeGuard &time_guard, - NonLockedHashSet &data_tablet_id_set); - int post_handle_batch_create_tablets(const obrpc::ObBatchCreateTabletArg &arg); - int do_remove_lob_tablet(const ObTabletHandle &tablet); - int set_disk_addr(const common::ObTabletID &tablet_id, const ObMetaDiskAddr &disk_addr); - int refresh_tablet_addr( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, - const ObMetaDiskAddr &new_addr, ObTabletHandle &tablet_handle); - int update_tablet_object_and_addr( - ObTabletHandle &new_tablet_handle, - const ObMetaDiskAddr &new_addr); - int create_lob_tablet( - const ObMigrationTabletParam &mig_tablet_param); - int create_lob_tablet( - const ObTablet &data_tablet); + int inner_remove_tablet( + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id); int rollback_rebuild_tablet(const ObTabletID &tablet_id); int trim_old_tablets(const ObTabletID &tablet_id); int rebuild_tablet_with_old( const ObMigrationTabletParam &mig_tablet_param, - ObMetaObjGuard &tablet_guard); + ObTabletHandle &tablet_guard); int migrate_update_tablet(const ObMigrationTabletParam &mig_tablet_param); int migrate_create_tablet( const ObMigrationTabletParam &mig_tablet_param, ObTabletHandle &handle); int delete_all_tablets(); - int choose_msd( - const ObUpdateTableStoreParam ¶m, - const ObTablet &old_tablet, - const ObTabletTxMultiSourceDataUnit *&tx_data, - const ObTabletBindingInfo *&binding_info, - const share::ObTabletAutoincSeq *&auto_inc_seq); - +private: static int check_real_leader_for_4377_(const ObLSID ls_id); - + static int check_need_rollback_in_transfer_for_4377_(const transaction::ObTxDesc *tx_desc, + ObTabletHandle &tablet_handle); static int build_create_sstable_param_for_migration( const blocksstable::ObMigrationSSTableParam &migrate_sstable_param, ObTabletCreateSSTableParam &create_sstable_param); - - static int get_tablet_schema_index( - const common::ObTabletID &tablet_id, - const common::ObIArray &table_ids, - int64_t &index); - static int get_all_tablet_id_hash_array( - const obrpc::ObBatchCreateTabletArg &arg, - common::ObIArray &all_tablet_id_hash_array); - int parse_and_verify_delete_tablet_info( - const obrpc::ObBatchRemoveTabletArg &arg, - common::ObLinearHashMap &delete_tablet_infos); - int get_all_tablet_id_hash_array( - common::ObLinearHashMap &delete_tablet_infos, - common::ObIArray &all_tablet_id_hash_array); - - int verify_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - NonLockedHashSet &existed_tablet_id_set); - int try_pin_tablet_if_needed(const ObTabletHandle &tablet_handle); static int need_check_old_row_legitimacy( ObDMLRunningCtx &run_ctx, bool &need_check, @@ -813,6 +717,13 @@ private: ObStoreCtx &store_ctx, const ObStoreRow &tbl_row); int set_allow_to_read_(ObLS *ls); + // TODO(chenqingxiang.cqx): remove this + int create_empty_shell_tablet( + const ObMigrationTabletParam ¶m, + ObTabletHandle &tablet_handle); + int no_lock_update_tablet_to_empty_shell( + const ObTabletMapKey &key, + ObTabletHandle &new_tablet_handle); private: int direct_insert_rows(const uint64_t table_id, @@ -824,11 +735,13 @@ private: private: friend class ObLSTabletIterator; + friend class ObTabletCreateMdsHelper; ObLS *ls_; ObTxDataMemtableMgr tx_data_memtable_mgr_; ObTxCtxMemtableMgr tx_ctx_memtable_mgr_; ObLockMemtableMgr lock_memtable_mgr_; + mds::ObMdsTableMgr mds_table_mgr_; ObTabletIDSet tablet_id_set_; common::ObBucketLock bucket_lock_; // for tablet update, not for dml observer::ObIMetaReport *rs_reporter_; diff --git a/src/storage/ls/ob_ls_tx_service.cpp b/src/storage/ls/ob_ls_tx_service.cpp index 4a098d783..d10d219f8 100644 --- a/src/storage/ls/ob_ls_tx_service.cpp +++ b/src/storage/ls/ob_ls_tx_service.cpp @@ -162,7 +162,7 @@ int ObLSTxService::get_write_store_ctx(ObTxDesc &tx, ret = OB_NOT_INIT; TRANS_LOG(WARN, "not init", K(ret)); } else { - ret = trans_service_->get_write_store_ctx(tx, snapshot, write_flag, store_ctx); + ret = trans_service_->get_write_store_ctx(tx, snapshot, write_flag, store_ctx, false); } return ret; } @@ -632,6 +632,60 @@ int ObLSTxService::online() return ret; } +int ObLSTxService::block_normal() +{ + int ret = OB_SUCCESS; + bool unused_is_all_tx_clean_up = false; + + if (OB_ISNULL(mgr_)) { + ret = OB_NOT_INIT; + TRANS_LOG(WARN, "not init", KR(ret), K_(ls_id)); + } else if (OB_FAIL(mgr_->block_normal(unused_is_all_tx_clean_up))) { + TRANS_LOG(WARN, "block normal tx failed", K_(ls_id)); + } + return ret; +} + +int ObLSTxService::unblock_normal() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(mgr_)) { + ret = OB_NOT_INIT; + TRANS_LOG(WARN, "not init", KR(ret), K_(ls_id)); + } else if (OB_FAIL(mgr_->unblock_normal())) { + TRANS_LOG(WARN, "ls tx service unblock normal failed", K(ret), K_(ls_id)); + } else { + // do nothing + } + return ret; +} + +int ObLSTxService::get_tx_ctx_count(int64_t &tx_ctx_count) +{ + int ret = OB_SUCCESS; + tx_ctx_count = -1; + if (OB_ISNULL(mgr_)) { + ret = OB_NOT_INIT; + TRANS_LOG(WARN, "not init", KR(ret), K_(ls_id)); + } else { + tx_ctx_count = mgr_->get_tx_ctx_count(); + } + return ret; +} + +int ObLSTxService::get_active_tx_count(int64_t &active_tx_count) +{ + int ret = OB_SUCCESS; + active_tx_count = -1; + if (OB_ISNULL(mgr_)) { + ret = OB_NOT_INIT; + TRANS_LOG(WARN, "not init", KR(ret), K_(ls_id)); + } else { + active_tx_count = mgr_->get_active_tx_count(); + } + return ret; +} + int ObLSTxService::set_max_replay_commit_version(share::SCN commit_version) { int ret = OB_SUCCESS; diff --git a/src/storage/ls/ob_ls_tx_service.h b/src/storage/ls/ob_ls_tx_service.h index 18e792601..3186228d2 100644 --- a/src/storage/ls/ob_ls_tx_service.h +++ b/src/storage/ls/ob_ls_tx_service.h @@ -72,6 +72,10 @@ public: int offline(); int online(); + // NB: block_normal and unblcok should pair used !!! + // when you finish block_noraml, you should unblock_normal then push to other state + int block_normal(); + int unblock_normal(); public: int init(const share::ObLSID &ls_id, transaction::ObLSTxCtxMgr *mgr, @@ -135,6 +139,8 @@ public: transaction::ObTransID &block_tx_id); // get the obj lock op iterator from tx of this ls. int iterate_tx_obj_lock_op(transaction::tablelock::ObLockOpIterator &iter) const; + int get_tx_ctx_count(int64_t &tx_ctx_count); + int get_active_tx_count(int64_t &active_tx_count); public: int replay(const void *buffer, const int64_t nbytes, const palf::LSN &lsn, const share::SCN &scn); diff --git a/src/storage/memtable/mvcc/ob_multi_version_iterator.cpp b/src/storage/memtable/mvcc/ob_multi_version_iterator.cpp index 91b3a6f97..844b8c44f 100644 --- a/src/storage/memtable/mvcc/ob_multi_version_iterator.cpp +++ b/src/storage/memtable/mvcc/ob_multi_version_iterator.cpp @@ -264,8 +264,11 @@ int ObMultiVersionValueIterator::get_trans_status(const transaction::ObTransID & UNUSED(cluster_version); int ret = OB_SUCCESS; SCN trans_version = SCN::max_scn(); - - if (OB_FAIL(ctx_->get_tx_table_guard().get_tx_state_with_scn(trans_id, merge_scn_, state, trans_version))) { + storage::ObTxTableGuards tx_table_guards = ctx_->get_tx_table_guards(); + if (OB_FAIL(tx_table_guards.get_tx_state_with_scn(trans_id, + merge_scn_, + state, + trans_version))) { STORAGE_LOG(WARN, "check_with_tx_data fail.", K(trans_id)); } @@ -576,8 +579,12 @@ int ObMultiVersionRowIterator::try_cleanout_tx_node_(ObMvccRow *value, ObMvccTra { int ret = OB_SUCCESS; const ObTransID data_tx_id = tnode->tx_id_; - if (!(tnode->is_committed() || tnode->is_aborted()) && tnode->is_delayed_cleanout() && - OB_FAIL(ctx_->get_tx_table_guard().cleanout_tx_node(data_tx_id, *value, *tnode, false /*need_row_latch*/))) { + if (!(tnode->is_committed() || tnode->is_aborted()) + && tnode->is_delayed_cleanout() + && OB_FAIL(ctx_->get_tx_table_guards().cleanout_tx_node(data_tx_id, + *value, + *tnode, + false /*need_row_latch*/))) { TRANS_LOG(WARN, "cleanout tx state failed", K(ret), K(*value), K(*tnode)); } else if (!tnode->is_aborted()) { const blocksstable::ObDmlFlag dml_flag = tnode->get_dml_flag(); diff --git a/src/storage/memtable/mvcc/ob_mvcc_acc_ctx.h b/src/storage/memtable/mvcc/ob_mvcc_acc_ctx.h old mode 100644 new mode 100755 index 1e8b029a2..2ef19ddcd --- a/src/storage/memtable/mvcc/ob_mvcc_acc_ctx.h +++ b/src/storage/memtable/mvcc/ob_mvcc_acc_ctx.h @@ -17,6 +17,7 @@ #include "storage/tx/ob_trans_define.h" #include "lib/oblog/ob_log.h" #include "lib/oblog/ob_log_module.h" +#include "storage/tx_table/ob_tx_table_guards.h" #include "storage/memtable/ob_concurrent_control.h" #include "storage/tx_table/ob_tx_table_interface.h" @@ -28,6 +29,8 @@ class ObPartTransCtx; namespace storage { class ObTxTable; +class ObTxTableGuard; +class ObTxTableGuards; } namespace memtable @@ -43,7 +46,7 @@ public: abs_lock_timeout_(-1), tx_lock_timeout_(-1), snapshot_(), - tx_table_guard_(), + tx_table_guards_(), tx_id_(), tx_desc_(NULL), tx_ctx_(NULL), @@ -75,7 +78,7 @@ public: abs_lock_timeout_ = -1; tx_lock_timeout_ = -1; snapshot_.reset(); - tx_table_guard_.reset(); + tx_table_guards_.reset(); tx_id_.reset(); tx_desc_ = NULL; tx_ctx_ = NULL; @@ -101,7 +104,7 @@ public: && mem_ctx_ && tx_scn_ > 0 && tx_id_.is_valid() - && tx_table_guard_.is_valid(); + && tx_table_guards_.is_valid(); } bool is_replay_valid__() const { return tx_ctx_ @@ -111,7 +114,7 @@ public: bool is_read_valid__() const { return abs_lock_timeout_ >= 0 && snapshot_.is_valid() - && tx_table_guard_.is_valid() + && tx_table_guards_.is_valid() && (!tx_ctx_ || mem_ctx_); } void init_read(transaction::ObPartTransCtx *tx_ctx, /* nullable */ @@ -126,7 +129,7 @@ public: type_ = is_weak_read ? T::WEAK_READ : T::STRONG_READ; tx_ctx_ = tx_ctx; mem_ctx_ = mem_ctx; - tx_table_guard_ = tx_table_guard; + tx_table_guards_.tx_table_guard_ = tx_table_guard; snapshot_ = snapshot; abs_lock_timeout_ = abs_lock_timeout; tx_lock_timeout_ = tx_lock_timeout; @@ -159,12 +162,21 @@ public: tx_id_ = tx_id; tx_scn_ = tx_scn; tx_desc_ = &tx_desc; - tx_table_guard_ = tx_table_guard; + tx_table_guards_.tx_table_guard_ = tx_table_guard; snapshot_ = snapshot; abs_lock_timeout_ = abs_lock_timeout; tx_lock_timeout_ = tx_lock_timeout; write_flag_ = write_flag; } + + void set_src_tx_table_guard(const storage::ObTxTableGuard &tx_table_guard) + { + tx_table_guards_.src_tx_table_guard_ = tx_table_guard; + } + void set_transfer_scn(const share::SCN transfer_scn) + { + tx_table_guards_.transfer_start_scn_ = transfer_scn; + } void init_replay(transaction::ObPartTransCtx &tx_ctx, ObMemtableCtx &mem_ctx, const transaction::ObTransID &tx_id) @@ -181,8 +193,9 @@ public: share::SCN get_snapshot_version() const { return snapshot_.version_; } - storage::ObTxTableGuard &get_tx_table_guard() { - return tx_table_guard_; + + storage::ObTxTableGuards &get_tx_table_guards() { + return tx_table_guards_; } ObMemtableCtx *get_mem_ctx() const { return mem_ctx_; @@ -220,7 +233,7 @@ public: K_(abs_lock_timeout), K_(tx_lock_timeout), K_(snapshot), - K_(tx_table_guard), + K_(tx_table_guards), K_(tx_id), KPC_(tx_desc), KP_(tx_ctx), @@ -248,7 +261,7 @@ public: // NOTE: those field should only be accessed by txn relative routine // - When ob_trx_lock_timeout is equal to 0, it means never wait int64_t tx_lock_timeout_; transaction::ObTxSnapshot snapshot_; - storage::ObTxTableGuard tx_table_guard_; + storage::ObTxTableGuards tx_table_guards_; // for transfer query // specials for MvccWrite transaction::ObTransID tx_id_; transaction::ObTxDesc *tx_desc_; // the txn descriptor diff --git a/src/storage/memtable/mvcc/ob_mvcc_ctx.cpp b/src/storage/memtable/mvcc/ob_mvcc_ctx.cpp index 0899b4daa..887bb2a5b 100644 --- a/src/storage/memtable/mvcc/ob_mvcc_ctx.cpp +++ b/src/storage/memtable/mvcc/ob_mvcc_ctx.cpp @@ -56,7 +56,8 @@ int ObIMvccCtx::register_row_commit_cb( const int64_t data_size, const ObRowData *old_row, ObMemtable *memtable, - const int64_t seq_no) + const int64_t seq_no, + const int64_t column_cnt) { int ret = OB_SUCCESS; const bool is_replay = false; @@ -66,9 +67,10 @@ int ObIMvccCtx::register_row_commit_cb( || OB_ISNULL(value) || OB_ISNULL(node) || data_size <= 0 - || OB_ISNULL(memtable)) { + || OB_ISNULL(memtable) + || column_cnt <= 0) { ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid argument", K(key), K(value), K(node), K(data_size), K(memtable)); + TRANS_LOG(WARN, "invalid argument", K(key), K(value), K(node), K(data_size), K(memtable), K(column_cnt)); } else if (OB_ISNULL(cb = alloc_row_callback(*this, *value, memtable))) { ret = OB_ALLOCATE_MEMORY_FAILED; TRANS_LOG(WARN, "alloc row callback failed", K(ret)); @@ -80,7 +82,8 @@ int ObIMvccCtx::register_row_commit_cb( data_size, old_row, is_replay, - seq_no); + seq_no, + column_cnt); cb->set_is_link(); if (OB_FAIL(append_callback(cb))) { @@ -102,7 +105,8 @@ int ObIMvccCtx::register_row_replay_cb( const int64_t data_size, ObMemtable *memtable, const int64_t seq_no, - const SCN scn) + const SCN scn, + const int64_t column_cnt) { int ret = OB_SUCCESS; const bool is_replay = true; @@ -122,7 +126,8 @@ int ObIMvccCtx::register_row_replay_cb( data_size, NULL, is_replay, - seq_no); + seq_no, + column_cnt); { ObRowLatchGuard guard(value->latch_); cb->link_trans_node(); diff --git a/src/storage/memtable/mvcc/ob_mvcc_ctx.h b/src/storage/memtable/mvcc/ob_mvcc_ctx.h index bc1ee4314..dbe523517 100644 --- a/src/storage/memtable/mvcc/ob_mvcc_ctx.h +++ b/src/storage/memtable/mvcc/ob_mvcc_ctx.h @@ -163,7 +163,8 @@ public: const int64_t data_size, const ObRowData *old_row, ObMemtable *memtable, - const int64_t seq_no); + const int64_t seq_no, + const int64_t column_cnt); int register_row_replay_cb( const ObMemtableKey *key, ObMvccRow *value, @@ -171,7 +172,8 @@ public: const int64_t data_size, ObMemtable *memtable, const int64_t seq_no, - const share::SCN scn); + const share::SCN scn, + const int64_t column_cnt); int register_table_lock_cb( transaction::tablelock::ObLockMemtable *memtable, ObMemCtxLockOpLinkNode *lock_op); diff --git a/src/storage/memtable/mvcc/ob_mvcc_define.h b/src/storage/memtable/mvcc/ob_mvcc_define.h index 386a009e0..fac97b49a 100644 --- a/src/storage/memtable/mvcc/ob_mvcc_define.h +++ b/src/storage/memtable/mvcc/ob_mvcc_define.h @@ -44,6 +44,7 @@ struct ObTxNodeArg int64_t seq_no_; // scn_ is thee log ts of the redo log share::SCN scn_; + int64_t column_cnt_; TO_STRING_KV(KP_(data), KP_(old_row), @@ -51,20 +52,23 @@ struct ObTxNodeArg K_(acc_checksum), K_(memstore_version), K_(seq_no), - K_(scn)); + K_(scn), + K_(column_cnt)); // Constructor for leader ObTxNodeArg(const ObMemtableData *data, const ObRowData *old_row, const int64_t memstore_version, - const int64_t seq_no) + const int64_t seq_no, + const int64_t column_cnt) : data_(data), old_row_(old_row), modify_count_(UINT32_MAX), acc_checksum_(0), memstore_version_(memstore_version), seq_no_(seq_no), - scn_(share::SCN::max_scn()) {} + scn_(share::SCN::max_scn()), + column_cnt_(column_cnt) {} // Constructor for follower ObTxNodeArg(const ObMemtableData *data, @@ -73,14 +77,16 @@ struct ObTxNodeArg const int64_t seq_no, const uint32_t modify_count, const uint32_t acc_checksum, - const share::SCN scn) + const share::SCN scn, + const int64_t column_cnt) : data_(data), old_row_(old_row), modify_count_(modify_count), acc_checksum_(acc_checksum), memstore_version_(memstore_version), seq_no_(seq_no), - scn_(scn) {} + scn_(scn), + column_cnt_(column_cnt) {} void reset() { data_ = NULL; @@ -90,6 +96,7 @@ struct ObTxNodeArg memstore_version_ = 0; seq_no_ = 0; scn_ = share::SCN::min_scn(); + column_cnt_ = 0; } }; diff --git a/src/storage/memtable/mvcc/ob_mvcc_iterator.cpp b/src/storage/memtable/mvcc/ob_mvcc_iterator.cpp old mode 100644 new mode 100755 index 404af9416..363f7fd7f --- a/src/storage/memtable/mvcc/ob_mvcc_iterator.cpp +++ b/src/storage/memtable/mvcc/ob_mvcc_iterator.cpp @@ -128,6 +128,11 @@ int ObMvccValueIterator::lock_for_read_inner_(const ObQueryFlag &flag, // // NB: For cursor, it will have its snapshot_tx_id different from // reader_tx_id. + const ObTransID &snapshot_tx_id = ctx_->snapshot_.tx_id_; + const ObTransID &reader_tx_id = ctx_->tx_id_; + const int64_t snapshot_seq_no = ctx_->snapshot_.scn_; + + const SCN snapshot_version = ctx_->get_snapshot_version(); const bool read_latest = flag.is_read_latest(); const ObTransID &data_tx_id = iter->get_tx_id(); @@ -141,7 +146,7 @@ int ObMvccValueIterator::lock_for_read_inner_(const ObQueryFlag &flag, const bool is_aborted = iter->is_aborted(); const bool is_elr = iter->is_elr(); const bool is_delayed_cleanout = iter->is_delayed_cleanout(); - + const SCN scn = iter->get_scn(); // Opt1: data is decided if ((is_committed || is_aborted || is_elr) // Opt2: data is not decided while we donot need cleanout @@ -218,10 +223,15 @@ int ObMvccValueIterator::lock_for_read_inner_(const ObQueryFlag &flag, ObLockForReadArg lock_for_read_arg(*ctx_, data_tx_id, iter->get_seq_no(), - read_latest); + read_latest, + scn); - if (OB_FAIL(ctx_->get_tx_table_guard().lock_for_read( - lock_for_read_arg, can_read, data_version, is_determined_state, *cleanout_op, *recheck_op))) { + if (OB_FAIL(ctx_->get_tx_table_guards().lock_for_read(lock_for_read_arg, + can_read, + data_version, + is_determined_state, + *cleanout_op, + *recheck_op))) { TRANS_LOG(WARN, "lock for read failed", KPC(iter), K(lock_for_read_arg)); } else if (can_read && ctx_->get_snapshot_version() >= data_version) { // Case 5.1: data is cleanout by lock for read and can be read by reader's @@ -258,8 +268,13 @@ int ObMvccValueIterator::lock_for_read_inner_(const ObQueryFlag &flag, int ObMvccValueIterator::try_cleanout_tx_node_(ObMvccTransNode *tnode) { int ret = OB_SUCCESS; - if (!(tnode->is_committed() || tnode->is_aborted()) && tnode->is_delayed_cleanout() && - OB_FAIL(ctx_->get_tx_table_guard().cleanout_tx_node(tnode->tx_id_, *value_, *tnode, true /*need_row_latch*/))) { + auto tx_table_guards = ctx_->get_tx_table_guards(); + if (!(tnode->is_committed() || tnode->is_aborted()) + && tnode->is_delayed_cleanout() + && OB_FAIL(tx_table_guards.cleanout_tx_node(tnode->tx_id_, + *value_, + *tnode, + true /*need_row_latch*/))) { TRANS_LOG(WARN, "cleanout tx state failed", K(ret), K(*value_), K(*tnode)); } return ret; diff --git a/src/storage/memtable/mvcc/ob_mvcc_row.cpp b/src/storage/memtable/mvcc/ob_mvcc_row.cpp index 094799f4d..0c25af901 100644 --- a/src/storage/memtable/mvcc/ob_mvcc_row.cpp +++ b/src/storage/memtable/mvcc/ob_mvcc_row.cpp @@ -897,6 +897,7 @@ int ObMvccRow::mvcc_write_(ObIMemtableCtx &ctx, lock_state.lock_dml_flag_ = iter->get_dml_flag(); lock_state.is_delayed_cleanout_ = iter->is_delayed_cleanout(); lock_state.mvcc_row_ = this; + lock_state.trans_scn_ = iter->get_scn(); } } } @@ -1044,6 +1045,7 @@ int ObMvccRow::check_row_locked(ObMvccAccessCtx &ctx, ObStoreRowLockState &lock_ ObRowLatchGuard guard(latch_); auto iter = ATOMIC_LOAD(&list_head_); + auto tx_table_guards = ctx.get_tx_table_guards(); bool need_retry = true; while (OB_SUCC(ret) && need_retry) { @@ -1055,8 +1057,12 @@ int ObMvccRow::check_row_locked(ObMvccAccessCtx &ctx, ObStoreRowLockState &lock_ need_retry = false; } else { auto data_tx_id = iter->tx_id_; - if (!(iter->is_committed() || iter->is_aborted()) && iter->is_delayed_cleanout() && - OB_FAIL(ctx.get_tx_table_guard().cleanout_tx_node(data_tx_id, *this, *iter, false /*need_row_latch*/))) { + if (!(iter->is_committed() || iter->is_aborted()) + && iter->is_delayed_cleanout() + && OB_FAIL(tx_table_guards.cleanout_tx_node(data_tx_id, + *this, + *iter, + false /*need_row_latch*/))) { TRANS_LOG(WARN, "cleanout tx state failed", K(ret), K(*this)); } else if (iter->is_committed() || iter->is_elr()) { // Case 2: the newest node is decided, so node currently is not be locked @@ -1074,6 +1080,7 @@ int ObMvccRow::check_row_locked(ObMvccAccessCtx &ctx, ObStoreRowLockState &lock_ lock_state.lock_data_sequence_ = iter->get_seq_no(); lock_state.lock_dml_flag_ = iter->get_dml_flag(); lock_state.is_delayed_cleanout_ = iter->is_delayed_cleanout(); + lock_state.trans_scn_ = iter->get_scn(); need_retry = false; } } diff --git a/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.cpp b/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.cpp index 7d2cc9bc7..2560b08c8 100644 --- a/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.cpp +++ b/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.cpp @@ -42,7 +42,8 @@ void RedoDataNode::set(const ObMemtableKey *key, const int64_t version, const int32_t flag, const int64_t seq_no, - const common::ObTabletID &tablet_id) + const common::ObTabletID &tablet_id, + const int64_t column_cnt) { key_.encode(*key); old_row_ = old_row; @@ -55,6 +56,7 @@ void RedoDataNode::set(const ObMemtableKey *key, seq_no_ = seq_no; callback_ = NULL; tablet_id_ = tablet_id; + column_cnt_ = column_cnt; } void TableLockRedoDataNode::set( @@ -1190,7 +1192,8 @@ int ObMvccRowCallback::get_redo(RedoDataNode &redo_node) tnode_->version_, 0, seq_no_, - this->get_tablet_id()); + this->get_tablet_id(), + column_cnt_); redo_node.set_callback(this); } return ret; diff --git a/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.h b/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.h index 61ca590fe..43d1b43d5 100644 --- a/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.h +++ b/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.h @@ -50,7 +50,8 @@ struct RedoDataNode const int64_t version, const int32_t flag, const int64_t seq_no, - const common::ObTabletID &tablet_id); + const common::ObTabletID &tablet_id, + const int64_t column_cnt); void set_callback(ObITransCallback *callback) { callback_ = callback; } ObMemtableKey key_; ObRowData old_row_; @@ -63,6 +64,7 @@ struct RedoDataNode int64_t seq_no_; ObITransCallback *callback_; common::ObTabletID tablet_id_; + int64_t column_cnt_; }; struct TableLockRedoDataNode @@ -347,7 +349,8 @@ public: memtable_(memtable), is_link_(false), not_calc_checksum_(false), - seq_no_(0) + seq_no_(0), + column_cnt_(0) {} ObMvccRowCallback(ObMvccRowCallback &cb, ObMemtable *memtable) : ObITransCallback(cb.need_fill_redo_, cb.need_submit_log_), @@ -358,7 +361,8 @@ public: memtable_(memtable), is_link_(cb.is_link_), not_calc_checksum_(cb.not_calc_checksum_), - seq_no_(cb.seq_no_) + seq_no_(cb.seq_no_), + column_cnt_(cb.column_cnt_) { (void)key_.encode(cb.key_.get_rowkey()); } @@ -372,7 +376,8 @@ public: const int64_t data_size, const ObRowData *old_row, const bool is_replay, - const int64_t seq_no) + const int64_t seq_no, + const int64_t column_cnt) { UNUSED(is_replay); @@ -394,6 +399,7 @@ public: if (tnode_) { tnode_->set_seq_no(seq_no_); } + column_cnt_ = column_cnt; } bool on_memtable(const ObIMemtable * const memtable) override; ObIMemtable *get_memtable() const override; @@ -465,6 +471,7 @@ private: bool not_calc_checksum_ : 1; }; int64_t seq_no_; + int64_t column_cnt_; }; }; // end namespace memtable diff --git a/src/storage/memtable/ob_memtable.cpp b/src/storage/memtable/ob_memtable.cpp old mode 100644 new mode 100755 index 70e5b0adc..f471b9bcf --- a/src/storage/memtable/ob_memtable.cpp +++ b/src/storage/memtable/ob_memtable.cpp @@ -105,6 +105,7 @@ ObMemtable::ObMemtable() query_engine_(local_allocator_), mvcc_engine_(), max_schema_version_(0), + max_data_schema_version_(0), pending_cb_cnt_(0), unsubmitted_cnt_(0), unsynced_cnt_(0), @@ -113,6 +114,8 @@ ObMemtable::ObMemtable() logging_blocked_start_time(0), unset_active_memtable_logging_blocked_(false), resolve_active_memtable_left_boundary_(true), + transfer_freeze_flag_(false), + recommend_snapshot_version_(share::SCN::invalid_scn()), freeze_scn_(SCN::max_scn()), max_end_scn_(ObScnRange::MIN_SCN), rec_scn_(SCN::max_scn()), @@ -132,7 +135,8 @@ ObMemtable::ObMemtable() multi_source_data_(local_allocator_), multi_source_data_lock_(), encrypt_meta_(nullptr), - encrypt_meta_lock_(ObLatchIds::DEFAULT_SPIN_RWLOCK) + encrypt_meta_lock_(ObLatchIds::DEFAULT_SPIN_RWLOCK), + max_column_cnt_(0) { mt_stat_.reset(); migration_clog_checkpoint_scn_.set_min(); @@ -181,6 +185,7 @@ int ObMemtable::init(const ObITable::TableKey &table_key, TRANS_LOG(WARN, "failed to set_table_key", K(ret), K(table_key)); } else { ls_handle_ = ls_handle; + ls_id_ = ls_handle_.get_ls()->get_ls_id(); if (table_key.get_tablet_id().is_sys_tablet()) { mode_ = lib::Worker::CompatMode::MYSQL; } else { @@ -252,6 +257,8 @@ void ObMemtable::destroy() memtable_mgr_ = nullptr; freeze_clock_ = 0; max_schema_version_ = 0; + max_data_schema_version_ = 0; + max_column_cnt_ = 0; mt_stat_.reset(); state_ = ObMemtableState::INVALID; freeze_state_ = ObMemtableFreezeState::INVALID; @@ -262,6 +269,8 @@ void ObMemtable::destroy() logging_blocked_start_time = 0; unset_active_memtable_logging_blocked_ = false; resolve_active_memtable_left_boundary_ = true; + transfer_freeze_flag_ = false; + recommend_snapshot_version_.reset(); max_end_scn_ = ObScnRange::MIN_SCN; migration_clog_checkpoint_scn_.set_min(); rec_scn_ = SCN::max_scn(); @@ -315,9 +324,8 @@ void ObMemtable::set_end(ObMvccAccessCtx &ctx, int ret) } int ObMemtable::set( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, const common::ObIArray &columns, const storage::ObStoreRow &row, const share::ObEncryptMeta *encrypt_meta) @@ -327,36 +335,32 @@ int ObMemtable::set( if (IS_NOT_INIT) { TRANS_LOG(WARN, "not init", K(*this)); ret = OB_NOT_INIT; - } else if (NULL == ctx.mvcc_acc_ctx_.get_mem_ctx() - || read_info.get_schema_rowkey_count() > columns.count() + } else if (!param.is_valid() || !context.is_valid()) { + ret = OB_INVALID_ARGUMENT; + TRANS_LOG(WARN, "invalid argument, ", K(ret), K(param), K(context)); + } else if (NULL == context.store_ctx_->mvcc_acc_ctx_.get_mem_ctx() + || param.get_schema_rowkey_count() > columns.count() || row.row_val_.count_ < columns.count()) { - TRANS_LOG(WARN, "invalid param", K(ctx), K(read_info), + TRANS_LOG(WARN, "invalid param", K(param), K(columns.count()), K(row.row_val_.count_)); ret = OB_INVALID_ARGUMENT; } if (OB_FAIL(ret)) { - } else if (OB_FAIL(guard.write_auth(ctx))) { - TRANS_LOG(WARN, "not allow to write", K(ctx)); + } else if (OB_FAIL(guard.write_auth(*context.store_ctx_))) { + TRANS_LOG(WARN, "not allow to write", K(*context.store_ctx_)); } else { lib::CompatModeGuard compat_guard(mode_); - ret = set_(ctx, - table_id, - read_info, - columns, - row, - NULL, - NULL); + ret = set_(param, context, columns, row, NULL, NULL); guard.set_memtable(this); } return ret; } int ObMemtable::set( - ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, const ObIArray &columns, const ObIArray &update_idx, const storage::ObStoreRow &old_row, @@ -368,131 +372,31 @@ int ObMemtable::set( if (IS_NOT_INIT) { TRANS_LOG(WARN, "not init", K(*this)); ret = OB_NOT_INIT; - } else if (NULL == ctx.mvcc_acc_ctx_.get_mem_ctx() - || read_info.get_schema_rowkey_count() > columns.count()) { + } else if (!param.is_valid() || !context.is_valid()) { ret = OB_INVALID_ARGUMENT; - TRANS_LOG(ERROR, "invalid param", K(ret), K(ctx), K(read_info)); + TRANS_LOG(WARN, "invalid argument, ", K(ret), K(param), K(context)); + } else if (NULL == context.store_ctx_->mvcc_acc_ctx_.get_mem_ctx() + || param.get_schema_rowkey_count() > columns.count()) { + ret = OB_INVALID_ARGUMENT; + TRANS_LOG(ERROR, "invalid param", K(ret), K(param)); } if (OB_FAIL(ret)){ - } else if (OB_FAIL(guard.write_auth(ctx))) { - TRANS_LOG(WARN, "not allow to write", K(ctx)); + } else if (OB_FAIL(guard.write_auth(*context.store_ctx_))) { + TRANS_LOG(WARN, "not allow to write", K(*context.store_ctx_)); } else { lib::CompatModeGuard compat_guard(mode_); - ret = set_(ctx, - table_id, - read_info, - columns, - new_row, - &old_row, - &update_idx); + ret = set_(param, context, columns, new_row, &old_row, &update_idx); guard.set_memtable(this); } return ret; } -int ObMemtable::lock_(ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const ObStoreRowkey &rowkey, - ObMemtableKey &mtk) -{ - int ret = OB_SUCCESS; - bool is_new_locked = false; - blocksstable::ObRowWriter row_writer; - char *buf = NULL; - int64_t len = 0; - if (OB_FAIL(mtk.encode(read_info.get_columns_desc(), &rowkey))) { - TRANS_LOG(WARN, "mtk encode fail", "ret", ret); - } else if (OB_FAIL(row_writer.write_rowkey(rowkey, buf, len))) { - TRANS_LOG(WARN, "Failed to writer rowkey", K(ret), K(rowkey)); - } else { - // for elr optimization - ctx.mvcc_acc_ctx_.get_mem_ctx()->set_row_updated(); - ObMemtableData mtd(blocksstable::ObDmlFlag::DF_LOCK, len, buf); - ObTxNodeArg arg(&mtd, /*memtable_data*/ - NULL, /*old_data*/ - timestamp_, /*memstore_version*/ - ctx.mvcc_acc_ctx_.tx_scn_ /*seq_no*/); - if (OB_FAIL(mvcc_write_(ctx, - &mtk, - /*used for mvcc_write on sstable*/ - read_info, - arg, - is_new_locked))) { - } else if (OB_UNLIKELY(!is_new_locked)) { - TRANS_LOG(DEBUG, "lock twice, no need to store lock trans node", K(table_id), K(ctx)); - } - } - - return ret; -} - -int ObMemtable::lock_(ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const ObStoreRowkey &rowkey) -{ - int ret = OB_SUCCESS; - ObMemtableKey mtk; - if (OB_FAIL(lock_(ctx, table_id, read_info, rowkey, mtk))) { - } - return ret; -} - -int ObMemtable::lock(ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - ObNewRowIterator &row_iter) -{ - int ret = OB_SUCCESS; - ObMvccWriteGuard guard; - - if (IS_NOT_INIT) { - TRANS_LOG(WARN, "not init", K(*this)); - ret = OB_NOT_INIT; - } else if (!read_info.is_valid() || !ctx.mvcc_acc_ctx_.is_write()) { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid param", K(ret), K(ctx), K(read_info)); - } else if (OB_FAIL(guard.write_auth(ctx))) { - TRANS_LOG(WARN, "not allow to write", K(ctx)); - } else { - ObNewRow *row = NULL; - ObMemtableKey mtk; - ObStoreRowkey tmp_key; - - while (OB_SUCCESS == ret && OB_SUCCESS == (ret = row_iter.get_next_row(row))) { - if (OB_ISNULL(row)) { - TRANS_LOG(WARN, "row iter get next row null pointer"); - ret = OB_ERR_UNEXPECTED; - } else { - mtk.reset(); - if (OB_FAIL(tmp_key.assign(row->cells_, read_info.get_schema_rowkey_count()))) { - TRANS_LOG(WARN, "Failed to assign tmp rowkey", K(ret), KPC(row), K(read_info)); - } else if (OB_FAIL(lock_(ctx, table_id, read_info, tmp_key, mtk))) { - TRANS_LOG(WARN, "lock_ failed", K(ret), K(ctx)); - } - } - } - ret = (OB_ITER_END == ret) ? OB_SUCCESS : ret; - } - if (OB_FAIL(ret) && (OB_TRY_LOCK_ROW_CONFLICT != ret)) { - TRANS_LOG(WARN, "lock fail", - "ret", ret, - "tablet_id", key_.tablet_id_, - "ctx", ctx, - "table_id", table_id, - "row_iter_ptr", &row_iter); - } - return ret; -} - int ObMemtable::lock( - ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const ObNewRow &row) + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const common::ObNewRow &row) { int ret = OB_SUCCESS; ObMvccWriteGuard guard; @@ -502,41 +406,29 @@ int ObMemtable::lock( if (IS_NOT_INIT) { TRANS_LOG(WARN, "not init", K(*this)); ret = OB_NOT_INIT; - } else if (!ctx.mvcc_acc_ctx_.is_write() - || !read_info.is_valid() - || row.count_ < read_info.get_schema_rowkey_count()) { + } else if (!context.store_ctx_->mvcc_acc_ctx_.is_write() + || row.count_ < param.get_schema_rowkey_count()) { ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid param", K(ret), K(ctx), K(row), K(read_info)); - } else if (OB_FAIL(guard.write_auth(ctx))) { - TRANS_LOG(WARN, "not allow to write", K(ctx)); - } else if (OB_FAIL(tmp_key.assign(row.cells_, - read_info.get_schema_rowkey_count()))) { - TRANS_LOG(WARN, "Failed to assign rowkey", K(row), K(read_info)); - } else if (OB_FAIL(lock_(ctx, - table_id, - read_info, - tmp_key))) { - TRANS_LOG(WARN, "lock_ failed", K(ret), K(ctx)); + TRANS_LOG(WARN, "invalid param", K(ret), K(row), K(param)); + } else if (OB_FAIL(guard.write_auth(*context.store_ctx_))) { + TRANS_LOG(WARN, "not allow to write", K(*context.store_ctx_)); + } else if (OB_FAIL(tmp_key.assign(row.cells_, param.get_schema_rowkey_count()))) { + TRANS_LOG(WARN, "Failed to assign rowkey", K(row), K(param)); + } else if (OB_FAIL(lock_(param, context, tmp_key))) { + TRANS_LOG(WARN, "lock_ failed", K(ret), K(param)); } if (OB_FAIL(ret) && (OB_TRY_LOCK_ROW_CONFLICT != ret)) { - TRANS_LOG(WARN, "lock fail", - "ret", ret, - "tablet_id", key_.tablet_id_, - "ctx", ctx, - "table_id", table_id, - "row", row, - "mtk", mtk); + TRANS_LOG(WARN, "lock fail", K(ret), K(row), K(mtk)); } return ret; } int ObMemtable::lock( - ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const ObDatumRowkey &rowkey) + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const blocksstable::ObDatumRowkey &rowkey) { int ret = OB_SUCCESS; ObMvccWriteGuard guard; @@ -544,55 +436,43 @@ int ObMemtable::lock( if (IS_NOT_INIT) { TRANS_LOG(WARN, "not init", K(*this)); ret = OB_NOT_INIT; - } else if (!ctx.mvcc_acc_ctx_.is_write() - || !rowkey.is_memtable_valid() - || !read_info.is_valid()) { + } else if (!context.store_ctx_->mvcc_acc_ctx_.is_write() || !rowkey.is_memtable_valid()) { ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid param", K(ret), K(ctx), K(rowkey), K(read_info)); - } else if (OB_FAIL(guard.write_auth(ctx))) { - TRANS_LOG(WARN, "not allow to write", K(ctx)); - } else if (OB_FAIL(lock_(ctx, - table_id, - read_info, - rowkey.get_store_rowkey()))) { + TRANS_LOG(WARN, "invalid param", K(ret), K(rowkey)); + } else if (OB_FAIL(guard.write_auth(*context.store_ctx_))) { + TRANS_LOG(WARN, "not allow to write", K(*context.store_ctx_)); + } else if (OB_FAIL(lock_(param, context, rowkey.get_store_rowkey()))) { } if (OB_FAIL(ret) && (OB_TRY_LOCK_ROW_CONFLICT != ret) && (OB_TRANSACTION_SET_VIOLATION != ret)) { - TRANS_LOG(WARN, "lock fail", - "ret", ret, - "tablet_id", key_.tablet_id_, - "ctx", ctx, - "table_id", table_id, - "row", rowkey); + TRANS_LOG(WARN, "lock fail", K(ret), K(rowkey)); } return ret; } int ObMemtable::check_row_locked_by_myself( - ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const ObDatumRowkey &rowkey, + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const blocksstable::ObDatumRowkey &rowkey, bool &locked) { int ret = OB_SUCCESS; ObMemtableKey mtk; ObMvccWriteGuard guard; + ObStoreCtx *ctx = context.store_ctx_; if (IS_NOT_INIT) { TRANS_LOG(WARN, "not init", K(*this)); ret = OB_NOT_INIT; - } else if (!ctx.mvcc_acc_ctx_.is_write() - || !rowkey.is_memtable_valid() - || !read_info.is_valid()) { + } else if (!ctx->mvcc_acc_ctx_.is_write() || !rowkey.is_memtable_valid()) { ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid param", K(ret), K(ctx), K(rowkey), K(read_info)); - } else if (OB_ISNULL(ctx.table_iter_)) { + TRANS_LOG(WARN, "invalid param", K(ret), KP(ctx), K(rowkey)); + } else if (OB_ISNULL(ctx->table_iter_)) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(ERROR, "tables handle or iterator in context is null", K(ret), K(ctx)); - } else if (OB_FAIL(guard.write_auth(ctx))) { - TRANS_LOG(WARN, "not allow to write", K(ctx)); - } else if (OB_FAIL(mtk.encode(read_info.get_columns_desc(), &rowkey.get_store_rowkey()))) { + } else if (OB_FAIL(guard.write_auth(*ctx))) { + TRANS_LOG(WARN, "not allow to write", KP(ctx)); + } else if (OB_FAIL(mtk.encode(param.get_read_info()->get_columns_desc(), &rowkey.get_store_rowkey()))) { TRANS_LOG(WARN, "mtk encode fail", "ret", ret); } else { bool is_locked = false; @@ -600,17 +480,17 @@ int ObMemtable::check_row_locked_by_myself( ObStoreRowLockState lock_state; const ObIArray *stores = nullptr; common::ObSEArray iter_tables; - ctx.table_iter_->resume(); - ObTransID my_tx_id = ctx.mvcc_acc_ctx_.get_tx_id(); + ctx->table_iter_->resume(); + ObTransID my_tx_id = ctx->mvcc_acc_ctx_.get_tx_id(); while (OB_SUCC(ret)) { ObITable *table_ptr = nullptr; - if (OB_FAIL(ctx.table_iter_->get_next(table_ptr))) { + if (OB_FAIL(ctx->table_iter_->get_next(table_ptr))) { if (OB_ITER_END != ret) { TRANS_LOG(WARN, "failed to get next tables", K(ret)); } } else if (OB_ISNULL(table_ptr)) { ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "table must not be null", K(ret), KPC(ctx.table_iter_)); + TRANS_LOG(WARN, "table must not be null", K(ret), KPC(ctx->table_iter_)); } else if (OB_FAIL(iter_tables.push_back(table_ptr))) { TRANS_LOG(WARN, "rowkey_exists check::", K(ret), KPC(table_ptr)); } @@ -627,7 +507,7 @@ int ObMemtable::check_row_locked_by_myself( TRANS_LOG(WARN, "ObIStore is null", K(ret), K(i)); } else if (stores->at(i)->is_data_memtable()) { ObMemtable *memtable = static_cast(stores->at(i)); - if (OB_FAIL(memtable->get_mvcc_engine().check_row_locked(ctx.mvcc_acc_ctx_, + if (OB_FAIL(memtable->get_mvcc_engine().check_row_locked(ctx->mvcc_acc_ctx_, &mtk, lock_state))) { TRANS_LOG(WARN, "mvcc engine check row lock fail", K(ret), K(mtk)); @@ -636,10 +516,7 @@ int ObMemtable::check_row_locked_by_myself( } } else if (stores->at(i)->is_sstable()) { ObSSTable *sstable = static_cast(stores->at(i)); - if (OB_FAIL(sstable->check_row_locked(ctx, - read_info, - rowkey, - lock_state))) { + if (OB_FAIL(sstable->check_row_locked(param, context, rowkey, lock_state))) { TRANS_LOG(WARN, "sstable check row lock fail", K(ret), K(rowkey)); } else if (lock_state.is_locked_ && lock_state.lock_trans_id_ == my_tx_id) { is_locked = true; @@ -660,6 +537,7 @@ int ObMemtable::check_row_locked_by_myself( return ret; } + //////////////////////////////////////////////////////////////////////////////////////////////////// void ObMemtable::get_begin(ObMvccAccessCtx &ctx) { @@ -678,9 +556,8 @@ void ObMemtable::get_end(ObMvccAccessCtx &ctx, int ret) } int ObMemtable::exist( - ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, + const ObTableIterParam ¶m, + ObTableAccessContext &context, const blocksstable::ObDatumRowkey &rowkey, bool &is_exist, bool &has_found) @@ -692,19 +569,19 @@ int ObMemtable::exist( ObQueryFlag query_flag; query_flag.read_latest_ = true; query_flag.prewarm_ = false; - //get_begin(ctx.mvcc_acc_ctx_); + //get_begin(context.store_ctx_->mvcc_acc_ctx_); if (IS_NOT_INIT) { ret = OB_NOT_INIT; TRANS_LOG(WARN, "not init", K(*this), K(ret)); - } else if (!ctx.mvcc_acc_ctx_.is_valid() + } else if (!param.is_valid() || !rowkey.is_memtable_valid() - || !read_info.is_valid()) { + || !context.is_valid()) { ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid param", K(ret), K(ctx), K(rowkey), K(read_info)); - } else if (OB_FAIL(parameter_mtk.encode(read_info.get_columns_desc(), + TRANS_LOG(WARN, "invalid param", K(ret), K(param), K(rowkey), K(context)); + } else if (OB_FAIL(parameter_mtk.encode(param.get_read_info()->get_columns_desc(), &rowkey.get_store_rowkey()))) { TRANS_LOG(WARN, "mtk encode fail", "ret", ret); - } else if (OB_FAIL(mvcc_engine_.get(ctx.mvcc_acc_ctx_, + } else if (OB_FAIL(mvcc_engine_.get(context.store_ctx_->mvcc_acc_ctx_, query_flag, ¶meter_mtk, &returned_mtk, @@ -735,10 +612,11 @@ 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(context.store_ctx_->mvcc_acc_ctx_, ret); return ret; } + int ObMemtable::exist( storage::ObRowsInfo &rows_info, bool &is_exist, @@ -749,21 +627,14 @@ int ObMemtable::exist( ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid argument to exist scan", K(rows_info), K(ret)); } else { - ObStoreCtx &ctx = rows_info.exist_helper_.get_store_ctx(); - const storage::ObTableReadInfo *read_info = rows_info.exist_helper_.get_read_info(); - if (OB_ISNULL(read_info)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "Unexpected null read_info", K(ret), K(rows_info.exist_helper_)); - } is_exist = false; all_rows_found = false; for (int64_t i = 0; OB_SUCC(ret) && !is_exist && !all_rows_found && i < rows_info.rowkeys_.count(); i++) { const blocksstable::ObDatumRowkey &rowkey = rows_info.rowkeys_.at(i); bool row_found = false; if (rowkey.is_max_rowkey()) { //skip deleted rowkey - } else if (OB_FAIL(exist(ctx, - rows_info.table_id_, - *read_info, + } else if (OB_FAIL(exist(rows_info.exist_helper_.table_iter_param_, + rows_info.exist_helper_.table_access_context_, rowkey, is_exist, row_found))) { @@ -809,8 +680,7 @@ int ObMemtable::get( ObMemtableKey parameter_mtk; ObMemtableKey returned_mtk; ObMvccValueIterator value_iter; - const ObTableReadInfo *read_info = nullptr; - + const ObITableReadInfo *read_info = nullptr; if (IS_NOT_INIT) { TRANS_LOG(WARN, "not init", K(*this)); ret = OB_NOT_INIT; @@ -843,9 +713,11 @@ int ObMemtable::get( key_.tablet_id_, freezer_->get_ls_id(), value_iter.get_mvcc_row()->get_last_compact_cnt(), - value_iter.get_mvcc_row()->get_total_trans_node_cnt()); + value_iter.get_mvcc_row()->get_total_trans_node_cnt(), + lock_state.trans_scn_); } } else { + const int64_t request_cnt = read_info->get_request_count(); if (OB_UNLIKELY(!row.is_valid())) { char *trans_info_ptr = nullptr; if (param.need_trans_info()) { @@ -857,7 +729,7 @@ int ObMemtable::get( } if (OB_FAIL(ret)) { // do nothing - } else if (OB_FAIL(row.init(*context.stmt_allocator_, out_cols.count(), trans_info_ptr))) { + } else if (OB_FAIL(row.init(*context.stmt_allocator_, request_cnt, trans_info_ptr))) { STORAGE_LOG(WARN, "Failed to init datum row", K(ret), K(param.need_trans_info())); } } @@ -872,8 +744,8 @@ int ObMemtable::get( } ObNopBitMap bitmap; int64_t row_scn = 0; - if (OB_FAIL(bitmap.init(out_cols.count(), store_rowkey->get_obj_cnt()))) { - TRANS_LOG(WARN, "Failed to innt bitmap", K(ret), K(out_cols), KPC(store_rowkey)); + if (OB_FAIL(bitmap.init(request_cnt, store_rowkey->get_obj_cnt()))) { + TRANS_LOG(WARN, "Failed to innt bitmap", K(ret), K(request_cnt), KPC(store_rowkey)); } else if (OB_FAIL(ObReadRow::iterate_row(*read_info, *store_rowkey, *context.allocator_, value_iter, row, bitmap, row_scn))) { TRANS_LOG(WARN, "Failed to iterate row, ", K(ret), K(rowkey)); } else { @@ -1139,6 +1011,7 @@ int ObMemtable::replay_row(ObStoreCtx &ctx, int64_t version = 0; int32_t flag = 0; int64_t seq_no = 0; + int64_t column_cnt = 0; ObStoreRowkey rowkey; ObRowData row; ObRowData old_row; @@ -1151,7 +1024,7 @@ int ObMemtable::replay_row(ObStoreCtx &ctx, if (OB_FAIL(mmi->get_mutator_row().copy(table_id, rowkey, table_version, row, old_row, dml_flag, modify_count, acc_checksum, version, - flag, seq_no))) { + flag, seq_no, column_cnt))) { if (OB_ITER_END != ret) { TRANS_LOG(WARN, "get next row error", K(ret)); } @@ -1173,7 +1046,8 @@ int ObMemtable::replay_row(ObStoreCtx &ctx, seq_no, /*seq_no*/ modify_count, /*modify_count*/ acc_checksum, /*acc_checksum*/ - scn /*scn*/); + scn, /*scn*/ + column_cnt /*column_cnt*/); if (OB_FAIL(mtk.encode(&rowkey))) { TRANS_LOG(WARN, "mtk encode fail", "ret", ret); @@ -1187,9 +1061,12 @@ int ObMemtable::replay_row(ObStoreCtx &ctx, TRANS_LOG(WARN, "m_replay_row fail", K(ret), K(table_id), K(rowkey), K(row), K(dml_flag), K(modify_count), K(acc_checksum)); } - } else if (part_ctx->need_update_schema_version(log_id, scn)) { - ctx.mvcc_acc_ctx_.mem_ctx_->set_table_version(table_version); - set_max_schema_version(table_version); + } else { + if (part_ctx->need_update_schema_version(log_id, scn)) { + ctx.mvcc_acc_ctx_.mem_ctx_->set_table_version(table_version); + } + set_max_data_schema_version(table_version); + set_max_column_cnt(column_cnt); } } return ret; @@ -1197,17 +1074,18 @@ int ObMemtable::replay_row(ObStoreCtx &ctx, //////////////////////////////////////////////////////////////////////////////////////////////////// -int ObMemtable::lock_row_on_frozen_stores_(ObStoreCtx &ctx, - const ObTxNodeArg &arg, - const ObMemtableKey *key, - ObMvccRow *value, - const storage::ObTableReadInfo &read_info, - ObMvccWriteResult &res) +int ObMemtable::lock_row_on_frozen_stores_( + const storage::ObTableIterParam ¶m, + const ObTxNodeArg &arg, + storage::ObTableAccessContext &context, + const ObMemtableKey *key, + ObMvccRow *value, + ObMvccWriteResult &res) { int ret = OB_SUCCESS; - const int64_t reader_seq_no = ctx.mvcc_acc_ctx_.snapshot_.scn_; ObStoreRowLockState &lock_state = res.lock_state_; - + ObStoreCtx &ctx = *(context.store_ctx_); + const int64_t reader_seq_no = ctx.mvcc_acc_ctx_.snapshot_.scn_; if (OB_ISNULL(value) || !ctx.mvcc_acc_ctx_.is_write() || NULL == key) { TRANS_LOG(WARN, "invalid param", KP(value), K(ctx), KP(key)); ret = OB_INVALID_ARGUMENT; @@ -1255,10 +1133,15 @@ int ObMemtable::lock_row_on_frozen_stores_(ObStoreCtx &ctx, } else if (stores->at(i)->is_data_memtable()) { ObMemtable *memtable = static_cast(stores->at(i)); ObMvccEngine &mvcc_engine = memtable->get_mvcc_engine(); - if (OB_UNLIKELY(memtable->is_active_memtable())) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(ERROR, "lock row on frozen stores check an active memtable", K(ret), KPC(stores)); - } else if (OB_FAIL(mvcc_engine.check_row_locked(ctx.mvcc_acc_ctx_, key, lock_state))) { + //TODO(handora.qc): fix memtable check +// if (OB_UNLIKELY(memtable->is_active_memtable())) { +// ret = OB_ERR_UNEXPECTED; +// TRANS_LOG(ERROR, "lock row on frozen stores check an active memtable", K(ret), KPC(stores)); +// } else if (OB_FAIL(mvcc_engine.check_row_locked(ctx.mvcc_acc_ctx_, key, lock_state))) { +// TRANS_LOG(WARN, "mvcc engine check row lock fail", K(ret), K(lock_state)); +// } + + if (OB_FAIL(mvcc_engine.check_row_locked(ctx.mvcc_acc_ctx_, key, lock_state))) { TRANS_LOG(WARN, "mvcc engine check row lock fail", K(ret), K(lock_state)); } } else if (stores->at(i)->is_sstable()) { @@ -1267,7 +1150,7 @@ int ObMemtable::lock_row_on_frozen_stores_(ObStoreCtx &ctx, ObSSTable *sstable = static_cast(stores->at(i)); if (OB_FAIL(rowkey_converter.convert_datum_rowkey(key->get_rowkey()->get_rowkey(), datum_rowkey))) { STORAGE_LOG(WARN, "Failed to convert datum rowkey", K(ret), KPC(key)); - } else if (OB_FAIL(sstable->check_row_locked(ctx, read_info, datum_rowkey, lock_state))) { + } else if (OB_FAIL(sstable->check_row_locked(param, context, datum_rowkey, lock_state))) { TRANS_LOG(WARN, "sstable check row lock fail", K(ret), K(datum_rowkey), K(*key), K(lock_state)); } TRANS_LOG(DEBUG, "check_row_locked meet sstable", @@ -1344,6 +1227,8 @@ int ObMemtable::lock_row_on_frozen_stores_(ObStoreCtx &ctx, return ret; } + + //////////////////////////////////////////////////////////////////////////////////////////////////// // no allocator here for it, so we desirialize and save the struct info @@ -1843,11 +1728,14 @@ bool ObMemtable::rec_scn_is_stable() STORAGE_LOG(WARN, "memtable rec_scn not stable for long time", K(freezer_->get_ls_id()), K(*this), K(mt_stat_.frozen_time_), K(max_consequent_callbacked_scn)); - ADD_SUSPECT_INFO(MINI_MERGE, + + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(ADD_SUSPECT_INFO(MINI_MERGE, freezer_->get_ls_id(), get_tablet_id(), - "memtable rec_scn not stable", - K(rec_scn_), - K(max_consequent_callbacked_scn)); + ObSuspectInfoType::SUSPECT_REC_SCN_NOT_STABLE, + rec_scn_.get_val_for_tx(), max_consequent_callbacked_scn.get_val_for_tx()))) { + STORAGE_LOG(WARN, "failed to add suspect info", K(tmp_ret)); + } } } return rec_scn_is_stable; @@ -1900,7 +1788,7 @@ bool ObMemtable::ready_for_flush_() if (OB_FAIL(resolve_snapshot_version_())) { TRANS_LOG(WARN, "fail to resolve snapshot version", K(ret), KPC(this), K(ls_id)); } else if (OB_FAIL(resolve_max_end_scn_())) { - TRANS_LOG(WARN, "fail to resolve snapshot version", K(ret), KPC(this), K(ls_id)); + TRANS_LOG(WARN, "fail to resolve max_end_scn", K(ret), KPC(this), K(ls_id)); } else { resolve_right_boundary(); TRANS_LOG(INFO, "[resolve_right_boundary] ready_for_flush_", K(ls_id), KPC(this)); @@ -1945,14 +1833,6 @@ bool ObMemtable::ready_for_flush_() K(current_right_boundary)); mt_stat_.last_print_time_ = ObTimeUtility::current_time(); } - ADD_SUSPECT_INFO(MINI_MERGE, - ls_id, get_tablet_id(), - "memtable not ready for flush", - K(is_frozen_memtable()), - K(get_write_ref()), - K(get_unsynced_cnt()), - K(current_right_boundary), - K(get_end_scn())); freezer_->get_stat().add_memtable_info(get_tablet_id(), get_start_scn(), get_end_scn(), @@ -1960,6 +1840,15 @@ bool ObMemtable::ready_for_flush_() get_unsubmitted_cnt(), get_unsynced_cnt(), current_right_boundary.get_val_for_tx()); + + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(ADD_SUSPECT_INFO(MINI_MERGE, + ls_id, get_tablet_id(), + ObSuspectInfoType::SUSPECT_NOT_READY_FOR_FLUSH, + static_cast(is_frozen_memtable()), get_write_ref(), get_unsynced_cnt(), + current_right_boundary.get_val_for_tx(), get_end_scn().get_val_for_tx()))) { + STORAGE_LOG(WARN, "failed to add suspcet info", K(tmp_ret)); + } } return bool_ret; @@ -2039,6 +1928,29 @@ int ObMemtable::resolve_snapshot_version_() } else if (SCN::invalid_scn() == freeze_snapshot_version) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(ERROR, "fail to get freeze_snapshot_version", K(ret), KPC(this)); + } else if (is_transfer_freeze()) { + // freeze_snapshot_version is used for read tables decision which guarantees + // that all version smaller than the freeze_snapshot_version belongs to + // table before the memtable. While the transfer want the it to be smaller + // than the transfer_scn which require we ignore the input snapshot version. + // + // NOTICE: While the recommend snapshot may be unsafe, so user must ensure + // its correctness. + // + // So use recommend snapshot version if transfer freeze + // recommend snapshot maybe smaller than data commit version when transfer rollback, + // but it will not has any bad effect when major freeze which relay on snapshot version. + if (!recommend_snapshot_version_.is_valid() + || ObScnRange::MAX_SCN == recommend_snapshot_version_ + || ObScnRange::MIN_SCN == recommend_snapshot_version_) { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(ERROR, "recommend_snapshot_version is invalid", K(ret), KPC(this)); + } else if (OB_FAIL(set_snapshot_version(recommend_snapshot_version_))) { + TRANS_LOG(ERROR, "fail to set snapshot_version", K(ret)); + } else { + TRANS_LOG(INFO, "use recommend snapshot version set snapshot_version", K(ret), + K(recommend_snapshot_version_), KPC(this)); + } } else if (OB_FAIL(set_snapshot_version(freeze_snapshot_version))) { TRANS_LOG(ERROR, "fail to set snapshot_version", K(ret)); } @@ -2061,6 +1973,7 @@ int ObMemtable::resolve_max_end_scn_() int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; SCN max_decided_scn; + bool use_max_decided_scn = false; if (OB_ISNULL(freezer_)) { ret = OB_ERR_UNEXPECTED; @@ -2069,8 +1982,18 @@ int ObMemtable::resolve_max_end_scn_() TRANS_LOG(ERROR, "fail to get freeze_snapshot_version", K(ret)); } else if (SCN::invalid_scn() == max_decided_scn) { // Pass if not necessary + } else if (is_transfer_freeze()) { + // max_decided_scn is critial for sstable read performance using larger + // right boundary of memtable(You can learn from the comments that follow + // the class member). While the transfer want the right boundary smaller + // than the transfer_out_scn which require we ignore the max_decided_scn. + // NOTICE: You should notice that we must double check the concurrency issue + // between transfer handler set_transfer_freeze then submit transfer out log + // and freezer get_transfer_freeze and decide its max_decided scn. + // + // So pass if transfer freeze } else if (OB_TMP_FAIL(set_max_end_scn(max_decided_scn))) { - // ignore the error code + TRANS_LOG(WARN, "fail to set max_end_scn", K(ret)); } return ret; @@ -2107,7 +2030,7 @@ int ObMemtable::resolve_right_boundary_for_migration() if (OB_FAIL(resolve_snapshot_version_())) { TRANS_LOG(WARN, "fail to resolve snapshot version", K(ret), KPC(this), K(ls_id)); } else if (OB_FAIL(resolve_max_end_scn_())) { - TRANS_LOG(WARN, "fail to resolve snapshot version", K(ret), KPC(this), K(ls_id)); + TRANS_LOG(WARN, "fail to resolve max_end_scn", K(ret), KPC(this), K(ls_id)); } else { resolve_right_boundary(); TRANS_LOG(INFO, "resolve_right_boundary_for_migration", K(ls_id), KPC(this)); @@ -2142,6 +2065,7 @@ void ObMemtable::set_freeze_state(const int64_t state) int ObMemtable::flush(share::ObLSID ls_id) { int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; int64_t cur_time = ObTimeUtility::current_time(); if (is_flushed_) { @@ -2167,16 +2091,14 @@ int ObMemtable::flush(share::ObLSID ls_id) cur_time - mt_stat_.ready_for_flush_time_ > 30 * 1000 * 1000) { STORAGE_LOG(WARN, "memtable can not create dag successfully for long time", K(ls_id), K(*this), K(mt_stat_.ready_for_flush_time_)); - const char *str_user_error = ob_errpkt_str_user_error(ret, false); - ADD_SUSPECT_INFO(MINI_MERGE, + if (OB_TMP_FAIL(ADD_SUSPECT_INFO(MINI_MERGE, ls_id, get_tablet_id(), - "memtable can not create dag successfully", - "extra info", - str_user_error, - "has been ready for flush time:", + ObSuspectInfoType::SUSPECT_MEMTABLE_CANT_CREATE_DAG, + static_cast(ret), cur_time - mt_stat_.ready_for_flush_time_, - "ready for flush time:", - mt_stat_.ready_for_flush_time_); + mt_stat_.ready_for_flush_time_))) { + STORAGE_LOG(WARN, "failed to add suspect info", K(tmp_ret)); + } } } @@ -2347,6 +2269,49 @@ int64_t ObMemtable::get_max_schema_version() const return ATOMIC_LOAD(&max_schema_version_); } +void ObMemtable::set_max_data_schema_version(const int64_t schema_version) +{ + if (INT64_MAX == schema_version) { + TRANS_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "invalid schema version", K(schema_version), KPC(this)); + } else { + inc_update(&max_data_schema_version_, schema_version); + } +} + +int64_t ObMemtable::get_max_data_schema_version() const +{ + return ATOMIC_LOAD(&max_data_schema_version_); +} + +void ObMemtable::set_max_column_cnt(const int64_t column_cnt) +{ + inc_update(&max_column_cnt_, column_cnt); +} + +int64_t ObMemtable::get_max_column_cnt() const +{ + return ATOMIC_LOAD(&max_column_cnt_); +} + +int ObMemtable::get_schema_info( + int64_t &max_schema_version_on_memtable, + int64_t &max_column_cnt_on_memtable) const +{ + int ret = OB_SUCCESS; + // rows on memtable are not including virtual generated column + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + TRANS_LOG(WARN, "not inited", K(ret)); + } else if (get_max_column_cnt() > max_column_cnt_on_memtable + || get_max_data_schema_version() > max_schema_version_on_memtable) { + TRANS_LOG(INFO, "column cnt or schema version is updated by memtable", KPC(this), + K(max_column_cnt_on_memtable), K(max_schema_version_on_memtable)); + max_column_cnt_on_memtable = MAX(max_column_cnt_on_memtable, get_max_column_cnt()); + max_schema_version_on_memtable = MAX(max_schema_version_on_memtable, get_max_data_schema_version()); + } + return ret; +} + uint32_t ObMemtable::get_freeze_flag() { return freezer_->get_freeze_flag(); @@ -2472,15 +2437,15 @@ int RowHeaderGetter::get() return ret; } -int ObMemtable::set_(ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const ObIArray &columns, - const ObStoreRow &new_row, - // old row can be NULL which means full log is not needed - const ObStoreRow *old_row, - // update idx means the columns we update - const ObIArray *update_idx) + + +int ObMemtable::set_( + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const common::ObIArray &columns, + const storage::ObStoreRow &new_row, + const storage::ObStoreRow *old_row, + const common::ObIArray *update_idx) { int ret = OB_SUCCESS; blocksstable::ObRowWriter row_writer; @@ -2489,19 +2454,20 @@ int ObMemtable::set_(ObStoreCtx &ctx, ObRowData old_row_data; ObStoreRowkey tmp_key; ObMemtableKey mtk; + ObStoreCtx &ctx = *(context.store_ctx_); auto *mem_ctx = ctx.mvcc_acc_ctx_.get_mem_ctx(); //set_begin(ctx.mvcc_acc_ctx_); if (OB_FAIL(tmp_key.assign(new_row.row_val_.cells_, - read_info.get_schema_rowkey_count()))) { + param.get_schema_rowkey_count()))) { TRANS_LOG(WARN, "Failed to assign tmp rowkey", K(ret), K(new_row), - K(read_info.get_schema_rowkey_count())); + K(param.get_schema_rowkey_count())); } else if (OB_FAIL(mtk.encode(columns, &tmp_key))) { TRANS_LOG(WARN, "mtk encode fail", "ret", ret); } else if (nullptr != old_row) { char *new_buf = nullptr; - if(OB_FAIL(row_writer.write(read_info.get_schema_rowkey_count(), *old_row, nullptr, buf, len))) { + if(OB_FAIL(row_writer.write(param.get_schema_rowkey_count(), *old_row, nullptr, buf, len))) { TRANS_LOG(WARN, "Failed to write old row", K(ret), KPC(old_row)); } else if (OB_ISNULL(new_buf = (char *)mem_ctx->old_row_alloc(len))) { ret = OB_ALLOCATE_MEMORY_FAILED; @@ -2518,7 +2484,7 @@ int ObMemtable::set_(ObStoreCtx &ctx, row_writer.reset(); if (OB_FAIL(ret)) { //do nothing - } else if (OB_FAIL(row_writer.write(read_info.get_schema_rowkey_count(), new_row, update_idx, buf, len))) { + } else if (OB_FAIL(row_writer.write(param.get_schema_rowkey_count(), new_row, update_idx, buf, len))) { TRANS_LOG(WARN, "Failed to write new row", K(ret), K(new_row)); } else if (OB_UNLIKELY(new_row.flag_.is_not_exist())) { ret = OB_ERR_UNEXPECTED; @@ -2526,14 +2492,11 @@ int ObMemtable::set_(ObStoreCtx &ctx, } else { ObMemtableData mtd(new_row.flag_.get_dml_flag(), len, buf); ObTxNodeArg arg(&mtd, /*memtable_data*/ - NULL == old_row ? NULL : &old_row_data, - timestamp_, /*memstore_version*/ - ctx.mvcc_acc_ctx_.tx_scn_ /*seq_no*/); - if (OB_FAIL(mvcc_write_(ctx, - &mtk, - read_info, - arg, - is_new_locked))) { + NULL == old_row ? NULL : &old_row_data, + timestamp_, /*memstore_version*/ + ctx.mvcc_acc_ctx_.tx_scn_, /*seq_no*/ + new_row.row_val_.count_ /*column_cnt*/); + if (OB_FAIL(mvcc_write_(param, context, &mtk, arg, is_new_locked))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret && OB_TRANSACTION_SET_VIOLATION != ret) { TRANS_LOG(WARN, "mvcc write fail", K(mtk), K(ret)); @@ -2543,13 +2506,11 @@ int ObMemtable::set_(ObStoreCtx &ctx, "ret", ret, "tablet_id_", key_.tablet_id_, "dml_flag", new_row.flag_.get_dml_flag(), - "read_info", read_info, "columns", strarray(columns), "old_row", to_cstring(old_row), "new_row", to_cstring(new_row), "update_idx", (update_idx == NULL ? "" : to_cstring(update_idx)), "mtd", to_cstring(mtd), - "store_ctx", ctx, K(arg)); } } @@ -2570,8 +2531,6 @@ int ObMemtable::set_(ObStoreCtx &ctx, TRANS_LOG(WARN, "set end, fail", "ret", ret, "tablet_id_", key_.tablet_id_, - "table_id", to_cstring(table_id), - "read_info", read_info, "columns", strarray(columns), "new_row", to_cstring(new_row), "mem_ctx", STR_PTR(mem_ctx), @@ -2580,12 +2539,50 @@ int ObMemtable::set_(ObStoreCtx &ctx, //set_end(ctx.mvcc_acc_ctx_, ret); if (OB_SUCC(ret)) { - set_max_schema_version(ctx.table_version_); + set_max_data_schema_version(ctx.table_version_); + set_max_column_cnt(new_row.row_val_.count_); } return ret; } + +int ObMemtable::lock_( + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const common::ObStoreRowkey &rowkey) +{ + int ret = OB_SUCCESS; + bool is_new_locked = false; + blocksstable::ObRowWriter row_writer; + ObMemtableKey mtk; + char *buf = NULL; + int64_t len = 0; + + if (OB_FAIL(mtk.encode(param.get_read_info()->get_columns_desc(), &rowkey))) { + TRANS_LOG(WARN, "mtk encode fail", "ret", ret); + } else if (OB_FAIL(row_writer.write_rowkey(rowkey, buf, len))) { + TRANS_LOG(WARN, "Failed to writer rowkey", K(ret), K(rowkey)); + } else { + ObMemtableData mtd(blocksstable::ObDmlFlag::DF_LOCK, len, buf); + ObTxNodeArg arg(&mtd, /*memtable_data*/ + NULL, /*old_data*/ + timestamp_, /*memstore_version*/ + context.store_ctx_->mvcc_acc_ctx_.tx_scn_, /*seq_no*/ + rowkey.get_obj_cnt() /*column_cnt*/); + if (OB_FAIL(mvcc_write_(param, context, &mtk, arg, is_new_locked))) { + } else if (OB_UNLIKELY(!is_new_locked)) { + TRANS_LOG(DEBUG, "lock twice, no need to store lock trans node", K(table_id)); + } + } + + return ret; +} + + + + + int ObMemtable::mvcc_replay_(storage::ObStoreCtx &ctx, const ObMemtableKey *key, const ObTxNodeArg &arg) @@ -2622,7 +2619,8 @@ int ObMemtable::mvcc_replay_(storage::ObStoreCtx &ctx, arg.data_->dup_size(), this, arg.seq_no_, - arg.scn_))) { + arg.scn_, + arg.column_cnt_))) { TRANS_LOG(WARN, "register_row_replay_cb fail", K(ret)); } else if (FALSE_IT(timeguard.click("register_row_replay_cb"))) { } @@ -2630,11 +2628,13 @@ int ObMemtable::mvcc_replay_(storage::ObStoreCtx &ctx, return ret; } -int ObMemtable::mvcc_write_(storage::ObStoreCtx &ctx, - const ObMemtableKey *key, - const storage::ObTableReadInfo &read_info, - const ObTxNodeArg &arg, - bool &is_new_locked) + +int ObMemtable::mvcc_write_( + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const ObMemtableKey *key, + const ObTxNodeArg &arg, + bool &is_new_locked) { int ret = OB_SUCCESS; bool is_new_add = false; @@ -2642,6 +2642,7 @@ int ObMemtable::mvcc_write_(storage::ObStoreCtx &ctx, RowHeaderGetter getter; ObMvccRow *value = NULL; ObMvccWriteResult res; + ObStoreCtx &ctx = *(context.store_ctx_); ObIMemtableCtx *mem_ctx = ctx.mvcc_acc_ctx_.get_mem_ctx(); SCN snapshot_version = ctx.mvcc_acc_ctx_.get_snapshot_version(); transaction::ObTxSnapshot &snapshot = ctx.mvcc_acc_ctx_.snapshot_; @@ -2651,7 +2652,7 @@ int ObMemtable::mvcc_write_(storage::ObStoreCtx &ctx, value, getter, is_new_add))) { - TRANS_LOG(WARN, "create kv failed", K(ret), K(arg), K(*key), K(ctx)); + TRANS_LOG(WARN, "create kv failed", K(ret), K(arg), K(*key)); } else if (OB_FAIL(mvcc_engine_.mvcc_write(*mem_ctx, ctx.mvcc_acc_ctx_.write_flag_, snapshot, @@ -2672,11 +2673,11 @@ int ObMemtable::mvcc_write_(storage::ObStoreCtx &ctx, } else { TRANS_LOG(WARN, "mvcc write fail", K(ret)); } - } else if (OB_FAIL(lock_row_on_frozen_stores_(ctx, + } else if (OB_FAIL(lock_row_on_frozen_stores_(param, arg, + context, key, value, - read_info, res))) { // Double lock detection is used to prevent that the row who has been // operated by the same txn before will be unexpectedly conflicted with @@ -2735,7 +2736,8 @@ int ObMemtable::mvcc_write_(storage::ObStoreCtx &ctx, arg.data_->dup_size(), arg.old_row_, this, - arg.seq_no_))) { + arg.seq_no_, + arg.column_cnt_))) { (void)mvcc_engine_.mvcc_undo(value); TRANS_LOG(WARN, "register row commit failed", K(ret)); } else { @@ -2764,6 +2766,8 @@ int ObMemtable::mvcc_write_(storage::ObStoreCtx &ctx, return ret; } + + int ObMemtable::post_row_write_conflict_(ObMvccAccessCtx &acc_ctx, const ObMemtableKey &row_key, ObStoreRowLockState &lock_state, @@ -2798,9 +2802,9 @@ int ObMemtable::post_row_write_conflict_(ObMvccAccessCtx &acc_ctx, lock_state.is_locked_ = false; if (lock_state.is_delayed_cleanout_) { auto lock_data_sequence = lock_state.lock_data_sequence_; - auto &tx_table_guard = acc_ctx.get_tx_table_guard(); - if (OB_FAIL(tx_table_guard.check_row_locked( - tx_id, conflict_tx_id, lock_data_sequence, lock_state))) { + auto &tx_table_guards = acc_ctx.get_tx_table_guards(); + if (OB_FAIL(tx_table_guards.check_row_locked( + tx_id, conflict_tx_id, lock_data_sequence, lock_state.trans_scn_, lock_state))) { TRANS_LOG(WARN, "re-check row locked via tx_table fail", K(ret), K(tx_id), K(lock_state)); } } else { diff --git a/src/storage/memtable/ob_memtable.h b/src/storage/memtable/ob_memtable.h index 5863e3f22..0ab7490aa 100644 --- a/src/storage/memtable/ob_memtable.h +++ b/src/storage/memtable/ob_memtable.h @@ -189,16 +189,14 @@ public: // old_row is the old version of the row for set action, it contains all columns(NB: it works for liboblog only currently) // new_row is the new version of the row for set action, it only contains the necessary columns for update and entire columns for insert virtual int set( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, const common::ObIArray &columns, // TODO: remove columns const storage::ObStoreRow &row, const share::ObEncryptMeta *encrypt_meta); virtual int set( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, const common::ObIArray &columns, // TODO: remove columns const ObIArray &update_idx, const storage::ObStoreRow &old_row, @@ -210,20 +208,14 @@ public: // tablet_id is necessary for the query_engine's key engine(NB: do we need it now?) // columns is the schema of the new_row, it contains the row key // row/rowkey/row_iter is the row key or row key iterator for lock + virtual int lock( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - common::ObNewRowIterator &row_iter); - virtual int lock( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, const common::ObNewRow &row); virtual int lock( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, const blocksstable::ObDatumRowkey &rowkey); // exist/prefix_exist is used to ensure the (prefix) existance of the row @@ -237,12 +229,11 @@ public: // all_rows_found returns the existance of all of the rowkey(may be deleted) or existance of one of the rowkey(must not be deleted) // may_exist returns the possible existance of the rowkey(may be deleted) virtual int exist( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const blocksstable::ObDatumRowkey &rowkey, - bool &is_exist, - bool &has_found); + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const blocksstable::ObDatumRowkey &rowkey, + bool &is_exist, + bool &has_found); virtual int exist( storage::ObRowsInfo &rows_info, bool &is_exist, @@ -304,11 +295,10 @@ public: // rowkey is the row key used for lock // locked returns whether lock is locked by myself int check_row_locked_by_myself( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, const blocksstable::ObDatumRowkey &rowkey, - bool &locked); + bool &locked); // // TODO: ==================== Memtable Other Interface ================== int set_freezer(storage::ObFreezer *handler); @@ -326,6 +316,13 @@ public: inline bool not_empty() const { return INT64_MAX != get_protection_clock(); }; void set_max_schema_version(const int64_t schema_version); virtual int64_t get_max_schema_version() const override; + void set_max_data_schema_version(const int64_t schema_version); + int64_t get_max_data_schema_version() const; + void set_max_column_cnt(const int64_t column_cnt); + int64_t get_max_column_cnt() const; + int get_schema_info( + int64_t &max_schema_version_on_memtable, + int64_t &max_column_cnt_on_memtable) const; int row_compact(ObMvccRow *value, const share::SCN snapshot_version, const int64_t flag); @@ -431,6 +428,16 @@ public: } } inline bool get_logging_blocked() { return ATOMIC_LOAD(&logging_blocked_); } + // User should take response of the recommend scn. All version smaller than + // recommend scn should belong to the tables before the memtable and the + // memtable. And under exception case, user need guarantee all new data is + // bigger than the recommend_scn. + inline void set_transfer_freeze(const share::SCN recommend_scn) + { + recommend_snapshot_version_.atomic_set(recommend_scn); + ATOMIC_STORE(&transfer_freeze_flag_, true); + } + inline bool is_transfer_freeze() const { return ATOMIC_LOAD(&transfer_freeze_flag_); } int64_t get_unsubmitted_cnt() const { return ATOMIC_LOAD(&unsubmitted_cnt_); } int inc_unsubmitted_cnt(); int dec_unsubmitted_cnt(); @@ -482,8 +489,10 @@ public: bool &is_all_delay_cleanout, int64_t &count); int dump2text(const char *fname); + // TODO(handora.qc) ready_for_flush interface adjustment + bool is_can_flush() { return ObMemtableFreezeState::READY_FOR_FLUSH == freeze_state_ && share::SCN::max_scn() != get_end_scn(); } INHERIT_TO_STRING_KV("ObITable", ObITable, KP(this), KP_(memtable_mgr), K_(timestamp), K_(state), - K_(freeze_clock), K_(max_schema_version), K_(write_ref_cnt), K_(local_allocator), + K_(freeze_clock), K_(max_schema_version), K_(max_data_schema_version), K_(write_ref_cnt), K_(local_allocator), K_(unsubmitted_cnt), K_(unsynced_cnt), K_(logging_blocked), K_(unset_active_memtable_logging_blocked), K_(resolve_active_memtable_left_boundary), K_(contain_hotspot_row), K_(max_end_scn), K_(rec_scn), K_(snapshot_version), K_(migration_clog_checkpoint_scn), @@ -491,24 +500,26 @@ public: K_(read_barrier), K_(is_flushed), K_(freeze_state), K_(allow_freeze), K_(mt_stat_.frozen_time), K_(mt_stat_.ready_for_flush_time), K_(mt_stat_.create_flush_dag_time), K_(mt_stat_.release_time), - K_(mt_stat_.last_print_time)); + K_(mt_stat_.last_print_time), K_(ls_id), K_(transfer_freeze_flag), K_(recommend_snapshot_version)); private: static const int64_t OB_EMPTY_MEMSTORE_MAX_SIZE = 10L << 20; // 10MB - int mvcc_write_(storage::ObStoreCtx &ctx, - const ObMemtableKey *key, - const storage::ObTableReadInfo &read_info, - const ObTxNodeArg &arg, - bool &is_new_locked); + int mvcc_write_( + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const ObMemtableKey *key, + const ObTxNodeArg &arg, + bool &is_new_locked); + int mvcc_replay_(storage::ObStoreCtx &ctx, const ObMemtableKey *key, const ObTxNodeArg &arg); int lock_row_on_frozen_stores_( - storage::ObStoreCtx &ctx, + const storage::ObTableIterParam ¶m, const ObTxNodeArg &arg, + storage::ObTableAccessContext &context, const ObMemtableKey *key, ObMvccRow *value, - const storage::ObTableReadInfo &read_info, ObMvccWriteResult &res); void get_begin(ObMvccAccessCtx &ctx); @@ -521,22 +532,22 @@ private: int check_standby_cluster_schema_condition_(storage::ObStoreCtx &ctx, const int64_t table_id, const int64_t table_version); - int set_(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObIArray &columns, - const storage::ObStoreRow &new_row, - const storage::ObStoreRow *old_row, - const common::ObIArray *update_idx); - int lock_(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObStoreRowkey &rowkey); - int lock_(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObStoreRowkey &rowkey, - ObMemtableKey &mtk); + + + int set_( + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const common::ObIArray &columns, + const storage::ObStoreRow &new_row, + const storage::ObStoreRow *old_row, + const common::ObIArray *update_idx); + int lock_( + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const common::ObStoreRowkey &rowkey); + + + int post_row_write_conflict_(ObMvccAccessCtx &acc_ctx, const ObMemtableKey &row_key, storage::ObStoreRowLockState &lock_state, @@ -561,7 +572,8 @@ private: ObQueryEngine query_engine_; ObMvccEngine mvcc_engine_; mutable ObMtStat mt_stat_; - int64_t max_schema_version_; // to record the max schema version of all data + int64_t max_schema_version_; // to record the max schema version of memtable & schema_change_clog + int64_t max_data_schema_version_; // to record the max schema version of write data int64_t pending_cb_cnt_; // number of transactions have to sync log int64_t unsubmitted_cnt_; // number of trans node to be submitted logs int64_t unsynced_cnt_; // number of trans node to be synced logs @@ -570,6 +582,12 @@ private: int64_t logging_blocked_start_time; // record the start time of logging blocked bool unset_active_memtable_logging_blocked_; bool resolve_active_memtable_left_boundary_; + // TODO(handora.qc): remove it as soon as possible + // only used for decide special right boundary of memtable + bool transfer_freeze_flag_; + // only used for decide special snapshot version of memtable + share::SCN recommend_snapshot_version_; + share::SCN freeze_scn_; share::SCN max_end_scn_; share::SCN rec_scn_; @@ -591,6 +609,7 @@ private: mutable common::TCRWLock multi_source_data_lock_; transaction::ObTxEncryptMeta *encrypt_meta_; common::SpinRWLock encrypt_meta_lock_; + int64_t max_column_cnt_; // record max column count of row }; template diff --git a/src/storage/memtable/ob_memtable_context.cpp b/src/storage/memtable/ob_memtable_context.cpp index f280033cc..f8d8f384c 100644 --- a/src/storage/memtable/ob_memtable_context.cpp +++ b/src/storage/memtable/ob_memtable_context.cpp @@ -18,6 +18,7 @@ #include "ob_memtable.h" #include "storage/tx/ob_trans_part_ctx.h" #include "storage/tx/ob_trans_define.h" +#include "storage/tx/ob_multi_data_source.h" #include "share/ob_tenant_mgr.h" #include "storage/tx/ob_trans_ctx_mgr.h" #include "share/ob_force_print_log.h" @@ -1205,6 +1206,8 @@ int ObMemtableCtx::register_multi_source_data_if_need_( const bool is_replay) { int ret = OB_SUCCESS; + ObRegisterMdsFlag mds_flag; + mds_flag.reset(); if (is_replay) { // replay does not need register multi source data, it is dealt // by multi source data itself. @@ -1226,10 +1229,12 @@ int ObMemtableCtx::register_multi_source_data_if_need_( } else if (OB_FAIL(lock_op.serialize(buf, serialize_size, pos))) { TRANS_LOG(WARN, "serialize lock op failed", K(ret), K(serialize_size), K(pos)); // TODO: yanyuan.cxf need seqno to do rollback. + // THE MULTI SOURCE BUFFER CAN REGISTER AGAIN IF THE RET CODE IS NOT OB_SUCCESS } else if (OB_FAIL(part_ctx->register_multi_data_source(type, buf, serialize_size, - true /* try lock */))) { + true /* try lock */, + mds_flag))) { TRANS_LOG(WARN, "register to multi source data failed", K(ret)); } else { // do nothing diff --git a/src/storage/memtable/ob_memtable_interface.h b/src/storage/memtable/ob_memtable_interface.h index 2d52e7146..74e5305c9 100644 --- a/src/storage/memtable/ob_memtable_interface.h +++ b/src/storage/memtable/ob_memtable_interface.h @@ -143,64 +143,22 @@ struct ObMergePriorityInfo class ObIMemtable: public storage::ObITable { public: - ObIMemtable() : snapshot_version_(share::SCN::max_scn()) + ObIMemtable() : ls_id_(), snapshot_version_(share::SCN::max_scn()) {} virtual ~ObIMemtable() {} - + virtual share::ObLSID &get_ls_id() { return ls_id_;} virtual int get( const storage::ObTableIterParam ¶m, storage::ObTableAccessContext &context, const blocksstable::ObDatumRowkey &rowkey, blocksstable::ObDatumRow &row) = 0; - // Insert/Delete/Update row - // - // @param [in] ctx, transaction - // @param [in] table_id - // @param [in] column_ids, input columns - // @param [in] row, row to be set - // - virtual int set(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObIArray &columns, // TODO: remove columns - const storage::ObStoreRow &row, - const share::ObEncryptMeta *encrypt_meta) = 0; - // - // Lock rows - // - // @param [in] ctx, transaction - // @param [in] table_id - // @param [in] row_iter, input iterator - // @param [in] lock_flag, operation flag - // - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - common::ObNewRowIterator &row_iter) = 0; - // - // Lock single row - // - // @param [in] ctx, transaction - // @param [in] table_id - // @param [in] row, row to be locked - // @param [in] lock_flag, operation flag - // - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObNewRow &row) = 0; - // - // Lock single row - // - // @param [in] ctx, transaction - // @param [in] table_id - // @param [in] rowkey, row to be locked - // - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const blocksstable::ObDatumRowkey &rowkey) = 0; + virtual int64_t get_frozen_trans_version() { return 0; } + virtual int major_freeze(const common::ObVersion &version) + { UNUSED(version); return common::OB_SUCCESS; } + virtual int minor_freeze(const common::ObVersion &version) + { UNUSED(version); return common::OB_SUCCESS; } + virtual void inc_pending_lob_count() {} virtual void dec_pending_lob_count() {} virtual int on_memtable_flushed() { return common::OB_SUCCESS; } @@ -268,6 +226,7 @@ public: return false; } protected: + share::ObLSID ls_id_; share::SCN snapshot_version_; }; diff --git a/src/storage/memtable/ob_memtable_iterator.cpp b/src/storage/memtable/ob_memtable_iterator.cpp old mode 100644 new mode 100755 index 059f3ea57..071eb58f7 --- a/src/storage/memtable/ob_memtable_iterator.cpp +++ b/src/storage/memtable/ob_memtable_iterator.cpp @@ -77,7 +77,7 @@ int ObMemtableGetIterator::init( if (is_inited_) { reset(); } - const ObTableReadInfo *read_info = param.get_read_info(context.use_fuse_row_cache_); + const ObITableReadInfo *read_info = param.get_read_info(context.use_fuse_row_cache_); if (param.need_trans_info()) { int64_t length = concurrency_control::ObTransStatRow::MAX_TRANS_STRING_SIZE; if (OB_ISNULL(trans_info_ptr = static_cast(context.stmt_allocator_->alloc(length)))) { @@ -384,7 +384,8 @@ int ObMemtableScanIterator::inner_get_next_row(const ObDatumRow *&row) context_->tablet_id_, context_->ls_id_, value_iter->get_mvcc_row()->get_last_compact_cnt(), - value_iter->get_mvcc_row()->get_total_trans_node_cnt()); + value_iter->get_mvcc_row()->get_total_trans_node_cnt(), + lock_state.trans_scn_); } } else if (OB_FAIL(ObReadRow::iterate_row(*read_info_, *rowkey, *(context_->allocator_), *value_iter, row_, bitmap_, row_scn))) { TRANS_LOG(WARN, "iterate_row fail", K(ret), K(*rowkey), KP(value_iter)); @@ -470,7 +471,7 @@ int ObMemtableMGetIterator::init( } char *trans_info_ptr = nullptr; - const ObTableReadInfo *read_info = param.get_read_info(context.use_fuse_row_cache_); + const ObITableReadInfo *read_info = param.get_read_info(); if (param.need_trans_info()) { int64_t length = concurrency_control::ObTransStatRow::MAX_TRANS_STRING_SIZE; if (OB_ISNULL(trans_info_ptr = static_cast(context.stmt_allocator_->alloc(length)))) { @@ -775,13 +776,13 @@ int ObMemtableMultiVersionScanIterator::init( reset(); } - const ObColDescIArray *columns; + const ObColDescIArray *rowkey_columns; const ObDatumRange *range = static_cast(query_range); ObMemtable *memtable = static_cast(table); if (OB_ISNULL(table) || OB_ISNULL(query_range) || !context.is_valid()) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "table and query range can not be null", KP(table), KP(query_range), K(ret)); - } else if (OB_ISNULL(columns = param.get_out_col_descs())) { + } else if (OB_ISNULL(rowkey_columns = param.get_out_col_descs())) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(WARN, "Unexpected null col descs", K(ret), K(param)); } else if (OB_ISNULL(read_info_ = param.get_read_info(true))) { @@ -791,10 +792,10 @@ int ObMemtableMultiVersionScanIterator::init( ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Unexpected invalid datum range", K(ret), K(range)); } else if (OB_FAIL(ObMemtableKey::build_without_hash( - start_key_, *columns, &range->get_start_key().get_store_rowkey(), *context.get_range_allocator()))) { + start_key_, *rowkey_columns, &range->get_start_key().get_store_rowkey(), *context.get_range_allocator()))) { TRANS_LOG(WARN, "start key build fail", K(param.table_id_), K(range->get_start_key())); } else if (OB_FAIL(ObMemtableKey::build_without_hash( - end_key_, *columns, &range->get_end_key().get_store_rowkey(), *context.get_range_allocator()))) { + end_key_, *rowkey_columns, &range->get_end_key().get_store_rowkey(), *context.get_range_allocator()))) { TRANS_LOG(WARN, "end key build fail", K(param.table_id_), K(range->get_end_key())); } else { TRANS_LOG(DEBUG, "init multi version scan iterator", K(param), K(*range)); @@ -812,7 +813,7 @@ int ObMemtableMultiVersionScanIterator::init( } else if (OB_FAIL(row_.init(*context.stmt_allocator_, read_info_->get_request_count()))) { TRANS_LOG(WARN, "Failed to init datum row", K(ret)); } else { - TRANS_LOG(DEBUG, "multi version scan iterator init succ", K(param.table_id_), K(range)); + TRANS_LOG(INFO, "multi version scan iterator init succ", K(param.table_id_), K(range), KPC(read_info_), K(row_)); trans_version_col_idx_ = param.get_schema_rowkey_count(); sql_sequence_col_idx_ = param.get_schema_rowkey_count() + 1; context_ = &context; @@ -1390,7 +1391,7 @@ OB_INLINE int ObReadRow::iterate_row_key(const ObStoreRowkey &rowkey, ObDatumRow } OB_INLINE int ObReadRow::iterate_row_value_( - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, common::ObIAllocator &allocator, ObMvccValueIterator &value_iter, ObDatumRow &row, @@ -1455,7 +1456,7 @@ OB_INLINE int ObReadRow::iterate_row_value_( } int ObReadRow::iterate_row( - const ObTableReadInfo &read_info, + const ObITableReadInfo &read_info, const ObStoreRowkey &key, common::ObIAllocator &allocator, ObMvccValueIterator &value_iter, diff --git a/src/storage/memtable/ob_memtable_iterator.h b/src/storage/memtable/ob_memtable_iterator.h index 8a6c7c28f..64d5a89f7 100644 --- a/src/storage/memtable/ob_memtable_iterator.h +++ b/src/storage/memtable/ob_memtable_iterator.h @@ -161,7 +161,7 @@ protected: bool is_scan_start_; const storage::ObTableIterParam *param_; storage::ObTableAccessContext *context_; - const storage::ObTableReadInfo *read_info_; + const storage::ObITableReadInfo *read_info_; ObIMemtable *memtable_; blocksstable::ObDatumRange cur_range_; ObMvccRowIterator row_iter_; @@ -304,7 +304,7 @@ protected: protected: const uint64_t MAGIC_; bool is_inited_; - const storage::ObTableReadInfo *read_info_; + const storage::ObITableReadInfo *read_info_; ObMemtableKey *start_key_; ObMemtableKey *end_key_; storage::ObTableAccessContext *context_; @@ -327,7 +327,7 @@ class ObReadRow DEFINE_ALLOCATOR_WRAPPER public: static int iterate_row( - const storage::ObTableReadInfo &read_info, + const storage::ObITableReadInfo &read_info, const common::ObStoreRowkey &key, common::ObIAllocator &allocator, ObMvccValueIterator &value_iter, @@ -341,7 +341,7 @@ private: DISALLOW_COPY_AND_ASSIGN(ObReadRow); private: static int iterate_row_value_( - const storage::ObTableReadInfo &read_info, + const storage::ObITableReadInfo &read_info, common::ObIAllocator &allocator, ObMvccValueIterator &value_iter, blocksstable::ObDatumRow &row, diff --git a/src/storage/memtable/ob_memtable_mutator.cpp b/src/storage/memtable/ob_memtable_mutator.cpp index 26b107f0e..016cdf908 100644 --- a/src/storage/memtable/ob_memtable_mutator.cpp +++ b/src/storage/memtable/ob_memtable_mutator.cpp @@ -326,7 +326,8 @@ ObMemtableMutatorRow::ObMemtableMutatorRow(): update_seq_(0), acc_checksum_(0), version_(0), - flag_(0) + flag_(0), + column_cnt_(0) { } @@ -340,7 +341,8 @@ ObMemtableMutatorRow::ObMemtableMutatorRow(const uint64_t table_id, const uint32_t acc_checksum, const int64_t version, const int32_t flag, - const int64_t seq_no): + const int64_t seq_no, + const int64_t column_cnt): ObMutator(table_id, rowkey, table_version, seq_no), dml_flag_(dml_flag), update_seq_((uint32_t)modify_count), @@ -348,7 +350,8 @@ ObMemtableMutatorRow::ObMemtableMutatorRow(const uint64_t table_id, old_row_(old_row), acc_checksum_(acc_checksum), version_(version), - flag_(flag) + flag_(flag), + column_cnt_(column_cnt) {} ObMemtableMutatorRow::~ObMemtableMutatorRow() @@ -376,7 +379,8 @@ int ObMemtableMutatorRow::copy(uint64_t &table_id, uint32_t &acc_checksum, int64_t &version, int32_t &flag, - int64_t &seq_no) const + int64_t &seq_no, + int64_t &column_cnt) const { int ret = OB_SUCCESS; table_id = table_id_; @@ -390,6 +394,7 @@ int ObMemtableMutatorRow::copy(uint64_t &table_id, version = version_; flag = flag_; seq_no = seq_no_; + column_cnt = column_cnt_; return ret; } @@ -429,13 +434,13 @@ int ObMemtableMutatorRow::serialize(char *buf, int64_t &buf_len, int64_t &pos, TRANS_LOG(INFO, "serialize row fail", K(ret), KP(buf), K(buf_len), K(pos)); } } - if (OB_SUCC(ret)) { - row_size_ = (uint32_t)(new_pos - pos); - if (OB_FAIL(encode_i32(buf, buf_len, pos, row_size_))) { - TRANS_LOG(WARN, "serialize row size fail", K(ret), K(buf_len), K(pos), K(table_id_)); - } else { - pos = new_pos; - } + if (FAILEDx(encode_vi64(buf, buf_len, new_pos, column_cnt_))) { + TRANS_LOG(WARN, "failed to serialize column cnt", K(column_cnt_)); + } else if (FALSE_IT(row_size_ = (uint32_t )(new_pos - pos))) { + } else if (OB_FAIL(encode_i32(buf, buf_len, pos, row_size_))) { + TRANS_LOG(WARN, "serialize row fail", K(ret), K(buf_len), K(pos), K(table_id_)); + } else { + pos = new_pos; } } return ret; @@ -504,6 +509,11 @@ int ObMemtableMutatorRow::deserialize(const char *buf, const int64_t buf_len, in TRANS_LOG(WARN, "deserialize seq no fail", K(ret), K(table_id_), K(decrypted_len), K(new_pos)); } } + if (OB_SUCC(ret) && (new_pos < decrypted_len)) { + if (OB_FAIL(decode_vi64(decrypted_buf, decrypted_len, new_pos, (int64_t *)&column_cnt_))) { + TRANS_LOG(WARN, "deserialize column cnt fail", K(ret), K(table_id_), K(decrypted_len), K(new_pos)); + } + } if (OB_SUCC(ret)) { pos += encrypted_len; } @@ -587,7 +597,7 @@ int ObMutatorTableLock::serialize( if (OB_ISNULL(buf) || pos < 0 || pos > buf_len) { ret = OB_INVALID_ARGUMENT; } else if (OB_FAIL(lock_id_.serialize(buf, buf_len, new_pos)) || - OB_FAIL(encode_vi64(buf, buf_len, new_pos, owner_id_)) || + OB_FAIL(owner_id_.serialize(buf, buf_len, new_pos)) || OB_FAIL(encode_i8(buf, buf_len, new_pos, mode_)) || OB_FAIL(encode_i8(buf, buf_len, new_pos, lock_type_)) || OB_FAIL(encode_vi64(buf, buf_len, new_pos, seq_no_)) || @@ -628,7 +638,7 @@ int ObMutatorTableLock::deserialize( K(pos), K_(row_size)); } else if (OB_FAIL(lock_id_.deserialize(buf, buf_len, new_pos))) { TRANS_LOG(WARN, "deserialize lock_id fail", K(ret), K(pos), K(new_pos), K(row_size_), K(buf_len)); - } else if (OB_FAIL(decode_vi64(buf, buf_len, new_pos, &owner_id_))) { + } else if (OB_FAIL(owner_id_.deserialize(buf, buf_len, new_pos))) { TRANS_LOG(WARN, "deserialize owner_id fail", K(ret), K(pos), K(new_pos), K(row_size_), K(buf_len)); } else if (OB_FAIL(decode_i8(buf, buf_len, new_pos, reinterpret_cast(&mode_)))) { TRANS_LOG(WARN, "deserialize lock mode fail", K(ret), K(pos), K(new_pos), K(row_size_), K(buf_len)); @@ -875,7 +885,8 @@ int ObMutatorWriter::append_row_kv( redo.acc_checksum_, redo.version_, redo.flag_, - redo.seq_no_); + redo.seq_no_, + redo.column_cnt_); int64_t tmp_pos = buf_.get_position(); int64_t row_capacity = row_capacity_; diff --git a/src/storage/memtable/ob_memtable_mutator.h b/src/storage/memtable/ob_memtable_mutator.h index eca2f48b4..569db41d9 100644 --- a/src/storage/memtable/ob_memtable_mutator.h +++ b/src/storage/memtable/ob_memtable_mutator.h @@ -161,7 +161,8 @@ public: const uint32_t acc_checksum, const int64_t version, const int32_t flag, - const int64_t seq_no); + const int64_t seq_no, + const int64_t column_cnt); virtual ~ObMemtableMutatorRow(); void reset(); int copy(uint64_t &table_id, @@ -174,7 +175,8 @@ public: uint32_t &acc_checksum, int64_t &version, int32_t &flag, - int64_t &seq_no) const; + int64_t &seq_no, + int64_t &column_cnt) const; int serialize(char *buf, int64_t &buf_len, int64_t &pos, const transaction::ObTxEncryptMeta *encrypt_meta, @@ -190,6 +192,7 @@ public: share::ObCLogEncryptStatMap &encrypt_stat_map, const bool is_big_row = false); uint32_t get_flag() const { return flag_; }; + int64_t get_column_cnt() const { return column_cnt_; } TO_STRING_KV(K_(row_size), K_(table_id), @@ -202,7 +205,8 @@ public: K_(acc_checksum), K_(version), K_(flag), - K_(seq_no)); + K_(seq_no), + K_(column_cnt)); public: blocksstable::ObDmlFlag dml_flag_; @@ -213,6 +217,7 @@ public: int64_t version_; int32_t flag_; // currently, unused uint8_t rowid_version_; + int64_t column_cnt_; }; class ObMutatorTableLock : public ObMutator diff --git a/src/storage/memtable/ob_multi_source_data.h b/src/storage/memtable/ob_multi_source_data.h index 9306492d4..0f29a7a17 100644 --- a/src/storage/memtable/ob_multi_source_data.h +++ b/src/storage/memtable/ob_multi_source_data.h @@ -258,7 +258,7 @@ int ObMultiSourceData::save_multi_source_data_unit(const T *const src, bool is_c if (units_[pos]->get_data_size() < data_size) { ret = common::OB_SIZE_OVERFLOW; TRANS_LOG(WARN, "no enough space to update multi_data_source_unit", K(ret), KP(src), K(pos)); - } else if (OB_FAIL(units_[pos]->deep_copy_unit(src))) { + } else if (OB_FAIL(units_[pos]->deep_copy_unit(src, &allocator_))) { TRANS_LOG(WARN, "fail to deep copy to update data", K(ret), KP(src), KP(units_[pos]), K(pos)); } } diff --git a/src/storage/memtable/ob_row_conflict_handler.cpp b/src/storage/memtable/ob_row_conflict_handler.cpp index 1090ed43d..b36c9aff1 100644 --- a/src/storage/memtable/ob_row_conflict_handler.cpp +++ b/src/storage/memtable/ob_row_conflict_handler.cpp @@ -13,6 +13,7 @@ #include "ob_row_conflict_handler.h" #include "storage/memtable/mvcc/ob_mvcc_iterator.h" #include "storage/memtable/ob_lock_wait_mgr.h" +#include "storage/tx_table/ob_tx_table_guards.h" namespace oceanbase { using namespace common; @@ -47,12 +48,13 @@ int ObRowConflictHandler::check_foreign_key_constraint_for_memtable(ObMvccValueI return ret; } -int ObRowConflictHandler::check_foreign_key_constraint_for_sstable(ObTxTableGuard &tx_table_guard, +int ObRowConflictHandler::check_foreign_key_constraint_for_sstable(ObTxTableGuards &tx_table_guards, const ObTransID &read_trans_id, const ObTransID &data_trans_id, const int64_t sql_sequence, const int64_t trans_version, const int64_t snapshot_version, + const share::SCN &end_scn, ObStoreRowLockState &lock_state) { int ret = OB_SUCCESS; // If a transaction is committed, the trans_id of it is 0, which is invalid. @@ -64,13 +66,12 @@ int ObRowConflictHandler::check_foreign_key_constraint_for_sstable(ObTxTableGuar } } else { ObTxTable *tx_table = nullptr; - int64_t read_epoch = ObTxTable::INVALID_READ_EPOCH; - if (!tx_table_guard.is_valid()) { + if (!tx_table_guards.is_valid()) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(ERROR, "tx table guard is invalid", KR(ret)); - } else if (OB_FAIL(tx_table_guard.check_row_locked( - read_trans_id, data_trans_id, sql_sequence, lock_state))){ - TRANS_LOG(WARN, "check row locked fail", K(ret), K(read_trans_id), K(data_trans_id), K(sql_sequence), K(read_epoch), K(lock_state)); + } else if (OB_FAIL(tx_table_guards.check_row_locked( + read_trans_id, data_trans_id, sql_sequence, end_scn, lock_state))){ + TRANS_LOG(WARN, "check row locked fail", K(ret), K(read_trans_id), K(data_trans_id), K(sql_sequence), K(lock_state)); } if (lock_state.is_locked_ && read_trans_id != lock_state.lock_trans_id_) { ret = OB_TRY_LOCK_ROW_CONFLICT; @@ -93,7 +94,8 @@ int ObRowConflictHandler::post_row_read_conflict(ObMvccAccessCtx &acc_ctx, const ObTabletID tablet_id, const share::ObLSID ls_id, const int64_t last_compact_cnt, - const int64_t total_trans_node_cnt) + const int64_t total_trans_node_cnt, + const share::SCN &trans_scn) { int ret = OB_TRY_LOCK_ROW_CONFLICT; ObLockWaitMgr *lock_wait_mgr = NULL; @@ -133,9 +135,9 @@ int ObRowConflictHandler::post_row_read_conflict(ObMvccAccessCtx &acc_ctx, lock_state.is_locked_ = false; if (lock_state.is_delayed_cleanout_) { auto lock_data_sequence = lock_state.lock_data_sequence_; - auto &tx_table_guard = acc_ctx.get_tx_table_guard(); - if (OB_FAIL(tx_table_guard.check_row_locked( - tx_id, conflict_tx_id, lock_data_sequence, lock_state))) { + auto &tx_table_guards = acc_ctx.get_tx_table_guards(); + if (OB_FAIL(tx_table_guards.check_row_locked( + tx_id, conflict_tx_id, lock_data_sequence, trans_scn, lock_state))) { TRANS_LOG(WARN, "re-check row locked via tx_table fail", K(ret), K(tx_id), K(lock_state)); } } else { diff --git a/src/storage/memtable/ob_row_conflict_handler.h b/src/storage/memtable/ob_row_conflict_handler.h index bb04a8117..50a2ea919 100644 --- a/src/storage/memtable/ob_row_conflict_handler.h +++ b/src/storage/memtable/ob_row_conflict_handler.h @@ -28,10 +28,11 @@ class ObStoreRowkey; } namespace share { class ObLSID; +class SCN; } namespace storage { class ObStoreRowLockState; -class ObTxTableGuard; +class ObTxTableGuards; class ObRowConflictHandler { public: @@ -46,12 +47,13 @@ public: // choose to retry or throw an exception according to the isolation level. static int check_foreign_key_constraint_for_memtable(memtable::ObMvccValueIterator *value_iter, storage::ObStoreRowLockState &lock_state); - static int check_foreign_key_constraint_for_sstable(storage::ObTxTableGuard &tx_table_guard, + static int check_foreign_key_constraint_for_sstable(storage::ObTxTableGuards &tx_table_guards, const transaction::ObTransID &read_trans_id, const transaction::ObTransID &data_trans_id, const int64_t sql_sequence, const int64_t trans_version, const int64_t snapshot_version, + const share::SCN &end_scn, storage::ObStoreRowLockState &lock_state); // TODO(yichang): This function is refered to ObMemtable::post_row_write_conflict_, // but remove the mem_ctx and tx_ctx in the implement. I think ObMemtable can call @@ -63,7 +65,8 @@ public: const common::ObTabletID tablet_id, const share::ObLSID ls_id, const int64_t last_compact_cnt, - const int64_t total_trans_node_cnt); + const int64_t total_trans_node_cnt, + const share::SCN &trans_scn); }; } } diff --git a/src/storage/meta_mem/ob_fixed_meta_obj_array.h b/src/storage/meta_mem/ob_fixed_meta_obj_array.h new file mode 100644 index 000000000..24940c54f --- /dev/null +++ b/src/storage/meta_mem/ob_fixed_meta_obj_array.h @@ -0,0 +1,379 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_FIXED_META_OBJ_ARRAY_H_ +#define OCEANBASE_STORAGE_OB_FIXED_META_OBJ_ARRAY_H_ + +#include "lib/container/ob_iarray.h" +#include "lib/utility/ob_unify_serialize.h" +#include "lib/utility/utility.h" + +namespace oceanbase +{ + +namespace storage +{ +/* + Fixed size array that support + 1. Allocate memory from inner allocator, lifetime guaranteed by container + 2. Construct array on specific memory segment, lifetime guaranteed by caller + Deep copy and trasition from memory layouts above + Serialization / deserialization + + type of item is prefered to be POD +*/ +template +class ObFixedMetaObjArray : public common::ObIArray +{ +public: + using common::ObIArray::count; + using common::ObIArray::at; + + ObFixedMetaObjArray() + : ObIArray(), + allocator_(nullptr), + capacity_(0), + init_cnt_(0) {} + + ~ObFixedMetaObjArray() { reset(); } + + inline int init(const int64_t capacity, ObIAllocator &allocator); + inline int init(const int64_t capacity, const int64_t buf_len, char *data_buf, int64_t &array_size); + inline int init_and_assign(const common::ObIArray &other, ObIAllocator &allocator); + inline int64_t get_serialize_size() const; + inline int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + inline int deserialize(const char *buf, int64_t data_len, int64_t &pos, ObIAllocator &allocator); + inline int64_t get_deep_copy_size() const; + inline int deep_copy(char *dst_buf, const int64_t buf_size, int64_t &pos, ObFixedMetaObjArray &dst_array) const; + inline T &operator[](const int64_t idx) { return at(idx); } + inline const T &operator[](const int64_t idx) const { return at(idx); } + inline void reset() override; + inline void reuse() override; + inline int push_back(const T &obj) override; + inline void pop_back() override; + inline int pop_back(T &obj) override; + inline int remove(int64_t idx) override; + inline int at(int64_t idx, T &obj) const override; + inline void extra_access_check(void) const override {} + inline void destroy() override; + inline int reserve(int64_t capacity) override; + inline int assign(const common::ObIArray &other) override; + inline int prepare_allocate(int64_t capacity) override; + int64_t get_count() const { return count_; } + bool is_empty() const { return 0 == count_; } + INHERIT_TO_STRING_KV("ObIArray", ObIArray, KP_(data), K_(count), + KP_(allocator), K_(capacity), K_(init_cnt)); +private: + DISALLOW_COPY_AND_ASSIGN(ObFixedMetaObjArray); +private: + using common::ObIArray::data_; + using common::ObIArray::count_; + ObIAllocator *allocator_; + int64_t capacity_; + int64_t init_cnt_; +}; + +template +int ObFixedMetaObjArray::init(const int64_t capacity, ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + if (OB_NOT_NULL(data_) || OB_NOT_NULL(allocator_)) { + ret = OB_INIT_TWICE; + STORAGE_LOG(WARN, "double initialization", K(ret), KPC(this)); + } else if (OB_UNLIKELY(capacity < 0)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "invalid argument", K(capacity)); + } else { + allocator_ = &allocator; + count_ = 0; + init_cnt_ = 0; + if (0 == capacity) { + capacity_ = capacity; + } else if (OB_ISNULL(data_ = static_cast(allocator_->alloc(capacity * sizeof(T))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "failed to allocate memory for array", K(ret), K(capacity), K(sizeof(T))); + } else { + capacity_ = capacity; + } + } + return ret; +} + +template +int ObFixedMetaObjArray::init( + const int64_t capacity, + const int64_t buf_len, + char *data_buf, + int64_t &pos) +{ + int ret = OB_SUCCESS; + const int64_t inner_array_size = sizeof(T) * capacity; + if (OB_NOT_NULL(data_) || OB_NOT_NULL(allocator_)) { + ret = OB_INIT_TWICE; + STORAGE_LOG(WARN, "init twice", K(ret), KPC(this)); + } else if (OB_UNLIKELY(capacity < 0 || (buf_len - pos) < inner_array_size) || OB_ISNULL(data_buf)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "invalid argument", K(capacity), K(buf_len), K(pos), K(inner_array_size), KP(data_buf)); + } else { + allocator_ = nullptr; + count_ = 0; + init_cnt_ = 0; + data_ = reinterpret_cast(data_buf + pos); + capacity_ = capacity; + pos += inner_array_size; + } + return ret; +} + +template +int ObFixedMetaObjArray::init_and_assign( + const common::ObIArray &other, + ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(init(other.count(), allocator))) { + STORAGE_LOG(WARN, "failed to init fixed array", K(ret)); + } else if (OB_FAIL(assign(other))) { + STORAGE_LOG(WARN, "failed to assign from other array", K(ret), K(other)); + } + return ret; +} + +template +int64_t ObFixedMetaObjArray::get_serialize_size() const +{ + int64_t len = 0; + OB_UNIS_ADD_LEN_ARRAY(data_, count_); + return len; +} + +template +int ObFixedMetaObjArray::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + OB_UNIS_ENCODE_ARRAY(data_, count_); + return ret; +} + +template +int ObFixedMetaObjArray::deserialize( + const char *buf, + int64_t data_len, + int64_t &pos, + ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + int64_t count = 0; + if (OB_UNLIKELY(0 != count_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "deserialize a non-empty fixed array is not supported", K(ret)); + } + OB_UNIS_DECODE(count); + if (OB_SUCC(ret) && count > 0) { + if (OB_FAIL(init(count, allocator))) { + STORAGE_LOG(WARN, "fail to init array", K(ret)); + } else if (OB_FAIL(prepare_allocate(count))) { + STORAGE_LOG(WARN, "fail to init array item", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < count; i ++) { + OB_UNIS_DECODE(at(i)); + } + } + } + return ret; +} + +template +int64_t ObFixedMetaObjArray::get_deep_copy_size() const +{ + return count_ * sizeof(T); +} + +template +int ObFixedMetaObjArray::deep_copy( + char *dst_buf, + const int64_t buf_size, + int64_t &pos, + ObFixedMetaObjArray &dst_array) const +{ + int ret = OB_SUCCESS; + const int64_t memory_size = get_deep_copy_size(); + if (OB_ISNULL(dst_buf) || OB_UNLIKELY(buf_size < memory_size)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalue argument", K(ret), KP(dst_buf), K(buf_size), K(memory_size)); + } else if (OB_NOT_NULL(dst_array.data_) || OB_NOT_NULL(dst_array.allocator_)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "can not copy to inited array with this deep copy interface", K(ret), K(dst_array)); + } else if (OB_FAIL(dst_array.init(count_, buf_size, dst_buf, pos))) { + STORAGE_LOG(WARN, "fail to init dst array with copy buf", K(ret), KP(dst_buf), K_(count)); + } else if (OB_FAIL(dst_array.assign(*this))) { + STORAGE_LOG(WARN, "fail to copy local data to dest array", K(ret)); + } + return ret; +} + +template +void ObFixedMetaObjArray::reset() +{ + if (nullptr != data_) { + for (int64_t i = 0; i < init_cnt_; ++i) { + data_[i].~T(); + } + if (allocator_ != nullptr) { + allocator_->free(data_); + allocator_ = nullptr; + } + data_ = nullptr; + } + count_ = 0; + capacity_ = 0; + init_cnt_ = 0; +} + +template +void ObFixedMetaObjArray::reuse() +{ + reset(); +} + +template +int ObFixedMetaObjArray::push_back(const T &obj) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(count_ >= capacity_)) { + ret = OB_SIZE_OVERFLOW; + STORAGE_LOG(WARN, "fixede array size over flow", K(ret), K_(capacity)); + } else if (OB_ISNULL(data_)) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "array not inited", K(ret)); + } else if (OB_LIKELY(count_ >= init_cnt_)) { + if (OB_FAIL(common::construct_assign(data_[count_], obj))) { + STORAGE_LOG(WARN, "failed to copy data", K(ret)); + } else { + ++init_cnt_; + } + } else if (OB_FAIL(common::copy_assign(data_[count_], obj))) { + STORAGE_LOG(WARN, "failed to copy data", K(ret)); + } + + if (OB_SUCC(ret)) { + ++count_; + } + return ret; +} + +template +void ObFixedMetaObjArray::pop_back() +{ + if (count_ > 0) { + --count_; + } +} + +template +int ObFixedMetaObjArray::pop_back(T &obj) +{ + UNUSED(obj); + return OB_NOT_IMPLEMENT; +} + +template +int ObFixedMetaObjArray::remove(int64_t idx) +{ + UNUSED(idx); + return OB_NOT_IMPLEMENT; +} + +template +int ObFixedMetaObjArray::at(int64_t idx, T &obj) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(idx < 0 || idx >= count_)) { + ret = OB_ARRAY_OUT_OF_RANGE; + } else { + if (OB_FAIL(common::copy_assign(obj, data_[idx]))) { + OB_LOG(WARN, "failed to copy obj", K(ret)); + } + } + return ret; +} + +template +void ObFixedMetaObjArray::destroy() +{ + reset(); +} + +template +int ObFixedMetaObjArray::reserve(int64_t capacity) +{ + UNUSED(capacity); + return OB_NOT_IMPLEMENT; +} + +template +int ObFixedMetaObjArray::assign(const common::ObIArray &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(capacity_ < other.count())) { + ret = OB_SIZE_OVERFLOW; + STORAGE_LOG(WARN, "memory of current array is not enough", K(ret), K_(capacity), K(other)); + } else if (OB_UNLIKELY(0 != count_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "assign to a non-empty array is not supported", K(ret)); + } else if (0 == other.count()) { + capacity_ = 0; + count_ = 0; + init_cnt_ = 0; + data_ = nullptr; + } else if (OB_ISNULL(data_)) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "assign to a non-inited fixed meta obj array is not supported", K(ret)); + } else if (this != &other) { + for (int64_t i = 0; OB_SUCC(ret) && i < other.count(); ++i) { + if (OB_FAIL(push_back(other.at(i)))) { + STORAGE_LOG(WARN, "failed to push item in array", K(ret), K(i)); + } + } + } + return ret; +} + +template +int ObFixedMetaObjArray::prepare_allocate(int64_t capacity) +{ + // memory required to be pre-allocated for ObFixedMetaObjArray + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(capacity > capacity_)) { + ret = OB_SIZE_OVERFLOW; + STORAGE_LOG(WARN, "fixed array size over flow", K(ret), K(capacity), K_(capacity)); + } else if (0 == capacity) { + count_ = 0; + init_cnt_ = 0; + } else if (OB_ISNULL(data_)) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "array not inited", K(ret)); + } else { + for (int64_t i = init_cnt_; i < capacity; ++i) { + new(&data_[i]) T(); + } + count_ = capacity > count_ ? capacity : count_; + init_cnt_ = capacity >init_cnt_ ? capacity : init_cnt_; + } + return ret; +} + +} // namespace oceanbase +} // namespace oceanbase + +#endif \ No newline at end of file diff --git a/src/storage/meta_mem/ob_meta_obj_struct.cpp b/src/storage/meta_mem/ob_meta_obj_struct.cpp index 85a321fbe..bbb164d8b 100644 --- a/src/storage/meta_mem/ob_meta_obj_struct.cpp +++ b/src/storage/meta_mem/ob_meta_obj_struct.cpp @@ -25,7 +25,8 @@ ObMetaDiskAddr::ObMetaDiskAddr() : first_id_(0), second_id_(0), third_id_(0), - fourth_id_(0) + fourth_id_(0), + fifth_id_(0) { static_assert(DiskType::MAX <= MAX_TYPE, "ObMetaDiskAddr's disk type is overflow"); type_ = DiskType::MAX; @@ -37,6 +38,7 @@ void ObMetaDiskAddr::reset() second_id_ = 0; third_id_ = 0; fourth_id_ = 0; + fifth_id_ = 0; type_ = DiskType::MAX; } @@ -137,10 +139,10 @@ int ObMetaDiskAddr::set_mem_addr(const int64_t offset, const int64_t size) } OB_SERIALIZE_MEMBER(ObMetaDiskAddr, - first_id_, - second_id_, - third_id_, - fourth_id_); + first_id_, + second_id_, + third_id_, + fourth_id_); bool ObMetaDiskAddr::is_valid() const { @@ -175,26 +177,30 @@ int64_t ObMetaDiskAddr::to_string(char *buf, const int64_t buf_len) const switch (type_) { case FILE: databuff_printf(buf, buf_len, pos, - "[%lu-%lu-%lu-%lu](file_id=%ld,offset=%lu,size=%lu,type=%lu)", + "[%lu-%lu-%lu-%lu-%lu](file_id=%ld,offset=%lu,size=%lu,type=%lu,seq=%lu)", first_id_, second_id_, third_id_, fourth_id_, + fifth_id_, file_id_, (uint64_t) offset_, (uint64_t) size_, - (uint64_t) type_); + (uint64_t) type_, + (uint64_t) seq_); break; default: databuff_printf(buf, buf_len, pos, - "[%lu-%lu-%lu-%lu](offset=%lu,size=%lu,type=%lu)", + "[%lu-%lu-%lu-%lu-%lu](offset=%lu,size=%lu,type=%lu,seq=%lu)", first_id_, second_id_, third_id_, fourth_id_, + fifth_id_, (uint64_t) offset_, (uint64_t) size_, - (uint64_t) type_); + (uint64_t) type_, + (uint64_t) seq_); break; }; @@ -202,6 +208,11 @@ int64_t ObMetaDiskAddr::to_string(char *buf, const int64_t buf_len) const } bool ObMetaDiskAddr::operator ==(const ObMetaDiskAddr &other) const +{ + return is_equal_for_persistence(other) && fifth_id_ == other.fifth_id_; +} + +bool ObMetaDiskAddr::is_equal_for_persistence(const ObMetaDiskAddr &other) const { return first_id_ == other.first_id_ && second_id_ == other.second_id_ diff --git a/src/storage/meta_mem/ob_meta_obj_struct.h b/src/storage/meta_mem/ob_meta_obj_struct.h index fb1c1f00e..ad7e905bf 100644 --- a/src/storage/meta_mem/ob_meta_obj_struct.h +++ b/src/storage/meta_mem/ob_meta_obj_struct.h @@ -17,6 +17,7 @@ #include "common/ob_clock_generator.h" #include "share/ob_define.h" #include "storage/meta_mem/ob_tenant_meta_obj_pool.h" +#include "storage/blocksstable/ob_macro_block_handle.h" namespace oceanbase { @@ -27,8 +28,6 @@ class MacroBlockId; namespace storage { -class ObTenantMetaMemMgr; - class ObMetaDiskAddr final { public: @@ -39,8 +38,6 @@ public: MEM = 3, MAX = 4, }; -public: - static const int64_t ROOT_BLOCK_SIZE_LIMIT = 16 << 10; // 16KB public: ObMetaDiskAddr(); ~ObMetaDiskAddr() = default; @@ -50,6 +47,7 @@ public: bool operator ==(const ObMetaDiskAddr &other) const; bool operator !=(const ObMetaDiskAddr &other) const; + bool is_equal_for_persistence(const ObMetaDiskAddr &other) const; OB_INLINE bool is_block() const { return BLOCK == type_; } OB_INLINE bool is_disked() const { return BLOCK == type_ || FILE == type_; } @@ -57,10 +55,15 @@ public: OB_INLINE bool is_memory() const { return MEM == type_; } OB_INLINE bool is_none() const { return NONE == type_; } OB_INLINE void set_none_addr() { type_ = NONE; } + OB_INLINE void set_seq(const uint64_t seq) { seq_ = seq; } OB_INLINE int64_t file_id() const { return file_id_; } OB_INLINE uint64_t size() const { return size_; } OB_INLINE uint64_t offset() const { return offset_; } + OB_INLINE uint64_t seq() const { return seq_; } OB_INLINE DiskType type() const { return static_cast(type_); } + OB_INLINE void inc_seq() { seq_++; } + OB_INLINE blocksstable::MacroBlockId block_id() const { + return blocksstable::MacroBlockId(first_id_, second_id_, third_id_);} int get_block_addr( blocksstable::MacroBlockId ¯o_id, @@ -87,12 +90,12 @@ public: OB_UNIS_VERSION(1); private: - static const uint64_t MD_FID_BIT_OFFSET = 30; - static const uint64_t MD_FID_BIT_SIZE = 30; - static const uint64_t MD_FID_BIT_TYPE = 4; - static const uint64_t MAX_OFFSET = (0x1UL << MD_FID_BIT_OFFSET) - 1; - static const uint64_t MAX_SIZE = (0x1UL << MD_FID_BIT_SIZE) - 1; - static const uint64_t MAX_TYPE = (0x1UL << MD_FID_BIT_TYPE) - 1; + static const uint64_t FOURTH_ID_BIT_OFFSET = 30; + static const uint64_t FOURTH_ID_BIT_SIZE = 30; + static const uint64_t FOURTH_ID_BIT_TYPE = 4; + static const uint64_t MAX_OFFSET = (0x1UL << FOURTH_ID_BIT_OFFSET) - 1; + static const uint64_t MAX_SIZE = (0x1UL << FOURTH_ID_BIT_SIZE) - 1; + static const uint64_t MAX_TYPE = (0x1UL << FOURTH_ID_BIT_TYPE) - 1; private: union { int64_t first_id_; @@ -107,11 +110,15 @@ private: union { int64_t fourth_id_; struct { - uint64_t offset_ : MD_FID_BIT_OFFSET; - uint64_t size_ : MD_FID_BIT_SIZE; - uint64_t type_ : MD_FID_BIT_TYPE; + uint64_t offset_ : FOURTH_ID_BIT_OFFSET; + uint64_t size_ : FOURTH_ID_BIT_SIZE; + uint64_t type_ : FOURTH_ID_BIT_TYPE; }; }; + union { // doesn't serialize + int64_t fifth_id_; + uint64_t seq_; + }; }; template @@ -119,13 +126,16 @@ class ObMetaObj { public: ObMetaObj(); - virtual ~ObMetaObj() = default; + virtual ~ObMetaObj() { reset(); }; + virtual void reset(); - TO_STRING_KV(KP_(pool), KP_(ptr)); + TO_STRING_KV(KP_(pool), KP_(allocator), KP_(ptr), KP_(t3m)); public: - ObTenantMetaObjPool *pool_; + ObITenantMetaObjPool *pool_; + common::ObIAllocator *allocator_; T *ptr_; + ObTenantMetaMemMgr *t3m_; }; template @@ -139,7 +149,7 @@ public: virtual void reset(); virtual void set_obj(ObMetaObj &obj); - virtual void set_obj(T *obj, common::ObIAllocator *allocator); + virtual void set_obj(T *obj, common::ObIAllocator *allocator, ObTenantMetaMemMgr *t3m); OB_INLINE virtual T *get_obj(); OB_INLINE virtual T *get_obj() const; @@ -150,32 +160,54 @@ public: ObMetaObjGuard &operator = (const ObMetaObjGuard &other); - VIRTUAL_TO_STRING_KV(KP_(obj), KP_(obj_pool), KP_(allocator)); + VIRTUAL_TO_STRING_KV(KP_(obj), KP_(obj_pool), KP_(allocator), KP_(t3m)); protected: static const int64_t HOLD_OBJ_MAX_TIME = 2 * 60 * 60 * 1000 * 1000L; // 2h virtual void reset_obj(); protected: + // TODO(zhuixin.gsy) rm *obj_pool_ and *allocator_ T *obj_; - ObTenantMetaObjPool *obj_pool_; + ObITenantMetaObjPool *obj_pool_; common::ObIAllocator *allocator_; + ObTenantMetaMemMgr *t3m_; int64_t hold_start_time_; }; +class ObIStorageMetaObj +{ +public: + ObIStorageMetaObj() = default; + virtual ~ObIStorageMetaObj() = default; + virtual int deep_copy(char *buf, const int64_t buf_len, ObIStorageMetaObj *&value) const = 0; + virtual int64_t get_deep_copy_size() const = 0; +}; + template ObMetaObj::ObMetaObj() : pool_(nullptr), - ptr_(nullptr) + allocator_(nullptr), + ptr_(nullptr), + t3m_(MTL(ObTenantMetaMemMgr*)) { } +template +void ObMetaObj::reset() +{ + pool_ = nullptr; + allocator_ = nullptr; + ptr_ = nullptr; + t3m_ = nullptr; +} + template ObMetaObjGuard::ObMetaObjGuard() : obj_(nullptr), obj_pool_(nullptr), allocator_(nullptr), - hold_start_time_(INT64_MAX) + t3m_(nullptr) { } @@ -184,7 +216,7 @@ ObMetaObjGuard::ObMetaObjGuard(const ObMetaObjGuard &other) : obj_(nullptr), obj_pool_(nullptr), allocator_(nullptr), - hold_start_time_(INT64_MAX) + t3m_(nullptr) { *this = other; } @@ -199,33 +231,39 @@ template void ObMetaObjGuard::set_obj(ObMetaObj &obj) { reset(); - obj_pool_ = obj.pool_; if (nullptr != obj.ptr_) { - if (nullptr == obj.pool_) { + if (OB_UNLIKELY((nullptr == obj.pool_ && nullptr == obj.allocator_) || nullptr == obj.t3m_)) { STORAGE_LOG_RET(ERROR, common::OB_ERR_UNEXPECTED, "object pool is nullptr", K(obj)); ob_abort(); } else { - obj_ = obj.ptr_; - obj_->inc_ref(); - hold_start_time_ = ObClockGenerator::getClock(); + obj_pool_ = obj.pool_; + allocator_ = obj.allocator_; + t3m_ = obj.t3m_; } + obj_ = obj.ptr_; + obj_->inc_ref(); + hold_start_time_ = ObClockGenerator::getClock(); } } template -void ObMetaObjGuard::set_obj(T *obj, common::ObIAllocator *allocator) +void ObMetaObjGuard::set_obj(T *obj, common::ObIAllocator *allocator, ObTenantMetaMemMgr *t3m) { reset(); allocator_ = allocator; - if (nullptr != obj) { - if (nullptr == allocator) { - STORAGE_LOG_RET(ERROR, common::OB_ERR_UNEXPECTED, "allocator is nullptr", KP(obj), KP(allocator)); - ob_abort(); - } else { - obj_ = obj; - obj_->inc_ref(); - hold_start_time_ = ObClockGenerator::getClock(); - } + t3m_ = t3m; + if (nullptr == obj && nullptr == allocator && nullptr == t3m) { + STORAGE_LOG_RET(ERROR, common::OB_ERR_UNEXPECTED, "invalid args to set", KP(obj), KP(allocator), KP(t3m)); + ob_abort(); + } else if (nullptr != obj) { + if (nullptr == allocator || nullptr == t3m) { + STORAGE_LOG_RET(ERROR, common::OB_ERR_UNEXPECTED, "allocator is nullptr", KP(obj), KP(allocator), KP(t3m)); + ob_abort(); + } else { + obj_ = obj; + obj_->inc_ref(); + hold_start_time_ = ObClockGenerator::getClock(); + } } } @@ -235,12 +273,14 @@ void ObMetaObjGuard::reset() reset_obj(); obj_pool_ = nullptr; allocator_ = nullptr; + t3m_ = nullptr; } template OB_INLINE bool ObMetaObjGuard::is_valid() const { return nullptr != obj_ + && nullptr != t3m_ && ((nullptr != obj_pool_ && nullptr == allocator_) || (nullptr == obj_pool_ && nullptr != allocator_)); } @@ -257,6 +297,7 @@ ObMetaObjGuard &ObMetaObjGuard::operator = (const ObMetaObjGuard &other reset(); obj_pool_ = other.obj_pool_; allocator_ = other.allocator_; + t3m_ = other.t3m_; if (nullptr != other.obj_) { if (OB_UNLIKELY(!other.is_valid())) { STORAGE_LOG_RET(ERROR, common::OB_ERR_UNEXPECTED, "object pool and allocator is nullptr", K(other), KPC(this)); @@ -290,7 +331,9 @@ template OB_INLINE void ObMetaObjGuard::get_obj(ObMetaObj &obj) const { obj.pool_ = obj_pool_; + obj.allocator_ = allocator_; obj.ptr_ = obj_; + obj.t3m_ = t3m_; } template @@ -310,7 +353,7 @@ void ObMetaObjGuard::reset_obj() } if (0 == ref_cnt) { if (nullptr != obj_pool_) { - obj_pool_->release(obj_); + obj_pool_->free_obj(obj_); } else { STORAGE_LOG(DEBUG, "release obj from allocator", KP(obj_), KP(allocator_)); obj_->reset(); @@ -321,11 +364,10 @@ void ObMetaObjGuard::reset_obj() STORAGE_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "obj ref cnt may be leaked", K(ref_cnt), KPC(this)); } obj_ = nullptr; + t3m_ = nullptr; } } - hold_start_time_ = INT64_MAX; } - } // end namespace storage } // end namespace oceanbase diff --git a/src/storage/meta_mem/ob_meta_pointer.h b/src/storage/meta_mem/ob_meta_pointer.h index 01ef86bb6..3f803fb63 100644 --- a/src/storage/meta_mem/ob_meta_pointer.h +++ b/src/storage/meta_mem/ob_meta_pointer.h @@ -16,6 +16,7 @@ #include "lib/allocator/ob_allocator.h" #include "share/rc/ob_tenant_base.h" #include "storage/meta_mem/ob_meta_obj_struct.h" +#include "storage/meta_mem/ob_tablet_handle.h" #include "storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h" #include "storage/slog/ob_storage_log_reader.h" #include "storage/slog/ob_storage_logger.h" @@ -36,8 +37,9 @@ public: virtual ~ObMetaPointer(); int get_in_memory_obj(ObMetaObjGuard &guard); + void get_obj(ObMetaObjGuard &guard); - void set_obj(ObMetaObjGuard &guard); + void set_obj(const ObMetaObjGuard &guard); void set_addr_without_reset_obj(const ObMetaDiskAddr &addr); void set_addr_with_reset_obj(const ObMetaDiskAddr &addr); OB_INLINE const ObMetaDiskAddr &get_addr() const { return phy_addr_; } @@ -58,21 +60,20 @@ public: int64_t get_serialize_size() const; // load and dump interface - int acquire_obj(T *&t); - int read_from_disk(common::ObIAllocator &allocator, char *&r_buf, int64_t &r_len); + virtual int acquire_obj(T *&t); + int read_from_disk(common::ObArenaAllocator &allocator, char *&r_buf, int64_t &r_len, ObMetaDiskAddr &addr); int deserialize( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const char *buf, const int64_t buf_len, T *t); - int hook_obj(T *&t, ObMetaObjGuard &guard); - int release_obj(T *&t); - virtual int dump_meta_obj(bool &is_washed) { return OB_NOT_IMPLEMENT; } + int deserialize( + const char *buf, + const int64_t buf_len, T *t); + int hook_obj(T *&t, ObMetaObjGuard &guard); + virtual int release_obj(T *&t); + virtual int dump_meta_obj(ObMetaObjGuard &guard, void *&free_obj) { return OB_NOT_IMPLEMENT; } protected: - // TIPS: - // - Use this interface with care, no locks, may be concurrent with slog checkpoint. - int load_obj_from_disk(common::ObIAllocator &allocator, T *&t); - virtual int do_post_work_for_load(); virtual void reset(); protected: @@ -101,7 +102,7 @@ ObMetaPointer::ObMetaPointer(const ObMetaDiskAddr &addr, ObMetaObjGuard &g { guard.get_obj(obj_); if (nullptr != obj_.ptr_) { - if (nullptr == obj_.pool_) { + if (nullptr == obj_.pool_ && nullptr == obj_.allocator_) { STORAGE_LOG_RET(ERROR, common::OB_ERR_UNEXPECTED, "object pool is nullptr", K_(obj)); ob_abort(); } else { @@ -124,41 +125,6 @@ ObMetaPointer::~ObMetaPointer() reset(); } -template -int ObMetaPointer::load_obj_from_disk(common::ObIAllocator &allocator, T *&t) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(acquire_obj(t))) { - STORAGE_LOG(WARN, "fail to acquire object", K(ret)); - } else { - common::ObArenaAllocator arena_allocator; - char *buf = nullptr; - int64_t buf_len = 0; - do { - if (OB_FAIL(read_from_disk(arena_allocator, buf, buf_len))) { - if (OB_SEARCH_NOT_FOUND != ret) { - STORAGE_LOG(ERROR, "fail to read from disk", K(ret), K(phy_addr_)); - } - } else { - break; - } - if (OB_SEARCH_NOT_FOUND == ret) { - if (REACH_TIME_INTERVAL(1000000)) { - STORAGE_LOG(WARN, "not found obj in ckpt", K(ret), K(phy_addr_)); - } - ob_usleep(10000); - } - } while (OB_SEARCH_NOT_FOUND == ret); - if (OB_SUCC(ret) && OB_FAIL(deserialize(allocator, buf, buf_len, t))) { - STORAGE_LOG(WARN, "fail to deserialize object", K(ret)); - } - } - if (OB_FAIL(ret) && OB_NOT_NULL(t)) { - release_obj(t); - } - return ret; -} - template int ObMetaPointer::acquire_obj(T *&t) { @@ -166,7 +132,7 @@ int ObMetaPointer::acquire_obj(T *&t) if (OB_ISNULL(obj_.pool_)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "object pool is nullptr", K(ret), K(obj_)); - } else if (OB_FAIL(obj_.pool_->acquire(t))) { + } else if (OB_FAIL(static_cast *>(obj_.pool_)->acquire(t))) { STORAGE_LOG(WARN, "fail to acquire object", K(ret), K(phy_addr_)); } else if (OB_ISNULL(t)) { ret = OB_ERR_UNEXPECTED; @@ -176,40 +142,21 @@ int ObMetaPointer::acquire_obj(T *&t) } template -int ObMetaPointer::read_from_disk(common::ObIAllocator &allocator, char *&r_buf, int64_t &r_len) +int ObMetaPointer::read_from_disk(common::ObArenaAllocator &allocator, char *&r_buf, int64_t &r_len, ObMetaDiskAddr &addr) { int ret = OB_SUCCESS; - bool need_alloc_buf = true; const int64_t buf_len = phy_addr_.size(); const ObMemAttr mem_attr(MTL_ID(), "MetaPointer"); - if (OB_UNLIKELY(0 != r_len) && OB_ISNULL(r_buf)) { + ObTenantCheckpointSlogHandler *ckpt_slog_hanlder = MTL(ObTenantCheckpointSlogHandler*); + if (OB_ISNULL(ckpt_slog_hanlder)) { ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "invalid argument", K(ret), KP(r_buf), K(r_len)); - } else if (nullptr != r_buf) { - if (buf_len == r_len) { - need_alloc_buf = false; - } else { - allocator.free(r_buf); - r_buf = nullptr; - r_len = 0; - } - } - if (OB_SUCC(ret)) { - if (need_alloc_buf && OB_ISNULL(r_buf = static_cast(allocator.alloc(buf_len, mem_attr)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - STORAGE_LOG(WARN, "fail to allocate buf", K(ret), KP(r_buf), K(buf_len)); - } else { - r_len = buf_len; - ObTenantCheckpointSlogHandler *ckpt_slog_hanlder = MTL(ObTenantCheckpointSlogHandler*); - if (OB_ISNULL(ckpt_slog_hanlder)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "slog handler is nullptr", K(ret), KP(ckpt_slog_hanlder)); - } else if (OB_FAIL(ckpt_slog_hanlder->read_from_disk_addr(phy_addr_, r_buf, buf_len, r_buf, r_len))) { - if (OB_SEARCH_NOT_FOUND != ret) { - STORAGE_LOG(ERROR, "fail to read from disk addr", K(ret), K(phy_addr_)); - } - } + STORAGE_LOG(WARN, "slog handler is nullptr", K(ret), KP(ckpt_slog_hanlder)); + } else if (OB_FAIL(ckpt_slog_hanlder->read_from_disk(phy_addr_, allocator, r_buf, r_len))) { + if (OB_SEARCH_NOT_FOUND != ret) { + STORAGE_LOG(ERROR, "fail to read from addr", K(ret), K(phy_addr_)); } + } else { + addr = phy_addr_; } return ret; } @@ -231,16 +178,14 @@ int ObMetaPointer::hook_obj(T *&t, ObMetaObjGuard &guard) STORAGE_LOG(ERROR, "obj ref cnt not 0", K(ret), K(phy_addr_), K(t->get_ref())); } else { t->inc_ref(); + t->set_tablet_addr(phy_addr_); obj_.ptr_ = t; - if (OB_FAIL(do_post_work_for_load())) { - STORAGE_LOG(WARN, "fail to do post work for load", K(ret)); - } else { - guard.set_obj(obj_); - } + guard.set_obj(obj_); + ObMetaObjBufferHelper::set_in_map(reinterpret_cast(t), true/*in_map*/); } if (OB_FAIL(ret) && OB_NOT_NULL(t)) { - obj_.pool_->release(t); + obj_.pool_->free_obj(t); obj_.ptr_ = nullptr; t = nullptr; } @@ -254,11 +199,15 @@ int ObMetaPointer::release_obj(T *&t) int ret = OB_SUCCESS; if (OB_ISNULL(t)) { // do nothing - } else if (OB_ISNULL(obj_.pool_)) { + } else if (OB_UNLIKELY(nullptr == obj_.pool_ && nullptr == obj_.allocator_)) { ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "object pool is nullptr", K(ret), K(obj_)); + STORAGE_LOG(WARN, "object pool or allocator is nullptr", K(ret), K(obj_)); + } else if (nullptr != obj_.pool_) { + obj_.pool_->free_obj(t); + t = nullptr; } else { - obj_.pool_->release(t); + t->~T(); + obj_.allocator_->free(t); t = nullptr; } return ret; @@ -282,6 +231,12 @@ int ObMetaPointer::get_in_memory_obj(ObMetaObjGuard &guard) return ret; } +template +void ObMetaPointer::get_obj(ObMetaObjGuard &guard) +{ + guard.set_obj(obj_); +} + template int ObMetaPointer::deep_copy(char *buf, const int64_t buf_len, ObMetaPointer *&value) const { @@ -293,9 +248,10 @@ int ObMetaPointer::deep_copy(char *buf, const int64_t buf_len, ObMetaPointer } else { ObMetaPointer *pvalue = new (buf) ObMetaPointer(phy_addr_); pvalue->obj_.pool_ = obj_.pool_; + pvalue->obj_.allocator_ = obj_.allocator_; pvalue->obj_.ptr_ = obj_.ptr_; if (nullptr != obj_.ptr_) { - if (nullptr == obj_.pool_) { + if (OB_UNLIKELY(nullptr == obj_.pool_ && nullptr == obj_.allocator_)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(ERROR, "object pool is nullptr", K(ret), K_(obj)); ob_abort(); @@ -339,13 +295,13 @@ void ObMetaPointer::set_addr_with_reset_obj(const ObMetaDiskAddr &addr) } template -void ObMetaPointer::set_obj(ObMetaObjGuard &guard) +void ObMetaPointer::set_obj(const ObMetaObjGuard &guard) { reset_obj(); guard.get_obj(obj_); set_attr_for_obj(obj_.ptr_); if (nullptr != obj_.ptr_) { - if (nullptr == obj_.pool_) { + if (OB_UNLIKELY(nullptr == obj_.pool_ && nullptr == obj_.allocator_)) { STORAGE_LOG_RET(ERROR, common::OB_ERR_UNEXPECTED, "object pool is nullptr", K_(obj)); ob_abort(); } else { @@ -394,16 +350,9 @@ int64_t ObMetaPointer::get_serialize_size() const return phy_addr_.get_serialize_size(); } -template -int ObMetaPointer::do_post_work_for_load() -{ - // nothing to do - return OB_SUCCESS; -} - template int ObMetaPointer::deserialize( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const char *buf, const int64_t buf_len, T *t) @@ -415,7 +364,26 @@ int ObMetaPointer::deserialize( STORAGE_LOG(WARN, "invalid argument", K(ret), KP(buf), K(buf_len), KP(t)); } else if (OB_FAIL(set_attr_for_obj(t))) { STORAGE_LOG(WARN, "fail to set attr for obj", K(ret)); - } else if (OB_FAIL(t->load_deserialize(allocator, buf, buf_len, pos))) { + } else if (OB_FAIL(t->deserialize(allocator, buf, buf_len, pos))) { + STORAGE_LOG(WARN, "fail to de-serialize T", K(ret), KP(buf), K(buf_len), KP(t)); + } + return ret; +} + +template +int ObMetaPointer::deserialize( + const char *buf, + const int64_t buf_len, + T *t) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + if (OB_UNLIKELY(buf_len <= 0) || OB_ISNULL(buf) || OB_ISNULL(t)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), KP(buf), K(buf_len), KP(t)); + } else if (OB_FAIL(set_attr_for_obj(t))) { + STORAGE_LOG(WARN, "fail to set attr for obj", K(ret)); + } else if (OB_FAIL(t->deserialize(buf, buf_len, pos))) { STORAGE_LOG(WARN, "fail to de-serialize T", K(ret), KP(buf), K(buf_len), KP(t)); } return ret; @@ -425,17 +393,31 @@ template void ObMetaPointer::reset_obj() { if (nullptr != obj_.ptr_) { - if (nullptr == obj_.pool_) { + if (OB_UNLIKELY(nullptr == obj_.pool_ && nullptr == obj_.allocator_)) { STORAGE_LOG_RET(ERROR, common::OB_ERR_UNEXPECTED, "object pool is nullptr", K_(obj)); ob_abort(); } else { const int64_t ref_cnt = obj_.ptr_->dec_ref(); if (0 == ref_cnt) { - obj_.pool_->release(obj_.ptr_); + if (nullptr != obj_.pool_) { + obj_.pool_->free_obj(obj_.ptr_); + } else { + obj_.ptr_->~T(); + obj_.allocator_->free(obj_.ptr_); + } } else if (OB_UNLIKELY(ref_cnt < 0)) { STORAGE_LOG_RET(ERROR, common::OB_ERR_UNEXPECTED, "obj ref cnt may be leaked", K(ref_cnt), KPC(this)); } + // The pool ptr on tablet pointer cann't be reset nullptr here. Otherwise, you will + // encounter the following bug when the tablet is deleted from the map. + // + // Bug timeline: + // - Thread 1 load tablet from meta. + // - Thread 2 remove tablet from map. + // - Thread 1 fail to hook loaded tablet into pointer. + // - Thread 1 rolls back and releases the tablet and encounters an error. obj_.ptr_ = nullptr; + obj_.allocator_ = nullptr; } } } @@ -444,7 +426,6 @@ template void ObMetaPointer::reset() { reset_obj(); - obj_.pool_ = nullptr; phy_addr_.reset(); } diff --git a/src/storage/meta_mem/ob_meta_pointer_map.h b/src/storage/meta_mem/ob_meta_pointer_map.h index 49d85c567..df4a424ad 100644 --- a/src/storage/meta_mem/ob_meta_pointer_map.h +++ b/src/storage/meta_mem/ob_meta_pointer_map.h @@ -14,6 +14,7 @@ #define OCEANBASE_STORAGE_OB_META_POINTER_MAP_H_ #include "lib/allocator/page_arena.h" +#include "lib/stat/ob_diagnose_info.h" #include "storage/meta_mem/ob_meta_obj_struct.h" #include "storage/meta_mem/ob_meta_pointer.h" #include "storage/ob_resource_map.h" @@ -30,12 +31,12 @@ class ObMetaPointerMap : public ObResourceMap> { public: typedef ObResourceMap> ResourceMap; - int erase(const Key &key, common::ObIAllocator &allocator); + int erase(const Key &key, ObMetaObjGuard &guard); int exist(const Key &key, bool &is_exist); - int get_meta_obj(const Key &key, common::ObIAllocator &allocator, ObMetaObjGuard &guard); + int get_meta_obj(const Key &key, ObMetaObjGuard &guard); int get_meta_obj_with_external_memory( const Key &key, - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, ObMetaObjGuard &guard, const bool force_alloc_new = false); int try_get_in_memory_meta_obj(const Key &key, bool &success, ObMetaObjGuard &guard); @@ -46,9 +47,9 @@ public: int get_meta_addr(const Key &key, ObMetaDiskAddr &addr); int set_meta_obj(const Key &key, ObMetaObjGuard &guard); int set_attr_for_obj(const Key &key, ObMetaObjGuard &guard); - int compare_and_swap_address_and_object( + int compare_and_swap_addr_and_object( const Key &key, - const ObMetaDiskAddr &addr, + const ObMetaDiskAddr &new_addr, const ObMetaObjGuard &old_guard, ObMetaObjGuard &new_guard); // TIPS: @@ -58,33 +59,31 @@ public: const ObMetaDiskAddr &old_addr, const ObMetaDiskAddr &new_addr); template int for_each_value_store(Operator &op); - int wash_meta_obj(const Key &key, bool &is_washed); - template - int wash_meta_obj_with_func( - const Key &key, - const ObMetaDiskAddr &old_addr, - Function &dump, - bool &is_washed); + int wash_meta_obj(const Key &key, ObMetaObjGuard &guard, void *&free_obj); int64_t count() const { return ResourceMap::map_.size(); } + private: + // used when tablet object and memory is hold by external allocator int load_meta_obj( const Key &key, ObMetaPointer *meta_pointer, - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, ObMetaDiskAddr &load_addr, - T *&t, - const bool using_obj_pool = true); - int load_and_hook_meta_obj( + T *t); + // used when tablet object and memory is hold by t3m + int load_meta_obj( const Key &key, - ObMetaPointerHandle &ptr_hdl, - common::ObIAllocator &allocator, - ObMetaObjGuard &guard); + ObMetaPointer *meta_pointer, + ObMetaDiskAddr &load_addr, + T *&t); + int load_and_hook_meta_obj(const Key &key, ObMetaPointerHandle &ptr_hdl, ObMetaObjGuard &guard); int try_get_in_memory_meta_obj( const Key &key, ObMetaPointerHandle &ptr_hdl, ObMetaObjGuard &guard, bool &is_in_memory); - int erase(const Key &key); + int inner_erase(const Key &key); + public: using ObResourceMap>::ObResourceMap; }; @@ -99,6 +98,7 @@ public: ObResourceValueStore> *ptr, ObMetaPointerMap *map); virtual ~ObMetaPointerHandle(); + public: virtual void reset() override; bool is_valid() const; @@ -109,6 +109,7 @@ private: int set( ObResourceValueStore> *ptr, ObMetaPointerMap *map); + private: ObMetaPointerMap *map_; @@ -124,8 +125,8 @@ ObMetaPointerHandle::ObMetaPointerHandle() template ObMetaPointerHandle::ObMetaPointerHandle(ObMetaPointerMap &map) - : ObResourceHandle>::ObResourceHandle(), - map_(&map) + : ObResourceHandle>::ObResourceHandle(), + map_(&map) { } @@ -133,8 +134,8 @@ template ObMetaPointerHandle::ObMetaPointerHandle( ObResourceValueStore> *ptr, ObMetaPointerMap *map) - : ObResourceHandle>::ObResourceHandle(), - map_(map) + : ObResourceHandle>::ObResourceHandle(), + map_(map) { abort_unless(common::OB_SUCCESS == set(ptr, map)); } @@ -202,37 +203,34 @@ int ObMetaPointerHandle::set( } template -int ObMetaPointerMap::erase(const Key &key, common::ObIAllocator &allocator) +int ObMetaPointerMap::erase(const Key &key, ObMetaObjGuard &guard) { int ret = common::OB_SUCCESS; - ObResourceValueStore> *ptr = NULL; - ObMetaObjGuard guard; bool need_erase = false; if (OB_UNLIKELY(!ResourceMap::is_inited_)) { ret = common::OB_NOT_INIT; STORAGE_LOG(WARN, "ObResourceMap has not been inited", K(ret)); - // make sure load object to memory to release any reference count. - } else if (OB_SUCC(get_meta_obj(key, allocator, guard))) { + } else if (OB_SUCC(get_meta_obj(key, guard))) { // make sure load object to memory to release any reference count. need_erase = true; } else if (OB_ENTRY_NOT_EXIST == ret) { - ret = OB_SUCCESS; // ignore ret error, may be creating failure or has been erased. + ret = OB_SUCCESS; // ignore ret error, may be creating failure or has been erased. } else if (OB_ITEM_NOT_SETTED == ret) { need_erase = true; - ret = OB_SUCCESS; // ignore ret error, may be creating failure. + ret = OB_SUCCESS; // ignore ret error, may be creating failure. } else { STORAGE_LOG(WARN, "fail to get meta obj", K(ret), K(key)); } if (OB_SUCC(ret) && need_erase) { - if (OB_FAIL(erase(key))) { + if (OB_FAIL(inner_erase(key))) { STORAGE_LOG(WARN, "fail to erase meta pointer", K(ret), K(key)); } } - guard.reset(); + STORAGE_LOG(DEBUG, "erase", K(ret), K(need_erase), K(guard), KPC(guard.get_obj())); return ret; } template -int ObMetaPointerMap::erase(const Key &key) +int ObMetaPointerMap::inner_erase(const Key &key) { int ret = common::OB_SUCCESS; ObResourceValueStore> *ptr = NULL; @@ -375,6 +373,7 @@ int ObMetaPointerMap::try_get_in_memory_meta_obj( int ret = OB_SUCCESS; uint64_t hash_val = 0; ObMetaPointer *t_ptr = nullptr; + is_in_memory = false; if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) { STORAGE_LOG(WARN, "fail to calc hash", K(ret), K(key)); } else { @@ -389,11 +388,9 @@ int ObMetaPointerMap::try_get_in_memory_meta_obj( } else if (OB_UNLIKELY(t_ptr->get_addr().is_none())) { ret = OB_ITEM_NOT_SETTED; STORAGE_LOG(DEBUG, "pointer addr is none, no object to be got", K(ret), K(key), KPC(t_ptr)); - } else { - is_in_memory = t_ptr->is_in_memory(); - if (is_in_memory && OB_FAIL(t_ptr->get_in_memory_obj(guard))) { - STORAGE_LOG(WARN, "fail to get meta object", K(ret), KP(t_ptr), K(key)); - } + } else if (t_ptr->is_in_memory()) { + t_ptr->get_obj(guard); + is_in_memory = true; } } return ret; @@ -402,7 +399,6 @@ int ObMetaPointerMap::try_get_in_memory_meta_obj( template int ObMetaPointerMap::get_meta_obj( const Key &key, - common::ObIAllocator &allocator, ObMetaObjGuard &guard) { int ret = common::OB_SUCCESS; @@ -418,10 +414,14 @@ int ObMetaPointerMap::get_meta_obj( } else { STORAGE_LOG(WARN, "fail to try get in memory meta obj", K(ret), K(key)); } - } else if (!is_in_memory) { - if (OB_FAIL(load_and_hook_meta_obj(key, ptr_hdl, allocator, guard))) { + } else if (OB_UNLIKELY(!is_in_memory)) { + if (OB_FAIL(load_and_hook_meta_obj(key, ptr_hdl, guard))) { STORAGE_LOG(WARN, "fail to load and hook meta obj", K(ret), K(key)); + } else { + EVENT_INC(ObStatEventIds::TABLET_CACHE_MISS); } + } else { + EVENT_INC(ObStatEventIds::TABLET_CACHE_HIT); } return ret; } @@ -430,7 +430,6 @@ template int ObMetaPointerMap::load_and_hook_meta_obj( const Key &key, ObMetaPointerHandle &ptr_hdl, - common::ObIAllocator &allocator, ObMetaObjGuard &guard) { int ret = OB_SUCCESS; @@ -438,10 +437,11 @@ int ObMetaPointerMap::load_and_hook_meta_obj( ObMetaDiskAddr disk_addr; ObMetaPointer *meta_pointer = ptr_hdl.get_resource_ptr(); do { + bool need_free_obj = false; T *t = nullptr; // Move load obj from disk out of the bucket lock, because // wash obj may acquire the bucket lock again, which cause dead lock. - if (OB_FAIL(load_meta_obj(key, meta_pointer, allocator, disk_addr, t))) { + if (OB_FAIL(load_meta_obj(key, meta_pointer, disk_addr, t))) { STORAGE_LOG(WARN, "load obj from disk fail", K(ret), K(key), KPC(meta_pointer), K(lbt())); } else if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) { STORAGE_LOG(WARN, "fail to calc hash", K(ret), K(key)); @@ -452,15 +452,11 @@ int ObMetaPointerMap::load_and_hook_meta_obj( if (OB_ENTRY_NOT_EXIST != ret) { STORAGE_LOG(WARN, "fail to get pointer handle", K(ret)); } - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = meta_pointer->release_obj(t))) { - STORAGE_LOG(ERROR, "fail to release object", K(ret), K(tmp_ret), KP(meta_pointer)); - } - } else if (meta_pointer->is_in_memory()) {// some other thread finish loading + need_free_obj = true; + } else if (meta_pointer->is_in_memory()) { // some other thread finish loading + need_free_obj = true; if (OB_FAIL(meta_pointer->get_in_memory_obj(guard))) { STORAGE_LOG(ERROR, "fail to get meta object", K(ret), KP(meta_pointer)); - } else if (OB_FAIL(meta_pointer->release_obj(t))) { - STORAGE_LOG(ERROR, "fail to release object", K(ret), KP(meta_pointer)); } } else if (OB_UNLIKELY(disk_addr != meta_pointer->get_addr() || meta_pointer != tmp_ptr_hdl.get_resource_ptr() @@ -488,6 +484,12 @@ int ObMetaPointerMap::load_and_hook_meta_obj( } } } // write lock end + if (need_free_obj) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(meta_pointer->release_obj(t))) { + STORAGE_LOG(ERROR, "fail to release object", K(ret), K(tmp_ret), KP(meta_pointer)); + } + } } while (OB_ITEM_NOT_MATCH == ret); return ret; } @@ -496,17 +498,53 @@ template int ObMetaPointerMap::load_meta_obj( const Key &key, ObMetaPointer *meta_pointer, - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, ObMetaDiskAddr &load_addr, - T *&t, - const bool using_obj_pool) + T *t) +{ + int ret = common::OB_SUCCESS; + uint64_t hash_val = 0; + if (OB_UNLIKELY(!key.is_valid()) || OB_ISNULL(meta_pointer)) { + ret = common::OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(key), KP(meta_pointer)); + } else if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) { + STORAGE_LOG(WARN, "fail to calc hash", K(ret), K(key)); + } else { + common::ObArenaAllocator arena_allocator; + char *buf = nullptr; + int64_t buf_len = 0; + { + common::ObBucketHashRLockGuard lock_guard(ResourceMap::bucket_lock_, hash_val); + if (OB_FAIL(meta_pointer->read_from_disk(arena_allocator, buf, buf_len, load_addr))) { + STORAGE_LOG(ERROR, "fail to read from disk", K(ret), KPC(meta_pointer)); + } + } + if (OB_SUCC(ret)) { + t->tablet_addr_ = load_addr; + if (OB_FAIL(meta_pointer->deserialize(allocator, buf, buf_len, t))) { + STORAGE_LOG(WARN, "fail to deserialize object", K(ret), K(key), KPC(meta_pointer)); + } + } + } + + // this load_meta_obj is called when tablet memory hold by external allocator + // let caller tackle failure, recycle object and memory, + return ret; +} + +template +int ObMetaPointerMap::load_meta_obj( + const Key &key, + ObMetaPointer *meta_pointer, + ObMetaDiskAddr &load_addr, + T *&t) { int ret = common::OB_SUCCESS; uint64_t hash_val = 0; if (OB_UNLIKELY(!key.is_valid()) || OB_ISNULL(meta_pointer)) { ret = common::OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid argument", K(ret), K(key), KP(meta_pointer), K(using_obj_pool)); - } else if (using_obj_pool && OB_FAIL(meta_pointer->acquire_obj(t))) { + STORAGE_LOG(WARN, "invalid argument", K(ret), K(key), KP(meta_pointer)); + } else if (OB_FAIL(meta_pointer->acquire_obj(t))) { STORAGE_LOG(WARN, "fail to acquire object", K(ret), K(key), KPC(meta_pointer)); } else if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) { STORAGE_LOG(WARN, "fail to calc hash", K(ret), K(key)); @@ -514,30 +552,21 @@ int ObMetaPointerMap::load_meta_obj( common::ObArenaAllocator arena_allocator; char *buf = nullptr; int64_t buf_len = 0; - do { - { // write lock - common::ObBucketHashRLockGuard lock_guard(ResourceMap::bucket_lock_, hash_val); - load_addr = meta_pointer->get_addr(); - if (OB_FAIL(meta_pointer->read_from_disk(arena_allocator, buf, buf_len))) { - if (OB_SEARCH_NOT_FOUND != ret) { - STORAGE_LOG(ERROR, "fail to read from disk", K(ret), KPC(meta_pointer)); - } - } else { - break; - } + { + common::ObBucketHashRLockGuard lock_guard(ResourceMap::bucket_lock_, hash_val); + if (OB_FAIL(meta_pointer->read_from_disk(arena_allocator, buf, buf_len, load_addr))) { + STORAGE_LOG(ERROR, "fail to read from disk", K(ret), KPC(meta_pointer)); } - if (OB_SEARCH_NOT_FOUND == ret) { - if (REACH_TIME_INTERVAL(1000000)) { - STORAGE_LOG(WARN, "not found obj in ckpt", K(ret), KPC(meta_pointer)); - } - ob_usleep(10000); + } + if (OB_SUCC(ret)) { + t->tablet_addr_ = load_addr; + if (OB_FAIL(meta_pointer->deserialize(buf, buf_len, t))) { + STORAGE_LOG(ERROR, "fail to deserialize object", K(ret), K(key), KPC(meta_pointer)); } - } while (OB_SEARCH_NOT_FOUND == ret); - if (OB_SUCC(ret) && OB_FAIL(meta_pointer->deserialize(allocator, buf, buf_len, t))) { - STORAGE_LOG(WARN, "fail to deserialize object", K(ret), K(key), KPC(meta_pointer)); } } - if (OB_FAIL(ret) && using_obj_pool && OB_NOT_NULL(t)) { + + if (OB_FAIL(ret) && OB_NOT_NULL(t)) { meta_pointer->release_obj(t); t = nullptr; } @@ -547,7 +576,7 @@ int ObMetaPointerMap::load_meta_obj( template int ObMetaPointerMap::get_meta_obj_with_external_memory( const Key &key, - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, ObMetaObjGuard &guard, const bool force_alloc_new) { @@ -575,6 +604,8 @@ int ObMetaPointerMap::get_meta_obj_with_external_memory( } else { STORAGE_LOG(WARN, "fail to try get in memory meta obj", K(ret), K(key)); } + } else if (is_in_memory) { + EVENT_INC(ObStatEventIds::TABLET_CACHE_HIT); } if (OB_SUCC(ret) && !is_in_memory) { t_ptr = ptr_hdl.get_resource_ptr(); @@ -585,11 +616,10 @@ int ObMetaPointerMap::get_meta_obj_with_external_memory( STORAGE_LOG(WARN, "fail to allocate memory", K(ret), KP(buf), "size of", sizeof(T)); } else { bool need_free_obj = false; - T *t = nullptr; - t = new (buf) T(); + T *t = new (buf) T(); do { t->reset(); - if (OB_FAIL(load_meta_obj(key, t_ptr, allocator, disk_addr, t, false/*using_obj_pool*/))) { + if (OB_FAIL(load_meta_obj(key, t_ptr, allocator, disk_addr, t))) { STORAGE_LOG(WARN, "load obj from disk fail", K(ret), K(key), KPC(t_ptr), K(lbt())); } else { ObMetaPointerHandle tmp_ptr_hdl(*this); @@ -619,14 +649,16 @@ int ObMetaPointerMap::get_meta_obj_with_external_memory( if (REACH_TIME_INTERVAL(1000000)) { STORAGE_LOG(WARN, "disk address change", K(ret), K(disk_addr), KPC(t_ptr)); } - } else if (OB_FAIL(t->deserialize_post_work())) { - STORAGE_LOG(WARN, "fail to deserialize post work", K(ret), KP(t)); } else if (OB_FAIL(t->assign_pointer_handle(ptr_hdl))) { STORAGE_LOG(WARN, "fail to assign pointer handle", K(ret), KP(t)); } else { - guard.set_obj(t, &allocator); + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + guard.set_obj(t, &allocator, t3m); } - }// write lock end + } // write lock end + if ((OB_FAIL(ret) && OB_NOT_NULL(t)) || need_free_obj) { + t->dec_macro_ref_cnt(); + } } while (OB_ITEM_NOT_MATCH == ret); if ((OB_FAIL(ret) && OB_NOT_NULL(t)) || need_free_obj) { t->~T(); @@ -654,7 +686,7 @@ int ObMetaPointerMap::get_meta_addr(const Key &key, ObMetaDiskAddr &addr } else { // read lock common::ObBucketHashRLockGuard lock_guard(ResourceMap::bucket_lock_, hash_val); if (OB_FAIL(ResourceMap::get_without_lock(key, ptr_hdl))) { - STORAGE_LOG(WARN, "fail to get pointer handle", K(ret)); + STORAGE_LOG(WARN, "fail to get pointer handle", K(ret), K(key)); } else if (OB_ISNULL(t_ptr = ptr_hdl.get_resource_ptr())) { ret = common::OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "fail to get meta pointer", K(ret), KP(t_ptr)); @@ -718,53 +750,56 @@ int ObMetaPointerMap::set_attr_for_obj(const Key &key, ObMetaObjGuard } template -int ObMetaPointerMap::compare_and_swap_address_and_object( +int ObMetaPointerMap::compare_and_swap_addr_and_object( const Key &key, - const ObMetaDiskAddr &addr, + const ObMetaDiskAddr &new_addr, const ObMetaObjGuard &old_guard, ObMetaObjGuard &new_guard) { int ret = common::OB_SUCCESS; - uint64_t hash_val = 0; - ObMetaObjGuard guard; ObMetaPointerHandle ptr_hdl(*this); ObMetaPointer *t_ptr = nullptr; - if (OB_UNLIKELY(!key.is_valid() - || !addr.is_valid() - || addr.is_none() - || !old_guard.is_valid() - || !new_guard.is_valid())) { - ret = common::OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid argument", K(ret), K(key), K(addr), K(old_guard), K(new_guard)); - } else if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) { + ObMetaObjGuard ptr_guard; + uint64_t hash_val = 0; + + if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) { STORAGE_LOG(WARN, "fail to calc hash", K(ret), K(key)); } else { common::ObBucketHashWLockGuard lock_guard(ResourceMap::bucket_lock_, hash_val); if (OB_FAIL(ResourceMap::get_without_lock(key, ptr_hdl))) { - STORAGE_LOG(WARN, "fail to get pointer handle", K(ret)); + if (common::OB_ENTRY_NOT_EXIST != ret) { + STORAGE_LOG(WARN, "fail to get pointer handle", K(ret), K(key)); + } } else if (OB_ISNULL(t_ptr = ptr_hdl.get_resource_ptr())) { ret = common::OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "fail to get meta pointer", K(ret), KP(t_ptr)); - } else if (OB_UNLIKELY(!t_ptr->is_in_memory() && t_ptr->get_addr().is_disked())) { - ret = common::OB_NOT_THE_OBJECT; - STORAGE_LOG(WARN, "old object has changed, need to get again", K(ret), KP(t_ptr)); - } else if (OB_FAIL(t_ptr->get_in_memory_obj(guard))) { - if (common::OB_ITEM_NOT_SETTED != ret || old_guard.get_obj() != new_guard.get_obj()) { - STORAGE_LOG(WARN, "fail to get object", K(ret), KP(t_ptr)); + } else if (OB_UNLIKELY(!t_ptr->is_in_memory())) { + if (t_ptr->get_addr().is_disked()) { + ret = common::OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "old object has changed, which is not allowed", K(ret), KP(t_ptr)); } else { - ret = common::OB_SUCCESS; + // first time CAS + if (!t_ptr->get_addr().is_none() || old_guard.get_obj() != new_guard.get_obj()) { + ret = common::OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "this is not the first time cas", K(ret), + K(t_ptr->get_addr()), KP(old_guard.get_obj()), KP(new_guard.get_obj())); + } else { + ret = common::OB_SUCCESS; + } } - } else if (OB_UNLIKELY(guard.get_obj() != old_guard.get_obj())) { + } else if (OB_FAIL(t_ptr->get_in_memory_obj(ptr_guard))) { + STORAGE_LOG(WARN, "fail to get object", K(ret), KP(t_ptr)); + } else if (OB_UNLIKELY(ptr_guard.get_obj() != old_guard.get_obj())) { ret = common::OB_NOT_THE_OBJECT; - STORAGE_LOG(WARN, "old object has changed, need to get again", K(ret), KP(t_ptr)); + STORAGE_LOG(WARN, "old object has changed", K(ret), KP(t_ptr)); } - if (OB_FAIL(ret)) { - } else if (OB_NOT_NULL(t_ptr)) { - t_ptr->set_addr_with_reset_obj(addr); + if (OB_SUCC(ret)) { + t_ptr->set_addr_with_reset_obj(new_addr); t_ptr->set_obj(new_guard); } } + return ret; } @@ -795,9 +830,9 @@ int ObMetaPointerMap::compare_and_swap_address_without_object( STORAGE_LOG(WARN, "fail to get meta pointer", K(ret), KP(t_ptr)); } else if (OB_UNLIKELY(t_ptr->get_addr() != old_addr)) { ret = common::OB_NOT_THE_OBJECT; - STORAGE_LOG(WARN, "old address has changed, need to get again", K(ret), KP(t_ptr)); + STORAGE_LOG(WARN, "old address has changed, need to get again", K(ret), KPC(t_ptr), K(old_addr)); } else { - t_ptr->set_addr_without_reset_obj(new_addr); + t_ptr->set_addr_with_reset_obj(new_addr); } } return ret; @@ -814,7 +849,7 @@ int ObMetaPointerMap::for_each_value_store(Operator &op) STORAGE_LOG(WARN, "ObMetaPointerMap has not been inited", K(ret)); } else { bool locked = false; - while(OB_SUCC(ret) && !locked) { + while (OB_SUCC(ret) && !locked) { common::ObBucketTryRLockAllGuard lock_guard(ResourceMap::bucket_lock_); if (OB_FAIL(lock_guard.get_ret()) && OB_EAGAIN != ret) { STORAGE_LOG(WARN, "fail to lock all tablet id set", K(ret)); @@ -834,11 +869,10 @@ int ObMetaPointerMap::for_each_value_store(Operator &op) } template -int ObMetaPointerMap::wash_meta_obj(const Key &key, bool &is_washed) +int ObMetaPointerMap::wash_meta_obj(const Key &key, ObMetaObjGuard &guard, void *&free_obj) { int ret = common::OB_SUCCESS; uint64_t hash_val = 0; - is_washed = false; ObMetaPointerHandle ptr_hdl(*this); ObMetaPointer *t_ptr = nullptr; @@ -862,65 +896,13 @@ int ObMetaPointerMap::wash_meta_obj(const Key &key, bool &is_washed) } else if (OB_ISNULL(t_ptr = ptr_hdl.get_resource_ptr())) { ret = common::OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "fail to get meta pointer", K(ret), KP(t_ptr), K(key)); - } else if (OB_FAIL(t_ptr->dump_meta_obj(is_washed))){ - STORAGE_LOG(ERROR, "fail to dump met obj", K(ret), K(key)); + } else if (OB_FAIL(t_ptr->dump_meta_obj(guard, free_obj))) { + STORAGE_LOG(ERROR, "fail to dump meta obj", K(ret), K(key)); } } return ret; } - -template -template -int ObMetaPointerMap::wash_meta_obj_with_func( - const Key &key, - const ObMetaDiskAddr &old_addr, - Function &dump, - bool &is_washed) -{ - int ret = common::OB_SUCCESS; - uint64_t hash_val = 0; - if (OB_UNLIKELY(!key.is_valid() || !old_addr.is_valid() || !old_addr.is_memory())) { - ret = common::OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid argument", K(ret), K(key), K(old_addr)); - } else if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) { - STORAGE_LOG(WARN, "fail to calc hash", K(ret), K(key)); - } else { - ObMetaPointerHandle ptr_hdl(*this); - ObMetaPointer *t_ptr = nullptr; - ObMetaObjGuard guard; - ObMetaDiskAddr new_addr; - common::ObBucketHashWLockGuard lock_guard(ResourceMap::bucket_lock_, hash_val); - if (OB_FAIL(ResourceMap::get_without_lock(key, ptr_hdl))) { - if (common::OB_ENTRY_NOT_EXIST != ret) { - STORAGE_LOG(WARN, "fail to get pointer handle", K(ret), K(key)); - } - } else if (OB_ISNULL(t_ptr = ptr_hdl.get_resource_ptr())) { - ret = common::OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "fail to get meta pointer", K(ret), KP(t_ptr), K(key)); - } else if (OB_UNLIKELY(t_ptr->get_addr() != old_addr)) { - ret = common::OB_NOT_THE_OBJECT; - STORAGE_LOG(WARN, "old address has changed, need to get again", K(ret), KPC(t_ptr), K(old_addr)); - } else if (OB_UNLIKELY(!t_ptr->is_in_memory())) { - ret = common::OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "address is memory, but object isn't in memory", K(ret), K(key), KPC(t_ptr)); - } else if (OB_FAIL(t_ptr->get_in_memory_obj(guard))) { - STORAGE_LOG(WARN, "fail to get meta object", K(ret), KP(t_ptr), K(key)); - } else if (OB_FAIL(dump(guard, new_addr))) { - STORAGE_LOG(WARN, "fail to dump", K(ret), K(guard), K(key)); - } else { - guard.reset(); - t_ptr->set_addr_without_reset_obj(new_addr); - if (OB_FAIL(t_ptr->dump_meta_obj(is_washed))){ - STORAGE_LOG(ERROR, "fail to dump met obj", K(ret), K(key)); - } else { - STORAGE_LOG(INFO, "wash tablet with slog succeed", K(key), K(old_addr), K(new_addr)); - } - } - } - return ret; -} - -} // end namespace storage -} // end namespace oceanbase +} // end namespace storage +} // end namespace oceanbase #endif /* OCEANBASE_STORAGE_OB_META_POINTER_MAP_H_ */ diff --git a/src/storage/meta_mem/ob_storage_meta_cache.cpp b/src/storage/meta_mem/ob_storage_meta_cache.cpp new file mode 100644 index 000000000..d452ed2cc --- /dev/null +++ b/src/storage/meta_mem/ob_storage_meta_cache.cpp @@ -0,0 +1,785 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "ob_storage_meta_cache.h" + +#include "lib/stat/ob_diagnose_info.h" +#include "lib/statistic_event/ob_stat_event.h" +#include "share/io/ob_io_struct.h" +#include "storage/blocksstable/ob_sstable.h" +#include "storage/blocksstable/ob_storage_cache_suite.h" +#include "storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h" +#include "storage/tablet/ob_tablet_table_store.h" +#include "storage/tablet/ob_tablet.h" +#include "share/ob_tablet_autoincrement_param.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/blocksstable/ob_storage_cache_suite.h" + +namespace oceanbase +{ +using namespace blocksstable; +namespace storage +{ +ObStorageMetaKey::ObStorageMetaKey() + : tenant_id_(0), + phy_addr_() +{ +} + +ObStorageMetaKey::ObStorageMetaKey(const uint64_t tenant_id, const ObMetaDiskAddr &phy_addr) + : tenant_id_(tenant_id), + phy_addr_(phy_addr) +{ +} + +ObStorageMetaKey::ObStorageMetaKey( + const uint64_t tenant_id, + const blocksstable::MacroBlockId &block_id, + const int64_t offset, + const int64_t size) + : tenant_id_(tenant_id) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(phy_addr_.set_block_addr(block_id, offset, size))) { + LOG_ERROR("fail to set block address", K(ret), K(block_id), K(offset), K(size)); + } + abort_unless(OB_SUCCESS == ret); +} + +ObStorageMetaKey::~ObStorageMetaKey() +{ +} + +bool ObStorageMetaKey::operator ==(const ObIKVCacheKey &other) const +{ + const ObStorageMetaKey &other_key = reinterpret_cast (other); + return phy_addr_ == other_key.phy_addr_ + && tenant_id_ == other_key.tenant_id_; +} + +uint64_t ObStorageMetaKey::get_tenant_id() const +{ + return tenant_id_; +} + +uint64_t ObStorageMetaKey::hash() const +{ + return murmurhash(this, sizeof(ObStorageMetaKey), 0); +} + +int64_t ObStorageMetaKey::size() const +{ + return sizeof(*this); +} + +int ObStorageMetaKey::deep_copy(char *buf, const int64_t buf_len, ObIKVCacheKey *&key) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(NULL == buf || buf_len < size())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret)); + } else if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid storage meta cache key", K(ret), K(*this)); + } else { + key = new (buf) ObStorageMetaKey(tenant_id_, phy_addr_); + } + return ret; +} + +bool ObStorageMetaKey::is_valid() const +{ + return phy_addr_.is_valid() && tenant_id_ > 0; +} + +const ObMetaDiskAddr &ObStorageMetaKey::get_meta_addr() const +{ + return phy_addr_; +} + +ObStorageMetaValue::StorageMetaProcessor ObStorageMetaValue::processor[ObStorageMetaValue::MetaType::MAX] + = { ObStorageMetaValue::process_sstable, + ObStorageMetaValue::process_table_store, + ObStorageMetaValue::process_autoinc_seq, + }; + +ObStorageMetaValue::StorageMetaBypassProcessor ObStorageMetaValue::bypass_processor[MetaType::MAX] + = { ObStorageMetaValue::bypass_process_storage_meta, + nullptr, // not support bypass process table store. + ObStorageMetaValue::bypass_process_storage_meta, + }; + + +ObStorageMetaValue::ObStorageMetaValue() + : type_(MetaType::MAX), + obj_(nullptr) +{ +} + +ObStorageMetaValue::ObStorageMetaValue( + const MetaType type, + ObIStorageMetaObj *obj) + : type_(type), + obj_(obj) +{ +} + +ObStorageMetaValue::~ObStorageMetaValue() +{ +} + +bool ObStorageMetaValue::is_valid() const +{ + return nullptr != obj_; +} + +int64_t ObStorageMetaValue::size() const +{ + return sizeof(*this) + obj_->get_deep_copy_size(); +} + +int ObStorageMetaValue::deep_copy(char *buf, const int64_t buf_len, ObIKVCacheValue *&value) const +{ + int ret = OB_SUCCESS; + ObStorageMetaValue *pvalue = nullptr; + if (OB_UNLIKELY(nullptr == buf || buf_len < size())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(buf), K(buf_len), "request_size", size()); + } else if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid storage meta cache value", K(ret)); + } else { + char *new_buf = buf + sizeof(ObStorageMetaValue); + pvalue = new (buf) ObStorageMetaValue(); + if (OB_FAIL(obj_->deep_copy(new_buf, buf_len - sizeof(ObStorageMetaValue), pvalue->obj_))) { + LOG_WARN("fail to deep copy storage meta object", K(ret), KP(buf), K(buf_len)); + } else { + pvalue->type_ = type_; + value = pvalue; + } + } + return ret; +} + +int ObStorageMetaValue::get_sstable(const blocksstable::ObSSTable *&sstable) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(obj_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (OB_UNLIKELY(MetaType::SSTABLE != type_)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("not sstable", K(ret), K(type_)); + } else { + sstable = static_cast(obj_); + } + return ret; +} + +int ObStorageMetaValue::get_sstable(blocksstable::ObSSTable *&sstable) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(obj_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (OB_UNLIKELY(MetaType::SSTABLE != type_)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("not sstable", K(ret), K(type_)); + } else { + sstable = static_cast(obj_); + } + return ret; +} + +int ObStorageMetaValue::get_table_store(const ObTabletTableStore *&store) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(obj_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (OB_UNLIKELY(MetaType::TABLE_STORE != type_)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("not table store", K(ret), K(type_)); + } else { + store = static_cast(obj_); + } + return ret; +} + +int ObStorageMetaValue::get_autoinc_seq(const share::ObTabletAutoincSeq *&seq) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(obj_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (OB_UNLIKELY(MetaType::AUTO_INC_SEQ != type_)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("not auto inc seq", K(ret), K(type_)); + } else { + seq = static_cast(obj_); + } + return ret; +} + +int ObStorageMetaValue::process_sstable( + ObStorageMetaValueHandle &handle, + const ObStorageMetaKey &key, + const char *buf, + const int64_t size, + const ObTablet *tablet) +{ + UNUSED(tablet); + int ret = OB_SUCCESS; + ObArenaAllocator allocator; + blocksstable::ObSSTable sstable; + ObIStorageMetaObj *tiny_meta = nullptr; + char *tmp_buf = nullptr; + int64_t pos = 0; + if (OB_ISNULL(buf) || OB_UNLIKELY(size <= 0 || !handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(buf), K(size), K(handle)); + } else if (OB_FAIL(sstable.deserialize(allocator, buf, size, pos))) { + LOG_WARN("fail to deserialize sstable", K(ret), KP(buf), K(size)); + } else if (OB_ISNULL(tmp_buf = static_cast(allocator.alloc(sstable.get_deep_copy_size())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate buffer", K(ret), K(sstable.get_deep_copy_size())); + } else if (OB_FAIL(sstable.deep_copy(tmp_buf, sstable.get_deep_copy_size(), tiny_meta))) { + LOG_WARN("fail to deep copy sstable", K(ret), KP(tmp_buf), K(sstable)); + } else { + ObStorageMetaCacheValue *cache_value = handle.get_cache_value(); + ObStorageMetaValue value(MetaType::SSTABLE, tiny_meta); + if (OB_FAIL(OB_STORE_CACHE.get_storage_meta_cache().put_and_fetch(key, value, cache_value->value_, cache_value->cache_handle_))) { + LOG_WARN("fail to put and fetch value into storage meta cache", K(ret), K(key), K(value), K(cache_value)); + } else { + LOG_DEBUG("succeed to process sstable", K(ret), K(value), KPC(cache_value)); + } + } + if (OB_NOT_NULL(tiny_meta)) { + tiny_meta->~ObIStorageMetaObj(); + } + return ret; +} + +int ObStorageMetaValue::process_table_store( + ObStorageMetaValueHandle &handle, + const ObStorageMetaKey &key, + const char *buf, + const int64_t size, + const ObTablet *tablet) +{ + int ret = OB_SUCCESS; + ObArenaAllocator allocator("ProcMetaVaule"); + ObTabletTableStore table_store; + ObIStorageMetaObj *tiny_meta = nullptr; + char *tmp_buf = nullptr; + int64_t pos = 0; + if (OB_ISNULL(buf) || OB_UNLIKELY(size <= 0 || !handle.is_valid()) || OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(buf), K(size), K(handle)); + } else if (OB_FAIL(table_store.deserialize(allocator, *tablet, buf, size, pos))) { + LOG_WARN("fail to deserialize table store", K(ret), KP(buf), K(size)); + } else if (OB_ISNULL(tmp_buf = static_cast(allocator.alloc(table_store.get_deep_copy_size())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate buffer", K(ret), K(table_store.get_deep_copy_size())); + } else if (OB_FAIL(table_store.deep_copy(tmp_buf, table_store.get_deep_copy_size(), tiny_meta))) { + LOG_WARN("fail to deep copy table store", K(ret), KP(tmp_buf), K(table_store)); + } else { + ObStorageMetaCacheValue *cache_value = handle.get_cache_value(); + ObStorageMetaValue value(MetaType::TABLE_STORE, tiny_meta); + if (OB_FAIL(OB_STORE_CACHE.get_storage_meta_cache().put_and_fetch(key, value, cache_value->value_, cache_value->cache_handle_))) { + LOG_WARN("fail to put and fetch value into storage meta cache", K(ret), K(key), K(value), K(cache_value)); + } + } + if (OB_NOT_NULL(tiny_meta)) { + tiny_meta->~ObIStorageMetaObj(); + } + return ret; +} + +int ObStorageMetaValue::process_autoinc_seq( + ObStorageMetaValueHandle &handle, + const ObStorageMetaKey &key, + const char *buf, + const int64_t size, + const ObTablet *tablet) +{ + UNUSED(tablet); // tablet pointer has no use here + int ret = OB_SUCCESS; + ObArenaAllocator allocator; + share::ObTabletAutoincSeq autoinc_seq; + ObIStorageMetaObj *tiny_meta = nullptr; + char *tmp_buf = nullptr; + int64_t pos = 0; + if (OB_ISNULL(buf) || OB_UNLIKELY(size <= 0 || !handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(buf), K(size), K(handle)); + } else if (OB_FAIL(autoinc_seq.deserialize(allocator, buf, size, pos))) { + LOG_WARN("fail to deserialize auto inc seq", K(ret), KP(buf), K(size)); + } else if (OB_ISNULL(tmp_buf = static_cast(allocator.alloc(autoinc_seq.get_deep_copy_size())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate buffer", K(ret), K(autoinc_seq.get_deep_copy_size())); + } else if (OB_FAIL(autoinc_seq.deep_copy(tmp_buf, autoinc_seq.get_deep_copy_size(), tiny_meta))) { + LOG_WARN("fail to deep copy auto inc seq", K(ret), KP(tmp_buf), K(autoinc_seq)); + } else { + ObStorageMetaCacheValue *cache_value = handle.get_cache_value(); + ObStorageMetaValue value(MetaType::AUTO_INC_SEQ, tiny_meta); + if (OB_FAIL(OB_STORE_CACHE.get_storage_meta_cache().put_and_fetch(key, value, cache_value->value_, cache_value->cache_handle_))) { + LOG_WARN("fail to put and fetch value into storage meta cache", K(ret), K(key), K(value), K(cache_value)); + } + } + if (OB_NOT_NULL(tiny_meta)) { + tiny_meta->~ObIStorageMetaObj(); + } + return ret; +} + +ObStorageMetaValueHandle::ObStorageMetaValueHandle(const ObStorageMetaValueHandle &other) + : cache_value_(nullptr), + allocator_(nullptr) +{ + *this = other; +} +ObStorageMetaValueHandle &ObStorageMetaValueHandle::operator=(const ObStorageMetaValueHandle &other) +{ + if (this != &other) { + reset(); + abort_unless(OB_SUCCESS == set_cache_value(other.cache_value_, other.allocator_)); + } + return *this; +} + +int ObStorageMetaValueHandle::new_value(common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + const int64_t size = sizeof(ObStorageMetaCacheValue); + reset(); + void *buf = nullptr; + allocator_ = &allocator; + if (OB_ISNULL(cache_value_ = OB_NEWx(ObStorageMetaCacheValue, allocator_))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory", K(ret), K(size), KP(allocator_)); + } else { + cache_value_->inc_ref(); + } + return ret; +} + +int ObStorageMetaValueHandle::set_cache_value( + ObStorageMetaCacheValue *value, + common::ObIAllocator *allocator) +{ + int ret = OB_SUCCESS; + if (nullptr == value && nullptr == allocator) { + reset(); + } else if (OB_ISNULL(allocator)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(value), KP(allocator)); + } else if (cache_value_ != value) { + value->inc_ref(); + cache_value_ = value; + allocator_ = allocator; + } else if (OB_UNLIKELY(allocator_ != allocator)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("allocator_ isn't equal to allocator", K(ret), KP(allocator_), KP(allocator)); + } + return ret; +} + +void ObStorageMetaValueHandle::reset() +{ + if (nullptr != cache_value_) { + if (OB_UNLIKELY(nullptr == allocator_)) { + LOG_ERROR_RET(OB_ERR_UNEXPECTED, "allocator is nullptr, and memory can be leak", KP_(cache_value), KP_(allocator)); + } else if (0 == cache_value_->dec_ref()) { + cache_value_->~ObStorageMetaCacheValue(); + allocator_->free(cache_value_); + } + } + cache_value_ = nullptr; + allocator_ = nullptr; +} + +ObStorageMetaHandle::ObStorageMetaHandle() + : phy_addr_(), + io_handle_(), + cache_handle_() +{ +} + +ObStorageMetaHandle::~ObStorageMetaHandle() +{ + reset(); +} + +int ObStorageMetaHandle::get_value(const ObStorageMetaValue *&value) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(wait(GCONF._data_storage_io_timeout / 1000L))) { + LOG_WARN("fail to wait", K(ret), KPC(this)); + } else { + value = cache_handle_.get_cache_value()->value_; + } + return ret; +} + +int ObStorageMetaHandle::get_sstable(blocksstable::ObSSTable *&sstable) +{ + int ret = OB_SUCCESS; + const ObStorageMetaValue *meta_value = nullptr; + sstable = nullptr; + if (OB_FAIL(get_value(meta_value))) { + LOG_WARN("fail to get sstable value", K(ret), K_(phy_addr), K_(io_handle), K_(cache_handle)); + } else if (OB_FAIL(meta_value->get_sstable(sstable))) { + LOG_WARN("fail to get loaded sstable", K(ret), KPC(meta_value)); + } + return ret; +} + +void ObStorageMetaHandle::reset() +{ + phy_addr_.reset(); + io_handle_.reset(); + cache_handle_.reset(); +} + +bool ObStorageMetaHandle::is_valid() const +{ + const bool valid_cache_handle = phy_addr_.is_valid() && cache_handle_.is_valid(); + const bool valid_io_handle = phy_addr_.is_block() && io_handle_.is_valid(); + return valid_cache_handle || valid_io_handle; +} + +int ObStorageMetaHandle::wait(const int64_t timeout_ms) +{ + int ret = OB_SUCCESS; + UNUSED(timeout_ms); + // TODO(zhuixin.gsy) use timeout_ms to wait + if (OB_UNLIKELY(!phy_addr_.is_block())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected meta address", K(ret), K_(phy_addr)); + } else if (OB_FAIL(io_handle_.wait())) { + LOG_WARN("fail to wait io handle", K(ret), K(io_handle_)); + } + return ret; +} + +int ObStorageMetaCache::init(const char *cache_name, const int64_t priority) +{ + int ret = OB_SUCCESS; + const int64_t mem_limit = 4 * 1024 * 1024 * 1024LL; + if (OB_FAIL((common::ObKVCache::init(cache_name, priority)))) { + LOG_WARN("fail to init storage meta kv cache", K(ret), K(priority)); + } else if (OB_FAIL(allocator_.init(mem_limit, OB_MALLOC_BIG_BLOCK_SIZE, OB_MALLOC_BIG_BLOCK_SIZE))) { + LOG_WARN("fail to init io allocator", K(ret)); + } else { + allocator_.set_label("StorMetaCacheIO"); + } + return ret; +} + +void ObStorageMetaCache::destory() +{ + common::ObKVCache::destroy(); +} + +ObStorageMetaCache::ObStorageMetaIOCallback::ObStorageMetaIOCallback() + : meta_type_(ObStorageMetaValue::MetaType::MAX), + offset_(0), + buf_size_(0), + data_buf_(nullptr), + handle_(), + allocator_(nullptr), + key_(), + tablet_(nullptr), + arena_allocator_(nullptr) +{ + static_assert(sizeof(*this) <= CALLBACK_BUF_SIZE, "IOCallback buf size not enough"); +} + +ObStorageMetaCache::ObStorageMetaIOCallback::ObStorageMetaIOCallback( + const ObStorageMetaValue::MetaType type, + const ObStorageMetaKey &key, + ObStorageMetaValueHandle &handle, + common::ObIAllocator *allocator, + const ObTablet *tablet, + common::ObSafeArenaAllocator *arena_allocator) + : meta_type_(type), + offset_(key.get_meta_addr().offset()), + buf_size_(key.get_meta_addr().size()), + data_buf_(nullptr), + handle_(handle), + allocator_(allocator), + key_(key), + tablet_(tablet), + arena_allocator_(arena_allocator) +{ + static_assert(sizeof(*this) <= CALLBACK_BUF_SIZE, "IOCallback buf size not enough"); +} + +ObStorageMetaCache::ObStorageMetaIOCallback::~ObStorageMetaIOCallback() +{ + if (nullptr != allocator_ && NULL != data_buf_) { + allocator_->free(data_buf_); + } + meta_type_ = ObStorageMetaValue::MetaType::MAX; + offset_ = 0; + buf_size_ = 0; + data_buf_ = nullptr; + handle_.reset(); + allocator_ = nullptr; +} + +int ObStorageMetaCache::ObStorageMetaIOCallback::inner_deep_copy( + char *buf, const + int64_t buf_len, + ObIOCallback *&callback) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(nullptr == buf || buf_len < size())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(buf), K(buf_len)); + } else if (OB_UNLIKELY(!handle_.is_valid()) || OB_ISNULL(allocator_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage meta io callback is not valid", K(ret), K_(handle), KP_(allocator)); + } else { + ObStorageMetaIOCallback *pcallback = new (buf) ObStorageMetaIOCallback(); + *pcallback = *this; + callback = pcallback; + } + return ret; +} + +int ObStorageMetaCache::ObStorageMetaIOCallback::inner_process(const char *data_buffer, const int64_t size) +{ + // TODO: callback need to deal with block-crossed shared blocks, + // in which scene we only store the first blocks' addr + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid storage meta cache callback", K(ret), K_(handle)); + } else if (OB_UNLIKELY(size <= 0 || data_buffer == nullptr)) { + ret = OB_INVALID_DATA; + LOG_WARN("invalid data buffer size", K(ret), K(size), KP(data_buffer)); + } else if (OB_UNLIKELY(NULL == (data_buf_ = (char*) (allocator_->alloc(size))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("Fail to allocate memory, ", K(ret), K(size)); + } else { + MEMCPY(data_buf_, data_buffer, size); + char *buf = nullptr; + int64_t buf_len = 0; + if (OB_FAIL(ObSharedBlockReadHandle::parse_data(data_buffer, size, buf, buf_len))) { + LOG_WARN("fail to parse data by shared block handle", K(ret), KP(data_buffer)); + } else if (OB_UNLIKELY(nullptr != arena_allocator_)) { // bypass cache processor + if (OB_FAIL(ObStorageMetaValue::bypass_processor[meta_type_](meta_type_, *arena_allocator_, + handle_, buf, buf_len))) { + LOG_WARN("fail to process io buf", K(ret), K(meta_type_), KP(buf), K(buf_len)); + } + } else if (OB_FAIL(ObStorageMetaValue::processor[meta_type_](handle_, key_, buf, buf_len, tablet_))) { + LOG_WARN("fail to process io buf", K(ret), K(meta_type_), KP(buf), K(buf_len)); + } + } + + if (OB_FAIL(ret) && NULL != allocator_ && NULL != data_buf_) { + allocator_->free(data_buf_); + data_buf_ = NULL; + } + return ret; +} + +int64_t ObStorageMetaCache::ObStorageMetaIOCallback::size() const +{ + return sizeof(*this); +} + +const char *ObStorageMetaCache::ObStorageMetaIOCallback::get_data() +{ + return data_buf_; +} + +bool ObStorageMetaCache::ObStorageMetaIOCallback::is_valid() const +{ + return key_.is_valid() + && handle_.is_valid() + && nullptr != allocator_ + && offset_ >= 0 + && buf_size_ > 0; +} + +int ObStorageMetaCache::get_meta( + const ObStorageMetaValue::MetaType type, + const ObStorageMetaKey &key, + ObStorageMetaHandle &meta_handle, + const ObTablet *tablet) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!key.is_valid() || type >= ObStorageMetaValue::MAX)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(key), K(type)); + } else if (OB_FAIL(meta_handle.cache_handle_.new_value(allocator_))) { + LOG_WARN("fail to new cache handle value", K(ret)); + } else if (OB_FAIL(get(key, meta_handle.cache_handle_.get_cache_value()->value_, + meta_handle.cache_handle_.get_cache_value()->cache_handle_))) { + if (OB_UNLIKELY(OB_ENTRY_NOT_EXIST != ret)) { + LOG_WARN("fail to get storage meta from cache", K(ret), K(type), K(key)); + } else if (OB_FAIL(prefetch(type, key, meta_handle, tablet))) { + LOG_WARN("fail to prefetch", K(ret), K(type), K(key)); + } else { + EVENT_INC(ObStatEventIds::STORAGE_META_CACHE_MISS); + } + } else { + meta_handle.phy_addr_ = key.get_meta_addr(); + EVENT_INC(ObStatEventIds::STORAGE_META_CACHE_HIT); + } + return ret; +} + +int ObStorageMetaCache::bypass_get_meta( + const ObStorageMetaValue::MetaType type, + const ObStorageMetaKey &key, + common::ObSafeArenaAllocator &allocator, + ObStorageMetaHandle &meta_handle) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(type >= ObStorageMetaValue::MAX)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(type)); + } else if (OB_UNLIKELY(ObStorageMetaValue::TABLE_STORE == type)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("Don't supported for table store", K(ret), K(type), K(key)); + } else if (OB_FAIL(get_meta_and_bypass_cache(type, key, allocator, meta_handle))) { + LOG_WARN("fail to get meta and bypass cache", K(ret), K(type), K(key)); + } + return ret; +} + +int ObStorageMetaCache::batch_get_meta_and_bypass_cache( + const ObStorageMetaValue::MetaType type, + const common::ObIArray &keys, + common::ObSafeArenaAllocator &allocator, + common::ObIArray &meta_handles) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(type >= ObStorageMetaValue::MAX + || keys.count() == 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(type), K(keys)); + } else if (OB_UNLIKELY(ObStorageMetaValue::TABLE_STORE == type)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("Don't supported for table store", K(ret), K(type), K(keys)); + } else { + // TODO: @zhuixin implement batch read in shared block reader. + for (int64_t i = 0; OB_SUCC(ret) && i < keys.count(); ++i) { + const ObStorageMetaKey &key = keys.at(i); + ObStorageMetaHandle meta_handle; + if (OB_FAIL(get_meta_and_bypass_cache(type, key, allocator, meta_handle))) { + LOG_WARN("fail to do get meta", K(ret), K(type), K(key), K(meta_handle)); + } else if (OB_FAIL(meta_handles.push_back(meta_handle))) { + LOG_WARN("fail to push back meta handle", K(ret), K(meta_handle)); + } + } + if (OB_SUCC(ret) && OB_UNLIKELY(keys.count() != meta_handles.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, the number of keys and meta handles is not equal", K(ret), K(type), + K(keys), K(meta_handles)); + } + } + return ret; +} + +int ObStorageMetaCache::prefetch( + const ObStorageMetaValue::MetaType type, + const ObStorageMetaKey &key, + ObStorageMetaHandle &meta_handle, + const ObTablet *tablet) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!key.is_valid() || type >= ObStorageMetaValue::MAX)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(key), K(type)); + } else { + ObStorageMetaIOCallback callback(type, + key, + meta_handle.cache_handle_, + &allocator_, + tablet); + if (OB_FAIL(read_io(key.get_meta_addr(), callback, meta_handle))) { + LOG_WARN("fail to read storage meta from io", K(ret), K(key), K(meta_handle)); + } + } + return ret; +} + +int ObStorageMetaCache::get_meta_and_bypass_cache( + const ObStorageMetaValue::MetaType type, + const ObStorageMetaKey &key, + common::ObSafeArenaAllocator &allocator, + ObStorageMetaHandle &handle) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!key.is_valid() || type >= ObStorageMetaValue::MAX)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(key), K(type)); + } else if (OB_FAIL(handle.cache_handle_.new_value(allocator_))) { + LOG_WARN("fail to new cache handle value", K(ret)); + } else { + ObStorageMetaIOCallback callback(type, + key, + handle.cache_handle_, + &allocator_, + nullptr/*tablet*/, + &allocator/*bypass_cache*/); + if (OB_FAIL(read_io(key.get_meta_addr(), callback, handle))) { + LOG_WARN("fail to read storage meta from io", K(ret), K(key), K(handle)); + } + } + return ret; +} + +int ObStorageMetaCache::read_io( + const ObMetaDiskAddr &meta_addr, + ObStorageMetaIOCallback &callback, + ObStorageMetaHandle &handle) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!meta_addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(meta_addr), K(callback)); + } else if (OB_UNLIKELY(!meta_addr.is_block())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("the meta disk address type hasn't be supported", K(ret), K(meta_addr), K(callback)); + } else { + ObSharedBlockReadInfo read_info; + read_info.addr_ = meta_addr; + read_info.io_callback_ = &callback; + read_info.io_desc_.set_mode(ObIOMode::READ); + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_DATA_READ); + handle.phy_addr_ = meta_addr; + if (OB_FAIL(ObSharedBlockReaderWriter::async_read(read_info, handle.io_handle_))) { + LOG_WARN("fail to async read", K(ret), K(read_info)); + } + } + return ret; +} + +ObStorageMetaCache::ObStorageMetaCache() + : allocator_() +{ +} + +ObStorageMetaCache::~ObStorageMetaCache() +{ +} + +} // end namespace storage +} // end namespace oceanbase diff --git a/src/storage/meta_mem/ob_storage_meta_cache.h b/src/storage/meta_mem/ob_storage_meta_cache.h new file mode 100644 index 000000000..345fd28a6 --- /dev/null +++ b/src/storage/meta_mem/ob_storage_meta_cache.h @@ -0,0 +1,321 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_STORAGE_META_CACHE_H_ +#define OCEANBASE_STORAGE_OB_STORAGE_META_CACHE_H_ + +#include "share/cache/ob_kv_storecache.h" +#include "storage/meta_mem/ob_meta_obj_struct.h" +#include "storage/blockstore/ob_shared_block_reader_writer.h" +#include "storage/access/ob_table_read_info.h" + +namespace oceanbase +{ + +namespace blocksstable +{ +class ObSSTable; +} + +namespace share +{ +class ObTabletAutoincSeq; +} + +namespace storage +{ + +class ObTablet; +class ObTabletTableStore; +class ObStorageMetaCache; +class ObStorageMetaValueHandle; + +class ObStorageMetaKey final : public common::ObIKVCacheKey +{ +public: + ObStorageMetaKey(); + ObStorageMetaKey( + const uint64_t tenant_id, + const ObMetaDiskAddr &phy_addr); + ObStorageMetaKey( + const uint64_t tenant_id, + const blocksstable::MacroBlockId &block_id, + const int64_t offset, + const int64_t size); + virtual ~ObStorageMetaKey(); + virtual bool operator ==(const ObIKVCacheKey &other) const override; + virtual uint64_t get_tenant_id() const override; + virtual uint64_t hash() const override; + virtual int64_t size() const override; + virtual int deep_copy(char *buf, const int64_t buf_len, ObIKVCacheKey *&key) const override; + bool is_valid() const; + const ObMetaDiskAddr &get_meta_addr() const; + TO_STRING_KV(K_(tenant_id), K_(phy_addr)); +private: + uint64_t tenant_id_; + ObMetaDiskAddr phy_addr_; +}; + +class ObStorageMetaValue final : public common::ObIKVCacheValue +{ +public: + enum MetaType : uint16_t + { + SSTABLE = 0, + TABLE_STORE = 1, + AUTO_INC_SEQ = 2, + MAX = 3, + }; +public: + ObStorageMetaValue(); + ObStorageMetaValue(const MetaType type, ObIStorageMetaObj *buf); + virtual ~ObStorageMetaValue(); + virtual int64_t size() const override; + virtual int deep_copy(char *buf, const int64_t buf_len, ObIKVCacheValue *&value) const override; + int get_sstable(const blocksstable::ObSSTable *&sstable) const; + int get_sstable(blocksstable::ObSSTable *&sstable) const; + int get_table_store(const ObTabletTableStore *&store) const; + int get_autoinc_seq(const share::ObTabletAutoincSeq *&seq) const; + bool is_valid() const; + void reset() + { + type_ = MetaType::MAX; + if (OB_LIKELY(nullptr != obj_)) { + obj_->~ObIStorageMetaObj(); + } + obj_ = nullptr; + } + static int process_sstable( + ObStorageMetaValueHandle &handle, + const ObStorageMetaKey &key, + const char *buf, + const int64_t size, + const ObTablet *tablet); + static int process_table_store( + ObStorageMetaValueHandle &handle, + const ObStorageMetaKey &key, + const char *buf, + const int64_t size, + const ObTablet *tablet); + static int process_autoinc_seq( + ObStorageMetaValueHandle &handle, + const ObStorageMetaKey &key, + const char *buf, + const int64_t size, + const ObTablet *tablet); + TO_STRING_KV(K_(type), KP_(obj)); +public: + typedef int (*StorageMetaProcessor)( + ObStorageMetaValueHandle &, + const ObStorageMetaKey &, + const char*, + const int64_t, + const ObTablet *); + typedef int (*StorageMetaBypassProcessor)( + const MetaType, + common::ObSafeArenaAllocator &, + ObStorageMetaValueHandle &, + const char *, + const int64_t); + static StorageMetaProcessor processor[MetaType::MAX]; + static StorageMetaBypassProcessor bypass_processor[MetaType::MAX]; +private: + template + static int bypass_process_storage_meta( + const MetaType type, + common::ObSafeArenaAllocator &allocator, + ObStorageMetaValueHandle &handle, + const char *buf, + const int64_t size); +private: + MetaType type_; + ObIStorageMetaObj *obj_; +}; + +class ObStorageMetaCacheValue final +{ +public: + ObStorageMetaCacheValue() : ref_cnt_(0), value_(nullptr), cache_handle_() {} + ~ObStorageMetaCacheValue() = default; + void inc_ref() { ATOMIC_INC(&ref_cnt_); } + int64_t dec_ref() { return ATOMIC_SAF(&ref_cnt_, 1); } + TO_STRING_KV(K_(ref_cnt), KPC_(value), K_(cache_handle)); +public: + int64_t ref_cnt_; + const ObStorageMetaValue *value_; + common::ObKVCacheHandle cache_handle_; +}; + +class ObStorageMetaValueHandle final +{ +public: + ObStorageMetaValueHandle() : cache_value_(nullptr), allocator_(nullptr) {} + ~ObStorageMetaValueHandle() { reset(); } + ObStorageMetaValueHandle(const ObStorageMetaValueHandle &other); + ObStorageMetaValueHandle &operator=(const ObStorageMetaValueHandle &other); + bool is_valid() const + { + return nullptr != cache_value_ && nullptr != allocator_; + } + int new_value(common::ObIAllocator &allocator); + void reset(); + OB_INLINE ObStorageMetaCacheValue *get_cache_value() { return cache_value_; } + OB_INLINE ObStorageMetaCacheValue *get_cache_value() const { return cache_value_; } + TO_STRING_KV(KPC_(cache_value), KP_(allocator)); +private: + int set_cache_value(ObStorageMetaCacheValue *value, common::ObIAllocator *allocator); +private: + ObStorageMetaCacheValue *cache_value_; + common::ObIAllocator *allocator_; +}; + +class ObStorageMetaHandle final +{ +public: + ObStorageMetaHandle(); + ~ObStorageMetaHandle(); + void reset(); + bool is_valid() const; + const ObMetaDiskAddr &get_phy_addr() const + { + return phy_addr_; + } + int get_value(const ObStorageMetaValue *&value); + int get_sstable(blocksstable::ObSSTable *&sstable); + TO_STRING_KV(K_(phy_addr), K_(io_handle), K_(cache_handle)); +private: + int wait(const int64_t timeout_ms); +private: + friend class ObStorageMetaCache; + ObMetaDiskAddr phy_addr_; + ObSharedBlockReadHandle io_handle_; + ObStorageMetaValueHandle cache_handle_; +}; + +class ObStorageMetaCache final + : public common::ObKVCache +{ +public: + typedef common::ObKVCache BaseSecondaryMetaCache; +public: + ObStorageMetaCache(); + virtual ~ObStorageMetaCache(); + int init(const char *cache_name, const int64_t priority); + void destory(); + int get_meta( + const ObStorageMetaValue::MetaType type, + const ObStorageMetaKey &key, + ObStorageMetaHandle &meta_handle, + const ObTablet *tablet); + int bypass_get_meta( + const ObStorageMetaValue::MetaType type, + const ObStorageMetaKey &key, + common::ObSafeArenaAllocator &allocator, + ObStorageMetaHandle &meta_handle); + int batch_get_meta_and_bypass_cache( + const ObStorageMetaValue::MetaType type, + const common::ObIArray &keys, + common::ObSafeArenaAllocator &allocator, + common::ObIArray &meta_handles); +private: + class ObStorageMetaIOCallback : public common::ObIOCallback + { + public: + ObStorageMetaIOCallback(); + ObStorageMetaIOCallback( + const ObStorageMetaValue::MetaType type, + const ObStorageMetaKey &key, + ObStorageMetaValueHandle &handle, + common::ObIAllocator *allocator, + const ObTablet *tablet, + common::ObSafeArenaAllocator *arena_allocator = nullptr); + virtual ~ObStorageMetaIOCallback(); + virtual int inner_deep_copy( + char *buf, const + int64_t buf_len, + ObIOCallback *&callback) const override; + virtual int inner_process(const char *data_buffer, const int64_t size) override; + virtual int64_t size() const override; + virtual const char *get_data() override; + bool is_valid() const; + TO_STRING_KV(K_(offset), K_(buf_size), KP_(data_buf), K_(key), KP_(tablet), KP_(arena_allocator)); + private: + ObStorageMetaValue::MetaType meta_type_; + int64_t offset_; // offset in block. + int64_t buf_size_; // read size in block. + char *data_buf_; // actual data buffer + ObStorageMetaValueHandle handle_; + common::ObIAllocator *allocator_; + ObStorageMetaKey key_; + const ObTablet *tablet_; + common::ObSafeArenaAllocator *arena_allocator_; + }; +private: + int prefetch( + const ObStorageMetaValue::MetaType type, + const ObStorageMetaKey &key, + ObStorageMetaHandle &meta_handle, + const ObTablet *tablet); + int get_meta_and_bypass_cache( + const ObStorageMetaValue::MetaType type, + const ObStorageMetaKey &key, + common::ObSafeArenaAllocator &allocator, + ObStorageMetaHandle &handle); + int read_io( + const ObMetaDiskAddr &meta_addr, + ObStorageMetaIOCallback &callback, + ObStorageMetaHandle &handle); +private: + common::ObConcurrentFIFOAllocator allocator_; + DISALLOW_COPY_AND_ASSIGN(ObStorageMetaCache); +}; + +template +int ObStorageMetaValue::bypass_process_storage_meta( + const MetaType type, + common::ObSafeArenaAllocator &allocator, + ObStorageMetaValueHandle &handle, + const char *buf, + const int64_t size) +{ + int ret = OB_SUCCESS; + ObArenaAllocator tmp_allocator("ProcMetaVaule"); + int64_t pos = 0; + T t; + char *buff = nullptr; + if (OB_ISNULL(buf) || OB_UNLIKELY(size <= 0 || !handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid arguments", K(ret), KP(buf), K(size), K(handle)); + } else if (OB_FAIL(t.deserialize(tmp_allocator, buf, size, pos))) { + STORAGE_LOG(WARN, "fail to deserialize ", K(ret), KP(buf), K(size)); + } else { + ObIStorageMetaObj *tiny_meta = nullptr; + const int64_t buff_pos = sizeof(ObStorageMetaValue); + const int64_t buff_size = sizeof(ObStorageMetaValue) + t.get_deep_copy_size(); + if (OB_ISNULL(buff = static_cast(allocator.alloc(buff_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "fail to allocate memory", K(ret), K(buff_size)); + } else { + if (OB_FAIL(t.deep_copy(buff + buff_pos, t.get_deep_copy_size(), tiny_meta))) { + STORAGE_LOG(WARN, "fail to deserialize sstable", K(ret), KP(buf), K(size)); + } else { + handle.get_cache_value()->value_ = new (buff) ObStorageMetaValue(type, tiny_meta); + } + } + } + return ret; +} + +} // end storage +} // end oceanbase + +#endif /* OCEANBASE_STORAGE_OB_STORAGE_META_CACHE_H_ */ diff --git a/src/storage/meta_mem/ob_tablet_handle.cpp b/src/storage/meta_mem/ob_tablet_handle.cpp index bebf7f088..0d4d460fd 100644 --- a/src/storage/meta_mem/ob_tablet_handle.cpp +++ b/src/storage/meta_mem/ob_tablet_handle.cpp @@ -14,51 +14,88 @@ #include "storage/meta_mem/ob_tablet_handle.h" #include "storage/tablet/ob_tablet.h" - +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" namespace oceanbase { namespace storage { ObTabletHandle::ObTabletHandle() : Base(), - wash_priority_(WashTabletPriority::WTP_MAX) + wash_priority_(WashTabletPriority::WTP_MAX), + allow_copy_and_assign_(true) { INIT_OBJ_LEAK_DEBUG_NODE(node_, this, share::LEAK_CHECK_OBJ_TABLET_HANDLE, MTL_ID()); } -ObTabletHandle::ObTabletHandle(const Base &other) +ObTabletHandle::ObTabletHandle( + const Base &other, + const WashTabletPriority priority) : Base(other), - wash_priority_(WashTabletPriority::WTP_MAX) + wash_priority_(priority), + allow_copy_and_assign_(true) { } ObTabletHandle::ObTabletHandle(const ObTabletHandle &other) : Base(), - wash_priority_(WashTabletPriority::WTP_MAX) + wash_priority_(WashTabletPriority::WTP_MAX), + allow_copy_and_assign_(true) { INIT_OBJ_LEAK_DEBUG_NODE(node_, this, share::LEAK_CHECK_OBJ_TABLET_HANDLE, MTL_ID()); *this = other; } + ObTabletHandle::~ObTabletHandle() { + reset(); } + ObTabletHandle &ObTabletHandle::operator=(const ObTabletHandle &other) { if (this != &other) { + abort_unless(other.allow_copy_and_assign_); reset(); Base::operator=(other); wash_priority_ = other.wash_priority_; + allow_copy_and_assign_ = other.allow_copy_and_assign_; } return *this; } void ObTabletHandle::reset() { - if (OB_NOT_NULL(obj_)) { + if (nullptr != obj_) { + int ret = OB_SUCCESS; obj_->update_wash_score(calc_wash_score(wash_priority_)); + if (OB_UNLIKELY(!is_valid())) { + STORAGE_LOG(ERROR, "object pool and allocator is nullptr", K_(obj), K_(obj_pool), K_(allocator)); + ob_abort(); + } else { + const int64_t ref_cnt = obj_->dec_ref(); + if (OB_UNLIKELY(ref_cnt < 0)) { + STORAGE_LOG(ERROR, "obj ref cnt may be leaked", K(ref_cnt), KPC(this)); + } else if (0 == ref_cnt) { + if (!allow_copy_and_assign_) { + // all in memory, no need to dec macro ref + if (OB_NOT_NULL(obj_pool_)) { + ob_usleep(1000 * 1000); + ob_abort(); + } + obj_->dec_macro_ref_cnt(); + obj_->~ObTablet(); + allocator_->free(obj_); + } else if (OB_FAIL(t3m_->gc_tablet(obj_))) { + STORAGE_LOG(ERROR, "fail to gc tablet", K(ret), KPC_(obj), K_(obj_pool), K_(allocator)); + } + } + obj_ = nullptr; + } } wash_priority_ = WashTabletPriority::WTP_MAX; - Base::reset(); + allow_copy_and_assign_ = true; + obj_pool_ = nullptr; + allocator_ = nullptr; + t3m_ = nullptr; } int64_t ObTabletHandle::calc_wash_score(const WashTabletPriority priority) const @@ -84,10 +121,93 @@ int64_t ObTabletHandle::to_string(char *buf, const int64_t buf_len) const J_OBJ_START(); J_KV(KP_(obj), KP_(obj_pool), - K_(wash_priority)); + KP_(allocator), + K_(wash_priority), + K_(allow_copy_and_assign)); J_OBJ_END(); return pos; } +void ObTabletTableIterator::operator=(const ObTabletTableIterator& other) +{ + if (this != &other) { + if (other.tablet_handle_.is_valid()) { + tablet_handle_ = other.tablet_handle_; + } else if (tablet_handle_.is_valid()) { + tablet_handle_.reset(); + } + if (other.table_store_iter_.is_valid()) { + table_store_iter_ = other.table_store_iter_; + } else if (table_store_iter_.is_valid()) { + table_store_iter_.reset(); + } + if (OB_UNLIKELY(nullptr != other.transfer_src_handle_)) { + if (nullptr == transfer_src_handle_) { + void *tablet_hdl_buf = ob_malloc(sizeof(ObTabletHandle), ObMemAttr(MTL_ID(), "TransferMetaH")); + transfer_src_handle_ = new (tablet_hdl_buf) ObTabletHandle(); + } + *transfer_src_handle_ = *(other.transfer_src_handle_); + } + } +} + +ObTableStoreIterator *ObTabletTableIterator::table_iter() +{ + return &table_store_iter_; +} + +int ObTabletTableIterator::set_tablet_handle(const ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(tablet_handle_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet table iterator already has a valid tablet handle", K(ret)); + } else { + tablet_handle_ = tablet_handle; + } + return ret; +} + +int ObTabletTableIterator::set_transfer_src_tablet_handle(const ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + if (nullptr == transfer_src_handle_) { + void *tablet_hdl_buf = ob_malloc(sizeof(ObTabletHandle), ObMemAttr(MTL_ID(), "TransferTblH")); + if (OB_ISNULL(tablet_hdl_buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocator memory for handles"); + } else { + transfer_src_handle_ = new (tablet_hdl_buf) ObTabletHandle(); + } + } + if (OB_SUCC(ret)) { + *transfer_src_handle_ = tablet_handle; + } + return ret; +} + +int ObTabletTableIterator::refresh_read_tables_from_tablet( + const int64_t snapshot_version, + const bool allow_no_ready_read, + const bool major_sstable_only) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!tablet_handle_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("try to refresh tables in tablet table iter with invalid tablet handle", K(ret)); + } else if (major_sstable_only) { + if (OB_FAIL(tablet_handle_.get_obj()->get_read_major_sstable(snapshot_version, *this))) { + LOG_WARN("failed to get read major sstable from tablet", + K(ret), K(snapshot_version), K_(tablet_handle)); + } + } else { + if (OB_FAIL(tablet_handle_.get_obj()->get_read_tables( + snapshot_version, *this, allow_no_ready_read))) { + LOG_WARN("failed to get read tables from tablet", K(ret), K_(tablet_handle)); + } + } + return ret; +} + } // end namespace storage } // end namespace oceanbase diff --git a/src/storage/meta_mem/ob_tablet_handle.h b/src/storage/meta_mem/ob_tablet_handle.h index d3a87acd6..2c5663d13 100644 --- a/src/storage/meta_mem/ob_tablet_handle.h +++ b/src/storage/meta_mem/ob_tablet_handle.h @@ -16,6 +16,7 @@ #include "storage/meta_mem/ob_meta_obj_struct.h" #include "share/leak_checker/obj_leak_checker.h" #include "storage/tablet/ob_table_store_util.h" +#include "storage/tablet/ob_tablet_table_store_iterator.h" namespace oceanbase { @@ -35,37 +36,71 @@ private: typedef ObMetaObjGuard Base; public: ObTabletHandle(); - ObTabletHandle(const Base &other); + ObTabletHandle( + const Base &other, + const WashTabletPriority priority); ObTabletHandle(const ObTabletHandle &other); virtual ~ObTabletHandle(); ObTabletHandle &operator = (const ObTabletHandle &other); virtual void reset() override; virtual bool need_hold_time_check() const override { return true; } - void set_wash_priority(WashTabletPriority priority) { wash_priority_ = priority; } + void set_wash_priority(const WashTabletPriority priority) { wash_priority_ = priority; } + common::ObArenaAllocator *get_allocator() { return static_cast(allocator_); } + void disallow_copy_and_assign() { allow_copy_and_assign_ = false; } + bool is_tmp_tablet() const { return !allow_copy_and_assign_; } + char *get_buf() { return reinterpret_cast(obj_); } + int64_t get_buf_len() const { return get_buf_header().buf_len_; } DECLARE_VIRTUAL_TO_STRING; private: int64_t calc_wash_score(const WashTabletPriority priority) const; + ObMetaObjBufferHeader &get_buf_header() const + { + return ObMetaObjBufferHelper::get_buffer_header(reinterpret_cast(obj_)); + } private: WashTabletPriority wash_priority_; + bool allow_copy_and_assign_; DEFINE_OBJ_LEAK_DEBUG_NODE(node_); }; class ObTabletTableIterator final { + friend class ObTablet; + friend class ObLSTabletService; public: - ObTabletTableIterator() = default; + ObTabletTableIterator() : tablet_handle_(), table_store_iter_(), transfer_src_handle_(nullptr) {} + explicit ObTabletTableIterator(const bool is_reverse) : tablet_handle_(), table_store_iter_(is_reverse), transfer_src_handle_(nullptr) {} + + ObTabletTableIterator(const ObTabletTableIterator& other) { *this = other; } ; + void operator=(const ObTabletTableIterator& other); ~ObTabletTableIterator() { reset(); } void reset() { + table_store_iter_.reset(); tablet_handle_.reset(); - table_iter_.reset(); + if (nullptr != transfer_src_handle_) { + transfer_src_handle_->~ObTabletHandle(); + ob_free(transfer_src_handle_); + transfer_src_handle_ = nullptr; + } } - // TODO: @yht146439 fix me. return tablet_handle_.is_valid() && table_iter.is_valid(); - bool is_valid() const { return tablet_handle_.is_valid() || table_iter_.is_valid(); } - TO_STRING_KV(K_(tablet_handle), K_(table_iter)); -public: + bool is_valid() const { return tablet_handle_.is_valid() || table_store_iter_.is_valid(); } + ObTableStoreIterator *table_iter(); + const ObTableStoreIterator *table_iter() const; + const ObTablet *get_tablet() const { return tablet_handle_.get_obj(); } + ObTablet *get_tablet() { return tablet_handle_.get_obj(); } + const ObTabletHandle &get_tablet_handle() { return tablet_handle_; } + int set_tablet_handle(const ObTabletHandle &tablet_handle); + int set_transfer_src_tablet_handle(const ObTabletHandle &tablet_handle); + int refresh_read_tables_from_tablet( + const int64_t snapshot_version, + const bool allow_no_ready_read, + const bool major_sstable_only = false); + TO_STRING_KV(K_(tablet_handle), K_(transfer_src_handle), K_(table_store_iter)); +private: ObTabletHandle tablet_handle_; - ObTableStoreIterator table_iter_; + ObTableStoreIterator table_store_iter_; + ObTabletHandle *transfer_src_handle_; }; struct ObGetTableParam diff --git a/src/storage/meta_mem/ob_tablet_map_key.cpp b/src/storage/meta_mem/ob_tablet_map_key.cpp index 113e54ad3..85e7eb8e4 100644 --- a/src/storage/meta_mem/ob_tablet_map_key.cpp +++ b/src/storage/meta_mem/ob_tablet_map_key.cpp @@ -51,8 +51,8 @@ int ObTabletMapKey::hash(uint64_t &hash_val) const uint64_t ObTabletMapKey::hash() const { uint64_t hash_val = 0; - hash_val = murmurhash(&ls_id_, sizeof(ls_id_), hash_val); - hash_val = murmurhash(&tablet_id_, sizeof(tablet_id_), hash_val); + hash_val = common::murmurhash(&ls_id_, sizeof(ls_id_), hash_val); + hash_val = common::murmurhash(&tablet_id_, sizeof(tablet_id_), hash_val); return hash_val; } } // namespace storage diff --git a/src/storage/meta_mem/ob_tablet_pointer.cpp b/src/storage/meta_mem/ob_tablet_pointer.cpp index 870e04799..ab301c372 100644 --- a/src/storage/meta_mem/ob_tablet_pointer.cpp +++ b/src/storage/meta_mem/ob_tablet_pointer.cpp @@ -10,18 +10,23 @@ * See the Mulan PubL v2 for more details. */ -#define USING_LOG_PREFIX STORAGE - -#include "storage/meta_mem/ob_tablet_pointer.h" - +#include "lib/ob_errno.h" +#include "lib/atomic/ob_atomic.h" #include "lib/container/ob_se_array.h" #include "lib/hash/ob_cuckoo_hashmap.h" #include "lib/stat/ob_latch_define.h" +#include "common/ob_tablet_id.h" +#include "share/ob_ls_id.h" #include "storage/ls/ob_ls.h" #include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_persister.h" #include "storage/tablet/ob_tablet_common.h" #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/meta_mem/ob_tablet_pointer.h" #include "storage/ddl/ob_tablet_ddl_kv_mgr.h" +#include "storage/tx_storage/ob_ls_service.h" + +#define USING_LOG_PREFIX STORAGE using namespace oceanbase::common; using namespace oceanbase::common::hash; @@ -37,11 +42,10 @@ ObTabletPointer::ObTabletPointer() ddl_kv_mgr_handle_(), memtable_mgr_handle_(), ddl_info_(), - tx_data_(), - redefined_schema_version_(OB_INVALID_VERSION), - cond_(), - msd_lock_(), - ddl_kv_mgr_lock_() + initial_state_(true), + mds_table_handler_(), + ddl_kv_mgr_lock_(), + old_version_chain_(nullptr) { } @@ -52,11 +56,10 @@ ObTabletPointer::ObTabletPointer( ls_handle_(ls_handle), 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_() + initial_state_(true), + mds_table_handler_(), + ddl_kv_mgr_lock_(), + old_version_chain_(nullptr) { } @@ -69,14 +72,15 @@ void ObTabletPointer::reset() { ls_handle_.reset(); { - ObMutexGuard guard(ddl_kv_mgr_lock_); + ObByteLockGuard guard(ddl_kv_mgr_lock_); ddl_kv_mgr_handle_.reset(); } + mds_table_handler_.reset(); memtable_mgr_handle_.reset(); ddl_info_.reset(); - tx_data_.reset(); - redefined_schema_version_ = OB_INVALID_VERSION; - cond_.destroy(); + initial_state_ = true; + ATOMIC_STORE(&initial_state_, true); + old_version_chain_ = nullptr; ObMetaPointer::reset(); } @@ -103,53 +107,61 @@ int ObTabletPointer::set_attr_for_obj(ObTablet *tablet) return ret; } -int ObTabletPointer::do_post_work_for_load() +int ObTabletPointer::dump_meta_obj(ObMetaObjGuard &guard, void *&free_obj) { int ret = OB_SUCCESS; - if (OB_FAIL(obj_.ptr_->deserialize_post_work())) { - LOG_WARN("fail to deserialize post work", K(ret), K(obj_)); - } else if (OB_FAIL(obj_.ptr_->dec_macro_disk_ref())) { - LOG_WARN("fail to dec macro disk ref", K(ret), K(obj_)); - } - return ret; -} - -int ObTabletPointer::dump_meta_obj(bool &is_washed) -{ - int ret = OB_SUCCESS; - is_washed = false; - ObTablet *tablet = nullptr; - + ObMetaObj meta_obj; if (OB_ISNULL(obj_.ptr_)) { LOG_INFO("tablet may be washed", KPC(obj_.ptr_)); - } else if (FALSE_IT(tablet = obj_.ptr_)) { - } else if (OB_UNLIKELY(tablet->get_ref() > 1)) { - LOG_INFO("tablet may be attached again, continue", KPC(tablet)); - } else if (OB_UNLIKELY(tablet->get_ref() < 1)) { + } else if (OB_UNLIKELY(obj_.ptr_->get_ref() > 1)) { + LOG_INFO("tablet may be attached again, continue", KPC(obj_.ptr_)); + } else if (OB_UNLIKELY(obj_.ptr_->get_ref() < 1)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, tablet ref is less than 1", K(ret), KPC(tablet)); + LOG_WARN("unexpected error, tablet ref is less than 1", K(ret), KPC(obj_.ptr_)); + } else if (OB_UNLIKELY(phy_addr_.is_file())) { + LOG_INFO("obj is empty shell, don't be wash", K(ret), K(phy_addr_)); + } else if (OB_ISNULL(obj_.pool_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("obj is not allocated from pool", K(ret), K(*this)); } else if (OB_UNLIKELY(!phy_addr_.is_disked())) { LOG_INFO("tablet may be removed, and created again, continue", K(phy_addr_)); - } else if (OB_FAIL(wash_obj())) { - LOG_WARN("fail to wash obj", K(ret)); + } else if (0 != obj_.ptr_->dec_ref()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("obj is still being used", K(ret), K(*this)); } else { - is_washed = true; - } - return ret; -} - -int ObTabletPointer::wash_obj() -{ - int ret = OB_SUCCESS; - const ObLSID ls_id = obj_.ptr_->tablet_meta_.ls_id_; - const ObTabletID tablet_id = obj_.ptr_->tablet_meta_.tablet_id_; - const int64_t wash_score = obj_.ptr_->get_wash_score(); - - if (OB_FAIL(obj_.ptr_->inc_macro_disk_ref())) { - LOG_WARN("fail to inc macro disk ref", K(ret), K(obj_)); - } else { - LOG_DEBUG("succeed to wash one tablet", KP(obj_.ptr_), K(ls_id), K(tablet_id), K(wash_score), K(phy_addr_)); - reset_obj(); + const ObLSID ls_id = obj_.ptr_->tablet_meta_.ls_id_; + const ObTabletID tablet_id = obj_.ptr_->tablet_meta_.tablet_id_; + const int64_t wash_score = obj_.ptr_->get_wash_score(); + const int64_t rowkey_info_size = nullptr == obj_.ptr_->rowkey_read_info_ + ? 0 : obj_.ptr_->rowkey_read_info_->get_deep_copy_size(); + guard.get_obj(meta_obj); + ObTablet *tmp_obj = obj_.ptr_; + if (OB_NOT_NULL(meta_obj.ptr_) && sizeof(ObTablet) + rowkey_info_size <= ObTenantMetaMemMgr::NORMAL_TABLET_POOL_SIZE) { + char *buf = reinterpret_cast(meta_obj.ptr_); + const int64_t buf_len = ObMetaObjBufferHelper::get_buffer_header(buf).buf_len_; + const int64_t cur_buf_len = ObMetaObjBufferHelper::get_buffer_header(reinterpret_cast(tmp_obj)).buf_len_; + if (OB_UNLIKELY(cur_buf_len != ObTenantMetaMemMgr::LARGE_TABLET_POOL_SIZE + || buf_len != ObTenantMetaMemMgr::NORMAL_TABLET_POOL_SIZE)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tablet buffer length", K(ret), K(cur_buf_len), K(buf_len), KP(tmp_obj), KP(meta_obj.ptr_)); + } else if (OB_FAIL(set_attr_for_obj(meta_obj.ptr_))) { + LOG_WARN("fail to set attr for object", K(ret), K(meta_obj)); + } else if (OB_FAIL(ObTabletPersister::transform_tablet_memory_footprint(*obj_.ptr_, buf, buf_len))) { + LOG_WARN("fail to degrade tablet memory", K(ret), KPC(obj_.ptr_), KP(buf), K(buf_len)); + } else { + meta_obj.ptr_->inc_ref(); + obj_ = meta_obj; + } + } else { + obj_.ptr_ = nullptr; + } + if (OB_FAIL(ret)) { + obj_.ptr_->inc_ref(); + } else { + ObMetaObjBufferHelper::del_meta_obj(tmp_obj); + free_obj = ObMetaObjBufferHelper::get_meta_obj_buffer_ptr(reinterpret_cast(tmp_obj)); + FLOG_INFO("wash one tablet",K(ret), KP(free_obj), K(ls_id), K(tablet_id), K(wash_score), K(obj_), K(meta_obj), K(phy_addr_)); + } } return ret; } @@ -171,8 +183,9 @@ int ObTabletPointer::deep_copy(char *buf, const int64_t buf_len, ObMetaPointerphy_addr_ = phy_addr_; pvalue->obj_.pool_ = obj_.pool_; pvalue->obj_.ptr_ = obj_.ptr_; + pvalue->obj_.allocator_ = obj_.allocator_; if (nullptr != obj_.ptr_) { - if (nullptr == obj_.pool_) { + if (OB_UNLIKELY(nullptr == obj_.pool_ && nullptr == obj_.allocator_)) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("object pool is nullptr", K(ret), K_(obj)); ob_abort(); @@ -186,8 +199,9 @@ int ObTabletPointer::deep_copy(char *buf, const int64_t buf_len, ObMetaPointerddl_kv_mgr_handle_ = ddl_kv_mgr_handle_; pvalue->memtable_mgr_handle_ = memtable_mgr_handle_; pvalue->ddl_info_ = ddl_info_; - pvalue->tx_data_ = tx_data_; - pvalue->redefined_schema_version_ = redefined_schema_version_; + pvalue->initial_state_ = initial_state_; + pvalue->mds_table_handler_ = mds_table_handler_;// src ObTabletPointer will destroy soon + pvalue->old_version_chain_ = old_version_chain_; value = pvalue; // NOTICE: cond and rw lock cannot be copied } else { @@ -197,36 +211,14 @@ int ObTabletPointer::deep_copy(char *buf, const int64_t buf_len, ObMetaPointerget_tablet_id(), + ls_handle_.get_ls()->get_ls_id(), + not_exist_create, + this))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to get mds table", K(ret), K(not_exist_create)); + } + } + return ret; +} + +int ObTabletPointer::try_release_mds_nodes_below(const share::SCN &scn) +{ + return mds_table_handler_.try_release_nodes_below(scn); +} + +int ObTabletPointer::try_gc_mds_table() +{ + return mds_table_handler_.try_gc_mds_table(); +} + +void ObTabletPointer::set_mds_written() +{ + mds_table_handler_.set_mds_written(); +} + +bool ObTabletPointer::is_mds_written() const +{ + return mds_table_handler_.is_mds_written(); +} + +void ObTabletPointer::mark_mds_table_deleted() +{ + return mds_table_handler_.mark_removed_from_t3m(this); +} + +int ObTabletPointer::add_tablet_to_old_version_chain(ObTablet *tablet) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(nullptr == tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("add invalid tablet to old version chain", K(ret), KPC(tablet)); + } else { + //defensive code + ObTablet *cur = old_version_chain_; + bool found = false; + while (OB_NOT_NULL(cur) && !found) { + found = tablet == cur; + cur = cur->get_next_tablet(); + } + if (found) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet has been in old version chain, some wrong occurs", + K(ret), KP(tablet), KP_(old_version_chain)); + } else { + tablet->set_next_tablet(old_version_chain_); + old_version_chain_ = tablet; + } + } + LOG_DEBUG("add_tablet_to_old_version_chain", K(ret), KP(tablet)); + return ret; +} + +int ObTabletPointer::remove_tablet_from_old_version_chain(ObTablet *tablet) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tablet to remove", K(ret), KP(tablet)); + } else if (OB_ISNULL(old_version_chain_)) { + // do nothing + } else if (old_version_chain_ == tablet) { + old_version_chain_ = old_version_chain_->get_next_tablet(); + } else { + ObTablet *cur = old_version_chain_; + ObTablet *next = nullptr; + while (OB_SUCC(ret) && OB_NOT_NULL(next = cur->get_next_tablet())) { + if (next == tablet) { + next = next->get_next_tablet(); + cur->set_next_tablet(next); + break; + } + cur = next; + } + } + LOG_DEBUG("remove_tablet_from_old_version_chain", K(ret), KP(tablet), KP(old_version_chain_)); + return ret; +} + +int ObTabletPointer::get_min_mds_ckpt_scn(share::SCN &scn) +{ + int ret = OB_SUCCESS; + scn.set_max(); + ObTablet *cur = old_version_chain_; + while (OB_SUCC(ret) && OB_NOT_NULL(cur)) { + scn = MIN(scn, cur->get_tablet_meta().mds_checkpoint_scn_); + cur = cur->get_next_tablet(); + + } + return ret; +} + +int ObTabletPointer::acquire_obj(ObTablet *&t) +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + if (OB_ISNULL(obj_.pool_) || OB_ISNULL(obj_.t3m_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "object pool is nullptr", K(ret), K(obj_)); + } else if (OB_FAIL(obj_.t3m_->acquire_tablet(obj_.pool_, t))) { + STORAGE_LOG(WARN, "fail to acquire tablet buffer", K(ret), K(phy_addr_)); + } + return ret; +} + +int ObTabletPointer::release_obj(ObTablet *&t) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(t)) { + // do nothing + } else if (OB_UNLIKELY(nullptr == obj_.pool_ && nullptr == obj_.allocator_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "object pool or allocator is nullptr", K(ret), K(obj_)); + } else if (nullptr != obj_.pool_) { + obj_.t3m_->release_tablet(t); + t = nullptr; + } else { + t->~ObTablet(); + obj_.allocator_->free(t); + t = nullptr; + } + return ret; +} + } // namespace storage } // namespace oceanbase diff --git a/src/storage/meta_mem/ob_tablet_pointer.h b/src/storage/meta_mem/ob_tablet_pointer.h index 9079250c0..ee7a8f594 100644 --- a/src/storage/meta_mem/ob_tablet_pointer.h +++ b/src/storage/meta_mem/ob_tablet_pointer.h @@ -13,15 +13,14 @@ #ifndef OCEANBASE_STORAGE_OB_TABLET_POINTER #define OCEANBASE_STORAGE_OB_TABLET_POINTER -#include "lib/lock/ob_tc_rwlock.h" -#include "lib/lock/ob_thread_cond.h" +#include "lib/lock/ob_mutex.h" #include "storage/meta_mem/ob_meta_pointer.h" #include "storage/meta_mem/ob_meta_obj_struct.h" #include "storage/ob_i_memtable_mgr.h" #include "storage/tablet/ob_tablet_ddl_info.h" #include "storage/tablet/ob_tablet_meta.h" -#include "storage/tablet/ob_tablet_multi_source_data.h" #include "storage/tx_storage/ob_ls_handle.h" +#include "storage/multi_data_source/mds_table_handler.h" namespace oceanbase { @@ -46,37 +45,48 @@ public: virtual void reset() override; virtual int set_attr_for_obj(ObTablet *tablet) override; - virtual int dump_meta_obj(bool &is_washed) override; + virtual int dump_meta_obj(ObMetaObjGuard &guard, void *&free_obj) override; virtual int deep_copy(char *buf, const int64_t buf_len, ObMetaPointer *&value) const override; virtual int64_t get_deep_copy_size() const override; + virtual int acquire_obj(ObTablet *&t) override; + virtual int release_obj(ObTablet *&t) override; + + // do not KPC memtable_mgr, may dead lock INHERIT_TO_STRING_KV("ObMetaPointer", ObMetaPointer, K_(ls_handle), K_(ddl_kv_mgr_handle), - K_(memtable_mgr_handle), K_(ddl_info), K_(redefined_schema_version)); + KP(memtable_mgr_handle_.get_memtable_mgr()), K_(ddl_info), K_(initial_state), KP_(old_version_chain)); 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; + bool get_initial_state() const; + void set_initial_state(const bool initial_state); 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); int remove_ddl_kv_mgr(const ObDDLKvMgrHandle &ddl_kv_mgr_handle); + int get_mds_table(mds::MdsTableHandle &handle, bool not_exist_create = false); + // interfaces forward to mds_table_handler_ + void mark_mds_table_deleted(); + void set_mds_written(); + bool is_mds_written() const; + int try_release_mds_nodes_below(const share::SCN &scn); + int try_gc_mds_table(); + int get_min_mds_ckpt_scn(share::SCN &scn); private: int wash_obj(); - virtual int do_post_work_for_load() override; + int add_tablet_to_old_version_chain(ObTablet *tablet); + int remove_tablet_from_old_version_chain(ObTablet *tablet); private: ObLSHandle ls_handle_; ObDDLKvMgrHandle ddl_kv_mgr_handle_; 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_; + bool initial_state_; + mds::ObMdsTableHandler mds_table_handler_;// 48B + ObByteLock ddl_kv_mgr_lock_; + ObTablet *old_version_chain_; DISALLOW_COPY_AND_ASSIGN(ObTabletPointer); }; + } // namespace storage } // namespace oceanbase diff --git a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp old mode 100644 new mode 100755 index d1ed82847..af52c7833 --- a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp +++ b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp @@ -10,10 +10,12 @@ * See the Mulan PubL v2 for more details. */ + #define USING_LOG_PREFIX STORAGE #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" - +#include "storage/meta_mem/ob_meta_pointer.h" +#include "storage/multi_data_source/mds_table_mgr.h" #include "lib/function/ob_function.h" #include "share/rc/ob_tenant_module_init_ctx.h" #include "share/leak_checker/obj_leak_checker.h" @@ -21,6 +23,7 @@ #include "storage/ls/ob_ls_meta.h" #include "storage/tablet/ob_tablet_memtable_mgr.h" #include "storage/tablet/ob_tablet_multi_source_data.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" #include "storage/tablet/ob_tablet_slog_helper.h" #include "storage/tx_table/ob_tx_data_memtable.h" #include "storage/tx_table/ob_tx_ctx_memtable.h" @@ -30,6 +33,7 @@ #include "storage/tx_storage/ob_ls_service.h" #include "storage/ddl/ob_tablet_ddl_kv.h" #include "share/ob_thread_define.h" +#include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" namespace oceanbase { @@ -49,6 +53,47 @@ ObTenantMetaMemStatus::ObTenantMetaMemStatus() name_[0] = '\0'; } +void ObTabletBufferInfo::reset() +{ + ls_id_.reset(); + tablet_id_.reset(); + tablet_buffer_ptr_ = nullptr; + tablet_ = nullptr; + pool_type_ = ObTabletPoolType::TP_MAX; + in_map_ = false; + last_access_time_ = -1; +} + +int ObTabletBufferInfo::fill_info(const ObTabletPoolType &pool_type, ObMetaObjBufferNode *node) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(node) || ObTabletPoolType::TP_MAX == pool_type) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), KP(node), K(pool_type)); + } else { + char *obj_buffer = ObMetaObjBufferHelper::get_obj_buffer(node); + tablet_ = reinterpret_cast(obj_buffer); + const ObTabletMeta &tablet_meta = tablet_->get_tablet_meta(); + tablet_id_ = tablet_meta.tablet_id_; + ls_id_ = tablet_meta.ls_id_; + tablet_buffer_ptr_ = reinterpret_cast(node); + in_map_ = ObMetaObjBufferHelper::is_in_map(obj_buffer); + pool_type_ = pool_type; + const int64_t wash_score = tablet_->get_wash_score(); + last_access_time_ = wash_score > 0 ? wash_score : INT64_MAX + wash_score; + } + return ret; +} + +void ObTenantMetaMemMgr::TabletGCTask::runTimerTask() +{ + int ret = OB_SUCCESS; + bool all_tablet_cleaned = false; + if (OB_FAIL(t3m_->gc_tablets_in_queue(all_tablet_cleaned))) { + LOG_WARN("fail to gc tables in queue", K(ret)); + } +} + void ObTenantMetaMemMgr::TableGCTask::runTimerTask() { int ret = OB_SUCCESS; @@ -58,14 +103,6 @@ void ObTenantMetaMemMgr::TableGCTask::runTimerTask() } } -void ObTenantMetaMemMgr::MinMinorSSTableGCTask::runTimerTask() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(t3m_->gc_min_minor_sstable_in_set())) { - LOG_WARN("fail to gc min minor sstable in set", K(ret)); - } -} - void ObTenantMetaMemMgr::RefreshConfigTask::runTimerTask() { int ret = OB_SUCCESS; @@ -78,6 +115,17 @@ void ObTenantMetaMemMgr::RefreshConfigTask::runTimerTask() } } +void ObTenantMetaMemMgr::TabletPersistTask::runTimerTask() +{ + int ret = OB_SUCCESS; + if (!ObServerCheckpointSlogHandler::get_instance().is_started()) { /* for compatibility */ + // do nothing + STORAGE_LOG(DEBUG, "ob block manager has not started"); + } else if (OB_FAIL(t3m_->get_mstx_tablet_creator().persist_tablet())) { + LOG_WARN("fail to persist tablet in tablet creator", K(ret)); + } +} + ObTenantMetaMemMgr::ObTenantMetaMemMgr(const uint64_t tenant_id) : cmp_ret_(OB_SUCCESS), compare_(cmp_ret_), @@ -85,27 +133,27 @@ ObTenantMetaMemMgr::ObTenantMetaMemMgr(const uint64_t tenant_id) wash_func_(*this), tenant_id_(tenant_id), bucket_lock_(), - allocator_(tenant_id, wash_func_), + full_tablet_creator_(), tablet_map_(), tg_id_(-1), + persist_tg_id_(-1), table_gc_task_(this), - min_minor_sstable_gc_task_(this), refresh_config_task_(), + tablet_persist_task_(this), + tablet_gc_task_(this), + gc_head_(nullptr), + wait_gc_tablets_cnt_(0), free_tables_queue_(), gc_queue_lock_(common::ObLatchIds::TENANT_META_MEM_MGR_LOCK), - last_min_minor_sstable_set_(), - sstable_set_lock_(common::ObLatchIds::TENANT_META_MEM_MGR_LOCK), - pin_set_lock_(), - pinned_tablet_set_(), - memtable_pool_(tenant_id, get_default_memtable_pool_count(), "MemTblObj", ObCtxIds::DEFAULT_CTX_ID, wash_func_), - sstable_pool_(tenant_id, get_default_sstable_pool_count(), "SSTblObj", ObCtxIds::META_OBJ_CTX_ID, wash_func_), - ddl_kv_pool_(tenant_id, MAX_DDL_KV_IN_OBJ_POOL, "DDLKVObj", ObCtxIds::DEFAULT_CTX_ID, wash_func_), - tablet_pool_(tenant_id, get_default_tablet_pool_count(), "TabletObj", ObCtxIds::META_OBJ_CTX_ID, wash_func_), - tablet_ddl_kv_mgr_pool_(tenant_id, get_default_tablet_pool_count(), "DDLKvMgrObj", ObCtxIds::DEFAULT_CTX_ID, wash_func_), - tablet_memtable_mgr_pool_(tenant_id, get_default_tablet_pool_count(), "MemTblMgrObj", ObCtxIds::DEFAULT_CTX_ID,wash_func_), - tx_data_memtable_pool_(tenant_id, MAX_TX_DATA_MEMTABLE_CNT_IN_OBJ_POOL, "TxDataMemObj", ObCtxIds::DEFAULT_CTX_ID,wash_func_), - tx_ctx_memtable_pool_(tenant_id, MAX_TX_CTX_MEMTABLE_CNT_IN_OBJ_POOL, "TxCtxMemObj", ObCtxIds::DEFAULT_CTX_ID,wash_func_), - lock_memtable_pool_(tenant_id, MAX_LOCK_MEMTABLE_CNT_IN_OBJ_POOL, "LockMemObj", ObCtxIds::DEFAULT_CTX_ID,wash_func_), + memtable_pool_(tenant_id, get_default_memtable_pool_count(), "MemTblObj", ObCtxIds::DEFAULT_CTX_ID), + tablet_buffer_pool_(tenant_id, get_default_normal_tablet_pool_count(), "N_TabletPool", ObCtxIds::META_OBJ_CTX_ID, &wash_func_), + large_tablet_buffer_pool_(tenant_id, get_default_large_tablet_pool_count(), "L_TabletPool", ObCtxIds::META_OBJ_CTX_ID, &wash_func_, false/*allow_over_max_free_num*/), + ddl_kv_pool_(tenant_id, MAX_DDL_KV_IN_OBJ_POOL, "DDLKVObj", ObCtxIds::DEFAULT_CTX_ID), + tablet_ddl_kv_mgr_pool_(tenant_id, get_default_tablet_pool_count(), "DDLKvMgrObj", ObCtxIds::DEFAULT_CTX_ID), + tablet_memtable_mgr_pool_(tenant_id, get_default_tablet_pool_count(), "MemTblMgrObj", ObCtxIds::DEFAULT_CTX_ID), + tx_data_memtable_pool_(tenant_id, MAX_TX_DATA_MEMTABLE_CNT_IN_OBJ_POOL, "TxDataMemObj", ObCtxIds::DEFAULT_CTX_ID), + tx_ctx_memtable_pool_(tenant_id, MAX_TX_CTX_MEMTABLE_CNT_IN_OBJ_POOL, "TxCtxMemObj", ObCtxIds::DEFAULT_CTX_ID), + lock_memtable_pool_(tenant_id, MAX_LOCK_MEMTABLE_CNT_IN_OBJ_POOL, "LockMemObj", ObCtxIds::DEFAULT_CTX_ID), is_inited_(false) { for (int64_t i = 0; i < ObITable::TableType::MAX_TABLE_TYPE; i++) { @@ -145,23 +193,17 @@ int ObTenantMetaMemMgr::init() } 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(full_tablet_creator_.init(tenant_id_))) { + LOG_WARN("fail to init full tablet creator", K(ret), K(tenant_id_)); } else if (OB_FAIL(tablet_map_.init(bucket_num, map_attr, TOTAL_LIMIT, HOLD_LIMIT, common::OB_MALLOC_NORMAL_BLOCK_SIZE))) { 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, other_attr))) { - LOG_WARN("fail to create last min minor sstable set", K(ret)); - } else if (OB_FAIL(pin_set_lock_.init(pin_set_bucket_num, ObLatchIds::BLOCK_MANAGER_LOCK, "T3MPinLock", - tenant_id_))) { - LOG_WARN("fail to init pin set lock", K(ret)); - } else if (OB_FAIL(pinned_tablet_set_.create(pin_set_bucket_num, other_attr))) { - LOG_WARN("fail to create pinned tablet set", K(ret)); } else if (OB_FAIL(gc_memtable_map_.create(10, "GCMemtableMap", "GCMemtableMap", tenant_id_))) { LOG_WARN("fail to initialize gc memtable map", K(ret)); } else if (OB_FAIL(TG_CREATE_TENANT(lib::TGDefIDs::TenantMetaMemMgr, tg_id_))) { LOG_WARN("fail to create thread for t3m", K(ret)); + } else if (OB_FAIL(TG_CREATE_TENANT(lib::TGDefIDs::TenantMetaMemMgr, persist_tg_id_))) { + LOG_WARN("fail to create thread for t3m", K(ret)); } else { init_pool_arr(); is_inited_ = true; @@ -180,12 +222,6 @@ void ObTenantMetaMemMgr::init_pool_arr() pool_arr_[static_cast(ObITable::TableType::TX_CTX_MEMTABLE)] = &tx_ctx_memtable_pool_; pool_arr_[static_cast(ObITable::TableType::LOCK_MEMTABLE)] = &lock_memtable_pool_; pool_arr_[static_cast(ObITable::TableType::DDL_MEM_SSTABLE)] = &ddl_kv_pool_; - - for (int64_t i = ObITable::TableType::MAJOR_SSTABLE; i < ObITable::TableType::MAX_TABLE_TYPE; i++) { - if (ObITable::is_sstable((ObITable::TableType)i) && !ObITable::is_ddl_mem_sstable((ObITable::TableType)i)) { - pool_arr_[i] = &sstable_pool_; - } - } } int ObTenantMetaMemMgr::start() @@ -196,16 +232,21 @@ int ObTenantMetaMemMgr::start() LOG_WARN("ObTenantMetaMemMgr hasn't been inited", K(ret)); } else if (OB_FAIL(TG_START(tg_id_))) { LOG_WARN("fail to start thread for t3m", K(ret), K(tg_id_)); + } else if (OB_FAIL(TG_START(persist_tg_id_))) { + LOG_WARN("fail to start thread for t3m", K(ret), K(persist_tg_id_)); } else if (OB_FAIL(TG_SCHEDULE(tg_id_, table_gc_task_, TABLE_GC_INTERVAL_US, true/*repeat*/))) { LOG_WARN("fail to schedule itables gc task", K(ret)); - } else if (OB_FAIL(TG_SCHEDULE( - tg_id_, min_minor_sstable_gc_task_, MIN_MINOR_SSTABLE_GC_INTERVAL_US, true/*repeat*/))) { - LOG_WARN("fail to schedule min minor sstable gc task", K(ret)); } else if (OB_FAIL(TG_SCHEDULE( tg_id_, refresh_config_task_, REFRESH_CONFIG_INTERVAL_US, true/*repeat*/))) { LOG_WARN("fail to schedule refresh config task", K(ret)); + } else if (OB_FAIL(TG_SCHEDULE( + persist_tg_id_, tablet_persist_task_, TABLET_TRANSFORM_INTERVAL_US, true/*repeat*/))) { + LOG_WARN("fail to schedule tablet persist task", K(ret)); + } else if (OB_FAIL(TG_SCHEDULE( + tg_id_, tablet_gc_task_, TABLE_GC_INTERVAL_US, true/*repeat*/))) { + LOG_WARN("fail to schedule tablet gc task", K(ret)); } else { - LOG_INFO("successfully to start t3m's three tasks", K(ret), K(tg_id_)); + LOG_INFO("successfully to start t3m's three tasks", K(ret), K(tg_id_), K(persist_tg_id_)); } return ret; } @@ -214,7 +255,8 @@ void ObTenantMetaMemMgr::stop() { if (OB_LIKELY(is_inited_)) { TG_STOP(tg_id_); - LOG_INFO("t3m's three tasks have been stopped", K(tg_id_)); + TG_STOP(persist_tg_id_); + LOG_INFO("t3m's three tasks have been stopped", K(tg_id_), K(persist_tg_id_)); } } @@ -222,7 +264,8 @@ void ObTenantMetaMemMgr::wait() { if (OB_LIKELY(is_inited_)) { TG_WAIT(tg_id_); - LOG_INFO("t3m's three tasks have finished wait", K(tg_id_)); + TG_WAIT(persist_tg_id_); + LOG_INFO("t3m's three tasks have finished wait", K(tg_id_), K(persist_tg_id_)); } } @@ -230,12 +273,17 @@ void ObTenantMetaMemMgr::destroy() { int ret = OB_SUCCESS; TG_DESTROY(tg_id_); + TG_DESTROY(persist_tg_id_); tg_id_ = -1; + persist_tg_id_ = -1; bool is_all_clean = false; + full_tablet_creator_.destroy_queue(); + ObT3mTabletMapIterator::GCTabletItemOp gc_op(tablet_map_); + tablet_map_.for_each_value_store(gc_op); + gc_op.~GCTabletItemOp(); + destroy_gc_tablets_queue(); + full_tablet_creator_.reset(); // must reset after gc_tablets tablet_map_.destroy(); - last_min_minor_sstable_set_.destroy(); - pin_set_lock_.destroy(); - pinned_tablet_set_.destroy(); while (!is_all_clean && OB_SUCC(gc_tables_in_queue(is_all_clean))); for (auto iter = gc_memtable_map_.begin(); OB_SUCC(ret) && iter != gc_memtable_map_.end(); ++iter) { @@ -252,7 +300,6 @@ void ObTenantMetaMemMgr::destroy() } gc_memtable_map_.destroy(); bucket_lock_.destroy(); - allocator_.reset(); for (int64_t i = 0; i <= ObITable::TableType::REMOTE_LOGICAL_MINOR_SSTABLE; i++) { pool_arr_[i] = nullptr; } @@ -269,6 +316,31 @@ void ObTenantMetaMemMgr::mtl_destroy(ObTenantMetaMemMgr *&meta_mem_mgr) } } +int ObTenantMetaMemMgr::print_old_chain( + const ObTabletMapKey &key, + const ObTabletPointer &tablet_ptr, + const int64_t buf_len, + char *buf) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + ObBucketHashWLockGuard lock_guard(bucket_lock_, key.hash()); + ObTablet *tablet = tablet_ptr.old_version_chain_; + while (nullptr != tablet && OB_SUCC(ret)) { + if (OB_FAIL(databuff_printf(buf, buf_len, pos, "{%p} ", static_cast(tablet)))) { + if (OB_SIZE_OVERFLOW != ret) { + SERVER_LOG(WARN, "fail to print tablet on old chain", K(ret), KP(tablet)); + } + } else { + tablet = tablet->get_next_tablet(); + } + } + if (OB_SIZE_OVERFLOW == ret) { + ret = OB_SUCCESS; + } + return ret; +} + int ObTenantMetaMemMgr::push_table_into_gc_queue(ObITable *table, const ObITable::TableType table_type) { int ret = OB_SUCCESS; @@ -281,7 +353,10 @@ int ObTenantMetaMemMgr::push_table_into_gc_queue(ObITable *table, const ObITable LOG_ERROR("invalid argument", K(ret), KP(table)); } else if (OB_UNLIKELY(!ObITable::is_table_type_valid(table_type))) { ret = OB_INVALID_ARGUMENT; - LOG_ERROR("invalid table key", K(ret), K(table_type), KP(table), K(*table)); + LOG_ERROR("invalid table key", K(ret), K(table_type), KPC(table)); + } else if (OB_UNLIKELY(ObITable::is_sstable(table_type) && ObITable::DDL_MEM_SSTABLE != table_type)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("should not recycle sstable", K(ret), K(table_type), KPC(table)); } else if (OB_ISNULL(item = (TableGCItem *)ob_malloc(size, attr))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("fail to allocate memory for TableGCItem", K(ret), K(size)); @@ -291,7 +366,7 @@ int ObTenantMetaMemMgr::push_table_into_gc_queue(ObITable *table, const ObITable if (OB_FAIL(free_tables_queue_.push((ObLink *)item))) { LOG_ERROR("fail to push back into free_tables_queue_", K(ret), KPC(item)); } else { - LOG_DEBUG("succeed to push table into gc queue", KP(table), K(table_type), K(lbt())); + LOG_INFO("succeed to push table into gc queue", KP(table), K(table_type)); } } @@ -312,7 +387,7 @@ int ObTenantMetaMemMgr::gc_tables_in_queue(bool &all_table_cleaned) if (IS_NOT_INIT) { ret = OB_NOT_INIT; - LOG_WARN("t3m has not been inited", K(ret)); + LOG_WARN("t3m has not been inited", K(ret), KP(this)); } else { lib::ObLockGuard lock_guard(gc_queue_lock_); while(OB_SUCC(ret) && left_recycle_cnt-- > 0 && free_tables_queue_.size() > 0) { @@ -397,17 +472,11 @@ int ObTenantMetaMemMgr::gc_tables_in_queue(bool &all_table_cleaned) if (recycled_cnt > 0) { FLOG_INFO("Successfully finish table gc", K(sstable_cnt), K(data_memtable_cnt), K(tx_data_memtable_cnt), K(tx_ctx_memtable_cnt), K(lock_memtable_cnt), - K(pending_cnt), K(recycled_cnt), K(allocator_), - K(tablet_pool_), K(sstable_pool_), K(ddl_kv_pool_), K(memtable_pool_), - "tablet count", tablet_map_.count(), - "min_minor_cnt", last_min_minor_sstable_set_.size(), - "pinned_tablet_cnt", pinned_tablet_set_.size()); + K(pending_cnt), K(recycled_cnt), K(tablet_buffer_pool_), K(large_tablet_buffer_pool_), K(ddl_kv_pool_), K(memtable_pool_), + "tablet count", tablet_map_.count()); } else if (REACH_COUNT_INTERVAL(100)) { - FLOG_INFO("Recycle 0 table", K(ret), K(allocator_), - K(tablet_pool_), K(sstable_pool_), K(ddl_kv_pool_), K(memtable_pool_), - "tablet count", tablet_map_.count(), - "min_minor_cnt", last_min_minor_sstable_set_.size(), - "pinned_tablet_cnt", pinned_tablet_set_.size()); + FLOG_INFO("Recycle 0 table", K(ret), K(tablet_buffer_pool_), K(large_tablet_buffer_pool_), K(ddl_kv_pool_), K(memtable_pool_), + "tablet count", tablet_map_.count()); } } @@ -523,185 +592,276 @@ int ObTenantMetaMemMgr::push_memtable_into_gc_map_(memtable::ObMemtable *memtabl return ret; } -void ObTenantMetaMemMgr::gc_sstable(ObSSTable *sstable) +int ObTenantMetaMemMgr::push_tablet_into_gc_queue(ObTablet *tablet) { - if (OB_UNLIKELY(nullptr == sstable)) { - LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid argument"); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(nullptr == tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fail to push invalid tablet into gc queue", K(ret), KP(tablet)); } else { - const int64_t block_cnt = sstable->get_meta().get_macro_info().get_total_block_cnt(); - const int64_t start_time = ObTimeUtility::current_time(); - if (sstable->is_ddl_mem_sstable()) { - ddl_kv_pool_.free_obj(sstable); + ObTabletHandle empty_handle; + tablet->set_next_tablet_guard(empty_handle); // release the ref_cnt of next_tablet_guard_ + do { + tablet->set_next_tablet(ATOMIC_LOAD(&gc_head_)); + } while (tablet->get_next_tablet() != ATOMIC_VCAS(&gc_head_, tablet->get_next_tablet(), tablet)); + ATOMIC_INC(&wait_gc_tablets_cnt_); + // can't do anything to tablet as long as tablet has been pushed into gc queue. + LOG_INFO("push tablet into gc queue", K(ret), KP(tablet)); + } + return ret; +} + +void ObTenantMetaMemMgr::push_tablet_list_into_gc_queue(ObTablet *tablet) +{ + ObTablet *head = tablet; + ObTablet *tail = head; + while (OB_NOT_NULL(tail) && OB_NOT_NULL(tail->get_next_tablet())) { + tail = tail->get_next_tablet(); + } + if (OB_NOT_NULL(tail)) { + do { + tail->set_next_tablet(ATOMIC_LOAD(&gc_head_)); + } while (tail->get_next_tablet() != ATOMIC_VCAS(&gc_head_, tail->get_next_tablet(), head)); + // no need to update wait_gc_tablets_cnt_ + } +} + +int ObTenantMetaMemMgr::gc_tablet(ObTablet *tablet) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("t3m has not been inited", K(ret)); + } else if (OB_UNLIKELY(nullptr == tablet || tablet->get_ref() != 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("push invalid tablet into gc queue", K(ret), KPC(tablet)); + } else if (!tablet->is_valid()) { // push invalid tablet into gc queue directly + LOG_INFO("gc invalid tablet", KP(tablet)); + } else { + const ObTabletMeta &tablet_meta = tablet->get_tablet_meta(); + const ObTabletMapKey key(tablet_meta.ls_id_, tablet_meta.tablet_id_); + ObBucketHashWLockGuard lock_guard(bucket_lock_, key.hash()); + + const ObTabletPointerHandle &ptr_handle = tablet->get_pointer_handle(); + ObTabletPointer *tablet_ptr = nullptr; + if (OB_ISNULL(tablet_ptr = static_cast(ptr_handle.get_resource_ptr()))) { + ret = OB_ERR_NULL_VALUE; + LOG_WARN("unexpected null tablet pointer", K(ret), K(key), K(ptr_handle)); + } else if (OB_FAIL(tablet_ptr->remove_tablet_from_old_version_chain(tablet))) { + LOG_WARN("fail to remove tablet from old version chain", K(ret), K(key), KPC(tablet)); + } + } + if (OB_SUCC(ret) && OB_FAIL(push_tablet_into_gc_queue(tablet))) { + LOG_WARN("fail to push tablet into gc queue", K(ret), KPC(tablet)); + } + return ret; +} + +void ObTenantMetaMemMgr::destroy_gc_tablets_queue() +{ + // only release memory of tablets + while (OB_NOT_NULL(gc_head_)) { + ObTablet *tablet = gc_head_; + gc_head_ = gc_head_->get_next_tablet(); + ObIAllocator *allocator = tablet->get_allocator(); + if (OB_ISNULL(allocator)) { + tablet_buffer_pool_.free_obj(tablet); } else { - sstable_pool_.free_obj(sstable); - } - const int64_t end_time = ObTimeUtility::current_time(); - if (end_time - start_time > SSTABLE_GC_MAX_TIME) { - int ret = OB_ERR_TOO_MUCH_TIME; - LOG_DEBUG("sstable gc costs too much time", K(ret), K(start_time), K(end_time), K(block_cnt)); + tablet->~ObTablet(); + allocator->~ObIAllocator(); } } + wait_gc_tablets_cnt_ = 0; } -int ObTenantMetaMemMgr::get_min_end_scn_for_ls(const share::ObLSID &ls_id, SCN &end_scn) +int ObTenantMetaMemMgr::gc_tablets_in_queue(bool &all_tablet_cleaned) { int ret = OB_SUCCESS; - end_scn = ObScnRange::MAX_SCN; - if (OB_UNLIKELY(!ls_id.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(ls_id)); + all_tablet_cleaned = false; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("t3m has not been inited", K(ret)); } else { - SpinRLockGuard guard(sstable_set_lock_); - SSTableSet::const_iterator iter = last_min_minor_sstable_set_.begin(); - while (OB_SUCC(ret) && iter != last_min_minor_sstable_set_.end()) { - const MinMinorSSTableInfo &info = iter->first; - if (info.ls_id_ != ls_id || info.table_key_.tablet_id_.is_ls_inner_tablet()) { - // just skip - } else if (OB_UNLIKELY(!info.is_valid())) { + int64_t gc_tablets_cnt = 0; + int64_t err_tablets_cnt = 0; + int64_t left_recycle_cnt = ONE_ROUND_TABLET_GC_COUNT_THRESHOLD; + ObTablet *tablet = nullptr; + do { + tablet = ATOMIC_LOAD(&gc_head_); + } while (tablet != ATOMIC_VCAS(&gc_head_, tablet, nullptr)); + + while(OB_SUCC(ret) && OB_NOT_NULL(tablet) && left_recycle_cnt > 0) { + ObTablet *next_tablet = static_cast(tablet->get_next_tablet()); + ATOMIC_DEC(&wait_gc_tablets_cnt_); + --left_recycle_cnt; + if (OB_UNLIKELY(tablet->get_ref() != 0)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, info is invalid", K(ret), K(info)); - } else if (info.sstable_handle_.get_table()->get_end_scn() < end_scn) { - end_scn = info.sstable_handle_.get_table()->get_end_scn(); - } - ++iter; - } - } - return ret; -} - -int ObTenantMetaMemMgr::record_min_minor_sstable( - const share::ObLSID &ls_id, - const ObTableHandleV2 &table_handle) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!ls_id.is_valid() || !table_handle.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(ls_id), K(table_handle)); - } else if (OB_UNLIKELY(!table_handle.get_table()->is_minor_sstable())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected table type, this table must be minor sstable", K(ret), K(table_handle)); - } else { - MinMinorSSTableInfo info(ls_id, table_handle.get_table()->get_key(), table_handle); - SpinWLockGuard guard(sstable_set_lock_); - if (OB_FAIL(last_min_minor_sstable_set_.set_refactored(info, 0/*flag, not overwrite*/))) { - if (OB_HASH_EXIST != ret) { - LOG_WARN("fail to set refactored min minor sstable", K(ret), K(info)); + LOG_WARN("unexpected tablet in gc queue", K(ret), KPC(tablet)); } else { - ret = OB_SUCCESS; + recycle_tablet(tablet); } + if (OB_FAIL(ret)) { + ++err_tablets_cnt; + FLOG_INFO("fail to gc tablet", K(ret), KP(tablet), KPC(tablet)); + if (OB_FAIL(push_tablet_into_gc_queue(tablet))) { + LOG_ERROR("fail to push tablet into gc queue, tablet may be leaked", K(ret), KP(tablet)); + } + ret = OB_SUCCESS; // continue to gc other tablet + } else { + ++gc_tablets_cnt; + LOG_DEBUG("succeed to gc tablet", K(ret), KP(tablet)); + } + tablet = static_cast(next_tablet); } + if (OB_NOT_NULL(tablet)) { + push_tablet_list_into_gc_queue(tablet); + } + if (left_recycle_cnt < ONE_ROUND_TABLET_GC_COUNT_THRESHOLD) { + FLOG_INFO("Finish tablets gc task one round", K(gc_tablets_cnt), K(err_tablets_cnt), K_(wait_gc_tablets_cnt)); + } + all_tablet_cleaned = (0 == ATOMIC_LOAD(&wait_gc_tablets_cnt_)); } return ret; } -int ObTenantMetaMemMgr::gc_min_minor_sstable_in_set() +void *ObTenantMetaMemMgr::recycle_tablet(ObTablet *tablet, TabletBufferList *header) +{ + void *free_obj = nullptr; + const bool need_free_obj = nullptr != header ? true : false; + tablet->dec_macro_ref_cnt(); + ObIAllocator *allocator = tablet->get_allocator(); + if (OB_ISNULL(allocator)) { + if (need_free_obj) { + ObMetaObjBufferHelper::del_meta_obj(tablet); + free_obj = ObMetaObjBufferHelper::get_meta_obj_buffer_ptr(reinterpret_cast(tablet)); + SpinWLockGuard guard(wash_lock_); + header->remove(static_cast(free_obj)); + } else { + release_tablet(tablet); + } + } else { + full_tablet_creator_.free_tablet(tablet); + } + return free_obj; +} + +int ObTenantMetaMemMgr::get_min_end_scn_for_ls( + const ObTabletMapKey &key, + SCN &min_end_scn_from_latest, + SCN &min_end_scn_from_old) { int ret = OB_SUCCESS; - common::ObArray need_remove_infos; - int64_t gc_table_cnt = 0; - { - SpinWLockGuard guard(sstable_set_lock_); - SSTableSet::const_iterator iter = last_min_minor_sstable_set_.begin(); - while (OB_SUCC(ret) && iter != last_min_minor_sstable_set_.end()) { - const MinMinorSSTableInfo &info = iter->first; - if (OB_UNLIKELY(!info.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("unexpected error, info is invalid", K(ret), K(info)); - } else if (1 == info.sstable_handle_.get_table()->get_ref()) { - if (OB_FAIL(need_remove_infos.push_back(&info))) { - LOG_WARN("fail to push back info need to remove", K(ret), K(info)); + ObArenaAllocator allocator; + ObTabletHandle handle; + min_end_scn_from_latest.set_max(); + min_end_scn_from_old.set_max(); + 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(get_tablet_with_allocator(WashTabletPriority::WTP_LOW, key, allocator, handle))) { + LOG_WARN("fail to get latest tablet", K(ret), K(key)); + } else if (OB_UNLIKELY(!handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid tablet handle", K(ret), K(key), K(handle)); + } else if (OB_FAIL(get_min_end_scn_from_single_tablet( + handle.get_obj(), false/*is_old*/, min_end_scn_from_latest))) { + LOG_WARN("fail to get min end scn from latest tablet", K(ret), K(key), K(handle)); + } else { + // get_ls_min_end_scn_in_latest_tablets must before get_ls_min_end_scn_in_old_tablets + const ObTabletPointerHandle &ptr_handle = handle.get_obj()->get_pointer_handle(); + ObTabletPointer *tablet_ptr = static_cast(ptr_handle.get_resource_ptr()); + ObTablet *tablet = nullptr; + ObBucketHashRLockGuard lock_guard(bucket_lock_, key.hash()); // lock old_version_chain + if (OB_ISNULL(tablet_ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet ptr is NULL", K(ret), K(ptr_handle)); + } else if (OB_ISNULL(tablet = tablet_ptr->old_version_chain_)) { // skip + } else { + // since the last tablet may not be the oldest, we traverse the wholo chain + while (OB_SUCC(ret) && OB_NOT_NULL(tablet)) { + if (OB_FAIL(get_min_end_scn_from_single_tablet(tablet, true/*is_old*/, min_end_scn_from_old))) { + LOG_WARN("fail to get min end scn from old tablet", K(ret), KP(tablet)); + } else { + tablet = tablet->get_next_tablet(); } } - ++iter; - } - } - if (OB_SUCC(ret) && need_remove_infos.count() > 0) { - for (int64_t i = 0; OB_SUCC(ret) && i < need_remove_infos.count(); ++i) { - SpinWLockGuard guard(sstable_set_lock_); - if (OB_FAIL(last_min_minor_sstable_set_.erase_refactored(*need_remove_infos.at(i)))) { - LOG_WARN("fail to erase info from last min minor sstable set", K(ret), K(i), "info", - *need_remove_infos.at(i)); - } else { - gc_table_cnt++; - } - } - if (gc_table_cnt > 0) { - FLOG_INFO("gc min minor sstable in set", K(ret), K(gc_table_cnt)); } } return ret; } -int ObTenantMetaMemMgr::acquire_sstable(ObTableHandleV2 &handle) +int ObTenantMetaMemMgr::get_min_end_scn_from_single_tablet( + ObTablet *tablet, const bool is_old, SCN &min_end_scn) { int ret = OB_SUCCESS; - ObSSTable *sstable = nullptr; - handle.reset(); + ObTabletMemberWrapper table_store_wrapper; + if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "tablet is nullptr.", K(ret), KP(this)); + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else { + ObITable *first_minor_mini_sstable = + table_store_wrapper.get_member()->get_minor_sstables().get_boundary_table(false /*is_last*/); + ObITable *last_major_sstable = nullptr; + + SCN end_scn = SCN::max_scn(); + if (OB_NOT_NULL(first_minor_mini_sstable)) { + // step 1 : get end_scn if minor/mini sstable exist + end_scn = first_minor_mini_sstable->get_end_scn(); + } else if (is_old) { + /* If an old tablet has no minor sstable, it means that all the data inside it has been assigned version numbers, + and therefore it does not depend on trx data. + Thus, it's only necessary to focus on the recycle scn provided by the latest tablet. */ + } else if (OB_NOT_NULL(last_major_sstable = + table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true /*is_last*/))) { + // step 2 : if minor/mini sstable do not exist, get end_scn from major sstable + end_scn = last_major_sstable->get_end_scn(); + } else { + // step 3 : if minor/major sstable do not exist, get end_scn from tablet clog_checkpoint + end_scn = tablet->get_tablet_meta().clog_checkpoint_scn_; + } + min_end_scn = MIN(end_scn, min_end_scn); + } + return ret; +} + +int ObTenantMetaMemMgr::get_min_mds_ckpt_scn(const ObTabletMapKey &key, share::SCN &scn) +{ + int ret = OB_SUCCESS; + SCN min_scn_from_old_tablets = SCN::max_scn(); + SCN min_scn_from_cur_tablet = SCN::max_scn(); + ObArenaAllocator allocator; + ObTabletHandle handle; + if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObTenantMetaMemMgr hasn't been initialized", K(ret)); - } else if (OB_FAIL(sstable_pool_.acquire(sstable))) { - LOG_WARN("fail to acquire sstable object", K(ret)); - // sstable may not be major, table_type here is only used to distinguish obj pool - } else if (OB_FAIL(handle.set_table(sstable, this, ObITable::TableType::MAJOR_SSTABLE))) { - LOG_WARN("fail to set table", K(ret), KP(sstable)); + } else if (OB_FAIL(get_tablet_with_allocator(WashTabletPriority::WTP_LOW, key, allocator, handle))) { + LOG_WARN("fail to get latest tablet", K(ret), K(key)); } else { - sstable = nullptr; - } - - if (OB_FAIL(ret)) { - handle.reset(); - if (OB_NOT_NULL(sstable)) { - release_sstable(sstable); + // since cur_tablet may be added into old_chain, we must get it at first + min_scn_from_cur_tablet = handle.get_obj()->get_tablet_meta().mds_checkpoint_scn_; + const ObTabletPointerHandle &ptr_handle = handle.get_obj()->get_pointer_handle(); + ObTabletPointer *tablet_ptr = static_cast(ptr_handle.get_resource_ptr()); + ObBucketHashRLockGuard lock_guard(bucket_lock_, key.hash()); // lock old_version_chain + 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->get_min_mds_ckpt_scn(min_scn_from_old_tablets))) { + LOG_WARN("fail to get min mds ckpt scn from old tablets", K(ret), K(key)); + } else { + scn = MIN(min_scn_from_cur_tablet, min_scn_from_old_tablets); + LOG_TRACE("get min mds ckpt scn", K(ret), K(key), + K(scn), K(min_scn_from_cur_tablet), K(min_scn_from_old_tablets)); } } return ret; } -int ObTenantMetaMemMgr::acquire_sstable(ObTableHandleV2 &handle, common::ObIAllocator &allocator) -{ - int ret = OB_SUCCESS; - handle.reset(); - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("ObTenantMetaMemMgr hasn't been initialized", K(ret)); - } else if (OB_UNLIKELY(is_used_obj_pool(&allocator))) { - if (OB_FAIL(acquire_sstable(handle))) { - LOG_WARN("fail to acquire sstable", K(ret)); - } - } else { - void *buf = nullptr; - if (OB_ISNULL(buf = allocator.alloc(sizeof(ObSSTable)))) { - LOG_WARN("fail to acquire sstable object", K(ret)); - } else { - ObSSTable *sstable = new (buf) ObSSTable(); - if (OB_FAIL(handle.set_table(sstable, &allocator))) { - LOG_WARN("sstable is null", K(ret)); - } - } - if (OB_FAIL(ret)) { - handle.reset(); - if (OB_NOT_NULL(buf)) { - static_cast(buf)->~ObSSTable(); - allocator.free(buf); - buf = nullptr; - } - } - } - return ret; -} - -void ObTenantMetaMemMgr::release_sstable(ObSSTable *sstable) -{ - if (OB_NOT_NULL(sstable)) { - if (0 != sstable->get_ref()) { - LOG_ERROR_RET(OB_ERR_UNEXPECTED, "ObSSTable reference count may be leak", KPC(sstable)); - } else { - sstable_pool_.release(sstable); - } - } -} - int ObTenantMetaMemMgr::acquire_ddl_kv(ObTableHandleV2 &handle) { int ret = OB_SUCCESS; @@ -860,6 +1020,7 @@ int ObTenantMetaMemMgr::acquire_tablet_ddl_kv_mgr(ObDDLKvMgrHandle &handle) int ret = OB_SUCCESS; ObMetaObj meta_obj; meta_obj.pool_ = &tablet_ddl_kv_mgr_pool_; + meta_obj.t3m_ = this; handle.reset(); if (OB_UNLIKELY(!is_inited_)) { @@ -956,80 +1117,28 @@ void ObTenantMetaMemMgr::release_lock_memtable_(ObLockMemtable *memtable) } } -int ObTenantMetaMemMgr::get_allocator_info(common::ObIArray &info) const +void ObTenantMetaMemMgr::mark_mds_table_deleted_(const ObTabletMapKey &key) { int ret = OB_SUCCESS; - ObTenantMetaMemStatus mem_status; - STRNCPY(mem_status.name_, "ALLOCATOR", mem_status.STRING_LEN); - mem_status.each_obj_size_ = 0; - mem_status.free_obj_cnt_ = 0; - mem_status.used_obj_cnt_ = 0; - mem_status.total_size_ = allocator_.total(); - mem_status.used_size_ = allocator_.used(); - if (OB_FAIL(info.push_back(mem_status))) { - LOG_WARN("fail to push mem status to info array", K(ret), K(mem_status)); - } - return ret; -} - -int ObTenantMetaMemMgr::acquire_tablet( - const WashTabletPriority &priority, - const ObTabletMapKey &key, - ObLSHandle &ls_handle, - ObTabletHandle &tablet_handle, - const bool only_acquire) -{ - int ret = OB_SUCCESS; - ObMetaObj meta_obj; - meta_obj.pool_ = &tablet_pool_; - tablet_handle.reset(); - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("ObTenantMetaMemMgr hasn't been initialized", K(ret)); - } else if (OB_UNLIKELY(!key.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(key)); - } else if (OB_FAIL(tablet_pool_.acquire(meta_obj.ptr_))) { - LOG_WARN("fail to acquire object", K(ret)); - } else if (OB_ISNULL(meta_obj.ptr_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet is nullptr", K(ret), K(meta_obj)); + ObTabletPointerHandle ptr_handle(tablet_map_); + if (OB_FAIL(tablet_map_.get(key, ptr_handle))) { + LOG_WARN_RET(OB_ERR_UNEXPECTED, "fail to get pointer from map", KR(ret), KPC(ptr_handle.get_resource_ptr())); } else { - tablet_handle.set_obj(meta_obj); - tablet_handle.set_wash_priority(priority); - meta_obj.ptr_ = nullptr; - bool is_exist = false; - ObBucketHashWLockGuard lock_guard(bucket_lock_, key.hash()); - if (OB_FAIL(has_tablet(key, is_exist))) { - LOG_WARN("fail to check tablet existence", K(ret), K(key)); - } else if (is_exist || only_acquire) { - ObTabletPointerHandle ptr_handle(tablet_map_); - if (OB_FAIL(tablet_map_.set_attr_for_obj(key, tablet_handle))) { - LOG_WARN("fail to set attribute for tablet", K(ret), K(key), K(tablet_handle)); - } else if (OB_FAIL(tablet_map_.get(key, ptr_handle))) { - LOG_WARN("fail to get tablet pointer handle", K(ret), K(key), K(tablet_handle)); - } else if (OB_FAIL(tablet_handle.get_obj()->assign_pointer_handle(ptr_handle))) { - LOG_WARN("fail to set tablet pointer handle for tablet", K(ret), K(key)); - } - } else if (OB_FAIL(create_tablet(key, ls_handle, tablet_handle))) { - LOG_WARN("fail to create tablet in map", K(ret), K(key), K(tablet_handle)); + if (OB_ISNULL(ptr_handle.get_resource_ptr())) { + LOG_ERROR_RET(OB_ERR_UNEXPECTED, "ptr_handle is null", KPC(ptr_handle.get_resource_ptr())); + } else { + ObTabletPointer *tablet_pointer = static_cast(ptr_handle.get_resource_ptr()); + tablet_pointer->mark_mds_table_deleted(); } } - if (OB_FAIL(ret)) { - tablet_handle.reset(); - if (OB_NOT_NULL(meta_obj.ptr_)) { - release_tablet(meta_obj.ptr_); - } - } - return ret; } -int ObTenantMetaMemMgr::acquire_tablet( +int ObTenantMetaMemMgr::create_tmp_tablet( const WashTabletPriority &priority, const ObTabletMapKey &key, - common::ObIAllocator &allocator, - ObTabletHandle &tablet_handle, - const bool only_acquire) + common::ObArenaAllocator &allocator, + ObLSHandle &ls_handle, + ObTabletHandle &tablet_handle) { int ret = OB_SUCCESS; void *buf = nullptr; @@ -1044,13 +1153,50 @@ int ObTenantMetaMemMgr::acquire_tablet( ret = OB_ALLOCATE_MEMORY_FAILED; STORAGE_LOG(WARN, "fail to allocate memory", K(ret), KP(buf)); } else { - tablet_handle.set_obj(new (buf) ObTablet(), &allocator); + tablet_handle.set_obj(new (buf) ObTablet(), &allocator, this); tablet_handle.set_wash_priority(priority); + tablet_handle.get_obj()->set_allocator(&allocator); + tablet_handle.disallow_copy_and_assign(); bool is_exist = false; ObBucketHashWLockGuard lock_guard(bucket_lock_, key.hash()); if (OB_FAIL(has_tablet(key, is_exist))) { LOG_WARN("fail to check tablet existence", K(ret), K(key)); - } else if (is_exist || only_acquire) { + } else if (is_exist) { + ret = OB_ENTRY_EXIST; + LOG_WARN("This tablet pointer has exist, and don't create again", K(ret), K(key), K(is_exist)); + } else if (OB_FAIL(create_tablet(key, ls_handle, tablet_handle))) { + LOG_WARN("fail to create tablet in map", K(ret), K(key), K(tablet_handle)); + } + } + if (OB_FAIL(ret)) { + tablet_handle.reset(); + } + return ret; +} + +int ObTenantMetaMemMgr::acquire_tablet_from_pool( + const ObTabletPoolType &type, + const WashTabletPriority &priority, + const ObTabletMapKey &key, + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + 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() || type >= ObTabletPoolType::TP_MAX)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(key), K(type)); + } else if (OB_FAIL(acquire_tablet(type, tablet_handle))) { + LOG_WARN("fail to acquire tablet", K(ret), K(type)); + } else { + tablet_handle.set_wash_priority(priority); + LOG_DEBUG("acquire tablet from pool", K(tablet_handle)); + bool is_exist = false; + ObBucketHashWLockGuard lock_guard(bucket_lock_, key.hash()); + if (OB_FAIL(has_tablet(key, is_exist))) { + LOG_WARN("fail to check tablet existence", K(ret), K(key)); + } else if (is_exist) { ObTabletPointerHandle ptr_handle(tablet_map_); if (OB_FAIL(tablet_map_.set_attr_for_obj(key, tablet_handle))) { LOG_WARN("fail to set attribute for tablet", K(ret), K(key), K(tablet_handle)); @@ -1060,8 +1206,209 @@ int ObTenantMetaMemMgr::acquire_tablet( LOG_WARN("fail to set tablet pointer handle for tablet", K(ret), K(key)); } } else { - ret = OB_NOT_SUPPORTED; - LOG_WARN("don't support to acquire for creating tablet", K(ret), K(key)); + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("The tablet pointer isn't exist, don't support to acquire", K(ret), K(key)); + } + } + if (OB_FAIL(ret)) { + tablet_handle.reset(); + } + return ret; +} + +int ObTenantMetaMemMgr::acquire_tablet( + const ObTabletPoolType type, + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + TabletBufferList *header = nullptr; + ObMetaObj meta_obj; + void *buf = nullptr; + meta_obj.t3m_ = this; + if (ObTabletPoolType::TP_NORMAL == type) { + meta_obj.pool_ = static_cast(&tablet_buffer_pool_); + header = &normal_tablet_header_; + } else if (ObTabletPoolType::TP_LARGE == type) { + meta_obj.pool_ = static_cast(&large_tablet_buffer_pool_); + header = &large_tablet_header_; + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported to wash", K(ret), K(type)); + } + if (FAILEDx(meta_obj.pool_->alloc_obj(buf))) { + LOG_WARN("fail to acquire tablet buffer", K(ret)); + } else if (OB_ISNULL(buf)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet buffer is nullptr", K(ret), KP(buf)); + } else { + ObMetaObjBufferHelper::new_meta_obj(buf, meta_obj.ptr_); + tablet_handle.set_obj(meta_obj); + SpinWLockGuard guard(wash_lock_); + if (OB_UNLIKELY(!header->add_last(static_cast(buf)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to add last normal tablet", K(ret), KP(buf)); + } + LOG_DEBUG("acquire tablet", K(type), K(meta_obj)); + } + return ret; +} + +int ObTenantMetaMemMgr::acquire_tablet(ObITenantMetaObjPool *pool, ObTablet *&tablet) +{ + int ret = OB_SUCCESS; + TabletBufferList *header = nullptr; + void *buf = nullptr; + tablet = nullptr; + if (OB_ISNULL(pool)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(pool)); + } else if (static_cast *>(pool) == &tablet_buffer_pool_) { + header = &normal_tablet_header_; + } else if (static_cast *>(pool) == &large_tablet_buffer_pool_) { + header = &large_tablet_header_; + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported to wash", K(ret), KP(pool)); + } + if (FAILEDx(pool->alloc_obj(buf))) { + LOG_WARN("fail to acquire tablet buffer", K(ret)); + } else if (OB_ISNULL(buf)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet buffer is nullptr", K(ret), KP(buf)); + } else { + ObMetaObjBufferHelper::new_meta_obj(buf, tablet); + SpinWLockGuard guard(wash_lock_); + if (OB_UNLIKELY(!header->add_last(static_cast(buf)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to add last normal tablet", K(ret), KP(buf)); + } + LOG_DEBUG("acquire tablet", KP(pool), KP(tablet)); + } + return ret; +} + +int ObTenantMetaMemMgr::acquire_tmp_tablet( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + common::ObArenaAllocator &allocator, + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + tablet_handle.reset(); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantMetaMemMgr hasn't been initialized", K(ret)); + } else if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(key)); + } else if (OB_ISNULL(buf = allocator.alloc(sizeof(ObTablet)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "fail to allocate memory", K(ret), KP(buf)); + } else { + tablet_handle.set_obj(new (buf) ObTablet(), &allocator, this); + tablet_handle.set_wash_priority(priority); + tablet_handle.get_obj()->set_allocator(&allocator); + tablet_handle.disallow_copy_and_assign(); + bool is_exist = false; + ObBucketHashWLockGuard lock_guard(bucket_lock_, key.hash()); + if (OB_FAIL(has_tablet(key, is_exist))) { + LOG_WARN("fail to check tablet existence", K(ret), K(key)); + } else if (is_exist) { + ObTabletPointerHandle ptr_handle(tablet_map_); + if (OB_FAIL(tablet_map_.set_attr_for_obj(key, tablet_handle))) { + LOG_WARN("fail to set attribute for tablet", K(ret), K(key), K(tablet_handle)); + } else if (OB_FAIL(tablet_map_.get(key, ptr_handle))) { + LOG_WARN("fail to get tablet pointer handle", K(ret), K(key), K(tablet_handle)); + } else if (OB_FAIL(tablet_handle.get_obj()->assign_pointer_handle(ptr_handle))) { + LOG_WARN("fail to set tablet pointer handle for tablet", K(ret), K(key)); + } + } else { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("The tablet pointer isn't exist, don't support to acquire", K(ret), K(key)); + } + } + if (OB_FAIL(ret)) { + tablet_handle.reset(); + } + return ret; +} + +int ObTenantMetaMemMgr::create_msd_tablet( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + ObLSHandle &ls_handle, + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + tablet_handle.reset(); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantMetaMemMgr hasn't been initialized", K(ret)); + } else if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(key)); + } else if (OB_FAIL(full_tablet_creator_.create_tablet(tablet_handle))) { + LOG_WARN("fail to create tablet", K(ret), K(key), K(tablet_handle)); + } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, tablet handle isn't valid", K(ret), K(tablet_handle)); + } else { + tablet_handle.set_wash_priority(priority); + bool is_exist = false; + ObBucketHashWLockGuard lock_guard(bucket_lock_, key.hash()); + if (OB_FAIL(has_tablet(key, is_exist))) { + LOG_WARN("fail to check tablet existence", K(ret), K(key)); + } else if (OB_UNLIKELY(is_exist)) { + ret = OB_ENTRY_EXIST; + LOG_WARN("This tablet pointer has exist, and don't create again", K(ret), K(key), K(is_exist)); + } else if (OB_FAIL(create_tablet(key, ls_handle, tablet_handle))) { + LOG_WARN("fail to create tablet in map", K(ret), K(key), K(tablet_handle)); + } + } + if (OB_FAIL(ret)) { + tablet_handle.reset(); + } + return ret; +} + +int ObTenantMetaMemMgr::acquire_msd_tablet( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + tablet_handle.reset(); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantMetaMemMgr hasn't been initialized", K(ret)); + } else if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(key)); + } else if (OB_FAIL(full_tablet_creator_.create_tablet(tablet_handle))) { + LOG_WARN("fail to create tablet", K(ret), K(key), K(tablet_handle)); + } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, tablet handle isn't valid", K(ret), K(tablet_handle)); + } else { + tablet_handle.set_wash_priority(priority); + bool is_exist = false; + ObBucketHashWLockGuard lock_guard(bucket_lock_, key.hash()); + if (OB_FAIL(has_tablet(key, is_exist))) { + LOG_WARN("fail to check tablet existence", K(ret), K(key)); + } else if (is_exist) { + ObTabletPointerHandle ptr_handle(tablet_map_); + if (OB_FAIL(tablet_map_.set_attr_for_obj(key, tablet_handle))) { + LOG_WARN("fail to set attribute for tablet", K(ret), K(key), K(tablet_handle)); + } else if (OB_FAIL(tablet_map_.get(key, ptr_handle))) { + LOG_WARN("fail to get tablet pointer handle", K(ret), K(key), K(tablet_handle)); + } else if (OB_FAIL(tablet_handle.get_obj()->assign_pointer_handle(ptr_handle))) { + LOG_WARN("fail to set tablet pointer handle for tablet", K(ret), K(key)); + } + } else { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("The tablet pointer isn't exist, don't support to acquire", K(ret), K(key)); } } if (OB_FAIL(ret)) { @@ -1105,7 +1452,8 @@ int ObTenantMetaMemMgr::create_tablet( ObMetaDiskAddr addr; addr.set_none_addr(); tablet_ptr.set_addr_with_reset_obj(addr); - + // After restarting and replaying the slog, the tablet will load the pool when it is accessed for the first time. + tablet_ptr.obj_.pool_ = &tablet_buffer_pool_; if (OB_FAIL(tablet_map_.set(key, tablet_ptr))) { LOG_WARN("fail to set tablet pointer", K(ret), K(key)); } else if (OB_FAIL(tablet_map_.set_attr_for_obj(key, tablet_handle))) { @@ -1118,9 +1466,11 @@ int ObTenantMetaMemMgr::create_tablet( if (OB_FAIL(ret)) { int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(tablet_map_.erase(key, allocator_))) { + ObTabletHandle handle; + if (OB_TMP_FAIL(tablet_map_.erase(key, handle))) { LOG_WARN("fail to erase tablet pointer", K(tmp_ret), K(key)); } + handle.set_wash_priority(WashTabletPriority::WTP_LOW); } } return ret; @@ -1139,7 +1489,7 @@ int ObTenantMetaMemMgr::get_tablet( } else if (OB_UNLIKELY(!key.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(key)); - } else if (OB_FAIL(tablet_map_.get_meta_obj(key, allocator_, handle))) { + } else if (OB_FAIL(tablet_map_.get_meta_obj(key, handle))) { if (OB_ENTRY_NOT_EXIST != ret && OB_ITEM_NOT_SETTED != ret) { LOG_WARN("fail to get tablet", K(ret), K(key)); } @@ -1155,7 +1505,7 @@ int ObTenantMetaMemMgr::get_tablet( int ObTenantMetaMemMgr::get_tablet_with_allocator( const WashTabletPriority &priority, const ObTabletMapKey &key, - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, ObTabletHandle &handle, const bool force_alloc_new) { @@ -1164,18 +1514,67 @@ int ObTenantMetaMemMgr::get_tablet_with_allocator( 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() || is_used_obj_pool(&allocator))) { + } else if (OB_UNLIKELY(!key.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(key), KP(&allocator), KP(&allocator_)); + LOG_WARN("invalid argument", K(ret), K(key), KP(&allocator)); } else if (OB_FAIL(tablet_map_.get_meta_obj_with_external_memory(key, allocator, handle, force_alloc_new))) { if (OB_ENTRY_NOT_EXIST != ret) { LOG_WARN("fail to get tablet", K(ret), K(key)); } - } else if (OB_ISNULL(handle.get_obj())) { + } else if (OB_UNLIKELY(!handle.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet is null", K(ret), K(key), K(handle)); } else { handle.set_wash_priority(priority); + if (OB_NOT_NULL(handle.get_allocator())) { + handle.disallow_copy_and_assign(); + handle.get_obj()->set_allocator(handle.get_allocator()); + } + } + return ret; +} + +int ObTenantMetaMemMgr::get_tablet_buffer_infos( + const ObTabletPoolType &pool_type, + ObIArray &buffer_infos) +{ + int ret = OB_SUCCESS; + int64_t size = 0; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantMetaMemMgr hasn't been initialized", K(ret)); + } else { + ObMetaObjBufferNode *tablet_buffer_node = nullptr; + ObMetaObjBufferNode *header = nullptr; + SpinRLockGuard guard(wash_lock_); + if (pool_type == ObTabletPoolType::TP_LARGE) { + tablet_buffer_node = large_tablet_header_.get_first(); + header = large_tablet_header_.get_header(); + size = large_tablet_header_.get_size(); + } else if (pool_type == ObTabletPoolType::TP_NORMAL) { + tablet_buffer_node = normal_tablet_header_.get_first(); + header = normal_tablet_header_.get_header(); + size = normal_tablet_header_.get_size(); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet pool type is invalid", K(ret), K(pool_type)); + } + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(buffer_infos.reserve(size))) { + LOG_WARN("fail to reserve memory for buffer_infos", K(ret), K(size)); + } else { + while (OB_SUCC(ret) && header != tablet_buffer_node) { + ObTabletBufferInfo buffer_info; + if (OB_FAIL(buffer_info.fill_info(pool_type, tablet_buffer_node))) { + LOG_WARN("fail to fill tablet buffer info", K(ret)); + } else if (OB_FAIL(buffer_infos.push_back(buffer_info))) { + LOG_WARN("fail to push back buffer info", K(ret), K(buffer_info)); + } else { + tablet_buffer_node = tablet_buffer_node->get_next(); + } + } + } } return ret; } @@ -1195,9 +1594,7 @@ int ObTenantMetaMemMgr::get_tablet_addr(const ObTabletMapKey &key, ObMetaDiskAdd return ret; } -int ObTenantMetaMemMgr::get_tablet_pointer_tx_data( - const ObTabletMapKey &key, - ObTabletTxMultiSourceDataUnit &tx_data) +int ObTenantMetaMemMgr::get_tablet_pointer_initial_state(const ObTabletMapKey &key, bool &initial_state) { int ret = OB_SUCCESS; ObTabletPointerHandle ptr_handle(tablet_map_); @@ -1214,8 +1611,8 @@ int ObTenantMetaMemMgr::get_tablet_pointer_tx_data( 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->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data in tablet pointer", K(ret), K(key)); + } else { + initial_state = tablet_ptr->get_initial_state(); } } return ret; @@ -1267,12 +1664,12 @@ int ObTenantMetaMemMgr::get_meta_mem_status(common::ObIArrayget_allocator())) { + ObMetaObjBufferHelper::set_in_map(reinterpret_cast(handle.get_obj()), false/*in_map*/); + } + LOG_DEBUG("succeed to delete tablet", K(ret), K(key)); + } + handle.set_wash_priority(WashTabletPriority::WTP_LOW); + } + if (OB_SUCC(ret) && handle.is_valid()) { /* do not get t3m::lock when remove from queue */ + if (OB_FAIL(full_tablet_creator_.remove_tablet_from_queue(handle))) { + LOG_WARN("failed to remove tablet from full queue", K(ret), K(key), K(handle)); + } } return ret; } int ObTenantMetaMemMgr::compare_and_swap_tablet( const ObTabletMapKey &key, - const ObMetaDiskAddr &new_addr, const ObTabletHandle &old_handle, ObTabletHandle &new_handle) { int ret = OB_SUCCESS; - bool is_exist = false; + const ObMetaDiskAddr &new_addr = new_handle.get_obj()->get_tablet_addr(); + const ObTablet *old_tablet = old_handle.get_obj(); + const ObTablet *new_tablet = new_handle.get_obj(); 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() || !new_addr.is_valid() - || new_addr.is_none() + || !new_handle.is_valid() || !old_handle.is_valid() - || !new_handle.is_valid())) { + || new_handle.is_tmp_tablet() + // TODO jingzhu : uncomment following code + // || !(new_addr.is_memory() || new_addr.is_block()) + )) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(key), K(new_addr), K(old_handle), K(new_handle)); } else { ObBucketHashWLockGuard lock_guard(bucket_lock_, key.hash()); - if (OB_FAIL(has_tablet(key, is_exist))) { - LOG_WARN("fail to check tablet is exist", K(ret), K(key)); - } else if (OB_UNLIKELY(!is_exist)) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("this tablet does not exist in map", K(ret), K(key), K(is_exist)); - } else if (OB_FAIL(tablet_map_.compare_and_swap_address_and_object(key, - new_addr, - old_handle, - new_handle))) { - LOG_WARN("fail to replace tablet in map", K(ret), K(key), K(new_addr), K(old_handle), - K(new_handle)); - } else if (old_handle.get_obj() != new_handle.get_obj()) { - ObTabletTableStore &table_store = old_handle.get_obj()->get_table_store(); - ObITable *sstable = table_store.get_minor_sstables().get_boundary_table(false /*is_last*/); - if (OB_NOT_NULL(sstable)) { - ObTableHandleV2 table_handle(sstable, this, ObITable::TableType::MAJOR_SSTABLE); - do { - if (OB_FAIL(record_min_minor_sstable(key.ls_id_, table_handle))) { - LOG_WARN("fail to record min minor sstable", K(ret), K(key), K(table_handle)); - usleep(1 * 1000 * 1000); - } - } while (OB_ALLOCATE_MEMORY_FAILED == ret); + if (OB_FAIL(tablet_map_.compare_and_swap_addr_and_object(key, new_addr, old_handle, new_handle))) { + LOG_WARN("fail to compare and swap tablet", K(ret), K(key), K(new_addr), K(old_handle), K(new_handle)); + } else if (OB_FAIL(update_tablet_buffer_header(old_handle.get_obj(), new_handle.get_obj()))) { + LOG_WARN("fail to update tablet buffer header", K(ret), K(old_handle), K(new_handle)); + } else if (old_handle.get_obj() != new_handle.get_obj()) { // skip first init, old_handle == new_handle + // TODO zhouxinlan.zxl update min minor sstable by link + const ObTabletPointerHandle &ptr_hdl = old_handle.get_obj()->get_pointer_handle(); + ObTabletPointer *t_ptr = nullptr; + if (OB_ISNULL(t_ptr = reinterpret_cast(ptr_hdl.get_resource_ptr()))) { + ret = common::OB_ERR_UNEXPECTED; + LOG_WARN("fail to get tablet pointer", K(ret), K(key), K(ptr_hdl)); + } else if (OB_FAIL(t_ptr->add_tablet_to_old_version_chain( + reinterpret_cast(old_handle.get_obj())))) { + LOG_WARN("fail to add tablet to old version chain", K(ret), K(key), KPC(old_tablet)); } } } if (OB_FAIL(ret)) { - } 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)); + } else { + // TODO(@bowen.gbw): Currently, the order is: + // 1. CAS operation, let the newest tablet be visible + // 2. check and set initial state on tablet pointer + // But upper layer may get tablet between step 1 and 2, which will cause that upper layer cannot + // read the newest initial state. + // Maybe we should let the two steps, CAS opereation and set initial state, be an atomic operation. + // The same issue exists on all 4.x version, and should be solved in future. + do { + // TODO(@bowen.gbw): delete the infinite retry later + if (OB_FAIL(new_handle.get_obj()->check_and_set_initial_state())) { + LOG_WARN("failed to check and set initial state", K(ret), K(key)); + } + } while (ret == OB_TIMEOUT || ret == OB_ALLOCATE_MEMORY_FAILED); } + + LOG_DEBUG("compare and swap object", K(ret), KPC(new_handle.get_obj()), K(lbt())); return ret; } -int ObTenantMetaMemMgr::compare_and_swap_tablet_pure_address_without_object( +int ObTenantMetaMemMgr::compare_and_swap_tablet( const ObTabletMapKey &key, const ObMetaDiskAddr &old_addr, const ObMetaDiskAddr &new_addr) @@ -1369,7 +1793,7 @@ int ObTenantMetaMemMgr::compare_and_swap_tablet_pure_address_without_object( 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() || !old_addr.is_disked() || !new_addr.is_disked())) { + } else if (OB_UNLIKELY(!key.is_valid() || !old_addr.is_valid() || !(new_addr.is_disked() || new_addr.is_memory()))) { ret = OB_INVALID_ARGUMENT; FLOG_WARN("invalid argument", K(ret), K(key), K(old_addr), K(new_addr)); } else { @@ -1386,17 +1810,28 @@ int ObTenantMetaMemMgr::compare_and_swap_tablet_pure_address_without_object( K(new_addr)); } } + LOG_DEBUG("compare and swap object", K(ret), K(old_addr), K(new_addr), K(lbt())); return ret; } void ObTenantMetaMemMgr::release_tablet(ObTablet *tablet) { if (OB_NOT_NULL(tablet)) { + ObMetaObjBufferNode &linked_node = ObMetaObjBufferHelper::get_linked_node(reinterpret_cast(tablet)); + ObMetaObjBufferHeader &buf_header = ObMetaObjBufferHelper::get_buffer_header(reinterpret_cast(tablet)); + void *buf = ObMetaObjBufferHelper::get_meta_obj_buffer_ptr(reinterpret_cast(tablet)); + LOG_DEBUG("release tablet", K(buf_header), KP(buf)); + SpinWLockGuard guard(wash_lock_); if (0 != tablet->get_ref()) { - LOG_ERROR_RET(OB_ERR_UNEXPECTED, "ObTablet reference count may be leak", KPC(tablet)); - } else { - tablet_pool_.release(tablet); + LOG_ERROR_RET(OB_ERR_UNEXPECTED, "ObTablet reference count may be leak", KP(tablet)); + } else if (NORMAL_TABLET_POOL_SIZE == buf_header.buf_len_) { + normal_tablet_header_.remove(&linked_node); + tablet_buffer_pool_.free_obj(buf); + } else if (LARGE_TABLET_POOL_SIZE == buf_header.buf_len_) { + large_tablet_header_.remove(&linked_node); + large_tablet_buffer_pool_.free_obj(buf); } + LOG_DEBUG("release tablet", K(buf_header.buf_len_), KP(tablet)); } } @@ -1426,30 +1861,27 @@ int ObTenantMetaMemMgr::check_all_meta_mem_released(ObLSService &ls_service, boo LOG_WARN("ObTenantMetaMemMgr hasn't been initialized", K(ret)); } else { int64_t memtable_cnt = memtable_pool_.get_used_obj_cnt(); - int64_t sstable_cnt = sstable_pool_.get_used_obj_cnt(); int64_t ddl_kv_cnt = ddl_kv_pool_.get_used_obj_cnt(); - int64_t tablet_cnt = tablet_pool_.get_used_obj_cnt(); + int64_t tablet_cnt = tablet_buffer_pool_.get_used_obj_cnt(); + int64_t large_tablet_cnt = large_tablet_buffer_pool_.get_used_obj_cnt(); int64_t ddl_kv_mgr_cnt = tablet_ddl_kv_mgr_pool_.get_used_obj_cnt(); int64_t tablet_memtable_mgr_cnt = tablet_memtable_mgr_pool_.get_used_obj_cnt(); int64_t tx_data_memtable_cnt_ = tx_data_memtable_pool_.get_used_obj_cnt(); int64_t tx_ctx_memtable_cnt_ = tx_ctx_memtable_pool_.get_used_obj_cnt(); int64_t lock_memtable_cnt_ = lock_memtable_pool_.get_used_obj_cnt(); - if (memtable_cnt != 0 || sstable_cnt != 0 || ddl_kv_cnt != 0 || tablet_cnt != 0 || ddl_kv_mgr_cnt != 0 + if (memtable_cnt != 0 || ddl_kv_cnt != 0 || tablet_cnt != 0 || 0 != large_tablet_cnt || ddl_kv_mgr_cnt != 0 || tablet_memtable_mgr_cnt != 0 || tx_data_memtable_cnt_ != 0 || tx_ctx_memtable_cnt_ != 0 || lock_memtable_cnt_ != 0) { is_released = false; } else { is_released = true; } - LOG_INFO("check all meta mem in t3m", K(module), K(is_released), K(memtable_cnt), K(sstable_cnt), K(ddl_kv_cnt), - K(tablet_cnt), K(ddl_kv_mgr_cnt), K(tablet_memtable_mgr_cnt), K(tx_data_memtable_cnt_), - K(tx_ctx_memtable_cnt_), K(lock_memtable_cnt_), - "min_minor_cnt", last_min_minor_sstable_set_.size(), - "pinned_tablet_cnt", pinned_tablet_set_.size()); + LOG_INFO("check all meta mem in t3m", K(module), K(is_released), K(memtable_cnt), K(ddl_kv_cnt), + K(tablet_cnt), K(large_tablet_cnt), K(ddl_kv_mgr_cnt), K(tablet_memtable_mgr_cnt), K(tx_data_memtable_cnt_), + K(tx_ctx_memtable_cnt_), K(lock_memtable_cnt_)); const uint64_t interval = 180 * 1000 * 1000; // 180s if (!is_released && REACH_TIME_INTERVAL(interval)) { dump_tablet(); - dump_pinned_tablet(); dump_ls(ls_service); PRINT_OBJ_LEAK(MTL_ID(), share::LEAK_CHECK_OBJ_MAX_NUM); } @@ -1463,24 +1895,20 @@ void ObTenantMetaMemMgr::dump_tablet() common::ObFunction&)> func = [](common::hash::HashMapPair &entry) { const ObTabletMapKey &key = entry.first; - FLOG_INFO("dump tablet", K(key)); + FLOG_INFO("dump tablet in map", K(key)); return OB_SUCCESS; }; if (OB_FAIL(tablet_map_.for_each_value_store(func))) { LOG_WARN("fail to traverse tablet map", K(ret)); } -} - -void ObTenantMetaMemMgr::dump_pinned_tablet() -{ - ObBucketTryRLockAllGuard try_rd_all_guard(pin_set_lock_); - int ret = try_rd_all_guard.get_ret(); - if (OB_SUCC(ret)) { - PinnedTabletSet::const_iterator iter = pinned_tablet_set_.begin(); - for (; iter != pinned_tablet_set_.end(); ++iter) { - const ObTabletMapKey &key = iter->first; - FLOG_INFO("dump pinned tablet", K(key)); - } + SpinWLockGuard guard(wash_lock_); + for (ObMetaObjBufferNode *node = normal_tablet_header_.get_first(); + node != normal_tablet_header_.get_header(); node = node->get_next()) { + FLOG_INFO("dump normal tablet buffer", KP(ObMetaObjBufferHelper::get_obj_buffer(node)), KP(node)); + } + for (ObMetaObjBufferNode *node = large_tablet_header_.get_first(); + node != large_tablet_header_.get_header(); node = node->get_next()) { + FLOG_INFO("dump large tablet buffer", KP(ObMetaObjBufferHelper::get_obj_buffer(node)), KP(node)); } } @@ -1529,372 +1957,199 @@ bool ObTenantMetaMemMgr::HeapCompare::operator() ( return bret; } -ObTenantMetaMemMgr::GetWashTabletCandidate::GetWashTabletCandidate( - Heap &heap, - common::ObIArray &mem_addr_tablets, - ObTenantMetaMemMgr &t3m, - ObIAllocator &allocator) - : heap_(heap), - mem_addr_tablets_(mem_addr_tablets), - t3m_(t3m), - allocator_(allocator), - none_addr_tablet_cnt_(0), - mem_addr_tablet_cnt_(0), - in_memory_tablet_cnt_(0), - inner_tablet_cnt_(0), - candidate_tablet_cnt_(0) -{ -} - -int ObTenantMetaMemMgr::GetWashTabletCandidate::operator()( - common::hash::HashMapPair &entry) +int ObTenantMetaMemMgr::get_wash_tablet_candidate(const std::type_info &type_info, CandidateTabletInfo &info) { int ret = OB_SUCCESS; - const ObTabletMapKey &tablet_key = entry.first; - TabletValueStore *value_store = entry.second; - ObTabletPointer *tablet_ptr = nullptr; - ObTablet *tablet = nullptr; - ObTabletHandle tablet_handle; - bool need_check = true; - - if (OB_ISNULL(value_store)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("value store is nullptr", K(ret), KP(value_store)); - } else if (OB_ISNULL(tablet_ptr = static_cast(value_store->get_value_ptr()))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet pointer is nullptr", K(ret), KP(tablet_ptr)); - } else if (tablet_ptr->get_addr().is_none()) { - ++none_addr_tablet_cnt_; - LOG_DEBUG("NONE addr tablet should not be washed", K(tablet_key)); + TabletBufferList *header = nullptr; + ObMetaObjBufferNode *curr = nullptr; + if (type_info == typeid(ObNormalTabletBuffer)) { + header = &normal_tablet_header_; + } else if (type_info == typeid(ObLargeTabletBuffer)) { + header = &large_tablet_header_; } else { - if (tablet_key.tablet_id_.is_inner_tablet()) { - ++inner_tablet_cnt_; - } else if (tablet_ptr->get_addr().is_memory()) { - ++mem_addr_tablet_cnt_; - } - if (tablet_ptr->is_in_memory()) { - ++in_memory_tablet_cnt_; - if (OB_FAIL(tablet_ptr->get_in_memory_obj(tablet_handle))) { - LOG_WARN("fail to get object", K(ret)); - } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet is nullptr", K(ret), KP(tablet)); - } else { - int tmp_ret = t3m_.exist_pinned_tablet(tablet_key); - if (OB_HASH_EXIST == tmp_ret) { - need_check = false; - LOG_DEBUG("tablet is in tx, should no be washed", K(tmp_ret), K(tablet_key)); - } else if (OB_HASH_NOT_EXIST == tmp_ret) { - } else { - ret = tmp_ret; - LOG_WARN("failed to check whether tablet is in tx", K(ret), K(tablet_key)); - } - } - - if (OB_FAIL(ret)) { - } else if (!need_check) { - // no need to check - } else if (2 == tablet->get_ref()) { - if (tablet_ptr->get_addr().is_memory()) { - InMemoryPinnedTabletInfo info; - info.key_ = tablet_key; - info.addr_ = tablet_ptr->get_addr(); - info.wash_score_ = tablet_handle.get_obj()->get_wash_score(); - if (OB_FAIL(mem_addr_tablets_.push_back(info))) { - LOG_WARN("fail to push back into in memory pinned tablet info", K(ret), K(info), K(tablet_key)); - } - } else { - // this tablet is hold by tablet_handle here and the tablet_map_ only + ret = OB_NOT_SUPPORTED; + STORAGE_LOG(WARN, "not supported to wash", K(ret), "type:", type_info.name()); + } + if (OB_SUCC(ret)) { + CandidateTabletInfo min; + min.wash_score_ = INT64_MAX; + for (curr = header->get_first(); + OB_SUCC(ret) && curr != header->get_header() && curr != nullptr; + curr = curr->get_next()) { + if (curr->get_data().has_new_) { + ObTablet *tablet = reinterpret_cast(ObMetaObjBufferHelper::get_obj_buffer(curr)); + const ObTabletMeta &tablet_meta = tablet->get_tablet_meta(); + const ObTabletMapKey tablet_key(tablet_meta.ls_id_, tablet_meta.tablet_id_); + if (1 == tablet->get_ref() && ObMetaObjBufferHelper::is_in_map(reinterpret_cast(tablet))) { + // While hope to wash normal buffer pool, we need to skip rebuild next tablet, which may be oversub macro ref cnt. + const bool need_skip = type_info == typeid(ObNormalTabletBuffer) && tablet->get_next_tablet_guard().is_valid(); + // this tablet is only hold by tablet map. CandidateTabletInfo candidate; candidate.ls_id_ = tablet_key.ls_id_.id(); candidate.tablet_id_ = tablet_key.tablet_id_.id(); candidate.wash_score_ = tablet->get_wash_score(); - if (OB_FAIL(heap_.push(candidate))) { - LOG_WARN("fail to push candidate tablet", K(ret), K(candidate)); - } else if (OB_SUCCESS != t3m_.cmp_ret_) { - ret = t3m_.cmp_ret_; - LOG_WARN("fail to add tablet pointer into heap", K(ret), K(candidate)); - } else { - ++candidate_tablet_cnt_; + LOG_DEBUG("get wash candidate", K(candidate)); + if (need_skip) { + // just skip, nothing to do. + } else if (candidate.wash_score_ < 0 + || (candidate.wash_score_ > 0 && (ObTimeUtility::current_time_ns() - candidate.wash_score_ > 1000000000))) { + info = candidate; + break; + } else if (candidate.wash_score_ < min.wash_score_) { + min = candidate; } } } } - } - return ret; -} - -void *ObTenantMetaMemMgr::TenantMetaAllocator::alloc_align( - const int64_t size, - const int64_t align) -{ - int ret = OB_SUCCESS; - void *ptr = nullptr; - const int64_t max_wait_ts = ObTimeUtility::fast_current_time() + 1000L * 1000L * 3L; // 3s - while (OB_ISNULL(ptr = ObFIFOAllocator::alloc_align(size, align)) - && OB_SUCC(ret) - && max_wait_ts - ObTimeUtility::fast_current_time() >= 0) { - ob_usleep(1); - if (OB_FAIL(wash_func_())) { - LOG_WARN("wash function fail", K(ret), K(size), K(align)); - } - } - return ptr; -} - -int ObTenantMetaMemMgr::try_wash_tablet() -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init ObTenantMetaMemMgr", K(ret)); - } else { - ObTimeGuard wash_time("wash_tablet_profiling"); - SpinWLockGuard guard(wash_lock_); - wash_time.click("wait_lock"); - const int64_t wash_cnt = max(1, calc_wash_tablet_cnt()); - if (OB_FAIL(try_wash_tablet(wash_cnt))) { - LOG_WARN("fail to try wash tablet", K(ret), K(wash_cnt)); - } - wash_time.click("do_wash"); - if (wash_time.get_diff() > 1 * 1000 * 1000) {// 1s - LOG_INFO("try_wash_tablet too much time", K(ret), K(wash_cnt), K(wash_time)); - } - } - return ret; -} - -int64_t ObTenantMetaMemMgr::calc_wash_tablet_cnt() const -{ - const int64_t used_tablet_cnt = tablet_pool_.get_used_obj_cnt(); - const double variable_mem_fragment_ratio = std::round(((allocator_.total() * 1.0) / allocator_.used()) * 10000) / 10000; - const int64_t wash_cnt = min(variable_mem_fragment_ratio > 3.75 ? INT64_MAX : static_cast(used_tablet_cnt * 0.2), 30000); - FLOG_INFO("calculate wash tablet count", K(wash_cnt), K(variable_mem_fragment_ratio), K(used_tablet_cnt)); - return wash_cnt; -} - -int ObTenantMetaMemMgr::write_slog_and_wash_tablet( - const ObTabletMapKey &key, - const ObMetaDiskAddr &old_addr, - bool &is_wash) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init ObTenantMetaMemMgr", K(ret)); - } else if (OB_UNLIKELY(!key.is_valid() || !old_addr.is_valid() || !old_addr.is_memory())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(key), K(old_addr)); - } else { - common::ObFunction &, ObMetaDiskAddr &)> dump = - [](const ObMetaObjGuard &handle, ObMetaDiskAddr &disk_addr) -> int { - ObTabletHandle tablet_handle = handle; - tablet_handle.set_wash_priority(WashTabletPriority::WTP_LOW); - return ObTabletSlogHelper::write_create_tablet_slog(handle, disk_addr); - }; - if (OB_FAIL(tablet_map_.wash_meta_obj_with_func(key, old_addr, dump, is_wash))) { - LOG_WARN("fail to wash meta object with function", K(ret), K(key), K(old_addr)); + if (OB_SUCC(ret)) { + if (info.is_valid()) { + // do nothing. + } else if (!info.is_valid() && min.is_valid()) { + info = min; + } else { + ret = OB_ITER_END; + LOG_WARN("Don't find one candidate", K(ret)); + } } } return ret; } int ObTenantMetaMemMgr::do_wash_candidate_tablet( - const int64_t expect_wash_cnt, - Heap &heap, - int64_t &wash_inner_cnt, - int64_t &wash_user_cnt) + const CandidateTabletInfo &candidate, + ObTabletHandle &handle, + void *&free_obj) { int ret = OB_SUCCESS; - bool is_wash = false; - while (OB_SUCC(ret) && !heap.empty() && wash_user_cnt + wash_inner_cnt < expect_wash_cnt) { - const CandidateTabletInfo &candidate = heap.top(); - const ObLSID ls_id(candidate.ls_id_); - const ObTabletID tablet_id(candidate.tablet_id_); - const ObTabletMapKey key(ls_id, tablet_id); - { - ObBucketHashRLockGuard guard(pin_set_lock_, key.hash()); - ret = pinned_tablet_set_.exist_refactored(key); - if (OB_HASH_EXIST == ret) { - ret = OB_SUCCESS; // tablet was pinned, skip - } else if (OB_HASH_NOT_EXIST != ret) { - LOG_WARN("check pinned set fail", K(ret), K(candidate)); - } else { - ret = OB_SUCCESS; - if (OB_FAIL(tablet_map_.wash_meta_obj(key, is_wash))) { - LOG_WARN("wash tablet obj fail", K(ret), K(candidate)); - } else if (is_wash) { - if (!key.tablet_id_.is_inner_tablet()) { - ++wash_user_cnt; - } else { - ++wash_inner_cnt; - } - } + const ObLSID ls_id(candidate.ls_id_); + const ObTabletID tablet_id(candidate.tablet_id_); + const ObTabletMapKey key(ls_id, tablet_id); + ObTabletPointerHandle ptr_handle(tablet_map_); + if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(key)); + } else if (OB_NOT_NULL(handle.get_obj())) { + if (OB_FAIL(tablet_map_.get(key, ptr_handle))) { + LOG_WARN("fail to get tablet pointer handle", K(ret), K(key), K(handle)); + } else if (OB_FAIL(handle.get_obj()->assign_pointer_handle(ptr_handle))) { + LOG_WARN("fail to set tablet pointer handle for tablet", K(ret), K(key)); + } + } + if (FAILEDx(tablet_map_.wash_meta_obj(key, handle, free_obj))) { + LOG_WARN("wash tablet obj fail", K(ret), K(key)); + } + return ret; +} + +int ObTenantMetaMemMgr::try_wash_tablet_from_gc_queue( + const int64_t buf_len, + TabletBufferList &header, + void *&free_obj) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + do { + tablet = ATOMIC_LOAD(&gc_head_); + } while (tablet != ATOMIC_VCAS(&gc_head_, tablet, nullptr)); + while (OB_ISNULL(free_obj) && OB_SUCC(ret) && OB_NOT_NULL(tablet)) { + ObTablet *next_tablet = static_cast(tablet->get_next_tablet()); + ATOMIC_DEC(&wait_gc_tablets_cnt_); + if (OB_UNLIKELY(tablet->get_ref() != 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected tablet in gc queue", K(ret), KPC(tablet)); + } else { + TabletBufferList *h = nullptr; + if (OB_ISNULL(tablet->get_allocator()) + && buf_len == ObMetaObjBufferHelper::get_buffer_header(reinterpret_cast(tablet)).buf_len_) { + h = &header; } + free_obj = recycle_tablet(tablet, h); } if (OB_FAIL(ret)) { - } else if (OB_FAIL(heap.pop())) { - LOG_WARN("fail to pop heap", K(ret)); + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(push_tablet_into_gc_queue(tablet))) { + LOG_ERROR("fail to push tablet into gc queue, tablet may be leaked", K(tmp_ret), KP(tablet)); + } + tablet = nullptr; } + tablet = static_cast(next_tablet); + } + if (OB_NOT_NULL(tablet)) { + push_tablet_list_into_gc_queue(tablet); } return ret; } -int ObTenantMetaMemMgr::do_wash_mem_addr_tablet( - const int64_t expect_wash_cnt, - const common::ObIArray &mem_addr_tablet_info, - int64_t &wash_inner_cnt, - int64_t &wash_user_cnt, - int64_t &wash_mem_addr_cnt) +int ObTenantMetaMemMgr::update_tablet_buffer_header(ObTablet *old_obj, ObTablet *new_obj) { int ret = OB_SUCCESS; - bool is_wash = false; - for (int64_t i = 0; - OB_SUCC(ret) && i < mem_addr_tablet_info.count() && wash_user_cnt + wash_inner_cnt < expect_wash_cnt; - ++i) { - const InMemoryPinnedTabletInfo &info = mem_addr_tablet_info.at(i); - if (OB_FAIL(write_slog_and_wash_tablet(info.key_, info.addr_, is_wash))) { - if (OB_NOT_THE_OBJECT == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("fail to write slog and wash tablet", K(ret), K(info)); - } - } else if (is_wash) { - ++wash_mem_addr_cnt; - if (!info.key_.tablet_id_.is_inner_tablet()) { - ++wash_user_cnt; - } else { - ++wash_inner_cnt; - } - } - } - return ret; -} - -int ObTenantMetaMemMgr::try_wash_tablet(const int64_t expect_wash_cnt) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(expect_wash_cnt < 1)) { + if (OB_ISNULL(old_obj) || OB_ISNULL(new_obj)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(expect_wash_cnt)); + LOG_WARN("invalid argument", K(ret), KP(old_obj), KP(new_obj)); + } else if (old_obj == new_obj) { + if (OB_ISNULL(new_obj->get_allocator())) { // from tablet buffer pool + ObMetaObjBufferHelper::set_in_map(reinterpret_cast(new_obj), true/*in_map*/); + } + } else if (old_obj != new_obj) { + if (OB_ISNULL(old_obj->get_allocator())) { // from tablet buffer pool + ObMetaObjBufferHelper::set_in_map(reinterpret_cast(old_obj), false/*in_map*/); + } + if (OB_ISNULL(new_obj->get_allocator())) { // from tablet buffer pool + ObMetaObjBufferHelper::set_in_map(reinterpret_cast(new_obj), true/*in_map*/); + } + } + return ret; +} + +int ObTenantMetaMemMgr::try_wash_tablet(const std::type_info &type_info, void *&free_obj) +{ + int ret = OB_SUCCESS; + ObTimeGuard time_guard("try_wash_tablet", 1000 * 1000); + ObNormalTabletBuffer *normal_buf = nullptr; + ObTabletHandle tablet_handle; + const bool is_large = typeid(ObLargeTabletBuffer) == type_info; + const int64_t buf_len = is_large ? LARGE_TABLET_POOL_SIZE : NORMAL_TABLET_POOL_SIZE; + TabletBufferList &header = is_large ? large_tablet_header_ : normal_tablet_header_; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init ObTenantMetaMemMgr", K(ret)); + } else if (OB_FAIL(try_wash_tablet_from_gc_queue(buf_len, header, free_obj))) { + LOG_WARN("fail to try wash tablet from gc queue", K(ret), K(buf_len), K(header)); + } else if (FALSE_IT(time_guard.click("wash_queue"))) { + } else if (OB_NOT_NULL(free_obj)) { + LOG_INFO("succeed to wash tablet from gc queue", K(ret), KP(free_obj)); + } else if (is_large && OB_FAIL(acquire_tablet(ObTabletPoolType::TP_NORMAL, tablet_handle))) { + LOG_WARN("fail to acquire tablet", K(ret)); } else { - ObArray mem_addr_tablet_info; - ObArenaAllocator allocator; - Heap heap(compare_, &allocator); - GetWashTabletCandidate op(heap, mem_addr_tablet_info, *this, allocator); - ObTimeGuard time_guard("try_wash_tablet"); - if (OB_FAIL(tablet_map_.for_each_value_store(op))) { + tablet_handle.set_wash_priority(WashTabletPriority::WTP_LOW); + ObArenaAllocator allocator("WashTablet"); + CandidateTabletInfo info; + time_guard.click("prepare"); + SpinWLockGuard guard(wash_lock_); + time_guard.click("wait_lock"); + if (OB_FAIL(get_wash_tablet_candidate(type_info, info))) { LOG_WARN("fail to get candidate tablet for wash", K(ret)); } else { - FLOG_INFO("candidate info", "tablet count", tablet_map_.count(), "candidate count", heap.count(), - "memory address count", mem_addr_tablet_info.count(), K(expect_wash_cnt), K(op)); time_guard.click("get_candidate_cost"); - int64_t wash_user_cnt = 0; - int64_t wash_inner_cnt = 0; - int64_t wash_mem_addr_cnt = 0; - if (OB_FAIL(do_wash_candidate_tablet(expect_wash_cnt, heap, wash_inner_cnt, wash_user_cnt))) { - LOG_WARN("fail to do wash candidate tablet", K(ret), K(expect_wash_cnt)); - } else if (FALSE_IT(time_guard.click("wash_candidate_tablet_cost"))) { - } - /* do_wash_mem_addr_tablet has concurrent issue with normal tablet update, disable it - else if (wash_inner_cnt + wash_user_cnt < expect_wash_cnt) { - std::sort(mem_addr_tablet_info.begin(), mem_addr_tablet_info.end()); - if (OB_FAIL(do_wash_mem_addr_tablet(expect_wash_cnt, mem_addr_tablet_info, wash_inner_cnt, - wash_user_cnt, wash_mem_addr_cnt))) { - LOG_WARN("fail to do wash memory address tablet", K(ret), K(expect_wash_cnt)); - } else { - time_guard.click("wash_mem_addr_tablet_cost"); - } - } - */ - if (OB_SUCC(ret)) { - if (0 == wash_inner_cnt + wash_user_cnt) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("no object can be washed", K(ret), K(wash_inner_cnt), K(wash_user_cnt), - K(wash_mem_addr_cnt), K(expect_wash_cnt), - "tablet count", tablet_map_.count(), K(allocator_), K(tablet_pool_), - K(sstable_pool_), K(ddl_kv_pool_), K(memtable_pool_), K(tablet_ddl_kv_mgr_pool_), - K(tablet_memtable_mgr_pool_), K(tx_data_memtable_pool_), K(tx_ctx_memtable_pool_), - K(lock_memtable_pool_), K(op), - "min_minor_cnt", last_min_minor_sstable_set_.size(), - "pinned_tablet_cnt", pinned_tablet_set_.size(), - K(time_guard), K(lbt())); - } else { - FLOG_INFO("succeed to wash tablet", K(wash_inner_cnt), K(wash_user_cnt), - K(wash_mem_addr_cnt), K(expect_wash_cnt), "tablet count", tablet_map_.count(), - K(allocator_), K(tablet_pool_), K(sstable_pool_), K(ddl_kv_pool_), K(memtable_pool_), K(op), - "min_minor_cnt", last_min_minor_sstable_set_.size(), - "pinned_tablet_cnt", pinned_tablet_set_.size(), - K(time_guard)); - } + if (OB_FAIL(do_wash_candidate_tablet(info, tablet_handle, free_obj))) { + LOG_WARN("fail to do wash candidate tablet", K(ret)); + } else if (OB_NOT_NULL(free_obj)) { + header.remove(static_cast(free_obj)); } + time_guard.click("wash_tablet"); } } - return ret; -} - -int ObTenantMetaMemMgr::insert_pinned_tablet(const ObTabletMapKey &key) -{ - int ret = OB_SUCCESS; - - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!key.is_valid())) { - LOG_WARN("invalid args", K(ret), K(key)); - } else { - ObBucketHashWLockGuard guard(pin_set_lock_, key.hash()); - if (OB_FAIL(pinned_tablet_set_.set_refactored(key, 0/*flag, not overwrite*/))) { - if (OB_HASH_EXIST == ret) { - LOG_DEBUG("tablet already exists", K(ret), K(key)); - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to insert into hash set", K(ret), K(key)); - } + if (OB_SUCC(ret)) { + if (OB_ISNULL(free_obj)) { + LOG_WARN("no object can be washed", K(ret), K(is_large), + "tablet count", tablet_map_.count(), K(tablet_buffer_pool_), K(large_tablet_buffer_pool_), + K(time_guard), K(sizeof(ObTablet)), K(sizeof(ObTabletPointer)), K(lbt())); + } else { + FLOG_INFO("succeed to wash tablet", K(is_large), "tablet count", tablet_map_.count(), + K(tablet_buffer_pool_), K(large_tablet_buffer_pool_), + K(sizeof(ObTablet)), K(sizeof(ObTabletPointer)), K(time_guard)); } } - - return ret; -} - -int ObTenantMetaMemMgr::erase_pinned_tablet(const ObTabletMapKey &key) -{ - int ret = OB_SUCCESS; - - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!key.is_valid())) { - LOG_WARN("invalid args", K(ret), K(key)); - } else { - ObBucketHashWLockGuard guard(pin_set_lock_, key.hash()); - if (OB_FAIL(pinned_tablet_set_.erase_refactored(key))) { - if (OB_HASH_NOT_EXIST == ret) { - LOG_DEBUG("tablet does not exist in t3m pinned set", K(ret), K(key)); - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to erase from hash set", K(ret), K(key)); - } - } - } - - return ret; -} - -int ObTenantMetaMemMgr::exist_pinned_tablet(const ObTabletMapKey &key) -{ - int ret = OB_SUCCESS; - - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!key.is_valid())) { - LOG_WARN("invalid args", K(ret), K(key)); - } else { - ObBucketHashRLockGuard guard(pin_set_lock_, key.hash()); - ret = pinned_tablet_set_.exist_refactored(key); - } - return ret; } @@ -1917,18 +2172,6 @@ ObTenantMetaMemMgr::MinMinorSSTableInfo::~MinMinorSSTableInfo() ObT3mTabletMapIterator::ObT3mTabletMapIterator(ObTenantMetaMemMgr &t3m) : tablet_map_(t3m.tablet_map_), - allocator_(t3m.allocator_), - tablet_items_(), - idx_(0) -{ - tablet_items_.set_attr(SET_USE_500("TabletItems")); -} - -ObT3mTabletMapIterator::ObT3mTabletMapIterator( - ObTenantMetaMemMgr &t3m, - common::ObIAllocator &allocator) - : tablet_map_(t3m.tablet_map_), - allocator_(allocator), tablet_items_(), idx_(0) { @@ -1982,17 +2225,38 @@ int ObT3mTabletMapIterator::FetchTabletItemOp::operator()(TabletPair &pair) return ret; } -ObTenantTabletIterator::ObTenantTabletIterator(ObTenantMetaMemMgr &t3m) - : ObT3mTabletMapIterator(t3m), - is_used_obj_pool_(true) +ObT3mTabletMapIterator::GCTabletItemOp::GCTabletItemOp(TabletMap &tablet_map) + : tablet_map_(tablet_map) { } +int ObT3mTabletMapIterator::GCTabletItemOp::operator()(TabletPair &pair) +{ + int ret = OB_SUCCESS; + /* we tranfer in_memory_tablet from tablet_map to tmp_handle, + and rely on tmp_handle::reset() to push tablet into gc_queue */ + ObTabletHandle tmp_handle; + ObTabletPointer::ObMetaPointer *ptr = nullptr; + ObMetaDiskAddr addr; + if (OB_NOT_NULL(ptr = pair.second->get_value_ptr())) { + addr = ptr->get_addr(); + ptr->get_in_memory_obj(tmp_handle); // ignore err + tmp_handle.set_wash_priority(WashTabletPriority::WTP_LOW); + } + if (addr.is_valid() && !addr.is_none()) { + LOG_INFO("macro blocks' ref cnt may be leaked, please check", K(pair.first), KPC(ptr)); + addr.set_none_addr(); + ptr->set_addr_with_reset_obj(addr); // update none addr to avoid trigger load_meta_obj + } + tmp_handle.reset(); + return ret; +} + ObTenantTabletIterator::ObTenantTabletIterator( ObTenantMetaMemMgr &t3m, - common::ObIAllocator &allocator) - : ObT3mTabletMapIterator(t3m, allocator), - is_used_obj_pool_(t3m.is_used_obj_pool(&allocator)) + common::ObArenaAllocator &allocator) + : ObT3mTabletMapIterator(t3m), + allocator_(&allocator) { } @@ -2009,17 +2273,18 @@ int ObTenantTabletIterator::get_next_tablet(ObTabletHandle &handle) ret = OB_ITER_END; } else { const ObTabletMapKey &key = tablet_items_.at(idx_); - if (!is_used_obj_pool_) { - if (OB_FAIL(tablet_map_.get_meta_obj_with_external_memory(key, allocator_, handle)) - && OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("fail to get tablet handle", K(ret), K(key)); - } - } else if (OB_FAIL(tablet_map_.get_meta_obj(key, allocator_, handle)) - && OB_ENTRY_NOT_EXIST != ret) { + if (OB_ISNULL(allocator_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("allocator_ is nullptr, which is not allowed", K(ret)); + } else if (OB_FAIL(tablet_map_.get_meta_obj_with_external_memory( + key, *allocator_, handle)) && OB_ENTRY_NOT_EXIST != ret) { LOG_WARN("fail to get tablet handle", K(ret), K(key)); } if (OB_SUCC(ret) || ignore_err_code(ret)) { handle.set_wash_priority(WashTabletPriority::WTP_LOW); + if (OB_NOT_NULL(handle.get_allocator())) { + handle.disallow_copy_and_assign(); + } ++idx_; } } diff --git a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h index c95482bc4..100a78e01 100644 --- a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h +++ b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h @@ -36,6 +36,7 @@ #include "storage/meta_mem/ob_tenant_meta_obj_pool.h" #include "storage/tablet/ob_tablet_memtable_mgr.h" #include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_full_tablet_creator.h" #include "lib/signal/ob_signal_utils.h" namespace oceanbase @@ -62,9 +63,16 @@ class ObTenantMetaMemMgr; class ObTxDataMemtable; class ObTxCtxMemtable; class ObLSMemberMemtable; -class ObTabletTxMultiSourceDataUnit; +class ObTabletCreateDeleteMdsUserData; -struct ObTenantMetaMemStatus +enum class ObTabletPoolType : uint8_t +{ + TP_NORMAL = 0, + TP_LARGE = 1, + TP_MAX +}; + +struct ObTenantMetaMemStatus final { public: ObTenantMetaMemStatus(); @@ -79,36 +87,84 @@ public: TO_STRING_KV(K_(name), K(total_size_), K(used_size_), K(used_obj_cnt_), K(free_obj_cnt_), K(each_obj_size_)); }; +struct ObTabletBufferInfo final +{ +public: + ObTabletBufferInfo() + : ls_id_(), tablet_id_(), + tablet_buffer_ptr_(nullptr), tablet_(nullptr), + pool_type_(), in_map_(false), last_access_time_(-1) + { + } + ~ObTabletBufferInfo() + { + reset(); + } + + void reset(); + int fill_info(const ObTabletPoolType &pool_type, ObMetaObjBufferNode *node); + TO_STRING_KV(K_(ls_id), K_(tablet_id), KP_(tablet_buffer_ptr), KP_(tablet), K_(pool_type), K_(in_map), K_(last_access_time)); + +public: + share::ObLSID ls_id_; + ObTabletID tablet_id_; + char *tablet_buffer_ptr_; + ObTablet *tablet_; + ObTabletPoolType pool_type_; + bool in_map_; + int64_t last_access_time_; +}; + class ObTenantMetaMemMgr final { public: typedef ObMetaPointerHandle ObTabletPointerHandle; -private: + static const int64_t THE_SIZE_OF_HEADERS = sizeof(ObFIFOAllocator::NormalPageHeader) + sizeof(ObMetaObjBufferNode); + static const int64_t NORMAL_TABLET_POOL_SIZE = 4 * 1024L - THE_SIZE_OF_HEADERS; // 4KB + static const int64_t LARGE_TABLET_POOL_SIZE = 64 * 1024L - THE_SIZE_OF_HEADERS; // 64KB + static const int64_t MIN_MODE_MAX_TABLET_CNT_IN_OBJ_POOL = 10000; - static const int64_t MIN_MODE_MAX_SSTABLE_CNT_IN_OBJ_POOL = 5 * MIN_MODE_MAX_TABLET_CNT_IN_OBJ_POOL; static const int64_t MIN_MODE_MAX_MEMTABLE_CNT_IN_OBJ_POOL = 2 * MIN_MODE_MAX_TABLET_CNT_IN_OBJ_POOL; static const int64_t MAX_TABLET_CNT_IN_OBJ_POOL = 50000; - static const int64_t MAX_SSTABLE_CNT_IN_OBJ_POOL = 5 * MAX_TABLET_CNT_IN_OBJ_POOL; static const int64_t MAX_MEMTABLE_CNT_IN_OBJ_POOL = 2 * MAX_TABLET_CNT_IN_OBJ_POOL; static const int64_t MAX_TX_DATA_MEMTABLE_CNT_IN_OBJ_POOL = MAX_MEMSTORE_CNT * OB_MINI_MODE_MAX_LS_NUM_PER_TENANT_PER_SERVER; static const int64_t MAX_TX_CTX_MEMTABLE_CNT_IN_OBJ_POOL = OB_MINI_MODE_MAX_LS_NUM_PER_TENANT_PER_SERVER; static const int64_t MAX_LOCK_MEMTABLE_CNT_IN_OBJ_POOL = OB_MINI_MODE_MAX_LS_NUM_PER_TENANT_PER_SERVER; static const int64_t MAX_DDL_KV_IN_OBJ_POOL = 5000; + static const int64_t TABLET_TRANSFORM_INTERVAL_US = 2 * 1000 * 1000L; // 2s static int64_t get_default_tablet_pool_count() { return lib::is_mini_mode() ? MIN_MODE_MAX_TABLET_CNT_IN_OBJ_POOL : MAX_TABLET_CNT_IN_OBJ_POOL; } - static int64_t get_default_sstable_pool_count() + static int64_t get_default_normal_tablet_pool_count() { - return lib::is_mini_mode() ? MIN_MODE_MAX_SSTABLE_CNT_IN_OBJ_POOL : MAX_SSTABLE_CNT_IN_OBJ_POOL; + return static_cast(get_default_tablet_pool_count() * 0.96); + } + static int64_t get_default_large_tablet_pool_count() + { + return get_default_tablet_pool_count() - get_default_normal_tablet_pool_count(); } static int64_t get_default_memtable_pool_count() { return lib::is_mini_mode() ? MIN_MODE_MAX_MEMTABLE_CNT_IN_OBJ_POOL : MAX_MEMTABLE_CNT_IN_OBJ_POOL; } + static int get_tablet_pool_type(const int64_t tablet_size, ObTabletPoolType &type) + { + int ret = OB_SUCCESS; + if (tablet_size <= NORMAL_TABLET_POOL_SIZE) { + type = ObTabletPoolType::TP_NORMAL; + } else if (tablet_size <= LARGE_TABLET_POOL_SIZE) { + type = ObTabletPoolType::TP_LARGE; + } else { + ret = OB_NOT_SUPPORTED; + STORAGE_LOG(WARN, "tablet size is too large", K(ret), K(tablet_size)); + } + return ret; + } + private: explicit ObTenantMetaMemMgr(const uint64_t tenant_id); public: @@ -122,18 +178,24 @@ public: void wait(); void destroy(); + int print_old_chain( + const ObTabletMapKey &key, + const ObTabletPointer &tablet_ptr, + const int64_t buf_len, + char *buf); // TIPS: // - only for tx data table to find min log ts. - int get_min_end_scn_for_ls(const share::ObLSID &ls_id, share::SCN &end_scn); + int get_min_end_scn_for_ls( + const ObTabletMapKey &key, + share::SCN &min_end_scn_from_latest, + share::SCN &min_end_scn_from_old); + int get_min_mds_ckpt_scn(const ObTabletMapKey &key, share::SCN &scn); // garbage collector for sstable and memtable. int push_table_into_gc_queue(ObITable *table, const ObITable::TableType table_type); int gc_tables_in_queue(bool &all_table_cleaned); - void gc_sstable(blocksstable::ObSSTable *sstable); - - // sstable interface - int acquire_sstable(ObTableHandleV2 &handle); - int acquire_sstable(ObTableHandleV2 &handle, common::ObIAllocator &allocator); + int gc_tablet(ObTablet *tablet); // add tablet into gc queue + int gc_tablets_in_queue(bool &all_tablet_cleaned); // trigger to gc tablets // ddl kv interface int acquire_ddl_kv(ObTableHandleV2 &handle); @@ -144,19 +206,35 @@ public: int acquire_tx_ctx_memtable(ObTableHandleV2 &handle); int acquire_lock_memtable(ObTableHandleV2 &handle); - // tablet interfaces - int acquire_tablet( + // tablet create and acquire interfaces + // - create_xx_tablet() is used for the first time to construct a tablet object and create a + // tablet pointer. + // - acquire_xx_tablet() is used for non-first time, and only constructs a tablet object. + int create_msd_tablet( const WashTabletPriority &priority, const ObTabletMapKey &key, ObLSHandle &ls_handle, - ObTabletHandle &tablet_handle, - const bool only_acquire); - int acquire_tablet( + ObTabletHandle &tablet_handle); + int acquire_msd_tablet( const WashTabletPriority &priority, const ObTabletMapKey &key, - common::ObIAllocator &allocator, - ObTabletHandle &tablet_handle, - const bool only_acquire); + ObTabletHandle &tablet_handle); + int create_tmp_tablet( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + common::ObArenaAllocator &allocator, + ObLSHandle &ls_handle, + ObTabletHandle &tablet_handle); + int acquire_tmp_tablet( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + common::ObArenaAllocator &allocator, + ObTabletHandle &tablet_handle); + int acquire_tablet_from_pool( + const ObTabletPoolType &type, + const WashTabletPriority &priority, + const ObTabletMapKey &key, + ObTabletHandle &tablet_handle); int get_tablet( const WashTabletPriority &priority, const ObTabletMapKey &key, @@ -165,9 +243,10 @@ public: int get_tablet_with_allocator( const WashTabletPriority &priority, const ObTabletMapKey &key, - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, ObTabletHandle &handle, const bool force_alloc_new = false); + int get_tablet_buffer_infos(const ObTabletPoolType &pool_type, ObIArray &buffer_infos); int get_tablet_addr(const ObTabletMapKey &key, ObMetaDiskAddr &addr); int has_tablet(const ObTabletMapKey &key, bool &is_exist); int del_tablet(const ObTabletMapKey &key); @@ -175,42 +254,34 @@ public: ObLSService &ls_service, bool &is_released, const char *module); - int compare_and_swap_tablet( - const ObTabletMapKey &key, - const ObMetaDiskAddr &new_addr, - const ObTabletHandle &old_handle, - ObTabletHandle &new_handle); - // TIPS: - // - only compare and swap pure address, but no reset object. - // - only for checkpoint writer. - int compare_and_swap_tablet_pure_address_without_object( const ObTabletMapKey &key, const ObMetaDiskAddr &old_addr, const ObMetaDiskAddr &new_addr); - int try_wash_tablet(); + int compare_and_swap_tablet( + const ObTabletMapKey &key, + const ObTabletHandle &old_handle, + ObTabletHandle &new_handle); + int update_tablet_buffer_header(ObTablet *old_obj, ObTablet *new_obj); + int try_wash_tablet(const std::type_info &type_info, void *&obj); int get_meta_mem_status(common::ObIArray &info) const; - int get_tablet_pointer_tx_data(const ObTabletMapKey &key, ObTabletTxMultiSourceDataUnit &tx_data); - int insert_pinned_tablet(const ObTabletMapKey &key); - int erase_pinned_tablet(const ObTabletMapKey &key); + int get_tablet_pointer_initial_state(const ObTabletMapKey &key, bool &initial_state); int get_tablet_ddl_kv_mgr(const ObTabletMapKey &key, ObDDLKvMgrHandle &ddl_kv_mgr_handle); - - // TIPS: - // - only for allocating variable meta object in storage meta. - OB_INLINE common::ObIAllocator &get_tenant_allocator() { return allocator_; } - OB_INLINE bool is_used_obj_pool(common::ObIAllocator *allocator) const - { - return &allocator_ == allocator; - } + ObFullTabletCreator &get_mstx_tablet_creator() { return full_tablet_creator_; } OB_INLINE int64_t get_total_tablet_cnt() const { return tablet_map_.count(); } - TO_STRING_KV(K_(tenant_id), K_(is_inited)); + TO_STRING_KV(K_(tenant_id), K_(is_inited), "tablet count", tablet_map_.count()); private: int64_t cal_adaptive_bucket_num(); - + int push_tablet_into_gc_queue(ObTablet *tablet); + void push_tablet_list_into_gc_queue(ObTablet *tablet); + int get_min_end_scn_from_single_tablet( + ObTablet *tablet, const bool is_old, share::SCN &min_end_scn); +private: typedef ObResourceValueStore> TabletValueStore; - + typedef ObMetaObjBuffer ObNormalTabletBuffer; + typedef ObMetaObjBuffer ObLargeTabletBuffer; struct CandidateTabletInfo final { public: @@ -224,21 +295,6 @@ private: uint64_t tablet_id_; // to use ObBinaryHeap, the type here must is_trivially_copyable int64_t wash_score_; }; - struct InMemoryPinnedTabletInfo final - { - public: - InMemoryPinnedTabletInfo() : key_(), addr_(), wash_score_(INT64_MIN) {} - ~InMemoryPinnedTabletInfo() = default; - bool operator < (const InMemoryPinnedTabletInfo &info) - { - return wash_score_ < info.wash_score_; - } - TO_STRING_KV(K_(key), K_(addr), K_(wash_score)); - public: - ObTabletMapKey key_; - ObMetaDiskAddr addr_; - int64_t wash_score_; - }; class HeapCompare final { public: @@ -260,6 +316,15 @@ private: ObITable *table_; ObITable::TableType table_type_; }; + class TabletGCTask : public common::ObTimerTask + { + public: + explicit TabletGCTask(ObTenantMetaMemMgr *t3m) : t3m_(t3m) {} + virtual ~TabletGCTask() = default; + virtual void runTimerTask() override; + private: + ObTenantMetaMemMgr *t3m_; + }; class TableGCTask : public common::ObTimerTask { public: @@ -273,15 +338,6 @@ private: private: ObTenantMetaMemMgr *t3m_; }; - class MinMinorSSTableGCTask : public common::ObTimerTask - { - public: - explicit MinMinorSSTableGCTask(ObTenantMetaMemMgr *t3m) : t3m_(t3m) {} - virtual ~MinMinorSSTableGCTask() = default; - virtual void runTimerTask() override; - private: - ObTenantMetaMemMgr *t3m_; - }; class RefreshConfigTask : public common::ObTimerTask { public: @@ -289,6 +345,15 @@ private: virtual ~RefreshConfigTask() = default; virtual void runTimerTask() override; }; + class TabletPersistTask : public common::ObTimerTask + { + public: + explicit TabletPersistTask(ObTenantMetaMemMgr *t3m) : t3m_(t3m) {} + virtual ~TabletPersistTask() = default; + virtual void runTimerTask() override; + private: + ObTenantMetaMemMgr *t3m_; + }; class MinMinorSSTableInfo final { public: @@ -329,52 +394,24 @@ private: private: friend class ObT3mTabletMapIterator; - friend class GetWashTabletCandidate; friend class TableGCTask; friend class ObTabletPointer; static const int64_t DEFAULT_BUCKET_NUM = 10243L; static const int64_t TOTAL_LIMIT = 15 * 1024L * 1024L * 1024L; static const int64_t HOLD_LIMIT = 8 * 1024L * 1024L; static const int64_t TABLE_GC_INTERVAL_US = 20 * 1000L; // 20ms - static const int64_t MIN_MINOR_SSTABLE_GC_INTERVAL_US = 1 * 1000 * 1000L; // 1s static const int64_t REFRESH_CONFIG_INTERVAL_US = 10 * 1000 * 1000L; // 10s static const int64_t ONE_ROUND_RECYCLE_COUNT_THRESHOLD = 20000L; + static const int64_t ONE_ROUND_TABLET_GC_COUNT_THRESHOLD = 200L; static const int64_t BATCH_MEMTABLE_GC_THRESHOLD = 100L; static const int64_t DEFAULT_TABLET_WASH_HEAP_COUNT = 16; static const int64_t DEFAULT_MINOR_SSTABLE_SET_COUNT = 49999; static const int64_t SSTABLE_GC_MAX_TIME = 500; // 500us typedef common::ObBinaryHeap Heap; + typedef common::ObDList TabletBufferList; typedef common::hash::ObHashSet SSTableSet; typedef common::hash::ObHashSet PinnedTabletSet; - class GetWashTabletCandidate final - { - public: - GetWashTabletCandidate( - Heap &heap, - common::ObIArray &mem_addr_tablets_, - ObTenantMetaMemMgr &t3m, - common::ObIAllocator &allocator); - ~GetWashTabletCandidate() = default; - int operator()(common::hash::HashMapPair &entry); - - TO_STRING_KV(K_(none_addr_tablet_cnt), - K_(mem_addr_tablet_cnt), - K_(in_memory_tablet_cnt), - K_(inner_tablet_cnt), - K_(candidate_tablet_cnt)); - private: - Heap &heap_; - common::ObIArray &mem_addr_tablets_; - ObTenantMetaMemMgr &t3m_; - common::ObIAllocator &allocator_; - int64_t none_addr_tablet_cnt_; // tablet whose meta disk addr is NONE, should not be washed - int64_t mem_addr_tablet_cnt_; // tablet whose meta disk addr is MEM, should not be washed - int64_t in_memory_tablet_cnt_; // tablet which exists in memory, may be washing candidate - int64_t inner_tablet_cnt_; - int64_t candidate_tablet_cnt_; - }; - class TenantMetaAllocator : public common::ObFIFOAllocator { public: @@ -389,49 +426,40 @@ private: }; private: + int acquire_tablet(const ObTabletPoolType type, ObTabletHandle &tablet_handle); + int acquire_tablet(ObITenantMetaObjPool *pool, ObTablet *&tablet); int acquire_tablet_ddl_kv_mgr(ObDDLKvMgrHandle &handle); int acquire_tablet_memtable_mgr(ObMemtableMgrHandle &handle); int create_tablet(const ObTabletMapKey &key, ObLSHandle &ls_handle, ObTabletHandle &tablet_handle); - int gc_min_minor_sstable_in_set(); - int record_min_minor_sstable(const share::ObLSID &ls_id, const ObTableHandleV2 &table_handle); - int try_wash_tablet(const int64_t expect_wash_cnt); int do_wash_candidate_tablet( - const int64_t expect_wash_cnt, - Heap &heap, - int64_t &wash_inner_cnt, - int64_t &wash_user_cnt); - int do_wash_mem_addr_tablet( - const int64_t expect_wash_cnt, - const common::ObIArray &mem_addr_tablet_info, - int64_t &wash_inner_cnt, - int64_t &wash_user_cnt, - int64_t &wash_mem_addr_cnt); - int write_slog_and_wash_tablet( - const ObTabletMapKey &key, - const ObMetaDiskAddr &old_addr, - bool &is_wash); - int64_t calc_wash_tablet_cnt() const; + const CandidateTabletInfo &info, + ObTabletHandle &tablet_handle, + void *& free_obj); + int try_wash_tablet_from_gc_queue( + const int64_t buf_len, + TabletBufferList &header, + void *&free_obj); void dump_tablet(); - void dump_pinned_tablet(); void dump_ls(ObLSService &ls_service) const; void init_pool_arr(); + void *recycle_tablet(ObTablet *tablet, TabletBufferList *header = nullptr); void release_memtable(memtable::ObMemtable *memtable); - void release_sstable(blocksstable::ObSSTable *sstable); - void release_ddl_kv(ObDDLKV *ddl_kv); void release_tablet(ObTablet *tablet); + void release_ddl_kv(ObDDLKV *ddl_kv); void release_tablet_ddl_kv_mgr(ObTabletDDLKvMgr *ddl_kv_mgr); void release_tablet_memtable_mgr(ObTabletMemtableMgr *memtable_mgr); void release_tx_data_memtable_(ObTxDataMemtable *memtable); void release_tx_ctx_memtable_(ObTxCtxMemtable *memtable); void release_lock_memtable_(transaction::tablelock::ObLockMemtable *memtable); + void mark_mds_table_deleted_(const ObTabletMapKey &key); template int get_obj_pool_info( const ObTenantMetaObjPool &obj_pool, const char *name, common::ObIArray &info) const; - int get_allocator_info(common::ObIArray &info) const; - int exist_pinned_tablet(const ObTabletMapKey &key); + int get_wash_tablet_candidate(const std::type_info &type_info, CandidateTabletInfo &info); + void destroy_gc_tablets_queue(); int push_memtable_into_gc_map_(memtable::ObMemtable *memtable); void batch_gc_memtable_(); @@ -442,25 +470,24 @@ private: TryWashTabletFunc wash_func_; const uint64_t tenant_id_; ObBucketLock bucket_lock_; - TenantMetaAllocator allocator_; + ObFullTabletCreator full_tablet_creator_; ObMetaPointerMap tablet_map_; int tg_id_; + int persist_tg_id_; // since persist task may cost too much time, we use another thread to exec. TableGCTask table_gc_task_; - MinMinorSSTableGCTask min_minor_sstable_gc_task_; RefreshConfigTask refresh_config_task_; + TabletPersistTask tablet_persist_task_; + TabletGCTask tablet_gc_task_; + ObTablet *gc_head_; + int64_t wait_gc_tablets_cnt_; common::ObLinkQueue free_tables_queue_; common::ObSpinLock gc_queue_lock_; - SSTableSet last_min_minor_sstable_set_; - common::SpinRWLock sstable_set_lock_; - ObBucketLock pin_set_lock_; - PinnedTabletSet pinned_tablet_set_; // tablets which are in multi source data transaction procedure - common::hash::ObHashMap gc_memtable_map_; ObTenantMetaObjPool memtable_pool_; - ObTenantMetaObjPool sstable_pool_; + ObTenantMetaObjPool tablet_buffer_pool_; + ObTenantMetaObjPool large_tablet_buffer_pool_; ObTenantMetaObjPool ddl_kv_pool_; - ObTenantMetaObjPool tablet_pool_; ObTenantMetaObjPool tablet_ddl_kv_mgr_pool_; ObTenantMetaObjPool tablet_memtable_mgr_pool_; ObTenantMetaObjPool tx_data_memtable_pool_; @@ -468,6 +495,10 @@ private: ObTenantMetaObjPool lock_memtable_pool_; ObITenantMetaObjPool *pool_arr_[ObITable::TableType::MAX_TABLE_TYPE]; + // for washing + TabletBufferList normal_tablet_header_; + TabletBufferList large_tablet_header_; + bool is_inited_; }; @@ -494,9 +525,9 @@ public: class ObT3mTabletMapIterator { + friend class ObTenantMetaMemMgr; public: explicit ObT3mTabletMapIterator(ObTenantMetaMemMgr &t3m); - ObT3mTabletMapIterator(ObTenantMetaMemMgr &t3m, common::ObIAllocator &allocator); virtual ~ObT3mTabletMapIterator(); void reset(); protected: @@ -517,11 +548,20 @@ private: TabletMap &tablet_map_; common::ObIArray &items_; }; +protected: + class GCTabletItemOp final + { + public: + GCTabletItemOp(TabletMap &tablet_map); + ~GCTabletItemOp() = default; + int operator()(TabletPair &pair); + private: + TabletMap &tablet_map_; + }; protected: static const int64_t DEFAULT_TABLET_ITEM_CNT = 8; TabletMap &tablet_map_; - common::ObIAllocator &allocator_; common::ObSEArray tablet_items_; int64_t idx_; private: @@ -532,13 +572,14 @@ class ObTenantTabletIterator : public ObT3mTabletMapIterator, public ObITenantTabletIterator { public: - explicit ObTenantTabletIterator(ObTenantMetaMemMgr &t3m); - ObTenantTabletIterator(ObTenantMetaMemMgr &t3m, common::ObIAllocator &allocator); + ObTenantTabletIterator( + ObTenantMetaMemMgr &t3m, + common::ObArenaAllocator &allocator); virtual ~ObTenantTabletIterator() = default; virtual int get_next_tablet(ObTabletHandle &handle) override; private: - const bool is_used_obj_pool_; + common::ObArenaAllocator *allocator_; }; class ObTenantInMemoryTabletIterator : public ObT3mTabletMapIterator, diff --git a/src/storage/meta_mem/ob_tenant_meta_obj_pool.cpp b/src/storage/meta_mem/ob_tenant_meta_obj_pool.cpp index be86486a7..a064db021 100644 --- a/src/storage/meta_mem/ob_tenant_meta_obj_pool.cpp +++ b/src/storage/meta_mem/ob_tenant_meta_obj_pool.cpp @@ -24,6 +24,7 @@ namespace storage constexpr const char RPMetaObjLabel::LABEL[]; + TryWashTabletFunc::TryWashTabletFunc(ObTenantMetaMemMgr &t3m) : t3m_(t3m) { @@ -33,9 +34,35 @@ TryWashTabletFunc::~TryWashTabletFunc() { } -int TryWashTabletFunc::operator()() +int TryWashTabletFunc::operator()(const std::type_info &type_info, void *&free_obj) { - return t3m_.try_wash_tablet(); + free_obj = nullptr; + return t3m_.try_wash_tablet(type_info, free_obj); +} + +ObMetaObjBufferNode &ObMetaObjBufferHelper::get_linked_node(char *obj) +{ + ObMetaObjBufferNode *header = reinterpret_cast(obj - sizeof(ObMetaObjBufferNode)); + abort_unless(nullptr != header); + abort_unless(ObMetaObjBufferHeader::MAGIC_NUM == header->get_data().magic_num_); + return *header; +} + +ObMetaObjBufferHeader &ObMetaObjBufferHelper::get_buffer_header(char *obj) +{ + return get_linked_node(obj).get_data(); +} + +char *ObMetaObjBufferHelper::get_obj_buffer(ObMetaObjBufferNode *node) +{ + abort_unless(nullptr != node); + abort_unless(ObMetaObjBufferHeader::MAGIC_NUM == node->get_data().magic_num_); + return reinterpret_cast(node) + sizeof(ObMetaObjBufferNode); +} + +void *ObMetaObjBufferHelper::get_meta_obj_buffer_ptr(char *obj) +{ + return static_cast(&get_linked_node(obj)); } } // end namespace storage diff --git a/src/storage/meta_mem/ob_tenant_meta_obj_pool.h b/src/storage/meta_mem/ob_tenant_meta_obj_pool.h index 63192891f..e67551c34 100644 --- a/src/storage/meta_mem/ob_tenant_meta_obj_pool.h +++ b/src/storage/meta_mem/ob_tenant_meta_obj_pool.h @@ -22,6 +22,7 @@ namespace storage { class ObTenantMetaMemMgr; +class ObTablet; class RPMetaObjLabel { @@ -29,16 +30,120 @@ public: static constexpr const char LABEL[] = "MetaObj"; }; +class ObMetaObjBufferHeader final +{ +public: + static const uint16_t MAGIC_NUM = 0xa12f; +public: + ObMetaObjBufferHeader() + : buf_len_(0), + magic_num_(MAGIC_NUM), + has_new_(false), + in_map_(false), + reserved_(0) + {} + explicit ObMetaObjBufferHeader(const uint64_t header) + : header_(header) + {} + ~ObMetaObjBufferHeader() = default; + TO_STRING_KV(K(header_), K(buf_len_), K(magic_num_), K(has_new_), K(in_map_), K(reserved_)); +public: + union { + uint64_t header_; + struct { + uint64_t buf_len_ : 32; + uint64_t magic_num_ : 16; + uint64_t has_new_ : 1; + uint64_t in_map_ : 1; + uint64_t reserved_ : 14; + }; + }; +private: + DISALLOW_COPY_AND_ASSIGN(ObMetaObjBufferHeader); +}; + +typedef common::ObDLinkNode ObMetaObjBufferNode; + +template +class ObMetaObjBuffer final +{ +public: + ObMetaObjBuffer() + : header_() + { + header_.get_data().buf_len_ = BUFFER_LENGTH; + memset(buf_, 0x0, BUFFER_LENGTH); + } + ~ObMetaObjBuffer() { reset(); } + char *buf() { return buf_; } + void reset() + { + if (header_.get_data().has_new_) { + reinterpret_cast(buf_)->~T(); + header_.get_data().has_new_ = false; + } + header_.get_data().in_map_ = false; + memset(buf_, 0x0, BUFFER_LENGTH); + } +public: + ObMetaObjBufferNode header_; + char buf_[BUFFER_LENGTH]; +private: + DISALLOW_COPY_AND_ASSIGN(ObMetaObjBuffer); +}; + +class ObMetaObjBufferHelper final +{ +public: + static ObMetaObjBufferNode &get_linked_node(char *obj); + static ObMetaObjBufferHeader &get_buffer_header(char *obj); + static char *get_obj_buffer(ObMetaObjBufferNode *node); + static void *get_meta_obj_buffer_ptr(char *obj); + static void set_in_map(char *obj, const bool in_map) + { + uint64_t old = ATOMIC_LOAD(&(get_buffer_header(obj).header_)); + ObMetaObjBufferHeader new_header(old); + new_header.in_map_ = in_map; + while (old != (new_header.header_ = ATOMIC_CAS(&(get_buffer_header(obj).header_), old, new_header.header_))) { + old = new_header.header_; + new_header.in_map_ = in_map; + } + } + static bool is_in_map(char *obj) + { + return ObMetaObjBufferHeader(ATOMIC_LOAD(&(get_buffer_header(obj).header_))).in_map_; + } + template + static void new_meta_obj(void *buf, T *&obj) + { + char *obj_buf = static_cast(buf) + sizeof(ObMetaObjBufferNode); + ObMetaObjBufferHeader &header = get_buffer_header(obj_buf); + abort_unless(false == header.has_new_); + obj = new (obj_buf) T(); + header.has_new_ = true; + header.in_map_ = false; + } + template + static void del_meta_obj(T *obj) + { + ObMetaObjBufferHeader &header = get_buffer_header(reinterpret_cast(obj)); + obj->~T(); + header.has_new_ = false; + header.in_map_ = false; + } +}; + class TryWashTabletFunc final { public: explicit TryWashTabletFunc(ObTenantMetaMemMgr &t3m); ~TryWashTabletFunc(); - int operator()(); + int operator()(const std::type_info &type_info, void *&free_obj); private: ObTenantMetaMemMgr &t3m_; + DISALLOW_COPY_AND_ASSIGN(TryWashTabletFunc); }; class ObITenantMetaObjPool @@ -48,6 +153,7 @@ public: virtual ~ObITenantMetaObjPool() = default; virtual void free_obj(void *obj) = 0; + virtual int alloc_obj(void *&obj) = 0; }; template @@ -63,7 +169,8 @@ public: const int64_t max_free_list_num, const lib::ObLabel &label, const uint64_t ctx_id, - TryWashTabletFunc &wash_func_); + TryWashTabletFunc *wash_func = nullptr, + const bool allow_over_max_free_num = true); virtual ~ObTenantMetaObjPool(); int64_t used() const { return allocator_.used(); } @@ -72,6 +179,7 @@ public: int64_t get_free_obj_cnt() const { return this->get_free_num(); } int64_t get_obj_size() const { return sizeof(T); } virtual void free_obj(void *obj) override; + virtual int alloc_obj(void *&obj) override; virtual void free_node_(typename BasePool::Node *ptr) override; int acquire(T *&t); @@ -81,9 +189,10 @@ public: this->get_free_num(), "allocator used", allocator_.used(), "allocator total", allocator_.total()); private: - TryWashTabletFunc &wash_func_; + TryWashTabletFunc *wash_func_; common::ObFIFOAllocator allocator_; int64_t used_obj_cnt_; + bool allow_over_max_free_num_; }; template @@ -92,35 +201,44 @@ void ObTenantMetaObjPool::free_obj(void *obj) release(static_cast(obj)); } +template +int ObTenantMetaObjPool::alloc_obj(void *&obj) +{ + int ret = OB_SUCCESS; + T *t = nullptr; + if (OB_FAIL(acquire(t))) { + STORAGE_LOG(WARN, "fail to acquire object", K(ret)); + } else { + obj = static_cast(t); + } + return ret; +} + template int ObTenantMetaObjPool::acquire(T *&t) { int ret = OB_SUCCESS; t = nullptr; - const int64_t max_wait_ts = ObTimeUtility::fast_current_time() + 1000L * 1000L * 3L; // 3s - while (OB_SUCC(ret) - && OB_ISNULL(t = BasePool::alloc()) - && max_wait_ts - ObTimeUtility::fast_current_time() >= 0) { - ob_usleep(1); - if (OB_FAIL(wash_func_())) { - STORAGE_LOG(WARN, "wash function fail", K(ret)); - } - } - if (OB_ALLOCATE_MEMORY_FAILED == ret && OB_NOT_NULL(t = BasePool::alloc())) { - ret = OB_SUCCESS; - } - - if (OB_FAIL(ret)) { - if (OB_NOT_NULL(t)) { - BasePool::free(t); - t = nullptr; - } + const bool allow_alloc = allow_over_max_free_num_ || (BasePool::max_free_list_num_ > ATOMIC_LOAD(&used_obj_cnt_)); + if (allow_alloc && OB_NOT_NULL(t = BasePool::alloc())) { + (void)ATOMIC_AAF(&used_obj_cnt_, 1); } else { + const int64_t max_wait_ts = ObTimeUtility::fast_current_time() + 1000L * 1000L * 3L; // 3s + while (OB_SUCC(ret) + && OB_ISNULL(t) + && OB_NOT_NULL(wash_func_) + && max_wait_ts - ObTimeUtility::fast_current_time() >= 0) { + ob_usleep(1); + void *free_obj = nullptr; + if (OB_FAIL((*wash_func_)(typeid(T), free_obj))) { + STORAGE_LOG(WARN, "wash function fail", K(ret)); + } else { + t = static_cast(free_obj); + } + } if (OB_ISNULL(t)) { ret = OB_ALLOCATE_MEMORY_FAILED; STORAGE_LOG(WARN, "no object could be acquired", K(ret)); - } else { - (void)ATOMIC_AAF(&used_obj_cnt_, 1); } } return ret; @@ -159,11 +277,13 @@ ObTenantMetaObjPool::ObTenantMetaObjPool( const int64_t max_free_list_num, const lib::ObLabel &label, const uint64_t ctx_id, - TryWashTabletFunc &wash_func_) + TryWashTabletFunc *wash_func, + const bool allow_over_max_free_num) : ObBaseResourcePool(max_free_list_num, &allocator_, lib::ObMemAttr(tenant_id, label, ctx_id)), - wash_func_(wash_func_), - used_obj_cnt_(0) + wash_func_(wash_func), + used_obj_cnt_(0), + allow_over_max_free_num_(allow_over_max_free_num) { int ret = OB_SUCCESS; omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); diff --git a/src/storage/multi_data_source/adapter_define/mds_dump_node.cpp b/src/storage/multi_data_source/adapter_define/mds_dump_node.cpp new file mode 100644 index 000000000..c62535e34 --- /dev/null +++ b/src/storage/multi_data_source/adapter_define/mds_dump_node.cpp @@ -0,0 +1,588 @@ +#include "mds_dump_node.h" +#include "lib/list/ob_dlist.h" +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log_module.h" +#include +#include "storage/multi_data_source/mds_table_handle.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +uint32_t MdsDumpKey::generate_hash() const +{ + #define PRINT_WRAPPER K(*this) + MDS_TG(1_ms); + uint64_t result = 0; + result = murmurhash(&mds_table_id_, sizeof(mds_table_id_), result); + result = murmurhash(&mds_unit_id_, sizeof(mds_unit_id_), result); + if (!key_.empty()) { + result = murmurhash(key_.ptr(), key_.length(), result); + } + return static_cast(result); + #undef PRINT_WRAPPER +} + +void MdsDumpKey::reset() +{ + MDS_TG(1_ms); + if (OB_NOT_NULL(allocator_)) { + if (OB_NOT_NULL(key_.ptr())) { + allocator_->free(key_.ptr()); + key_.reset(); + } + allocator_ = nullptr; + } + new (this) MdsDumpKey(); +} + +struct DeserializeCompareHelper +{ + template + struct InnerDeserializeCompareHelper + { + template + int help_compare_key(const MdsDumpKey &lhs, + const MdsDumpKey &rhs, + int &result) + { + #define PRINT_WRAPPER KR(ret), K(lhs.mds_table_id_), K(lhs.mds_unit_id_), K(result) + int ret = OB_SUCCESS; + MDS_TG(1_ms); + if (IDX == lhs.mds_unit_id_) { + using UnitType = typename std::decay< + decltype(std::declval().template element())>::type; + using KeyType = typename UnitType::key_type; + KeyType lhs_key; + KeyType rhs_key; + int64_t pos = 0; + if (MDS_FAIL(lhs_key.deserialize(lhs.key_.ptr(), lhs.key_.length(), pos))) { + MDS_LOG_NONE(ERROR, "fail to deseialize lhs key"); + } else if (FALSE_IT(pos = 0)) { + } else if (MDS_FAIL(rhs_key.deserialize(rhs.key_.ptr(), rhs.key_.length(), pos))) { + MDS_LOG_NONE(ERROR, "fail to deseialize rhs key"); + } else { + if (lhs_key < rhs_key) { + result = -1; + } else if (lhs_key == rhs_key) { + result = 0; + } else { + result = 1; + } + MDS_LOG_NONE(DEBUG, "success to compare non dummy key"); + } + } else if (MDS_FAIL(help_compare_key(lhs, rhs, result))) { + } + return ret; + #undef PRINT_WRAPPER + } + template <> + int help_compare_key(const MdsDumpKey &lhs, + const MdsDumpKey &rhs, + int &result) + { + int ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "no this mds_unit_id", K(lhs.mds_unit_id_), KR(ret)); + return ret; + } + }; + template + int help_compare(const MdsDumpKey &lhs, const MdsDumpKey &rhs, int &result) + { + MDS_TG(1_ms); + int ret = OB_SUCCESS; + if (IDX == lhs.mds_table_id_) { + using MdsTableType = typename std::decay< + decltype(std::declval().element())>::type; + InnerDeserializeCompareHelper inner_helper; + inner_helper.template help_compare_key<0>(lhs, rhs, result); + } else if (MDS_FAIL(help_compare(lhs, rhs, result))) { + } + return ret; + } + template <> + int help_compare(const MdsDumpKey &lhs, + const MdsDumpKey &rhs, + int &result) + { + int ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "no this mds_table_id", K(lhs.mds_table_id_), KR(ret)); + return ret; + } +}; + +struct DeserializePrintHelper +{ + template + struct InnerDeserializePrintHelper + { + template + void help_print_key(const uint8_t mds_unit_id, + const ObString &data_buf, + char *buf, + const int64_t buf_len, + int64_t &pos) + { + int ret = OB_SUCCESS; + MDS_TG(1_ms); + if (IDX == mds_unit_id) { + using UnitType = typename std::decay< + decltype(std::declval().template element())>::type; + using KeyType = typename UnitType::key_type; + char stack_buffer[sizeof(KeyType)]; + KeyType *user_key = (KeyType *)stack_buffer; + new (user_key) KeyType(); + int64_t des_pos = 0; + if (MDS_FAIL(user_key->deserialize(data_buf.ptr(), data_buf.length(), des_pos))) { + databuff_printf(buf, buf_len, pos, "user_key:ERROR:%d", ret); + } else { + databuff_printf(buf, buf_len, pos, "%s", to_cstring(*user_key)); + } + user_key->~KeyType(); + } else { + help_print_key(mds_unit_id, data_buf, buf, buf_len, pos); + } + } + template <> + void help_print_key(const uint8_t mds_unit_id, + const ObString &data_buf, + char *buf, + const int64_t buf_len, + int64_t &pos) + { + databuff_printf(buf, buf_len, pos, + "user_key:ERROR:unit_id not in tuple(%ld)", (int64_t)mds_unit_id); + } + template + void help_print_data(const uint8_t mds_unit_id, + const ObString &data_buf, + char *buf, + const int64_t buf_len, + int64_t &pos) + { + int ret = OB_SUCCESS; + MDS_TG(1_ms); + if (IDX == mds_unit_id) { + using UnitType = typename std::decay< + decltype(std::declval().template element())>::type; + using ValueType = typename UnitType::value_type; + char stack_buffer[sizeof(ValueType)]; + ValueType *user_data = (ValueType *)stack_buffer; + new (user_data) ValueType(); + int64_t des_pos = 0; + meta::MetaSerializer serializer(DefaultAllocator::get_instance(), *user_data); + if (MDS_FAIL(serializer.deserialize(data_buf.ptr(), data_buf.length(), des_pos))) { + databuff_printf(buf, buf_len, pos, "user_data:ERROR:%d", ret); + } else { + databuff_printf(buf, buf_len, pos, "user_data:%s", to_cstring(*user_data)); + } + user_data->~ValueType(); + } else { + help_print_data(mds_unit_id, data_buf, buf, buf_len, pos); + } + } + template <> + void help_print_data(const uint8_t mds_unit_id, + const ObString &data_buf, + char *buf, + const int64_t buf_len, + int64_t &pos) + { + databuff_printf(buf, buf_len, pos, + "user_data:ERROR:mds_unit_id not in tuple(%ld)", (int64_t)mds_unit_id); + } + }; + template + void help_print(const bool need_print_key, + const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const ObString &data_buf, + char *buf, + const int64_t buf_len, + int64_t &pos) + { + MDS_TG(1_ms); + int ret = OB_SUCCESS; + if (IDX == mds_table_id) { + using MdsTableType = typename std::decay< + decltype(std::declval().element())>::type; + InnerDeserializePrintHelper inner_helper; + if (need_print_key) { + inner_helper.template help_print_key<0>(mds_unit_id, data_buf, buf, buf_len, pos); + } else { + inner_helper.template help_print_data<0>(mds_unit_id, data_buf, buf, buf_len, pos); + } + } else { + help_print(need_print_key, mds_table_id, mds_unit_id, data_buf, buf, buf_len, pos); + } + } + template <> + void help_print(const bool need_print_key, + const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const ObString &data_buf, + char *buf, + const int64_t buf_len, + int64_t &pos) + { + databuff_printf(buf, buf_len, pos, + "user_data:ERROR:table_id not in tuple(%ld)", (int64_t)mds_table_id); + } +}; + +bool MdsDumpKey::is_valid() const +{ + return mds_table_id_ != UINT8_MAX && mds_unit_id_ != UINT8_MAX; +} + +int MdsDumpKey::compare(const MdsDumpKey &rhs, int &result) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(rhs), K(result) + MDS_TG(1_ms); + int ret = OB_SUCCESS; + DeserializeCompareHelper helper; + if (rhs.mds_table_id_ != mds_table_id_) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_NONE(ERROR, "can not compare in different mds table"); + } else if (rhs.mds_unit_id_ != mds_unit_id_) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_NONE(ERROR, "can not compare in different unit"); + } else if (MDS_FAIL(helper.help_compare<0>(*this, rhs, result))) { + MDS_LOG_NONE(ERROR, "fail to do compare operation"); + } + return ret; + #undef PRINT_WRAPPER +} + +bool MdsDumpNode::is_valid() const +{ + return mds_table_id_ != UINT8_MAX && mds_unit_id_ != UINT8_MAX; +} + +void MdsDumpNode::reset() { + MDS_TG(1_ms); + if (OB_NOT_NULL(allocator_)) { + if (OB_NOT_NULL(user_data_.ptr())) { + allocator_->free(user_data_.ptr()); + } + allocator_ = nullptr; + } + user_data_.reset(); + new (this) MdsDumpNode(); +} + +uint32_t MdsDumpNode::generate_hash() const +{ + #define PRINT_WRAPPER K(*this) + MDS_TG(1_ms); + uint64_t result = 0; + result = murmurhash(&mds_table_id_, sizeof(mds_table_id_), result); + result = murmurhash(&mds_unit_id_, sizeof(mds_unit_id_), result); + result = murmurhash(&writer_id_, sizeof(writer_id_), result); + result = murmurhash(&seq_no_, sizeof(seq_no_), result); + result = murmurhash(&redo_scn_, sizeof(redo_scn_), result); + result = murmurhash(&end_scn_, sizeof(end_scn_), result); + result = murmurhash(&trans_version_, sizeof(trans_version_), result); + result = murmurhash(&status_.union_.value_, sizeof(status_.union_.value_), result); + if (user_data_.empty()) { + const int64_t ret = OB_ERR_SYS;//only used for log + MDS_LOG_NONE(ERROR, "user data should not be empty"); + } else { + result = murmurhash(user_data_.ptr(), user_data_.length(), result); + } + return static_cast(result); + #undef PRINT_WRAPPER +} + +int64_t MdsDumpKey::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + DeserializePrintHelper print_helper; + print_helper.help_print<0>(true, mds_table_id_, mds_unit_id_, key_, buf, buf_len, pos); + return pos; +} + +int64_t MdsDumpNode::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + databuff_printf(buf, buf_len, pos, "{"); + databuff_printf(buf, buf_len, pos, "mds_table_id:%ld, ", (int64_t)mds_table_id_); + databuff_printf(buf, buf_len, pos, "mds_unit_id:%ld, ", (int64_t)mds_unit_id_); + databuff_printf(buf, buf_len, pos, "crc:0x%lx, ", (int64_t)crc_check_number_); + databuff_printf(buf, buf_len, pos, "allocator:%p, ", (void*)allocator_); + databuff_printf(buf, buf_len, pos, "writer_id:%ld, ", writer_id_); + databuff_printf(buf, buf_len, pos, "seq_no:%ld, ", seq_no_); + databuff_printf(buf, buf_len, pos, "redo_scn:%s, ", obj_to_string(redo_scn_)); + databuff_printf(buf, buf_len, pos, "end_scn:%s, ", obj_to_string(end_scn_)); + databuff_printf(buf, buf_len, pos, "trans_version:%s, ", obj_to_string(trans_version_)); + databuff_printf(buf, buf_len, pos, "status:%s, ", to_cstring(status_)); + DeserializePrintHelper print_helper; + if (user_data_.empty()) { + databuff_printf(buf, buf_len, pos, "user_data:null"); + } else { + print_helper.help_print<0>(false, mds_table_id_, mds_unit_id_, user_data_, buf, buf_len, pos); + } + databuff_printf(buf, buf_len, pos, "}"); + return pos; +} + +int64_t MdsDumpNode::simple_to_string(char *buf, const int64_t buf_len, int64_t &pos) const +{ + databuff_printf(buf, buf_len, pos, "{status:%s, ", to_cstring(status_)); + DeserializePrintHelper print_helper; + if (user_data_.empty()) { + databuff_printf(buf, buf_len, pos, "user_data:null"); + } else { + print_helper.help_print<0>(false, mds_table_id_, mds_unit_id_, user_data_, buf, buf_len, pos); + } + databuff_printf(buf, buf_len, pos, "}"); + return pos; +} + +int MdsDumpKey::assign(const MdsDumpKey &rhs, ObIAllocator &alloc) +{ + int ret = OB_SUCCESS; + + if (this != &rhs) { + char *buffer = nullptr; + const common::ObString &rhs_key = rhs.key_; + const int64_t length = rhs_key.length(); + reset(); + + if (!rhs_key.empty()) { + if (OB_ISNULL(buffer = static_cast(alloc.alloc(length)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG(WARN, "fail to alloc memory", KR(ret), K(length)); + } else if (FALSE_IT(key_.assign_buffer(buffer, length))) { + } else if (OB_UNLIKELY(length != key_.write(rhs_key.ptr(), length))) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(WARN, "failed to write key", K(ret), K(length)); + } + } + if (OB_SUCC(ret)) { + mds_table_id_ = rhs.mds_table_id_; + mds_unit_id_ = rhs.mds_unit_id_; + crc_check_number_ = rhs.crc_check_number_; + } + } + + return ret; +} + +int MdsDumpNode::assign(const MdsDumpNode &rhs, ObIAllocator &alloc) +{ + int ret = OB_SUCCESS; + + if (this != &rhs) { + char *buffer = nullptr; + const common::ObString &rhs_user_data = rhs.user_data_; + const int64_t length = rhs_user_data.length(); + reset(); + + if (0 == length) { + // dump node is empty, do nothing + } else if (OB_ISNULL(buffer = static_cast(alloc.alloc(length)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG(WARN, "fail to alloc memory", KR(ret), K(length)); + } + + if (OB_FAIL(ret)) { + } else { + mds_table_id_ = rhs.mds_table_id_; + mds_unit_id_ = rhs.mds_unit_id_; + crc_check_number_ = rhs.crc_check_number_; + status_ = rhs.status_; + allocator_ = &alloc; + writer_id_ = rhs.writer_id_; + seq_no_ = rhs.seq_no_; + redo_scn_ = rhs.redo_scn_; + end_scn_ = rhs.end_scn_; + trans_version_ = rhs.trans_version_; + if (0 == length) { + } else if (FALSE_IT(user_data_.assign_buffer(buffer, length))) { + } else if (OB_UNLIKELY(length != user_data_.write(rhs_user_data.ptr(), length))) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(WARN, "failed to write user data", K(ret), K(length)); + } + } + } + + + return ret; +} + +MdsDumpKV::MdsDumpKV() + : k_(), + v_() +{ +} + +void MdsDumpKV::reset() +{ + k_.reset(); + v_.reset(); +} + +int64_t MdsDumpKV::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + databuff_printf(buf, buf_len, pos, "{"); + databuff_printf(buf, buf_len, pos, "k:%s, ", to_cstring(k_)); + databuff_printf(buf, buf_len, pos, "v:%s", to_cstring(v_)); + databuff_printf(buf, buf_len, pos, "}"); + return pos; +} + +bool MdsDumpKV::is_valid() const +{ + return k_.is_valid() && v_.is_valid(); // TODO(@bowen.gbw): add more rules +} + +int MdsDumpKV::assign(const MdsDumpKV &rhs, ObIAllocator &alloc) +{ + int ret = OB_SUCCESS; + if (this != &rhs) { + reset(); + + if (OB_FAIL(k_.assign(rhs.k_, alloc))) { + MDS_LOG(WARN, "fail to assign key", KR(ret)); + } else if (OB_FAIL(v_.assign(rhs.v_, alloc))) { + MDS_LOG(WARN, "fail to assign value", KR(ret)); + } + if (OB_FAIL(ret)) { + if (OB_NOT_NULL(k_.key_.ptr())) { + alloc.free(k_.key_.ptr()); + k_.key_.reset(); + } + if (OB_NOT_NULL(v_.user_data_.ptr())) { + alloc.free(v_.user_data_.ptr()); + v_.user_data_.reset(); + } + } + } + return ret; +} + +int MdsDumpKV::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + + LST_DO_CODE(OB_UNIS_ENCODE, + UNIS_VERSION, + k_, + v_); + + return ret; +} + +int MdsDumpKV::deserialize(common::ObIAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + int64_t version = 0; + + LST_DO_CODE(OB_UNIS_DECODE, + version, + k_); + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(v_.deserialize(allocator, buf, data_len, pos))) { + MDS_LOG(WARN, "failed to deserialize", K(ret)); + } + + return ret; +} + +int64_t MdsDumpKV::get_serialize_size() const +{ + int64_t len = 0; + + LST_DO_CODE(OB_UNIS_ADD_LEN, + UNIS_VERSION, + k_, + v_); + + return len; +} + +int MdsDumpNode::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + + LST_DO_CODE(OB_UNIS_ENCODE, + UNIS_VERSION, + mds_table_id_, + mds_unit_id_, + writer_id_, + seq_no_, + redo_scn_, + end_scn_, + trans_version_, + status_, + crc_check_number_, + user_data_); + + return ret; +} + +int MdsDumpNode::deserialize(common::ObIAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + int64_t version = 0; + ObString user_data; + + LST_DO_CODE(OB_UNIS_DECODE, + version, + mds_table_id_, + mds_unit_id_, + writer_id_, + seq_no_, + redo_scn_, + end_scn_, + trans_version_, + status_, + crc_check_number_, + user_data); + + if (OB_SUCC(ret)) { + allocator_ = &allocator; + const int64_t len = user_data.length(); + char *buffer = nullptr; + if (0 == len) { + } else if (OB_ISNULL(buffer = static_cast(allocator_->alloc(len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG(WARN, "failed to allocate memory", K(ret), K(len)); + } else { + MEMCPY(buffer, user_data.ptr(), len); + user_data_.assign(buffer, len); + } + } + + return ret; +} + +int64_t MdsDumpNode::get_serialize_size() const +{ + int64_t len = 0; + + LST_DO_CODE(OB_UNIS_ADD_LEN, + UNIS_VERSION, + mds_table_id_, + mds_unit_id_, + writer_id_, + seq_no_, + redo_scn_, + end_scn_, + trans_version_, + status_, + crc_check_number_, + user_data_); + + return len; +} + +} +} +} diff --git a/src/storage/multi_data_source/adapter_define/mds_dump_node.h b/src/storage/multi_data_source/adapter_define/mds_dump_node.h new file mode 100644 index 000000000..00bf49924 --- /dev/null +++ b/src/storage/multi_data_source/adapter_define/mds_dump_node.h @@ -0,0 +1,292 @@ +#ifndef SHARE_STORAGE_MULTI_DATA_SOURCE_MDSDUMPNODE_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_MDSDUMPNODE_H +#include "lib/allocator/ob_allocator.h" +#include "lib/ob_errno.h" +#include "lib/hash_func/murmur_hash.h" +#include "lib/utility/ob_unify_serialize.h" +#include "share/ob_ls_id.h" +#include "src/storage/multi_data_source/compile_utility/compile_mapper.h" +#include "src/storage/multi_data_source/mds_node.h" +#include "src/storage/multi_data_source/compile_utility/map_type_index_in_tuple.h" +#include "src/storage/multi_data_source/runtime_utility/mds_factory.h" +#include "storage/multi_data_source/compile_utility/mds_dummy_key.h" +#include +#include "common/meta_programming/ob_meta_serialization.h" + + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +struct MdsDumpKey; +struct MdsDumpNode; + +struct MdsDumpKey// RAII +{ + OB_UNIS_VERSION(1); +public: + MdsDumpKey() : mds_table_id_(UINT8_MAX), mds_unit_id_(UINT8_MAX), allocator_(nullptr) {} + ~MdsDumpKey() { reset(); } + template + int init(const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const UnitKey &key, + ObIAllocator &alloc); + int assign(const MdsDumpKey &rhs, common::ObIAllocator &alloc); + template + int convert_to_user_key(UnitKey &user_key) const; + void reset(); + int compare(const MdsDumpKey &rhs, int &result) const; + uint32_t generate_hash() const; + bool is_valid() const; + int64_t to_string(char *, const int64_t) const; +public: + uint8_t mds_table_id_; + uint8_t mds_unit_id_; + uint32_t crc_check_number_; + ObIAllocator *allocator_;// to release serialized buffer + common::ObString key_; +}; +OB_SERIALIZE_MEMBER_TEMP(inline, MdsDumpKey, mds_table_id_, mds_unit_id_, crc_check_number_, key_); + +struct MdsDumpNode// RAII +{ +public: + MdsDumpNode() : + mds_table_id_(UINT8_MAX), + mds_unit_id_(UINT8_MAX), + crc_check_number_(UINT32_MAX), + allocator_(nullptr), + writer_id_(INVALID_VALUE), + seq_no_(INVALID_VALUE) {}// deserialize need default construction + ~MdsDumpNode() { reset(); } + // disallow copy, assign and move sematic + MdsDumpNode(const MdsDumpNode &) = delete; + MdsDumpNode(MdsDumpNode &&) = delete; + MdsDumpNode& operator=(const MdsDumpNode &) = delete; + MdsDumpNode& operator=(MdsDumpNode &&) = delete; + + bool is_valid() const; + // every dump node is converted from UserMdsNode from a multi-version row in a K-V unit in MdsTable + template + int init(const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const UserMdsNode &user_mds_node, + ObIAllocator &alloc); + // can be compared(only can be compared in same unit, compare key first, compare version if key is same) + int compare(const MdsDumpNode& rhs, int &result); + void reset(); + uint32_t generate_hash() const; + // print + int64_t to_string(char *buf, const int64_t buf_len) const; + int64_t simple_to_string(char *buf, const int64_t buf_len, int64_t &pos) const; + template + int convert_to_user_mds_node(UserMdsNode &user_mds_node, const share::ObLSID &ls_id, const ObTabletID &tablet_id) const; + + int assign(const MdsDumpNode &rhs, ObIAllocator &alloc); + + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize(common::ObIAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos); + int64_t get_serialize_size() const; + + static const int64_t UNIS_VERSION = 1; + + // member state + uint8_t mds_table_id_; + uint8_t mds_unit_id_; + uint32_t crc_check_number_; + MdsNodeStatus status_; + ObIAllocator *allocator_;// to release serialized buffer + int64_t writer_id_; // mostly is tx id + int64_t seq_no_;// not used for now + share::SCN redo_scn_; // log scn of redo + share::SCN end_scn_; // log scn of commit/abort + share::SCN trans_version_; // read as prepare version if phase is not COMMIT, or read as commit version + common::ObString user_data_;// different user data type serialized result(may be very large, but should be less than 1.5MB) +}; + +struct MdsDumpKV +{ +public: + MdsDumpKV(); +public: + void reset(); + bool is_valid() const; + int assign(const MdsDumpKV &rhs, ObIAllocator &alloc); + + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize(common::ObIAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos); + int64_t get_serialize_size() const; + + int64_t to_string(char *buf, const int64_t buf_len) const; +public: + static const int64_t UNIS_VERSION = 1; + MdsDumpKey k_; + MdsDumpNode v_; +}; + +template +int MdsDumpKey::init(const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const UnitKey &key, + ObIAllocator &alloc) +{ + #define PRINT_WRAPPER KR(ret), K(mds_table_id), K(mds_unit_id), K(key), K(key_size) + int ret = OB_SUCCESS; + MDS_TG(1_ms); + int64_t key_size = key.get_serialize_size(); + int64_t pos = 0; + char *key_buffer = nullptr; + bool need_free_key_buffer = false; + reset(); + if (MDS_FAIL_FLAG(OB_ISNULL(key_buffer = (char*)alloc.alloc(key_size)), need_free_key_buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG_NONE(WARN, "fail to alloc key serlialize buffer"); + } else if (OB_FAIL(key.serialize(key_buffer, key_size, pos))) { + MDS_LOG_NONE(WARN, "fail to serialize key"); + } else { + crc_check_number_ = generate_hash(); + mds_table_id_ = mds_table_id; + mds_unit_id_ = mds_unit_id; + allocator_ = &alloc; + key_.assign(key_buffer, key_size); + } + if (MDS_FAIL(ret)) { + if (need_free_key_buffer) { + allocator_->free(key_buffer); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template <> +inline int MdsDumpKey::init(const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const DummyKey &key, + ObIAllocator &alloc) +{ + UNUSED(key); + UNUSED(alloc); + reset(); + mds_table_id_ = mds_table_id; + mds_unit_id_ = mds_unit_id; + crc_check_number_ = generate_hash(); + return OB_SUCCESS; +} + +template +int MdsDumpNode::init(const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const UserMdsNode &user_mds_node, + ObIAllocator &alloc) +{ + #define PRINT_WRAPPER KR(ret), K(user_mds_node), K(data_size) + int ret = OB_SUCCESS; + MDS_TG(1_ms); + int64_t pos = 0; + bool need_free_data_buffer = false; + int64_t data_size = user_mds_node.user_data_.get_serialize_size(); + char *data_buffer = nullptr; + reset(); + if (MDS_FAIL_FLAG(OB_ISNULL(data_buffer = (char*)alloc.alloc(data_size)), + need_free_data_buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG_NONE(WARN, "fail to alloc data serlialize buffer"); + } else if (OB_FAIL(user_mds_node.user_data_.serialize(data_buffer, data_size, pos))) { + MDS_LOG_NONE(WARN, "fail to serialize user data"); + } else { + mds_table_id_ = mds_table_id; + mds_unit_id_ = mds_unit_id; + allocator_ = &alloc; + writer_id_ = user_mds_node.writer_id_; + seq_no_ = user_mds_node.seq_no_; + redo_scn_ = user_mds_node.redo_scn_; + end_scn_ = user_mds_node.end_scn_; + trans_version_ = user_mds_node.trans_version_; + status_ = user_mds_node.status_; + user_data_.assign(data_buffer, data_size); + crc_check_number_ = generate_hash(); + } + // roll back path + if (MDS_FAIL(ret)) { + if (need_free_data_buffer) { + alloc.free(data_buffer); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template +int MdsDumpKey::convert_to_user_key(UnitKey &user_key) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(generated_hash), K(typeid(UnitKey).name()) + int ret = OB_SUCCESS; + MDS_TG(1_ms); + int64_t pos = 0; + uint32_t generated_hash = generate_hash(); + if (generated_hash != crc_check_number_) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_NONE(ERROR, "CRC CHECK FAILED!"); + } else if (MDS_FAIL(user_key.deserialize(key_.ptr(), key_.length(), pos))) { + MDS_LOG_NONE(ERROR, "deserialize user data failed"); + } else { + } + return ret; + #undef PRINT_WRAPPER +} + +template <> +inline int MdsDumpKey::convert_to_user_key(DummyKey &user_key) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(generated_hash) + int ret = OB_SUCCESS; + MDS_TG(1_ms); + int64_t pos = 0; + uint32_t generated_hash = generate_hash(); + if (generated_hash != crc_check_number_) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_NONE(ERROR, "CRC CHECK FAILED!"); + } else { + } + return ret; + #undef PRINT_WRAPPER +} + +template +int MdsDumpNode::convert_to_user_mds_node(UserMdsNode &user_mds_node, const share::ObLSID &ls_id, const ObTabletID &tablet_id) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(generated_hash), K(typeid(V).name()) + int ret = OB_SUCCESS; + MDS_TG(1_ms); + int64_t pos = 0; + uint32_t generated_hash = generate_hash(); + set_mds_mem_check_thread_local_info(ls_id, tablet_id, typeid(UserMdsNode).name()); + meta::MetaSerializer serializer(MdsAllocator::get_instance(), user_mds_node.user_data_); + if (generated_hash != crc_check_number_) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_NONE(ERROR, "CRC CHECK FAILED!"); + } else if (MDS_FAIL(serializer.deserialize(user_data_.ptr(), user_data_.length(), pos))) { + MDS_LOG_NONE(ERROR, "deserialize user data failed"); + } else { + user_mds_node.writer_id_ = writer_id_; + user_mds_node.seq_no_ = seq_no_; + user_mds_node.redo_scn_ = redo_scn_; + user_mds_node.end_scn_ = end_scn_; + user_mds_node.trans_version_ = trans_version_; + user_mds_node.status_ = status_; + } + reset_mds_mem_check_thread_local_info(); + return ret; + #undef PRINT_WRAPPER +} + +} +} +} + +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/buffer_ctx.cpp b/src/storage/multi_data_source/buffer_ctx.cpp new file mode 100644 index 000000000..1cb0a0764 --- /dev/null +++ b/src/storage/multi_data_source/buffer_ctx.cpp @@ -0,0 +1,136 @@ +#include "buffer_ctx.h" +#include "lib/ob_define.h" +#include "lib/ob_errno.h" +#include "lib/utility/ob_print_utils.h" +#include "lib/utility/serialization.h" +#include "lib/utility/utility.h" +#include "runtime_utility/mds_factory.h" +#include "compile_utility/map_type_index_in_tuple.h" +#include "share/rc/ob_tenant_base.h" +#include "storage/multi_data_source/compile_utility/compile_mapper.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/multi_data_source/mds_writer.h" +#include "storage/multi_data_source/runtime_utility/common_define.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" +#include "storage/tx/ob_trans_define.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +void BufferCtxNode::destroy_ctx() { + if (OB_NOT_NULL(ctx_)) { + ctx_->~BufferCtx(); + MTL(mds::ObTenantMdsService*)->get_buffer_ctx_allocator().free(ctx_); + ctx_ = nullptr; + } +} + +int BufferCtxNode::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + MDS_TG(10_ms); + if (OB_NOT_NULL(ctx_)) { + // 序列化时,如果ctx不为空,那么其类型必须是有效的,这里防御一下,否则反序列化的报错会增加排查难度 + OB_ASSERT(ctx_->get_binding_type_id() != INVALID_VALUE); + int64_t type_id = ctx_->get_binding_type_id(); + if (MDS_FAIL(serialization::encode(buf, buf_len, pos, type_id))) { + MDS_LOG(ERROR, "serialize buffer ctx id failed", KR(ret), K(type_id)); + } else if (MDS_FAIL(ctx_->serialize(buf, buf_len, pos))) { + MDS_LOG(ERROR, "serialize buffer ctx impl failed", KR(ret), K(type_id)); + } else { + MDS_LOG(DEBUG, "serialize buffer ctx impl success", KR(ret), K(type_id), K(buf_len), K(pos)); + } + } else { + int64_t type_id = INVALID_VALUE; + if (MDS_FAIL(serialization::encode(buf, buf_len, pos, type_id))) { + MDS_LOG(ERROR, "serialize invalid buffer ctx id failed", KR(ret), K(type_id)); + } else { + MDS_LOG(DEBUG, "serialize invalid buffer ctx id failed", KR(ret), K(type_id), K(buf_len), K(pos)); + } + } + return ret; +} + +template +int deserialize_(BufferCtx *&ctx_, int64_t type_idx, const char *buf, const int64_t buf_len, int64_t &pos) { + int ret = OB_SUCCESS; + MDS_TG(10_ms); + if (IDX == type_idx) { + using ImplType = GET_CTX_TYPE_BY_TUPLE_IDX(IDX); + ImplType *p_impl = nullptr; + set_mds_mem_check_thread_local_info(MdsWriter(WriterType::UNKNOWN_WRITER, 0), typeid(ImplType).name()); + if (OB_ISNULL(p_impl = (ImplType *)MTL(ObTenantMdsService*)->get_buffer_ctx_allocator().alloc(sizeof(ImplType), + ObMemAttr(MTL_ID(), + "MDS_CTX_DESE", + ObCtxIds::MDS_CTX_ID)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG(ERROR, "fail to alloc buffer ctx memory", KR(ret), K(type_idx), K(IDX)); + } else if (FALSE_IT(new (p_impl) ImplType())) { + } else if (MDS_FAIL(p_impl->deserialize(buf, buf_len, pos))) { + MTL(mds::ObTenantMdsService*)->get_buffer_ctx_allocator().free(p_impl); + p_impl = nullptr; + MDS_LOG(ERROR, "deserialzed from buffer failed", KR(ret), K(type_idx), K(IDX)); + } else { + ctx_ = p_impl; + ctx_->set_binding_type_id(type_idx); + MTL(ObTenantMdsService*)->update_mem_leak_debug_info(p_impl, [p_impl](const ObIntWarp &key, + ObMdsMemoryLeakDebugInfo &value) -> bool { + databuff_printf(value.tag_str_, TAG_SIZE, "%s", to_cstring(p_impl->get_writer())); + return true; + }); + MDS_LOG(INFO, "deserialize ctx success", KR(ret), K(*p_impl), K(type_idx), K(IDX), K(buf_len), K(pos), K(lbt())); + } + reset_mds_mem_check_thread_local_info(); + } else if (MDS_FAIL(deserialize_(ctx_, type_idx, buf, buf_len, pos))) { + MDS_LOG(ERROR, "deserialzed from buffer failed", KR(ret), K(type_idx), K(IDX)); + } + return ret; +} + +template <> +int deserialize_(BufferCtx *&ctx_, + int64_t type_idx, + const char *buf, + const int64_t buf_len, + int64_t &pos) +{ + int ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "type idx out of tuple range", KR(ret), K(type_idx), K(BufferCtxTupleHelper::get_element_size())); + return ret; +} + +int BufferCtxNode::deserialize(const char *buf, const int64_t buf_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + MDS_TG(10_ms); + int64_t type_idx = INVALID_VALUE; + if (MDS_FAIL(serialization::decode(buf, buf_len, pos, type_idx))) { + MDS_LOG(ERROR, "fail to deserialize buffer ctx id", KR(ret), K(type_idx)); + } else if (INVALID_VALUE == type_idx) { + MDS_LOG(DEBUG, "deserialized INVALD buffer ctx", KR(ret), K(type_idx), K(buf_len), K(pos)); + } else if (MDS_FAIL(deserialize_<0>(ctx_, type_idx, buf, buf_len, pos))) { + MDS_LOG(WARN, "deserialized buffer ctx failed", KR(ret), K(type_idx)); + } + return ret; +} + +int64_t BufferCtxNode::get_serialize_size(void) const +{ + int64_t size = 0; + if (OB_NOT_NULL(ctx_)) { + size += serialization::encoded_length(ctx_->get_binding_type_id()); + size += ctx_->get_serialize_size(); + } else { + size += serialization::encoded_length(INVALID_VALUE); + } + return size; +} + +} +} +} diff --git a/src/storage/multi_data_source/buffer_ctx.h b/src/storage/multi_data_source/buffer_ctx.h new file mode 100644 index 000000000..c1d5a30df --- /dev/null +++ b/src/storage/multi_data_source/buffer_ctx.h @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2021 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 SHARE_STORAGE_MULTI_DATA_SOURCE_BUFFER_CTX_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_BUFFER_CTX_H + +#include "lib/ob_define.h" +#include "lib/oblog/ob_log_module.h" +#include "runtime_utility/common_define.h" +#include "mds_writer.h" + +namespace oceanbase +{ +namespace share +{ +class SCN; +} + +namespace storage +{ +namespace mds +{ + +class BufferCtx +{ +public: + BufferCtx() : binding_type_id_(INVALID_VALUE) {} + virtual ~BufferCtx() {} + void set_binding_type_id(const int64_t type_id) { binding_type_id_ = type_id; } + int64_t get_binding_type_id() const { return binding_type_id_; } + // 允许用户重写的方法 + virtual const MdsWriter get_writer() const = 0; + virtual void on_redo(const share::SCN &redo_scn) {} + virtual void before_prepare() {} + virtual void on_prepare(const share::SCN &prepare_version) {} + virtual void on_commit(const share::SCN &commit_version, const share::SCN &commit_scn) {} + virtual void on_abort(const share::SCN &abort_scn) {} + // 事务上下文恢复的时候需要从事务状态表将BufferCtx深拷贝至事务上下文 + virtual int deep_copy(BufferCtx &) const { return common::OB_SUCCESS; } + virtual int64_t get_impl_binging_type_id() { return 0; }// 在事务层反序列化和深拷贝时需要得知子类对象的类型 + + virtual int64_t to_string(char*, const int64_t buf_len) const = 0; + // 同事务状态一起持久化以及恢复 + virtual int serialize(char*, const int64_t, int64_t&) const = 0; + virtual int deserialize(const char*, const int64_t, int64_t&) = 0; + virtual int64_t get_serialize_size(void) const = 0; +private: + int64_t binding_type_id_; +}; + +// 该结构嵌入事务上下文中,与多数据源的BufferNode一一对应,同事务状态一起持久化以及恢复 +// 多数据源框架负责维护该结构内的状态 +// 事务层需要在指定的事件节点调用该结构对应的接口 +class BufferCtxNode +{ +public: + BufferCtxNode() : ctx_(nullptr) {} + void set_ctx(BufferCtx *ctx) { OB_ASSERT(ctx_ == nullptr); ctx_ = ctx; }// 预期不应该出现覆盖的情况 + const BufferCtx *get_ctx() const { return ctx_; } + void destroy_ctx(); + void on_redo(const share::SCN &redo_scn) { ctx_->on_redo(redo_scn); } + void before_prepare() { ctx_->before_prepare(); } + void on_prepare(const share::SCN &prepare_version) { ctx_->on_prepare(prepare_version); } + void on_commit(const share::SCN &commit_version, const share::SCN &commit_scn) { + MDS_LOG(INFO, "buffer ctx on commit", KP(this), K(*this)); + ctx_->on_commit(commit_version, commit_scn); + } + void on_abort(const share::SCN &abort_scn) { + MDS_LOG(INFO, "buffer ctx on abort", KP(this), K(*this)); + ctx_->on_abort(abort_scn); + } + // 同事务状态一起持久化以及恢复 + int serialize(char*, const int64_t, int64_t&) const;// 要把实际的ctx类型编码进二进制中 + int deserialize(const char*, const int64_t, int64_t&);// 要根据实际的ctx的类型,在编译期反射子类类型 + int64_t get_serialize_size(void) const; + TO_STRING_KV(KP(this), KP_(ctx), KPC_(ctx)); +private: + BufferCtx *ctx_; +}; + +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/compile_utility/compile_mapper.h b/src/storage/multi_data_source/compile_utility/compile_mapper.h new file mode 100644 index 000000000..b58284699 --- /dev/null +++ b/src/storage/multi_data_source/compile_utility/compile_mapper.h @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2021 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 SHARE_STORAGE_MULTI_DATA_SOURCE_COMPILE_MAPPER_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_COMPILE_MAPPER_H +#define NEED_MDS_REGISTER_DEFINE +#include "mds_register.h" +#undef NEED_MDS_REGISTER_DEFINE +#include "map_type_index_in_tuple.h" +#include "deps/oblib/src/common/meta_programming/ob_type_traits.h" +#include "deps/oblib/src/common/meta_programming/ob_meta_compare.h" +#include "deps/oblib/src/common/meta_programming/ob_meta_copy.h" + +// 这个文件负责生成两个编译期的映射关系,一个是从Helper类型和BufferCtx类型到ID的映射,以及反向映射 +// 另一个是从Data类型到多版本标志的映射,不需要反向映射 +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +template +class __TypeMapper {}; + +template +class __IDMapper {}; + +// 调用以下宏生成编译期的 TYPE <-> ID 映射关系 +#define REGISTER_TYPE_ID(HELPER, CTX, ID) \ +template <>\ +class __TypeMapper {\ +public:\ + static const std::uint64_t id = ID;\ +};\ +template <>\ +class __IDMapper {\ +public:\ + typedef HELPER helper_type;\ + typedef CTX ctx_type;\ +}; + +#define NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION +#define _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_(helper_type, buffer_ctx_type, ID, TEST) \ +REGISTER_TYPE_ID(helper_type, buffer_ctx_type, ID) +#include "mds_register.h" +#undef _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_ +#undef NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION + +// 通过以下宏在编译期获取这些信息 +template +struct TupleIdxType { + typedef typename std::decay().template element())>::type type; +}; +template +struct TupleTypeIdx { + template + static constexpr int64_t get_type_idx() { + return std::is_same::type>::value ? + IDX : + get_type_idx(); + } + template <> + static constexpr int64_t get_type_idx() { + return Tuple::get_element_size(); + } + static constexpr int64_t value = get_type_idx<0>(); +}; +#define GET_HELPER_TYPE_BY_ID(ID) __IDMapper::helper_type +#define GET_HELPER_ID_BY_TYPE(T) __TypeMapper::id +#define GET_CTX_TYPE_BY_ID(ID) __IDMapper::ctx_type +#define GET_CTX_TYPE_BY_TUPLE_IDX(IDX) \ +typename std::decay().element())>::type + +#define GET_MULTIVERSION_FLAG(K, V) get_multi_version_flag() + +#undef REGISTER_TYPE_ID +#undef REGISTER_TYPE_MULTI_VERSION_FLAG + +} +} +} + +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/compile_utility/map_type_index_in_tuple.h b/src/storage/multi_data_source/compile_utility/map_type_index_in_tuple.h new file mode 100644 index 000000000..68fcce45e --- /dev/null +++ b/src/storage/multi_data_source/compile_utility/map_type_index_in_tuple.h @@ -0,0 +1,53 @@ +#ifndef SHARE_STORAGE_MULTI_DATA_SOURCE_MAP_TYPE_INDEX_IN_TUPLE_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_MAP_TYPE_INDEX_IN_TUPLE_H + +#define NEED_MDS_REGISTER_DEFINE +#include "mds_register.h" +#undef NEED_MDS_REGISTER_DEFINE +#include "lib/container/ob_tuple.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +template +struct TypeHelper {}; + +template +struct DropFirstElemtTuple { typedef common::ObTuple type; }; + +#define GENERATE_TEST_MDS_TABLE +#define GENERATE_NORMAL_MDS_TABLE +#define GENERATE_LS_INNER_MDS_TABLE +#define _GENERATE_MDS_UNIT_(KEY_TYPE, VALUE_TYPE, NEED_MULTI_VERSION) \ +,TypeHelper, \ +TypeHelper +typedef DropFirstElemtTuple::type MdsTableTypeHelper; +#undef _GENERATE_MDS_UNIT_ +#undef GENERATE_LS_INNER_MDS_TABLE +#undef GENERATE_NORMAL_MDS_TABLE +#undef GENERATE_TEST_MDS_TABLE + +#define NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION +#define _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_(HELPER_CLASS, BUFFER_CTX_TYPE, ID, ENUM_NAME) \ +,BUFFER_CTX_TYPE +typedef DropFirstElemtTuple::type BufferCtxTupleHelper; +#undef _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_ +#undef NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION + +template +inline constexpr bool get_multi_version_flag() { + return (MdsTableTypeHelper::get_element_index>() & 1) == 0; +} + +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/compile_utility/mds_dummy_key.h b/src/storage/multi_data_source/compile_utility/mds_dummy_key.h new file mode 100644 index 000000000..4ca32f1f3 --- /dev/null +++ b/src/storage/multi_data_source/compile_utility/mds_dummy_key.h @@ -0,0 +1,34 @@ +#ifndef SHARE_STORAGE_MULTI_DATA_SOURCE_COMPILE_UTILITY_MDS_DUMMYKEY_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_COMPILE_UTILITY_MDS_DUMMYKEY_H +#include "lib/list/ob_dlist.h" +#include "lib/ob_errno.h" +#include "lib/ob_define.h" +#include "lib/utility/ob_print_utils.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +struct DummyKey +{ + DummyKey() = default; + int serialize(char *, const int64_t, int64_t &) const { return OB_SUCCESS; } + int deserialize(const char *, const int64_t, int64_t &) { return OB_SUCCESS; } + int64_t get_serialize_size() const { return 0; } + int64_t to_string(char *buf, const int64_t buf_len) const { + int64_t pos = 0; + databuff_printf(buf, buf_len, pos, "Dummy"); + return pos; + } + bool operator<(const DummyKey& rhs) const { return false; } + bool operator==(const DummyKey& rhs) const { return true; } +}; + +} +} +} + +#endif diff --git a/src/storage/multi_data_source/compile_utility/mds_register.h b/src/storage/multi_data_source/compile_utility/mds_register.h new file mode 100644 index 000000000..91f9218a1 --- /dev/null +++ b/src/storage/multi_data_source/compile_utility/mds_register.h @@ -0,0 +1,163 @@ +/************************register header file with class defination********************************/ +// the MDS FRAME must know the defination of some class type to generate legal CPP codes, including: +// 1. DATA type defination if you need multi source data support. +// 1.a. KEY type defination if you need multi source data support with multi key support. +// 2. HELPER FUNCTION type and inherited class of BufferCtx definations if you need multi source +// transaction support. +// inlcude those classes definations header file in below MACRO BLOCK +// CAUTION: MAKE SURE your header file is as CLEAN as possible to avoid recursive dependencies! +#if defined (NEED_MDS_REGISTER_DEFINE) && !defined (NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION) + #include "src/storage/multi_data_source/compile_utility/mds_dummy_key.h" + #include "src/storage/multi_data_source/mds_ctx.h" + #include "unittest/storage/multi_data_source/example_user_data_define.h" + #include "unittest/storage/multi_data_source/example_user_helper_define.h" + #include "src/storage/tablet/ob_tablet_create_delete_mds_user_data.h" + #include "src/storage/tablet/ob_tablet_create_mds_helper.h" + #include "src/storage/tablet/ob_tablet_delete_mds_helper.h" + #include "src/storage/tablet/ob_tablet_binding_helper.h" + #include "src/storage/tablet/ob_tablet_binding_mds_user_data.h" + #include "src/share/ob_tablet_autoincrement_param.h" + #include "src/storage/compaction/ob_medium_compaction_info.h" + #include "src/storage/tablet/ob_tablet_start_transfer_mds_helper.h" + #include "src/storage/tablet/ob_tablet_finish_transfer_mds_helper.h" + #include "src/share/balance/ob_balance_task_table_operator.h" +#endif +/**************************************************************************************************/ + +/**********************generate mds frame code with multi source transaction***********************/ +// GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(HELPER_CLASS, BUFFER_CTX_TYPE, ID, ENUM_NAME) is an +// interface MACRO to transfer necessary information to MDS FRAME to generate codes in transaction +// layer, mostly in ob_multi_data_source.cpp and ob_trans_part_ctx.cpp. +// +// @param HELPER_CLASS the class must has two static method signatures(or COMPILE ERROR): +// 1. static int on_register(const char* buf, +// const int64_t len, +// storage::mds::BufferCtx &ctx);// on leader +// 2. static int on_replay(const char* buf, +// const int64_t len, +// const share::SCN &scn, +// storage::mds::BufferCtx &ctx);// on follower +// the actual ctx's type is BUFFER_CTX_TYPE user registered. +// @param BUFFER_CTX_TYPE must inherited from storage::mds::BufferCtx. +// @param ID for FRAME code reflection reason and compat reason, write the number by INC logic. +// @param ENUM_NAME transaction layer needed, will be defined in enum class +// ObTxDataSourceType(ob_multi_data_source.h) +#define GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(HELPER_CLASS, BUFFER_CTX_TYPE, ID, ENUM_NAME) \ +_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_(HELPER_CLASS, BUFFER_CTX_TYPE, ID, ENUM_NAME) +#ifdef NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::unittest::ExampleUserHelperFunction1,\ + ::oceanbase::storage::mds::MdsCtx,\ + 14,\ + TEST1) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::unittest::ExampleUserHelperFunction2,\ + ::oceanbase::storage::mds::MdsCtx,\ + 15,\ + TEST2) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::unittest::ExampleUserHelperFunction3,\ + ::oceanbase::unittest::ExampleUserHelperCtx,\ + 16,\ + TEST3) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::storage::ObTabletCreateMdsHelper,\ + ::oceanbase::storage::mds::MdsCtx,\ + 3,\ + CREATE_TABLET_NEW_MDS) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::storage::ObTabletDeleteMdsHelper,\ + ::oceanbase::storage::mds::MdsCtx,\ + 4,\ + DELETE_TABLET_NEW_MDS) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::storage::ObTabletUnbindMdsHelper,\ + ::oceanbase::storage::mds::MdsCtx,\ + 7,\ + UNBIND_TABLET_NEW_MDS) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::storage::ObTabletStartTransferOutHelper,\ + ::oceanbase::storage::mds::MdsCtx,\ + 20,\ + START_TRANSFER_OUT) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::storage::ObTabletStartTransferInHelper,\ + ::oceanbase::storage::mds::MdsCtx,\ + 21,\ + START_TRANSFER_IN) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::storage::ObTabletFinishTransferOutHelper,\ + ::oceanbase::storage::mds::MdsCtx,\ + 22,\ + FINISH_TRANSFER_OUT) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::storage::ObTabletFinishTransferInHelper,\ + ::oceanbase::storage::mds::MdsCtx,\ + 23,\ + FINISH_TRANSFER_IN) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::share::ObBalanceTaskMDSHelper,\ + ::oceanbase::storage::mds::MdsCtx,\ + 24,\ + TRANSFER_TASK) +#undef GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION +#endif +/**************************************************************************************************/ + +/**********************generate mds frame code with multi source data******************************/ +// GENERATE_MDS_UNIT(KEY_TYPE, VALUE_TYPE, NEED_MULTI_VERSION) is an +// interface MACRO to transfer necessary information to MDS FRAME to generate codes on MdsTable. +// 1. There are some requirements about class type KEY_TYPE and VALUE_TYPE, if your type is not +// satisfied with below requirments, COMPILE ERROR will occured. +// 2. If you want store your data on normal tablet, write register macro in +// GENERATE_NORMAL_MDS_TABLE block, if you want store your data on LS INNER tablet, write +// register macro in GENERATE_LS_INNER_MDS_TABLE block. +// +// @param KEY_TYPE if you do not need multi row specfied by key, use DummyKey, otherwise, your Key +// type must support: +// 1. has both [bool T::operator==(const T &)] and [bool T::operator<(const T &)], +// or has [int T::compare(const Key &, bool &)] +// 2. be able to_string: [int64_t T::to_string(char *, const int64_t)] +// 3. serializeable(the classic 3 serialize methods) +// 4. copiable, Frame code will try call(ordered): +// a. copy construction: [T::T(const T &)] +// b. assign operator: [T &T::operator=(const T &)] +// c. assign method: [int T::assign(const T &)] +// d. COMPILE ERROR if neither of above method exists. +// @param VALUE_TYPE must support: +// 1. be able to string: [int64_t to_string(char *, const int64_t)] +// 2. serializeable(the classic 3 serialize methods) +// 3. copiable as KEY_TYPE +// 4. (optional) if has [void on_redo(const share::SCN&)] will be called. +// (optional) if has [void on_prepare(const share::SCN&)] will be called. +// (optional) if has [void on_commit(const share::SCN&)] will be called. +// (optional) if has [void on_abort()] will be called. +// CAUTION: DO NOT do heavy action in these optinal functions! +// 5. (optional) optimized if VALUE_TYPE support rvalue sematic. +// @param NEED_MULTI_VERSION if setted true, will remain multi version data, +// or just remain uncommitted and the last committed data. +#define GENERATE_MDS_UNIT(KEY_TYPE, VALUE_TYPE, NEED_MULTI_VERSION) \ +_GENERATE_MDS_UNIT_(KEY_TYPE, VALUE_TYPE, NEED_MULTI_VERSION) +#ifdef GENERATE_TEST_MDS_TABLE + GENERATE_MDS_UNIT(::oceanbase::storage::mds::DummyKey,\ + ::oceanbase::unittest::ExampleUserData1,\ + true) // no need multi row, need multi version + // (complicated data with rvalue optimized) + GENERATE_MDS_UNIT(::oceanbase::storage::mds::DummyKey,\ + ::oceanbase::unittest::ExampleUserData2,\ + true) // no need multi row, need multi version(simple data) + GENERATE_MDS_UNIT(::oceanbase::unittest::ExampleUserKey,\ + ::oceanbase::unittest::ExampleUserData1,\ + false)// need multi row, no need multi version +#endif + +#ifdef GENERATE_NORMAL_MDS_TABLE + GENERATE_MDS_UNIT(::oceanbase::storage::mds::DummyKey,\ + ::oceanbase::storage::ObTabletCreateDeleteMdsUserData,\ + false) + GENERATE_MDS_UNIT(::oceanbase::storage::mds::DummyKey,\ + ::oceanbase::storage::ObTabletBindingMdsUserData,\ + false) + GENERATE_MDS_UNIT(::oceanbase::storage::mds::DummyKey,\ + ::oceanbase::share::ObTabletAutoincSeq,\ + false) + GENERATE_MDS_UNIT(::oceanbase::compaction::ObMediumCompactionInfoKey,\ + ::oceanbase::compaction::ObMediumCompactionInfo,\ + false) +#endif + +#ifdef GENERATE_LS_INNER_MDS_TABLE + GENERATE_MDS_UNIT(::oceanbase::storage::mds::DummyKey,\ + ::oceanbase::unittest::ExampleUserData1,\ + true) // replace this line if you are the first user to register LS INNER TABLET +#endif +/**************************************************************************************************/ diff --git a/src/storage/multi_data_source/mds_ctx.cpp b/src/storage/multi_data_source/mds_ctx.cpp new file mode 100644 index 000000000..849feaec3 --- /dev/null +++ b/src/storage/multi_data_source/mds_ctx.cpp @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2021 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 "mds_ctx.h" +#include "lib/ob_errno.h" +#include "lib/utility/ob_macro_utils.h" +#include "mds_table_handle.h" +#include "share/ob_errno.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +MdsCtx::MdsCtx() : state_(TwoPhaseCommitState::STATE_INIT) {} + +MdsCtx::MdsCtx(const MdsWriter &writer) +: writer_(writer), +state_(TwoPhaseCommitState::STATE_INIT) {} + +MdsCtx::~MdsCtx() +{ + if (!write_list_.empty()) { + MDS_LOG_RET(WARN, OB_ERR_UNEXPECTED, "nodes not commit or abort when mds ctx destroyed", K(*this)); + on_abort(share::SCN::max_scn()); + } +} + +int MdsCtx::assign(const MdsCtx &rhs) { + writer_ = rhs.writer_; + state_ = rhs.state_; + return OB_SUCCESS; +} + +const MdsWriter MdsCtx::get_writer() const { return writer_; } + +void MdsCtx::set_writer(const MdsWriter &writer) +{ + if (state_ != TwoPhaseCommitState::STATE_INIT) { + MDS_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "not allow set writer in non-init state", K(*this), K(writer)); + } else { + writer_.writer_type_ = writer.writer_type_; + writer_.writer_id_ = writer.writer_id_; + } +} + +bool MdsCtx::can_write() const +{ + return state_ == TwoPhaseCommitState::STATE_INIT && + writer_.is_valid(); +} + +void MdsCtx::record_written_node(ListNode *node) +{ + MdsWLockGuard lg(lock_); + write_list_.append(node); +} + +void MdsCtx::on_redo(const share::SCN &redo_scn) +{ + OB_ASSERT(writer_.writer_type_ == WriterType::TRANSACTION);// can only called by TRANS, or must call single_log_commit() + do_while_retry_with_lock_until_success_for_all_([this, redo_scn]() {// if failed on any node, will release lock and try from first node again + return for_each_node_try_([redo_scn](MdsNode &node) {// the operation tried on each node + bool try_success = true; + if (node.redo_scn_.is_max()) {// avoid try lock + try_success = node.try_on_redo(redo_scn); + } + return try_success; + }); + }, TwoPhaseCommitState::STATE_END);// no need advance state +} + +void MdsCtx::before_prepare() +{ + OB_ASSERT(writer_.writer_type_ == WriterType::TRANSACTION);// can only called by TRANS, or must call single_log_commit() + do_while_retry_with_lock_until_success_for_all_([this]() {// if failed on any node, will release lock and try from first node again + return for_each_node_try_([](MdsNode &node) {// the operation tried on each node + bool try_success = true; + if (node.status_.get_state() < TwoPhaseCommitState::BEFORE_PREPARE) {// avoid try lock + try_success = node.try_before_prepare(); + } + return try_success; + }); + }, TwoPhaseCommitState::BEFORE_PREPARE); +} + +void MdsCtx::on_prepare(const share::SCN &prepare_version) +{ + OB_ASSERT(writer_.writer_type_ == WriterType::TRANSACTION);// can only called by TRANS, or must call single_log_commit() + do_while_retry_with_lock_until_success_for_all_([this, prepare_version]() {// if failed on any node, will release lock and try from first node again + return for_each_node_try_([prepare_version](MdsNode &node) {// the operation tried on each node + bool try_success = true; + if (node.status_.get_state() < TwoPhaseCommitState::ON_PREPARE) {// avoid try lock + try_success = node.try_on_prepare(prepare_version); + } + return try_success; + }); + }, TwoPhaseCommitState::ON_PREPARE); +} + +void MdsCtx::on_commit(const share::SCN &commit_version, const share::SCN &commit_scn) +{ + OB_ASSERT(writer_.writer_type_ == WriterType::TRANSACTION);// can only called by TRANS, or must call single_log_commit() + do_while_retry_with_lock_until_success_for_all_([this, commit_version, commit_scn]() {// if failed on any node, will release lock and try from first node again + return for_each_node_fetch_to_try_([commit_version, commit_scn](MdsNode &node) {// the operation tried on each node, if failed, the fetched node will be insert to head again to rollback + bool try_success = true; + if (node.status_.get_state() < TwoPhaseCommitState::ON_COMMIT) {// avoid try lock + try_success = node.try_on_commit(commit_version, commit_scn); + } + return try_success; + }); + }, TwoPhaseCommitState::ON_COMMIT); +} + +void MdsCtx::on_abort(const share::SCN &abort_scn) +{ + do_while_retry_with_lock_until_success_for_all_([this, abort_scn]() {// if failed on any node, will release lock and try from first node again + return for_each_node_fetch_to_try_([abort_scn](MdsNode &node) {// the operation tried on each node, if failed, the fetched node will be insert to head again to rollback + bool try_success = true; + if (node.status_.get_state() < TwoPhaseCommitState::ON_ABORT) {// avoid try lock + try_success = node.try_on_abort(abort_scn); + } + return try_success; + }); + }, TwoPhaseCommitState::ON_ABORT); +} + +void MdsCtx::single_log_commit(const share::SCN commit_version, const share::SCN commit_scn) +{ + do_while_retry_with_lock_until_success_for_all_([this, commit_version, commit_scn]() {// if failed on any node, will release lock and try from first node again + return for_each_node_fetch_to_try_([commit_version, commit_scn](MdsNode &node) {// the operation tried on each node, if failed, the fetched node will be insert to head again to rollback + bool try_success = true; + if (node.status_.get_state() < TwoPhaseCommitState::ON_COMMIT) {// avoid try lock + try_success = node.try_single_log_commit(commit_version, commit_scn); + } + return try_success; + }); + }, TwoPhaseCommitState::ON_COMMIT); +} + +void MdsCtx::single_log_abort() +{ + OB_ASSERT(writer_.writer_type_ != WriterType::TRANSACTION);// TRANSACTION use two-phase-commit + do_while_retry_with_lock_until_success_for_all_([this]() {// if failed on any node, will release lock and try from first node again + return for_each_node_fetch_to_try_([](MdsNode &node) {// the operation tried on each node, if failed, the fetched node will be insert to head again to rollback + bool try_success = true; + if (node.status_.get_state() < TwoPhaseCommitState::ON_ABORT) {// avoid try lock + try_success = node.try_on_abort(share::SCN::max_scn()); + } + return try_success; + }); + }, TwoPhaseCommitState::ON_ABORT); +} + +void MdsCtx::remove_node(ListNode *node) +{ + MdsWLockGuard lg(lock_); + write_list_.del(node); +} + +} +} +} diff --git a/src/storage/multi_data_source/mds_ctx.h b/src/storage/multi_data_source/mds_ctx.h new file mode 100644 index 000000000..de5b86e5d --- /dev/null +++ b/src/storage/multi_data_source/mds_ctx.h @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2021 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 SHARE_STORAGE_MULTI_DATA_SOURCE_MDS_CTX_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_MDS_CTX_H + +#include "buffer_ctx.h" +#include "lib/container/ob_se_array.h" +#include "lib/lock/ob_small_spin_lock.h" +#include "lib/lock/ob_spin_lock.h" +#include "lib/ob_define.h" +#include "lib/utility/ob_unify_serialize.h" +#include "mds_node.h" +#include "mds_writer.h" +#include "meta_programming/ob_type_traits.h" +namespace oceanbase +{ +namespace share +{ +class ObLSID; +} +namespace common +{ +class ObTabletID; +} +namespace storage +{ +namespace mds +{ +class MdsTableHandle; +class MdsCtx final : public BufferCtx +{ + friend class MdsNode; + OB_UNIS_VERSION(1); +public: + MdsCtx(); + explicit MdsCtx(const MdsWriter &writer); + virtual ~MdsCtx(); + MdsCtx(const MdsCtx &) = delete; + MdsCtx(MdsCtx &&) = delete; + MdsCtx &operator=(const MdsCtx &) = delete; + MdsCtx &operator=(MdsCtx &&) = delete; + int assign(const MdsCtx &); + void set_writer(const MdsWriter &writer); + bool can_write() const; + TO_STRING_KV(K_(writer), K_(write_list), K(obj_to_string(state_))); + void record_written_node(ListNode *node); + virtual const MdsWriter get_writer() const override; + virtual void before_prepare() override; + virtual void on_redo(const share::SCN &redo_scn) override; + virtual void on_prepare(const share::SCN &prepare_version) override; + virtual void on_commit(const share::SCN &commit_version, const share::SCN &commit_scn) override; + virtual void on_abort(const share::SCN &abort_scn) override; + void single_log_commit(const share::SCN commit_version, const share::SCN commit_scn); + void single_log_abort(); + void remove_node(ListNode *node); +private: + template + void do_while_retry_with_lock_until_success_for_all_(OP &&op, TwoPhaseCommitState new_state) {// if do op success, advance state to new_state + bool operate_all_nodes_succeed = true; + int64_t try_times = 0; + do { + MdsWLockGuard lg(lock_); + operate_all_nodes_succeed = op(); + if (OB_LIKELY(operate_all_nodes_succeed)) { + if (new_state != TwoPhaseCommitState::STATE_END) { + check_and_advance_two_phase_commit(state_, new_state); + } + } else if (OB_UNLIKELY((++try_times % 10000) == 0)) { + MDS_LOG_RET(WARN, OB_ERR_TOO_MUCH_TIME, "do-while retry too much times", K(try_times), K(*this)); + } + } while (!operate_all_nodes_succeed && ({PAUSE(); true;}));// keep trying lock until success, while-try is for avoid thread deadlock + } + template + bool for_each_node_try_(OP &&op) {// this is for ON_REDO/BEFORE_PREPARE/ON_PREPARE + bool operate_all_nodes_succeed = true; + write_list_.for_each_node_from_head_to_tail_until_true( + [&operate_all_nodes_succeed, &op](const MdsNode &node) { + MdsNode &cast_node = const_cast(node); + operate_all_nodes_succeed = op(cast_node); + return !operate_all_nodes_succeed; + } + ); + return operate_all_nodes_succeed; + } + template + bool for_each_node_fetch_to_try_(OP &&op) {// this is for ON_COMMIT/ON_ABORT/SINGLE_LOG_COMMIT/SINGLE_LOG_ABORT + bool operate_all_nodes_succeed = true; + ListNode *head = nullptr; + while (operate_all_nodes_succeed && OB_NOT_NULL(head = write_list_.fetch_from_head())) { + MdsNode *cast_head = static_cast(head); + operate_all_nodes_succeed = op(*cast_head); + if (!operate_all_nodes_succeed) {// rollback + write_list_.insert_into_head(cast_head); + } + }; + return operate_all_nodes_succeed; + } +private: + List write_list_; + MdsWriter writer_; + TwoPhaseCommitState state_; + MdsLock lock_; +}; +OB_SERIALIZE_MEMBER_TEMP(inline, MdsCtx, writer_); +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_node.cpp b/src/storage/multi_data_source/mds_node.cpp new file mode 100644 index 000000000..f5e9fe81e --- /dev/null +++ b/src/storage/multi_data_source/mds_node.cpp @@ -0,0 +1,189 @@ +#include "mds_node.h" +#include "lib/atomic/ob_atomic.h" +#include "lib/list/ob_dlist.h" +#include "lib/ob_errno.h" +#include "lib/utility/ob_macro_utils.h" +#include "lib/utility/ob_print_utils.h" +#include "mds_table_base.h" +#include "mds_ctx.h" +#include "storage/multi_data_source/runtime_utility/mds_lock.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +MdsNodeStatus::MdsNodeStatus() { union_.value_ = 0; } + +MdsNodeStatus::~MdsNodeStatus() { union_.value_ = 0; } + +MdsNodeStatus::MdsNodeStatus(MdsNodeType node_type, WriterType writer_type) +{ + union_.field_.node_type_ = node_type; + union_.field_.writer_type_ = writer_type; + union_.field_.state_ = TwoPhaseCommitState::STATE_INIT; + union_.field_.is_dumped_ = false; +} + +MdsNodeStatus::MdsNodeStatus(const MdsNodeStatus &rhs) { union_.value_ = rhs.union_.value_; } + +void MdsNodeStatus::set_dumped()// ATOMIC +{ + MdsNodeStatus old_node_status, new_node_status; + do { + old_node_status.union_.value_ = ATOMIC_LOAD(&union_.value_); + new_node_status.union_.value_ = old_node_status.union_.value_; + new_node_status.union_.field_.is_dumped_ = true; + } while (!ATOMIC_BCAS(&union_.value_, old_node_status.union_.value_, new_node_status.union_.value_)); +} + +bool MdsNodeStatus::is_dumped() const// ATOMIC +{ + MdsNodeStatus node_status; + node_status.union_.value_ = ATOMIC_LOAD(&union_.value_); + return node_status.union_.field_.is_dumped_; +} + +MdsNodeStatus &MdsNodeStatus::operator=(const MdsNodeStatus &rhs)// ATOMIC +{ + MdsNodeStatus old_node_status, new_node_status; + do { + old_node_status.union_.value_ = ATOMIC_LOAD(&union_.value_); + new_node_status.union_.value_ = ATOMIC_LOAD(&rhs.union_.value_); + } while (!ATOMIC_BCAS(&union_.value_, old_node_status.union_.value_, new_node_status.union_.value_)); + return *this; +} + +MdsNodeStatus::Union::Union() : value_(0) {} + +void MdsNodeStatus::advance(TwoPhaseCommitState new_stat)// ATOMIC +{ + MdsNodeStatus old_node_status, new_node_status; + do { + old_node_status.union_.value_ = ATOMIC_LOAD(&union_.value_); + OB_ASSERT(new_stat >= old_node_status.union_.field_.state_ && + new_stat < TwoPhaseCommitState::STATE_END && + new_stat > TwoPhaseCommitState::STATE_INIT); + OB_ASSERT(STATE_CHECK_ALLOWED_MAP[(int)old_node_status.union_.field_.state_][(int)new_stat] == true); + new_node_status.union_.value_ = old_node_status.union_.value_; + new_node_status.union_.field_.state_ = new_stat; + } while (!ATOMIC_BCAS(&union_.value_, old_node_status.union_.value_, new_node_status.union_.value_)); +} + +TwoPhaseCommitState MdsNodeStatus::get_state() const// ATOMIC +{ + MdsNodeStatus node_status; + node_status.union_.value_ = ATOMIC_LOAD(&union_.value_); + return (TwoPhaseCommitState)node_status.union_.field_.state_; +} + +int64_t MdsNodeStatus::to_string(char *buf, const int64_t buf_len) const// ATOMIC +{ + MdsNodeStatus node_status; + node_status.union_.value_ = ATOMIC_LOAD(&union_.value_); + int64_t pos = 0; + databuff_printf(buf, buf_len, pos, "%s|", obj_to_string(node_status.union_.field_.node_type_)); + databuff_printf(buf, buf_len, pos, "%s|", obj_to_string(node_status.union_.field_.writer_type_)); + databuff_printf(buf, buf_len, pos, "%s|", obj_to_string(node_status.union_.field_.state_)); + databuff_printf(buf, buf_len, pos, "%s", to_cstring(node_status.union_.field_.is_dumped_)); + return pos; +} + +MdsNode::MdsNode(MdsNodeType node_type, + WriterType writer_type, + const int64_t writer_id) : +ListNode(), +status_(node_type, writer_type), +writer_id_(writer_id), +seq_no_(0), +redo_scn_(share::SCN::max_scn()), +end_scn_(share::SCN::max_scn()), +trans_version_(share::SCN::max_scn()), +mds_ctx_(nullptr) {} + +void MdsNode::remove_self_if_in_mds_ctx_() +{ + if (OB_NOT_NULL(mds_ctx_)) { + MDS_TG(1_ms); + mds_ctx_->remove_node(this); + MDS_LOG(INFO, "remove mds_node from mds_ctx", K(*this)); + mds_ctx_ = nullptr; + } +} + +MdsNode::~MdsNode() { ListNode::~ListNode(); } + +MdsWriter MdsNode::get_writer_() const +{ + return MdsWriter(status_.union_.field_.writer_type_, writer_id_); +} + +bool MdsNode::is_aborted_() const +{ + return status_.get_state() == TwoPhaseCommitState::ON_ABORT; +} + +bool MdsNode::is_committed_() const +{ + return status_.get_state() == TwoPhaseCommitState::ON_COMMIT; +} + +bool MdsNode::is_decided_() const +{ + TwoPhaseCommitState state = status_.get_state(); + return state == TwoPhaseCommitState::ON_ABORT || state == TwoPhaseCommitState::ON_COMMIT; +} + +share::SCN MdsNode::get_commit_version_() const +{ + return status_.get_state() == TwoPhaseCommitState::ON_COMMIT ? + trans_version_ : + share::SCN::max_scn(); +} + +share::SCN MdsNode::get_prepare_version_() const +{ + share::SCN prepare_vresion; + TwoPhaseCommitState stat = status_.get_state(); + if (stat == TwoPhaseCommitState::STATE_INIT || + stat == TwoPhaseCommitState::ON_ABORT) {// not in two-phase-commit, should not see this node + prepare_vresion = share::SCN::max_scn(); + } else if (stat == TwoPhaseCommitState::BEFORE_PREPARE) {// in two-phase-commit, see if need block + prepare_vresion = share::SCN::min_scn(); + } else {// otherwise, trans_version is prepare version: + // 1. either trans_version really is prepare version in BEFORE_PREPARE/ON_PREPARE phase. + // 2. or trans_version is commit version in ON_COMMIT phase. + prepare_vresion = trans_version_; + } + return prepare_vresion; +} + +int MdsNodeInfoForVirtualTable::assign(const MdsNodeInfoForVirtualTable &rhs) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(user_key_.assign(rhs.user_key_))) { + MDS_LOG(WARN, "fail to copy user key", KR(ret)); + } else if (OB_FAIL(user_data_.assign(rhs.user_data_))) { + MDS_LOG(WARN, "fail to copy user data", KR(ret)); + } else { + ls_id_ = rhs.ls_id_; + tablet_id_ = rhs.tablet_id_; + unit_id_ = rhs.unit_id_; + version_idx_ = rhs.version_idx_; + writer_ = rhs.writer_; + seq_no_ = rhs.seq_no_; + redo_scn_ = rhs.redo_scn_; + end_scn_ = rhs.end_scn_; + trans_version_ = rhs.trans_version_; + node_type_ = rhs.node_type_; + state_ = rhs.state_; + position_ = rhs.position_; + } + return ret; +} + +} +} +} \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_node.h b/src/storage/multi_data_source/mds_node.h new file mode 100644 index 000000000..ed15acd86 --- /dev/null +++ b/src/storage/multi_data_source/mds_node.h @@ -0,0 +1,267 @@ +/** + * Copyright (c) 2023 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 STORAGE_MULTI_DATA_SOURCE_MDS_NODE_H +#define STORAGE_MULTI_DATA_SOURCE_MDS_NODE_H + +#include "lib/atomic/ob_atomic.h" +#include "lib/list/ob_dlist.h" +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log.h" +#include "lib/queue/ob_link.h" +#include "ob_clock_generator.h" +#include "ob_tablet_id.h" +#include "share/ob_ls_id.h" +#include "share/scn.h" +#include "runtime_utility/common_define.h" +#include "runtime_utility/list_helper.h" +#include +#include +#include +#include "mds_writer.h" +#include "deps/oblib/src/common/meta_programming/ob_type_traits.h" +#include "runtime_utility/mds_lock.h" +#include "lib/string/ob_string_holder.h" +#include "meta_programming/ob_meta_copy.h" +#include "mds_table_base.h" +#include "runtime_utility/mds_factory.h" + +namespace oceanbase +{ +namespace unittest +{ +class TestMdsUserNode; +} +namespace storage +{ +namespace mds +{ +class MdsNode; +template +class UserMdsNode; +class MdsDumpNode; +class MdsTableBase; +class MdsNodeBase; +class MdsCtx; + +struct MdsNodeInfoForVirtualTable +{ + MdsNodeInfoForVirtualTable() + : ls_id_(), tablet_id_(), unit_id_(UINT8_MAX), user_key_(), version_idx_(-1), writer_(), seq_no_(-1), redo_scn_(), + end_scn_(), trans_version_(), node_type_(MdsNodeType::TYPE_END), state_(TwoPhaseCommitState::STATE_END), + position_(NodePosition::POSITION_END), user_data_() {} + share::ObLSID ls_id_; + common::ObTabletID tablet_id_; + int64_t unit_id_; + common::ObStringHolder user_key_; + int64_t version_idx_; + MdsWriter writer_; + int64_t seq_no_; + share::SCN redo_scn_; + share::SCN end_scn_; + share::SCN trans_version_; + MdsNodeType node_type_; + TwoPhaseCommitState state_; + NodePosition position_; + common::ObStringHolder user_data_; + int assign(const MdsNodeInfoForVirtualTable &rhs); + int64_t to_string(char *buf, const int64_t len) const { return 0; } +}; + +template +struct MdsUnitBase +{ + MdsUnitBase() : p_mds_table_(nullptr), unit_id_(UINT8_MAX) {} + ~MdsUnitBase() { p_mds_table_ = nullptr; } + MdsTableBase *p_mds_table_; + uint8_t unit_id_; +}; + +template +struct MdsRowBase +{ + MdsRowBase() : p_mds_unit_(nullptr), key_(nullptr) {} + virtual ~MdsRowBase() { p_mds_unit_ = nullptr; key_ = nullptr; } + // if a node aborted, delete it immediately. + virtual void node_abort_callback_(ListNodeBase *node) = 0; + MdsUnitBase *p_mds_unit_; + K *key_; + mutable MdsLock lock_; +}; + +struct MdsNodeStatus// No need lock, atomic operatrion for all interfaces +{ + OB_UNIS_VERSION(1); +public: + MdsNodeStatus(); + ~MdsNodeStatus(); + MdsNodeStatus(MdsNodeType node_type, WriterType writer_type); + MdsNodeStatus(const MdsNodeStatus &rhs); + MdsNodeStatus &operator=(const MdsNodeStatus &rhs); + void advance(TwoPhaseCommitState new_stat); + void set_dumped(); + bool is_dumped() const; + TwoPhaseCommitState get_state() const; + int64_t to_string(char *buf, const int64_t buf_len) const; + union Union { + Union(); + struct { + // won't change + MdsNodeType node_type_ : 4; + WriterType writer_type_ : 8; + // can be changed + TwoPhaseCommitState state_ : 4; + bool is_dumped_ : 1; + } field_; + uint32_t value_; + } union_; +}; +OB_SERIALIZE_MEMBER_TEMP(inline, MdsNodeStatus, union_.value_); + +// define a base NO TEMPLATE class +// so that most method can be defined in cpp file +class MdsNode : public ListNode +{ + template + friend class MdsTableImpl; + template + friend class MdsRow; + template + friend class UserMdsNode; + friend class MdsDumpNode; +public: + MdsNode(MdsNodeType node_type, + WriterType writer_type, + const int64_t writer_id); + virtual ~MdsNode() override; +public:// log sync and two-phase-commit related + virtual bool try_on_redo(const share::SCN &redo_scn) = 0; + virtual bool try_before_prepare() = 0; + virtual bool try_on_prepare(const share::SCN &prepare_version) = 0; + virtual bool try_on_commit(const share::SCN &commit_version, const share::SCN &commit_scn) = 0; + virtual bool try_on_abort(const share::SCN &abort_scn) = 0; + virtual bool try_single_log_commit(const share::SCN &commit_version, const share::SCN &commit_scn) = 0; + virtual int64_t to_string(char *buf, const int64_t buf_len) const = 0; + virtual int fill_virtual_info(MdsNodeInfoForVirtualTable &mds_node_indo) const = 0; +public:// node states related + void remove_self_if_in_mds_ctx_(); + void set_dumped_() { status_.set_dumped(); } + bool is_dumped_() const { return status_.is_dumped(); } + MdsWriter get_writer_() const; + bool is_persisted_() const; + bool is_aborted_() const; + bool is_committed_() const; + bool is_decided_() const; + share::SCN get_commit_version_() const; + share::SCN get_prepare_version_() const; +public: + MdsNodeStatus status_;// include lock state, type state, persisted state and two-phase-commit state + int64_t writer_id_; // mostly is tx id, and maybe not tx id, depends on writer_type_ in status_; + int64_t seq_no_;// not used for now + share::SCN redo_scn_; // log scn of redo + share::SCN end_scn_; // log scn of commit/abort + share::SCN trans_version_; // read as prepare version if phase is not COMMIT, or read as commit version + MdsCtx *mds_ctx_;// need remove node from ctx when forcelly delete node before decided +}; + +template +class UserMdsNode final : public MdsNode, public ListNode>// this order can not be changed!!! +{ + template + friend class MdsTableImpl; + template + friend class MdsRow; + friend class MdsDumpNode; +private: + struct TryLockGuard {// for RAII + TryLockGuard(UserMdsNode *p_mds_node) : lock_(nullptr) { + if (OB_NOT_NULL(p_mds_node->p_mds_row_)) { + bool lock_succ = p_mds_node->p_mds_row_->lock_.try_wrlock(); + if (OB_LIKELY(lock_succ)) { + lock_ = &p_mds_node->p_mds_row_->lock_; + } + } else { + OCCAM_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "not expected valid mds_node! no row related!", KPC(p_mds_node)); + } + } + bool lock_succeed() const { + return OB_NOT_NULL(lock_); + } + ~TryLockGuard() { + if (OB_NOT_NULL(lock_)) { + lock_->unlock(); + } + } + MdsLock *lock_; + }; +public: + UserMdsNode(); + UserMdsNode(MdsRowBase *p_mds_row, + MdsNodeType node_type, + WriterType writer_type, + const int64_t writer_id); + ~UserMdsNode(); + bool operator<(const UserMdsNode &rhs) const; + bool operator==(const UserMdsNode &rhs) const; + virtual int64_t to_string(char * buf, const int64_t buf_len) const override; + template + void report_event_(const char (&event)[N], + const char *file = __builtin_FILE(), + const uint32_t line = __builtin_LINE(), + const char *function_name = __builtin_FUNCTION()) const; + virtual int fill_virtual_info(MdsNodeInfoForVirtualTable &mds_node_indo) const override; + template + int fill_event_(observer::MdsEvent &mds_event, const char (&event)[N], char *buffer, const int64_t len) const; + MdsNodeType get_node_type() const; +public:// do user action if there has define, in transaction phase point + bool try_on_redo(const share::SCN &redo_scn) override; + void on_redo_(const share::SCN &redo_scn); + bool try_before_prepare() override; + void before_prepare_(); + bool try_on_prepare(const share::SCN &prepare_version) override; + void on_prepare_(const share::SCN &prepare_version); + bool try_on_commit(const share::SCN &commit_version, const share::SCN &commit_scn) override; + void on_commit_(const share::SCN &commit_version, const share::SCN &commit_scn); + bool try_on_abort(const share::SCN &abort_scn) override; + bool try_single_log_commit(const share::SCN &commit_version, const share::SCN &commit_scn) override; +public:// conditional compile + template + void on_user_data_set_() {} + template + void on_user_data_set_() { user_data_.on_set(); } + template + void on_user_data_redo_(const share::SCN redo_scn) {} + template + void on_user_data_redo_(const share::SCN redo_scn) { user_data_.on_redo(redo_scn); } + template + void on_user_data_commit_(const share::SCN, const share::SCN) {} + template + void on_user_data_commit_(const share::SCN commit_version, const share::SCN commit_scn) { user_data_.on_commit(commit_version, commit_scn); } + template + void on_user_data_abort_(const share::SCN abort_scn) {} + template + void on_user_data_abort_(const share::SCN abort_scn) { user_data_.on_abort(abort_scn); } +public: + bool is_valid_scn_(const share::SCN &scn) const; + bool has_valid_link_back_ptr_() const; + MdsRowBase *p_mds_row_; + V user_data_; +}; +} +} +} + +#ifndef STORAGE_MULTI_DATA_SOURCE_MDS_NODE_H_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_NODE_H_IPP +#include "mds_node.ipp" +#endif + +#endif diff --git a/src/storage/multi_data_source/mds_node.ipp b/src/storage/multi_data_source/mds_node.ipp new file mode 100644 index 000000000..7f4239edc --- /dev/null +++ b/src/storage/multi_data_source/mds_node.ipp @@ -0,0 +1,396 @@ +/** + * Copyright (c) 2021 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 STORAGE_MULTI_DATA_SOURCE_MDS_NODE_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_NODE_IPP + +#include "lib/ob_abort.h" +#include "lib/ob_errno.h" +#include "lib/utility/ob_macro_utils.h" +#include "storage/multi_data_source/runtime_utility/list_helper.h" +#ifndef STORAGE_MULTI_DATA_SOURCE_MDS_NODE_H_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_NODE_H_IPP +#include "mds_node.h" +#endif + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +template +UserMdsNode::UserMdsNode() +: MdsNode(MdsNodeType::UNKNOWN_NODE, + WriterType::UNKNOWN_WRITER, + INVALID_VALUE), +ListNode>() { p_mds_row_ = nullptr; } + +template +UserMdsNode::UserMdsNode(MdsRowBase *p_mds_row, + MdsNodeType node_type, + WriterType writer_type, + const int64_t writer_id) +: MdsNode(node_type, writer_type, writer_id), +ListNode>() +{ + static_assert(std::is_default_constructible::value, + "User Data MUST SUPPORT default construction"); + p_mds_row_ = p_mds_row; + if (OB_LIKELY(has_valid_link_back_ptr_())) { + p_mds_row_->p_mds_unit_->p_mds_table_->inc_valid_node_cnt(); + } +} + +template +UserMdsNode::~UserMdsNode() +{ + remove_self_if_in_mds_ctx_(); + if (OB_UNLIKELY((nullptr != ((ListNode>*)this)->prev_) || + (nullptr != ((ListNode>*)this)->next_) || + (nullptr != ((ListNode*)this)->prev_) || + (nullptr != ((ListNode*)this)->next_))) { + ob_abort(); + } + if (OB_LIKELY(has_valid_link_back_ptr_())) { + MDS_LOG(INFO, "mds node destructed", K(*this)); + p_mds_row_->p_mds_unit_->p_mds_table_->dec_valid_node_cnt(); + p_mds_row_ = nullptr; + } +} + +template +bool UserMdsNode::operator<(const UserMdsNode &rhs) const +{ + return redo_scn_ < rhs.redo_scn_; +} + +template +bool UserMdsNode::operator==(const UserMdsNode &rhs) const +{ + return redo_scn_ == rhs.redo_scn_; +} + +template +int64_t UserMdsNode::to_string(char * buf, const int64_t buf_len) const +{ + int64_t pos = 0; + MdsTableBase *p_mds_table = nullptr; + if (p_mds_row_ && p_mds_row_->p_mds_unit_) { + p_mds_table = p_mds_row_->p_mds_unit_->p_mds_table_; + } + databuff_printf(buf, buf_len, pos, "this:0x%lx, ", (unsigned long)this); + databuff_printf(buf, buf_len, pos, "ls_id:%s, ", p_mds_table ? to_cstring(p_mds_table->ls_id_) : "NULL"); + databuff_printf(buf, buf_len, pos, "tablet_id:%s, ", p_mds_table ? to_cstring(p_mds_table->tablet_id_) : "NULL"); + databuff_printf(buf, buf_len, pos, "writer:%ld, ", writer_id_); + databuff_printf(buf, buf_len, pos, "seq_no:%ld, ", seq_no_); + databuff_printf(buf, buf_len, pos, "redo_scn:%s, ", obj_to_string(redo_scn_)); + databuff_printf(buf, buf_len, pos, "end_scn:%s, ", obj_to_string(end_scn_)); + databuff_printf(buf, buf_len, pos, "trans_version:%s, ", obj_to_string(trans_version_)); + databuff_printf(buf, buf_len, pos, "status:%s, ", to_cstring(status_)); + databuff_printf(buf, buf_len, pos, "ver_next:0x%lx, ", + (unsigned long)(static_cast(static_cast>*>(ListNode>::next_)))); + databuff_printf(buf, buf_len, pos, "linked:0x%lx, ", + (unsigned long)(static_cast(static_cast*>(ListNode::next_)))); + databuff_printf(buf, buf_len, pos, "mds_ctx:0x%lx, ", (unsigned long)(mds_ctx_)); + databuff_printf(buf, buf_len, pos, "user_data:%s", to_cstring(user_data_)); + return pos; +} + +template +MdsNodeType UserMdsNode::get_node_type() const +{ + MDS_TG(1_ms); + CLICK(); + return status_.union_.field_.node_type_; +} + +template +bool UserMdsNode::try_on_redo(const share::SCN &redo_scn) +{ + MDS_TG(1_ms); + TryLockGuard lg(this); + if (lg.lock_succeed()) { + CLICK(); + on_redo_(redo_scn); + } + return lg.lock_succeed(); +} + +template +void UserMdsNode::on_redo_(const share::SCN &redo_scn) +{ + MdsTableBase *p_mds_table = nullptr; + if (p_mds_row_ && p_mds_row_->p_mds_unit_) { + p_mds_table = p_mds_row_->p_mds_unit_->p_mds_table_; + } + if (is_valid_scn_(redo_scn_)) { + if (redo_scn != redo_scn_) { + MDS_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "there has been a valid reso scn!", K(*this), K(redo_scn)); + } + } else if (!is_valid_scn_(redo_scn)) { + MDS_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "redo scn is not a valid scn!", K(*this), K(redo_scn)); + } else { + if (OB_ISNULL(p_mds_table)) { + MDS_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "pointer is NULL, can not try decline rec_scn", K(*this), K(redo_scn)); + } else { + p_mds_table->try_decline_rec_scn(redo_scn); + } + redo_scn_ = redo_scn; + on_user_data_redo_(redo_scn); + report_event_("ON_REDO"); + } +} + +template +bool UserMdsNode::try_before_prepare() +{ + MDS_TG(1_ms); + TryLockGuard lg(this); + if (lg.lock_succeed()) { + CLICK(); + before_prepare_(); + } + return lg.lock_succeed(); +} + +template +void UserMdsNode::before_prepare_() +{ + if (status_.union_.field_.state_ == TwoPhaseCommitState::BEFORE_PREPARE) {// reentrant + OB_ASSERT(trans_version_.is_min()); + } else { + status_.advance(TwoPhaseCommitState::BEFORE_PREPARE); + trans_version_.set_min();// block all read operation + report_event_("BEFORE_PREPARE"); + } +} + +template +bool UserMdsNode::try_on_prepare(const share::SCN &prepare_version) +{ + MDS_TG(1_ms); + TryLockGuard lg(this); + if (lg.lock_succeed()) { + CLICK(); + on_prepare_(prepare_version); + } + return lg.lock_succeed(); +} + +template +void UserMdsNode::on_prepare_(const share::SCN &prepare_version) +{ + if (status_.union_.field_.state_ == TwoPhaseCommitState::ON_PREPARE) {// reentrant + if (is_valid_scn_(prepare_version)) { + OB_ASSERT(trans_version_ == prepare_version); + } + } else { + status_.advance(TwoPhaseCommitState::ON_PREPARE); + if (is_valid_scn_(prepare_version)) { + trans_version_ = prepare_version; + } + report_event_("ON_PREPARE"); + } +} + +template +bool UserMdsNode::try_on_commit(const share::SCN &commit_version, + const share::SCN &commit_scn) +{ + bool lock_success = true; + MDS_TG(1_ms); + TryLockGuard lg(this); + if (lg.lock_succeed()) { + CLICK(); + on_commit_(commit_version, commit_scn); + } + return lg.lock_succeed(); +} + +template +void UserMdsNode::on_commit_(const share::SCN &commit_version, + const share::SCN &commit_scn) +{ + if (!is_valid_scn_(commit_scn) || !is_valid_scn_(commit_scn)) { + MDS_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "commit version or commit scn is not a valid scn!", + K(*this), K(commit_version), K(commit_scn)); + } else { + if (status_.union_.field_.state_ == TwoPhaseCommitState::ON_COMMIT) {// reentrant + OB_ASSERT(trans_version_ == commit_version); + OB_ASSERT(end_scn_ == commit_scn); + } else { + status_.advance(TwoPhaseCommitState::ON_COMMIT); + trans_version_ = commit_version; + end_scn_ = commit_scn; + if (!redo_scn_.is_max() && end_scn_ < redo_scn_) { + MDS_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "end scn lower than redo scn", K(*this)); + } + on_user_data_commit_(commit_version, commit_scn); + report_event_("ON_COMMIT"); + mds_ctx_ = nullptr;// if this node destroyed, don't access to ctx again + } + } +} + +template +bool UserMdsNode::try_on_abort(const share::SCN &abort_scn)// CAUTIONS: non-reentrant!!! +{ + MDS_TG(1_ms); + TryLockGuard lg(this); + if (lg.lock_succeed()) { + CLICK(); + status_.advance(TwoPhaseCommitState::ON_ABORT); + end_scn_ = abort_scn; + on_user_data_abort_(abort_scn); + MDS_LOG(INFO, "mds node on_abort", K(*this), K(abort_scn)); + if (is_valid_scn_(redo_scn_) && is_valid_scn_(abort_scn)) { + if (end_scn_ < redo_scn_) { + MDS_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "end scn lower than redo scn", K(*this), K(abort_scn)); + } + } else if (is_valid_scn_(redo_scn_)) { + MDS_LOG_RET(WARN, OB_INVALID_ARGUMENT, "node has been assocaited with a valid redo log, " + "connot abort with an invalid scn", K(*this), K(abort_scn)); + } else { + report_event_("ON_ABORT"); + } + mds_ctx_ = nullptr;// this node will be destroyed in abort callback, if ctx is valid, will try to remove self from ctx, and will deadlock with self thread + if (OB_NOT_NULL(p_mds_row_)) { + // this must be last line of this function, caus this node may be deleted inner + p_mds_row_->node_abort_callback_((ListNodeBase*)(ListNode>*)(this)); + } + } + return lg.lock_succeed(); +} + +template +bool UserMdsNode::try_single_log_commit(const share::SCN &commit_version, const share::SCN &commit_scn) +{ + MDS_TG(1_ms); + TryLockGuard lg(this); + if (lg.lock_succeed()) { + CLICK(); + if (redo_scn_.is_max()) { + on_redo_(commit_scn); + } + before_prepare_(); + on_prepare_(commit_version); + on_commit_(commit_version, commit_scn); + } + return lg.lock_succeed(); +} + +template +bool UserMdsNode::is_valid_scn_(const share::SCN &scn) const +{ + return scn.is_valid() && !scn.is_max() && !scn.is_min(); +} + +template +bool UserMdsNode::has_valid_link_back_ptr_() const +{ + return OB_NOT_NULL(p_mds_row_) && + OB_NOT_NULL(p_mds_row_->key_) && + OB_NOT_NULL(p_mds_row_->p_mds_unit_) && + OB_NOT_NULL(p_mds_row_->p_mds_unit_->p_mds_table_); +} + +template +int UserMdsNode::fill_virtual_info(MdsNodeInfoForVirtualTable &mds_node_info) const +{ + int ret = OB_SUCCESS; + constexpr int64_t buffer_size = 2_KB; + char stack_buffer[buffer_size] = { 0 }; + int64_t pos = 0; + if (FALSE_IT(databuff_printf(stack_buffer, buffer_size, pos, "%s", to_cstring(user_data_)))) { + } else if (OB_FAIL(mds_node_info.user_data_.assign(ObString(pos, stack_buffer)))) { + MDS_LOG(WARN, "fail construct ObStringHolder", K(*this)); + } else { + if (OB_LIKELY(has_valid_link_back_ptr_())) { + mds_node_info.ls_id_ = p_mds_row_->p_mds_unit_->p_mds_table_->get_ls_id(); + mds_node_info.tablet_id_ = p_mds_row_->p_mds_unit_->p_mds_table_->get_tablet_id(); + } + mds_node_info.writer_ = MdsWriter(status_.union_.field_.writer_type_, writer_id_); + mds_node_info.seq_no_ = seq_no_; + mds_node_info.redo_scn_ = redo_scn_; + mds_node_info.end_scn_ = end_scn_; + mds_node_info.trans_version_ = trans_version_; + mds_node_info.node_type_ = status_.union_.field_.node_type_; + mds_node_info.state_ = status_.union_.field_.state_; + mds_node_info.position_ = NodePosition::MDS_TABLE; + } + return ret; +} + +template +template +void UserMdsNode::report_event_(const char (&event_str)[N], + const char *file, + const uint32_t line, + const char *function_name) const +{ + int ret = OB_SUCCESS; + constexpr int64_t buffer_size = 1_KB; + char stack_buffer[buffer_size] = { 0 }; + observer::MdsEvent event; + if (OB_UNLIKELY(!has_valid_link_back_ptr_())) { + // do nothing + } else if (OB_FAIL(fill_event_(event, event_str, stack_buffer, buffer_size))) { + MDS_LOG(WARN, "fail fill mds event", K(*this)); + } else { + observer::MdsEventKey key(MTL_ID(), + p_mds_row_->p_mds_unit_->p_mds_table_->ls_id_, + p_mds_row_->p_mds_unit_->p_mds_table_->tablet_id_); + observer::ObMdsEventBuffer::append(key, event, file, line, function_name); + } +} + +template +template +int UserMdsNode::fill_event_(observer::MdsEvent &event, + const char (&event_str)[N], + char *stack_buffer, + const int64_t buffer_size) const +{ + int ret = OB_SUCCESS; + MDS_TG(1_ms); + int64_t pos = 0; + int64_t last_pos = 0; + if (FALSE_IT(databuff_printf(stack_buffer, buffer_size, pos, "%s", to_cstring(user_data_)))) { + } else if (FALSE_IT(event.info_str_.assign_ptr(stack_buffer, pos))) { + } else if (FALSE_IT(last_pos = pos)) { + } else if (MDS_FAIL(databuff_printf(stack_buffer, buffer_size, pos, "%s", p_mds_row_ ? to_cstring(*p_mds_row_->key_) : "NULL"))) { + MDS_LOG(WARN, "fail to_string user key", K(*this)); + } else if (FALSE_IT(event.key_str_.assign_ptr(&stack_buffer[last_pos], pos - last_pos))) { + } else if (FALSE_IT(last_pos = pos)) { + } else { + event.record_thread_info_(); + event.event_ = event_str; + if (OB_LIKELY(has_valid_link_back_ptr_())) { + event.unit_id_ = p_mds_row_->p_mds_unit_->unit_id_; + } + event.writer_type_ = status_.union_.field_.writer_type_; + event.writer_id_ = writer_id_; + event.seq_no_ = seq_no_; + event.redo_scn_ = redo_scn_; + event.end_scn_ = end_scn_; + event.trans_version_ = trans_version_; + event.node_type_ = status_.union_.field_.node_type_; + event.state_ = status_.union_.field_.state_; + } + return ret; +} +#undef CONSTRUCT_ROW_LOCK_GUARD +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_row.h b/src/storage/multi_data_source/mds_row.h new file mode 100644 index 000000000..bb4f48963 --- /dev/null +++ b/src/storage/multi_data_source/mds_row.h @@ -0,0 +1,161 @@ +/** + * Copyright (c) 2023 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 STORAGE_MULTI_DATA_SOURCE_MDS_ROW_H +#define STORAGE_MULTI_DATA_SOURCE_MDS_ROW_H + +#include "lib/lock/ob_small_spin_lock.h" +#include "lib/lock/ob_spin_lock.h" +#include "lib/ob_errno.h" +#include "lib/utility/utility.h" +#include "share/ob_errno.h" +#include "share/scn.h" +#include "runtime_utility/mds_factory.h" +#include "runtime_utility/common_define.h" +#include "mds_node.h" +#include "mds_ctx.h" +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_table_base.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include +#include "deps/oblib/src/common/meta_programming/ob_meta_copy.h" + +namespace oceanbase +{ +namespace unittest +{ +class TestMdsRowAndMdsCtx; +} +namespace storage +{ +namespace mds +{ + +template +class MdsUnit; +template +class MdsRow : public MdsRowBase// Row OWNS all UserMdsNode in list +{ + template + friend class MdsTableImpl; + friend class unittest::TestMdsRowAndMdsCtx; + template + friend class MdsUnit; + template + friend class ObMdsNodeScanIterator; +public:// iterator defination + template + struct IteratorBase; + template + struct NormalIterator; + template + struct ReverseIterator; + using iterator = NormalIterator>; + using const_iterator = NormalIterator>; + using reverse_iterator = ReverseIterator>; + using const_reverse_iterator = ReverseIterator>; + iterator begin(); + iterator end(); + const_iterator cbegin(); + const_iterator cend(); + reverse_iterator rbegin(); + reverse_iterator rend(); + const_reverse_iterator crbegin(); + const_reverse_iterator crend(); +public: + MdsRow() : MdsRowBase() {} + ~MdsRow(); + template + int set(DATA &&data, + MdsCtx &ctx, + const int64_t lock_timeout_us, + const bool is_for_remove = false); + template + int replay(DATA &&data, + MdsCtx &ctx, + const share::SCN scn, + const bool is_for_remove = false); + template + int get_snapshot(READ_OP &&read_operation, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const; + template + int get_latest(READ_OP &&read_operation, const int64_t read_seq) const; + template + int get_by_writer(READ_OP &&read_operation, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const; + template + int scan_dump_node_from_tail_to_head(DUMP_OP &&op, + const uint8_t mds_table_id, + const uint8_t mds_unit_id, + MdsDumpKV &dump_kv, + const share::SCN &flush_scn, + const bool for_flush) const; + // template + // int for_each_node_from_tail_to_head(OP &&op) const; + template + int fill_virtual_info(const Key &key, ObIArray &mds_node_info_array, const int64_t unit_id) const; + // if a node aborted, delete it immediately. + virtual void node_abort_callback_(ListNodeBase *node) override; + int64_t to_string(char *buf, const int64_t buf_len) const; + // TO_STRING_KV(K_(sorted_list), KPC_(MdsRowBase::p_mds_table), KPC_(MdsRowBase::key)); +public: + template + int for_each_node_(OPERATION &&op) const; + template + int get_with_read_wrapper_(READ_OP &&read_operation, SPECIFIED_GET_LOGIC &&specified_logic) const; + template + int write_operation_wrapper_(WRITE_OPERATION &&write_op, + MdsCtx &ctx, + const int64_t lock_timeout_us); + template + int construct_insert_record_user_mds_node_(MdsRowBase *p_mds_row, + DATA &&data, + const MdsNodeType node_type, + const share::SCN scn, + MdsCtx &ctx); + int check_node_snapshot_(const UserMdsNode &node, + const share::SCN snapshot, + const int64_t timeout_ts, + bool &can_read) const; + template + void report_event_(const char (&event_str)[N], + const UserMdsNode &node, + const char *file = __builtin_FILE(), + const uint32_t line = __builtin_LINE(), + const char *function_name = __builtin_FUNCTION()) const; +public: + // define this structure cause C++11 not support perfect-forwarding capture lambda + struct ForwardWrapper + { + ForwardWrapper(const V &data) : is_constructed_from_lvalue_(true), data_(data) {} + ForwardWrapper(V &&data) : is_constructed_from_lvalue_(false), data_(data) {} + bool is_constructed_from_lvalue_; + const V &data_; + }; +public: + SortedList, + SORT_TYPE::DESC> sorted_list_; +}; +} +} +} + +#ifndef STORAGE_MULTI_DATA_SOURCE_MDS_ROW_H_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_ROW_H_IPP +#include "mds_row.ipp" +#endif + +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_row.ipp b/src/storage/multi_data_source/mds_row.ipp new file mode 100644 index 000000000..9fdb95cd6 --- /dev/null +++ b/src/storage/multi_data_source/mds_row.ipp @@ -0,0 +1,691 @@ +/** + * Copyright (c) 2023 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 STORAGE_MULTI_DATA_SOURCE_MDS_ROW_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_ROW_IPP + +#include "share/ob_errno.h" +#include "storage/multi_data_source/mds_table_base.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" +#ifndef STORAGE_MULTI_DATA_SOURCE_MDS_ROW_H_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_ROW_H_IPP +#include "mds_row.h" +#endif + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +template +template +struct MdsRow::IteratorBase {// Bidirectional iterators + // iterator traits + using difference_type = int64_t; + using value_type = ValueType; + using pointer = ValueType *; + using reference = ValueType &; + using iterator_category = std::bidirectional_iterator_tag; + // method needed define + IteratorBase() : p_node_(nullptr) {} + IteratorBase(ValueType *val) : p_node_(val) {} + IteratorBase(const IteratorBase &rhs) : p_node_(rhs.p_node_) {} + IteratorBase &operator=(const IteratorBase &rhs) { p_node_ = rhs.p_node_; return *this; } + bool operator==(const IteratorBase &rhs) { return p_node_ == rhs.p_node_; } + bool operator!=(const IteratorBase &rhs) { return p_node_ != rhs.p_node_; } + ValueType &operator*() { return *p_node_; } + ValueType *operator->() { return p_node_; } + UserMdsNode *p_node_; +}; + +template +template +struct MdsRow::NormalIterator : public IteratorBase { + NormalIterator() : IteratorBase() {} + NormalIterator(const NormalIterator &rhs) : IteratorBase(rhs) {} + NormalIterator(ValueType *val) : IteratorBase(val) {} + NormalIterator &operator++() { + IteratorBase::p_node_ = (UserMdsNode *)IteratorBase:: + p_node_->ListNode>::next(); + return *this; + } + NormalIterator operator++(int) { + NormalIterator ret_val = *this; + ++(*this); + return ret_val; + } + NormalIterator &operator--() { + IteratorBase::p_node_ = (UserMdsNode *)IteratorBase:: + p_node_->ListNode>::prev(); + return *this; + } + NormalIterator operator--(int) { + NormalIterator ret_val = *this; + ++(*this); + return ret_val; + } +}; + +template +template +struct MdsRow::ReverseIterator : public IteratorBase { + ReverseIterator() : IteratorBase() {} + ReverseIterator(const ReverseIterator &rhs) : IteratorBase(rhs) {} + ReverseIterator(ValueType *val) : IteratorBase(val) {} + ReverseIterator &operator++() { + IteratorBase::p_node_ = (UserMdsNode *)IteratorBase:: + p_node_->ListNode>::prev(); + return *this; + } + ReverseIterator operator++(int) { + ReverseIterator ret_val = *this; + ++(*this); + return ret_val; + } + ReverseIterator &operator--() { + IteratorBase::p_node_ = (UserMdsNode *)IteratorBase:: + p_node_->ListNode>::next(); + return *this; + } + ReverseIterator operator--(int) { + ReverseIterator ret_val = *this; + ++(*this); + return ret_val; + } +}; + +template +typename MdsRow::iterator MdsRow::begin() +{ return iterator((UserMdsNode*)(ListNode>*)sorted_list_.list_head_); } +template +typename MdsRow::iterator MdsRow::end() +{ return iterator(nullptr); } +template +typename MdsRow::const_iterator MdsRow::cbegin() +{ return const_iterator((UserMdsNode*)(ListNode>*)sorted_list_.list_head_); } +template +typename MdsRow::const_iterator MdsRow::cend() +{ return const_iterator(nullptr); } +template +typename MdsRow::reverse_iterator MdsRow::rbegin() +{ return reverse_iterator((UserMdsNode*)(ListNode>*)sorted_list_.list_tail_); } +template +typename MdsRow::reverse_iterator MdsRow::rend() +{ return reverse_iterator(nullptr); } +template +typename MdsRow::const_reverse_iterator MdsRow::crbegin() +{ return const_reverse_iterator((UserMdsNode*)(ListNode>*)sorted_list_.list_tail_); } +template +typename MdsRow::const_reverse_iterator MdsRow::crend() +{ return const_reverse_iterator(nullptr); } + +template +MdsRow::~MdsRow()// all mds nodes lived with RAII, owned by MdsRow +{ + MdsWLockGuard lg(MdsRowBase::lock_); + if (!sorted_list_.empty()) { + MDS_LOG_RET(WARN, OB_INVALID_ARGUMENT, "release mds mode when mds row destructed", K(*this)); + sorted_list_.for_each_node_from_tail_to_head_until_true( + [this](const UserMdsNode &node) { + UserMdsNode &cast_node = const_cast &>(node); + sorted_list_.del((ListNodeBase*)(ListNode>*)&cast_node); + MdsFactory::destroy(&cast_node); + return false; + } + ); + } +} + +template +template +int MdsRow::for_each_node_(OPERATION &&op) const +{ + int ret = 0; + sorted_list_.for_each_node_from_head_to_tail_until_true( + [&ret, &op](const UserMdsNode &node) { + ret = op(node); + return OB_SUCCESS != ret; + } + ); + return ret; +} + +template +template +int MdsRow::construct_insert_record_user_mds_node_(MdsRowBase *mds_row, + DATA &&data, + const MdsNodeType node_type, + const share::SCN scn, + MdsCtx &ctx) +{ + #define PRINT_WRAPPER KR(ret), K(typeid(V).name()), K(obj_to_string(node_type)), K(scn), K(ctx),\ + K(*this), KP(new_node) + int ret = OB_SUCCESS; + MDS_TG(5_ms); + bool need_rollback_node = false; + UserMdsNode *new_node = nullptr; +#ifndef UNITTEST_DEBUG + set_mds_mem_check_thread_local_info(mds_row->p_mds_unit_->p_mds_table_->ls_id_, + mds_row->p_mds_unit_->p_mds_table_->tablet_id_, + typeid(new_node).name()); +#endif + // if this is an insert action, check is same scn mds node exists + if (scn != share::SCN::max_scn() && MDS_FAIL(for_each_node_( + [scn](const UserMdsNode &node) { + int ret = OB_SUCCESS; + if (scn == node.redo_scn_) { + ret = OB_ENTRY_EXIST; + } + return ret; + } + ))) { + MDS_LOG_SET(WARN, "scn is not max, this is an insert action, but node with same scn exists"); + } else if (MDS_FAIL_FLAG(MdsFactory::create(new_node, + mds_row, + node_type, + ctx.get_writer().writer_type_, + ctx.get_writer().writer_id_), + need_rollback_node)) { + MDS_LOG_SET(WARN, "construct new node failed"); + } else if (MDS_FAIL(common::meta::move_or_copy_or_assign(std::forward(data), + new_node->user_data_, + MdsAllocator::get_instance()))) { + MDS_LOG_SET(WARN, "move_or_copy_or_assign user data failed"); + } else { + CLICK(); + new_node->on_user_data_set_(); + if (!scn.is_max()) {// replay + new_node->on_redo_(scn); + } + sorted_list_.insert(new_node); + new_node->mds_ctx_ = &ctx; + CLICK(); + ctx.record_written_node(new_node); + if (scn == share::SCN::max_scn()) { + report_event_("WRITE_NODE", *new_node); + } else { + report_event_("REPLAY_NODE", *new_node); + } + } + // rollback logic + if (OB_FAIL(ret)) { + if (need_rollback_node) { + MdsFactory::destroy(new_node); + new_node = nullptr; + } + if (OB_ENTRY_EXIST == ret) { + ret = OB_SUCCESS; + } + } + reset_mds_mem_check_thread_local_info(); + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsRow::write_operation_wrapper_(WRITE_OPERATION &&write_op, + MdsCtx &ctx, + const int64_t lock_timeout_us) +{ + #define PRINT_WRAPPER KR(ret), K(typeid(V).name()), K(ctx), KTIME(timeout_ts),\ + K(lock_timeout_us), K(try_lock_times), K(*this) + int ret = OB_SUCCESS; + bool write_conflict = true; + int try_lock_times = 0; + int64_t timeout_ts = ObClockGenerator::getRealClock() + lock_timeout_us; + MDS_TG(std::max(lock_timeout_us, (int64_t)5_ms)); + if (!ctx.can_write()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG_SET(WARN, "invalid mds ctx"); + } else { + do { + MDS_TG(5_ms); + MdsWLockGuard lg(MdsRowBase::lock_);// lock row + if (sorted_list_.empty()) {// for now, all writting data are in memory + write_conflict = false; + } else { + if (OB_LIKELY(sorted_list_.get_head().is_decided_())) { + write_conflict = false; + } else if (sorted_list_.get_head().get_writer_() == ctx.get_writer()) { + write_conflict = false; + } + } + UserMdsNode *new_node = nullptr; + if (OB_UNLIKELY(write_conflict)) { + ret = OB_TRY_LOCK_ROW_CONFLICT; + } else if (MDS_FAIL(write_op())) { + MDS_LOG_SET(WARN, "execute write op failed"); + } else { + MDS_LOG_SET(TRACE, "MdsRow set node success"); + } + } while (++try_lock_times && + OB_TRY_LOCK_ROW_CONFLICT == ret &&// keep trying but release latch + ObClockGenerator::getRealClock() < timeout_ts &&// check timeout + ({ob_usleep(50_ms); true;}));// if not, wait and try again + } + if (OB_FAIL(ret)) { + if (lock_timeout_us != 0 && OB_TRY_LOCK_ROW_CONFLICT == ret) { + ret = OB_ERR_EXCLUSIVE_LOCK_CONFLICT; + MDS_LOG_SET(WARN, "write data conflict cause reach lock timeout"); + } else { + MDS_LOG_SET(WARN, "write failed"); + } + } else { + MDS_LOG_SET(TRACE, "MdsRow write node success"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsRow::set(DATA &&data, + MdsCtx &ctx, + const int64_t lock_timeout_us, + const bool is_for_remove) +{ + ForwardWrapper forward_wrapper(std::forward(data)); + return write_operation_wrapper_( + [&forward_wrapper, &ctx, is_for_remove, this]() -> int { + int ret = OB_SUCCESS; + if (forward_wrapper.is_constructed_from_lvalue_) { + ret = construct_insert_record_user_mds_node_(this, + forward_wrapper.data_, + is_for_remove ? MdsNodeType::DELETE : MdsNodeType::SET, + share::SCN::max_scn(), + ctx); + } else { + ret = construct_insert_record_user_mds_node_(this, + std::move(forward_wrapper.data_), + is_for_remove ? MdsNodeType::DELETE : MdsNodeType::SET, + share::SCN::max_scn(), + ctx); + } + return ret; + }, + ctx, lock_timeout_us); +} + +template +template +int MdsRow::replay(DATA &&data, + MdsCtx &ctx, + const share::SCN scn, + const bool is_for_remove) +{ + #define PRINT_WRAPPER KR(ret), K(typeid(V).name()), K(ctx), K(scn), K(is_for_remove), K(*this) + int ret = OB_SUCCESS; + MDS_TG(5_ms); + if (!ctx.can_write() || !scn.is_valid() || scn.is_max()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG_SET(ERROR, "invalid argument"); + } else { + MdsWLockGuard lg(MdsRowBase::lock_); + if (MDS_FAIL(construct_insert_record_user_mds_node_(this, + std::forward(data), + is_for_remove ? MdsNodeType::DELETE : MdsNodeType::SET, + scn, + ctx))) { + MDS_LOG_SET(WARN, "fail to constrtuct data node"); + if (OB_ENTRY_NOT_EXIST == ret) {// may replay multi times + ret = OB_SUCCESS; + MDS_LOG_SET(INFO, "this node has been replayed"); + } + } else { + MDS_LOG_SET(TRACE, "MdsRow replay node success"); + } + } + return ret; + #undef PRINT_WRAPPER +} + +// this function must be called from for_each_lock_ method with lock protection. +// but this function may hung until node decided, so when it sleep, must release lock, +// when it awaken, must add lock again. +template +int MdsRow::check_node_snapshot_(const UserMdsNode &node, + const share::SCN snapshot, + const int64_t timeout_ts, + bool &can_read) const +{ + #define PRINT_WRAPPER KR(ret), KPC(node), K(typeid(READ_OP).name()), K(retry_times), K(can_read),\ + K(*this), K(snapshot_converted) + int ret = OB_SUCCESS; + can_read = false; + share::SCN snapshot_converted = snapshot; + if (snapshot_converted == share::SCN::max_scn()) { + snapshot_converted = share::SCN::scn_dec(snapshot_converted); + } + if (!node.is_decided_() && node.get_prepare_version_() <= snapshot_converted) { + if (ObClockGenerator::getRealClock() > timeout_ts) { + ret = OB_ERR_SHARED_LOCK_CONFLICT; + MDS_LOG(WARN, "timeout when wait node decided", K(node), K(node.get_prepare_version_()), K(snapshot_converted), K(snapshot)); + } else { + ret = OB_EAGAIN; + } + } else if (node.is_committed_() && node.get_commit_version_() <= snapshot_converted) { + can_read = true; + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsRow::get_with_read_wrapper_(READ_OP &&read_operation, + CHECK_NODE_OP &&check_node_op) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(typeid(V).name()) + int ret = OB_SUCCESS; + bool read_op_applied = false; + auto read_op_wrapper = [&read_operation, &read_op_applied](const UserMdsNode &data) -> int { + read_op_applied = true; + return read_operation(data); + }; + for_each_node_([&](const UserMdsNode &node) { + bool can_read = false; + OB_ASSERT(!node.is_aborted_());// should not meet aborted node, cause aborted node deleted immediately + if (OB_FAIL(check_node_op(node, can_read))) { + MDS_LOG_GET(WARN, "check node can read meet failed"); + } else if (can_read) { + if (node.get_node_type() == MdsNodeType::DELETE) { + ret = OB_ENTRY_NOT_EXIST; + MDS_LOG_GET(INFO, "data is marked removed, return not exist"); + } else if (node.get_node_type() == MdsNodeType::SET) { + if (OB_FAIL(read_op_wrapper(node))) { + MDS_LOG_GET(WARN, "call user read op failed"); + } + } else { + MDS_LOG_GET(ERROR, "meet unknown mds node type"); + } + } + return OB_FAIL(ret) || can_read;// either fail or read already, stop iter + }); + if (OB_SUCC(ret)) { + if (!read_op_applied) {// no node satisfied + ret = OB_SNAPSHOT_DISCARDED; + MDS_LOG_GET(DEBUG, "there is no node can be read"); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsRow::get_snapshot(READ_OP &&read_operation, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + #define PRINT_WRAPPER KR(ret), K(snapshot), K(read_seq), K(timeout_us), K(timeout_ts), K(*this) + int ret = OB_SUCCESS; + UNUSED(read_seq); + int64_t timeout_ts = ObClockGenerator::getRealClock() + timeout_us; + MDS_TG(5_ms); + do { + MdsRLockGuard lg(MdsRowBase::lock_); + if (MDS_FAIL(get_with_read_wrapper_(read_operation, + [&](const UserMdsNode &node, bool &can_read) -> int { + return check_node_snapshot_(node, snapshot, timeout_ts, can_read); + } + ))) { + if (OB_EAGAIN != ret && OB_SNAPSHOT_DISCARDED != ret) { + MDS_LOG_GET(WARN, "MdsRow get_snapshot failed"); + } + } else { + MDS_LOG_GET(TRACE, "MdsRow get_snapshot success"); + } + } while (OB_EAGAIN == ret && + ({ob_usleep(10_ms); true;})); + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsRow::get_latest(READ_OP &&read_operation, const int64_t read_seq) const +{ + #define PRINT_WRAPPER KR(ret), K(read_seq), K(*this) + int ret = OB_SUCCESS; + UNUSED(read_seq); + MDS_TG(5_ms); + MdsRLockGuard lg(MdsRowBase::lock_); + if (MDS_FAIL(get_with_read_wrapper_(read_operation, + [&](const UserMdsNode &, bool &can_read) -> int { + can_read = true; + return OB_SUCCESS; + } + ))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG_GET(WARN, "MdsRow get_latest failed"); + } + } else { + MDS_LOG_GET(TRACE, "MdsRow get_latest success"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsRow::get_by_writer(READ_OP &&read_operation, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + #define PRINT_WRAPPER KR(ret), K(writer), K(snapshot), K(read_seq), K(timeout_us),\ + KTIME(timeout_ts), K(*this) + int ret = OB_SUCCESS; + UNUSED(read_seq); + MDS_TG(5_ms); + int64_t timeout_ts = ObClockGenerator::getRealClock() + timeout_us; + do { + MdsRLockGuard lg(MdsRowBase::lock_); + if (MDS_FAIL(get_with_read_wrapper_(read_operation, + [&](const UserMdsNode &node, bool &can_read) -> int { + int ret = OB_SUCCESS; + if (node.get_writer_() == writer) { + can_read = true; + } else { + ret = check_node_snapshot_(node, snapshot, timeout_ts, can_read); + } + return ret; + } + ))) { + if (OB_UNLIKELY(OB_EAGAIN != ret && OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG_GET(WARN, "MdsRow get_by_writer failed"); + } + } else { + MDS_LOG_GET(TRACE, "MdsRow get_by_writer success"); + } + } while (OB_EAGAIN == ret && + ({ob_usleep(10_ms); true;})); + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsRow::scan_dump_node_from_tail_to_head(DUMP_OP &&op, + const uint8_t mds_table_id, + const uint8_t mds_unit_id, + MdsDumpKV &dump_kv, + const share::SCN &flush_scn, + const bool for_flush) const +{ + #define PRINT_WRAPPER KR(ret), K(dump_kv), K(flush_scn), K(for_flush) + int ret = OB_SUCCESS; + MDS_TG(5_ms); + MdsRLockGuard lg(MdsRowBase::lock_); + CLICK(); + bool has_meet_undump_node = false; + sorted_list_.for_each_node_from_tail_to_head_until_true(// from old to new + [this, &op, &ret, &dump_kv, flush_scn, for_flush, mds_table_id, mds_unit_id, &has_meet_undump_node](const UserMdsNode &node) { + bool need_break = false; + MDS_TG(5_ms); + OB_ASSERT(!node.is_aborted_());// should not see aborted node, cause it is deleted immediatly + if (!node.is_committed_()) { + if (node.redo_scn_.is_valid() && !flush_scn.is_max()) { + OB_ASSERT(node.redo_scn_ > flush_scn);// defense + } + need_break = true; + } else if (node.is_dumped_()) {// just skip it + // all nodes before first undumped node should be dumped status,(reverse scan order) + // and all nodes after first undumped node should be undemped status(reverse scan order) + OB_ASSERT(has_meet_undump_node == false);// defense + } else if (FALSE_IT(has_meet_undump_node = true)) {// this is a barrier, mark it to defense + } else if (!check_node_scn_beflow_flush(node, flush_scn)) { + need_break = true; + } else if (MDS_FAIL(dump_kv.v_.init(mds_table_id, + mds_unit_id, + node, + DefaultAllocator::get_instance()))) { + MDS_LOG_SCAN(WARN, "failt to convert user mds node to dump node", K(node)); + } else if (MDS_FAIL(op(dump_kv))) { + MDS_LOG_SCAN(WARN, "failt to apply op on dump node", K(node)); + } else if (for_flush) { + report_event_("DUMP_NODE_FOR_FLUSH", node); + } else { + report_event_("DUMP_NODE", node); + } + return need_break || OB_SUCCESS != ret; + } + ); + if (OB_FAIL(ret)) { + MDS_LOG_SCAN(WARN, "failt to apply op on mds node", K(*this)); + } else { + MDS_LOG_SCAN(TRACE, "scan row", K(*this)); + } + return ret; + #undef PRINT_WRAPPER +} + +template +void MdsRow::node_abort_callback_(ListNodeBase *node) +{ + #define PRINT_WRAPPER KR(ret), KPC(node) + int ret = OB_SUCCESS; + MDS_TG(1_ms); + UserMdsNode *cast_node = dynamic_cast*>(node); + if (OB_ISNULL(cast_node)) { + MDS_LOG_GC(ERROR, "down cast failed!", K(*this), KP(cast_node)); + } else if (!cast_node->is_aborted_()) { + MDS_LOG_GC(ERROR, "node state is not aborted", K(*this), KP(cast_node)); + } else { + bool has_meet_input_arg_node = false; + sorted_list_.for_each_node_from_head_to_tail_until_true([this, + cast_node, + &has_meet_input_arg_node] + (const UserMdsNode &node) { + bool ret = false; + if (&node == cast_node) { + has_meet_input_arg_node = true; + sorted_list_.del((ListNodeBase*)(ListNode>*)&node); + MdsFactory::destroy(const_cast*>(&node)); + ret = true; + } + return ret; + }); + OB_ASSERT(has_meet_input_arg_node); + } + #undef PRINT_WRAPPER +} + +template +int64_t MdsRow::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + MdsTableBase *p_mds_table = nullptr; + if (MdsRowBase::p_mds_unit_) { + p_mds_table = MdsRowBase::p_mds_unit_->p_mds_table_; + } + databuff_printf(buf, buf_len, pos, "sorted_list={%s}, ", to_cstring(sorted_list_)); + databuff_printf(buf, buf_len, pos, "mds_table={%s}, ", p_mds_table ? to_cstring(*p_mds_table) : "NULL"); + databuff_printf(buf, buf_len, pos, "key={%s}", MdsRowBase::key_ ? to_cstring(* MdsRowBase::key_) : "NULL"); + return pos; +} + +template +template +int MdsRow::fill_virtual_info(const Key &key, + ObIArray &mds_node_info_array, + const int64_t unit_id) const +{ + #define PRINT_WRAPPER KR(ret), K(key), KPC(this) + int ret = OB_SUCCESS; + MDS_TG(5_ms); + MdsRLockGuard lg(MdsRowBase::lock_); + CLICK(); + int idx = 0; + constexpr int64_t buffer_size = 512_B; + char stack_buffer[buffer_size] = { 0 }; + int64_t pos = 0; + if (FALSE_IT(databuff_printf(stack_buffer, buffer_size, pos, "%s", to_cstring(key)))) { + } else { + ObString key_str(pos, stack_buffer); + sorted_list_.for_each_node_from_head_to_tail_until_true([&ret, &key, &idx, &mds_node_info_array, &key_str, unit_id, this](const UserMdsNode &node) { + MDS_TG(5_ms); + if (MDS_FAIL(mds_node_info_array.push_back(MdsNodeInfoForVirtualTable()))) { + MDS_LOG_SCAN(WARN, "fail to push new element to array"); + } else { + MdsNodeInfoForVirtualTable &virtual_info = mds_node_info_array.at(mds_node_info_array.count() - 1); + if (MDS_FAIL(virtual_info.user_key_.assign(key_str))) { + MDS_LOG_SCAN(WARN, "fail to construct ObStringHolder"); + } else if (MDS_FAIL(node.fill_virtual_info(virtual_info))) { + MDS_LOG_SCAN(WARN, "fail to fill virtual info from mds node"); + } else { + virtual_info.version_idx_ = idx++; + virtual_info.unit_id_ = unit_id; + } + } + return OB_SUCCESS != ret; + }); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +void MdsRow::report_event_(const char (&event_str)[N], + const UserMdsNode &node, + const char *file, + const uint32_t line, + const char *function_name) const +{ + int ret = OB_SUCCESS; + constexpr int64_t buffer_size = 1_KB; + char stack_buffer[buffer_size] = { 0 }; + observer::MdsEvent event; + if (nullptr == MdsRowBase::p_mds_unit_ || + nullptr == MdsRowBase::p_mds_unit_->p_mds_table_) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "not expected ptr", K(*this)); + } else if (OB_FAIL(node.fill_event_(event, event_str, stack_buffer, buffer_size))) { + MDS_LOG(WARN, "fail fill mds event", K(*this)); + } else { + observer::MdsEventKey key(MTL_ID(), + MdsRowBase::p_mds_unit_->p_mds_table_->ls_id_, + MdsRowBase::p_mds_unit_->p_mds_table_->tablet_id_); + observer::ObMdsEventBuffer::append(key, event, file, line, function_name); + } +} + +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_table_base.cpp b/src/storage/multi_data_source/mds_table_base.cpp new file mode 100644 index 000000000..6d3094457 --- /dev/null +++ b/src/storage/multi_data_source/mds_table_base.cpp @@ -0,0 +1,252 @@ +/** + * Copyright (c) 2023 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 "mds_table_base.h" +#include "lib/lock/ob_small_spin_lock.h" +#include "lib/ob_errno.h" +#include "lib/profile/ob_trace_id.h" +#include "ob_clock_generator.h" +#include "share/scn.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/compaction/ob_schedule_dag_func.h" +#include "storage/multi_data_source/ob_mds_table_merge_dag_param.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +int MdsTableBase::advance_state_to(State new_state) const +{ + int ret = OB_SUCCESS; + MDS_TG(1_ms); + bool success = false; + while (!success && OB_SUCC(ret)) { + State old_state = ATOMIC_LOAD(&state_); + if (new_state < old_state) {// no need advance + break; + } else if (!StateChecker[old_state][new_state]) { + ret = OB_STATE_NOT_MATCH; + MDS_LOG(WARN, "not allow switch mds table state", KR(ret), K(*this), + K(state_to_string(old_state)), K(state_to_string(new_state))); + } else { + success = ATOMIC_BCAS(&state_, old_state, new_state); + } + } + return ret; +} + +int MdsTableBase::init(const ObTabletID tablet_id, + const share::ObLSID ls_id, + ObTabletPointer *pointer, + ObMdsTableMgr *p_mgr) +{ + int ret = OB_SUCCESS; + MDS_TG(1_ms); + if (!ls_id.is_valid() || !tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG(ERROR, "invalid argument", KR(ret), K(*this), K(ls_id), K(tablet_id)); + } else if (MDS_FAIL(advance_state_to(State::INIT))) { + MDS_LOG(ERROR, "mds table maybe init twice", KR(ret), K(*this), K(ls_id), K(tablet_id)); + } else { + tablet_id_ = tablet_id; + ls_id_ = ls_id; + if (OB_NOT_NULL(p_mgr)) { + mgr_handle_.set_mds_table_mgr(p_mgr); + debug_info_.do_init_tablet_pointer_ = pointer; + debug_info_.init_trace_id_ = *ObCurTraceId::get_trace_id(); + debug_info_.init_ts_ = ObClockGenerator::getCurrentTime(); + if (MDS_FAIL(register_to_mds_table_mgr())) { + MDS_LOG(WARN, "fail to register mds table", KR(ret), K(*this), K(ls_id), K(tablet_id)); + } + } + MDS_LOG(INFO, "mds table inited", KR(ret), K(*this)); + } + return ret; +} + +int MdsTableBase::register_to_mds_table_mgr() +{ + int ret = OB_SUCCESS; + MDS_TG(1_ms); + if (OB_ISNULL(mgr_handle_.get_mds_table_mgr())) { + ret = OB_BAD_NULL_ERROR; + MDS_LOG(WARN, "mds_table_mgr ptr is null", KR(ret), K(*this)); + } else if (MDS_FAIL(mgr_handle_.get_mds_table_mgr()->register_to_mds_table_mgr(this))) { + MDS_LOG(WARN, "fail to register mds table", KR(ret), K(*this)); + } + return ret; +} + +void MdsTableBase::mark_removed_from_t3m(ObTabletPointer *pointer) +{ + if (ATOMIC_LOAD(&debug_info_.remove_ts_) != 0) { + MDS_LOG_RET(WARN, OB_ERR_UNEXPECTED, "this MdsTable has been marked removed", K(*this)); + } else { + debug_info_.do_remove_tablet_pointer_ = pointer; + debug_info_.remove_trace_id_ = *ObCurTraceId::get_trace_id(); + ATOMIC_STORE(&debug_info_.remove_ts_, ObClockGenerator::getCurrentTime()); + } +} + +bool MdsTableBase::is_removed_from_t3m() const +{ + return ATOMIC_LOAD(&debug_info_.remove_ts_) != 0; +} + +int64_t MdsTableBase::get_removed_from_t3m_ts() const +{ + return ATOMIC_LOAD(&debug_info_.remove_ts_); +} + +int MdsTableBase::unregister_from_mds_table_mgr() +{ + int ret = OB_SUCCESS; + MDS_TG(1_ms); + if (!mgr_handle_.is_valid()) { + MDS_LOG(INFO, "no need unregister from mds_table_mgr cause invalid mds_table_mgr", KR(ret), K(*this)); + } else if (!ls_id_.is_valid() || !tablet_id_.is_valid()) { + MDS_LOG(INFO, "no need unregister from mds_table_mgr cause invalid id", KR(ret), K(*this)); + } else if (MDS_FAIL(mgr_handle_.get_mds_table_mgr()->unregister_from_mds_table_mgr(this))) { + MDS_LOG(ERROR, "fail to unregister mds table", K(*this)); + } else { + mgr_handle_.reset(); + } + return ret; +} + +int MdsTableBase::get_ls_max_consequent_callbacked_scn_(share::SCN &max_consequent_callbacked_scn) const +{ + int ret = OB_SUCCESS; + ObLSService *ls_service = MTL(ObLSService *); + ObLSHandle ls_handle; + MDS_TG(1_ms); + if (!ls_id_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(WARN, "ls id not valid", KR(ret), K(*this)); + } else if (OB_ISNULL(ls_service)) { + ret = OB_BAD_NULL_ERROR; + MDS_LOG(WARN, "ls tx service is null", KR(ret), K(*this)); + } else if (MDS_FAIL(ls_service->get_ls(ls_id_, ls_handle, ObLSGetMod::MDS_TABLE_MOD))) { + MDS_LOG(WARN, "fail to get ls handle", KR(ret), K(*this)); + } else if (MDS_FAIL(ls_handle.get_ls()->get_freezer()->get_max_consequent_callbacked_scn(max_consequent_callbacked_scn))) { + MDS_LOG(WARN, "fail to get max_consequent_callbacked_scn", KR(ret), K(*this)); + } + return ret; +} + +int MdsTableBase::merge(const share::SCN &flushing_scn) +{ + int ret = OB_SUCCESS; + ObMdsTableMergeDagParam param; + param.ls_id_ = ls_id_; + param.tablet_id_ = tablet_id_; + param.flush_scn_ = flushing_scn; + if (OB_FAIL(compaction::ObScheduleDagFunc::schedule_mds_table_merge_dag(param))) { + if (OB_EAGAIN != ret && OB_SIZE_OVERFLOW != ret) { + MDS_LOG(WARN, "failed to schedule mds table merge dag", K(ret), K(param)); + } + } else { + MDS_LOG(DEBUG, "succeeded to schedule mds table merge dag", K(ret), K(param)); + } + return ret; +} + +int64_t MdsTableBase::get_node_cnt() const +{ + int64_t total_cnt = ATOMIC_LOAD(&total_node_cnt_); + if (total_cnt < 0) { + MDS_LOG_RET(ERROR, OB_ERR_SYS, "total_valid_node_cnt_ is less than 0", KP(this), K(total_cnt)); + } + return total_cnt; +} + +void MdsTableBase::inc_valid_node_cnt() +{ + if (ATOMIC_AAF(&total_node_cnt_, 1) <= 0) { + MDS_LOG_RET(ERROR, OB_ERR_SYS, "total_valid_node_cnt_ is less than 0", KP(this), K(total_node_cnt_)); + } +} + +void MdsTableBase::dec_valid_node_cnt() +{ + if (ATOMIC_AAF(&total_node_cnt_, -1) < 0) { + MDS_LOG_RET(ERROR, OB_ERR_SYS, "total_valid_node_cnt_ is less than 0", KP(this), K(total_node_cnt_)); + } +} + +void MdsTableBase::try_advance_rec_scn(const share::SCN scn) +{ + bool success = false; + while (!success) { + share::SCN old_scn = rec_scn_; + if (scn > old_scn) { + success = rec_scn_.atomic_bcas(old_scn, scn); + if (success) { + report_rec_scn_event_("ADVANCE_REC_SCN", old_scn, scn); + } + } else { + break; + } + } +} + +void MdsTableBase::try_decline_rec_scn(const share::SCN scn) +{ + bool success = false; + while (!success) { + share::SCN old_scn = rec_scn_; + if (scn < old_scn) { + success = rec_scn_.atomic_bcas(old_scn, scn); + if (success) { + report_rec_scn_event_("DECLINE_REC_SCN", old_scn, scn); + } + } else { + break; + } + } +} + +common::ObTabletID MdsTableBase::get_tablet_id() const +{ + return tablet_id_; +} + +share::ObLSID MdsTableBase::get_ls_id() const +{ + return ls_id_; +} + +share::SCN MdsTableBase::get_rec_scn() +{ + return rec_scn_.atomic_get(); +} + +bool MdsTableBase::is_flushing() const +{ + MdsRLockGuard lg(lock_); + return flushing_scn_.is_valid(); +} + +bool check_node_scn_beflow_flush(const MdsNode &node, const share::SCN &flush_scn) +{ + bool need_dump = false; + if (node.end_scn_ <= flush_scn) {// change to redo_scn <= flush_scn after support dump uncommitted node + need_dump = true; + } + return need_dump; +} + +} // namespace mds +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/multi_data_source/mds_table_base.h b/src/storage/multi_data_source/mds_table_base.h new file mode 100644 index 000000000..8075adc6f --- /dev/null +++ b/src/storage/multi_data_source/mds_table_base.h @@ -0,0 +1,292 @@ +/** + * Copyright (c) 2023 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 STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_BASE_H +#define STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_BASE_H + +#include "lib/container/ob_array.h" +#include "lib/ob_define.h" +#include "lib/profile/ob_trace_id.h" +#include "storage/checkpoint/ob_common_checkpoint.h" +#include "lib/function/ob_function.h" +#include "runtime_utility/mds_lock.h" +#include "storage/multi_data_source/mds_table_mgr.h" +#include "observer/virtual_table/ob_mds_event_buffer.h" +#include "storage/multi_data_source/runtime_utility/list_helper.h" + +namespace oceanbase +{ +namespace share +{ +class SCN; +} +namespace storage +{ +class ObTabletPointer; +namespace mds +{ +template +class MdsRow; +template +class MdsUnit; +template +class UserMdsNode; +class MdsNode; +class MdsCtx; +class MdsWriter; +class MdsDumpKV; +class MdsNodeInfoForVirtualTable; +enum class MdsTableType { + LS_INNER_TABLE = 1, + NORMAL_TABLE = 2, + UNKNOWN = 3, +}; + +class MdsTableBase : public ListNode +{ + template + friend class MdsRow; + template + friend class MdsUnit; + friend class MdsNode; + template + friend class UserMdsNode; +protected: + enum State : uint8_t { + UNKNOWN = 0, + INIT, + WRITTING,// replay or set + END, + }; + const char *state_to_string(State state) const { + switch (state) { + case State::UNKNOWN: return "UNKNOWN"; + case State::INIT: return "INIT"; + case State::WRITTING: return "WRITTING"; + default: return "UNEXPECTED"; + } + } + static constexpr bool StateChecker[static_cast(State::END)][static_cast(State::END)] = { + {0, 1, 0},// from UNKNOWN, only allowed to switch to INIT + {0, 0, 1},// from INIT, allowed to switch to WRITTING + {0, 0, 1},// from WRITTING, not allowed to switch to any state + }; + int advance_state_to(State new_state) const; +public: + MdsTableBase() + : state_(State::UNKNOWN), + ls_id_(), + tablet_id_(), + flushing_scn_(), + last_flushed_scn_(share::SCN::min_scn()), + last_inner_recycled_scn_(share::SCN::min_scn()), + rec_scn_(share::SCN::max_scn()), + total_node_cnt_(0), + lock_() {} + virtual ~MdsTableBase() {} + int init(const ObTabletID tablet_id, + const share::ObLSID ls_id, + ObTabletPointer *pointer, + ObMdsTableMgr *p_mgr); + virtual int set(int64_t unit_id, + void *key, + void *data, + bool is_rvalue, + MdsCtx &ctx, + const int64_t lock_timeout_us) = 0; + virtual int replay(int64_t unit_id, + void *key, + void *data, + bool is_rvalue, + MdsCtx &ctx, + const share::SCN &scn) = 0; + virtual int remove(int64_t unit_id, + void *key, + MdsCtx &ctx, + const int64_t lock_timeout_us) = 0; + virtual int replay_remove(int64_t unit_id, + void *key, + MdsCtx &ctx, + const share::SCN &scn) = 0; + virtual int get_latest(int64_t unit_id, + void *key, + ObFunction &op, + bool &is_committed, + const int64_t read_seq) const = 0; + virtual int get_snapshot(int64_t unit_id, + void *key, + ObFunction &op, + const share::SCN &snapshot, + const int64_t read_seq, + const int64_t timeout_us) const = 0; + virtual int get_by_writer(int64_t unit_id, + void *key, + ObFunction &op, + const MdsWriter &writer, + const share::SCN &snapshot, + const int64_t read_seq, + const int64_t timeout_us) const = 0; + virtual int is_locked_by_others(int64_t unit_id, + void *key, + bool &is_locked, + const MdsWriter &self) const = 0; + virtual int for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump( + ObFunction &for_each_op, + const bool for_flush) const = 0; + virtual void on_flush(const share::SCN &flushed_scn, const int flush_ret) = 0; + virtual int try_recycle(const share::SCN recycle_scn) = 0; + share::ObLSID get_ls_id() const; + int64_t get_node_cnt() const; + virtual share::SCN get_rec_scn(); + virtual int flush(share::SCN recycle_scn, bool need_freeze = true) = 0; + virtual ObTabletID get_tablet_id() const; + virtual bool is_flushing() const; + virtual int fill_virtual_info(ObIArray &mds_node_info_array) const = 0; + virtual int forcely_release_all_mds_nodes(const char *reason) = 0; + void mark_removed_from_t3m(ObTabletPointer *pointer);// need called in del tablet phase + bool is_removed_from_t3m() const; + int64_t get_removed_from_t3m_ts() const; + VIRTUAL_TO_STRING_KV(KP(this)); +protected: + void inc_valid_node_cnt(); + void dec_valid_node_cnt(); + void try_advance_rec_scn(const share::SCN scn); + void try_decline_rec_scn(const share::SCN scn); + int get_ls_max_consequent_callbacked_scn_(share::SCN &max_consequent_callbacked_scn) const; + int register_to_mds_table_mgr(); + int unregister_from_mds_table_mgr(); + int merge(const share::SCN &flushing_scn); + template + void report_rec_scn_event_(const char (&event_str)[N], + share::SCN old_scn, + share::SCN new_scn, + const char *file = __builtin_FILE(), + const uint32_t line = __builtin_LINE(), + const char *function_name = __builtin_FUNCTION()) { + int ret = OB_SUCCESS; + observer::MdsEvent event; + constexpr int64_t buffer_size = 1_KB; + char stack_buffer[buffer_size] = { 0 }; + int64_t pos = 0; + if (FALSE_IT(databuff_printf(stack_buffer, buffer_size, pos, "%s -> %s", to_cstring(old_scn), to_cstring(new_scn)))) { + } else { + event.record_thread_info_(); + event.info_str_.assign(stack_buffer, pos); + event.event_ = event_str; + observer::MdsEventKey key(MTL_ID(), + ls_id_, + tablet_id_); + observer::ObMdsEventBuffer::append(key, event, file, line, function_name); + } + } + template + void report_flush_event_(const char (&event_str)[N], + share::SCN flush_scn, + bool need_freeze, + const char *file = __builtin_FILE(), + const uint32_t line = __builtin_LINE(), + const char *function_name = __builtin_FUNCTION()) { + int ret = OB_SUCCESS; + observer::MdsEvent event; + constexpr int64_t buffer_size = 1_KB; + char stack_buffer[buffer_size] = { 0 }; + int64_t pos = 0; + if (FALSE_IT(databuff_printf(stack_buffer, buffer_size, pos, + "flush_scn:%s, need_freeze:%s", to_cstring(flush_scn), to_cstring(need_freeze)))) { + } else { + event.record_thread_info_(); + event.info_str_.assign(stack_buffer, pos); + event.event_ = event_str; + observer::MdsEventKey key(MTL_ID(), + ls_id_, + tablet_id_); + observer::ObMdsEventBuffer::append(key, event, file, line, function_name); + } + } + template + void report_on_flush_event_(const char (&event_str)[N], + share::SCN flush_scn, + const char *file = __builtin_FILE(), + const uint32_t line = __builtin_LINE(), + const char *function_name = __builtin_FUNCTION()) { + int ret = OB_SUCCESS; + observer::MdsEvent event; + constexpr int64_t buffer_size = 1_KB; + char stack_buffer[buffer_size] = { 0 }; + int64_t pos = 0; + if (FALSE_IT(databuff_printf(stack_buffer, buffer_size, pos, + "flush_scn:%s", to_cstring(flush_scn)))) { + } else { + event.record_thread_info_(); + event.info_str_.assign(stack_buffer, pos); + event.event_ = event_str; + observer::MdsEventKey key(MTL_ID(), + ls_id_, + tablet_id_); + observer::ObMdsEventBuffer::append(key, event, file, line, function_name); + } + } + void report_recycle_event_(share::SCN recycle_scn, + const char *file = __builtin_FILE(), + const uint32_t line = __builtin_LINE(), + const char *function_name = __builtin_FUNCTION()) { + int ret = OB_SUCCESS; + observer::MdsEvent event; + constexpr int64_t buffer_size = 1_KB; + char stack_buffer[buffer_size] = { 0 }; + int64_t pos = 0; + if (FALSE_IT(databuff_printf(stack_buffer, buffer_size, pos, "recycle_scn:%s", to_cstring(recycle_scn)))) { + } else { + event.record_thread_info_(); + event.info_str_.assign(stack_buffer, pos); + event.event_ = "RECYCLE"; + observer::MdsEventKey key(MTL_ID(), + ls_id_, + tablet_id_); + observer::ObMdsEventBuffer::append(key, event, file, line, function_name); + } + } +protected: + struct DebugInfo { + DebugInfo() + : do_init_tablet_pointer_(nullptr), + do_remove_tablet_pointer_(nullptr), + init_ts_(0), + remove_ts_(0), + init_trace_id_(), + remove_trace_id_() {} + TO_STRING_KV(KP_(do_init_tablet_pointer), KP_(do_remove_tablet_pointer), KTIME_(init_ts), KTIME_(remove_ts), + K_(init_trace_id), K_(remove_trace_id)); + ObTabletPointer *do_init_tablet_pointer_;// can not be accessed, jsut record it to debug + ObTabletPointer *do_remove_tablet_pointer_;// can not be accessed, jsut record it to debug + int64_t init_ts_; + int64_t remove_ts_; + ObCurTraceId::TraceId init_trace_id_; + ObCurTraceId::TraceId remove_trace_id_; + } debug_info_;// 40B + mutable State state_; + share::ObLSID ls_id_; + ObTabletID tablet_id_; + share::SCN flushing_scn_;// To tell if this mds table is flushing + share::SCN last_flushed_scn_;// To filter repeated flush operation + share::SCN last_inner_recycled_scn_;// To filter repeated release operation + share::SCN rec_scn_;// To CLOG to recycle + int64_t total_node_cnt_;// To tell if this mds table is safety to destroy + MdsTableMgrHandle mgr_handle_; + mutable MdsLock lock_; +}; + +bool check_node_scn_beflow_flush(const MdsNode &node, const share::SCN &flush_scn); + +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_table_handle.h b/src/storage/multi_data_source/mds_table_handle.h new file mode 100644 index 000000000..b8defe863 --- /dev/null +++ b/src/storage/multi_data_source/mds_table_handle.h @@ -0,0 +1,196 @@ +/** + * Copyright (c) 2023 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 STORAGE_MULTI_DATE_SOURCE_MDS_TABLE_HANDLE_H +#define STORAGE_MULTI_DATE_SOURCE_MDS_TABLE_HANDLE_H + +#include "lib/ob_errno.h" +#include "mds_table_impl.h" +#include "lib/guard/ob_light_shared_gaurd.h" + +namespace oceanbase +{ +namespace storage +{ +class ObLS; +class ObTabletPointer; +namespace mds +{ +class MdsTableHandle +{ +public: + MdsTableHandle() : mds_table_id_(UINT8_MAX) {} + MdsTableHandle(const MdsTableHandle &rhs) = default; + MdsTableHandle &operator=(const MdsTableHandle &rhs) = default; + bool operator==(const MdsTableHandle &rhs) const; + ~MdsTableHandle(); + int get_tablet_id(common::ObTabletID &tablet_id) const; + int get_ls_id(share::ObLSID &ls_id) const; + template + int init(ObIAllocator &allocator, + const ObTabletID tablet_id, + const share::ObLSID ls_id, + ObTabletPointer *pointer, + ObMdsTableMgr *mgr_handle = nullptr); + template + int get_mds_unit(MdsUnit *&p_mds_unit); + int fill_virtual_info(ObIArray &mds_node_info_array) const; + int mark_removed_from_t3m(ObTabletPointer *pointer); + template + int forcely_release_all_mds_nodes(const char (&reason)[N]); + /******************************Single Key Unit Access Interface**********************************/ + template + int set(T &&data, MdsCtx &ctx, const int64_t lock_timeout_us = 0); + template + int replay(T &&data, MdsCtx &ctx, const share::SCN &scn); + template + int get_latest(OP &&read_op, bool &is_committed, const int64_t read_seq = 0) const; + template + int get_snapshot(OP &&read_op, + const share::SCN snapshot = share::SCN::max_scn(), + const int64_t read_seq = 0, + const int64_t timeout_us = 0) const; + template + int get_by_writer(OP &&read_op, + const MdsWriter &writer, + const share::SCN snapshot = share::SCN::max_scn(), + const int64_t read_seq = 0, + const int64_t timeout_us = 0) const; + template + int is_locked_by_others(bool &is_locked, const MdsWriter &self = MdsWriter()) const; + /************************************************************************************************/ + + /******************************Multi Key Unit Access Interface***********************************/ + template + int set(const Key &key, Value &&data, MdsCtx &ctx, const int64_t lock_timeout_us = 0); + template + int replay(const Key &key, Value &&data, MdsCtx &ctx, const share::SCN &scn); + template + int remove(const Key &key, MdsCtx &ctx, const int64_t lock_timeout_us = 0); + template + int replay_remove(const Key &key, MdsCtx &ctx, share::SCN &scn); + template + int get_latest(const Key &key, OP &&read_op, bool &is_committed, const int64_t read_seq = 0) const; + template + int get_snapshot(const Key &key, + OP &&read_op, + const share::SCN snapshot = share::SCN::max_scn(), + const int64_t read_seq = 0, + const int64_t timeout_us = 0) const; + template + int get_by_writer(const Key &key, + OP &&read_op, + const MdsWriter &writer, + const share::SCN snapshot = share::SCN::max_scn(), + const int64_t read_seq = 0, + const int64_t timeout_us = 0) const; + template + int is_locked_by_others(const Key &key, + bool &is_locked, + const MdsWriter &self = MdsWriter()) const; + /************************************************************************************************/ + template + int for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump(DUMP_OP &&for_each_op, + const bool for_flush) const; + int flush(share::SCN recycle_scn, bool need_freeze = true); + int is_flushing(bool &is_flushing) const; + void on_flush(const share::SCN &flush_scn, const int flush_ret); + int try_recycle(const share::SCN &recycle_scn);// release nodes + int sync_ref_until_last() const; + int get_ref_cnt(int64_t &ref_cnt) const; + int get_node_cnt(int64_t &valid_cnt) const; + int get_rec_scn(share::SCN &rec_scn) const; + bool is_valid() const; + void reset(); + MdsTableBase *get_mds_table_ptr() { return p_mds_table_base_.ptr(); } + TO_STRING_KV(K_(p_mds_table_base), K_(mds_table_id)); +public:// compile error message + template + int for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump(DUMP_OP &&for_each_op) const { + static_assert(OB_TRAIT_IS_FUNCTION_LIKE(DUMP_OP, int(const MdsDumpKV &)), + "for_each_op required to be used like: int for_each_op(const MdsDumpKV &)"); + return OB_NOT_SUPPORTED; + } +private: + uint8_t mds_table_id_; + ObLightSharedPtr p_mds_table_base_; +}; + +inline void construct_lock_guard(mds::MdsRLockGuard &guard, mds::MdsLock &lock) { + guard.~MdsRLockGuard(); + new (&guard) mds::MdsRLockGuard(lock); +} + +template +struct ObMdsKvRowScanIterator {// will lock unit when init, but won't lock row when get_next_kv_row() + using KvRowIter = typename mds::MdsUnit::iterator; + using KvRow = mds::KvPair>; + ObMdsKvRowScanIterator(); + int init(mds::MdsTableHandle &mds_table_handle); + int get_next_kv_row(KvRow *&p_kv_row); + TO_STRING_KV(KP(this), K_(is_inited), K_(is_first_scan),\ + K(typeid(UnitKey).name()), K(typeid(UnitValue).name())) +private: + bool is_inited_; + bool is_first_scan_; + mds::MdsUnit *p_mds_unit_; + KvRowIter kv_row_iter_; + mds::MdsRLockGuard unit_guard_; +}; + +template +struct ObMdsNodeScanIterator {// will lock row when init, but won't lock node when get_next() + using KvRow = mds::KvPair>; + using KvRowIter = typename mds::MdsUnit::iterator; + using NodeIter = typename KvRowIter::row_type::iterator; + ObMdsNodeScanIterator(); + int init(KvRow *&p_kv_row); + int get_next_kv_node(UnitKey &key, mds::UserMdsNode *&p_node); + bool is_valid() const; + void reset(); + TO_STRING_KV(KP(this), K_(is_inited), K_(is_first_scan),\ + K(typeid(UnitKey).name()), K(typeid(UnitValue).name())) +private: + bool is_inited_; + bool is_first_scan_; + KvRow *p_mds_kv_row_; + NodeIter node_iter_; + mds::MdsRLockGuard row_guard_; +}; + +template +struct ObMdsUnitRowNodeScanIterator {// will add mds table ref when init to make sure inner iter safe + using KvRow = mds::KvPair>; + using KvRowIter = typename mds::MdsUnit::iterator; + using NodeIter = typename KvRowIter::row_type::iterator; + ObMdsUnitRowNodeScanIterator(); + int init(mds::MdsTableHandle &mds_table_handle); + int get_next(UnitKey &key, mds::UserMdsNode *&p_node); + TO_STRING_KV(KP(this), K_(is_inited), K_(is_first_scan), K_(mds_table_handle),\ + K(typeid(UnitKey).name()), K(typeid(UnitValue).name())) +private: + bool is_inited_; + bool is_first_scan_; + mds::MdsTableHandle mds_table_handle_; + ObMdsKvRowScanIterator row_scan_iter_; + ObMdsNodeScanIterator node_scan_iter_; +}; + +} +} +} + +#ifndef STORAGE_MULTI_DATE_SOURCE_MDS_TABLE_HANDLE_H_IPP +#define STORAGE_MULTI_DATE_SOURCE_MDS_TABLE_HANDLE_H_IPP +#include "mds_table_handle.ipp" +#endif + +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_table_handle.ipp b/src/storage/multi_data_source/mds_table_handle.ipp new file mode 100644 index 000000000..50e45e850 --- /dev/null +++ b/src/storage/multi_data_source/mds_table_handle.ipp @@ -0,0 +1,883 @@ +/** + * Copyright (c) 2023 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 STORAGE_MULTI_DATE_SOURCE_MDS_TABLE_HANDLE_IPP +#define STORAGE_MULTI_DATE_SOURCE_MDS_TABLE_HANDLE_IPP + +#include "lib/ob_errno.h" +#ifndef STORAGE_MULTI_DATE_SOURCE_MDS_TABLE_HANDLE_H_IPP +#define STORAGE_MULTI_DATE_SOURCE_MDS_TABLE_HANDLE_H_IPP +#include "mds_table_handle.h" +#endif + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +#define CHECK_MDS_TABLE_INIT() \ +do {\ + if (!is_valid()) {\ + ret = OB_NOT_INIT;\ + MDS_LOG(ERROR, "MdsTableHandle is not init yet", KR(ret), K(*this));\ + return ret;\ + }\ +} while(0) + +template +struct MdsTableHandleHelper { + template + struct InnerInnerHelper { + template + static int get_unit_id(uint8_t &mds_unit_id) { + int ret = OB_SUCCESS; + using UnitType = typename TupleIdxType::type; + if (std::is_same::type>::value && + std::is_same::type>::value) { + mds_unit_id = IDX; + } else { + ret = get_unit_id(mds_unit_id); + } + return ret; + } + template <> + static int get_unit_id(uint8_t &mds_unit_id) { + int ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(ERROR, "type error, no this KV unit in this MdsTable", KR(ret), + K(typeid(MdsTableType).name()), K(typeid(K).name()), K(typeid(V).name()), + K(typeid(typename TupleIdxType::type::key_type).name()), + K(typeid(typename TupleIdxType::type::value_type).name())); + return ret; + } + }; + template + static int get_unit_id(const uint8_t mds_table_id, uint8_t &mds_unit_id) { + int ret = OB_SUCCESS; + if (IDX == mds_table_id) { + ret = InnerInnerHelper::type>:: + template get_unit_id<0>(mds_unit_id); + } else { + ret = get_unit_id(mds_table_id, mds_unit_id); + } + return ret; + } + template <> + static int get_unit_id(const uint8_t mds_table_id, + uint8_t &mds_unit_id) { + int ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(ERROR, "type error, no this MdsTable", KR(ret), K(mds_table_id), + K(typeid(K).name()), K(typeid(V).name())); + return ret; + } +}; + +inline bool MdsTableHandle::operator==(const MdsTableHandle &rhs) const +{ + return mds_table_id_ == rhs.mds_table_id_ && + p_mds_table_base_ == rhs.p_mds_table_base_; +} + +inline MdsTableHandle::~MdsTableHandle() +{ + MDS_LOG(DEBUG, "MdsTableHandle destructed", K_(mds_table_id), KPC_(p_mds_table_base_.ctrl_ptr)); + mds_table_id_ = UINT8_MAX; +} + +inline int MdsTableHandle::get_tablet_id(common::ObTabletID &tablet_id) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + if (!p_mds_table_base_.is_valid()) { + ret = OB_BAD_NULL_ERROR; + MDS_LOG(WARN, "p_mds_table_base_ is invalid", K(*this)); + } else { + tablet_id = p_mds_table_base_->get_tablet_id(); + } + return ret; +} + +inline int MdsTableHandle::get_ls_id(share::ObLSID &ls_id) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + if (!p_mds_table_base_.is_valid()) { + ret = OB_BAD_NULL_ERROR; + MDS_LOG(WARN, "p_mds_table_base_ is invalid", K(*this)); + } else { + ls_id = p_mds_table_base_->get_ls_id(); + } + return ret; +} + +template +int MdsTableHandle::init(ObIAllocator &allocator, + const ObTabletID tablet_id, + const share::ObLSID ls_id, + ObTabletPointer *pointer, + ObMdsTableMgr *p_mgr) +{ + int ret = OB_SUCCESS; + ObLightSharedPtr> p_mds_table; + if (TupleTypeIdx::value == MdsTableTypeTuple::get_element_size()) { + ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(WARN, "this MdsTableType not exist", K(typeid(MdsTableType).name())); + } else if (is_valid()) { + this->~MdsTableHandle(); + new (this) MdsTableHandle(); + MDS_LOG(WARN, "mds_table has been inited, reset and init again", KP(this), K(lbt())); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table.construct(allocator))) { + MDS_LOG(WARN, "construct mds table impl failed", KP(this), K(lbt())); + } else if (OB_FAIL(p_mds_table->init(tablet_id, ls_id, pointer, p_mgr))) { + MDS_LOG(WARN, "init mds table failed", KR(ret), K(mds_table_id_), + K(typeid(MdsTableType).name())); + } else { + p_mds_table_base_ = p_mds_table; + uint8_t tablet_id = TupleTypeIdx::value; + ATOMIC_STORE(&mds_table_id_, tablet_id); + } + } + return ret; +} + +template +int MdsTableHandle::set(T &&data, MdsCtx &ctx, const int64_t lock_timeout_us) +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + DummyKey dummy_key; + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->set(unit_id, + (void*)&dummy_key, + (void*)&data, + std::is_rvalue_reference::value, + ctx, + lock_timeout_us))) { + MDS_LOG(WARN, "fail to call set", KR(ret), K(unit_id), K(data), K(ctx), K(lock_timeout_us)); + } + } + return ret; +} + +template +int MdsTableHandle::replay(T &&data, MdsCtx &ctx, const share::SCN &scn) +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + DummyKey dummy_key; + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->replay(unit_id, + (void*)&dummy_key, + (void*)&data, + std::is_rvalue_reference::value, + ctx, + scn))) { + MDS_LOG(WARN, "fail to call replay", KR(ret), K(unit_id), K(data), K(ctx), K(scn)); + } + } + return ret; +} + +template ::type> +int MdsTableHandle::get_latest(OP &&read_op, bool &is_committed, const int64_t read_seq) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + DummyKey dummy_key; + ObFunction function = [&read_op](void *data) -> int { + return read_op(*reinterpret_cast(data)); + }; + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->get_latest(unit_id, + (void*)&dummy_key, + function, + is_committed, + read_seq))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG(WARN, "fail to call get_latest", KR(ret), K(unit_id), K(read_seq)); + } + } + } + return ret; +} + +template ::type> +int MdsTableHandle::get_snapshot(OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + DummyKey dummy_key; + ObFunction function = [&read_op](void *data) -> int { + return read_op(*reinterpret_cast(data)); + }; + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->get_snapshot(unit_id, + (void*)&dummy_key, + function, + snapshot, + read_seq, + timeout_us))) { + if (OB_SNAPSHOT_DISCARDED != ret) { + MDS_LOG(WARN, "fail to call get_snapshot", KR(ret), K(unit_id), K(snapshot), + K(read_seq), K(timeout_us)); + } + } + } + return ret; +} + +template ::type> +int MdsTableHandle::get_by_writer(OP &&read_op, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + DummyKey dummy_key; + ObFunction function = [&read_op](void *data) -> int { + return read_op(*reinterpret_cast(data)); + }; + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->get_by_writer(unit_id, + (void*)&dummy_key, + function, + writer, + snapshot, + read_seq, + timeout_us))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG(WARN, "fail to call get_by_writer", KR(ret), K(unit_id), K(writer), + K(snapshot), K(read_seq), K(timeout_us)); + } + } + } + return ret; +} + +template +int MdsTableHandle::is_locked_by_others(bool &is_locked, const MdsWriter &self) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + DummyKey dummy_key; + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->is_locked_by_others(unit_id, + (void*)&dummy_key, + is_locked, + self))) { + MDS_LOG(WARN, "fail to call is_locked_by_others", KR(ret), K(unit_id), K(is_locked), + K(self)); + } + } + return ret; +} +/**************************************************************************************************/ + +/******************************Multi Key Unit Access Interface*************************************/ +template +int MdsTableHandle::set(const Key &key, Value &&data, MdsCtx &ctx, const int64_t lock_timeout_us) +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->set(unit_id, + (void*)&key, + (void*)&data, + std::is_rvalue_reference::value, + ctx, + lock_timeout_us))) { + MDS_LOG(WARN, "fail to call set", KR(ret), K(unit_id), K(key), K(data), K(ctx), + K(lock_timeout_us)); + } + } + return ret; +} + +template +int MdsTableHandle::replay(const Key &key, Value &&data, MdsCtx &ctx, const share::SCN &scn) +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->replay(unit_id, + (void*)&key, + (void*)&data, + std::is_rvalue_reference::value, + ctx, + scn))) { + MDS_LOG(WARN, "fail to call replay", KR(ret), K(unit_id), K(key), K(data), K(ctx), K(scn)); + } + } + return ret; +} + +template +int MdsTableHandle::remove(const Key &key, MdsCtx &ctx, const int64_t lock_timeout_us) +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->remove(unit_id, + (void*)&key, + ctx, + lock_timeout_us))) { + MDS_LOG(WARN, "fail to call remove", KR(ret), K(unit_id), K(key), K(ctx), + K(lock_timeout_us)); + } + } + return ret; +} + +template +int MdsTableHandle::replay_remove(const Key &key, MdsCtx &ctx, share::SCN &scn) +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->replay_remove(unit_id, + (void*)&key, + ctx, + scn))) { + MDS_LOG(WARN, "fail to call replay_remove", KR(ret), K(unit_id), K(key), K(ctx), K(scn)); + } + } + return ret; +} + +template +int MdsTableHandle::get_latest(const Key &key, + OP &&read_op, + bool &is_committed, + const int64_t read_seq) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + ObFunction function = [&read_op](void *data) -> int { + return read_op(*reinterpret_cast(data)); + }; + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->get_latest(unit_id, + (void*)&key, + function, + is_committed, + read_seq))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG(WARN, "fail to call get_latest", KR(ret), K(unit_id), K(key), K(read_seq)); + } + } + } + return ret; +} + +template +int MdsTableHandle::get_snapshot(const Key &key, + OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + ObFunction function = [&read_op](void *data) -> int { + return read_op(*reinterpret_cast(data)); + }; + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->get_snapshot(unit_id, + (void*)&key, + function, + snapshot, + read_seq, + timeout_us))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG(WARN, "fail to call get_snapshot", KR(ret), K(unit_id), K(key), K(snapshot), + K(read_seq), K(timeout_us)); + } + } + } + return ret; +} + +template +int MdsTableHandle::get_by_writer(const Key &key, + OP &&read_op, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + ObFunction function = [&read_op](void *data) -> int { + return read_op(*reinterpret_cast(data)); + }; + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->get_by_writer(unit_id, + (void*)&key, + function, + writer, + snapshot, + read_seq, + timeout_us))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG(WARN, "fail to call get_by_writer", KR(ret), K(unit_id), K(key), K(writer), + K(snapshot), K(read_seq), K(timeout_us)); + } + } + } + return ret; +} + +template +int MdsTableHandle::is_locked_by_others(const Key &key, + bool &is_locked, + const MdsWriter &self) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + uint8_t unit_id = INT8_MAX; + ret = MdsTableHandleHelper::template get_unit_id<0>(mds_table_id_, unit_id); + if (OB_SUCC(ret)) { + if (OB_FAIL(p_mds_table_base_->is_locked_by_others(unit_id, + (void*)&key, + is_locked, + self))) { + MDS_LOG(WARN, "fail to call is_locked_by_others", KR(ret), K(unit_id), K(key), K(is_locked), + K(self)); + } + } + return ret; +} + +template ::type> +int MdsTableHandle::for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump(DUMP_OP &&for_each_op, + const bool for_flush) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + ObFunction op = [&for_each_op](const MdsDumpKV &kv) -> int { + return for_each_op(kv); + }; + if (OB_FAIL(p_mds_table_base_-> + for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump(op, for_flush))) { + MDS_LOG(WARN, "fail to do for_each dump op", KR(ret), K(*this)); + } + return ret; +} + +inline int MdsTableHandle::flush(share::SCN recycle_scn, bool need_freeze) +{ + int ret = OB_SUCCESS; + // return ret;// FIXME: for lixia test, will block CLOG recycle +#ifndef TEST_MDS_TRANSACTION + CHECK_MDS_TABLE_INIT(); + ret = p_mds_table_base_->flush(recycle_scn, need_freeze); +#endif + return ret; +} + +inline int MdsTableHandle::is_flushing(bool &is_flushing) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + is_flushing = p_mds_table_base_->is_flushing(); + return ret; +} + +inline void MdsTableHandle::on_flush(const share::SCN &flush_scn, const int flush_ret) +{ + if (!is_valid()) { + MDS_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "can not do on_flush, cause this handle is invalid", K(*this)); + } else { + p_mds_table_base_->on_flush(flush_scn, flush_ret); + } +} + +inline int MdsTableHandle::get_rec_scn(share::SCN &rec_scn) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + rec_scn = p_mds_table_base_->get_rec_scn(); + return ret; +} + +inline int MdsTableHandle::get_node_cnt(int64_t &valid_cnt) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + valid_cnt = p_mds_table_base_->get_node_cnt(); + return ret; +} + +inline bool MdsTableHandle::is_valid() const +{ + uint8_t mds_table_id = ATOMIC_LOAD(&mds_table_id_); + return mds_table_id >= 0 && mds_table_id < MdsTableTypeTuple::get_element_size(); +} + +inline void MdsTableHandle::reset() +{ + this->~MdsTableHandle(); +} + +inline int MdsTableHandle::try_recycle(const share::SCN &recycle_scn)// release nodes +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + return p_mds_table_base_->try_recycle(recycle_scn); +} + +inline int MdsTableHandle::sync_ref_until_last() const +{ + #define PRINT_WRAPPER KR(ret), K(*this) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (!p_mds_table_base_.is_valid()) { + ret = OB_NOT_INIT; + MDS_LOG_GC(ERROR, "this is an invalid handle", K(*this)); + } else if (MDS_FAIL(p_mds_table_base_.sync_until_last())) { + MDS_LOG_GC(WARN, "fail to sync ref", K(*this)); + } + return ret; + #undef PRINT_WRAPPER +} + +inline int MdsTableHandle::get_ref_cnt(int64_t &ref_cnt) const +{ + #define PRINT_WRAPPER KR(ret), K(*this) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (!p_mds_table_base_.is_valid()) { + ret = OB_NOT_INIT; + MDS_LOG_GC(ERROR, "this is an invalid handle", K(*this)); + } else if (MDS_FAIL(p_mds_table_base_.get_ref_cnt(ref_cnt))) { + MDS_LOG_GC(WARN, "fail to get ref cnt", K(*this)); + } + return ret; + #undef PRINT_WRAPPER +} + +template +struct MdsTableUnitConvertHelper { + template + struct InnerInnerHelper { + template + static int get_unit(MdsTableBase *p_mds_table, MdsUnit *&p_mds_unit) { + int ret = OB_SUCCESS; + using UnitType = typename TupleIdxType::type; + if (std::is_same::type>::value && + std::is_same::type>::value) { + p_mds_unit = (MdsUnit *)&(static_cast *>(p_mds_table)->unit_tuple().template element()); + } else { + ret = get_unit(p_mds_table, p_mds_unit); + } + return ret; + } + template <> + static int get_unit(MdsTableBase *p_mds_table, + MdsUnit *&p_mds_unit) { + int ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(ERROR, "type error, no this KV unit in this MdsTable", KR(ret), + K(typeid(MdsTableType).name()), K(typeid(K).name()), K(typeid(V).name()), + K(typeid(typename TupleIdxType::type::key_type).name()), + K(typeid(typename TupleIdxType::type::value_type).name())); + return ret; + } + }; + template + static int get_unit(const uint8_t mds_table_id, + MdsTableBase *p_mds_table, + MdsUnit *&p_mds_unit) { + int ret = OB_SUCCESS; + if (IDX == mds_table_id) { + ret = InnerInnerHelper::type>:: + template get_unit<0>(p_mds_table, p_mds_unit); + } else { + ret = get_unit(mds_table_id, p_mds_table, p_mds_unit); + } + return ret; + } + template <> + static int get_unit(const uint8_t mds_table_id, + MdsTableBase *p_mds_table, + MdsUnit *&p_mds_unit) { + int ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(ERROR, "type error, no this MdsTable", KR(ret), K(mds_table_id), + K(typeid(K).name()), K(typeid(V).name())); + return ret; + } +}; +template +int MdsTableHandle::get_mds_unit(MdsUnit *&p_mds_unit) +{ + int ret = OB_SUCCESS; + p_mds_unit = nullptr; + if (!p_mds_table_base_.is_valid()) { + ret = OB_NOT_INIT; + MDS_LOG(ERROR, "this is an invalid handle", K(*this)); + } else if (OB_SUCCESS != (ret = (MdsTableUnitConvertHelper:: + template get_unit<0>(mds_table_id_, + get_mds_table_ptr(), + p_mds_unit)))) { + MDS_LOG(WARN, "fail to get mds unit", K(*this)); + } + return ret; +} + +inline int MdsTableHandle::fill_virtual_info(ObIArray &mds_node_info_array) const +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + if (!p_mds_table_base_.is_valid()) { + ret = OB_BAD_NULL_ERROR; + MDS_LOG(WARN, "p_mds_table_base_ is invalid", K(*this)); + } else if (OB_FAIL(p_mds_table_base_->fill_virtual_info(mds_node_info_array))) { + MDS_LOG(WARN, "fail to fill virtual info", K(*this)); + } + return ret; +} + +inline int MdsTableHandle::mark_removed_from_t3m(ObTabletPointer *pointer) +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + if (!p_mds_table_base_.is_valid()) { + ret = OB_BAD_NULL_ERROR; + MDS_LOG(WARN, "p_mds_table_base_ is invalid", K(*this)); + } else { + p_mds_table_base_->mark_removed_from_t3m(pointer); + } + return ret; +} + +template +inline int MdsTableHandle::forcely_release_all_mds_nodes(const char (&reason)[N]) +{ + int ret = OB_SUCCESS; + CHECK_MDS_TABLE_INIT(); + if (!p_mds_table_base_.is_valid()) { + ret = OB_BAD_NULL_ERROR; + MDS_LOG(WARN, "p_mds_table_base_ is invalid", K(*this)); + } else { + p_mds_table_base_->forcely_release_all_mds_nodes(reason); + } + return ret; +} + +template +ObMdsKvRowScanIterator::ObMdsKvRowScanIterator() +: is_inited_(false), +is_first_scan_(false), +p_mds_unit_(nullptr) {} + +template +int ObMdsKvRowScanIterator::init(mds::MdsTableHandle &mds_table_handle) { + #define PRINT_WRAPPER KR(ret), K(mds_table_handle), K(typeid(UnitKey).name()),\ + K(typeid(UnitValue).name()) + int ret = OB_SUCCESS; + if (is_inited_) { + ret = OB_INIT_TWICE; + MDS_LOG_NONE(WARN, "ObMdsKvRowScanIterator init twice"); + } else if (!mds_table_handle.is_valid()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG_NONE(WARN, "try iterate invalid mds table"); + } else if (OB_FAIL(mds_table_handle.get_mds_unit(p_mds_unit_))) { + MDS_LOG_NONE(WARN, "fail to find unit in this mds table"); + } else { + construct_lock_guard(unit_guard_, p_mds_unit_->lock_);// lock unit to make sure get kv_row safe + is_inited_ = true; + is_first_scan_ = true; + } + return ret; + #undef PRINT_WRAPPER +} + +template +int ObMdsKvRowScanIterator::get_next_kv_row(KvRow *&p_kv_row) { + #define PRINT_WRAPPER KR(ret), K(*this) + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + MDS_LOG_NONE(WARN, "ObMdsKvRowScanIterator not init"); + } else if (is_first_scan_) { + is_first_scan_ = false; + kv_row_iter_ = p_mds_unit_->begin(); + } + if (OB_SUCC(ret)) { + if (kv_row_iter_ == p_mds_unit_->end()) { + ret = OB_ITER_END; + } else { + p_kv_row = &(*(kv_row_iter_++)); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template +ObMdsNodeScanIterator::ObMdsNodeScanIterator() +: is_inited_(false), +is_first_scan_(true), +p_mds_kv_row_(nullptr) {} + +template +int ObMdsNodeScanIterator::init(KvRow *&p_kv_row) { + #define PRINT_WRAPPER KR(ret), K(*this), KP(p_kv_row) + int ret = OB_SUCCESS; + if (is_inited_) { + ret = OB_INIT_TWICE; + MDS_LOG_NONE(WARN, "ObMdsNodeScanIterator init twice"); + } else if (OB_ISNULL(p_kv_row)) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG_NONE(WARN, "p_kv_row is NULL"); + } else { + p_mds_kv_row_ = p_kv_row; + construct_lock_guard(row_guard_, p_mds_kv_row_->v_.lock_);// lock unit to make sure get kv_row safe + is_inited_ = true; + is_first_scan_ = true; + } + return ret; + #undef PRINT_WRAPPER +} + +template +int ObMdsNodeScanIterator::get_next_kv_node(UnitKey &key, mds::UserMdsNode *&p_node) { + #define PRINT_WRAPPER KR(ret), K(*this) + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + MDS_LOG_NONE(WARN, "ObMdsNodeScanIterator not init"); + } else if (is_first_scan_) { + is_first_scan_ = false; + node_iter_ = p_mds_kv_row_->v_.begin(); + } + if (OB_SUCC(ret)) { + if (node_iter_ == p_mds_kv_row_->v_.end()) { + ret = OB_ITER_END; + } else { + key = p_mds_kv_row_->k_; + p_node = &(*node_iter_++); + MDS_LOG_NONE(TRACE, "scan node", K(*p_node)); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template +bool ObMdsNodeScanIterator::is_valid() const { return is_inited_; } + +template +void ObMdsNodeScanIterator::reset() { + this->~ObMdsNodeScanIterator(); + new (this) ObMdsNodeScanIterator(); +} + +template +ObMdsUnitRowNodeScanIterator::ObMdsUnitRowNodeScanIterator() +: is_inited_(false), +is_first_scan_(true) {} + +template +int ObMdsUnitRowNodeScanIterator::init(mds::MdsTableHandle &mds_table_handle) { + #define PRINT_WRAPPER KR(ret), K(*this), K(mds_table_handle) + int ret = OB_SUCCESS; + if (is_inited_) { + ret = OB_INIT_TWICE; + MDS_LOG_NONE(WARN, "ObMdsUnitRowNodeScanIterator init twice"); + } else if (!mds_table_handle.is_valid()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG_NONE(WARN, "mds_table_handle invalid"); + } else { + mds_table_handle_ = mds_table_handle; + is_inited_ = true; + is_first_scan_ = true; + } + return ret; + #undef PRINT_WRAPPER +} + +template +int ObMdsUnitRowNodeScanIterator::get_next(UnitKey &key, mds::UserMdsNode *&p_node) { + #define PRINT_WRAPPER KR(ret), K(*this) + int ret = OB_SUCCESS; + bool node_meet_end = false; + bool row_mmet_end = false; + if (!is_inited_) { + ret = OB_NOT_INIT; + MDS_LOG_NONE(WARN, "ObMdsUnitRowNodeScanIterator not init"); + } else if (is_first_scan_) { + is_first_scan_ = false; + if (OB_FAIL(row_scan_iter_.init(mds_table_handle_))) { + MDS_LOG_NONE(WARN, "fail to init row_scan_iter_"); + } + } + while (OB_SUCC(ret) && + (!node_scan_iter_.is_valid() || // first time to scan + OB_ITER_END == (ret = node_scan_iter_.get_next_kv_node(key, p_node)))) {// every time scan row end + node_scan_iter_.reset(); + KvRow *p_kv_row = nullptr; + if (OB_FAIL(row_scan_iter_.get_next_kv_row(p_kv_row))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + MDS_LOG_NONE(WARN, "fail to get kv row"); + } + } else if (OB_FAIL(node_scan_iter_.init(p_kv_row))) { + MDS_LOG_NONE(WARN, "fail to init node_scan_iter_"); + } + } + return ret; + #undef PRINT_WRAPPER +} + +} +} +} +#undef CHECK_MDS_TABLE_INIT +#endif diff --git a/src/storage/multi_data_source/mds_table_handler.cpp b/src/storage/multi_data_source/mds_table_handler.cpp new file mode 100644 index 000000000..76aea2b27 --- /dev/null +++ b/src/storage/multi_data_source/mds_table_handler.cpp @@ -0,0 +1,187 @@ +#include "mds_table_handler.h" +#include "lib/lock/ob_small_spin_lock.h" +#include "lib/ob_errno.h" +#include "mds_table_mgr.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/meta_mem/ob_tablet_pointer.h" + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +ObMdsTableHandler::~ObMdsTableHandler() { ATOMIC_STORE(&is_written_, false); } + +int ObMdsTableHandler::get_mds_table_handle(mds::MdsTableHandle &handle, + const ObTabletID &tablet_id, + const share::ObLSID &ls_id, + const bool not_exist_create, + ObTabletPointer *pointer) +{ + #define PRINT_WRAPPER KR(ret), K(tablet_id), K(ls_id), K(not_exist_create), K(*this) + int ret = OB_SUCCESS; + ObLSService *ls_service = MTL(storage::ObLSService *); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + mds::ObMdsTableMgr *mds_table_mgr; + + auto try_get_handle_directly = [this](mds::MdsTableHandle &handle) -> void { + if (OB_LIKELY(mds_table_handle_.is_valid())) { + handle = mds_table_handle_; + } + }; + + handle.reset(); + MDS_TG(5_ms); + { + MdsRLockGuard guard(lock_); + CLICK(); + try_get_handle_directly(handle); + } + + if (OB_LIKELY(handle.is_valid())) { + // do nothing + } else if (OB_LIKELY(!handle.is_valid() && !not_exist_create)) {// mds_table is released and no need create new one + ret = OB_ENTRY_NOT_EXIST; + } else {// mds_table is released and need create new one + MdsWLockGuard guard(lock_); + try_get_handle_directly(handle);// try again(check if mds_table created between Rlock and Wlock) + if (OB_UNLIKELY(handle.is_valid())) { + // do nothing + } else { + if (OB_ISNULL(mds_table_mgr_handle_.get_mds_table_mgr())) { + if (OB_ISNULL(ls_service)) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_INIT(WARN, "ls service should not be NULL"); + } else if (MDS_FAIL(ls_service->get_ls(ls_id, + ls_handle, + ObLSGetMod::TABLET_MOD))) { + MDS_LOG_INIT(WARN, "failed to get ls"); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_INIT(WARN, "ls should not be NULL"); + } else if (MDS_FAIL(ls->get_tablet_svr()->get_mds_table_mgr(mds_table_mgr_handle_))) { + MDS_LOG_INIT(WARN, "get mds table mgr failed"); + } else if (OB_ISNULL(mds_table_mgr = mds_table_mgr_handle_.get_mds_table_mgr())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_INIT(ERROR, "mds table mgr is unexpected nullptr"); + } + } + if (OB_SUCC(ret)) { + set_mds_mem_check_thread_local_info(ls_id, tablet_id, typeid(mds::NormalMdsTable).name()); + if (MDS_FAIL(mds_table_handle_.init(mds::MdsAllocator::get_instance(), + tablet_id, + ls_id, + pointer, + mds_table_mgr_handle_.get_mds_table_mgr()))) { + MDS_LOG_INIT(WARN, "fail to init mds table"); + } else { + handle = mds_table_handle_; + } + reset_mds_mem_check_thread_local_info(); + } + } + } + return ret; + #undef PRINT_WRAPPER +} + +int ObMdsTableHandler::try_gc_mds_table() +{ + #define PRINT_WRAPPER KR(ret), K(valid_node_cnt), K(*this) + MDS_TG(100_ms); + int ret = OB_SUCCESS; + int64_t valid_node_cnt = 0; + bool is_flushing = false; + if (!mds_table_handle_.is_valid()) { + // do nothing + } else if (MDS_FAIL(mds_table_handle_.get_node_cnt(valid_node_cnt))) {// 1. check if count is 0 + MDS_LOG_GC(WARN, "fail to get total valid node cnt"); + } else if (0 != valid_node_cnt) { + ret = OB_EAGAIN; + MDS_LOG_GC(DEBUG, "there are valid nodes remains, maybe later"); + } else if (OB_FAIL(mds_table_handle_.is_flushing(is_flushing))) {// 2. check if is in flushing process + MDS_LOG_GC(WARN, "fail to get mds_table flushing state"); + } else if (is_flushing) { + ret = OB_EAGAIN; + MDS_LOG_GC(INFO, "this mds_table is in flushing state, waiting for DAG on_flush() callback"); + } else { + MdsWLockGuard guard(lock_);// 3. stop incoming incremental accessing to mds_table_handle(there are some stock accessing remain still) + CLICK(); + if (mds_table_handle_.is_valid()) { + int64_t handle_ref_cnt = 0; + if (MDS_FAIL(mds_table_handle_.get_ref_cnt(handle_ref_cnt))) {// 4. check if this is the last ref + MDS_LOG_GC(WARN, "fail to gc mds_table"); + } else if (handle_ref_cnt != 1) { + MDS_LOG_GC(INFO, "althrough valid node cnt is 0, but ref cnt is not 0, wait next scan", K(handle_ref_cnt)); + } else if (MDS_FAIL(mds_table_handle_.get_node_cnt(valid_node_cnt))) { + MDS_LOG_GC(WARN, "fail to get total valid node cnt"); + } else if (0 != valid_node_cnt) {// 5. double check to see if stock accessing write new nodes + ret = OB_EAGAIN; + MDS_LOG_GC(DEBUG, "there are valid nodes(by concurrent insert), maybe later"); + } else { + MDS_LOG_GC(INFO, "success to gc mds_table"); + mds_table_handle_.reset();// 6. release the last ref, will do actual destruction and free here + } + } + } + return ret; + #undef PRINT_WRAPPER +} + +int ObMdsTableHandler::try_release_nodes_below(const share::SCN &scn) +{ + #define PRINT_WRAPPER KR(ret), K(scn), K(*this) + int ret = OB_SUCCESS; + MDS_TG(5_ms); + MdsTableHandle mds_table_handle; + { + MdsWLockGuard guard(lock_); + CLICK(); + mds_table_handle = mds_table_handle_; + } + if (mds_table_handle.is_valid()) { + if (MDS_FAIL(mds_table_handle.try_recycle(scn))) { + MDS_LOG_GC(WARN, "fail to try recycle"); + } + } + return ret; + #undef PRINT_WRAPPER +} + +ObMdsTableHandler &ObMdsTableHandler::operator=(const ObMdsTableHandler &rhs)// value sematic for tablet ponter deep copy +{ + #define PRINT_WRAPPER KR(ret), K(*this) + int ret = OB_SUCCESS; + + MDS_TG(5_ms); + MdsWLockGuard guard(lock_); + CLICK(); + ATOMIC_STORE(&is_written_, ATOMIC_LOAD(&rhs.is_written_)); + mds_table_handle_ = rhs.mds_table_handle_; + if (OB_NOT_NULL(rhs.mds_table_mgr_handle_.get_mds_table_mgr())) { + mds_table_mgr_handle_.set_mds_table_mgr(const_cast(rhs.mds_table_mgr_handle_.get_mds_table_mgr())); + } + return *this; + #undef PRINT_WRAPPER +} + +void ObMdsTableHandler::mark_removed_from_t3m(ObTabletPointer *pointer) +{ + int ret = OB_SUCCESS; + MdsWLockGuard guard(lock_); + if (mds_table_handle_.is_valid()) { + if (OB_FAIL(mds_table_handle_.mark_removed_from_t3m(pointer))) { + MDS_LOG(WARN, "fail to unregister_from_mds_table_mgr", K(*this)); + } + } +} + +} +} +} \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_table_handler.h b/src/storage/multi_data_source/mds_table_handler.h new file mode 100644 index 000000000..69e22379b --- /dev/null +++ b/src/storage/multi_data_source/mds_table_handler.h @@ -0,0 +1,44 @@ +#ifndef SRC_STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_HANDLER_H +#define SRC_STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_HANDLER_H +#include "lib/lock/ob_small_spin_lock.h" +#include "mds_table_handle.h" +#include "mds_table_mgr.h" + +namespace oceanbase +{ +namespace storage +{ +class ObTabletPointer; +namespace mds +{ + +class ObMdsTableHandler +{ +public: + ObMdsTableHandler() : is_written_(false) {} + ~ObMdsTableHandler(); + ObMdsTableHandler(const ObMdsTableHandler &) = delete; + ObMdsTableHandler &operator=(const ObMdsTableHandler &);// value sematic for tablet ponter deep copy + int get_mds_table_handle(mds::MdsTableHandle &handle, + const ObTabletID &tablet_id, + const share::ObLSID &ls_id, + const bool not_exist_create, + ObTabletPointer *pointer); + int try_gc_mds_table(); + int try_release_nodes_below(const share::SCN &scn); + void reset() { this->~ObMdsTableHandler(); } + void set_mds_written() { ATOMIC_CAS(&(is_written_), false, true); } + void mark_removed_from_t3m(ObTabletPointer *pointer); + bool is_mds_written() const { return ATOMIC_LOAD(&(is_written_)); } + TO_STRING_KV(K_(mds_table_handle)); +private: + MdsTableMgrHandle mds_table_mgr_handle_;// mgr handle destroy after table handle destroy + MdsTableHandle mds_table_handle_;// primary handle, all other handles are copied from this one + bool is_written_; + mutable MdsLock lock_; +}; + +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_table_impl.h b/src/storage/multi_data_source/mds_table_impl.h new file mode 100644 index 000000000..dd993edf1 --- /dev/null +++ b/src/storage/multi_data_source/mds_table_impl.h @@ -0,0 +1,282 @@ +/** + * Copyright (c) 2023 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 STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_IMPL_H +#define STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_IMPL_H + +#include "lib/lock/ob_small_spin_lock.h" +#include "storage/multi_data_source/compile_utility/mds_dummy_key.h" +#include "storage/multi_data_source/runtime_utility/common_define.h" +#include "mds_unit.h" +#include "lib/lock/ob_spin_lock.h" +#include "lib/ob_define.h" +#include "lib/utility/ob_macro_utils.h" +#include "lib/utility/utility.h" +#include "ob_clock_generator.h" +#include "ob_tablet_id.h" +#include "share/ob_errno.h" +#include "share/scn.h" +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#include "lib/ob_errno.h" +#include "mds_ctx.h" +#include "mds_node.h" +#include "lib/utility/ob_print_utils.h" +#include "adapter_define/mds_dump_node.h" +#include "mds_writer.h" +#include "common/ob_tablet_id.h" +#include "share/ob_ls_id.h" +#include "mds_table_base.h" +#include "compile_utility/map_type_index_in_tuple.h" +#include "storage/multi_data_source/compile_utility/compile_mapper.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +class MdsDumpNode; +class MdsTableHandle; + +typedef DropFirstElemtTuple +#include "compile_utility/mds_register.h" +#undef _GENERATE_MDS_UNIT_ +#undef GENERATE_TEST_MDS_TABLE +>::type UnitTestMdsTable; + +typedef DropFirstElemtTuple +#include "compile_utility/mds_register.h" +#undef _GENERATE_MDS_UNIT_ +#undef GENERATE_NORMAL_MDS_TABLE +>::type NormalMdsTable; + +typedef DropFirstElemtTuple +#include "compile_utility/mds_register.h" +#undef _GENERATE_MDS_UNIT_ +#undef GENERATE_LS_INNER_MDS_TABLE +>::type LsInnerMdsTable; + +typedef ObTuple MdsTableTypeTuple; + +template +struct GET_MDS_TABLE_ID { + static constexpr uint8_t value = MdsTableTypeTuple::get_element_index(); +}; + +template +struct GET_MDS_UNIT_ID { + static constexpr uint8_t value = MdsTableType::template get_element_index>(); +}; + +template +class MdsTableImpl final : public MdsTableBase +{ + friend class MdsDumpNode; + friend class MdsTableHandle; +public: + MdsTableImpl(); + virtual ~MdsTableImpl() override; + virtual int set(int64_t unit_id, + void *key, + void *data, + bool is_rvalue, + MdsCtx &ctx, + const int64_t lock_timeout_us) override; + virtual int replay(int64_t unit_id, + void *key, + void *data, + bool is_rvalue, + MdsCtx &ctx, + const share::SCN &scn) override; + virtual int remove(int64_t unit_id, + void *key, + MdsCtx &ctx, + const int64_t lock_timeout_us) override; + virtual int replay_remove(int64_t unit_id, + void *key, + MdsCtx &ctx, + const share::SCN &scn) override; + virtual int get_latest(int64_t unit_id, + void *key, + ObFunction &op, + bool &is_committed, + const int64_t read_seq) const override; + virtual int get_snapshot(int64_t unit_id, + void *key, + ObFunction &op, + const share::SCN &snapshot, + const int64_t read_seq, + const int64_t timeout_us) const override; + virtual int get_by_writer(int64_t unit_id, + void *key, + ObFunction &op, + const MdsWriter &writer, + const share::SCN &snapshot, + const int64_t read_seq, + const int64_t timeout_us) const override; + virtual int is_locked_by_others(int64_t unit_id, + void *key, + bool &is_locked, + const MdsWriter &self = MdsWriter()) const override; + virtual int for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump( + ObFunction &for_each_op, + const bool for_flush) const override; + virtual int flush(share::SCN recycle_scn, bool need_freeze) override; + virtual void on_flush(const share::SCN &flush_scn, const int flush_ret) override; + void on_flush_(const share::SCN &flush_scn, const int flush_ret); + virtual int try_recycle(const share::SCN recycle_scn) override; + virtual int fill_virtual_info(ObIArray &mds_node_info_array) const override { + ForEachUnitFillVirtualInfoHelper helper(mds_node_info_array); + return unit_tuple_.for_each(helper); + } + virtual int forcely_release_all_mds_nodes(const char *reason) override; + /*****************************Single Key Unit Access Interface***********************************/ + template + int set(T &&data, + MdsCtx &ctx, + const int64_t lock_timeout_us = 0); + template + int replay(T &&data, + MdsCtx &ctx, + const share::SCN &scn); + template + int get_latest(OP &&read_op, + bool &is_committed, + const int64_t read_seq = 0) const; + template + int get_snapshot(OP &&read_op, + const share::SCN snapshot = share::SCN::max_scn(), + const int64_t read_seq = 0, + const int64_t timeout_us = 0) const; + template + int get_by_writer(OP &&read_op, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq = 0, + const int64_t timeout_us = 0) const; + template + int is_locked_by_others(bool &is_locked, const MdsWriter &self = MdsWriter()) const; + /************************************************************************************************/ + + /******************************Multi Key Unit Access Interface***********************************/ + template + int set(const Key &key, + Value &&data, + MdsCtx &ctx, + const int64_t lock_timeout_us = 0); + template + int replay(const Key &key, + Value &&data, + MdsCtx &ctx, + const share::SCN &scn); + template + int remove(const Key &key, + MdsCtx &ctx, + const int64_t lock_timeout_us = 0); + template + int replay_remove(const Key &key, + MdsCtx &ctx, + const share::SCN &scn); + template + int get_latest(const Key &key, + OP &&read_op, + bool &is_committed, + const int64_t read_seq = 0) const; + template + int get_snapshot(const Key &key, + OP &&read_op, + const share::SCN snapshot = share::SCN::max_scn(), + const int64_t read_seq = 0, + const int64_t timeout_us = 0) const; + template + int get_by_writer(const Key &key, + OP &&read_op, + const MdsWriter &writer, + const share::SCN snapshot = share::SCN::max_scn(), + const int64_t read_seq = 0, + const int64_t timeout_us = 0) const; + template + int is_locked_by_others(const Key &key, + bool &is_locked, + const MdsWriter &self = MdsWriter()) const; + /************************************************************************************************/ + template + int for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump(DUMP_OP &&for_each_op, const bool for_flush); + TO_STRING_KV(KP(this), K_(ls_id), K_(tablet_id), K_(flushing_scn), K_(last_flushed_scn), + K_(rec_scn), K_(last_inner_recycled_scn), K_(total_node_cnt), K_(debug_info)); + // template + // int for_each_scan_node(SCAN_OP &&op); + template + int for_each_scan_row(SCAN_OP &&op); + MdsTableType &unit_tuple() { return unit_tuple_; } +private:// helper define + struct ForEachUnitFillVirtualInfoHelper { + ForEachUnitFillVirtualInfoHelper(ObIArray &array) : array_(array), idx_(0) {} + template + int operator()(const MdsUnit &unit) { + return unit.fill_virtual_info(array_, idx_++); + } + private: + ObIArray &array_; + int64_t idx_; + }; + template + struct ForEachUnitDumpHelper {// this operator applied on all row in units + ForEachUnitDumpHelper(DUMP_OP &op, share::SCN flusing_scn, bool for_flush) + : op_(op), + flusing_scn_(flusing_scn), + for_flush_(for_flush) {} + template + int operator()(MdsUnit &unit) { + uint8_t mds_table_id = GET_MDS_TABLE_ID::value; + uint8_t mds_unit_id = GET_MDS_UNIT_ID::value; + return unit.scan_KV_row(op_, flusing_scn_, mds_table_id, mds_unit_id, for_flush_); + } + private: + DUMP_OP &op_; + share::SCN flusing_scn_; + bool for_flush_; + }; + template + struct ForEachUnitScanRowHelper { + ForEachUnitScanRowHelper(SCAN_OP &op) : op_(op) {} + template + int operator()(MdsUnit &unit) { return unit.for_each_row(op_); } + private: + SCAN_OP &op_; + }; + template + int for_each_to_dump_node_(DUMP_OP &&op, share::SCN &flushing_scn, const bool for_flush) { + ForEachUnitDumpHelper for_each_op(op, flushing_scn, for_flush); + return unit_tuple_.for_each(for_each_op); + } + MdsTableType unit_tuple_; +}; + +} +} +} + +#ifndef STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_IMPL_H_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_IMPL_H_IPP +#include "mds_table_impl.ipp" +#endif + +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_table_impl.ipp b/src/storage/multi_data_source/mds_table_impl.ipp new file mode 100644 index 000000000..77b0c5c18 --- /dev/null +++ b/src/storage/multi_data_source/mds_table_impl.ipp @@ -0,0 +1,1456 @@ +/** + * Copyright (c) 2023 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 STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_IMPL_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_IMPL_IPP + +#include "storage/multi_data_source/mds_table_base.h" +#ifndef STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_IMPL_H_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_IMPL_H_IPP +#include "mds_table_impl.h" +#endif + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +#define MDS_ELEMENT(K, V) const_cast(unit_tuple_).\ + template element::type>>() + +template +struct InitHelper { + InitHelper(MdsTableBase *p_mds_table) : p_mds_table_(p_mds_table) {} + template + struct InnerHelper { + void operator()(MdsUnit &mds_unit, MdsTableBase *p_mds_table) { + mds_unit.p_mds_table_ = p_mds_table; + mds_unit.unit_id_ = TupleTypeIdx>::value; + } + }; + template + struct InnerHelper {// this is for single unit logic + void operator()(MdsUnit &mds_unit, MdsTableBase *p_mds_table) { + mds_unit.p_mds_table_ = p_mds_table; + mds_unit.unit_id_ = TupleTypeIdx>::value; + } + }; + template + int operator()(MdsUnit &mds_unit) { + InnerHelper inner_helper; + inner_helper(mds_unit, p_mds_table_); + return OB_SUCCESS; + } + MdsTableBase *p_mds_table_; +}; +template +MdsTableImpl::MdsTableImpl() : MdsTableBase::MdsTableBase() +{ + InitHelper helper(this); + unit_tuple_.for_each(helper); +} + +template +MdsTableImpl::~MdsTableImpl() { + int ret = OB_SUCCESS; + if (OB_FAIL(unregister_from_mds_table_mgr())) { + MDS_LOG(ERROR, "fail to unregister from mds table mgr", K(*this)); + } + MDS_LOG(INFO, "mds table destructed", K(*this)); +} + +template +struct SetHelper {// find which unit to set at runtime + SetHelper(MdsTableImpl &mds_table_impl, + const uint8_t unit_id, + void *key, + void *data, + bool is_rvalue, + MdsCtx &ctx, + const int64_t lock_timeout_us) + : mds_table_impl_(mds_table_impl), + current_idx_(0), + unit_id_(unit_id), + key_(key), + data_(data), + is_rvalue_(is_rvalue), + ctx_(ctx), + lock_timeout_us_(lock_timeout_us) {} + template + struct InnerHelper {// member states of multi unit and single unit is not same, + // so need template partial specialization here, + // but function template partial specialization is not suppoted, + // so defined a inner class here + // this is for multi unit logic + InnerHelper(SetHelper &helper) : helper_(helper) {} + int operator()(MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (helper_.is_rvalue_) { + ret = helper_.mds_table_impl_.set(*(reinterpret_cast(helper_.key_)), + std::move(*(reinterpret_cast(helper_.data_))), + helper_.ctx_, + helper_.lock_timeout_us_); + } else { + ret = helper_.mds_table_impl_.set(*(reinterpret_cast(helper_.key_)), + *(reinterpret_cast(helper_.data_)), + helper_.ctx_, + helper_.lock_timeout_us_); + } + return ret; + } + SetHelper &helper_; + }; + template + struct InnerHelper {// this is for single unit logic + InnerHelper(SetHelper &helper) : helper_(helper) {} + int operator()(MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (helper_.is_rvalue_) { + ret = helper_.mds_table_impl_.set(std::move(*(reinterpret_cast(helper_.data_))), + helper_.ctx_, + helper_.lock_timeout_us_); + } else { + ret = helper_.mds_table_impl_.set(*(reinterpret_cast(helper_.data_)), + helper_.ctx_, + helper_.lock_timeout_us_); + } + return ret; + } + SetHelper &helper_; + }; + template + int operator()(MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (current_idx_++ == unit_id_) { + InnerHelper inner_helper(*this); + if (OB_FAIL(inner_helper(mds_unit))) { + } else { + ret = OB_ITER_END; + } + } + return ret;// if ret == OB_ITER_END or other err, interruptted + } + MdsTableImpl &mds_table_impl_; + uint8_t current_idx_; + const uint8_t unit_id_; + void *key_; + void *data_; + bool is_rvalue_; + MdsCtx &ctx_; + const int64_t lock_timeout_us_; +}; +template +int MdsTableImpl::set(int64_t unit_id, + void *key, + void *data, + bool is_rvalue, + MdsCtx &ctx, + const int64_t lock_timeout_us) { + int ret = OB_SUCCESS; + MDS_TG(5_ms);// point write should be fast + if (MDS_FAIL(advance_state_to(State::WRITTING))) { + MDS_LOG(ERROR, "mds table switch state failed", KR(ret), K(*this)); + } else { + SetHelper> helper(*this, + unit_id, + key, + data, + is_rvalue, + ctx, + lock_timeout_us); + if (OB_ITER_END == (ret = unit_tuple_.for_each(helper))) { + ret = OB_SUCCESS; + } else if (OB_FAIL(ret)) { + MDS_LOG(WARN, "fail to set", KR(ret)); + } else { + ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(WARN, "not found in tuple", KR(ret)); + } + } + return ret; +} + +template +struct ReplayHelper { + ReplayHelper(MdsTableImpl &mds_table_impl, + int64_t unit_id, + void *key, + void *data, + bool is_rvalue, + MdsCtx &ctx, + const share::SCN &scn) + : mds_table_impl_(mds_table_impl), + current_idx_(0), + unit_id_(unit_id), + key_(key), + data_(data), + is_rvalue_(is_rvalue), + ctx_(ctx), + scn_(scn) {} + template + struct InnerHelper { + InnerHelper(ReplayHelper &helper) : helper_(helper) {} + int operator()(MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (helper_.is_rvalue_) { + ret = helper_.mds_table_impl_.replay(*(reinterpret_cast(helper_.key_)), + std::move(*(reinterpret_cast(helper_.data_))), + helper_.ctx_, + helper_.scn_); + } else { + ret = helper_.mds_table_impl_.replay(*(reinterpret_cast(helper_.key_)), + *(reinterpret_cast(helper_.data_)), + helper_.ctx_, + helper_.scn_); + } + return ret; + } + ReplayHelper &helper_; + }; + template + struct InnerHelper { + InnerHelper(ReplayHelper &helper) : helper_(helper) {} + int operator()(MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (helper_.is_rvalue_) { + ret = helper_.mds_table_impl_.replay(std::move(*(reinterpret_cast(helper_.data_))), + helper_.ctx_, + helper_.scn_); + } else { + ret = helper_.mds_table_impl_.replay(*(reinterpret_cast(helper_.data_)), + helper_.ctx_, + helper_.scn_); + } + return ret; + } + ReplayHelper &helper_; + }; + template + int operator()(MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (current_idx_++ == unit_id_) { + InnerHelper inner_helper(*this); + if (OB_FAIL(inner_helper(mds_unit))) { + } else { + ret = OB_ITER_END; + } + } + return ret;// if ret == OB_ITER_END or other err, interruptted + } + MdsTableImpl &mds_table_impl_; + uint8_t current_idx_; + const uint8_t unit_id_; + void *key_; + void *data_; + bool is_rvalue_; + MdsCtx &ctx_; + const share::SCN &scn_; +}; +template +int MdsTableImpl::replay(int64_t unit_id, + void *key, + void *data, + bool is_rvalue, + MdsCtx &ctx, + const share::SCN &scn) { + int ret = OB_SUCCESS; + MDS_TG(5_ms);// point write should be fast + if (MDS_FAIL(advance_state_to(State::WRITTING))) { + MDS_LOG(ERROR, "mds table switch state failed", KR(ret), K(*this)); + } else { + ReplayHelper> helper(*this, + unit_id, + key, + data, + is_rvalue, + ctx, + scn); + if (OB_ITER_END == (ret = unit_tuple_.for_each(helper))) { + ret = OB_SUCCESS; + } else if (OB_FAIL(ret)) { + MDS_LOG(WARN, "fail to set", KR(ret)); + } else { + ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(WARN, "not found in tuple", KR(ret)); + } + } + return ret; +} + +template +struct RemoveHelper { + RemoveHelper(MdsTableImpl &mds_table_impl, + int64_t unit_id, + void *key, + MdsCtx &ctx, + const int64_t lock_timeout_us) + : mds_table_impl_(mds_table_impl), + current_idx_(0), + unit_id_(unit_id), + key_(key), + ctx_(ctx), + lock_timeout_us_(lock_timeout_us) {} + template + struct InnerHelper { + InnerHelper(RemoveHelper &helper) : helper_(helper) {} + int operator()(MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + ret = helper_.mds_table_impl_.template remove(*(reinterpret_cast(helper_.key_)), + helper_.ctx_, + helper_.lock_timeout_us_); + return ret; + } + RemoveHelper &helper_; + }; + template + struct InnerHelper { + InnerHelper(RemoveHelper &helper) : helper_(helper) {} + int operator()(MdsUnit &mds_unit) { + return OB_OBJ_TYPE_ERROR; + } + RemoveHelper &helper_; + }; + template + int operator()(MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (current_idx_++ == unit_id_) { + InnerHelper inner_helper(*this); + if (OB_FAIL(inner_helper(mds_unit))) { + } else { + ret = OB_ITER_END; + } + } + return ret;// if ret == OB_ITER_END or other err, interruptted + } + MdsTableImpl &mds_table_impl_; + uint8_t current_idx_; + const uint8_t unit_id_; + void *key_; + MdsCtx &ctx_; + const int64_t lock_timeout_us_; +}; +template +int MdsTableImpl::remove(int64_t unit_id, + void *key, + MdsCtx &ctx, + const int64_t lock_timeout_us) { + int ret = OB_SUCCESS; + MDS_TG(5_ms);// point write should be fast + if (MDS_FAIL(advance_state_to(State::WRITTING))) { + MDS_LOG(ERROR, "mds table switch state failed", KR(ret), K(*this)); + } else { + RemoveHelper> helper(*this, + unit_id, + key, + ctx, + lock_timeout_us); + if (OB_ITER_END == (ret = unit_tuple_.for_each(helper))) { + ret = OB_SUCCESS; + } else if (OB_FAIL(ret)) { + MDS_LOG(WARN, "fail to set", KR(ret)); + } else { + ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(WARN, "not found in tuple", KR(ret)); + } + } + return ret; +} + +template +struct ReplayRemoveHelper { + ReplayRemoveHelper(MdsTableImpl &mds_table_impl, + int64_t unit_id, + void *key, + MdsCtx &ctx, + const share::SCN &scn) + : mds_table_impl_(mds_table_impl), + current_idx_(0), + unit_id_(unit_id), + key_(key), + ctx_(ctx), + scn_(scn) {} + template + struct InnerHelper { + InnerHelper(ReplayRemoveHelper &helper) : helper_(helper) {} + int operator()(MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + ret = helper_.mds_table_impl_.template + replay_remove(*(reinterpret_cast(helper_.key_)), + helper_.ctx_, + helper_.scn_); + return ret; + } + ReplayRemoveHelper &helper_; + }; + template + struct InnerHelper { + InnerHelper(ReplayRemoveHelper &helper) : helper_(helper) {} + int operator()(MdsUnit &mds_unit) { + return OB_OBJ_TYPE_ERROR; + } + ReplayRemoveHelper &helper_; + }; + template + int operator()(MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (current_idx_++ == unit_id_) { + InnerHelper inner_helper(*this); + if (OB_FAIL(inner_helper(mds_unit))) { + } else { + ret = OB_ITER_END; + } + } + return ret;// if ret == OB_ITER_END or other err, interruptted + } + MdsTableImpl &mds_table_impl_; + uint8_t current_idx_; + const uint8_t unit_id_; + void *key_; + MdsCtx &ctx_; + const share::SCN &scn_; +}; +template +int MdsTableImpl::replay_remove(int64_t unit_id, + void *key, + MdsCtx &ctx, + const share::SCN &scn) { + int ret = OB_SUCCESS; + MDS_TG(5_ms);// point write should be fast + if (MDS_FAIL(advance_state_to(State::WRITTING))) { + MDS_LOG(ERROR, "mds table switch state failed", KR(ret), K(*this)); + } else { + ReplayRemoveHelper> helper(*this, + unit_id, + key, + ctx, + scn); + if (OB_ITER_END == (ret = unit_tuple_.for_each(helper))) { + ret = OB_SUCCESS; + } else if (OB_FAIL(ret)) { + MDS_LOG(WARN, "fail to set", KR(ret)); + } else { + ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(WARN, "not found in tuple", KR(ret)); + } + } + return ret; +} + +template +struct GetLatestHelper { + GetLatestHelper(const MdsTableImpl &mds_table_impl, + int64_t unit_id, + void *key, + ObFunction &op, + bool &is_committed, + const int64_t read_seq) + : mds_table_impl_(mds_table_impl), + current_idx_(0), + unit_id_(unit_id), + key_(key), + function_(op), + is_committed_(is_committed), + read_seq_(read_seq) {} + template + struct InnerHelper { + InnerHelper(GetLatestHelper &helper) : helper_(helper) {} + int operator()(const MdsUnit &mds_unit) { + return helper_.mds_table_impl_.template get_latest( + *reinterpret_cast(helper_.key_), + [this](const V &data) { + return helper_.function_(reinterpret_cast(&const_cast(data))); + }, + helper_.is_committed_, + helper_.read_seq_ + ); + } + GetLatestHelper &helper_; + }; + template + struct InnerHelper { + InnerHelper(GetLatestHelper &helper) : helper_(helper) {} + int operator()(const MdsUnit &mds_unit) { + return helper_.mds_table_impl_.template get_latest( + [this](const V &data) -> int { + return helper_.function_(reinterpret_cast(&const_cast(data))); + }, + helper_.is_committed_, + helper_.read_seq_ + ); + } + GetLatestHelper &helper_; + }; + template + int operator()(const MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (current_idx_++ == unit_id_) { + InnerHelper inner_helper(*this); + if (OB_FAIL(inner_helper(mds_unit))) { + } else { + ret = OB_ITER_END; + } + } + return ret;// if ret == OB_ITER_END or other err, interruptted + } + const MdsTableImpl &mds_table_impl_; + uint8_t current_idx_; + const uint8_t unit_id_; + void *key_; + ObFunction &function_; + bool &is_committed_; + const int64_t read_seq_; +}; +template +int MdsTableImpl::get_latest(int64_t unit_id, + void *key, + ObFunction &op, + bool &is_committed, + const int64_t read_seq) const { + int ret = OB_SUCCESS; + MDS_TG(5_ms);// point select should be fast + if (MDS_FAIL(advance_state_to(State::WRITTING))) { + MDS_LOG(ERROR, "mds table switch state failed", KR(ret), K(*this)); + } else { + GetLatestHelper> helper(*this, + unit_id, + key, + op, + is_committed, + read_seq); + if (OB_ITER_END == (ret = unit_tuple_.for_each(helper))) { + ret = OB_SUCCESS; + } else if (OB_FAIL(ret)) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG(WARN, "fail to get_latest", KR(ret)); + } + } else { + ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(WARN, "not found in tuple", KR(ret)); + } + } + return ret; +} + +template +struct GetSnapshotHelper { + GetSnapshotHelper(const MdsTableImpl &mds_table_impl, + int64_t unit_id, + void *key, + ObFunction &op, + const share::SCN &snapshot, + const int64_t read_seq, + const int64_t timeout_us) + : mds_table_impl_(mds_table_impl), + current_idx_(0), + unit_id_(unit_id), + key_(key), + function_(op), + snapshot_(snapshot), + read_seq_(read_seq), + timeout_us_(timeout_us) {} + template + struct InnerHelper { + InnerHelper(GetSnapshotHelper &helper) : helper_(helper) {} + int operator()(const MdsUnit &mds_unit) { + return helper_.mds_table_impl_.template get_snapshot( + *reinterpret_cast(helper_.key_), + [this](const V &data) { + return helper_.function_(reinterpret_cast(&const_cast(data))); + }, + helper_.snapshot_, + helper_.read_seq_, + helper_.timeout_us_ + ); + } + GetSnapshotHelper &helper_; + }; + template + struct InnerHelper { + InnerHelper(GetSnapshotHelper &helper) : helper_(helper) {} + int operator()(const MdsUnit &mds_unit) { + return helper_.mds_table_impl_.template get_snapshot( + [this](const V &data) { + return helper_.function_(reinterpret_cast(&const_cast(data))); + }, + helper_.snapshot_, + helper_.read_seq_, + helper_.timeout_us_ + ); + } + GetSnapshotHelper &helper_; + }; + template + int operator()(const MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (current_idx_++ == unit_id_) { + InnerHelper inner_helper(*this); + if (OB_FAIL(inner_helper(mds_unit))) { + } else { + ret = OB_ITER_END; + } + } + return ret;// if ret == OB_ITER_END or other err, interruptted + } + const MdsTableImpl &mds_table_impl_; + uint8_t current_idx_; + const uint8_t unit_id_; + void *key_; + ObFunction &function_; + const share::SCN &snapshot_; + const int64_t read_seq_; + const int64_t timeout_us_; +}; +template +int MdsTableImpl::get_snapshot(int64_t unit_id, + void *key, + ObFunction &op, + const share::SCN &snapshot, + const int64_t read_seq, + const int64_t timeout_us) const { + int ret = OB_SUCCESS; + MDS_TG(5_ms);// point select should be fast + if (MDS_FAIL(advance_state_to(State::WRITTING))) { + MDS_LOG(ERROR, "mds table switch state failed", KR(ret), K(*this)); + } else { + GetSnapshotHelper> helper(*this, + unit_id, + key, + op, + snapshot, + read_seq, + timeout_us); + if (OB_ITER_END == (ret = unit_tuple_.for_each(helper))) { + ret = OB_SUCCESS; + } else if (OB_FAIL(ret)) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG(WARN, "fail to get_snapshot", KR(ret)); + } + } else { + ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(WARN, "not found in tuple", KR(ret)); + } + } + return ret; +} + +template +struct GetByWriterHelper { + GetByWriterHelper(const MdsTableImpl &mds_table_impl, + int64_t unit_id, + void *key, + ObFunction &op, + const MdsWriter &writer, + const share::SCN &snapshot, + const int64_t read_seq, + const int64_t timeout_us) + : mds_table_impl_(mds_table_impl), + current_idx_(0), + unit_id_(unit_id), + key_(key), + function_(op), + writer_(writer), + snapshot_(snapshot), + read_seq_(read_seq), + timeout_us_(timeout_us) {} + template + struct InnerHelper { + InnerHelper(GetByWriterHelper &helper) : helper_(helper) {} + int operator()(const MdsUnit &mds_unit) { + return helper_.mds_table_impl_.template get_by_writer( + *reinterpret_cast(helper_.key_), + [this](const V &data) { + return helper_.function_(reinterpret_cast(&const_cast(data))); + }, + helper_.writer_, + helper_.snapshot_, + helper_.read_seq_, + helper_.timeout_us_ + ); + } + GetByWriterHelper &helper_; + }; + template + struct InnerHelper { + InnerHelper(GetByWriterHelper &helper) : helper_(helper) {} + int operator()(const MdsUnit &mds_unit) { + return helper_.mds_table_impl_.template get_by_writer( + [this](const V &data) { + return helper_.function_(reinterpret_cast(&const_cast(data))); + }, + helper_.writer_, + helper_.snapshot_, + helper_.read_seq_, + helper_.timeout_us_ + ); + } + GetByWriterHelper &helper_; + }; + template + int operator()(const MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (current_idx_++ == unit_id_) { + InnerHelper inner_helper(*this); + if (OB_FAIL(inner_helper(mds_unit))) { + } else { + ret = OB_ITER_END; + } + } + return ret;// if ret == OB_ITER_END or other err, interruptted + } + const MdsTableImpl &mds_table_impl_; + uint8_t current_idx_; + const uint8_t unit_id_; + void *key_; + ObFunction &function_; + const MdsWriter &writer_; + const share::SCN &snapshot_; + const int64_t read_seq_; + const int64_t timeout_us_; +}; +template +int MdsTableImpl::get_by_writer(int64_t unit_id, + void *key, + ObFunction &op, + const MdsWriter &writer, + const share::SCN &snapshot, + const int64_t read_seq, + const int64_t timeout_us) const { + int ret = OB_SUCCESS; + MDS_TG(5_ms);// point select should be fast + if (MDS_FAIL(advance_state_to(State::WRITTING))) { + MDS_LOG(ERROR, "mds table switch state failed", KR(ret), K(*this)); + } else { + GetByWriterHelper> helper(*this, + unit_id, + key, + op, + writer, + snapshot, + read_seq, + timeout_us); + if (OB_ITER_END == (ret = unit_tuple_.for_each(helper))) { + ret = OB_SUCCESS; + } else if (OB_FAIL(ret)) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG(WARN, "fail to get_by_writer", KR(ret)); + } + } else { + ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(WARN, "not found in tuple", KR(ret)); + } + } + return ret; +} + +template +struct IsLockedByOthersHelper { + IsLockedByOthersHelper(const MdsTableImpl &mds_table_impl, + int64_t unit_id, + void *key, + bool &is_locked, + const MdsWriter &self) + : mds_table_impl_(mds_table_impl), + current_idx_(0), + unit_id_(unit_id), + key_(key), + is_locked_(is_locked), + self_(self) {} + template + struct InnerHelper { + InnerHelper(IsLockedByOthersHelper &helper) : helper_(helper) {} + int operator()(const MdsUnit &mds_unit) { + return helper_.mds_table_impl_.template is_locked_by_others( + *reinterpret_cast(helper_.key_), + helper_.is_locked_, + helper_.self_ + ); + } + IsLockedByOthersHelper &helper_; + }; + template + struct InnerHelper { + InnerHelper(IsLockedByOthersHelper &helper) : helper_(helper) {} + int operator()(const MdsUnit &mds_unit) { + return helper_.mds_table_impl_.template is_locked_by_others( + helper_.is_locked_, + helper_.self_ + ); + } + IsLockedByOthersHelper &helper_; + }; + template + int operator()(const MdsUnit &mds_unit) { + int ret = OB_SUCCESS; + if (current_idx_++ == unit_id_) { + InnerHelper inner_helper(*this); + if (OB_FAIL(inner_helper(mds_unit))) { + } else { + ret = OB_ITER_END; + } + } + return ret;// if ret == OB_ITER_END or other err, interruptted + } + const MdsTableImpl &mds_table_impl_; + uint8_t current_idx_; + const uint8_t unit_id_; + void *key_; + bool &is_locked_; + const MdsWriter &self_; +}; +template +int MdsTableImpl::is_locked_by_others(int64_t unit_id, + void *key, + bool &is_locked, + const MdsWriter &self) const { + int ret = OB_SUCCESS; + MDS_TG(5_ms);// point select should be fast + if (MDS_FAIL(advance_state_to(State::WRITTING))) { + MDS_LOG(ERROR, "mds table switch state failed", KR(ret), K(*this)); + } else { + IsLockedByOthersHelper> helper(*this, + unit_id, + key, + is_locked, + self); + if (OB_ITER_END == (ret = unit_tuple_.for_each(helper))) { + ret = OB_SUCCESS; + } else if (OB_FAIL(ret)) { + MDS_LOG(WARN, "fail to set", KR(ret)); + } else { + ret = OB_OBJ_TYPE_ERROR; + MDS_LOG(WARN, "not found in tuple", KR(ret)); + } + } + return ret; +} + +template +int MdsTableImpl::for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump( + ObFunction &for_each_op, + const bool for_flush) const { + int ret = OB_SUCCESS; + MDS_TG(100_ms);// scan could be slow + if (MDS_FAIL(advance_state_to(State::WRITTING))) { + MDS_LOG(WARN, "mds table switch state failed", KR(ret), K(*this)); + } else if (MDS_FAIL(const_cast*>(this)-> + for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump( + [for_each_op](const MdsDumpKV& data) { + return for_each_op(data); + }, for_flush + ))) { + MDS_LOG(WARN, "mds table switch state failed", KR(ret), K(*this)); + } + return ret; +} + +struct RecalculateFlushScnCauseOnlySuppportDumpCommittedNodeOP// FIXME: delete this after support dump uncommitted node +{ + RecalculateFlushScnCauseOnlySuppportDumpCommittedNodeOP(share::SCN &do_flush_scn) : do_flush_scn_(do_flush_scn) {} + template + int operator()(const MdsRow &row) { + int ret = OB_SUCCESS; + // already add lock on unit, but no lock on row + MDS_TG(5_ms); + MdsRLockGuard lg(row.lock_);// lock on row + CLICK(); + row.sorted_list_.for_each_node_from_tail_to_head_until_true( + [this](const UserMdsNode &mds_node) { + bool need_break = false; + if (do_flush_scn_ >= mds_node.redo_scn_ && do_flush_scn_ < mds_node.end_scn_) { + need_break = true; + MDS_LOG(DEBUG, "try decline do_flush_scn", K_(do_flush_scn), K(mds_node)); + do_flush_scn_ = std::min(do_flush_scn_, share::SCN::minus(mds_node.redo_scn_, 1)); + } else if (!mds_node.redo_scn_.is_max() && do_flush_scn_ < mds_node.redo_scn_) { + need_break = true; + } + return need_break; + } + ); + return ret; + } + share::SCN &do_flush_scn_; +}; +struct CountUnDumpdedNodesBelowDoFlushScn// To filter unnecessary flush operation +{ + CountUnDumpdedNodesBelowDoFlushScn(int64_t &total_cnt, share::SCN &do_flush_scn) + : total_cnt_(total_cnt), do_flush_scn_(do_flush_scn) { total_cnt_ = 0; } + template + int operator()(const MdsRow &row) { + int ret = OB_SUCCESS; + // already add lock on unit, but no lock on row + MDS_TG(5_ms); + MdsRLockGuard lg(row.lock_);// lock on row + CLICK(); + row.sorted_list_.for_each_node_from_tail_to_head_until_true( + [this](const UserMdsNode &mds_node) { + bool need_break = false; + if (check_node_scn_beflow_flush(mds_node, do_flush_scn_)) { + if (!mds_node.is_dumped_()) { + total_cnt_++; + } + } else { + need_break = true; + } + return need_break; + } + ); + return ret; + } + int64_t &total_cnt_; + const share::SCN &do_flush_scn_; +}; +template +int MdsTableImpl::flush(share::SCN recycle_scn, bool need_freeze) +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(recycle_scn), K(need_freeze),\ + K(ls_max_consequent_callbacked_scn), K(do_flush_scn), K(temp_flushing_scn), K(undump_node_cnt) + MDS_TG(100_ms); + int ret = OB_SUCCESS; + share::SCN ls_max_consequent_callbacked_scn = share::SCN::max_scn(); + share::SCN do_flush_scn;// this scn is defined for calculation + share::SCN temp_flushing_scn; + int64_t undump_node_cnt = 0; + MdsWLockGuard lg(lock_); + if (need_freeze) { + // if need_freeze is true, decide a flushing_scn + if (!recycle_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG_FLUSH(WARN, "invalid recycle scn"); + } else if (last_flushed_scn_.is_valid() && last_flushed_scn_ >= recycle_scn) { + // skip freeze if this flushed_scn >= recycle_scn + MDS_LOG_FLUSH(INFO, "no need do freeze action cause a not-less-than version has been flushed"); + } else if (flushing_scn_.is_valid()) { + // skip freeze if this mds table is flushing + MDS_LOG_FLUSH(DEBUG, "no need do freeze action cause another flush dag is running"); + } else { + // do freeze mds table +#ifndef UNITTEST_DEBUG + if (MDS_FAIL(get_ls_max_consequent_callbacked_scn_(ls_max_consequent_callbacked_scn))) { + MDS_LOG_FLUSH(WARN, "fail to get ls_max_consequent_callbacked_scn"); + } else if (ls_max_consequent_callbacked_scn.is_max()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_FLUSH(ERROR, "invalid ls max consequent callbacked scn"); + } else { + do_flush_scn = ls_max_consequent_callbacked_scn; + } +#else + do_flush_scn = recycle_scn; +#endif + if (OB_SUCC(ret)) { + RecalculateFlushScnCauseOnlySuppportDumpCommittedNodeOP op1(do_flush_scn); + CountUnDumpdedNodesBelowDoFlushScn op2(undump_node_cnt, do_flush_scn); + if (MDS_FAIL(for_each_scan_row(op1))) { + MDS_LOG_FLUSH(WARN, "for each to calculate flush scn failed"); + } else if (MDS_FAIL(for_each_scan_row(op2))) { + MDS_LOG_FLUSH(WARN, "for each to count undumped nodes failed"); + } else if (undump_node_cnt != 0) { + temp_flushing_scn = do_flush_scn;// will do flush operation + } else {// no need do flush actually + // mds_ckpt_scn on tablet won't be advanced, + // replay will cost more time after restart process, but saved cpu and io for dump dag + MDS_LOG_FLUSH(INFO, "no undump nodes below do flush scn, directly advance rec_scn"); + flushing_scn_ = do_flush_scn;// will be resetted in on_flush_() + on_flush_(do_flush_scn, OB_SUCCESS); + } + } + } + } + + if (OB_SUCC(ret) && + (flushing_scn_.is_valid() || // need_freeze is false, not calculate temp_flushing_scn, but need generate dag + temp_flushing_scn.is_valid())) {// need_freeze is true, calculated a temp flushing scn + // if we get a valid flushing_scn, schedule mini merge +#ifndef UNITTEST_DEBUG + share::SCN do_merge_scn = temp_flushing_scn.is_valid() ? temp_flushing_scn : flushing_scn_; + if (MDS_FAIL(merge(do_merge_scn))) { + MDS_LOG_FLUSH(WARN, "failed to merge mds table"); + } else { + if (temp_flushing_scn.is_valid()) { + flushing_scn_ = temp_flushing_scn;// if and only if calculated valid temp_flushing_scn(need_freeze is true) and generate dag success, set flushing_scn + } + report_flush_event_("DO_FLUSH", flushing_scn_, need_freeze); + } +#else + flushing_scn_ = temp_flushing_scn; +#endif + } + MDS_LOG_FLUSH(DEBUG, "call flush mds_table"); + return ret; + #undef PRINT_WRAPPER +} + +struct CalculateRecScnOp +{ + CalculateRecScnOp(const share::SCN on_flush_scn) + : on_flush_scn_(on_flush_scn), + rec_scn_(share::SCN::max_scn()) {} + ~CalculateRecScnOp() { + for (int64_t idx = 0; idx < lock_array_.count(); ++idx) { + ((MdsLock*)lock_array_[idx])->unlock(); + } + } + template + int operator()(const MdsRow &row) { + int ret = OB_SUCCESS; + MDS_TG(5_ms); + // add row's lock until calculation done + if (MDS_FAIL(lock_array_.push_back(nullptr))) { + MDS_LOG(WARN, "fail to add lock placeholder on low"); + } else { + row.lock_.wrlock(); + lock_array_[lock_array_.count() - 1] = &row.lock_; + CLICK(); + share::SCN closest_bigger_scn = share::SCN::max_scn(); + // must scan from tail to head, cause flush may happend in replay phase(replay operation is out of order) + row.sorted_list_.for_each_node_from_tail_to_head_until_true( + [this, &ret, &closest_bigger_scn](const UserMdsNode &mds_node) { + bool need_break = false; + MDS_TG(1_ms); + if (check_node_scn_beflow_flush(mds_node, on_flush_scn_)) { + if (!mds_node.is_dumped_()) { + const_cast &>(mds_node).set_dumped_();// mark it dumped, so no need dump again + MDS_LOG(INFO, "mark mds node dumped", K(mds_node)); + } + if (mds_node.redo_scn_ <= on_flush_scn_ && mds_node.end_scn_ > on_flush_scn_) { + MDS_LOG(ERROR, "should not go here cause not support dump uncomitted node yet", K(mds_node));// FIXME: remove this log after support dump uncomitted node + closest_bigger_scn = mds_node.end_scn_; + need_break = true;// break for_each operation + } + } else { + closest_bigger_scn = mds_node.redo_scn_; + need_break = true;// break for_each operation + } + return need_break || OB_FAIL(ret); + } + ); + rec_scn_ = std::min(rec_scn_, closest_bigger_scn); + } + return ret; + } + const share::SCN on_flush_scn_; + share::SCN rec_scn_; + common::ObSEArray lock_array_; +}; +template +void MdsTableImpl::on_flush(const share::SCN &flush_scn, const int flush_ret) +{ + MDS_TG(10_ms); + MdsWLockGuard lg(lock_); + CLICK(); + on_flush_(flush_scn, flush_ret); +} +template +void MdsTableImpl::on_flush_(const share::SCN &flush_scn, const int flush_ret) +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(flush_scn) + int ret = flush_ret; + MDS_TG(10_ms); + share::SCN max_consequent_callbacked_scn = share::SCN::max_scn(); + if (MDS_FAIL(ret)) { + MDS_LOG_FLUSH(WARN, "flush failed"); + flushing_scn_.reset(); + } else if (!flushing_scn_.is_valid() || flushing_scn_ != flush_scn) { + MDS_LOG_FLUSH(ERROR, "flush version mismatch!"); + } else { + last_flushed_scn_ = flushing_scn_; + flushing_scn_.reset(); + bool need_retry = false; + do { + need_retry = false; + CalculateRecScnOp op(flush_scn); + if (MDS_FAIL(for_each_scan_row(op))) {// lock all rows failed, retry until lock all rows success + need_retry = true; + MDS_LOG_FLUSH(WARN, "fail to do on flush");// record row lock guard may failed, cause lock guard array may meet extended failed cause memory not enough, but retry will make it success + } else { + share::SCN new_rec_scn = op.rec_scn_; + OB_ASSERT(new_rec_scn >= last_flushed_scn_); + try_advance_rec_scn(new_rec_scn); + report_on_flush_event_("ON_FLUSH", last_flushed_scn_); + } + } while (need_retry && !FALSE_IT(PAUSE()));// here will release all rows lock + } + #undef PRINT_WRAPPER +} + +template +template ::type> +int MdsTableImpl:: + for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump(DUMP_OP &&for_each_op, + const bool for_flush/*false is for transfer to bring mds data from old tablet to new*/) { + #define PRINT_WRAPPER KR(ret), K(*this) + MDS_TG(100_ms); + int ret = OB_SUCCESS; + share::SCN flushing_version; + MdsRLockGuard lg(lock_); + CLICK(); + if (for_flush) { + if (!flushing_scn_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_FLUSH(WARN, "not in flushing process"); + } else { + flushing_version = flushing_scn_; + } + } else { + flushing_version = share::SCN::max_scn(); + } + if (OB_SUCC(ret)) { + if (MDS_FAIL(for_each_to_dump_node_(std::forward(for_each_op), flushing_version, for_flush))) { + MDS_LOG_FLUSH(WARN, "for each node to dump failed"); + } else { + MDS_LOG_FLUSH(TRACE, "for each node to dump success"); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsTableImpl::set(T &&data, MdsCtx &ctx, const int64_t lock_timeout_us) +{ + uint8_t unit_id = TupleTypeIdx>::value; + return MDS_ELEMENT(DummyKey, T).set(this, + std::forward(data), + ctx, + lock_timeout_us); +} + +template +template +int MdsTableImpl::replay(T &&data, MdsCtx &ctx, const share::SCN &scn) +{ + MdsRLockGuard lg(lock_);// Mutex with on_flush(replay is out-of-order, may affects calculate rec_scn phase) + uint8_t unit_id = TupleTypeIdx>::value; + return MDS_ELEMENT(DummyKey, T).replay(this, std::forward(data), ctx, scn); +} + +template +template ::type> +int MdsTableImpl::get_latest(OP &&read_op, + bool &is_committed, + const int64_t read_seq) const +{ + auto read_op_wrapper = [&read_op, &is_committed](const UserMdsNode &node) -> int { + is_committed = node.is_committed_(); + return read_op(node.user_data_); + }; + return MDS_ELEMENT(DummyKey, T).get_latest(read_op_wrapper, read_seq); +} + +template +template ::type> +int MdsTableImpl::get_snapshot(OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, const int64_t timeout_us) const +{ + auto read_op_wrapper = [&read_op](const UserMdsNode &node) -> int { + return read_op(node.user_data_); + }; + return MDS_ELEMENT(DummyKey, T).get_snapshot(read_op_wrapper, + snapshot, + read_seq, + timeout_us); +} + +template +template ::type> +int MdsTableImpl::get_by_writer(OP &&read_op, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + auto read_op_wrapper = [&read_op](const UserMdsNode &node) -> int { + return read_op(node.user_data_); + }; + return MDS_ELEMENT(DummyKey, T).get_by_writer(read_op_wrapper, + writer, + snapshot, + read_seq, + timeout_us); +} + +template +template +int MdsTableImpl::is_locked_by_others(bool &is_locked, const MdsWriter &self) const +{ + auto read_op_wrapper = [&is_locked, &self](const UserMdsNode &node) -> int { + OB_ASSERT(node.status_.union_.field_.state_ != TwoPhaseCommitState::ON_ABORT); + if (node.status_.union_.field_.state_ == TwoPhaseCommitState::ON_COMMIT) {// no lock on decided node + is_locked = false; + } else if (node.status_.union_.field_.writer_type_ == self.writer_type_ && + node.writer_id_ == self.writer_id_) {// lock by myself + is_locked = false; + } else { + is_locked = true; + } + return OB_SUCCESS; + }; + return MDS_ELEMENT(DummyKey, T).get_latest(read_op_wrapper, 0); +} + +template +template +int MdsTableImpl::set(const Key &key, + Value &&data, + MdsCtx &ctx, + const int64_t lock_timeout_us) +{ + MdsRLockGuard lg(lock_);// Mutex with on_flush(this operation may create new mds_row, but locks all rows in on_flush phase) + uint8_t unit_id = TupleTypeIdx>::value; + return MDS_ELEMENT(Key, Value).set(this, key, std::forward(data), ctx, lock_timeout_us); +} + +template +template +int MdsTableImpl::replay(const Key &key, + Value &&data, + MdsCtx &ctx, + const share::SCN &scn) +{ + MdsRLockGuard lg(lock_);// Mutex with on_flush(replay is out-of-order, may affects calculate rec_scn phase) + uint8_t unit_id = TupleTypeIdx>::value; + return MDS_ELEMENT(Key, Value).replay(this, key, std::forward(data), ctx, scn); +} + +template +template +int MdsTableImpl::remove(const Key &key, + MdsCtx &ctx, + const int64_t lock_timeout_us) +{ + MdsRLockGuard lg(lock_);// Mutex with on_flush(this operation may create new mds_row, but locks all rows in on_flush phase) + uint8_t unit_id = TupleTypeIdx>::value; + return MDS_ELEMENT(Key, Value).set(this, key, Value(), ctx, lock_timeout_us, true); +} + +template +template +int MdsTableImpl::replay_remove(const Key &key, + MdsCtx &ctx, + const share::SCN &scn) +{ + MdsRLockGuard lg(lock_);// Mutex with on_flush(replay is out-of-order, may affects calculate rec_scn phase) + uint8_t unit_id = TupleTypeIdx>::value; + return MDS_ELEMENT(Key, Value).replay(this, key, Value(), ctx, scn, true); +} + +template +template +int MdsTableImpl::get_latest(const Key &key, + OP &&read_op, + bool &is_committed, + const int64_t read_seq) const +{ + auto read_op_wrapper = [&read_op, &is_committed](const UserMdsNode &node) -> int { + is_committed = node.is_committed_(); + return read_op(node.user_data_); + }; + return MDS_ELEMENT(Key, Value).get_latest(key, read_op_wrapper, read_seq); +} + +template +template +int MdsTableImpl::get_snapshot(const Key &key, + OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + auto read_op_wrapper = [&read_op](const UserMdsNode &node) -> int { + return read_op(node.user_data_); + }; + return MDS_ELEMENT(Key, Value).get_snapshot(key, + read_op_wrapper, + snapshot, + read_seq, + timeout_us); +} + +template +template +int MdsTableImpl::get_by_writer(const Key &key, + OP &&read_op, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + auto read_op_wrapper = [&read_op](const UserMdsNode &node) -> int { + return read_op(node.user_data_); + }; + return MDS_ELEMENT(Key, Value).get_by_writer(key, + read_op_wrapper, + writer, + snapshot, + read_seq, + timeout_us); +} + +template +template +int MdsTableImpl::is_locked_by_others(const Key &key, + bool &is_locked, + const MdsWriter &self) const +{ + auto read_op_wrapper = [&is_locked, &self](const UserMdsNode &node) -> int { + OB_ASSERT(node.status_.union_.field_.state_ != TwoPhaseCommitState::ON_ABORT); + if (node.status_.union_.field_.state_ == TwoPhaseCommitState::ON_COMMIT) { + is_locked = false; + } else if (node.status_.union_.field_.writer_type_ == self.writer_type_ && + node.writer_id_ == self.writer_id_) {// lock by myself + is_locked = false; + } else { + is_locked = true; + } + return OB_SUCCESS; + }; + return MDS_ELEMENT(Key, Value).get_latest(key, read_op_wrapper, 0); +} + +template +template +int MdsTableImpl::for_each_scan_row(SCAN_OP &&op) +{// add lock on unit + ForEachUnitScanRowHelper for_each_op(op); + return unit_tuple_.for_each(for_each_op); +} + +struct RecycleNodeOp +{ + RecycleNodeOp(const share::SCN recycle_scn) : recycle_scn_(recycle_scn) {} + template + int operator()(const MdsRow &row) { + int ret = OB_SUCCESS; + // already add lock on unit, but no lock on row + MDS_TG(5_ms); + MdsWLockGuard lg(row.lock_);// lock on row + CLICK(); + // must scan from tail to head, cause recycle may happened in replay phase(replay operation is out of order) + // skip nodes no need to see(see class MdsRowSkipAndDestroyOp to check definitions) + row.sorted_list_.for_each_node_from_tail_to_head_until_true( + [&ret, this, &row](const UserMdsNode &mds_node) { + bool need_break = false; + bool need_delete = false; + MDS_TG(1_ms); + { + CLICK(); + OB_ASSERT(!mds_node.is_aborted_());// should not see aborted node cause cause it is deleted immediatly + if (mds_node.is_committed_()) { + if (mds_node.end_scn_ == share::SCN::max_scn()) {// must has an associated valid end LOG to commit/abort + ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "meet a valid decided mds node with max scn", K(mds_node)); + } else if (mds_node.end_scn_ <= recycle_scn_ && mds_node.is_dumped_()) {// safe to destroy mds node + need_delete = true; + } else { + need_break = true;// break for each operation + } + } + } + if (need_delete) { + UserMdsNode &cast_node = const_cast &>(mds_node); + const_cast &>(row).sorted_list_.del((ListNodeBase*)(ListNode>*)(&cast_node)); + MdsFactory::destroy(&cast_node); + } + return need_break || OB_SUCCESS != ret; + } + ); + return ret; + } + const share::SCN recycle_scn_; +}; +template +int MdsTableImpl::try_recycle(const share::SCN recycle_scn) +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(recycle_scn), K(do_inner_recycle_scn) + int ret = OB_SUCCESS; + MDS_TG(100_ms); + if (!recycle_scn.is_min()) { + MdsWLockGuard lg(lock_); + share::SCN do_inner_recycle_scn = std::min(get_rec_scn(), recycle_scn); + if (!recycle_scn.is_valid() || recycle_scn.is_max()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG_GC(ERROR, "invalid argument"); + } else if (last_inner_recycled_scn_.is_valid() && last_inner_recycled_scn_ >= do_inner_recycle_scn) { + // do nothing + } else { + RecycleNodeOp op(do_inner_recycle_scn); + if (OB_FAIL(for_each_scan_row(op))) { + MDS_LOG_GC(ERROR, "fail to do recycle"); + } else { + last_inner_recycled_scn_ = do_inner_recycle_scn; + report_recycle_event_(do_inner_recycle_scn); + } + } + } + return ret; + #undef PRINT_WRAPPER +} + +struct ForcelyReleaseAllNodeOp +{ + ForcelyReleaseAllNodeOp(const char *reason) : reason_(reason) {} + template + int operator()(const MdsRow &row) { + #define PRINT_WRAPPER K(cast_node), K_(reason) + int ret = OB_SUCCESS; + // already add lock on unit, but no lock on row + MDS_TG(5_ms); + MdsWLockGuard lg(row.lock_);// lock on row + CLICK(); + row.sorted_list_.for_each_node_from_tail_to_head_until_true( + [this, &row](const UserMdsNode &mds_node) { + UserMdsNode &cast_node = const_cast &>(mds_node); + if (!cast_node.is_committed_()) { + MDS_LOG_GC(INFO, "release uncommitted node"); + } + const_cast &>(row).sorted_list_.del((ListNodeBase*)(ListNode>*)(&cast_node)); + MdsFactory::destroy(&cast_node); + return false; + } + ); + return ret; + #undef PRINT_WRAPPER + } + const char *reason_; +}; +template +int MdsTableImpl::forcely_release_all_mds_nodes(const char *reason) +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(reason) + int ret = OB_SUCCESS; + MDS_TG(100_ms); + MdsWLockGuard lg(lock_); + ForcelyReleaseAllNodeOp op(reason); + if (OB_FAIL(for_each_scan_row(op))) { + MDS_LOG_GC(ERROR, "fail to do recycle"); + } else { + MDS_LOG_GC(INFO, "forcely release all mds nodes"); + } + return ret; + #undef PRINT_WRAPPER +} + +#undef MDS_ELEMENT +} +} +} +#endif diff --git a/src/storage/multi_data_source/mds_table_mgr.cpp b/src/storage/multi_data_source/mds_table_mgr.cpp new file mode 100644 index 000000000..6e5e33c3f --- /dev/null +++ b/src/storage/multi_data_source/mds_table_mgr.cpp @@ -0,0 +1,368 @@ +/** + * Copyright (c) 2021 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/ob_errno.h" +#include "ob_tablet_id.h" +#define USING_LOG_PREFIX MDS + +#include "mds_table_mgr.h" +#include "mds_table_handle.h" +#include "storage/ls/ob_ls.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/tablet/ob_tablet_iterator.h" +#include "storage/multi_data_source/mds_table_base.h" +#include "storage/meta_mem/ob_tablet_pointer.h" + +namespace oceanbase { + +using namespace share; + +namespace storage { +namespace mds { + +int ObMdsTableMgr::init(ObLS *ls) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + MDS_LOG(WARN, "init mds table mgr twice", KR(ret), KPC(this)); + } else if (OB_ISNULL(ls) || OB_ISNULL(ls->get_tx_svr())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "invalid ls when init mds table mgr", KR(ret), KPC(ls), KPC(this)); + } else if (OB_FAIL(ls->get_ls_id().debug_for_mds() && ls->get_tx_svr()->register_common_checkpoint(checkpoint::MDS_TABLE_TYPE, this))) { + MDS_LOG(WARN, "register common checkpoint failed", KR(ret), KPC(this)); + } else if (OB_FAIL(mds_table_map_.init("MdsTableMgr", MTL_ID()))) { + MDS_LOG(ERROR, "fail to init mds table map", KR(ret), KPC(ls), KPC(this)); + } else { + ls_ = ls; + is_inited_ = true; + } + + return ret; +} + +int ObMdsTableMgr::reset() +{ + int ret = OB_SUCCESS; + is_inited_ = false; + is_freezing_ = false; + rec_log_ts_ = 0; + ref_cnt_ = 0; + mds_table_cnt_ = 0; + ls_ = nullptr; + if (OB_FAIL(mds_table_map_.reset())) { + MDS_LOG(WARN, "fail to reset mds_table_map", KR(ret)); + } + return ret; +} + +void ObMdsTableMgr::destroy() { reset(); } + +int ObMdsTableMgr::register_to_mds_table_mgr(MdsTableBase *p_mds_table) +{ + int ret = OB_SUCCESS; + common::ObTabletID tablet_id; + if (OB_ISNULL(p_mds_table)) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG(ERROR, "invalid mdstable handle", KR(ret), KP(p_mds_table)); + } else if (FALSE_IT(tablet_id = p_mds_table->get_tablet_id())) { + } else { + int op_result = OB_SUCCESS; + auto op = [p_mds_table, &op_result](const ObTabletID &id, List &list) {// with map's bucket lock protected + if (list.empty()) { + list.insert_into_head(p_mds_table); + } else { + MdsTableBase *head_mds_table = static_cast(list.list_head_); + if (!head_mds_table->is_removed_from_t3m()) { + op_result = OB_ENTRY_EXIST; + MDS_LOG_RET(INFO, op_result, "register meet conflct", K(id), K(list), KPC(p_mds_table)); + } else { + list.insert_into_head(p_mds_table); + } + } + return true; + }; + bool need_break = false; + List tmp_list; + tmp_list.append(p_mds_table); + while (!need_break) { + if (OB_FAIL(mds_table_map_.insert(tablet_id, tmp_list))) { + if (OB_ENTRY_EXIST == ret) { + ret = OB_SUCCESS; + if (OB_FAIL(mds_table_map_.operate(tablet_id, op))) { + if (OB_ENTRY_NOT_EXIST == ret) {// meet concurrent erase + ret = OB_SUCCESS; + } else {// meet errors can't handle, no need retry + need_break = true; + MDS_LOG(WARN, "operate list failed and ret is not ENTRY_NOT_EXIST", KR(ret), K(tablet_id)); + } + } else {// insert to existing list success, no need retry + need_break = true; + } + } else { + need_break = true;// meet errors can't handle, no need retry + MDS_LOG(WARN, "insert list failed and ret is not ENTRY_EXIST", KR(ret), K(tablet_id)); + } + } else { + need_break = true;// insert new list success, no need retry + } + }; + if (OB_FAIL(ret)) { + // do nothing + } else { + ret = op_result; + if (OB_SUCC(ret)) { + MDS_LOG(INFO, "register success", KR(ret), KPC(p_mds_table)); + } + } + } + return ret; +} + +int ObMdsTableMgr::unregister_from_mds_table_mgr(MdsTableBase *p_mds_table) +{ + int ret = OB_SUCCESS; + common::ObTabletID tablet_id; + auto op = [p_mds_table](const ObTabletID &id, List &list) {// with map's bucket lock protected + if (list.check_node_exist(p_mds_table)) { + list.del(p_mds_table); + } else { + MDS_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "mds table not in list", KPC(p_mds_table), K(id), K(list)); + ob_abort(); + } + return list.empty(); + }; + if (OB_ISNULL(p_mds_table)) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG(ERROR, "invalid mdstable handle", KR(ret), KP(p_mds_table)); + } else if (FALSE_IT(tablet_id = p_mds_table->get_tablet_id())) { + } else if (OB_FAIL(mds_table_map_.erase_if(tablet_id, op))) { + if (OB_EAGAIN == ret) { + ret = OB_SUCCESS; + } else { + MDS_LOG(WARN, "fail to erase kv", KR(ret), K(tablet_id)); + } + } else { + MDS_LOG(INFO, "unregister success", KR(ret), KPC(p_mds_table)); + } + return ret; +} + +int ObMdsTableMgr::flush(SCN recycle_scn, bool need_freeze) +{ + int ret = OB_SUCCESS; + MDS_LOG(DEBUG, "start flush", "ls_id", ls_->get_ls_id(), K(recycle_scn), K(need_freeze)); + common::ObTimeGuard tg("flush mds tables", 100 * 1000); + MdsTableFreezeGuard freeze_guard; + freeze_guard.init(this); + int64_t flushed_table_cnt = 0; + MdsTableHandle *flushing_mds_table = nullptr; + ObLSID ls_of_flushing_tablet; + ObTabletID flushing_tablet; + auto flush_op = + [&flushed_table_cnt, recycle_scn, need_freeze](const common::ObTabletID &tablet_id, + List &mds_table_list) { + int tmp_ret = OB_SUCCESS; + if (mds_table_list.empty()) { + MDS_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "meet empty mds table list", K(tablet_id)); + } else { + MdsTableBase *mds_table = static_cast(mds_table_list.list_head_); + if (mds_table->is_removed_from_t3m()) { + // jsut skip it + } else if (OB_TMP_FAIL(mds_table->flush(recycle_scn, need_freeze))) { + MDS_LOG_RET(WARN, ret, "flush mds table failed", KR(tmp_ret), K(tablet_id)); + } else { + flushed_table_cnt++; + } + } + // true means iterating the next mds table + return true; + }; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + MDS_LOG(ERROR, "regsiter mds table failed", KR(ret)); + } else if (!freeze_guard.can_freeze()) { + if (REACH_TIME_INTERVAL(2 * 1000 * 1000 /*2 seconds*/)) { + MDS_LOG(INFO, "mds table is flushing, skip flush once", K(recycle_scn), KPC(this)); + } + } else if (has_flushing_mds_table_(ls_of_flushing_tablet, flushing_tablet)) { + // if there are some mds tables flushing, skip flushing this time + ret = OB_EAGAIN; + if (REACH_TIME_INTERVAL(10 * 1000 * 1000 /*10 seconds*/)) { + MDS_LOG(INFO, "skip trigger logstream mds table flush due to some mds tables are flushing", + KR(ret), K(ls_of_flushing_tablet), K(flushing_tablet)); + } + } else { + if (OB_FAIL(mds_table_map_.for_each(flush_op))) { + MDS_LOG(WARN, "fail to do map for_each", KR(ret), KPC(flushing_mds_table)); + } + } + MDS_LOG(DEBUG, "[MdsTableMgr] finish flush", "ls_id", ls_->get_ls_id(), K(flushed_table_cnt)); + return ret; +} + +bool ObMdsTableMgr::has_flushing_mds_table_(ObLSID &ls_id_of_flushing_tablet, + ObTabletID &flushing_tablet_id) +{ + int ret = OB_SUCCESS; + bool has_flushing_mds_table_ = false; + + auto find_first_flushing_mds_table_and_retry = + [&has_flushing_mds_table_, + &ls_id_of_flushing_tablet, + &flushing_tablet_id] (const common::ObTabletID &tablet_id, List &mds_table_list) { + int tmp_ret = OB_SUCCESS; + bool is_flushing = false; + if (mds_table_list.empty()) { + MDS_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "meet empty mds table list", K(tablet_id)); + } else { + MdsTableBase *p_mds_table = static_cast(mds_table_list.list_head_); + if (p_mds_table->is_removed_from_t3m()) { + // jsut skip it + } else if (FALSE_IT(is_flushing = p_mds_table->is_flushing())) { + } else if (is_flushing) { + if (OB_TMP_FAIL(p_mds_table->flush(SCN::max_scn() /*recycle_scn*/, false /*need_freeze*/))) { + MDS_LOG_RET(WARN, tmp_ret, "flush mds table failed", KR(tmp_ret), KPC(p_mds_table)); + } + if (!flushing_tablet_id.is_valid()) { + ls_id_of_flushing_tablet = p_mds_table->get_ls_id(); + flushing_tablet_id = p_mds_table->get_tablet_id(); + } + has_flushing_mds_table_ = true; + } + } + // true means iterating the next mds table + return true; + }; + if (OB_FAIL(mds_table_map_.for_each(find_first_flushing_mds_table_and_retry))) { + MDS_LOG(WARN, "flush mds table failed", KR(ret)); + } + return has_flushing_mds_table_; +} + +SCN ObMdsTableMgr::get_rec_scn() +{ + int ret = OB_SUCCESS; + // TODO : @gengli FIX ME + SCN min_rec_scn; + SCN max_decided_scn = SCN::min_scn(); + common::ObTimeGuard tg("get mds table rec log scn", 100 * 1000); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + MDS_LOG(ERROR, "regsiter mds table failed", KR(ret)); + } else if (OB_FAIL(ls_->get_max_decided_scn(max_decided_scn))) { + MDS_LOG(WARN, "get max decided log ts failed", KR(ret)); + } else { + min_rec_scn = max_decided_scn; + auto get_scn_op = [&min_rec_scn, &ret](const common::ObTabletID &tablet_id, + List &mds_table_list) { + SCN rec_scn; + if (mds_table_list.empty()) { + MDS_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "meet empty mds table list", K(tablet_id)); + } else { + MdsTableBase *p_mds_table = static_cast(mds_table_list.list_head_); + if (p_mds_table->is_removed_from_t3m()) { + // jsut skip it + } else if (FALSE_IT(rec_scn = p_mds_table->get_rec_scn())) { + } else if (!rec_scn.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "get invalid rec scn", KR(ret)); + } else { + min_rec_scn = std::min(min_rec_scn, rec_scn); + } + } + // true means iterating the next mds table + return OB_SUCCESS == ret; + }; + if (OB_FAIL(mds_table_map_.for_each(get_scn_op))) { + MDS_LOG(WARN, "fail to do for_each in map", KR(ret)); + } + // todo zk: retry + if (OB_FAIL(ret)) { + min_rec_scn = SCN::min_scn(); + } + } + return min_rec_scn; +} + +DEF_TO_STRING(ObMdsTableMgr) +{ + int64_t pos = 0; + J_OBJ_START(); + J_KV(KP(this), K_(is_inited), K_(rec_log_ts), KPC_(ls)); + J_OBJ_END(); + return pos; +} + +int MdsTableFreezeGuard::init(ObMdsTableMgr *mds_mgr) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_ISNULL(mds_mgr)) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG(WARN, "invalid tx data table", KR(ret)); + } else { + can_freeze_ = (false == ATOMIC_CAS(&(mds_mgr->is_freezing_), false, true)); + if (can_freeze_) { + mds_mgr_ = mds_mgr; + } + } + return ret; +} + +void MdsTableFreezeGuard::reset() +{ + can_freeze_ = false; + if (OB_NOT_NULL(mds_mgr_)) { + ATOMIC_STORE(&(mds_mgr_->is_freezing_), false); + mds_mgr_ = nullptr; + } +} + +MdsTableMgrHandle::MdsTableMgrHandle() + : mgr_(nullptr) +{ +} + +MdsTableMgrHandle::~MdsTableMgrHandle() +{ + reset(); +} + +int MdsTableMgrHandle::reset() +{ + if (OB_NOT_NULL(mgr_)) { + mgr_->dec_ref(); + } + mgr_ = nullptr; + return OB_SUCCESS; +} + +int MdsTableMgrHandle::set_mds_table_mgr(ObMdsTableMgr *mds_table_mgr) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(mds_table_mgr)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), KP(mds_table_mgr), K(lbt())); + } else { + reset(); + mgr_ = mds_table_mgr; + mgr_->inc_ref(); + } + return ret; +} + +} // namespace mds +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/multi_data_source/mds_table_mgr.h b/src/storage/multi_data_source/mds_table_mgr.h new file mode 100644 index 000000000..3f8f924f7 --- /dev/null +++ b/src/storage/multi_data_source/mds_table_mgr.h @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2021 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 SHARE_STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_MGR_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_MDS_TABLE_MGR_H + +#include "lib/lock/ob_tc_rwlock.h" +#include "meta_programming/ob_type_traits.h" +#include "storage/checkpoint/ob_common_checkpoint.h" +#include "storage/multi_data_source/runtime_utility/list_helper.h" +#include "lib/hash/ob_linear_hash_map.h" + +namespace oceanbase { +namespace storage { +class ObLS; +class ObTabletHandle; +namespace mds { +class MdsTableFreezeGuard; +class MdsTableBase; +class ObMdsTableMgr final : public checkpoint::ObCommonCheckpoint +{ + using MdsTableMap = common::ObLinearHashMap>; + friend MdsTableFreezeGuard; +public: + ObMdsTableMgr() + : is_inited_(false), + is_freezing_(false), + rec_log_ts_(0), + ref_cnt_(0), + mds_table_cnt_(0), + ls_(nullptr), + mds_table_map_() {} + ~ObMdsTableMgr() { destroy(); } + + int init(ObLS *ls); + int reset(); + void destroy(); + int register_to_mds_table_mgr(MdsTableBase *p_mds_table); + int unregister_from_mds_table_mgr(MdsTableBase *p_mds_table); + template &))> + int for_each_mds_table_list(OP &&op) { + return mds_table_map_.for_each(op); + } + + DECLARE_TO_STRING; + + +public: // derived from ObCommonCheckpoint + virtual share::SCN get_rec_scn() override; + virtual int flush(share::SCN recycle_scn, bool need_freeze = true) override; + virtual ObTabletID get_tablet_id() const override { return ObTabletID(0); } + virtual bool is_flushing() const override { return false; } + +public: // getter and setter + void inc_ref() { ATOMIC_INC(&ref_cnt_); }; + void dec_ref() { ATOMIC_DEC(&ref_cnt_); }; + int64_t get_ref() { return ATOMIC_LOAD(&ref_cnt_); } + int64_t get_mds_table_cnt() { return ATOMIC_LOAD(&mds_table_cnt_); } + +private: + bool has_flushing_mds_table_(share::ObLSID &ls_id, ObTabletID &tablet_id); + +private: + bool is_inited_; + bool is_freezing_; + int64_t rec_log_ts_; + int64_t ref_cnt_; + int64_t mds_table_cnt_; + ObLS *ls_; + MdsTableMap mds_table_map_; +}; + +class MdsTableFreezeGuard +{ +public: + MdsTableFreezeGuard() : can_freeze_(false), mds_mgr_(nullptr) {} + ~MdsTableFreezeGuard() { reset(); } + + int init(ObMdsTableMgr *mds_mgr); + void reset(); + bool can_freeze() { return can_freeze_; } + +public: + bool can_freeze_; + ObMdsTableMgr *mds_mgr_; +}; + +class MdsTableMgrHandle +{ +public: + MdsTableMgrHandle(); + ~MdsTableMgrHandle(); + MdsTableMgrHandle(const MdsTableMgrHandle &other) = delete; + MdsTableMgrHandle &operator= (const MdsTableMgrHandle &other) = delete; + + int reset(); + int set_mds_table_mgr(ObMdsTableMgr *mds_table_mgr); + bool is_valid() const { return OB_NOT_NULL(mgr_); } + + OB_INLINE ObMdsTableMgr *get_mds_table_mgr() { return mgr_; } + OB_INLINE const ObMdsTableMgr *get_mds_table_mgr() const { return mgr_; } + + TO_STRING_KV(KPC_(mgr)); +private: + ObMdsTableMgr *mgr_; +}; + + +} // namespace mds +} // namespace storage +} // namespace oceanbase + +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_unit.h b/src/storage/multi_data_source/mds_unit.h new file mode 100644 index 000000000..e64d4facb --- /dev/null +++ b/src/storage/multi_data_source/mds_unit.h @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2023 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 STORAGE_MULTI_DATA_SOURCE_MDS_UNIT_H +#define STORAGE_MULTI_DATA_SOURCE_MDS_UNIT_H + +#include "lib/lock/ob_small_spin_lock.h" +#include "lib/ob_errno.h" +#include "lib/utility/utility.h" +#include "mds_row.h" +#include "share/scn.h" +#include "storage/multi_data_source/mds_node.h" +#include "storage/multi_data_source/runtime_utility/list_helper.h" +#include "storage/multi_data_source/runtime_utility/common_define.h" +#include "storage/multi_data_source/compile_utility/mds_dummy_key.h" +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#include +#include +#include "mds_table_base.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +template +using Row = MdsRow; +template +struct KvPair : public ListNode> +{ + KvPair() = default; + bool operator<(const KvPair &rhs) const { return k_ < rhs.k_; } + bool operator==(const KvPair &rhs) const { return k_ == rhs.k_; } + TO_STRING_KV(K_(k), K_(v)); + K k_; + V v_; +}; +// multi row defination +template +class MdsUnit final : public MdsUnitBase +{ +public: + typedef K key_type; + typedef V value_type; +public:// iterator defination + template + struct IteratorBase; + template + struct NormalIterator; + template + struct ReverseIterator; + using iterator = NormalIterator>>; + using const_iterator = NormalIterator>>; + using reverse_iterator = ReverseIterator>>; + using const_reverse_iterator = ReverseIterator>>; + iterator begin(); + iterator end(); + const_iterator cbegin(); + const_iterator cend(); + reverse_iterator rbegin(); + reverse_iterator rend(); + const_reverse_iterator crbegin(); + const_reverse_iterator crend(); +public: + MdsUnit(); + ~MdsUnit(); +public: + template + int set(MdsTableBase *p_mds_table, + const K &key, + Value &&value, + MdsCtx &ctx, + const int64_t lock_timeout_us, + const bool is_for_remove = false); + template + int replay(MdsTableBase *p_mds_table, + const K &key, + Value &&value, + MdsCtx &ctx, + const share::SCN scn, + const bool is_for_remove = false); + template + int get_snapshot(const K &key, + OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const; + template + int get_by_writer(const K &key, + OP &&op, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const; + template + int get_latest(const K &key, OP &&op, const int64_t read_seq) const; + template + int scan_KV_row(DUMP_OP &&op, + share::SCN &flush_scn, + const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const bool for_flush) const; + template + int for_each_node_on_row(OP &&op) const; + template + int for_each_row(OP &&op); + void lock() const { lock_.wrlock(); } + void unlock() const { lock_.unlock(); } + int fill_virtual_info(ObIArray &mds_node_info_array, const int64_t unit_id) const; + TO_STRING_KV(K_(multi_row_list)); +public: + template + void report_event_(const char (&event_str)[N], + const K &key, + const char *file = __builtin_FILE(), + const uint32_t line = __builtin_LINE(), + const char *function_name = __builtin_FUNCTION()) const; + const Row *get_row_from_list_(const K &key) const; + int insert_empty_kv_to_list_(const K &key, Row *&row, MdsTableBase *p_mds_table); + SortedList>, SORT_TYPE::ASC> multi_row_list_; + mutable MdsLock lock_; +}; + +// signal row defination +template +class MdsUnit final : public MdsUnitBase +{ +public: + typedef DummyKey key_type; + typedef V value_type; +public:// iterator defination + template + struct IteratorBase; + template + struct NormalIterator; + template + struct ReverseIterator; + using iterator = NormalIterator>>; + using const_iterator = NormalIterator>>; + using reverse_iterator = ReverseIterator>>; + using const_reverse_iterator = ReverseIterator>>; + iterator begin(); + iterator end(); + const_iterator cbegin(); + const_iterator cend(); + reverse_iterator rbegin(); + reverse_iterator rend(); + const_reverse_iterator crbegin(); + const_reverse_iterator crend(); +public: + MdsUnit(); + template + int set(MdsTableBase *p_mds_table, Value &&value, MdsCtx &ctx, const int64_t lock_timeout_us); + template + int replay(MdsTableBase *p_mds_table, Value &&value, MdsCtx &ctx, const share::SCN scn); + template + int get_snapshot(OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const; + template + int get_by_writer(OP &&op, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const; + template + int get_latest(OP &&op, const int64_t read_seqs) const; + template + int scan_KV_row(DUMP_OP &&op, + share::SCN &flush_scn, + const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const bool for_flush) const; + template + int for_each_node_on_row(OP &&op) const; + template + int for_each_row(OP &&op) const; + void lock() const { lock_.wrlock(); } + void unlock() const { lock_.unlock(); } + int fill_virtual_info(ObIArray &mds_node_info_array, const int64_t unit_id) const; + TO_STRING_KV(K_(single_row)); +public: + KvPair> single_row_; + mutable MdsLock lock_; +}; +} +} +} + +#ifndef STORAGE_MULTI_DATA_SOURCE_MDS_UNIT_H_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_UNIT_H_IPP +#include "mds_unit.ipp" +#endif + +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_unit.ipp b/src/storage/multi_data_source/mds_unit.ipp new file mode 100644 index 000000000..f5796e7e8 --- /dev/null +++ b/src/storage/multi_data_source/mds_unit.ipp @@ -0,0 +1,796 @@ +/** + * Copyright (c) 2023 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 STORAGE_MULTI_DATA_SOURCE_MDS_UNIT_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_UNIT_IPP + +#include "lib/list/ob_dlist.h" +#include "observer/virtual_table/ob_mds_event_buffer.h" +#include "share/ob_errno.h" +#ifndef STORAGE_MULTI_DATA_SOURCE_MDS_UNIT_H_IPP +#define STORAGE_MULTI_DATA_SOURCE_MDS_UNIT_H_IPP +#include "mds_unit.h" +#endif + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +/************************************MULTI ROW METHOD DEFINATION***********************************/ + +template +template +struct MdsUnit::IteratorBase {// Bidirectional iterators + // iterator traits + using difference_type = int64_t; + using value_type = ValueType; + using pointer = ValueType *; + using reference = ValueType &; + using iterator_category = std::bidirectional_iterator_tag; + using row_type = Row;// extra + // method needed define + IteratorBase() : p_kv_(nullptr) {} + IteratorBase(ValueType *val) : p_kv_(val) {} + IteratorBase(const IteratorBase &rhs) : p_kv_(rhs.p_kv_) {} + IteratorBase &operator=(const IteratorBase &rhs) { p_kv_ = rhs.p_kv_; return *this; } + bool operator==(const IteratorBase &rhs) { return p_kv_ == rhs.p_kv_; } + bool operator!=(const IteratorBase &rhs) { return p_kv_ != rhs.p_kv_; } + ValueType &operator*() { return *p_kv_; } + ValueType *operator->() { return p_kv_; } + KvPair> *p_kv_; +}; + +template +template +struct MdsUnit::NormalIterator : public IteratorBase { + NormalIterator() : IteratorBase() {} + NormalIterator(const NormalIterator &rhs) : IteratorBase(rhs) {} + NormalIterator(ValueType *val) : IteratorBase(val) {} + NormalIterator &operator++() { + IteratorBase::p_kv_ = (KvPair> *)IteratorBase::p_kv_->next(); + return *this; + } + NormalIterator operator++(int) { + NormalIterator ret_val = *this; + ++(*this); + return ret_val; + } + NormalIterator &operator--() { + IteratorBase::p_kv_ = (KvPair> *)IteratorBase::p_kv_->prev(); + return *this; + } + NormalIterator operator--(int) { + NormalIterator ret_val = *this; + ++(*this); + return ret_val; + } +}; + +template +template +struct MdsUnit::ReverseIterator : public IteratorBase { + ReverseIterator() : IteratorBase() {} + ReverseIterator(const ReverseIterator &rhs) : IteratorBase(rhs) {} + ReverseIterator(ValueType *val) : IteratorBase(val) {} + ReverseIterator &operator++() { + IteratorBase::p_kv_ = (KvPair> *)IteratorBase::p_kv_->prev(); + return *this; + } + ReverseIterator operator++(int) { + ReverseIterator ret_val = *this; + ++(*this); + return ret_val; + } + ReverseIterator &operator--() { + IteratorBase::p_kv_ = (KvPair> *)IteratorBase::p_kv_->next(); + return *this; + } + ReverseIterator operator--(int) { + ReverseIterator ret_val = *this; + ++(*this); + return ret_val; + } +}; + +template +typename MdsUnit::iterator MdsUnit::begin() +{ return iterator((KvPair>*)multi_row_list_.list_head_); } +template +typename MdsUnit::iterator MdsUnit::end() +{ return iterator(nullptr); } +template +typename MdsUnit::const_iterator MdsUnit::cbegin() +{ return const_iterator((KvPair>*)multi_row_list_.list_head_); } +template +typename MdsUnit::const_iterator MdsUnit::cend() +{ return const_iterator(nullptr); } +template +typename MdsUnit::reverse_iterator MdsUnit::rbegin() +{ return reverse_iterator((KvPair>*)multi_row_list_.list_tail_); } +template +typename MdsUnit::reverse_iterator MdsUnit::rend() +{ return reverse_iterator(nullptr); } +template +typename MdsUnit::const_reverse_iterator MdsUnit::crbegin() +{ return const_reverse_iterator((KvPair>*)multi_row_list_.list_tail_); } +template +typename MdsUnit::const_reverse_iterator MdsUnit::crend() +{ return const_reverse_iterator(nullptr); } + +template +MdsUnit::MdsUnit() {} + +template +MdsUnit::~MdsUnit() +{ + #define PRINT_WRAPPER KR(ret) + int ret = OB_SUCCESS; + if (!multi_row_list_.empty()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_DESTROY(WARN, "there are still valid data in this unit, they will be detroyed here"); + multi_row_list_.for_each_node_from_head_to_tail_until_true( + [&ret, this](const KvPair> &kv_pair) { + MDS_LOG_DESTROY(WARN, "destroy row when unit destroy", K(kv_pair)); + KvPair> &kv = const_cast> &>(kv_pair); + ListNode>> *p_kv = static_cast>>*>(&kv); + multi_row_list_.del(p_kv); + MdsFactory::destroy(p_kv); + return false; + }); + } + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::for_each_node_on_row(OP &&op) const +{ + #define PRINT_WRAPPER KR(ret) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsWLockGuard lg(lock_); + CLICK(); + multi_row_list_.for_each_node_from_head_to_tail_until_true( + [&op, &ret](const KvPair> &kv_row) { + MDS_TG(1_ms); + const K *p_k = &kv_row.k_; + const Row &row = kv_row.v_; + if (MDS_FAIL(row.for_each_node_from_tail_to_head(std::forward(op)))) { + MDS_LOG_SCAN(WARN, "fail to scan node on row", KPC(p_k), K(kv_row)); + } + return OB_SUCCESS != ret;// keep scanning until meet failure + }); + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::for_each_row(OP &&op)// node maybe recycled in this function +{ + #define PRINT_WRAPPER KR(ret) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsWLockGuard lg(lock_); + CLICK(); + multi_row_list_.for_each_node_from_head_to_tail_until_true( + [&op, &ret, this](const KvPair> &kv_row) mutable { + MDS_TG(1_ms); + const K *p_k = &kv_row.k_; + const Row &row = kv_row.v_; + if (MDS_FAIL(op(row))) { + MDS_LOG_SCAN(WARN, "fail to scan row", KPC(p_k), K(kv_row)); + } + if (row.sorted_list_.empty()) {// if this row is recycled, just delete it + KvPair> *p_kv = &const_cast> &>(kv_row); + multi_row_list_.del(p_kv); + MdsFactory::destroy(p_kv); + } + return OB_SUCCESS != ret;// keep scanning until meet failure + }); + MDS_LOG_SCAN(TRACE, "for_each_row done", K_(multi_row_list)); + return ret; + #undef PRINT_WRAPPER +} + +template +const Row *MdsUnit::get_row_from_list_(const K &key) const +{ + const Row *row = nullptr; + multi_row_list_.for_each_node_from_head_to_tail_until_true( + [&row, &key](const KvPair> &kv_pair) { + if (kv_pair.k_ == key) { + row = &const_cast &>(kv_pair.v_); + } + return nullptr != row; + } + ); + return row; +} + +template +int MdsUnit::insert_empty_kv_to_list_(const K &key, Row *&row, MdsTableBase *p_mds_table) +{ + #define PRINT_WRAPPER KR(ret), K(key), K(typeid(K).name()), K(typeid(V).name()) + int ret = OB_SUCCESS; + MDS_TG(1_ms); + KvPair> *p_kv; + set_mds_mem_check_thread_local_info(p_mds_table->ls_id_, + p_mds_table->tablet_id_, + typeid(p_kv).name()); + if (MDS_FAIL(MdsFactory::create(p_kv))) { + MDS_LOG_SET(WARN, "MdsUnit create kv pair failed"); + } else if (FALSE_IT(p_kv->v_.p_mds_unit_ = this)) { + } else if (MDS_FAIL(common::meta::copy_or_assign(key, p_kv->k_))) { + MDS_LOG_SET(ERROR, "copy user key failed"); + } else { + p_kv->v_.key_ = &(p_kv->k_); + multi_row_list_.insert(p_kv); + row = &(p_kv->v_); + report_event_("CREATE_KEY", key); + } + reset_mds_mem_check_thread_local_info(); + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::set(MdsTableBase *p_mds_table, + const K &key, + Value &&value, + MdsCtx &ctx, + const int64_t lock_timeout_us, + const bool is_for_remove) +{ + #define PRINT_WRAPPER KR(ret), K(key), K(value), K(ctx), K(lock_timeout_us), K(is_for_remove) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsWLockGuard lg(lock_); + CLICK(); + Row *mds_row = const_cast *>(get_row_from_list_(key)); + if (OB_ISNULL(mds_row)) { + if (MDS_FAIL(insert_empty_kv_to_list_(key, mds_row, p_mds_table))) { + MDS_LOG_SET(WARN, "insert new key to unit failed"); + } else { + MDS_LOG_SET(INFO, "insert new key to unit"); + } + } + if (OB_SUCC(ret)) { + if (MDS_FAIL(mds_row->set(std::forward(value), + ctx, + lock_timeout_us, + is_for_remove))) { + MDS_LOG_SET(WARN, "MdsUnit set value failed"); + } else { + MDS_LOG_SET(TRACE, "MdsUnit set value success"); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::replay(MdsTableBase *p_mds_table, + const K &key, + Value &&value, + MdsCtx &ctx, + const share::SCN scn, + const bool is_for_remove) +{ + #define PRINT_WRAPPER KR(ret), K(key), K(value), K(ctx), K(scn), K(is_for_remove) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsWLockGuard lg(lock_); + CLICK(); + Row *mds_row = const_cast *>(get_row_from_list_(key)); + if (OB_ISNULL(mds_row)) { + if (MDS_FAIL(insert_empty_kv_to_list_(key, mds_row, p_mds_table))) { + MDS_LOG_SET(WARN, "insert new key to unit failed"); + } else { + MDS_LOG_SET(INFO, "insert new key to unit"); + } + } + if (OB_SUCC(ret)) { + if (MDS_FAIL(mds_row->replay(std::forward(value), + ctx, + scn, + is_for_remove))) { + MDS_LOG_SET(WARN, "MdsUnit set value failed"); + } else { + MDS_LOG_SET(TRACE, "MdsUnit set value success"); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::get_snapshot(const K &key, + OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t lock_timeout_us) const +{ + #define PRINT_WRAPPER KR(ret), K(key), K(typeid(OP).name()), K(snapshot), K(read_seq),\ + K(lock_timeout_us) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsRLockGuard lg(lock_); + CLICK(); + const Row *mds_row = get_row_from_list_(key); + if (OB_ISNULL(mds_row)) { + ret = OB_ENTRY_NOT_EXIST; + MDS_LOG_GET(WARN, "row key not exist"); + } else if (MDS_FAIL(mds_row->get_snapshot(std::forward(read_op), + snapshot, + read_seq, + lock_timeout_us))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG_GET(WARN, "MdsUnit get_snapshot failed"); + } + } else { + MDS_LOG_GET(TRACE, "MdsUnit get_snapshot success"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::get_by_writer(const K &key, + OP &&read_op, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t lock_timeout_us) const +{ + #define PRINT_WRAPPER KR(ret), K(key), K(typeid(OP).name()), K(writer), K(snapshot), K(read_seq),\ + K(lock_timeout_us) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsRLockGuard lg(lock_); + CLICK(); + const Row *mds_row = get_row_from_list_(key); + if (OB_ISNULL(mds_row)) { + ret = OB_ENTRY_NOT_EXIST; + MDS_LOG_GET(WARN, "row key not exist"); + } else if (MDS_FAIL(mds_row->get_by_writer(std::forward(read_op), + writer, + snapshot, + read_seq, + lock_timeout_us))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG_GET(WARN, "MdsUnit get_by_writer failed"); + } + } else { + MDS_LOG_GET(TRACE, "MdsUnit get_by_writer success"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::get_latest(const K &key, OP &&read_op, const int64_t read_seq) const +{ + #define PRINT_WRAPPER KR(ret), K(key), K(typeid(OP).name()), K(read_seq) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsRLockGuard lg(lock_); + CLICK(); + const Row *mds_row = get_row_from_list_(key); + if (OB_ISNULL(mds_row)) { + ret = OB_ENTRY_NOT_EXIST; + MDS_LOG_GET(WARN, "row key not exist"); + } else if (MDS_FAIL(mds_row->get_latest(std::forward(read_op), read_seq))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG_GET(WARN, "MdsUnit get_latest failed"); + } + } else { + MDS_LOG_GET(TRACE, "MdsUnit get_latest success"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::scan_KV_row(DUMP_OP &&op, + share::SCN &flush_scn, + const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const bool for_flush) const +{ + #define PRINT_WRAPPER KR(ret), K(flush_scn), K(for_flush) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsRLockGuard lg(lock_); + CLICK(); + MdsDumpKV kv; + multi_row_list_.for_each_node_from_head_to_tail_until_true( + [&op, flush_scn, &ret, &kv, mds_table_id, mds_unit_id, for_flush](const KvPair> &kv_row) { + MDS_TG(10_ms); + if (MDS_FAIL(kv.k_.init(mds_table_id, + mds_unit_id, + kv_row.k_, + DefaultAllocator::get_instance()))) { + MDS_LOG_SCAN(WARN, "fail to init MdsDumpKey"); + } else if (MDS_FAIL(kv_row.v_.scan_dump_node_from_tail_to_head(op, + mds_table_id, + mds_unit_id, + kv, + flush_scn, + for_flush))) { + MDS_LOG_SCAN(WARN, "fail to scan dump node on row"); + } + return OB_SUCCESS != ret;// keep scanning until meet failure + } + ); + return ret; + #undef PRINT_WRAPPER +} + +template +int MdsUnit::fill_virtual_info(ObIArray &mds_node_info_array, const int64_t unit_id) const +{ + #define PRINT_WRAPPER KR(ret) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsRLockGuard lg(lock_); + CLICK(); + multi_row_list_.for_each_node_from_head_to_tail_until_true( + [&ret, &mds_node_info_array, unit_id](const KvPair> &kv_row) { + MDS_TG(10_ms); + if (MDS_FAIL(kv_row.v_.fill_virtual_info(kv_row.k_, mds_node_info_array, unit_id))) { + MDS_LOG_SCAN(WARN, "fail to fill virtual info"); + } + return OB_SUCCESS != ret;// keep scanning until meet failure + } + ); + return ret; + #undef PRINT_WRAPPER +} + +template +template +void MdsUnit::report_event_(const char (&event_str)[N], + const K &key, + const char *file, + const uint32_t line, + const char *function_name) const +{ + int ret = OB_SUCCESS; + observer::MdsEvent event; + constexpr int64_t buffer_size = 1_KB; + char stack_buffer[buffer_size] = { 0 }; + int64_t pos = 0; + if (FALSE_IT(databuff_printf(stack_buffer, buffer_size, pos, "%s", to_cstring(key)))) { + } else { + event.key_str_.assign(stack_buffer, pos); + event.event_ = event_str; + observer::MdsEventKey key(MTL_ID(), + MdsUnitBase::p_mds_table_->ls_id_, + MdsUnitBase::p_mds_table_->tablet_id_); + observer::ObMdsEventBuffer::append(key, event, file, line, function_name); + } +} + +/************************************SIGNLE ROW METHOD DEFINATION**********************************/ + +template +MdsUnit::MdsUnit() +{ + single_row_.v_.key_ = &(single_row_.k_); + single_row_.v_.p_mds_unit_ = this; +} + +template +template +struct MdsUnit::IteratorBase {// Bidirectional iterators + // iterator traits + using difference_type = int64_t; + using value_type = ValueType; + using pointer = ValueType *; + using reference = ValueType &; + using iterator_category = std::bidirectional_iterator_tag; + using row_type = Row;// extra + // method needed define + IteratorBase() : p_kv_(nullptr) {} + IteratorBase(ValueType *val) : p_kv_(val) {} + IteratorBase(const IteratorBase &rhs) : p_kv_(rhs.p_kv_) {} + IteratorBase &operator=(const IteratorBase &rhs) { p_kv_ = rhs.p_kv_; } + bool operator==(const IteratorBase &rhs) { return p_kv_ == rhs.p_kv_; } + bool operator!=(const IteratorBase &rhs) { return p_kv_ != rhs.p_kv_; } + ValueType &operator*() { return *p_kv_; } + ValueType *operator->() { return p_kv_; } + KvPair> *p_kv_; +}; + +template +template +struct MdsUnit::NormalIterator : public IteratorBase { + NormalIterator() : IteratorBase() {} + NormalIterator(const NormalIterator &rhs) : IteratorBase(rhs) {} + NormalIterator(ValueType *val) : IteratorBase(val) {} + NormalIterator &operator++() { + IteratorBase::p_kv_ = (KvPair> *)IteratorBase::p_kv_->next(); + return *this; + } + NormalIterator operator++(int) { + NormalIterator ret_val = *this; + ++(*this); + return ret_val; + } + NormalIterator &operator--() { + IteratorBase::p_kv_ = (KvPair> *)IteratorBase::p_kv_->prev(); + return *this; + } + NormalIterator operator--(int) { + NormalIterator ret_val = *this; + ++(*this); + return ret_val; + } +}; + +template +template +struct MdsUnit::ReverseIterator : public IteratorBase { + ReverseIterator() : IteratorBase() {} + ReverseIterator(const ReverseIterator &rhs) : IteratorBase(rhs) {} + ReverseIterator(ValueType *val) : IteratorBase(val) {} + ReverseIterator &operator++() { + IteratorBase::p_kv_ = (KvPair> *)IteratorBase::p_kv_->prev(); + return *this; + } + ReverseIterator operator++(int) { + ReverseIterator ret_val = *this; + ++(*this); + return ret_val; + } + ReverseIterator &operator--() { + IteratorBase::p_kv_ = (KvPair> *)IteratorBase::p_kv_->next(); + return *this; + } + ReverseIterator operator--(int) { + ReverseIterator ret_val = *this; + ++(*this); + return ret_val; + } +}; + +template +typename MdsUnit::iterator MdsUnit::begin() +{ return iterator(&single_row_); } +template +typename MdsUnit::iterator MdsUnit::end() +{ return iterator(nullptr); } +template +typename MdsUnit::const_iterator MdsUnit::cbegin() +{ return const_iterator(&single_row_); } +template +typename MdsUnit::const_iterator MdsUnit::cend() +{ return const_iterator(nullptr); } +template +typename MdsUnit::reverse_iterator MdsUnit::rbegin() +{ return reverse_iterator(&single_row_); } +template +typename MdsUnit::reverse_iterator MdsUnit::rend() +{ return reverse_iterator(nullptr); } +template +typename MdsUnit::const_reverse_iterator MdsUnit::crbegin() +{ return const_reverse_iterator(&single_row_); } +template +typename MdsUnit::const_reverse_iterator MdsUnit::crend() +{ return const_reverse_iterator(nullptr); } + +template +template +int MdsUnit::set(MdsTableBase *p_mds_table, + Value &&value, + MdsCtx &ctx, + const int64_t lock_timeout_us) +{ + #define PRINT_WRAPPER KR(ret), K(value), K(ctx), K(lock_timeout_us) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsWLockGuard lg(lock_); + CLICK(); + if (MDS_FAIL(single_row_.v_.set(std::forward(value), ctx, lock_timeout_us))) { + MDS_LOG_SET(WARN, "MdsUnit set value failed"); + } else { + MDS_LOG_SET(TRACE, "MdsUnit set value success"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::replay(MdsTableBase *p_mds_table, + Value &&value, + MdsCtx &ctx, + const share::SCN scn) +{ + #define PRINT_WRAPPER KR(ret), K(value), K(ctx), K(scn) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsWLockGuard lg(lock_); + CLICK(); + if (MDS_FAIL(single_row_.v_.replay(std::forward(value), ctx, scn))) { + MDS_LOG_SET(WARN, "MdsUnit replay value failed"); + } else { + MDS_LOG_SET(TRACE, "MdsUnit replay value success"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::get_snapshot(OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t lock_timeout_us) const +{ + #define PRINT_WRAPPER KR(ret), K(typeid(OP).name()), K(read_seq), K(lock_timeout_us) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsRLockGuard lg(lock_); + CLICK(); + if (MDS_FAIL(single_row_.v_.get_snapshot(std::forward(read_op), + snapshot, + read_seq, + lock_timeout_us))) { + if (OB_SNAPSHOT_DISCARDED != ret) { + MDS_LOG_GET(WARN, "MdsUnit get_snapshot failed"); + } + } else { + MDS_LOG_GET(TRACE, "MdsUnit get_snapshot success"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::get_by_writer(OP &&read_op, + const MdsWriter &writer, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t lock_timeout_us) const +{ + #define PRINT_WRAPPER KR(ret), K(typeid(OP).name()), K(writer), K(snapshot), K(read_seq),\ + K(lock_timeout_us) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsRLockGuard lg(lock_); + CLICK(); + if (MDS_FAIL(single_row_.v_.get_by_writer(std::forward(read_op), + writer, + snapshot, + read_seq, + lock_timeout_us))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG_GET(WARN, "MdsUnit get_by_writer failed"); + } + } else { + MDS_LOG_GET(TRACE, "MdsUnit get_by_writer success"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::get_latest(OP &&read_op, const int64_t read_seq) const +{ + #define PRINT_WRAPPER KR(ret), K(typeid(OP).name()), K(read_seq) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsRLockGuard lg(lock_); + CLICK(); + if (MDS_FAIL(single_row_.v_.get_latest(std::forward(read_op), read_seq))) { + if (OB_UNLIKELY(OB_SNAPSHOT_DISCARDED != ret)) { + MDS_LOG_GET(WARN, "MdsUnit get_latest failed"); + } + } else { + MDS_LOG_GET(TRACE, "MdsUnit get_latest success"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::scan_KV_row(DUMP_OP &&op, + share::SCN &flush_scn, + const uint8_t mds_table_id, + const uint8_t mds_unit_id, + const bool for_flush) const +{ + #define PRINT_WRAPPER KR(ret), K(kv), K(typeid(op).name()), K(flush_scn), K(for_flush) + MDS_TG(100_ms); + int ret = OB_SUCCESS; + MdsRLockGuard lg(lock_); + CLICK(); + MdsDumpKV kv; + if (MDS_FAIL(kv.k_.init(mds_table_id, + mds_unit_id, + DummyKey(), + DefaultAllocator::get_instance()))) { + MDS_LOG_SCAN(WARN, "init key failed"); + } else if (MDS_FAIL(single_row_.v_.scan_dump_node_from_tail_to_head(std::forward(op), + mds_table_id, + mds_unit_id, + kv, + flush_scn, + for_flush))) { + MDS_LOG_SCAN(WARN, "scan single row to dump failed"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::for_each_node_on_row(OP &&op) const { + #define PRINT_WRAPPER KR(ret) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsWLockGuard lg(lock_); + CLICK(); + if (MDS_FAIL(single_row_.v_.for_each_node_from_tail_to_head(std::forward(op)))) { + MDS_LOG_SCAN(WARN, "fail to scan node on single row"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +template +int MdsUnit::for_each_row(OP &&op) const { + #define PRINT_WRAPPER KR(ret) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsWLockGuard lg(lock_); + CLICK(); + if (MDS_FAIL(op(single_row_.v_))) { + MDS_LOG_SCAN(WARN, "fail to scan single row"); + } + MDS_LOG_SCAN(TRACE, "for_each_row done", K_(single_row_.v)); + return ret; + #undef PRINT_WRAPPER +} + +template +int MdsUnit::fill_virtual_info(ObIArray &mds_node_info_array, const int64_t unit_id) const +{ + #define PRINT_WRAPPER KR(ret) + int ret = OB_SUCCESS; + MDS_TG(10_ms); + MdsRLockGuard lg(lock_); + CLICK(); + if (MDS_FAIL(single_row_.v_.fill_virtual_info(DummyKey(), mds_node_info_array, unit_id))) { + MDS_LOG_SCAN(WARN, "fail to fill_virtual_info"); + } + return ret; + #undef PRINT_WRAPPER +} + +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_writer.cpp b/src/storage/multi_data_source/mds_writer.cpp new file mode 100644 index 000000000..bc1c32c30 --- /dev/null +++ b/src/storage/multi_data_source/mds_writer.cpp @@ -0,0 +1,22 @@ +#include "mds_writer.h" +#include "storage/tx/ob_trans_define.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +MdsWriter::MdsWriter(const WriterType writer_type, const int64_t writer_id) : writer_type_(writer_type), writer_id_(writer_id) {} + +MdsWriter::MdsWriter(const transaction::ObTransID &tx_id) : writer_type_(WriterType::TRANSACTION), writer_id_(tx_id.get_id()) {} + +bool MdsWriter::is_valid() const +{ + return writer_type_ != WriterType::UNKNOWN_WRITER && writer_type_ < WriterType::END; +} + +} +} +} \ No newline at end of file diff --git a/src/storage/multi_data_source/mds_writer.h b/src/storage/multi_data_source/mds_writer.h new file mode 100644 index 000000000..1cddad231 --- /dev/null +++ b/src/storage/multi_data_source/mds_writer.h @@ -0,0 +1,41 @@ +#ifndef SRC_STORAGE_MULTI_DATA_SOURCE_MDS_WRITTER_H +#define SRC_STORAGE_MULTI_DATA_SOURCE_MDS_WRITTER_H + +#include +#include "lib/utility/ob_print_utils.h" +#include "runtime_utility/common_define.h" + +namespace oceanbase +{ +namespace transaction +{ +class ObTransID; +} +namespace storage +{ +namespace mds +{ +struct MdsWriter +{ + OB_UNIS_VERSION(1); +public: + MdsWriter() : writer_type_(WriterType::UNKNOWN_WRITER), writer_id_(INVALID_VALUE) {} + MdsWriter(const WriterType writer_type, const int64_t writer_id = DEFAULT_WRITER_ID); + explicit MdsWriter(const transaction::ObTransID &tx_id); + bool operator==(const MdsWriter &rhs) { + return writer_type_ == rhs.writer_type_ && writer_id_ == rhs.writer_id_; + } + bool is_valid() const; + TO_STRING_KV("writer_type", obj_to_string(writer_type_), K_(writer_id)); +public: + static constexpr int64_t DEFAULT_WRITER_ID = 10000; + + WriterType writer_type_; + int64_t writer_id_; +}; +OB_SERIALIZE_MEMBER_TEMP(inline, MdsWriter, writer_type_, writer_id_); +} +} +} + +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/ob_mds_table_merge_dag.cpp b/src/storage/multi_data_source/ob_mds_table_merge_dag.cpp new file mode 100644 index 000000000..df640742f --- /dev/null +++ b/src/storage/multi_data_source/ob_mds_table_merge_dag.cpp @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2021 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 "storage/multi_data_source/ob_mds_table_merge_dag.h" +#include "lib/hash_func/murmur_hash.h" +#include "lib/utility/ob_print_utils.h" +#include "storage/multi_data_source/ob_mds_table_merge_task.h" +#include "storage/tablet/ob_tablet_common.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" + +#define USING_LOG_PREFIX MDS + +using namespace oceanbase::common; +using namespace oceanbase::share; + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +ObMdsTableMergeDag::ObMdsTableMergeDag() + : ObIDag(ObDagType::DAG_TYPE_MDS_TABLE_MERGE), + is_inited_(false) +{ +} + +int ObMdsTableMergeDag::init_by_param(const share::ObIDagInitParam *param) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_ISNULL(param)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(param)); + } else { + const ObMdsTableMergeDagParam *mds_param = static_cast(param); + const share::ObLSID &ls_id = mds_param->ls_id_; + const common::ObTabletID &tablet_id = mds_param->tablet_id_; + ObLSService *ls_service = MTL(ObLSService*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + + if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::MDS_TABLE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id), K(ls_handle)); + } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(tablet_id), K(tablet_handle)); + } else { + compat_mode_ = tablet->get_tablet_meta().compat_mode_; + param_ = *mds_param; + is_inited_ = true; + } + } + + return ret; +} + +bool ObMdsTableMergeDag::operator==(const share::ObIDag &other) const +{ + bool is_same = true; + + if (this == &other) { + is_same = true; + } else if (get_type() != other.get_type()) { + is_same = false; + } else { + const ObMdsTableMergeDag &other_dag = static_cast(other); + is_same = (param_ == other_dag.param_); + } + + return is_same; +} + +int64_t ObMdsTableMergeDag::hash() const +{ + uint64_t hash_val = 0; + hash_val = common::murmurhash(¶m_.ls_id_, sizeof(share::ObLSID), hash_val); + hash_val = common::murmurhash(¶m_.tablet_id_, sizeof(common::ObTabletID), hash_val); + return hash_val; +} + +int ObMdsTableMergeDag::create_first_task() +{ + int ret = OB_SUCCESS; + ObMdsTableMergeTask *task = nullptr; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K_(is_inited)); + } else if (OB_FAIL(alloc_task(task))) { + LOG_WARN("failed to alloc task", K(ret)); + } else if (OB_FAIL(task->init(param_))) { + LOG_WARN("failed to ini task", K(ret), K_(param)); + } else if (OB_FAIL(add_task(*task))) { + LOG_WARN("failed to add task", K(ret)); + } + + return ret; +} + +int ObMdsTableMergeDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("mds table merge dag do not init", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + param_.ls_id_.id(), + static_cast(param_.tablet_id_.id()), + static_cast(param_.flush_scn_.get_val_for_inner_table_field())))){ + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} + +int ObMdsTableMergeDag::fill_dag_key(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(databuff_printf(buf, buf_len, "mds table merge task, ls_id=%ld, tablet_id=%ld, flush_scn=%ld", + param_.ls_id_.id(), param_.tablet_id_.id(), param_.flush_scn_.get_val_for_inner_table_field()))) { + LOG_WARN("failed to fill dag key", K(ret), K_(param)); + } + + return ret; +} + +bool ObMdsTableMergeDag::ignore_warning() +{ + return OB_LS_NOT_EXIST == dag_ret_ + || OB_TABLET_NOT_EXIST == dag_ret_ + || OB_CANCELED == dag_ret_; +} +} // namespace mds +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/multi_data_source/ob_mds_table_merge_dag.h b/src/storage/multi_data_source/ob_mds_table_merge_dag.h new file mode 100644 index 000000000..d5b8da6e4 --- /dev/null +++ b/src/storage/multi_data_source/ob_mds_table_merge_dag.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_MDS_TABLE_MERGE_DAG +#define OCEANBASE_STORAGE_OB_MDS_TABLE_MERGE_DAG + +#include +#include "lib/worker.h" +#include "share/scheduler/ob_dag_scheduler.h" +#include "storage/multi_data_source/ob_mds_table_merge_dag_param.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +class ObMdsTableMergeDag : public share::ObIDag +{ +public: + ObMdsTableMergeDag(); + virtual ~ObMdsTableMergeDag() = default; + ObMdsTableMergeDag(const ObMdsTableMergeDag&) = delete; + ObMdsTableMergeDag &operator=(const ObMdsTableMergeDag&) = delete; + const ObMdsTableMergeDagParam& get_param() const { return param_; } +public: + virtual int init_by_param(const share::ObIDagInitParam *param) override; + virtual bool operator==(const share::ObIDag &other) const override; + virtual int64_t hash() const override; + virtual int create_first_task() override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; + virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; + virtual bool ignore_warning() override; + virtual lib::Worker::CompatMode get_compat_mode() const override { return compat_mode_; } + virtual uint64_t get_consumer_group_id() const override { return consumer_group_id_; } + + INHERIT_TO_STRING_KV("ObIDag", ObIDag, K_(is_inited), K_(compat_mode), K_(param)); +private: + bool is_inited_; + lib::Worker::CompatMode compat_mode_; + ObMdsTableMergeDagParam param_; +}; +} // namespace mds +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_MDS_TABLE_MERGE_DAG diff --git a/src/storage/multi_data_source/ob_mds_table_merge_dag_param.cpp b/src/storage/multi_data_source/ob_mds_table_merge_dag_param.cpp new file mode 100644 index 000000000..15019e00a --- /dev/null +++ b/src/storage/multi_data_source/ob_mds_table_merge_dag_param.cpp @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2021 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 "storage/multi_data_source/ob_mds_table_merge_dag_param.h" + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +ObMdsTableMergeDagParam::ObMdsTableMergeDagParam() + : ls_id_(), + tablet_id_(), + flush_scn_(share::SCN::invalid_scn()) +{ +} +} // namespace mds +} // namespace storage +} // namespace oceanbase \ No newline at end of file diff --git a/src/storage/multi_data_source/ob_mds_table_merge_dag_param.h b/src/storage/multi_data_source/ob_mds_table_merge_dag_param.h new file mode 100644 index 000000000..d3e703efa --- /dev/null +++ b/src/storage/multi_data_source/ob_mds_table_merge_dag_param.h @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_MDS_TABLE_MERGE_PARAM +#define OCEANBASE_STORAGE_OB_MDS_TABLE_MERGE_PARAM + +#include "share/scheduler/ob_dag_scheduler.h" +#include "share/scn.h" +#include "share/ob_ls_id.h" +#include "common/ob_tablet_id.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +class ObMdsTableMergeDagParam : public share::ObIDagInitParam +{ +public: + ObMdsTableMergeDagParam(); + virtual ~ObMdsTableMergeDagParam() = default; +public: + virtual bool is_valid() const override; + bool operator==(const ObMdsTableMergeDagParam &other) const; + + TO_STRING_KV(K_(ls_id), K_(tablet_id), K_(flush_scn)); +public: + share::ObLSID ls_id_; + common::ObTabletID tablet_id_; + share::SCN flush_scn_; +}; + +inline bool ObMdsTableMergeDagParam::is_valid() const +{ + return ls_id_.is_valid() + && tablet_id_.is_valid() + && !tablet_id_.is_ls_inner_tablet() + && flush_scn_.is_valid(); +} + +inline bool ObMdsTableMergeDagParam::operator==(const ObMdsTableMergeDagParam &other) const +{ + return ls_id_ == other.ls_id_ + && tablet_id_ == other.tablet_id_ + && flush_scn_ == other.flush_scn_; +} +} // namespace mds +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_MDS_TABLE_MERGE_PARAM \ No newline at end of file diff --git a/src/storage/multi_data_source/ob_mds_table_merge_task.cpp b/src/storage/multi_data_source/ob_mds_table_merge_task.cpp new file mode 100644 index 000000000..49f3ec718 --- /dev/null +++ b/src/storage/multi_data_source/ob_mds_table_merge_task.cpp @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2021 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 "storage/multi_data_source/ob_mds_table_merge_task.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/ls/ob_ls_get_mod.h" +#include "storage/tablet/ob_tablet_common.h" +#include "storage/tablet/ob_tablet.h" + +#define USING_LOG_PREFIX MDS + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +ObMdsTableMergeTask::ObMdsTableMergeTask() + : ObITask(ObITaskType::TASK_TYPE_MDS_TABLE_MERGE), + is_inited_(false), + param_() +{ +} + +int ObMdsTableMergeTask::init(const ObMdsTableMergeDagParam ¶m) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + } else { + param_ = param; + is_inited_ = true; + } + + return ret; +} + +int ObMdsTableMergeTask::process() +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObLSService *ls_service = MTL(ObLSService*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + const share::ObLSID &ls_id = param_.ls_id_; + const common::ObTabletID &tablet_id = param_.tablet_id_; + const share::SCN &flush_scn = param_.flush_scn_; + + DEBUG_SYNC(AFTER_EMPTY_SHELL_TABLET_CREATE); + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id), K(ls_handle)); + } else if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(ls_id), K(tablet_handle)); + } else if (OB_FAIL(ls->get_tablet_svr()->build_new_tablet_from_mds_table(tablet_id, flush_scn))) { + LOG_WARN("failed to build new tablet from mds table", K(ret), K(ls_id), K(tablet_id), K(flush_scn)); + } + + // always notify flush ret + if (OB_NOT_NULL(tablet) && OB_TMP_FAIL(tablet->notify_mds_table_flush_ret(flush_scn, ret))) { + LOG_WARN("failed to notify mds table flush ret", K(tmp_ret), K(ls_id), K(tablet_id), K(flush_scn), "flush_ret", ret); + } + + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(OB_SUCCESS != tmp_ret)) { + ret = tmp_ret; + } + + return ret; +} +} // namespace mds +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/multi_data_source/ob_mds_table_merge_task.h b/src/storage/multi_data_source/ob_mds_table_merge_task.h new file mode 100644 index 000000000..7d25ab9b4 --- /dev/null +++ b/src/storage/multi_data_source/ob_mds_table_merge_task.h @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_MDS_TABLE_MERGE_TASK +#define OCEANBASE_STORAGE_OB_MDS_TABLE_MERGE_TASK + +#include "share/scheduler/ob_dag_scheduler.h" +#include "storage/multi_data_source/ob_mds_table_merge_dag_param.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ +class ObMdsTableMergeTask : public share::ObITask +{ +public: + ObMdsTableMergeTask(); + virtual ~ObMdsTableMergeTask() = default; + ObMdsTableMergeTask(const ObMdsTableMergeTask&) = delete; + ObMdsTableMergeTask &operator=(const ObMdsTableMergeTask&) = delete; +public: + virtual int process() override; + + int init(const ObMdsTableMergeDagParam ¶m); +private: + bool is_inited_; + ObMdsTableMergeDagParam param_; +}; +} // namespace mds +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_MDS_TABLE_MERGE_TASK diff --git a/src/storage/multi_data_source/runtime_utility/common_define.h b/src/storage/multi_data_source/runtime_utility/common_define.h new file mode 100644 index 000000000..d9b26aef7 --- /dev/null +++ b/src/storage/multi_data_source/runtime_utility/common_define.h @@ -0,0 +1,240 @@ +#ifndef SHARE_STORAGE_MULTI_DATA_SOURCE_UTILITY_COMMON_DEFINE_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_UTILITY_COMMON_DEFINE_H +#include "lib/ob_errno.h" +#include "lib/utility/ob_macro_utils.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/ob_define.h" +#include "lib/oblog/ob_log.h" +#include "src/share/ob_errno.h" +#include "src/share/scn.h" +#include "src/share/ob_occam_time_guard.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +enum class NodePosition { + MDS_TABLE, + DISK, + KV_CACHE, + TABLET, + POSITION_END, +}; + +inline const char *obj_to_string(NodePosition pos) { + const char *ret = "UNKNOWN"; + switch (pos) { + case NodePosition::MDS_TABLE: + ret = "MDS_TABLE"; + break; + case NodePosition::DISK: + ret = "DISK"; + break; + case NodePosition::KV_CACHE: + ret = "KV_CACHE"; + break; + case NodePosition::TABLET: + ret = "TABLET"; + break; + default: + break; + } + return ret; +} + +enum class TwoPhaseCommitState : uint8_t +{ + STATE_INIT = 0, + BEFORE_PREPARE, + ON_PREPARE, + ON_COMMIT, + ON_ABORT, + STATE_END +}; + +static inline const char *obj_to_string(TwoPhaseCommitState state) { + const char *ret = "UNKNOWN"; + switch (state) { + case TwoPhaseCommitState::STATE_INIT: + ret = "INIT"; + break; + case TwoPhaseCommitState::BEFORE_PREPARE: + ret = "BEFORE_PREPARE"; + break; + case TwoPhaseCommitState::ON_PREPARE: + ret = "ON_PREPARE"; + break; + case TwoPhaseCommitState::ON_COMMIT: + ret = "ON_COMMIT"; + break; + case TwoPhaseCommitState::ON_ABORT: + ret = "ON_ABORT"; + break; + default: + break; + } + return ret; +} + +static constexpr bool STATE_CHECK_ALLOWED_MAP[static_cast(TwoPhaseCommitState::STATE_END)] + [static_cast(TwoPhaseCommitState::STATE_END)] = { + {0, 1, 1, 1, 1},// from INIT, can change to any state(in replay phase) + {0, 1, 1, 1, 1},// from BEFORE_PREPARE, just allow to switch to ON_PREPARE/ON_ABORT, may switch to COMMIT in one-phase commit + {0, 0, 1, 1, 1},// from ON_PREPARE, allow to switch to ON_COMMIT/ON_ABORT + {0, 0, 0, 1, 0},// maybe repeat switch to ON_COMMIT + {0, 0, 0, 0, 1},// maybe repeat switch to ON_ABORT +}; + +static inline void check_and_advance_two_phase_commit(TwoPhaseCommitState &state, TwoPhaseCommitState new_state) +{ + OB_ASSERT(STATE_CHECK_ALLOWED_MAP[(int)state][(int)new_state] == true); + state = new_state; +} + +enum class WriterType : uint8_t +{ + UNKNOWN_WRITER = 0, + TRANSACTION, + AUTO_INC_SEQ, + MEDIUM_INFO, + END, +}; + +static inline const char *obj_to_string(WriterType type) { + const char *ret = "UNKNOWN"; + switch (type) { + case WriterType::TRANSACTION: + ret = "TRANS"; + break; + case WriterType::AUTO_INC_SEQ: + ret = "AUTO_INC_SEQ"; + break; + case WriterType::MEDIUM_INFO: + ret = "MEDIUM_INFO"; + break; + default: + break; + } + return ret; +} + +static inline const char *obj_to_string(share::SCN scn) { + const char *ret = nullptr; + if (scn == share::SCN::max_scn()) { + ret = "MAX"; + } else if (scn == share::SCN::min_scn()) { + ret = "MIN"; + } else { + ret = to_cstring(scn); + } + return ret; +} + +enum class MdsNodeType : uint8_t +{ + UNKNOWN_NODE = 0, + SET, + DELETE, + TYPE_END +}; + +static inline const char *obj_to_string(MdsNodeType type) { + const char *ret = "UNKNOWN"; + switch (type) { + case MdsNodeType::SET: + ret = "SET"; + break; + case MdsNodeType::DELETE: + ret = "DELETE"; + break; + default: + break; + } + return ret; +} + +enum LogPhase +{ + INIT, + DESTROY, + SET, + GET, + DUMP, + LOAD, + SCAN, + FLUSH, + GC, + NONE +}; + +constexpr int64_t INVALID_VALUE = -1; +#define MDS_TG(ms) TIMEGUARD_INIT(MDS, ms, 5_s) +#define _MDS_LOG_PHASE(level, phase, info, args...) \ +do {\ + if (phase == mds::LogPhase::NONE) {\ + MDS_LOG(level, info, ##args, PRINT_WRAPPER);\ + } else {\ + constexpr int64_t joined_length = 512;\ + char joined_info[joined_length] = {0};\ + int64_t pos = 0;\ + switch (phase) {\ + case mds::LogPhase::INIT:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[INIT]%s", info);\ + break;\ + case mds::LogPhase::DESTROY:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[DESTROY]%s", info);\ + break;\ + case mds::LogPhase::SET:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[SET]%s", info);\ + break;\ + case mds::LogPhase::GET:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[GET]%s", info);\ + break;\ + case mds::LogPhase::DUMP:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[DUMP]%s", info);\ + break;\ + case mds::LogPhase::LOAD:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[LOAD]%s", info);\ + break;\ + case mds::LogPhase::SCAN:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[SCAN]%s", info);\ + break;\ + case mds::LogPhase::FLUSH:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[FLUSH]%s", info);\ + break;\ + case mds::LogPhase::GC:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[GC]%s", info);\ + break;\ + case mds::LogPhase::NONE:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[NONE]%s", info);\ + break;\ + default:\ + oceanbase::common::databuff_printf(joined_info, joined_length, pos, "[UNKNOWN]%s", info);\ + break;\ + }\ + MDS_LOG(level, joined_info, ##args, PRINT_WRAPPER);\ + }\ +} while(0) + +#define MDS_LOG_INIT(level, info, args...) _MDS_LOG_PHASE(level, mds::LogPhase::INIT, info, ##args) +#define MDS_LOG_DESTROY(level, info, args...) _MDS_LOG_PHASE(level, mds::LogPhase::DESTROY, info, ##args) +#define MDS_LOG_SET(level, info, args...) _MDS_LOG_PHASE(level, mds::LogPhase::SET, info, ##args) +#define MDS_LOG_GET(level, info, args...) _MDS_LOG_PHASE(level, mds::LogPhase::GET, info, ##args) +#define MDS_LOG_DUMP(level, info, args...) _MDS_LOG_PHASE(level, mds::LogPhase::DUMP, info, ##args) +#define MDS_LOG_LOAD(level, info, args...) _MDS_LOG_PHASE(level, mds::LogPhase::LOAD, info, ##args) +#define MDS_LOG_SCAN(level, info, args...) _MDS_LOG_PHASE(level, mds::LogPhase::SCAN, info, ##args) +#define MDS_LOG_FLUSH(level, info, args...) _MDS_LOG_PHASE(level, mds::LogPhase::FLUSH, info, ##args) +#define MDS_LOG_GC(level, info, args...) _MDS_LOG_PHASE(level, mds::LogPhase::GC, info, ##args) +#define MDS_LOG_NONE(level, info, args...) _MDS_LOG_PHASE(level, mds::LogPhase::NONE, info, ##args) + +// flag is needed to rollback logic +#define MDS_FAIL_FLAG(stmt, flag) (CLICK_FAIL(stmt) || FALSE_IT(flag = true)) +#define MDS_FAIL(stmt) (CLICK_FAIL(stmt)) + +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/runtime_utility/list_helper.h b/src/storage/multi_data_source/runtime_utility/list_helper.h new file mode 100644 index 000000000..e16809aa2 --- /dev/null +++ b/src/storage/multi_data_source/runtime_utility/list_helper.h @@ -0,0 +1,307 @@ +#ifndef SRC_STORAGE_MULTI_DATA_SOURCE_UTILITY_LIST_HELPER_H +#define SRC_STORAGE_MULTI_DATA_SOURCE_UTILITY_LIST_HELPER_H + +#include "lib/ob_errno.h" +#include "lib/utility/ob_macro_utils.h" +#include "common_define.h" +#include "src/share/ob_delegate.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +template +class List; + +struct ListNodeBase// erase ListNode type +{ + ListNodeBase() : prev_(nullptr), next_(nullptr) {} + virtual ~ListNodeBase() { reset(); } + ListNodeBase(const ListNodeBase &) = delete; + ListNodeBase(ListNodeBase &&) = delete; + ListNodeBase &operator=(const ListNodeBase &) = delete; + ListNodeBase &operator=(ListNodeBase &&) = delete; + void reset() { prev_= nullptr; next_ = nullptr; } + virtual int64_t to_string(char *, const int64_t) const = 0; + ListNodeBase *prev_; + ListNodeBase *next_; +}; + +template +struct ListNode : public ListNodeBase +{ + ListNode() : ListNodeBase() {} + virtual ~ListNode() { reset(); } + ListNode *prev() { return dynamic_cast *>(prev_); } + ListNode *next() { return dynamic_cast *>(next_); } +}; + +template +struct CompareOperationWrapper +{ + CompareOperationWrapper(T &data) : data_(data) {} + bool operator<(const CompareOperationWrapper &rhs) const { return data_ < rhs.data_; } + bool operator>(const CompareOperationWrapper &rhs) const { return !(data_ < rhs.data_) && !(data_ == rhs.data_); } + bool operator==(const CompareOperationWrapper &rhs) const { return data_ == rhs.data_; } + bool operator>=(const CompareOperationWrapper &rhs) const { return data_ > rhs.data_ || data_ == rhs.data_;} + bool operator<=(const CompareOperationWrapper &rhs) const { return data_ < rhs.data_ || data_ == rhs.data_;} + T &data_; +}; + +struct ListBase// erase List Type +{ + ListBase() : list_head_(nullptr), list_tail_(nullptr) {} + virtual ~ListBase() { clear(); } + void check_invariance_() const { +#ifdef UNITTEST_DEBUG + if (OB_NOT_NULL(list_head_)) { + OB_ASSERT(OB_NOT_NULL(list_tail_)); + OB_ASSERT(OB_ISNULL(list_head_->prev_)); + OB_ASSERT(OB_ISNULL(list_tail_->next_)); + // can reach tail from head + const ListNodeBase *iter = list_head_; + while (iter != list_tail_) { + iter = iter->next_; + } + OB_ASSERT(iter == list_tail_); + } + if (OB_NOT_NULL(list_tail_)) { + OB_ASSERT(OB_NOT_NULL(list_tail_)); + OB_ASSERT(OB_ISNULL(list_head_->prev_)); + OB_ASSERT(OB_ISNULL(list_tail_->next_)); + // can reach head from tail + const ListNodeBase *iter = list_tail_; + while (iter != list_head_) { + iter = iter->prev_; + } + OB_ASSERT(iter == list_head_); + } +#endif + } + int64_t to_string(char *buf, const int64_t buf_len) const { + int64_t pos = 0; + ListNodeBase *iter = list_head_; + common::databuff_printf(buf, buf_len, pos, "list_head:0x%llx", (unsigned long long)list_head_); + common::databuff_printf(buf, buf_len, pos, ", list_tail:0x%llx, list:", (unsigned long long)list_tail_); + int64_t list_len = 0; + while (OB_NOT_NULL(iter)) { + common::databuff_printf(buf, buf_len, pos, "[%s]<->", to_cstring(*iter)); + ++list_len; + iter = iter->next_; + } + common::databuff_printf(buf, buf_len, pos, "NULL, total_size:%ld", list_len); + return pos; + } + ListBase(const ListBase &) = default; + ListBase(ListBase &&) = default; + ListBase &operator=(const ListBase &) = default; + ListBase &operator=(ListBase &&) = default; + void clear() { list_head_ = nullptr; list_tail_ = nullptr; } + bool empty() const { return nullptr == list_head_; } + void append(ListNodeBase *new_node) { + new_node->reset(); + if (OB_ISNULL(list_head_)) {// insert into head + OB_ASSERT(OB_ISNULL(list_tail_)); + list_head_ = new_node; + list_tail_ = new_node; + } else {// insert after tail + OB_ASSERT(OB_ISNULL(list_tail_->next_)); + OB_ASSERT(OB_NOT_NULL(new_node)); + OB_ASSERT(OB_ISNULL(new_node->prev_)); + OB_ASSERT(OB_ISNULL(new_node->next_)); + list_tail_->next_ = new_node; + new_node->prev_ = list_tail_; + new_node->next_ = nullptr; + list_tail_ = new_node; + } + check_invariance_(); + } + void del(ListNodeBase *list_node) { + OB_ASSERT(OB_NOT_NULL(list_node)); + ListNodeBase *before = list_node->prev_; + ListNodeBase *after = list_node->next_; + if (OB_ISNULL(before)) {// the first node + OB_ASSERT(list_head_ == list_node); + list_head_ = after; + if (OB_NOT_NULL(list_head_)) { + list_head_->prev_ = nullptr; + } + } else { + before->next_ = list_node->next_; + } + if (OB_ISNULL(after)) {// the last node + OB_ASSERT(list_tail_ == list_node); + list_tail_ = before; + if (OB_NOT_NULL(list_tail_)) { + list_tail_->next_ = nullptr; + } + } else { + after->prev_ = list_node->prev_; + } + check_invariance_(); + list_node->reset(); + } + bool check_node_exist(ListNodeBase *list_node) { + const ListNodeBase *iter = list_head_; + while (OB_NOT_NULL(iter) && + iter != list_node && + iter != list_tail_) { + iter = iter->next_; + } + return iter == list_node; + } +public: + ListNodeBase *list_head_; + ListNodeBase *list_tail_; +}; + +template +class List : public ListBase// the List DO NOT OWN those nodes +{ +public: + List() : ListBase() {} + virtual ~List() override { clear(); } + template + void for_each_node_from_head_to_tail_until_true(FUNC &&func) const { + const ListNode *iter = dynamic_cast *>(list_head_); + while (OB_NOT_NULL(iter)) { + const T *data = dynamic_cast(iter); + if (OB_ISNULL(data)) { + int ret = OB_ERR_UNEXPECTED; + OCCAM_LOG(ERROR, "downcast failed", KP(iter), KP(data), KP(this), KP(list_head_), KP(list_tail_)); + } + const ListNode *temp_iter_next = dynamic_cast *>(iter->next_); + if (func(*data)) { + break; + } + iter = temp_iter_next; + } + check_invariance_(); + } + template + void for_each_node_from_tail_to_head_until_true(FUNC &&func) const { + const ListNode *iter = dynamic_cast *>(list_tail_); + while (OB_NOT_NULL(iter)) { + const T *data = dynamic_cast(iter); + if (OB_ISNULL(data)) { + int ret = OB_ERR_UNEXPECTED; + OCCAM_LOG(ERROR, "downcast failed", KP(iter), KP(data), KP(this), KP(list_head_), KP(list_tail_)); + } + const ListNode *temp_iter_prev = dynamic_cast *>(iter->prev_); + if (func(*data)) { + break; + } + iter = temp_iter_prev; + } + check_invariance_(); + } + ListNode *fetch_from_head() { + ListNode *head = static_cast *>(list_head_); + if (OB_NOT_NULL(head)) { + ListBase::del(head); + } + check_invariance_(); + return head; + } + void insert_into_head(ListNode *new_node) { + OB_ASSERT(OB_NOT_NULL(new_node)); + new_node->reset(); + if (OB_ISNULL(list_head_)) {// insert into head + OB_ASSERT(OB_ISNULL(list_tail_)); + list_head_ = new_node; + list_tail_ = new_node; + } else {// insert before head + OB_ASSERT(OB_ISNULL(list_head_->prev_)); + OB_ASSERT(OB_ISNULL(new_node->prev_)); + OB_ASSERT(OB_ISNULL(new_node->next_)); + list_head_->prev_ = new_node; + new_node->next_ = list_head_; + new_node->prev_ = nullptr; + list_head_ = new_node; + } + check_invariance_(); + } +}; + +enum SORT_TYPE +{ + DESC = 0, + ASC = 1, +}; + +// if b is false, get reverse of a +static inline bool XNOR(bool a, bool b) { + return ((a & b) | (!a & !b)); +} + +// sorted from small to big(from head to tail) by default +// if REVERSE == true, sorted from big to small(from head to tail) +// two elements equal is allowed +template +class SortedList : public List +{ +public: + SortedList() = default; + virtual ~SortedList() override { ListBase::clear(); } + SortedList(const SortedList &) = delete; + SortedList(SortedList &&) = delete; + SortedList &operator=(const SortedList &) = delete; + SortedList &operator=(SortedList &&) = delete; + void insert(ListNode *new_node) { + OB_ASSERT(OB_NOT_NULL(new_node)); + OB_ASSERT(OB_ISNULL(new_node->next_)); + OB_ASSERT(OB_ISNULL(new_node->prev_)); + if (ListBase::empty()) { + ListBase::list_head_ = new_node; + ListBase::list_tail_ = new_node; + } else { + ListNode *next_node = nullptr; + List::for_each_node_from_head_to_tail_until_true( + [new_node, &next_node](const T &node) { + const ListNode &list_node = dynamic_cast&>(node); + T &rhs_data = dynamic_cast(*new_node); + if (XNOR(CompareOperationWrapper(node) > CompareOperationWrapper(rhs_data), SORT_TYPE)) { + next_node = &const_cast &>(list_node); + return true; + } else { + return false; + } + } + ); + if (OB_ISNULL(next_node)) {// insert to tail + ListBase::list_tail_->next_ = new_node; + new_node->prev_ = ListBase::list_tail_; + ListBase::list_tail_ = new_node; + } else if (OB_ISNULL(next_node->prev_)) {// insert to head + OB_ASSERT(ListBase::list_head_ == next_node); + ListBase::list_head_->prev_ = new_node; + new_node->next_ = ListBase::list_head_; + ListBase::list_head_ = new_node; + } else {// insert to middle + new_node->prev_ = next_node->prev_; + new_node->prev_->next_ = new_node; + next_node->prev_ = new_node; + new_node->next_ = next_node; + } + } + List::check_invariance_(); + } + T &get_head() { + T *data = nullptr; + OB_ASSERT(OB_NOT_NULL(data = dynamic_cast(ListBase::list_head_))); + return *data; + } + T &get_tail() { + T *data = nullptr; + OB_ASSERT(OB_NOT_NULL(data = dynamic_cast(ListBase::list_tail_))); + return *data; + } +}; + +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/runtime_utility/mds_factory.cpp b/src/storage/multi_data_source/runtime_utility/mds_factory.cpp new file mode 100644 index 000000000..629d4707e --- /dev/null +++ b/src/storage/multi_data_source/runtime_utility/mds_factory.cpp @@ -0,0 +1,174 @@ +#include "mds_factory.h" +#include "lib/ob_errno.h" +#include "share/rc/ob_tenant_base.h" +#include "storage/multi_data_source/buffer_ctx.h" +#include "storage/tx/ob_trans_define.h" +#include "storage/tx_storage/ob_tenant_freezer.h" +#include "storage/tx/ob_multi_data_source.h" +#include "storage/multi_data_source/compile_utility/compile_mapper.h" +#include "mds_tenant_service.h" +#include + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +void *MdsAllocator::alloc(const int64_t size) +{ + void *ptr = MTL(ObTenantMdsService*)->get_allocator().alloc(size); + if (OB_NOT_NULL(ptr)) { + ATOMIC_INC(&alloc_times_); + } + return ptr; +} + +void *MdsAllocator::alloc(const int64_t size, const ObMemAttr &attr) +{ + return MTL(ObTenantMdsService*)->get_allocator().alloc(size, attr); +} + +void MdsAllocator::free(void *ptr) { + if (OB_NOT_NULL(ptr)) { + ATOMIC_INC(&free_times_); + MTL(ObTenantMdsService*)->get_allocator().free(ptr); + } +} + +void MdsAllocator::set_label(const lib::ObLabel &) {} + +MdsAllocator &MdsAllocator::get_instance() { static MdsAllocator alloc; return alloc; } + +template +int deepcopy(const transaction::ObTransID &trans_id, + const BufferCtx &old_ctx, + BufferCtx *&new_ctx, + const char *alloc_file, + const char *alloc_func, + const int64_t line) { + int ret = OB_SUCCESS; + ObTenantFreezer *tenant_freezer = MTL(ObTenantFreezer*); + MDS_TG(1_ms); + if (OB_ISNULL(tenant_freezer)) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "MTL is not inited", KR(ret)); + } else if (IDX == old_ctx.get_binding_type_id()) { + using ImplType = GET_CTX_TYPE_BY_TUPLE_IDX(IDX); + ImplType *p_impl = nullptr; + const ImplType *p_old_impl_ctx = dynamic_cast(&old_ctx); + OB_ASSERT(OB_NOT_NULL(p_old_impl_ctx)); + const ImplType &old_impl_ctx = *p_old_impl_ctx; + set_mds_mem_check_thread_local_info(MdsWriter(trans_id), typeid(ImplType).name(), alloc_file, alloc_func, line); + if (CLICK() && + OB_ISNULL(p_impl = (ImplType *)MTL(ObTenantMdsService*)->get_buffer_ctx_allocator().alloc(sizeof(ImplType), + ObMemAttr(MTL_ID(), + "MDS_CTX_COPY", + ObCtxIds::MDS_CTX_ID)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG(WARN, "alloc memory failed", KR(ret), K(IDX)); + } else { + CLICK(); + new (p_impl)ImplType(); + if (MDS_FAIL(common::meta::copy_or_assign(old_impl_ctx, *p_impl))) { + p_impl->~ImplType(); + MTL(mds::ObTenantMdsService*)->get_buffer_ctx_allocator().free(p_impl); + MDS_LOG(WARN, "fail to assign old ctx to new", KR(ret), K(IDX)); + } else { + new_ctx = p_impl; + new_ctx->set_binding_type_id(old_ctx.get_binding_type_id()); + } + } + reset_mds_mem_check_thread_local_info(); + } else { + ret = deepcopy(trans_id, old_ctx, new_ctx, alloc_file, alloc_func, line); + } + return ret; +} + +template <> +int deepcopy(const transaction::ObTransID &trans_id, + const BufferCtx &old_ctx, + BufferCtx *&new_ctx, + const char *alloc_file, + const char *alloc_func, + const int64_t line) +{ + int ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "invalid old ctx", K(trans_id), K(old_ctx.get_binding_type_id()), K(alloc_file), K(alloc_func), K(line)); + return ret; +} + +int MdsFactory::deep_copy_buffer_ctx(const transaction::ObTransID &trans_id, + const BufferCtx &old_ctx, + BufferCtx *&new_ctx, + const char *alloc_file, + const char *alloc_func, + const int64_t line) +{ + int ret = OB_SUCCESS; + MDS_TG(1_ms); + if (old_ctx.get_binding_type_id() == INVALID_VALUE) { + ret = OB_INVALID_ARGUMENT; + new_ctx = nullptr;// won't copy + MDS_LOG(WARN, "invalid old_ctx", K(old_ctx.get_binding_type_id())); + } else if (MDS_FAIL(deepcopy<0>(trans_id, old_ctx, new_ctx, alloc_file, alloc_func, line))) { + MDS_LOG(WARN, "fail to deep copy buffer ctx", K(old_ctx.get_binding_type_id())); + } + return ret; +} + +template ::value, bool>::type = true> +void try_set_writer(T &ctx, const transaction::ObTransID &trans_id) { + ctx.set_writer(MdsWriter(trans_id)); +} + +template ::value, bool>::type = true> +void try_set_writer(T &ctx, const transaction::ObTransID &trans_id) { + // do nothing +} + +int MdsFactory::create_buffer_ctx(const transaction::ObTxDataSourceType &data_source_type, + const transaction::ObTransID &trans_id, + BufferCtx *&buffer_ctx, + const char *alloc_file, + const char *alloc_func, + const int64_t line) { + int ret = OB_SUCCESS; + switch (data_source_type) { + #define NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION + #define _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_(HELPER_CLASS, BUFFER_CTX_TYPE, ID, ENUM_NAME) \ + case transaction::ObTxDataSourceType::ENUM_NAME:\ + {\ + set_mds_mem_check_thread_local_info(MdsWriter(trans_id), typeid(BUFFER_CTX_TYPE).name(), alloc_file, alloc_func, line);\ + int64_t type_id = TupleTypeIdx::value;\ + BUFFER_CTX_TYPE *ctx_impl = (BUFFER_CTX_TYPE *)\ + MTL(ObTenantMdsService*)->get_buffer_ctx_allocator().alloc(sizeof(BUFFER_CTX_TYPE),\ + ObMemAttr(MTL_ID(),\ + "MDS_CTX_CREATE",\ + ObCtxIds::MDS_CTX_ID));\ + if (OB_ISNULL(ctx_impl)) {\ + ret = OB_ALLOCATE_MEMORY_FAILED;\ + MDS_LOG(WARN, "alloc memory failed", KR(ret));\ + } else {\ + new (ctx_impl) BUFFER_CTX_TYPE();\ + ctx_impl->set_binding_type_id(type_id);\ + try_set_writer(*ctx_impl, trans_id);\ + buffer_ctx = ctx_impl;\ + }\ + reset_mds_mem_check_thread_local_info();\ + }\ + break; + #include "storage/multi_data_source/compile_utility/mds_register.h" + #undef _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_ + #undef NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION + default: + ob_abort(); + } + return ret; +} + +} +} +} diff --git a/src/storage/multi_data_source/runtime_utility/mds_factory.h b/src/storage/multi_data_source/runtime_utility/mds_factory.h new file mode 100644 index 000000000..838ed7c29 --- /dev/null +++ b/src/storage/multi_data_source/runtime_utility/mds_factory.h @@ -0,0 +1,135 @@ +#ifndef SHARE_STORAGE_MULTI_DATA_SOURCE_UTILITY_MDS_FACTORY_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_UTILITY_MDS_FACTORY_H +#include "lib/allocator/ob_malloc.h" +#include +#include +#include "lib/atomic/ob_atomic.h" +#include "ob_tablet_id.h" +#include "share/ob_ls_id.h" +#include "src/share/ob_errno.h" +#include "common/meta_programming/ob_type_traits.h" +#include "mds_tenant_service.h" + +namespace oceanbase +{ +namespace transaction +{ +enum class ObTxDataSourceType : int64_t; +class ObTransID; +} +namespace storage +{ +namespace mds +{ + +struct DefaultAllocator : public ObIAllocator +{ + void *alloc(const int64_t size) { return ob_malloc(size, "MDS"); } + void *alloc(const int64_t size, const ObMemAttr &attr) { return ob_malloc(size, attr); } + void free(void *ptr) { ob_free(ptr); } + void set_label(const lib::ObLabel &) {} + static DefaultAllocator &get_instance() { static DefaultAllocator alloc; return alloc; } + static int64_t get_alloc_times() { return ATOMIC_LOAD(&get_instance().alloc_times_); } + static int64_t get_free_times() { return ATOMIC_LOAD(&get_instance().free_times_); } +private: + DefaultAllocator() : alloc_times_(0), free_times_(0) {} + int64_t alloc_times_; + int64_t free_times_; +}; + +class BufferCtx; +struct MdsAllocator : public ObIAllocator +{ + void *alloc(const int64_t size); + void *alloc(const int64_t size, const ObMemAttr &attr); + void free(void *ptr); + void set_label(const lib::ObLabel &); + static MdsAllocator &get_instance(); + static int64_t get_alloc_times() { return ATOMIC_LOAD(&get_instance().alloc_times_); } + static int64_t get_free_times() { return ATOMIC_LOAD(&get_instance().free_times_); } +private: + MdsAllocator() : alloc_times_(0), free_times_(0) {} + int64_t alloc_times_; + int64_t free_times_; +}; + +struct MdsFactory +{ + // 如果类型T有init函数,那么先用默认构造函数构造,然后再调用其init函数 + template ::value, bool>::type = true> + static int create(T *&p_obj, Args &&...args) + { + int ret = OB_SUCCESS; + if (OB_FAIL(create_(p_obj, std::forward(args)...))) { + MDS_LOG(WARN, "fail to create object", KR(ret), K(typeid(T).name()), KP(p_obj), K(lbt())); + } + return ret; + } + template + static void destroy(T *obj) + { + MDS_LOG(DEBUG, "destroy object", K(typeid(T).name()), KP(obj), K(lbt())); + if (OB_NOT_NULL(obj)) { + obj->~T(); + MdsAllocator::get_instance().free(obj); + } + } + + // 根据构造对象时编码好的信息进行运行时反射 + static int deep_copy_buffer_ctx(const transaction::ObTransID &trans_id, + const BufferCtx &old_ctx, + BufferCtx *&new_ctx, + const char *alloc_file = __builtin_FILE(), + const char *alloc_func = __builtin_FUNCTION(), + const int64_t line = __builtin_LINE()); + static int create_buffer_ctx(const transaction::ObTxDataSourceType &data_source_type, + const transaction::ObTransID &trans_id, + BufferCtx *&buffer_ctx, + const char *alloc_file = __builtin_FILE(), + const char *alloc_func = __builtin_FUNCTION(), + const int64_t line = __builtin_LINE()); +private: + // 如果类型T有init函数,那么先用默认构造函数构造,然后再调用其init函数 + template + static int create_(T *&p_obj, Args &&...args) + { + int ret = common::OB_SUCCESS; + T *temp_obj = (T *)MdsAllocator::get_instance().alloc(sizeof(T)); + if (OB_ISNULL(temp_obj)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG(WARN, "alloc memory failed", KR(ret)); + } else { + new (temp_obj)T(); + if (OB_FAIL(temp_obj->init(std::forward(args)...))) { + MDS_LOG(WARN, "init obj failed", KR(ret), K(typeid(T).name())); + temp_obj->~T(); + MdsAllocator::get_instance().free(temp_obj); + } else { + p_obj = temp_obj; + } + } + MDS_LOG(DEBUG, "create object with init", K(typeid(T).name()), KP(p_obj), K(lbt())); + return ret; + } + // 如果类型T没有init函数,则通过构造函数构造 + template + static int create_(T *&p_obj, Args &&...args) + { + int ret = common::OB_SUCCESS; + T *temp_obj = (T *)MdsAllocator::get_instance().alloc(sizeof(T)); + if (OB_ISNULL(temp_obj)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MDS_LOG(WARN, "alloc memory failed", KR(ret)); + } else { + new (temp_obj)T(std::forward(args)...); + p_obj = temp_obj; + } + MDS_LOG(DEBUG, "create object with construction", K(typeid(T).name()), KP(p_obj), K(lbt())); + return ret; + } +}; + +} +} +} +#endif \ No newline at end of file diff --git a/src/storage/multi_data_source/runtime_utility/mds_lock.h b/src/storage/multi_data_source/runtime_utility/mds_lock.h new file mode 100644 index 000000000..3d8e1975f --- /dev/null +++ b/src/storage/multi_data_source/runtime_utility/mds_lock.h @@ -0,0 +1,45 @@ +#ifndef SHARE_STORAGE_MULTI_DATA_SOURCE_RUNTIME_UTILITY_MDS_LOCK_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_RUNTIME_UTILITY_MDS_LOCK_H +#include "lib/ob_define.h" +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log_module.h" +#include "ob_clock_generator.h" +#include "lib/literals/ob_literals.h" +#include "lib/utility/utility.h" +#include "common_define.h" + +namespace oceanbase +{ +namespace storage +{ +namespace mds +{ + +using MdsLock = common::SpinRWLock; + +struct MdsRLockGuard {// RAII + MdsRLockGuard() : p_guard_(nullptr) {} + MdsRLockGuard(const MdsLock &lock) : p_guard_(reinterpret_cast(guard_buffer_)) { new (p_guard_) common::SpinRLockGuard(lock); } + MdsRLockGuard(const MdsRLockGuard&) = delete; + MdsRLockGuard &operator=(const MdsRLockGuard&) = delete; + ~MdsRLockGuard() { if (OB_NOT_NULL(p_guard_)) { p_guard_->~SpinRLockGuard(); } } + char guard_buffer_[sizeof(common::SpinRLockGuard)]; + common::SpinRLockGuard *p_guard_; +}; + +struct MdsWLockGuard {// RAII + MdsWLockGuard() : p_guard_(nullptr) {} + MdsWLockGuard(const MdsLock &lock) : p_guard_(reinterpret_cast(guard_buffer_)) { new (p_guard_) common::SpinWLockGuard(lock); } + MdsWLockGuard(const MdsWLockGuard&) = delete; + MdsWLockGuard &operator=(const MdsWLockGuard&) = delete; + ~MdsWLockGuard() { if (OB_NOT_NULL(p_guard_)) { p_guard_->~SpinWLockGuard(); } } + int64_t to_string(char *buf, const int64_t buf_len) const { return 0; }// to put it in ObSEArray + char guard_buffer_[sizeof(common::SpinRLockGuard)]; + common::SpinWLockGuard *p_guard_; +}; + +} +} +} + +#endif diff --git a/src/storage/multi_data_source/runtime_utility/mds_tenant_service.cpp b/src/storage/multi_data_source/runtime_utility/mds_tenant_service.cpp new file mode 100644 index 000000000..691535264 --- /dev/null +++ b/src/storage/multi_data_source/runtime_utility/mds_tenant_service.cpp @@ -0,0 +1,542 @@ +/** + * Copyright (c) 2021 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 "mds_tenant_service.h" +#include "lib/list/ob_dlist.h" +#include "lib/ob_errno.h" +#include "lib/profile/ob_trace_id.h" +#include "lib/string/ob_string_holder.h" +#include "lib/time/ob_time_utility.h" +#include "lib/utility/utility.h" +#include "share/rc/ob_tenant_base.h" +#include "storage/meta_mem/ob_tablet_map_key.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_memtable_mgr.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "share/scn.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/tablet/ob_tablet_iterator.h" + +namespace oceanbase +{ +using namespace share; +namespace storage +{ +namespace mds +{ + +/********************FOR MEMORY LEAK DEBUG***************************/ +thread_local char __thread_mds_tag__[TAG_SIZE] = {0}; +TLOCAL(const char *, __thread_mds_alloc_type__) = nullptr; +TLOCAL(const char *, __thread_mds_alloc_file__) = nullptr; +TLOCAL(const char *, __thread_mds_alloc_func__) = nullptr; +TLOCAL(uint32_t, __thread_mds_alloc_line__) = 0; + +void set_mds_mem_check_thread_local_info(const MdsWriter &writer, + const char *alloc_ctx_type, + const char *alloc_file, + const char *alloc_func, + const uint32_t alloc_line) +{ + int64_t pos = 0; + databuff_printf(__thread_mds_tag__, TAG_SIZE, pos, "%s", to_cstring(writer)); + __thread_mds_alloc_type__ = alloc_ctx_type; + __thread_mds_alloc_file__ = alloc_file; + __thread_mds_alloc_func__ = alloc_func; + __thread_mds_alloc_line__ = alloc_line; +} + +void set_mds_mem_check_thread_local_info(const share::ObLSID &ls_id, + const ObTabletID &tablet_id, + const char *data_type, + const char *alloc_file, + const char *alloc_func, + const uint32_t alloc_line) +{ + int64_t pos = 0; + databuff_printf(__thread_mds_tag__, TAG_SIZE, pos, "%s, %s", to_cstring(ls_id), to_cstring(tablet_id)); + __thread_mds_alloc_type__ = data_type; + __thread_mds_alloc_file__ = alloc_file; + __thread_mds_alloc_func__ = alloc_func; + __thread_mds_alloc_line__ = alloc_line; +} + +void reset_mds_mem_check_thread_local_info() +{ + __thread_mds_tag__[0] = '\0'; + __thread_mds_alloc_type__ = nullptr; + __thread_mds_alloc_file__ = nullptr; + __thread_mds_alloc_func__ = nullptr; + __thread_mds_alloc_line__ = 0; +} +/********************************************************************/ + +int ObTenantMdsAllocator::init() +{ + int ret = OB_SUCCESS; + ObMemAttr mem_attr; + // TODO : @gengli new ctx id? + mem_attr.tenant_id_ = MTL_ID(); + mem_attr.ctx_id_ = ObCtxIds::MDS_DATA_ID; + mem_attr.label_ = "MdsTable"; + MDS_TG(10_ms); + if (MDS_FAIL(allocator_.init(OB_MALLOC_NORMAL_BLOCK_SIZE, block_alloc_, mem_attr))) { + MDS_LOG(WARN, "init vslice allocator failed", + K(ret), K(OB_MALLOC_NORMAL_BLOCK_SIZE), KP(this), K(mem_attr)); + } else { + allocator_.set_nway(MDS_ALLOC_CONCURRENCY); + } + return ret; +} + +void *ObTenantMdsAllocator::alloc(const int64_t size) +{ + void *obj = allocator_.alloc(size); + MDS_LOG(DEBUG, "mds alloc ", K(size), KP(obj)); + if (OB_NOT_NULL(obj)) { + MTL(ObTenantMdsService*)->record_alloc_backtrace(obj, + __thread_mds_tag__, + __thread_mds_alloc_type__, + __thread_mds_alloc_file__, + __thread_mds_alloc_func__, + __thread_mds_alloc_line__);// for debug mem leak + } + return obj; +} + +void *ObTenantMdsAllocator::alloc(const int64_t size, const ObMemAttr &attr) +{ + UNUSED(attr); + void *obj = alloc(size); + MDS_LOG_RET(WARN, OB_INVALID_ARGUMENT, "VSLICE Allocator not support mark attr", KP(obj), K(size), K(attr)); + return obj; +} + +void ObTenantMdsAllocator::free(void *ptr) +{ + allocator_.free(ptr); + MTL(ObTenantMdsService*)->erase_alloc_backtrace(ptr); +} + +void ObTenantMdsAllocator::set_attr(const ObMemAttr &attr) +{ + allocator_.set_attr(attr); +} + +void *ObTenantBufferCtxAllocator::alloc(const int64_t size) +{ + void *obj = share::mtl_malloc(size, ObMemAttr(MTL_ID(), "MDS_CTX_DEFAULT", ObCtxIds::MDS_CTX_ID)); + if (OB_NOT_NULL(obj)) { + MTL(ObTenantMdsService*)->record_alloc_backtrace(obj, + __thread_mds_tag__, + __thread_mds_alloc_type__, + __thread_mds_alloc_file__, + __thread_mds_alloc_func__, + __thread_mds_alloc_line__);// for debug mem leak + } + return obj; +} + +void *ObTenantBufferCtxAllocator::alloc(const int64_t size, const ObMemAttr &attr) +{ + void *obj = share::mtl_malloc(size, attr); + if (OB_NOT_NULL(obj)) { + MTL(ObTenantMdsService*)->record_alloc_backtrace(obj, + __thread_mds_tag__, + __thread_mds_alloc_type__, + __thread_mds_alloc_file__, + __thread_mds_alloc_func__, + __thread_mds_alloc_line__);// for debug mem leak + } + return obj; +} + +void ObTenantBufferCtxAllocator::free(void *ptr) +{ + share::mtl_free(ptr); + MTL(ObTenantMdsService*)->erase_alloc_backtrace(ptr); +} + +int ObTenantMdsService::mtl_init(ObTenantMdsService *&mds_service) +{ + int ret = OB_SUCCESS; + MDS_TG(10_ms); + if (mds_service->is_inited_) { + ret = OB_INIT_TWICE; + MDS_LOG(ERROR, "init mds tenant service twice!", KR(ret), KPC(mds_service)); + } else if (MDS_FAIL(mds_service->memory_leak_debug_map_.init("MdsDebugMap", MTL_ID()))) { + MDS_LOG(WARN, "init map failed", K(ret)); + } else if (MDS_FAIL(mds_service->mds_allocator_.init())) { + MDS_LOG(ERROR, "fail to init allocator", KR(ret), KPC(mds_service)); + } else if (MDS_FAIL(mds_service->mds_timer_.timer_.init_and_start(1/*worker number*/, + 100_ms/*precision*/, + "MdsT"/*thread name*/))) { + MDS_LOG(ERROR, "fail to init timer", KR(ret), KPC(mds_service)); + } else { + mds_service->is_inited_ = true; + } + return ret; +} + +int ObTenantMdsService::mtl_start(ObTenantMdsService *&mds_service) +{ + int ret = OB_SUCCESS; + MDS_TG(10_ms); + if (MDS_FAIL(mds_service->mds_timer_.timer_.schedule_task_repeat( + mds_service->mds_timer_.recycle_task_handle_, + 3_s, + [mds_service]() -> bool { + ObCurTraceId::init(GCONF.self_addr_); + if (REACH_TIME_INTERVAL(30_s)) { + observer::ObMdsEventBuffer::dump_statistics(); + mds_service->dump_map_holding_item(5_min); + } + mds_service->mds_timer_.try_recycle_mds_table_task(); + return false;// won't stop until tenant exit + } + ))) { + MDS_LOG(ERROR, "fail to register recycle timer task to timer", KR(ret), KPC(mds_service)); + } + return ret; +} + +void ObTenantMdsService::mtl_stop(ObTenantMdsService *&mds_service) +{ + if (nullptr != mds_service) { + mds_service->mds_timer_.recycle_task_handle_.stop(); + } +} + +void ObTenantMdsService::mtl_wait(ObTenantMdsService *&mds_service) +{ + if (nullptr != mds_service) { + mds_service->mds_timer_.recycle_task_handle_.wait(); + } +} + +void ObTenantMdsTimer::try_recycle_mds_table_task() +{ + #define PRINT_WRAPPER KR(ret), KPC(this), K(tablet_oldest_scn), K(mds_table_handle) + int ret = OB_SUCCESS; + ObCurTraceId::init(GCONF.self_addr_); + ObTenantMdsService::for_each_ls_in_tenant([this](ObLS &ls) -> int { + ObTenantMdsService::for_each_mds_table_in_ls(ls, [this](ObTablet &tablet) -> int {// FIXME: there is no need scan all tablets + (void) this->process_with_tablet_(tablet); + return OB_SUCCESS;// keep doing ignore error + }); + return OB_SUCCESS;// keep doing ignore error + }); + #undef PRINT_WRAPPER +} + +int ObTenantMdsService::for_each_ls_in_tenant(const ObFunction &op) +{ + #define PRINT_WRAPPER KR(ret) + int ret = OB_SUCCESS; + MDS_TG(3_s); + ObSharedGuard iter; + ObLS *ls = nullptr; + int64_t succ_num = 0; + if (!op.is_valid()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG_NONE(WARN, "invalid op"); + } else if (MDS_FAIL(MTL(ObLSService*)->get_ls_iter(iter, ObLSGetMod::MDS_TABLE_MOD))) { + MDS_LOG_NONE(WARN, "fail to get ls iterator"); + } else { + do { + if (MDS_FAIL(iter->get_next(ls))) { + if (OB_ITER_END != ret) { + MDS_LOG_NONE(WARN, "get next iter failed"); + } else { + ret = OB_SUCCESS; + break; + } + } else if (MDS_FAIL(op(*ls))) { + MDS_LOG_NONE(WARN, "fail to for each ls", K(succ_num)); + } + } while (++succ_num && OB_SUCC(ret)); + } + MDS_LOG_NONE(INFO, "for each ls", K(succ_num)); + return ret; + #undef PRINT_WRAPPER +} + +int ObTenantMdsService::for_each_tablet_in_ls(ObLS &ls, const ObFunction &op) +{ + #define PRINT_WRAPPER KR(ret), K(ls) + int ret = OB_SUCCESS; + int64_t succ_num = 0; + ObLSTabletIterator tablet_iter(storage::ObMDSGetTabletMode::READ_WITHOUT_CHECK); + MDS_TG(500_ms); + if (!op.is_valid()) { + ret = OB_INVALID_ARGUMENT; + MDS_LOG_NONE(WARN, "invalid op"); + } else if (MDS_FAIL(ls.build_tablet_iter(tablet_iter))) { + MDS_LOG_NONE(WARN, "failed to build ls tablet iter"); + } else { + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + do { + tablet_handle.reset(); + tablet = nullptr; + if (MDS_FAIL(tablet_iter.get_next_tablet(tablet_handle))) { + if (OB_ITER_END != ret && OB_EMPTY_RESULT != ret) { + MDS_LOG_NONE(WARN, "failed to get tablet"); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_NONE(WARN, "tablet should not be NULL", KPC(tablet)); + } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { + // FIXME: threr is no mds table on ls inner tablet yet, but there will be + } else { + op(*tablet); + } + } while (++succ_num && OB_SUCC(ret)); + MDS_LOG_NONE(INFO, "for each tablet", K(succ_num)); + } + return ret; + #undef PRINT_WRAPPER +} + +int ObTenantMdsService::for_each_mds_table_in_ls(ObLS &ls, const ObFunction &op) +{ + #define PRINT_WRAPPER KR(ret), K(ls), K(mds_table_total_num), K(ids_in_t3m_array.count()) + int ret = OB_SUCCESS; + int64_t succ_num = 0; + ObLSTabletIterator tablet_iter(storage::ObMDSGetTabletMode::READ_WITHOUT_CHECK); + MDS_TG(10_s); + + int64_t mds_table_total_num = 0; + MdsTableMgrHandle mgr_handle; + ObArray ids_in_t3m_array; + if (MDS_FAIL(ls.get_mds_table_mgr(mgr_handle))) { + MDS_LOG_NONE(WARN, "fail to get mds table mgr"); + } else if (MDS_FAIL(mgr_handle.get_mds_table_mgr()->for_each_mds_table_list( + [&mds_table_total_num, &ids_in_t3m_array, &ls](const ObTabletID &tablet_id, List &mds_table_list) -> bool {// with map's bucket lock protected + MDS_TG(1_s); + int ret = OB_SUCCESS; + if (mds_table_list.empty()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_NONE(ERROR, "meet empty mds_table_list", K(tablet_id)); + } else { + MdsTableBase *p_mds_table = static_cast(mds_table_list.list_head_); + if (!p_mds_table->is_removed_from_t3m()) { + MDS_LOG_NONE(TRACE, "process with mds_table", KPC(p_mds_table)); + if (MDS_FAIL(ids_in_t3m_array.push_back(p_mds_table->get_tablet_id()))) { + MDS_LOG_NONE(WARN, "fail to push array", KPC(p_mds_table)); + } + } else { + MDS_LOG_NONE(WARN, "consider mds_table leaked if this log keep printing", KPC(p_mds_table)); + } + ++mds_table_total_num; + MdsTableBase *iter = static_cast(p_mds_table->next_); + while (OB_NOT_NULL(iter)) { + if (ObTimeUtility::fast_current_time() - iter->get_removed_from_t3m_ts() > 5_min) { + MDS_LOG_NONE(WARN, "consider mds_table leaked if this log keep printing", KPC(iter)); + } + ++mds_table_total_num; + iter = static_cast(iter->next_); + } + } + return true;// keep iter + } + ))) { + MDS_LOG_NONE(WARN, "fail to scan mds_table"); + } else { + MDS_LOG_NONE(INFO, "succ to scan mds_table"); + constexpr int64_t PRINT_SIZE = 128; + // print those in t3m array ids, and if ids too many, print random part of them + if (ids_in_t3m_array.count() < PRINT_SIZE) { + MDS_LOG_NONE(INFO, "dump tablet ids in t3m", K(ids_in_t3m_array)); + } else { + int64_t random_start = rand() % ids_in_t3m_array.count(); + ObSEArray print_array; + for (int64_t idx = 0; idx < PRINT_SIZE; ++idx) { + print_array.push_back(ids_in_t3m_array[(random_start + idx) % ids_in_t3m_array.count()]); + } + MDS_LOG_NONE(INFO, "dump random part tablet ids in t3m", K(print_array), K(ids_in_t3m_array.count()), K(PRINT_SIZE)); + } + for (int64_t idx = 0; idx < ids_in_t3m_array.count(); ++idx) {// ignore ret + ObTabletHandle tablet_handle; + if (OB_FAIL(ls.get_tablet(ids_in_t3m_array[idx], tablet_handle, 1_s, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + MDS_LOG_NONE(WARN, "fail to get tablet_handle", K(ids_in_t3m_array[idx])); + } else if (OB_FAIL(op(*tablet_handle.get_obj()))) { + MDS_LOG_NONE(WARN, "fail to process with tablet", K(ids_in_t3m_array[idx])); + } + } + } + return ret; + #undef PRINT_WRAPPER +} + +int ObTenantMdsTimer::process_with_tablet_(ObTablet &tablet) +{ + #define PRINT_WRAPPER KR(ret), KPC(this), K(tablet_oldest_scn), K(tablet.get_tablet_meta().tablet_id_) + int ret = OB_SUCCESS; + share::SCN tablet_oldest_scn; + MDS_TG(10_ms); + if (MDS_FAIL(get_tablet_oldest_scn_(tablet, tablet_oldest_scn))) { + MDS_LOG_GC(WARN, "fail to get tablet oldest scn"); + } else if (MDS_FAIL(try_recycle_mds_table_(tablet, tablet_oldest_scn))) { + MDS_LOG_GC(WARN, "fail to recycle mds table"); + } else if (MDS_FAIL(try_gc_mds_table_(tablet))) { + if (OB_EAGAIN != ret) { + MDS_LOG_GC(WARN, "fail to gc mds table"); + } else { + MDS_LOG_GC(INFO, "try gc mds table need do again later"); + } + } else { + MDS_LOG_GC(INFO, "success do try gc mds table"); + } + return ret; + #undef PRINT_WRAPPER +} + +int ObTenantMdsTimer::get_tablet_oldest_scn_(ObTablet &tablet, share::SCN &oldest_scn) +{ + #define PRINT_WRAPPER KR(ret), K(tablet.get_tablet_meta().tablet_id_), K(oldest_scn), KPC(this) + int ret = OB_SUCCESS; + MDS_TG(5_ms); + if (OB_ISNULL(MTL(ObTenantMetaMemMgr*))) { + ret = OB_BAD_NULL_ERROR; + MDS_LOG_GC(ERROR, "MTL ObTenantMetaMemMgr is NULL"); + } else if (MDS_FAIL(MTL(ObTenantMetaMemMgr*)->get_min_mds_ckpt_scn(ObTabletMapKey(tablet.get_tablet_meta().ls_id_, + tablet.get_tablet_meta().tablet_id_), + oldest_scn))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + MDS_LOG_GC(WARN, "get_min_mds_ckpt_scn meet OB_ENTRY_NOT_EXIST"); + } else { + MDS_LOG_GC(WARN, "fail to get oldest tablet min_mds_ckpt_scn"); + } + oldest_scn = SCN::min_scn();// means can not recycle any node + } else if (oldest_scn.is_max() || !oldest_scn.is_valid()) { + oldest_scn = SCN::min_scn();// means can not recycle any node + } + return ret; + #undef PRINT_WRAPPER +} + +int ObTenantMdsTimer::try_recycle_mds_table_(ObTablet &tablet, + const share::SCN &tablet_oldest_scn) +{ + #define PRINT_WRAPPER KR(ret), K(tablet.get_tablet_meta().tablet_id_), K(tablet_oldest_scn), KPC(this) + int ret = OB_SUCCESS; + const ObTablet::ObTabletPointerHandle &pointer_handle = tablet.get_pointer_handle(); + ObMetaPointer *resource_ptr = pointer_handle.get_resource_ptr(); + ObTabletPointer *tablet_pointer = dynamic_cast(resource_ptr); + MDS_TG(5_ms); + if (OB_ISNULL(tablet_pointer)) { + ret = OB_BAD_NULL_ERROR; + MDS_LOG_GC(ERROR, "down cast to tablet pointer failed"); + } else if (MDS_FAIL(tablet_pointer->try_release_mds_nodes_below(tablet_oldest_scn))) { + MDS_LOG_GC(WARN, "fail to release mds nodes"); + } else { + MDS_LOG_GC(DEBUG, "success to release mds nodes"); + } + return ret; + #undef PRINT_WRAPPER +} + +int ObTenantMdsTimer::try_gc_mds_table_(ObTablet &tablet) +{ + #define PRINT_WRAPPER KR(ret), K(tablet.get_tablet_meta().tablet_id_), KPC(this) + int ret = OB_SUCCESS; + const ObTablet::ObTabletPointerHandle &pointer_handle = tablet.get_pointer_handle(); + ObMetaPointer *resource_ptr = pointer_handle.get_resource_ptr(); + ObTabletPointer *tablet_pointer = dynamic_cast(resource_ptr); + MDS_TG(5_ms); + if (OB_ISNULL(tablet_pointer)) { + ret = OB_BAD_NULL_ERROR; + MDS_LOG_GC(ERROR, "down cast to tablet pointer failed"); + } else if (MDS_FAIL(tablet_pointer->try_gc_mds_table())) { + if (OB_EAGAIN != ret) { + MDS_LOG_GC(WARN, "try gc mds table failed"); + } + } else { + MDS_LOG_GC(DEBUG, "success to release mds nodes"); + } + return ret; + #undef PRINT_WRAPPER +} + +void ObTenantMdsService::record_alloc_backtrace(void *obj, + const char *tag, + const char *data_type, + const char *alloc_file, + const char *alloc_func, + const int64_t line) +{ +#ifdef ENABLE_DEBUG_MDS_MEM_LEAK + int ret = OB_SUCCESS; + if (OB_FAIL(memory_leak_debug_map_.insert(ObIntWarp((int64_t)obj), + ObMdsMemoryLeakDebugInfo(tag, + TAG_SIZE, + data_type, + alloc_file, + alloc_func, + line)))) { + MDS_LOG(WARN, "fail to insert lbt to map", KR(ret), KP(obj), K(data_type), K(alloc_file), K(alloc_func), K(line)); + } +#else + UNUSED(obj); + UNUSED(tag); + UNUSED(data_type); + UNUSED(alloc_file); + UNUSED(alloc_func); + UNUSED(line); +#endif +} + +void ObTenantMdsService::erase_alloc_backtrace(void *obj) +{ +#ifdef ENABLE_DEBUG_MDS_MEM_LEAK + int ret = OB_SUCCESS; + if (OB_FAIL(memory_leak_debug_map_.erase(ObIntWarp((int64_t)obj)))) { + MDS_LOG(WARN, "fail to erase record from map", KR(ret), KP(obj)); + } +#else + UNUSED(obj); +#endif +} + +void ObTenantMdsService::dump_map_holding_item(int64_t check_alive_time_threshold) +{ + int ret = OB_SUCCESS; + int64_t scan_cnt = 0; + auto op = [&scan_cnt, check_alive_time_threshold](const ObIntWarp &obj_wrapper, + ObMdsMemoryLeakDebugInfo &debug_info) { + void *obj = (void *)(int64_t)obj_wrapper.get_value(); + ++scan_cnt; + if (ObTimeUtility::fast_current_time() - debug_info.alloc_ts_ >= check_alive_time_threshold) { + MDS_LOG(INFO, "print item alloc backtrace", + KP(obj), K(debug_info), K(ObTimeLiteralPrettyPrinter(check_alive_time_threshold))); + } + return true; + }; + if (OB_FAIL(memory_leak_debug_map_.for_each(op))) { + MDS_LOG(WARN, "fail to do for_each", KR(ret)); + } else { + MDS_LOG(INFO, "finish scan map holding items", K(scan_cnt)); + } +} + +} // namespace mds +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/multi_data_source/runtime_utility/mds_tenant_service.h b/src/storage/multi_data_source/runtime_utility/mds_tenant_service.h new file mode 100644 index 000000000..d4d40a0f0 --- /dev/null +++ b/src/storage/multi_data_source/runtime_utility/mds_tenant_service.h @@ -0,0 +1,198 @@ +/** + * Copyright (c) 2021 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 SHARE_STORAGE_MULTI_DATA_SOURCE_MDS_TENANT_SERVICE_H +#define SHARE_STORAGE_MULTI_DATA_SOURCE_MDS_TENANT_SERVICE_H + +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/string/ob_string_holder.h" +#include "lib/time/ob_time_utility.h" +#include "lib/utility/ob_macro_utils.h" +#include "lib/utility/ob_print_utils.h" +#include "lib/allocator/ob_vslice_alloc.h" +#include "share/ob_ls_id.h" +#include "share/ob_occam_timer.h" +// #include "storage/tx/ob_trans_define.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "lib/hash/ob_linear_hash_map.h" + +namespace oceanbase +{ +namespace share +{ +class SCN; +} +namespace storage +{ +class ObLS; +class ObLSHandle; +class ObTablet; +class ObTabletHandle; +namespace mds +{ +class MdsWriter; +class MdsTableHandle; +class ObTenantMdsService; +/********************FOR MEMORY LEAK DEBUG***************************/ +static constexpr const int64_t TAG_SIZE = 64; +extern thread_local char __thread_mds_tag__[TAG_SIZE]; +extern TLOCAL(const char *, __thread_mds_alloc_type__); +extern TLOCAL(const char *, __thread_mds_alloc_file__); +extern TLOCAL(const char *, __thread_mds_alloc_func__); +extern TLOCAL(uint32_t, __thread_mds_alloc_line__); + +extern void set_mds_mem_check_thread_local_info(const MdsWriter &writer, + const char *alloc_ctx_type, + const char *alloc_file = __builtin_FILE(), + const char *alloc_func = __builtin_FUNCTION(), + const uint32_t line = __builtin_LINE()); +extern void set_mds_mem_check_thread_local_info(const share::ObLSID &ls_id, + const ObTabletID &tablet_id, + const char *data_type, + const char *alloc_file = __builtin_FILE(), + const char *alloc_func = __builtin_FUNCTION(), + const uint32_t line = __builtin_LINE()); +extern void reset_mds_mem_check_thread_local_info(); +/********************************************************************/ + +struct ObMdsMemoryLeakDebugInfo +{ + ObMdsMemoryLeakDebugInfo() + : data_type_(nullptr), alloc_file_(nullptr), alloc_func_(nullptr), alloc_line_(0), alloc_ts_(0), tid_(0) {} + ObMdsMemoryLeakDebugInfo(const char *tag, + const int64_t tag_size, + const char *type, + const char *alloc_file, + const char *alloc_func, + int64_t line) + : data_type_(type), + alloc_file_(alloc_file), + alloc_func_(alloc_func), + alloc_line_(line), + alloc_ts_(ObTimeUtility::fast_current_time()), + tid_(GETTID()) { + memcpy(tag_str_, tag, std::min(TAG_SIZE, tag_size)); + } + ObMdsMemoryLeakDebugInfo(const ObMdsMemoryLeakDebugInfo &rhs) = default;// value sematic copy construction + ObMdsMemoryLeakDebugInfo &operator=(const ObMdsMemoryLeakDebugInfo &rhs) = default;// value sematic copy assign + TO_STRING_KV(K_(tag_str), K_(data_type), K_(alloc_file), K_(alloc_func), K_(alloc_line), KTIME_(alloc_ts), K_(tid)); + const char *data_type_; + const char *alloc_file_; + const char *alloc_func_; + int64_t alloc_line_; + char tag_str_[TAG_SIZE] = {0}; + int64_t alloc_ts_; + int64_t tid_; +}; + +class ObTenantMdsAllocator : public ObIAllocator +{ + friend class ObTenantMdsService; +private: + static const int64_t MDS_ALLOC_CONCURRENCY = 32; +public: + ObTenantMdsAllocator() = default; + int init(); + void destroy() {} + virtual void *alloc(const int64_t size) override; + virtual void *alloc(const int64_t size, const ObMemAttr &attr) override; + virtual void free(void *ptr) override; + virtual void set_attr(const ObMemAttr &attr) override; + int64_t hold() { return allocator_.hold(); } + TO_STRING_KV(KP(this)); +private: + common::ObBlockAllocMgr block_alloc_; + common::ObVSliceAlloc allocator_; +}; + +struct ObTenantBufferCtxAllocator : public ObIAllocator// for now, it is just a wrapper of mtl_malloc +{ + virtual void *alloc(const int64_t size) override; + virtual void *alloc(const int64_t size, const ObMemAttr &attr) override; + virtual void free(void *ptr) override; + virtual void set_attr(const ObMemAttr &) override {} +}; + +struct ObTenantMdsTimer +{ + ObTenantMdsTimer() = default; + int init_and_start(); + void stop(); + void wait(); + void try_recycle_mds_table_task(); + TO_STRING_KV(KP(this), K_(recycle_task_handle)) + common::ObOccamTimerTaskRAIIHandle recycle_task_handle_; + common::ObOccamTimer timer_; +private: + int process_with_tablet_(ObTablet &tablet); + int get_tablet_oldest_scn_(ObTablet &tablet, share::SCN &oldest_scn); + int try_recycle_mds_table_(ObTablet &tablet, const share::SCN &recycle_scn); + int try_gc_mds_table_(ObTablet &tablet); +}; + +class ObTenantMdsService +{ +public: + ObTenantMdsService() : is_inited_(false) {} + ~ObTenantMdsService() { + if (memory_leak_debug_map_.count() != 0) { + MDS_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "there are holding items not released when mds allocator released"); + dump_map_holding_item(0); + } + MDS_LOG_RET(INFO, OB_SUCCESS, "ObTenantMdsAllocator destructed"); + } + static int mtl_init(ObTenantMdsService* &); + static int mtl_start(ObTenantMdsService* &); + static void mtl_stop(ObTenantMdsService* &); + static void mtl_wait(ObTenantMdsService* &); + void destroy() { this->~ObTenantMdsService(); } + static int for_each_ls_in_tenant(const ObFunction &op); + static int for_each_tablet_in_ls(ObLS &ls, const ObFunction &op); + static int for_each_mds_table_in_ls(ObLS &ls, const ObFunction &op); + ObTenantMdsAllocator &get_allocator() { return mds_allocator_; } + ObTenantBufferCtxAllocator &get_buffer_ctx_allocator() { return buffer_ctx_allocator_; } + TO_STRING_KV(KP(this), K_(is_inited), K_(mds_allocator), K_(mds_timer)) +public: + /*******************debug for memoy leak************************/ + template + void update_mem_leak_debug_info(void *obj, OP &&op) { + int ret = OB_SUCCESS; + if (OB_FAIL(memory_leak_debug_map_.operate(ObIntWarp((int64_t)obj), op))) { + MDS_LOG(WARN, "fail to update mem check debug info", KR(ret), KP(obj)); + } + } + void record_alloc_backtrace(void *obj, + const char *tag, + const char *data_type, + const char *alloc_file, + const char *alloc_func, + const int64_t line); + void erase_alloc_backtrace(void *obj); + void dump_map_holding_item(int64_t check_alive_time_threshold); + /***************************************************************/ +private: + bool is_inited_; + ObTenantMdsAllocator mds_allocator_; + ObTenantBufferCtxAllocator buffer_ctx_allocator_; + ObTenantMdsTimer mds_timer_; + /*******************debug for memoy leak************************/ + ObLinearHashMap memory_leak_debug_map_; + /***************************************************************/ +}; + +} // namespace mds +} // namespace storage +} // namespace oceanbase + + +#endif \ No newline at end of file diff --git a/src/storage/ob_all_micro_block_range_iterator.cpp b/src/storage/ob_all_micro_block_range_iterator.cpp index 6649f248a..31de6764e 100644 --- a/src/storage/ob_all_micro_block_range_iterator.cpp +++ b/src/storage/ob_all_micro_block_range_iterator.cpp @@ -23,7 +23,7 @@ namespace storage { ObAllMicroBlockRangeIterator::ObAllMicroBlockRangeIterator() - : sstable_meta_(nullptr), + : schema_rowkey_cnt_(0), tree_cursor_(), start_bound_micro_block_(), end_bound_micro_block_(), @@ -49,7 +49,7 @@ ObAllMicroBlockRangeIterator::~ObAllMicroBlockRangeIterator() void ObAllMicroBlockRangeIterator::reset() { if (is_inited_) { - sstable_meta_ = nullptr; + schema_rowkey_cnt_ = 0; tree_cursor_.reset(); start_bound_micro_block_.reset(); end_bound_micro_block_.reset(); @@ -77,26 +77,24 @@ void ObAllMicroBlockRangeIterator::reset() int ObAllMicroBlockRangeIterator::open( const ObSSTable &sstable, const ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse_scan) { int ret = OB_SUCCESS; - int64_t rowkey_column_cnt = 0; if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("Inited twice", K(ret)); } else if (OB_UNLIKELY(!sstable.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid sstable", K(ret)); - } else if (sstable.get_meta().is_empty()) { + } else if (sstable.is_empty()) { is_iter_end_ = true; is_inited_ = true; - } else if (FALSE_IT(rowkey_column_cnt = sstable.get_meta().get_basic_meta().rowkey_column_count_)) { - } else if (OB_FAIL(tree_cursor_.init(sstable, allocator, &index_read_info))) { + } else if (OB_FAIL(tree_cursor_.init(sstable, allocator, &rowkey_read_info))) { LOG_WARN("Fail to init index tree cursor", K(ret), K(sstable)); } else { - sstable_meta_ = &sstable.get_meta(); + schema_rowkey_cnt_ = rowkey_read_info.get_schema_rowkey_count(); range_ = ⦥ bool start_key_beyond_range = false; bool end_key_beyond_range = false; @@ -261,7 +259,6 @@ int ObAllMicroBlockRangeIterator::generate_cur_range( micro_range_.set_right_closed(); ObDatumRowkey &start_key = is_reverse_scan_ ? curr_key_ : prev_key_; ObDatumRowkey &endkey = is_reverse_scan_ ? prev_key_ : curr_key_; - const int64_t schema_rowkey_cnt = sstable_meta_->get_schema_rowkey_column_count(); if (is_first_block) { micro_range_.start_key_ = range_->get_start_key(); if (range_->get_border_flag().inclusive_start()) { @@ -279,8 +276,8 @@ int ObAllMicroBlockRangeIterator::generate_cur_range( micro_range_.start_key_ = start_key; micro_range_.end_key_ = endkey; } - micro_range_.start_key_.datum_cnt_ = MIN(micro_range_.start_key_.datum_cnt_, schema_rowkey_cnt); - micro_range_.end_key_.datum_cnt_ = MIN(micro_range_.end_key_.datum_cnt_, schema_rowkey_cnt); + micro_range_.start_key_.datum_cnt_ = MIN(micro_range_.start_key_.datum_cnt_, schema_rowkey_cnt_); + micro_range_.end_key_.datum_cnt_ = MIN(micro_range_.end_key_.datum_cnt_, schema_rowkey_cnt_); return ret; } diff --git a/src/storage/ob_all_micro_block_range_iterator.h b/src/storage/ob_all_micro_block_range_iterator.h index 85fbe5fcd..fc94a5534 100644 --- a/src/storage/ob_all_micro_block_range_iterator.h +++ b/src/storage/ob_all_micro_block_range_iterator.h @@ -29,7 +29,7 @@ public: int open( const blocksstable::ObSSTable &sstable, const blocksstable::ObDatumRange &range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &rowkey_read_info, ObIAllocator &allocator, const bool is_reverse_scan); int get_next_range(const blocksstable::ObDatumRange *&range); @@ -42,7 +42,7 @@ private: int generate_cur_range(const bool is_first_range, const bool is_last_range); int deep_copy_rowkey(const blocksstable::ObDatumRowkey &src_key, blocksstable::ObDatumRowkey &dest_key, char *&key_buf); private: - const blocksstable::ObSSTableMeta *sstable_meta_; + int64_t schema_rowkey_cnt_; blocksstable::ObIndexBlockTreeCursor tree_cursor_; blocksstable::ObMicroBlockId start_bound_micro_block_; blocksstable::ObMicroBlockId end_bound_micro_block_; diff --git a/src/storage/ob_bloom_filter_task.cpp b/src/storage/ob_bloom_filter_task.cpp index 3b33998a9..fc377a0aa 100644 --- a/src/storage/ob_bloom_filter_task.cpp +++ b/src/storage/ob_bloom_filter_task.cpp @@ -168,7 +168,7 @@ int ObBloomFilterBuildTask::build_bloom_filter() } else { ObStorageDatumUtils datum_utils; ObDatumRowkey rowkey; - if (OB_FAIL(datum_utils.init(macro_bare_iter->get_column_descs(), + if (OB_FAIL(datum_utils.init(macro_bare_iter->get_rowkey_column_descs(), macro_header.fixed_header_.rowkey_column_count_, compat_mode == lib::Worker::CompatMode::ORACLE, allocator_))) { diff --git a/src/storage/ob_common_id_utils.cpp b/src/storage/ob_common_id_utils.cpp new file mode 100644 index 000000000..2b8379dfe --- /dev/null +++ b/src/storage/ob_common_id_utils.cpp @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "ob_common_id_utils.h" +#include "share/ob_share_util.h" +#include "storage/tx/ob_unique_id_service.h" // ObUniqueIDService + +namespace oceanbase +{ +using namespace common; +using namespace share; +namespace storage +{ +int ObCommonIDUtils::gen_unique_id(const uint64_t tenant_id, ObCommonID &id) +{ + int ret = OB_SUCCESS; + ObTimeoutCtx ctx; + const int64_t DEFAULT_TIMEOUT = GCONF.rpc_timeout; + int64_t unique_id = ObCommonID::INVALID_ID; + + id.reset(); + + if (OB_UNLIKELY(MTL_ID() != tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invaild tenant id", KR(ret), K(tenant_id), K(MTL_ID())); + } else if (OB_FAIL(share::ObShareUtil::set_default_timeout_ctx(ctx, DEFAULT_TIMEOUT))) { + LOG_WARN("set default timeout ctx fail", KR(ret), K(DEFAULT_TIMEOUT)); + } else if (OB_FAIL(MTL(transaction::ObUniqueIDService*)->gen_unique_id(unique_id, + ctx.get_timeout()))) { + LOG_WARN("gen_unique_id failed", KR(ret), K(tenant_id), K(ctx)); + } else { + id = ObCommonID(unique_id); + } + + return ret; +} + +int ObCommonIDUtils::gen_unique_id_by_rpc(const uint64_t tenant_id, ObCommonID &id) +{ + int ret = OB_SUCCESS; + obrpc::ObSrvRpcProxy *srv_rpc_proxy = nullptr; + share::ObLocationService *location_service = nullptr; + ObAddr leader_addr; + if (OB_ISNULL(srv_rpc_proxy = GCTX.srv_rpc_proxy_) + || OB_ISNULL(location_service = GCTX.location_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("root service or location_cache is null", KR(ret), KP(srv_rpc_proxy), KP(location_service)); + } else if (OB_FAIL(location_service->get_leader(GCONF.cluster_id, + tenant_id, + SYS_LS, + false,/*force_renew*/ + leader_addr))) { + LOG_WARN("get leader failed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(srv_rpc_proxy->to(leader_addr).by(tenant_id).gen_unique_id(tenant_id, id))) { + LOG_WARN("fail to send gen unique id rpc", KR(ret), K(tenant_id)); + } + return ret; +} + +int ObCommonIDUtils::gen_monotonic_id(const uint64_t tenant_id, + const ObMaxIdType id_type, + common::ObMySQLProxy &proxy, + share::ObCommonID &id) +{ + int ret = OB_SUCCESS; + uint64_t ret_id = OB_INVALID_ID; + ObMaxIdFetcher id_fetcher(proxy); + + id.reset(); + + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_FAIL(id_fetcher.fetch_new_max_id(tenant_id, id_type, ret_id, 1L/*start id*/))) { + LOG_WARN("fetch new max id failed", KR(ret), K(tenant_id), K(id_type)); + } else { + id = ObCommonID(ret_id); + } + + return ret; +} + +} // end namespace storage +} // end namespace oceanbase diff --git a/src/storage/ob_common_id_utils.h b/src/storage/ob_common_id_utils.h new file mode 100644 index 000000000..47dff0b28 --- /dev/null +++ b/src/storage/ob_common_id_utils.h @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_COMMON_ID_UTILS_H_ +#define OCEANBASE_STORAGE_OB_COMMON_ID_UTILS_H_ + +#include "share/ob_common_id.h" // ObCommonID + +#include "share/ob_max_id_fetcher.h" // ObMaxIdType, ObMaxIdFetcher + +namespace oceanbase +{ +namespace common +{ +class ObMySQLProxy; +} + +namespace share +{ +enum ObMaxIdType; +} +namespace storage +{ + +// Utils for ObCommonID +class ObCommonIDUtils +{ +public: + // Use ObUniqueIDService to generate Unique ID for ObCommonID in target tenant. + // + // NOTE: ID is unique, but not monotonic. + // + // + // @param [in] tenant_id target tenant id + // @param [out] id generated ID + // + // @return + // - OB_INVALID_ARGUMENT tenant_id is invalid or not matched with MTL_ID + static int gen_unique_id(const uint64_t tenant_id, share::ObCommonID &id); + + // Send rpc to the leader of sys LS of target tenant to execute gen_unique_id. + // + // Use this one when target tenant doesn't exist on current machine. + static int gen_unique_id_by_rpc(const uint64_t tenant_id, share::ObCommonID &id); + + // Use ObMaxIdFetcher to generate monotonically increasing ID for ObCommonID in target tenant + // + // @param [in] tenant_id target tenant id + // @param [in] id_type id type for ObMaxIdFetcher + // @param [in] proxy sql proxy + // @param [out] id generated monotonically increasing ID + static int gen_monotonic_id(const uint64_t tenant_id, + const share::ObMaxIdType id_type, + common::ObMySQLProxy &proxy, + share::ObCommonID &id); +}; + +} +} + +#endif /* OCEANBASE_STORAGE_OB_COMMON_ID_UTILS_H_ */ diff --git a/src/storage/ob_disk_usage_reporter.cpp b/src/storage/ob_disk_usage_reporter.cpp index 6130e441b..3e7e9cf55 100644 --- a/src/storage/ob_disk_usage_reporter.cpp +++ b/src/storage/ob_disk_usage_reporter.cpp @@ -38,8 +38,6 @@ namespace storage ObDiskUsageReportTask::ObDiskUsageReportTask() : is_inited_(false), - tablet_iter_(nullptr), - iter_buf_(nullptr), sql_proxy_(NULL) { // do nothing @@ -56,12 +54,6 @@ int ObDiskUsageReportTask::init(ObMySQLProxy &sql_proxy) STORAGE_LOG(WARN, "Failed to create result_map_", K(ret)); } else if (OB_FAIL(disk_usage_table_operator_.init(sql_proxy))) { STORAGE_LOG(WARN, "failed to init disk_usage_table_operator_", K(ret)); - } else if (OB_FAIL(allocator_.init(lib::ObMallocAllocator::get_instance(), - OB_MALLOC_NORMAL_BLOCK_SIZE, mem_attr))) { - STORAGE_LOG(WARN, "fail to init fifo allocator", K(ret)); - } else if (OB_ISNULL(iter_buf_ = allocator_.alloc(sizeof(ObTenantTabletIterator)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - SERVER_LOG(WARN, "fail to alloc tablet iter buf", K(ret)); } else { sql_proxy_ = &sql_proxy; is_inited_ = true; @@ -77,13 +69,6 @@ int ObDiskUsageReportTask::init(ObMySQLProxy &sql_proxy) void ObDiskUsageReportTask::destroy() { result_map_.destroy(); - if (OB_NOT_NULL(tablet_iter_)) { - tablet_iter_->~ObTenantTabletIterator(); - tablet_iter_ = nullptr; - } - if (OB_NOT_NULL(iter_buf_)) { - allocator_.free(iter_buf_); - } is_inited_ = false; } @@ -202,42 +187,36 @@ int ObDiskUsageReportTask::count_tenant_data(const uint64_t tenant_id) { int ret = OB_SUCCESS; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, allocator_); + ObArenaAllocator iter_allocator("DiskReport", OB_MALLOC_NORMAL_BLOCK_SIZE, tenant_id); + ObTenantTabletIterator tablet_iter(*t3m, iter_allocator); ObTabletHandle tablet_handle; ObDiskUsageReportKey report_key; - if (OB_ISNULL(tablet_iter_)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "fail to new tablet_iter_", K(ret)); - } else { - int64_t data_size = 0; - int64_t sstable_size = 0; - while (OB_SUCC(ret) && OB_SUCC(tablet_iter_->get_next_tablet(tablet_handle))) { - if (OB_UNLIKELY(!tablet_handle.is_valid())) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "unexpected invalid tablet", K(ret), K(tablet_handle)); - } else if (OB_FAIL(tablet_handle.get_obj()->get_sstables_size(sstable_size, true /*ignore shared block*/))) { - STORAGE_LOG(WARN, "failed to get new tablet's disk usage", K(ret), K(sstable_size)); - } else { - data_size += sstable_size; - } - sstable_size = 0; + int64_t data_size = 0; + int64_t sstable_size = 0; + while (OB_SUCC(ret) && OB_SUCC(tablet_iter.get_next_tablet(tablet_handle))) { + if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "unexpected invalid tablet", K(ret), K(tablet_handle)); + } else if (OB_FAIL(tablet_handle.get_obj()->get_sstables_size(sstable_size, true /*ignore shared block*/))) { + STORAGE_LOG(WARN, "failed to get new tablet's disk usage", K(ret), K(sstable_size)); + } else { + data_size += sstable_size; } - if (OB_ITER_END == ret || OB_SUCCESS == ret) { - ret = OB_SUCCESS; - data_size += MTL(ObSharedMacroBlockMgr*)->get_shared_block_cnt() * OB_DEFAULT_MACRO_BLOCK_SIZE; - report_key.tenant_id_ = tenant_id; - report_key.file_type_ = ObDiskReportFileType::OB_DISK_REPORT_TENANT_DATA; - if (OB_FAIL(result_map_.set_refactored(report_key, data_size, 1))) { - STORAGE_LOG(WARN, "failed to set result_map_", K(ret), K(report_key), K(data_size)); - } + sstable_size = 0; + tablet_handle.reset(); + iter_allocator.reuse(); + } + if (OB_ITER_END == ret || OB_SUCCESS == ret) { + ret = OB_SUCCESS; + data_size += MTL(ObSharedMacroBlockMgr*)->get_shared_block_cnt() * OB_DEFAULT_MACRO_BLOCK_SIZE; + report_key.tenant_id_ = tenant_id; + report_key.file_type_ = ObDiskReportFileType::OB_DISK_REPORT_TENANT_DATA; + if (OB_FAIL(result_map_.set_refactored(report_key, data_size, 1))) { + STORAGE_LOG(WARN, "failed to set result_map_", K(ret), K(report_key), K(data_size)); } } - if (OB_NOT_NULL(tablet_iter_)) { - tablet_iter_->~ObTenantTabletIterator(); - tablet_iter_ = nullptr; - } return ret; } diff --git a/src/storage/ob_disk_usage_reporter.h b/src/storage/ob_disk_usage_reporter.h index d204f40e2..ab2615ff3 100644 --- a/src/storage/ob_disk_usage_reporter.h +++ b/src/storage/ob_disk_usage_reporter.h @@ -96,11 +96,8 @@ private: private: bool is_inited_; ReportResultMap result_map_; - ObTenantTabletIterator *tablet_iter_; - void *iter_buf_; common::ObMySQLProxy *sql_proxy_; share::ObDiskUsageTableOperator disk_usage_table_operator_; - common::ObFIFOAllocator allocator_; }; } // namespace storage diff --git a/src/storage/ob_dml_running_ctx.cpp b/src/storage/ob_dml_running_ctx.cpp index a416eaf01..3a0f52f3a 100644 --- a/src/storage/ob_dml_running_ctx.cpp +++ b/src/storage/ob_dml_running_ctx.cpp @@ -22,6 +22,7 @@ #include "storage/tablet/ob_tablet.h" #include "storage/tablet/ob_tablet_binding_helper.h" #include "storage/ob_value_row_iterator.h" +#include "storage/memtable/ob_memtable_context.h" namespace oceanbase { @@ -76,8 +77,8 @@ int ObDMLRunningCtx::init( const uint64_t table_id = dml_param_.table_param_->get_data_table().get_table_id(); const int64_t version = dml_param_.schema_version_; const int64_t tenant_schema_version = dml_param_.tenant_schema_version_; - if (!tablet_handle.get_obj()->is_lob_meta_tablet() && - OB_FAIL(check_schema_version(*schema_service, tenant_id, table_id, tenant_schema_version, version, tablet_handle))) { + if (dml_param_.check_schema_version_ && OB_FAIL(check_schema_version(*schema_service, tenant_id, table_id, + tenant_schema_version, version, tablet_handle))) { LOG_WARN("failed to check schema version", K(ret), K(tenant_id), K(tenant_schema_version), K(table_id), K(version)); } } @@ -92,6 +93,7 @@ int ObDMLRunningCtx::init( } else if (NULL != column_ids && OB_FAIL(prepare_column_info(*column_ids))) { LOG_WARN("fail to get column descriptions and column map", K(ret), K(*column_ids)); } else { + store_ctx_.mvcc_acc_ctx_.mem_ctx_->set_table_version(dml_param_.schema_version_); store_ctx_.table_version_ = dml_param_.schema_version_; column_ids_ = column_ids; is_inited_ = true; @@ -135,9 +137,10 @@ int ObDMLRunningCtx::prepare_relative_table( if (OB_FAIL(relative_table_.init(&schema, tablet_handle.get_obj()->get_tablet_meta().tablet_id_, schema.is_storage_index_table() && !schema.can_read_index()))) { LOG_WARN("fail to init relative_table_", K(ret), K(tablet_handle), K(schema.get_index_status())); - } else if (FALSE_IT(relative_table_.tablet_iter_.tablet_handle_ = tablet_handle)) { - } else if (OB_FAIL(tablet_handle.get_obj()->get_read_tables( - read_snapshot.get_val_for_tx(), relative_table_.tablet_iter_, relative_table_.allow_not_ready()))) { + } else if (OB_FAIL(relative_table_.tablet_iter_.set_tablet_handle(tablet_handle))) { + LOG_WARN("fail to set tablet handle to iter", K(ret), K(relative_table_.tablet_iter_)); + } else if (OB_FAIL(relative_table_.tablet_iter_.refresh_read_tables_from_tablet( + read_snapshot.get_val_for_tx(), relative_table_.allow_not_ready()))) { LOG_WARN("failed to get relative table read tables", K(ret)); } return ret; @@ -189,8 +192,13 @@ int ObDMLRunningCtx::check_schema_version( LOG_WARN("table version mismatch", K(ret), K(table_id), K(table_version), K(table_schema->get_schema_version())); } if (OB_SUCC(ret)) { - if (OB_FAIL(ObTabletBindingHelper::check_schema_version(tablet_handle, table_version))) { - LOG_WARN("failed to check schema version", K(ret)); + const int64_t current_time = ObClockGenerator::getClock(); + const int64_t timeout = dml_param_.timeout_ - current_time; + if (OB_UNLIKELY(timeout <= 0)) { + ret = OB_TIMEOUT; + LOG_WARN("check schema version timeout", K(ret), K(current_time), "dml_param_timeout", dml_param_.timeout_); + } else if (OB_FAIL(tablet_handle.get_obj()->check_schema_version_with_cache(table_version, timeout))) { + LOG_WARN("failed to check schema version", K(ret), K(table_version), K(timeout)); } } return ret; diff --git a/src/storage/ob_i_memtable_mgr.cpp b/src/storage/ob_i_memtable_mgr.cpp index 404d1c16f..8516d9a7f 100644 --- a/src/storage/ob_i_memtable_mgr.cpp +++ b/src/storage/ob_i_memtable_mgr.cpp @@ -387,7 +387,8 @@ void ObMemtableMgrHandle::reset() { if (nullptr != memtable_mgr_) { if (nullptr == pool_) { - STORAGE_LOG(DEBUG, "this memory manager is a special handle", KPC(memtable_mgr_)); + STORAGE_LOG(DEBUG, "this memory manager is a special handle", KP(memtable_mgr_), "ref_cnt", + memtable_mgr_->get_ref(), K(lbt())); // at present, inner tablet's memtable_mgr_ is not managed by pool, // just decrease ref and leave the release to the owner of memtable_mgr. memtable_mgr_->dec_ref(); diff --git a/src/storage/ob_i_memtable_mgr.h b/src/storage/ob_i_memtable_mgr.h index a696625bd..79f0e8a86 100644 --- a/src/storage/ob_i_memtable_mgr.h +++ b/src/storage/ob_i_memtable_mgr.h @@ -15,6 +15,7 @@ #include "lib/lock/ob_spin_rwlock.h" #include "lib/lock/ob_qsync_lock.h" +#include "ob_tablet_id.h" #include "storage/ob_i_table.h" #include "storage/memtable/ob_multi_source_data.h" @@ -266,6 +267,8 @@ public: int get_newest_snapshot_version(share::SCN &snapshot_version); + common::ObTabletID get_tablet_id() const { return tablet_id_; } + OB_INLINE int64_t dec_ref() { return ATOMIC_SAF(&ref_cnt_, 1 /* just sub 1 */); } OB_INLINE int64_t get_ref() const { return ATOMIC_LOAD(&ref_cnt_); } OB_INLINE void inc_ref() { ATOMIC_INC(&ref_cnt_); } diff --git a/src/storage/ob_i_store.cpp b/src/storage/ob_i_store.cpp index 4d6960ce1..4f091721f 100644 --- a/src/storage/ob_i_store.cpp +++ b/src/storage/ob_i_store.cpp @@ -137,6 +137,7 @@ void ObStoreRowLockState::reset() lock_dml_flag_ = blocksstable::ObDmlFlag::DF_NOT_EXIST; is_delayed_cleanout_ = false; mvcc_row_ = NULL; + trans_scn_ = SCN::max_scn(); } OB_DEF_SERIALIZE(ObStoreRow) @@ -321,7 +322,7 @@ int ObLockRowChecker::check_lock_row_valid( int ObLockRowChecker::check_lock_row_valid( const blocksstable::ObDatumRow &row, - const ObTableReadInfo &read_info) + const ObITableReadInfo &read_info) { int ret = OB_SUCCESS; int64_t rowkey_read_cnt = MIN(read_info.get_seq_read_column_count(), read_info.get_rowkey_count()); @@ -329,7 +330,7 @@ int ObLockRowChecker::check_lock_row_valid( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(read_info), K(row)); } else if (row.is_uncommitted_row()) { - const common::ObIArray &col_index = read_info.get_columns_index(); + const ObColumnIndexArray &col_index = read_info.get_columns_index(); for (int i = rowkey_read_cnt; i < row.get_column_count(); ++i) { if (col_index.at(i) < read_info.get_rowkey_count()) { // not checking rowkey col diff --git a/src/storage/ob_i_store.h b/src/storage/ob_i_store.h index 0ed76e95c..145556127 100644 --- a/src/storage/ob_i_store.h +++ b/src/storage/ob_i_store.h @@ -228,7 +228,8 @@ public: lock_data_sequence_(0), lock_dml_flag_(blocksstable::ObDmlFlag::DF_NOT_EXIST), is_delayed_cleanout_(false), - mvcc_row_(NULL) {} + mvcc_row_(NULL), + trans_scn_(share::SCN::max_scn()) {} void reset(); TO_STRING_KV(K_(is_locked), K_(trans_version), @@ -236,7 +237,8 @@ public: K_(lock_data_sequence), K_(lock_dml_flag), K_(is_delayed_cleanout), - KP_(mvcc_row)); + KP_(mvcc_row), + K_(trans_scn)); bool is_locked_; share::SCN trans_version_; @@ -245,6 +247,7 @@ public: blocksstable::ObDmlFlag lock_dml_flag_; bool is_delayed_cleanout_; memtable::ObMvccRow *mvcc_row_; + share::SCN trans_scn_; // sstable takes end_scn, memtable takes scn_ of ObMvccTransNode }; @@ -320,7 +323,7 @@ public: bool is_memtable_iter_row_check); static int check_lock_row_valid( const blocksstable::ObDatumRow &row, - const ObTableReadInfo &read_info); + const ObITableReadInfo &read_info); }; #define STORE_ITER_ROW_IN_GAP 1 diff --git a/src/storage/ob_i_table.cpp b/src/storage/ob_i_table.cpp index 5ec53606b..0a68a4c5d 100644 --- a/src/storage/ob_i_table.cpp +++ b/src/storage/ob_i_table.cpp @@ -14,6 +14,7 @@ #include "storage/ob_i_table.h" #include "share/ob_force_print_log.h" #include "storage/blocksstable/ob_sstable.h" +#include "storage/blocksstable/ob_storage_cache_suite.h" #include "storage/memtable/ob_memtable.h" #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" #include "storage/tablelock/ob_lock_memtable.h" @@ -128,7 +129,7 @@ int ObITable::safe_to_destroy(bool &is_safe) int ObITable::exist( ObStoreCtx &ctx, const uint64_t table_id, - const storage::ObTableReadInfo &read_info, + const storage::ObITableReadInfo &read_info, const blocksstable::ObDatumRowkey &rowkey, bool &is_exist, bool &has_found) @@ -142,6 +143,21 @@ int ObITable::exist( return common::OB_NOT_SUPPORTED; } +int ObITable::exist( + const ObTableIterParam ¶m, + ObTableAccessContext &context, + const blocksstable::ObDatumRowkey &rowkey, + bool &is_exist, + bool &has_found) +{ + UNUSED(param); + UNUSED(context); + UNUSED(rowkey); + is_exist = false; + has_found = false; + return common::OB_NOT_SUPPORTED; +} + int ObITable::exist( ObRowsInfo &rows_info, bool &is_exist, @@ -167,16 +183,11 @@ int64_t ObITable::to_string(char *buf, const int64_t buf_len) const } ObTableHandleV2::ObTableHandleV2() - : table_(nullptr), t3m_(nullptr), allocator_(nullptr), table_type_(ObITable::TableType::MAX_TABLE_TYPE) + : table_(nullptr), t3m_(nullptr), allocator_(nullptr), + meta_handle_(), table_type_(ObITable::TableType::MAX_TABLE_TYPE) { } -ObTableHandleV2::ObTableHandleV2(ObITable *table, ObTenantMetaMemMgr *t3m, ObITable::TableType type) - : table_(nullptr), t3m_(nullptr), allocator_(nullptr), table_type_(type) -{ - abort_unless(OB_SUCCESS == set_table(table, t3m, table_type_)); -} - ObTableHandleV2::~ObTableHandleV2() { reset(); @@ -184,8 +195,17 @@ ObTableHandleV2::~ObTableHandleV2() bool ObTableHandleV2::is_valid() const { - return nullptr != table_ - && ((nullptr != t3m_ && nullptr == allocator_) || (nullptr == t3m_ && nullptr != allocator_)); + bool bret = false; + if (nullptr == table_) { + } else if (ObITable::is_memtable(table_type_)) { + bret = (nullptr != t3m_) ^ (nullptr != allocator_); + } else if (ObITable::is_ddl_mem_sstable(table_type_)) { + bret = nullptr != t3m_; + } else { + // all other sstables + bret = (meta_handle_.is_valid() ^ (nullptr != allocator_)) || lifetime_guaranteed_by_tablet_; + } + return bret; } void ObTableHandleV2::reset() @@ -199,18 +219,23 @@ void ObTableHandleV2::reset() if (0 == ref_cnt) { if (nullptr != t3m_) { t3m_->push_table_into_gc_queue(table_, table_type_); - } else { + } else if (nullptr != allocator_) { table_->~ObITable(); allocator_->free(table_); + } else if (OB_UNLIKELY(!ObITable::is_sstable(table_type_))) { + LOG_ERROR_RET(OB_ERR_UNEXPECTED, "possible table leak!!!", K(ref_cnt), KPC(table_), K(table_type_)); } - } else if (OB_UNLIKELY(ref_cnt < 0)) { + } else if (OB_UNLIKELY(ref_cnt < 0 && !ObITable::is_sstable(table_type_))) { LOG_ERROR_RET(OB_ERR_UNEXPECTED, "table ref cnt may be leaked", K(ref_cnt), KP(table_), K(table_type_)); } - table_ = nullptr; - t3m_ = nullptr; - allocator_ = nullptr; } } + table_ = nullptr; + t3m_ = nullptr; + allocator_ = nullptr; + table_type_ = ObITable::TableType::MAX_TABLE_TYPE; + meta_handle_.reset(); + lifetime_guaranteed_by_tablet_ = false; } int ObTableHandleV2::get_sstable(blocksstable::ObSSTable *&sstable) @@ -418,7 +443,12 @@ int ObTableHandleV2::get_lock_memtable(const ObLockMemtable *&memtable) const } ObTableHandleV2::ObTableHandleV2(const ObTableHandleV2 &other) - : table_(nullptr), t3m_(nullptr) + : table_(nullptr), + t3m_(nullptr), + allocator_(nullptr), + meta_handle_(), + table_type_(ObITable::TableType::MAX_TABLE_TYPE), + lifetime_guaranteed_by_tablet_(false) { *this = other; } @@ -436,8 +466,10 @@ ObTableHandleV2 &ObTableHandleV2::operator= (const ObTableHandleV2 &other) other.table_->inc_ref(); t3m_ = other.t3m_; allocator_ = other.allocator_; + meta_handle_ = other.meta_handle_; table_type_ = other.table_type_; - if (OB_UNLIKELY(other.table_->get_ref() < 2)) { + lifetime_guaranteed_by_tablet_ = other.lifetime_guaranteed_by_tablet_; + if (!ObITable::is_sstable(table_type_) && OB_UNLIKELY(other.table_->get_ref() < 2)) { STORAGE_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "The reference count of the table is unexpectedly decreased," " the possible reason is that the table handle has concurrency", K(other)); } @@ -459,6 +491,9 @@ int ObTableHandleV2::set_table( OB_UNLIKELY(!ObITable::is_table_type_valid(table_type))) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "invalid argument", K(ret), KP(table), KP(t3m), K(table_type)); + } else if (OB_UNLIKELY(ObITable::is_sstable(table_type) && !ObITable::is_ddl_mem_sstable(table_type))) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(ERROR, "sstable should not use this interface", K(ret), KP(table), K(table_type)); } else { table_ = table; table_->inc_ref(); @@ -469,7 +504,7 @@ int ObTableHandleV2::set_table( return ret; } -int ObTableHandleV2::set_table( +int ObTableHandleV2::set_sstable( ObITable *table, common::ObIAllocator *allocator) { @@ -483,16 +518,51 @@ int ObTableHandleV2::set_table( table_->inc_ref(); t3m_ = nullptr; allocator_ = allocator; - table_type_ = ObITable::TableType::MAX_TABLE_TYPE; + table_type_ = table->get_key().table_type_; + } + return ret; +} + +int ObTableHandleV2::set_sstable_with_tablet(ObITable *table) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_ISNULL(table) + || OB_UNLIKELY(!ObITable::is_sstable(table->get_key().table_type_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KPC(table)); + } else { + table_ = table; + table_->inc_ref(); + lifetime_guaranteed_by_tablet_ = true; + table_type_ = table->get_key().table_type_; + } + return ret; +} + +int ObTableHandleV2::set_sstable(ObITable *table, const ObStorageMetaHandle &meta_handle) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_ISNULL(table) + || OB_UNLIKELY(!ObITable::is_sstable(table->get_key().table_type_)) + || OB_UNLIKELY(!meta_handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KPC(table), K(meta_handle)); + } else { + table_ = table; + table_->inc_ref(); + t3m_ = nullptr; + allocator_ = nullptr; + meta_handle_ = meta_handle; + table_type_ = table->get_key().table_type_; } return ret; } ObTablesHandleArray::ObTablesHandleArray() - : meta_mem_mgr_(nullptr), - allocator_(nullptr), - tablet_id_(), - tables_() + : tablet_id_(), + handles_array_() { } @@ -503,106 +573,79 @@ ObTablesHandleArray::~ObTablesHandleArray() void ObTablesHandleArray::reset() { - if (tables_.count() > 0) { - for (int64_t i = 0; i < tables_.count(); ++i) { - ObITable *table = tables_.at(i); - if (OB_NOT_NULL(table)) { - const int64_t ref_cnt = table->dec_ref(); - if (0 == ref_cnt) { - if (OB_ISNULL(meta_mem_mgr_) && OB_ISNULL(allocator_)) { - STORAGE_LOG_RET(ERROR, OB_ERR_UNEXPECTED, "[MEMORY LEAK] meta_mem_mgr is unexpected null!!!", KPC(table), K(tablet_id_), KP(meta_mem_mgr_), KP(allocator_)); - } else if (nullptr != meta_mem_mgr_) { - meta_mem_mgr_->push_table_into_gc_queue(table, table->get_key().table_type_); - } else { - table->~ObITable(); - allocator_->free(table); - } - } else if (OB_UNLIKELY(ref_cnt < 0)) { - LOG_ERROR_RET(OB_ERR_UNEXPECTED, "table ref cnt may be leaked", K(ref_cnt), KP(table), "table type", table->get_key().table_type_); - } - } - tables_.at(i) = nullptr; - } - tables_.reset(); - tablet_id_.reset(); - meta_mem_mgr_ = nullptr; - allocator_ = nullptr; - } + tablet_id_.reset(); + handles_array_.reset(); } -int ObTablesHandleArray::add_table(ObITable *table, common::ObIAllocator *allocator) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(table) || OB_ISNULL(allocator)) { - ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid arguments", K(ret), KP(table), KP(allocator)); - } else if (OB_NOT_NULL(meta_mem_mgr_)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tables either use an allocator or a t3m, not a mix", K(ret), KP(allocator_), - KP(meta_mem_mgr_), KP(MTL(ObTenantMetaMemMgr *))); - } else if (0 == tables_.count()) { // first add table, set allocator_ && tablet_id - allocator_ = allocator; - tablet_id_ = table->get_key().tablet_id_; - } else if (OB_UNLIKELY(allocator_ != allocator)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tables must own the same allocator!!!", K(ret), KP(allocator_), KP(allocator)); - } else if (OB_UNLIKELY(tablet_id_ != table->get_key().tablet_id_)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tables must belong to the same tablet!!!", K(ret), K(tablet_id_), K(table->get_key())); - } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(tables_.push_back(table))) { - STORAGE_LOG(WARN, "failed to add table", K(ret)); - } else { - table->inc_ref(); - } - return ret; -} - -int ObTablesHandleArray::add_table(ObITable *table) +int ObTablesHandleArray::add_memtable(ObITable *table) { int ret = OB_SUCCESS; + ObTableHandleV2 handle; if (OB_ISNULL(table)) { ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "get invalid arguments", K(ret), KP(table)); - } else if (0 == tables_.count()) { // first add table, set meta_mem_mgr && tablet_id - if (OB_ISNULL(meta_mem_mgr_ = MTL(ObTenantMetaMemMgr *))) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "failed to get TenantMetaMemMgr from MTL", K(ret)); - } else { - allocator_ = nullptr; - tablet_id_ = table->get_key().tablet_id_; - } - } else if (OB_NOT_NULL(allocator_)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tables either use an allocator or a t3m, not a mix", K(ret), KP(allocator_), - KP(meta_mem_mgr_), KP(MTL(ObTenantMetaMemMgr *))); - } else if (OB_UNLIKELY(meta_mem_mgr_ != MTL(ObTenantMetaMemMgr *))) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tables must own the same t3m!!!", K(ret), KP(meta_mem_mgr_), KP(MTL(ObTenantMetaMemMgr *))); - } else if (OB_UNLIKELY(tablet_id_ != table->get_key().tablet_id_)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tables must belong to the same tablet!!!", K(ret), K(tablet_id_), K(table->get_key())); - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(tables_.push_back(table))) { - STORAGE_LOG(WARN, "failed to add table", K(ret)); - } else { - table->inc_ref(); + LOG_WARN("get invalid arguments", K(ret), KP(table)); + } else if (OB_FAIL(tablet_id_check(table->get_key().get_tablet_id()))) { + LOG_WARN("failed to check tablet id", K(ret), KPC(table)); + } else if (OB_FAIL(handle.set_table(table, MTL(ObTenantMetaMemMgr *), table->get_key().table_type_))) { + LOG_WARN("failed to set table to handle", K(ret)); + } else if (OB_FAIL(handles_array_.push_back(handle))) { + LOG_WARN("failed to add table handle", K(ret), K(handle)); } return ret; } -int ObTablesHandleArray::add_table(ObTableHandleV2 &handle) +int ObTablesHandleArray::add_table(const ObTableHandleV2 &handle) { int ret = OB_SUCCESS; - if (OB_NOT_NULL(handle.get_allocator())) { - if (OB_FAIL(add_table(handle.get_table(), handle.get_allocator()))) { - STORAGE_LOG(WARN, "fail to add table", K(ret), K(handle)); + if (OB_FAIL(tablet_id_check(handle.get_table()->get_key().get_tablet_id()))) { + LOG_WARN("failed to add table handle to array", K(ret)); + } else if (OB_FAIL(handles_array_.push_back(handle))) { + STORAGE_LOG(WARN, "failed to add sstable", K(ret), K(handle)); + } + return ret; +} + +int ObTablesHandleArray::add_sstable(ObITable *table, const ObStorageMetaHandle &meta_handle) +{ + // invalid meta_handle means table lifetime is guaranteed by tablet handle + int ret = OB_SUCCESS; + ObTableHandleV2 table_handle; + if (OB_UNLIKELY(!table->is_sstable())) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid table type", K(ret), KPC(table)); + } else if (OB_FAIL(tablet_id_check(table->get_key().get_tablet_id()))) { + LOG_WARN("failed to check tablet id", K(ret), KPC(table)); + } else if (static_cast(table)->is_loaded()) { + if (!meta_handle.is_valid()) { + if (OB_FAIL(table_handle.set_sstable_with_tablet(table))) { + LOG_WARN("fail to set sstable with tablet", K(ret), KPC(table)); + } + } else if (OB_FAIL(table_handle.set_sstable(table, meta_handle))) { + LOG_WARN("fail to set table handle", K(ret), KPC(table)); } - } else if (OB_FAIL(add_table(handle.get_table()))) { - STORAGE_LOG(WARN, "fail to add table", K(ret), K(handle)); + } else { + const ObMetaDiskAddr addr = static_cast(table)->get_addr(); + if (OB_UNLIKELY(!addr.is_valid() || addr.is_none())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(addr)); + } else { + // FIXME: this reload logic looks weird here, should remove after resolve dependencies + ObStorageMetaCache &meta_cache = OB_STORE_CACHE.get_storage_meta_cache(); + ObStorageMetaKey meta_key(MTL_ID(), addr); + ObStorageMetaHandle handle; + ObSSTable *sstable = nullptr; + if (OB_FAIL(meta_cache.get_meta(ObStorageMetaValue::MetaType::SSTABLE, meta_key, handle, nullptr))) { + LOG_WARN("fail to get sstable from meta cache", K(ret), K(addr)); + } else if (OB_FAIL(handle.get_sstable(sstable))) { + LOG_WARN("fail to get sstable", K(ret), K(handle)); + } else if (OB_FAIL(table_handle.set_sstable(sstable, handle))) { + LOG_WARN("fail to set table handle", K(ret), KPC(table), KPC(sstable)); + } + } + } + + if (FAILEDx(handles_array_.push_back(table_handle))) { + STORAGE_LOG(WARN, "failed to push back table", K(ret), KPC(table), K(table_handle)); } return ret; } @@ -611,32 +654,64 @@ int ObTablesHandleArray::assign(const ObTablesHandleArray &other) { int ret = OB_SUCCESS; reset(); - for (int64_t i = 0; OB_SUCC(ret) && i < other.get_count(); ++i) { - ObITable *table = other.get_table(i); - if (OB_ISNULL(table)) { - ret = OB_ERR_SYS; - STORAGE_LOG(WARN, "table must not null", K(ret), K(other)); - } else if (OB_NOT_NULL(other.allocator_)) { - if (OB_FAIL(add_table(table, other.allocator_))) { - STORAGE_LOG(WARN, "fail to add table", K(ret)); - } - } else if (OB_FAIL(add_table(table))) { - STORAGE_LOG(WARN, "failed to add table", K(ret)); + if (OB_FAIL(add_table(other.handles_array_.at(i)))) { + LOG_WARN("fail to add table", K(ret), K(i), K(other)); } } return ret; } +int ObTablesHandleArray::get_table(const int64_t idx, ObTableHandleV2 &table_handle) const +{ + int ret = OB_SUCCESS; + ObITable *table = nullptr; + if (OB_UNLIKELY(idx >= handles_array_.count() || idx < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(idx), K(handles_array_.count())); + } else { + const ObTableHandleV2 &handle = handles_array_.at(idx); + if (OB_UNLIKELY(!handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid table handle", K(ret), K(idx), K(handle)); + } else { + table_handle = handle; + } + } + return ret; +} + +int ObTablesHandleArray::get_table(const ObITable::TableKey &table_key, ObTableHandleV2 &table_handle) const +{ + int ret = OB_SUCCESS; + bool found = false; + for (int64_t i = 0; OB_SUCC(ret) && !found && i < handles_array_.count(); ++i) { + const ObITable *table = nullptr; + if (OB_ISNULL(table = handles_array_.at(i).get_table())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "unexpected null table pointer"); + } else if (table->get_key() == table_key) { + found = true; + if (OB_FAIL(get_table(i, table_handle))) { + STORAGE_LOG(WARN, "failed to get table by index", K(ret)); + } + } + } + if (OB_SUCC(ret) && !found) { + ret = OB_ENTRY_NOT_EXIST; + } + return ret; +} + int ObTablesHandleArray::get_tables(common::ObIArray &tables) const { int ret = OB_SUCCESS; tables.reset(); - for (int64_t i = 0; OB_SUCC(ret) && i < tables_.count(); ++i) { - if (OB_ISNULL(tables_.at(i))) { + for (int64_t i = 0; OB_SUCC(ret) && i < handles_array_.count(); ++i) { + if (OB_UNLIKELY(!handles_array_.at(i).is_valid())) { ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "get unexpected null table", K(ret), K(i), K(tables_)); - } else if (OB_FAIL(tables.push_back(tables_.at(i)))) { + STORAGE_LOG(WARN, "invalid table handle", K(ret), K(i), K_(handles_array)); + } else if (OB_FAIL(tables.push_back(handles_array_.at(i).table_))) { STORAGE_LOG(WARN, "failed to add table", K(ret)); } } @@ -647,9 +722,9 @@ int ObTablesHandleArray::get_first_memtable(memtable::ObIMemtable *&memtable) co { int ret = OB_SUCCESS; memtable = nullptr; - for (int64_t i = 0; OB_SUCC(ret) && i < tables_.count(); ++i) { - if (tables_.at(i)->is_memtable()) { - memtable = static_cast(tables_.at(i)); + for (int64_t i = 0; OB_SUCC(ret) && i < handles_array_.count(); ++i) { + if (handles_array_.at(i).get_table()->is_memtable()) { + memtable = static_cast(handles_array_.at(i).table_); break; } } @@ -664,8 +739,8 @@ int ObTablesHandleArray::get_all_minor_sstables(common::ObIArray &ta int ret = OB_SUCCESS; tables.reset(); - for (int64_t i = 0; OB_SUCC(ret) && i < tables_.count(); ++i) { - ObITable *table = tables_.at(i); + for (int64_t i = 0; OB_SUCC(ret) && i < handles_array_.count(); ++i) { + ObITable *table = handles_array_.at(i).table_; if (table->is_minor_sstable() && OB_FAIL(tables.push_back(table))) { STORAGE_LOG(WARN, "failed to add minor sstable", K(ret), K(i)); } @@ -677,14 +752,14 @@ int ObTablesHandleArray::check_continues(const share::ObScnRange *scn_range) con { int ret = OB_SUCCESS; - if (!tables_.empty()) { + if (!handles_array_.empty()) { // 1:check major sstable // there can only be one major or meta merge const ObITable *last_table = nullptr; const ObITable *table = nullptr; SCN base_end_scn = SCN::min_scn(); int64_t i = 0; - if (OB_ISNULL(table = tables_.at(i))) { + if (OB_ISNULL(table = handles_array_.at(i).get_table())) { ret = OB_ERR_SYS; LOG_WARN("table is NULL", KPC(table)); } else if (table->is_major_sstable() || table->is_meta_major_sstable()) { @@ -692,8 +767,8 @@ int ObTablesHandleArray::check_continues(const share::ObScnRange *scn_range) con i++; } // 2:check minor sstable - for ( ; OB_SUCC(ret) && i < tables_.count(); ++i) { - table = tables_.at(i); + for ( ; OB_SUCC(ret) && i < handles_array_.count(); ++i) { + table = handles_array_.at(i).get_table(); if (OB_ISNULL(table)) { ret = OB_ERR_SYS; LOG_WARN("table is NULL", KPC(table)); @@ -720,21 +795,31 @@ int ObTablesHandleArray::check_continues(const share::ObScnRange *scn_range) con return ret; } +int ObTablesHandleArray::tablet_id_check(const common::ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + if (0 == handles_array_.count()) { + tablet_id_ = tablet_id; + } else if (OB_UNLIKELY(tablet_id != tablet_id_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tablet id check in handle array failed", K(ret), K(tablet_id), K_(tablet_id)); + } + return ret; +} + int64_t ObTablesHandleArray::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; if (OB_ISNULL(buf) || buf_len <= 0) { } else { J_OBJ_START(); - J_KV(KP(meta_mem_mgr_), KP(allocator_)); - J_COMMA(); J_KV("tablet_id", tablet_id_); J_COMMA(); - J_KV("table_count", tables_.count()); + J_KV("table_count", handles_array_.count()); J_COMMA(); J_ARRAY_START(); - for (int64_t i = 0; i < tables_.count(); ++i) { - const ObITable *table = tables_.at(i); + for (int64_t i = 0; i < handles_array_.count(); ++i) { + const ObITable *table = handles_array_.at(i).get_table(); if (NULL != table) { J_OBJ_START(); J_KV(K(i), "table_key", table->get_key(), "ref", table->get_ref()); diff --git a/src/storage/ob_i_table.h b/src/storage/ob_i_table.h index 13a422f6e..250b204d2 100644 --- a/src/storage/ob_i_table.h +++ b/src/storage/ob_i_table.h @@ -24,6 +24,8 @@ #include "storage/ob_i_store.h" #include "storage/access/ob_table_read_info.h" #include "storage/meta_mem/ob_tenant_meta_obj_pool.h" +#include "storage/meta_mem/ob_storage_meta_cache.h" +#include "share/leak_checker/obj_leak_checker.h" #include "share/ob_table_range.h" #include "share/scn.h" @@ -91,6 +93,7 @@ public: REMOTE_LOGICAL_MINOR_SSTABLE = 15, DDL_MEM_SSTABLE = 16, // < add new sstable before here, See is_sstable() + MAX_TABLE_TYPE }; @@ -126,7 +129,6 @@ public: OB_INLINE bool is_ddl_mem_sstable() const { return ObITable::is_ddl_mem_sstable(table_type_); } OB_INLINE bool is_table_with_scn_range() const { return ObITable::is_table_with_scn_range(table_type_); } OB_INLINE bool is_remote_logical_minor_sstable() const { return ObITable::is_remote_logical_minor_sstable(table_type_); } - OB_INLINE const common::ObTabletID &get_tablet_id() const { return tablet_id_; } OB_INLINE share::SCN get_start_scn() const { return scn_range_.start_scn_; } OB_INLINE share::SCN get_end_scn() const { return scn_range_.end_scn_; } @@ -169,10 +171,16 @@ public: virtual int exist( ObStoreCtx &ctx, const uint64_t table_id, - const storage::ObTableReadInfo &read_info, + const storage::ObITableReadInfo &read_info, const blocksstable::ObDatumRowkey &rowkey, bool &is_exist, bool &has_found); + virtual int exist( + const ObTableIterParam ¶m, + ObTableAccessContext &context, + const blocksstable::ObDatumRowkey &rowkey, + bool &is_exist, + bool &has_found); virtual int exist( ObRowsInfo &rowsInfo, @@ -212,9 +220,9 @@ public: virtual int64_t get_max_merged_trans_version() const { return get_snapshot_version(); } virtual int get_frozen_schema_version(int64_t &schema_version) const = 0; - void inc_ref(); + virtual void inc_ref(); virtual int64_t dec_ref(); - inline int64_t get_ref() const { return ATOMIC_LOAD(&ref_cnt_); } + virtual int64_t get_ref() const { return ATOMIC_LOAD(&ref_cnt_); } // TODO @hanhui so many table type judgement virtual bool is_sstable() const { return is_sstable(key_.table_type_); } @@ -365,9 +373,9 @@ inline int64_t ObITable::dec_ref() class ObTableHandleV2 final { + friend class ObTablesHandleArray; public: ObTableHandleV2(); - ObTableHandleV2(ObITable *table, ObTenantMetaMemMgr *t3m, ObITable::TableType type); ~ObTableHandleV2(); bool is_valid() const; @@ -376,6 +384,7 @@ public: OB_INLINE ObITable *get_table() { return table_; } OB_INLINE const ObITable *get_table() const { return table_; } OB_INLINE common::ObIAllocator *get_allocator() { return allocator_; } + OB_INLINE const ObStorageMetaHandle &get_meta_handle() { return meta_handle_; } int get_sstable(blocksstable::ObSSTable *&sstable); int get_sstable(const blocksstable::ObSSTable *&sstable) const; @@ -394,47 +403,59 @@ public: ObTableHandleV2 &operator= (const ObTableHandleV2 &other); int set_table(ObITable *const table, ObTenantMetaMemMgr *const t3m, const ObITable::TableType table_type); - int set_table(ObITable *table, common::ObIAllocator *allocator); - - TO_STRING_KV(KP_(table), KP(t3m_), KP(allocator_), K(table_type_)); + // TODO: simplify set_sstable interfaces + // only used when create stand alone sstable + int set_sstable(ObITable *table, common::ObIAllocator *allocator); + // set sstable when lifetime is guaranteed by tablet + int set_sstable_with_tablet(ObITable *table); + int set_sstable(ObITable *table, const ObStorageMetaHandle &meta_handle); + TO_STRING_KV(KP_(table), KP(t3m_), KP(allocator_), K(table_type_), + K_(meta_handle), K_(lifetime_guaranteed_by_tablet)); private: ObITable *table_; ObTenantMetaMemMgr *t3m_; common::ObIAllocator *allocator_; + ObStorageMetaHandle meta_handle_; ObITable::TableType table_type_; + bool lifetime_guaranteed_by_tablet_; }; class ObTablesHandleArray final { public: typedef common::ObSEArray TableArray; + typedef common::ObArray MetaHandleArray; + typedef common::ObArray HandlesArray; ObTablesHandleArray(); ~ObTablesHandleArray(); void reset(); - OB_INLINE bool empty() const { return tables_.empty(); } - OB_INLINE int64_t get_count() const { return tables_.count(); } - OB_INLINE common::ObIArray &get_tables() { return tables_; } - OB_INLINE const common::ObIArray &get_tables() const { return tables_; } - OB_INLINE ObITable *get_table(const int64_t idx) const { return (idx < 0 || idx >= tables_.count()) ? nullptr : tables_.at(idx); } + OB_INLINE bool empty() const { return handles_array_.empty(); } + OB_INLINE int64_t get_count() const { return handles_array_.count(); } + OB_INLINE ObITable *get_table(const int64_t idx) const + { + return (idx < 0 || idx >= handles_array_.count()) ? nullptr : handles_array_.at(idx).table_; + } - int add_table(ObITable *table); - int add_table(ObITable *table, common::ObIAllocator *allocator); - int add_table(ObTableHandleV2 &handle); + int get_table(const int64_t idx, ObTableHandleV2 &table_handle) const; + int get_table(const ObITable::TableKey &table_key, ObTableHandleV2 &table_handle) const; + // TODO: simplify this add_sstable interface + int add_sstable(ObITable *table, const ObStorageMetaHandle &meta_handle); + int add_memtable(ObITable *table); + int add_table(const ObTableHandleV2 &handle); int assign(const ObTablesHandleArray &other); int get_tables(common::ObIArray &tables) const; int get_first_memtable(memtable::ObIMemtable *&memtable) const; int get_all_minor_sstables(common::ObIArray &tables) const; int check_continues(const share::ObScnRange *scn_range) const; - TableArray::iterator table_begin() { return tables_.begin(); } - TableArray::iterator table_end() { return tables_.end(); } DECLARE_TO_STRING; private: - storage::ObTenantMetaMemMgr *meta_mem_mgr_; - common::ObIAllocator *allocator_; + int tablet_id_check(const common::ObTabletID &tablet_id); + +private: common::ObTabletID tablet_id_; - TableArray tables_; + HandlesArray handles_array_; DISALLOW_COPY_AND_ASSIGN(ObTablesHandleArray); }; diff --git a/src/storage/ob_micro_block_handle_mgr.cpp b/src/storage/ob_micro_block_handle_mgr.cpp index fdfc62f78..be2f3024a 100644 --- a/src/storage/ob_micro_block_handle_mgr.cpp +++ b/src/storage/ob_micro_block_handle_mgr.cpp @@ -73,7 +73,6 @@ int ObMicroBlockDataHandle::get_data_block_data( if (OB_FAIL(ObStorageCacheSuite::get_instance().get_block_cache().load_block( micro_block_id, des_meta_, - nullptr, &block_reader, block_data, nullptr))) { @@ -83,15 +82,10 @@ int ObMicroBlockDataHandle::get_data_block_data( return ret; } -int ObMicroBlockDataHandle::get_index_block_data( - const ObTableReadInfo &read_info, - ObMicroBlockData &index_block) +int ObMicroBlockDataHandle::get_index_block_data(ObMicroBlockData &index_block) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!read_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid columns info", K(ret), K(read_info)); - } else if (OB_FAIL(get_loaded_block_data(index_block))) { + if (OB_FAIL(get_loaded_block_data(index_block))) { try_release_loaded_index_block(); //try sync io ObMicroBlockId micro_block_id; @@ -102,11 +96,10 @@ int ObMicroBlockDataHandle::get_index_block_data( if (OB_FAIL(ObStorageCacheSuite::get_instance().get_index_block_cache().load_block( micro_block_id, des_meta_, - &read_info, nullptr, loaded_index_block_data_, allocator_))) { - LOG_WARN("Fail to load index micro block", K(ret), K_(macro_block_id), K(read_info), K(micro_block_id)); + LOG_WARN("Fail to load index micro block", K(ret), K_(macro_block_id), K(micro_block_id)); try_release_loaded_index_block(); } else { index_block = loaded_index_block_data_; @@ -115,15 +108,10 @@ int ObMicroBlockDataHandle::get_index_block_data( return ret; } -int ObMicroBlockDataHandle::get_cached_index_block_data( - const ObTableReadInfo &read_info, - ObMicroBlockData &index_block) +int ObMicroBlockDataHandle::get_cached_index_block_data(ObMicroBlockData &index_block) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!read_info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid columns info", K(ret), K(read_info)); - } else if (ObSSTableMicroBlockState::IN_BLOCK_CACHE != block_state_) { + if (ObSSTableMicroBlockState::IN_BLOCK_CACHE != block_state_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Fail to get block data, unexpected block state", K(ret), K(block_state_)); } else { diff --git a/src/storage/ob_micro_block_handle_mgr.h b/src/storage/ob_micro_block_handle_mgr.h index 4c6654510..057a887ac 100644 --- a/src/storage/ob_micro_block_handle_mgr.h +++ b/src/storage/ob_micro_block_handle_mgr.h @@ -41,12 +41,8 @@ struct ObMicroBlockDataHandle { int get_data_block_data( blocksstable::ObMacroBlockReader &block_reader, blocksstable::ObMicroBlockData &block_data); - int get_index_block_data( - const ObTableReadInfo &read_info, - blocksstable::ObMicroBlockData &index_block); - int get_cached_index_block_data( - const ObTableReadInfo &read_info, - blocksstable::ObMicroBlockData &index_block); + int get_index_block_data(blocksstable::ObMicroBlockData &index_block); + int get_cached_index_block_data(blocksstable::ObMicroBlockData &index_block); TO_STRING_KV(K_(tenant_id), K_(macro_block_id), K_(micro_info), K_(block_state), K_(block_index), K_(cache_handle), K_(io_handle)); uint64_t tenant_id_; diff --git a/src/storage/ob_partition_range_spliter.cpp b/src/storage/ob_partition_range_spliter.cpp index a6ef19f39..d2d692151 100644 --- a/src/storage/ob_partition_range_spliter.cpp +++ b/src/storage/ob_partition_range_spliter.cpp @@ -68,13 +68,13 @@ int ObEndkeyIterator::open( ObDatumRowkey sstable_endkey; ObArenaAllocator temp_allocator; ObDatumRange datum_range; - const ObTableReadInfo *index_read_info = range_info.index_read_info_; + const ObITableReadInfo *index_read_info = range_info.index_read_info_; const ObStorageDatumUtils &datum_utils = index_read_info->get_datum_utils(); int cmp_ret = 0; // Sample start from a specified point if (OB_FAIL(datum_range.from_range(*range_info.store_range_, temp_allocator))) { STORAGE_LOG(WARN, "Failed to transfer store range", K(ret), K(range_info)); - } else if (OB_FAIL(sstable.get_last_rowkey(*index_read_info, temp_allocator, sstable_endkey))) { + } else if (OB_FAIL(sstable.get_last_rowkey(temp_allocator, sstable_endkey))) { STORAGE_LOG(WARN, "Failed to get last rowkey from sstable"); } else if (OB_FAIL(sstable_endkey.compare(datum_range.get_start_key(), datum_utils, cmp_ret))) { STORAGE_LOG(WARN, "Failed to compare sstable endkey with range start key", @@ -165,7 +165,7 @@ int ObMacroEndkeyIterator::init_endkeys( int ret = OB_SUCCESS; ObIAllocator *key_allocator = range_info.key_allocator_; ObSSTableSecMetaIterator *macro_iter = nullptr; - const ObTableReadInfo *index_read_info = range_info.index_read_info_; + const ObITableReadInfo *index_read_info = range_info.index_read_info_; ObDataMacroBlockMeta macro_meta; if (OB_UNLIKELY( @@ -215,7 +215,7 @@ int ObMicroEndkeyIterator::init_endkeys( blocksstable::ObSSTable &sstable) { int ret = OB_SUCCESS; - const ObTableReadInfo *index_read_info = range_info.index_read_info_; + const ObITableReadInfo *index_read_info = range_info.index_read_info_; ObIAllocator *key_allocator = range_info.key_allocator_; ObIMacroBlockIterator *macro_block_iter = nullptr; @@ -850,7 +850,7 @@ void ObPartitionRangeSpliter::reset() } int ObPartitionRangeSpliter::get_range_split_info(ObIArray &tables, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, const ObStoreRange &store_range, ObRangeSplitInfo &range_info) { @@ -912,7 +912,7 @@ int ObPartitionRangeSpliter::get_range_split_info(ObIArray &tables, } int ObPartitionRangeSpliter::get_single_range_info(const ObStoreRange &store_range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, ObITable *table, int64_t &total_size, int64_t ¯o_block_cnt, @@ -934,10 +934,15 @@ int ObPartitionRangeSpliter::get_single_range_info(const ObStoreRange &store_ran } else { ObSSTable *sstable = static_cast(table); if (store_range.is_whole_range()) { - total_size = sstable->get_meta().get_basic_meta().occupy_size_; - macro_block_cnt = sstable->get_meta().get_basic_meta().data_macro_block_count_; - estimate_micro_block_cnt = sstable->get_meta().get_basic_meta().data_micro_block_count_; - } else if (0 == sstable->get_meta().get_basic_meta().data_macro_block_count_) { + macro_block_cnt = sstable->get_data_macro_block_count(); + ObSSTableMetaHandle sst_meta_hdl; + if (OB_FAIL(sstable->get_meta(sst_meta_hdl))) { + STORAGE_LOG(WARN, "Failed to get sstable meta handle", K(ret)); + } else { + total_size = sst_meta_hdl.get_sstable_meta().get_occupy_size(); + estimate_micro_block_cnt = sst_meta_hdl.get_sstable_meta().get_data_micro_block_count(); + } + } else if (0 == sstable->get_data_macro_block_count()) { total_size = 0; macro_block_cnt = 0; estimate_micro_block_cnt = 0; @@ -954,7 +959,7 @@ int ObPartitionRangeSpliter::get_single_range_info(const ObStoreRange &store_ran int cmp_ret = 0; if (OB_FAIL(datum_range.from_range(store_range, temp_allocator))) { STORAGE_LOG(WARN, "Failed to transfer store range", K(ret), K(store_range)); - } else if (OB_FAIL(sstable->get_last_rowkey(index_read_info, temp_allocator, sstable_endkey))) { + } else if (OB_FAIL(sstable->get_last_rowkey(temp_allocator, sstable_endkey))) { STORAGE_LOG(WARN, "Failed to get last rowkey from sstable"); } else if (OB_FAIL(sstable_endkey.compare(datum_range.get_start_key(), datum_utils, cmp_ret))) { STORAGE_LOG(WARN, "Failed to compare sstable endkey with range start key", @@ -1145,13 +1150,18 @@ int ObPartitionMultiRangeSpliter::get_split_tables(ObTableStoreIterator &table_i } else if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Unexpected null table", K(ret), K(table_iter)); - } else if (table->is_major_sstable()) { - major_size = (reinterpret_cast(table))->get_meta().get_basic_meta().occupy_size_; - last_major_sstable = table; - } else if (table->is_minor_sstable()) { - minor_size += (reinterpret_cast(table))->get_meta().get_basic_meta().occupy_size_; - if (OB_FAIL(minor_sstables.push_back(table))) { - STORAGE_LOG(WARN, "Fail to cache minor sstables", K(ret), KP(table)); + } else if (table->is_sstable()) { + ObSSTableMetaHandle sst_meta_hdl; + if (OB_FAIL(static_cast(table)->get_meta(sst_meta_hdl))) { + STORAGE_LOG(WARN, "Fail to get sstable meta handle", K(ret)); + } else if (table->is_major_sstable()) { + major_size = sst_meta_hdl.get_sstable_meta().get_occupy_size(); + last_major_sstable = table; + } else if (table->is_minor_sstable()) { + minor_size += sst_meta_hdl.get_sstable_meta().get_occupy_size(); + if (OB_FAIL(minor_sstables.push_back(table))) { + STORAGE_LOG(WARN, "Fail to cache minor sstables", K(ret), KP(table)); + } } } else if (table->is_data_memtable()) { int64_t mem_rows = 0; @@ -1209,7 +1219,7 @@ int ObPartitionMultiRangeSpliter::get_split_tables(ObTableStoreIterator &table_i int ObPartitionMultiRangeSpliter::get_multi_range_size( const ObIArray &range_array, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, ObTableStoreIterator &table_iter, int64_t &total_size) { @@ -1450,7 +1460,7 @@ int ObPartitionMultiRangeSpliter::build_single_range_array( int ObPartitionMultiRangeSpliter::get_split_multi_ranges( const common::ObIArray &range_array, const int64_t expected_task_count, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, ObTableStoreIterator &table_iter, common::ObIAllocator &allocator, common::ObArrayArray &multi_range_split_array) @@ -1498,7 +1508,7 @@ int ObPartitionMultiRangeSpliter::get_split_multi_ranges( } int ObPartitionMultiRangeSpliter::get_range_split_infos(ObIArray &tables, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, const ObIArray &range_array, RangeSplitInfoArray &range_info_array, int64_t &total_size) @@ -1542,7 +1552,7 @@ ObPartitionMajorSSTableRangeSpliter::~ObPartitionMajorSSTableRangeSpliter() { } -int ObPartitionMajorSSTableRangeSpliter::init(const ObTableReadInfo &index_read_info, +int ObPartitionMajorSSTableRangeSpliter::init(const ObITableReadInfo &index_read_info, ObSSTable *major_sstable, int64_t tablet_size, ObIAllocator &allocator) { @@ -1587,10 +1597,10 @@ int ObPartitionMajorSSTableRangeSpliter::split_ranges(ObIArray &re STORAGE_LOG(WARN, "ObPartitionMajorSSTableRangeSpliter not init", KR(ret)); } else { // 计算parallel_degree - if (major_sstable_->get_meta().is_empty() || tablet_size_ == 0) { + if (major_sstable_->is_empty() || tablet_size_ == 0) { parallel_degree = 1; } else { - const int64_t macro_block_count = major_sstable_->get_meta().get_basic_meta().data_macro_block_count_; + const int64_t macro_block_count = major_sstable_->get_data_macro_block_count(); const int64_t occupy_size = macro_block_count * OB_SERVER_BLOCK_MGR.get_macro_block_size(); parallel_degree = (occupy_size + tablet_size_ - 1) / tablet_size_; if (parallel_degree > MAX_MERGE_THREAD) { @@ -1620,8 +1630,7 @@ int ObPartitionMajorSSTableRangeSpliter::generate_ranges_by_macro_block( { int ret = OB_SUCCESS; const ObIArray &col_descs = index_read_info_->get_columns_desc(); - const int64_t macro_block_count = - major_sstable_->get_meta().get_basic_meta().data_macro_block_count_; + const int64_t macro_block_count = major_sstable_->get_data_macro_block_count(); const int64_t macro_block_cnt_per_range = (macro_block_count + parallel_degree - 1) / parallel_degree; @@ -1761,13 +1770,11 @@ int ObPartitionIncrementalRangeSpliter::ObIncrementalIterator::prepare_table_acc { int ret = OB_SUCCESS; const ObStorageSchema *storage_schema = merge_ctx_.get_schema(); - if (OB_FAIL(storage_schema->get_rowkey_column_ids(rowkey_col_ids_))) { + if (OB_FAIL(storage_schema->get_mulit_version_rowkey_column_ids(rowkey_col_ids_))) { STORAGE_LOG(WARN, "Failed to get rowkey column ids", KR(ret)); - } else if (OB_FAIL(ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(rowkey_col_ids_))) { - STORAGE_LOG(WARN, "failed to add extra rowkey cols", KR(ret)); } else if (OB_FAIL(tbl_read_info_.init(allocator_, storage_schema->get_column_count(), storage_schema->get_rowkey_column_num(), - lib::is_oracle_mode(), rowkey_col_ids_, true))) { + lib::is_oracle_mode(), rowkey_col_ids_))) { STORAGE_LOG(WARN, "Failed to init columns info", KR(ret)); } else if (OB_FAIL(tbl_xs_param_.init_merge_param( merge_ctx_.param_.tablet_id_.id(), merge_ctx_.param_.tablet_id_, tbl_read_info_))) { @@ -1829,12 +1836,12 @@ int ObPartitionIncrementalRangeSpliter::ObIncrementalIterator::prepare_get_table ObITable *table = nullptr; for (int64_t i = 1; OB_SUCC(ret) && i < merge_ctx_.tables_handle_.get_count(); i++) { table = merge_ctx_.tables_handle_.get_table(i); - if (OB_FAIL(tbls_iter_.add_tables(&table, 1))) { + if (OB_FAIL(tbls_iter_.add_table(table))) { STORAGE_LOG(WARN, "Failed to add table to inc handle", KR(ret)); } } if (OB_SUCC(ret)) { - get_tbl_param_.tablet_iter_.table_iter_ = tbls_iter_; + *get_tbl_param_.tablet_iter_.table_iter() = tbls_iter_; } return ret; } @@ -1945,9 +1952,7 @@ int ObPartitionIncrementalRangeSpliter::init_incremental_iter() int ObPartitionIncrementalRangeSpliter::get_major_sstable_end_rowkey(ObDatumRowkey &rowkey) { int ret = OB_SUCCESS; - const ObTableReadInfo &index_read_info = - merge_ctx_->tablet_handle_.get_obj()->get_index_read_info(); - if (OB_FAIL(major_sstable_->get_last_rowkey(index_read_info, *allocator_, rowkey))) { + if (OB_FAIL(major_sstable_->get_last_rowkey(*allocator_, rowkey))) { STORAGE_LOG(WARN, "failed to get major sstable last rowkey", KR(ret), K(*major_sstable_)); } return ret; @@ -1957,9 +1962,9 @@ int ObPartitionIncrementalRangeSpliter::scan_major_sstable_secondary_meta( const ObDatumRange &scan_range, ObSSTableSecMetaIterator *&meta_iter) { int ret = OB_SUCCESS; - const ObTableReadInfo &index_read_info = - merge_ctx_->tablet_handle_.get_obj()->get_index_read_info(); - if (OB_FAIL(major_sstable_->scan_secondary_meta(*allocator_, scan_range, index_read_info, + const ObITableReadInfo &rowkey_read_info = + merge_ctx_->tablet_handle_.get_obj()->get_rowkey_read_info(); + if (OB_FAIL(major_sstable_->scan_secondary_meta(*allocator_, scan_range, rowkey_read_info, DATA_BLOCK_META, meta_iter))) { STORAGE_LOG(WARN, "Failed to scan secondary meta", KR(ret), K(*major_sstable_)); } @@ -1976,7 +1981,7 @@ int ObPartitionIncrementalRangeSpliter::check_is_incremental(bool &is_incrementa } else if (tables_handle_cnt <= 1) { // no incremental data is_incremental = false; - } else if (major_sstable_->get_meta().is_empty()) { + } else if (major_sstable_->is_empty()) { // no base data is_incremental = true; } else { @@ -1999,7 +2004,7 @@ int ObPartitionIncrementalRangeSpliter::check_is_incremental(bool &is_incrementa ObDatumRowkey end_rowkey; const int64_t rowkey_column_num = merge_ctx_->get_schema()->get_rowkey_column_num(); const ObStorageDatumUtils &datum_utils = - merge_ctx_->tablet_handle_.get_obj()->get_index_read_info().get_datum_utils(); + merge_ctx_->tablet_handle_.get_obj()->get_rowkey_read_info().get_datum_utils(); if (OB_FAIL(row_rowkey.assign(row->storage_datums_, rowkey_column_num))) { STORAGE_LOG(WARN, "failed to assign datum rowkey", KR(ret), K(*row), K(rowkey_column_num)); @@ -2035,7 +2040,7 @@ int ObPartitionIncrementalRangeSpliter::split_ranges(ObDatumRangeArray &result_r if (OB_FAIL(get_ranges_by_inc_data(*inc_ranges_))) { STORAGE_LOG(WARN, "failed to get ranges by inc data", KR(ret)); } else if (merge_ctx_->is_full_merge_) { - if (major_sstable_->get_meta().is_empty()) { + if (major_sstable_->is_empty()) { ranges = inc_ranges_; } else if (OB_FAIL(get_ranges_by_base_sstable(*base_ranges_))) { STORAGE_LOG(WARN, "failed to get ranges by base sstable", KR(ret)); @@ -2059,7 +2064,7 @@ int ObPartitionIncrementalRangeSpliter::split_ranges(ObDatumRangeArray &result_r if (OB_SUCC(ret) && result_ranges.count() > 0) { const ObStorageDatumUtils &datum_utils = - merge_ctx_->tablet_handle_.get_obj()->get_index_read_info().get_datum_utils(); + merge_ctx_->tablet_handle_.get_obj()->get_rowkey_read_info().get_datum_utils(); if (OB_FAIL(check_continuous(datum_utils, result_ranges))) { STORAGE_LOG(WARN, "failed to check continuous", KR(ret), K(result_ranges)); } @@ -2082,17 +2087,24 @@ int ObPartitionIncrementalRangeSpliter::get_ranges_by_inc_data(ObDatumRangeArray } else { int64_t num_rows_per_range = default_row_num_per_range_; // calculate num_rows_per_range by macro block - const int64_t macro_block_count = - major_sstable_->get_meta().get_basic_meta().data_macro_block_count_; + const int64_t macro_block_count = major_sstable_->get_data_macro_block_count(); const int64_t macro_block_size = OB_SERVER_BLOCK_MGR.get_macro_block_size(); if (macro_block_count * macro_block_size > tablet_size_) { - const int64_t row_count = major_sstable_->get_meta().get_basic_meta().row_count_; - const int64_t num_rows_per_macro_block = row_count / macro_block_count; - num_rows_per_range = num_rows_per_macro_block * tablet_size_ / macro_block_size; + ObSSTableMetaHandle sst_meta_hdl; + if (OB_FAIL(major_sstable_->get_meta(sst_meta_hdl))) { + STORAGE_LOG(WARN, "fail to get sstable meta handle", K(ret)); + } else { + const int64_t row_count = sst_meta_hdl.get_sstable_meta().get_row_count(); + const int64_t num_rows_per_macro_block = row_count / macro_block_count; + num_rows_per_range = num_rows_per_macro_block * tablet_size_ / macro_block_size; + } } - // to avoid block the macro-block, simply make num_rows_per_range >= DEFAULT_NOISY_ROW_NUM_SKIPPED - if (num_rows_per_range < default_noisy_row_num_skipped_) { - num_rows_per_range = default_noisy_row_num_skipped_; + + if (OB_SUCC(ret)) { + // to avoid block the macro-block, simply make num_rows_per_range >= DEFAULT_NOISY_ROW_NUM_SKIPPED + if (num_rows_per_range < default_noisy_row_num_skipped_) { + num_rows_per_range = default_noisy_row_num_skipped_; + } } const int64_t rowkey_column_num = merge_ctx_->get_schema()->get_rowkey_column_num(); @@ -2175,7 +2187,7 @@ int ObPartitionIncrementalRangeSpliter::get_ranges_by_base_sstable(ObDatumRangeA STORAGE_LOG(WARN, "Failed to scan secondary meta", KR(ret), K(*major_sstable_)); } else { const int64_t macro_block_cnt = - major_sstable_->get_meta().get_basic_meta().data_macro_block_count_; + major_sstable_->get_data_macro_block_count(); const int64_t total_size = macro_block_cnt * OB_SERVER_BLOCK_MGR.get_macro_block_size(); const int64_t range_cnt = (total_size + tablet_size_ - 1) / tablet_size_; const int64_t macro_block_cnt_per_range = (macro_block_cnt + range_cnt - 1) / range_cnt; diff --git a/src/storage/ob_partition_range_spliter.h b/src/storage/ob_partition_range_spliter.h index af0d996df..4ad9a27ce 100644 --- a/src/storage/ob_partition_range_spliter.h +++ b/src/storage/ob_partition_range_spliter.h @@ -105,7 +105,7 @@ struct ObRangeSplitInfo TO_STRING_KV(K_(store_range), KPC_(tables), K_(total_size), K_(max_macro_block_count), K_(max_estimate_micro_block_cnt), K_(parallel_target_count), K_(is_sstable)); const common::ObStoreRange *store_range_; - const ObTableReadInfo *index_read_info_; + const ObITableReadInfo *index_read_info_; common::ObIArray *tables_; int64_t total_size_; int64_t parallel_target_count_; @@ -239,7 +239,7 @@ public: ~ObPartitionRangeSpliter(); void reset(); int get_range_split_info(common::ObIArray &tables, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, const common::ObStoreRange &store_range, ObRangeSplitInfo &range_info); int split_ranges(ObRangeSplitInfo &range_info, @@ -253,7 +253,7 @@ private: common::ObIAllocator &allocator, common::ObIArray &range_array); int get_single_range_info(const ObStoreRange &store_range, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, ObITable *table, int64_t &total_size, int64_t ¯o_block_cnt, @@ -272,13 +272,13 @@ public: // return total size(byte) of all sstables in read_tables int get_multi_range_size( const common::ObIArray &range_array, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, ObTableStoreIterator &table_iter, int64_t &total_size); int get_split_multi_ranges( const common::ObIArray &range_array, const int64_t expected_task_count, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, ObTableStoreIterator &table_iter, common::ObIAllocator &allocator, common::ObArrayArray &multi_range_split_array); @@ -299,7 +299,7 @@ private: common::ObIAllocator &allocator, common::ObArrayArray &multi_range_split_array); int get_range_split_infos(common::ObIArray &tables, - const ObTableReadInfo &index_read_info, + const ObITableReadInfo &index_read_info, const common::ObIArray &range_array, RangeSplitInfoArray &range_info_array, int64_t &total_size); @@ -318,7 +318,7 @@ class ObPartitionMajorSSTableRangeSpliter public: ObPartitionMajorSSTableRangeSpliter(); virtual ~ObPartitionMajorSSTableRangeSpliter(); - int init(const ObTableReadInfo &index_read_info, blocksstable::ObSSTable *major_sstable, + int init(const ObITableReadInfo &index_read_info, blocksstable::ObSSTable *major_sstable, int64_t tablet_size, common::ObIAllocator &allocator); int split_ranges(common::ObIArray &ranges); private: @@ -328,7 +328,7 @@ private: common::ObIArray &ranges); private: blocksstable::ObSSTable *major_sstable_; - const storage::ObTableReadInfo *index_read_info_; + const storage::ObITableReadInfo *index_read_info_; int64_t tablet_size_; common::ObIAllocator *allocator_; bool is_inited_; @@ -383,7 +383,7 @@ protected: ObIAllocator &allocator_; ObSEArray rowkey_col_ids_; ObSEArray out_cols_project_; - ObTableReadInfo tbl_read_info_; + ObRowkeyReadInfo tbl_read_info_; ObTableAccessParam tbl_xs_param_; ObStoreCtx store_ctx_; ObTableAccessContext tbl_xs_ctx_; diff --git a/src/storage/ob_resource_map.h b/src/storage/ob_resource_map.h index 11286683c..ee582d432 100644 --- a/src/storage/ob_resource_map.h +++ b/src/storage/ob_resource_map.h @@ -162,8 +162,7 @@ public: virtual ~ObResourceMap(); int init(const int64_t bucket_num, const ObMemAttr &attr, const int64_t total_limit, const int64_t hold_limit, const int64_t page_size); - template > - int get(const Key &key, ObResourceHandle &handle, Callback callback = ObResourceDefaultCallback()); + int get(const Key &key, ObResourceHandle &handle); template > int set(const Key &key, Value &value, Callback callback = ObResourceDefaultCallback()); template > @@ -175,11 +174,9 @@ public: common::ObIAllocator &get_allocator() { return allocator_; } int inc_handle_ref(ObResourceValueStore *ptr); protected: - template > int get_without_lock( const Key &key, - ObResourceHandle &handle, - Callback callback = ObResourceDefaultCallback()); + ObResourceHandle &handle); void free_resource(ObResourceValueStore *ptr); protected: typedef ObResourceValueStore ValueStore; @@ -240,8 +237,7 @@ int ObResourceMap::init( } template -template -int ObResourceMap::get(const Key &key, ObResourceHandle &handle, Callback callback) +int ObResourceMap::get(const Key &key, ObResourceHandle &handle) { int ret = OB_SUCCESS; uint64_t hash_val = 0; @@ -250,18 +246,16 @@ int ObResourceMap::get(const Key &key, ObResourceHandle &hand } else { common::ObBucketHashRLockGuard guard(bucket_lock_, hash_val); handle.reset(); - ret = get_without_lock(key, handle, callback); + ret = get_without_lock(key, handle); } return ret; } template -template int ObResourceMap::get_without_lock( const Key &key, - ObResourceHandle &handle, - Callback callback) + ObResourceHandle &handle) { int ret = common::OB_SUCCESS; ValueStore *ptr = NULL; @@ -274,17 +268,10 @@ int ObResourceMap::get_without_lock( } else { ret = common::OB_ENTRY_NOT_EXIST; } + } else if (OB_FAIL(ptr->inc_ref_cnt())) { + STORAGE_LOG(WARN, "fail to increase ref count", K(ret)); } else { - common::hash::HashMapPair pair; - pair.first = key; - pair.second = ptr->get_value_ptr(); - if (OB_FAIL(callback(pair))) { - STORAGE_LOG(WARN, "fail to callback", K(ret)); - } else if (OB_FAIL(inc_handle_ref(ptr))) { - STORAGE_LOG(WARN, "fail to inc handle ref count", K(ret)); - } else { - handle.ptr_ = ptr; - } + handle.ptr_ = ptr; } return ret; } diff --git a/src/storage/ob_row_fuse.cpp b/src/storage/ob_row_fuse.cpp index 674a4db50..86f7f68a0 100644 --- a/src/storage/ob_row_fuse.cpp +++ b/src/storage/ob_row_fuse.cpp @@ -259,8 +259,9 @@ int ObRowFuse::fuse_row(const blocksstable::ObDatumRow &former, } } final_result = (0 == left_cnt); - result.count_ = former.count_; + result.count_ = MAX(result.count_, former.count_); nop_pos.count_ = left_cnt; + STORAGE_LOG(DEBUG, "fuse row", K(ret), K(former), K(result)); } } else { ret = common::OB_INVALID_ARGUMENT; diff --git a/src/storage/ob_sstable_struct.cpp b/src/storage/ob_sstable_struct.cpp index 15f8bcd18..4016ca1f4 100644 --- a/src/storage/ob_sstable_struct.cpp +++ b/src/storage/ob_sstable_struct.cpp @@ -13,6 +13,7 @@ #define USING_LOG_PREFIX STORAGE #include "ob_sstable_struct.h" +#include "compaction/ob_compaction_diagnose.h" #include "share/ob_force_print_log.h" using namespace oceanbase::common; @@ -109,8 +110,36 @@ void ObParalleMergeInfo::reset() } } +/* + * PartTableInfo func + * */ +void PartTableInfo::fill_info(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + if (is_major_merge_) { + compaction::ADD_COMPACTION_INFO_PARAM(buf, buf_len, + "table_cnt", table_cnt_, + "[MAJOR]snapshot_version", snapshot_version_); + if (table_cnt_ > 1) { + compaction::ADD_COMPACTION_INFO_PARAM(buf, buf_len, + "[MINI]start_scn", start_scn_, + "end_scn", end_scn_); + } + } else { + if (table_cnt_ > 0) { + compaction::ADD_COMPACTION_INFO_PARAM(buf, buf_len, + "table_cnt", table_cnt_, + "start_scn", start_scn_, + "end_scn", end_scn_); + } + } +} + +/* + * ObSSTableMergeInfo func + * */ ObSSTableMergeInfo::ObSSTableMergeInfo() - : tenant_id_(0), + : compaction::ObIDiagnoseInfo(), ls_id_(), tablet_id_(), compaction_scn_(0), @@ -134,9 +163,13 @@ ObSSTableMergeInfo::ObSSTableMergeInfo() progressive_merge_num_(0), concurrent_cnt_(0), macro_bloomfilter_count_(0), + dag_ret_(OB_SUCCESS), + task_id_(), + retry_cnt_(0), + add_time_(0), parallel_merge_info_(), filter_statistics_(), - participant_table_str_("\0"), + participant_table_info_(), macro_id_list_("\0"), comment_("\0") { @@ -205,9 +238,14 @@ void ObSSTableMergeInfo::reset() progressive_merge_num_ = 0; concurrent_cnt_ = 0; macro_bloomfilter_count_ = 0; + dag_ret_ = OB_SUCCESS; + task_id_.reset(); + retry_cnt_ = 0; + add_time_ = 0; + info_param_ = nullptr; // allow nullptr parallel_merge_info_.reset(); filter_statistics_.reset(); - MEMSET(participant_table_str_, '\0', sizeof(participant_table_str_)); + participant_table_info_.reset(); MEMSET(macro_id_list_, '\0', sizeof(macro_id_list_)); MEMSET(comment_, '\0', sizeof(comment_)); } @@ -224,3 +262,62 @@ void ObSSTableMergeInfo::dump_info(const char *msg) FLOG_INFO("dump merge info", K(msg), K(output_row_per_s), K(new_macro_KB_per_s), K(*this)); } +int ObSSTableMergeInfo::fill_comment(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + if (0 != add_time_) { + compaction::ADD_COMPACTION_INFO_PARAM(buf, buf_len, + "add_timestamp", add_time_); + } + if (0 != dag_ret_) { + compaction::ADD_COMPACTION_INFO_PARAM(buf, buf_len, + "dag warning info: latest_error_code", dag_ret_, + "latest_error_trace", task_id_, + "retry_cnt", retry_cnt_); + } + compaction::ADD_COMPACTION_INFO_PARAM(buf, buf_len, + "extra_info", comment_); + return ret; +} + +void ObSSTableMergeInfo::shallow_copy(ObIDiagnoseInfo *other) +{ + ObSSTableMergeInfo *info = nullptr; + if (OB_NOT_NULL(other) && OB_NOT_NULL(info = dynamic_cast(other))) { + tenant_id_ = info->tenant_id_; + ls_id_ = info->ls_id_; + tablet_id_ = info->tablet_id_; + compaction_scn_ = info->compaction_scn_; + merge_type_ = info->merge_type_; + merge_start_time_ = info->merge_start_time_; + merge_finish_time_ = info->merge_finish_time_; + dag_id_ = info->dag_id_; + occupy_size_ = info->occupy_size_; + new_flush_occupy_size_ = info->new_flush_occupy_size_; + original_size_ = info->original_size_; + compressed_size_ = info->compressed_size_; + macro_block_count_ = info->macro_block_count_; + multiplexed_macro_block_count_ = info->multiplexed_macro_block_count_; + new_micro_count_in_new_macro_ = info->new_micro_count_in_new_macro_; + multiplexed_micro_count_in_new_macro_ = info->multiplexed_micro_count_in_new_macro_; + total_row_count_ = info->total_row_count_; + incremental_row_count_ = info->incremental_row_count_; + new_flush_data_rate_ = info->new_flush_data_rate_; + is_full_merge_ = info->is_full_merge_; + progressive_merge_round_ = info->progressive_merge_round_; + progressive_merge_num_ = info->progressive_merge_num_; + concurrent_cnt_ = info->concurrent_cnt_; + macro_bloomfilter_count_ = info->macro_bloomfilter_count_; + dag_ret_ = info->dag_ret_; + task_id_ = info->task_id_; + retry_cnt_ = info->retry_cnt_; + add_time_ = info->add_time_; + parallel_merge_info_ = info->parallel_merge_info_; + filter_statistics_ = info->filter_statistics_; + participant_table_info_ = info->participant_table_info_; + MEMSET(macro_id_list_, '\0', sizeof(macro_id_list_)); + strncpy(macro_id_list_, info->macro_id_list_, strlen(info->macro_id_list_)); + MEMSET(comment_, '\0', sizeof(comment_)); + strncpy(comment_, info->comment_, strlen(info->comment_)); + } +} diff --git a/src/storage/ob_sstable_struct.h b/src/storage/ob_sstable_struct.h index f35797b31..c0918ae27 100644 --- a/src/storage/ob_sstable_struct.h +++ b/src/storage/ob_sstable_struct.h @@ -17,6 +17,8 @@ #include "ob_i_table.h" #include "compaction/ob_i_compaction_filter.h" #include "compaction/ob_compaction_util.h" +#include "share/scheduler/ob_dag_scheduler_config.h" +#include "storage/compaction/ob_compaction_diagnose.h" namespace oceanbase { @@ -107,7 +109,32 @@ public: BasicInfo info_[ARRAY_IDX_MAX]; }; -struct ObSSTableMergeInfo final +struct PartTableInfo { + PartTableInfo() + : is_major_merge_(false), + table_cnt_(0), + snapshot_version_(0), + start_scn_(0), + end_scn_(0) + {} + void reset() + { + is_major_merge_ = false; + table_cnt_ = 0; + snapshot_version_ = 0; + start_scn_ = 0; + end_scn_ = 0; + } + void fill_info(char *buf, const int64_t buf_len) const; + TO_STRING_KV(K_(is_major_merge), K_(table_cnt), K_(snapshot_version), K_(start_scn), K_(end_scn)); + bool is_major_merge_; + int32_t table_cnt_; + int64_t snapshot_version_; + int64_t start_scn_; + int64_t end_scn_; +}; + +struct ObSSTableMergeInfo final : public compaction::ObIDiagnoseInfo { public: ObSSTableMergeInfo(); @@ -124,10 +151,16 @@ public: K_(new_micro_count_in_new_macro), K_(multiplexed_micro_count_in_new_macro), K_(total_row_count), K_(incremental_row_count), K_(new_flush_data_rate), K_(is_full_merge), K_(progressive_merge_round), K_(progressive_merge_num), - K_(concurrent_cnt), K_(parallel_merge_info), K_(filter_statistics), K_(participant_table_str), + K_(concurrent_cnt), K_(dag_ret), K_(task_id), K_(retry_cnt), K_(add_time), + K_(parallel_merge_info), K_(filter_statistics), K_(participant_table_info), K_(macro_id_list), K_(comment)); + + int fill_comment(char *buf, const int64_t buf_len) const; + + virtual void shallow_copy(ObIDiagnoseInfo *other) override; + static const int64_t MERGE_INFO_COMMENT_LENGTH = 96; + public: - uint64_t tenant_id_; share::ObLSID ls_id_; ObTabletID tablet_id_; int64_t compaction_scn_; // major_scn OR minor end_log_ts @@ -151,11 +184,18 @@ public: int64_t progressive_merge_num_; int64_t concurrent_cnt_; int64_t macro_bloomfilter_count_; + // from dag warn info + int64_t dag_ret_; + common::ObCurTraceId::TraceId task_id_; + int64_t retry_cnt_; + // from suspect info + int64_t add_time_; + // ObParalleMergeInfo parallel_merge_info_; compaction::ObICompactionFilter::ObFilterStatistics filter_statistics_; - char participant_table_str_[common::OB_PART_TABLE_INFO_LENGTH]; + PartTableInfo participant_table_info_; char macro_id_list_[common::OB_MACRO_ID_INFO_LENGTH]; - char comment_[common::OB_COMPACTION_EVENT_STR_LENGTH]; + char comment_[MERGE_INFO_COMMENT_LENGTH]; }; } // end namespace storage diff --git a/src/storage/ob_storage_rpc.cpp b/src/storage/ob_storage_rpc.cpp index 4b005079d..4823160ec 100644 --- a/src/storage/ob_storage_rpc.cpp +++ b/src/storage/ob_storage_rpc.cpp @@ -23,6 +23,9 @@ #include "logservice/ob_log_handler.h" #include "storage/restore/ob_ls_restore_handler.h" #include "observer/ob_server_event_history_table_operator.h" +#include "storage/high_availability/ob_transfer_service.h" +#include "storage/tablet/ob_tablet_iterator.h" +#include "storage/tablet/ob_tablet.h" #include "storage/high_availability/ob_storage_ha_utils.h" namespace oceanbase @@ -354,7 +357,7 @@ bool ObCopyTabletsSSTableInfoArg::is_valid() const return OB_INVALID_ID != tenant_id_ && ls_id_.is_valid() && ((need_check_seq_ && ls_rebuild_seq_ >= 0) || !need_check_seq_) - && tablet_sstable_info_arg_list_.count() > 0 + && tablet_sstable_info_arg_list_.count() >= 0 && version_ != OB_INVALID_ID; } @@ -462,7 +465,8 @@ OB_SERIALIZE_MEMBER(ObFetchLSMetaInfoArg, tenant_id_, ls_id_, version_); ObFetchLSMetaInfoResp::ObFetchLSMetaInfoResp() : ls_meta_package_(), - version_(OB_INVALID_ID) + version_(OB_INVALID_ID), + has_transfer_table_(false) { } @@ -470,6 +474,7 @@ void ObFetchLSMetaInfoResp::reset() { ls_meta_package_.reset(); version_ = OB_INVALID_ID; + has_transfer_table_ = false; } bool ObFetchLSMetaInfoResp::is_valid() const @@ -478,7 +483,7 @@ bool ObFetchLSMetaInfoResp::is_valid() const && version_ != OB_INVALID_ID; } -OB_SERIALIZE_MEMBER(ObFetchLSMetaInfoResp, ls_meta_package_, version_); +OB_SERIALIZE_MEMBER(ObFetchLSMetaInfoResp, ls_meta_package_, version_, has_transfer_table_); ObFetchLSMemberListArg::ObFetchLSMemberListArg() : tenant_id_(OB_INVALID_ID), @@ -736,6 +741,385 @@ bool ObRestoreUpdateLSMetaArg::is_valid() const OB_SERIALIZE_MEMBER(ObRestoreUpdateLSMetaArg, tenant_id_, ls_meta_package_); +ObCheckSrcTransferTabletsArg::ObCheckSrcTransferTabletsArg() + : tenant_id_(OB_INVALID_ID), + src_ls_id_(), + tablet_info_array_() +{ +} + +void ObCheckSrcTransferTabletsArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + src_ls_id_.reset(); + tablet_info_array_.reset(); +} + + +bool ObCheckSrcTransferTabletsArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ + && src_ls_id_.is_valid() + && !tablet_info_array_.empty(); +} + +OB_SERIALIZE_MEMBER(ObCheckSrcTransferTabletsArg, tenant_id_, src_ls_id_, tablet_info_array_); + + +ObGetLSActiveTransCountArg::ObGetLSActiveTransCountArg() + : tenant_id_(OB_INVALID_ID), + src_ls_id_() +{ +} + +void ObGetLSActiveTransCountArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + src_ls_id_.reset(); +} + +bool ObGetLSActiveTransCountArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ + && src_ls_id_.is_valid(); +} + +OB_SERIALIZE_MEMBER(ObGetLSActiveTransCountArg, tenant_id_, src_ls_id_); + +ObGetLSActiveTransCountRes::ObGetLSActiveTransCountRes() + : active_trans_count_(-1) +{ +} + +void ObGetLSActiveTransCountRes::reset() +{ + active_trans_count_ = -1; +} + +bool ObGetLSActiveTransCountRes::is_valid() const +{ + return active_trans_count_ >= 0; +} + +OB_SERIALIZE_MEMBER(ObGetLSActiveTransCountRes, active_trans_count_); + + +ObGetTransferStartScnArg::ObGetTransferStartScnArg() + : tenant_id_(OB_INVALID_ID), + src_ls_id_(), + tablet_list_() +{ +} + +void ObGetTransferStartScnArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + src_ls_id_.reset(); + tablet_list_.reset(); +} + +bool ObGetTransferStartScnArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ + && src_ls_id_.is_valid() + && !tablet_list_.empty(); +} + +OB_SERIALIZE_MEMBER(ObGetTransferStartScnArg, tenant_id_, src_ls_id_, tablet_list_); + +ObGetTransferStartScnRes::ObGetTransferStartScnRes() + : start_scn_() +{ +} + +void ObGetTransferStartScnRes::reset() +{ + start_scn_.reset(); +} + +bool ObGetTransferStartScnRes::is_valid() const +{ + return start_scn_.is_valid(); +} + +OB_SERIALIZE_MEMBER(ObGetTransferStartScnRes, start_scn_); + + +ObTransferTabletInfoArg::ObTransferTabletInfoArg() + : tenant_id_(OB_INVALID_ID), + src_ls_id_(), + dest_ls_id_(), + tablet_list_() +{ +} + +void ObTransferTabletInfoArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + src_ls_id_.reset(); + dest_ls_id_.reset(); + tablet_list_.reset(); +} + +bool ObTransferTabletInfoArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ + && src_ls_id_.is_valid() + && dest_ls_id_.is_valid() + && !tablet_list_.empty(); +} + +OB_SERIALIZE_MEMBER(ObTransferTabletInfoArg, tenant_id_, src_ls_id_, dest_ls_id_, tablet_list_); + +ObFetchLSReplayScnArg::ObFetchLSReplayScnArg() + : tenant_id_(OB_INVALID_ID), + ls_id_() +{ +} +void ObFetchLSReplayScnArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + ls_id_.reset(); +} +bool ObFetchLSReplayScnArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ + && ls_id_.is_valid(); +} +OB_SERIALIZE_MEMBER(ObFetchLSReplayScnArg, tenant_id_, ls_id_); +ObFetchLSReplayScnRes::ObFetchLSReplayScnRes() + : replay_scn_() +{ +} +void ObFetchLSReplayScnRes::reset() +{ + replay_scn_.reset(); +} +bool ObFetchLSReplayScnRes::is_valid() const +{ + return replay_scn_.is_valid(); +} +OB_SERIALIZE_MEMBER(ObFetchLSReplayScnRes, replay_scn_); +ObCheckTransferTabletBackfillArg::ObCheckTransferTabletBackfillArg() + : tenant_id_(OB_INVALID_ID), + ls_id_(), + tablet_list_() +{ +} +bool ObCheckTransferTabletBackfillArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ + && ls_id_.is_valid() + && !tablet_list_.empty(); +} +void ObCheckTransferTabletBackfillArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + ls_id_.reset(); + tablet_list_.reset(); +} +OB_SERIALIZE_MEMBER(ObCheckTransferTabletBackfillArg, tenant_id_, ls_id_, tablet_list_); +ObCheckTransferTabletBackfillRes::ObCheckTransferTabletBackfillRes() + : backfill_finished_(false) +{ +} +void ObCheckTransferTabletBackfillRes::reset() +{ + backfill_finished_ = false; +} +OB_SERIALIZE_MEMBER(ObCheckTransferTabletBackfillRes, backfill_finished_); + +ObStorageReplaceMemberArg::ObStorageReplaceMemberArg() + : tenant_id_(OB_INVALID_ID), + ls_id_(), + added_member_(), + removed_member_(), + ls_transfer_scn_() +{ +} + +bool ObStorageReplaceMemberArg::is_valid() const +{ + return OB_INVALID_ID == tenant_id_ + && ls_id_.is_valid() + && added_member_.is_valid() + && removed_member_.is_valid() + && ls_transfer_scn_.is_valid(); +} + +void ObStorageReplaceMemberArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + ls_id_.reset(); + added_member_.reset(); + removed_member_.reset(); + ls_transfer_scn_.reset(); +} + +OB_SERIALIZE_MEMBER(ObStorageReplaceMemberArg, tenant_id_, ls_id_, added_member_, removed_member_, ls_transfer_scn_); + +ObStorageAddMemberArg::ObStorageAddMemberArg() + : tenant_id_(OB_INVALID_ID), + ls_id_(), + member_(), + new_replica_num_(), + ls_transfer_scn_() +{ +} + +bool ObStorageAddMemberArg::is_valid() const +{ + return OB_INVALID_ID == tenant_id_ + && ls_id_.is_valid() + && member_.is_valid() + && new_replica_num_ > 0 + && ls_transfer_scn_.is_valid(); +} + +void ObStorageAddMemberArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + ls_id_.reset(); + member_.reset(); + new_replica_num_ = 0; + ls_transfer_scn_.reset(); +} + +OB_SERIALIZE_MEMBER(ObStorageAddMemberArg, tenant_id_, ls_id_, member_, new_replica_num_, ls_transfer_scn_); + +ObStorageSwitchLToFArg::ObStorageSwitchLToFArg() + : tenant_id_(OB_INVALID_ID), + ls_id_(), + learner_(), + new_replica_num_(), + ls_transfer_scn_() +{ +} + +bool ObStorageSwitchLToFArg::is_valid() const +{ + return OB_INVALID_ID == tenant_id_ + && ls_id_.is_valid() + && learner_.is_valid() + && new_replica_num_ > 0 + && ls_transfer_scn_.is_valid(); +} + +void ObStorageSwitchLToFArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + ls_id_.reset(); + learner_.reset(); + new_replica_num_ = 0; + ls_transfer_scn_.reset(); +} + +OB_SERIALIZE_MEMBER(ObStorageSwitchLToFArg, tenant_id_, ls_id_, learner_, new_replica_num_, ls_transfer_scn_); + +ObStorageChangeMemberRes::ObStorageChangeMemberRes() + : change_succ_(false) +{ +} + +void ObStorageChangeMemberRes::reset() +{ + change_succ_ = false; +} + +OB_SERIALIZE_MEMBER(ObStorageChangeMemberRes, change_succ_); + + +ObCopyLSViewArg::ObCopyLSViewArg() + : tenant_id_(OB_INVALID_ID), + ls_id_() +{ +} + +void ObCopyLSViewArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + ls_id_.reset(); +} + +bool ObCopyLSViewArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ + && ls_id_.is_valid(); +} + +OB_SERIALIZE_MEMBER(ObCopyLSViewArg, + tenant_id_, ls_id_); + +ObStorageBlockTxArg::ObStorageBlockTxArg() + : tenant_id_(OB_INVALID_ID), + ls_id_(), + gts_() +{ +} + +bool ObStorageBlockTxArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ + && ls_id_.is_valid() + && gts_.is_valid(); +} + +void ObStorageBlockTxArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + ls_id_.reset(); + gts_.reset(); +} + +OB_SERIALIZE_MEMBER(ObStorageBlockTxArg, tenant_id_, ls_id_, gts_); + +ObStorageKillTxArg::ObStorageKillTxArg() + : tenant_id_(OB_INVALID_ID), + ls_id_(), + gts_() +{ +} + +bool ObStorageKillTxArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ + && ls_id_.is_valid() + && gts_.is_valid(); +} + +void ObStorageKillTxArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + ls_id_.reset(); + gts_.reset(); +} + +OB_SERIALIZE_MEMBER(ObStorageKillTxArg, tenant_id_, ls_id_, gts_); + +ObStorageUnBlockTxArg::ObStorageUnBlockTxArg() + : tenant_id_(OB_INVALID_ID), + ls_id_(), + gts_() +{ +} + +bool ObStorageUnBlockTxArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ + && ls_id_.is_valid() + && gts_.is_valid(); +} + +void ObStorageUnBlockTxArg::reset() +{ + tenant_id_ = OB_INVALID_ID; + ls_id_.reset(); + gts_.reset(); +} + +OB_SERIALIZE_MEMBER(ObStorageUnBlockTxArg, tenant_id_, ls_id_, gts_); + + template ObStorageStreamRpcP::ObStorageStreamRpcP(common::ObInOutBandwidthThrottle *bandwidth_throttle) : bandwidth_throttle_(bandwidth_throttle), @@ -749,11 +1133,13 @@ template int ObStorageStreamRpcP::fill_data(const Data &data) { int ret = OB_SUCCESS; - + const int64_t curr_ts = ObTimeUtil::current_time(); if (NULL == (this->result_.get_data())) { STORAGE_LOG(WARN, "fail to alloc migration data buffer."); ret = OB_ALLOCATE_MEMORY_FAILED; - } else if (serialization::encoded_length(data) > this->result_.get_remain()) { + } else if (serialization::encoded_length(data) > this->result_.get_remain() + || (curr_ts - last_send_time_ >= FLUSH_TIME_INTERVAL + && this->result_.get_capacity() != this->result_.get_remain())) { LOG_INFO("flush", K(this->result_)); if (OB_FAIL(flush_and_wait())) { STORAGE_LOG(WARN, "failed to flush_and_wait", K(ret)); @@ -775,13 +1161,15 @@ template int ObStorageStreamRpcP::fill_buffer(blocksstable::ObBufferReader &data) { int ret = OB_SUCCESS; - + const int64_t curr_ts = ObTimeUtil::current_time(); if (NULL == (this->result_.get_data())) { STORAGE_LOG(WARN, "fail to alloc migration data buffer."); ret = OB_ALLOCATE_MEMORY_FAILED; } else { while (OB_SUCC(ret) && data.remain() > 0) { - if (0 == this->result_.get_remain()) { + if (0 == this->result_.get_remain() + || (curr_ts - last_send_time_ >= FLUSH_TIME_INTERVAL + && this->result_.get_capacity() != this->result_.get_remain())) { if (OB_FAIL(flush_and_wait())) { STORAGE_LOG(WARN, "failed to flush_and_wait", K(ret)); } @@ -808,6 +1196,7 @@ template int ObStorageStreamRpcP::fill_data_list(ObIArray &data_list) { int ret = OB_SUCCESS; + const int64_t curr_ts = ObTimeUtil::current_time(); if (NULL == (this->result_.get_data())) { STORAGE_LOG(WARN, "fail to alloc migration data buffer."); @@ -815,7 +1204,9 @@ int ObStorageStreamRpcP::fill_data_list(ObIArray &data_list) } else { for (int64_t i = 0; OB_SUCC(ret) && i < data_list.count(); ++i) { Data &data = data_list.at(i); - if (data.get_serialize_size() > this->result_.get_remain()) { + if (data.get_serialize_size() > this->result_.get_remain() + || (curr_ts - last_send_time_ >= FLUSH_TIME_INTERVAL + && this->result_.get_capacity() != this->result_.get_remain())) { if (OB_FAIL(flush_and_wait())) { STORAGE_LOG(WARN, "failed to flush_and_wait", K(ret)); } @@ -1113,7 +1504,6 @@ int ObFetchSSTableInfoP::process() ObLSHandle ls_handle; ObLSService *ls_service = nullptr; char * buf = NULL; - ObCopySSTableInfoObProducer producer; ObCopyTabletSSTableInfo sstable_info; ObMigrationStatus migration_status; ObLS *ls = nullptr; @@ -1340,10 +1730,50 @@ int ObFetchLSMetaInfoP::process() LOG_WARN("failed to get ls meta package", K(ret), K(arg_)); } else if (OB_FAIL(ObStorageHAUtils::get_server_version(result_.version_))) { LOG_WARN("failed to get server version", K(ret), K_(arg)); + } else if (OB_FAIL(check_has_transfer_logical_table_(ls))) { + LOG_WARN("failed to check has transfer logical table", K(ret), KP(ls)); } } return ret; +} +int ObFetchLSMetaInfoP::check_has_transfer_logical_table_(storage::ObLS *ls) +{ + int ret = OB_SUCCESS; + storage::ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); + if (OB_ISNULL(ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls not should be null", K(ret), KP(ls)); + } else if (OB_FAIL(ls->build_tablet_iter(tablet_iter))) { + LOG_WARN("failed to build ls tablet iter", K(ret)); + } else { + bool has_logical_table = true; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + while (OB_SUCC(ret)) { + tablet_handle.reset(); + tablet = nullptr; + if (OB_FAIL(tablet_iter.get_next_tablet(tablet_handle))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get tablet", K(ret), KPC(ls)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); + } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { + //do nothing + } else if (tablet->get_tablet_meta().has_transfer_table()) { + bool has_dependent_ls = false; + result_.has_transfer_table_ = true; + LOG_INFO("tablet still has logical table", K(tablet_handle)); + break; + } + } + } + return ret; } ObFetchLSMemberListP::ObFetchLSMemberListP() @@ -1362,9 +1792,20 @@ int ObFetchLSMemberListP::process() logservice::ObLogHandler *log_handler = NULL; common::ObMemberList member_list; int64_t paxos_replica_num = 0; + logservice::ObLogService *log_service = nullptr; + ObRole role; + int64_t proposal_id = 0; if (tenant_id != MTL_ID()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("rpc get member list tenant not match", K(ret), K(tenant_id)); + } else if (OB_ISNULL(log_service = MTL(logservice::ObLogService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log service should not be NULL", K(ret), KP(log_service)); + } else if (OB_FAIL(log_service->get_palf_role(ls_id, role, proposal_id))) { + LOG_WARN("failed to get role", K(ret), "arg", arg_); + } else if (!is_strong_leader(role)) { + ret = OB_PARTITION_NOT_LEADER; + LOG_WARN("ls is not leader, cannot get member list", K(ret), K(role), K(arg_)); } else if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls service should not be null", K(ret)); @@ -1507,6 +1948,173 @@ int ObFetchSSTableMacroInfoP::fetch_sstable_macro_range_info_(const obrpc::ObCop return ret; } +ObCheckStartTransferTabletsP::ObCheckStartTransferTabletsP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} + +int ObCheckStartTransferTabletsP::process() +{ + int ret = OB_SUCCESS; + MTL_SWITCH(arg_.tenant_id_) { + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + ObDeviceHealthStatus dhs = DEVICE_HEALTH_NORMAL; + int64_t disk_abnormal_time = 0; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + +#ifdef ERRSIM + if (OB_SUCC(ret) && DEVICE_HEALTH_NORMAL == dhs && GCONF.fake_disk_error) { + dhs = DEVICE_HEALTH_ERROR; + } +#endif + if (!arg_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("check src transfer tablets get invalid argument", K(ret), K(arg_)); + } else if (DEVICE_HEALTH_NORMAL == dhs + && OB_FAIL(ObIOManager::get_instance().get_device_health_status(dhs, disk_abnormal_time))) { + STORAGE_LOG(WARN, "failed to check is disk error", KR(ret)); + } else if (DEVICE_HEALTH_ERROR == dhs) { + ret = OB_DISK_ERROR; + STORAGE_LOG(ERROR, "observer has disk error, cannot restore", KR(ret), + "disk_health_status", device_health_status_to_str(dhs), K(disk_abnormal_time)); + } else if (OB_FAIL(check_start_transfer_out_tablets_())) { + LOG_WARN("failed to check start transfer out tablets", K(ret), K(arg_)); + } else if (OB_FAIL(check_start_transfer_in_tablets_())) { + LOG_WARN("failed to check start transfer in tablets", K(ret), K(arg_)); + } + } + return ret; +} + +int ObCheckStartTransferTabletsP::check_transfer_out_tablet_sstable_(const ObTablet *tablet) +{ + int ret = OB_SUCCESS; + ObTableStoreIterator ddl_iter; + ObTabletMemberWrapper wrapper; + if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet is null", K(ret)); + } else if (OB_FAIL(tablet->fetch_table_store(wrapper))) { + LOG_WARN("fetch table store fail", K(ret), KP(tablet)); + } else if (!wrapper.get_member()->get_major_sstables().empty()) { + // do nothing + } else if (OB_FAIL(tablet->get_ddl_sstables(ddl_iter))) { + LOG_WARN("failed to get ddl sstable", K(ret)); + } else if (ddl_iter.is_valid()) { + // do nothing + } else if (tablet->get_tablet_meta().ha_status_.is_restore_status_full()) { + ret = OB_INVALID_TABLE_STORE; + LOG_ERROR("neither major sstable nor ddl sstable exists", K(ret), K(ddl_iter)); + } + return ret; +} + +int ObCheckStartTransferTabletsP::check_start_transfer_out_tablets_() +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + + if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(arg_.src_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(arg_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src ls should not be NULL", K(ret), K(arg_), KP(ls)); + } else if (OB_FAIL(ls->get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), K(arg_)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("src ls migration status is not none", K(ret), K(migration_status), KPC(ls), K(arg_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < arg_.tablet_list_.count(); ++i) { + const ObTransferTabletInfo &tablet_info = arg_.tablet_list_.at(i); + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + bool committed_flag = false; + if (!tablet_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet info is invalid", K(ret), K(tablet_info), K(user_data), K(arg_)); + } else if (OB_FAIL(ls->get_tablet(tablet_info.tablet_id_, tablet_handle, 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_info)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_latest_tablet_status(user_data, committed_flag))) { + LOG_WARN("failed to get lastest tablet status", K(ret), KPC(tablet)); + } else if (!committed_flag) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("transfer src tablet still has uncommitted user data", K(ret), K(user_data), KPC(tablet)); + } else if (ObTabletStatus::NORMAL != user_data.tablet_status_) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("transfer src tablet status is not match", K(ret), KPC(tablet), K(tablet_info), K(user_data)); + } else if (tablet_info.transfer_seq_ != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet transfer seq is unexpected", K(ret), KPC(tablet), K(tablet_info), K(user_data)); + } else if (OB_FAIL(check_transfer_out_tablet_sstable_(tablet))) { + LOG_WARN("failed to check sstable", K(ret), KPC(tablet), K(user_data)); + } + } + } + return ret; +} + +int ObCheckStartTransferTabletsP::check_start_transfer_in_tablets_() +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + + if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(arg_.dest_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(arg_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src ls should not be NULL", K(ret), K(arg_), KP(ls)); + } else if (OB_FAIL(ls->get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), K(arg_)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("src ls migration status is not none", K(ret), K(migration_status), KPC(ls), K(arg_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < arg_.tablet_list_.count(); ++i) { + const ObTransferTabletInfo &tablet_info = arg_.tablet_list_.at(i); + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + if (OB_FAIL(ls->get_tablet(tablet_info.tablet_id_, tablet_handle, 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(tablet_info)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); + } else if (!tablet->is_empty_shell()) { + ret = OB_EAGAIN; + LOG_WARN("dest ls in start status should not exist transfer tablet, need retry", K(ret), KPC(tablet), K(tablet_info)); + } else if (tablet->get_tablet_meta().transfer_info_.transfer_seq_ > tablet_info.transfer_seq_ + 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is in empty shell but transfer seq not match", K(ret), KPC(tablet), K(tablet_info)); + } + } + } + return ret; +} ObNotifyRestoreTabletsP::ObNotifyRestoreTabletsP( common::ObInOutBandwidthThrottle *bandwidth_throttle) @@ -1585,7 +2193,6 @@ ObInquireRestoreP::ObInquireRestoreP( } - int ObInquireRestoreP::process() { int ret = OB_SUCCESS; @@ -1653,7 +2260,6 @@ ObUpdateLSMetaP::ObUpdateLSMetaP( } - int ObUpdateLSMetaP::process() { int ret = OB_SUCCESS; @@ -1815,6 +2421,635 @@ int ObLobQueryP::process() return ret; } +ObGetLSActiveTransCountP::ObGetLSActiveTransCountP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} + +int ObGetLSActiveTransCountP::process() +{ + int ret = OB_SUCCESS; + MTL_SWITCH(arg_.tenant_id_) { + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + bool is_follower = false; + ObDeviceHealthStatus dhs = DEVICE_HEALTH_NORMAL; + int64_t disk_abnormal_time = 0; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + +#ifdef ERRSIM + if (OB_SUCC(ret) && DEVICE_HEALTH_NORMAL == dhs && GCONF.fake_disk_error) { + dhs = DEVICE_HEALTH_ERROR; + } +#endif + if (!arg_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get ls active trans count get invalid argument", K(ret), K(arg_)); + } else if (DEVICE_HEALTH_NORMAL == dhs + && OB_FAIL(ObIOManager::get_instance().get_device_health_status(dhs, disk_abnormal_time))) { + STORAGE_LOG(WARN, "failed to check is disk error", KR(ret)); + } else if (DEVICE_HEALTH_ERROR == dhs) { + ret = OB_DISK_ERROR; + STORAGE_LOG(ERROR, "observer has disk error, cannot restore", KR(ret), + "disk_health_status", device_health_status_to_str(dhs), K(disk_abnormal_time)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(arg_.src_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(arg_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src ls should not be NULL", K(ret), K(arg_), KP(ls)); + } else if (OB_FAIL(ls->get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), K(arg_)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src ls migration status is not none", K(ret), K(migration_status), KPC(ls), K(arg_)); + } else if (OB_FAIL(ls->get_active_tx_count(result_.active_trans_count_))) { + LOG_WARN("failed to get active trans count", K(ret), KPC(ls), K(arg_)); + } + } + return ret; +} + +ObGetTransferStartScnP::ObGetTransferStartScnP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} + +int ObGetTransferStartScnP::process() +{ + int ret = OB_SUCCESS; + MTL_SWITCH(arg_.tenant_id_) { + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + bool is_follower = false; + ObDeviceHealthStatus dhs = DEVICE_HEALTH_NORMAL; + int64_t disk_abnormal_time = 0; + ObTabletHandle tablet_handle; + ObTabletCreateDeleteMdsUserData user_data; + +#ifdef ERRSIM + if (OB_SUCC(ret) && DEVICE_HEALTH_NORMAL == dhs && GCONF.fake_disk_error) { + dhs = DEVICE_HEALTH_ERROR; + } +#endif + if (!arg_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get ls active trans count get invalid argument", K(ret), K(arg_)); + } else if (DEVICE_HEALTH_NORMAL == dhs + && OB_FAIL(ObIOManager::get_instance().get_device_health_status(dhs, disk_abnormal_time))) { + STORAGE_LOG(WARN, "failed to check is disk error", KR(ret)); + } else if (DEVICE_HEALTH_ERROR == dhs) { + ret = OB_DISK_ERROR; + STORAGE_LOG(ERROR, "observer has disk error, cannot restore", KR(ret), + "disk_health_status", device_health_status_to_str(dhs), K(disk_abnormal_time)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(arg_.src_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(arg_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src ls should not be NULL", K(ret), K(arg_), KP(ls)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < arg_.tablet_list_.count(); ++i) { + const ObTransferTabletInfo &tablet_info = arg_.tablet_list_.at(i); + ObTablet *tablet = nullptr; + if (OB_FAIL(ls->get_tablet(tablet_info.tablet_id_, tablet_handle, 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(arg_)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); + } else if (tablet->get_tablet_meta().transfer_info_.transfer_seq_ != tablet_info.transfer_seq_) { + ret = OB_TABLET_TRANSFER_SEQ_NOT_MATCH; + LOG_WARN("transfer tablet seq is unexpected", K(ret), K(user_data), K(tablet_info), KPC(tablet)); + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, tablet_handle, user_data))) { + LOG_WARN("failed to get tablet status", K(ret), K(tablet_info)); + } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_) { + if (ObTabletStatus::NORMAL == user_data.tablet_status_) { + //tablet status is normal, set start_scn min which means get start scn need retry. + result_.start_scn_.set_min(); + LOG_INFO("tablet status is normal, get min start scn", K(result_), K(tablet_handle), K(user_data)); + break; + } + } else { + if (i > 0) { + if (user_data.transfer_scn_ != result_.start_scn_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tx data is not same", K(ret), K(tablet_handle), K(user_data), K(result_)); + } + } else if (user_data.transfer_scn_.is_min()) { + result_.start_scn_.set_min(); + LOG_INFO("tablet status is transfer out, but on_redo is not executed. Retry is required"); + break; + } else { + result_.start_scn_ = user_data.transfer_scn_; + LOG_INFO("succeed get start scn", K(result_), K(user_data)); + } + } + } + } + } + return ret; +} + +ObFetchTransferTabletsInfoP::ObFetchTransferTabletsInfoP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} + +int ObFetchTransferTabletsInfoP::process() +{ + int ret = OB_SUCCESS; + MTL_SWITCH(arg_.tenant_id_) { + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + char * buf = NULL; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + ObCopyTransferTabletInfoObProducer producer; + ObCopyTabletInfo tablet_info; + LOG_INFO("start to fetch transfer tablet info", K(arg_)); + + last_send_time_ = ObTimeUtility::current_time(); + + if (NULL == (buf = reinterpret_cast(allocator_.alloc(OB_MALLOC_BIG_BLOCK_SIZE)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "failed to alloc migrate data buffer.", K(ret)); + } else if (!result_.set_data(buf, OB_MALLOC_BIG_BLOCK_SIZE)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "failed set data to result", K(ret)); + } else if (OB_ISNULL(bandwidth_throttle_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "bandwidth_throttle_ must not null", K(ret), + KP_(bandwidth_throttle)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(arg_.src_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get log stream", KR(ret), K(arg_)); + } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", KR(ret), K(arg_), KP(ls)); + } else if (OB_FAIL(ls->get_migration_status(migration_status))) { + LOG_WARN("failed to log stream get migration status", K(ret), K(migration_status)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("migration status is unexpected", KR(ret), K(arg_), KPC(ls)); + } else if (OB_FAIL(producer.init(arg_.tenant_id_, arg_.src_ls_id_, arg_.dest_ls_id_, arg_.tablet_list_))) { + LOG_WARN("failed to init copy tablet info producer", K(ret), K(arg_)); + } else { + while (OB_SUCC(ret)) { + tablet_info.reset(); + if (OB_FAIL(producer.get_next_tablet_info(tablet_info))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + STORAGE_LOG(WARN, "failed to get next tablet meta info", K(ret)); + } + } else if (OB_FAIL(fill_data(tablet_info))) { + STORAGE_LOG(WARN, "fill to fill tablet info", K(ret), K(tablet_info)); + } + } + } + } + return ret; +} + +ObFetchLSReplayScnP::ObFetchLSReplayScnP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} +int ObFetchLSReplayScnP::process() +{ + int ret = OB_SUCCESS; + MTL_SWITCH(arg_.tenant_id_) { + ObLSHandle ls_handle; + ObLSService *ls_service = NULL; + ObLS *ls = NULL; + SCN max_decided_scn; + LOG_INFO("start to fetch ls replay scn", K(arg_)); + if (OB_ISNULL(bandwidth_throttle_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "bandwidth_throttle_ must not null", K(ret), + KP_(bandwidth_throttle)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(arg_.ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get log stream", KR(ret), K(arg_)); + } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", KR(ret), K(arg_), KP(ls)); + } else if (OB_FAIL(ls->get_max_decided_scn(max_decided_scn))) { + LOG_WARN("failed to log stream get migration status", K(ret), K_(arg)); + } else { + result_.replay_scn_ = max_decided_scn; + LOG_INFO("get ls replay scn", K(max_decided_scn), K(arg_)); + } + } + return ret; +} +ObCheckTransferTabletsBackfillP::ObCheckTransferTabletsBackfillP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} +int ObCheckTransferTabletsBackfillP::process() +{ + int ret = OB_SUCCESS; + MTL_SWITCH(arg_.tenant_id_) { + ObLSHandle ls_handle; + ObLSService *ls_service = NULL; + ObLS *ls = NULL; + ObTransferService *transfer_service = NULL; + LOG_INFO("check transfer tablet", K(arg_)); + if (OB_ISNULL(bandwidth_throttle_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "bandwidth_throttle_ must not null", K(ret), + KP_(bandwidth_throttle)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(arg_.ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get log stream", KR(ret), K(arg_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", KR(ret), K(arg_), KP(ls)); + } else if (OB_ISNULL(transfer_service = MTL(ObTransferService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer service should not be null", K(ret), K_(arg)); + } else { + bool backfill_finished = true; + for (int64_t i = 0; OB_SUCC(ret) && i < arg_.tablet_list_.count(); ++i) { + bool has_transfer_table = false; + const ObTransferTabletInfo &tablet_info = arg_.tablet_list_.at(i); + if (OB_FAIL(check_has_transfer_table_(tablet_info, ls, has_transfer_table))) { + LOG_WARN("failed to check has transfer table", K(ret), K(tablet_info)); + } else if (has_transfer_table) { + backfill_finished = false; + LOG_INFO("[TRANSFER]tablet still has transfer table, backfill not finished", K(tablet_info), K(arg_)); + break; + } + } + if (OB_SUCC(ret)) { + result_.backfill_finished_ = backfill_finished; + if (!backfill_finished) { + transfer_service->wakeup(); + } + LOG_INFO("[TRANSFER]check backfill tx finish", K(backfill_finished), K(arg_.tablet_list_), K(ls->get_ls_id())); + } + } + } + return ret; +} +int ObCheckTransferTabletsBackfillP::check_has_transfer_table_( + const ObTransferTabletInfo &tablet_info, storage::ObLS *ls, bool &has_transfer_table) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + has_transfer_table = false; + if (OB_ISNULL(ls) || !tablet_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls is null or tablet info is invalid", K(ret), K(tablet_info)); + } else if (OB_FAIL(ls->get_tablet(tablet_info.tablet_id_, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_info)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); + } else if (tablet_info.transfer_seq_ + 1 != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_TABLET_TRANSFER_SEQ_NOT_MATCH; + LOG_WARN("tablet transfer seq not match", K(ret), K(tablet_info), "transfer_seq", tablet->get_tablet_meta().transfer_info_.transfer_seq_); + } else if (tablet->get_tablet_meta().has_transfer_table()) { + has_transfer_table = true; + LOG_INFO("transfer table exist", K(tablet_info), K(tablet->get_tablet_meta())); + } + return ret; +} + +ObStorageReplaceMemberP::ObStorageReplaceMemberP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} + +int ObStorageReplaceMemberP::process() +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = arg_.tenant_id_; + const share::ObLSID &ls_id = arg_.ls_id_; + const share::SCN &transfer_scn = arg_.ls_transfer_scn_; + const common::ObMember &added_member = arg_.added_member_; + const common::ObMember &removed_member = arg_.removed_member_; + const int64_t change_member_timeout = GCONF.sys_bkgd_migration_change_member_list_timeout; + MTL_SWITCH(tenant_id) { + ObLSHandle ls_handle; + ObLSService *ls_service = NULL; + ObLS *ls = NULL; + if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get log stream", KR(ret), K(arg_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", KR(ret), K(arg_), KP(ls)); + } else if (OB_FAIL(ls->replace_member(added_member, removed_member, transfer_scn, change_member_timeout))) { + LOG_WARN("fail to add member", KR(ret), K(arg_)); + } else { + LOG_INFO("replace member success", K(arg_)); + } + } + return ret; +} + +ObStorageAddMemberP::ObStorageAddMemberP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} + +int ObStorageAddMemberP::process() +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = arg_.tenant_id_; + const share::ObLSID &ls_id = arg_.ls_id_; + const share::SCN transfer_scn = arg_.ls_transfer_scn_; + const common::ObMember &member = arg_.member_; + const int64_t paxos_replica_num = arg_.new_replica_num_; + const int64_t add_member_timeout = GCONF.sys_bkgd_migration_change_member_list_timeout; + MTL_SWITCH(tenant_id) { + ObLSHandle ls_handle; + ObLSService *ls_service = NULL; + ObLS *ls = NULL; + int64_t local_transfer_scn = 0; + if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get log stream", KR(ret), K(arg_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", KR(ret), K(arg_), KP(ls)); + } else if (OB_FAIL(ls->add_member(member, paxos_replica_num, transfer_scn, add_member_timeout))) { + LOG_WARN("fail to add member", KR(ret), K(arg_)); + } else { + LOG_INFO("add member success", K(arg_)); + } + } + + return ret; +} + +ObStorageSwitchLearnerToAcceptorP::ObStorageSwitchLearnerToAcceptorP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} + +int ObStorageSwitchLearnerToAcceptorP::process() +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = arg_.tenant_id_; + const share::ObLSID &ls_id = arg_.ls_id_; + const share::SCN transfer_scn = arg_.ls_transfer_scn_; + const common::ObMember &learner = arg_.learner_; + const int64_t paxos_replica_num = arg_.new_replica_num_; + const int64_t add_member_timeout = GCONF.sys_bkgd_migration_change_member_list_timeout; + MTL_SWITCH(tenant_id) { + ObLSHandle ls_handle; + ObLSService *ls_service = NULL; + ObLS *ls = NULL; + int64_t local_transfer_scn = 0; + if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get log stream", KR(ret), K(arg_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", KR(ret), K(arg_), KP(ls)); + } else if (OB_FAIL(ls->switch_learner_to_acceptor(learner, paxos_replica_num, transfer_scn, add_member_timeout))) { + LOG_WARN("fail to switch learner to acceptor", KR(ret), K(arg_)); + } else { + LOG_INFO("switch learner to acceptor success", K(arg_)); + } + } + return ret; +} + +ObStorageFetchLSViewP::ObStorageFetchLSViewP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} + +int ObStorageFetchLSViewP::process() +{ + int ret = OB_SUCCESS; + LOG_INFO("receive fetch ls view request", K_(arg)); + MTL_SWITCH(arg_.tenant_id_) { + ObLSHandle ls_handle; + ObLSService *ls_service = NULL; + ObLS *ls = NULL; + char * buf = NULL; + const int64_t MAX_TABLET_NUM = 100; + + int64_t filled_tablet_count = 0; + int64_t total_tablet_count = 0; + last_send_time_ = ObTimeUtility::current_time(); + + auto fill_ls_meta_f = [this](const ObLSMetaPackage &ls_meta)->int { + int ret = OB_SUCCESS; + if (OB_FAIL(fill_data(ls_meta))) { + LOG_WARN("failed to fill ls meta", K(ret), K(ls_meta)); + } + return ret; + }; + + auto fill_tablet_meta_f = [this, &filled_tablet_count, &total_tablet_count](const obrpc::ObCopyTabletInfo &tablet_info)->int { + int ret = OB_SUCCESS; + if (!tablet_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fill tablet meta info get invalid argument", K(ret), K(tablet_info)); + } else if (filled_tablet_count >= MAX_TABLET_NUM) { + if (this->result_.get_position() > 0 && OB_FAIL(flush_and_wait())) { + LOG_WARN("failed to flush and wait", K(ret), K(tablet_info)); + } else { + LOG_INFO("batch flush and wait", K(filled_tablet_count), K(total_tablet_count)); + filled_tablet_count = 0; + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(fill_data(tablet_info))) { + STORAGE_LOG(WARN, "fill to fill tablet info", K(ret), K(tablet_info)); + } else { + ++filled_tablet_count; + ++total_tablet_count; + } + return ret; + }; + const int64_t cost_time = 10 * 1000 * 1000; + common::ObTimeGuard timeguard("ObStorageFetchLSViewP", cost_time); + timeguard.click(); + if (NULL == (buf = reinterpret_cast(allocator_.alloc(OB_MALLOC_BIG_BLOCK_SIZE)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc migrate data buffer.", K(ret)); + } else if (!result_.set_data(buf, OB_MALLOC_BIG_BLOCK_SIZE)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed set data to result", K(ret)); + } else if (OB_ISNULL(bandwidth_throttle_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("bandwidth_throttle_ must not null", K(ret), KP_(bandwidth_throttle)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } + + timeguard.click(); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ls_service->get_ls(arg_.ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get log stream", K(ret), K_(arg)); + } + + timeguard.click(); + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream should not be NULL", KR(ret), K_(arg), KP(ls)); + } else if (OB_FAIL(ls->get_ls_meta_package_and_tablet_metas( + false/* no need check archive */, + fill_ls_meta_f, + fill_tablet_meta_f))) { + LOG_WARN("failed to get ls meta package and tablet metas", K(ret), K_(arg)); + } else { + LOG_INFO("succeed fetch ls view", K_(arg), K(total_tablet_count)); + } + timeguard.click(); + } + return ret; +} + +ObStorageBlockTxP::ObStorageBlockTxP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} +int ObStorageBlockTxP::process() +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = arg_.tenant_id_; + const share::ObLSID &src_ls_id = arg_.ls_id_; + const share::SCN >s = arg_.gts_; + MTL_SWITCH(tenant_id) { + ObLSHandle ls_handle; + ObLSService *ls_srv = NULL; + ObLS *ls = NULL; + logservice::ObLogService *log_service = nullptr; + ObRole role; + int64_t proposal_id = 0; + if (!arg_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K_(arg)); + } else if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls srv should not be NULL", K(ret), KP(ls_srv)); + } else if (OB_FAIL(ls_srv->get_ls(src_ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("ls_srv->get_ls() fail", K(ret), K(src_ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); + } else if (OB_FAIL(ls->ha_block_tx(gts))) { + LOG_WARN("failed to kill all tx", K(ret), KPC(ls)); + } else { + LOG_INFO("success to kill all tx", K(ret), K_(arg)); + } + } + return ret; +} + +ObStorageKillTxP::ObStorageKillTxP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} +int ObStorageKillTxP::process() +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = arg_.tenant_id_; + const share::ObLSID &src_ls_id = arg_.ls_id_; + const share::SCN >s = arg_.gts_; + MTL_SWITCH(tenant_id) { + ObLSHandle ls_handle; + ObLSService *ls_srv = NULL; + ObLS *ls = NULL; + logservice::ObLogService *log_service = nullptr; + ObRole role; + int64_t proposal_id = 0; + if (!arg_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K_(arg)); + } else if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls srv should not be NULL", K(ret), KP(ls_srv)); + } else if (OB_FAIL(ls_srv->get_ls(src_ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("ls_srv->get_ls() fail", K(ret), K(src_ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); + } else if (OB_FAIL(ls->ha_kill_tx(gts))) { + LOG_WARN("failed to kill all tx", K(ret), KPC(ls)); + } else { + LOG_INFO("success to kill all tx", K(ret), K_(arg)); + } + } + return ret; +} + +ObStorageUnBlockTxP::ObStorageUnBlockTxP( + common::ObInOutBandwidthThrottle *bandwidth_throttle) + : ObStorageStreamRpcP(bandwidth_throttle) +{ +} +int ObStorageUnBlockTxP::process() +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = arg_.tenant_id_; + const share::ObLSID &src_ls_id = arg_.ls_id_; + const share::SCN >s = arg_.gts_; + MTL_SWITCH(tenant_id) { + ObLSHandle ls_handle; + ObLSService *ls_srv = NULL; + ObLS *ls = NULL; + logservice::ObLogService *log_service = nullptr; + ObRole role; + int64_t proposal_id = 0; + if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls srv should not be NULL", K(ret), KP(ls_srv)); + } else if (OB_FAIL(ls_srv->get_ls(src_ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("ls_srv->get_ls() fail", K(ret), K(src_ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", KR(ret), K(ls_handle)); + } else if (OB_FAIL(ls->ha_unblock_tx(gts))) { + LOG_WARN("failed to unblock normal", K(ret), K_(arg)); + } + } + return ret; +} + } //namespace obrpc @@ -2056,6 +3291,328 @@ int ObStorageRpc::update_ls_meta( return ret; } +int ObStorageRpc::check_start_transfer_tablets( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const common::ObIArray &tablet_array) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !src_ls_id.is_valid() || !dest_ls_id.is_valid() || tablet_array.empty()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(src_ls_id), K(dest_ls_id), K(tablet_array)); + } else { + ObTransferTabletInfoArg arg; + arg.tenant_id_ = tenant_id; + arg.src_ls_id_ = src_ls_id; + arg.dest_ls_id_ = dest_ls_id; + if (OB_FAIL(arg.tablet_list_.assign(tablet_array))) { + LOG_WARN("failed to assign tablet list", K(ret), K(tablet_array)); + } else if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).dst_cluster_id(src_info.cluster_id_).check_start_transfer_tablets(arg))) { + LOG_WARN("failed to check src transfer tablets", K(ret), K(src_info), K(arg)); + } + } + return ret; +} + +int ObStorageRpc::get_ls_active_trans_count( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + int64_t &active_trans_count) +{ + int ret = OB_SUCCESS; + active_trans_count = -1; + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } else { + ObGetLSActiveTransCountRes res; + ObGetLSActiveTransCountArg arg; + arg.tenant_id_ = tenant_id; + arg.src_ls_id_ = ls_id; + if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).dst_cluster_id(src_info.cluster_id_).get_ls_active_trans_count(arg, res))) { + LOG_WARN("failed to get ls active trans count", K(ret), K(src_info), K(arg)); + } else { + active_trans_count = res.active_trans_count_; + } + } + return ret; +} + +int ObStorageRpc::get_transfer_start_scn( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObIArray &tablet_list, + SCN &transfer_start_scn) +{ + int ret = OB_SUCCESS; + transfer_start_scn.reset(); + const int64_t GET_TRANSFER_START_SCN_TIMEOUT = GCONF._transfer_start_rpc_timeout; //default 10ms + + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } else { + ObGetTransferStartScnRes res; + ObGetTransferStartScnArg arg; + arg.tenant_id_ = tenant_id; + arg.src_ls_id_ = ls_id; + if (OB_FAIL(arg.tablet_list_.assign(tablet_list))) { + LOG_WARN("failed to assign tablet list", K(ret), K(tablet_list)); + } else if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).dst_cluster_id(src_info.cluster_id_) + .timeout(GET_TRANSFER_START_SCN_TIMEOUT).get_transfer_start_scn(arg, res))) { + LOG_WARN("failed to get transfer start scn", K(ret), K(src_info), K(arg)); + } else { + transfer_start_scn = res.start_scn_; + } + } + return ret; +} + +int ObStorageRpc::fetch_ls_replay_scn( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + SCN &ls_replay_scn) +{ + int ret = OB_SUCCESS; + ls_replay_scn.reset(); + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } else { + ObFetchLSReplayScnArg arg; + ObFetchLSReplayScnRes res; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).dst_cluster_id(src_info.cluster_id_).fetch_ls_replay_scn(arg, res))) { + LOG_WARN("failed to fetch ls replay scn", K(ret), K(src_info), K(arg)); + } else { + ls_replay_scn = res.replay_scn_; + } + } + return ret; +} +int ObStorageRpc::check_tablets_logical_table_replaced( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &dest_ls_id, + const common::ObIArray& tablet_array, + bool &backfill_finished) +{ + int ret = OB_SUCCESS; + backfill_finished = false; + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(dest_ls_id)); + } else { + ObCheckTransferTabletBackfillArg arg; + ObCheckTransferTabletBackfillRes res; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = dest_ls_id; + if (OB_FAIL(arg.tablet_list_.assign(tablet_array))) { + LOG_WARN("failed to assign tablet array", K(ret), K(tablet_array)); + } else if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).dst_cluster_id(src_info.cluster_id_) + .check_transfer_tablet_backfill_completed(arg, res))) { + LOG_WARN("failed to check tablets backfill completed", K(ret), K(src_info), K(arg)); + } else { + backfill_finished = res.backfill_finished_; + } + } + return ret; +} + +int ObStorageRpc::replace_member( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObMember &added_member, + const common::ObMember &removed_member, + const share::SCN &ls_transfer_scn, + const int64_t timeout) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } else { + ObStorageReplaceMemberArg arg; + ObStorageChangeMemberRes res; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + arg.added_member_ = added_member; + arg.removed_member_ = removed_member; + arg.ls_transfer_scn_ = ls_transfer_scn; + if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).timeout(timeout) + .dst_cluster_id(src_info.cluster_id_).replace_member(arg, res))) { + LOG_WARN("failed to replace member", K(ret), K(src_info), K(arg)); + } else { + FLOG_INFO("replace member", K(tenant_id), K(src_info), K(ls_id), K(ls_transfer_scn)); + } + } + return ret; +} + +int ObStorageRpc::add_member( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObMember &added_member, + const int64_t new_replica_num, + const share::SCN &ls_transfer_scn, + const int64_t timeout) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } else { + ObStorageAddMemberArg arg; + ObStorageChangeMemberRes res; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + arg.member_ = added_member; + arg.new_replica_num_ = new_replica_num; + arg.ls_transfer_scn_ = ls_transfer_scn; + if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).timeout(timeout) + .dst_cluster_id(src_info.cluster_id_).add_member(arg, res))) { + LOG_WARN("failed to replace member", K(ret), K(src_info), K(arg)); + } + } + return ret; +} + +int ObStorageRpc::switch_learner_to_acceptor( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObMember &learner, + const int64_t new_replica_num, + const share::SCN &ls_transfer_scn, + const int64_t timeout) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } else { + ObStorageSwitchLToFArg arg; + ObStorageChangeMemberRes res; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + arg.learner_ = learner; + arg.new_replica_num_ = new_replica_num; + arg.ls_transfer_scn_ = ls_transfer_scn; + if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).timeout(timeout) + .dst_cluster_id(src_info.cluster_id_).switch_learner_to_acceptor(arg, res))) { + LOG_WARN("failed to replace member", K(ret), K(src_info), K(arg)); + } + } + return ret; +} + +int ObStorageRpc::block_tx( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const share::SCN >s) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } else { + ObStorageBlockTxArg arg; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + arg.gts_ = gts; + if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).dst_cluster_id(src_info.cluster_id_).block_tx(arg))) { + LOG_WARN("failed to block tx", K(ret), K(src_info), K(arg)); + } + } + return ret; +} + +int ObStorageRpc::kill_tx( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const share::SCN >s) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } else { + ObStorageKillTxArg arg; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + arg.gts_ = gts; + if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).dst_cluster_id(src_info.cluster_id_).kill_tx(arg))) { + LOG_WARN("failed to block tx", K(ret), K(src_info), K(arg)); + } + } + return ret; +} + +int ObStorageRpc::unblock_tx( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const share::SCN >s) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "storage rpc is not inited", K(ret)); + } else if (tenant_id == OB_INVALID_ID || !src_info.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(src_info), K(ls_id)); + } else { + ObStorageUnBlockTxArg arg; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + arg.gts_ = gts; + if (OB_FAIL(rpc_proxy_->to(src_info.src_addr_).dst_cluster_id(src_info.cluster_id_).unblock_tx(arg))) { + LOG_WARN("failed to unblock tx", K(ret), K(src_info), K(arg)); + } + } + return ret; +} + } // storage } // oceanbase diff --git a/src/storage/ob_storage_rpc.h b/src/storage/ob_storage_rpc.h old mode 100644 new mode 100755 index 60b0a1c91..5cda7bda2 --- a/src/storage/ob_storage_rpc.h +++ b/src/storage/ob_storage_rpc.h @@ -28,6 +28,7 @@ #include "storage/ls/ob_ls_meta_package.h" #include "tablet/ob_tablet_meta.h" #include "share/restore/ob_ls_restore_status.h" +#include "share/transfer/ob_transfer_info.h" #include "storage/lob/ob_lob_rpc_struct.h" #include "storage/blocksstable/ob_logic_macro_id.h" @@ -265,9 +266,10 @@ public: bool is_valid() const; void reset(); - TO_STRING_KV(K_(ls_meta_package), K_(version)); + TO_STRING_KV(K_(ls_meta_package), K_(has_transfer_table), K_(version)); storage::ObLSMetaPackage ls_meta_package_; uint64_t version_; + bool has_transfer_table_; }; struct ObFetchLSMemberListArg @@ -428,18 +430,302 @@ public: storage::ObLSMetaPackage ls_meta_package_; }; +//transfer +struct ObCheckSrcTransferTabletsArg final +{ + OB_UNIS_VERSION(1); +public: + ObCheckSrcTransferTabletsArg(); + ~ObCheckSrcTransferTabletsArg() {} + bool is_valid() const; + void reset(); + + TO_STRING_KV(K_(tenant_id), K_(src_ls_id), K_(tablet_info_array)); + uint64_t tenant_id_; + share::ObLSID src_ls_id_; + common::ObSArray tablet_info_array_; +private: + DISALLOW_COPY_AND_ASSIGN(ObCheckSrcTransferTabletsArg); +}; + +struct ObGetLSActiveTransCountArg final +{ + OB_UNIS_VERSION(1); +public: + ObGetLSActiveTransCountArg(); + ~ObGetLSActiveTransCountArg() {} + bool is_valid() const; + void reset(); + + TO_STRING_KV(K_(tenant_id), K_(src_ls_id)); + uint64_t tenant_id_; + share::ObLSID src_ls_id_; +}; + +struct ObGetLSActiveTransCountRes final +{ + OB_UNIS_VERSION(1); +public: + ObGetLSActiveTransCountRes(); + ~ObGetLSActiveTransCountRes() {} + bool is_valid() const; + void reset(); + + TO_STRING_KV(K_(active_trans_count)); + int64_t active_trans_count_; +}; + +struct ObGetTransferStartScnArg final +{ + OB_UNIS_VERSION(1); +public: + ObGetTransferStartScnArg(); + ~ObGetTransferStartScnArg() {} + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(tenant_id), K_(src_ls_id), K_(tablet_list)); + uint64_t tenant_id_; + share::ObLSID src_ls_id_; + common::ObSArray tablet_list_; +}; + +struct ObGetTransferStartScnRes final +{ + OB_UNIS_VERSION(1); +public: + ObGetTransferStartScnRes(); + ~ObGetTransferStartScnRes() {} + bool is_valid() const; + void reset(); + + TO_STRING_KV(K_(start_scn)); + share::SCN start_scn_; +}; + +struct ObTransferTabletInfoArg final +{ + OB_UNIS_VERSION(1); +public: + ObTransferTabletInfoArg(); + ~ObTransferTabletInfoArg() {} + bool is_valid() const; + void reset(); + + TO_STRING_KV(K_(tenant_id), K_(src_ls_id), K_(dest_ls_id), K_(tablet_list)); + uint64_t tenant_id_; + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + common::ObSArray tablet_list_; +private: + DISALLOW_COPY_AND_ASSIGN(ObTransferTabletInfoArg); +}; + +struct ObFetchLSReplayScnArg final +{ + OB_UNIS_VERSION(1); +public: + ObFetchLSReplayScnArg(); + ~ObFetchLSReplayScnArg() {} + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(tenant_id), K_(ls_id)); + uint64_t tenant_id_; + share::ObLSID ls_id_; +}; + +struct ObFetchLSReplayScnRes final +{ + OB_UNIS_VERSION(1); +public: + ObFetchLSReplayScnRes(); + ~ObFetchLSReplayScnRes() {} + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(replay_scn)); + share::SCN replay_scn_; +}; + +struct ObCheckTransferTabletBackfillArg final +{ + OB_UNIS_VERSION(1); +public: + ObCheckTransferTabletBackfillArg(); + ~ObCheckTransferTabletBackfillArg() {} + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(tablet_list)); + uint64_t tenant_id_; + share::ObLSID ls_id_; + common::ObSArray tablet_list_; +private: + DISALLOW_COPY_AND_ASSIGN(ObCheckTransferTabletBackfillArg); +}; + +struct ObCheckTransferTabletBackfillRes final +{ + OB_UNIS_VERSION(1); +public: + ObCheckTransferTabletBackfillRes(); + ~ObCheckTransferTabletBackfillRes() {} + void reset(); + TO_STRING_KV(K_(backfill_finished)); + bool backfill_finished_; +}; + +struct ObStorageReplaceMemberArg final +{ + OB_UNIS_VERSION(1); +public: + ObStorageReplaceMemberArg(); + ~ObStorageReplaceMemberArg() {} + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(added_member), K_(removed_member), K_(ls_transfer_scn)); + uint64_t tenant_id_; + share::ObLSID ls_id_; + common::ObMember added_member_; + common::ObMember removed_member_; + share::SCN ls_transfer_scn_; +private: + DISALLOW_COPY_AND_ASSIGN(ObStorageReplaceMemberArg); +}; + +struct ObStorageAddMemberArg final +{ + OB_UNIS_VERSION(1); +public: + ObStorageAddMemberArg(); + ~ObStorageAddMemberArg() {} + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(member), K_(new_replica_num), K_(ls_transfer_scn)); + uint64_t tenant_id_; + share::ObLSID ls_id_; + common::ObMember member_; + int64_t new_replica_num_; + share::SCN ls_transfer_scn_; +private: + DISALLOW_COPY_AND_ASSIGN(ObStorageAddMemberArg); +}; + +struct ObStorageSwitchLToFArg final +{ + OB_UNIS_VERSION(1); +public: + ObStorageSwitchLToFArg(); + ~ObStorageSwitchLToFArg() {} + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(learner), K_(new_replica_num), K_(ls_transfer_scn)); + uint64_t tenant_id_; + share::ObLSID ls_id_; + common::ObMember learner_; + int64_t new_replica_num_; + share::SCN ls_transfer_scn_; +private: + DISALLOW_COPY_AND_ASSIGN(ObStorageSwitchLToFArg); +}; + +struct ObStorageChangeMemberRes final +{ + OB_UNIS_VERSION(1); +public: + ObStorageChangeMemberRes(); + ~ObStorageChangeMemberRes() {} + void reset(); + TO_STRING_KV(K_(change_succ)); + bool change_succ_; +private: + DISALLOW_COPY_AND_ASSIGN(ObStorageChangeMemberRes); +}; + +// Fetch ls meta and all tablet metas by stream reader. +struct ObCopyLSViewArg final +{ + OB_UNIS_VERSION(1); +public: + ObCopyLSViewArg(); + ~ObCopyLSViewArg() {} + bool is_valid() const; + void reset(); + + TO_STRING_KV(K_(tenant_id), K_(ls_id)); + uint64_t tenant_id_; + share::ObLSID ls_id_; +}; + +struct ObCheckStartTransferTabletsRes final +{ + OB_UNIS_VERSION(1); +public: + ObCheckStartTransferTabletsRes(); + ~ObCheckStartTransferTabletsRes() {} + void reset(); + TO_STRING_KV(K_(change_succ)); + bool change_succ_; +private: + DISALLOW_COPY_AND_ASSIGN(ObCheckStartTransferTabletsRes); +}; + +struct ObStorageBlockTxArg final +{ + OB_UNIS_VERSION(1); +public: + ObStorageBlockTxArg(); + ~ObStorageBlockTxArg() {} + bool is_valid() const; + void reset(); + + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(gts)); + uint64_t tenant_id_; + share::ObLSID ls_id_; + share::SCN gts_; +}; + +struct ObStorageKillTxArg final +{ + OB_UNIS_VERSION(1); +public: + ObStorageKillTxArg(); + ~ObStorageKillTxArg() {} + bool is_valid() const; + void reset(); + + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(gts)); + uint64_t tenant_id_; + share::ObLSID ls_id_; + share::SCN gts_; +}; + +struct ObStorageUnBlockTxArg final +{ + OB_UNIS_VERSION(1); +public: + ObStorageUnBlockTxArg(); + ~ObStorageUnBlockTxArg() {} + bool is_valid() const; + void reset(); + + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(gts)); + uint64_t tenant_id_; + share::ObLSID ls_id_; + share::SCN gts_; +}; + //src class ObStorageRpcProxy : public obrpc::ObRpcProxy { public: static const int64_t STREAM_RPC_TIMEOUT = 30 * 1000 * 1000LL; // 30s DEFINE_TO(ObStorageRpcProxy); + //stream RPC_SS(PR5 fetch_macro_block, OB_HA_FETCH_MACRO_BLOCK, (ObCopyMacroBlockRangeArg), common::ObDataBuffer); RPC_SS(PR5 fetch_tablet_info, OB_HA_FETCH_TABLET_INFO, (ObCopyTabletInfoArg), common::ObDataBuffer); RPC_SS(PR5 fetch_tablet_sstable_info, OB_HA_FETCH_SSTABLE_INFO, (ObCopyTabletsSSTableInfoArg), common::ObDataBuffer); RPC_SS(PR5 fetch_sstable_macro_info, OB_HA_FETCH_SSTABLE_MACRO_INFO, (ObCopySSTableMacroRangeInfoArg), common::ObDataBuffer); - // lob RPC_SS(PR5 lob_query, OB_LOB_QUERY, (ObLobQueryArg), common::ObDataBuffer); + RPC_SS(PR5 fetch_transfer_tablet_info, OB_FETCH_TRANSFER_TABLET_INFO, (ObTransferTabletInfoArg), common::ObDataBuffer); + RPC_SS(PR5 fetch_ls_view, OB_HA_FETCH_LS_VIEW, (ObCopyLSViewArg), common::ObDataBuffer); RPC_S(PR5 fetch_ls_member_list, OB_HA_FETCH_LS_MEMBER_LIST, (ObFetchLSMemberListArg), ObFetchLSMemberListInfo); RPC_S(PR5 fetch_ls_meta_info, OB_HA_FETCH_LS_META_INFO, (ObFetchLSMetaInfoArg), ObFetchLSMetaInfoResp); @@ -447,6 +733,17 @@ public: RPC_S(PR5 notify_restore_tablets, OB_HA_NOTIFY_RESTORE_TABLETS, (ObNotifyRestoreTabletsArg), ObNotifyRestoreTabletsResp); RPC_S(PR5 inquire_restore, OB_HA_NOTIFY_FOLLOWER_RESTORE, (ObInquireRestoreArg), ObInquireRestoreResp); RPC_S(PR5 update_ls_meta, OB_HA_UPDATE_LS_META, (ObRestoreUpdateLSMetaArg)); + RPC_S(PR5 check_start_transfer_tablets, OB_CHECK_START_TRANSFER_TABLETS, (ObTransferTabletInfoArg)); + RPC_S(PR5 get_ls_active_trans_count, OB_GET_LS_ACTIVE_TRANSACTION_COUNT, (ObGetLSActiveTransCountArg), ObGetLSActiveTransCountRes); + RPC_S(PR5 get_transfer_start_scn, OB_GET_TRANSFER_START_SCN, (ObGetTransferStartScnArg), ObGetTransferStartScnRes); + RPC_S(PR5 fetch_ls_replay_scn, OB_HA_FETCH_LS_REPLAY_SCN, (ObFetchLSReplayScnArg), ObFetchLSReplayScnRes); + RPC_S(PR5 check_transfer_tablet_backfill_completed, OB_HA_CHECK_TRANSFER_TABLET_BACKFILL, (ObCheckTransferTabletBackfillArg), ObCheckTransferTabletBackfillRes); + RPC_S(PR5 replace_member, OB_HA_REPLACE_MEMBER, (ObStorageReplaceMemberArg), ObStorageChangeMemberRes); + RPC_S(PR5 add_member, OB_HA_ADD_MEMBER, (ObStorageAddMemberArg), ObStorageChangeMemberRes); + RPC_S(PR5 switch_learner_to_acceptor, OB_HA_SWITCH_LEARNER_TO_ACCEPTOR, (ObStorageSwitchLToFArg), ObStorageChangeMemberRes); + RPC_S(PR5 block_tx, OB_HA_BLOCK_TX, (ObStorageBlockTxArg)); + RPC_S(PR5 kill_tx, OB_HA_KILL_TX, (ObStorageKillTxArg)); + RPC_S(PR5 unblock_tx, OB_HA_UNBLOCK_TX, (ObStorageUnBlockTxArg)); }; template @@ -471,6 +768,7 @@ protected: common::ObInOutBandwidthThrottle *bandwidth_throttle_; int64_t last_send_time_; common::ObArenaAllocator allocator_; + static const int64_t FLUSH_TIME_INTERVAL = ObStorageRpcProxy::STREAM_RPC_TIMEOUT / 2; }; class ObHAFetchMacroBlockP: public ObStorageStreamRpcP @@ -527,6 +825,8 @@ public: virtual ~ObFetchLSMetaInfoP() { } protected: int process(); +private: + int check_has_transfer_logical_table_(storage::ObLS *ls); }; class ObFetchLSMemberListP: @@ -583,6 +883,101 @@ protected: int process(); }; +class ObCheckStartTransferTabletsP : public ObStorageStreamRpcP +{ +public: + explicit ObCheckStartTransferTabletsP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObCheckStartTransferTabletsP() {} +protected: + int process(); +private: + int check_start_transfer_out_tablets_(); + int check_start_transfer_in_tablets_(); + // Major sstable or ddl sstable needs to exist in src_tablet + int check_transfer_out_tablet_sstable_(const ObTablet *tablet); +}; + +class ObGetLSActiveTransCountP : public ObStorageStreamRpcP +{ +public: + explicit ObGetLSActiveTransCountP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObGetLSActiveTransCountP() {} +protected: + int process(); +}; + +class ObGetTransferStartScnP : public ObStorageStreamRpcP +{ +public: + explicit ObGetTransferStartScnP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObGetTransferStartScnP() {} +protected: + int process(); +}; + +class ObFetchTransferTabletsInfoP : + public ObStorageStreamRpcP +{ +public: + explicit ObFetchTransferTabletsInfoP( + common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObFetchTransferTabletsInfoP() {} +protected: + int process(); +}; + +class ObFetchLSReplayScnP: + public ObStorageStreamRpcP +{ +public: + explicit ObFetchLSReplayScnP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObFetchLSReplayScnP() {} +protected: + int process(); +}; +class ObCheckTransferTabletsBackfillP: + public ObStorageStreamRpcP +{ +public: + explicit ObCheckTransferTabletsBackfillP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObCheckTransferTabletsBackfillP() {} +protected: + int process(); +private: + int check_has_transfer_table_(const share::ObTransferTabletInfo &tablet_info, + storage::ObLS *ls, bool &has_transfer_table); +}; + +class ObStorageReplaceMemberP: + public ObStorageStreamRpcP +{ +public: + explicit ObStorageReplaceMemberP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObStorageReplaceMemberP() {} +protected: + int process(); +}; + +class ObStorageAddMemberP: + public ObStorageStreamRpcP +{ +public: + explicit ObStorageAddMemberP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObStorageAddMemberP() {} +protected: + int process(); +}; + +class ObStorageSwitchLearnerToAcceptorP: + public ObStorageStreamRpcP +{ +public: + explicit ObStorageSwitchLearnerToAcceptorP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObStorageSwitchLearnerToAcceptorP() {} +protected: + int process(); +}; + class ObLobQueryP : public ObStorageStreamRpcP { public: @@ -595,6 +990,51 @@ private: int process_getlength(); }; + +// Stream get ls meta and all tablet meta +class ObStorageFetchLSViewP: + public ObStorageStreamRpcP +{ +public: + explicit ObStorageFetchLSViewP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObStorageFetchLSViewP() {} + +protected: + int process(); +}; + +class ObStorageBlockTxP: + public ObStorageStreamRpcP +{ +public: + explicit ObStorageBlockTxP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObStorageBlockTxP() {} +protected: + int process(); +private: + int check_before_kill_(storage::ObLS *ls, const share::ObLSID &ls_id, const int64_t timeout); +}; + +class ObStorageKillTxP: + public ObStorageStreamRpcP +{ +public: + explicit ObStorageKillTxP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObStorageKillTxP() {} +protected: + int process(); +}; + +class ObStorageUnBlockTxP: + public ObStorageStreamRpcP +{ +public: + explicit ObStorageUnBlockTxP(common::ObInOutBandwidthThrottle *bandwidth_throttle); + virtual ~ObStorageUnBlockTxP() {} +protected: + int process(); +}; + } // obrpc @@ -652,6 +1092,78 @@ public: const uint64_t tenant_id, const ObStorageHASrcInfo &dest_info, const storage::ObLSMetaPackage &ls_meta) = 0; + + virtual int check_start_transfer_tablets( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const common::ObIArray& tablet_array) = 0; + + virtual int get_ls_active_trans_count( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + int64_t &active_trans_count) = 0; + + virtual int get_transfer_start_scn( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObIArray &tablet_list, + share::SCN &transfer_start_scn) = 0; + + virtual int fetch_ls_replay_scn( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + share::SCN &ls_replay_scn) = 0; + virtual int check_tablets_logical_table_replaced( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &dest_ls_id, + const common::ObIArray &tablet_array, + bool &replace_finished) = 0; + + virtual int replace_member( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObMember &added_member, + const common::ObMember &removed_member, + const share::SCN &ls_transfer_scn, + const int64_t timeout) = 0; + virtual int add_member( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObMember &added_member, + const int64_t new_replica_num, + const share::SCN &ls_transfer_scn, + const int64_t timeout) = 0; + virtual int switch_learner_to_acceptor( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObMember &learner, + const int64_t paxos_replica_num, + const share::SCN &ls_transfer_scn, + const int64_t timeout) = 0; + virtual int block_tx( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const share::SCN >s) = 0; + virtual int kill_tx( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const share::SCN >s) = 0; + virtual int unblock_tx( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const share::SCN >s) = 0; }; class ObStorageRpc: public ObIStorageRpc @@ -703,6 +1215,78 @@ public: const uint64_t tenant_id, const ObStorageHASrcInfo &dest_info, const storage::ObLSMetaPackage &ls_meta); + + virtual int check_start_transfer_tablets( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const common::ObIArray& tablet_array); + + virtual int get_ls_active_trans_count( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + int64_t &active_trans_count); + + virtual int get_transfer_start_scn( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObIArray &tablet_list, + share::SCN &transfer_start_scn); + + virtual int fetch_ls_replay_scn( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + share::SCN &ls_replay_scn); + virtual int check_tablets_logical_table_replaced( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &dest_ls_id, + const common::ObIArray &tablet_array, + bool &replace_finished); + virtual int replace_member( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObMember &added_member, + const common::ObMember &removed_member, + const share::SCN &ls_transfer_scn, + const int64_t timeout); + virtual int add_member( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObMember &added_member, + const int64_t new_replica_num, + const share::SCN &ls_transfer_scn, + const int64_t timeout); + virtual int switch_learner_to_acceptor( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const common::ObMember &learner, + const int64_t new_replica_num, + const share::SCN &ls_transfer_scn, + const int64_t timeout); + virtual int block_tx( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const share::SCN >s); + virtual int kill_tx( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const share::SCN >s); + virtual int unblock_tx( + const uint64_t tenant_id, + const ObStorageHASrcInfo &src_info, + const share::ObLSID &ls_id, + const share::SCN >s); + private: bool is_inited_; obrpc::ObStorageRpcProxy *rpc_proxy_; diff --git a/src/storage/ob_storage_schema.cpp b/src/storage/ob_storage_schema.cpp index d86f237dc..06232afb0 100644 --- a/src/storage/ob_storage_schema.cpp +++ b/src/storage/ob_storage_schema.cpp @@ -151,6 +151,7 @@ ObStorageSchema::ObStorageSchema() encrypt_key_(), rowkey_array_(), column_array_(), + store_column_cnt_(0), is_inited_(false) { } @@ -164,14 +165,15 @@ int ObStorageSchema::init( common::ObIAllocator &allocator, const ObTableSchema &input_schema, const lib::Worker::CompatMode compat_mode, - const bool skip_column_info/* = false*/) + const bool skip_column_info/* = false*/, + const int64_t compat_version/* = STORAGE_SCHEMA_VERSION_V2*/) { int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; STORAGE_LOG(WARN, "init twice", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!input_schema.is_valid() || true == skip_column_info)) { + } else if (OB_UNLIKELY(!input_schema.is_valid())) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "invalid args", K(ret), K(input_schema), K(skip_column_info)); } else { @@ -179,7 +181,7 @@ int ObStorageSchema::init( rowkey_array_.set_allocator(&allocator); column_array_.set_allocator(&allocator); - storage_schema_version_ = STORAGE_SCHEMA_VERSION; + storage_schema_version_ = compat_version; copy_from(input_schema); compat_mode_ = static_cast(compat_mode); } @@ -187,9 +189,9 @@ int ObStorageSchema::init( if (OB_FAIL(ret)) { } else if (OB_FAIL(generate_str(input_schema))) { STORAGE_LOG(WARN, "failed to generate string", K(ret), K(input_schema)); - } else if (!skip_column_info && OB_FAIL(generate_column_array(input_schema))) { - STORAGE_LOG(WARN, "failed to generate column array", K(ret), K(input_schema)); } else if (FALSE_IT(column_info_simplified_ = skip_column_info)) { + } else if (OB_FAIL(generate_column_array(input_schema))) { + STORAGE_LOG(WARN, "failed to generate column array", K(ret), K(input_schema)); } else if (OB_UNLIKELY(!is_valid())) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "storage schema is invalid", K(ret)); @@ -214,7 +216,7 @@ int ObStorageSchema::init( if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; STORAGE_LOG(WARN, "init twice", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!old_schema.is_valid() || true == skip_column_info)) { + } else if (OB_UNLIKELY(!old_schema.is_valid())) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "invalid args", K(ret), K(old_schema), K(skip_column_info)); } else { @@ -222,10 +224,11 @@ int ObStorageSchema::init( rowkey_array_.set_allocator(&allocator); column_array_.set_allocator(&allocator); - storage_schema_version_ = STORAGE_SCHEMA_VERSION; + storage_schema_version_ = STORAGE_SCHEMA_VERSION_V2;; copy_from(old_schema); compat_mode_ = old_schema.compat_mode_; compressor_type_ = old_schema.compressor_type_; + store_column_cnt_ = old_schema.store_column_cnt_; column_info_simplified_ = (skip_column_info || old_schema.column_info_simplified_); } @@ -234,12 +237,12 @@ int ObStorageSchema::init( STORAGE_LOG(WARN, "failed to deep copy encryption", K(ret), K(old_schema)); } else if (OB_FAIL(deep_copy_str(old_schema.encrypt_key_, encrypt_key_))) { STORAGE_LOG(WARN, "failed to deep copy encryption key", K(ret), K(old_schema)); - } else if (column_info_simplified_) { - // do nothing } else if (OB_FAIL(rowkey_array_.reserve(old_schema.rowkey_array_.count()))) { STORAGE_LOG(WARN, "failed to reserve for rowkey array", K(ret), K(old_schema)); } else if (OB_FAIL(rowkey_array_.assign(old_schema.rowkey_array_))) { STORAGE_LOG(WARN, "failed to copy row key array", K(ret), K(old_schema)); + } else if (column_info_simplified_) { + // do nothing } else if (OB_FAIL(deep_copy_column_array(allocator, old_schema, old_schema.column_array_.count()))) { STORAGE_LOG(WARN, "failed to deep copy column array", K(ret), K(old_schema)); } @@ -312,6 +315,7 @@ void ObStorageSchema::reset() row_store_type_ = ObStoreFormat::get_default_row_store_type(); schema_version_ = OB_INVALID_VERSION; column_cnt_ = 0; + store_column_cnt_ = 0; tablet_size_ = OB_DEFAULT_TABLET_SIZE; pctfree_ = OB_DEFAULT_PCTFREE; block_size_ = 0; @@ -358,6 +362,18 @@ bool ObStorageSchema::is_valid() const return valid_ret; } +int ObStorageSchema::assign(common::ObIAllocator &allocator, const ObStorageSchema &other) +{ + int ret = OB_SUCCESS; + reset(); + + if (OB_FAIL(init(allocator, other))) { + STORAGE_LOG(WARN, "failed to init", K(ret), K(other)); + } + + return ret; +} + int ObStorageSchema::serialize(char *buf, const int64_t buf_len, int64_t &pos) const { int ret = OB_SUCCESS; @@ -370,7 +386,8 @@ int ObStorageSchema::serialize(char *buf, const int64_t buf_len, int64_t &pos) c || OB_UNLIKELY(pos < 0)) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "invalid args", K(ret), K(buf), K(buf_len), K(pos)); - } else if (STORAGE_SCHEMA_VERSION == storage_schema_version_) { + } else if (STORAGE_SCHEMA_VERSION == storage_schema_version_ + || STORAGE_SCHEMA_VERSION_V2 == storage_schema_version_) { LST_DO_CODE(OB_UNIS_ENCODE, storage_schema_version_, info_, @@ -389,15 +406,19 @@ int ObStorageSchema::serialize(char *buf, const int64_t buf_len, int64_t &pos) c compressor_type_, encryption_, encrypt_key_); - if (OB_FAIL(ret) || column_info_simplified_) { + if (OB_FAIL(ret)) { } else if (OB_FAIL(serialize_column_array(buf, buf_len, pos, rowkey_array_))){ STORAGE_LOG(WARN, "failed to serialize rowkey columns", K_(rowkey_array)); - } else if (OB_FAIL(serialize_column_array(buf, buf_len, pos, column_array_))){ + } else if (!column_info_simplified_ + && OB_FAIL(serialize_column_array(buf, buf_len, pos, column_array_))){ STORAGE_LOG(WARN, "failed to serialize columns", K_(column_array)); + } else if (STORAGE_SCHEMA_VERSION_V2 == storage_schema_version_ + && OB_FAIL(serialization::encode_i64(buf, buf_len, pos, store_column_cnt_))) { + STORAGE_LOG(WARN, "failed to serialize store_column_cnt", K(ret), K(store_column_cnt_)); } } else { ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "invalid storage schema version", K(ret), K_(version)); + STORAGE_LOG(WARN, "invalid storage schema version", K(ret), K_(storage_schema_version)); } return ret; @@ -428,7 +449,8 @@ int ObStorageSchema::deserialize( if (OB_FAIL(serialization::decode(buf, data_len, pos, storage_schema_version_))) { STORAGE_LOG(WARN, "failed to deserialize version", K(ret), K(data_len), K(pos)); - } else if (STORAGE_SCHEMA_VERSION == storage_schema_version_) { + } else if (STORAGE_SCHEMA_VERSION == storage_schema_version_ + || STORAGE_SCHEMA_VERSION_V2 == storage_schema_version_) { ObString tmp_encryption; ObString tmp_encrypt_key; LST_DO_CODE(OB_UNIS_DECODE, @@ -453,15 +475,19 @@ int ObStorageSchema::deserialize( STORAGE_LOG(WARN, "failed to deep copy string", K(ret), K(tmp_encryption)); } else if (OB_FAIL(deep_copy_str(tmp_encrypt_key, encrypt_key_))) { STORAGE_LOG(WARN, "failed to deep copy string", K(ret), K(tmp_encrypt_key)); - } else if (column_info_simplified_) { - // do noting } else if (OB_FAIL(deserialize_rowkey_column_array(buf, data_len, pos))){ STORAGE_LOG(WARN, "failed to deserialize rowkey columns", K(ret), K_(rowkey_array)); - } else if (OB_FAIL(deserialize_column_array(allocator, buf, data_len, pos))){ + } else if (!column_info_simplified_ && OB_FAIL(deserialize_column_array(allocator, buf, data_len, pos))){ STORAGE_LOG(WARN, "failed to deserialize columns", K(ret), K_(column_array)); + } else if (STORAGE_SCHEMA_VERSION == storage_schema_version_) { + store_column_cnt_ = get_store_column_count_by_column_array(); + // TODO(lixia.yq) delete column array or later? + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &store_column_cnt_))) { + STORAGE_LOG(WARN, "failed to deserialize store_column_cnt", K(ret), K_(store_column_cnt)); } if (OB_SUCC(ret)) { is_inited_ = true; + storage_schema_version_ = STORAGE_SCHEMA_VERSION_V2; } } else { ret = OB_ERR_UNEXPECTED; @@ -568,11 +594,14 @@ int64_t ObStorageSchema::get_serialize_size() const compressor_type_, encryption_, encrypt_key_); + len += get_column_array_serialize_length(rowkey_array_); //get columms size if (!column_info_simplified_) { - len += get_column_array_serialize_length(rowkey_array_); len += get_column_array_serialize_length(column_array_); } + if (STORAGE_SCHEMA_VERSION_V2 == storage_schema_version_) { + len += serialization::encoded_length_i64(store_column_cnt_); + } return len; } @@ -590,29 +619,30 @@ int ObStorageSchema::generate_str(const ObTableSchema &input_schema) int ObStorageSchema::generate_column_array(const ObTableSchema &input_schema) { int ret = OB_SUCCESS; - const bool skip_rowkey = true; // build column schema map common::hash::ObHashMap tmp_map; // column_id -> index if (OB_FAIL(tmp_map.create(input_schema.get_column_count(), "StorageSchema"))) { STORAGE_LOG(WARN, "failed to create map", K(ret)); - } else if (OB_FAIL(input_schema.check_column_array_sorted_by_column_id(skip_rowkey))) { + } else if (OB_FAIL(input_schema.check_column_array_sorted_by_column_id(true/*skip_rowkey*/))) { STORAGE_LOG(WARN, "invalid schema", K(ret), K(input_schema)); } ObTableSchema::const_column_iterator iter = input_schema.column_begin(); ObColumnSchemaV2 *col = NULL; ObStorageColumnSchema col_schema; - if (OB_FAIL(ret)) { - } else if (OB_FAIL(column_array_.reserve(input_schema.get_column_count()))) { + if (FAILEDx(column_array_.reserve(input_schema.get_column_count()))) { STORAGE_LOG(WARN, "Fail to reserve column array", K(ret)); } - int col_idx = 0; + int64_t col_idx = 0; + int64_t col_cnt_in_sstable = 0; blocksstable::ObStorageDatum datum; for ( ; OB_SUCC(ret) && iter != input_schema.column_end(); iter++) { if (OB_ISNULL(col = *iter)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "The column is NULL", K(col)); - } else { + } else if (FALSE_IT(col_cnt_in_sstable += col->is_column_stored_in_sstable())) { + // only record stored column count here + } else if (!column_info_simplified_) { col_schema.reset(); col_schema.is_rowkey_column_ = col->is_rowkey_column(); col_schema.is_column_stored_in_sstable_ = col->is_column_stored_in_sstable(); @@ -630,18 +660,20 @@ int ObStorageSchema::generate_column_array(const ObTableSchema &input_schema) } else if (OB_FAIL(column_array_.push_back(col_schema))) { STORAGE_LOG(WARN, "Fail to push into column array", K(ret), K(col_schema)); col_schema.destroy(*allocator_); - } else if (OB_FAIL(tmp_map.set_refactored(col->get_column_id(), col_idx))) { - STORAGE_LOG(WARN, "failed to set column map", K(ret), "col_id", col->get_column_id(), K(col_idx)); - } else { - col_idx++; } } - + if (FAILEDx(tmp_map.set_refactored(col->get_column_id(), col_idx))) { + STORAGE_LOG(WARN, "failed to set column map", K(ret), "col_id", col->get_column_id(), K(col_idx)); + } else { + col_idx++; + } + } // end of for + if (OB_SUCC(ret)) { + store_column_cnt_ = is_storage_index_table() ? input_schema.get_column_count() : col_cnt_in_sstable; } - + // add rowkey columns ObStorageRowkeyColumnSchema rowkey_schema; const common::ObRowkeyInfo &rowkey_info = input_schema.get_rowkey_info(); - // add rowkey columns const ObRowkeyColumn *rowkey_column = NULL; if (OB_FAIL(ret)) { } else if (OB_FAIL(rowkey_array_.reserve(rowkey_info.get_size()))) { @@ -671,58 +703,35 @@ int ObStorageSchema::generate_column_array(const ObTableSchema &input_schema) return ret; } -int ObStorageSchema::get_store_column_ids( - common::ObIArray &column_ids, - const bool full_col) const -{ - UNUSED(full_col); - int ret = OB_SUCCESS; - bool no_virtual = true; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - STORAGE_LOG(WARN, "not inited", K(ret), K_(is_inited)); - } else { - if (is_storage_index_table()) { - no_virtual = false; - } - if (OB_FAIL(get_column_ids(column_ids, no_virtual))) { - STORAGE_LOG(WARN, "fail to get column ids", K(ret)); - } - } - return ret; -} - int ObStorageSchema::get_column_ids_without_rowkey( common::ObIArray &column_ids, const bool no_virtual) const { int ret = OB_SUCCESS; ObColDesc col_desc; - for (int64_t i = 0; OB_SUCC(ret) && i < column_cnt_; i++) { - const ObStorageColumnSchema &column = column_array_[i]; - if (!(column.is_rowkey_column_ - || (no_virtual && !column.is_column_stored_in_sstable_))) { + if (column_info_simplified_) { + // fake column ids + for (int64_t i = rowkey_array_.count(); OB_SUCC(ret) && i < store_column_cnt_; i++) { col_desc.col_id_ = common::OB_APP_MIN_COLUMN_ID + i; - col_desc.col_type_ = column.meta_type_; //for non-rowkey, col_desc.col_order_ is not meaningful if (OB_FAIL(column_ids.push_back(col_desc))) { STORAGE_LOG(WARN, "Fail to add column id to column_ids", K(ret)); } } - } - return ret; -} - -int ObStorageSchema::get_column_ids(common::ObIArray &column_ids, bool no_virtual) const -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - STORAGE_LOG(WARN, "not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(get_rowkey_column_ids(column_ids))) { // add rowkey columns - STORAGE_LOG(WARN, "Fail to get rowkey column ids", K(ret)); - } else if (OB_FAIL(get_column_ids_without_rowkey(column_ids, no_virtual))) { //add other columns - STORAGE_LOG(WARN, "Fail to get column ids with out rowkey", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < column_cnt_; i++) { + const ObStorageColumnSchema &column = column_array_[i]; + if (!column.is_rowkey_column_ // column is not a rowkey column(rowkey column is already added in step1 get_rowkey_column_ids) + && (column.is_column_stored_in_sstable_ // current column is not virtual + || !no_virtual)) { // could have virtual column + col_desc.col_id_ = common::OB_APP_MIN_COLUMN_ID + i; + col_desc.col_type_ = column.meta_type_; + //for non-rowkey, col_desc.col_order_ is not meaningful + if (OB_FAIL(column_ids.push_back(col_desc))) { + STORAGE_LOG(WARN, "Fail to add column id to column_ids", K(ret)); + } + } + } // end of for } return ret; } @@ -748,28 +757,6 @@ int ObStorageSchema::get_rowkey_column_ids(common::ObIArray &column_i return ret; } -int ObStorageSchema::has_lob_column(bool &has_lob, const bool check_large /*= false*/) const -{ - int ret = OB_SUCCESS; - has_lob = false; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - STORAGE_LOG(WARN, "not inited", K(ret), K_(is_inited)); - } - for (int i = 0; OB_SUCC(ret) && !has_lob && i < column_array_.count(); ++i) { - if (ob_is_json_tc(column_array_[i].meta_type_.get_type())) { - has_lob = true; - } else if (check_large) { - if (ob_is_large_text(column_array_[i].meta_type_.get_type())) { - has_lob = true; - } - } else if (ob_is_text_tc(column_array_[i].meta_type_.get_type())) { - has_lob = true; - } - } - return ret; -} - int ObStorageSchema::get_encryption_id(int64_t &encrypt_id) const { int ret = OB_SUCCESS; @@ -806,11 +793,23 @@ int ObStorageSchema::get_store_column_count(int64_t &column_count, const bool fu { UNUSED(full_col); int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { + if (IS_NOT_INIT) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "not inited", K(ret), K_(is_inited)); } else if (is_storage_index_table()) { column_count = column_cnt_; + } else { + column_count = store_column_cnt_; + } + return ret; +} + +// will call in deserialize for compat to init store_column_cnt_ +int64_t ObStorageSchema::get_store_column_count_by_column_array() +{ + int64_t column_count = 0; + if (is_storage_index_table()) { + column_count = column_cnt_; } else { column_count = 0; for (int64_t i = 0; i < column_cnt_; ++i) { @@ -819,7 +818,7 @@ int ObStorageSchema::get_store_column_count(int64_t &column_count, const bool fu } } } - return ret; + return column_count; } int ObStorageSchema::init_column_meta_array( @@ -827,7 +826,13 @@ int ObStorageSchema::init_column_meta_array( { int ret = OB_SUCCESS; ObArray columns; - if (OB_FAIL(get_multi_version_column_descs(columns))) { + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "not inited", K(ret), K_(is_inited)); + } else if (column_info_simplified_) { + ret = OB_NOT_SUPPORTED; + STORAGE_LOG(WARN, "not support get multi version column desc array when column simplified", K(ret), KPC(this)); + } else if (OB_FAIL(get_multi_version_column_descs(columns))) { STORAGE_LOG(WARN, "fail to get store column ids", K(ret)); } else { // build column schema map @@ -920,19 +925,19 @@ const ObStorageColumnSchema *ObStorageSchema::get_column_schema(const int64_t co return found_col; } - int ObStorageSchema::get_multi_version_column_descs(common::ObIArray &column_descs) const { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { + if (IS_NOT_INIT) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(get_rowkey_column_ids(column_descs))) { // add rowkey columns + } else if (column_info_simplified_) { + ret = OB_NOT_SUPPORTED; + STORAGE_LOG(WARN, "not support get multi version column desc array when column simplified", K(ret), KPC(this)); + } else if (OB_FAIL(get_mulit_version_rowkey_column_ids(column_descs))) { // add rowkey columns STORAGE_LOG(WARN, "Fail to get rowkey column descs", K(ret)); - } else if (OB_FAIL(storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(column_descs))) { - STORAGE_LOG(WARN, "failed to add extra rowkey cols", K(ret)); } else if (OB_FAIL(get_column_ids_without_rowkey(column_descs, !is_storage_index_table()))) { //add other columns - STORAGE_LOG(WARN, "Fail to get column descs with out rowkey", K(ret)); + STORAGE_LOG(WARN, "Fail to get column descs without rowkey", K(ret)); } return ret; } diff --git a/src/storage/ob_storage_schema.h b/src/storage/ob_storage_schema.h index 7e7413e73..6ad75e171 100644 --- a/src/storage/ob_storage_schema.h +++ b/src/storage/ob_storage_schema.h @@ -103,7 +103,8 @@ public: common::ObIAllocator &allocator, const share::schema::ObTableSchema &input_schema, const lib::Worker::CompatMode compat_mode, - const bool skip_column_info = false); + const bool skip_column_info = false, + const int64_t compat_version = STORAGE_SCHEMA_VERSION_V2); int init( common::ObIAllocator &allocator, const ObStorageSchema &old_schema, @@ -132,6 +133,9 @@ public: int64_t &pos); int64_t get_serialize_size() const; + // for new mds + int assign(common::ObIAllocator &allocator, const ObStorageSchema &other); + //TODO @lixia use compact mode in storage schema to compaction inline bool is_oracle_mode() const { return compat_mode_ == static_cast(lib::Worker::CompatMode::ORACLE); } inline lib::Worker::CompatMode get_compat_mode() const { return static_cast(compat_mode_);} @@ -154,14 +158,11 @@ public: virtual inline bool is_global_index_table() const override { return share::schema::ObSimpleTableSchemaV2::is_global_index_table(index_type_); } virtual inline int64_t get_block_size() const override { return block_size_; } - virtual int get_store_column_ids(common::ObIArray &column_ids, const bool full_col = false) const override; virtual int get_store_column_count(int64_t &column_count, const bool full_col) const override; int get_stored_column_count_in_sstable(int64_t &column_count) const; - virtual int get_column_ids(common::ObIArray &column_ids, bool no_virtual) const override; virtual int get_multi_version_column_descs(common::ObIArray &column_descs) const override; virtual int get_rowkey_column_ids(common::ObIArray &column_ids) const override; - virtual int has_lob_column(bool &has_lob, const bool check_large = false) const override; virtual int get_encryption_id(int64_t &encrypt_id) const override; virtual const common::ObString &get_encryption_str() const override { return encryption_; } virtual bool need_encrypt() const override; @@ -174,10 +175,10 @@ public: virtual inline share::schema::ObTableType get_table_type() const override { return table_type_; } virtual inline share::schema::ObIndexType get_index_type() const override { return index_type_; } virtual inline share::schema::ObIndexStatus get_index_status() const override { return index_status_; } - const common::ObIArray &get_store_column_schemas() const { return column_array_; } virtual inline common::ObRowStoreType get_row_store_type() const override { return row_store_type_; } virtual inline const char *get_compress_func_name() const override { return all_compressor_name[compressor_type_]; } virtual inline common::ObCompressorType get_compressor_type() const override { return compressor_type_; } + virtual inline bool is_column_info_simplified() const override { return column_info_simplified_; } virtual int init_column_meta_array( common::ObIArray &meta_array) const override; @@ -185,12 +186,20 @@ public: blocksstable::ObDatumRow &default_row) const; const ObStorageColumnSchema *get_column_schema(const int64_t column_id) const; - INHERIT_TO_STRING_KV("ObIMultiSourceDataUnit", ObIMultiSourceDataUnit, KP(this), K_(version), + // Use this comparison function to determine which schema has been updated later + // true: input_schema is newer + // false: current schema is newer + bool compare_schema_newer(const ObStorageSchema &input_schema) const + { + return store_column_cnt_ < input_schema.store_column_cnt_; + } + + INHERIT_TO_STRING_KV("ObIMultiSourceDataUnit", ObIMultiSourceDataUnit, KP(this), K_(storage_schema_version), K_(version), K_(is_use_bloomfilter), K_(column_info_simplified), K_(compat_mode), K_(table_type), K_(index_type), K_(index_status), K_(row_store_type), K_(schema_version), - K_(column_cnt), K_(tablet_size), K_(pctfree), K_(block_size), K_(progressive_merge_round), + K_(column_cnt), K_(store_column_cnt), K_(tablet_size), K_(pctfree), K_(block_size), K_(progressive_merge_round), K_(master_key_id), K_(compressor_type), K_(encryption), K_(encrypt_key), - K_(rowkey_array), K_(column_array)); + "rowkey_cnt", rowkey_array_.count(), K_(rowkey_array), K_(column_array)); private: void copy_from(const share::schema::ObMergeSchema &input_schema); int deep_copy_str(const ObString &src, ObString &dest); @@ -202,6 +211,7 @@ private: common::ObIArray &column_ids, bool no_virtual) const; void reset_string(ObString &str); + int64_t get_store_column_count_by_column_array(); /* serialize related function */ template @@ -229,6 +239,7 @@ public: // thus we add a static variable STORAGE_SCHEMA_VERSION and a class member storage_schema_version_ here. // Compatibility code should be added if new variables occur in future static const int64_t STORAGE_SCHEMA_VERSION = 1; + static const int64_t STORAGE_SCHEMA_VERSION_V2 = 2; // add for store_column_cnt_ common::ObIAllocator *allocator_; int64_t storage_schema_version_; @@ -250,7 +261,7 @@ public: share::schema::ObIndexStatus index_status_; ObRowStoreType row_store_type_; int64_t schema_version_; - int64_t column_cnt_; + int64_t column_cnt_; // include virtual generated column int64_t tablet_size_; int64_t pctfree_; int64_t block_size_; //KB @@ -262,6 +273,7 @@ public: ObString encrypt_key_; // for encryption common::ObFixedArray rowkey_array_; // rowkey column common::ObFixedArray column_array_; // column schema + int64_t store_column_cnt_; // NOT include virtual generated column bool is_inited_; private: DISALLOW_COPY_AND_ASSIGN(ObStorageSchema); diff --git a/src/storage/ob_storage_schema_recorder.cpp b/src/storage/ob_storage_schema_recorder.cpp index adcfb183b..664791bdc 100644 --- a/src/storage/ob_storage_schema_recorder.cpp +++ b/src/storage/ob_storage_schema_recorder.cpp @@ -50,7 +50,7 @@ ObStorageSchemaRecorder::ObStorageSchemaRecorder() table_id_(0) { #if defined(__x86_64__) - STATIC_ASSERT(sizeof(ObStorageSchemaRecorder) <= 120, "size of schema recorder is oversize"); + STATIC_ASSERT(sizeof(ObStorageSchemaRecorder) <= 128, "size of schema recorder is oversize"); #endif } @@ -145,16 +145,17 @@ int ObStorageSchemaRecorder::inner_replay_clog( ObTabletHandle tmp_tablet_handle; if (OB_FAIL(replay_get_tablet_handle(ls_id_, tablet_id_, scn, tmp_tablet_handle))) { - LOG_WARN("failed to get tablet handle", K(ret), K_(tablet_id), K(scn)); + if (OB_OBSOLETE_CLOG_NEED_SKIP == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet handle", K(ret), K_(tablet_id), K(scn)); + } } else if (OB_FAIL(replay_storage_schema.deserialize(tmp_allocator, buf, size, pos))) { LOG_WARN("fail to deserialize table schema", K(ret), K_(tablet_id)); - } else if (FALSE_IT(replay_storage_schema.set_sync_finish(true))) { - } else if (OB_FAIL(tmp_tablet_handle.get_obj()->save_multi_source_data_unit(&replay_storage_schema, scn, - true/*for_replay*/, memtable::MemtableRefOp::NONE))) { - LOG_WARN("failed to save storage schema", K(ret), K_(tablet_id), K(replay_storage_schema)); } else { - LOG_INFO("success to replay schema clog", K(ret), K_(ls_id), K_(tablet_id), - K(replay_storage_schema.get_schema_version()), K(replay_storage_schema.compat_mode_)); + // just replay schema clog, do not save storage schema + // DDL is forbidden during upgrade + LOG_INFO("success to replay schema clog", K(ret), K(replay_storage_schema)); } replay_storage_schema.reset(); tmp_tablet_handle.reset(); @@ -168,6 +169,7 @@ int ObStorageSchemaRecorder::try_update_storage_schema( const int64_t timeout_ts) { int ret = OB_SUCCESS; + uint64_t compat_version = 0; if (IS_NOT_INIT) { ret = OB_NOT_INIT; @@ -178,6 +180,10 @@ int ObStorageSchemaRecorder::try_update_storage_schema( } else if (ignore_storage_schema_) { ret = OB_NOT_SUPPORTED; LOG_WARN("not supported to update storage schema", K(ret), K_(tablet_id)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), compat_version))) { + LOG_WARN("fail to get data version", K(ret)); + } else if (compat_version >= DATA_VERSION_4_2_0_0) { + // for compat, before all server upgrade to 4.2, need sync storage schema } else if (FALSE_IT(table_id_ = table_id)) { // clear in free_allocated_info } else if (OB_FAIL(try_update_for_leader(table_version, &allocator, timeout_ts))) { LOG_WARN("failed to update for leader", K(ret), K(table_version)); @@ -322,7 +328,7 @@ int ObStorageSchemaRecorder::get_schema( } } else { table_version = t_schema->get_schema_version(); - if (OB_FAIL(storage_schema_->init(*allocator_, *t_schema, compat_mode_))) { + if (OB_FAIL(storage_schema_->init(*allocator_, *t_schema, compat_mode_, false/*skip_column_info*/, ObStorageSchema::STORAGE_SCHEMA_VERSION))) { LOG_WARN("failed to init storage schema", K(ret), K(t_schema)); } } diff --git a/src/storage/ob_storage_struct.cpp b/src/storage/ob_storage_struct.cpp index 1b6dee099..96f3b55ed 100644 --- a/src/storage/ob_storage_struct.cpp +++ b/src/storage/ob_storage_struct.cpp @@ -235,7 +235,7 @@ ObUpdateTableStoreParam::ObUpdateTableStoreParam( const int64_t multi_version_start, const ObStorageSchema *storage_schema, const int64_t rebuild_seq) - : table_handle_(), + : sstable_(nullptr), snapshot_version_(snapshot_version), clog_checkpoint_scn_(), multi_version_start_(multi_version_start), @@ -248,15 +248,14 @@ ObUpdateTableStoreParam::ObUpdateTableStoreParam( allow_duplicate_sstable_(false), tx_data_(), binding_info_(), - auto_inc_seq_(), - medium_info_list_(nullptr), + autoinc_seq_(), merge_type_(MERGE_TYPE_MAX) { clog_checkpoint_scn_.set_min(); } ObUpdateTableStoreParam::ObUpdateTableStoreParam( - const ObTableHandleV2 &table_handle, + const blocksstable::ObSSTable *sstable, const int64_t snapshot_version, const int64_t multi_version_start, const ObStorageSchema *storage_schema, @@ -265,9 +264,8 @@ ObUpdateTableStoreParam::ObUpdateTableStoreParam( const SCN clog_checkpoint_scn, const bool need_check_sstable, const bool allow_duplicate_sstable, - const compaction::ObMediumCompactionInfoList *medium_info_list, const ObMergeType merge_type) - : table_handle_(table_handle), + : sstable_(sstable), snapshot_version_(snapshot_version), clog_checkpoint_scn_(), multi_version_start_(multi_version_start), @@ -280,22 +278,22 @@ ObUpdateTableStoreParam::ObUpdateTableStoreParam( allow_duplicate_sstable_(allow_duplicate_sstable), tx_data_(), binding_info_(), - auto_inc_seq_(), - medium_info_list_(medium_info_list), + autoinc_seq_(), merge_type_(merge_type) { clog_checkpoint_scn_ = clog_checkpoint_scn; } ObUpdateTableStoreParam::ObUpdateTableStoreParam( - const ObTableHandleV2 &table_handle, + const blocksstable::ObSSTable *sstable, const int64_t snapshot_version, const int64_t multi_version_start, const int64_t rebuild_seq, const ObStorageSchema *storage_schema, const bool update_with_major_flag, + const ObMergeType merge_type, const bool need_report) - : table_handle_(table_handle), + : sstable_(sstable), snapshot_version_(snapshot_version), clog_checkpoint_scn_(), multi_version_start_(multi_version_start), @@ -308,9 +306,8 @@ ObUpdateTableStoreParam::ObUpdateTableStoreParam( allow_duplicate_sstable_(false), tx_data_(), binding_info_(), - auto_inc_seq_(), - medium_info_list_(nullptr), - merge_type_(MERGE_TYPE_MAX) + autoinc_seq_(), + merge_type_(merge_type) { clog_checkpoint_scn_.set_min(); } @@ -330,9 +327,12 @@ ObBatchUpdateTableStoreParam::ObBatchUpdateTableStoreParam() : tables_handle_(), rebuild_seq_(OB_INVALID_VERSION), update_logical_minor_sstable_(false), + is_transfer_replace_(false), start_scn_(SCN::min_scn()), - tablet_meta_(nullptr) + tablet_meta_(nullptr), + update_ddl_sstable_(false) { + ha_status_.init_status(); } void ObBatchUpdateTableStoreParam::reset() @@ -340,15 +340,19 @@ void ObBatchUpdateTableStoreParam::reset() tables_handle_.reset(); rebuild_seq_ = OB_INVALID_VERSION; update_logical_minor_sstable_ = false; + is_transfer_replace_ = false; start_scn_.set_min(); tablet_meta_ = nullptr; + update_ddl_sstable_ = false; + ha_status_.init_status(); } bool ObBatchUpdateTableStoreParam::is_valid() const { return rebuild_seq_ > OB_INVALID_VERSION && (!update_logical_minor_sstable_ - || (update_logical_minor_sstable_ && start_scn_ > SCN::min_scn() && OB_ISNULL(tablet_meta_))); + || (update_logical_minor_sstable_ && start_scn_ > SCN::min_scn() && OB_ISNULL(tablet_meta_))) + && ha_status_.is_valid(); } int ObBatchUpdateTableStoreParam::assign( @@ -363,8 +367,11 @@ int ObBatchUpdateTableStoreParam::assign( } else { rebuild_seq_ = param.rebuild_seq_; update_logical_minor_sstable_ = param.update_logical_minor_sstable_; + is_transfer_replace_ = param.is_transfer_replace_; start_scn_ = param.start_scn_; tablet_meta_ = param.tablet_meta_; + update_ddl_sstable_ = param.update_ddl_sstable_; + ha_status_ = param.ha_status_; } return ret; } @@ -431,202 +438,6 @@ void ObPartitionReadableInfo::reset() force_ = false; } - -int ObMigrateStatusHelper::trans_replica_op(const ObReplicaOpType &op_type, ObMigrateStatus &migrate_status) -{ - int ret = OB_SUCCESS; - migrate_status = OB_MIGRATE_STATUS_MAX; - - if (!is_replica_op_valid(op_type)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(op_type)); - } else { - switch (op_type) { - case ADD_REPLICA_OP: { - migrate_status = OB_MIGRATE_STATUS_ADD; - break; - } - case FAST_MIGRATE_REPLICA_OP: - case MIGRATE_REPLICA_OP: { - migrate_status = OB_MIGRATE_STATUS_MIGRATE; - break; - } - case REBUILD_REPLICA_OP: { - migrate_status = OB_MIGRATE_STATUS_REBUILD; - break; - } - case CHANGE_REPLICA_OP: { - migrate_status = OB_MIGRATE_STATUS_CHANGE; - break; - } - case RESTORE_REPLICA_OP: { - migrate_status = OB_MIGRATE_STATUS_RESTORE; - break; - } - case COPY_GLOBAL_INDEX_OP: { - migrate_status = OB_MIGRATE_STATUS_COPY_GLOBAL_INDEX; - break; - } - case COPY_LOCAL_INDEX_OP: { - migrate_status = OB_MIGRATE_STATUS_COPY_LOCAL_INDEX; - break; - } - case RESTORE_FOLLOWER_REPLICA_OP: { - migrate_status = OB_MIGRATE_STATUS_RESTORE_FOLLOWER; - break; - } - case RESTORE_STANDBY_OP: { - migrate_status = OB_MIGRATE_STATUS_RESTORE_STANDBY; - break; - } - case LINK_SHARE_MAJOR_OP: { - migrate_status = OB_MIGRATE_STATUS_LINK_MAJOR; - break; - } - - default: { - ret = OB_INVALID_ARGUMENT; - LOG_ERROR("unknown op type", K(ret), K(op_type)); - } - } - } - - return ret; -} - -int ObMigrateStatusHelper::trans_fail_status(const ObMigrateStatus &cur_status, ObMigrateStatus &fail_status) -{ - int ret = OB_SUCCESS; - fail_status = OB_MIGRATE_STATUS_MAX; - - if (cur_status < OB_MIGRATE_STATUS_NONE || cur_status >= OB_MIGRATE_STATUS_MAX) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(cur_status)); - } else { - switch (cur_status) { - case OB_MIGRATE_STATUS_ADD: { - fail_status = OB_MIGRATE_STATUS_ADD_FAIL; - break; - } - case OB_MIGRATE_STATUS_MIGRATE: { - fail_status = OB_MIGRATE_STATUS_MIGRATE_FAIL; - break; - } - case OB_MIGRATE_STATUS_REBUILD: { - fail_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_CHANGE: { - fail_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_RESTORE: { - //allow observer self reentry - fail_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_COPY_GLOBAL_INDEX: { - fail_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_COPY_LOCAL_INDEX: { - fail_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_HOLD: { - fail_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_RESTORE_FOLLOWER : { - //allow observer self reentry - fail_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_RESTORE_STANDBY : { - //allow observer self reentry - fail_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_LINK_MAJOR : { - fail_status = OB_MIGRATE_STATUS_NONE; - break; - } - default: { - ret = OB_INVALID_ARGUMENT; - LOG_ERROR("invalid cur status for fail", K(ret), K(cur_status)); - } - } - } - return ret; -} - -int ObMigrateStatusHelper::trans_reboot_status(const ObMigrateStatus &cur_status, ObMigrateStatus &reboot_status) -{ - int ret = OB_SUCCESS; - reboot_status = OB_MIGRATE_STATUS_MAX; - - if (cur_status < OB_MIGRATE_STATUS_NONE || cur_status >= OB_MIGRATE_STATUS_MAX) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(cur_status)); - } else { - switch (cur_status) { - case OB_MIGRATE_STATUS_NONE: { - reboot_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_ADD: - case OB_MIGRATE_STATUS_ADD_FAIL: { - reboot_status = OB_MIGRATE_STATUS_ADD_FAIL; - break; - } - case OB_MIGRATE_STATUS_MIGRATE: - case OB_MIGRATE_STATUS_MIGRATE_FAIL: { - reboot_status = OB_MIGRATE_STATUS_MIGRATE_FAIL; - break; - } - case OB_MIGRATE_STATUS_REBUILD: { - reboot_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_CHANGE: { - reboot_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_RESTORE: - case OB_MIGRATE_STATUS_RESTORE_FOLLOWER: - case OB_MIGRATE_STATUS_RESTORE_STANDBY: { - reboot_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_RESTORE_FAIL: { - reboot_status = OB_MIGRATE_STATUS_RESTORE_FAIL; - break; - } - case OB_MIGRATE_STATUS_COPY_GLOBAL_INDEX: { - reboot_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_COPY_LOCAL_INDEX: { - reboot_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_HOLD: { - reboot_status = OB_MIGRATE_STATUS_NONE; - break; - } - case OB_MIGRATE_STATUS_LINK_MAJOR: { - reboot_status = OB_MIGRATE_STATUS_NONE; - break; - } - default: { - ret = OB_INVALID_ARGUMENT; - LOG_ERROR("invalid cur status for fail", K(ret), K(cur_status)); - } - } - } - return ret; -} - int ObCreateSSTableParamExtraInfo::assign(const ObCreateSSTableParamExtraInfo &other) { int ret = OB_SUCCESS; diff --git a/src/storage/ob_storage_struct.h b/src/storage/ob_storage_struct.h old mode 100644 new mode 100755 index 99702c2b7..2f6b0995d --- a/src/storage/ob_storage_struct.h +++ b/src/storage/ob_storage_struct.h @@ -24,17 +24,16 @@ #include "storage/ob_storage_schema.h" #include "storage/tablet/ob_tablet_table_store_flag.h" #include "storage/compaction/ob_compaction_util.h" +#include "storage/compaction/ob_medium_compaction_mgr.h" #include "share/scn.h" #include "storage/tablet/ob_tablet_multi_source_data.h" #include "storage/tablet/ob_tablet_binding_helper.h" +#include "storage/tablet/ob_tablet_binding_info.h" #include "storage/ddl/ob_ddl_struct.h" +#include "storage/high_availability/ob_tablet_ha_status.h" namespace oceanbase { -namespace compaction -{ -struct ObMediumCompactionInfoList; -} namespace transaction { @@ -44,7 +43,7 @@ class ObLSTxCtxMgr; namespace storage { class ObStorageSchema; -class ObMigrationTabletParam; +struct ObMigrationTabletParam; typedef common::ObSEArray GetRowkeyArray; typedef common::ObSEArray ScanRangeArray; @@ -134,18 +133,6 @@ inline bool need_migrate_trans_table(const ObReplicaOpType replica_op) || RESTORE_STANDBY_OP == replica_op; } -struct ObMigrateStatusHelper -{ -public: - static int trans_replica_op(const ObReplicaOpType &op_type, ObMigrateStatus &migrate_status); - static int trans_fail_status(const ObMigrateStatus &cur_status, ObMigrateStatus &fail_status); - static int trans_reboot_status(const ObMigrateStatus &cur_status, ObMigrateStatus &reboot_status); - static OB_INLINE bool check_can_election(const ObMigrateStatus &cur_status); - static OB_INLINE bool check_allow_gc(const ObMigrateStatus &cur_status); - static OB_INLINE bool check_can_migrate_out(const ObMigrateStatus &cur_status); -}; - - struct ObTabletReportStatus { ObTabletReportStatus() @@ -320,7 +307,7 @@ struct ObUpdateTableStoreParam const ObStorageSchema *storage_schema, const int64_t rebuild_seq); ObUpdateTableStoreParam( - const ObTableHandleV2 &table_handle, + const blocksstable::ObSSTable *sstable, const int64_t snapshot_version, const int64_t multi_version_start, const ObStorageSchema *storage_schema, @@ -329,25 +316,25 @@ struct ObUpdateTableStoreParam const share::SCN clog_checkpoint_scn = share::SCN::min_scn(), const bool need_check_sstable = false, const bool allow_duplicate_sstable = false, - const compaction::ObMediumCompactionInfoList *medium_info_list = nullptr, const ObMergeType merge_type = MERGE_TYPE_MAX); ObUpdateTableStoreParam( // for ddl merge task only - const ObTableHandleV2 &table_handle, + const blocksstable::ObSSTable *sstable, const int64_t snapshot_version, const int64_t multi_version_start, const int64_t rebuild_seq, const ObStorageSchema *storage_schema, const bool update_with_major_flag, - const bool need_report = false); + const ObMergeType merge_type, + const bool need_report); bool is_valid() const; - TO_STRING_KV(K_(table_handle), K_(snapshot_version), K_(clog_checkpoint_scn), K_(multi_version_start), + TO_STRING_KV(KP_(sstable), K_(snapshot_version), K_(clog_checkpoint_scn), K_(multi_version_start), K_(need_report), KPC_(storage_schema), K_(rebuild_seq), K_(update_with_major_flag), - K_(need_check_sstable), K_(ddl_info), K_(allow_duplicate_sstable), K_(tx_data), K_(binding_info), K_(auto_inc_seq), - KPC_(medium_info_list), "merge_type", merge_type_to_str(merge_type_)); + K_(need_check_sstable), K_(ddl_info), K_(allow_duplicate_sstable), + K_(tx_data), K_(binding_info), K_(autoinc_seq), "merge_type", merge_type_to_str(merge_type_)); - ObTableHandleV2 table_handle_; + const blocksstable::ObSSTable *sstable_; int64_t snapshot_version_; share::SCN clog_checkpoint_scn_; int64_t multi_version_start_; @@ -362,9 +349,7 @@ struct ObUpdateTableStoreParam // msd ObTabletTxMultiSourceDataUnit tx_data_; ObTabletBindingInfo binding_info_; - share::ObTabletAutoincSeq auto_inc_seq_; - - const compaction::ObMediumCompactionInfoList *medium_info_list_; + share::ObTabletAutoincSeq autoinc_seq_; ObMergeType merge_type_; // set merge_type only when update tablet in compaction }; @@ -377,14 +362,17 @@ struct ObBatchUpdateTableStoreParam final int assign(const ObBatchUpdateTableStoreParam ¶m); int get_max_clog_checkpoint_scn(share::SCN &clog_checkpoint_scn) const; - TO_STRING_KV(K_(tables_handle), K_(rebuild_seq), K_(update_logical_minor_sstable), K_(start_scn), - KP_(tablet_meta)); + TO_STRING_KV(K_(tables_handle), K_(rebuild_seq), K_(update_logical_minor_sstable), K_(is_transfer_replace), + K_(start_scn), KP_(tablet_meta), K_(update_ddl_sstable), K_(ha_status)); ObTablesHandleArray tables_handle_; int64_t rebuild_seq_; bool update_logical_minor_sstable_; + bool is_transfer_replace_; share::SCN start_scn_; const ObMigrationTabletParam *tablet_meta_; + bool update_ddl_sstable_; + ObTabletHAStatus ha_status_; DISALLOW_COPY_AND_ASSIGN(ObBatchUpdateTableStoreParam); }; @@ -413,50 +401,6 @@ struct ObPartitionReadableInfo K(max_readable_ts_)); }; -bool ObMigrateStatusHelper::check_can_election(const ObMigrateStatus &cur_status) -{ - bool can_election = true; - - if (OB_MIGRATE_STATUS_ADD == cur_status - || OB_MIGRATE_STATUS_ADD_FAIL == cur_status - || OB_MIGRATE_STATUS_MIGRATE == cur_status - || OB_MIGRATE_STATUS_MIGRATE_FAIL == cur_status) { - can_election = false; - } - - return can_election; -} - -bool ObMigrateStatusHelper::check_allow_gc(const ObMigrateStatus &cur_status) -{ - bool allow_gc = true; - - if (OB_MIGRATE_STATUS_ADD == cur_status - || OB_MIGRATE_STATUS_MIGRATE == cur_status - || OB_MIGRATE_STATUS_REBUILD == cur_status - || OB_MIGRATE_STATUS_CHANGE == cur_status - || OB_MIGRATE_STATUS_RESTORE == cur_status - || OB_MIGRATE_STATUS_COPY_GLOBAL_INDEX == cur_status - || OB_MIGRATE_STATUS_COPY_LOCAL_INDEX == cur_status - || OB_MIGRATE_STATUS_HOLD == cur_status - || OB_MIGRATE_STATUS_RESTORE_FOLLOWER == cur_status - || OB_MIGRATE_STATUS_RESTORE_STANDBY == cur_status) { - allow_gc = false; - } - - return allow_gc; -} - -bool ObMigrateStatusHelper::check_can_migrate_out(const ObMigrateStatus &cur_status) -{ - bool can_migrate_out = true; - if (OB_MIGRATE_STATUS_NONE != cur_status) { - can_migrate_out = false; - } - return can_migrate_out; -} - - struct ObCreateSSTableParamExtraInfo { public: diff --git a/src/storage/ob_storage_table_guard.cpp b/src/storage/ob_storage_table_guard.cpp index 9e5fa04ff..49a956047 100644 --- a/src/storage/ob_storage_table_guard.cpp +++ b/src/storage/ob_storage_table_guard.cpp @@ -130,7 +130,7 @@ int ObStorageTableGuard::refresh_and_protect_table(ObRelativeTable &relative_tab LOG_WARN("ls is null", K(ret), K(ls_id)); } - while (OB_SUCC(ret) && need_to_refresh_table(iter.table_iter_)) { + while (OB_SUCC(ret) && need_to_refresh_table(*iter.table_iter())) { if (OB_FAIL(store_ctx_.ls_->get_tablet_svr()->get_read_tables( tablet_id, store_ctx_.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), @@ -140,7 +140,7 @@ int ObStorageTableGuard::refresh_and_protect_table(ObRelativeTable &relative_tab "table id", relative_table.get_table_id()); } else { // no worry. iter will hold tablet reference and its life cycle is longer than guard - tablet_ = iter.tablet_handle_.get_obj(); + tablet_ = iter.get_tablet(); // TODO: check if seesion is killed if (store_ctx_.timeout_ > 0) { const int64_t query_left_time = store_ctx_.timeout_ - ObTimeUtility::current_time(); @@ -369,10 +369,29 @@ bool ObStorageTableGuard::need_to_refresh_table(ObTableStoreIterator &iter) bool bool_ret = false; bool for_replace_tablet_meta = false; int exit_flag = -1; - - ObITable *table = iter.get_boundary_table(true); + ObITable *table = iter.get_last_memtable(); + bool need_create_memtable = false; if (NULL == table || !table->is_memtable()) { - // TODO: get the newest schema_version from tablet + need_create_memtable = true; + } else { + memtable::ObIMemtable *memtable = static_cast(table); + ObLSID ls_id = memtable->get_ls_id(); + if (OB_UNLIKELY(!ls_id.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get memtable ls_id", K(ret), KPC(table)); + } else if (ls_id != store_ctx_.ls_->get_ls_id()) { + if (OB_UNLIKELY(!table->is_data_memtable())) { + ret =OB_ERR_UNEXPECTED; + ObLSID curr_ls_id = store_ctx_.ls_->get_ls_id(); + LOG_WARN("table is not data memtable, it does not allow ls_id to be different", K(ret), K(ls_id), K(curr_ls_id), KPC(table)); + } else { + // TODO (wenjinyu.wjy) Active memtable is not allowed while ls_id is different + need_create_memtable = true; + } + } + } + if (OB_FAIL(ret)) { + } else if (need_create_memtable) { const common::ObTabletID &tablet_id = tablet_->get_tablet_meta().tablet_id_; if (OB_FAIL(store_ctx_.ls_->get_tablet_svr()->create_memtable(tablet_id, 0/*schema version*/, for_replay_))) { LOG_WARN("fail to create a boundary memtable", K(ret), K(tablet_id)); @@ -419,7 +438,6 @@ bool ObStorageTableGuard::need_to_refresh_table(ObTableStoreIterator &iter) } } } - return bool_ret; } diff --git a/src/storage/ob_super_block_struct.cpp b/src/storage/ob_super_block_struct.cpp old mode 100644 new mode 100755 index 8aa6b3f08..a14f3ff86 --- a/src/storage/ob_super_block_struct.cpp +++ b/src/storage/ob_super_block_struct.cpp @@ -249,14 +249,13 @@ ObTenantSuperBlock::ObTenantSuperBlock() } ObTenantSuperBlock::ObTenantSuperBlock(const uint64_t tenant_id, const bool is_hidden) - : tenant_id_(tenant_id), is_hidden_(is_hidden) + : tenant_id_(tenant_id), is_hidden_(is_hidden), version_(TENANT_SUPER_BLOCK_VERSION) { replay_start_point_.file_id_ = 1; replay_start_point_.log_id_ = 1; // // Due to the design of slog, the log_id_'s initial value must be 1 replay_start_point_.offset_ = 0; tablet_meta_entry_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK; ls_meta_entry_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK; - ls_dup_table_entry_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK; } void ObTenantSuperBlock::reset() @@ -265,24 +264,114 @@ void ObTenantSuperBlock::reset() replay_start_point_.reset(); ls_meta_entry_.reset(); tablet_meta_entry_.reset(); - ls_dup_table_entry_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK; is_hidden_= false; + version_ = TENANT_SUPER_BLOCK_VERSION; } bool ObTenantSuperBlock::is_valid() const { - return OB_INVALID_TENANT_ID != tenant_id_ && replay_start_point_.is_valid() - && ls_meta_entry_.is_valid() && tablet_meta_entry_.is_valid() - && ls_dup_table_entry_.is_valid(); + bool is_valid = OB_INVALID_TENANT_ID != tenant_id_ + && replay_start_point_.is_valid() + && ls_meta_entry_.is_valid() + && tablet_meta_entry_.is_valid() + && version_ > MIN_SUPER_BLOCK_VERSION + && (is_old_version() || IS_EMPTY_BLOCK_LIST(tablet_meta_entry_)); + return is_valid; } -OB_SERIALIZE_MEMBER(ObTenantSuperBlock, - tenant_id_, - replay_start_point_, - ls_meta_entry_, - tablet_meta_entry_, - is_hidden_, - ls_dup_table_entry_); +int ObTenantSuperBlock::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + OB_UNIS_ENCODE(UNIS_VERSION); + if (OB_SUCC(ret)) { + int64_t size_nbytes = NS_::OB_SERIALIZE_SIZE_NEED_BYTES; + int64_t pos_bak = (pos += size_nbytes); + if (OB_SUCC(ret)) { + if (OB_FAIL(serialize_(buf, buf_len, pos))) { + LOG_WARN("fail to serialize", K(ret), KP(buf), K(buf_len), K(pos)); + } + } + int64_t serial_size = pos - pos_bak; + int64_t tmp_pos = 0; + int64_t expect_size = get_serialize_size_(); + assert(expect_size >= serial_size); + if (OB_SUCC(ret)) { + ret = common::serialization::encode_fixed_bytes_i64(buf + pos_bak - size_nbytes, size_nbytes, tmp_pos, serial_size); + } + } + return ret; +} + +int ObTenantSuperBlock::serialize_(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, + tenant_id_, + replay_start_point_, + ls_meta_entry_, + tablet_meta_entry_, + is_hidden_); + return ret; +} + +int ObTenantSuperBlock::deserialize(const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + int64_t len = 0; + OB_UNIS_DECODEx(version_); + OB_UNIS_DECODEx(len); + if (OB_SUCC(ret)) { + if (UNIS_VERSION < version_) { + ret = ::oceanbase::common::OB_NOT_SUPPORTED; + LOG_WARN("ObTenantSuperBlock object version mismatch", K(ret), K_(version)); + } else if (len < 0) { + ret = ::oceanbase::common::OB_ERR_UNEXPECTED; + LOG_WARN("can't decode object with negative length", K(ret), K(len)); + } else if (data_len < len + pos) { + ret = ::oceanbase::common::OB_DESERIALIZE_ERROR; + LOG_WARN("buf length not enough", K(ret), K(len), K(pos), K(data_len)); + } else { + int64_t pos_orig = pos; + pos = 0; + if (OB_FAIL(deserialize_(buf + pos_orig, len, pos))) { + LOG_WARN("fail to de-serialize", K(ret), "len", len, K(pos)); + } + pos = pos_orig + len; + } + } + return ret; +} + +int ObTenantSuperBlock::deserialize_(const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, + tenant_id_, + replay_start_point_, + ls_meta_entry_, + tablet_meta_entry_, + is_hidden_); + return ret; +} + +int64_t ObTenantSuperBlock::get_serialize_size(void) const +{ + int64_t len = get_serialize_size_(); + SERIALIZE_SIZE_HEADER(UNIS_VERSION); + return len; +} + +int64_t ObTenantSuperBlock::get_serialize_size_(void) const +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, + tenant_id_, + replay_start_point_, + ls_meta_entry_, + tablet_meta_entry_, + is_hidden_); + return len; +} } // end namespace storage } // end namespace oceanbase diff --git a/src/storage/ob_super_block_struct.h b/src/storage/ob_super_block_struct.h index 4d8407f5b..2b81a7855 100644 --- a/src/storage/ob_super_block_struct.h +++ b/src/storage/ob_super_block_struct.h @@ -106,30 +106,29 @@ public: struct ObTenantSuperBlock final { public: - static const uint64_t HIDDEN_FLAG_MASK = 0x01; - - static const int64_t TENANT_SUPER_BLOCK_VERSION = 1; + static const int64_t MIN_SUPER_BLOCK_VERSION = 0; + static const int64_t TENANT_SUPER_BLOCK_VERSION = 2; ObTenantSuperBlock(); ObTenantSuperBlock(const uint64_t tenant_id, const bool is_hidden = false); ~ObTenantSuperBlock() = default; void reset(); bool is_valid() const; + bool is_old_version() const { return version_ < TENANT_SUPER_BLOCK_VERSION; } TO_STRING_KV(K_(tenant_id), K_(replay_start_point), K_(ls_meta_entry), K_(tablet_meta_entry), - K_(ls_dup_table_entry), - K_(is_hidden)); + K_(is_hidden), + K_(version)); OB_UNIS_VERSION(TENANT_SUPER_BLOCK_VERSION); - public: uint64_t tenant_id_; common::ObLogCursor replay_start_point_; blocksstable::MacroBlockId ls_meta_entry_; blocksstable::MacroBlockId tablet_meta_entry_; - blocksstable::MacroBlockId ls_dup_table_entry_; bool is_hidden_; + int64_t version_; }; #define IS_EMPTY_BLOCK_LIST(entry_block) (entry_block == oceanbase::storage::ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK) diff --git a/src/storage/ob_sync_tablet_seq_clog.cpp b/src/storage/ob_sync_tablet_seq_clog.cpp index 970f9c13e..56210cc74 100644 --- a/src/storage/ob_sync_tablet_seq_clog.cpp +++ b/src/storage/ob_sync_tablet_seq_clog.cpp @@ -14,6 +14,7 @@ #include "lib/objectpool/ob_concurrency_objpool.h" #include "lib/utility/serialization.h" +#include "share/ob_tablet_autoincrement_param.h" #include "storage/ob_sync_tablet_seq_clog.h" #include "storage/memtable/ob_memtable.h" #include "storage/tablet/ob_tablet.h" @@ -92,100 +93,61 @@ int64_t ObSyncTabletSeqLog::get_serialize_size() const return size; } -int ObSyncTabletSeqLogCb::init(const ObLSID &ls_id, - const ObTabletID &tablet_id, - const uint64_t new_autoinc_seq) + +ObSyncTabletSeqMdsLogCb::ObSyncTabletSeqMdsLogCb() + : state_(ObDDLClogState::STATE_INIT), + the_other_release_this_(false), + ret_code_(OB_SUCCESS), + tablet_handle_(), + mds_ctx_(mds::MdsWriter(mds::WriterType::AUTO_INC_SEQ)) +{ +} + +int ObSyncTabletSeqMdsLogCb::init(const ObLSID &ls_id, const ObTabletID &tablet_id, const int64_t writer_id) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(is_inited_)) { - ret = OB_INIT_TWICE; - LOG_WARN("init twice", K(ret), K(is_inited_)); + ObLSHandle ls_handle; + ObLSService *ls_srv = MTL(ObLSService *); + if (OB_UNLIKELY(!ls_id.is_valid() || !tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ls id or tablet id", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(ls_srv->get_ls(ls_id, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("get ls handle failed", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is unexpected null", K(ret)); + } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id, + tablet_handle_, + 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ls_id), K(tablet_id)); } else { - ls_id_ = ls_id; - tablet_id_ = tablet_id; - new_autoinc_seq_ = new_autoinc_seq; - is_inited_ = true; + mds_ctx_.set_writer(mds::MdsWriter(mds::WriterType::AUTO_INC_SEQ, writer_id)); } return ret; } -int ObSyncTabletSeqLogCb::on_success() +int ObSyncTabletSeqMdsLogCb::on_success() { int ret = OB_SUCCESS; - ObLSHandle ls_handle; - ObTabletHandle tablet_handle; - ObTabletAutoincSeq autoinc_seq; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) { - LOG_WARN("get ls handle failed", K(ret), K(ls_id_)); - } else if (OB_ISNULL(ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is unexpected null", K(ret)); - } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id_, - tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_SUCCESS; - } else { - ob_abort(); - } - } else if (OB_FAIL(tablet_handle.get_obj()->get_latest_autoinc_seq(autoinc_seq))) { - LOG_WARN("fail to get latest autoinc seq", K(ret)); - } else if (OB_FAIL(autoinc_seq.set_autoinc_seq_value(new_autoinc_seq_))) { - LOG_WARN("failed to set autoinc seq value", K(ret), K(new_autoinc_seq_)); - } else if (OB_FAIL(tablet_handle.get_obj()->save_multi_source_data_unit(&autoinc_seq, - __get_scn(), - false/*for_replay*/, - memtable::MemtableRefOp::DEC_REF, - true/*is_callback*/))) { - LOG_WARN("failed to save autoinc seq", K(ret), K(autoinc_seq)); - } ret_code_ = ret; state_ = STATE_SUCCESS; + mds_ctx_.single_log_commit(__get_scn(), __get_scn()); try_release(); - return OB_SUCCESS; + return ret; } -int ObSyncTabletSeqLogCb::on_failure() +int ObSyncTabletSeqMdsLogCb::on_failure() { int ret = OB_SUCCESS; - ObLSHandle ls_handle; - ObTabletHandle tablet_handle; - ObTabletAutoincSeq autoinc_seq; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) { - LOG_WARN("get ls handle failed", K(ret), K(ls_id_)); - } else if (OB_ISNULL(ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is unexpected null", K(ret)); - } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id_, - tablet_handle, - ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_SUCCESS; - } else { - ob_abort(); - } - } else if (OB_FAIL(tablet_handle.get_obj()->get_latest_autoinc_seq(autoinc_seq))) { - LOG_WARN("fail to get latest autoinc seq", K(ret)); - } else if (OB_FAIL(tablet_handle.get_obj()->save_multi_source_data_unit(&autoinc_seq, - SCN::invalid_scn()/*scn*/, - false/*for_replay*/, - memtable::MemtableRefOp::DEC_REF, - true/*is_callback*/))) { - LOG_WARN("failed to save autoinc seq", K(ret), K(autoinc_seq)); - } ret_code_ = ret; state_ = STATE_FAILED; + mds_ctx_.single_log_abort(); try_release(); - return OB_SUCCESS; + return ret; } -void ObSyncTabletSeqLogCb::try_release() +void ObSyncTabletSeqMdsLogCb::try_release() { if (ATOMIC_BCAS(&the_other_release_this_, false, true)) { } else { diff --git a/src/storage/ob_sync_tablet_seq_clog.h b/src/storage/ob_sync_tablet_seq_clog.h index cb2ce59df..682c5191e 100644 --- a/src/storage/ob_sync_tablet_seq_clog.h +++ b/src/storage/ob_sync_tablet_seq_clog.h @@ -19,6 +19,8 @@ #include "share/ob_ls_id.h" #include "share/ob_tablet_autoincrement_param.h" #include "storage/ddl/ob_ddl_clog.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/meta_mem/ob_tablet_handle.h" namespace oceanbase { @@ -47,14 +49,13 @@ private: uint64_t autoinc_seq_; }; -class ObSyncTabletSeqLogCb : public logservice::AppendCb +class ObSyncTabletSeqMdsLogCb : public logservice::AppendCb { public: - ObSyncTabletSeqLogCb() - : is_inited_(false), state_(ObDDLClogState::STATE_INIT), the_other_release_this_(false), - ret_code_(OB_SUCCESS), ls_id_(), tablet_id_(), new_autoinc_seq_(0) {} - int init(const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const uint64_t new_autoinc_seq); - virtual ~ObSyncTabletSeqLogCb() = default; + ObSyncTabletSeqMdsLogCb(); + virtual ~ObSyncTabletSeqMdsLogCb() = default; + + int init(const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const int64_t writer_id); virtual int on_success() override; virtual int on_failure() override; void try_release(); @@ -62,14 +63,13 @@ public: inline bool is_failed() const { return state_ == ObDDLClogState::STATE_FAILED; } inline bool is_finished() const { return state_ != ObDDLClogState::STATE_INIT; } inline int get_ret_code() const { return ret_code_; } + mds::MdsCtx &get_mds_ctx() { return mds_ctx_; } private: - bool is_inited_; ObDDLClogState state_; bool the_other_release_this_; int ret_code_; - share::ObLSID ls_id_; - common::ObTabletID tablet_id_; - uint64_t new_autoinc_seq_; + ObTabletHandle tablet_handle_; + mds::MdsCtx mds_ctx_; }; } // namespace storage diff --git a/src/storage/ob_table_store_stat_mgr.h b/src/storage/ob_table_store_stat_mgr.h index a5ea3c94d..ad3b2930a 100644 --- a/src/storage/ob_table_store_stat_mgr.h +++ b/src/storage/ob_table_store_stat_mgr.h @@ -16,7 +16,7 @@ #include "lib/oblog/ob_log_module.h" #include "lib/utility/ob_print_utils.h" #include "lib/lock/ob_spin_rwlock.h" -#include "lib/allocator//page_arena.h" +#include "lib/allocator/page_arena.h" #include "lib/hash_func/murmur_hash.h" #include "lib/hash/ob_hashmap.h" #include "lib/task/ob_timer.h" diff --git a/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp b/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp new file mode 100644 index 000000000..2ded45924 --- /dev/null +++ b/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp @@ -0,0 +1,298 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "ob_tablet_autoinc_seq_rpc_handler.h" +#include "logservice/ob_log_service.h" +#include "rootserver/ob_root_service.h" +#include "share/location_cache/ob_location_service.h" +#include "share/ob_rpc_struct.h" +#include "share/ob_tablet_autoincrement_param.h" +#include "share/scn.h" +#include "storage/tx_storage/ob_ls_handle.h" + +using namespace oceanbase::share; + +namespace oceanbase +{ +namespace storage +{ + +// ObSyncTabletSeqReplayExecutor +ObSyncTabletSeqReplayExecutor::ObSyncTabletSeqReplayExecutor() + : ObTabletReplayExecutor(), seq_(0), scn_() +{ +} + +int ObSyncTabletSeqReplayExecutor::init( + const uint64_t autoinc_seq, + const SCN &replay_scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(autoinc_seq == 0) + || OB_UNLIKELY(!replay_scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(autoinc_seq), K(replay_scn), K(ret)); + } else { + seq_ = autoinc_seq; + scn_ = replay_scn; + is_inited_ = true; + } + + return ret; +} + +int ObSyncTabletSeqReplayExecutor::do_replay_(ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = handle.get_obj(); + if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(handle)); + } else { + // replay to mds table + ObArenaAllocator allocator; + ObTabletAutoincSeq curr_autoinc_seq; + uint64_t curr_autoinc_seq_value; + if (OB_FAIL(tablet->get_autoinc_seq(allocator, share::SCN::max_scn(), curr_autoinc_seq))) { + LOG_WARN("fail to get latest autoinc seq", K(ret), KPC(tablet)); + } else if (OB_FAIL(curr_autoinc_seq.get_autoinc_seq_value(curr_autoinc_seq_value))) { + LOG_WARN("failed to get autoinc seq value", K(ret), KPC(tablet), K(curr_autoinc_seq)); + } else if (seq_ > curr_autoinc_seq_value) { + if (OB_FAIL(curr_autoinc_seq.set_autoinc_seq_value(allocator, seq_))) { + LOG_WARN("failed to set autoinc seq value", K(ret), K(seq_), K(curr_autoinc_seq)); + } else { + mds::MdsWriter mds_writer(mds::WriterType::AUTO_INC_SEQ, static_cast(seq_)); + mds::MdsCtx mds_ctx(mds_writer); + if (OB_FAIL(replay_to_mds_table_(handle, curr_autoinc_seq, mds_ctx, scn_))) { + LOG_WARN("failed to save autoinc seq", K(ret), K(curr_autoinc_seq)); + } else { + mds_ctx.single_log_commit(scn_, scn_); + } + } + } + } + return ret; +} + + +// ObTabletAutoincSeqRpcHandler +ObTabletAutoincSeqRpcHandler::ObTabletAutoincSeqRpcHandler() + : is_inited_(false), bucket_lock_() +{ +} + +ObTabletAutoincSeqRpcHandler::~ObTabletAutoincSeqRpcHandler() +{ +} + +ObTabletAutoincSeqRpcHandler &ObTabletAutoincSeqRpcHandler::get_instance() +{ + static ObTabletAutoincSeqRpcHandler autoinc_rpc_handler; + return autoinc_rpc_handler; +} + +int ObTabletAutoincSeqRpcHandler::init() +{ + int ret = OB_SUCCESS; + if (OB_FAIL(bucket_lock_.init(BUCKET_LOCK_BUCKET_CNT))) { + LOG_WARN("fail to init bucket lock", K(ret)); + } else { + is_inited_ = true; + } + return ret; +} + +int ObTabletAutoincSeqRpcHandler::fetch_tablet_autoinc_seq_cache( + const ObFetchTabletSeqArg &arg, + ObFetchTabletSeqRes &res) +{ + int ret = OB_SUCCESS; + uint64_t tenant_id = arg.tenant_id_; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else { + MTL_SWITCH(tenant_id) { + ObLSHandle ls_handle; + share::ObLSID ls_id = arg.ls_id_; + ObRole role = common::INVALID_ROLE; + ObTabletHandle tablet_handle; + ObTabletAutoincInterval autoinc_interval; + const ObTabletID &tablet_id = arg.tablet_id_; + int64_t proposal_id = -1; + ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); + if (OB_FAIL(MTL(logservice::ObLogService*)->get_palf_role(ls_id, role, proposal_id))) { + LOG_WARN("get palf role failed", K(ret)); + } else if (!is_strong_leader(role)) { + ret = OB_NOT_MASTER; + LOG_WARN("follwer received FetchTabletsSeq rpc", K(ret), K(ls_id)); + } else if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { + LOG_WARN("get ls failed", K(ret), K(ls_id)); + } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to get tablet", KR(ret), K(arg)); + } else if (OB_FAIL(tablet_handle.get_obj()->fetch_tablet_autoinc_seq_cache( + arg.cache_size_, autoinc_interval))) { + LOG_WARN("failed to fetch tablet autoinc seq on tablet", K(ret), K(tablet_id)); + } else { + res.cache_interval_ = autoinc_interval; + } + } + } + return ret; +} + +int ObTabletAutoincSeqRpcHandler::batch_get_tablet_autoinc_seq( + const obrpc::ObBatchGetTabletAutoincSeqArg &arg, + obrpc::ObBatchGetTabletAutoincSeqRes &res) +{ + int ret = OB_SUCCESS; + uint64_t tenant_id = arg.tenant_id_; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(arg)); + } else { + MTL_SWITCH(tenant_id) { + ObLSHandle ls_handle; + share::ObLSID ls_id = arg.ls_id_; + ObRole role = common::INVALID_ROLE; + int64_t proposal_id = -1; + if (OB_FAIL(MTL(logservice::ObLogService*)->get_palf_role(ls_id, role, proposal_id))) { + LOG_WARN("get palf role failed", K(ret)); + } else if (!is_strong_leader(role)) { + ret = OB_NOT_MASTER; + LOG_WARN("follwer received FetchTabletsSeq rpc", K(ret), K(ls_id)); + } else if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { + LOG_WARN("get ls failed", K(ret), K(ls_id)); + } else if (OB_FAIL(res.autoinc_params_.reserve(arg.src_tablet_ids_.count()))) { + LOG_WARN("failed to reserve autoinc param", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < arg.src_tablet_ids_.count(); i++) { + int tmp_ret = OB_SUCCESS; + const ObTabletID &src_tablet_id = arg.src_tablet_ids_.at(i); + ObTabletHandle tablet_handle; + share::ObMigrateTabletAutoincSeqParam autoinc_param; + ObArenaAllocator allocator("BatchGetSeq"); + autoinc_param.src_tablet_id_ = src_tablet_id; + autoinc_param.dest_tablet_id_ = arg.dest_tablet_ids_.at(i); + ObBucketHashRLockGuard lock_guard(bucket_lock_, src_tablet_id.hash()); + if (OB_TMP_FAIL(ls_handle.get_ls()->get_tablet(src_tablet_id, tablet_handle))) { + LOG_WARN("failed to get tablet", K(tmp_ret), K(src_tablet_id)); + } else { + ObTabletAutoincSeq autoinc_seq; + if (OB_TMP_FAIL(tablet_handle.get_obj()->get_autoinc_seq(allocator, share::SCN::max_scn(), autoinc_seq))) { + LOG_WARN("fail to get latest autoinc seq", K(ret)); + } else if (OB_TMP_FAIL(autoinc_seq.get_autoinc_seq_value(autoinc_param.autoinc_seq_))) { + LOG_WARN("failed to get autoinc seq value", K(tmp_ret)); + } + } + autoinc_param.ret_code_ = tmp_ret; + if (OB_FAIL(res.autoinc_params_.push_back(autoinc_param))) { + LOG_WARN("failed to push autoinc param", K(ret), K(autoinc_param)); + } + } + } + } + } + return ret; +} + +int ObTabletAutoincSeqRpcHandler::batch_set_tablet_autoinc_seq( + const obrpc::ObBatchSetTabletAutoincSeqArg &arg, + obrpc::ObBatchSetTabletAutoincSeqRes &res) +{ + int ret = OB_SUCCESS; + uint64_t tenant_id = arg.tenant_id_; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(arg)); + } else if (OB_FAIL(res.autoinc_params_.assign(arg.autoinc_params_))) { + LOG_WARN("failed to assign autoinc params", K(ret), K(arg)); + } else { + MTL_SWITCH(tenant_id) { + ObLSHandle ls_handle; + ObLS *ls = nullptr; + share::ObLSID ls_id = arg.ls_id_; + ObRole role = common::INVALID_ROLE; + int64_t proposal_id = -1; + if (OB_FAIL(MTL(logservice::ObLogService*)->get_palf_role(ls_id, role, proposal_id))) { + LOG_WARN("get palf role failed", K(ret)); + } else if (!is_strong_leader(role)) { + ret = OB_NOT_MASTER; + LOG_WARN("follwer received FetchTabletsSeq rpc", K(ret), K(ls_id)); + } else if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { + LOG_WARN("get ls failed", K(ret), K(ls_id)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < res.autoinc_params_.count(); i++) { + int tmp_ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + share::ObMigrateTabletAutoincSeqParam &autoinc_param = res.autoinc_params_.at(i); + ObBucketHashWLockGuard lock_guard(bucket_lock_, autoinc_param.dest_tablet_id_.hash()); + if (OB_TMP_FAIL(ls_handle.get_ls()->get_tablet(autoinc_param.dest_tablet_id_, tablet_handle))) { + LOG_WARN("failed to get tablet", K(tmp_ret), K(autoinc_param)); + } else if (OB_TMP_FAIL(tablet_handle.get_obj()->update_tablet_autoinc_seq(autoinc_param.autoinc_seq_))) { + LOG_WARN("failed to update tablet autoinc seq", K(tmp_ret), K(autoinc_param)); + } + autoinc_param.ret_code_ = tmp_ret; + } + } + } + } + return ret; +} + +int ObTabletAutoincSeqRpcHandler::replay_update_tablet_autoinc_seq( + const ObLS *ls, + const ObTabletID &tablet_id, + const uint64_t autoinc_seq, + const share::SCN &replay_scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(ls == nullptr || !tablet_id.is_valid() || autoinc_seq == 0 || !replay_scn.is_valid_and_not_min())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tablet_id), K(autoinc_seq), K(replay_scn)); + } else { + ObTabletHandle tablet_handle; + ObBucketHashWLockGuard guard(bucket_lock_, tablet_id.hash()); + ObSyncTabletSeqReplayExecutor replay_executor; + if (OB_FAIL(replay_executor.init(autoinc_seq, replay_scn))) { + LOG_WARN("failed to init tablet auto inc sequence replay executor", K(ret), K(autoinc_seq), K(replay_scn)); + } else if (OB_FAIL(replay_executor.execute(replay_scn, ls->get_ls_id(), tablet_id))) { + if (OB_TABLET_NOT_EXIST == ret) { + LOG_INFO("tablet may be deleted, skip this log", K(ret), K(tablet_id), K(replay_scn)); + ret = OB_SUCCESS; + } else if (OB_NO_NEED_UPDATE == ret) { + LOG_INFO("no need replay, skip this log", K(ret), K(tablet_id), K(replay_scn)); + ret = OB_SUCCESS; + } else if (OB_EAGAIN == ret) { + // retry replay again + } else { + LOG_WARN("fail to replay get tablet, retry again", K(ret), K(tablet_id), K(replay_scn)); + ret = OB_EAGAIN; + } + } + } + return ret; +} + +} +} diff --git a/src/storage/ob_tablet_autoinc_seq_rpc_handler.h b/src/storage/ob_tablet_autoinc_seq_rpc_handler.h new file mode 100644 index 000000000..87317256c --- /dev/null +++ b/src/storage/ob_tablet_autoinc_seq_rpc_handler.h @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2021 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_OB_TABLET_AUTOINC_SEQ_RPC_HANDLER_H_ +#define OCEANBASE_SHARE_OB_TABLET_AUTOINC_SEQ_RPC_HANDLER_H_ + +#include "lib/hash/ob_hashmap.h" +#include "lib/hash/ob_link_hashmap.h" +#include "lib/allocator/ob_small_allocator.h" +#include "share/ob_tablet_autoincrement_param.h" +#include "share/ob_rpc_struct.h" +#include "logservice/replayservice/ob_tablet_replay_executor.h" + +namespace oceanbase +{ +namespace storage +{ + +class ObSyncTabletSeqReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObSyncTabletSeqReplayExecutor(); + int init(const uint64_t autoinc_seq, + const share::SCN &replay_scn); + + TO_STRING_KV(K_(seq), + K_(scn)); + +protected: + bool is_replay_update_user_data_() const override + { + return false; + } + + // replay to the tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + int do_replay_(ObTabletHandle &handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return true; + } + +private: + uint64_t seq_; + share::SCN scn_; +}; + + +class ObTabletAutoincSeqRpcHandler final +{ +public: + static ObTabletAutoincSeqRpcHandler &get_instance(); + int init(); + int fetch_tablet_autoinc_seq_cache( + const obrpc::ObFetchTabletSeqArg &arg, + obrpc::ObFetchTabletSeqRes &res); + int batch_get_tablet_autoinc_seq( + const obrpc::ObBatchGetTabletAutoincSeqArg &arg, + obrpc::ObBatchGetTabletAutoincSeqRes &res); + int batch_set_tablet_autoinc_seq( + const obrpc::ObBatchSetTabletAutoincSeqArg &arg, + obrpc::ObBatchSetTabletAutoincSeqRes &res); + int replay_update_tablet_autoinc_seq( + const ObLS *ls, + const ObTabletID &tablet_id, + const uint64_t autoinc_seq, + const share::SCN &replay_scn); +private: + ObTabletAutoincSeqRpcHandler(); + ~ObTabletAutoincSeqRpcHandler(); +private: + static const int64_t BUCKET_LOCK_BUCKET_CNT = 10243L; + bool is_inited_; + common::ObBucketLock bucket_lock_; +}; + +} // end namespace storage +} // end namespace oceanbase +#endif diff --git a/src/storage/ob_tenant_tablet_stat_mgr.cpp b/src/storage/ob_tenant_tablet_stat_mgr.cpp index 36ebee666..98ad18b3d 100644 --- a/src/storage/ob_tenant_tablet_stat_mgr.cpp +++ b/src/storage/ob_tenant_tablet_stat_mgr.cpp @@ -317,24 +317,6 @@ void ObTabletStream::refresh() past_buckets_.refresh(tablet_stat, has_retired_stat); } -template -int ObTabletStream::get_bucket_tablet_stat( - const ObTabletStatBucket &bucket, - common::ObIArray &tablet_stats) const -{ - int ret = OB_SUCCESS; - int64_t idx = bucket.head_idx_; - - for (int64_t i = 0; OB_SUCC(ret) && i < bucket.count(); ++i) { - int64_t curr_idx = bucket.get_idx(idx); - if (OB_FAIL(tablet_stats.push_back(bucket.units_[curr_idx]))) { - LOG_WARN("failed to add tablet stat", K(ret), K(idx)); - } - ++idx; - } - return ret; -} - int ObTabletStream::get_all_tablet_stat(common::ObIArray &tablet_stats) const { int ret = OB_SUCCESS; diff --git a/src/storage/ob_tenant_tablet_stat_mgr.h b/src/storage/ob_tenant_tablet_stat_mgr.h index 6b1dea6f3..b7c64c194 100644 --- a/src/storage/ob_tenant_tablet_stat_mgr.h +++ b/src/storage/ob_tenant_tablet_stat_mgr.h @@ -149,7 +149,7 @@ template class ObTabletStatBucket { public: - ObTabletStatBucket(const uint64_t step) + ObTabletStatBucket(const uint32_t step) : head_idx_(0), curr_idx_(SIZE - 1), refresh_cnt_(0), step_(step) {} ~ObTabletStatBucket() {} void reset(); @@ -378,6 +378,23 @@ private: bool is_inited_; }; +template +int ObTabletStream::get_bucket_tablet_stat( + const ObTabletStatBucket &bucket, + common::ObIArray &tablet_stats) const +{ + int ret = OB_SUCCESS; + int64_t idx = bucket.head_idx_; + + for (int64_t i = 0; OB_SUCC(ret) && i < bucket.count(); ++i) { + int64_t curr_idx = bucket.get_idx(idx); + if (OB_FAIL(tablet_stats.push_back(bucket.units_[curr_idx]))) { + STORAGE_LOG(WARN, "failed to add tablet stat", K(ret), K(idx)); + } + ++idx; + } + return ret; +} #define CHECK_SCHEDULE_TIME_INTERVAL(interval, step) \ ({ \ diff --git a/src/storage/ob_value_row_iterator.cpp b/src/storage/ob_value_row_iterator.cpp index 24840d3e3..88eb1e2f6 100644 --- a/src/storage/ob_value_row_iterator.cpp +++ b/src/storage/ob_value_row_iterator.cpp @@ -205,7 +205,7 @@ int ObSingleRowGetter::init_dml_access_param(ObRelativeTable &relative_table, } if (OB_SUCC(ret)) { if (OB_FAIL(access_param_.init_dml_access_param(relative_table, - tablet_->get_full_read_info(), + tablet_->get_rowkey_read_info(), *schema_param, &output_projector_))) { LOG_WARN("init dml access param failed", K(ret)); diff --git a/src/storage/restore/ob_ls_restore_args.cpp b/src/storage/restore/ob_ls_restore_args.cpp index 76db96d35..4ee48f01f 100644 --- a/src/storage/restore/ob_ls_restore_args.cpp +++ b/src/storage/restore/ob_ls_restore_args.cpp @@ -20,6 +20,7 @@ ObTenantRestoreCtx::ObTenantRestoreCtx() : job_id_(0), restore_type_(), restore_scn_(), + consistent_scn_(), tenant_id_(0), backup_cluster_version_(0), backup_set_list_(), @@ -50,6 +51,7 @@ int ObTenantRestoreCtx::assign(const ObTenantRestoreCtx &args) job_id_ = args.get_job_id(); restore_type_ = args.get_restore_type(); restore_scn_ = args.get_restore_scn(); + consistent_scn_ = args.get_consistent_scn(); tenant_id_ = args.get_tenant_id(); backup_cluster_version_ = args.get_backup_cluster_version(); } diff --git a/src/storage/restore/ob_ls_restore_args.h b/src/storage/restore/ob_ls_restore_args.h index 77615559d..f1c864ca2 100644 --- a/src/storage/restore/ob_ls_restore_args.h +++ b/src/storage/restore/ob_ls_restore_args.h @@ -37,6 +37,7 @@ struct ObTenantRestoreCtx int64_t get_job_id() const { return job_id_; } const share::ObRestoreType &get_restore_type() const { return restore_type_; } const share::SCN &get_restore_scn() const { return restore_scn_; } + const share::SCN &get_consistent_scn() const { return consistent_scn_; } uint64_t get_tenant_id() const { return tenant_id_; } int64_t get_backup_cluster_version() const { return backup_cluster_version_; } const common::ObArray &get_backup_set_list() const { return backup_set_list_; } @@ -45,6 +46,7 @@ struct ObTenantRestoreCtx K_(job_id), K_(restore_type), K_(restore_scn), + K_(consistent_scn), K_(tenant_id), K_(backup_cluster_version), K_(backup_set_list), @@ -53,6 +55,7 @@ struct ObTenantRestoreCtx int64_t job_id_; share::ObRestoreType restore_type_; // quick restore or normal restore share::SCN restore_scn_; // restore end scn + share::SCN consistent_scn_; uint64_t tenant_id_; int64_t backup_cluster_version_; // every set path is integral. diff --git a/src/storage/restore/ob_ls_restore_handler.cpp b/src/storage/restore/ob_ls_restore_handler.cpp index 91de94e4b..efc508009 100644 --- a/src/storage/restore/ob_ls_restore_handler.cpp +++ b/src/storage/restore/ob_ls_restore_handler.cpp @@ -28,7 +28,7 @@ #include "storage/high_availability/ob_storage_ha_service.h" #include "storage/tablet/ob_tablet_iterator.h" #include "share/restore/ob_physical_restore_table_operator.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" #include "observer/ob_server_event_history_table_operator.h" #include "share/restore/ob_restore_persist_helper.h" #include "storage/tablet/ob_tablet.h" @@ -173,6 +173,37 @@ int ObLSRestoreHandler::record_clog_failed_info( return ret; } +void ObLSRestoreHandler::try_record_one_tablet_to_restore(const common::ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(mtx_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(state_handler_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("state_handler_ is null", K(ret)); + } else if (OB_FAIL(state_handler_->get_tablet_mgr().record_one_tablet_to_restore(tablet_id))) { + LOG_WARN("fail to record one tablet to restore", K(ret), KPC_(ls), K(tablet_id)); + } else { + LOG_INFO("succeed record one tablet to restore", KPC_(ls), K(tablet_id)); + } +} + +int ObLSRestoreHandler::get_consistent_scn(share::SCN &consistent_scn) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(mtx_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else { + consistent_scn = ls_restore_arg_.get_consistent_scn(); + } + + return ret; +} + int ObLSRestoreHandler::handle_execute_over( const share::ObTaskId &task_id, const ObIArray &restore_succeed_tablets, @@ -202,18 +233,21 @@ int ObLSRestoreHandler::handle_execute_over( role = state_handler_->get_role(); } +#ifdef ERRSIM + SERVER_EVENT_ADD("storage_ha", "handle_execute_over_errsim", "result", result); +#endif + if (status.is_restore_sys_tablets()) { state_handler_->set_retry_flag(); result_mgr_.set_result(result, task_id, ObLSRestoreResultMgr::RestoreFailedType::DATA_RESTORE_FAILED_TYPE); LOG_WARN("restore sys tablets dag failed, need retry", K(ret)); } else if (OB_TABLET_NOT_EXIST == result) { - // TODO: Transfer sequence in 4.1 needs to be compared when result is OB_TABLET_NOT_EXIST LOG_INFO("tablet has been deleted, no need to record err info", K(restore_failed_tablets)); } else if (common::ObRole::FOLLOWER == role && result_mgr_.can_retrieable_err(result)) { - LOG_INFO("follower met retrieable err, no need to record", K(result)); + LOG_INFO("follower met retrieable err, no need to record", K(result), K(task_id)); } else { result_mgr_.set_result(result, task_id, ObLSRestoreResultMgr::RestoreFailedType::DATA_RESTORE_FAILED_TYPE); - LOG_WARN("failed restore dag net task", K(result), K(task_id), K(ls_id), K(restore_succeed_tablets), K(restore_failed_tablets)); + LOG_WARN("failed restore dag net task", K(result), K(task_id), K(ls_id), K(restore_succeed_tablets), K(restore_failed_tablets), KPC_(ls)); } } return ret; @@ -433,6 +467,24 @@ int ObLSRestoreHandler::get_restore_state_handler_(const share::ObLSRestoreStatu } break; } + case ObLSRestoreStatus::Status::RESTORE_TO_CONSISTENT_SCN: { + ObLSRestoreConsistentScnState *tmp_ptr = nullptr; + if (OB_FAIL(construct_state_handler_(tmp_ptr))) { + LOG_WARN("fail to construct ObLSRestoreConsistentScnState", K(ret), K(new_status)); + } else { + new_state_handler = tmp_ptr; + } + break; + } + case ObLSRestoreStatus::Status::WAIT_RESTORE_TO_CONSISTENT_SCN: { + ObLSWaitRestoreConsistentScnState *tmp_ptr = nullptr; + if (OB_FAIL(construct_state_handler_(tmp_ptr))) { + LOG_WARN("fail to construct ObLSWaitRestoreConsistentScnState", K(ret), K(new_status)); + } else { + new_state_handler = tmp_ptr; + } + break; + } case ObLSRestoreStatus::Status::QUICK_RESTORE: { ObLSQuickRestoreState *tmp_ptr = nullptr; if (OB_FAIL(construct_state_handler_(tmp_ptr))) { @@ -546,69 +598,6 @@ int ObLSRestoreHandler::deal_failed_restore_() return ret; } -int ObLSRestoreHandler::check_tablet_restore_finish_( - const share::ObLSRestoreStatus &ls_restore_status, - const ObTabletMeta &tablet_meta, - bool &is_finish) -{ - int ret = OB_SUCCESS; - ObTabletRestoreStatus::STATUS restore_status = ObTabletRestoreStatus::RESTORE_STATUS_MAX; - - is_finish = false; - if (!ls_restore_status.is_valid() || !tablet_meta.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(ls_restore_status), K(tablet_meta)); - } else if (OB_FAIL(tablet_meta.ha_status_.get_restore_status(restore_status))) { - LOG_WARN("failed to get tablet restore status", K(ret), K(tablet_meta)); - } else { - switch (ls_restore_status.get_status()) { - case ObLSRestoreStatus::RESTORE_TABLETS_META : { - if (!ObTabletRestoreStatus::is_pending(restore_status)) { - is_finish = true; - } - break; - } - case ObLSRestoreStatus::QUICK_RESTORE: { - if (ObTabletRestoreStatus::is_minor_and_major_meta(restore_status) - || ObTabletRestoreStatus::is_full(restore_status)) { - // tablet restored from backup, expected status is MINOR_AND_MAJOR_DATA - // tablet created from clog, expected status is FULL - is_finish = true; - } - break; - } - case ObLSRestoreStatus::RESTORE_MAJOR_DATA : { - if (ObTabletRestoreStatus::is_full(restore_status)) { - is_finish = true; - } - break; - } - default: { - is_finish = false; - } - } - } - return ret; -} - -int ObLSRestoreHandler::check_tablet_deleted(const ObTabletHandle &tablet_handle, bool &is_deleted) -{ - int ret = OB_SUCCESS; - // TODO(chongrong.th) need to think about transfer out deleted in 4.2 - is_deleted = false; - ObTabletStatus::Status tablet_status = ObTabletStatus::Status::MAX; - if (!tablet_handle.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid tablet handle", K(ret)); - } else if (OB_FAIL(tablet_handle.get_obj()->get_tablet_status(tablet_status))) { - LOG_WARN("failed to get tablet status", K(ret)); - } else if (ObTabletStatus::Status::DELETED == tablet_status) { - is_deleted = true; - const ObTabletID tablet_id = tablet_handle.get_obj()->get_tablet_meta().tablet_id_; - LOG_INFO("tablet deleted", K(tablet_id), K(tablet_status)); - } - return ret; -} void ObLSRestoreHandler::wakeup() { int ret = OB_SUCCESS; @@ -671,6 +660,7 @@ int64_t ObLSRestoreHandler::get_rebuild_seq() return ATOMIC_LOAD(&rebuild_seq_); } + //================================ObILSRestoreState======================================= ObILSRestoreState::ObILSRestoreState(const share::ObLSRestoreStatus::Status &status) @@ -703,28 +693,25 @@ int ObILSRestoreState::init(storage::ObLS &ls, logservice::ObLogService &log_srv if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret)); - } else if (OB_FAIL(tablet_mgr_.init())) { + } else if (OB_FAIL(tablet_mgr_.init(this, ls.get_ls_id()))) { LOG_WARN("fail to init tablet mgr", K(ret), K(ls)); } else if (OB_FAIL(log_srv.get_palf_role(ls.get_ls_id(), role_, proposal_id_))) { LOG_WARN("fail to get role", K(ret), "ls_id", ls.get_ls_id()); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); } else { ls_ = &ls; ls_restore_arg_ = &restore_args; - if (OB_FAIL(reload_tablet_())) { - LOG_WARN("fail to reload tablet", K(ret), K(ls)); - } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); - } else { - cluster_id_ = GCONF.cluster_id; - location_service_ = GCTX.location_service_; - bandwidth_throttle_ = GCTX.bandwidth_throttle_; - proxy_ = GCTX.sql_proxy_; - self_addr_ = GCTX.self_addr(); - svr_rpc_proxy_ = ls_service->get_storage_rpc_proxy(); - storage_rpc_ = ls_service->get_storage_rpc(); - is_inited_ = true; - } + cluster_id_ = GCONF.cluster_id; + location_service_ = GCTX.location_service_; + bandwidth_throttle_ = GCTX.bandwidth_throttle_; + proxy_ = GCTX.sql_proxy_; + self_addr_ = GCTX.self_addr(); + svr_rpc_proxy_ = ls_service->get_storage_rpc_proxy(); + storage_rpc_ = ls_service->get_storage_rpc(); + tablet_mgr_.set_force_reload(); + is_inited_ = true; } return ret; } @@ -765,6 +752,19 @@ int ObILSRestoreState::handle_pull_tablet( return ret; } +int ObILSRestoreState::check_leader_restore_finish(bool &finish) +{ + int ret = OB_SUCCESS; + ObLSRestoreStatus leader_restore_status; + if (OB_FAIL(request_leader_status_(leader_restore_status))) { + LOG_WARN("fail to request leader tablets and status", K(ret), KPC_(ls)); + } else { + finish = check_leader_restore_finish_(leader_restore_status, ls_restore_status_); + } + + return ret; +} + int ObILSRestoreState::update_restore_status_( storage::ObLS &ls, const share::ObLSRestoreStatus &next_status) { @@ -796,14 +796,14 @@ int ObILSRestoreState::deal_failed_restore(const ObLSRestoreResultMgr &result_mg { int ret = OB_SUCCESS; ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::RESTORE_FAILED); - ObLSRestoreResultMgr::Comment comment; + ObHAResultInfo::Comment comment; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); } else if (OB_FAIL(update_restore_status_(*ls_, next_status))) { LOG_WARN("failed to update restore status", K(ret), KPC(ls_), K(next_status)); - } else if (OB_FAIL(result_mgr.get_comment_str(comment))) { + } else if (OB_FAIL(result_mgr.get_comment_str(ls_->get_ls_id(), self_addr_, comment))) { LOG_WARN("fail to get comment str", K(ret)); } else if (OB_FAIL(report_ls_restore_progress_(*ls_, next_status, result_mgr.get_trace_id(), result_mgr.get_result(), comment.ptr()))) { @@ -929,15 +929,13 @@ int ObILSRestoreState::update_role_() } else if (is_switch_to_leader_(new_role)) { LOG_WARN("change role from follower to leader", K(ret), "new role", new_role, "old role", role_); role_ = new_role; - if (OB_FAIL(reload_tablet_())) { - LOG_WARN("fail to reload tablet", K(ret), KPC(ls_)); - } + tablet_mgr_.switch_to_leader(); } else if (is_switch_to_follower_(new_role)) { LOG_WARN("change role from leader to follower", K(ret), "new role", new_role, "old role", role_); - tablet_mgr_.reuse_wait_set(); role_ = new_role; + tablet_mgr_.switch_to_follower(); } else if (ObRole::FOLLOWER == role_ && proposal_id != proposal_id_) { - tablet_mgr_.reuse_wait_set(); + tablet_mgr_.leader_switched(); } if (OB_SUCC(ret)) { proposal_id_ = proposal_id; @@ -979,75 +977,6 @@ int ObILSRestoreState::check_new_election_(bool &is_changed) const return ret; } -int ObILSRestoreState::reload_tablet_() -{ - // when server downtime, and restart need reload tablet into wait set or scheduler set - int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObLSTabletService *ls_tablet_svr = nullptr; - ObTablet *tablet = nullptr; - ObSArray need_restore_tablets; - ObSArray restored_tablets; - - if (!ls_restore_status_.is_quick_restore() && !ls_restore_status_.is_restore_major_data() && !ls_restore_status_.is_restore_tablets_meta()) { - LOG_INFO("no need reload tablet", K(ls_restore_status_), KPC(ls_)); - } else if (OB_ISNULL(ls_tablet_svr = ls_->get_tablet_svr())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls_tablet_svr is nullptr", K(ret)); - } else { - ObLSTabletIterator iterator(ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US); - if (OB_FAIL(ls_tablet_svr->build_tablet_iter(iterator))) { - LOG_WARN("fail to build tablet iterator", K(ret), KPC(ls_)); - } - - while (OB_SUCC(ret)) { - bool is_deleted = false; - if (OB_FAIL(iterator.get_next_tablet(tablet_handle))) { - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - break; - } else { - LOG_WARN("fail to get next tablet", K(ret)); - } - } else if (OB_FAIL(ObLSRestoreHandler::check_tablet_deleted(tablet_handle, is_deleted))) { - LOG_WARN("failed to check tablet need schedule restore", K(ret), K(tablet_handle)); - } else if (is_deleted) { - } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tablet is nullptr", K(ret)); - } else { - const ObTabletMeta &tablet_meta = tablet->get_tablet_meta(); - const ObTabletID &tablet_id = tablet_meta.tablet_id_; - bool is_finish = false; - if (!tablet_meta.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid tablet meta", K(ret), K(tablet_meta)); - } else if (tablet_meta.tablet_id_.is_ls_inner_tablet()) { - } else if (OB_FAIL(ObLSRestoreHandler::check_tablet_restore_finish_(ls_restore_status_, tablet_meta, is_finish))) { - LOG_WARN("fail to check tablet restored finish", K(ret), K(ls_restore_status_), K(tablet_meta), KPC(ls_)); - } else if (is_finish) { - if (OB_FAIL(restored_tablets.push_back(tablet_id))) { - LOG_WARN("fail to insert tablet into scheduler tablet set", K(ret), K(tablet_id)); - } - } else if (!is_follower(role_) && OB_FAIL(need_restore_tablets.push_back(tablet_id))) { - LOG_WARN("fail to insert tablet into wait tablet set", K(ret), K(tablet_id)); - } - } - } - - LOG_INFO("server downtime and restart", KPC(ls_), K(role_), K(need_restore_tablets), K(restored_tablets)); - if (OB_FAIL(ret)) { - } else if (!restored_tablets.empty() && OB_FAIL(tablet_mgr_.add_tablet_in_schedule_set(restored_tablets))) { - LOG_WARN("fail to add finish restore tablet into scheduled set of tablet mgr", K(ret), K(restored_tablets)); - } else if (!need_restore_tablets.empty() && OB_FAIL(tablet_mgr_.add_tablet_in_wait_set(need_restore_tablets))) { - LOG_WARN("fail to add need restore tablet into wait tablet set of tablet mgr", K(ret), K(need_restore_tablets)); - } else { - LOG_INFO("success to reload tablet", KPC(ls_), K(need_restore_tablets), K(restored_tablets)); - } - } - return ret; -} - int ObILSRestoreState::request_leader_status_(ObLSRestoreStatus &leader_restore_status) { int ret = OB_SUCCESS; @@ -1086,62 +1015,6 @@ int ObILSRestoreState::get_leader_(ObStorageHASrcInfo &leader) return ret; } -int ObILSRestoreState::upload_wait_restore_tablet_() -{ - int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObLSTabletService *ls_tablet_svr = nullptr; - ObLSTabletIterator iterator(ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US); - ObTablet *tablet = nullptr; - ObSArray tablet_ids; - - if (nullptr == (ls_tablet_svr = ls_->get_tablet_svr())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("ls_tablet_svr is nullptr", K(ret)); - } else if (OB_FAIL(ls_tablet_svr->build_tablet_iter(iterator))) { - LOG_WARN("fail to get tablet iterator", K(ret), KPC(ls_)); - } else { - bool is_finish = false; - while (OB_SUCC(ret)) { - is_finish = false; - bool is_deleted = false; - if (OB_FAIL(iterator.get_next_tablet(tablet_handle))) { - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - break; - } else { - LOG_WARN("fail to get next tablet", K(ret)); - } - } else if (OB_FAIL(ObLSRestoreHandler::check_tablet_deleted(tablet_handle, is_deleted))) { - LOG_WARN("failed to check tablet need schedule restore", K(ret), K(tablet_handle)); - } else if (is_deleted) { - } else if (nullptr == (tablet = tablet_handle.get_obj())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tablet is nullptr", K(ret)); - } else { - const ObTabletMeta &tablet_meta = tablet->get_tablet_meta(); - if (!tablet_meta.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid tablet meta", K(ret), K(tablet_meta)); - } else if (tablet_meta.tablet_id_.is_ls_inner_tablet()) { - } else if (OB_FAIL(ObLSRestoreHandler::check_tablet_restore_finish_(ls_restore_status_, - tablet_meta, is_finish))) { - LOG_WARN("fail to check tablet restore finish", K(ret)); - } else if (!is_finish && OB_FAIL(tablet_ids.push_back(tablet_meta.tablet_id_))) { - LOG_WARN("fail to push back tablet id", K(ret), K(tablet_meta)); - } - } - } - if (OB_FAIL(ret) || tablet_ids.empty()) { - } else if (OB_FAIL(tablet_mgr_.add_tablet_in_wait_set(tablet_ids))) { - LOG_WARN("fail to add tablet in wait set of tablet mgr", K(ret), KPC(ls_)); - } else { - LOG_INFO("succ to upload tablet from ls", KPC(ls_), K(tablet_ids)); - } - } - return ret; -} - int ObILSRestoreState::leader_fill_tablet_group_restore_arg_( const ObIArray &tablet_need_restore, const ObTabletRestoreAction::ACTION &action, @@ -1346,7 +1219,8 @@ int ObILSRestoreState::check_follower_restore_finish(const share::ObLSRestoreSta } bool ObILSRestoreState::check_leader_restore_finish_( - const share::ObLSRestoreStatus &leader_status, const share::ObLSRestoreStatus &follower_status) + const share::ObLSRestoreStatus &leader_status, + const share::ObLSRestoreStatus &follower_status) const { bool ret = false; if (!leader_status.is_valid() || leader_status.is_restore_failed()) { @@ -1359,19 +1233,6 @@ bool ObILSRestoreState::check_leader_restore_finish_( return ret; } -int ObILSRestoreState::reload_miss_tablet_(bool &all_finish) -{ - int ret = OB_SUCCESS; - all_finish = false; - if (OB_FAIL(upload_wait_restore_tablet_())) { - LOG_WARN("fail to upload wait restore tablet", K(ret), KPC(ls_)); - } else if (tablet_mgr_.is_restore_completed()) { - all_finish = true; - LOG_INFO("follower succed restore tablets", KPC(ls_)); - } - return ret; -} - int ObILSRestoreState::check_restore_concurrency_limit_(bool &reach_limit) { int ret = OB_SUCCESS; @@ -1447,7 +1308,6 @@ int ObILSRestoreState::schedule_tablet_group_restore_dag_net_( const share::ObTaskId &task_id) { int ret = OB_SUCCESS; - ObTabletGroupRestoreDagNet *tg_restore_dag_net = nullptr; ObTGRDagNetInitParam param; if (!is_inited_) { @@ -1465,15 +1325,17 @@ int ObILSRestoreState::schedule_tablet_group_restore_dag_net_( if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret), KP(scheduler)); - } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m, tg_restore_dag_net))) { + } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m))) { LOG_WARN("failed to create and add tablet group restore dag net", K(ret), K(arg), K(task_id)); } else { SERVER_EVENT_ADD("storage_ha", "restore_tablet_group", "tenant_id", MTL_ID(), "ls_id", arg.ls_id_.id(), + "status", ls_restore_status_.get_status(), "task_id", task_id, + "action", arg.action_, "tablet_count", arg.tablet_id_array_.count()); - LOG_INFO("success to create tablet group restore dag net", K(ret), K(arg), K(task_id), KP(tg_restore_dag_net)); + LOG_INFO("success to create tablet group restore dag net", K(ret), K(arg), K(task_id)); } } return ret; @@ -1507,7 +1369,6 @@ int ObILSRestoreState::schedule_ls_restore_dag_net_( const share::ObTaskId &task_id) { int ret = OB_SUCCESS; - ObLSRestoreDagNet *ls_restore_dag_net = nullptr; ObLSRestoreDagNetInitParam param; if (!is_inited_) { @@ -1525,15 +1386,38 @@ int ObILSRestoreState::schedule_ls_restore_dag_net_( if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret), KP(scheduler)); - } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m, ls_restore_dag_net))) { + } else if (OB_FAIL(scheduler->create_and_add_dag_net(¶m))) { LOG_WARN("failed to create and add ls restore dag net", K(ret), K(arg), K(task_id)); } else { - LOG_INFO("success to create ls restore dag net", K(ret), K(arg), K(task_id), KP(ls_restore_dag_net)); + LOG_INFO("success to create ls restore dag net", K(ret), K(arg), K(task_id)); } } return ret; } +int ObILSRestoreState::check_replay_to_target_scn_( + const share::SCN &target_scn, + bool &replayed) const +{ + int ret = OB_SUCCESS; + replayed = false; + rootserver::ObLSRecoveryStatHandler *ls_recovery_stat_handler = nullptr; + share::SCN readable_scn; + if (!target_scn.is_valid_and_not_min()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid target scn", K(ret), K(target_scn)); + } else if (OB_ISNULL(ls_recovery_stat_handler = ls_->get_ls_recovery_stat_handler())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls recovery stat handler must not be null", K(ret)); + } else if (OB_FAIL(ls_recovery_stat_handler->get_ls_replica_readable_scn(readable_scn))) { + LOG_WARN("failed to get ls replica readable scn", K(ret), KPC(ls_)); + } else if (target_scn <= readable_scn) { + replayed = true; + LOG_INFO("clog replay to target scn finish", K(target_scn), K(readable_scn), KPC(ls_)); + } + return ret; +} + //================================ObLSRestoreStartState======================================= ObLSRestoreStartState::ObLSRestoreStartState() : ObILSRestoreState(ObLSRestoreStatus::Status::RESTORE_START) @@ -1621,8 +1505,8 @@ int ObLSRestoreStartState::do_with_no_ls_meta_() int ret = OB_SUCCESS; // ls with no ls meta means it created after backup ls_attr_infos. // this ls doesn't have ls meta and tablet in backup, it only needs to replay clog. - // so just advance to qucik restore and start replay clog. - ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::QUICK_RESTORE); + // so just advance to restore to consistent_scn and start replay clog. + ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::RESTORE_TO_CONSISTENT_SCN); if (OB_FAIL(online_())) { LOG_WARN("fail to enable log", K(ret)); } else if (OB_FAIL(advance_status_(*ls_, next_status))) { @@ -1711,6 +1595,7 @@ int ObLSRestoreHandler::fill_restore_arg_() ls_restore_arg_.restore_type_ = share::ObRestoreType::NORMAL_RESTORE; // quick restore or normal restore ls_restore_arg_.tenant_id_ = tenant_id; ls_restore_arg_.restore_scn_ = job_info.get_restore_scn(); + ls_restore_arg_.consistent_scn_ = job_info.get_consistent_scn(); ls_restore_arg_.backup_cluster_version_ = job_info.get_source_cluster_version(); ls_restore_arg_.backup_set_list_.reset(); ls_restore_arg_.backup_piece_list_.reset(); @@ -1752,7 +1637,7 @@ int ObLSRestoreStartState::check_ls_created_(bool &is_created) int ObLSRestoreStartState::check_ls_meta_exist_(bool &is_exist) { int ret = OB_SUCCESS; - share::ObBackupDataStore store; + storage::ObBackupDataStore store; const ObArray &backup_set_array = ls_restore_arg_->get_backup_set_list(); int idx = backup_set_array.count() - 1; ObLSMetaPackage ls_meta_packge; @@ -1846,15 +1731,14 @@ int ObLSRestoreSysTabletState::leader_restore_sys_tablet_() int ret = OB_SUCCESS; ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::WAIT_RESTORE_SYS_TABLETS); ObArray no_use_tablet_ids; - storage::ObLSRestoreHandler *ls_restore_handler = nullptr; LOG_INFO("ready to restore leader sys tablet", K(ls_restore_status_), KPC(ls_)); - if (tablet_mgr_.has_no_task()) { + if (tablet_mgr_.has_no_tablets_restoring()) { if (OB_FAIL(do_restore_sys_tablet())) { LOG_WARN("fail to do restore sys tablet", K(ret), KPC(ls_)); } - } else if (OB_FAIL(tablet_mgr_.pop_restored_tablets(*ls_, no_use_tablet_ids))) { + } else if (OB_FAIL(tablet_mgr_.remove_restored_tablets(no_use_tablet_ids))) { LOG_WARN("fail to pop restored tablets", K(ret)); - } else if (!tablet_mgr_.is_restore_completed()) {// TODO: check restore finish, should read from extern. fix later + } else if (!tablet_mgr_.has_no_tablets_restoring()) {// TODO: check restore finish, should read from extern. fix later } else if (is_need_retry_()) { // next term to retry } else if (OB_FAIL(online_())) { @@ -1873,20 +1757,20 @@ int ObLSRestoreSysTabletState::leader_restore_sys_tablet_() int ObLSRestoreSysTabletState::follower_restore_sys_tablet_() { int ret = OB_SUCCESS; - ObLSRestoreStatus leader_restore_status; ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::WAIT_RESTORE_SYS_TABLETS); ObArray no_use_tablet_ids; LOG_INFO("ready to restore follower sys tablet", K(ls_restore_status_), KPC(ls_)); - if (tablet_mgr_.has_no_task()) { - if (OB_FAIL(request_leader_status_(leader_restore_status))) { - LOG_WARN("fail to request leader tablets and status", K(ret), KPC(ls_)); - } else if (check_leader_restore_finish_(leader_restore_status, ls_restore_status_) - && OB_FAIL(do_restore_sys_tablet())) { + if (tablet_mgr_.has_no_tablets_restoring()) { + bool finish = false; + if (OB_FAIL(check_leader_restore_finish(finish))) { + LOG_WARN("fail to check leader restore finish", K(ret), KPC(ls_)); + } else if (!finish) { + } else if (OB_FAIL(do_restore_sys_tablet())) { LOG_WARN("fail to do restore sys tablet", K(ret), KPC(ls_)); } - } else if (OB_FAIL(tablet_mgr_.pop_restored_tablets(*ls_, no_use_tablet_ids))) { - LOG_WARN("fail to pop restored tablets", K(ret), KPC(ls_)); - } else if (!tablet_mgr_.is_restore_completed()) { + } else if (OB_FAIL(tablet_mgr_.remove_restored_tablets(no_use_tablet_ids))) { + LOG_WARN("fail to handle restoring tablets", K(ret), KPC(ls_)); + } else if (!tablet_mgr_.has_no_tablets_restoring()) { } else if (is_need_retry_()) { // next term to retry } else if (OB_FAIL(online_())) { @@ -1907,18 +1791,14 @@ int ObLSRestoreSysTabletState::do_restore_sys_tablet() int ret = OB_SUCCESS; ObLSRestoreArg arg; uint64_t tenant_id = arg.tenant_id_; - ObSArray fake_tablets; ObCurTraceId::init(GCONF.self_addr_); ObTaskId task_id(*ObCurTraceId::get_trace_id()); - bool reach_dag_limit = false; if (!is_follower(role_) && OB_FAIL(leader_fill_ls_restore_arg_(arg))) { LOG_WARN("fail to fill ls restore arg", K(ret)); } else if (is_follower(role_) && OB_FAIL(follower_fill_ls_restore_arg_(arg))) { LOG_WARN("fail to fill ls restore arg", K(ret)); - } else if (OB_FAIL(tablet_mgr_.schedule_tablet(task_id, fake_tablets, reach_dag_limit))) { - LOG_WARN("fail to schedule tablet", K(ret), K(fake_tablets), KPC(ls_)); - } else if (reach_dag_limit) { - LOG_INFO("reach restore dag net max limit, wait later"); + } else if (OB_FAIL(tablet_mgr_.schedule_ls_restore(task_id))) { + LOG_WARN("fail to schedule tablet", K(ret), KPC(ls_)); } else if (OB_FAIL(schedule_ls_restore_(arg, task_id))) { LOG_WARN("fail to schedule restore sys tablet", KR(ret), K(arg), K(task_id)); } else { @@ -2012,11 +1892,11 @@ int ObLSRestoreCreateUserTabletState::leader_create_user_tablet_() { int ret = OB_SUCCESS; ObSArray restored_tablets; - ObSArray tablet_need_restore; + ObLSRestoreTaskMgr::ToRestoreTabletGroup tablet_need_restore; LOG_INFO("ready to create leader user tablet", K(ls_restore_status_), KPC(ls_)); - if (OB_FAIL(tablet_mgr_.pop_restored_tablets(*ls_, restored_tablets))) { + if (OB_FAIL(tablet_mgr_.remove_restored_tablets(restored_tablets))) { LOG_WARN("fail to pop restored tablets", K(ret), KPC(ls_)); - } else if (OB_FAIL(tablet_mgr_.pop_need_restore_tablets(*ls_, tablet_need_restore))) { + } else if (OB_FAIL(tablet_mgr_.choose_tablets_to_restore(tablet_need_restore))) { LOG_WARN("fail to pop need restore tablets", K(ret), KPC(ls_)); } else if (tablet_need_restore.empty()) { ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::WAIT_RESTORE_TABLETS_META); @@ -2025,7 +1905,6 @@ int ObLSRestoreCreateUserTabletState::leader_create_user_tablet_() LOG_WARN("fail to advance status", K(ret), KPC(ls_), K(next_status)); } else { LOG_INFO("success create leader user tablets", KPC(ls_)); - tablet_mgr_.reuse_set(); } } else if (OB_FAIL(do_create_user_tablet_(tablet_need_restore))) { LOG_WARN("fail to do quick restore", K(ret), K(tablet_need_restore), KPC(ls_)); @@ -2045,41 +1924,30 @@ int ObLSRestoreCreateUserTabletState::follower_create_user_tablet_() { int ret = OB_SUCCESS; ObSArray restored_tablets; - ObSArray tablet_need_restore; + ObLSRestoreTaskMgr::ToRestoreTabletGroup tablet_need_restore; LOG_INFO("ready to create follower user tablet", K(ls_restore_status_), KPC(ls_)); - if (OB_FAIL(tablet_mgr_.pop_restored_tablets(*ls_, restored_tablets))) { + if (OB_FAIL(tablet_mgr_.remove_restored_tablets(restored_tablets))) { LOG_WARN("fail to pop restored tablets", K(ret), KPC(ls_)); - } else if (OB_FAIL(tablet_mgr_.pop_need_restore_tablets(*ls_, tablet_need_restore))) { - LOG_WARN("fail to pop need restore tablets", K(ret), KPC(ls_)); + } else if (OB_FAIL(tablet_mgr_.choose_tablets_to_restore(tablet_need_restore))) { + LOG_WARN("fail to choose need restore tablets", K(ret), KPC(ls_)); } else if (tablet_need_restore.empty()) { ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::WAIT_RESTORE_TABLETS_META); ObLSRestoreStatus leader_restore_status; - bool all_finish = false; - if (OB_FAIL(request_leader_status_(leader_restore_status))) { - LOG_WARN("fail to request leader tablets and status", K(ret), KPC(ls_)); - } else if (check_leader_restore_finish_(leader_restore_status, ls_restore_status_)) { - if (OB_FAIL(reload_miss_tablet_(all_finish))) { - LOG_WARN("fail to check follower restore tablet all finish", K(ret), KPC(ls_)); - } else if (all_finish) { - if (OB_FAIL(advance_status_(*ls_, next_status))) { - LOG_WARN("fail to advance status", K(ret), KPC(ls_), K(next_status)); - } else { - LOG_INFO("success create follower user tablets", KPC(ls_)); - tablet_mgr_.reuse_set(); - } - } + bool finish = false; + if (!tablet_mgr_.is_restore_completed()) { + } else if (OB_FAIL(advance_status_(*ls_, next_status))) { + LOG_WARN("fail to advance status", K(ret), KPC(ls_), K(next_status)); + } else { + LOG_INFO("success create follower user tablets", KPC(ls_)); } } else if (OB_FAIL(do_create_user_tablet_(tablet_need_restore))) { - if (OB_EAGAIN == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("fail to do quick restore", K(ret), K(tablet_need_restore), KPC(ls_)); - } + LOG_WARN("fail to do quick restore", K(ret), K(tablet_need_restore), KPC(ls_)); } return ret; } -int ObLSRestoreCreateUserTabletState::do_create_user_tablet_(const ObSArray &tablet_need_restore) +int ObLSRestoreCreateUserTabletState::do_create_user_tablet_( + const ObLSRestoreTaskMgr::ToRestoreTabletGroup &tablet_need_restore) { int ret = OB_SUCCESS; ObTabletGroupRestoreArg arg; @@ -2087,16 +1955,16 @@ int ObLSRestoreCreateUserTabletState::do_create_user_tablet_(const ObSArrayget_consistent_scn(), is_finish))) { + LOG_WARN("failed to check clog replay to consistent scn", K(ret)); + } + + return ret; +} + +int ObLSRestoreConsistentScnState::set_empty_for_transfer_tablets_() +{ + int ret = OB_SUCCESS; + ObLSTabletService *ls_tablet_svr = nullptr; + ObLSTabletIterator iterator(ObMDSGetTabletMode::READ_WITHOUT_CHECK); + const ObTabletRestoreStatus::STATUS restore_status = ObTabletRestoreStatus::EMPTY; + + if (OB_ISNULL(ls_tablet_svr = ls_->get_tablet_svr())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_tablet_svr is nullptr", K(ret)); + } else if (OB_FAIL(ls_tablet_svr->build_tablet_iter(iterator))) { + LOG_WARN("fail to build tablet iterator", K(ret), KPC_(ls)); + } + + while (OB_SUCC(ret)) { + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + if (OB_FAIL(iterator.get_next_tablet(tablet_handle))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get next tablet", K(ret)); + } + break; + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is nullptr", K(ret), K(tablet_handle)); + } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { + } else if (tablet->is_empty_shell()) { + LOG_INFO("skip empty shell", "tablet_id", tablet->get_tablet_meta().tablet_id_); + } else if (!tablet->get_tablet_meta().has_transfer_table()) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + if (OB_EMPTY_RESULT == ret) { + LOG_INFO("skip tablet which transfer in not commit", KPC(tablet)); + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet status", K(ret), KPC(tablet)); + } + } else if (!tablet->get_tablet_meta().ha_status_.is_restore_status_full()) { + LOG_INFO("skip tablet which restore status is not full", + "tablet_id", tablet->get_tablet_meta().tablet_id_, + "ha_status", tablet->get_tablet_meta().ha_status_); + } else if (OB_FAIL(ls_->update_tablet_restore_status(tablet->get_tablet_meta().tablet_id_, restore_status))) { + LOG_WARN("failed to update tablet restore status to EMPTY", K(ret), KPC(tablet)); + } else { + LOG_INFO("update tablet restore status to EMPTY", + "tablet_meta", tablet->get_tablet_meta()); + } + } + + return ret; +} + + //================================ObLSQuickRestoreState======================================= ObLSQuickRestoreState::ObLSQuickRestoreState() @@ -2119,9 +2079,18 @@ ObLSQuickRestoreState::~ObLSQuickRestoreState() { } +int ObLSQuickRestoreState::check_recover_finish(bool &is_finish) const +{ + int ret = OB_SUCCESS; + if (OB_FAIL(check_replay_to_target_scn_(ls_restore_arg_->get_restore_scn(), is_finish))) { + LOG_WARN("failed to check clog replay to restore scn", K(ret)); + } + + return ret; +} + int ObLSQuickRestoreState::do_restore() { - // TODO: restore adaptats transfer in 4.1 DEBUG_SYNC(BEFORE_RESTORE_MINOR); int ret = OB_SUCCESS; if (IS_NOT_INIT) { @@ -2141,16 +2110,16 @@ int ObLSQuickRestoreState::leader_quick_restore_() { int ret = OB_SUCCESS; ObSArray restored_tablets; - ObSArray tablet_need_restore; + ObLSRestoreTaskMgr::ToRestoreTabletGroup tablet_need_restore; ObLogRestoreHandler *log_restore_handle = ls_->get_log_restore_handler(); LOG_INFO("ready to leader quick restore", K(ls_restore_status_), KPC(ls_)); if (OB_ISNULL(log_restore_handle)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log restore handle can't nullptr", K(ret), K(log_restore_handle)); - } else if (OB_FAIL(tablet_mgr_.pop_restored_tablets(*ls_, restored_tablets))) { + } else if (OB_FAIL(tablet_mgr_.remove_restored_tablets(restored_tablets))) { LOG_WARN("fail to pop restored tablets", K(ret), KPC(ls_)); - } else if (OB_FAIL(tablet_mgr_.pop_need_restore_tablets(*ls_, tablet_need_restore))) { - LOG_WARN("fail to pop need restore tablets", K(ret), KPC(ls_)); + } else if (OB_FAIL(tablet_mgr_.choose_tablets_to_restore(tablet_need_restore))) { + LOG_WARN("fail to choose need restore tablets", K(ret), KPC(ls_)); } else if (tablet_need_restore.empty()) { bool is_finish = false; ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::WAIT_QUICK_RESTORE); @@ -2167,7 +2136,6 @@ int ObLSQuickRestoreState::leader_quick_restore_() LOG_WARN("fail to advance status", K(ret), KPC(ls_), K(next_status)); } else { LOG_INFO("leader quick restore success", KPC(ls_)); - tablet_mgr_.reuse_set(); } } else if (OB_FAIL(do_quick_restore_(tablet_need_restore))) { LOG_WARN("fail to do quick restore", K(ret), K(tablet_need_restore), KPC(ls_)); @@ -2179,6 +2147,9 @@ int ObLSQuickRestoreState::leader_quick_restore_() #endif } +#if 0 + // TODO(wangxiaohui.wxh): let leader restore from backup and follower restore from leader. + int tmp_ret = OB_SUCCESS; // try rpc's best if (restored_tablets.empty()) { } else if (OB_SUCCESS != (tmp_ret = notify_follower_restore_tablet_(restored_tablets))) { @@ -2186,6 +2157,8 @@ int ObLSQuickRestoreState::leader_quick_restore_() } else { LOG_INFO("success send tablets to follower for restore", K(restored_tablets)); } +#endif + return ret; } @@ -2193,48 +2166,40 @@ int ObLSQuickRestoreState::follower_quick_restore_() { int ret = OB_SUCCESS; ObSArray restored_tablets; - ObSArray tablet_need_restore; + ObLSRestoreTaskMgr::ToRestoreTabletGroup tablet_need_restore; ObLogRestoreHandler *log_restore_handle = ls_->get_log_restore_handler(); LOG_INFO("ready to follower quick restore", K(ls_restore_status_), KPC(ls_)); if (OB_ISNULL(log_restore_handle)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log restore handle can't nullptr", K(ret), K(log_restore_handle)); - } else if (OB_FAIL(tablet_mgr_.pop_restored_tablets(*ls_, restored_tablets))) { + } else if (OB_FAIL(tablet_mgr_.remove_restored_tablets(restored_tablets))) { LOG_WARN("fail to pop restored tablets", K(ret), KPC(ls_)); - } else if (OB_FAIL(tablet_mgr_.pop_need_restore_tablets(*ls_, tablet_need_restore))) { - LOG_WARN("fail to pop need restore tablets", K(ret), KPC(ls_)); + } else if (OB_FAIL(tablet_mgr_.choose_tablets_to_restore(tablet_need_restore))) { + LOG_WARN("fail to choose need restore tablets", K(ret), KPC(ls_)); } else if (tablet_need_restore.empty()) { + bool is_finish = false; ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::WAIT_QUICK_RESTORE); - ObLSRestoreStatus leader_restore_status; - bool all_finish = false; - if (OB_FAIL(request_leader_status_(leader_restore_status))) { - LOG_WARN("fail to request leader tablets and status", K(ret), KPC(ls_)); - } else if (check_leader_restore_finish_(leader_restore_status, ls_restore_status_)) { - if (OB_FAIL(reload_miss_tablet_(all_finish))) { - LOG_WARN("fail to check follower restore tablet all finish", K(ret), KPC(ls_)); - } else if (all_finish) { - bool is_finish = false; - if (OB_FAIL(check_tablet_checkpoint_())) { - LOG_WARN("fail to check tablet clog checkpoint ts", K(ret), KPC(ls_)); - } else if (OB_FAIL(advance_status_(*ls_, next_status))) { - LOG_WARN("fail to advance status", K(ret), KPC(ls_), K(next_status)); - } else { - LOG_INFO("follower quick restore success", KPC(ls_)); - tablet_mgr_.reuse_set(); - } + if (OB_FAIL(check_clog_replay_finish_(is_finish))) { + LOG_WARN("fail to check clog replay finish", K(ret), KPC(ls_)); + } else if (!is_finish) { + if (REACH_TIME_INTERVAL(10 * 1000 * 1000L)) { + LOG_INFO("clog replay not finish, wait later", KPC(ls_)); } + } else if (!tablet_mgr_.is_restore_completed()) { + } else if (OB_FAIL(check_tablet_checkpoint_())) { + LOG_WARN("fail to check tablet clog checkpoint ts", K(ret), KPC(ls_)); + } else if (OB_FAIL(advance_status_(*ls_, next_status))) { + LOG_WARN("fail to advance status", K(ret), KPC(ls_), K(next_status)); + } else { + LOG_INFO("follower quick restore success", KPC(ls_)); } } else if (OB_FAIL(do_quick_restore_(tablet_need_restore))) { - if (OB_EAGAIN == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("fail to do quick restore", K(ret), K(tablet_need_restore), KPC(ls_)); - } + LOG_WARN("fail to do quick restore", K(ret), K(tablet_need_restore), KPC(ls_)); } return ret; } -int ObLSQuickRestoreState::do_quick_restore_(const ObSArray &tablet_need_restore) +int ObLSQuickRestoreState::do_quick_restore_(const ObLSRestoreTaskMgr::ToRestoreTabletGroup &tablet_need_restore) { int ret = OB_SUCCESS; ObCurTraceId::init(GCONF.self_addr_); @@ -2242,16 +2207,31 @@ int ObLSQuickRestoreState::do_quick_restore_(const ObSArray &tablet_ ObTabletGroupRestoreArg arg; bool reach_dag_limit = false; bool is_new_election = false; - if (!is_follower(role_) && OB_FAIL(leader_fill_tablet_group_restore_arg_(tablet_need_restore, ObTabletRestoreAction::ACTION::RESTORE_MINOR, arg))) { - LOG_WARN("fail to fill ls restore arg", K(ret)); - } else if (is_follower(role_) && OB_FAIL(follower_fill_tablet_group_restore_arg_(tablet_need_restore, ObTabletRestoreAction::ACTION::RESTORE_MINOR, arg))) { - LOG_WARN("fail to fill ls restore arg", K(ret)); - } else if (OB_FAIL(check_new_election_(is_new_election))) { + // No matter is leader or follower, always restore data from backup. + if (OB_FAIL(leader_fill_tablet_group_restore_arg_(tablet_need_restore.get_tablet_list(), tablet_need_restore.action(), arg))) { + LOG_WARN("fail to fill leader ls restore arg", K(ret)); + } + +#if 0 + // TODO(wangxiaohui.wxh): let leader restore from backup and follower restore from leader. + if (!is_follower(role_) + || tablet_need_restore.action() == ObTabletRestoreAction::ACTION::RESTORE_TABLET_META) { + if (OB_FAIL(leader_fill_tablet_group_restore_arg_(tablet_need_restore.get_tablet_list(), tablet_need_restore.action(), arg))) { + LOG_WARN("fail to fill leader ls restore arg", K(ret)); + } + } else { + if (OB_FAIL(follower_fill_tablet_group_restore_arg_(tablet_need_restore.get_tablet_list(), tablet_need_restore.action(), arg))) { + LOG_WARN("fail to fill follower ls restore arg", K(ret)); + } + } +#endif + + if (FAILEDx(check_new_election_(is_new_election))) { LOG_WARN("fail to check change role", K(ret)); } else if (is_new_election) { ret = OB_EAGAIN; LOG_WARN("new election, role may changed, retry later", K(ret), KPC(ls_)); - } else if (OB_FAIL(tablet_mgr_.schedule_tablet(task_id, tablet_need_restore, reach_dag_limit))) { + } else if (OB_FAIL(tablet_mgr_.schedule_tablet_group_restore(task_id, tablet_need_restore, reach_dag_limit))) { LOG_WARN("fail to schedule tablet", K(ret), K(tablet_need_restore), KPC(ls_)); } else if (reach_dag_limit) { LOG_INFO("reach restore dag net max limit, wait later"); @@ -2288,7 +2268,7 @@ int ObLSQuickRestoreState::check_tablet_checkpoint_() int ret = OB_SUCCESS; ObTabletHandle tablet_handle; ObLSTabletService *ls_tablet_svr = nullptr; - ObLSTabletIterator iterator(ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US); // restore only needs to see the created tabelts + ObLSTabletIterator iterator(ObMDSGetTabletMode::READ_WITHOUT_CHECK); ObTablet *tablet = nullptr; if (OB_ISNULL(ls_tablet_svr = ls_->get_tablet_svr())) { @@ -2359,7 +2339,6 @@ int ObLSQuickRestoreFinishState::leader_quick_restore_finish_() if (ls_restore_arg_->get_restore_type().is_quick_restore()) { ret = OB_NOT_SUPPORTED; LOG_WARN("quick restore is not supported now", K(ret), KPC(ls_)); - // TODO: report quick restore finish , need the interface to report restore result to rs. } else if (ls_restore_arg_->get_restore_type().is_normal_restore()) { ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::RESTORE_MAJOR_DATA); bool all_finish = false; @@ -2386,7 +2365,6 @@ int ObLSQuickRestoreFinishState::follower_quick_restore_finish_() } else if (ls_restore_arg_->get_restore_type().is_quick_restore()) { ret = OB_NOT_SUPPORTED; LOG_WARN("quick restore is not supported now", K(ret), KPC(ls_)); - // TODO: report quick restore finish , need the interface to report restore result to rs. } else { ObLSRestoreStatus leader_restore_status; ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::RESTORE_MAJOR_DATA); @@ -2432,12 +2410,12 @@ int ObLSRestoreMajorState::leader_restore_major_data_() { int ret = OB_SUCCESS; ObSArray restored_tablets; - ObSArray tablet_need_restore; + ObLSRestoreTaskMgr::ToRestoreTabletGroup tablet_need_restore; LOG_INFO("ready to restore leader major data", K(ls_restore_status_), KPC(ls_)); - if (OB_FAIL(tablet_mgr_.pop_restored_tablets(*ls_, restored_tablets))) { + if (OB_FAIL(tablet_mgr_.remove_restored_tablets(restored_tablets))) { LOG_WARN("fail to pop restored tablets", K(ret), KPC(ls_)); - } else if (OB_FAIL(tablet_mgr_.pop_need_restore_tablets(*ls_, tablet_need_restore))) { - LOG_WARN("fail to pop need restore tablets", K(ret), KPC(ls_)); + } else if (OB_FAIL(tablet_mgr_.choose_tablets_to_restore(tablet_need_restore))) { + LOG_WARN("fail to choose need restore tablets", K(ret), KPC(ls_)); } else if (tablet_need_restore.empty()) { ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::WAIT_RESTORE_MAJOR_DATA); if (!tablet_mgr_.is_restore_completed()) { @@ -2445,7 +2423,6 @@ int ObLSRestoreMajorState::leader_restore_major_data_() LOG_WARN("fail to advance status to WAIT_RESTORE_MAJOR_DATA from RESTORE_MAJOR_DATA", K(ret), KPC(ls_), K(next_status)); } else { LOG_INFO("leader restore major data finish", KPC(ls_)); - tablet_mgr_.reuse_set(); } } else if (OB_FAIL(do_restore_major_(tablet_need_restore))) { LOG_WARN("fail to do restore major", K(ret), K(tablet_need_restore), KPC(ls_)); @@ -2465,41 +2442,28 @@ int ObLSRestoreMajorState::follower_restore_major_data_() { int ret = OB_SUCCESS; ObSArray restored_tablets; - ObSArray tablet_need_restore; + ObLSRestoreTaskMgr::ToRestoreTabletGroup tablet_need_restore; LOG_INFO("ready to restore follower major data", K(ls_restore_status_), KPC(ls_)); - if (OB_FAIL(tablet_mgr_.pop_restored_tablets(*ls_, restored_tablets))) { + if (OB_FAIL(tablet_mgr_.remove_restored_tablets(restored_tablets))) { LOG_WARN("fail to pop restored tablets", K(ret), KPC(ls_)); - } else if (OB_FAIL(tablet_mgr_.pop_need_restore_tablets(*ls_, tablet_need_restore))) { - LOG_WARN("fail to pop need restore tablets", K(ret), KPC(ls_)); + } else if (OB_FAIL(tablet_mgr_.choose_tablets_to_restore(tablet_need_restore))) { + LOG_WARN("fail to choose need restore tablets", K(ret), KPC(ls_)); } else if (tablet_need_restore.empty()) { ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::WAIT_RESTORE_MAJOR_DATA); - ObLSRestoreStatus leader_restore_status; - bool all_finish = false; - if (OB_FAIL(request_leader_status_(leader_restore_status))) { - LOG_WARN("fail to request leader tablets and status", K(ret), KPC(ls_)); - } else if (check_leader_restore_finish_(leader_restore_status, ls_restore_status_)) { - if (OB_FAIL(reload_miss_tablet_(all_finish))) { - LOG_WARN("fail to check follower restore tablet all finish", K(ret), KPC(ls_)); - } else if (all_finish) { - if (OB_FAIL(advance_status_(*ls_, next_status))) { - LOG_WARN("fail to advance status", K(ret), K(next_status), KPC(ls_)); - } else { - LOG_INFO("follower restore major data finish", KPC(ls_)); - tablet_mgr_.reuse_set(); - } - } + if (!tablet_mgr_.is_restore_completed()) { + } else if (OB_FAIL(advance_status_(*ls_, next_status))) { + LOG_WARN("fail to advance status", K(ret), K(next_status), KPC(ls_)); + } else { + LOG_INFO("follower restore major data finish", KPC(ls_)); } } else if (OB_FAIL(do_restore_major_(tablet_need_restore))) { - if (OB_EAGAIN == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("fail to do restore major", K(ret), K(tablet_need_restore), KPC(ls_)); - } + LOG_WARN("fail to do restore major", K(ret), K(tablet_need_restore), KPC(ls_)); } return ret; } -int ObLSRestoreMajorState::do_restore_major_(const ObSArray &tablet_need_restore) +int ObLSRestoreMajorState::do_restore_major_( + const ObLSRestoreTaskMgr::ToRestoreTabletGroup &tablet_need_restore) { int ret = OB_SUCCESS; ObCurTraceId::init(GCONF.self_addr_); @@ -2507,16 +2471,16 @@ int ObLSRestoreMajorState::do_restore_major_(const ObSArray &tablet_ ObTabletGroupRestoreArg arg; bool reach_dag_limit = false; bool is_new_election = false; - if (!is_follower(role_) && OB_FAIL(leader_fill_tablet_group_restore_arg_(tablet_need_restore, ObTabletRestoreAction::ACTION::RESTORE_MAJOR, arg))) { + if (!is_follower(role_) && OB_FAIL(leader_fill_tablet_group_restore_arg_(tablet_need_restore.get_tablet_list(), tablet_need_restore.action(), arg))) { LOG_WARN("fail to fill ls restore arg", K(ret)); - } else if (is_follower(role_) && OB_FAIL(follower_fill_tablet_group_restore_arg_(tablet_need_restore, ObTabletRestoreAction::ACTION::RESTORE_MAJOR, arg))) { + } else if (is_follower(role_) && OB_FAIL(follower_fill_tablet_group_restore_arg_(tablet_need_restore.get_tablet_list(), tablet_need_restore.action(), arg))) { LOG_WARN("fail to fill ls restore arg", K(ret)); } else if (OB_FAIL(check_new_election_(is_new_election))) { LOG_WARN("fail to check change role", K(ret)); } else if (is_new_election) { ret = OB_EAGAIN; LOG_WARN("new election, role may changed, retry later", K(ret), KPC(ls_)); - } else if (OB_FAIL(tablet_mgr_.schedule_tablet(task_id, tablet_need_restore, reach_dag_limit))) { + } else if (OB_FAIL(tablet_mgr_.schedule_tablet_group_restore(task_id, tablet_need_restore, reach_dag_limit))) { LOG_WARN("fail to schedule tablet", K(ret), K(tablet_need_restore), KPC(ls_)); } else if (reach_dag_limit) { LOG_INFO("reach restore dag net max limit, wait later"); @@ -2560,7 +2524,7 @@ int ObLSRestoreFinishState::restore_finish_() //================================ObLSRestoreWaitState======================================= ObLSRestoreWaitState::ObLSRestoreWaitState(const share::ObLSRestoreStatus::Status &status) - : ObILSRestoreState(status) + : ObILSRestoreState(status), has_confirmed_(false) { } @@ -2571,16 +2535,58 @@ ObLSRestoreWaitState::~ObLSRestoreWaitState() int ObLSRestoreWaitState::do_restore() { int ret = OB_SUCCESS; + bool all_finished = true; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); } else if (OB_FAIL(update_role_())) { LOG_WARN("fail to update role and status", K(ret), KPC(this)); + } else if (has_confirmed_) { + } else if (OB_FAIL(check_all_tablets_has_finished_(all_finished))) { + LOG_WARN("fail to check all tablets finished", K(ret), KPC(this)); + } + + if (OB_FAIL(ret)) { + } else if (!all_finished) { + // fatal error + ret = OB_ERR_SYS; + LOG_ERROR("not all tablets finished", K(ret), KPC(this)); } else if (!is_follower(role_) && OB_FAIL(leader_wait_follower_())) { LOG_WARN("fail to do leader restore sys tablet", K(ret), KPC(this)); } else if(is_follower(role_) && OB_FAIL(follower_wait_leader_())) { LOG_WARN("fail to do follower restore sys tablet", K(ret), KPC(this)); } + + return ret; +} + +int ObLSRestoreWaitState::check_can_advance_status_(bool &can) const +{ + int ret = OB_SUCCESS; + can = true; + return ret; +} + +int ObLSRestoreWaitState::check_all_tablets_has_finished_(bool &all_finished) +{ + int ret = OB_SUCCESS; + ObArray unfinished_high_pri_tablets; + ObArray unfinished_tablets; + if (ls_restore_status_.is_wait_restore_sys_tablets()) { + all_finished = true; + } else if (ls_restore_status_.is_wait_restore_consistent_scn()) { + all_finished = true; + } else if (OB_FAIL(tablet_mgr_.reload_get_unfinished_tablets(unfinished_high_pri_tablets, unfinished_tablets))) { + LOG_WARN("fail to get unfinished tablets", K(ret), KPC(this)); + } else if (!unfinished_high_pri_tablets.empty() || !unfinished_tablets.empty()) { + all_finished = false; + LOG_INFO("still have tablets not restored", K(ret), KPC(this), K(unfinished_high_pri_tablets), K(unfinished_tablets)); + } else { + all_finished = true; + } + + has_confirmed_ = true; + return ret; } @@ -2588,12 +2594,16 @@ int ObLSRestoreWaitState::leader_wait_follower_() { int ret = OB_SUCCESS; bool all_finish = false; + bool can_advance = false; ObLSRestoreStatus next_status; if (ls_restore_status_.is_wait_restore_sys_tablets()) { DEBUG_SYNC(BEFORE_WAIT_RESTORE_SYS_TABLETS); next_status = ObLSRestoreStatus::Status::RESTORE_TABLETS_META; } else if (ls_restore_status_.is_wait_restore_tablets_meta()) { DEBUG_SYNC(BEFORE_WAIT_RESTORE_TABLETS_META); + next_status = ObLSRestoreStatus::Status::RESTORE_TO_CONSISTENT_SCN; + } else if (ls_restore_status_.is_wait_restore_consistent_scn()) { + DEBUG_SYNC(BEFORE_WAIT_LS_RESTORE_TO_CONSISTENT_SCN); next_status = ObLSRestoreStatus::Status::QUICK_RESTORE; } else if (ls_restore_status_.is_wait_quick_restore()) { DEBUG_SYNC(BEFORE_WAIT_QUICK_RESTORE); @@ -2606,6 +2616,10 @@ int ObLSRestoreWaitState::leader_wait_follower_() if (OB_FAIL(check_all_follower_restore_finish_(all_finish))) { LOG_WARN("fail to request follower restore meta result", K(ret), KPC(ls_)); } else if (!all_finish) { + } else if (OB_FAIL(check_can_advance_status_(can_advance))) { + LOG_WARN("fail to check can advance status", K(ret), KPC(ls_)); + } else if (!can_advance) { + // do nothing } else if (OB_FAIL(advance_status_(*ls_, next_status))) { LOG_WARN("fail to advance status", K(ret), K(next_status), KPC(ls_)); } @@ -2619,6 +2633,8 @@ int ObLSRestoreWaitState::follower_wait_leader_() if (ls_restore_status_.is_wait_restore_sys_tablets()) { next_status = ObLSRestoreStatus::Status::RESTORE_TABLETS_META; } else if (ls_restore_status_.is_wait_restore_tablets_meta()) { + next_status = ObLSRestoreStatus::Status::RESTORE_TO_CONSISTENT_SCN; + } else if (ls_restore_status_.is_wait_restore_consistent_scn()) { next_status = ObLSRestoreStatus::Status::QUICK_RESTORE; } else if (ls_restore_status_.is_wait_quick_restore()) { next_status = ObLSRestoreStatus::Status::QUICK_RESTORE_FINISH; @@ -2631,7 +2647,12 @@ int ObLSRestoreWaitState::follower_wait_leader_() if (OB_FAIL(request_leader_status_(leader_restore_status))) { LOG_WARN("fail to request leader tablets and status", K(ret), KPC(ls_)); } else if (check_leader_restore_finish_(leader_restore_status, ls_restore_status_)) { - if (OB_FAIL(advance_status_(*ls_, next_status))) { + bool can_advance = false; + if (OB_FAIL(check_can_advance_status_(can_advance))) { + LOG_WARN("fail to check can advance status", K(ret), KPC(ls_)); + } else if (!can_advance) { + // do nothing + } else if (OB_FAIL(advance_status_(*ls_, next_status))) { LOG_WARN("fail to advance status", K(ret), KPC(ls_), K(next_status)); } else { LOG_INFO("follower success advance status", K(next_status), K(leader_restore_status), KPC(ls_)); @@ -2640,6 +2661,31 @@ int ObLSRestoreWaitState::follower_wait_leader_() return ret; } + +//================================ObLSWaitRestoreConsistentScnState======================================= +int ObLSWaitRestoreConsistentScnState::check_can_advance_status_(bool &can) const +{ + int ret = OB_SUCCESS; + share::ObPhysicalRestoreTableOperator restore_table_operator; + const uint64_t tenant_id = ls_->get_tenant_id(); + if (OB_FAIL(restore_table_operator.init(proxy_, tenant_id))) { + LOG_WARN("fail to init restore table operator", K(ret), K(tenant_id)); + } else { + ObLSRestoreStatus next_status(ObLSRestoreStatus::QUICK_RESTORE); + HEAP_VAR(ObPhysicalRestoreJob, job_info) { + if (OB_FAIL(restore_table_operator.get_job_by_tenant_id(tenant_id, job_info))) { + LOG_WARN("fail to get restore job", K(ret), K(tenant_id)); + } else if (share::PhysicalRestoreStatus::PHYSICAL_RESTORE_WAIT_LS != job_info.get_status()) { + can = false; + } else { + can = true; + } + } + } + return ret; +} + + ObLSRestoreResultMgr::ObLSRestoreResultMgr() : mtx_(), result_(OB_SUCCESS), @@ -2679,28 +2725,26 @@ void ObLSRestoreResultMgr::set_result(const int result, const share::ObTaskId &t // 1. result_ is OB_SUCCESS; // 2. result_ is retrieable err, but input result is non retrieable err. lib::ObMutexGuard guard(mtx_); - if (retry_cnt_ >= OB_MAX_RESTORE_RETRY_TIMES) { // avoiding overwrite error code - } else if ((!can_retrieable_err(result) && can_retrieable_err(result_)) - || OB_SUCCESS == result_) { - result_ = result; - trace_id_.set(trace_id); - failed_type_ = failed_type; + if (result == OB_EAGAIN) { + } else { + if (retry_cnt_ >= OB_MAX_RESTORE_RETRY_TIMES) { // avoiding overwrite error code + } else if ((!can_retrieable_err(result) && can_retrieable_err(result_)) + || OB_SUCCESS == result_) { + result_ = result; + trace_id_.set(trace_id); + failed_type_ = failed_type; + } + retry_cnt_++; } - retry_cnt_++; last_err_ts_ = ObTimeUtility::current_time(); } -int ObLSRestoreResultMgr::get_comment_str(ObLSRestoreResultMgr::Comment &comment) const +int ObLSRestoreResultMgr::get_comment_str(const ObLSID &ls_id, const ObAddr &addr, ObHAResultInfo::Comment &comment) const { - int ret = OB_SUCCESS; - const char *type = RestoreFailedType::DATA_RESTORE_FAILED_TYPE == failed_type_ ? OB_STR_DATA : OB_STR_CLOG; - char trace_id[OB_MAX_TRACE_ID_BUFFER_SIZE] = ""; - if (OB_FALSE_IT(trace_id_.to_string(trace_id, OB_MAX_TRACE_ID_BUFFER_SIZE))) { - } else if (OB_FAIL(databuff_printf(comment.ptr(), comment.capacity(), "module: %.*s, result: %d, trace_id: %.*s", - static_cast(STRLEN(type)), type, result_, static_cast(OB_MAX_TRACE_ID_BUFFER_SIZE), trace_id))) { - LOG_WARN("fail to fill comment", K(ret)); - } - return ret; + ObHAResultInfo::FailedType type = RestoreFailedType::DATA_RESTORE_FAILED_TYPE == failed_type_ ? + ObHAResultInfo::RESTORE_DATA : ObHAResultInfo::RESTORE_CLOG; + ObHAResultInfo result_info(type, ls_id, addr, trace_id_, result_); + return result_info.get_comment_str(comment); } bool ObLSRestoreResultMgr::can_retrieable_err(const int err) const diff --git a/src/storage/restore/ob_ls_restore_handler.h b/src/storage/restore/ob_ls_restore_handler.h index 179707725..633093374 100644 --- a/src/storage/restore/ob_ls_restore_handler.h +++ b/src/storage/restore/ob_ls_restore_handler.h @@ -38,7 +38,6 @@ public: CLOG_RESTORE_FAILED_TYPE = 1, MAX_FAILED_TYPE }; - using Comment = common::ObFixedLengthString; const static int64_t OB_MAX_LS_RESTORE_RETRY_TIME_INTERVAL = 10 * 1000 * 1000; // 10s const static int64_t OB_MAX_RESTORE_RETRY_TIMES = 64; public: @@ -49,8 +48,7 @@ public: bool can_retry() const; bool is_met_retry_time_interval(); void set_result(const int result, const share::ObTaskId &trace_id, const RestoreFailedType &failed_type); - int get_comment_str(Comment &comment) const; - + int get_comment_str(const ObLSID &ls_id, const ObAddr &addr, ObHAResultInfo::Comment &comment) const; bool can_retrieable_err(const int err) const; TO_STRING_KV(K_(result), K_(retry_cnt), K_(trace_id), K_(failed_type)); @@ -78,14 +76,15 @@ public: // used by clog restore to record the failed info. int record_clog_failed_info(const share::ObTaskId &trace_id, const share::ObLSID &ls_id, const int &result); + void try_record_one_tablet_to_restore(const common::ObTabletID &tablet_id); + + int get_consistent_scn(share::SCN &consistent_scn); + int handle_execute_over(const share::ObTaskId &task_id, const ObIArray &restore_succeed_tablets, const ObIArray &restore_failed_tablets, const share::ObLSID &ls_id, const int &result); // when follower received rpc, call this int handle_pull_tablet(const ObIArray &tablet_ids, const share::ObLSRestoreStatus &leader_restore_status, const int64_t leader_proposal_id); - static int check_tablet_restore_finish_(const share::ObLSRestoreStatus &ls_restore_status, - const ObTabletMeta &tablet_meta, bool &is_finish); - static int check_tablet_deleted(const ObTabletHandle &tablet_handle, bool &is_deleted); void wakeup(); void stop() { ATOMIC_STORE(&is_stop_, true); } // when remove ls, set this int safe_to_destroy(bool &is_safe); @@ -134,6 +133,15 @@ public: share::ObLSRestoreStatus get_restore_status() const { return ls_restore_status_; } common::ObRole get_role() const { return role_; } ObLSRestoreTaskMgr &get_tablet_mgr() { return tablet_mgr_; } + int check_leader_restore_finish(bool &finish); + storage::ObLS *get_ls() const { return ls_; } + + // Check if log has been recovered to consistent_scn. + virtual int check_recover_to_consistent_scn_finish(bool &is_finish) const { return false; } + + // Check if log has been recovered to restore_scn. + virtual int check_recover_finish(bool &is_finish) const { return false; } + TO_STRING_KV(K_(*ls), K_(ls_restore_status)); protected: int leader_fill_tablet_group_restore_arg_(const ObIArray &tablet_need_restore, @@ -147,22 +155,17 @@ protected: int check_follower_restore_finish(const share::ObLSRestoreStatus &leader_status, const share::ObLSRestoreStatus &follower_status, bool &is_finish); bool check_leader_restore_finish_( - const share::ObLSRestoreStatus &leader_status, const share::ObLSRestoreStatus &follower_status); + const share::ObLSRestoreStatus &leader_status, + const share::ObLSRestoreStatus &follower_status) const; int update_role_(); bool is_switch_to_leader_(const ObRole &new_role); bool is_switch_to_follower_(const ObRole &new_role); - int reload_tablet_(); - int advance_status_(storage::ObLS &ls, const share::ObLSRestoreStatus &next_status); int report_ls_restore_status_(const storage::ObLS &ls, const share::ObLSRestoreStatus &next_status); int request_leader_status_(share::ObLSRestoreStatus &leader_restore_status); int get_leader_(ObStorageHASrcInfo &leader); - - int upload_wait_restore_tablet_(); - int reload_miss_tablet_(bool &all_finish); - int schedule_tablet_group_restore_( const ObTabletGroupRestoreArg &arg, const share::ObTaskId &task_id); @@ -188,6 +191,10 @@ protected: const share::ObLSRestoreStatus &next_status); int check_new_election_(bool &is_changed) const; + int check_replay_to_target_scn_( + const share::SCN &target_scn, + bool &replayed) const; + protected: bool is_inited_; int64_t cluster_id_; @@ -252,20 +259,50 @@ public: private: int leader_create_user_tablet_(); int follower_create_user_tablet_(); - int do_create_user_tablet_(const ObSArray &tablet_need_restore); + int do_create_user_tablet_( + const ObLSRestoreTaskMgr::ToRestoreTabletGroup &tablet_need_restore); DISALLOW_COPY_AND_ASSIGN(ObLSRestoreCreateUserTabletState); }; + +class ObLSRestoreConsistentScnState final : public ObILSRestoreState +{ +public: + ObLSRestoreConsistentScnState(): ObILSRestoreState(ObLSRestoreStatus::Status::RESTORE_TO_CONSISTENT_SCN) {} + virtual ~ObLSRestoreConsistentScnState() {} + virtual int do_restore() override; + + // Check if log has recovered to consistent_scn. + virtual int check_recover_to_consistent_scn_finish(bool &is_finish) const override; + +private: + // Set restore status to EMPTY for those committed tablets whose restore status is FULL, + // but transfer table is not replaced. + int set_empty_for_transfer_tablets_(); + +private: + DISALLOW_COPY_AND_ASSIGN(ObLSRestoreConsistentScnState); +}; + + class ObLSQuickRestoreState final : public ObILSRestoreState { public: ObLSQuickRestoreState(); virtual ~ObLSQuickRestoreState(); virtual int do_restore() override; + + // Check if log has been recovered to consistent_scn. + virtual int check_recover_to_consistent_scn_finish(bool &is_finish) const override { return true; } + + // Check if log has been recovered to restore_scn. + virtual int check_recover_finish(bool &is_finish) const override; + private: int leader_quick_restore_(); int follower_quick_restore_(); - int do_quick_restore_(const ObSArray &tablet_need_restore); + int do_quick_restore_( + const ObLSRestoreTaskMgr::ToRestoreTabletGroup &tablet_need_restore); int check_clog_replay_finish_(bool &is_finish); int check_tablet_checkpoint_(); DISALLOW_COPY_AND_ASSIGN(ObLSQuickRestoreState); @@ -277,6 +314,12 @@ public: ObLSQuickRestoreFinishState(); virtual ~ObLSQuickRestoreFinishState(); virtual int do_restore() override; + + // Check if log has been recovered to consistent_scn. + virtual int check_recover_to_consistent_scn_finish(bool &is_finish) const override { return true; } + + // Check if log has been recovered to restore_scn. + virtual int check_recover_finish(bool &is_finish) const override { return true; } private: int leader_quick_restore_finish_(); int follower_quick_restore_finish_(); @@ -289,10 +332,16 @@ public: ObLSRestoreMajorState(); virtual ~ObLSRestoreMajorState(); virtual int do_restore() override; + // Check if log has been recovered to consistent_scn. + virtual int check_recover_to_consistent_scn_finish(bool &is_finish) const override { return true; } + + // Check if log has been recovered to restore_scn. + virtual int check_recover_finish(bool &is_finish) const override { return true; } private: int leader_restore_major_data_(); int follower_restore_major_data_(); - int do_restore_major_(const ObSArray &tablet_need_restore); + int do_restore_major_( + const ObLSRestoreTaskMgr::ToRestoreTabletGroup &tablet_need_restore); DISALLOW_COPY_AND_ASSIGN(ObLSRestoreMajorState); }; @@ -302,6 +351,11 @@ class ObLSRestoreFinishState final : public ObILSRestoreState ObLSRestoreFinishState(); virtual ~ObLSRestoreFinishState(); virtual int do_restore() override; + // Check if log has been recovered to consistent_scn. + virtual int check_recover_to_consistent_scn_finish(bool &is_finish) const override { return true; } + + // Check if log has been recovered to restore_scn. + virtual int check_recover_finish(bool &is_finish) const override { return true; } private: int restore_finish_(); DISALLOW_COPY_AND_ASSIGN(ObLSRestoreFinishState); @@ -313,9 +367,18 @@ public: ObLSRestoreWaitState(const share::ObLSRestoreStatus::Status &status); virtual ~ObLSRestoreWaitState(); virtual int do_restore() override; + +protected: + virtual int check_can_advance_status_(bool &can) const; + private: + int check_all_tablets_has_finished_(bool &all_finished); int leader_wait_follower_(); int follower_wait_leader_(); + +private: + // Indicate whether has checked all tablets has been restored. + bool has_confirmed_; DISALLOW_COPY_AND_ASSIGN(ObLSRestoreWaitState); }; @@ -339,12 +402,40 @@ private: DISALLOW_COPY_AND_ASSIGN(ObLSRestoreWaitCreateUserTabletState); }; + +class ObLSWaitRestoreConsistentScnState final : public ObLSRestoreWaitState +{ +public: + ObLSWaitRestoreConsistentScnState() + : ObLSRestoreWaitState(ObLSRestoreStatus::Status::WAIT_RESTORE_TO_CONSISTENT_SCN) {} + virtual ~ObLSWaitRestoreConsistentScnState() {} + + // Check if log has been recovered to consistent_scn. + virtual int check_recover_to_consistent_scn_finish(bool &is_finish) const override { return true; } + + // Check if log has been recovered to restore_scn. + virtual int check_recover_finish(bool &is_finish) const override { return false; } + +protected: + int check_can_advance_status_(bool &can) const override; + +private: + DISALLOW_COPY_AND_ASSIGN(ObLSWaitRestoreConsistentScnState); +}; + + class ObLSRestoreWaitQuickRestoreState final : public ObLSRestoreWaitState { public: ObLSRestoreWaitQuickRestoreState() : ObLSRestoreWaitState(share::ObLSRestoreStatus::Status::WAIT_QUICK_RESTORE) {} virtual ~ObLSRestoreWaitQuickRestoreState() {} + + // Check if log has been recovered to consistent_scn. + virtual int check_recover_to_consistent_scn_finish(bool &is_finish) const override { return true; } + + // Check if log has been recovered to restore_scn. + virtual int check_recover_finish(bool &is_finish) const override { return true; } private: DISALLOW_COPY_AND_ASSIGN(ObLSRestoreWaitQuickRestoreState); }; @@ -355,6 +446,12 @@ public: ObLSRestoreWaitRestoreMajorDataState() : ObLSRestoreWaitState(share::ObLSRestoreStatus::Status::WAIT_RESTORE_MAJOR_DATA) {} virtual ~ObLSRestoreWaitRestoreMajorDataState() {} + + // Check if log has been recovered to consistent_scn. + virtual int check_recover_to_consistent_scn_finish(bool &is_finish) const override { return true; } + + // Check if log has been recovered to restore_scn. + virtual int check_recover_finish(bool &is_finish) const override { return true; } private: DISALLOW_COPY_AND_ASSIGN(ObLSRestoreWaitRestoreMajorDataState); }; diff --git a/src/storage/restore/ob_ls_restore_task_mgr.cpp b/src/storage/restore/ob_ls_restore_task_mgr.cpp index 3d2993c3b..ec62dd2e4 100644 --- a/src/storage/restore/ob_ls_restore_task_mgr.cpp +++ b/src/storage/restore/ob_ls_restore_task_mgr.cpp @@ -14,7 +14,9 @@ #include "ob_ls_restore_task_mgr.h" #include "storage/ls/ob_ls.h" #include "lib/lock/ob_mutex.h" +#include "lib/atomic/ob_atomic.h" #include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_iterator.h" using namespace oceanbase; using namespace share; @@ -23,12 +25,32 @@ using namespace storage; using namespace backup; using namespace logservice; +int ObLSRestoreTaskMgr::ToRestoreTabletGroup::assign(const ToRestoreTabletGroup &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(tablet_list_.assign(other.tablet_list_))) { + LOG_WARN("fail to assign tablet list", K(ret)); + } else { + action_ = other.action_; + from_q_type_ = other.from_q_type_; + need_redo_failed_tablets_ = other.need_redo_failed_tablets_; + task_type_ = other.task_type_; + } + return ret; +} + + ObLSRestoreTaskMgr::ObLSRestoreTaskMgr() : is_inited_(false), mtx_(ObLatchIds::RESTORE_LOCK), tablet_map_(), schedule_tablet_set_(), - wait_tablet_set_() + wait_tablet_set_(), + high_pri_wait_tablet_set_(), + restore_state_handler_(nullptr), + force_reload_(false), + final_reload_(false), + has_checked_leader_done_(false) { } @@ -36,7 +58,7 @@ ObLSRestoreTaskMgr::~ObLSRestoreTaskMgr() { } -int ObLSRestoreTaskMgr::init() +int ObLSRestoreTaskMgr::init(ObILSRestoreState *state_handler, const share::ObLSID &ls_id) { int ret = OB_SUCCESS; ObMemAttr attr(MTL_ID(), "RestoreTaskMgr"); @@ -49,181 +71,313 @@ int ObLSRestoreTaskMgr::init() LOG_WARN("fail to create schedule_tablet_set_", K(ret)); } else if (OB_FAIL(wait_tablet_set_.create(OB_LS_RESTORE_MAX_TABLET_NUM, attr))) { LOG_WARN("fail to create wait_tablet_set_", K(ret)); + } else if (OB_FAIL(high_pri_wait_tablet_set_.create(OB_LS_RESTORE_MAX_TABLET_NUM, attr))) { + LOG_WARN("fail to create high_pri_wait_tablet_set_", K(ret)); } else { + restore_state_handler_ = state_handler; + ls_id_ = ls_id; is_inited_ = true; } if (OB_FAIL(ret)) { - int tmp_ret = OB_SUCCESS; - if (tablet_map_.created() && OB_SUCCESS != (tmp_ret = tablet_map_.destroy())) { - LOG_WARN("fail to destroy tablet map", K(tmp_ret)); - } - if (schedule_tablet_set_.created() && OB_SUCCESS != (tmp_ret = schedule_tablet_set_.destroy())) { - LOG_WARN("fail to destroy schedule_tablet_set_", K(tmp_ret)); - } + destroy(); } return ret; } void ObLSRestoreTaskMgr::destroy() { - tablet_map_.destroy(); - wait_tablet_set_.destroy(); - schedule_tablet_set_.destroy(); -} - -int ObLSRestoreTaskMgr::pop_need_restore_tablets( - storage::ObLS &ls, ObIArray &tablet_need_restore) -{ - int ret = OB_SUCCESS; - tablet_need_restore.reset(); - ObArray need_remove_tablet; - lib::ObMutexGuard guard(mtx_); - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (0 == wait_tablet_set_.size()) { - LOG_INFO("no tablet need to schedule, wait later"); - } else { - TabletSet::iterator iter = wait_tablet_set_.begin(); - while (OB_SUCC(ret) && iter != wait_tablet_set_.end()) { - bool is_deleted = false; - bool is_restored = false; - if (OB_FAIL(check_tablet_deleted_or_restored_(ls, iter->first, is_deleted, is_restored))) { - LOG_WARN("failed to check tablet deleted or restored", K(ret)); - } else if (is_deleted || is_restored) { - if (OB_FAIL(need_remove_tablet.push_back(iter->first))) { - LOG_WARN("failed to push back tablet", K(ret)); - } else { - ++iter; - } - } else if (OB_FAIL(tablet_need_restore.push_back(iter->first))) { - LOG_WARN("fail to push backup tablet", K(ret)); - } else if (tablet_need_restore.count() >= OB_LS_RESOTRE_TABLET_DAG_NET_BATCH_NUM) { - break; - } else { - ++iter; - } - } - - if(!need_remove_tablet.empty()) { - ARRAY_FOREACH(need_remove_tablet, i) { - if (OB_FAIL(wait_tablet_set_.erase_refactored(need_remove_tablet.at(i)))) { - LOG_WARN("failed to erase from set", K(ret)); - } - } - LOG_INFO("tablets may be deleted or restored and removed from wait set.", K(ls), K(need_remove_tablet)); - } - if (OB_SUCC(ret)) { - LOG_INFO("succeed pop need restore tablets", K(tablet_need_restore)); - } + if (tablet_map_.created()) { + tablet_map_.destroy(); + } + if (schedule_tablet_set_.created()) { + schedule_tablet_set_.destroy(); + } + if (wait_tablet_set_.created()) { + wait_tablet_set_.destroy(); + } + if (high_pri_wait_tablet_set_.created()) { + high_pri_wait_tablet_set_.destroy(); } - return ret; } - -int ObLSRestoreTaskMgr::pop_restored_tablets(storage::ObLS &ls, ObIArray &tablet_send_to_follower) +int ObLSRestoreTaskMgr::add_tablet_in_wait_set(const ObIArray &tablet_ids) { int ret = OB_SUCCESS; - bool is_exist = false; - tablet_send_to_follower.reset(); - ObArray finish_task; - ObArray tablet_need_redo; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); + } else if (tablet_ids.empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet_ids can't empty", K(ret)); } else { lib::ObMutexGuard guard(mtx_); - TaskMap::iterator iter = tablet_map_.begin(); - for (; OB_SUCC(ret) && iter != tablet_map_.end(); ++iter) { - if (OB_FAIL(check_task_exist_(iter->first, is_exist))) { + int tmp_ret = OB_SUCCESS; + ARRAY_FOREACH_NORET(tablet_ids, i) { + const ObTabletID &tablet_id = tablet_ids.at(i); + if (OB_TMP_FAIL(wait_tablet_set_.set_refactored(tablet_id))) { + LOG_WARN("fail to insert tablet id into wait tablet set", K(tmp_ret), K_(ls_id), K(tablet_id)); + } + } + + LOG_INFO("add tablet in wait set", K_(ls_id), K(tablet_ids)); + } + return ret; +} + +int ObLSRestoreTaskMgr::record_one_tablet_to_restore(const common::ObTabletID& tablet_id) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(high_pri_wait_tablet_set_.set_refactored(tablet_id))) { + // EMPTY tablets with transfer table should be restored as soon as possible. + set_force_reload(); + LOG_WARN("fail to add high pri tablet, set force reload", K(ret), K_(ls_id), K(tablet_id)); + } else { + LOG_INFO("record one high pri tablet", K_(ls_id), K(tablet_id)); + } + return ret; +} + +int ObLSRestoreTaskMgr::choose_tablets_to_restore( + ObLSRestoreTaskMgr::ToRestoreTabletGroup &tablet_group) +{ + int ret = OB_SUCCESS; + bool reload = false; + ObLS *ls = nullptr; + ObLSRestoreStatus ls_restore_status = restore_state_handler_->get_restore_status(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(ls = restore_state_handler_->get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret)); + } else if (OB_FAIL(check_need_reload_tablets_(reload))) { + LOG_WARN("failed to check need reload tablets", K(ret)); + } else if (!reload) { + } else if (OB_FAIL(reload_tablets_())) { + LOG_WARN("failed to reload tablets", K(ret)); + } + + if (OB_FAIL(ret)) { + } else if (ls_restore_status.is_quick_restore()) { + // During QUICK_RESTORE, EMPTY tablets with transfer table need to be restored first. + if (OB_FAIL(choose_tablets_from_high_pri_tablet_set_(*ls, tablet_group))) { + LOG_WARN("failed to choose tablets from high pri tablet set", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (!tablet_group.empty()) { + } else if (OB_FAIL(choose_tablets_from_wait_set_(*ls, tablet_group))) { + LOG_WARN("failed to choose tablets from wait set", K(ret)); + } + return ret; +} + +int ObLSRestoreTaskMgr::remove_restored_tablets(ObIArray &restored_tablets) +{ + int ret = OB_SUCCESS; + restored_tablets.reset(); + + ObLS *ls = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(ls = restore_state_handler_->get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret)); + } else { + ObArray finish_task; + ObArray high_pri_tablet_need_redo; + ObArray wait_tablet_need_redo; + bool is_task_doing = false; + lib::ObMutexGuard guard(mtx_); + FOREACH_X(iter, tablet_map_, OB_SUCC(ret)) { + if (OB_FAIL(check_task_exist_(iter->first, is_task_doing))) { LOG_WARN("fail to check task exist", K(ret), "taks_id", iter->first); - } else if (is_exist) { - LOG_INFO("task exist, wait later", "taks_id", iter->first); + } else if (is_task_doing) { + LOG_INFO("task is still doing, wait later", "task_id", iter->first); } else if (OB_FAIL(finish_task.push_back(iter->first))) { - LOG_WARN("fail to push back task id", K(ret)); + LOG_WARN("fail to push back finished task id", K(ret)); } else { - ObIArray &tablet_id_array = iter->second; - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_id_array.count(); ++i) { - const ObTabletID &tablet_id = tablet_id_array.at(i); - bool is_restored = false; - bool is_deleted = false; - if (OB_FAIL(check_tablet_deleted_or_restored_(ls, tablet_id, is_deleted, is_restored))) { - LOG_WARN("fail to check tabelt restored", K(ret), K(ls), K(tablet_id)); - } else if (is_deleted) {// if tablet is deleted, it is no need to send it to follower to restore. - } else if (is_restored) { - // if tablet is restored by leader, then it will be send to follower to restore. - if (OB_FAIL(tablet_send_to_follower.push_back(tablet_id))) { - LOG_WARN("fail to push tablet id to tablet send to follower", K(ret), K(tablet_id)); - } - } else if (OB_FAIL(tablet_need_redo.push_back(tablet_id))) { - LOG_WARN("fail to push tablet id to tablet_need_redo", K(ret), K(tablet_id)); - } + const ToRestoreTabletGroup &restored_tg = iter->second; + LOG_INFO("task is finished", "task_id", iter->first, K_(ls_id), K(restored_tg), KP(&high_pri_wait_tablet_set_), KP(&wait_tablet_set_)); + if (!restored_tg.is_tablet_group_task()) { + } else if (OB_FAIL(handle_task_finish_(ls, restored_tg, restored_tablets, high_pri_tablet_need_redo, wait_tablet_need_redo))) { + LOG_WARN("fail to handle finish task", K(ret), "task_id", iter->first); } } } - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_need_redo.count(); ++i) { - const ObTabletID &tablet_id = tablet_need_redo.at(i); - if (OB_FAIL(wait_tablet_set_.set_refactored(tablet_id))) { - if (OB_HASH_EXIST == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("fail to insert tabelt id", K(ret)); - } - } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(schedule_tablet_set_.erase_refactored(tablet_id))) { - if (OB_HASH_NOT_EXIST == ret) { - ret = OB_SUCCESS; - LOG_WARN("tablet not exist, no need to erase", K(ret)); - } else { - LOG_WARN("fail to erase tablet id", K(ret)); - } - } - } - - for (int64_t i = 0; OB_SUCC(ret) && i < finish_task.count(); ++i) { - const ObTaskId &task_id = finish_task.at(i); - if (OB_FAIL(tablet_map_.erase_refactored(task_id))) { - if (OB_HASH_NOT_EXIST == ret) { - ret = OB_SUCCESS; - LOG_WARN("task id not exist, no need to erase", K(ret)); - } else { - LOG_WARN("fail to erase task id", K(ret)); - } - } - } - if (OB_SUCC(ret)) { - LOG_INFO("succeed pop restored tablets", K(ret), K(tablet_need_redo), K(tablet_send_to_follower)); + if (FAILEDx(redo_failed_tablets_(high_pri_tablet_need_redo, wait_tablet_need_redo))) { + LOG_WARN("failed to redo failed tablets", K(ret), K(task_id)); + } else { + remove_finished_task_(finish_task); + LOG_INFO("succeed remove restored tablets", K_(ls_id), K(high_pri_tablet_need_redo), K(wait_tablet_need_redo), K(restored_tablets)); } } return ret; } -int ObLSRestoreTaskMgr::schedule_tablet(const ObTaskId &task_id, const ObSArray &tablet_need_restore, bool &reach_dag_limit) +int ObLSRestoreTaskMgr::reload_get_unfinished_tablets( + ObIArray &unfinished_high_pri_tablets, + ObIArray &unfinished_tablets) const { int ret = OB_SUCCESS; - reach_dag_limit = false; + ObLSTabletService *ls_tablet_svr = nullptr; + ObLS *ls = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(ls = restore_state_handler_->get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret)); + } else if (OB_ISNULL(ls_tablet_svr = ls->get_tablet_svr())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_tablet_svr is nullptr", K(ret)); + } else { + ObLSRestoreStatus ls_restore_status = restore_state_handler_->get_restore_status(); + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObLSTabletIterator iterator(ObMDSGetTabletMode::READ_WITHOUT_CHECK); + if (OB_FAIL(ls_tablet_svr->build_tablet_iter(iterator))) { + LOG_WARN("fail to build tablet iterator", K(ret), KPC(ls)); + } + + while (OB_SUCC(ret)) { + if (OB_FAIL(iterator.get_next_tablet(tablet_handle))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get next tablet", K(ret)); + } + break; + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is nullptr", K(ret), K(tablet_handle)); + } else { + const ObTabletMeta &tablet_meta = tablet->get_tablet_meta(); + const ObTabletID &tablet_id = tablet_meta.tablet_id_; + bool is_restored = false; + if (tablet_id.is_ls_inner_tablet()) { + // do nothing + } else if (tablet->is_empty_shell()) { + // do nothing + } else if (OB_FAIL(is_tablet_restore_finish_(ls_restore_status, tablet_handle, is_restored))) { + LOG_WARN("failed to check tablet restore finish", K(ret), K(ls_restore_status), K(tablet_meta)); + } else if (is_restored) { + } else if (tablet_meta.has_transfer_table()) { + if (OB_FAIL(unfinished_high_pri_tablets.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet", K(ret)); + } else { + LOG_INFO("find an unfinished tablet with transfer table", K(tablet)); + } + } else if (OB_FAIL(unfinished_tablets.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet", K(ret)); + } else { + LOG_INFO("find an unfinished tablet", KPC(tablet)); + } + } + } + } + + return ret; +} + +int ObLSRestoreTaskMgr::schedule_ls_restore( + const share::ObTaskId &task_id) +{ + int ret = OB_SUCCESS; + ToRestoreTabletGroup ls_restore_task; + bool is_exist = false; lib::ObMutexGuard guard(mtx_); if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); } else if (task_id.is_invalid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(task_id), K(tablet_need_restore)); - } else if (tablet_map_.size() >= OB_RESTORE_MAX_DAG_NET_NUM) { + LOG_WARN("invalid task id", K(ret), K(task_id)); + } else if (OB_FAIL(check_task_exist_(task_id, is_exist))) { + LOG_WARN("fail to check task exist", K(ret), K(task_id)); + } else if (is_exist) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task id exist", K(ret), K(task_id)); + } else if (OB_FALSE_IT(ls_restore_task.from_q_type_ = ToRestoreFromQType::FROM_NONE)) { + } else if (OB_FALSE_IT(ls_restore_task.task_type_ = TaskType::LS_RESTORE_TASK)) { + } else if (OB_FAIL(tablet_map_.set_refactored(task_id, ls_restore_task))) { + LOG_WARN("fail to set task id map", K(ret), K(task_id)); + } + + return ret; +} + +int ObLSRestoreTaskMgr::schedule_tablet_group_restore( + const share::ObTaskId &task_id, + const ToRestoreTabletGroup &to_restore_tg, + bool &reach_dag_limit) +{ + int ret = OB_SUCCESS; + reach_dag_limit = false; + bool is_exist = false; + lib::ObMutexGuard guard(mtx_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (task_id.is_invalid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid task id", K(ret), K(task_id)); + } else if (!to_restore_tg.is_tablet_group_task() || to_restore_tg.empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("to_restore_tg is invalid", K(ret), K(task_id), K(to_restore_tg)); + } else if (OB_FAIL(check_task_exist_(task_id, is_exist))) { + LOG_WARN("fail to check task exist", K(ret), K(task_id)); + } else if (is_exist) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task id exist", K(ret), K(task_id), K(to_restore_tg)); + } else if (OB_RESTORE_MAX_DAG_NET_NUM <= tablet_map_.size()) { reach_dag_limit = true; LOG_INFO("two many restore dag net, wait later", "dag_net num", tablet_map_.size()); - } else if (OB_FAIL(tablet_map_.set_refactored(task_id, tablet_need_restore))) { - LOG_WARN("fail to set task id map", K(ret), K(task_id), K(tablet_need_restore)); + } else if (OB_FAIL(tablet_map_.set_refactored(task_id, to_restore_tg))) { + LOG_WARN("fail to set task id map", K(ret), K(task_id), K(to_restore_tg)); } else { + // move to DOING set + int64_t succeed_cnt = 0; + const ObSArray &tablet_need_restore = to_restore_tg.get_tablet_list(); for (int64_t i = 0; OB_SUCC(ret) && i < tablet_need_restore.count(); ++i) { const ObTabletID &tablet_id = tablet_need_restore.at(i); - if (OB_FAIL(wait_tablet_set_.erase_refactored(tablet_id))) { - LOG_WARN("fail to erase tablet id", K(ret), K(tablet_id)); - } else if (OB_FAIL(schedule_tablet_set_.set_refactored(tablet_id))) { - LOG_WARN("fail to set tabelt set", K(ret), K(tablet_id)); + if (OB_FAIL(schedule_tablet_set_.set_refactored(tablet_id))) { + LOG_WARN("fail to set into schedule_tablet_set_", K(ret), K(tablet_id), K(succeed_cnt)); + } else { + ++succeed_cnt; + } + } + + if (OB_FAIL(ret)) { + // rollback, remove from DOING set + int tmp_ret = OB_SUCCESS; + for (int64_t i = 0; i < succeed_cnt; ++i) { + const ObTabletID &tablet_id = tablet_need_restore.at(i); + if (OB_TMP_FAIL(schedule_tablet_set_.erase_refactored(tablet_id))) { + LOG_ERROR("fail to remove from schedule_tablet_set_ ", K(tmp_ret), K(tablet_id), K(i), K(succeed_cnt)); + } + } + + // remove from task map + if (OB_TMP_FAIL(tablet_map_.erase_refactored(task_id))) { + LOG_ERROR("fail to remove from task map", K(tmp_ret), K(task_id)); + } + } else { + // remove from TODO set + int tmp_ret = OB_SUCCESS; + TabletSet *todo_set = to_restore_tg.from_q_type() == ToRestoreFromQType::FROM_WAIT_TABLETS_Q ? &wait_tablet_set_ : &high_pri_wait_tablet_set_; + for (int64_t i = 0; i < succeed_cnt; ++i) { + const ObTabletID &tablet_id = tablet_need_restore.at(i); + if (OB_TMP_FAIL(todo_set->erase_refactored(tablet_id))) { + LOG_ERROR("fail to remove from wait_tablet_set_ ", K(tmp_ret), K(tablet_id), K(i), K(succeed_cnt)); + } } } } @@ -243,103 +397,68 @@ int ObLSRestoreTaskMgr::cancel_task() for (; OB_SUCC(ret) && iter != tablet_map_.end(); ++iter) { is_exist = false; if (OB_FAIL(check_task_exist_(iter->first, is_exist))) { - LOG_WARN("fail to check task exist", K(ret), "taks_id", iter->first); + LOG_WARN("fail to check task exist", K(ret), "task_id", iter->first); } else if (is_exist) { ObTenantDagScheduler *scheduler = nullptr; if (OB_ISNULL(scheduler = MTL(ObTenantDagScheduler*))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get ObTenantDagScheduler from MTL", K(ret), KP(scheduler)); } else if (OB_FAIL(scheduler->cancel_dag_net(iter->first))) { - LOG_WARN("failed to check dag net exist", K(ret), K(iter->first)); + LOG_WARN("failed to check dag net exist", K(ret), "task_id", iter->first); } } } int64_t start_ts = ObTimeUtil::current_time(); + iter = tablet_map_.begin(); for (; OB_SUCC(ret) && iter != tablet_map_.end(); ++iter) { is_exist = true; do { if (OB_FAIL(check_task_exist_(iter->first, is_exist))) { - LOG_WARN("fail to check task exist", K(ret), "taks_id", iter->first); + LOG_WARN("fail to check task exist", K(ret), "task_id", iter->first); } else if (is_exist && REACH_TIME_INTERVAL(60 * 1000 * 1000)) { - LOG_WARN_RET(OB_ERR_TOO_MUCH_TIME, "cancel dag next task cost too much time", K(ret), "task_id", iter->first, + ret = OB_EAGAIN; // dag may hold ls lock. return OB_EAGAIN , ls offline can retry in next time. + LOG_WARN("[RESTORE]cancel dag task cost too much time", K(ret), "task_id", iter->first, "cost_time", ObTimeUtil::current_time() - start_ts); } } while (is_exist && OB_SUCC(ret)); } if (OB_SUCC(ret)) { - reuse_set(); - tablet_map_.reuse(); + clear_all(); } } return ret; } -int ObLSRestoreTaskMgr::add_tablet_in_wait_set(const ObIArray &tablet_ids) +void ObLSRestoreTaskMgr::switch_to_leader() { - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (tablet_ids.empty()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tablet_ids can't empty", K(ret)); - } else { - lib::ObMutexGuard guard(mtx_); - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { - const ObTabletID &tablet_id = tablet_ids.at(i); - if (!tablet_id.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid tablet id", K(ret), K(tablet_id)); - } else if (OB_FAIL(schedule_tablet_set_.exist_refactored(tablet_id))) { - if (OB_HASH_NOT_EXIST == ret) { - ret = OB_SUCCESS; - } else if (OB_HASH_EXIST == ret) { - ret = OB_SUCCESS; - continue; - } else { - LOG_WARN("fail to check tablet exist in schedule set", K(ret), K(tablet_id)); - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(wait_tablet_set_.set_refactored(tablet_id))) { - LOG_WARN("fail to insert tablet id into wait tablet set", K(ret), K(tablet_id)); - } - } - if(OB_SUCC(ret)) { - LOG_INFO("success to add tablet in wait set", K(tablet_ids)); - } - } - return ret; + // Reload tablets from local tablet service. + clear_tablets_to_restore(); + set_force_reload(); + final_reload_ = false; + has_checked_leader_done_ = false; + LOG_INFO("handle switch to leader", K_(ls_id)); } -int ObLSRestoreTaskMgr::add_tablet_in_schedule_set(const ObIArray &tablet_ids) +void ObLSRestoreTaskMgr::switch_to_follower() { - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (tablet_ids.empty()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("tablet_ids can't empty", K(ret)); - } else { - lib::ObMutexGuard guard(mtx_); - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { - const ObTabletID &tablet_id = tablet_ids.at(i); - if (!tablet_id.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid tablet id", K(ret), K(tablet_id)); - } else if (OB_FAIL(schedule_tablet_set_.set_refactored(tablet_id))) { - LOG_WARN("fail to insert tablet id into schedule tablet set", K(ret), K(tablet_id)); - } - } - if(OB_SUCC(ret)) { - LOG_INFO("success to add tablet in schedule set", K(tablet_ids)); - } - } - return ret; + // Clear tablets to restore, and prepare to receive tablets from new leader. + clear_tablets_to_restore(); + set_noneed_redo_failed_tablets_(); + final_reload_ = false; + has_checked_leader_done_ = false; + LOG_INFO("handle switch to follower", K_(ls_id)); +} + +void ObLSRestoreTaskMgr::leader_switched() +{ + // Clear tablets to restore, and prepare to receive tablets from new leader. + clear_tablets_to_restore(); + set_noneed_redo_failed_tablets_(); + final_reload_ = false; + has_checked_leader_done_ = false; + LOG_INFO("handle leader switched", K_(ls_id)); } int ObLSRestoreTaskMgr::check_task_exist_( @@ -366,40 +485,719 @@ int ObLSRestoreTaskMgr::check_task_exist_( return ret; } -int ObLSRestoreTaskMgr::check_tablet_deleted_or_restored_(storage::ObLS &ls, const common::ObTabletID &tablet_id, - bool &is_deleted, bool &is_restored) +int ObLSRestoreTaskMgr::check_transfer_start_finish_(const ObTabletHandle &tablet_handle, bool &is_finish) const { - // tablets may be deleted while replaying clog. - // restore task mgr should skip the deleted tablet. int ret = OB_SUCCESS; - is_deleted = false; - is_restored = false; - ObTabletHandle tablet_handle; - ObLSRestoreStatus ls_restore_status; - ObTablet *tablet; - const int64_t timeout_us = ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US; - if (OB_FAIL(ls.get_restore_status(ls_restore_status))) { - LOG_WARN("fail to get ls restore status", K(ret), K(ls)); - } else if (OB_FAIL(ls.get_tablet(tablet_id, tablet_handle, timeout_us))) { - if (OB_TABLET_NOT_EXIST == ret) { - is_deleted = true; + ObTabletCreateDeleteMdsUserData user_data; + ObTablet *tablet = nullptr; + if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet is nullptr", K(ret)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status( + share::SCN::max_scn(), user_data, -1))) { + if (OB_EMPTY_RESULT == ret) { + // No committed user data exist, indicate that transfer start transaction is not finish. ret = OB_SUCCESS; - LOG_INFO("[LS_RESTORE]tablet has been deleted, no need to check is it restored", K(tablet_id), K(ls)); + is_finish = false; } else { - LOG_WARN("fail to get tablet handle", K(ret), K(tablet_id), K(timeout_us)); + LOG_WARN("failed to get user data", K(ret), KPC(tablet)); } - } else if (nullptr == (tablet = tablet_handle.get_obj())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("nullptr tablet", K(ret)); - } else if (OB_FAIL(ObLSRestoreHandler::check_tablet_deleted(tablet_handle, is_deleted))) { - LOG_WARN("failed to check tablet deleted", K(ret), K(tablet_handle)); - } else if (is_deleted) { // do nothing } else { - const ObTabletMeta &tablet_meta = tablet->get_tablet_meta(); - if (OB_FAIL(ObLSRestoreHandler::check_tablet_restore_finish_(ls_restore_status, tablet_meta, is_restored))) { - LOG_WARN("fail to check tablet restore finish", K(ret), K(tablet_meta), K(ls)); + is_finish = true; + } + + return ret; +} + +int ObLSRestoreTaskMgr::check_transfer_start_finish_(const common::ObTabletID &tablet_id, bool &is_finish) const +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObLS *ls = nullptr; + + if (OB_ISNULL(ls = restore_state_handler_->get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret)); + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("fail to get tablet handle", K(ret), K(tablet_id)); + } else if (OB_FAIL(check_transfer_start_finish_(tablet_handle, is_finish))) { + LOG_WARN("fail to check transfer start finish", K(ret), K(tablet_id)); + } + + return ret; +} + +void ObLSRestoreTaskMgr::set_force_reload() +{ + LOG_INFO("set force reload tablets", KPC_(restore_state_handler)); + ATOMIC_STORE(&force_reload_, true); +} + +void ObLSRestoreTaskMgr::clear_tablets_to_restore() +{ + wait_tablet_set_.reuse(); + high_pri_wait_tablet_set_.reuse(); +} + +void ObLSRestoreTaskMgr::clear_all() +{ + wait_tablet_set_.reuse(); + high_pri_wait_tablet_set_.reuse(); + schedule_tablet_set_.reuse(); + tablet_map_.reuse(); +} + +bool ObLSRestoreTaskMgr::is_restore_completed() const +{ + return has_no_tablets_to_restore() && has_no_tablets_restoring() && final_reload_; +} + +int ObLSRestoreTaskMgr::reload_tablets_() +{ + int ret = OB_SUCCESS; + ObLSTabletService *ls_tablet_svr = nullptr; + ObLS *ls = nullptr; + bool is_follower = is_follower_(); + if (OB_ISNULL(ls = restore_state_handler_->get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret)); + } else if (OB_ISNULL(ls_tablet_svr = ls->get_tablet_svr())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_tablet_svr is nullptr", K(ret)); + } else { + ObLSRestoreStatus ls_restore_status = restore_state_handler_->get_restore_status(); + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObLSTabletIterator iterator(ObMDSGetTabletMode::READ_WITHOUT_CHECK); + if (OB_FAIL(ls_tablet_svr->build_tablet_iter(iterator))) { + LOG_WARN("fail to build tablet iterator", K(ret), KPC(ls)); } + + while (OB_SUCC(ret)) { + bool discard = false; + if (OB_FAIL(iterator.get_next_tablet(tablet_handle))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get next tablet", K(ret)); + } + break; + } else if (OB_FAIL(check_tablet_need_discard_when_reload_(tablet_handle, discard))) { + LOG_WARN("fail to check tablet need discard when reload", K(ret), K(tablet_handle)); + } else if (discard) { + LOG_DEBUG("this tablet will discard", K(tablet_handle), K(ls_restore_status)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is nullptr", K(ret), K(tablet_handle)); + } else { + const ObTabletMeta &tablet_meta = tablet->get_tablet_meta(); + const ObTabletID &tablet_id = tablet_meta.tablet_id_; + if (tablet_meta.has_transfer_table()) { + // restore status must be FULL or EMPTY. + // These tablets which have transfer info have higher priority to restore minor. + if (OB_FAIL(schedule_tablet_set_.exist_refactored(tablet_id))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(high_pri_wait_tablet_set_.set_refactored(tablet_id))) { + LOG_WARN("fail to add tablet to high_pri_wait_tablet_set_", K(ret), K(tablet_id), K(ls_restore_status), K(tablet_meta)); + } else { + LOG_INFO("add one tablet to high_pri_wait_tablet_set_", K(tablet_id), K(ls_restore_status)); + } + } else if (OB_HASH_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("tablet is restoring, skip", K(tablet_id), K(ls_restore_status), K(tablet_meta)); + } else { + LOG_WARN("fail to check tablet exist in schedule_tablet_set_", K(ret), K(tablet_id), K(ls_restore_status)); + } + } + } else if (OB_FAIL(schedule_tablet_set_.exist_refactored(tablet_id))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(wait_tablet_set_.set_refactored(tablet_id))) { + LOG_WARN("fail to add tablet to wait_tablet_set_", K(ret), K(tablet_id)); + } else { + LOG_INFO("add one tablet to wait_tablet_set_", K(tablet_id)); + } + } else if (OB_HASH_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("tablet is restoring, skip", K(tablet_id)); + } else { + LOG_WARN("fail to check tablet exist in schedule_tablet_set_", K(ret), K(tablet_id)); + } + } + } + } + } + + if (OB_SUCC(ret)) { + // If no tablets to restore are found, mark 'final_reload_' true. + if (has_no_tablets_to_restore() + && (!is_follower || (is_follower && has_checked_leader_done_))) { + final_reload_ = true; + LOG_INFO("no tablets to restore are found, set final reload", K_(ls_id), K(is_follower)); + } else { + final_reload_ = false; + } + unset_force_reload_(); + } + + LOG_INFO("reload tablets", K(ret), K_(ls_id), K(is_follower), + "wait_tablet_set size", wait_tablet_set_.size(), + "high_pri_wait_tablet_set size", high_pri_wait_tablet_set_.size(), + "schedule_tablet_set size", schedule_tablet_set_.size(), + "task_map size", tablet_map_.size()); + + return ret; +} + + +int ObLSRestoreTaskMgr::check_need_reload_tablets_(bool &reload) +{ + int ret = OB_SUCCESS; + ObLSRestoreStatus ls_restore_status = restore_state_handler_->get_restore_status(); + reload = false; + // Reload tablets is only allowed if restore status is RESTORE_TABLETS_META, QUICK_RESTORE, or RESTORE_MAJOR_DATA + if (!ls_restore_status.is_restore_tablets_meta() + && !ls_restore_status.is_quick_restore() + && !ls_restore_status.is_restore_major_data()) { + LOG_DEBUG("no need reload", K_(ls_id), K(ls_restore_status), "is_follower", is_follower_()); + } else if (ATOMIC_LOAD(&force_reload_)) { + reload = true; + } else if (!has_no_tablets_to_restore() || !has_no_tablets_restoring()) { + } else if (final_reload_) { + LOG_DEBUG("final reload is set, need not reload", K_(ls_id), K(ls_restore_status), "is_follower", is_follower_()); + } else if (is_follower_()) { + // follower can reload tablets only if leader has been restored except at QUICK_RESTORE. + bool finish = true; + if (!ls_restore_status.is_quick_restore() + && OB_FAIL(restore_state_handler_->check_leader_restore_finish(finish))) { + LOG_WARN("fail to check leader restore finish", K(ret), KPC_(restore_state_handler)); + } else if (!finish) { + has_checked_leader_done_ = false; + LOG_DEBUG("wait leader restore finish", K_(ls_id), K(ls_restore_status)); + } else { + has_checked_leader_done_ = true; + reload = true; + LOG_INFO("follower need reload tablets", K_(ls_id), K(ls_restore_status)); + } + } else { + reload = true; + LOG_INFO("leader need reload tablets", K_(ls_id), K(ls_restore_status)); + } + + return ret; +} + +int ObLSRestoreTaskMgr::check_tablet_need_discard_when_reload_( + const ObTabletHandle &tablet_handle, + bool &discard) const +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + discard = false; + if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is nullptr", K(ret)); + } else { + // the following tablets will be discarded during reload. + // 1. inner tablet + // 2. restored tablet + // 3. empty shell tablet + // 4. this is follower, but leader has not been restored + bool is_follower = is_follower_(); + bool is_finish = false; + const ObTabletMeta &tablet_meta = tablet->get_tablet_meta(); + const ObTabletID &tablet_id = tablet_meta.tablet_id_; + const ObLSRestoreStatus ls_restore_status = restore_state_handler_->get_restore_status(); + if (!tablet_meta.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tablet meta", K(ret), K(tablet_meta)); + } else if (tablet_meta.tablet_id_.is_ls_inner_tablet()) { + discard = true; + } else if (tablet->is_empty_shell()) { + discard = true; + LOG_INFO("find a empty shell tablet", K(tablet_id)); + } else if (OB_FAIL(is_tablet_restore_finish_(ls_restore_status, tablet_handle, is_finish))) { + LOG_WARN("failed to check tablet restore finish", K(ret), K(ls_restore_status), K(tablet_handle)); + } else if (is_finish) { + discard = true; + LOG_DEBUG("skip restored tablet", K(tablet_id), K(ls_restore_status), "ha_status", tablet_meta.ha_status_); + } else if (ls_restore_status.is_quick_restore()) { + } else if (is_follower && !has_checked_leader_done_) { + // The follower does not load tablets to restore before leader has been restored. + discard = true; + LOG_DEBUG("skip tablet to restore before leader has been restored.", K(tablet_id), K(ls_restore_status), "ha_status", tablet_meta.ha_status_); + } + } + + return ret; +} + +int ObLSRestoreTaskMgr::check_tablet_is_deleted_( + const ObTabletHandle &tablet_handle, + bool &is_deleted) const +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData data; + + is_deleted = false; + + if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet is null", K(ret)); + } else if (tablet->is_empty_shell()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet is empty shell", K(ret), KPC(tablet)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + if (OB_EMPTY_RESULT == ret) { + LOG_WARN("tablet_status is null", K(ret), KPC(tablet)); + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get latest tablet status", K(ret), KPC(tablet)); + } + } else if (ObTabletStatus::DELETED == data.tablet_status_ + || ObTabletStatus::TRANSFER_OUT_DELETED == data.tablet_status_) { + is_deleted = true; } return ret; } +int ObLSRestoreTaskMgr::check_need_discard_transfer_tablet_( + const ObTabletHandle &tablet_handle, + bool &discard) const +{ + int ret = OB_SUCCESS; + bool is_finish = false; + discard = false; + if (OB_FAIL(check_transfer_start_finish_(tablet_handle, is_finish))) { + if (OB_ERR_SHARED_LOCK_CONFLICT == ret) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(restore_state_handler_->check_recover_finish(is_finish))) { + LOG_WARN("fail to check recover finish", K(ret), K(tmp_ret), KPC_(restore_state_handler), K_(ls_id)); + } else if (!is_finish) { + // overwrite error code if transfer start has stepped into 2-phase transaction before recover finished. + ret = OB_SUCCESS; + } else { + // TODO(wangxiaohui.wxh): cannot let restore failed if restore_scn is between prepare and commit. + } + } else { + LOG_WARN("fail to check transfer start finish", K(ret), K_(ls_id), K(tablet_handle)); + } + } else if (!is_finish && OB_FAIL(check_need_discard_uncommit_transfer_tablet_(discard))) { + LOG_WARN("fail to check need discard uncommit transfer tablet", K(ret)); + } + return ret; +} + +int ObLSRestoreTaskMgr::check_need_discard_uncommit_transfer_tablet_( + bool &discard) const +{ + int ret = OB_SUCCESS; + bool is_finish = false; + discard = false; + if (OB_FAIL(restore_state_handler_->check_recover_finish(is_finish))) { + LOG_WARN("fail to check recover finish", K(ret), KPC_(restore_state_handler), K_(ls_id)); + } else if (is_finish) { + discard = true; + } + return ret; +} + +bool ObLSRestoreTaskMgr::is_follower_() const +{ + return is_follower(restore_state_handler_->get_role()); +} + +int ObLSRestoreTaskMgr::is_tablet_restore_finish_( + const share::ObLSRestoreStatus &ls_restore_status, + const ObTabletHandle &tablet_handle, + bool &is_finish) const +{ + int ret = OB_SUCCESS; + bool discard = false; + const ObTabletMeta &tablet_meta = tablet_handle.get_obj()->get_tablet_meta(); + const ObTabletHAStatus &ha_status = tablet_meta.ha_status_; + + is_finish = true; + switch (ls_restore_status.get_status()) { + case ObLSRestoreStatus::RESTORE_TABLETS_META : + case ObLSRestoreStatus::WAIT_RESTORE_TABLETS_META : { + is_finish = !ha_status.is_restore_status_pending(); + break; + } + + case ObLSRestoreStatus::RESTORE_TO_CONSISTENT_SCN : + case ObLSRestoreStatus::WAIT_RESTORE_TO_CONSISTENT_SCN : { + is_finish = !(ha_status.is_restore_status_full() && tablet_meta.has_transfer_table()); + break; + } + + case ObLSRestoreStatus::QUICK_RESTORE: + case ObLSRestoreStatus::WAIT_QUICK_RESTORE: + case ObLSRestoreStatus::QUICK_RESTORE_FINISH: { + is_finish = ha_status.is_restore_status_minor_and_major_meta() + || ha_status.is_restore_status_undefined(); + + if (!ha_status.is_restore_status_full()) { + } else if (!tablet_meta.has_transfer_table()) { + is_finish = true; + } else if (OB_FAIL(check_need_discard_transfer_tablet_(tablet_handle, discard))) { + LOG_WARN("failed to check tablet need discard", K(ret), K_(ls_id), K(tablet_meta)); + } else if (discard) { + // uncommitted tablet created by transfer, but log has been recovered. + is_finish = true; + } else { + // FULL tablet with transfer table, need wait the table be replaced. + is_finish = false; + } + break; + } + + case ObLSRestoreStatus::RESTORE_MAJOR_DATA : + case ObLSRestoreStatus::WAIT_RESTORE_MAJOR_DATA : { + is_finish = ha_status.is_restore_status_full() + || ha_status.is_restore_status_undefined(); + + if (!is_finish) { + // If tablet is deleted, major is no need to be restored. + bool is_deleted = true; + if (OB_FAIL(check_tablet_is_deleted_(tablet_handle, is_deleted))) { + LOG_WARN("failed to check tablet is deleted", K(ret), K_(ls_id), K(tablet_meta)); + } else if (is_deleted) { + is_finish = true; + LOG_INFO("ignore deleted tablet during restore major", K_(ls_id), K(tablet_meta)); + } + } + break; + } + + default: { + is_finish = true; + break; + } + } + + return ret; +} + +int ObLSRestoreTaskMgr::choose_tablets_from_wait_set_( + storage::ObLS &ls, + ObLSRestoreTaskMgr::ToRestoreTabletGroup &tablet_group) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(mtx_); + bool is_exist = false; + bool is_restored = false; + bool is_restoring = false; + ObTabletRestoreStatus::STATUS restore_status = ObTabletRestoreStatus::RESTORE_STATUS_MAX; + ObArray need_remove_tablet; + ObLSRestoreStatus ls_restore_status = restore_state_handler_->get_restore_status(); + tablet_group.action_ = get_common_restore_action_(ls_restore_status); + tablet_group.from_q_type_ = ToRestoreFromQType::FROM_WAIT_TABLETS_Q; + tablet_group.task_type_ = TaskType::TABLET_GROUP_RESTORE_TASK; + FOREACH_X(iter, wait_tablet_set_, OB_SUCC(ret)) { + const ObTabletID &tablet_id = iter->first; + if (OB_FAIL(check_tablet_is_restoring_(tablet_id, is_restoring))) { + LOG_WARN("failed to check tablet is restoring", K(ret), K_(ls_id), K(tablet_id)); + } else if (is_restoring) { + LOG_INFO("tablet is restoring, skip it this time", K_(ls_id), K(tablet_id)); + } else if (OB_FAIL(check_tablet_status_(ls, iter->first, is_exist, is_restored, restore_status))) { + LOG_WARN("failed to check tablet status", K(ret), K_(ls_id), K(tablet_id)); + } else if (!is_exist || is_restored || ObTabletRestoreStatus::is_full(restore_status)) { + if (OB_FAIL(need_remove_tablet.push_back(iter->first))) { + LOG_WARN("failed to push back tablet", K(ret)); + } else { + LOG_INFO("remove not exist or restored tablet or full tablet", K(ls), K(tablet_id), K(is_exist), K(is_restored), K(restore_status)); + } + } else if (OB_FAIL(tablet_group.tablet_list_.push_back(iter->first))) { + LOG_WARN("fail to push backup tablet", K(ret)); + } else if (tablet_group.count() >= OB_LS_RESOTRE_TABLET_DAG_NET_BATCH_NUM) { + break; + } + } + + if(!need_remove_tablet.empty()) { + int tmp_ret = OB_SUCCESS; + ARRAY_FOREACH(need_remove_tablet, i) { + if (OB_TMP_FAIL(wait_tablet_set_.erase_refactored(need_remove_tablet.at(i)))) { + LOG_WARN("failed to erase from wait_tablet_set_", K(tmp_ret)); + } + } + } + + if (OB_SUCC(ret) && !tablet_group.empty()) { + LOG_INFO("succeed choose tablets from wait set", K_(ls_id), K(tablet_group), KP(&high_pri_wait_tablet_set_), KP(&wait_tablet_set_)); + } + + return ret; +} + +int ObLSRestoreTaskMgr::choose_tablets_from_high_pri_tablet_set_( + storage::ObLS &ls, + ObLSRestoreTaskMgr::ToRestoreTabletGroup &tablet_group) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(mtx_); + + bool is_exist = false; + bool is_restored = false; + bool is_restoring = false; + ObTabletRestoreStatus::STATUS restore_status = ObTabletRestoreStatus::RESTORE_STATUS_MAX; + ObArray need_remove_tablet; + tablet_group.action_ = ObTabletRestoreAction::RESTORE_MINOR; + tablet_group.from_q_type_ = ToRestoreFromQType::FROM_HIGH_PRI_WAIT_TABLETS_Q; + tablet_group.task_type_ = TaskType::TABLET_GROUP_RESTORE_TASK; + FOREACH_X(iter, high_pri_wait_tablet_set_, OB_SUCC(ret)) { + const ObTabletID &tablet_id = iter->first; + if (OB_FAIL(check_tablet_is_restoring_(tablet_id, is_restoring))) { + LOG_WARN("failed to check tablet is restoring", K(ret), K_(ls_id), K(tablet_id)); + } else if (is_restoring) { + LOG_INFO("tablet is restoring, skip it this time", K_(ls_id), K(tablet_id)); + } else if (OB_FAIL(check_tablet_status_(ls, tablet_id, is_exist, is_restored, restore_status))) { + LOG_WARN("failed to check tablet status", K(ret), K_(ls_id), K(tablet_id)); + } else if (!is_exist || is_restored) { + if (OB_FAIL(need_remove_tablet.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet", K(ret)); + } else { + LOG_INFO("remove not exist or restored tablet", K_(ls_id), K(tablet_id), K(is_exist), K(is_restored), K(restore_status)); + } + } else if (ObTabletRestoreStatus::is_full(restore_status)) { + LOG_INFO("this tablet need wait transfer replace", K_(ls_id), K(tablet_id)); + } else if (OB_FAIL(tablet_group.tablet_list_.push_back(tablet_id))) { + LOG_WARN("fail to push backup tablet", K(ret)); + } else if (tablet_group.count() >= OB_LS_RESOTRE_TABLET_DAG_NET_BATCH_NUM) { + break; + } + } + + if(!need_remove_tablet.empty()) { + int tmp_ret = OB_SUCCESS; + ARRAY_FOREACH(need_remove_tablet, i) { + if (OB_TMP_FAIL(high_pri_wait_tablet_set_.erase_refactored(need_remove_tablet.at(i)))) { + LOG_WARN("failed to erase from high_pri_wait_tablet_set_", K(tmp_ret)); + } + } + } + + if (OB_SUCC(ret) && !tablet_group.empty()) { + LOG_INFO("succeed to choose tablets from high pri tablet set", K_(ls_id), K(tablet_group), KP(&high_pri_wait_tablet_set_), KP(&wait_tablet_set_)); + } + + return ret; +} + +int ObLSRestoreTaskMgr::check_tablet_status_( + storage::ObLS &ls, + const common::ObTabletID &tablet_id, + bool &is_exist, + bool &is_restored, + ObTabletRestoreStatus::STATUS &restore_status) const +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObLSRestoreStatus ls_restore_status = restore_state_handler_->get_restore_status(); + + is_exist = false; + is_restored = false; + + if (OB_FAIL(ls.ha_get_tablet(tablet_id, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + is_exist = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get tablet handle", K(ret), K(tablet_id)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("nullptr tablet", K(ret)); + } else if (OB_FALSE_IT(is_exist = true)) { + } else if (OB_FAIL(tablet->get_restore_status(restore_status))) { + LOG_WARN("failed to get restore status", K(ret), KPC(tablet)); + } else if (OB_FAIL(is_tablet_restore_finish_(ls_restore_status, tablet_handle, is_restored))) { + LOG_WARN("fail to check tablet restore finish", K(ret), K(ls_restore_status), K(tablet_handle)); + } + return ret; +} + +ObTabletRestoreAction::ACTION ObLSRestoreTaskMgr::get_common_restore_action_( + const share::ObLSRestoreStatus &ls_restore_status) const +{ + ObTabletRestoreAction::ACTION action = ObTabletRestoreAction::RESTORE_NONE; + switch (ls_restore_status.get_status()) { + case ObLSRestoreStatus::RESTORE_TABLETS_META : { + action = ObTabletRestoreAction::RESTORE_TABLET_META; + break; + } + + case ObLSRestoreStatus::RESTORE_TO_CONSISTENT_SCN : { + action = ObTabletRestoreAction::RESTORE_TABLET_META; + break; + } + + case ObLSRestoreStatus::QUICK_RESTORE: { + action = ObTabletRestoreAction::RESTORE_MINOR; + break; + } + + case ObLSRestoreStatus::RESTORE_MAJOR_DATA : { + action = ObTabletRestoreAction::RESTORE_MAJOR; + break; + } + + default: { + action = ObTabletRestoreAction::RESTORE_NONE; + break; + } + } + + return action; +} + +void ObLSRestoreTaskMgr::unset_force_reload_() +{ + ATOMIC_STORE(&force_reload_, false); +} + +bool ObLSRestoreTaskMgr::has_no_tablets_to_restore() const +{ + return wait_tablet_set_.empty() && high_pri_wait_tablet_set_.empty(); +} + +bool ObLSRestoreTaskMgr::has_no_tablets_restoring() const +{ + return tablet_map_.empty(); +} + +int ObLSRestoreTaskMgr::check_tablet_is_restoring_( + const common::ObTabletID &tablet_id, + bool &is_restoring) const +{ + int ret = OB_SUCCESS; + if (OB_FAIL(schedule_tablet_set_.exist_refactored(tablet_id))) { + if (OB_HASH_NOT_EXIST == ret) { + is_restoring = false; + ret = OB_SUCCESS; + } else if (OB_HASH_EXIST == ret) { + is_restoring = true; + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to check tablet exist in schedule set", K(ret), K_(ls_id), K(tablet_id)); + } + } + + return ret; +} + +void ObLSRestoreTaskMgr::set_noneed_redo_failed_tablets_() +{ + lib::ObMutexGuard guard(mtx_); + FOREACH(iter, tablet_map_) { + iter->second.need_redo_failed_tablets_ = false; + } +} + +int ObLSRestoreTaskMgr::handle_task_finish_( + ObLS *ls, + const ToRestoreTabletGroup &restored_tg, + ObIArray &restored_tablets, + ObIArray &high_pri_tablet_need_redo, + ObIArray &wait_tablet_need_redo) +{ + int ret = OB_SUCCESS; + bool is_exist = false; + bool is_restored = false; + ObTabletRestoreStatus::STATUS restore_status = ObTabletRestoreStatus::RESTORE_STATUS_MAX; + const ObIArray &tablet_id_array = restored_tg.get_tablet_list(); + // find all finished task, and group all tablet by restored or not. + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_id_array.count(); ++i) { + const ObTabletID &tablet_id = tablet_id_array.at(i); + if (OB_FAIL(check_tablet_status_(*ls, tablet_id, is_exist, is_restored, restore_status))) { + LOG_WARN("fail to check tablet status", K(ret), KPC(ls), K(tablet_id)); + } else if (!is_exist) { + LOG_INFO("this tablet is not exist, may be deleted", K_(ls_id), K(tablet_id)); + } else if (is_restored) { + // if tablet is restored by leader, then it will be send to follower to restore. + if (OB_FAIL(restored_tablets.push_back(tablet_id))) { + LOG_WARN("fail to push tablet id", K(ret), K(tablet_id)); + } + } else if (!restored_tg.need_redo_failed_tablets()) { + final_reload_ = false; + LOG_INFO("skip the failed tablet when need_redo_failed_tablets marked true", K_(ls_id), K(tablet_id)); + } else if (restored_tg.from_q_type() == ToRestoreFromQType::FROM_HIGH_PRI_WAIT_TABLETS_Q) { + if (OB_FAIL(high_pri_tablet_need_redo.push_back(tablet_id))) { + LOG_WARN("fail to push back tablet to high_pri_tablet_need_redo", K(ret)); + } else { + LOG_INFO("this tablet need redo", K_(ls_id), K(tablet_id), K(restore_status)); + } + } else if (OB_FAIL(wait_tablet_need_redo.push_back(tablet_id))) { + LOG_WARN("fail to push tablet id to wait_tablet_need_redo", K(ret)); + } else { + LOG_INFO("this tablet need redo", K_(ls_id), K(tablet_id), K(restore_status)); + } + } + + return ret; +} + +int ObLSRestoreTaskMgr::redo_failed_tablets_( + ObIArray &high_pri_tablet_need_redo, + ObIArray &wait_tablet_need_redo) +{ + int ret = OB_SUCCESS; + // add redo tablets back to todo set. + ARRAY_FOREACH(high_pri_tablet_need_redo, i) { + const ObTabletID &tablet_id = high_pri_tablet_need_redo.at(i); + if (OB_FAIL(high_pri_wait_tablet_set_.set_refactored(tablet_id))) { + if (OB_HASH_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to insert tablet id to high_pri_wait_tablet_set_", K(ret)); + } + } + } + + ARRAY_FOREACH(wait_tablet_need_redo, i) { + const ObTabletID &tablet_id = wait_tablet_need_redo.at(i); + if (OB_FAIL(wait_tablet_set_.set_refactored(tablet_id))) { + if (OB_HASH_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to insert tablet id to wait_tablet_set_", K(ret)); + } + } + } + + return ret; +} + +void ObLSRestoreTaskMgr::remove_finished_task_(const ObIArray &finish_task) +{ + int ret = OB_SUCCESS; + ARRAY_FOREACH_NORET(finish_task, i) { + const ObTaskId &task_id = finish_task.at(i); + const ToRestoreTabletGroup *restored_tg = nullptr; + if (OB_ISNULL(restored_tg = tablet_map_.get(task_id))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task id not exist", K(ret), K(task_id)); + } else if (!restored_tg->is_tablet_group_task()) { + } else { + const ObIArray &tablet_id_array = restored_tg->get_tablet_list(); + ARRAY_FOREACH_NORET(tablet_id_array, i) { + const ObTabletID &tablet_id = tablet_id_array.at(i); + // remove from DOING set + if (OB_FAIL(schedule_tablet_set_.erase_refactored(tablet_id))) { + LOG_WARN("fail to erase tablet id", K(ret), K(tablet_id)); + } + } + } + + // remove from task map + if (OB_FAIL(tablet_map_.erase_refactored(task_id))) { + LOG_WARN("fail to erase task id", K(ret), K(task_id)); + } + } + + if (tablet_map_.empty()) { + schedule_tablet_set_.reuse(); + } +} diff --git a/src/storage/restore/ob_ls_restore_task_mgr.h b/src/storage/restore/ob_ls_restore_task_mgr.h index 7aa19e94d..4e63aef89 100644 --- a/src/storage/restore/ob_ls_restore_task_mgr.h +++ b/src/storage/restore/ob_ls_restore_task_mgr.h @@ -14,52 +14,221 @@ #define OCEABASE_STORAGE_LS_RESTORE_TASK_MGR_H #include "ob_ls_restore_args.h" #include "share/restore/ob_ls_restore_status.h" +#include "storage/high_availability/ob_storage_restore_struct.h" namespace oceanbase { namespace storage { -class ObLSRestoreTaskMgr +class ObILSRestoreState; +class ObLSRestoreTaskMgr final { public: static const int64_t OB_RESTORE_MAX_DAG_NET_NUM = 5; static const int64_t OB_LS_RESTORE_MAX_TABLET_NUM = 10000; static const int64_t OB_LS_RESOTRE_TABLET_DAG_NET_BATCH_NUM = 1024; - using TaskMap = common::hash::ObHashMap, common::hash::NoPthreadDefendMode>; + // There are 2 kinds of types during restore. One is log stream restore + // task at phase RESTORE_SYS_TABLETS, which does not have any tablets in + // ToRestoreTabletGroup. The other is tablet group restore task at phase + // RESTORE_TABLETS_META, RESTORE_TO_CONSISTENT_SCN, QUICK_RESTORE, + // or RESTORE_MAJOR_DATA. + enum TaskType + { + TABLET_GROUP_RESTORE_TASK = 0, + LS_RESTORE_TASK + }; + + enum ToRestoreFromQType + { + FROM_WAIT_TABLETS_Q = 0, // from wait_tablet_set_ + FROM_HIGH_PRI_WAIT_TABLETS_Q, // from high_pri_wait_tablet_set_ + FROM_NONE, // use for ls restore + }; + + // To restore tablet group returned by 'choose_tablets_to_restore'. + class ToRestoreTabletGroup final + { + friend class ObLSRestoreTaskMgr; + + public: + ToRestoreTabletGroup() : + tablet_list_(), + action_(ObTabletRestoreAction::MAX), + from_q_type_(ToRestoreFromQType::FROM_NONE), + need_redo_failed_tablets_(true), + task_type_(TaskType::TABLET_GROUP_RESTORE_TASK) {} + const ObSArray &get_tablet_list() const { return tablet_list_; } + ObTabletRestoreAction::ACTION action() const { return action_; } + ToRestoreFromQType from_q_type() const { return from_q_type_; } + bool empty() const { return tablet_list_.empty(); } + int64_t count() const { return tablet_list_.count(); } + bool need_redo_failed_tablets() const { return need_redo_failed_tablets_; } + TaskType task_type() const { return task_type_; } + bool is_tablet_group_task() const + { + return TaskType::TABLET_GROUP_RESTORE_TASK == task_type_; + } + + int assign(const ToRestoreTabletGroup &tg); + + TO_STRING_KV(K_(tablet_list), K_(action), K_(from_q_type), K_(need_redo_failed_tablets), K_(task_type)); + + private: + ObSArray tablet_list_; + ObTabletRestoreAction::ACTION action_; + // From wait_tablet_set_ or high_pri_wait_tablet_set_ + ToRestoreFromQType from_q_type_; + // In case of leader switch, the restoring tablets from old leader may + // have not been restored on new leader. Therefore, we discard the failed + // tablets after task finish. + bool need_redo_failed_tablets_; + TaskType task_type_; + }; + + using TaskMap = common::hash::ObHashMap; using TabletSet = common::hash::ObHashSet; public: ObLSRestoreTaskMgr(); ~ObLSRestoreTaskMgr(); - int init(); + int init(ObILSRestoreState *state_handler, const share::ObLSID &ls_id); void destroy(); + // receive restored tablets from leader + int add_tablet_in_wait_set( + const ObIArray &tablet_ids); + // PENDING tablets generated by transfer + int record_one_tablet_to_restore( + const common::ObTabletID& tablet_id); + + // choose some tablets to restore. + // Note: not remove from to do list. + int choose_tablets_to_restore(ToRestoreTabletGroup &tablet_group); + + // schedule the pre choosed tablets to restore. + int schedule_tablet_group_restore( + const share::ObTaskId &task_id, + const ToRestoreTabletGroup &to_restore_tg, + bool &reach_dag_limit); - int add_tablet_in_wait_set(const ObIArray &tablet_ids); - int add_tablet_in_schedule_set(const ObIArray &tablet_ids); + int schedule_ls_restore( + const share::ObTaskId &task_id); - int schedule_tablet(const share::ObTaskId &task_id, const ObSArray &tablet_need_restore, bool &reach_dag_limit); - int pop_need_restore_tablets(storage::ObLS &ls, ObIArray &need_restore_tablets); - int pop_restored_tablets(storage::ObLS &ls, ObIArray &tablet_send_to_follower); + // handle restoring task, check if some task is finish, and returned the restored tablets. + int remove_restored_tablets(ObIArray &restored_tablets); + int reload_get_unfinished_tablets( + ObIArray &unfinished_high_pri_tablets, + ObIArray &unfinished_tablets) const; int cancel_task(); + bool is_restore_completed() const; - void reuse_set() { schedule_tablet_set_.reuse(); wait_tablet_set_.reuse(); } - void reuse_wait_set() { wait_tablet_set_.reuse(); } - bool is_restore_completed() { return 0 == tablet_map_.size() && 0 == wait_tablet_set_.size(); } - bool has_no_task() { return 0 == tablet_map_.size(); } + void set_force_reload(); + void clear_tablets_to_restore(); + void clear_all(); + + bool has_no_tablets_to_restore() const; + bool has_no_tablets_restoring() const; + + // Current ls switch from follower to leader. + void switch_to_leader(); + // Current ls switch from leader to follower. + void switch_to_follower(); + // Leader switched, and current ls is still a follower. + void leader_switched(); private: + int choose_tablets_from_wait_set_(storage::ObLS &ls, ToRestoreTabletGroup &tablet_group); + int choose_tablets_from_high_pri_tablet_set_(storage::ObLS &ls, ToRestoreTabletGroup &tablet_group); int check_task_exist_(const share::ObTaskId &task_id, bool &is_exist); - int check_tablet_deleted_or_restored_(storage::ObLS &ls, const common::ObTabletID &tablet_id, - bool &is_deleted, bool &is_restored); + int check_tablet_status_( + storage::ObLS &ls, + const common::ObTabletID &tablet_id, + bool &is_exist, + bool &is_restored, + ObTabletRestoreStatus::STATUS &restore_status) const; + + int check_transfer_start_finish_(const ObTabletHandle &tablet_handle, bool &is_finish) const; + int check_transfer_start_finish_(const common::ObTabletID &tablet_id, bool &is_finish) const; + int is_tablet_restore_finish_( + const share::ObLSRestoreStatus &ls_restore_status, + const ObTabletHandle &tablet_handle, + bool &is_finish) const; + int check_tablet_is_restoring_(const common::ObTabletID &tablet_id, bool &is_restoring) const; + int check_need_reload_tablets_(bool &reload); + + int check_tablet_need_discard_when_reload_( + const ObTabletHandle &tablet_handle, + bool &discard) const; + + // Discard restore the uncommitted tablet created by transfer in, + // while the log has been recovered. + int check_need_discard_transfer_tablet_( + const ObTabletHandle &tablet_handle, + bool &discard) const; + + // check tablet status is DELETED or TRANSFER_OUT_DELETED. + int check_tablet_is_deleted_( + const ObTabletHandle &tablet_handle, + bool &is_deleted) const; + + // At phase QUICK_RESTORE, for tablets created by transfer, the initial status + // is FULL. Its next status may be EMPTY if source tablet is UNDEFINED. Therefore, + // the transfer table can only be restored from backup, rather than be replaced by + // the table from source tablet. That is to say, for FULL tablet with transfer + // table, there are two ways to replace it with actual table. One is from source tablet, + // the other is from backup. We should ensure which way to use. So, when we find a FULL + // tablet with transfer table during reload, the transfer table is first considered to be + // replaced by table from backup. But can only be schedulered to restore before turn into EMPTY. + + // If the transfer in commit scn is smaller than the specified restore scn, the transfer table of + // the tablet is no need to be replaced during QUICK_RESTORE. + int check_need_discard_uncommit_transfer_tablet_( + bool &discard) const; + bool is_follower_() const; + ObTabletRestoreAction::ACTION get_common_restore_action_( + const share::ObLSRestoreStatus &ls_restore_status) const; + + int reload_tablets_(); + int handle_task_finish_( + ObLS *ls, + const ToRestoreTabletGroup &restored_tg, + ObIArray &restored_tablets, + ObIArray &high_pri_tablet_need_redo, + ObIArray &wait_tablet_need_redo); + + int redo_failed_tablets_( + ObIArray &high_pri_tablet_need_redo, + ObIArray &wait_tablet_need_redo); + void remove_finished_task_(const ObIArray &finish_task); + + void unset_force_reload_(); + void set_noneed_redo_failed_tablets_(); private: bool is_inited_; + share::ObLSID ls_id_; lib::ObMutex mtx_; + // The doing task. TaskMap tablet_map_; + // Tablets that are restoring. TabletSet schedule_tablet_set_; + // Tablets that are to do restore. + // To restore tablets are from local tablet service for leader. However, + // for follower, they are from leader before it has been restored. TabletSet wait_tablet_set_; + // Record these tablets which should restore minor data as soon as possible. + TabletSet high_pri_wait_tablet_set_; + + ObILSRestoreState *restore_state_handler_; + // Force reload tablets before choose tablets to restore. + bool force_reload_; + // 'final_reload_' is marked as True when no tablets to restore are found after reload. Then, + // reload is forbidden while no tablets in wait or doing set. + bool final_reload_; + // Follower can reload tablets only if leader has been restored. This is + // true for restore status of RESTORE_TABLETS_META and RESTORE_MAJOR_DATA. + bool has_checked_leader_done_; DISALLOW_COPY_AND_ASSIGN(ObLSRestoreTaskMgr); }; diff --git a/src/storage/slog/ob_storage_log.cpp b/src/storage/slog/ob_storage_log.cpp index 03455e9d2..09467dc4a 100644 --- a/src/storage/slog/ob_storage_log.cpp +++ b/src/storage/slog/ob_storage_log.cpp @@ -161,8 +161,8 @@ int ObCreateTabletLog::serialize(char *buf, const int64_t buf_len, int64_t &pos) int ObCreateTabletLog::deserialize(const char *buf, const int64_t data_len, int64_t &pos) { - common::ObIAllocator &allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); - return tablet_->deserialize(allocator, buf, data_len, pos); + // abandoned slog, skip deserialization + return OB_SUCCESS; } int64_t ObCreateTabletLog::get_serialize_size() const @@ -210,5 +210,139 @@ DEF_TO_STRING(ObDeleteTabletLog) return pos; } +ObUpdateTabletLog::ObUpdateTabletLog( + const ObLSID &ls_id, + const ObTabletID &tablet_id, + const ObMetaDiskAddr &disk_addr) + : ls_id_(ls_id), + tablet_id_(tablet_id), + disk_addr_(disk_addr) +{ +} + +bool ObUpdateTabletLog::is_valid() const +{ + return ls_id_.is_valid() && tablet_id_.is_valid() && disk_addr_.is_valid(); +} + +OB_SERIALIZE_MEMBER(ObUpdateTabletLog, ls_id_, tablet_id_, disk_addr_); + +DEF_TO_STRING(ObUpdateTabletLog) +{ + int64_t pos = 0; + J_OBJ_START(); + J_KV(K_(ls_id), K_(tablet_id), K_(disk_addr)); + J_OBJ_END(); + return pos; +} + +ObEmptyShellTabletLog::ObEmptyShellTabletLog( + const ObLSID &ls_id, + const ObTabletID &tablet_id, + ObTablet *tablet) + : version_(EMPTY_SHELL_SLOG_VERSION), + ls_id_(ls_id), + tablet_id_(tablet_id), + tablet_(tablet) +{ +} + +int ObEmptyShellTabletLog::serialize( + char *buf, + const int64_t data_len, + int64_t &pos) const +{ + int ret = OB_SUCCESS; + if (OB_FAIL(serialization::encode(buf, data_len, pos, version_))) { + STORAGE_LOG(WARN, "deserialize version_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(ls_id_.serialize(buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize ls_id_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(tablet_id_.serialize(buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize tablet_id_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(tablet_->serialize(buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize tablet failed", K(ret), KP(data_len), K(pos)); + } + + return ret; +} + +int ObEmptyShellTabletLog::deserialize_id( + const char *buf, + const int64_t data_len, + int64_t &pos) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(serialization::decode(buf, data_len, pos, version_))) { + STORAGE_LOG(WARN, "deserialize version_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(ls_id_.deserialize(buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize ls_id_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(tablet_id_.deserialize(buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize tablet_id_ failed", K(ret), KP(data_len), K(pos)); + } + return ret; +} + +int ObEmptyShellTabletLog::deserialize( + const char *buf, + const int64_t data_len, + int64_t &pos) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(serialization::decode(buf, data_len, pos, version_))) { + STORAGE_LOG(WARN, "deserialize version_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(ls_id_.deserialize(buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize ls_id_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(tablet_id_.deserialize(buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize tablet_id_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(tablet_->deserialize(buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize tablet failed", K(ret), KP(data_len), K(pos)); + } + + return ret; +} +int ObEmptyShellTabletLog::deserialize( + ObArenaAllocator &allocator, + const char *buf, + const int64_t data_len, + int64_t &pos) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(serialization::decode(buf, data_len, pos, version_))) { + STORAGE_LOG(WARN, "deserialize version_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(ls_id_.deserialize(buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize ls_id_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(tablet_id_.deserialize(buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize tablet_id_ failed", K(ret), KP(data_len), K(pos)); + } else if (OB_FAIL(tablet_->deserialize(allocator, buf, data_len, pos))) { + STORAGE_LOG(WARN, "deserialize tablet failed", K(ret), KP(data_len), K(pos)); + } + + return ret; +} + +int64_t ObEmptyShellTabletLog::get_serialize_size() const +{ + int64_t size = 0; + size += serialization::encoded_length(version_); + size += ls_id_.get_serialize_size(); + size += tablet_id_.get_serialize_size(); + size += tablet_->get_serialize_size(); + return size; +} + +bool ObEmptyShellTabletLog::is_valid() const +{ + return ls_id_.is_valid() && tablet_id_.is_valid(); +} + +DEF_TO_STRING(ObEmptyShellTabletLog) +{ + int64_t pos = 0; + J_OBJ_START(); + J_KV(K_(ls_id), K_(tablet_id)); + J_OBJ_END(); + return pos; +} + } } diff --git a/src/storage/slog/ob_storage_log.h b/src/storage/slog/ob_storage_log.h index 68453aeed..17d4ec5b2 100644 --- a/src/storage/slog/ob_storage_log.h +++ b/src/storage/slog/ob_storage_log.h @@ -215,6 +215,60 @@ public: common::ObTabletID tablet_id_; }; +struct ObUpdateTabletLog : public ObIBaseStorageLogEntry +{ +public: + ObUpdateTabletLog() = default; + ObUpdateTabletLog( + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id, + const ObMetaDiskAddr &disk_addr); + virtual ~ObUpdateTabletLog() = default; + virtual bool is_valid() const override; + DECLARE_TO_STRING; + OB_UNIS_VERSION_V(1); +public: + share::ObLSID ls_id_; + common::ObTabletID tablet_id_; + ObMetaDiskAddr disk_addr_; +}; + +struct ObEmptyShellTabletLog : public ObIBaseStorageLogEntry +{ +public: + const int64_t EMPTY_SHELL_SLOG_VERSION = 1; +public: + ObEmptyShellTabletLog() = default; + explicit ObEmptyShellTabletLog(const ObLSID &ls_id_, const ObTabletID &tablet_id, ObTablet *tablet); + virtual ~ObEmptyShellTabletLog() {} + virtual bool is_valid() const override; + virtual int serialize( + char* buf, + const int64_t buf_len, + int64_t& pos) const; + virtual int deserialize( + const char* buf, + const int64_t data_len, + int64_t& pos); + int deserialize_id( + const char* buf, + const int64_t data_len, + int64_t& pos); + int deserialize( + ObArenaAllocator &allocator, + const char* buf, + const int64_t data_len, + int64_t& pos); + virtual int64_t get_serialize_size() const; + + DECLARE_TO_STRING; +public: + int64_t version_; + share::ObLSID ls_id_; + common::ObTabletID tablet_id_; + ObTablet *tablet_; +}; + } } diff --git a/src/storage/slog/ob_storage_log_struct.h b/src/storage/slog/ob_storage_log_struct.h index a88b2c9f7..9acaebe31 100644 --- a/src/storage/slog/ob_storage_log_struct.h +++ b/src/storage/slog/ob_storage_log_struct.h @@ -48,10 +48,12 @@ enum class ObRedoLogSubType OB_REDO_LOG_UPDATE_LS = 12, OB_REDO_LOG_DELETE_LS = 13, - OB_REDO_LOG_PUT_TABLET = 14, + OB_REDO_LOG_PUT_OLD_TABLET = 14, // discard from 4.1 OB_REDO_LOG_DELETE_TABLET = 15, + OB_REDO_LOG_UPDATE_TABLET = 16, + OB_REDO_LOG_EMPTY_SHELL_TABLET = 17, - OB_REDO_LOG_UPDATE_DUP_TABLE_LS = 16, + OB_REDO_LOG_UPDATE_DUP_TABLE_LS = 18, OB_REDO_LOG_MAX }; diff --git a/src/storage/slog/ob_storage_log_writer.h b/src/storage/slog/ob_storage_log_writer.h index b5a8e021f..a7d066e5f 100644 --- a/src/storage/slog/ob_storage_log_writer.h +++ b/src/storage/slog/ob_storage_log_writer.h @@ -51,7 +51,6 @@ public: int delete_log_file(const int64_t file_id); int get_using_disk_space(int64_t &using_space) const; - inline int64_t get_pwrite_ts() const { return file_handler_.get_pwrite_ts(); } int start_log(const common::ObLogCursor &start_cursor); diff --git a/src/storage/slog/ob_storage_logger.cpp b/src/storage/slog/ob_storage_logger.cpp index 2ab6d7cf3..b6395c034 100644 --- a/src/storage/slog/ob_storage_logger.cpp +++ b/src/storage/slog/ob_storage_logger.cpp @@ -174,7 +174,7 @@ int ObStorageLogger::start_log(const ObLogCursor &start_cursor) STORAGE_REDO_LOG(WARN, "SLogger has been started", K(ret)); } else if (OB_UNLIKELY(!start_cursor.is_valid())) { ret = OB_INVALID_ARGUMENT; - STORAGE_REDO_LOG(WARN, "invalid arguments", K(ret)); + STORAGE_REDO_LOG(WARN, "invalid arguments", K(ret), K(start_cursor)); } else if (OB_FAIL(log_writer_->start_log(start_cursor))) { STORAGE_REDO_LOG(WARN, "fail to pass the start_cursor to log_writer_", K(ret), K(start_cursor)); } else { diff --git a/src/storage/slog/ob_storage_logger.h b/src/storage/slog/ob_storage_logger.h index 146d225ca..0c3ab7493 100644 --- a/src/storage/slog/ob_storage_logger.h +++ b/src/storage/slog/ob_storage_logger.h @@ -52,11 +52,6 @@ public: int write_log(ObStorageLogParam ¶m); int write_log(ObIArray ¶m_arr); const char *get_dir() { return tnt_slog_dir_; } - - inline int64_t get_pwrite_ts() const - { - return nullptr == log_writer_ ? 0 : log_writer_->get_pwrite_ts(); - } int get_active_cursor(common::ObLogCursor &log_cursor); int remove_useless_log_file(const int64_t end_file_id, const uint64_t tenant_id); diff --git a/src/storage/slog_ckpt/ob_linked_macro_block_reader.cpp b/src/storage/slog_ckpt/ob_linked_macro_block_reader.cpp index 80b1895e3..f22d9b11b 100644 --- a/src/storage/slog_ckpt/ob_linked_macro_block_reader.cpp +++ b/src/storage/slog_ckpt/ob_linked_macro_block_reader.cpp @@ -271,6 +271,9 @@ int ObLinkedMacroBlockItemReader::get_next_item( char *&item_buf, int64_t &item_buf_len, ObMetaDiskAddr &addr) { int ret = OB_SUCCESS; + item_buf = nullptr; + item_buf_len = 0; + addr.reset(); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObLinkedMacroBlockItemReader has not been inited", K(ret)); diff --git a/src/storage/slog_ckpt/ob_linked_macro_block_struct.cpp b/src/storage/slog_ckpt/ob_linked_macro_block_struct.cpp index b0b9928ee..c48928cb6 100644 --- a/src/storage/slog_ckpt/ob_linked_macro_block_struct.cpp +++ b/src/storage/slog_ckpt/ob_linked_macro_block_struct.cpp @@ -98,7 +98,7 @@ ObMetaBlockListHandle::~ObMetaBlockListHandle() reset(); } -int ObMetaBlockListHandle::add_macro_blocks(const ObIArray &block_list, const bool need_switch_handle) +int ObMetaBlockListHandle::add_macro_blocks(const ObIArray &block_list) { int ret = OB_SUCCESS; ObMacroBlocksHandle &new_handle = meta_handles_[1 - cur_handle_pos_]; @@ -108,9 +108,7 @@ int ObMetaBlockListHandle::add_macro_blocks(const ObIArray &block_list, - const bool need_switch_handle); + int add_macro_blocks(const common::ObIArray &block_list); void reset(); int reserve(const int64_t block_count); const common::ObIArray &get_meta_block_list() const; diff --git a/src/storage/slog_ckpt/ob_linked_macro_block_writer.cpp b/src/storage/slog_ckpt/ob_linked_macro_block_writer.cpp index c2a18977d..94f309823 100644 --- a/src/storage/slog_ckpt/ob_linked_macro_block_writer.cpp +++ b/src/storage/slog_ckpt/ob_linked_macro_block_writer.cpp @@ -131,6 +131,15 @@ void ObLinkedMacroBlockWriter::reset() write_ctx_.reset(); handle_.reset(); entry_block_id_.reset(); + io_desc_.reset(); +} + +void ObLinkedMacroBlockWriter::reuse_for_next_round() +{ + is_inited_ = false; + handle_.reset(); + entry_block_id_.reset(); + io_desc_.reset(); } //================== ObLinkedMacroBlockItemWriter ============================= @@ -439,6 +448,18 @@ int ObLinkedMacroBlockItemWriter::close() } void ObLinkedMacroBlockItemWriter::reset() +{ + inner_reset(); + block_writer_.reset(); +} + +void ObLinkedMacroBlockItemWriter::reuse_for_next_round() +{ + inner_reset(); + block_writer_.reuse_for_next_round(); +} + +void ObLinkedMacroBlockItemWriter::inner_reset() { is_inited_ = false; is_closed_ = false; @@ -448,7 +469,6 @@ void ObLinkedMacroBlockItemWriter::reset() pre_block_inflight_items_cnt_ = 0; curr_block_inflight_items_cnt_ = 0; allocator_.reset(); - block_writer_.reset(); item_size_arr_.reset(); item_disk_addr_arr_.reset(); io_buf_ = nullptr; diff --git a/src/storage/slog_ckpt/ob_linked_macro_block_writer.h b/src/storage/slog_ckpt/ob_linked_macro_block_writer.h index 9e44ce633..69e1611ca 100644 --- a/src/storage/slog_ckpt/ob_linked_macro_block_writer.h +++ b/src/storage/slog_ckpt/ob_linked_macro_block_writer.h @@ -42,6 +42,7 @@ public: const blocksstable::MacroBlockId &get_entry_block() const; ObIArray &get_meta_block_list(); void reset(); + void reuse_for_next_round(); private: bool is_inited_; @@ -63,12 +64,14 @@ public: int write_item(const char *item_buf, const int64_t item_buf_len, int64_t *item_idx = nullptr); int close(); void reset(); + void reuse_for_next_round(); int get_entry_block(blocksstable::MacroBlockId &entry_block) const; common::ObIArray &get_meta_block_list(); int64_t get_item_disk_addr(const int64_t item_idx, ObMetaDiskAddr &addr) const; private: + void inner_reset(); int write_block(); int write_item_header(const char *item_buf, const int64_t item_buf_len); int write_item_content(const char *item_buf, const int64_t item_buf_len, int64_t &item_pos); diff --git a/src/storage/slog_ckpt/ob_server_checkpoint_slog_handler.cpp b/src/storage/slog_ckpt/ob_server_checkpoint_slog_handler.cpp index c6bf1b98a..4d61204d7 100644 --- a/src/storage/slog_ckpt/ob_server_checkpoint_slog_handler.cpp +++ b/src/storage/slog_ckpt/ob_server_checkpoint_slog_handler.cpp @@ -15,9 +15,11 @@ #include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" #include "storage/slog_ckpt/ob_server_checkpoint_reader.h" #include "storage/slog_ckpt/ob_server_checkpoint_writer.h" +#include "storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h" #include "storage/ob_super_block_struct.h" #include "observer/ob_server_struct.h" #include "observer/omt/ob_multi_tenant.h" +#include "observer/omt/ob_tenant.h" #include "storage/slog/ob_storage_log_replayer.h" #include "storage/slog/ob_storage_log.h" #include "storage/slog/ob_storage_logger_manager.h" @@ -106,14 +108,17 @@ int ObServerCheckpointSlogHandler::start() LOG_WARN("fail to replay_sever_slog", K(ret)); } else if (OB_FAIL(OB_SERVER_BLOCK_MGR.first_mark_device())) { // mark must after finish replay slog LOG_WARN("fail to first mark device", K(ret)); - } else if(OB_FAIL(enable_replay_clog())) { - LOG_WARN("fail to enable_replay_clog", K(ret)); + } else if (OB_FAIL(try_write_checkpoint_for_compat())) { + LOG_WARN("fail to try write checkpoint for compat", K(ret)); + } else if (OB_FAIL(finish_slog_replay())) { + LOG_ERROR("fail to finish slog replay", KR(ret)); } else if (OB_FAIL(task_timer_.start())) { // start checkpoint task after finsh replay slog LOG_WARN("fail to start task timer", K(ret)); } else { ATOMIC_STORE(&is_started_, true); LOG_INFO("succ to start server checkpoint slog handler"); } + return ret; } @@ -153,7 +158,42 @@ void ObServerCheckpointSlogHandler::destroy() task_timer_.destroy(); } -int ObServerCheckpointSlogHandler::enable_replay_clog() +int ObServerCheckpointSlogHandler::try_write_checkpoint_for_compat() +{ + int ret = OB_SUCCESS; + common::ObArray tenant_metas; + omt::ObMultiTenant *omt = GCTX.omt_; + if (OB_ISNULL(omt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, omt is nullptr", K(ret)); + } else if (OB_FAIL(omt->get_tenant_metas(tenant_metas))) { + LOG_WARN("fail to get tenant metas", K(ret), KP(omt)); + } else { + bool need_svr_ckpt = false; + for (int64_t i = 0; OB_SUCC(ret) && i < tenant_metas.size(); ++i) { + const ObTenantSuperBlock &super_block = tenant_metas.at(i).super_block_; + if (!super_block.is_old_version()) { + // nothing to do. + } else { + MTL_SWITCH(super_block.tenant_id_) { + if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->write_checkpoint(true/*is_force*/))) { + LOG_WARN("fail to write tenant slog checkpoint", K(ret)); + } else { + need_svr_ckpt = true; + } + } + } + } + if (OB_SUCC(ret)) { + if (need_svr_ckpt && OB_FAIL(write_checkpoint(true/*is_force*/))) { + LOG_WARN("fail to write server checkpoint", K(ret)); + } + } + } + return ret; +} + +int ObServerCheckpointSlogHandler::finish_slog_replay() { int ret = OB_SUCCESS; common::ObArray tenant_ids; @@ -168,15 +208,57 @@ int ObServerCheckpointSlogHandler::enable_replay_clog() for (int64_t i = 0; OB_SUCC(ret) && i < tenant_ids.size(); i++) { const uint64_t &tenant_id = tenant_ids.at(i); MTL_SWITCH(tenant_id) { - if (OB_FAIL(MTL(ObLSService*)->enable_replay())) { - LOG_WARN("fail to enable replay clog", K(ret)); + common::ObSharedGuard ls_iter; + ObLS *ls = nullptr; + ObLSTabletService *ls_tablet_svr = nullptr; + if (OB_FAIL(MTL(ObLSService *)->get_ls_iter(ls_iter, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls iter", K(ret)); + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(ls_iter->get_next(ls))) { + if (OB_ITER_END != ret) { + LOG_WARN("fail to get next ls", K(ret)); + } + } else if (nullptr == ls) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret)); + } else if (OB_FAIL(ls->finish_slog_replay())) { + LOG_WARN("finish replay failed", K(ret), KPC(ls)); + } + } + if (OB_ITER_END == ret) { + if (OB_FAIL(MTL(ObLSService*)->gc_ls_after_replay_slog())) { + LOG_WARN("fail to gc ls after replay slog", K(ret)); + } + } } } } - return ret; } +int ObServerCheckpointSlogHandler::enable_replay_clog() +{ + int ret = OB_SUCCESS; + common::ObArray tenant_ids; + omt::ObMultiTenant *omt = GCTX.omt_; + if (OB_ISNULL(omt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, omt is nullptr", K(ret)); + } else if (OB_FAIL(omt->get_mtl_tenant_ids(tenant_ids))) { + LOG_WARN("fail to get_mtl_tenant_ids", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < tenant_ids.size(); i++) { + const uint64_t &tenant_id = tenant_ids.at(i); + MTL_SWITCH(tenant_id) { + if (OB_FAIL(OB_FAIL(MTL(ObLSService*)->enable_replay()))) { + LOG_WARN("fail enable replay clog", K(ret)); + } + } + } + FLOG_INFO("enable replay clog", K(ret)); + return ret; +} int ObServerCheckpointSlogHandler::read_checkpoint(const ObServerSuperBlock &super_block) { @@ -197,7 +279,7 @@ int ObServerCheckpointSlogHandler::set_meta_block_list(ObIArray &m { int ret = OB_SUCCESS; TCWLockGuard guard(lock_); - if (OB_FAIL(server_meta_block_handle_.add_macro_blocks(meta_block_list, true /*switch handle*/))) { + if (OB_FAIL(server_meta_block_handle_.add_macro_blocks(meta_block_list))) { LOG_WARN("fail to add_macro_blocks", K(ret)); } return ret; @@ -227,8 +309,8 @@ int ObServerCheckpointSlogHandler::replay_and_apply_server_slog(const ObLogCurso LOG_WARN("fail to replay_sever_slog", K(ret)); } else if (OB_FAIL(server_slogger_->start_log(replay_finish_point))) { LOG_WARN("fail to start slog", K(ret)); - } else if (OB_FAIL(applay_replay_result())) { - LOG_WARN("fail to applay_replay_result", K(ret)); + } else if (OB_FAIL(apply_replay_result())) { + LOG_WARN("fail to apply_replay_result", K(ret)); } else if (OB_FAIL(tenant_meta_map_for_replay_.clear())) { LOG_WARN("fail to clear tenant_meta_map_for_replay_", K(ret)); } @@ -659,7 +741,7 @@ int ObServerCheckpointSlogHandler::replay_over() int ret = OB_SUCCESS; return ret; } -int ObServerCheckpointSlogHandler::applay_replay_result() +int ObServerCheckpointSlogHandler::apply_replay_result() { int ret = OB_SUCCESS; int64_t tenant_count = tenant_meta_map_for_replay_.size(); diff --git a/src/storage/slog_ckpt/ob_server_checkpoint_slog_handler.h b/src/storage/slog_ckpt/ob_server_checkpoint_slog_handler.h index b8de4bb63..0e70f70f2 100644 --- a/src/storage/slog_ckpt/ob_server_checkpoint_slog_handler.h +++ b/src/storage/slog_ckpt/ob_server_checkpoint_slog_handler.h @@ -26,7 +26,6 @@ namespace storage { struct ObMetaDiskAddr; -class ObTenantStorageCheckpointWriter; class ObRedoModuleReplayParam; @@ -75,12 +74,13 @@ public: int load_all_tenant_metas(); // for obadmin int write_tenant_super_block_slog(const ObTenantSuperBlock &super_block); const TENANT_META_MAP &get_tenant_meta_map() const { return tenant_meta_map_for_replay_; } // for obadmin + static int enable_replay_clog(); private: virtual int parse(const int32_t cmd, const char *buf, const int64_t len, FILE *stream) override; - int enable_replay_clog(); + int try_write_checkpoint_for_compat(); int read_checkpoint(const ObServerSuperBlock &super_block); int replay_and_apply_server_slog(const common::ObLogCursor &replay_start_point); int replay_server_slog(const common::ObLogCursor &replay_start_point, common::ObLogCursor &replay_finish_point); @@ -96,11 +96,12 @@ private: int replay_update_tenant_super_block(const char *buf, const int64_t buf_len); int set_meta_block_list(common::ObIArray &meta_block_list); - int applay_replay_result(); + int apply_replay_result(); int handle_tenant_creating(const uint64_t tenant_id); int handle_tenant_create_commit(const omt::ObTenantMeta &tenant_meta); int handle_tenant_deleting(const uint64_t tenant_id); + int finish_slog_replay(); int mock_start(); // for test; private: diff --git a/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.cpp b/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.cpp old mode 100644 new mode 100755 index b8811abb5..1229bd34a --- a/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.cpp +++ b/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.cpp @@ -40,6 +40,107 @@ using namespace common; using namespace blocksstable; namespace storage { + +ObLSCkptMember::ObLSCkptMember() + : version_(LS_CKPT_MEM_VERSION), length_(0), + ls_meta_(), dup_ls_meta_(), tablet_meta_entry_() +{ +} + +ObLSCkptMember::~ObLSCkptMember() +{ + reset(); +} + +void ObLSCkptMember::reset() +{ + version_ = LS_CKPT_MEM_VERSION; + length_ = 0; + ls_meta_.reset(); + tablet_meta_entry_.reset(); + dup_ls_meta_.reset(); +} + +int ObLSCkptMember::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + const int64_t length = get_serialize_size(); + + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0) || OB_UNLIKELY(pos < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(buf), K(buf_len), K(pos)); + } else if (LS_CKPT_MEM_VERSION != version_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid version", K(ret), K_(version)); + } else if (OB_UNLIKELY(length_ > buf_len - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer's length is not enough", K(ret), K_(length), K(buf_len), K(pos)); + } else if (OB_FAIL(serialization::encode_i32(buf, buf_len, new_pos, version_))) { + LOG_WARN("fail to serialize ObLSCkptMember's version", K(ret), K(buf_len), K(new_pos), K(version_)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i32(buf, buf_len, new_pos, length))) { + LOG_WARN("fail to serialize ObLSCkptMember's length", K(ret), K(buf_len), K(new_pos), K(length)); + } else if (new_pos - pos < length && OB_FAIL(ls_meta_.serialize(buf, buf_len, new_pos))) { + LOG_WARN("fail to serialize ls meta", K(ret), K(buf_len), K(new_pos), K(ls_meta_)); + } else if (new_pos - pos < length && OB_FAIL(dup_ls_meta_.serialize(buf, buf_len, new_pos))) { + LOG_WARN("fail to serialize dup ls meta", K(ret), K(buf_len), K(new_pos), K(dup_ls_meta_)); + } else if (new_pos - pos < length && OB_FAIL(tablet_meta_entry_.serialize(buf, buf_len, new_pos))) { + LOG_WARN("fail to serialize tablet meta entry", K(ret), K(buf_len), K(new_pos), K(tablet_meta_entry_)); + } else if (OB_UNLIKELY(length != new_pos - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("length doesn't match", K(ret), K(length), K(new_pos), K(pos)); + } else { + pos = new_pos; + } + + return ret; +} + +int ObLSCkptMember::deserialize(const char *buf, const int64_t buf_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0) || OB_UNLIKELY(pos < 0) || OB_UNLIKELY(buf_len <= pos)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(buf), K(buf_len), K(pos)); + } else if (OB_FAIL(serialization::decode_i32(buf, buf_len, new_pos, (int32_t *)&version_))) { + LOG_WARN("fail to deserialize ObLSCkptMember's version", K(ret), K(buf_len), K(new_pos)); + } else if (OB_FAIL(serialization::decode_i32(buf, buf_len, new_pos, (int32_t *)&length_))) { + LOG_WARN("fail to deserialize ObLSCkptMember's length", K(ret), K(buf_len), K(new_pos)); + } else if (OB_UNLIKELY(length_ > buf_len - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer's length is not enough", K(ret), K(length_), K(buf_len), K(pos)); + } else if (OB_UNLIKELY(LS_CKPT_MEM_VERSION != version_)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("ObLSCkptMember's version is invalid", K(ret), K(version_)); + } else if (new_pos - pos < length_ && OB_FAIL(ls_meta_.deserialize(buf, buf_len, new_pos))) { + LOG_WARN("fail to deserialize ls meta", K(ret), K(buf_len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(dup_ls_meta_.deserialize(buf, buf_len, new_pos))) { + LOG_WARN("fail to deserialize dup ls meta", K(ret), K(buf_len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(tablet_meta_entry_.deserialize(buf, buf_len, new_pos))) { + LOG_WARN("fail to deserialize tablet meta entry", K(ret), K(buf_len), K(new_pos)); + } else if (OB_UNLIKELY(length_ != new_pos - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("length doesn't match", K(ret), K(buf_len), K(new_pos)); + } else { + pos = new_pos; + } + + return ret; +} + +int64_t ObLSCkptMember::get_serialize_size() const +{ + int64_t size = 0; + size += serialization::encoded_length_i32(version_); + size += serialization::encoded_length_i32(length_); + size += ls_meta_.get_serialize_size(); + size += dup_ls_meta_.get_serialize_size(); + size += tablet_meta_entry_.get_serialize_size(); + return size; +} + void ObTenantCheckpointSlogHandler::ObWriteCheckpointTask::runTimerTask() { int ret = OB_SUCCESS; @@ -60,11 +161,16 @@ ObTenantCheckpointSlogHandler::ObTenantCheckpointSlogHandler() last_ckpt_time_(0), last_frozen_version_(0), lock_(common::ObLatchIds::SLOG_CKPT_LOCK), + mutex_(), + tablet_key_set_(), + is_copying_tablets_(false), + ckpt_cursor_(), ls_block_handle_(), tablet_block_handle_(), tg_id_(-1), write_ckpt_task_(this), - replay_tablet_disk_addr_map_() + replay_tablet_disk_addr_map_(), + shared_block_rwriter_() { } @@ -88,6 +194,8 @@ int ObTenantCheckpointSlogHandler::init() LOG_WARN("ObTenantCheckpointSlogHandler has inited", K(ret)); } else if (OB_FAIL(TG_CREATE_TENANT(lib::TGDefIDs::WriteCkpt, tg_id_))) { LOG_WARN("fail to tg create tenant", K(ret)); + } else if (OB_FAIL(shared_block_rwriter_.init())) { + LOG_WARN("fail to init linked block manager", K(ret)); } else { is_inited_ = true; } @@ -148,6 +256,10 @@ void ObTenantCheckpointSlogHandler::destroy() tablet_block_handle_.reset(); tg_id_ = -1; replay_tablet_disk_addr_map_.destroy(); + shared_block_rwriter_.reset(); + tablet_key_set_.destroy(); + ckpt_cursor_.reset(); + is_copying_tablets_ = false; is_inited_ = false; } } @@ -165,9 +277,7 @@ int ObTenantCheckpointSlogHandler::replay_checkpoint_and_slog(const ObTenantSupe } else if (OB_FAIL(replay_checkpoint(super_block))) { LOG_WARN("fail to read_ls_checkpoint", K(ret), K(super_block)); } else if (OB_FAIL(replay_tenant_slog(super_block.replay_start_point_))) { - LOG_WARN("fail to replay_tenant_slog", K(ret)); - } else if (OB_FAIL(MTL(ObLSService*)->gc_ls_after_replay_slog())) { - LOG_WARN("fail to gc ls after replay slog", K(ret)); + LOG_WARN("fail to replay_tenant_slog", K(ret), K(super_block)); } else { replay_tablet_disk_addr_map_.destroy(); } @@ -175,6 +285,26 @@ int ObTenantCheckpointSlogHandler::replay_checkpoint_and_slog(const ObTenantSupe } int ObTenantCheckpointSlogHandler::replay_checkpoint(const ObTenantSuperBlock &super_block) +{ + int ret = OB_SUCCESS; + const bool is_replay_old = super_block.is_old_version(); + + if (OB_UNLIKELY(is_replay_old)) { + if (OB_FAIL(replay_old_checkpoint(super_block))) { + LOG_WARN("fail to replay old version checkpoint", K(ret), K(super_block)); + } + } else { + if (OB_FAIL(replay_new_checkpoint(super_block))) { + LOG_WARN("fail to replay new version checkpoint", K(ret), K(super_block)); + } + } + + LOG_INFO("finish replay tenant checkpoint", K(ret), K(super_block)); + + return ret; +} + +int ObTenantCheckpointSlogHandler::replay_old_checkpoint(const ObTenantSuperBlock &super_block) { int ret = OB_SUCCESS; @@ -189,37 +319,122 @@ int ObTenantCheckpointSlogHandler::replay_checkpoint(const ObTenantSuperBlock &s std::bind(&ObTenantCheckpointSlogHandler::replay_tablet, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); - ObTenantStorageCheckpointReader::ObCheckpointMetaOp replay_dup_table_ls_meta_op = - std::bind(&ObTenantCheckpointSlogHandler::replay_dup_table_ls_meta, - this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); - if (!replay_ls_op.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("replay_ls_op invalid", K(ret)); } else if (!replay_tablet_op.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("replay_tablet_op invalid", K(ret)); - } else if (!replay_dup_table_ls_meta_op.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("replay_dup_table_ls_meta_op invalid", K(ret)); } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_checkpoint_item( super_block.ls_meta_entry_, replay_ls_op, meta_block_list))) { LOG_WARN("fail to replay ls meta checkpoint", K(ret)); - } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(meta_block_list, false /*switch handle*/))) { + } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(meta_block_list))) { LOG_WARN("fail to add_macro_blocks", K(ret)); } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_checkpoint_item( super_block.tablet_meta_entry_, replay_tablet_op, meta_block_list))) { LOG_WARN("fail to replay tablet checkpoint", K(ret)); - } else if (OB_FAIL(tablet_block_handle_.add_macro_blocks(meta_block_list, true /*switch handle*/))) { - LOG_WARN("fail to add_macro_blocks", K(ret)); - } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_checkpoint_item( - super_block.ls_dup_table_entry_, replay_dup_table_ls_meta_op, meta_block_list))) { - LOG_WARN("fail to replay tablet checkpoint", K(ret)); - } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(meta_block_list, true /*switch handle*/))) { + } else if (OB_FAIL(tablet_block_handle_.add_macro_blocks(meta_block_list))) { LOG_WARN("fail to add_macro_blocks", K(ret)); } - LOG_INFO("finish replay tenant checkpoint", K(ret), K(super_block)); + return ret; +} + +int ObTenantCheckpointSlogHandler::replay_new_checkpoint(const ObTenantSuperBlock &super_block) +{ + int ret = OB_SUCCESS; + ObTenantStorageCheckpointReader tenant_storage_ckpt_reader; + const MacroBlockId &ls_meta_entry = super_block.ls_meta_entry_; + ObLinkedMacroBlockItemReader ls_ckpt_reader; + ObSArray tablet_block_list; + + if (OB_UNLIKELY(IS_EMPTY_BLOCK_LIST(ls_meta_entry))) { + LOG_INFO("no ls checkpoint", K(ret)); + } else if (OB_FAIL(ls_ckpt_reader.init(ls_meta_entry))) { + LOG_WARN("fail to init log stream item reader", K(ret), K(ls_meta_entry)); + } else { + char *item_buf = nullptr; + int64_t item_buf_len = 0; + ObLSCkptMember ls_ckpt_member; + int64_t pos = 0; + ObMetaDiskAddr addr; + while (OB_SUCC(ret)) { + item_buf = nullptr; + item_buf_len = 0; + pos = 0; + ls_ckpt_member.reset(); + if (OB_FAIL(ls_ckpt_reader.get_next_item(item_buf, item_buf_len, addr))) { + if (OB_ITER_END != ret) { + LOG_WARN("fail to get next log stream item", K(ret)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(ls_ckpt_member.deserialize(item_buf, item_buf_len, pos))) { + LOG_WARN("fail to deserialize ls ckpt member", K(ret), KP(item_buf), K(item_buf_len), K(pos)); + } else if (OB_FAIL(MTL(ObLSService *)->replay_create_ls(ls_ckpt_member.ls_meta_))) { + LOG_WARN("fail to replay put ls", K(ret), K(ls_ckpt_member)); + } else if (OB_FAIL(replay_dup_table_ls_meta(ls_ckpt_member.dup_ls_meta_))) { + LOG_WARN("fail to replay set dup table ls meta", K(ret), K(ls_ckpt_member)); + } else if (OB_FAIL(replay_new_tablet_checkpoint(ls_ckpt_member.tablet_meta_entry_, tablet_block_list))) { + LOG_WARN("fail to replay new tablet ckpt", K(ret), K(ls_ckpt_member)); + } + } + + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(ls_ckpt_reader.get_meta_block_list()))) { + LOG_WARN("fail to add ls macro blocks", K(ret)); + } else if (OB_FAIL(tablet_block_handle_.add_macro_blocks(tablet_block_list))) { + LOG_WARN("fail to add tablet macro blocks", K(ret)); + } + } + + return ret; +} + +int ObTenantCheckpointSlogHandler::replay_new_tablet_checkpoint( + const blocksstable::MacroBlockId &tablet_entry_block, + ObIArray &tablet_block_list) +{ + int ret = OB_SUCCESS; + ObLinkedMacroBlockItemReader tablet_ckpt_reader; + + if (OB_UNLIKELY(IS_EMPTY_BLOCK_LIST(tablet_entry_block))) { + LOG_INFO("no tablet checkpoint", K(tablet_entry_block)); + } else if (OB_FAIL(tablet_ckpt_reader.init(tablet_entry_block))) { + LOG_WARN("fail to init tablet ckpt reader", K(ret), K(tablet_entry_block)); + } else { + char *item_buf = nullptr; + int64_t item_buf_len = 0; + int64_t pos = 0; + ObMetaDiskAddr addr; + while (OB_SUCC(ret)) { + item_buf = nullptr; + item_buf_len = 0; + pos = 0; + if (OB_FAIL(tablet_ckpt_reader.get_next_item(item_buf, item_buf_len, addr))) { + if (OB_ITER_END != ret) { + LOG_WARN("fail to get next log stream item", K(ret)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(inner_replay_deserialize( + item_buf, item_buf_len, false /* allow to overwrite the map's element or not */))) { + LOG_WARN("fail to replay tablet", K(ret), KP(item_buf), K(item_buf_len)); + } + } + + if (OB_SUCC(ret)) { + const ObIArray ¯o_block_list = tablet_ckpt_reader.get_meta_block_list(); + for (int64_t i = 0; i < macro_block_list.count() && OB_SUCC(ret); i++) { + if (OB_FAIL(tablet_block_list.push_back(macro_block_list.at(i)))) { + LOG_WARN("fail to push back macro block id", K(ret)); + } + } + } + } return ret; } @@ -228,7 +443,7 @@ int ObTenantCheckpointSlogHandler::replay_ls_meta( const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len) { int ret = OB_SUCCESS; - UNUSED(addr); + UNUSEDx(addr); ObLSMeta ls_meta; int64_t pos = 0; if (OB_ISNULL(buf)) { @@ -243,49 +458,14 @@ int ObTenantCheckpointSlogHandler::replay_ls_meta( return ret; } -int ObTenantCheckpointSlogHandler::replay_tablet( - const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len) +int ObTenantCheckpointSlogHandler::replay_dup_table_ls_meta( + const transaction::ObDupTableLSCheckpoint::ObLSDupTableMeta &dup_ls_meta) { int ret = OB_SUCCESS; - ObTabletMapKey map_key; - - if (OB_UNLIKELY(!addr.is_valid() || nullptr == buf || buf_len <= 0 || !addr.is_block())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(addr)); - } else if (OB_FAIL(ObTablet::deserialize_id(buf, buf_len, map_key.ls_id_, map_key.tablet_id_))) { - LOG_WARN("fail to deserialize log stream id and tablet id", K(ret)); - } else if (OB_FAIL(replay_tablet_disk_addr_map_.set_refactored(map_key, addr, 0/*should not exist*/))) { - LOG_WARN("update tablet meta addr fail", K(ret), K(map_key), K(addr)); - } else { - LOG_INFO("Successfully load tablet ckpt", K(map_key), K(addr)); - } - - return ret; -} - - -int ObTenantCheckpointSlogHandler::replay_dup_table_ls_meta(const ObMetaDiskAddr &addr, - const char *buf, - const int64_t buf_len) -{ - int ret = OB_SUCCESS; - UNUSED(addr); - transaction::ObDupTableLSCheckpoint::ObLSDupTableMeta dup_ls_meta; ObLSHandle ls_handle; ObLS *ls = nullptr; - int64_t pos = 0; - if (OB_ISNULL(buf)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret)); - } else if (OB_FAIL(dup_ls_meta.deserialize(buf, buf_len, pos))) { - LOG_WARN("fail to deserialize", K(ret)); - } else if (OB_FAIL(MTL(ObLSService *)->get_ls(dup_ls_meta.ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { - if (OB_LS_NOT_EXIST == ret) { - LOG_INFO("this is possible when writing ls checkpoint but ls is removing", K(dup_ls_meta)); - ret = OB_SUCCESS; - } else { - LOG_WARN("fail to get ls", K(ret), K(dup_ls_meta)); - } + if (OB_FAIL(MTL(ObLSService *)->get_ls(dup_ls_meta.ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get ls", K(ret), K(dup_ls_meta)); } else if (OB_ISNULL(ls = ls_handle.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls is null", K(dup_ls_meta)); @@ -325,86 +505,216 @@ int ObTenantCheckpointSlogHandler::replay_tenant_slog(const common::ObLogCursor return ret; } +int ObTenantCheckpointSlogHandler::read_from_share_blk( + const ObMetaDiskAddr &addr, + common::ObArenaAllocator &allocator, + char *&buf, + int64_t &buf_len) +{ + int ret = OB_SUCCESS; + ObSharedBlockReadHandle read_handle; + ObSharedBlockReadInfo read_info; + read_info.io_desc_.set_wait_event(ObWaitEventIds::SLOG_CKPT_LOCK_WAIT); + read_info.addr_ = addr; + if (OB_FAIL(shared_block_rwriter_.async_read(read_info, read_handle))) { + LOG_WARN("fail to read tablet from macro block", K(ret), K(read_info)); + } else if (OB_FAIL(read_handle.wait())) { + LOG_WARN("fail to wait for read handle", K(ret)); + } else if (OB_FAIL(read_handle.get_data(allocator, buf, buf_len))) { + LOG_WARN("fail to get data from read handle", K(ret), KP(buf), K(buf_len)); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::read_from_disk( + const ObMetaDiskAddr &addr, + common::ObArenaAllocator &allocator, + char *&buf, + int64_t &buf_len) +{ + int ret = OB_SUCCESS; + char *read_buf = nullptr; + const int64_t read_buf_len = addr.size(); + const ObTenantSuperBlock super_block = static_cast(share::ObTenantEnv::get_tenant())->get_super_block(); + if (OB_UNLIKELY(!super_block.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("super block is invalid", K(ret), K(super_block)); + } else if (!super_block.is_old_version()) { + if (ObMetaDiskAddr::DiskType::FILE == addr.type()) { + if (OB_FAIL(read_empty_shell_file(addr, allocator, buf, buf_len))) { + LOG_WARN("fail to read empty shell", K(ret), K(addr), K(buf), K(buf_len)); + } + } else { + if (OB_FAIL(read_from_share_blk(addr, allocator, buf, buf_len))) { + LOG_WARN("fail to read from share block", K(ret), K(addr), K(buf), K(buf_len)); + } + } + } else if (OB_ISNULL(read_buf = static_cast(allocator.alloc(read_buf_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate buffer", K(ret), K(read_buf_len), KP(read_buf)); + } else if (OB_FAIL(read_from_disk_addr(addr, read_buf, read_buf_len, buf, buf_len))) { + LOG_WARN("fail to read tablet from addr", K(ret), K(addr), KP(read_buf), K(read_buf_len)); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::check_is_need_record_transfer_info( + const share::ObLSID &src_ls_id, + const share::SCN &transfer_start_scn, + bool &is_need) +{ + int ret = OB_SUCCESS; + ObLSService* ls_srv = nullptr; + ObLSHandle src_ls_handle; + ObLS *src_ls = NULL; + is_need = false; + if (!src_ls_id.is_valid() || !transfer_start_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("src_ls_id or transfer_start_scn is invalid", K(ret), K(src_ls_id), K(transfer_start_scn)); + } else if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls srv should not be NULL", K(ret), KP(ls_srv)); + } else if (OB_FAIL(ls_srv->get_ls(src_ls_id, src_ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", KR(ret), K(src_ls_id)); + } else if (OB_ISNULL(src_ls = src_ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", KR(ret), K(src_ls_id)); + } else if (src_ls->get_ls_meta().get_clog_checkpoint_scn() < transfer_start_scn) { + is_need = true; + LOG_INFO("src ls max decided scn is smaller than transfer start scn, need wait clog replay", K(ret), + K(src_ls_id), K(transfer_start_scn), "ls_meta", src_ls->get_ls_meta()); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::record_ls_transfer_info( + const ObLSHandle &ls_handle, + const ObTabletID &tablet_id, + const ObTabletTransferInfo &tablet_transfer_info) +{ + int ret = OB_SUCCESS; + storage::ObLS *ls = NULL; + bool is_need = false; + ObMigrationStatus current_migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + ObMigrationStatus new_migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + if (!ls_handle.is_valid() || !tablet_transfer_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(ls_handle), K(tablet_transfer_info)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream not exist", K(ret)); + } else if (OB_FAIL(ls->get_migration_status(current_migration_status))) { + LOG_WARN("failed to get ls migration status", K(ret)); + } else if (OB_FAIL(ObMigrationStatusHelper::trans_reboot_status(current_migration_status, new_migration_status))) { + LOG_WARN("failed to trans fail status", K(ret), "ls_id", ls->get_ls_id(), + K(current_migration_status), K(new_migration_status)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != new_migration_status) { + LOG_INFO("The log stream does not need to record transfer_info", "ls_id", ls->get_ls_id(), K(current_migration_status), K(new_migration_status)); + } else if (!tablet_transfer_info.has_transfer_table()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should has transfer table", K(ret), "ls_id", ls->get_ls_id(), K(tablet_id), K(tablet_transfer_info)); + } else if (ls->get_ls_startup_transfer_info().is_valid()) { + if (ls->get_ls_startup_transfer_info().ls_id_ != tablet_transfer_info.ls_id_ + || ls->get_ls_startup_transfer_info().transfer_start_scn_ != tablet_transfer_info.transfer_start_scn_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("The transfer_info of different tablet records on the same ls is different", K(ret), "ls_id", ls->get_ls_id(), + K(tablet_id), K(tablet_transfer_info), "ls_startup_transfer_info", ls->get_ls_startup_transfer_info()); + } + } else if (OB_FAIL(check_is_need_record_transfer_info(tablet_transfer_info.ls_id_, + tablet_transfer_info.transfer_start_scn_, is_need))) { + LOG_WARN("failed to check is need record ls", K(ret), "ls_id", ls->get_ls_id(), K(tablet_id), K(tablet_transfer_info)); + } else if (!is_need) { + // do nothing + } else if (OB_FAIL(ls->get_ls_startup_transfer_info().init(tablet_transfer_info.ls_id_, + tablet_transfer_info.transfer_start_scn_))) { + LOG_WARN("failed to init ls transfer info", K(ret), "ls_id", ls->get_ls_id(), K(tablet_id), K(tablet_transfer_info)); + } + return ret; +} int ObTenantCheckpointSlogHandler::replay_load_tablets() { int ret = OB_SUCCESS; - const ObMemAttr mem_attr(MTL_ID(), "TenantReplay"); char *buf = nullptr; int64_t buf_len = 0; - char *r_buf = nullptr; - int64_t r_len = 0; - ObArray tablets; ReplayTabletDiskAddrMap::iterator iter = replay_tablet_disk_addr_map_.begin(); + ObTabletTransferInfo tablet_transfer_info; while (OB_SUCC(ret) && iter != replay_tablet_disk_addr_map_.end()) { + ObArenaAllocator allocator("ReplayLoad"); const ObTabletMapKey &key = iter->first; - if (OB_FAIL(tablets.push_back(key))) { - LOG_WARN("fail to push table key into array", K(ret), K(key)); + ObMetaDiskAddr addr = iter->second; + ObLSTabletService *ls_tablet_svr = nullptr; + ObLSHandle ls_handle; + tablet_transfer_info.reset(); + if (OB_FAIL(read_from_disk(addr, allocator, buf, buf_len))) { + LOG_WARN("fail to read from disk", K(ret), K(addr), KP(buf), K(buf_len)); + } else if (OB_FAIL(get_tablet_svr(key.ls_id_, ls_tablet_svr, ls_handle))) { + LOG_WARN("fail to get ls tablet service", K(ret)); + } else if (OB_FAIL(ls_tablet_svr->replay_create_tablet(addr, buf, buf_len, key.tablet_id_, tablet_transfer_info))) { + LOG_WARN("fail to create tablet for replay", K(ret), K(key), K(addr)); + } else if (tablet_transfer_info.has_transfer_table() && OB_FAIL(record_ls_transfer_info(ls_handle, key.tablet_id_, tablet_transfer_info))) { + LOG_WARN("fail to create tablet for replay", K(ret), K(key), K(addr)); } else { + LOG_INFO("Successfully load tablet", K(key), K(addr)); ++iter; } } - if (OB_SUCC(ret)) { - std::sort(tablets.begin(), tablets.end(), [](ObTabletMapKey &l, ObTabletMapKey &r) { - bool ret = true; - if (l.tablet_id_.is_inner_tablet() && !r.tablet_id_.is_inner_tablet()) { - ret = true; - } else if (!l.tablet_id_.is_inner_tablet() && r.tablet_id_.is_inner_tablet()) { - ret = false; - } else { // Both of tablets is inner or non-inner. - if (l.ls_id_ < r.ls_id_) { - ret = true; - } else if (l.ls_id_ > r.ls_id_) { - ret = false; - } else if (l.tablet_id_ < r.tablet_id_) { - ret = true; - } else { - ret = false; - } - } - return ret; - }); - } - for (int64_t i = 0; OB_SUCC(ret) && i < tablets.count(); ++i) { - const ObTabletMapKey &map_key = tablets.at(i); - ObMetaDiskAddr tablet_addr; - ObLSTabletService *ls_tablet_svr = nullptr; - ObLSHandle ls_handle; - if (OB_FAIL(replay_tablet_disk_addr_map_.get_refactored(map_key, tablet_addr))) { - LOG_WARN("fail to get tablet address", K(ret), K(map_key)); - } else { - if (OB_NOT_NULL(buf)) { - if (buf_len >= tablet_addr.size()) { - // reuse last buf to reduce malloc - } else { - ob_free(buf); - buf = nullptr; - buf_len = 0; - } - } - if (OB_ISNULL(buf)) { - if (OB_ISNULL(buf = (char*)ob_malloc(tablet_addr.size(), mem_attr))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to allocate tablet buffer", K(ret), K(tablet_addr)); - } else { - buf_len = tablet_addr.size(); - } - } - } + return ret; +} - if (OB_FAIL(ret)) { - } else if (OB_FAIL(read_from_disk_addr(tablet_addr, buf, buf_len, r_buf, r_len))) { - LOG_WARN("fail to read tablet from addr", K(ret), K(tablet_addr)); - } else if (OB_FAIL(get_tablet_svr(map_key.ls_id_, ls_tablet_svr, ls_handle))) { - LOG_WARN("fail to get ls tablet service", K(ret)); - } else if (OB_FAIL(ls_tablet_svr->replay_create_tablet( - tablet_addr, r_buf, r_len, map_key.tablet_id_))) { - LOG_WARN("fail to create tablet for replay", K(ret), K(map_key), K(tablet_addr)); +int ObTenantCheckpointSlogHandler::report_slog( + const ObTabletMapKey &tablet_key, + const ObMetaDiskAddr &slog_addr) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantCheckpointSlogHandler hasn't been inited", K(ret)); + } else if (OB_UNLIKELY(!slog_addr.is_valid() || !slog_addr.is_file())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("slog_addr is invalid", K(ret), K(slog_addr)); + } else { + int64_t file_id; + int64_t offset; + int64_t size; + lib::ObMutexGuard guard(mutex_); + if (is_copying_tablets_) { + if (OB_UNLIKELY(!ckpt_cursor_.is_valid())) { + LOG_WARN("checkpoint cursor is invalid", K(ret), K(ckpt_cursor_)); + } else if (OB_FAIL(slog_addr.get_file_addr(file_id, offset, size))) { + LOG_WARN("fail to get slog file addr", K(ret), K(slog_addr)); + } else if (file_id < ckpt_cursor_.file_id_ + || (file_id == ckpt_cursor_.file_id_ && offset < ckpt_cursor_.offset_)) { + LOG_INFO("tablet slog cursor is smaller, no need to add it to the set", + K(ret), K(ckpt_cursor_), K(file_id), K(offset)); + } else if (OB_FAIL(tablet_key_set_.set_refactored(tablet_key, 1 /* whether allow override */))) { + LOG_WARN("fail to insert element into tablet key set", K(ret), K(tablet_key)); + } } - LOG_INFO("Successfully load tablet", K(map_key), K(tablet_addr)); } - if (OB_NOT_NULL(buf)) { - ob_free(buf); - buf = nullptr; + return ret; +} + +int ObTenantCheckpointSlogHandler::check_slog(const ObTabletMapKey &tablet_key, bool &has_slog) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantCheckpointSlogHandler hasn't been inited", K(ret)); + } else if (OB_UNLIKELY(!tablet_key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet key is invalid", K(ret), K(tablet_key)); + } else { + lib::ObMutexGuard guard(mutex_); + int tmp_ret = tablet_key_set_.exist_refactored(tablet_key); + if (OB_HASH_EXIST == tmp_ret) { + has_slog = true; + LOG_INFO("tablet slog has been written, no need to write checkpoint", K(tmp_ret), K(tablet_key)); + } else if (OB_UNLIKELY(OB_HASH_NOT_EXIST != tmp_ret)) { + ret = tmp_ret; + LOG_WARN("fail to check whether tablet slog has been written", K(ret), K(tablet_key)); + } else { + has_slog = false; + } } return ret; } @@ -412,7 +722,6 @@ int ObTenantCheckpointSlogHandler::replay_load_tablets() int ObTenantCheckpointSlogHandler::write_checkpoint(bool is_force) { int ret = OB_SUCCESS; - ObLogCursor cur_cursor; int64_t alert_interval = ObWriteCheckpointTask::FAIL_WRITE_CHECKPOINT_ALERT_INTERVAL; int64_t min_interval = ObWriteCheckpointTask::RETRY_WRITE_CHECKPOINT_MIN_INTERVAL; @@ -422,7 +731,6 @@ int ObTenantCheckpointSlogHandler::write_checkpoint(bool is_force) omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); ObTenantSuperBlock last_super_block = tenant->get_super_block(); - int64_t frozen_version = MTL(ObTenantTabletScheduler*)->get_frozen_version(); bool is_writing_checkpoint_set = false; const int64_t start_time = ObTimeUtility::current_time(); @@ -431,10 +739,13 @@ int ObTenantCheckpointSlogHandler::write_checkpoint(bool is_force) if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObTenantCheckpointSlogHandler not init", K(ret)); - } else if (!ATOMIC_BCAS(&is_writing_checkpoint_, false, true)) { - ret = OB_NEED_WAIT; - LOG_WARN("is writing checkpoint, need wait", K(ret)); } else { + while (!ATOMIC_BCAS(&is_writing_checkpoint_, false, true)) { + if (REACH_TIME_INTERVAL(10 * 1000 * 1000)) { // 10s + LOG_INFO("wait until last checkpoint finished"); + } + ob_usleep(100 * 1000); // 100ms + } is_writing_checkpoint_set = true; } if (OB_FAIL(ret)) { @@ -444,50 +755,89 @@ int ObTenantCheckpointSlogHandler::write_checkpoint(bool is_force) } else if (OB_UNLIKELY(!last_super_block.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to get tenant super block", K(ret), K(last_super_block)); - } else if (OB_FAIL(MTL(ObStorageLogger *)->get_active_cursor(cur_cursor))) { + } else if (OB_FAIL(get_cur_cursor())) { LOG_WARN("get slog current cursor fail", K(ret)); - } else if (OB_UNLIKELY(!cur_cursor.is_valid())) { + } else if (OB_UNLIKELY(!ckpt_cursor_.is_valid())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("cur_cursor is invalid", K(ret)); - } else if (is_force || (last_frozen_version_ < frozen_version) || - ((start_time > last_ckpt_time_ + min_interval) && cur_cursor.newer_than(last_super_block.replay_start_point_) && - (cur_cursor.log_id_ - last_super_block.replay_start_point_.log_id_ >= + LOG_WARN("ckpt_cursor_ is invalid", K(ret)); + } else if (is_force || last_super_block.is_old_version() || (last_frozen_version_ < frozen_version) || + ((start_time > last_ckpt_time_ + min_interval) && ckpt_cursor_.newer_than(last_super_block.replay_start_point_) && + (ckpt_cursor_.log_id_ - last_super_block.replay_start_point_.log_id_ >= ObWriteCheckpointTask::MIN_WRITE_CHECKPOINT_LOG_CNT))) { - tmp_super_block.replay_start_point_ = cur_cursor; + DEBUG_SYNC(AFTER_CHECKPOINT_GET_CURSOR); + + tmp_super_block.replay_start_point_ = ckpt_cursor_; if (OB_FAIL(tenant_storage_ckpt_writer.init())) { LOG_WARN("fail to init tenant_storage_ckpt_writer_", K(ret)); } else if (OB_FAIL(tenant_storage_ckpt_writer.write_checkpoint(tmp_super_block))) { LOG_WARN("fail to write_checkpoint", K(ret)); + } + clean_copy_status(); + if (OB_FAIL(ret)) { + // do nothing } else if (OB_FAIL(ObServerCheckpointSlogHandler::get_instance().write_tenant_super_block_slog(tmp_super_block))) { LOG_WARN("fail to write_tenant_super_block_slog", K(ret), K(tmp_super_block)); - } else if (OB_FAIL(update_tablet_meta_addr_and_block_list(tenant_storage_ckpt_writer))) { - LOG_WARN("fail to update_tablet_meta_addr_and_block_list", K(ret)); + } else if (OB_FAIL(update_tablet_meta_addr_and_block_list( + last_super_block.is_old_version(), tenant_storage_ckpt_writer))) { + LOG_ERROR("fail to update_tablet_meta_addr_and_block_list", K(ret), K(last_super_block)); // abort if failed, because it cannot be rolled back if partially success. // otherwise, updates need to be transactional. + ob_usleep(1000 * 1000); ob_abort(); - } else if (FALSE_IT(tenant->set_tenant_super_block(tmp_super_block))) { - } else if (OB_FAIL(MTL(ObStorageLogger *)->remove_useless_log_file(cur_cursor.file_id_, MTL_ID()))) { - LOG_WARN("fail to remove_useless_log_file", K(ret), K(tmp_super_block)); } else { - last_ckpt_time_ = start_time; - last_frozen_version_ = frozen_version; - cost_time = ObTimeUtility::current_time() - start_time; + tenant->set_tenant_super_block(tmp_super_block); + if (OB_FAIL(MTL(ObStorageLogger *)->remove_useless_log_file(ckpt_cursor_.file_id_, MTL_ID()))) { + LOG_WARN("fail to remove_useless_log_file", K(ret), K(tmp_super_block)); + } else { + last_ckpt_time_ = start_time; + last_frozen_version_ = frozen_version; + cost_time = ObTimeUtility::current_time() - start_time; + } } + + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(tenant_storage_ckpt_writer.rollback())) { + LOG_ERROR("fail to rollback checkpoint, macro blocks leak", K(tmp_ret)); + } + FLOG_INFO("finish write tenant checkpoint", K(ret), K(last_super_block), K(tmp_super_block), K_(last_ckpt_time), K(start_time), K(frozen_version), K_(last_frozen_version), K(is_force), K(cost_time)); SERVER_EVENT_ADD("storage", "write slog checkpoint", "tenant_id", tenant_id, - "ret", ret, "cursor", cur_cursor, "frozen_version", frozen_version, "cost_time(us)", cost_time); + "ret", ret, "cursor", ckpt_cursor_, "frozen_version", frozen_version, "cost_time(us)", cost_time); } + clean_copy_status(); // in case fail after get_cur_cursor if (is_writing_checkpoint_set) { ATOMIC_STORE(&is_writing_checkpoint_, false); } - return ret; } +int ObTenantCheckpointSlogHandler::get_cur_cursor() +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(mutex_); + tablet_key_set_.destroy(); + if (OB_FAIL(MTL(ObStorageLogger *)->get_active_cursor(ckpt_cursor_))) { + LOG_WARN("fail to get current cursor", K(ret)); + } else if (OB_FAIL(tablet_key_set_.create(BUCKET_NUM, ObModIds::OB_HASH_BUCKET, ObModIds::OB_HASH_BUCKET, MTL_ID()))) { + LOG_WARN("fail to create tablet key set", K(ret)); + } else { + is_copying_tablets_ = true; + } + return ret; +} + +void ObTenantCheckpointSlogHandler::clean_copy_status() +{ + lib::ObMutexGuard guard(mutex_); + is_copying_tablets_ = false; + tablet_key_set_.destroy(); +} + int ObTenantCheckpointSlogHandler::update_tablet_meta_addr_and_block_list( - ObTenantStorageCheckpointWriter &ckpt_writer) + const bool is_replay_old, + ObTenantStorageCheckpointWriter &ckpt_writer) { int ret = OB_SUCCESS; ObIArray *meta_block_list = nullptr; @@ -500,27 +850,29 @@ int ObTenantCheckpointSlogHandler::update_tablet_meta_addr_and_block_list( // update the tablet addr. to resolve the dead lock, update_tablet_meta_addr is moved out of lock, // but this may cause t3m read a new addr which is not in the tablet_block_handle_. when this // happens, t3m needs to retry. - if (OB_FAIL(ckpt_writer.update_tablet_meta_addr())) { - LOG_WARN("fail to update_tablet_meta_addr", K(ret)); + if (OB_FAIL(ckpt_writer.batch_compare_and_swap_tablet(is_replay_old))) { + LOG_WARN("fail to update_tablet_meta_addr", K(ret), K(is_replay_old)); } TCWLockGuard guard(lock_); if (OB_FAIL(ret)) { - LOG_WARN("fail to update_tablet_meta_addr", K(ret)); - } else if (OB_FAIL(ckpt_writer.get_ls_block_list(meta_block_list))) { - LOG_WARN("fail to get_ls_block_list", K(ret)); - } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(*meta_block_list, false /*switch handle*/))) { - LOG_WARN("fail to add_macro_blocks", K(ret)); - } else if (OB_FAIL(ckpt_writer.get_dup_ls_block_list(meta_block_list))) { - LOG_WARN("fail to get_ls_block_list", K(ret)); - } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(*meta_block_list, true /*switch handle*/))) { - LOG_WARN("fail to add_macro_blocks", K(ret)); - } else if (OB_FAIL(ckpt_writer.get_tablet_block_list(meta_block_list))) { - LOG_WARN("fail to get_tablet_block_list", K(ret)); - } else if (OB_FAIL( - tablet_block_handle_.add_macro_blocks(*meta_block_list, true /*switch handle*/))) { - LOG_WARN("fail to set_tablet_block_list", K(ret)); + } else { + do { + if (OB_FAIL(ckpt_writer.get_ls_block_list(meta_block_list))) { + LOG_WARN("fail to get_ls_block_list", K(ret)); + } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(*meta_block_list))) { + LOG_WARN("fail to add_macro_blocks", K(ret)); + } else if (OB_FAIL(ckpt_writer.get_tablet_block_list(meta_block_list))) { + LOG_WARN("fail to get_tablet_block_list", K(ret)); + } else if (OB_FAIL(tablet_block_handle_.add_macro_blocks(*meta_block_list))) { + LOG_WARN("fail to set_tablet_block_list", K(ret)); + } + if (OB_UNLIKELY(OB_ALLOCATE_MEMORY_FAILED == ret)) { + LOG_WARN("memory is insufficient, retry", K(ret)); + } + } while (OB_UNLIKELY(OB_ALLOCATE_MEMORY_FAILED == ret)); } + return ret; } @@ -606,9 +958,9 @@ int ObTenantCheckpointSlogHandler::replay(const ObRedoModuleReplayParam ¶m) } break; } - case ObRedoLogSubType::OB_REDO_LOG_PUT_TABLET: { - if (OB_FAIL(inner_replay_put_tablet(param))) { - LOG_WARN("fail to replay create tablet slog", K(ret), K(param)); + case ObRedoLogSubType::OB_REDO_LOG_UPDATE_TABLET: { + if (OB_FAIL(inner_replay_update_tablet(param))) { + LOG_WARN("fail to replay update tablet slog", K(ret), K(param)); } break; } @@ -618,6 +970,18 @@ int ObTenantCheckpointSlogHandler::replay(const ObRedoModuleReplayParam ¶m) } break; } + case ObRedoLogSubType::OB_REDO_LOG_PUT_OLD_TABLET: { + if (OB_FAIL(inner_replay_put_old_tablet(param))) { + LOG_WARN("fail to replay put old tablet slog", K(param)); + } + break; + } + case ObRedoLogSubType::OB_REDO_LOG_EMPTY_SHELL_TABLET: { + if (OB_FAIL(inner_replay_empty_shell_tablet(param))) { + LOG_WARN("fail to replay put old tablet slog", K(param)); + } + break; + } case ObRedoLogSubType::OB_REDO_LOG_UPDATE_DUP_TABLE_LS: { if (OB_FAIL(inner_replay_dup_table_ls_slog(param))) { LOG_WARN("fail to replay dup_table ls slog", K(param)); @@ -688,7 +1052,6 @@ int ObTenantCheckpointSlogHandler::inner_replay_dup_table_ls_slog( } else { LOG_WARN("fail to get ls", K(ret), K(slog_entry)); } - LOG_WARN("get ls failed", K(ret), K(param), K(pos)); } else if (OB_ISNULL(ls_ptr = ls_handle.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid ls_ptr", K(ret), K(param), K(pos)); @@ -766,19 +1129,86 @@ int ObTenantCheckpointSlogHandler::remove_tablets_from_replay_map_(const ObLSID return ret; } -int ObTenantCheckpointSlogHandler::inner_replay_put_tablet(const ObRedoModuleReplayParam ¶m) +int ObTenantCheckpointSlogHandler::inner_replay_update_tablet(const ObRedoModuleReplayParam ¶m) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(inner_replay_deserialize(param.buf_, param.data_size_, true /*overwrite if tablet exists*/))) { + LOG_WARN("fail to deserialize slog and set disk addr map", K(ret)); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::inner_replay_deserialize( + const char *buf, + const int64_t buf_len, + bool allow_override /* allow to overwrite the map's element or not */) +{ + int ret = OB_SUCCESS; + ObUpdateTabletLog slog; + ObTabletMapKey tablet_key; + int64_t pos = 0; + if (OB_FAIL(slog.deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize create tablet slog", K(ret), K(pos), K(buf_len), K(slog)); + } else if (OB_UNLIKELY(!slog.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("slog is invalid", K(ret), K(slog)); + } else { + tablet_key.ls_id_ = slog.ls_id_; + tablet_key.tablet_id_ = slog.tablet_id_; + if (OB_FAIL(replay_tablet_disk_addr_map_.set_refactored(tablet_key, slog.disk_addr_, allow_override ? 1 : 0))) { + LOG_WARN("fail to update tablet meta addr", K(ret), K(slog)); + } else { + LOG_INFO("Successfully load tablet meta addr for ckpt", K(slog)); + } + } + + return ret; +} + +int ObTenantCheckpointSlogHandler::inner_replay_put_old_tablet(const ObRedoModuleReplayParam ¶m) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(inner_replay_old_deserialize( + param.disk_addr_, + param.buf_, + param.disk_addr_.size(), + true /* allow to overwrite the map's element or not */))) { + LOG_WARN("fail to replay old tablet", K(ret), K(param)); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::replay_tablet( + const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!addr.is_valid() || nullptr == buf || buf_len <= 0 || !addr.is_block())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(addr)); + } else if (OB_FAIL(inner_replay_old_deserialize( + addr, + buf, + buf_len, + false /* allow to overwrite the map's element or not */))) { + LOG_WARN("fail to replay old tablet", K(ret), K(addr), KP(buf), K(buf_len)); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::inner_replay_old_deserialize( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + bool allow_override /* allow to overwrite the map's element or not */) { int ret = OB_SUCCESS; ObTabletMapKey map_key; - if (OB_FAIL(ObTablet::deserialize_id(param.buf_, param.disk_addr_.size(), map_key.ls_id_, map_key.tablet_id_))) { - LOG_WARN("fail to deserialize ls id and tablet id", K(param)); - } else if (OB_FAIL(replay_tablet_disk_addr_map_.set_refactored(map_key, param.disk_addr_, 1/*overwrite if exist*/))) { - LOG_WARN("update tablet meta addr fail", K(ret), K(map_key), K(param.disk_addr_)); - } else { - LOG_INFO("Successfully load tablet from slog", K(map_key), K(param.disk_addr_)); + if (OB_FAIL(ObTablet::deserialize_id(buf, buf_len, map_key.ls_id_, map_key.tablet_id_))) { + LOG_WARN("fail to deserialize log stream id and tablet id", K(ret)); + } else if (OB_FAIL(replay_tablet_disk_addr_map_.set_refactored(map_key, addr, allow_override ? 1 : 0))) { + LOG_WARN("update tablet meta addr fail", K(ret), K(map_key), K(addr)); } - return ret; } @@ -804,6 +1234,25 @@ int ObTenantCheckpointSlogHandler::inner_replay_delete_tablet(const ObRedoModule return ret; } +int ObTenantCheckpointSlogHandler::inner_replay_empty_shell_tablet(const ObRedoModuleReplayParam ¶m) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + ObEmptyShellTabletLog slog; + + if (OB_FAIL(slog.deserialize_id(param.buf_, param.disk_addr_.size(), pos))) { + STORAGE_LOG(WARN, "failed to serialize tablet_id_", K(ret), K(param.disk_addr_.size()), K(pos)); + } else { + const ObTabletMapKey map_key(slog.ls_id_, + slog.tablet_id_); + if (OB_FAIL(replay_tablet_disk_addr_map_.set_refactored(map_key, param.disk_addr_, 1))) { + LOG_WARN("fail to set tablet", K(ret), K(map_key), K(param.disk_addr_)); + } + } + + return ret; +} + int ObTenantCheckpointSlogHandler::get_tablet_svr( const ObLSID &ls_id, ObLSTabletService *&ls_tablet_svr, @@ -812,7 +1261,7 @@ int ObTenantCheckpointSlogHandler::get_tablet_svr( int ret = OB_SUCCESS; ObLS *ls = nullptr; if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { - LOG_WARN("fail to get ls handle", K(ls_id)); + LOG_WARN("fail to get ls handle", K(ret), K(ls_id)); } else if (OB_ISNULL(ls = ls_handle.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls is null", K(ret), K(ls_id)); @@ -887,9 +1336,8 @@ int ObTenantCheckpointSlogHandler::parse( } break; } - case ObRedoLogSubType::OB_REDO_LOG_PUT_TABLET: { + case ObRedoLogSubType::OB_REDO_LOG_UPDATE_TABLET: { ObTabletMeta tablet_meta; - ObArenaAllocator allocator; int64_t pos = 0; int32_t length = 0; int32_t version = 0; @@ -898,7 +1346,7 @@ int ObTenantCheckpointSlogHandler::parse( LOG_WARN("failed to deserialize version"); } else if (OB_FAIL(serialization::decode_i32(buf, len, pos, &length))) { LOG_WARN("failed to deserialize length"); - } else if (OB_FAIL(tablet_meta.deserialize(allocator, buf, len, pos))) { + } else if (OB_FAIL(tablet_meta.deserialize(buf, len, pos))) { LOG_WARN("fail to deserialize tablet meta", K(ret), KP(buf), K(len), K(pos)); } snprintf(slog_name, ObStorageLogReplayer::MAX_SLOG_NAME_LEN, "put tablet slog: "); @@ -939,32 +1387,7 @@ int ObTenantCheckpointSlogHandler::parse( int ObTenantCheckpointSlogHandler::replay_over() { - int ret = OB_SUCCESS; - - common::ObSharedGuard ls_iter; - ObLS *ls = nullptr; - ObLSTabletService *ls_tablet_svr = nullptr; - if (OB_FAIL(MTL(ObLSService *)->get_ls_iter(ls_iter, ObLSGetMod::STORAGE_MOD))) { - LOG_WARN("failed to get ls iter", K(ret)); - } else { - while (OB_SUCC(ret)) { - if (OB_FAIL(ls_iter->get_next(ls))) { - if (OB_ITER_END != ret) { - LOG_WARN("fail to get next ls", K(ret)); - } - } else if (nullptr == ls) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is null", K(ret)); - } else if (OB_FAIL(ls->finish_slog_replay())) { - LOG_WARN("finish replay failed", K(ret), KPC(ls)); - } - } - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - } - } - - return ret; + return OB_SUCCESS; // nothing to do. } int ObTenantCheckpointSlogHandler::read_from_disk_addr(const ObMetaDiskAddr &addr, @@ -1058,6 +1481,34 @@ int ObTenantCheckpointSlogHandler::read_from_slog(const ObMetaDiskAddr &addr, return ret; } +int ObTenantCheckpointSlogHandler::read_empty_shell_file( + const ObMetaDiskAddr &addr, + common::ObArenaAllocator &allocator, + char *&buf, + int64_t &buf_len) +{ + int ret = OB_SUCCESS; + + ObEmptyShellTabletLog slog; + int64_t pos = 0; + if (ObMetaDiskAddr::DiskType::FILE != addr.type()) { + ret = OB_STATE_NOT_MATCH; + STORAGE_LOG(WARN, "addr type is not correct", K(ret), K(addr)); + } else if (OB_ISNULL(buf = static_cast(allocator.alloc(addr.size())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + } else if (FALSE_IT(buf_len = addr.size())) { + } else if (OB_FAIL(read_from_slog(addr, buf, buf_len, pos))) { + STORAGE_LOG(WARN, "fail to read from slog", K(ret), K(addr), KP(buf), K(buf_len), K(pos)); + } else if (OB_FAIL(slog.deserialize_id(buf, buf_len, pos))) { + STORAGE_LOG(WARN, "fail to deserialize id", K(ret), K(addr), KP(buf), K(buf_len), K(pos)); + } else { + buf += pos; + buf_len -= pos; + } + + return ret; +} + } // end namespace storage } // namespace oceanbase diff --git a/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h b/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h index 6e9e2e057..035eafb52 100644 --- a/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h +++ b/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h @@ -19,6 +19,10 @@ #include "storage/meta_mem/ob_tablet_map_key.h" #include "storage/ob_super_block_struct.h" #include "storage/slog/ob_storage_log_replayer.h" +#include "storage/blockstore/ob_shared_block_reader_writer.h" +#include "storage/ls/ob_ls_meta.h" +#include "storage/tx/ob_dup_table_base.h" +#include "storage/high_availability/ob_tablet_transfer_info.h" namespace oceanbase { @@ -37,6 +41,31 @@ class ObStorageLogger; class ObLSTabletService; class ObLSHandle; +struct ObLSCkptMember final +{ +public: + static const int64_t LS_CKPT_MEM_VERSION = 1; + ObLSCkptMember(); + ~ObLSCkptMember(); + DISALLOW_COPY_AND_ASSIGN(ObLSCkptMember); + void reset(); + + int serialize(char *buf, const int64_t len, int64_t &pos) const; + int deserialize( + const char *buf, + const int64_t len, + int64_t &pos); + int64_t get_serialize_size() const; + TO_STRING_KV(K_(version), K_(ls_meta), K_(tablet_meta_entry), K_(dup_ls_meta)); + +public: + int32_t version_; + int32_t length_; + ObLSMeta ls_meta_; + transaction::ObDupTableLSCheckpoint::ObLSDupTableMeta dup_ls_meta_; + blocksstable::MacroBlockId tablet_meta_entry_; +}; + class ObTenantCheckpointSlogHandler : public ObIRedoModule { public: @@ -48,7 +77,10 @@ public: static const int64_t RETRY_WRITE_CHECKPOINT_MIN_INTERVAL = 1000L * 1000L * 300L; // 5min static const int64_t MIN_WRITE_CHECKPOINT_LOG_CNT = 50000; // TODO(fenggu) - explicit ObWriteCheckpointTask(ObTenantCheckpointSlogHandler *handler) : handler_(handler) {} + explicit ObWriteCheckpointTask(ObTenantCheckpointSlogHandler *handler) : handler_(handler) + { + disable_timeout_check(); + } virtual ~ObWriteCheckpointTask() = default; virtual void runTimerTask() override; @@ -68,41 +100,80 @@ public: void wait(); void destroy(); + int report_slog(const ObTabletMapKey &tablet_key, const ObMetaDiskAddr &slog_addr); + int check_slog(const ObTabletMapKey &tablet_key, bool &has_slog); int read_tablet_checkpoint_by_addr( const ObMetaDiskAddr &addr, char *item_buf, int64_t &item_buf_len); int get_meta_block_list(common::ObIArray &block_list); + ObSharedBlockReaderWriter &get_shared_block_reader_writer() { return shared_block_rwriter_; } virtual int replay(const ObRedoModuleReplayParam ¶m) override; virtual int replay_over() override; int write_checkpoint(bool is_force); - int read_from_disk_addr(const ObMetaDiskAddr &phy_addr, char *buf, const int64_t buf_len, char *&r_buf, int64_t &r_len); + int read_from_disk( + const ObMetaDiskAddr &addr, + common::ObArenaAllocator &allocator, + char *&buf, + int64_t &buf_len); private: + int get_cur_cursor(); + void clean_copy_status(); virtual int parse(const int32_t cmd, const char *buf, const int64_t len, FILE *stream) override; int replay_checkpoint_and_slog(const ObTenantSuperBlock &super_block); int replay_checkpoint(const ObTenantSuperBlock &super_block); + int replay_new_checkpoint(const ObTenantSuperBlock &super_block); + int replay_old_checkpoint(const ObTenantSuperBlock &super_block); + int replay_new_tablet_checkpoint( + const blocksstable::MacroBlockId &tablet_entry_block, + common::ObIArray &tablet_block_list); int replay_ls_meta(const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len); int replay_tablet(const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len); - int replay_dup_table_ls_meta(const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len); - int update_tablet_meta_addr_and_block_list(ObTenantStorageCheckpointWriter &ckpt_writer); + int update_tablet_meta_addr_and_block_list( + const bool is_replay_old, ObTenantStorageCheckpointWriter &ckpt_writer); + int replay_dup_table_ls_meta(const transaction::ObDupTableLSCheckpoint::ObLSDupTableMeta &dup_ls_meta); int replay_tenant_slog(const common::ObLogCursor &start_point); int replay_load_tablets(); - int inner_replay_update_ls_slog(const ObRedoModuleReplayParam ¶m); int inner_replay_create_ls_slog(const ObRedoModuleReplayParam ¶m); int inner_replay_create_ls_commit_slog(const ObRedoModuleReplayParam ¶m); int inner_replay_delete_ls(const ObRedoModuleReplayParam ¶m); + int inner_replay_put_old_tablet(const ObRedoModuleReplayParam ¶m); + int inner_replay_update_tablet(const ObRedoModuleReplayParam ¶m); int inner_replay_dup_table_ls_slog(const ObRedoModuleReplayParam ¶m); - int inner_replay_put_tablet(const ObRedoModuleReplayParam ¶m); int inner_replay_delete_tablet(const ObRedoModuleReplayParam ¶m); + int inner_replay_empty_shell_tablet(const ObRedoModuleReplayParam ¶m); int inner_replay_gts_record(const ObRedoModuleReplayParam ¶m); int inner_replay_gti_record(const ObRedoModuleReplayParam ¶m); int inner_replay_das_record(const ObRedoModuleReplayParam ¶m); int get_tablet_svr(const share::ObLSID &ls_id, ObLSTabletService *&ls_tablet_svr, ObLSHandle &ls_handle); + int read_from_disk_addr(const ObMetaDiskAddr &phy_addr, char *buf, const int64_t buf_len, char *&r_buf, int64_t &r_len); + int read_from_share_blk(const ObMetaDiskAddr &addr, common::ObArenaAllocator &allocator, char *&buf, int64_t &buf_len); int read_from_ckpt(const ObMetaDiskAddr &phy_addr, char *buf, const int64_t buf_len, int64_t &r_len); int read_from_slog(const ObMetaDiskAddr &phy_addr, char *buf, const int64_t buf_len, int64_t &pos); + int read_empty_shell_file(const ObMetaDiskAddr &phy_addr, common::ObArenaAllocator &allocator, char *&buf, int64_t &buf_len); int remove_tablets_from_replay_map_(const share::ObLSID &ls_id); + int inner_replay_deserialize( + const char *buf, + const int64_t buf_len, + bool allow_override /* allow to overwrite the map's element or not */); + int inner_replay_old_deserialize( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + bool allow_override /* allow to overwrite the map's element or not */); + int record_ls_transfer_info( + const ObLSHandle &ls_handle, + const ObTabletID &tablet_id, + const ObTabletTransferInfo &tablet_transfer_info); + int check_is_need_record_transfer_info( + const share::ObLSID &src_ls_id, + const share::SCN &transfer_start_scn, + bool &is_need); + +private: + const static int64_t BUCKET_NUM = 109; private: typedef common::hash::ObHashMap ReplayTabletDiskAddrMap; bool is_inited_; @@ -110,12 +181,17 @@ private: int64_t last_ckpt_time_; int64_t last_frozen_version_; common::TCRWLock lock_; // protect block_handle + lib::ObMutex mutex_; + common::hash::ObHashSet tablet_key_set_; + bool is_copying_tablets_; + ObLogCursor ckpt_cursor_; ObMetaBlockListHandle ls_block_handle_; ObMetaBlockListHandle tablet_block_handle_; int tg_id_; ObWriteCheckpointTask write_ckpt_task_; ReplayTabletDiskAddrMap replay_tablet_disk_addr_map_; + ObSharedBlockReaderWriter shared_block_rwriter_; }; } // end namespace storage diff --git a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.cpp b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.cpp index bf79872d4..4cb88d4c2 100644 --- a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.cpp +++ b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.cpp @@ -45,7 +45,6 @@ int ObTenantStorageCheckpointReader::iter_read_checkpoint_item(const MacroBlockI char *item_buf = nullptr; int64_t item_buf_len = 0; ObMetaDiskAddr addr; - int64_t idx = 0; while (OB_SUCC(ret)) { if (OB_FAIL(item_reader.get_next_item(item_buf, item_buf_len, addr))) { if (OB_ITER_END != ret) { diff --git a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.cpp b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.cpp old mode 100644 new mode 100755 index fcd8dc863..8335fc1fb --- a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.cpp +++ b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.cpp @@ -15,7 +15,6 @@ #include "storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.h" #include "share/rc/ob_tenant_base.h" #include "storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h" -#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" #include "storage/slog/ob_storage_log_reader.h" #include "storage/slog/ob_storage_logger.h" #include "storage/tablet/ob_tablet_iterator.h" @@ -24,6 +23,8 @@ #include "storage/tx/ob_dup_table_base.h" #include "storage/tx_storage/ob_ls_service.h" #include "sql/das/ob_das_id_service.h" +#include "storage/tablet/ob_tablet_persister.h" +#include "storage/blockstore/ob_shared_block_reader_writer.h" namespace oceanbase { @@ -35,11 +36,8 @@ using namespace oceanbase::blocksstable; ObTenantStorageCheckpointWriter::ObTenantStorageCheckpointWriter() : is_inited_(false), - allocator_(), tablet_item_addr_info_arr_(), - ls_id_set_(), ls_item_writer_(), - dup_ls_item_writer_(), tablet_item_writer_() { } @@ -47,17 +45,9 @@ ObTenantStorageCheckpointWriter::ObTenantStorageCheckpointWriter() int ObTenantStorageCheckpointWriter::init() { int ret = OB_SUCCESS; - const int64_t MEM_LIMIT = 128 << 20; // 128M - const char *MEM_LABEL = "TenantStorageCheckpointWriter"; - if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("ObTenantStorageCheckpointWriter init twice", K(ret)); - } else if (OB_FAIL(allocator_.init( - common::OB_MALLOC_NORMAL_BLOCK_SIZE, MEM_LABEL, MTL_ID(), MEM_LIMIT))) { - LOG_WARN("fail to init allocator_", K(ret)); - } else if (OB_FAIL(ls_id_set_.create(128))) { - LOG_WARN("fail to crete ls id set", K(ret)); } else { is_inited_ = true; } @@ -67,11 +57,8 @@ int ObTenantStorageCheckpointWriter::init() void ObTenantStorageCheckpointWriter::reset() { is_inited_ = false; - allocator_.reset(); tablet_item_addr_info_arr_.reset(); - ls_id_set_.clear(); ls_item_writer_.reset(); - dup_ls_item_writer_.reset(); tablet_item_writer_.reset(); } @@ -83,19 +70,14 @@ int ObTenantStorageCheckpointWriter::write_checkpoint(ObTenantSuperBlock &super_ ret = OB_NOT_INIT; LOG_WARN("ObTenantStorageCheckpointWriter not inited", K(ret)); } else if (OB_FAIL(write_ls_checkpoint(super_block.ls_meta_entry_))) { - LOG_WARN("fail to write_ls_checkpoint", K(ret)); - } else if (OB_FAIL(write_tablet_checkpoint(super_block.replay_start_point_, - super_block.tablet_meta_entry_))) { - LOG_WARN("fail to write_tablet_checkpoint", K(ret)); - } else if (OB_FAIL(write_ls_dup_table_checkpoint(super_block.ls_dup_table_entry_))) { - LOG_WARN("fail to write dup_table ls checkpoint", K(ret)); + LOG_WARN("fail to construct ls ckpt linked list", K(ret)); } else if (OB_FAIL(THE_IO_DEVICE->fsync_block())) { LOG_WARN("fail to fsync_block", K(ret)); } return ret; } -int ObTenantStorageCheckpointWriter::write_ls_checkpoint(blocksstable::MacroBlockId &entry_block) +int ObTenantStorageCheckpointWriter::write_ls_checkpoint(MacroBlockId &ls_entry_block) { int ret = OB_SUCCESS; common::ObSharedGuard ls_iter; @@ -103,16 +85,15 @@ int ObTenantStorageCheckpointWriter::write_ls_checkpoint(blocksstable::MacroBloc char *buf = nullptr; int64_t buf_len = 0; int64_t pos = 0; - ObLSMeta ls_meta; + ObLSCkptMember ls_ckpt_member; int64_t count = 0; ls_item_writer_.reset(); - if (OB_FAIL(ls_id_set_.clear())) { - LOG_WARN("fail to clear ls id set", K(ret)); - } else if (OB_FAIL(MTL(ObLSService *)->get_ls_iter(ls_iter, ObLSGetMod::STORAGE_MOD))) { + tablet_item_writer_.reset(); + if (OB_FAIL(MTL(ObLSService *)->get_ls_iter(ls_iter, ObLSGetMod::STORAGE_MOD))) { LOG_WARN("failed to get log stream iter", K(ret)); - } else if (OB_FAIL(ls_item_writer_.init(false /*no need addr*/))) { - LOG_WARN("failed to init logs tream item writer", K(ret)); + } else if (OB_FAIL(ls_item_writer_.init(false /*whether need addr*/))) { + LOG_WARN("failed to init log stream item writer", K(ret)); } else { while (OB_SUCC(ret)) { if (OB_FAIL(ls_iter->get_next(ls))) { @@ -126,265 +107,151 @@ int ObTenantStorageCheckpointWriter::write_ls_checkpoint(blocksstable::MacroBloc if (OB_SUCC(ret)) { ObLSLockGuard lock_ls(ls); - if (OB_FAIL(ls->get_ls_meta(ls_meta))) { - LOG_WARN("fail to get_ls_meta", K(ret)); + if (OB_FAIL(ls->get_ls_meta(ls_ckpt_member.ls_meta_))) { + LOG_WARN("fail to get ls meta", K(ret)); + } else if (OB_FAIL(ls->get_dup_table_ls_meta(ls_ckpt_member.dup_ls_meta_))) { + LOG_WARN("fail to get dup ls meta", K(ret)); } } if (OB_FAIL(ret)) { // do nothing + } else if (OB_FAIL(write_tablet_checkpoint(*ls, ls_ckpt_member.tablet_meta_entry_))) { + LOG_WARN("fail to write tablet checkpoint for this ls", K(ret), KPC(ls)); } else { - count++; - buf_len = ls_meta.get_serialize_size(); + buf_len = ls_ckpt_member.get_serialize_size(); pos = 0; - if (OB_ISNULL(buf = static_cast(allocator_.alloc(buf_len)))) { + if (OB_ISNULL(buf = static_cast(ob_malloc(buf_len, "SlogCkptWriter")))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate memory", K(ret)); - } else if (OB_FAIL(ls_meta.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize", K(ret)); - } else if (OB_FAIL(ls_item_writer_.write_item(buf, buf_len, nullptr))) { - LOG_WARN("fail to write log stream item", K(ret)); - } else if (OB_FAIL(ls_id_set_.set_refactored(ls_meta.ls_id_))) { - LOG_WARN("fail to set ls id", K(ret), K(ls_meta)); - } - - if (OB_LIKELY(nullptr != buf)) { - allocator_.free(buf); - } - } - } - - if (OB_SUCC(ret)) { - if (OB_FAIL(ls_item_writer_.close())) { - LOG_WARN("fail to close log stream item writer", K(ret)); - } else if (OB_FAIL(ls_item_writer_.get_entry_block(entry_block))) { - LOG_WARN("fail to get entry block", K(ret)); - } - } - - } - - LOG_INFO("write ls checkpoint finish", K(ret), K(count), K(entry_block)); - - return ret; -} - -int ObTenantStorageCheckpointWriter::write_ls_dup_table_checkpoint(blocksstable::MacroBlockId &entry_block) -{ - int ret = OB_SUCCESS; - - common::ObSharedGuard ls_iter; - ObLS *ls = nullptr; - char *buf = nullptr; - int64_t buf_len = 0; - int64_t pos = 0; - int64_t count = 0; - - transaction::ObDupTableLSCheckpoint::ObLSDupTableMeta dup_ls_meta; - - dup_ls_item_writer_.reset(); - if (OB_FAIL(MTL(ObLSService *)->get_ls_iter(ls_iter, ObLSGetMod::STORAGE_MOD))) { - LOG_WARN("failed to get log stream iter", K(ret)); - } else if (OB_FAIL(dup_ls_item_writer_.init(false /*no need addr*/))) { - LOG_WARN("failed to init logs tream item writer", K(ret)); - } else { - while (OB_SUCC(ret)) { - if (OB_FAIL(ls_iter->get_next(ls))) { - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - break; + } else if (OB_FAIL(ls_ckpt_member.serialize(buf, buf_len, pos))) { + LOG_WARN("fail to serialize ls ckpt member", K(ret), KP(buf), K(buf_len), K(pos)); + } else if (OB_FAIL(ls_item_writer_.write_item(buf, buf_len, nullptr /*item idx*/))) { + LOG_WARN("fail to write ls ckpt item", K(ret), KP(buf), K(buf_len)); } else { - LOG_WARN("fail to get next log stream", K(ret)); + count++; } - } - - if (OB_SUCC(ret)) { - if (OB_FAIL(ls->get_dup_table_ls_meta(dup_ls_meta))) { - LOG_WARN("fail to get_ls_meta", K(ret)); - } - } - - if (OB_FAIL(ret)) { - // do nothing - } else { - count++; - buf_len = dup_ls_meta.get_serialize_size(); - pos = 0; - if (OB_ISNULL(buf = static_cast(allocator_.alloc(buf_len)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to allocate memory", K(ret)); - } else if (OB_FAIL(dup_ls_meta.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize", K(ret)); - } else if (OB_FAIL(dup_ls_item_writer_.write_item(buf, buf_len, nullptr))) { - LOG_WARN("fail to write log stream item", K(ret)); - } - if (OB_LIKELY(nullptr != buf)) { - allocator_.free(buf); + ob_free(buf); } } } - if (OB_SUCC(ret)) { - if (OB_FAIL(dup_ls_item_writer_.close())) { - LOG_WARN("fail to close log stream item writer", K(ret)); - } else if (OB_FAIL(dup_ls_item_writer_.get_entry_block(entry_block))) { - LOG_WARN("fail to get entry block", K(ret)); - } + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(ls_item_writer_.close())) { + LOG_WARN("fail to close ls item writer", K(ret)); + } else if (OB_FAIL(ls_item_writer_.get_entry_block(ls_entry_block))) { + LOG_WARN("fail to get ls entry block", K(ret)); } - } - LOG_INFO("write ls dup_table checkpoint finish", K(ret), K(count), K(entry_block)); + LOG_INFO("write ls checkpoint finish", K(ret), K(count), K(ls_entry_block)); return ret; } int ObTenantStorageCheckpointWriter::write_tablet_checkpoint( - const common::ObLogCursor &cursor, blocksstable::MacroBlockId &entry_block) + ObLS &ls, MacroBlockId &tablet_meta_entry) { int ret = OB_SUCCESS; - ObMetaDiskAddr addr; - int64_t item_idx = -1; - TabletItemAddrInfo addr_info; - ObLSHandle ls_handle; - ObLS *ls = nullptr; - ObLSTabletIterator tablet_iter; + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_READABLE_COMMITED); ObTabletMapKey tablet_key; + bool has_slog = false; + char slog_buf[sizeof(ObUpdateTabletLog)]; - tablet_item_writer_.reset(); - if (OB_FAIL(tablet_item_writer_.init(true /*need addr*/))) { + tablet_item_writer_.reuse_for_next_round(); + if (OB_FAIL(tablet_item_writer_.init(false /*whether need addr*/))) { LOG_WARN("failed to init tablet item writer", K(ret)); + } else if (OB_FAIL(ls.get_tablet_svr()->build_tablet_iter(tablet_iter))) { + LOG_WARN("fail to build ls tablet iter", K(ret), K(ls)); } - for (hash::ObHashSet::const_iterator it = ls_id_set_.begin(); - OB_SUCC(ret) && it != ls_id_set_.end(); it++) { - if (OB_FAIL(MTL(ObLSService *)->get_ls(it->first, ls_handle, ObLSGetMod::STORAGE_MOD))) { - if (OB_LS_NOT_EXIST == ret) { // ls maybe delete when write tablet checkpoint + while (OB_SUCC(ret)) { + if (OB_FAIL(tablet_iter.get_next_tablet_addr(tablet_key, addr))) { + if (OB_ITER_END == ret) { ret = OB_SUCCESS; - continue; + break; } else { - LOG_WARN("fail to get ls", K(ret), "ls_id", it->first); + LOG_WARN("fail to get next tablet", K(ret)); } - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + } else if (OB_UNLIKELY(!tablet_key.is_valid() || !addr.is_valid())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is nullptr", K(ret), "ls_id", it->first); - } else if (OB_FAIL(ls->get_tablet_svr()->build_tablet_iter(tablet_iter))) { - LOG_WARN("fail to build ls tablet iter", K(ret), "ls_id", it->first); - } - - while (OB_SUCC(ret)) { - if (OB_FAIL(tablet_iter.get_next_tablet_addr(tablet_key, addr))) { - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - break; - } else { - LOG_WARN("fail to get next item", K(ret)); - } - } else if (addr.is_file() && (addr.file_id() > cursor.file_id_ || - (addr.file_id() == cursor.file_id_ && addr.offset() >= cursor.offset_))) { - // no need copy if addr exceeds the replay cursor - LOG_INFO("skip copy tablet", K(cursor), K(addr), K(tablet_key)); - } else if (addr.is_memory()) { - FLOG_INFO("skip MEM type", K(ret), K(tablet_key), K(addr)); - } else if (OB_FAIL(copy_one_tablet_item(tablet_item_writer_, addr, &item_idx))) { - LOG_WARN("fail to copy_one_tablet_item", K(ret), K(tablet_key), K(addr)); - } else { - addr_info.tablet_key_ = tablet_key; - addr_info.item_idx_ = item_idx; - addr_info.old_addr_ = addr; - if (OB_FAIL(tablet_item_addr_info_arr_.push_back(addr_info))) { - LOG_WARN("fail to push back addr info", K(ret)); - } - } - } - } - - if (OB_SUCC(ret)) { - if (OB_FAIL(tablet_item_writer_.close())) { - LOG_WARN("fail to close tablet item writer", K(ret)); - } else if (OB_FAIL(tablet_item_writer_.get_entry_block(entry_block))) { - LOG_WARN("fail to get entry block", K(ret)); - } - } - - const int64_t tablet_count = tablet_item_addr_info_arr_.count(); - - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_count; i++) { - TabletItemAddrInfo &addr_info = tablet_item_addr_info_arr_.at(i); - if (OB_FAIL( - tablet_item_writer_.get_item_disk_addr(addr_info.item_idx_, addr_info.new_addr_))) { - LOG_WARN("fail to get tablet item disk addr", K(ret), K(i), K(addr_info)); - } - } - - FLOG_INFO("write tablet checkpoint finish", K(ret), K(tablet_count), K(entry_block)); - - return ret; -} - -// copy tablet item from old addr to new checkpoint -int ObTenantStorageCheckpointWriter::copy_one_tablet_item( - ObLinkedMacroBlockItemWriter &tablet_item_writer, const ObMetaDiskAddr &addr, int64_t *item_idx) -{ - int ret = OB_SUCCESS; - ObTenantCheckpointSlogHandler *slog_handler = MTL(ObTenantCheckpointSlogHandler*); - char *item_buf = nullptr; - int64_t item_buf_len = 0; - char *buf = nullptr; - int64_t buf_len = 0; - int64_t pos = 0; - - if (OB_UNLIKELY(!addr.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(addr)); - } else if (OB_ISNULL(buf = static_cast(allocator_.alloc(addr.size())))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to allocate memory", K(ret)); - } else { - if (addr.is_none()) { - ret = OB_NEED_RETRY; // may be just write tablet slog and not update the addr yet + LOG_WARN("tablet key or addr is invalid", K(ret), K(tablet_key), K(addr)); + } else if (addr.is_memory()) { + FLOG_INFO("skip MEM type", K(ret), K(tablet_key), K(addr)); + } else if (addr.is_none()) { + ret = OB_NEED_RETRY; // tablet slog has been written, but the addr hasn't been updated LOG_WARN("addr is none", K(ret)); - } else if (addr.is_file()) { - if (OB_FAIL(read_tablet_from_slog(addr, buf, pos))) { - LOG_WARN("fail to read_tablet_from_slog", K(ret), K(addr)); - } else { - item_buf = buf + pos; - item_buf_len = addr.size() - pos; - } - } else if (addr.is_block()) { - if (OB_FAIL(slog_handler->read_tablet_checkpoint_by_addr(addr, buf, buf_len))) { - LOG_WARN("fail to read_tablet_checkpoint_by_addr", K(ret), K(addr)); - } else { - item_buf = buf; - item_buf_len = buf_len; - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("invalid addr type", K(ret), K(addr)); + } else if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->check_slog(tablet_key, has_slog))) { + LOG_WARN("fail to check whether tablet has been written slog", K(ret), K(tablet_key)); + } else if (!has_slog && OB_FAIL(copy_one_tablet_item(tablet_key, addr, slog_buf))) { + LOG_WARN("fail to copy_one_tablet_item", K(ret), K(tablet_key), K(addr)); } } if (OB_FAIL(ret)) { - } else if (OB_FAIL(tablet_item_writer.write_item(item_buf, item_buf_len, item_idx))) { - LOG_WARN("fail to write tablet item", K(ret)); - } - - if (OB_LIKELY(nullptr != buf)) { - allocator_.free(buf); + // do nothing + } else if (OB_FAIL(tablet_item_writer_.close())) { + LOG_WARN("fail to close tablet item writer", K(ret)); + } else if (OB_FAIL(tablet_item_writer_.get_entry_block(tablet_meta_entry))) { + LOG_WARN("fail to get tablet meta entry", K(ret)); } + FLOG_INFO("write tablet checkpoint finish", K(ret), K(tablet_item_addr_info_arr_.count()), K(tablet_meta_entry)); return ret; } -int ObTenantStorageCheckpointWriter::read_tablet_from_slog( - const ObMetaDiskAddr &addr, char *buf, int64_t &pos) +int ObTenantStorageCheckpointWriter::copy_one_tablet_item( + const ObTabletMapKey &tablet_key, + const ObMetaDiskAddr &old_addr, + char *slog_buf) { int ret = OB_SUCCESS; + ObArenaAllocator allocator("SlogCkptWriter"); + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObLSService *ls_service = MTL(ObLSService*); + ObLSHandle ls_handle; + ObTabletHandle old_tablet_handle; + ObTabletHandle new_tablet_handle; + ObTablet *old_tablet = nullptr; + ObTablet *new_tablet = nullptr; + int64_t slog_buf_pos = 0; + MEMSET(slog_buf, 0, sizeof(ObUpdateTabletLog)); + ObUpdateTabletLog slog; + slog.ls_id_ = tablet_key.ls_id_; + slog.tablet_id_ = tablet_key.tablet_id_; - if (OB_FAIL(ObStorageLogReader::read_log(MTL(ObStorageLogger *)->get_dir(), - addr, addr.size(), buf, pos, MTL_ID()))) { - LOG_WARN("fail to read slog", K(ret)); + if (OB_FAIL(OB_E(EventTable::EN_SLOG_CKPT_ERROR) OB_SUCCESS)) { + } else if (OB_FAIL(t3m->get_tablet_with_allocator(WashTabletPriority::WTP_LOW, tablet_key, allocator, old_tablet_handle))) { + if (OB_ENTRY_NOT_EXIST == ret) { + // skip write this tablet's checkpoint + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get tablet with allocator", K(ret), K(tablet_key)); + } + } else if (FALSE_IT(old_tablet = old_tablet_handle.get_obj())) { + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*old_tablet, new_tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), K(tablet_key), KPC(old_tablet)); + } else if (FALSE_IT(new_tablet = new_tablet_handle.get_obj())) { + } else if (FALSE_IT(slog.disk_addr_ = new_tablet->get_tablet_addr())) { + } else if (OB_FAIL(slog.serialize(slog_buf, sizeof(ObUpdateTabletLog), slog_buf_pos))) { + LOG_WARN("fail to serialize update tablet slog", K(ret), K(slog_buf_pos)); + } else if (OB_FAIL(tablet_item_writer_.write_item(slog_buf, slog.get_serialize_size()))) { + LOG_WARN("fail to write update tablet slog into ckpt", K(ret)); + } else if (OB_FAIL(new_tablet->inc_macro_ref_cnt())) { + LOG_WARN("fail to increase meta and data macro blocks' ref cnt", K(ret)); + } else { + TabletItemAddrInfo addr_info; + addr_info.tablet_key_ = tablet_key; + addr_info.old_addr_ = old_addr; + addr_info.new_addr_ = slog.disk_addr_; + addr_info.need_rollback_ = true; + if (OB_FAIL(ObTenantMetaMemMgr::get_tablet_pool_type(new_tablet_handle.get_buf_len(), addr_info.tablet_pool_type_))) { + LOG_WARN("fail to get tablet pool type", K(ret), K(addr_info)); + } else if (OB_FAIL(tablet_item_addr_info_arr_.push_back(addr_info))) { + LOG_WARN("fail to push back addr info", K(ret), K(addr_info)); + } } return ret; @@ -403,19 +270,6 @@ int ObTenantStorageCheckpointWriter::get_ls_block_list(common::ObIArray *&block_list) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("ObTenantStorageCheckpointWriter not inited", K(ret)); - } else { - ObIArray &ls_block_list = dup_ls_item_writer_.get_meta_block_list(); - block_list = &ls_block_list; - } - return ret; -} - int ObTenantStorageCheckpointWriter::get_tablet_block_list( common::ObIArray *&block_list) { @@ -430,7 +284,7 @@ int ObTenantStorageCheckpointWriter::get_tablet_block_list( return ret; } -int ObTenantStorageCheckpointWriter::update_tablet_meta_addr() +int ObTenantStorageCheckpointWriter::batch_compare_and_swap_tablet(const bool is_replay_old) { int ret = OB_SUCCESS; @@ -439,26 +293,187 @@ int ObTenantStorageCheckpointWriter::update_tablet_meta_addr() LOG_WARN("ObTenantStorageCheckpointWriter not init", K(ret)); } ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr *); + ObTabletHandle new_tablet_handle; + ObLSHandle ls_handle; + ObLSService *ls_svr = nullptr; for (int64_t i = 0; OB_SUCC(ret) && i < tablet_item_addr_info_arr_.count(); i++) { - const TabletItemAddrInfo &addr_info = tablet_item_addr_info_arr_.at(i); - if (OB_FAIL(t3m->compare_and_swap_tablet_pure_address_without_object( - addr_info.tablet_key_, addr_info.old_addr_, addr_info.new_addr_))) { - if (OB_NOT_THE_OBJECT == ret) { // addr may be change, ignore - LOG_INFO("tablet addr changed when update_tablet_meta_addr", K(ret), K(addr_info)); - ret = OB_SUCCESS; - } else if (OB_ENTRY_NOT_EXIST == ret) { // may be deleted ignore - LOG_INFO("tablet not exist when update_tablet_meta_addr", K(ret), K(addr_info)); - ret = OB_SUCCESS; + TabletItemAddrInfo &addr_info = tablet_item_addr_info_arr_.at(i); + ObMetaDiskAddr tablet_addr; + if (OB_FAIL(t3m->get_tablet_addr(addr_info.tablet_key_, tablet_addr))) { + // OB_ENTRY_NOT_EXIST is not allowed during upgrade + if (OB_ENTRY_NOT_EXIST != ret || is_replay_old) { + LOG_WARN("fail to get tablet addr", K(ret), K(addr_info)); } else { - LOG_WARN("fail to update_tablet_meta_addr", K(ret), K(addr_info)); - break; + ret = OB_SUCCESS; + LOG_INFO("this tablet has been deleted, skip the swap", K(addr_info)); } + } else if (OB_ISNULL(ls_svr = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service is null", K(ret)); + } else if (OB_FAIL(ls_svr->get_ls(addr_info.tablet_key_.ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get ls", K(ret), K(addr_info)); + } else if (!is_replay_old) { + if (OB_FAIL(get_tablet_with_addr(addr_info, new_tablet_handle))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to load tablet", K(ret), K(addr_info)); + } else { + ret = OB_SUCCESS; + LOG_INFO("this tablet has been deleted, skip the swap", K(addr_info)); + } + } else if (FALSE_IT(addr_info.need_rollback_ = false)) { + } else if (!tablet_addr.is_equal_for_persistence(addr_info.old_addr_)) { // ignore the change of memtable seq + // we must check the addr after loading tablet, otherwise the macro ref cnt won't be decreased + LOG_INFO("the tablet has changed, skip the swap", K(tablet_addr), K(addr_info)); + } else { + do { + if (OB_FAIL(ls_handle.get_ls()->update_tablet_checkpoint( + addr_info.tablet_key_, + addr_info.old_addr_, + addr_info.new_addr_, + is_replay_old, + new_tablet_handle))) { + if (OB_NOT_THE_OBJECT == ret) { + ret = OB_SUCCESS; + LOG_INFO("tablet has changed, no need to swap", K(ret), K(addr_info)); + } else if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("tablet has been deleted, no need to swap", K(ret), K(addr_info)); + } else { + LOG_WARN("fail to compare and swap tablet with seq check", K(ret), K(addr_info)); + } + } + } while (ignore_ret(ret)); + } + } else { + addr_info.need_rollback_ = false; + do { + ObArenaAllocator allocator("CompatLoad"); + ObTabletHandle old_tablet_handle; + if (OB_FAIL(t3m->get_tablet_with_allocator( + WashTabletPriority::WTP_LOW, addr_info.tablet_key_, allocator, old_tablet_handle))) { + LOG_WARN("fail to get tablet with allocator", K(ret), K(addr_info)); + } else if (OB_FAIL(ls_handle.get_ls()->update_tablet_checkpoint( + addr_info.tablet_key_, + addr_info.old_addr_, + addr_info.new_addr_, + is_replay_old, + new_tablet_handle))) { + LOG_WARN("fail to compare and swap tablet with seq check", K(ret), K(addr_info)); + } else { + old_tablet_handle.get_obj()->dec_macro_ref_cnt(); + } + } while (ignore_ret(ret)); } } return ret; } +bool ObTenantStorageCheckpointWriter::ignore_ret(int ret) +{ + return OB_ALLOCATE_MEMORY_FAILED == ret || OB_DISK_HUNG == ret || OB_TIMEOUT == ret; +} + +int ObTenantStorageCheckpointWriter::rollback() +{ + int ret = OB_SUCCESS; + int64_t rollback_cnt = 0; + if (!is_inited_ || 0 == tablet_item_addr_info_arr_.count()) { + // there's no new tablet, no need to rollback + } else { + ObArenaAllocator allocator("CkptRollback"); + for (int64_t i = 0; i < tablet_item_addr_info_arr_.count(); i++) { + allocator.reuse(); + const TabletItemAddrInfo &addr_info = tablet_item_addr_info_arr_.at(i); + if (addr_info.need_rollback_) { + rollback_cnt++; + do { + if (OB_FAIL(do_rollback(allocator, addr_info.new_addr_))) { + if (OB_ALLOCATE_MEMORY_FAILED != ret) { + LOG_ERROR("fail to rollback ref cnt", K(ret), K(addr_info)); + } else if (REACH_TIME_INTERVAL(1000 * 1000L)) { // 1s + LOG_ERROR("fail to rollback ref cnt due to memory limit", K(ret), K(addr_info)); + } + } + } while (OB_ALLOCATE_MEMORY_FAILED == ret); + } + } + } + FLOG_INFO("finsh checkpoint rollback", K(ret), K(tablet_item_addr_info_arr_.count()), K(rollback_cnt)); + return ret; +} + +int ObTenantStorageCheckpointWriter::do_rollback( + common::ObArenaAllocator &allocator, + const ObMetaDiskAddr &load_addr) +{ + int ret = OB_SUCCESS; + ObTablet tablet; + ObSharedBlockReadInfo read_info; + ObSharedBlockReadHandle block_handle; + int64_t buf_len; + char *buf = nullptr; + int64_t pos = 0; + read_info.addr_ = load_addr; + read_info.io_desc_.set_wait_event(ObWaitEventIds::SLOG_CKPT_LOCK_WAIT); + + if (OB_FAIL(ObSharedBlockReaderWriter::async_read(read_info, block_handle))) { + LOG_WARN("fail to read tablet buf from macro block", K(ret), K(read_info)); + } else if (OB_FAIL(block_handle.wait())) { + LOG_WARN("fail to wait async read", K(ret)); + } else if (OB_FAIL(block_handle.get_data(allocator, buf, buf_len))) { + LOG_WARN("fail to get tablet buf and buf_len", K(ret), K(block_handle)); + } else if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("data of block handle is invalid", K(ret), K(block_handle)); + } else if (FALSE_IT(tablet.set_tablet_addr(load_addr))) { + } else if (OB_FAIL(tablet.rollback_ref_cnt(allocator, buf, buf_len, pos))) { + LOG_WARN("fail to rollback ref cnt", K(ret), KP(buf), K(buf_len), K(pos)); + } + + return ret; +} + +int ObTenantStorageCheckpointWriter::get_tablet_with_addr( + const TabletItemAddrInfo &addr_info, + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + + ObSharedBlockReadInfo read_info; + int64_t buf_len; + char *buf = nullptr; + int64_t pos = 0; + read_info.addr_ = addr_info.new_addr_; + read_info.io_desc_.set_wait_event(ObWaitEventIds::SLOG_CKPT_LOCK_WAIT); + + do { + ObArenaAllocator allocator("SlogCkptWriter"); + ObSharedBlockReadHandle block_handle; + if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->acquire_tablet_from_pool( + addr_info.tablet_pool_type_, + WashTabletPriority::WTP_LOW, + addr_info.tablet_key_, + tablet_handle))) { + LOG_WARN("fail to acquire 4k tablet", K(ret), K(addr_info)); + } else if (OB_FAIL(ObSharedBlockReaderWriter::async_read(read_info, block_handle))) { + LOG_WARN("fail to read tablet buf from macro block", K(ret), K(read_info)); + } else if (OB_FAIL(block_handle.wait())) { + LOG_WARN("fail to wait async read", K(ret)); + } else if (OB_FAIL(block_handle.get_data(allocator, buf, buf_len))) { + LOG_WARN("fail to get tablet buf and buf_len", K(ret), K(block_handle)); + } else if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("data of block handle is invalid", K(ret), K(block_handle)); + } else if (FALSE_IT(tablet_handle.get_obj()->set_tablet_addr(addr_info.new_addr_))) { + } else if (OB_FAIL(tablet_handle.get_obj()->deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize tiny tablet", K(ret), K(block_handle), K(addr_info), K(pos)); + } + } while (ignore_ret(ret)); + + return ret; +} + } // namespace storage } // end namespace oceanbase diff --git a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.h b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.h index faaf09b0e..e16bcc281 100644 --- a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.h +++ b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.h @@ -16,12 +16,13 @@ #include "storage/slog_ckpt/ob_linked_macro_block_writer.h" #include "storage/ob_super_block_struct.h" #include "storage/meta_mem/ob_tablet_map_key.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" namespace oceanbase { namespace storage { - +class ObSharedBlockReaderWriter; class ObTenantStorageCheckpointWriter final { public: @@ -34,43 +35,48 @@ public: void reset(); int write_checkpoint(ObTenantSuperBlock &super_block); int get_ls_block_list(common::ObIArray *&block_list); - int get_dup_ls_block_list(common::ObIArray *&block_list); int get_tablet_block_list(common::ObIArray *&block_list); - - int update_tablet_meta_addr(); - + int batch_compare_and_swap_tablet(const bool is_replay_old); + int rollback(); private: struct TabletItemAddrInfo { ObTabletMapKey tablet_key_; - int64_t item_idx_; ObMetaDiskAddr old_addr_; ObMetaDiskAddr new_addr_; + ObTabletPoolType tablet_pool_type_; + bool need_rollback_; - TO_STRING_KV(K_(tablet_key), K_(item_idx), K_(old_addr), K_(new_addr)); + TabletItemAddrInfo() + : tablet_key_(), old_addr_(), new_addr_(), + tablet_pool_type_(ObTabletPoolType::TP_MAX), + need_rollback_(true) + { + } + + TO_STRING_KV(K_(tablet_key), K_(old_addr), K_(new_addr), K_(tablet_pool_type), K_(need_rollback)); }; - int write_ls_checkpoint(blocksstable::MacroBlockId &entry_block); - int write_ls_dup_table_checkpoint(blocksstable::MacroBlockId &entry_block); - int write_tablet_checkpoint(const common::ObLogCursor &cursor, blocksstable::MacroBlockId &entry_block); - int copy_one_tablet_item(ObLinkedMacroBlockItemWriter &tablet_item_writer, - const ObMetaDiskAddr &addr, int64_t *item_idx); - int read_tablet_from_slog(const ObMetaDiskAddr &addr, char *buf, int64_t &pos); + static bool ignore_ret(int ret); + int get_tablet_with_addr( + const TabletItemAddrInfo &addr_info, + ObTabletHandle &tablet_handle); + int do_rollback( + common::ObArenaAllocator &allocator, + const ObMetaDiskAddr &load_addr); + int write_ls_checkpoint(blocksstable::MacroBlockId &ls_entry_block); + int write_tablet_checkpoint(ObLS &ls, blocksstable::MacroBlockId &tablet_meta_entry); + int copy_one_tablet_item( + const ObTabletMapKey &tablet_key, + const ObMetaDiskAddr &old_addr, + char *slog_buf); private: bool is_inited_; - common::ObConcurrentFIFOAllocator allocator_; - common::ObArray tablet_item_addr_info_arr_; - - // record ls ids when make ls checkpoint to filter out unwanted tablets when making tablet checkpoint, - // this ensures that the ls of the tablet is replayed before than the tablet - common::hash::ObHashSet ls_id_set_; ObLinkedMacroBlockItemWriter ls_item_writer_; - ObLinkedMacroBlockItemWriter dup_ls_item_writer_; ObLinkedMacroBlockItemWriter tablet_item_writer_; - }; } // end namespace storage diff --git a/src/storage/tablelock/ob_lock_inner_connection_util.cpp b/src/storage/tablelock/ob_lock_inner_connection_util.cpp new file mode 100644 index 000000000..124e94c69 --- /dev/null +++ b/src/storage/tablelock/ob_lock_inner_connection_util.cpp @@ -0,0 +1,718 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX TABLELOCK + +#include "share/ob_errno.h" +#include "lib/oblog/ob_log_module.h" +#include "ob_lock_inner_connection_util.h" +#include "observer/ob_inner_sql_connection.h" +#include "observer/ob_inner_sql_result.h" +#include "storage/tablelock/ob_table_lock_rpc_struct.h" +#include "storage/tablelock/ob_table_lock_service.h" + + +using namespace oceanbase::observer; +using namespace oceanbase::obrpc; +namespace oceanbase +{ +namespace transaction +{ +namespace tablelock +{ + +#define __REQUEST_LOCK_CHECK_VERSION(v, T, operation_type, arg, conn) \ + { \ + int64_t pos = 0; \ + T lock_arg; \ + if (GET_MIN_CLUSTER_VERSION() < v) { \ + ret = OB_NOT_SUPPORTED; \ + LOG_WARN("cluster version check faild", KR(ret), K(v), K(GET_MIN_CLUSTER_VERSION())); \ + } else if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), \ + arg.get_inner_sql().length(), \ + pos))) { \ + LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); \ + } else if (OB_FAIL(request_lock_(arg.get_tenant_id(), \ + lock_arg, \ + operation_type, \ + conn))) { \ + LOG_WARN("request lock failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); \ + } \ + } + +#define REQUEST_LOCK_4_1(T, operation_type, arg, conn) \ + __REQUEST_LOCK_CHECK_VERSION(CLUSTER_VERSION_4_1_0_0, T, operation_type, arg, conn) + +#define REQUEST_LOCK_4_2(T, operation_type, arg, conn) \ + __REQUEST_LOCK_CHECK_VERSION(CLUSTER_VERSION_4_2_0_0, T, operation_type, arg, conn) + +int ObInnerConnectionLockUtil::process_lock_rpc( + const ObInnerSQLTransmitArg &arg, + sqlclient::ObISQLConnection *conn) +{ + int ret = OB_SUCCESS; + observer::ObInnerSQLConnection *inner_conn = static_cast(conn); + if (OB_ISNULL(conn)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(arg), KP(conn)); + } else { + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type = arg.get_operation_type(); + switch (operation_type) { + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: { + if (OB_FAIL(process_lock_table_(operation_type, + arg, + inner_conn))) { + LOG_WARN("process lock table failed", K(ret)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLE: { + REQUEST_LOCK_4_1(ObUnLockTableRequest, operation_type, arg, inner_conn); + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: { + if (OB_FAIL(process_lock_tablet_(operation_type, + arg, + inner_conn))) { + LOG_WARN("process lock tablet failed", K(ret)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLET: { + REQUEST_LOCK_4_1(ObUnLockTabletRequest, operation_type, arg, inner_conn); + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJ: { + REQUEST_LOCK_4_1(ObLockObjRequest, operation_type, arg, inner_conn); + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJ: { + REQUEST_LOCK_4_1(ObUnLockObjRequest, operation_type, arg, inner_conn); + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_PART: { + REQUEST_LOCK_4_1(ObLockPartitionRequest, operation_type, arg, inner_conn); + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_PART: { + REQUEST_LOCK_4_1(ObUnLockPartitionRequest, operation_type, arg, inner_conn); + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_SUBPART: { + REQUEST_LOCK_4_1(ObLockPartitionRequest, operation_type, arg, inner_conn); + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_SUBPART: { + REQUEST_LOCK_4_1(ObUnLockPartitionRequest, operation_type, arg, inner_conn); + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_ALONE_TABLET: { + REQUEST_LOCK_4_2(ObLockAloneTabletRequest, operation_type, arg, inner_conn); + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_ALONE_TABLET: { + REQUEST_LOCK_4_2(ObUnLockAloneTabletRequest, operation_type, arg, inner_conn); + break; + } + default: { + ret = OB_NOT_SUPPORTED; + LOG_WARN("Unknown operation type", K(ret), K(operation_type)); + break; + } + } + } + return ret; +} + +int ObInnerConnectionLockUtil::process_lock_table_( + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, + const ObInnerSQLTransmitArg &arg, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + ObTabletID no_used; + + if (GET_MIN_CLUSTER_VERSION() <= CLUSTER_VERSION_4_0_0_0) { + ObInTransLockTableRequest lock_arg; + if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { + LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); + } else { + // we can only rewrite the arg to new arg type at the execute place. + if (OB_FAIL(request_lock_(arg.get_tenant_id(), + lock_arg.table_id_, + no_used, + lock_arg.lock_mode_, + lock_arg.timeout_us_, + operation_type, + conn))) { + LOG_WARN("lock table failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); + } + } + } else { + REQUEST_LOCK_4_1(ObLockTableRequest, operation_type, arg, conn); + } + + return ret; +} + +int ObInnerConnectionLockUtil::process_lock_tablet_( + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, + const ObInnerSQLTransmitArg &arg, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + + if (GET_MIN_CLUSTER_VERSION() <= CLUSTER_VERSION_4_0_0_0) { + ObInTransLockTabletRequest lock_arg; + if (OB_FAIL(lock_arg.deserialize(arg.get_inner_sql().ptr(), arg.get_inner_sql().length(), pos))) { + LOG_WARN("deserialize multi source data str failed", K(ret), K(arg), K(pos)); + } else { + // we can only rewrite the argument at local. + if (OB_FAIL(request_lock_(arg.get_tenant_id(), + lock_arg.table_id_, + lock_arg.tablet_id_, + lock_arg.lock_mode_, + lock_arg.timeout_us_, + operation_type, + conn))) { + LOG_WARN("lock tablet failed", K(ret), K(arg.get_tenant_id()), K(lock_arg)); + } + } + } else { + REQUEST_LOCK_4_1(ObLockTabletRequest, operation_type, arg, conn); + } + + return ret; +} + +int ObInnerConnectionLockUtil::lock_table( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTableLockMode lock_mode, + const int64_t timeout_us, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + ObTabletID no_used; + if (GET_MIN_CLUSTER_VERSION() > CLUSTER_VERSION_4_0_0_0) { + ObLockTableRequest lock_arg; + lock_arg.owner_id_ = 0; + lock_arg.lock_mode_ = lock_mode; + lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; + lock_arg.timeout_us_ = timeout_us; + lock_arg.table_id_ = table_id; + + ret = request_lock_(tenant_id, lock_arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE, conn); + } else { + ret = request_lock_(tenant_id, table_id, no_used, lock_mode, timeout_us, + ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE, conn); + } + return ret; +} + +int ObInnerConnectionLockUtil::lock_table( + const uint64_t tenant_id, + const ObLockTableRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + return request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE, conn); +} + +int ObInnerConnectionLockUtil::unlock_table( + const uint64_t tenant_id, + const ObUnLockTableRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); + } else { + ret = request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLE, conn); + } + return ret; +} + +int ObInnerConnectionLockUtil::lock_partition( + const uint64_t tenant_id, + const ObLockPartitionRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + return request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_PART, conn); +} + +int ObInnerConnectionLockUtil::unlock_partition( + const uint64_t tenant_id, + const ObUnLockPartitionRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); + } else { + ret = request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_PART, conn); + } + return ret; +} + +int ObInnerConnectionLockUtil::lock_subpartition( + const uint64_t tenant_id, + const ObLockPartitionRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + return request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_SUBPART, conn); +} + +int ObInnerConnectionLockUtil::unlock_subpartition( + const uint64_t tenant_id, + const ObUnLockPartitionRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); + } else { + ret = request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_SUBPART, conn); + } + return ret; +} + +int ObInnerConnectionLockUtil::lock_tablet( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTabletID tablet_id, + const ObTableLockMode lock_mode, + const int64_t timeout_us, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + if (GET_MIN_CLUSTER_VERSION() > CLUSTER_VERSION_4_0_0_0) { + ObLockTabletRequest lock_arg; + lock_arg.owner_id_ = 0; + lock_arg.lock_mode_ = lock_mode; + lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; + lock_arg.timeout_us_ = timeout_us; + lock_arg.table_id_ = table_id; + lock_arg.tablet_id_ = tablet_id; + + ret = request_lock_(tenant_id, lock_arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET, conn); + } else { + // for 4.0 + ret = request_lock_(tenant_id, table_id, tablet_id, lock_mode, + timeout_us, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET, conn); + } + return ret; +} + +int ObInnerConnectionLockUtil::lock_tablet( + const uint64_t tenant_id, + const ObLockTabletRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + return request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET, conn); +} + +int ObInnerConnectionLockUtil::unlock_tablet( + const uint64_t tenant_id, + const ObUnLockTabletRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); + } else { + ret = request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLET, conn); + } + return ret; +} + +int ObInnerConnectionLockUtil::lock_tablet( + const uint64_t tenant_id, + const ObLockAloneTabletRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + return request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_ALONE_TABLET, conn); +} + +int ObInnerConnectionLockUtil::unlock_tablet( + const uint64_t tenant_id, + const ObUnLockAloneTabletRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); + } else { + ret = request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_ALONE_TABLET, conn); + } + return ret; +} + +int ObInnerConnectionLockUtil::lock_obj( + const uint64_t tenant_id, + const ObLockObjRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + return request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJ, conn); +} + +int ObInnerConnectionLockUtil::unlock_obj( + const uint64_t tenant_id, + const ObUnLockObjRequest &arg, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only OUT_TRANS_LOCK should unlock.", K(ret), K(arg)); + } else { + ret = request_lock_(tenant_id, arg, ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJ, conn); + } + return ret; +} + +int ObInnerConnectionLockUtil::do_obj_lock_( + const uint64_t tenant_id, + const ObLockRequest &arg, + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, + observer::ObInnerSQLConnection *conn, + observer::ObInnerSQLResult &res) +{ + int ret = OB_SUCCESS; + transaction::ObTxDesc *tx_desc = nullptr; + + if (OB_ISNULL(conn)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid conn", KR(ret)); + } else if (OB_ISNULL(tx_desc = conn->get_session().get_tx_desc())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid tx_desc"); + } else { + transaction::ObTxParam tx_param; + tx_param.access_mode_ = transaction::ObTxAccessMode::RW; + tx_param.isolation_ = conn->get_session().get_tx_isolation(); + tx_param.cluster_id_ = GCONF.cluster_id; + conn->get_session().get_tx_timeout(tx_param.timeout_us_); + tx_param.lock_timeout_us_ = conn->get_session().get_trx_lock_timeout(); + + MTL_SWITCH(tenant_id) { + switch (operation_type) { + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: { + const ObLockTableRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->lock_table(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("lock table failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLE: { + const ObUnLockTableRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->unlock_table(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("unlock table failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: { + const ObLockTabletRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->lock_tablet(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("lock tablet failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLET: { + const ObUnLockTabletRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->unlock_tablet(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("unlock tablet failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_PART: { + const ObLockPartitionRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->lock_partition(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("lock partition failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_PART: { + const ObUnLockPartitionRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->unlock_partition(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("unlock partition failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJ: { + const ObLockObjRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->lock_obj(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("lock object failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJ: { + const ObUnLockObjRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->unlock_obj(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("unlock object failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_SUBPART: { + const ObLockPartitionRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->lock_subpartition(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("lock subpartition failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_SUBPART: { + const ObUnLockPartitionRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->unlock_subpartition(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("unlock subpartition failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_ALONE_TABLET: { + const ObLockAloneTabletRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->lock_tablet(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("lock alone tablet failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_ALONE_TABLET: { + const ObUnLockAloneTabletRequest &lock_arg = static_cast(arg); + if (OB_FAIL(MTL(ObTableLockService*)->unlock_tablet(*tx_desc, + tx_param, + lock_arg))) { + LOG_WARN("unlock alone tablet failed", K(ret), K(tenant_id), K(lock_arg)); + } + break; + } + default: { + LOG_WARN("operation_type is not expected", K(operation_type)); + ret = OB_ERR_UNEXPECTED; + } // default + } // switch + if (OB_SUCC(ret) && OB_FAIL(res.close())) { + LOG_WARN("close result set failed", K(ret), K(tenant_id)); + } + } // MTL_SWITCH + } // else + return ret; +} + +int ObInnerConnectionLockUtil::request_lock_( + const uint64_t tenant_id, + const ObLockRequest &arg, + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + observer::ObReqTimeGuard req_timeinfo_guard; + + const bool local_execute = conn->is_local_execute(GCONF.cluster_id, tenant_id); + + SMART_VAR(ObInnerSQLResult, res, conn->get_session()) + { + if (OB_INVALID_ID == tenant_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id)); + } else if (local_execute) { + if (OB_FAIL(conn->switch_tenant(tenant_id))) { + LOG_WARN("set system tenant id failed", K(ret), K(tenant_id)); + } + } else { + LOG_DEBUG("tenant not in server", K(ret), K(tenant_id)); + } + + if (OB_SUCC(ret)) { + if (!conn->is_in_trans()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("inner conn must be already in trans", K(ret)); + } else if (OB_FAIL(res.init(local_execute))) { + LOG_WARN("init result set", K(ret), K(local_execute)); + } else if (local_execute) { + if (OB_FAIL(do_obj_lock_(tenant_id, arg, operation_type, conn, res))) { + LOG_WARN("do obj lock failed", KR(ret), K(operation_type), K(arg)); + } + } else { + char *tmp_str = nullptr; + int64_t pos = 0; + ObString sql; + if (OB_ISNULL(tmp_str = static_cast(ob_malloc(arg.get_serialize_size(), "InnerLock")))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc memory for sql_str failed", K(ret), K(arg.get_serialize_size())); + } else if (OB_FAIL(arg.serialize(tmp_str, arg.get_serialize_size(), pos))) { + LOG_WARN("serialize lock table arg failed", K(ret), K(arg)); + } else { + sql.assign_ptr(tmp_str, arg.get_serialize_size()); + ret = conn->forward_request(tenant_id, operation_type, sql, res); + } + + if (OB_NOT_NULL(tmp_str)) { + ob_free(tmp_str); + } + } + } + } + + return ret; +} + +// for version 4.0 +int ObInnerConnectionLockUtil::request_lock_( + const uint64_t tenant_id, + const uint64_t table_id, // as obj_id when lock_obj + const ObTabletID tablet_id, //just used when lock_tablet + const ObTableLockMode lock_mode, + const int64_t timeout_us, + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + observer::ObReqTimeGuard req_timeinfo_guard; + + const bool local_execute = conn->is_local_execute(GCONF.cluster_id, tenant_id); + + SMART_VAR(ObInnerSQLResult, res, conn->get_session()) + { + if (OB_INVALID_ID == tenant_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id)); + } else if (local_execute) { + if (OB_FAIL(conn->switch_tenant(tenant_id))) { + LOG_WARN("set system tenant id failed", K(ret), K(tenant_id)); + } + } else { + LOG_DEBUG("tenant not in server", K(ret), K(tenant_id)); + } + + if (OB_SUCC(ret)) { + if (!conn->is_in_trans()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("inner conn must be already in trans", K(ret)); + } else if (OB_FAIL(res.init(local_execute))) { + LOG_WARN("init result set", K(ret), K(local_execute)); + } else if (local_execute) { + // we can safely rewrite the argument here, because it is only used local. + ObLockRequest *lock_arg = nullptr; + ObLockTableRequest lock_table_arg; + ObLockTabletRequest lock_tablet_arg; + switch (operation_type) { + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: { + lock_arg = &lock_table_arg; + lock_table_arg.owner_id_ = 0; + lock_table_arg.lock_mode_ = lock_mode; + lock_table_arg.op_type_ = IN_TRANS_COMMON_LOCK; + lock_table_arg.timeout_us_ = timeout_us; + lock_table_arg.table_id_ = table_id; + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: { + lock_arg = &lock_tablet_arg; + lock_tablet_arg.owner_id_ = 0; + lock_tablet_arg.lock_mode_ = lock_mode; + lock_tablet_arg.op_type_ = IN_TRANS_COMMON_LOCK; + lock_tablet_arg.timeout_us_ = timeout_us; + lock_tablet_arg.table_id_ = table_id; + lock_tablet_arg.tablet_id_ = tablet_id; + break; + } + default: + LOG_WARN("operation_type is not expected", K(operation_type)); + ret = OB_ERR_UNEXPECTED; + } + if (OB_SUCC(ret) && OB_FAIL(do_obj_lock_(tenant_id, *lock_arg, operation_type, conn, res))) { + LOG_WARN("close result set failed", K(ret), K(tenant_id)); + } + } else { + char *tmp_str = nullptr; + int64_t pos = 0; + ObString sql; + switch (operation_type) { + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: { + ObInTransLockTableRequest arg; + arg.table_id_ = table_id; + arg.lock_mode_ = lock_mode; + arg.timeout_us_ = timeout_us; + + if (OB_ISNULL(tmp_str = static_cast(ob_malloc(arg.get_serialize_size(), "InnerLock")))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc memory for sql_str failed", K(ret), K(arg.get_serialize_size())); + } else if (OB_FAIL(arg.serialize(tmp_str, arg.get_serialize_size(), pos))) { + LOG_WARN("serialize lock table arg failed", K(ret), K(arg)); + } else { + sql.assign_ptr(tmp_str, arg.get_serialize_size()); + } + break; + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: { + ObInTransLockTabletRequest arg; + arg.table_id_ = table_id; + arg.tablet_id_ = tablet_id; + arg.lock_mode_ = lock_mode; + arg.timeout_us_ = timeout_us; + + if (OB_ISNULL(tmp_str = static_cast(ob_malloc(arg.get_serialize_size(), "InnerLock")))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc memory for sql_str failed", K(ret), K(arg.get_serialize_size())); + } else if (OB_FAIL(arg.serialize(tmp_str, arg.get_serialize_size(), pos))) { + LOG_WARN("serialize lock table arg failed", K(ret), K(arg)); + } else { + sql.assign_ptr(tmp_str, arg.get_serialize_size()); + } + break; + } + default: { + LOG_WARN("operation_type is not expected", K(operation_type)); + ret = OB_ERR_UNEXPECTED; + } // default + } // switch + ret = conn->forward_request(tenant_id, operation_type, sql, res); + if (OB_NOT_NULL(tmp_str)) { + ob_free(tmp_str); + } + } + } + } + + return ret; +} + +#undef REQUEST_LOCK_4_1 + +} // tablelock +} // transaction +} // oceanbase diff --git a/src/storage/tablelock/ob_lock_inner_connection_util.h b/src/storage/tablelock/ob_lock_inner_connection_util.h new file mode 100644 index 000000000..820997283 --- /dev/null +++ b/src/storage/tablelock/ob_lock_inner_connection_util.h @@ -0,0 +1,158 @@ +/** + * Copyright (c) 2021 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 OCEABASE_OB_LOCK_INNER_CONNECTION_UTIL_ +#define OCEABASE_OB_LOCK_INNER_CONNECTION_UTIL_ + +#include "observer/ob_inner_sql_rpc_proxy.h" +#include "storage/tablelock/ob_table_lock_common.h" + +namespace oceanbase +{ +namespace observer +{ +class ObInnerSQLConnection; +} +namespace common +{ +namespace sqlclient +{ +class ObISQLConnection; +} +} +namespace observer +{ +class ObInnerSQLResult; +} + +namespace transaction +{ +namespace tablelock +{ +class ObLockRequest; +class ObLockObjRequest; +class ObLockTableRequest; +class ObLockTabletRequest; +class ObLockPartitionRequest; +class ObLockAloneTabletRequest; +using ObUnLockObjRequest = ObLockObjRequest; +using ObUnLockTableRequest = ObLockTableRequest; +using ObUnLockPartitionRequest = ObLockPartitionRequest; +using ObUnLockTabletRequest = ObLockTabletRequest; +using ObUnLockAloneTabletRequest = ObLockAloneTabletRequest; + +class ObInnerConnectionLockUtil +{ +// --------------------- interface for inner connection rpc processor ----------------------- +public: + static int process_lock_rpc( + const obrpc::ObInnerSQLTransmitArg &arg, + common::sqlclient::ObISQLConnection *conn); +private: + static int process_lock_table_( + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, + const obrpc::ObInnerSQLTransmitArg &arg, + observer::ObInnerSQLConnection *conn); + static int process_lock_tablet_( + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, + const obrpc::ObInnerSQLTransmitArg &arg, + observer::ObInnerSQLConnection *conn); +// --------------------- interface for inner connection client ----------------------- +public: + static int lock_table( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTableLockMode lock_mode, + const int64_t timeout_us, + observer::ObInnerSQLConnection *conn); + static int lock_table( + const uint64_t tenant_id, + const ObLockTableRequest &arg, + observer::ObInnerSQLConnection *conn); + static int unlock_table( + const uint64_t tenant_id, + const ObUnLockTableRequest &arg, + observer::ObInnerSQLConnection *conn); + static int lock_partition( + const uint64_t tenant_id, + const ObLockPartitionRequest &arg, + observer::ObInnerSQLConnection *conn); + static int unlock_partition( + const uint64_t tenant_id, + const ObUnLockPartitionRequest &arg, + observer::ObInnerSQLConnection *conn); + static int lock_subpartition( + const uint64_t tenant_id, + const ObLockPartitionRequest &arg, + observer::ObInnerSQLConnection *conn); + static int unlock_subpartition( + const uint64_t tenant_id, + const ObUnLockPartitionRequest &arg, + observer::ObInnerSQLConnection *conn); + static int lock_tablet( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTabletID tablet_id, + const ObTableLockMode lock_mode, + const int64_t timeout_us, + observer::ObInnerSQLConnection *conn); + static int lock_tablet( + const uint64_t tenant_id, + const ObLockTabletRequest &arg, + observer::ObInnerSQLConnection *conn); + static int unlock_tablet( + const uint64_t tenant_id, + const ObUnLockTabletRequest &arg, + observer::ObInnerSQLConnection *conn); + static int lock_tablet( + const uint64_t tenant_id, + const ObLockAloneTabletRequest &arg, + observer::ObInnerSQLConnection *conn); + static int unlock_tablet( + const uint64_t tenant_id, + const ObUnLockAloneTabletRequest &arg, + observer::ObInnerSQLConnection *conn); + static int lock_obj( + const uint64_t tenant_id, + const ObLockObjRequest &arg, + observer::ObInnerSQLConnection *conn); + static int unlock_obj( + const uint64_t tenant_id, + const ObUnLockObjRequest &arg, + observer::ObInnerSQLConnection *conn); +private: + static int do_obj_lock_( + const uint64_t tenant_id, + const ObLockRequest &arg, + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, + observer::ObInnerSQLConnection *conn, + observer::ObInnerSQLResult &res); + static int request_lock_( + const uint64_t tenant_id, + const uint64_t table_id, + const ObTabletID tablet_id, //just used when lock_tablet + const ObTableLockMode lock_mode, + const int64_t timeout_us, + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, + observer::ObInnerSQLConnection *conn); + static int request_lock_( + const uint64_t tenant_id, + const ObLockRequest &arg, + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, + observer::ObInnerSQLConnection *conn); +}; + +} // tablelock +} // transaction +} // oceanbase + +#endif diff --git a/src/storage/tablelock/ob_lock_memtable.cpp b/src/storage/tablelock/ob_lock_memtable.cpp index 44bd76e33..b3ae899d1 100644 --- a/src/storage/tablelock/ob_lock_memtable.cpp +++ b/src/storage/tablelock/ob_lock_memtable.cpp @@ -45,7 +45,6 @@ namespace tablelock ObLockMemtable::ObLockMemtable() : ObIMemtable(), is_inited_(false), - ls_id_(), freeze_scn_(SCN::min_scn()), flushed_scn_(SCN::min_scn()), rec_scn_(SCN::max_scn()), @@ -100,7 +99,6 @@ void ObLockMemtable::reset() rec_scn_.set_max(); pre_rec_scn_.set_max(); max_committed_scn_.reset(); - ls_id_.reset(); ObITable::reset(); obj_lock_map_.reset(); freeze_scn_.reset(); @@ -131,45 +129,66 @@ int ObLockMemtable::lock_( { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; + int64_t USLEEP_TIME = 100 * 1000; // 100 ms ObMemtableCtx *mem_ctx = NULL; - bool lock_exist = false; + bool need_retry = false; ObTableLockMode lock_mode_in_same_trans = 0x0; + bool lock_exist = false; ObLockStep succ_step = STEP_BEGIN; ObTxIDSet conflict_tx_set; - ObMvccWriteGuard guard(true); // 1. record lock myself(check conflict). // 2. record lock at memtable ctx. // 3. create lock callback and list it on the callback list of memtable ctx. - if (OB_FAIL(guard.write_auth(ctx))) { - LOG_WARN("not allow lock table.", K(ret), K(ctx)); - } else if (FALSE_IT(mem_ctx = static_cast(ctx.mvcc_acc_ctx_.mem_ctx_))) { - } else if (OB_FAIL(mem_ctx->check_lock_exist(lock_op.lock_id_, - lock_op.owner_id_, - lock_op.lock_mode_, - lock_op.op_type_, - lock_exist, - lock_mode_in_same_trans))) { - LOG_WARN("failed to check lock exist ", K(ret), K(lock_op)); - } else if (lock_exist) { - // do nothing - } else if (FALSE_IT(lock_upgrade(lock_mode_in_same_trans, lock_op))) { - } else if (OB_FAIL(obj_lock_map_.lock(param, - ctx, - lock_op, - lock_mode_in_same_trans, - conflict_tx_set))) { - if (ret != OB_TRY_LOCK_ROW_CONFLICT && - ret != OB_OBJ_LOCK_EXIST) { - LOG_WARN("record lock at lock map mgr failed.", K(ret), K(lock_op)); + do { + // retry if there is lock conflict at part trans ctx. + need_retry = false; + { + succ_step = STEP_BEGIN; + lock_exist = false; + lock_mode_in_same_trans = 0x0; + conflict_tx_set.reset(); + ObMvccWriteGuard guard(true); + if (ObClockGenerator::getClock() >= param.expired_time_) { + ret = OB_TIMEOUT; + LOG_WARN("lock timeout", K(ret), K(param)); + } else if (OB_FAIL(guard.write_auth(ctx))) { + LOG_WARN("not allow lock table.", K(ret), K(ctx)); + } else if (FALSE_IT(mem_ctx = static_cast(ctx.mvcc_acc_ctx_.mem_ctx_))) { + } else if (OB_FAIL(mem_ctx->check_lock_exist(lock_op.lock_id_, + lock_op.owner_id_, + lock_op.lock_mode_, + lock_op.op_type_, + lock_exist, + lock_mode_in_same_trans))) { + LOG_WARN("failed to check lock exist ", K(ret), K(lock_op)); + } else if (lock_exist) { + // do nothing + } else if (FALSE_IT(lock_upgrade(lock_mode_in_same_trans, lock_op))) { + } else if (OB_FAIL(obj_lock_map_.lock(param, + ctx, + lock_op, + lock_mode_in_same_trans, + conflict_tx_set))) { + if (ret != OB_TRY_LOCK_ROW_CONFLICT && + ret != OB_OBJ_LOCK_EXIST) { + LOG_WARN("record lock at lock map mgr failed.", K(ret), K(lock_op)); + } + } else if (FALSE_IT(succ_step = STEP_IN_LOCK_MGR)) { + } else if (OB_FAIL(mem_ctx->add_lock_record(lock_op))) { + if (OB_EAGAIN == ret) { + need_retry = true; + } + LOG_WARN("record lock at mem_ctx failed.", K(ret), K(lock_op)); + } + if (OB_FAIL(ret) && succ_step == STEP_IN_LOCK_MGR) { + obj_lock_map_.remove_lock_record(lock_op); + } } - } else if (FALSE_IT(succ_step = STEP_IN_LOCK_MGR)) { - } else if (OB_FAIL(mem_ctx->add_lock_record(lock_op))) { - LOG_WARN("record lock at mem_ctx failed.", K(ret), K(lock_op)); - } - if (OB_FAIL(ret) && succ_step == STEP_IN_LOCK_MGR) { - obj_lock_map_.remove_lock_record(lock_op); - } + if (need_retry) { + ob_usleep(USLEEP_TIME); + } + } while (need_retry); // return success if lock twice. if (ret == OB_OBJ_LOCK_EXIST) { ret = OB_SUCCESS; @@ -220,39 +239,59 @@ int ObLockMemtable::unlock_( const int64_t expired_time) { int ret = OB_SUCCESS; + int64_t USLEEP_TIME = 100 * 1000; // 100 ms ObMemtableCtx *mem_ctx = NULL; bool lock_op_exist = false; + bool need_retry = false; ObTableLockMode unused_lock_mode_in_same_trans = 0x0; ObLockStep succ_step = STEP_BEGIN; - ObMvccWriteGuard guard(true); // 1. record unlock op myself(check conflict). // 2. record unlock op at memtable ctx. // 3. create unlock callback and list it on the callback list of memtable ctx. - if (OB_FAIL(guard.write_auth(ctx))) { - LOG_WARN("not allow unlock table.", K(ret), K(ctx)); - } else if (FALSE_IT(mem_ctx = static_cast(ctx.mvcc_acc_ctx_.mem_ctx_))) { - // check whether the unlock op exist already - } else if (OB_FAIL(mem_ctx->check_lock_exist(unlock_op.lock_id_, - unlock_op.owner_id_, - unlock_op.lock_mode_, - unlock_op.op_type_, - lock_op_exist, - unused_lock_mode_in_same_trans))) { - LOG_WARN("failed to check lock exist ", K(ret), K(unlock_op)); - } else if (lock_op_exist) { - // do nothing - } else if (OB_FAIL(obj_lock_map_.unlock(unlock_op, - is_try_lock, - expired_time))) { - LOG_WARN("record lock at lock map mgr failed.", K(ret), K(unlock_op)); - } else if (FALSE_IT(succ_step = STEP_IN_LOCK_MGR)) { - } else if (OB_FAIL(mem_ctx->add_lock_record(unlock_op))) { - LOG_WARN("record lock at mem_ctx failed.", K(ret), K(unlock_op)); - } - if (OB_FAIL(ret) && succ_step == STEP_IN_LOCK_MGR) { - obj_lock_map_.remove_lock_record(unlock_op); - } + do { + // retry if there is lock conflict at part trans ctx. + need_retry = false; + { + succ_step = STEP_BEGIN; + lock_op_exist = false; + unused_lock_mode_in_same_trans = 0x0; + ObMvccWriteGuard guard(true); + if (ObClockGenerator::getClock() >= expired_time) { + ret = OB_TIMEOUT; + LOG_WARN("unlock timeout", K(ret), K(unlock_op), K(expired_time)); + } else if (OB_FAIL(guard.write_auth(ctx))) { + LOG_WARN("not allow unlock table.", K(ret), K(ctx)); + } else if (FALSE_IT(mem_ctx = static_cast(ctx.mvcc_acc_ctx_.mem_ctx_))) { + // check whether the unlock op exist already + } else if (OB_FAIL(mem_ctx->check_lock_exist(unlock_op.lock_id_, + unlock_op.owner_id_, + unlock_op.lock_mode_, + unlock_op.op_type_, + lock_op_exist, + unused_lock_mode_in_same_trans))) { + LOG_WARN("failed to check lock exist ", K(ret), K(unlock_op)); + } else if (lock_op_exist) { + // do nothing + } else if (OB_FAIL(obj_lock_map_.unlock(unlock_op, + is_try_lock, + expired_time))) { + LOG_WARN("record lock at lock map mgr failed.", K(ret), K(unlock_op)); + } else if (FALSE_IT(succ_step = STEP_IN_LOCK_MGR)) { + } else if (OB_FAIL(mem_ctx->add_lock_record(unlock_op))) { + if (OB_EAGAIN == ret) { + need_retry = true; + } + LOG_WARN("record lock at mem_ctx failed.", K(ret), K(unlock_op)); + } + if (OB_FAIL(ret) && succ_step == STEP_IN_LOCK_MGR) { + obj_lock_map_.remove_lock_record(unlock_op); + } + } + if (need_retry) { + ob_usleep(USLEEP_TIME); + } + } while (need_retry); return ret; } @@ -657,62 +696,6 @@ int ObLockMemtable::get( } -int ObLockMemtable::set( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const ObIArray &columns, - const storage::ObStoreRow &row, - const share::ObEncryptMeta *encrypt_meta) -{ - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(columns); - UNUSED(row); - UNUSED(encrypt_meta); - return OB_NOT_SUPPORTED; -} - -int ObLockMemtable::lock( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - ObNewRowIterator &row_iter) -{ - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(row_iter); - return OB_NOT_SUPPORTED; -} - -int ObLockMemtable::lock( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const ObNewRow &row) -{ - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(row); - return OB_NOT_SUPPORTED; -} - -int ObLockMemtable::lock( - storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const blocksstable::ObDatumRowkey &rowkey) -{ - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(rowkey); - return OB_NOT_SUPPORTED; -} - int ObLockMemtable::get( const storage::ObTableIterParam ¶m, storage::ObTableAccessContext &context, @@ -897,7 +880,7 @@ int ObLockMemtable::replay_row( int ret = OB_SUCCESS; ObLockID lock_id; - ObTableLockOwnerID owner_id = 0; + ObTableLockOwnerID owner_id(0); ObTableLockMode lock_mode = NO_LOCK; ObTableLockOpType lock_op_type = ObTableLockOpType::UNKNOWN_TYPE; int64_t seq_no = 0; diff --git a/src/storage/tablelock/ob_lock_memtable.h b/src/storage/tablelock/ob_lock_memtable.h index b3e9192c6..723bfd8dc 100644 --- a/src/storage/tablelock/ob_lock_memtable.h +++ b/src/storage/tablelock/ob_lock_memtable.h @@ -51,7 +51,6 @@ public: int init(const ObITable::TableKey &table_key, const share::ObLSID &ls_id, storage::ObFreezer *freezer); - void reset(); // =================== LOCK FUNCTIONS ===================== // try to lock a object. @@ -149,28 +148,6 @@ public: const blocksstable::ObDatumRowkey &rowkey, blocksstable::ObDatumRow &row) override; - virtual int set(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObIArray &columns, - const storage::ObStoreRow &row, - const share::ObEncryptMeta *encrypt_meta) override; - - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - common::ObNewRowIterator &row_iter) override; - - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObNewRow &row) override; - - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const blocksstable::ObDatumRowkey &rowkey) override; - virtual int get(const storage::ObTableIterParam ¶m, storage::ObTableAccessContext &context, const blocksstable::ObDatumRowkey &rowkey, @@ -225,7 +202,6 @@ private: bool is_inited_; - share::ObLSID ls_id_; // the lock map store lock data ObOBJLockMap obj_lock_map_; share::SCN freeze_scn_; diff --git a/src/storage/tablelock/ob_lock_table.cpp b/src/storage/tablelock/ob_lock_table.cpp index e48073997..f3d2a7212 100644 --- a/src/storage/tablelock/ob_lock_table.cpp +++ b/src/storage/tablelock/ob_lock_table.cpp @@ -92,10 +92,9 @@ int ObLockTable::restore_lock_table_(ObITable &sstable) LOG_WARN("failed to push back key", K(ret), K(key)); } else if (OB_FAIL(columns.push_back(value))) { LOG_WARN("failed to push back value", K(ret), K(value)); - } else if (OB_FAIL(read_info.init(allocator, LOCKTABLE_SCHEMA_COLUMN_CNT, LOCKTABLE_SCHEMA_ROEKEY_CNT, lib::is_oracle_mode(), columns))) { + } else if (OB_FAIL(read_info.init(allocator, LOCKTABLE_SCHEMA_COLUMN_CNT, LOCKTABLE_SCHEMA_ROEKEY_CNT, lib::is_oracle_mode(), columns, nullptr/*storage_cols_index*/))) { LOG_WARN("Fail to init read_info", K(ret)); } else if (FALSE_IT(iter_param.read_info_ = &read_info)) { - } else if (FALSE_IT(iter_param.full_read_info_ = &read_info)) { } else if (OB_FAIL(sstable.scan(iter_param, access_context, whole_range, @@ -219,60 +218,6 @@ int ObLockTable::get_table_schema_( return ret; } -int ObLockTable::gen_create_tablet_arg_( - const ObTabletID &tablet_id, - const uint64_t tenant_id, - const ObLSID ls_id, - const lib::Worker::CompatMode compat_mode, - const ObTableSchema &table_schema, - obrpc::ObBatchCreateTabletArg &arg) -{ - int ret = OB_SUCCESS; - obrpc::ObCreateTabletInfo create_tablet_info; - ObArray tablet_ids; - ObArray tablet_schema_idxs; - - arg.reset(); - // create ObCreateTabletInfo - if (OB_FAIL(tablet_ids.push_back(tablet_id))) { - LOG_WARN("insert tablet id failed", K(ret), K(tablet_id)); - // only one tablet, only one schema - } else if (OB_FAIL(tablet_schema_idxs.push_back(0))) { - LOG_WARN("insert tablet schema idx failed", K(ret)); - } else if (OB_FAIL(create_tablet_info.init(tablet_ids, - tablet_id, - tablet_schema_idxs, - compat_mode, - false/*is_create_bind_hidden_tablets*/))) { - LOG_WARN("create tablet info init failed", K(ret), K(tablet_ids), K(tablet_id)); - // create ObBatchCreateTabletArg - } else if (OB_FAIL(arg.init_create_tablet(ls_id, SCN::base_scn(), false/*need_check_tablet_cnt*/))) { - LOG_WARN("ObBatchCreateTabletArg init create tablet failed", K(ret), K(tenant_id), K(ls_id)); - } else if (OB_FAIL(arg.table_schemas_.push_back(table_schema))) { - LOG_WARN("add table schema failed", K(ret), K(table_schema)); - } else if (OB_FAIL(arg.tablets_.push_back(create_tablet_info))) { - LOG_WARN("add create tablet info failed", K(ret), K(create_tablet_info)); - } - - return ret; -} - -int ObLockTable::gen_remove_tablet_arg_( - const common::ObTabletID &tablet_id, - const uint64_t tenant_id, - const share::ObLSID ls_id, - obrpc::ObBatchRemoveTabletArg &arg) -{ - int ret = OB_SUCCESS; - arg.reset(); - if (OB_FAIL(arg.tablet_ids_.push_back(tablet_id))) { - LOG_WARN("insert tablet id failed", K(ret), K(tablet_id)); - } else { - arg.id_ = ls_id; - } - return ret; -} - int ObLockTable::init(ObLS *parent) { int ret = OB_SUCCESS; @@ -334,6 +279,7 @@ int ObLockTable::online() int ret = OB_SUCCESS; ObTabletHandle handle; ObTablet *tablet; + ObTabletMemberWrapper table_store_wrapper; ObLSTabletService *ls_tablet_svr = nullptr; LOG_INFO("online lock table", K(parent_->get_ls_id())); @@ -346,12 +292,22 @@ int ObLockTable::online() } else if (FALSE_IT(tablet = handle.get_obj())) { } else if (OB_FAIL(ls_tablet_svr->create_memtable(LS_LOCK_TABLET, 0 /* schema_version */))) { LOG_WARN("failed to create memtable", K(ret)); + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - ObTabletTableStore &table_store = tablet->get_table_store(); - ObSSTableArray &sstables = table_store.get_minor_sstables(); - + const ObSSTableArray &sstables = table_store_wrapper.get_member()->get_minor_sstables(); if (!sstables.empty()) { - ret = restore_lock_table_(*sstables[0]); + ObStorageMetaHandle loaded_sstable_handle; + ObSSTable *loaded_sstable = nullptr; + if (OB_FAIL(ObTabletTableStore::load_sstable_on_demand( + table_store_wrapper.get_meta_handle(), + *sstables[0], + loaded_sstable_handle, + loaded_sstable))) { + LOG_WARN("fail to load sstable on demand", K(ret)); + } else if (OB_FAIL(restore_lock_table_(*loaded_sstable))) { + LOG_WARN("fail to restore lock table", K(ret)); + } } } @@ -361,32 +317,24 @@ int ObLockTable::online() int ObLockTable::create_tablet(const lib::Worker::CompatMode compat_mode, const SCN &create_scn) { int ret = OB_SUCCESS; - uint64_t tenant_id = parent_->get_tenant_id(); - share::ObLSID ls_id = parent_->get_ls_id(); - obrpc::ObBatchCreateTabletArg arg; - const bool no_need_write_clog = true; + const uint64_t tenant_id = parent_->get_tenant_id(); + const share::ObLSID &ls_id = parent_->get_ls_id(); share::schema::ObTableSchema table_schema; ObIMemtableMgr *memtable_mgr = nullptr; ObMemtableMgrHandle memtable_mgr_handle; - if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("ObLockTable not inited", K(ret)); - } else if (OB_FAIL(get_table_schema_(tenant_id, - table_schema))) { + } else if (OB_FAIL(get_table_schema_(tenant_id, table_schema))) { LOG_WARN("get lock table schema failed", K(ret)); - } else if (OB_FAIL(gen_create_tablet_arg_(LS_LOCK_TABLET, - tenant_id, - ls_id, - compat_mode, - table_schema, - arg))) { - LOG_WARN("gen create tablet arg failed", K(ret), K(LS_LOCK_TABLET), K(tenant_id), - K(ls_id), K(table_schema)); - } else if (OB_FAIL(parent_->batch_create_tablets(arg, - create_scn, - no_need_write_clog))) { - LOG_WARN("create lock tablet failed", K(ret), K(arg), K(create_scn)); + } else if (OB_FAIL(parent_->create_ls_inner_tablet(ls_id, + LS_LOCK_TABLET, + ObLS::LS_INNER_TABLET_FROZEN_SCN, + table_schema, + compat_mode, + create_scn))) { + LOG_WARN("failed to create lock tablet", K(ret), K(ls_id), K(LS_LOCK_TABLET), + K(table_schema), K(compat_mode), K(create_scn)); } else if (OB_FAIL(parent_->get_tablet_svr()-> get_lock_memtable_mgr(memtable_mgr_handle))) { LOG_WARN("get_lock_memtable_mgr failed", K(ret)); @@ -402,19 +350,9 @@ int ObLockTable::create_tablet(const lib::Worker::CompatMode compat_mode, const int ObLockTable::remove_tablet() { int ret = OB_SUCCESS; - obrpc::ObBatchRemoveTabletArg arg; - const ObTabletID &tablet_id = LS_LOCK_TABLET; - const bool no_need_write_clog = true; - uint64_t tenant_id = parent_->get_tenant_id(); - if (OB_FAIL(gen_remove_tablet_arg_(tablet_id, - tenant_id, - parent_->get_ls_id(), - arg))) { - LOG_WARN("gen remove tablet arg failed", K(ret), K(tablet_id), - K(tenant_id), K(parent_->get_ls_id())); - } else if (OB_FAIL(parent_->batch_remove_tablets(arg, - no_need_write_clog))) { - LOG_WARN("remove tablet failed", K(ret), K(arg)); + const share::ObLSID &ls_id = parent_->get_ls_id(); + if (OB_FAIL(parent_->remove_ls_inner_tablet(ls_id, LS_LOCK_TABLET))) { + LOG_WARN("failed to remove ls inner tablet", K(ret), K(ls_id), K(LS_LOCK_TABLET)); } return ret; } @@ -424,6 +362,7 @@ int ObLockTable::load_lock() int ret = OB_SUCCESS; ObTabletHandle handle; ObTablet *tablet; + ObTabletMemberWrapper table_store_wrapper; ObLSTabletService *ls_tablet_svr = nullptr; LOG_INFO("load_lock_table()", K(parent_->get_ls_id())); @@ -436,12 +375,22 @@ int ObLockTable::load_lock() } else if (FALSE_IT(tablet = handle.get_obj())) { } else if (OB_FAIL(ls_tablet_svr->create_memtable(LS_LOCK_TABLET, 0 /* schema_version */))) { LOG_WARN("failed to create memtable", K(ret)); + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - ObTabletTableStore &table_store = tablet->get_table_store(); - ObSSTableArray &sstables = table_store.get_minor_sstables(); - + const ObSSTableArray &sstables = table_store_wrapper.get_member()->get_minor_sstables(); if (!sstables.empty()) { - ret = restore_lock_table_(*sstables[0]); + ObStorageMetaHandle loaded_sstable_handle; + ObSSTable *loaded_sstable = nullptr; + if (OB_FAIL(ObTabletTableStore::load_sstable_on_demand( + table_store_wrapper.get_meta_handle(), + *sstables[0], + loaded_sstable_handle, + loaded_sstable))) { + LOG_WARN("fail to load sstable on demand", K(ret)); + } else if (OB_FAIL(restore_lock_table_(*loaded_sstable))) { + LOG_WARN("fail to restore lock table", K(ret)); + } } } diff --git a/src/storage/tablelock/ob_lock_table.h b/src/storage/tablelock/ob_lock_table.h index 11691627f..99920298e 100644 --- a/src/storage/tablelock/ob_lock_table.h +++ b/src/storage/tablelock/ob_lock_table.h @@ -156,16 +156,6 @@ private: int recover_(const blocksstable::ObDatumRow &row); int get_table_schema_(const uint64_t tenant_id, share::schema::ObTableSchema &schema); - int gen_create_tablet_arg_(const common::ObTabletID &tablet_id, - const uint64_t tenant_id, - const share::ObLSID ls_id, - const lib::Worker::CompatMode compat_mode, - const share::schema::ObTableSchema &table_schema, - obrpc::ObBatchCreateTabletArg &arg); - int gen_remove_tablet_arg_(const common::ObTabletID &tablet_id, - const uint64_t tenant_id, - const share::ObLSID ls_id, - obrpc::ObBatchRemoveTabletArg &arg); private: static const int64_t LOCKTABLE_SCHEMA_VERSION = 0; diff --git a/src/storage/tablelock/ob_lock_utils.cpp b/src/storage/tablelock/ob_lock_utils.cpp new file mode 100644 index 000000000..12351c203 --- /dev/null +++ b/src/storage/tablelock/ob_lock_utils.cpp @@ -0,0 +1,98 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX TABLELOCK + +#include "storage/tablelock/ob_lock_utils.h" +#include "storage/tablelock/ob_table_lock_rpc_struct.h" // ObLockObjRequest +#include "lib/mysqlclient/ob_mysql_transaction.h" // ObMysqlTransaction +#include "observer/ob_inner_sql_connection.h" // ObInnerSQLConnection +#include "share/ob_share_util.h" // ObShareUtil +#include "storage/tablelock/ob_lock_inner_connection_util.h" + +namespace oceanbase +{ +using namespace common; +using namespace observer; +using namespace share; +namespace transaction +{ +namespace tablelock +{ +int ObInnerTableLockUtil::lock_inner_table_in_trans( + common::ObMySQLTransaction &trans, + const uint64_t tenant_id, + const uint64_t inner_table_id, + const ObTableLockMode &lock_mode) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *conn = NULL; + ObTimeoutCtx ctx; + const int64_t DEFAULT_TIMEOUT = GCONF.internal_sql_execute_timeout; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) + || !is_inner_table(inner_table_id) + || !is_lock_mode_valid(lock_mode))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(inner_table_id), K(lock_mode)); + } else if (OB_ISNULL(conn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("connection is null", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, DEFAULT_TIMEOUT))) { + LOG_WARN("fail to set default_timeout_ctx", KR(ret)); + } else { + ObLockTableRequest table_lock_arg; + table_lock_arg.lock_mode_ = lock_mode; + table_lock_arg.timeout_us_ = ctx.get_timeout(); + table_lock_arg.table_id_ = inner_table_id; + table_lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; + if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(tenant_id, table_lock_arg, conn))) { + LOG_WARN("lock table failed", KR(ret), K(table_lock_arg)); + } + } + return ret; +} + +int ObLSObjLockUtil::lock_ls_in_trans( + common::ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObLSID &ls_id, + const transaction::tablelock::ObTableLockMode &lock_mode) +{ + int ret = OB_SUCCESS; + ObInnerSQLConnection *conn = NULL; + ObTimeoutCtx ctx; + const int64_t DEFAULT_TIMEOUT = GCONF.internal_sql_execute_timeout; + if (OB_UNLIKELY(!ls_id.is_valid_with_tenant(tenant_id) || !is_lock_mode_valid(lock_mode))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(tenant_id), K(ls_id), K(lock_mode)); + } else if (OB_ISNULL(conn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("connection is null", KR(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, DEFAULT_TIMEOUT))) { + LOG_WARN("fail to set default_timeout_ctx", KR(ret)); + } else { + ObLockObjRequest lock_arg; + lock_arg.lock_mode_ = lock_mode; + lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; + lock_arg.timeout_us_ = ctx.get_timeout(); + lock_arg.obj_type_ = ObLockOBJType::OBJ_TYPE_LS; + lock_arg.obj_id_ = ls_id.id(); + if (OB_FAIL(ObInnerConnectionLockUtil::lock_obj(tenant_id, lock_arg, conn))) { + LOG_WARN("lock obj failed", KR(ret), K(tenant_id), K(lock_arg)); + } + } + return ret; +} + +} // end namespace tablelock +} // end namespace transaction +} // end namespace oceanbase diff --git a/src/storage/tablelock/ob_lock_utils.h b/src/storage/tablelock/ob_lock_utils.h new file mode 100644 index 000000000..24c8de688 --- /dev/null +++ b/src/storage/tablelock/ob_lock_utils.h @@ -0,0 +1,84 @@ +/** + * 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_STORAGE_TABLELOCK_OB_LOCK_UTILS_H +#define OCEANBASE_STORAGE_TABLELOCK_OB_LOCK_UTILS_H + +#include "share/ob_ls_id.h" // ObLSID +#include "share/inner_table/ob_inner_table_schema.h" +#include "storage/tablelock/ob_table_lock_common.h" // ObTableLockMode + +namespace oceanbase +{ +namespace common +{ +class ObMySQLTransaction; +} + +namespace transaction +{ +namespace tablelock +{ +class ObInnerTableLockUtil +{ +public: + // only inner tables in the white list can be locked + // please think carefully about circular dependencies before adding inner table into the white list + static bool in_inner_table_lock_white_list(const uint64_t inner_table_id) + { + return share::OB_ALL_BALANCE_JOB_TID == inner_table_id; + } + /* + * lock inner table in trans with internal_sql_execute_timeout + * + * @param[in] trans: ObMySQLTransaction + * @param[in] tenant_id: tenant_id of the inner table + * @param[in] inner_table_id: inner table id which you want to lock + * @param[in] lock_mode: table lock mode + * @return + * - OB_SUCCESS: lock inner table successfully + * - OB_TRY_LOCK_ROW_CONFLICT: lock conflict + * - other: lock failed + */ + static int lock_inner_table_in_trans( + common::ObMySQLTransaction &trans, + const uint64_t tenant_id, + const uint64_t inner_table_id, + const ObTableLockMode &lock_mode); +}; + +class ObLSObjLockUtil +{ +public: + /* + * lock ls in trans with internal_sql_execute_timeout + * + * @param[in] trans: ObMySQLTransaction + * @param[in] tenant_id: tenant_id of the ls + * @param[in] ls_id: target log stream(ls) id + * @param[in] lock_mode: obj lock mode + * @return + * - OB_SUCCESS: lock ls successfully + * - OB_TRY_LOCK_ROW_CONFLICT: lock conflict + * - other: lock failed + */ + static int lock_ls_in_trans( + common::ObMySQLTransaction &trans, + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObTableLockMode &lock_mode); +}; + +} // end namespace tablelock +} // end namespace transaction +} // end namespace oceanbase +#endif \ No newline at end of file diff --git a/src/storage/tablelock/ob_mem_ctx_table_lock.cpp b/src/storage/tablelock/ob_mem_ctx_table_lock.cpp old mode 100644 new mode 100755 index 18971cb72..a1aafb932 --- a/src/storage/tablelock/ob_mem_ctx_table_lock.cpp +++ b/src/storage/tablelock/ob_mem_ctx_table_lock.cpp @@ -296,7 +296,7 @@ void ObLockMemCtx::set_log_synced( } } -int ObLockMemCtx::check_lock_exist( +int ObLockMemCtx::check_lock_exist( //TODO(lihongqin):check it const ObLockID &lock_id, const ObTableLockOwnerID &owner_id, const ObTableLockMode mode, diff --git a/src/storage/tablelock/ob_table_lock_common.cpp b/src/storage/tablelock/ob_table_lock_common.cpp index 56b5deaba..879d299c8 100644 --- a/src/storage/tablelock/ob_table_lock_common.cpp +++ b/src/storage/tablelock/ob_table_lock_common.cpp @@ -84,13 +84,26 @@ DEFINE_GET_SERIALIZE_SIZE(ObLockID) return size; } +int ObLockID::convert_to(common::ObTabletID &tablet_id) const +{ + int ret = OB_SUCCESS; + common::ObTabletID tmp_id(obj_id_); + if (!is_tablet_lock() || !tmp_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("can not convert to", K(ret), K_(obj_type), K_(obj_id)); + } else { + tablet_id = tmp_id; + } + return ret; +} + int ObLockID::set(const ObLockOBJType &type, const uint64_t obj_id) { int ret = OB_SUCCESS; if (!is_lock_obj_type_valid(type) || !is_valid_id(obj_id)) { ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "init fail", K(ret), K(type), K(obj_id)); + LOG_WARN("init fail", K(ret), K(type), K(obj_id)); } else { obj_type_ = type; obj_id_ = obj_id; diff --git a/src/storage/tablelock/ob_table_lock_common.h b/src/storage/tablelock/ob_table_lock_common.h old mode 100644 new mode 100755 index 28c503432..75b9d2e45 --- a/src/storage/tablelock/ob_table_lock_common.h +++ b/src/storage/tablelock/ob_table_lock_common.h @@ -13,10 +13,12 @@ #ifndef OCEANBASE_STORAGE_TABLELOCK_OB_TABLE_LOCK_COMMON_ #define OCEANBASE_STORAGE_TABLELOCK_OB_TABLE_LOCK_COMMON_ #include "common/ob_simple_iterator.h" +#include "lib/allocator/ob_mod_define.h" #include "lib/list/ob_dlist.h" #include "lib/utility/ob_print_utils.h" #include "lib/allocator/ob_mod_define.h" #include "share/scn.h" +#include "share/ob_common_id.h" #include "storage/tx/ob_trans_define.h" namespace oceanbase @@ -219,6 +221,8 @@ enum class ObLockOBJType : char OBJ_TYPE_LS = 4, // for ls OBJ_TYPE_TENANT = 5, // for tenant OBJ_TYPE_EXTERNAL_TABLE_REFRESH = 6, // for external table + OBJ_TYPE_ONLINE_DDL_TABLE = 7, // online ddl table + OBJ_TYPE_ONLINE_DDL_TABLET = 8, // online ddl tablets OBJ_TYPE_MAX }; @@ -264,6 +268,12 @@ bool is_lock_obj_type_valid(const ObLockOBJType &type) type < ObLockOBJType::OBJ_TYPE_MAX); } +static inline +bool is_tablet_obj_type(const ObLockOBJType &type) +{ + return (ObLockOBJType::OBJ_TYPE_TABLET == type); +} + struct ObLockID final { public: @@ -306,6 +316,9 @@ public: } bool operator<(const ObLockID &other) const { return -1 == compare(other); } bool operator!=(const ObLockID &other) const { return !operator==(other); } + bool is_tablet_lock() const { return is_tablet_obj_type(obj_type_); } + // convert to tablet id, if it is not a valid tablet id, return error code. + int convert_to(common::ObTabletID &tablet_id) const; int set(const ObLockOBJType &type, const uint64_t obj_id); void reset() { @@ -327,7 +340,7 @@ int get_lock_id(const uint64_t table_id, ObLockID &lock_id); int get_lock_id(const common::ObTabletID &tablet, ObLockID &lock_id); -typedef int64_t ObTableLockOwnerID; +typedef share::ObCommonID ObTableLockOwnerID; struct ObTableLockOp { diff --git a/src/storage/tablelock/ob_table_lock_rpc_processor.cpp b/src/storage/tablelock/ob_table_lock_rpc_processor.cpp index d20382884..b85d0ff1c 100644 --- a/src/storage/tablelock/ob_table_lock_rpc_processor.cpp +++ b/src/storage/tablelock/ob_table_lock_rpc_processor.cpp @@ -16,6 +16,7 @@ #include "storage/tx_storage/ob_ls_service.h" #include "storage/tablelock/ob_table_lock_service.h" #include "storage/tablelock/ob_table_lock_rpc_struct.h" +#include "storage/tablet/ob_tablet.h" #include "storage/tx/ob_clog_encrypt_info.h" // TODO: remove with old trans interface #include "storage/tx/ob_trans_service.h" @@ -27,18 +28,109 @@ using namespace transaction::tablelock; namespace observer { -#define BATCH_PROCESS(arg, func_name) \ - ({ \ - int ret = OB_SUCCESS; \ - ObAccessService *access_srv = MTL(ObAccessService *); \ - for (int i = 0; i < arg.params_.count() && OB_SUCC(ret); i++) { \ - if (OB_FAIL(access_srv->func_name(arg.lsid_, \ - *(arg.tx_desc_), \ - arg.params_[i]))) { \ - LOG_WARN("failed to exec", K(ret), K(arg.params_[i])); \ - } \ - } \ - ret; \ +int check_exist(const share::ObLSID &ls_id, ObLSHandle &ls_handle) +{ + int ret = OB_SUCCESS; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::TABLELOCK_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); + } else { + // do nothing + } + return ret; +} + +int check_exist(const ObLockTaskBatchRequest &arg, + const common::ObTabletID &tablet_id, + ObLSHandle ls_handle) +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + ObTabletHandle tablet_handle; + ObTabletStatus::Status tablet_status = ObTabletStatus::MAX; + ObTabletCreateDeleteMdsUserData data; + bool is_commited = false; + if (ObTableLockTaskType::LOCK_ALONE_TABLET == arg.task_type_ || + ObTableLockTaskType::UNLOCK_ALONE_TABLET == arg.task_type_) { + // alone tablet does not check exist + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); + } else if (OB_FAIL(ls->get_tablet(tablet_id, + tablet_handle, + 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("get tablet with timeout failed", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_latest_tablet_status( + data, is_commited))) { + LOG_WARN("failed to get CreateDeleteMdsUserData", KR(ret)); + } else if (FALSE_IT(tablet_status = data.get_tablet_status())) { + } else if (ObTabletStatus::NORMAL == tablet_status + || ObTabletStatus::TRANSFER_OUT == tablet_status + || ObTabletStatus::TRANSFER_IN == tablet_status) { + // do nothing + } else if (ObTabletStatus::DELETED == tablet_status + || ObTabletStatus::TRANSFER_OUT_DELETED == tablet_status) { + // tablet shell + ret = OB_TABLET_NOT_EXIST; + LOG_INFO("tablet is already deleted", KR(ret), K(tablet_id)); + } else { + // do nothing + } + return ret; +} + +#define BATCH_PROCESS(arg, func_name, result) \ + ({ \ + int ret = OB_SUCCESS; \ + ObAccessService *access_srv = MTL(ObAccessService *); \ + ObLSHandle ls_handle; \ + common::ObTabletID tablet_id; \ + if (OB_FAIL(check_exist(arg.lsid_, ls_handle))) { \ + LOG_WARN("check ls failed", K(ret), K(arg)); \ + if (OB_LS_NOT_EXIST == ret) { \ + result.can_retry_ = true; \ + } \ + } else { \ + for (int i = 0; i < arg.params_.count() && OB_SUCC(ret); i++) { \ + if (arg.params_[i].lock_id_.is_tablet_lock()) { \ + if (OB_FAIL(arg.params_[i].lock_id_.convert_to(tablet_id))) { \ + LOG_WARN("convert lock id to tablet id failed", K(ret), \ + K(arg.params_[i].lock_id_)); \ + } else if (OB_FAIL(check_exist(arg, \ + tablet_id, \ + ls_handle))) { \ + LOG_WARN("check tablet failed", K(ret), K(tablet_id), \ + K(arg.params_[i].expired_time_), K(ls_handle)); \ + if (OB_TABLET_NOT_EXIST == ret) { \ + result.can_retry_ = true; \ + } \ + } \ + } \ + if (OB_FAIL(ret)) { \ + } else if (OB_FAIL(access_srv->func_name(arg.lsid_, \ + *(arg.tx_desc_), \ + arg.params_[i]))) { \ + LOG_WARN("failed to exec", K(ret), K(arg.params_[i])); \ + } else if (arg.params_[i].lock_id_.is_tablet_lock() && \ + OB_FAIL(check_exist(arg, \ + tablet_id, \ + ls_handle))) { \ + LOG_WARN("check tablet failed", K(ret), K(tablet_id), \ + K(arg.params_[i].expired_time_), K(ls_handle)); \ + } else { \ + result.success_pos_ = i; \ + } \ + } \ + } \ + ret; \ }) int ObTableLockTaskP::process() @@ -180,15 +272,16 @@ int ObBatchLockTaskP::process() switch (arg_.task_type_) { case ObTableLockTaskType::PRE_CHECK_TABLET: { // NOTE: yanyuan.cxf pre check should not check timeout - ret = BATCH_PROCESS(arg_, pre_check_lock); + ret = BATCH_PROCESS(arg_, pre_check_lock, result_); break; } case ObTableLockTaskType::LOCK_TABLE: case ObTableLockTaskType::LOCK_PARTITION: case ObTableLockTaskType::LOCK_SUBPARTITION: case ObTableLockTaskType::LOCK_TABLET: - case ObTableLockTaskType::LOCK_OBJECT: { - if (OB_FAIL(BATCH_PROCESS(arg_, lock_obj))) { + case ObTableLockTaskType::LOCK_OBJECT: + case ObTableLockTaskType::LOCK_ALONE_TABLET: { + if (OB_FAIL(BATCH_PROCESS(arg_, lock_obj, result_))) { LOG_WARN("failed to exec lock obj operation", K(ret), K(arg_)); } break; @@ -235,8 +328,9 @@ int ObHighPriorityBatchLockTaskP::process() case ObTableLockTaskType::UNLOCK_PARTITION: case ObTableLockTaskType::UNLOCK_SUBPARTITION: case ObTableLockTaskType::UNLOCK_TABLET: - case ObTableLockTaskType::UNLOCK_OBJECT: { - if (OB_FAIL(BATCH_PROCESS(arg_, unlock_obj))) { + case ObTableLockTaskType::UNLOCK_OBJECT: + case ObTableLockTaskType::UNLOCK_ALONE_TABLET: { + if (OB_FAIL(BATCH_PROCESS(arg_, unlock_obj, result_))) { LOG_WARN("failed to exec unlock obj operation", K(ret), K(arg_)); } break; diff --git a/src/storage/tablelock/ob_table_lock_rpc_struct.cpp b/src/storage/tablelock/ob_table_lock_rpc_struct.cpp old mode 100644 new mode 100755 index 478f4645f..6ca6a3b4c --- a/src/storage/tablelock/ob_table_lock_rpc_struct.cpp +++ b/src/storage/tablelock/ob_table_lock_rpc_struct.cpp @@ -53,10 +53,18 @@ OB_SERIALIZE_MEMBER_INHERIT(ObLockPartitionRequest, ObLockTableRequest, OB_SERIALIZE_MEMBER_INHERIT(ObLockTabletRequest, ObLockTableRequest, tablet_id_); +OB_SERIALIZE_MEMBER_INHERIT(ObLockTabletsRequest, ObLockTableRequest, + tablet_ids_); + +OB_SERIALIZE_MEMBER_INHERIT(ObLockAloneTabletRequest, ObLockTabletsRequest, + ls_id_); + OB_SERIALIZE_MEMBER(ObTableLockTaskResult, ret_code_, tx_result_ret_code_, - tx_result_); + tx_result_, + can_retry_, + success_pos_); OB_DEF_SERIALIZE_SIZE(ObTableLockTaskRequest) { @@ -201,7 +209,9 @@ bool ObLockParam::is_valid() const (ObLockOBJType::OBJ_TYPE_COMMON_OBJ == lock_id_.obj_type_ || ObLockOBJType::OBJ_TYPE_TENANT == lock_id_.obj_type_ || ObLockOBJType::OBJ_TYPE_LS == lock_id_.obj_type_ - || ObLockOBJType::OBJ_TYPE_EXTERNAL_TABLE_REFRESH == lock_id_.obj_type_))); + || ObLockOBJType::OBJ_TYPE_EXTERNAL_TABLE_REFRESH == lock_id_.obj_type_ + || ObLockOBJType::OBJ_TYPE_ONLINE_DDL_TABLE == lock_id_.obj_type_ + || ObLockOBJType::OBJ_TYPE_ONLINE_DDL_TABLET == lock_id_.obj_type_))); } void ObLockRequest::reset() @@ -275,6 +285,42 @@ bool ObLockTabletRequest::is_valid() const tablet_id_.is_valid()); } +void ObLockTabletsRequest::reset() +{ + ObLockTableRequest::reset(); + tablet_ids_.reset(); +} + +bool ObLockTabletsRequest::is_valid() const +{ + bool is_valid = true; + is_valid = (ObLockMsgType::LOCK_TABLET_REQ == type_ && + ObLockRequest::is_valid() && + is_valid_id(table_id_)); + for (int64_t i = 0; i < tablet_ids_.count() && is_valid; i++) { + is_valid = is_valid && tablet_ids_.at(i).is_valid(); + } + return is_valid; +} + +void ObLockAloneTabletRequest::reset() +{ + ObLockTabletsRequest::reset(); + ls_id_.reset(); +} + +bool ObLockAloneTabletRequest::is_valid() const +{ + bool is_valid = true; + is_valid = (ObLockMsgType::LOCK_ALONE_TABLET_REQ == type_ && + ObLockRequest::is_valid() && + ls_id_.is_valid()); + for (int64_t i = 0; i < tablet_ids_.count() && is_valid; i++) { + is_valid = is_valid && tablet_ids_.at(i).is_valid(); + } + return is_valid; +} + int ObTableLockTaskRequest::set( const ObTableLockTaskType task_type, const share::ObLSID &lsid, @@ -378,6 +424,7 @@ bool ObLockTaskBatchRequest::is_valid() const valid = false; } } + valid = valid && tx_desc_->is_valid(); } else { valid = false; } diff --git a/src/storage/tablelock/ob_table_lock_rpc_struct.h b/src/storage/tablelock/ob_table_lock_rpc_struct.h old mode 100644 new mode 100755 index 187076a81..57aa2ae76 --- a/src/storage/tablelock/ob_table_lock_rpc_struct.h +++ b/src/storage/tablelock/ob_table_lock_rpc_struct.h @@ -49,6 +49,12 @@ enum ObTableLockTaskType UNLOCK_SUBPARTITION = 8, LOCK_OBJECT = 9, UNLOCK_OBJECT = 10, + LOCK_DDL_TABLE = 11, + UNLOCK_DDL_TABLE = 12, + LOCK_DDL_TABLET = 13, + UNLOCK_DDL_TABLET = 14, + LOCK_ALONE_TABLET = 15, + UNLOCK_ALONE_TABLET = 16, MAX_TASK_TYPE, }; @@ -109,6 +115,7 @@ public: LOCK_TABLE_REQ = 4, LOCK_PARTITION_REQ = 5, LOCK_TABLET_REQ = 6, + LOCK_ALONE_TABLET_REQ = 7, }; public: ObLockRequest() : @@ -197,6 +204,35 @@ public: }; using ObUnLockTabletRequest = ObLockTabletRequest; +struct ObLockTabletsRequest : public ObLockTableRequest +{ + OB_UNIS_VERSION_V(1); +public: + ObLockTabletsRequest() : tablet_ids_() + { type_ = ObLockMsgType::LOCK_TABLET_REQ; } + virtual ~ObLockTabletsRequest() { reset(); } + virtual void reset(); + virtual bool is_valid() const; + INHERIT_TO_STRING_KV("ObLockTableRequest", ObLockTableRequest, K_(tablet_ids)); + public: + common::ObTabletIDArray tablet_ids_; +}; + +struct ObLockAloneTabletRequest : public ObLockTabletsRequest +{ + OB_UNIS_VERSION_V(1); +public: + ObLockAloneTabletRequest() : ls_id_() + { type_ = ObLockMsgType::LOCK_ALONE_TABLET_REQ; } + virtual ~ObLockAloneTabletRequest() { reset(); } + virtual void reset(); + virtual bool is_valid() const; + INHERIT_TO_STRING_KV("ObLockTabletsRequest", ObLockTabletsRequest, K_(ls_id)); + public: + share::ObLSID ls_id_; +}; +using ObUnLockAloneTabletRequest = ObLockAloneTabletRequest; + class ObTableLockTaskRequest final { OB_UNIS_VERSION(1); @@ -234,13 +270,14 @@ public: ObLockParam param_; transaction::ObTxDesc *tx_desc_; private: + DISALLOW_COPY_AND_ASSIGN(ObTableLockTaskRequest); bool need_release_tx_; }; class ObLockTaskBatchRequest final { OB_UNIS_VERSION(1); - public: +public: ObLockTaskBatchRequest() : task_type_(INVALID_LOCK_TASK_TYPE), lsid_(), @@ -256,17 +293,17 @@ class ObLockTaskBatchRequest final bool is_valid() const; int assign(const ObLockTaskBatchRequest &arg); - TO_STRING_KV(K(task_type_), K(lsid_), K(params_)); - public: + TO_STRING_KV(K(task_type_), K(lsid_), K(params_), KPC(tx_desc_)); +public: ObTableLockTaskType task_type_; share::ObLSID lsid_; // go to which ls to lock. common::ObSArray params_; transaction::ObTxDesc *tx_desc_; - private: +private: + DISALLOW_COPY_AND_ASSIGN(ObLockTaskBatchRequest); bool need_release_tx_; }; - class ObTableLockTaskResult final { OB_UNIS_VERSION(1); @@ -274,20 +311,27 @@ public: ObTableLockTaskResult() : ret_code_(common::OB_SUCCESS), tx_result_ret_code_(common::OB_SUCCESS), - tx_result_() {} + tx_result_(), + can_retry_(false), + success_pos_(-1) {} ~ObTableLockTaskResult() {} int get_ret_code() const { return ret_code_; } int get_tx_result_code() const { return tx_result_ret_code_; } transaction::ObTxExecResult &get_tx_result() { return tx_result_; } + bool can_retry() const { return can_retry_; } + int64_t get_success_pos() const { return success_pos_; } - TO_STRING_KV(K(ret_code_), K(tx_result_)); + TO_STRING_KV(K(ret_code_), K(tx_result_ret_code_), K(tx_result_), K(can_retry_), K(success_pos_)); private: DISALLOW_COPY_AND_ASSIGN(ObTableLockTaskResult); public: int ret_code_; int tx_result_ret_code_; transaction::ObTxExecResult tx_result_; + // retry param + bool can_retry_; // whether we can retry this task or not + int64_t success_pos_; // the pos we need begin to retry }; // --------------------- used for client request ------------------------------ diff --git a/src/storage/tablelock/ob_table_lock_service.cpp b/src/storage/tablelock/ob_table_lock_service.cpp old mode 100644 new mode 100755 index c5af938fa..a638746f2 --- a/src/storage/tablelock/ob_table_lock_service.cpp +++ b/src/storage/tablelock/ob_table_lock_service.cpp @@ -21,8 +21,10 @@ #include "share/schema/ob_part_mgr_util.h" #include "share/schema/ob_schema_getter_guard.h" #include "share/schema/ob_tenant_schema_service.h" +#include "storage/ob_common_id_utils.h" #include "storage/tx/ob_trans_deadlock_adapter.h" #include "storage/tx/ob_trans_service.h" +#include "storage/tablelock/ob_lock_utils.h" // ObInnerTableLockUtil #include "storage/tx_storage/ob_ls_service.h" namespace oceanbase @@ -74,12 +76,12 @@ ObTableLockService::ObTableLockCtx::ObTableLockCtx(const ObTableLockTaskType tas ObTableLockService::ObTableLockCtx::ObTableLockCtx(const ObTableLockTaskType task_type, const uint64_t table_id, - const ObTabletID &tablet_id, + const share::ObLSID &ls_id, const int64_t origin_timeout_us, const int64_t timeout_us) - : ObTableLockCtx(task_type, table_id, origin_timeout_us, timeout_us) + : ObTableLockCtx(task_type, table_id, origin_timeout_us, timeout_us) { - tablet_id_ = tablet_id; + ls_id_ = ls_id; } ObTableLockService::ObTableLockCtx::ObTableLockCtx(const ObTableLockTaskType task_type, @@ -227,6 +229,28 @@ void ObTableLockService::ObOBJLockGarbageCollector::check_and_report_timeout_() } } +int ObTableLockService::ObTableLockCtx::set_tablet_id(const common::ObIArray &tablet_ids) +{ + int ret = OB_SUCCESS; + tablet_list_.reuse(); + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); i++) { + if (OB_FAIL(tablet_list_.push_back(tablet_ids.at(i)))) { + LOG_WARN("set tablet id failed", K(ret), K(i), K(tablet_ids)); + } + } + return ret; +} + +int ObTableLockService::ObTableLockCtx::set_tablet_id(const common::ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + tablet_list_.reuse(); + if (OB_FAIL(tablet_list_.push_back(tablet_id))) { + LOG_WARN("set tablet id failed", K(ret), K(tablet_id)); + } + return ret; +} + bool ObTableLockService::ObTableLockCtx::is_timeout() const { return ObTimeUtility::current_time() >= abs_timeout_ts_; @@ -350,9 +374,8 @@ bool need_retry_partitions(const int64_t ret) int ObTableLockService::generate_owner_id(ObTableLockOwnerID &owner_id) { - // TODO: cxf use idservice to make sure it is unique int ret = OB_SUCCESS; - owner_id = ObTimeUtility::current_time(); + ret = ObCommonIDUtils::gen_unique_id(MTL_ID(), owner_id); return ret; } @@ -387,9 +410,7 @@ int ObTableLockService::lock_table(const uint64_t table_id, ObTableLockCtx ctx(LOCK_TABLE, table_id, timeout_us, retry_timeout_us); ctx.lock_op_type_ = OUT_TRANS_LOCK; ret = process_lock_task_(ctx, lock_mode, lock_owner); - need_retry = (ctx.tx_is_killed_ && - !ctx.is_try_lock() && - !ctx.is_timeout()); + need_retry = need_retry_trans_(ctx, ret); } while (need_retry); } ret = rewrite_return_code_(ret); @@ -414,9 +435,20 @@ int ObTableLockService::unlock_table(const uint64_t table_id, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(table_id), K(lock_mode), K(lock_owner)); } else { - ObTableLockCtx ctx(UNLOCK_TABLE, table_id, timeout_us, timeout_us); - ctx.lock_op_type_ = OUT_TRANS_UNLOCK; - ret = process_lock_task_(ctx, lock_mode, lock_owner); + int64_t retry_timeout_us = timeout_us; + bool need_retry = false; + int64_t abs_timeout_ts = (0 == timeout_us) + ? ObTimeUtility::current_time() + DEFAULT_TIMEOUT_US + : ObTimeUtility::current_time() + timeout_us; + do { + if (timeout_us != 0) { + retry_timeout_us = abs_timeout_ts - ObTimeUtility::current_time(); + } + ObTableLockCtx ctx(UNLOCK_TABLE, table_id, timeout_us, retry_timeout_us); + ctx.lock_op_type_ = OUT_TRANS_UNLOCK; + ret = process_lock_task_(ctx, lock_mode, lock_owner); + need_retry = need_retry_trans_(ctx, ret); + } while (need_retry); } ret = rewrite_return_code_(ret); return ret; @@ -451,12 +483,14 @@ int ObTableLockService::lock_tablet(const uint64_t table_id, if (timeout_us != 0) { retry_timeout_us = abs_timeout_ts - ObTimeUtility::current_time(); } - ObTableLockCtx ctx(LOCK_TABLET, table_id, tablet_id, timeout_us, retry_timeout_us); + ObTableLockCtx ctx(LOCK_TABLET, table_id, timeout_us, retry_timeout_us); ctx.lock_op_type_ = OUT_TRANS_LOCK; - ret = process_lock_task_(ctx, lock_mode, lock_owner); - need_retry = (ctx.tx_is_killed_ && - !ctx.is_try_lock() && - !ctx.is_timeout()); + if (OB_FAIL(ctx.set_tablet_id(tablet_id))) { + LOG_WARN("set tablet id failed", K(ret), K(tablet_id)); + } else if (OB_FAIL(process_lock_task_(ctx, lock_mode, lock_owner))) { + LOG_WARN("process lock task failed", K(ret), K(tablet_id)); + } + need_retry = need_retry_trans_(ctx, ret); } while (need_retry); } ret = rewrite_return_code_(ret); @@ -482,11 +516,27 @@ int ObTableLockService::unlock_tablet(const uint64_t table_id, LOG_WARN("invalid argument", K(ret), K(table_id), K(tablet_id), K(lock_mode), K(lock_owner)); } else { - ObTableLockCtx ctx(UNLOCK_TABLET, table_id, tablet_id, timeout_us, timeout_us); - ctx.lock_op_type_ = OUT_TRANS_UNLOCK; - ret = process_lock_task_(ctx, lock_mode, lock_owner); + int64_t retry_timeout_us = timeout_us; + bool need_retry = false; + int64_t abs_timeout_ts = (0 == timeout_us) + ? ObTimeUtility::current_time() + DEFAULT_TIMEOUT_US + : ObTimeUtility::current_time() + timeout_us; + do { + if (timeout_us != 0) { + retry_timeout_us = abs_timeout_ts - ObTimeUtility::current_time(); + } + ObTableLockCtx ctx(UNLOCK_TABLET, table_id, timeout_us, retry_timeout_us); + ctx.lock_op_type_ = OUT_TRANS_UNLOCK; + if (OB_FAIL(ctx.set_tablet_id(tablet_id))) { + LOG_WARN("set tablet id failed", K(ret), K(tablet_id)); + } else if (OB_FAIL(process_lock_task_(ctx, lock_mode, lock_owner))) { + LOG_WARN("process lock task failed", K(ret), K(tablet_id)); + } + need_retry = need_retry_trans_(ctx, ret); + } while (need_retry); } ret = rewrite_return_code_(ret); + return ret; } @@ -553,7 +603,7 @@ int ObTableLockService::lock_tablet(ObTxDesc &tx_desc, const ObLockTabletRequest &arg) { int ret = OB_SUCCESS; - const ObTableLockOwnerID lock_owner = 0; + const ObTableLockOwnerID lock_owner(0); if (IS_NOT_INIT) { ret = OB_NOT_INIT; @@ -565,13 +615,17 @@ int ObTableLockService::lock_tablet(ObTxDesc &tx_desc, LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), K(tx_param.is_valid()), K(arg.is_valid())); } else { - ObTableLockCtx ctx(LOCK_TABLET, arg.table_id_, arg.tablet_id_, + ObTableLockCtx ctx(LOCK_TABLET, arg.table_id_, arg.timeout_us_, arg.timeout_us_); ctx.is_in_trans_ = true; ctx.tx_desc_ = &tx_desc; ctx.tx_param_ = tx_param; ctx.lock_op_type_ = arg.op_type_; - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); + if (OB_FAIL(ctx.set_tablet_id(arg.tablet_id_))) { + LOG_WARN("set tablet id failed", K(ret), K(arg)); + } else if (OB_FAIL(process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_))) { + LOG_WARN("process lock task failed", K(ret), K(arg)); + } } return ret; } @@ -581,7 +635,7 @@ int ObTableLockService::unlock_tablet(ObTxDesc &tx_desc, const ObUnLockTabletRequest &arg) { int ret = OB_SUCCESS; - const ObTableLockOwnerID lock_owner = 0; + const ObTableLockOwnerID lock_owner(0); if (IS_NOT_INIT) { ret = OB_NOT_INIT; @@ -594,13 +648,84 @@ int ObTableLockService::unlock_tablet(ObTxDesc &tx_desc, LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), K(tx_param.is_valid()), K(arg.is_valid())); } else { - ObTableLockCtx ctx(UNLOCK_TABLET, arg.table_id_, arg.tablet_id_, + ObTableLockCtx ctx(UNLOCK_TABLET, arg.table_id_, arg.timeout_us_, arg.timeout_us_); ctx.is_in_trans_ = true; ctx.tx_desc_ = &tx_desc; ctx.tx_param_ = tx_param; ctx.lock_op_type_ = arg.op_type_; - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); + if (OB_FAIL(ctx.set_tablet_id(arg.tablet_id_))) { + LOG_WARN("set tablet id failed", K(ret), K(arg)); + } else if (OB_FAIL(process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_))) { + LOG_WARN("process lock task failed", K(ret), K(arg)); + } + } + return ret; +} + +int ObTableLockService::lock_tablet(ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObLockAloneTabletRequest &arg) +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("lock service is not inited", K(ret)); + } else if (OB_UNLIKELY(!tx_desc.is_valid()) || + OB_UNLIKELY(!tx_param.is_valid()) || + OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), + K(tx_param.is_valid()), K(arg.is_valid())); + } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_2_0_0))) { + LOG_WARN("cluster version check failed", K(ret), K(arg)); + } else { + ObTableLockCtx ctx(LOCK_ALONE_TABLET, arg.table_id_, + arg.ls_id_, arg.timeout_us_, arg.timeout_us_); + ctx.is_in_trans_ = true; + ctx.tx_desc_ = &tx_desc; + ctx.tx_param_ = tx_param; + ctx.lock_op_type_ = arg.op_type_; + if (OB_FAIL(ctx.set_tablet_id(arg.tablet_ids_))) { + LOG_WARN("set tablet id failed", K(ret), K(arg)); + } else if (OB_FAIL(process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_))) { + LOG_WARN("process lock task failed", K(ret), K(arg)); + } + } + return ret; +} + +int ObTableLockService::unlock_tablet(ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObUnLockAloneTabletRequest &arg) +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("lock service is not inited", K(ret)); + } else if (OB_UNLIKELY(!tx_desc.is_valid()) || + OB_UNLIKELY(!tx_param.is_valid()) || + OB_UNLIKELY(!arg.is_valid()) || + OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), + K(tx_param.is_valid()), K(arg.is_valid())); + } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_2_0_0))) { + LOG_WARN("cluster version check failed", K(ret), K(arg)); + } else { + ObTableLockCtx ctx(UNLOCK_ALONE_TABLET, arg.table_id_, + arg.ls_id_, arg.timeout_us_, arg.timeout_us_); + ctx.is_in_trans_ = true; + ctx.tx_desc_ = &tx_desc; + ctx.tx_param_ = tx_param; + ctx.lock_op_type_ = arg.op_type_; + if (OB_FAIL(ctx.set_tablet_id(arg.tablet_ids_))) { + LOG_WARN("set tablet id failed", K(ret), K(arg)); + } else if (OB_FAIL(process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_))) { + LOG_WARN("process lock task failed", K(ret), K(arg)); + } } return ret; } @@ -655,6 +780,8 @@ int ObTableLockService::lock_partition(ObTxDesc &tx_desc, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(tx_desc.is_valid()), K(tx_param.is_valid()), K(arg.is_valid()), K(tx_desc), K(tx_param), K(arg)); + } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_1_0_0))) { + LOG_WARN("cluster version check failed", K(ret), K(arg)); } else { ObTableLockCtx ctx(LOCK_PARTITION, arg.table_id_, arg.part_object_id_, arg.timeout_us_, arg.timeout_us_); @@ -684,6 +811,8 @@ int ObTableLockService::unlock_partition(ObTxDesc &tx_desc, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), K(tx_param.is_valid()), K(arg.is_valid())); + } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_1_0_0))) { + LOG_WARN("cluster version check failed", K(ret), K(arg)); } else { ObTableLockCtx ctx(UNLOCK_PARTITION, arg.table_id_, arg.part_object_id_, arg.timeout_us_, arg.timeout_us_); @@ -711,6 +840,8 @@ int ObTableLockService::lock_subpartition(ObTxDesc &tx_desc, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), K(tx_param.is_valid()), K(arg.is_valid())); + } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_1_0_0))) { + LOG_WARN("cluster version check failed", K(ret), K(arg)); } else { ObTableLockCtx ctx(LOCK_SUBPARTITION, arg.table_id_, arg.part_object_id_, arg.timeout_us_, arg.timeout_us_); @@ -740,6 +871,8 @@ int ObTableLockService::unlock_subpartition(ObTxDesc &tx_desc, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), K(tx_param.is_valid()), K(arg.is_valid())); + } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_1_0_0))) { + LOG_WARN("cluster version check failed", K(ret), K(arg)); } else { ObTableLockCtx ctx(UNLOCK_SUBPARTITION, arg.table_id_, arg.part_object_id_, arg.timeout_us_, arg.timeout_us_); @@ -767,6 +900,8 @@ int ObTableLockService::lock_obj(ObTxDesc &tx_desc, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), K(tx_param.is_valid()), K(arg.is_valid())); + } else if (OB_FAIL(check_data_version_after_(DATA_VERSION_4_1_0_0))) { + LOG_WARN("data version check failed", K(ret), K(arg)); } else { ObTableLockCtx ctx(LOCK_OBJECT, arg.obj_type_, arg.obj_id_, arg.timeout_us_, arg.timeout_us_); ctx.is_in_trans_ = true; @@ -794,6 +929,8 @@ int ObTableLockService::unlock_obj(ObTxDesc &tx_desc, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), K(tx_param.is_valid()), K(arg.is_valid())); + } else if (OB_FAIL(check_data_version_after_(DATA_VERSION_4_1_0_0))) { + LOG_WARN("data version check failed", K(ret), K(arg)); } else { ObTableLockCtx ctx(UNLOCK_OBJECT, arg.obj_type_, arg.obj_id_, arg.timeout_us_, arg.timeout_us_); ctx.is_in_trans_ = true; @@ -836,10 +973,6 @@ int ObTableLockService::process_lock_task_(ObTableLockCtx &ctx, { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; - const uint64_t tenant_id = MTL_ID(); - ObSchemaGetterGuard schema_guard; - const ObTableSchema *table_schema = NULL; - ObMultiVersionSchemaService *schema_service = MTL(ObTenantSchemaService*)->get_schema_service(); if (!ctx.is_in_trans_ && OB_FAIL(start_tx_(ctx))) { LOG_WARN("failed to start trans", K(ret)); @@ -849,9 +982,14 @@ int ObTableLockService::process_lock_task_(ObTableLockCtx &ctx, if (OB_FAIL(process_obj_lock_task_(ctx, lock_mode, lock_owner))) { LOG_WARN("lock obj failed", K(ret), K(ctx), K(lock_mode), K(lock_owner)); } + } else if (LOCK_ALONE_TABLET == ctx.task_type_ || UNLOCK_ALONE_TABLET == ctx.task_type_) { + // only alone tablet should do like this. + if (OB_FAIL(process_tablet_lock_task_(ctx, lock_mode, lock_owner, nullptr/* schema ptr */))) { + LOG_WARN("process tablet lock task failed", K(ret), K(ctx), K(lock_mode), K(lock_owner)); + } } else { if (OB_FAIL(process_table_lock_task_(ctx, lock_mode, lock_owner))) { - LOG_WARN("lock table task failed", K(ret), K(ctx), K(lock_mode), K(lock_owner)); + LOG_WARN("process table lock task failed", K(ret), K(ctx), K(lock_mode), K(lock_owner)); } } @@ -902,39 +1040,59 @@ int ObTableLockService::process_table_lock_task_(ObTableLockCtx &ctx, { int ret = OB_SUCCESS; const uint64_t tenant_id = MTL_ID(); - ObTableSchema *table_schema = nullptr; - ObRefreshSchemaStatus schema_status; - ObMultiVersionSchemaService *schema_service = MTL(ObTenantSchemaService*)->get_schema_service(); + ObSimpleTableSchemaV2 *table_schema = nullptr; bool is_allowed = false; - LockMap lock_map; - ObLSLockMap ls_lock_map; ObArenaAllocator allocator("TableSchema"); - schema_status.tenant_id_ = tenant_id; ctx.schema_version_ = 0; if (OB_FAIL(process_table_lock_(ctx, lock_mode, lock_owner))) { LOG_WARN("lock table failed", K(ret), K(ctx), K(lock_mode), K(lock_owner)); - } else if (OB_FAIL(schema_service->get_schema_service()->get_table_schema(schema_status, - ctx.table_id_, - INT64_MAX - 1/* refresh the newest schema */, - *sql_proxy_, - allocator, - table_schema))) { - LOG_WARN("get table schema failed", K(ret), K(ctx)); - } else if (OB_ISNULL(table_schema)) { - ret = OB_TABLE_NOT_EXIST; - LOG_INFO("table not exist, check whether it meets expectations", K(ret), K(ctx)); - } else if (FALSE_IT(ctx.schema_version_ = table_schema->get_schema_version())) { + } else if (OB_FAIL(ObSchemaUtils::get_latest_table_schema( + *sql_proxy_, + allocator, + tenant_id, + ctx.table_id_, + table_schema))) { + if (OB_TABLE_NOT_EXIST == ret) { + LOG_INFO("table not exist, check whether it meets expectations", K(ret), K(ctx)); + } else { + LOG_WARN("get table schema failed", K(ret), K(ctx)); + } } else if (OB_FAIL(check_op_allowed_(ctx.table_id_, table_schema, is_allowed))) { LOG_WARN("failed to check op allowed", K(ret), K(ctx)); } else if (!is_allowed) { ret = OB_OP_NOT_ALLOW; LOG_WARN("lock table not allowed now", K(ret), K(ctx)); - } else if (OB_FAIL(get_process_tablets_(lock_mode, table_schema, ctx))) { + } else if (OB_FAIL(process_tablet_lock_task_(ctx, + lock_mode, + lock_owner, + table_schema))) { + LOG_WARN("failed to lock table tablet", K(ret), K(ctx)); + } + return ret; +} + +int ObTableLockService::process_tablet_lock_task_(ObTableLockCtx &ctx, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + const ObSimpleTableSchemaV2 *table_schema) +{ + int ret = OB_SUCCESS; + LockMap lock_map; + ObLSLockMap ls_lock_map; + + // TODO: yanyuan.cxf we may need the right schema_version while lock/unlock alone tablet. + if (OB_ISNULL(table_schema)) { + ctx.schema_version_ = 0; + } else { + ctx.schema_version_ = table_schema->get_schema_version(); + } + + if (OB_FAIL(get_process_tablets_(lock_mode, table_schema, ctx))) { LOG_WARN("failed to get parts", K(ret), K(ctx)); // lock_map and ls_lock_map are the map of lock which is generated with tablet_id - } else if (OB_FAIL(get_ls_lock_map_(ctx, lock_map, ls_lock_map))) { + } else if (OB_FAIL(get_ls_lock_map_(ctx, ctx.tablet_list_, lock_map, ls_lock_map))) { LOG_WARN("fail to get ls lock map", K(ret), K(ctx.get_tablet_cnt())); } else if (OB_FAIL(pre_check_lock_(ctx, lock_mode, @@ -955,7 +1113,8 @@ bool ObTableLockService::is_part_table_lock_(const ObTableLockTaskType task_type { return (LOCK_TABLET == task_type || UNLOCK_TABLET == task_type || LOCK_PARTITION == task_type || UNLOCK_PARTITION == task_type || - LOCK_SUBPARTITION == task_type || UNLOCK_SUBPARTITION == task_type); + LOCK_SUBPARTITION == task_type || UNLOCK_SUBPARTITION == task_type || + LOCK_ALONE_TABLET == task_type || UNLOCK_ALONE_TABLET == task_type); } int ObTableLockService::get_table_lock_mode_(const ObTableLockTaskType task_type, @@ -984,17 +1143,72 @@ int ObTableLockService::get_table_lock_mode_(const ObTableLockTaskType task_type return ret; } +int ObTableLockService::get_retry_tablet_list_(const ObLockIDArray &lock_ids, + common::ObTabletIDArray &retry_tablets) +{ + int ret = OB_SUCCESS; + common::ObTabletID tablet_id; + for (int64_t i = 0; i < lock_ids.count() && OB_SUCC(ret); ++i) { + if (OB_FAIL(lock_ids.at(i).convert_to(tablet_id))) { + LOG_WARN("lock id failed to convert to tablet id", K(ret)); + } else if (OB_FAIL(retry_tablets.push_back(tablet_id))) { + LOG_WARN("get retry tablet failed", K(ret), K(tablet_id)); + } + } + return ret; +} + +template +int ObTableLockService::get_retry_tablet_list_(const ObLSLockMap &ls_lock_map, + const RpcProxy &proxy_batch, + const ObArray &ls_array, + common::ObTabletIDArray &retry_tablets) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObLockIDArray *lock_ids = nullptr; + common::ObTabletID tablet_id; + ObLSID ls_id; + for (int64_t i = 0; i < proxy_batch.get_results().count() && OB_SUCC(ret); ++i) { + const ObTableLockTaskResult *result = proxy_batch.get_results().at(i); + ls_id = ls_array.at(i); + if (OB_ISNULL(result)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret), K(i), K(ls_id)); + } else if (FALSE_IT(tmp_ret = result->get_ret_code())) { + } else if (OB_TMP_FAIL(tmp_ret) && need_retry_rpc_task_(tmp_ret, result)) { + // get the retry tablet list + if (OB_ISNULL(lock_ids = const_cast(ls_lock_map.get(ls_id)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the ls not exist at tablet map", K(ret), K(ls_id)); + } else { + // get the tablet ids + for (int64_t i = result->get_success_pos() + 1; i < lock_ids->count() && OB_SUCC(ret); ++i) { + if (OB_FAIL(lock_ids->at(i).convert_to(tablet_id))) { + LOG_WARN("lock id failed to convert to tablet id", K(ret)); + } else if (OB_FAIL(retry_tablets.push_back(tablet_id))) { + LOG_WARN("get retry tablet failed", K(ret), K(tablet_id)); + } + } + } + } + } + return ret; +} + template int ObTableLockService::handle_parallel_rpc_response_(int rpc_call_ret, int64_t rpc_count, RpcProxy &proxy_batch, ObTableLockCtx &ctx, - ObArray &ls_array) + ObArray &ls_array, + bool &can_retry) { int ret = rpc_call_ret; int tmp_ret = OB_SUCCESS; ObTransService *txs = MTL(ObTransService*); + can_retry = true; if (OB_FAIL(ret)) { // need wait rpcs that sent finish // otherwise proxy reused or destructored will cause flying rpc core @@ -1007,6 +1221,7 @@ int ObTableLockService::handle_parallel_rpc_response_(int rpc_call_ret, LOG_ERROR("add touched ls failed.", K(tmp_ret), K(ls_array.at(i))); } } + can_retry = false; } else { // handle result ObArray return_code_array; @@ -1021,6 +1236,7 @@ int ObTableLockService::handle_parallel_rpc_response_(int rpc_call_ret, LOG_ERROR("add touched ls failed.", K(tmp_ret), K(ls_array.at(i))); } } + can_retry = false; } else { //check each ret of every rpc for (int64_t i = 0; i < return_code_array.count(); ++i) { @@ -1038,6 +1254,7 @@ int ObTableLockService::handle_parallel_rpc_response_(int rpc_call_ret, // we need add the ls into touched to make rollback. if (OB_SUCCESS != tmp_ret) { ret = tmp_ret; + can_retry = false; share::ObLSID ls_id = ls_array.at(i); if (OB_SUCCESS != (tmp_ret = ctx.add_touched_ls(ls_id))) { LOG_ERROR("add touched ls failed.", K(tmp_ret), K(ls_id)); @@ -1045,6 +1262,7 @@ int ObTableLockService::handle_parallel_rpc_response_(int rpc_call_ret, } else if (OB_SUCCESS != (tmp_ret = (txs->add_tx_exec_result(*ctx.tx_desc_, proxy_batch.get_results().at(i)->tx_result_)))) { ret = tmp_ret; + can_retry = false; // must rollback the whole tx. LOG_WARN("failed to add exec result", K(tmp_ret), K(ctx), K(proxy_batch.get_results().at(i)->tx_result_)); @@ -1052,11 +1270,14 @@ int ObTableLockService::handle_parallel_rpc_response_(int rpc_call_ret, LOG_ERROR("add touched ls failed.", K(tmp_ret), K(ls_array.at(i))); } } else { - // if error codes are noly OB_TRY_LOCK_ROW_CONFLICT, will retry + // if error codes are only OB_TRY_LOCK_ROW_CONFLICT, will retry tmp_ret = result->get_ret_code(); if (OB_TRANS_KILLED == tmp_ret) { // the trans need kill. ctx.tx_is_killed_ = true; + can_retry = false; + } else if (OB_TMP_FAIL(tmp_ret)) { + can_retry = can_retry && need_retry_rpc_task_(tmp_ret, result); } if (OB_FAIL(tmp_ret)) { LOG_WARN("lock rpc wrong", K(tmp_ret), K(ls_array.at(i))); @@ -1087,6 +1308,160 @@ int ObTableLockService::pre_check_lock_(ObTableLockCtx &ctx, } // for 4.1 +template +int ObTableLockService::parallel_batch_rpc_handle_(RpcProxy &proxy_batch, + ObTableLockCtx &ctx, + const ObTableLockTaskType lock_task_type, + const ObLSLockMap &ls_lock_map, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner) +{ + int ret = OB_SUCCESS; + constexpr static int64_t MAP_NUM = 2; + ObLSLockMap maps[MAP_NUM]; + const ObLSLockMap *in_map = nullptr; + ObLSLockMap *retry_map = nullptr; + bool can_retry = true; // whether the whole rpc task can retry. + int64_t retry_times = 0; + for (int64_t i = 0; i < MAP_NUM && OB_SUCC(ret); i++) { + if (OB_FAIL(maps[i].create(10, lib::ObLabel("LSLockMap")))) { + LOG_WARN("ls lock map create failed", KR(ret), K(i)); + } + } + if (OB_FAIL(ret)) { + // do nothing + } else { + retry_map = const_cast(&ls_lock_map); + do { + in_map = retry_map; + retry_map = &maps[retry_times % MAP_NUM]; + if (OB_FAIL(parallel_batch_rpc_handle_(proxy_batch, + ctx, + lock_task_type, + *in_map, + lock_mode, + lock_owner, + can_retry, + *retry_map))) { + LOG_WARN("process rpc failed", KR(ret), K(ctx), K(retry_times)); + } + if (can_retry && !retry_map->empty()) { + retry_times++; + } + if (retry_times % 10) { + LOG_WARN("retry too many times", K(retry_times), K(ctx)); + } + } while (can_retry && !retry_map->empty()); + } + return ret; +} + +template +int ObTableLockService::parallel_batch_rpc_handle_(RpcProxy &proxy_batch, + ObTableLockCtx &ctx, + const ObTableLockTaskType lock_task_type, + const ObLSLockMap &ls_lock_map, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + bool &can_retry, + ObLSLockMap &retry_ls_lock_map) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + int64_t rpc_count = 0; + int64_t timeout_us = 0; + ObArray ls_array; + common::ObTabletIDArray retry_tablets; + bool tmp_can_retry = false; // whether a single rpc can retry. + bool has_retry = false; + proxy_batch.reuse(); + + // send async rpc parallel + FOREACH_X(data, ls_lock_map, OB_SUCC(ret) || can_retry) { + tmp_can_retry = false; + share::ObLSID ls_id = data->first; + const ObLockIDArray &lock_ids = data->second; + ObLockTaskBatchRequest request; + ObAddr addr; + if (!has_retry) { + if (OB_FAIL(ls_array.push_back(ls_id))) { + LOG_WARN("push_back lsid failed", K(ret), K(ls_id)); + } else if (OB_FAIL(pack_batch_request_(ctx, + lock_task_type, + lock_mode, + lock_owner, + ls_id, + lock_ids, + request))) { + LOG_WARN("pack_request_ failed", K(ret), K(ls_id)); + } else if (OB_FAIL(get_ls_leader_(ctx.tx_desc_->get_cluster_id(), + ctx.tx_desc_->get_tenant_id(), + ls_id, + ctx.abs_timeout_ts_, + addr))) { + if (need_renew_location_(ret)) { + tmp_can_retry = true; + ret = OB_SUCCESS; + } + LOG_WARN("failed to get ls leader", K(ret), K(ctx), K(ls_id)); + } else if (FALSE_IT(timeout_us = ctx.get_rpc_timeoutus())) { + } else if (ctx.is_timeout()) { + ret = OB_TIMEOUT; + LOG_WARN("process obj lock timeout", K(ret), K(ctx)); + } else if (OB_FAIL(proxy_batch.call(addr, + timeout_us, + ctx.tx_desc_->get_tenant_id(), + request))) { + LOG_WARN("failed to all async rpc", KR(ret), K(addr), + K(ctx.abs_timeout_ts_), K(request)); + } else { + rpc_count++; + ALLOW_NEXT_LOG(); + LOG_INFO("send table lock rpc", KR(ret), K(addr), "request", request); + } + } + if (tmp_can_retry || has_retry) { + has_retry = true; + if (OB_TMP_FAIL(get_retry_tablet_list_(lock_ids, + retry_tablets))) { + LOG_WARN("get retry tablet failed", KR(ret)); + ret = tmp_ret; + can_retry = false; + }; + } + } + + ret = handle_parallel_rpc_response_(ret, + rpc_count, + proxy_batch, + ctx, + ls_array, + tmp_can_retry); + can_retry = can_retry && tmp_can_retry; + // does not need retry if it is success. + if (OB_FAIL(ret) && can_retry) { + if (OB_TMP_FAIL(get_retry_tablet_list_(ls_lock_map, + proxy_batch, + ls_array, + retry_tablets))) { + LOG_WARN("get retry tablet failed", KR(tmp_ret)); + ret = tmp_ret; + can_retry = false; + }; + } + // get the retry map + if (can_retry and retry_tablets.count() != 0) { + if (OB_FAIL(fill_ls_lock_map_(ctx, + retry_tablets, + retry_ls_lock_map, + true /* force refresh location */))) { + LOG_WARN("refill ls lock map failed", KP(ret), K(ctx)); + can_retry = false; + } + } + return ret; +} + int ObTableLockService::batch_pre_check_lock_(ObTableLockCtx &ctx, const ObTableLockMode lock_mode, const ObTableLockOwnerID lock_owner, @@ -1096,53 +1471,32 @@ int ObTableLockService::batch_pre_check_lock_(ObTableLockCtx &ctx, int last_ret = OB_SUCCESS; int64_t USLEEP_TIME = 100; // 0.1 ms bool need_retry = false; - ObArray ls_array; ObBatchLockProxy proxy_batch(*GCTX.srv_rpc_proxy_, &obrpc::ObSrvRpcProxy::batch_lock_obj); // only used in LOCK_TABLE/LOCK_PARTITION if (LOCK_TABLE == ctx.task_type_ || LOCK_PARTITION == ctx.task_type_) { do { need_retry = false; - int64_t rpc_count = 0; - int64_t timeout_us = 0; - proxy_batch.reuse(); - ls_array.reuse(); - - // send async rpc parallel - FOREACH_X(data, ls_lock_map, OB_SUCC(ret)) { - share::ObLSID ls_id = data->first; - const ObLockIDArray &lock_ids = data->second; - ObLockTaskBatchRequest request; - ObAddr addr; - if (OB_FAIL(ls_array.push_back(ls_id))) { - LOG_WARN("push_back lsid failed", K(ret), K(ls_id)); - } else if (OB_FAIL(pack_batch_request_(ctx, PRE_CHECK_TABLET, lock_mode, lock_owner, - ls_id, lock_ids, request))) { - LOG_WARN("pack_request_ failed", K(ret), K(ls_id)); - } else if (OB_FAIL(get_ls_leader_(ctx.tx_desc_->get_cluster_id(), - ctx.tx_desc_->get_tenant_id(), - ls_id, - ctx.abs_timeout_ts_, - addr))) { - LOG_WARN("failed to get ls leader", K(ret), K(ctx), K(ls_id)); - } else if (FALSE_IT(timeout_us = ctx.get_rpc_timeoutus())) { - } else if (ctx.is_timeout()) { - ret = (last_ret == OB_TRY_LOCK_ROW_CONFLICT) ? OB_ERR_EXCLUSIVE_LOCK_CONFLICT : OB_TIMEOUT; + if (ctx.is_timeout()) { + ret = (last_ret == OB_TRY_LOCK_ROW_CONFLICT) ? + OB_ERR_EXCLUSIVE_LOCK_CONFLICT : OB_TIMEOUT; + LOG_WARN("process obj lock timeout", K(ret), K(ctx)); + } else { + ret = parallel_batch_rpc_handle_(proxy_batch, + ctx, + PRE_CHECK_TABLET, + ls_lock_map, + lock_mode, + lock_owner); + // the process process may be timeout because left time not enough, + // just rewrite it to OB_ERR_EXCLUSIVE_LOCK_CONFLICT + if (is_timeout_ret_code_(ret)) { + ret = (last_ret == OB_TRY_LOCK_ROW_CONFLICT) ? + OB_ERR_EXCLUSIVE_LOCK_CONFLICT : OB_TIMEOUT; LOG_WARN("process obj lock timeout", K(ret), K(ctx)); - } else if (OB_FAIL(proxy_batch.call(addr, - timeout_us, - ctx.tx_desc_->get_tenant_id(), - request))) { - LOG_WARN("failed to all async rpc", KR(ret), K(addr), - K(ctx.abs_timeout_ts_), K(request)); - } else { - rpc_count++; - ALLOW_NEXT_LOG(); - LOG_INFO("send table pre_check rpc", KR(ret), K(addr), "request", request); } } - ret = handle_parallel_rpc_response_(ret, rpc_count, proxy_batch, ctx, ls_array); if (!ctx.is_try_lock() && ctx.is_deadlock_avoid_enabled() && OB_TRY_LOCK_ROW_CONFLICT == ret) { @@ -1162,7 +1516,7 @@ int ObTableLockService::batch_pre_check_lock_(ObTableLockCtx &ctx, ob_usleep(USLEEP_TIME); } } - } while (need_retry); + } while (need_retry); // retry task level LOG_DEBUG("ObTableLockService::pre_check_lock_", K(ret), K(ctx), K(ctx.task_type_), K(lock_mode), K(lock_owner)); } @@ -1177,6 +1531,7 @@ int ObTableLockService::pre_check_lock_old_version_(ObTableLockCtx &ctx, int last_ret = OB_SUCCESS; int64_t USLEEP_TIME = 100; // 0.1 ms bool need_retry = false; + bool unused = false; // only used in LOCK_TABLE/LOCK_PARTITION if (LOCK_TABLE == ctx.task_type_ || LOCK_PARTITION == ctx.task_type_) { @@ -1193,10 +1548,9 @@ int ObTableLockService::pre_check_lock_old_version_(ObTableLockCtx &ctx, share::ObLSID ls_id; ObLockID lock_id; ObTabletID &tablet_id = ctx.tablet_list_.at(i); - if (OB_FAIL(get_tablet_ls_(tablet_id, ls_id))) { + if (OB_FAIL(get_tablet_ls_(ctx, tablet_id, ls_id))) { LOG_WARN("failed to get tablet ls", K(ret), K(tablet_id)); - } else if (OB_FAIL(get_lock_id(tablet_id, - lock_id))) { + } else if (OB_FAIL(get_lock_id(tablet_id, lock_id))) { LOG_WARN("get lock id failed", K(ret), K(ctx)); } else { ObAddr addr; @@ -1226,8 +1580,13 @@ int ObTableLockService::pre_check_lock_old_version_(ObTableLockCtx &ctx, } } } + ret = handle_parallel_rpc_response_(ret, rpc_count, proxy_batch, ctx, ls_array, unused); + + if (is_timeout_ret_code_(ret)) { + ret = (last_ret == OB_TRY_LOCK_ROW_CONFLICT) ? OB_ERR_EXCLUSIVE_LOCK_CONFLICT : OB_TIMEOUT; + LOG_WARN("process obj lock timeout", K(ret), K(ctx)); + } - ret = handle_parallel_rpc_response_(ret, rpc_count, proxy_batch, ctx, ls_array); if (!ctx.is_try_lock() && ctx.is_deadlock_avoid_enabled() && OB_TRY_LOCK_ROW_CONFLICT == ret) { @@ -1283,22 +1642,15 @@ int ObTableLockService::get_table_partition_level_(const ObTableID table_id, ObPartitionLevel &part_level) { int ret = OB_SUCCESS; - ObMultiVersionSchemaService *schema_service = MTL(ObTenantSchemaService*)->get_schema_service(); - ObRefreshSchemaStatus schema_status; - ObTableSchema *table_schema = nullptr; + ObSimpleTableSchemaV2 *table_schema = nullptr; ObArenaAllocator allocator("TableSchema"); - schema_status.tenant_id_ = MTL_ID(); - if (OB_ISNULL(schema_service)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("can not get schema service", K(ret)); - } else if (OB_FAIL(schema_service->get_schema_service() - ->get_table_schema(schema_status, - table_id, - INT64_MAX - 1 /* refresh the newest schema */, - *sql_proxy_, - allocator, - table_schema))) { + if (OB_FAIL(ObSchemaUtils::get_latest_table_schema( + *sql_proxy_, + allocator, + MTL_ID(), + table_id, + table_schema))) { LOG_WARN("can not get table schema", K(ret), K(table_id)); } else { part_level = table_schema->get_part_level(); @@ -1380,8 +1732,61 @@ int ObTableLockService::batch_rpc_handle_(RpcProxy &proxy_batch, const ObTableLockOwnerID lock_owner) { int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + constexpr static int64_t MAP_NUM = 2; + ObLSLockMap maps[MAP_NUM]; + const ObLSLockMap *in_map = nullptr; + ObLSLockMap *retry_map = nullptr; + bool can_retry = true; // whether the whole rpc task can retry. + int64_t retry_times = 0; + for (int64_t i = 0; i < MAP_NUM && OB_SUCC(ret); i++) { + if (OB_FAIL(maps[i].create(10, lib::ObLabel("LSLockMap")))) { + LOG_WARN("ls lock map create failed", KR(ret), K(i)); + } + } + if (OB_FAIL(ret)) { + // do nothing + } else { + retry_map = const_cast(&ls_lock_map); + do { + in_map = retry_map; + retry_map = &maps[retry_times % MAP_NUM]; + if (OB_FAIL(batch_rpc_handle_(proxy_batch, + ctx, + *in_map, + lock_mode, + lock_owner, + can_retry, + *retry_map))) { + LOG_WARN("process rpc failed", KR(ret), K(ctx), K(retry_times)); + } + if (can_retry && !retry_map->empty()) { + retry_times++; + } + if (retry_times % 10) { + LOG_WARN("retry too many times", K(retry_times), K(ctx), K(retry_map->size())); + } + } while (can_retry && !retry_map->empty()); + } + return ret; +} + +template +int ObTableLockService::batch_rpc_handle_(RpcProxy &proxy_batch, + ObTableLockCtx &ctx, + const ObLSLockMap &ls_lock_map, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + bool &can_retry, + ObLSLockMap &retry_ls_lock_map) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; int64_t timeout_us = 0; - FOREACH_X(data, ls_lock_map, OB_SUCC(ret)) { + common::ObTabletIDArray retry_tablets; + bool tmp_can_retry = false; // whether a single rpc can retry. + FOREACH_X(data, ls_lock_map, OB_SUCC(ret) || can_retry) { + tmp_can_retry = false; proxy_batch.reuse(); ObArray ls_array; int64_t rpc_count = 0; @@ -1400,6 +1805,10 @@ int ObTableLockService::batch_rpc_handle_(RpcProxy &proxy_batch, ls_id, ctx.abs_timeout_ts_, addr))) { + if (need_renew_location_(ret)) { + tmp_can_retry = true; + ret = OB_SUCCESS; + } LOG_WARN("failed to get ls leader", K(ret), K(ctx), K(ls_id)); } else if (FALSE_IT(timeout_us = ctx.get_rpc_timeoutus())) { } else if (ctx.is_timeout()) { @@ -1416,7 +1825,42 @@ int ObTableLockService::batch_rpc_handle_(RpcProxy &proxy_batch, ALLOW_NEXT_LOG(); LOG_INFO("send table lock rpc", KR(ret), K(rpc_count), K(addr), "request", request); } - ret = handle_parallel_rpc_response_(ret, rpc_count, proxy_batch, ctx, ls_array); + if (tmp_can_retry) { + if (OB_FAIL(get_retry_tablet_list_(lock_ids, + retry_tablets))) { + LOG_WARN("get retry tablet failed", KR(ret)); + can_retry = false; + }; + } else { + ret = handle_parallel_rpc_response_(ret, + rpc_count, + proxy_batch, + ctx, + ls_array, + tmp_can_retry); + } + can_retry = can_retry && tmp_can_retry; + // does not need retry if it is success. + if (OB_FAIL(ret) && can_retry) { + if (OB_TMP_FAIL(get_retry_tablet_list_(ls_lock_map, + proxy_batch, + ls_array, + retry_tablets))) { + LOG_WARN("get retry tablet failed", KR(tmp_ret)); + ret = tmp_ret; + can_retry = false; + }; + } + } + // get the retry map + if (can_retry and retry_tablets.count() != 0) { + if (OB_FAIL(fill_ls_lock_map_(ctx, + retry_tablets, + retry_ls_lock_map, + true /* force refresh location */))) { + LOG_WARN("refill ls lock map failed", KP(ret), K(ctx)); + can_retry = false; + } } return ret; } @@ -1430,6 +1874,7 @@ int ObTableLockService::parallel_rpc_handle_(RpcProxy &proxy_batch, { int ret = OB_SUCCESS; int64_t timeout_us = 0; + bool unused = false; FOREACH_X(lock, lock_map, OB_SUCC(ret)) { proxy_batch.reuse(); ObArray ls_array; @@ -1438,7 +1883,6 @@ int ObTableLockService::parallel_rpc_handle_(RpcProxy &proxy_batch, share::ObLSID ls_id = lock->second; ObAddr addr; ObTableLockTaskRequest request; - ObTableLockTaskResult result; if (OB_FAIL(ls_array.push_back(ls_id))) { LOG_WARN("push_back lsid failed", K(ret), K(ls_id)); @@ -1460,7 +1904,7 @@ int ObTableLockService::parallel_rpc_handle_(RpcProxy &proxy_batch, ALLOW_NEXT_LOG(); LOG_INFO("send table lock rpc", KR(ret), K(rpc_count), K(addr), "request", request); } - ret = handle_parallel_rpc_response_(ret, rpc_count, proxy_batch, ctx, ls_array); + ret = handle_parallel_rpc_response_(ret, rpc_count, proxy_batch, ctx, ls_array, unused); } return ret; } @@ -1471,11 +1915,7 @@ int ObTableLockService::inner_process_obj_lock_batch_(ObTableLockCtx &ctx, const ObTableLockOwnerID lock_owner) { int ret = OB_SUCCESS; - if (ctx.task_type_ == UNLOCK_TABLE || - ctx.task_type_ == UNLOCK_PARTITION || - ctx.task_type_ == UNLOCK_SUBPARTITION || - ctx.task_type_ == UNLOCK_TABLET || - ctx.task_type_ == UNLOCK_OBJECT) { + if (ctx.is_unlock_task()) { ObHighPriorityBatchLockProxy proxy_batch(*GCTX.srv_rpc_proxy_, &obrpc::ObSrvRpcProxy::batch_unlock_obj); ret = batch_rpc_handle_(proxy_batch, ctx, lock_map, lock_mode, lock_owner); } else { @@ -1493,11 +1933,7 @@ int ObTableLockService::inner_process_obj_lock_old_version_(ObTableLockCtx &ctx, { int ret = OB_SUCCESS; // TODO: yanyuan.cxf we process the rpc one by one and do parallel later. - if (ctx.task_type_ == UNLOCK_TABLE || - ctx.task_type_ == UNLOCK_PARTITION || - ctx.task_type_ == UNLOCK_SUBPARTITION || - ctx.task_type_ == UNLOCK_TABLET || - ctx.task_type_ == UNLOCK_OBJECT) { + if (ctx.is_unlock_task()) { ObHighPriorityTableLockProxy proxy_batch(*GCTX.srv_rpc_proxy_, &obrpc::ObSrvRpcProxy::unlock_table); ret = parallel_rpc_handle_(proxy_batch, ctx, lock_map, lock_mode, lock_owner); } else { @@ -1658,7 +2094,7 @@ int ObTableLockService::process_table_tablet_lock_(ObTableLockCtx &ctx, } int ObTableLockService::check_op_allowed_(const uint64_t table_id, - const ObTableSchema *table_schema, + const ObSimpleTableSchemaV2 *table_schema, bool &is_allowed) { int ret = OB_SUCCESS; @@ -1666,10 +2102,12 @@ int ObTableLockService::check_op_allowed_(const uint64_t table_id, is_allowed = true; - if (is_inner_table(table_id)) { - is_allowed = false; - } else if (!table_schema->is_user_table() && !table_schema->is_mysql_tmp_table() && !table_schema->is_external_table()) { - // table lock not support virtual table/oracle tmp table /sys table etc. + if (!table_schema->is_user_table() + && !table_schema->is_tmp_table() + && !ObInnerTableLockUtil::in_inner_table_lock_white_list(table_id) + && !table_schema->is_external_table()) { + // all the tmp table is a normal table now, deal it as a normal user table + // table lock not support virtual table/sys table(not in white list) etc. is_allowed = false; } else if (GCTX.is_standby_cluster() && OB_SYS_TENANT_ID != tenant_id) { is_allowed = false; @@ -1689,15 +2127,29 @@ int ObTableLockService::check_op_allowed_(const uint64_t table_id, } int ObTableLockService::get_tablet_ls_( + const ObTableLockCtx &ctx, const ObTabletID &tablet_id, - ObLSID &ls_id) + ObLSID &ls_id, + bool force_refresh) { int ret = OB_SUCCESS; bool unused_cache_hit; const uint64_t tenant_id = MTL_ID(); - if (OB_FAIL(location_service_->nonblock_get(tenant_id, - tablet_id, - ls_id))) { + if (LOCK_ALONE_TABLET == ctx.task_type_ || UNLOCK_ALONE_TABLET == ctx.task_type_) { + // we have specified the ls, just do lock and unlock at the specified ls + ls_id = ctx.ls_id_; + } else if (force_refresh) { + if (OB_FAIL(location_service_->get(tenant_id, + tablet_id, + INT64_MAX, + unused_cache_hit, + ls_id))) { + LOG_WARN("failed to sync get ls by tablet failed.", + K(ret), K(tenant_id), K(tablet_id)); + } + } else if (OB_FAIL(location_service_->nonblock_get(tenant_id, + tablet_id, + ls_id))) { if (OB_MAPPING_BETWEEN_TABLET_AND_LS_NOT_EXIST == ret && OB_FAIL(location_service_->get(tenant_id, tablet_id, @@ -1717,70 +2169,107 @@ int ObTableLockService::get_tablet_ls_( } int ObTableLockService::get_process_tablets_(const ObTableLockMode lock_mode, - const ObTableSchema *table_schema, + const ObSimpleTableSchemaV2 *table_schema, ObTableLockCtx &ctx) { int ret = OB_SUCCESS; - ctx.tablet_list_.reuse(); - if ((ctx.task_type_ == LOCK_TABLET || ctx.task_type_ == UNLOCK_TABLET)) { + if (ctx.is_tablet_lock_task()) { // case 1: lock/unlock tablet // just push the specified tablet into the tablet list. - if (OB_FAIL(ctx.tablet_list_.push_back(ctx.tablet_id_))) { - LOG_WARN("failed to push back tablet id", K(ret)); - } - } else if (LOCK_PARTITION == ctx.task_type_ || UNLOCK_PARTITION == ctx.task_type_) { - // case 2: lock/unlock partition - // get all the tablet of this partition. - ObObjectID part_id(ctx.partition_id_); - if (OB_FAIL(table_schema->get_tablet_ids_by_part_object_id(part_id, - ctx.tablet_list_))) { - LOG_WARN("failed to get tablet ids", K(ret), K(part_id)); - } - } else if (LOCK_SUBPARTITION == ctx.task_type_ || UNLOCK_SUBPARTITION == ctx.task_type_) { - // case 3: lock/unlock subpartition - // get the tablet of subpartition - ObObjectID part_id(ctx.partition_id_); - ObTabletID tablet_id; - if (OB_FAIL(table_schema->get_tablet_id_by_object_id(part_id, - tablet_id))) { - LOG_WARN("failed to get tablet id", K(ret), K(part_id)); - } else if (OB_FAIL(ctx.tablet_list_.push_back(tablet_id))) { - LOG_WARN("failed to push back tablet id", K(ret)); - } - } else if ((LOCK_TABLE == ctx.task_type_ || UNLOCK_TABLE == ctx.task_type_) && - (SHARE == lock_mode || SHARE_ROW_EXCLUSIVE == lock_mode || EXCLUSIVE == lock_mode)) { - // case 4: lock/unlock table - // get all the tablet of this table. - if (OB_FAIL(table_schema->get_tablet_ids(ctx.tablet_list_))) { - LOG_WARN("failed to get tablet ids", K(ret)); - } + // if (OB_FAIL(ctx.tablet_list_.push_back(ctx.tablet_id_))) { + // LOG_WARN("failed to push back tablet id", K(ret)); + // } } else { - // do nothing + ctx.tablet_list_.reuse(); + if (LOCK_PARTITION == ctx.task_type_ || UNLOCK_PARTITION == ctx.task_type_) { + // case 2: lock/unlock partition + // get all the tablet of this partition. + ObObjectID part_id(ctx.partition_id_); + if (OB_FAIL(table_schema->get_tablet_ids_by_part_object_id(part_id, + ctx.tablet_list_))) { + LOG_WARN("failed to get tablet ids", K(ret), K(part_id)); + } + } else if (LOCK_SUBPARTITION == ctx.task_type_ || UNLOCK_SUBPARTITION == ctx.task_type_) { + // case 3: lock/unlock subpartition + // get the tablet of subpartition + ObObjectID part_id(ctx.partition_id_); + ObTabletID tablet_id; + if (OB_FAIL(table_schema->get_tablet_id_by_object_id(part_id, + tablet_id))) { + LOG_WARN("failed to get tablet id", K(ret), K(part_id)); + } else if (OB_FAIL(ctx.tablet_list_.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret)); + } + } else if ((LOCK_TABLE == ctx.task_type_ || UNLOCK_TABLE == ctx.task_type_) && + (SHARE == lock_mode || SHARE_ROW_EXCLUSIVE == lock_mode || EXCLUSIVE == lock_mode)) { + // case 4: lock/unlock table + // get all the tablet of this table. + if (OB_FAIL(table_schema->get_tablet_ids(ctx.tablet_list_))) { + LOG_WARN("failed to get tablet ids", K(ret)); + } + } else { + // do nothing + } } LOG_DEBUG("ObTableLockService::get_process_tablets_", K(ret), K(ctx.task_type_), K(ctx)); return ret; } -int ObTableLockService::get_ls_lock_map_(ObTableLockCtx &ctx, +int ObTableLockService::fill_ls_lock_map_(ObTableLockCtx &ctx, + const common::ObTabletIDArray &tablets, + ObLSLockMap &ls_lock_map, + bool force_refresh_location) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ls_lock_map.reuse())) { + LOG_WARN("fail to reuse ls_lock_map", KR(ret)); + } else { + for (int64_t i = 0; i < tablets.count() && OB_SUCC(ret); ++i) { + share::ObLSID ls_id; + ObLockIDArray lock_array; + ObLockIDArray *p = nullptr; + const ObTabletID &tablet_id = tablets.at(i); + ObLockID lock_id; + if (OB_FAIL(get_tablet_ls_(ctx, tablet_id, ls_id, force_refresh_location))) { + LOG_WARN("failed to get tablet ls", K(ret), K(tablet_id)); + } else if (OB_FAIL(get_lock_id(tablet_id, lock_id))) { + LOG_WARN("get lock id failed", K(ret), K(ctx)); + } else if (OB_FAIL(ls_lock_map.set_refactored(ls_id, lock_array)) && + OB_ENTRY_EXIST != ret && OB_HASH_EXIST != ret) { + LOG_WARN("fail to set ls_lock_map", K(ret), K(ls_id)); + } else if (OB_ISNULL(p = ls_lock_map.get(ls_id))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the ls not exist at ls lock map", K(ret), K(ls_id)); + } else if (OB_FAIL(p->push_back(lock_id))) { + LOG_WARN("push_back lock_id failed", K(ret), K(ls_id), K(lock_id)); + } + LOG_DEBUG("tablet add to lock map", K(lock_id), K(tablet_id), K(i)); + } + } + + return ret; +} + +int ObTableLockService::fill_ls_lock_map_(ObTableLockCtx &ctx, + const common::ObTabletIDArray &tablets, LockMap &lock_map, ObLSLockMap &ls_lock_map) { int ret = OB_SUCCESS; - if (OB_FAIL(lock_map.create(ctx.get_tablet_cnt() > 0 ? ctx.get_tablet_cnt() : 1, - lib::ObLabel("TableLockMap")))) { - LOG_WARN("fail to create lock_map", K(ret), K(ctx.get_tablet_cnt())); - } else if (OB_FAIL(ls_lock_map.create(10, lib::ObLabel("LSLockMap")))) { - LOG_WARN("ls_lock_map create failed"); + if (OB_FAIL(lock_map.reuse())) { + LOG_WARN("fail to reuse lock_map", KR(ret)); + } else if (OB_FAIL(ls_lock_map.reuse())) { + LOG_WARN("fail to reuse ls_lock_map", KR(ret)); } else { - for (int64_t i = 0; i < ctx.get_tablet_cnt() && OB_SUCC(ret); ++i) { + for (int64_t i = 0; i < tablets.count() && OB_SUCC(ret); ++i) { share::ObLSID ls_id; ObLockIDArray lock_array; ObLockIDArray *p = nullptr; - ObTabletID &tablet_id = ctx.tablet_list_.at(i); + const ObTabletID &tablet_id = tablets.at(i); ObLockID lock_id; - if (OB_FAIL(get_tablet_ls_(tablet_id, ls_id))) { + if (OB_FAIL(get_tablet_ls_(ctx, tablet_id, ls_id))) { LOG_WARN("failed to get tablet ls", K(ret), K(tablet_id)); } else if (OB_FAIL(get_lock_id(tablet_id, lock_id))) { @@ -1804,19 +2293,97 @@ int ObTableLockService::get_ls_lock_map_(ObTableLockCtx &ctx, return ret; } +int ObTableLockService::get_ls_lock_map_(ObTableLockCtx &ctx, + const common::ObTabletIDArray &tablets, + LockMap &lock_map, + ObLSLockMap &ls_lock_map) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(lock_map.create(tablets.count() > 0 ? tablets.count() : 1, + lib::ObLabel("TableLockMap")))) { + LOG_WARN("fail to create lock_map", K(ret), K(tablets.count())); + } else if (OB_FAIL(ls_lock_map.create(10, lib::ObLabel("LSLockMap")))) { + LOG_WARN("ls_lock_map create failed", KR(ret)); + } else if (OB_FAIL(fill_ls_lock_map_(ctx, tablets, lock_map, ls_lock_map))) { + LOG_WARN("fill ls lock map failed", KR(ret)); + } + + return ret; +} + +int ObTableLockService::check_cluster_version_after_(const uint64_t version) +{ + int ret = OB_SUCCESS; + uint64_t compat_version = GET_MIN_CLUSTER_VERSION(); + if (compat_version < version) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("cluster version check failed, not supported now", K(ret), K(compat_version), K(version)); + } + return ret; +} + +int ObTableLockService::check_data_version_after_(const uint64_t version) +{ + int ret = OB_SUCCESS; + uint64_t compat_version = 0; + if (OB_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), compat_version))) { + LOG_WARN("fail to get data version", K(ret)); + } else if (compat_version < version) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("data version check failed, not supported now", K(ret), K(compat_version), K(version)); + } + return ret; +} + +bool ObTableLockService::need_retry_trans_(const ObTableLockCtx &ctx, + const int64_t ret) const +{ + bool need_retry = false; + if (ctx.is_in_trans_) { + } else { + // only anonymous can retry + // retry condition 1 + need_retry = (ctx.tx_is_killed_ && + !ctx.is_try_lock() && + !ctx.is_timeout()); + // retry condition 2 + need_retry = need_retry || ((OB_NOT_MASTER == ret || + OB_LS_NOT_EXIST == ret || + OB_TABLET_NOT_EXIST == ret) && !ctx.is_timeout()); + } + return need_retry; +} + bool ObTableLockService::need_retry_single_task_(const ObTableLockCtx &ctx, const int64_t ret) const { bool need_retry = false; if (ctx.is_in_trans_) { need_retry = (OB_NOT_MASTER == ret || - OB_LS_NOT_EXIST == ret); + OB_LS_NOT_EXIST == ret || + OB_TABLET_NOT_EXIST == ret); } else { // TODO: yanyuan.cxf multi data source can not rollback, so we can not retry. } return need_retry; } +bool ObTableLockService::need_retry_rpc_task_(const int64_t ret, + const ObTableLockTaskResult *result) const +{ + bool need_retry = false; + need_retry = (OB_LS_NOT_EXIST == ret || + OB_TABLET_NOT_EXIST == ret); + need_retry = need_retry && result->can_retry(); + // retry if OB_LS_NOT_EXIST/OB_TABLET_NOT_EXIST and lock task result is can retry. + return need_retry; +} + +bool ObTableLockService::need_renew_location_(const int64_t ret) const +{ + return (OB_LS_LOCATION_NOT_EXIST == ret || OB_LS_LOCATION_LEADER_NOT_EXIST == ret); +} + int ObTableLockService::rewrite_return_code_(const int ret) const { int rewrite_rcode = ret; @@ -1827,6 +2394,11 @@ int ObTableLockService::rewrite_return_code_(const int ret) const return rewrite_rcode; } +int ObTableLockService::is_timeout_ret_code_(const int ret) const +{ + return (OB_TIMEOUT == ret || OB_GET_LOCATION_TIME_OUT == ret); +} + int ObTableLockService::get_ls_leader_( const int64_t cluster_id, const uint64_t tenant_id, @@ -1835,20 +2407,23 @@ int ObTableLockService::get_ls_leader_( ObAddr &addr) { int ret = OB_SUCCESS; - if (OB_ISNULL(location_service_)) { + // priority to set timeout_ctx: ctx > worker > default_timeout + ObTimeoutCtx ctx; + if (OB_FAIL(ctx.set_abs_timeout(abs_timeout_ts))) { + LOG_WARN("set abs timeout ts failed", KR(ret)); + } else if (OB_ISNULL(location_service_)) { ret = OB_NOT_INIT; LOG_WARN("table lock service not inited", K(ret)); - } else if (OB_FAIL(location_service_->get_leader_with_retry_until_timeout( - cluster_id, - tenant_id, - ls_id, - addr, - abs_timeout_ts))) { + } else if (OB_FAIL(location_service_->get_leader(cluster_id, + tenant_id, + ls_id, + true, /* force renew */ + addr))) { LOG_WARN("failed to get ls leader with retry until timeout", - K(ret), K(cluster_id), K(tenant_id), K(ls_id), K(addr), K(abs_timeout_ts)); + K(ret), K(cluster_id), K(tenant_id), K(ls_id), K(addr)); } else { LOG_DEBUG("get ls leader from location_service", - K(ret), K(cluster_id), K(tenant_id), K(ls_id), K(addr), K(abs_timeout_ts)); + K(ret), K(cluster_id), K(tenant_id), K(ls_id), K(addr)); } LOG_DEBUG("ObTableLockService::process_obj_lock_", K(ret), K(tenant_id), K(ls_id), K(addr)); diff --git a/src/storage/tablelock/ob_table_lock_service.h b/src/storage/tablelock/ob_table_lock_service.h old mode 100644 new mode 100755 index 7171152c1..b171f5734 --- a/src/storage/tablelock/ob_table_lock_service.h +++ b/src/storage/tablelock/ob_table_lock_service.h @@ -72,7 +72,7 @@ private: const int64_t timeout_us); ObTableLockCtx(const ObTableLockTaskType task_type, const uint64_t table_id, - const common::ObTabletID &tablet_id, + const share::ObLSID &ls_id, const int64_t origin_timeout_us, const int64_t timeout_us); ObTableLockCtx(const ObTableLockTaskType task_type, @@ -81,6 +81,8 @@ private: const int64_t origin_timeout_us, const int64_t timeout_us); ~ObTableLockCtx() {} + int set_tablet_id(const common::ObIArray &tablet_ids); + int set_tablet_id(const common::ObTabletID &tablet_id); bool is_try_lock() const { return 0 == timeout_us_; } bool is_deadlock_avoid_enabled() const; bool is_timeout() const; @@ -96,6 +98,22 @@ private: bool is_stmt_savepoint_valid() { return -1 != stmt_savepoint_; } void reset_stmt_savepoint() { stmt_savepoint_ = -1; } ObTableLockOpType get_lock_op_type() const { return lock_op_type_; } + bool is_unlock_task() const + { + return (UNLOCK_TABLE == task_type_ || + UNLOCK_PARTITION == task_type_ || + UNLOCK_SUBPARTITION == task_type_ || + UNLOCK_TABLET == task_type_ || + UNLOCK_OBJECT == task_type_ || + UNLOCK_ALONE_TABLET == task_type_); + } + bool is_tablet_lock_task() const + { + return (LOCK_TABLET == task_type_ || + UNLOCK_TABLET == task_type_ || + LOCK_ALONE_TABLET == task_type_ || + UNLOCK_ALONE_TABLET == task_type_); + } public: ObTableLockTaskType task_type_; // current lock request type bool is_in_trans_; @@ -103,8 +121,8 @@ private: // used for table/partition/tablet struct { uint64_t table_id_; - uint64_t partition_id_; // set when lock or unlock specified partition - common::ObTabletID tablet_id_; // set when lock or unlock specified tablet + uint64_t partition_id_; // set when lock or unlock specified partition + share::ObLSID ls_id_; // used for alone tablet lock and unlock }; // used for lock object struct { @@ -135,7 +153,7 @@ private: int64_t stmt_savepoint_; TO_STRING_KV(K(is_in_trans_), K(table_id_), K(partition_id_), - K(tablet_id_), K(obj_type_), K(obj_id_), K(lock_op_type_), + K(tablet_list_), K(obj_type_), K(obj_id_), K(lock_op_type_), K(origin_timeout_us_), K(timeout_us_), K(abs_timeout_ts_), KPC(tx_desc_), K(tx_param_), K(current_savepoint_), K(need_rollback_ls_), @@ -257,6 +275,14 @@ public: int unlock_tablet(ObTxDesc &tx_desc, const ObTxParam &tx_param, const ObUnLockTabletRequest &arg); + int lock_tablet(ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObLockAloneTabletRequest &arg); + // arg.op_type_ should be OUT_TRANS_UNLOCK: + // unlock the table level lock and the tablet level lock. + int unlock_tablet(ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObUnLockAloneTabletRequest &arg); int lock_partition_or_subpartition(ObTxDesc &tx_desc, const ObTxParam &tx_param, const ObLockPartitionRequest &arg); @@ -281,9 +307,17 @@ public: int garbage_collect_right_now(); int get_obj_lock_garbage_collector(ObOBJLockGarbageCollector *&obj_lock_garbage_collector); private: + int check_cluster_version_after_(const uint64_t version); + int check_data_version_after_(const uint64_t version); + bool need_retry_trans_(const ObTableLockCtx &ctx, + const int64_t ret) const; bool need_retry_single_task_(const ObTableLockCtx &ctx, const int64_t ret) const; + bool need_retry_rpc_task_(const int64_t ret, + const ObTableLockTaskResult *result) const; + bool need_renew_location_(const int64_t ret) const; int rewrite_return_code_(const int ret) const; + int is_timeout_ret_code_(const int ret) const; int process_lock_task_(ObTableLockCtx &ctx, const ObTableLockMode lock_mode, const ObTableLockOwnerID lock_owner); @@ -293,6 +327,10 @@ private: int process_table_lock_task_(ObTableLockCtx &ctx, const ObTableLockMode lock_mode, const ObTableLockOwnerID lock_owner); + int process_tablet_lock_task_(ObTableLockCtx &ctx, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + const ObSimpleTableSchemaV2 *table_schema); int start_tx_(ObTableLockCtx &ctx); int end_tx_(ObTableLockCtx &ctx, const bool is_rollback); int start_sub_tx_(ObTableLockCtx &ctx); @@ -300,16 +338,27 @@ private: int start_stmt_(ObTableLockCtx &ctx); int end_stmt_(ObTableLockCtx &ctx, const bool is_rollback); int check_op_allowed_(const uint64_t table_id, - const ObTableSchema *table_schema, + const ObSimpleTableSchemaV2 *table_schema, bool &is_allowed); int get_process_tablets_(const ObTableLockMode lock_mode, - const ObTableSchema *table_schema, + const ObSimpleTableSchemaV2 *table_schema, ObTableLockCtx &ctx); int get_ls_lock_map_(ObTableLockCtx &ctx, + const common::ObTabletIDArray &tablets, LockMap &lock_map, ObLSLockMap &ls_lock_map); - int get_tablet_ls_(const ObTabletID &tablet_id, - share::ObLSID &ls_id); + int fill_ls_lock_map_(ObTableLockCtx &ctx, + const common::ObTabletIDArray &tablets, + ObLSLockMap &ls_lock_map, + bool force_refresh_location); + int fill_ls_lock_map_(ObTableLockCtx &ctx, + const common::ObTabletIDArray &tablets, + LockMap &lock_map, + ObLSLockMap &ls_lock_map); + int get_tablet_ls_(const ObTableLockCtx &ctx, + const ObTabletID &tablet_id, + share::ObLSID &ls_id, + bool force_refresh = false); int get_ls_leader_(const int64_t cluster_id, const uint64_t tenant_id, const share::ObLSID &ls_id, @@ -343,11 +392,43 @@ private: const ObTableLockMode lock_mode, const ObTableLockOwnerID lock_owner); template + int batch_rpc_handle_(RpcProxy &proxy_batch, + ObTableLockCtx &ctx, + const ObLSLockMap &ls_lock_map, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + bool &can_retry, + ObLSLockMap &retry_ls_lock_map); + template int handle_parallel_rpc_response_(int rpc_call_ret, int64_t rpc_count, RpcProxy &proxy_batch, ObTableLockCtx &ctx, - ObArray &ls_array); + ObArray &ls_array, + bool &can_retry); + template + int parallel_batch_rpc_handle_(RpcProxy &proxy_batch, + ObTableLockCtx &ctx, + const ObTableLockTaskType lock_task_type, + const ObLSLockMap &ls_lock_map, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner); + template + int parallel_batch_rpc_handle_(RpcProxy &proxy_batch, + ObTableLockCtx &ctx, + const ObTableLockTaskType lock_task_type, + const ObLSLockMap &ls_lock_map, + const ObTableLockMode lock_mode, + const ObTableLockOwnerID lock_owner, + bool &can_retry, + ObLSLockMap &retry_ls_lock_map); + int get_retry_tablet_list_(const ObLockIDArray &lock_ids, + common::ObTabletIDArray &retry_tablets); + template + int get_retry_tablet_list_(const ObLSLockMap &ls_lock_map, + const RpcProxy &proxy_batch, + const ObArray &ls_array, + common::ObTabletIDArray &retry_tablets); int inner_process_obj_lock_(ObTableLockCtx &ctx, const LockMap &lock_map, const ObLSLockMap &ls_lock_map, @@ -397,7 +478,7 @@ private: DISALLOW_COPY_AND_ASSIGN(ObTableLockService); private: // TODO: yanyuan.cxf use parallel rpc and modify this to 5s. - static const int64_t DEFAULT_TIMEOUT_US = 15L * 1000L * 1000L; // 15s + static const int64_t DEFAULT_TIMEOUT_US = 1500L * 1000L * 1000L; // 1500s static const int64_t DEFAULT_RPC_TIMEOUT_US = 2L * 1000L * 1000L; // 2s share::ObLocationService *location_service_; diff --git a/src/storage/tablet/ob_full_tablet_creator.cpp b/src/storage/tablet/ob_full_tablet_creator.cpp new file mode 100644 index 000000000..33591548f --- /dev/null +++ b/src/storage/tablet/ob_full_tablet_creator.cpp @@ -0,0 +1,385 @@ +/** + * 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 "storage/tablet/ob_full_tablet_creator.h" +#include "storage/tablet/ob_tablet_persister.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" + +#define USING_LOG_PREFIX STORAGE + +namespace oceanbase +{ +namespace storage +{ +ObFullTabletCreator::ObFullTabletCreator() + : is_inited_(false), + mstx_allocator_(), + tiny_allocator_(), + transform_head_(), + transform_tail_(), + wait_create_tablets_cnt_(0), + created_tablets_cnt_(0), + persist_queue_cnt_(0), + persist_tablets_cnt_(0), + gc_tablets_cnt_(0), + mutex_() +{ +} + +int ObFullTabletCreator::init(const uint64_t tenant_id) +{ + /* We use two fifo allocators to minimize the memory hole caused by tablets of different lifetime. + 1. MSTXAllocator is used to alloc tablets. To ensure that each tablet can occupy one whole page, we set the page_size = 8K. + 2. TinyAllocator is used to alloc ObArenaAllocator. We set the page_size = 4K to minimize the memory hole. */ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("ObTenantMetaMemMgr has been initialized", K(ret)); + } else if (OB_FAIL(mstx_allocator_.init(lib::ObMallocAllocator::get_instance(), + OB_MALLOC_NORMAL_BLOCK_SIZE, ObMemAttr(tenant_id, "MSTXAllocator", ObCtxIds::DEFAULT_CTX_ID)))) { + LOG_WARN("fail to init tenant mstx allocator", K(ret)); + } else if (OB_FAIL(tiny_allocator_.init(lib::ObMallocAllocator::get_instance(), + OB_MALLOC_NORMAL_BLOCK_SIZE/2, ObMemAttr(tenant_id, "TinyAllocator", ObCtxIds::DEFAULT_CTX_ID)))) { + LOG_WARN("fail to init tenant tiny allocator", K(ret)); + } else { + is_inited_ = true; + } + if (OB_UNLIKELY(!is_inited_)) { + reset(); + } + return ret; +} + +void ObFullTabletCreator::reset() +{ + transform_head_.reset(); + transform_tail_.reset(); + persist_queue_cnt_ = 0; + wait_create_tablets_cnt_ = 0; + persist_tablets_cnt_ = 0; + gc_tablets_cnt_ = 0; + created_tablets_cnt_ = 0; + mstx_allocator_.reset(); + tiny_allocator_.reset(); + is_inited_ = false; +} + +void ObFullTabletCreator::free_tablet(ObTablet *tablet) +{ + if (OB_NOT_NULL(tablet)) { + ObIAllocator *allocator = tablet->get_allocator(); + tablet->~ObTablet(); + allocator->~ObIAllocator(); + tiny_allocator_.free(allocator); + ATOMIC_INC(&gc_tablets_cnt_); + } + return; +} + +int ObFullTabletCreator::throttle_tablet_creation() +{ + int ret = OB_SUCCESS; + + bool need_wait = false; + const int64_t limit_size = get_tenant_memory_limit(MTL_ID()) / 10; // 10% + const int64_t timeout = 5 * 1000L; // 5ms for effective replay + const int64_t log_timeout = 1 * 1000 * 1000L; // 1s + const int64_t start_time = ObTimeUtility::fast_current_time(); + + ATOMIC_INC(&wait_create_tablets_cnt_); + do { + if (need_wait) { + ob_usleep(10); // sleep 10us, do not get mutex here + } + lib::ObMutexGuard guard(mutex_); + if (mstx_allocator_.total() + tiny_allocator_.total() < limit_size) { + need_wait = false; + ATOMIC_DEC(&wait_create_tablets_cnt_); + } else if (ObTimeUtility::fast_current_time() - start_time >= timeout) { + ret = OB_EAGAIN; + LOG_WARN("throttle tablet creation timeout", K(ret)); + break; + } else { + need_wait = true; + if (REACH_TENANT_TIME_INTERVAL(log_timeout)) { + const int64_t hanging_tablets_cnt = ATOMIC_LOAD(&created_tablets_cnt_) - ATOMIC_LOAD(&gc_tablets_cnt_); + const int64_t wait_create_tablets_cnt = ATOMIC_LOAD(&wait_create_tablets_cnt_); + LOG_WARN("prepare create tablet timeout", + K_(persist_queue_cnt), K(wait_create_tablets_cnt), K(hanging_tablets_cnt), K(limit_size), + K(mstx_allocator_.total()), K(mstx_allocator_.used()), + K(tiny_allocator_.total()), K(tiny_allocator_.used())); + } + } + } while (need_wait); + return ret; +} + +int ObFullTabletCreator::create_tablet(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + ObArenaAllocator *allocator = nullptr; + ObMetaDiskAddr mem_addr; + const int64_t page_size = OB_MALLOC_NORMAL_BLOCK_SIZE - FIFO_START_OFFSET; + + if (OB_ISNULL(allocator = OB_NEWx(ObArenaAllocator, (&tiny_allocator_), mstx_allocator_, page_size))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new arena allocator", K(ret)); + /* TODO(zhuixin.gsy) rm these set_xx after merge master*/ + } else if (FALSE_IT(allocator->set_label("MSTXAllocator"))) { + } else if (FALSE_IT(allocator->set_tenant_id(MTL_ID()))) { + } else if (FALSE_IT(allocator->set_ctx_id(ObCtxIds::DEFAULT_CTX_ID))) { + } else if (OB_ISNULL(tablet = OB_NEWx(ObTablet, allocator))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new tablet", K(ret)); + } else if (OB_FAIL(mem_addr.set_mem_addr(0, sizeof(ObTablet)))) { + LOG_WARN("fail to set memory address", K(ret)); + } else { + tablet->set_allocator(allocator); + tablet->set_tablet_addr(mem_addr); + ATOMIC_INC(&created_tablets_cnt_); + } + if (OB_SUCC(ret)) { + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr *); + tablet_handle.set_obj(tablet, allocator, t3m); + tablet_handle.set_wash_priority(WashTabletPriority::WTP_LOW); + } else { + if (OB_NOT_NULL(tablet)) { + tablet->~ObTablet(); + tablet = nullptr; + } + if (OB_NOT_NULL(allocator)) { + allocator->~ObArenaAllocator(); + tiny_allocator_.free(allocator); + allocator = nullptr; + } + } + return ret; +} + +int ObFullTabletCreator::persist_tablet() +{ + int ret = OB_SUCCESS; + int64_t persist_tablets_cnt = 0; + int64_t error_tablets_cnt = 0; + ObTabletHandle old_handle; + const int64_t per_round_time = ObTenantMetaMemMgr::TABLET_TRANSFORM_INTERVAL_US; + const int64_t start_time = ObTimeUtility::fast_current_time(); + while (OB_SUCC(ret) && ObTimeUtility::fast_current_time() - start_time < per_round_time && OB_SUCC(pop_tablet(old_handle))) { + const ObTablet *old_tablet = old_handle.get_obj(); + const ObMetaDiskAddr old_addr = old_tablet->get_tablet_addr(); + const ObTabletMeta &tablet_meta = old_tablet->get_tablet_meta(); + ObTabletMapKey key(tablet_meta.ls_id_, tablet_meta.tablet_id_); + ObMetaDiskAddr addr; + ObTabletHandle new_handle; + ObLSHandle ls_handle; + ObLSTabletService *ls_tablet_svr = nullptr; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTabletCreateDeleteMdsUserData mds_data; + ObTimeGuard single_guard("try persist tablet", 5 * 1000); // 5ms + if (OB_UNLIKELY(!old_tablet->is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected old tablet", K(ret), K(key), K(old_handle), KPC(old_tablet)); + } else if (FALSE_IT(single_guard.click("start persist"))) { + } else if (OB_FAIL(t3m->get_tablet_addr(key, addr))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; // deleted, skip + } else { + LOG_ERROR("fail to get meta addr", K(ret), K(key), K(old_handle), K(old_tablet->is_empty_shell())); + } + } else if (!addr.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected not memory tablet addr", K(ret), K(key), K(addr), K(old_handle), K(old_tablet->is_empty_shell())); + } else if (addr != old_addr) { + if (addr.is_block()) { + LOG_INFO("full tablet has been persisted, skip this", K(ret), K(key), K(old_addr), K(addr)); + } else { + ret = OB_NOT_THE_OBJECT; // create_memtable may change the addr, push back to queue + LOG_INFO("memory addr changed, push back to queue", K(ret), K(key), K(old_addr), K(addr)); + } + } else if (OB_FAIL(old_tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), mds_data, 0))) { + if (OB_EMPTY_RESULT != ret && OB_ERR_SHARED_LOCK_CONFLICT != ret) { + LOG_ERROR("fail to get tablet status", K(ret), K(key), K(addr), K(old_handle), K(old_tablet->is_empty_shell())); + } + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*old_tablet, new_handle))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; // deleted, skip + } else { + LOG_WARN("fail to persist old tablet", K(ret), K(key), K(old_handle), K(old_tablet->is_empty_shell())); + } + } else if (FALSE_IT(single_guard.click("end persist"))) { + } else if (OB_FAIL(MTL(ObLSService*)->get_ls(tablet_meta.ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_ERROR("fail to get ls", K(ret), K(tablet_meta.ls_id_)); + } else if (OB_ISNULL(ls_tablet_svr = ls_handle.get_ls()->get_tablet_svr())) { + ret = OB_ERR_NULL_VALUE; + LOG_ERROR("null ls tablet svr", K(ret), K(ls_handle)); + } else if (OB_FAIL(ls_tablet_svr->update_tablet_mstx(key, old_addr, old_handle, new_handle))) { + LOG_WARN("fail to update tablet mstx", K(ret), K(key), K(old_addr), K(old_handle), K(new_handle), K(old_tablet->is_empty_shell())); + } else { + single_guard.click("end update mstx"); + } + + if (OB_FAIL(ret)) { + ++error_tablets_cnt; + if (OB_FAIL(push_tablet_to_queue(old_handle))) { + LOG_ERROR("fail to push tablet, wrong tablet may be leaked", K(ret), K(key), K(old_handle), K(old_tablet->is_empty_shell())); + } + ret = OB_SUCCESS; // continue to persist other tablet + } else { + ++persist_tablets_cnt; + LOG_DEBUG("succeed to persist one tablet", KP(old_tablet), K(single_guard)); + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + // persist_tablets_cnt: the cnt of tablets that have been persisted in this round + // error_tablets_cnt: the cnt of tablets that couldn't be persisted in this round + // tablets_cnt: the cnt of tablets left in queue (including error_tablets_cnt) + if (persist_tablets_cnt + error_tablets_cnt > 0) { + lib::ObMutexGuard guard(mutex_); + persist_tablets_cnt_ += persist_tablets_cnt; + const int64_t hanging_tablets_cnt = ATOMIC_LOAD(&created_tablets_cnt_) - ATOMIC_LOAD(&gc_tablets_cnt_); + const int64_t wait_create_tablets_cnt = ATOMIC_LOAD(&wait_create_tablets_cnt_); + FLOG_INFO("Finish persist task one round", K(persist_tablets_cnt), K(error_tablets_cnt), K_(persist_queue_cnt), + K(wait_create_tablets_cnt), K(hanging_tablets_cnt), + K(mstx_allocator_.total()), K(mstx_allocator_.used()), + K(tiny_allocator_.total()), K(tiny_allocator_.used())); + } + return ret; +} + +int ObFullTabletCreator::pop_tablet(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + tablet_handle.reset(); + lib::ObMutexGuard guard(mutex_); + if (OB_UNLIKELY(0 > persist_queue_cnt_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected <0 tablets cnt", K(ret), K_(persist_queue_cnt)); + } else if (0 == persist_queue_cnt_) { + ret = OB_ITER_END; + } else if (OB_UNLIKELY(!transform_head_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid tablet handle to pop", K(ret), K_(persist_queue_cnt), K_(transform_head)); + } else { + tablet_handle = transform_head_; + transform_head_ = transform_head_.get_obj()->get_next_full_tablet(); + ObTabletHandle empty_handle; + tablet_handle.get_obj()->set_next_full_tablet(empty_handle); + --persist_queue_cnt_; + if (!persist_queue_cnt_) { + transform_tail_.reset(); + } + } + return ret; +} + +int ObFullTabletCreator::push_tablet_to_queue(const ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(mutex_); + bool hdl_valid, tablet_valid, addr_valid; + hdl_valid = tablet_valid = addr_valid = true; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("full tablet creator not inited", K(ret)); + } else if (OB_UNLIKELY(!(hdl_valid = tablet_handle.is_valid()) + || !(tablet_valid = tablet_handle.get_obj()->is_valid()) + || !(addr_valid = tablet_handle.get_obj()->get_tablet_addr().is_valid()) + || tablet_handle.get_obj()->get_tablet_addr().is_block())) { + // TODO (@chenqingxiang.cqx) use !is_memory() to skip tablet if empty shell is allocated from pool + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tablet handle or not memory tablet addr", K(ret), K(hdl_valid), K(tablet_valid), K(addr_valid), + K(tablet_handle), KPC(tablet_handle.get_obj())); + } else if (0 == persist_queue_cnt_) { + tablet_handle.get_obj()->set_next_full_tablet(transform_head_); + transform_head_ = transform_tail_ = tablet_handle; + ++persist_queue_cnt_; + } else { + transform_tail_.get_obj()->set_next_full_tablet(tablet_handle); + transform_tail_ = tablet_handle; + ++persist_queue_cnt_; + } + return ret; +} + +int ObFullTabletCreator::remove_tablet_from_queue(const ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(mutex_); + bool hdl_valid, tablet_valid, addr_valid; + hdl_valid = tablet_valid = addr_valid = true; + ObMetaDiskAddr tablet_addr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("full tablet creator not inited", K(ret)); + } else if (OB_UNLIKELY(!(hdl_valid = tablet_handle.is_valid()) + || !(tablet_valid = tablet_handle.get_obj()->is_valid()) + || !(addr_valid = (tablet_addr = tablet_handle.get_obj()->get_tablet_addr()).is_valid()))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fail to remove invalid tablet", K(ret), K(hdl_valid), K(tablet_valid), K(addr_valid), + K(tablet_handle), K(tablet_addr), KPC(tablet_handle.get_obj())); + } else if (tablet_addr.is_block() + || tablet_addr.is_none() + || 0 == persist_queue_cnt_) { + // skip persisted or none-addr tablet + // TODO (@chenqingxiang.cqx) use !is_memory() to skip tablet if empty shell is allocated from pool + } else { + ObTabletHandle curr_handle = transform_head_; + if (OB_UNLIKELY(!curr_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tranform head", K(ret), K_(transform_head)); + } else if (curr_handle.get_obj() == tablet_handle.get_obj()) { + transform_head_ = transform_head_.get_obj()->get_next_full_tablet(); + --persist_queue_cnt_; + if (!persist_queue_cnt_) { + transform_tail_.reset(); + } + } else { + ObTabletHandle prev_handle = curr_handle; + while (curr_handle.is_valid()) { + if (curr_handle.get_obj() == tablet_handle.get_obj()) { + prev_handle.get_obj()->set_next_full_tablet(curr_handle.get_obj()->get_next_full_tablet()); + if (curr_handle.get_obj() == transform_tail_.get_obj()) { + transform_tail_ = prev_handle; + } + --persist_queue_cnt_; + break; + } + prev_handle = curr_handle; + curr_handle = curr_handle.get_obj()->get_next_full_tablet(); + } + } + } + return ret; +} + +void ObFullTabletCreator::destroy_queue() +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(mutex_); + while (transform_head_.is_valid()) { + transform_head_ = transform_head_.get_obj()->get_next_full_tablet(); + --persist_queue_cnt_; + } + transform_tail_.reset(); + if (OB_UNLIKELY(0 != persist_queue_cnt_)) { + LOG_ERROR("unexpected tablets cnt", K_(persist_queue_cnt)); + } +} + +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_full_tablet_creator.h b/src/storage/tablet/ob_full_tablet_creator.h new file mode 100644 index 000000000..3f100bd17 --- /dev/null +++ b/src/storage/tablet/ob_full_tablet_creator.h @@ -0,0 +1,70 @@ +/** + * 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_STORAGE_OB_FULL_TABLET_CREATOR +#define OCEANBASE_STORAGE_OB_FULL_TABLET_CREATOR + +#include "lib/allocator/ob_fifo_allocator.h" +#include "lib/allocator/page_arena.h" +#include "lib/list/ob_dlist.h" +#include "storage/meta_mem/ob_tablet_handle.h" + +namespace oceanbase +{ +namespace common +{ +class ObIAllocator; +} + +namespace storage +{ + +class ObFullTabletCreator final +{ + static const int64_t ONE_ROUND_PERSIST_COUNT_THRESHOLD = 200L; + static const int64_t FIFO_START_OFFSET = + sizeof(ObFIFOAllocator::NormalPageHeader) + sizeof(ObFIFOAllocator::AllocHeader) + 16 - 1; +public: + ObFullTabletCreator(); + ~ObFullTabletCreator() = default; +public: + int init(const uint64_t tenant_id); + void reset(); + int create_tablet(ObTabletHandle &tablet_handle); + int persist_tablet(); + void destroy_queue(); // used to release tablets when t3m::destroy + common::ObIAllocator &get_allocator() { return mstx_allocator_; } + /* ATTENTION: below functions should be called without any ls_tablet or t3m locks */ + int throttle_tablet_creation(); + int push_tablet_to_queue(const ObTabletHandle &tablet_handle); + int remove_tablet_from_queue(const ObTabletHandle &tablet_handle); + void free_tablet(ObTablet *tablet); +private: + int pop_tablet(ObTabletHandle &tablet_handle); +private: + bool is_inited_; + common::ObFIFOAllocator mstx_allocator_; + common::ObFIFOAllocator tiny_allocator_; + ObTabletHandle transform_head_; // for transform thread + ObTabletHandle transform_tail_; // for transform thread + int64_t wait_create_tablets_cnt_; // tablets waiting to be created + int64_t created_tablets_cnt_; // tablets has been created + int64_t persist_queue_cnt_; // tablets in persist queue + int64_t persist_tablets_cnt_; // tablets has been persisted + int64_t gc_tablets_cnt_; // tablets has been gc + lib::ObMutex mutex_; + DISALLOW_COPY_AND_ASSIGN(ObFullTabletCreator); +}; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_FULL_TABLET_CREATOR diff --git a/src/storage/tablet/ob_i_tablet_mds_interface.h b/src/storage/tablet/ob_i_tablet_mds_interface.h new file mode 100644 index 000000000..8fe774353 --- /dev/null +++ b/src/storage/tablet/ob_i_tablet_mds_interface.h @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2021 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_STORAGE_TABLET_OB_TABLET_MDS_PART +#define OCEANBASE_STORAGE_TABLET_OB_TABLET_MDS_PART + +#include "lib/ob_errno.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/meta_mem/ob_tablet_pointer.h" +#include "storage/tablet/ob_tablet_mds_data.h" +#include "storage/tablet/ob_tablet_member_wrapper.h" +#include "storage/tablet/ob_tablet_meta.h" + +namespace oceanbase +{ +namespace storage +{ +class ObTabletCreateDeleteHelper; + +class ObITabletMdsInterface +{ + friend class ObTabletCreateDeleteHelper; +public: + // new mds + // Currently, we only support read LATEST multi source data, so please pass MAX_SCN as snapshot. + // Other value will cause OB_NOT_SUPPOTED error. + // Snapshot read operation will be implemented after multi source data dumped into macro blocks. + template // general set for dummy key unit + int set(T &&data, mds::MdsCtx &ctx, const int64_t lock_timeout_us = 0); + template // general set for multi key unit + int set(const Key &key, Value &&data, mds::MdsCtx &ctx, const int64_t lock_timeout_us = 0); + template // general remove for multi key unit + int remove(const Key &key, mds::MdsCtx &ctx, const int64_t lock_timeout_us = 0); + // sometimes mds ndoes needed be forcely released, e.g.: ls offline + template + int forcely_release_all_mds_nodes(const char (&reason)[N]);// reason must be cimpile-time str + template + int is_locked_by_others(bool &is_locked, const mds::MdsWriter &self = mds::MdsWriter()) const; + + int check_mds_written(bool &written); + // specialization get for each module + int get_latest_tablet_status(ObTabletCreateDeleteMdsUserData &data, bool &is_committed) const; + int get_tablet_status(const share::SCN &snapshot, + ObTabletCreateDeleteMdsUserData &data, + const int64_t timeout = 0) const; + int get_ddl_data(const share::SCN &snapshot, + ObTabletBindingMdsUserData &data, + const int64_t timeout = 0) const; + int get_autoinc_seq(ObIAllocator &allocator, + const share::SCN &snapshot, + share::ObTabletAutoincSeq &data, + const int64_t timeout = 0) const; + int fill_virtual_info(ObIArray &mds_node_info_array) const; + TO_STRING_KV(KP(this), "is_inited", check_is_inited_(), "ls_id", get_tablet_meta_().ls_id_, + "tablet_id", get_table_id_(), KP(get_tablet_ponter_())); + int get_mds_table_rec_log_scn(share::SCN &rec_scn); + int mds_table_flush(const share::SCN &recycle_scn); +protected:// implemented by ObTablet + virtual bool check_is_inited_() const = 0; + virtual const ObTabletMdsData &get_mds_data_() const = 0; + virtual const ObTabletMeta &get_tablet_meta_() const = 0; + virtual int get_mds_table_handle_(mds::MdsTableHandle &handle, + const bool create_if_not_exist) const = 0; + virtual ObTabletPointer *get_tablet_ponter_() const = 0; + virtual int fetch_autoinc_seq(ObTabletMemberWrapper &wrapper) const = 0; + template + int get_mds_data_from_tablet(const common::ObFunction &read_op) const; + + template + int replay(T &&mds, + mds::MdsCtx &ctx, + const share::SCN &scn); +private: + template + int replay(const Key &key, + Value &&mds, + mds::MdsCtx &ctx, + const share::SCN &scn); + template + int replay_remove(const Key &key, + mds::MdsCtx &ctx, + const share::SCN &scn);// called only by ObTabletReplayExecutor + template + int get_latest(OP &&read_op, bool &is_committed, const int64_t read_seq) const; + template + int get_snapshot(OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const;// general get for dummy key unit + template + int get_snapshot(const Key &key, + OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const;// general get for multi key unit + common::ObTabletID get_table_id_() const; + template + int obj_to_string_holder_(const T &obj, ObStringHolder &holder) const; + template + int fill_virtual_info_by_obj_(const T &obj, const mds::NodePosition position, ObIArray &mds_node_info_array) const; + template + int fill_virtual_info_by_complex_addr_(const ObTabletComplexAddr &addr, + ObIArray &mds_node_info_array) const; +}; +} +} + +#ifndef INCLUDE_OB_TABLET_MDS_PART_IPP +#define INCLUDE_OB_TABLET_MDS_PART_IPP +#include "ob_i_tablet_mds_interface.ipp" +#endif + +#endif diff --git a/src/storage/tablet/ob_i_tablet_mds_interface.ipp b/src/storage/tablet/ob_i_tablet_mds_interface.ipp new file mode 100644 index 000000000..06d5b4ce1 --- /dev/null +++ b/src/storage/tablet/ob_i_tablet_mds_interface.ipp @@ -0,0 +1,709 @@ +#ifndef INCLUDE_OB_TABLET_MDS_PART_IPP +#define INCLUDE_OB_TABLET_MDS_PART_IPP +#include "lib/ob_errno.h" +#include "ob_i_tablet_mds_interface.h" +#include "storage/multi_data_source/compile_utility/compile_mapper.h" +#include "storage/multi_data_source/mds_node.h" +#include "storage/multi_data_source/mds_unit.h" +#endif +namespace oceanbase +{ +namespace storage +{ + +/********************************IMPLEMENTATION WITHOUT TEMPLATE***********************************/ + +inline common::ObTabletID ObITabletMdsInterface::get_table_id_() const +{ + return get_tablet_meta_().tablet_id_; +} + +inline int ObITabletMdsInterface::get_tablet_status(const share::SCN &snapshot, + ObTabletCreateDeleteMdsUserData &data, + const int64_t timeout) const +{ + #define PRINT_WRAPPER KR(ret), K(snapshot), K(data), K(timeout), K(*this) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!check_is_inited_())) { + ret = OB_NOT_INIT; + MDS_LOG_GET(WARN, "not inited"); + } else if (OB_UNLIKELY(!snapshot.is_max())) { + ret = OB_NOT_SUPPORTED; + MDS_LOG_GET(WARN, "only support read latest data currently"); + } else if (CLICK_FAIL(get_snapshot( + [&data](const ObTabletCreateDeleteMdsUserData &user_data) -> int { + return data.assign(user_data); + }, snapshot, 0, timeout))) { + MDS_LOG_GET(WARN, "tablet_status does not exist on neither mds_table nor tablet", K(lbt())); + } else if (!data.is_valid()) { + MDS_LOG_GET(WARN, "get invalid ObTabletCreateDeleteMdsUserData", K(lbt())); + } + return ret; + #undef PRINT_WRAPPER +} + +inline int ObITabletMdsInterface::get_latest_tablet_status(ObTabletCreateDeleteMdsUserData &data, bool &is_committed) const +{ + #define PRINT_WRAPPER KR(ret), K(data) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!check_is_inited_())) { + ret = OB_NOT_INIT; + MDS_LOG_GET(WARN, "not inited"); + } else if (CLICK_FAIL(get_latest( + [&data](const ObTabletCreateDeleteMdsUserData &user_data) -> int { + return data.assign(user_data); + }, is_committed, 0))) { + MDS_LOG_GET(WARN, "fail to get_latest_tablet_status"); + } else if (!data.is_valid()) { + MDS_LOG_GET(WARN, "get invalid ObTabletCreateDeleteMdsUserData", K(lbt())); + } + return ret; + #undef PRINT_WRAPPER +} + +inline int ObITabletMdsInterface::get_ddl_data(const share::SCN &snapshot, + ObTabletBindingMdsUserData &data, + const int64_t timeout) const +{ + #define PRINT_WRAPPER KR(ret), K(data), K(snapshot), K(timeout) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!check_is_inited_())) { + ret = OB_NOT_INIT; + MDS_LOG_GET(WARN, "not inited"); + } else if (OB_UNLIKELY(!snapshot.is_max())) { + ret = OB_NOT_SUPPORTED; + MDS_LOG_GET(WARN, "only support read latest data currently"); + } else if (CLICK_FAIL(get_snapshot( + [&data](const ObTabletBindingMdsUserData &user_data) -> int { return data.assign(user_data); }, + snapshot, 0, timeout))) { + if (OB_EMPTY_RESULT == ret) { + data.reset(); // use default value + ret = OB_SUCCESS; + } else { + MDS_LOG_GET(WARN, "fail to get_ddl_data"); + } + } + return ret; + #undef PRINT_WRAPPER +} + +inline int ObITabletMdsInterface::get_autoinc_seq(ObIAllocator &allocator, + const share::SCN &snapshot, + share::ObTabletAutoincSeq &data, + const int64_t timeout) const +{ + #define PRINT_WRAPPER KR(ret), K(data), K(snapshot), K(timeout) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!check_is_inited_())) { + ret = OB_NOT_INIT; + MDS_LOG_GET(WARN, "not inited"); + } else if (OB_UNLIKELY(!snapshot.is_max())) { + ret = OB_NOT_SUPPORTED; + MDS_LOG_GET(WARN, "only support read latest data currently"); + } else if (CLICK_FAIL(get_snapshot( + [&allocator, &data](const share::ObTabletAutoincSeq &user_data) -> int { + return data.assign(allocator, user_data); + }, snapshot, 0, timeout))) { + if (OB_EMPTY_RESULT == ret) { + data.reset(); // use default value + ret = OB_SUCCESS; + } else { + MDS_LOG_GET(WARN, "fail to get_autoinc_seq"); + } + } + + return ret; + #undef PRINT_WRAPPER +} + +inline int ObITabletMdsInterface::check_mds_written(bool &written) +{ + int ret = OB_SUCCESS; + written = false; + if (OB_UNLIKELY(!check_is_inited_())) { + ret = OB_NOT_INIT; + MDS_LOG(WARN, "not inited", K(ret), KPC(this)); + } else if (OB_ISNULL(get_tablet_ponter_())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG(ERROR, "tablet pointer is null", K(ret), KPC(this)); + } else { + written = get_tablet_ponter_()->is_mds_written(); + } + return ret; +} + +template +int ObITabletMdsInterface::forcely_release_all_mds_nodes(const char (&reason)[N]) +{ + #define PRINT_WRAPPER KR(ret), K(reason) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + mds::MdsTableHandle handle; + if (OB_UNLIKELY(!check_is_inited_())) { + ret = OB_NOT_INIT; + MDS_LOG_GC(WARN, "not inited"); + } else if (CLICK_FAIL(get_mds_table_handle_(handle, false))) { + if (OB_ENTRY_NOT_EXIST != ret) { + MDS_LOG_GC(WARN, "failed to get_mds_table"); + } else { + ret = OB_SUCCESS; + } + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_GC(WARN, "mds cannot be NULL"); + } else if (CLICK_FAIL(handle.forcely_release_all_mds_nodes(reason))) { + MDS_LOG_GC(WARN, "fail to release mds nodes in mds table"); + } + return ret; + #undef PRINT_WRAPPER +} + +/**********************************IMPLEMENTATION WITH TEMPLATE************************************/ + +template <> +inline int ObITabletMdsInterface::get_mds_data_from_tablet( + const common::ObFunction &read_op) const +{ + #define PRINT_WRAPPER KR(ret), K(data), KPC(kv), K(*this) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObTabletCreateDeleteMdsUserData data; + const mds::MdsDumpKV *kv = nullptr; + ObArenaAllocator allocator("mds_reader"); + const ObTabletComplexAddr &tablet_status_addr = get_mds_data_().tablet_status_.committed_kv_; + const ObTabletCreateDeleteMdsUserData& tablet_status_cache = get_mds_data_().tablet_status_cache_; + + // TODO(@chenqingxiang.cqx): remove read from IO after cache ready + if (tablet_status_cache.is_valid()) { + if (CLICK_FAIL(read_op(tablet_status_cache))) { + MDS_LOG_GET(WARN, "failed to do read op", K(tablet_status_cache)); + } + } else { + if (CLICK_FAIL(ObTabletMdsData::load_mds_dump_kv(allocator, tablet_status_addr, kv))) { + MDS_LOG_GET(WARN, "failed to load mds dump kv"); + } else if (OB_ISNULL(kv)) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_GET(WARN, "unexpected error, mds dump kv is null"); + } else { + const common::ObString &user_data = kv->v_.user_data_; + int64_t pos = 0; + if (user_data.empty()) { + ret = OB_EMPTY_RESULT; + MDS_LOG_GET(WARN, "data on tablet is empty", K(ret), KPC(kv)); + } else if (CLICK_FAIL(data.deserialize(user_data.ptr(), user_data.length(), pos))) { + MDS_LOG_GET(WARN, "failed to deserialize", K(user_data), + "user_data_length", user_data.length(), + "user_hash:%x", user_data.hash(), + "crc_check_number", kv->v_.crc_check_number_); + } else if (CLICK_FAIL(read_op(data))) { + MDS_LOG_GET(WARN, "failed to do read op"); + } + } + + ObTabletMdsData::free_mds_dump_kv(allocator, kv); + } + return ret; + #undef PRINT_WRAPPER +} + +template <> +inline int ObITabletMdsInterface::get_mds_data_from_tablet( + const common::ObFunction &read_op) const +{ + #define PRINT_WRAPPER KR(ret), K(data), KPC(kv), K(*this) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObTabletBindingMdsUserData data; + const mds::MdsDumpKV *kv = nullptr; + ObArenaAllocator allocator("mds_reader"); + const ObTabletComplexAddr &aux_tablet_info_addr = get_mds_data_().aux_tablet_info_.committed_kv_; + const ObTabletBindingMdsUserData& aux_tablet_info_cache = get_mds_data_().aux_tablet_info_cache_; + + // TODO(@chenqingxiang.cqx): remove read from IO after cache ready + if (aux_tablet_info_addr.is_disk_object() && !aux_tablet_info_cache.is_valid()) { + if (CLICK_FAIL(ObTabletMdsData::load_mds_dump_kv(allocator, aux_tablet_info_addr, kv))) { + MDS_LOG_GET(WARN, "failed to load mds dump kv"); + } else if (OB_ISNULL(kv)) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_GET(WARN, "unexpected error, mds dump kv is null"); + } else { + const common::ObString &user_data = kv->v_.user_data_; + int64_t pos = 0; + if (user_data.empty()) { + ret = OB_EMPTY_RESULT; + } else if (CLICK_FAIL(data.deserialize(user_data.ptr(), user_data.length(), pos))) { + MDS_LOG_GET(WARN, "failed to deserialize", K(user_data), + "user_data_length", user_data.length(), + "user_hash:%x", user_data.hash(), + "crc_check_number", kv->v_.crc_check_number_); + } else if (CLICK_FAIL(read_op(data))) { + MDS_LOG_GET(WARN, "failed to read_op"); + } + } + + ObTabletMdsData::free_mds_dump_kv(allocator, kv); + } else { + if (CLICK_FAIL(read_op(aux_tablet_info_cache))) { + MDS_LOG_GET(WARN, "failed to read_op aux_tablet_info_cache", K(aux_tablet_info_cache)); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template <> +inline int ObITabletMdsInterface::get_mds_data_from_tablet( + const common::ObFunction &read_op) const +{ + #define PRINT_WRAPPER KR(ret), K(auto_inc_seq_addr), K(*this) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + const ObTabletComplexAddr &auto_inc_seq_addr = get_mds_data_().auto_inc_seq_; + const share::ObTabletAutoincSeq *auto_inc_seq = nullptr; + ObTabletMemberWrapper wrapper; + + if (CLICK_FAIL(ObTabletMdsData::fetch_auto_inc_seq(auto_inc_seq_addr, wrapper))) { + MDS_LOG_GET(WARN, "failed to fetch auto inc seq"); + } else if (CLICK_FAIL(wrapper.get_member(auto_inc_seq))) { + MDS_LOG_GET(WARN, "failed to get member"); + } else if (CLICK_FAIL(read_op(*auto_inc_seq))) { + MDS_LOG_GET(WARN, "failed to read_op"); + } + + return ret; + #undef PRINT_WRAPPER +} + +template // general set for dummy key unit +int ObITabletMdsInterface::set(T &&data, mds::MdsCtx &ctx, const int64_t lock_timeout_us) +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(data), K(ctx), K(lock_timeout_us) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + mds::MdsTableHandle handle; + if (CLICK_FAIL(get_mds_table_handle_(handle, true))) { + MDS_LOG_SET(WARN, "failed to get_mds_table"); + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "mds cannot be NULL"); + } else if (CLICK_FAIL(handle.set(std::forward(data), ctx, lock_timeout_us))) { + MDS_LOG_SET(WARN, "failed to set dummy key unit data"); + } else if (OB_ISNULL(get_tablet_ponter_())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "tablet pointer is null", K(ret), KPC(this)); + } else { + get_tablet_ponter_()->set_mds_written(); + MDS_LOG_SET(TRACE, "success to set dummy key unit data"); + } + return ret; + #undef PRINT_WRAPPER +} + +template // general replay for dummy key unit +int ObITabletMdsInterface::replay(T &&data, mds::MdsCtx &ctx, const share::SCN &scn)// called by ObTabletReplayExecutor +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(data), K(ctx), K(scn) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (scn < get_tablet_meta_().mds_checkpoint_scn_) { + MDS_LOG_SET(TRACE, "no need do replay"); + } else { + mds::MdsTableHandle handle; + if (CLICK_FAIL(get_mds_table_handle_(handle, true))) { + MDS_LOG_SET(WARN, "failed to get_mds_table"); + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "mds cannot be NULL"); + } else if (CLICK_FAIL(handle.replay(std::forward(data), ctx, scn))) { + MDS_LOG_SET(WARN, "failed to replay dummy key unit data"); + } else if (OB_ISNULL(get_tablet_ponter_())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "tablet pointer is null", K(ret), KPC(this)); + } else { + get_tablet_ponter_()->set_mds_written(); + MDS_LOG_SET(TRACE, "success to replay dummy key unit data"); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template // general set for multi key unit +int ObITabletMdsInterface::set(const Key &key, Value &&data, mds::MdsCtx &ctx, const int64_t lock_timeout_us) +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(key), K(data), K(ctx), K(lock_timeout_us) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + mds::MdsTableHandle handle; + if (CLICK_FAIL(get_mds_table_handle_(handle, true))) { + MDS_LOG_SET(WARN, "failed to get_mds_table"); + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "mds cannot be NULL"); + } else if (CLICK_FAIL(handle.set(key, std::forward(data), ctx, lock_timeout_us))) { + MDS_LOG_SET(WARN, "failed to set multi key unit data"); + } else if (OB_ISNULL(get_tablet_ponter_())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "tablet pointer is null", K(ret), KPC(this)); + } else { + get_tablet_ponter_()->set_mds_written(); + MDS_LOG_SET(TRACE, "success to set multi key unit data"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +int ObITabletMdsInterface::replay(const Key &key, + Value &&mds, + mds::MdsCtx &ctx, + const share::SCN &scn)// called only by ObTabletReplayExecutor +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(key), K(mds), K(ctx), K(scn) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (scn < get_tablet_meta_().mds_checkpoint_scn_) { + MDS_LOG_SET(TRACE, "no need do replay"); + } else { + mds::MdsTableHandle handle; + if (CLICK_FAIL(get_mds_table_handle_(handle, true))) { + MDS_LOG_SET(WARN, "failed to get_mds_table"); + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "mds cannot be NULL"); + } else if (CLICK_FAIL(handle.replay(key, std::forward(mds), ctx, scn))) { + MDS_LOG_SET(WARN, "failed to replay multi key unit data"); + } else if (OB_ISNULL(get_tablet_ponter_())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "tablet pointer is null", K(ret), KPC(this)); + } else { + get_tablet_ponter_()->set_mds_written(); + MDS_LOG_SET(TRACE, "success to replay multi key unit data"); + } + } + return ret; + #undef PRINT_WRAPPER +} + +template // general remove for multi key unit +int ObITabletMdsInterface::remove(const Key &key, mds::MdsCtx &ctx, const int64_t lock_timeout_us) +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(key), K(ctx), K(lock_timeout_us) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + mds::MdsTableHandle handle; + if (CLICK_FAIL(get_mds_table_handle_(handle, true))) { + MDS_LOG_SET(WARN, "failed to get_mds_table"); + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "mds cannot be NULL"); + } else if (CLICK_FAIL(handle.remove(key, ctx, lock_timeout_us))) { + MDS_LOG_SET(WARN, "failed to remove multi key unit data"); + } else if (OB_ISNULL(get_tablet_ponter_())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "tablet pointer is null", K(ret), KPC(this)); + } else { + get_tablet_ponter_()->set_mds_written(); + MDS_LOG_SET(TRACE, "success to remove multi key unit data"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +int ObITabletMdsInterface::replay_remove(const Key &key, mds::MdsCtx &ctx, const share::SCN &scn) +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(key), K(ctx), K(scn) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + mds::MdsTableHandle handle; + if (CLICK_FAIL(get_mds_table_handle_(handle, true))) { + MDS_LOG_SET(WARN, "failed to get_mds_table"); + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "mds cannot be NULL"); + } else if (CLICK() && OB_SUCCESS != (ret = handle.replay_remove(key, ctx, scn))) { + MDS_LOG_SET(WARN, "failed to replay remove multi key unit data"); + } else if (OB_ISNULL(get_tablet_ponter_())) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_SET(WARN, "tablet pointer is null", K(ret), KPC(this)); + } else { + get_tablet_ponter_()->set_mds_written(); + MDS_LOG_SET(TRACE, "success to remove multi key unit data"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +int ObITabletMdsInterface::is_locked_by_others(bool &is_locked, const mds::MdsWriter &self) const +{// FIXME: need concern about dumped uncommitted data on tablet + #define PRINT_WRAPPER KR(ret), K(*this), K(is_locked), K(self) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + mds::MdsTableHandle handle; + if (CLICK_FAIL(get_mds_table_handle_(handle, false))) { + if (OB_ENTRY_NOT_EXIST != ret) { + MDS_LOG_GET(WARN, "failed to get_mds_table"); + } else { + MDS_LOG_GET(TRACE, "failed to get_mds_table"); + ret = OB_SUCCESS; + is_locked = false; + } + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_GET(WARN, "mds cannot be NULL"); + } else if (CLICK_FAIL(handle.is_locked_by_others(is_locked, self))) { + if (OB_SNAPSHOT_DISCARDED != ret) { + MDS_LOG_GET(WARN, "failed to check lock unit data"); + } else { + MDS_LOG_GET(TRACE, "failed to check lock unit data"); + ret = OB_SUCCESS; + is_locked = false; + } + } + if (OB_SUCC(ret)) { + MDS_LOG_GET(TRACE, "success to get is locked by others state"); + } + return ret; + #undef PRINT_WRAPPER +} + +template +int ObITabletMdsInterface::get_latest(OP &&read_op, bool &is_committed, const int64_t read_seq) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(read_seq), K(typeid(OP).name()) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + mds::MdsTableHandle handle; + if (CLICK_FAIL(get_mds_table_handle_(handle, false))) { + if (OB_ENTRY_NOT_EXIST != ret) { + MDS_LOG_GET(WARN, "failed to get_mds_table"); + } else { + MDS_LOG_GET(TRACE, "failed to get_mds_table"); + } + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_GET(WARN, "mds cannot be NULL"); + } else if (CLICK_FAIL(handle.get_latest(read_op, is_committed, read_seq))) { + MDS_LOG_GET(WARN, "failed to get_latest"); + } + if (CLICK_FAIL(ret)) { + if (OB_ENTRY_NOT_EXIST == ret || OB_SNAPSHOT_DISCARDED == ret) { + auto func = [&read_op, &is_committed](const T& data) -> int { + is_committed = true;// FIXME: here need more judge after support dump uncommitted node + return read_op(data); + }; + if (CLICK_FAIL(get_mds_data_from_tablet(func))) { + MDS_LOG_GET(WARN, "failed to get latest data from tablet"); + } + } + } + return ret; + #undef PRINT_WRAPPER +} + +template // general get for dummy key unit +int ObITabletMdsInterface::get_snapshot(OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(snapshot), K(read_seq), K(typeid(OP).name()) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + mds::MdsTableHandle handle; + if (CLICK_FAIL(get_mds_table_handle_(handle, false))) { + if (OB_ENTRY_NOT_EXIST != ret) { + MDS_LOG_GET(WARN, "failed to get_mds_table"); + } else { + MDS_LOG_GET(TRACE, "failed to get_mds_table"); + } + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_GET(WARN, "mds cannot be NULL"); + } else if (CLICK_FAIL(handle.get_snapshot(read_op, snapshot, read_seq, timeout_us))) { + if (OB_SNAPSHOT_DISCARDED != ret) { + MDS_LOG_GET(WARN, "failed to get_snapshot"); + } + } + if (CLICK_FAIL(ret)) { + if (OB_ENTRY_NOT_EXIST == ret || OB_SNAPSHOT_DISCARDED == ret) { + auto func = [&read_op](const T& data) -> int { + return read_op(data); + }; + if (CLICK_FAIL(get_mds_data_from_tablet(func))) { + MDS_LOG_GET(WARN, "failed to get snapshot data from tablet"); + } + } + } + return ret; + #undef PRINT_WRAPPER +} + +template // general get for multi key unit +int ObITabletMdsInterface::get_snapshot(const Key &key, + OP &&read_op, + const share::SCN snapshot, + const int64_t read_seq, + const int64_t timeout_us) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(key), K(snapshot), K(read_seq), K(typeid(OP).name()) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + mds::MdsTableHandle handle; + if (CLICK_FAIL(get_mds_table_handle_(handle, false))) { + if (OB_ENTRY_NOT_EXIST != ret) { + MDS_LOG_GET(WARN, "failed to get_mds_table"); + } else { + MDS_LOG_GET(TRACE, "failed to get_mds_table"); + } + } else if (!handle.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_GET(WARN, "mds cannot be NULL"); + } else if (CLICK() && OB_SUCCESS != (ret = handle.get_snapshot(key, read_op, snapshot, read_seq, timeout_us))) { + MDS_LOG_GET(WARN, "failed to get_snapshot"); + } + if (CLICK_FAIL(ret)) { + if (OB_ENTRY_NOT_EXIST == ret || OB_SNAPSHOT_DISCARDED == ret) { + auto func = [&read_op](const Value& data) -> int { + return read_op(data); + }; + if (CLICK_FAIL(get_mds_data_from_tablet(func))) { + MDS_LOG_GET(WARN, "failed to get latest data from tablet"); + } + } + } + return ret; + #undef PRINT_WRAPPER +} + +template +int ObITabletMdsInterface::obj_to_string_holder_(const T &obj, ObStringHolder &holder) const +{ + int ret = OB_SUCCESS; + constexpr int64_t buffer_size = 1_KB; + char stack_buffer[buffer_size] = { 0 }; + int64_t pos = 0; + if (FALSE_IT(databuff_printf(stack_buffer, buffer_size, pos, "%s", to_cstring(obj)))) {// try hard to fill buffer, it's ok if buffer not enough + } else if (OB_FAIL(holder.assign(ObString(pos, stack_buffer)))) { + MDS_LOG(WARN, "fatil to assign to holder"); + } + return ret; +} + +template +int ObITabletMdsInterface::fill_virtual_info_by_complex_addr_(const ObTabletComplexAddr &addr, + ObIArray &mds_node_info_array) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(mds_node_info_array), K(typeid(T).name()), KPC(dump_kv) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObArenaAllocator allocator("vir_mds_reader"); + mds::MdsNodeInfoForVirtualTable *cur_virtual_info = nullptr; + mds::UserMdsNode user_mds_node; + const mds::MdsDumpKV *dump_kv = nullptr; + + if (CLICK_FAIL(mds_node_info_array.push_back(mds::MdsNodeInfoForVirtualTable()))) { + MDS_LOG_GET(WARN, "fatil to push_back"); + } else if (FALSE_IT(cur_virtual_info = &mds_node_info_array.at(mds_node_info_array.count() - 1))) { + } else { + if (CLICK_FAIL(ObTabletMdsData::load_mds_dump_kv(allocator, addr, dump_kv))) { + MDS_LOG_GET(WARN, "fatil to read tablet_status_addr"); + } else if (!dump_kv->is_valid()) { + ret = OB_ENTRY_NOT_EXIST; + MDS_LOG_GET(INFO, "dump kv not exist"); + if (OB_NOT_NULL(dump_kv)) { + MDS_LOG_GET(INFO, "xuwang.txw debug", K(dump_kv->k_), K(dump_kv->v_)); + } + } else if (CLICK_FAIL(obj_to_string_holder_(dump_kv->k_, cur_virtual_info->user_key_))) { + MDS_LOG_GET(WARN, "fatil to fill string holder"); + } else if (CLICK_FAIL(dump_kv->v_.convert_to_user_mds_node(user_mds_node, get_tablet_meta_().ls_id_, get_tablet_meta_().tablet_id_))) { + MDS_LOG_GET(WARN, "fatil to convert tablet_status_node"); + } else if (CLICK_FAIL(user_mds_node.fill_virtual_info(*cur_virtual_info))) { + MDS_LOG_GET(WARN, "fatil to fill virtual info"); + } else { + cur_virtual_info->ls_id_ = get_tablet_meta_().ls_id_; + cur_virtual_info->tablet_id_ = get_tablet_meta_().tablet_id_; + cur_virtual_info->position_ = mds::NodePosition::DISK; + cur_virtual_info->unit_id_ = dump_kv->v_.mds_unit_id_; + } + if (OB_FAIL(ret)) { + mds_node_info_array.pop_back(); + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } + } + + ObTabletMdsData::free_mds_dump_kv(allocator, dump_kv); + } + return ret; + #undef PRINT_WRAPPER +} + +template +int ObITabletMdsInterface::fill_virtual_info_by_obj_(const T &obj, + const mds::NodePosition position, + ObIArray &mds_node_info_array) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(mds_node_info_array) + MDS_TG(10_ms); + mds::MdsNodeInfoForVirtualTable *cur_virtual_info = nullptr; + int ret = OB_SUCCESS; + if (!obj.is_valid()) { + MDS_LOG_GET(INFO, "obj is not valid"); + } else if (CLICK_FAIL(mds_node_info_array.push_back(mds::MdsNodeInfoForVirtualTable()))) { + MDS_LOG_GET(WARN, "fatil to push_back"); + } else if (FALSE_IT(cur_virtual_info = &mds_node_info_array.at(mds_node_info_array.count() - 1))) { + } else { + if (CLICK_FAIL(obj_to_string_holder_(obj, cur_virtual_info->user_data_))) { + MDS_LOG_GET(WARN, "fatil to fill string holder"); + } else { + cur_virtual_info->ls_id_ = get_tablet_meta_().ls_id_; + cur_virtual_info->tablet_id_ = get_tablet_meta_().tablet_id_; + cur_virtual_info->position_ = position; + cur_virtual_info->unit_id_ = mds::TupleTypeIdx>::value; + } + if (CLICK_FAIL(ret)) { + mds_node_info_array.pop_back(); + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } + } + } + return ret; + #undef PRINT_WRAPPER +} + +inline int ObITabletMdsInterface::fill_virtual_info(ObIArray &mds_node_info_array) const +{ + #define PRINT_WRAPPER KR(ret), K(*this), K(mds_node_info_array) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + + ObArenaAllocator allocator("mds_reader"); + share::ObTabletAutoincSeq seq_on_tablet; + if (CLICK_FAIL(get_mds_data_from_tablet([&allocator, &seq_on_tablet](const share::ObTabletAutoincSeq &seq) { + return seq_on_tablet.assign(allocator, seq); + }))) { + MDS_LOG_GET(WARN, "fatil to get seq from disk"); + } else if (CLICK_FAIL(fill_virtual_info_by_obj_(seq_on_tablet, mds::NodePosition::DISK, mds_node_info_array))) { + MDS_LOG_GET(WARN, "fatil to fill seq from disk"); + } else if (CLICK_FAIL(fill_virtual_info_by_obj_(get_mds_data_().tablet_status_cache_, mds::NodePosition::TABLET, mds_node_info_array))) { + MDS_LOG_GET(WARN, "fatil to fill tablet_status_ from cache"); + } else if (CLICK_FAIL(fill_virtual_info_by_complex_addr_(get_mds_data_().tablet_status_.committed_kv_, mds_node_info_array))) { + MDS_LOG_GET(WARN, "fatil to fill tablet_status_"); + } else if (CLICK_FAIL(fill_virtual_info_by_complex_addr_(get_mds_data_().aux_tablet_info_.committed_kv_, mds_node_info_array))) { + MDS_LOG_GET(WARN, "fatil to fill aux_tablet_info_"); + } + + return ret; + #undef PRINT_WRAPPER +} + +} +} diff --git a/src/storage/tablet/ob_table_store_util.cpp b/src/storage/tablet/ob_table_store_util.cpp old mode 100644 new mode 100755 index 501535141..0fbd9dbb2 --- a/src/storage/tablet/ob_table_store_util.cpp +++ b/src/storage/tablet/ob_table_store_util.cpp @@ -32,268 +32,155 @@ using namespace common; using namespace storage; using namespace blocksstable; -ObITableArray::ObITableArray() - : meta_mem_mgr_(nullptr), - array_(nullptr), - allocator_(nullptr), - count_(0), - is_inited_(false) -{ -} - -ObITableArray::~ObITableArray() -{ - destroy(); -} - -void ObITableArray::destroy() +void ObSSTableArray::reset() { + if (OB_LIKELY(nullptr != sstable_array_)) { + for (int64_t i = 0; i < cnt_; i++) { + ObSSTable *sstable = sstable_array_[i]; + if (OB_LIKELY(nullptr != sstable)) { + sstable->~ObSSTable(); + sstable = nullptr; + } + } + } + cnt_ = 0; + sstable_array_ = nullptr; is_inited_ = false; - if (OB_NOT_NULL(array_)) { - for (int64_t i = 0; i < count_; ++i) { - reset_table(i); - } - if (OB_NOT_NULL(allocator_)) { - allocator_->free(array_); - } - array_ = nullptr; - } - count_ = 0; - if (OB_NOT_NULL(allocator_)) { - allocator_ = nullptr; - } } -void ObITableArray::reset_table(const int64_t pos) -{ - if (pos < 0 || pos >= count_) { // do nothing - } else if (OB_ISNULL(array_[pos])) { - // maybe called by thread without tenant, such as iocallback, comment until remove tablet_handle from iocallback - // } else if (OB_UNLIKELY(meta_mem_mgr_ != MTL(ObTenantMetaMemMgr *) || nullptr == meta_mem_mgr_)) { - } else if (OB_ISNULL(meta_mem_mgr_) || OB_ISNULL(allocator_)) { - LOG_ERROR_RET(OB_ERR_UNEXPECTED, "[MEMORY LEAK] TenantMetaMemMgr is unexpected not equal!!!", K(meta_mem_mgr_), KP(allocator_), KPC(array_[pos])); - } else if (0 == array_[pos]->dec_ref()) { - if (meta_mem_mgr_->is_used_obj_pool(allocator_)) { - if (OB_UNLIKELY(OB_INVALID_TENANT_ID == MTL_ID() - && array_[pos]->is_sstable() - && reinterpret_cast(array_[pos])->is_small_sstable())) { - FLOG_INFO("this thread doesn't have MTL ctx, push sstable into gc queue", KP(array_[pos]), K(array_[pos]->get_key())); - meta_mem_mgr_->push_table_into_gc_queue(array_[pos], array_[pos]->get_key().table_type_); - } else if (array_[pos]->is_sstable() && !array_[pos]->is_ddl_mem_sstable()) { - meta_mem_mgr_->gc_sstable(reinterpret_cast(array_[pos])); - } else { - meta_mem_mgr_->push_table_into_gc_queue(array_[pos], array_[pos]->get_key().table_type_); - } - } else { - array_[pos]->~ObITable(); - allocator_->free(array_[pos]); - } - array_[pos] = nullptr; - } else { - array_[pos] = nullptr; - } -} - -int ObITableArray::init(ObIAllocator &allocator, const int64_t count) -{ - int ret = OB_SUCCESS; - ObITable **buf = nullptr; - ObTenantMetaMemMgr *meta_mem_mgr = MTL(ObTenantMetaMemMgr *); - if (IS_INIT) { - ret = OB_INIT_TWICE; - LOG_WARN("ObITableArray cannot init twice", K(ret), K(*this)); - } else if (OB_UNLIKELY(0 >= count)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid argument", K(ret), K(count)); - } else if (OB_ISNULL(buf = static_cast(allocator.alloc(sizeof(ObITable*) * count)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("failed to alloc memory for table pointer", K(ret), K(count)); - } else if (OB_ISNULL(meta_mem_mgr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get meta mem mgr from MTL", K(ret)); - } else { - MEMSET(buf, 0, sizeof(ObITable*) * count); - meta_mem_mgr_ = meta_mem_mgr; - allocator_ = &allocator; - array_ = buf; - count_ = count; - is_inited_ = true; - } - - if (OB_UNLIKELY(!is_inited_) && OB_NOT_NULL(buf)) { - allocator.free(buf); - array_ = nullptr; - } - return ret; -} - -int ObITableArray::copy( - ObIAllocator &allocator, - const ObITableArray &other, - const bool allow_empty_table) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(init(allocator, other.count_))) { - LOG_WARN("failed to init ObITableArray for copying", K(ret), K(other)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < count_; ++i) { - if (OB_ISNULL(other[i])) { - if (!allow_empty_table) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table must be not null", K(ret), K(i), K(other)); - } - } else if (OB_FAIL(assign(i, other[i]))) { - LOG_WARN("failed to add table", K(ret), K(i), K(other[i])); - } - } - if (OB_FAIL(ret)) { - destroy(); - } - } - return ret; -} - -int ObITableArray::init_and_copy( - ObIAllocator &allocator, +int ObSSTableArray::init( + ObArenaAllocator &allocator, const ObIArray &tables, const int64_t start_pos) { int ret = OB_SUCCESS; - if (tables.empty() || start_pos < 0 || start_pos >= tables.count()) { + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_UNLIKELY(start_pos > tables.count())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid argument", K(ret), K(tables), K(MAX_SSTABLE_CNT_IN_STORAGE)); - } else if (OB_FAIL(init(allocator, tables.count() - start_pos))) { - LOG_WARN("failed to init ObITableArray", K(ret), K(*this)); + LOG_WARN("invalid start pos", K(ret), K(start_pos), K(tables.count())); + } else if (OB_FAIL(inner_init(allocator, tables, start_pos, tables.count() - start_pos))) { + LOG_WARN("fail to init sstable array", K(ret)); } else { - ObITable *table = nullptr; - for (int64_t i = start_pos; OB_SUCC(ret) && i < tables.count(); ++i) { - if (OB_ISNULL(table = tables.at(i))) { + is_inited_ = true; + } + return ret; +} + +int ObSSTableArray::init(ObArenaAllocator &allocator, const blocksstable::ObSSTable *sstable) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_UNLIKELY(!sstable->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("try to init sstable array with an unserialized sstable", K(ret), KPC(sstable)); + } else { + cnt_ = 1; + sstable_array_ = reinterpret_cast(allocator.alloc(sizeof(ObSSTable *))); + if (OB_ISNULL(sstable_array_)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for sstable address array", K(ret), K_(cnt)); + } else if (OB_FAIL(sstable->deep_copy(allocator, sstable_array_[0]))) { + LOG_WARN("fail to deep copy sstable address", K(ret), KPC(sstable)); + } else { + is_inited_ = true; + } + } + return ret; +} + +int ObSSTableArray::init( + ObArenaAllocator &allocator, + const ObIArray &tables, + const ObIArray &addrs, + const int64_t start_pos, + const int64_t cnt) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_FAIL(inner_init(allocator, tables, start_pos, cnt))) { + LOG_WARN("fail to inner init sstable array", K(ret)); + } else { + for (int64_t i = start_pos; OB_SUCC(ret) && i < start_pos + cnt; ++i) { + ObSSTable *sstable = sstable_array_[i - start_pos]; + if (OB_ISNULL(sstable)) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("table must not null", K(ret), K(tables)); - } else if (OB_FAIL(assign(i - start_pos, table))) { - LOG_WARN("failed to add table to tables", K(ret)); + LOG_WARN("unexpected null sstable pointer", K(ret), K(tables), K(addrs), K(start_pos), K(cnt)); + } else if (OB_FAIL(sstable->set_addr(addrs.at(i)))) { + LOG_WARN("fail to set sstable meta disk address", K(ret)); + } + } + if (OB_SUCC(ret)) { + is_inited_ = true; + } + } + return ret; +} + +int ObSSTableArray::init(ObArenaAllocator &allocator, const ObSSTableArray &other) +{ + int ret = OB_SUCCESS; + ObSEArray tables; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_FAIL(other.get_all_tables(tables))) { + LOG_WARN("fail to get all tables from old array", K(ret), K(other)); + } else if (OB_FAIL(inner_init(allocator, tables, 0, tables.count()))) { + LOG_WARN("fail to inner init sstable array", K(ret)); + } else { + is_inited_ = true; + } + return ret; +} + +int ObSSTableArray::inner_init( + ObArenaAllocator &allocator, + const ObIArray &tables, + const int64_t start_pos, + const int64_t count) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY( + tables.count() < 0 + || count < 0 + || start_pos + count > tables.count() + || start_pos < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments to init sstable array for serialize", K(ret), + K(tables), K(start_pos), K(count)); + } else if (0 == count) { + // nothing to do. + cnt_ = 0; + sstable_array_ = nullptr; + } else { + cnt_ = count; + sstable_array_ = static_cast(allocator.alloc(sizeof(ObSSTable *) * cnt_)); + if (OB_ISNULL(sstable_array_)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for sstable address array", K(ret), K_(cnt)); + } + for (int64_t i = start_pos; OB_SUCC(ret) && i < start_pos + count; ++i) { + ObITable *table = tables.at(i); + if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null table ptr", K(ret)); + } else if (OB_UNLIKELY(!table->is_sstable() && !table->is_ddl_mem_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table type", K(ret), KPC(table)); + } else if (OB_FAIL(static_cast(table)->deep_copy(allocator, sstable_array_[i - start_pos]))) { + LOG_WARN("fail to copy sstable", K(ret), KPC(static_cast(table))); } } if (OB_FAIL(ret)) { - destroy(); - } - } - return ret; -} - -int ObITableArray::assign(const int64_t pos, ObITable * const table) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *meta_mem_mgr = MTL(ObTenantMetaMemMgr *); - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("ObITableArray not inited", K(ret), K(*this)); - } else if (OB_UNLIKELY(pos < 0 || pos >= count_ || NULL == table)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid argument", K(ret), K(pos), KP(table), K(*this)); - } else if (meta_mem_mgr_ != meta_mem_mgr) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("meta mem mgr is unexpected not equal!", K(ret), K(meta_mem_mgr_), K(meta_mem_mgr)); - } else { - array_[pos] = table; - table->inc_ref(); - } - return ret; -} - -int ObITableArray::get_all_tables(common::ObIArray &tables) const -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - } else if (0 >= count_) { - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < count_; ++i) { - if (OB_ISNULL(array_[i])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table must not be null", K(ret), K(i), K(*this)); - } else if (OB_FAIL(tables.push_back(array_[i]))) { - LOG_WARN("fail to push back", K(ret), K(i)); - } - } - } - return ret; -} - -ObITable *ObITableArray::get_boundary_table(const bool last) const -{ - ObITable *table = nullptr; - if (IS_NOT_INIT) { - // not inited, just return nullptr - } else if (0 >= count_) { - // no table, just return nullptr. - } else if (last) { - table = array_[count_ - 1]; - } else { - table = array_[0]; - } - return table; -} - -int ObITableArray::get_table(const ObITable::TableKey &table_key, ObTableHandleV2 &handle) const -{ - int ret = OB_SUCCESS; - handle.reset(); - if (IS_NOT_INIT) { - } else if (0 >= count_) { - } else if (OB_UNLIKELY(!table_key.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(table_key)); - } else { - ObITable *table = nullptr; - for (int64_t i = 0; OB_SUCC(ret) && i < count_; ++i) { - if (OB_ISNULL(array_[i])) { - } else if (table_key == array_[i]->get_key()) { - table = array_[i]; - break; - } - } - - if (OB_SUCC(ret) && OB_NOT_NULL(table)) { - if (OB_FAIL(handle.set_table(table, meta_mem_mgr_, table->get_key().table_type_))) { - LOG_WARN("failed to set table handle", K(ret)); - } - } - } - return ret; -} - -int ObITableArray::get_all_tables(storage::ObTablesHandleArray &tables) const -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - } else if (0 >= count_) { - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < count_; ++i) { - if (OB_ISNULL(array_[i])) { - } else if (OB_FAIL(tables.add_table(array_[i]))) { - LOG_WARN("failed to add table to handle array", K(ret)); - } - } - } - return ret; -} - - -int ObSSTableArray::serialize(char *buf, const int64_t buf_len, int64_t &pos) const -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(NULL == buf || buf_len <= 0 || pos < 0)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments.", KP(buf), K(buf_len), K(pos), K(ret)); - } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, count_))) { - LOG_WARN("failed to encode count", K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < count_; ++i) { - if (OB_ISNULL(array_[i])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table in array_ must not be null", K(ret), K(i)); - } else if (OB_FAIL(array_[i]->serialize(buf, buf_len, pos))) { - LOG_WARN("failed to serialize table", K(ret), KPC(array_[i])); + if (nullptr != sstable_array_) { + allocator.free(sstable_array_); + sstable_array_ = nullptr; } } } @@ -302,335 +189,537 @@ int ObSSTableArray::serialize(char *buf, const int64_t buf_len, int64_t &pos) co int64_t ObSSTableArray::get_serialize_size() const { + int ret = OB_SUCCESS; int64_t len = 0; - len += serialization::encoded_length_i64(count_); - for (int64_t i = 0; i < count_; ++i) { - len += array_[i]->get_serialize_size(); + len += serialization::encoded_length_i64(cnt_); + for (int64_t i = 0; OB_SUCC(ret) && i < cnt_; ++i) { + ObSSTable *sstable = sstable_array_[i]; + if (OB_ISNULL(sstable) || + OB_UNLIKELY(!sstable->get_addr().is_valid() || sstable->get_addr().is_none())) { + len = 0; + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid sstable", K(ret), KPC(sstable)); + } else { + len += sstable->get_serialize_size(); + } } return len; } +int ObSSTableArray::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(buf_len)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, cnt_))) { + LOG_WARN("fail to encode count", K(ret), K_(cnt)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < cnt_; ++i) { + ObSSTable *sstable = sstable_array_[i]; + if (OB_ISNULL(sstable) + || OB_UNLIKELY(!sstable->get_addr().is_valid() || sstable->get_addr().is_none())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid sstable address", K(ret), KPC(sstable)); + } else if (OB_FAIL(sstable->serialize(buf, buf_len, pos))) { + LOG_WARN("failed to serialize sstable address", K(ret), KPC(sstable)); + } + } + + return ret; +} + int ObSSTableArray::deserialize( - ObIAllocator &allocator, + ObArenaAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos) { int ret = OB_SUCCESS; - int64_t count = 0; - - if (OB_UNLIKELY(NULL == buf || data_len <= 0 || pos < 0)) { + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_ISNULL(buf) || OB_UNLIKELY(pos < 0 || data_len <= pos)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid arguments.", KP(buf),K(data_len), K(pos), K(ret)); - } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &count))) { - LOG_WARN("failed to decode count_", K(ret)); - } else if (0 >= count) { - } else if (OB_FAIL(init(allocator, count))) { - LOG_WARN("failed to init ObSSTableArray", K(ret), K(*this)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < count && pos < data_len; ++i) { - ObTableHandleV2 table_handle; - ObSSTable *sstable = nullptr; - if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->acquire_sstable(table_handle, allocator))) { - LOG_WARN("failed to acquire sstable from meta_mem_mgr", K(ret)); - } else if (OB_ISNULL(sstable = static_cast(table_handle.get_table()))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, sstable is nullptr", K(ret), K(table_handle)); - } else if (OB_FAIL(sstable->deserialize(allocator, buf, data_len, pos))) { - LOG_WARN("failed to deserialize sstable", K(ret)); - } else if (OB_FAIL(assign(i, table_handle.get_table()))) { - LOG_WARN("failed to assign table to ObSSTableArray", K(ret), K(i)); - } - } - } - - if (OB_FAIL(ret)) { - destroy(); - } - return ret; -} - -int ObSSTableArray::get_min_schema_version(int64_t &min_schema_version) const -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("ObSSTableArray not inited", K(ret), K(*this)); - } else { - min_schema_version = INT64_MAX; - for (int64_t i = 0; OB_SUCC(ret) && i < count_; ++i) { - if (OB_ISNULL(array_[i])) { - ret = OB_ERR_SYS; - LOG_ERROR("unexpected null sstable", K(ret), K(i), K(*this)); - } else { - min_schema_version = MIN(min_schema_version, static_cast(array_[i])->get_meta().get_basic_meta().schema_version_); - } - } - } - return ret; -} - - -int ObExtendTableArray::serialize(char *buf, const int64_t buf_len, int64_t &pos) const -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { + LOG_WARN("invalid argument", K(ret), KP(buf), K(data_len), K(pos)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &cnt_))) { + LOG_WARN("fail to decode count", K(ret)); + } else if (0 == cnt_) { + // empty sstable array + } else if (OB_UNLIKELY(cnt_ < 0)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("ObExtendTableArray not inited, cannot serialize", K(ret)); - } else if (OB_UNLIKELY(NULL == buf || buf_len <= 0 || pos < 0)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments.", KP(buf), K(buf_len), K(pos), K(ret)); + LOG_WARN("deserialized array count less than 0", K(ret), K_(cnt)); } else { - int64_t table_count = 0; - for (int64_t i = 0; i < count_; ++i) { - if (OB_NOT_NULL(array_[i])) { - ++table_count; - } - } - if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, table_count))) { - LOG_WARN("failed to serialize table count", K(ret)); - } else if (0 == table_count) { // no extend tables + const int64_t ptr_array_size = sizeof(ObSSTable *) * cnt_; + const int64_t obj_array_size = sizeof(ObSSTable) * cnt_; + char *buff = nullptr; + if (OB_ISNULL(buff = static_cast(allocator.alloc(ptr_array_size + obj_array_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for sstable array", K(ret), K_(cnt), K(ptr_array_size), K(obj_array_size)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < count_; ++i) { - if (OB_ISNULL(array_[i])) { - } else if (OB_FAIL(array_[i]->serialize(buf, buf_len, pos))) { - LOG_WARN("failed to serialize table", K(ret), KPC(array_[i])); + sstable_array_ = reinterpret_cast(buff); + ObSSTable *obj_array = new (buff + ptr_array_size) ObSSTable[cnt_]; + for (int64_t i = 0; OB_SUCC(ret) && i < cnt_; ++i) { + sstable_array_[i] = obj_array + i; + if (OB_FAIL(sstable_array_[i]->deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("fail to deserialized sstable address", K(ret)); } } } + if (OB_FAIL(ret)) { + if (nullptr != sstable_array_) { + allocator.free(sstable_array_); + sstable_array_ = nullptr; + } + } else { + is_inited_ = true; + } } return ret; } -int64_t ObExtendTableArray::get_serialize_size() const +int64_t ObSSTableArray::get_deep_copy_size() const { int64_t len = 0; - int64_t count = 0; - for (int64_t i = 0; i < count_; ++i) { - if (OB_NOT_NULL(array_[i])) { - ++count; - } - } - len += serialization::encoded_length_i64(count); - for (int64_t i = 0; i < count_; ++i) { - if (OB_NOT_NULL(array_[i])) { - len += array_[i]->get_serialize_size(); + len += cnt_ * sizeof(ObSSTable *); + for (int64_t i = 0; i < cnt_; ++i) { + if (OB_ISNULL(sstable_array_[i])) { + len = 0; + LOG_ERROR_RET(OB_ERR_UNEXPECTED, "unexpected null pointer for sstable array", KPC(this), K(i), K_(cnt)); + break; + } else { + len += sstable_array_[i]->get_deep_copy_size(); } } return len; } -int ObExtendTableArray::deserialize( - ObIAllocator &allocator, - const char *buf, - const int64_t data_len, - int64_t &pos) +int ObSSTableArray::deep_copy( + char *dst_buf, + const int64_t buf_size, + int64_t &pos, + ObSSTableArray &dst_array) const { int ret = OB_SUCCESS; - int64_t count = 0; - - if (OB_UNLIKELY(count_ <= 0)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ObExtendTableArray should alloc memory for array before deserializing", K(ret), K(*this)); - } else if (OB_UNLIKELY(NULL == buf || data_len <= 0 || pos < 0)) { + const int64_t memory_size = get_deep_copy_size(); + if (OB_ISNULL(dst_buf) || OB_UNLIKELY(buf_size - pos < memory_size)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid arguments.", K(ret), KP(buf), K(data_len), K(pos)); - } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &count))) { - LOG_WARN("failed to decode count_", K(ret)); + LOG_WARN("invalue argument", K(ret), KP(dst_buf), K(buf_size), K(pos), K_(cnt), K(memory_size)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < count && pos < data_len; ++i) { - ObTableHandleV2 table_handle; - ObSSTable *sstable = nullptr; - if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->acquire_sstable(table_handle, allocator))) { - LOG_WARN("failed to acquire sstable from meta_mem_mgr", K(ret)); - } else if (OB_ISNULL(sstable = static_cast(table_handle.get_table()))) { + dst_array.cnt_ = cnt_; + dst_array.sstable_array_ = 0 == cnt_ ? nullptr : reinterpret_cast(dst_buf + pos); + const int64_t array_size = cnt_ * sizeof(ObSSTable *); + pos += array_size; + for (int64_t i = 0; OB_SUCC(ret) && i < cnt_; ++i) { + int64_t sstable_copy_size = 0; + ObIStorageMetaObj *new_sstable = nullptr; + char *sstable_copy_buf = dst_buf + pos; + if (OB_ISNULL(sstable_array_[i])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, sstable is nullptr", K(ret), K(table_handle)); - } else if (OB_FAIL(sstable->deserialize(allocator, buf, data_len, pos))) { - LOG_WARN("failed to deserialize sstable", K(ret)); - } else if (table_handle.get_table()->is_meta_major_sstable()) { - if (OB_FAIL(assign(ObTabletTableStore::META_MAJOR, table_handle.get_table()))) { - LOG_WARN("failed to add meta major table", K(ret)); + LOG_WARN("unexpected null sstable pointer", K(ret), KPC(this), K(i)); + } else if (FALSE_IT(sstable_copy_size = sstable_array_[i]->get_deep_copy_size())) { + } else if (OB_FAIL(sstable_array_[i]->deep_copy(sstable_copy_buf, buf_size - pos, new_sstable))) { + LOG_WARN("fail to deep copy sstable addr", K(ret)); + } else { + dst_array.sstable_array_[i] = static_cast(new_sstable); + pos += sstable_copy_size; + } + } + if (OB_SUCC(ret)) { + dst_array.is_inited_ = is_inited_; + } + } + return ret; +} + +ObSSTable *ObSSTableArray::operator[](const int64_t pos) const +{ + return at(pos); +} + +blocksstable::ObSSTable *ObSSTableArray::at(const int64_t pos) const +{ + ObSSTable *sstable = nullptr; + if (!is_valid() || pos >= cnt_ || pos < 0) { + sstable = nullptr; + } else { + sstable = sstable_array_[pos]; + } + return sstable; +} + +ObITable *ObSSTableArray::get_boundary_table(const bool is_last) const +{ + ObSSTable *sstable = nullptr; + if (!is_valid() || 0 == cnt_) { + sstable = nullptr; + } else { + sstable = is_last ? sstable_array_[cnt_ - 1] : sstable_array_[0]; + } + return sstable; +} + +int ObSSTableArray::get_all_tables(ObIArray &tables) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < cnt_; ++i) { + if (OB_FAIL(tables.push_back(sstable_array_[i]))) { + LOG_WARN("fail to push sstable address into array", K(ret), K(i), K(tables)); + } + } + } + return ret; +} + +int ObSSTableArray::get_table(const ObITable::TableKey &table_key, ObITable *&table) const +{ + int ret = OB_SUCCESS; + table = nullptr; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(table_key)); + } else if (OB_UNLIKELY(!table_key.is_valid() || table_key.is_memtable())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table key", K(ret), K(table_key)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < cnt_; ++i) { + if (OB_ISNULL(sstable_array_[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null sstable pointer", K(ret), KPC(this)); + } else if (table_key == sstable_array_[i]->get_key()) { + table = sstable_array_[i]; + break; + } + } + } + return ret; +} + +int ObSSTableArray::inc_macro_ref(bool &is_success) const +{ + int ret = OB_SUCCESS; + is_success = false; + bool inc_data_success = false; + bool inc_meta_success = false; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(inc_data_ref_cnt(inc_data_success))) { + LOG_WARN("fail to increase sstables' data ref cnt", K(ret)); + } else if (OB_FAIL(inc_meta_ref_cnt(inc_meta_success))) { + LOG_WARN("fail to increase sstables' meta ref cnt", K(ret)); + } + + if (OB_FAIL(ret)) { + if (inc_data_success) { + dec_data_ref_cnt(); + } + if (inc_meta_success) { + dec_meta_ref_cnt(); + } + } else { + is_success = true; + } + return ret; +} + +void ObSSTableArray::dec_macro_ref() const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else { + dec_data_ref_cnt(); + dec_meta_ref_cnt(); + } +} + +int ObSSTableArray::inc_meta_ref_cnt(bool &inc_success) const +{ + int ret = OB_SUCCESS; + inc_success = false; + ObITable *table = nullptr; + int64_t sstable_cnt = 0; + ObMetaDiskAddr addr; + MacroBlockId macro_id; + int64_t offset = 0; + int64_t size = 0; + + for (int64_t i = 0; OB_SUCC(ret) && i < cnt_; i++) { + table = sstable_array_[i]; + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("table is invalid", K(ret), KPC(table)); + // shouldn't abort after being merged into master !!! + ob_abort(); + } else { + ObSSTable *sstable = reinterpret_cast(table); + addr = sstable->get_addr(); + if (addr.is_memory()) { + // full/old tablet, skip increase + sstable_cnt++; + } else if (OB_UNLIKELY(!addr.is_block() || !addr.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("addr is invalid", K(ret), K(addr)); + } else if (OB_FAIL(addr.get_block_addr(macro_id, offset, size))) { + LOG_WARN("fail to get macro id from addr", K(ret), K(addr)); + } else if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(macro_id))) { + LOG_ERROR("fail to increase ref cnt for sstable meta's macro block", K(ret), K(macro_id)); + } else { + sstable_cnt++; + FLOG_INFO("barry debug inc sstable meta's macro ref", K(ret), K(macro_id), KPC(sstable)); + } + } + } + + if (OB_FAIL(ret) && 0 != sstable_cnt) { + int tmp_ret = OB_SUCCESS; + for (int64_t i = 0; i < sstable_cnt; i++) { + table = sstable_array_[i]; + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { + tmp_ret = OB_ERR_UNEXPECTED; + LOG_ERROR("table is invalid", K(tmp_ret), KPC(table)); + } else { + ObSSTable *sstable = reinterpret_cast(table); + addr = sstable->get_addr(); + if (addr.is_memory()) { + // full/old tablet, skip increase + } else if (OB_UNLIKELY(!addr.is_block() || !addr.is_valid())) { + tmp_ret = OB_ERR_UNEXPECTED; + LOG_ERROR("addr is invalid", K(tmp_ret), K(addr)); + } else if (OB_TMP_FAIL(addr.get_block_addr(macro_id, offset, size))) { + LOG_ERROR("fail to get macro id from addr", K(tmp_ret), K(addr)); + } else if (OB_TMP_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to decrease ref cnt for sstable meta's macro block", K(tmp_ret), K(macro_id)); + } else { + FLOG_INFO("barry debug decrease sstable meta's macro ref", K(tmp_ret), K(addr), K(macro_id), KPC(sstable)); } } } } + + if (OB_SUCC(ret)) { + inc_success = true; + } + + FLOG_INFO("barry debug the number of sstables that increase meta ref cnt", K(ret), K(sstable_cnt), K(lbt())); + return ret; } - -ObMemtableArray::ObMemtableArray() - : meta_mem_mgr_(nullptr), - allocator_(nullptr), - array_(nullptr), - is_inited_(false) +int ObSSTableArray::inc_data_ref_cnt(bool &inc_success) const { -} + int ret = OB_SUCCESS; + inc_success = false; + ObITable *table = nullptr; + int64_t sstable_cnt = 0; -ObMemtableArray::~ObMemtableArray() -{ - destroy(); -} + for (int64_t i = 0; OB_SUCC(ret) && i < cnt_; i++) { + bool inc_data_block_success = false; + table = sstable_array_[i]; + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("table is invalid", K(ret), KPC(table)); + // shouldn't abort after being merged into master !!! + ob_abort(); + } else { + ObSSTable *sstable = reinterpret_cast(table); + if (OB_FAIL(sstable->inc_macro_ref(inc_data_block_success))) { + LOG_WARN("fail to increase ref cnt for sstable", K(ret), KPC(sstable), K(inc_data_block_success)); + } else { + sstable_cnt++; + } + LOG_DEBUG("barry debug increase sstable data macro ref", K(ret), KPC(sstable)); + } + } -void ObMemtableArray::destroy() -{ - if (OB_ISNULL(allocator_) || OB_ISNULL(array_)) { - // do nothing - } else { - ObITable *table = nullptr; - for (int64_t i = 0; i < count(); ++i) { - if (OB_NOT_NULL(table = array_->at(i))) { - reset_table(i); + if (OB_FAIL(ret) && 0 != sstable_cnt) { + int tmp_ret = OB_SUCCESS; + for (int64_t i = 0; i < sstable_cnt; i++) { + table = sstable_array_[i]; + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { + tmp_ret = OB_ERR_UNEXPECTED; + LOG_ERROR("table is invalid", K(tmp_ret), KPC(table)); + // shouldn't abort after being merged into master !!! + ob_abort(); + } else { + ObSSTable *sstable = reinterpret_cast(table); + sstable->dec_macro_ref(); + LOG_DEBUG("barry debug decrease sstable data macro ref", K(tmp_ret), KPC(sstable)); } } - array_->~ObSEArray(); - allocator_->free(array_); } - meta_mem_mgr_ = nullptr; - allocator_ = nullptr; - array_ = nullptr; - is_inited_ = false; -} - -int ObMemtableArray::init(common::ObIAllocator *allocator) -{ - int ret = OB_SUCCESS; - char *buf = nullptr; - const int64_t alloc_size = sizeof(ObSEArray); - - if (IS_INIT) { - ret = OB_INIT_TWICE; - LOG_WARN("ObMemtableArray has been inited", K(ret), KPC(this)); - } else if (OB_UNLIKELY(NULL == allocator)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid arguments", K(ret), K(allocator)); - } else if (OB_ISNULL(meta_mem_mgr_ = MTL(ObTenantMetaMemMgr *))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get meta mem mgr from MTL", K(ret)); - } else if (FALSE_IT(allocator_ = allocator)) { - } else if (OB_ISNULL(buf = static_cast(allocator_->alloc(alloc_size)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("failed to allocate mem for buf", K(ret)); - } else { - array_ = new (buf) ObSEArray(OB_MALLOC_NORMAL_BLOCK_SIZE, *allocator_); - is_inited_ = true; + if (OB_SUCC(ret)) { + inc_success = true; } + return ret; } -int ObMemtableArray::init( - common::ObIAllocator *allocator, - const ObMemtableArray &other) +void ObSSTableArray::dec_meta_ref_cnt() const { int ret = OB_SUCCESS; - if (IS_INIT) { - ret = OB_INIT_TWICE; - LOG_WARN("ObMemtableArray has been inited", K(ret), KPC(this)); - } else if (OB_FAIL(init(allocator))) { - LOG_WARN("failed to init ObMemtableArray", K(ret)); - } else if (meta_mem_mgr_ != other.meta_mem_mgr_) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("meta mem mgr must be same", K(ret), K(meta_mem_mgr_), K(other.meta_mem_mgr_)); - } - ObITable *table = nullptr; - for (int64_t i = 0; OB_SUCC(ret) && i < other.count(); ++i) { - table = other.get_table(i); - if (OB_UNLIKELY(nullptr == table || !table->is_memtable())) { + ObMetaDiskAddr addr; + MacroBlockId macro_id; + int64_t offset = 0; + int64_t size = 0; + int64_t sstable_cnt = 0; + + for (int64_t i = 0; i < cnt_; i++) { + table = sstable_array_[i]; + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("table must be memtable", K(ret), K(i), KPC(table)); - } else if (OB_FAIL(add_table(table))) { - LOG_WARN("failed to add to memtables", K(ret)); + LOG_ERROR("table is invalid", K(ret), KPC(table)); + // shouldn't abort after being merged into master !!! + ob_abort(); + } else { + ObSSTable *sstable = reinterpret_cast(table); + addr = sstable->get_addr(); + if (addr.is_memory()) { + // full/old tablet, skip decrease + } else if (OB_UNLIKELY(!addr.is_block() || !addr.is_valid())) { + LOG_ERROR("addr is invalid", K(ret), K(addr)); + } else if (OB_FAIL(addr.get_block_addr(macro_id, offset, size))) { + LOG_ERROR("fail to get macro id from addr", K(ret), K(addr)); + } else if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to decrease ref cnt for sstable meta's macro block", K(ret), K(macro_id)); + } else { + sstable_cnt++; + FLOG_INFO("barry debug decrease sstable meta's macro ref", K(ret), K(macro_id), KPC(sstable)); + } } } - if (OB_FAIL(ret)) { - destroy(); + + FLOG_INFO("barry debug the number of sstables that decrease meta ref cnt", K(ret), K(sstable_cnt), K(lbt())); +} + +void ObSSTableArray::dec_data_ref_cnt() const +{ + int ret = OB_SUCCESS; + ObITable *table = nullptr; + int64_t sstable_cnt = 0; + + for (int64_t i = 0; i < cnt_; i++) { + table = sstable_array_[i]; + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("table is invalid", K(ret), KPC(table)); + // shouldn't abort after being merged into master !!! + ob_abort(); + } else { + sstable_cnt++; + ObSSTable *sstable = reinterpret_cast(table); + sstable->dec_macro_ref(); + LOG_DEBUG("barry debug decrease sstable data's macro ref", K(ret), KPC(sstable)); + } + } +} + +int ObMemtableArray::assign(ObMemtableArray &dst_array) const +{ + int ret = OB_SUCCESS; + dst_array.count_ = count_; + for (int64_t i = 0; i < MEMTABLE_ARRAY_SIZE; ++i) { + dst_array.memtable_array_[i] = memtable_array_[i]; } return ret; } int ObMemtableArray::build( - common::ObIArray &handle_array, + common::ObIArray &table_array, const int64_t start_pos) { int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("ObMemtableArray not inited", K(ret), KPC(this)); - } else if (start_pos < 0 || start_pos >= handle_array.count()) { + if (OB_UNLIKELY(0 != count_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable array is not empry", K(ret)); + } else if (OB_UNLIKELY(start_pos < 0 || start_pos >= table_array.count())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid arguments", K(ret), K(start_pos), K(handle_array)); + LOG_WARN("get invalid arguments", K(ret), K(start_pos), K(table_array)); } ObITable *table = nullptr; - for (int64_t i = start_pos; OB_SUCC(ret) && i < handle_array.count(); ++i) { + for (int64_t i = start_pos; OB_SUCC(ret) && i < table_array.count(); ++i) { memtable::ObMemtable *memtable = nullptr; - table = handle_array.at(i).get_table(); + table = table_array.at(i); if (OB_UNLIKELY(nullptr == table || !table->is_memtable())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table must be memtable", K(ret), K(i), KPC(table)); } else if (FALSE_IT(memtable = reinterpret_cast(table))) { } else if (memtable->is_empty()) { - FLOG_INFO("Empty memtable discarded", KPC(memtable)); - } else if (OB_FAIL(add_table(table))) { - LOG_WARN("failed to add to memtables", K(ret)); + FLOG_INFO("empty memtable discarded", KPC(memtable)); + } else if (OB_UNLIKELY(count_ == MEMTABLE_ARRAY_SIZE)) { + ret = OB_ARRAY_OUT_OF_RANGE; + LOG_WARN("too many elements for memtable array", K(ret)); + } else { + memtable_array_[count_] = memtable; + ++count_; } } + if (OB_FAIL(ret)) { - destroy(); + count_ = 0; } return ret; } -int ObMemtableArray::rebuild(common::ObIArray &handle_array) +int ObMemtableArray::rebuild(const common::ObIArray &table_array) { int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_ERROR("ObMemtableArray not inited", K(ret), KPC(this), K(handle_array)); + if (OB_FAIL(trim_empty_last_memtable())) { + LOG_WARN("failed to trim empty last memtable", K(ret)); } else { - ObITable *last_memtable = get_table(count() - 1); - SCN end_scn = (NULL == last_memtable) ? SCN::min_scn() : last_memtable->get_end_scn(); + const memtable::ObMemtable *last_memtable = count_ > 0 ? memtable_array_[count_ - 1] : nullptr; + const share::SCN endscn = (NULL == last_memtable) ? share::SCN::min_scn() : last_memtable->get_end_scn(); - for (int64_t i = 0; OB_SUCC(ret) && i < handle_array.count(); ++i) { + for (int64_t i = 0; OB_SUCC(ret) && i < table_array.count(); ++i) { memtable::ObMemtable *memtable = nullptr; - ObITable *table = handle_array.at(i).get_table(); + ObITable *table = table_array.at(i); if (OB_UNLIKELY(nullptr == table || !table->is_memtable())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table must be memtable", K(ret), K(i), KPC(table)); } else if (FALSE_IT(memtable = static_cast(table))) { } else if (memtable->is_empty()) { FLOG_INFO("Empty memtable discarded", KPC(memtable)); - } else if (table->get_end_scn() < end_scn) { - } else if (table->get_end_scn() == end_scn && table == last_memtable) { //fix issue 41996395 - } else if (OB_FAIL(add_table(table))) { - LOG_WARN("failed to add memtable to curr memtables", K(ret), KPC(this)); + } else if (table->get_end_scn() < endscn) { + } else if (table->get_end_scn() == endscn && memtable == last_memtable) { //fix issue 41996395 + } else if (OB_UNLIKELY(count_ == MEMTABLE_ARRAY_SIZE)) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("too many elements for memtable array", K(ret)); + } else { + memtable_array_[count_] = memtable; + ++count_; } } } + return ret; } int ObMemtableArray::rebuild( const share::SCN &clog_checkpoint_scn, - common::ObIArray &handle_array) + common::ObIArray &table_array) { int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_ERROR("ObMemtableArray not inited", K(ret), KPC(this), K(handle_array)); - } else if (OB_UNLIKELY(!empty())) { + if (OB_UNLIKELY(!empty())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("current memtable array is not empty", K(ret), K(clog_checkpoint_scn), KPC(this)); } else { - // use clog checkpoint scn to filter memtable handle array - for (int64_t i = 0; OB_SUCC(ret) && i < handle_array.count(); ++i) { + // use clog checkpoint scn to filter memtable array + for (int64_t i = 0; OB_SUCC(ret) && i < table_array.count(); ++i) { memtable::ObMemtable *memtable = nullptr; - ObITable *table = handle_array.at(i).get_table(); + ObITable *table = table_array.at(i); if (OB_UNLIKELY(nullptr == table || !table->is_memtable())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table must be memtable", K(ret), K(i), KPC(table)); @@ -640,62 +729,42 @@ int ObMemtableArray::rebuild( } else if (table->get_end_scn() <= clog_checkpoint_scn) { FLOG_INFO("memtable end scn no greater than clog checkpoint scn, should be discarded", K(ret), "end_scn", table->get_end_scn(), K(clog_checkpoint_scn)); - } else if (OB_FAIL(add_table(table))) { - LOG_WARN("failed to add memtable to curr memtables", K(ret), KPC(this)); + } else if (OB_UNLIKELY(count_ == MEMTABLE_ARRAY_SIZE)) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("too many elements for memtable array", K(ret)); + } else { + memtable_array_[count_] = memtable; + ++count_; } } } return ret; } -int ObMemtableArray::prepare_allocate() +int ObMemtableArray::find(const ObITable::TableKey &table_key, ObITable *&table) const { int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("ObMemtableArray not inited", K(ret), KPC(this)); - } else { - int64_t cur_capacity = array_->get_capacity(); - int64_t cur_count = array_->count(); - if (cur_capacity > cur_count) { - } else if (OB_FAIL(array_->reserve(cur_capacity * 2))) { - LOG_WARN("failed to realloc memory for ObMemtableArray", K(ret), KPC(this)); - } - } - return ret; -} + table = nullptr; -int ObMemtableArray::find( - const ObITable::TableKey &table_key, - ObTableHandleV2 &handle) const -{ - int ret = OB_SUCCESS; - handle.reset(); - - if (empty()) { + if (0 == count_) { } else if (OB_UNLIKELY(!table_key.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), K(table_key)); } - ObITable *table = nullptr; - for (int64_t i = 0; OB_SUCC(ret) && i < count(); ++i) { - if (OB_ISNULL(get_table(i))) { - } else if (table_key == get_table(i)->get_key()) { - table = get_table(i); + for (int64_t i = 0; OB_SUCC(ret) && i < count_; ++i) { + if (OB_ISNULL(memtable_array_[i])) { + } else if (table_key == memtable_array_[i]->get_key()) { + table = memtable_array_[i]; break; } } - if (OB_SUCC(ret) && OB_NOT_NULL(table)) { - if (OB_FAIL(handle.set_table(table, meta_mem_mgr_, table->get_key().table_type_))) { - LOG_WARN("failed to set table handle", K(ret)); - } - } + return ret; } int ObMemtableArray::find( - const SCN &start_scn, + const share::SCN &start_scn, const int64_t base_version, ObITable *&table, int64_t &mem_pos) const @@ -704,18 +773,18 @@ int ObMemtableArray::find( mem_pos = -1; table = nullptr; - if (OB_UNLIKELY(empty())) { + if (OB_UNLIKELY(0 == count_)) { ret = OB_ENTRY_NOT_EXIST; LOG_WARN("no memtable", K(ret), KPC(this)); } else if (OB_UNLIKELY(!start_scn.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid arguments", K(ret), K(start_scn), K(base_version)); - } else if (SCN::min_scn() == start_scn) { + } else if (share::SCN::min_scn() == start_scn) { mem_pos = 0; - table = get_table(0); + table = memtable_array_[0]; } else { - for (int64_t i = 0; OB_SUCC(ret) && i < count(); ++i) { - ObITable * memtable = get_table(i); + for (int64_t i = 0; OB_SUCC(ret) && i < count_; ++i) { + ObITable *memtable = memtable_array_[i]; if (OB_ISNULL(memtable)) { ret = OB_ERR_SYS; LOG_WARN("table must not null", K(ret), KPC(memtable), KPC(this)); @@ -735,287 +804,44 @@ int ObMemtableArray::find( return ret; } -int ObMemtableArray::add_table(ObITable * const table) +int ObMemtableArray::trim_empty_last_memtable() { + // trim last memtable if it is empty since right boundary of memtable could be refine asynchronuously int ret = OB_SUCCESS; - ObTenantMetaMemMgr *meta_mem_mgr = nullptr; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("ObMemtableArray not inited", K(ret), KPC(this)); - } else if (OB_ISNULL(table)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid argument", K(ret), KPC(table)); - } else if (FALSE_IT(meta_mem_mgr = MTL(ObTenantMetaMemMgr *))) { - } else if (meta_mem_mgr_ != meta_mem_mgr) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("meta mem mgr is unexpected not equal!", K(ret), K(meta_mem_mgr_), K(meta_mem_mgr)); - } else if (OB_FAIL(array_->push_back(table))) { - LOG_WARN("failed to add table", K(ret)); - } else { - table->inc_ref(); + const int64_t last_memtable_idx = count_ - 1; + if (0 == count_) { + // skip + } else if (memtable_array_[last_memtable_idx]->is_empty()) { + LOG_INFO("trim empty last memtable", K(ret), K(memtable_array_[last_memtable_idx])); + memtable_array_[last_memtable_idx] = nullptr; + count_--; } return ret; } -void ObMemtableArray::reset_table(const int64_t pos) -{ - ObITable *table = nullptr; - - if (pos < 0 || pos >= count()) { // do nothing - } else if (OB_ISNULL(table = get_table(pos))) { - } else if (OB_ISNULL(meta_mem_mgr_)) { - LOG_ERROR_RET(OB_ERR_UNEXPECTED, "[MEMORY LEAK] TenantMetaMemMgr is unexpected not equal!!!", K(meta_mem_mgr_), KPC(table)); - } else if (0 == table->dec_ref()) { - meta_mem_mgr_->push_table_into_gc_queue(table, table->get_key().table_type_); - } -} - - -/* ObTableStoreIterator Section */ -ObTableStoreIterator::ObTableStoreIterator(const bool reverse_iter) - : array_(), - pos_(INT64_MAX), - memstore_retired_(nullptr) -{ - step_ = reverse_iter ? -1 : 1; -} - -ObTableStoreIterator::~ObTableStoreIterator() -{ - reset(); -} - -void ObTableStoreIterator::reset() -{ - array_.reset(); - pos_ = INT64_MAX; - memstore_retired_ = nullptr; -} - -void ObTableStoreIterator::resume() -{ - pos_ = step_ < 0 ? array_.count() - 1 : 0; -} - -ObITable *ObTableStoreIterator::get_boundary_table(const bool is_last) -{ - ObITable *table = nullptr; - if (!is_valid()) { - } else if (is_last) { - table = step_ > 0 ? array_.at(array_.count() - 1) : array_.at(0); - } else { - table = step_ < 0 ? array_.at(array_.count() - 1) : array_.at(0); - } - return table; -} - -int ObTableStoreIterator::copy(const ObTableStoreIterator &other) -{ - int ret = OB_SUCCESS; - if (!other.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid argument", K(ret), K(other)); - } else if (OB_FAIL(array_.assign(other.array_))) { - LOG_WARN("failed to copy array", K(ret)); - } else { - memstore_retired_ = other.memstore_retired_; - } - return ret; -} - -int ObTableStoreIterator::add_tables(ObMemtableArray &array, const int64_t start_pos) -{ - int ret = OB_SUCCESS; - if (start_pos < 0 || start_pos >= array.count()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid arguments", K(ret), K(start_pos)); - } - - for (int64_t i = start_pos; OB_SUCC(ret) && i < array.count(); ++i) { - ObITable *cur = array[i]; - if (OB_ISNULL(cur)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected null table", K(ret), K(i), K(cur)); - } else if (OB_FAIL(array_.push_back(cur))) { - LOG_WARN("failed to add table to iterator", K(ret)); - } - } - return ret; -} - -int ObTableStoreIterator::add_tables(ObITable **start, const int64_t count) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(start) || count <= 0) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid arguments", K(ret), K(start), K(count)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { - ObITable **cur = start + i; - if (OB_ISNULL(*cur)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected null table", K(ret), K(start), K(i), K(cur), K(count)); - } else if (OB_FAIL(array_.push_back(*cur))) { - LOG_WARN("failed to add table to iterator", K(ret)); - } - } - } - return ret; -} - -int ObTableStoreIterator::add_table(ObITable *input_table) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(input_table)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), KP(input_table)); - } else if (OB_FAIL(array_.push_back(input_table))) { - LOG_WARN("failed to add table to iterator", K(ret), KP(input_table)); - } - return ret; -} - -int ObTableStoreIterator::get_next(ObITable *&table) -{ - int ret = OB_SUCCESS; - table = nullptr; - if (0 == array_.count()) { - ret = OB_ITER_END; - } else if (INT64_MAX == pos_) { - pos_ = (-1 == step_) ? array_.count() - 1 : 0; - } else if (pos_ >= array_.count() || pos_ < 0) { - ret = OB_ITER_END; - } - - if (OB_FAIL(ret)) { - } else if (OB_ISNULL(array_.at(pos_))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("iter unexpected null table", K(ret), K(*this)); - } else { - table = array_.at(pos_); - pos_ += step_; - } - return ret; -} - -int ObTableStoreIterator::set_retire_check() -{ - int ret = OB_SUCCESS; - memstore_retired_ = nullptr; - ObITable *first_memtable = nullptr; - - for (int64_t i = array_.count() - 1; OB_SUCC(ret) && i >= 0; --i) { - if (OB_ISNULL(array_.at(i))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table must not null", K(ret), K(*this)); - } else if (array_.at(i)->is_data_memtable()) { - first_memtable = array_.at(i); - } else { - break; - } - } - - if (OB_SUCC(ret) && OB_NOT_NULL(first_memtable)) { - memtable::ObMemtable *memtable = static_cast(first_memtable); - memstore_retired_ = &memtable->get_read_barrier(); - } - return ret; -} - -/* ObPrintTableStoreIterator Section */ -ObPrintTableStoreIterator::ObPrintTableStoreIterator(const ObTableStoreIterator &iter) - : array_(iter.array_), - pos_(iter.pos_), - step_(iter.step_), - memstore_retired_(iter.memstore_retired_) -{ -} - -ObPrintTableStoreIterator::~ObPrintTableStoreIterator() -{ -} - -int64_t ObPrintTableStoreIterator::to_string(char *buf, const int64_t buf_len) const +int64_t ObMemtableArray::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; if (OB_ISNULL(buf) || buf_len <= 0) { // do nothing } else { J_OBJ_START(); - J_NAME("ObTableStoreIterator_Pretty"); - J_COLON(); - J_KV(KP(this), K_(array), K_(pos), K_(step), K_(memstore_retired)); - J_COMMA(); - BUF_PRINTF("iter array"); - J_COLON(); - J_OBJ_START(); - if (array_.count() > 0) { - ObCurTraceId::TraceId *trace_id = ObCurTraceId::get_trace_id(); - J_NEWLINE(); - BUF_PRINTF("[%ld] [ ", GETTID()); - BUF_PRINTO(PC(trace_id)); - BUF_PRINTF(" ] "); - BUF_PRINTF(" %-10s %-19s %-19s %-19s %-19s %-19s %-4s %-16s \n", - "table_type", "table_addr", "upper_trans_ver", "max_merge_ver", - "start_scn", "end_scn", "ref", "uncommit_row"); - for (int64_t i = 0; i < array_.count(); ++i) { - if (i > 0) { - J_NEWLINE(); - } - ObITable *table = array_.at(i); - table_to_string(table, buf, buf_len, pos); - } - } else { - J_EMPTY_OBJ(); - } - J_OBJ_END(); + J_NAME("ObMemtableArray"); + J_KV(KP(this), + K_(count), + "memtable_ptr_array", ObArrayWrap(memtable_array_, count_)); J_OBJ_END(); } return pos; } -void ObPrintTableStoreIterator::table_to_string( - ObITable *table, - char *buf, - const int64_t buf_len, - int64_t &pos) const -{ - if (nullptr != table) { - ObCurTraceId::TraceId *trace_id = ObCurTraceId::get_trace_id(); - BUF_PRINTF("[%ld] [ ", GETTID()); - BUF_PRINTO(PC(trace_id)); - BUF_PRINTF(" ] "); - const char* table_name = table->is_sstable() - ? ObITable::get_table_type_name(table->get_key().table_type_) - : (table->is_active_memtable() ? "ACTIVE" : "FROZEN"); - const char * uncommit_row = table->is_sstable() - ? (static_cast(table)->get_meta().get_basic_meta().contain_uncommitted_row_ ? "true" : "false") - : "unused"; - - BUF_PRINTF(" %-10s %-19p %-19lu %-19lu %-19s %-19s %-4ld %-16s ", - table_name, - reinterpret_cast(table), - table->get_upper_trans_version(), - table->get_max_merged_trans_version(), - to_cstring(table->get_start_scn()), - to_cstring(table->get_end_scn()), - table->get_ref(), - uncommit_row); - } else { - BUF_PRINTF(" %-10s %-19s %-10s %-19s %-19s %-19s %-19s %-4s %-16s \n", - "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL"); - } -} - - /* ObTableStoreUtil Section */ bool ObTableStoreUtil::ObITableLogTsRangeCompare::operator()( const ObITable *ltable, const ObITable *rtable) const { bool bret = false; if (OB_SUCCESS != result_code_) { - } else if (OB_SUCCESS != (result_code_ = compare_table_by_scn_range(ltable, rtable, bret))) { + } else if (OB_SUCCESS != (result_code_ = compare_table_by_scn_range(ltable, rtable, true/*is_ascend*/, bret))) { LOG_WARN_RET(result_code_, "failed to compare table with LogTsRange", K(result_code_), KPC(ltable), KPC(rtable)); } return bret; @@ -1040,13 +866,27 @@ bool ObTableStoreUtil::ObTableHandleV2LogTsRangeCompare::operator()( } else { const ObITable *ltable = lhandle.get_table(); const ObITable *rtable = rhandle.get_table(); - if (OB_SUCCESS != (result_code_ = compare_table_by_scn_range(ltable, rtable, bret))) { + if (OB_SUCCESS != (result_code_ = compare_table_by_scn_range(ltable, rtable, true/*is_ascend*/, bret))) { LOG_WARN_RET(result_code_, "failed to compare table with LogTsRange", K(result_code_), KPC(ltable), KPC(rtable)); } } return bret; } +bool ObTableStoreUtil::ObTableHandleV2LogTsRangeReverseCompare::operator()( + const ObTableHandleV2 &lhandle, const ObTableHandleV2 &rhandle) const +{ + bool bret = false; + if (OB_SUCCESS != result_code_) { + } else { + const ObITable *ltable = lhandle.get_table(); + const ObITable *rtable = rhandle.get_table(); + if (OB_SUCCESS != (result_code_ = compare_table_by_scn_range(ltable, rtable, false/*is_ascend*/, bret))) { + LOG_WARN_RET(result_code_, "failed to compare table with LogTsRange", K(result_code_), KPC(ltable), KPC(rtable)); + } + } + return bret; +} bool ObTableStoreUtil::ObTableHandleV2SnapshotVersionCompare::operator()( const ObTableHandleV2 &lhandle, const ObTableHandleV2 &rhandle) const @@ -1065,7 +905,7 @@ bool ObTableStoreUtil::ObTableHandleV2SnapshotVersionCompare::operator()( } -int ObTableStoreUtil::compare_table_by_scn_range(const ObITable *ltable, const ObITable *rtable, bool &bret) +int ObTableStoreUtil::compare_table_by_scn_range(const ObITable *ltable, const ObITable *rtable, const bool is_ascend, bool &bret) { int ret = OB_SUCCESS; bret = false; @@ -1087,8 +927,11 @@ int ObTableStoreUtil::compare_table_by_scn_range(const ObITable *ltable, const O bret = true; ret = OB_ERR_UNEXPECTED; LOG_ERROR("table end log ts shouldn't be equal", KPC(ltable), KPC(rtable)); - } else { // log ts not equal + } else if (is_ascend) { + // log ts not equal bret = ltable->get_end_scn() < rtable->get_end_scn(); + } else { + bret = ltable->get_end_scn() > rtable->get_end_scn(); } return ret; } @@ -1146,6 +989,23 @@ int ObTableStoreUtil::sort_minor_tables(ObArray &tables) return ret; } +int ObTableStoreUtil::reverse_sort_minor_table_handles(ObArray &table_handles) +{ + int ret = OB_SUCCESS; + + if (table_handles.empty()) { + // no need sort + } else { + // There is an assumption: either all tables are with scn range, or none + ObTableHandleV2LogTsRangeReverseCompare comp(ret); + std::sort(table_handles.begin(), table_handles.end(), comp); + if (OB_FAIL(ret)) { + LOG_ERROR("failed to sort tables", K(ret), K(table_handles)); + } + } + return ret; +} + bool ObTableStoreUtil::check_include_by_scn_range(const ObITable &a, const ObITable &b) { bool bret = false; diff --git a/src/storage/tablet/ob_table_store_util.h b/src/storage/tablet/ob_table_store_util.h old mode 100644 new mode 100755 index a19aa6fb0..1011093ab --- a/src/storage/tablet/ob_table_store_util.h +++ b/src/storage/tablet/ob_table_store_util.h @@ -27,168 +27,101 @@ namespace storage class ObTabletTableStore; class ObTabletTablesSet; class ObTenantMetaMemMgr; +class ObITableArray; -// TODO maybe need 2-d array to store ObSSTableArray, ObMemtableArray, ObExtendArray -class ObITableArray +class ObSSTableArray { public: - ObITableArray(); - virtual ~ObITableArray(); + friend class ObTabletTableStore; + ObSSTableArray() : cnt_(0), sstable_array_(nullptr), is_inited_(false) {} + virtual ~ObSSTableArray() {} - int init(common::ObIAllocator &allocator, const int64_t count); - int copy(common::ObIAllocator &allocator, const ObITableArray &other, const bool allow_empty_table = false); - int init_and_copy( - common::ObIAllocator &allocator, - const common::ObIArray &tables, - const int64_t start_pos = 0); - bool empty() const { return count_ <= 0; } - bool is_valid() const { return is_inited_ && count_ > 0; } - int64_t count() const { return count_; } - virtual void destroy(); + void reset(); + int init( + ObArenaAllocator &allocator, + const ObIArray &tables, + const int64_t start_pos = 0); + int init(ObArenaAllocator &allocator, const blocksstable::ObSSTable *sstable); + int init( + ObArenaAllocator &allocator, + const ObIArray &tables, + const ObIArray &addrs, + const int64_t start_pos, + const int64_t count); + int init( + ObArenaAllocator &allocator, + const ObSSTableArray &other); + int64_t get_deep_copy_size() const; + int deep_copy(char *dst_buf, const int64_t buf_size, int64_t &pos, ObSSTableArray &dst_array) const; - int assign(const int64_t pos, ObITable * const table); - void reset_table(const int64_t pos); + int64_t get_serialize_size() const; + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize(ObArenaAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos); + blocksstable::ObSSTable *operator[](const int64_t pos) const; + blocksstable::ObSSTable *at(const int64_t pos) const; + ObITable *get_boundary_table(const bool is_last) const; + int get_all_tables(ObIArray &tables) const; + int get_table(const ObITable::TableKey &table_key, ObITable *&table) const; + int inc_macro_ref(bool &is_success) const; + void dec_macro_ref() const; - virtual int get_all_tables(common::ObIArray &tables) const; - virtual int get_all_tables(storage::ObTablesHandleArray &tables) const; - virtual ObITable *get_boundary_table(const bool last) const; - int get_table(const ObITable::TableKey &table_key, ObTableHandleV2 &handle) const; - OB_INLINE ObITable *get_table(const int64_t pos) const { return (pos < count_ && pos >= 0) ? array_[pos] : nullptr; } - OB_INLINE ObITable *operator[](const int64_t pos) const { return (pos < count_ && pos >= 0) ? array_[pos] : nullptr; } - VIRTUAL_TO_STRING_KV(K_(is_inited), K_(count), KP_(array)); - -public: - storage::ObTenantMetaMemMgr* meta_mem_mgr_; - ObITable **array_; - common::ObIAllocator *allocator_; - int64_t count_; + OB_INLINE bool is_valid() const + { + return 0 == cnt_ || (is_inited_ && cnt_ > 0 && nullptr != sstable_array_); + } + OB_INLINE int64_t count() const { return cnt_; } + OB_INLINE bool empty() const { return 0 == cnt_; } + TO_STRING_KV(K_(cnt), K_(is_inited)); +private: + int inc_meta_ref_cnt(bool &inc_success) const; + int inc_data_ref_cnt(bool &inc_success) const; + void dec_meta_ref_cnt() const; + void dec_data_ref_cnt() const; + int inner_init( + ObArenaAllocator &allocator, + const ObIArray &tables, + const int64_t start_pos, + const int64_t end_pos); +private: + int64_t cnt_; + blocksstable::ObSSTable **sstable_array_; bool is_inited_; private: - DISALLOW_COPY_AND_ASSIGN(ObITableArray); -}; - -class ObSSTableArray: public ObITableArray -{ -public: - virtual int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; - virtual int64_t get_serialize_size() const; - virtual int deserialize( - common::ObIAllocator &allocator, - const char *buf, - const int64_t data_len, - int64_t &pos); - int get_min_schema_version(int64_t &min_schema_version) const; -}; - -class ObExtendTableArray: public ObITableArray -{ -public: - virtual int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; - virtual int64_t get_serialize_size() const; - virtual int deserialize( - common::ObIAllocator &allocator, - const char *buf, - const int64_t data_len, - int64_t &pos); - -private: - virtual int get_all_tables(common::ObIArray &sstables) const override { UNUSED(sstables); return OB_NOT_SUPPORTED; } - virtual ObITable *get_boundary_table(const bool last) const { UNUSED(last); return nullptr; } + DISALLOW_COPY_AND_ASSIGN(ObSSTableArray); }; class ObMemtableArray { public: - ObMemtableArray(); - virtual ~ObMemtableArray(); - void destroy(); - OB_INLINE int64_t count() const { return (nullptr == array_) ? 0 : array_->count(); } - OB_INLINE bool empty() const { return 0 == count(); } - OB_INLINE ObITable *get_table(const int64_t idx) const { return (idx < count() && idx >= 0) ? array_->at(idx) : nullptr; } - OB_INLINE ObITable *operator[](const int64_t idx) { return get_table(idx); } - OB_INLINE ObITable *operator[](const int64_t idx) const { return get_table(idx); } + static constexpr int64_t MEMTABLE_ARRAY_SIZE =16; + ObMemtableArray() : memtable_array_(), count_(0) {} + OB_INLINE memtable::ObMemtable *operator[](const int64_t pos) const + { + OB_ASSERT(pos < count_ && pos >= 0); + return memtable_array_[pos]; + } + OB_INLINE void reset() { new (this) ObMemtableArray(); } + OB_INLINE int64_t count() const { return count_; } + OB_INLINE bool empty() const { return 0 == count_; } + OB_INLINE bool is_valid() const { return !empty(); } - int init(common::ObIAllocator *allocator); - int init(common::ObIAllocator *allocator, const ObMemtableArray &other); - int build(common::ObIArray &handle_array, const int64_t start_pos = 0); - int rebuild(common::ObIArray &handle_array); + int build(common::ObIArray &table_array, const int64_t start_pos = 0); + int rebuild(const common::ObIArray &table_array); int rebuild( const share::SCN &clog_checkpoint_scn, - common::ObIArray &handle_array); - int prepare_allocate(); - int find(const ObITable::TableKey &table_key, ObTableHandleV2 &handle) const; + common::ObIArray &table_array); + int find(const ObITable::TableKey &table_key, ObITable *&table) const; int find(const share::SCN &start_scn, const int64_t base_version, ObITable *&table, int64_t &mem_pos) const; - TO_STRING_KV(K_(is_inited), KPC_(array)); + int assign(ObMemtableArray &dst_array) const; + int64_t to_string(char *buf, const int64_t buf_len) const; private: - int add_table(ObITable * const table); - void reset_table(const int64_t pos); - -public: - static const int64_t DEFAULT_TABLE_CNT = 16; - storage::ObTenantMetaMemMgr* meta_mem_mgr_; - common::ObIAllocator *allocator_; - common::ObSEArray *array_; - bool is_inited_; + int trim_empty_last_memtable(); + memtable::ObMemtable *memtable_array_[MEMTABLE_ARRAY_SIZE]; + int64_t count_; private: DISALLOW_COPY_AND_ASSIGN(ObMemtableArray); }; -class ObTableStoreIterator -{ -public: - friend class ObPrintTableStoreIterator; - static const int64_t DEFAULT_TABLET_CNT = 16; - typedef common::ObSEArray TableArray; - - explicit ObTableStoreIterator(const bool reverse_iter = false); - virtual ~ObTableStoreIterator(); - void reset(); - void resume(); - bool is_valid() const { return array_.count() > 0; } - int64_t count() const { return array_.count(); } - - int copy(const ObTableStoreIterator &other); - int add_tables(ObMemtableArray &array, const int64_t start_pos = 0); - int add_tables(ObITable **start, const int64_t count = 1); - int add_table(ObITable *input_table); - int get_next(ObITable *&table); - - ObITable *get_boundary_table(const bool is_last); - - int set_retire_check(); - bool check_store_expire() const { return (NULL == memstore_retired_) ? false : ATOMIC_LOAD(memstore_retired_); } - TO_STRING_KV(K_(array), K_(pos), K_(memstore_retired), K_(step)); - -private: - TableArray array_; - int64_t pos_; - int64_t step_; - bool * memstore_retired_; -}; - - -class ObPrintTableStoreIterator -{ -public: - ObPrintTableStoreIterator(const ObTableStoreIterator &iter); - virtual ~ObPrintTableStoreIterator(); - int64_t to_string(char *buf, const int64_t buf_len) const; -private: - void table_to_string( - ObITable *table, - char *buf, - const int64_t buf_len, - int64_t &pos) const; -private: - const ObTableStoreIterator::TableArray &array_; - int64_t pos_; - int64_t step_; - bool *memstore_retired_; -}; - -#define PRINT_TS_ITER(x) (ObPrintTableStoreIterator(x)) - - struct ObTableStoreUtil { struct ObITableLogTsRangeCompare { @@ -215,6 +148,14 @@ struct ObTableStoreUtil int &result_code_; }; + struct ObTableHandleV2LogTsRangeReverseCompare { + explicit ObTableHandleV2LogTsRangeReverseCompare(int &sort_ret) + : result_code_(sort_ret) {} + bool operator()(const ObTableHandleV2 &lhandle, const ObTableHandleV2 &rhandle) const; + + int &result_code_; + }; + struct ObTableHandleV2SnapshotVersionCompare { explicit ObTableHandleV2SnapshotVersionCompare(int &sort_ret) : result_code_(sort_ret) {} @@ -223,10 +164,11 @@ struct ObTableStoreUtil int &result_code_; }; - static int compare_table_by_scn_range(const ObITable *ltable, const ObITable *rtable, bool &bret); + static int compare_table_by_scn_range(const ObITable *ltable, const ObITable *rtable, const bool is_ascend, bool &bret); static int compare_table_by_snapshot_version(const ObITable *ltable, const ObITable *rtable, bool &bret); static int sort_minor_tables(ObArray &tables); + static int reverse_sort_minor_table_handles(ObArray &table_handles); static int sort_major_tables(ObSEArray &tables); static bool check_include_by_scn_range(const ObITable <able, const ObITable &rtable); diff --git a/src/storage/tablet/ob_tablet.cpp b/src/storage/tablet/ob_tablet.cpp old mode 100644 new mode 100755 index ef29005e9..e17b897db --- a/src/storage/tablet/ob_tablet.cpp +++ b/src/storage/tablet/ob_tablet.cpp @@ -10,10 +10,12 @@ * See the Mulan PubL v2 for more details. */ +#include "lib/ob_errno.h" #define USING_LOG_PREFIX STORAGE #include "storage/tablet/ob_tablet.h" +#include "common/ob_clock_generator.h" #include "common/sql_mode/ob_sql_mode_utils.h" #include "lib/allocator/ob_allocator.h" #include "lib/lock/ob_thread_cond.h" @@ -38,30 +40,41 @@ #include "storage/ob_storage_schema.h" #include "storage/blocksstable/ob_sstable.h" #include "storage/blocksstable/ob_sstable_sec_meta_iterator.h" +#include "storage/blocksstable/ob_storage_cache_suite.h" #include "storage/compaction/ob_tenant_freeze_info_mgr.h" #include "storage/compaction/ob_tenant_tablet_scheduler.h" #include "storage/memtable/ob_memtable.h" #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" #include "storage/meta_mem/ob_meta_obj_struct.h" +#include "storage/meta_mem/ob_storage_meta_cache.h" +#include "storage/meta_mem/ob_tablet_handle.h" #include "storage/access/ob_table_scan_iterator.h" #include "storage/access/ob_rows_info.h" #include "storage/ddl/ob_ddl_clog.h" #include "storage/ddl/ob_ddl_struct.h" #include "storage/ddl/ob_tablet_ddl_kv_mgr.h" +#include "storage/ddl/ob_tablet_ddl_kv.h" #include "storage/ls/ob_ls_tablet_service.h" #include "storage/tablet/ob_tablet_common.h" +#include "storage/tablet/ob_tablet_obj_load_helper.h" #include "storage/tablet/ob_tablet_create_delete_helper.h" #include "storage/tablet/ob_tablet_memtable_mgr.h" #include "storage/tablet/ob_tablet_ddl_info.h" +#include "storage/tablet/ob_tablet_mds_node_dump_operator.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/tablet/ob_tablet_binding_mds_user_data.h" #include "storage/tx/ob_trans_part_ctx.h" #include "storage/tx/ob_trans_service.h" #include "storage/tx_storage/ob_ls_service.h" #include "storage/ob_tenant_tablet_stat_mgr.h" +#include "storage/blocksstable/ob_storage_cache_suite.h" +#include "storage/tablet/ob_tablet_medium_info_reader.h" namespace oceanbase { using namespace memtable; using namespace share; +using namespace common; using namespace share::schema; using namespace blocksstable; using namespace logservice; @@ -70,27 +83,66 @@ using namespace palf; namespace storage { +#define ALLOC_AND_INIT(allocator, addr, args...) \ + do { \ + if (OB_SUCC(ret)) { \ + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, addr.ptr_))) { \ + LOG_WARN("fail to allocate and new object", K(ret)); \ + } else if (OB_FAIL(addr.get_ptr()->init(allocator, args))) { \ + LOG_WARN("fail to initialize tablet member", K(ret), K(addr)); \ + } \ + } \ + } while (false) \ + +#define IO_AND_DESERIALIZE(allocator, meta_addr, meta_ptr, args...) \ + do { \ + if (OB_SUCC(ret)) { \ + ObArenaAllocator io_allocator; \ + char *io_buf = nullptr; \ + int64_t buf_len = -1; \ + int64_t io_pos = 0; \ + if (OB_FAIL(ObTabletObjLoadHelper::read_from_addr(io_allocator, meta_addr, io_buf, buf_len))) { \ + LOG_WARN("read table store failed", K(ret)); \ + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, meta_ptr))) { \ + LOG_WARN("alloc and new table store ptr failed", K(ret), K(buf_len), K(io_pos)); \ + } else if (OB_FAIL(meta_ptr->deserialize(allocator, ##args, io_buf, buf_len, io_pos))) { \ + LOG_WARN("deserialize failed", K(ret), K(buf_len), K(io_pos)); \ + } \ + } \ + } while (false) \ + ObTablet::ObTablet() - : version_(TABLET_VERSION), + : version_(TABLET_VERSION_V2), length_(0), wash_score_(INT64_MIN), ref_cnt_(0), - pointer_hdl_(), + next_tablet_guard_(), tablet_meta_(), - table_store_(), - storage_schema_(), - medium_info_list_(), + rowkey_read_info_(nullptr), + table_store_addr_(), + storage_schema_addr_(), + memtable_count_(0), + ddl_kvs_(), + ddl_kv_count_(0), + pointer_hdl_(), + next_full_tablet_guard_(), + allocator_(nullptr), + tablet_addr_(), memtable_mgr_(nullptr), log_handler_(nullptr), - table_store_lock_(common::ObLatchIds::TABLET_TABLE_STORE_LOCK), - full_read_info_(), - allocator_(nullptr), - next_tablet_guard_(), + mds_data_(), + memtables_lock_(), + mds_cache_lock_(), + tablet_status_cache_(), + ddl_data_cache_(), + next_tablet_(nullptr), + hold_ref_cnt_(false), is_inited_(false) { #if defined(__x86_64__) - static_assert(sizeof(ObTablet) <= 2560, "The size of ObTablet will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); + static_assert(sizeof(ObTablet) + sizeof(ObRowkeyReadInfo) <= 6000, "The size of ObTablet will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); #endif + MEMSET(memtables_, 0x0, sizeof(memtables_)); } ObTablet::~ObTablet() @@ -100,37 +152,50 @@ ObTablet::~ObTablet() void ObTablet::reset() { - LOG_DEBUG("reset tablet", KP(this)); + LOG_DEBUG("reset tablet", KP(this), "ls_id", tablet_meta_.ls_id_, "tablet_id", tablet_meta_.tablet_id_, K(lbt())); + + reset_memtable(); + reset_ddl_memtables(); + storage_schema_addr_.reset(); + table_store_addr_.reset(); wash_score_ = INT64_MIN; tablet_meta_.reset(); - table_store_.reset(); - storage_schema_.reset(); - medium_info_list_.reset(); + mds_data_.reset(); + tablet_addr_.reset(); + next_full_tablet_guard_.reset(); memtable_mgr_ = nullptr; log_handler_ = nullptr; pointer_hdl_.reset(); - full_read_info_.reset(); + if (nullptr != rowkey_read_info_) { + rowkey_read_info_->reset(); + rowkey_read_info_->~ObRowkeyReadInfo(); + rowkey_read_info_ = nullptr; + } + tablet_status_cache_.reset(); + ddl_data_cache_.reset(); next_tablet_guard_.reset(); - allocator_ = nullptr; + // allocator_ = nullptr; can't reset allocator_ which would be used when gc tablet + version_ = TABLET_VERSION_V2; + length_ = 0; + next_tablet_ = nullptr; + hold_ref_cnt_ = false; is_inited_ = false; } int ObTablet::init( + common::ObArenaAllocator &allocator, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const common::ObTabletID &data_tablet_id, - const common::ObTabletID &lob_meta_tablet_id, - const common::ObTabletID &lob_piece_tablet_id, - const SCN &create_scn, + const share::SCN &create_scn, const int64_t snapshot_version, const share::schema::ObTableSchema &table_schema, const lib::Worker::CompatMode compat_mode, const ObTabletTableStoreFlag &store_flag, - ObTableHandleV2 &table_handle, + blocksstable::ObSSTable *sstable, ObFreezer *freezer) { int ret = OB_SUCCESS; - allocator_ = &(MTL(ObTenantMetaMemMgr*)->get_tenant_allocator()); const int64_t default_max_sync_medium_scn = 0; if (OB_UNLIKELY(is_inited_)) { @@ -140,7 +205,7 @@ int ObTablet::init( || OB_UNLIKELY(!tablet_id.is_valid()) || OB_UNLIKELY(!data_tablet_id.is_valid()) //|| OB_UNLIKELY(create_scn <= OB_INVALID_TIMESTAMP) - || OB_UNLIKELY(snapshot_version <= OB_INVALID_TIMESTAMP) + || OB_UNLIKELY(OB_INVALID_VERSION == snapshot_version) || OB_UNLIKELY(!table_schema.is_valid()) || OB_UNLIKELY(lib::Worker::CompatMode::INVALID == compat_mode) || OB_ISNULL(freezer)) { @@ -152,35 +217,40 @@ int ObTablet::init( || OB_ISNULL(log_handler_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet pointer handle is invalid", K(ret), K_(pointer_hdl), K_(memtable_mgr), K_(log_handler)); - } else if (OB_FAIL(init_shared_params(ls_id, tablet_id, table_schema.get_schema_version(), default_max_sync_medium_scn, compat_mode, freezer))) { - LOG_WARN("failed to init shared params", K(ret), K(ls_id), K(tablet_id), KP(freezer)); - } else if (OB_FAIL(tablet_meta_.init(*allocator_, ls_id, tablet_id, data_tablet_id, - lob_meta_tablet_id, lob_piece_tablet_id, - create_scn, snapshot_version, compat_mode, store_flag, table_schema.get_schema_version(), default_max_sync_medium_scn))) { + } else if (OB_FAIL(init_shared_params(ls_id, tablet_id, table_schema.get_schema_version(), + default_max_sync_medium_scn, compat_mode, freezer))) { + LOG_WARN("failed to init shared params", K(ret), K(ls_id), K(tablet_id), K(compat_mode), KP(freezer)); + } else if (OB_FAIL(tablet_meta_.init(ls_id, tablet_id, data_tablet_id, + create_scn, snapshot_version, compat_mode, store_flag, table_schema.get_schema_version()/*create_schema_version*/))) { LOG_WARN("failed to init tablet meta", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), - K(lob_meta_tablet_id), K(lob_piece_tablet_id), K(create_scn), K(snapshot_version), K(compat_mode), K(store_flag)); } else if (is_ls_inner_tablet() && OB_FAIL(inner_create_memtable())) { LOG_WARN("failed to create first memtable", K(ret), K(tablet_id)); - } else if (OB_FAIL(table_store_.init(*allocator_, this, &table_handle))) { - LOG_WARN("failed to init table store", K(ret), K(table_handle)); - } else if (OB_FAIL(storage_schema_.init(*allocator_, table_schema, compat_mode))) { - LOG_WARN("failed to init storage schema", K(ret), K(table_schema), K(compat_mode)); - } else if (OB_FAIL(medium_info_list_.init(*allocator_, nullptr))) { - LOG_WARN("failed to init medium info list", K(ret)); - } else if (OB_FAIL(build_read_info(*allocator_))) { - LOG_WARN("failed to build read info", K(ret)); - } else if (OB_FAIL(pre_transform_sstable_root_block(*full_read_info_.get_index_read_info()))) { - LOG_WARN("failed to pre-transform sstable root block", K(ret), K(full_read_info_)); - } else if (OB_FAIL(check_sstable_column_checksum())) { - LOG_WARN("failed to check sstable column checksum", K(ret), KPC(this)); + } else if (OB_FAIL(pull_memtables())) { + LOG_WARN("fail to pull memtable", K(ret)); } else { - is_inited_ = true; - LOG_INFO("succeeded to init tablet", K(ret), KP(this), K(ls_id), K(tablet_id), K(data_tablet_id), - K(snapshot_version), K(table_schema), K(compat_mode), K(lob_meta_tablet_id), K(lob_piece_tablet_id), - K(table_handle)); + ALLOC_AND_INIT(allocator, table_store_addr_, (*this), sstable); + ALLOC_AND_INIT(allocator, storage_schema_addr_, table_schema, compat_mode, + true/*skip_column_info*/, ObStorageSchema::STORAGE_SCHEMA_VERSION_V2); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(check_sstable_column_checksum())) { + LOG_WARN("failed to check sstable column checksum", K(ret), KPC(this)); + } else if (OB_FAIL(build_read_info(allocator))) { + LOG_WARN("failed to build read info", K(ret)); + } else if (OB_FAIL(mds_data_.init(allocator))) { + LOG_WARN("failed to init mds data", K(ret)); + } else if (is_ls_inner_tablet() && + OB_FAIL(mds_data_.set_tablet_status(allocator_, ObTabletStatus::Status::NORMAL, ObTabletMdsUserDataType::CREATE_TABLET))) { + LOG_WARN("failed to set normal status for ls inner tablet", K(ret)); + } else if (FALSE_IT(set_mem_addr())) { + } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { + LOG_WARN("failed to increase macro ref cnt", K(ret)); + } else { + is_inited_ = true; + LOG_INFO("succeeded to init tablet for first time creation", K(ret), KPC(sstable), K(*this)); + } } - if (OB_UNLIKELY(!is_inited_)) { reset(); } @@ -189,19 +259,21 @@ int ObTablet::init( } int ObTablet::init( + common::ObArenaAllocator &allocator, const ObUpdateTableStoreParam ¶m, - const ObTablet &old_tablet, - const ObTabletTxMultiSourceDataUnit &tx_data, - const ObTabletBindingInfo &ddl_data, - const ObTabletAutoincSeq &autoinc_seq) + const ObTablet &old_tablet) { int ret = OB_SUCCESS; int64_t max_sync_schema_version = 0; - int64_t max_serialized_medium_scn = nullptr != param.medium_info_list_ ? param.medium_info_list_->get_max_medium_snapshot() : 0; int64_t input_max_sync_schema_version = 0; - ObITable *last_major = nullptr; - const bool update_in_major_type_merge = param.need_report_ && param.table_handle_.get_table()->is_major_sstable(); - allocator_ = &(MTL(ObTenantMetaMemMgr*)->get_tenant_allocator()); + common::ObArenaAllocator tmp_arena_allocator("InitTablet"); + ObTabletMemberWrapper old_table_store_wrapper; + const ObTabletTableStore *old_table_store = nullptr; + const ObStorageSchema *old_storage_schema = nullptr; + const ObTabletMdsData &old_mds_data = old_tablet.mds_data_; + const bool update_in_major_type_merge = param.need_report_ && param.sstable_->is_major_sstable(); + int64_t finish_medium_scn = 0; + if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret), K(is_inited_)); @@ -216,52 +288,58 @@ int ObTablet::init( LOG_WARN("tablet pointer handle is invalid", K(ret), K_(pointer_hdl), K_(memtable_mgr), K_(log_handler)); } else if (OB_FAIL(old_tablet.get_max_sync_storage_schema_version(max_sync_schema_version))) { LOG_WARN("failed to get max sync storage schema version", K(ret)); + } else if (OB_FAIL(old_tablet.load_storage_schema(tmp_arena_allocator, old_storage_schema))) { + LOG_WARN("failed to load storage schema", K(ret), K(old_tablet)); } else if (FALSE_IT(input_max_sync_schema_version = MIN(MAX(param.storage_schema_->schema_version_, - old_tablet.storage_schema_.schema_version_), max_sync_schema_version))) { + old_storage_schema->schema_version_), max_sync_schema_version))) { // use min schema version to avoid lose storage_schema in replay/reboot - } else if (OB_FAIL(tablet_meta_.init(*allocator_, old_tablet.tablet_meta_, + } else if (OB_FAIL(tablet_meta_.init(old_tablet.tablet_meta_, param.snapshot_version_, param.multi_version_start_, - tx_data, ddl_data, autoinc_seq, input_max_sync_schema_version, - MAX(max_serialized_medium_scn, old_tablet.tablet_meta_.max_serialized_medium_scn_), + input_max_sync_schema_version, param.clog_checkpoint_scn_, param.ddl_info_))) { LOG_WARN("failed to init tablet meta", K(ret), K(old_tablet), K(param), - K(tx_data), K(ddl_data), K(autoinc_seq), K(input_max_sync_schema_version)); - } else if (OB_FAIL(table_store_.init(*allocator_, this, param, old_tablet.table_store_))) { - LOG_WARN("failed to init table store", K(ret), K(old_tablet)); - } else if (OB_FAIL(choose_and_save_storage_schema(*allocator_, old_tablet.storage_schema_, *param.storage_schema_))) { + K(input_max_sync_schema_version)); + } else if (OB_FAIL(choose_and_save_storage_schema(allocator, *old_storage_schema, *param.storage_schema_))) { LOG_WARN("failed to choose and save storage schema", K(ret), K(old_tablet), K(param)); - } else if (OB_FAIL(try_update_start_scn())) { - LOG_WARN("failed to update start scn", K(ret), K(param), K(table_store_)); + } else if (OB_FAIL(old_tablet.fetch_table_store(old_table_store_wrapper))) { + LOG_WARN("failed to fetch old table store", K(ret), K(old_tablet)); + } else if (OB_FAIL(old_table_store_wrapper.get_member(old_table_store))) { + LOG_WARN("failed to get old table store", K(ret)); + } else if (OB_FAIL(pull_memtables())) { + LOG_WARN("failed to pull memtable", K(ret)); + } else { + ALLOC_AND_INIT(allocator, table_store_addr_, (*this), param, (*old_table_store)); + } + + if (FAILEDx(try_update_start_scn())) { + LOG_WARN("failed to update start scn", K(ret), K(param), K(table_store_addr_)); } else if (OB_FAIL(try_update_ddl_checkpoint_scn())) { - LOG_WARN("failed to update clog checkpoint ts", K(ret), K(param), K(table_store_)); + LOG_WARN("failed to update clog checkpoint ts", K(ret), K(param), K(table_store_addr_)); } else if (OB_FAIL(try_update_table_store_flag(param))) { - LOG_WARN("failed to update table store flag", K(ret), K(param), K(table_store_)); - } else if (FALSE_IT(last_major = table_store_.get_major_sstables().get_boundary_table(true/*last*/))) { - } else if (OB_FAIL(medium_info_list_.init( - *allocator_, - &(old_tablet.get_medium_compaction_info_list()), - param.medium_info_list_, - // delete all medium before latest finish major snapshot - nullptr != last_major ? last_major->get_snapshot_version() : 0, - param.merge_type_))) { - LOG_WARN("failed to init medium info list", K(ret)); - } else if (OB_FAIL(build_read_info(*allocator_))) { + LOG_WARN("failed to update table store flag", K(ret), K(param), K(table_store_addr_)); + } else if (OB_FAIL(get_finish_medium_scn(finish_medium_scn))) { + LOG_WARN("failed to get finish medium scn", K(ret)); + } else if (OB_FAIL(mds_data_.init(allocator, old_mds_data, finish_medium_scn, param.merge_type_))) { + LOG_WARN("failed to init mds data", K(ret), K(old_mds_data), K(finish_medium_scn), "merge_type", param.merge_type_); + } else if (OB_FAIL(build_read_info(allocator))) { LOG_WARN("failed to build read info", K(ret)); - } else if (OB_FAIL(pre_transform_sstable_root_block(*full_read_info_.get_index_read_info()))) { - LOG_WARN("failed to pre-transform sstable root block", K(ret), K(full_read_info_)); - } else if (OB_FAIL(inner_check_valid())) { - LOG_WARN("failed to check tablet valid", K(ret), K(param), K(old_tablet)); + } else if (OB_FAIL(check_medium_list())) { + LOG_WARN("failed to check medium list", K(ret), K(param), K(old_tablet)); + } else if (OB_FAIL(check_sstable_column_checksum())) { + LOG_WARN("failed to check sstable column checksum", K(ret), KPC(this)); + } else if (FALSE_IT(set_mem_addr())) { + } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { + LOG_WARN("failed to increase macro ref cnt", K(ret)); } else { if (old_tablet.get_tablet_meta().has_next_tablet_) { set_next_tablet_guard(old_tablet.next_tablet_guard_); } is_inited_ = true; - LOG_INFO("succeeded to init tablet", K(ret), K(param), K(old_tablet), K(tx_data), K(ddl_data), - K(autoinc_seq), K(medium_info_list_), KPC(this)); + LOG_INFO("succeeded to init tablet for mini/minor/major merge", K(ret), K(param), K(old_tablet), KPC(this)); } if (OB_SUCC(ret) && update_in_major_type_merge) { - const ObSSTable *major_table = static_cast(param.table_handle_.get_table()); + const ObSSTable *major_table = param.sstable_; int tmp_ret = OB_SUCCESS; if (OB_ISNULL(major_table)) { // init tablet with no major table, skip to init report info } else if (OB_TMP_FAIL(ObTabletMeta::init_report_info(major_table, @@ -275,10 +353,77 @@ int ObTablet::init( reset(); } + ObTablet::free_storage_schema(tmp_arena_allocator, old_storage_schema); + return ret; } int ObTablet::init( + common::ObArenaAllocator &allocator, + const ObTablet &old_tablet, + const share::SCN &flush_scn, + const ObTabletMdsData &mds_table_data, + const ObTabletMdsData &base_data) +{ + int ret = OB_SUCCESS; + allocator_ = &allocator; + common::ObArenaAllocator tmp_arena_allocator("InitTabletMDS"); + ObTabletMemberWrapper old_table_store_wrapper; + const ObTabletTableStore *old_table_store = nullptr; + const ObStorageSchema *old_storage_schema = nullptr; + int64_t finish_medium_scn = 0; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K(is_inited_)); + } else if (OB_UNLIKELY(!pointer_hdl_.is_valid()) + || OB_ISNULL(memtable_mgr_) + || OB_ISNULL(log_handler_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet pointer handle is invalid", K(ret), K_(pointer_hdl), K_(memtable_mgr), K_(log_handler)); + } else if (OB_FAIL(old_tablet.fetch_table_store(old_table_store_wrapper))) { + LOG_WARN("failed to fetch old table store", K(ret), K(old_tablet)); + } else if (OB_FAIL(old_table_store_wrapper.get_member(old_table_store))) { + LOG_WARN("failed to get old table store", K(ret)); + } else if (OB_FAIL(old_tablet.load_storage_schema(tmp_arena_allocator, old_storage_schema))) { + LOG_WARN("failed to load storage schema", K(ret), K(old_tablet)); + } else if (OB_FAIL(tablet_meta_.init(old_tablet.tablet_meta_, flush_scn))) { + LOG_WARN("failed to init tablet meta", K(ret), K(old_tablet), K(flush_scn)); + } else if (OB_FAIL(pull_memtables())) { + LOG_WARN("fail to pull memtable", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, table_store_addr_.ptr_))) { + LOG_WARN("fail to alloc and new table store object", K(ret), K_(table_store_addr)); + } else if (OB_FAIL(table_store_addr_.get_ptr()->init(*allocator_, *this, *old_table_store))) { + LOG_WARN("fail to init table store", K(ret), KPC(old_table_store)); + } else if (OB_FAIL(get_finish_medium_scn(finish_medium_scn))) { + LOG_WARN("failed to get finish medium scn", K(ret)); + } else if (OB_FAIL(mds_data_.init(allocator, mds_table_data, base_data, finish_medium_scn))) { + LOG_WARN("failed to init mds data", K(ret), K(finish_medium_scn)); + } else { + ALLOC_AND_INIT(allocator, storage_schema_addr_, *old_storage_schema); + } + + if (FAILEDx(build_read_info(*allocator_))) { + LOG_WARN("failed to build read info", K(ret)); + } else if (OB_FAIL(check_sstable_column_checksum())) { + LOG_WARN("failed to check sstable column checksum", K(ret), KPC(this)); + } else if (FALSE_IT(set_mem_addr())) { + } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { + LOG_WARN("failed to increase macro ref cnt", K(ret)); + } else { + if (old_tablet.get_tablet_meta().has_next_tablet_) { + set_next_tablet_guard(old_tablet.next_tablet_guard_); + } + is_inited_ = true; + LOG_INFO("succeeded to init tablet for dump mds table", K(ret), K(old_tablet), K(flush_scn), KPC(this), K(mds_table_data), K(base_data)); + } + ObTablet::free_storage_schema(tmp_arena_allocator, old_storage_schema); + + return ret; +} + +int ObTablet::init( + common::ObArenaAllocator &allocator, const ObMigrationTabletParam ¶m, const bool is_update, ObFreezer *freezer) @@ -286,8 +431,7 @@ int ObTablet::init( int ret = OB_SUCCESS; const share::ObLSID &ls_id = param.ls_id_; const common::ObTabletID &tablet_id = param.tablet_id_; - allocator_ = &(MTL(ObTenantMetaMemMgr*)->get_tenant_allocator()); - + allocator_ = &allocator; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret), K(is_inited_)); @@ -306,23 +450,53 @@ int ObTablet::init( param.compat_mode_, freezer))) { LOG_WARN("failed to init shared params", K(ret), K(ls_id), K(tablet_id), KP(freezer)); - } else if (OB_FAIL(tablet_meta_.init(*allocator_, param))) { + } else if (OB_FAIL(tablet_meta_.init(param))) { LOG_WARN("failed to init tablet meta", K(ret), K(param)); - } else if (OB_FAIL(table_store_.init(*allocator_, this, nullptr/*ObTableHandleV2*/))) { - LOG_WARN("failed to init table store", K(ret)); - } else if (OB_FAIL(storage_schema_.init(*allocator_, param.storage_schema_))) { - LOG_WARN("failed to init storage schema", K(ret), K(param)); - } else if (OB_FAIL(medium_info_list_.init(*allocator_, ¶m.medium_info_list_))) { - LOG_WARN("failed to init medium info list", K(ret)); - } else if (OB_FAIL(build_read_info(*allocator_))) { - LOG_WARN("failed to build read info", K(ret), K(param)); - } else if (OB_FAIL(pre_transform_sstable_root_block(*full_read_info_.get_index_read_info()))) { - LOG_WARN("failed to pre-transform sstable root block", K(ret), K(full_read_info_)); - } else if (OB_FAIL(inner_check_valid())) { - LOG_WARN("failed to check tablet valid", K(ret), K(param)); - } else { - is_inited_ = true; - LOG_INFO("succeeded to init tablet", K(ret), K(param), KPC(this)); + } + + if (OB_SUCC(ret)) { + if (param.is_empty_shell()) { + int64_t pos = 0; + ObString data = param.mds_data_.tablet_status_committed_kv_.v_.user_data_; + ObTabletCreateDeleteMdsUserData user_data; + if (OB_FAIL(user_data.deserialize(data.ptr(), data.length(), pos))) { + LOG_WARN("fail to deserialize tablet status cache", K(ret)); + } else if (OB_FAIL(mds_data_.init(allocator, user_data))) { + LOG_WARN("failed to init mds data", K(ret), K(user_data)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, table_store_addr_.ptr_))) { + LOG_WARN("fail to allocate and new rowkey read info", K(ret)); + } else if (OB_FAIL(table_store_addr_.ptr_->init(allocator, *this))) { + LOG_WARN("fail to init table store", K(ret)); + } else { + table_store_addr_.addr_.set_none_addr(); + storage_schema_addr_.addr_.set_none_addr(); + is_inited_ = true; + LOG_INFO("succeeded to init empty shell tablet", K(ret), K(param), KPC(this)); + } + } else { + if (OB_FAIL(mds_data_.init(*allocator_, param.mds_data_))) { + LOG_WARN("failed to assign mds data", K(ret), K(param)); + } else if (OB_FAIL(pull_memtables())) { + LOG_WARN("fail to pull memtable", K(ret)); + } else { + ALLOC_AND_INIT(allocator, table_store_addr_, (*this), nullptr/*ObTableHandleV2*/); + ALLOC_AND_INIT(allocator, storage_schema_addr_, param.storage_schema_); + } + + if (FAILEDx(build_read_info(allocator))) { + LOG_WARN("fail to build read info", K(ret)); + } else if (OB_FAIL(check_medium_list())) { + LOG_WARN("failed to check medium list", K(ret), K(param)); + } else if (OB_FAIL(check_sstable_column_checksum())) { + LOG_WARN("failed to check sstable column checksum", K(ret), KPC(this)); + } else if (FALSE_IT(set_mem_addr())) { + } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { + LOG_WARN("failed to increase macro ref cnt", K(ret)); + } else { + is_inited_ = true; + LOG_INFO("succeeded to init tablet with migration tablet param", K(ret), K(param), KPC(this)); + } + } } if (OB_UNLIKELY(!is_inited_)) { @@ -333,19 +507,22 @@ int ObTablet::init( } int ObTablet::init( - const ObIArray &table_handles, - const ObTablet &old_tablet, - const ObTabletTxMultiSourceDataUnit &tx_data, - const ObTabletBindingInfo &ddl_data, - const share::ObTabletAutoincSeq &autoinc_seq) + common::ObArenaAllocator &allocator, + const ObIArray &tables, + const ObTablet &old_tablet) { int ret = OB_SUCCESS; - allocator_ = &(MTL(ObTenantMetaMemMgr*)->get_tenant_allocator()); + common::ObArenaAllocator tmp_arena_allocator("InitTablet"); + ObTabletMemberWrapper old_table_store_wrapper; + const ObTabletTableStore *old_table_store = nullptr; + const ObStorageSchema *old_storage_schema = nullptr; + const ObTabletMdsData &old_mds_data = old_tablet.mds_data_; + allocator_ = &allocator; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("tablet has been inited", K(ret)); - } else if (OB_UNLIKELY(!old_tablet.is_valid() || 0 == table_handles.count())) { + } else if (OB_UNLIKELY(!old_tablet.is_valid() || 0 == tables.count())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("old tablet is invalid", K(ret), K(old_tablet)); } else if (OB_UNLIKELY(!pointer_hdl_.is_valid()) @@ -353,48 +530,69 @@ int ObTablet::init( || OB_ISNULL(log_handler_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet pointer handle is invalid", K(ret), K_(pointer_hdl), K_(memtable_mgr), K_(log_handler)); - } else if (OB_FAIL(tablet_meta_.init(*allocator_, old_tablet.tablet_meta_, old_tablet.get_snapshot_version(), - old_tablet.get_multi_version_start(), tx_data, ddl_data, autoinc_seq, - old_tablet.tablet_meta_.max_sync_storage_schema_version_, - old_tablet.tablet_meta_.max_serialized_medium_scn_))) { - LOG_WARN("fail to init tablet_meta", K(ret), K(old_tablet.tablet_meta_), K(tx_data), K(ddl_data), K(autoinc_seq)); - } else if (OB_FAIL(table_store_.batch_replace_sstables(*allocator_, this, table_handles, old_tablet.table_store_))) { - LOG_WARN("fail to init table store", K(ret), K(old_tablet), K(table_handles)); - } else if (OB_FAIL(storage_schema_.init(*allocator_, old_tablet.storage_schema_))) { - LOG_WARN("fail to init storage schema", K(ret), K(old_tablet.storage_schema_)); - } else if (OB_FAIL(medium_info_list_.init(*allocator_, &(old_tablet.get_medium_compaction_info_list())))) { - LOG_WARN("fail to init medium info list", K(ret)); + } else if (OB_FAIL(old_tablet.load_storage_schema(tmp_arena_allocator, old_storage_schema))) { + LOG_WARN("failed to load storage schema", K(ret), K(old_tablet)); + } else if (OB_FAIL(old_tablet.fetch_table_store(old_table_store_wrapper))) { + LOG_WARN("failed to fetch old table store", K(ret), K(old_tablet)); + } else if (OB_FAIL(old_table_store_wrapper.get_member(old_table_store))) { + LOG_WARN("failed to get old table store", K(ret)); + } else if (OB_FAIL(tablet_meta_.init(old_tablet.tablet_meta_, + old_tablet.get_snapshot_version(), + old_tablet.get_multi_version_start(), + old_tablet.tablet_meta_.max_sync_storage_schema_version_))) { + LOG_WARN("fail to init tablet_meta", K(ret), K(old_tablet.tablet_meta_)); + } else if (OB_FAIL(pull_memtables())) { + LOG_WARN("fail to pull memtable", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, table_store_addr_.ptr_))) { + LOG_WARN("fail to alloc and new table store object", K(ret), K_(table_store_addr)); + } else if (OB_FAIL(table_store_addr_.get_ptr()->init(*allocator_, *this, tables, *old_table_store))) { + LOG_WARN("fail to init table store", K(ret), K(old_tablet), K(tables)); + } else { + ALLOC_AND_INIT(allocator, storage_schema_addr_, *old_storage_schema); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(mds_data_.init(allocator, old_mds_data, 0/*finish_medium_scn*/))) { + LOG_WARN("failed to init mds data", K(ret), K(old_mds_data)); } else if (OB_FAIL(build_read_info(*allocator_))) { LOG_WARN("fail to build read info", K(ret)); - } else if (OB_FAIL(pre_transform_sstable_root_block(*full_read_info_.get_index_read_info()))) { - LOG_WARN("failed to pre-transform sstable root block", K(ret), K(full_read_info_)); } else if (OB_FAIL(check_sstable_column_checksum())) { LOG_WARN("failed to check sstable column checksum", K(ret), KPC(this)); + } else if (FALSE_IT(set_mem_addr())) { + } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { + LOG_WARN("failed to increase macro ref cnt", K(ret)); } else { if (old_tablet.get_tablet_meta().has_next_tablet_) { set_next_tablet_guard(old_tablet.next_tablet_guard_); } is_inited_ = true; - LOG_INFO("succeeded to init tablet", K(ret), K(old_tablet), KPC(this)); + LOG_INFO("succeeded to init tablet for sstable defragmentation", K(ret), K(old_tablet), KPC(this)); } if (OB_UNLIKELY(!is_inited_)) { reset(); } + + ObTablet::free_storage_schema(tmp_arena_allocator, old_storage_schema); + return ret; } int ObTablet::init( + common::ObArenaAllocator &allocator, const ObBatchUpdateTableStoreParam ¶m, - const ObTablet &old_tablet, - const ObTabletTxMultiSourceDataUnit &tx_data, - const ObTabletBindingInfo &ddl_data, - const ObTabletAutoincSeq &autoinc_seq) + const ObTablet &old_tablet) { int ret = OB_SUCCESS; - allocator_ = &(MTL(ObTenantMetaMemMgr*)->get_tenant_allocator()); + allocator_ = &allocator; + SCN max_clog_checkpoint_scn; + common::ObArenaAllocator tmp_arena_allocator("InitTablet"); + ObTabletMemberWrapper old_table_store_wrapper; + const ObTabletTableStore *old_table_store = nullptr; + const ObStorageSchema *old_storage_schema = nullptr; const ObStorageSchema *storage_schema = nullptr; - ObITable *last_major = nullptr; + int64_t finish_medium_scn = 0; + if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret), K(is_inited_)); @@ -406,46 +604,61 @@ int ObTablet::init( || OB_ISNULL(log_handler_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet pointer handle is invalid", K(ret), K_(pointer_hdl), K_(memtable_mgr), K_(log_handler)); - } else if (FALSE_IT(storage_schema = OB_ISNULL(param.tablet_meta_) ? &old_tablet.storage_schema_ : ¶m.tablet_meta_->storage_schema_)) { - } else if (OB_FAIL(tablet_meta_.init(*allocator_, old_tablet.tablet_meta_, tx_data, ddl_data, autoinc_seq, param.tablet_meta_ + } else if (param.is_transfer_replace_ && OB_FAIL(param.get_max_clog_checkpoint_scn(max_clog_checkpoint_scn))) { + LOG_WARN("failed to get max clog checkpoint ts", K(ret), K(param)); + } else if (OB_FAIL(old_tablet.load_storage_schema(tmp_arena_allocator, old_storage_schema))) { + LOG_WARN("failed to load storage schema", K(ret), K(old_tablet)); + } else if (OB_FAIL(old_tablet.fetch_table_store(old_table_store_wrapper))) { + LOG_WARN("failed to fetch old table store", K(ret), K(old_tablet)); + } else if (OB_FAIL(old_table_store_wrapper.get_member(old_table_store))) { + LOG_WARN("failed to get old table store", K(ret)); + } else if (FALSE_IT(storage_schema = OB_ISNULL(param.tablet_meta_) ? old_storage_schema : ¶m.tablet_meta_->storage_schema_)) { + } else if (OB_FAIL(tablet_meta_.init(old_tablet.tablet_meta_, param.tablet_meta_ // this interface for migration to batch update table store - // use old tablet clog_checkpoint_ts to avoid lose tx data - // use max schema to makesure sstable and schema match + // use max schema to make sure sstable and schema match ))) { - LOG_WARN("failed to init tablet meta", K(ret), K(old_tablet), K(param), K(tx_data), K(ddl_data), K(autoinc_seq)); - } else if (OB_FAIL(table_store_.build_ha_new_table_store(*allocator_, this, param, old_tablet.table_store_))) { + LOG_WARN("failed to init tablet meta", K(ret), K(old_tablet), K(param)); + } else if (OB_FAIL(pull_memtables())){ + LOG_WARN("fail to pull memtable", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, table_store_addr_.ptr_))) { + LOG_WARN("fail to alloc and new table store object", K(ret), K_(table_store_addr)); + } else if (OB_FAIL(table_store_addr_.ptr_->build_ha_new_table_store(allocator, *this, param, *old_table_store))) { LOG_WARN("failed to init table store", K(ret), K(old_tablet)); - } else if (OB_FAIL(choose_and_save_storage_schema(*allocator_, old_tablet.storage_schema_, *storage_schema))) { + } else if (OB_FAIL(choose_and_save_storage_schema(*allocator_, *old_storage_schema, *storage_schema))) { LOG_WARN("failed to choose and save storage schema", K(ret), K(old_tablet), K(param)); } else if (OB_FAIL(try_update_start_scn())) { - LOG_WARN("failed to update start scn", K(ret), K(param), K(table_store_)); - } else if (FALSE_IT(last_major = table_store_.get_major_sstables().get_boundary_table(true/*last*/))) { - } else if (OB_FAIL(medium_info_list_.init( - *allocator_, - &(old_tablet.get_medium_compaction_info_list()), - OB_ISNULL(param.tablet_meta_) ? nullptr : ¶m.tablet_meta_->medium_info_list_, - // delete all medium before latest finish major snapshot - nullptr != last_major ? last_major->get_snapshot_version() : 0))) { - LOG_WARN("failed to init medium info list", K(ret), K(old_tablet)); - //This interface should not try_update_ddl_checkpoint_ts - //Bug : 45542552 + LOG_WARN("failed to update start scn", K(ret), K(param), K(table_store_addr_)); + } else if (OB_FAIL(get_finish_medium_scn(finish_medium_scn))) { + LOG_WARN("failed to get finish medium scn", K(ret)); + } else if (nullptr != param.tablet_meta_ + && OB_FAIL(mds_data_.init(allocator, old_tablet.mds_data_, param.tablet_meta_->mds_data_.medium_info_list_, finish_medium_scn))) { + LOG_WARN("failed to init mds data", K(ret), "mds_data", param.tablet_meta_->mds_data_, K(finish_medium_scn)); + } else if (nullptr == param.tablet_meta_ + && OB_FAIL(mds_data_.init(allocator, old_tablet.mds_data_, finish_medium_scn))) { + LOG_WARN("failed to init mds data", K(ret), "mds_data", old_tablet.mds_data_, K(finish_medium_scn)); } else if (OB_FAIL(build_read_info(*allocator_))) { LOG_WARN("failed to build read info", K(ret)); - } else if (OB_FAIL(pre_transform_sstable_root_block(*full_read_info_.get_index_read_info()))) { - LOG_WARN("failed to pre-transform sstable root block", K(ret), K(full_read_info_)); - } else if (OB_FAIL(inner_check_valid())) { - LOG_WARN("failed to check tablet valid", K(ret), K(param), K(old_tablet)); + } else if (OB_FAIL(check_medium_list())) { + LOG_WARN("failed to check medium list", K(ret), K(param), K(old_tablet)); + } else if (OB_FAIL(check_sstable_column_checksum())) { + LOG_WARN("failed to check sstable column checksum", K(ret), KPC(this)); + } else if (param.is_transfer_replace_ && OB_FAIL(tablet_meta_.reset_transfer_table())) { + LOG_WARN("failed to set finish tansfer replace", K(ret), K(tablet_meta_), K(param)); + } else if (param.is_transfer_replace_ && OB_FALSE_IT(tablet_meta_.ha_status_ = param.ha_status_)) { + } else if (FALSE_IT(set_mem_addr())) { + } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { + LOG_WARN("failed to increase macro ref cnt", K(ret)); } else { if (old_tablet.get_tablet_meta().has_next_tablet_) { set_next_tablet_guard(old_tablet.next_tablet_guard_); } is_inited_ = true; - LOG_INFO("succeeded to init tablet", K(ret), K(param), K(old_tablet), KPC(this)); + LOG_INFO("succeeded to init tablet for ha build new table store", K(ret), K(param), K(old_tablet), KPC(this)); } if (OB_SUCC(ret)) { DEBUG_SYNC(HA_REPORT_META_TABLE); - const ObSSTable *last_major = static_cast(table_store_.get_major_sstables().get_boundary_table(true/*last*/)); + const ObSSTable *last_major = static_cast(table_store_addr_.get_ptr()->get_major_sstables().get_boundary_table(true/*last*/)); int tmp_ret = OB_SUCCESS; if (OB_ISNULL(last_major)) { // init tablet with no major table, skip to init report info } else if (OB_TMP_FAIL(ObTabletMeta::init_report_info(last_major, @@ -458,15 +671,172 @@ int ObTablet::init( reset(); } + ObTablet::free_storage_schema(tmp_arena_allocator, old_storage_schema); + return ret; } -int ObTablet::init_with_update_medium_info(const ObTablet &old_tablet) +int ObTablet::fetch_table_store(ObTabletMemberWrapper &wrapper) const { int ret = OB_SUCCESS; + if (OB_UNLIKELY(!table_store_addr_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table store addr", K(ret), K_(table_store_addr)); + } else if (table_store_addr_.is_memory_object() + || table_store_addr_.is_none_object()) { + if (OB_ISNULL(table_store_addr_.get_ptr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table store addr ptr is null", K(ret), K_(table_store_addr)); + } else { + wrapper.set_member(table_store_addr_.get_ptr()); + } + } else { + ObStorageMetaHandle handle; + ObStorageMetaKey meta_key(MTL_ID(), table_store_addr_.addr_); + if (OB_FAIL(OB_STORE_CACHE.get_storage_meta_cache().get_meta( + ObStorageMetaValue::MetaType::TABLE_STORE, meta_key, handle, this))) { + LOG_WARN("get meta failed", K(ret), K(meta_key)); + } else if (OB_FAIL(wrapper.set_cache_handle(handle))) { + LOG_WARN("wrapper set cache handle failed", K(ret), K(meta_key), K_(table_store_addr)); + } + } + return ret; +} + +int ObTablet::fetch_autoinc_seq(ObTabletMemberWrapper &wrapper) const +{ + int ret = OB_SUCCESS; + const ObTabletComplexAddr &auto_inc_seq_addr = mds_data_.auto_inc_seq_; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!auto_inc_seq_addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid auto inc seq addr", K(ret)); + } else if (auto_inc_seq_addr.is_memory_object() + || auto_inc_seq_addr.is_none_object()) { + if (OB_ISNULL(auto_inc_seq_addr.get_ptr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("auto inc seq addr ptr is null", K(ret), K_(mds_data_.auto_inc_seq)); + } else { + wrapper.set_member(auto_inc_seq_addr.get_ptr()); + } + } else { + ObStorageMetaHandle handle; + ObStorageMetaKey meta_key(MTL_ID(), auto_inc_seq_addr.addr_); + if (OB_FAIL(OB_STORE_CACHE.get_storage_meta_cache().get_meta( + ObStorageMetaValue::MetaType::AUTO_INC_SEQ, meta_key, handle, this))) { + LOG_WARN("get meta failed", K(ret), K(meta_key)); + } else if (OB_FAIL(wrapper.set_cache_handle(handle))) { + LOG_WARN("wrapper set cache handle failed", K(ret), K(meta_key), K(auto_inc_seq_addr)); + } + } + return ret; +} + +int ObTablet::load_storage_schema( + common::ObArenaAllocator &allocator, + const ObStorageSchema *&storage_schema) const +{ + int ret = OB_SUCCESS; + ObStorageSchema *schema = nullptr; + if (OB_UNLIKELY(!storage_schema_addr_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid storage schema address", K(ret), K(storage_schema_addr_)); + } else if (storage_schema_addr_.is_memory_object()) { + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, schema))) { + LOG_WARN("alloc and new failed", K(ret)); + } else if (OB_FAIL(schema->init(allocator, *storage_schema_addr_.ptr_))) { + LOG_WARN("failed to copy storage schema", K(ret)); + } + } else { + IO_AND_DESERIALIZE(allocator, storage_schema_addr_.addr_, schema); + } + + if (OB_FAIL(ret)) { + ObTablet::free_storage_schema(allocator, schema); + } else if (OB_ISNULL(schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to load storage schema", K(ret), K_(storage_schema_addr)); + } else if (OB_UNLIKELY(!schema->is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid schema", K(ret), K_(storage_schema_addr), KPC(schema)); + + ObTablet::free_storage_schema(allocator, schema); + } else { + storage_schema = schema; + } + return ret; +} + +void ObTablet::free_storage_schema(common::ObIAllocator &allocator, const ObStorageSchema *storage_schema) +{ + if (OB_NOT_NULL(storage_schema)) { + storage_schema->~ObStorageSchema(); + allocator.free(const_cast(storage_schema)); + } +} + +int ObTablet::read_medium_info_list( + common::ObArenaAllocator &allocator, + const compaction::ObMediumCompactionInfoList *&medium_info_list) const +{ + int ret = OB_SUCCESS; + const ObTabletComplexAddr &complex_addr = mds_data_.medium_info_list_; + int64_t finish_medium_scn = 0; + ObTabletDumpedMediumInfo mds_table_medium_info_list; + const ObTabletDumpedMediumInfo *base_medium_info_list = nullptr; + ObTabletDumpedMediumInfo fused_medium_info_list; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(fused_medium_info_list.init(allocator))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else if (OB_FAIL(get_finish_medium_scn(finish_medium_scn))) { + LOG_WARN("failed to get finish medium scn", K(ret)); + } else if (OB_FAIL(read_mds_table_medium_info_list(allocator, mds_table_medium_info_list))) { + LOG_WARN("failed to read mds table medium info list", K(ret)); + } else if (OB_FAIL(ObTabletMdsData::load_medium_info_list(allocator, complex_addr, base_medium_info_list))) { + LOG_WARN("failed to load medium info list", K(ret)); + } else if (OB_FAIL(ObTabletMdsData::copy_medium_info_list(finish_medium_scn, *base_medium_info_list, fused_medium_info_list))) { + LOG_WARN("failed to copy base medium info list", K(ret)); + } else if (OB_FAIL(ObTabletMdsData::copy_medium_info_list(finish_medium_scn, mds_table_medium_info_list, fused_medium_info_list))) { + LOG_WARN("failed to copy mds table medium info list", K(ret)); + } else { + compaction::ObMediumCompactionInfoList *tmp_list = nullptr; + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, tmp_list))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(tmp_list->init(allocator, mds_data_.extra_medium_info_, fused_medium_info_list))) { + LOG_WARN("failed to init", K(ret)); + } else { + medium_info_list = tmp_list; + } + + if (OB_FAIL(ret)) { + if (nullptr != tmp_list) { + tmp_list->compaction::ObMediumCompactionInfoList::~ObMediumCompactionInfoList(); + allocator.free(tmp_list); + } + } + } + + ObTabletMdsData::free_medium_info_list(allocator, base_medium_info_list); + + return ret; +} + +int ObTablet::init_with_update_medium_info( + common::ObArenaAllocator &allocator, + const ObTablet &old_tablet) +{ + int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + ObTabletMemberWrapper auto_inc_seqwrapper; const ObTabletMeta &old_tablet_meta = old_tablet.tablet_meta_; - const ObTabletTableStore &old_table_store = old_tablet.table_store_; - allocator_ = &(MTL(ObTenantMetaMemMgr*)->get_tenant_allocator()); + const ObTabletTableStore *old_table_store = nullptr; + const ObStorageSchema *old_storage_schema = nullptr; + const ObTabletMdsData &old_mds_data = old_tablet.mds_data_; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; @@ -479,67 +849,151 @@ int ObTablet::init_with_update_medium_info(const ObTablet &old_tablet) || OB_ISNULL(log_handler_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet pointer handle is invalid", K(ret), K_(pointer_hdl), K_(pointer_hdl), K_(memtable_mgr), K_(log_handler)); - } else if (OB_FAIL(tablet_meta_.init(*allocator_, old_tablet_meta))) { + } else if (OB_FAIL(assign_memtables(old_tablet))) { + LOG_WARN("fail to assign memtables", K(ret)); + } else if (OB_FAIL(old_tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret), K(old_tablet)); + } else if (OB_FAIL(table_store_wrapper.get_member(old_table_store))) { + LOG_WARN("fail to get table store", K(ret), K(table_store_wrapper)); + } else if (OB_FAIL(old_tablet.load_storage_schema(allocator, old_storage_schema))) { + LOG_WARN("fail to load storage schema", K(ret)); + } else if (OB_FAIL(tablet_meta_.init(allocator, old_tablet_meta))) { LOG_WARN("failed to init tablet meta", K(ret), K(old_tablet_meta)); - } else if (OB_FAIL(table_store_.assign(*allocator_, old_table_store, this))) { - LOG_WARN("failed to copy table store", K(ret), K(old_table_store)); - } else if (OB_FAIL(storage_schema_.init(*allocator_, old_tablet.storage_schema_))) { - LOG_WARN("failed to init storage schema", K(ret), K(old_tablet)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, table_store_addr_.ptr_))) { + LOG_WARN("fail to allocate and new table store", K(ret)); + } else if (OB_FAIL(table_store_addr_.ptr_->init(allocator, *this, *old_table_store))) { + LOG_WARN("fail to copy table store", K(ret), KPC(old_table_store)); } else if (OB_FAIL(try_update_start_scn())) { - LOG_WARN("failed to update start scn", K(ret), K(table_store_)); - } else if (OB_FAIL(medium_info_list_.init_after_check_finish(*allocator_, old_tablet.get_medium_compaction_info_list()))) { - LOG_WARN("failed to init medium info mgr", K(ret)); - } else if (OB_FAIL(build_read_info(*allocator_))) { - LOG_WARN("failed to build read info", K(ret)); + LOG_WARN("failed to update start scn", K(ret), KPC(old_table_store)); + } else if (OB_FAIL(mds_data_.init_with_update_medium_info(allocator, old_mds_data))) { + LOG_WARN("failed to init mds data", K(ret), K(old_mds_data)); + } else if (FALSE_IT(set_mem_addr())) { + } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { + LOG_WARN("failed to increase macro ref cnt", K(ret)); } else { - if (old_tablet.get_tablet_meta().has_next_tablet_) { - set_next_tablet_guard(old_tablet.next_tablet_guard_); + ALLOC_AND_INIT(allocator, storage_schema_addr_, *old_storage_schema); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(build_read_info(allocator))) { + LOG_WARN("failed to build read info", K(ret)); + } else { + if (old_tablet.get_tablet_meta().has_next_tablet_) { + set_next_tablet_guard(old_tablet.next_tablet_guard_); + } + LOG_INFO("succeeded to init tablet with update medium info", K(ret), K(this), K(old_tablet)); + is_inited_ = true; } - LOG_INFO("succeeded to init tablet", K(ret), K(medium_info_list_), K(old_tablet)); - is_inited_ = true; } if (OB_UNLIKELY(!is_inited_)) { reset(); } + + ObTablet::free_storage_schema(allocator, old_storage_schema); + + return ret; +} + +int ObTablet::init_empty_shell( + ObArenaAllocator &allocator, + const ObTablet &old_tablet) +{ + int ret = OB_SUCCESS; + bool is_commited; + const mds::MdsDumpKV *kv = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K(is_inited_)); + } else if (OB_UNLIKELY(old_tablet.get_tablet_meta().has_next_tablet_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("old tablet should not have next tablet", K(ret), K(old_tablet.get_tablet_meta())); + } else if (OB_FAIL(old_tablet.ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data))) { + LOG_WARN("old tablet get ObTabletCreateDeleteMdsUserData failed", K(ret), K(old_tablet)); + } else if (user_data.tablet_status_ != ObTabletStatus::DELETED && + user_data.tablet_status_ != ObTabletStatus::TRANSFER_OUT_DELETED) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("old tablet status is not deleted", K(ret), K(user_data.tablet_status_)); + } else if (OB_FAIL(tablet_meta_.assign(old_tablet.tablet_meta_))) { + LOG_WARN("assign old tablet meta to empty shell failed", K(ret), K(old_tablet.tablet_meta_)); + } else if (OB_FAIL(mds_data_.init(allocator, user_data))) { + LOG_WARN("failed to init mds data", K(ret), K(user_data)); + } else if (OB_FAIL(wait_release_memtables_())) { + LOG_ERROR("fail to release memtables", K(ret), K(old_tablet)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, table_store_addr_.ptr_))) { + LOG_WARN("fail to allocate and new rowkey read info", K(ret)); + } else if (OB_FAIL(table_store_addr_.ptr_->init(allocator, *this))) { + LOG_WARN("fail to init table store", K(ret)); + } else { + table_store_addr_.addr_.set_none_addr(); + storage_schema_addr_.addr_.set_none_addr(); + tablet_meta_.clog_checkpoint_scn_ = user_data.delete_commit_scn_; + tablet_meta_.mds_checkpoint_scn_ = user_data.delete_commit_scn_; + is_inited_ = true; + LOG_INFO("init empty shell", K(ret), K(old_tablet), KPC(this)); + } + + + if (OB_UNLIKELY(!is_inited_)) { + reset(); + } + return ret; } int ObTablet::check_sstable_column_checksum() const { int ret = OB_SUCCESS; - ObSEArray sstables; + common::ObArenaAllocator allocator; + const ObStorageSchema *storage_schema = nullptr; + ObTableStoreIterator iter; int64_t schema_col_cnt = 0; int64_t sstable_col_cnt = 0; - if (OB_UNLIKELY(!table_store_.is_valid() || !storage_schema_.is_valid())) { + if (OB_UNLIKELY(!table_store_addr_.is_valid() || !storage_schema_addr_.is_valid())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to check tablet ", K(ret), K(table_store_), K(storage_schema_)); - } else if (OB_FAIL(storage_schema_.get_stored_column_count_in_sstable(schema_col_cnt))) { - LOG_WARN("failed to get stored column count of storage schema", K(ret), KPC(this)); - } else if (OB_FAIL(inner_get_all_sstables(sstables))) { + LOG_WARN("failed to check tablet ", K(ret), K(table_store_addr_), K(storage_schema_addr_)); + } else if (OB_FAIL(load_storage_schema(allocator, storage_schema))) { + LOG_WARN("fail to load storage schema", K(ret)); + } else if (OB_FAIL(storage_schema->get_stored_column_count_in_sstable(schema_col_cnt))) { LOG_WARN("failed to get stored column count of storage schema", K(ret), KPC(this)); + } else if (OB_FAIL(inner_get_all_sstables(iter))) { + LOG_WARN("fail to get all sstables", K(ret)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < sstables.count(); ++i) { - ObSSTable *cur = reinterpret_cast(sstables.at(i)); - if (OB_ISNULL(cur)) { - ret = OB_ERR_NULL_VALUE; - LOG_WARN("invalid null sstable", K(ret), K(i), KP(cur), KPC(this)); - } else if (cur->is_major_sstable() && cur->get_meta().is_empty()) { - // since empty major sstable may have wrong column count, skip for compatibility from 4.0 to 4.1 - } else if ((sstable_col_cnt = cur->get_meta().get_col_checksum().count()) > schema_col_cnt) { + ObITable *table = nullptr; + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.get_next(table))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get next table", K(ret), KPC(this)); + } + } else if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("The storage schema is older than the sstable, and cann’t explain the data.", - K(ret), K(i), K(sstable_col_cnt), K(schema_col_cnt), KPC(cur), K_(storage_schema)); + LOG_WARN("unexpected error, table is nullptr", K(ret), KPC(table)); + } else { + ObSSTable *cur = reinterpret_cast(table); + ObSSTableMetaHandle meta_handle; + if (OB_FAIL(cur->get_meta(meta_handle))) { + LOG_WARN("fail to get sstable meta", K(ret), KPC(cur), KPC(this)); + } else if (cur->is_major_sstable() && meta_handle.get_sstable_meta().is_empty()) { + // since empty major sstable may have wrong column count, skip for compatibility from 4.0 to 4.1 + } else if ((sstable_col_cnt = meta_handle.get_sstable_meta().get_col_checksum_cnt()) > schema_col_cnt) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("The storage schema is older than the sstable, and cann’t explain the data.", + K(ret), K(sstable_col_cnt), K(schema_col_cnt), KPC(cur), KPC(storage_schema)); + } } } } + ObTablet::free_storage_schema(allocator, storage_schema); return ret; } -int ObTablet::serialize(char *buf, const int64_t len, int64_t &pos) + +int ObTablet::serialize(char *buf, const int64_t len, int64_t &pos) const { int ret = OB_SUCCESS; int64_t new_pos = pos; - + const int64_t length = get_self_size(); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); @@ -548,211 +1002,152 @@ int ObTablet::serialize(char *buf, const int64_t len, int64_t &pos) || OB_UNLIKELY(pos < 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(buf), K(len), K(pos)); - } else if (TABLET_VERSION != version_) { + } else if (OB_UNLIKELY(!is_valid() && !is_empty_shell())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid version", K(ret), K_(version)); - } else if (FALSE_IT(length_ = get_self_size())) { - // do nothing - } else if (OB_UNLIKELY(length_ > len - pos)) { + LOG_ERROR("tablet is invalid", K(ret), K(*this)); + } else if (TABLET_VERSION_V2 != version_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("buffer's length is not enough", K(ret), K(length_), K(len - new_pos)); + LOG_ERROR("invalid version", K(ret), K_(version)); + } else if (OB_UNLIKELY(length > len - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer's length is not enough", K(ret), K(length), K(len - new_pos)); } else if (OB_FAIL(serialization::encode_i32(buf, len, new_pos, version_))) { - LOG_WARN("failed to serialize tablet's version", K(ret), K(len), K(new_pos), K_(version)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_i32(buf, len, new_pos, length_))) { - LOG_WARN("failed to serialize tablet's length", K(ret), K(len), K(new_pos), K_(length)); - } else if (new_pos - pos < length_ && OB_FAIL(tablet_meta_.serialize(buf, len, new_pos))) { - LOG_WARN("failed to serialize tablet meta", K(ret), K(len), K(new_pos), K_(length), K_(version)); - } else if (new_pos - pos < length_ && OB_FAIL(table_store_.serialize(buf, len, new_pos))) { - LOG_WARN("failed to serialize table store", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(storage_schema_.serialize(buf, len, new_pos))) { - LOG_WARN("failed to serialize storage schema", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(medium_info_list_.serialize(buf, len, new_pos))) { - LOG_WARN("failed to serialize medium compaction list", K(ret), K(len), K(new_pos)); - } else if (OB_UNLIKELY(length_ != new_pos - pos)) { + LOG_WARN("failed to serialize tablet meta's version", K(ret), K(len), K(new_pos), K_(version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i32(buf, len, new_pos, length))) { + LOG_WARN("failed to serialize tablet meta's length", K(ret), K(len), K(new_pos), K(length)); + } else if (new_pos - pos < length && OB_FAIL(tablet_meta_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize tablet meta", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(table_store_addr_.addr_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize table store addr", K(ret), K(len), K(new_pos), K(table_store_addr_)); + } else if (new_pos - pos < length && OB_FAIL(storage_schema_addr_.addr_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize storage schema addr", K(ret), K(len), K(new_pos), K(table_store_addr_)); + } else if (!is_empty_shell() && new_pos - pos < length && OB_FAIL(rowkey_read_info_->serialize(buf, len, new_pos))) { + LOG_WARN("fail to serialize rowkey read info", K(ret), KPC(rowkey_read_info_)); + } else if (new_pos - pos < length && OB_FAIL(mds_data_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize mds data", K(ret), K(len), K(new_pos)); + } else if (OB_UNLIKELY(length != new_pos - pos)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K_(length)); + LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K(length), KPC(this)); } else if (tablet_meta_.has_next_tablet_ && OB_FAIL(next_tablet_guard_.get_obj()->serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize next tablet", K(ret), K(len), K(new_pos)); } else { pos = new_pos; } - return ret; } -int ObTablet::deserialize( - common::ObIAllocator &allocator, - const char *buf, - const int64_t len, - int64_t &pos) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(load_deserialize(allocator, buf, len, pos))) { - LOG_WARN("fail to load deserialize", K(ret), KP(buf), K(len), K(pos)); - } else if (OB_FAIL(deserialize_post_work())) { - LOG_WARN("fail to deserialize post work", K(ret), KP(buf), K(len), K(pos)); - } - return ret; -} - -int ObTablet::deserialize_post_work() -{ - int ret = OB_SUCCESS; - ObSEArray sstables; - if (OB_FAIL(get_all_sstables(sstables))) { - LOG_WARN("fail to get all sstables", K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < sstables.count(); i++) { - ObSSTable *sstable = static_cast(sstables.at(i)); - if (OB_ISNULL(sstable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, sstable is nullptr", K(ret), KP(sstable)); - } else if (OB_FAIL(sstable->deserialize_post_work())) { - LOG_WARN("fail to do deserialize post work for sstable", K(ret), KPC(sstable)); - } - } - } - if (OB_SUCC(ret) && tablet_meta_.has_next_tablet_) { - if (OB_FAIL(next_tablet_guard_.get_obj()->deserialize_post_work())) { - LOG_WARN("fail to deserialize next post work", K(ret), K(next_tablet_guard_)); - } - } - return ret; -} - -int ObTablet::dec_macro_disk_ref() -{ - int ret = OB_SUCCESS; - ObSEArray sstables; - if (OB_FAIL(get_all_sstables(sstables))) { - LOG_WARN("fail to get all sstables", K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < sstables.count(); i++) { - ObSSTable *sstable = static_cast(sstables.at(i)); - if (OB_ISNULL(sstable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, sstable is nullptr", K(ret), KP(sstable)); - } else if (OB_FAIL(sstable->dec_disk_ref())) { - LOG_ERROR("fail to dec disk ref cnt for sstable", K(ret), KPC(sstable)); - } - } - } - if (OB_SUCC(ret) && tablet_meta_.has_next_tablet_) { - if (OB_FAIL(next_tablet_guard_.get_obj()->dec_macro_disk_ref())) { - LOG_WARN("fail to dec macro disk ref", K(ret), K(next_tablet_guard_)); - } - } - return ret; -} - -int ObTablet::inc_macro_disk_ref() -{ - int ret = OB_SUCCESS; - ObSEArray sstables; - if (OB_FAIL(get_all_sstables(sstables))) { - LOG_WARN("fail to get all sstables", K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < sstables.count(); i++) { - ObSSTable *sstable = static_cast(sstables.at(i)); - if (OB_ISNULL(sstable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, sstable is nullptr", K(ret), KP(sstable)); - } else if (OB_FAIL(sstable->add_disk_ref())) { - LOG_ERROR("fail to add disk ref cnt for sstable", K(ret), KPC(sstable)); - } - } - } - if (OB_SUCC(ret) && tablet_meta_.has_next_tablet_) { - if (OB_FAIL(next_tablet_guard_.get_obj()->inc_macro_disk_ref())) { - LOG_WARN("fail to inc macro disk ref", K(ret), K(next_tablet_guard_)); - } - } - return ret; -} - -int ObTablet::load_deserialize( - common::ObIAllocator &allocator, +int ObTablet::rollback_ref_cnt( + common::ObArenaAllocator &allocator, const char *buf, const int64_t len, int64_t &pos) { int ret = OB_SUCCESS; int64_t new_pos = pos; - allocator_ = &allocator; - ObTabletHandle next_tablet_handle; - ObLSHandle ls_handle; - ObLSService *ls_service = MTL(ObLSService*); - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; - LOG_WARN("cannot deserialize inited tablet", K(ret), K_(is_inited)); + LOG_WARN("cannot deserialize inited tablet meta", K(ret), K_(is_inited)); } else if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0) - || OB_UNLIKELY(pos < 0)) { + || OB_UNLIKELY(pos < 0) + || OB_UNLIKELY(len <= pos)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(buf), K(len), K(pos)); - } else if (OB_ISNULL(memtable_mgr_) || OB_ISNULL(log_handler_)) { - // tablet pointer handle is not ready here, so DO NOT validate it + } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, (int32_t *)&version_))) { + LOG_WARN("failed to deserialize tablet meta's version", K(ret), K(len), K(new_pos)); + } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, (int32_t *)&length_))) { + LOG_WARN("failed to deserialize tablet meta's length", K(ret), K(len), K(new_pos)); + } else if (OB_UNLIKELY(length_ > len - pos)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null pointer", K(ret), K_(memtable_mgr), K_(log_handler)); - } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, &version_))) { - LOG_WARN("failed to deserialize tablet's version", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, &length_))) { - LOG_WARN("failed to deserialize tablet's length", K(ret), K(len), K(new_pos)); - } else if (TABLET_VERSION == version_) { - if (OB_UNLIKELY(length_ > len - pos)) { + LOG_WARN("buffer's length is not enough", K(ret), K(length_), K(len - new_pos)); + } else if (OB_FAIL(load_deserialize_v2(allocator, buf, len, pos, new_pos, false))) { + LOG_WARN("fail to load deserialize tablet v2", K(ret), K(length_), K(len - new_pos), KPC(this)); + } else if (OB_UNLIKELY(length_ != new_pos - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K_(length)); + } else if (tablet_meta_.has_next_tablet_) { + ObTablet next_tablet; + next_tablet.set_tablet_addr(tablet_addr_); + if (OB_FAIL(next_tablet.rollback_ref_cnt(allocator, buf, len, new_pos))) { + LOG_WARN("fail to deserialize next tablet for rollback", K(ret), KP(buf), K(len), K(new_pos)); + } + } + + if (OB_SUCC(ret)) { + hold_ref_cnt_ = true; + dec_macro_ref_cnt(); + pos = new_pos; + } + return ret; +} + +int ObTablet::deserialize( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + int64_t &pos) +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("cannot deserialize inited tablet meta", K(ret), K_(is_inited)); + } else if (OB_ISNULL(buf) + || OB_UNLIKELY(len <= 0) + || OB_UNLIKELY(pos < 0) + || OB_UNLIKELY(len <= pos)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(buf), K(len), K(pos)); + } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, (int32_t *)&version_))) { + LOG_WARN("failed to deserialize tablet meta's version", K(ret), K(len), K(new_pos)); + } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, (int32_t *)&length_))) { + LOG_WARN("failed to deserialize tablet meta's length", K(ret), K(len), K(new_pos)); + } else if (OB_UNLIKELY(length_ > len - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer's length is not enough", K(ret), K(length_), K(len - new_pos)); + } else if (TABLET_VERSION_V2 == version_ && OB_FAIL(load_deserialize_v2(allocator, buf, len, pos, new_pos))) { + LOG_WARN("failed to load deserialize v2", K(ret), K(length_), K(len - new_pos), KPC(this)); + } else if (TABLET_VERSION == version_ && OB_FAIL(load_deserialize_v1(allocator, buf, len, pos, new_pos))) { + LOG_WARN("failed to load deserialize v1", K(ret), K(length_), K(len - new_pos), KPC(this)); + } else if (OB_UNLIKELY(length_ != new_pos - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K_(length)); + } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { + LOG_WARN("failed to increase macro ref cnt", K(ret)); + } else if (tablet_meta_.has_next_tablet_) { + const ObTabletMapKey key(tablet_meta_.ls_id_, tablet_meta_.tablet_id_); + if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tmp_tablet(key, allocator, next_tablet_guard_))) { + LOG_WARN("failed to acquire tablet", K(ret), K(key)); + } else if (OB_ISNULL(next_tablet_guard_.get_obj())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("buffer's length is not enough", K(ret), K(length_), K(len - new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(tablet_meta_.deserialize(allocator, buf, len, new_pos))) { - LOG_WARN("failed to deserialize tablet meta", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(table_store_.deserialize(allocator, this, buf, len, new_pos))) { - LOG_WARN("failed to deserialize table store", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(storage_schema_.deserialize(allocator, buf, len, new_pos))) { - LOG_WARN("failed to deserialize storage schema", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(medium_info_list_.deserialize(allocator, buf, len, new_pos))) { - LOG_WARN("failed to deserialize medium compaction list", K(ret), K(len), K(new_pos)); - } else if (OB_UNLIKELY(length_ != new_pos - pos)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K_(length)); - } else if (OB_FAIL(build_read_info(allocator))) { - LOG_WARN("failed to build read info", K(ret)); - } else if (OB_FAIL(pre_transform_sstable_root_block(*full_read_info_.get_index_read_info()))) { - LOG_WARN("failed to pre-transform sstable root block", K(ret), K(full_read_info_)); - } else if (tablet_meta_.has_next_tablet_) { - LOG_WARN("The len and pos is", K(len), K(new_pos)); - const ObTabletMapKey key(tablet_meta_.ls_id_, tablet_meta_.tablet_id_); - if (OB_FAIL(ls_service->get_ls(tablet_meta_.ls_id_, ls_handle, ObLSGetMod::TABLET_MOD))) { - LOG_WARN("failed to get ls", K(ret), "ls_id", tablet_meta_.ls_id_); - } else if (t3m->is_used_obj_pool(&allocator)) { - if (OB_FAIL(t3m->acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, next_tablet_handle, false/*only acquire*/))) { - LOG_WARN("failed to acquire tablet", K(ret), K(key)); - } - } else if (OB_FAIL(t3m->acquire_tablet(WashTabletPriority::WTP_HIGH, key, allocator, next_tablet_handle, false/*only acquire*/))) { - LOG_WARN("failed to acquire tablet", K(ret), K(key)); - } - if (OB_FAIL(ret)) { - } else if (OB_ISNULL(next_tablet_handle.get_obj())) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("next tablet is null", K(ret)); - } else if (OB_FAIL(next_tablet_handle.get_obj()->load_deserialize(allocator, buf, len, new_pos))) { - LOG_WARN("failed to deserialize next tablet", K(ret), K(len), K(new_pos)); - } else { - set_next_tablet_guard(next_tablet_handle); - } + LOG_ERROR("next tablet is null", K(ret)); + } else if (FALSE_IT(next_tablet_guard_.get_obj()->tablet_addr_ = tablet_addr_)) { + } else if (OB_FAIL(next_tablet_guard_.get_obj()->deserialize(allocator, buf, len, new_pos))) { + LOG_WARN("failed to deserialize next tablet", K(ret), K(len), K(new_pos)); } } if (OB_SUCC(ret)) { pos = new_pos; - if (tablet_meta_.max_sync_storage_schema_version_ > storage_schema_.schema_version_) { - LOG_INFO("tablet meta status is not right, upgrade may happened. fix max_sync_schema_version on purpose", - K(tablet_meta_.max_sync_storage_schema_version_), - K(storage_schema_.schema_version_)); - tablet_meta_.max_sync_storage_schema_version_ = storage_schema_.schema_version_; + ObArenaAllocator arena_allocator; + const ObStorageSchema *schema = nullptr; + if (!is_empty_shell()) { + if (OB_FAIL(load_storage_schema(allocator, schema))) { + LOG_WARN("load storage schema failed", K(ret)); + } else if (tablet_meta_.max_sync_storage_schema_version_ > schema->schema_version_) { + LOG_INFO("tablet meta status is not right, upgrade may happened. fix max_sync_schema_version on purpose", + K(tablet_meta_.max_sync_storage_schema_version_), + K(schema->schema_version_)); + tablet_meta_.max_sync_storage_schema_version_ = schema->schema_version_; + } else { + is_inited_ = true; + LOG_INFO("succeed to deserialize tablet", K(ret), KPC(this)); + } + ObTablet::free_storage_schema(allocator, schema); + } else { + is_inited_ = true; + LOG_INFO("succeed to deserialize tablet", K(ret), KPC(this)); } - is_inited_ = true; - LOG_DEBUG("succeeded to deserialize tablet", K(ret), K(*this)); } else if (OB_UNLIKELY(!is_inited_)) { reset(); } @@ -760,6 +1155,656 @@ int ObTablet::load_deserialize( return ret; } +int ObTablet::load_deserialize_v1( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + const int64_t pos, + int64_t &new_pos) +{ + int ret = OB_SUCCESS; + ObTabletAutoincSeq auto_inc_seq; + ObTabletTxMultiSourceDataUnit tx_data; + ObTabletBindingInfo ddl_data; + ObMediumCompactionInfoList info_list; + + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, table_store_addr_.ptr_))) { + LOG_WARN("fail to allocate and new table store", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, storage_schema_addr_.ptr_))) { + LOG_WARN("fail to allocate and new storage schema", K(ret)); + } else if (new_pos - pos < length_ && OB_FAIL(deserialize_meta_v1(allocator, buf, len, new_pos, + auto_inc_seq, tx_data, ddl_data))) { + LOG_WARN("failed to deserialize tablet meta", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(table_store_addr_.ptr_->deserialize(allocator, *this, buf, len, new_pos))) { + LOG_WARN("failed to deserialize table store", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(storage_schema_addr_.ptr_->deserialize(allocator, buf, len, new_pos))) { + LOG_WARN("failed to deserialize storage schema", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(info_list.deserialize(allocator, buf, len, new_pos))) { + LOG_WARN("failed to deserialize medium compaction info list", K(ret), K(len), K(new_pos)); + } else if (OB_UNLIKELY(length_ != new_pos - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K_(length)); + } + + // old mds data convert to new mds data + if (FAILEDx(ObTabletMdsData::build_mds_data(allocator, auto_inc_seq, tx_data, tablet_meta_.create_scn_, + ddl_data, tablet_meta_.clog_checkpoint_scn_, info_list, mds_data_))) { + LOG_WARN("failed to build mds data", K(ret)); + } else if (OB_FAIL(tablet_meta_.transfer_info_.init())) { + LOG_WARN("failed to init transfer info", K(ret), K(tablet_meta_)); + } else { + tablet_meta_.mds_checkpoint_scn_ = tablet_meta_.clog_checkpoint_scn_; + LOG_INFO("succeeded to build mds data", K(ret), "ls_id", tablet_meta_.ls_id_, "tablet_id", tablet_meta_.tablet_id_, K(mds_data_)); + } + + if (FAILEDx(build_read_info(allocator))) { + LOG_WARN("failed to build read info", K(ret)); + } else if (OB_FAIL(pull_memtables())) { + LOG_WARN("fail to pull memtable", K(ret), K(len), K(new_pos)); + } else { + set_mem_addr(); + mds_data_.set_mem_addr(); + version_ = TABLET_VERSION_V2; + } + return ret; +} + +int ObTablet::deserialize_meta_v1( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + int64_t &pos, + ObTabletAutoincSeq &auto_inc_seq, + ObTabletTxMultiSourceDataUnit &tx_data, + ObTabletBindingInfo &ddl_data) +{ + int ret = OB_SUCCESS; + + int64_t new_pos = pos; + if (OB_ISNULL(buf) + || OB_UNLIKELY(len <= 0) + || OB_UNLIKELY(pos < 0) + || OB_UNLIKELY(len <= pos)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(buf), K(len), K(pos)); + } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, &tablet_meta_.version_))) { + LOG_WARN("failed to deserialize tablet meta's version", K(ret), K(len), K(new_pos)); + } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, &tablet_meta_.length_))) { + LOG_WARN("failed to deserialize tablet meta's length", K(ret), K(len), K(new_pos)); + } else if (tablet_meta_.TABLET_META_VERSION == tablet_meta_.version_) { + int8_t compat_mode = -1; + tablet_meta_.ddl_execution_id_ = 0; + if (OB_UNLIKELY(tablet_meta_.length_ > len - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer's length is not enough", K(ret), K(tablet_meta_.length_), K(len - new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.ls_id_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ls id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.tablet_id_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize tablet id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.data_tablet_id_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize data tablet id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.ref_tablet_id_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ref tablet id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(serialization::decode_bool(buf, len, new_pos, &tablet_meta_.has_next_tablet_))) { + LOG_WARN("failed to deserialize has_next_tablet_", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.create_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize create scn", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.start_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize start scn", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.clog_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize clog checkpoint ts", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.ddl_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ddl checkpoint ts", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &tablet_meta_.snapshot_version_))) { + LOG_WARN("failed to deserialize snapshot version", K(ret), K(len)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &tablet_meta_.multi_version_start_))) { + LOG_WARN("failed to deserialize multi version start", K(ret), K(len)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(serialization::decode_i8(buf, len, new_pos, &compat_mode))) { + LOG_WARN("failed to deserialize compat mode", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(auto_inc_seq.deserialize(allocator, buf, len, new_pos))) { // get autoinc seq + LOG_WARN("failed to deserialize auto inc seq", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.ha_status_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize restore status", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.report_status_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize report status", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tx_data.deserialize(buf, len, new_pos))) { // get tx data + LOG_WARN("failed to deserialize multi source data", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(ddl_data.deserialize(buf, len, new_pos))) { // get ddl data + LOG_WARN("failed to deserialize ddl data", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.table_store_flag_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize table store flag", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.ddl_start_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ddl start log ts", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &tablet_meta_.ddl_snapshot_version_))) { + LOG_WARN("failed to deserialize ddl snapshot version", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &tablet_meta_.max_sync_storage_schema_version_))) { + LOG_WARN("failed to deserialize max_sync_storage_schema_version", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &tablet_meta_.ddl_execution_id_))) { + LOG_WARN("failed to deserialize ddl execution id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &tablet_meta_.ddl_data_format_version_))) { + LOG_WARN("failed to deserialize ddl cluster version", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &tablet_meta_.max_serialized_medium_scn_))) { + LOG_WARN("failed to deserialize max serialized medium scn", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.ddl_commit_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ddl commit scn", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < tablet_meta_.length_ && OB_FAIL(tablet_meta_.mds_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize mds checkpoint scn", K(ret), K(len), K(new_pos)); + } else if (OB_UNLIKELY(tablet_meta_.length_ != new_pos - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K_(tablet_meta_.length)); + } else { + pos = new_pos; + tablet_meta_.compat_mode_ = static_cast(compat_mode); + tablet_meta_.is_inited_ = true; + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid version", K(ret), K_(tablet_meta_.version)); + } + + return ret; + +} + +int ObTablet::load_deserialize_v2( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + const int64_t pos, + int64_t &new_pos, + const bool prepare_memtable) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, rowkey_read_info_))) { + LOG_WARN("fail to allocate and new rowkey read info", K(ret)); + } else if (new_pos - pos < length_ && OB_FAIL(tablet_meta_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize tablet meta", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(table_store_addr_.addr_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize table store addr", K(ret), K(len), K(new_pos)); + } else if (FALSE_IT(table_store_addr_.addr_.set_seq(tablet_addr_.seq()))) { + } else if (new_pos - pos < length_ && OB_FAIL(storage_schema_addr_.addr_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize storage schema addr", K(ret), K(len), K(new_pos)); + } else if (!is_empty_shell() && new_pos - pos < length_ && OB_FAIL(rowkey_read_info_->deserialize(allocator, buf, len, new_pos))) { + LOG_WARN("fail to deserialize rowkey read info", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(mds_data_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize mds data", K(ret), K(len), K(new_pos)); + } else if (prepare_memtable && OB_FAIL(pull_memtables())) { + LOG_WARN("fail to pull memtable", K(ret), K(len), K(new_pos)); + } else { + if (!table_store_addr_.addr_.is_none()) { + IO_AND_DESERIALIZE(allocator, table_store_addr_.addr_, table_store_addr_.ptr_, *this); + if (FAILEDx(table_store_addr_.ptr_->batch_cache_sstable_meta(allocator, INT64_MAX))) {// cache all + LOG_WARN("fail to cache all of sstable", K(ret), KPC(table_store_addr_.ptr_)); + } + } else { + ALLOC_AND_INIT(allocator, table_store_addr_, (*this)); + } + } + return ret; +} + +int ObTablet::deserialize( + const char *buf, + const int64_t len, + int64_t &pos) +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + char* tablet_buf = reinterpret_cast(this); + ObMetaObjBufferHeader &buf_header = ObMetaObjBufferHelper::get_buffer_header(tablet_buf); + int64_t remain = buf_header.buf_len_ - sizeof(ObTablet); + int64_t start_pos = sizeof(ObTablet); + ObArenaAllocator allocator; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("cannot deserialize inited tablet meta", K(ret), K_(is_inited)); + } else if (OB_ISNULL(buf) + || OB_UNLIKELY(len <= 0) + || OB_UNLIKELY(pos < 0) + || OB_UNLIKELY(len <= pos)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(buf), K(len), K(pos)); + } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, (int32_t *)&version_))) { + LOG_WARN("failed to deserialize tablet meta's version", K(ret), K(len), K(new_pos)); + } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, (int32_t *)&length_))) { + LOG_WARN("failed to deserialize tablet meta's length", K(ret), K(len), K(new_pos)); + } else if (TABLET_VERSION_V2 != version_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid version", K(ret), K_(version)); + } else { + if (OB_UNLIKELY(length_ > len - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer's length is not enough", K(ret), K(length_), K(len - new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(tablet_meta_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize tablet meta", K(ret), K(len), K(new_pos)); + } else if (OB_FAIL(pull_memtables())) { + LOG_WARN("fail to pull memtable", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(table_store_addr_.addr_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize table read info addr", K(ret), K(len), K(new_pos)); + } else if (FALSE_IT(table_store_addr_.addr_.set_seq(tablet_addr_.seq()))) { + } else if (new_pos - pos < length_ && OB_FAIL(storage_schema_addr_.addr_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize table store addr", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && !table_store_addr_.addr_.is_none()) { + ObRowkeyReadInfo *rowkey_read_info = nullptr; + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, rowkey_read_info))) { + LOG_WARN("fail to deserialize rowkey read info", K(ret), K(len), K(new_pos)); + } else if (OB_FAIL(rowkey_read_info->deserialize(allocator, buf, len, new_pos))) { + LOG_WARN("fail to deserialize rowkey read info", K(ret), K(len), K(new_pos)); + } else if (remain < rowkey_read_info->get_deep_copy_size()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet memory buffer not enough for rowkey read info", K(ret), K(remain), K(rowkey_read_info->get_deep_copy_size())); + } else if (OB_FAIL(rowkey_read_info->deep_copy( + tablet_buf + start_pos, remain, rowkey_read_info_))) { + LOG_WARN("fail to deep copy rowkey read info to tablet", K(ret), KPC(rowkey_read_info), K(remain)); + } else if (OB_ISNULL(rowkey_read_info_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr for rowkey read info deep copy", K(ret)); + } else { + remain -= rowkey_read_info_->get_deep_copy_size(); + start_pos += rowkey_read_info_->get_deep_copy_size(); + } + } + + if (OB_SUCC(ret)) { + if (new_pos - pos < length_ && OB_FAIL(mds_data_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize mds data", K(ret), K(len), K(new_pos)); + } + } + if (OB_SUCC(ret)) { + ObTabletTableStore *table_store = nullptr; + if (table_store_addr_.addr_.is_none()) { + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, table_store))) { + LOG_WARN("failed to alloc and new table store"); + } else if (OB_FAIL(table_store->init(allocator, *this))) { + LOG_WARN("failed to init table store"); + } + } else { + IO_AND_DESERIALIZE(allocator, table_store_addr_.addr_, table_store, *this); + } + if (OB_SUCC(ret)) { + int64_t table_store_size = table_store->get_deep_copy_size(); + ObIStorageMetaObj *table_store_obj = nullptr; + if (remain < table_store_size) { + LOG_INFO("tablet memory buffer not enough for table store", K(ret), K(remain), K(table_store_size)); + } else if (OB_FAIL(table_store->batch_cache_sstable_meta(allocator, remain - table_store_size))) { + LOG_WARN("fail to batch cache sstable meta", K(ret), K(remain), K(table_store_size)); + } else if (FALSE_IT(table_store_size = table_store->get_deep_copy_size())) { // re-get deep size + } else if (OB_FAIL(table_store->deep_copy(tablet_buf + start_pos, remain, table_store_obj))) { + LOG_WARN("fail to deep copy table store to tablet", K(ret), KPC(table_store)); + } else if (OB_ISNULL(table_store_obj)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr for table store deep copy", K(ret)); + } else { + table_store_addr_.ptr_ = static_cast(table_store_obj); + remain -= table_store_size; + start_pos += table_store_size; + } + } + } + + if (OB_SUCC(ret)) { + ObTabletAutoincSeq *auto_inc_seq = nullptr; + if (mds_data_.auto_inc_seq_.addr_.is_none()) { + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, auto_inc_seq))) { + LOG_WARN("fail to allocate and new rowkey read info", K(ret)); + } + } else { + IO_AND_DESERIALIZE(allocator, mds_data_.auto_inc_seq_.addr_, auto_inc_seq); + } + if (OB_SUCC(ret)) { + const int auto_inc_seq_size = auto_inc_seq->get_deep_copy_size(); + ObIStorageMetaObj *auto_inc_seq_obj = nullptr; + if (OB_UNLIKELY(remain < auto_inc_seq_size)) { + LOG_INFO("tablet memory buffer not enough for auto inc seq", K(ret), K(remain), K(auto_inc_seq_size)); + } else if (OB_FAIL(auto_inc_seq->deep_copy( + tablet_buf + start_pos, remain, auto_inc_seq_obj))) { + LOG_WARN("fail to deep copy auto inc seq to tablet", K(ret), KPC(auto_inc_seq)); + } else if (OB_ISNULL(auto_inc_seq_obj)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr for auto inc seq deep copy", K(ret)); + } else { + mds_data_.auto_inc_seq_.ptr_ = static_cast(auto_inc_seq_obj); + remain -= auto_inc_seq_size; + start_pos += auto_inc_seq_size; + } + } + } + + if (OB_SUCC(ret) && tablet_meta_.has_next_tablet_) { + ObTabletHandle next_tablet_handle; + const ObTabletMapKey key(tablet_meta_.ls_id_, tablet_meta_.tablet_id_); + if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet_from_pool(ObTabletPoolType::TP_NORMAL, key, next_tablet_handle))) { + LOG_WARN("failed to acquire tablet", K(ret), K(key)); + } else if (OB_ISNULL(next_tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("next tablet is null", K(ret)); + } else if (FALSE_IT(next_tablet_handle.get_obj()->set_tablet_addr(tablet_addr_))) { + } else if (OB_FAIL(next_tablet_handle.get_obj()->deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize next tablet", K(ret), K(len), K(new_pos)); + } else { + set_next_tablet_guard(next_tablet_handle); + } + } + + if (OB_SUCC(ret)) { + pos = new_pos; + is_inited_ = true; + // must succeed if hold_ref_cnt_ has been set to true + hold_ref_cnt_ = true; + LOG_INFO("succeed to load deserialize tablet", K(ret), KPC(this)); + } + } + if (OB_UNLIKELY(!is_inited_)) { + reset(); + } + return ret; +} + +int ObTablet::get_tablet_meta_ids(ObIArray &meta_ids) const +{ + int ret = OB_SUCCESS; + const ObMetaDiskAddr &tablet_status_uncommitted_kv_addr = mds_data_.tablet_status_.uncommitted_kv_.addr_; + const ObMetaDiskAddr &tablet_status_committed_kv_addr = mds_data_.tablet_status_.committed_kv_.addr_; + const ObMetaDiskAddr &aux_tablet_info_uncommitted_kv_addr = mds_data_.aux_tablet_info_.uncommitted_kv_.addr_; + const ObMetaDiskAddr &aux_tablet_info_committed_kv_addr = mds_data_.aux_tablet_info_.committed_kv_.addr_; + const ObMetaDiskAddr &medium_info_list_addr = mds_data_.medium_info_list_.addr_; + const ObMetaDiskAddr &auto_inc_seq_addr = mds_data_.auto_inc_seq_.addr_; + + if (OB_UNLIKELY(tablet_meta_.has_next_tablet_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("shouldn't have next tablet", K(ret), K(tablet_meta_), K(next_tablet_guard_)); + } else if (OB_FAIL(parse_meta_addr(tablet_addr_, meta_ids))) { + LOG_WARN("fail to parse tablet addr", K(ret), K(tablet_addr_)); + } else if (OB_FAIL(parse_meta_addr(table_store_addr_.addr_, meta_ids))) { + LOG_WARN("fail to parse table store addr", K(ret), K(table_store_addr_.addr_)); + } else if (OB_FAIL(parse_meta_addr(storage_schema_addr_.addr_, meta_ids))) { + LOG_WARN("fail to parse storage schema addr", K(ret), K(storage_schema_addr_.addr_)); + } else if (OB_FAIL(parse_meta_addr(tablet_status_uncommitted_kv_addr, meta_ids))) { + LOG_WARN("fail to parse tablet_status_uncommitted_kv_addr", K(ret), K(tablet_status_uncommitted_kv_addr)); + } else if (OB_FAIL(parse_meta_addr(tablet_status_committed_kv_addr, meta_ids))) { + LOG_WARN("fail to parse tablet_status_committed_kv_addr", K(ret), K(tablet_status_committed_kv_addr)); + } else if (OB_FAIL(parse_meta_addr(aux_tablet_info_uncommitted_kv_addr, meta_ids))) { + LOG_WARN("fail to parse aux_tablet_info_uncommitted_kv_addr", K(ret), K(aux_tablet_info_uncommitted_kv_addr)); + } else if (OB_FAIL(parse_meta_addr(aux_tablet_info_committed_kv_addr, meta_ids))) { + LOG_WARN("fail to parse aux_tablet_info_committed_kv_addr", K(ret), K(aux_tablet_info_committed_kv_addr)); + } else if (OB_FAIL(parse_meta_addr(medium_info_list_addr, meta_ids))) { + LOG_WARN("fail to parse medium_info_list_addr", K(ret), K(medium_info_list_addr)); + } else if (OB_FAIL(parse_meta_addr(auto_inc_seq_addr, meta_ids))) { + LOG_WARN("fail to parse auto_inc_seq_addr", K(ret), K(auto_inc_seq_addr)); + } + return ret; +} + +int ObTablet::parse_meta_addr(const ObMetaDiskAddr &addr, ObIArray &meta_ids) +{ + int ret = OB_SUCCESS; + MacroBlockId macro_id; + if (addr.is_block()) { + if (OB_UNLIKELY(!addr.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet_status_uncommitted_kv_addr is invalid", K(ret), K(addr)); + } else if (FALSE_IT(macro_id = addr.block_id())) { + } else if (OB_FAIL(meta_ids.push_back(macro_id))) { + LOG_WARN("fail to push back macro id", K(ret), K(macro_id)); + } + } + return ret; +} + +int ObTablet::inc_macro_ref_cnt() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("tablet hasn't been inited", K(ret), K(is_inited_)); + } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { + LOG_WARN("fail to increase macro ref cnt", K(ret)); + } else if (tablet_meta_.has_next_tablet_ + && OB_FAIL(next_tablet_guard_.get_obj()->inc_macro_ref_cnt())) { + LOG_WARN("fail to increase macro ref cnt for next tablet", + K(ret), KPC(next_tablet_guard_.get_obj())); + } + return ret; +} + +int ObTablet::inner_inc_macro_ref_cnt() +{ + int ret = OB_SUCCESS; + bool inc_table_store_ref = false; + bool inc_storage_schema_ref = false; + bool inc_medium_info_list_ref = false; + bool inc_tablet_ref = false; + bool inc_table_store_member_ref = false; + bool inc_sstable_meta_ref = false; + bool inc_tablet_status_uncommitted_kv_ref = false; + bool inc_tablet_status_committed_kv_ref = false; + bool inc_aux_tablet_info_uncommitted_kv_ref = false; + bool inc_aux_tablet_info_committed_kv_ref = false; + bool inc_auto_inc_ref = false; + + const ObTabletComplexAddr &tablet_status_uncommitted_kv_addr = mds_data_.tablet_status_.uncommitted_kv_; + const ObTabletComplexAddr &tablet_status_committed_kv_addr = mds_data_.tablet_status_.committed_kv_; + const ObTabletComplexAddr &aux_tablet_info_uncommitted_kv_addr = mds_data_.aux_tablet_info_.uncommitted_kv_; + const ObTabletComplexAddr &aux_tablet_info_committed_kv_addr = mds_data_.aux_tablet_info_.committed_kv_; + const ObTabletComplexAddr &medium_info_list_addr = mds_data_.medium_info_list_; + const ObTabletComplexAddr &auto_inc_seq_addr = mds_data_.auto_inc_seq_; + + if (OB_FAIL(check_meta_addr())) { + LOG_WARN("fail to check meta addrs", K(ret)); + } else if (OB_FAIL(inc_addr_ref_cnt(table_store_addr_.addr_, inc_table_store_ref))) { + LOG_WARN("fail to increase macro blocks' ref cnt for table store", K(ret), K(table_store_addr_.addr_)); + } else if (OB_FAIL(inc_addr_ref_cnt(storage_schema_addr_.addr_, inc_storage_schema_ref))) { + LOG_WARN("fail to increase macro blocks' ref cnt for storage schema", K(ret), K(storage_schema_addr_.addr_)); + } else if (OB_FAIL(inc_addr_ref_cnt(tablet_status_uncommitted_kv_addr.addr_, inc_tablet_status_uncommitted_kv_ref))) { + LOG_WARN("fail to increase macro blocks' ref cnt for tablet status uncommitted kv", K(ret), K(tablet_status_uncommitted_kv_addr.addr_)); + } else if (OB_FAIL(inc_addr_ref_cnt(tablet_status_committed_kv_addr.addr_, inc_tablet_status_committed_kv_ref))) { + LOG_WARN("fail to increase macro blocks' ref cnt for tablet status committed kv", K(ret), K(tablet_status_committed_kv_addr.addr_)); + } else if (OB_FAIL(inc_addr_ref_cnt(aux_tablet_info_uncommitted_kv_addr.addr_, inc_aux_tablet_info_uncommitted_kv_ref))) { + LOG_WARN("fail to increase macro blocks' ref cnt for aux tablet info uncommitted kv", K(ret), K(aux_tablet_info_uncommitted_kv_addr.addr_)); + } else if (OB_FAIL(inc_addr_ref_cnt(aux_tablet_info_committed_kv_addr.addr_, inc_aux_tablet_info_committed_kv_ref))) { + LOG_WARN("fail to increase macro blocks' ref cnt for aux tablet info committed kv", K(ret), K(aux_tablet_info_committed_kv_addr.addr_)); + } else if (OB_FAIL(inc_addr_ref_cnt(medium_info_list_addr.addr_, inc_medium_info_list_ref))) { + LOG_WARN("fail to increase macro blocks' ref cnt for medium info list", K(ret), K(medium_info_list_addr)); + } else if (OB_FAIL(inc_addr_ref_cnt(auto_inc_seq_addr.addr_, inc_auto_inc_ref))) { + LOG_WARN("fail to increase macro blocks' ref cnt for auto inc seq", K(ret), K(auto_inc_seq_addr.addr_)); + } else if (OB_FAIL(inc_addr_ref_cnt(tablet_addr_, inc_tablet_ref))) { + LOG_WARN("fail to increase macro blocks' ref cnt for 4k tablet", K(ret), K(tablet_addr_)); + } else if (OB_FAIL(inc_table_store_ref_cnt(inc_table_store_member_ref))) { + LOG_WARN("fail to increase macro blocks' ref cnt for sstable meta", K(ret)); + } else { + hold_ref_cnt_ = true; + } + FLOG_INFO("barry debug the tablet that inner increases ref cnt is", + K(is_inited_), K(tablet_meta_.ls_id_), K(tablet_meta_.tablet_id_), K(table_store_addr_.addr_.is_valid()), + K(auto_inc_seq_addr.addr_), K(storage_schema_addr_.addr_), K(medium_info_list_addr.addr_), + K(tablet_status_uncommitted_kv_addr.addr_), K(tablet_status_committed_kv_addr.addr_), + K(aux_tablet_info_uncommitted_kv_addr.addr_), K(aux_tablet_info_committed_kv_addr.addr_), + K(tablet_addr_), KP(this), K(lbt())); + + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + if (inc_table_store_ref) { + dec_addr_ref_cnt(table_store_addr_.addr_); + } + if (inc_storage_schema_ref) { + dec_addr_ref_cnt(storage_schema_addr_.addr_); + } + if (inc_medium_info_list_ref) { + dec_addr_ref_cnt(medium_info_list_addr.addr_); + } + if (inc_tablet_status_uncommitted_kv_ref) { + dec_addr_ref_cnt(tablet_status_uncommitted_kv_addr.addr_); + } + if (inc_tablet_status_committed_kv_ref) { + dec_addr_ref_cnt(tablet_status_committed_kv_addr.addr_); + } + if (inc_aux_tablet_info_uncommitted_kv_ref) { + dec_addr_ref_cnt(aux_tablet_info_uncommitted_kv_addr.addr_); + } + if (inc_aux_tablet_info_committed_kv_ref) { + dec_addr_ref_cnt(aux_tablet_info_committed_kv_addr.addr_); + } + if (inc_auto_inc_ref) { + dec_addr_ref_cnt(auto_inc_seq_addr.addr_); + } + if (inc_tablet_ref) { + dec_addr_ref_cnt(tablet_addr_); + } + if (inc_table_store_member_ref) { + dec_table_store_ref_cnt(); + } + } + return ret; +} + +void ObTablet::dec_macro_ref_cnt() +{ + int ret = OB_SUCCESS; + const ObTabletComplexAddr &tablet_status_uncommitted_kv_addr = mds_data_.tablet_status_.uncommitted_kv_; + const ObTabletComplexAddr &tablet_status_committed_kv_addr = mds_data_.tablet_status_.committed_kv_; + const ObTabletComplexAddr &aux_tablet_info_uncommitted_kv_addr = mds_data_.aux_tablet_info_.uncommitted_kv_; + const ObTabletComplexAddr &aux_tablet_info_committed_kv_addr = mds_data_.aux_tablet_info_.committed_kv_; + const ObTabletComplexAddr &medium_info_list_addr = mds_data_.medium_info_list_; + const ObTabletComplexAddr &auto_inc_seq_addr = mds_data_.auto_inc_seq_; + // We don't need to recursively decrease macro ref cnt, since we will push both them to gc queue + FLOG_INFO("barry debug the tablet that decreases ref cnt is", + K(is_inited_), K(tablet_meta_.ls_id_), K(tablet_meta_.tablet_id_), K(table_store_addr_.addr_.is_valid()), + K(auto_inc_seq_addr.addr_), K(storage_schema_addr_.addr_), K(medium_info_list_addr.addr_), + K(tablet_status_uncommitted_kv_addr.addr_), K(tablet_status_committed_kv_addr.addr_), + K(aux_tablet_info_uncommitted_kv_addr.addr_), K(aux_tablet_info_committed_kv_addr.addr_), + K(tablet_addr_), KP(this), K(lbt())); + if (OB_UNLIKELY(!hold_ref_cnt_)) { + FLOG_INFO("tablet doesn't hold ref cnt, no need to dec ref cnt", + K(is_inited_), K(tablet_meta_.ls_id_), K(tablet_meta_.tablet_id_), K(table_store_addr_.addr_.is_valid()), + K(auto_inc_seq_addr.addr_), K(storage_schema_addr_.addr_), K(medium_info_list_addr.addr_), + K(tablet_status_uncommitted_kv_addr.addr_), K(tablet_status_committed_kv_addr.addr_), + K(aux_tablet_info_uncommitted_kv_addr.addr_), K(aux_tablet_info_committed_kv_addr.addr_), + K(tablet_addr_), KP(this), K(lbt())); + } else if (OB_FAIL(check_meta_addr())) { + LOG_WARN("fail to check meta addrs", K(ret)); + } else { + // the order can't be changed, must be sstable blocks' ref cnt -> tablet meta blocks' ref cnt + dec_table_store_ref_cnt(); + dec_addr_ref_cnt(table_store_addr_.addr_); + dec_addr_ref_cnt(storage_schema_addr_.addr_); + dec_addr_ref_cnt(tablet_status_uncommitted_kv_addr.addr_); + dec_addr_ref_cnt(tablet_status_committed_kv_addr.addr_); + dec_addr_ref_cnt(aux_tablet_info_uncommitted_kv_addr.addr_); + dec_addr_ref_cnt(aux_tablet_info_committed_kv_addr.addr_); + dec_addr_ref_cnt(medium_info_list_addr.addr_); + dec_addr_ref_cnt(auto_inc_seq_addr.addr_); + dec_addr_ref_cnt(tablet_addr_); + } +} + +int ObTablet::inc_table_store_ref_cnt(bool &inc_success) +{ + int ret = OB_SUCCESS; + inc_success = false; + ObTabletMemberWrapper table_store_wrapper; + + if (table_store_addr_.addr_.is_none()) { + // skip empty shell + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->inc_macro_ref())) { + LOG_WARN("fail to increase sstables' ref cnt", + K(ret), K(table_store_wrapper), K(table_store_addr_.addr_)); + } else { + inc_success = true; + } + return ret; +} + +void ObTablet::dec_table_store_ref_cnt() +{ + int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + if (table_store_addr_.addr_.is_none()) { + // skip empty shell + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else { + table_store_wrapper.get_member()->dec_macro_ref(); + } +} + +int ObTablet::inc_addr_ref_cnt(const ObMetaDiskAddr &addr, bool &inc_success) +{ + int ret = OB_SUCCESS; + inc_success = false; + MacroBlockId macro_id; + int64_t offset; + int64_t size; + if (addr.is_block()) { // skip full/old/empty_shell tablet + if (OB_FAIL(addr.get_block_addr(macro_id, offset, size))) { + LOG_WARN("fail to get macro id from addr", K(ret), K(addr)); + } else if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(macro_id))) { + LOG_ERROR("fail to increase macro block's ref cnt", K(ret), K(macro_id)); + } else { + inc_success = true; + } + } + return ret; +} + +void ObTablet::dec_addr_ref_cnt(const ObMetaDiskAddr &addr) +{ + int ret = OB_SUCCESS; + MacroBlockId macro_id; + int64_t offset; + int64_t size; + if (addr.is_block()) { // skip full/old/empty_shell tablet + if (OB_FAIL(addr.get_block_addr(macro_id, offset, size))) { + LOG_ERROR("fail to get macro id from addr", K(ret), K(addr)); + } else if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(macro_id))) { + LOG_ERROR("fail to decrease macro block's ref cnt", K(ret), K(macro_id)); + } + } +} + +void ObTablet::set_mem_addr() +{ + if (!table_store_addr_.addr_.is_none() && !storage_schema_addr_.addr_.is_none()) { + table_store_addr_.addr_.set_mem_addr(0, sizeof(ObTabletTableStore)); + storage_schema_addr_.addr_.set_mem_addr(0, sizeof(ObStorageSchema)); + } + tablet_addr_.set_mem_addr(0, sizeof(ObTablet)); +} + +int ObTablet::check_meta_addr() const +{ + int ret = OB_SUCCESS; + const ObTabletComplexAddr &tablet_status_uncommitted_kv_addr = mds_data_.tablet_status_.uncommitted_kv_; + const ObTabletComplexAddr &tablet_status_committed_kv_addr = mds_data_.tablet_status_.committed_kv_; + const ObTabletComplexAddr &aux_tablet_info_uncommitted_kv_addr = mds_data_.aux_tablet_info_.uncommitted_kv_; + const ObTabletComplexAddr &aux_tablet_info_committed_kv_addr = mds_data_.aux_tablet_info_.committed_kv_; + const ObTabletComplexAddr &medium_info_list_addr = mds_data_.medium_info_list_; + const ObTabletComplexAddr &auto_inc_seq_addr = mds_data_.auto_inc_seq_; + + if (OB_UNLIKELY(!table_store_addr_.addr_.is_valid() || !auto_inc_seq_addr.addr_.is_valid() + || !storage_schema_addr_.addr_.is_valid() || !medium_info_list_addr.addr_.is_valid() + || !tablet_addr_.is_valid() || !tablet_status_uncommitted_kv_addr.is_valid() + || !tablet_status_committed_kv_addr.is_valid() || !aux_tablet_info_uncommitted_kv_addr.is_valid() + || !aux_tablet_info_committed_kv_addr.is_valid())) + { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("meta addrs are invalid", K(ret), K(tablet_addr_), K(table_store_addr_.addr_), + K(auto_inc_seq_addr.addr_), K(storage_schema_addr_.addr_), K(medium_info_list_addr.addr_), + K(tablet_status_uncommitted_kv_addr.addr_), K(tablet_status_committed_kv_addr.addr_), + K(aux_tablet_info_uncommitted_kv_addr.addr_), K(aux_tablet_info_committed_kv_addr.addr_)); + } else if (((tablet_addr_.is_block() ^ table_store_addr_.addr_.is_block()) + || (tablet_addr_.is_block() ^ storage_schema_addr_.addr_.is_block())) + && ((tablet_addr_.is_block() ^ table_store_addr_.addr_.is_none()) + || (tablet_addr_.is_block() ^ storage_schema_addr_.addr_.is_none()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("meta addrs are inconsistent", + K(ret), K(tablet_addr_), K(table_store_addr_.addr_), K(storage_schema_addr_.addr_)); + } + + return ret; +} + int ObTablet::get_multi_version_start(SCN &scn) const { int ret = OB_SUCCESS; @@ -789,20 +1834,31 @@ int64_t ObTablet::get_serialize_size() const int64_t ObTablet::get_self_size() const { - int64_t size = 0; + int64_t size =0; size += serialization::encoded_length_i32(version_); size += serialization::encoded_length_i32(length_); size += tablet_meta_.get_serialize_size(); - size += table_store_.get_serialize_size(); - size += storage_schema_.get_serialize_size(); - size += medium_info_list_.get_serialize_size(); + size += storage_schema_addr_.addr_.get_serialize_size(); + size += table_store_addr_.addr_.get_serialize_size(); + size += is_empty_shell() ? 0 : rowkey_read_info_->get_serialize_size(); + size += mds_data_.get_serialize_size(); return size; } -void ObTablet::set_next_tablet_guard(const ObMetaObjGuard &next_tablet_guard) +void ObTablet::set_next_tablet_guard(const ObTabletHandle &next_tablet_guard) { - tablet_meta_.has_next_tablet_ = true; - next_tablet_guard_ = next_tablet_guard; + if (OB_UNLIKELY(next_tablet_guard.is_valid())) { + int ret = OB_NOT_SUPPORTED; + LOG_ERROR("shouldn't have next tablet", K(ret), KPC(this)); + } +} + +void ObTablet::set_tablet_addr(const ObMetaDiskAddr &tablet_addr) +{ + tablet_addr_ = tablet_addr; + if (tablet_meta_.has_next_tablet_ && next_tablet_guard_.is_valid()) { + next_tablet_guard_.get_obj()->set_tablet_addr(tablet_addr); + } } void ObTablet::trim_tablet_list() @@ -812,10 +1868,10 @@ void ObTablet::trim_tablet_list() } int ObTablet::deserialize_id( - const char *buf, - const int64_t len, - share::ObLSID &ls_id, - common::ObTabletID &tablet_id) + const char *buf, + const int64_t len, + share::ObLSID &ls_id, + common::ObTabletID &tablet_id) { int ret = OB_SUCCESS; int32_t version = 0; @@ -825,9 +1881,10 @@ int ObTablet::deserialize_id( LOG_WARN("fail to deserialize tablet meta's version", K(ret), K(len), K(pos)); } else if (OB_FAIL(serialization::decode_i32(buf, len, pos, (int32_t *)&length))) { LOG_WARN("fail to deserialize tablet meta's length", K(ret), K(len), K(pos)); - } else if (TABLET_VERSION == version && - OB_FAIL(ObTabletMeta::deserialize_id(buf, len, pos, ls_id, tablet_id))) { - LOG_WARN("fail to deserialize ls_id and tablet_id from tablet meta", K(ret), K(len)); + } else if (TABLET_VERSION == version || TABLET_VERSION_V2 == version) { + if (OB_FAIL(ObTabletMeta::deserialize_id(buf, len, pos, ls_id, tablet_id))) { + LOG_WARN("fail to deserialize ls_id and tablet_id from tablet meta", K(ret), K(len)); + } } return ret; @@ -895,6 +1952,7 @@ int ObTablet::try_update_storage_schema( return ret; } +// be careful to use this max_schem_version on storage_schema int ObTablet::get_max_schema_version(int64_t &schema_version) { int ret = OB_SUCCESS; @@ -926,26 +1984,6 @@ int ObTablet::get_max_schema_version(int64_t &schema_version) return ret; } -int ObTablet::pre_transform_sstable_root_block(const ObTableReadInfo &index_read_info) -{ - int ret = OB_SUCCESS; - ObSEArray sstables; - if (OB_FAIL(inner_get_all_sstables(sstables))) { - LOG_WARN("fail to get all sstables", K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < sstables.count(); i++) { - ObSSTable *sstable = static_cast(sstables.at(i)); - if (OB_ISNULL(sstable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, sstable is nullptr", K(ret), KP(sstable)); - } else if (OB_FAIL(sstable->pre_transform_root_block(index_read_info))) { - LOG_WARN("fail to pre-transform sstable root block", K(ret), KPC(sstable)); - } - } - } - return ret; -} - int ObTablet::check_schema_version_for_bounded_staleness_read( const int64_t table_version_for_read, const int64_t data_max_schema_version, @@ -1040,12 +2078,17 @@ int ObTablet::lock_row( LOG_WARN("fail to protect table", K(ret), "tablet_id", tablet_meta_.tablet_id_); } if (OB_SUCC(ret)) { + ObArenaAllocator allocator(ObModIds::OB_STORE_ROW_LOCK_CHECKER); ObMemtable *write_memtable = nullptr; + ObTableIterParam param; + ObTableAccessContext context; + if (OB_FAIL(prepare_memtable(relative_table, store_ctx, write_memtable))) { LOG_WARN("prepare write memtable fail", K(ret), K(relative_table)); - } else if (OB_FAIL(write_memtable->lock(store_ctx, relative_table.get_table_id(), - full_read_info_, row))) { - LOG_WARN("failed to lock write_memtable", K(ret), K_(full_read_info), K(row)); + } else if (OB_FAIL(prepare_param_ctx(allocator, relative_table, store_ctx, param, context))) { + LOG_WARN("prepare param ctx fail, ", K(ret)); + } else if (OB_FAIL(write_memtable->lock(param, context, row))) { + LOG_WARN("failed to lock write_memtable", K(ret), K(row)); } } return ret; @@ -1079,17 +2122,48 @@ int ObTablet::lock_row( } else if (OB_FAIL(guard.refresh_and_protect_table(relative_table))) { LOG_WARN("fail to protect table", K(ret)); } else { - memtable::ObMemtable *write_memtable = nullptr; + ObArenaAllocator allocator(ObModIds::OB_STORE_ROW_LOCK_CHECKER); + ObMemtable *write_memtable = nullptr; + ObTableIterParam param; + ObTableAccessContext context; const uint64_t table_id = relative_table.get_table_id(); + if (OB_FAIL(prepare_memtable(relative_table, store_ctx, write_memtable))) { LOG_WARN("prepare write memtable fail", K(ret), K(relative_table)); - } else if (OB_FAIL(write_memtable->lock(store_ctx, table_id, full_read_info_, rowkey))) { - LOG_WARN("failed to lock write memtable", K(ret), K(table_id), K_(full_read_info), K(rowkey)); + } else if (OB_FAIL(prepare_param_ctx(allocator, relative_table, store_ctx, param, context))) { + LOG_WARN("prepare param context fail, ", K(ret), K(table_id)); + } else if (OB_FAIL(write_memtable->lock(param, context, rowkey))) { + LOG_WARN("failed to lock write memtable", K(ret), K(table_id), K(rowkey)); } } return ret; } + +int ObTablet::check_row_locked_by_myself( + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const blocksstable::ObDatumRowkey &rowkey, + bool &locked) +{ + int ret = OB_SUCCESS; + ObArenaAllocator allocator(ObModIds::OB_STORE_ROW_LOCK_CHECKER); + ObMemtable *write_memtable = nullptr; + ObTableIterParam param; + ObTableAccessContext context; + + if (OB_FAIL(prepare_memtable(relative_table, store_ctx, write_memtable))) { + LOG_WARN("prepare write memtable fail", K(ret), K(relative_table)); + } else if (OB_FAIL(prepare_param_ctx(allocator, relative_table, store_ctx, param, context))) { + LOG_WARN("prepare param context fail, ", K(ret), K(rowkey)); + } else if (OB_FAIL(write_memtable->check_row_locked_by_myself(param, context, rowkey, locked))) { + LOG_WARN("failed to lock write memtable", K(ret), K(rowkey)); + } + + return ret; +} + + int ObTablet::get_read_tables( const int64_t snapshot_version, ObTabletTableIterator &iter, @@ -1101,27 +2175,146 @@ int ObTablet::get_read_tables( LOG_WARN("not inited", K(ret), K_(is_inited)); } else if (OB_FAIL(allow_to_read_())) { LOG_WARN("not allowed to read", K(ret), K(tablet_meta_)); - } else if (OB_UNLIKELY(!iter.tablet_handle_.is_valid() || iter.tablet_handle_.get_obj() != this)) { + } else if (OB_UNLIKELY(!iter.is_valid() || iter.get_tablet() != this)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(iter), K(this)); - } else if (OB_FAIL(get_read_tables(snapshot_version, iter.table_iter_, allow_no_ready_read))) { + } else if (OB_FAIL(auto_get_read_tables(snapshot_version, iter, allow_no_ready_read))) { LOG_WARN("failed to get read tables", K(ret), K(snapshot_version), K(allow_no_ready_read)); } + + return ret; +} + +// TODO (wenjinyu.wjy) need to be moved to ObLSTableService +int ObTablet::get_src_tablet_read_tables_( + const int64_t snapshot_version, + const bool allow_no_ready_read, + ObTabletTableIterator &iter, + bool &succ_get_src_tables) +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + succ_get_src_tables = false; + ObTabletCreateDeleteMdsUserData user_data; + if (OB_UNLIKELY(snapshot_version < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid argument", K(ret), K(snapshot_version)); + } else if (OB_FAIL(ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(tablet), K(user_data)); + } else if (ObTabletStatus::TRANSFER_IN != user_data.tablet_status_) { + ret = OB_SNAPSHOT_DISCARDED; + LOG_WARN("tablet status is not match, need retry", K(ret), K(user_data), "tablet_id", tablet_meta_.tablet_id_); + } else if (!user_data.transfer_ls_id_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table type is unexpected", K(ret), K(user_data)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(user_data.transfer_ls_id_, ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(user_data)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(user_data)); + } else if (OB_FAIL(ls->get_tablet(tablet_meta_.tablet_id_, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_meta_.tablet_id_), K(ls->get_ls_id())); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(user_data)); + } + // TODO (wenjinyu.wjy) need to supplement the continuity check of src and dest tables + if (OB_SUCC(ret)) { + if (OB_ISNULL(iter.table_store_iter_.transfer_src_table_store_handle_)) { + void *meta_hdl_buf = ob_malloc(sizeof(ObStorageMetaHandle), ObMemAttr(MTL_ID(), "TransferMetaH")); + if (OB_ISNULL(meta_hdl_buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocator memory for handles"); + } else { + iter.table_store_iter_.transfer_src_table_store_handle_ = new (meta_hdl_buf) ObStorageMetaHandle(); + } + } + + if (FAILEDx(iter.set_transfer_src_tablet_handle(tablet_handle))) { + LOG_WARN("failed to set transfer src tablet handle", K(ret)); + } else if (OB_FAIL(tablet->get_read_tables_( + snapshot_version, + iter.table_store_iter_, + *(iter.table_store_iter_.transfer_src_table_store_handle_), + allow_no_ready_read))) { + LOG_WARN("failed to get read tables from table store", K(ret), KPC(tablet)); + } else { + succ_get_src_tables = true; + } + } + + return ret; +} + +int ObTablet::auto_get_read_tables( + const int64_t snapshot_version, + ObTabletTableIterator &iter, + const bool allow_no_ready_read) +{ + int ret = OB_SUCCESS; + iter.table_store_iter_.reset(); + bool succ_get_src_tables = false; + if (OB_UNLIKELY(tablet_meta_.has_transfer_table())) { + if (OB_FAIL(get_src_tablet_read_tables_(snapshot_version, allow_no_ready_read, iter, succ_get_src_tables))) { + LOG_WARN("failed to get src ls read tables", K(ret), K(snapshot_version), K(tablet_meta_)); + } + } + if (OB_FAIL(ret)) { + } else { + bool allow_not_ready = succ_get_src_tables ? true : allow_no_ready_read; + if (OB_FAIL(get_read_tables_(snapshot_version, iter.table_store_iter_, iter.table_store_iter_.table_store_handle_, allow_not_ready))) { + LOG_WARN("failed to get read tables from table store", K(ret), K(*this)); + } else if (OB_UNLIKELY(succ_get_src_tables)) { + LOG_DEBUG("succ get read tables", K(iter), K(allow_not_ready), K(snapshot_version), K(tablet_meta_)); // TODO (wenjinyu.wjy) it will be deleted later + } + } return ret; } -int ObTablet::get_read_tables( +int ObTablet::get_read_tables_( const int64_t snapshot_version, ObTableStoreIterator &iter, + ObStorageMetaHandle &table_store_handle, const bool allow_no_ready_read) { - TCRLockGuard guard(table_store_lock_); - return table_store_.get_read_tables(snapshot_version, iter, allow_no_ready_read); + int ret = OB_SUCCESS; + const ObTabletTableStore *table_store = nullptr; + if (OB_UNLIKELY(!table_store_addr_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table store addr", K(ret), K_(table_store_addr)); + } else if (table_store_addr_.is_memory_object()) { + table_store = table_store_addr_.get_ptr(); + } else { + ObStorageMetaKey meta_key(MTL_ID(), table_store_addr_.addr_); + const ObStorageMetaValue *value = nullptr; + if (OB_FAIL(OB_STORE_CACHE.get_storage_meta_cache().get_meta( + ObStorageMetaValue::MetaType::TABLE_STORE, meta_key, table_store_handle, this))) { + LOG_WARN("get meta failed", K(ret), K(meta_key)); + } else if (OB_FAIL(table_store_handle.get_value(value))) { + LOG_WARN("fail to get cache value", K(ret), K(table_store_handle)); + } else if (OB_FAIL(value->get_table_store(table_store))) { + LOG_WARN("fail to get tablet store", K(ret), KPC(value)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(table_store->get_read_tables( + snapshot_version, *this, iter, allow_no_ready_read))) { + LOG_WARN("fail to get read tables", K(ret), K(iter), K(snapshot_version)); + } + } + return ret; } int ObTablet::get_read_major_sstable( const int64_t &major_snapshot_version, - ObTabletTableIterator &iter) + ObTabletTableIterator &iter) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { @@ -1129,10 +2322,10 @@ int ObTablet::get_read_major_sstable( LOG_WARN("not inited", K(ret), K_(is_inited)); } else if (OB_FAIL(allow_to_read_())) { LOG_WARN("not allowed to read", K(ret), K(tablet_meta_)); - } else if (OB_UNLIKELY(!iter.tablet_handle_.is_valid() || iter.tablet_handle_.get_obj() != this)) { + } else if (OB_UNLIKELY(!iter.is_valid() || iter.get_tablet() != this)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(iter), K(this)); - } else if (OB_FAIL(get_read_major_sstable(major_snapshot_version, iter.table_iter_))) { + } else if (OB_FAIL(get_read_major_sstable(major_snapshot_version, *iter.table_iter()))) { LOG_WARN("failed to get read tables", K(ret), K(major_snapshot_version)); } return ret; @@ -1140,95 +2333,121 @@ int ObTablet::get_read_major_sstable( int ObTablet::get_read_major_sstable( const int64_t &major_snapshot_version, - ObTableStoreIterator &iter) + ObTableStoreIterator &iter) const { - TCRLockGuard guard(table_store_lock_); - return table_store_.get_read_major_sstable(major_snapshot_version, iter); + int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->get_read_major_sstable( + major_snapshot_version, iter))) { + LOG_WARN("fail to get read tables", K(ret), K(table_store_wrapper), K(iter), + K(major_snapshot_version)); + } else if (!table_store_addr_.is_memory_object() + && OB_FAIL(iter.set_handle(table_store_wrapper.get_meta_handle()))) { + LOG_WARN("fail to set storage meta handle", K(ret), K_(table_store_addr), K(table_store_wrapper)); + } + return ret; } int ObTablet::get_ddl_memtables(common::ObIArray &ddl_memtables) const { int ret = OB_SUCCESS; ddl_memtables.reset(); - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else { - const ObSSTableArray &tmp_tables = table_store_.get_ddl_memtables(); - if (!tmp_tables.empty() && OB_FAIL(tmp_tables.get_all_tables(ddl_memtables))) { - LOG_WARN("fail to get ddl memtables", K(ret)); + for (int64_t i = 0; OB_SUCC(ret) && i < ddl_kv_count_; ++i) { + if (OB_ISNULL(ddl_kvs_[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null ddl mem table", K(ret), K(i), KPC(this)); + } else if (OB_FAIL(ddl_memtables.push_back(ddl_kvs_[i]))) { + LOG_WARN("failed to push back ddl memtables", K(ret)); } } return ret; } -int ObTablet::get_all_sstables(common::ObIArray &sstables) const +int ObTablet::get_all_sstables(ObTableStoreIterator &iter) const { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { + if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(inner_get_all_sstables(sstables))) { + } else if (OB_FAIL(inner_get_all_sstables(iter))) { LOG_WARN("fail to get all sstable", K(ret)); } return ret; } -int ObTablet::inner_get_all_sstables(common::ObIArray &sstables) const + +int ObTablet::get_all_tables(ObTableStoreIterator &iter) const { int ret = OB_SUCCESS; - const ObSSTableArray &major_sstables = table_store_.get_major_sstables(); - const ObSSTableArray &minor_sstables = table_store_.get_minor_sstables(); - const ObSSTableArray &ddl_sstables = table_store_.get_ddl_sstables(); - - sstables.reset(); - if (!major_sstables.empty() && OB_FAIL(major_sstables.get_all_tables(sstables))) { - LOG_WARN("fail to get all tables from major sstables", K(ret)); - } else if (!minor_sstables.empty() && OB_FAIL(minor_sstables.get_all_tables(sstables))) { - LOG_WARN("fail to get all tables from minor sstables", K(ret)); - } else if (!ddl_sstables.empty() && OB_FAIL(ddl_sstables.get_all_tables(sstables))) { - LOG_WARN("fail to get all tables from ddl sstables", K(ret)); - } else{ - ObITable *table = nullptr; - for (int64_t i = 0; OB_SUCC(ret) && i < ObTabletTableStore::ExtendTable::EXTEND_CNT; i++) { - if (OB_NOT_NULL(table = table_store_.get_extend_sstable(i))) { - if (OB_FAIL(sstables.push_back(table))) { - LOG_WARN("fail to push back", K(ret), KPC(table)); - } + ObSEArray memtables; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(inner_get_all_sstables(iter))) { + LOG_WARN("fail to get all sstable", K(ret)); + } else if (OB_FAIL(get_memtables(memtables, true))) { + LOG_WARN("fail to get memtables", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < memtables.count(); ++i) { + if (OB_FAIL(iter.add_table(memtables.at(i)))) { + LOG_WARN("fail to add memtable to iter", K(ret), K(memtables), K(iter)); } } } + return ret; +} +int ObTablet::inner_get_all_sstables(ObTableStoreIterator &iter) const +{ + int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->get_all_sstable(iter))) { + LOG_WARN("fail to get all sstables", K(ret), K(table_store_wrapper)); + } else if (!table_store_addr_.is_memory_object() + && OB_FAIL(iter.set_handle(table_store_wrapper.get_meta_handle()))) { + LOG_WARN("fail to set storage meta handle", K(ret), K_(table_store_addr), K(table_store_wrapper)); + } return ret; } int ObTablet::get_sstables_size(int64_t &used_size, const bool ignore_shared_block) const { int ret = OB_SUCCESS; - common::ObSArray sstables; + ObTableStoreIterator table_store_iter; bool multi_version = false; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(get_all_sstables(sstables))) { + } else if (OB_FAIL(get_all_sstables(table_store_iter))) { LOG_WARN("fail to get all sstables", K(ret)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < sstables.count(); i++) { + while (OB_SUCC(ret)) { ObITable *table = nullptr; ObSSTable *sstable = nullptr; - if (OB_ISNULL(table = sstables[i])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("sstable is null", K(ret), K(*this), K(i)); - } else if (FALSE_IT(sstable = static_cast (table))) { + ObSSTableMetaHandle sstable_meta_hdl; + if (OB_FAIL(table_store_iter.get_next(table))) { + if (OB_UNLIKELY(OB_ITER_END == ret)) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("fail to get next table from iter", K(ret), K(table_store_iter)); + } + } else if (FALSE_IT(sstable = static_cast(table))) { + } else if (OB_ISNULL(table)) { + } else if (OB_FAIL(sstable->get_meta(sstable_meta_hdl))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); } else if (sstable->is_small_sstable() && ignore_shared_block) { // skip small sstables } else { - const ObSSTableBasicMeta &basic_meta = sstable->get_meta().get_basic_meta(); if (multi_version && sstable->is_major_sstable()) { - used_size -= basic_meta.get_total_use_old_macro_block_count() * sstable->get_macro_read_size(); + used_size -= sstable_meta_hdl.get_sstable_meta().get_total_use_old_macro_block_count() * sstable->get_macro_read_size(); } else if (sstable->is_major_sstable()) { multi_version = true; } - used_size += basic_meta.get_total_macro_block_count() * sstable->get_macro_read_size(); + used_size += sstable_meta_hdl.get_sstable_meta().get_total_macro_block_count() * sstable->get_macro_read_size(); } } if (OB_SUCC(ret) && tablet_meta_.has_next_tablet_ && OB_FAIL( @@ -1241,8 +2460,8 @@ int ObTablet::get_sstables_size(int64_t &used_size, const bool ignore_shared_blo int ObTablet::get_memtables(common::ObIArray &memtables, const bool need_active) const { - TCRLockGuard guard(table_store_lock_); - return table_store_.get_memtables(memtables, need_active); + TCRLockGuard guard(memtables_lock_); + return inner_get_memtables(memtables, need_active); } int ObTablet::check_need_remove_old_table( @@ -1250,11 +2469,14 @@ int ObTablet::check_need_remove_old_table( bool &need_remove) const { int ret = OB_SUCCESS; - + ObTabletMemberWrapper table_store_wrapper; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(table_store_.need_remove_old_table(multi_version_start, need_remove))) { + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->need_remove_old_table( + multi_version_start, need_remove))) { LOG_WARN("failed to check need rebuild table store", K(ret), K(multi_version_start)); } @@ -1266,43 +2488,53 @@ int ObTablet::update_upper_trans_version(ObLS &ls, bool &is_updated) int ret = OB_SUCCESS; is_updated = false; bool is_paused = false; - + ObTabletMemberWrapper table_store_wrapper; + ObTableStoreIterator iter; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); } else if (FALSE_IT(is_paused = false)) { // TODO(DanLing) get is_paused } else if (is_paused) { LOG_INFO("paused, cannot update trans version now", K(tablet_meta_.tablet_id_)); + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->get_mini_minor_sstables( + true/*is_ha_data_status_complete*/, iter))) { + LOG_WARN("fail to get mini minor sstable", K(ret), K(table_store_wrapper)); } else { - ObSSTableArray &minor_tables = table_store_.get_minor_sstables(); - for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.count(); ++i) { - ObSSTable *sstable = static_cast(minor_tables[i]); - if (OB_ISNULL(sstable)) { + ObITable *table = nullptr; + while (OB_SUCC(ret) && OB_SUCC(iter.get_next(table))) { + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("sstable must not be null", K(ret), K(i), K(minor_tables)); - } else if (INT64_MAX == sstable->get_upper_trans_version()) { - int64_t max_trans_version = INT64_MAX; - SCN tmp_scn = SCN::max_scn(); - if (OB_FAIL(ls.get_upper_trans_version_before_given_scn( - sstable->get_end_scn(), tmp_scn))) { - LOG_WARN("failed to get upper trans version before given log ts", K(ret), KPC(sstable)); - } else if (FALSE_IT(max_trans_version = tmp_scn.get_val_for_tx())) { - } else if (0 == max_trans_version) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("max trans version should not be 0", KPC(sstable)); - } else if (INT64_MAX != max_trans_version) { - if (OB_UNLIKELY(0 == max_trans_version)) { - FLOG_INFO("get max_trans_version = 0, maybe all the trans have been rollbacked", K(max_trans_version), KPC(sstable)); - } - if (OB_FAIL(sstable->set_upper_trans_version(max_trans_version))) { - LOG_WARN("failed to set_upper_trans_version", K(ret), KPC(sstable)); - } else { - is_updated = true; - FLOG_INFO("success to update sstable's upper trans version", K(max_trans_version), KPC(sstable)); + LOG_WARN("unexpected error, table is nullptr", K(ret), KPC(table)); + } else { + ObSSTable *sstable = reinterpret_cast(table); + if (INT64_MAX == sstable->get_upper_trans_version()) { + int64_t max_trans_version = INT64_MAX; + SCN tmp_scn = SCN::max_scn(); + if (OB_FAIL(ls.get_upper_trans_version_before_given_scn(sstable->get_end_scn(), tmp_scn))) { + LOG_WARN("failed to get upper trans version before given log ts", K(ret), KPC(sstable)); + } else if (FALSE_IT(max_trans_version = tmp_scn.get_val_for_tx())) { + } else if (0 == max_trans_version) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("max trans version should not be 0", KPC(sstable)); + } else if (INT64_MAX != max_trans_version) { + if (OB_UNLIKELY(0 == max_trans_version)) { + FLOG_INFO("get max_trans_version = 0, maybe all the trans have been rollbacked", K(max_trans_version), KPC(sstable)); + } + if (OB_FAIL(sstable->set_upper_trans_version(max_trans_version))) { + LOG_WARN("failed to set_upper_trans_version", K(ret), KPC(sstable)); + } else { + is_updated = true; + FLOG_INFO("success to update sstable's upper trans version", K(max_trans_version), KPC(sstable)); + } } } } } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } } return ret; @@ -1362,14 +2594,13 @@ int ObTablet::update_row( LOG_WARN("not inited", K(ret), K_(is_inited)); } else if (OB_UNLIKELY(!store_ctx.is_valid() || col_descs.count() <= 0 - || !full_read_info_.is_valid_full_read_info() || !old_row.is_valid() || !new_row.is_valid() || !relative_table.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(store_ctx), K(relative_table), K(col_descs), K(update_idx), - K(old_row), K(new_row), K_(full_read_info)); + K(old_row), K(new_row)); } else if (OB_UNLIKELY(relative_table.get_tablet_id() != tablet_meta_.tablet_id_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet id doesn't match", K(ret), K(relative_table.get_tablet_id()), K(tablet_meta_.tablet_id_)); @@ -1382,9 +2613,15 @@ int ObTablet::update_row( LOG_WARN("fail to protect table", K(ret)); } else if (OB_FAIL(prepare_memtable(relative_table, store_ctx, write_memtable))) { LOG_WARN("prepare write memtable fail", K(ret), K(relative_table)); - } else if (OB_FAIL(write_memtable->set(store_ctx, relative_table.get_table_id(), - full_read_info_, col_descs, update_idx, old_row, new_row, encrypt_meta))) { - LOG_WARN("failed to set write memtable", K(ret)); + } else { + ObArenaAllocator allocator(ObModIds::OB_STORE_ROW_EXISTER); + ObTableIterParam param; + ObTableAccessContext context; + if (OB_FAIL(prepare_param_ctx(allocator, relative_table, store_ctx, param, context))) { + LOG_WARN("prepare param ctx fail, ", K(ret)); + } else if (OB_FAIL(write_memtable->set(param, context, col_descs, update_idx, old_row, new_row, encrypt_meta))) { + LOG_WARN("failed to set memtable, ", K(ret)); + } } } @@ -1409,12 +2646,11 @@ int ObTablet::insert_row_without_rowkey_check( LOG_WARN("not inited", K(ret), K_(is_inited)); } else if (OB_UNLIKELY(!store_ctx.is_valid() || col_descs.count() <= 0 - || !full_read_info_.is_valid_full_read_info() || !row.is_valid() || !relative_table.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(store_ctx), K(relative_table), - K(col_descs), K(row), K_(full_read_info)); + K(col_descs), K(row)); } else if (OB_UNLIKELY(relative_table.get_tablet_id() != tablet_meta_.tablet_id_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet id doesn't match", K(ret), K(relative_table.get_tablet_id()), K(tablet_meta_.tablet_id_)); @@ -1427,48 +2663,49 @@ int ObTablet::insert_row_without_rowkey_check( LOG_WARN("fail to protect table", K(ret)); } else if (OB_FAIL(prepare_memtable(relative_table, store_ctx, write_memtable))) { LOG_WARN("prepare write memtable fail", K(ret), K(relative_table)); - } else if (OB_FAIL(write_memtable->set(store_ctx, relative_table.get_table_id(), - full_read_info_, col_descs, row, encrypt_meta))) { - LOG_WARN("failed to set memtable", K(ret)); + } else { + ObArenaAllocator allocator(ObModIds::OB_STORE_ROW_EXISTER); + ObTableIterParam param; + ObTableAccessContext context; + if (OB_FAIL(prepare_param_ctx(allocator, relative_table, store_ctx, param, context))) { + LOG_WARN("prepare param ctx fail, ", K(ret)); + } else if (OB_FAIL(write_memtable->set(param, context, col_descs, row, encrypt_meta))) { + LOG_WARN("fail to set memtable", K(ret)); + } } } - return ret; } int ObTablet::do_rowkey_exists( - ObStoreCtx &store_ctx, - const int64_t table_id, + ObTableIterParam ¶m, + ObTableAccessContext &context, const blocksstable::ObDatumRowkey &rowkey, - const ObQueryFlag &query_flag, bool &exists) { int ret = OB_SUCCESS; - ObTableStoreIterator table_iter(true/*reverse_iter*/); - - if (OB_UNLIKELY(!store_ctx.is_valid() || OB_INVALID_ID == table_id - || !rowkey.is_valid())) { + ObTabletTableIterator table_iter(true/*reverse_iter*/); + if (OB_UNLIKELY(!rowkey.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(store_ctx), K(rowkey), K(query_flag)); + LOG_WARN("invalid argument", K(ret), K(rowkey)); } else if (OB_FAIL(allow_to_read_())) { LOG_WARN("not allowed to read", K(ret), K(tablet_meta_)); - } else if (OB_FAIL(get_read_tables(store_ctx.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), - table_iter, - query_flag.index_invalid_))) { + } else if (OB_FAIL(auto_get_read_tables( + context.store_ctx_->mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), table_iter, context.query_flag_.index_invalid_))) { LOG_WARN("get read iterator fail", K(ret)); } else { bool found = false; ObITable *table = nullptr; int64_t check_table_cnt = 0; while (OB_SUCC(ret) && !found) { - if (OB_FAIL(table_iter.get_next(table))) { + if (OB_FAIL(table_iter.table_store_iter_.get_next(table))) { if (OB_ITER_END != ret) { LOG_WARN("failed to get next tables", K(ret)); } } else if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table must not be null", K(ret), K(table_iter)); - } else if (OB_FAIL(table->exist(store_ctx, table_id, full_read_info_, rowkey, exists, found))) { + } else if (OB_FAIL(table->exist(param, context, rowkey, exists, found))) { LOG_WARN("Fail to check if exist in store", K(ret), KPC(table)); } else { ++check_table_cnt; @@ -1479,13 +2716,13 @@ int ObTablet::do_rowkey_exists( if (OB_ITER_END == ret) { ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; - if (0 == store_ctx.tablet_stat_.query_cnt_) { + if (0 == context.store_ctx_->tablet_stat_.query_cnt_) { // ROWKEY IN_ROW_CACHE / NOT EXIST - } else if (FALSE_IT(store_ctx.tablet_stat_.exist_row_read_table_cnt_ = check_table_cnt)) { - } else if (FALSE_IT(store_ctx.tablet_stat_.exist_row_total_table_cnt_ = table_iter.count())) { + } else if (FALSE_IT(context.store_ctx_->tablet_stat_.exist_row_read_table_cnt_ = check_table_cnt)) { + } else if (FALSE_IT(context.store_ctx_->tablet_stat_.exist_row_total_table_cnt_ = table_iter.table_store_iter_.count())) { } else if (MTL(ObTenantTabletScheduler *)->enable_adaptive_compaction()) { bool report_succ = false; /*placeholder*/ - if (OB_TMP_FAIL(MTL(ObTenantTabletStatMgr *)->report_stat(store_ctx.tablet_stat_, report_succ))) { + if (OB_TMP_FAIL(MTL(ObTenantTabletStatMgr *)->report_stat(context.store_ctx_->tablet_stat_, report_succ))) { LOG_WARN("failed to report tablet stat", K(tmp_ret), K(stat)); } } @@ -1556,11 +2793,6 @@ int ObTablet::rowkey_exists( { int ret = OB_SUCCESS; const bool read_latest = true; - ObQueryFlag flag; - flag.read_latest_ = read_latest & ObQueryFlag::OBSF_MASK_READ_LATEST; - if (relative_table.is_storage_index_table()) { - flag.index_invalid_ = !relative_table.can_read_index(); - } if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -1585,13 +2817,18 @@ int ObTablet::rowkey_exists( ObStoreRowkey rowkey; ObDatumRowkey datum_rowkey; ObDatumRowkeyHelper rowkey_helper; + ObArenaAllocator allocator(ObModIds::OB_STORE_ROW_EXISTER); + ObTableIterParam param; + ObTableAccessContext context; + if (OB_FAIL(rowkey.assign(row.cells_, relative_table.get_rowkey_column_num()))) { LOG_WARN("Failed to assign rowkey", K(ret), K(row)); } else if (OB_FAIL(rowkey_helper.convert_datum_rowkey(rowkey.get_rowkey(), datum_rowkey))) { LOG_WARN("Failed to transfer datum rowkey", K(ret), K(rowkey)); - } else if (OB_FAIL(do_rowkey_exists(store_ctx, relative_table.get_table_id(), - datum_rowkey, flag, exists))) { - LOG_WARN("do rowkey exist fail", K(ret), K(rowkey), K(flag)); + } else if (OB_FAIL(prepare_param_ctx(allocator, relative_table, store_ctx, param, context))) { + LOG_WARN("Failed to prepare param ctx, ", K(ret), K(rowkey)); + } else if (OB_FAIL(do_rowkey_exists(param, context, datum_rowkey, exists))) { + LOG_WARN("do rowkey exist fail", K(ret), K(rowkey)); } LOG_DEBUG("chaser debug row", K(ret), K(row), K(rowkey)); } @@ -1606,7 +2843,7 @@ int ObTablet::rowkeys_exists( bool &exists) { int ret = OB_SUCCESS; - ObTableStoreIterator tables_iter(true/*reverse_iter*/); + ObTabletTableIterator tables_iter(true/*reverse_iter*/); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -1619,7 +2856,7 @@ int ObTablet::rowkeys_exists( LOG_WARN("tablet id doesn't match", K(ret), K(relative_table.get_tablet_id()), K(tablet_meta_.tablet_id_)); } else if (OB_FAIL(allow_to_read_())) { LOG_WARN("not allowed to read", K(ret), K(tablet_meta_)); - } else if (OB_FAIL(get_read_tables(store_ctx.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), + } else if (OB_FAIL(auto_get_read_tables(store_ctx.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), tables_iter, relative_table.allow_not_ready()))) { LOG_WARN("get read iterator fail", K(ret)); @@ -1632,7 +2869,7 @@ int ObTablet::rowkeys_exists( } if (OB_SUCC(ret)) { - if (OB_FAIL(do_rowkeys_exist(tables_iter, rows_info, exists))) { + if (OB_FAIL(do_rowkeys_exist(tables_iter.table_store_iter_, rows_info, exists))) { LOG_WARN("fail to check the existence of rows", K(ret), K(rows_info), K(exists)); } } @@ -1648,9 +2885,11 @@ int ObTablet::prepare_memtable( { int ret = OB_SUCCESS; write_memtable = nullptr; - store_ctx.table_iter_ = &relative_table.tablet_iter_.table_iter_; - ObITable* last_table = relative_table.tablet_iter_.table_iter_.get_boundary_table(true/*is_last*/); - if (OB_ISNULL(last_table)) { + store_ctx.table_iter_ = relative_table.tablet_iter_.table_iter(); + ObITable* last_table = nullptr; + if (OB_FAIL(relative_table.tablet_iter_.table_iter()->get_boundary_table(true, last_table))) { + LOG_WARN("fail to get last table from iter", K(ret)); + } else if (OB_ISNULL(last_table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("last table is null", K(relative_table)); } else if (OB_UNLIKELY(!last_table->is_data_memtable())) { @@ -1663,28 +2902,37 @@ int ObTablet::prepare_memtable( } int ObTablet::choose_and_save_storage_schema( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const ObStorageSchema &tablet_schema, const ObStorageSchema ¶m_schema) { int ret = OB_SUCCESS; - const ObStorageSchema *schema = &tablet_schema; - + const ObStorageSchema *chosen_schema = &tablet_schema; + const ObStorageSchema *other_schema = ¶m_schema; + int64_t chosen_schema_stored_col_cnt = 0; + int64_t other_schema_stored_col_cnt = 0; if (OB_UNLIKELY(!tablet_schema.is_valid()) || OB_UNLIKELY(!param_schema.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("input schema is invalid", K(ret), K(tablet_schema), K(param_schema)); - } else if (tablet_schema.schema_version_ >= param_schema.schema_version_) { - schema = &tablet_schema; + } else if (tablet_schema.schema_version_ > param_schema.schema_version_) { LOG_INFO("tablet storage schema version is no smaller than that in param", "tablet_schema_version", tablet_schema.get_schema_version(), "param_schema_version", param_schema.schema_version_); } else { - schema = ¶m_schema; + chosen_schema = ¶m_schema; + other_schema = &tablet_schema; } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(storage_schema_.init(allocator, *schema))) { - LOG_WARN("failed to init storage schema", K(ret), KPC(schema)); + } else if (OB_FAIL(chosen_schema->get_stored_column_count_in_sstable(chosen_schema_stored_col_cnt))) { + LOG_WARN("failed to get stored column count from schema", KR(ret), KPC(chosen_schema)); + } else if (OB_FAIL(other_schema->get_stored_column_count_in_sstable(other_schema_stored_col_cnt))) { + LOG_WARN("failed to get stored column count from schema", KR(ret), KPC(other_schema)); + } else if (OB_UNLIKELY(chosen_schema_stored_col_cnt < other_schema_stored_col_cnt)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("chosen schema have less column cnt, but with large schema version", KR(ret), + K(tablet_schema), K(param_schema)); + } else { + ALLOC_AND_INIT(allocator, storage_schema_addr_, *chosen_schema, true/*skip_column_info*/); } return ret; @@ -1803,18 +3051,21 @@ int ObTablet::replay_medium_compaction_clog( return ret; } -int ObTablet::get_schema_version_from_storage_schema(int64_t &schema_version) +int ObTablet::get_schema_version_from_storage_schema(int64_t &schema_version) const { int ret = OB_SUCCESS; const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; - + const ObStorageSchema *storage_schema = nullptr; + ObArenaAllocator arena_allocator; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited), K(tablet_id)); + } else if (OB_FAIL(load_storage_schema(arena_allocator, storage_schema))) { + LOG_WARN("fail to load storage schema", K(ret), K_(storage_schema_addr)); } else { - schema_version = storage_schema_.schema_version_; + schema_version = storage_schema->schema_version_; } - + ObTablet::free_storage_schema(arena_allocator, storage_schema); return ret; } @@ -1836,13 +3087,14 @@ int ObTablet::get_active_memtable(ObTableHandleV2 &handle) const return ret; } -int ObTablet::create_memtable(const int64_t schema_version, - const SCN clog_checkpoint_scn, - const bool for_replay) +int ObTablet::create_memtable( + const int64_t schema_version, + const SCN clog_checkpoint_scn, + const bool for_replay) { int ret = OB_SUCCESS; ObTimeGuard time_guard("ObTablet::create_memtable", 10 * 1000); - TCWLockGuard guard(table_store_lock_); + TCWLockGuard guard(memtables_lock_); time_guard.click("lock"); const SCN new_clog_checkpoint_scn = clog_checkpoint_scn.is_min() ? tablet_meta_.clog_checkpoint_scn_ : clog_checkpoint_scn; @@ -1852,23 +3104,37 @@ int ObTablet::create_memtable(const int64_t schema_version, } else if (OB_UNLIKELY(schema_version < 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid schema version", K(ret), K(schema_version)); - } else if (OB_FAIL(table_store_.prepare_memtables())) { - LOG_WARN("failed to pre-allocate memory for new memtable", K(ret), KPC(this)); } else if (FALSE_IT(time_guard.click("prepare_memtables"))) { } else if (OB_FAIL(inner_create_memtable(new_clog_checkpoint_scn, schema_version, for_replay))) { if (OB_ENTRY_EXIST == ret) { ret = OB_SUCCESS; } else if (OB_MINOR_FREEZE_NOT_ALLOW != ret) { - LOG_WARN("failed to create memtable", K(ret), K(new_clog_checkpoint_scn), + LOG_WARN("failed to create memtable", K(ret), K(clog_checkpoint_scn), K(schema_version), K(for_replay)); } } else if (FALSE_IT(time_guard.click("inner_create_memtable"))) { - } else if (OB_FAIL(table_store_.update_memtables())) { - LOG_ERROR("failed to append new memtable to table store", K(ret), KPC(this)); - ob_usleep(1000 * 1000); - ob_abort(); + } else if (OB_FAIL(update_memtables())) { + LOG_WARN("failed to append new memtable to table store", K(ret), KPC(this)); + if (OB_SIZE_OVERFLOW == ret) { + // rewrite errno to OB_EAGAIN when memtable count overflow, in case to stuck the log relpay engine + ret = OB_EAGAIN; + } + } else if (FALSE_IT(time_guard.click("update_memtables"))) { } else { - time_guard.click("update_memtables"); + tablet_addr_.inc_seq(); + table_store_addr_.addr_.inc_seq(); + + if (table_store_addr_.is_memory_object()) { + ObSEArray memtable_array; + if (OB_FAIL(inner_get_memtables(memtable_array, true/*need_active*/))) { + LOG_WARN("inner get memtables fail", K(ret), K(*this)); + } else if (OB_FAIL(table_store_addr_.get_ptr()->update_memtables(memtable_array))) { + LOG_WARN("table store update memtables fail", K(ret), K(memtable_array)); + } else { + time_guard.click("ts update mem"); + LOG_INFO("table store update memtable success", KPC(table_store_addr_.get_ptr()), KP(this)); + } + } } return ret; @@ -1886,6 +3152,12 @@ int ObTablet::inner_create_memtable( if (OB_UNLIKELY(!clog_checkpoint_scn.is_valid_and_not_min()) || OB_UNLIKELY(schema_version < 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(clog_checkpoint_scn), K(schema_version)); + } else if (OB_UNLIKELY(ObTablet::MEMTABLE_ARRAY_SIZE == memtable_count_)) { + ret = OB_MINOR_FREEZE_NOT_ALLOW; + if (TC_REACH_TIME_INTERVAL(1000 * 1000)) { + LOG_WARN("The memtable array in the tablet reaches the upper limit, and no more memtable can " + "be created", K(ret), K(memtable_count_), KPC(this)); + } } else if (OB_FAIL(get_memtable_mgr(memtable_mgr))) { LOG_WARN("failed to get memtable mgr", K(ret)); } else if (OB_FAIL(memtable_mgr->create_memtable(clog_checkpoint_scn, schema_version, for_replay))) { @@ -1901,6 +3173,23 @@ int ObTablet::inner_create_memtable( return ret; } +int ObTablet::inner_get_memtables(common::ObIArray &memtables, const bool need_active) const +{ + int ret = OB_SUCCESS; + memtables.reset(); + for (int64_t i = 0; OB_SUCC(ret) && i < memtable_count_; ++i) { + if (OB_ISNULL(memtables_[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable must not null", K(ret), K(memtables_)); + } else if (!need_active && memtables_[i]->is_active_memtable()) { + continue; + } else if (OB_FAIL(memtables.push_back(memtables_[i]))) { + LOG_WARN("failed to add memtables", K(ret), K(*this)); + } + } + return ret; +} + int ObTablet::release_memtables(const SCN scn) { int ret = OB_SUCCESS; @@ -1926,6 +3215,8 @@ int ObTablet::release_memtables() if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (is_empty_shell()) { + LOG_DEBUG("tablet is empty shell", K(ret)); } else if (OB_FAIL(get_memtable_mgr(memtable_mgr))) { LOG_WARN("failed to get memtable mgr", K(ret)); } else if (OB_FAIL(memtable_mgr->release_memtables())) { @@ -1938,12 +3229,23 @@ int ObTablet::release_memtables() int ObTablet::wait_release_memtables() { int ret = OB_SUCCESS; - ObIMemtableMgr *memtable_mgr = nullptr; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(get_memtable_mgr(memtable_mgr))) { + } else if (OB_FAIL(wait_release_memtables_())) { + LOG_WARN("failed to release memtables", K(ret)); + } + + return ret; +} + +int ObTablet::wait_release_memtables_() +{ + int ret = OB_SUCCESS; + ObIMemtableMgr *memtable_mgr = nullptr; + + if (OB_FAIL(get_memtable_mgr(memtable_mgr))) { LOG_WARN("failed to get memtable mgr", K(ret)); } else { const int64_t start = ObTimeUtility::current_time(); @@ -1972,6 +3274,8 @@ int ObTablet::reset_storage_related_member() LOG_WARN("not inited", K(ret), K_(is_inited)); } else if (is_ls_inner_tablet()) { // do nothing + } else if (is_empty_shell()) { + LOG_DEBUG("tablet is empty shell", K(ret)); } else if (OB_FAIL(get_memtable_mgr(memtable_mgr))) { LOG_WARN("failed to get memtable mgr", K(ret)); } else if (OB_FAIL(memtable_mgr->reset_storage_recorder())) { @@ -2045,19 +3349,6 @@ int ObTablet::remove_ddl_kv_mgr(const ObDDLKvMgrHandle &ddl_kv_mgr_handle) return ret; } - -common::ObThreadCond &ObTablet::get_cond() -{ - ObTabletPointer *tablet_ptr = static_cast(pointer_hdl_.get_resource_ptr()); - return tablet_ptr->cond_; -} - -common::TCRWLock &ObTablet::get_rw_lock() -{ - ObTabletPointer *tablet_ptr = static_cast(pointer_hdl_.get_resource_ptr()); - return tablet_ptr->msd_lock_; -} - int ObTablet::init_shared_params( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, @@ -2074,7 +3365,6 @@ int ObTablet::init_shared_params( } else { ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); ObIMemtableMgr *memtable_mgr = nullptr; - common::ObThreadCond &cond = get_cond(); if (OB_FAIL(get_memtable_mgr(memtable_mgr))) { LOG_WARN("failed to get memtable mgr", K(ret)); @@ -2088,44 +3378,55 @@ int ObTablet::init_shared_params( freezer, t3m))) { LOG_WARN("failed to init memtable mgr", K(ret), K(tablet_id), K(ls_id), KP(freezer)); - } else if (OB_FAIL(cond.init(ObWaitEventIds::TABLET_LOCK_WAIT))) { - LOG_WARN("failed to init thread cond", K(ret)); } } return ret; } -int ObTablet::build_read_info(common::ObIAllocator &allocator) +int ObTablet::build_read_info(common::ObArenaAllocator &allocator, const ObTablet *tablet) { int ret = OB_SUCCESS; + int64_t full_stored_col_cnt = 0; + common::ObArenaAllocator tmp_allocator; + const ObStorageSchema *storage_schema = nullptr; ObSEArray cols_desc; - if (OB_UNLIKELY(storage_schema_.get_compat_mode() != tablet_meta_.compat_mode_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("compat mode of schema and tablet_meta is not equal", K(ret), K_(storage_schema), K_(tablet_meta)); - } else if (OB_FAIL(storage_schema_.get_multi_version_column_descs(cols_desc))) { - LOG_WARN("Fail to get rowkey column ids", K(ret)); - } else if (OB_FAIL(full_read_info_.init(allocator, - storage_schema_.get_column_count(), - storage_schema_.get_rowkey_column_num(), - storage_schema_.is_oracle_mode(), - cols_desc, - true))) { - LOG_WARN("Fail to init read info", K(ret)); + tablet = (tablet == nullptr) ? this : tablet; + if (OB_FAIL(tablet->load_storage_schema(tmp_allocator, storage_schema))) { + LOG_WARN("fail to load storage schema", K(ret)); + } else if (OB_FAIL(storage_schema->get_mulit_version_rowkey_column_ids(cols_desc))) { + LOG_WARN("fail to get rowkey column ids", K(ret), KPC(storage_schema)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, rowkey_read_info_))) { + LOG_WARN("fail to allocate and new rowkey read info", K(ret)); + } else if (OB_FAIL(storage_schema->get_store_column_count(full_stored_col_cnt, true/*full col*/))) { + LOG_WARN("failed to get store column count", K(ret), KPC(storage_schema)); + } else if (OB_FAIL(rowkey_read_info_->init(allocator, + full_stored_col_cnt, + storage_schema->get_rowkey_column_num(), + storage_schema->is_oracle_mode(), + cols_desc))) { + LOG_WARN("fail to init rowkey read info", K(ret), KPC(storage_schema)); } - + ObTablet::free_storage_schema(tmp_allocator, storage_schema); return ret; } int ObTablet::try_update_start_scn() { int ret = OB_SUCCESS; - ObSSTable *first_minor = static_cast(table_store_.get_minor_sstables().get_boundary_table(false /*first*/)); - const SCN &start_scn = OB_NOT_NULL(first_minor) ? first_minor->get_start_scn() : tablet_meta_.clog_checkpoint_scn_; - const SCN &tablet_meta_scn = tablet_meta_.start_scn_; - tablet_meta_.start_scn_ = start_scn; - if (OB_UNLIKELY(start_scn < tablet_meta_scn)) { - FLOG_INFO("tablet start scn is small than tablet meta start scn", K(start_scn), K(tablet_meta_scn), K(tablet_meta_)); + ObTabletMemberWrapper table_store_wrapper; + ObTableStoreIterator iter; + if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else { + ObSSTable *first_minor = static_cast( + table_store_wrapper.get_member()->get_minor_sstables().get_boundary_table(false /*first*/)); + const SCN &start_scn = OB_NOT_NULL(first_minor) ? first_minor->get_start_scn() : tablet_meta_.clog_checkpoint_scn_; + const SCN &tablet_meta_scn = tablet_meta_.start_scn_; + tablet_meta_.start_scn_ = start_scn; + if (OB_UNLIKELY(start_scn < tablet_meta_scn)) { + FLOG_INFO("tablet start scn is small than tablet meta start scn", K(start_scn), K(tablet_meta_scn), K(tablet_meta_)); + } } return ret; } @@ -2133,19 +3434,26 @@ int ObTablet::try_update_start_scn() int ObTablet::try_update_ddl_checkpoint_scn() { int ret = OB_SUCCESS; - ObSSTable *last_ddl_sstable = static_cast(table_store_.get_ddl_sstables().get_boundary_table(true/*last*/)); - if (OB_NOT_NULL(last_ddl_sstable)) { - const SCN &ddl_checkpoint_scn = last_ddl_sstable->get_end_scn(); - if (OB_UNLIKELY(ddl_checkpoint_scn < tablet_meta_.ddl_checkpoint_scn_)) { - if (ddl_checkpoint_scn < tablet_meta_.ddl_start_scn_) { - ret = OB_TASK_EXPIRED; - LOG_INFO("ddl checkpoint scn is less than ddl start log ts, task expired", K(ret), K(ddl_checkpoint_scn), K(tablet_meta_)); + ObTabletMemberWrapper table_store_wrapper; + ObTableStoreIterator iter; + if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else { + ObSSTable *last_ddl_sstable = static_cast( + table_store_wrapper.get_member()->get_ddl_sstables().get_boundary_table(true/*last*/)); + if (OB_NOT_NULL(last_ddl_sstable)) { + const SCN &ddl_checkpoint_scn = last_ddl_sstable->get_end_scn(); + if (OB_UNLIKELY(ddl_checkpoint_scn < tablet_meta_.ddl_checkpoint_scn_)) { + if (ddl_checkpoint_scn < tablet_meta_.ddl_start_scn_) { + ret = OB_TASK_EXPIRED; + LOG_INFO("ddl checkpoint scn is less than ddl start log ts, task expired", K(ret), K(ddl_checkpoint_scn), K(tablet_meta_)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected clog checkpoint scn", K(ret), K(ddl_checkpoint_scn), K(tablet_meta_)); + } } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected clog checkpoint scn", K(ret), K(ddl_checkpoint_scn), K(tablet_meta_)); + tablet_meta_.ddl_checkpoint_scn_ = ddl_checkpoint_scn; } - } else { - tablet_meta_.ddl_checkpoint_scn_ = ddl_checkpoint_scn; } } return ret; @@ -2164,7 +3472,6 @@ int ObTablet::build_migration_tablet_param( ObMigrationTabletParam &mig_tablet_param) const { int ret = OB_SUCCESS; - if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); @@ -2174,33 +3481,56 @@ int ObTablet::build_migration_tablet_param( mig_tablet_param.data_tablet_id_ = tablet_meta_.data_tablet_id_; mig_tablet_param.ref_tablet_id_ = tablet_meta_.ref_tablet_id_; mig_tablet_param.create_scn_ = tablet_meta_.create_scn_; + mig_tablet_param.create_schema_version_ = tablet_meta_.create_schema_version_; mig_tablet_param.start_scn_ = tablet_meta_.start_scn_; mig_tablet_param.clog_checkpoint_scn_ = tablet_meta_.clog_checkpoint_scn_; mig_tablet_param.snapshot_version_ = tablet_meta_.snapshot_version_; mig_tablet_param.multi_version_start_ = tablet_meta_.multi_version_start_; mig_tablet_param.compat_mode_ = tablet_meta_.compat_mode_; mig_tablet_param.ha_status_ = tablet_meta_.ha_status_; - mig_tablet_param.tx_data_ = tablet_meta_.tx_data_; mig_tablet_param.table_store_flag_ = tablet_meta_.table_store_flag_; mig_tablet_param.ddl_checkpoint_scn_ = tablet_meta_.ddl_checkpoint_scn_; mig_tablet_param.ddl_start_scn_ = tablet_meta_.ddl_start_scn_; mig_tablet_param.ddl_snapshot_version_ = tablet_meta_.ddl_snapshot_version_; - // max_version on tablet meta is the latest serialized version mig_tablet_param.max_sync_storage_schema_version_ = tablet_meta_.max_sync_storage_schema_version_; mig_tablet_param.max_serialized_medium_scn_ = tablet_meta_.max_serialized_medium_scn_; + // max_version on tablet meta is the latest serialized version mig_tablet_param.ddl_execution_id_ = tablet_meta_.ddl_execution_id_; mig_tablet_param.ddl_data_format_version_ = tablet_meta_.ddl_data_format_version_; mig_tablet_param.ddl_commit_scn_ = tablet_meta_.ddl_commit_scn_; mig_tablet_param.report_status_ = tablet_meta_.report_status_; + mig_tablet_param.mds_checkpoint_scn_ = tablet_meta_.mds_checkpoint_scn_; + mig_tablet_param.transfer_info_ = tablet_meta_.transfer_info_; + mig_tablet_param.is_empty_shell_ = is_empty_shell(); - if (OB_FAIL(mig_tablet_param.storage_schema_.init(mig_tablet_param.allocator_, storage_schema_))) { - LOG_WARN("failed to copy storage schema", K(ret), K_(tablet_meta)); - } else if (OB_FAIL(mig_tablet_param.medium_info_list_.init(mig_tablet_param.allocator_, &medium_info_list_))) { - LOG_WARN("failed to copy medium info list", K(ret), K(medium_info_list_)); - } else if (OB_FAIL(mig_tablet_param.ddl_data_.assign(tablet_meta_.ddl_data_))) { - LOG_WARN("failed to assign ddl data", K(ret), K_(tablet_meta)); - } else if (OB_FAIL(mig_tablet_param.autoinc_seq_.assign(tablet_meta_.autoinc_seq_))) { - LOG_WARN("failed to assign autoinc seq", K(ret), K_(tablet_meta)); + + ObArenaAllocator arena_allocator("BuildMigParam"); + const ObStorageSchema *storage_schema = nullptr; + const ObTabletAutoincSeq *tablet_autoinc_seq = nullptr; + if (!is_empty_shell()) { + if (OB_FAIL(load_storage_schema(arena_allocator, storage_schema))) { + LOG_WARN("fail to load storage schema", K(ret)); + } else if (OB_FAIL(get_medium_info_list(mig_tablet_param.allocator_, mig_tablet_param.medium_info_list_))) { + LOG_WARN("failed to get medium info list", K(ret)); + } else if (OB_FAIL(mig_tablet_param.storage_schema_.init(mig_tablet_param.allocator_, *storage_schema))) { + LOG_WARN("failed to copy storage schema", K(ret), KPC(storage_schema)); + } else if (OB_FAIL(mig_tablet_param.mds_data_.init(mig_tablet_param.allocator_, mds_data_))) { + LOG_WARN("failed to assign mds data", K(ret), K_(mds_data)); + } + ObTablet::free_storage_schema(arena_allocator, storage_schema); + } else { + const ObTabletCreateDeleteMdsUserData &user_data = mds_data_.tablet_status_cache_; + const int64_t serialize_size = user_data.get_serialize_size(); + int64_t pos = 0; + char *buffer = nullptr; + if (OB_ISNULL(buffer = static_cast(mig_tablet_param.allocator_.alloc(serialize_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret), K(serialize_size)); + } else if (OB_FAIL(user_data.serialize(buffer, serialize_size, pos))) { + LOG_WARN("user data serialize failed", K(ret), K(user_data)); + } else { + mig_tablet_param.mds_data_.tablet_status_committed_kv_.v_.user_data_.assign_ptr(buffer, serialize_size); + } } } @@ -2213,6 +3543,9 @@ int ObTablet::build_migration_sstable_param( { int ret = OB_SUCCESS; ObTableHandleV2 handle; + ObTabletMemberWrapper table_store_wrapper; + ObTableStoreIterator iter; + ObSSTableMetaHandle sstable_meta_handle; ObSSTable *sstable = nullptr; if (OB_UNLIKELY(!is_inited_)) { @@ -2221,30 +3554,29 @@ int ObTablet::build_migration_sstable_param( } else if (OB_UNLIKELY(!table_key.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(table_key)); - } else if (OB_FAIL(table_store_.get_table(table_key, handle))) { + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->get_table( + table_store_wrapper.get_meta_handle(), table_key, handle))) { LOG_WARN("fail to get table from table store", K(ret), K(table_key)); } else if (OB_FAIL(handle.get_sstable(sstable))) { - LOG_WARN("fail to get sstable", K(ret), K(sstable)); + LOG_WARN("fail to get sstable", K(ret), KPC(sstable)); } else if (OB_ISNULL(sstable)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error", K(ret), KP(sstable)); + LOG_WARN("unexpected error", K(ret), KPC(sstable)); + } else if (OB_FAIL(sstable->get_meta(sstable_meta_handle))) { + LOG_WARN("fail to get sstable meta handle", K(ret), KPC(sstable)); } else { - const ObSSTableMeta &sstable_meta = sstable->get_meta(); + const ObSSTableMeta &sstable_meta = sstable_meta_handle.get_sstable_meta(); mig_sstable_param.basic_meta_ = sstable_meta.get_basic_meta(); mig_sstable_param.table_key_ = table_key; mig_sstable_param.is_small_sstable_ = sstable->is_small_sstable(); - if (OB_FAIL(mig_sstable_param.column_checksums_.assign(sstable_meta.get_col_checksum()))) { - LOG_WARN("fail to assign column checksums", K(ret), K(sstable_meta)); - } else if (OB_FAIL(ObSSTableMergeRes::fill_column_default_checksum_from_schema(&storage_schema_, - mig_sstable_param.column_default_checksums_))) { - LOG_WARN("fail to assign column default checksums", K(ret), K(storage_schema_)); - } else if (OB_UNLIKELY(mig_sstable_param.column_default_checksums_.count() - < mig_sstable_param.column_checksums_.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected column count", K(ret), - KP(this), K(mig_sstable_param), K(sstable_meta), K(storage_schema_)); - } else { - mig_sstable_param.table_key_ = sstable->get_key(); + mig_sstable_param.table_key_ = sstable->get_key(); + + for (int64_t i = 0; OB_SUCC(ret) && i < sstable_meta.get_col_checksum_cnt(); ++i) { + if (OB_FAIL(mig_sstable_param.column_checksums_.push_back(sstable_meta.get_col_checksum()[i]))) { + LOG_WARN("fail to push back column checksum", K(ret), K(i)); + } } } @@ -2258,18 +3590,22 @@ int ObTablet::get_ha_sstable_size(int64_t &data_size) { int ret = OB_SUCCESS; data_size = 0; + ObTabletMemberWrapper table_store_wrapper; ObTableStoreIterator iter; bool is_ready_for_read = true; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(table_store_.get_ha_tables(iter, is_ready_for_read))) { + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->get_ha_tables(iter, is_ready_for_read))) { LOG_WARN("failed to get read tables", K(ret)); } else { while (OB_SUCC(ret)) { ObITable *table = nullptr; ObSSTable *sstable = nullptr; + ObSSTableMetaHandle sstable_meta_hdl; if (OB_FAIL(iter.get_next(table))) { if (OB_ITER_END == ret) { ret = OB_SUCCESS; @@ -2281,8 +3617,10 @@ int ObTablet::get_ha_sstable_size(int64_t &data_size) ret = OB_ERR_UNEXPECTED; LOG_WARN("get migration get memtable", K(ret), KPC(table)); } else if (FALSE_IT(sstable = static_cast (table))) { + } else if (OB_FAIL(sstable->get_meta(sstable_meta_hdl))) { + LOG_WARN("failed to get sstable meta", K(ret)); } else { - data_size += sstable->get_meta().get_basic_meta().occupy_size_; + data_size += sstable_meta_hdl.get_sstable_meta().get_occupy_size(); } } } @@ -2294,24 +3632,25 @@ int ObTablet::fetch_tablet_autoinc_seq_cache( share::ObTabletAutoincInterval &result) { int ret = OB_SUCCESS; + ObArenaAllocator allocator; ObTabletAutoincSeq autoinc_seq; - uint64_t autoinc_seq_value = 0; + uint64_t auto_inc_seqvalue = 0; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(get_latest_autoinc_seq(autoinc_seq))) { + } else if (OB_FAIL(get_autoinc_seq(allocator, share::SCN::max_scn(), autoinc_seq))) { LOG_WARN("fail to get latest autoinc seq", K(ret)); - } else if (OB_FAIL(autoinc_seq.get_autoinc_seq_value(autoinc_seq_value))) { + } else if (OB_FAIL(autoinc_seq.get_autoinc_seq_value(auto_inc_seqvalue))) { LOG_WARN("failed to get autoinc seq value", K(ret), K(autoinc_seq)); } else { - const uint64_t interval_start = autoinc_seq_value; - const uint64_t interval_end = autoinc_seq_value + cache_size - 1; - const uint64_t result_autoinc_seq = autoinc_seq_value + cache_size; + const uint64_t interval_start = auto_inc_seqvalue; + const uint64_t interval_end = auto_inc_seqvalue + cache_size - 1; + const uint64_t result_autoinc_seq = auto_inc_seqvalue + cache_size; const ObTabletID &tablet_id = tablet_meta_.tablet_id_; SCN scn = SCN::min_scn(); - if (OB_FAIL(autoinc_seq.set_autoinc_seq_value(result_autoinc_seq))) { + if (OB_FAIL(autoinc_seq.set_autoinc_seq_value(allocator, result_autoinc_seq))) { LOG_WARN("failed to set autoinc seq value", K(ret), K(result_autoinc_seq)); - } else if (OB_FAIL(write_sync_tablet_seq_log(autoinc_seq, result_autoinc_seq, scn))) { + } else if (OB_FAIL(write_sync_tablet_seq_log(autoinc_seq, scn))) { LOG_WARN("fail to write sync tablet seq log", K(ret)); } else { result.start_ = interval_start; @@ -2404,68 +3743,11 @@ int ObTablet::get_msd_from_memtables( return ret; } -int ObTablet::get_min_medium_snapshot(int64_t &min_medium_snapshot) const -{ - int ret = OB_SUCCESS; - min_medium_snapshot = INT64_MAX; - const ObMediumCompactionInfoList &medium_list = get_medium_compaction_info_list(); - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (is_ls_inner_tablet()) { - // do nothing - } else if (medium_list.size() > 0) { // oldest medium info in Tablet - min_medium_snapshot = medium_list.get_min_medium_snapshot(); - } else { - ObArenaAllocator temp_allocator; - ObMediumCompactionInfo medium_info; - if (OB_FAIL(get_msd_from_memtables(medium_info, &temp_allocator, false/*get_latest*/))) { - if (OB_ENTRY_NOT_EXIST == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get medium from memtable", K(ret), KPC(this), K(medium_info)); - } - } else { - min_medium_snapshot = medium_info.medium_snapshot_; - } - } - return ret; -} - -int ObTablet::get_max_medium_snapshot(int64_t &max_medium_snapshot) const -{ - int ret = OB_SUCCESS; - max_medium_snapshot = 0; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (is_ls_inner_tablet()) { - // do nothing - } else { - ObArenaAllocator temp_allocator; - ObMediumCompactionInfo medium_info; - if (OB_FAIL(get_msd_from_memtables(medium_info, &temp_allocator, true/*get_latest*/))) { - if (OB_ENTRY_NOT_EXIST == ret) { - ret = OB_SUCCESS; - const ObMediumCompactionInfoList &medium_list = get_medium_compaction_info_list(); - if (medium_list.size() > 0) { - max_medium_snapshot = medium_list.get_max_medium_snapshot(); - } - } else { - LOG_WARN("failed to get medium from memtable", K(ret), KPC(this), K(medium_info)); - } - } else { - max_medium_snapshot = medium_info.medium_snapshot_; - } - } - return ret; -} - // MIN { ls min_reserved_snapshot, freeze_info, all_acquired_snapshot} int ObTablet::get_kept_multi_version_start( - ObLS &ls, - const ObTablet &tablet, - int64_t &multi_version_start) + ObLS &ls, + const ObTablet &tablet, + int64_t &multi_version_start) { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; @@ -2475,9 +3757,16 @@ int ObTablet::get_kept_multi_version_start( int64_t min_medium_snapshot = INT64_MAX; int64_t ls_min_reserved_snapshot = INT64_MAX; const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; - const ObTabletTableStore &table_store = tablet.get_table_store(); - if (0 != table_store.get_major_sstables().count()) { - max_merged_snapshot = table_store.get_major_sstables().get_boundary_table(true/*last*/)->get_snapshot_version(); + ObTabletMemberWrapper table_store_wrapper; + const ObTabletTableStore *table_store = nullptr; + common::ObArenaAllocator arena_allocator("reader"); + + if (OB_FAIL(tablet.fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member(table_store))) { + LOG_WARN("fail to get table store", K(ret), K(table_store_wrapper)); + } else if (0 != table_store->get_major_sstables().count()) { + max_merged_snapshot = table_store->get_major_sstables().get_boundary_table(true/*last*/)->get_snapshot_version(); } if (OB_FAIL(ret)) { @@ -2485,9 +3774,13 @@ int ObTablet::get_kept_multi_version_start( } else if (OB_FAIL(MTL(ObTenantFreezeInfoMgr*)->get_min_reserved_snapshot( tablet_id, max_merged_snapshot, min_reserved_snapshot))) { LOG_WARN("failed to get multi version from freeze info mgr", K(ret), K(table_id)); - } else if (!tablet.is_ls_inner_tablet() - && OB_FAIL(tablet.get_min_medium_snapshot(min_medium_snapshot))) { - LOG_WARN("failed to get min medium snapshot", K(ret), K(tablet)); + } else if (!tablet.is_ls_inner_tablet()) { + ObTabletMediumInfoReader medium_info_reader(tablet); + if (OB_FAIL(medium_info_reader.init(arena_allocator))) { + LOG_WARN("failed to init medium info reader", K(ret)); + } else if (OB_FAIL(medium_info_reader.get_min_medium_snapshot(min_medium_snapshot))) { + LOG_WARN("failed to get min medium snapshot", K(ret), K(tablet)); + } } // for compat, if receive ls_reserved_snapshot clog, should consider ls.get_min_reserved_snapshot() @@ -2517,26 +3810,8 @@ int ObTablet::get_kept_multi_version_start( return ret; } -int ObTablet::get_latest_autoinc_seq(ObTabletAutoincSeq &autoinc_seq) const -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(memtable_mgr_->get_multi_source_data_unit(&autoinc_seq))) { - if (OB_ENTRY_NOT_EXIST == ret || OB_NOT_SUPPORTED == ret) { - ret = OB_SUCCESS; - if (OB_FAIL(autoinc_seq.assign(tablet_meta_.autoinc_seq_))) { - LOG_WARN("failed to assign autoinc seq", K(ret)); - } - } - } - return ret; -} - int ObTablet::write_sync_tablet_seq_log(ObTabletAutoincSeq &autoinc_seq, - const uint64_t new_autoinc_seq, - SCN &scn) + share::SCN &scn) { int ret = OB_SUCCESS; const int64_t WAIT_TIME = 1000; // 1ms @@ -2550,32 +3825,27 @@ int ObTablet::write_sync_tablet_seq_log(ObTabletAutoincSeq &autoinc_seq, char buffer[buffer_size]; int64_t retry_cnt = 0; int64_t pos = 0; - ObSyncTabletSeqLogCb *cb = nullptr; + ObSyncTabletSeqMdsLogCb *cb = nullptr; ObLogHandler *log_handler = get_log_handler(); palf::LSN lsn; const bool need_nonblock= false; const SCN ref_scn = SCN::min_scn(); - - if (OB_FAIL(log.init(tablet_id, new_autoinc_seq))) { + uint64_t new_autoinc_seq = 0; + if (OB_FAIL(autoinc_seq.get_autoinc_seq_value(new_autoinc_seq))) { + LOG_WARN("failed to get autoinc seq value", K(ret)); + } else if (OB_FAIL(log.init(tablet_id, new_autoinc_seq))) { LOG_WARN("fail to init SyncTabletSeqLog", K(tablet_id), K(new_autoinc_seq)); - } else if (OB_ISNULL(cb = op_alloc(ObSyncTabletSeqLogCb))) { + } else if (OB_ISNULL(cb = op_alloc(ObSyncTabletSeqMdsLogCb))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory", K(ret)); - } else if (OB_FAIL(cb->init(tablet_meta_.ls_id_, tablet_id, new_autoinc_seq))) { - LOG_WARN("failed to init ObSyncTabletSeqLogCb", K(ret), K(autoinc_seq), K(new_autoinc_seq)); } else if (OB_FAIL(base_header.serialize(buffer, buffer_size, pos))) { LOG_WARN("failed to serialize log base header", K(ret)); } else if (OB_FAIL(log.serialize(buffer, buffer_size, pos))) { LOG_WARN("fail to serialize sync tablet seq log", K(ret)); - } else if (autoinc_seq.get_intervals().count() == 0 && OB_FAIL(autoinc_seq.set_autoinc_seq_value(1))) { - // need to do this to ensure the intervals list size is always 1, so the memory size is same before and after clog. - LOG_WARN("failed to set autoinc seq value", K(ret)); - } else if (OB_FAIL(save_multi_source_data_unit(&autoinc_seq, SCN::max_scn(), - false/*for_replay*/, memtable::MemtableRefOp::INC_REF))) { - if (OB_BLOCK_FROZEN == ret) { - ret = OB_EAGAIN; - } - LOG_WARN("failed to inc ref for auto inc seq", K(ret)); + } else if (OB_FAIL(cb->init(tablet_meta_.ls_id_, tablet_id, static_cast(new_autoinc_seq)))) { + LOG_WARN("failed to init cb", K(ret), K(tablet_meta_)); + } else if (OB_FAIL(set(std::move(autoinc_seq), cb->get_mds_ctx()))) { + LOG_WARN("failed to set mds", K(ret)); } else if (OB_FAIL(log_handler->append(buffer, buffer_size, ref_scn, @@ -2584,16 +3854,9 @@ int ObTablet::write_sync_tablet_seq_log(ObTabletAutoincSeq &autoinc_seq, lsn, scn))) { LOG_WARN("fail to submit sync tablet seq log", K(ret), K(buffer_size)); - // rollback, dec ref - int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(save_multi_source_data_unit(&autoinc_seq, SCN::max_scn(), - false/*for_replay*/, memtable::MemtableRefOp::DEC_REF, true/*is_callback*/))) { - LOG_ERROR("failed to dec ref for auto inc seq", K(tmp_ret)); - ob_usleep(1000 * 1000); - ob_abort(); - } + cb->on_failure(); } else { - // wait unti majority + // wait until majority bool wait_timeout = false; int64_t start_time = ObTimeUtility::fast_current_time(); while (!cb->is_finished() && !wait_timeout) { @@ -2603,7 +3866,7 @@ int ObTablet::write_sync_tablet_seq_log(ObTabletAutoincSeq &autoinc_seq, if (ObTimeUtility::fast_current_time() - start_time > SYNC_TABLET_SEQ_LOG_TIMEOUT) { wait_timeout = true; } - LOG_WARN_RET(OB_ERR_TOO_MUCH_TIME, "submit sync tablet seq log wait too much time", K(retry_cnt), K(wait_timeout)); + LOG_WARN("submit sync tablet seq log wait too much time", K(retry_cnt), K(wait_timeout)); } } if (wait_timeout) { @@ -2628,34 +3891,25 @@ int ObTablet::write_sync_tablet_seq_log(ObTabletAutoincSeq &autoinc_seq, return ret; } -int ObTablet::update_tablet_autoinc_seq( - const uint64_t autoinc_seq, - const SCN &replay_scn) +int ObTablet::update_tablet_autoinc_seq(const uint64_t autoinc_seq) { int ret = OB_SUCCESS; + ObArenaAllocator allocator("UpdAutoincSeq"); ObTabletAutoincSeq curr_autoinc_seq; - uint64_t curr_autoinc_seq_value; - bool is_replay = replay_scn != SCN::max_scn(); - SCN scn = replay_scn; + uint64_t curr_auto_inc_seqvalue; + SCN scn; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(get_latest_autoinc_seq(curr_autoinc_seq))) { + } else if (OB_FAIL(get_autoinc_seq(allocator, share::SCN::max_scn(), curr_autoinc_seq))) { LOG_WARN("fail to get latest autoinc seq", K(ret)); - } else if (OB_FAIL(curr_autoinc_seq.get_autoinc_seq_value(curr_autoinc_seq_value))) { + } else if (OB_FAIL(curr_autoinc_seq.get_autoinc_seq_value(curr_auto_inc_seqvalue))) { LOG_WARN("failed to get autoinc seq value", K(ret)); - } else if (autoinc_seq > curr_autoinc_seq_value) { - if (!is_replay) { - // this is not replay, then we need to write clog by ourselves - if (OB_FAIL(write_sync_tablet_seq_log(curr_autoinc_seq, autoinc_seq, scn))) { - LOG_WARN("fail to write sync tablet seq log", K(ret)); - } - } else if (OB_FAIL(curr_autoinc_seq.set_autoinc_seq_value(autoinc_seq))) { + } else if (autoinc_seq > curr_auto_inc_seqvalue) { + if (OB_FAIL(curr_autoinc_seq.set_autoinc_seq_value(allocator, autoinc_seq))) { LOG_WARN("failed to set autoinc seq value", K(ret), K(autoinc_seq)); - } else if (OB_FAIL(save_multi_source_data_unit(&curr_autoinc_seq, - scn, - is_replay))) { - LOG_WARN("failed to save autoinc seq", K(ret), K(curr_autoinc_seq)); + } else if (OB_FAIL(write_sync_tablet_seq_log(curr_autoinc_seq, scn))) { + LOG_WARN("fail to write sync tablet seq log", K(ret)); } } return ret; @@ -2887,48 +4141,135 @@ int ObTablet::get_tablet_report_info( const bool need_checksums) { int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + const ObTabletTableStore *table_store = nullptr; column_checksums.reset(); data_size = 0; required_size = 0; const ObSSTable *main_major = nullptr; - const ObSSTableArray &major_sstables = table_store_.get_major_sstables(); + ObSSTableMetaHandle main_major_meta_hdl; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); - } else if (major_sstables.count_ == 0) { + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member(table_store))) { + LOG_WARN("fail to get table store", K(ret), K(table_store_wrapper)); + } else if (table_store->get_major_sstables().empty()) { ret = OB_TABLET_NOT_EXIST; LOG_INFO("no major sstables in this tablet, cannot report", K(ret)); - } else if (FALSE_IT(main_major = static_cast(major_sstables.get_boundary_table(true)))) { + } else if (FALSE_IT(main_major = static_cast(table_store->get_major_sstables().get_boundary_table(true)))) { } else if (OB_UNLIKELY(nullptr == main_major || snapshot_version != main_major->get_snapshot_version())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected main major", K(ret), K(snapshot_version), KPC(main_major), KPC(this)); - } else if (need_checksums && OB_FAIL(column_checksums.assign(main_major->get_meta().get_col_checksum()))) { - LOG_WARN("failed to assign column checksums", K(ret)); + LOG_WARN("failed to get unexpected null major", K(ret)); + } else if (OB_FAIL(main_major->get_meta(main_major_meta_hdl))) { + LOG_WARN("failed to get sstable meta handle", K(ret)); + } else if (need_checksums) { + for (int64_t i = 0; OB_SUCC(ret) && i < main_major_meta_hdl.get_sstable_meta().get_col_checksum_cnt(); ++i) { + if (OB_FAIL(column_checksums.push_back(main_major_meta_hdl.get_sstable_meta().get_col_checksum()[i]))) { + LOG_WARN("fail to push back column checksum", K(ret), K(i)); + } + } } if (OB_SUCC(ret)) { - data_size = main_major->get_meta().get_basic_meta().occupy_size_; + data_size = main_major_meta_hdl.get_sstable_meta().get_basic_meta().occupy_size_; const int64_t macro_block_size = OB_SERVER_BLOCK_MGR.get_macro_block_size(); - for (int64_t i = 0; OB_SUCC(ret) && i < major_sstables.count_; ++i) { - const ObSSTable *table = static_cast(major_sstables[i]); - const ObSSTableBasicMeta &basic_meta = table->get_meta().get_basic_meta(); - if (0 == i) { - required_size += (basic_meta.get_total_macro_block_count()) * macro_block_size; + ObITable *table = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && i < table_store->get_major_sstables().count(); ++i) { + table = table_store->get_major_sstables().at(i); + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, table is nullptr", K(ret), KPC(table)); } else { - required_size += (basic_meta.get_total_macro_block_count() - basic_meta.get_total_use_old_macro_block_count()) * macro_block_size; + ObSSTable *sstable = reinterpret_cast(table); + ObSSTableMetaHandle major_meta_hdl; + if (OB_FAIL(sstable->get_meta(major_meta_hdl))) { + LOG_WARN("fail to get major sstable meta", K(ret)); + } else if (0 == i) { + required_size += (major_meta_hdl.get_sstable_meta().get_total_macro_block_count()) * macro_block_size; + } else { + required_size += + (major_meta_hdl.get_sstable_meta().get_total_macro_block_count() + - major_meta_hdl.get_sstable_meta().get_total_use_old_macro_block_count()) + * macro_block_size; + } } } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } } return ret; } -int ObTablet::get_ddl_sstable_handles(ObTablesHandleArray &ddl_sstable_handles) +int ObTablet::get_ddl_sstables(ObTableStoreIterator &table_store_iter) const { int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + const ObTabletTableStore *table_store = nullptr; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(table_store_.get_ddl_sstable_handles(ddl_sstable_handles))) { + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member(table_store))) { + LOG_WARN("fail to get table store", K(ret), K(table_store_wrapper)); + } else if (OB_FAIL(table_store->get_ddl_sstables(table_store_iter))) { + LOG_WARN("fail to get read tables", K(ret)); + } else if (!table_store_addr_.is_memory_object() + && OB_FAIL(table_store_iter.set_handle(table_store_wrapper.get_meta_handle()))) { + LOG_WARN("fail to set storage meta handle", K(ret), K_(table_store_addr), K(table_store_wrapper)); + } + return ret; +} + +int ObTablet::get_mini_minor_sstables(ObTableStoreIterator &table_store_iter) const +{ + int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->get_mini_minor_sstables( + tablet_meta_.ha_status_.is_data_status_complete(), table_store_iter))) { + LOG_WARN("fail to get ddl sstable handles", K(ret)); + } else if (!table_store_addr_.is_memory_object() + && OB_FAIL(table_store_iter.set_handle(table_store_wrapper.get_meta_handle()))) { + LOG_WARN("fail to set storage meta handle", K(ret), K_(table_store_addr), K(table_store_wrapper)); + } + return ret; +} + +int ObTablet::get_table(const ObITable::TableKey &table_key, ObTableHandleV2 &handle) const +{ + int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->get_table( + table_store_wrapper.get_meta_handle(), table_key, handle))) { + LOG_WARN("fail to get ddl sstable handles", K(ret)); + } + return ret; +} + +int ObTablet::get_recycle_version(const int64_t multi_version_start, int64_t &recycle_version) const +{ + int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->get_recycle_version( + multi_version_start, recycle_version))) { LOG_WARN("fail to get ddl sstable handles", K(ret)); } return ret; @@ -2939,12 +4280,17 @@ int ObTablet::get_ha_tables( bool &is_ready_for_read) { int ret = OB_SUCCESS; - + ObTabletMemberWrapper table_store_wrapper; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(table_store_.get_ha_tables(iter, is_ready_for_read))) { - LOG_WARN("failed to get read tables", K(ret)); + } else if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(table_store_wrapper.get_member()->get_ha_tables(iter, is_ready_for_read))) { + LOG_WARN("fail to get ha tables", K(ret)); + } else if (!table_store_addr_.is_memory_object() + && OB_FAIL(iter.set_handle(table_store_wrapper.get_meta_handle()))) { + LOG_WARN("fail to set storage meta handle", K(ret), K_(table_store_addr), K(table_store_wrapper)); } return ret; @@ -2973,184 +4319,6 @@ int ObTablet::get_ddl_info(int64_t &schema_version, int64_t &schema_refreshed_ts return ret; } -// only for redo -int ObTablet::set_tx_scn( - const transaction::ObTransID &tx_id, - const SCN &scn, - const bool for_replay) -{ - int ret = OB_SUCCESS; - ObTabletTxMultiSourceDataUnit tx_data; - - if (OB_UNLIKELY(!scn.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(scn)); - } else if (OB_FAIL(get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret)); - } else if (OB_UNLIKELY(tx_data.tx_id_ != tx_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("set log ts for non-locked tablet", K(ret), K(tx_data), K(tx_id), K(get_tablet_meta())); - } else { - tx_data.tx_scn_ = scn; - if (OB_FAIL(save_multi_source_data_unit(&tx_data, scn, for_replay, memtable::MemtableRefOp::DEC_REF, true/*is_callback*/))) { - LOG_WARN("failed to save tx data", K(ret), K(tx_data), K(scn)); - } - } - - return ret; -} - -// only for commit, abort -int ObTablet::set_tablet_final_status( - ObTabletTxMultiSourceDataUnit &tx_data, - const SCN &memtable_scn, - const bool for_replay, - const memtable::MemtableRefOp ref_op) -{ - int ret = OB_SUCCESS; - - if (OB_UNLIKELY(ObTabletStatus::Status::MAX == tx_data.tablet_status_) - || OB_UNLIKELY(for_replay && !tx_data.tx_scn_.is_valid()) - || OB_UNLIKELY(SCN::max_scn() == tx_data.tx_scn_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tx_data), K(memtable_scn), K(for_replay)); - } else if (OB_FAIL(set_multi_data_for_commit(tx_data, memtable_scn, for_replay, ref_op))) { - LOG_WARN("failed to save tx data", K(ret), K(tx_data), K(memtable_scn), K(for_replay), K(ref_op)); - } - - return ret; -} - -int ObTablet::set_tx_data( - const ObTabletTxMultiSourceDataUnit &tx_data, - const bool for_replay, - const MemtableRefOp ref_op, - const bool is_callback) -{ - int ret = OB_SUCCESS; - const SCN scn = tx_data.tx_scn_; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!tx_data.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tx_data)); - } else if (OB_FAIL(save_multi_source_data_unit(&tx_data, scn, for_replay, ref_op, is_callback))) { - LOG_WARN("failed to save tx data", K(ret), K(tx_data), K(scn), K(for_replay), K(ref_op), K(is_callback)); - } - - return ret; -} - -int ObTablet::set_tx_data( - const ObTabletTxMultiSourceDataUnit &tx_data, - const SCN &memtable_log_scn, - const bool for_replay, - const memtable::MemtableRefOp ref_op, - const bool is_callback) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!tx_data.is_valid()) - || OB_UNLIKELY(memtable_log_scn < SCN::min_scn())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tx_data), K(memtable_log_scn)); - } else if (OB_FAIL(save_multi_source_data_unit(&tx_data, memtable_log_scn, for_replay, ref_op, is_callback))) { - LOG_WARN("failed to save tx data", K(ret), K(tx_data), K(memtable_log_scn), K(for_replay), K(ref_op), K(is_callback)); - } - - return ret; -} - -int ObTablet::inner_get_tx_data(ObTabletTxMultiSourceDataUnit &tx_data, bool &exist_on_memtable) const -{ - int ret = OB_SUCCESS; - const share::ObLSID &ls_id = tablet_meta_.ls_id_; - const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; - exist_on_memtable = false; - - if (OB_FAIL(get_msd_from_memtables(tx_data))) { - if (OB_ENTRY_NOT_EXIST == ret) { - exist_on_memtable = false; - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get msd from memtable", K(ret), K(ls_id), K(tablet_id)); - } - } else { - exist_on_memtable = true; - } - - if (OB_FAIL(ret)) { - } else if (exist_on_memtable) { - } else if (OB_FAIL(tx_data.deep_copy(&tablet_meta_.tx_data_))) { - LOG_WARN("failed to get tx data from tablet", K(ret), K(ls_id), K(tablet_id), "tx_data", tablet_meta_.tx_data_); - } - - return ret; -} - -int ObTablet::get_tx_data(ObTabletTxMultiSourceDataUnit &tx_data, const bool check_valid) const -{ - int ret = OB_SUCCESS; - const uint64_t tenant_id = MTL_ID(); - const share::ObLSID &ls_id = tablet_meta_.ls_id_; - const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; - bool exist_on_memtable = true; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited), K(tenant_id), K(ls_id), K(tablet_id)); - } else if (OB_FAIL(inner_get_tx_data(tx_data, exist_on_memtable))) { - LOG_WARN("fail to inner get tx data", K(ret)); - } else if (check_valid && OB_UNLIKELY(!tx_data.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, tx data is invalid", K(ret), K(tenant_id), K(ls_id), K(tablet_id), - K(exist_on_memtable), K(tx_data)); - } - return ret; -} - -int ObTablet::check_tx_data(bool &is_valid) const -{ - int ret = OB_SUCCESS; - const share::ObLSID &ls_id = tablet_meta_.ls_id_; - const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; - ObTabletTxMultiSourceDataUnit tx_data; - bool exist_on_memtable = true; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited), K(ls_id), K(tablet_id)); - } else if (OB_FAIL(inner_get_tx_data(tx_data, exist_on_memtable))) { - LOG_WARN("fail to inner get tx data", K(ret), K(ls_id), K(tablet_id)); - } else { - is_valid = tx_data.is_valid(); - } - return ret; -} - -int ObTablet::get_tablet_status(ObTabletStatus::Status &tablet_status) -{ - int ret = OB_SUCCESS; - const share::ObLSID &ls_id = tablet_meta_.ls_id_; - const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; - ObTabletTxMultiSourceDataUnit tx_data; - bool exist_on_memtable = true; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited), K(ls_id), K(tablet_id)); - } else if (OB_FAIL(inner_get_tx_data(tx_data, exist_on_memtable))) { - LOG_WARN("failed to get tx data", K(ret), K(ls_id), K(tablet_id)); - } else { - tablet_status = tx_data.tablet_status_; - } - - return ret; -} - int ObTablet::get_rec_log_scn(SCN &rec_scn) { int ret = OB_SUCCESS; rec_scn = SCN::max_scn(); @@ -3179,17 +4347,61 @@ int ObTablet::get_rec_log_scn(SCN &rec_scn) { return ret; } -int ObTablet::get_ddl_data(ObTabletBindingInfo &info) const +int ObTablet::get_mds_table_rec_log_scn(SCN &rec_scn) +{ + int ret = OB_SUCCESS; + mds::MdsTableHandle mds_table; + rec_scn = SCN::max_scn(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret), K_(is_inited)); + } else if (is_ls_inner_tablet()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("inner tablet does not have mds table", K(ret)); + } else if (OB_FAIL(inner_get_mds_table(mds_table))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("mds_table not exist", K(ret)); + } else { + LOG_WARN("failed to get mds table", K(ret)); + } + } else if (OB_FAIL(mds_table.get_rec_scn(rec_scn))) { + LOG_WARN("failed to get mds table rec scn", K(ret)); + } else if (!rec_scn.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get invalid scn from mds table", K(ret)); + } + return ret; +} + +int ObTablet::mds_table_flush(const share::SCN &recycle_scn) +{ + int ret = OB_SUCCESS; + mds::MdsTableHandle mds_table; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret), K_(is_inited)); + } else if (is_ls_inner_tablet()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("inner tablet does not have mds table", K(ret)); + } else if (OB_FAIL(inner_get_mds_table(mds_table))) { + LOG_WARN("failed to get mds table", K(ret)); + } else if (OB_FAIL(mds_table.flush(recycle_scn))) { + LOG_WARN("failed to flush mds table", KR(ret), KPC(this)); + } + return ret; +} + +int ObTablet::get_auto_inc_seq(common::ObArenaAllocator &allocator, share::ObTabletAutoincSeq &auto_inc_seq) const { int ret = OB_SUCCESS; const share::ObLSID &ls_id = tablet_meta_.ls_id_; const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; bool exist_on_memtable = false; - if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(get_msd_from_memtables(info))) { + } else if (OB_FAIL(get_msd_from_memtables(auto_inc_seq, &allocator))) { if (OB_ENTRY_NOT_EXIST == ret) { exist_on_memtable = false; ret = OB_SUCCESS; @@ -3199,142 +4411,152 @@ int ObTablet::get_ddl_data(ObTabletBindingInfo &info) const } else { exist_on_memtable = true; } - if (OB_FAIL(ret)) { } else if (exist_on_memtable) { - } else if (OB_FAIL(info.assign(tablet_meta_.ddl_data_))) { - LOG_WARN("failed to get tx data from tablet", K(ret), K(ls_id), K(tablet_id), "ddl_data", tablet_meta_.ddl_data_); + } else { + const share::ObTabletAutoincSeq *autoin_seq_from_meta = nullptr; + ObTabletMemberWrapper wrapper; + if (OB_FAIL(fetch_autoinc_seq(wrapper))) { + LOG_WARN("failed to get autoinc seq wrapper", K(ret)); + } else if (OB_ISNULL(autoin_seq_from_meta = wrapper.get_member())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("autoinc seq from meta is null", K(ret)); + } else if (OB_FAIL(auto_inc_seq.assign(allocator, *autoin_seq_from_meta))) { + LOG_WARN("failed to get tx data from tablet", K(ret), K(ls_id), K(tablet_id), KPC(autoin_seq_from_meta)); + } } - return ret; } -int ObTablet::set_tx_data_in_tablet_pointer(const ObTabletTxMultiSourceDataUnit &tx_data) +int ObTablet::get_storage_schema_for_transfer_in( + common::ObArenaAllocator &allocator, + ObStorageSchema &storage_schema) const { int ret = OB_SUCCESS; - const ObTabletMapKey key(tablet_meta_.ls_id_, tablet_meta_.tablet_id_); - ObTabletPointer *tablet_ptr = static_cast(pointer_hdl_.get_resource_ptr()); - - if (OB_UNLIKELY(!is_inited_)) { + const share::ObLSID &ls_id = tablet_meta_.ls_id_; + const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; + const ObStorageSchema *tablet_storage_schema = nullptr; + ObIMemtableMgr *memtable_mgr = nullptr; + ObArray memtables; + int64_t max_column_cnt_in_memtable = 0; + int64_t max_schema_version_in_memtable = 0; + int64_t store_column_cnt_in_schema = 0; + if (IS_NOT_INIT) { 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)); + } else if (OB_UNLIKELY(tablet_id.is_ls_inner_tablet())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported to get storage schema for ls inner tablet", KR(ret), K(tablet_id)); + } else if (OB_ISNULL(memtable_mgr = get_memtable_mgr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable mgr should not be NULL", K(ret), KP(memtable_mgr)); + } else if (OB_FAIL(memtable_mgr->get_all_memtables(memtables))) { + LOG_WARN("failed to get all memtables", K(ret), KPC(this)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < memtables.count(); ++i) { + ObITable *table = memtables.at(i).get_table(); + if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table in tables_handle is invalid", K(ret), KP(table)); + } else if (OB_FAIL(static_cast(table)->get_schema_info( + max_schema_version_in_memtable, max_column_cnt_in_memtable))) { + LOG_WARN("failed to get schema info from memtable", KR(ret), KPC(table)); + } + } } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(load_storage_schema(allocator, tablet_storage_schema))) { + LOG_WARN("fail to load storage schema", K(ret), K_(storage_schema_addr)); + } else if (OB_FAIL(storage_schema.deep_copy(tablet_storage_schema, &allocator))) { + LOG_WARN("failed to get tx data from tablet", K(ret), K(ls_id), K(tablet_id), KPC(tablet_storage_schema)); + } else if (OB_FAIL(storage_schema.get_store_column_count(store_column_cnt_in_schema, true/*full_col*/))) { + LOG_WARN("failed to get store column count", K(ret), K(store_column_cnt_in_schema)); + } else { + int64_t old_column_cnt = storage_schema.get_column_count(); + int64_t old_schema_version = storage_schema.get_schema_version(); + storage_schema.column_cnt_ = MAX(old_column_cnt, max_column_cnt_in_memtable); + storage_schema.store_column_cnt_ = MAX(store_column_cnt_in_schema, max_column_cnt_in_memtable); + storage_schema.schema_version_ = MAX(old_schema_version, max_schema_version_in_memtable); + LOG_INFO("succeeded to get storage schema from transfer source tablet", K(ret), K(storage_schema), K(max_column_cnt_in_memtable), + K(max_schema_version_in_memtable), K(old_column_cnt), K(store_column_cnt_in_schema), K(old_schema_version)); + } + ObTablet::free_storage_schema(allocator, tablet_storage_schema); return ret; } -int ObTablet::update_msd_cache_on_pointer() +int ObTablet::check_and_set_initial_state() { 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; + bool initial_state = true; - 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)); + if (is_empty_shell()) { + initial_state = false; + } else if (OB_FAIL(check_initial_state(initial_state))) { + LOG_WARN("failed to check initial state", K(ret)); } - return ret; -} - -int ObTablet::get_redefined_schema_version_in_tablet_pointer(int64_t &schema_version) const -{ - int ret = OB_SUCCESS; - ObTabletPointer *tablet_ptr = static_cast(pointer_hdl_.get_resource_ptr()); - - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(tablet_ptr->get_redefined_schema_version(schema_version))) { - LOG_WARN("failed to get redefined schema version from pointer", K(ret)); - } - - return ret; -} - -int ObTablet::set_redefined_schema_version_in_tablet_pointer(const int64_t schema_version) -{ - int ret = OB_SUCCESS; - ObTabletPointer *tablet_ptr = static_cast(pointer_hdl_.get_resource_ptr()); - - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(tablet_ptr->set_redefined_schema_version(schema_version))) { - LOG_WARN("failed to set redefined schema version in tablet pointer", K(ret), K(schema_version)); - } - - return ret; -} - -int ObTablet::allow_to_read_() -{ - int ret = OB_SUCCESS; - const bool is_ready_for_read = tablet_meta_.ha_status_.is_none(); - - if (!is_ready_for_read) { - ret = OB_REPLICA_NOT_READABLE; - LOG_WARN("tablet not allowed to read", K(ret), K(tablet_meta_)); - } - return ret; -} - -int ObTablet::check_max_sync_schema_version() const -{ - int ret = OB_SUCCESS; - int64_t max_sync_schema_version = 0; - if (is_ls_inner_tablet()) { - // do nothing - } else if (OB_FAIL(get_max_sync_storage_schema_version(max_sync_schema_version))) { - LOG_WARN("failed to get max sync storage schema version", K(ret)); - } else if (max_sync_schema_version > storage_schema_.schema_version_) { // need check memtable - ObArenaAllocator tmp_allocator; - ObStorageSchema storage_schema; - ObIMemtableMgr *memtable_mgr = nullptr; - ObTabletMemtableMgr *data_memtable_mgr = nullptr; - if (OB_FAIL(get_memtable_mgr(memtable_mgr))) { - LOG_WARN("failed to get memtable mgr", K(ret)); - } else if (FALSE_IT(data_memtable_mgr = static_cast(memtable_mgr))) { - } else if (OB_UNLIKELY(!data_memtable_mgr->get_storage_schema_recorder().is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("schema recorder is invalid", K(ret), K_(tablet_meta), KPC(data_memtable_mgr)); - } else if (OB_FAIL(data_memtable_mgr->get_multi_source_data_unit(&storage_schema, &tmp_allocator))) { - LOG_ERROR("failed to get storage schema from memtable, max_sync_schema_version is invalid", K(ret), - K(max_sync_schema_version), KPC(data_memtable_mgr)); - } else if (OB_UNLIKELY(storage_schema.schema_version_ < max_sync_schema_version)) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("unexpected max sync schema version", K(ret), K(max_sync_schema_version), - "storage_schema_on_memtable", storage_schema, - "storage_schema_on_tablet", storage_schema_, K_(tablet_meta), KPC(data_memtable_mgr)); + if (OB_FAIL(ret)) { + } else if (!initial_state) { + if (OB_FAIL(set_initial_state(false/*initial_state*/))) { + LOG_WARN("failed to set initial state", K(ret)); + } else { + FLOG_INFO("set initial state to false", K(ret), K(ls_id), K(tablet_id)); } } + return ret; } int ObTablet::check_medium_list() const { int ret = OB_SUCCESS; - ObITable *last_major = nullptr; - if (nullptr != (last_major = table_store_.get_major_sstables().get_boundary_table(true/*last*/)) - && get_medium_compaction_info_list().get_last_compaction_scn() > 0) { // for compat - if (OB_UNLIKELY(get_medium_compaction_info_list().get_last_compaction_scn() != last_major->get_snapshot_version())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("medium list is invalid for last major sstable", K(ret), "medium_list", get_medium_compaction_info_list(), - KPC(last_major)); + if (tablet_meta_.ha_status_.is_none()) { + ObTabletMemberWrapper table_store_wrapper; + ObITable *last_major = nullptr; + if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_NOT_NULL(last_major = table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true/*last*/))) { + ObArenaAllocator arena_allocator("check_medium", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); + ObMediumCompactionInfoList medium_info_list; + if (OB_FAIL(load_medium_info_list(arena_allocator, + mds_data_.medium_info_list_, + mds_data_.extra_medium_info_, + medium_info_list))) { + LOG_WARN("fail to load medium info list", K(ret)); + } else if (medium_info_list.get_last_compaction_scn() > 0) { // for compat + if (OB_UNLIKELY(medium_info_list.get_last_compaction_scn() != last_major->get_snapshot_version())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("medium list is invalid for last major sstable", K(ret), K(medium_info_list), KPC(last_major)); + } + } } } return ret; } + +int ObTablet::get_finish_medium_scn(int64_t &finish_medium_scn) const +{ + int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + + if (OB_FAIL(fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else { + const ObTabletTableStore *table_store = table_store_wrapper.get_member(); + ObITable *last_major = table_store->get_major_sstables().get_boundary_table(true/*last*/); + if (nullptr == last_major) { + finish_medium_scn = 0; + } else { + finish_medium_scn = last_major->get_snapshot_version(); + } + } + + return ret; +} + int ObTablet::set_memtable_clog_checkpoint_scn( const ObMigrationTabletParam *tablet_meta) { @@ -3375,18 +4597,1361 @@ int ObTablet::set_memtable_clog_checkpoint_scn( return ret; } +int ObTablet::get_medium_info_list( + common::ObArenaAllocator &allocator, + compaction::ObMediumCompactionInfoList &medium_info_list) const +{ + int ret = OB_SUCCESS; + const share::ObLSID &ls_id = tablet_meta_.ls_id_; + const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(load_medium_info_list(allocator, + mds_data_.medium_info_list_, + mds_data_.extra_medium_info_, + medium_info_list))) { + LOG_WARN("load medium info list failed", K(ret)); + } + + return ret; +} + +int ObTablet::prepare_param_ctx( + ObIAllocator &allocator, + ObRelativeTable &relative_table, + ObStoreCtx &ctx, + ObTableIterParam ¶m, + ObTableAccessContext &context) +{ + int ret = OB_SUCCESS; + ObVersionRange trans_version_range; + const bool read_latest = true; + ObQueryFlag query_flag; + + + trans_version_range.base_version_ = 0; + trans_version_range.multi_version_start_ = 0; + trans_version_range.snapshot_version_ = EXIST_READ_SNAPSHOT_VERSION; + query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; + query_flag.read_latest_ = read_latest & ObQueryFlag::OBSF_MASK_READ_LATEST; + if (relative_table.is_storage_index_table()) { + query_flag.index_invalid_ = !relative_table.can_read_index(); + } + + param.table_id_ = relative_table.get_table_id(); + param.tablet_id_ = tablet_meta_.tablet_id_; + param.read_info_ = rowkey_read_info_; + + if (OB_FAIL(context.init(query_flag, ctx, allocator, trans_version_range))) { + LOG_WARN("Fail to init access context", K(ret)); + } + return ret; +} + +int ObTablet::build_transfer_tablet_param( + const share::ObLSID &dest_ls_id, + ObMigrationTabletParam &mig_tablet_param) +{ + int ret = OB_SUCCESS; + mig_tablet_param.reset(); + ObTabletCreateDeleteMdsUserData user_data; + share::SCN max_data_scn; + ObTabletMdsData mds_table_data; + ObTabletMdsData new_mds_data; + bool unused_committed_flag = false; + int64_t finish_medium_scn = 0; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (!dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("build transfer tablet param get invalid argument", K(ret), K(dest_ls_id)); + } else if (!tablet_meta_.ha_status_.is_data_status_complete()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet meta data status is incompleted, unexpected", K(ret), KPC(this), K(tablet_meta_)); + } else if (tablet_meta_.ref_tablet_id_.is_valid()) { + //ref tablet id is unused now. So it should be invalid + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ref tablet id is valid, unexpected", K(ret), KPC(this), K(tablet_meta_)); + } else if (OB_FAIL(ObITabletMdsInterface::get_latest_tablet_status(user_data, unused_committed_flag))) { + LOG_WARN("failed to get lastest tablet status", K(ret), KPC(this), K(tablet_meta_)); + } else if (OB_FAIL(get_storage_schema_for_transfer_in(mig_tablet_param.allocator_, mig_tablet_param.storage_schema_))) { + LOG_WARN("failed to get storage schema", K(ret), KPC(this)); + } else if (OB_FAIL(get_medium_info_list(mig_tablet_param.allocator_, mig_tablet_param.medium_info_list_))) { + LOG_WARN("failed to get_medium_info_list", K(ret), KPC(this)); + } else { + //TODO(lingchuan) need split it into slog, mds data, ddl data + mig_tablet_param.ls_id_ = dest_ls_id; + mig_tablet_param.tablet_id_ = tablet_meta_.tablet_id_; + mig_tablet_param.data_tablet_id_ = tablet_meta_.data_tablet_id_; + mig_tablet_param.ref_tablet_id_ = tablet_meta_.ref_tablet_id_; + mig_tablet_param.create_scn_ = tablet_meta_.create_scn_; + mig_tablet_param.create_schema_version_ = tablet_meta_.create_schema_version_; + mig_tablet_param.start_scn_ = tablet_meta_.start_scn_; + mig_tablet_param.clog_checkpoint_scn_ = user_data.transfer_scn_; + mig_tablet_param.snapshot_version_ = 1; + mig_tablet_param.multi_version_start_ = 1; + mig_tablet_param.compat_mode_ = tablet_meta_.compat_mode_; + mig_tablet_param.ha_status_ = tablet_meta_.ha_status_; + mig_tablet_param.table_store_flag_ = tablet_meta_.table_store_flag_; + // Due to the need to wait for ddl merge in the doing phase of transfer, the ddl checkpoint scn of src_tablet may be pushed up after the transfer in tablet is created. + mig_tablet_param.ddl_checkpoint_scn_ = user_data.transfer_scn_; + mig_tablet_param.ddl_start_scn_ = tablet_meta_.ddl_start_scn_; + mig_tablet_param.ddl_snapshot_version_ = tablet_meta_.ddl_snapshot_version_; + mig_tablet_param.max_sync_storage_schema_version_ = mig_tablet_param.storage_schema_.schema_version_; + mig_tablet_param.ddl_execution_id_ = tablet_meta_.ddl_execution_id_; + mig_tablet_param.ddl_data_format_version_ = tablet_meta_.ddl_data_format_version_; + mig_tablet_param.mds_checkpoint_scn_ = user_data.transfer_scn_; + mig_tablet_param.report_status_.reset(); + const int64_t transfer_seq = tablet_meta_.transfer_info_.transfer_seq_ + 1; + + if (OB_FAIL(mig_tablet_param.transfer_info_.init(tablet_meta_.ls_id_, user_data.transfer_scn_, transfer_seq))) { + LOG_WARN("failed to init transfer info", K(ret), K(tablet_meta_), K(user_data)); + } else if (OB_FAIL(read_mds_table(mig_tablet_param.allocator_, mds_table_data, false))) { + LOG_WARN("failed to read mds table", K(ret)); + } else if (OB_FAIL(get_finish_medium_scn(finish_medium_scn))) { + LOG_WARN("failed to get finish medium scn", K(ret)); + } else if (OB_FAIL(new_mds_data.init(mig_tablet_param.allocator_, mds_table_data, mds_data_, finish_medium_scn))) { + LOG_WARN("failed to init new mds data", K(ret), K(finish_medium_scn)); + } else if (OB_FAIL(build_transfer_in_tablet_status_(user_data, new_mds_data, mig_tablet_param.allocator_))) { + LOG_WARN("failed to build transfer in tablet status", K(new_mds_data), K(mds_data_), KPC(this)); + } else if (OB_FAIL(mig_tablet_param.mds_data_.init(mig_tablet_param.allocator_, new_mds_data))) { + LOG_WARN("failed to assign mds data", K(ret), K(new_mds_data), K(mds_data_), K(mds_table_data)); + } else { + LOG_INFO("succeed build_transfer_tablet_param_mds", K(user_data), K(max_data_scn), + K(new_mds_data), K(mds_table_data), K(mds_data_), K(mig_tablet_param), KPC(this)); + } + } + return ret; +} + +int64_t ObTablet::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + if (OB_ISNULL(buf) || buf_len <= 0) { + // do nothing + } else { + J_OBJ_START(); + J_NAME("ObTablet"); + J_COLON(); + J_KV(KP(this), + K_(wash_score), + K_(ref_cnt), + K_(version), + K_(length), + K_(tablet_addr), + KP_(allocator), + K_(tablet_meta), + K_(table_store_addr), + K_(storage_schema_addr), + K_(next_tablet_guard), + K_(pointer_hdl), + K_(next_full_tablet_guard), + KP_(next_tablet), + KP_(memtable_mgr), + KP_(log_handler), + K_(rowkey_read_info), + K_(mds_data), + K_(hold_ref_cnt), + K_(is_inited), + K_(memtable_count)); + J_COMMA(); + BUF_PRINTF("memtables"); + J_COLON(); + J_ARRAY_START(); + for (int64_t i = 0; i < MEMTABLE_ARRAY_SIZE; ++i) { + if (i > 0) { + J_COMMA(); + } + BUF_PRINTO(OB_P(memtables_[i])); + } + J_ARRAY_END(); + J_OBJ_END(); + } + return pos; +} + +int ObTablet::refresh_memtable_and_update_seq(const uint64_t seq) +{ + int ret = OB_SUCCESS; + if (table_store_addr_.is_memory_object()) { + table_store_addr_.get_ptr()->clear_memtables(); + } + reset_memtable(); + if (OB_FAIL(pull_memtables_without_ddl())) { + LOG_WARN("fail to pull memtables", K(ret), KPC(this)); + } else { + tablet_addr_.set_seq(seq); + table_store_addr_.addr_.set_seq(seq); + if (table_store_addr_.is_memory_object()) { + ObSEArray memtable_array; + if (OB_FAIL(inner_get_memtables(memtable_array, true/*need_active*/))) { + LOG_WARN("inner get memtables fail", K(ret), K(*this)); + } else if (OB_FAIL(table_store_addr_.get_ptr()->update_memtables(memtable_array))) { + LOG_WARN("table store update memtables fail", K(ret), K(memtable_array)); + } else { + LOG_INFO("table store update memtable success", KPC(table_store_addr_.get_ptr()), KP(this)); + } + } + } + return ret; +} + +int ObTablet::pull_memtables() +{ + int ret = OB_SUCCESS; + if (OB_FAIL(pull_memtables_without_ddl())) { + LOG_WARN("fail to pull memtables without ddl", K(ret)); + } else if (OB_FAIL(pull_ddl_memtables())) { + LOG_WARN("failed to pull ddl memtables", K(ret)); + } + return ret; +} + +int ObTablet::pull_memtables_without_ddl() +{ + int ret = OB_SUCCESS; + ObTableHandleArray memtable_handles; + + if (OB_ISNULL(memtable_mgr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable_mgr_ is null", K(ret)); + } else if (!memtable_mgr_->has_memtable()) { + LOG_TRACE("no memtable in memtable mgr", K(ret)); + } else if (OB_FAIL(memtable_mgr_->get_all_memtables(memtable_handles))) { + LOG_WARN("failed to get all memtables from memtable_mgr", K(ret)); + } else { + int64_t start_snapshot_version = get_snapshot_version(); + const SCN& clog_checkpoint_scn = tablet_meta_.clog_checkpoint_scn_; + int64_t start_pos = -1; + + for (int64_t i = 0; OB_SUCC(ret) && i < memtable_handles.count(); ++i) { + memtable::ObIMemtable *table = static_cast(memtable_handles.at(i).get_table()); + if (OB_ISNULL(table) || !table->is_memtable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must not null and must be memtable", K(ret), K(table)); + } else if (table->is_resident_memtable()) { // Single full resident memtable will be available always + LOG_INFO("is_resident_memtable will be pulled always", K(table->get_key().tablet_id_.id())); + start_pos = i; + break; + } else if (table->get_end_scn() == clog_checkpoint_scn) { + if (table->get_snapshot_version() > start_snapshot_version) { + start_pos = i; + break; + } + } else if (table->get_end_scn() > clog_checkpoint_scn) { + start_pos = i; + break; + } + } + if (OB_FAIL(ret)) { + } else if (start_pos < 0 || start_pos >= memtable_handles.count()) { + // all memtables need to be released + reset_memtable(); + } else if (OB_FAIL(build_memtable(memtable_handles, start_pos))) { + LOG_WARN("failed to build table store memtables", K(ret), K(memtable_handles), K(start_pos), K(*this)); + } + } + return ret; +} + +int ObTablet::build_transfer_in_tablet_status_( + const ObTabletCreateDeleteMdsUserData &user_data, + ObTabletMdsData &mds_data, + common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + + ObTabletCreateDeleteMdsUserData new_user_data; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(new_user_data.assign(user_data))) { + LOG_WARN("assign user data failed", K(ret), K_(is_inited)); + } else { + mds_data.tablet_status_.committed_kv_.get_ptr()->reset(); + new_user_data.tablet_status_ = ObTabletStatus::TRANSFER_IN; + new_user_data.transfer_ls_id_ = tablet_meta_.ls_id_; + new_user_data.data_type_ = ObTabletMdsUserDataType::START_TRANSFER_IN; + + const int64_t length = user_data.get_serialize_size(); + char *buffer = static_cast(allocator.alloc(length)); + int64_t pos = 0; + if (OB_ISNULL(buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to allocate memory", K(ret), K(length)); + } else if (OB_FAIL(new_user_data.serialize(buffer, length, pos))) { + LOG_WARN("failed to serialize user data", K(ret)); + } else { + mds::MdsDumpKV *uncommitted_kv = mds_data.tablet_status_.uncommitted_kv_.ptr_; + const mds::MdsDumpKV *committed_kv = mds_data.tablet_status_.committed_kv_.ptr_; + + if (OB_ISNULL(uncommitted_kv) || OB_ISNULL(committed_kv)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dump kv is null", K(ret), KP(uncommitted_kv), KP(committed_kv)); + } else if (OB_FAIL(uncommitted_kv->assign(*committed_kv, allocator))) { + LOG_WARN("failed to copy committed kv to uncommitted kv", K(ret)); + } else { + mds::MdsDumpNode &node = uncommitted_kv->v_; + node.allocator_ = &allocator; + node.user_data_.assign(buffer, length); + } + + } + } + return ret; +} + +int ObTablet::update_memtables() +{ + int ret = OB_SUCCESS; + ObTableHandleArray inc_memtables; + ObIMemtableMgr *memtable_mgr; + + if (OB_FAIL(get_memtable_mgr(memtable_mgr))) { + LOG_WARN("failed to get memtable_mgr", K(ret)); + } else if (!memtable_mgr->has_memtable()) { + LOG_INFO("no memtable in memtable mgr", K(ret)); + } else if (OB_FAIL(memtable_mgr->get_all_memtables(inc_memtables))) { + LOG_WARN("failed to get all memtables from memtable_mgr", K(ret)); + } else if (OB_FAIL(rebuild_memtable(inc_memtables))) { + LOG_ERROR("failed to rebuild table store memtables", K(ret), K(inc_memtables), KPC(this)); + } else if (is_ls_inner_tablet() && OB_FAIL(rebuild_memtable(inc_memtables))) { + LOG_ERROR("failed to rebuild table store memtables for ls inner tablet", K(ret), K(inc_memtables)); + } else if (!is_ls_inner_tablet() && memtable_count_ > 0 && OB_FAIL(rebuild_memtable(inc_memtables))) { + LOG_ERROR("failed to rebuild table store memtables for normal tablet when current memtable exists", K(ret), K(inc_memtables), KPC(this)); + } else if (!is_ls_inner_tablet() && memtable_count_ == 0 && OB_FAIL(rebuild_memtable(tablet_meta_.clog_checkpoint_scn_, inc_memtables))) { + LOG_ERROR("failed to rebuild table store memtables for normal tablet when current memtable does not exist", K(ret), + "clog_checkpoint_scn", tablet_meta_.clog_checkpoint_scn_, + K(inc_memtables)); + } + LOG_DEBUG("update memtables", K(ret), K(inc_memtables)); + return ret; +} + +int ObTablet::build_memtable() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(memtable_mgr_)) { + ret = OB_ERR_NULL_VALUE; + LOG_ERROR("failed to get all memtables from memtable_mgr", K(ret)); + } else if (OB_SUCC(ret)) { // init sstables when first creating tablet + ObSEArray memtable_handles; + if (memtable_mgr_->has_memtable()) { + if (OB_FAIL(memtable_mgr_->get_all_memtables(memtable_handles))) { + LOG_WARN("failed to get all memtables from memtable_mgr", K(ret)); + } else if (OB_FAIL(build_memtable(memtable_handles))) { + LOG_WARN("failed to pull memtable array", K(ret)); + } else { + LOG_INFO("success to pull memtables when first creating tablet", K(ret), K(*this)); + } + } + } + return ret; +} + +int ObTablet::inner_get_mds_table(mds::MdsTableHandle &mds_table, bool not_exist_create) const +{ + int ret = OB_SUCCESS; + ObTabletPointer *tablet_ptr = nullptr; + if (OB_ISNULL(tablet_ptr = static_cast(pointer_hdl_.get_resource_ptr()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet pointer is null", K(ret), KPC(this)); + } else if (OB_FAIL(tablet_ptr->get_mds_table(mds_table, not_exist_create))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("failed to get mds table", K(ret)); + } + } + return ret; +} + +int ObTablet::build_memtable(common::ObIArray &handle_array, const int64_t start_pos) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(start_pos < 0 || start_pos >= handle_array.count() || handle_array.count() > MEMTABLE_ARRAY_SIZE)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid arguments", K(ret), K(start_pos), K(handle_array)); + } + + ObITable *table = nullptr; + for (int64_t i = start_pos; OB_SUCC(ret) && i < handle_array.count(); ++i) { + memtable::ObMemtable *memtable = nullptr; + table = handle_array.at(i).get_table(); + if (OB_UNLIKELY(nullptr == table || !table->is_memtable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must be memtable", K(ret), K(i), KPC(table)); + } else if (FALSE_IT(memtable = reinterpret_cast(table))) { + } else if (memtable->is_empty()) { + FLOG_INFO("Empty memtable discarded", KPC(memtable)); + } else if (OB_FAIL(add_memtable(memtable))) { + LOG_WARN("failed to add to memtables", K(ret)); + } + } + if (OB_FAIL(ret)) { + if (OB_UNLIKELY(OB_SIZE_OVERFLOW == ret)) { + LOG_DEBUG("memtable is full while building memtable", K(ret), KPC(table), K(memtable_count_)); + } else { + reset_memtable(); + } + } + return ret; +} + +int ObTablet::read_mds_table(common::ObIAllocator &allocator, ObTabletMdsData &mds_data, const bool for_flush) +{ + int ret = OB_SUCCESS; + mds_data.reset(); + mds::MdsTableHandle mds_table_handle; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(mds_data.init(allocator))) { + LOG_WARN("failed to init mds data", K(ret)); + } else if (OB_FAIL(inner_get_mds_table(mds_table_handle))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("mds table does not exist, may be released", K(ret)); + } else { + LOG_WARN("failed to get mds table", K(ret)); + } + } else { + ObTabletDumpMdsNodeOperator op(mds_data, allocator); + if (OB_FAIL(mds_table_handle.for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump(op, for_flush))) { + LOG_WARN("failed to traverse mds table", K(ret)); + } + } + + return ret; +} + +int ObTablet::read_mds_table_medium_info_list( + common::ObIAllocator &allocator, + ObTabletDumpedMediumInfo &medium_info_list) const +{ + int ret = OB_SUCCESS; + medium_info_list.reset(); + mds::MdsTableHandle mds_table_handle; + + if (OB_FAIL(inner_get_mds_table(mds_table_handle))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get mds table", K(ret)); + } + } else if (OB_FAIL(medium_info_list.init(allocator))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else { + ObTabletMediumInfoNodeOperator op(medium_info_list, allocator); + if (OB_FAIL(mds_table_handle.for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump(op, false/*for_flush*/))) { + LOG_WARN("failed to traverse mds table", K(ret)); + } + } + + return ret; +} + +int ObTablet::notify_mds_table_flush_ret( + const share::SCN &flush_scn, + const int flush_ret) +{ + int ret = OB_SUCCESS; + mds::MdsTableHandle mds_table; + const share::ObLSID &ls_id = tablet_meta_.ls_id_; + const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (is_ls_inner_tablet()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("inner tablet does not have mds table", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(inner_get_mds_table(mds_table))) { + LOG_WARN("failed to get mds table", K(ret), K(ls_id), K(tablet_id)); + } else if (!mds_table.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("mds table is null", K(ret), K(ls_id), K(tablet_id)); + } else { + mds_table.on_flush(flush_scn, flush_ret); + } + + return ret; +} + +int ObTablet::rebuild_memtable(common::ObIArray &handle_array) +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_ERROR("ObTablet isn't inited", K(ret), KPC(this), K(handle_array)); + } else if (OB_FAIL(trim_empty_last_memtable())) { + LOG_WARN("failed to trim empty last memtable", K(ret)); + } else { + int last_idx = memtable_count_ > 0 ? memtable_count_ - 1 : 0; + ObITable *last_memtable = memtables_[last_idx]; + share::SCN end_scn = (NULL == last_memtable) ? share::SCN() : last_memtable->get_end_scn(); + + LOG_DEBUG("before rebuild memtable", K(memtable_count_), K(last_idx), KP(last_memtable), K(end_scn), K(handle_array)); + for (int64_t i = 0; OB_SUCC(ret) && i < handle_array.count(); ++i) { + memtable::ObMemtable *memtable = nullptr; + ObITable *table = handle_array.at(i).get_table(); + if (OB_UNLIKELY(nullptr == table || !table->is_memtable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must be memtable", K(ret), K(i), KPC(table)); + } else if (FALSE_IT(memtable = static_cast(table))) { + } else if (memtable->is_empty()) { + FLOG_INFO("Empty memtable discarded", KPC(memtable)); + } else if (table->get_end_scn() < end_scn) { + } else if (table->get_end_scn() == end_scn && memtable == last_memtable) { //fix issue 41996395 + } else if (OB_FAIL(add_memtable(memtable))) { + LOG_WARN("failed to add memtable to curr memtables", K(ret), KPC(this)); + } else { + LOG_INFO("succeed to add memtable", K(ret), KPC(memtable)); + } + } + LOG_DEBUG("after rebuild memtable", K(memtable_count_), K(last_idx), KP(last_memtable), K(end_scn), K(handle_array)); + } + return ret; +} + +int ObTablet::rebuild_memtable( + const share::SCN &clog_checkpoint_scn, + common::ObIArray &handle_array) +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_ERROR("ObMemtableArray not inited", K(ret), KPC(this), K(handle_array)); + } else if (OB_UNLIKELY(0 != memtable_count_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("current memtable array is not empty", K(ret), K(clog_checkpoint_scn), K(memtable_count_)); + } else { + // use clog checkpoint scn to filter memtable handle array + for (int64_t i = 0; OB_SUCC(ret) && i < handle_array.count(); ++i) { + memtable::ObMemtable *memtable = nullptr; + ObITable *table = handle_array.at(i).get_table(); + if (OB_UNLIKELY(nullptr == table || !table->is_memtable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must be memtable", K(ret), K(i), KPC(table)); + } else if (FALSE_IT(memtable = static_cast(table))) { + } else if (memtable->is_empty()) { + FLOG_INFO("Empty memtable discarded", K(ret), KPC(memtable)); + } else if (table->get_end_scn() <= clog_checkpoint_scn) { + FLOG_INFO("memtable end scn no greater than clog checkpoint scn, should be discarded", K(ret), + "end_scn", table->get_end_scn(), K(clog_checkpoint_scn)); + } else if (OB_FAIL(add_memtable(memtable))) { + LOG_WARN("failed to add memtable", K(ret), KPC(memtable)); + } + } + } + return ret; +} + +int ObTablet::add_memtable(memtable::ObMemtable* const table) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(table)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid argument", K(ret), KPC(table)); + } else if (MEMTABLE_ARRAY_SIZE == memtable_count_) { + ret = OB_SIZE_OVERFLOW; + LOG_DEBUG("memtable is full", K(ret), KPC(table), K(memtable_count_)); + } else { + memtables_[memtable_count_]=table; + memtable_count_++; + table->inc_ref(); + } + return ret; +} + +int ObTablet::trim_empty_last_memtable() +{ + // trim last memtable if it is empty since right boundary of memtable could be refine asynchronuously + int ret = OB_SUCCESS; + const int64_t last_memtable_idx = memtable_count_ - 1; + if (0 == memtable_count_) { + // skip + } else if (memtables_[last_memtable_idx]->is_empty()) { + LOG_INFO("trim empty last memtable", K(ret), K(memtables_[last_memtable_idx])); + const int64_t ref_cnt = memtables_[last_memtable_idx]->dec_ref(); + if (0 == ref_cnt) { + const ObITable::TableType table_type = memtables_[last_memtable_idx]->get_key().table_type_; + if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->push_table_into_gc_queue(memtables_[last_memtable_idx], table_type))) { + LOG_WARN("Failed to push trimmed empty memtable to gc queue", K(ret), KPC(memtables_[last_memtable_idx])); + } + } + memtables_[last_memtable_idx] = nullptr; + memtable_count_--; + } + return ret; +} + +int ObTablet::assign_memtables(const ObTablet &other_tablet) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(other_tablet.memtables_) + || OB_ISNULL(other_tablet.ddl_kvs_) + || OB_UNLIKELY(other_tablet.memtable_count_ < 0 || 0 != memtable_count_) + || OB_UNLIKELY(other_tablet.ddl_kv_count_ < 0 || 0 != ddl_kv_count_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid other tablet memtable array", K(ret), K_(memtable_count), K_(ddl_kv_count), K(other_tablet)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < other_tablet.memtable_count_; ++i) { + memtable::ObIMemtable * memtable = other_tablet.memtables_[i]; + if (OB_ISNULL(memtable)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null memtable ptr", K(ret), K(i), K(other_tablet)); + } else { + memtables_[i] = memtable; + memtable->inc_ref(); + ++memtable_count_; + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < other_tablet.ddl_kv_count_; ++i) { + ObITable *ddl_kv = other_tablet.ddl_kvs_[i]; + if (OB_ISNULL(ddl_kv)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected ddl kv", K(ret), K(i), K(other_tablet)); + } else { + ddl_kvs_[i] = ddl_kv; + ddl_kv->inc_ref(); + ++ddl_kv_count_; + } + } + } + return ret; +} + +void ObTablet::reset_memtable() +{ + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + for(int i = 0; i < MEMTABLE_ARRAY_SIZE; ++i) { + if (OB_NOT_NULL(memtables_[i])) { + const ObITable::TableType table_type = memtables_[i]->get_key().table_type_; + const int64_t ref_cnt = memtables_[i]->dec_ref(); + if (0 == ref_cnt) { + t3m->push_table_into_gc_queue(memtables_[i], table_type); + } + } + memtables_[i] = nullptr; + } + memtable_count_ = 0; +} + int ObTablet::clear_memtables_on_table_store() // be careful to call this func { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_ISNULL(allocator_) || OB_ISNULL(table_store_addr_.get_ptr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("clear_memtables_on_table_store can only be called by full memory tablet", + K(ret), KP(allocator_), K(table_store_addr_)); } else { - table_store_.clear_memtables(); + table_store_addr_.get_ptr()->clear_memtables(); + reset_memtable(); } return ret; } -// only check storage_schema & medium_list when ha_status is none + +int ObTablet::get_restore_status(ObTabletRestoreStatus::STATUS &restore_status) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FALSE_IT(tablet_meta_.ha_status_.get_restore_status(restore_status))) { + } else if (!ObTabletRestoreStatus::is_valid(restore_status)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("restore status is invalid", KR(ret), K(restore_status)); + } + + return ret; +} + +int ObTablet::get_mds_table_handle_(mds::MdsTableHandle &handle, + const bool create_if_not_exist) const +{ + int ret = OB_SUCCESS; + if (is_ls_inner_tablet()) { + ret = OB_ENTRY_NOT_EXIST;// will continue read mds_data on tablet + LOG_TRACE("there is no mds table on ls inner tablet yet", KR(ret)); + } else if (OB_FAIL(inner_get_mds_table(handle, create_if_not_exist))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("inner get mds table failed", KR(ret)); + } else { + LOG_TRACE("inner get mds table failed", KR(ret)); + } + } + return ret; +} + +int ObTablet::pull_ddl_memtables() +{ + int ret = OB_SUCCESS; + ObArray ddl_memtables; + ObDDLKvMgrHandle kv_mgr_handle; + bool has_ddl_kv = false; + ObTablesHandleArray ddl_kvs_handle; + if (OB_UNLIKELY(0 != ddl_kv_count_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected ddl kv count when pull ddl memtables", K(ret), K_(ddl_kv_count), KPC(this)); + } else if (OB_FAIL(get_ddl_kv_mgr(kv_mgr_handle))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("get ddl kv mgr failed", K(ret), KPC(this)); + } else { + LOG_TRACE("there is no ddl kv mgr in this tablet", K(ret)); + ret = OB_SUCCESS; + } + } else if (OB_FAIL(kv_mgr_handle.get_obj()->get_ddl_kvs_for_query(*this, ddl_kvs_handle))) { + LOG_WARN("failed to get all ddl freeze kvs", K(ret)); + } else { + SCN ddl_checkpoint_scn = get_tablet_meta().ddl_checkpoint_scn_; + for (int64_t i = 0; OB_SUCC(ret) && i < ddl_kvs_handle.get_count(); ++i) { + ObDDLKV *ddl_kv = static_cast(ddl_kvs_handle.get_table(i)); + if (OB_ISNULL(ddl_kv)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get ddl kv failed", K(ret), K(i)); + } else if (ddl_kv->is_closed()) { + // skip, because closed meanns ddl dump sstable created + } else if (ddl_kv->get_freeze_scn() > ddl_checkpoint_scn) { + if (OB_FAIL(ddl_kv->prepare_sstable(false/*need_check*/))) { + LOG_WARN("prepare sstable failed", K(ret)); + } else if (OB_UNLIKELY(ddl_kv_count_ >= DDL_KV_ARRAY_SIZE)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ddl kv count overflow", K(ret), K(i), K_(ddl_kv_count), K(ddl_kvs_handle)); + } else { + ddl_kvs_[ddl_kv_count_] = ddl_kv; + ddl_kv->inc_ref(); + ++ddl_kv_count_; + } + } + } + } + return ret; +} + +void ObTablet::reset_ddl_memtables() +{ + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + for(int i = 0; i < ddl_kv_count_; ++i) { + ObITable *ddl_kv = ddl_kvs_[i]; + if (OB_NOT_NULL(ddl_kv)) { + const ObITable::TableType table_type = ddl_kv->get_key().table_type_; + const int64_t ref_cnt = ddl_kv->dec_ref(); + if (0 == ref_cnt) { + t3m->push_table_into_gc_queue(ddl_kv, table_type); + } + } + ddl_kvs_[i] = nullptr; + } + ddl_kv_count_ = 0; +} + +int ObTablet::set_initial_state(const bool initial_state) +{ + int ret = OB_SUCCESS; + ObTabletPointer *tablet_ptr = static_cast(pointer_hdl_.get_resource_ptr()); + + if (OB_ISNULL(tablet_ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet pointer is null", K(ret)); + } else { + tablet_ptr->set_initial_state(initial_state); + } + + return ret; +} + +int ObTablet::check_initial_state(bool &initial_state) +{ + int ret = OB_SUCCESS; + initial_state = true; + const ObTabletComplexAddr &uncommitted_tablet_status_addr = mds_data_.tablet_status_.uncommitted_kv_; + const ObTabletComplexAddr &committed_tablet_status_addr = mds_data_.tablet_status_.committed_kv_; + ObTabletCreateDeleteMdsUserData uncommitted_data; + ObTabletCreateDeleteMdsUserData committed_data; + const mds::MdsDumpKV *uncommitted_kv = nullptr; + const mds::MdsDumpKV *committed_kv = nullptr; + ObArenaAllocator arena_allocator("mds_reader"); + + if (OB_UNLIKELY(!(uncommitted_tablet_status_addr.is_memory_object() || uncommitted_tablet_status_addr.is_disk_object()) + || !(committed_tablet_status_addr.is_memory_object() || committed_tablet_status_addr.is_disk_object()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet status addr is not mem or disk type", K(ret), K(uncommitted_tablet_status_addr), K(committed_tablet_status_addr)); + } + + // TODO(@bowen.gbw): optimize, check initial state without IO + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObTabletMdsData::load_mds_dump_kv(arena_allocator, uncommitted_tablet_status_addr, uncommitted_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret), K(uncommitted_tablet_status_addr)); + } else if (OB_ISNULL(uncommitted_kv)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, mds dump kv is null", K(ret)); + } else { + const common::ObString &user_data = uncommitted_kv->v_.user_data_; + int64_t pos = 0; + if (user_data.empty()) { + // uncommitted tablet status is empty + } else if (OB_FAIL(uncommitted_data.deserialize(user_data.ptr(), user_data.length(), pos))) { + LOG_WARN("failed to deserialize", K(user_data), + "user_data_length", user_data.length(), + "user_hash:%x", user_data.hash(), + "crc_check_number", uncommitted_kv->v_.crc_check_number_); + } else if (ObTabletStatus::MAX != uncommitted_data.tablet_status_) { + initial_state = false; + } + } + + if (OB_FAIL(ret)) { + } else if (!initial_state) { + // no need to check committed tablet status + } else if (OB_FAIL(ObTabletMdsData::load_mds_dump_kv(arena_allocator, committed_tablet_status_addr, committed_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret), K(committed_tablet_status_addr)); + } else if (OB_ISNULL(committed_kv)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, mds dump kv is null", K(ret)); + } else { + const common::ObString &user_data = committed_kv->v_.user_data_; + int64_t pos = 0; + if (user_data.empty()) { + // committed tablet status is empty + } else if (OB_FAIL(committed_data.deserialize(user_data.ptr(), user_data.length(), pos))) { + LOG_WARN("failed to deserialize", K(user_data), + "user_data_length", user_data.length(), + "user_hash:%x", user_data.hash(), + "crc_check_number", committed_kv->v_.crc_check_number_); + } else if (ObTabletStatus::MAX != committed_data.tablet_status_) { + initial_state = false; + } + } + + ObTabletMdsData::free_mds_dump_kv(arena_allocator, uncommitted_kv); + ObTabletMdsData::free_mds_dump_kv(arena_allocator, committed_kv); + + return ret; +} + +int ObTablet::load_medium_info_list( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &complex_addr, + const ObTaletExtraMediumInfo &extra_info, + compaction::ObMediumCompactionInfoList &medium_info_list) +{ + int ret = OB_SUCCESS; + const ObTabletDumpedMediumInfo *list = nullptr; + + if (OB_FAIL(ObTabletMdsData::load_medium_info_list(allocator, complex_addr, list))) { + LOG_WARN("failed to load medium info list", K(ret), K(complex_addr)); + } else if (OB_ISNULL(list)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, list is null", K(ret), KP(list)); + } else if (OB_FAIL(medium_info_list.init(allocator, extra_info, *list))) { + LOG_WARN("failed to init", K(ret)); + } + + ObTabletMdsData::free_medium_info_list(allocator, list); + + return ret; +} + +int ObTablet::get_fused_medium_info_list( + common::ObArenaAllocator &allocator, + ObTabletFullMemoryMdsData &mds_data) +{ + int ret = OB_SUCCESS; + mds_data.reset(); + ObTabletMdsData mds_table_data; + int64_t finish_medium_scn = 0; + ObTabletMdsData new_mds_data; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(read_mds_table(allocator, mds_table_data, false))) { + LOG_WARN("failed to read mds table", K(ret)); + } else if (OB_FAIL(get_finish_medium_scn(finish_medium_scn))) { + LOG_WARN("failed to get finish medium scn", K(ret)); + } else if (OB_FAIL(new_mds_data.init(allocator, mds_table_data, mds_data_, finish_medium_scn))) { + LOG_WARN("failed to init new mds data", K(ret), K(finish_medium_scn)); + } else if (OB_FAIL(mds_data.init(allocator, new_mds_data))) { + LOG_WARN("failed to assign mds data", K(ret), K(new_mds_data), K(mds_data_), K(mds_table_data)); + } + return ret; +} + +int ObTablet::convert_to_mds_dump_kv( + common::ObIAllocator &allocator, + const share::ObTabletAutoincSeq &auto_inc_seq, + mds::MdsDumpKV &kv) +{ + int ret = OB_SUCCESS; + mds::MdsDumpKey &key = kv.k_; + mds::MdsDumpNode &node = kv.v_; + + key.mds_table_id_ = mds::TupleTypeIdx::value; + key.mds_unit_id_ = mds::TupleTypeIdx>::value; + key.allocator_ = &allocator; + // no need to serialize dummy key + key.key_.reset(); + + node.mds_table_id_ = mds::TupleTypeIdx::value; + node.mds_unit_id_ = mds::TupleTypeIdx::value; + node.status_.union_.field_.node_type_ = mds::MdsNodeType::SET; + node.status_.union_.field_.writer_type_ = mds::WriterType::AUTO_INC_SEQ; + node.status_.union_.field_.state_ = mds::TwoPhaseCommitState::ON_COMMIT; + + node.allocator_ = &allocator; + node.writer_id_ = 0; + //node->seq_no_ = ; + node.redo_scn_ = share::SCN::minus(share::SCN::max_scn(), 1); + node.end_scn_ = share::SCN::invalid_scn(); + node.trans_version_ = share::SCN::minus(share::SCN::max_scn(), 1); + + // serialize + const int64_t size = auto_inc_seq.get_serialize_size(); + char *buffer = static_cast(allocator.alloc(size)); + int64_t pos = 0; + if (OB_ISNULL(buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret), K(size)); + } else if (OB_FAIL(auto_inc_seq.serialize(buffer, size, pos))) { + LOG_WARN("failed to serialize auto inc seq", K(ret), K(auto_inc_seq)); + } else { + node.user_data_.assign(buffer, size); + } + + if (OB_FAIL(ret)) { + if (nullptr != buffer) { + allocator.free(buffer); + } + } + + return ret; +} + +int ObTablet::convert_to_mds_dump_kv( + common::ObIAllocator &allocator, + const compaction::ObMediumCompactionInfo &info, + mds::MdsDumpKV &kv) +{ + int ret = OB_NOT_IMPLEMENT; + + return ret; +} + +int ObTablet::get_tablet_status_uncommitted_mds_dump_kv( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *&kv) +{ + int ret = OB_SUCCESS; + const ObTabletComplexAddr &complex_addr = mds_data_.tablet_status_.uncommitted_kv_; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(ObTabletMdsData::load_mds_dump_kv(allocator, complex_addr, kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } + + return ret; +} + +int ObTablet::get_tablet_status_committed_mds_dump_kv( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *&kv) +{ + int ret = OB_SUCCESS; + const ObTabletComplexAddr &complex_addr = mds_data_.tablet_status_.committed_kv_; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(ObTabletMdsData::load_mds_dump_kv(allocator, complex_addr, kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } + + return ret; +} + +int ObTablet::get_aux_tablet_info_uncommitted_mds_dump_kv( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *&kv) +{ + int ret = OB_SUCCESS; + const ObTabletComplexAddr &complex_addr = mds_data_.aux_tablet_info_.uncommitted_kv_; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(ObTabletMdsData::load_mds_dump_kv(allocator, complex_addr, kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } + + return ret; +} + +int ObTablet::get_aux_tablet_info_committed_mds_dump_kv( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *&kv) +{ + int ret = OB_SUCCESS; + const ObTabletComplexAddr &complex_addr = mds_data_.aux_tablet_info_.committed_kv_; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(ObTabletMdsData::load_mds_dump_kv(allocator, complex_addr, kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } + + return ret; +} + +int ObTablet::get_auto_inc_seq_mds_dump_kv( + common::ObIAllocator &allocator, + mds::MdsDumpKV *&kv) +{ + int ret = OB_SUCCESS; + const ObTabletComplexAddr &complex_addr = mds_data_.auto_inc_seq_; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, kv))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else { + ObTabletMemberWrapper wrapper; + const share::ObTabletAutoincSeq *auto_inc_seq = nullptr; + if (OB_FAIL(ObTabletMdsData::fetch_auto_inc_seq(complex_addr, wrapper))) { + LOG_WARN("failed to fetch auto inc seq", K(ret)); + } else if (OB_FAIL(wrapper.get_member(auto_inc_seq))) { + LOG_WARN("failed to get member", K(ret)); + } else if (OB_FAIL(convert_to_mds_dump_kv(allocator, *auto_inc_seq, *kv))) { + LOG_WARN("failed to convert to mds dump kv", K(ret)); + } + + if (OB_FAIL(ret)) { + if (nullptr != kv) { + allocator.free(kv); + } + } + } + + return ret; +} + +int ObTablet::get_medium_info_mds_dump_kv_by_key( + common::ObIAllocator &allocator, + const compaction::ObMediumCompactionInfoKey &key, + mds::MdsDumpKV *&kv) +{ + int ret = OB_NOT_IMPLEMENT; + + return ret; +} + +int ObTablet::get_medium_info_mds_dump_kv( + common::ObIAllocator &allocator, + const int64_t idx, + mds::MdsDumpKV *&kv) +{ + int ret = OB_NOT_IMPLEMENT; + + return ret; +} + +int ObTablet::check_new_mds_with_cache( + const int64_t snapshot_version, + const int64_t timeout) +{ + int ret = OB_SUCCESS; + const ObTabletID &tablet_id = get_tablet_meta().tablet_id_; + const ObLSID &ls_id = get_tablet_meta().ls_id_; + bool r_valid = false; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else { + { + SpinRLockGuard guard(mds_cache_lock_); + if (tablet_status_cache_.is_valid()) { + if (OB_FAIL(ObTabletCreateDeleteHelper::check_read_snapshot_by_commit_version( + *this, tablet_status_cache_.get_create_commit_version(), tablet_status_cache_.get_delete_commit_version(), + snapshot_version, tablet_status_cache_.get_tablet_status()))) { + LOG_WARN("failed to check read snapshot by commit version", K(ret), K(snapshot_version), K(tablet_status_cache_)); + } + r_valid = true; + } + } + if (OB_SUCC(ret) && !r_valid) { + SpinWLockGuard guard(mds_cache_lock_); + if (tablet_status_cache_.is_valid()) { + if (OB_FAIL(ObTabletCreateDeleteHelper::check_read_snapshot_by_commit_version( + *this, tablet_status_cache_.get_create_commit_version(), tablet_status_cache_.get_delete_commit_version(), + snapshot_version, tablet_status_cache_.get_tablet_status()))) { + LOG_WARN("failed to check read snapshot by commit version", K(ret), K(snapshot_version), K(tablet_status_cache_)); + } + } else if (OB_FAIL(ObTabletCreateDeleteHelper::check_status_for_new_mds(*this, snapshot_version, timeout, tablet_status_cache_))) { + if (OB_TABLET_NOT_EXIST != ret) { + LOG_WARN("failed to check status for new mds", KR(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(timeout)); + } + } + } + } + + // Todo yq: for quick debug, remove later + ObTaskController::get().allow_next_syslog(); + LOG_INFO("get tablet status from cache", K(ret), K(r_valid), K(tablet_id), K(ls_id), K(tablet_status_cache_), + K(snapshot_version), KP(this)); + + return ret; +} + +int ObTablet::check_tablet_status_for_read_all_committed() +{ + int ret = OB_SUCCESS; + const ObTabletID &tablet_id = get_tablet_meta().tablet_id_; + const ObLSID &ls_id = get_tablet_meta().ls_id_; + ObTabletCreateDeleteMdsUserData user_data; + + if (OB_FAIL(get_tablet_status(share::SCN::max_scn(), user_data, 0/*timeout*/))) { + LOG_WARN("failed to get tablet status", K(ret), K(ls_id), K(tablet_id)); + } else if (ObTabletStatus::NORMAL == user_data.tablet_status_ + || ObTabletStatus::TRANSFER_IN == user_data.tablet_status_ + || ObTabletStatus::TRANSFER_OUT == user_data.tablet_status_) { + // do nothing + } else { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("tablet does not exist", K(ret), K(ls_id), K(tablet_id), K(user_data)); + } + + return ret; +} + +int ObTablet::set_tablet_status( + const ObTabletCreateDeleteMdsUserData &tablet_status, + mds::MdsCtx &ctx) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else { + SpinWLockGuard guard(mds_cache_lock_); + if (OB_FAIL(ObITabletMdsInterface::set(tablet_status, ctx))) { + LOG_WARN("failed to set mds data", K(ret)); + } else { + tablet_status_cache_.reset(); + } + } + return ret; +} + +int ObTablet::replay_set_tablet_status( + const share::SCN &scn, + const ObTabletCreateDeleteMdsUserData &tablet_status, + mds::MdsCtx &ctx) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else { + SpinWLockGuard guard(mds_cache_lock_); + if (OB_FAIL(ObITabletMdsInterface::replay(tablet_status, ctx, scn))) { + LOG_WARN("failed to replay mds data", K(ret)); + } else { + tablet_status_cache_.reset(); + } + } + return ret; +} + +int ObTablet::check_schema_version_with_cache( + const int64_t schema_version, + const int64_t timeout) +{ + int ret = OB_SUCCESS; + const ObTabletID &tablet_id = get_tablet_meta().tablet_id_; + bool r_valid = false; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(timeout < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(timeout)); + } else { + { + SpinRLockGuard guard(mds_cache_lock_); + if (ddl_data_cache_.is_valid()) { + if (OB_FAIL(check_schema_version(schema_version))) { + LOG_WARN("fail to check schema version", K(ret)); + } + r_valid = true; + } + } + + if (OB_SUCC(ret) && !r_valid) { + SpinWLockGuard guard(mds_cache_lock_); + if (ddl_data_cache_.is_valid()) { + if (OB_FAIL(check_schema_version(schema_version))) { + LOG_WARN("fail to check schema version", K(ret)); + } + } else { + ObTabletBindingMdsUserData tmp_ddl_data; + if (OB_FAIL(ObITabletMdsInterface::get_ddl_data(share::SCN::max_scn(), tmp_ddl_data, timeout))) { + LOG_WARN("failed to get snapshot", KR(ret), K(timeout)); + } else if (FALSE_IT(ddl_data_cache_.set_value(tmp_ddl_data))) { + } else if (OB_FAIL(check_schema_version(schema_version))) { + LOG_WARN("fail to check schema version", K(ret), K(ddl_data_cache_)); + } + } + } + } + + // Todo yq: for quick debug, remove later + ObTaskController::get().allow_next_syslog(); + LOG_INFO("check ddl info schema version with cache", K(ret), K(r_valid), K(tablet_id), K(ls_id), K(ddl_data_cache_), + K(schema_version), K(timeout), KP(this)); + return ret; +} + +int ObTablet::check_schema_version(int64_t schema_version) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(schema_version < ddl_data_cache_.get_schema_version())) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("use stale schema before ddl", K(ret), K(get_tablet_meta().tablet_id_), + K(ddl_data_cache_.get_schema_version()), K(schema_version)); + } + return ret; +} + +int ObTablet::check_snapshot_readable_with_cache( + const int64_t snapshot_version, + const int64_t timeout) +{ + int ret = OB_SUCCESS; + const ObTabletID &tablet_id = get_tablet_meta().tablet_id_; + bool r_valid = false; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(timeout < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(timeout)); + } else { + { + SpinRLockGuard guard(mds_cache_lock_); + if (ddl_data_cache_.is_valid()) { + if (OB_FAIL(check_snapshot_readable(snapshot_version))) { + LOG_WARN("fail to check schema version", K(ret)); + } + r_valid = true; + } + } + + if (OB_SUCC(ret) && !r_valid) { + SpinWLockGuard guard(mds_cache_lock_); + if (ddl_data_cache_.is_valid()) { + if (OB_FAIL(check_snapshot_readable(snapshot_version))) { + LOG_WARN("fail to check snapshot version", K(ret)); + } + } else { + ObTabletBindingMdsUserData tmp_ddl_data; + if (OB_FAIL(ObITabletMdsInterface::get_ddl_data(share::SCN::max_scn(), tmp_ddl_data, timeout))) { + LOG_WARN("failed to get snapshot", KR(ret), K(timeout)); + } else if (FALSE_IT(ddl_data_cache_.set_value(tmp_ddl_data))) { + } else if (OB_FAIL(check_snapshot_readable(snapshot_version))) { + LOG_WARN("fail to check snapshot version", K(ret), K(ddl_data_cache_)); + } + } + } + } + + // Todo yq: for quick debug, remove later + ObTaskController::get().allow_next_syslog(); + LOG_INFO("check ddl info snapshot readable with cache", K(ret), K(r_valid), K(tablet_id), K(ls_id), K(ddl_data_cache_), + K(snapshot_version), K(timeout), KP(this)); + return ret; +} + +int ObTablet::check_snapshot_readable(int64_t snapshot_version) +{ + int ret = OB_SUCCESS; + const share::ObLSID &ls_id = tablet_meta_.ls_id_; + const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; + if (OB_UNLIKELY(ddl_data_cache_.is_redefined() && snapshot_version >= ddl_data_cache_.get_snapshot_version())) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("read data after ddl, need to retry on new tablet", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K_(ddl_data_cache)); + } else if (OB_UNLIKELY(!ddl_data_cache_.is_redefined() && snapshot_version < ddl_data_cache_.get_snapshot_version())) { + ret = OB_SNAPSHOT_DISCARDED; + LOG_WARN("read data before ddl", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K_(ddl_data_cache)); + } + return ret; +} + +int ObTablet::set_ddl_info( + const ObTabletBindingMdsUserData &ddl_info, + mds::MdsCtx &ctx, + const int64_t lock_timeout_us) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else { + SpinWLockGuard guard(mds_cache_lock_); + if (OB_FAIL(ObITabletMdsInterface::set(ddl_info, ctx, lock_timeout_us))) { + LOG_WARN("failed to set ddl info", K(ret)); + } else { + ddl_data_cache_.reset(); + } + } + return ret; +} + +int ObTablet::replay_set_ddl_info( + const share::SCN &scn, + const ObTabletBindingMdsUserData &ddl_info, + mds::MdsCtx &ctx) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else { + SpinWLockGuard guard(mds_cache_lock_); + if (OB_FAIL(ObITabletMdsInterface::replay(ddl_info, ctx, scn))) { + LOG_WARN("failed to replay set ddl info", K(ret)); + } else { + ddl_data_cache_.reset(); + } + } + return ret; +} + +bool ObTablet::is_empty_shell() const +{ + return table_store_addr_.addr_.is_none(); +} + +bool ObTablet::is_data_complete() const +{ + return !is_empty_shell() + && !tablet_meta_.has_transfer_table() + && tablet_meta_.ha_status_.is_data_status_complete(); +} + int ObTablet::check_valid(const bool ignore_ha_status) const { int ret = OB_SUCCESS; @@ -3399,13 +5964,12 @@ int ObTablet::check_valid(const bool ignore_ha_status) const return ret; } +// only check storage_schema & medium_list when ha_status is none int ObTablet::inner_check_valid(const bool ignore_ha_status) const { int ret = OB_SUCCESS; const bool need_check_ha = tablet_meta_.ha_status_.is_none() && !ignore_ha_status; - if (need_check_ha && OB_FAIL(check_max_sync_schema_version())) { - LOG_WARN("fialed to check max sync schema version", K(ret), KPC(this)); - } else if (need_check_ha && OB_FAIL(check_medium_list())) { + if (need_check_ha && OB_FAIL(check_medium_list())) { LOG_WARN("failed to check medium list", K(ret), KPC(this)); } else if (OB_FAIL(check_sstable_column_checksum())) { LOG_WARN("failed to check sstable column checksum", K(ret), KPC(this)); diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h old mode 100644 new mode 100755 index 513d3985d..edde1c6f2 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -22,14 +22,20 @@ #include "storage/compaction/ob_medium_compaction_mgr.h" #include "storage/memtable/ob_memtable.h" #include "storage/meta_mem/ob_tablet_map_key.h" +#include "storage/meta_mem/ob_tablet_pointer.h" #include "storage/meta_mem/ob_meta_pointer_map.h" +#include "storage/tablet/ob_tablet_complex_addr.h" +#include "storage/tablet/ob_tablet_member_wrapper.h" #include "storage/tablet/ob_tablet_memtable_mgr.h" #include "storage/tablet/ob_tablet_meta.h" #include "storage/tablet/ob_tablet_table_store.h" #include "storage/tablet/ob_tablet_table_store_flag.h" +#include "storage/tablet/ob_tablet_mds_data.h" +#include "storage/tablet/ob_tablet_mds_data_cache.h" #include "storage/tx/ob_trans_define.h" #include "share/scn.h" -#include "storage/meta_mem/ob_tablet_pointer.h" +#include "ob_i_tablet_mds_interface.h" +#include namespace oceanbase { @@ -69,6 +75,16 @@ namespace transaction class ObTransID; } +namespace logservice +{ +class ObTabletReplayExecutor; +} + +namespace observer +{ +class ObAllVirtualMdsNodeStat; +} + namespace storage { class ObStoreCtx; @@ -76,36 +92,40 @@ class ObTableHandleV2; class ObFreezer; class ObTabletDDLInfo; class ObTabletDDLKvMgr; +class ObDDLKVHandle; class ObStorageSchema; class ObTabletTableIterator; class ObMetaDiskAddr; +class ObTabletMdsDumpStruct; +class ObTabletCreateDeleteMdsUserData; +class ObTabletBindingMdsUserData; +class ObMemtableArray; -class ObTablet +class ObTablet final : public ObITabletMdsInterface { friend class ObLSTabletService; - friend class ObTabletCreateDeleteHelper; - friend class ObTabletBindingHelper; friend class ObTabletPointer; - friend class ObTabletStatusChecker; + friend class ObTabletMediumInfoReader; + friend class logservice::ObTabletReplayExecutor; + friend class ObTabletPersister; + friend class ObMetaPointerMap; + friend class observer::ObAllVirtualMdsNodeStat;// for virtual table to show inner mds states + friend class ObTabletTableIterator; public: typedef ObMetaPointerHandle ObTabletPointerHandle; + typedef common::ObSEArray ObTableHandleArray; typedef common::ObFixedArray ColDescArray; public: ObTablet(); ObTablet(const ObTablet&) = delete; ObTablet &operator=(const ObTablet&) = delete; - ~ObTablet(); - + virtual ~ObTablet(); public: void reset(); bool is_ls_inner_tablet() const; bool is_ls_tx_data_tablet() const; bool is_ls_tx_ctx_tablet() const; bool is_data_tablet() const; - bool is_local_index_tablet() const; - bool is_lob_meta_tablet() const; - bool is_lob_piece_tablet() const; - bool is_aux_tablet() const; void update_wash_score(const int64_t score); void inc_ref(); int64_t dec_ref(); @@ -114,70 +134,114 @@ public: int get_rec_log_scn(share::SCN &rec_scn); int get_max_sync_medium_scn(int64_t &max_medium_scn) const; int get_max_sync_storage_schema_version(int64_t &max_schema_version) const; + int get_mds_table_rec_log_scn(share::SCN &rec_scn); + int mds_table_flush(const share::SCN &recycle_scn); + public: // first time create tablet int init( + common::ObArenaAllocator &allocator, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const common::ObTabletID &data_tablet_id, - const common::ObTabletID &lob_meta_tablet_id, - const common::ObTabletID &lob_piece_tablet_id, const share::SCN &create_scn, const int64_t snapshot_version, const share::schema::ObTableSchema &table_schema, const lib::Worker::CompatMode compat_mode, const ObTabletTableStoreFlag &store_flag, - ObTableHandleV2 &table_handle, + blocksstable::ObSSTable *sstable, ObFreezer *freezer); // dump/merge build new multi version tablet int init( + common::ObArenaAllocator &allocator, const ObUpdateTableStoreParam ¶m, + const ObTablet &old_tablet); + // dump/merge mds table to tablet_meta + int init( + common::ObArenaAllocator &allocator, const ObTablet &old_tablet, - const ObTabletTxMultiSourceDataUnit &tx_data, - const ObTabletBindingInfo &ddl_data, - const share::ObTabletAutoincSeq &autoinc_seq); + const share::SCN &flush_scn, + const ObTabletMdsData &mds_table_data, + const ObTabletMdsData &base_data); // transfer build new tablet int init( + common::ObArenaAllocator &allocator, const ObMigrationTabletParam ¶m, const bool is_update, ObFreezer *freezer); //batch update table store with range cut int init( + common::ObArenaAllocator &allocator, const ObBatchUpdateTableStoreParam ¶m, - const ObTablet &old_tablet, - const ObTabletTxMultiSourceDataUnit &tx_data, - const ObTabletBindingInfo &ddl_data, - const share::ObTabletAutoincSeq &autoinc_seq); + const ObTablet &old_tablet); // update medium compaction info mgr and build new tablet - int init_with_update_medium_info(const ObTablet &old_tablet); + int init_with_update_medium_info( + common::ObArenaAllocator &allocator, + const ObTablet &old_tablet); // batch replace sstables without data modification int init( - const ObIArray &table_handles, - const ObTablet &old_tablet, - const ObTabletTxMultiSourceDataUnit &tx_data, - const ObTabletBindingInfo &ddl_data, - const share::ObTabletAutoincSeq &autoinc_seq); + common::ObArenaAllocator &allocator, + const ObIArray &tables, + const ObTablet &old_tablet); + + // init empty tablet for delete + int init_empty_shell( + ObArenaAllocator &allocator, + const ObTablet &old_tablet); bool is_valid() const; + // refresh memtable and update tablet_addr_ and table_store_addr_ sequence, only used by slog ckpt + int refresh_memtable_and_update_seq(const uint64_t seq); + void dec_macro_ref_cnt(); + int inc_macro_ref_cnt(); + // these interfaces is only for tiny mode + // load_$member: member will always exist in disk(slog file/macro block), so read from disk then deserialize + // fetch_$member: member may exist in memory or disk, if in memory, get it directly, if in disk, + // read from disk then put into kv cache, and return kv cache handle for caller + int fetch_table_store(ObTabletMemberWrapper &wrapper) const; + int fetch_autoinc_seq(ObTabletMemberWrapper &wrapper) const; + int load_storage_schema( + common::ObArenaAllocator &allocator, + const ObStorageSchema *&storage_schema) const; + int read_medium_info_list( + common::ObArenaAllocator &allocator, + const compaction::ObMediumCompactionInfoList *&medium_info_list) const; + + static void free_storage_schema(common::ObIAllocator &allocator, const ObStorageSchema *storage_schema); + + void set_tablet_addr(const ObMetaDiskAddr &tablet_addr); + void set_allocator(ObArenaAllocator *allocator) { allocator_ = allocator; } + void set_next_full_tablet(const ObTabletHandle &next_tablet_guard) { next_full_tablet_guard_ = next_tablet_guard;} + ObTabletHandle &get_next_full_tablet() { return next_full_tablet_guard_; } + void set_next_tablet(ObTablet* tablet) { next_tablet_ = tablet; } + ObTablet *get_next_tablet() { return next_tablet_; } + ObArenaAllocator *get_allocator() { return allocator_;} + bool is_empty_shell() const; + // major merge or medium merge call + bool is_data_complete() const; // serialize & deserialize - int serialize(char *buf, const int64_t len, int64_t &pos); + int serialize(char *buf, const int64_t len, int64_t &pos) const; + // for normal tablet deserialize int deserialize( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const char *buf, const int64_t len, int64_t &pos); - int load_deserialize( - common::ObIAllocator &allocator, + // for 4k tablet + int deserialize( + const char *buf, + const int64_t len, + int64_t &pos); + int rollback_ref_cnt( + common::ObArenaAllocator &allocator, const char *buf, const int64_t len, int64_t &pos); - int deserialize_post_work(); - int dec_macro_disk_ref(); - int inc_macro_disk_ref(); int64_t get_serialize_size() const; ObMetaObjGuard &get_next_tablet_guard() { return next_tablet_guard_; } - void set_next_tablet_guard(const ObMetaObjGuard &next_tablet_guard); + const ObMetaObjGuard &get_next_tablet_guard() const { return next_tablet_guard_; } + void set_next_tablet_guard(const ObTabletHandle &next_tablet_guard); void trim_tablet_list(); // dml operation @@ -208,6 +272,11 @@ public: ObRelativeTable &relative_table, ObStoreCtx &store_ctx, const blocksstable::ObDatumRowkey &rowkey); + int check_row_locked_by_myself( + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const blocksstable::ObDatumRowkey &rowkey, + bool &locked); int try_update_storage_schema( const int64_t table_id, const int64_t schema_version, @@ -215,14 +284,9 @@ public: const int64_t timeout_ts); // table operation - int get_read_tables( - const int64_t snapshot_version, - ObTabletTableIterator &iter, - const bool allow_no_ready_read); - int get_read_major_sstable( - const int64_t &major_snapshot_version, - ObTabletTableIterator &iter); - int get_all_sstables(common::ObIArray &sstables) const; + int get_tablet_meta_ids(ObIArray &meta_ids) const; + int get_all_tables(ObTableStoreIterator &iter) const; + int get_all_sstables(ObTableStoreIterator &iter) const; int get_sstables_size(int64_t &used_size, const bool ignore_shared_block = false) const; int get_memtables(common::ObIArray &memtables, const bool need_active = false) const; int get_ddl_memtables(common::ObIArray &ddl_memtables) const; @@ -231,6 +295,7 @@ public: // memtable operation ObIMemtableMgr *get_memtable_mgr() const { return memtable_mgr_; } // TODO(bowen.gbw): get memtable mgr from tablet pointer handle + // get the active memtable for write or replay. int get_active_memtable(ObTableHandleV2 &handle) const; int release_memtables(const share::SCN scn); @@ -241,10 +306,15 @@ public: int reset_storage_related_member(); // multi-source data operation - int check_tx_data(bool &is_valid) const; - int get_tx_data(ObTabletTxMultiSourceDataUnit &tx_data, const bool check_valid = true) const; - int get_ddl_data(ObTabletBindingInfo &ddl_data) const; - int get_tablet_status(ObTabletStatus::Status &tablet_status); + int get_auto_inc_seq(common::ObArenaAllocator &allocator, share::ObTabletAutoincSeq &auto_inc_seq) const; + int get_storage_schema_for_transfer_in( + common::ObArenaAllocator &allocator, + ObStorageSchema &storage_schema) const; + int get_medium_info_list( + common::ObArenaAllocator &allocator, + compaction::ObMediumCompactionInfoList &medium_info_list) const; + + int get_restore_status(ObTabletRestoreStatus::STATUS &restore_status); template int prepare_data(T &multi_source_data_unit, const transaction::ObMulSourceDataNotifyArg &trans_flags); @@ -253,8 +323,6 @@ public: T &multi_source_data_unit, const share::SCN &scn, const bool for_replay); - template - int set_multi_data_for_commit(T &multi_source_data_unit, const share::SCN &log_scn, const bool for_replay, const memtable::MemtableRefOp ref_op); template int save_multi_source_data_unit( @@ -283,10 +351,6 @@ public: ObRelativeTable &relative_table, ObRowsInfo &rows_info, bool &exists); - static int prepare_memtable( - ObRelativeTable &relative_table, - ObStoreCtx &store_ctx, - memtable::ObMemtable *&write_memtable); // migration section // used for migration source generating create tablet rpc argument @@ -299,6 +363,14 @@ public: ObTableStoreIterator &iter, bool &is_ready_for_read); int get_ha_sstable_size(int64_t &data_size); + //transfer + int build_transfer_tablet_param( + const share::ObLSID &dest_ls_id, + ObMigrationTabletParam &mig_tablet_param); + int build_transfer_in_tablet_status_( + const ObTabletCreateDeleteMdsUserData &user_data, + ObTabletMdsData &mds_data, + common::ObIAllocator &allocator); // for restore // check whether we have dumped a sstable or not. @@ -308,27 +380,24 @@ public: int set_ddl_kv_mgr(const ObDDLKvMgrHandle &ddl_kv_mgr_handle); int remove_ddl_kv_mgr(const ObDDLKvMgrHandle &ddl_kv_mgr_handle); int start_ddl_if_need(); - int get_ddl_sstable_handles(ObTablesHandleArray &ddl_sstable_handles); + int get_ddl_sstables(ObTableStoreIterator &table_store_iter) const; + int get_mini_minor_sstables(ObTableStoreIterator &table_store_iter) const; + int get_table(const ObITable::TableKey &table_key, ObTableHandleV2 &handle) const; + int get_recycle_version(const int64_t multi_version_start, int64_t &recycle_version) const; int get_migration_sstable_size(int64_t &data_size); // other + const ObMetaDiskAddr &get_tablet_addr() const { return tablet_addr_; } const ObTabletMeta &get_tablet_meta() const { return tablet_meta_; } - const ObTabletTableStore &get_table_store() const { return table_store_; } share::SCN get_clog_checkpoint_scn() const { return tablet_meta_.clog_checkpoint_scn_; } + share::SCN get_mds_checkpoint_scn() const { return tablet_meta_.mds_checkpoint_scn_; } int64_t get_snapshot_version() const { return tablet_meta_.snapshot_version_; } int64_t get_multi_version_start() const { return tablet_meta_.multi_version_start_; } int get_multi_version_start(share::SCN &scn) const; int get_snapshot_version(share::SCN &scn) const; - // deprecated later, DO NOT use it! - ObTabletTableStore &get_table_store() { return table_store_; } - - const ObStorageSchema &get_storage_schema() const { return storage_schema_; } - - const ObTableReadInfo &get_full_read_info() const { return full_read_info_; } - const ObTableReadInfo &get_index_read_info() const { return *full_read_info_.get_index_read_info(); } + const ObITableReadInfo &get_rowkey_read_info() const { return *rowkey_read_info_; } const ObTabletPointerHandle &get_pointer_handle() { return pointer_hdl_; } - const compaction::ObMediumCompactionInfoList &get_medium_compaction_info_list() const { return medium_info_list_; } int get_meta_disk_addr(ObMetaDiskAddr &addr) const; @@ -339,7 +408,8 @@ public: const char *buf, const int64_t buf_size, int64_t &pos); - int get_schema_version_from_storage_schema(int64_t &schema_version); + //Deprecated interface, DONOT use it anymore + int get_schema_version_from_storage_schema(int64_t &schema_version) const; int submit_medium_compaction_clog( compaction::ObMediumCompactionInfo &medium_info, @@ -354,10 +424,7 @@ public: const uint64_t cache_size, share::ObTabletAutoincInterval &result); - int get_latest_autoinc_seq(share::ObTabletAutoincSeq &autoinc_seq) const; - int update_tablet_autoinc_seq( - const uint64_t autoinc_seq, - const share::SCN &replay_scn); + int update_tablet_autoinc_seq(const uint64_t autoinc_seq); static int get_kept_multi_version_start( ObLS &ls, const ObTablet &tablet, @@ -380,33 +447,104 @@ public: const bool for_replay, const memtable::MemtableRefOp ref_op = memtable::MemtableRefOp::NONE, const bool is_callback = false); - int get_max_medium_snapshot(int64_t &max_medium_snapshot) const; int get_msd_from_memtables( memtable::ObIMultiSourceDataUnit &msd, ObIAllocator *allocator = nullptr, const bool get_latest = true) const; - 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); + int check_and_set_initial_state(); + int set_memtable_clog_checkpoint_scn(const ObMigrationTabletParam *tablet_meta); + int read_mds_table(common::ObIAllocator &allocator, ObTabletMdsData &mds_data, const bool for_flush); + int notify_mds_table_flush_ret( + const share::SCN &flush_scn, + const int flush_ret); int clear_memtables_on_table_store(); // be careful to call this func, will destroy memtables array on table_store + int64_t get_memtable_count() const { return memtable_count_; } + + // tablet mds data read interface + int get_tablet_status_uncommitted_mds_dump_kv( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *&kv); + int get_tablet_status_committed_mds_dump_kv( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *&kv); + int get_aux_tablet_info_uncommitted_mds_dump_kv( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *&kv); + int get_aux_tablet_info_committed_mds_dump_kv( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *&kv); + int get_auto_inc_seq_mds_dump_kv( + common::ObIAllocator &allocator, + mds::MdsDumpKV *&kv); + int get_medium_info_mds_dump_kv_by_key( + common::ObIAllocator &allocator, + const compaction::ObMediumCompactionInfoKey &key, + mds::MdsDumpKV *&kv); + int get_medium_info_mds_dump_kv( + common::ObIAllocator &allocator, + const int64_t idx, + mds::MdsDumpKV *&kv); + + int check_new_mds_with_cache(const int64_t snapshot_version, const int64_t timeout); + int check_tablet_status_for_read_all_committed(); + int check_schema_version_with_cache(const int64_t schema_version, const int64_t timeout); + int check_snapshot_readable_with_cache(const int64_t snapshot_version, const int64_t timeout); + int set_tablet_status( + const ObTabletCreateDeleteMdsUserData &tablet_status, + mds::MdsCtx &ctx); + int replay_set_tablet_status( + const share::SCN &scn, + const ObTabletCreateDeleteMdsUserData &tablet_status, + mds::MdsCtx &ctx); + int set_ddl_info( + const ObTabletBindingMdsUserData &ddl_info, + mds::MdsCtx &ctx, + const int64_t lock_timeout_us); + int replay_set_ddl_info( + const share::SCN &scn, + const ObTabletBindingMdsUserData &ddl_info, + mds::MdsCtx &ctx); + + int set_frozen_for_all_memtables(); // different from the is_valid() function // typically used for check valid for migration or restore int check_valid(const bool ignore_ha_status = false) const; - TO_STRING_KV(KP(this), K_(wash_score), K_(ref_cnt), K_(tablet_meta), K_(table_store), K_(storage_schema), - K_(medium_info_list)); + + int get_fused_medium_info_list( + common::ObArenaAllocator &allocator, + ObTabletFullMemoryMdsData &mds_data); + int64_t to_string(char *buf, const int64_t buf_len) const; +protected:// for MDS use + virtual bool check_is_inited_() const override final { return is_inited_; } + virtual const ObTabletMdsData &get_mds_data_() const override final { return mds_data_; } + virtual const ObTabletMeta &get_tablet_meta_() const override final { return tablet_meta_; } + virtual int get_mds_table_handle_(mds::MdsTableHandle &handle, + const bool create_if_not_exist) const override final; + virtual ObTabletPointer *get_tablet_ponter_() const override final { + return static_cast(pointer_hdl_.get_resource_ptr()); + } +private: + void set_mem_addr(); + int check_meta_addr() const; + static int parse_meta_addr(const ObMetaDiskAddr &addr, ObIArray &meta_ids); + int inner_inc_macro_ref_cnt(); + void dec_table_store_ref_cnt(); + int inc_table_store_ref_cnt(bool &inc_success); + void dec_addr_ref_cnt(const ObMetaDiskAddr &addr); + int inc_addr_ref_cnt(const ObMetaDiskAddr &addr, bool &inc_success); + private: int inner_check_valid(const bool ignore_ha_status = false) const; int get_min_medium_snapshot(int64_t &min_medium_snapshot) const; + int64_t get_self_size() const; int get_memtable_mgr(ObIMemtableMgr *&memtable_mgr) const; + int check_schema_version(const int64_t schema_version); + int check_snapshot_readable(const int64_t snapshot_version); logservice::ObLogHandler *get_log_handler() const { return log_handler_; } // TODO(bowen.gbw): get log handler from tablet pointer handle - common::ObThreadCond &get_cond(); - common::TCRWLock &get_rw_lock(); int init_shared_params( const share::ObLSID &ls_id, @@ -415,16 +553,15 @@ private: const int64_t max_saved_medium_scn, const lib::Worker::CompatMode compat_mode, ObFreezer *freezer); - int build_read_info(common::ObIAllocator &allocator); + int build_read_info(common::ObArenaAllocator &allocator, const ObTablet *tablet = nullptr); int create_memtable(const int64_t schema_version, const share::SCN clog_checkpoint_scn, const bool for_replay=false); int try_update_start_scn(); int try_update_ddl_checkpoint_scn(); int try_update_table_store_flag(const ObUpdateTableStoreParam ¶m); int get_max_schema_version(int64_t &schema_version); - int inner_get_all_sstables(common::ObIArray &sstables) const; - int pre_transform_sstable_root_block(const ObTableReadInfo &index_read_info); + int inner_get_all_sstables(ObTableStoreIterator &iter) const; int choose_and_save_storage_schema( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const ObStorageSchema &tablet_schema, const ObStorageSchema ¶m_schema); int check_schema_version_for_bounded_staleness_read( @@ -433,15 +570,18 @@ private: const uint64_t table_id); int do_rowkey_exists( - ObStoreCtx &store_ctx, - const int64_t table_id, + ObTableIterParam ¶m, + ObTableAccessContext &context, const blocksstable::ObDatumRowkey &rowkey, - const common::ObQueryFlag &query_flag, bool &exists); static int do_rowkeys_exist( ObTableStoreIterator &tables_iter, ObRowsInfo &rows_info, bool &exists); + static int prepare_memtable( + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + memtable::ObMemtable *&write_memtable); // used for freeze_tablet int inner_create_memtable( @@ -449,9 +589,11 @@ private: const int64_t schema_version = 0/*0 for first memtable*/, const bool for_replay=false); + int inner_get_memtables(common::ObIArray &memtables, const bool need_active) const; + int write_sync_tablet_seq_log(share::ObTabletAutoincSeq &autoinc_seq, - const uint64_t new_autoinc_seq, share::SCN &scn); + int update_ddl_info( const int64_t schema_version, const share::SCN &scn, @@ -464,37 +606,105 @@ private: int64_t &refreshed_schema_ts) const; int get_read_tables( const int64_t snapshot_version, - ObTableStoreIterator &iter, + ObTabletTableIterator &iter, const bool allow_no_ready_read); int get_read_major_sstable( const int64_t &major_snapshot_version, - ObTableStoreIterator &iter); + ObTabletTableIterator &iter); + int auto_get_read_tables( + const int64_t snapshot_version, + ObTabletTableIterator &iter, + const bool allow_no_ready_read); + int get_read_tables_( + const int64_t snapshot_version, + ObTableStoreIterator &iter, + ObStorageMetaHandle &table_store_handle, + const bool allow_no_ready_read); + int get_read_major_sstable( + const int64_t &major_snapshot_version, + ObTableStoreIterator &iter) const; int allow_to_read_(); // multi-source data - int inner_get_tx_data(ObTabletTxMultiSourceDataUnit &tx_data, bool &exist_on_memtable) const; - int set_tx_id( - const transaction::ObTransID &tx_id, - const bool for_replay); - int set_tx_scn( - const transaction::ObTransID &tx_id, - const share::SCN &scn, - const bool for_replay); - int set_tablet_final_status( - ObTabletTxMultiSourceDataUnit &tx_data, - const share::SCN &memtable_scn, - const bool for_replay, - const memtable::MemtableRefOp ref_op); - int set_tx_data( - const ObTabletTxMultiSourceDataUnit &tx_data, - const bool for_replay, - const memtable::MemtableRefOp ref_op = memtable::MemtableRefOp::NONE, - const bool is_callback = false); - int set_tx_data_in_tablet_pointer(const ObTabletTxMultiSourceDataUnit &tx_data); - int check_max_sync_schema_version() const; int check_medium_list() const; int check_sstable_column_checksum() const; + int get_finish_medium_scn(int64_t &finish_medium_scn) const; + int read_mds_table_medium_info_list( + common::ObIAllocator &allocator, + ObTabletDumpedMediumInfo &medium_info_list) const; + int inner_get_mds_table( + mds::MdsTableHandle &mds_table, + bool not_exist_create = false) const; + + int build_mds_data( + common::ObArenaAllocator &allocator, + const share::ObTabletAutoincSeq &auto_inc_seq, + const ObTabletTxMultiSourceDataUnit &tx_data, + const ObTabletBindingInfo &ddl_data, + const compaction::ObMediumCompactionInfoList &info_list); + int build_tablet_status( + common::ObArenaAllocator &allocator, + const ObTabletTxMultiSourceDataUnit &tx_data); + int build_aux_tablet_info( + common::ObArenaAllocator &allocator, + const ObTabletTxMultiSourceDataUnit &tx_data, + const ObTabletBindingInfo &ddl_data); + int build_auto_inc_seq( + common::ObArenaAllocator &allocator, + const share::ObTabletAutoincSeq &auto_inc_seq); + static int load_medium_info_list( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &complex_addr, + const ObTaletExtraMediumInfo &extra_info, + compaction::ObMediumCompactionInfoList &medium_info_list); + int set_initial_state(const bool initial_state); + int check_initial_state(bool &initial_state); + + int load_deserialize_v1( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + const int64_t pos, + int64_t &new_pos); + int deserialize_meta_v1( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + int64_t &pos, + share::ObTabletAutoincSeq &autoinc_seq, + ObTabletTxMultiSourceDataUnit &tx_data, + ObTabletBindingInfo &ddl_data); + int load_deserialize_v2( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + const int64_t pos, + int64_t &new_pos, + const bool prepare_memtable = true /* whether to prepare memtable */); + + static int convert_to_mds_dump_kv( + common::ObIAllocator &allocator, + const share::ObTabletAutoincSeq &auto_inc_seq, + mds::MdsDumpKV &kv); + static int convert_to_mds_dump_kv( + common::ObIAllocator &allocator, + const compaction::ObMediumCompactionInfo &info, + mds::MdsDumpKV &kv); + + int get_src_tablet_read_tables_( + const int64_t snapshot_version, + const bool allow_no_ready_read, + ObTabletTableIterator &iter, + bool &succ_get_src_tables); + int get_max_data_scn_(share::SCN &scn) const; + + int prepare_param_ctx( + common::ObIAllocator &allocator, + ObRelativeTable &relative_table, + ObStoreCtx &ctx, + ObTableIterParam ¶m, + ObTableAccessContext &context); template int dec_unsynced_cnt_for_if_need( T &multi_source_data_unit, @@ -509,38 +719,73 @@ private: void print_memtables_for_table(); + // memtable operation + int pull_memtables(); + int pull_memtables_without_ddl(); + int update_memtables(); + int build_memtable(); + int build_memtable(common::ObIArray &handle_array, const int64_t start_pos = 0); + int rebuild_memtable(common::ObIArray &handle_array); + int rebuild_memtable( + const share::SCN &clog_checkpoint_scn, + common::ObIArray &handle_array); + int add_memtable(memtable::ObMemtable* const table); + int trim_empty_last_memtable(); + int assign_memtables(const ObTablet &other_tablet); + void reset_memtable(); + int pull_ddl_memtables(); + void reset_ddl_memtables(); + int wait_release_memtables_(); private: + static const int64_t MEMTABLE_ARRAY_SIZE = 16; + // ObTabletDDLKvMgr::MAX_DDL_KV_CNT_IN_STORAGE + // Array size is too large, need to shrink it if possible + static const int64_t DDL_KV_ARRAY_SIZE = 64; static const int32_t TABLET_VERSION = 1; + static const int32_t TABLET_VERSION_V2 = 2; private: int32_t version_; int32_t length_; volatile int64_t wash_score_ CACHE_ALIGNED; volatile int64_t ref_cnt_ CACHE_ALIGNED; - ObTabletPointerHandle pointer_hdl_; + ObTabletHandle next_tablet_guard_; ObTabletMeta tablet_meta_; - ObTabletTableStore table_store_; - ObStorageSchema storage_schema_; - compaction::ObMediumCompactionInfoList medium_info_list_; - + ObRowkeyReadInfo *rowkey_read_info_; + // in memory or disk + ObTabletComplexAddr table_store_addr_; + // always in disk + ObTabletComplexAddr storage_schema_addr_; + // won't persist + memtable::ObIMemtable *memtables_[MEMTABLE_ARRAY_SIZE]; + int64_t memtable_count_; + ObITable *ddl_kvs_[DDL_KV_ARRAY_SIZE]; + int64_t ddl_kv_count_; + ObTabletPointerHandle pointer_hdl_; + ObTabletHandle next_full_tablet_guard_; + ObArenaAllocator *allocator_; + ObMetaDiskAddr tablet_addr_; // NOTICE: these two pointers: memtable_mgr_ and log_handler_, // are considered as cache for tablet. // we keep it on tablet because we cannot get them in ObTablet::deserialize // through ObTabletPointerHandle. // may be some day will fix this issue, then the pointers have no need to exist. - ObIMemtableMgr *memtable_mgr_; logservice::ObLogHandler *log_handler_; + ObTabletMdsData mds_data_; - mutable common::TCRWLock table_store_lock_; // protect table store memtable cache read and update - - ObTableReadInfo full_read_info_; - common::ObIAllocator *allocator_; - ObMetaObjGuard next_tablet_guard_; + mutable common::TCRWLock memtables_lock_; // protect memtable read and update + mutable common::SpinRWLock mds_cache_lock_; + ObTabletStatusCache tablet_status_cache_; + ObDDLInfoCache ddl_data_cache_; //ATTENTION : Add a new variable need consider ObMigrationTabletParam // and tablet meta init interface for migration. // yuque : - + ObTablet *next_tablet_; // used in old_version_chain and tablet_gc_queue + // whether hold ref cnt + // when destroying tablet, only if hold_ref_cnt_ is true do we decrease meta blocks' ref cnt + // we need to set it to true after increasing meta blocks' ref cnt or deserializing tablet + bool hold_ref_cnt_; bool is_inited_; }; @@ -561,10 +806,17 @@ inline bool ObTablet::is_ls_tx_ctx_tablet() const inline bool ObTablet::is_valid() const { - return pointer_hdl_.is_valid() - && tablet_meta_.is_valid() - && table_store_.is_valid() - && storage_schema_.is_valid(); + return (!is_empty_shell() + && pointer_hdl_.is_valid() + && tablet_meta_.is_valid() + && table_store_addr_.is_valid() + && storage_schema_addr_.is_valid() + && nullptr != rowkey_read_info_) + || (is_empty_shell() + && table_store_addr_.addr_.is_none() + && storage_schema_addr_.addr_.is_none() + && mds_data_.auto_inc_seq_.addr_.is_none() + && nullptr == rowkey_read_info_); } inline bool ObTablet::is_data_tablet() const @@ -573,30 +825,9 @@ inline bool ObTablet::is_data_tablet() const && (tablet_meta_.tablet_id_ == tablet_meta_.data_tablet_id_); } -inline bool ObTablet::is_local_index_tablet() const +inline int ObTablet::allow_to_read_() { - return is_valid() - && (tablet_meta_.tablet_id_ != tablet_meta_.data_tablet_id_) - && !(tablet_meta_.ddl_data_.lob_meta_tablet_id_.is_valid()) - && !(tablet_meta_.ddl_data_.lob_piece_tablet_id_.is_valid()); -} - -inline bool ObTablet::is_lob_meta_tablet() const -{ - return is_valid() - && (tablet_meta_.tablet_id_ == tablet_meta_.ddl_data_.lob_meta_tablet_id_); -} - -inline bool ObTablet::is_lob_piece_tablet() const -{ - return is_valid() - && (tablet_meta_.tablet_id_ == tablet_meta_.ddl_data_.lob_piece_tablet_id_); -} - -inline bool ObTablet::is_aux_tablet() const -{ - return is_valid() - && (is_local_index_tablet() || is_lob_meta_tablet() || is_lob_piece_tablet()); + return tablet_meta_.ha_status_.is_none() ? common::OB_SUCCESS : common::OB_REPLICA_NOT_READABLE; } inline void ObTablet::update_wash_score(const int64_t score) @@ -616,14 +847,14 @@ inline void ObTablet::update_wash_score(const int64_t score) inline void ObTablet::inc_ref() { - int64_t cnt = ATOMIC_AAF(&ref_cnt_, 1); + const int64_t cnt = ATOMIC_AAF(&ref_cnt_, 1); const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; STORAGE_LOG(DEBUG, "tablet inc ref", KP(this), K(tablet_id), "ref_cnt", cnt, K(lbt())); } inline int64_t ObTablet::dec_ref() { - int64_t cnt = ATOMIC_SAF(&ref_cnt_, 1/* just sub 1 */); + const int64_t cnt = ATOMIC_SAF(&ref_cnt_, 1/* just sub 1 */); const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; STORAGE_LOG(DEBUG, "tablet dec ref", KP(this), K(tablet_id), "ref_cnt", cnt, K(lbt())); @@ -664,114 +895,6 @@ int ObTablet::prepare_data(T &multi_source_data_unit, const transaction::ObMulSo return ret; } -template -int ObTablet::set_multi_data_for_commit( - T &multi_source_data_unit, - const share::SCN &scn, - const bool for_replay, - const memtable::MemtableRefOp ref_op) -{ - int ret = OB_SUCCESS; - - bool is_callback = true; - TRANS_LOG(INFO, "set_multi_data_for_commit", K(multi_source_data_unit), K(ref_op)); - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - TRANS_LOG(WARN, "not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!multi_source_data_unit.is_valid())) { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid args", K(ret), K(multi_source_data_unit)); - } else if (!multi_source_data_unit.is_tx_end()) { - if (OB_FAIL(save_multi_source_data_unit(&multi_source_data_unit, scn, for_replay, ref_op, is_callback))) { - TRANS_LOG(WARN, "failed to save tx data", K(ret), K(multi_source_data_unit), K(for_replay), K(ref_op)); - } - } else if (OB_FAIL(inner_set_multi_data_for_commit(multi_source_data_unit, scn, for_replay, ref_op))) { - TRANS_LOG(WARN, "failed to back_fill_scn_for_ddl_data", K(ret), K(multi_source_data_unit)); - } - return ret; -} - -template -int ObTablet::dec_unsynced_cnt_for_if_need( - T &multi_source_data_unit, - const bool for_replay, - const memtable::MemtableRefOp ref_op) -{ - int ret = OB_SUCCESS; - const share::SCN scn = share::SCN::max_scn(); - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - TRANS_LOG(WARN, "not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!multi_source_data_unit.is_valid())) { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid args", K(ret), K(multi_source_data_unit)); - } else if (memtable::MultiSourceDataUnitType::TABLET_TX_DATA == multi_source_data_unit.type()) { - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(get_tx_data(tx_data))) { - TRANS_LOG(WARN, "failed to get tx data", K(ret)); - } else if (OB_FAIL(save_multi_source_data_unit(&tx_data, scn, for_replay, ref_op, true/*is_callback*/))) { - TRANS_LOG(WARN, "failed to save tx data", K(ret), K(tx_data), K(scn)); - } - } else if (memtable::MultiSourceDataUnitType::TABLET_BINDING_INFO == multi_source_data_unit.type()) { - ObTabletBindingInfo binding_info; - if (OB_FAIL(get_ddl_data(binding_info))) { - TRANS_LOG(WARN, "failed to get binding info", K(ret)); - } else if (OB_FAIL(save_multi_source_data_unit(&binding_info, scn, for_replay, ref_op, true/*is_callback*/))) { - TRANS_LOG(WARN, "failed to binding info", K(ret), K(binding_info), K(scn)); - } - } else { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "multi-data type not support", K(ret), K(multi_source_data_unit)); - } - return ret; -} - -template -int ObTablet::inner_set_multi_data_for_commit( - T &multi_source_data_unit, - const share::SCN &scn, - const bool for_replay, - const memtable::MemtableRefOp ref_op) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - TRANS_LOG(WARN, "not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!multi_source_data_unit.is_valid())) { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid args", K(ret), K(multi_source_data_unit)); - } else if (OB_FAIL(dec_unsynced_cnt_for_if_need(multi_source_data_unit, for_replay, ref_op))) { - TRANS_LOG(WARN, "failed to dec_unsynced_cnt_for_ddl_data_if_need", K(ret), K(multi_source_data_unit), K(for_replay), K(ref_op)); - } else if (memtable::MultiSourceDataUnitType::TABLET_TX_DATA == multi_source_data_unit.type()) { - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(get_tx_data(tx_data))) { - TRANS_LOG(WARN, "failed to get tx data", K(ret)); - } else if (OB_FAIL(tx_data.deep_copy(&multi_source_data_unit))) { - TRANS_LOG(WARN, "fail to deep_copy", K(ret), K(multi_source_data_unit), K(tx_data), K(get_tablet_meta())); - } else if (OB_FAIL(clear_unsynced_cnt_for_tx_end_if_need(tx_data, scn, for_replay))) { - TRANS_LOG(WARN, "failed to save tx data", K(ret), K(tx_data), K(scn)); - } - } else if (memtable::MultiSourceDataUnitType::TABLET_BINDING_INFO == multi_source_data_unit.type()) { - ObTabletBindingInfo binding_info; - if (OB_FAIL(get_ddl_data(binding_info))) { - TRANS_LOG(WARN, "failed to get binding info", K(ret)); - - } else if (OB_FAIL(binding_info.deep_copy(&multi_source_data_unit))) { - TRANS_LOG(WARN, "fail to deep_copy", K(ret), K(multi_source_data_unit), K(binding_info), K(get_tablet_meta())); - } else if (OB_FAIL(clear_unsynced_cnt_for_tx_end_if_need(binding_info, scn, for_replay))) { - TRANS_LOG(WARN, "failed to save ddl data", K(ret), K(multi_source_data_unit), K(scn)); - } - } else { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "multi-data type not support", K(ret), K(multi_source_data_unit)); - } - - return ret; -} - - template int ObTablet::clear_unsynced_cnt_for_tx_end_if_need( T &multi_source_data_unit, diff --git a/src/storage/tablet/ob_tablet_binding_helper.cpp b/src/storage/tablet/ob_tablet_binding_helper.cpp old mode 100644 new mode 100755 index a91de4255..2eb6f1f54 --- a/src/storage/tablet/ob_tablet_binding_helper.cpp +++ b/src/storage/tablet/ob_tablet_binding_helper.cpp @@ -13,7 +13,7 @@ #define USING_LOG_PREFIX STORAGE #include "storage/tablet/ob_tablet_binding_helper.h" - +#include "storage/tablet/ob_tablet_binding_replay_executor.h" #include "lib/ob_abort.h" #include "lib/lock/ob_tc_rwlock.h" #include "lib/utility/ob_unify_serialize.h" @@ -21,6 +21,7 @@ #include "storage/ls/ob_ls.h" #include "storage/memtable/ob_memtable.h" #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/multi_data_source/mds_ctx.h" #include "storage/tablet/ob_tablet_common.h" #include "storage/tablet/ob_tablet_create_delete_helper.h" #include "storage/tx/ob_trans_define.h" @@ -39,83 +40,13 @@ namespace oceanbase namespace storage { -ObTabletBindingInfo::ObTabletBindingInfo() - : redefined_(false), - snapshot_version_(INT64_MAX), - schema_version_(INT64_MAX), - data_tablet_id_(), - hidden_tablet_ids_(), - lob_meta_tablet_id_(), - lob_piece_tablet_id_() -{ -} - -void ObTabletBindingInfo::reset() -{ - redefined_ = false; - snapshot_version_ = INT64_MAX; - schema_version_ = INT64_MAX; - data_tablet_id_.reset(); - hidden_tablet_ids_.reset(); - lob_meta_tablet_id_.reset(); - lob_piece_tablet_id_.reset(); -} - -bool ObTabletBindingInfo::is_valid() const -{ - bool valid = true; - - if (INT64_MAX == snapshot_version_) { - valid = false; - } else if (INT64_MAX == schema_version_) { - valid = false; - } - - return valid; -} - -int ObTabletBindingInfo::assign(const ObTabletBindingInfo &other) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(hidden_tablet_ids_.assign(other.hidden_tablet_ids_))) { - LOG_WARN("failed to assign hidden tablet ids", K(ret)); - } else { - redefined_ = other.redefined_; - snapshot_version_ = other.snapshot_version_; - schema_version_ = other.schema_version_; - data_tablet_id_ = other.data_tablet_id_; - lob_meta_tablet_id_ = other.lob_meta_tablet_id_; - lob_piece_tablet_id_ = other.lob_piece_tablet_id_; - } - return ret; -} - -int ObTabletBindingInfo::deep_copy( - const memtable::ObIMultiSourceDataUnit *src, - ObIAllocator *allocator) -{ - UNUSED(allocator); - int ret = OB_SUCCESS; - if (OB_ISNULL(src)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid src info", K(ret)); - } else if (OB_UNLIKELY(src->type() != type())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid type", K(ret)); - } else if (OB_FAIL(assign(*static_cast(src)))) { - LOG_WARN("failed to copy tablet binding info", K(ret)); - } - return ret; -} - -OB_SERIALIZE_MEMBER(ObTabletBindingInfo, redefined_, snapshot_version_, schema_version_, data_tablet_id_, hidden_tablet_ids_, lob_meta_tablet_id_, lob_piece_tablet_id_); - ObBatchUnbindTabletArg::ObBatchUnbindTabletArg() : tenant_id_(OB_INVALID_ID), ls_id_(), schema_version_(OB_INVALID_VERSION), orig_tablet_ids_(), - hidden_tablet_ids_() + hidden_tablet_ids_(), + is_old_mds_(false) { } @@ -130,592 +61,35 @@ int ObBatchUnbindTabletArg::assign(const ObBatchUnbindTabletArg &other) tenant_id_ = other.tenant_id_; ls_id_ = other.ls_id_; schema_version_ = other.schema_version_; + is_old_mds_ = other.is_old_mds_; } return ret; } -OB_SERIALIZE_MEMBER(ObBatchUnbindTabletArg, tenant_id_, ls_id_, schema_version_, orig_tablet_ids_, hidden_tablet_ids_); - -// lock non-creating orig tablet and data tablets -int ObTabletBindingHelper::lock_tablet_binding_for_create( - const ObBatchCreateTabletArg &arg, - ObLS &ls, - const ObMulSourceDataNotifyArg &trans_flags, - ObTabletBindingPrepareCtx &ctx) +OB_DEF_SERIALIZE(ObBatchUnbindTabletArg) { int ret = OB_SUCCESS; - ctx.skip_idx_.reset(); - ctx.last_idx_ = -1; - ObTabletBindingHelper helper(ls, trans_flags); - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); i++) { - const ObCreateTabletInfo &info = arg.tablets_[i]; - // for mixed tablets, no need to lock data tablet because it will be locked on creating - if (is_contain(ctx.skip_idx_, i)) { - // do nothing - } else if (ObTabletCreateDeleteHelper::is_pure_hidden_tablets(info)) { - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - int64_t aux_idx = -1; - if (ObTabletCreateDeleteHelper::find_related_aux_info(arg, info.tablet_ids_.at(j), aux_idx) - && OB_FAIL(ctx.skip_idx_.push_back(aux_idx))) { - LOG_WARN("failed to push related aux idx", K(ret), K(aux_idx)); - } - } - if (OB_SUCC(ret)) { - ctx.last_idx_ = i; - if (OB_FAIL(helper.lock_tablet_binding(info.data_tablet_id_))) { - LOG_WARN("failed to lock orig tablet binding", K(ret)); - } - } - } else if (ObTabletCreateDeleteHelper::is_pure_aux_tablets(info)) { - if (has_lob_tablets(arg, info)) { - ctx.last_idx_ = i; - if (OB_FAIL(helper.lock_tablet_binding(info.data_tablet_id_))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } - } - } - } + LST_DO_CODE(OB_UNIS_ENCODE, tenant_id_, ls_id_, schema_version_, orig_tablet_ids_, hidden_tablet_ids_, is_old_mds_); return ret; } -void ObTabletBindingHelper::rollback_lock_tablet_binding_for_create( - const ObBatchCreateTabletArg &arg, - ObLS &ls, - const ObMulSourceDataNotifyArg &prepare_trans_flags, - const ObTabletBindingPrepareCtx &ctx) +OB_DEF_SERIALIZE_SIZE(ObBatchUnbindTabletArg) { - if (arg.is_valid()) { - int tmp_ret = OB_SUCCESS; - ObMulSourceDataNotifyArg trans_flags = prepare_trans_flags; - trans_flags.notify_type_ = NotifyType::ON_ABORT; - ObTabletBindingHelper helper(ls, trans_flags); - for (int64_t i = 0; i <= ctx.last_idx_ && i < arg.tablets_.count(); i++) { - const ObCreateTabletInfo &info = arg.tablets_[i]; - if (is_contain(ctx.skip_idx_, i)) { - // do nothing - } else if (ObTabletCreateDeleteHelper::is_pure_hidden_tablets(info)) { - if (OB_TMP_FAIL(helper.unlock_tablet_binding(info.data_tablet_id_))) { - LOG_ERROR_RET(tmp_ret, "failed to lock orig tablet binding", K(tmp_ret)); - } - } else if (ObTabletCreateDeleteHelper::is_pure_aux_tablets(info)) { - if (has_lob_tablets(arg, info) && OB_TMP_FAIL(helper.unlock_tablet_binding(info.data_tablet_id_))) { - LOG_ERROR_RET(tmp_ret, "failed to lock tablet binding", K(tmp_ret)); - } - } - } - } - return; + int len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, tenant_id_, ls_id_, schema_version_, orig_tablet_ids_, hidden_tablet_ids_, is_old_mds_); + return len; } -// set log scn for non-creating orig tablets and data tablets -int ObTabletBindingHelper::set_scn_for_create(const ObBatchCreateTabletArg &arg, ObLS &ls, const ObMulSourceDataNotifyArg &trans_flags) +OB_DEF_DESERIALIZE(ObBatchUnbindTabletArg) { int ret = OB_SUCCESS; - ObSArray skip_idx; - ObTabletBindingHelper helper(ls, trans_flags); - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); i++) { - const ObCreateTabletInfo &info = arg.tablets_[i]; - if (is_contain(skip_idx, i)) { - // do nothing - } else if (ObTabletCreateDeleteHelper::is_pure_hidden_tablets(info)) { - if (OB_FAIL(helper.set_scn(info.data_tablet_id_))) { - LOG_WARN("failed to set log ts for orig tablet", K(ret)); - } - - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - int64_t aux_idx = -1; - if (ObTabletCreateDeleteHelper::find_related_aux_info(arg, info.tablet_ids_.at(j), aux_idx) - && OB_FAIL(skip_idx.push_back(aux_idx))) { - LOG_WARN("failed to push related aux idx", K(ret), K(aux_idx)); - } - } - } else if (ObTabletCreateDeleteHelper::is_pure_aux_tablets(info)) { - if (has_lob_tablets(arg, info) && OB_FAIL(helper.set_scn(info.data_tablet_id_))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } - } - } - return ret; -} - -// unlock non-creating orig tablets and data tablets -int ObTabletBindingHelper::unlock_tablet_binding_for_create(const ObBatchCreateTabletArg &arg, ObLS &ls, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObSArray skip_idx; - ObTabletBindingHelper helper(ls, trans_flags); - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); i++) { - const ObCreateTabletInfo &info = arg.tablets_[i]; - if (is_contain(skip_idx, i)) { - // do nothing - } else if (ObTabletCreateDeleteHelper::is_pure_hidden_tablets(info)) { - if (OB_FAIL(helper.unlock_tablet_binding(info.data_tablet_id_))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } - - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - int64_t aux_idx = -1; - if (ObTabletCreateDeleteHelper::find_related_aux_info(arg, info.tablet_ids_.at(j), aux_idx) - && OB_FAIL(skip_idx.push_back(aux_idx))) { - LOG_WARN("failed to push related aux idx", K(ret), K(aux_idx)); - } - } - } else if (ObTabletCreateDeleteHelper::is_pure_aux_tablets(info)) { - if (has_lob_tablets(arg, info) && OB_FAIL(helper.unlock_tablet_binding(info.data_tablet_id_))) { - LOG_WARN("failed to unlock tablet binding", K(ret)); - } - } - } - return ret; -} - -// bind aux and hidden tablets to creating and non-creating data tablet -int ObTabletBindingHelper::modify_tablet_binding_for_create( - const ObBatchCreateTabletArg &arg, - ObLS &ls, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObArray empty_array; - ObTabletBindingHelper helper(ls, trans_flags); - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); i++) { - const ObCreateTabletInfo &info = arg.tablets_[i]; - bool need_modify = false; - bool tablet_ids_as_aux_tablets = false; - if (ObTabletCreateDeleteHelper::is_pure_hidden_tablets(info)) { - need_modify = true; - } else if (ObTabletCreateDeleteHelper::is_pure_aux_tablets(info) || ObTabletCreateDeleteHelper::is_mixed_tablets(info)) { - if (has_lob_tablets(arg, info)) { - need_modify = true; - tablet_ids_as_aux_tablets = true; - } - } - if (OB_SUCC(ret) && need_modify) { - ObTabletHandle handle; - if (OB_FAIL(helper.get_tablet(info.data_tablet_id_, handle))) { - if (OB_NO_NEED_UPDATE == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret)); - } - } else if (tablet_ids_as_aux_tablets) { - if (OB_FAIL(add_tablet_binding(arg, info, handle, info.tablet_ids_, empty_array, trans_flags))) { - LOG_WARN("failed to modify tablet binding", K(ret), K(info)); - } - } else { - if (OB_FAIL(add_tablet_binding(arg, info, handle, empty_array, info.tablet_ids_, trans_flags))) { - LOG_WARN("failed to modify tablet binding", K(ret), K(info)); - } - } - } - } - return ret; -} - -int ObTabletBindingHelper::add_tablet_binding( - const ObBatchCreateTabletArg &arg, - const ObCreateTabletInfo &tinfo, - ObTabletHandle &orig_tablet_handle, - const ObIArray &aux_tablet_ids, - const ObIArray &hidden_tablet_ids, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = arg.id_; - ObTablet *tablet = orig_tablet_handle.get_obj(); - const ObTabletID &orig_tablet_id = tablet->get_tablet_meta().tablet_id_; - bool is_locked = false; - if (OB_FAIL(check_is_locked(orig_tablet_handle, trans_flags.tx_id_, is_locked))) { - LOG_WARN("failed to check is locked", K(ret)); - } else if (is_locked) { - ObTabletBindingInfo info; - if (OB_FAIL(tablet->get_ddl_data(info))) { - LOG_WARN("failed to get ddl data", K(ret)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < aux_tablet_ids.count(); i++) { - const ObTabletID &tablet_id = aux_tablet_ids.at(i); - if (tablet_id != orig_tablet_id) { - if (arg.table_schemas_.at(tinfo.table_schema_index_.at(i)).is_aux_lob_meta_table()) { - info.lob_meta_tablet_id_ = tablet_id; - } else if (arg.table_schemas_.at(tinfo.table_schema_index_.at(i)).is_aux_lob_piece_table()) { - info.lob_piece_tablet_id_ = tablet_id; - } else { - // do not maintain index tablet ids - } - } - } - for (int64_t i = 0; OB_SUCC(ret) && i < hidden_tablet_ids.count(); i++) { - const ObTabletID &tablet_id = hidden_tablet_ids.at(i); - if (tablet_id != orig_tablet_id && !is_contain(info.hidden_tablet_ids_, tablet_id) - && OB_FAIL(info.hidden_tablet_ids_.push_back(tablet_id))) { - LOG_WARN("failed to push back tablet id", K(ret)); - } - } - - if (OB_SUCC(ret)) { - if (OB_FAIL(tablet->set_multi_data_for_commit(info, trans_flags.scn_, trans_flags.for_replay_, MemtableRefOp::NONE))) { - LOG_WARN("failed to save multi source data", K(ret)); - } - } - } - return ret; -} - -int ObTabletBindingHelper::lock_tablet_binding_for_unbind(const ObBatchUnbindTabletArg &batch_arg, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - if (OB_FAIL(get_ls(batch_arg.ls_id_, ls_handle))) { - LOG_WARN("failed to get ls", K(ret)); - } else { - ObTabletBindingHelper helper(*ls_handle.get_ls(), trans_flags); - int64_t last_orig_idx = -1; - int64_t last_hidden_idx = -1; - for (int64_t i = 0; OB_SUCC(ret) && i < batch_arg.orig_tablet_ids_.count(); i++) { - last_orig_idx = i; - if (OB_FAIL(helper.lock_tablet_binding(batch_arg.orig_tablet_ids_[i]))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } - } - if (batch_arg.is_redefined()) { - for (int64_t i = 0; OB_SUCC(ret) && i < batch_arg.hidden_tablet_ids_.count(); i++) { - last_hidden_idx = i; - if (OB_FAIL(helper.lock_tablet_binding(batch_arg.hidden_tablet_ids_[i]))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } - } - } - - if (OB_FAIL(ret) && !trans_flags.for_replay_) { - int tmp_ret = OB_SUCCESS; - ObMulSourceDataNotifyArg rollback_trans_flags = trans_flags; - rollback_trans_flags.notify_type_ = NotifyType::ON_ABORT; - ObTabletBindingHelper rollback_helper(*ls_handle.get_ls(), rollback_trans_flags); - for (int64_t i = 0; i <= last_orig_idx; i++) { - if (OB_TMP_FAIL(rollback_helper.unlock_tablet_binding(batch_arg.orig_tablet_ids_[i]))) { - LOG_ERROR("failed to unlock tablet binding", K(tmp_ret)); - } - } - for (int64_t i = 0; i <= last_hidden_idx; i++) { - if (OB_TMP_FAIL(rollback_helper.unlock_tablet_binding(batch_arg.hidden_tablet_ids_[i]))) { - LOG_ERROR("failed to unlock tablet binding", K(tmp_ret)); - } - } - } - } - return ret; -} - -int ObTabletBindingHelper::set_scn_for_unbind(const ObBatchUnbindTabletArg &batch_arg, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - if (OB_FAIL(get_ls(batch_arg.ls_id_, ls_handle))) { - LOG_WARN("failed to get ls", K(ret)); - } else { - ObTabletBindingHelper helper(*ls_handle.get_ls(), trans_flags); - if (OB_FAIL(helper.set_scn(batch_arg.orig_tablet_ids_))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } else if (batch_arg.is_redefined()) { - if (OB_FAIL(helper.set_scn(batch_arg.hidden_tablet_ids_))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } - } - } - return ret; -} - -int ObTabletBindingHelper::prepare_data_for_tablet(const ObTabletID &tablet_id, const ObLS &ls, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - bool skip = false; - if (trans_flags.for_replay_ - && OB_FAIL(check_skip_tx_end(tablet_id, ls, trans_flags, skip))) { - LOG_WARN("fail to check_skip_tx_end", K(ret), K(tablet_id), K(trans_flags)); - } else if (skip) { - LOG_INFO("skip tx_end_unbind for replay", K(tablet_id), K(trans_flags)); - } - // prepare tablet status_info of orig_tablet - else if (OB_FAIL(ObTabletCreateDeleteHelper::prepare_data_for_tablet_status(tablet_id, ls, trans_flags))) { - LOG_WARN("failed to prepare_data_for_tablet_status", KR(ret), K(tablet_id), K(ls)); - } - // prepare tablet binding_info of orig_tablet - else if (OB_FAIL(ObTabletCreateDeleteHelper::prepare_data_for_binding_info(tablet_id, ls, trans_flags))) { - LOG_WARN("failed to prepare_data_for_binding_info", KR(ret), K(tablet_id), K(ls)); - } - - return ret; -} - -int ObTabletBindingHelper::check_skip_tx_end(const ObTabletID &tablet_id, const ObLS &ls, const ObMulSourceDataNotifyArg &trans_flags, bool &skip) -{ - int ret = OB_SUCCESS; - skip = false; - ObTabletHandle tablet_handle; - ObTablet *tablet = nullptr; - ObTabletTxMultiSourceDataUnit tx_data; - ObTabletBindingHelper helper(ls, trans_flags); - - if (!trans_flags.scn_.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tablet_id), K(trans_flags)); - } else if (OB_FAIL(helper.get_tablet(tablet_id, tablet_handle))) { - if (OB_NO_NEED_UPDATE == ret) { - skip = true; - ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, tenant_id_, ls_id_, schema_version_, orig_tablet_ids_, hidden_tablet_ids_); + if (OB_SUCC(ret)) { + if (pos == data_len) { + is_old_mds_ = true; } else { - LOG_WARN("failed to get tablet", K(ret)); + LST_DO_CODE(OB_UNIS_DECODE, is_old_mds_); } - } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_FAIL(tablet->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", KR(ret)); - } else if (tx_data.tx_scn_ >= trans_flags.scn_) { - skip = true; - } - return ret; -} - -int ObTabletBindingHelper::on_tx_end_for_modify_tablet_binding(const ObBatchUnbindTabletArg &batch_arg, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - - ObLSHandle ls_handle; - if (OB_FAIL(get_ls(batch_arg.ls_id_, ls_handle))) { - LOG_WARN("failed to get ls", K(ret)); - } else { - ObLS &ls = *ls_handle.get_ls(); - for (int64_t i = 0; OB_SUCC(ret) && i < batch_arg.orig_tablet_ids_.count(); i++) { - const ObTabletID &tablet_id = batch_arg.orig_tablet_ids_.at(i); - if (OB_FAIL(prepare_data_for_tablet(tablet_id, ls, trans_flags))) { - LOG_WARN("failed to prepare_data_for_tablet", K(tablet_id), K(ret), K(batch_arg)); - } - } - - if (batch_arg.is_redefined()) { - for (int64_t i = 0; OB_SUCC(ret) && i < batch_arg.hidden_tablet_ids_.count(); i++) { - const ObTabletID &tablet_id = batch_arg.hidden_tablet_ids_.at(i); - if (OB_FAIL(prepare_data_for_tablet(tablet_id, ls, trans_flags))) { - LOG_WARN("failed to prepare_data_for_tablet", K(tablet_id), K(ret), K(batch_arg)); - } - } - } - } - - return ret; -} - -int ObTabletBindingHelper::unlock_tablet_binding_for_unbind(const ObBatchUnbindTabletArg &batch_arg, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - if (OB_FAIL(get_ls(batch_arg.ls_id_, ls_handle))) { - LOG_WARN("failed to get ls", K(ret)); - } else { - ObTabletBindingHelper helper(*ls_handle.get_ls(), trans_flags); - if (OB_FAIL(helper.unlock_tablet_binding(batch_arg.orig_tablet_ids_))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } else if (batch_arg.is_redefined()) { - if (OB_FAIL(helper.unlock_tablet_binding(batch_arg.hidden_tablet_ids_))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } - } - } - return ret; -} - -int ObTabletBindingHelper::fix_unsynced_cnt_for_binding_info(const ObTabletID &tablet_id) -{ - int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObTablet *tablet = nullptr; - ObTabletBindingInfo binding_info; - const SCN scn = SCN::max_scn(); - - if (OB_FAIL(get_tablet(tablet_id, tablet_handle))) { - if (OB_NO_NEED_UPDATE == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); - } - } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_FAIL(tablet->get_ddl_data(binding_info))) { - LOG_WARN("failed to get ddl data", KR(ret)); - } else if (OB_FAIL(tablet->clear_unsynced_cnt_for_tx_end_if_need(binding_info, scn, trans_flags_.for_replay_))) { - LOG_WARN("failed to prepare binding info", KR(ret), K(binding_info)); - } - - return ret; -} - -int ObTabletBindingHelper::fix_binding_info_for_create_tablets(const ObBatchCreateTabletArg &arg, const ObLS &ls, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - // fix data_tablet binding_info for pure_aux_table - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); i++) { - const ObCreateTabletInfo &info = arg.tablets_[i]; - bool need_modify = false; - if (ObTabletCreateDeleteHelper::is_pure_hidden_tablets(info)) { - need_modify = true; - } else if (ObTabletCreateDeleteHelper::is_pure_aux_tablets(info) || ObTabletCreateDeleteHelper::is_mixed_tablets(info)) { - if (has_lob_tablets(arg, info)) { - need_modify = true; - } - } - if (OB_SUCC(ret) && need_modify) { - ObTabletBindingHelper helper(ls, trans_flags); - if (OB_FAIL(helper.fix_unsynced_cnt_for_binding_info(info.data_tablet_id_))) { - LOG_WARN("failed to fix_unsynced_cnt_for_binding_info", K(ret)); - } - } - } - return ret; -} - -int ObTabletBindingHelper::fix_binding_info_for_modify_tablet_binding( - const ObBatchUnbindTabletArg &batch_arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - if (OB_FAIL(get_ls(batch_arg.ls_id_, ls_handle))) { - LOG_WARN("failed to get ls", K(ret)); - } else { - ObTabletBindingHelper helper(*ls_handle.get_ls(), trans_flags); - for (int64_t i = 0; OB_SUCC(ret) && i < batch_arg.orig_tablet_ids_.count(); i++) { - const ObTabletID &tablet_id = batch_arg.orig_tablet_ids_.at(i); - if (OB_FAIL(helper.fix_unsynced_cnt_for_binding_info(tablet_id))) { - LOG_WARN("failed to fix_unsynced_cnt_for_binding_info", K(tablet_id), K(ret), K(batch_arg)); - } - } - - if (batch_arg.is_redefined()) { - for (int64_t i = 0; OB_SUCC(ret) && i < batch_arg.hidden_tablet_ids_.count(); i++) { - const ObTabletID &tablet_id = batch_arg.hidden_tablet_ids_.at(i); - if (OB_FAIL(helper.fix_unsynced_cnt_for_binding_info(tablet_id))) { - LOG_WARN("failed to fix_unsynced_cnt_for_binding_info", K(tablet_id), K(ret), K(batch_arg)); - } - } - } - } - return ret; -} - -int ObTabletBindingHelper::modify_tablet_binding_for_unbind( - const ObBatchUnbindTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObLSHandle ls_handle; - const ObTransID &tx_id = trans_flags.tx_id_; - const SCN scn = trans_flags.scn_; - const bool for_replay = trans_flags.for_replay_; - const SCN commit_version = trans_flags.trans_version_; - if (OB_FAIL(get_ls(arg.ls_id_, ls_handle))) { - LOG_WARN("failed to get ls", K(ret)); - } else { - ObTabletBindingHelper helper(*ls_handle.get_ls(), trans_flags); - ObTabletHandle tablet_handle; - ObTablet *tablet = nullptr; - bool is_locked = false; - ObTabletBindingInfo info; - for (int64_t i = 0; OB_SUCC(ret) && i < arg.orig_tablet_ids_.count(); i++) { - if (OB_FAIL(helper.get_tablet(arg.orig_tablet_ids_.at(i), tablet_handle))) { - if (OB_NO_NEED_UPDATE == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret)); - } - } else if (OB_FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_FAIL(check_is_locked(tablet_handle, tx_id, is_locked))) { - LOG_WARN("failed to check is locked", K(ret)); - } else if (!is_locked) { - LOG_WARN("already commit", K(ret), K(tx_id)); - } else if (OB_FAIL(tablet->get_ddl_data(info))) { - LOG_WARN("failed to get ddl data", K(ret)); - } else { - info.hidden_tablet_ids_.reset(); - if (arg.is_redefined()) { - info.redefined_ = true; - info.snapshot_version_ = commit_version.get_val_for_tx(); - } - 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)); - } - } - } - if (OB_SUCC(ret) && arg.is_redefined()) { - for (int64_t i = 0; OB_SUCC(ret) && i < arg.hidden_tablet_ids_.count(); i++) { - const ObTabletID &tablet_id = arg.hidden_tablet_ids_.at(i); - ObTabletBindingInfo info; - if (OB_FAIL(helper.get_tablet(tablet_id, tablet_handle))) { - if (OB_NO_NEED_UPDATE == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret)); - } - } else if (OB_FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_FAIL(check_is_locked(tablet_handle, tx_id, is_locked))) { - LOG_WARN("failed to check is locked", K(ret)); - } else if (!is_locked) { - LOG_WARN("already commit", K(ret), K(tx_id)); - } else if (OB_FAIL(tablet->get_ddl_data(info))) { - LOG_WARN("failed to get ddl data", K(ret)); - } else { - info.redefined_ = false; - info.snapshot_version_ = commit_version.get_val_for_tx(); - 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)); - } - } - } - } - } - return ret; -} - -int ObTabletBindingHelper::check_schema_version(ObIArray &handles, const int64_t schema_version) -{ - int ret = OB_SUCCESS; - for (int64_t i = 0; OB_SUCC(ret) && i < handles.count(); i++) { - if (OB_FAIL(check_schema_version(handles.at(i), schema_version))) { - LOG_WARN("failed to check schema version", K(ret)); - } - } - return ret; -} - -int ObTabletBindingHelper::check_schema_version(ObTabletHandle &handle, const int64_t schema_version) -{ - int ret = OB_SUCCESS; - ObTablet *tablet = handle.get_obj(); - 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 < redefined_schema_version)) { - ret = OB_SCHEMA_EAGAIN; - 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; -} - -int ObTabletBindingHelper::check_snapshot_readable(ObTabletHandle &handle, const int64_t snapshot_version) -{ - 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))) { - LOG_WARN("failed to get tablet binding info", K(ret)); - } else if (OB_UNLIKELY(info.redefined_ && snapshot_version >= info.snapshot_version_)) { - ret = OB_SCHEMA_EAGAIN; - LOG_WARN("read data after ddl, need to retry on new tablet", K(ret), K(tablet->get_tablet_meta().tablet_id_), K(snapshot_version), K(info)); - } else if (OB_UNLIKELY(!info.redefined_ && snapshot_version < info.snapshot_version_)) { - ret = OB_SNAPSHOT_DISCARDED; - LOG_WARN("read data before ddl", K(ret), K(tablet->get_tablet_meta().tablet_id_), K(snapshot_version), K(info)); } return ret; } @@ -737,80 +111,24 @@ int ObTabletBindingHelper::get_ls(const ObLSID &ls_id, ObLSHandle &ls_handle) return ret; } -int ObTabletBindingHelper::get_tablet(const ObTabletID &tablet_id, ObTabletHandle &handle) const +int ObTabletBindingHelper::get_tablet_for_new_mds(const ObLS &ls, const ObTabletID &tablet_id, const share::SCN &replay_scn, ObTabletHandle &handle) { int ret = OB_SUCCESS; - const ObLSID &ls_id = ls_.get_ls_id(); - const ObTabletMapKey key(ls_id, tablet_id); - if (trans_flags_.for_replay_) { - ret = replay_get_tablet(key, handle); - } else { - ret = ObTabletCreateDeleteHelper::get_tablet(key, handle); - } - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_NO_NEED_UPDATE; - LOG_INFO("tablet removed", K(ret), K(key), K(trans_flags_)); - } else if (OB_EAGAIN == ret) { - // do nothing - } else if (OB_SUCCESS == ret) { - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(key)); - } else if (SCN::invalid_scn() != trans_flags_.scn_ && trans_flags_.scn_ <= tx_data.tx_scn_) { - ret = OB_NO_NEED_UPDATE; - LOG_INFO("tablet frozen", K(ret), K(key), K(trans_flags_), K(tx_data)); - } - } else { - LOG_WARN("failed to get tablet", K(ret), K(key), K(trans_flags_)); - } - return ret; -} - -int ObTabletBindingHelper::replay_get_tablet(const ObTabletMapKey &key, ObTabletHandle &handle) const -{ - // NOTICE: temporarily used, will be removed later! - int ret = OB_SUCCESS; - const SCN tablet_change_checkpoint_scn = ls_.get_tablet_change_checkpoint_scn(); - ObTabletHandle tablet_handle; - - if (OB_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST != ret) { - LOG_WARN("failed to get tablet", KR(ret), K(key)); - } else if (trans_flags_.scn_ <= tablet_change_checkpoint_scn) { - LOG_WARN("tablet already gc", KR(ret), K(key), K(trans_flags_), K(tablet_change_checkpoint_scn)); - } else { - LOG_INFO("tablet already gc, trans_flags_.scn_ is not less than tablet_change_checkpoint_scn", - KR(ret), K(key), K(trans_flags_), K(tablet_change_checkpoint_scn)); - } - } else { - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get tablet tx data", KR(ret), K(tablet_handle)); - } else if (ObTabletStatus::DELETED == tx_data.tablet_status_) { - ret = OB_TABLET_NOT_EXIST; - LOG_INFO("tablet is already deleted", KR(ret), K(key), K(tx_data)); + const ObTabletMapKey key(ls.get_ls_id(), tablet_id); + const bool for_replay = replay_scn.is_valid(); + if (for_replay) { + if (OB_FAIL(ls.replay_get_tablet(tablet_id, replay_scn, handle))) { + if (OB_OBSOLETE_CLOG_NEED_SKIP == ret) { + ret = OB_NO_NEED_UPDATE; + LOG_WARN("clog is obsolete, should skip replay", K(ret)); + } else { + LOG_WARN("failed to get tablet", K(ret)); + } } + } else if (OB_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, handle))) { + LOG_WARN("failed to get tablet", K(ret), K(key)); } - if (OB_SUCC(ret)) { - handle = tablet_handle; - } - - return ret; -} - -int ObTabletBindingHelper::check_is_locked(ObTabletHandle &handle, const ObTransID &tx_id, bool &is_locked) -{ - int ret = OB_SUCCESS; - ObTablet *tablet = handle.get_obj(); - TCRWLock &lock = tablet->get_rw_lock(); - TCRLockGuard guard(lock); - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(tablet->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret)); - } else { - is_locked = tx_id == tx_data.tx_id_; - } return ret; } @@ -826,261 +144,233 @@ bool ObTabletBindingHelper::has_lob_tablets(const obrpc::ObBatchCreateTabletArg return has_lob; } -// for prepare -int ObTabletBindingHelper::lock_and_set_tx_data(ObTabletHandle &handle, ObTabletTxMultiSourceDataUnit &tx_data, const bool for_replay) +int ObTabletBindingHelper::modify_tablet_binding_for_new_mds_create(const ObBatchCreateTabletArg &arg, const share::SCN &replay_scn, mds::BufferCtx &ctx) { + MDS_TG(100_ms); int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - ObTablet *tablet = handle.get_obj(); - const ObLSID &ls_id = tablet->get_tablet_meta().ls_id_; - const ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; - const ObTabletMapKey key(ls_id, tablet_id); - - const SCN scn = for_replay ? tx_data.tx_scn_ : SCN::max_scn(); - const MemtableRefOp ref_op = for_replay ? MemtableRefOp::NONE : MemtableRefOp::INC_REF; - ObTabletTxMultiSourceDataUnit old_tx_data; - if (OB_FAIL(tablet->get_tx_data(old_tx_data))) { - LOG_WARN("failed to get tx data", K(ret)); + ObLSHandle ls_handle; + if (OB_FAIL(ObTabletBindingHelper::get_ls(arg.id_, ls_handle))) { + LOG_WARN("failed to get ls", K(ret)); } else { - const ObTransID &old_tx_id = old_tx_data.tx_id_; - bool need_update = true; - if (!old_tx_id.is_valid()) { - // do nothing - } else if (old_tx_id == tx_data.tx_id_) { - need_update = false; - } else { - ret = OB_EAGAIN; - LOG_WARN("tablet binding locked by others", K(ret), K(tablet_id), K(tx_data), K(old_tx_data)); - } - if (OB_FAIL(ret)) { - } else if (need_update && OB_FAIL(tablet->set_tx_data(tx_data, scn, for_replay, - ref_op, false/*is_callback*/))) { - LOG_WARN("failed to save msd", K(ret), K(tx_data), K(scn), K(for_replay), K(ref_op)); - } else if (OB_FAIL(t3m->insert_pinned_tablet(key))) { - LOG_WARN("failed to insert in tx tablet", K(ret), K(key)); - } - } - return ret; -} - -// for prepare, reentrant -int ObTabletBindingHelper::lock_tablet_binding(ObTabletHandle &handle, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - const ObTransID &tx_id = trans_flags.tx_id_; - const SCN scn = trans_flags.scn_; - const bool for_replay = trans_flags.for_replay_; - ObTablet *tablet = handle.get_obj(); - const ObTabletMapKey key(tablet->tablet_meta_.ls_id_, tablet->tablet_meta_.tablet_id_); - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(tablet->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret)); - } else { - const ObTransID old_tx_id = tx_data.tx_id_; - const SCN old_scn = tx_data.tx_scn_; - bool need_update = true; - const SCN memtable_scn = for_replay ? scn : SCN::max_scn();; - const MemtableRefOp ref_op = for_replay ? MemtableRefOp::NONE : MemtableRefOp::INC_REF; - if (!old_tx_id.is_valid()) { - tx_data.tx_id_ = tx_id; - tx_data.tx_scn_ = for_replay ? scn : old_scn; - } else if (old_tx_id == tx_id) { - need_update = false; // already same - } else { - ret = OB_EAGAIN; - handle.get_obj()->print_memtables_for_table(); - LOG_WARN("tablet binding locked by others", K(ret), K(tx_id), K(scn), K(tablet->get_tablet_meta()), K(tx_data)); - } - if (OB_FAIL(ret)) { - } else if (need_update && OB_FAIL(tablet->set_tx_data(tx_data, memtable_scn, for_replay, - ref_op, false/*is_callback*/))) { - LOG_WARN("failed to save tx data", K(ret), K(tx_data), K(scn), K(for_replay), K(ref_op)); - if (!for_replay && OB_BLOCK_FROZEN == ret) { - ret = OB_EAGAIN; + const ObArray empty_array; + ObLS &ls = *ls_handle.get_ls(); + for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); i++) { + const ObCreateTabletInfo &info = arg.tablets_[i]; + if (ObTabletCreateDeleteHelper::is_pure_hidden_tablets(info)) { + if (CLICK_FAIL(bind_hidden_tablet_to_orig_tablet(ls, info, replay_scn, ctx))) { + LOG_WARN("failed to add hidden tablet", K(ret)); + } + } else if (ObTabletBindingHelper::has_lob_tablets(arg, info)) { + if (CLICK_FAIL(bind_lob_tablet_to_data_tablet(ls, arg, info, replay_scn, ctx))) { + LOG_WARN("failed to add lob tablet", K(ret)); + } } - } else if (OB_FAIL(t3m->insert_pinned_tablet(key))) { - LOG_WARN("failed to insert in tx tablet", K(ret), K(key)); } } return ret; } -/// reentrant, lock by tx_id_ -int ObTabletBindingHelper::lock_tablet_binding(const ObTabletID &tablet_id) const +int ObTabletBindingHelper::bind_hidden_tablet_to_orig_tablet( + ObLS &ls, + const ObCreateTabletInfo &info, + const share::SCN &replay_scn, + mds::BufferCtx &ctx) { + return modify_tablet_binding_new_mds(ls, info.data_tablet_id_, replay_scn, ctx, [&info](ObTabletBindingMdsUserData &data) -> int { + int ret = OB_SUCCESS; + const ObTabletID &orig_tablet_id = info.data_tablet_id_; + for (int64_t i = 0; OB_SUCC(ret) && i < info.tablet_ids_.count(); i++) { + const ObTabletID &tablet_id = info.tablet_ids_.at(i); + if (tablet_id != orig_tablet_id && tablet_id != data.hidden_tablet_id_) { + data.hidden_tablet_id_ = tablet_id; + } + } + return ret; + }); +} + +int ObTabletBindingHelper::bind_lob_tablet_to_data_tablet( + ObLS &ls, + const ObBatchCreateTabletArg &arg, + const ObCreateTabletInfo &info, + const share::SCN &replay_scn, + mds::BufferCtx &ctx) +{ + return modify_tablet_binding_new_mds(ls, info.data_tablet_id_, replay_scn, ctx, [&arg, &info](ObTabletBindingMdsUserData &data) -> int { + int ret = OB_SUCCESS; + const ObTabletID &data_tablet_id = info.data_tablet_id_; + for (int64_t i = 0; OB_SUCC(ret) && i < info.tablet_ids_.count(); i++) { + const ObTabletID &tablet_id = info.tablet_ids_.at(i); + if (tablet_id != data_tablet_id) { + if (arg.table_schemas_.at(info.table_schema_index_.at(i)).is_aux_lob_meta_table()) { + data.lob_meta_tablet_id_ = tablet_id; + } else if (arg.table_schemas_.at(info.table_schema_index_.at(i)).is_aux_lob_piece_table()) { + data.lob_piece_tablet_id_ = tablet_id; + } else { + // do not maintain index tablet ids + } + } + } + return ret; + }); +} + +// TODO (lihongqin.lhq) Separate the code of replay +template +int ObTabletBindingHelper::modify_tablet_binding_new_mds( + ObLS &ls, + const ObTabletID &tablet_id, + const share::SCN &replay_scn, + mds::BufferCtx &ctx, + F op) +{ + MDS_TG(100_ms); int ret = OB_SUCCESS; - ObTabletHandle handle; - if (OB_FAIL(get_tablet(tablet_id, handle))) { + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletBindingMdsUserData data; + mds::MdsCtx &user_ctx = static_cast(ctx); + if (CLICK_FAIL(get_tablet_for_new_mds(ls, tablet_id, replay_scn, tablet_handle))) { if (OB_NO_NEED_UPDATE == ret) { ret = OB_SUCCESS; } else { LOG_WARN("failed to get tablet", K(ret)); } - } else if (OB_FAIL(lock_tablet_binding(handle, trans_flags_))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } - return ret; -} - -/// reentrant, lock by tx_id_ -int ObTabletBindingHelper::lock_tablet_binding(const ObIArray &tablet_ids) const -{ - int ret = OB_SUCCESS; - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); i++) { - if (OB_FAIL(lock_tablet_binding(tablet_ids.at(i)))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } - } - return ret; -} - -// for redo and not replay, fill log ts, not reentrant -int ObTabletBindingHelper::set_scn(ObTabletHandle &handle, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObTransID &tx_id = trans_flags.tx_id_; - const SCN scn = trans_flags.scn_; - const bool for_replay = trans_flags.for_replay_; - ObTablet *tablet = handle.get_obj(); - ObTabletTxMultiSourceDataUnit data; - if (OB_FAIL(tablet->get_tx_data(data))) { - LOG_WARN("failed to get data", K(ret)); - } else if (OB_UNLIKELY(data.tx_id_ != tx_id)) { - ret = OB_ERR_UNEXPECTED; - tablet->print_memtables_for_table(); - LOG_WARN("cannot set log ts for unlocked tablet", K(ret), K(tx_id), K(data), "tablet_id", tablet->get_tablet_meta()); - } else if (OB_UNLIKELY(!data.tx_scn_.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid log scn", K(ret), K(tx_id), K(scn), K(data)); - } else if (data.tx_scn_ == scn) { - LOG_WARN("log ts already set, may be bug or retry", K(ret), K(tx_id), K(scn), K(data)); + } else if (OB_FALSE_IT(tablet = tablet_handle.get_obj())) { + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::get_ddl_data(share::SCN::max_scn(), data))) { + LOG_WARN("failed to get ddl data", K(ret)); + } else if (CLICK_FAIL(op(data))) { + LOG_WARN("failed to operate on mds", K(ret)); } else { - data.tx_scn_ = scn; - if (OB_FAIL(tablet->set_tx_data(data, scn, for_replay, memtable::MemtableRefOp::DEC_REF, true/*is_callback*/))) { - LOG_WARN("failed to save msd", K(ret), K(data), K(scn), K(for_replay)); - } - } - return ret; -} - -int ObTabletBindingHelper::set_scn(const ObTabletID &tablet_id) const -{ - int ret = OB_SUCCESS; - ObTabletHandle handle; - if (OB_FAIL(get_tablet(tablet_id, handle))) { - if (OB_NO_NEED_UPDATE == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret)); - } - } else if (OB_FAIL(set_scn(handle, trans_flags_))) { - LOG_WARN("failed to set log ts", K(ret)); - } - return ret; -} - -int ObTabletBindingHelper::set_scn(const ObIArray &tablet_ids) const -{ - int ret = OB_SUCCESS; - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); i++) { - if (OB_FAIL(set_scn(tablet_ids.at(i)))) { - LOG_WARN("failed to set log ts", K(ret)); - } - } - return ret; -} - -int ObTabletBindingHelper::check_need_dec_cnt_for_abort(const ObTabletTxMultiSourceDataUnit &tx_data, bool &need_dec) -{ - int ret = OB_SUCCESS; - const int cnt = tx_data.get_unsync_cnt_for_multi_data(); - need_dec = false; - if ((tx_data.is_tx_end() && cnt == 2) || (!tx_data.is_tx_end() && cnt == 1)) { - need_dec = true; - } else if ((tx_data.is_tx_end() && cnt == 1) || (!tx_data.is_tx_end() && cnt == 0)) { - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid cnt", K(ret), K(tx_data)); - } - return ret; -} - -/// for commit or abort, reentrant for replay -int ObTabletBindingHelper::unlock_tablet_binding(ObTabletHandle &handle, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - const ObTransID &tx_id = trans_flags.tx_id_; - const SCN scn = trans_flags.scn_; - const bool for_replay = trans_flags.for_replay_; - const bool for_commit = trans_flags.notify_type_ == NotifyType::ON_COMMIT; - ObTablet *tablet = handle.get_obj(); - const ObTabletMapKey key(tablet->tablet_meta_.ls_id_, tablet->tablet_meta_.tablet_id_); - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(tablet->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret)); - } else { - const SCN old_scn = tx_data.tx_scn_; - if (tx_data.tx_id_ == tx_id) { - if (for_replay && scn <= old_scn) { - // replaying procedure, clog ts is smaller than tx log ts, just skip - LOG_INFO("skip abort create tablet", K(ret), K(trans_flags), K(tx_data)); - } else if (for_commit && OB_UNLIKELY(!scn.is_valid() || !old_scn.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid log scn", K(ret), K(tx_id), K(scn), K(old_scn), K(tx_data)); - } else { - const bool abort_without_redo = !for_commit && !for_replay && !trans_flags.is_redo_synced(); - tx_data.tx_id_ = ObTabletCommon::FINAL_TX_ID; - tx_data.tx_scn_ = abort_without_redo ? old_scn : scn; - const SCN memtable_scn = (!scn.is_valid()) ? SCN::max_scn(): scn; - bool need_dec = false; - MemtableRefOp ref_op = MemtableRefOp::NONE; - if (OB_FAIL(check_need_dec_cnt_for_abort(tx_data, need_dec))) { - LOG_WARN("failed to save tx data", K(ret), K(tx_data), K(scn), K(for_replay)); - } else if (FALSE_IT(ref_op = (need_dec ? MemtableRefOp::DEC_REF : MemtableRefOp::NONE))) { - } else if (OB_FAIL(tablet->set_tablet_final_status(tx_data, memtable_scn, for_replay, ref_op))) { - LOG_WARN("failed to save tx data", K(ret), K(tx_data), K(scn), K(for_replay), K(ref_op)); - } else if (OB_FAIL(t3m->erase_pinned_tablet(key))) { - LOG_WARN("failed to erase in tx tablet", K(ret), K(key)); + if (replay_scn.is_valid()) { + ObTabletBindingReplayExecutor replay_executor; + if (CLICK_FAIL(replay_executor.init(ctx, data, replay_scn))) { + LOG_WARN("failed to init replay executor", K(ret)); + } else if (CLICK_FAIL(replay_executor.execute(replay_scn, ls.get_ls_id(), tablet_id))) { + if (OB_EAGAIN != ret) { + LOG_WARN("failed to replay tablet binding log", K(ret)); } } } else { - const ObTabletMeta &tablet_meta = tablet->get_tablet_meta(); - LOG_WARN("already unlocked or bug", K(ret), K(tablet_meta), K(scn), K(trans_flags), K(tx_data)); - handle.get_obj()->print_memtables_for_table(); + if (CLICK_FAIL(ls.get_tablet_svr()->set_ddl_info(tablet_id, std::move(data), user_ctx, 0/*lock_timeout_us*/))) { + LOG_WARN("failed to save tablet binding info", K(ret)); + } } } return ret; } -/// reentrant, unlock by tx_id_ -int ObTabletBindingHelper::unlock_tablet_binding(const ObTabletID &tablet_id) const +int ObTabletUnbindMdsHelper::register_process( + ObBatchUnbindTabletArg &arg, + mds::BufferCtx &ctx) { int ret = OB_SUCCESS; - ObTabletHandle handle; - if (OB_FAIL(get_tablet(tablet_id, handle))) { - if (OB_NO_NEED_UPDATE == ret) { - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret)); - } - } else if (OB_FAIL(unlock_tablet_binding(handle, trans_flags_))) { - LOG_ERROR("failed to unlock tablet binding", K(ret)); + + if (OB_FAIL(modify_tablet_binding_for_unbind(arg, SCN::invalid_scn(), ctx))) { + LOG_WARN("failed to modify tablet binding", K(ret)); + } else { + LOG_INFO("modify_tablet_binding_for_unbind register", KR(ret), K(arg)); + } + + return ret; +} + +int ObTabletUnbindMdsHelper::on_commit_for_old_mds( + const char* buf, + const int64_t len, + const transaction::ObMulSourceDataNotifyArg ¬ify_arg) +{ + return ObTabletCreateDeleteHelper::process_for_old_mds(buf, len, notify_arg); +} + +int ObTabletUnbindMdsHelper::on_register(const char* buf, const int64_t len, mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + ObBatchUnbindTabletArg arg; + if (OB_FAIL(arg.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize arg", K(ret)); + } else if (arg.is_old_mds_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, arg is old mds", K(ret), K(arg)); + } else if (OB_FAIL(register_process(arg, ctx))) { + LOG_WARN("failed to register_process", K(ret)); } return ret; } -/// reentrant, unlock by tx_id_ -int ObTabletBindingHelper::unlock_tablet_binding(const ObIArray &tablet_ids) const +int ObTabletUnbindMdsHelper::on_replay(const char* buf, const int64_t len, const share::SCN &scn, mds::BufferCtx &ctx) { int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - for (int64_t i = 0; i < tablet_ids.count(); i++) { - if (OB_TMP_FAIL(unlock_tablet_binding(tablet_ids.at(i)))) { - LOG_WARN("failed to unlock tablet binding", K(ret), K(tmp_ret)); - if (OB_SUCC(ret)) { - ret = tmp_ret; + int64_t pos = 0; + ObBatchUnbindTabletArg arg; + if (OB_FAIL(arg.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize arg", K(ret)); + } else if (arg.is_old_mds_) { + LOG_INFO("skip unbind mds tablet for old mds", K(arg), K(scn)); + } else if (OB_FAIL(modify_tablet_binding_for_unbind(arg, scn, ctx))) { + LOG_WARN("failed to modify tablet binding", K(ret)); + } + return ret; +} + +int ObTabletUnbindMdsHelper::unbind_hidden_tablets_from_orig_tablets( + ObLS &ls, + const ObBatchUnbindTabletArg &arg, + const share::SCN &replay_scn, + mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < arg.orig_tablet_ids_.count(); i++) { + const ObTabletID &orig_tablet = arg.orig_tablet_ids_.at(i); + if (OB_FAIL(ObTabletBindingHelper::modify_tablet_binding_new_mds(ls, orig_tablet, replay_scn, ctx, [&arg](ObTabletBindingMdsUserData &data) -> int { + data.hidden_tablet_id_.reset(); + if (arg.is_redefined()) { + data.redefined_ = true; + data.snapshot_version_ = OB_INVALID_VERSION; // will be fill back on commit + } + return OB_SUCCESS; + }))) { + LOG_WARN("failed to modify tablet binding", K(ret)); + } + } + return ret; +} + +int ObTabletUnbindMdsHelper::set_redefined_versions_for_hidden_tablets( + ObLS &ls, + const ObBatchUnbindTabletArg &arg, + const share::SCN &replay_scn, + mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < arg.hidden_tablet_ids_.count(); i++) { + const ObTabletID &hidden_tablet = arg.hidden_tablet_ids_.at(i); + if (OB_FAIL(ObTabletBindingHelper::modify_tablet_binding_new_mds(ls, hidden_tablet, replay_scn, ctx, [&arg](ObTabletBindingMdsUserData &data) -> int { + data.redefined_ = false; + data.snapshot_version_ = OB_INVALID_VERSION; // will be fill back on commit + data.schema_version_ = arg.schema_version_; + return OB_SUCCESS; + }))) { + LOG_WARN("failed to modify tablet binding", K(ret)); + } + } + return ret; +} + +int ObTabletUnbindMdsHelper::modify_tablet_binding_for_unbind(const ObBatchUnbindTabletArg &arg, const share::SCN &replay_scn, mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + if (OB_FAIL(ObTabletBindingHelper::get_ls(arg.ls_id_, ls_handle))) { + LOG_WARN("failed to get ls", K(ret)); + } else { + ObLS &ls = *ls_handle.get_ls(); + if (OB_FAIL(unbind_hidden_tablets_from_orig_tablets(ls, arg, replay_scn, ctx))) { + LOG_WARN("failed to unbind", K(ret)); + } else if (arg.is_redefined()) { + if (OB_FAIL(set_redefined_versions_for_hidden_tablets(ls, arg, replay_scn, ctx))) { + LOG_WARN("failed to set redefined versions", K(ret)); } } } diff --git a/src/storage/tablet/ob_tablet_binding_helper.h b/src/storage/tablet/ob_tablet_binding_helper.h index 41ea62c21..d1b972779 100644 --- a/src/storage/tablet/ob_tablet_binding_helper.h +++ b/src/storage/tablet/ob_tablet_binding_helper.h @@ -15,10 +15,9 @@ #include "common/ob_tablet_id.h" #include "lib/container/ob_array.h" +#include "lib/container/ob_array_serialization.h" #include "lib/ob_define.h" -#include "storage/memtable/ob_multi_source_data.h" -#include "storage/tx/ob_trans_define.h" -#include "share/scn.h" +#include "share/ob_ls_id.h" namespace oceanbase { @@ -31,7 +30,7 @@ struct ObCreateTabletInfo; namespace share { -class ObLSID; +class SCN; } namespace transaction @@ -42,42 +41,18 @@ class ObTransID; namespace storage { +namespace mds +{ +struct BufferCtx; +class MdsCtx; +} + class ObLS; class ObLSHandle; class ObTabletHandle; class ObTabletTxMultiSourceDataUnit; class ObTabletMapKey; -class ObTabletBindingInfo : public memtable::ObIMultiSourceDataUnit -{ -public: - OB_UNIS_VERSION_V(1); -public: - typedef common::ObSArray TabletArray; - - ObTabletBindingInfo(); - virtual ~ObTabletBindingInfo() {} - int assign(const ObTabletBindingInfo &arg); - - virtual int deep_copy(const memtable::ObIMultiSourceDataUnit *src, ObIAllocator *allocator = nullptr) override; - virtual void reset() override; - virtual bool is_valid() const override; - virtual int64_t get_data_size() const override { return sizeof(ObTabletBindingInfo); } - virtual memtable::MultiSourceDataUnitType type() const override { return memtable::MultiSourceDataUnitType::TABLET_BINDING_INFO; } - - TO_STRING_KV(K_(redefined), K_(snapshot_version), K_(schema_version), K_(data_tablet_id), K_(hidden_tablet_ids), K_(lob_meta_tablet_id), K_(lob_piece_tablet_id), K_(is_tx_end), K_(unsynced_cnt_for_multi_data)); -public: - bool redefined_; - int64_t snapshot_version_; // if redefined it is max readable snapshot, else it is min readable snapshot. - int64_t schema_version_; - common::ObTabletID data_tablet_id_; - common::ObSEArray hidden_tablet_ids_; - common::ObTabletID lob_meta_tablet_id_; - common::ObTabletID lob_piece_tablet_id_; -private: - DISALLOW_COPY_AND_ASSIGN(ObTabletBindingInfo); -}; - class ObBatchUnbindTabletArg final { public: @@ -86,6 +61,7 @@ public: int assign(const ObBatchUnbindTabletArg &other); inline bool is_redefined() const { return schema_version_ != OB_INVALID_VERSION; } TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(schema_version), K_(orig_tablet_ids), K_(hidden_tablet_ids)); + bool is_valid() { return true; } OB_UNIS_VERSION_V(1); public: @@ -94,21 +70,11 @@ public: int64_t schema_version_; ObSArray orig_tablet_ids_; ObSArray hidden_tablet_ids_; + bool is_old_mds_; private: DISALLOW_COPY_AND_ASSIGN(ObBatchUnbindTabletArg); }; -class ObTabletBindingPrepareCtx final -{ -public: - ObTabletBindingPrepareCtx() - : skip_idx_(), last_idx_(-1) {} - ~ObTabletBindingPrepareCtx() {} -public: - ObSArray skip_idx_; - int64_t last_idx_; -}; - class ObTabletBindingHelper final { public: @@ -116,65 +82,18 @@ public: : ls_(ls), trans_flags_(trans_flags) {} ~ObTabletBindingHelper() {} - // create tablet - static int lock_tablet_binding_for_create( - const obrpc::ObBatchCreateTabletArg &arg, - ObLS &ls, - const transaction::ObMulSourceDataNotifyArg &trans_flags, - ObTabletBindingPrepareCtx &ctx); - static void rollback_lock_tablet_binding_for_create( - const obrpc::ObBatchCreateTabletArg &arg, - ObLS &ls, - const transaction::ObMulSourceDataNotifyArg &prepare_trans_flags, - const ObTabletBindingPrepareCtx &ctx); - static int set_scn_for_create(const obrpc::ObBatchCreateTabletArg &arg, ObLS &ls, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int unlock_tablet_binding_for_create(const obrpc::ObBatchCreateTabletArg &arg, ObLS &ls, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int modify_tablet_binding_for_create(const obrpc::ObBatchCreateTabletArg &arg, ObLS &ls, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int add_tablet_binding( - const obrpc::ObBatchCreateTabletArg &arg, - const obrpc::ObCreateTabletInfo &tinfo, - ObTabletHandle &orig_tablet_handle, - const ObIArray &index_tablet_ids_to_add, - const ObIArray &hidden_tablet_ids_to_add, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - - // unbind tablet - static int lock_tablet_binding_for_unbind(const ObBatchUnbindTabletArg &arg, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int set_scn_for_unbind(const ObBatchUnbindTabletArg &arg, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int unlock_tablet_binding_for_unbind(const ObBatchUnbindTabletArg &arg, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int fix_binding_info_for_modify_tablet_binding(const ObBatchUnbindTabletArg &arg, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int modify_tablet_binding_for_unbind(const ObBatchUnbindTabletArg &arg, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int check_skip_tx_end(const ObTabletID &tablet_id, const ObLS &ls, const transaction::ObMulSourceDataNotifyArg &trans_flags, bool &skip); - static int on_tx_end_for_modify_tablet_binding(const ObBatchUnbindTabletArg &arg, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int fix_binding_info_for_create_tablets(const obrpc::ObBatchCreateTabletArg &arg, const ObLS &ls, const transaction::ObMulSourceDataNotifyArg &trans_flags); - - // dml snapshot/schema version guard - static int check_schema_version(common::ObIArray &handle, const int64_t schema_version); - static int check_schema_version(ObTabletHandle &handle, const int64_t schema_version); - static int check_snapshot_readable(ObTabletHandle &handle, const int64_t snapshot_version); + // create tablet by new mds + static int modify_tablet_binding_for_new_mds_create(const obrpc::ObBatchCreateTabletArg &arg, const share::SCN &replay_scn, mds::BufferCtx &ctx); + static int bind_hidden_tablet_to_orig_tablet(ObLS &ls, const obrpc::ObCreateTabletInfo &info, const share::SCN &replay_scn, mds::BufferCtx &ctx); + static int bind_lob_tablet_to_data_tablet(ObLS &ls, const obrpc::ObBatchCreateTabletArg &arg, const obrpc::ObCreateTabletInfo &info, const share::SCN &replay_scn, mds::BufferCtx &ctx); + // TODO (lihongqin.lhq) delete get_tablet_for_new_mds + static int get_tablet_for_new_mds(const ObLS &ls, const ObTabletID &tablet_id, const share::SCN &replay_scn, ObTabletHandle &handle); // common + template + static int modify_tablet_binding_new_mds(ObLS &ls, const ObTabletID &tablet_id, const share::SCN &replay_scn, mds::BufferCtx &ctx, F op); static bool has_lob_tablets(const obrpc::ObBatchCreateTabletArg &arg, const obrpc::ObCreateTabletInfo &info); - static int check_need_dec_cnt_for_abort(const ObTabletTxMultiSourceDataUnit &tx_data, bool &need_dec); - static int lock_and_set_tx_data(ObTabletHandle &handle, ObTabletTxMultiSourceDataUnit &tx_data, const bool for_replay); - static int lock_tablet_binding(ObTabletHandle &handle, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int set_scn(ObTabletHandle &handle, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int unlock_tablet_binding(ObTabletHandle &handle, const transaction::ObMulSourceDataNotifyArg &trans_flags); - static int check_is_locked(ObTabletHandle &handle, const transaction::ObTransID &tx_id, bool &is_locked); static int get_ls(const share::ObLSID &ls_id, ObLSHandle &ls_handle); - int get_tablet(const ObTabletID &tablet_id, ObTabletHandle &handle) const; - - // TODO(lihongqin.lhq): remove this interface later - int replay_get_tablet(const ObTabletMapKey &key, ObTabletHandle &handle) const; -private: - int lock_tablet_binding(const ObTabletID &tablet_id) const; - int lock_tablet_binding(const common::ObIArray &tablet_ids) const; - int set_scn(const ObTabletID &tablet_id) const; - int set_scn(const common::ObIArray &tablet_ids) const; - int unlock_tablet_binding(const ObTabletID &tablet_id) const; - int unlock_tablet_binding(const common::ObIArray &tablet_ids) const; - static int prepare_data_for_tablet(const ObTabletID &tablet_id, const ObLS &ls, const transaction::ObMulSourceDataNotifyArg &trans_flags); - int fix_unsynced_cnt_for_binding_info(const ObTabletID &tablet_id); private: const ObLS &ls_; const transaction::ObMulSourceDataNotifyArg &trans_flags_; @@ -182,6 +101,19 @@ private: DISALLOW_COPY_AND_ASSIGN(ObTabletBindingHelper); }; +class ObTabletUnbindMdsHelper +{ +public: + static int on_register(const char* buf, const int64_t len, mds::BufferCtx &ctx); + static int register_process(ObBatchUnbindTabletArg &arg, mds::BufferCtx &ctx); + static int on_commit_for_old_mds(const char* buf, const int64_t len, const transaction::ObMulSourceDataNotifyArg ¬ify_arg); + static int on_replay(const char* buf, const int64_t len, const share::SCN &scn, mds::BufferCtx &ctx); +private: + static int unbind_hidden_tablets_from_orig_tablets(ObLS &ls, const ObBatchUnbindTabletArg &arg, const share::SCN &replay_scn, mds::BufferCtx &ctx); + static int set_redefined_versions_for_hidden_tablets(ObLS &ls, const ObBatchUnbindTabletArg &arg, const share::SCN &replay_scn, mds::BufferCtx &ctx); + static int modify_tablet_binding_for_unbind(const ObBatchUnbindTabletArg &arg, const share::SCN &replay_scn, mds::BufferCtx &ctx); +}; + } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_binding_info.cpp b/src/storage/tablet/ob_tablet_binding_info.cpp new file mode 100644 index 000000000..202a9f696 --- /dev/null +++ b/src/storage/tablet/ob_tablet_binding_info.cpp @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_binding_info.h" + +#define USING_LOG_PREFIX STORAGE + +namespace oceanbase +{ +namespace storage +{ +ObTabletBindingInfo::ObTabletBindingInfo() + : redefined_(false), + snapshot_version_(INT64_MAX), + schema_version_(INT64_MAX), + data_tablet_id_(), + hidden_tablet_ids_(), + lob_meta_tablet_id_(), + lob_piece_tablet_id_() +{ +} + +void ObTabletBindingInfo::reset() +{ + redefined_ = false; + snapshot_version_ = INT64_MAX; + schema_version_ = INT64_MAX; + data_tablet_id_.reset(); + hidden_tablet_ids_.reset(); + lob_meta_tablet_id_.reset(); + lob_piece_tablet_id_.reset(); +} + +bool ObTabletBindingInfo::is_valid() const +{ + bool valid = true; + + if (INT64_MAX == snapshot_version_) { + valid = false; + } else if (INT64_MAX == schema_version_) { + valid = false; + } + + return valid; +} + +int ObTabletBindingInfo::assign(const ObTabletBindingInfo &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(hidden_tablet_ids_.assign(other.hidden_tablet_ids_))) { + LOG_WARN("failed to assign hidden tablet ids", K(ret)); + } else { + redefined_ = other.redefined_; + snapshot_version_ = other.snapshot_version_; + schema_version_ = other.schema_version_; + data_tablet_id_ = other.data_tablet_id_; + lob_meta_tablet_id_ = other.lob_meta_tablet_id_; + lob_piece_tablet_id_ = other.lob_piece_tablet_id_; + } + return ret; +} + +int ObTabletBindingInfo::deep_copy( + const memtable::ObIMultiSourceDataUnit *src, + ObIAllocator *allocator) +{ + UNUSED(allocator); + int ret = OB_SUCCESS; + if (OB_ISNULL(src)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid src info", K(ret)); + } else if (OB_UNLIKELY(src->type() != type())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid type", K(ret)); + } else if (OB_FAIL(assign(*static_cast(src)))) { + LOG_WARN("failed to copy tablet binding info", K(ret)); + } + return ret; +} + +OB_SERIALIZE_MEMBER( + ObTabletBindingInfo, + redefined_, + snapshot_version_, + schema_version_, + data_tablet_id_, + hidden_tablet_ids_, + lob_meta_tablet_id_, + lob_piece_tablet_id_); +} // namespace storage +} // namespace oceanbase \ No newline at end of file diff --git a/src/storage/tablet/ob_tablet_binding_info.h b/src/storage/tablet/ob_tablet_binding_info.h new file mode 100644 index 000000000..0637d071f --- /dev/null +++ b/src/storage/tablet/ob_tablet_binding_info.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_BINDING_INFO +#define OCEANBASE_STORAGE_OB_TABLET_BINDING_INFO + +#include +#include "lib/utility/ob_print_utils.h" +#include "lib/utility/ob_unify_serialize.h" +#include "lib/container/ob_se_array.h" +#include "common/ob_tablet_id.h" +#include "storage/memtable/ob_multi_source_data.h" + +namespace oceanbase +{ +namespace storage +{ +class ObTabletBindingInfo : public memtable::ObIMultiSourceDataUnit +{ +public: + OB_UNIS_VERSION_V(1); +public: + ObTabletBindingInfo(); + virtual ~ObTabletBindingInfo() = default; + int set_allocator(ObIAllocator &allocator); + int assign(const ObTabletBindingInfo &arg); + + virtual int deep_copy(const memtable::ObIMultiSourceDataUnit *src, ObIAllocator *allocator = nullptr) override; + virtual void reset() override; + virtual bool is_valid() const override; + virtual int64_t get_data_size() const override { return sizeof(ObTabletBindingInfo); } + virtual memtable::MultiSourceDataUnitType type() const override { return memtable::MultiSourceDataUnitType::TABLET_BINDING_INFO; } + + TO_STRING_KV(K_(redefined), K_(snapshot_version), K_(schema_version), K_(data_tablet_id), K_(hidden_tablet_ids), K_(lob_meta_tablet_id), K_(lob_piece_tablet_id), K_(is_tx_end), K_(unsynced_cnt_for_multi_data)); +public: + bool redefined_; + int64_t snapshot_version_; // if redefined it is max readable snapshot, else it is min readable snapshot. + int64_t schema_version_; + common::ObTabletID data_tablet_id_; + common::ObSEArray hidden_tablet_ids_; + common::ObTabletID lob_meta_tablet_id_; + common::ObTabletID lob_piece_tablet_id_; +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletBindingInfo); +}; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_BINDING_INFO diff --git a/src/storage/tablet/ob_tablet_binding_mds_user_data.cpp b/src/storage/tablet/ob_tablet_binding_mds_user_data.cpp new file mode 100644 index 000000000..f405c80da --- /dev/null +++ b/src/storage/tablet/ob_tablet_binding_mds_user_data.cpp @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_binding_mds_user_data.h" +#include "storage/tablet/ob_tablet_binding_info.h" + +#define USING_LOG_PREFIX STORAGE + +namespace oceanbase +{ +namespace storage +{ +ObTabletBindingMdsUserData::ObTabletBindingMdsUserData() + : redefined_(false), + snapshot_version_(0), + schema_version_(0), + data_tablet_id_(), + hidden_tablet_id_(), + lob_meta_tablet_id_(), + lob_piece_tablet_id_() +{ +} + +void ObTabletBindingMdsUserData::reset() +{ + redefined_ = false; + snapshot_version_ = 0; + schema_version_ = 0; + data_tablet_id_.reset(); + hidden_tablet_id_.reset(); + lob_meta_tablet_id_.reset(); + lob_piece_tablet_id_.reset(); +} + +bool ObTabletBindingMdsUserData::is_valid() const +{ + bool valid = true; + + if (0 == snapshot_version_) { + valid = false; + } else if (0 == schema_version_) { + valid = false; + } + + return valid; +} + +int ObTabletBindingMdsUserData::assign(const ObTabletBindingMdsUserData &other) +{ + int ret = OB_SUCCESS; + redefined_ = other.redefined_; + snapshot_version_ = other.snapshot_version_; + schema_version_ = other.schema_version_; + data_tablet_id_ = other.data_tablet_id_; + hidden_tablet_id_ = other.hidden_tablet_id_; + lob_meta_tablet_id_ = other.lob_meta_tablet_id_; + lob_piece_tablet_id_ = other.lob_piece_tablet_id_; + return ret; +} + +int ObTabletBindingMdsUserData::assign_from_tablet_meta(const ObTabletBindingInfo &other) +{ + int ret = OB_SUCCESS; + + if (other.hidden_tablet_ids_.count() == 0) { + hidden_tablet_id_.reset(); + } else if (other.hidden_tablet_ids_.count() == 1) { + hidden_tablet_id_ = other.hidden_tablet_ids_.at(0); + } else { + ret = OB_ERR_UNEXPECTED; + } + if (OB_SUCC(ret)) { + redefined_ = other.redefined_; + snapshot_version_ = other.snapshot_version_; + schema_version_ = other.schema_version_; + data_tablet_id_ = other.data_tablet_id_; + lob_meta_tablet_id_ = other.lob_meta_tablet_id_; + lob_piece_tablet_id_ = other.lob_piece_tablet_id_; + } + + return ret; +} + +int ObTabletBindingMdsUserData::dump_to_tablet_meta(ObTabletBindingInfo &other) +{ + int ret = OB_SUCCESS; + + other.hidden_tablet_ids_.reset(); + if (hidden_tablet_id_.is_valid() && OB_FAIL(other.hidden_tablet_ids_.push_back(hidden_tablet_id_))) { + LOG_WARN("failed to push back hidden tablet id", K(ret)); + } else { + other.redefined_ = redefined_; + other.snapshot_version_ = snapshot_version_; + other.schema_version_ = schema_version_; + other.data_tablet_id_ = data_tablet_id_; + other.lob_meta_tablet_id_ = lob_meta_tablet_id_; + other.lob_piece_tablet_id_ = lob_piece_tablet_id_; + } + + return ret; +} + +void ObTabletBindingMdsUserData::on_commit(const share::SCN &commit_version, const share::SCN &commit_scn) +{ + if (OB_INVALID_VERSION == snapshot_version_) { + // unbind has set the mds with snapshot_version_ of -1, indicating that we need to fill in the commit version here + snapshot_version_ = commit_version.get_val_for_tx(); + } + LOG_INFO("binding mds commit", K(redefined_), K(snapshot_version_), K(commit_version)); + return; +} + +OB_SERIALIZE_MEMBER( + ObTabletBindingMdsUserData, + redefined_, + snapshot_version_, + schema_version_, + data_tablet_id_, + hidden_tablet_id_, + lob_meta_tablet_id_, + lob_piece_tablet_id_); +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_binding_mds_user_data.h b/src/storage/tablet/ob_tablet_binding_mds_user_data.h new file mode 100644 index 000000000..77c129203 --- /dev/null +++ b/src/storage/tablet/ob_tablet_binding_mds_user_data.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_BINDING_MDS_USER_DATA +#define OCEANBASE_STORAGE_OB_TABLET_BINDING_MDS_USER_DATA + +#include +#include "lib/container/ob_se_array.h" +#include "lib/utility/ob_print_utils.h" +#include "share/scn.h" +#include "common/ob_tablet_id.h" + +namespace oceanbase +{ +namespace common +{ +class ObIAllocator; +} + +namespace storage +{ +class ObTabletBindingInfo; + +class ObTabletBindingMdsUserData +{ +public: + OB_UNIS_VERSION(1); + +public: + ObTabletBindingMdsUserData(); + ~ObTabletBindingMdsUserData() = default; + ObTabletBindingMdsUserData(const ObTabletBindingMdsUserData &) = delete; + ObTabletBindingMdsUserData &operator=(const ObTabletBindingMdsUserData &) = delete; + +public: + bool is_valid() const; + int set_allocator(common::ObIAllocator &allocator); + int assign(const ObTabletBindingMdsUserData &other); + int assign_from_tablet_meta(const ObTabletBindingInfo &other); + int dump_to_tablet_meta(ObTabletBindingInfo &other); + void on_commit(const share::SCN &commit_version, const share::SCN &commit_scn); + + void reset(); + + TO_STRING_KV(K_(redefined), + K_(snapshot_version), + K_(schema_version), + K_(data_tablet_id), + K_(hidden_tablet_id), + K_(lob_meta_tablet_id), + K_(lob_piece_tablet_id), + K_(is_old_mds)); + +public: + bool redefined_; + int64_t snapshot_version_; // if redefined it is max readable snapshot, else it is min readable snapshot. + int64_t schema_version_; + common::ObTabletID data_tablet_id_; + common::ObTabletID hidden_tablet_id_; + common::ObTabletID lob_meta_tablet_id_; + common::ObTabletID lob_piece_tablet_id_; + bool is_old_mds_; +}; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_BINDING_MDS_USER_DATA diff --git a/src/storage/tablet/ob_tablet_binding_replay_executor.cpp b/src/storage/tablet/ob_tablet_binding_replay_executor.cpp new file mode 100644 index 000000000..935836bed --- /dev/null +++ b/src/storage/tablet/ob_tablet_binding_replay_executor.cpp @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2023 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 "storage/tablet/ob_tablet_binding_replay_executor.h" +#include "storage/multi_data_source/mds_ctx.h" + +#define USING_LOG_PREFIX STORAGE + +namespace oceanbase +{ +namespace storage +{ + +ObTabletBindingReplayExecutor::ObTabletBindingReplayExecutor() + :logservice::ObTabletReplayExecutor(), user_ctx_(nullptr), user_data_(nullptr) +{} + +int ObTabletBindingReplayExecutor::init( + mds::BufferCtx &user_ctx, + ObTabletBindingMdsUserData &user_data, + const share::SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("tablet binding replay executor init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid argument", KR(ret), K(scn)); + } else { + user_ctx_ = &user_ctx; + user_data_ = &user_data; + scn_ = scn; + is_inited_ = true; + } + return ret; +} + + +int ObTabletBindingReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + mds::MdsCtx &user_ctx = static_cast(*user_ctx_); + + if (OB_FAIL(replay_to_mds_table_(tablet_handle, *user_data_, user_ctx, scn_))) { + LOG_WARN("failed to replay to tablet", K(ret)); + } + + return ret; +} + +} +} \ No newline at end of file diff --git a/src/storage/tablet/ob_tablet_binding_replay_executor.h b/src/storage/tablet/ob_tablet_binding_replay_executor.h new file mode 100644 index 000000000..deef3a398 --- /dev/null +++ b/src/storage/tablet/ob_tablet_binding_replay_executor.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2023 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_STORAGE_OB_TABLET_BINDING_REPLAY_EXECUTOR +#define OCEANBASE_STORAGE_OB_TABLET_BINDING_REPLAY_EXECUTOR + +#include "common/ob_tablet_id.h" +#include "logservice/replayservice/ob_tablet_replay_executor.h" +#include "storage/tablet/ob_tablet_binding_mds_user_data.h" + +namespace oceanbase +{ + +namespace storage +{ + +class ObTabletBindingReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObTabletBindingReplayExecutor(); + + int init( + mds::BufferCtx &user_ctx, + ObTabletBindingMdsUserData &user_data, + const share::SCN &scn); + +protected: + bool is_replay_update_user_data_() const override + { + return false; + } + + int do_replay_(ObTabletHandle &tablet_handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return true; + } + +private: + mds::BufferCtx *user_ctx_; + ObTabletBindingMdsUserData *user_data_; + share::SCN scn_; +}; + + +} +} + +#endif diff --git a/src/storage/tablet/ob_tablet_common.cpp b/src/storage/tablet/ob_tablet_common.cpp index fb60dd1a6..8cab1b613 100644 --- a/src/storage/tablet/ob_tablet_common.cpp +++ b/src/storage/tablet/ob_tablet_common.cpp @@ -16,9 +16,6 @@ namespace oceanbase { namespace storage { -const int64_t ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US; -const int64_t ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US; -const int64_t ObTabletCommon::DEFAULT_GET_TABLET_TIMEOUT_US; const int64_t ObTabletCommon::FINAL_TX_ID; } // namespace storage } // namespace oceanbase \ No newline at end of file diff --git a/src/storage/tablet/ob_tablet_common.h b/src/storage/tablet/ob_tablet_common.h index a49f03b86..07570e266 100644 --- a/src/storage/tablet/ob_tablet_common.h +++ b/src/storage/tablet/ob_tablet_common.h @@ -19,21 +19,44 @@ namespace oceanbase { namespace storage { +/* + Tablet is created/deleted through MDS which has transactional meaning. + Consider creating tablet as inserting a row to database, and deleting tablet as + remove a row from database. So below ObMDSGetTabletMode can be understood as read + isolation level in a database. + + READ_ALL_COMMITED: + Read committed row after transaction committed, except deletion transaction. + Return tablet in NORMAL, TRANSFER_IN, TRANSFER_OUT status. + Not return CREATING and DELETING who was abandoned from 4.2. + In addition, you should NOT pass read timeout under this mode. + + READ_WITHOUT_CHECK: + Read uncommitted row. Return tablet whatever it is in a MDS transaction or not. + + READ_READABLE_COMMITED: + Read commited row, not include deleted one. The most frequently used mode. Return + tablet in NORMAL, TRANSFER_IN status. Not return one in unreadable status. + If latest tablet status is TRANSFER_OUT, we should check transfer scn to decide + whether it is legal to return the tablet. + If read operation reaches read timeout, you'll get OB_ERR_SHARED_LOCK_CONFLICT error. +*/ +enum class ObMDSGetTabletMode +{ + READ_ALL_COMMITED = 0, + READ_WITHOUT_CHECK = 1, + READ_READABLE_COMMITED = 2, +}; + class ObTabletCommon final { public: - // DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US: only get NORMAL tablet instantly - static const int64_t DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US = -1; - // NO_CHECK_GET_TABLET_TIMEOUT_US: return tablet handle IMMEDIATELY if succeeded, won't check tablet status - static const int64_t NO_CHECK_GET_TABLET_TIMEOUT_US = 0; - // DEFAULT_GET_TABLET_TIMEOUT_US: cond wait until tablet status changes to NORMAL/DELETED - static const int64_t DEFAULT_GET_TABLET_TIMEOUT_US = 10 * 1000 * 1000; // 10s - static const int64_t DEFAULT_ITERATOR_TABLET_ID_CNT = 128; static const int64_t BUCKET_LOCK_BUCKET_CNT = 10243L; static const int64_t TABLET_ID_SET_BUCKET_CNT = 10243L; + static const int64_t DEFAULT_GET_TABLET_NO_WAIT = 0; // 0s static const int64_t DEFAULT_GET_TABLET_DURATION_US = 1 * 1000 * 1000; // 1s - + static const int64_t DEFAULT_GET_TABLET_DURATION_10_S = 10 * 1000 * 1000; // 10s static const int64_t FINAL_TX_ID = 0; }; } // namespace storage diff --git a/src/storage/tablet/ob_tablet_complex_addr.cpp b/src/storage/tablet/ob_tablet_complex_addr.cpp new file mode 100644 index 000000000..ce7a10590 --- /dev/null +++ b/src/storage/tablet/ob_tablet_complex_addr.cpp @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_complex_addr.h" + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +template <> +int64_t ObTabletComplexAddr::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + + if (OB_ISNULL(buf) || buf_len <= 0) { + // do nothing + } else { + databuff_printf(buf, buf_len, pos, "{ptr:%p", static_cast(ptr_)); + if (nullptr != ptr_) { + databuff_printf(buf, buf_len, pos, ", dump_node:"); + const mds::MdsDumpNode &dump_node = ptr_->v_; + dump_node.simple_to_string(buf, buf_len, pos); + } + databuff_print_json_kv_comma(buf, buf_len, pos, "addr", addr_); + databuff_printf(buf, buf_len, pos, "}"); + } + return pos; +} + +template <> +int64_t ObTabletComplexAddr::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + + if (OB_ISNULL(buf) || buf_len <= 0) { + // do nothing + } else { + databuff_printf(buf, buf_len, pos, "{ptr:%p", static_cast(ptr_)); + if (nullptr != ptr_) { + databuff_printf(buf, buf_len, pos, ", auto_inc_seq:"); + databuff_print_obj(buf, buf_len, pos, *ptr_); + } + databuff_print_json_kv_comma(buf, buf_len, pos, "addr", addr_); + databuff_printf(buf, buf_len, pos, "}"); + } + return pos; +} + +template <> +int64_t ObTabletComplexAddr::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + + if (OB_ISNULL(buf) || buf_len <= 0) { + // do nothing + } else { + databuff_printf(buf, buf_len, pos, "{ptr:%p", static_cast(ptr_)); + if (nullptr != ptr_) { + databuff_printf(buf, buf_len, pos, ", dumped_medium_info:"); + ptr_->simple_to_string(buf, buf_len, pos); + } + databuff_print_json_kv_comma(buf, buf_len, pos, "addr", addr_); + databuff_printf(buf, buf_len, pos, "}"); + } + return pos; +} +} // namespace storage +} // namespace oceanbase \ No newline at end of file diff --git a/src/storage/tablet/ob_tablet_complex_addr.h b/src/storage/tablet/ob_tablet_complex_addr.h new file mode 100644 index 000000000..a3b02ccf9 --- /dev/null +++ b/src/storage/tablet/ob_tablet_complex_addr.h @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_COMPLEX_ADDR +#define OCEANBASE_STORAGE_OB_TABLET_COMPLEX_ADDR + +#include +#include "lib/ob_errno.h" +#include "lib/utility/ob_macro_utils.h" +#include "lib/utility/ob_unify_serialize.h" +#include "share/ob_tablet_autoincrement_param.h" +#include "storage/meta_mem/ob_meta_obj_struct.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include "storage/tablet/ob_tablet_dumped_medium_info.h" + +namespace oceanbase +{ +namespace storage +{ +template +class ObTabletComplexAddr final +{ +public: + ObTabletComplexAddr(); + explicit ObTabletComplexAddr(T *ptr); + ~ObTabletComplexAddr(); +public: + bool is_valid() const; + bool is_memory_object() const; + bool is_disk_object() const; + bool is_none_object() const; + void reset(); + T* get_ptr() const { return ptr_; } +public: + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize(const char *buf, const int64_t data_len, int64_t &pos); + int64_t get_serialize_size() const; + + int64_t to_string(char *buf, const int64_t buf_len) const; +public: + T *ptr_; + ObMetaDiskAddr addr_; +}; + +template +ObTabletComplexAddr::ObTabletComplexAddr() + : ptr_(nullptr), + addr_() +{ +} + +template +ObTabletComplexAddr::ObTabletComplexAddr(T *ptr) + : ptr_(ptr), + addr_() +{ +} + +template +ObTabletComplexAddr::~ObTabletComplexAddr() +{ + reset(); +} + +template +bool ObTabletComplexAddr::is_valid() const +{ + return is_memory_object() || is_disk_object() || is_none_object(); +} + +template +bool ObTabletComplexAddr::is_memory_object() const +{ + return nullptr != ptr_; +} + +template +bool ObTabletComplexAddr::is_disk_object() const +{ + return nullptr == ptr_ && addr_.is_block(); +} + +template +bool ObTabletComplexAddr::is_none_object() const +{ + return nullptr == ptr_ && addr_.is_none(); +} + +template +void ObTabletComplexAddr::reset() +{ + if (nullptr != ptr_) { + ptr_->~T(); + ptr_ = nullptr; + } + addr_.reset(); +} + +template +int ObTabletComplexAddr::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = common::OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, + addr_); + return ret; +} + +template +int ObTabletComplexAddr::deserialize(const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = common::OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, + addr_); + return ret; +} + +template +int64_t ObTabletComplexAddr::get_serialize_size() const +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, + addr_); + return len; +} + +template +int64_t ObTabletComplexAddr::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + + if (OB_ISNULL(buf) || buf_len <= 0) { + // do nothing + } else { + J_OBJ_START(); + J_KV(K_(ptr), K_(addr)); + J_OBJ_END(); + } + + return pos; +} + +template <> +int64_t ObTabletComplexAddr::to_string(char *buf, const int64_t buf_len) const; + +template <> +int64_t ObTabletComplexAddr::to_string(char *buf, const int64_t buf_len) const; + +template <> +int64_t ObTabletComplexAddr::to_string(char *buf, const int64_t buf_len) const; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_COMPLEX_ADDR diff --git a/src/storage/tablet/ob_tablet_create_delete_helper.cpp b/src/storage/tablet/ob_tablet_create_delete_helper.cpp old mode 100644 new mode 100755 index ed4b5f573..116cfb3d0 --- a/src/storage/tablet/ob_tablet_create_delete_helper.cpp +++ b/src/storage/tablet/ob_tablet_create_delete_helper.cpp @@ -24,11 +24,12 @@ #include "storage/ls/ob_ls_tablet_service.h" #include "storage/meta_mem/ob_tablet_map_key.h" #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/meta_mem/ob_tablet_handle.h" #include "storage/tablet/ob_tablet_binding_helper.h" #include "storage/tablet/ob_tablet_create_sstable_param.h" #include "storage/tablet/ob_tablet.h" #include "storage/tablet/ob_tablet_id_set.h" -#include "storage/tablet/ob_tablet_status.h" +#include "storage/tablet/ob_tablet_persister.h" #include "storage/tx/ob_trans_define.h" #include "storage/tx_storage/ob_ls_service.h" #include "share/scn.h" @@ -51,1348 +52,6 @@ namespace oceanbase { namespace storage { -ObTabletCreateInfo::ObTabletCreateInfo() - : create_data_tablet_(false), - data_tablet_id_(), - index_tablet_id_array_(), - lob_meta_tablet_id_(), - lob_piece_tablet_id_() -{ -} - -ObTabletCreateInfo::ObTabletCreateInfo(const ObTabletCreateInfo &other) - : create_data_tablet_(other.create_data_tablet_), - data_tablet_id_(other.data_tablet_id_), - index_tablet_id_array_(other.index_tablet_id_array_), - lob_meta_tablet_id_(other.lob_meta_tablet_id_), - lob_piece_tablet_id_(other.lob_piece_tablet_id_) -{ -} - -ObTabletCreateInfo &ObTabletCreateInfo::operator=(const ObTabletCreateInfo &other) -{ - if (this != &other) { - create_data_tablet_ = other.create_data_tablet_; - data_tablet_id_ = other.data_tablet_id_; - index_tablet_id_array_ = other.index_tablet_id_array_; - lob_meta_tablet_id_ = other.lob_meta_tablet_id_; - lob_piece_tablet_id_ = other.lob_piece_tablet_id_; - } - return *this; -} - - -ObTabletCreateDeleteHelper::ObTabletCreateDeleteHelper( - ObLS &ls, - ObTabletIDSet &tablet_id_set) - : ls_(ls), - tablet_id_set_(tablet_id_set) -{ -} - -int ObTabletCreateDeleteHelper::prepare_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = ls_.get_ls_id(); - const ObTransID &tx_id = trans_flags.tx_id_; - const SCN scn = trans_flags.scn_; - const bool is_clog_replaying = trans_flags.for_replay_; - const int64_t create_begin_ts = ObTimeUtility::current_monotonic_time(); - ObTabletBindingPrepareCtx binding_ctx; - - if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(PRINT_CREATE_ARG(arg))); - } else if (OB_UNLIKELY(arg.id_ != ls_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected arg", K(ret), K(PRINT_CREATE_ARG(arg)), K(ls_id)); - } else if (OB_FAIL(ObTabletBindingHelper::lock_tablet_binding_for_create(arg, ls_, trans_flags, binding_ctx))) { - LOG_WARN("failed to lock tablet binding", K(ret)); - } else if (is_clog_replaying) { - if (OB_FAIL(replay_prepare_create_tablets(arg, trans_flags))) { - LOG_WARN("failed to replay prepare create tablets", K(ret), K(trans_flags), K(PRINT_CREATE_ARG(arg))); - } - } else { - // NOT in clog replaying procedure - if (OB_FAIL(check_create_new_tablets(arg))) { - LOG_WARN("failed to check crate new tablets", K(ret), K(trans_flags), K(PRINT_CREATE_ARG(arg))); - } else if (OB_FAIL(do_prepare_create_tablets(arg, trans_flags))) { - LOG_WARN("failed to do prepare create tablets", K(ret), K(trans_flags), K(PRINT_CREATE_ARG(arg))); - } else { - LOG_INFO("succeeded to prepare create tablets", K(ret), K(trans_flags), K(PRINT_CREATE_ARG(arg))); - } - } - - if (OB_FAIL(ret) && !is_clog_replaying) { - ObTabletBindingHelper::rollback_lock_tablet_binding_for_create(arg, ls_, trans_flags, binding_ctx); - } - - if (OB_SUCC(ret)) { - const int64_t create_cost_time = ObTimeUtility::current_monotonic_time() - create_begin_ts; - LOG_INFO("prepare create cost time", K(ret), K(trans_flags), K(create_begin_ts), K(create_cost_time)); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::replay_prepare_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - SCN scn = trans_flags.scn_; - const ObBatchCreateTabletArg *final_arg = &arg; - ObBatchCreateTabletArg new_arg; - ObSArray existed_tablet_id_array; - NonLockedHashSet existed_tablet_id_set; - bool need_create = true; - - if (OB_UNLIKELY(!arg.is_valid() || !scn.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(PRINT_CREATE_ARG(arg)), K(scn)); - } else if (OB_FAIL(existed_tablet_id_set.create(arg.get_tablet_count()))) { - LOG_WARN("failed to init existed tablet id set", K(ret), K(PRINT_CREATE_ARG(arg))); - } else if (OB_FAIL(get_all_existed_tablets(arg, scn, existed_tablet_id_array, existed_tablet_id_set))) { - LOG_WARN("failed to get all existed tablets", K(ret), K(PRINT_CREATE_ARG(arg)), K(scn)); - } else if (!existed_tablet_id_set.empty()) { - if (OB_FAIL(build_batch_create_tablet_arg(arg, existed_tablet_id_set, new_arg))) { - LOG_WARN("failed to build new batch create tablet arg", K(ret), - K(PRINT_CREATE_ARG(arg)), K(existed_tablet_id_set)); - } else if (new_arg.get_tablet_count() == 0) { - // all tablet ids exist, no need to create, do nothing - need_create = false; - } else if (OB_UNLIKELY(!new_arg.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("new arg is invalid", K(ret), K(PRINT_CREATE_ARG(new_arg))); - } else { - final_arg = &new_arg; - } - } - - if (OB_FAIL(ret)) { - } else if (trans_flags.for_replay_ - && OB_FAIL(handle_special_tablets_for_replay(existed_tablet_id_array, trans_flags))) { - LOG_WARN("failed to handle special tablets for replay", K(ret), K(existed_tablet_id_array), K(trans_flags)); - } else if (!need_create) { - LOG_INFO("all tablets exist, no need to create", K(ret), K(PRINT_CREATE_ARG(arg)), KPC(final_arg)); - // MUST check data tablet existence because skipping early replaying auxiliary tablets creation - // might omit updating attributes on data tablet - if (OB_FAIL(ensure_skip_create_all_tablets_safe(*final_arg, scn))) { - LOG_WARN("failed to replay check tablet", K(ret), K(scn), K(PRINT_CREATE_ARG(*final_arg))); - } - } else if (OB_FAIL(do_prepare_create_tablets(*final_arg, trans_flags))) { - LOG_WARN("failed to do prepare create tablets", K(ret), K(trans_flags), K(PRINT_CREATE_ARG(*final_arg))); - } else { - LOG_INFO("succeeded to replay prepare create tablets", K(ret), K(trans_flags), K(PRINT_CREATE_ARG(*final_arg))); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::do_prepare_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObSArray tablet_create_info_array; - - if (OB_FAIL(verify_tablets_absence(arg, tablet_create_info_array))) { - LOG_WARN("failed to verify tablets", K(ret), K(PRINT_CREATE_ARG(arg))); - } else { - if (OB_FAIL(batch_create_tablets(arg, trans_flags))) { - LOG_WARN("failed to do batch create tablets", K(ret), K(PRINT_CREATE_ARG(arg)), K(trans_flags)); - } else if (OB_FAIL(record_tablet_id(tablet_create_info_array))) { - LOG_WARN("failed to record tablet id", K(ret)); - } - - // roll back operation - if (OB_FAIL(ret)) { - int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(roll_back_remove_tablets(arg, trans_flags))) { - LOG_WARN("failed to roll back remove tablets", K(tmp_ret), K(trans_flags), K(PRINT_CREATE_ARG(arg)), K(lbt())); - ob_usleep(1000 * 1000); - ob_abort(); // roll back operation should NOT fail - } - } - } - - if (OB_FAIL(ret) && OB_ALLOCATE_MEMORY_FAILED == ret) { - ret = OB_EAGAIN; - LOG_WARN("failed due to 4013, has rolled back operations", K(ret), K(trans_flags), K(arg)); - } - - if (OB_SUCC(ret)) { - print_multi_data_for_create_tablet(tablet_create_info_array); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::record_tablet_id( - const ObIArray &tablet_create_info_array) -{ - int ret = OB_SUCCESS; - - for (int64_t i = 0; i < tablet_create_info_array.count(); ++i) { - const ObTabletCreateInfo &info = tablet_create_info_array.at(i); - if (info.create_data_tablet_) { - if (OB_FAIL(tablet_id_set_.set(info.data_tablet_id_))) { - LOG_WARN("fail to set tablet id set", K(ret), "tablet_id", info.data_tablet_id_); - } - } - - for (int64_t j = 0; j < info.index_tablet_id_array_.count(); ++j) { - const ObTabletID &tablet_id = info.index_tablet_id_array_.at(j); - if (OB_FAIL(tablet_id_set_.set(tablet_id))) { - LOG_WARN("fail to set tablet id set", K(ret), K(tablet_id)); - } - } - - if (info.lob_meta_tablet_id_.is_valid()) { - const ObTabletID &tablet_id = info.lob_meta_tablet_id_; - if (OB_FAIL(tablet_id_set_.set(tablet_id))) { - LOG_WARN("fail to set tablet id set", K(ret), K(tablet_id)); - } - } - - if (info.lob_piece_tablet_id_.is_valid()) { - const ObTabletID &tablet_id = info.lob_piece_tablet_id_; - if (OB_FAIL(tablet_id_set_.set(tablet_id))) { - LOG_WARN("fail to set tablet id set", K(ret), K(tablet_id)); - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::handle_special_tablets_for_replay( - const ObIArray &existed_tablet_id_array, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - ObTabletHandle tablet_handle; - ObTabletTxMultiSourceDataUnit tx_data; - const ObLSID &ls_id = ls_.get_ls_id(); - ObTabletMapKey key; - key.ls_id_ = ls_id; - - if (OB_UNLIKELY(!trans_flags.for_replay_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("only handle special tablets for replay", K(ret), K(trans_flags)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < existed_tablet_id_array.count(); ++i) { - const ObTabletID &tablet_id = existed_tablet_id_array.at(i); - key.tablet_id_ = tablet_id; - tx_data.reset(); - bool tx_data_is_valid = false; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } else if (OB_FAIL(tablet_handle.get_obj()->check_tx_data(tx_data_is_valid))) { - LOG_WARN("failed to check tx data", K(ret)); - } else if (OB_UNLIKELY(tx_data_is_valid)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tx data should not be valid", K(ret), K(key)); - } else { - int tmp_ret = OB_SUCCESS; - tx_data.tx_id_ = trans_flags.tx_id_; - tx_data.tx_scn_ = trans_flags.scn_; - tx_data.tablet_status_ = ObTabletStatus::CREATING; - const MemtableRefOp ref_op = MemtableRefOp::NONE; - - if (OB_FAIL(tablet_handle.get_obj()->set_tx_data(tx_data, trans_flags.for_replay_, ref_op))) { - LOG_WARN("failed to set tx data", K(ret), K(tx_data), K(trans_flags), K(ref_op)); - } else if (OB_FAIL(t3m->insert_pinned_tablet(key))) { - LOG_WARN("failed to insert in tx tablet", K(ret)); - } - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::set_scn( - const ObIArray &tablet_create_info_array, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObTablet *tablet = nullptr; - const ObLSID &ls_id = ls_.get_ls_id(); - ObTabletMapKey key; - key.ls_id_ = ls_id; - SCN scn = trans_flags.scn_; - const int64_t tx_id = trans_flags.tx_id_; - const bool for_replay = false; - - for (int64_t i = 0; i < tablet_create_info_array.count(); ++i) { - const ObTabletCreateInfo &info = tablet_create_info_array.at(i); - if (info.create_data_tablet_) { - key.tablet_id_ = info.data_tablet_id_; - if (OB_TMP_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", K(tmp_ret), K(key)); - } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_TMP_FAIL(tablet->set_tx_scn(tx_id, scn, for_replay))) { - LOG_WARN("failed to set tx log ts", K(tmp_ret), K(key), K(scn)); - } else if (OB_TMP_FAIL(tablet->tablet_meta_.update_create_scn(scn))) { - LOG_WARN("failed to update create scn", K(tmp_ret), K(scn)); - } - } - if (OB_SUCC(ret) && OB_TMP_FAIL(tmp_ret)) { - ret = tmp_ret; - } - - if (info.lob_meta_tablet_id_.is_valid()) { - key.tablet_id_ = info.lob_meta_tablet_id_; - if (OB_TMP_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", K(tmp_ret), K(key)); - } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_TMP_FAIL(tablet->set_tx_scn(tx_id, scn, for_replay))) { - LOG_WARN("failed to set tx log ts", K(tmp_ret), K(key), K(scn)); - } else if (OB_TMP_FAIL(tablet->tablet_meta_.update_create_scn(scn))) { - LOG_WARN("failed to update create scn", K(tmp_ret), K(scn)); - } - } - if (OB_SUCC(ret) && OB_TMP_FAIL(tmp_ret)) { - ret = tmp_ret; - } - - if (info.lob_piece_tablet_id_.is_valid()) { - key.tablet_id_ = info.lob_piece_tablet_id_; - if (OB_TMP_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", K(tmp_ret), K(key)); - } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_TMP_FAIL(tablet->set_tx_scn(tx_id, scn, for_replay))) { - LOG_WARN("failed to set tx log ts", K(tmp_ret), K(key), K(scn)); - } else if (OB_TMP_FAIL(tablet->tablet_meta_.update_create_scn(scn))) { - LOG_WARN("failed to update create scn", K(tmp_ret), K(scn)); - } - } - if (OB_SUCC(ret) && OB_TMP_FAIL(tmp_ret)) { - ret = tmp_ret; - } - - for (int64_t j = 0; j < info.index_tablet_id_array_.count(); ++j) { - const ObTabletID &index_tablet_id = info.index_tablet_id_array_.at(j); - key.tablet_id_ = index_tablet_id; - if (OB_TMP_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", K(tmp_ret), K(key)); - } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_TMP_FAIL(tablet->set_tx_scn(tx_id, scn, for_replay))) { - LOG_WARN("failed to set tx log ts", K(tmp_ret), K(key), K(scn)); - } else if (OB_TMP_FAIL(tablet->tablet_meta_.update_create_scn(scn))) { - LOG_WARN("failed to update create scn", K(tmp_ret), K(scn)); - } - if (OB_SUCC(ret) && OB_TMP_FAIL(tmp_ret)) { - ret = tmp_ret; - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::print_multi_data_for_create_tablet( - const ObIArray &tablet_create_info_array) -{ - int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - const ObLSID &ls_id = ls_.get_ls_id(); - ObTabletMapKey key; - key.ls_id_ = ls_id; - ObTabletTxMultiSourceDataUnit tx_data; - - for (int64_t i = 0; i < tablet_create_info_array.count(); ++i) { - const ObTabletCreateInfo &info = tablet_create_info_array.at(i); - if (info.create_data_tablet_) { - key.tablet_id_ = info.data_tablet_id_; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_SUCCESS; - LOG_INFO("tablet does not exist", K(key)); - } else { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } else if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get_tx_data", K(ret), K(key)); - } else { - LOG_INFO("create tablet tx_data", K(tx_data), K(tablet_handle.get_obj()->get_tablet_meta().tablet_id_)); - } - } - - for (int64_t j = 0; j < info.index_tablet_id_array_.count(); ++j) { - const ObTabletID &index_tablet_id = info.index_tablet_id_array_.at(j); - key.tablet_id_ = index_tablet_id; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_SUCCESS; - LOG_INFO("tablet does not exist", K(key)); - } else { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } else if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get_tx_data", K(ret), K(key)); - } else { - LOG_INFO("create index tablet tx_data", K(tx_data), K(tablet_handle.get_obj()->get_tablet_meta().tablet_id_)); - } - } - - if (info.lob_meta_tablet_id_.is_valid()) { - key.tablet_id_ = info.lob_meta_tablet_id_; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_SUCCESS; - LOG_INFO("tablet does not exist", K(key)); - } else { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } else if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get_tx_data", K(ret), K(key)); - } else { - LOG_INFO("create lob meta tablet tx_data", K(tx_data), K(tablet_handle.get_obj()->get_tablet_meta().tablet_id_)); - } - } - - if (info.lob_piece_tablet_id_.is_valid()) { - key.tablet_id_ = info.lob_piece_tablet_id_; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_SUCCESS; - LOG_INFO("tablet does not exist", K(key)); - } else { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } else if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get_tx_data", K(ret), K(key)); - } else { - LOG_INFO("create lob piece tablet tx_data", K(tx_data), K(tablet_handle.get_obj()->get_tablet_meta().tablet_id_)); - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::print_multi_data_for_remove_tablet( - const ObBatchRemoveTabletArg &arg) -{ - int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObTabletMapKey key; - key.ls_id_ = arg.id_; - - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_ids_.count(); ++i) { - const ObTabletID &tablet_id = arg.tablet_ids_[i]; - key.tablet_id_ = tablet_id; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_SUCCESS; - LOG_INFO("tablet does not exist", "ls_id", arg.id_, K(tablet_id)); - } else { - LOG_WARN("failed to get tablet", K(ret), "ls_id", arg.id_, K(tablet_id)); - } - } else { - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(tablet_handle)); - } else { - LOG_INFO("remove tablet tx_data", K(tx_data), K(tablet_handle.get_obj()->get_tablet_meta().tablet_id_)); - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::redo_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = ls_.get_ls_id(); - SCN scn = trans_flags.scn_; - const bool is_clog_replaying = trans_flags.for_replay_; - - if (OB_UNLIKELY(!arg.is_valid() || !scn.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_ERROR("invalid args", K(ret), K(PRINT_CREATE_ARG(arg))); - } else if (OB_UNLIKELY(arg.id_ != ls_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("unexpected arg", K(ret), K(PRINT_CREATE_ARG(arg)), K(ls_id)); - } else if (is_clog_replaying) { - LOG_INFO("in clog replaying procedure, do nothing while redo log callback", K(ret)); - } else { - bool is_valid = true; - ObSArray tablet_create_info_array; - if (OB_FAIL(check_tablet_existence(arg, is_valid))) { - LOG_ERROR("failed to check tablet existence", K(ret), K(PRINT_CREATE_ARG(arg))); - } else if (!is_valid) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("unexpected error, tablet does not exist", K(ret)); - } else if (OB_FAIL(build_tablet_create_info(arg, tablet_create_info_array))) { - LOG_ERROR("failed to build tablet create info", K(ret)); - } else if (OB_FAIL(set_scn(tablet_create_info_array, trans_flags))) { - LOG_ERROR("failed to set log ts", K(ret), K(tablet_create_info_array), K(scn)); - } else if (FALSE_IT(print_multi_data_for_create_tablet(tablet_create_info_array))) { - } else if (OB_FAIL(ObTabletBindingHelper::set_scn_for_create(arg, ls_, trans_flags))) { - LOG_WARN("failed to set log ts for create", K(ret)); - } else { - LOG_INFO("succeeded to redo create tablets", K(ret), K(trans_flags), K(PRINT_CREATE_ARG(arg))); - } - } - return ret; -} - -int ObTabletCreateDeleteHelper::commit_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags, - ObIArray &tablet_id_array) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = ls_.get_ls_id(); - - if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(PRINT_CREATE_ARG(arg))); - } else if (OB_UNLIKELY(arg.id_ != ls_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected arg", K(ret), K(PRINT_CREATE_ARG(arg)), K(ls_id)); - } else { - bool is_valid = true; - ObSArray tablet_create_info_array; - if (OB_FAIL(ObTabletBindingHelper::modify_tablet_binding_for_create(arg, ls_, trans_flags))) { - LOG_ERROR("failed to modify tablet binding", K(ret), K(trans_flags)); - } else if (OB_FAIL(build_tablet_create_info(arg, tablet_create_info_array))) { - LOG_WARN("failed to build tablet create info", K(ret), K(PRINT_CREATE_ARG(arg))); - } else if (OB_FAIL(do_commit_create_tablets(arg, trans_flags, tablet_id_array))) { - LOG_WARN("failed to commit create tablets", K(ret), K(PRINT_CREATE_ARG(arg)), K(trans_flags)); - } else if (FALSE_IT(print_multi_data_for_create_tablet(tablet_create_info_array))) { - } else if (OB_FAIL(ObTabletBindingHelper::unlock_tablet_binding_for_create(arg, ls_, trans_flags))) { - LOG_ERROR("failed to unlock tablet binding", K(ret), K(trans_flags)); - } else { - LOG_INFO("succeeded to commit create tablets", K(ret), K(PRINT_CREATE_ARG(arg)), K(trans_flags)); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::do_commit_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags, - ObIArray &tablet_id_array) -{ - int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObTabletMapKey key; - key.ls_id_ = arg.id_; - - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - const ObTabletID &tablet_id = info.tablet_ids_.at(j); - key.tablet_id_ = tablet_id; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - if (trans_flags.for_replay_) { - ret = OB_SUCCESS; - LOG_INFO("tablet does not exist, maybe already deleted, skip commit", K(ret), K(key)); - } else { - LOG_WARN("unexepected error, tablet does not exist", K(ret), K(key)); - } - } else { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } else if (OB_FAIL(do_commit_create_tablet(tablet_id, trans_flags))) { - LOG_WARN("failed to do commit create tablet", K(ret), K(tablet_id), K(trans_flags)); - } else if (OB_FAIL(tablet_id_array.push_back(tablet_id))) { - LOG_WARN("failed to push back tablet id", K(ret), K(tablet_id)); - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::do_commit_create_tablet( - const ObTabletID &tablet_id, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - const ObTabletMapKey key(ls_.get_ls_id(), tablet_id); - ObTabletHandle tablet_handle; - ObTabletTxMultiSourceDataUnit tx_data; - - if (OB_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } else if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(tablet_handle)); - } else if (trans_flags.for_replay_ && trans_flags.scn_ <= tx_data.tx_scn_) { - // replaying procedure, clog ts is smaller than tx log ts, just skip - LOG_INFO("skip commit create tablet", K(ret), K(key), K(trans_flags), K(tx_data)); - } else if (OB_UNLIKELY(!trans_flags.for_replay_ && trans_flags.scn_ <= tx_data.tx_scn_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("log ts is smaller than tx log ts", K(ret), K(key), K(trans_flags), K(tx_data)); - } else if (OB_UNLIKELY(trans_flags.tx_id_ != tx_data.tx_id_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tx id does not equal", K(ret), K(key), K(trans_flags), K(tx_data)); - tablet_handle.get_obj()->print_memtables_for_table(); - } else if (OB_UNLIKELY(ObTabletStatus::CREATING != tx_data.tablet_status_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet status is not CREATING", K(ret), K(key), K(trans_flags), K(tx_data)); - } else { - if (OB_FAIL(set_tablet_final_status(tablet_handle, ObTabletStatus::NORMAL, - trans_flags.scn_, trans_flags.scn_, trans_flags.for_replay_))) { - LOG_WARN("failed to set tablet status to NORMAL", K(ret), K(tablet_handle), - K(trans_flags.scn_), K(trans_flags)); - } else if (OB_FAIL(t3m->erase_pinned_tablet(key))) { - LOG_ERROR("failed to erase tablet handle", K(ret), K(key)); - ob_usleep(1000 * 1000); - ob_abort(); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::abort_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = ls_.get_ls_id(); - - if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(PRINT_CREATE_ARG(arg))); - } else if (OB_UNLIKELY(arg.id_ != ls_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected arg", K(ret), K(PRINT_CREATE_ARG(arg))); - } else if (OB_FAIL(ObTabletBindingHelper::fix_binding_info_for_create_tablets(arg, ls_, trans_flags))) { - LOG_WARN("failed to fix_binding_info_for_create_tablets", K(ret), K(arg), K(trans_flags)); - } else if (OB_FAIL(do_abort_create_tablets(arg, trans_flags))) { - LOG_WARN("failed to do abort create tablets", K(ret), K(PRINT_CREATE_ARG(arg)), K(trans_flags)); - } else if (OB_FAIL(ObTabletBindingHelper::unlock_tablet_binding_for_create(arg, ls_, trans_flags))) { - LOG_WARN("failed to unlock tablet binding", K(ret), K(trans_flags)); - } else { - LOG_INFO("succeeded to abort create tablets", K(ret), K(PRINT_CREATE_ARG(arg)), K(trans_flags)); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::do_abort_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObTabletMapKey key; - key.ls_id_ = ls_.get_ls_id(); - - if (!trans_flags.is_redo_synced()) { - // on redo cb has not been called - // just remove tablets directly - if (OB_FAIL(roll_back_remove_tablets(arg, trans_flags))) { - LOG_WARN("failed to remove tablets", K(ret), K(trans_flags), K(PRINT_CREATE_ARG(arg))); - } - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - const ObTabletID &tablet_id = info.tablet_ids_.at(j); - key.tablet_id_ = tablet_id; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_SUCCESS; - LOG_INFO("tablet does not exist, maybe already deleted", K(ret), K(key)); - } else { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } else if (OB_FAIL(do_abort_create_tablet(tablet_handle, trans_flags))) { - LOG_WARN("failed to do abort create tablet", K(ret), K(tablet_handle), K(trans_flags)); - } - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::do_tx_end_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - // modify tablet status_info - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - bool skip = false; - const ObTabletID &tablet_id = info.tablet_ids_.at(j); - if (trans_flags.for_replay_ - && OB_FAIL(ObTabletBindingHelper::check_skip_tx_end(tablet_id, ls_, trans_flags, skip))) { - LOG_WARN("fail to check_skip_tx_end_create", K(ret), K(arg)); - } else if (skip) { - LOG_INFO("skip tx_end for replay_create", K(tablet_id), K(trans_flags)); - } else if (OB_FAIL(prepare_data_for_tablet_status(tablet_id, ls_, trans_flags))) { - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_SUCCESS; - LOG_INFO("tablet does not exist, maybe fail to create", K(ret), K(tablet_id)); - } else { - LOG_WARN("fail to prepare_data", K(ret), K(tablet_id)); - } - } - } - } - - // modify data_tablet status_info and binding_info - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); i++) { - const ObCreateTabletInfo &info = arg.tablets_[i]; - bool need_modify = false; - if (is_pure_hidden_tablets(info)) { - need_modify = true; - } else if (is_pure_aux_tablets(info) || is_mixed_tablets(info)) { - if (ObTabletBindingHelper::has_lob_tablets(arg, info)) { - need_modify = true; - } - } - - if (OB_SUCC(ret) && need_modify) { - bool skip = false; - if (trans_flags.for_replay_ - && OB_FAIL(ObTabletBindingHelper::check_skip_tx_end(info.data_tablet_id_, ls_, trans_flags, skip))) { - LOG_WARN("fail to check_skip_tx_end_create", K(ret), K(arg)); - } else if (skip) { - LOG_INFO("skip tx_end for replay_create", K(info.data_tablet_id_), K(trans_flags)); - } else if (OB_FAIL(prepare_data_for_tablet_status(info.data_tablet_id_, ls_, trans_flags))) { - LOG_WARN("failed to prepare_data_for_tablet_status", K(ret)); - } else if (OB_FAIL(prepare_data_for_binding_info(info.data_tablet_id_, ls_, trans_flags))) { - LOG_WARN("failed to prepare_data_for_binding_info", K(ret)); - } - } - } - return ret; -} - -int ObTabletCreateDeleteHelper::tx_end_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const uint64_t tenant_id = MTL_ID(); - const ObLSID &ls_id = ls_.get_ls_id(); - - if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(arg)); - } else if (OB_UNLIKELY(arg.id_ != ls_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected arg", K(ret), K(PRINT_CREATE_ARG(arg))); - } else { - bool is_valid = true; - ObSArray tablet_create_info_array; - if (OB_FAIL(do_tx_end_create_tablets(arg, trans_flags))) { - LOG_WARN("failed to prepare data", K(ret)); - } else if (OB_FAIL(build_tablet_create_info(arg, tablet_create_info_array))) { - LOG_WARN("failed to build tablet create info", K(ret), K(arg)); - } else { - print_multi_data_for_create_tablet(tablet_create_info_array); - LOG_INFO("succeeded to tx_end_create_tablets", K(ret), K(arg), K(trans_flags)); - } - } - return ret; -} - -int ObTabletCreateDeleteHelper::roll_back_remove_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - const ObLSID &ls_id = ls_.get_ls_id(); - - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - const ObTabletID &tablet_id = info.tablet_ids_.at(j); - if (OB_FAIL(roll_back_remove_tablet(ls_id, tablet_id, trans_flags))) { - LOG_WARN("failed to remove tablet for abort create", K(ret), K(ls_id), K(tablet_id), K(trans_flags)); - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::roll_back_remove_tablet( - const ObLSID &ls_id, - const ObTabletID &tablet_id, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - const ObTabletMapKey key(ls_id, tablet_id); - ObTabletHandle tablet_handle; - - // Try figure out if tablet needs to dec memtable ref or not - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret || OB_ITEM_NOT_SETTED == ret) { - // tablet does not exist or tablet creation failed on half way, do nothing - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret), K(ls_id), K(tablet_id)); - } - } else { - ObTablet *tablet = tablet_handle.get_obj(); - ObTabletMemtableMgr *memtable_mgr = static_cast(tablet->get_memtable_mgr()); - ObSEArray memtable_handle_array; - bool need_dec = false; - if (OB_FAIL(memtable_mgr->get_all_memtables(memtable_handle_array))) { - LOG_WARN("failed to get all memtables", K(ret), K(ls_id), K(tablet_id)); - } else if (memtable_handle_array.empty()) { - // tablet does not have memtable, do nothing - } else { - const int64_t cnt = memtable_handle_array.count(); - ObTableHandleV2 &last_table_handle = memtable_handle_array.at(cnt - 1); - ObMemtable *last_memtable = nullptr; - ObTabletTxMultiSourceDataUnit tx_data; - - if (OB_FAIL(last_table_handle.get_data_memtable(last_memtable))) { - LOG_WARN("failed to get memtable", K(ret), K(ls_id), K(tablet_id), K(cnt)); - } else if (OB_ISNULL(last_memtable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("last memtable is null", K(ret), K(ls_id), K(tablet_id), K(cnt)); - } else if (!last_memtable->has_multi_source_data_unit(MultiSourceDataUnitType::TABLET_TX_DATA)) { - LOG_INFO("last memtable does not have msd, do nothing", K(ret), K(ls_id), K(tablet_id), K(cnt)); - } else if (OB_FAIL(tablet->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(ls_id), K(tablet_id), K(cnt)); - } else if (OB_FAIL(ObTabletBindingHelper::check_need_dec_cnt_for_abort(tx_data, need_dec))) { - LOG_WARN("failed to save tx data", K(ret), K(tx_data), K(trans_flags)); - } else if (need_dec && OB_FAIL(tablet->set_multi_data_for_commit(tx_data, ObScnRange::MAX_SCN, - trans_flags.for_replay_, MemtableRefOp::DEC_REF))) { - LOG_WARN("failed to save msd", K(ret), K(ls_id), K(tablet_id), K(cnt)); - } else { - LOG_INFO("succeeded to dec ref for memtable in roll back operation", K(ret), K(ls_id), K(tablet_id), K(cnt)); - } - } - } - - // Whatever, delete tablet object from map and id set - // del_tablet and erase should swallow any not exist error - if (OB_SUCC(ret)) { - if (OB_FAIL(t3m->del_tablet(key))) { - LOG_WARN("failed to delete tablet from t3m", K(ret), K(key)); - } else if (OB_FAIL(tablet_id_set_.erase(tablet_id))) { - if (OB_HASH_NOT_EXIST == ret) { - // tablet id does not exist in hash set - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to erase tablet id from hash set", K(ret), K(tablet_id)); - } - } - } - return ret; -} - -int ObTabletCreateDeleteHelper::do_abort_create_tablet( - ObTabletHandle &tablet_handle, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - const ObTabletID &tablet_id = tablet_handle.get_obj()->get_tablet_meta().tablet_id_; - const ObTabletMapKey key(ls_.get_ls_id(), tablet_id); - ObTabletTxMultiSourceDataUnit tx_data; - - if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(tablet_handle)); - } else if (trans_flags.for_replay_ && trans_flags.scn_ <= tx_data.tx_scn_) { - // replaying procedure, clog ts is smaller than tx log ts, just skip - LOG_INFO("skip abort create tablet", K(ret), K(tablet_id), K(trans_flags), K(tx_data)); - } else if (OB_UNLIKELY(!trans_flags.for_replay_ - && trans_flags.scn_.is_valid() - && tx_data.tx_scn_ != SCN::max_scn() - && trans_flags.scn_ <= tx_data.tx_scn_)) { - // If tx log ts equals SCN::max_scn(), it means redo callback has not been called. - // Thus, we should handle this situation - ret = OB_ERR_UNEXPECTED; - LOG_WARN("log ts is no bigger than tx log ts", K(ret), K(tablet_id), K(trans_flags), K(tx_data)); - } else if (OB_UNLIKELY(trans_flags.tx_id_ != tx_data.tx_id_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tx id does not equal", K(ret), K(tablet_id), K(trans_flags), K(tx_data)); - tablet_handle.get_obj()->print_memtables_for_table(); - } else if (OB_UNLIKELY(ObTabletStatus::CREATING != tx_data.tablet_status_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet status is not CREATING", K(ret), K(tablet_id), K(trans_flags), K(tx_data)); - } else { - share::SCN tx_scn; - share::SCN memtable_scn; - if (trans_flags.scn_.is_valid()) { - tx_scn = trans_flags.scn_; - memtable_scn = trans_flags.scn_; - } else { - // trans flags scn is invalid, maybe tx is force killed - tx_scn = tx_data.tx_scn_; - memtable_scn = tx_data.tx_scn_; - } - - if (OB_FAIL(set_tablet_final_status(tablet_handle, ObTabletStatus::DELETED, - tx_scn, memtable_scn, trans_flags.for_replay_))) { - LOG_WARN("failed to set tablet status to DELETED", K(ret), K(key), K(tablet_handle), K(trans_flags), K(tx_scn), K(memtable_scn)); - } else if (OB_FAIL(t3m->erase_pinned_tablet(key))) { - LOG_ERROR("failed to erase tablet handle", K(ret), K(key)); - ob_usleep(1000 * 1000); - ob_abort(); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::prepare_remove_tablets( - const ObBatchRemoveTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = ls_.get_ls_id(); - bool normal = true; - ObSArray tablet_id_array; - const int64_t tablet_cnt = arg.tablet_ids_.count(); - - if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(arg)); - } else if (OB_UNLIKELY(arg.id_ != ls_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected arg", K(ret), K(arg), K(ls_id)); - } else if (!trans_flags.for_replay_ - && OB_FAIL(check_tablet_status(arg, normal))) { - LOG_WARN("failed to check tablet status", K(ret), K(arg)); - } else if (OB_UNLIKELY(!normal)) { - ret = OB_EAGAIN; - LOG_WARN("some tablet is not normal", K(ret), K(arg)); - } else if (trans_flags.for_replay_) { - if (OB_FAIL(tablet_id_array.reserve(tablet_cnt))) { - LOG_WARN("fail to allocate memory for tablet_id_array", K(ret), K(tablet_cnt)); - } else if (OB_FAIL(replay_verify_tablets(arg, trans_flags.scn_, tablet_id_array))) { - LOG_WARN("failed to replay verify tablets", K(ret), K(trans_flags)); - } - } - - if (OB_SUCC(ret)) { - const ObIArray *tablet_ids = trans_flags.for_replay_ ? &tablet_id_array : &arg.tablet_ids_; - ObTabletHandle tablet_handle; - ObTabletTxMultiSourceDataUnit cur_tx_data; - ObTabletMapKey key; - key.ls_id_ = ls_id; - - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids->count(); ++i) { - key.tablet_id_ = tablet_ids->at(i); - if (OB_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } else if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(cur_tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(key)); - } else { - SCN flag_scn = trans_flags.scn_; - ObTabletTxMultiSourceDataUnit tx_data; - tx_data.tx_id_ = trans_flags.tx_id_; - tx_data.tx_scn_ = trans_flags.for_replay_ ? flag_scn: cur_tx_data.tx_scn_; - tx_data.tablet_status_ = ObTabletStatus::DELETING; - - if (OB_FAIL(ObTabletBindingHelper::lock_and_set_tx_data(tablet_handle, tx_data, trans_flags.for_replay_))) { - LOG_WARN("failed to lock tablet binding", K(ret), K(key), K(tx_data)); - } - } - } - } - - if (OB_FAIL(ret) && !trans_flags.for_replay_) { - int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(abort_remove_tablets(arg, trans_flags))) { - LOG_WARN("failed to rollback prepare_remove", K(tmp_ret), K(trans_flags)); - } else if (OB_ALLOCATE_MEMORY_FAILED == ret) { - ret = OB_EAGAIN; - LOG_WARN("failed due to 4013, has rolled back operations", K(ret), K(trans_flags), K(arg)); - } - } - - if (OB_SUCC(ret)) { - LOG_INFO("succeeded to prepare remove tablets", K(ret), K(arg), K(trans_flags)); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::replay_verify_tablets( - const ObBatchRemoveTabletArg &arg, - const SCN &scn, - ObIArray &tablet_id_array) -{ - int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_ids_.count(); ++i) { - const ObTabletID &tablet_id = arg.tablet_ids_[i]; - if (OB_FAIL(ls_.replay_get_tablet(tablet_id, scn, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - LOG_INFO("tablet already deleted", K(ret), K(tablet_id), K(scn)); - ret = OB_SUCCESS; // tablet already deleted, won't regard it as error - } else if (OB_EAGAIN == ret) { - // retry again - } else { - LOG_WARN("failed to replay get tablet", K(ret), K(tablet_id), K(scn)); - } - } else { - ObTabletTxMultiSourceDataUnit tx_data; - if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(tablet_handle)); - } else if (scn <= tx_data.tx_scn_) { - FLOG_INFO("clog ts is no bigger than tx log ts in tx data, should skip this clog", - K(tablet_id), K(scn), K(tx_data)); - } else if (OB_FAIL(tablet_id_array.push_back(tablet_id))) { - LOG_WARN("failed to push back into tablet id array", K(ret), K(tablet_id)); - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::redo_remove_tablets( - const ObBatchRemoveTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = ls_.get_ls_id(); - const bool is_clog_replaying = trans_flags.for_replay_; - const SCN scn = trans_flags.scn_; - - if (OB_UNLIKELY(!arg.is_valid() || !scn.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(arg)); - } else if (OB_UNLIKELY(arg.id_ != ls_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected arg", K(ret), K(arg), K(ls_id)); - } else if (trans_flags.for_replay_) { - LOG_INFO("in clog replaying procedure, do nothing while redo log callback", K(ret), K(trans_flags)); - } else { - ObTabletHandle tablet_handle; - ObTabletTxMultiSourceDataUnit tx_data; - ObTabletMapKey key; - key.ls_id_ = ls_id; - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_ids_.count(); ++i) { - key.tablet_id_ = arg.tablet_ids_.at(i); - if (OB_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } else if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(tablet_handle)); - } else if (OB_FAIL(tablet_handle.get_obj()->set_tx_scn(tx_data.tx_id_, scn, false/*for_replay*/))) { - LOG_WARN("failed to set tx data", K(ret), K(tablet_handle), K(tx_data), K(scn)); - } - } - } - - if (OB_SUCC(ret)) { - LOG_INFO("succeeded to redo remove tablets", K(ret), K(arg), K(trans_flags)); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::commit_remove_tablets( - const ObBatchRemoveTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = ls_.get_ls_id(); - - if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(arg)); - } else if (OB_UNLIKELY(arg.id_ != ls_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected arg", K(ret), K(arg), K(ls_id)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_ids_.count(); ++i) { - const ObTabletID &tablet_id = arg.tablet_ids_.at(i); - if (OB_FAIL(do_commit_remove_tablet(tablet_id, trans_flags))) { - LOG_WARN("failed to do commit remove tablet", K(ret), K(ls_id), K(tablet_id), K(trans_flags)); - } - } - } - - if (OB_SUCC(ret)) { - LOG_INFO("succeeded to commit remove tablets", K(ret), K(arg), K(trans_flags)); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::do_commit_remove_tablet( - const common::ObTabletID &tablet_id, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - const share::ObLSID &ls_id = ls_.get_ls_id(); - const ObTabletMapKey key(ls_id, tablet_id); - ObTabletHandle tablet_handle; - ObTabletTxMultiSourceDataUnit tx_data; - bool should_skip = false; - - if (trans_flags.for_replay_) { - const share::SCN &scn = trans_flags.scn_; - if (OB_FAIL(ls_.replay_get_tablet(tablet_id, scn, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - LOG_INFO("tablet already deleted", K(ret), K(ls_id), K(tablet_id), K(scn)); - ret = OB_SUCCESS; // tablet already deleted, won't regard it as error - should_skip = true; - } else if (OB_EAGAIN == ret) { - // retry again - } else { - LOG_WARN("failed to replay get tablet", K(ret), K(ls_id), K(tablet_id), K(scn)); - } - } - } else { - if (OB_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } - - if (OB_FAIL(ret)) { - } else if (should_skip) { - } else if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(key)); - } else if (OB_UNLIKELY(!trans_flags.for_replay_ && trans_flags.scn_ <= tx_data.tx_scn_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("log ts is smaller than tx log ts", K(ret), K(key), K(trans_flags), K(tx_data)); - } else if (OB_UNLIKELY(trans_flags.tx_id_ != tx_data.tx_id_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tx id does not equal", K(ret), K(key), K(trans_flags), K(tx_data)); - tablet_handle.get_obj()->print_memtables_for_table(); - } else if (OB_UNLIKELY(ObTabletStatus::DELETING != tx_data.tablet_status_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet status is not DELETING", K(ret), K(key), K(trans_flags), K(tx_data)); - } else { - if (OB_FAIL(set_tablet_final_status(tablet_handle, ObTabletStatus::DELETED, - trans_flags.scn_, trans_flags.scn_, trans_flags.for_replay_))) { - LOG_WARN("failed to set tablet status to DELETED", K(ret), K(tablet_handle), - K(trans_flags.scn_), K(trans_flags)); - } else if (OB_FAIL(t3m->erase_pinned_tablet(key))) { - LOG_ERROR("failed to erase tablet handle", K(ret), K(key)); - ob_usleep(1000 * 1000); - ob_abort(); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::abort_remove_tablets( - const ObBatchRemoveTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = ls_.get_ls_id(); - - if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(arg)); - } else if (OB_UNLIKELY(arg.id_ != ls_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected arg", K(ret), K(arg), K(ls_id)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_ids_.count(); ++i) { - const ObTabletID &tablet_id = arg.tablet_ids_.at(i); - if (OB_FAIL(do_abort_remove_tablet(tablet_id, trans_flags))) { - LOG_WARN("failed to do abort remove tablet", K(ret), K(ls_id), K(tablet_id), K(trans_flags)); - } - } - } - - if (OB_SUCC(ret)) { - LOG_INFO("succeeded to abort remove tablets", K(ret), K(trans_flags)); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::do_abort_remove_tablet( - const ObTabletID &tablet_id, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - const share::ObLSID &ls_id = ls_.get_ls_id(); - const ObTabletMapKey key(ls_id, tablet_id); - ObTabletHandle tablet_handle; - ObTabletTxMultiSourceDataUnit tx_data; - MemtableRefOp ref_op = MemtableRefOp::NONE; - bool is_valid = true; - bool should_skip = false; - SCN tx_scn; - - if (trans_flags.for_replay_) { - const share::SCN &scn = trans_flags.scn_; - if (OB_FAIL(ls_.replay_get_tablet(tablet_id, scn, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - LOG_INFO("tablet already deleted", K(ret), K(ls_id), K(tablet_id), K(scn)); - ret = OB_SUCCESS; // tablet already deleted, won't regard it as error - should_skip = true; - } else if (OB_EAGAIN == ret) { - // retry again - } else { - LOG_WARN("failed to replay get tablet", K(ret), K(ls_id), K(tablet_id), K(scn)); - } - } - } else { - if (OB_FAIL(get_tablet(key, tablet_handle))) { - // leader handle 4013 error(caused by memory not enough in load and dump procedure) - if (OB_ALLOCATE_MEMORY_FAILED == ret) { - ObTabletTxMultiSourceDataUnit tx_data; - int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(t3m->get_tablet_pointer_tx_data(key, tx_data))) { - LOG_WARN("failed to get tablet status", K(tmp_ret), K(key)); - } else if (ObTabletStatus::NORMAL == tx_data.tablet_status_) { - ret = OB_SUCCESS; - is_valid = false; - LOG_INFO("tablet status is NORMAL, no need to handle", K(ret), K(key)); - } else { - LOG_WARN("tablet status is NOT NORMAL", K(ret), K(key), K(tx_data)); - } - } else { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } - } - - if (OB_FAIL(ret)) { - } else if (should_skip) { - } else if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(key)); - } else if (OB_UNLIKELY(!trans_flags.for_replay_ - && trans_flags.scn_ != SCN::invalid_scn() - && trans_flags.scn_ <= tx_data.tx_scn_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("log ts is no bigger than tx log ts", K(ret), K(key), K(trans_flags), K(tx_data)); - } else if (OB_UNLIKELY(trans_flags.tx_id_ != tx_data.tx_id_)) { - is_valid = false; - LOG_INFO("tx id does not equal", K(ret), K(key), K(trans_flags), K(tx_data)); - tablet_handle.get_obj()->print_memtables_for_table(); - } else if (OB_UNLIKELY(ObTabletStatus::DELETING != tx_data.tablet_status_)) { - is_valid = false; - LOG_INFO("tablet status is not DELETING", K(ret), K(key), K(trans_flags), K(tx_data)); - } else { - bool need_dec = false; - if (OB_FAIL(ObTabletBindingHelper::check_need_dec_cnt_for_abort(tx_data, need_dec))) { - LOG_WARN("failed to save tx data", K(ret), K(tx_data), K(trans_flags)); - } else if (need_dec) { - ref_op = MemtableRefOp::DEC_REF; - } - } - - if (OB_FAIL(ret)) { - } else if (should_skip) { - } else if (!is_valid) { - if (trans_flags.for_replay_) { - // if tablet is NORMAL, and meets abort remove procedure when replaying, we should not consider it illegal - if (ObTabletStatus::NORMAL == tx_data.tablet_status_ && ObTabletCommon::FINAL_TX_ID == tx_data.tx_id_) { - LOG_INFO("tablet is in NORMAL status, do nothing", K(ret), K(key), K(trans_flags)); - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet is not valid, and not in NORMAL status", K(ret), K(key), K(trans_flags)); - } - } else { - // For leader, we may encounter such disorder: - // 1) redo create - // 2) prepare remove - // 3) commit create - // 4) abort remove - // This is because upper layer may do 'prepare action' before lower layer actually do 'commit create' callback, - // thus 'commit create' callback may be delayed. - // So we should NOT consider such scene as error if tx id or tablet status is not what we expected. - LOG_INFO("tablet is no valid but do nothing", K(ret), K(key), K(trans_flags)); - } - } else { - if (trans_flags.for_replay_) { - tx_scn = trans_flags.scn_; - } else if (trans_flags.is_redo_synced()) { - tx_scn = trans_flags.scn_; - } else { - tx_scn = tx_data.tx_scn_; - } - - const SCN &memtable_scn = (SCN::invalid_scn() == trans_flags.scn_) ? SCN::max_scn() : trans_flags.scn_; - - if (OB_FAIL(set_tablet_final_status(tablet_handle, ObTabletStatus::NORMAL, - tx_scn, memtable_scn, trans_flags.for_replay_, ref_op))) { - LOG_WARN("failed to set tablet status to NORMAL", K(ret), K(tablet_handle), - K(tx_scn), K(memtable_scn), K(trans_flags), K(ref_op)); - } else if (OB_FAIL(t3m->erase_pinned_tablet(key))) { - LOG_ERROR("failed to erase tablet handle", K(ret), K(key)); - ob_usleep(1000 * 1000); - ob_abort(); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::do_tx_end_remove_tablets( - - const ObBatchRemoveTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_ids_.count(); ++i) { - const ObTabletID &tablet_id = arg.tablet_ids_.at(i); - bool skip = false; - if (trans_flags.for_replay_ - && OB_FAIL(ObTabletBindingHelper::check_skip_tx_end(tablet_id, ls_, trans_flags, skip))) { - LOG_WARN("fail to check_skip_tx_end_remove", K(ret), K(arg)); - } else if (skip) { - LOG_INFO("skip tx_end for replay_remove", K(tablet_id), K(trans_flags)); - } - // modify tablet status_info - else if (OB_FAIL(prepare_data_for_tablet_status(tablet_id, ls_, trans_flags))) { - LOG_WARN("failed to prepare_data_for_tablet_status", KR(ret), K(tablet_id)); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::tx_end_remove_tablets( - const ObBatchRemoveTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const uint64_t tenant_id = MTL_ID(); - const ObLSID &ls_id = ls_.get_ls_id(); - - if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(arg)); - } else if (OB_UNLIKELY(arg.id_ != ls_id)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected arg", K(ret), K(arg), K(ls_id), K(tenant_id)); - } else if (OB_FAIL(do_tx_end_remove_tablets(arg, trans_flags))) { - LOG_WARN("failed to do_tx_end", K(ret)); - } else { - print_multi_data_for_remove_tablet(arg); - } - - return ret; -} - int ObTabletCreateDeleteHelper::get_tablet( const ObTabletMapKey &key, ObTabletHandle &handle, @@ -1401,12 +60,11 @@ int ObTabletCreateDeleteHelper::get_tablet( int ret = OB_SUCCESS; static const int64_t SLEEP_TIME_US = 10; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - ObTabletHandle tablet_handle; const int64_t begin_time = ObClockGenerator::getClock(); int64_t current_time = 0; while (OB_SUCC(ret)) { - ret = t3m->get_tablet(WashTabletPriority::WTP_HIGH, key, tablet_handle); + ret = t3m->get_tablet(WashTabletPriority::WTP_HIGH, key, handle); if (OB_SUCC(ret)) { break; } else if (OB_ENTRY_NOT_EXIST == ret) { @@ -1416,7 +74,8 @@ int ObTabletCreateDeleteHelper::get_tablet( 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)); + LOG_WARN("continuously meet item not set error", K(ret), K(key), + K(begin_time), K(current_time), K(timeout_us)); } else { ret = OB_SUCCESS; ob_usleep(SLEEP_TIME_US); @@ -1425,491 +84,351 @@ int ObTabletCreateDeleteHelper::get_tablet( LOG_WARN("failed to get tablet", K(ret), K(key)); } } - - if (OB_SUCC(ret)) { - handle = tablet_handle; - } - return ret; } int ObTabletCreateDeleteHelper::check_and_get_tablet( const ObTabletMapKey &key, ObTabletHandle &handle, - const int64_t timeout_us) + const int64_t timeout_us, + const ObMDSGetTabletMode mode, + const int64_t snapshot_version) { int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObTabletStatus::Status tablet_status = ObTabletStatus::MAX; + ObTablet *tablet = nullptr; - // TODO(bowen.gbw): optimize this logic, refactor ObTabletStatusChecker - if (OB_FAIL(get_tablet(key, tablet_handle, timeout_us))) { + if (OB_FAIL(get_tablet(key, handle, timeout_us))) { if (OB_TABLET_NOT_EXIST == ret) { - LOG_DEBUG("tablet does not exist", K(ret), K(key), K(timeout_us)); + LOG_DEBUG("tablet does not exist", K(ret), K(key), K(mode)); } else { - LOG_WARN("failed to get tablet", K(ret), K(key), K(timeout_us)); + LOG_WARN("failed to get tablet", K(ret), K(key), K(mode)); } - } else if (tablet_handle.get_obj()->is_ls_inner_tablet()) { + } else if (OB_ISNULL(tablet = handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(handle)); + } else if (tablet->is_ls_inner_tablet()) { // no need to check ls inner tablet, do nothing - } else if (ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US == timeout_us) { + } else if (ObMDSGetTabletMode::READ_WITHOUT_CHECK == mode) { // no checking - } else if (OB_FAIL(tablet_handle.get_obj()->get_tablet_status(tablet_status))) { - LOG_WARN("failed to get tablet status", K(ret)); - } else if (ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US == timeout_us) { - if (ObTabletStatus::NORMAL != tablet_status) { - ret = OB_TABLET_NOT_EXIST; + } else if (ObMDSGetTabletMode::READ_ALL_COMMITED == mode) { + if (OB_UNLIKELY(snapshot_version != ObTransVersion::MAX_TRANS_VERSION)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("read all committed mode should only pass max scn", K(ret), K(key), K(mode), K(snapshot_version)); + } else if (OB_FAIL(tablet->check_tablet_status_for_read_all_committed())) { + LOG_WARN("failed to check tablet status", K(ret), K(key)); + } + } else if (ObMDSGetTabletMode::READ_READABLE_COMMITED == mode) { + if (OB_FAIL(tablet->check_new_mds_with_cache(snapshot_version, timeout_us))) { + LOG_WARN("failed to check status for new mds", K(ret), K(mode), K(snapshot_version), K(timeout_us)); } } else { - if (ObTabletStatus::NORMAL == tablet_status) { - } else if (ObTabletStatus::DELETED == tablet_status) { - ret = OB_TABLET_NOT_EXIST; - } else { - // check status - ObTabletStatusChecker checker(*tablet_handle.get_obj()); - if (OB_FAIL(checker.check(timeout_us))) { - LOG_WARN("failed to check tablet status", K(ret), K(timeout_us), K(tablet_handle)); - } + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected mode", K(ret), K(key), K(mode)); + } + return ret; +} + +int ObTabletCreateDeleteHelper::check_status_for_new_mds( + ObTablet &tablet, + const int64_t snapshot_version, + const int64_t timeout_us, + ObTabletStatusCache &tablet_status_cache) +{ + int ret = OB_SUCCESS; + const ObLSID &ls_id = tablet.get_tablet_meta().ls_id_; + const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; + share::SCN snapshot; + ObTabletCreateDeleteMdsUserData user_data; + ObTabletStatus tablet_status(ObTabletStatus::MAX); + bool is_committed = false; + + auto func = [&user_data](const ObTabletCreateDeleteMdsUserData &data) -> int { + int ret = OB_SUCCESS; + if (OB_FAIL(user_data.assign(data))) { + LOG_WARN("failed to copy", K(ret)); } + return ret; + }; + + // get latest, then check transfer scn + // if read snapshot > transfer scn: + // if tx is not committed, we will return OB_SCHEMA_EAGAIN and let upper layer retry + // if tx is committed, tablet is deleted for sure and we will return OB_TABLET_NOT_EXIST + if (OB_FAIL(tablet.get_latest(func, is_committed, 0/*read_seq*/))) { + if (OB_EMPTY_RESULT == ret) { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("tablet creation has not been committed, or has been roll backed", K(ret), K(ls_id), K(tablet_id)); + } else { + LOG_WARN("failed to get snapshot", KR(ret), K(ls_id), K(tablet_id)); + } + } else if (FALSE_IT(tablet_status = user_data.tablet_status_)) { + } else if (OB_FAIL(snapshot.convert_for_tx(snapshot_version))) { + LOG_WARN("failed to convert snapshot", K(ret), K(snapshot_version)); + } else if (ObTabletStatus::TRANSFER_OUT == tablet_status + && OB_FAIL(check_read_snapshot_by_transfer_scn(user_data.transfer_scn_, is_committed, snapshot))) { + LOG_WARN("failed to check read snapshot by transfer scn", K(ret), K(ls_id), K(tablet_id), K(user_data), K(is_committed), K(snapshot)); + } else if (OB_FAIL(tablet.get_snapshot( + func, + snapshot, + 0/*read_seq*/, + timeout_us))) { + if (OB_EMPTY_RESULT == ret) { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("tablet creation has not been committed, or has been roll backed", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_ERR_SHARED_LOCK_CONFLICT == ret) { + LOG_WARN("tablet transaction is in commit progress", K(ret), K(ls_id), K(tablet_id), K(snapshot), K(timeout_us)); + } else { + LOG_WARN("failed to get snapshot", KR(ret), K(ls_id), K(tablet_id), K(snapshot), K(timeout_us)); + } + } else if (OB_FAIL(check_read_snapshot_by_commit_version(tablet, + user_data.create_commit_version_, + user_data.delete_commit_version_, + snapshot_version, + user_data.tablet_status_))) { + LOG_WARN("failed to check read snapshot by commit version", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(user_data)); } - if (OB_SUCC(ret)) { - handle = tablet_handle; + if (OB_SUCC(ret) && ObTabletStatus::TRANSFER_OUT != tablet_status && user_data.is_valid()) { + tablet_status_cache.set_value(user_data); } return ret; } -int ObTabletCreateDeleteHelper::acquire_tablet( +int ObTabletCreateDeleteHelper::check_read_snapshot_by_transfer_scn( + const share::SCN &transfer_scn, + const bool is_committed, + const share::SCN &snapshot) +{ + int ret = OB_SUCCESS; + + if (!is_committed) { + if (snapshot > transfer_scn) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("read snapshot is bigger than transfer scn, should retry", K(ret), K(snapshot), K(transfer_scn)); + } + } else if (is_committed) { + if (snapshot > transfer_scn) { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("read snapshot is bigger than transfer scn after transfer out committed, should retry on target ls", + K(ret), K(snapshot), K(transfer_scn)); + } + } + + return ret; +} + +int ObTabletCreateDeleteHelper::check_read_snapshot_by_commit_version( + ObTablet &tablet, + const int64_t create_commit_version, + const int64_t delete_commit_version, + const int64_t snapshot_version, + const ObTabletStatus &tablet_status) +{ + int ret = OB_SUCCESS; + const ObLSID &ls_id = tablet.get_tablet_meta().ls_id_; + const ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; + + ObTabletStatus infered_tablet_status = tablet_status; + if (snapshot_version == ObTransVersion::MAX_TRANS_VERSION) { + // do nothing + } else if (OB_UNLIKELY(create_commit_version == ObTransVersion::INVALID_TRANS_VERSION)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("create tablet trans version is invalid", + K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(create_commit_version)); + } else if (snapshot_version < create_commit_version) { + // read snapshot is smaller than create tablet trans version, + // no previous committed transaction + infered_tablet_status = ObTabletStatus::MAX; + LOG_INFO("tablet status is set to MAX because read snapshot is smaller than create trans version", + K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(create_commit_version)); + } else if (delete_commit_version == ObTransVersion::INVALID_TRANS_VERSION) { + // delete commit version is not valid, no delete transaction committed + } else if (snapshot_version < delete_commit_version) { + // read snapshot is smaller than delete tablet trans version, + // previous transaction is create tablet/transfer in create tablet, so tablet status is NORMAL + infered_tablet_status = ObTabletStatus::NORMAL; + LOG_INFO("tablet status is set to NORMAL because read snapshot is smaller than delete trans version", + K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(delete_commit_version)); + } else { + // snapshot_version >= user_data.delete_commit_version_ + // do nothing + } + + if (OB_FAIL(ret)) { + } else if (ObTabletStatus::NORMAL == infered_tablet_status || ObTabletStatus::TRANSFER_IN == infered_tablet_status) { + if (OB_UNLIKELY(tablet.is_empty_shell())) { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("tablet is empty shell", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(create_commit_version)); + } + } else if (ObTabletStatus::MAX == infered_tablet_status) { + ret = OB_SNAPSHOT_DISCARDED; + LOG_WARN("no valid tablet status can be read", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(create_commit_version)); + } else { + ret = OB_TABLET_NOT_EXIST; + } + + return ret; +} + +int ObTabletCreateDeleteHelper::create_tmp_tablet( const ObTabletMapKey &key, - ObTabletHandle &handle, - const bool only_acquire) + common::ObArenaAllocator &allocator, + ObTabletHandle &handle) { int ret = OB_SUCCESS; ObLSHandle ls_handle; - ObTabletHandle tablet_handle; ObLSService *ls_service = MTL(ObLSService*); ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - if (OB_UNLIKELY(!key.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), K(key)); } else if (OB_FAIL(ls_service->get_ls(key.ls_id_, ls_handle, ObLSGetMod::TABLET_MOD))) { - LOG_WARN("failed to get ls", K(ret), "ls_id", key.ls_id_); - } else if (OB_FAIL(t3m->acquire_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, tablet_handle, only_acquire))) { - LOG_WARN("failed to acquire tablet", K(ret), K(key)); - } else if (OB_ISNULL(tablet_handle.get_obj())) { + LOG_WARN("fail to get ls", K(ret), "ls_id", key.ls_id_); + } else if (OB_FAIL(t3m->create_tmp_tablet(WashTabletPriority::WTP_HIGH, key, allocator, ls_handle, handle))) { + LOG_WARN("fail to create temporary tablet", K(ret), K(key)); + } else if (OB_ISNULL(handle.get_obj())) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("new tablet is null", K(ret), K(tablet_handle)); - } else { - handle = tablet_handle; + LOG_ERROR("new tablet is null", K(ret), K(handle)); } + return ret; +} +int ObTabletCreateDeleteHelper::prepare_create_msd_tablet() +{ + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + if (OB_FAIL(t3m->get_mstx_tablet_creator().throttle_tablet_creation())) { + LOG_WARN("fail to prepare full tablet", K(ret)); + } + return ret; +} + +int ObTabletCreateDeleteHelper::push_msd_tablet_to_queue(ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + if (OB_FAIL(t3m->get_mstx_tablet_creator().push_tablet_to_queue(handle))) { + LOG_WARN("fail to push full tablet to queue", K(ret)); + } + return ret; +} + +int ObTabletCreateDeleteHelper::create_msd_tablet( + const ObTabletMapKey &key, + ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLSService *ls_service = MTL(ObLSService*); + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(key)); + } else if (OB_FAIL(ls_service->get_ls(key.ls_id_, ls_handle, ObLSGetMod::TABLET_MOD))) { + LOG_WARN("fail to get ls", K(ret), "ls_id", key.ls_id_); + } else if (OB_FAIL(t3m->create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, handle))) { + LOG_WARN("fail to create multi source data tablet", K(ret), K(key)); + } else if (OB_ISNULL(handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("new tablet is null", K(ret), K(handle)); + } + return ret; +} + +int ObTabletCreateDeleteHelper::acquire_msd_tablet( + const ObTabletMapKey &key, + ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(key)); + } else if (OB_FAIL(t3m->acquire_msd_tablet(WashTabletPriority::WTP_HIGH, key, handle))) { + LOG_WARN("fail to acquire multi source data tablet", K(ret), K(key)); + } else if (OB_ISNULL(handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("new tablet is null", K(ret), K(handle)); + } + return ret; +} + +int ObTabletCreateDeleteHelper::acquire_tmp_tablet( + const ObTabletMapKey &key, + common::ObArenaAllocator &allocator, + ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(key)); + } else if (OB_FAIL(t3m->acquire_tmp_tablet(WashTabletPriority::WTP_HIGH, key, allocator, handle))) { + LOG_WARN("fail to acquire temporary tablet", K(ret), K(key)); + } else if (OB_ISNULL(handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("new tablet is null", K(ret), K(handle)); + } + return ret; +} + +int ObTabletCreateDeleteHelper::acquire_tablet_from_pool( + const ObTabletPoolType &type, + const ObTabletMapKey &key, + ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(key)); + } else if (OB_FAIL(t3m->acquire_tablet_from_pool(type, WashTabletPriority::WTP_HIGH, key, handle))) { + LOG_WARN("fail to acquire tablet from pool", K(ret), K(key), K(type)); + } else if (OB_ISNULL(handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("new tablet is null", K(ret), K(handle)); + } + return ret; +} + +int ObTabletCreateDeleteHelper::create_sstable_for_migrate( + const ObTabletCreateSSTableParam ¶m, + common::ObArenaAllocator &allocator, + ObTableHandleV2 &table_handle) +{ + int ret = OB_SUCCESS; + void *buf = allocator.alloc(sizeof(ObSSTable)); + ObSSTable *sstable = nullptr; + if (OB_ISNULL(buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate sstable memory", K(ret)); + } else if (OB_ISNULL(sstable = new (buf) ObSSTable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to new sstable", K(ret)); + } else if (OB_FAIL(create_sstable(param, allocator, *sstable))) { + LOG_WARN("fail to create sstable", K(ret)); + } else if (OB_FAIL(table_handle.set_sstable(sstable, &allocator))) { + LOG_WARN("fail to set table handle", K(ret), KPC(sstable)); + } return ret; } int ObTabletCreateDeleteHelper::create_sstable( const ObTabletCreateSSTableParam ¶m, - ObTableHandleV2 &table_handle) + common::ObArenaAllocator &allocator, + blocksstable::ObSSTable &sstable) { int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); if (OB_UNLIKELY(!param.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(param)); - } else { - ObIAllocator &allocator = t3m->get_tenant_allocator(); - ObTableHandleV2 handle; - ObSSTable *sstable = nullptr; - - if (OB_FAIL(t3m->acquire_sstable(handle))) { - LOG_WARN("failed to acquire sstable", K(ret)); - } else if (OB_ISNULL(sstable = static_cast(handle.get_table()))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get table", K(ret), K(handle)); - } else if (OB_FAIL(sstable->init(param, &allocator))) { - LOG_WARN("failed to init sstable", K(ret), K(param)); - } else { - table_handle = handle; - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::check_create_new_tablets(const obrpc::ObBatchCreateTabletArg &arg) -{ - int ret = OB_SUCCESS; - const uint64_t tenant_id = MTL_ID(); - ObUnitInfoGetter::ObTenantConfig unit; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - int64_t tablet_cnt_per_gb = 20000; // default value - bool skip_check = !arg.need_check_tablet_cnt_; - - // skip hidden tablet creation or truncate tablet creation - for (int64_t i = 0; OB_SUCC(ret) && !skip_check && i < arg.table_schemas_.count(); ++i) { - if (arg.table_schemas_[i].is_user_hidden_table() - || OB_INVALID_VERSION != arg.table_schemas_[i].get_truncate_version()) { - skip_check = true; - } - } - - if (OB_FAIL(ret)) { - } else if (skip_check) { - } else { - { - omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); - if (OB_UNLIKELY(!tenant_config.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("get invalid tenant config", K(ret)); - } else { - tablet_cnt_per_gb = tenant_config->_max_tablet_cnt_per_gb; - } - } - - if (FAILEDx(GCTX.omt_->get_tenant_unit(tenant_id, unit))) { - if (OB_TENANT_NOT_IN_SERVER != ret) { - LOG_WARN("failed to get tenant unit", K(ret), K(tenant_id)); - } else { - // during restart, tenant unit not ready, skip check - ret = OB_SUCCESS; - } - } else { - const double memory_limit = unit.config_.memory_size(); - const int64_t max_tablet_cnt = memory_limit / (1 << 30) * tablet_cnt_per_gb; - const int64_t cur_tablet_cnt = t3m->get_total_tablet_cnt(); - const int64_t inc_tablet_cnt = arg.get_tablet_count(); - - if (OB_UNLIKELY(cur_tablet_cnt + inc_tablet_cnt >= max_tablet_cnt)) { - ret = OB_TOO_MANY_PARTITIONS_ERROR; - LOG_WARN("too many partitions of tenant", K(ret), K(tenant_id), K(memory_limit), K(tablet_cnt_per_gb), - K(max_tablet_cnt), K(cur_tablet_cnt), K(inc_tablet_cnt)); - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::verify_tablets_absence( - const ObBatchCreateTabletArg &arg, - ObIArray &tablet_create_info_array) -{ - int ret = OB_SUCCESS; - bool is_valid = false; - - if (OB_FAIL(check_tablet_absence(arg, is_valid))) { - LOG_WARN("failed to check tablet absence", K(ret), K(PRINT_CREATE_ARG(arg))); - } else if (!is_valid) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, some tablet exists", K(ret)); - } else if (OB_FAIL(build_tablet_create_info(arg, tablet_create_info_array))) { - LOG_WARN("failed to build tablet create info", K(ret)); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::check_tablet_existence( - const ObBatchCreateTabletArg &arg, - bool &is_valid) -{ - // expect all tablets exist - int ret = OB_SUCCESS; - bool exist = true; - ObTabletHandle tablet_handle; - ObTabletMapKey key; - key.ls_id_ = arg.id_; - - for (int64_t i = 0; OB_SUCC(ret) && exist && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - for (int64_t j = 0; OB_SUCC(ret) && exist && j < info.tablet_ids_.count(); ++j) { - key.tablet_id_ = info.tablet_ids_.at(j); - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - exist = false; - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } else { - exist = true; - } - } - } - - if (OB_SUCC(ret)) { - is_valid = exist; - } - - return ret; -} - -int ObTabletCreateDeleteHelper::check_tablet_absence( - const ObBatchCreateTabletArg &arg, - bool &is_valid) -{ - // expect all tablets do not exist, except data tablet when creating pure index/hidden tablets - int ret = OB_SUCCESS; - is_valid = true; - const ObLSID &ls_id = arg.id_; - ObSArray skip_idx; - for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - if (is_contain(skip_idx, i)) { - // do nothing - } else if (is_pure_data_tablets(info) || is_mixed_tablets(info)) { - if (OB_FAIL(check_pure_data_or_mixed_tablets_info(ls_id, info, is_valid))) { - LOG_WARN("failed to check create tablet info", K(ret), K(ls_id), K(info)); - } - } else if (is_pure_aux_tablets(info)) { - if (OB_FAIL(check_pure_index_or_hidden_tablets_info(ls_id, info, is_valid))) { - LOG_WARN("failed to check create tablet info", K(ret), K(ls_id), K(info)); - } - } else if (is_pure_hidden_tablets(info)) { - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - int64_t aux_idx = -1; - if (find_related_aux_info(arg, info.tablet_ids_.at(j), aux_idx)) { - const ObCreateTabletInfo &aux_info = arg.tablets_.at(aux_idx); - if (OB_FAIL(check_pure_data_or_mixed_tablets_info(ls_id, aux_info, is_valid))) { - LOG_WARN("failed to check create tablet info", K(ret), K(ls_id), K(aux_info)); - } else if (OB_FAIL(skip_idx.push_back(aux_idx))) { - LOG_WARN("failed to push back skip idx", K(ret), K(aux_idx)); - } - } - } - if (OB_SUCC(ret) && OB_FAIL(check_pure_index_or_hidden_tablets_info(ls_id, info, is_valid))) { - LOG_WARN("failed to check create tablet info", K(ret), K(ls_id), K(info)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected create tablet info", K(ret), K(info)); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::check_pure_data_or_mixed_tablets_info( - const ObLSID &ls_id, - const ObCreateTabletInfo &info, - bool &is_valid) -{ - int ret = OB_SUCCESS; - bool not_exist = true; - ObTabletHandle tablet_handle; - ObTabletMapKey key; - key.ls_id_ = ls_id; - - for (int64_t i = 0; OB_SUCC(ret) && not_exist && i < info.tablet_ids_.count(); ++i) { - const ObTabletID &tablet_id = info.tablet_ids_[i]; - key.tablet_id_ = tablet_id; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - not_exist = true; - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } else { - not_exist = false; - LOG_INFO("tablet exists", K(ret), K(key)); - } - } - - if (OB_FAIL(ret)) { - } else { - is_valid = not_exist; - } - - return ret; -} - -int ObTabletCreateDeleteHelper::check_pure_index_or_hidden_tablets_info( - const ObLSID &ls_id, - const ObCreateTabletInfo &info, - bool &is_valid) -{ - int ret = OB_SUCCESS; - bool valid = true; - ObTabletHandle tablet_handle; - ObTabletMapKey key; - key.ls_id_ = ls_id; - - for (int64_t i = 0; OB_SUCC(ret) && valid && i < info.tablet_ids_.count(); ++i) { - const ObTabletID &tablet_id = info.tablet_ids_[i]; - key.tablet_id_ = tablet_id; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - valid = true; - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret), K(key)); - } - } else { - valid = false; - LOG_INFO("tablet exists", K(ret), K(key)); - } - } - - if (OB_FAIL(ret)) { - } else { - is_valid = valid; - } - - return ret; -} - -int ObTabletCreateDeleteHelper::build_tablet_create_info( - const ObBatchCreateTabletArg &arg, - ObIArray &tablet_create_info_array) -{ - int ret = OB_SUCCESS; - ObSArray skip_idx; - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - ObTabletCreateInfo tablet_create_info; - bool need_push = false; - if (is_contain(skip_idx, i)) { - // do nothing - } else if (is_pure_data_tablets(info)) { - tablet_create_info.create_data_tablet_ = true; - tablet_create_info.data_tablet_id_ = info.data_tablet_id_; - need_push = true; - } else if (is_mixed_tablets(info)) { - tablet_create_info.create_data_tablet_ = true; - tablet_create_info.data_tablet_id_ = info.data_tablet_id_; - need_push = true; - if (OB_FAIL(fill_aux_infos(arg, info, tablet_create_info))) { - LOG_WARN("failed to fill aux info", K(ret)); - } - } else if (is_pure_aux_tablets(info)) { - tablet_create_info.create_data_tablet_ = false; - tablet_create_info.data_tablet_id_ = info.data_tablet_id_; - need_push = true; - if (OB_FAIL(fill_aux_infos(arg, info, tablet_create_info))) { - LOG_WARN("failed to fill aux info", K(ret)); - } - } else if (is_pure_hidden_tablets(info)) { - tablet_create_info.create_data_tablet_ = true; - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); j++) { - tablet_create_info.data_tablet_id_ = info.tablet_ids_[j]; - // find hidden lob info - int64_t aux_idx = -1; - if (find_related_aux_info(arg, tablet_create_info.data_tablet_id_, aux_idx)) { - const ObCreateTabletInfo &aux_info = arg.tablets_.at(aux_idx); - if (OB_FAIL(fill_aux_infos(arg, aux_info, tablet_create_info))) { - LOG_WARN("failed to fill aux info", K(ret), K(PRINT_CREATE_ARG(arg)), K(aux_idx)); - } else if (OB_FAIL(skip_idx.push_back(aux_idx))) { - LOG_WARN("failed to push skip idx", K(ret), K(aux_idx)); - } - } - if (OB_SUCC(ret) && OB_FAIL(tablet_create_info_array.push_back(tablet_create_info))) { - LOG_WARN("failed to push back tablet create info", K(ret), K(tablet_create_info)); - } - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid tablet create info", K(ret), K(info)); - } - - if (OB_FAIL(ret)) { - } else if (need_push) { - if (!tablet_create_info.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid tablet create info", K(ret), K(tablet_create_info)); - } else if (OB_FAIL(tablet_create_info_array.push_back(tablet_create_info))) { - LOG_WARN("failed to push back tablet create info", K(ret), K(tablet_create_info)); - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::ensure_skip_create_all_tablets_safe( - const ObBatchCreateTabletArg &arg, - const SCN &scn) -{ - int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; - ObSArray skip_idx; - - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - const ObTabletID &data_tablet_id = info.data_tablet_id_; - if (is_contain(skip_idx, i)) { - // do nothing - LOG_INFO("pure aux tablet info should be skipped", K(ret), K(info)); - } else if (is_mixed_tablets(info) || is_pure_data_tablets(info)) { - // data tablet already checked, can ignore - } else if (is_pure_aux_tablets(info) || is_pure_hidden_tablets(info)) { - if (is_pure_hidden_tablets(info)) { - // If hidden tablets and related lob tablets are created simultaneously, - // upper layer ensures that hidden tablet info occurs before lob tablets(as aux tablet info). - // So here we only need to find aux info which is related to hidden tablets, - // and the related aux tablet info will be skipped later. - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - int64_t aux_idx = -1; - if (find_related_aux_info(arg, info.tablet_ids_.at(j), aux_idx)) { - if (OB_FAIL(skip_idx.push_back(aux_idx))) { - LOG_WARN("failed to push back skip idx", K(ret), K(aux_idx)); - } - } - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(ls_.replay_get_tablet(data_tablet_id, scn, tablet_handle))) { - if (OB_TABLET_NOT_EXIST != ret && OB_EAGAIN != ret) { - LOG_WARN("failed to replay get tablet", K(ret), K(data_tablet_id), K(scn)); - } else if (OB_TABLET_NOT_EXIST == ret) { - // data tablet is deleted after log_ts of this transaction, safe to skip creation - ret = OB_SUCCESS; - } - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::fill_aux_infos( - const ObBatchCreateTabletArg &arg, - const ObCreateTabletInfo &info, - ObTabletCreateInfo &tablet_create_info) -{ - int ret = OB_SUCCESS; - for (int j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - const ObTabletID &tablet_id = info.tablet_ids_.at(j); - if (tablet_id == info.data_tablet_id_) { - // do nothing - } else if (arg.table_schemas_.at(info.table_schema_index_.at(j)).is_aux_lob_meta_table()) { - tablet_create_info.lob_meta_tablet_id_ = tablet_id; - } else if (arg.table_schemas_.at(info.table_schema_index_.at(j)).is_aux_lob_piece_table()) { - tablet_create_info.lob_piece_tablet_id_ = tablet_id; - } else if (OB_FAIL(tablet_create_info.index_tablet_id_array_.push_back(tablet_id))) { - LOG_WARN("failed to push back tablet id", K(ret), K(tablet_id)); - } + } else if (OB_FAIL(sstable.init(param, &allocator))) { + LOG_WARN("fail to init sstable", K(ret), K(param)); } return ret; } -bool ObTabletCreateDeleteHelper::find_related_aux_info( - const ObBatchCreateTabletArg &arg, - const ObTabletID &data_tablet_id, - int64_t &idx) -{ - bool bret = false; - for (int64_t i = 0; !bret && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - if (is_pure_aux_tablets(info) && info.data_tablet_id_ == data_tablet_id) { - idx = i; - bret = true; - } - } - return bret; -} - bool ObTabletCreateDeleteHelper::is_pure_data_tablets(const ObCreateTabletInfo &info) { const ObTabletID &data_tablet_id = info.data_tablet_id_; @@ -1938,456 +457,6 @@ bool ObTabletCreateDeleteHelper::is_pure_hidden_tablets(const ObCreateTabletInfo return tablet_ids.count() >= 1 && !is_contain(tablet_ids, data_tablet_id) && info.is_create_bind_hidden_tablets_; } -int ObTabletCreateDeleteHelper::get_all_existed_tablets( - const ObBatchCreateTabletArg &arg, - const SCN &scn, - ObIArray &existed_tablet_id_array, - NonLockedHashSet &existed_tablet_id_set) -{ - int ret = OB_SUCCESS; - bool b_exist = false; - ObTabletHandle tablet_handle; - ObTabletMapKey key; - key.ls_id_ = arg.id_; - - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - for (int64_t j = 0; OB_SUCC(ret) && j < info.tablet_ids_.count(); ++j) { - const ObTabletID &tablet_id = info.tablet_ids_[j]; - key.tablet_id_ = tablet_id; - b_exist = true; - if (OB_FAIL(get_tablet(key, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - b_exist = false; - ret = OB_SUCCESS; - } else { - LOG_WARN("failed to get tablet", K(ret), "ls_id", arg.id_, K(tablet_id)); - } - } - - if (OB_FAIL(ret)) { - } else if (b_exist) { - FLOG_INFO("tablet already exists while clog replaying", K(tablet_handle)); - bool tx_data_is_valid = false; - // check tx data - if (OB_FAIL(tablet_handle.get_obj()->check_tx_data(tx_data_is_valid))) { - LOG_WARN("failed to check tx data in new tablet", K(ret)); - } else if (!tx_data_is_valid) { - // tx data is invalid, because we may write slog before tablet gc service does minor freezing - // in this situation, tx data is NOT valid - if (OB_FAIL(existed_tablet_id_array.push_back(tablet_id))) { - LOG_WARN("failed to push back into array", K(ret), K(tablet_id)); - } else { - LOG_INFO("tablet exists and tx data is invalid", K(ret), K(key)); - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(existed_tablet_id_set.set_refactored(tablet_id))) { - LOG_WARN("failed to insert into hash set", K(ret), K(tablet_id)); - } - } - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::build_batch_create_tablet_arg( - const ObBatchCreateTabletArg &old_arg, - const NonLockedHashSet &existed_tablet_id_set, - ObBatchCreateTabletArg &new_arg) -{ - int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; - const ObSArray &old_info_array = old_arg.tablets_; - - for (int64_t i = 0; OB_SUCC(ret) && i < old_info_array.count(); ++i) { - const ObCreateTabletInfo &old_info = old_info_array[i]; - const ObSArray &old_tablet_id_array = old_info.tablet_ids_; - ObCreateTabletInfo new_info; - new_info.data_tablet_id_ = old_info.data_tablet_id_; - new_info.compat_mode_ = old_info.compat_mode_; - new_info.is_create_bind_hidden_tablets_ = old_info.is_create_bind_hidden_tablets_; - - for (int64_t j = 0; OB_SUCC(ret) && j < old_tablet_id_array.count(); ++j) { - const ObTabletID &old_tablet_id = old_tablet_id_array[j]; - tmp_ret = existed_tablet_id_set.exist_refactored(old_tablet_id); - if (OB_HASH_EXIST == tmp_ret) { - LOG_INFO("tablet id exists, should skip", K(old_tablet_id)); - } else if (OB_HASH_NOT_EXIST == tmp_ret) { - const int64_t old_table_schema_index = old_info.table_schema_index_[j]; - if (OB_FAIL(new_info.tablet_ids_.push_back(old_tablet_id))) { - LOG_WARN("failed to push back old tablet id", K(ret), K(old_tablet_id)); - } else if (OB_FAIL(new_info.table_schema_index_.push_back(old_table_schema_index))) { - LOG_WARN("failed to push back table schema index", K(ret), K(old_tablet_id)); - } - } else { - ret = tmp_ret; - LOG_WARN("unexpected error when checking old tablet id", K(ret), K(old_tablet_id)); - } - } - - if (OB_FAIL(ret)) { - } else if (new_info.get_tablet_count() > 0) { - if (OB_FAIL(new_arg.tablets_.push_back(new_info))) { - LOG_WARN("failed to push back tablet info", K(ret), K(new_info)); - } - } else { - LOG_INFO("skip create tablet info", K(ret), K(old_info)); - } - } - - // copy other members in arg - if (OB_FAIL(ret)) { - } else { - new_arg.id_ = old_arg.id_; - new_arg.major_frozen_scn_ = old_arg.major_frozen_scn_; - - if (new_arg.get_tablet_count() > 0 && OB_FAIL(new_arg.table_schemas_.assign(old_arg.table_schemas_))) { - LOG_WARN("failed to assign table schemas", K(ret), K(old_arg)); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::batch_create_tablets( - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - - for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { - const ObCreateTabletInfo &info = arg.tablets_.at(i); - if (OB_FAIL(create_tablet(arg, info, trans_flags))) { - LOG_WARN("failed to create tablet", K(ret), K(info), K(i), K(trans_flags)); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::create_tablet( - const ObBatchCreateTabletArg &arg, - const ObCreateTabletInfo &info, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - - if (OB_UNLIKELY(!info.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid create tablet info", K(ret), K(info)); - } else if (is_pure_data_tablets(info)) { - // pure data tablet. - if (OB_FAIL(build_pure_data_tablet(arg, info, trans_flags))) { - LOG_WARN("failed to build single data tablet", K(ret), K(PRINT_CREATE_ARG(arg)), K(info), K(trans_flags)); - } - } else if (is_mixed_tablets(info)) { - // data tablet + index tablets. - if (OB_FAIL(build_mixed_tablets(arg, info, trans_flags))) { - LOG_WARN("failed to build index tablets", K(ret), K(PRINT_CREATE_ARG(arg)), K(info), K(trans_flags)); - } - } else if (is_pure_aux_tablets(info)) { - // pure index tablet. - if (OB_FAIL(build_pure_aux_tablets(arg, info, trans_flags))) { - LOG_WARN("failed to build index tablets", K(ret), K(PRINT_CREATE_ARG(arg)), K(info), K(trans_flags)); - } - } else if (is_pure_hidden_tablets(info)) { - // pure hidden tablet. - if (OB_FAIL(build_pure_hidden_tablets(arg, info, trans_flags))) { - LOG_WARN("failed to build hidden tablets", K(ret), K(PRINT_CREATE_ARG(arg)), K(info), K(trans_flags)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("info is invalid", K(ret), K(info)); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::build_pure_data_tablet( - const ObBatchCreateTabletArg &arg, - const ObCreateTabletInfo &info, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = arg.id_; - const ObTabletID &data_tablet_id = info.data_tablet_id_; - const ObSArray &tablet_ids = info.tablet_ids_; - const ObSArray &table_schemas = arg.table_schemas_; - const lib::Worker::CompatMode &compat_mode = info.compat_mode_; - ObSArray empty_array; - ObTabletID empty_lob_tablet_id; - ObTabletHandle tablet_handle; - int64_t index = -1; - ObTabletMapKey key(ls_id, data_tablet_id); - - if (OB_FAIL(get_tablet_schema_index(data_tablet_id, tablet_ids, index))) { - LOG_WARN("failed to get tablet schema index in array", K(ret), K(data_tablet_id)); - } else if (OB_UNLIKELY(index < 0)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, table schema index is invalid", K(ret), K(key), K(index)); - } else if (OB_FAIL(do_create_tablet(data_tablet_id, data_tablet_id, empty_lob_tablet_id, - empty_lob_tablet_id, empty_array, arg, trans_flags, - table_schemas[info.table_schema_index_[index]], compat_mode, tablet_handle))) { - LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(data_tablet_id), K(PRINT_CREATE_ARG(arg))); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::build_mixed_tablets( - const ObBatchCreateTabletArg &arg, - const ObCreateTabletInfo &info, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = arg.id_; - const ObTabletID &data_tablet_id = info.data_tablet_id_; - const ObSArray &tablet_ids = info.tablet_ids_; - const ObSArray &table_schemas = arg.table_schemas_; - const lib::Worker::CompatMode &compat_mode = info.compat_mode_; - ObSArray empty_array; - ObSArray index_tablet_array; - ObTabletHandle data_tablet_handle; - int64_t data_tablet_index = -1; - int64_t lob_meta_tablet_index = -1; - int64_t lob_piece_tablet_index = -1; - ObTabletID lob_meta_tablet_id; - ObTabletID lob_piece_tablet_id; - ObTabletID empty_lob_tablet_id; - - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { - const ObTabletID &tablet_id = tablet_ids[i]; - if (tablet_id == data_tablet_id) { - data_tablet_index = i; - } else if (table_schemas.at(info.table_schema_index_.at(i)).is_aux_lob_meta_table()) { - lob_meta_tablet_index = i; - } else if (table_schemas.at(info.table_schema_index_.at(i)).is_aux_lob_piece_table()) { - lob_piece_tablet_index = i; - } else { - ObTabletHandle tablet_handle; - if (OB_FAIL(index_tablet_array.push_back(tablet_id))) { - LOG_WARN("failed to insert tablet id into index tablet array", K(ret), K(tablet_id)); - } else if (OB_FAIL(do_create_tablet(tablet_id, data_tablet_id, empty_lob_tablet_id, - empty_lob_tablet_id, empty_array, arg, trans_flags, - table_schemas[info.table_schema_index_[i]], compat_mode, tablet_handle))) { - LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), K(PRINT_CREATE_ARG(arg))); - } - } - } - - // process lob tablets - ObTabletHandle lob_meta_tablet_handle; - ObTabletHandle lob_piece_tablet_handle; - if (OB_FAIL(ret)) { // do nothing - } else if (lob_meta_tablet_index != -1) { - lob_meta_tablet_id = tablet_ids[lob_meta_tablet_index]; - if (OB_FAIL(do_create_tablet(lob_meta_tablet_id, data_tablet_id, lob_meta_tablet_id, - empty_lob_tablet_id, empty_array, arg, trans_flags, - table_schemas[info.table_schema_index_[lob_meta_tablet_index]], compat_mode, lob_meta_tablet_handle))) { - LOG_WARN("failed to do create lob meta tablet", K(ret), K(ls_id), K(lob_meta_tablet_id), K(data_tablet_id), K(PRINT_CREATE_ARG(arg))); - } - } - if (OB_FAIL(ret)) { // do nothing - } else if (lob_piece_tablet_index != -1) { - lob_piece_tablet_id = tablet_ids[lob_piece_tablet_index]; - if (OB_FAIL(do_create_tablet(lob_piece_tablet_id, data_tablet_id, empty_lob_tablet_id, - lob_piece_tablet_id, empty_array, arg, trans_flags, - table_schemas[info.table_schema_index_[lob_piece_tablet_index]], compat_mode, lob_piece_tablet_handle))) { - LOG_WARN("failed to do create lob piece tablet", K(ret), K(ls_id), K(lob_piece_tablet_id), K(data_tablet_id), K(PRINT_CREATE_ARG(arg))); - } - } - - if (OB_FAIL(ret)) { - } else if (OB_UNLIKELY(data_tablet_index < 0)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, data tablet index is invalid", K(ret), K(data_tablet_index)); - } else if (OB_FAIL(do_create_tablet(data_tablet_id, data_tablet_id, lob_meta_tablet_id, - lob_piece_tablet_id, index_tablet_array, arg, trans_flags, - table_schemas[info.table_schema_index_[data_tablet_index]], compat_mode, data_tablet_handle))) { - LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(data_tablet_id), K(index_tablet_array), K(PRINT_CREATE_ARG(arg))); - } - return ret; -} - -int ObTabletCreateDeleteHelper::build_pure_aux_tablets( - const ObBatchCreateTabletArg &arg, - const ObCreateTabletInfo &info, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = arg.id_; - const ObTabletID &data_tablet_id = info.data_tablet_id_; - const ObSArray &tablet_ids = info.tablet_ids_; - const ObSArray &table_schemas = arg.table_schemas_; - const lib::Worker::CompatMode &compat_mode = info.compat_mode_; - ObSArray empty_array; - ObTabletID lob_meta_tablet_id; - ObTabletID lob_piece_tablet_id; - ObTabletID empty_lob_tablet_id; - ObTabletHandle aux_tablet_handle; - - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { - const ObTabletID &aux_tablet_id = tablet_ids[i]; - if (table_schemas.at(info.table_schema_index_.at(i)).is_aux_lob_meta_table()) { - lob_meta_tablet_id = aux_tablet_id; - } else if (table_schemas.at(info.table_schema_index_.at(i)).is_aux_lob_piece_table()) { - lob_piece_tablet_id = aux_tablet_id; - } else { - lob_meta_tablet_id.reset(); - lob_piece_tablet_id.reset(); - } - if (OB_FAIL(do_create_tablet(aux_tablet_id, data_tablet_id, lob_meta_tablet_id, - lob_piece_tablet_id, empty_array, arg, trans_flags, - table_schemas[info.table_schema_index_[i]], compat_mode, aux_tablet_handle))) { - LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(aux_tablet_id), K(data_tablet_id), K(PRINT_CREATE_ARG(arg))); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::build_pure_hidden_tablets( - const ObBatchCreateTabletArg &arg, - const ObCreateTabletInfo &info, - const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObLSID &ls_id = arg.id_; - const ObSArray &hidden_tablet_ids = info.tablet_ids_; - const ObSArray &table_schemas = arg.table_schemas_; - const lib::Worker::CompatMode &compat_mode = info.compat_mode_; - ObSArray empty_array; - ObTabletHandle hidden_tablet_handle; - ObMetaDiskAddr mem_addr; - if (OB_FAIL(mem_addr.set_mem_addr(0, sizeof(ObTablet)))) { - LOG_WARN("fail to set memory address", K(ret)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < hidden_tablet_ids.count(); ++i) { - const ObTabletID &hidden_tablet_id = hidden_tablet_ids[i]; - int64_t aux_idx = -1; - ObTabletID lob_meta_tablet_id; - ObTabletID lob_piece_tablet_id; - if (find_related_aux_info(arg, hidden_tablet_id, aux_idx)) { - const ObCreateTabletInfo &aux_info = arg.tablets_.at(aux_idx); - for (int64_t j = 0; j < aux_info.tablet_ids_.count(); ++j) { - if (arg.table_schemas_.at(aux_info.table_schema_index_.at(j)).is_aux_lob_meta_table()) { - lob_meta_tablet_id = aux_info.tablet_ids_.at(j); - } else if (arg.table_schemas_.at(aux_info.table_schema_index_.at(j)).is_aux_lob_piece_table()) { - lob_piece_tablet_id = aux_info.tablet_ids_.at(j); - } - } - } - if (OB_FAIL(do_create_tablet(hidden_tablet_id, hidden_tablet_id, lob_meta_tablet_id, - lob_piece_tablet_id, empty_array, arg, trans_flags, - table_schemas[info.table_schema_index_[i]], compat_mode, hidden_tablet_handle))) { - LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(hidden_tablet_id), K(PRINT_CREATE_ARG(arg))); - } - } - - return ret; -} - -int ObTabletCreateDeleteHelper::get_tablet_schema_index( - const ObTabletID &tablet_id, - const ObIArray &table_ids, - int64_t &index) -{ - int ret = OB_SUCCESS; - bool match = false; - - for (int64_t i = 0; !match && i < table_ids.count(); ++i) { - if (table_ids.at(i) == tablet_id) { - index = i; - match = true; - } - } - - if (OB_UNLIKELY(!match)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("cannot find target tablet id in array", K(ret), K(tablet_id)); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::do_create_tablet( - const ObTabletID &tablet_id, - const ObTabletID &data_tablet_id, - const ObTabletID &lob_meta_tablet_id, - const ObTabletID &lob_piece_tablet_id, - const ObIArray &index_tablet_array, - const ObBatchCreateTabletArg &arg, - const ObMulSourceDataNotifyArg &trans_flags, - const ObTableSchema &table_schema, - const lib::Worker::CompatMode &compat_mode, - ObTabletHandle &tablet_handle) -{ - int ret = OB_SUCCESS; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - const ObLSID &ls_id = arg.id_; - const ObTabletMapKey key(ls_id, tablet_id); - ObTablet *tablet = nullptr; - ObTableHandleV2 table_handle; - ObTabletCreateSSTableParam param; - ObFreezer *freezer = ls_.get_freezer(); - bool need_create_empty_major_sstable = false; - const ObTransID &tx_id = trans_flags.tx_id_; - const bool for_replay = trans_flags.for_replay_; - MemtableRefOp ref_op = for_replay ? MemtableRefOp::NONE : MemtableRefOp::INC_REF; - SCN scn = trans_flags.for_replay_ ? trans_flags.scn_ : SCN::max_scn(); - SCN create_scn = trans_flags.scn_; - ObMetaDiskAddr mem_addr; - ObTabletTableStoreFlag table_store_flag; - table_store_flag.set_with_major_sstable(); - if (OB_FAIL(mem_addr.set_mem_addr(0, sizeof(ObTablet)))) { - LOG_WARN("fail to set memory address", K(ret)); - } else if (OB_FAIL(acquire_tablet(key, tablet_handle, false/*only acquire*/))) { - LOG_WARN("failed to acquire tablet", K(ret), K(key)); - } else if (OB_FAIL(check_need_create_empty_major_sstable(table_schema, need_create_empty_major_sstable))) { - LOG_WARN("failed to check need create sstable", K(ret)); - } else if (!need_create_empty_major_sstable) { - table_store_flag.set_without_major_sstable(); - LOG_INFO("no need to create sstable", K(ls_id), K(tablet_id), K(table_schema)); - } else if (OB_FAIL(build_create_sstable_param( - table_schema, tablet_id, arg.major_frozen_scn_.get_val_for_tx(), param))) { - LOG_WARN("failed to build create sstable param", K(ret), K(tablet_id), - K(table_schema), K(arg), K(param)); - } else if (OB_FAIL(create_sstable(param, table_handle))) { - LOG_WARN("failed to create sstable", K(ret), K(param)); - } - - if (OB_FAIL(ret)) { - } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error, tablet is NULL", K(ret), K(tablet_handle)); - } else if (OB_FAIL(tablet->init(ls_id, tablet_id, data_tablet_id, lob_meta_tablet_id, lob_piece_tablet_id, - create_scn, arg.major_frozen_scn_.get_val_for_tx(), table_schema, compat_mode, table_store_flag, table_handle, freezer))) { - LOG_WARN("failed to init tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), - K(lob_meta_tablet_id), K(lob_piece_tablet_id), K(index_tablet_array), - K(arg), K(create_scn), K(table_schema), K(compat_mode), K(table_store_flag)); - } else if (OB_FAIL(t3m->compare_and_swap_tablet(key, mem_addr, tablet_handle, tablet_handle))) { - LOG_WARN("failed to compare and swap tablet", K(ret), K(key), K(mem_addr), K(tablet_handle)); - } else { - LOG_INFO("prepare to set tx data", K(ret), K(ls_id), K(tablet_id)); - - ObTabletTxMultiSourceDataUnit tx_data; - tx_data.tx_id_ = tx_id; - tx_data.tx_scn_ = scn; - tx_data.tablet_status_ = ObTabletStatus::CREATING; - - if (OB_FAIL(tablet->set_tx_data(tx_data, trans_flags.for_replay_, ref_op))) { - LOG_WARN("failed to set tx data", K(ret), K(tx_data), K(trans_flags), K(ref_op)); - } else if (OB_FAIL(t3m->insert_pinned_tablet(key))) { - LOG_WARN("failed to insert in tx tablet", K(ret), K(key)); - } - } - - return ret; -} - int ObTabletCreateDeleteHelper::check_need_create_empty_major_sstable( const ObTableSchema &table_schema, bool &need_create_sstable) @@ -2403,6 +472,20 @@ int ObTabletCreateDeleteHelper::check_need_create_empty_major_sstable( return ret; } +void ObTabletCreateDeleteHelper::print_memtables_for_table(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + common::ObSArray memtables; + if (!tablet_handle.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet_handle is not valid", K(ret), K(tablet_handle)); + } else if (OB_FAIL(tablet_handle.get_obj()->get_memtables(memtables, true))) { + LOG_WARN("failed to get_memtables", K(ret), K(tablet_handle)); + } else { + LOG_INFO("memtables print", K(memtables), K(tablet_handle)); + } +} + int ObTabletCreateDeleteHelper::build_create_sstable_param( const ObTableSchema &table_schema, const ObTabletID &tablet_id, @@ -2466,99 +549,6 @@ int ObTabletCreateDeleteHelper::build_create_sstable_param( return ret; } -int ObTabletCreateDeleteHelper::set_tablet_final_status( - ObTabletHandle &tablet_handle, - const ObTabletStatus::Status status, - const SCN &tx_scn, - const SCN &memtable_scn, - const bool for_replay, - const MemtableRefOp ref_op) -{ - int ret = OB_SUCCESS; - ObTablet *tablet = tablet_handle.get_obj(); - const ObLSID &ls_id = tablet->get_tablet_meta().ls_id_; - const ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; - ObTabletTxMultiSourceDataUnit tx_data; - ObTabletStatusChecker checker(*tablet); - - if (ObTabletStatus::NORMAL != status && ObTabletStatus::DELETED != status) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(status)); - } else if (OB_FAIL(tablet->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(ls_id), K(tablet_id)); - } else if (OB_UNLIKELY(!ObTabletStatus::is_valid_status(tx_data.tablet_status_, status))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid status", K(ret), "current_status", tx_data.tablet_status_, "target_status", status); - } else { - tx_data.tx_id_ = ObTabletCommon::FINAL_TX_ID; - tx_data.tablet_status_ = status; - tx_data.tx_scn_ = tx_scn; - - if (OB_FAIL(checker.wake_up(tx_data, memtable_scn, for_replay, ref_op))) { - LOG_WARN("failed to wake up", K(ret), KPC(tablet), K(status), - K(tx_scn), K(memtable_scn), K(for_replay), K(ref_op)); - } else { - LOG_INFO("succeeded to set tablet final status", K(ret), K(ls_id), K(tablet_id), K(status), - K(tx_scn), K(memtable_scn), K(for_replay), K(ref_op)); - } - } - - return ret; -} - -bool ObTabletCreateDeleteHelper::check_tablet_status( - const ObTabletHandle &tablet_handle, - const ObTabletStatus::Status expected_status) -{ - bool b_ret = true; - int ret = OB_SUCCESS; - ObTablet *tablet = tablet_handle.get_obj(); - ObTabletTxMultiSourceDataUnit tx_data; - - if (OB_FAIL(tablet->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret)); - } else if (expected_status != tx_data.tablet_status_) { - b_ret = false; - } - - if (OB_FAIL(ret)) { - b_ret = false; - } - - return b_ret; -} - -int ObTabletCreateDeleteHelper::check_tablet_status( - const ObBatchRemoveTabletArg &arg, - bool &normal) -{ - int ret = OB_SUCCESS; - normal = true; - ObTabletHandle tablet_handle; - ObTabletMapKey key; - key.ls_id_ = arg.id_; - - for (int64_t i = 0; OB_SUCC(ret) && normal && i < arg.tablet_ids_.count(); ++i) { - const ObTabletID &tablet_id = arg.tablet_ids_.at(i); - key.tablet_id_ = tablet_id; - if (OB_FAIL(check_and_get_tablet(key, tablet_handle, ObTabletCommon::DEFAULT_GET_TABLET_TIMEOUT_US))) { - if (OB_TIMEOUT == ret) { - normal = false; - ret = OB_SUCCESS; - LOG_INFO("tablet is not in NORMAL status", K(ret), K(key)); - } else if (OB_TABLET_NOT_EXIST == ret) { - normal = false; - ret = OB_SUCCESS; - LOG_INFO("tablet does not exist or may be deleted", K(ret), K(key)); - } else { - LOG_WARN("failed to check and get tablet", K(ret), K(key)); - } - } - } - - return ret; -} - ObSimpleBatchCreateTabletArg::ObSimpleBatchCreateTabletArg(const ObBatchCreateTabletArg &arg) : arg_(arg) { @@ -2599,46 +589,5 @@ int64_t ObSimpleBatchCreateTabletArg::to_string(char *buf, const int64_t buf_len } return pos; } - -int ObTabletCreateDeleteHelper::prepare_data_for_tablet_status(const ObTabletID &tablet_id, const ObLS &ls, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObTabletMapKey key(ls.get_ls_id(), tablet_id); - ObTabletHandle tablet_handle; - ObTablet *tablet = nullptr; - ObTabletTxMultiSourceDataUnit tx_data; - - if (OB_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", KR(ret), K(key)); - } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_FAIL(tablet->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", KR(ret)); - } else if (OB_FAIL(tablet->prepare_data(tx_data, trans_flags))) { - LOG_WARN("failed to prepare tx data", KR(ret), K(tx_data)); - } - - return ret; -} - -int ObTabletCreateDeleteHelper::prepare_data_for_binding_info(const ObTabletID &tablet_id, const ObLS &ls, const ObMulSourceDataNotifyArg &trans_flags) -{ - int ret = OB_SUCCESS; - const ObTabletMapKey key(ls.get_ls_id(), tablet_id); - ObTabletHandle tablet_handle; - ObTablet *tablet = nullptr; - ObTabletBindingInfo binding_info; - - if (OB_FAIL(get_tablet(key, tablet_handle))) { - LOG_WARN("failed to get tablet", KR(ret), K(key)); - } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_FAIL(tablet->get_ddl_data(binding_info))) { - LOG_WARN("failed to get tx data", KR(ret)); - } else if (OB_FAIL(tablet->prepare_data(binding_info, trans_flags))) { - LOG_WARN("failed to prepare binding info", KR(ret), K(binding_info)); - } - - return ret; -} - } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_create_delete_helper.h b/src/storage/tablet/ob_tablet_create_delete_helper.h index 8111a369d..d3d0949d1 100644 --- a/src/storage/tablet/ob_tablet_create_delete_helper.h +++ b/src/storage/tablet/ob_tablet_create_delete_helper.h @@ -20,17 +20,17 @@ #include "common/ob_tablet_id.h" #include "storage/memtable/ob_memtable.h" #include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" #include "share/scn.h" #include "storage/tablet/ob_tablet_status.h" #include "storage/tablet/ob_tablet_common.h" +#include "storage/tablet/ob_tablet_mds_data_cache.h" namespace oceanbase { namespace obrpc { struct ObBatchCreateTabletArg; -struct ObBatchRemoveTabletArg; -struct ObCreateTabletInfo; } namespace share @@ -40,94 +40,68 @@ namespace schema class ObTableSchema; } } - -namespace transaction -{ -struct ObMulSourceDataNotifyArg; -} - namespace storage { -class ObLS; class ObTabletMapKey; class ObTabletCreateSSTableParam; class ObTableHandleV2; -class ObTabletIDSet; - -class ObTabletCreateInfo final -{ -public: - ObTabletCreateInfo(); - ~ObTabletCreateInfo() = default; - ObTabletCreateInfo(const ObTabletCreateInfo &other); - ObTabletCreateInfo &operator=(const ObTabletCreateInfo &other); - bool is_valid() { return data_tablet_id_.is_valid(); } - TO_STRING_KV(K_(create_data_tablet), - K_(data_tablet_id), - K_(index_tablet_id_array), - K_(lob_meta_tablet_id), - K_(lob_piece_tablet_id)); -public: - bool create_data_tablet_; - ObTabletID data_tablet_id_; - common::ObSArray index_tablet_id_array_; - ObTabletID lob_meta_tablet_id_; - ObTabletID lob_piece_tablet_id_; -}; +class ObTablet; +class ObTabletCreateDeleteMdsUserData; class ObTabletCreateDeleteHelper { -private: - typedef common::hash::ObHashSet NonLockedHashSet; -public: - ObTabletCreateDeleteHelper( - ObLS &ls, - ObTabletIDSet &tablet_id_set); -public: - int prepare_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int redo_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int commit_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags, - common::ObIArray &tablet_id_array); - int abort_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int tx_end_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int prepare_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int redo_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int commit_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int tx_end_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int abort_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); public: static int get_tablet( const ObTabletMapKey &key, ObTabletHandle &handle, const int64_t timeout_us = ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US); + + // snapshot version is used for multi source data reading, + // tablet's multi source data will infect its visibility. + // if snapshot version is MAX_TRANS_VERSION, it means we'll ignore + // tablet creation/deletion transaction commit version, + // and the tablet is fully visible as long as it really exists. static int check_and_get_tablet( const ObTabletMapKey &key, ObTabletHandle &handle, - const int64_t timeout_us); - static int acquire_tablet( + const int64_t timeout_us, + const ObMDSGetTabletMode mode, + const int64_t snapshot_version); + static int check_status_for_new_mds( + ObTablet &tablet, + const int64_t snapshot_version, + const int64_t timeout_us, + ObTabletStatusCache &tablet_status_cache); + static int check_read_snapshot_by_transfer_scn( + const share::SCN &transfer_scn, + const bool is_committed, + const share::SCN &snapshot); + static int check_read_snapshot_by_commit_version( + ObTablet &tablet, + const int64_t create_commit_version, + const int64_t delete_commit_version, + const int64_t snapshot_version, + const ObTabletStatus &tablet_status); + static int create_tmp_tablet( const ObTabletMapKey &key, - ObTabletHandle &handle, - const bool only_acquire = false); + common::ObArenaAllocator &allocator, + ObTabletHandle &handle); + static int prepare_create_msd_tablet(); + static int push_msd_tablet_to_queue(ObTabletHandle &handle); + static int create_msd_tablet( + const ObTabletMapKey &key, + ObTabletHandle &handle); + static int acquire_msd_tablet( + const ObTabletMapKey &key, + ObTabletHandle &handle); + static int acquire_tmp_tablet( + const ObTabletMapKey &key, + common::ObArenaAllocator &allocator, + ObTabletHandle &handle); + static int acquire_tablet_from_pool( + const ObTabletPoolType &type, + const ObTabletMapKey &key, + ObTabletHandle &handle); static int check_need_create_empty_major_sstable( const share::schema::ObTableSchema &table_schema, bool &need_create_sstable); @@ -136,171 +110,66 @@ public: const common::ObTabletID &tablet_id, const int64_t snapshot_version, ObTabletCreateSSTableParam ¶m); + static int create_sstable_for_migrate( // TODO: @jinzhu remove me later. + const ObTabletCreateSSTableParam ¶m, + common::ObArenaAllocator &allocator, + ObTableHandleV2 &table_handle); static int create_sstable( const ObTabletCreateSSTableParam ¶m, - ObTableHandleV2 &table_handle); + common::ObArenaAllocator &allocator, + blocksstable::ObSSTable &sstable); + // ObTabletBindingHelper usage static bool is_pure_data_tablets(const obrpc::ObCreateTabletInfo &info); static bool is_mixed_tablets(const obrpc::ObCreateTabletInfo &info); static bool is_pure_aux_tablets(const obrpc::ObCreateTabletInfo &info); static bool is_pure_hidden_tablets(const obrpc::ObCreateTabletInfo &info); - static bool find_related_aux_info( - const obrpc::ObBatchCreateTabletArg &arg, - const common::ObTabletID &data_tablet_id, - int64_t &idx); - static int prepare_data_for_tablet_status(const ObTabletID &tablet_id, const ObLS &ls, const transaction::ObMulSourceDataNotifyArg &trans_flags); + static void print_memtables_for_table(ObTabletHandle &tablet_handle); + template + static int process_for_old_mds( + const char *buf, + const int64_t len, + const transaction::ObMulSourceDataNotifyArg ¬ify_arg); +}; - static int prepare_data_for_binding_info(const ObTabletID &tablet_id, const ObLS &ls, const transaction::ObMulSourceDataNotifyArg &trans_flags); -private: - static int check_create_new_tablets(const obrpc::ObBatchCreateTabletArg &arg); - static int verify_tablets_absence( - const obrpc::ObBatchCreateTabletArg &arg, - common::ObIArray &tablet_create_info_array); - static int check_tablet_existence( - const obrpc::ObBatchCreateTabletArg &arg, - bool &is_valid); - static int check_tablet_absence( - const obrpc::ObBatchCreateTabletArg &arg, - bool &is_valid); - static int check_pure_data_or_mixed_tablets_info( - const share::ObLSID &ls_id, - const obrpc::ObCreateTabletInfo &info, - bool &is_valid); - static int check_pure_index_or_hidden_tablets_info( - const share::ObLSID &ls_id, - const obrpc::ObCreateTabletInfo &info, - bool &is_valid); - static int build_tablet_create_info( - const obrpc::ObBatchCreateTabletArg &arg, - common::ObIArray &tablet_create_info_array); - static int get_all_existed_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const share::SCN &scn, - common::ObIArray &existed_tablet_id_array, - NonLockedHashSet &existed_tablet_id_set); - static int build_batch_create_tablet_arg( - const obrpc::ObBatchCreateTabletArg &old_arg, - const NonLockedHashSet &existed_tablet_id_set, - obrpc::ObBatchCreateTabletArg &new_arg); - static int get_tablet_schema_index( - const common::ObTabletID &tablet_id, - const common::ObIArray &table_ids, - int64_t &index); - static int set_tablet_final_status( - ObTabletHandle &tablet_handle, - const ObTabletStatus::Status status, - const share::SCN &tx_scn, - const share::SCN &memtable_scn, - const bool for_replay, - const memtable::MemtableRefOp ref_op = memtable::MemtableRefOp::NONE); - static bool check_tablet_status( - const ObTabletHandle &tablet_handle, - const ObTabletStatus::Status expected_status); - static int check_tablet_status( - const obrpc::ObBatchRemoveTabletArg &arg, - bool &normal); - static int fill_aux_infos( - const obrpc::ObBatchCreateTabletArg &arg, - const obrpc::ObCreateTabletInfo &info, - ObTabletCreateInfo &tablet_create_info); -private: - int replay_prepare_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int do_prepare_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int record_tablet_id( - const common::ObIArray &tablet_create_info_array); - int handle_special_tablets_for_replay( - const common::ObIArray &existed_tablet_id_array, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int set_scn( - const common::ObIArray &tablet_create_info_array, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int print_multi_data_for_create_tablet( - const common::ObIArray &tablet_create_info_array); - int print_multi_data_for_remove_tablet( - const obrpc::ObBatchRemoveTabletArg &arg); - int batch_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int create_tablet( - const obrpc::ObBatchCreateTabletArg &arg, - const obrpc::ObCreateTabletInfo &info, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int ensure_skip_create_all_tablets_safe( - const obrpc::ObBatchCreateTabletArg &arg, - const share::SCN &scn); - int build_pure_data_tablet( - const obrpc::ObBatchCreateTabletArg &arg, - const obrpc::ObCreateTabletInfo &info, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int build_mixed_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const obrpc::ObCreateTabletInfo &info, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int build_pure_aux_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const obrpc::ObCreateTabletInfo &info, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int build_pure_hidden_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const obrpc::ObCreateTabletInfo &info, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int build_mixed_hidden_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const obrpc::ObCreateTabletInfo &info, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int do_create_tablet( - const common::ObTabletID &tablet_id, - const common::ObTabletID &data_tablet_id, - const common::ObTabletID &lob_meta_tablet_id, - const common::ObTabletID &lob_piece_tablet_id, - const common::ObIArray &index_tablet_array, - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags, - const share::schema::ObTableSchema &table_schema, - const lib::Worker::CompatMode &compat_mode, - ObTabletHandle &tablet_handle); - int do_commit_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags, - common::ObIArray &tablet_id_array); - int do_commit_create_tablet( - const common::ObTabletID &tablet_id, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int do_abort_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int do_tx_end_create_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int roll_back_remove_tablets( - const obrpc::ObBatchCreateTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int roll_back_remove_tablet( - const share::ObLSID &ls_id, - const common::ObTabletID &tablet_id, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int do_abort_create_tablet( - ObTabletHandle &tablet_handle, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int do_commit_remove_tablet( - const common::ObTabletID &tablet_id, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int do_abort_remove_tablet( - const common::ObTabletID &tablet_id, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int do_tx_end_remove_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const transaction::ObMulSourceDataNotifyArg &trans_flags); - int replay_verify_tablets( - const obrpc::ObBatchRemoveTabletArg &arg, - const share::SCN &scn, - common::ObIArray &tablet_id_array); -private: - ObLS &ls_; - ObTabletIDSet &tablet_id_set_; +template +int ObTabletCreateDeleteHelper::process_for_old_mds( + const char *buf, + const int64_t len, + const transaction::ObMulSourceDataNotifyArg ¬ify_arg) +{ + int ret = OB_SUCCESS; + Arg arg; + int64_t pos = 0; + + if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0)) { + ret = OB_INVALID_ARGUMENT; + TRANS_LOG(WARN, "invalid args", K(ret), KP(buf), K(len)); + } else if (OB_FAIL(arg.deserialize(buf, len, pos))) { + TRANS_LOG(WARN, "failed to deserialize", K(ret)); + } else if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(WARN, "arg is invalid", K(ret), K(arg)); + } else if (arg.is_old_mds_) { + mds::MdsCtx mds_ctx; + mds_ctx.set_binding_type_id(mds::TupleTypeIdx::value); + mds_ctx.set_writer(mds::MdsWriter(notify_arg.tx_id_)); + do { + if (OB_FAIL(Helper::register_process(arg, mds_ctx))) { + TRANS_LOG(ERROR, "fail to register_process, retry", K(ret), K(arg)); + usleep(100 * 1000); + } + } while (OB_FAIL(ret) && !notify_arg.for_replay_); + + if (OB_FAIL(ret)) { + if (notify_arg.for_replay_) { + ret = OB_EAGAIN; + } + } else { + mds_ctx.single_log_commit(notify_arg.trans_version_, notify_arg.scn_); + TRANS_LOG(INFO, "replay create commit for old_mds", KR(ret), K(arg)); + } + } + return ret; }; class ObSimpleBatchCreateTabletArg diff --git a/src/storage/tablet/ob_tablet_create_delete_mds_user_data.cpp b/src/storage/tablet/ob_tablet_create_delete_mds_user_data.cpp new file mode 100644 index 000000000..4d5f1a847 --- /dev/null +++ b/src/storage/tablet/ob_tablet_create_delete_mds_user_data.cpp @@ -0,0 +1,247 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/utility/ob_unify_serialize.h" +#include "share/ob_errno.h" +#include "storage/tx/ob_trans_define.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" + +#define USING_LOG_PREFIX MDS + +using namespace oceanbase::common; +using namespace oceanbase::transaction; + +namespace oceanbase +{ +namespace storage +{ +ObTabletCreateDeleteMdsUserData::ObTabletCreateDeleteMdsUserData() + : tablet_status_(), + transfer_scn_(share::SCN::invalid_scn()), + transfer_ls_id_(), + data_type_(ObTabletMdsUserDataType::NONE), + create_commit_scn_(share::SCN::invalid_scn()), + create_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), + delete_commit_scn_(share::SCN::invalid_scn()), + delete_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), + transfer_out_commit_version_(ObTransVersion::INVALID_TRANS_VERSION) +{ +} + +ObTabletCreateDeleteMdsUserData::ObTabletCreateDeleteMdsUserData(const ObTabletStatus::Status &status, const ObTabletMdsUserDataType type) + : tablet_status_(status), + transfer_scn_(share::SCN::invalid_scn()), + transfer_ls_id_(), + data_type_(type), + create_commit_scn_(share::SCN::invalid_scn()), + create_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), + delete_commit_scn_(share::SCN::invalid_scn()), + delete_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), + transfer_out_commit_version_(ObTransVersion::INVALID_TRANS_VERSION) +{ +} + +int ObTabletCreateDeleteMdsUserData::assign(const ObTabletCreateDeleteMdsUserData &other) +{ + int ret = OB_SUCCESS; + tablet_status_ = other.tablet_status_; + transfer_scn_ = other.transfer_scn_; + transfer_ls_id_ = other.transfer_ls_id_; + data_type_ = other.data_type_; + create_commit_scn_ = other.create_commit_scn_; + create_commit_version_ = other.create_commit_version_; + delete_commit_scn_ = other.delete_commit_scn_; + delete_commit_version_ = other.delete_commit_version_; + transfer_out_commit_version_ = other.transfer_out_commit_version_; + return ret; +} + +void ObTabletCreateDeleteMdsUserData::reset() +{ + tablet_status_ = ObTabletStatus::MAX; + transfer_scn_.set_invalid(); + transfer_ls_id_.reset(); + data_type_ = ObTabletMdsUserDataType::NONE; + create_commit_scn_.set_invalid(); + create_commit_version_ = ObTransVersion::INVALID_TRANS_VERSION; + delete_commit_scn_.set_invalid(); + create_commit_version_ = ObTransVersion::INVALID_TRANS_VERSION; + transfer_out_commit_version_ = ObTransVersion::INVALID_TRANS_VERSION; +} + +void ObTabletCreateDeleteMdsUserData::on_redo(const share::SCN &redo_scn) +{ + int ret = OB_SUCCESS; + switch (data_type_) { + case ObTabletMdsUserDataType::NONE : + case ObTabletMdsUserDataType::CREATE_TABLET : + case ObTabletMdsUserDataType::REMOVE_TABLET : + case ObTabletMdsUserDataType::START_TRANSFER_IN : + case ObTabletMdsUserDataType::FINISH_TRANSFER_OUT : { + break; + } + case ObTabletMdsUserDataType::START_TRANSFER_OUT : { + start_transfer_out_on_redo_(redo_scn); + break; + } + case ObTabletMdsUserDataType::FINISH_TRANSFER_IN : { + finish_transfer_in_on_redo_(redo_scn); + break; + } + default: { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid cur status for fail", K(ret), KPC(this)); + } + } +} + +void ObTabletCreateDeleteMdsUserData::start_transfer_out_on_redo_(const share::SCN &redo_scn) +{ + transfer_scn_ = redo_scn; + LOG_INFO("[TRANSFER] start transfer out on redo", KPC(this)); +} + +void ObTabletCreateDeleteMdsUserData::finish_transfer_in_on_redo_(const share::SCN &redo_scn) +{ + transfer_scn_ = redo_scn; + LOG_INFO("[TRANSFER] finish transfer in on redo", KPC(this)); +} + +void ObTabletCreateDeleteMdsUserData::on_commit(const share::SCN &commit_version, const share::SCN &commit_scn) +{ + int ret = OB_SUCCESS; + switch (data_type_) { + case ObTabletMdsUserDataType::NONE : + case ObTabletMdsUserDataType::FINISH_TRANSFER_IN : { + break; + } + case ObTabletMdsUserDataType::CREATE_TABLET : { + create_tablet_on_commit_(commit_version, commit_scn); + break; + } + case ObTabletMdsUserDataType::START_TRANSFER_IN : { + start_transfer_in_on_commit_(commit_version, commit_scn); + break; + } + case ObTabletMdsUserDataType::REMOVE_TABLET : { + delete_tablet_on_commit_(commit_version, commit_scn); + break; + } + case ObTabletMdsUserDataType::FINISH_TRANSFER_OUT : { + finish_transfer_out_on_commit_(commit_version, commit_scn); + break; + } + case ObTabletMdsUserDataType::START_TRANSFER_OUT : { + start_transfer_out_on_commit_(commit_version); + break; + } + default: { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid cur status for fail", K(ret), KPC(this)); + } + } +} + +void ObTabletCreateDeleteMdsUserData::create_tablet_on_commit_( + const share::SCN &commit_version, + const share::SCN &commit_scn) +{ + create_commit_scn_ = commit_scn; + create_commit_version_ = commit_version.get_val_for_tx(); + LOG_INFO("create tablet commit", KPC(this)); +} + +void ObTabletCreateDeleteMdsUserData::start_transfer_in_on_commit_( + const share::SCN &commit_version, + const share::SCN &commit_scn) +{ + LOG_INFO("[TRANSFER] transfer in create tablet commit", KPC(this)); +} + +void ObTabletCreateDeleteMdsUserData::delete_tablet_on_commit_( + const share::SCN &commit_version, + const share::SCN &commit_scn) +{ + delete_commit_scn_ = commit_scn; + delete_commit_version_ = commit_version.get_val_for_tx(); + LOG_INFO("delete tablet commit", KPC(this)); +} + +void ObTabletCreateDeleteMdsUserData::finish_transfer_out_on_commit_( + const share::SCN &commit_version, + const share::SCN &commit_scn) +{ + delete_commit_scn_ = commit_scn; + delete_commit_version_ = commit_version.get_val_for_tx(); + LOG_INFO("[TRANSFER] transfer out delete tablet commit", KPC(this)); +} + +void ObTabletCreateDeleteMdsUserData::start_transfer_out_on_commit_( + const share::SCN &commit_version) +{ + transfer_out_commit_version_ = commit_version.get_val_for_tx(); + LOG_INFO("[TRANSFER] transfer out on commit", KPC(this)); +} + +int ObTabletCreateDeleteMdsUserData::set_tablet_gc_trigger( + const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObLSService *ls_service = MTL(ObLSService*); + if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::MDS_TABLE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id), K(ls_handle)); + } else { + ls->get_tablet_gc_handler()->set_tablet_gc_trigger(); + } + return ret; +} + +int ObTabletCreateDeleteMdsUserData::set_tablet_empty_shell_trigger( + const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObLSService *ls_service = MTL(ObLSService*); + if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::MDS_TABLE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id), K(ls_handle)); + } else { + ls->get_tablet_empty_shell_handler()->set_empty_shell_trigger(true); + LOG_INFO("set_tablet_empty_shell_trigger", K(ls_id), "handler", ls->get_tablet_empty_shell_handler()); + } + return ret; +} + +OB_SERIALIZE_MEMBER( + ObTabletCreateDeleteMdsUserData, + tablet_status_, + transfer_scn_, + transfer_ls_id_, + data_type_, + create_commit_scn_, + create_commit_version_, + delete_commit_scn_, + delete_commit_version_, + transfer_out_commit_version_) +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_create_delete_mds_user_data.h b/src/storage/tablet/ob_tablet_create_delete_mds_user_data.h new file mode 100644 index 000000000..9016f4d17 --- /dev/null +++ b/src/storage/tablet/ob_tablet_create_delete_mds_user_data.h @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_CREATE_DELETE_MDS_USER_DATA +#define OCEANBASE_STORAGE_OB_TABLET_CREATE_DELETE_MDS_USER_DATA + +#include +#include "lib/utility/ob_print_utils.h" +#include "share/scn.h" +#include "share/ob_ls_id.h" +#include "storage/tablet/ob_tablet_status.h" +#include "storage/tablet/ob_tablet_common.h" + +namespace oceanbase +{ +namespace storage +{ + +enum class ObTabletMdsUserDataType : int64_t +{ + NONE = 0, + //for create tablet + CREATE_TABLET = 1, + //for drop tablet + REMOVE_TABLET = 2, + //for start transfer out + START_TRANSFER_OUT = 3, + //for start transfer in + START_TRANSFER_IN = 4, + //for finish transfer out + FINISH_TRANSFER_OUT = 5, + // for finish transfer in + FINISH_TRANSFER_IN = 6, + MAX_TYPE, +}; + +class ObTabletCreateDeleteMdsUserData +{ + OB_UNIS_VERSION(1); +public: + ObTabletCreateDeleteMdsUserData(); + ~ObTabletCreateDeleteMdsUserData() = default; + ObTabletCreateDeleteMdsUserData(const ObTabletStatus::Status &status, const ObTabletMdsUserDataType type); + ObTabletCreateDeleteMdsUserData(const ObTabletCreateDeleteMdsUserData &) = delete; + ObTabletCreateDeleteMdsUserData &operator=(const ObTabletCreateDeleteMdsUserData &) = delete; +public: + void reset(); + bool is_valid() const; + int assign(const ObTabletCreateDeleteMdsUserData &other); + + ObTabletStatus get_tablet_status() const; + share::SCN get_create_scn() const; + void on_redo(const share::SCN &redo_scn); + void on_commit(const share::SCN &commit_version, const share::SCN &commit_scn); + // todo(zk250686): tablet shell + static int set_tablet_gc_trigger(const share::ObLSID &ls_id); + static int set_tablet_empty_shell_trigger(const share::ObLSID &ls_id); + + TO_STRING_KV(K_(tablet_status), K_(transfer_scn), + K_(transfer_ls_id), K_(data_type), + K_(create_commit_scn), K_(create_commit_version), + K_(delete_commit_scn), K_(delete_commit_version), K_(transfer_out_commit_version)); +private: + void start_transfer_out_on_redo_(const share::SCN &redo_scn); + void finish_transfer_in_on_redo_(const share::SCN &redo_scn); + void create_tablet_on_commit_(const share::SCN &commit_version, const share::SCN &commit_scn); + void start_transfer_in_on_commit_(const share::SCN &commit_version, const share::SCN &commit_scn); + + void delete_tablet_on_commit_(const share::SCN &commit_version, const share::SCN &commit_scn); + void finish_transfer_out_on_commit_(const share::SCN &commit_version, const share::SCN &commit_scn); + void start_transfer_out_on_commit_(const share::SCN &commit_version); +public: + ObTabletStatus tablet_status_; + share::SCN transfer_scn_; + share::ObLSID transfer_ls_id_; + ObTabletMdsUserDataType data_type_; + + // create_commit_scn_ remain unchanged throughout the entire tablet lifecycle + share::SCN create_commit_scn_; // tablet's first create tx commit log scn, set this in create_tablet_on_commit_ + int64_t create_commit_version_; // create tx commit trans version + share::SCN delete_commit_scn_; // delete tx commit log scn + int64_t delete_commit_version_; // delete tx commit trans version + int64_t transfer_out_commit_version_; //transfer out commit trans version +}; + +inline bool ObTabletCreateDeleteMdsUserData::is_valid() const +{ + return tablet_status_.is_valid() + && data_type_ >= ObTabletMdsUserDataType::NONE + && data_type_ < ObTabletMdsUserDataType::MAX_TYPE; +} + +inline ObTabletStatus ObTabletCreateDeleteMdsUserData::get_tablet_status() const +{ + return tablet_status_; +} + +inline share::SCN ObTabletCreateDeleteMdsUserData::get_create_scn() const +{ + return create_commit_scn_; +} + +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_CREATE_DELETE_MDS_USER_DATA diff --git a/src/storage/tablet/ob_tablet_create_mds_helper.cpp b/src/storage/tablet/ob_tablet_create_mds_helper.cpp new file mode 100644 index 000000000..f277127bb --- /dev/null +++ b/src/storage/tablet/ob_tablet_create_mds_helper.cpp @@ -0,0 +1,974 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_create_mds_helper.h" +#include "common/ob_tablet_id.h" +#include "share/scn.h" +#include "share/ob_ls_id.h" +#include "share/ob_rpc_struct.h" +#include "share/schema/ob_table_schema.h" +#include "storage/ls/ob_ls_get_mod.h" +#include "storage/multi_data_source/buffer_ctx.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/meta_mem/ob_tablet_map_key.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "logservice/replayservice/ob_tablet_replay_executor.h" + +#define USING_LOG_PREFIX MDS +#define PRINT_CREATE_ARG(arg) (ObSimpleBatchCreateTabletArg(arg)) + +using namespace oceanbase::common; +using namespace oceanbase::share; +using namespace oceanbase::obrpc; + +namespace oceanbase +{ +namespace storage +{ +class ObTabletCreateReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObTabletCreateReplayExecutor(); + + int init( + mds::BufferCtx &user_ctx, + const share::SCN &scn); + +protected: + bool is_replay_update_user_data_() const override + { + return true; + } + + int do_replay_(ObTabletHandle &tablet_handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return true; + } + +private: + mds::BufferCtx *user_ctx_; + share::SCN scn_; +}; + + +ObTabletCreateReplayExecutor::ObTabletCreateReplayExecutor() + :logservice::ObTabletReplayExecutor(), user_ctx_(nullptr) +{} + +int ObTabletCreateReplayExecutor::init( + mds::BufferCtx &user_ctx, + const share::SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("tablet create replay executor init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid argument", KR(ret), K(scn)); + } else { + user_ctx_ = &user_ctx; + scn_ = scn; + is_inited_ = true; + } + return ret; +} + +int ObTabletCreateReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + mds::MdsCtx &user_ctx = static_cast(*user_ctx_); + ObTabletCreateDeleteMdsUserData user_data(ObTabletStatus::NORMAL, ObTabletMdsUserDataType::CREATE_TABLET); + + if (OB_FAIL(replay_to_mds_table_(tablet_handle, user_data, user_ctx, scn_))) { + LOG_WARN("failed to replay to tablet", K(ret)); + } + + return ret; +} + +int ObTabletCreateMdsHelper::on_commit_for_old_mds( + const char* buf, + const int64_t len, + const transaction::ObMulSourceDataNotifyArg ¬ify_arg) +{ + return ObTabletCreateDeleteHelper::process_for_old_mds(buf, len, notify_arg); +} + +int ObTabletCreateMdsHelper::register_process( + const ObBatchCreateTabletArg &arg, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + bool valid = false; + common::ObSArray tablet_id_array; + if (CLICK_FAIL(tablet_id_array.reserve(arg.get_tablet_count()))) { + LOG_WARN("failed to reserve memory", K(ret), "capacity", arg.get_tablet_count()); + } else if (CLICK_FAIL(check_create_arg(arg, valid))) { + LOG_WARN("failed to check tablet arg", K(ret), K(arg)); + } else if (OB_UNLIKELY(!valid)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, arg is not valid", K(ret), K(arg)); + } else if (CLICK_FAIL(create_tablets(arg, false/*for_replay*/, share::SCN::invalid_scn(), ctx, tablet_id_array))) { + LOG_WARN("failed to create tablets", K(ret), K(arg)); + + // roll back + int tmp_ret = OB_SUCCESS; + if (CLICK() && OB_TMP_FAIL(roll_back_remove_tablets(arg.id_, tablet_id_array))) { + LOG_ERROR("failed to roll back remove tablets", K(tmp_ret)); + ob_usleep(1 * 1000 * 1000); + ob_abort(); + } + } else if (CLICK_FAIL(ObTabletCreateDeleteMdsUserData::set_tablet_gc_trigger(arg.id_))) { + LOG_WARN("failed to set tablet gc trigger", K(ret)); + } + + if (OB_SUCC(ret) && OB_FAIL(ObTabletBindingHelper::modify_tablet_binding_for_new_mds_create(arg, SCN::invalid_scn(), ctx))) { + LOG_WARN("failed to modify tablet binding", K(ret)); + } + LOG_INFO("create tablet register", KR(ret), K(arg)); + return ret; +} + +int ObTabletCreateMdsHelper::on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObBatchCreateTabletArg arg; + int64_t pos = 0; + + if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(buf), K(len)); + } else if (CLICK_FAIL(arg.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("arg is invalid", K(ret), K(PRINT_CREATE_ARG(arg))); + } else if (arg.is_old_mds_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, arg is old mds", K(ret), K(arg)); + } else if (CLICK_FAIL(check_create_new_tablets(arg))) { + LOG_WARN("failed to check crate new tablets", K(ret), K(PRINT_CREATE_ARG(arg))); + } else if (CLICK_FAIL(register_process(arg, ctx))) { + LOG_WARN("fail to register_process", K(ret), K(PRINT_CREATE_ARG(arg))); + } + return ret; +} + +int ObTabletCreateMdsHelper::on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObBatchCreateTabletArg arg; + int64_t pos = 0; + common::ObSArray tablet_id_array; + const ObLSID &ls_id = arg.id_; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + share::SCN tablet_change_checkpoint_scn; + + if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0) || OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(buf), K(len), K(scn)); + } else if (CLICK_FAIL(arg.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("arg is invalid", K(ret), K(PRINT_CREATE_ARG(arg))); + } else if (arg.is_old_mds_) { + LOG_INFO("skip replay create tablet for old mds", K(arg), K(scn)); + } else if (CLICK_FAIL(tablet_id_array.reserve(arg.get_tablet_count()))) { + LOG_WARN("failed to reserve memory", K(ret), "capacity", arg.get_tablet_count()); + } else if (CLICK_FAIL(get_ls(ls_id, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id), K(ls_handle)); + } else if (FALSE_IT(tablet_change_checkpoint_scn = ls->get_tablet_change_checkpoint_scn())) { + } else if (scn <= tablet_change_checkpoint_scn) { + LOG_INFO("current scn is smaller than ls tablet change check point scn, log replaying can be skipped", + K(ret), K(scn), K(tablet_change_checkpoint_scn)); + } else if (CLICK_FAIL(create_tablets(arg, true/*for_replay*/, scn, ctx, tablet_id_array))) { + LOG_WARN("failed to create tablets", K(ret), K(arg), K(scn)); + } else if (CLICK_FAIL(ObTabletBindingHelper::modify_tablet_binding_for_new_mds_create(arg, scn, ctx))) { + LOG_WARN("failed to modify tablet binding", K(ret)); + } else if (CLICK_FAIL(ObTabletCreateDeleteMdsUserData::set_tablet_gc_trigger(ls_id))) { + LOG_WARN("failed to trigger tablet gc task", K(ret)); + } + + if (CLICK_FAIL(ret)) { + // roll back + int tmp_ret = OB_SUCCESS; + if (CLICK() && OB_TMP_FAIL(roll_back_remove_tablets(arg.id_, tablet_id_array))) { + LOG_ERROR("failed to roll back remove tablets", K(tmp_ret)); + ob_usleep(1 * 1000 * 1000); + ob_abort(); + } + } + LOG_INFO("create tablet replay", KR(ret), K(arg), K(scn)); + + return ret; +} + +int ObTabletCreateMdsHelper::check_create_new_tablets(const obrpc::ObBatchCreateTabletArg &arg) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + ObUnitInfoGetter::ObTenantConfig unit; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + int64_t tablet_cnt_per_gb = 20000; // default value + bool skip_check = !arg.need_check_tablet_cnt_; + + // skip hidden tablet creation or truncate tablet creation + for (int64_t i = 0; OB_SUCC(ret) && !skip_check && i < arg.table_schemas_.count(); ++i) { + if (arg.table_schemas_[i].is_user_hidden_table() + || OB_INVALID_VERSION != arg.table_schemas_[i].get_truncate_version()) { + skip_check = true; + } + } + + if (OB_FAIL(ret)) { + } else if (skip_check) { + } else { + { + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); + if (OB_UNLIKELY(!tenant_config.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("get invalid tenant config", K(ret)); + } else { + tablet_cnt_per_gb = tenant_config->_max_tablet_cnt_per_gb; + } + } + + if (FAILEDx(GCTX.omt_->get_tenant_unit(tenant_id, unit))) { + if (OB_TENANT_NOT_IN_SERVER != ret) { + LOG_WARN("failed to get tenant unit", K(ret), K(tenant_id)); + } else { + // during restart, tenant unit not ready, skip check + ret = OB_SUCCESS; + } + } else { + const double memory_limit = unit.config_.memory_size(); + const int64_t max_tablet_cnt = memory_limit / (1 << 30) * tablet_cnt_per_gb; + const int64_t cur_tablet_cnt = t3m->get_total_tablet_cnt(); + const int64_t inc_tablet_cnt = arg.get_tablet_count(); + + if (OB_UNLIKELY(cur_tablet_cnt + inc_tablet_cnt >= max_tablet_cnt)) { + ret = OB_TOO_MANY_PARTITIONS_ERROR; + LOG_WARN("too many partitions of tenant", K(ret), K(tenant_id), K(memory_limit), K(tablet_cnt_per_gb), + K(max_tablet_cnt), K(cur_tablet_cnt), K(inc_tablet_cnt)); + } + } + } + + return ret; +} + +int ObTabletCreateMdsHelper::check_create_arg( + const obrpc::ObBatchCreateTabletArg &arg, + bool &valid) +{ + int ret = OB_SUCCESS; + valid = true; + const ObLSID &ls_id = arg.id_; + int64_t aux_info_idx = -1; + ObSArray aux_info_idx_array; + + for (int64_t i = 0; OB_SUCC(ret) && valid && i < arg.tablets_.count(); ++i) { + const ObCreateTabletInfo &info = arg.tablets_.at(i); + const ObTabletID &data_tablet_id = info.data_tablet_id_; + if (is_contain(aux_info_idx_array, i)) { + // do nothing + } else if (is_pure_data_tablets(info) || is_mixed_tablets(info)) { + if (OB_FAIL(check_pure_data_or_mixed_tablets_info(ls_id, info, valid))) { + LOG_WARN("failed to check create tablet info", K(ret), K(ls_id), K(info)); + } + } else if (is_pure_aux_tablets(info)) { + if (OB_FAIL(check_pure_aux_tablets_info(ls_id, info, valid))) { + LOG_WARN("failed to check create tablet info", K(ret), K(ls_id), K(info)); + } + } else if (is_hidden_tablets(info)) { + for (int64_t i = 0; OB_SUCC(ret) && i < info.tablet_ids_.count(); ++i) { + const ObTabletID &tablet_id = info.tablet_ids_.at(i); + bool has_related_aux_info = find_aux_info_for_hidden_tablets(arg, tablet_id, aux_info_idx); + if (has_related_aux_info) { + const ObCreateTabletInfo &aux_info = arg.tablets_.at(aux_info_idx); + if (OB_FAIL(check_hidden_tablets_info(ls_id, info, &aux_info, valid))) { + LOG_WARN("failed to check create tablet info", K(ret), K(ls_id), K(info), K(aux_info)); + } else if (OB_FAIL(aux_info_idx_array.push_back(aux_info_idx))) { + LOG_WARN("failed to push back aux info idx", K(ret)); + } + } else if (OB_FAIL(check_hidden_tablets_info(ls_id, info, nullptr/*aux_info*/, valid))) { + LOG_WARN("failed to check create tablet info", K(ret), K(ls_id), K(info)); + } + } + } + } + + return ret; +} + +int ObTabletCreateMdsHelper::create_tablets( + const obrpc::ObBatchCreateTabletArg &arg, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array) +{ + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + + for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablets_.count(); ++i) { + const ObCreateTabletInfo &info = arg.tablets_.at(i); + if (is_pure_data_tablets(info)) { + if (CLICK_FAIL(build_pure_data_tablet(arg, info, for_replay, scn, ctx, tablet_id_array))) { + LOG_WARN("failed to build pure data tablet", K(ret), K(info)); + } + } else if (is_mixed_tablets(info)) { + if (CLICK_FAIL(build_mixed_tablets(arg, info, for_replay, scn, ctx, tablet_id_array))) { + LOG_WARN("failed to build mixed tablets", K(ret), K(info)); + } + } else if (is_pure_aux_tablets(info)) { + if (CLICK_FAIL(build_pure_aux_tablets(arg, info, for_replay, scn, ctx, tablet_id_array))) { + LOG_WARN("failed to build pure aux tablets", K(ret), K(info)); + } + } else if (is_hidden_tablets(info)) { + if (CLICK_FAIL(build_hidden_tablets(arg, info, for_replay, scn, ctx, tablet_id_array))) { + LOG_WARN("failed to build hidden tablets", K(ret), K(info)); + } + } + } + + return ret; +} + +int ObTabletCreateMdsHelper::get_table_schema_index( + const common::ObTabletID &tablet_id, + const common::ObIArray &tablet_ids, + int64_t &index) +{ + int ret = OB_SUCCESS; + bool match = false; + + for (int64_t i = 0; !match && i < tablet_ids.count(); ++i) { + if (tablet_ids.at(i) == tablet_id) { + index = i; + match = true; + } + } + + if (OB_UNLIKELY(!match)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("cannot find target tablet id in array", K(ret), K(tablet_id)); + } + + return ret; +} + +bool ObTabletCreateMdsHelper::is_pure_data_tablets(const obrpc::ObCreateTabletInfo &info) +{ + const ObTabletID &data_tablet_id = info.data_tablet_id_; + const ObSArray &tablet_ids = info.tablet_ids_; + return tablet_ids.count() == 1 && is_contain(tablet_ids, data_tablet_id) && !info.is_create_bind_hidden_tablets_; +} + +bool ObTabletCreateMdsHelper::is_mixed_tablets(const obrpc::ObCreateTabletInfo &info) +{ + const ObTabletID &data_tablet_id = info.data_tablet_id_; + const ObSArray &tablet_ids = info.tablet_ids_; + return tablet_ids.count() >= 1 && is_contain(tablet_ids, data_tablet_id) && !info.is_create_bind_hidden_tablets_; +} + +bool ObTabletCreateMdsHelper::is_pure_aux_tablets(const obrpc::ObCreateTabletInfo &info) +{ + const ObTabletID &data_tablet_id = info.data_tablet_id_; + const ObSArray &tablet_ids = info.tablet_ids_; + return tablet_ids.count() >= 1 && !is_contain(tablet_ids, data_tablet_id) && !info.is_create_bind_hidden_tablets_; +} + +bool ObTabletCreateMdsHelper::is_hidden_tablets(const obrpc::ObCreateTabletInfo &info) +{ + const ObTabletID &data_tablet_id = info.data_tablet_id_; + const ObSArray &tablet_ids = info.tablet_ids_; + return tablet_ids.count() >= 1 && !is_contain(tablet_ids, data_tablet_id) && info.is_create_bind_hidden_tablets_; +} + +int ObTabletCreateMdsHelper::check_pure_data_or_mixed_tablets_info( + const share::ObLSID &ls_id, + const obrpc::ObCreateTabletInfo &info, + bool &valid) +{ + int ret = OB_SUCCESS; + bool exist = false; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTabletMapKey key; + key.ls_id_ = ls_id; + + for (int64_t i = 0; OB_SUCC(ret) && !exist && i < info.tablet_ids_.count(); ++i) { + const ObTabletID &tablet_id = info.tablet_ids_[i]; + key.tablet_id_ = tablet_id; + if (OB_FAIL(t3m->has_tablet(key, exist))) { + LOG_WARN("failed to check tablet existence", K(ret), K(key)); + } else if (OB_UNLIKELY(exist)) { + LOG_WARN("unexpected tablet existence", K(ret), K(key), K(exist)); + } + } + + if (OB_FAIL(ret)) { + } else { + valid = !exist; + } + + return ret; +} + +int ObTabletCreateMdsHelper::check_pure_aux_tablets_info( + const share::ObLSID &ls_id, + const obrpc::ObCreateTabletInfo &info, + bool &valid) +{ + int ret = OB_SUCCESS; + bool exist = false; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTabletMapKey key; + key.ls_id_ = ls_id; + + for (int64_t i = 0; OB_SUCC(ret) && !exist && i < info.tablet_ids_.count(); ++i) { + const ObTabletID &tablet_id = info.tablet_ids_[i]; + key.tablet_id_ = tablet_id; + if (OB_FAIL(t3m->has_tablet(key, exist))) { + LOG_WARN("failed to check tablet existence", K(ret), K(key)); + } else if (OB_UNLIKELY(exist)) { + LOG_WARN("unexpected tablet existence", K(ret), K(key), K(exist)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(exist)) { + valid = false; + } else { + key.tablet_id_ = info.data_tablet_id_; + if (OB_FAIL(t3m->has_tablet(key, exist))) { + LOG_WARN("failed to check tablet existence", K(ret), K(key)); + } else if (OB_UNLIKELY(!exist)) { + valid = false; + LOG_WARN("data tablet does not exist", K(ret), K(key)); + } else { + valid = true; + } + } + + return ret; +} + +int ObTabletCreateMdsHelper::check_hidden_tablets_info( + const share::ObLSID &ls_id, + const obrpc::ObCreateTabletInfo &hidden_info, + const obrpc::ObCreateTabletInfo *aux_info, + bool &valid) +{ + int ret = OB_SUCCESS; + bool exist = false; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTabletMapKey key; + key.ls_id_ = ls_id; + + for (int64_t i = 0; OB_SUCC(ret) && !exist && i < hidden_info.tablet_ids_.count(); ++i) { + const ObTabletID &tablet_id = hidden_info.tablet_ids_[i]; + key.tablet_id_ = tablet_id; + if (OB_FAIL(t3m->has_tablet(key, exist))) { + LOG_WARN("failed to check tablet existence", K(ret), K(key)); + } else if (OB_UNLIKELY(exist)) { + LOG_WARN("unexpected tablet existence", K(ret), K(key), K(exist)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(exist)) { + valid = false; + } else { + key.tablet_id_ = hidden_info.data_tablet_id_; + if (OB_FAIL(t3m->has_tablet(key, exist))) { + LOG_WARN("failed to check tablet existence", K(ret), K(key)); + } else if (OB_UNLIKELY(!exist)) { + valid = false; + LOG_WARN("data tablet does not exist", K(ret), K(key)); + } else { + valid = true; + } + } + + if (OB_FAIL(ret)) { + } else if (!valid) { + } else if (nullptr != aux_info) { + exist = false; + for (int64_t i = 0; OB_SUCC(ret) && !exist && i < aux_info->tablet_ids_.count(); ++i) { + key.tablet_id_ = aux_info->tablet_ids_[i]; + if (OB_FAIL(t3m->has_tablet(key, exist))) { + LOG_WARN("failed to check tablet existence", K(ret), K(key)); + } else if (OB_UNLIKELY(exist)) { + LOG_WARN("unexpected tablet existence", K(ret), K(key), K(exist)); + } + } + + if (OB_FAIL(ret)) { + } else { + valid = !exist; + } + } + + return ret; +} + +bool ObTabletCreateMdsHelper::find_aux_info_for_hidden_tablets( + const obrpc::ObBatchCreateTabletArg &arg, + const common::ObTabletID &tablet_id, + int64_t &aux_info_idx) +{ + bool found = false; + + for (int64_t i = 0; !found && i < arg.tablets_.count(); ++i) { + const ObCreateTabletInfo &info = arg.tablets_.at(i); + if (is_pure_aux_tablets(info) && tablet_id == info.data_tablet_id_) { + aux_info_idx = i; + found = true; + } + } + + return found; +} + +int ObTabletCreateMdsHelper::build_pure_data_tablet( + const obrpc::ObBatchCreateTabletArg &arg, + const obrpc::ObCreateTabletInfo &info, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array) +{ + MDS_TG(5_ms); + int ret = OB_SUCCESS; + const ObLSID &ls_id = arg.id_; + const ObTabletID &data_tablet_id = info.data_tablet_id_; + const ObSArray &table_schemas = arg.table_schemas_; + const lib::Worker::CompatMode &compat_mode = info.compat_mode_; + const int64_t snapshot_version = arg.major_frozen_scn_.get_val_for_tx(); + ObTabletHandle tablet_handle; + bool exist = false; + int64_t index = -1; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + + if (for_replay) { + const ObTabletMapKey key(ls_id, data_tablet_id); + if (CLICK_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + exist = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(ls_id), K(data_tablet_id)); + } + } else { + exist = true; + } + } + + if (CLICK_FAIL(ret)) { + } else if (for_replay && exist) { + LOG_INFO("create pure data tablet is already exist, skip it", K(for_replay), K(exist), + K(ls_id), K(data_tablet_id)); + } else if (CLICK_FAIL(get_table_schema_index(data_tablet_id, info.tablet_ids_, index))) { + LOG_WARN("failed to get table schema index", K(ret), K(ls_id), K(data_tablet_id)); + } else if (OB_UNLIKELY(index < 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, table schema index is invalid", K(ret), K(ls_id), K(data_tablet_id), K(index)); + } else if (CLICK_FAIL(get_ls(ls_id, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id), K(ls_handle)); + } else if (CLICK_FAIL(tablet_id_array.push_back(data_tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret), K(ls_id), K(data_tablet_id)); + } else if (CLICK_FAIL(ls->get_tablet_svr()->create_tablet(ls_id, data_tablet_id, data_tablet_id, + scn, snapshot_version, table_schemas[info.table_schema_index_[index]], compat_mode, + tablet_handle))) { + LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(data_tablet_id), K(PRINT_CREATE_ARG(arg))); + } + + if (OB_FAIL(ret)) { + } else if (CLICK_FAIL(set_tablet_normal_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx))) { + LOG_WARN("failed to set tablet normal status", K(ret), K(ls_id), K(data_tablet_id)); + } + + return ret; +} + +int ObTabletCreateMdsHelper::build_mixed_tablets( + const obrpc::ObBatchCreateTabletArg &arg, + const obrpc::ObCreateTabletInfo &info, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + const ObLSID &ls_id = arg.id_; + const ObTabletID &data_tablet_id = info.data_tablet_id_; + const ObSArray &tablet_ids = info.tablet_ids_; + const ObSArray &table_schemas = arg.table_schemas_; + const lib::Worker::CompatMode &compat_mode = info.compat_mode_; + const int64_t snapshot_version = arg.major_frozen_scn_.get_val_for_tx(); + ObTabletHandle data_tablet_handle; + ObTabletHandle tablet_handle; + ObTabletID lob_meta_tablet_id; + ObTabletID lob_piece_tablet_id; + bool exist = false; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + + if (CLICK_FAIL(get_ls(ls_id, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id), K(ls_handle)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { + MDS_TG(5_ms); + exist = false; + const ObTabletID &tablet_id = tablet_ids[i]; + const share::schema::ObTableSchema &table_schema = table_schemas[info.table_schema_index_[i]]; + if (table_schema.is_aux_lob_meta_table()) { + lob_meta_tablet_id = tablet_id; + } else if (table_schema.is_aux_lob_piece_table()) { + lob_piece_tablet_id = tablet_id; + } + + if (for_replay) { + const ObTabletMapKey key(ls_id, tablet_id); + if (CLICK_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + exist = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(ls_id), K(data_tablet_id), K(tablet_id)); + } + } else { + exist = true; + } + } + + if (OB_FAIL(ret)) { + } else if (for_replay && exist) { + LOG_INFO("tablet already exists in replay procedure, skip it", K(ret), K(ls_id), K(tablet_id)); + } else if (CLICK_FAIL(tablet_id_array.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret), K(ls_id), K(tablet_id)); + } else if (CLICK_FAIL(ls->get_tablet_svr()->create_tablet(ls_id, tablet_id, data_tablet_id, + scn, snapshot_version, table_schema, compat_mode, tablet_handle))) { + LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), K(PRINT_CREATE_ARG(arg))); + } + + if (OB_FAIL(ret)) { + } else if (CLICK_FAIL(set_tablet_normal_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx))) { + LOG_WARN("failed to set tablet normal status", K(ret), K(ls_id), K(tablet_id)); + } + + if (OB_FAIL(ret)) { + } else if (tablet_id == data_tablet_id) { + data_tablet_handle = tablet_handle; + } + } + + if (OB_FAIL(ret)) { + } else if (lob_meta_tablet_id.is_valid() || lob_piece_tablet_id.is_valid()) { + // process lob meta/piece tablet + ObTablet *data_tablet = data_tablet_handle.get_obj(); + if (OB_ISNULL(data_tablet)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("data tablet is null", K(ret), K(ls_id), K(data_tablet_id)); + } else { + // binding info + } + } + + return ret; +} + +int ObTabletCreateMdsHelper::build_pure_aux_tablets( + const obrpc::ObBatchCreateTabletArg &arg, + const obrpc::ObCreateTabletInfo &info, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + const ObLSID &ls_id = arg.id_; + const ObTabletID &data_tablet_id = info.data_tablet_id_; + const ObSArray &tablet_ids = info.tablet_ids_; + const ObSArray &table_schemas = arg.table_schemas_; + const lib::Worker::CompatMode &compat_mode = info.compat_mode_; + const int64_t snapshot_version = arg.major_frozen_scn_.get_val_for_tx(); + ObTabletHandle tablet_handle; + bool exist = false; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + + if (CLICK_FAIL(get_ls(ls_id, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id), K(ls_handle)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { + MDS_TG(5_ms); + exist = false; + const ObTabletID &tablet_id = tablet_ids[i]; + const share::schema::ObTableSchema &table_schema = table_schemas[info.table_schema_index_[i]]; + + if (for_replay) { + const ObTabletMapKey key(ls_id, tablet_id); + if (CLICK_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + exist = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(ls_id), K(data_tablet_id)); + } + } else { + exist = true; + } + } + + if (OB_FAIL(ret)) { + } else if (for_replay && exist) { + LOG_INFO("create pure aux tablet is already exist, skip it", K(for_replay), K(exist), + K(ls_id), K(data_tablet_id), K(tablet_id)); + } else if (CLICK_FAIL(tablet_id_array.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret), K(ls_id), K(tablet_id)); + } else if (CLICK_FAIL(ls->get_tablet_svr()->create_tablet(ls_id, tablet_id, data_tablet_id, + scn, snapshot_version, table_schema, compat_mode, tablet_handle))) { + LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), K(PRINT_CREATE_ARG(arg))); + } + + if (OB_FAIL(ret)) { + } else if (CLICK_FAIL(set_tablet_normal_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx))) { + LOG_WARN("failed to set tablet normal status", K(ret), K(ls_id), K(tablet_id)); + } + } + + // process lob meta/piece tablet + + return ret; +} + +int ObTabletCreateMdsHelper::build_hidden_tablets( + const obrpc::ObBatchCreateTabletArg &arg, + const obrpc::ObCreateTabletInfo &info, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + const ObLSID &ls_id = arg.id_; + const ObTabletID &data_tablet_id = info.data_tablet_id_; + const ObSArray &tablet_ids = info.tablet_ids_; + const ObSArray &table_schemas = arg.table_schemas_; + const lib::Worker::CompatMode &compat_mode = info.compat_mode_; + const int64_t snapshot_version = arg.major_frozen_scn_.get_val_for_tx(); + ObTabletHandle tablet_handle; + int64_t aux_info_idx = -1; + ObTabletID lob_meta_tablet_id; + ObTabletID lob_piece_tablet_id; + bool exist = false; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + + if (CLICK_FAIL(get_ls(ls_id, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id), K(ls_handle)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { + MDS_TG(5_ms); + exist = false; + lob_meta_tablet_id.reset(); + lob_piece_tablet_id.reset(); + const ObTabletID &tablet_id = tablet_ids[i]; + const share::schema::ObTableSchema &table_schema = table_schemas[info.table_schema_index_[i]]; + bool has_related_aux_info = find_aux_info_for_hidden_tablets(arg, tablet_id, aux_info_idx); + if (has_related_aux_info) { + const ObCreateTabletInfo &aux_info = arg.tablets_.at(aux_info_idx); + for (int64_t j = 0; j < aux_info.tablet_ids_.count(); ++j) { + const int64_t table_schema_index = aux_info.table_schema_index_.at(j); + const share::schema::ObTableSchema &aux_table_schema = table_schemas[table_schema_index]; + if (aux_table_schema.is_aux_lob_meta_table()) { + lob_meta_tablet_id = aux_info.tablet_ids_.at(j); + } else if (aux_table_schema.is_aux_lob_piece_table()) { + lob_piece_tablet_id = aux_info.tablet_ids_.at(j); + } + } + } + + if (for_replay) { + const ObTabletMapKey key(ls_id, tablet_id); + if (CLICK_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + exist = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(ls_id), K(data_tablet_id), K(tablet_id)); + } + } else { + exist = true; + } + } + + if (OB_FAIL(ret)) { + } else if (for_replay && exist) { + LOG_INFO("create hidden tablet is already exist, skip it", K(for_replay), K(exist), + K(ls_id), K(data_tablet_id), K(tablet_id)); + } else if (CLICK_FAIL(tablet_id_array.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret), K(ls_id), K(tablet_id)); + } else if (CLICK_FAIL(ls->get_tablet_svr()->create_tablet(ls_id, tablet_id, data_tablet_id, + scn, snapshot_version, table_schema, compat_mode, tablet_handle))) { + LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), K(PRINT_CREATE_ARG(arg))); + } + + if (OB_FAIL(ret)) { + } else if (CLICK_FAIL(set_tablet_normal_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx))) { + LOG_WARN("failed to set tablet normal status", K(ret), K(ls_id), K(tablet_id)); + } + + // process lob meta/piece tablet + } + + return ret; +} + +int ObTabletCreateMdsHelper::roll_back_remove_tablets( + const share::ObLSID &ls_id, + const common::ObIArray &tablet_id_array) +{ + MDS_TG(100_ms); + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObTabletMapKey key; + key.ls_id_ = ls_id; + + if (CLICK_FAIL(get_ls(ls_id, ls_handle))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id), K(ls_handle)); + } else { + ObTabletIDSet &tablet_id_set = ls->get_tablet_svr()->tablet_id_set_; + + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_id_array.count(); ++i) { + MDS_TG(10_ms); + key.tablet_id_ = tablet_id_array.at(i); + if (CLICK_FAIL(ls->get_tablet_svr()->do_remove_tablet(key))) { + LOG_WARN("failed to delete tablet", K(ret), K(key)); + } else if (CLICK_FAIL(tablet_id_set.erase(key.tablet_id_))) { + if (OB_HASH_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_DEBUG("tablet id does not exist, maybe has not been inserted yet", K(ret), K(key)); + } else { + LOG_WARN("failed to erase tablet id", K(ret), K(key)); + } + } + } + } + + return ret; +} + +int ObTabletCreateMdsHelper::get_ls( + const share::ObLSID &ls_id, + ObLSHandle &ls_handle) +{ + int ret = OB_SUCCESS; + ObLSService *ls_service = MTL(ObLSService*); + + if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::MDS_TABLE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } + + return ret; +} + +int ObTabletCreateMdsHelper::set_tablet_normal_status( + ObLSTabletService *ls_tablet_service, + ObTabletHandle &tablet_handle, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + MDS_TG(5_ms); + int ret = OB_SUCCESS; + ObTablet *tablet = tablet_handle.get_obj(); + mds::MdsCtx &user_ctx = static_cast(ctx); + ObTabletCreateDeleteMdsUserData data(ObTabletStatus::NORMAL, ObTabletMdsUserDataType::CREATE_TABLET); + + if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(tablet_handle)); + } else if (OB_UNLIKELY(for_replay && !scn.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("scn is invalid", K(ret), + "ls_id", tablet->get_tablet_meta().ls_id_, + "tablet_id", tablet->get_tablet_meta().tablet_id_, + K(for_replay), K(scn)); + } else if (for_replay) { + ObTabletCreateReplayExecutor replay_executor; + const share::ObLSID &ls_id = tablet->get_tablet_meta().ls_id_; + const common::ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; + if (CLICK_FAIL(replay_executor.init(ctx, scn))) { + LOG_WARN("failed to init replay executor", K(ret)); + } else if (CLICK_FAIL(replay_executor.execute(scn, ls_id, tablet_id))) { + LOG_WARN("failed to replay mds data", K(ret)); + } + } else if (CLICK_FAIL(ls_tablet_service->set_tablet_status(tablet->get_tablet_meta().tablet_id_, data, user_ctx))) { + LOG_WARN("failed to set mds data", K(ret)); + } + + return ret; +} +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_create_mds_helper.h b/src/storage/tablet/ob_tablet_create_mds_helper.h new file mode 100644 index 000000000..f19874555 --- /dev/null +++ b/src/storage/tablet/ob_tablet_create_mds_helper.h @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_CREATE_MDS_HELPER +#define OCEANBASE_STORAGE_OB_TABLET_CREATE_MDS_HELPER + +#include +#include "lib/worker.h" +#include "lib/container/ob_iarray.h" +#include "storage/tx/ob_trans_define.h" + +namespace oceanbase +{ +namespace share +{ +namespace schema +{ +class ObTableSchema; +} + +class ObLSID; +class SCN; +} + +namespace common +{ +class ObTabletID; +} + +namespace obrpc +{ +struct ObBatchCreateTabletArg; +struct ObCreateTabletInfo; +} + +namespace storage +{ +namespace mds +{ +struct BufferCtx; +} + +class ObLSHandle; +class ObTabletHandle; +class ObLSTabletService; + +class ObTabletCreateMdsHelper +{ +public: + static int on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx); + static int on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx); + static int on_commit_for_old_mds( + const char* buf, + const int64_t len, + const transaction::ObMulSourceDataNotifyArg &arg); + static int register_process( + const obrpc::ObBatchCreateTabletArg &arg, + mds::BufferCtx &ctx); +private: + static int check_create_new_tablets(const obrpc::ObBatchCreateTabletArg &arg); + static int check_create_arg( + const obrpc::ObBatchCreateTabletArg &arg, + bool &valid); + static int create_tablets( + const obrpc::ObBatchCreateTabletArg &arg, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array); + static int get_table_schema_index( + const common::ObTabletID &tablet_id, + const common::ObIArray &tablet_ids, + int64_t &index); + static bool is_pure_data_tablets(const obrpc::ObCreateTabletInfo &info); + static bool is_mixed_tablets(const obrpc::ObCreateTabletInfo &info); + static bool is_pure_aux_tablets(const obrpc::ObCreateTabletInfo &info); + static bool is_hidden_tablets(const obrpc::ObCreateTabletInfo &info); + static int check_pure_data_or_mixed_tablets_info( + const share::ObLSID &ls_id, + const obrpc::ObCreateTabletInfo &info, + bool &valid); + static int check_pure_aux_tablets_info( + const share::ObLSID &ls_id, + const obrpc::ObCreateTabletInfo &info, + bool &valid); + static int check_hidden_tablets_info( + const share::ObLSID &ls_id, + const obrpc::ObCreateTabletInfo &hidden_info, + const obrpc::ObCreateTabletInfo *aux_info, + bool &valid); + static bool find_aux_info_for_hidden_tablets( + const obrpc::ObBatchCreateTabletArg &arg, + const common::ObTabletID &tablet_id, + int64_t &aux_info_idx); + static int build_pure_data_tablet( + const obrpc::ObBatchCreateTabletArg &arg, + const obrpc::ObCreateTabletInfo &info, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array); + static int build_mixed_tablets( + const obrpc::ObBatchCreateTabletArg &arg, + const obrpc::ObCreateTabletInfo &info, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array); + static int build_pure_aux_tablets( + const obrpc::ObBatchCreateTabletArg &arg, + const obrpc::ObCreateTabletInfo &info, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array); + static int build_hidden_tablets( + const obrpc::ObBatchCreateTabletArg &arg, + const obrpc::ObCreateTabletInfo &info, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array); + static int roll_back_remove_tablets( + const share::ObLSID &ls_id, + const common::ObIArray &tablet_id_array); + static int get_ls( + const share::ObLSID &ls_id, + ObLSHandle &ls_handle); + static int set_tablet_normal_status( + ObLSTabletService *ls_tablet_service, + ObTabletHandle &tablet_handle, + const bool for_replay, + const share::SCN &scn, + mds::BufferCtx &ctx); +}; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_CREATE_MDS_HELPER diff --git a/src/storage/tablet/ob_tablet_create_sstable_param.cpp b/src/storage/tablet/ob_tablet_create_sstable_param.cpp index e71310078..42b3d30f5 100644 --- a/src/storage/tablet/ob_tablet_create_sstable_param.cpp +++ b/src/storage/tablet/ob_tablet_create_sstable_param.cpp @@ -101,11 +101,11 @@ bool ObTabletCreateSSTableParam::is_valid() const && original_size_ >= 0 && recycle_version_ >= 0)) { ret = false; - LOG_WARN("invalid basic params", K(schema_version_), K(create_snapshot_version_), K(index_type_), + LOG_WARN("invalid basic params", K(schema_version_), K_(sstable_logic_seq), K(create_snapshot_version_), K(index_type_), K(root_row_store_type_), K_(latest_row_store_type), K(data_index_tree_height_), K(index_blocks_cnt_), K(data_blocks_cnt_), K(micro_block_cnt_), K(use_old_macro_block_count_), K(row_count_), K(rowkey_column_cnt_), K(column_cnt_), K(occupy_size_), - K(original_size_), K(ddl_scn_), K(filled_tx_scn_), K_(recycle_version)); + K(ddl_scn_), K(filled_tx_scn_), K(original_size_), K_(recycle_version)); } else if (ObITable::is_ddl_sstable(table_key_.table_type_)) { // ddl sstable can have invalid meta addr, so skip following ifs if (!ddl_scn_.is_valid_and_not_min()) { diff --git a/src/storage/tablet/ob_tablet_delete_mds_helper.cpp b/src/storage/tablet/ob_tablet_delete_mds_helper.cpp new file mode 100644 index 000000000..3ea22cf19 --- /dev/null +++ b/src/storage/tablet/ob_tablet_delete_mds_helper.cpp @@ -0,0 +1,233 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_delete_mds_helper.h" +#include "common/ob_tablet_id.h" +#include "share/scn.h" +#include "share/ob_rpc_struct.h" +#include "storage/multi_data_source/buffer_ctx.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/meta_mem/ob_tablet_map_key.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/tablet/ob_tablet_delete_replay_executor.h" +#include "storage/tx_storage/ob_ls_service.h" + +#define USING_LOG_PREFIX MDS + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +int ObTabletDeleteMdsHelper::register_process( + obrpc::ObBatchRemoveTabletArg &arg, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + + if (CLICK_FAIL(delete_tablets(arg, ctx))) { + LOG_WARN("failed to delete tablets", K(ret), K(arg)); + } else if (CLICK_FAIL(ObTabletCreateDeleteMdsUserData::set_tablet_empty_shell_trigger(arg.id_))) { + LOG_WARN("failed to set_tablet_empty_shell_trigger", K(ret), K(arg)); + } else { + LOG_INFO("delete tablet register", KR(ret), K(arg)); + } + + return ret; +} + +int ObTabletDeleteMdsHelper::on_commit_for_old_mds( + const char* buf, + const int64_t len, + const transaction::ObMulSourceDataNotifyArg ¬ify_arg) +{ + return ObTabletCreateDeleteHelper::process_for_old_mds(buf, len, notify_arg); +} + +int ObTabletDeleteMdsHelper::on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + obrpc::ObBatchRemoveTabletArg arg; + int64_t pos = 0; + bool exist = true; + + if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(buf), K(len)); + } else if (CLICK_FAIL(arg.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (arg.is_old_mds_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, arg is old mds", K(ret), K(arg)); + } else if (CLICK_FAIL(register_process(arg, ctx))) { + LOG_WARN("failed to register_process", K(ret), K(arg)); + } + + return ret; +} + +int ObTabletDeleteMdsHelper::on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + obrpc::ObBatchRemoveTabletArg arg; + int64_t pos = 0; + bool exist = true; + + if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(buf), K(len)); + } else if (CLICK_FAIL(arg.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (arg.is_old_mds_) { + LOG_INFO("skip replay delete tablet for old mds", K(arg), K(scn)); + } else if (CLICK_FAIL(replay_delete_tablets(arg, scn, ctx))) { + LOG_WARN("failed to delete tablets", K(ret), K(arg), K(scn)); + } else if (CLICK_FAIL(ObTabletCreateDeleteMdsUserData::set_tablet_empty_shell_trigger(arg.id_))) { + LOG_WARN("failed to set_tablet_empty_shell_trigger", K(ret), K(arg)); + } else { + LOG_INFO("delete tablet replay", KR(ret), K(arg)); + } + + return ret; +} + +int ObTabletDeleteMdsHelper::delete_tablets( + const obrpc::ObBatchRemoveTabletArg &arg, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + bool exist = false; + ObTabletHandle tablet_handle; + ObTabletMapKey key; + key.ls_id_ = arg.id_; + + ObLSService *ls_service = MTL(ObLSService*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + if (CLICK_FAIL(ls_service->get_ls(key.ls_id_, ls_handle, ObLSGetMod::MDS_TABLE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + } else { + CLICK(); + for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_ids_.count(); ++i) { + MDS_TG(10_ms); + exist = false; + key.tablet_id_ = arg.tablet_ids_.at(i); + + if (CLICK_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + exist = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(key)); + } + } else { + exist = true; + } + + if (CLICK_FAIL(ret)) { + } else if (!exist) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet does not exist", K(ret), K(key)); + } else if (CLICK_FAIL(set_tablet_deleted_status(ls->get_tablet_svr(), tablet_handle, ctx))) { + LOG_WARN("failed to set tablet deleted status", K(ret), K(key)); + } + } + } + + // remember to roll back if failed + + return ret; +} + +int ObTabletDeleteMdsHelper::replay_delete_tablets( + const obrpc::ObBatchRemoveTabletArg &arg, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + bool exist = false; + ObRemoveTabletArg remove_tablet_arg; + remove_tablet_arg.ls_id_ = arg.id_; + + for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_ids_.count(); ++i) { + MDS_TG(10_ms); + exist = true; + remove_tablet_arg.tablet_id_ = arg.tablet_ids_.at(i); + ObTabletDeleteReplayExecutor replayer; + if (CLICK_FAIL(replayer.init(ctx, scn))) { + LOG_WARN("failed to init tablet delete replay executor", K(ret), K(remove_tablet_arg)); + } else if (CLICK_FAIL(replayer.execute(scn, remove_tablet_arg.ls_id_, remove_tablet_arg.tablet_id_))) { + if (OB_TABLET_NOT_EXIST == ret) { + exist = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to replay", K(ret), K(remove_tablet_arg), K(scn)); + } + } + + if (OB_FAIL(ret)) { + } else if (!exist) { + // tablet does not exist, maybe already deleted, do nothing + } + } + + // remember to roll back if failed + + return ret; +} + +int ObTabletDeleteMdsHelper::set_tablet_deleted_status( + ObLSTabletService *ls_tablet_service, + ObTabletHandle &tablet_handle, + mds::BufferCtx &ctx) +{ + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObTablet *tablet = tablet_handle.get_obj(); + mds::MdsCtx &user_ctx = static_cast(ctx); + ObTabletCreateDeleteMdsUserData data; + if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(tablet_handle)); + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), data))) { + LOG_WARN("failed to get tablet status", K(ret)); + } else { + data.tablet_status_ = ObTabletStatus::DELETED; + data.data_type_ = ObTabletMdsUserDataType::REMOVE_TABLET; + if (CLICK_FAIL(ls_tablet_service->set_tablet_status(tablet->get_tablet_meta().tablet_id_, data, user_ctx))) { + LOG_WARN("failed to set mds data", K(ret)); + } + } + + return ret; +} + +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_delete_mds_helper.h b/src/storage/tablet/ob_tablet_delete_mds_helper.h new file mode 100644 index 000000000..e6944790d --- /dev/null +++ b/src/storage/tablet/ob_tablet_delete_mds_helper.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_DELETE_MDS_HELPER +#define OCEANBASE_STORAGE_OB_TABLET_DELETE_MDS_HELPER + +#include +#include "storage/tx/ob_trans_define.h" + +namespace oceanbase +{ +namespace share +{ +class SCN; +} + +namespace obrpc +{ +struct ObBatchRemoveTabletArg; +} + +namespace storage +{ +namespace mds +{ +struct BufferCtx; +} + +class ObTabletHandle; +class ObLSTabletService; + +class ObTabletDeleteMdsHelper +{ +public: + static int on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx); + static int register_process( + obrpc::ObBatchRemoveTabletArg &arg, + mds::BufferCtx &ctx); + static int on_commit_for_old_mds( + const char* buf, + const int64_t len, + const transaction::ObMulSourceDataNotifyArg ¬ify_arg); + static int on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx); +private: + static int delete_tablets( + const obrpc::ObBatchRemoveTabletArg &arg, + mds::BufferCtx &ctx); + static int replay_delete_tablets( + const obrpc::ObBatchRemoveTabletArg &arg, + const share::SCN &scn, + mds::BufferCtx &ctx); + static int set_tablet_deleted_status( + ObLSTabletService *ls_tablet_service, + ObTabletHandle &tablet_handle, + mds::BufferCtx &ctx); +}; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_DELETE_MDS_HELPER diff --git a/src/storage/tablet/ob_tablet_delete_replay_executor.cpp b/src/storage/tablet/ob_tablet_delete_replay_executor.cpp new file mode 100644 index 000000000..c10f708b5 --- /dev/null +++ b/src/storage/tablet/ob_tablet_delete_replay_executor.cpp @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_delete_replay_executor.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/meta_mem/ob_tablet_map_key.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" + +#define USING_LOG_PREFIX MDS + +namespace oceanbase +{ +namespace storage +{ + +OB_SERIALIZE_MEMBER(ObRemoveTabletArg, ls_id_, tablet_id_); + + +// ObTabletDeleteReplayExecutor +ObTabletDeleteReplayExecutor::ObTabletDeleteReplayExecutor() + :logservice::ObTabletReplayExecutor(), ctx_(nullptr) +{} + +int ObTabletDeleteReplayExecutor::init( + mds::BufferCtx &ctx, + const share::SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("tablet delete replay executor init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid argument", KR(ret), K(scn)); + } else { + ctx_ = &ctx; + scn_ = scn; + is_inited_ = true; + } + return ret; +} + +int ObTabletDeleteReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) +{ + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObTablet *tablet = tablet_handle.get_obj(); + mds::MdsCtx &user_ctx = static_cast(*ctx_); + ObTabletCreateDeleteMdsUserData data; + + if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(tablet_handle)); + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), data))) { + LOG_WARN("failed to get tablet status", K(ret)); + } else { + data.tablet_status_ = ObTabletStatus::DELETED; + data.data_type_ = ObTabletMdsUserDataType::REMOVE_TABLET; + if (CLICK_FAIL(replay_to_mds_table_(tablet_handle, data, user_ctx, scn_))) { + LOG_WARN("failed to replay to tablet", K(ret)); + } + } + + return ret; +} + +} +} diff --git a/src/storage/tablet/ob_tablet_delete_replay_executor.h b/src/storage/tablet/ob_tablet_delete_replay_executor.h new file mode 100644 index 000000000..584fc6bfd --- /dev/null +++ b/src/storage/tablet/ob_tablet_delete_replay_executor.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_DELETE_REPLAY_EXECUTOR +#define OCEANBASE_STORAGE_OB_TABLET_DELETE_REPLAY_EXECUTOR + +#include "share/ob_ls_id.h" +#include "common/ob_tablet_id.h" +#include "logservice/replayservice/ob_tablet_replay_executor.h" + +namespace oceanbase +{ + +namespace storage +{ + +struct ObRemoveTabletArg +{ + OB_UNIS_VERSION(1); +public: + inline bool is_valid() const + { + return ls_id_.is_valid() && tablet_id_.is_valid(); + } + + TO_STRING_KV(K_(ls_id), K_(tablet_id)); + +public: + share::ObLSID ls_id_; + common::ObTabletID tablet_id_; +}; + +class ObTabletDeleteReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObTabletDeleteReplayExecutor(); + + int init(mds::BufferCtx &ctx, const share::SCN &scn); + +protected: + bool is_replay_update_user_data_() const override + { + return true; + } + + int do_replay_(ObTabletHandle &tablet_handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return true; + } + +private: + const ObRemoveTabletArg *arg_; + mds::BufferCtx *ctx_; + share::SCN scn_; +}; + + +} +} + +#endif diff --git a/src/storage/tablet/ob_tablet_dumped_medium_info.cpp b/src/storage/tablet/ob_tablet_dumped_medium_info.cpp new file mode 100644 index 000000000..2a42aea57 --- /dev/null +++ b/src/storage/tablet/ob_tablet_dumped_medium_info.cpp @@ -0,0 +1,605 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_dumped_medium_info.h" +#include +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include "storage/tablet/ob_tablet_obj_load_helper.h" + +#define USING_LOG_PREFIX STORAGE + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +ObTabletDumpedMediumInfo::ObTabletDumpedMediumInfo() + : is_inited_(false), + allocator_(nullptr), + medium_info_list_() +{ +} + +ObTabletDumpedMediumInfo::~ObTabletDumpedMediumInfo() +{ + reset(); +} + +void ObTabletDumpedMediumInfo::reset() +{ + if (OB_NOT_NULL(allocator_)) { + for (int64_t i = 0; i < medium_info_list_.count(); ++i) { + compaction::ObMediumCompactionInfo *medium_info = medium_info_list_[i]; + if (OB_ISNULL(medium_info)) { + LOG_ERROR_RET(OB_ERR_SYS, "medium info is null", KP(medium_info), K(i)); + } else { + medium_info->compaction::ObMediumCompactionInfo::~ObMediumCompactionInfo(); + allocator_->free(medium_info); + } + } + } + + medium_info_list_.reset(); + is_inited_ = false; +} + +int ObTabletDumpedMediumInfo::init(common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else { + allocator_ = &allocator; + is_inited_ = true; + } + + return ret; +} + +int ObTabletDumpedMediumInfo::assign(const ObTabletDumpedMediumInfo &other, common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + + if (this != &other) { + reset(); + + for (int64_t i = 0; OB_SUCC(ret) && i < other.medium_info_list_.count(); ++i) { + compaction::ObMediumCompactionInfo *medium_info = nullptr; + const compaction::ObMediumCompactionInfo *src_medium_info = other.medium_info_list_.at(i); + if (OB_ISNULL(src_medium_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src medium info is null", K(ret), KP(src_medium_info), K(i)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, medium_info))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(medium_info->assign(allocator, *src_medium_info))) { + LOG_WARN("failed to copy mds dump kv", K(ret)); + } else if (OB_FAIL(medium_info_list_.push_back(medium_info))) { + LOG_WARN("failed to push back to array", K(ret)); + } + + if (OB_FAIL(ret)) { + if (nullptr != medium_info) { + medium_info->reset(); + allocator.free(medium_info); + } + } + } + + if (OB_FAIL(ret)) { + reset(); + } else { + allocator_ = &allocator; + is_inited_ = true; + } + } + + return ret; +} + +int ObTabletDumpedMediumInfo::append( + const mds::MdsDumpKey &key, + const mds::MdsDumpNode &node) +{ + int ret = OB_SUCCESS; + void *buffer = nullptr; + compaction::ObMediumCompactionInfo *medium_info = nullptr; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else { + const common::ObString &user_data = node.user_data_; + int64_t pos = 0; + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(*allocator_, medium_info))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(medium_info->deserialize(*allocator_, user_data.ptr(), user_data.length(), pos))) { + LOG_WARN("failed to deserialize medium info", K(ret)); + } else if (OB_FAIL(medium_info_list_.push_back(medium_info))) { + LOG_WARN("failed to push back to array", K(ret)); + } else { + std::sort(medium_info_list_.begin(), medium_info_list_.end(), compare); + } + } + + if (OB_FAIL(ret)) { + if (nullptr != medium_info) { + medium_info->compaction::ObMediumCompactionInfo::~ObMediumCompactionInfo(); + allocator_->free(medium_info); + } + } + + return ret; +} + +int ObTabletDumpedMediumInfo::append(const compaction::ObMediumCompactionInfo &medium_info) +{ + int ret = OB_SUCCESS; + compaction::ObMediumCompactionInfo *info = nullptr; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(*allocator_, info))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(info->assign(*allocator_, medium_info))) { + LOG_WARN("failed to copy medium info", K(ret), K(medium_info)); + } else if (OB_FAIL(medium_info_list_.push_back(info))) { + LOG_WARN("failed to push back to array", K(ret), KPC(info)); + } + + if (OB_FAIL(ret)) { + if (nullptr != info) { + info->compaction::ObMediumCompactionInfo::~ObMediumCompactionInfo(); + allocator_->free(info); + } + } + + return ret; +} + +bool ObTabletDumpedMediumInfo::is_valid() const +{ + bool valid = true; + int ret = OB_SUCCESS; + + if (medium_info_list_.empty()) { + valid = false; + } else { + for (int64_t i = 0; OB_SUCC(ret) && valid && i < medium_info_list_.count(); ++i) { + const compaction::ObMediumCompactionInfo *medium_info = medium_info_list_.at(i); + if (OB_ISNULL(medium_info)) { + ret = OB_ERR_UNEXPECTED; + valid = false; + LOG_ERROR("mds dump kv is null", K(ret), KP(medium_info), K(i)); + } else if (!medium_info->is_valid()) { + valid = false; + } + } + } + + return valid; +} + +int ObTabletDumpedMediumInfo::get_min_medium_info_key(compaction::ObMediumCompactionInfoKey &key) const +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (medium_info_list_.empty()) { + ret = OB_EMPTY_RESULT; + LOG_INFO("no medium info exists", K(ret)); + } else { + ObTabletDumpedMediumInfoIterator iter; + ObArenaAllocator arena_allocator("iter"); + if (OB_FAIL(iter.init(arena_allocator, *this))) { + LOG_WARN("failed to init", K(ret)); + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.get_next_key(key))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get next medium info", K(ret)); + } + } + } + } + } + + return ret; +} + +int ObTabletDumpedMediumInfo::get_max_medium_info_key(compaction::ObMediumCompactionInfoKey &key) const +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (medium_info_list_.empty()) { + ret = OB_EMPTY_RESULT; + LOG_INFO("no medium info exists", K(ret)); + } else { + ObTabletDumpedMediumInfoIterator iter; + ObArenaAllocator arena_allocator("iter"); + if (OB_FAIL(iter.init(arena_allocator, *this))) { + LOG_WARN("failed to init", K(ret)); + } else if (OB_FAIL(iter.get_next_key(key))) { + LOG_WARN("failed to get next medium info", K(ret)); + } + } + + return ret; +} + +int64_t ObTabletDumpedMediumInfo::get_min_medium_snapshot() const +{ + return medium_info_list_.empty() ? 0 : medium_info_list_.at(0)->medium_snapshot_; +} + +int64_t ObTabletDumpedMediumInfo::get_max_medium_snapshot() const +{ + return medium_info_list_.empty() ? 0 : medium_info_list_.at(medium_info_list_.count() - 1)->medium_snapshot_; +} + +int ObTabletDumpedMediumInfo::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + const int64_t count = medium_info_list_.count(); + int64_t new_pos = pos; + + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0) || OB_UNLIKELY(pos < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(buf), K(buf_len), K(pos)); + } else if (OB_FAIL(serialization::encode(buf, buf_len, new_pos, count))) { + LOG_WARN("failed to serialize", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { + const compaction::ObMediumCompactionInfo *medium_info = medium_info_list_.at(i); + if (OB_ISNULL(medium_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("medium info is null", K(ret), KP(medium_info), K(i)); + } else if (OB_FAIL(medium_info->serialize(buf, buf_len, new_pos))) { + LOG_WARN("failed to serialize medium info", K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + pos = new_pos; + } + + return ret; +} + +int ObTabletDumpedMediumInfo::deserialize(common::ObIAllocator &allocator, const char *buf, const int64_t buf_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + int64_t count = 0; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0) || OB_UNLIKELY(pos < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KP(buf), K(buf_len), K(pos)); + } else if (OB_FAIL(serialization::decode(buf, buf_len, new_pos, count))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(medium_info_list_.reserve(count))) { + LOG_WARN("failed to reserve memory for array", K(ret), K(count)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { + compaction::ObMediumCompactionInfo *medium_info = nullptr; + void *buffer = allocator.alloc(sizeof(compaction::ObMediumCompactionInfo)); + if (OB_ISNULL(buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to allocate memory", K(ret)); + } else if (FALSE_IT(medium_info = new (buffer) compaction::ObMediumCompactionInfo())) { + } else if (OB_FAIL(medium_info->deserialize(allocator, buf, buf_len, new_pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(medium_info_list_.push_back(medium_info))) { + LOG_WARN("failed to push back to array", K(ret)); + } + + if (OB_FAIL(ret)) { + if (nullptr != medium_info) { + medium_info->reset(); + } + if (nullptr != buffer) { + allocator.free(buffer); + } + } + } + + if (OB_FAIL(ret)) { + for (int64_t i = 0; i < medium_info_list_.count(); ++i) { + compaction::ObMediumCompactionInfo *medium_info = medium_info_list_[i]; + if (OB_ISNULL(medium_info)) { + LOG_ERROR("medium info kv is null", KP(medium_info), K(i)); + } else { + medium_info->reset(); + allocator.free(medium_info); + } + } + medium_info_list_.reset(); + } + } + + if (OB_SUCC(ret)) { + pos = new_pos; + allocator_ = &allocator; + is_inited_ = true; + } + + return ret; +} + +int64_t ObTabletDumpedMediumInfo::get_serialize_size() const +{ + int64_t size = 0; + int ret = OB_SUCCESS; + const int64_t count = medium_info_list_.count(); + + size += serialization::encoded_length(count); + for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { + const compaction::ObMediumCompactionInfo *medium_info = medium_info_list_.at(i); + if (OB_ISNULL(medium_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("medium info kv is null", K(ret), KP(medium_info), K(i)); + } else { + size += medium_info->get_serialize_size(); + } + } + + return size; +} + +int64_t ObTabletDumpedMediumInfo::to_string(char* buf, const int64_t buf_len) const +{ + int64_t pos = 0; + + if (OB_ISNULL(buf) || buf_len <= 0) { + } else { + J_OBJ_START(); + J_KV(K_(is_inited), KP_(allocator)); + J_COMMA(); + + J_NAME("medium_info"); + J_COLON(); + J_ARRAY_START(); + for (int64_t i = 0; i < medium_info_list_.count(); ++i) { + const compaction::ObMediumCompactionInfo *info = medium_info_list_[i]; + if (i != 0) { + J_COMMA(); + } + + if (OB_ISNULL(info)) { + BUF_PRINTO(info); + } else { + BUF_PRINTO(*info); + } + } + J_ARRAY_END(); + J_OBJ_END(); + } + + return pos; +} + +int64_t ObTabletDumpedMediumInfo::simple_to_string(char* buf, const int64_t buf_len, int64_t &pos) const +{ + if (OB_ISNULL(buf) || buf_len <= 0) { + } else { + const int64_t count = medium_info_list_.count(); + + databuff_printf(buf, buf_len, pos, "{"); + databuff_print_json_kv(buf, buf_len, pos, "count", count); + databuff_printf(buf, buf_len, pos, ", "); + databuff_printf(buf, buf_len, pos, "elements:["); + for (int64_t i = 0; i < count; ++i) { + const compaction::ObMediumCompactionInfo *info = medium_info_list_.at(i); + if (i != 0) { + databuff_printf(buf, buf_len, pos, ", "); + } + + if (OB_ISNULL(info)) { + databuff_printf(buf, buf_len, pos, "{"); + databuff_print_json_kv(buf, buf_len, pos, "i", i); + databuff_print_json_kv_comma(buf, buf_len, pos, "info", info); + databuff_printf(buf, buf_len, pos, "}"); + } else { + databuff_printf(buf, buf_len, pos, "{"); + databuff_print_json_kv(buf, buf_len, pos, "i", i); + databuff_print_json_kv_comma(buf, buf_len, pos, "medium_compat_version", info->medium_compat_version_); + databuff_print_json_kv_comma(buf, buf_len, pos, "cluster_id", info->cluster_id_); + databuff_print_json_kv_comma(buf, buf_len, pos, "data_version", info->data_version_); + databuff_print_json_kv_comma(buf, buf_len, pos, "medium_snapshot", info->medium_snapshot_); + databuff_printf(buf, buf_len, pos, "}"); + } + } + databuff_printf(buf, buf_len, pos, "]"); + databuff_printf(buf, buf_len, pos, "}"); + } + + return pos; +} + +bool ObTabletDumpedMediumInfo::compare( + const compaction::ObMediumCompactionInfo *lhs, + const compaction::ObMediumCompactionInfo *rhs) +{ + return lhs->medium_snapshot_ < rhs->medium_snapshot_; +} + + +ObTabletDumpedMediumInfoIterator::ObTabletDumpedMediumInfoIterator() + : is_inited_(false), + idx_(0), + allocator_(nullptr), + medium_info_list_() +{ +} + +ObTabletDumpedMediumInfoIterator::~ObTabletDumpedMediumInfoIterator() +{ + reset(); +} + +int ObTabletDumpedMediumInfoIterator::init( + common::ObIAllocator &allocator, + const ObTabletDumpedMediumInfo &dumped_medium_info) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else { + const common::ObSEArray &array = dumped_medium_info.medium_info_list_; + compaction::ObMediumCompactionInfo* info = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && i < array.count(); ++i) { + compaction::ObMediumCompactionInfo* src_medium_info = array.at(i); + info = nullptr; + if (OB_ISNULL(src_medium_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, src medium info is null", K(ret), K(i), KP(src_medium_info)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, info))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(info->assign(allocator, *src_medium_info))) { + LOG_WARN("failed to copy medium info", K(ret), KPC(src_medium_info)); + } else if (OB_FAIL(medium_info_list_.push_back(info))) { + LOG_WARN("failed to push back to array", K(ret)); + } + + if (OB_FAIL(ret)) { + if (nullptr != info) { + allocator.free(info); + } + } + } + + if (OB_FAIL(ret)) { + reset(); + } else { + std::sort(medium_info_list_.begin(), medium_info_list_.end(), ObTabletDumpedMediumInfo::compare); + + idx_ = 0; + allocator_ = &allocator; + is_inited_ = true; + } + } + + return ret; +} + +void ObTabletDumpedMediumInfoIterator::reset() +{ + if (OB_NOT_NULL(allocator_)) { + for (int64_t i = 0; i < medium_info_list_.count(); ++i) { + compaction::ObMediumCompactionInfo* medium_info = medium_info_list_.at(i); + if (OB_ISNULL(medium_info)) { + LOG_ERROR_RET(OB_ERR_SYS, "medium info is null", K(ret), KP(medium_info), K(i)); + } else { + medium_info->compaction::ObMediumCompactionInfo::~ObMediumCompactionInfo(); + allocator_->free(medium_info); + } + } + } + + allocator_ = nullptr; + medium_info_list_.reset(); + idx_ = 0; + is_inited_ = false; +} + +int ObTabletDumpedMediumInfoIterator::get_next_key(compaction::ObMediumCompactionInfoKey &key) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (idx_ == medium_info_list_.count()) { + ret = OB_ITER_END; + } else { + const compaction::ObMediumCompactionInfo *medium_info = medium_info_list_.at(idx_); + key = medium_info->medium_snapshot_; + ++idx_; + } + + return ret; +} + +int ObTabletDumpedMediumInfoIterator::get_next_medium_info( + common::ObIAllocator &allocator, + compaction::ObMediumCompactionInfoKey &key, + compaction::ObMediumCompactionInfo &medium_info) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (idx_ == medium_info_list_.count()) { + ret = OB_ITER_END; + } else { + int64_t pos = 0; + const compaction::ObMediumCompactionInfo *info = medium_info_list_.at(idx_); + if (OB_ISNULL(info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, medium info is null", K(ret), K_(idx), KP(info)); + } else if (OB_FAIL(medium_info.assign(allocator, *info))) { + LOG_WARN("failed to copy medium info", K(ret), KPC(info)); + } else { + key = info->medium_snapshot_; + ++idx_; + } + } + + return ret; +} + +int ObTabletDumpedMediumInfoIterator::get_next_medium_info( + compaction::ObMediumCompactionInfoKey &key, + const compaction::ObMediumCompactionInfo *&medium_info) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (idx_ == medium_info_list_.count()) { + ret = OB_ITER_END; + LOG_DEBUG("iter end", K(ret), K_(idx)); + } else { + const compaction::ObMediumCompactionInfo *info = medium_info_list_.at(idx_); + if (OB_ISNULL(info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, medium info is null", K(ret), K_(idx), KP(info)); + } else { + key = info->medium_snapshot_; + medium_info = info; + ++idx_; + } + } + + return ret; +} +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_dumped_medium_info.h b/src/storage/tablet/ob_tablet_dumped_medium_info.h new file mode 100644 index 000000000..e00d2ec67 --- /dev/null +++ b/src/storage/tablet/ob_tablet_dumped_medium_info.h @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_DUMPED_MEDIUM_INFO +#define OCEANBASE_STORAGE_OB_TABLET_DUMPED_MEDIUM_INFO + +#include +#include "lib/container/ob_se_array.h" +#include "lib/utility/ob_print_utils.h" +#include "storage/compaction/ob_medium_compaction_info.h" + +namespace oceanbase +{ +namespace common +{ +class ObIAllocator; +} + +namespace storage +{ +namespace mds +{ +struct MdsDumpKey; +struct MdsDumpNode; +} + +class ObTabletDumpedMediumInfo +{ +public: + ObTabletDumpedMediumInfo(); + ~ObTabletDumpedMediumInfo(); + ObTabletDumpedMediumInfo(const ObTabletDumpedMediumInfo &) = delete; + ObTabletDumpedMediumInfo &operator=(const ObTabletDumpedMediumInfo &) = delete; +public: + int init(common::ObIAllocator &allocator); + void reset(); + + // key order in array: big -> small + int append( + const mds::MdsDumpKey &key, + const mds::MdsDumpNode &node); + int append(const compaction::ObMediumCompactionInfo &medium_info); + int assign(const ObTabletDumpedMediumInfo &other, common::ObIAllocator &allocator); + bool is_valid() const; + + int get_min_medium_info_key(compaction::ObMediumCompactionInfoKey &key) const; + int get_max_medium_info_key(compaction::ObMediumCompactionInfoKey &key) const; + + int64_t get_min_medium_snapshot() const; + int64_t get_max_medium_snapshot() const; + + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize(common::ObIAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos); + int64_t get_serialize_size() const; + + int64_t to_string(char* buf, const int64_t buf_len) const; + int64_t simple_to_string(char* buf, const int64_t buf_len, int64_t &pos) const; +public: + static bool compare(const compaction::ObMediumCompactionInfo *lhs, const compaction::ObMediumCompactionInfo *rhs); +public: + bool is_inited_; + common::ObIAllocator *allocator_; + common::ObSEArray medium_info_list_; +}; + +class ObTabletDumpedMediumInfoIterator +{ +public: + ObTabletDumpedMediumInfoIterator(); + ~ObTabletDumpedMediumInfoIterator(); + ObTabletDumpedMediumInfoIterator(const ObTabletDumpedMediumInfoIterator &) = delete; + ObTabletDumpedMediumInfoIterator &operator=(const ObTabletDumpedMediumInfoIterator &) = delete; +public: + int init( + common::ObIAllocator &allocator, + const ObTabletDumpedMediumInfo &dumped_medium_info); + void reset(); + int get_next_key(compaction::ObMediumCompactionInfoKey &key); + int get_next_medium_info( + common::ObIAllocator &allocator, + compaction::ObMediumCompactionInfoKey &key, + compaction::ObMediumCompactionInfo &medium_info); + int get_next_medium_info( + compaction::ObMediumCompactionInfoKey &key, + const compaction::ObMediumCompactionInfo *&medium_info); +private: + bool is_inited_; + int64_t idx_; + common::ObIAllocator *allocator_; + common::ObSEArray medium_info_list_; +}; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_DUMPED_MEDIUM_INFO diff --git a/src/storage/tablet/ob_tablet_finish_transfer_mds_helper.cpp b/src/storage/tablet/ob_tablet_finish_transfer_mds_helper.cpp new file mode 100644 index 000000000..eff50db79 --- /dev/null +++ b/src/storage/tablet/ob_tablet_finish_transfer_mds_helper.cpp @@ -0,0 +1,1153 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_finish_transfer_mds_helper.h" +#include "share/scn.h" +#include "share/ob_ls_id.h" +#include "share/transfer/ob_transfer_info.h" +#include "common/ob_tablet_id.h" +#include "storage/ls/ob_ls_get_mod.h" +#include "storage/multi_data_source/buffer_ctx.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/meta_mem/ob_tablet_map_key.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "logservice/replayservice/ob_tablet_replay_executor.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "observer/ob_server_event_history_table_operator.h" +#include "storage/high_availability/ob_rebuild_service.h" +#include "storage/high_availability/ob_storage_ha_utils.h" + +#define USING_LOG_PREFIX MDS + +namespace oceanbase +{ +namespace storage +{ + +ERRSIM_POINT_DEF(EN_TRANSFER_NEED_REBUILD); + +int ObTabletFinishTransferUtil::check_transfer_table_replaced( + ObTabletHandle &tablet_handle, + bool &all_replaced) +{ + int ret = OB_SUCCESS; + all_replaced = true; + ObTablet *tablet = NULL; + if (!tablet_handle.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_handle)); + } else if (tablet->get_tablet_meta().has_transfer_table()) { + all_replaced = false; + } + return ret; +} + +int ObTabletFinishTransferUtil::can_skip_check_transfer_tablets( + const uint64_t tenant_id, + const share::ObLSID &ls_id /* transfer dest ls */, + const share::SCN &scn /* finish transfer in log scn */, + bool &can_skip_check) +{ + // There are 2 cases that source tablets are no need to check ready while replaying transfer in. The following + // order needs to be followed. + // 1. Current ls is in restore, and scn is smaller than consistent_scn; + // 2. GTS is over current log scn, but current ls is in rebuild. + int ret = OB_SUCCESS; + ObLSService *ls_svr = nullptr; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObLSRestoreHandler *restore_handler = nullptr; + ObLSRestoreStatus restore_status; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + SCN consistent_scn; + SCN gts_scn; + can_skip_check = false; + + if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls svr should not be NULL", K(ret), KP(ls_svr)); + } else if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", K(ret), K(ls_id), K(ls_handle)); + } else if (OB_FAIL(ls->get_restore_status(restore_status))) { + LOG_WARN("failed to get restore status", K(ret), KPC(ls)); + } else if (!restore_status.is_in_restore()) { + // ls not in restore, cannot skip. + } else if (OB_FALSE_IT(restore_handler = ls->get_ls_restore_handler())) { + } else if (OB_FAIL(restore_handler->get_consistent_scn(consistent_scn))) { + LOG_WARN("failed to get consistent_scn", K(ret), KPC(ls)); + } else if (scn <= consistent_scn) { + can_skip_check = true; + LOG_INFO("transfer finish in scn <= consistent_scn, skip check local finish transfer in tablet ready", K(scn), K(consistent_scn)); + } else { + // transfer finish in log scn is bigger than consistent_scn, cannot skip. + } + + if (OB_FAIL(ret)) { + } else if (can_skip_check) { + } else if (OB_FAIL(ObTransferUtils::get_gts(tenant_id, gts_scn))) { + LOG_WARN("failed to get gts", K(ret), K(tenant_id), K(scn)); + //overwrite ret + ret = OB_SUCCESS; + } else if (gts_scn <= scn) { + LOG_INFO("can not skip check transfer table replaced", K(gts_scn), K(scn)); + } else if (OB_FAIL(ls->get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), KPC(ls)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_ADD == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD == migration_status) { + can_skip_check = true; + LOG_INFO("ls is in add or migrate or rebuild status, skip check local finish transfer in tablet ready", + K(migration_status)); + } + return ret; +} + +/******************ObTabletFinishTransferOutReplayExecutor*********************/ +class ObTabletFinishTransferOutReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObTabletFinishTransferOutReplayExecutor(); + virtual ~ObTabletFinishTransferOutReplayExecutor(); + + int init( + const share::SCN &scn, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const share::ObTransferTabletInfo &tablet_info, + mds::BufferCtx &buffer_ctx); +protected: + virtual bool is_replay_update_user_data_() const override + { + return true; + } + + virtual int do_replay_(ObTabletHandle &tablet_handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return true; + } + +private: + int check_src_transfer_tablet_(ObTabletHandle &tablet_handle); + +private: + share::SCN scn_; + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + share::ObTransferTabletInfo tablet_info_; + mds::BufferCtx *buffer_ctx_; + DISALLOW_COPY_AND_ASSIGN(ObTabletFinishTransferOutReplayExecutor); +}; + +ObTabletFinishTransferOutReplayExecutor::ObTabletFinishTransferOutReplayExecutor() + :logservice::ObTabletReplayExecutor(), + scn_(), + src_ls_id_(), + dest_ls_id_(), + tablet_info_(), + buffer_ctx_(nullptr) +{ +} + +ObTabletFinishTransferOutReplayExecutor::~ObTabletFinishTransferOutReplayExecutor() +{ +} + +int ObTabletFinishTransferOutReplayExecutor::init( + const share::SCN &scn, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const share::ObTransferTabletInfo &tablet_info, + mds::BufferCtx &buffer_ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("tablet finish transfer out replay executor init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!scn.is_valid()) + || OB_UNLIKELY(!src_ls_id.is_valid()) + || OB_UNLIKELY(!dest_ls_id.is_valid()) + || OB_UNLIKELY(!tablet_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid argument", KR(ret), K(scn), K(src_ls_id), K(dest_ls_id), K(tablet_info)); + } else { + scn_ = scn; + src_ls_id_ = src_ls_id; + dest_ls_id_ = dest_ls_id; + tablet_info_ = tablet_info; + buffer_ctx_ = &buffer_ctx; + scn_ = scn; + is_inited_ = true; + } + return ret; +} + +int ObTabletFinishTransferOutReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + ObTabletCreateDeleteMdsUserData user_data; + mds::MdsCtx &user_ctx = static_cast(*buffer_ctx_); + ObTablet *tablet = nullptr; + bool is_committed = false; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet finish transfer out replay executor do not init", K(ret)); + } else if (OB_FAIL(check_src_transfer_tablet_(tablet_handle))) { + LOG_WARN("failed to check src transfer tablet", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_handle)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_latest_tablet_status(user_data, is_committed))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(tablet), K(user_data)); + } else if (!is_committed) { + ret = OB_EAGAIN; + LOG_WARN("transfer out tablet still has uncommitted mds data", K(ret), K(user_data), K(is_committed), KPC(tablet)); + } else { + user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT_DELETED; + user_data.data_type_ = ObTabletMdsUserDataType::FINISH_TRANSFER_OUT; + if (OB_FAIL(replay_to_mds_table_(tablet_handle, user_data, user_ctx, scn_))) { + LOG_WARN("failed to replay to tablet", K(ret)); + } else { + LOG_INFO("succeed replay finish transfer out to mds table", KP(tablet), K(user_data), K(scn_)); + } +#ifdef ERRSIM + ObTransferEventRecorder::record_tablet_transfer_event("tx_finish_transfer_out", + src_ls_id_, tablet->get_tablet_meta().tablet_id_, + tablet->get_tablet_meta().transfer_info_.transfer_seq_, user_data.tablet_status_, + ret); +#endif + } + return ret; +} + +int ObTabletFinishTransferOutReplayExecutor::check_src_transfer_tablet_( + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + const int64_t transfer_seq = tablet_info_.transfer_seq(); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet start transfer out replay executor do not init", K(ret)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_info_), K(src_ls_id_), K(dest_ls_id_)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet), K(tablet_info_)); + } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ + || transfer_seq != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet tx data is unexpected", + K(ret), + K(ObTabletStatus::get_str(user_data.tablet_status_)), + K(transfer_seq), + K(user_data), + KPC(tablet)); + } + return ret; +} + +/******************ObTabletFinishTransferOutHelper*********************/ +int ObTabletFinishTransferOutHelper::on_register( + const char *buf, + const int64_t len, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObTXFinishTransferOutInfo tx_finish_transfer_out_info; + int64_t pos = 0; + + if (OB_ISNULL(buf) || len < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on register finish transfer out get invalid argument", K(ret), KP(buf), K(len)); + } else if (CLICK_FAIL(tx_finish_transfer_out_info.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize tx finish transfer out info", K(ret), K(len), K(pos)); + } else if (!tx_finish_transfer_out_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tx finish transfer out info is unexpected", K(ret), K(tx_finish_transfer_out_info)); + } else if (CLICK_FAIL(on_register_success_(tx_finish_transfer_out_info, ctx))) { + LOG_WARN("failed to on register", K(ret), K(tx_finish_transfer_out_info)); + } else if (CLICK_FAIL(ObTabletCreateDeleteMdsUserData::set_tablet_empty_shell_trigger(tx_finish_transfer_out_info.src_ls_id_))) { + LOG_WARN("failed to set_tablet_empty_shell_trigger", K(ret), K(tx_finish_transfer_out_info)); + } + return ret; +} + +int ObTabletFinishTransferOutHelper::on_register_success_( + const ObTXFinishTransferOutInfo &tx_finish_transfer_out_info, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObLSService *ls_svr = NULL; + ObLSHandle ls_handle; + ObLS *ls = NULL; + const share::ObLSID &src_ls_id = tx_finish_transfer_out_info.src_ls_id_; + const int64_t start_ts = ObTimeUtil::current_time(); + LOG_INFO("[TRANSFER] start tx finish transfer out on_register_success_", K(tx_finish_transfer_out_info)); +#ifdef ERRSIM + SERVER_EVENT_ADD("transfer", "tx_finish_transfer_out", + "stage", "on_register_success", + "tenant_id", MTL_ID(), + "src_ls_id", tx_finish_transfer_out_info.src_ls_id_.id(), + "dest_ls_id", tx_finish_transfer_out_info.dest_ls_id_.id(), + "finish_scn", tx_finish_transfer_out_info.finish_scn_, + "tablet_count", tx_finish_transfer_out_info.tablet_list_.count()); +#endif + + if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls svr should not be NULL", K(ret), KP(ls_svr)); + } else if (CLICK_FAIL(ls_svr->get_ls(src_ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(src_ls_id), K(tx_finish_transfer_out_info)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", K(ret), K(src_ls_id), K(ls_handle)); + } else if (CLICK_FAIL(check_transfer_out_tablets_validity_(tx_finish_transfer_out_info, ls))) { + LOG_WARN("failed to check transfer out tablets validity", K(ret), K(src_ls_id), K(tx_finish_transfer_out_info)); + } else if (CLICK_FAIL(update_transfer_tablets_deleted_(tx_finish_transfer_out_info, ls, ctx))) { + LOG_WARN("failed to update transfer tablets deleted", K(ret), K(tx_finish_transfer_out_info)); + } + + if (OB_FAIL(ret)) { + LOG_WARN("tx finish transfer out on_register_success_ failed", K(ret), K(tx_finish_transfer_out_info)); + } else { + ls->get_tablet_gc_handler()->set_tablet_persist_trigger(); + LOG_INFO("[TRANSFER] finish tx finish transfer out on_register_success_", K(tx_finish_transfer_out_info), + "cost_ts", ObTimeUtil::current_time() - start_ts); + } + + return ret; +} + +int ObTabletFinishTransferOutHelper::check_transfer_out_tablets_validity_( + const ObTXFinishTransferOutInfo &tx_finish_transfer_out_info, + storage::ObLS *ls) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + const common::ObSArray &tablet_list = tx_finish_transfer_out_info.tablet_list_; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_list.count(); ++i) { + const share::ObTransferTabletInfo &tablet_info = tablet_list.at(i); + if (OB_FAIL(inner_check_transfer_out_tablet_validity_(tablet_info, ls))) { + LOG_WARN("failed to inner check transfer out tablet validity", K(ret), K(tablet_info), KP(ls)); + } + } + return ret; +} + +int ObTabletFinishTransferOutHelper::inner_check_transfer_out_tablet_validity_( + const share::ObTransferTabletInfo &tablet_info, + storage::ObLS *ls) +{ + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = NULL; + const common::ObTabletID &tablet_id = tablet_info.tablet_id(); + const int64_t transfer_seq = tablet_info.transfer_seq(); + ObTabletCreateDeleteMdsUserData user_data; + + if (CLICK_FAIL(ls->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_info)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_info), KP(tablet)); + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet data", K(ret), KPC(tablet)); + } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ + || transfer_seq != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet tx data is unexpected", + K(ret), + K(ObTabletStatus::get_str(user_data.tablet_status_)), + K(transfer_seq), + K(user_data), + KPC(tablet)); + } + return ret; +} + +int ObTabletFinishTransferOutHelper::update_transfer_tablets_deleted_( + const ObTXFinishTransferOutInfo &tx_finish_transfer_out_info, + storage::ObLS *ls, + mds::BufferCtx &ctx) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + const common::ObSArray &tablet_list = tx_finish_transfer_out_info.tablet_list_; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_list.count(); ++i) { + const share::ObTransferTabletInfo &tablet_info = tablet_list.at(i); + if (OB_FAIL(update_transfer_tablet_deleted_(tablet_info, ls, ctx))) { + LOG_WARN("failed to update transfer tablet deleted", K(ret), K(tablet_info), KP(ls)); + } + } + return ret; +} + +int ObTabletFinishTransferOutHelper::update_transfer_tablet_deleted_( + const share::ObTransferTabletInfo &tablet_info, + storage::ObLS *ls, + mds::BufferCtx &ctx) +{ + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = NULL; + ObTabletCreateDeleteMdsUserData user_data; + if (!tablet_info.is_valid() || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check src transfer tablets get invalid argument", K(ret), K(tablet_info), KP(ls)); + } else if (CLICK_FAIL(ls->get_tablet(tablet_info.tablet_id(), tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_info)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_info)); + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet data", K(ret), KPC(tablet)); + } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ + || tablet_info.transfer_seq() != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet tx data is unexpected", K(ret), KPC(tablet), K(tablet_info), K(user_data)); + } else { + LOG_INFO("[TRANSFER] inner update transfer tablet deleted", K(tablet_info), K(user_data)); + mds::MdsCtx &user_ctx = static_cast(ctx); + user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT_DELETED; + user_data.data_type_ = ObTabletMdsUserDataType::FINISH_TRANSFER_OUT; + if (OB_FAIL(ls->get_tablet_svr()->set_tablet_status(tablet->get_tablet_meta().tablet_id_, user_data, user_ctx))) { + LOG_WARN("failed to set tx data", K(ret), K(user_data), K(tablet_info)); + } +#ifdef ERRSIM + ObTransferEventRecorder::record_tablet_transfer_event("tx_finish_transfer_out", + ls->get_ls_id(), tablet_info.tablet_id_, tablet->get_tablet_meta().transfer_info_.transfer_seq_, + user_data.tablet_status_, ret); +#endif + } + return ret; +} + +int ObTabletFinishTransferOutHelper::on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObTXFinishTransferOutInfo tx_finish_transfer_out_info; + int64_t pos = 0; + + if (OB_ISNULL(buf) || len < 0 || !scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on replay finish transfer out get invalid argument", K(ret), KP(buf), K(len), K(scn)); + } else if (CLICK_FAIL(tx_finish_transfer_out_info.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize tx finish transfer out info", K(ret), K(len), K(pos)); + } else if (!tx_finish_transfer_out_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tx finish transfer out info is unexpected", K(ret), K(tx_finish_transfer_out_info)); + } else if (CLICK_FAIL(on_replay_success_(scn, tx_finish_transfer_out_info, ctx))) { + LOG_WARN("failed to do on_replay_success_", K(ret), K(tx_finish_transfer_out_info)); + } else if (CLICK_FAIL(ObTabletCreateDeleteMdsUserData::set_tablet_empty_shell_trigger(tx_finish_transfer_out_info.src_ls_id_))) { + LOG_WARN("failed to set_tablet_empty_shell_trigger", K(ret), K(tx_finish_transfer_out_info)); + } + return ret; +} + +int ObTabletFinishTransferOutHelper::on_replay_success_( + const share::SCN &scn, + const ObTXFinishTransferOutInfo &tx_finish_transfer_out_info, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + const int64_t start_ts = ObTimeUtil::current_time(); + ObLSService *ls_svr = NULL; + ObLSHandle ls_handle; + ObLS *ls = NULL; + + FLOG_INFO("[TRANSFER] start tx finish transfer out on_replay_success_", K(scn), K(tx_finish_transfer_out_info)); +#ifdef ERRSIM + SERVER_EVENT_ADD("transfer", "tx_finish_transfer_out", + "stage", "on_replay_success", + "tenant_id", MTL_ID(), + "src_ls_id", tx_finish_transfer_out_info.src_ls_id_.id(), + "dest_ls_id", tx_finish_transfer_out_info.dest_ls_id_.id(), + "finish_scn", tx_finish_transfer_out_info.finish_scn_, + "tablet_count", tx_finish_transfer_out_info.tablet_list_.count()); +#endif + + if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls svr should not be NULL", K(ret), KP(ls_svr)); + } else if (CLICK_FAIL(ls_svr->get_ls(tx_finish_transfer_out_info.src_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(tx_finish_transfer_out_info), K(tx_finish_transfer_out_info)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", K(ret), K(tx_finish_transfer_out_info), K(ls_handle)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < tx_finish_transfer_out_info.tablet_list_.count(); ++i) { + const share::ObTransferTabletInfo &tablet_info = tx_finish_transfer_out_info.tablet_list_.at(i); + ObTabletFinishTransferOutReplayExecutor executor; + if (OB_FAIL(executor.init(scn, tx_finish_transfer_out_info.src_ls_id_, tx_finish_transfer_out_info.dest_ls_id_, tablet_info, ctx))) { + LOG_WARN("failed to init tablet finish transfer out replay executor", K(ret), K(tx_finish_transfer_out_info), K(tablet_info)); + } else if (OB_FAIL(executor.execute(scn, tx_finish_transfer_out_info.src_ls_id_, tablet_info.tablet_id_))) { + LOG_WARN("failed to do finish transfer out replay execute", K(ret), K(tx_finish_transfer_out_info), K(tablet_info)); + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to replay tablet finish transfer out", K(ret), K(scn), K(tablet_info)); + } + } + if (i == tx_finish_transfer_out_info.tablet_list_.count() / 2) { +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", + "AFTER_PART_ON_REDO_FINISH_TRANSFER_OUT", + "src_ls_id", + tx_finish_transfer_out_info.src_ls_id_.id(), + "dest_ls_id", + tx_finish_transfer_out_info.dest_ls_id_.id()); +#endif + DEBUG_SYNC(AFTER_PART_ON_REDO_FINISH_TRANSFER_OUT); + } + } +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", + "AFTER_ON_REDO_FINISH_TRANSFER_OUT", + "src_ls_id", + tx_finish_transfer_out_info.src_ls_id_.id(), + "dest_ls_id", + tx_finish_transfer_out_info.dest_ls_id_.id()); +#endif + DEBUG_SYNC(AFTER_ON_REDO_FINISH_TRANSFER_OUT); + CLICK(); + if (OB_FAIL(ret)) { + LOG_WARN("tx finish transfer out on_replay_success_ failed", K(ret), K(scn), K(tx_finish_transfer_out_info)); + ret = OB_EAGAIN; + } else { + ls->get_tablet_gc_handler()->set_tablet_persist_trigger(); + LOG_INFO("[TRANSFER] finish tx finish transfer out on_replay_success_", K(scn), K(tx_finish_transfer_out_info), + "cost_ts", ObTimeUtil::current_time() - start_ts); + } + + return ret; +} + +/******************ObTabletFinishTransferInReplayExecutor*********************/ +class ObTabletFinishTransferInReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObTabletFinishTransferInReplayExecutor(); + virtual ~ObTabletFinishTransferInReplayExecutor(); + + int init( + const share::SCN &scn, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const share::ObTransferTabletInfo &tablet_info, + mds::BufferCtx &buffer_ctx); +protected: + virtual bool is_replay_update_user_data_() const override + { + return true; + } + + virtual int do_replay_(ObTabletHandle &tablet_handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return true; + } + +private: + int check_dest_transfer_tablet_(ObTabletHandle &tablet_handle); + int check_transfer_table_replaced_(ObTabletHandle &tablet_handle); + int try_make_dest_ls_rebuild_(); + int set_dest_ls_rebuild_(); + +private: + share::SCN scn_; + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + share::ObTransferTabletInfo tablet_info_; + mds::BufferCtx *buffer_ctx_; + DISALLOW_COPY_AND_ASSIGN(ObTabletFinishTransferInReplayExecutor); +}; + +ObTabletFinishTransferInReplayExecutor::ObTabletFinishTransferInReplayExecutor() + :logservice::ObTabletReplayExecutor(), + scn_(), + src_ls_id_(), + dest_ls_id_(), + tablet_info_(), + buffer_ctx_(nullptr) +{ +} + +ObTabletFinishTransferInReplayExecutor::~ObTabletFinishTransferInReplayExecutor() +{ +} + +int ObTabletFinishTransferInReplayExecutor::init( + const share::SCN &scn, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const share::ObTransferTabletInfo &tablet_info, + mds::BufferCtx &buffer_ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("tablet finish transfer out replay executor init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!scn.is_valid()) + || OB_UNLIKELY(!src_ls_id.is_valid()) + || OB_UNLIKELY(!dest_ls_id.is_valid()) + || OB_UNLIKELY(!tablet_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid argument", KR(ret), K(scn), K(src_ls_id), K(dest_ls_id), K(tablet_info)); + } else { + scn_ = scn; + src_ls_id_ = src_ls_id; + dest_ls_id_ = dest_ls_id; + tablet_info_ = tablet_info; + buffer_ctx_ = &buffer_ctx; + scn_ = scn; + is_inited_ = true; + } + return ret; +} + +int ObTabletFinishTransferInReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + ObLSService *ls_svr = NULL; + ObLSHandle ls_handle; + ObLS *ls = NULL; + ObTabletCreateDeleteMdsUserData user_data; + mds::MdsCtx &user_ctx = static_cast(*buffer_ctx_); + ObTablet *tablet = nullptr; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet finish transfer out replay executor do not init", K(ret)); + } else if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls svr should not be NULL", K(ret), KP(ls_svr)); + } else if (OB_FAIL(ls_svr->get_ls(dest_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(dest_ls_id_), K(tablet_info_)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", K(ret), K(dest_ls_id_), K(ls_handle)); + } else if (OB_FAIL(check_dest_transfer_tablet_(tablet_handle))) { + LOG_WARN("failed to check src transfer tablet", K(ret), K(tablet_handle)); + } else if (OB_FAIL(check_transfer_table_replaced_(tablet_handle))) { + LOG_WARN("failed to check transfer table replaced", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_info_)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet data", K(ret), KPC(tablet)); + } else { + user_data.tablet_status_ = ObTabletStatus::NORMAL; + user_data.transfer_ls_id_.reset(); + user_data.data_type_ = ObTabletMdsUserDataType::FINISH_TRANSFER_IN; + if (OB_FAIL(replay_to_mds_table_(tablet_handle, user_data, user_ctx, scn_))) { + LOG_WARN("failed to replay to tablet", K(ret)); + } else { + LOG_INFO("succeed replay finish transfer in to mds table", KP(tablet), K(user_data), K(scn_)); + } +#ifdef ERRSIM + ObTransferEventRecorder::record_tablet_transfer_event("tx_finish_transfer_in", + dest_ls_id_, tablet->get_tablet_meta().tablet_id_, + tablet->get_tablet_meta().transfer_info_.transfer_seq_, user_data.tablet_status_, + ret); +#endif + } + return ret; +} + +int ObTabletFinishTransferInReplayExecutor::check_dest_transfer_tablet_( + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + const int64_t transfer_seq = tablet_info_.transfer_seq(); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet start transfer out replay executor do not init", K(ret)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_info_), K(src_ls_id_), K(dest_ls_id_)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet data", K(ret), KPC(tablet)); + } else if (ObTabletStatus::TRANSFER_IN != user_data.tablet_status_ + || transfer_seq + 1 != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tablet tx data is unexpected", + K(ret), + K(user_data), + K(scn_), + K(tablet->get_tablet_meta()), + K(ObTabletStatus::get_str(user_data.tablet_status_)), + K(transfer_seq), + K(user_data), + KPC(tablet)); + } + return ret; +} + +int ObTabletFinishTransferInReplayExecutor::check_transfer_table_replaced_( + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + bool all_replaced = false; + bool can_skip_check = false; + const uint64_t tenant_id = MTL_ID(); + ObTablet *tablet = tablet_handle.get_obj(); + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet start transfer out replay executor do not init", K(ret)); + } else if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_handle)); + } else if (OB_FAIL(ObTabletFinishTransferUtil::check_transfer_table_replaced(tablet_handle, all_replaced))) { + LOG_WARN("failed to check transfer table replace", K(ret), KPC(tablet)); + } else if (all_replaced) { + //do nothing + } else if (OB_FAIL(ObTabletFinishTransferUtil::can_skip_check_transfer_tablets(tenant_id, dest_ls_id_, scn_, can_skip_check))) { + LOG_WARN("failed to do can skip check transfer tablets", K(ret), K_(dest_ls_id), K_(scn)); + } + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_TRANSFER_NEED_REBUILD ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_TRANSFER_NEED_REBUILD", K(ret)); + can_skip_check = false; + all_replaced = false; + ret = OB_SUCCESS; + } + } +#endif + + if (OB_FAIL(ret)) { + } else if (can_skip_check || all_replaced) { + //do nothing + } else { + ret = OB_EAGAIN; + LOG_WARN("transfer table still exist, need retry", K(ret), K(can_skip_check), K(all_replaced), KPC(tablet)); + if (OB_SUCCESS != (tmp_ret = (try_make_dest_ls_rebuild_()))) { + LOG_WARN("failed to try make dest ls rebuild", K(tmp_ret), K(tablet_info_), K(src_ls_id_), K(dest_ls_id_)); + } + } + return ret; +} + +int ObTabletFinishTransferInReplayExecutor::try_make_dest_ls_rebuild_() +{ + int ret = OB_SUCCESS; + ObLSService *ls_svr = NULL; + ObLSHandle ls_handle; + ObLS *ls = NULL; + share::SCN max_decided_scn; + ObTabletHandle src_tablet_handle; + bool need_rebuild = false; + + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet start transfer out replay executor do not init", K(ret)); + } else if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls svr should not be NULL", K(ret), KP(ls_svr)); + } else if (OB_FAIL(ls_svr->get_ls(src_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(src_ls_id_), K(tablet_info_)); + if (OB_LS_NOT_EXIST == ret) { + //overwrite ret + bool is_ls_deleted = true; + if (OB_FAIL(ObStorageHAUtils::check_ls_deleted(src_ls_id_, is_ls_deleted))) { + LOG_WARN("failed to get ls status", K(ret), K(src_ls_id_)); + } else if (!is_ls_deleted) { + need_rebuild = true; + } else { + need_rebuild = false; + } + } + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), K(src_ls_id_), K(ls_handle)); + } else if (OB_FAIL(ls->get_max_decided_scn(max_decided_scn))) { + LOG_WARN("failed to get max decided scn", K(ret), KPC(ls), K(src_ls_id_)); + } else if (max_decided_scn <= scn_) { + need_rebuild = false; + //src still exist transfer out tablet, need wait + } else if (OB_FAIL(ls->ha_get_tablet(tablet_info_.tablet_id_, src_tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + need_rebuild = true; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to do ha get tablet", K(ret), K(tablet_info_), K(scn_)); + } + } else { + need_rebuild = false; + } + +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = EN_TRANSFER_NEED_REBUILD ? : OB_SUCCESS; + if (OB_FAIL(ret)) { + STORAGE_LOG(ERROR, "fake EN_TRANSFER_NEED_REBUILD", K(ret)); + need_rebuild = true; + ret = OB_SUCCESS; + } + } +#endif + + if (OB_SUCC(ret) && need_rebuild) { + if (OB_FAIL(set_dest_ls_rebuild_())) { + LOG_WARN("failed to set dest ls rebuild", K(ret), K(dest_ls_id_)); + } + } + return ret; +} + +int ObTabletFinishTransferInReplayExecutor::set_dest_ls_rebuild_() +{ + int ret = OB_SUCCESS; + ObRebuildService *rebuild_service = nullptr; + const ObLSRebuildType rebuild_type(ObLSRebuildType::TRANSFER); + if (OB_ISNULL(rebuild_service = MTL(ObRebuildService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rebuild should not be null", K(ret), KP(rebuild_service)); + } else if (OB_FAIL(rebuild_service->add_rebuild_ls(dest_ls_id_, rebuild_type))) { + LOG_WARN("failed to add rebuild ls", K(ret), K(dest_ls_id_), K(rebuild_type)); + } + return ret; +} + +/******************ObTabletStartTransferInHelper*********************/ +int ObTabletFinishTransferInHelper::on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObTXFinishTransferInInfo tx_finish_transfer_in_info; + int64_t pos = 0; + const bool for_replay = false; + + if (OB_ISNULL(buf) || len < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on register finish transfer in get invalid argument", K(ret), KP(buf), K(len)); + } else if (CLICK_FAIL(tx_finish_transfer_in_info.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize tx finish transfer in info", K(ret), K(len), K(pos)); + } else if (!tx_finish_transfer_in_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tx finish transfer in info is unexpected", K(ret), K(tx_finish_transfer_in_info)); + } else if (CLICK_FAIL(on_register_success_(tx_finish_transfer_in_info, ctx))) { + LOG_WARN("failed to do on register success", K(ret), K(tx_finish_transfer_in_info)); + } + return ret; +} + +int ObTabletFinishTransferInHelper::on_register_success_( + const ObTXFinishTransferInInfo &tx_finish_transfer_in_info, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObLSService *ls_svr = NULL; + ObLSHandle ls_handle; + ObLS *ls = NULL; + const share::ObLSID &dest_ls_id = tx_finish_transfer_in_info.dest_ls_id_; + const int64_t start_ts = ObTimeUtil::current_time(); + LOG_INFO("[TRANSFER] start tx finish transfer in on_register_success_", K(tx_finish_transfer_in_info)); +#ifdef ERRSIM + SERVER_EVENT_ADD("transfer", "tx_finish_transfer_in", + "stage", "on_register_success", + "tenant_id", MTL_ID(), + "src_ls_id", tx_finish_transfer_in_info.src_ls_id_.id(), + "dest_ls_id", tx_finish_transfer_in_info.dest_ls_id_.id(), + "start_scn", tx_finish_transfer_in_info.start_scn_, + "tablet_count", tx_finish_transfer_in_info.tablet_list_.count()); +#endif + + if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls svr should not be NULL", K(ret), KP(ls_svr)); + } else if (CLICK_FAIL(ls_svr->get_ls(dest_ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(dest_ls_id), K(tx_finish_transfer_in_info)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", K(ret), K(dest_ls_id), K(ls_handle)); + } else if (CLICK_FAIL(check_ls_replay_scn_(tx_finish_transfer_in_info, ls))) { + LOG_WARN("check ls replay scn", K(ret), K(tx_finish_transfer_in_info), KPC(ls)); + } else if (CLICK_FAIL(check_transfer_in_tablets_validity_(tx_finish_transfer_in_info, ls))) { + LOG_WARN("failed to check transfer in tablets validity", K(ret), K(tx_finish_transfer_in_info) + , "ls_meta", ls->get_ls_meta()); + } else if (CLICK_FAIL(update_transfer_tablets_normal_(tx_finish_transfer_in_info, ls, ctx))) { + LOG_WARN("failed to update transfer tablets normal", K(ret), K(tx_finish_transfer_in_info), KPC(ls)); + } + + if (OB_FAIL(ret)) { + LOG_WARN("tx finish transfer in on_register_success_ failed", K(ret), K(tx_finish_transfer_in_info)); + } else { + LOG_INFO("[TRANSFER] finish tx finish transfer in on_register_success_", K(tx_finish_transfer_in_info), + "cost_ts", ObTimeUtil::current_time() - start_ts); + } + + return ret; +} + +int ObTabletFinishTransferInHelper::check_ls_replay_scn_( + const ObTXFinishTransferInInfo &tx_finish_transfer_in_info, + storage::ObLS *dest_ls) +{ + int ret = OB_SUCCESS; + SCN max_decided_scn; + if (OB_ISNULL(dest_ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dest ls should not be null", K(ret)); + } else if (OB_FAIL(dest_ls->get_max_decided_scn(max_decided_scn))) { + LOG_WARN("failed to get max decided scn", K(ret), KPC(dest_ls)); + } else if (max_decided_scn < tx_finish_transfer_in_info.start_scn_) { + ret = OB_EAGAIN; + LOG_INFO("ls replay scn do not greater than max decided scn", K(ret), K(tx_finish_transfer_in_info), KPC(dest_ls), K(max_decided_scn)); + } + return ret; +} + +int ObTabletFinishTransferInHelper::check_transfer_in_tablets_validity_( + const ObTXFinishTransferInInfo &tx_finish_transfer_in_info, + storage::ObLS *ls) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + const common::ObSArray &tablet_list = tx_finish_transfer_in_info.tablet_list_; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_list.count(); ++i) { + MDS_TG(10_ms); + const share::ObTransferTabletInfo &tablet_info = tablet_list.at(i); + bool all_replaced = false; + ObTabletHandle tablet_handle; + if (CLICK_FAIL(inner_check_transfer_in_tablet_validity_(tablet_info, ls))) { + LOG_WARN("failed to inner check transfer in tablet validity", K(ret), K(tablet_info), KPC(ls)); + } else if (CLICK_FAIL(ls->get_tablet(tablet_info.tablet_id_, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get transfer in tablet", K(ret), K(tablet_info)); + } else if (CLICK_FAIL(ObTabletFinishTransferUtil::check_transfer_table_replaced(tablet_handle, all_replaced))) { + LOG_WARN("failed to check transfer table replace", K(ret), K(tablet_info), KPC(ls)); + } else if (all_replaced) { + //do nothing + } else { + ret = OB_EAGAIN; + LOG_WARN("transfer table still exit, need retry", K(ret), K(tablet_info)); + } + } + return ret; +} + +int ObTabletFinishTransferInHelper::inner_check_transfer_in_tablet_validity_( + const share::ObTransferTabletInfo &tablet_info, + storage::ObLS *ls) +{ + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = NULL; + ObTabletCreateDeleteMdsUserData data; + const common::ObTabletID &tablet_id = tablet_info.tablet_id(); + const int64_t transfer_seq = tablet_info.transfer_seq(); + + if (CLICK_FAIL(ls->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_info)); + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet data", K(ret), KPC(tablet)); + } else if (ObTabletStatus::TRANSFER_IN != data.tablet_status_ + || transfer_seq + 1 != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tablet tx data is unexpected", + K(ret), + K(ObTabletStatus::get_str(data.tablet_status_)), + K(transfer_seq), + K(data), + KPC(tablet)); + } + return ret; +} + +int ObTabletFinishTransferInHelper::update_transfer_tablets_normal_( + const ObTXFinishTransferInInfo &tx_finish_transfer_in_info, + storage::ObLS *src_ls, + mds::BufferCtx &ctx) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + const common::ObSArray &tablet_list = tx_finish_transfer_in_info.tablet_list_; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_list.count(); ++i) { + const share::ObTransferTabletInfo &tablet_info = tablet_list.at(i); + if (OB_FAIL(update_transfer_tablet_normal_(tablet_info, src_ls, ctx))) { + LOG_WARN("failed to update transfer tablet normal", K(ret), K(tablet_info), KPC(src_ls)); + } + } + return ret; +} + +int ObTabletFinishTransferInHelper::update_transfer_tablet_normal_( + const share::ObTransferTabletInfo &tablet_info, + storage::ObLS *ls, + mds::BufferCtx &ctx) +{ + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = NULL; + ObTabletCreateDeleteMdsUserData data; + mds::MdsCtx &user_ctx = static_cast(ctx); + + if (!tablet_info.is_valid() || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check src transfer tablets get invalid argument", K(ret), K(tablet_info), KP(ls)); + } else if (CLICK_FAIL(ls->get_tablet(tablet_info.tablet_id(), tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_info)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_info)); + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet), K(tablet_info)); + } else if (ObTabletStatus::TRANSFER_IN != data.tablet_status_ + || tablet_info.transfer_seq() + 1 != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet tx data is unexpected", K(ret), KPC(tablet), K(tablet_info)); + } else { + LOG_INFO("[TRANSFER] update transfer tablet normal", K(ret), K(tablet_info), K(data)); + data.tablet_status_ = ObTabletStatus::NORMAL; + data.transfer_ls_id_.reset(); + data.data_type_ = ObTabletMdsUserDataType::FINISH_TRANSFER_IN; + if (CLICK_FAIL(ls->get_tablet_svr()->set_tablet_status(tablet->get_tablet_meta().tablet_id_, data, user_ctx))) { + LOG_WARN("failed to set mds data", K(ret), K(data)); + } +#ifdef ERRSIM + ObTransferEventRecorder::record_tablet_transfer_event("tx_finish_transfer_in", + ls->get_ls_id(), tablet_info.tablet_id(), + tablet->get_tablet_meta().transfer_info_.transfer_seq_, data.tablet_status_, ret); +#endif + } + return ret; +} + +int ObTabletFinishTransferInHelper::on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObTXFinishTransferInInfo tx_finish_transfer_in_info; + int64_t pos = 0; + bool skip_replay = false; + const bool for_replay = true; + + if (OB_ISNULL(buf) || len < 0 || !scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on_replay_success_ finish transfer in get invalid argument", K(ret), KP(buf), K(len), K(scn)); + } else if (CLICK_FAIL(tx_finish_transfer_in_info.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize tx finish transfer in info", K(ret), K(len), K(pos)); + } else if (!tx_finish_transfer_in_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tx finish transfer in info is unexpected", K(ret), K(tx_finish_transfer_in_info)); + } else if (CLICK_FAIL(on_replay_success_(scn, tx_finish_transfer_in_info, ctx))) { + LOG_WARN("failed to do on_replay_success_", K(ret), K(tx_finish_transfer_in_info)); + } + return ret; +} + +int ObTabletFinishTransferInHelper::on_replay_success_( + const share::SCN &scn, + const ObTXFinishTransferInInfo &tx_finish_transfer_in_info, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + const int64_t start_ts = ObTimeUtil::current_time(); + LOG_INFO("[TRANSFER] start tx finish transfer in on_replay_success_", K(scn), K(tx_finish_transfer_in_info)); +#ifdef ERRSIM + SERVER_EVENT_ADD("transfer", "tx_finish_transfer_in", + "stage", "on_replay_success", + "tenant_id", MTL_ID(), + "src_ls_id", tx_finish_transfer_in_info.src_ls_id_.id(), + "dest_ls_id", tx_finish_transfer_in_info.dest_ls_id_.id(), + "start_scn", tx_finish_transfer_in_info.start_scn_, + "tablet_count", tx_finish_transfer_in_info.tablet_list_.count()); +#endif + ObLSService *ls_svr = NULL; + ObLSHandle ls_handle; + ObLS *ls = NULL; + + if (OB_ISNULL(ls_svr = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls svr should not be NULL", K(ret), KP(ls_svr)); + } else if (CLICK_FAIL(ls_svr->get_ls(tx_finish_transfer_in_info.dest_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(tx_finish_transfer_in_info), K(tx_finish_transfer_in_info)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", K(ret), K(tx_finish_transfer_in_info), K(ls_handle)); + } else if (CLICK_FAIL(check_ls_replay_scn_(tx_finish_transfer_in_info, ls))) { + LOG_WARN("failed to check ls replay scn", K(ret), K(tx_finish_transfer_in_info)); + } else { + CLICK(); + for (int64_t i = 0; OB_SUCC(ret) && i < tx_finish_transfer_in_info.tablet_list_.count(); ++i) { + const share::ObTransferTabletInfo &tablet_info = tx_finish_transfer_in_info.tablet_list_.at(i); + ObTabletFinishTransferInReplayExecutor executor; + if (OB_FAIL(executor.init(scn, tx_finish_transfer_in_info.src_ls_id_, + tx_finish_transfer_in_info.dest_ls_id_, tablet_info, ctx))) { + LOG_WARN("failed to init tablet finish transfer in replay executor", K(ret), K(tx_finish_transfer_in_info), K(tablet_info)); + } else if (OB_FAIL(executor.execute(scn, tx_finish_transfer_in_info.dest_ls_id_, tablet_info.tablet_id_))) { + LOG_WARN("failed to do transfer finish in executor", K(ret), K(tx_finish_transfer_in_info), K(tablet_info)); + } + } + } + + if (OB_FAIL(ret)) { + LOG_WARN("tx finish transfer in on_replay_success_ failed", K(ret), K(scn), K(tx_finish_transfer_in_info)); + ret = OB_EAGAIN; + } else { + LOG_INFO("[TRANSFER] finish tx finish transfer in on_replay_success_", K(scn), K(tx_finish_transfer_in_info), + "cost_ts", ObTimeUtil::current_time() - start_ts); + } + + return ret; +} + +} +} diff --git a/src/storage/tablet/ob_tablet_finish_transfer_mds_helper.h b/src/storage/tablet/ob_tablet_finish_transfer_mds_helper.h new file mode 100644 index 000000000..90d06f7e7 --- /dev/null +++ b/src/storage/tablet/ob_tablet_finish_transfer_mds_helper.h @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_FINISH_TRANSFER_MDS_HELPER +#define OCEANBASE_STORAGE_OB_TABLET_FINISH_TRANSFER_MDS_HELPER + +#include +#include "lib/container/ob_iarray.h" +#include "lib/utility/ob_macro_utils.h" +#include "src/storage/high_availability/ob_storage_ha_struct.h" + +namespace oceanbase +{ +namespace share +{ +class SCN; +class ObLSID; +struct ObTransferTabletInfo; +} +namespace storage +{ + +namespace mds +{ +struct BufferCtx; +} + +class ObLS; +class ObTabletHandle; +struct ObTXFinishTransferInInfo; +struct ObTXFinishTransferOutInfo; + +class ObTabletFinishTransferUtil +{ +public: + static int check_transfer_table_replaced( + ObTabletHandle &tablet_handle, + bool &all_replaced); + static int can_skip_check_transfer_tablets( + const uint64_t tenant_id, + const share::ObLSID &ls_id /* transfer dest ls */, + const share::SCN &scn /* finish transfer in log scn */, + bool &can_skip_check); + +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletFinishTransferUtil); +}; + +class ObTabletFinishTransferOutHelper +{ +public: + static int on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx); + static int on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx); +private: + static int on_register_success_( + const ObTXFinishTransferOutInfo &tx_finish_transfer_out_info, + mds::BufferCtx &ctx); + static int check_transfer_out_tablets_validity_( + const ObTXFinishTransferOutInfo &tx_finish_transfer_out_info, + storage::ObLS *ls); + static int inner_check_transfer_out_tablet_validity_( + const share::ObTransferTabletInfo &tablet_info, + storage::ObLS *ls); + static int update_transfer_tablets_deleted_( + const ObTXFinishTransferOutInfo &tx_finish_transfer_out_info, + storage::ObLS *ls, + mds::BufferCtx &ctx); + static int update_transfer_tablet_deleted_( + const share::ObTransferTabletInfo &tablet_info, + storage::ObLS *ls, + mds::BufferCtx &ctx); + + static int on_replay_success_( + const share::SCN &scn, + const ObTXFinishTransferOutInfo &tx_finish_transfer_out_info, + mds::BufferCtx &ctx); + +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletFinishTransferOutHelper); +}; + +class ObTabletFinishTransferInHelper +{ +public: + static int on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx); + static int on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx); +private: + static int on_register_success_( + const ObTXFinishTransferInInfo &tx_finish_transfer_in_info, + mds::BufferCtx &ctx); + static int check_ls_replay_scn_( + const ObTXFinishTransferInInfo &tx_finish_transfer_in_info, + storage::ObLS *ls); + + static int check_transfer_in_tablets_validity_( + const ObTXFinishTransferInInfo &tx_finish_transfer_in_info, + storage::ObLS *ls); + static int inner_check_transfer_in_tablet_validity_( + const share::ObTransferTabletInfo &tablet_info, + storage::ObLS *ls); + static int update_transfer_tablets_normal_( + const ObTXFinishTransferInInfo &tx_finish_transfer_in_info, + storage::ObLS *ls, + mds::BufferCtx &ctx); + static int update_transfer_tablet_normal_( + const share::ObTransferTabletInfo &tablet_info, + storage::ObLS *ls, + mds::BufferCtx &ctx); + static int on_replay_success_( + const share::SCN &scn, + const ObTXFinishTransferInInfo &tx_finish_transfer_in_info, + mds::BufferCtx &ctx); + static int can_skip_check_transfer_tablets_( + ObLS &ls, + bool &can_skip_check); + + +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletFinishTransferInHelper); +}; + + +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_FINISH_TRANSFER_MDS_HELPER diff --git a/src/storage/tablet/ob_tablet_full_medium_info.cpp b/src/storage/tablet/ob_tablet_full_medium_info.cpp new file mode 100644 index 000000000..1a7bdeaf2 --- /dev/null +++ b/src/storage/tablet/ob_tablet_full_medium_info.cpp @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_full_medium_info.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/utility/ob_macro_utils.h" + +#define USING_LOG_PREFIX STORAGE + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +ObTaletExtraMediumInfo::ObTaletExtraMediumInfo() + : compat_(MEDIUM_LIST_VERSION), + last_compaction_type_(0), + wait_check_flag_(0), + reserved_(0), + last_medium_scn_(0) +{ +} + +void ObTaletExtraMediumInfo::reset() +{ + compat_ = MEDIUM_LIST_VERSION; + last_compaction_type_ = 0; + wait_check_flag_ = 0; + reserved_ = 0; + last_medium_scn_ = 0; +} + +int ObTaletExtraMediumInfo::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, + info_, + last_medium_scn_); + + return ret; +} + +int ObTaletExtraMediumInfo::deserialize(const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, + info_, + last_medium_scn_); + + return ret; +} + +int64_t ObTaletExtraMediumInfo::get_serialize_size() const +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, + info_, + last_medium_scn_); + + return len; +} + + +ObTabletFullMediumInfo::ObTabletFullMediumInfo() + : extra_medium_info_(), + medium_info_list_() +{ +} + +void ObTabletFullMediumInfo::reset() +{ + extra_medium_info_.reset(); + medium_info_list_.reset(); +} + +int ObTabletFullMediumInfo::assign(common::ObIAllocator &allocator, const ObTabletFullMediumInfo &other) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(medium_info_list_.assign(other.medium_info_list_, allocator))) { + LOG_WARN("failed to assign", K(ret), K(other)); + } else { + extra_medium_info_.info_ = other.extra_medium_info_.info_; + extra_medium_info_.last_medium_scn_ = other.extra_medium_info_.last_medium_scn_; + } + + return ret; +} + +int ObTabletFullMediumInfo::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, + extra_medium_info_, + medium_info_list_); + + return ret; +} + +int ObTabletFullMediumInfo::deserialize(common::ObIAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(extra_medium_info_.deserialize(buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(medium_info_list_.deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } + + return ret; +} + +int64_t ObTabletFullMediumInfo::get_serialize_size() const +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, + extra_medium_info_, + medium_info_list_); + + return len; +} +} // namespace storage +} // namespace oceanbase \ No newline at end of file diff --git a/src/storage/tablet/ob_tablet_full_medium_info.h b/src/storage/tablet/ob_tablet_full_medium_info.h new file mode 100644 index 000000000..23e84b4a7 --- /dev/null +++ b/src/storage/tablet/ob_tablet_full_medium_info.h @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_FULL_MEDIUM_INFO +#define OCEANBASE_STORAGE_OB_TABLET_FULL_MEDIUM_INFO + +#include +#include "lib/utility/ob_print_utils.h" +#include "storage/compaction/ob_compaction_util.h" +#include "storage/tablet/ob_tablet_dumped_medium_info.h" + +namespace oceanbase +{ +namespace common +{ +class ObIAllocator; +} + +namespace storage +{ +class ObTaletExtraMediumInfo +{ +public: + ObTaletExtraMediumInfo(); + ~ObTaletExtraMediumInfo() = default; +public: + void reset(); + + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize(const char *buf, const int64_t data_len, int64_t &pos); + int64_t get_serialize_size() const; + + TO_STRING_KV(K_(info), + K_(compat), + K_(last_compaction_type), + K_(wait_check_flag), + K_(last_medium_scn)); +private: + static const int64_t MEDIUM_LIST_VERSION = 1; + static const int32_t MEDIUM_LIST_INFO_RESERVED_BITS = 51; +public: + union + { + uint64_t info_; + struct + { + uint64_t compat_ : 8; + uint64_t last_compaction_type_ : 4; // check inner_table when last_compaction is major + uint64_t wait_check_flag_ : 1; // true: need check finish, false: don't need check + uint64_t reserved_ : MEDIUM_LIST_INFO_RESERVED_BITS; + }; + }; + int64_t last_medium_scn_; +}; + +class ObTabletFullMediumInfo +{ +public: + ObTabletFullMediumInfo(); + ~ObTabletFullMediumInfo() = default; + ObTabletFullMediumInfo(const ObTabletFullMediumInfo &) = delete; + ObTabletFullMediumInfo &operator=(const ObTabletFullMediumInfo &) = delete; +public: + void reset(); + int assign(common::ObIAllocator &allocator, const ObTabletFullMediumInfo &other); + + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize(common::ObIAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos); + int64_t get_serialize_size() const; + + TO_STRING_KV(K_(extra_medium_info), K_(medium_info_list)); +public: + ObTaletExtraMediumInfo extra_medium_info_; + ObTabletDumpedMediumInfo medium_info_list_; +}; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_FULL_MEDIUM_INFO diff --git a/src/storage/tablet/ob_tablet_full_memory_mds_data.cpp b/src/storage/tablet/ob_tablet_full_memory_mds_data.cpp new file mode 100644 index 000000000..2d1a4126c --- /dev/null +++ b/src/storage/tablet/ob_tablet_full_memory_mds_data.cpp @@ -0,0 +1,254 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_full_memory_mds_data.h" +#include "lib/allocator/ob_allocator.h" +#include "storage/blockstore/ob_shared_block_reader_writer.h" +#include "storage/tablet/ob_tablet_mds_data.h" +#include "storage/tablet/ob_tablet_obj_load_helper.h" + +#define USING_LOG_PREFIX STORAGE + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +ObTabletFullMemoryMdsData::ObTabletFullMemoryMdsData() + : is_inited_(false), + tablet_status_uncommitted_kv_(), + tablet_status_committed_kv_(), + aux_tablet_info_uncommitted_kv_(), + aux_tablet_info_committed_kv_(), + medium_info_list_(), + auto_inc_seq_() +{ +} + +ObTabletFullMemoryMdsData::~ObTabletFullMemoryMdsData() +{ + reset(); +} + +int ObTabletFullMemoryMdsData::init(common::ObArenaAllocator &allocator) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_FAIL(medium_info_list_.medium_info_list_.init(allocator))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else { + is_inited_ = true; + } + + return ret; +} + +int ObTabletFullMemoryMdsData::init(common::ObArenaAllocator &allocator, const ObTabletMdsData &mds_data) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_FAIL(read_mds_dump_kv(allocator, mds_data.tablet_status_.uncommitted_kv_, tablet_status_uncommitted_kv_))) { + LOG_WARN("failed to read mds dump kv", K(ret)); + } else if (OB_FAIL(read_mds_dump_kv(allocator, mds_data.tablet_status_.committed_kv_, tablet_status_committed_kv_))) { + LOG_WARN("failed to read mds dump kv", K(ret)); + } else if (OB_FAIL(read_mds_dump_kv(allocator, mds_data.aux_tablet_info_.uncommitted_kv_, aux_tablet_info_uncommitted_kv_))) { + LOG_WARN("failed to read mds dump kv", K(ret)); + } else if (OB_FAIL(read_mds_dump_kv(allocator, mds_data.aux_tablet_info_.committed_kv_, aux_tablet_info_committed_kv_))) { + LOG_WARN("failed to read mds dump kv", K(ret)); + } else if (OB_FAIL(read_medium_info_list(allocator, mds_data.medium_info_list_, medium_info_list_.medium_info_list_))) { + LOG_WARN("failed to assign medium info list", K(ret), K(mds_data)); + } else if (OB_FAIL(read_auto_inc_seq(allocator, mds_data.auto_inc_seq_, auto_inc_seq_))) { + LOG_WARN("failed to read auto inc seq", K(ret)); + } else { + medium_info_list_.extra_medium_info_.info_ = mds_data.extra_medium_info_.info_; + medium_info_list_.extra_medium_info_.last_medium_scn_ = mds_data.extra_medium_info_.last_medium_scn_; + + is_inited_ = true; + } + + return ret; +} + +void ObTabletFullMemoryMdsData::reset() +{ + tablet_status_uncommitted_kv_.reset(); + tablet_status_committed_kv_.reset(); + aux_tablet_info_uncommitted_kv_.reset(); + aux_tablet_info_committed_kv_.reset(); + medium_info_list_.reset(); + auto_inc_seq_.reset(); + is_inited_ = false; +} + +int ObTabletFullMemoryMdsData::assign(const ObTabletFullMemoryMdsData &other, common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + + if (this != &other) { + reset(); + + if (OB_FAIL(tablet_status_uncommitted_kv_.assign(other.tablet_status_uncommitted_kv_, allocator))) { + LOG_WARN("failed to assign", K(ret), K(other)); + } else if (OB_FAIL(tablet_status_committed_kv_.assign(other.tablet_status_committed_kv_, allocator))) { + LOG_WARN("failed to assign", K(ret), K(other)); + } else if (OB_FAIL(aux_tablet_info_uncommitted_kv_.assign(other.aux_tablet_info_uncommitted_kv_, allocator))) { + LOG_WARN("failed to assign", K(ret), K(other)); + } else if (OB_FAIL(aux_tablet_info_committed_kv_.assign(other.aux_tablet_info_committed_kv_, allocator))) { + LOG_WARN("failed to assign", K(ret), K(other)); + } else if (OB_FAIL(medium_info_list_.assign(allocator, other.medium_info_list_))) { + LOG_WARN("failed to assign", K(ret), K(other)); + } else if (OB_FAIL(auto_inc_seq_.assign(allocator, other.auto_inc_seq_))) { + LOG_WARN("failed to assign", K(ret), K(other)); + } else { + is_inited_ = true; + } + } + + return ret; +} + +int ObTabletFullMemoryMdsData::read_mds_dump_kv( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &mds_dump_kv_addr, + mds::MdsDumpKV &dump_kv) +{ + int ret = OB_SUCCESS; + const mds::MdsDumpKV *ptr = nullptr; + + if (OB_UNLIKELY(!mds_dump_kv_addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(mds_dump_kv_addr)); + } else if (OB_FAIL(ObTabletMdsData::load_mds_dump_kv(allocator, mds_dump_kv_addr, ptr))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_ISNULL(ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, ptr is null", K(ret), KP(ptr)); + } else if (OB_FAIL(dump_kv.assign(*ptr, allocator))) { + LOG_WARN("failed to copy mds dump kv", K(ret)); + } + + ObTabletMdsData::free_mds_dump_kv(allocator, ptr); + + return ret; +} + +int ObTabletFullMemoryMdsData::read_medium_info_list( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &medium_info_list_addr, + ObTabletDumpedMediumInfo &medium_info_list) +{ + int ret = OB_SUCCESS; + const ObTabletDumpedMediumInfo *ptr = nullptr; + + if (OB_UNLIKELY(!medium_info_list_addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(medium_info_list_addr)); + } else if (OB_FAIL(ObTabletMdsData::load_medium_info_list(allocator, medium_info_list_addr, ptr))) { + LOG_WARN("failed to load medium info list", K(ret)); + } else if (OB_ISNULL(ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, ptr is null", K(ret), KP(ptr)); + } else if (OB_FAIL(medium_info_list.assign(*ptr, allocator))) { + LOG_WARN("failed to medium info list", K(ret)); + } + + ObTabletMdsData::free_medium_info_list(allocator, ptr); + + return ret; +} + +int ObTabletFullMemoryMdsData::read_auto_inc_seq( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &auto_inc_seq_addr, + share::ObTabletAutoincSeq &auto_inc_seq) +{ + int ret = OB_SUCCESS; + const share::ObTabletAutoincSeq *ptr = nullptr; + ObTabletMemberWrapper auto_inc_seq_wrapper; + + if (OB_FAIL(ObTabletMdsData::fetch_auto_inc_seq(auto_inc_seq_addr, auto_inc_seq_wrapper))) { + LOG_WARN("failed to fetch auto inc seq", K(ret)); + } else if (OB_FAIL(auto_inc_seq_wrapper.get_member(ptr))) { + LOG_WARN("ObTabletMemberWrapper get member failed", K(ret)); + } else if (OB_ISNULL(ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, ptr is null", K(ret), KP(ptr)); + } else if (OB_FAIL(auto_inc_seq.assign(allocator, *ptr))) { + LOG_WARN("failed to copy auto inc seq", K(ret)); + } + + return ret; +} + +int ObTabletFullMemoryMdsData::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, + tablet_status_uncommitted_kv_, + tablet_status_committed_kv_, + aux_tablet_info_uncommitted_kv_, + aux_tablet_info_committed_kv_, + medium_info_list_, + auto_inc_seq_); + + return ret; +} + +int ObTabletFullMemoryMdsData::deserialize(common::ObIAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_FAIL(tablet_status_uncommitted_kv_.deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(tablet_status_committed_kv_.deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(aux_tablet_info_uncommitted_kv_.deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(aux_tablet_info_committed_kv_.deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(medium_info_list_.deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(auto_inc_seq_.deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else { + is_inited_ = true; + LOG_INFO("succeeded to deserialize full memory mds data", K(ret), KPC(this)); + } + + return ret; +} + +int64_t ObTabletFullMemoryMdsData::get_serialize_size() const +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, + tablet_status_uncommitted_kv_, + tablet_status_committed_kv_, + aux_tablet_info_uncommitted_kv_, + aux_tablet_info_committed_kv_, + medium_info_list_, + auto_inc_seq_); + + return len; +} +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_full_memory_mds_data.h b/src/storage/tablet/ob_tablet_full_memory_mds_data.h new file mode 100644 index 000000000..1e6afc4cc --- /dev/null +++ b/src/storage/tablet/ob_tablet_full_memory_mds_data.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_FULL_MEMORY_MDS_DATA +#define OCEANBASE_STORAGE_OB_TABLET_FULL_MEMORY_MDS_DATA + +#include "lib/utility/ob_print_utils.h" +#include "share/ob_tablet_autoincrement_param.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include "storage/tablet/ob_tablet_complex_addr.h" +#include "storage/tablet/ob_tablet_full_medium_info.h" + +namespace oceanbase +{ +namespace common +{ +class ObIAllocator; +class ObArenaAllocator; +} + +namespace storage +{ +class ObTabletMdsData; + +class ObTabletFullMemoryMdsData +{ +public: + ObTabletFullMemoryMdsData(); + ~ObTabletFullMemoryMdsData(); + ObTabletFullMemoryMdsData(const ObTabletFullMemoryMdsData &) = delete; + ObTabletFullMemoryMdsData &operator=(const ObTabletFullMemoryMdsData &) = delete; +public: + int init(common::ObArenaAllocator &allocator); + int init(common::ObArenaAllocator &allocator, const ObTabletMdsData &mds_data); + void reset(); + int assign(const ObTabletFullMemoryMdsData &other, common::ObIAllocator &allocator); +public: + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize(common::ObIAllocator &allocator, const char *buf, const int64_t data_len, int64_t &pos); + int64_t get_serialize_size() const; + + TO_STRING_KV(K_(is_inited), + K_(tablet_status_uncommitted_kv), + K_(tablet_status_committed_kv), + K_(aux_tablet_info_uncommitted_kv), + K_(aux_tablet_info_committed_kv), + K_(medium_info_list), + K_(auto_inc_seq)); +private: + static int read_mds_dump_kv( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &mds_dump_kv_addr, + mds::MdsDumpKV &dump_kv); + static int read_medium_info_list( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &medium_info_list_addr, + ObTabletDumpedMediumInfo &medium_info_list); + static int read_auto_inc_seq( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &auto_inc_seq_addr, + share::ObTabletAutoincSeq &auto_inc_seq); +private: + static const int64_t MEDIUM_LIST_VERSION = 1; + static const int32_t MEDIUM_LIST_INFO_RESERVED_BITS = 52; +public: + bool is_inited_; + mds::MdsDumpKV tablet_status_uncommitted_kv_; + mds::MdsDumpKV tablet_status_committed_kv_; + mds::MdsDumpKV aux_tablet_info_uncommitted_kv_; + mds::MdsDumpKV aux_tablet_info_committed_kv_; + ObTabletFullMediumInfo medium_info_list_; + share::ObTabletAutoincSeq auto_inc_seq_; +}; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_FULL_MEMORY_MDS_DATA diff --git a/src/storage/tablet/ob_tablet_iterator.cpp b/src/storage/tablet/ob_tablet_iterator.cpp index 59feb8501..8ccb0b8f5 100644 --- a/src/storage/tablet/ob_tablet_iterator.cpp +++ b/src/storage/tablet/ob_tablet_iterator.cpp @@ -26,11 +26,11 @@ namespace oceanbase { namespace storage { -ObLSTabletIterator::ObLSTabletIterator(const int64_t timeout_us) +ObLSTabletIterator::ObLSTabletIterator(const ObMDSGetTabletMode mode) : ls_tablet_service_(nullptr), tablet_ids_(), idx_(0), - timeout_us_(timeout_us) + mode_(mode) { } @@ -49,7 +49,7 @@ void ObLSTabletIterator::reset() bool ObLSTabletIterator::is_valid() const { return nullptr != ls_tablet_service_ - && timeout_us_ >= ObTabletCommon::DIRECT_GET_COMMITTED_TABLET_TIMEOUT_US; + && mode_ >= ObMDSGetTabletMode::READ_ALL_COMMITED; } int ObLSTabletIterator::get_next_tablet(ObTabletHandle &handle) @@ -66,9 +66,9 @@ int ObLSTabletIterator::get_next_tablet(ObTabletHandle &handle) ret = OB_ITER_END; } else { const common::ObTabletID &tablet_id = tablet_ids_.at(idx_); - if (OB_FAIL(ls_tablet_service_->get_tablet(tablet_id, handle, timeout_us_)) + if (OB_FAIL(ls_tablet_service_->get_tablet(tablet_id, handle, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S, mode_)) && OB_TABLET_NOT_EXIST != ret) { - LOG_WARN("fail to get tablet", K(ret), K(idx_), K(tablet_id), K_(timeout_us)); + LOG_WARN("fail to get tablet", K(ret), K(idx_), K(tablet_id), K_(mode)); } else { handle.set_wash_priority(WashTabletPriority::WTP_LOW); ++idx_; @@ -170,24 +170,24 @@ int ObHALSTabletIDIterator::get_next_tablet_id(common::ObTabletID &tablet_id) { int ret = OB_SUCCESS; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - ObTabletTxMultiSourceDataUnit tx_data; ObTabletMapKey key; key.ls_id_ = ls_id_; + bool initial_state = true; while (OB_SUCC(ret)) { if (OB_UNLIKELY(tablet_ids_.count() == idx_)) { ret = OB_ITER_END; } else { - tx_data.reset(); + initial_state = true; key.tablet_id_ = tablet_ids_.at(idx_); - if (OB_FAIL(t3m->get_tablet_pointer_tx_data(key, tx_data))) { + if (OB_FAIL(t3m->get_tablet_pointer_initial_state(key, initial_state))) { if (OB_ENTRY_NOT_EXIST == ret) { ++idx_; ret = OB_SUCCESS; } else { - LOG_WARN("failed to get tx data from tablet pointer", K(ret), K(key)); + LOG_WARN("failed to get tablet status from tablet pointer", K(ret), K(key)); } - } else if (ObTabletStatus::MAX == tx_data.tablet_status_ && !need_initial_state_ ) { + } else if (initial_state && !need_initial_state_) { LOG_INFO("tablet is in initial state, should skip", K(ret), K(key)); ++idx_; } else { @@ -200,5 +200,47 @@ int ObHALSTabletIDIterator::get_next_tablet_id(common::ObTabletID &tablet_id) return ret; } + + +ObHALSTabletIterator::ObHALSTabletIterator( + const share::ObLSID &ls_id, + const bool need_initial_state) + : ls_tablet_service_(nullptr), + tablet_id_iter_(ls_id, need_initial_state) +{} + + +ObHALSTabletIterator::~ObHALSTabletIterator() +{} + +bool ObHALSTabletIterator::is_valid() const +{ + return tablet_id_iter_.is_valid(); +} + +void ObHALSTabletIterator::reset() +{ + tablet_id_iter_.reset(); +} + +int ObHALSTabletIterator::get_next_tablet(ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + ObTabletID tablet_id; + handle.reset(); + if (OB_ISNULL(ls_tablet_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls tablet service is nullptr", K(ret), KP(ls_tablet_service_)); + } else if (OB_FAIL(tablet_id_iter_.get_next_tablet_id(tablet_id))) { + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next tablet id", K(ret)); + } + } else if (OB_FAIL(ls_tablet_service_->get_tablet(tablet_id, handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } + + return ret; +} + } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_iterator.h b/src/storage/tablet/ob_tablet_iterator.h index 66466238b..76fa2386e 100644 --- a/src/storage/tablet/ob_tablet_iterator.h +++ b/src/storage/tablet/ob_tablet_iterator.h @@ -34,7 +34,7 @@ class ObLSTabletIterator final { friend class ObLSTabletService; public: - explicit ObLSTabletIterator(const int64_t timeout_us = ObTabletCommon::DEFAULT_GET_TABLET_TIMEOUT_US); + explicit ObLSTabletIterator(const ObMDSGetTabletMode mode); ~ObLSTabletIterator(); ObLSTabletIterator(const ObLSTabletIterator&) = delete; ObLSTabletIterator &operator=(const ObLSTabletIterator&) = delete; @@ -46,12 +46,12 @@ public: void reset(); bool is_valid() const; - TO_STRING_KV(KP_(ls_tablet_service), K_(tablet_ids), K_(idx), K_(timeout_us)); + TO_STRING_KV(KP_(ls_tablet_service), K_(tablet_ids), K_(idx), K_(mode)); private: ObLSTabletService *ls_tablet_service_; common::ObSEArray tablet_ids_; int64_t idx_; - const int64_t timeout_us_; + ObMDSGetTabletMode mode_; }; class ObHALSTabletIDIterator final @@ -77,6 +77,28 @@ private: int64_t idx_; const bool need_initial_state_; }; + + +class ObHALSTabletIterator final +{ + friend class ObLSTabletService; +public: + explicit ObHALSTabletIterator(const share::ObLSID &ls_id, const bool need_initial_state); + ~ObHALSTabletIterator(); + ObHALSTabletIterator(const ObHALSTabletIterator&) = delete; + ObHALSTabletIterator &operator=(const ObHALSTabletIterator&) = delete; +public: + int get_next_tablet(ObTabletHandle &handle); + + void reset(); + bool is_valid() const; + + TO_STRING_KV(KP_(ls_tablet_service), K_(tablet_id_iter)); +private: + ObLSTabletService *ls_tablet_service_; + ObHALSTabletIDIterator tablet_id_iter_; +}; + } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_mds_data.cpp b/src/storage/tablet/ob_tablet_mds_data.cpp new file mode 100644 index 000000000..32f17b9b2 --- /dev/null +++ b/src/storage/tablet/ob_tablet_mds_data.cpp @@ -0,0 +1,1362 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_mds_data.h" +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/utility/ob_macro_utils.h" +#include "storage/blocksstable/ob_storage_cache_suite.h" +#include "storage/compaction/ob_medium_compaction_mgr.h" +#include "storage/tablet/ob_tablet_full_memory_mds_data.h" +#include "storage/tablet/ob_tablet_obj_load_helper.h" +#include "ob_i_tablet_mds_interface.h" + +#define USING_LOG_PREFIX MDS + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +ObTabletMdsDumpStruct::ObTabletMdsDumpStruct() + : uncommitted_kv_(), + committed_kv_() +{ +} + +ObTabletMdsDumpStruct::~ObTabletMdsDumpStruct() +{ + reset(); +} + +int ObTabletMdsDumpStruct::init(common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, uncommitted_kv_.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, committed_kv_.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } + + return ret; +} + +void ObTabletMdsDumpStruct::reset() +{ + uncommitted_kv_.reset(); + committed_kv_.reset(); +} + +int ObTabletMdsDumpStruct::assign( + const ObTabletMdsDumpStruct &other, + common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + + if (this != &other) { + reset(); + + if (OB_FAIL(init(allocator))) { + LOG_WARN("failed to init", K(ret)); + } else if (OB_FAIL(uncommitted_kv_.ptr_->assign(*other.uncommitted_kv_.ptr_, allocator))) { + LOG_WARN("failed to assign mds dump kv", K(ret)); + } else if (OB_FAIL(committed_kv_.ptr_->assign(*other.committed_kv_.ptr_, allocator))) { + LOG_WARN("failed to assign mds dump kv", K(ret)); + } + } + + return ret; +} + +OB_SERIALIZE_MEMBER(ObTabletMdsDumpStruct, + uncommitted_kv_, + committed_kv_) + + +ObTabletMdsData::ObTabletMdsData() + : is_inited_(false), + tablet_status_(), + aux_tablet_info_(), + extra_medium_info_(), + medium_info_list_(), + auto_inc_seq_(), + tablet_status_cache_(), + aux_tablet_info_cache_() +{ +} + +ObTabletMdsData::~ObTabletMdsData() +{ + reset(); +} + +void ObTabletMdsData::reset() +{ + auto_inc_seq_.reset(); + medium_info_list_.reset(); + extra_medium_info_.reset(); + aux_tablet_info_.reset(); + tablet_status_.reset(); + tablet_status_cache_.reset(); + aux_tablet_info_cache_.reset(); + is_inited_ = false; +} + +bool ObTabletMdsData::is_valid() const +{ + // TODO(@bowen.gbw): add more check rules + return is_inited_; +} + +int ObTabletMdsData::init(common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_FAIL(tablet_status_.init(allocator))) { + LOG_WARN("failed to init tablet status", K(ret)); + } else if (OB_FAIL(aux_tablet_info_.init(allocator))) { + LOG_WARN("failed to init aux tablet info", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, medium_info_list_.ptr_))) { + LOG_WARN("failed to alloc and new medium info list", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, auto_inc_seq_.ptr_))) { + LOG_WARN("failed to alloc and new auto inc seq", K(ret)); + } else if (OB_FAIL(medium_info_list_.ptr_->init(allocator))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else { + set_mem_addr(); + is_inited_ = true; + } + + return ret; +} + +int ObTabletMdsData::init( + common::ObIAllocator &allocator, + const ObTabletMdsData &mds_table_data, + const ObTabletMdsData &base_data, + const int64_t finish_medium_scn) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_FAIL(tablet_status_.init(allocator))) { + LOG_WARN("failed to init tablet status", K(ret)); + } else if (OB_FAIL(aux_tablet_info_.init(allocator))) { + LOG_WARN("failed to init aux tablet info", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, medium_info_list_.ptr_))) { + LOG_WARN("failed to alloc and new medium info list", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, auto_inc_seq_.ptr_))) { + LOG_WARN("failed to alloc and new auto inc seq", K(ret)); + } else if (OB_FAIL(medium_info_list_.ptr_->init(allocator))) { + LOG_WARN("failed to init medium info list", K(ret)); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(fuse_mds_dump_node(allocator, mds_table_data.tablet_status_, base_data.tablet_status_, tablet_status_))) { + LOG_WARN("failed to fuse", K(ret)); + } else if (OB_FAIL(fuse_mds_dump_node(allocator, mds_table_data.aux_tablet_info_, base_data.aux_tablet_info_, aux_tablet_info_))) { + LOG_WARN("failed to fuse", K(ret)); + } else if (OB_FAIL(fuse_mds_dump_node(allocator, finish_medium_scn, mds_table_data.medium_info_list_, base_data.medium_info_list_, medium_info_list_))) { + LOG_WARN("failed to fuse", K(ret)); + } else if (OB_FAIL(fuse_mds_dump_node(allocator, mds_table_data.auto_inc_seq_, base_data.auto_inc_seq_, auto_inc_seq_))) { + LOG_WARN("failed to fuse", K(ret)); + } else { + // always use base data to set extra medium info + extra_medium_info_.last_compaction_type_ = base_data.extra_medium_info_.last_compaction_type_; + extra_medium_info_.last_medium_scn_ = base_data.extra_medium_info_.last_medium_scn_; + extra_medium_info_.wait_check_flag_ = base_data.extra_medium_info_.wait_check_flag_; + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(update_user_data_from_complex_addr(tablet_status_.committed_kv_, tablet_status_cache_))) { + LOG_WARN("failed to update user data cache", K(ret), "complex_addr", tablet_status_.committed_kv_); + } else if (OB_FAIL(update_user_data_from_complex_addr(aux_tablet_info_.committed_kv_, aux_tablet_info_cache_))) { + LOG_WARN("failed to update user data cache", K(ret), "complex_addr", aux_tablet_info_.committed_kv_); + } + + if (OB_SUCC(ret)) { + set_mem_addr(); + + is_inited_ = true; + } + + return ret; +} + +int ObTabletMdsData::init( + common::ObIAllocator &allocator, + const ObTabletMdsData &other, + const int64_t finish_medium_scn, + const ObMergeType merge_type) +{ + int ret = OB_SUCCESS; + ObArenaAllocator arena_allocator("mds_data"); + const mds::MdsDumpKV *tablet_status_uncommitted_kv = nullptr; + const mds::MdsDumpKV *tablet_status_committed_kv = nullptr; + const mds::MdsDumpKV *aux_tablet_info_uncommitted_kv = nullptr; + const mds::MdsDumpKV *aux_tablet_info_committed_kv = nullptr; + const ObTabletDumpedMediumInfo *medium_info_list = nullptr; + const share::ObTabletAutoincSeq *auto_inc_seq = nullptr; + ObTabletMemberWrapper auto_inc_seq_wrapper; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } + + // load or fetch + if (OB_FAIL(ret)) { + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.tablet_status_.uncommitted_kv_, tablet_status_uncommitted_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.tablet_status_.committed_kv_, tablet_status_committed_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.aux_tablet_info_.uncommitted_kv_, aux_tablet_info_uncommitted_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.aux_tablet_info_.committed_kv_, aux_tablet_info_committed_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_medium_info_list(arena_allocator, other.medium_info_list_, medium_info_list))) { + LOG_WARN("failed to load medium info list", K(ret)); + } else if (OB_FAIL(fetch_auto_inc_seq(other.auto_inc_seq_, auto_inc_seq_wrapper))) { + LOG_WARN("failed to fetch auto inc seq", K(ret)); + } else if (OB_FAIL(auto_inc_seq_wrapper.get_member(auto_inc_seq))) { + LOG_WARN("ObTabletMemberWrapper get member failed", K(ret)); + } + + // do initialization + if (OB_FAIL(ret)) { + } else if (OB_FAIL(do_init(allocator, + tablet_status_uncommitted_kv, tablet_status_committed_kv, + aux_tablet_info_uncommitted_kv, aux_tablet_info_committed_kv, + auto_inc_seq))) { + LOG_WARN("failed to do init", K(ret)); + } else if (OB_FAIL(init_medium_info_list(allocator, medium_info_list, other.extra_medium_info_, + finish_medium_scn, merge_type))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else { + set_mem_addr(); + is_inited_ = true; + } + + ObTabletMdsData::free_mds_dump_kv(arena_allocator, tablet_status_uncommitted_kv); + ObTabletMdsData::free_mds_dump_kv(arena_allocator, tablet_status_committed_kv); + ObTabletMdsData::free_mds_dump_kv(arena_allocator, aux_tablet_info_uncommitted_kv); + ObTabletMdsData::free_mds_dump_kv(arena_allocator, aux_tablet_info_committed_kv); + ObTabletMdsData::free_medium_info_list(arena_allocator, medium_info_list); + + return ret; +} + +int ObTabletMdsData::init( + common::ObIAllocator &allocator, + const ObTabletFullMemoryMdsData &full_memory_mds_data) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(alloc_and_new(allocator))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(tablet_status_.uncommitted_kv_.ptr_->assign(full_memory_mds_data.tablet_status_uncommitted_kv_, allocator))) { + LOG_WARN("failed to assign", K(ret)); + } else if (OB_FAIL(tablet_status_.committed_kv_.ptr_->assign(full_memory_mds_data.tablet_status_committed_kv_, allocator))) { + LOG_WARN("failed to assign", K(ret)); + } else if (OB_FAIL(aux_tablet_info_.uncommitted_kv_.ptr_->assign(full_memory_mds_data.aux_tablet_info_uncommitted_kv_, allocator))) { + LOG_WARN("failed to assign", K(ret)); + } else if (OB_FAIL(aux_tablet_info_.committed_kv_.ptr_->assign(full_memory_mds_data.aux_tablet_info_committed_kv_, allocator))) { + LOG_WARN("failed to assign", K(ret)); + } else if (OB_FAIL(auto_inc_seq_.ptr_->assign(allocator, full_memory_mds_data.auto_inc_seq_))) { + LOG_WARN("failed to assign auto inc seq", K(ret), "auto_inc_seq", full_memory_mds_data.auto_inc_seq_); + } else if (OB_FAIL(init_medium_info_list(allocator, &full_memory_mds_data.medium_info_list_.medium_info_list_, full_memory_mds_data.medium_info_list_.extra_medium_info_))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else if (OB_FAIL(update_user_data_from_complex_addr(tablet_status_.committed_kv_, tablet_status_cache_))) { + LOG_WARN("failed to update user data cache", K(ret), "complex_addr", tablet_status_.committed_kv_); + } else if (OB_FAIL(update_user_data_from_complex_addr(aux_tablet_info_.committed_kv_, aux_tablet_info_cache_))) { + LOG_WARN("failed to update user data cache", K(ret), "complex_addr", aux_tablet_info_.committed_kv_); + } else { + set_mem_addr(); + is_inited_ = true; + } + + return ret; +} + +int ObTabletMdsData::init( + common::ObIAllocator &allocator, + const ObTabletMdsData &other, + const ObTabletFullMediumInfo &full_memory_medium_info_list, + const int64_t finish_medium_scn) +{ + int ret = OB_SUCCESS; + ObArenaAllocator arena_allocator("mds_data"); + const mds::MdsDumpKV *tablet_status_uncommitted_kv = nullptr; + const mds::MdsDumpKV *tablet_status_committed_kv = nullptr; + const mds::MdsDumpKV *aux_tablet_info_uncommitted_kv = nullptr; + const mds::MdsDumpKV *aux_tablet_info_committed_kv = nullptr; + const ObTabletDumpedMediumInfo *medium_info_list = nullptr; + const share::ObTabletAutoincSeq *auto_inc_seq = nullptr; + ObTabletMemberWrapper auto_inc_seq_wrapper; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } + + // load or fetch + if (OB_FAIL(ret)) { + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.tablet_status_.uncommitted_kv_, tablet_status_uncommitted_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.tablet_status_.committed_kv_, tablet_status_committed_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.aux_tablet_info_.uncommitted_kv_, aux_tablet_info_uncommitted_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.aux_tablet_info_.committed_kv_, aux_tablet_info_committed_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_medium_info_list(arena_allocator, other.medium_info_list_, medium_info_list))) { + LOG_WARN("failed to load medium info list", K(ret)); + } else if (OB_FAIL(fetch_auto_inc_seq(other.auto_inc_seq_, auto_inc_seq_wrapper))) { + LOG_WARN("failed to fetch auto inc seq", K(ret)); + } else if (OB_FAIL(auto_inc_seq_wrapper.get_member(auto_inc_seq))) { + LOG_WARN("ObTabletMemberWrapper get member failed", K(ret)); + } + + // do initialization + if (OB_FAIL(ret)) { + } else if (OB_FAIL(do_init(allocator, + tablet_status_uncommitted_kv, tablet_status_committed_kv, + aux_tablet_info_uncommitted_kv, aux_tablet_info_committed_kv, + auto_inc_seq))) { + LOG_WARN("failed to do init", K(ret)); + } else if (OB_FAIL(init_medium_info_list(allocator, medium_info_list, full_memory_medium_info_list, other.extra_medium_info_, finish_medium_scn))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else { + set_mem_addr(); + is_inited_ = true; + } + + ObTabletMdsData::free_mds_dump_kv(arena_allocator, tablet_status_uncommitted_kv); + ObTabletMdsData::free_mds_dump_kv(arena_allocator, tablet_status_committed_kv); + ObTabletMdsData::free_mds_dump_kv(arena_allocator, aux_tablet_info_uncommitted_kv); + ObTabletMdsData::free_mds_dump_kv(arena_allocator, aux_tablet_info_committed_kv); + ObTabletMdsData::free_medium_info_list(arena_allocator, medium_info_list); + + return ret; +} + +int ObTabletMdsData::init_with_update_medium_info( + common::ObIAllocator &allocator, + const ObTabletMdsData &other) +{ + int ret = OB_SUCCESS; + ObArenaAllocator arena_allocator("mds_data"); + const mds::MdsDumpKV *tablet_status_uncommitted_kv = nullptr; + const mds::MdsDumpKV *tablet_status_committed_kv = nullptr; + const mds::MdsDumpKV *aux_tablet_info_uncommitted_kv = nullptr; + const mds::MdsDumpKV *aux_tablet_info_committed_kv = nullptr; + const ObTabletDumpedMediumInfo *medium_info_list = nullptr; + const share::ObTabletAutoincSeq *auto_inc_seq = nullptr; + ObTabletMemberWrapper auto_inc_seq_wrapper; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } + + // load or fetch + if (OB_FAIL(ret)) { + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.tablet_status_.uncommitted_kv_, tablet_status_uncommitted_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.tablet_status_.committed_kv_, tablet_status_committed_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.aux_tablet_info_.uncommitted_kv_, aux_tablet_info_uncommitted_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_mds_dump_kv(arena_allocator, other.aux_tablet_info_.committed_kv_, aux_tablet_info_committed_kv))) { + LOG_WARN("failed to load mds dump kv", K(ret)); + } else if (OB_FAIL(load_medium_info_list(arena_allocator, other.medium_info_list_, medium_info_list))) { + LOG_WARN("failed to load medium info list", K(ret)); + } else if (OB_FAIL(fetch_auto_inc_seq(other.auto_inc_seq_, auto_inc_seq_wrapper))) { + LOG_WARN("failed to fetch auto inc seq", K(ret)); + } else if (OB_FAIL(auto_inc_seq_wrapper.get_member(auto_inc_seq))) { + LOG_WARN("ObTabletMemberWrapper get member failed", K(ret)); + } + + // do initialization + if (OB_FAIL(ret)) { + } else if (OB_FAIL(do_init(allocator, + tablet_status_uncommitted_kv, tablet_status_committed_kv, + aux_tablet_info_uncommitted_kv, aux_tablet_info_committed_kv, + auto_inc_seq))) { + LOG_WARN("failed to do init", K(ret)); + } else if (OB_FAIL(init_with_update_medium_info(allocator, medium_info_list, other.extra_medium_info_))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else { + set_mem_addr(); + is_inited_ = true; + } + + ObTabletMdsData::free_mds_dump_kv(arena_allocator, tablet_status_uncommitted_kv); + ObTabletMdsData::free_mds_dump_kv(arena_allocator, tablet_status_committed_kv); + ObTabletMdsData::free_mds_dump_kv(arena_allocator, aux_tablet_info_uncommitted_kv); + ObTabletMdsData::free_mds_dump_kv(arena_allocator, aux_tablet_info_committed_kv); + ObTabletMdsData::free_medium_info_list(arena_allocator, medium_info_list); + + return ret; +} + +int ObTabletMdsData::init( + ObArenaAllocator &allocator, + const ObTabletCreateDeleteMdsUserData &tablet_status) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_FAIL(tablet_status_cache_.assign(tablet_status))) { + LOG_WARN("failed to copy", K(ret), K(tablet_status)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, auto_inc_seq_.ptr_))) { + LOG_WARN("fail to allocate and new rowkey read info", K(ret)); + } else { + tablet_status_.uncommitted_kv_.addr_.set_none_addr(); + tablet_status_.committed_kv_.addr_.set_none_addr(); + aux_tablet_info_.uncommitted_kv_.addr_.set_none_addr(); + aux_tablet_info_.committed_kv_.addr_.set_none_addr(); + extra_medium_info_.reset(); + medium_info_list_.addr_.set_none_addr(); + auto_inc_seq_.addr_.set_none_addr(); + + is_inited_ = true; + } + + return ret; +} + +int ObTabletMdsData::alloc_and_new(common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, tablet_status_.uncommitted_kv_.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, tablet_status_.committed_kv_.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, aux_tablet_info_.uncommitted_kv_.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, aux_tablet_info_.committed_kv_.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, medium_info_list_.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, auto_inc_seq_.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } + + return ret; +} + +void ObTabletMdsData::set_mem_addr() +{ + auto_inc_seq_.addr_.set_mem_addr(0, sizeof(share::ObTabletAutoincSeq)); + medium_info_list_.addr_.set_mem_addr(0, sizeof(ObTabletDumpedMediumInfo)); + aux_tablet_info_.committed_kv_.addr_.set_mem_addr(0, sizeof(mds::MdsDumpKV)); + aux_tablet_info_.uncommitted_kv_.addr_.set_mem_addr(0, sizeof(mds::MdsDumpKV)); + tablet_status_.committed_kv_.addr_.set_mem_addr(0, sizeof(mds::MdsDumpKV)); + tablet_status_.uncommitted_kv_.addr_.set_mem_addr(0, sizeof(mds::MdsDumpKV)); +} + +int ObTabletMdsData::do_init( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *tablet_status_uncommitted_kv, + const mds::MdsDumpKV *tablet_status_committed_kv, + const mds::MdsDumpKV *aux_tablet_info_uncommitted_kv, + const mds::MdsDumpKV *aux_tablet_info_committed_kv, + const share::ObTabletAutoincSeq *auto_inc_seq) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(tablet_status_uncommitted_kv) + || OB_ISNULL(tablet_status_committed_kv) + || OB_ISNULL(aux_tablet_info_uncommitted_kv) + || OB_ISNULL(aux_tablet_info_committed_kv) + || OB_ISNULL(auto_inc_seq)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), + KP(tablet_status_uncommitted_kv), KP(tablet_status_committed_kv), + KP(aux_tablet_info_uncommitted_kv), KP(aux_tablet_info_committed_kv), + KP(auto_inc_seq)); + } else if (OB_FAIL(alloc_and_new(allocator))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(tablet_status_.uncommitted_kv_.ptr_->assign(*tablet_status_uncommitted_kv, allocator))) { + LOG_WARN("failed to assign tablet status uncommitted kv", K(ret)); + } else if (OB_FAIL(tablet_status_.committed_kv_.ptr_->assign(*tablet_status_committed_kv, allocator))) { + LOG_WARN("failed to assign tablet status committed kv", K(ret)); + } else if (OB_FAIL(aux_tablet_info_.uncommitted_kv_.ptr_->assign(*aux_tablet_info_uncommitted_kv, allocator))) { + LOG_WARN("failed to assign aux tablet info uncommitted kv", K(ret)); + } else if (OB_FAIL(aux_tablet_info_.committed_kv_.ptr_->assign(*aux_tablet_info_committed_kv, allocator))) { + LOG_WARN("failed to assign aux tablet info committed kv", K(ret)); + } else if (OB_FAIL(auto_inc_seq_.ptr_->assign(allocator, *auto_inc_seq))) { + LOG_WARN("failed to assign auto inc seq kv", K(ret)); + } else if (OB_FAIL(update_user_data_from_complex_addr(tablet_status_.committed_kv_, tablet_status_cache_))) { + LOG_WARN("failed to update user data", K(ret), "complex_addr", tablet_status_.committed_kv_); + } else if (OB_FAIL(update_user_data_from_complex_addr(aux_tablet_info_.committed_kv_, aux_tablet_info_cache_))) { + LOG_WARN("failed to update user data", K(ret), "complex_addr", aux_tablet_info_.committed_kv_); + } + + if (OB_FAIL(ret)) { + reset(); + } + + return ret; +} + +int ObTabletMdsData::init_medium_info_list( + common::ObIAllocator &allocator, + const ObTabletDumpedMediumInfo *old_medium_info_list, + const ObTaletExtraMediumInfo &old_extra_medium_info, + const int64_t finish_medium_scn, + const ObMergeType merge_type) +{ + int ret = OB_SUCCESS; + ObTabletDumpedMediumInfo *cur_medium_info_list = medium_info_list_.ptr_; + + if (OB_ISNULL(cur_medium_info_list)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("medium info list is null", K(ret), KP(cur_medium_info_list)); + } else if (OB_FAIL(cur_medium_info_list->init(allocator))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else if (nullptr == old_medium_info_list) { + // no need to copy, do nothing + extra_medium_info_.reset(); + } else if (OB_FAIL(copy_medium_info_list(finish_medium_scn, *old_medium_info_list, *cur_medium_info_list))) { + LOG_WARN("failed to copy medium info list", K(ret), K(finish_medium_scn), KPC(old_medium_info_list)); + } else if (is_major_merge_type(merge_type)) { + extra_medium_info_.last_compaction_type_ = is_major_merge(merge_type) ? compaction::ObMediumCompactionInfo::MAJOR_COMPACTION : compaction::ObMediumCompactionInfo::MEDIUM_COMPACTION; + extra_medium_info_.last_medium_scn_ = finish_medium_scn; + extra_medium_info_.wait_check_flag_ = true; + } else { + extra_medium_info_.last_compaction_type_ = old_extra_medium_info.last_compaction_type_; + extra_medium_info_.last_medium_scn_ = old_extra_medium_info.last_medium_scn_; + extra_medium_info_.wait_check_flag_ = old_extra_medium_info.wait_check_flag_; + } + + if (OB_SUCC(ret)) { + LOG_INFO("succeeded to init medium info list", K(ret), KPC(old_medium_info_list), K(finish_medium_scn), K(merge_type), + KPC(cur_medium_info_list), K_(extra_medium_info)); + } + + return ret; +} + +int ObTabletMdsData::init_medium_info_list( + common::ObIAllocator &allocator, + const ObTabletDumpedMediumInfo *old_medium_info_list, + const ObTabletFullMediumInfo &full_memory_medium_info_list, + const ObTaletExtraMediumInfo &old_extra_medium_info, + const int64_t finish_medium_scn) +{ + int ret = OB_SUCCESS; + ObTabletDumpedMediumInfo *cur_medium_info_list = medium_info_list_.ptr_; + + if (OB_ISNULL(cur_medium_info_list)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("medium info list is null", K(ret), KP(cur_medium_info_list)); + } else if (OB_FAIL(cur_medium_info_list->init(allocator))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else if (nullptr != old_medium_info_list && OB_FAIL(copy_medium_info_list(finish_medium_scn, *old_medium_info_list, *cur_medium_info_list))) { + LOG_WARN("failed to copy medium info", K(ret)); + } else if (OB_FAIL(copy_medium_info_list(finish_medium_scn, full_memory_medium_info_list.medium_info_list_, *cur_medium_info_list))) { + LOG_WARN("failed to copy medium info", K(ret)); + } else { + /* + * finish_medium_scn = last_major->get_snapshot_version() + * if finish_medium_scn < old_extra_medium_info.last_medium_scn_, means local extra_medium_info is invalid, + * use input medium list to replace + */ + if (nullptr == old_medium_info_list + || finish_medium_scn < old_extra_medium_info.last_medium_scn_ + || old_extra_medium_info.last_medium_scn_ < full_memory_medium_info_list.extra_medium_info_.last_medium_scn_) { + extra_medium_info_.last_compaction_type_ = full_memory_medium_info_list.extra_medium_info_.last_compaction_type_; + extra_medium_info_.last_medium_scn_ = full_memory_medium_info_list.extra_medium_info_.last_medium_scn_; + extra_medium_info_.wait_check_flag_ = true; + } else { + extra_medium_info_.last_compaction_type_ = old_extra_medium_info.last_compaction_type_; + extra_medium_info_.last_medium_scn_ = old_extra_medium_info.last_medium_scn_; + extra_medium_info_.wait_check_flag_ = old_extra_medium_info.wait_check_flag_; + } + } + + if (OB_SUCC(ret)) { + LOG_INFO("succeeded to init medium info list", K(ret), KPC(old_medium_info_list), K(old_extra_medium_info), K(full_memory_medium_info_list), + K(finish_medium_scn), K(old_extra_medium_info), + KPC(cur_medium_info_list), K_(extra_medium_info)); + } + + return ret; +} + +int ObTabletMdsData::init_with_update_medium_info( + common::ObIAllocator &allocator, + const ObTabletDumpedMediumInfo *old_medium_info_list, + const ObTaletExtraMediumInfo &old_extra_medium_info) +{ + int ret = OB_SUCCESS; + const int64_t finish_medium_scn = old_extra_medium_info.last_medium_scn_; + ObTabletDumpedMediumInfo *cur_medium_info_list = medium_info_list_.ptr_; + + if (OB_ISNULL(cur_medium_info_list)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("medium info list is null", K(ret), KP(cur_medium_info_list)); + } else if (OB_FAIL(cur_medium_info_list->init(allocator))) { + LOG_WARN("failed to init medium info list", K(ret)); + } else if (OB_FAIL(copy_medium_info_list(finish_medium_scn, *old_medium_info_list, *cur_medium_info_list))) { + LOG_WARN("failed to copy medium info", K(ret)); + } else { + extra_medium_info_.last_compaction_type_ = old_extra_medium_info.last_compaction_type_; + extra_medium_info_.last_medium_scn_ = old_extra_medium_info.last_medium_scn_; + extra_medium_info_.wait_check_flag_ = false; + } + + if (OB_SUCC(ret)) { + LOG_INFO("succeeded to init medium info list", K(ret), KPC(old_medium_info_list), K(old_extra_medium_info), + KPC(cur_medium_info_list), K_(extra_medium_info)); + } + + return ret; +} + +int ObTabletMdsData::copy_medium_info_list( + const int64_t finish_medium_scn, + const ObTabletDumpedMediumInfo &input_medium_info_list, + ObTabletDumpedMediumInfo &medium_info_list) +{ + int ret = OB_SUCCESS; + const common::ObIArray &array = input_medium_info_list.medium_info_list_; + + for (int64_t i = 0; OB_SUCC(ret) && i < array.count(); ++i) { + const compaction::ObMediumCompactionInfo *input_medium_info = array.at(i); + if (OB_ISNULL(input_medium_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, medium info is null", K(ret), K(i), KP(input_medium_info)); + } else if (input_medium_info->medium_snapshot_ > finish_medium_scn) { + if (input_medium_info->medium_snapshot_ <= medium_info_list.get_max_medium_snapshot()) { + // do nothing + } else if (OB_FAIL(medium_info_list.append(*input_medium_info))) { + LOG_WARN("failed to append medium info", K(ret), KPC(input_medium_info)); + } + } + } + + return ret; +} + +int ObTabletMdsData::fuse_mds_dump_node( + common::ObIAllocator &allocator, + const ObTabletComplexAddr &mds_table_data, + const ObTabletComplexAddr &base_data, + ObTabletComplexAddr &fused_data) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!fused_data.is_memory_object())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fused data must be memory object", K(ret), K(fused_data)); + } else if (OB_UNLIKELY(!mds_table_data.is_memory_object())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("mds table data is not in memory", K(ret), K(mds_table_data)); + } else if (OB_UNLIKELY(!base_data.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("base data is invalid", K(ret), K(base_data)); + } else { + const mds::MdsDumpKV *mds_dump_kv = mds_table_data.ptr_; + const common::ObString &mds_user_data = mds_dump_kv->v_.user_data_; + + if (mds_user_data.empty()) { + // mds data in mds table is empty, use that in base data + ObArenaAllocator arena_allocator("mds_reader"); + char *buf = nullptr; + int64_t len = 0; + int64_t pos = 0; + if (base_data.is_memory_object()) { + if (OB_FAIL(fused_data.ptr_->assign(*base_data.ptr_, allocator))) { + LOG_WARN("failed to copy", K(ret), K(base_data)); + } + } else if (OB_FAIL(ObTabletObjLoadHelper::read_from_addr(arena_allocator, base_data.addr_, buf, len))) { + LOG_WARN("failed to read mds data from block addr", K(ret)); + } else if (OB_FAIL(fused_data.ptr_->deserialize(allocator, buf, len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } + } else { + // mds data in mds table is valid, just copy it + if (OB_FAIL(fused_data.ptr_->assign(*mds_dump_kv, allocator))) { + LOG_WARN("failed to copy", K(ret), KPC(mds_dump_kv)); + } + } + } + + return ret; +} + +int ObTabletMdsData::fuse_mds_dump_node( + common::ObIAllocator &allocator, + const ObTabletMdsDumpStruct &mds_table_data, + const ObTabletMdsDumpStruct &base_data, + ObTabletMdsDumpStruct &fused_data) +{ + int ret = OB_SUCCESS; + const ObTabletComplexAddr &mds_uncommitted_kv = mds_table_data.uncommitted_kv_; + const ObTabletComplexAddr &mds_committed_kv = mds_table_data.committed_kv_; + const ObTabletComplexAddr &base_uncommitted_kv = base_data.uncommitted_kv_; + const ObTabletComplexAddr &base_committed_kv = base_data.committed_kv_; + + if (OB_FAIL(fuse_mds_dump_node(allocator, mds_uncommitted_kv, base_uncommitted_kv, fused_data.uncommitted_kv_))) { + LOG_WARN("failed to fuse complex addr", K(ret)); + } else if (OB_FAIL(fuse_mds_dump_node(allocator, mds_committed_kv, base_committed_kv, fused_data.committed_kv_))) { + LOG_WARN("failed to fuse complex addr", K(ret)); + } + + return ret; +} + +int ObTabletMdsData::fuse_mds_dump_node( + common::ObIAllocator &allocator, + const ObTabletComplexAddr &mds_table_data, + const ObTabletComplexAddr &base_data, + ObTabletComplexAddr &fused_data) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!fused_data.is_memory_object())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fused data must be memory object", K(ret), K(fused_data)); + } else if (OB_UNLIKELY(!mds_table_data.is_memory_object())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("mds table data is not in memory", K(ret), K(mds_table_data)); + } else if (OB_UNLIKELY(!base_data.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("base data is invalid", K(ret), K(base_data)); + } else { + const share::ObTabletAutoincSeq *mds_table_auto_inc_seq = mds_table_data.ptr_; + + if (mds_table_auto_inc_seq->is_valid()) { + if (OB_FAIL(fused_data.ptr_->assign(allocator, *mds_table_auto_inc_seq))) { + LOG_WARN("failed to assign", K(ret), KPC(mds_table_auto_inc_seq)); + } + } else { + // auto inc seq in mds table is not valid, use that in base data + ObTabletMemberWrapper auto_inc_seq_wrapper; + const share::ObTabletAutoincSeq *auto_inc_seq = nullptr; + if (OB_FAIL(fetch_auto_inc_seq(base_data, auto_inc_seq_wrapper))) { + LOG_WARN("failed to fetch auto inc seq", K(ret), K(base_data)); + } else if (OB_FAIL(auto_inc_seq_wrapper.get_member(auto_inc_seq))) { + LOG_WARN("failed to get member", K(ret)); + } else if (OB_FAIL(fused_data.ptr_->assign(allocator, *auto_inc_seq))) { + LOG_WARN("failed to assign", K(ret), KPC(auto_inc_seq)); + } + } + } + + return ret; +} + +int ObTabletMdsData::fuse_mds_dump_node( + common::ObIAllocator &allocator, + const int64_t finish_medium_scn, + const ObTabletComplexAddr &mds_table_data, + const ObTabletComplexAddr &base_data, + ObTabletComplexAddr &fused_data) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!fused_data.is_memory_object())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fused data must be memory object", K(ret), K(fused_data)); + } else if (OB_UNLIKELY(!mds_table_data.is_memory_object())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("mds table data is not in memory", K(ret), K(mds_table_data)); + } else if (OB_UNLIKELY(!base_data.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("base data is invalid", K(ret), K(base_data)); + } else { + const ObTabletDumpedMediumInfo *mds_table_medium_info_list = mds_table_data.ptr_; + const ObTabletDumpedMediumInfo *base_medium_info_list = base_data.ptr_; + ObTabletDumpedMediumInfo *fused_medium_info_list = fused_data.ptr_; + + if (OB_FAIL(load_medium_info_list(allocator, base_data, base_medium_info_list))) { + LOG_WARN("failed to laod medium info list", K(ret), K(base_data)); + } else if (OB_ISNULL(base_medium_info_list)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, base medium info list is null", K(ret), KP(base_medium_info_list)); + } else if (OB_FAIL(copy_medium_info_list(finish_medium_scn, *base_medium_info_list, *fused_medium_info_list))) { + LOG_WARN("failed to copy base medium info list", K(ret)); + } else if (OB_FAIL(copy_medium_info_list(finish_medium_scn, *mds_table_medium_info_list, *fused_medium_info_list))) { + LOG_WARN("failed to copy mds table medium info list", K(ret)); + } + + ObTabletMdsData::free_medium_info_list(allocator, base_medium_info_list); + } + + return ret; +} + +int ObTabletMdsData::load_mds_dump_kv( + common::ObIAllocator &allocator, + const ObTabletComplexAddr &complex_addr, + const mds::MdsDumpKV *&kv) +{ + int ret = OB_SUCCESS; + mds::MdsDumpKV *ptr = nullptr; + + if (OB_UNLIKELY(!complex_addr.is_valid() || complex_addr.is_none_object())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid addr", K(ret), K(complex_addr)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, ptr))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (complex_addr.is_memory_object()) { + if (OB_FAIL(ptr->assign(*complex_addr.ptr_, allocator))) { + LOG_WARN("failed to copy mds dump kv", K(ret)); + } + } else if (complex_addr.is_disk_object()) { + const ObMetaDiskAddr &addr = complex_addr.addr_; + ObArenaAllocator arena_allocator("dump_kv_reader"); + char *buf = nullptr; + int64_t len = 0; + int64_t pos = 0; + if (OB_FAIL(ObTabletObjLoadHelper::read_from_addr(arena_allocator, addr, buf, len))) { + LOG_WARN("failed to read from addr", K(ret), K(addr)); + } else if (OB_FAIL(ptr->deserialize(allocator, buf, len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected complex addr type", K(ret), K(complex_addr)); + } + + if (OB_FAIL(ret)) { + if (nullptr != ptr) { + allocator.free(ptr); + } + } else { + kv = ptr; + } + + return ret; +} + +int ObTabletMdsData::load_medium_info_list( + common::ObIAllocator &allocator, + const ObTabletComplexAddr &complex_addr, + const ObTabletDumpedMediumInfo *&medium_info_list) +{ + int ret = OB_SUCCESS; + ObTabletDumpedMediumInfo *ptr = nullptr; + + if (OB_UNLIKELY(!complex_addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid addr", K(ret), K(complex_addr)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, ptr))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (complex_addr.is_none_object()) { + if (OB_FAIL(ptr->init(allocator))) { + LOG_WARN("failed to init medium info list", K(ret)); + } + } else if (complex_addr.is_memory_object()) { + if (OB_FAIL(ptr->assign(*complex_addr.ptr_, allocator))) { + LOG_INFO("failed to copy medium info list", K(ret)); + } + } else if (complex_addr.is_disk_object()) { + if (OB_FAIL(read_medium_info(allocator, complex_addr.addr_, ptr->medium_info_list_))) { + LOG_WARN("failed to read medium info", K(ret), "addr", complex_addr.addr_); + } else { + std::sort(ptr->medium_info_list_.begin(), ptr->medium_info_list_.end(), ObTabletDumpedMediumInfo::compare); + + ptr->allocator_ = &allocator; + ptr->is_inited_ = true; + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected complex addr type", K(ret), K(complex_addr)); + } + + if (OB_FAIL(ret)) { + if (nullptr != ptr) { + allocator.free(ptr); + } + } else { + medium_info_list = ptr; + } + + return ret; +} + +void ObTabletMdsData::free_mds_dump_kv( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *kv) +{ + if (nullptr != kv) { + kv->mds::MdsDumpKV::~MdsDumpKV(); + allocator.free(const_cast(kv)); + } +} + +void ObTabletMdsData::free_medium_info_list( + common::ObIAllocator &allocator, + const ObTabletDumpedMediumInfo *medium_info_list) +{ + if (nullptr != medium_info_list) { + medium_info_list->~ObTabletDumpedMediumInfo(); + allocator.free(const_cast(medium_info_list)); + } +} + +int ObTabletMdsData::read_medium_info( + common::ObIAllocator &allocator, + const ObMetaDiskAddr &addr, + common::ObSEArray &array) +{ + int ret = OB_SUCCESS; + ObSharedBlockLinkIter iter; + compaction::ObMediumCompactionInfo *info = nullptr; + char *buf = nullptr; + int64_t len = 0; + + if (OB_UNLIKELY(!addr.is_block())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("addr is not block addr", K(ret), K(addr)); + } else if (OB_FAIL(iter.init(addr))) { + LOG_WARN("failed to init link iter", K(ret), K(addr)); + } else { + while (OB_SUCC(ret)) { + info = nullptr; + buf = nullptr; + len = 0; + int64_t pos = 0; + + if (OB_FAIL(iter.get_next(allocator, buf, len))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get next item", K(ret)); + } + } else if (OB_ISNULL(buf) || OB_UNLIKELY(0 == len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, buf is null or len is 0", K(ret), KP(buf), K(len)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, info))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(info->deserialize(allocator, buf, len, pos))) { + LOG_WARN("failed to deserialize medium info", K(ret)); + } else if (OB_FAIL(array.push_back(info))) { + LOG_WARN("failed to push back to array", K(ret), KPC(info)); + } + + if (OB_FAIL(ret)) { + if (nullptr != info) { + allocator.free(info); + } + } + } + } + + return ret; +} + +int ObTabletMdsData::fetch_auto_inc_seq( + const ObTabletComplexAddr &auto_inc_seq_addr, + ObTabletMemberWrapper &wrapper) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!auto_inc_seq_addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid auto inc seq addr", K(ret)); + } else if (auto_inc_seq_addr.is_memory_object()) { + wrapper.set_member(auto_inc_seq_addr.get_ptr()); + } else { + ObStorageMetaHandle handle; + ObStorageMetaKey meta_key(MTL_ID(), auto_inc_seq_addr.addr_); + const ObTablet *tablet = nullptr; // no use here + if (OB_FAIL(OB_STORE_CACHE.get_storage_meta_cache().get_meta(ObStorageMetaValue::MetaType::AUTO_INC_SEQ, + meta_key, handle, tablet))) { + LOG_WARN("get meta failed", K(ret), K(meta_key)); + } else if (OB_FAIL(wrapper.set_cache_handle(handle))) { + LOG_WARN("wrapper set cache handle failed", K(ret), K(meta_key), K(auto_inc_seq_addr)); + } + } + + return ret; +} + +int ObTabletMdsData::build_mds_data( + common::ObArenaAllocator &allocator, + const share::ObTabletAutoincSeq &auto_inc_seq, + const ObTabletTxMultiSourceDataUnit &tx_data, + const share::SCN &create_commit_scn, + const ObTabletBindingInfo &ddl_data, + const share::SCN &clog_checkpoint_scn, + const compaction::ObMediumCompactionInfoList &info_list, + ObTabletMdsData &mds_data) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(build_tablet_status(allocator, tx_data, create_commit_scn, mds_data))) { + LOG_WARN("failed to build tablet status", K(ret)); + } else if (OB_FAIL(build_aux_tablet_info(allocator, tx_data, ddl_data, clog_checkpoint_scn, mds_data))) { + LOG_WARN("failed to build binding info", K(ret)); + } else if (OB_FAIL(build_auto_inc_seq(allocator, auto_inc_seq, mds_data))) { + LOG_WARN("failed to build auto inc seq", K(ret)); + } else { + mds_data.extra_medium_info_.info_ = info_list.get_union_info(); + mds_data.extra_medium_info_.last_medium_scn_ = info_list.get_last_compaction_scn(); + const compaction::ObMediumCompactionInfoList::MediumInfoList &medium_info_list = info_list.get_list(); + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, mds_data.medium_info_list_.ptr_))) { + LOG_WARN("failed to alloc and new mda data medium info list", K(ret)); + } else if (OB_FAIL(mds_data.medium_info_list_.ptr_->init(allocator))) { + LOG_WARN("failed to init mda data medium info list", K(ret)); + } + + DLIST_FOREACH(info, medium_info_list) { + if (OB_FAIL(mds_data.medium_info_list_.ptr_->append(*info))) { + LOG_WARN("failed to assign medium info", K(ret), K(*info)); + } + } + } + + return ret; +} + +int ObTabletMdsData::build_tablet_status( + common::ObArenaAllocator &allocator, + const ObTabletTxMultiSourceDataUnit &tx_data, + const share::SCN &create_commit_scn, + ObTabletMdsData &mds_data) +{ + int ret = OB_SUCCESS; + ObTabletComplexAddr &uncommitted_kv = mds_data.tablet_status_.uncommitted_kv_; + ObTabletComplexAddr &committed_kv = mds_data.tablet_status_.committed_kv_; + mds::MdsDumpKey *key = nullptr; + mds::MdsDumpNode *node = nullptr; + + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, uncommitted_kv.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, committed_kv.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (tx_data.is_in_tx()) { + key = &uncommitted_kv.ptr_->k_; + node = &uncommitted_kv.ptr_->v_; + if (OB_ISNULL(node)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("node is null", K(ret), KP(node)); + } else { + key->mds_table_id_ = mds::TupleTypeIdx::value; + key->mds_unit_id_ = mds::TupleTypeIdx>::value; + key->allocator_ = &allocator; + // no need to serialize dummy key + key->key_.reset(); + + node->mds_table_id_ = mds::TupleTypeIdx::value; + node->mds_unit_id_ = mds::TupleTypeIdx::value; + + node->status_.union_.field_.node_type_ = mds::MdsNodeType::SET; + node->status_.union_.field_.writer_type_ = mds::WriterType::TRANSACTION; + node->status_.union_.field_.state_ = mds::TwoPhaseCommitState::ON_PREPARE; + + node->allocator_ = &allocator; + node->writer_id_ = tx_data.tx_id_.get_id(); + //node->seq_no_ = ; + node->redo_scn_ = tx_data.tx_scn_; + node->end_scn_ = share::SCN::invalid_scn(); + node->trans_version_ = tx_data.tx_scn_; + } + } else { + key = &committed_kv.ptr_->k_; + node = &committed_kv.ptr_->v_; + if (OB_ISNULL(node)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("node is null", K(ret), KP(node)); + } else { + key->mds_table_id_ = mds::TupleTypeIdx::value; + key->mds_unit_id_ = mds::TupleTypeIdx>::value; + key->allocator_ = &allocator; + // no need to serialize dummy key + key->key_.reset(); + + node->mds_table_id_ = mds::TupleTypeIdx::value; + node->mds_unit_id_ = mds::TupleTypeIdx::value; + + node->status_.union_.field_.node_type_ = mds::MdsNodeType::SET; + node->status_.union_.field_.writer_type_ = mds::WriterType::TRANSACTION; + if (ObTabletStatus::NORMAL == tx_data.tablet_status_) { + node->status_.union_.field_.state_ = mds::TwoPhaseCommitState::ON_COMMIT; + } else if (ObTabletStatus::DELETED == tx_data.tablet_status_) { + // state set as ON_COMMIT even if it may be create abort transaction + node->status_.union_.field_.state_ = mds::TwoPhaseCommitState::ON_COMMIT; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tablet status", K(ret), "tx_data", tx_data); + } + + node->allocator_ = &allocator; + node->writer_id_ = 0; + //node->seq_no_ = ; + node->redo_scn_ = share::SCN::invalid_scn(); + node->end_scn_ = tx_data.tx_scn_; + node->trans_version_ = tx_data.tx_scn_; + } + } + + if (OB_SUCC(ret)) { + ObTabletCreateDeleteMdsUserData user_data; + user_data.tablet_status_ = tx_data.tablet_status_; + user_data.create_commit_scn_ = create_commit_scn; + user_data.create_commit_version_ = tx_data.tx_scn_.get_val_for_tx(); + user_data.transfer_scn_ = tx_data.transfer_scn_; + user_data.transfer_ls_id_ = tx_data.transfer_ls_id_; + if (ObTabletStatus::DELETED == tx_data.tablet_status_) { + //TODO(bizhu) check deleted trans scn + user_data.delete_commit_scn_ = tx_data.tx_scn_; + //user_data.delete_commit_version_ = tx_data.tx_scn_; + } + const int64_t serialize_size = user_data.get_serialize_size(); + int64_t pos = 0; + char *buffer = nullptr; + if (OB_ISNULL(buffer = static_cast(allocator.alloc(serialize_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret), K(serialize_size)); + } else if (OB_FAIL(user_data.serialize(buffer, serialize_size, pos))) { + LOG_WARN("user data serialize failed", K(ret), K(user_data)); + } else { + node->user_data_.assign(buffer, serialize_size); + } + + if (OB_FAIL(ret) && OB_NOT_NULL(buffer)) { + allocator.free(buffer); + } + } + + return ret; +} + +int ObTabletMdsData::build_aux_tablet_info( + common::ObArenaAllocator &allocator, + const ObTabletTxMultiSourceDataUnit &tx_data, + const ObTabletBindingInfo &ddl_data, + const share::SCN &clog_checkpoint_scn, + ObTabletMdsData &mds_data) +{ + int ret = OB_SUCCESS; + ObTabletComplexAddr &uncommitted_kv = mds_data.aux_tablet_info_.uncommitted_kv_; + ObTabletComplexAddr &committed_kv = mds_data.aux_tablet_info_.committed_kv_; + mds::MdsDumpKey *key = nullptr; + mds::MdsDumpNode *node = nullptr; + + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, uncommitted_kv.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, committed_kv.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (tx_data.is_in_tx()) { + key = &uncommitted_kv.ptr_->k_; + node = &uncommitted_kv.ptr_->v_; + if (OB_ISNULL(node)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("node is null", K(ret), KP(node)); + } else { + key->mds_table_id_ = mds::TupleTypeIdx::value; + key->mds_unit_id_ = mds::TupleTypeIdx>::value; + key->allocator_ = &allocator; + // no need to serialize dummy key + key->key_.reset(); + + node->mds_table_id_ = mds::TupleTypeIdx::value; + node->mds_unit_id_ = mds::TupleTypeIdx::value; + + node->status_.union_.field_.node_type_ = mds::MdsNodeType::SET; + node->status_.union_.field_.writer_type_ = mds::WriterType::TRANSACTION; + node->status_.union_.field_.state_ = mds::TwoPhaseCommitState::ON_PREPARE; + + node->allocator_ = &allocator; + node->writer_id_ = tx_data.tx_id_.get_id(); + //node->seq_no_ = ; + + node->redo_scn_ = tx_data.tx_scn_; + node->end_scn_ = share::SCN::invalid_scn(); + node->trans_version_ = tx_data.tx_scn_; + } + } else { + key = &committed_kv.ptr_->k_; + node = &committed_kv.ptr_->v_; + if (OB_ISNULL(node)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("node is null", K(ret), KP(node)); + } else { + key->mds_table_id_ = mds::TupleTypeIdx::value; + key->mds_unit_id_ = mds::TupleTypeIdx>::value; + key->allocator_ = &allocator; + // no need to serialize dummy key + key->key_.reset(); + + node->mds_table_id_ = mds::TupleTypeIdx::value; + node->mds_unit_id_ = mds::TupleTypeIdx::value; + + node->status_.union_.field_.node_type_ = mds::MdsNodeType::SET; + node->status_.union_.field_.writer_type_ = mds::WriterType::TRANSACTION; + node->status_.union_.field_.state_ = mds::TwoPhaseCommitState::ON_COMMIT; // ON_ABORT? + + node->allocator_ = &allocator; + node->writer_id_ = 0; + //node->seq_no_ = ; + + node->redo_scn_ = clog_checkpoint_scn; + node->end_scn_ = clog_checkpoint_scn; + node->trans_version_ = clog_checkpoint_scn; + } + } + + if (OB_SUCC(ret)) { + ObTabletBindingMdsUserData user_data; + user_data.redefined_ = ddl_data.redefined_; + user_data.snapshot_version_ = ddl_data.snapshot_version_; + user_data.schema_version_ = ddl_data.schema_version_; + user_data.data_tablet_id_ = ddl_data.data_tablet_id_; + if (!ddl_data.hidden_tablet_ids_.empty()) { + user_data.hidden_tablet_id_ = ddl_data.hidden_tablet_ids_.at(0); // only have one valid hidden tablet + } + user_data.lob_meta_tablet_id_ = ddl_data.lob_meta_tablet_id_; + user_data.lob_piece_tablet_id_ = ddl_data.lob_piece_tablet_id_; + + const int64_t serialize_size = user_data.get_serialize_size(); + int64_t pos = 0; + char *buffer = nullptr; + if (OB_ISNULL(buffer = static_cast(allocator.alloc(serialize_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret), K(serialize_size)); + } else if (OB_FAIL(user_data.serialize(buffer, serialize_size, pos))) { + LOG_WARN("user data serialize failed", K(ret), K(user_data)); + } else { + node->user_data_.assign(buffer, serialize_size); + } + + if (OB_FAIL(ret) && OB_NOT_NULL(buffer)) { + allocator.free(buffer); + } + } + + return ret; +} + +int ObTabletMdsData::build_auto_inc_seq( + common::ObArenaAllocator &allocator, + const share::ObTabletAutoincSeq &auto_inc_seq, + ObTabletMdsData &mds_data) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, mds_data.auto_inc_seq_.ptr_))) { + LOG_WARN("failed to alloc and new", K(ret)); + } else if (OB_FAIL(mds_data.auto_inc_seq_.ptr_->assign(allocator, auto_inc_seq))) { + LOG_WARN("failed to copy auto inc seq", K(ret), K(auto_inc_seq)); + } + + return ret; +} + +int ObTabletMdsData::set_tablet_status( + ObArenaAllocator *allocator, + const ObTabletStatus::Status &tablet_status, + const ObTabletMdsUserDataType &data_type) +{ + int ret = OB_SUCCESS; + ObTabletCreateDeleteMdsUserData user_data; + user_data.tablet_status_ = tablet_status; + user_data.data_type_ = data_type; + + const int64_t length = user_data.get_serialize_size(); + char *buffer = static_cast(allocator->alloc(length)); + int64_t pos = 0; + if (OB_ISNULL(buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret), K(length)); + } else if (OB_FAIL(user_data.serialize(buffer, length, pos))) { + LOG_WARN("failed to serialize", K(ret)); + } else if (OB_FAIL(tablet_status_cache_.assign(user_data))) { + LOG_WARN("failed to assign tablet status cache", K(ret)); + } else { + mds::MdsDumpNode &node = tablet_status_.committed_kv_.get_ptr()->v_; + node.allocator_ = allocator; + node.user_data_.assign(buffer, length); + } + + if (OB_FAIL(ret)) { + if (nullptr != buffer) { + allocator->free(buffer); + } + } + return ret; +} + +int ObTabletMdsData::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, + tablet_status_, + aux_tablet_info_, + extra_medium_info_, + medium_info_list_, + auto_inc_seq_, + tablet_status_cache_); + + return ret; +} + +int ObTabletMdsData::deserialize(const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_FAIL(tablet_status_.deserialize(buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(aux_tablet_info_.deserialize(buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(extra_medium_info_.deserialize(buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(medium_info_list_.deserialize(buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(auto_inc_seq_.deserialize(buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else if (OB_FAIL(tablet_status_cache_.deserialize(buf, data_len, pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else { + is_inited_ = true; + LOG_INFO("succeeded to deserialize mds data", K(ret), KPC(this)); + } + + return ret; +} + +int64_t ObTabletMdsData::get_serialize_size() const +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, + tablet_status_, + aux_tablet_info_, + extra_medium_info_, + medium_info_list_, + auto_inc_seq_, + tablet_status_cache_); + + return len; +} +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_mds_data.h b/src/storage/tablet/ob_tablet_mds_data.h new file mode 100644 index 000000000..59df9a319 --- /dev/null +++ b/src/storage/tablet/ob_tablet_mds_data.h @@ -0,0 +1,258 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_MDS_DATA +#define OCEANBASE_STORAGE_OB_TABLET_MDS_DATA + +#include +#include "lib/container/ob_se_array.h" +#include "lib/string/ob_string.h" +#include "share/ob_tablet_autoincrement_param.h" +#include "storage/compaction/ob_compaction_util.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include "storage/tablet/ob_tablet_complex_addr.h" +#include "storage/tablet/ob_tablet_member_wrapper.h" +#include "storage/tablet/ob_tablet_full_medium_info.h" + +namespace oceanbase +{ +namespace common +{ +class ObIAllocator; +class ObArenaAllocator; +} +namespace compaction +{ +class ObMediumCompactionInfoKey; +class ObMediumCompactionInfo; +class ObMediumCompactionInfoList; +} + +namespace storage +{ +class ObTabletFullMemoryMdsData; + +class ObTabletMdsDumpStruct +{ + OB_UNIS_VERSION(1); +public: + ObTabletMdsDumpStruct(); + ~ObTabletMdsDumpStruct(); + ObTabletMdsDumpStruct(const ObTabletMdsDumpStruct &) = delete; + ObTabletMdsDumpStruct &operator=(const ObTabletMdsDumpStruct &) = delete; +public: + int init(common::ObIAllocator &allocator); + void reset(); + int assign(const ObTabletMdsDumpStruct &other, common::ObIAllocator &allocator); + + TO_STRING_KV(K_(uncommitted_kv), K_(committed_kv)); +public: + ObTabletComplexAddr uncommitted_kv_; + ObTabletComplexAddr committed_kv_; +}; + +class ObTabletMdsData +{ + friend class ObTablet; +public: + ObTabletMdsData(); + ~ObTabletMdsData(); + ObTabletMdsData(const ObTabletMdsData&) = delete; + ObTabletMdsData &operator=(const ObTabletMdsData&) = delete; +public: + void reset(); + int init(common::ObIAllocator &allocator); + int init( + common::ObIAllocator &allocator, + const ObTabletFullMemoryMdsData &full_memory_mds_data); + int init( + common::ObIAllocator &allocator, + const ObTabletMdsData &mds_table_data, + const ObTabletMdsData &base_data, + const int64_t finish_medium_scn); + int init( + common::ObIAllocator &allocator, + const ObTabletMdsData &other, + const int64_t finish_medium_scn, + const ObMergeType merge_type = ObMergeType::MERGE_TYPE_MAX); + int init( + common::ObIAllocator &allocator, + const ObTabletMdsData &other, + const ObTabletFullMediumInfo &full_memory_medium_info_list, + const int64_t finish_medium_scn); + int init_with_update_medium_info( + common::ObIAllocator &allocator, + const ObTabletMdsData &other); + int init( + ObArenaAllocator &allocator, + const ObTabletCreateDeleteMdsUserData &tablet_status); + int set_tablet_status( + ObArenaAllocator *allocator, + const ObTabletStatus::Status &tablet_status, + const ObTabletMdsUserDataType &data_type); + bool is_valid() const; + void set_mem_addr(); +public: + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; + int deserialize(const char *buf, const int64_t data_len, int64_t &pos); + int64_t get_serialize_size() const; + + TO_STRING_KV(K_(is_inited), + K_(tablet_status), + K_(aux_tablet_info), + K_(extra_medium_info), + K_(medium_info_list), + K_(auto_inc_seq), + K_(tablet_status_cache), + K_(aux_tablet_info_cache)); +public: + static int load_mds_dump_kv( + common::ObIAllocator &allocator, + const ObTabletComplexAddr &complex_addr, + const mds::MdsDumpKV *&kv); + static int load_medium_info_list( + common::ObIAllocator &allocator, + const ObTabletComplexAddr &complex_addr, + const ObTabletDumpedMediumInfo *&medium_info_list); + static void free_mds_dump_kv( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *kv); + static void free_medium_info_list( + common::ObIAllocator &allocator, + const ObTabletDumpedMediumInfo *medium_info_list); + static int fetch_auto_inc_seq( + const ObTabletComplexAddr &auto_inc_seq_addr, + ObTabletMemberWrapper &wrapper); + static int build_tablet_status( + common::ObArenaAllocator &allocator, + const ObTabletTxMultiSourceDataUnit &tx_data, + const share::SCN &create_commit_scn, + ObTabletMdsData &mds_data); + static int build_aux_tablet_info( + common::ObArenaAllocator &allocator, + const ObTabletTxMultiSourceDataUnit &tx_data, + const ObTabletBindingInfo &ddl_data, + const share::SCN &clog_checkpoint_scn, + ObTabletMdsData &mds_data); + static int build_auto_inc_seq( + common::ObArenaAllocator &allocator, + const share::ObTabletAutoincSeq &auto_inc_seq, + ObTabletMdsData &mds_data); + static int build_mds_data( + common::ObArenaAllocator &allocator, + const share::ObTabletAutoincSeq &auto_inc_seq, + const ObTabletTxMultiSourceDataUnit &tx_data, + const share::SCN &create_commit_scn, + const ObTabletBindingInfo &ddl_data, + const share::SCN &clog_checkpoint_scn, + const compaction::ObMediumCompactionInfoList &info_list, + ObTabletMdsData &mds_data); +private: + int alloc_and_new(common::ObIAllocator &allocator); + int do_init( + common::ObIAllocator &allocator, + const mds::MdsDumpKV *tablet_status_uncommitted_kv, + const mds::MdsDumpKV *tablet_status_committed_kv, + const mds::MdsDumpKV *aux_tablet_info_uncommitted_kv, + const mds::MdsDumpKV *aux_tablet_info_committed_kv, + const share::ObTabletAutoincSeq *auto_inc_seq); + int init_medium_info_list( + common::ObIAllocator &allocator, + const ObTabletDumpedMediumInfo *old_medium_info_list, + const ObTaletExtraMediumInfo &old_extra_medium_info, + const int64_t finish_medium_scn = 0, + const ObMergeType merge_type = ObMergeType::MERGE_TYPE_MAX); + int init_medium_info_list( + common::ObIAllocator &allocator, + const ObTabletDumpedMediumInfo *old_medium_info_list, + const ObTabletFullMediumInfo &full_memory_medium_info_list, + const ObTaletExtraMediumInfo &old_extra_medium_info, + const int64_t finish_medium_scn); + int init_with_update_medium_info( + common::ObIAllocator &allocator, + const ObTabletDumpedMediumInfo *old_medium_info_list, + const ObTaletExtraMediumInfo &old_extra_medium_info); + static int fuse_mds_dump_node( + common::ObIAllocator &allocator, + const ObTabletComplexAddr &mds_table_data, + const ObTabletComplexAddr &base_data, + ObTabletComplexAddr &fused_data); + static int fuse_mds_dump_node( + common::ObIAllocator &allocator, + const ObTabletMdsDumpStruct &mds_table_data, + const ObTabletMdsDumpStruct &base_data, + ObTabletMdsDumpStruct &fused_data); + static int fuse_mds_dump_node( + common::ObIAllocator &allocator, + const ObTabletComplexAddr &mds_table_data, + const ObTabletComplexAddr &base_data, + ObTabletComplexAddr &fused_data); + static int fuse_mds_dump_node( + common::ObIAllocator &allocator, + const int64_t finish_medium_scn, + const ObTabletComplexAddr &mds_table_data, + const ObTabletComplexAddr &base_data, + ObTabletComplexAddr &fused_data); + static int read_medium_info( + common::ObIAllocator &allocator, + const ObMetaDiskAddr &addr, + common::ObSEArray &array); + static int copy_medium_info_list( + const int64_t finish_medium_scn, + const ObTabletDumpedMediumInfo &input_medium_info_list, + ObTabletDumpedMediumInfo &medium_info_list); + template + static int update_user_data_from_complex_addr( + const ObTabletComplexAddr &complex_addr, + T &user_data); +public: + bool is_inited_; + ObTabletMdsDumpStruct tablet_status_; + ObTabletMdsDumpStruct aux_tablet_info_; + + ObTaletExtraMediumInfo extra_medium_info_; + ObTabletComplexAddr medium_info_list_; + + ObTabletComplexAddr auto_inc_seq_; + ObTabletCreateDeleteMdsUserData tablet_status_cache_; + ObTabletBindingMdsUserData aux_tablet_info_cache_; +}; + +template +int ObTabletMdsData::update_user_data_from_complex_addr( + const ObTabletComplexAddr &complex_addr, + T &user_data) +{ + int ret = common::OB_SUCCESS; + + if (OB_UNLIKELY(!complex_addr.is_memory_object())) { + ret = common::OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "complex addr is not memory type", K(ret), K(complex_addr)); + } else { + const mds::MdsDumpKV *kv = complex_addr.ptr_; + const common::ObString &str = kv->v_.user_data_; + if (str.empty()) { + // do nothing + } else { + int64_t pos = 0; + if (OB_FAIL(user_data.deserialize(str.ptr(), str.length(), pos))) { + STORAGE_LOG(WARN, "failed to deserialize", K(ret)); + } + } + } + + return ret; +} +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_MDS_DATA diff --git a/src/storage/tablet/ob_tablet_mds_data_cache.cpp b/src/storage/tablet/ob_tablet_mds_data_cache.cpp new file mode 100644 index 000000000..91b90bf85 --- /dev/null +++ b/src/storage/tablet/ob_tablet_mds_data_cache.cpp @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_mds_data_cache.h" + +#include "storage/tx/ob_trans_define.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/tablet/ob_tablet_binding_mds_user_data.h" + +using namespace oceanbase::transaction; + +namespace oceanbase +{ +namespace storage +{ +ObTabletStatusCache::ObTabletStatusCache() + : tablet_status_(ObTabletStatus::MAX), + create_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), + delete_commit_version_(ObTransVersion::INVALID_TRANS_VERSION) +{ +} + +void ObTabletStatusCache::set_value( + const ObTabletStatus &tablet_status, + const int64_t create_commit_version, + const int64_t delete_commit_version) +{ + tablet_status_ = tablet_status; + create_commit_version_ = create_commit_version; + delete_commit_version_ = delete_commit_version; +} + +void ObTabletStatusCache::set_value(const ObTabletCreateDeleteMdsUserData &user_data) +{ + tablet_status_ = user_data.tablet_status_; + create_commit_version_ = user_data.create_commit_version_; + delete_commit_version_ = user_data.delete_commit_version_; +} + +void ObTabletStatusCache::reset() +{ + tablet_status_ = ObTabletStatus::MAX; + create_commit_version_ = ObTransVersion::INVALID_TRANS_VERSION; + delete_commit_version_ = ObTransVersion::INVALID_TRANS_VERSION; +} + + +ObDDLInfoCache::ObDDLInfoCache() + : redefined_(false), + schema_version_(INT64_MAX), + snapshot_version_(INT64_MAX) +{ +} + +void ObDDLInfoCache::set_value( + const bool redefined, + const int64_t schema_version, + const int64_t snapshot_version) +{ + redefined_ = redefined; + schema_version_ = schema_version; + snapshot_version_ = snapshot_version; +} + +void ObDDLInfoCache::set_value(const ObTabletBindingMdsUserData &user_data) +{ + redefined_ = user_data.redefined_; + schema_version_ = user_data.schema_version_; + snapshot_version_ = user_data.snapshot_version_; +} + +void ObDDLInfoCache::reset() +{ + redefined_ = false; + schema_version_ = INT64_MAX; + snapshot_version_ = INT64_MAX; +} +} // namespace storage +} // namespace oceanbase \ No newline at end of file diff --git a/src/storage/tablet/ob_tablet_mds_data_cache.h b/src/storage/tablet/ob_tablet_mds_data_cache.h new file mode 100644 index 000000000..b3f0c9514 --- /dev/null +++ b/src/storage/tablet/ob_tablet_mds_data_cache.h @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_MDS_DATA_CACHE +#define OCEANBASE_STORAGE_OB_TABLET_MDS_DATA_CACHE + +#include +#include "storage/tablet/ob_tablet_status.h" + +namespace oceanbase +{ +namespace storage +{ +class ObTabletCreateDeleteMdsUserData; +class ObTabletBindingMdsUserData; + +// Only for cache the most frequent case, Nomal tablet status +class ObTabletStatusCache final +{ +public: + ObTabletStatusCache(); + ObTabletStatusCache(const ObTabletStatusCache&) = delete; + ObTabletStatusCache &operator=(const ObTabletStatusCache&) = delete; +public: + void set_value( + const ObTabletStatus &tablet_status, + const int64_t create_commit_version, + const int64_t delete_commit_version); + + void set_value(const ObTabletCreateDeleteMdsUserData &user_data); + + ObTabletStatus get_tablet_status() const { return tablet_status_; } + int64_t get_create_commit_version() const { return create_commit_version_; } + int64_t get_delete_commit_version() const { return delete_commit_version_; } + + void reset(); + + bool is_valid() const { return tablet_status_.is_valid(); } + +public: + TO_STRING_KV(K_(tablet_status), + K_(create_commit_version), + K_(delete_commit_version)); +private: + ObTabletStatus tablet_status_; + int64_t create_commit_version_; + int64_t delete_commit_version_; +}; + + +class ObDDLInfoCache final +{ +public: + ObDDLInfoCache(); + ObDDLInfoCache(const ObDDLInfoCache&) = delete; + ObDDLInfoCache &operator=(const ObDDLInfoCache&) = delete; +public: + void set_value( + const bool redefined, + const int64_t schema_version, + const int64_t snapshot_version); + + void set_value(const ObTabletBindingMdsUserData &user_data); + + bool is_redefined() const { return redefined_; } + int64_t get_schema_version() const { return schema_version_; } + int64_t get_snapshot_version() const { return snapshot_version_; } + + void reset(); + + bool is_valid() const + { + return INT64_MAX != schema_version_ + && INT64_MAX != snapshot_version_; + } + +public: + TO_STRING_KV(K_(redefined), + K_(schema_version), + K_(snapshot_version)); +private: + bool redefined_; + int64_t schema_version_; + int64_t snapshot_version_; +}; + +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_MDS_DATA_CACHE diff --git a/src/storage/tablet/ob_tablet_mds_node_dump_operator.cpp b/src/storage/tablet/ob_tablet_mds_node_dump_operator.cpp new file mode 100644 index 000000000..35d4b0117 --- /dev/null +++ b/src/storage/tablet/ob_tablet_mds_node_dump_operator.cpp @@ -0,0 +1,235 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_mds_node_dump_operator.h" +#include "lib/ob_errno.h" +#include "lib/oblog/ob_log.h" +#include "lib/string/ob_string.h" +#include "share/ob_errno.h" +#include "share/ob_tablet_autoincrement_param.h" +#include "storage/tablet/ob_tablet_mds_data.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include "storage/multi_data_source/compile_utility/mds_dummy_key.h" +#include "storage/multi_data_source/mds_table_handle.h" + +#define USING_LOG_PREFIX MDS + +namespace oceanbase +{ +namespace storage +{ +ObTabletDumpMdsNodeOperator::ObTabletDumpMdsNodeOperator(ObTabletMdsData &mds_data, common::ObIAllocator &allocator) + : mds_data_(mds_data), + allocator_(allocator) +{ +} + +template <> +int ObTabletDumpMdsNodeOperator::dump(const mds::MdsDumpKV &kv, bool &dumped) +{ + int ret = OB_SUCCESS; + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + const mds::MdsDumpKey &key = kv.k_; + const mds::MdsDumpNode &node = kv.v_; + + if (table_id == key.mds_table_id_ && unit_id == key.mds_unit_id_) { + const mds::TwoPhaseCommitState &state = node.status_.get_state(); + switch (state) { + case mds::TwoPhaseCommitState::STATE_INIT: + case mds::TwoPhaseCommitState::BEFORE_PREPARE: + case mds::TwoPhaseCommitState::ON_ABORT: + case mds::TwoPhaseCommitState::ON_PREPARE: + if (OB_FAIL(mds_data_.tablet_status_.uncommitted_kv_.ptr_->assign(kv, allocator_))) { + LOG_WARN("failed to copy mds dump kv", K(ret)); + } + break; + case mds::TwoPhaseCommitState::ON_COMMIT: + if (OB_FAIL(mds_data_.tablet_status_.committed_kv_.ptr_->assign(kv, allocator_))) { + LOG_WARN("failed to copy mds dump kv", K(ret)); + } + break; + case mds::TwoPhaseCommitState::STATE_END: + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid state", K(ret), K(table_id), K(unit_id), K(state)); + break; + } + + if (OB_SUCC(ret)) { + dumped = true; + } + } + + return ret; +} + +template <> +int ObTabletDumpMdsNodeOperator::dump(const mds::MdsDumpKV &kv, bool &dumped) +{ + int ret = OB_SUCCESS; + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + const mds::MdsDumpKey &key = kv.k_; + const mds::MdsDumpNode &node = kv.v_; + + if (table_id == key.mds_table_id_ && unit_id == key.mds_unit_id_) { + const mds::TwoPhaseCommitState &state = node.status_.get_state(); + switch (state) { + case mds::TwoPhaseCommitState::STATE_INIT: + case mds::TwoPhaseCommitState::BEFORE_PREPARE: + case mds::TwoPhaseCommitState::ON_ABORT: + case mds::TwoPhaseCommitState::ON_PREPARE: + if (OB_FAIL(mds_data_.aux_tablet_info_.uncommitted_kv_.ptr_->assign(kv, allocator_))) { + LOG_WARN("failed to copy mds dump kv", K(ret)); + } + break; + case mds::TwoPhaseCommitState::ON_COMMIT: + if (OB_FAIL(mds_data_.aux_tablet_info_.committed_kv_.ptr_->assign(kv, allocator_))) { + LOG_WARN("failed to copy mds dump kv", K(ret)); + } + break; + case mds::TwoPhaseCommitState::STATE_END: + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid state", K(ret), K(table_id), K(unit_id), K(state)); + break; + } + + if (OB_SUCC(ret)) { + dumped = true; + } + } + + return ret; +} + +template <> +int ObTabletDumpMdsNodeOperator::dump(const mds::MdsDumpKV &kv, bool &dumped) +{ + int ret = OB_SUCCESS; + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + const mds::MdsDumpKey &key = kv.k_; + const mds::MdsDumpNode &node = kv.v_; + + if (table_id == key.mds_table_id_ && unit_id == key.mds_unit_id_) { + const mds::TwoPhaseCommitState &state = node.status_.get_state(); + const common::ObString &user_data = kv.v_.user_data_; + int64_t pos = 0; + share::ObTabletAutoincSeq *auto_inc_seq = mds_data_.auto_inc_seq_.ptr_; + if (OB_UNLIKELY(state != mds::TwoPhaseCommitState::ON_COMMIT)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid state", K(ret), K(state)); + } else if (OB_FAIL(auto_inc_seq->deserialize(allocator_, user_data.ptr(), user_data.length(), pos))) { + LOG_WARN("failed to deserialize", K(ret)); + } else { + dumped = true; + } + } + + return ret; +} + +template <> +int ObTabletDumpMdsNodeOperator::dump(const mds::MdsDumpKV &kv, bool &dumped) +{ + int ret = OB_SUCCESS; + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + const mds::MdsDumpKey &key = kv.k_; + const mds::MdsDumpNode &node = kv.v_; + + if (table_id == key.mds_table_id_ && unit_id == key.mds_unit_id_) { + const mds::TwoPhaseCommitState &state = node.status_.get_state(); + ObTabletDumpedMediumInfo *medium_info_list = mds_data_.medium_info_list_.ptr_; + if (OB_UNLIKELY(state != mds::TwoPhaseCommitState::ON_COMMIT)) { + ret = OB_SUCCESS; + LOG_WARN("invalid state", K(ret), K(state)); + } else if (OB_FAIL(medium_info_list->append(key, node))) { + LOG_WARN("failed to copy mds dump node", K(ret)); + } else { + dumped = true; + } + } + + return ret; +} + +int ObTabletDumpMdsNodeOperator::operator()(const mds::MdsDumpKV &kv) +{ + int ret = OB_SUCCESS; + bool dumped = false; + + if (OB_SUCC(ret) && !dumped) { + if (OB_UNLIKELY(OB_SUCCESS != (ret = dump(kv, dumped)))) { + LOG_WARN("failed to dump tablet status", K(ret), K(kv)); + } + } + + if (OB_SUCC(ret) && !dumped) { + if (OB_UNLIKELY(OB_SUCCESS != (ret = dump(kv, dumped)))) { + LOG_WARN("failed to dump aux tablet info", K(ret), K(kv)); + } + } + + if (OB_SUCC(ret) && !dumped) { + if (OB_UNLIKELY(OB_SUCCESS != (ret = dump(kv, dumped)))) { + LOG_WARN("failed to dump auto inc seq", K(ret), K(kv)); + } + } + + if (OB_SUCC(ret) && !dumped) { + if (OB_UNLIKELY(OB_SUCCESS != (ret = dump(kv, dumped)))) { + LOG_WARN("failed to dump medium info", K(ret), K(kv)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(!dumped)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected kv type, not dumped", K(ret), K(kv), K(dumped)); + } + + return ret; +} + + +ObTabletMediumInfoNodeOperator::ObTabletMediumInfoNodeOperator(ObTabletDumpedMediumInfo &medium_info_list, common::ObIAllocator &allocator) + : medium_info_list_(medium_info_list), + allocator_(allocator) +{ +} + +int ObTabletMediumInfoNodeOperator::operator()(const mds::MdsDumpKV &kv) +{ + int ret = OB_SUCCESS; + constexpr uint8_t table_id = mds::TupleTypeIdx::value; + constexpr uint8_t unit_id = mds::TupleTypeIdx>::value; + const mds::MdsDumpKey &key = kv.k_; + const mds::MdsDumpNode &node = kv.v_; + + if (table_id == key.mds_table_id_ && unit_id == key.mds_unit_id_) { + const mds::TwoPhaseCommitState &state = node.status_.get_state(); + if (OB_UNLIKELY(state != mds::TwoPhaseCommitState::ON_COMMIT)) { + ret = OB_SUCCESS; + LOG_WARN("invalid state", K(ret), K(state)); + } else if (OB_FAIL(medium_info_list_.append(key, node))) { + LOG_WARN("failed to copy mds dump node", K(ret)); + } + } + + return ret; + + return ret; +} +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_mds_node_dump_operator.h b/src/storage/tablet/ob_tablet_mds_node_dump_operator.h new file mode 100644 index 000000000..5494bd8d7 --- /dev/null +++ b/src/storage/tablet/ob_tablet_mds_node_dump_operator.h @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_DUMP_MDS_NODE_OPERATOR +#define OCEANBASE_STORAGE_OB_TABLET_DUMP_MDS_NODE_OPERATOR + +namespace oceanbase +{ +namespace common +{ +class ObIAllocator; +} + +namespace storage +{ +namespace mds +{ +struct MdsDumpKV; +} + +class ObTabletMdsData; +class ObTabletDumpedMediumInfo; + +class ObTabletDumpMdsNodeOperator +{ +public: + ObTabletDumpMdsNodeOperator(ObTabletMdsData &mds_data, common::ObIAllocator &allocator); +public: + int operator()(const mds::MdsDumpKV &kv); +private: + template + int dump(const mds::MdsDumpKV &kv, bool &dumped); +private: + ObTabletMdsData &mds_data_; + common::ObIAllocator &allocator_; +}; + +class ObTabletMediumInfoNodeOperator +{ +public: + ObTabletMediumInfoNodeOperator(ObTabletDumpedMediumInfo &medium_info_list, common::ObIAllocator &allocator); +public: + int operator()(const mds::MdsDumpKV &kv); +private: + ObTabletDumpedMediumInfo &medium_info_list_; + common::ObIAllocator &allocator_; +}; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_DUMP_MDS_NODE_OPERATOR diff --git a/src/storage/tablet/ob_tablet_medium_info_reader.cpp b/src/storage/tablet/ob_tablet_medium_info_reader.cpp new file mode 100644 index 000000000..ada3ea2fd --- /dev/null +++ b/src/storage/tablet/ob_tablet_medium_info_reader.cpp @@ -0,0 +1,336 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_medium_info_reader.h" +#include "lib/ob_errno.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_mds_data.h" + +#define USING_LOG_PREFIX STORAGE + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +ObTabletMediumInfoReader::ObTabletMediumInfoReader(const ObTablet &tablet) + : is_inited_(false), + tablet_(tablet), + allocator_(nullptr), + mds_iter_(), + dump_iter_(), + mds_key_(), + mds_node_(nullptr), + dump_key_(), + dump_medium_info_(nullptr), + mds_end_(false), + dump_end_(false) +{ +} + +ObTabletMediumInfoReader::~ObTabletMediumInfoReader() +{ + reset(); +} + +int ObTabletMediumInfoReader::init(common::ObArenaAllocator &allocator) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else { + mds::MdsTableHandle mds_table; + const ObTabletDumpedMediumInfo *dumped_medium_info = nullptr; + if (OB_FAIL(tablet_.inner_get_mds_table(mds_table, false/*not_exist_create*/))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("failed to get mds table", K(ret)); + } else { + mds_end_ = true; // no mds table, directly iter end + ret = OB_SUCCESS; + LOG_INFO("no mds table", K(ret), K_(mds_end)); + } + } else if (OB_FAIL(mds_iter_.init(mds_table))) { + LOG_WARN("failed to init mds iter", K(ret)); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObTabletMdsData::load_medium_info_list(allocator, tablet_.mds_data_.medium_info_list_, dumped_medium_info))) { + LOG_WARN("failed to load medium info list", K(ret), + "ls_id", tablet_.get_tablet_meta().ls_id_, + "tablet_id", tablet_.get_tablet_meta().tablet_id_); + } else if (OB_ISNULL(dumped_medium_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, medium info is null", K(ret), KP(dumped_medium_info)); + } else if (OB_FAIL(dump_iter_.init(allocator, *dumped_medium_info))) { + LOG_WARN("failed to init dumped iter", K(ret)); + } else { + allocator_ = &allocator; + } + + ObTabletMdsData::free_medium_info_list(allocator, dumped_medium_info); + } + + if (OB_SUCC(ret)) { + is_inited_ = true; + } + + return ret; +} + +void ObTabletMediumInfoReader::reset() +{ + dump_end_ = false; + mds_end_ = false; + dump_medium_info_ = nullptr; + dump_key_.reset(); + mds_node_ = nullptr; + mds_key_.reset(); + dump_iter_.reset(); + allocator_ = nullptr; + is_inited_ = false; + // TODO(@xianzhi) clear mds table lock +} + +int ObTabletMediumInfoReader::get_next_medium_info( + common::ObIAllocator &allocator, + compaction::ObMediumCompactionInfoKey &key, + compaction::ObMediumCompactionInfo &medium_info) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else { + if (OB_FAIL(ret)) { + } else if (!mds_key_.is_valid()) { + if (OB_FAIL(advance_mds_iter())) { + LOG_WARN("failed to advance mds iter", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (!dump_key_.is_valid()) { + if (OB_FAIL(advance_dump_iter())) { + LOG_WARN("failed to advance dump iter", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (mds_end_ && dump_end_) { + // both end, just output iter end + ret = OB_ITER_END; + LOG_DEBUG("iter end", K(ret)); + } else if (mds_end_) { + // mds end, output dump node + if (OB_FAIL(output_medium_info_from_dump_iter(allocator, key, medium_info))) { + LOG_WARN("failed to output medium info", K(ret)); + } else if (OB_FAIL(advance_dump_iter())) { + LOG_WARN("failed to advance dump iter", K(ret)); + } + } else if (dump_end_) { + // dump end, output mds node + if (OB_FAIL(output_medium_info_from_mds_iter(allocator, key, medium_info))) { + LOG_WARN("failed to output medium info", K(ret)); + } else if (OB_FAIL(advance_mds_iter())) { + LOG_WARN("failed to advance mds iter", K(ret)); + } + } else if (OB_UNLIKELY(!mds_key_.is_valid() || !dump_key_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, mds key and dump key should both be valid", K(ret), K_(mds_key), K_(dump_key)); + } else if (dump_key_ < mds_key_) { + // output dump node + if (OB_FAIL(output_medium_info_from_dump_iter(allocator, key, medium_info))) { + LOG_WARN("failed to output medium info", K(ret)); + } else if (OB_FAIL(advance_dump_iter())) { + LOG_WARN("failed to advance dump iter", K(ret)); + } + } else if (dump_key_ == mds_key_) { + // output mds node + if (OB_FAIL(output_medium_info_from_mds_iter(allocator, key, medium_info))) { + LOG_WARN("failed to output medium info", K(ret)); + } else if (OB_FAIL(advance_mds_iter())) { + LOG_WARN("failed to advance mds iter", K(ret)); + } else if (OB_FAIL(advance_dump_iter())) { + LOG_WARN("failed to advance dump iter", K(ret)); + } + } else { + // output mds node + if (OB_FAIL(output_medium_info_from_mds_iter(allocator, key, medium_info))) { + LOG_WARN("failed to output medium info", K(ret)); + } else if (OB_FAIL(advance_mds_iter())) { + LOG_WARN("failed to advance mds iter", K(ret)); + } + } + } + + return ret; +} + +// temp solution, TODO(@xianzhi) +int ObTabletMediumInfoReader::get_specified_medium_info( + common::ObIAllocator &allocator, + const compaction::ObMediumCompactionInfoKey &input_key, + compaction::ObMediumCompactionInfo &input_medium_info) +{ + int ret = OB_SUCCESS; + ObArenaAllocator tmp_allocator; + compaction::ObMediumCompactionInfoKey tmp_key; + compaction::ObMediumCompactionInfo tmp_medium_info; + while (OB_SUCC(ret)) { + if (OB_FAIL(get_next_medium_info(tmp_allocator, tmp_key, tmp_medium_info))) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + break; + } else { + LOG_WARN("failed to get medium info", K(ret)); + } + } else if (OB_UNLIKELY(tmp_key > input_key)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("medium info not exist", K(ret), K(tmp_key), K(input_key)); + } else if (tmp_key == input_key) { + if (OB_FAIL(input_medium_info.init(allocator, tmp_medium_info))) { + LOG_WARN("failed to init medium info", K(ret)); + } else { + break; + } + } + tmp_medium_info.reset(); + } // end of while + return ret; +} + +// temp solution, TODO(@xianzhi) +int ObTabletMediumInfoReader::get_min_medium_snapshot(int64_t &min_medium_snapshot) +{ + int ret = OB_SUCCESS; + ObArenaAllocator tmp_allocator; + compaction::ObMediumCompactionInfoKey tmp_key; + compaction::ObMediumCompactionInfo tmp_medium_info; + min_medium_snapshot = INT64_MAX; + while (OB_SUCC(ret)) { + if (OB_FAIL(get_next_medium_info(tmp_allocator, tmp_key, tmp_medium_info))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get medium info", K(ret)); + } + } else { + min_medium_snapshot = tmp_key.get_medium_snapshot(); + break; + } + } // end of while + return ret; +} + +// temp solution!!!, TODO(@xianzhi) +int ObTabletMediumInfoReader::get_max_medium_snapshot(int64_t &max_medium_snapshot) +{ + int ret = OB_SUCCESS; + ObArenaAllocator tmp_allocator; + compaction::ObMediumCompactionInfoKey tmp_key; + compaction::ObMediumCompactionInfo tmp_medium_info; + max_medium_snapshot = 0; + while (OB_SUCC(ret)) { + if (OB_FAIL(get_next_medium_info(tmp_allocator, tmp_key, tmp_medium_info))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get medium info", K(ret)); + } + } else { + max_medium_snapshot = tmp_key.get_medium_snapshot(); + } + tmp_medium_info.reset(); + } // end of while + return ret; +} + +int ObTabletMediumInfoReader::advance_mds_iter() +{ + int ret = OB_SUCCESS; + + if (mds_end_) { + } else if (OB_FAIL(mds_iter_.get_next(mds_key_, mds_node_))) { + if (OB_ITER_END == ret) { + mds_end_ = true; + ret = OB_SUCCESS; + LOG_DEBUG("mds iter end", K(ret), K_(mds_end)); + } else { + LOG_WARN("failed to get mds node", K(ret)); + } + } else { + LOG_DEBUG("get next mds node", K_(mds_key), K_(mds_node)); + } + + return ret; +} + +int ObTabletMediumInfoReader::advance_dump_iter() +{ + int ret = OB_SUCCESS; + + if (dump_end_) { + } else if (OB_FAIL(dump_iter_.get_next_medium_info(dump_key_, dump_medium_info_))) { + if (OB_ITER_END == ret) { + dump_end_ = true; + ret = OB_SUCCESS; + LOG_DEBUG("dump iter end", K(ret), K_(dump_end)); + } else { + LOG_WARN("failed to get dump node", K(ret)); + } + } else { + LOG_DEBUG("get next dump node", K_(dump_key), K_(dump_medium_info)); + } + + return ret; +} + +int ObTabletMediumInfoReader::output_medium_info_from_mds_iter( + common::ObIAllocator &allocator, + compaction::ObMediumCompactionInfoKey &key, + compaction::ObMediumCompactionInfo &medium_info) +{ + int ret = OB_SUCCESS; + + const compaction::ObMediumCompactionInfo &user_data = mds_node_->user_data_; + if (OB_FAIL(medium_info.assign(allocator, user_data))) { + LOG_WARN("failed to copy medium info", K(ret), K(user_data)); + } else { + key = mds_key_; + } + + return ret; +} + +int ObTabletMediumInfoReader::output_medium_info_from_dump_iter( + common::ObIAllocator &allocator, + compaction::ObMediumCompactionInfoKey &key, + compaction::ObMediumCompactionInfo &medium_info) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(medium_info.assign(allocator, *dump_medium_info_))) { + LOG_WARN("failed to copy medium info", K(ret)); + } else { + key = dump_key_; + } + + return ret; +} +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_medium_info_reader.h b/src/storage/tablet/ob_tablet_medium_info_reader.h new file mode 100644 index 000000000..c1624f794 --- /dev/null +++ b/src/storage/tablet/ob_tablet_medium_info_reader.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_MEDIUM_INFO_READER +#define OCEANBASE_STORAGE_OB_TABLET_MEDIUM_INFO_READER + +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/tablet/ob_tablet_dumped_medium_info.h" + +namespace oceanbase +{ +namespace storage +{ +class ObTabletDumpedMediumInfo; + +class ObTabletMediumInfoReader +{ +public: + ObTabletMediumInfoReader(const ObTablet &tablet); + ~ObTabletMediumInfoReader(); +public: + int init(common::ObArenaAllocator &allocator); + void reset(); + + // TODO(@bowen.gbw): filter uncommitted node + int get_next_medium_info( + common::ObIAllocator &allocator, + compaction::ObMediumCompactionInfoKey &key, + compaction::ObMediumCompactionInfo &medium_info); + int get_specified_medium_info( + common::ObIAllocator &allocator, + const compaction::ObMediumCompactionInfoKey &key, + compaction::ObMediumCompactionInfo &medium_info); + + int get_min_medium_snapshot(int64_t &min_medium_snapshot); + int get_max_medium_snapshot(int64_t &max_medium_snapshot); +private: + int advance_mds_iter(); + int advance_dump_iter(); + int output_medium_info_from_mds_iter( + common::ObIAllocator &allocator, + compaction::ObMediumCompactionInfoKey &key, + compaction::ObMediumCompactionInfo &medium_info); + int output_medium_info_from_dump_iter( + common::ObIAllocator &allocator, + compaction::ObMediumCompactionInfoKey &key, + compaction::ObMediumCompactionInfo &medium_info); +private: + bool is_inited_; + const ObTablet &tablet_; + common::ObArenaAllocator *allocator_; + + // mds iter will hold mds table handle + mds::ObMdsUnitRowNodeScanIterator mds_iter_; + ObTabletDumpedMediumInfoIterator dump_iter_; + compaction::ObMediumCompactionInfoKey mds_key_; + mds::UserMdsNode *mds_node_; + compaction::ObMediumCompactionInfoKey dump_key_; + const compaction::ObMediumCompactionInfo *dump_medium_info_; + bool mds_end_; + bool dump_end_; +}; +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_MEDIUM_INFO_READER diff --git a/src/storage/tablet/ob_tablet_member_wrapper.h b/src/storage/tablet/ob_tablet_member_wrapper.h new file mode 100644 index 000000000..d2ade7785 --- /dev/null +++ b/src/storage/tablet/ob_tablet_member_wrapper.h @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_MEMBER_WRAPPER +#define OCEANBASE_STORAGE_OB_TABLET_MEMBER_WRAPPER + +#include +#include "lib/oblog/ob_log.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/meta_mem/ob_storage_meta_cache.h" +#include "storage/tablet/ob_tablet_table_store.h" +#include "share/ob_tablet_autoincrement_param.h" + +namespace oceanbase +{ +namespace storage +{ + +// only allow such classes to specialize template class ObTabletMemberWrapper: +// ObTabletTableStore +// ObTabletAutoincSeq +// forbidden classes: ObStorageSchema, ObMediumCompactionInfoList +template ::value || std::is_same::value, T>::type> +class ObTabletMemberWrapper final +{ +public: + friend class ObTablet; + friend class ObTabletMdsData; +public: + ObTabletMemberWrapper(); + ~ObTabletMemberWrapper() = default; +public: + bool is_valid() const; + int get_member(const T *&t) const; + const T *get_member() const; + const ObStorageMetaHandle &get_meta_handle() const { return secondary_meta_handle_; } + TO_STRING_KV(KP_(ptr), KPC_(ptr), K_(secondary_meta_handle)); +private: + void set_member(T *t); + int set_cache_handle(ObStorageMetaHandle &handle); + int set_cache_handle(const ObStorageMetaValue &value); +private: + const T *ptr_; + ObStorageMetaHandle secondary_meta_handle_; +}; + +template +ObTabletMemberWrapper::ObTabletMemberWrapper() + : ptr_(nullptr), + secondary_meta_handle_() +{ +} + +template +bool ObTabletMemberWrapper::is_valid() const +{ + return nullptr != ptr_ || secondary_meta_handle_.is_valid(); +}; + +template +void ObTabletMemberWrapper::set_member(T *t) +{ + ptr_ = t; +}; + +template +int ObTabletMemberWrapper::set_cache_handle(ObStorageMetaHandle &handle) +{ + int ret = common::OB_SUCCESS; + const ObStorageMetaValue *value = nullptr; + if (OB_UNLIKELY(!handle.is_valid())) { + STORAGE_LOG(WARN, "secondary meta handle is not valid", K(ret), K(handle)); + } else if (OB_FAIL(handle.get_value(value))) { + STORAGE_LOG(WARN, "secondary meta handle get value failed", K(ret), K(handle)); + } else if (OB_ISNULL(value)) { + ret = common::OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "unexpected null secondary meta value", K(ret), K(handle)); + } else if (OB_FAIL(set_cache_handle(*value))) { + STORAGE_LOG(WARN, "failed to set cache handle", K(ret)); + } else { + secondary_meta_handle_ = handle; + } + return ret; +}; + +template <> +inline int ObTabletMemberWrapper::set_cache_handle(const ObStorageMetaValue &value) +{ + int ret = OB_SUCCESS; + const ObTabletTableStore *table_store = nullptr; + if (OB_FAIL(value.get_table_store(table_store))) { + STORAGE_LOG(WARN, "get table store failed", K(ret)); + } else { + ptr_ = table_store; + } + return ret; +} + +template <> +inline int ObTabletMemberWrapper::set_cache_handle(const ObStorageMetaValue &value) +{ + int ret = OB_SUCCESS; + const share::ObTabletAutoincSeq *autoinc_seq = nullptr; + if (OB_FAIL(value.get_autoinc_seq(autoinc_seq))) { + STORAGE_LOG(WARN, "get auto inc seq failed", K(ret)); + } else { + ptr_ = autoinc_seq; + } + return ret; +} + +template +int ObTabletMemberWrapper::get_member(const T *&t) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_INVALID_ERROR; + STORAGE_LOG(WARN, "tablet member wrapper is not valid"); + } else if (OB_ISNULL(ptr_)) { + ret = OB_ERR_NULL_VALUE; + STORAGE_LOG(WARN, "tablet member wrapper pointer is nullptr"); + } else { + t = ptr_; + } + return ret; +} + +template +const T *ObTabletMemberWrapper::get_member() const +{ + OB_ASSERT(is_valid()); + OB_ASSERT(nullptr != ptr_); + return ptr_; +} + +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_MEMBER_WRAPPER diff --git a/src/storage/tablet/ob_tablet_memtable_mgr.cpp b/src/storage/tablet/ob_tablet_memtable_mgr.cpp index 1b9e1d5f6..b760fda1b 100644 --- a/src/storage/tablet/ob_tablet_memtable_mgr.cpp +++ b/src/storage/tablet/ob_tablet_memtable_mgr.cpp @@ -31,17 +31,18 @@ using namespace share; using namespace obrpc; namespace storage { +using namespace mds; ObTabletMemtableMgr::ObTabletMemtableMgr() : ObIMemtableMgr(LockType::OB_SPIN_RWLOCK, &lock_def_), - ls_(NULL), + ls_(nullptr), lock_def_(common::ObLatchIds::TABLET_MEMTABLE_LOCK), retry_times_(0), schema_recorder_(), medium_info_recorder_() { #if defined(__x86_64__) - static_assert(sizeof(ObTabletMemtableMgr) <= 480, "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) <= 2048, "The size of ObTabletMemtableMgr will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); #endif } @@ -52,6 +53,7 @@ ObTabletMemtableMgr::~ObTabletMemtableMgr() void ObTabletMemtableMgr::destroy() { + STORAGE_LOG(DEBUG, "destroy tablet memtable mgr", KP(this), KPC(this)); MemMgrWLockGuard lock_guard(lock_); // release memtable memtable::ObIMemtable *imemtable = nullptr; @@ -68,6 +70,7 @@ void ObTabletMemtableMgr::destroy() memtable->set_frozen(); } } + reset_tables(); tablet_id_ = 0; ls_ = NULL; @@ -86,6 +89,7 @@ int ObTabletMemtableMgr::init(const common::ObTabletID &tablet_id, int ret = OB_SUCCESS; ObLSService *ls_service = MTL(storage::ObLSService *); ObLSHandle ls_handle; + ObMdsTableMgr *mds_table_mgr = nullptr; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; @@ -101,7 +105,7 @@ int ObTabletMemtableMgr::init(const common::ObTabletID &tablet_id, } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::TABLET_MOD))) { - TRANS_LOG(WARN, "failed to get ls", K(ret), K(MTL_ID())); + LOG_WARN("failed to get ls", K(ret), K(MTL_ID())); } else if (OB_ISNULL(ls_ = ls_handle.get_ls())) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(WARN, "ls should not be NULL", K(ret), KP(ls_)); @@ -112,7 +116,7 @@ int ObTabletMemtableMgr::init(const common::ObTabletID &tablet_id, freezer_ = freezer; retry_times_ = 0; is_inited_ = true; - TRANS_LOG(DEBUG, "succeeded to init tablet memtable mgr", K(ret), K(ls_id), K(tablet_id)); + TRANS_LOG(DEBUG, "succeeded to init tablet memtable mgr", K(ret), K(ls_id), K(tablet_id), KP(this), KPC(this)); } if (OB_UNLIKELY(!is_inited_)) { @@ -872,6 +876,8 @@ 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(); + + /************* memtable array **************/ MemMgrRLockGuard lock_guard(lock_); J_OBJ_START(); J_ARRAY_START(); @@ -884,9 +890,11 @@ int64_t ObTabletMemtableMgr::to_string(char *buf, const int64_t buf_len) const J_COMMA(); } } - J_KV("schema_recorder", schema_recorder_); J_ARRAY_END(); J_OBJ_END(); + /************* memtable array **************/ + + J_KV(K_(schema_recorder)); J_OBJ_END(); } return pos; diff --git a/src/storage/tablet/ob_tablet_memtable_mgr.h b/src/storage/tablet/ob_tablet_memtable_mgr.h index 332b4454a..6d1a1d2fb 100644 --- a/src/storage/tablet/ob_tablet_memtable_mgr.h +++ b/src/storage/tablet/ob_tablet_memtable_mgr.h @@ -19,6 +19,8 @@ #include "storage/ob_storage_struct.h" #include "storage/ob_storage_schema_recorder.h" #include "storage/compaction/ob_medium_compaction_mgr.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/multi_data_source/mds_table_mgr.h" namespace oceanbase { @@ -68,6 +70,7 @@ public: virtual int get_memtable_for_multi_source_data_unit( ObTableHandleV2 &handle, const memtable::MultiSourceDataUnitType type) const override; + int release_tail_memtable(memtable::ObIMemtable *memtable); int create_memtable(const share::SCN clog_checkpoint_scn, const int64_t schema_version, const bool for_replay); @@ -87,14 +90,9 @@ public: int set_is_tablet_freeze_for_active_memtable(ObTableHandleV2 &handle, bool is_force_freeze = false); - ObStorageSchemaRecorder &get_storage_schema_recorder() - { - return schema_recorder_; - } - compaction::ObTabletMediumCompactionInfoRecorder &get_medium_info_recorder() - { - return medium_info_recorder_; - } + ObStorageSchemaRecorder &get_storage_schema_recorder() { return schema_recorder_; } + compaction::ObTabletMediumCompactionInfoRecorder &get_medium_info_recorder() { return medium_info_recorder_; } + virtual int init_storage_recorder( const ObTabletID &tablet_id, const share::ObLSID &ls_id, diff --git a/src/storage/tablet/ob_tablet_meta.cpp b/src/storage/tablet/ob_tablet_meta.cpp index f329c84a7..abbe79a3b 100644 --- a/src/storage/tablet/ob_tablet_meta.cpp +++ b/src/storage/tablet/ob_tablet_meta.cpp @@ -16,8 +16,9 @@ #include "lib/ob_define.h" #include "lib/utility/serialization.h" -#include "share/schema/ob_table_schema.h" #include "share/scn.h" +#include "share/schema/ob_table_schema.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" namespace oceanbase { @@ -47,11 +48,8 @@ ObTabletMeta::ObTabletMeta() snapshot_version_(OB_INVALID_TIMESTAMP), multi_version_start_(OB_INVALID_TIMESTAMP), compat_mode_(lib::Worker::CompatMode::INVALID), - autoinc_seq_(), ha_status_(), report_status_(), - tx_data_(), - ddl_data_(), table_store_flag_(), ddl_start_scn_(SCN::min_scn()), ddl_snapshot_version_(OB_INVALID_TIMESTAMP), @@ -60,6 +58,9 @@ ObTabletMeta::ObTabletMeta() ddl_data_format_version_(0), max_serialized_medium_scn_(0), ddl_commit_scn_(SCN::min_scn()), + mds_checkpoint_scn_(), + transfer_info_(), + create_schema_version_(0), is_inited_(false) { } @@ -70,18 +71,14 @@ ObTabletMeta::~ObTabletMeta() } int ObTabletMeta::init( - ObIAllocator &allocator, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const common::ObTabletID &data_tablet_id, - const common::ObTabletID &lob_meta_tablet_id, - const common::ObTabletID &lob_piece_tablet_id, - const SCN create_scn, + const share::SCN create_scn, const int64_t snapshot_version, const lib::Worker::CompatMode compat_mode, const ObTabletTableStoreFlag &table_store_flag, - const int64_t max_sync_storage_schema_version, - const int64_t max_serialized_medium_scn) + const int64_t create_schema_version) { int ret = OB_SUCCESS; @@ -91,24 +88,26 @@ int ObTabletMeta::init( } else if (OB_UNLIKELY(!ls_id.is_valid()) || OB_UNLIKELY(!tablet_id.is_valid()) || OB_UNLIKELY(!data_tablet_id.is_valid()) - // TODO: fix it after multi source data refactor - // || OB_UNLIKELY(!create_scn.is_valid()) - || OB_UNLIKELY(OB_INVALID_TIMESTAMP == snapshot_version) + //|| OB_UNLIKELY(create_scn <= OB_INVALID_TIMESTAMP) + || OB_UNLIKELY(OB_INVALID_VERSION == snapshot_version) || OB_UNLIKELY(lib::Worker::CompatMode::INVALID == compat_mode)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), K(create_scn), K(snapshot_version), K(compat_mode)); } else if (OB_FAIL(ha_status_.init_status())) { LOG_WARN("failed to init ha status", K(ret)); + } else if (OB_FAIL(transfer_info_.init())) { + LOG_WARN("failed to init transfer info", K(ret)); } else { version_ = TABLET_META_VERSION; ls_id_ = ls_id; tablet_id_ = tablet_id; data_tablet_id_ = data_tablet_id; create_scn_ = create_scn; + create_schema_version_ = create_schema_version; start_scn_ = INIT_CLOG_CHECKPOINT_SCN; clog_checkpoint_scn_ = INIT_CLOG_CHECKPOINT_SCN; - ddl_checkpoint_scn_.set_min(); + ddl_checkpoint_scn_ = INIT_CLOG_CHECKPOINT_SCN; compat_mode_ = compat_mode; snapshot_version_ = snapshot_version; multi_version_start_ = snapshot_version; @@ -116,25 +115,14 @@ int ObTabletMeta::init( ddl_start_scn_.set_min(); ddl_commit_scn_.set_min(); ddl_snapshot_version_ = 0; - max_sync_storage_schema_version_ = max_sync_storage_schema_version; - max_serialized_medium_scn_ = max_serialized_medium_scn; - ddl_execution_id_ = -1; - ddl_data_format_version_ = 0; + max_sync_storage_schema_version_ = create_schema_version; + mds_checkpoint_scn_ = INIT_CLOG_CHECKPOINT_SCN; report_status_.merge_snapshot_version_ = snapshot_version; report_status_.cur_report_version_ = snapshot_version; report_status_.data_checksum_ = 0; report_status_.row_count_ = 0; - ddl_data_.snapshot_version_ = OB_INVALID_VERSION; - ddl_data_.schema_version_ = OB_INVALID_VERSION; - ddl_data_.lob_meta_tablet_id_ = lob_meta_tablet_id; - ddl_data_.lob_piece_tablet_id_ = lob_piece_tablet_id; - - if (tablet_id_.is_ls_inner_tablet()) { - tx_data_.tablet_status_ = ObTabletStatus::NORMAL; - } - is_inited_ = true; } @@ -145,15 +133,10 @@ int ObTabletMeta::init( } int ObTabletMeta::init( - common::ObIAllocator &allocator, const ObTabletMeta &old_tablet_meta, const int64_t snapshot_version, const int64_t multi_version_start, - const ObTabletTxMultiSourceDataUnit &tx_data, - const ObTabletBindingInfo &ddl_data, - const ObTabletAutoincSeq &autoinc_seq, const int64_t max_sync_storage_schema_version, - const int64_t max_serialized_medium_scn, const SCN clog_checkpoint_scn, const ObDDLTableStoreParam &ddl_info) { @@ -166,10 +149,6 @@ int ObTabletMeta::init( || OB_UNLIKELY(OB_INVALID_VERSION == max_sync_storage_schema_version)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(old_tablet_meta), K(max_sync_storage_schema_version)); - } else if (OB_FAIL(ddl_data_.assign(ddl_data))) { - LOG_WARN("failed to assign ddl data", K(ret)); - } else if (OB_FAIL(autoinc_seq_.assign(autoinc_seq))) { - LOG_WARN("failed to assign autoinc seq", K(ret)); } else { version_ = TABLET_META_VERSION; ls_id_ = old_tablet_meta.ls_id_; @@ -177,6 +156,7 @@ int ObTabletMeta::init( data_tablet_id_ = old_tablet_meta.data_tablet_id_; ref_tablet_id_ = old_tablet_meta.ref_tablet_id_; create_scn_ = old_tablet_meta.create_scn_; + create_schema_version_ = old_tablet_meta.create_schema_version_; start_scn_ = old_tablet_meta.start_scn_; ddl_start_scn_ = SCN::max(ddl_info.ddl_start_scn_, old_tablet_meta.ddl_start_scn_); ddl_commit_scn_ = SCN::max(ddl_info.ddl_commit_scn_, old_tablet_meta.ddl_commit_scn_); @@ -187,14 +167,15 @@ int ObTabletMeta::init( snapshot_version_ = MAX(snapshot_version, old_tablet_meta.snapshot_version_); multi_version_start_ = MIN(MAX(multi_version_start, old_tablet_meta.multi_version_start_), snapshot_version_); - tx_data_ = tx_data; table_store_flag_ = old_tablet_meta.table_store_flag_; max_sync_storage_schema_version_ = max_sync_storage_schema_version; - max_serialized_medium_scn_ = max_serialized_medium_scn; + max_serialized_medium_scn_ = 0; // abandoned ddl_checkpoint_scn_ = SCN::max(old_tablet_meta.ddl_checkpoint_scn_, ddl_info.ddl_checkpoint_scn_); ddl_snapshot_version_ = MAX(old_tablet_meta.ddl_snapshot_version_, ddl_info.ddl_snapshot_version_); ddl_execution_id_ = MAX(old_tablet_meta.ddl_execution_id_, ddl_info.ddl_execution_id_); ddl_data_format_version_ = MAX(old_tablet_meta.ddl_data_format_version_, ddl_info.data_format_version_); + mds_checkpoint_scn_ = old_tablet_meta.mds_checkpoint_scn_; + transfer_info_ = old_tablet_meta.transfer_info_; is_inited_ = true; } @@ -205,7 +186,55 @@ int ObTabletMeta::init( } int ObTabletMeta::init( - common::ObIAllocator &allocator, + const ObTabletMeta &old_tablet_meta, + const share::SCN &flush_scn) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!old_tablet_meta.is_valid()) + || OB_UNLIKELY(!flush_scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(old_tablet_meta), K(flush_scn)); + } else { + version_ = TABLET_META_VERSION; + ls_id_ = old_tablet_meta.ls_id_; + tablet_id_ = old_tablet_meta.tablet_id_; + data_tablet_id_ = old_tablet_meta.data_tablet_id_; + ref_tablet_id_ = old_tablet_meta.ref_tablet_id_; + create_scn_ = old_tablet_meta.create_scn_; + create_schema_version_ = old_tablet_meta.create_schema_version_; + start_scn_ = old_tablet_meta.start_scn_; + clog_checkpoint_scn_ = old_tablet_meta.clog_checkpoint_scn_; + ddl_checkpoint_scn_ = old_tablet_meta.ddl_checkpoint_scn_; + snapshot_version_ = old_tablet_meta.snapshot_version_; + multi_version_start_ = old_tablet_meta.multi_version_start_; + compat_mode_ = old_tablet_meta.compat_mode_; + ha_status_ = old_tablet_meta.ha_status_; + report_status_ = old_tablet_meta.report_status_; + table_store_flag_ = old_tablet_meta.table_store_flag_; + ddl_start_scn_ = old_tablet_meta.ddl_start_scn_; + ddl_commit_scn_ = old_tablet_meta.ddl_commit_scn_; + ddl_execution_id_ = old_tablet_meta.ddl_execution_id_; + ddl_data_format_version_ = old_tablet_meta.ddl_data_format_version_; + ddl_snapshot_version_ = old_tablet_meta.ddl_snapshot_version_; + max_sync_storage_schema_version_ = old_tablet_meta.max_sync_storage_schema_version_; + max_serialized_medium_scn_ = old_tablet_meta.max_serialized_medium_scn_; + mds_checkpoint_scn_ = flush_scn; + transfer_info_ = old_tablet_meta.transfer_info_; + is_inited_ = true; + } + + if (OB_UNLIKELY(!is_inited_)) { + reset(); + } + + return ret; +} + +int ObTabletMeta::init( const ObMigrationTabletParam ¶m) { int ret = OB_SUCCESS; @@ -216,12 +245,6 @@ int ObTabletMeta::init( } else if (OB_UNLIKELY(!param.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(param)); - } else if (OB_FAIL(ddl_data_.assign(param.ddl_data_))) { - LOG_WARN("failed to assign ddl data", K(ret)); - } else if (OB_FAIL(autoinc_seq_.assign(param.autoinc_seq_))) { - LOG_WARN("failed to assign autoinc seq", K(ret)); - } else if (OB_FAIL(ha_status_.init_status_for_ha(param.ha_status_))) { - LOG_WARN("failed to init status for ha", K(ret)); } else { version_ = TABLET_META_VERSION; ls_id_ = param.ls_id_; @@ -229,6 +252,7 @@ int ObTabletMeta::init( data_tablet_id_ = param.data_tablet_id_; ref_tablet_id_ = param.ref_tablet_id_; create_scn_ = param.create_scn_; + create_schema_version_ = param.create_schema_version_; start_scn_ = param.start_scn_; clog_checkpoint_scn_ = param.clog_checkpoint_scn_; ddl_checkpoint_scn_ = param.ddl_checkpoint_scn_; @@ -236,15 +260,17 @@ int ObTabletMeta::init( multi_version_start_ = param.multi_version_start_; compat_mode_ = param.compat_mode_; report_status_.reset(); - tx_data_ = param.tx_data_; table_store_flag_ = param.table_store_flag_; ddl_start_scn_ = param.ddl_start_scn_; ddl_commit_scn_ = param.ddl_commit_scn_; ddl_snapshot_version_ = param.ddl_snapshot_version_; max_sync_storage_schema_version_ = param.max_sync_storage_schema_version_; + ha_status_ = param.ha_status_; max_serialized_medium_scn_ = param.max_serialized_medium_scn_; ddl_execution_id_ = param.ddl_execution_id_; ddl_data_format_version_ = param.ddl_data_format_version_; + mds_checkpoint_scn_ = param.mds_checkpoint_scn_; + transfer_info_ = param.transfer_info_; is_inited_ = true; } @@ -266,10 +292,6 @@ int ObTabletMeta::init( } else if (OB_UNLIKELY(!old_tablet_meta.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(old_tablet_meta)); - } else if (OB_FAIL(ddl_data_.assign(old_tablet_meta.ddl_data_))) { - LOG_WARN("failed to assign ddl data", K(ret), K_(old_tablet_meta.ddl_data)); - } else if (OB_FAIL(autoinc_seq_.assign(old_tablet_meta.autoinc_seq_))) { - LOG_WARN("failed to assign autoinc seq", K(ret)); } else { version_ = TABLET_META_VERSION; ls_id_ = old_tablet_meta.ls_id_; @@ -277,6 +299,7 @@ int ObTabletMeta::init( data_tablet_id_ = old_tablet_meta.data_tablet_id_; ref_tablet_id_ = old_tablet_meta.ref_tablet_id_; create_scn_ = old_tablet_meta.create_scn_; + create_schema_version_ = old_tablet_meta.create_schema_version_; start_scn_ = old_tablet_meta.start_scn_; clog_checkpoint_scn_ = old_tablet_meta.clog_checkpoint_scn_; ddl_checkpoint_scn_ = old_tablet_meta.ddl_checkpoint_scn_; @@ -285,7 +308,6 @@ int ObTabletMeta::init( ha_status_ = old_tablet_meta.ha_status_; snapshot_version_ = old_tablet_meta.snapshot_version_; multi_version_start_ = old_tablet_meta.multi_version_start_; - tx_data_ = old_tablet_meta.tx_data_; table_store_flag_ = old_tablet_meta.table_store_flag_; ddl_start_scn_ = old_tablet_meta.ddl_start_scn_; ddl_commit_scn_ = old_tablet_meta.ddl_commit_scn_; @@ -294,6 +316,8 @@ int ObTabletMeta::init( max_serialized_medium_scn_ = old_tablet_meta.max_serialized_medium_scn_; ddl_execution_id_ = old_tablet_meta.ddl_execution_id_; ddl_data_format_version_ = old_tablet_meta.ddl_data_format_version_; + mds_checkpoint_scn_ = old_tablet_meta.mds_checkpoint_scn_; + transfer_info_ = old_tablet_meta.transfer_info_; is_inited_ = true; } @@ -304,11 +328,7 @@ int ObTabletMeta::init( } int ObTabletMeta::init( - common::ObIAllocator &allocator, const ObTabletMeta &old_tablet_meta, - const ObTabletTxMultiSourceDataUnit &tx_data, - const ObTabletBindingInfo &ddl_data, - const share::ObTabletAutoincSeq &autoinc_seq, const ObMigrationTabletParam *tablet_meta) { int ret = OB_SUCCESS; @@ -331,36 +351,23 @@ int ObTabletMeta::init( tablet_meta->max_sync_storage_schema_version_); const SCN clog_checkpoint_scn = OB_ISNULL(tablet_meta) ? old_tablet_meta.clog_checkpoint_scn_ : MAX(old_tablet_meta.clog_checkpoint_scn_, tablet_meta->clog_checkpoint_scn_); + ObTabletTransferInfo transfer_info = old_tablet_meta.transfer_info_; + if (transfer_info.has_transfer_table()) { + transfer_info = OB_ISNULL(tablet_meta) ? old_tablet_meta.transfer_info_ : tablet_meta->transfer_info_; + } ObTabletTableStoreFlag table_store_flag = old_tablet_meta.table_store_flag_; if (!table_store_flag.with_major_sstable()) { table_store_flag = OB_ISNULL(tablet_meta) ? table_store_flag : tablet_meta->table_store_flag_; } - if (OB_NOT_NULL(tablet_meta) && tablet_meta->clog_checkpoint_scn_ > old_tablet_meta.clog_checkpoint_scn_) { - if (OB_FAIL(autoinc_seq_.assign(tablet_meta->autoinc_seq_))) { - LOG_WARN("failed to assign autoinc seq", K(ret)); - } else if (OB_FAIL(ddl_data_.assign(tablet_meta->ddl_data_))) { - LOG_WARN("failed to assign ddl data", K(ret)); - } else { - tx_data_ = tablet_meta->tx_data_; - } - } else { - if (OB_FAIL(autoinc_seq_.assign(autoinc_seq))) { - LOG_WARN("failed to assign autoinc seq", K(ret)); - } else if (OB_FAIL(ddl_data_.assign(ddl_data))) { - LOG_WARN("failed to assign ddl data", K(ret)); - } else { - tx_data_ = tx_data; - } - } - version_ = TABLET_META_VERSION; ls_id_ = old_tablet_meta.ls_id_; tablet_id_ = old_tablet_meta.tablet_id_; data_tablet_id_ = old_tablet_meta.data_tablet_id_; ref_tablet_id_ = old_tablet_meta.ref_tablet_id_; create_scn_ = old_tablet_meta.create_scn_; + create_schema_version_ = old_tablet_meta.create_schema_version_; start_scn_ = old_tablet_meta.start_scn_; clog_checkpoint_scn_ = clog_checkpoint_scn; snapshot_version_ = snapshot_version; @@ -378,6 +385,8 @@ int ObTabletMeta::init( OB_ISNULL(tablet_meta) ? 0 : tablet_meta->max_serialized_medium_scn_); ddl_execution_id_ = old_tablet_meta.ddl_execution_id_; ddl_data_format_version_ = old_tablet_meta.ddl_data_format_version_; + transfer_info_ = transfer_info; + mds_checkpoint_scn_ = old_tablet_meta.mds_checkpoint_scn_; if (OB_SUCC(ret)) { is_inited_ = true; @@ -399,17 +408,15 @@ void ObTabletMeta::reset() ref_tablet_id_.reset(); has_next_tablet_ = false; create_scn_ = ObTabletMeta::INVALID_CREATE_SCN; + create_schema_version_ = 0; start_scn_.reset(); clog_checkpoint_scn_.reset(); ddl_checkpoint_scn_.set_min(); snapshot_version_ = OB_INVALID_TIMESTAMP; multi_version_start_ = OB_INVALID_TIMESTAMP; compat_mode_ = lib::Worker::CompatMode::INVALID; - autoinc_seq_.reset(); ha_status_.reset(); report_status_.reset(); - tx_data_.reset(); - ddl_data_.reset(); table_store_flag_.reset(); ddl_start_scn_.set_min(); ddl_commit_scn_.set_min(); @@ -418,6 +425,8 @@ void ObTabletMeta::reset() max_serialized_medium_scn_ = 0; ddl_execution_id_ = -1; ddl_data_format_version_ = 0; + mds_checkpoint_scn_.reset(); + transfer_info_.reset(); is_inited_ = false; } @@ -430,21 +439,67 @@ bool ObTabletMeta::is_valid() const && create_scn_ != INVALID_CREATE_SCN && multi_version_start_ >= 0 && multi_version_start_ <= snapshot_version_ + && snapshot_version_ >= 0 + && snapshot_version_ != INT64_MAX && compat_mode_ != lib::Worker::CompatMode::INVALID && max_sync_storage_schema_version_ >= 0 && max_serialized_medium_scn_ >= 0 && ha_status_.is_valid() + && transfer_info_.is_valid() && (ha_status_.is_restore_status_pending() || (!ha_status_.is_restore_status_pending() && clog_checkpoint_scn_ >= INIT_CLOG_CHECKPOINT_SCN && start_scn_ >= INIT_CLOG_CHECKPOINT_SCN - && start_scn_ <= clog_checkpoint_scn_)); + && start_scn_ <= clog_checkpoint_scn_)) + && create_schema_version_ >= 0; } -int ObTabletMeta::serialize(char *buf, const int64_t len, int64_t &pos) +int ObTabletMeta::assign(const ObTabletMeta &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + reset(); + version_ = other.version_; + length_ = other.length_; + ls_id_ = other.ls_id_; + tablet_id_ = other.tablet_id_; + data_tablet_id_ = other.data_tablet_id_; + ref_tablet_id_ = other.ref_tablet_id_; + has_next_tablet_ = other.has_next_tablet_; + create_scn_ = other.create_scn_; + create_schema_version_ = other.create_schema_version_; + start_scn_ = other.start_scn_; + clog_checkpoint_scn_ = other.clog_checkpoint_scn_; + ddl_checkpoint_scn_ = other.ddl_checkpoint_scn_; + snapshot_version_ = other.snapshot_version_; + multi_version_start_ = other.multi_version_start_; + compat_mode_ = other.compat_mode_; + ha_status_ = other.ha_status_; + report_status_ = other.report_status_; + + table_store_flag_ = other.table_store_flag_; + ddl_start_scn_ = other.ddl_start_scn_; + ddl_commit_scn_ = other.ddl_commit_scn_; + ddl_snapshot_version_ = other.ddl_snapshot_version_; + max_sync_storage_schema_version_ = other.max_sync_storage_schema_version_; + ddl_execution_id_ = other.ddl_execution_id_; + ddl_data_format_version_ = other.ddl_data_format_version_; + max_serialized_medium_scn_ = other.max_serialized_medium_scn_; + mds_checkpoint_scn_ = other.mds_checkpoint_scn_; + transfer_info_ = other.transfer_info_; + + if (OB_SUCC(ret)) { + is_inited_ = other.is_inited_; + } + } + return ret; +} + +int ObTabletMeta::serialize(char *buf, const int64_t len, int64_t &pos) const { int ret = OB_SUCCESS; int64_t new_pos = pos; + const int64_t length = get_serialize_size(); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -460,68 +515,66 @@ int ObTabletMeta::serialize(char *buf, const int64_t len, int64_t &pos) } else if (TABLET_META_VERSION != version_) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("invalid version", K(ret), K_(version)); - } else if (FALSE_IT(length_ = get_serialize_size())) { - // do nothing - } else if (OB_UNLIKELY(length_ > len - pos)) { + } else if (OB_UNLIKELY(length > len - pos)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("buffer's length is not enough", K(ret), K(length_), K(len - new_pos)); + LOG_WARN("buffer's length is not enough", K(ret), K(length), K(len - new_pos)); } else if (OB_FAIL(serialization::encode_i32(buf, len, new_pos, version_))) { LOG_WARN("failed to serialize tablet meta's version", K(ret), K(len), K(new_pos), K_(version)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_i32(buf, len, new_pos, length_))) { - LOG_WARN("failed to serialize tablet meta's length", K(ret), K(len), K(new_pos), K_(length)); - } else if (new_pos - pos < length_ && OB_FAIL(ls_id_.serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i32(buf, len, new_pos, length))) { + LOG_WARN("failed to serialize tablet meta's length", K(ret), K(len), K(new_pos), K(length)); + } else if (new_pos - pos < length && OB_FAIL(ls_id_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize ls id", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(tablet_id_.serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(tablet_id_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize tablet id", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(data_tablet_id_.serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(data_tablet_id_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize data tablet id", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(ref_tablet_id_.serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(ref_tablet_id_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize ref tablet id", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_bool(buf, len, new_pos, has_next_tablet_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_bool(buf, len, new_pos, has_next_tablet_))) { LOG_WARN("failed to serialize has next tablet", K(ret), K(len), K(new_pos), K_(has_next_tablet)); - } else if (new_pos - pos < length_ && OB_FAIL(create_scn_.fixed_serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(create_scn_.fixed_serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize create scn", K(ret), K(len), K(new_pos), K_(create_scn)); - } else if (new_pos - pos < length_ && OB_FAIL(start_scn_.fixed_serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(start_scn_.fixed_serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize start scn", K(ret), K(len), K(new_pos), K_(start_scn)); - } else if (new_pos - pos < length_ && OB_FAIL(clog_checkpoint_scn_.fixed_serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(clog_checkpoint_scn_.fixed_serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize clog checkpoint ts", K(ret), K(len), K(new_pos), K_(clog_checkpoint_scn)); - } else if (new_pos - pos < length_ && OB_FAIL(ddl_checkpoint_scn_.fixed_serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(ddl_checkpoint_scn_.fixed_serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize ddl checkpoint ts", K(ret), K(len), K(new_pos), K_(ddl_checkpoint_scn)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_i64(buf, len, new_pos, snapshot_version_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, snapshot_version_))) { LOG_WARN("failed to serialize snapshot version", K(ret), K(len), K(new_pos), K_(snapshot_version)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_i64(buf, len, new_pos, multi_version_start_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, multi_version_start_))) { LOG_WARN("failed to serialize multi version start", K(ret), K(len), K(new_pos), K_(multi_version_start)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_i8(buf, len, new_pos, static_cast(compat_mode_)))) { - LOG_WARN("failed to serialize auto inc seq", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(autoinc_seq_.serialize(buf, len, new_pos))) { - LOG_WARN("failed to serialize auto inc seq", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(ha_status_.serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i8(buf, len, new_pos, static_cast(compat_mode_)))) { + LOG_WARN("failed to serialize compat mode", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ha_status_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize ha status", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(report_status_.serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(report_status_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize report status", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(tx_data_.serialize(buf, len, new_pos))) { - LOG_WARN("failed to serialize multi source data", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(ddl_data_.serialize(buf, len, new_pos))) { - LOG_WARN("failed to serialize ddl data", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(table_store_flag_.serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(table_store_flag_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize table store flag", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(ddl_start_scn_.fixed_serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(ddl_start_scn_.fixed_serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize ddl start log ts", K(ret), K(len), K(new_pos), K_(ddl_start_scn)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_snapshot_version_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_snapshot_version_))) { LOG_WARN("failed to serialize ddl snapshot version", K(ret), K(len), K(new_pos), K_(ddl_snapshot_version)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_i64(buf, len, new_pos, max_sync_storage_schema_version_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, max_sync_storage_schema_version_))) { LOG_WARN("failed to serialize max_sync_storage_schema_version", K(ret), K(len), K(new_pos), K_(max_sync_storage_schema_version)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_execution_id_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_execution_id_))) { LOG_WARN("failed to serialize ddl execution id", K(ret), K(len), K(new_pos), K_(ddl_execution_id)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_data_format_version_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_data_format_version_))) { LOG_WARN("failed to serialize ddl data format version", K(ret), K(len), K(new_pos), K_(ddl_data_format_version)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::encode_i64(buf, len, new_pos, max_serialized_medium_scn_))) { - LOG_WARN("failed to serialize max_serialized_medium_scn", K(ret), K(len), K(new_pos), K_(max_serialized_medium_scn)); - } else if (new_pos - pos < length_ && OB_FAIL(ddl_commit_scn_.fixed_serialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, max_serialized_medium_scn_))) { + LOG_WARN("failed to serialize max serialized medium scn", K(ret), K(len), K(new_pos), K_(max_serialized_medium_scn)); + } else if (new_pos - pos < length && OB_FAIL(ddl_commit_scn_.fixed_serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize ddl commit scn", K(ret), K(len), K(new_pos), K_(ddl_commit_scn)); - } else if (OB_UNLIKELY(length_ != new_pos - pos)) { + } else if (new_pos - pos < length && OB_FAIL(mds_checkpoint_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize mds checkpoint ts", K(ret), K(len), K(new_pos), K_(mds_checkpoint_scn)); + } else if (new_pos - pos < length && OB_FAIL(transfer_info_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize transfer info", K(ret), K(len), K(new_pos), K_(transfer_info)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, create_schema_version_))) { + LOG_WARN("failed to serialize create schema version", K(ret), K(len), K(new_pos), K_(create_schema_version)); + } else if (OB_UNLIKELY(length != new_pos - pos)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet meta's length doesn't match standard length", K(ret), K(new_pos), K(pos), K_(length)); + LOG_WARN("tablet meta's length doesn't match standard length", K(ret), K(new_pos), K(pos), K(length), K(length)); } else { pos = new_pos; } @@ -530,7 +583,6 @@ int ObTabletMeta::serialize(char *buf, const int64_t len, int64_t &pos) } int ObTabletMeta::deserialize( - common::ObIAllocator &allocator, const char *buf, const int64_t len, int64_t &pos) @@ -547,9 +599,9 @@ int ObTabletMeta::deserialize( || OB_UNLIKELY(len <= pos)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(buf), K(len), K(pos)); - } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, (int32_t *)&version_))) { + } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, &version_))) { LOG_WARN("failed to deserialize tablet meta's version", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, (int32_t *)&length_))) { + } else if (OB_FAIL(serialization::decode_i32(buf, len, new_pos, &length_))) { LOG_WARN("failed to deserialize tablet meta's length", K(ret), K(len), K(new_pos)); } else if (TABLET_META_VERSION == version_) { int8_t compat_mode = -1; @@ -565,7 +617,7 @@ int ObTabletMeta::deserialize( LOG_WARN("failed to deserialize data tablet id", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(ref_tablet_id_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize ref tablet id", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::decode_bool(buf, len, new_pos, (bool *)&has_next_tablet_))) { + } else if (new_pos - pos < length_ && OB_FAIL(serialization::decode_bool(buf, len, new_pos, &has_next_tablet_))) { LOG_WARN("failed to deserialize has_next_tablet_", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(create_scn_.fixed_deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize create scn", K(ret), K(len), K(new_pos)); @@ -579,18 +631,12 @@ int ObTabletMeta::deserialize( LOG_WARN("failed to deserialize snapshot version", K(ret), K(len)); } else if (new_pos - pos < length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &multi_version_start_))) { LOG_WARN("failed to deserialize multi version start", K(ret), K(len)); - } else if (new_pos - pos < length_ && OB_FAIL(serialization::decode_i8(buf, len, new_pos, (int8_t*)(&compat_mode)))) { + } else if (new_pos - pos < length_ && OB_FAIL(serialization::decode_i8(buf, len, new_pos, &compat_mode))) { LOG_WARN("failed to deserialize compat mode", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(autoinc_seq_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize auto inc seq", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(ha_status_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize restore status", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(report_status_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize report status", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(tx_data_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize multi source data", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length_ && OB_FAIL(ddl_data_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize ddl data", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(table_store_flag_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize table store flag", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(ddl_start_scn_.fixed_deserialize(buf, len, new_pos))) { @@ -604,9 +650,15 @@ int ObTabletMeta::deserialize( } else if (new_pos - pos < length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_data_format_version_))) { LOG_WARN("failed to deserialize ddl data format version", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &max_serialized_medium_scn_))) { - LOG_WARN("failed to deserialize max_serialized_medium_scn", K(ret), K(len), K(new_pos)); + LOG_WARN("failed to deserialize max serialized medium scn", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(ddl_commit_scn_.fixed_deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize ddl commit scn", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(mds_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize mds checkpoint ts", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(transfer_info_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize transfer info", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &create_schema_version_))) { + LOG_WARN("failed to deserialize create schema version", K(ret), K(len)); } else if (OB_UNLIKELY(length_ != new_pos - pos)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K_(length)); @@ -640,11 +692,8 @@ int64_t ObTabletMeta::get_serialize_size() const size += serialization::encoded_length_i64(snapshot_version_); size += serialization::encoded_length_i64(multi_version_start_); size += serialization::encoded_length_i8(static_cast(compat_mode_)); - size += autoinc_seq_.get_serialize_size(); size += ha_status_.get_serialize_size(); size += report_status_.get_serialize_size(); - size += tx_data_.get_serialize_size(); - size += ddl_data_.get_serialize_size(); size += table_store_flag_.get_serialize_size(); size += ddl_start_scn_.get_fixed_serialize_size(); size += serialization::encoded_length_i64(ddl_snapshot_version_); @@ -653,6 +702,9 @@ int64_t ObTabletMeta::get_serialize_size() const size += serialization::encoded_length_i64(ddl_data_format_version_); size += serialization::encoded_length_i64(max_serialized_medium_scn_); size += ddl_commit_scn_.get_fixed_serialize_size(); + size += mds_checkpoint_scn_.get_fixed_serialize_size(); + size += transfer_info_.get_serialize_size(); + size += serialization::encoded_length_i64(create_schema_version_); return size; } @@ -690,6 +742,8 @@ int ObTabletMeta::init_report_info( ObTabletReportStatus &report_status) { int ret = OB_SUCCESS; + blocksstable::ObSSTableMetaHandle sst_meta_hdl; + if (OB_ISNULL(sstable) || !sstable->is_major_sstable() || report_version < 0) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid arguments", K(ret), K(sstable), K(report_version)); @@ -697,86 +751,23 @@ int ObTabletMeta::init_report_info( ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected merge snapshot version", K(ret), K(report_status), KPC(sstable)); } else if (sstable->get_snapshot_version() == report_status.merge_snapshot_version_) { + } else if (OB_FAIL(sstable->get_meta(sst_meta_hdl))) { + SERVER_LOG(WARN, "fail to get sstable meta handle", K(ret)); } else { report_status.reset(); report_status.cur_report_version_ = report_version; report_status.merge_snapshot_version_ = sstable->get_snapshot_version(); - report_status.data_checksum_ = sstable->get_meta().get_basic_meta().data_checksum_; - report_status.row_count_ = sstable->get_meta().get_basic_meta().row_count_; + report_status.data_checksum_ = sst_meta_hdl.get_sstable_meta().get_data_checksum(); + report_status.row_count_ = sst_meta_hdl.get_sstable_meta().get_row_count(); } return ret; } -int ObTabletMeta::update(const ObMigrationTabletParam ¶m) -{ - int ret = OB_SUCCESS; - ObTabletRestoreStatus::STATUS change_status = ObTabletRestoreStatus::RESTORE_STATUS_MAX; - ObTabletRestoreStatus::STATUS current_status = ObTabletRestoreStatus::RESTORE_STATUS_MAX; - bool can_change = false; - - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!param.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(param)); - } else if (OB_FAIL(param.ha_status_.get_restore_status(change_status))) { - LOG_WARN("failed to get restore status", K(ret), K(param)); - } else if (OB_FAIL(ha_status_.get_restore_status(current_status))) { - LOG_WARN("failed to get restore status", K(ret), K(ha_status_)); - } else if (OB_FAIL(ObTabletRestoreStatus::check_can_change_status(current_status, change_status, can_change))) { - LOG_WARN("failed to check can change restore status", K(ret), K(ha_status_), K(change_status), K(param)); - } else if (!can_change) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("can not change restore status", K(ret), K(param), K(ha_status_), K(change_status)); - } else if (OB_FAIL(ha_status_.set_restore_status(change_status))) { - LOG_WARN("failed to set restore status", K(ret), K(param)); - } else if (OB_FAIL(autoinc_seq_.assign(param.autoinc_seq_))) { - LOG_WARN("failed to assign autoinc seq", K(ret), K(param)); - } else { - ls_id_ = param.ls_id_; - tablet_id_ = param.tablet_id_; - data_tablet_id_ = param.data_tablet_id_; - ref_tablet_id_ = param.ref_tablet_id_; - create_scn_ = param.create_scn_; - start_scn_ = param.start_scn_; - clog_checkpoint_scn_ = param.clog_checkpoint_scn_; - ddl_checkpoint_scn_ = param.ddl_checkpoint_scn_; - table_store_flag_ = param.table_store_flag_; - ddl_start_scn_ = param.ddl_start_scn_; - ddl_commit_scn_ = param.ddl_commit_scn_; - ddl_snapshot_version_ = param.ddl_snapshot_version_; - max_sync_storage_schema_version_ = param.max_sync_storage_schema_version_; - max_serialized_medium_scn_ = param.max_serialized_medium_scn_; - ddl_execution_id_ = param.ddl_execution_id_; - ddl_data_format_version_ = param.ddl_data_format_version_; - } - - return ret; -} - SCN ObTabletMeta::get_ddl_sstable_start_scn() const { return ddl_start_scn_.is_valid_and_not_min () ? share::SCN::scn_dec(ddl_start_scn_) : ddl_start_scn_; } -int ObTabletMeta::update_create_scn(const SCN create_scn) -{ - int ret = OB_SUCCESS; - - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(!create_scn.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(create_scn)); - } else { - create_scn_ = create_scn; - } - - return ret; -} - int ObTabletMeta::inner_check_( const ObTabletMeta &old_tablet_meta, const ObMigrationTabletParam *tablet_meta) @@ -786,12 +777,16 @@ int ObTabletMeta::inner_check_( ret = OB_INVALID_ARGUMENT; LOG_WARN("inner check get invalid argument", K(ret), K(old_tablet_meta)); } else if (OB_ISNULL(tablet_meta)) { - //do nohting - } else if (OB_FAIL(old_tablet_meta.ls_id_ != tablet_meta->ls_id_ + //do nothing + } else if (old_tablet_meta.ls_id_ != tablet_meta->ls_id_ || old_tablet_meta.tablet_id_ != tablet_meta->tablet_id_ || old_tablet_meta.data_tablet_id_ != tablet_meta->data_tablet_id_ || old_tablet_meta.ref_tablet_id_ != tablet_meta->ref_tablet_id_ - || old_tablet_meta.compat_mode_ != tablet_meta->compat_mode_)) { + || old_tablet_meta.compat_mode_ != tablet_meta->compat_mode_ + || old_tablet_meta.transfer_info_.transfer_seq_ != tablet_meta->transfer_info_.transfer_seq_) { + //TODO(muwei.ym) Fix it in 4.3 + //1.tablet meta transfer seq < old tablet meta transfer seq should failed. + //2.tablet meta transfer seq > old tablet meta transfer seq should use tablet meta ret = OB_ERR_UNEXPECTED; LOG_WARN("old tablet meta part variable is not same with migration tablet param", K(ret), K(old_tablet_meta), KPC(tablet_meta)); @@ -799,10 +794,32 @@ int ObTabletMeta::inner_check_( return ret; } +bool ObTabletMeta::has_transfer_table() const +{ + return transfer_info_.has_transfer_table(); +} + +int ObTabletMeta::reset_transfer_table() +{ + int ret = OB_SUCCESS; + if (!transfer_info_.has_transfer_table()) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_WARN("logical table should be exist", K(ret), K(transfer_info_)); + } else { + transfer_info_.reset_transfer_table(); + } + return ret; +} + +SCN ObTabletMeta::get_max_replayed_scn() const +{ + return MAX3(clog_checkpoint_scn_, mds_checkpoint_scn_, ddl_checkpoint_scn_); +} ObMigrationTabletParam::ObMigrationTabletParam() : magic_number_(MAGIC_NUM), - version_(PARAM_VERSION), + version_(PARAM_VERSION_V2), + is_empty_shell_(false), ls_id_(), tablet_id_(), data_tablet_id_(), @@ -814,11 +831,8 @@ ObMigrationTabletParam::ObMigrationTabletParam() snapshot_version_(OB_INVALID_TIMESTAMP), multi_version_start_(OB_INVALID_TIMESTAMP), compat_mode_(lib::Worker::CompatMode::INVALID), - autoinc_seq_(), ha_status_(), report_status_(), - tx_data_(), - ddl_data_(), storage_schema_(), medium_info_list_(), table_store_flag_(), @@ -829,30 +843,75 @@ ObMigrationTabletParam::ObMigrationTabletParam() ddl_data_format_version_(0), max_serialized_medium_scn_(0), ddl_commit_scn_(SCN::min_scn()), + mds_checkpoint_scn_(), + mds_data_(), + transfer_info_(), + create_schema_version_(0), allocator_() { } bool ObMigrationTabletParam::is_valid() const { - return MAGIC_NUM == magic_number_ - && PARAM_VERSION == version_ + bool bool_ret = true; + + if (bool_ret) { + bool_ret = MAGIC_NUM == magic_number_ + && PARAM_VERSION_V2 == version_ && ls_id_.is_valid() && tablet_id_.is_valid() && data_tablet_id_.is_valid() - && create_scn_ != ObTabletMeta::INVALID_CREATE_SCN - && multi_version_start_ >= 0 - && multi_version_start_ <= snapshot_version_ - && compat_mode_ != lib::Worker::CompatMode::INVALID - && max_sync_storage_schema_version_ >= 0 - && max_serialized_medium_scn_ >= 0 - && ha_status_.is_valid() + && create_scn_ != ObTabletMeta::INVALID_CREATE_SCN; + if (!bool_ret) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid param", K_(ls_id), K_(tablet_id), K_(data_tablet_id), K_(create_scn), + K_(magic_number), K_(version)); + } + } + + if (bool_ret) { + bool_ret = multi_version_start_ >= 0 + && multi_version_start_ <= snapshot_version_ + && compat_mode_ != lib::Worker::CompatMode::INVALID + && max_sync_storage_schema_version_ >= 0 + && max_serialized_medium_scn_ >= 0; + if (!bool_ret) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid param", K_(multi_version_start), K_(snapshot_version), + K_(compat_mode), K_(max_sync_storage_schema_version), K_(max_serialized_medium_scn), + K_(clog_checkpoint_scn)); + } + } + + if (bool_ret) { + bool_ret = ha_status_.is_valid() + && transfer_info_.is_valid() && (ha_status_.is_restore_status_pending() || (start_scn_ >= SCN::base_scn() && clog_checkpoint_scn_ >= SCN::base_scn() && start_scn_ <= clog_checkpoint_scn_ - && storage_schema_.is_valid() - && medium_info_list_.is_valid())); + && (is_empty_shell() + || (!is_empty_shell() + && storage_schema_.is_valid() + && medium_info_list_.is_valid())))); + // no valid storage_schema_ and medium_info_list_ for empty shell + if (!bool_ret) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid param", K_(ha_status), K_(transfer_info), + K_(start_scn), K_(clog_checkpoint_scn), K_(start_scn), K(is_empty_shell()), + "storage_schema", storage_schema_.is_valid(), + "medium_info_list", medium_info_list_.is_valid()); + } + } + + return bool_ret; +} + +bool ObMigrationTabletParam::is_empty_shell() const +{ + return is_empty_shell_; +} + +SCN ObMigrationTabletParam::get_max_tablet_checkpoint_scn() const +{ + return MAX3(clog_checkpoint_scn_, mds_checkpoint_scn_, ddl_checkpoint_scn_); } int ObMigrationTabletParam::serialize(char *buf, const int64_t len, int64_t &pos) const @@ -879,6 +938,8 @@ int ObMigrationTabletParam::serialize(char *buf, const int64_t len, int64_t &pos LOG_WARN("failed to serialize version", K(ret), K(len), K(new_pos), K_(version)); } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, length))) { LOG_WARN("failed to serialize length", K(ret), K(len), K(new_pos), K(length)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_bool(buf, len, new_pos, is_empty_shell_))) { + LOG_WARN("failed to serialize is empty shell", K(ret), K(len), K(new_pos), K(is_empty_shell_)); } else if (new_pos - pos < length && OB_FAIL(ls_id_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize ls id", K(ret), K(len), K(new_pos), K_(ls_id)); } else if (new_pos - pos < length && OB_FAIL(tablet_id_.serialize(buf, len, new_pos))) { @@ -901,19 +962,13 @@ int ObMigrationTabletParam::serialize(char *buf, const int64_t len, int64_t &pos LOG_WARN("failed to serialize clog checkpoint ts", K(ret), K(len), K(new_pos), K_(multi_version_start)); } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i8(buf, len, new_pos, static_cast(compat_mode_)))) { LOG_WARN("failed to serialize compat mode", K(ret), K(len), K(new_pos), K_(compat_mode)); - } else if (new_pos - pos < length && OB_FAIL(autoinc_seq_.serialize(buf, len, new_pos))) { - LOG_WARN("failed to serialize auto inc seq", K(ret), K(len), K(new_pos), K_(autoinc_seq)); } else if (new_pos - pos < length && OB_FAIL(ha_status_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize ha status", K(ret), K(len), K(new_pos), K_(ha_status)); } else if (new_pos - pos < length && OB_FAIL(report_status_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize report status", K(ret), K(len), K(new_pos), K_(report_status)); - } else if (new_pos - pos < length && OB_FAIL(tx_data_.serialize(buf, len, new_pos))) { - LOG_WARN("failed to serialize multi source data", K(ret), K(len), K(new_pos), K_(tx_data)); - } else if (new_pos - pos < length && OB_FAIL(ddl_data_.serialize(buf, len, new_pos))) { - LOG_WARN("failed to serialize ddl data", K(ret), K(len), K(new_pos), K_(ddl_data)); - } else if (new_pos - pos < length && OB_FAIL(storage_schema_.serialize(buf, len, new_pos))) { + } else if (!is_empty_shell() && new_pos - pos < length && OB_FAIL(storage_schema_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize storage schema", K(ret), K(len), K(new_pos), K_(storage_schema)); - } else if (new_pos - pos < length && OB_FAIL(medium_info_list_.serialize(buf, len, new_pos))) { + } else if (!is_empty_shell() && new_pos - pos < length && OB_FAIL(medium_info_list_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize medium compaction list", K(ret), K(len), K(new_pos), K_(medium_info_list)); } else if (new_pos - pos < length && OB_FAIL(table_store_flag_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize table store flag", K(ret), K(len), K(new_pos), K_(table_store_flag)); @@ -928,9 +983,17 @@ int ObMigrationTabletParam::serialize(char *buf, const int64_t len, int64_t &pos } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_data_format_version_))) { LOG_WARN("failed to serialize ddl data format version", K(ret), K(len), K(new_pos), K_(ddl_data_format_version)); } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, max_serialized_medium_scn_))) { - LOG_WARN("failed to serialize max_serialized_medium_scn", K(ret), K(len), K(new_pos), K_(max_serialized_medium_scn)); + LOG_WARN("failed to serialize max serialized medium scn", K(ret), K(len), K(new_pos), K_(max_serialized_medium_scn)); } else if (new_pos - pos < length && OB_FAIL(ddl_commit_scn_.fixed_serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize ddl commit scn", K(ret), K(len), K(new_pos), K_(ddl_commit_scn)); + } else if (new_pos - pos < length && OB_FAIL(mds_checkpoint_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize mds checkpoint ts", K(ret), K(len), K(new_pos), K_(mds_checkpoint_scn)); + } else if (new_pos - pos < length && OB_FAIL(mds_data_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize mds data", K(ret), K(len), K(new_pos), K_(mds_data)); + } else if (new_pos - pos < length && OB_FAIL(transfer_info_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize transfer info", K(ret), K(len), K(new_pos), K_(transfer_info)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, create_schema_version_))) { + LOG_WARN("failed to serialize create schema version", K(ret), K(len), K(new_pos), K_(create_schema_version)); } else if (OB_UNLIKELY(length != new_pos - pos)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("length doesn't match standard length", K(ret), K(new_pos), K(pos), K(length)); @@ -941,66 +1004,79 @@ int ObMigrationTabletParam::serialize(char *buf, const int64_t len, int64_t &pos return ret; } -// old format compatibility to 4.0, DO NOT add any new member deserialization!!! -int ObMigrationTabletParam::deserialize_old(const char *buf, const int64_t len, int64_t &pos) +int ObMigrationTabletParam::deserialize_v2(const char *buf, const int64_t len, int64_t &pos) { int ret = OB_SUCCESS; + int64_t new_pos = pos; int8_t compat_mode = -1; - ddl_execution_id_ = 0; + int64_t length = 0; - if (OB_FAIL(ls_id_.deserialize(buf, len, new_pos))) { + if (OB_FAIL(serialization::decode_i64(buf, len, new_pos, &length))) { + LOG_WARN("failed to deserialize length", K(ret), K(len), K(new_pos)); + } else if (OB_UNLIKELY(length - 24 > len - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer's length is not enough", K(ret), K(length), K(len - new_pos)); + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_bool(buf, len, new_pos, &is_empty_shell_))) { + LOG_WARN("failed to serialize is empty shell", K(ret), K(len), K(new_pos), K(is_empty_shell_)); + } else if (new_pos - pos < length && OB_FAIL(ls_id_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize ls id", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(tablet_id_.deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(tablet_id_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize tablet id", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(data_tablet_id_.deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(data_tablet_id_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize data tablet id", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(ref_tablet_id_.deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(ref_tablet_id_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize ref tablet id", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(create_scn_.fixed_deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(create_scn_.fixed_deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize create scn", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(start_scn_.fixed_deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(start_scn_.fixed_deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize start scn", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(clog_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(clog_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize clog checkpoint ts", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(ddl_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(ddl_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize ddl checkpoint ts", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(serialization::decode_i64(buf, len, new_pos, &snapshot_version_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &snapshot_version_))) { LOG_WARN("failed to deserialize clog checkpoint ts", K(ret), K(len)); - } else if (OB_FAIL(serialization::decode_i64(buf, len, new_pos, &multi_version_start_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &multi_version_start_))) { LOG_WARN("failed to deserialize clog checkpoint ts", K(ret), K(len)); - } else if (OB_FAIL(serialization::decode_i8(buf, len, new_pos, (int8_t*)(&compat_mode)))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i8(buf, len, new_pos, (int8_t*)(&compat_mode)))) { LOG_WARN("failed to deserialize compat mode", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(autoinc_seq_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize auto inc seq", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(ha_status_.deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(ha_status_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize ha status", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(report_status_.deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(report_status_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize report status", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(tx_data_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize multi source data", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(ddl_data_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize ddl data", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(storage_schema_.deserialize(allocator_, buf, len, new_pos))) { + } else if (!is_empty_shell() && new_pos - pos < length && OB_FAIL(storage_schema_.deserialize(allocator_, buf, len, new_pos))) { LOG_WARN("failed to deserialize storage schema", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(medium_info_list_.deserialize(allocator_, buf, len, new_pos))) { + } else if (!is_empty_shell() && new_pos - pos < length && OB_FAIL(medium_info_list_.deserialize(allocator_, buf, len, new_pos))) { LOG_WARN("failed to deserialize medium compaction list", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(table_store_flag_.deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(table_store_flag_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize table store flag", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(ddl_start_scn_.fixed_deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(ddl_start_scn_.fixed_deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize ddl start log ts", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_snapshot_version_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_snapshot_version_))) { LOG_WARN("failed to deserialize ddl snapshot version", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(serialization::decode_i64(buf, len, new_pos, &max_sync_storage_schema_version_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &max_sync_storage_schema_version_))) { LOG_WARN("failed to deserialize max sync storage schema version", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_execution_id_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_execution_id_))) { LOG_WARN("failed to deserialize ddl execution id", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_data_format_version_))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_data_format_version_))) { LOG_WARN("failed to deserialize ddl data format version", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(ddl_commit_scn_.fixed_deserialize(buf, len, new_pos))) { + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &max_serialized_medium_scn_))) { + LOG_WARN("failed to deserialize max sync medium snapshot", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ddl_commit_scn_.fixed_deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize ddl commit scn", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(mds_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize mds_checkpoint_scn", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(mds_data_.deserialize(allocator_, buf, len, new_pos))) { + LOG_WARN("failed to deserialize mds data", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(transfer_info_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize transfer info", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &create_schema_version_))) { + LOG_WARN("failed to deserialize create schema version", K(ret), K(len)); + } else if (OB_UNLIKELY(length - 16 != new_pos - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K(length), KPC(this)); } else { - // old format compatibility to 4.0, DO NOT add any new member deserialization!!! compat_mode_ = static_cast(compat_mode); pos = new_pos; } @@ -1008,13 +1084,102 @@ int ObMigrationTabletParam::deserialize_old(const char *buf, const int64_t len, return ret; } +int ObMigrationTabletParam::deserialize_v1(const char *buf, const int64_t len, int64_t &pos) +{ + int ret = OB_SUCCESS; + + int64_t new_pos = pos; + int8_t compat_mode = -1; + int64_t length = 0; + ObArenaAllocator allocator("MigDeser"); + ObTabletAutoincSeq auto_inc_seq; + ObTabletTxMultiSourceDataUnit tx_data; + ObTabletBindingInfo ddl_data; + ObTabletMdsData mds_data; + + if (OB_FAIL(serialization::decode_i64(buf, len, new_pos, &length))) { + LOG_WARN("failed to deserialize length", K(ret), K(len), K(new_pos)); + } else if (OB_UNLIKELY(length - 24 > len - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer's length is not enough", K(ret), K(length), K(len - new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ls_id_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ls id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(tablet_id_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize tablet id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(data_tablet_id_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize data tablet id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ref_tablet_id_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ref tablet id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(create_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize create scn", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(start_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize start scn", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(clog_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize clog checkpoint ts", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ddl_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ddl checkpoint ts", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &snapshot_version_))) { + LOG_WARN("failed to deserialize clog checkpoint ts", K(ret), K(len)); + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &multi_version_start_))) { + LOG_WARN("failed to deserialize clog checkpoint ts", K(ret), K(len)); + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i8(buf, len, new_pos, (int8_t*)(&compat_mode)))) { + LOG_WARN("failed to deserialize compat mode", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(auto_inc_seq.deserialize(allocator, buf, len, new_pos))) { + LOG_WARN("failed to deserialize auto inc seq", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ha_status_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ha status", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(report_status_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize report status", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(tx_data.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize multi source data", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ddl_data.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ddl data", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(storage_schema_.deserialize(allocator_, buf, len, new_pos))) { + LOG_WARN("failed to deserialize storage schema", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(medium_info_list_.deserialize(allocator_, buf, len, new_pos))) { + LOG_WARN("failed to deserialize medium compaction list", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(table_store_flag_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize table store flag", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ddl_start_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ddl start log ts", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_snapshot_version_))) { + LOG_WARN("failed to deserialize ddl snapshot version", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &max_sync_storage_schema_version_))) { + LOG_WARN("failed to deserialize max sync storage schema version", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_execution_id_))) { + LOG_WARN("failed to deserialize ddl execution id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_data_format_version_))) { + LOG_WARN("failed to deserialize ddl data format version", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &max_serialized_medium_scn_))) { + LOG_WARN("failed to deserialize max sync medium snapshot", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ddl_commit_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize ddl commit scn", K(ret), K(len), K(new_pos)); + } else if (OB_UNLIKELY(length - 16 != new_pos - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K(length), KPC(this)); + } else if (OB_FAIL(ObTabletMdsData::build_mds_data(allocator, auto_inc_seq, tx_data, create_scn_, ddl_data, + clog_checkpoint_scn_, medium_info_list_, mds_data))) { + LOG_WARN("failed to build mds data with version 1", K(ret), K(auto_inc_seq), K(tx_data), K_(create_scn), + K(ddl_data), K_(clog_checkpoint_scn), K_(medium_info_list)); + } else if (OB_FAIL(mds_data_.init(allocator_, mds_data))) { + LOG_WARN("failed to assign mds data", K(ret), K_(mds_data)); + } else if (OB_FAIL(transfer_info_.init())) { + LOG_WARN("failed to init transfer info", K(ret)); + } else { + is_empty_shell_ = false; + compat_mode_ = static_cast(compat_mode); + version_ = PARAM_VERSION_V2; + pos = new_pos; + } + + return ret; +} + int ObMigrationTabletParam::deserialize(const char *buf, const int64_t len, int64_t &pos) { int ret = OB_SUCCESS; int64_t new_pos = pos; - int8_t compat_mode = -1; - int64_t length = 0; - ddl_execution_id_ = 0; + int64_t length; if (OB_ISNULL(buf) || OB_UNLIKELY(len <= 0) @@ -1027,79 +1192,16 @@ int ObMigrationTabletParam::deserialize(const char *buf, const int64_t len, int6 } else if (MAGIC_NUM == magic_number_) { if (OB_FAIL(serialization::decode_i64(buf, len, new_pos, &version_))) { LOG_WARN("failed to deserialize version", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(serialization::decode_i64(buf, len, new_pos, &length))) { - LOG_WARN("failed to deserialize length", K(ret), K(len), K(new_pos)); - } else if (OB_UNLIKELY(PARAM_VERSION != version_)) { + } else if (PARAM_VERSION != version_ && PARAM_VERSION_V2 != version_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid version", K(ret), K_(version)); - } else if (OB_UNLIKELY(length > len - pos)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("buffer's length is not enough", K(ret), K(length), K(len - new_pos)); - } else if (new_pos - pos < length && OB_FAIL(ls_id_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize ls id", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(tablet_id_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize tablet id", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(data_tablet_id_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize data tablet id", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(ref_tablet_id_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize ref tablet id", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(create_scn_.fixed_deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize create scn", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(start_scn_.fixed_deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize start scn", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(clog_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize clog checkpoint ts", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(ddl_checkpoint_scn_.fixed_deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize ddl checkpoint ts", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &snapshot_version_))) { - LOG_WARN("failed to deserialize clog checkpoint ts", K(ret), K(len)); - } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &multi_version_start_))) { - LOG_WARN("failed to deserialize clog checkpoint ts", K(ret), K(len)); - } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i8(buf, len, new_pos, (int8_t*)(&compat_mode)))) { - LOG_WARN("failed to deserialize compat mode", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(autoinc_seq_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize auto inc seq", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(ha_status_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize ha status", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(report_status_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize report status", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(tx_data_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize multi source data", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(ddl_data_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize ddl data", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(storage_schema_.deserialize(allocator_, buf, len, new_pos))) { - LOG_WARN("failed to deserialize storage schema", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(medium_info_list_.deserialize(allocator_, buf, len, new_pos))) { - LOG_WARN("failed to deserialize medium compaction list", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(table_store_flag_.deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize table store flag", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(ddl_start_scn_.fixed_deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize ddl start log ts", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_snapshot_version_))) { - LOG_WARN("failed to deserialize ddl snapshot version", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &max_sync_storage_schema_version_))) { - LOG_WARN("failed to deserialize max sync storage schema version", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_execution_id_))) { - LOG_WARN("failed to deserialize ddl execution id", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &ddl_data_format_version_))) { - LOG_WARN("failed to deserialize ddl data format version", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &max_serialized_medium_scn_))) { - LOG_WARN("failed to deserialize max sync medium snapshot", K(ret), K(len), K(new_pos)); - } else if (new_pos - pos < length && OB_FAIL(ddl_commit_scn_.fixed_deserialize(buf, len, new_pos))) { - LOG_WARN("failed to deserialize ddl commit scn", K(ret), K(len), K(new_pos)); - } else if (OB_UNLIKELY(length != new_pos - pos)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet's length doesn't match standard length", K(ret), K(new_pos), K(pos), K(length), KPC(this)); + LOG_WARN("invalid param version_", K(ret), K(version_)); + } else if (PARAM_VERSION_V2 == version_ && OB_FAIL(deserialize_v2(buf, len, new_pos))) { + LOG_WARN("failed to deserialize v2", K(ret), K(len), K(new_pos)); + } else if (PARAM_VERSION == version_ && OB_FAIL(deserialize_v1(buf, len, new_pos))) { + LOG_WARN("failed to deserialize v1", K(ret), K(len), K(new_pos)); } else { - compat_mode_ = static_cast(compat_mode); pos = new_pos; } - } else { // old format without length and version - magic_number_ = MAGIC_NUM; - version_ = PARAM_VERSION; - if (OB_FAIL(deserialize_old(buf, len, pos))) { - LOG_WARN("failed to deserialize old format", K(ret), K(len), K(pos)); - } } return ret; @@ -1112,6 +1214,7 @@ int64_t ObMigrationTabletParam::get_serialize_size() const size += serialization::encoded_length_i64(magic_number_); size += serialization::encoded_length_i64(version_); size += serialization::encoded_length_i64(length); + size += serialization::encoded_length_bool(is_empty_shell_); size += ls_id_.get_serialize_size(); size += tablet_id_.get_serialize_size(); size += data_tablet_id_.get_serialize_size(); @@ -1123,13 +1226,10 @@ int64_t ObMigrationTabletParam::get_serialize_size() const size += serialization::encoded_length_i64(snapshot_version_); size += serialization::encoded_length_i64(multi_version_start_); size += serialization::encoded_length_i8(static_cast(compat_mode_)); - size += autoinc_seq_.get_serialize_size(); size += ha_status_.get_serialize_size(); size += report_status_.get_serialize_size(); - size += tx_data_.get_serialize_size(); - size += ddl_data_.get_serialize_size(); - size += storage_schema_.get_serialize_size(); - size += medium_info_list_.get_serialize_size(); + size += is_empty_shell() ? 0 : storage_schema_.get_serialize_size(); + size += is_empty_shell() ? 0 : medium_info_list_.get_serialize_size(); size += table_store_flag_.get_serialize_size(); size += ddl_start_scn_.get_fixed_serialize_size(); size += serialization::encoded_length_i64(ddl_snapshot_version_); @@ -1138,11 +1238,16 @@ int64_t ObMigrationTabletParam::get_serialize_size() const size += serialization::encoded_length_i64(ddl_data_format_version_); size += serialization::encoded_length_i64(max_serialized_medium_scn_); size += ddl_commit_scn_.get_fixed_serialize_size(); + size += mds_checkpoint_scn_.get_fixed_serialize_size(); + size += mds_data_.get_serialize_size(); + size += transfer_info_.get_serialize_size(); + size += serialization::encoded_length_i64(create_schema_version_); return size; } void ObMigrationTabletParam::reset() { + is_empty_shell_ = false; ls_id_.reset(); tablet_id_.reset(); data_tablet_id_.reset(); @@ -1154,11 +1259,8 @@ void ObMigrationTabletParam::reset() snapshot_version_ = OB_INVALID_TIMESTAMP; multi_version_start_ = OB_INVALID_TIMESTAMP; compat_mode_ = lib::Worker::CompatMode::INVALID; - autoinc_seq_.reset(); ha_status_.reset(); report_status_.reset(); - tx_data_.reset(); - ddl_data_.reset(); storage_schema_.reset(); medium_info_list_.reset(); table_store_flag_.reset(); @@ -1169,6 +1271,10 @@ void ObMigrationTabletParam::reset() ddl_data_format_version_ = 0; max_serialized_medium_scn_ = 0; ddl_commit_scn_.set_min(); + mds_checkpoint_scn_.reset(); + mds_data_.reset(); + transfer_info_.reset(); + create_schema_version_ = 0; allocator_.reset(); } @@ -1179,11 +1285,13 @@ int ObMigrationTabletParam::assign(const ObMigrationTabletParam ¶m) ret = OB_INVALID_ARGUMENT; LOG_WARN("migration tablet param is invalid", K(ret), K(param)); } else { + is_empty_shell_ = param.is_empty_shell_; ls_id_ = param.ls_id_; tablet_id_ = param.tablet_id_; data_tablet_id_ = param.data_tablet_id_; ref_tablet_id_ = param.ref_tablet_id_; create_scn_ = param.create_scn_; + create_schema_version_ = param.create_schema_version_; start_scn_ = param.start_scn_; clog_checkpoint_scn_ = param.clog_checkpoint_scn_; ddl_checkpoint_scn_ = param.ddl_checkpoint_scn_; @@ -1192,7 +1300,6 @@ int ObMigrationTabletParam::assign(const ObMigrationTabletParam ¶m) compat_mode_ = param.compat_mode_; ha_status_ = param.ha_status_; report_status_ = param.report_status_; - tx_data_ = param.tx_data_; storage_schema_.reset(); // TODO: refactor? medium_info_list_.reset(); table_store_flag_ = param.table_store_flag_; @@ -1203,24 +1310,70 @@ int ObMigrationTabletParam::assign(const ObMigrationTabletParam ¶m) ddl_execution_id_ = param.ddl_execution_id_; ddl_data_format_version_ = param.ddl_data_format_version_; ddl_commit_scn_ = param.ddl_commit_scn_; + mds_checkpoint_scn_ = param.mds_checkpoint_scn_; + transfer_info_ = param.transfer_info_; - if (OB_FAIL(ddl_data_.assign(param.ddl_data_))) { - LOG_WARN("failed to assign ddl data", K(ret), K(param), K(*this)); - } else if (OB_FAIL(autoinc_seq_.assign(param.autoinc_seq_))) { - LOG_WARN("failed to assign autoinc seq", K(ret), K(param), K(*this)); + if (OB_FAIL(mds_data_.assign(param.mds_data_, allocator_))) { + LOG_WARN("failed to assign mds data", K(ret), K(param)); + } else if (is_empty_shell()) { + // do nothing } else if (OB_FAIL(storage_schema_.init(allocator_, param.storage_schema_))) { LOG_WARN("failed to assign storage schema", K(ret), K(param)); } else if (OB_FAIL(medium_info_list_.init(allocator_, ¶m.medium_info_list_))) { LOG_WARN("failed to assign medium info list", K(ret), K(param)); } + } return ret; } +int ObMigrationTabletParam::build_deleted_tablet_info(const share::ObLSID &ls_id, const ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + if (!ls_id.is_valid() || !tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(ls_id), K(tablet_id)); + } else { + const ObTabletRestoreStatus::STATUS restore_status = ObTabletRestoreStatus::FULL; + const ObTabletDataStatus::STATUS data_status = ObTabletDataStatus::COMPLETE; + const ObTabletExpectedStatus::STATUS expected_status = ObTabletExpectedStatus::DELETED; + ls_id_ = ls_id; + tablet_id_ = tablet_id; + data_tablet_id_ = tablet_id; + create_scn_ = ObTabletMeta::INIT_CREATE_SCN; + create_schema_version_ = 0; + start_scn_ = ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN; + clog_checkpoint_scn_ = ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN; + compat_mode_ = lib::Worker::get_compatibility_mode(); + multi_version_start_ = 0; + snapshot_version_ = 0; + transfer_info_.ls_id_ = ls_id; + transfer_info_.transfer_start_scn_ = SCN::min_scn(); + transfer_info_.transfer_seq_ = 0; + + if (OB_FAIL(ha_status_.set_restore_status(restore_status))) { + LOG_WARN("failed to set restore status", K(ret), K(restore_status)); + } else if (OB_FAIL(ha_status_.set_data_status(data_status))) { + LOG_WARN("failed to set data status", K(ret), K(data_status)); + } else if (OB_FAIL(ha_status_.set_expected_status(expected_status))) { + LOG_WARN("failed to set expected status", K(ret), K(expected_status)); + } else if (OB_FAIL(ObMigrationTabletParam::construct_placeholder_storage_schema_and_medium( + allocator_, + storage_schema_, + medium_info_list_, + mds_data_))) { + LOG_WARN("failed to construct placeholder storage schema"); + } + } + return ret; +} + + int ObMigrationTabletParam::construct_placeholder_storage_schema_and_medium( - ObIAllocator &allocator, + common::ObArenaAllocator &allocator, ObStorageSchema &storage_schema, - compaction::ObMediumCompactionInfoList &medium_info_list) + compaction::ObMediumCompactionInfoList &medium_info_list, + ObTabletFullMemoryMdsData &full_memory_mds_data) { int ret = OB_SUCCESS; storage_schema.reset(); @@ -1229,15 +1382,16 @@ int ObMigrationTabletParam::construct_placeholder_storage_schema_and_medium( storage_schema.rowkey_array_.set_allocator(&allocator); storage_schema.column_array_.set_allocator(&allocator); - storage_schema.storage_schema_version_ = ObStorageSchema::STORAGE_SCHEMA_VERSION; + storage_schema.storage_schema_version_ = ObStorageSchema::STORAGE_SCHEMA_VERSION_V2; storage_schema.is_use_bloomfilter_ = false; storage_schema.table_type_ = ObTableType::USER_TABLE; //storage_schema.table_mode_ storage_schema.index_type_ = ObIndexType::INDEX_TYPE_PRIMARY; storage_schema.index_status_ = ObIndexStatus::INDEX_STATUS_AVAILABLE; storage_schema.row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; - storage_schema.schema_version_ = ObStorageSchema::STORAGE_SCHEMA_VERSION; + storage_schema.schema_version_ = ObStorageSchema::STORAGE_SCHEMA_VERSION_V2; storage_schema.column_cnt_ = 1; + storage_schema.store_column_cnt_ = 1; storage_schema.tablet_size_ = OB_DEFAULT_TABLET_SIZE; storage_schema.pctfree_ = OB_DEFAULT_PCTFREE; storage_schema.block_size_ = OB_DEFAULT_MACRO_BLOCK_SIZE; @@ -1273,6 +1427,10 @@ int ObMigrationTabletParam::construct_placeholder_storage_schema_and_medium( LOG_WARN("failed to init medium info list", K(ret)); } + if (FAILEDx(full_memory_mds_data.init(allocator))) { + LOG_WARN("failed to init full memory mds data", K(ret)); + } + if (OB_SUCC(ret) && OB_UNLIKELY(!storage_schema.is_valid() || !medium_info_list.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("placeholder storage schema or medium info list is not valid", K(ret), K(storage_schema), K(medium_info_list)); diff --git a/src/storage/tablet/ob_tablet_meta.h b/src/storage/tablet/ob_tablet_meta.h index 0eaf4c7fe..1c9d28908 100644 --- a/src/storage/tablet/ob_tablet_meta.h +++ b/src/storage/tablet/ob_tablet_meta.h @@ -29,10 +29,15 @@ #include "storage/ddl/ob_tablet_barrier_log.h" #include "storage/tablet/ob_tablet_binding_helper.h" #include "storage/tablet/ob_tablet_multi_source_data.h" +#include "storage/tablet/ob_tablet_mds_data.h" +#include "storage/tablet/ob_tablet_full_memory_mds_data.h" #include "storage/tx/ob_trans_define.h" #include "storage/high_availability/ob_tablet_ha_status.h" #include "storage/tablet/ob_tablet_table_store_flag.h" #include "share/scn.h" +#include "storage/tablet/ob_tablet_mds_data.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/high_availability/ob_tablet_transfer_info.h" namespace oceanbase { @@ -42,6 +47,7 @@ struct ObMigrationTabletParam; class ObTabletMeta final { + friend class ObTablet; public: static const share::SCN INIT_CLOG_CHECKPOINT_SCN; static const share::SCN INVALID_CREATE_SCN; @@ -53,40 +59,30 @@ public: ObTabletMeta &operator=(const ObTabletMeta &other) = delete; ~ObTabletMeta(); public: + // first init func int init( - common::ObIAllocator &allocator, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, const common::ObTabletID &data_tablet_id, - const common::ObTabletID &lob_meta_tablet_id, - const common::ObTabletID &lob_piece_tablet_id, const share::SCN create_scn, const int64_t snapshot_version, const lib::Worker::CompatMode compat_mode, const ObTabletTableStoreFlag &table_store_flag, - const int64_t max_sync_storage_schema_version, - const int64_t max_serialized_medium_scn); + const int64_t create_schema_version); int init( - common::ObIAllocator &allocator, const ObTabletMeta &old_tablet_meta, const int64_t snapshot_version, const int64_t multi_version_start, - const ObTabletTxMultiSourceDataUnit &tx_data, - const ObTabletBindingInfo &ddl_data, - const share::ObTabletAutoincSeq &autoinc_seq, const int64_t max_sync_storage_schema_version, - const int64_t max_serialized_medium_scn, const share::SCN clog_checkpoint_scn = share::SCN::min_scn(), const ObDDLTableStoreParam &ddl_info = ObDDLTableStoreParam()); int init( - common::ObIAllocator &allocator, + const ObTabletMeta &old_tablet_meta, + const share::SCN &flush_scn); + int init( const ObMigrationTabletParam ¶m); int init( - common::ObIAllocator &allocator, const ObTabletMeta &old_tablet_meta, - const ObTabletTxMultiSourceDataUnit &tx_data, - const ObTabletBindingInfo &ddl_data, - const share::ObTabletAutoincSeq &autoinc_seq, const ObMigrationTabletParam *tablet_meta); int init( common::ObIAllocator &allocator, @@ -95,18 +91,21 @@ public: void reset(); bool is_valid() const; + int assign(const ObTabletMeta &other); // serialize & deserialize - int serialize(char *buf, const int64_t len, int64_t &pos); + int serialize(char *buf, const int64_t len, int64_t &pos) const; int deserialize( - common::ObIAllocator &allocator, const char *buf, const int64_t len, int64_t &pos); int64_t get_serialize_size() const; - - int update(const ObMigrationTabletParam ¶m); - int update_create_scn(const share::SCN create_scn); + int reset_transfer_table(); + bool has_transfer_table() const; share::SCN get_ddl_sstable_start_scn() const; + // Return the max replayed scn which is the max scn among clog_checkpoint_scn, + // mds_checkpoint_scn and ddl_checkpoint_scn. + // Note, if a new type of checkpoint scn is added, donot forget to modify the returned scn. + share::SCN get_max_replayed_scn() const; public: static int deserialize_id( const char *buf, @@ -124,18 +123,16 @@ public: K_(tablet_id), K_(data_tablet_id), K_(ref_tablet_id), + K_(has_next_tablet), K_(create_scn), K_(start_scn), K_(clog_checkpoint_scn), K_(ddl_checkpoint_scn), K_(snapshot_version), K_(multi_version_start), - K_(autoinc_seq), K_(compat_mode), K_(ha_status), K_(report_status), - K_(tx_data), - K_(ddl_data), K_(table_store_flag), K_(ddl_start_scn), K_(ddl_snapshot_version), @@ -143,7 +140,10 @@ public: K_(max_serialized_medium_scn), K_(ddl_execution_id), K_(ddl_data_format_version), - K_(ddl_commit_scn)); + K_(ddl_commit_scn), + K_(mds_checkpoint_scn), + K_(transfer_info), + K_(create_schema_version)); public: int32_t version_; @@ -161,22 +161,23 @@ public: int64_t snapshot_version_; int64_t multi_version_start_; lib::Worker::CompatMode compat_mode_; - share::ObTabletAutoincSeq autoinc_seq_; ObTabletHAStatus ha_status_; ObTabletReportStatus report_status_; - ObTabletTxMultiSourceDataUnit tx_data_; - ObTabletBindingInfo ddl_data_; ObTabletTableStoreFlag table_store_flag_; share::SCN ddl_start_scn_; int64_t ddl_snapshot_version_; // max_sync_storage_schema_version_ = MIN(serialized_schema_version, sync_schema_version) // serialized_schema_version > sync_schema_version when major update storage schema // sync_schema_version > serialized_schema_version when replay schema clog but not mini merge yet + // max_sync_storage_schema_version will be inaccurate after 4.2 int64_t max_sync_storage_schema_version_; int64_t ddl_execution_id_; int64_t ddl_data_format_version_; - int64_t max_serialized_medium_scn_; // update when serialized medium info + int64_t max_serialized_medium_scn_; // abandon after 4.2 share::SCN ddl_commit_scn_; + share::SCN mds_checkpoint_scn_; + ObTabletTransferInfo transfer_info_; + int64_t create_schema_version_; // add after 4.2, record schema_version when first create tablet. NEED COMPAT //ATTENTION : Add a new variable need consider ObMigrationTabletParam // and tablet meta init interface for migration. // yuque : @@ -201,20 +202,29 @@ public: ObMigrationTabletParam &operator=(const ObMigrationTabletParam &) = delete; public: bool is_valid() const; + bool is_empty_shell() const; int serialize(char *buf, const int64_t len, int64_t &pos) const; int deserialize(const char *buf, const int64_t len, int64_t &pos); int64_t get_serialize_size() const; void reset(); int assign(const ObMigrationTabletParam ¶m); + int build_deleted_tablet_info(const share::ObLSID &ls_id, const ObTabletID &tablet_id); + + // Return the max tablet checkpoint scn which is the max scn among clog_checkpoint_scn, + // mds_checkpoint_scn and ddl_checkpoint_scn. + // Note, if a new type of checkpoint scn is added, donot forget to modify the returned scn. + share::SCN get_max_tablet_checkpoint_scn() const; // used for restore PENDING tablet, the placeholder tablet doesn't have storage schema to use static int construct_placeholder_storage_schema_and_medium( - ObIAllocator &allocator, + common::ObArenaAllocator &allocator, ObStorageSchema &storage_schema, - compaction::ObMediumCompactionInfoList &medium_info_list); + compaction::ObMediumCompactionInfoList &medium_info_list, + ObTabletFullMemoryMdsData &full_memory_mds_data); TO_STRING_KV(K_(magic_number), K_(version), + K_(is_empty_shell), K_(ls_id), K_(tablet_id), K_(data_tablet_id), @@ -227,29 +237,35 @@ public: K_(ddl_start_scn), K_(snapshot_version), K_(multi_version_start), - K_(autoinc_seq), K_(compat_mode), K_(ha_status), K_(report_status), - K_(tx_data), - K_(ddl_data), K_(storage_schema), K_(medium_info_list), K_(table_store_flag), K_(max_sync_storage_schema_version), + K_(ddl_execution_id), + K_(ddl_data_format_version), K_(max_serialized_medium_scn), - K_(ddl_commit_scn)); + K_(ddl_commit_scn), + K_(mds_checkpoint_scn), + K_(mds_data), + K_(transfer_info), + K_(create_schema_version)); private: - int deserialize_old(const char *buf, const int64_t len, int64_t &pos); + int deserialize_v2(const char *buf, const int64_t len, int64_t &pos); + int deserialize_v1(const char *buf, const int64_t len, int64_t &pos); // magic_number_ is added to support upgrade from old format(without version and length compatibility) // The old format first member is ls_id_(also 8 bytes long), which is not possible be a negative number. const static int64_t MAGIC_NUM = -20230111; const static int64_t PARAM_VERSION = 1; + const static int64_t PARAM_VERSION_V2 = 2; public: int64_t magic_number_; int64_t version_; + bool is_empty_shell_; share::ObLSID ls_id_; common::ObTabletID tablet_id_; common::ObTabletID data_tablet_id_; @@ -261,13 +277,10 @@ public: int64_t snapshot_version_; int64_t multi_version_start_; lib::Worker::CompatMode compat_mode_; - share::ObTabletAutoincSeq autoinc_seq_; ObTabletHAStatus ha_status_; ObTabletReportStatus report_status_; - ObTabletTxMultiSourceDataUnit tx_data_; - ObTabletBindingInfo ddl_data_; - ObStorageSchema storage_schema_; - compaction::ObMediumCompactionInfoList medium_info_list_; + ObStorageSchema storage_schema_; // not valid for empty shell + compaction::ObMediumCompactionInfoList medium_info_list_; // not valid for empty shell ObTabletTableStoreFlag table_store_flag_; share::SCN ddl_start_scn_; int64_t ddl_snapshot_version_; @@ -277,6 +290,10 @@ public: int64_t ddl_data_format_version_; int64_t max_serialized_medium_scn_; share::SCN ddl_commit_scn_; + share::SCN mds_checkpoint_scn_; + ObTabletFullMemoryMdsData mds_data_; + ObTabletTransferInfo transfer_info_; + int64_t create_schema_version_; // Add new serialization member before this line, below members won't serialize common::ObArenaAllocator allocator_; // for storage schema diff --git a/src/storage/tablet/ob_tablet_multi_source_data.cpp b/src/storage/tablet/ob_tablet_multi_source_data.cpp index b0bdf671d..378e45488 100644 --- a/src/storage/tablet/ob_tablet_multi_source_data.cpp +++ b/src/storage/tablet/ob_tablet_multi_source_data.cpp @@ -30,7 +30,10 @@ ObTabletTxMultiSourceDataUnit::ObTabletTxMultiSourceDataUnit() : version_(TX_DATA_VERSION), length_(0), tx_id_(ObTabletCommon::FINAL_TX_ID), - tablet_status_() + tablet_status_(), + transfer_seq_(0), + transfer_ls_id_(), + transfer_scn_() { tx_scn_.set_max(); } @@ -46,7 +49,10 @@ ObTabletTxMultiSourceDataUnit::ObTabletTxMultiSourceDataUnit(const ObTabletTxMul length_(other.length_), tx_id_(other.tx_id_), tx_scn_(other.tx_scn_), - tablet_status_(other.tablet_status_) + tablet_status_(other.tablet_status_), + transfer_seq_(other.transfer_seq_), + transfer_ls_id_(other.transfer_ls_id_), + transfer_scn_(other.transfer_scn_) { } @@ -59,6 +65,9 @@ ObTabletTxMultiSourceDataUnit &ObTabletTxMultiSourceDataUnit::operator=(const Ob tx_id_ = other.tx_id_; tx_scn_ = other.tx_scn_; tablet_status_ = other.tablet_status_; + transfer_seq_ = other.transfer_seq_; + transfer_ls_id_ = other.transfer_ls_id_; + transfer_scn_ = other.transfer_scn_; } return *this; } @@ -80,6 +89,9 @@ int ObTabletTxMultiSourceDataUnit::deep_copy(const ObIMultiSourceDataUnit *src, tx_id_ = data->tx_id_; tx_scn_ = data->tx_scn_; tablet_status_ = data->tablet_status_; + transfer_seq_ = data->transfer_seq_; + transfer_ls_id_ = data->transfer_ls_id_; + transfer_scn_ = data->transfer_scn_; } return ret; @@ -93,6 +105,9 @@ void ObTabletTxMultiSourceDataUnit::reset() tx_scn_.reset(); tx_scn_.set_max(); tablet_status_ = ObTabletStatus::MAX; + transfer_seq_ = 0; + transfer_ls_id_.reset(); + transfer_scn_.reset(); } int64_t ObTabletTxMultiSourceDataUnit::to_string(char *buf, const int64_t buf_len) const @@ -105,7 +120,10 @@ int64_t ObTabletTxMultiSourceDataUnit::to_string(char *buf, const int64_t buf_le K_(tx_scn), K_(tablet_status), K_(is_tx_end), - K_(unsynced_cnt_for_multi_data)); + K_(unsynced_cnt_for_multi_data), + K_(transfer_seq), + K_(transfer_ls_id), + K_(transfer_scn)); J_OBJ_END(); return pos; } @@ -147,6 +165,12 @@ int ObTabletTxMultiSourceDataUnit::serialize( LOG_WARN("failed to serialize tx scn", K(ret), K(len), K(new_pos), K_(tx_scn)); } else if (OB_FAIL(tablet_status_.serialize(buf, len, new_pos))) { LOG_WARN("failed to serialize tablet status", K(ret), K(len), K(new_pos)); + } else if (OB_FAIL(serialization::encode_i64(buf, len, new_pos, transfer_seq_))) { + LOG_WARN("failed to serialize tx log ts", K(ret), K(len), K(new_pos), K_(transfer_seq)); + } else if (OB_FAIL(transfer_ls_id_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize transfer ls id", K(ret), K(len), K(new_pos), K_(transfer_ls_id)); + } else if (OB_FAIL(transfer_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize transfer scn", K(ret), K(len), K(new_pos), K_(transfer_scn)); } else if (OB_UNLIKELY(pos + length_ != new_pos)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("serialize length does not match member length", K(ret), K(pos), K_(length), K(new_pos)); @@ -181,6 +205,12 @@ int ObTabletTxMultiSourceDataUnit::deserialize( LOG_WARN("failed to deserialize tx scn", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(tablet_status_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize tablet status", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(serialization::decode_i64(buf, len, new_pos, &transfer_seq_))) { + LOG_WARN("failed to deserialize tx log ts", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(transfer_ls_id_.deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize transfer ls id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length_ && OB_FAIL(transfer_scn_.fixed_deserialize(buf, len, new_pos))) { + LOG_WARN("failed to deserialize transfer scn", K(ret), K(len), K(new_pos)); } } @@ -203,6 +233,9 @@ int64_t ObTabletTxMultiSourceDataUnit::get_serialize_size() const size += tx_id_.get_serialize_size(); size += tx_scn_.get_fixed_serialize_size(); size += tablet_status_.get_serialize_size(); + size += serialization::encoded_length_i64(transfer_seq_); + size += transfer_ls_id_.get_serialize_size(); + size += transfer_scn_.get_fixed_serialize_size(); return size; } diff --git a/src/storage/tablet/ob_tablet_multi_source_data.h b/src/storage/tablet/ob_tablet_multi_source_data.h index d1fc9a212..e147cd4d3 100644 --- a/src/storage/tablet/ob_tablet_multi_source_data.h +++ b/src/storage/tablet/ob_tablet_multi_source_data.h @@ -52,6 +52,9 @@ public: transaction::ObTransID tx_id_; share::SCN tx_scn_; ObTabletStatus tablet_status_; + int64_t transfer_seq_; + share::ObLSID transfer_ls_id_; + share::SCN transfer_scn_; private: static const int32_t TX_DATA_VERSION = 1; }; diff --git a/src/storage/tablet/ob_tablet_obj_load_helper.cpp b/src/storage/tablet/ob_tablet_obj_load_helper.cpp new file mode 100644 index 000000000..69fb6f605 --- /dev/null +++ b/src/storage/tablet/ob_tablet_obj_load_helper.cpp @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_obj_load_helper.h" +#include "lib/allocator/page_arena.h" +#include "storage/blockstore/ob_shared_block_reader_writer.h" +#include "storage/meta_mem/ob_meta_obj_struct.h" + +#define USING_LOG_PREFIX STORAGE + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ +int ObTabletObjLoadHelper::read_from_addr( + common::ObArenaAllocator &allocator, + const ObMetaDiskAddr &meta_addr, + char *&buf, + int64_t &buf_len) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!meta_addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(meta_addr)); + } else if (OB_UNLIKELY(!meta_addr.is_block())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("the meta disk address type is not supported", K(ret), K(meta_addr)); + } else { + ObSharedBlockReadInfo read_info; + read_info.addr_ = meta_addr; + read_info.io_desc_.set_mode(ObIOMode::READ); + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_DATA_READ); + + ObSharedBlockReadHandle io_handle; + if (OB_FAIL(ObSharedBlockReaderWriter::async_read(read_info, io_handle))) { + LOG_WARN("fail to async read", K(ret), K(read_info)); + } else if (OB_FAIL(io_handle.wait())) { + LOG_WARN("fail to wait io_hanlde", K(ret), K(read_info)); + } else if (OB_FAIL(io_handle.get_data(allocator, buf, buf_len))) { + LOG_WARN("fail to get data", K(ret), K(read_info)); + } + } + return ret; +} +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_obj_load_helper.h b/src/storage/tablet/ob_tablet_obj_load_helper.h new file mode 100644 index 000000000..7feaa5eab --- /dev/null +++ b/src/storage/tablet/ob_tablet_obj_load_helper.h @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_OBJ_LOAD_HELPER +#define OCEANBASE_STORAGE_OB_TABLET_OBJ_LOAD_HELPER + +#include +#include "lib/ob_errno.h" +#include "lib/allocator/ob_allocator.h" +#include "lib/oblog/ob_log.h" + +namespace oceanbase +{ +namespace common +{ +class ObArenaAllocator; +} + +namespace storage +{ +class ObMetaDiskAddr; + +class ObTabletObjLoadHelper +{ +public: + template + static int alloc_and_new(common::ObIAllocator &allocator, T *&ptr); + + static int read_from_addr( + common::ObArenaAllocator &allocator, + const ObMetaDiskAddr &meta_addr, + char *&buf, + int64_t &buf_len); +}; + +template +int ObTabletObjLoadHelper::alloc_and_new(common::ObIAllocator &allocator, T *&ptr) +{ + int ret = common::OB_SUCCESS; + void *buffer = allocator.alloc(sizeof(T)); + + if (OB_ISNULL(buffer)) { + ret = common::OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "fail to allocate memory", K(ret), "size", sizeof(T)); + } else { + ptr = new (buffer) T(); + } + + return ret; +} +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_OBJ_LOAD_HELPER diff --git a/src/storage/tablet/ob_tablet_persister.cpp b/src/storage/tablet/ob_tablet_persister.cpp new file mode 100644 index 000000000..7314484ce --- /dev/null +++ b/src/storage/tablet/ob_tablet_persister.cpp @@ -0,0 +1,806 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "storage/tablet/ob_tablet_persister.h" +#include "storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/tablet/ob_tablet_obj_load_helper.h" + +using namespace std::placeholders; +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace storage +{ + +ObTabletTransformArg::ObTabletTransformArg() + : auto_inc_seq_ptr_(nullptr), + rowkey_read_info_ptr_(nullptr), + tablet_meta_(), + table_store_addr_(), + storage_schema_addr_(), + tablet_status_uncommitted_kv_addr_(), + tablet_status_committed_kv_addr_(), + aux_tablet_info_uncommitted_kv_addr_(), + aux_tablet_info_committed_kv_addr_(), + extra_medium_info_(), + medium_info_list_addr_(), + auto_inc_seq_addr_(), + tablet_status_cache_(), + aux_tablet_info_cache_() +{ +} + +ObTabletTransformArg::~ObTabletTransformArg() +{ + reset(); +} + +void ObTabletTransformArg::reset() +{ + auto_inc_seq_ptr_ = nullptr; + rowkey_read_info_ptr_ = nullptr; + tablet_meta_.reset(); + table_store_addr_.reset(); + storage_schema_addr_.reset(); + tablet_status_uncommitted_kv_addr_.reset(); + tablet_status_committed_kv_addr_.reset(); + aux_tablet_info_uncommitted_kv_addr_.reset(); + aux_tablet_info_committed_kv_addr_.reset(); + extra_medium_info_.reset(); + medium_info_list_addr_.reset(); + auto_inc_seq_addr_.reset(); + tablet_status_cache_.reset(); + aux_tablet_info_cache_.reset(); +} + +bool ObTabletTransformArg::is_valid() const +{ + return nullptr != auto_inc_seq_ptr_ + && table_store_addr_.is_none() ^ (nullptr != rowkey_read_info_ptr_) + && tablet_meta_.is_valid() + && table_store_addr_.is_valid() + && storage_schema_addr_.is_valid() + && tablet_status_uncommitted_kv_addr_.is_valid() + && tablet_status_committed_kv_addr_.is_valid() + && aux_tablet_info_uncommitted_kv_addr_.is_valid() + && aux_tablet_info_committed_kv_addr_.is_valid() + && auto_inc_seq_addr_.is_valid() + && medium_info_list_addr_.is_valid(); +} + +int ObTabletPersister::persist_and_transform_tablet( + const ObTablet &old_tablet, + ObTabletHandle &new_handle) +{ + int ret = OB_SUCCESS; + common::ObArenaAllocator allocator; + common::ObSEArray tablet_meta_write_ctxs; + common::ObSEArray sstable_meta_write_ctxs; + + if (OB_UNLIKELY(!old_tablet.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid old tablet to persist", K(ret), K(old_tablet)); + } else if (OB_FAIL(recursively_persist( + old_tablet, allocator, tablet_meta_write_ctxs, sstable_meta_write_ctxs, new_handle))) { + LOG_WARN("fail to recursively persist and fill tablet", K(ret), K(old_tablet)); + } else if (OB_FAIL(check_tablet_meta_ids(tablet_meta_write_ctxs, *(new_handle.get_obj())))) { + LOG_WARN("fail to check whether tablet meta's macro ids match", K(ret), K(tablet_meta_write_ctxs), KPC(new_handle.get_obj())); + } else if (OB_FAIL(persist_4k_tablet(allocator, new_handle))) { + LOG_WARN("fail to persist 4k tablet", K(ret), K(new_handle), KPC(new_handle.get_obj())); + } else { + FLOG_INFO("succeed to persist 4k tablet", K(&old_tablet), K(new_handle.get_obj())); + } + return ret; +} + +int ObTabletPersister::recursively_persist( + const ObTablet &old_tablet, + common::ObArenaAllocator &allocator, + common::ObIArray &tablet_meta_write_ctxs, + common::ObIArray &sstable_meta_write_ctxs, + ObTabletHandle &new_handle) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(persist_and_fill_tablet( + old_tablet, allocator, tablet_meta_write_ctxs, sstable_meta_write_ctxs, new_handle))) { + LOG_WARN("fail to persist and fill tablet", K(ret), K(old_tablet)); + } else if (old_tablet.get_tablet_meta().has_next_tablet_) { + ObTabletHandle new_next_handle; + const ObTablet &old_next_tablet = *(old_tablet.get_next_tablet_guard().get_obj()); + if (OB_FAIL(recursively_persist( + old_next_tablet, allocator, tablet_meta_write_ctxs, sstable_meta_write_ctxs, new_next_handle))) { + LOG_WARN("fail to recursively persist and fill next tablet", + K(ret), K(old_next_tablet), K(tablet_meta_write_ctxs), K(sstable_meta_write_ctxs)); + } else { + new_handle.get_obj()->set_next_tablet_guard(new_next_handle); + } + } + return ret; +} + +int ObTabletPersister::convert_tablet_to_mem_arg( + const ObTablet &tablet, + ObTabletMemberWrapper &auto_inc_seq, + ObTabletTransformArg &arg) +{ + int ret = OB_SUCCESS; + arg.reset(); + if (OB_UNLIKELY(!tablet.is_valid())) { + ret = OB_NOT_INIT; + LOG_WARN("old tablet isn't valid, don't allow to degrade tablet memory", K(ret), K(tablet)); + } else if (OB_FAIL(arg.tablet_status_cache_.assign(tablet.mds_data_.tablet_status_cache_))) { + LOG_WARN("fail to assign tablet status cache", K(ret), K(tablet)); + } else if (OB_FAIL(arg.aux_tablet_info_cache_.assign(tablet.mds_data_.aux_tablet_info_cache_))) { + LOG_WARN("fail to assign aux tablet info cache", K(ret), K(tablet)); + } else if (OB_FAIL(arg.tablet_meta_.assign(tablet.tablet_meta_))) { + LOG_WARN("fail to assign tablet meta", K(ret), K(tablet)); + } else if (OB_FAIL(tablet.fetch_autoinc_seq(auto_inc_seq))) { + LOG_WARN("fail to fetch autoinc seq", K(ret), K(tablet)); + } else { + arg.auto_inc_seq_ptr_ = auto_inc_seq.get_member(); + arg.rowkey_read_info_ptr_ = tablet.rowkey_read_info_; + arg.table_store_addr_ = tablet.table_store_addr_.addr_; + arg.storage_schema_addr_ = tablet.storage_schema_addr_.addr_; + arg.tablet_status_uncommitted_kv_addr_ = tablet.mds_data_.tablet_status_.uncommitted_kv_.addr_; + arg.tablet_status_committed_kv_addr_ = tablet.mds_data_.tablet_status_.committed_kv_.addr_; + arg.aux_tablet_info_uncommitted_kv_addr_ = tablet.mds_data_.aux_tablet_info_.uncommitted_kv_.addr_; + arg.aux_tablet_info_committed_kv_addr_ = tablet.mds_data_.aux_tablet_info_.committed_kv_.addr_; + arg.extra_medium_info_ = tablet.mds_data_.extra_medium_info_; + arg.medium_info_list_addr_ = tablet.mds_data_.medium_info_list_.addr_; + arg.auto_inc_seq_addr_ = tablet.mds_data_.auto_inc_seq_.addr_; + } + return ret; +} +int ObTabletPersister::convert_tablet_to_disk_arg( + common::ObArenaAllocator &allocator, + const ObTablet &tablet, + common::ObIArray &tablet_meta_write_ctxs, + common::ObIArray &sstable_meta_write_ctxs, + ObTabletPoolType &type, + ObTabletMemberWrapper &auto_inc_seq, + ObTabletTransformArg &arg) +{ + int ret = OB_SUCCESS; + arg.reset(); + + common::ObSEArray write_infos; + // fetch member wrapper + ObTabletMemberWrapper table_store; + // fetch member function + FetchTableStore fetch_table_store = + std::bind(&ObTablet::fetch_table_store, &tablet, _1); + FetchAutoincSeq fetch_auto_inc_seq = + std::bind(&ObTabletMdsData::fetch_auto_inc_seq, std::cref(tablet.mds_data_.auto_inc_seq_), _1); + + // load member + const ObStorageSchema *storage_schema = nullptr; + // load member function + LoadStorageSchema load_storage_schema = + std::bind(&ObTablet::load_storage_schema, &tablet, _1, _2); + + // load new mds data + const ObTabletComplexAddr &uncommitted_tablet_status_addr = tablet.mds_data_.tablet_status_.uncommitted_kv_; + const ObTabletComplexAddr &committed_tablet_status_addr = tablet.mds_data_.tablet_status_.committed_kv_; + const ObTabletComplexAddr &uncommitted_aux_tablet_info_addr = tablet.mds_data_.aux_tablet_info_.uncommitted_kv_; + const ObTabletComplexAddr &committed_aux_tablet_info_addr = tablet.mds_data_.aux_tablet_info_.committed_kv_; + const ObTabletComplexAddr &medium_info_list_addr = tablet.mds_data_.medium_info_list_; + + if (OB_FAIL(arg.tablet_status_cache_.assign(tablet.mds_data_.tablet_status_cache_))) { + LOG_WARN("fail to assign tablet status cache", K(ret), K(tablet)); + } else if (OB_FAIL(arg.aux_tablet_info_cache_.assign(tablet.mds_data_.aux_tablet_info_cache_))) { + LOG_WARN("fail to assign aux tablet info cache", K(ret), K(tablet)); + } else if (OB_FAIL(arg.tablet_meta_.assign(tablet.tablet_meta_))) { + LOG_WARN("fail to assign tablet meta", K(ret), K(tablet)); + } else if (FALSE_IT(arg.rowkey_read_info_ptr_ = tablet.rowkey_read_info_)) { + } else if (FALSE_IT(arg.extra_medium_info_ = tablet.mds_data_.extra_medium_info_)) { + } else if (OB_FAIL(fetch_wrapper_and_write_info(allocator, fetch_table_store, table_store, write_infos, sstable_meta_write_ctxs))) { + LOG_WARN("fail to fetch table store wrapper and write info", K(ret)); + } else if (OB_FAIL(fetch_wrapper_and_write_info( + allocator, fetch_auto_inc_seq, auto_inc_seq, write_infos, tablet_meta_write_ctxs))) { + LOG_WARN("fail to fetch auto inc seq wrapper and write info", K(ret)); + } else if (FALSE_IT(arg.auto_inc_seq_ptr_ = auto_inc_seq.get_member())) { + } else if (OB_FAIL(load_member_and_write_info( + allocator, load_storage_schema, storage_schema, write_infos))) { + LOG_WARN("fail to load storage schema and write info", K(ret)); + } else if (OB_FAIL(load_dump_kv_and_fill_write_info(allocator, uncommitted_tablet_status_addr, write_infos))) { + LOG_WARN("fail to load tablet status uncommitted kv", K(ret), K(uncommitted_tablet_status_addr)); + } else if (OB_FAIL(load_dump_kv_and_fill_write_info(allocator, committed_tablet_status_addr, write_infos))) { + LOG_WARN("fail to load tablet status committed kv", K(ret), K(committed_tablet_status_addr)); + } else if (OB_FAIL(load_dump_kv_and_fill_write_info(allocator, uncommitted_aux_tablet_info_addr, write_infos))) { + LOG_WARN("fail to load aux tablet info uncommitted kv", K(ret), K(uncommitted_aux_tablet_info_addr)); + } else if (OB_FAIL(load_dump_kv_and_fill_write_info(allocator, committed_aux_tablet_info_addr, write_infos))) { + LOG_WARN("fail to load aux tablet info committed kv", K(ret), K(committed_aux_tablet_info_addr)); + } else if (OB_FAIL(write_and_fill_args(write_infos, arg, tablet_meta_write_ctxs))) { + LOG_WARN("fail to write and fill address", K(ret), K(write_infos), K(auto_inc_seq)); + } else if (OB_FAIL(load_medium_info_list_and_write(allocator, medium_info_list_addr, arg.medium_info_list_addr_, tablet_meta_write_ctxs))) { + LOG_WARN("fail to load medium info list and write", K(ret), K(medium_info_list_addr)); + } else { + const int64_t try_cache_size = sizeof(ObTablet) + + tablet.rowkey_read_info_->get_deep_copy_size() + + table_store.get_member()->get_deep_copy_size(); + if (try_cache_size > ObTenantMetaMemMgr::NORMAL_TABLET_POOL_SIZE) { + type = ObTabletPoolType::TP_LARGE; + } + } + ObTablet::free_storage_schema(allocator, storage_schema); + + return ret; +} + +int ObTabletPersister::persist_and_fill_tablet( + const ObTablet &old_tablet, + common::ObArenaAllocator &allocator, + common::ObIArray &tablet_meta_write_ctxs, + common::ObIArray &sstable_meta_write_ctxs, + ObTabletHandle &new_handle) +{ + int ret = OB_SUCCESS; + common::ObSEArray write_infos; + ObTabletTransformArg arg; + + const ObTabletMeta &tablet_meta = old_tablet.get_tablet_meta(); + const ObTabletMapKey key(tablet_meta.ls_id_, tablet_meta.tablet_id_); + ObTabletPoolType type = ObTabletPoolType::TP_NORMAL; + ObTabletMemberWrapper auto_inc_seq; + bool try_smaller_pool = true; + + if (old_tablet.is_empty_shell()) { + if (OB_FAIL(convert_tablet_to_mem_arg(old_tablet, auto_inc_seq, arg))) { + LOG_WARN("fail to conver tablet to mem arg", K(ret), K(old_tablet)); + } + } else if (OB_FAIL(convert_tablet_to_disk_arg( + allocator, old_tablet, tablet_meta_write_ctxs, sstable_meta_write_ctxs, type, auto_inc_seq, arg))) { + LOG_WARN("fail to conver tablet to disk arg", K(ret), K(old_tablet)); + } else if (sizeof(old_tablet) + old_tablet.rowkey_read_info_->get_deep_copy_size() > ObTenantMetaMemMgr::NORMAL_TABLET_POOL_SIZE) { + try_smaller_pool = false; + } + + if (FAILEDx(acquire_tablet(type, key, try_smaller_pool, new_handle))) { + LOG_WARN("fail to acquire tablet", K(ret), K(key), K(type)); + } else if (OB_FAIL(transform(arg, new_handle.get_buf(), new_handle.get_buf_len()))) { + LOG_WARN("fail to transform old tablet", K(ret), K(arg), K(new_handle), K(type)); + } + + return ret; +} + +int ObTabletPersister::check_tablet_meta_ids( + const common::ObIArray &tablet_meta_write_ctxs, + const ObTablet &tablet) +{ + int ret = OB_SUCCESS; + ObSArray meta_ids; + ObSArray ctx_ids; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_meta_write_ctxs.count(); i++) { + if (OB_FAIL(ObTablet::parse_meta_addr(tablet_meta_write_ctxs.at(i).addr_, ctx_ids))) { + LOG_WARN("fail to parse meta addr", K(ret), K(tablet_meta_write_ctxs.at(i).addr_)); + } + } + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(tablet.get_tablet_meta_ids(meta_ids))) { + LOG_WARN("fail to get tablet meta ids", K(ret), K(tablet)); + } else if (meta_ids.count() != ctx_ids.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet meta's macro ids don't match", K(ret), K(meta_ids.count()), K(ctx_ids.count())); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < ctx_ids.count(); i++) { + for (int64_t j = 0; OB_SUCC(ret) && j < meta_ids.count(); j++) { + if (meta_ids.at(j) == ctx_ids.at(i)) { + if (OB_FAIL(meta_ids.remove(j))) { + LOG_WARN("fail to remove id from array", K(ret), K(ctx_ids.at(i))); + } else { + break; + } + } + if (OB_SUCC(ret) && j == meta_ids.count() - 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet meta's macro ids don't match", K(ret), K(ctx_ids.at(i))); + } + } + } + } + return ret; +} + +int ObTabletPersister::acquire_tablet( + const ObTabletPoolType &type, + const ObTabletMapKey &key, + const bool try_smaller_pool, + ObTabletHandle &new_handle) +{ + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + if (OB_FAIL(t3m->acquire_tablet_from_pool(type, WashTabletPriority::WTP_HIGH, key, new_handle))) { + if (OB_ENTRY_NOT_EXIST == ret) { + } else if (ObTabletPoolType::TP_LARGE == type + && try_smaller_pool + && OB_SUCC(t3m->acquire_tablet_from_pool(ObTabletPoolType::TP_NORMAL, WashTabletPriority::WTP_HIGH, key, new_handle))) { + } else if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to acquire tablet from pool", K(ret), K(key), K(type)); + } + } + + if (OB_SUCC(ret) && OB_ISNULL(new_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("new tablet is null", K(ret), K(new_handle)); + } + return ret; +} + +int ObTabletPersister::persist_4k_tablet(common::ObArenaAllocator &allocator, ObTabletHandle &new_handle) +{ + int ret = OB_SUCCESS; + ObTablet *new_tablet = new_handle.get_obj(); + ObTenantCheckpointSlogHandler *ckpt_slog_hanlder = MTL(ObTenantCheckpointSlogHandler*); + common::ObSEArray write_infos; + ObSharedBlockWriteHandle handle; + ObSharedBlocksWriteCtx write_ctx; + if (OB_FAIL(fill_write_info(allocator, new_tablet, write_infos))) { + LOG_WARN("fail to fill write info", K(ret), KPC(new_tablet)); + } else if (OB_ISNULL(ckpt_slog_hanlder)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, ckpt slog handler is nullptr", K(ret), KP(ckpt_slog_hanlder)); + } else if (OB_FAIL(ckpt_slog_hanlder->get_shared_block_reader_writer().async_write(write_infos.at(0), handle))) { + LOG_WARN("fail to async write", K(ret), K(write_infos)); + } else if (OB_FAIL(handle.get_write_ctx(write_ctx))) { + LOG_WARN("fail to batch get address", K(ret), K(handle)); + } else if (FALSE_IT(new_tablet->set_tablet_addr(write_ctx.addr_))) { + } else if (OB_FAIL(new_tablet->inc_macro_ref_cnt())) { + LOG_WARN("fail to increase macro ref cnt for new tablet", K(ret), KPC(new_tablet)); + } + return ret; +} + +int ObTabletPersister::convert_arg_to_tablet( + const ObTabletTransformArg &arg, + ObTablet &tablet) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(arg)); + } else if (OB_FAIL(tablet.tablet_meta_.assign(arg.tablet_meta_))) { + LOG_WARN("fail to assign tablet meta", K(ret), K(arg.tablet_meta_)); + } else if (OB_FAIL(tablet.pull_memtables())) { + LOG_WARN("fail to build memtables", K(ret), K(tablet)); + } else if (OB_FAIL(tablet.mds_data_.tablet_status_cache_.assign(arg.tablet_status_cache_))) { + LOG_WARN("fail to assign tablet status cache", K(ret), K(arg.aux_tablet_info_cache_)); + } else if (OB_FAIL(tablet.mds_data_.aux_tablet_info_cache_.assign(arg.aux_tablet_info_cache_))) { + LOG_WARN("fail to assign aux tablet info cache", K(ret), K(arg.aux_tablet_info_cache_)); + } else { + tablet.table_store_addr_.addr_ = arg.table_store_addr_; + tablet.storage_schema_addr_.addr_ = arg.storage_schema_addr_; + tablet.mds_data_.tablet_status_.uncommitted_kv_.addr_ = arg.tablet_status_uncommitted_kv_addr_; + tablet.mds_data_.tablet_status_.committed_kv_.addr_ = arg.tablet_status_committed_kv_addr_; + tablet.mds_data_.aux_tablet_info_.uncommitted_kv_.addr_ = arg.aux_tablet_info_uncommitted_kv_addr_; + tablet.mds_data_.aux_tablet_info_.committed_kv_.addr_ = arg.aux_tablet_info_committed_kv_addr_; + tablet.mds_data_.extra_medium_info_.info_ = arg.extra_medium_info_.info_; + tablet.mds_data_.extra_medium_info_.last_medium_scn_ = arg.extra_medium_info_.last_medium_scn_; + tablet.mds_data_.medium_info_list_.addr_ = arg.medium_info_list_addr_; + tablet.mds_data_.auto_inc_seq_.addr_ = arg.auto_inc_seq_addr_; + tablet.mds_data_.is_inited_ = true; + } + return ret; +} + +int ObTabletPersister::transform( + const ObTabletTransformArg &arg, + char *buf, + const int64_t len) +{ + int ret = OB_SUCCESS; + ObTablet *tiny_tablet = reinterpret_cast(buf); + if (len <= sizeof(ObTablet) || OB_ISNULL(buf)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(buf), K(len)); + } else if (OB_FAIL(convert_arg_to_tablet(arg, *tiny_tablet))) { + LOG_WARN("fail to convert arg to tablet", K(ret), K(arg.tablet_meta_)); + } else { + // buf related + int64_t start_pos = sizeof(ObTablet); + int64_t remain = len - start_pos; + common::ObArenaAllocator allocator("Transform"); + + LOG_DEBUG("TINY TABLET: tablet", KP(buf), K(start_pos), K(remain)); + // rowkey read info related + int64_t rowkey_read_info_size = 0; + if (OB_SUCC(ret) && OB_NOT_NULL(arg.rowkey_read_info_ptr_)) { + rowkey_read_info_size = arg.rowkey_read_info_ptr_->get_deep_copy_size(); + if (OB_UNLIKELY(remain < rowkey_read_info_size)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet memory buffer not enough for rowkey read info", K(ret), K(remain), K(rowkey_read_info_size)); + } else if (OB_FAIL(arg.rowkey_read_info_ptr_->deep_copy( + buf + start_pos, remain, tiny_tablet->rowkey_read_info_))) { + LOG_WARN("fail to deep copy rowkey read info to tablet", K(ret), KPC(arg.rowkey_read_info_ptr_)); + } else if (OB_ISNULL(tiny_tablet->rowkey_read_info_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr for rowkey read info deep copy", K(ret)); + } else { + remain -= rowkey_read_info_size; + start_pos += rowkey_read_info_size; + } + LOG_DEBUG("TINY TABLET: tablet + rowkey_read_info", KP(buf), K(start_pos), K(remain)); + } + + // table store related + ObTabletTableStore *table_store = nullptr; + if (OB_SUCC(ret)) { + if (arg.table_store_addr_.is_none()) { + void *ptr = nullptr; + if (OB_ISNULL(ptr = allocator.alloc(sizeof(ObTabletTableStore)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate a buffer", K(ret), "sizeof", sizeof(ObTabletTableStore)); + } else { + table_store = new (ptr) ObTabletTableStore(); + if (OB_FAIL(table_store->init(allocator, *tiny_tablet))) { + LOG_WARN("fail to init table store", K(ret), K(*tiny_tablet)); + } + } + } else if (OB_FAIL(load_table_store(allocator, *tiny_tablet, arg.table_store_addr_, table_store))) { + LOG_WARN("fail to load table store", K(ret), KPC(tiny_tablet), K(arg.table_store_addr_)); + } + } + + if (OB_SUCC(ret)) { + int64_t table_store_size = table_store->get_deep_copy_size(); + if (OB_LIKELY((remain - table_store_size) >= 0)) { + if (OB_FAIL(table_store->batch_cache_sstable_meta(allocator, remain - table_store_size))) { + LOG_WARN("fail to batch cache sstable meta", K(ret), K(remain), K(table_store_size)); + } else { + ObIStorageMetaObj *table_store_obj = nullptr; + table_store_size = table_store->get_deep_copy_size(); + if (OB_FAIL(table_store->deep_copy(buf + start_pos, remain, table_store_obj))) { + LOG_WARN("fail to deep copy table store v2", K(ret), K(table_store)); + } else if (OB_ISNULL(table_store_obj)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr for rowkey table store deep copy", K(ret), K(table_store_obj)); + } else { + tiny_tablet->table_store_addr_.ptr_ = static_cast(table_store_obj); + remain -= table_store_size; + start_pos += table_store_size; + } + } + } else { + LOG_DEBUG("TINY TABLET: no enough memory for tablet store", K(rowkey_read_info_size), K(remain), + K(table_store_size)); + } + } + + // auto_inc_seq related + if (OB_SUCC(ret)) { + LOG_DEBUG("TINY TABLET: tablet + rowkey_read_info + tablet store", KP(buf), K(start_pos), K(remain)); + ObIStorageMetaObj *auto_inc_obj = nullptr; + const int auto_inc_seq_size = arg.auto_inc_seq_ptr_->get_deep_copy_size(); + if (OB_LIKELY((remain - auto_inc_seq_size) > 0)) { + if(OB_FAIL(arg.auto_inc_seq_ptr_->deep_copy(buf + start_pos, remain, auto_inc_obj))) { + LOG_WARN("fail to deep copy auto inc seq", K(ret), K(arg.auto_inc_seq_ptr_)); + } else { + tiny_tablet->mds_data_.auto_inc_seq_.ptr_ = static_cast(auto_inc_obj); + remain -= auto_inc_seq_size; + start_pos += auto_inc_seq_size; + } + } else { + LOG_DEBUG("TINY TABLET: no enough memory for auto inc seq", K(rowkey_read_info_size), K(remain), + K(auto_inc_seq_size)); + } + } + if (OB_SUCC(ret)) { + tiny_tablet->is_inited_ = true; + } + } + return ret; +} + +int ObTabletPersister::fetch_and_persist_sstable( + common::ObArenaAllocator &allocator, + ObTableStoreIterator &table_iter, + ObTabletTableStore &new_table_store, + common::ObIArray &meta_write_ctxs) +{ + int ret = OB_SUCCESS; + common::ObSEArray tables; + common::ObSEArray addrs; + common::ObSEArray write_ctxs; + common::ObSEArray write_infos; + ObSharedBlockBatchHandle handle; + ObITable *table = nullptr; + while (OB_SUCC(ret) && OB_SUCC(table_iter.get_next(table))) { + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, table is nullptr", K(ret), KPC(table)); + } else { + ObMetaDiskAddr addr; + ObSSTable *sstable = nullptr; + ObArenaAllocator tmp_allocator("PersistSSTable"); + // The sstable by cache in table store, the address is also valid. But, here we hope that all + // members of the sstable are serialized. So, we deep copy the sstable and set mem address. + addr.set_mem_addr(0, sizeof(ObSSTable)); + if (OB_FAIL(static_cast(table)->deep_copy(tmp_allocator, sstable))) { + LOG_WARN("fail to deep copy sstable", K(ret), KPC(table)); + } else if (OB_FAIL(sstable->set_addr(addr))) { + LOG_WARN("fail to set sstable address", K(ret), K(addr)); + } else if (OB_FAIL(fill_write_info(allocator, sstable, write_infos))) { + LOG_WARN("fail to fill sstable write info", K(ret), KPC(table)); + } else if (OB_FAIL(tables.push_back(table))) { + LOG_WARN("fail to push back sstable address", K(ret), K(tables)); + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + if (OB_SUCC(ret) && write_infos.count() > 0) { + ObTenantCheckpointSlogHandler *ckpt_slog_hanlder = MTL(ObTenantCheckpointSlogHandler*); + if (OB_ISNULL(ckpt_slog_hanlder)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, ckpt slog handler is nullptr", K(ret), KP(ckpt_slog_hanlder)); + } else if (OB_FAIL(ckpt_slog_hanlder->get_shared_block_reader_writer().async_batch_write(write_infos, handle))) { + LOG_WARN("fail to batch async write", K(ret), K(write_infos)); + } else if (OB_FAIL(handle.batch_get_write_ctx(write_ctxs))) { + LOG_WARN("fail to batch get addr", K(ret), K(handle)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < write_ctxs.count(); ++i) { + if (OB_UNLIKELY(!write_ctxs.at(i).is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid addr", K(ret), K(i), K(write_ctxs.at(i))); + } else if (OB_FAIL(addrs.push_back(write_ctxs.at(i).addr_))) { + LOG_WARN("fail to push sstable addr to array", K(ret), K(i), K(write_ctxs.at(i))); + } else if (OB_FAIL(meta_write_ctxs.push_back(write_ctxs.at(i)))) { + LOG_WARN("fail to push write ctxs to array", K(ret), K(i), K(write_ctxs.at(i))); + } + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(new_table_store.init(allocator, tables, addrs))) { + LOG_WARN("fail to init new table store", K(ret), K(tables), K(addrs)); + } + return ret; +} + +int ObTabletPersister::write_and_fill_args( + const common::ObIArray &write_infos, + ObTabletTransformArg &arg, + common::ObIArray &meta_write_ctxs) +{ + int ret = OB_SUCCESS; + ObTenantCheckpointSlogHandler *ckpt_slog_hanlder = MTL(ObTenantCheckpointSlogHandler*); + ObSharedBlockReaderWriter &reader_writer = ckpt_slog_hanlder->get_shared_block_reader_writer(); + ObSharedBlockBatchHandle handle; + ObMetaDiskAddr* addr[] = { // NOTE: The order must be the same as the batch async write. + &arg.table_store_addr_, + &arg.auto_inc_seq_addr_, + &arg.storage_schema_addr_, + &arg.tablet_status_uncommitted_kv_addr_, + &arg.tablet_status_committed_kv_addr_, + &arg.aux_tablet_info_uncommitted_kv_addr_, + &arg.aux_tablet_info_committed_kv_addr_, + }; + common::ObSEArray write_ctxs; + if (OB_UNLIKELY(sizeof(addr)/sizeof(addr[0]) != write_infos.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), "write info count", write_infos.count(), K(write_infos)); + } else if (OB_ISNULL(ckpt_slog_hanlder)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, ckpt slog handler is nullptr", K(ret), KP(ckpt_slog_hanlder)); + } else if (OB_FAIL(ckpt_slog_hanlder->get_shared_block_reader_writer().async_batch_write(write_infos, handle))) { + LOG_WARN("fail to batch async write", K(ret), K(write_infos)); + } else if (OB_FAIL(handle.batch_get_write_ctx(write_ctxs))) { + LOG_WARN("fail to batch get addr", K(ret), K(handle)); + } else if (OB_UNLIKELY(sizeof(addr)/sizeof(addr[0]) != write_ctxs.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), "write ctx count", write_ctxs.count(), K(write_ctxs), K(handle)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < write_ctxs.count(); ++i) { + if (OB_UNLIKELY(!write_ctxs.at(i).is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid addr", K(ret), K(i), K(write_ctxs.at(i)), K(handle)); + } else if (OB_FAIL(meta_write_ctxs.push_back(write_ctxs.at(i)))) { + LOG_WARN("fail to push write ctx to array", K(ret), K(i), K(write_ctxs.at(i))); + } else { + *addr[i] = write_ctxs.at(i).addr_; + } + } + } + + return ret; +} + +int ObTabletPersister::load_dump_kv_and_fill_write_info( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &complex_addr, + common::ObIArray &write_infos) +{ + int ret = OB_SUCCESS; + const mds::MdsDumpKV *kv = nullptr; + + if (complex_addr.addr_.is_none()) { + // do nothing + } else if (OB_FAIL(ObTabletMdsData::load_mds_dump_kv(allocator, complex_addr, kv))) { + LOG_WARN("fail to load mds dump kv", K(ret), K(complex_addr)); + } else if (OB_ISNULL(kv)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, kv is null", K(ret), KP(kv)); + } else if (OB_FAIL(fill_write_info(allocator, kv, write_infos))) { + LOG_WARN("fail to fill write info", K(ret), KPC(kv)); + } + + ObTabletMdsData::free_mds_dump_kv(allocator, kv); + + return ret; +} + +int ObTabletPersister::load_medium_info_list_and_write( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &complex_addr, + ObMetaDiskAddr &addr, + common::ObIArray &meta_write_ctxs) +{ + int ret = OB_SUCCESS; + const ObTabletDumpedMediumInfo *medium_info_list = nullptr; + + if (OB_FAIL(ObTabletMdsData::load_medium_info_list(allocator, complex_addr, medium_info_list))) { + LOG_WARN("fail to load medium info list", K(ret), K(complex_addr)); + } else if (OB_ISNULL(medium_info_list)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, medium info list is null", K(ret), KP(medium_info_list)); + } else if (OB_FAIL(link_write_medium_info_list(*medium_info_list, addr, meta_write_ctxs))) { + LOG_WARN("failed to link write medium info list", K(ret)); + } + + ObTabletMdsData::free_medium_info_list(allocator, medium_info_list); + + return ret; +} + +int ObTabletPersister::link_write_medium_info_list( + const ObTabletDumpedMediumInfo &medium_info_list, + ObMetaDiskAddr &addr, + common::ObIArray &meta_write_ctxs) +{ + int ret = OB_SUCCESS; + ObTenantCheckpointSlogHandler *ckpt_slog_hanlder = MTL(ObTenantCheckpointSlogHandler*); + ObSharedBlockReaderWriter &reader_writer = ckpt_slog_hanlder->get_shared_block_reader_writer(); + common::ObArenaAllocator arena_allocator("serializer"); + ObSharedBlockWriteInfo write_info; + ObSharedBlockLinkHandle write_handle; + + const common::ObIArray &array = medium_info_list.medium_info_list_; + for (int64_t i = 0; OB_SUCC(ret) && i < array.count(); ++i) { + const compaction::ObMediumCompactionInfo *medium_info = array.at(i); + if (OB_ISNULL(medium_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, medium info is null", K(ret), K(i), KP(medium_info)); + } else { + const int64_t size = medium_info->get_serialize_size(); + + if (0 == size) { + LOG_INFO("medium info serialize size is 0, just skip", K(ret)); + } else { + int64_t pos = 0; + char *buffer = static_cast(arena_allocator.alloc(size)); + if (OB_ISNULL(buffer)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret), K(size)); + } else if (OB_FAIL(medium_info->serialize(buffer, size, pos))) { + LOG_WARN("failed to serialize medium info", K(ret)); + } else { + write_info.reset(); + write_info.buffer_ = buffer; + write_info.offset_ = 0; + write_info.size_ = size; + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + if (OB_FAIL(reader_writer.async_link_write(write_info, write_handle))) { + LOG_WARN("failed to do async link write", K(ret), K(write_info)); + } else if (OB_UNLIKELY(!write_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, write handle is invalid", K(ret), K(write_handle)); + } + } + + if (nullptr != buffer) { + arena_allocator.free(buffer); + } + } + } + } + + if (OB_FAIL(ret)) { + } else if (array.empty()) { + addr.set_none_addr(); + } else { + ObSharedBlocksWriteCtx write_ctx; + if (OB_FAIL(write_handle.get_write_ctx(write_ctx))) { + LOG_WARN("failed to get write ctx", K(ret), K(write_handle)); + } else if (OB_FAIL(meta_write_ctxs.push_back(write_ctx))) { + LOG_WARN("failed to push back write ctx", K(ret), K(write_ctx)); + } else { + addr = write_ctx.addr_; + } + } + + return ret; +} + +int ObTabletPersister::load_table_store( + common::ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObMetaDiskAddr &addr, + ObTabletTableStore *&table_store) +{ + int ret = OB_SUCCESS; + void *ptr = nullptr; + ObArenaAllocator io_allocator("PersisterTmpIO"); + if (OB_UNLIKELY(!addr.is_block())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("address type isn't disk", K(ret), K(addr)); + } else if (OB_ISNULL(ptr = allocator.alloc(sizeof(ObTabletTableStore)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate a buffer", K(ret), "sizeof", sizeof(ObTabletTableStore)); + } else { + ObTabletTableStore *tmp_store = new (ptr) ObTabletTableStore(); + char *io_buf = nullptr; + int64_t buf_len = -1; + int64_t io_pos = 0; + ObSharedBlockReadInfo read_info; + ObSharedBlockReadHandle io_handle; + read_info.addr_ = addr; + read_info.io_desc_.set_mode(ObIOMode::READ); + read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_DATA_READ); + if (OB_FAIL(ObSharedBlockReaderWriter::async_read(read_info, io_handle))) { + LOG_WARN("fail to async read", K(ret), K(read_info)); + } else if (OB_FAIL(io_handle.wait())) { + LOG_WARN("fail to wait io_hanlde", K(ret), K(read_info)); + } else if (OB_FAIL(io_handle.get_data(io_allocator, io_buf, buf_len))) { + LOG_WARN("fail to get data", K(ret), K(read_info)); + } else if (OB_FAIL(tmp_store->deserialize(allocator, tablet, io_buf, buf_len, io_pos))) { + LOG_WARN("fail to deserialize table store", K(ret), K(tablet), KP(io_buf), K(buf_len)); + } else { + table_store = tmp_store; + LOG_DEBUG("succeed to load table store", K(ret), K(addr), KPC(table_store), K(tablet)); + } + } + return ret; +} + +int ObTabletPersister::transform_tablet_memory_footprint( + const ObTablet &old_tablet, + char *buf, + const int64_t len) +{ + int ret = OB_SUCCESS; + ObTabletMemberWrapper auto_inc_seq; + ObTabletTransformArg arg; + if (OB_UNLIKELY(!old_tablet.hold_ref_cnt_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("old tablet doesn't hold ref cnt", K(ret), K(old_tablet)); + } else if (OB_FAIL(convert_tablet_to_mem_arg(old_tablet, auto_inc_seq, arg))) { + LOG_WARN("fail to convert tablet to mem arg", K(ret), K(arg), KP(buf), K(len), K(old_tablet)); + } else if (OB_FAIL(transform(arg, buf, len))) { + LOG_WARN("fail to transform tablet", K(ret), K(arg), KP(buf), K(len), K(old_tablet)); + } else { + ObTablet *tablet = reinterpret_cast(buf); + tablet->set_next_tablet_guard(old_tablet.next_tablet_guard_); + tablet->set_tablet_addr(old_tablet.get_tablet_addr()); + tablet->hold_ref_cnt_ = old_tablet.hold_ref_cnt_; + } + return ret; +} + +} // end namespace storage +} // end namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_persister.h b/src/storage/tablet/ob_tablet_persister.h new file mode 100644 index 000000000..f741bdc71 --- /dev/null +++ b/src/storage/tablet/ob_tablet_persister.h @@ -0,0 +1,296 @@ +/** + * 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_STORAGE_OB_TABLET_PERSIST_H_ +#define OCEANBASE_STORAGE_OB_TABLET_PERSIST_H_ + +#include "lib/allocator/page_arena.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/blockstore/ob_shared_block_reader_writer.h" +#include "storage/tablet/ob_tablet_complex_addr.h" +#include "storage/tablet/ob_tablet_dumped_medium_info.h" + +namespace oceanbase +{ +namespace storage +{ +class ObTabletTransformArg final +{ +public: + ObTabletTransformArg(); + ~ObTabletTransformArg(); + ObTabletTransformArg(const ObTabletTransformArg &) = delete; + ObTabletTransformArg &operator=(const ObTabletTransformArg &) = delete; + void reset(); + bool is_valid() const; + TO_STRING_KV(KP_(auto_inc_seq_ptr), + KP_(rowkey_read_info_ptr), + K_(tablet_meta), + K_(table_store_addr), + K_(storage_schema_addr), + K_(tablet_status_uncommitted_kv_addr), + K_(tablet_status_committed_kv_addr), + K_(aux_tablet_info_uncommitted_kv_addr), + K_(aux_tablet_info_committed_kv_addr), + K_(extra_medium_info), + K_(medium_info_list_addr), + K_(auto_inc_seq_addr), + K_(tablet_status_cache), + K_(aux_tablet_info_cache)); +public: + const share::ObTabletAutoincSeq *auto_inc_seq_ptr_; + const ObRowkeyReadInfo *rowkey_read_info_ptr_; + ObTabletMeta tablet_meta_; + ObMetaDiskAddr table_store_addr_; + ObMetaDiskAddr storage_schema_addr_; + ObMetaDiskAddr tablet_status_uncommitted_kv_addr_; + ObMetaDiskAddr tablet_status_committed_kv_addr_; + ObMetaDiskAddr aux_tablet_info_uncommitted_kv_addr_; + ObMetaDiskAddr aux_tablet_info_committed_kv_addr_; + ObTaletExtraMediumInfo extra_medium_info_; + ObMetaDiskAddr medium_info_list_addr_; + ObMetaDiskAddr auto_inc_seq_addr_; + ObTabletCreateDeleteMdsUserData tablet_status_cache_; + ObTabletBindingMdsUserData aux_tablet_info_cache_; + // If you want to add new member, make sure all member is assigned in 2 convert function. + // ObTabletPersister::convert_tablet_to_mem_arg + // ObTabletPersister::convert_tablet_to_disk_arg +}; + +class ObTabletPersister final +{ +public: + ObTabletPersister() = default; + ~ObTabletPersister() = default; + + // Persist the old tablet itself and all internal members, and transform it into a new tablet + // from object pool. The old tablet can be allocated by allocator or from object pool. + static int persist_and_transform_tablet( + const ObTablet &old_tablet, + ObTabletHandle &new_handle); + // change tablet memory footprint + // - degrade larger tablet objects to relatively smaller tablet objects, reducing the memory footprint. + // - upgrade smaller tablet objects to relatively larger tablet objects, achieving more performance. + static int transform_tablet_memory_footprint( + const ObTablet &old_tablet, + char *buf, + const int64_t len); +private: + using FetchTableStore = std::function &)>; + using FetchAutoincSeq = std::function &)>; + using LoadStorageSchema = std::function; + using LoadMediumInfoList = std::function; + using LoadMdsDumpKV = std::function; +private: + static int check_tablet_meta_ids( + const common::ObIArray &tablet_meta_write_ctxs, + const ObTablet &tablet); + static int acquire_tablet( + const ObTabletPoolType &type, + const ObTabletMapKey &key, + const bool try_smaller_pool, + ObTabletHandle &new_handle); + static int convert_tablet_to_mem_arg( + const ObTablet &tablet, + ObTabletMemberWrapper &auto_inc_seq, + ObTabletTransformArg &arg); + static int convert_tablet_to_disk_arg( + common::ObArenaAllocator &allocator, + const ObTablet &tablet, + common::ObIArray &tablet_meta_write_ctxs, + common::ObIArray &sstable_meta_write_ctxs, + ObTabletPoolType &type, + ObTabletMemberWrapper &auto_inc_seq, + ObTabletTransformArg &arg); + static int convert_arg_to_tablet( + const ObTabletTransformArg &arg, + ObTablet &tablet); + static int transform( + const ObTabletTransformArg &arg, + char *buf, + const int64_t len); + static int recursively_persist( + const ObTablet &old_tablet, + common::ObArenaAllocator &allocator, + common::ObIArray &tablet_meta_write_ctxs, + common::ObIArray &sstable_meta_write_ctxs, + ObTabletHandle &new_handle); + static int persist_and_fill_tablet( + const ObTablet &old_tablet, + common::ObArenaAllocator &allocator, + common::ObIArray &tablet_meta_write_ctxs, + common::ObIArray &sstable_meta_write_ctxs, + ObTabletHandle &new_handle); + static int fetch_and_persist_sstable( + common::ObArenaAllocator &allocator, + ObTableStoreIterator &table_iter, + ObTabletTableStore &new_table_store, + common::ObIArray &meta_write_ctxs); + template + static int fetch_wrapper_and_write_info( + common::ObArenaAllocator &allocator, + Fetch &fetch, + ObTabletMemberWrapper &wrapper, + common::ObIArray &write_infos, + common::ObIArray &meta_write_ctxs); + template + static int load_member_and_write_info( + common::ObArenaAllocator &allocator, + Load &load, + T *&t, + common::ObIArray &write_infos); + static int load_dump_kv_and_fill_write_info( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &complex_addr, + common::ObIArray &write_infos); + static int load_medium_info_list_and_write( + common::ObArenaAllocator &allocator, + const ObTabletComplexAddr &complex_addr, + ObMetaDiskAddr &addr, + common::ObIArray &meta_write_ctxs); + static int link_write_medium_info_list( + const ObTabletDumpedMediumInfo &medium_info_list, + ObMetaDiskAddr &addr, + common::ObIArray &meta_write_ctxs); + template + static int fill_write_info( + common::ObArenaAllocator &allocator, + const T *t, + common::ObIArray &write_infos); + static int fill_write_info( + common::ObArenaAllocator &allocator, + const common::ObIArray &medium_info_list, + common::ObIArray &write_infos); + static int write_and_fill_args( + const common::ObIArray &write_infos, + ObTabletTransformArg &arg, + common::ObIArray &meta_write_ctxs); + static int persist_4k_tablet( + common::ObArenaAllocator &allocator, + ObTabletHandle &new_handle); + static int load_table_store( + common::ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObMetaDiskAddr &addr, + ObTabletTableStore *&table_store); +}; + +template +int ObTabletPersister::fetch_wrapper_and_write_info( + common::ObArenaAllocator &allocator, + Fetch &fetch, + ObTabletMemberWrapper &wrapper, + common::ObIArray &write_infos, + common::ObIArray &meta_write_ctxs) +{ + UNUSED(meta_write_ctxs); + int ret = common::OB_SUCCESS; + const T *member = nullptr; + if (OB_FAIL(fetch(wrapper))) { + STORAGE_LOG(WARN, "fail to fetch tablet wrapper", K(ret)); + } else if (OB_FAIL(wrapper.get_member(member))) { + STORAGE_LOG(WARN, "fail to get tablet member", K(ret), K(wrapper)); + } else if (OB_ISNULL(member)) { + ret = common::OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "unexpected error, member is nullptr", K(ret), KP(member)); + } else if (OB_FAIL(fill_write_info(allocator, member, write_infos))) { + STORAGE_LOG(WARN, "fail to fill write info", K(ret), KP(member)); + } + return ret; +}; + +template <> +inline int ObTabletPersister::fetch_wrapper_and_write_info( + common::ObArenaAllocator &allocator, + FetchTableStore &fetch, + ObTabletMemberWrapper &wrapper, + common::ObIArray &write_infos, + common::ObIArray &meta_write_ctxs) +{ + int ret = common::OB_SUCCESS; + ObTabletTableStore new_table_store; + const ObTabletTableStore *table_store = nullptr; + ObTableStoreIterator table_iter; + if (OB_FAIL(fetch(wrapper))) { + STORAGE_LOG(WARN, "fail to fetch table store", K(ret)); + } else if (OB_FAIL(wrapper.get_member(table_store))) { + STORAGE_LOG(WARN, "fail to get table store from wrapper", K(ret), K(wrapper)); + } else if (OB_ISNULL(table_store)) { + ret = common::OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "unexpected error, table store is nullptr", K(ret), KP(table_store)); + } else if (OB_FAIL(table_store->get_all_sstable(table_iter))) { + STORAGE_LOG(WARN, "fail to get all sstable iterator", K(ret), KPC(table_store)); + } else if (OB_FAIL(fetch_and_persist_sstable(allocator, table_iter, new_table_store, meta_write_ctxs))) { + STORAGE_LOG(WARN, "fail to fetch and persist sstable", K(ret), K(table_iter)); + } else if (OB_FAIL(fill_write_info(allocator, &new_table_store, write_infos))) { + STORAGE_LOG(WARN, "fail to fill table store write info", K(ret), K(new_table_store)); + } + return ret; +} + +template +int ObTabletPersister::load_member_and_write_info( + common::ObArenaAllocator &allocator, + Load &load, + T *&t, + common::ObIArray &write_infos) +{ + int ret = common::OB_SUCCESS; + if (OB_FAIL(load(allocator, t))) { + STORAGE_LOG(WARN, "fail to load tablet member", K(ret)); + } else if (OB_ISNULL(t)) { + ret = common::OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "unexpected error, t is nullptr", K(ret), KP(t)); + } else if (OB_FAIL(fill_write_info(allocator, t, write_infos))) { + STORAGE_LOG(WARN, "fail to fill write info", K(ret), KP(t)); + } + return ret; +} + +template +int ObTabletPersister::fill_write_info( + common::ObArenaAllocator &allocator, + const T *t, + common::ObIArray &write_infos) +{ + int ret = common::OB_SUCCESS; + if (OB_ISNULL(t)) { + ret = common::OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "unexpected error, tablet member is nullptr", K(ret), KP(t)); + } else { + const int64_t size = t->get_serialize_size(); + char *buf = static_cast(allocator.alloc(size)); + int64_t pos = 0; + if (OB_ISNULL(buf)) { + ret = common::OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "fail to allocate memory for serialize", K(ret), K(size)); + } else if (OB_FAIL(t->serialize(buf, size, pos))) { + STORAGE_LOG(WARN, "fail to serialize member", K(ret), KP(buf), K(size), K(pos)); + } else { + ObSharedBlockWriteInfo write_info; + write_info.buffer_ = buf; + write_info.offset_ = 0; + write_info.size_ = size; + write_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_COMPACT_WRITE); + if (OB_FAIL(write_infos.push_back(write_info))) { + STORAGE_LOG(WARN, "fail to push back write info", K(ret)); + } + } + } + return ret; +} + +} // end namespace storage +} // end namespace oceanbase + +#endif /* OCEANBASE_STORAGE_OB_TABLET_PERSIST_H_ */ diff --git a/src/storage/tablet/ob_tablet_service_clog_replay_executor.cpp b/src/storage/tablet/ob_tablet_service_clog_replay_executor.cpp index 6b6c02ecc..da4b64357 100644 --- a/src/storage/tablet/ob_tablet_service_clog_replay_executor.cpp +++ b/src/storage/tablet/ob_tablet_service_clog_replay_executor.cpp @@ -25,90 +25,47 @@ namespace oceanbase { namespace storage { -ObTabletServiceClogReplayExecutor::ObTabletServiceClogReplayExecutor( - ObLS *ls, - const palf::LSN &lsn, - const SCN &scn) - : ls_(ls), - lsn_(lsn), - scn_(scn) +ObTabletServiceClogReplayExecutor::ObTabletServiceClogReplayExecutor() + : ObTabletReplayExecutor(), buf_(nullptr), buf_size_(0), pos_(0), scn_() { } -int ObTabletServiceClogReplayExecutor::execute( - ObLS *ls, +int ObTabletServiceClogReplayExecutor::init( const char *buf, const int64_t buf_size, const int64_t pos, - const palf::LSN &lsn, const SCN &scn) { int ret = OB_SUCCESS; - int64_t tmp_pos = pos; - ObTabletServiceClogReplayExecutor replay_executor(ls, lsn, scn); - ObLogBaseHeader base_header; - - if (OB_ISNULL(ls) - || OB_ISNULL(buf) - || OB_UNLIKELY(buf_size <= 0) - || OB_UNLIKELY(pos < 0) - || OB_UNLIKELY(!lsn.is_valid()) - || OB_UNLIKELY(!scn.is_valid())) { + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret), K_(is_inited)); + } else if (OB_ISNULL(buf) + || OB_UNLIKELY(buf_size <= 0) + || OB_UNLIKELY(pos < 0) + || OB_UNLIKELY(!scn.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(replay_executor), K(buf), K(buf_size), K(pos), - K(lsn), K(scn), K(ret)); - } else if (OB_FAIL(base_header.deserialize(buf, buf_size, tmp_pos))) { - LOG_WARN("log base header deserialize error", K(ret)); + LOG_WARN("invalid arguments", KP(buf), K(buf_size), K(pos), K(scn), K(ret)); } else { - const ObLogBaseType log_type = base_header.get_log_type(); - switch (log_type) { - case ObLogBaseType::STORAGE_SCHEMA_LOG_BASE_TYPE: - ret = replay_executor.replay_update_storage_schema(scn, buf, buf_size, tmp_pos); - break; - default: - ret = OB_NOT_SUPPORTED; - LOG_WARN("log type not supported", K(ret), K(log_type)); - } + buf_ = buf; + buf_size_ = buf_size; + pos_ = pos; + scn_ = scn; + is_inited_ = true; } return ret; } -int ObTabletServiceClogReplayExecutor::replay_update_storage_schema( - const SCN &scn, - const char *buf, - const int64_t buf_size, - const int64_t pos) +int ObTabletServiceClogReplayExecutor::do_replay_(ObTabletHandle &handle) { int ret = OB_SUCCESS; - ObTabletID tablet_id; - ObTabletHandle handle; - int64_t tmp_pos = pos; - - if (OB_ISNULL(buf) - || OB_UNLIKELY(buf_size <= pos) - || OB_UNLIKELY(pos < 0) - || OB_UNLIKELY(buf_size <= 0) - || OB_UNLIKELY(!scn.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), KP(buf), K(buf_size), K(pos)); - } else if (OB_FAIL(tablet_id.deserialize(buf, buf_size, tmp_pos))) { - LOG_WARN("fail to deserialize tablet id", K(ret), K(buf_size), K(pos), K(tablet_id)); - } else if (OB_FAIL(ls_->replay_get_tablet(tablet_id, scn, handle))) { - if (OB_TABLET_NOT_EXIST == ret) { - ret = OB_SUCCESS; // TODO (bowen.gbw): unify multi data replay logic - LOG_INFO("tablet does not exist, skip", K(ret), K(tablet_id)); - } else if (OB_EAGAIN == ret) { - if (REACH_TIME_INTERVAL(3 * 1000 * 1000)) { - LOG_WARN("unexpected EAGAIN error", K(ret), K(tablet_id), K(scn)); - } - } else { - LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); - } - } else if (OB_FAIL(handle.get_obj()->replay_update_storage_schema(scn, buf, buf_size, tmp_pos))) { - LOG_WARN("update tablet storage schema fail", K(ret), K(tablet_id), K(scn)); + if (OB_FAIL(handle.get_obj()->replay_update_storage_schema(scn_, buf_, buf_size_, pos_))) { + LOG_WARN("update tablet storage schema fail", K(ret), K(handle), K_(scn), KP_(buf), K_(buf_size), K_(pos)); } + return ret; } + } } diff --git a/src/storage/tablet/ob_tablet_service_clog_replay_executor.h b/src/storage/tablet/ob_tablet_service_clog_replay_executor.h index d6981d60a..7ae913639 100644 --- a/src/storage/tablet/ob_tablet_service_clog_replay_executor.h +++ b/src/storage/tablet/ob_tablet_service_clog_replay_executor.h @@ -14,7 +14,9 @@ #define OCEANBASE_STORAGE_OB_TABLET_SERVICE_CLOG_REPLAY_EXECUTOR #include +#include "common/ob_tablet_id.h" #include "logservice/palf/lsn.h" +#include "logservice/replayservice/ob_tablet_replay_executor.h" #include "share/scn.h" namespace oceanbase @@ -23,36 +25,43 @@ namespace storage { class ObLS; -class ObTabletServiceClogReplayExecutor final +class ObTabletServiceClogReplayExecutor final : public logservice::ObTabletReplayExecutor { public: - static int execute( - ObLS *ls, + ObTabletServiceClogReplayExecutor(); + int init( const char *buf, const int64_t log_size, const int64_t pos, - const palf::LSN &lsn, const share::SCN &scn); -public: - TO_STRING_KV(KP(ls_), K(lsn_), K(scn_)); + + TO_STRING_KV(KP_(buf), + K_(buf_size), + K_(pos), + K_(scn)); + +protected: + bool is_replay_update_user_data_() const override + { + return false; + } + + // replay to the tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + int do_replay_(ObTabletHandle &handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return false; + } private: - ObTabletServiceClogReplayExecutor( - ObLS *ls, - const palf::LSN &lsn, - const share::SCN &scn); - ~ObTabletServiceClogReplayExecutor() = default; - ObTabletServiceClogReplayExecutor(const ObTabletServiceClogReplayExecutor&) = delete; - ObTabletServiceClogReplayExecutor &operator=(const ObTabletServiceClogReplayExecutor&) = delete; -private: - int replay_update_storage_schema( - const share::SCN &scn, - const char *buf, - const int64_t buf_size, - const int64_t pos); -private: - ObLS *ls_; - palf::LSN lsn_; + const char *buf_; + int64_t buf_size_; + int64_t pos_; share::SCN scn_; }; diff --git a/src/storage/tablet/ob_tablet_slog_helper.cpp b/src/storage/tablet/ob_tablet_slog_helper.cpp old mode 100644 new mode 100755 index 9ff31dd2c..9c96c3732 --- a/src/storage/tablet/ob_tablet_slog_helper.cpp +++ b/src/storage/tablet/ob_tablet_slog_helper.cpp @@ -30,85 +30,64 @@ namespace oceanbase { namespace storage { -int ObTabletSlogHelper::write_create_tablet_slog( - const ObTabletHandle &tablet_handle, - ObMetaDiskAddr &disk_addr) +int ObTabletSlogHelper::write_update_tablet_slog( + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id, + const ObMetaDiskAddr &disk_addr) { int ret = OB_SUCCESS; - - if (OB_UNLIKELY(!tablet_handle.is_valid())) { + const ObTabletMapKey tablet_key(ls_id, tablet_id); + if (OB_UNLIKELY(!ls_id.is_valid() || !tablet_id.is_valid() || !disk_addr.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(tablet_handle)); + LOG_WARN("invalid arguments", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); } else if (OB_FAIL(THE_IO_DEVICE->fsync_block())) { // make sure that all data or meta written on the macro block is flushed LOG_WARN("fail to fsync_block", K(ret)); } else { - ObCreateTabletLog slog_entry(tablet_handle.get_obj()); + ObUpdateTabletLog slog_entry(ls_id, tablet_id, disk_addr); ObStorageLogParam log_param; log_param.cmd_ = ObIRedoModule::gen_cmd(ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, - ObRedoLogSubType::OB_REDO_LOG_PUT_TABLET); + ObRedoLogSubType::OB_REDO_LOG_UPDATE_TABLET); log_param.data_ = &slog_entry; if (OB_FAIL(MTL(ObStorageLogger*)->write_log(log_param))) { LOG_WARN("fail to write slog for creating tablet", K(ret), K(log_param)); } else { - disk_addr = log_param.disk_addr_;; + do { + if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->report_slog(tablet_key, log_param.disk_addr_))) { + if (OB_ALLOCATE_MEMORY_FAILED != ret) { + LOG_WARN("fail to report slog", K(ret), K(tablet_key)); + } else if (REACH_TIME_INTERVAL(1000 * 1000L)) { // 1s + LOG_WARN("fail to report slog due to memory limit", K(ret), K(tablet_key)); + } + } + } while (OB_ALLOCATE_MEMORY_FAILED == ret); } } - return ret; } -int ObTabletSlogHelper::write_create_tablet_slog( - const common::ObIArray &tablet_handle_array, - common::ObIArray &disk_addr_array) +int ObTabletSlogHelper::write_empty_shell_tablet_slog(ObTablet *tablet, ObMetaDiskAddr &disk_addr) { int ret = OB_SUCCESS; - const int64_t tablet_count = tablet_handle_array.count(); - const int32_t cmd = ObIRedoModule::gen_cmd(ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, - ObRedoLogSubType::OB_REDO_LOG_PUT_TABLET); - ObSArray slog_array; - ObSArray param_array; - - if (OB_FAIL(slog_array.reserve(tablet_count))) { - LOG_WARN("failed to reserve for slog array", K(ret), K(tablet_count)); - } else if (OB_FAIL(param_array.reserve(tablet_count))) { - LOG_WARN("failed to reserve for param array", K(ret), K(tablet_count)); - } else if (OB_FAIL(disk_addr_array.reserve(tablet_count))) { - LOG_WARN("failed to reserve for disk addr array", K(ret), K(tablet_count)); - } - - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_count; ++i) { - const ObTabletHandle &tablet_handle = tablet_handle_array.at(i); - if (OB_UNLIKELY(!tablet_handle.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet handle is invalid", K(ret), K(tablet_handle)); - } else { - ObCreateTabletLog slog_entry(tablet_handle.get_obj()); - if (OB_FAIL(slog_array.push_back(slog_entry))) { - LOG_WARN("fail to push slog entry into slog array", K(ret), K(slog_entry), K(i)); - } - } - } - - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_count; i++) { - ObStorageLogParam log_param(cmd, &slog_array[i]); - if (OB_FAIL(param_array.push_back(log_param))) { - LOG_WARN("fail to push log param into param array", K(ret), K(log_param), K(i)); - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(THE_IO_DEVICE->fsync_block())) { // make sure that all data or meta written on the macro block is flushed - LOG_WARN("fail to fsync_block", K(ret)); - } else if (OB_FAIL(MTL(ObStorageLogger*)->write_log(param_array))) { - LOG_WARN("fail to write slog for batch creating tablet", K(ret), K(param_array)); + if (OB_UNLIKELY(!tablet->is_empty_shell())) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("the tablet is not empty shell", K(ret), K(tablet)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_count; i++) { - if (OB_FAIL(disk_addr_array.push_back(param_array[i].disk_addr_))) { - LOG_WARN("fail to push disk addr into disk addr array", K(ret), K(i), K(tablet_count)); - } + const ObTabletMapKey tablet_key(tablet->get_tablet_meta().ls_id_, tablet->get_tablet_meta().tablet_id_); + ObEmptyShellTabletLog slog_entry(tablet->get_tablet_meta().ls_id_, + tablet->get_tablet_meta().tablet_id_, + tablet); + ObStorageLogParam log_param; + log_param.cmd_ = ObIRedoModule::gen_cmd(ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, + ObRedoLogSubType::OB_REDO_LOG_EMPTY_SHELL_TABLET); + log_param.data_ = &slog_entry; + if (OB_FAIL(MTL(ObStorageLogger*)->write_log(log_param))) { + LOG_WARN("fail to write slog for empty shell tablet", K(ret), K(log_param)); + } else if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->report_slog(tablet_key, log_param.disk_addr_))) { + LOG_WARN("fail to report slog", K(ret), K(tablet_key)); + } else { + disk_addr = log_param.disk_addr_; } } - return ret; } @@ -151,6 +130,27 @@ int ObTabletSlogHelper::write_remove_tablet_slog( return ret; } +int ObTabletSlogHelper::write_remove_tablet_slog( + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!ls_id.is_valid() || !tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(ls_id), K(tablet_id)); + } else { + ObDeleteTabletLog slog_entry(ls_id, tablet_id); + ObStorageLogParam log_param; + log_param.cmd_ = ObIRedoModule::gen_cmd(ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, + ObRedoLogSubType::OB_REDO_LOG_DELETE_TABLET); + log_param.data_ = &slog_entry; + if (OB_FAIL(MTL(ObStorageLogger*)->write_log(log_param))) { + LOG_WARN("fail to write slog for creating tablet", K(ret), K(log_param)); + } + } + return ret; +} + int ObTabletSlogHelper::safe_batch_write_remove_tablet_slog( const ObLSID &ls_id, const common::ObIArray &tablet_ids) diff --git a/src/storage/tablet/ob_tablet_slog_helper.h b/src/storage/tablet/ob_tablet_slog_helper.h index 2e5d350b8..b76ea3100 100644 --- a/src/storage/tablet/ob_tablet_slog_helper.h +++ b/src/storage/tablet/ob_tablet_slog_helper.h @@ -24,15 +24,19 @@ namespace storage class ObTabletSlogHelper { public: - static int write_create_tablet_slog( - const ObTabletHandle &tablet_handle, + static int write_update_tablet_slog( + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id, + const ObMetaDiskAddr &disk_addr); + static int write_empty_shell_tablet_slog( + ObTablet *empty_shell_tablet, ObMetaDiskAddr &disk_addr); - static int write_create_tablet_slog( - const common::ObIArray &tablet_handle_array, - common::ObIArray &disk_addr_array); static int write_remove_tablet_slog( const share::ObLSID &ls_id, const common::ObIArray &tablet_ids); + static int write_remove_tablet_slog( + const share::ObLSID &ls_id, + const common::ObTabletID &tablet_ids); private: static int safe_batch_write_remove_tablet_slog( const share::ObLSID &ls_id, diff --git a/src/storage/tablet/ob_tablet_start_transfer_mds_helper.cpp b/src/storage/tablet/ob_tablet_start_transfer_mds_helper.cpp new file mode 100644 index 000000000..ea14647da --- /dev/null +++ b/src/storage/tablet/ob_tablet_start_transfer_mds_helper.cpp @@ -0,0 +1,1553 @@ +/** + * Copyright (c) 2021 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 "storage/tablet/ob_tablet_start_transfer_mds_helper.h" +#include "share/scn.h" +#include "share/ob_ls_id.h" +#include "share/transfer/ob_transfer_info.h" +#include "storage/ls/ob_ls_get_mod.h" +#include "storage/multi_data_source/buffer_ctx.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/meta_mem/ob_tablet_map_key.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "logservice/replayservice/ob_tablet_replay_executor.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "observer/ob_server_event_history_table_operator.h" +#include "storage/high_availability/ob_transfer_service.h" +#include "storage/high_availability/ob_rebuild_service.h" +#include "storage/high_availability/ob_storage_ha_utils.h" +#define USING_LOG_PREFIX MDS + +namespace oceanbase +{ +namespace storage +{ + +/******************ObTabletStartTransferOutReplayExecutor*********************/ +class ObTabletStartTransferOutReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObTabletStartTransferOutReplayExecutor(); + virtual ~ObTabletStartTransferOutReplayExecutor(); + + int init( + const share::SCN &scn, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const share::ObTransferTabletInfo &tablet_info, + mds::BufferCtx &buffer_ctx); +protected: + virtual bool is_replay_update_user_data_() const override + { + return true; + } + + virtual int do_replay_(ObTabletHandle &tablet_handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return true; + } + +private: + int check_src_transfer_tablet_(ObTabletHandle &tablet_handle); + +private: + share::SCN scn_; + share::ObLSID src_ls_id_; + share::ObLSID dest_ls_id_; + share::ObTransferTabletInfo tablet_info_; + mds::BufferCtx *buffer_ctx_; + DISALLOW_COPY_AND_ASSIGN(ObTabletStartTransferOutReplayExecutor); +}; + +ObTabletStartTransferOutReplayExecutor::ObTabletStartTransferOutReplayExecutor() + :logservice::ObTabletReplayExecutor(), + scn_(), + src_ls_id_(), + dest_ls_id_(), + tablet_info_(), + buffer_ctx_(nullptr) +{ +} + +ObTabletStartTransferOutReplayExecutor::~ObTabletStartTransferOutReplayExecutor() +{ +} + +int ObTabletStartTransferOutReplayExecutor::init( + const share::SCN &scn, + const share::ObLSID &src_ls_id, + const share::ObLSID &dest_ls_id, + const share::ObTransferTabletInfo &tablet_info, + mds::BufferCtx &buffer_ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("tablet start transfer out replay executor init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!scn.is_valid()) + || OB_UNLIKELY(!src_ls_id.is_valid()) + || OB_UNLIKELY(!dest_ls_id.is_valid()) + || OB_UNLIKELY(!tablet_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid argument", KR(ret), K(scn), K(src_ls_id), K(dest_ls_id), K(tablet_info)); + } else { + scn_ = scn; + src_ls_id_ = src_ls_id; + dest_ls_id_ = dest_ls_id; + buffer_ctx_ = &buffer_ctx; + tablet_info_ = tablet_info; + scn_ = scn; + is_inited_ = true; + } + return ret; +} + + +int ObTabletStartTransferOutReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + ObTabletCreateDeleteMdsUserData user_data; + mds::MdsCtx &user_ctx = static_cast(*buffer_ctx_); + ObTablet *tablet = nullptr; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + ObLSHandle ls_handle; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet start transfer out replay executor do not init", K(ret)); + } else if (OB_FAIL(check_src_transfer_tablet_(tablet_handle))) { + LOG_WARN("failed to check src transfer tablet", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_handle)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet), K(tablet_info_)); + } else if (OB_FAIL(ls_service->get_ls(src_ls_id_, ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls", K(ret)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(ls)); + } else if (OB_FAIL(ObTXTransferUtils::set_tablet_freeze_flag(ls->get_ls_id(), tablet))) { + LOG_WARN("failed to freeze tablet memtable", K(ret), "tablet id", tablet->get_tablet_meta().tablet_id_); + } else { + user_data.transfer_ls_id_ = dest_ls_id_; + user_data.data_type_ = ObTabletMdsUserDataType::START_TRANSFER_OUT; + user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT; + user_data.transfer_scn_.set_min(); + //user_data.transfer_scn_ will be update in user data on_redo + if (OB_FAIL(replay_to_mds_table_(tablet_handle, user_data, user_ctx, scn_))) { + LOG_WARN("failed to replay to tablet", K(ret)); + } +#ifdef ERRSIM + ObTransferEventRecorder::record_tablet_transfer_event("tx_start_transfer_out", + src_ls_id_, tablet->get_tablet_meta().tablet_id_, + tablet->get_tablet_meta().transfer_info_.transfer_seq_, user_data.tablet_status_, + ret); +#endif + } + return ret; +} + +int ObTabletStartTransferOutReplayExecutor::check_src_transfer_tablet_( + ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("tablet start transfer out replay executor do not init", K(ret)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_info_), K(src_ls_id_), K(dest_ls_id_)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet), K(tablet_info_)); + } else if (scn_ <= tablet->get_tablet_meta().mds_checkpoint_scn_) { + LOG_INFO("skip replay", K(ret), K_(scn), K(tablet->get_tablet_meta())); + } else if (ObTabletStatus::NORMAL != user_data.tablet_status_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet status is unexpected", K(ret), KPC(tablet), K(tablet_info_), K(user_data)); + } else if (tablet_info_.transfer_seq_ != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet transfer seq is unexpected", K(ret), KPC(tablet), K(tablet_info_), K(user_data)); + } + return ret; +} + +/******************ObTabletStartTransferOutHelper*********************/ +int ObTabletStartTransferOutHelper::on_register( + const char *buf, + const int64_t len, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObTXStartTransferOutInfo tx_start_transfer_out_info; + int64_t pos = 0; + const bool for_replay = false; + + if (OB_ISNULL(buf) || len < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on register start transfer out get invalid argument", K(ret), KP(buf), K(len)); + } else if (CLICK_FAIL(tx_start_transfer_out_info.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize tx start transfer out info", K(ret), K(len), K(pos)); + } else if (!tx_start_transfer_out_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tx start transfer out info is unexpected", K(ret), K(tx_start_transfer_out_info)); + } else if (CLICK_FAIL(on_register_success_(tx_start_transfer_out_info, ctx))) { + LOG_WARN("failed to on register", K(ret), K(tx_start_transfer_out_info)); + } + return ret; +} + +int ObTabletStartTransferOutHelper::on_register_success_( + const ObTXStartTransferOutInfo &tx_start_transfer_out_info, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + const int64_t start_ts = ObTimeUtil::current_time(); + LOG_INFO("[TRANSFER] start tx start transfer out on_register_success_", K(tx_start_transfer_out_info)); +#ifdef ERRSIM + SERVER_EVENT_ADD("transfer", "tx_start_transfer_out", + "stage", "on_register_success", + "tenant_id", MTL_ID(), + "src_ls_id", tx_start_transfer_out_info.src_ls_id_.id(), + "dest_ls_id", tx_start_transfer_out_info.dest_ls_id_.id(), + "tablet_count", tx_start_transfer_out_info.tablet_list_.count()); +#endif + + if (!tx_start_transfer_out_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on_register_ get invalid argument", K(ret), K(tx_start_transfer_out_info)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } else if (CLICK_FAIL(ls_service->get_ls(tx_start_transfer_out_info.src_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get ls", KR(ret), K(tx_start_transfer_out_info)); + } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", KR(ret), K(tx_start_transfer_out_info), KP(ls)); + } else if (CLICK_FAIL(prepare_src_transfer_tablets_(tx_start_transfer_out_info , ls))) { + LOG_WARN("failed to prepare src transfer tablets", K(ret), K(tx_start_transfer_out_info), KPC(ls)); + } else if (CLICK_FAIL(update_tablets_transfer_out_(tx_start_transfer_out_info, ls, ctx))) { + LOG_WARN("failed to update tables transfer out", K(ret), K(tx_start_transfer_out_info), KPC(ls)); + } + + if (OB_FAIL(ret)) { + LOG_WARN("tx start transfer out on_register_ failed", K(ret), K(tx_start_transfer_out_info)); + } else { + LOG_INFO("[TRANSFER] finish tx start transfer out on_register_success_", K(tx_start_transfer_out_info), + "cost_ts", ObTimeUtil::current_time() - start_ts); + } + return ret; +} + +int ObTabletStartTransferOutHelper::prepare_src_transfer_tablets_( + const ObTXStartTransferOutInfo &tx_start_transfer_out_info, + ObLS *ls) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + if (!tx_start_transfer_out_info.is_valid() || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("prepare src transfer tablets get invalid argument", K(ret), + K(tx_start_transfer_out_info), KP(ls)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tx_start_transfer_out_info.tablet_list_.count(); ++i) { + MDS_TG(50_ms); + const share::ObTransferTabletInfo &tablet_info = tx_start_transfer_out_info.tablet_list_.at(i); + if (OB_FAIL(prepare_src_transfer_tablet_(tablet_info, ls))) { + LOG_WARN("failed to prepare src transfer tablet", K(ret), K(tablet_info)); + } + } + } + return ret; +} + +int ObTabletStartTransferOutHelper::prepare_src_transfer_tablet_( + const share::ObTransferTabletInfo &tablet_info, + ObLS *ls) +{ + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + if (!tablet_info.is_valid() || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check src transfer tablets get invalid argument", K(ret), K(tablet_info), KP(ls)); + } else if (CLICK_FAIL(ls->get_tablet(tablet_info.tablet_id_, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_info)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_info)); + } else if (CLICK_FAIL(check_src_transfer_tablet_(ls->get_ls_id(), tablet_info, tablet))) { + LOG_WARN("failed to check src transfer tablet", K(ret), K(tablet_info), KPC(tablet)); + } else if (CLICK_FAIL(ObTXTransferUtils::set_tablet_freeze_flag(ls->get_ls_id(), tablet))) { + LOG_WARN("failed to freeze memtable", K(ret), K(tablet_info), KPC(tablet)); + } + return ret; +} + +int ObTabletStartTransferOutHelper::check_src_transfer_tablet_( + const share::ObLSID &ls_id, + const share::ObTransferTabletInfo &tablet_info, + ObTablet *tablet) +{ + MDS_TG(10_ms); + int ret = OB_SUCCESS; + ObTabletCreateDeleteMdsUserData user_data; + + if (!tablet_info.is_valid() || OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check src transfer tablets get invalid argument", K(ret), K(tablet_info), KP(tablet)); + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet), K(tablet_info)); + } else if (ObTabletStatus::NORMAL != user_data.tablet_status_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet status is unexpected", K(ret), KPC(tablet), K(tablet_info), K(user_data)); + } else if (tablet_info.transfer_seq_ != tablet->get_tablet_meta().transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet transfer seq is unexpected", K(ret), KPC(tablet), K(tablet_info), K(user_data)); + } + return ret; +} + +int ObTabletStartTransferOutHelper::update_tablets_transfer_out_( + const ObTXStartTransferOutInfo &tx_start_transfer_out_info, + ObLS *ls, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + if (!tx_start_transfer_out_info.is_valid() || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("update tablets transfer out get invalid argument", K(ret), + K(tx_start_transfer_out_info), KP(ls)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tx_start_transfer_out_info.tablet_list_.count(); ++i) { + MDS_TG(50_ms); + const share::ObTransferTabletInfo &tablet_info = tx_start_transfer_out_info.tablet_list_.at(i); + const share::ObLSID &dest_ls_id = tx_start_transfer_out_info.dest_ls_id_; + if (CLICK_FAIL(update_tablet_transfer_out_(dest_ls_id, tablet_info, ls, ctx))) { + LOG_WARN("failed to update tablet transfer out", K(ret), K(dest_ls_id), K(tablet_info)); + } + } + } + return ret; +} + +int ObTabletStartTransferOutHelper::update_tablet_transfer_out_( + const share::ObLSID &dest_ls_id, + const share::ObTransferTabletInfo &tablet_info, + ObLS *ls, + mds::BufferCtx &ctx) +{ + MDS_TG(50_ms); + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + + if (!tablet_info.is_valid() || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check src transfer tablets get invalid argument", K(ret), K(tablet_info), KP(ls)); + } else if (CLICK_FAIL(ls->get_tablet(tablet_info.tablet_id_, tablet_handle, 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_info)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_info)); + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet), K(tablet_info)); + } else if (ObTabletStatus::NORMAL != user_data.tablet_status_ + || tablet->get_tablet_meta().transfer_info_.transfer_seq_ != tablet_info.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet user data is unexpected", K(ret), KPC(tablet), K(tablet_info), K(user_data)); + } else { + mds::MdsCtx &user_ctx = static_cast(ctx); + user_data.transfer_ls_id_ = dest_ls_id; + user_data.data_type_ = ObTabletMdsUserDataType::START_TRANSFER_OUT; + user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT; + user_data.transfer_scn_.set_min(); + //user_data.transfer_scn_ will be update in user data on_redo + //now here setting min value is inorder to check transfer scn which is setted in redo stage. + if (CLICK_FAIL(ls->get_tablet_svr()->set_tablet_status(tablet->get_tablet_meta().tablet_id_, user_data, user_ctx))) { + LOG_WARN("failed to set user data", K(ret), K(user_data), K(tablet_info)); + } else { + LOG_INFO("succeed to update tablet status transfer out", KPC(tablet), K(user_data), K(tablet_info)); + } +#ifdef ERRSIM + ObTabletStatus tablet_status(ObTabletStatus::TRANSFER_OUT); + ObTransferEventRecorder::record_tablet_transfer_event("tx_start_transfer_out", + ls->get_ls_id(), tablet_info.tablet_id_, + tablet->get_tablet_meta().transfer_info_.transfer_seq_, tablet_status, + ret); +#endif + } + return ret; +} + +int ObTabletStartTransferOutHelper::on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObTXStartTransferOutInfo tx_start_transfer_out_info; + int64_t pos = 0; + const bool for_replay = true; + + if (OB_ISNULL(buf) || len < 0 || !scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on replay start transfer out get invalid argument", K(ret), KP(buf), K(len), K(scn)); + } else if (CLICK_FAIL(tx_start_transfer_out_info.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize tx start transfer out info", K(ret), K(len), K(pos)); + } else if (!tx_start_transfer_out_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tx start transfer out info is unexpected", K(ret), K(tx_start_transfer_out_info)); + } +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "BEFORE_ON_REDO_START_TRANSFER_OUT", + "tenant_id", MTL_ID(), + "src_ls_id", tx_start_transfer_out_info.src_ls_id_.id(), + "dest_ls_id", tx_start_transfer_out_info.dest_ls_id_.id(), + "for_replay", for_replay, + "scn", scn); +#endif + DEBUG_SYNC(BEFORE_ON_REDO_START_TRANSFER_OUT); + if (CLICK() && FAILEDx(on_replay_success_(scn, tx_start_transfer_out_info, ctx))) { + LOG_WARN("failed to on register_success_", K(ret), K(scn), K(tx_start_transfer_out_info)); + } +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "AFTER_ON_REDO_START_TRANSFER_OUT", + "tenant_id", MTL_ID(), + "src_ls_id", tx_start_transfer_out_info.src_ls_id_.id(), + "dest_ls_id", tx_start_transfer_out_info.dest_ls_id_.id(), + "for_replay", for_replay, + "scn", scn); +#endif + DEBUG_SYNC(AFTER_ON_REDO_START_TRANSFER_OUT); + return ret; +} + +int ObTabletStartTransferOutHelper::try_enable_dest_ls_clog_replay( + const share::SCN &scn, + const share::ObLSID &dest_ls_id) +{ + MDS_TG(100_ms); + int ret = OB_SUCCESS; + ObLSService* ls_srv = nullptr; + ObLSHandle dest_ls_handle; + ObLS *dest_ls = NULL; + SCN max_decided_scn; + bool can_replay = true; + ObLSTransferInfo transfer_info; + if (!scn.is_valid() || !dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("replay scn or dest ls id is invalid", K(ret), K(scn), K(dest_ls_id)); + } else if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls srv should not be NULL", K(ret), KP(ls_srv)); + } else if (CLICK_FAIL(ls_srv->get_ls(dest_ls_id, dest_ls_handle, ObLSGetMod::STORAGE_MOD))) { + if (OB_LS_NOT_EXIST == ret) { + LOG_INFO("ls not exist", KR(ret), K(dest_ls_id)); + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get ls", KR(ret), K(dest_ls_id)); + } + } else if (OB_ISNULL(dest_ls = dest_ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", KR(ret), K(dest_ls)); + } else if (dest_ls->get_ls_startup_transfer_info().already_enable_replay()) { + // do nothing + } else if (scn < dest_ls->get_ls_startup_transfer_info().transfer_start_scn_) { + LOG_INFO("replay scn is smaller than transfer start scn, no need enable clog replay", K(dest_ls_id), K(scn), + "ls_startup_transfer_info", dest_ls->get_ls_startup_transfer_info()); + } else { + transfer_info = dest_ls->get_ls_startup_transfer_info(); + dest_ls->get_ls_startup_transfer_info().reset(); + if (OB_FAIL(dest_ls->check_can_replay_clog(can_replay))) { + LOG_WARN("failed to check can replay clog", KR(ret), K(dest_ls)); + } else if (!can_replay) { + // do nothing + } else if (CLICK_FAIL(dest_ls->enable_replay())) { + dest_ls->get_ls_startup_transfer_info() = transfer_info; + LOG_ERROR("fail to enable replay", K(ret), K(scn), K(dest_ls_id), "ls_startup_transfer_info", dest_ls->get_ls_startup_transfer_info()); + } else { + LOG_INFO("succ enable ls clog replay", K(dest_ls_id), K(scn), "ls_startup_transfer_info", dest_ls->get_ls_startup_transfer_info()); + } + } + + return ret; +} + +int ObTabletStartTransferOutHelper::on_replay_success_( + const share::SCN &scn, + const ObTXStartTransferOutInfo &tx_start_transfer_out_info, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + const int64_t start_ts = ObTimeUtil::current_time(); + LOG_INFO("[TRANSFER] start tx start transfer out on_replay_success_", K(scn), K(tx_start_transfer_out_info)); +#ifdef ERRSIM + SERVER_EVENT_ADD("transfer", "tx_start_transfer_out", + "stage", "on_replay_success", + "tenant_id", MTL_ID(), + "src_ls_id", tx_start_transfer_out_info.src_ls_id_.id(), + "dest_ls_id", tx_start_transfer_out_info.dest_ls_id_.id(), + "tablet_count", tx_start_transfer_out_info.tablet_list_.count()); +#endif + + if (!scn.is_valid() || !tx_start_transfer_out_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on_register_ get invalid argument", K(ret), K(scn), K(tx_start_transfer_out_info)); + } else if (CLICK_FAIL(try_enable_dest_ls_clog_replay(scn, tx_start_transfer_out_info.dest_ls_id_))) { + LOG_WARN("failed to try enable dest ls clog replay", K(ret), K(scn), K(tx_start_transfer_out_info)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tx_start_transfer_out_info.tablet_list_.count(); ++i) { + MDS_TG(10_ms); + const share::ObTransferTabletInfo &tablet_info = tx_start_transfer_out_info.tablet_list_.at(i); + ObTabletStartTransferOutReplayExecutor executor; + if (CLICK_FAIL(executor.init(scn, tx_start_transfer_out_info.src_ls_id_, tx_start_transfer_out_info.dest_ls_id_, tablet_info, ctx))) { + LOG_WARN("failed to init tablet start transfer out replay executor", K(ret), K(scn), K(tx_start_transfer_out_info), K(tablet_info)); + } else if (CLICK_FAIL(executor.execute(scn, tx_start_transfer_out_info.src_ls_id_, tablet_info.tablet_id_))) { + LOG_WARN("failed to execute start transfer out replay", K(ret), K(scn), K(tx_start_transfer_out_info), K(tablet_info)); + } + } + } + if (OB_FAIL(ret)) { + LOG_WARN("tx start transfer out on_replay_success_ failed", K(ret), K(scn), K(tx_start_transfer_out_info)); + ret = OB_EAGAIN; + } else { + LOG_INFO("[TRANSFER] finish tx start transfer out on_replay_success_", K(scn), K(tx_start_transfer_out_info), + "cost_ts", ObTimeUtil::current_time() - start_ts); + } + return ret; +} + +/******************ObTabletStartTransferInReplayExecutor*********************/ +class ObTabletStartTransferInReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObTabletStartTransferInReplayExecutor(); + virtual ~ObTabletStartTransferInReplayExecutor(); + + int init( + const share::SCN &scn, + const ObTabletCreateDeleteMdsUserData &user_data, + mds::BufferCtx &user_ctx); + +protected: + bool is_replay_update_user_data_() const override + { + return true; + } + + int do_replay_(ObTabletHandle &tablet_handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return true; + } + + virtual int replay_check_restore_status_(storage::ObTabletHandle &tablet_handle) override + { + UNUSED(tablet_handle); + return OB_SUCCESS; + } + +private: + share::SCN scn_; + ObTabletCreateDeleteMdsUserData user_data_; + mds::BufferCtx *user_ctx_; +}; + + +ObTabletStartTransferInReplayExecutor::ObTabletStartTransferInReplayExecutor() + :logservice::ObTabletReplayExecutor(), + user_ctx_(nullptr) +{ +} + +ObTabletStartTransferInReplayExecutor::~ObTabletStartTransferInReplayExecutor() +{ +} + +int ObTabletStartTransferInReplayExecutor::init( + const share::SCN &scn, + const ObTabletCreateDeleteMdsUserData &user_data, + mds::BufferCtx &user_ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("tablet create replay executor init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!scn.is_valid()) || OB_UNLIKELY(!user_data.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid argument", KR(ret), K(user_data)); + } else if (OB_FAIL(user_data_.assign(user_data))) { + LOG_WARN("fail to assign user data", KR(ret), K(user_data)); + } else { + scn_ = scn; + user_ctx_ = &user_ctx; + is_inited_ = true; + } + return ret; +} + +int ObTabletStartTransferInReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + mds::MdsCtx &user_ctx = static_cast(*user_ctx_); + + if (OB_FAIL(replay_to_mds_table_(tablet_handle, user_data_, user_ctx, scn_))) { + LOG_WARN("failed to replay to tablet", K(ret), K(tablet_handle), K(user_data_), K(scn_)); + } else { + LOG_INFO("succeed to replay transfer in to mds table", K(ret), K(user_data_), K(scn_), K(tablet_handle)); + } + + return ret; +} + +/******************ObTabletStartTransferInHelper*********************/ +int ObTabletStartTransferInHelper::on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObTXStartTransferInInfo tx_start_transfer_in_info; + int64_t pos = 0; + + if (OB_ISNULL(buf) || len < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on register start transfer in get invalid argument", K(ret), KP(buf), K(len)); + } else if (CLICK_FAIL(tx_start_transfer_in_info.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize tx start transfer in info", K(ret), K(len), K(pos)); + } else if (!tx_start_transfer_in_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tx start transfer in info is unexpected", K(ret), K(tx_start_transfer_in_info)); + } else if (CLICK_FAIL(on_register_success_(tx_start_transfer_in_info, ctx))) { + LOG_WARN("failed to do on register success", K(ret), K(tx_start_transfer_in_info)); + } else if (CLICK_FAIL(ObTabletCreateDeleteMdsUserData::set_tablet_gc_trigger(tx_start_transfer_in_info.dest_ls_id_))) { + LOG_WARN("failed to set_tablet_gc_trigger", K(ret), K(tx_start_transfer_in_info)); + } + return ret; +} + +int ObTabletStartTransferInHelper::on_register_success_( + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + const share::SCN scn; + const bool for_replay = false; + const int64_t start_ts = ObTimeUtil::current_time(); + LOG_INFO("[TRANSFER] start tx start transfer in on_register_success_", + K(tx_start_transfer_in_info)); +#ifdef ERRSIM + SERVER_EVENT_ADD("transfer", "tx_start_transfer_in", + "stage", "on_register_success", + "tenant_id", MTL_ID(), + "src_ls_id", tx_start_transfer_in_info.src_ls_id_.id(), + "dest_ls_id", tx_start_transfer_in_info.dest_ls_id_.id(), + "start_scn", tx_start_transfer_in_info.start_scn_); +#endif + + if (!tx_start_transfer_in_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on register success get invalid argument", K(ret), K(tx_start_transfer_in_info)); + } else if (CLICK_FAIL(check_transfer_dest_tablets_(tx_start_transfer_in_info, for_replay))) { + LOG_WARN("failed to check transfer dest tablets", K(ret), K(tx_start_transfer_in_info)); + } else if (CLICK_FAIL(check_transfer_src_tablets_(false /* for replay */, tx_start_transfer_in_info))) { + LOG_WARN("failed to check transfer src tablets", K(ret), K(tx_start_transfer_in_info)); + } else if (CLICK_FAIL(create_transfer_in_tablets_(scn, for_replay, tx_start_transfer_in_info, ctx))) { + LOG_WARN("failed to create transfer in tablets", K(ret), K(tx_start_transfer_in_info)); + } + + if (OB_FAIL(ret)) { + LOG_WARN("tx start transfer in on register success failed", K(ret), K(tx_start_transfer_in_info)); + } else { + LOG_INFO("[TRANSFER] finish tx start transfer in on_register_success_", K(tx_start_transfer_in_info), + "cost_ts", ObTimeUtil::current_time() - start_ts); + } + return ret; +} + +int ObTabletStartTransferInHelper::check_transfer_dest_tablets_( + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + const bool for_replay) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + if (!tx_start_transfer_in_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("start transfer in check transfer dest tablets exist get invalid argument", K(ret), K(tx_start_transfer_in_info)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } else if (CLICK_FAIL(ls_service->get_ls(tx_start_transfer_in_info.dest_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get ls", KR(ret), K(tx_start_transfer_in_info)); + } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", KR(ret), K(tx_start_transfer_in_info), KP(ls)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tx_start_transfer_in_info.tablet_meta_list_.count(); ++i) { + MDS_TG(10_ms); + const ObMigrationTabletParam &tablet_meta = tx_start_transfer_in_info.tablet_meta_list_.at(i); + if (CLICK_FAIL(check_transfer_dest_tablet_(tablet_meta, for_replay, ls))) { + LOG_WARN("failed to check transfer dest tablet", K(ret), K(tablet_meta)); + } + } + } + return ret; +} + +int ObTabletStartTransferInHelper::check_transfer_dest_tablet_( + const ObMigrationTabletParam &tablet_meta, + const bool for_replay, + ObLS *ls) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + bool unused_committed_flag = false; + SCN local_tablet_start_scn; + SCN transfer_info_scn; + int64_t local_transfer_seq = 0; + int64_t transfer_info_seq = 0; + + if (!tablet_meta.is_valid() || OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check transfer dest tablet get invalid argument", K(ret), K(tablet_meta), KP(ls)); + } else { + const ObTabletMapKey key(ls->get_ls_id(), tablet_meta.tablet_id_); + if (OB_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(tablet_meta)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_handle), KP(tablet)); + } else if (FALSE_IT(local_tablet_start_scn = tablet->get_tablet_meta().transfer_info_.transfer_start_scn_)) { + } else if (FALSE_IT(transfer_info_scn = tablet_meta.transfer_info_.transfer_start_scn_)) { + } else if (FALSE_IT(local_transfer_seq = tablet->get_tablet_meta().transfer_info_.transfer_seq_)) { + } else if (FALSE_IT(transfer_info_seq = tablet_meta.transfer_info_.transfer_seq_)) { + } else if (!for_replay) { + if (!tablet->is_empty_shell()) { + ret = OB_EAGAIN; + LOG_WARN("on register start transfer in tablet should not exist", K(ret), K(tablet_handle), K(tablet_meta)); + } else if (local_tablet_start_scn > transfer_info_scn) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("on register start transfer in tablet empty shell start transfer scn should not bigger than create tablet transfer scn", + K(ret), KPC(tablet), K(tablet_meta)); + } + } else if (tablet->is_empty_shell()) { + if ((local_tablet_start_scn > transfer_info_scn && local_transfer_seq < transfer_info_seq) + || (local_tablet_start_scn == transfer_info_scn && local_transfer_seq != transfer_info_seq) + || (local_tablet_start_scn < transfer_info_scn && local_transfer_seq > transfer_info_seq)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer in tablet in empty shell status is unexpected", K(ret), KPC(tablet), K(tablet_meta)); + } + } else if (local_tablet_start_scn < transfer_info_scn) { + ret = OB_EAGAIN; + LOG_WARN("tablet should be delete, need wait gc", K(ret), KPC(tablet), K(tablet_meta)); + } else if (local_tablet_start_scn > transfer_info_scn) { + FLOG_INFO("tablet is already exist", KPC(tablet), K(tablet_meta)); + } else if (tablet->get_tablet_meta().transfer_info_.transfer_seq_ != tablet_meta.transfer_info_.transfer_seq_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet seq is not match", K(ret), KPC(tablet), K(tablet_meta)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_latest_tablet_status(user_data, unused_committed_flag))) { + LOG_WARN("failed to get lastest tablet status", K(ret), KPC(tablet), K(tablet_meta)); + if (OB_SNAPSHOT_DISCARDED == ret || OB_ENTRY_NOT_EXIST == ret || OB_EMPTY_RESULT == ret) { + //local tablet exist but mds table do not persistence + ret = OB_SUCCESS; + FLOG_INFO("tablet is already exist", KPC(tablet), K(tablet_meta)); + } + } else if (ObTabletStatus::TRANSFER_IN != user_data.tablet_status_ + && ObTabletStatus::NORMAL != user_data.tablet_status_ + && ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ + && ObTabletStatus::TRANSFER_OUT_DELETED != user_data.tablet_status_ + && ObTabletStatus::DELETED != user_data.tablet_status_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet status is unexpected", K(ret), K(user_data), KPC(tablet), K(tablet_meta)); + } else { + FLOG_INFO("tablet is already exist", K(tablet_handle), K(tablet_meta), K(user_data)); + } + } + return ret; +} + +int ObTabletStartTransferInHelper::check_can_skip_replay_( + const share::SCN &scn, + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + bool &skip_replay) +{ + int ret = OB_SUCCESS; + skip_replay = true; + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + + if (!scn.is_valid() || !tx_start_transfer_in_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check can skip replay start transfer in get invalid argument", K(ret), K(scn), K(tx_start_transfer_in_info)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(tx_start_transfer_in_info.dest_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get ls", KR(ret), K(tx_start_transfer_in_info)); + } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", KR(ret), K(tx_start_transfer_in_info), KP(ls)); + } else if (scn <= ls->get_tablet_change_checkpoint_scn()) { + skip_replay = true; + LOG_INFO("replay skip for register tx start transfer in", KR(ret), K(scn), + K(tx_start_transfer_in_info), K(ls->get_ls_meta())); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tx_start_transfer_in_info.tablet_meta_list_.count(); ++i) { + const ObMigrationTabletParam &tablet_meta = tx_start_transfer_in_info.tablet_meta_list_.at(i); + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + const ObTabletMapKey key(ls->get_ls_id(), tablet_meta.tablet_id_); + if (OB_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + skip_replay = false; + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get tablet", K(ret), K(tablet_meta)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_meta), KP(tablet)); + } else if (tablet->get_tablet_meta().mds_checkpoint_scn_ < scn) { + skip_replay = false; + break; + } + } + } + return ret; +} + +int ObTabletStartTransferInHelper::check_transfer_src_tablets_( + const bool for_replay, + const ObTXStartTransferInInfo &tx_start_transfer_in_info) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObLSHandle src_ls_handle; + ObLS *src_ls = NULL; + ObLSService* ls_srv = nullptr; + SCN max_decided_scn; + + if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls srv should not be NULL", K(ret), KP(ls_srv)); + } else if (CLICK_FAIL(ls_srv->get_ls(tx_start_transfer_in_info.src_ls_id_, src_ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("ls_srv->get_ls() fail", KR(ret), "src ls id", tx_start_transfer_in_info.src_ls_id_); + if (OB_LS_NOT_EXIST == ret) { + bool is_ls_deleted = false; + if (OB_SUCCESS != (tmp_ret = ObStorageHAUtils::check_ls_deleted(tx_start_transfer_in_info.src_ls_id_, is_ls_deleted))) { + LOG_WARN("failed to get ls status from inner table", K(tmp_ret), K(tx_start_transfer_in_info)); + } else if (!is_ls_deleted) { + //do nothing + } else if (!for_replay) { + } else if (OB_SUCCESS != (tmp_ret = set_dest_ls_rebuild_(tx_start_transfer_in_info.dest_ls_id_))) { + LOG_WARN("failed to set dest ls rebuild", K(tmp_ret), K(tx_start_transfer_in_info)); + } + } + } else if (OB_ISNULL(src_ls = src_ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", KR(ret), K(src_ls)); + } else if (CLICK_FAIL(src_ls->get_max_decided_scn(max_decided_scn))) { + LOG_WARN("failed to log stream get decided scn", K(ret), K(src_ls), K(tx_start_transfer_in_info)); + } else if (max_decided_scn < tx_start_transfer_in_info.start_scn_) { + ret = OB_EAGAIN; + LOG_WARN("src ls max decided scn is smaller than transfer start scn, need wait", K(ret), K(max_decided_scn), K(tx_start_transfer_in_info)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tx_start_transfer_in_info.tablet_meta_list_.count(); ++i) { + MDS_TG(10_ms); + const ObMigrationTabletParam &tablet_meta = tx_start_transfer_in_info.tablet_meta_list_.at(i); + if (CLICK_FAIL(check_transfer_src_tablet_(for_replay, tablet_meta, src_ls))) { + LOG_WARN("failed to check src tablet", K(ret), K(for_replay), K(tablet_meta)); + } + } + } + return ret; +} + +int ObTabletStartTransferInHelper::check_transfer_src_tablet_( + const bool for_replay, + const ObMigrationTabletParam &tablet_meta, + ObLS *src_ls) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + bool unused_committed_flag = false; + const ObLSID &dest_ls_id = tablet_meta.ls_id_; + + //replay scn need check + if (!tablet_meta.is_valid() || OB_ISNULL(src_ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check src tablete get invalid argument", K(ret), K(tablet_meta), KP(src_ls)); + } else if (CLICK_FAIL(src_ls->get_tablet(tablet_meta.tablet_id_, tablet_handle, 0, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + if (ret == OB_TABLET_NOT_EXIST) { + ret = OB_EAGAIN; + if (!for_replay) { + } else if (OB_SUCCESS != (tmp_ret = set_dest_ls_rebuild_(dest_ls_id))) { + LOG_WARN("failed to set dest ls rebuild", K(tmp_ret), K(dest_ls_id)); + } + } else { + LOG_WARN("failed to get tablet", K(ret), KPC(src_ls), K(tablet_meta)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KPC(src_ls), KP(tablet), K(tablet_meta)); + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::get_latest_tablet_status(user_data, unused_committed_flag))) { + LOG_WARN("failed to get lastest tablet status", K(ret), KPC(tablet), K(tablet_meta)); + } else if (tablet->get_tablet_meta().transfer_info_.transfer_seq_ != tablet_meta.transfer_info_.transfer_seq_ - 1 + || (user_data.tablet_status_ != ObTabletStatus::TRANSFER_OUT + && user_data.tablet_status_ != ObTabletStatus::TRANSFER_OUT_DELETED)) { + ret = OB_EAGAIN; + LOG_WARN("src ls tablet not ready, need retry", K(ret), K(user_data), K(tablet_meta)); + if (!for_replay) { + } else if (OB_SUCCESS != (tmp_ret = set_dest_ls_rebuild_(dest_ls_id))) { + LOG_WARN("failed to set dest ls rebuild", K(tmp_ret), K(dest_ls_id)); + } + } + return ret; +} + +int ObTabletStartTransferInHelper::create_transfer_in_tablets_( + const share::SCN &scn, + const bool for_replay, + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + mds::BufferCtx &ctx) +{ + MDS_TG(500_ms); + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObLSHandle dest_ls_handle; + ObLS *dest_ls = NULL; + ObLSService* ls_srv = nullptr; + ObArray tablet_id_array; + + if ((!scn.is_valid() && for_replay) || !tx_start_transfer_in_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("create transfer in tablet get invalid argument", K(ret), K(scn), K(tx_start_transfer_in_info)); + } else if (OB_ISNULL(ls_srv = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls srv should not be NULL", K(ret), KP(ls_srv)); + } else if (CLICK_FAIL(ls_srv->get_ls(tx_start_transfer_in_info.dest_ls_id_, dest_ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_ERROR("ls_srv->get_ls() fail", KR(ret)); + } else if (OB_ISNULL(dest_ls = dest_ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is NULL", KR(ret), KP(dest_ls)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tx_start_transfer_in_info.tablet_meta_list_.count(); ++i) { + MDS_TG(10_ms); + const ObMigrationTabletParam &tablet_meta = tx_start_transfer_in_info.tablet_meta_list_.at(i); + if (CLICK_FAIL(create_transfer_in_tablet_(scn, for_replay, tablet_meta, dest_ls, ctx, tablet_id_array))) { + LOG_WARN("failed to create transfer in tablet", K(ret), K(tablet_meta)); + } + } + + // roll back operation + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + if (CLICK() && OB_TMP_FAIL(rollback_transfer_in_tablets_(tablet_id_array, dest_ls))) { + LOG_WARN("failed to roll back remove tablets", K(tmp_ret), + K(tx_start_transfer_in_info), K(lbt())); + ob_usleep(1000 * 1000); + ob_abort(); // roll back operation should NOT fail + } + } + } + return ret; +} + + +int ObTabletStartTransferInHelper::create_transfer_in_tablet_( + const share::SCN &scn, + const bool for_replay, + const ObMigrationTabletParam &tablet_meta, + ObLS *dest_ls, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + mds::MdsCtx &user_ctx = static_cast(ctx); + const ObTabletID &tablet_id = tablet_meta.tablet_id_; + const ObTabletMapKey key(dest_ls->get_ls_id(), tablet_id); + bool need_create_tablet = false; + + if (OB_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { + //overwrite ret + if (OB_TABLET_NOT_EXIST == ret) { + need_create_tablet = true; + ret = OB_SUCCESS; + LOG_INFO("need create transfer in tablet", K(key)); + } else { + LOG_WARN("failed to get tablet", K(ret), KPC(dest_ls), K(tablet_meta)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); + } else if (tablet->is_empty_shell() && tablet->get_tablet_meta().transfer_info_.transfer_start_scn_ < tablet_meta.transfer_info_.transfer_start_scn_) { + need_create_tablet = true; + LOG_INFO("need create transfer in tablet", K(key), K(tablet->is_empty_shell())); + } + + if (OB_FAIL(ret)) { + } else if (!need_create_tablet) { + //do nothing + } else if (OB_FAIL(tablet_id_array.push_back(tablet_meta.tablet_id_))) { + LOG_WARN("failed to push tablet id into array", K(ret), K(tablet_meta)); + } else if (OB_FAIL(inner_create_transfer_in_tablet_(scn, for_replay, tablet_meta, dest_ls, tablet_handle))) { + LOG_WARN("failed to create transfer in tablet", K(ret), K(scn), K(for_replay), K(tablet_meta), KPC(dest_ls)); + } + + + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); + } else { + const mds::MdsDumpKV &kv = tablet_meta.mds_data_.tablet_status_uncommitted_kv_; + const common::ObString &str = kv.v_.user_data_; + ObTabletCreateDeleteMdsUserData user_data; + int64_t pos = 0; + if (OB_FAIL(user_data.deserialize(str.ptr(), str.length(), pos))) { + LOG_WARN("failed to deserialize user data", K(ret)); + } else if (OB_UNLIKELY(ObTabletStatus::TRANSFER_IN != user_data.tablet_status_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet status is not TRANSFER_IN", K(ret), K(key), K(user_data)); + } else { + user_data.transfer_scn_ = tablet_meta.transfer_info_.transfer_start_scn_; + } + + if (OB_FAIL(ret)) { + } else if (for_replay) { + if (OB_FAIL(do_for_replay_(scn, user_data, dest_ls->get_ls_id(), tablet_meta.transfer_info_.transfer_start_scn_, + tablet_handle, ctx))) { + LOG_WARN("failed to do for replay", K(ret), K(scn), K(user_data)); + } + } else { + if (OB_FAIL(dest_ls->get_tablet_svr()->set_tablet_status(tablet_id, user_data, user_ctx))) { + LOG_WARN("failed to set mds data", K(ret), K(user_data)); + } + } + + if (OB_SUCC(ret)) { + LOG_INFO("succeeded to create transfer in tablet", K(key), "ls_id", dest_ls->get_ls_id(), K(user_data)); + } +#ifdef ERRSIM + ObTransferEventRecorder::record_tablet_transfer_event("tx_start_transfer_in", + dest_ls->get_ls_id(), tablet->get_tablet_meta().tablet_id_, + tablet->get_tablet_meta().transfer_info_.transfer_seq_, user_data.tablet_status_, + ret); +#endif + } + return ret; +} + +int ObTabletStartTransferInHelper::inner_create_transfer_in_tablet_( + const share::SCN &scn, + const bool for_replay, + const ObMigrationTabletParam &tablet_meta, + ObLS *dest_ls, + ObTabletHandle &tablet_handle) +{ + UNUSED(scn); + UNUSED(for_replay); + int ret = OB_SUCCESS; + if (OB_FAIL(dest_ls->get_tablet_svr()->create_transfer_in_tablet(dest_ls->get_ls_id(), tablet_meta, tablet_handle))) { + LOG_WARN("failed to create transfer in tablet", K(ret), K(tablet_meta), KPC(dest_ls)); + } + return ret; +} + +int ObTabletStartTransferInHelper::rollback_transfer_in_tablets_( + const common::ObIArray &tablet_id_array, + ObLS *dest_ls) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_id_array.count(); ++i) { + const ObTabletID &tablet_id = tablet_id_array.at(i); + if (OB_FAIL(rollback_transfer_in_tablet_(tablet_id, dest_ls))) { + LOG_WARN("failed to rollback transfer in tablet", K(ret), K(tablet_id_array)); + } + } + return ret; +} + +int ObTabletStartTransferInHelper::rollback_transfer_in_tablet_( + const common::ObTabletID &tablet_id, + ObLS *dest_ls) +{ + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + const ObTabletMapKey key(dest_ls->get_ls_id(), tablet_id); + ObTabletHandle tablet_handle; + + // Try figure out if tablet needs to dec memtable ref or not + if (OB_FAIL(dest_ls->get_tablet(tablet_id, tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + if (OB_TABLET_NOT_EXIST == ret || OB_ITEM_NOT_SETTED == ret) { + // tablet does not exist or tablet creation failed on half way, do nothing + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), KPC(dest_ls), K(tablet_id)); + } + } else if (OB_FAIL(dest_ls->get_tablet_svr()->rollback_tablet(dest_ls->get_ls_id(), tablet_id))) { + LOG_WARN("failed to rollback tablet", K(ret), K(dest_ls), K(tablet_id)); + } + return ret; +} + +int ObTabletStartTransferInHelper::on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObTXStartTransferInInfo tx_start_transfer_in_info; + int64_t pos = 0; + bool skip_replay = false; + ObTransferService *transfer_service = nullptr; + + if (OB_ISNULL(buf) || len < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on replay start transfer in get invalid argument", K(ret), KP(buf), K(len)); + } else if (OB_ISNULL(transfer_service = MTL(ObTransferService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(transfer_service)); + } else if (CLICK_FAIL(tx_start_transfer_in_info.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize tx start transfer in info", K(ret), K(len), K(pos)); + } else if (!tx_start_transfer_in_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tx start transfer in info is unexpected", K(ret), K(tx_start_transfer_in_info)); + } else if (CLICK_FAIL(check_can_skip_replay_(scn, tx_start_transfer_in_info, skip_replay))) { + LOG_WARN("failed to check can skip replay", K(ret), K(tx_start_transfer_in_info)); + } else if (skip_replay) { + FLOG_INFO("skip replay start transfer in", K(scn), K(tx_start_transfer_in_info)); + } else if (CLICK_FAIL(on_replay_success_(scn, tx_start_transfer_in_info, ctx))) { + LOG_WARN("failed to do on_replay_success_", K(ret), K(tx_start_transfer_in_info)); + } else if (CLICK_FAIL(ObTabletCreateDeleteMdsUserData::set_tablet_gc_trigger(tx_start_transfer_in_info.dest_ls_id_))) { + LOG_WARN("failed to set_tablet_gc_trigger", K(ret), K(tx_start_transfer_in_info)); + } else { + transfer_service->wakeup(); + } +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("TRANSFER", "AFTER_ON_REDO_START_TRANSFER_IN"); +#endif + DEBUG_SYNC(AFTER_ON_REDO_START_TRANSFER_IN); + return ret; +} + +int ObTabletStartTransferInHelper::on_replay_success_( + const share::SCN &scn, + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + mds::BufferCtx &ctx) +{ + MDS_TG(1_s); + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObLSService *ls_service = nullptr; + ObLS *ls = nullptr; + const bool for_replay = true; + bool can_skip_replay = false; + bool can_skip_check_src = false; + const int64_t start_ts = ObTimeUtil::current_time(); + LOG_INFO("[TRANSFER] start tx start transfer in on_replay_success_", + K(tx_start_transfer_in_info)); +#ifdef ERRSIM + SERVER_EVENT_ADD("transfer", "tx_start_transfer_in", + "stage", "on_replay_success", + "tenant_id", MTL_ID(), + "src_ls_id", tx_start_transfer_in_info.src_ls_id_.id(), + "dest_ls_id", tx_start_transfer_in_info.dest_ls_id_.id(), + "start_scn", tx_start_transfer_in_info.start_scn_); +#endif + + if (!scn.is_valid() || !tx_start_transfer_in_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on replay success get invalid argument", K(ret), K(scn), K(tx_start_transfer_in_info)); + } else if (CLICK_FAIL(check_transfer_dest_tablets_(tx_start_transfer_in_info, for_replay))) { + LOG_WARN("failed to check transfer dest tablets", K(ret), K(tx_start_transfer_in_info)); + } else if (CLICK_FAIL(create_transfer_in_tablets_(scn, for_replay, tx_start_transfer_in_info, ctx))) { + LOG_WARN("failed to create transfer in tablets", K(ret), K(tx_start_transfer_in_info)); + } + + if (OB_FAIL(ret)) { + LOG_WARN("tx start transfer in on_replay_success_ failed", K(ret), K(tx_start_transfer_in_info)); + ret = OB_EAGAIN; + } else { + LOG_INFO("[TRANSFER] finish tx start transfer in on_replay_success_", K(tx_start_transfer_in_info), + K(for_replay), "cost_ts", ObTimeUtil::current_time() - start_ts); + } + return ret; +} + +int ObTabletStartTransferInHelper::do_for_replay_( + const share::SCN &scn, + const ObTabletCreateDeleteMdsUserData &user_data, + const share::ObLSID &ls_id, + const share::SCN &transfer_start_scn, + ObTabletHandle &tablet_handle, + mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + ObTabletStartTransferInReplayExecutor executor; + storage::ObTablet *tablet = tablet_handle.get_obj(); + SCN local_tablet_start_scn; + + if (OB_ISNULL(tablet)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is NULL", K(ret), K(scn), K(user_data), K(ls_id)); + } else if (FALSE_IT(local_tablet_start_scn = tablet->get_tablet_meta().transfer_info_.transfer_start_scn_)) { + } else if (tablet->is_empty_shell()) { + if (local_tablet_start_scn >= transfer_start_scn) { + LOG_INFO("tablet is empty shell and transfer start scn is bigger than transfer in tablet start scn", K(ret), + KPC(tablet), K(transfer_start_scn)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("local tablet is empty shell but transfer start scn is smaller than transfer in", K(ret), KPC(tablet), K(transfer_start_scn)); + } + } else if (local_tablet_start_scn < transfer_start_scn) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("local tablet transfer start scn is smaller than transfer in", K(ret), KPC(tablet), K(transfer_start_scn)); + } else if (local_tablet_start_scn > transfer_start_scn) { + //do nothing + } else if (OB_FAIL(executor.init(scn, user_data, ctx))) { + LOG_WARN("failed to init tablet start transfer in replay executor", K(ret), K(scn), K(user_data), K(tablet_handle)); + } else if (OB_FAIL(executor.execute(scn, ls_id, tablet->get_tablet_meta().tablet_id_))) { + LOG_WARN("failed to do start transfer in replay execute", K(ret), K(scn), K(user_data), K(tablet_handle)); + } + return ret; +} + +int ObTabletStartTransferInHelper::check_can_skip_check_transfer_src_tablet_( + const share::SCN &scn, + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + bool &can_skip) +{ + int ret = OB_SUCCESS; + can_skip = false; + bool is_gts_push = false; + ObLSRestoreStatus restore_status; + // There are 2 cases that source tablets are no need to check ready while replaying transfer in. The following + // order needs to be followed. + // 1. Current ls is in restore, and scn is smaller than consistent_scn; + // 2. GTS is over current log scn, but current ls is in rebuild. + + if (!scn.is_valid() || !tx_start_transfer_in_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check can skip check transfer src tablet get invalid argument", K(ret)); + } else if (OB_FAIL(check_transfer_dest_tablets_ready_(scn, tx_start_transfer_in_info, can_skip))) { + LOG_WARN("failed to check transfer dest tablets ready", K(ret), K(scn), K(tx_start_transfer_in_info)); + } else if (can_skip) { + //do nothing + } else if (OB_FAIL(check_transfer_dest_ls_restore_status_(scn, tx_start_transfer_in_info.dest_ls_id_, can_skip))) { + LOG_WARN("failed to check transfer dest ls restore status", K(ret), K(scn), K(tx_start_transfer_in_info)); + } else if (can_skip) { + //do nothing + } else if (OB_FAIL(check_gts_(scn, is_gts_push))) { + LOG_WARN("failed to check gts", K(ret), K(scn)); + } else if (!is_gts_push) { + can_skip = false; + } else if (OB_FAIL(check_transfer_dest_ls_status_(scn, tx_start_transfer_in_info.dest_ls_id_, can_skip))) { + LOG_WARN("failed to check transfer dest ls status", K(ret), K(tx_start_transfer_in_info)); + } + return ret; +} + +int ObTabletStartTransferInHelper::check_gts_( + const share::SCN &scn, + bool &is_gts_push) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + share::SCN gts_scn; + is_gts_push = false; + + if (!scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check gts get invalid argument", K(ret), K(scn)); + } else if (OB_FAIL(ObTransferUtils::get_gts(tenant_id, gts_scn))) { + LOG_WARN("failed to get gts", K(ret), K(tenant_id), K(scn)); + is_gts_push = false; + //overwrite ret + ret = OB_SUCCESS; + } else if (gts_scn <= scn) { + is_gts_push = false; + LOG_INFO("can not skip check transfer src ls and tablet", K(gts_scn), K(scn)); + } else { + is_gts_push = true; + } + return ret; +} + +int ObTabletStartTransferInHelper::check_transfer_dest_ls_status_( + const share::SCN &scn, + const share::ObLSID &ls_id, + bool &can_skip) +{ + int ret = OB_SUCCESS; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + can_skip = false; + + if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check transfer dest ls status get invalid argument", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get ls", KR(ret), K(ls_id)); + } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", KR(ret), K(ls_id), KP(ls)); + } else if (OB_FAIL(ls->get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), K(ls_id)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_ADD == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD == migration_status) { + can_skip = true; + FLOG_INFO("ls migration status is in add or migrate or rebuild, skip check transfer src ls", + K(ret), K(migration_status), KPC(ls)); + } + return ret; +} + +int ObTabletStartTransferInHelper::check_transfer_dest_ls_restore_status_( + const share::SCN &scn, + const share::ObLSID &ls_id, + bool &can_skip) +{ + int ret = OB_SUCCESS; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObLSRestoreStatus restore_status; + share::SCN consistent_scn; + can_skip = false; + if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check transfer dest ls restore status get invalid argument", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get ls", KR(ret), K(ls_id)); + } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", KR(ret), K(ls_id), KP(ls)); + } else if (OB_FAIL(ls->get_restore_status(restore_status))) { + LOG_WARN("failed to get restore status", K(ret), KPC(ls)); + } else if (restore_status.is_in_restore()) { + if(OB_FAIL(ls->get_ls_restore_handler()->get_consistent_scn(consistent_scn))) { + LOG_WARN("failed to get consistent scn", K(ret)); + } else if (!consistent_scn.is_valid_and_not_min()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid consistent_scn", K(ret), K(consistent_scn)); + } else if (scn <= consistent_scn) { + can_skip = true; + LOG_INFO("ls is in restore, and cur scn is older than restore consistent scn, skip check transfer src ls", + K(ret), K(restore_status), K(consistent_scn), K(scn), KPC(ls)); + } + } + return ret; +} + +int ObTabletStartTransferInHelper::check_transfer_dest_tablets_ready_( + const share::SCN &scn, + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + bool &can_skip) +{ + int ret = OB_SUCCESS; + can_skip = false; + + if (!scn.is_valid() || !tx_start_transfer_in_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check transfer dest tablets ready invalid argument", K(ret), K(scn)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tx_start_transfer_in_info.tablet_meta_list_.count(); ++i) { + const ObMigrationTabletParam &tablet_meta = tx_start_transfer_in_info.tablet_meta_list_.at(i); + if (OB_FAIL(check_transfer_dest_tablet_ready_(tablet_meta, can_skip))) { + LOG_WARN("failed to create transfer in tablet", K(ret), K(tablet_meta)); + } else if (!can_skip) { + break; + } + } + } + return ret; +} + +int ObTabletStartTransferInHelper::check_transfer_dest_tablet_ready_( + const ObMigrationTabletParam &tablet_meta, + bool &can_skip) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + can_skip = false; + SCN local_tablet_start_scn; + SCN transfer_info_scn; + + if (!tablet_meta.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("check transfer dest tablet get invalid argument", K(ret), K(tablet_meta)); + } else { + const ObTabletMapKey key(tablet_meta.ls_id_, tablet_meta.tablet_id_); + if (OB_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + can_skip = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), K(tablet_meta)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(tablet_handle), KP(tablet)); + } else if (FALSE_IT(local_tablet_start_scn = tablet->get_tablet_meta().transfer_info_.transfer_start_scn_)) { + } else if (FALSE_IT(transfer_info_scn = tablet_meta.transfer_info_.transfer_start_scn_)) { + } else if (tablet->is_empty_shell()) { + if (local_tablet_start_scn >= transfer_info_scn) { + can_skip = true; + } else { + can_skip = false; + } + LOG_INFO("tablet is empty shell", KPC(tablet), K(tablet_meta), K(can_skip)); + } else if (local_tablet_start_scn > transfer_info_scn) { + can_skip = true; + } else if (local_tablet_start_scn < transfer_info_scn) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet transfer start scn is not match", K(ret), KPC(tablet), K(tablet_meta)); + } else if (!tablet->get_tablet_meta().has_transfer_table()) { + can_skip = true; + } else { + LOG_INFO("tablet still has transfer table, cannot skip check src tablet", KPC(tablet)); + } + } + return ret; +} + +int ObTabletStartTransferInHelper::set_dest_ls_rebuild_( + const share::ObLSID &dest_ls_id) +{ + int ret = OB_SUCCESS; + ObRebuildService *rebuild_service = nullptr; + const ObLSRebuildType rebuild_type(ObLSRebuildType::TRANSFER); + + if (!dest_ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("set dest ls rebuild get invalid argument", K(ret), K(dest_ls_id)); + } else if (OB_ISNULL(rebuild_service = MTL(ObRebuildService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rebuild should not be null", K(ret), KP(rebuild_service)); + } else if (OB_FAIL(rebuild_service->add_rebuild_ls(dest_ls_id, rebuild_type))) { + LOG_WARN("failed to add rebuild ls", K(ret), K(dest_ls_id), K(rebuild_type)); + } + return ret; +} + +bool ObTabletStartTransferInHelper::check_can_replay_commit( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + bool b_ret = false; + int ret = OB_SUCCESS; + ObTXStartTransferInInfo tx_start_transfer_in_info; + int64_t pos = 0; + bool skip_replay = false; + ObTransferService *transfer_service = nullptr; + bool can_skip_check_src = false; + LOG_INFO("check can replay start transfer in commit", K(scn)); + if (OB_ISNULL(buf) || len < 0 || !scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("on register start transfer in get invalid argument", K(ret), KP(buf), K(len), K(scn)); + } else if (OB_ISNULL(transfer_service = MTL(ObTransferService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be null", K(ret), KP(transfer_service)); + } else if (OB_FAIL(tx_start_transfer_in_info.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize tx start transfer in info", K(ret), K(len), K(pos)); + } else if (!tx_start_transfer_in_info.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tx start transfer in info is unexpected", K(ret), K(tx_start_transfer_in_info)); + } else { + if (OB_FAIL(check_can_skip_check_transfer_src_tablet_(scn, tx_start_transfer_in_info, can_skip_check_src))) { + LOG_WARN("failed to check can skip check transfer src tablet", K(ret), K(tx_start_transfer_in_info)); + } else if (!can_skip_check_src && OB_FAIL(check_transfer_src_tablets_(true /* for replay */, tx_start_transfer_in_info))) { + LOG_WARN("failed to check transfer src tablets", K(ret), K(tx_start_transfer_in_info)); + } + if (OB_FAIL(ret)) { + b_ret = false; + LOG_WARN("start transfer in src tablet not ready, need retry", K(ret), K(scn), K(tx_start_transfer_in_info)); + } else { + b_ret = true; + transfer_service->wakeup(); + } + } + return b_ret; +} + +} +} diff --git a/src/storage/tablet/ob_tablet_start_transfer_mds_helper.h b/src/storage/tablet/ob_tablet_start_transfer_mds_helper.h new file mode 100644 index 000000000..5a93621fa --- /dev/null +++ b/src/storage/tablet/ob_tablet_start_transfer_mds_helper.h @@ -0,0 +1,203 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TABLET_START_TRANSFER_MDS_HELPER +#define OCEANBASE_STORAGE_OB_TABLET_START_TRANSFER_MDS_HELPER + +#include +#include "lib/container/ob_iarray.h" +#include "lib/utility/ob_macro_utils.h" +#include "common/ob_tablet_id.h" + +namespace oceanbase +{ +namespace share +{ +class SCN; +class ObLSID; +struct ObTransferTabletInfo; +} +namespace storage +{ + +namespace mds +{ +struct BufferCtx; +} + +class ObLS; +class ObTablet; +class ObTabletHandle; +class ObTabletCreateDeleteMdsUserData; +class ObTXStartTransferOutInfo; +class ObTXStartTransferInInfo; +class ObMigrationTabletParam; + +class ObTabletStartTransferOutHelper +{ +public: + static int on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx); + static int on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx); +private: + static int on_register_success_( + const ObTXStartTransferOutInfo &tx_start_transfer_out_info, + mds::BufferCtx &ctx); + static int prepare_src_transfer_tablets_( + const ObTXStartTransferOutInfo &tx_start_transfer_out_info, + ObLS *ls); + static int prepare_src_transfer_tablet_( + const share::ObTransferTabletInfo &tablet_info, + ObLS *ls); + static int check_src_transfer_tablet_( + const share::ObLSID &ls_id, + const share::ObTransferTabletInfo &tablet_info, + ObTablet *tablet); + static int update_tablets_transfer_out_( + const ObTXStartTransferOutInfo &tx_start_transfer_out_info, + ObLS *ls, + mds::BufferCtx &ctx); + static int update_tablet_transfer_out_( + const share::ObLSID &dest_ls_id, + const share::ObTransferTabletInfo &tablet_info, + ObLS *ls, + mds::BufferCtx &ctx); + + static int on_replay_success_( + const share::SCN &scn, + const ObTXStartTransferOutInfo &tx_start_transfer_out_info, + mds::BufferCtx &ctx); + static int try_enable_dest_ls_clog_replay( + const share::SCN &scn, + const share::ObLSID &dest_ls_id); + +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletStartTransferOutHelper); +}; + +class ObTabletStartTransferInHelper +{ +public: + static int on_register( + const char* buf, + const int64_t len, + mds::BufferCtx &ctx); + static int on_replay( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx); + static bool check_can_replay_commit( + const char* buf, + const int64_t len, + const share::SCN &scn, + mds::BufferCtx &ctx); +private: + static int on_register_success_( + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + mds::BufferCtx &ctx); + static int check_can_skip_replay_( + const share::SCN &scn, + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + bool &skip_replay); + static int check_transfer_dest_tablets_( + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + const bool for_replay); + static int check_transfer_dest_tablet_( + const ObMigrationTabletParam &tablet_meta, + const bool for_replay, + ObLS *dest_ls); + // TODO:(muwei) donot pass parameter 'for_replay' + static int check_transfer_src_tablets_( + const bool for_replay, + const ObTXStartTransferInInfo &tx_start_transfer_in_info); + static int check_transfer_src_tablet_( + const bool for_replay, + const ObMigrationTabletParam &tablet_meta, + ObLS *src_ls); + static int create_transfer_in_tablets_( + const share::SCN &scn, + const bool for_replay, + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + mds::BufferCtx &ctx); + static int create_transfer_in_tablet_( + const share::SCN &scn, + const bool for_replay, + const ObMigrationTabletParam &tablet_meta, + ObLS *dest_ls, + mds::BufferCtx &ctx, + common::ObIArray &tablet_id_array); + static int rollback_transfer_in_tablets_( + const common::ObIArray &tablet_id_array, + ObLS *dest_ls); + static int rollback_transfer_in_tablet_( + const common::ObTabletID &tablet_id, + ObLS *dest_ls); + + static int inner_create_transfer_in_tablet_( + const share::SCN &scn, + const bool for_replay, + const ObMigrationTabletParam &tablet_meta, + ObLS *dest_ls, + ObTabletHandle &tablet_handle); + + static int on_replay_success_( + const share::SCN &scn, + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + mds::BufferCtx &ctx); + static int do_for_replay_( + const share::SCN &scn, + const ObTabletCreateDeleteMdsUserData &user_data, + const share::ObLSID &ls_id, + const share::SCN &transfer_start_scn, + ObTabletHandle &tablet_handle, + mds::BufferCtx &ctx); + static int check_can_skip_check_transfer_src_tablet_( + const share::SCN &scn, + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + bool &can_skip); + static int check_gts_( + const share::SCN &scn, + bool &can_skip); + static int check_transfer_dest_ls_status_( + const share::SCN &scn, + const share::ObLSID &ls_id, + bool &can_skip); + static int check_transfer_dest_ls_restore_status_( + const share::SCN &scn, + const share::ObLSID &ls_id, + bool &can_skip); + static int check_transfer_dest_tablets_ready_( + const share::SCN &scn, + const ObTXStartTransferInInfo &tx_start_transfer_in_info, + bool &can_skip); + static int check_transfer_dest_tablet_ready_( + const ObMigrationTabletParam &tablet_meta, + bool &can_skip); + static int set_dest_ls_rebuild_( + const share::ObLSID &dest_ls_id); + +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletStartTransferInHelper); +}; + + +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_START_TRANSFER_MDS_HELPER diff --git a/src/storage/tablet/ob_tablet_status.cpp b/src/storage/tablet/ob_tablet_status.cpp index a942d32ee..2a8e71afe 100644 --- a/src/storage/tablet/ob_tablet_status.cpp +++ b/src/storage/tablet/ob_tablet_status.cpp @@ -13,19 +13,12 @@ #define USING_LOG_PREFIX STORAGE #include "storage/tablet/ob_tablet_status.h" - -#include "lib/lock/ob_thread_cond.h" #include "lib/oblog/ob_log_module.h" #include "lib/utility/serialization.h" #include "share/ob_errno.h" -#include "storage/tablet/ob_tablet.h" -#include "storage/tablet/ob_tablet_multi_source_data.h" -#include "storage/tx/ob_trans_define.h" -#include "share/scn.h" namespace oceanbase { -using namespace share; namespace storage { ObTabletStatus::ObTabletStatus() @@ -38,6 +31,28 @@ ObTabletStatus::ObTabletStatus(const Status &status) { } +static const char *TABLET_STATUS_STRS[] = { + "CREATING", + "NORMAL", + "DELETING", + "DELETED", + "TRANSFER_OUT", + "TRANSFER_IN", + "TRANSFER_OUT_DELETED", +}; + +const char *ObTabletStatus::get_str(const ObTabletStatus &status) +{ + const char *str = NULL; + + if (status.status_ < 0 || status.status_ >= ObTabletStatus::MAX) { + str = "UNKNOWN"; + } else { + str = TABLET_STATUS_STRS[status.status_]; + } + return str; +} + int ObTabletStatus::serialize(char *buf, const int64_t len, int64_t &pos) const { int ret = OB_SUCCESS; @@ -92,7 +107,8 @@ bool ObTabletStatus::is_valid_status(const Status current_status, const Status t } break; case NORMAL: - if (target_status != DELETING && target_status != NORMAL) { + if (target_status != DELETING && target_status != NORMAL + && target_status != TRANSFER_OUT && target_status != TRANSFER_IN) { b_ret = false; } break; @@ -109,6 +125,21 @@ bool ObTabletStatus::is_valid_status(const Status current_status, const Status t b_ret = false; } break; + case TRANSFER_OUT: + if (target_status != NORMAL && target_status != TRANSFER_OUT_DELETED && target_status != TRANSFER_OUT) { + b_ret = false; + } + break; + case TRANSFER_IN: + if (target_status != NORMAL && target_status != DELETED && target_status != TRANSFER_IN) { + b_ret = false; + } + break; + case TRANSFER_OUT_DELETED: + if (target_status != DELETED && target_status != TRANSFER_OUT_DELETED && target_status != TRANSFER_OUT_DELETED) { + b_ret = false; + } + break; default: b_ret = false; break; @@ -117,96 +148,5 @@ bool ObTabletStatus::is_valid_status(const Status current_status, const Status t return b_ret; } -ObTabletStatusChecker::ObTabletStatusChecker(ObTablet &tablet) - : tablet_(tablet) -{ -} - -int ObTabletStatusChecker::check(const uint64_t time_us) -{ - int ret = OB_SUCCESS; - common::ObThreadCond &cond = tablet_.get_cond(); - ObThreadCondGuard guard(cond); - - if (OB_FAIL(do_wait(cond, time_us))) { - LOG_WARN("failed to do cond wait", K(ret)); - } - - return ret; -} - -int ObTabletStatusChecker::wake_up( - ObTabletTxMultiSourceDataUnit &tx_data, - const SCN &memtable_scn, - const bool for_replay, - const memtable::MemtableRefOp ref_op) -{ - int ret = OB_SUCCESS; - common::ObThreadCond &cond = tablet_.get_cond(); - ObThreadCondGuard guard(cond); - - if (OB_FAIL(tablet_.set_tablet_final_status(tx_data, memtable_scn, for_replay, ref_op))) { - LOG_WARN("failed to set tablet status", K(ret), K(tx_data), K(memtable_scn), - K(for_replay), K(ref_op)); - } else if (OB_FAIL(cond.broadcast())) { - LOG_WARN("failed to broadcast", K(ret)); - } - - return ret; -} - -int ObTabletStatusChecker::do_wait(common::ObThreadCond &cond, const uint64_t time_us) -{ - int ret = OB_SUCCESS; - const uint64_t tenant_id = MTL_ID(); - const share::ObLSID &ls_id = tablet_.tablet_meta_.ls_id_; - const common::ObTabletID &tablet_id = tablet_.tablet_meta_.tablet_id_; - bool need_wait = true; - ObTabletStatus::Status actual_status = ObTabletStatus::MAX; - - if (OB_FAIL(tablet_.get_tablet_status(actual_status))) { - LOG_WARN("failed to get status", K(ret)); - } else if (ObTabletStatus::NORMAL == actual_status - || ObTabletStatus::DELETED == actual_status) { - need_wait = false; - } else if (ObTabletStatus::CREATING == actual_status - || ObTabletStatus::DELETING == actual_status - || ObTabletStatus::MAX == actual_status) { - need_wait = true; - // MAX status only occurs when tablet is in creating procedure - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected status", K(ret), K(tenant_id), K(ls_id), K(tablet_id), K(actual_status)); - } - - if (OB_FAIL(ret)) { - } else if (!need_wait) { - } else { - while (OB_SUCC(ret) && !is_final_status(actual_status)) { - if (OB_FAIL(tablet_.get_tablet_status(actual_status))) { - LOG_WARN("failed to get status", K(ret)); - } else if (is_final_status(actual_status)) { - break; - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(cond.wait_us(time_us))) { - if (OB_TIMEOUT == ret) { - LOG_WARN("cond wait timeout", K(ret), K(tenant_id), K(ls_id), K(tablet_id), - K(time_us), K(actual_status)); - } else { - LOG_WARN("failed to cond wait", K(ret)); - } - } - } - } - - if (OB_SUCC(ret) && ObTabletStatus::DELETED == actual_status) { - ret = OB_TABLET_NOT_EXIST; - LOG_WARN("tablet does not exist, may be deleted", K(ret), K(actual_status)); - } - - return ret; -} } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_status.h b/src/storage/tablet/ob_tablet_status.h index ebd2ae594..a2aa2cbac 100644 --- a/src/storage/tablet/ob_tablet_status.h +++ b/src/storage/tablet/ob_tablet_status.h @@ -15,38 +15,23 @@ #include #include "lib/utility/ob_print_utils.h" -#include "storage/memtable/ob_memtable.h" namespace oceanbase { -namespace common -{ -class ObThreadCond; -} - -namespace transaction -{ -class ObTransID; -} -namespace share -{ -class SCN; -} - namespace storage { -class ObTablet; -class ObTabletTxMultiSourceDataUnit; - class ObTabletStatus { public: enum Status : uint8_t { - CREATING = 0, - NORMAL, - DELETING, - DELETED, + CREATING = 0, // deprecated after 4.1 + NORMAL = 1, + DELETING = 2, // deprecated after 4.1 + DELETED = 3, + TRANSFER_OUT = 4, + TRANSFER_IN = 5, + TRANSFER_OUT_DELETED = 6, MAX, }; public: @@ -60,6 +45,7 @@ public: operator Status() const; bool is_valid() const; + static const char *get_str(const ObTabletStatus &status); Status &get_status() { return status_; } const Status &get_status() const { return status_; } @@ -100,31 +86,6 @@ inline bool ObTabletStatus::is_valid() const return status_ < Status::MAX; } -class ObTabletStatusChecker -{ -public: - ObTabletStatusChecker(ObTablet &tablet); - ~ObTabletStatusChecker() = default; - ObTabletStatusChecker(const ObTabletStatusChecker&) = delete; - ObTabletStatusChecker &operator=(const ObTabletStatusChecker&) = delete; -public: - int check(const uint64_t time_us); - int wake_up( - ObTabletTxMultiSourceDataUnit &tx_data, - const share::SCN &memtable_scn, - const bool for_replay, - const memtable::MemtableRefOp ref_op); -private: - int do_wait(common::ObThreadCond &cond, const uint64_t time_ms); - static bool is_final_status(const ObTabletStatus::Status &status); -private: - ObTablet &tablet_; -}; - -inline bool ObTabletStatusChecker::is_final_status(const ObTabletStatus::Status &status) -{ - return ObTabletStatus::NORMAL == status || ObTabletStatus::DELETED == status; -} } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_table_store.cpp b/src/storage/tablet/ob_tablet_table_store.cpp old mode 100644 new mode 100755 index 1b63cdad1..53cef709a --- a/src/storage/tablet/ob_tablet_table_store.cpp +++ b/src/storage/tablet/ob_tablet_table_store.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 OceanBase + * 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: @@ -13,39 +13,33 @@ #define USING_LOG_PREFIX STORAGE #define PRINT_TS(x) (ObPrintTableStore(x)) -#include "lib/oblog/ob_log_module.h" -#include "share/ob_force_print_log.h" #include "storage/compaction/ob_partition_merge_policy.h" -#include "storage/ob_i_memtable_mgr.h" -#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/tablet/ob_tablet.h" #include "storage/tablet/ob_tablet_table_store.h" +#include "storage/tablet/ob_tablet_table_store_iterator.h" +#include "storage/blocksstable/ob_sstable.h" +#include "storage/blocksstable/ob_storage_cache_suite.h" +#include "storage/memtable/ob_memtable.h" #include "share/scn.h" #include "lib/container/ob_array_iterator.h" #include "storage/meta_mem/ob_tablet_pointer.h" #include "storage/ddl/ob_tablet_ddl_kv.h" #include "storage/concurrency_control/ob_multi_version_garbage_collector.h" -using namespace oceanbase; -using namespace oceanbase::blocksstable; -using namespace oceanbase::common; +namespace oceanbase +{ +using namespace blocksstable; using namespace oceanbase::share; -using namespace oceanbase::storage; -using namespace oceanbase::memtable; -using namespace oceanbase::share::schema; -using compaction::ObPartitionMergePolicy; -using compaction::ObAdaptiveMergePolicy; +namespace storage +{ - -/* ObTabletTableStore Section */ ObTabletTableStore::ObTabletTableStore() - : tablet_ptr_(nullptr), + : version_(TABLE_STORE_VERSION_V2), major_tables_(), minor_tables_(), ddl_sstables_(), - extend_tables_(), + meta_major_tables_(), memtables_(), - read_cache_(), - version_(TABLE_STORE_VERSION), is_ready_for_read_(false), is_inited_(false) { @@ -58,15 +52,14 @@ ObTabletTableStore::~ObTabletTableStore() void ObTabletTableStore::reset() { - major_tables_.destroy(); - minor_tables_.destroy(); - ddl_sstables_.destroy(); - extend_tables_.destroy(); - memtables_.destroy(); - ddl_mem_sstables_.destroy(); - read_cache_.reset(); + // all sub structs of table store will not actively release memory on reset + major_tables_.reset(); + minor_tables_.reset(); + ddl_sstables_.reset(); + meta_major_tables_.reset(); + memtables_.reset(); + ddl_mem_sstables_.reset(); is_ready_for_read_ = false; - tablet_ptr_ = nullptr; is_inited_ = false; } @@ -74,78 +67,74 @@ int ObTabletTableStore::serialize(char *buf, const int64_t buf_len, int64_t &pos { int ret = OB_SUCCESS; int64_t serialized_length = get_serialize_size(); - if (IS_NOT_INIT) { ret = OB_NOT_INIT; - LOG_ERROR("table store not init", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(NULL == buf || buf_len <= 0 || pos < 0)) { + LOG_WARN("not inited", K(ret)); + } else if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len < 0)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid arguments", KP(buf), K(buf_len), K(ret)); + LOG_WARN("invalid arguments", K(ret), K(buf_len)); } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, version_))) { LOG_WARN("failed to serialize table_store_version", K(ret)); } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, serialized_length))) { LOG_WARN("failed to seriazlie serialized_length", K(ret)); - } else if (OB_FAIL(major_tables_.serialize(buf, buf_len, pos))) { - LOG_WARN("failed to serialize major_tables", K(ret)); - } else if (OB_FAIL(minor_tables_.serialize(buf, buf_len, pos))) { - LOG_WARN("failed to serialize minor_tables", K(ret)); - } else if (OB_FAIL(ddl_sstables_.serialize(buf, buf_len, pos))) { - LOG_WARN("failed to serialize ddl_sstables_", K(ret)); - } else if (OB_FAIL(extend_tables_.serialize(buf, buf_len, pos))) { - LOG_WARN("failed to serialize extend_tables", K(ret)); + } else { + LST_DO_CODE(OB_UNIS_ENCODE, + major_tables_, + minor_tables_, + ddl_sstables_, + meta_major_tables_); } return ret; } int ObTabletTableStore::deserialize( - common::ObIAllocator &allocator, - ObTablet *tablet, + ObArenaAllocator &allocator, + const ObTablet &tablet, const char *buf, const int64_t data_len, int64_t &pos) { int ret = OB_SUCCESS; + const int start_pos = pos; int64_t serialized_length = 0; - if (IS_INIT) { ret = OB_INIT_TWICE; - LOG_WARN("cannot deserialize inited ObTabletTableStore", K(ret), K_(is_inited)); - } else if (OB_UNLIKELY(NULL == tablet || NULL == buf || data_len <= 0 || pos < 0)) { + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(buf) || OB_UNLIKELY(data_len < 0 || data_len < pos)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid arguments", K(ret), KP(tablet), KP(buf), K(data_len)); - } else if (OB_FAIL(init(allocator, tablet))) { - LOG_WARN("failed to init an empty Table Store before deserializing", K(ret)); + LOG_WARN("invalid argument", K(ret)); } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &version_))) { LOG_WARN("failed to deserialize table_store_version", K(ret)); - } else if (version_ != TABLE_STORE_VERSION) { + } else if (OB_UNLIKELY(version_ != TABLE_STORE_VERSION_V1 && version_ != TABLE_STORE_VERSION_V2)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("version_ must be equal to TABLE_STORE_VERSION", K(ret), K(version_)); + LOG_WARN("unexpected deserialized version", K(ret), K(data_len), K(pos), K_(version), KPHEX(buf, data_len)); } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &serialized_length))) { LOG_WARN("failed to deserialize serialized_length", K(ret)); } else if (OB_FAIL(major_tables_.deserialize(allocator, buf, data_len, pos))) { - LOG_WARN("failed to deserialize major_tables", K(ret)); + LOG_WARN("fail to deserialize major sstables", K(ret)); } else if (OB_FAIL(minor_tables_.deserialize(allocator, buf, data_len, pos))) { - LOG_WARN("failed to deserialize minor_tables", K(ret)); + LOG_WARN("fail to deserialize minor sstables", K(ret)); } else if (OB_FAIL(ddl_sstables_.deserialize(allocator, buf, data_len, pos))) { - LOG_WARN("failed to deserialize ddl_sstables_", K(ret)); - } else if (OB_FAIL(extend_tables_.deserialize(allocator, buf, data_len, pos))) { - LOG_WARN("failed to deserialize extend_tables", K(ret)); - } else if (OB_FAIL(pull_memtables())) { - LOG_WARN("failed to pull memtable from memtable_mgr", K(ret)); - } else if (OB_FAIL(pull_ddl_memtables(allocator))) { + LOG_WARN("fail to deserialize ddl sstables", K(ret)); + } else if (OB_FAIL(meta_major_tables_.deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("fail to deserialize extend sstables", K(ret)); + } else if (OB_FAIL(build_memtable_array(tablet))) { + LOG_WARN("fail to pull memtables from tablet", K(ret)); + } else if (OB_FAIL(pull_ddl_memtables(allocator, tablet))) { LOG_WARN("pull_ddl_memtables failed", K(ret)); - } else if (OB_FAIL(check_ready_for_read())) { - LOG_WARN("failed to check ready for read", K(ret)); + } else if (OB_UNLIKELY(pos - start_pos != serialized_length)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected deserialization length not match", K(ret), K(pos), K(start_pos), K(serialized_length)); } else { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = init_read_cache())) { - LOG_WARN("failed to init read cache iterator", K(tmp_ret)); + version_ = TABLE_STORE_VERSION_V2; + is_inited_ = true; + if (OB_FAIL(check_ready_for_read(tablet))) { + LOG_WARN("fail to check if tablet is ready for read", K(ret)); } if (!memtables_.empty()) { FLOG_INFO("succeed to deserialize table store", K(major_tables_), K(minor_tables_), K(memtables_), K(PRINT_TS(*this))); } } - return ret; } @@ -154,187 +143,255 @@ int64_t ObTabletTableStore::get_serialize_size() const int64_t len = 0; len += serialization::encoded_length_i64(version_); len += serialization::encoded_length_i64(len); - len += major_tables_.get_serialize_size(); - len += minor_tables_.get_serialize_size(); - len += ddl_sstables_.get_serialize_size(); - len += extend_tables_.get_serialize_size(); + LST_DO_CODE(OB_UNIS_ADD_LEN, + major_tables_, + minor_tables_, + ddl_sstables_, + meta_major_tables_); return len; } int ObTabletTableStore::init( - ObIAllocator &allocator, - ObTablet *tablet, - ObTableHandleV2 * const handle) + ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObSSTable *sstable) { int ret = OB_SUCCESS; if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("ObTabletTableStore init twice", K(ret), K(*this)); - } else if (OB_ISNULL(tablet) || OB_ISNULL(tablet->get_memtable_mgr())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("Invalid arguments to init ObTabletTableStore", K(ret), KP(tablet)); - } else if (OB_FAIL(extend_tables_.init(allocator, EXTEND_CNT))) { - LOG_WARN("Failed to init extend tables array", K(ret)); - } else if (OB_FAIL(memtables_.init(&allocator))) { - LOG_WARN("Failed to init memtable array", K(ret)); + } else if (OB_ISNULL(sstable)) { + // skip + } else if (OB_FAIL(build_memtable_array(tablet))) { + LOG_WARN("failed to build memtable array", K(ret)); + } else if (OB_UNLIKELY(!sstable->is_major_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table", K(ret), KPC(sstable)); + } else if (OB_FAIL(major_tables_.init(allocator, sstable))) { + LOG_WARN("failed to init major tables", K(ret)); } else { - tablet_ptr_ = tablet; - } - - if (OB_SUCC(ret) && OB_NOT_NULL(handle) && handle->is_valid()) { // init sstables when first creating tablet - ObSEArray memtable_handles; - if (tablet->get_memtable_mgr()->has_memtable()) { - if (OB_FAIL(tablet->get_memtable_mgr()->get_all_memtables(memtable_handles))) { - LOG_WARN("failed to get all memtables from memtable_mgr", K(ret)); - } else if (OB_FAIL(memtables_.build(memtable_handles))) { - LOG_WARN("failed to build memtable array", K(ret)); - } else { - LOG_INFO("success to pull memtables when first creating tablet", K(ret), K(*this)); - } - } - if (OB_FAIL(ret)) { - } else if (OB_ISNULL(handle->get_table()) || !handle->get_table()->is_major_sstable()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Unexpected table handle", K(ret), KPC(handle->get_table())); - } else if (OB_FAIL(major_tables_.init(allocator, 1))) { - LOG_WARN("Failed to init major tables", K(ret)); - } else if (OB_FAIL(major_tables_.assign(0, handle->get_table()))) { - LOG_WARN("Failed to add table to major_tables", K(ret)); - } else { - is_ready_for_read_ = true; // exist major sstable and no minor sstable, must be ready for read - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = init_read_cache())) { - LOG_WARN("failed to init read cache, just skip", K(tmp_ret)); - } + is_ready_for_read_ = true; // exist major sstable and no minor sstable, must be ready for read + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_cache_local_sstables(allocator))) { + LOG_WARN("failed to cache local sstables", K(tmp_ret)); } } if (OB_SUCC(ret)) { is_inited_ = true; - } else if (OB_UNLIKELY(!is_inited_)) { - reset(); } return ret; } int ObTabletTableStore::init( - ObIAllocator &allocator, - ObTablet *tablet, + ObArenaAllocator &allocator, + const ObTablet &tablet, const ObUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!param.is_valid() || !old_store.is_valid())) { + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid() || !old_store.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid arguments", K(ret), K(param), K(old_store)); - } else if (OB_FAIL(init(allocator, tablet))) { - LOG_WARN("failed to init a new empty table store", K(ret), K(old_store)); - } else if (OB_FAIL(build_new_table_store(allocator, param, old_store))) { + } else if (OB_FAIL(build_new_table_store(allocator, tablet, param, old_store))) { LOG_WARN("failed to build new table store with old store", K(ret), K(old_store), K(*this)); } return ret; } -int ObTabletTableStore::build_ha_new_table_store( - common::ObIAllocator &allocator, - ObTablet *tablet, - const ObBatchUpdateTableStoreParam ¶m, - const ObTabletTableStore &old_store) +int ObTabletTableStore::init( + ObArenaAllocator &allocator, + common::ObIArray &sstable_array, + common::ObIArray &addr_array) { int ret = OB_SUCCESS; - if (OB_ISNULL(tablet) || !param.is_valid() || !old_store.is_valid()) { + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_UNLIKELY(sstable_array.count() != addr_array.count())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("init tablet table store get invalid argument", K(ret), KP(tablet), K(param), K(old_store)); - } else if (OB_FAIL(init(allocator, tablet))) { - LOG_WARN("failed to init a new empty table store", K(ret)); - } else if (OB_FAIL(build_ha_new_table_store_(allocator, param, old_store))) { - LOG_WARN("failed to build new table store with old store", K(ret)); + LOG_WARN("invalid sstable array", K(ret), K(sstable_array.count()), K(addr_array.count())); + } else { + int64_t meta_major_start_pos = -1, major_start_pos = -1, minor_start_pos = -1, ddl_start_pos = -1; + int64_t meta_major_cnt = 0, major_cnt = 0, minor_cnt = 0, ddl_cnt = 0; + // traverse sstable array and mark boundary for different type of sstables + for (int64_t i = 0; OB_SUCC(ret) && i < sstable_array.count(); ++i) { + ObITable *table = sstable_array.at(i); + if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null table pointer", K(ret)); + } else if (table->is_meta_major_sstable()) { + if (OB_UNLIKELY(0 != i || meta_major_cnt != 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("encounter a meta major sstable at not-first position in iter", K(ret), K(i)); + } else { + meta_major_start_pos = 0; + ++meta_major_cnt; + } + } else if (table->is_major_sstable()) { + if (OB_UNLIKELY(0 != minor_cnt || 0 != ddl_cnt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("encounter a major sstable after minor/ddl sstable is iterated", + K(ret), K(sstable_array), K(addr_array)); + } else { + major_start_pos = 0 == major_cnt ? i : major_start_pos; + ++major_cnt; + } + } else if (table->is_minor_sstable()) { + if (OB_UNLIKELY(0 != ddl_cnt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("encounter a minor sstable after ddl sstables", + K(ret), K(sstable_array), K(addr_array)); + } else { + minor_start_pos = 0 == minor_cnt ? i : minor_start_pos; + ++minor_cnt; + } + } else if (table->is_ddl_sstable()) { + ddl_start_pos = 0 == ddl_cnt ? i : ddl_start_pos; + ++ddl_cnt; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table type to init table store for serialize", K(ret), KPC(table)); + } + } + + if (OB_FAIL(ret)) { + } else if (0 != meta_major_cnt && OB_FAIL(meta_major_tables_.init( + allocator, sstable_array, addr_array, meta_major_start_pos, meta_major_cnt))) { + LOG_WARN("fail to init meta major tables for serialize", K(ret), K(sstable_array), K(addr_array)); + } else if (0 != major_cnt && OB_FAIL(major_tables_.init( + allocator, sstable_array, addr_array, major_start_pos, major_cnt))) { + LOG_WARN("fail to init major sstables for serialize", K(ret), K(major_start_pos), + K(major_cnt), K(sstable_array), K(addr_array)); + } else if (0 != minor_cnt && OB_FAIL(minor_tables_.init( + allocator, sstable_array, addr_array, minor_start_pos, minor_cnt))) { + LOG_WARN("fail to init minor sstables for serialize", K(ret), K(sstable_array), K(addr_array)); + } else if (0 != ddl_cnt && OB_FAIL(ddl_sstables_.init( + allocator, sstable_array, addr_array, ddl_start_pos, ddl_cnt))) { + LOG_WARN("fail to init ddl sstables for serialize", K(ret), K(sstable_array), K(addr_array)); + } else { + is_ready_for_read_ = false; // can not read temp table store for serialize + is_inited_ = true; + } } return ret; } -int ObTabletTableStore::batch_replace_sstables( - common::ObIAllocator &allocator, - ObTablet *tablet, - const ObIArray &table_handles, +int ObTabletTableStore::init( + ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObIArray &replace_sstable_array, const ObTabletTableStore &old_store) { int ret = OB_SUCCESS; - if (OB_ISNULL(tablet) || !old_store.is_valid()) { + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_UNLIKELY(!old_store.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("init tablet table store get invalid argument", K(ret), KP(tablet), K(old_store)); - } else if (OB_FAIL(init(allocator, tablet))) { - LOG_WARN("failed to init a new empty table store", K(ret)); - } else if (OB_FAIL(inner_replace_sstables(allocator, table_handles, old_store))) { + LOG_WARN("init tablet table store get invalid argument", K(ret), K(tablet), K(old_store)); + } else if (OB_FAIL(inner_replace_sstables(allocator, replace_sstable_array, old_store))) { LOG_WARN("failed to build new table store with old store", K(ret)); + } else if (OB_FAIL(build_memtable_array(tablet))) { + LOG_WARN("failed to pull memtable from memtable_mgr", K(ret)); + } else if (OB_FAIL(pull_ddl_memtables(allocator, tablet))) { + LOG_WARN("pull_ddl_memtables failed", K(ret)); + } else { + is_inited_ = true; + if (OB_FAIL(check_ready_for_read(tablet))) { + LOG_WARN("failed to check ready for read", K(ret)); + } else { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_cache_local_sstables(allocator))) { + LOG_WARN("failed to cache local sstables", K(tmp_ret)); + } + FLOG_INFO("succeed to batch replace table store", K(major_tables_), K(minor_tables_), K(memtables_), K(PRINT_TS(*this))); + } + } + return ret; +} + +int ObTabletTableStore::init( + ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObTabletTableStore &old_store) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_UNLIKELY(!old_store.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("init tablet table store get invalid argument", K(ret), K(tablet), K(old_store)); + } else if (OB_FAIL(build_memtable_array(tablet))) { + LOG_WARN("failed to build memtable array", K(ret)); + } else if (OB_FAIL(pull_ddl_memtables(allocator, tablet))) { + LOG_WARN("pull_ddl_memtables failed", K(ret)); + } else if (OB_FAIL(major_tables_.init(allocator, old_store.major_tables_))) { + LOG_WARN("failed to init major tables", K(ret), K(old_store.major_tables_)); + } else if (OB_FAIL(minor_tables_.init(allocator, old_store.minor_tables_))) { + LOG_WARN("failed to init minor tables", K(ret), K(old_store.minor_tables_)); + } else if (OB_FAIL(ddl_sstables_.init(allocator, old_store.ddl_sstables_))) { + LOG_WARN("failed to init ddl tables", K(ret), K(old_store.ddl_sstables_)); + } else if (OB_FAIL(meta_major_tables_.init(allocator, old_store.meta_major_tables_))) { + LOG_WARN("failede to init meta major tables", K(ret), K(old_store.meta_major_tables_)); + } else { + is_inited_ = true; + if (OB_FAIL(check_ready_for_read(tablet))) { + LOG_WARN("failed to check ready for read", K(ret)); + } else { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_cache_local_sstables(allocator))) { + LOG_WARN("failed to cache read iterator", K(tmp_ret)); + } + FLOG_INFO("succeed to assign table store", K(ret), K(PRINT_TS(*this))); + } } return ret; } int ObTabletTableStore::inner_replace_sstables( - common::ObIAllocator &allocator, - const ObIArray &table_handles, + common::ObArenaAllocator &allocator, + const ObIArray &replace_sstable_array, const ObTabletTableStore &old_store) { int ret = OB_SUCCESS; - const ObITableArray &old_extend = old_store.extend_tables_; // check table key first - ObTableHandleV2 tmp_handle; - for (int64_t i = 0; OB_SUCC(ret) && i < table_handles.count(); ++i) { - const ObITable *table = table_handles.at(i).get_table(); + ObITable *tmp_table = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && i < replace_sstable_array.count(); ++i) { + const ObITable *table = replace_sstable_array.at(i); if (OB_UNLIKELY(nullptr == table || !table->is_sstable())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table must be sstable", K(ret), KPC(table)); - } else if (OB_FAIL(old_store.get_table(table->get_key(), tmp_handle))) { + } else if (OB_FAIL(old_store.get_table(table->get_key(), tmp_table))) { LOG_WARN("failed to get the same key sstable in old store", K(ret), KPC(table), K(old_store)); } } - ObSEArray major_tables; - ObSEArray minor_tables; - ObSEArray ddl_sstables; - ObSEArray ddl_mem_sstables; + if (OB_FAIL(ret)) { - } else if (OB_FAIL(get_replaced_tables(table_handles, old_store.major_tables_, major_tables))) { + } else if (OB_FAIL(replace_sstables(allocator, replace_sstable_array, old_store.major_tables_, major_tables_))) { LOG_WARN("failed to get replaced major tables", K(ret)); - } else if (OB_FAIL(get_replaced_tables(table_handles, old_store.minor_tables_, minor_tables))) { + } else if (OB_FAIL(replace_sstables(allocator, replace_sstable_array, old_store.minor_tables_, minor_tables_))) { LOG_WARN("failed to get replaced minor tables", K(ret)); - } else if (OB_FAIL(get_replaced_tables(table_handles, old_store.ddl_sstables_, ddl_sstables))) { - LOG_WARN("failed to get replaced ddl sstables", K(ret)); - } else if (OB_FAIL(get_replaced_tables(table_handles, old_store.ddl_mem_sstables_, ddl_mem_sstables))) { - LOG_WARN("failed to get replaced ddl memtables", K(ret)); - } else if (!major_tables.empty() && OB_FAIL(major_tables_.init_and_copy(allocator, major_tables))) { - LOG_WARN("failed to init major tables", K(ret)); - } else if (!minor_tables.empty() && OB_FAIL(minor_tables_.init_and_copy(allocator, minor_tables))) { - LOG_WARN("failed to init minor tables", K(ret)); - } else if (!ddl_sstables.empty() && OB_FAIL(ddl_sstables_.init_and_copy(allocator, ddl_sstables))) { - LOG_WARN("failed to init ddl tables", K(ret)); - } else if (nullptr != old_extend[META_MAJOR] && OB_FAIL(extend_tables_.assign(META_MAJOR, old_extend[META_MAJOR]))) { - LOG_WARN("failed to build buf minor table", K(ret), K(old_extend)); - } else if (OB_FAIL(pull_memtables())) { - LOG_WARN("failed to pull memtable from memtable_mgr", K(ret)); - } else if (OB_FAIL(pull_ddl_memtables(allocator))) { - LOG_WARN("pull_ddl_memtables failed", K(ret)); - } else if (OB_FAIL(check_ready_for_read())) { - LOG_WARN("failed to check ready for read", K(ret)); - } else { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = init_read_cache())) { - if (OB_SNAPSHOT_DISCARDED != tmp_ret) { - LOG_WARN("failed to cache read iterator", K(tmp_ret)); - } - } - FLOG_INFO("succeed to batch replace table store", K(major_tables_), K(minor_tables_), K(memtables_), K(PRINT_TS(*this))); + } else if (OB_FAIL(replace_sstables(allocator, replace_sstable_array, old_store.ddl_sstables_, ddl_sstables_))) { + LOG_WARN("failed to get replaced ddl tables", K(ret)); + } else if (OB_FAIL(meta_major_tables_.init(allocator, old_store.meta_major_tables_))) { + LOG_WARN("failed to init meta major tables for new table store", K(ret)); } return ret; } -int ObTabletTableStore::get_replaced_tables( - const ObIArray &table_handles, - const ObITableArray &old_tables, - ObSEArray &replaced_tables) const +int ObTabletTableStore::replace_sstables( + common::ObArenaAllocator &allocator, + const ObIArray &replace_sstable_array, + const ObSSTableArray &old_tables, + ObSSTableArray &new_tables) const { int ret = OB_SUCCESS; - replaced_tables.reset(); + ObSEArray replaced_tables; if (OB_FAIL(old_tables.get_all_tables(replaced_tables))) { LOG_WARN("failed to get all table from old tables", K(ret), K(old_tables)); } @@ -344,282 +401,302 @@ int ObTabletTableStore::get_replaced_tables( ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null table", K(ret), K(replaced_tables)); } - for (int64_t pos = 0; OB_SUCC(ret) && pos < table_handles.count(); ++pos) { - if (table->get_key() == table_handles.at(pos).get_table()->get_key()) { - replaced_tables[idx] = const_cast(table_handles.at(pos).get_table()); + + for (int64_t pos = 0; OB_SUCC(ret) && pos < replace_sstable_array.count(); ++pos) { + if (table->get_key() == replace_sstable_array.at(pos)->get_key()) { + replaced_tables.at(idx) = replace_sstable_array.at(pos); break; } } } - return ret; -} - -int ObTabletTableStore::get_table(const ObITable::TableKey &table_key, ObTableHandleV2 &handle) const -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table store is unexpected invalid", K(ret), KPC(this)); - } else if (OB_UNLIKELY(!table_key.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(table_key)); - } else { - handle.reset(); - if (OB_FAIL(major_tables_.get_table(table_key, handle))) { - LOG_WARN("failed to get table", K(ret), K(table_key)); - } else if (!handle.is_valid() && OB_FAIL(minor_tables_.get_table(table_key, handle))) { - LOG_WARN("failed to get table", K(ret), K(table_key)); - } else if (!handle.is_valid() && OB_FAIL(ddl_sstables_.get_table(table_key, handle))) { - LOG_WARN("failed to get table", K(ret), K(table_key)); - } else if (!handle.is_valid() && OB_FAIL(extend_tables_.get_table(table_key, handle))) { - LOG_WARN("failed to get table", K(ret), K(table_key)); - } else if (!handle.is_valid() && OB_FAIL(memtables_.find(table_key, handle))) { - LOG_WARN("failed to get table", K(ret), K(table_key)); - } else if (!handle.is_valid() && OB_FAIL(ddl_mem_sstables_.get_table(table_key, handle))) { - LOG_WARN("failed to get table", K(ret), K(table_key)); - } - - if (OB_SUCC(ret)) { - if (OB_UNLIKELY(!handle.is_valid())) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("not found table", K(ret), K(table_key), K(handle)); - } - } - } - return ret; -} - -int ObTabletTableStore::get_first_frozen_memtable(ObITable *&table) -{ - int ret = OB_SUCCESS; - for (int64_t i = 0; OB_SUCC(ret) && i < memtables_.count(); ++i) { - if (OB_ISNULL(memtables_[i])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("memtable must not null", K(ret), K(memtables_)); - } else if (memtables_[i]->is_frozen_memtable()) { - table = memtables_[i]; - break; - } - } - return ret; -} - -int ObTabletTableStore::get_memtables(ObIArray &memtables, const bool need_active) const -{ - int ret = OB_SUCCESS; - for (int64_t i = 0; OB_SUCC(ret) && i < memtables_.count(); ++i) { - if (OB_ISNULL(memtables_.get_table(i))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("memtable must not null", K(ret), K(memtables_)); - } else if (!need_active && memtables_.get_table(i)->is_active_memtable()) { - continue; - } else if (OB_FAIL(memtables.push_back(memtables_.get_table(i)))) { - LOG_WARN("failed to add memtables", K(ret), K(*this)); - } - } - return ret; -} - -int ObTabletTableStore::prepare_memtables() -{ - return memtables_.prepare_allocate(); -} - -int ObTabletTableStore::update_memtables() -{ - int ret = OB_SUCCESS; - ObTableHandleArray inc_memtables; - ObTimeGuard time_guard("ObTabletTableStore::update_memtables", 5 * 1000); - - if (OB_ISNULL(tablet_ptr_) || OB_ISNULL(tablet_ptr_->get_memtable_mgr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected tablet_ptr or memtable_mgr", K(ret), KP(tablet_ptr_)); - } else if (!tablet_ptr_->get_memtable_mgr()->has_memtable()) { - LOG_INFO("no memtable in memtable mgr", K(ret)); - } else if (FALSE_IT(time_guard.click("has_memtable"))) { - } else if (OB_FAIL(tablet_ptr_->get_memtable_mgr()->get_all_memtables(inc_memtables))) { - LOG_WARN("failed to get all memtables from memtable_mgr", K(ret)); - } else if (FALSE_IT(time_guard.click("get_all_memtable"))) { - } else if (tablet_ptr_->is_ls_inner_tablet() && OB_FAIL(memtables_.rebuild(inc_memtables))) { - LOG_ERROR("failed to rebuild table store memtables for ls inner tablet", K(ret), K(inc_memtables), KPC(this)); - } else if (!tablet_ptr_->is_ls_inner_tablet() && !memtables_.empty() && OB_FAIL(memtables_.rebuild(inc_memtables))) { - LOG_ERROR("failed to rebuild table store memtables for normal tablet when current memtable exists", K(ret), K(inc_memtables), KPC(this)); - } else if (!tablet_ptr_->is_ls_inner_tablet() && memtables_.empty() && OB_FAIL(memtables_.rebuild(tablet_ptr_->get_clog_checkpoint_scn(), inc_memtables))) { - LOG_ERROR("failed to rebuild table store memtables for normal tablet when current memtable does not exist", K(ret), - "clog_checkpoint_scn", tablet_ptr_->get_clog_checkpoint_scn(), - K(inc_memtables), KPC(this)); - } else if (FALSE_IT(time_guard.click("memtables_.rebuild"))) { - } else { - int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(init_read_cache())) { - LOG_WARN("failed to rebuild read cache", K(tmp_ret)); - } - time_guard.click("init_read_cache"); - } - return ret; -} - -int ObTabletTableStore::clear_memtables() -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table store is unexpected invalid", K(ret), KPC(this)); - } else { - memtables_.destroy(); - read_cache_.reset(); - } - return ret; -} - -int ObTabletTableStore::init_read_cache() -{ - int ret = OB_SUCCESS; - read_cache_.reset(); - - if (OB_UNLIKELY(is_major_sstable_empty() && minor_tables_.empty() && memtables_.empty())) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("no table in table store, skip init read cache", K(ret), KPC(this)); - } else if (OB_FAIL(calculate_read_tables(read_cache_, INT64_MAX))) { - if (OB_SNAPSHOT_DISCARDED != ret) { - LOG_WARN("failed to init read_cache", K(ret)); - } - } else if (OB_FAIL(read_cache_.set_retire_check())) { - LOG_WARN("failed to set retire check to iterator", K(ret)); - } if (OB_FAIL(ret)) { - read_cache_.reset(); + } else if (!replaced_tables.empty() && OB_FAIL(new_tables.init(allocator, replaced_tables))) { + LOG_WARN("failed to init sstable array", K(ret), K(new_tables), K(replaced_tables)); } return ret; } -int ObTabletTableStore::get_read_tables( - const int64_t snapshot_version, - ObTableStoreIterator &iterator, - const bool allow_no_ready_read) +int64_t ObTabletTableStore::get_deep_copy_size() const { - int ret = OB_SUCCESS; - iterator.reset(); - - if (OB_UNLIKELY(snapshot_version < 0)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid argument", K(ret), K(snapshot_version)); - } else if (OB_UNLIKELY(is_major_sstable_empty() && minor_tables_.empty() && allow_no_ready_read)) { - if (memtables_.empty()) { - LOG_INFO("no table in table store, cannot read", K(ret), K(*this)); - } else if (OB_FAIL(iterator.add_tables(memtables_))) { - LOG_WARN("failed to add tables to iterator", K(ret)); - } - } else if (OB_UNLIKELY(!allow_no_ready_read && !is_ready_for_read_)) { - ret = OB_REPLICA_NOT_READABLE; - LOG_WARN("table store not ready for read", K(ret), K(allow_no_ready_read), K(PRINT_TS(*this))); - } else if (OB_UNLIKELY(!is_valid())) { - ret = OB_ERR_SYS; - LOG_WARN("table store not valid", K(ret), K(snapshot_version), K(*this)); - } else if (check_read_cache(snapshot_version)) { // use read_cache - if (OB_FAIL(iterator.copy(read_cache_))) { - LOG_WARN("failed to copy read tables from cache", K(ret)); - } - } else { // don't use cache - if (OB_FAIL(calculate_read_tables(iterator, snapshot_version, allow_no_ready_read))) { - LOG_WARN("failed to get read tables", K(ret)); - } - } - if (OB_SUCC(ret)) { - if (OB_FAIL(iterator.set_retire_check())) { - LOG_WARN("failed to set retire check to iterator", K(ret)); - } - } - return ret; + return (sizeof(ObTabletTableStore) + + major_tables_.get_deep_copy_size() + + minor_tables_.get_deep_copy_size() + + ddl_mem_sstables_.get_deep_copy_size() + + ddl_sstables_.get_deep_copy_size() + + meta_major_tables_.get_deep_copy_size()); } -int ObTabletTableStore::get_read_major_sstable( - const int64_t &major_snapshot_version, - ObTableStoreIterator &iterator) +int ObTabletTableStore::deep_copy( + char *buf, + const int64_t buf_len, + ObIStorageMetaObj *&value) const { int ret = OB_SUCCESS; - iterator.reset(); - if (OB_UNLIKELY(major_snapshot_version <= 0)) { + int64_t pos = 0; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len < get_deep_copy_size())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid args", K(ret), K(major_snapshot_version)); + LOG_WARN("invalid argument", K(ret), KP(buf), K(buf_len)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i get_snapshot_version()) { - break; - } else if (major_snapshot_version == major_tables_[i]->get_snapshot_version()) { - if (OB_FAIL(iterator.add_tables(major_tables_.array_ + i))) { - LOG_WARN("failed to add major table to iterator", K(ret)); + ObTabletTableStore *new_table_store = new (buf) ObTabletTableStore(); + pos = sizeof(ObTabletTableStore); + if (OB_FAIL(major_tables_.deep_copy(buf, buf_len, pos, new_table_store->major_tables_))) { + LOG_WARN("fail to deep copy major sstables", K(ret)); + } else if (OB_FAIL(minor_tables_.deep_copy(buf, buf_len, pos, new_table_store->minor_tables_))) { + LOG_WARN("fail to deep copy minor sstables", K(ret)); + } else if (OB_FAIL(ddl_mem_sstables_.deep_copy(buf, buf_len, pos, new_table_store->ddl_mem_sstables_))) { + LOG_WARN("fail to deep copy ddl mem sstables", K(ret)); + } else if (OB_FAIL(ddl_sstables_.deep_copy(buf, buf_len, pos, new_table_store->ddl_sstables_))) { + LOG_WARN("fail to deep copy ddl sstables", K(ret)); + } else if (OB_FAIL(meta_major_tables_.deep_copy(buf, buf_len, pos, new_table_store->meta_major_tables_))) { + LOG_WARN("fail to deep copy meta major sstables", K(ret)); + } else if (OB_FAIL(memtables_.assign(new_table_store->memtables_))) { + LOG_WARN("fail to assign memtable pointers to new table store", K(ret)); + } else { + new_table_store->version_ = version_; + new_table_store->is_inited_ = is_inited_; + new_table_store->is_ready_for_read_ = is_ready_for_read_; + value = new_table_store; + FLOG_INFO("succeed to deep_copy table store", K(major_tables_), K(minor_tables_), K(memtables_), K(PRINT_TS(*this))); + } + } + return ret; +} + +int ObTabletTableStore::get_local_sstable_size_limit( + const int64_t table_store_mem_ctx_size, + int64_t &local_sstable_size_limit) const +{ + int ret = OB_SUCCESS; + const int64_t table_store_object_size = get_deep_copy_size(); + if (OB_UNLIKELY(table_store_mem_ctx_size < table_store_object_size)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table store memory context size", K(ret), K(table_store_mem_ctx_size)); + } else { + local_sstable_size_limit = table_store_mem_ctx_size - table_store_object_size; + } + return ret; +} + +int ObTabletTableStore::try_cache_local_sstables(common::ObArenaAllocator &allocator) +{ + int ret = OB_SUCCESS; + int64_t local_sstable_size_limit = 0; + int64_t local_sstable_meta_size = 0; + if (OB_FAIL(get_local_sstable_size_limit(MAX_TABLE_STORE_MEMORY_SIZE, local_sstable_size_limit))) { + LOG_WARN("failed to get local sstable size limit", K(ret)); + } else if (OB_FAIL(try_cache_local_sstable_meta( + allocator, meta_major_tables_, local_sstable_size_limit, local_sstable_meta_size))) { + if (OB_UNLIKELY(ret != OB_BUF_NOT_ENOUGH)) { + LOG_WARN("fail to cache local meta major sstable meta", K(ret)); + } + } else if (OB_FAIL(try_cache_local_sstable_meta( + allocator, major_tables_, local_sstable_size_limit, local_sstable_meta_size))) { + if (OB_UNLIKELY(ret != OB_BUF_NOT_ENOUGH)) { + LOG_WARN("fail to cache local major sstable meta", K(ret)); + } + } else if (OB_FAIL(try_cache_local_sstable_meta( + allocator, minor_tables_, local_sstable_size_limit, local_sstable_meta_size))) { + if (OB_UNLIKELY(ret != OB_BUF_NOT_ENOUGH)) { + LOG_WARN("fail to cache local minor sstable meta", K(ret)); + } + } + return ret; +} + +int ObTabletTableStore::cache_local_sstable_meta( + ObArenaAllocator &allocator, + blocksstable::ObSSTable *array_sstable, + const blocksstable::ObSSTable *loaded_sstable, + const int64_t local_sstable_size_limit, + int64_t &local_sstable_meta_size) +{ + int ret = OB_SUCCESS; + ObSSTableMetaHandle sst_meta_hdl; + if (OB_ISNULL(array_sstable) || OB_ISNULL(loaded_sstable) + || OB_UNLIKELY(!loaded_sstable->is_loaded()) + || OB_UNLIKELY(array_sstable->get_key() != loaded_sstable->get_key())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KPC(array_sstable), KPC(loaded_sstable), + K(local_sstable_size_limit), K(local_sstable_meta_size)); + } else if (local_sstable_meta_size >= local_sstable_size_limit) { + ret = OB_BUF_NOT_ENOUGH; + } else if (array_sstable->is_loaded()) { + // sstable in table store array already loaded + if (OB_FAIL(array_sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta", K(ret)); + } else { + local_sstable_meta_size += sst_meta_hdl.get_sstable_meta().get_deep_copy_size(); + } + } else if (OB_FAIL(loaded_sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta", K(ret)); + } else { + const int64_t deep_copy_size = sst_meta_hdl.get_sstable_meta().get_deep_copy_size(); + ObSSTableMeta *copied_sstable_meta = nullptr; + int64_t pos = 0; + if (local_sstable_meta_size + deep_copy_size <= local_sstable_size_limit) { + // cache local sstable meta + char *buf = nullptr; + if (OB_ISNULL(buf = static_cast(allocator.alloc(deep_copy_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for sstable", K(ret)); + } else if (OB_FAIL(sst_meta_hdl.get_sstable_meta().deep_copy(buf, deep_copy_size, pos, copied_sstable_meta))) { + LOG_WARN("fail to copy read cache to local sstable meta array", K(ret)); + } else if (OB_FAIL(array_sstable->assign_meta(copied_sstable_meta))) { + LOG_WARN("fail to assign cached sstable meta to sstable", K(ret), KP(array_sstable)); + } else { + local_sstable_meta_size += deep_copy_size; + } + } else { + // size of sstables exceed limit + ret = OB_BUF_NOT_ENOUGH; + } + } + return ret; +} + +int ObTabletTableStore::try_cache_local_sstable_meta( + ObArenaAllocator &allocator, + ObSSTableArray &sstable_array, + const int64_t local_sstable_size_limit, + int64_t &local_sstable_meta_size) +{ + // TODO: now load sstable synchronously, async it + int ret = OB_SUCCESS; + if (local_sstable_meta_size >= local_sstable_size_limit) { + ret = OB_BUF_NOT_ENOUGH; + } else { + ObStorageMetaHandle sstable_handle; + // try to cache major sstables + for (int64_t i = 0; OB_SUCC(ret) && i < sstable_array.count(); ++i) { + sstable_handle.reset(); + ObSSTable *loaded_sstable = nullptr; + ObSSTable *array_sstable = sstable_array[i]; + if (array_sstable->is_loaded()) { + // sstable is already loaded to memory + } else if (OB_FAIL(load_sstable(array_sstable->get_addr(), sstable_handle))) { + LOG_WARN("fail to load sstable", K(ret), KPC(array_sstable)); + } else if (OB_FAIL(sstable_handle.get_sstable(loaded_sstable))) { + LOG_WARN("fail to get sstable value", K(ret), K(sstable_handle)); + } else if (OB_FAIL(cache_local_sstable_meta( + allocator, + array_sstable, + loaded_sstable, + local_sstable_size_limit, + local_sstable_meta_size))) { + if (OB_UNLIKELY(OB_BUF_NOT_ENOUGH != ret)) { + LOG_WARN("fail to cache local sstable meta", K(ret)); } - break; } } } - if (OB_SUCC(ret)) { - if (OB_FAIL(iterator.set_retire_check())) { - LOG_WARN("failed to set retire check to iterator", K(ret)); - } - } return ret; } -bool ObTabletTableStore::check_read_cache(const int64_t snapshot_version) +int ObTabletTableStore::inc_macro_ref() const { - bool use_cache = false; - if (!read_cache_.is_valid()) { - } else if (INT64_MAX != snapshot_version) { - } else { - use_cache = true; + int ret = OB_SUCCESS; + bool major_success = false; + bool meta_major_success = false; + bool minor_success = false; + bool ddl_success = false; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("tablet store hasn't been inited", K(ret)); + } else if (!major_tables_.empty() + && OB_FAIL(major_tables_.inc_macro_ref(major_success))) { + LOG_WARN("fail to increase major sstables' ref cnt", K(ret), K(major_tables_)); + } else if (!meta_major_tables_.empty() + && OB_FAIL(meta_major_tables_.inc_macro_ref(meta_major_success))) { + LOG_WARN("fail to increase meta major sstables' ref cnt", K(ret), K(meta_major_tables_)); + } else if (!minor_tables_.empty() + && OB_FAIL(minor_tables_.inc_macro_ref(minor_success))) { + LOG_WARN("fail to increase minor sstables' ref cnt", K(ret), K(minor_tables_)); + } else if (!ddl_sstables_.empty() + && OB_FAIL(ddl_sstables_.inc_macro_ref(ddl_success))) { + LOG_WARN("fail to increase ddl sstables' ref cnt", K(ret), K(ddl_sstables_)); + } + + if (OB_FAIL(ret)) { + if (major_success) { + major_tables_.dec_macro_ref(); + } + if (meta_major_success) { + meta_major_tables_.dec_macro_ref(); + } + if (minor_success) { + minor_tables_.dec_macro_ref(); + } + if (ddl_success) { + ddl_sstables_.dec_macro_ref(); + } + } + + return ret; +} + +void ObTabletTableStore::dec_macro_ref() const +{ + if (!major_tables_.empty()) { + major_tables_.dec_macro_ref(); + } + if (!meta_major_tables_.empty()) { + meta_major_tables_.dec_macro_ref(); + } + if (!minor_tables_.empty()) { + minor_tables_.dec_macro_ref(); + } + if (!ddl_sstables_.empty()) { + ddl_sstables_.dec_macro_ref(); } - return use_cache; } bool ObTabletTableStore::check_read_tables( - ObTableStoreIterator &iterator, - const int64_t snapshot_version) + const ObTablet &tablet, + const int64_t snapshot_version, + const ObSSTable *base_table) const { bool contain_snapshot_version = false; - if (!iterator.is_valid()) { - LOG_WARN_RET(OB_INVALID_ARGUMENT, "iterator invalid, must not contain snapshot_version", K(iterator)); - } else if (OB_ISNULL(tablet_ptr_)) { - LOG_WARN_RET(OB_INVALID_ARGUMENT, "Unexpected null tablet ptr, must not contain snapshot version"); + if (OB_ISNULL(base_table)) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "null base table, must not contain snapshot_version", KP(base_table)); } else { - if (iterator.get_boundary_table(false)->is_major_sstable()) { - contain_snapshot_version = iterator.get_boundary_table(false)->get_snapshot_version() == snapshot_version; + if (base_table->is_major_sstable()) { + contain_snapshot_version = base_table->get_snapshot_version() == snapshot_version; } - if (!contain_snapshot_version && - snapshot_version >= tablet_ptr_->get_multi_version_start()) { + if (!contain_snapshot_version && snapshot_version >= tablet.get_multi_version_start()) { contain_snapshot_version = true; } } if (!contain_snapshot_version) { - LOG_WARN_RET(OB_ERR_UNEXPECTED, "table store has no contain snapshot version", K(snapshot_version), KPC_(tablet_ptr), K(iterator), K(*this)); + LOG_WARN_RET(OB_ERR_UNEXPECTED, "table store has no contain snapshot version", + K(snapshot_version), K(tablet), KPC(base_table), KPC(this)); } return contain_snapshot_version; } int ObTabletTableStore::calculate_read_tables( - ObTableStoreIterator &iterator, const int64_t snapshot_version, - const bool allow_no_ready_read) + const ObTablet &tablet, + ObTableStoreIterator &iterator, + const bool allow_no_ready_read) const { int ret = OB_SUCCESS; - ObSSTable *base_table = nullptr; + const ObSSTable *base_table = nullptr; - if (OB_NOT_NULL(extend_tables_[META_MAJOR]) - && extend_tables_[META_MAJOR]->get_snapshot_version() <= snapshot_version) { - base_table = static_cast(extend_tables_[META_MAJOR]); - if (OB_FAIL(iterator.add_tables(extend_tables_.array_ + META_MAJOR))) { - LOG_WARN("failed to add meta sstable to iterator", K(ret)); + if (!meta_major_tables_.empty() && meta_major_tables_.at(0)->get_snapshot_version() < snapshot_version) { + base_table = meta_major_tables_.at(0); + if (OB_FAIL(iterator.add_table(meta_major_tables_.at(0)))) { + LOG_WARN("failed to add meta major table to iterator", K(ret), K(meta_major_tables_)); } } else if (!is_major_sstable_empty()) { if (!major_tables_.empty()) { - for (int64_t i = major_tables_.count_ - 1; OB_SUCC(ret) && i >= 0; --i) { + for (int64_t i = major_tables_.count() - 1; OB_SUCC(ret) && i >= 0; --i) { if (major_tables_[i]->get_snapshot_version() <= snapshot_version) { - base_table = static_cast(major_tables_[i]); - if (OB_FAIL(iterator.add_tables(major_tables_.array_ + i))) { + base_table = major_tables_[i]; + if (OB_FAIL(iterator.add_table(major_tables_[i]))) { LOG_WARN("failed to add major table to iterator", K(ret)); } break; @@ -635,9 +712,12 @@ int ObTabletTableStore::calculate_read_tables( } else { ObSSTable *first_ddl_sstable = static_cast(ddl_major_sstables.at(0)); if (first_ddl_sstable->get_data_version() <= snapshot_version) { - if (OB_FAIL(iterator.add_tables(ddl_major_sstables.get_data(), ddl_major_sstables.count()))) { - LOG_WARN("add ddl major sstable failec", K(ret)); - } else { + for (int64_t i = 0; OB_SUCC(ret) && i < ddl_major_sstables.count(); ++i) { + if (OB_FAIL(iterator.add_table(ddl_major_sstables.at(i)))) { + LOG_WARN("add ddl major sstable failed", K(ret), K(i), K(ddl_major_sstables)); + } + } + if (OB_SUCC(ret)) { base_table = first_ddl_sstable; } } else { @@ -651,15 +731,12 @@ int ObTabletTableStore::calculate_read_tables( } if (OB_FAIL(ret)) { - } else if (OB_ISNULL(tablet_ptr_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null tablet", K(ret)); } else if (OB_NOT_NULL(base_table)) { // find read minor tables - ObITable *table = nullptr; + const ObSSTable *table = nullptr; int64_t inc_pos = -1; // TODO@wenqu: better abstract to calculate read tables in ddl path SCN last_scn = base_table->is_major_sstable() || base_table->is_ddl_sstable() ? SCN::max_scn() : base_table->get_end_scn(); - for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables_.count_; ++i) { + for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables_.count(); ++i) { table = minor_tables_[i]; if (((base_table->is_major_sstable() || base_table->is_ddl_sstable()) && table->get_upper_trans_version() >= base_table->get_data_version()) || table->get_end_scn() >= last_scn) { @@ -668,16 +745,17 @@ int ObTabletTableStore::calculate_read_tables( } } if (OB_SUCC(ret) && inc_pos >= 0 - && OB_FAIL(iterator.add_tables(minor_tables_.array_ + inc_pos, minor_tables_.count_ - inc_pos))) { + && OB_FAIL(iterator.add_tables(minor_tables_, inc_pos, minor_tables_.count() - inc_pos))) { LOG_WARN("failed add table to iterator", K(ret)); } else { // try to add memtables for reading - if (OB_FAIL(calculate_read_memtables(*tablet_ptr_, iterator))) { + if (OB_FAIL(calculate_read_memtables(tablet, iterator))) { LOG_WARN("failed to calculate read memtables", K(ret), K(snapshot_version), K(iterator), KPC(this)); } } - if (OB_SUCC(ret) && !check_read_tables(iterator, snapshot_version)) { + if (OB_SUCC(ret) && !check_read_tables(tablet, snapshot_version, base_table)) { ret = OB_SNAPSHOT_DISCARDED; - LOG_WARN("exist base table, but no read table found for specific version", K(ret), K(snapshot_version), K(iterator), K(PRINT_TS(*this))); + LOG_WARN("exist base table, but no read table found for specific version", + K(ret), K(snapshot_version), K(iterator), K(PRINT_TS(*this))); } } else { // not find base table if (!allow_no_ready_read) { @@ -690,27 +768,27 @@ int ObTabletTableStore::calculate_read_tables( LOG_WARN("no base table found for specific version", K(ret), K(snapshot_version), K(allow_no_ready_read), K(PRINT_TS(*this))); } - } else if (!major_tables_.empty()) { - ret = OB_SNAPSHOT_DISCARDED; - LOG_WARN("exist major table, allow_no_ready_read can not be true", - K(ret), K(snapshot_version), K(allow_no_ready_read), K(PRINT_TS(*this))); - } else if (!minor_tables_.empty() && OB_FAIL(iterator.add_tables(minor_tables_.array_, minor_tables_.count_))) { + } else if (!minor_tables_.empty() && OB_FAIL(iterator.add_tables( + minor_tables_, 0, minor_tables_.count()))) { LOG_WARN("failed to add all minor tables to iterator", K(ret)); } else { - if (OB_FAIL(calculate_read_memtables(*tablet_ptr_, iterator))) { + if (OB_FAIL(calculate_read_memtables(tablet, iterator))) { LOG_WARN("no base table, but allow no ready read, failed to calculate read memtables", K(ret), K(snapshot_version), K(memtables_), K(PRINT_TS(*this))); } } } + return ret; } -int ObTabletTableStore::calculate_read_memtables(const ObTablet &tablet, ObTableStoreIterator &iterator) +int ObTabletTableStore::calculate_read_memtables( + const ObTablet &tablet, + ObTableStoreIterator &iterator) const { int ret = OB_SUCCESS; int64_t start_snapshot_version = tablet.get_snapshot_version(); - SCN start_scn = tablet.get_clog_checkpoint_scn(); + share::SCN start_scn = tablet.get_clog_checkpoint_scn(); int64_t mem_pos = -1; ObITable *memtable = nullptr; @@ -724,140 +802,396 @@ int ObTabletTableStore::calculate_read_memtables(const ObTablet &tablet, ObTable return ret; } -int ObTabletTableStore::pull_memtables() +int ObTabletTableStore::get_table( + const ObStorageMetaHandle &table_store_handle, + const ObITable::TableKey &table_key, + ObTableHandleV2 &handle) const { int ret = OB_SUCCESS; - ObTableHandleArray memtable_handles; - - if (OB_ISNULL(tablet_ptr_) || OB_ISNULL(tablet_ptr_->get_memtable_mgr())) { + handle.reset(); + ObITable *table = nullptr; + if (OB_UNLIKELY(!is_valid())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected tablet_ptr or memtable_mgr", K(ret), KP(tablet_ptr_)); - } else if (!tablet_ptr_->get_memtable_mgr()->has_memtable()) { - LOG_TRACE("no memtable in memtable mgr", K(ret)); - } else if (OB_FAIL(tablet_ptr_->get_memtable_mgr()->get_all_memtables(memtable_handles))) { - LOG_WARN("failed to get all memtables from memtable_mgr", K(ret)); - } else { - int64_t start_snapshot_version = tablet_ptr_->get_snapshot_version(); - SCN clog_checkpoint_scn = tablet_ptr_->get_clog_checkpoint_scn(); - int64_t start_pos = -1; - - for (int64_t i = 0; OB_SUCC(ret) && i < memtable_handles.count(); ++i) { - ObIMemtable *table = static_cast(memtable_handles.at(i).get_table()); - if (OB_ISNULL(table) || !table->is_memtable()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table must not null and must be memtable", K(ret), K(table)); - } else if (table->is_resident_memtable()) { // Single full resident memtable will be available always - LOG_INFO("is_resident_memtable will be pulled always", K(table->get_key().tablet_id_.id())); - start_pos = i; - break; - } else if (table->get_end_scn() == clog_checkpoint_scn) { - if (table->get_snapshot_version() > start_snapshot_version) { - start_pos = i; - break; - } - } else if (table->get_end_scn() > clog_checkpoint_scn) { - start_pos = i; - break; - } + LOG_WARN("table store is unexpected invalid", K(ret), KPC(this)); + } else if (OB_FAIL(get_table(table_key, table))) { + LOG_WARN("fail to get table pointer", K(ret)); + } else if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("found null table pointer", K(ret), K(table_key)); + } else if (table->is_memtable()) { + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr *); + if (OB_FAIL(handle.set_table(table, t3m, table->get_key().table_type_))) { + LOG_WARN("Failed to set memtable to handle", K(ret), K(handle), K(table_key), KPC(table)); } - if (OB_FAIL(ret)) { - } else if (start_pos < 0 || start_pos >= memtable_handles.count()) { - // all memtables need to be released - } else if (OB_FAIL(memtables_.build(memtable_handles, start_pos))) { - LOG_WARN("failed to build table store memtables", K(ret), K(memtable_handles), K(start_pos), K(*this)); + } else if (static_cast(table)->is_loaded()) { + if (!table_store_handle.is_valid()) { + // table store object on tablet meta memory + if (OB_FAIL(handle.set_sstable_with_tablet(table))) { + LOG_WARN("failed to set sstable to handle", K(ret)); + } + } else if (OB_FAIL(handle.set_sstable(table, table_store_handle))) { + LOG_WARN("failed to set sstable to handle", K(ret)); + } + } else { + ObStorageMetaHandle sst_handle; + ObSSTable *sstable = nullptr; + if (OB_FAIL(load_sstable( + static_cast(table)->get_addr(), sst_handle))) { + LOG_WARN("fail to load sstable", K(ret), KPC(table)); + } else if (OB_FAIL(sst_handle.get_sstable(sstable))) { + LOG_WARN("fail to get loaded sstable", K(ret)); + } else if (OB_FAIL(handle.set_sstable(sstable, sst_handle))) { + LOG_WARN("fail to set sstable to handle", K(ret), KPC(sstable), K(handle)); } } return ret; } -int ObTabletTableStore::assign( - ObIAllocator &allocator, - const ObTabletTableStore &other, ObTablet *new_tablet) +int ObTabletTableStore::get_table(const ObITable::TableKey &table_key, ObITable *&table) const { int ret = OB_SUCCESS; - if (IS_INIT) { - ret = OB_INIT_TWICE; - LOG_WARN("ObTabletTableStore has been inited, cannot assign", K(ret), K(*this)); - } else if (OB_UNLIKELY(!other.is_valid() || NULL == (tablet_ptr_ = new_tablet))) { + if (OB_UNLIKELY(!table_key.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid arguments", K(ret), K(other), K(new_tablet)); - } else if (other.major_tables_.count_ > 0 && OB_FAIL(major_tables_.copy(allocator, other.major_tables_))) { - LOG_WARN("failed to copy major tables", K(ret)); - } else if (other.minor_tables_.count_ > 0 && OB_FAIL(minor_tables_.copy(allocator, other.minor_tables_))) { - LOG_WARN("failed to copy minor tables", K(ret)); - } else if (other.ddl_sstables_.count_ > 0 && OB_FAIL(ddl_sstables_.copy(allocator, other.ddl_sstables_))) { - LOG_WARN("failed to copy ddl sstables", K(ret)); - } else if (other.ddl_mem_sstables_.count_ > 0 && OB_FAIL(ddl_mem_sstables_.copy(allocator, other.ddl_mem_sstables_))) { - LOG_WARN("failed to copy ddl memtables", K(ret)); - } else if (OB_FAIL(extend_tables_.copy(allocator, other.extend_tables_, true/*allow_empty_table*/))) { - LOG_WARN("failed to copy extend tables", K(ret)); - } else if (OB_FAIL(memtables_.init(&allocator, other.memtables_))) { - LOG_WARN("failed to copy memtables", K(ret)); + LOG_WARN("invalid arguments", K(ret), K(table_key)); } else { - is_ready_for_read_ = other.is_ready_for_read_; - is_inited_ = true; - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = init_read_cache())) { - LOG_WARN("failed to init read cache iterator", K(tmp_ret)); + table = nullptr; + const ObSSTableArray *sst_array = nullptr; + if (table_key.is_major_sstable()) { + sst_array = &major_tables_; + } else if (table_key.is_minor_sstable()) { + sst_array = &minor_tables_; + } else if (table_key.is_ddl_sstable()) { + sst_array = &ddl_sstables_; + } else if (table_key.is_meta_major_sstable()) { + sst_array = &meta_major_tables_; } - FLOG_INFO("success to assign table store", K(ret), K(PRINT_TS(*this))); + + if (table_key.is_memtable()) { + if (OB_FAIL(memtables_.find(table_key, table))) { + LOG_WARN("fail to get memtable", K(ret), K(table_key), K_(memtables)); + } + } else if (OB_ISNULL(sst_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null sstable array", K(ret), K(table_key)); + } else if (sst_array->empty()) { + // not found + } else if (OB_FAIL(sst_array->get_table(table_key, table))) { + LOG_WARN("fail to get table from sstable array", K(ret)); + } + + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(table)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("table not found", K(ret), K(table_key)); + } + } + return ret; +} + +int ObTabletTableStore::get_read_tables( + const int64_t snapshot_version, + const ObTablet &tablet, + ObTableStoreIterator &iterator, + const bool allow_no_ready_read) const +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(snapshot_version < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(snapshot_version)); + } else if (OB_UNLIKELY(is_major_sstable_empty() && minor_tables_.empty() && allow_no_ready_read)) { + if (memtables_.empty()) { + LOG_INFO("no table in table store, cannot read", K(ret), K(*this)); + } else if (OB_FAIL(iterator.add_tables(memtables_))) { + LOG_WARN("failed to add tables to iterator", K(ret)); + } + } else if (OB_UNLIKELY(!allow_no_ready_read && !is_ready_for_read_)) { + ret = OB_REPLICA_NOT_READABLE; + LOG_WARN("table store not ready for read", K(ret), K(allow_no_ready_read), K(PRINT_TS(*this))); + } else if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_SYS; + LOG_WARN("table store not valid", K(ret), K(snapshot_version), K(*this)); + } else if (OB_FAIL(calculate_read_tables(snapshot_version, tablet, iterator, allow_no_ready_read))) { + LOG_WARN("failed to get read tables", K(ret)); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(iterator.set_retire_check())) { + LOG_WARN("failed to set retire check to iterator", K(ret)); + } + } + return ret; +} + +int ObTabletTableStore::get_read_major_sstable( + const int64_t snapshot_version, + ObTableStoreIterator &iterator) const +{ + int ret = OB_SUCCESS; + iterator.reset(); + + if (OB_UNLIKELY(snapshot_version < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(snapshot_version)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < major_tables_.count(); ++i) { + ObSSTable *sstable = major_tables_[i]; + if (OB_ISNULL(sstable)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null sstable pointer", K(ret)); + } else if (snapshot_version < sstable->get_snapshot_version()) { + break; + } else if (snapshot_version == sstable->get_snapshot_version()) { + if (OB_FAIL(iterator.add_table(sstable))) { + LOG_WARN("failed to add major table to iterator", K(ret), KPC(sstable)); + } + } + } + } + + return ret; +} + +int ObTabletTableStore::get_all_sstable(ObTableStoreIterator &iter) const +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (!meta_major_tables_.empty() && OB_FAIL(iter.add_tables(meta_major_tables_, 0, meta_major_tables_.count()))) { + LOG_WARN("fail to add all meta major tables to iterator", K(ret), K_(meta_major_tables)); + } else if (!major_tables_.empty() && OB_FAIL(iter.add_tables(major_tables_, 0, major_tables_.count()))) { + LOG_WARN("fail to add all major tables to iterator", K(ret), K_(major_tables)); + } else if (!minor_tables_.empty() && OB_FAIL(iter.add_tables(minor_tables_, 0, minor_tables_.count()))) { + LOG_WARN("fail to add all minor tables to iterator", K(ret), K_(major_tables)); + } else if (!ddl_sstables_.empty() && OB_FAIL(iter.add_tables(ddl_sstables_, 0, ddl_sstables_.count()))) { + LOG_WARN("fail to add all ddl sstables to iterator", K(ret), K_(ddl_sstables)); + } + return ret; +} + +int ObTabletTableStore::get_memtables( + common::ObIArray &memtables, + const bool need_active) const +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < memtables_.count(); ++i) { + if (OB_ISNULL(memtables_[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable must not null", K(ret), K(memtables_)); + } else if (!need_active && memtables_[i]->is_active_memtable()) { + continue; + } else if (OB_FAIL(memtables.push_back(memtables_[i]))) { + LOG_WARN("failed to add memtables", K(ret), K(*this)); + } + } + return ret; +} + +int ObTabletTableStore::update_memtables(const common::ObIArray &memtables) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(memtables_.rebuild(memtables))) { + LOG_ERROR("failed to rebuild table store memtables", K(ret), K(memtables), KPC(this)); + } + return ret; +} + +int ObTabletTableStore::clear_memtables() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table store is unexpected invalid", K(ret), KPC(this)); + } else { + memtables_.reset(); + } + return ret; +} + +int ObTabletTableStore::get_first_frozen_memtable(ObITable *&table) const +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < memtables_.count(); ++i) { + if (OB_ISNULL(memtables_[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable must not null", K(ret), K(memtables_)); + } else if (memtables_[i]->is_frozen_memtable()) { + table = memtables_[i]; + break; + } + } + return ret; +} + +int ObTabletTableStore::get_ddl_sstables(ObTableStoreIterator &iter) const +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("table store is not inited", K(ret)); + } else if (OB_FAIL(iter.add_tables(ddl_sstables_, 0, ddl_sstables_.count()))) { + LOG_WARN("failed to add ddl sstables to iterator", K(ret)); + } + return ret; +} + +int ObTabletTableStore::get_ha_tables(ObTableStoreIterator &iter, bool &is_ready_for_read) const +{ + int ret = OB_SUCCESS; + iter.reset(); + is_ready_for_read = false; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("table store is not inited", K(ret)); + } else if (FALSE_IT(is_ready_for_read = is_ready_for_read_)) { + } else if (!major_tables_.empty() && OB_FAIL(iter.add_tables(major_tables_, 0, major_tables_.count()))) { + LOG_WARN("failed to add major table to iterator", K(ret)); + } else if (!minor_tables_.empty() && OB_FAIL(iter.add_tables(minor_tables_, 0, minor_tables_.count()))) { + LOG_WARN("failed to add minor table to iterator", K(ret)); + } else if (!ddl_sstables_.empty() && OB_FAIL(iter.add_tables(ddl_sstables_, 0, ddl_sstables_.count()))) { + LOG_WARN("failed to add ddl table to iterator", K(ret)); + } else if (OB_FAIL(iter.set_retire_check())) { + LOG_WARN("failed to set retire check to iterator", K(ret)); + } else { + LOG_INFO("succeed to get ha tables", K(major_tables_), K(minor_tables_), K(ddl_sstables_)); + } + return ret; +} + +int ObTabletTableStore::get_mini_minor_sstables( + const bool is_ha_data_status_complete, + ObTableStoreIterator &iter) const +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("table store is not inited", K(ret)); + } else if (is_ha_data_status_complete) { + if (OB_FAIL(iter.add_tables(minor_tables_, 0, minor_tables_.count()))) { + LOG_WARN("failed to get all minor tables", K(ret)); + } + } else if (OB_FAIL(get_ha_mini_minor_sstables_(iter))) { + LOG_WARN("failed to get ha mini minor sstables", K(ret), K(minor_tables_)); + } + return ret; +} + +int ObTabletTableStore::get_recycle_version( + const int64_t multi_version_start, + int64_t &recycle_version) const +{ + int ret = OB_SUCCESS; + recycle_version = 0; + ObSEArray major_tables; + if (major_tables_.empty()) { + } else if (OB_FAIL(major_tables_.get_all_tables(major_tables))) { + LOG_WARN("failed to get major tables from old store", K(ret), KPC(this)); + } else if (OB_FAIL(ObTableStoreUtil::sort_major_tables(major_tables))) { + LOG_WARN("failed to sort major tables", K(ret)); + } else { + for (int64_t i = major_tables.count() - 1; OB_SUCC(ret) && i >= 0; --i) { + if (major_tables.at(i)->get_snapshot_version() <= multi_version_start) { + recycle_version = major_tables.at(i)->get_snapshot_version(); + break; + } + } + if (0 == recycle_version && major_tables.count() > 0) { + recycle_version = major_tables.at(0)->get_snapshot_version(); + LOG_WARN("not found inc base snapshot version, use the oldest major table", K(ret)); + } + } + return ret; +} + +int ObTabletTableStore::load_sstable(const ObMetaDiskAddr &addr, ObStorageMetaHandle &handle) +{ + int ret = OB_SUCCESS; + handle.reset(); + if (OB_UNLIKELY(!addr.is_valid() || addr.is_none() || addr.is_memory())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(addr)); + } else { + ObStorageMetaCache &meta_cache = OB_STORE_CACHE.get_storage_meta_cache(); + ObStorageMetaKey meta_key(MTL_ID(), addr); + if (OB_FAIL(meta_cache.get_meta(ObStorageMetaValue::MetaType::SSTABLE, meta_key, handle, nullptr))) { + LOG_WARN("fail to retrieve sstable meta from meta cache", K(ret), K(addr)); + } + } + return ret; +} + +int ObTabletTableStore::load_sstable_on_demand( + const ObStorageMetaHandle &table_store_handle, + blocksstable::ObSSTable &orig_sstable, + ObStorageMetaHandle &loaded_sstable_handle, + blocksstable::ObSSTable *&loaded_sstable) +{ + int ret = OB_SUCCESS; + if (orig_sstable.is_loaded()) { + // sstable is already loaded, life time guaranteed by table store. + loaded_sstable = &orig_sstable; + loaded_sstable_handle = table_store_handle; + } else if (OB_FAIL(load_sstable(orig_sstable.get_addr(), loaded_sstable_handle))) { + LOG_WARN("fail to load sstable", K(ret), K(orig_sstable)); + } else if (OB_FAIL(loaded_sstable_handle.get_sstable(loaded_sstable))) { + LOG_WARN("fail to get loaded sstable from storage meta handle", K(ret), K(loaded_sstable_handle)); } return ret; } int ObTabletTableStore::build_new_table_store( - ObIAllocator &allocator, + ObArenaAllocator &allocator, + const ObTablet &tablet, const ObUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store) { int ret = OB_SUCCESS; - ObITable *new_table = const_cast(param.table_handle_.get_table()); //table can be null + const ObITable *new_table = static_cast(const_cast(param.sstable_)); //table can be null + int64_t inc_base_snapshot_version = -1; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("ObTabletTableStore is not inited", K(ret)); - } else if (!major_tables_.empty() || !minor_tables_.empty()) { + if (OB_UNLIKELY(!major_tables_.empty() || !minor_tables_.empty())) { ret = OB_ERR_SYS; LOG_ERROR("already exists sstable, cannot build new table store", K(ret), KPC(this)); - } - - if (OB_SUCC(ret) && OB_NOT_NULL(new_table)) { - if (new_table->is_meta_major_sstable()) { - ObITable *meta_major_table = old_store.extend_tables_[META_MAJOR]; - if (OB_NOT_NULL(meta_major_table) && new_table->get_end_scn() <= meta_major_table->get_end_scn()) { - ret= OB_MINOR_SSTABLE_RANGE_CROSS; - LOG_WARN("new meta major table is covered by old one", K(ret), KPC(new_table), KPC(meta_major_table)); - } - } else if (new_table->is_ddl_sstable() || new_table->is_major_sstable() || new_table->is_minor_sstable()) { - // ddl will deal in build_ddl_table later; all major/minor sstables always need rebuild - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("Unexpected table type", K(ret), KPC(new_table)); + } else if (OB_ISNULL(new_table)) { + // skip range check + } else if (OB_UNLIKELY(!new_table->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table type", K(ret), KPC(new_table)); + } else if (new_table->is_meta_major_sstable()) { + if (!old_store.meta_major_tables_.empty() + && new_table->get_end_scn() <= old_store.meta_major_tables_.at(0)->get_end_scn()) { + ret= OB_MINOR_SSTABLE_RANGE_CROSS; + LOG_WARN("new meta major table is covered by old one", K(ret), KPC(new_table), K(old_store)); } } - if (OB_SUCC(ret)) { - int64_t inc_base_snapshot_version = -1; - if (OB_FAIL(build_major_tables(allocator, param, old_store, inc_base_snapshot_version))) { - LOG_WARN("failed to build major_tables", K(ret)); - } else if (OB_FAIL(build_minor_tables(allocator, param, old_store, inc_base_snapshot_version))) { - if (OB_NO_NEED_MERGE != ret) { - LOG_WARN("failed to build minor_tables", K(ret)); - } - } else if (OB_FAIL(build_ddl_sstables(allocator, param, old_store))) { - LOG_WARN("Failed to add ddl minor sstable", K(ret)); - } else if (OB_FAIL(build_meta_major_table(param.table_handle_, old_store))) { - LOG_WARN("Failed to add meta sstable", K(ret)); - } else if (OB_FAIL(pull_memtables())) { - LOG_WARN("failed to pull memtable from memtable_mgr", K(ret)); - } else if (OB_FAIL(pull_ddl_memtables(allocator))) { - LOG_WARN("pull_ddl_memtables failed", K(ret)); - } else if (OB_FAIL(check_ready_for_read())) { + if (OB_FAIL(ret)) { + } else if (OB_FAIL(build_major_tables(allocator, param, old_store, inc_base_snapshot_version))) { + LOG_WARN("failed to build major_tables", K(ret)); + } else if (OB_FAIL(build_minor_tables(allocator, param, old_store, inc_base_snapshot_version))) { + if (OB_UNLIKELY(OB_NO_NEED_MERGE != ret)) { + LOG_WARN("failed to build minor_tables", K(ret)); + } + } else if (OB_FAIL(build_ddl_sstables(allocator, tablet, param, old_store))) { + LOG_WARN("failed to add ddl minor sstable", K(ret)); + } else if (OB_FAIL(build_meta_major_table(allocator, param.sstable_, old_store))) { + LOG_WARN("failed to build meta major tables", K(ret)); + } else if (OB_FAIL(build_memtable_array(tablet))) { + LOG_WARN("failed to pull memtable from memtable_mgr", K(ret)); + } else if (OB_FAIL(pull_ddl_memtables(allocator, tablet))) { + LOG_WARN("pull_ddl_memtables failed", K(ret)); + } else { + is_inited_ = true; + if (OB_FAIL(check_ready_for_read(tablet))) { LOG_WARN("failed to check ready for read", K(ret)); } else { int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = init_read_cache())) { - LOG_WARN("failed to cache read iterator", K(tmp_ret)); + if (OB_TMP_FAIL(try_cache_local_sstables(allocator))) { + LOG_WARN("failed to try cache local sstables", K(tmp_ret)); } FLOG_INFO("succeed to build new table store", K(major_tables_), K(minor_tables_), K(memtables_), K(PRINT_TS(*this))); } @@ -866,28 +1200,28 @@ int ObTabletTableStore::build_new_table_store( } int ObTabletTableStore::build_major_tables( - ObIAllocator &allocator, + ObArenaAllocator &allocator, const ObUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store, int64_t &inc_base_snapshot_version) { int ret = OB_SUCCESS; inc_base_snapshot_version = -1; - ObITable *new_table = const_cast(param.table_handle_.get_table()); //table can be null - ObTablesHandleArray tables_handle; - if (OB_NOT_NULL(new_table) && OB_FAIL(tables_handle.add_table(new_table))) { + ObITable *new_table = static_cast(const_cast(param.sstable_)); //table can be null + ObSEArray major_tables; + if (OB_NOT_NULL(new_table) && OB_FAIL(major_tables.push_back(new_table))) { LOG_WARN("failed to add table into tables handle", K(ret), K(param)); - } else if (OB_FAIL(inner_build_major_tables_(allocator, old_store, tables_handle, + } else if (OB_FAIL(inner_build_major_tables_(allocator, old_store, major_tables, param.multi_version_start_, param.allow_duplicate_sstable_, inc_base_snapshot_version))) { - LOG_WARN("failed to inner build major tables", K(ret), K(param), K(tables_handle)); + LOG_WARN("failed to inner build major tables", K(ret), K(param), K(major_tables)); } return ret; } int ObTabletTableStore::inner_build_major_tables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const ObTabletTableStore &old_store, - const ObTablesHandleArray &tables_handle, + const ObIArray &tables_array, const int64_t multi_version_start, const bool allow_duplicate_sstable, int64_t &inc_base_snapshot_version) @@ -900,23 +1234,31 @@ int ObTabletTableStore::inner_build_major_tables_( if (!old_store.major_tables_.empty() && OB_FAIL(old_store.major_tables_.get_all_tables(major_tables))) { LOG_WARN("failed to get major tables from old store", K(ret), K(old_store)); } - for (int64_t i = 0; OB_SUCC(ret) && i < tables_handle.get_count(); ++i) { - ObITable *new_table = tables_handle.get_table(i); + for (int64_t i = 0; OB_SUCC(ret) && i < tables_array.count(); ++i) { + ObITable *new_table = tables_array.at(i); need_add = true; if (OB_NOT_NULL(new_table) && new_table->is_major_sstable()) { for (int64_t j = 0; OB_SUCC(ret) && j < major_tables.count(); ++j) { ObITable *table = major_tables.at(j); - if (!table->is_major_sstable()) { + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_major_sstable())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("table type is unexpected", K(ret), KPC(table)); + LOG_WARN("unexpected table", K(ret), KPC(table)); } else if (new_table->get_key() == table->get_key()) { - if (!allow_duplicate_sstable) { + if (OB_UNLIKELY(!allow_duplicate_sstable)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected new major table which has same range with old major sstable", K(ret), KPC(new_table), KPC(table)); + LOG_WARN("get unexpected new major table which has same range with old major sstable", + K(ret), KPC(new_table), KPC(table)); } else { ObSSTable *new_sstable = static_cast(new_table); ObSSTable *old_sstable = static_cast(table); - if (OB_FAIL(ObSSTableMetaChecker::check_sstable_meta(old_sstable->get_meta(), new_sstable->get_meta()))) { + ObSSTableMetaHandle new_sst_meta_hdl; + ObSSTableMetaHandle old_sst_meta_hdl; + if (OB_FAIL(new_sstable->get_meta(new_sst_meta_hdl))) { + LOG_WARN("failed to get new sstable meta handle", K(ret)); + } else if (OB_FAIL(old_sstable->get_meta(old_sst_meta_hdl))) { + LOG_WARN("failed to get old sstable meta handle", K(ret)); + } else if (OB_FAIL(ObSSTableMetaChecker::check_sstable_meta( + new_sst_meta_hdl.get_sstable_meta(), old_sst_meta_hdl.get_sstable_meta()))) { LOG_WARN("failed to check sstable meta", K(ret), KPC(new_sstable), KPC(old_sstable)); } else { need_add = false; @@ -950,7 +1292,7 @@ int ObTabletTableStore::inner_build_major_tables_( if (major_tables.empty()) { LOG_INFO("major tables is empty", K(major_tables)); - } else if (OB_FAIL(major_tables_.init_and_copy(allocator, major_tables, start_pos))) { + } else if (OB_FAIL(major_tables_.init(allocator, major_tables, start_pos))) { LOG_WARN("failed to init major_tables", K(ret)); } } @@ -958,13 +1300,14 @@ int ObTabletTableStore::inner_build_major_tables_( } int ObTabletTableStore::build_minor_tables( - ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const ObUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store, const int64_t inc_base_snapshot_version) { int ret = OB_SUCCESS; - ObITable *new_table = const_cast(param.table_handle_.get_table()); //table can be null + ObSSTable *new_sstable = const_cast(param.sstable_); + ObITable *new_table = static_cast(new_sstable); //table can be null ObArray minor_tables; if (NULL == new_table || !new_table->is_minor_sstable()) { @@ -988,7 +1331,7 @@ int ObTabletTableStore::build_minor_tables( if (OB_SUCC(ret)) { ObITable *table = nullptr; - for (int64_t i = 0; OB_SUCC(ret) && i < old_store.minor_tables_.count_; ++i) { + for (int64_t i = 0; OB_SUCC(ret) && i < old_store.minor_tables_.count(); ++i) { table = old_store.minor_tables_[i]; bool need_add = true; if (OB_UNLIKELY(NULL == table || !table->is_minor_sstable())) { @@ -997,9 +1340,7 @@ int ObTabletTableStore::build_minor_tables( } else if (OB_NOT_NULL(new_table) && new_table->is_minor_sstable()) { if (new_table->get_key() == table->get_key()) { ObSSTable *sstable = static_cast(table); - ObSSTable *new_sstable = static_cast(new_table); - if (sstable->get_meta().get_basic_meta().max_merged_trans_version_ - <= new_sstable->get_meta().get_basic_meta().max_merged_trans_version_) { + if (sstable->get_max_merged_trans_version() <= new_sstable->get_max_merged_trans_version()) { need_add = false; LOG_INFO("new table's max merge trans version is not less than the old table, " "add new table when table key is same", KPC(sstable), KPC(new_sstable)); @@ -1043,7 +1384,7 @@ int ObTabletTableStore::build_minor_tables( } } if (OB_FAIL(ret)) { - } else if (inc_pos >= 0 && OB_FAIL(minor_tables_.init_and_copy(allocator, minor_tables, inc_pos))) { + } else if (inc_pos >= 0 && OB_FAIL(minor_tables_.init(allocator, minor_tables, inc_pos))) { LOG_WARN("failed to init minor_tables", K(ret)); } } @@ -1052,14 +1393,14 @@ int ObTabletTableStore::build_minor_tables( } int ObTabletTableStore::build_meta_major_table( - const ObTableHandleV2 &new_handle, + common::ObArenaAllocator &allocator, + const blocksstable::ObSSTable *new_sstable, const ObTabletTableStore &old_store) { int ret = OB_SUCCESS; - ObITable *new_table = const_cast(new_handle.get_table()); - ObITable *old_meta_major = old_store.extend_tables_[META_MAJOR]; + ObITable *new_table = static_cast(const_cast(new_sstable)); ObITable *last_major = nullptr; - extend_tables_.reset_table(META_MAJOR); + meta_major_tables_.reset(); if (OB_ISNULL(last_major = major_tables_.get_boundary_table(true))) { LOG_INFO("no major sstable exists, skip to try to build meta sstable", K(*this)); @@ -1067,22 +1408,23 @@ int ObTabletTableStore::build_meta_major_table( if (new_table->get_max_merged_trans_version() <= last_major->get_snapshot_version()) { ret= OB_MINOR_SSTABLE_RANGE_CROSS; LOG_WARN("the new meta merge sstable is covered by major", K(ret), KPC(new_table), KPC(last_major)); - } else if (OB_FAIL(extend_tables_.assign(META_MAJOR, new_table))) { - LOG_WARN("failed to add new meta merge sstable", K(ret)); + } else if (OB_FAIL(meta_major_tables_.init(allocator, static_cast(new_table)))) { + LOG_WARN("failed to init meta major tables", K(ret)); } } else if (OB_NOT_NULL(new_table) && new_table->is_major_sstable()) { // new table is major sstable, retire old meta sstable. - } else if (OB_NOT_NULL(old_meta_major)) { + } else if (!old_store.meta_major_tables_.empty()) { + ObITable *old_meta_major = old_store.meta_major_tables_.at(0); if (old_meta_major->get_snapshot_version() <= last_major->get_snapshot_version()) { // new table is not meta sstable FLOG_INFO("meta sstable is covered by major sstable", KPC(last_major), KPC(old_meta_major)); - } else if (OB_FAIL(extend_tables_.assign(META_MAJOR, old_meta_major))) { - LOG_WARN("failed to add new meta sstable", K(ret)); + } else if (OB_FAIL(meta_major_tables_.init(allocator, static_cast(old_meta_major)))) { + LOG_WARN("failed to init meta major tables", K(ret)); } } return ret; } -int ObTabletTableStore::get_ddl_major_sstables(ObIArray &ddl_major_sstables) +int ObTabletTableStore::get_ddl_major_sstables(ObIArray &ddl_major_sstables) const { int ret = OB_SUCCESS; ddl_major_sstables.reset(); @@ -1095,12 +1437,12 @@ int ObTabletTableStore::get_ddl_major_sstables(ObIArray &ddl_major_s LOG_WARN("reserve ddl sstable array failed", K(ret), K(ddl_sstable_count)); } for (int64_t i = 0; OB_SUCC(ret) && i < ddl_sstables_.count(); ++i) { - if (OB_FAIL(ddl_major_sstables.push_back(ddl_sstables_.get_table(i)))) { + if (OB_FAIL(ddl_major_sstables.push_back(ddl_sstables_[i]))) { LOG_WARN("push back ddl dump sstable failed", K(ret), K(i)); } } for (int64_t i = 0; OB_SUCC(ret) && i < ddl_mem_sstables_.count(); ++i) { - if (OB_FAIL(ddl_major_sstables.push_back(ddl_mem_sstables_.get_table(i)))) { + if (OB_FAIL(ddl_major_sstables.push_back(ddl_mem_sstables_[i]))) { LOG_WARN("push back old ddl sstable failed", K(ret), K(i)); } } @@ -1108,67 +1450,46 @@ int ObTabletTableStore::get_ddl_major_sstables(ObIArray &ddl_major_s return ret; } -int ObTabletTableStore::pull_ddl_memtables(common::ObIAllocator &allocator) +int ObTabletTableStore::pull_ddl_memtables( + common::ObArenaAllocator &allocator, + const ObTablet &tablet) { int ret = OB_SUCCESS; - ObArray ddl_memtables; - ObDDLKvMgrHandle kv_mgr_handle; - bool has_ddl_kv = false; - ObTablesHandleArray ddl_kvs_handle; - if (OB_ISNULL(tablet_ptr_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected tablet_ptr", K(ret), KP(tablet_ptr_)); - } else if (OB_FAIL(tablet_ptr_->get_ddl_kv_mgr(kv_mgr_handle))) { - if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("get ddl kv mgr failed", K(ret), KPC(tablet_ptr_)); - } else { - LOG_TRACE("there is no ddl kv mgr in this tablet", K(ret)); - ret = OB_SUCCESS; - } - } else if (OB_FAIL(kv_mgr_handle.get_obj()->get_ddl_kvs_for_query(*tablet_ptr_, ddl_kvs_handle))) { - LOG_WARN("failed to get all ddl freeze kvs", K(ret)); - } else { - SCN ddl_checkpoint_scn = tablet_ptr_->get_tablet_meta().ddl_checkpoint_scn_; - for (int64_t i = 0; OB_SUCC(ret) && i < ddl_kvs_handle.get_count(); ++i) { - ObDDLKV *ddl_kv = static_cast(ddl_kvs_handle.get_table(i)); - if (OB_ISNULL(ddl_kv)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get ddl kv failed", K(ret), K(i)); - } else if (ddl_kv->is_closed()) { - // skip, because closed meanns ddl dump sstable created - } else if (ddl_kv->get_freeze_scn() > ddl_checkpoint_scn) { - if (OB_FAIL(ddl_kv->prepare_sstable())) { - LOG_WARN("prepare sstable failed", K(ret)); - } else if (OB_FAIL(ddl_memtables.push_back(ddl_kv))) { - LOG_WARN("push back ddl kv failed", K(ret)); - } - } - } - if (OB_SUCC(ret)) { - if (!ddl_memtables.empty() && OB_FAIL(ddl_mem_sstables_.init_and_copy(allocator, ddl_memtables))) { - LOG_WARN("assign ddl memtables failed", K(ret)); - } - } + if (OB_FAIL(tablet.get_ddl_memtables(ddl_memtables))) { + LOG_WARN("failed to get ddl memtables array from tablet", K(ret)); + } else if (!ddl_memtables.empty() && OB_FAIL(ddl_mem_sstables_.init(allocator, ddl_memtables))) { + LOG_WARN("assign ddl memtables failed", K(ret), K(ddl_memtables)); } return ret; } int ObTabletTableStore::build_ddl_sstables( - ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store) { int ret = OB_SUCCESS; - ObITable *new_table = const_cast(param.table_handle_.get_table()); + ObITable *new_table = static_cast(const_cast(param.sstable_)); + ObSSTableMetaHandle new_table_meta_handle; ObArray ddl_dump_sstables; ObArray ddl_mem_sstables; - const bool is_new_table_valid_ddl_sstable = nullptr != new_table && new_table->is_ddl_dump_sstable() - && static_cast(new_table)->get_meta().get_basic_meta().ddl_scn_ >= tablet_ptr_->get_tablet_meta().ddl_start_scn_; + bool is_new_table_valid_ddl_sstable = false; if (OB_UNLIKELY(!param.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(param)); + } else if (OB_ISNULL(new_table)) { + is_new_table_valid_ddl_sstable = false; + } else if (OB_FAIL(static_cast(new_table)->get_meta(new_table_meta_handle))) { + LOG_WARN("fail to get sstable meta handle", K(ret)); + } else { + is_new_table_valid_ddl_sstable = nullptr != new_table && new_table->is_ddl_dump_sstable() + && new_table_meta_handle.get_sstable_meta().get_basic_meta().ddl_scn_ >= tablet.get_tablet_meta().ddl_start_scn_; + } + + if (OB_FAIL(ret)) { } else if (param.ddl_info_.keep_old_ddl_sstable_) { if (!is_new_table_valid_ddl_sstable) { // not valid ddl sstable, simple keep old ddl sstable if (OB_FAIL(old_store.ddl_sstables_.get_all_tables(ddl_dump_sstables))) { @@ -1187,7 +1508,7 @@ int ObTabletTableStore::build_ddl_sstables( LOG_WARN("reserve ddl sstable array failed", K(ret), K(ddl_sstable_count)); } for (int64_t i = 0; OB_SUCC(ret) && i < old_store.ddl_sstables_.count(); ++i) { - if (OB_FAIL(ddl_sstables.push_back(old_store.ddl_sstables_.get_table(i)))) { + if (OB_FAIL(ddl_sstables.push_back(old_store.ddl_sstables_.at(i)))) { LOG_WARN("push back old ddl sstable failed", K(ret), K(i)); } } @@ -1226,43 +1547,57 @@ int ObTabletTableStore::build_ddl_sstables( } if (OB_SUCC(ret) && !ddl_dump_sstables.empty()) { - if (OB_FAIL(ddl_sstables_.init_and_copy(allocator, ddl_dump_sstables))) { + if (OB_FAIL(ddl_sstables_.init(allocator, ddl_dump_sstables))) { LOG_WARN("failed to init ddl_sstables", K(ret)); } } return ret; } -int ObTabletTableStore::check_ready_for_read() +int ObTabletTableStore::build_memtable_array(const ObTablet &tablet) +{ + int ret = OB_SUCCESS; + ObSEArray memtable_array; + if (OB_FAIL(tablet.get_memtables(memtable_array, true/*need_active*/))) { + LOG_WARN("failed to get all memtables from memtable_mgr", K(ret)); + } else if (memtable_array.empty()) { + // empty memtable array + } else if (OB_FAIL(memtables_.build(memtable_array))) { + LOG_WARN("failed to build memtable array", K(ret), K(memtable_array)); + } + return ret; +} + +int ObTabletTableStore::check_ready_for_read(const ObTablet &tablet) { int ret = OB_SUCCESS; is_ready_for_read_ = false; - if (OB_UNLIKELY(!is_inited_ || nullptr == tablet_ptr_)) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("table store not init", K(ret), KPC(this), KPC(tablet_ptr_)); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), KPC(this)); } else if (is_major_sstable_empty()) { LOG_INFO("no valid major sstable, not ready for read", K(*this)); } else if (OB_FAIL(check_continuous())) { LOG_WARN("failed to check continuous of tables", K(ret)); } else if (minor_tables_.count() + 1 > MAX_SSTABLE_CNT_IN_STORAGE) { ret = OB_SIZE_OVERFLOW; - LOG_WARN("Too Many sstables in table store", K(ret), KPC(this), KPC(tablet_ptr_)); + LOG_WARN("Too Many sstables in table store", K(ret), KPC(this), K(tablet)); MTL(concurrency_control::ObMultiVersionGarbageCollector *)->report_sstable_overflow(); } else if (get_table_count() > ObTabletTableStore::MAX_SSTABLE_CNT) { ret = OB_SIZE_OVERFLOW; - LOG_WARN("Too Many sstables, cannot add another sstable any more", K(ret), KPC(this), KPC(tablet_ptr_)); + LOG_WARN("Too Many sstables, cannot add another sstable any more", K(ret), KPC(this), K(tablet)); MTL(concurrency_control::ObMultiVersionGarbageCollector *)->report_sstable_overflow(); - ObPartitionMergePolicy::diagnose_table_count_unsafe(MAJOR_MERGE, *tablet_ptr_); + compaction::ObPartitionMergePolicy::diagnose_table_count_unsafe(MAJOR_MERGE, tablet); } else if (minor_tables_.empty()) { is_ready_for_read_ = true; } else { - const SCN &clog_checkpoint_scn = tablet_ptr_->get_clog_checkpoint_scn(); + const SCN &clog_checkpoint_scn = tablet.get_clog_checkpoint_scn(); const SCN &last_minor_end_scn = minor_tables_.get_boundary_table(true/*last*/)->get_end_scn(); if (OB_UNLIKELY(clog_checkpoint_scn != last_minor_end_scn)) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("last minor table's end_scn must be equal to clog_checkpoint_scn", - K(ret), K(last_minor_end_scn), K(clog_checkpoint_scn), KPC(this), KPC(tablet_ptr_)); + K(ret), K(last_minor_end_scn), K(clog_checkpoint_scn), KPC(this), K(tablet)); } else { is_ready_for_read_ = true; } @@ -1287,7 +1622,7 @@ int ObTabletTableStore::check_continuous() const ret = OB_NOT_INIT; LOG_WARN("table store not inited", K(ret)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < major_tables_.count_; ++i) { + for (int64_t i = 0; OB_SUCC(ret) && i < major_tables_.count(); ++i) { if (OB_UNLIKELY(NULL == (table = major_tables_[i]) || !table->is_major_sstable())) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("table must be major table", K(ret), K(i), KPC(table)); @@ -1301,7 +1636,7 @@ int ObTabletTableStore::check_continuous() const } if (OB_SUCC(ret)) { - if (OB_FAIL(check_minor_tables_continue_(minor_tables_.count(), minor_tables_.array_))) { + if (OB_FAIL(check_minor_tables_continue_(minor_tables_))) { LOG_WARN("failed to check minor tables continue", K(ret), K(minor_tables_)); } } @@ -1309,6 +1644,142 @@ int ObTabletTableStore::check_continuous() const return ret; } +int ObTabletTableStore::batch_cache_sstable_meta( + common::ObArenaAllocator &allocator, + const int64_t remain_size) +{ + int ret = OB_SUCCESS; + common::ObArenaAllocator tmp_allocator("CacheSSTable"); + ObSafeArenaAllocator safe_allocator(tmp_allocator); + common::ObSEArray cache_keys; + common::ObSEArray sstables; + common::ObSEArray cache_handles; + if (OB_UNLIKELY(remain_size < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(remain_size)); + } else if (OB_UNLIKELY(remain_size < sizeof(ObSSTableMeta))) { + // The remain_size is too small to hold an sstable meta. + } else if (OB_FAIL(get_need_to_cache_sstables(cache_keys, sstables))) { + LOG_WARN("fail to get need to cache keys", K(ret)); + } else if (OB_UNLIKELY(0 == cache_keys.count())) { + } else if (OB_FAIL(OB_STORE_CACHE.get_storage_meta_cache().batch_get_meta_and_bypass_cache( + ObStorageMetaValue::SSTABLE, cache_keys, safe_allocator, cache_handles))) { + LOG_WARN("fail to batch get meta and bypass cache", K(ret), K(cache_keys)); + } else if (OB_FAIL(batch_cache_sstable_meta(allocator, remain_size, sstables, cache_handles))) { + LOG_WARN("fail to cache sstable meta", K(ret), K(remain_size), K(sstables), K(cache_handles)); + } + return ret; +} + +int ObTabletTableStore::get_need_to_cache_sstables( + common::ObIArray &keys, + common::ObIArray &sstables) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(get_need_to_cache_sstables(meta_major_tables_, keys, sstables))) { + LOG_WARN("fail to get need to cache sstables", K(ret), K(meta_major_tables_)); + } else if (OB_FAIL(get_need_to_cache_sstables(major_tables_, keys, sstables))) { + LOG_WARN("fail to get need to cache sstables", K(ret), K(major_tables_)); + } else if (OB_FAIL(get_need_to_cache_sstables(minor_tables_, keys, sstables))) { + LOG_WARN("fail to get need to cache sstables", K(ret), K(minor_tables_)); + } else if (OB_FAIL(get_need_to_cache_sstables(ddl_sstables_, keys, sstables))) { + LOG_WARN("fail to get need to cache sstables", K(ret), K(ddl_sstables_)); + } else if (OB_UNLIKELY(keys.count() != sstables.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, the number of keys and sstables is not equal", K(ret), K(keys), K(sstables)); + } + return ret; +} + +int ObTabletTableStore::get_need_to_cache_sstables( + const ObSSTableArray &sstable_array, + common::ObIArray &keys, + common::ObIArray &sstables) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < sstable_array.count(); ++i) { + ObSSTable *sstable = sstable_array[i]; + if (OB_ISNULL(sstable)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, sstable is nullptr", K(ret), KP(sstable)); + } else if (sstable->is_loaded()) { // sstable is already loaded to memory + } else { + ObStorageMetaKey key(MTL_ID(), sstable->get_addr()); + if (OB_FAIL(keys.push_back(key))) { + LOG_WARN("fail to push back meta cache key", K(ret), K(key)); + } else if (OB_FAIL(sstables.push_back(sstable))) { + LOG_WARN("fail to push back sstable ptr", K(ret), KPC(sstable)); + } + } + } + return ret; +} + +int ObTabletTableStore::batch_cache_sstable_meta( + common::ObArenaAllocator &allocator, + const int64_t limit_size, + common::ObIArray &sstables, + common::ObIArray &handles) +{ + int ret = OB_SUCCESS; + int64_t remain_size = limit_size; + if (OB_UNLIKELY(limit_size <= 0 || sstables.count() != handles.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(remain_size), K(sstables), K(handles)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < sstables.count(); ++i) { + ObStorageMetaHandle &handle = handles.at(i); + ObSSTableMetaHandle sst_meta_hdl; + blocksstable::ObSSTable *sstable = sstables.at(i); + blocksstable::ObSSTable *tmp_sstable = nullptr; + if (OB_ISNULL(sstable) || OB_UNLIKELY(!handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(sstable), K(handle)); + } else if (OB_FAIL(handle.get_sstable(tmp_sstable))) { + LOG_WARN("fail to get sstable", K(ret), K(handle)); + } else if (OB_FAIL(tmp_sstable->get_meta(sst_meta_hdl))) { + LOG_WARN("fail to get sstable meta", K(ret)); + } else { + const int64_t deep_copy_size = sst_meta_hdl.get_sstable_meta().get_deep_copy_size(); + int64_t pos = 0; + if (0 <= remain_size - deep_copy_size) { + // cache local sstable meta + char *buf = nullptr; + ObSSTableMeta *copied_sstable_meta = nullptr; + if (OB_ISNULL(buf = static_cast(allocator.alloc(deep_copy_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for sstable", K(ret), K(deep_copy_size)); + } else if (OB_FAIL(sst_meta_hdl.get_sstable_meta().deep_copy(buf, deep_copy_size, pos, copied_sstable_meta))) { + LOG_WARN("fail to copy read cache to local sstable meta array", K(ret)); + } else if (OB_FAIL(sstable->assign_meta(copied_sstable_meta))) { + LOG_WARN("fail to assign cached sstable meta to sstable", K(ret), KPC(sstable)); + } else { + remain_size -= deep_copy_size; + } + } else { + break; // The remaining size is not enough to hold the sstable meta. + } + } + } + } + return ret; +} + +template +int ObTabletTableStore::check_minor_tables_continue_(T &minor_tables) const +{ + int ret = OB_SUCCESS; + ObITable *prev_table = nullptr; + prev_table = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables.count(); ++i) { + ObITable *table = minor_tables.at(i); + if (OB_FAIL(check_minor_table_continue_(table, prev_table))) { + LOG_WARN("failed to check minor table continue", K(ret), KPC(table)); + } + } + return ret; +} + int ObTabletTableStore::need_remove_old_table( const int64_t multi_version_start, bool &need_remove) const @@ -1330,196 +1801,82 @@ int ObTabletTableStore::need_remove_old_table( // don't need to care about kept_multi_version_start here // becase major_tables_[0]::snapshot_version must <= kept_multi_version_start need_remove = true; - FLOG_INFO("need recycle unused minor table", K(ret), KPC(minor_tables_[0]), KPC(major_tables_[0])); + LOG_INFO("need recycle unused minor table", K(ret), KPC(minor_tables_[0]), KPC(major_tables_[0])); } else if (major_tables_.count() > 1 && major_tables_[1]->get_snapshot_version() <= multi_version_start) { need_remove = true; - FLOG_INFO("need recycle oldest major sstable", K(ret), K(multi_version_start), KPC(major_tables_[1])); + LOG_INFO("need recycle oldest major sstable", K(ret), K(multi_version_start), KPC(major_tables_[1])); } return ret; } -int64_t ObTabletTableStore::to_string(char *buf, const int64_t buf_len) const -{ - int64_t pos = 0; - if (OB_ISNULL(buf) || buf_len <= 0) { - // do nothing - } else { - J_OBJ_START(); - J_NAME("ObTabletTableStore"); - J_COLON(); - J_KV(KP(this), KP_(tablet_ptr), K_(major_tables), K_(minor_tables), K_(memtables), K_(is_ready_for_read)); - J_COMMA(); - J_ARRAY_START(); - if (major_tables_.is_valid()) { - for (int64_t i = 0; i < major_tables_.count_; ++i) { - ObITable *table = major_tables_[i]; - if (NULL != table && table->is_sstable()) { - J_OBJ_START(); - J_KV(K(i), "ptr", table, "type", ObITable::get_table_type_name(table->get_key().table_type_), - "tablet_id", table->get_key().tablet_id_, - "scn_range", table->get_key().scn_range_, - "ref", table->get_ref(), - "snapshot_version", table->get_snapshot_version(), - "max_merge_version", static_cast(table)->get_max_merged_trans_version(), - "table_mode_flag", static_cast(table)->get_meta().get_basic_meta().table_mode_.mode_flag_); - J_OBJ_END(); - J_COMMA(); - } - } - } - if (minor_tables_.is_valid()) { - for (int64_t i = 0; i < minor_tables_.count_; ++i) { - ObITable *table = minor_tables_[i]; - if (NULL != table && table->is_sstable()) { - J_OBJ_START(); - J_KV(K(i), "ptr", table, "type", ObITable::get_table_type_name(table->get_key().table_type_), - "tablet_id", table->get_key().tablet_id_, - "scn_range", table->get_key().scn_range_, - "ref", table->get_ref(), - "contain_uncommitted_row", static_cast(table)->get_meta().contain_uncommitted_row() ? "yes" : "no", - "max_merge_version", static_cast(table)->get_max_merged_trans_version(), - "upper_trans_version", static_cast(table)->get_upper_trans_version(), - "table_mode_flag", static_cast(table)->get_meta().get_basic_meta().table_mode_.mode_flag_); - J_OBJ_END(); - J_COMMA(); - } - } - } - if (ddl_sstables_.is_valid()) { - for (int64_t i = 0; i < ddl_sstables_.count_; ++i) { - ObITable *table = ddl_sstables_[i]; - if (NULL != table && table->is_sstable()) { - J_OBJ_START(); - J_KV(K(i), "ptr", table, "type", ObITable::get_table_type_name(table->get_key().table_type_), - "tablet_id", table->get_key().tablet_id_, - "scn_range", table->get_key().scn_range_, - "ref", table->get_ref(), - "max_merge_version", static_cast(table)->get_max_merged_trans_version(), - "table_mode_flag", static_cast(table)->get_meta().get_basic_meta().table_mode_.mode_flag_); - J_OBJ_END(); - J_COMMA(); - } - } - } - if (ddl_mem_sstables_.is_valid()) { - for (int64_t i = 0; i < ddl_mem_sstables_.count_; ++i) { - ObITable *table = ddl_mem_sstables_[i]; - if (NULL != table && table->is_sstable()) { - J_OBJ_START(); - J_KV(K(i), "ptr", table, "type", ObITable::get_table_type_name(table->get_key().table_type_), - "tablet_id", table->get_key().tablet_id_, - "scn_range", table->get_key().scn_range_, - "ref", table->get_ref(), - "max_merge_version", static_cast(table)->get_max_merged_trans_version(), - "table_mode_flag", static_cast(table)->get_meta().get_basic_meta().table_mode_.mode_flag_); - J_OBJ_END(); - J_COMMA(); - } - } - } - if (extend_tables_.is_valid()) { - for (int64_t i = 0; i < extend_tables_.count_; ++i) { - ObITable *table = extend_tables_[i]; - if (NULL != table && table->is_sstable()) { - J_OBJ_START(); - J_KV(K(i), "ptr", table, "type", ObITable::get_table_type_name(table->get_key().table_type_), - "tablet_id", table->get_key().tablet_id_, - "scn_range", table->get_key().scn_range_, - "ref", table->get_ref(), - "max_merge_version", static_cast(table)->get_max_merged_trans_version(), - "table_mode_flag", static_cast(table)->get_meta().get_basic_meta().table_mode_.mode_flag_); - J_OBJ_END(); - J_COMMA(); - } - } - } - J_ARRAY_END(); - J_OBJ_END(); - } - return pos; -} - -int ObTabletTableStore::get_ddl_sstable_handles(ObTablesHandleArray &ddl_sstable_handles) const +int ObTabletTableStore::build_ha_new_table_store( + common::ObArenaAllocator &allocator, + ObTablet &tablet, + const ObBatchUpdateTableStoreParam ¶m, + const ObTabletTableStore &old_store) { int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("table store is not inited", K(ret)); - } else if (OB_FAIL(ddl_sstables_.get_all_tables(ddl_sstable_handles))) { - LOG_WARN("failed to get ddl sstables handle", K(ret)); - } - return ret; -} - -int ObTabletTableStore::get_ha_tables( - ObTableStoreIterator &iterator, - bool &is_ready_for_read) -{ - int ret = OB_SUCCESS; - iterator.reset(); - is_ready_for_read = false; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("table store is not inited", K(ret)); - } else if (FALSE_IT(is_ready_for_read = is_ready_for_read_)) { - } else if (!major_tables_.empty() && OB_FAIL(iterator.add_tables(major_tables_.array_, major_tables_.count_))) { - LOG_WARN("failed to add major table to iterator", K(ret)); - } else if (!minor_tables_.empty() && OB_FAIL(iterator.add_tables(minor_tables_.array_, minor_tables_.count_))) { - LOG_WARN("failed to add minor table to iterator", K(ret)); - } else if (!ddl_sstables_.empty() && OB_FAIL(iterator.add_tables(ddl_sstables_.array_, ddl_sstables_.count_))) { - LOG_WARN("failed to add ddl table to iterator", K(ret)); - } else if (OB_FAIL(iterator.set_retire_check())) { - LOG_WARN("failed to set retire check to iterator", K(ret)); - } else { - LOG_INFO("succeed get ha tables", K(major_tables_), K(minor_tables_), K(ddl_sstables_)); + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid() || !old_store.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("init tablet table store get invalid argument", K(ret), K(tablet), K(param), K(old_store)); + } else if (OB_FAIL(init(allocator, tablet))) { + LOG_WARN("failed to init a new empty table store", K(ret)); + } else if (OB_FAIL(build_ha_new_table_store_(allocator, tablet, param, old_store))) { + LOG_WARN("failed to build new table store with old store", K(ret)); } return ret; } int ObTabletTableStore::build_ha_new_table_store_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store) { int ret = OB_SUCCESS; - const ObExtendTableArray &meta_major_table = old_store.extend_tables_; + const ObSSTableArray &meta_major_table = old_store.meta_major_tables_; int64_t inc_base_snapshot_version = 0; - ObTableHandleV2 tmp_handle; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("table store is not inited", K(ret)); - } else if (!param.is_valid() || !old_store.is_valid()) { + } else if (OB_UNLIKELY(!param.is_valid() || !old_store.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("build ha new table store get invalid argument", K(ret), K(param), K(old_store)); } else if (OB_FAIL(build_ha_major_tables_(allocator, param, old_store, inc_base_snapshot_version))) { LOG_WARN("failed to build ha major tables", K(ret), K(param), K(old_store)); - } else if (OB_FAIL(build_ha_minor_tables_(allocator, param, old_store, inc_base_snapshot_version))) { + } else if (OB_FAIL(build_ha_minor_tables_(allocator, tablet, param, old_store, inc_base_snapshot_version))) { LOG_WARN("failed to build ha minor tables", K(ret), K(param), K(old_store)); - } else if (OB_FAIL(build_ha_ddl_tables_(allocator, param, old_store))) { + } else if (OB_FAIL(build_ha_ddl_tables_(allocator, tablet, param, old_store))) { LOG_WARN("failed to build ha ddl tables", K(ret), K(param), K(old_store)); - } else if (!meta_major_table.empty() && OB_FAIL(build_meta_major_table(tmp_handle, old_store))) { - LOG_WARN("failed to build buf minor table", K(ret), K(old_store)); - } else if (OB_FAIL(pull_memtables())) { + } else if (!meta_major_table.empty() && OB_FAIL(build_meta_major_table(allocator, nullptr/*new sstable*/, old_store))) { + LOG_WARN("failed to build meta major table", K(ret), K(old_store)); + } else if (OB_FAIL(build_memtable_array(tablet))) { LOG_WARN("failed to pull memtable from memtable_mgr", K(ret)); - } else if (OB_FAIL(pull_ddl_memtables(allocator))) { + } else if (OB_FAIL(pull_ddl_memtables(allocator, tablet))) { LOG_WARN("pull_ddl_memtables failed", K(ret)); - } else if (OB_FAIL(check_ready_for_read())) { - LOG_WARN("failed to check ready for read", K(ret)); } else { - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = init_read_cache())) { - LOG_WARN("failed to cache read iterator", K(tmp_ret)); + is_inited_ = true; + if (OB_FAIL(check_ready_for_read(tablet))) { + LOG_WARN("failed to check ready for read", K(ret)); + } else { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_cache_local_sstables(allocator))) { + LOG_WARN("failed to try cache local sstables", K(tmp_ret)); + } + FLOG_INFO("succeed to build ha new table store", + K(major_tables_), K(minor_tables_), K(memtables_), K(PRINT_TS(*this))); } - FLOG_INFO("succeed to build ha new table store", K(major_tables_), K(minor_tables_), K(memtables_), K(PRINT_TS(*this))); } return ret; } int ObTabletTableStore::build_ha_major_tables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store, int64_t &inc_base_snapshot_version) @@ -1530,17 +1887,71 @@ int ObTabletTableStore::build_ha_major_tables_( const bool allow_duplicate_sstable = true; const int64_t multi_version_start = 0; - if (!old_store.major_tables_.empty() && OB_FAIL(old_store.major_tables_.get_all_tables(major_tables))) { - LOG_WARN("failed to get all tables", K(ret), K(old_store)); - } else if (OB_FAIL(inner_build_major_tables_(allocator, old_store, param.tables_handle_, + if (!param.tables_handle_.empty() && OB_FAIL(param.tables_handle_.get_tables(major_tables))) { + LOG_WARN("failed to get major tables from param", K(ret)); + } else if (OB_FAIL(inner_build_major_tables_(allocator, old_store, major_tables, multi_version_start, allow_duplicate_sstable, inc_base_snapshot_version))) { LOG_WARN("failed to inner build major tables", K(ret), K(param)); } return ret; } +int ObTabletTableStore::replace_transfer_minor_sstables_( + common::ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObBatchUpdateTableStoreParam ¶m, + const ObTabletTableStore &old_store) +{ + int ret = OB_SUCCESS; + ObArray new_minor_tables; + ObSEArray need_add_minor_tables; + ObSEArray old_minor_tables; + const int64_t inc_pos = 0; + ObArray cut_minor_tables; + + if (OB_FAIL(param.tables_handle_.get_all_minor_sstables(need_add_minor_tables))) { + LOG_WARN("failed to add need add minor tables", K(ret), K(param)); + } else if (OB_FAIL(old_store.minor_tables_.get_all_tables(old_minor_tables))) { + LOG_WARN("failed to get old minor tables", K(ret), K(old_store)); + } else if (OB_FAIL(check_old_store_minor_sstables_(old_minor_tables))) { + LOG_WARN("failed to check old store minor sstables", K(ret), K(old_minor_tables)); + } else if (OB_FAIL(combine_transfer_minor_sstables_(allocator, tablet, old_minor_tables, + need_add_minor_tables, param, new_minor_tables))) { + LOG_WARN("failed to combine transfer minor sstables", K(ret), K(old_store), K(param)); + } + + if (OB_FAIL(ret)) { + } else if (new_minor_tables.empty()) { + LOG_INFO("minor tables is empty, skip it", K(ret), K(new_minor_tables)); + } else if (OB_FAIL(ObTableStoreUtil::sort_minor_tables(new_minor_tables))) { + LOG_WARN("failed to sort minor tables", K(ret)); + } else if (OB_FAIL(cut_ha_sstable_scn_range_(allocator, new_minor_tables, cut_minor_tables))) { + LOG_WARN("failed to cut ha sstable log ts range", K(ret), K(old_store), K(param)); + } else if (OB_FAIL(check_minor_tables_continue_(cut_minor_tables.count(), cut_minor_tables.get_data()))) { + LOG_WARN("minor tables is not continue", K(ret), K(param), K(new_minor_tables), K(old_store)); + } else if (tablet.get_tablet_meta().ha_status_.is_data_status_complete() + && cut_minor_tables.at(cut_minor_tables.count() - 1)->get_end_scn() != tablet.get_tablet_meta().clog_checkpoint_scn_) { + // When the tablet's is_data_status_complete=false, it means that the data of the tablet has not been copied during the migration process. + // In this scenario, no check is allowed. + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet meta is not match with minor sstables", K(ret), K(cut_minor_tables), K(param), K(tablet.get_tablet_meta())); + } else if (OB_FAIL(minor_tables_.init(allocator, cut_minor_tables, inc_pos))) { + LOG_WARN("failed to init minor_tables", K(ret)); + } else { + LOG_INFO("succeed build transfer minor sstables", K(old_store), K(cut_minor_tables)); + } + return ret; +} + +//migration will add tables with ddl and minor tables. replace_ha_minor_sstables_ will copy old minor +//tables when add ddl tables with param.update_ddl_sstable_ = true. +//new_minor_tables is empty +// The corresponding reason may be that there is no minor at the source or the transfer_in tablet still exists in the transfer table +//new_minor_tables is not empty +// Tablet still has a transfer table, so need to check the continuity of the transfer table and minor sstable int ObTabletTableStore::replace_ha_minor_sstables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store, const int64_t inc_base_snapshot_version) @@ -1551,8 +1962,7 @@ int ObTabletTableStore::replace_ha_minor_sstables_( ObSEArray need_add_minor_tables; ObSEArray old_minor_tables; const int64_t inc_pos = 0; - ObTablesHandleArray tables_handle; - ObArray minor_tables; + ObArray cut_minor_tables; if (OB_FAIL(param.tables_handle_.get_all_minor_sstables(need_add_minor_tables))) { LOG_WARN("failed to add need add minor tables", K(ret), K(param)); @@ -1560,15 +1970,22 @@ int ObTabletTableStore::replace_ha_minor_sstables_( LOG_WARN("failed to get old minor tables", K(ret), K(old_store)); } else if (OB_FAIL(check_old_store_minor_sstables_(old_minor_tables))) { LOG_WARN("failed to check old store minor sstables", K(ret), K(old_minor_tables)); - } else if (need_add_minor_tables.empty()) { - if (old_minor_tables.empty()) { - } else if (OB_FAIL(minor_tables_.init_and_copy(allocator, old_minor_tables, inc_pos))) { + } else if (param.update_ddl_sstable_) { + if (!need_add_minor_tables.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("update ddl sstable but minor tables is not empty", K(ret), K(param), K(old_store)); + } else if (old_minor_tables.empty()) { + } else if (OB_FAIL(minor_tables_.init(allocator, old_minor_tables, inc_pos))) { LOG_WARN("failed to init minor_tables", K(ret)); } - } else if (OB_FAIL(combin_ha_minor_sstables_(old_minor_tables, need_add_minor_tables, new_minor_tables))) { + } else if (OB_FAIL(combine_ha_minor_sstables_( + tablet, old_minor_tables, need_add_minor_tables, new_minor_tables))) { LOG_WARN("failed to combin ha minor sstables", K(ret), K(old_store), K(param)); } else if (new_minor_tables.empty()) { // no minor tables - if (tablet_ptr_->get_tablet_meta().start_scn_ != tablet_ptr_->get_tablet_meta().clog_checkpoint_scn_) { + if ((tablet.get_tablet_meta().start_scn_ != tablet.get_tablet_meta().clog_checkpoint_scn_ + && !tablet.get_tablet_meta().has_transfer_table()) + || (tablet.get_tablet_meta().has_transfer_table() + && tablet.get_tablet_meta().transfer_info_.transfer_start_scn_ != tablet.get_tablet_meta().clog_checkpoint_scn_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet meta is not match with minor sstables", K(ret), K(new_minor_tables), K(param), K(old_store)); } else { @@ -1576,26 +1993,26 @@ int ObTabletTableStore::replace_ha_minor_sstables_( } } else if (OB_FAIL(ObTableStoreUtil::sort_minor_tables(new_minor_tables))) { LOG_WARN("failed to sort minor tables", K(ret)); - } else if (OB_FAIL(cut_ha_sstable_scn_range_(new_minor_tables, tables_handle))) { + } else if (OB_FAIL(cut_ha_sstable_scn_range_(allocator, new_minor_tables, cut_minor_tables))) { LOG_WARN("failed to cut ha sstable log ts range", K(ret), K(old_store), K(param)); - } else if (OB_FAIL(tables_handle.get_tables(minor_tables))) { - LOG_WARN("failed to get minor tables", K(ret), K(tables_handle)); - } else if (OB_FAIL(check_minor_tables_continue_(minor_tables.count(), minor_tables.get_data()))) { - LOG_WARN("minor tables is not continue", K(ret), K(param), K(minor_tables), K(old_store)); - } else if (minor_tables.at(0)->get_start_scn() > tablet_ptr_->get_tablet_meta().start_scn_ - || minor_tables.at(minor_tables.count() - 1)->get_end_scn() != tablet_ptr_->get_tablet_meta().clog_checkpoint_scn_) { + } else if (OB_FAIL(check_minor_tables_continue_(cut_minor_tables.count(), cut_minor_tables.get_data()))) { + LOG_WARN("minor tables is not continue", K(ret), K(param), K(cut_minor_tables), K(old_store)); + } else if (cut_minor_tables.at(cut_minor_tables.count() - 1)->get_end_scn() != tablet.get_tablet_meta().clog_checkpoint_scn_ + || (tablet.get_tablet_meta().has_transfer_table() + && tablet.get_tablet_meta().transfer_info_.transfer_start_scn_ != cut_minor_tables.at(0)->get_start_scn())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet meta is not match with minor sstables", K(ret), K(minor_tables), K(param), K(old_store)); - } else if (OB_FAIL(minor_tables_.init_and_copy(allocator, minor_tables, inc_pos))) { + LOG_WARN("tablet meta is not match with minor sstables", K(ret), K(cut_minor_tables), K(param), K(old_store), "tablet_meta", tablet.get_tablet_meta()); + } else if (OB_FAIL(minor_tables_.init(allocator, cut_minor_tables, inc_pos))) { LOG_WARN("failed to init minor_tables", K(ret)); } else { - LOG_INFO("succeed build ha minor sstables", K(old_store), K(minor_tables)); + LOG_INFO("succeed build ha minor sstables", K(old_store), K(cut_minor_tables)); } return ret; } int ObTabletTableStore::build_ha_ddl_tables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store) { @@ -1604,8 +2021,9 @@ int ObTabletTableStore::build_ha_ddl_tables_( ObITable *new_table = nullptr; ObITable *last_ddl_table = nullptr; bool need_add_ddl_tables = true; + ObSSTableMetaHandle new_meta_handle; - if (!old_store.get_major_sstables().empty()) { + if (!old_store.major_tables_.empty()) { need_add_ddl_tables = false; } @@ -1619,7 +2037,9 @@ int ObTabletTableStore::build_ha_ddl_tables_( break; } else if (!new_table->is_ddl_sstable()) { //do nothing - } else if (static_cast(new_table)->get_meta().get_basic_meta().ddl_scn_ < tablet_ptr_->get_tablet_meta().ddl_start_scn_) { + } else if (OB_FAIL(static_cast(new_table)->get_meta(new_meta_handle))) { + LOG_WARN("get new table meta fail", K(ret), KPC(new_table)); + } else if (new_meta_handle.get_sstable_meta().get_basic_meta().ddl_scn_ < tablet.get_tablet_meta().ddl_start_scn_) { // the ddl start scn is old, drop it } else if (OB_NOT_NULL(last_ddl_table) && new_table->get_start_scn() != last_ddl_table->get_end_scn()) { ret = OB_ERR_UNEXPECTED; @@ -1651,7 +2071,7 @@ int ObTabletTableStore::build_ha_ddl_tables_( LOG_INFO("has major sstable ,no need add ddl sstable", K(param), K(old_store)); } else if (ddl_tables.empty()) { // no minor tables LOG_INFO("ddl tables is empty, skip it", K(ret), K(ddl_tables)); - } else if (OB_FAIL(ddl_sstables_.init_and_copy(allocator, ddl_tables))) { + } else if (OB_FAIL(ddl_sstables_.init(allocator, ddl_tables))) { LOG_WARN("failed to init minor_tables", K(ret)); } } @@ -1659,14 +2079,14 @@ int ObTabletTableStore::build_ha_ddl_tables_( } int ObTabletTableStore::cut_ha_sstable_scn_range_( - common::ObIArray &minor_sstables, - ObTablesHandleArray &tables_handle) + common::ObArenaAllocator &allocator, + common::ObIArray &orig_minor_sstables, + common::ObIArray &cut_minor_sstables) { int ret = OB_SUCCESS; SCN last_end_scn = SCN::min_scn(); - for (int64_t i = 0; OB_SUCC(ret) && i < minor_sstables.count(); ++i) { - ObITable *table = minor_sstables.at(i); - ObTableHandleV2 new_table_handle; + for (int64_t i = 0; OB_SUCC(ret) && i < orig_minor_sstables.count(); ++i) { + ObITable *table = orig_minor_sstables.at(i); if (OB_ISNULL(table) || !table->is_multi_version_minor_sstable()) { ret = OB_ERR_UNEXPECTED; @@ -1675,15 +2095,30 @@ int ObTabletTableStore::cut_ha_sstable_scn_range_( last_end_scn = table->get_end_scn(); } else if (last_end_scn < table->get_start_scn() || last_end_scn >= table->get_end_scn()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("minor sstable log ts is not continue or scn has overlap", K(ret), K(minor_sstables)); + LOG_WARN("minor sstable log ts is not continue or scn has overlap", K(ret), K(orig_minor_sstables)); } else if (last_end_scn == table->get_start_scn()) { last_end_scn = table->get_end_scn(); } else { ObSSTable *sstable = static_cast(table); - if (OB_FAIL(deep_copy_sstable_(*sstable, new_table_handle))) { - LOG_WARN("failed to deep copy sstable", KPC(sstable), K(new_table_handle)); + ObSSTable *orig_sstable = nullptr; + ObSSTable *copied_sstable = nullptr; + ObMetaDiskAddr addr; + addr.set_mem_addr(0, sizeof(ObSSTable)); + ObStorageMetaHandle sstable_handle; + if (sstable->is_loaded()) { + orig_sstable = sstable; + } else if (OB_FAIL(ObTabletTableStore::load_sstable(sstable->get_addr(), sstable_handle))) { + LOG_WARN("failed to load sstable", K(ret), KPC(sstable)); + } else if (OB_FAIL(sstable_handle.get_sstable(orig_sstable))) { + LOG_WARN("failed to get sstable from sstable handle", K(ret), K(sstable_handle)); + } + + if (FAILEDx(orig_sstable->deep_copy(allocator, copied_sstable))) { + LOG_WARN("failed to deep copy sstable", K(ret), KPC(orig_sstable), KP(copied_sstable)); + } else if (OB_FAIL(copied_sstable->set_addr(addr))) { + LOG_WARN("failed to set sstable addr", K(ret), K(addr), KPC(copied_sstable)); } else { - table = new_table_handle.get_table(); + table = copied_sstable; ObScnRange new_scn_range; ObScnRange original_scn_range = table->get_scn_range(); new_scn_range.start_scn_ = last_end_scn; @@ -1691,7 +2126,8 @@ int ObTabletTableStore::cut_ha_sstable_scn_range_( table->set_scn_range(new_scn_range); last_end_scn = table->get_end_scn(); - LOG_INFO("cut ha sstable log ts range", KPC(sstable), K(new_scn_range), K(original_scn_range)); + LOG_INFO("cut ha sstable log ts range", KPC(orig_sstable), KPC(copied_sstable), + K(new_scn_range), K(original_scn_range)); } } @@ -1699,7 +2135,7 @@ int ObTabletTableStore::cut_ha_sstable_scn_range_( if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table should not be NULL", K(ret), KP(table)); - } else if (OB_FAIL(tables_handle.add_table(table))) { + } else if (OB_FAIL(cut_minor_sstables.push_back(table))) { LOG_WARN("failed to add table into array", K(ret), KPC(table)); } } @@ -1707,125 +2143,135 @@ int ObTabletTableStore::cut_ha_sstable_scn_range_( return ret; } +int ObTabletTableStore::check_minor_table_continue_( + ObITable *table, + ObITable *prev_table) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_ISNULL(table) || !table->is_multi_version_minor_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must be multi version minor table", K(ret), KPC(table)); + } else if (OB_ISNULL(prev_table)) { + // do nothing + } else if (table->get_start_scn() > prev_table->get_end_scn() + || table->get_end_scn() <= prev_table->get_end_scn()) { + ret = OB_ERR_SYS; + LOG_ERROR("table scn range not continuous or overlap", K(ret), KPC(table), KPC(prev_table)); + } + prev_table = table; + return ret; +} + int ObTabletTableStore::check_minor_tables_continue_( const int64_t count, ObITable **minor_sstables) const { int ret = OB_SUCCESS; ObITable *prev_table = nullptr; - ObITable *table = nullptr; prev_table = nullptr; - if (count > 0 && OB_ISNULL(minor_sstables)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("check minor tables continue minor sstables is unexpected", KP(minor_sstables), K(count)); + LOG_WARN("check minor tables continue minor sstables is unexpected", K(ret), KP(minor_sstables), K(count)); } for (int64_t i = 0; OB_SUCC(ret) && i < count; ++i) { - if (OB_UNLIKELY(NULL == (table = minor_sstables[i]) || !table->is_multi_version_minor_sstable())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table must be multi version minor table", K(ret), K(i), KPC(table)); - } else if (OB_ISNULL(prev_table)) { - } else if (table->get_start_scn() > prev_table->get_end_scn() - || table->get_end_scn() <= prev_table->get_end_scn()) { - ret = OB_ERR_SYS; - LOG_ERROR("table scn range not continuous or overlap", K(ret), KPC(table), KPC(prev_table)); + ObITable *table = minor_sstables[i]; + if (OB_FAIL(check_minor_table_continue_(table, prev_table))) { + LOG_WARN("failed to check minor table continue", K(ret), KPC(table)); } - prev_table = table; } return ret; } -int ObTabletTableStore::combin_ha_minor_sstables_( +int ObTabletTableStore::combine_ha_minor_sstables_( + const ObTablet &tablet, common::ObIArray &old_store_minor_sstables, common::ObIArray &need_add_minor_sstables, common::ObIArray &new_minor_sstables) { int ret = OB_SUCCESS; - SCN logical_start_scn = ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN; - SCN logical_end_scn = ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN; - SCN max_copy_end_scn = ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN; - int64_t old_store_minor_tables_index = 0; + //TODO(muwei.ym) remove logical sstable in master + //1.ha now will not reuse minor sstable so it need add minor sstable which is from src and end_scn <= clog_checkpoint_scn + //2.old store minor sstables contains remote logical sstable and after clog_checkpoint_scn sstables. + SCN max_copy_end_scn; + max_copy_end_scn.set_min(); + for (int64_t i = 0; OB_SUCC(ret) && i < need_add_minor_sstables.count(); ++i) { + ObITable *table = need_add_minor_sstables.at(i); + if (OB_FAIL(new_minor_sstables.push_back(table))) { + LOG_WARN("failed to push table into array", K(ret), KPC(table)); + } else { + max_copy_end_scn = table->get_end_scn(); + } + } - //get remote logical minor sstable log ts for (int64_t i = 0; OB_SUCC(ret) && i < old_store_minor_sstables.count(); ++i) { ObITable *table = old_store_minor_sstables.at(i); - old_store_minor_tables_index = i; if (table->is_remote_logical_minor_sstable()) { - logical_start_scn = table->get_start_scn(); - logical_end_scn = table->get_end_scn(); - break; + if (max_copy_end_scn < table->get_end_scn() && !max_copy_end_scn.is_min()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("remote logical minor sstable end scn is bigger than max copy end scn, unexpected", + K(ret), K(max_copy_end_scn), KPC(table)); + } + } else if (table->get_end_scn() <= max_copy_end_scn) { + //do nothing + } else if (OB_FAIL(new_minor_sstables.push_back(table))) { + LOG_WARN("failed to push table into array", K(ret), KPC(table)); + } + } + return ret; +} + +int ObTabletTableStore::combine_transfer_minor_sstables_( + common::ObArenaAllocator &allocator, + const ObTablet &tablet, + common::ObIArray &old_store_minor_sstables, + common::ObIArray &need_add_minor_sstables, + const ObBatchUpdateTableStoreParam ¶m, + common::ObIArray &new_minor_sstables) +{ + int ret = OB_SUCCESS; + + for (int64_t i = 0; OB_SUCC(ret) && i < need_add_minor_sstables.count(); ++i) { + ObITable *table = need_add_minor_sstables.at(i); + if (OB_ISNULL(table) || !table->is_minor_sstable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("new table is null or table type is unexpected", K(ret), KPC(table)); + } else if (table->get_start_scn() >= tablet.get_tablet_meta().transfer_info_.transfer_start_scn_) { + //do nothing + } else if (table->get_end_scn() <= tablet.get_tablet_meta().transfer_info_.transfer_start_scn_) { + if (OB_FAIL(new_minor_sstables.push_back(table))) { + LOG_WARN("failed to push table into array", K(ret), KPC(table)); + } + } else { + ObSSTable *old_sstable = static_cast(table); + ObSSTable *sstable = NULL; + if (OB_FAIL(old_sstable->deep_copy(allocator, sstable))) { + LOG_WARN("failed to copy sstable", K(ret), KP(old_sstable)); + } else { + ObScnRange new_scn_range; + ObScnRange original_scn_range = sstable->get_scn_range(); + new_scn_range.start_scn_ = original_scn_range.start_scn_; + new_scn_range.end_scn_ = tablet.get_tablet_meta().transfer_info_.transfer_start_scn_; + sstable->set_scn_range(new_scn_range); + FLOG_INFO("cut ha sstable log ts range", KPC(sstable), K(new_scn_range), K(original_scn_range), K(param)); + + if (OB_FAIL(new_minor_sstables.push_back(sstable))) { + LOG_WARN("failed to push table into array", K(ret), KPC(sstable)); + } + } + } + } + + for (int64_t i = 0; OB_SUCC(ret) && i < old_store_minor_sstables.count(); ++i) { + ObITable *table = old_store_minor_sstables.at(i); + if (OB_ISNULL(table) || !table->is_minor_sstable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table is null or table type is unexpected", K(ret), KPC(table)); } else if (OB_FAIL(new_minor_sstables.push_back(table))) { LOG_WARN("failed to push minor table into array", K(ret), K(old_store_minor_sstables), KPC(table)); - } else { - max_copy_end_scn = std::max(table->get_end_scn(), max_copy_end_scn); } } - //push new sstable into array - const SCN checkpoint_scn = tablet_ptr_->get_clog_checkpoint_scn(); - if (OB_SUCC(ret)) { - if (need_add_minor_sstables.empty()) { - //do nothing - } else { - bool found = false; - int64_t param_table_index = 0; - for (int64_t i = 0; OB_SUCC(ret) && i < need_add_minor_sstables.count() && !found; ++i) { - ObITable *new_table = need_add_minor_sstables.at(i); - if (OB_ISNULL(new_table) || !new_table->is_minor_sstable()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("new table is null or table type is unexpected", K(ret), KPC(new_table)); - } else if (!found && new_table->get_start_scn() <= logical_start_scn - && new_table->get_end_scn() >= logical_start_scn) { - found = true; - param_table_index = i; - } else if (new_table->get_start_scn() >= checkpoint_scn) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("[MIGRATION ERROR] table's start log scn must be less than checkpoint scn", - K(ret), KPC(this), KPC(tablet_ptr_)); - } - } - - if (OB_SUCC(ret) && !found && ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN != logical_end_scn) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("can not find table continue with old table store", K(ret), - K(old_store_minor_sstables), K(logical_start_scn), K(logical_end_scn), K(need_add_minor_sstables)); - } - - for (int64_t i = param_table_index; OB_SUCC(ret) && i < need_add_minor_sstables.count(); ++i) { - ObITable *new_table = need_add_minor_sstables.at(i); - if (OB_ISNULL(new_table) || !new_table->is_minor_sstable()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("new table is null or table type is unexpected", K(ret), KPC(new_table)); - } else if (new_table->get_end_scn() <= max_copy_end_scn) { - //do nothing - //need_add_minor_sstables is copied from src. - //Old table store table will be reused when new table end log ts is smaller than old table. - } else if (OB_FAIL(new_minor_sstables.push_back(new_table))) { - LOG_WARN("failed to push minor table into array", K(ret), K(new_minor_sstables), KPC(new_table)); - } else if (new_table->get_end_scn() > max_copy_end_scn) { - max_copy_end_scn = new_table->get_end_scn(); - } - } - - if (OB_SUCC(ret) && max_copy_end_scn < logical_end_scn) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("need add minor tables can not cover remote logical minor log ts", K(ret), - K(need_add_minor_sstables), K(old_store_minor_sstables), K(max_copy_end_scn), K(logical_end_scn)); - } - } - } - //push old table store left table into array - if (OB_SUCC(ret)) { - for (int64_t i = old_store_minor_tables_index + 1; OB_SUCC(ret) && i < old_store_minor_sstables.count(); ++i) { - ObITable *table = old_store_minor_sstables.at(i); - if (table->get_end_scn() <= max_copy_end_scn) { - //do nothing - } else if (OB_FAIL(new_minor_sstables.push_back(table))) { - LOG_WARN("failed to push table into array", K(ret), K(table)); - } - } - } return ret; } @@ -1835,7 +2281,7 @@ int ObTabletTableStore::check_old_store_minor_sstables_( int ret = OB_SUCCESS; int64_t remote_logical_minor_sstable_count = 0; - if (OB_FAIL(check_minor_tables_continue_(old_store_minor_sstables.count(), old_store_minor_sstables.get_data()))) { + if (OB_FAIL(check_minor_tables_continue_(old_store_minor_sstables))) { LOG_WARN("failed to check minor tables continue", K(ret), K(old_store_minor_sstables)); } @@ -1856,30 +2302,13 @@ int ObTabletTableStore::check_old_store_minor_sstables_( return ret; } -int ObTabletTableStore::get_mini_minor_sstables(ObTablesHandleArray &minor_sstables) const -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("table store is not inited", K(ret)); - } else if (tablet_ptr_->get_tablet_meta().ha_status_.is_data_status_complete()) { - if (OB_FAIL(minor_tables_.get_all_tables(minor_sstables))) { - LOG_WARN("failed to get all tables", K(ret), K(minor_tables_)); - } - } else if (OB_FAIL(get_ha_mini_minor_sstables_(minor_sstables))) { - LOG_WARN("failed to get ha mini minor sstables", K(ret), K(minor_tables_)); - } - return ret; -} - -int ObTabletTableStore::get_ha_mini_minor_sstables_( - ObTablesHandleArray &minor_sstables) const +int ObTabletTableStore::get_ha_mini_minor_sstables_(ObTableStoreIterator &iter) const { int ret = OB_SUCCESS; int64_t index = 0; for (int64_t i = 0; OB_SUCC(ret) && i < minor_tables_.count(); ++i) { - ObITable *table = minor_tables_[i]; + ObSSTable *table = minor_tables_[i]; if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table should not be NULL", K(ret), K(minor_tables_), KP(table)); @@ -1890,14 +2319,14 @@ int ObTabletTableStore::get_ha_mini_minor_sstables_( } for (int64_t i = index; OB_SUCC(ret) && i < minor_tables_.count(); ++i) { - ObITable *table = minor_tables_[i]; + ObSSTable *table = minor_tables_[i]; if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("table should not be NULL", K(ret), K(minor_tables_), KP(table)); } else if (table->is_remote_logical_minor_sstable()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet table store has multi remote logical minor sstable, unexpected !!!", K(ret), K(minor_tables_)); - } else if (OB_FAIL(minor_sstables.add_table(table))) { + } else if (OB_FAIL(iter.add_table(table))) { LOG_WARN("failed to push table into minor sstables array", K(ret), KPC(table), K(minor_tables_)); } } @@ -1905,21 +2334,22 @@ int ObTabletTableStore::get_ha_mini_minor_sstables_( } int ObTabletTableStore::update_ha_minor_sstables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store) { int ret = OB_SUCCESS; ObArray new_minor_tables; - const ObSSTableArray &old_minor_tables = old_store.get_minor_sstables(); + const ObSSTableArray &old_minor_tables = old_store.minor_tables_; - if (param.start_scn_ >= tablet_ptr_->get_clog_checkpoint_scn()) { + if (param.start_scn_ >= tablet.get_clog_checkpoint_scn()) { //no need keep local minor sstable LOG_INFO("start scn is bigger than clog checkpoint ts, no need keep local minor sstable", K(old_store)); } else { int64_t index = 0; bool has_remote_logical_sstable = false; - for (int64_t i = 0; i < old_minor_tables.count_; ++i) { + for (int64_t i = 0; i < old_minor_tables.count(); ++i) { const ObITable *table = old_minor_tables[i]; if (table->is_remote_logical_minor_sstable()) { has_remote_logical_sstable = true; @@ -1955,7 +2385,7 @@ int ObTabletTableStore::update_ha_minor_sstables_( LOG_WARN("failed to get all minor tables", K(ret), K(old_minor_tables)); } else if (index >= new_minor_tables.count()) { //reuse nothing, copy from src - } else if (OB_FAIL(minor_tables_.init_and_copy(allocator, new_minor_tables, index))) { + } else if (OB_FAIL(minor_tables_.init(allocator, new_minor_tables, index))) { LOG_WARN("failed to init minor_tables", K(ret), K(new_minor_tables)); } } @@ -1964,107 +2394,114 @@ int ObTabletTableStore::update_ha_minor_sstables_( } int ObTabletTableStore::build_ha_minor_tables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store, const int64_t inc_base_snapshot_version) { int ret = OB_SUCCESS; if (param.update_logical_minor_sstable_) { - if (OB_FAIL(update_ha_minor_sstables_(allocator, param, old_store))) { + if (OB_FAIL(update_ha_minor_sstables_(allocator, tablet, param, old_store))) { LOG_WARN("failed to update ha minor sstables", K(ret), K(param), K(old_store)); } + } else if (param.is_transfer_replace_) { + if (OB_FAIL(replace_transfer_minor_sstables_(allocator, tablet, param, old_store))) { + LOG_WARN("failed to replace transfer minor tables", K(ret), K(param), K(old_store)); + } } else { - if (OB_FAIL(replace_ha_minor_sstables_(allocator, param, old_store, inc_base_snapshot_version))) { + if (OB_FAIL(replace_ha_minor_sstables_(allocator, tablet, param, old_store, inc_base_snapshot_version))) { LOG_WARN("failed to replace ha minor tables", K(ret), K(param), K(old_store)); } } return ret; } -int ObTabletTableStore::get_recycle_version( - const int64_t multi_version_start, - int64_t &recycle_version) const +int64_t ObTabletTableStore::to_string(char *buf, const int64_t buf_len) const { - int ret = OB_SUCCESS; - recycle_version = 0; - ObSEArray major_tables; - if (major_tables_.empty()) { - } else if (OB_FAIL(major_tables_.get_all_tables(major_tables))) { - LOG_WARN("failed to get major tables from old store", K(ret), KPC(this)); - } else if (OB_FAIL(ObTableStoreUtil::sort_major_tables(major_tables))) { - LOG_WARN("failed to sort major tables", K(ret)); + int64_t pos = 0; + if (OB_ISNULL(buf) || buf_len <= 0) { + // do nothing } else { - for (int64_t i = major_tables.count() - 1; OB_SUCC(ret) && i >= 0; --i) { - if (major_tables.at(i)->get_snapshot_version() <= multi_version_start) { - recycle_version = major_tables.at(i)->get_snapshot_version(); - break; + J_OBJ_START(); + J_NAME("ObTabletTableStore"); + J_COLON(); + J_KV(KP(this), K_(version), K_(major_tables), K_(minor_tables), K_(memtables), K_(is_ready_for_read)); + J_COMMA(); + J_ARRAY_START(); + for (int64_t i = 0; i < major_tables_.count(); ++i) { + const ObSSTable *table = major_tables_[i]; + J_OBJ_START(); + J_KV(K(i), "addr", table->get_addr(), + "type", ObITable::get_table_type_name(table->get_key().table_type_), + "tablet_id", table->get_key().tablet_id_, + "scn_range", table->get_key().scn_range_, + "snapshot_version", table->get_snapshot_version(), + "max_merge_version", table->get_max_merged_trans_version()); + J_OBJ_END(); + J_COMMA(); + } + for (int64_t i = 0; i < minor_tables_.count(); ++i) { + const ObSSTable *table = minor_tables_[i]; + J_OBJ_START(); + J_KV(K(i), "addr", table->get_addr(), + "type", ObITable::get_table_type_name(table->get_key().table_type_), + "tablet_id", table->get_key().tablet_id_, + "scn_range", table->get_key().scn_range_, + "contain_uncommitted_row", table->contain_uncommitted_row() ? "yes" : "no", + "max_merge_version", table->get_max_merged_trans_version(), + "upper_trans_version", table->get_upper_trans_version()); + J_OBJ_END(); + J_COMMA(); + } + for (int64_t i = 0; i < ddl_sstables_.count(); ++i) { + const ObSSTable *table = ddl_sstables_[i]; + J_OBJ_START(); + J_KV(K(i), "type", ObITable::get_table_type_name(table->get_key().table_type_), + "tablet_id", table->get_key().tablet_id_, + "scn_range", table->get_key().scn_range_, + "max_merge_version", table->get_max_merged_trans_version()); + J_OBJ_END(); + J_COMMA(); + } + for (int64_t i = 0; i < ddl_mem_sstables_.count(); ++i) { + ObITable *table = ddl_mem_sstables_[i]; + if (NULL != table && table->is_sstable()) { + J_OBJ_START(); + J_KV(K(i), "type", ObITable::get_table_type_name(table->get_key().table_type_), + "tablet_id", table->get_key().tablet_id_, + "scn_range", table->get_key().scn_range_, + "ref", table->get_ref(), + "max_merge_version", static_cast(table)->get_max_merged_trans_version()); + J_OBJ_END(); + J_COMMA(); } } - if (0 == recycle_version && major_tables.count() > 0) { - recycle_version = major_tables.at(0)->get_snapshot_version(); - LOG_WARN("not found inc base snapshot version, use the oldest major table", K(ret)); + for (int64_t i = 0; i < meta_major_tables_.count(); ++i) { + const ObSSTable *table = meta_major_tables_[i]; + J_OBJ_START(); + J_KV(K(i), "type", ObITable::get_table_type_name(table->get_key().table_type_), + "tablet_id", table->get_key().tablet_id_, + "scn_range", table->get_key().scn_range_, + "max_merge_version", table->get_max_merged_trans_version()); + J_OBJ_END(); + J_COMMA(); } + + J_ARRAY_END(); + J_OBJ_END(); } - - return ret; + return pos; } - -int ObTabletTableStore::deep_copy_sstable_( - const blocksstable::ObSSTable &old_sstable, - ObTableHandleV2 &new_table_handle) -{ - int ret = OB_SUCCESS; - new_table_handle.reset(); - ObArenaAllocator allocator; - int64_t pos = 0; - int64_t size = 0; - char *buf = nullptr; - ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr *); - ObSSTable *new_sstable = nullptr; - - if (!old_sstable.is_valid()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("deep copy sstable get invalid argument", K(ret), K(old_sstable)); - } else if (OB_ISNULL(t3m)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("t3m should not be NULL", K(ret), KP(t3m)); - } else if (FALSE_IT(size = old_sstable.get_serialize_size())) { - } else if (OB_ISNULL(buf = static_cast(allocator.alloc(size)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("failed to alloc memory", K(ret), K(size)); - } else if (OB_FAIL(old_sstable.serialize(buf, size, pos))) { - LOG_WARN("failed to serialize sstable", K(ret), K(old_sstable), K(size)); - } else if (OB_FAIL(t3m->acquire_sstable(new_table_handle))) { - LOG_WARN("failed to acquire sstable", K(ret)); - } else if (OB_ISNULL(new_sstable = static_cast(new_table_handle.get_table()))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table should not be NULL", K(ret), K(new_table_handle)); - } else if (FALSE_IT(pos = 0)) { - } else if (OB_FAIL(new_sstable->deserialize(t3m->get_tenant_allocator(), buf, size, pos))) { - LOG_WARN("failed to deserialize new sstable", K(ret), K(size), K(pos), K(old_sstable)); - } else if (OB_FAIL(new_sstable->deserialize_post_work())) { - LOG_WARN("failed to deserialize post work", K(ret), KPC(new_sstable), K(old_sstable)); - } - return ret; -} - - ObPrintTableStore::ObPrintTableStore(const ObTabletTableStore &table_store) : major_tables_(table_store.major_tables_), minor_tables_(table_store.minor_tables_), memtables_(table_store.memtables_), ddl_mem_sstables_(table_store.ddl_mem_sstables_), ddl_sstables_(table_store.ddl_sstables_), - extend_tables_(table_store.extend_tables_), - is_ready_for_read_(table_store.is_ready_for_read_) -{ -} - -ObPrintTableStore::~ObPrintTableStore() -{ -} + meta_major_tables_(table_store.meta_major_tables_), + is_ready_for_read_(table_store.is_ready_for_read_) {} int64_t ObPrintTableStore::to_string(char *buf, const int64_t buf_len) const { @@ -2080,7 +2517,8 @@ int64_t ObPrintTableStore::to_string(char *buf, const int64_t buf_len) const BUF_PRINTF("table_array"); J_COLON(); J_OBJ_START(); - if (!major_tables_.empty() || !minor_tables_.empty() || !memtables_.empty()) { + if (!major_tables_.empty() || !minor_tables_.empty() || !memtables_.empty() || !ddl_mem_sstables_.empty() + || !ddl_sstables_.empty() || !meta_major_tables_.empty()) { ObCurTraceId::TraceId *trace_id = ObCurTraceId::get_trace_id(); J_NEWLINE(); // table_type|max_merge_version @@ -2097,12 +2535,7 @@ int64_t ObPrintTableStore::to_string(char *buf, const int64_t buf_len) const print_arr(ddl_sstables_, "DDL_DUMP", buf, buf_len, pos, is_print); print_arr(ddl_mem_sstables_, "DDL_MEM", buf, buf_len, pos, is_print); print_mem(memtables_, "MEM", buf, buf_len, pos, is_print); - if (nullptr != extend_tables_[ObTabletTableStore::META_MAJOR]) { - if (is_print) { - J_NEWLINE(); - } - table_to_string(extend_tables_[ObTabletTableStore::META_MAJOR], "BUF", buf, buf_len, pos); - } + print_arr(meta_major_tables_, "META_MAJOR", buf, buf_len, pos, is_print); } else { J_EMPTY_OBJ(); } @@ -2112,28 +2545,6 @@ int64_t ObPrintTableStore::to_string(char *buf, const int64_t buf_len) const return pos; } -void ObPrintTableStore::print_arr( - const ObITableArray &tables, - const char* table_arr, - char *buf, - const int64_t buf_len, - int64_t &pos, - bool &is_print) const -{ - for (int64_t i = 0; i < tables.count_; ++i) { - if (is_print && 0 == i) { - J_NEWLINE(); - } - table_to_string(tables[i], i == 0 ? table_arr : " ", buf, buf_len, pos); - if (i < tables.count_ - 1) { - J_NEWLINE(); - } - } - if (tables.count_ > 0) { - is_print = true; - } -} - void ObPrintTableStore::print_mem( const ObMemtableArray &tables, const char* table_arr, @@ -2146,7 +2557,29 @@ void ObPrintTableStore::print_mem( if (is_print && 0 == i) { J_NEWLINE(); } - table_to_string(tables.get_table(i), i == 0 ? table_arr : " ", buf, buf_len, pos); + table_to_string(tables[i], i == 0 ? table_arr : " ", buf, buf_len, pos); + if (i < tables.count() - 1) { + J_NEWLINE(); + } + } + if (tables.count() > 0) { + is_print = true; + } +} + +void ObPrintTableStore::print_arr( + const ObSSTableArray &tables, + const char* table_arr, + char *buf, + const int64_t buf_len, + int64_t &pos, + bool &is_print) const +{ + for (int64_t i = 0; i < tables.count(); ++i) { + if (is_print && 0 == i) { + J_NEWLINE(); + } + table_to_string(tables[i], i == 0 ? table_arr : " ", buf, buf_len, pos); if (i < tables.count() - 1) { J_NEWLINE(); } @@ -2172,7 +2605,7 @@ void ObPrintTableStore::table_to_string( ? ObITable::get_table_type_name(table->get_key().table_type_) : (table->is_active_memtable() ? "ACTIVE" : "FROZEN"); const char * uncommit_row = table->is_sstable() - ? (static_cast(table)->get_meta().get_basic_meta().contain_uncommitted_row_ ? "true" : "false") + ? (static_cast(table)->contain_uncommitted_row() ? "true" : "false") : "unused"; BUF_PRINTF(" %-10s %-10s %-19lu %-19lu %-10s %-10s %-4ld %-16s ", @@ -2186,3 +2619,6 @@ void ObPrintTableStore::table_to_string( uncommit_row); } } + +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_table_store.h b/src/storage/tablet/ob_tablet_table_store.h old mode 100644 new mode 100755 index aa3b6830d..db4b405d2 --- a/src/storage/tablet/ob_tablet_table_store.h +++ b/src/storage/tablet/ob_tablet_table_store.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 OceanBase + * 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: @@ -15,240 +15,319 @@ #include "storage/blocksstable/ob_sstable.h" #include "storage/memtable/ob_memtable.h" -#include "ob_table_store_util.h" +#include "storage/tablet/ob_table_store_util.h" +#include "storage/meta_mem/ob_meta_obj_struct.h" namespace oceanbase { -namespace blocksstable -{ -class ObSSTable; -} namespace storage { - -class ObSSTableArray; -class ObMemtableArray; -class ObTableStoreIterator; -class ObIMemtableMgr; -class ObTablet; struct ObUpdateTableStoreParam; struct ObBatchUpdateTableStoreParam; +class ObTablet; +class ObTableStoreIterator; +class ObCachedTableHandle; +class ObStorageMetaHandle; -class ObTabletTableStore +class ObTabletTableStore : public ObIStorageMetaObj { public: friend class ObPrintTableStore; - typedef common::ObSEArray ObTableHandleArray; - enum ExtendTable: int64_t { - META_MAJOR = 0, - EXTEND_CNT - }; - ObTabletTableStore(); virtual ~ObTabletTableStore(); - // handle is not null when first creating table store + void reset(); + // first init int init( - common::ObIAllocator &allocator, - ObTablet *tablet, - ObTableHandleV2 * const handle = nullptr); + ObArenaAllocator &allocator, + const ObTablet &tablet, + const blocksstable::ObSSTable *sstable = nullptr); + // init for update int init( - common::ObIAllocator &allocator, - ObTablet *tablet, + ObArenaAllocator &allocator, + const ObTablet &tablet, const ObUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store); - + // init temp table store with address for serialize, no memtable array + int init( + ObArenaAllocator &allocator, + common::ObIArray &sstable_array, + common::ObIArray &addr_array); + // init for replace sstables in table store + int init( + ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObIArray &replace_sstable_array, + const ObTabletTableStore &old_store); + // init from old table store directly + int init( + ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObTabletTableStore &old_store); + virtual int64_t get_deep_copy_size() const override; + virtual int deep_copy(char *buf, const int64_t buf_len, ObIStorageMetaObj *&value) const override; int serialize(char *buf, const int64_t buf_len, int64_t &pos) const; int deserialize( - common::ObIAllocator &allocator, - ObTablet *tablet, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const char *buf, const int64_t data_len, int64_t &pos); int64_t get_serialize_size() const; - - void reset(); - - OB_INLINE bool is_valid() const; + OB_INLINE bool is_valid() const + { + return is_inited_ && + get_table_count() >= 0 && + get_table_count() <= ObTabletTableStore::MAX_SSTABLE_CNT; + } OB_INLINE bool is_ready_for_read() const { return is_ready_for_read_; } OB_INLINE int64_t get_table_count() const { return major_tables_.count() + minor_tables_.count(); } - OB_INLINE ObTablet *get_tablet() { return tablet_ptr_; } - OB_INLINE ObSSTableArray &get_major_sstables() { return major_tables_; } - OB_INLINE ObSSTableArray &get_minor_sstables() { return minor_tables_; } - OB_INLINE ObSSTableArray &get_ddl_sstables() { return ddl_sstables_; } - OB_INLINE ObSSTableArray &get_ddl_memtables() { return ddl_mem_sstables_; } - OB_INLINE storage::ObITable *get_extend_sstable(const int64_t type) { return extend_tables_[type]; } + // Interfaces below that access sstable array member of table store directly does not guarantee + // sstables in array were loaded OB_INLINE const storage::ObSSTableArray &get_major_sstables() const { return major_tables_; } OB_INLINE const storage::ObSSTableArray &get_minor_sstables() const { return minor_tables_; } OB_INLINE const storage::ObSSTableArray &get_ddl_sstables() const { return ddl_sstables_; } OB_INLINE const storage::ObSSTableArray &get_ddl_memtables() const { return ddl_mem_sstables_; } - OB_INLINE storage::ObITable *get_extend_sstable(const int64_t type) const { return extend_tables_[type]; } + OB_INLINE const storage::ObSSTableArray &get_meta_major_sstables() const { return meta_major_tables_; } + OB_INLINE blocksstable::ObSSTable *get_meta_major_sstable() const + { + return meta_major_tables_.empty() ? nullptr : meta_major_tables_.at(0); + } + int inc_macro_ref() const; + void dec_macro_ref() const; // called by SSTable Garbage Collector Thread int need_remove_old_table( const int64_t multi_version_start, bool &need_remove) const; - int get_table(const ObITable::TableKey &table_key, ObTableHandleV2 &handle) const; - int get_read_tables(const int64_t snapshot_version, - ObTableStoreIterator &iterator, - const bool allow_no_ready_read = false); - int get_read_major_sstable(const int64_t &major_snapshot_version, - ObTableStoreIterator &iterator); - + // won't set secondary meta handle in CachedTableHandle for memtable + // FIXME: make lifetime of such interface safer? + int get_table( + const ObStorageMetaHandle &table_store_handle, + const ObITable::TableKey &table_key, + ObTableHandleV2 &handle) const; + int get_table(const ObITable::TableKey &table_key, ObITable *&table) const; + int get_read_tables( + const int64_t snapshot_version, + const ObTablet &tablet, + ObTableStoreIterator &iter, + const bool allow_no_ready_read = false) const; + int get_all_sstable(ObTableStoreIterator &iter) const; + int get_read_major_sstable(const int64_t snapshot_version, ObTableStoreIterator &iter) const; int get_memtables(common::ObIArray &memtables, const bool need_active = false) const; + int update_memtables(const common::ObIArray &memtables); + int clear_memtables(); + int get_first_frozen_memtable(ObITable *&table) const; + int get_ddl_sstables(ObTableStoreIterator &iter) const; + int get_mini_minor_sstables( + const bool is_ha_data_status_complete, + ObTableStoreIterator &iter) const; int64_t get_memtables_count() const { return memtables_.count(); } - int prepare_memtables(); - int update_memtables(); - int clear_memtables(); - int get_first_frozen_memtable(ObITable *&table); - - int get_ddl_sstable_handles(ObTablesHandleArray &ddl_sstable_handles) const; - int get_mini_minor_sstables(ObTablesHandleArray &minor_sstables) const; - int assign(common::ObIAllocator &allocator, const ObTabletTableStore &other, ObTablet *new_tablet); int get_recycle_version(const int64_t multi_version_start, int64_t &recycle_version) const; - - int64_t to_string(char *buf, const int64_t buf_len) const; - - //ha - int get_ha_tables( - ObTableStoreIterator &iterator, - bool &is_ready_for_read); + int get_ha_tables(ObTableStoreIterator &iter, bool &is_ready_for_read) const; int build_ha_new_table_store( - common::ObIAllocator &allocator, - ObTablet *tablet, + common::ObArenaAllocator &allocator, + ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store); - int batch_replace_sstables( - common::ObIAllocator &allocator, - ObTablet *tablet, - const ObIArray &table_handles, - const ObTabletTableStore &old_store); - + // Asynchronously batch cache sstable meta according to the specified memory size. + // - Here remain_size doesn't include the size of the table store itself. + // - Taking the bypass don't pollute the meta cache. + // - Asynchronously batch performance is better. + int batch_cache_sstable_meta( + common::ObArenaAllocator &allocator, + const int64_t remain_size); + int64_t to_string(char *buf, const int64_t buf_len) const; + // Load sstable with @addr, loaded object lifetime guaranteed by @handle + static int load_sstable(const ObMetaDiskAddr &addr, ObStorageMetaHandle &handle); + // load @orig_sstable on demand, return @loaded_sstable. + // Lifetime guaranteed by loaded_sstable_handle if is loaded. + static int load_sstable_on_demand( + const ObStorageMetaHandle &table_store_handle, + blocksstable::ObSSTable &orig_sstable, + ObStorageMetaHandle &loaded_sstable_handle, + blocksstable::ObSSTable *&loaded_sstable); private: + int get_need_to_cache_sstables( + common::ObIArray &keys, + common::ObIArray &sstables); + int get_need_to_cache_sstables( + const ObSSTableArray &sstable_array, + common::ObIArray &keys, + common::ObIArray &sstables); + int batch_cache_sstable_meta( + common::ObArenaAllocator &allocator, + const int64_t limit_size, + common::ObIArray &sstables, + common::ObIArray &handles); + int get_local_sstable_size_limit( + const int64_t table_store_mem_ctx_size, + int64_t &local_sstable_size_limit) const; int build_new_table_store( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store); - int pull_memtables(); - int init_read_cache(); - bool check_read_cache(const int64_t snapshot_version); - + int build_memtable_array(const ObTablet &tablet); + // Synchronous cache sstable meta with 2MB memory. + // - The cache size is 2M, and include the size of the table store itself. + // - Synchronous cache sstable meta, and one by one. + int try_cache_local_sstables(common::ObArenaAllocator &allocator); int calculate_read_tables( - ObTableStoreIterator &iterator, const int64_t snapshot_version, - const bool allow_no_ready_read = false); - int calculate_read_memtables(const ObTablet &tablet, ObTableStoreIterator &iterator); - + const ObTablet &tablet, + ObTableStoreIterator &iterator, + const bool allow_no_ready_read = false) const; + int calculate_read_memtables(const ObTablet &tablet, ObTableStoreIterator &iterator) const; bool check_read_tables( - ObTableStoreIterator &iterator, - const int64_t snapshot_version); - + const ObTablet &tablet, + const int64_t snapshot_version, + const blocksstable::ObSSTable *base_table) const; int build_major_tables( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const ObUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store, int64_t &inc_base_snapshot_version); int build_minor_tables( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const ObUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store, const int64_t inc_base_snapshot_version); int build_meta_major_table( - const ObTableHandleV2 &new_handle, + common::ObArenaAllocator &allocator, + const blocksstable::ObSSTable *new_sstable, const ObTabletTableStore &old_store); - int inner_build_major_tables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const ObTabletTableStore &old_store, - const ObTablesHandleArray &tables_handle, + const ObIArray &tables_array, const int64_t multi_version_start, const bool allow_duplicate_sstable, int64_t &inc_base_snapshot_version); - int check_ready_for_read(); + int check_ready_for_read(const ObTablet &tablet); int check_continuous() const; + template + int check_minor_tables_continue_(T &minor_tables) const; + int cache_local_sstable_meta( + ObArenaAllocator &allocator, + blocksstable::ObSSTable *array_sstable, + const blocksstable::ObSSTable *loaded_sstable, + const int64_t local_sstable_size_limit, + int64_t &local_sstable_meta_size); + int try_cache_local_sstable_meta( + ObArenaAllocator &allocator, + ObSSTableArray &sstable_array, + const int64_t local_sstable_size_limit, + int64_t &local_sstable_meta_size); + // ha int build_ha_new_table_store_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store); int build_ha_major_tables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store, int64_t &inc_base_snapshot_version); + int build_ha_minor_tables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store, const int64_t inc_base_snapshot_version); int build_ha_ddl_tables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store); int cut_ha_sstable_scn_range_( - common::ObIArray &minor_sstables, - ObTablesHandleArray &tables_handle); + common::ObArenaAllocator &allocator, + common::ObIArray &orig_minor_sstables, + common::ObIArray &cut_minor_sstables); int check_minor_tables_continue_( const int64_t count, ObITable **minor_sstables) const; - int combin_ha_minor_sstables_( + int check_minor_table_continue_( + ObITable *table, + ObITable *prev_table) const; + int combine_ha_minor_sstables_( + const ObTablet &tablet, common::ObIArray &old_store_minor_sstables, common::ObIArray &need_add_minor_sstables, common::ObIArray &new_minor_sstables); + int combine_transfer_minor_sstables_( + common::ObArenaAllocator &allocator, + const ObTablet &tablet, + common::ObIArray &old_store_minor_sstables, + common::ObIArray &need_add_minor_sstables, + const ObBatchUpdateTableStoreParam ¶m, + common::ObIArray &new_minor_sstables); int check_old_store_minor_sstables_( common::ObIArray &old_store_minor_sstables); - int get_ha_mini_minor_sstables_( - ObTablesHandleArray &minor_sstables) const; + int get_ha_mini_minor_sstables_(ObTableStoreIterator &iter) const; int replace_ha_minor_sstables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store, const int64_t inc_base_snapshot_version); + int replace_transfer_minor_sstables_( + common::ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObBatchUpdateTableStoreParam ¶m, + const ObTabletTableStore &old_store); int update_ha_minor_sstables_( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObBatchUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store); // ddl - int pull_ddl_memtables(common::ObIAllocator &allocator); + int pull_ddl_memtables(common::ObArenaAllocator &allocator, const ObTablet &tablet); int build_ddl_sstables( - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, + const ObTablet &tablet, const ObUpdateTableStoreParam ¶m, const ObTabletTableStore &old_store); bool is_major_sstable_empty() const { return major_tables_.empty() && ddl_mem_sstables_.empty() && ddl_sstables_.empty(); } - int get_ddl_major_sstables(ObIArray &ddl_major_sstables); + int get_ddl_major_sstables(ObIArray &ddl_major_sstables) const; int inner_replace_sstables( - common::ObIAllocator &allocator, - const ObIArray &table_handles, + common::ObArenaAllocator &allocator, + const ObIArray &table_handles, const ObTabletTableStore &old_store); - int get_replaced_tables( - const ObIArray &table_handles, - const ObITableArray &old_tables, - ObSEArray &replaced_tables) const; - int deep_copy_sstable_(const blocksstable::ObSSTable &old_sstable, - ObTableHandleV2 &new_table_handle); + int replace_sstables( + common::ObArenaAllocator &allocator, + const ObIArray &replace_sstable_array, + const ObSSTableArray &old_tables, + ObSSTableArray &new_tables) const; public: - static const int64_t TABLE_STORE_VERSION = 0x0100; + static const int64_t TABLE_STORE_VERSION_V1 = 0x0100; + static const int64_t TABLE_STORE_VERSION_V2 = 0x0101; static const int64_t MAX_SSTABLE_CNT = 128; + // limit table store memory size to one ACHUNK + static const int64_t MAX_TABLE_STORE_MEMORY_SIZE= lib::ACHUNK_SIZE - lib::AOBJECT_META_SIZE; static const int64_t EMERGENCY_SSTABLE_CNT = 48; private: - ObTablet *tablet_ptr_; + int64_t version_; ObSSTableArray major_tables_; ObSSTableArray minor_tables_; ObSSTableArray ddl_sstables_; - storage::ObExtendTableArray extend_tables_; - storage::ObMemtableArray memtables_; + ObSSTableArray meta_major_tables_; + ObMemtableArray memtables_; ObSSTableArray ddl_mem_sstables_; - storage::ObTableStoreIterator read_cache_; - int64_t version_; bool is_ready_for_read_; bool is_inited_; + +private: DISALLOW_COPY_AND_ASSIGN(ObTabletTableStore); }; @@ -257,7 +336,7 @@ class ObPrintTableStore { public: ObPrintTableStore(const ObTabletTableStore &table_store); - virtual ~ObPrintTableStore(); + virtual ~ObPrintTableStore() {} int64_t to_string(char *buf, const int64_t buf_len) const; private: void table_to_string( @@ -268,7 +347,7 @@ private: int64_t &pos) const; void print_arr( - const ObITableArray &tables, + const ObSSTableArray &tables, const char* table_arr, char *buf, const int64_t buf_len, @@ -289,19 +368,11 @@ private: const ObMemtableArray &memtables_; const ObSSTableArray &ddl_mem_sstables_; const ObSSTableArray &ddl_sstables_; - const ObExtendTableArray &extend_tables_; + const ObSSTableArray &meta_major_tables_; const bool is_ready_for_read_; }; -OB_INLINE bool ObTabletTableStore::is_valid() const -{ - return is_inited_ && - get_table_count() >= 0 && - get_table_count() <= ObTabletTableStore::MAX_SSTABLE_CNT; -} - -}//storage -}//oceanbase - +} // namespace storage +} // namespace oceanbase #endif /* OCEANBASE_STORAGE_OB_TABLET_TABLE_STORE_H_ */ diff --git a/src/storage/tablet/ob_tablet_table_store_iterator.cpp b/src/storage/tablet/ob_tablet_table_store_iterator.cpp new file mode 100644 index 000000000..3d60649cc --- /dev/null +++ b/src/storage/tablet/ob_tablet_table_store_iterator.cpp @@ -0,0 +1,331 @@ +/** + * 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "storage/blocksstable/ob_sstable.h" +#include "storage/memtable/ob_memtable.h" +#include "storage/tablet/ob_tablet_table_store_iterator.h" +#include "storage/tablet/ob_tablet_table_store.h" + +namespace oceanbase +{ +using namespace blocksstable; +using namespace memtable; +namespace storage +{ + +ObTableStoreIterator::ObTableStoreIterator(const bool reverse, const bool need_load_sstable) + : need_load_sstable_(need_load_sstable), + table_store_handle_(), + sstable_handle_array_(), + table_ptr_array_(), + pos_(INT64_MAX), + memstore_retired_(nullptr), + transfer_src_table_store_handle_(nullptr) +{ + step_ = reverse ? -1 : 1; +} + +void ObTableStoreIterator::operator=(const ObTableStoreIterator& other) +{ + if (this != &other) { + need_load_sstable_ = other.need_load_sstable_; + if (other.table_store_handle_.is_valid()) { + table_store_handle_ = other.table_store_handle_; + } else if (table_store_handle_.is_valid()) { + table_store_handle_.reset(); + } + if (other.sstable_handle_array_.count() > 0) { + sstable_handle_array_ = other.sstable_handle_array_; + } else if (sstable_handle_array_.count() > 0) { + sstable_handle_array_.reset(); + } + table_ptr_array_ = other.table_ptr_array_; + pos_ = other.pos_; + step_ = other.step_; + memstore_retired_ = other.memstore_retired_; + if (OB_UNLIKELY(nullptr != other.transfer_src_table_store_handle_)) { + if (nullptr == transfer_src_table_store_handle_) { + void *meta_hdl_buf = ob_malloc(sizeof(ObStorageMetaHandle), ObMemAttr(MTL_ID(), "TransferMetaH")); + transfer_src_table_store_handle_ = new (meta_hdl_buf) ObStorageMetaHandle(); + } + *transfer_src_table_store_handle_ = *(other.transfer_src_table_store_handle_); + } + } +} + +ObTableStoreIterator::~ObTableStoreIterator() +{ + reset(); +} + +void ObTableStoreIterator::reset() +{ + table_ptr_array_.reset(); + sstable_handle_array_.reset(); + table_store_handle_.reset(); + if (nullptr != transfer_src_table_store_handle_) { + transfer_src_table_store_handle_->~ObStorageMetaHandle(); + ob_free(transfer_src_table_store_handle_); + transfer_src_table_store_handle_ = nullptr; + } + pos_ = INT64_MAX; + memstore_retired_ = nullptr; +} + +void ObTableStoreIterator::resume() +{ + pos_ = step_ < 0 ? table_ptr_array_.count() - 1 : 0; +} + +int ObTableStoreIterator::get_next(ObITable *&table) +{ + int ret = OB_SUCCESS; + table = nullptr; + if (OB_FAIL(inner_move_idx_to_next())) { + } else if (OB_FAIL(get_ith_table(pos_, table))) { + LOG_WARN("fail to get ith table", K(ret), K(pos_)); + } else { + pos_ += step_; + } + return ret; +} + +int ObTableStoreIterator::get_next(ObTableHandleV2 &table_handle) +{ + int ret = OB_SUCCESS; + table_handle.reset(); + ObITable *table = nullptr; + if (OB_UNLIKELY(nullptr != transfer_src_table_store_handle_)) { + ret = OB_NOT_SUPPORTED; + LOG_ERROR("doesn't support cross tablet get table handl", K(ret), KP(transfer_src_table_store_handle_)); + } else if (OB_FAIL(inner_move_idx_to_next())) { + } else { + if (OB_FAIL(get_ith_table(pos_, table))) { + LOG_WARN("fail to get ith table", K(ret), K(pos_)); + } else if (table->is_memtable() || table->is_ddl_mem_sstable()) { + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + if (OB_FAIL(table_handle.set_table(table, t3m, table->get_key().table_type_))) { + LOG_WARN("failed to set memtable to table handle", K(ret), KPC(table)); + } + } else if (table->is_sstable()) { + const int64_t hdl_idx = table_ptr_array_.at(pos_).hdl_idx_; + const ObStorageMetaHandle &meta_handle = hdl_idx >= 0 ? sstable_handle_array_.at(hdl_idx) : table_store_handle_; + if (!meta_handle.is_valid()) { + // table lifetime guaranteed by tablet handle + if (OB_FAIL(table_handle.set_sstable_with_tablet(table))) { + LOG_WARN("failed to set sstable on tablet memory", K(ret)); + } + } else if (OB_FAIL(table_handle.set_sstable(table, meta_handle))) { + LOG_WARN("failed to set sstable to table handle", K(ret), KPC(table), K(meta_handle)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table type", K(ret), KPC(table)); + } + if (OB_SUCC(ret)) { + pos_ += step_; + } + } + return ret; +} + +int ObTableStoreIterator::get_boundary_table(const bool is_last, ObITable *&table) +{ + int ret = OB_SUCCESS; + const int64_t count = table_ptr_array_.count(); + int64_t table_idx = -1; + if (!is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid table store iterator to get boundary table", K(ret), K_(table_ptr_array)); + } else { + if (is_last) { + table_idx = step_ > 0 ? (count - 1) : 0; + } else { + table_idx = step_ < 0 ? (count - 1) : 0; + } + if (OB_FAIL(get_ith_table(table_idx, table))) { + LOG_WARN("fail to get ith table", K(ret), K(table_idx)); + } + } + return ret; +} + +ObITable *ObTableStoreIterator::get_last_memtable() +{ + ObITable *table = nullptr; + const int64_t count = table_ptr_array_.count(); + if (!is_valid()) { + } else { + const TablePtr &ptr = step_ > 0 ? table_ptr_array_.at(count - 1) : table_ptr_array_.at(0); + if (nullptr != ptr.table_ && ptr.table_->is_memtable()) { + table = ptr.table_; + } + } + return table; +} + +int ObTableStoreIterator::set_handle(const ObStorageMetaHandle &table_store_handle) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!table_store_handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table store handle", K(ret), K(table_store_handle)); + } else { + table_store_handle_ = table_store_handle; + } + return ret; +} + +int ObTableStoreIterator::add_table(ObITable *table) +{ + int ret = OB_SUCCESS; + ObSSTable *sstable = nullptr; + TablePtr table_ptr; + if (OB_ISNULL(table)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table ptr", K(ret), KP(table)); + } else if (FALSE_IT(table_ptr.table_ = table)) { + } else if (table->is_memtable()) { + // lifetime guaranteed by tablet_handle_ + } else if (static_cast(table)->is_loaded() || !need_load_sstable_) { + // lifetime guaranteed by table_store_handle_ + } else { + ObStorageMetaHandle sstable_meta_hdl; + if (OB_FAIL(ObTabletTableStore::load_sstable(static_cast(table)->get_addr(), + sstable_meta_hdl))) { + LOG_WARN("fail to load sstable", K(ret)); + } else if (OB_FAIL(sstable_handle_array_.push_back(sstable_meta_hdl))) { + LOG_WARN("fail to push sstable meta handle", K(ret), K(sstable_meta_hdl)); + } else if (OB_FAIL(sstable_meta_hdl.get_sstable(sstable))) { + LOG_WARN("fail to get sstable from meta handle", K(ret), K(sstable_meta_hdl), KPC(table)); + } else { + table_ptr.table_ = sstable; + table_ptr.hdl_idx_ = sstable_handle_array_.count() - 1; + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(table_ptr_array_.push_back(table_ptr))) { + LOG_WARN("fail to push table handle into array", K(ret)); + } + return ret; +} + +int ObTableStoreIterator::inner_move_idx_to_next() +{ + int ret = OB_SUCCESS; + if (0 == table_ptr_array_.count()) { + ret = OB_ITER_END; + } else if (INT64_MAX == pos_) { + pos_ = (-1 == step_) ? table_ptr_array_.count() - 1 : 0; + } else if (pos_ >= table_ptr_array_.count() || pos_ < 0) { + ret = OB_ITER_END; + } + return ret; +} + +int ObTableStoreIterator::add_tables( + const ObSSTableArray &sstable_array, + const int64_t start_pos, + const int64_t count) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!sstable_array.is_valid() + || start_pos < 0 + || start_pos + count > sstable_array.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(sstable_array), K(start_pos), K(count)); + } else { + for (int64_t i = start_pos; OB_SUCC(ret) && i < start_pos + count; ++i) { + if (OB_FAIL(add_table(sstable_array[i]))) { + LOG_WARN("fail to add sstable to iterator", K(ret), K(i)); + } + } + } + return ret; +} + +int ObTableStoreIterator::add_tables( + const ObMemtableArray &memtable_array, + const int64_t start_pos) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!memtable_array.is_valid() || start_pos >= memtable_array.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(memtable_array), K(start_pos)); + } else { + for (int64_t i = start_pos; OB_SUCC(ret) && i < memtable_array.count(); ++i) { + if (OB_FAIL(add_table(memtable_array[i]))) { + LOG_WARN("fail to add memtable to iterator", K(ret), K(i), K(memtable_array)); + } + } + } + return ret; +} + +int ObTableStoreIterator::get_ith_table(const int64_t pos, ObITable *&table) +{ + int ret = OB_SUCCESS; + ObITable *tmp_table = nullptr; + if (OB_UNLIKELY(pos < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(pos)); + } else if (OB_ISNULL(tmp_table = table_ptr_array_.at(pos).table_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid table handle", K(ret), KP(tmp_table), K(pos), K(table_ptr_array_)); + } else if (tmp_table->is_memtable()) { + table = tmp_table; + } else if (static_cast(tmp_table)->is_loaded() || !need_load_sstable_) { + // table store local sstable + table = tmp_table; + } else { + const int64_t hdl_idx = table_ptr_array_.at(pos).hdl_idx_; + ObSSTable *sstable = nullptr; + if (OB_FAIL(sstable_handle_array_.at(hdl_idx).get_sstable(sstable))) { + LOG_WARN("fail to get sstable value", K(ret), K(hdl_idx), K(sstable_handle_array_)); + } else { + table = sstable; + table_ptr_array_.at(pos).table_ = sstable; + } + } + return ret; +} + +int ObTableStoreIterator::set_retire_check() +{ + int ret = OB_SUCCESS; + memstore_retired_ = nullptr; + ObITable *first_memtable = nullptr; + + for (int64_t i = table_ptr_array_.count() - 1; OB_SUCC(ret) && i >= 0; --i) { + const TablePtr &table_ptr = table_ptr_array_.at(i); + if (OB_UNLIKELY(!table_ptr.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected invalid table handle", K(ret), K(table_ptr), K(*this)); + } else if (table_ptr.table_->is_data_memtable()) { + first_memtable = table_ptr.table_; + } else { + break; + } + } + + if (OB_SUCC(ret) && OB_NOT_NULL(first_memtable)) { + memtable::ObMemtable *memtable = static_cast(first_memtable); + memstore_retired_ = &memtable->get_read_barrier(); + } + return ret; +} + +} // storage +} // blocksstable diff --git a/src/storage/tablet/ob_tablet_table_store_iterator.h b/src/storage/tablet/ob_tablet_table_store_iterator.h new file mode 100644 index 000000000..017825f3a --- /dev/null +++ b/src/storage/tablet/ob_tablet_table_store_iterator.h @@ -0,0 +1,103 @@ +/** + * 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_STORAGE_OB_TABLET_TABLE_STORE_ITERATOR_ +#define OCEANBASE_STORAGE_OB_TABLET_TABLE_STORE_ITERATOR_ + +#include "storage/meta_mem/ob_storage_meta_cache.h" +#include "share/cache/ob_kv_storecache.h" + +namespace oceanbase +{ +namespace storage +{ + +class ObITable; +class ObTableHandleV2; +class ObSSTableArray; +class ObMemtableArray; + +class ObTableStoreIterator +{ +// TODO: currently, we will load all related tables into memory on initializetion of iterator, +// maybe we should init with sstable address and prefetch sstable on iteratring for more smooth memory usage +public: + class TablePtr final + { + public: + TablePtr() : table_(nullptr), hdl_idx_(-1) {} + ~TablePtr() = default; + bool is_valid() const { return nullptr != table_; } + TO_STRING_KV(KP_(table), K_(hdl_idx)); + public: + ObITable *table_; + int64_t hdl_idx_; + }; +public: + static const int64_t DEFAULT_TABLE_HANDLE_CNT = 1; + static const int64_t DEFAULT_TABLE_CNT = 16; + typedef common::ObSEArray SSTableHandleArray; + typedef common::ObSEArray TableArray; + ObTableStoreIterator(const bool is_reverse = false, const bool need_load_sstable = true); + ObTableStoreIterator(const ObTableStoreIterator& other) { *this = other; } ; + void operator=(const ObTableStoreIterator& other); + virtual ~ObTableStoreIterator(); + + OB_INLINE bool is_valid() const { return table_ptr_array_.count() > 0; } + OB_INLINE bool is_valid_with_handle() const + { + return table_store_handle_.is_valid(); + } + int64_t count() const { return table_ptr_array_.count(); } + void reset(); + void resume(); + + int set_handle(const ObStorageMetaHandle &table_store_handle); + + ObITable *get_last_memtable(); + int get_next(ObITable *&table); + int get_next(ObTableHandleV2 &table_handle); + int get_boundary_table(const bool is_last, ObITable *&table); + int set_retire_check(); + + int add_table(ObITable *table); + int add_tables( + const ObSSTableArray &sstable_array, + const int64_t start_pos = 0, + const int64_t count = 1); + inline bool check_store_expire() const + { + return (NULL == memstore_retired_) ? false : ATOMIC_LOAD(memstore_retired_); + } + TO_STRING_KV(K_(table_ptr_array), K_(sstable_handle_array), K_(pos), K_(step), K_(memstore_retired)); +private: + int inner_move_idx_to_next(); + int add_tables(const ObMemtableArray &memtable_array, const int64_t start_pos = 0); + int get_ith_table(const int64_t pos, ObITable *&table); +private: + friend class ObTablet; // TODO: remove this friend class when possible + friend class ObTabletTableStore; + bool need_load_sstable_; + ObStorageMetaHandle table_store_handle_; + SSTableHandleArray sstable_handle_array_; + TableArray table_ptr_array_; + int64_t pos_; + int64_t step_; + bool * memstore_retired_; + ObStorageMetaHandle *transfer_src_table_store_handle_; +}; + + +} // namespace storage +} // namespace oceanbase + +#endif diff --git a/src/storage/tx/ob_dup_table_base.cpp b/src/storage/tx/ob_dup_table_base.cpp old mode 100644 new mode 100755 diff --git a/src/storage/tx/ob_dup_table_util.cpp b/src/storage/tx/ob_dup_table_util.cpp old mode 100644 new mode 100755 index 610575e7a..8a8d99b4e --- a/src/storage/tx/ob_dup_table_util.cpp +++ b/src/storage/tx/ob_dup_table_util.cpp @@ -658,7 +658,7 @@ int ObDupTableLSHandler::ls_loop_handle() { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; - // TODO check stopped + if (!is_inited() || OB_ISNULL(lease_mgr_ptr_) || OB_ISNULL(tablets_mgr_ptr_) || OB_ISNULL(ts_sync_mgr_ptr_)) { ret = OB_NOT_INIT; diff --git a/src/storage/tx/ob_location_adapter.cpp b/src/storage/tx/ob_location_adapter.cpp index 11fcc2c6d..b147c8463 100644 --- a/src/storage/tx/ob_location_adapter.cpp +++ b/src/storage/tx/ob_location_adapter.cpp @@ -12,6 +12,7 @@ #include "ob_location_adapter.h" #include "share/location_cache/ob_location_service.h" +#include "share/ls/ob_ls_status_operator.h" namespace oceanbase { @@ -144,6 +145,19 @@ int ObLocationAdapter::get_leader_(const int64_t cluster_id, } } } + if (OB_LS_LOCATION_NOT_EXIST == ret) { + int tmp_ret = OB_SUCCESS; + ObLSExistState state; + if (OB_SUCCESS != (tmp_ret = ObLocationService::check_ls_exist(tenant_id, ls_id, state))) { + TRANS_LOG(WARN, "check if ls exist failed", K(tmp_ret), K(ls_id)); + } else if (state.is_deleted()) { + // rewrite ret + ret = OB_LS_IS_DELETED; + TRANS_LOG(INFO, "ls is deleted", K(ret), K(ls_id)); + } else { + // do nothing + } + } if (OB_SUCC(ret)) { if (!leader.is_valid()) { TRANS_LOG(WARN, "invalid server", K(ls_id), K(leader)); @@ -211,6 +225,19 @@ int ObLocationAdapter::nonblock_get(const int64_t cluster_id, } else { // do nothing } + if (OB_LS_LOCATION_NOT_EXIST == ret) { + int tmp_ret = OB_SUCCESS; + ObLSExistState state; + if (OB_SUCCESS != (tmp_ret = ObLocationService::check_ls_exist(tenant_id, ls_id, state))) { + TRANS_LOG(WARN, "check if ls exist failed", K(tmp_ret), K(ls_id)); + } else if (state.is_deleted()) { + // rewrite ret + ret = OB_LS_IS_DELETED; + TRANS_LOG(INFO, "ls is deleted", K(ret), K(ls_id)); + } else { + // do nothing + } + } return ret; } diff --git a/src/storage/tx/ob_multi_data_source.cpp b/src/storage/tx/ob_multi_data_source.cpp index 4036ccb47..3a80e050a 100644 --- a/src/storage/tx/ob_multi_data_source.cpp +++ b/src/storage/tx/ob_multi_data_source.cpp @@ -11,15 +11,20 @@ */ #include "ob_multi_data_source.h" +#include "lib/ob_abort.h" +#include "lib/ob_errno.h" #include "ob_trans_define.h" #include "share/ob_errno.h" #include "storage/ddl/ob_ddl_clog.h" -#include "storage/ls/ob_ls_member_table.h" #include "storage/tx/ob_trans_part_ctx.h" #include "storage/memtable/ob_memtable_context.h" #include "storage/tablelock/ob_table_lock_common.h" #include "storage/tablet/ob_tablet_binding_helper.h" #include "share/ls/ob_ls_operator.h" +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#define NEED_MDS_REGISTER_DEFINE +#include "storage/multi_data_source/compile_utility/mds_register.h" +#undef NEED_MDS_REGISTER_DEFINE #include "share/ob_standby_upgrade.h" // ObStandbyUpgrade namespace oceanbase @@ -27,55 +32,22 @@ namespace oceanbase using namespace common; using namespace memtable; +using namespace storage; using namespace transaction::tablelock; namespace transaction { -//##################################################### -// ObMDSStr -//#####################################################3 - -OB_SERIALIZE_MEMBER(ObMDSStr, mds_str_, type_, ls_id_); - -ObMDSStr::ObMDSStr() { reset(); } - -ObMDSStr::~ObMDSStr() {} - -void ObMDSStr::reset() -{ - mds_str_.reset(); - type_ = ObTxDataSourceType::UNKNOWN; - ls_id_.reset(); -} - -int ObMDSStr::set(const char *msd_buf, - const int64_t msd_buf_len, - const ObTxDataSourceType &type, - const share::ObLSID ls_id) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(msd_buf) || 0 == msd_buf_len || ObTxDataSourceType::UNKNOWN == type - || !ls_id.is_valid()) { - ret = OB_INVALID_ARGUMENT; - TRANS_LOG(WARN, "invalid arguments", K(ret), KP(msd_buf), K(msd_buf_len), K(type), K(ls_id)); - } else if (!mds_str_.empty()) { - TRANS_LOG(WARN, "MSD str is not empty", K(ret), K(*this)); - } else { - mds_str_.assign_ptr(msd_buf, msd_buf_len); - type_ = type; - ls_id_ = ls_id; - } - return ret; -} - //##################################################### // ObTxBufferNode -//#####################################################3 +//##################################################### OB_SERIALIZE_MEMBER(ObTxBufferNode, type_, data_); -int ObTxBufferNode::init(const ObTxDataSourceType type, const ObString &data) +int ObTxBufferNode::init(const ObTxDataSourceType type, + const ObString &data, + const share::SCN &base_scn, + mds::BufferCtx *ctx) { int ret = OB_SUCCESS; if (OB_UNLIKELY(type <= ObTxDataSourceType::UNKNOWN || type >= ObTxDataSourceType::MAX_TYPE)) { @@ -85,6 +57,8 @@ int ObTxBufferNode::init(const ObTxDataSourceType type, const ObString &data) reset(); type_ = type; data_ = data; + mds_base_scn_ = base_scn; + buffer_ctx_node_.set_ctx(ctx); } return ret; } @@ -102,12 +76,12 @@ void ObTxBufferNode::replace_data(const common::ObString &data) } //##################################################### // ObTxMDSRange -//#####################################################3 +//##################################################### //##################################################### // ObMulSourceTxDataNotifier -//#####################################################3 +//##################################################### int ObMulSourceTxDataNotifier::notify_table_lock(const ObTxBufferNodeArray &array, const ObMulSourceDataNotifyArg &arg, @@ -175,43 +149,99 @@ int ObMulSourceTxDataNotifier::notify(const ObTxBufferNodeArray &array, tmp_notify_arg.redo_submitted_ = node.is_submitted(); tmp_notify_arg.redo_synced_ = node.is_synced(); - switch (node.type_) { - case ObTxDataSourceType::TABLE_LOCK: { - ret = notify_table_lock(notify_type, buf, len, tmp_notify_arg, mt_ctx); - break; - } - case ObTxDataSourceType::LS_TABLE: { - ret = notify_ls_table(notify_type, buf, len, tmp_notify_arg); - break; - } - case ObTxDataSourceType::CREATE_TABLET: { - ret = notify_create_tablet(notify_type, buf, len, tmp_notify_arg); - break; - } - case ObTxDataSourceType::REMOVE_TABLET: { - ret = notify_remove_tablet(notify_type, buf, len, tmp_notify_arg); - break; - } - case ObTxDataSourceType::DDL_TRANS: { - ret = notify_ddl_trans(notify_type, buf, len, tmp_notify_arg); - break; - } - case ObTxDataSourceType::DDL_BARRIER: { - ret = notify_ddl_barrier(notify_type, buf, len, tmp_notify_arg); - break; - } - case ObTxDataSourceType::MODIFY_TABLET_BINDING: { - ret = notify_modify_tablet_binding(notify_type, buf, len, tmp_notify_arg); - break; - } - case ObTxDataSourceType::STANDBY_UPGRADE: { - ret = notify_standby_upgrade(notify_type, buf, len, tmp_notify_arg); - break; - } - default: { - ret = OB_ERR_UNEXPECTED; - break; - } + OB_ASSERT(node.type_ != ObTxDataSourceType::BEFORE_VERSION_4_1); + if (node.type_ < ObTxDataSourceType::BEFORE_VERSION_4_1 + && ObTxDataSourceType::CREATE_TABLET_NEW_MDS != node.type_ + && ObTxDataSourceType::DELETE_TABLET_NEW_MDS != node.type_ + && ObTxDataSourceType::UNBIND_TABLET_NEW_MDS != node.type_) { + switch (node.type_) { + case ObTxDataSourceType::TABLE_LOCK: { + ret = notify_table_lock(notify_type, buf, len, tmp_notify_arg, mt_ctx); + break; + } + case ObTxDataSourceType::LS_TABLE: { + ret = notify_ls_table(notify_type, buf, len, tmp_notify_arg); + break; + } + case ObTxDataSourceType::DDL_TRANS: { + ret = notify_ddl_trans(notify_type, buf, len, tmp_notify_arg); + break; + } + case ObTxDataSourceType::DDL_BARRIER: { + ret = notify_ddl_barrier(notify_type, buf, len, tmp_notify_arg); + break; + } + case ObTxDataSourceType::STANDBY_UPGRADE: { + ret = notify_standby_upgrade(notify_type, buf, len, tmp_notify_arg); + break; + } + default: { + ret = OB_ERR_UNEXPECTED; + break; + } + } + } else { + switch (node.type_) { + #define NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION + #define _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_(HELPER_CLASS, BUFFER_CTX_TYPE, ID, ENUM_NAME) \ + case ObTxDataSourceType::ENUM_NAME:\ + switch (notify_type) {\ + case NotifyType::REGISTER_SUCC:\ + {\ + if (!arg.for_replay_) {\ + if (OB_FAIL(HELPER_CLASS::on_register(buf, len, *const_cast(node.get_buffer_ctx_node().get_ctx())))) {\ + MDS_LOG(WARN, "call user helper on_register failed", KR(ret));\ + } else {\ + MDS_LOG(TRACE, "call user helper on_register success", K(node));\ + }\ + } else {\ + if (OB_FAIL(HELPER_CLASS::on_replay(buf, len, arg.scn_, *const_cast(node.get_buffer_ctx_node().get_ctx())))) {\ + MDS_LOG(WARN, "call user helper on_replay failed", KR(ret));\ + } else {\ + MDS_LOG(TRACE, "call user helper on_replay success", K(node));\ + }\ + }\ + }\ + break;\ + case NotifyType::ON_REDO:\ + node.get_buffer_ctx_node().on_redo(arg.scn_);\ + break;\ + case NotifyType::TX_END:\ + node.get_buffer_ctx_node().before_prepare();\ + break;\ + case NotifyType::ON_PREPARE:\ + node.get_buffer_ctx_node().on_prepare(arg.trans_version_);\ + break;\ + case NotifyType::ON_COMMIT:\ + if (OB_FAIL(common::meta::MdsCommitForOldMdsWrapper::\ + on_commit_for_old_mds(buf,\ + len,\ + tmp_notify_arg))) {\ + MDS_LOG(WARN, "fail to on_commit_for_old_mds", KR(ret));\ + } else if (arg.for_replay_ && !common::meta::MdsCheckCanReplayWrapper::\ + check_can_replay_commit(buf,\ + len,\ + arg.scn_,\ + *const_cast(node.get_buffer_ctx_node().get_ctx()))) {\ + ret = OB_EAGAIN;\ + MDS_LOG(INFO, "check can replay commit return false", KR(ret), K(node));\ + } else {\ + node.get_buffer_ctx_node().on_commit(arg.trans_version_, arg.scn_);\ + }\ + break;\ + case NotifyType::ON_ABORT:\ + node.get_buffer_ctx_node().on_abort(arg.scn_);\ + break;\ + default:\ + ob_abort();\ + }\ + break; + #include "storage/multi_data_source/compile_utility/mds_register.h" + #undef _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_ + #undef NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION + default: + ob_abort(); + } } if (OB_FAIL(ret)) { TRANS_LOG(WARN, "notify data source failed", KR(ret), K(node)); @@ -341,87 +371,6 @@ int ObMulSourceTxDataNotifier::notify_standby_upgrade(const NotifyType type, return ret; } -int ObMulSourceTxDataNotifier::notify_create_tablet(const NotifyType type, - const char *buf, const int64_t len, - const ObMulSourceDataNotifyArg & arg) -{ - int ret = ObLSMemberTable::handle_create_tablet_notify(type, buf, len, arg); - - ob_abort_log_cb_notify_(type, ret, arg.for_replay_); - - return ret; -} - -int ObMulSourceTxDataNotifier::notify_remove_tablet(const NotifyType type, - const char *buf, const int64_t len, - const ObMulSourceDataNotifyArg &arg) -{ - int ret = ObLSMemberTable::handle_remove_tablet_notify(type, buf, len, arg); - - ob_abort_log_cb_notify_(type, ret, arg.for_replay_); - - return ret; -} - -int ObMulSourceTxDataNotifier::notify_modify_tablet_binding(const NotifyType type, - const char *buf, - const int64_t len, - const ObMulSourceDataNotifyArg &arg) -{ - int ret = OB_SUCCESS; - int64_t pos = 0; - ObBatchUnbindTabletArg modify_arg; - if (OB_FAIL(modify_arg.deserialize(buf, len, pos))) { - TRANS_LOG(WARN, "failed to deserialize arg", K(ret)); - } else { - switch (type) { - case transaction::NotifyType::REGISTER_SUCC: { - if (OB_FAIL(ObTabletBindingHelper::lock_tablet_binding_for_unbind(modify_arg, arg))) { - TRANS_LOG(WARN, "failed to lock tablet binding", K(ret)); - } - break; - } - case transaction::NotifyType::ON_REDO: { - if (!arg.for_replay_ && OB_FAIL(ObTabletBindingHelper::set_scn_for_unbind(modify_arg, arg))) { - TRANS_LOG(WARN, "failed to lock tablet binding, retry", K(ret)); - } - break; - } - case transaction::NotifyType::TX_END: { - if (arg.is_redo_submitted()) { - if (OB_FAIL(ObTabletBindingHelper::on_tx_end_for_modify_tablet_binding(modify_arg, arg))) { - TRANS_LOG(WARN, "failed to tx_end", K(ret)); - } - } - break; - } - case transaction::NotifyType::ON_COMMIT: { - if (OB_FAIL(ObTabletBindingHelper::modify_tablet_binding_for_unbind(modify_arg, arg))) { - TRANS_LOG(WARN, "failed to modify tablet binding, retry", K(ret)); - } else if (OB_FAIL(ObTabletBindingHelper::unlock_tablet_binding_for_unbind(modify_arg, arg))) { - TRANS_LOG(WARN, "failed to unlock tablet binding, retry", K(ret)); - } - break; - } - case transaction::NotifyType::ON_ABORT: { - if (OB_FAIL(ObTabletBindingHelper::fix_binding_info_for_modify_tablet_binding(modify_arg, arg))) { - TRANS_LOG(WARN, "failed to fix_binding_info_for_modify_tablet_binding", K(ret), K(modify_arg), K(arg)); - } else if (OB_FAIL(ObTabletBindingHelper::unlock_tablet_binding_for_unbind(modify_arg, arg))) { - TRANS_LOG(WARN, "failed to unlock tablet binding, retry", K(ret)); - } - break; - } - default: { - break; - } - } - } - - ob_abort_log_cb_notify_(type, ret, arg.for_replay_); - - return ret; -} - int ObMulSourceTxDataNotifier::notify_ddl_trans(const NotifyType type, const char *buf, const int64_t len, const ObMulSourceDataNotifyArg &arg) @@ -455,6 +404,9 @@ int ObMulSourceTxDataNotifier::notify_ddl_barrier(const NotifyType type, return ret; } +//##################################################### +// ObMulSourceTxDataDump +//##################################################### const char * ObMulSourceTxDataDump::dump_buf(ObTxDataSourceType source_type, const char *buf, const int64_t len) { @@ -491,7 +443,7 @@ ObMulSourceTxDataDump::dump_buf(ObTxDataSourceType source_type, const char *buf, } break; } - case ObTxDataSourceType::CREATE_TABLET: { + case ObTxDataSourceType::CREATE_TABLET_NEW_MDS: { obrpc::ObBatchCreateTabletArg create_arg; if (OB_FAIL(create_arg.deserialize(buf, len, pos))) { TRANS_LOG(WARN, "deserialize failed for ls_member trans", KR(ret)); @@ -503,7 +455,7 @@ ObMulSourceTxDataDump::dump_buf(ObTxDataSourceType source_type, const char *buf, } break; } - case ObTxDataSourceType::REMOVE_TABLET: { + case ObTxDataSourceType::DELETE_TABLET_NEW_MDS: { obrpc::ObBatchRemoveTabletArg remove_arg; if (OB_FAIL(remove_arg.deserialize(buf, len, pos))) { TRANS_LOG(WARN, "deserialize failed for ls_member trans", KR(ret)); @@ -527,7 +479,7 @@ ObMulSourceTxDataDump::dump_buf(ObTxDataSourceType source_type, const char *buf, } break; } - case ObTxDataSourceType::MODIFY_TABLET_BINDING: { + case ObTxDataSourceType::UNBIND_TABLET_NEW_MDS: { ObBatchUnbindTabletArg modify_arg; if (OB_FAIL(modify_arg.deserialize(buf, len, pos))) { TRANS_LOG(WARN, "failed to deserialize arg", K(ret)); @@ -548,6 +500,51 @@ ObMulSourceTxDataDump::dump_buf(ObTxDataSourceType source_type, const char *buf, return dump_str; } +//##################################################### +// ObRegisterMdsArg +//##################################################### +OB_SERIALIZE_MEMBER(ObRegisterMdsFlag, need_flush_redo_instantly_, mds_base_scn_); + +//##################################################### +// ObMDSStr +//##################################################### + +OB_SERIALIZE_MEMBER(ObMDSInnerSQLStr, mds_str_, type_, ls_id_, register_flag_); + +ObMDSInnerSQLStr::ObMDSInnerSQLStr() { reset(); } + +ObMDSInnerSQLStr::~ObMDSInnerSQLStr() {} + +void ObMDSInnerSQLStr::reset() +{ + mds_str_.reset(); + type_ = ObTxDataSourceType::UNKNOWN; + ls_id_.reset(); + register_flag_.reset(); +} + +int ObMDSInnerSQLStr::set(const char *msd_buf, + const int64_t msd_buf_len, + const ObTxDataSourceType &type, + const share::ObLSID ls_id, + const ObRegisterMdsFlag ®ister_flag) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(msd_buf) || 0 == msd_buf_len || ObTxDataSourceType::UNKNOWN == type + || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + TRANS_LOG(WARN, "invalid arguments", K(ret), KP(msd_buf), K(msd_buf_len), K(type), K(ls_id)); + } else if (!mds_str_.empty()) { + TRANS_LOG(WARN, "MSD str is not empty", K(ret), K(*this)); + } else { + mds_str_.assign_ptr(msd_buf, msd_buf_len); + type_ = type; + ls_id_ = ls_id; + register_flag_ = register_flag; + } + return ret; +} + } // transaction } // oceanbase diff --git a/src/storage/tx/ob_multi_data_source.h b/src/storage/tx/ob_multi_data_source.h index 6dcdf4ccd..ba83ff5fb 100644 --- a/src/storage/tx/ob_multi_data_source.h +++ b/src/storage/tx/ob_multi_data_source.h @@ -18,6 +18,9 @@ #include "lib/utility/ob_unify_serialize.h" #include "lib/string/ob_string.h" #include "share/ob_ls_id.h" +#include "share/scn.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/multi_data_source/buffer_ctx.h" namespace oceanbase { @@ -47,50 +50,21 @@ enum class ObTxDataSourceType : int64_t TABLE_LOCK = 1, // for log stream table(create log stream) LS_TABLE = 2, - // for create tablet - CREATE_TABLET = 3, - // for drop tablet - REMOVE_TABLET = 4, // for liboblog DDL_BARRIER = 5, // for all ddl trans(record incremental schema) DDL_TRANS = 6, - // for unbind hidden tablet and reuse index tablet - MODIFY_TABLET_BINDING = 7, // for standby upgrade STANDBY_UPGRADE = 8, + BEFORE_VERSION_4_1 = 13, +#define NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION +#define _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_(helper_class_name, buffer_ctx_type, ID, ENUM_NAME) ENUM_NAME = ID, + #include "storage/multi_data_source/compile_utility/mds_register.h" +#undef _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_ +#undef NEED_GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION MAX_TYPE = 100 }; -class ObMDSStr -{ - OB_UNIS_VERSION(1); - -public: - ObMDSStr(); - ~ObMDSStr(); - void reset(); - - int set(const char *msd_buf, - const int64_t msd_buf_len, - const ObTxDataSourceType &type, - const share::ObLSID ls_id); - - const char *get_msd_buf() { return mds_str_.ptr(); } - int64_t get_msd_buf_len() { return mds_str_.length(); } - const ObTxDataSourceType &get_msd_type() { return type_; } - const share::ObLSID &get_ls_id() { return ls_id_; } - - TO_STRING_KV(K(mds_str_), K(type_), K(ls_id_)); - -private: - // const char *msd_buf_; - // int64_t msd_buf_len_; - // bool from_copy_; - common::ObString mds_str_; - ObTxDataSourceType type_; - share::ObLSID ls_id_; -}; enum class NotifyType : int64_t { @@ -113,7 +87,7 @@ class ObTxBufferNode public: ObTxBufferNode() : type_(ObTxDataSourceType::UNKNOWN), data_() { reset(); } ~ObTxBufferNode() {} - int init(const ObTxDataSourceType type, const common::ObString &data); + int init(const ObTxDataSourceType type, const common::ObString &data, const share::SCN &base_scn, storage::mds::BufferCtx *ctx); bool is_valid() const { return type_ > ObTxDataSourceType::UNKNOWN && type_ < ObTxDataSourceType::MAX_TYPE @@ -125,6 +99,7 @@ public: data_.reset(); has_submitted_ = false; has_synced_ = false; + mds_base_scn_.reset(); } void replace_data(const common::ObString &data); @@ -140,22 +115,26 @@ public: void set_synced() { has_synced_ = true; } bool is_synced() const { return has_synced_; } + const share::SCN &get_base_scn() { return mds_base_scn_; } + void log_sync_fail() { has_submitted_ = false; has_synced_ = false; } - + storage::mds::BufferCtxNode &get_buffer_ctx_node() const { return buffer_ctx_node_; } TO_STRING_KV(K(has_submitted_), K(has_synced_), K_(type), K(data_.length())); - private: bool has_submitted_; bool has_synced_; + share::SCN mds_base_scn_; ObTxDataSourceType type_; common::ObString data_; + mutable storage::mds::BufferCtxNode buffer_ctx_node_; }; typedef common::ObSEArray ObTxBufferNodeArray; +typedef common::ObSEArray ObTxBufferCtxArray; class ObMulSourceTxDataNotifier { @@ -181,16 +160,6 @@ private: static int notify_standby_upgrade(const NotifyType type, const char *buf, const int64_t len, const ObMulSourceDataNotifyArg &arg); - static int notify_create_tablet(const NotifyType type, - const char *buf, const int64_t len, - const ObMulSourceDataNotifyArg &arg); - static int notify_remove_tablet(const NotifyType type, - const char *buf, const int64_t len, - const ObMulSourceDataNotifyArg &arg); - static int notify_modify_tablet_binding(const NotifyType type, - const char *buf, - const int64_t len, - const ObMulSourceDataNotifyArg &arg); static int notify_ddl_trans(const NotifyType type, const char *buf, const int64_t len, const ObMulSourceDataNotifyArg &arg); @@ -208,6 +177,56 @@ private: }; +struct ObRegisterMdsFlag +{ + bool need_flush_redo_instantly_; + share::SCN mds_base_scn_; + + ObRegisterMdsFlag() { reset(); } + void reset() + { + need_flush_redo_instantly_ = false; + mds_base_scn_.reset(); + } + + TO_STRING_KV(K(need_flush_redo_instantly_), K(mds_base_scn_)); + + OB_UNIS_VERSION(1); +}; + +class ObMDSInnerSQLStr +{ + OB_UNIS_VERSION(1); + +public: + ObMDSInnerSQLStr(); + ~ObMDSInnerSQLStr(); + void reset(); + + int set(const char *mds_buf, + const int64_t mds_buf_len, + const ObTxDataSourceType &type, + const share::ObLSID ls_id, + const ObRegisterMdsFlag ®ister_flag); + + const char *get_msd_buf() { return mds_str_.ptr(); } + int64_t get_msd_buf_len() { return mds_str_.length(); } + const ObTxDataSourceType &get_msd_type() { return type_; } + const share::ObLSID &get_ls_id() { return ls_id_; } + const ObRegisterMdsFlag &get_register_flag() { return register_flag_; } + + TO_STRING_KV(K(mds_str_), K(type_), K(ls_id_), K(register_flag_)); + +private: + // const char *msd_buf_; + // int64_t msd_buf_len_; + // bool from_copy_; + common::ObString mds_str_; + ObTxDataSourceType type_; + share::ObLSID ls_id_; + ObRegisterMdsFlag register_flag_; +}; + } // transaction } // oceanbase diff --git a/src/storage/tx/ob_trans_ctx.cpp b/src/storage/tx/ob_trans_ctx.cpp index fcbe3fb52..a7249e05f 100644 --- a/src/storage/tx/ob_trans_ctx.cpp +++ b/src/storage/tx/ob_trans_ctx.cpp @@ -149,6 +149,7 @@ void ObTransCtx::set_exiting_() if (!is_exiting_) { is_exiting_ = true; print_trace_log_if_necessary_(); + ls_tx_ctx_mgr_->dec_active_tx_count(); const int64_t ctx_ref = get_ref(); if (NULL == ls_tx_ctx_mgr_) { diff --git a/src/storage/tx/ob_trans_ctx_mgr_v4.cpp b/src/storage/tx/ob_trans_ctx_mgr_v4.cpp index 9dfcea105..766c8bf02 100644 --- a/src/storage/tx/ob_trans_ctx_mgr_v4.cpp +++ b/src/storage/tx/ob_trans_ctx_mgr_v4.cpp @@ -216,6 +216,7 @@ void ObLSTxCtxMgr::reset() tx_table_ = NULL; lock_table_ = NULL; total_tx_ctx_count_ = 0; + active_tx_count_ = 0; leader_takeover_ts_.reset(); max_replay_commit_version_.reset(); aggre_rec_scn_.reset(); @@ -261,21 +262,23 @@ void ObLSTxCtxMgr::print_all_tx_ctx_(const int64_t max_print, const bool verbose ls_tx_ctx_map_.for_each(print_fn); } -//STATE \ ACTION START LEADER_REVOKE SWL_CB_SUCC SWL_CB_FAIL LEADER_TAKEOVER RESUME_LEADER BLOCK STOP ONLINE -//--------------------------------------------------------------------------------------------------------------------------------------------------------------- -//INIT F_WORKING N N N N N N N N -//F_WORKING N F_WORKING N N T_PENDING R_PENDING F_BLOCKED STOPPED N -//T_PENDING N F_WORKING L_WORKING T_PENDING N N T_BLOCKED_PENDING STOPPED N -//R_PENDING N F_WORKING L_WORKING R_PENDING N N R_BLOCKED_PENDING STOPPED N -//L_WORKING N F_WORKING N N N N L_BLOCKED STOPPED N -//F_BLOCKED N F_BLOCKED N N T_BLOCKED_PENDING R_BLOCKED_PENDING F_BLOCKED STOPPED F_WORKING -//L_BLOCKED N F_BLOCKED N N N N L_BLOCKED STOPPED N +// NB: BLOCK_NORMAL only block noraml tran, only leader can block normal trans +//STATE \ ACTION START LEADER_REVOKE SWL_CB_SUCC SWL_CB_FAIL LEADER_TAKEOVER RESUME_LEADER BLOCK BLOCK_NORMAL STOP ONLINE UNBLOCK_NORMAL +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//INIT F_WORKING N N N N N N N N N N +//F_WORKING N F_WORKING N N T_PENDING R_PENDING F_BLOCKED N STOPPED N N +//T_PENDING N F_WORKING L_WORKING T_PENDING N N T_BLOCKED_PENDING N STOPPED N N +//R_PENDING N F_WORKING L_WORKING R_PENDING N N R_BLOCKED_PENDING N STOPPED N N +//L_WORKING N F_WORKING N N N N L_BLOCKED L_BLOCKED_NORMAL STOPPED N N +//F_BLOCKED N F_BLOCKED N N T_BLOCKED_PENDING R_BLOCKED_PENDING F_BLOCKED N STOPPED F_WORKING N +//L_BLOCKED N F_BLOCKED N N N N L_BLOCKED N STOPPED N N +//L_BLOCKED_NORMAL N F_WORKING N N N N L_BLOCKED L_BLOCKED_NORMAL STOPPED N L_WORKING // -//T_BLOCKED_PENDING N F_BLOCKED L_BLOCKED T_BLOCKED_PENDING N N T_BLOCKED_PENDING STOPPED N -//R_BLOCKED_PENDING N F_BLOCKED L_BLOCKED R_BLOCKED_PENDING N N R_BLOCKED_PENDING STOPPED N +//T_BLOCKED_PENDING N F_BLOCKED L_BLOCKED T_BLOCKED_PENDING N N T_BLOCKED_PENDING N STOPPED N N +//R_BLOCKED_PENDING N F_BLOCKED L_BLOCKED R_BLOCKED_PENDING N N R_BLOCKED_PENDING N STOPPED N N // -//STOPPED N STOPPED N N N N N STOPPED N -//END N N N N N N N N N +//STOPPED N STOPPED N N N N N N STOPPED N N +//END N N N N N N N N N N N int ObLSTxCtxMgr::StateHelper::switch_state(const int64_t op) { int ret = OB_SUCCESS; @@ -288,24 +291,26 @@ int ObLSTxCtxMgr::StateHelper::switch_state(const int64_t op) static const int64_t F_BLOCKED = State::F_BLOCKED; static const int64_t T_BLOCKED_PENDING = State::T_BLOCKED_PENDING; static const int64_t R_BLOCKED_PENDING = State::R_BLOCKED_PENDING; + static const int64_t L_BLOCKED_NORMAL = State::L_BLOCKED_NORMAL; static const int64_t STOPPED = State::STOPPED; static const int64_t END = State::END; static const int64_t STATE_MAP[State::MAX][Ops::MAX] = { -// START L_REVOKE SWL_CB_SUCC SWL_CB_FAIL LEADER_TAKEOVER RESUME_LEADER BLOCK STOP ONLINE - {F_WORKING, N, N, N, N, N, N, N, N}, - {N, F_WORKING, N, N, T_PENDING, R_PENDING, F_BLOCKED, STOPPED, N}, - {N, F_WORKING, L_WORKING, T_PENDING, N, N, T_BLOCKED_PENDING, STOPPED, N}, - {N, F_WORKING, L_WORKING, R_PENDING, N, N, R_BLOCKED_PENDING, STOPPED, N}, - {N, F_WORKING, N, N, N, N, L_BLOCKED, STOPPED, N}, - {N, F_BLOCKED, N, N, T_BLOCKED_PENDING, R_BLOCKED_PENDING, F_BLOCKED, STOPPED, F_WORKING}, - {N, F_BLOCKED, N, N, N, N, L_BLOCKED, STOPPED, N}, +// START L_REVOKE SWL_CB_SUCC SWL_CB_FAIL LEADER_TAKEOVER RESUME_LEADER BLOCK BLOCK_NORMAL STOP ONLINE UNBLOCK_NORMAL + {F_WORKING, N, N, N, N, N, N, N, N, N, N}, + {N, F_WORKING, N, N, T_PENDING, R_PENDING, F_BLOCKED, N, STOPPED, N, N}, + {N, F_WORKING, L_WORKING, T_PENDING, N, N, T_BLOCKED_PENDING, N, STOPPED, N, N}, + {N, F_WORKING, L_WORKING, R_PENDING, N, N, R_BLOCKED_PENDING, N, STOPPED, N, N}, + {N, F_WORKING, N, N, N, N, L_BLOCKED, L_BLOCKED_NORMAL, STOPPED, N, N}, + {N, F_BLOCKED, N, N, T_BLOCKED_PENDING, R_BLOCKED_PENDING, F_BLOCKED, N, STOPPED, F_WORKING, N}, + {N, F_BLOCKED, N, N, N, N, L_BLOCKED, N, STOPPED, N, N}, + {N, F_WORKING, N, N, N, N, L_BLOCKED, L_BLOCKED_NORMAL, STOPPED, N, L_WORKING}, // - {N, F_BLOCKED, L_BLOCKED, T_BLOCKED_PENDING, N, N, T_BLOCKED_PENDING, STOPPED, N}, - {N, F_BLOCKED, L_BLOCKED, R_BLOCKED_PENDING, N, N, R_BLOCKED_PENDING, STOPPED, N}, + {N, F_BLOCKED, L_BLOCKED, T_BLOCKED_PENDING, N, N, T_BLOCKED_PENDING, N, STOPPED, N, N}, + {N, F_BLOCKED, L_BLOCKED, R_BLOCKED_PENDING, N, N, R_BLOCKED_PENDING, N, STOPPED, N, N}, // - {N, STOPPED, N, N, N, N, N, STOPPED, N}, - {N, N, N, N, N, N, N, N, N} + {N, STOPPED, N, N, N, N, N, N, STOPPED, N, N}, + {N, N, N, N, N, N, N, N, N, N, N} }; if (OB_UNLIKELY(!Ops::is_valid(op))) { @@ -327,6 +332,9 @@ int ObLSTxCtxMgr::StateHelper::switch_state(const int64_t op) if (OB_SUCC(ret)) { _TRANS_LOG(INFO, "ObLSTxCtxMgr switch state success(ls_id=%jd, %s ~> %s, op=%s)", ls_id_.id(), State::state_str(last_state_), State::state_str(state_), Ops::op_str(op)); + } else if (Ops::BLOCK_NORMAL == op || Ops::UNBLOCK_NORMAL == op) { + _TRANS_LOG(WARN, "ObLSTxCtxMgr switch state failed when try block or unblock normal trans(ret=%d, ls_id=%jd, state=%s, op=%s)", + ret, ls_id_.id(), State::state_str(state_), Ops::op_str(op)); } else { _TRANS_LOG(ERROR, "ObLSTxCtxMgr switch state error(ret=%d, ls_id=%jd, state=%s, op=%s)", ret, ls_id_.id(), State::state_str(state_), Ops::op_str(op)); @@ -367,6 +375,15 @@ int ObLSTxCtxMgr::create_tx_ctx_(const ObTxCreateArg &arg, bool leader = false, insert_succ = false; int64_t epoch = 0; + bool block = false; + if (is_blocked_()) { + block = true; + } else if (is_normal_blocked_()) { + if (!arg.for_special_tx_) { + block = true; + } + } + exist = false; if (IS_NOT_INIT) { TRANS_LOG(WARN, "ObLSTxCtxMgr not inited"); @@ -376,8 +393,8 @@ int ObLSTxCtxMgr::create_tx_ctx_(const ObTxCreateArg &arg, ret = OB_INVALID_ARGUMENT; } else if (!arg.for_replay_ && !is_master_()) { ret = OB_NOT_MASTER; - } else if (!arg.for_replay_ && is_blocked_()) { - TRANS_LOG(WARN, "ObLSTxCtxMgr is blocked", K(arg)); + } else if (!arg.for_replay_ && block) { + TRANS_LOG(WARN, "ObLSTxCtxMgr is blocked", K(arg), K(get_state_())); ret = OB_PARTITION_IS_BLOCKED; } else if (is_stopped_()) { TRANS_LOG(WARN, "ObLSTxCtxMgr is stopped", K(arg)); @@ -421,6 +438,7 @@ int ObLSTxCtxMgr::create_tx_ctx_(const ObTxCreateArg &arg, TRANS_LOG(WARN, "insert transaction context error", KR(ret), K(arg)); } } else if (FALSE_IT(insert_succ = true)) { + } else if (FALSE_IT(inc_active_tx_count())) { } else if (!arg.for_replay_ && OB_FAIL(tmp->start_trans())) { TRANS_LOG(WARN, "ctx start trans fail", K(ret), "ctx", tmp); } else { @@ -598,7 +616,7 @@ int ObLSTxCtxMgr::on_start_working_log_cb_succ(SCN start_working_ts) bool ignore_ret = false; WLockGuardWithRetryInterval guard(rwlock_, TRY_THRESOLD_US, RETRY_INTERVAL_US); StateHelper state_helper(ls_id_, state_); - if (State::T_PENDING == state_ || State::T_BLOCKED_PENDING == state_) { + if (is_t_pending_()) { SwitchToLeaderFunctor fn(start_working_ts); if (OB_FAIL(ls_tx_ctx_map_.for_each(fn))) { TRANS_LOG(WARN, "switch to leader failed", KR(ret), K(ls_id_)); @@ -608,7 +626,7 @@ int ObLSTxCtxMgr::on_start_working_log_cb_succ(SCN start_working_ts) ignore_ret = true; } } - } else if (State::R_PENDING == state_ || State::R_BLOCKED_PENDING == state_) { + } else if (is_r_pending_()) { ResumeLeaderFunctor fn(start_working_ts); if (OB_FAIL(ls_tx_ctx_map_.for_each(fn))) { TRANS_LOG(WARN, "resume leader failed", KR(ret), K(ls_id_)); @@ -769,11 +787,7 @@ int ObLSTxCtxMgr::switch_to_follower_gracefully() StateHelper state_helper(ls_id_, state_); int64_t start_time = ObTimeUtility::current_time(); int64_t process_count = 0; - while (OB_SUCC(ret) - && (State::T_PENDING == state_helper.get_state() - || State::R_PENDING == state_helper.get_state() - || State::T_BLOCKED_PENDING == state_helper.get_state() - || State::R_BLOCKED_PENDING == state_helper.get_state())) { + while (OB_SUCC(ret) && is_pending_()) { if (ObTimeUtility::current_time() - start_time >= WAIT_SW_CB_TIMEOUT) { ret = OB_TIMEOUT; TRANS_LOG(WARN, "start working cb waiting timeout", K(ret)); @@ -961,6 +975,20 @@ int ObLSTxCtxMgr::block(bool &is_all_tx_cleaned_up) return ret; } +int ObLSTxCtxMgr::block_normal(bool &is_all_tx_cleaned_up) +{ + int ret = OB_SUCCESS; + StateHelper state_helper(ls_id_, state_); + WLockGuardWithRetryInterval guard(rwlock_, TRY_THRESOLD_US, RETRY_INTERVAL_US); + + if (OB_FAIL(state_helper.switch_state(Ops::BLOCK_NORMAL))) { + TRANS_LOG(WARN, "switch state error", KR(ret), "manager", *this); + } else { + is_all_tx_cleaned_up = (get_tx_ctx_count() == 0); + } + return ret; +} + int ObLSTxCtxMgr::online() { int ret = OB_SUCCESS; @@ -975,6 +1003,18 @@ int ObLSTxCtxMgr::online() return ret; } +int ObLSTxCtxMgr::unblock_normal() +{ + int ret = OB_SUCCESS; + StateHelper state_helper(ls_id_, state_); + WLockGuardWithRetryInterval guard(rwlock_, TRY_THRESOLD_US, RETRY_INTERVAL_US); + + if (OB_FAIL(state_helper.switch_state(Ops::UNBLOCK_NORMAL))) { + TRANS_LOG(WARN, "switch state error", KR(ret), "manager", *this); + } + return ret; +} + int ObLSTxCtxMgr::get_ls_min_uncommit_tx_prepare_version(SCN &min_prepare_version) { int ret = OB_SUCCESS; diff --git a/src/storage/tx/ob_trans_ctx_mgr_v4.h b/src/storage/tx/ob_trans_ctx_mgr_v4.h index 3f524d7d3..989e28d60 100644 --- a/src/storage/tx/ob_trans_ctx_mgr_v4.h +++ b/src/storage/tx/ob_trans_ctx_mgr_v4.h @@ -90,6 +90,7 @@ typedef common::LinkHashValue ObLSTxCtxMgrHashValue; struct ObTxCreateArg { ObTxCreateArg(const bool for_replay, + const bool for_special_tx, const uint64_t tenant_id, const ObTransID &trans_id, const share::ObLSID &ls_id, @@ -100,6 +101,7 @@ struct ObTxCreateArg const int64_t trans_expired_time, ObTransService *trans_service) : for_replay_(for_replay), + for_special_tx_(for_special_tx), tenant_id_(tenant_id), tx_id_(trans_id), ls_id_(ls_id), @@ -116,11 +118,13 @@ struct ObTxCreateArg && trans_expired_time_ > 0 && NULL != trans_service_; } - TO_STRING_KV(K_(for_replay), + + TO_STRING_KV(K_(for_replay), K_(for_special_tx), K_(tenant_id), K_(tx_id), K_(ls_id), K_(cluster_id), K_(cluster_version), K_(session_id), K_(scheduler), K_(trans_expired_time), KP_(trans_service)); bool for_replay_; + bool for_special_tx_; uint64_t tenant_id_; ObTransID tx_id_; share::ObLSID ls_id_; @@ -255,11 +259,20 @@ public: // Block this ObLSTxCtxMgr, it can no longer create new tx_ctx; // @param [out] is_all_tx_cleaned_up: set it to true, when all transactions are cleaned up; int block(bool &is_all_tx_cleaned_up); + + // Block this ObLSTxCtxMgr, it can no longer create normal tx_ctx; + // Allow create special tx_ctx, exp: mds_trans; + // @param [out] is_all_tx_cleaned_up: set it to true, when all transactions are cleaned up; + int block_normal(bool &is_all_tx_cleaned_up); + int unblock_normal(); int online(); // Get the TxCtx count in this ObLSTxCtxMgr; int64_t get_tx_ctx_count() const { return get_tx_ctx_count_(); } + // Get the count of active transactions which have not been committed or aborted + int64_t get_active_tx_count() const { return ATOMIC_LOAD(&active_tx_count_); } + // Check all active and not "for_replay" tx_ctx in this ObLSTxCtxMgr // whether all the transactions that modify the specified tablet before // a schema version are finished. @@ -329,6 +342,12 @@ public: // Decrease this ObLSTxCtxMgr's total_tx_ctx_count void dec_total_tx_ctx_count() { (void)ATOMIC_AAF(&total_tx_ctx_count_, -1); } + // Increase active trx count in this ls + void inc_active_tx_count() { (void)ATOMIC_AAF(&active_tx_count_, 1); } + + // Decrease active trx count in this ls + void dec_active_tx_count() { (void)ATOMIC_AAF(&active_tx_count_, -1); } + // Get all tx obj lock information in this ObLSTxCtxMgr // @param [out] iter: all tx obj lock op information int iterate_tx_obj_lock_op(ObLockOpIterator &iter); @@ -491,6 +510,7 @@ public: "state", State::state_str(state_), K_(total_tx_ctx_count), + K_(active_tx_count), K_(ls_retain_ctx_mgr), K_(aggre_rec_scn), K_(prev_aggre_rec_scn), @@ -532,11 +552,12 @@ private: static const int64_t L_WORKING = 4; static const int64_t F_BLOCKED = 5; static const int64_t L_BLOCKED = 6; - static const int64_t T_BLOCKED_PENDING = 7; - static const int64_t R_BLOCKED_PENDING = 8; - static const int64_t STOPPED = 9; - static const int64_t END = 10; - static const int64_t MAX = 11; + static const int64_t L_BLOCKED_NORMAL = 7; + static const int64_t T_BLOCKED_PENDING = 8; + static const int64_t R_BLOCKED_PENDING = 9; + static const int64_t STOPPED = 10; + static const int64_t END = 11; + static const int64_t MAX = 12; public: static bool is_valid(const int64_t state) { return state > INVALID && state < MAX; } @@ -559,6 +580,7 @@ private: TCM_STATE_CASE_TO_STR(L_BLOCKED); TCM_STATE_CASE_TO_STR(T_BLOCKED_PENDING); TCM_STATE_CASE_TO_STR(R_BLOCKED_PENDING); + TCM_STATE_CASE_TO_STR(L_BLOCKED_NORMAL); TCM_STATE_CASE_TO_STR(STOPPED); TCM_STATE_CASE_TO_STR(END); default: @@ -580,9 +602,11 @@ private: static const int64_t LEADER_TAKEOVER = 4; static const int64_t RESUME_LEADER = 5; static const int64_t BLOCK = 6; - static const int64_t STOP = 7; - static const int64_t ONLINE = 8; - static const int64_t MAX = 9; + static const int64_t BLOCK_NORMAL = 7; + static const int64_t STOP = 8; + static const int64_t ONLINE = 9; + static const int64_t UNBLOCK_NORMAL = 10; + static const int64_t MAX = 11; public: static bool is_valid(const int64_t op) @@ -604,7 +628,9 @@ private: TCM_OP_CASE_TO_STR(LEADER_TAKEOVER); TCM_OP_CASE_TO_STR(RESUME_LEADER); TCM_OP_CASE_TO_STR(BLOCK); + TCM_OP_CASE_TO_STR(BLOCK_NORMAL); TCM_OP_CASE_TO_STR(STOP); + TCM_OP_CASE_TO_STR(UNBLOCK_NORMAL); TCM_OP_CASE_TO_STR(ONLINE); default: break; @@ -635,12 +661,15 @@ private: inline bool is_master_() const { return is_master_(ATOMIC_LOAD(&state_)); } inline bool is_master_(int64_t state) const - { return State::L_WORKING == state || State::L_BLOCKED == state; } + { return State::L_WORKING == state || + State::L_BLOCKED == state || + State::L_BLOCKED_NORMAL == state; } inline bool is_follower_() const { return is_follower_(ATOMIC_LOAD(&state_)); } inline bool is_follower_(int64_t state) const - { return State::F_WORKING == state || State::F_BLOCKED == state; } + { return State::F_WORKING == state || + State::F_BLOCKED == state; } inline bool is_blocked_() const { return is_blocked_(ATOMIC_LOAD(&state_)); } @@ -652,6 +681,37 @@ private: State::R_BLOCKED_PENDING == state; } + inline bool is_normal_blocked_() const + { return is_normal_blocked_(ATOMIC_LOAD(&state_)); } + inline bool is_normal_blocked_(int64_t state) const + { + return State::L_BLOCKED_NORMAL == state; + } + + // check pending substate + inline bool is_t_pending_() const + { return is_t_pending_(ATOMIC_LOAD(&state_)); } + inline bool is_t_pending_(int64_t state) const + { + return State::T_PENDING == state || + State::T_BLOCKED_PENDING == state; + } + + inline bool is_r_pending_() const + { return is_r_pending_(ATOMIC_LOAD(&state_)); } + inline bool is_r_pending_(int64_t state) const + { + return State::R_PENDING == state || + State::R_BLOCKED_PENDING == state; + } + + inline bool is_pending_() const + { return is_pending_(ATOMIC_LOAD(&state_)); } + inline bool is_pending_(int64_t state) const + { + return is_t_pending_(state) || is_r_pending_(state); + } + inline bool is_stopped_() const { return is_stopped_(ATOMIC_LOAD(&state_)); } inline bool is_stopped_(int64_t state) const @@ -697,6 +757,8 @@ private: // Total TxCtx count in this ObLSTxCtxMgr int64_t total_tx_ctx_count_; + int64_t active_tx_count_; + // It is used to record the time point of leader takeover // gts must be refreshed to the newest before the leader provides services MonotonicTs leader_takeover_ts_; diff --git a/src/storage/tx/ob_trans_define.cpp b/src/storage/tx/ob_trans_define.cpp old mode 100644 new mode 100755 index 9c0e2a875..bcdacca6e --- a/src/storage/tx/ob_trans_define.cpp +++ b/src/storage/tx/ob_trans_define.cpp @@ -696,7 +696,7 @@ DEF_TO_STRING(ObLockForReadArg) { int64_t pos = 0; J_OBJ_START(); - J_KV(K(mvcc_acc_ctx_), K(data_trans_id_), K(data_sql_sequence_), K(read_latest_)); + J_KV(K(mvcc_acc_ctx_), K(data_trans_id_), K(data_sql_sequence_), K(read_latest_), K(scn_)); J_OBJ_END(); return pos; } @@ -864,6 +864,7 @@ void ObTxMDSCache::reset() unsubmitted_size_ = 0; mds_list_.reset(); submitted_iterator_ = mds_list_.end();//ObTxBufferNodeList::iterator(); + need_retry_submit_mds_ = false; } void ObTxMDSCache::destroy() @@ -874,8 +875,9 @@ void ObTxMDSCache::destroy() { mds_list_.pop_front(tmp_node); if (nullptr != tmp_node.data_.ptr()) { - share::mtl_free(tmp_node.data_.ptr()); + share::mtl_free(tmp_node.data_.ptr()); } + tmp_node.get_buffer_ctx_node().destroy_ctx(); } } @@ -904,6 +906,7 @@ int ObTxMDSCache::rollback_last_mds_node() TRANS_LOG(WARN, "pop back last node failed", K(ret)); } else { share::mtl_free(buf_node.get_ptr()); + buf_node.get_buffer_ctx_node().destroy_ctx(); } clear_submitted_iterator(); @@ -913,11 +916,18 @@ int ObTxMDSCache::rollback_last_mds_node() int ObTxMDSCache::fill_mds_log(ObTxMultiDataSourceLog &mds_log, ObTxMDSRange &mds_range, - bool &need_pre_replay_barrier) + logservice::ObReplayBarrierType &barrier_flag, + share::SCN &mds_base_scn) { int ret = OB_SUCCESS; mds_range.reset(); + mds_base_scn.reset(); + barrier_flag = logservice::ObReplayBarrierType::NO_NEED_BARRIER; + + share::SCN tmp_base_scn; + tmp_base_scn.reset(); + logservice::ObReplayBarrierType tmp_barrier_type = logservice::ObReplayBarrierType::NO_NEED_BARRIER; if (OB_FAIL(mds_range.init(&mds_list_))) { TRANS_LOG(WARN, "init mds range failed", K(ret)); @@ -935,12 +945,26 @@ int ObTxMDSCache::fill_mds_log(ObTxMultiDataSourceLog &mds_log, } } else if (OB_FAIL(mds_range.update_range(iter))) { TRANS_LOG(WARN, "update mds range failed", K(ret), K(iter)); - } else if (need_pre_replay_barrier) { - //has been pre replay barrier } else if (OB_FALSE_IT( - need_pre_replay_barrier = ObTxLogTypeChecker::need_pre_replay_barrier( + tmp_barrier_type = ObTxLogTypeChecker::need_replay_barrier( ObTxLogType::TX_MULTI_DATA_SOURCE_LOG, iter->get_data_source_type()))) { // set need_barrier flag + } else if (OB_FALSE_IT(tmp_base_scn = iter->get_base_scn())) { + // set base scn + } + + if (OB_SUCC(ret)) { + if (!mds_base_scn.is_valid() && tmp_base_scn.is_valid()) { + mds_base_scn = tmp_base_scn; + } + if (logservice::ObReplayBarrierType::NO_NEED_BARRIER == barrier_flag + && logservice::ObReplayBarrierType::NO_NEED_BARRIER != tmp_barrier_type) { + barrier_flag = tmp_barrier_type; + } + if (mds_base_scn != tmp_base_scn || barrier_flag != tmp_barrier_type) { + ret = OB_EAGAIN; + break; + } } } } @@ -1023,15 +1047,68 @@ void ObTxExecInfo::reset() void ObTxExecInfo::destroy() { + if (!mds_buffer_ctx_array_.empty()) { + TRANS_LOG_RET(WARN, OB_ERR_UNEXPECTED, "mds_buffer_ctx_array_ is valid when exec_info destroy", + K_(mds_buffer_ctx_array), K(*this)); + for (int64_t i = 0; i < mds_buffer_ctx_array_.count(); ++i) { + mds_buffer_ctx_array_[i].destroy_ctx(); + } + } for (int64_t i = 0; i < multi_data_source_.count(); ++i) { ObTxBufferNode &node = multi_data_source_.at(i); if (nullptr != node.data_.ptr()) { share::mtl_free(node.data_.ptr()); + node.buffer_ctx_node_.destroy_ctx(); } } reset(); } +int ObTxExecInfo::generate_mds_buffer_ctx_array() +{ + int ret = OB_SUCCESS; + mds_buffer_ctx_array_.reset(); + for (int64_t idx = 0; idx < multi_data_source_.count() && OB_SUCC(ret); ++idx) { + const ObTxBufferNode &buffer_node = multi_data_source_.at(idx); + if (OB_FAIL(mds_buffer_ctx_array_.push_back(buffer_node.get_buffer_ctx_node()))) { + TRANS_LOG(WARN, "fail to push back", KR(ret), K(*this)); + } + } + if (OB_FAIL(ret)) { + mds_buffer_ctx_array_.reset(); + } + TRANS_LOG(INFO, "generate mds buffer ctx array", KR(ret), K(multi_data_source_), K(mds_buffer_ctx_array_)); + return ret; +} + +void ObTxExecInfo::mrege_buffer_ctx_array_to_multi_data_source() const +{ + ObTxBufferNodeArray &multi_data_source = const_cast(multi_data_source_); + ObTxBufferCtxArray &mds_buffer_ctx_array = const_cast(mds_buffer_ctx_array_); + TRANS_LOG_RET(INFO, OB_SUCCESS, "merge deserialized buffer ctx to multi_data_source", K(mds_buffer_ctx_array), K(multi_data_source)); + if (mds_buffer_ctx_array.count() != multi_data_source.count()) { + TRANS_LOG_RET(ERROR, OB_ERR_UNEXPECTED, + "mds buffer ctx array size not equal to multi data source array size" + ", destroy deserialized mds_buffer_ctx_array directly", + K(multi_data_source), K(mds_buffer_ctx_array), K(*this)); + for (int64_t idx = 0; idx < mds_buffer_ctx_array.count(); ++idx) { + mds_buffer_ctx_array[idx].destroy_ctx(); + } + } else { + for (int64_t idx = 0; idx < multi_data_source.count(); ++idx) { + multi_data_source[idx].buffer_ctx_node_ = mds_buffer_ctx_array[idx]; + } + } + mds_buffer_ctx_array.reset(); +} + +void ObTxExecInfo::clear_buffer_ctx_in_multi_data_source() +{ + for (int64_t idx = 0; idx < multi_data_source_.count(); ++idx) { + multi_data_source_[idx].buffer_ctx_node_.destroy_ctx(); + } +} + OB_SERIALIZE_MEMBER(ObTxExecInfo, state_, upstream_, @@ -1057,7 +1134,8 @@ OB_SERIALIZE_MEMBER(ObTxExecInfo, prepare_log_info_arr_, xid_, need_checksum_, - is_sub2pc_); + is_sub2pc_, + mds_buffer_ctx_array_); bool ObMulSourceDataNotifyArg::is_redo_submitted() const { return redo_submitted_; } @@ -1095,5 +1173,6 @@ const char *trans_type_to_cstr(const TransType &trans_type) } return str; } + } // transaction } // oceanbase diff --git a/src/storage/tx/ob_trans_define.h b/src/storage/tx/ob_trans_define.h index f41751941..08bff1d8f 100644 --- a/src/storage/tx/ob_trans_define.h +++ b/src/storage/tx/ob_trans_define.h @@ -22,6 +22,7 @@ #include "lib/list/ob_list.h" #include "lib/trace/ob_trace_event.h" #include "logservice/palf/lsn.h" +#include "logservice/ob_log_base_header.h" #include "share/ob_cluster_version.h" #include "share/ob_ls_id.h" #include "share/allocator/ob_reserve_arena.h" @@ -287,11 +288,13 @@ struct ObLockForReadArg ObLockForReadArg(memtable::ObMvccAccessCtx &acc_ctx, ObTransID data_trans_id, int64_t data_sql_sequence, - bool read_latest) + bool read_latest, + share::SCN scn) : mvcc_acc_ctx_(acc_ctx), data_trans_id_(data_trans_id), data_sql_sequence_(data_sql_sequence), - read_latest_(read_latest) {} + read_latest_(read_latest), + scn_(scn) {} DECLARE_TO_STRING; @@ -299,6 +302,7 @@ struct ObLockForReadArg ObTransID data_trans_id_; int64_t data_sql_sequence_; bool read_latest_; + share::SCN scn_; // Compare with transfer_start_scn, sstable is end_scn, and memtable is ObMvccTransNode scn }; class ObTransKey final @@ -745,12 +749,9 @@ class ObTransVersion { public: static const int64_t INVALID_TRANS_VERSION = -1; + static const int64_t MAX_TRANS_VERSION = INT64_MAX; public: - static bool is_valid(const int64_t trans_version) - { return trans_version >= 0; } -private: - ObTransVersion() {} - ~ObTransVersion() {} + static bool is_valid(const int64_t trans_version) { return trans_version >= 0; } }; typedef ObMonotonicTs MonotonicTs; @@ -1553,7 +1554,10 @@ public: int insert_mds_node(const ObTxBufferNode &buf_node); int rollback_last_mds_node(); - int fill_mds_log(ObTxMultiDataSourceLog &mds_log, ObTxMDSRange &mds_range, bool &need_barrier); + int fill_mds_log(ObTxMultiDataSourceLog &mds_log, + ObTxMDSRange &mds_range, + logservice::ObReplayBarrierType &barrier_flag, + share::SCN &mds_base_scn); int copy_to(ObTxBufferNodeArray &tmp_array) const; int64_t get_unsubmitted_size() const { return unsubmitted_size_; } @@ -1567,10 +1571,14 @@ public: bool is_contain(const ObTxDataSourceType target_type) const; + void set_need_retry_submit_mds(bool need_retry) { need_retry_submit_mds_ = need_retry; }; + bool need_retry_submit_mds() { return need_retry_submit_mds_; } + TO_STRING_KV(K(unsubmitted_size_), K(mds_list_.size())); private: // TransModulePageAllocator allocator_; + bool need_retry_submit_mds_; int64_t unsubmitted_size_; ObTxBufferNodeList mds_list_; ObTxBufferNodeList::iterator submitted_iterator_; @@ -1615,6 +1623,9 @@ public: redo_lsns_(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator(allocator, "REDO_LSNS")), prepare_log_info_arr_(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator(allocator, "PREPARE_INFO")) {} public: + int generate_mds_buffer_ctx_array(); + void mrege_buffer_ctx_array_to_multi_data_source() const; + void clear_buffer_ctx_in_multi_data_source(); void reset(); // can not destroy in tx_ctx_table void destroy(); @@ -1651,6 +1662,7 @@ public: LogOffSet prev_record_lsn_; ObRedoLSNArray redo_lsns_; ObTxBufferNodeArray multi_data_source_; + ObTxBufferCtxArray mds_buffer_ctx_array_; // check common::ObAddr scheduler_; share::SCN prepare_version_; diff --git a/src/storage/tx/ob_trans_part_ctx.cpp b/src/storage/tx/ob_trans_part_ctx.cpp old mode 100644 new mode 100755 index 290468b2c..88a7e77e0 --- a/src/storage/tx/ob_trans_part_ctx.cpp +++ b/src/storage/tx/ob_trans_part_ctx.cpp @@ -33,6 +33,11 @@ #include "storage/tx_table/ob_tx_table_define.h" #include "storage/tx/ob_trans_service.h" #include "share/ob_alive_server_tracer.h" +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" +#define NEED_MDS_REGISTER_DEFINE +#include "storage/multi_data_source/compile_utility/mds_register.h" +#undef NEED_MDS_REGISTER_DEFINE namespace oceanbase { @@ -541,6 +546,14 @@ int ObPartTransCtx::handle_timeout(const int64_t delay) } } + if (mds_cache_.need_retry_submit_mds()) { + if (OB_TMP_FAIL(submit_multi_data_source_())) { + TRANS_LOG(WARN, "retry submit mds log failed", K(tmp_ret), K(*this)); + } else { + mds_cache_.set_need_retry_submit_mds(false); + } + } + // handle commit timeout on root node if (!is_sub2pc() && !is_follower_() && part_trans_action_ == ObPartTransAction::COMMIT && (is_local_tx_() || is_root())) { @@ -1423,6 +1436,7 @@ int ObPartTransCtx::recover_tx_ctx_table_info(ObTxCtxTableInfo &ctx_info) int ret = OB_SUCCESS; CtxLockGuard guard(lock_); + ObTxBufferNodeArray _unused_; if (!ctx_info.is_valid()) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", K(ctx_info)); @@ -1456,10 +1470,15 @@ int ObPartTransCtx::recover_tx_ctx_table_info(ObTxCtxTableInfo &ctx_info) mt_ctx_.set_trans_version(exec_info_.prepare_version_); } exec_info_.multi_data_source_.reset(); + exec_info_.mds_buffer_ctx_array_.reset(); if (OB_FAIL(ret)) { // do nothing - } else if (OB_FAIL(deep_copy_mds_array(ctx_info.exec_info_.multi_data_source_))) { + } else if (FALSE_IT(ctx_info.exec_info_.mrege_buffer_ctx_array_to_multi_data_source())) { + } else if (OB_FAIL(deep_copy_mds_array(ctx_info.exec_info_.multi_data_source_, _unused_))) { TRANS_LOG(WARN, "deep copy ctx_info mds_array failed", K(ret)); + } else if (FALSE_IT(ctx_info.exec_info_.clear_buffer_ctx_in_multi_data_source())) { + // clear it cause buffer ctx memory need released + // and ObString in buffer node no need released cause it's just part reference of deserialized buffer } else if (FALSE_IT(mt_ctx_.update_checksum(exec_info_.checksum_, exec_info_.checksum_scn_))) { TRANS_LOG(ERROR, "recover checksum failed", K(ret), KPC(this), K(ctx_info)); @@ -1536,7 +1555,6 @@ int ObPartTransCtx::get_tx_ctx_table_info(ObTxCtxTableInfo &info) { int ret = OB_SUCCESS; CtxLockGuard guard(lock_); - // 1. Tx ctx has already exited, so it means that it may have no chance to // push its rec_log_ts to aggre_rec_log_ts, so we must not persist it // NB: You need take note that retained tx ctx should be dumped due to @@ -5149,6 +5167,7 @@ int ObPartTransCtx::replay_multi_data_source(const ObTxMultiDataSourceLog &log, bool repeat_replay = (timestamp == exec_info_.max_applied_log_ts_); + ObTxBufferNodeArray increamental_array; int64_t additional_index = exec_info_.multi_data_source_.count(); if (OB_FAIL(check_replay_avaliable_(lsn, timestamp, part_log_no, need_replay))) { TRANS_LOG(WARN, "check replay available failed", KR(ret), K(lsn), K(timestamp), K(*this)); @@ -5157,8 +5176,9 @@ int ObPartTransCtx::replay_multi_data_source(const ObTxMultiDataSourceLog &log, // no need to replay } else if (update_replaying_log_no_(timestamp, part_log_no)) { TRANS_LOG(WARN, "update replaying log no failed", K(ret), K(timestamp), K(part_log_no)); - } else if (OB_FAIL(deep_copy_mds_array(log.get_data(), false))) { - TRANS_LOG(WARN, "deep copy mds array failed", K(ret)); + // TODO: We need filter the replay of mds array after recovered from the tx_ctx_table + //} else if (OB_FAIL(deep_copy_mds_array(log.get_data(), false))) { + //TRANS_LOG(WARN, "deep copy mds array failed", K(ret)); } if (OB_SUCC(ret)) { @@ -5177,11 +5197,18 @@ int ObPartTransCtx::replay_multi_data_source(const ObTxMultiDataSourceLog &log, if (OB_FAIL(ret)) { // do nothing - } else if (OB_FAIL(notify_data_source_(NotifyType::REGISTER_SUCC, notify_redo_scn, true, - log.get_data()))) { + //TODO & ATTENTION: deep copy a part of the mds array in the log twice after recovered from the tx_ctx_table + } else if (OB_FAIL(deep_copy_mds_array(log.get_data(), increamental_array))) { + TRANS_LOG(WARN, "deep copy mds array failed", K(ret)); + } else if (OB_FAIL(notify_data_source_(NotifyType::REGISTER_SUCC, + timestamp, + true, + increamental_array))) { TRANS_LOG(WARN, "notify data source for REGISTER_SUCC failed", K(ret)); - } else if (OB_FAIL( - notify_data_source_(NotifyType::ON_REDO, notify_redo_scn, true, log.get_data()))) { + } else if (OB_FAIL(notify_data_source_(NotifyType::ON_REDO, + timestamp, + true, + increamental_array))) { TRANS_LOG(WARN, "notify data source for ON_REDO failed", K(ret)); } @@ -5199,6 +5226,7 @@ int ObPartTransCtx::replay_multi_data_source(const ObTxMultiDataSourceLog &log, if (nullptr != node.data_.ptr()) { mtl_free(node.data_.ptr()); node.data_.assign_ptr(nullptr, 0); + node.get_buffer_ctx_node().destroy_ctx(); } } for (int64_t i = exec_info_.multi_data_source_.count() - 1; @@ -5295,18 +5323,19 @@ int ObPartTransCtx::switch_to_leader(const SCN &start_working_ts) } else if (OB_FAIL(state_helper.switch_state(TxCtxOps::TAKEOVER))) { TRANS_LOG(WARN, "switch role state error", KR(ret), K(*this)); } else { - const bool contain_table_lock = is_contain_mds_type_(ObTxDataSourceType::TABLE_LOCK); + const bool need_kill_tx = is_contain_mds_type_(ObTxDataSourceType::TABLE_LOCK) + || is_contain_mds_type_(ObTxDataSourceType::START_TRANSFER_OUT); if (ObTxState::INIT == exec_info_.state_) { - if (exec_info_.data_complete_ && !contain_table_lock) { + if (exec_info_.data_complete_ && !need_kill_tx) { if (OB_FAIL(mt_ctx_.replay_to_commit(false /*is_resume*/))) { TRANS_LOG(WARN, "replay to commit failed", KR(ret), K(*this)); } } else { - TRANS_LOG(WARN, "txn data incomplete, will be aborted", K(contain_table_lock), KPC(this)); + TRANS_LOG(WARN, "txn data incomplete, will be aborted", K(need_kill_tx), KPC(this)); if (has_persisted_log_()) { if (ObPartTransAction::COMMIT == part_trans_action_ || get_upstream_state() >= ObTxState::REDO_COMPLETE) { - TRANS_LOG(WARN, "abort self instantly with a tx_commit request", K(contain_table_lock), + TRANS_LOG(WARN, "abort self instantly with a tx_commit request", K(need_kill_tx), KPC(this)); if (OB_FAIL(do_local_tx_end_(TxEndAction::ABORT_TX))) { TRANS_LOG(WARN, "abort tx failed", KR(ret), KPC(this)); @@ -5790,11 +5819,14 @@ int ObPartTransCtx::get_tx_ctx_table_info_(ObTxCtxTableInfo &info) } else if (OB_FAIL(mt_ctx_.calc_checksum_before_scn( exec_info_.max_applied_log_ts_, exec_info_.checksum_, exec_info_.checksum_scn_))) { TRANS_LOG(ERROR, "calc checksum before log ts failed", K(ret), KPC(this)); + } else if (OB_FAIL(exec_info_.generate_mds_buffer_ctx_array())) { + TRANS_LOG(WARN, "fail to generate mds buffer ctx array", K(ret), KPC(this)); } else { info.tx_id_ = trans_id_; info.ls_id_ = ls_id_; info.exec_info_ = exec_info_; info.cluster_id_ = cluster_id_; + exec_info_.mds_buffer_ctx_array_.reset(); if (OB_FAIL(mt_ctx_.get_table_lock_store_info(info.table_lock_info_))) { TRANS_LOG(WARN, "get_table_lock_store_info failed", K(ret), K(info)); } else { @@ -5855,8 +5887,40 @@ int ObPartTransCtx::gen_total_mds_array_(ObTxBufferNodeArray &mds_array) const return ret; } -int ObPartTransCtx::deep_copy_mds_array(const ObTxBufferNodeArray &mds_array, bool need_replace) +int ObPartTransCtx::deep_copy_mds_array(const ObTxBufferNodeArray &mds_array, + ObTxBufferNodeArray &incremental_array, + bool need_replace) { + auto process_with_buffer_ctx = [this](const ObTxBufferNode &old_node, + mds::BufferCtx *&new_ctx) -> int { + int ret = OB_SUCCESS; + if (old_node.get_data_source_type() <= ObTxDataSourceType::UNKNOWN || + old_node.get_data_source_type() >= ObTxDataSourceType::MAX_TYPE) { + ret = OB_ERR_UNDEFINED; + TRANS_LOG(ERROR, "unexpected mds type", KR(ret), K(*this)); + } else if (old_node.get_data_source_type() <= ObTxDataSourceType::BEFORE_VERSION_4_1 + && ObTxDataSourceType::CREATE_TABLET_NEW_MDS != old_node.get_data_source_type() + && ObTxDataSourceType::DELETE_TABLET_NEW_MDS != old_node.get_data_source_type() + && ObTxDataSourceType::UNBIND_TABLET_NEW_MDS != old_node.get_data_source_type()) { + TRANS_LOG(INFO, "old mds type, no need process with buffer ctx", + K(old_node.get_data_source_type()), K(*this)); + } else { + if (OB_ISNULL(old_node.get_buffer_ctx_node().get_ctx())) {// this is replay path, create ctx + if (OB_FAIL(mds::MdsFactory::create_buffer_ctx(old_node.get_data_source_type(), + trans_id_, + new_ctx))) { + TRANS_LOG(WARN, "fail to create buffer ctx", KR(ret), KPC(new_ctx), K(*this), K(old_node)); + } + } else {// this is recover path, copy ctx + if (OB_FAIL(mds::MdsFactory::deep_copy_buffer_ctx(trans_id_, + *(old_node.buffer_ctx_node_.get_ctx()), + new_ctx))) { + TRANS_LOG(WARN, "fail to deep copy buffer ctx", KR(ret), KPC(new_ctx), K(*this), K(old_node)); + } + } + } + return ret; + }; int ret = OB_SUCCESS; const int64_t origin_count = exec_info_.multi_data_source_.count(); @@ -5890,9 +5954,25 @@ int ObPartTransCtx::deep_copy_mds_array(const ObTxBufferNodeArray &mds_array, bo ObTxBufferNode new_node; ObString data; data.assign_ptr(reinterpret_cast(ptr), len); - if (OB_FAIL(new_node.init(node.type_, data))) { - TRANS_LOG(WARN, "init tx buffer node failed", KR(ret), K(new_node)); + mds::BufferCtx *new_ctx = nullptr; + if (OB_FAIL(process_with_buffer_ctx(node, new_ctx))) { + TRANS_LOG(WARN, "process_with_buffer_ctx failed", KR(ret), K(*this)); + } else if (OB_FAIL(new_node.init(node.get_data_source_type(), + data, + node.mds_base_scn_, + new_ctx))) { + mtl_free(data.ptr()); + if (OB_NOT_NULL(new_ctx)) { + MTL(mds::ObTenantMdsService*)->get_buffer_ctx_allocator().free(new_ctx); + new_ctx = nullptr; + } + TRANS_LOG(WARN, "init new node failed", KR(ret), K(*this)); } else if (OB_FAIL(tmp_buf_arr.push_back(new_node))) { + mtl_free(data.ptr()); + if (OB_NOT_NULL(new_ctx)) { + MTL(mds::ObTenantMdsService*)->get_buffer_ctx_allocator().free(new_ctx); + new_ctx = nullptr; + } TRANS_LOG(WARN, "push multi source data failed", KR(ret), K(*this)); } } @@ -5901,6 +5981,7 @@ int ObPartTransCtx::deep_copy_mds_array(const ObTxBufferNodeArray &mds_array, bo if (OB_FAIL(ret)) { for (int64_t i = 0; i < tmp_buf_arr.count(); ++i) { mtl_free(tmp_buf_arr[i].data_.ptr()); + tmp_buf_arr[i].buffer_ctx_node_.destroy_ctx(); } tmp_buf_arr.reset(); } @@ -5914,6 +5995,7 @@ int ObPartTransCtx::deep_copy_mds_array(const ObTxBufferNodeArray &mds_array, bo if (nullptr != exec_info_.multi_data_source_[i].data_.ptr()) { mtl_free(exec_info_.multi_data_source_[i].data_.ptr()); } + exec_info_.multi_data_source_[i].buffer_ctx_node_.destroy_ctx(); } exec_info_.multi_data_source_.reset(); } @@ -5929,6 +6011,8 @@ int ObPartTransCtx::deep_copy_mds_array(const ObTxBufferNodeArray &mds_array, bo } if (OB_FAIL(exec_info_.multi_data_source_.push_back(tmp_buf_arr[i]))) { TRANS_LOG(WARN, "push back exec_info_.multi_data_source_ failed", K(ret)); + } else if (OB_FAIL(incremental_array.push_back(tmp_buf_arr[i]))) { + TRANS_LOG(WARN, "push back incremental_array failed", K(ret)); } } } @@ -5971,7 +6055,9 @@ int ObPartTransCtx::submit_multi_data_source_() int ObPartTransCtx::submit_multi_data_source_(ObTxLogBlock &log_block) { int ret = OB_SUCCESS; - bool need_pre_replay_barrier = false; + + logservice::ObReplayBarrierType barrier_type = logservice::ObReplayBarrierType::NO_NEED_BARRIER; + share::SCN mds_base_scn; ObTxLogCb *log_cb = nullptr; if (mds_cache_.count() > 0) { @@ -5979,6 +6065,8 @@ int ObPartTransCtx::submit_multi_data_source_(ObTxLogBlock &log_block) ObTxMDSRange range; while (OB_SUCC(ret)) { log.reset(); + mds_base_scn.reset(); + barrier_type = logservice::ObReplayBarrierType::NO_NEED_BARRIER; if (OB_FAIL(exec_info_.redo_lsns_.reserve(exec_info_.redo_lsns_.count() + 1))) { TRANS_LOG(WARN, "reserve memory for redo lsn failed", K(ret)); } else if (OB_FAIL(prepare_log_cb_(!NEED_FINAL_CB, log_cb))) { @@ -5986,7 +6074,7 @@ int ObPartTransCtx::submit_multi_data_source_(ObTxLogBlock &log_block) TRANS_LOG(WARN, "get log cb failed", KR(ret), K(*this)); } } else { - ret = mds_cache_.fill_mds_log(log, log_cb->get_mds_range(), need_pre_replay_barrier); + ret = mds_cache_.fill_mds_log(log, log_cb->get_mds_range(), barrier_type, mds_base_scn); } // TRANS_LOG(INFO, "after fill mds log", K(ret), K(trans_id_)); @@ -6004,10 +6092,6 @@ int ObPartTransCtx::submit_multi_data_source_(ObTxLogBlock &log_block) TRANS_LOG(WARN, "add new log failed", KR(ret), K(*this)); if (OB_LOG_TOO_LARGE == ret) { - logservice::ObReplayBarrierType barrier_type = logservice::ObReplayBarrierType::NO_NEED_BARRIER; - if (need_pre_replay_barrier) { - barrier_type = logservice::ObReplayBarrierType::PRE_BARRIER; - } share::SCN base_scn; base_scn.set_min(); if (OB_FAIL(prepare_big_segment_submit_(log_cb, base_scn, barrier_type, @@ -6018,10 +6102,9 @@ int ObPartTransCtx::submit_multi_data_source_(ObTxLogBlock &log_block) TRANS_LOG(INFO, "construct big multi data source",K(ret),K(trans_id_),K(ls_id_),K(log)); } } - } else if (need_pre_replay_barrier - && OB_FAIL(log_block.rewrite_barrier_log_block( - trans_id_.get_id(), logservice::ObReplayBarrierType::PRE_BARRIER))) { - + } else if (barrier_type != logservice::ObReplayBarrierType::NO_NEED_BARRIER + && OB_FAIL( + log_block.rewrite_barrier_log_block(trans_id_.get_id(), barrier_type))) { TRANS_LOG(WARN, "rewrite multi data source log barrier failed", K(ret)); return_log_cb_(log_cb); log_cb = NULL; @@ -6031,13 +6114,20 @@ int ObPartTransCtx::submit_multi_data_source_(ObTxLogBlock &log_block) } else if (OB_FAIL(acquire_ctx_ref_())) { TRANS_LOG(ERROR, "acquire ctx ref failed", KR(ret), K(*this)); log_cb = nullptr; + } else if ((mds_base_scn.is_valid() ? OB_FALSE_IT(mds_base_scn = share::SCN::scn_inc(mds_base_scn)) : OB_FALSE_IT(mds_base_scn.set_min()))) { + // do nothing } else if (OB_FAIL(ls_tx_ctx_mgr_->get_ls_log_adapter()->submit_log( - log_block.get_buf(), log_block.get_size(), SCN::min_scn(), log_cb, false))) { + log_block.get_buf(), log_block.get_size(), mds_base_scn, log_cb, false))) { TRANS_LOG(WARN, "submit log to clog adapter failed", KR(ret), K(*this)); release_ctx_ref_(); } else if (OB_FAIL(after_submit_log_(log_block, log_cb, NULL))) { log_cb = nullptr; } else { + if (barrier_type != logservice::ObReplayBarrierType::NO_NEED_BARRIER || !mds_base_scn.is_min()) { + TRANS_LOG(INFO, "submit MDS redo with barrier or base_scn successfully", K(ret), K(trans_id_), + K(ls_id_), KPC(log_cb), K(mds_cache_), K(exec_info_.multi_data_source_), + K(mds_base_scn), K(barrier_type)); + } log_cb = nullptr; } if (OB_NOT_NULL(log_cb) && OB_FAIL(ret)) { @@ -6180,7 +6270,8 @@ int ObPartTransCtx::notify_data_source_(const NotifyType notify_type, int ObPartTransCtx::register_multi_data_source(const ObTxDataSourceType data_source_type, const char *buf, const int64_t len, - const bool try_lock) + const bool try_lock, + const ObRegisterMdsFlag ®ister_flag) { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; @@ -6234,7 +6325,16 @@ int ObPartTransCtx::register_multi_data_source(const ObTxDataSourceType data_sou } else if (FALSE_IT(MEMCPY(ptr, buf, len))) { } else if (FALSE_IT(data.assign_ptr(reinterpret_cast(ptr), len))) { } else { - if (OB_FAIL(node.init(data_source_type, data))) { + mds::BufferCtx *buffer_ctx = nullptr; + if (data_source_type > ObTxDataSourceType::BEFORE_VERSION_4_1 + || ObTxDataSourceType::CREATE_TABLET_NEW_MDS == data_source_type + || ObTxDataSourceType::DELETE_TABLET_NEW_MDS == data_source_type + || ObTxDataSourceType::UNBIND_TABLET_NEW_MDS == data_source_type) { + ret = mds::MdsFactory::create_buffer_ctx(data_source_type, trans_id_, buffer_ctx); + } + if (OB_FAIL(ret)) { + TRANS_LOG(WARN, "execute MDS frame code failed, execution interruped", KR(ret), K(data_source_type), K(*this)); + } else if (OB_FAIL(node.init(data_source_type, data, register_flag.mds_base_scn_, buffer_ctx))) { TRANS_LOG(WARN, "init tx buffer node failed", KR(ret), K(data_source_type), K(*this)); } else if (OB_FAIL(tmp_array.push_back(node))) { TRANS_LOG(WARN, "push back notify node failed", KR(ret)); @@ -6250,24 +6350,40 @@ int ObPartTransCtx::register_multi_data_source(const ObTxDataSourceType data_sou if (OB_FAIL(ret)) { mtl_free(ptr); - } else if (OB_FAIL(notify_data_source_(NotifyType::REGISTER_SUCC, SCN(), false, tmp_array))) { + if (OB_NOT_NULL(buffer_ctx)) { + MTL(mds::ObTenantMdsService*)->get_buffer_ctx_allocator().free(buffer_ctx); + } + } else if (OB_FAIL(notify_data_source_(NotifyType::REGISTER_SUCC, SCN(), false, + tmp_array))) { if (OB_SUCCESS != (tmp_ret = mds_cache_.rollback_last_mds_node())) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(ERROR, "rollback last mds node failed", K(tmp_ret), K(ret)); } TRANS_LOG(WARN, "notify data source for register_succ failed", K(tmp_ret)); - } else if (mds_cache_.get_unsubmitted_size() < ObTxMultiDataSourceLog::MAX_PENDING_BUF_SIZE) { + } else if (mds_cache_.get_unsubmitted_size() < ObTxMultiDataSourceLog::MAX_PENDING_BUF_SIZE + && !register_flag.need_flush_redo_instantly_) { // do nothing - } else if (OB_SUCCESS - != (tmp_ret = submit_log_impl_(ObTxLogType::TX_MULTI_DATA_SOURCE_LOG))) { - TRANS_LOG(WARN, "submit mds log failed", K(tmp_ret)); + } else if (OB_SUCCESS != (tmp_ret = submit_log_impl_(ObTxLogType::TX_MULTI_DATA_SOURCE_LOG))) { + if (tmp_ret == OB_NOT_MASTER) { + ret = OB_TRANS_NEED_ROLLBACK; + } else if (tmp_ret == OB_TX_NOLOGCB) { + ret = OB_SUCCESS; + if (register_flag.need_flush_redo_instantly_) { + mds_cache_.set_need_retry_submit_mds(true); + } + } + TRANS_LOG(WARN, "submit mds log failed", K(tmp_ret), K(ret), + K(register_flag), K(data_source_type),KPC(this)); + } else { + TRANS_LOG(DEBUG, "submit mds log success", K(tmp_ret)); } } } + if (OB_FAIL(ret)) { TRANS_LOG(WARN, "register MDS redo in part_ctx failed", K(ret), K(trans_id_), K(ls_id_), - K(data_source_type), K(len), K(mds_cache_), K(exec_info_.multi_data_source_)); + K(data_source_type), K(len), K(register_flag), K(mds_cache_), K(*this), K(lbt())); } REC_TRANS_TRACE_EXT2(tlog_, register_multi_data_source, OB_ID(ret), ret, OB_ID(type), @@ -7591,8 +7707,8 @@ int ObPartTransCtx::build_and_post_ask_state_msg_(const SCN &snapshot) int ObPartTransCtx::check_ls_state_(const SCN &snapshot, const ObLSID &ls_id) { int ret = OB_SUCCESS; - share::ObLSStatusOperator::ObLSExistState ls_state; - if (OB_FAIL(share::ObLSStatusOperator::check_ls_exist(MTL_ID(), ls_id, ls_state))) { + ObLSExistState ls_state; + if (OB_FAIL(ObLocationService::check_ls_exist(MTL_ID(), ls_id, ls_state))) { TRANS_LOG(WARN, "get ls state failed", K(ret)); } else if (ls_state.is_uncreated()) { ObStateInfo state_info; diff --git a/src/storage/tx/ob_trans_part_ctx.h b/src/storage/tx/ob_trans_part_ctx.h index 461643e13..c521fb117 100644 --- a/src/storage/tx/ob_trans_part_ctx.h +++ b/src/storage/tx/ob_trans_part_ctx.h @@ -24,6 +24,7 @@ #include "ob_one_phase_committer.h" #include "ob_two_phase_committer.h" #include +#include "storage/multi_data_source/buffer_ctx.h" namespace oceanbase @@ -393,7 +394,8 @@ public: int register_multi_data_source(const ObTxDataSourceType type, const char *buf, const int64_t len, - const bool try_lock = false); + const bool try_lock, + const ObRegisterMdsFlag ®ister_flag); const share::SCN get_start_log_ts() { @@ -533,7 +535,9 @@ private: const bool is_force_kill = false); int gen_final_mds_array_(ObTxBufferNodeArray &array, bool is_committing = true) const; int gen_total_mds_array_(ObTxBufferNodeArray &mds_array) const; - int deep_copy_mds_array(const ObTxBufferNodeArray &mds_array, bool need_replace = false); + int deep_copy_mds_array(const ObTxBufferNodeArray &mds_array, + ObTxBufferNodeArray &incremental_array, + bool need_replace = false); bool is_contain_mds_type_(const ObTxDataSourceType target_type); int submit_multi_data_source_(); int submit_multi_data_source_(ObTxLogBlock &log_block); @@ -602,7 +606,8 @@ public: int handle_tx_2pc_clear_resp(const Ob2pcClearRespMsg &msg); static int handle_tx_orphan_2pc_msg(const ObTxMsg &recv_msg, const common::ObAddr& self_addr, - ObITransRpc* rpc); + ObITransRpc* rpc, + const bool ls_deleted); // for xa int handle_tx_2pc_prepare_redo_req(const Ob2pcPrepareRedoReqMsg &msg); int handle_tx_2pc_prepare_redo_resp(const Ob2pcPrepareRedoRespMsg &msg); @@ -644,7 +649,8 @@ private: static int post_orphan_msg_(const ObTwoPhaseCommitMsgType &msg_type, const ObTxMsg &recv_msg, const common::ObAddr &self_addr, - ObITransRpc* rpc); + ObITransRpc* rpc, + const bool ls_deleted); static int get_max_decided_scn_(const share::ObLSID &ls_id, share::SCN &scn); int get_2pc_participants_copy(share::ObLSArray ©_participants); // for xa diff --git a/src/storage/tx/ob_trans_rpc.cpp b/src/storage/tx/ob_trans_rpc.cpp index c95b9572f..eedf5603e 100644 --- a/src/storage/tx/ob_trans_rpc.cpp +++ b/src/storage/tx/ob_trans_rpc.cpp @@ -429,7 +429,14 @@ int ObTransRpc::post_msg(const ObLSID &ls_id, ObTxMsg &msg) ret = OB_INVALID_ARGUMENT; } else if (OB_FAIL(trans_service_->get_location_adapter()->nonblock_get_leader(cluster_id, tenant_id, ls_id, server))) { TRANS_LOG(WARN, "get leader failed", KR(ret), K(msg), K(cluster_id), K(ls_id)); - (void)refresh_location_cache(ls_id); + if (ObTxMsgTypeChecker::is_2pc_msg_type(msg.get_msg_type())) { + if (OB_LS_IS_DELETED == ret) { + int tmp_ret = trans_service_->handle_ls_deleted(msg); + if (OB_SUCCESS == tmp_ret) { + ret = OB_SUCCESS; + } + } + } } else if (ObTxMsgTypeChecker::is_2pc_msg_type(msg.get_msg_type())) { // 2pc msg optimization const int64_t dst_cluster_id = obrpc::ObRpcNetHandler::CLUSTER_ID; diff --git a/src/storage/tx/ob_trans_service.cpp b/src/storage/tx/ob_trans_service.cpp old mode 100644 new mode 100755 index c760b8c0e..b30a30166 --- a/src/storage/tx/ob_trans_service.cpp +++ b/src/storage/tx/ob_trans_service.cpp @@ -148,7 +148,7 @@ int ObTransService::init(const ObAddr &self, TRANS_LOG(ERROR, "dup table scan timer init error", K(ret)); } else if (OB_FAIL(ObSimpleThreadPool::init(2, msg_task_cnt, "TransService", tenant_id))) { TRANS_LOG(WARN, "thread pool init error", KR(ret), K(msg_task_cnt)); - } else if (OB_FAIL(tx_desc_mgr_.init(std::bind(&ObTransService::gen_trans_id_, + } else if (OB_FAIL(tx_desc_mgr_.init(std::bind(&ObTransService::gen_trans_id, this, std::placeholders::_1), lib::ObMemAttr(tenant_id, "TxDescMgr")))) { TRANS_LOG(WARN, "ObTxDescMgr init error", K(ret)); @@ -706,7 +706,8 @@ int ObTransService::register_mds_into_tx(ObTxDesc &tx_desc, const ObTxDataSourceType &type, const char *buf, const int64_t buf_len, - const int64_t request_id) + const int64_t request_id, + const ObRegisterMdsFlag ®ister_flag) { const int64_t MAX_RETRY_CNT = 5; const int64_t RETRY_INTERVAL = 400 * 1000; @@ -740,7 +741,8 @@ int ObTransService::register_mds_into_tx(ObTxDesc &tx_desc, } else if (OB_ISNULL(rpc_proxy_)) { ret = OB_NOT_INIT; TRANS_LOG(WARN, "rpc proxy not inited", KR(ret), K(tx_desc), K(ls_id), K(type)); - } else if (OB_FAIL(arg.init(tx_desc.tenant_id_, tx_desc, ls_id, type, str, request_id))) { + } else if (OB_FAIL(arg.init(tx_desc.tenant_id_, tx_desc, ls_id, type, str, request_id, + register_flag))) { TRANS_LOG(WARN, "rpc arg init failed", KR(ret), K(tx_desc), K(ls_id), K(type)); } else if (OB_FAIL(create_implicit_savepoint(tx_desc, tx_param, savepoint))) { TRANS_LOG(WARN, "create implicit savepoint failed", K(ret), K(tx_desc)); @@ -756,27 +758,29 @@ int ObTransService::register_mds_into_tx(ObTxDesc &tx_desc, if (ObTimeUtil::current_time() >= tx_desc.expire_ts_) { ret = OB_TIMEOUT; - TRANS_LOG(WARN, "register tx data timeout", KR(ret), K(tx_desc), K(ls_id), K(type),K(retry_cnt)); + TRANS_LOG(WARN, "register tx data timeout", KR(ret), K(tx_desc), K(ls_id), K(type), + K(retry_cnt)); } else if (OB_ISNULL(location_adapter_) - || OB_FAIL(location_adapter_->nonblock_get_leader(tx_desc.cluster_id_, tx_desc.tenant_id_, - ls_id, ls_leader_addr))) { + || OB_FAIL(location_adapter_->nonblock_get_leader( + tx_desc.cluster_id_, tx_desc.tenant_id_, ls_id, ls_leader_addr))) { TRANS_LOG(WARN, "get leader failed", KR(ret), K(ls_id)); } else if (ls_leader_addr == self_) { local_retry_cnt = 0; time_guard.click("register in ctx begin"); do { - if (OB_FAIL(register_mds_into_ctx(*(arg.tx_desc_), ls_id, type, buf, buf_len))) { + if (OB_FAIL(register_mds_into_ctx(*(arg.tx_desc_), ls_id, type, buf, buf_len, + register_flag))) { TRANS_LOG(WARN, "register msd into ctx failed", K(ret)); if (OB_EAGAIN == ret) { if (ObTimeUtil::current_time() >= tx_desc.expire_ts_) { ret = OB_TIMEOUT; TRANS_LOG(WARN, "register tx data timeout in this participant", KR(ret), K(tx_desc), - K(ls_id), K(type),K(retry_cnt),K(local_retry_cnt)); + K(ls_id), K(type), K(retry_cnt), K(local_retry_cnt)); } else if (local_retry_cnt > MAX_RETRY_CNT) { ret = OB_NOT_MASTER; - TRANS_LOG(WARN, "local retry too many times, need retry by the scheduler", - K(ret), K(local_retry_cnt), K(retry_cnt) ); + TRANS_LOG(WARN, "local retry too many times, need retry by the scheduler", K(ret), + K(local_retry_cnt), K(retry_cnt)); } else { local_retry_cnt++; } @@ -810,8 +814,8 @@ int ObTransService::register_mds_into_tx(ObTxDesc &tx_desc, .by(tx_desc.tenant_id_) .timeout(tx_desc.expire_ts_) .register_tx_data(arg, result))) { - TRANS_LOG(WARN, "register_tx_fata failed", KR(ret), K(ls_leader_addr), K(arg), K(tx_desc), K(ls_id), - K(result)); + TRANS_LOG(WARN, "register_tx_fata failed", KR(ret), K(ls_leader_addr), K(arg), K(tx_desc), + K(ls_id), K(result)); time_guard.click("register by rpc end"); } else if (OB_FALSE_IT(time_guard.click("register by rpc end"))) { } else if (OB_FAIL(result.result_)) { @@ -830,7 +834,7 @@ int ObTransService::register_mds_into_tx(ObTxDesc &tx_desc, K(type)); } } - } while (OB_NOT_MASTER == ret && this->self_ == tx_desc.addr_); + } while (OB_NOT_MASTER == ret && this->self_ == tx_desc.addr_); if (OB_SUCC(ret)) { if (OB_FAIL(add_tx_exec_result(tx_desc, tx_result))) { @@ -848,24 +852,17 @@ int ObTransService::register_mds_into_tx(ObTxDesc &tx_desc, } } - TRANS_LOG(INFO, - "register multi data source result", - KR(ret), - K(arg), - K(result), - K(tx_desc), - K(local_retry_cnt), - K(retry_cnt), - K(request_id), - K(time_guard)); + TRANS_LOG(INFO, "register multi data source result", KR(ret), K(arg), K(result), K(tx_desc), + K(local_retry_cnt), K(retry_cnt), K(request_id), K(time_guard)); return ret; } int ObTransService::register_mds_into_ctx(ObTxDesc &tx_desc, - const ObLSID &ls_id, - const ObTxDataSourceType &type, - const char *buf, - const int64_t buf_len) + const ObLSID &ls_id, + const ObTxDataSourceType &type, + const char *buf, + const int64_t buf_len, + const ObRegisterMdsFlag ®ister_flag) { int ret = OB_SUCCESS; ObStoreCtx store_ctx; @@ -873,14 +870,11 @@ int ObTransService::register_mds_into_ctx(ObTxDesc &tx_desc, snapshot.init_none_read(); concurrent_control::ObWriteFlag write_flag; write_flag.set_is_mds(); - if (OB_UNLIKELY(!tx_desc.is_valid() || - !ls_id.is_valid() || - OB_ISNULL(buf) || - buf_len <= 0)) { + if (OB_UNLIKELY(!tx_desc.is_valid() || !ls_id.is_valid() || OB_ISNULL(buf) || buf_len <= 0)) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", KR(ret), K(tx_desc), K(ls_id), KP(buf), K(buf_len)); } else if (FALSE_IT(store_ctx.ls_id_ = ls_id)) { - } else if (OB_FAIL(get_write_store_ctx(tx_desc, snapshot, write_flag, store_ctx))) { + } else if (OB_FAIL(get_write_store_ctx(tx_desc, snapshot, write_flag, store_ctx, true))) { TRANS_LOG(WARN, "get store ctx failed", KR(ret), K(tx_desc), K(ls_id)); } else { do { @@ -892,8 +886,10 @@ int ObTransService::register_mds_into_ctx(ObTxDesc &tx_desc, if (OB_ISNULL(ctx)) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(WARN, "unexpected null ptr", KR(ret), K(tx_desc), K(ls_id), K(type)); - } else if (OB_FAIL(ctx->register_multi_data_source(type, buf, buf_len))) { - TRANS_LOG(WARN, "register multi source data failed", KR(ret), K(tx_desc), K(ls_id), K(type)); + } else if (OB_FAIL(ctx->register_multi_data_source( + type, buf, buf_len, false /* try lock */, register_flag))) { + TRANS_LOG(WARN, "register multi source data failed", KR(ret), K(tx_desc), K(ls_id), + K(type)); } } } while (0); @@ -902,7 +898,8 @@ int ObTransService::register_mds_into_ctx(ObTxDesc &tx_desc, TRANS_LOG(WARN, "revert store ctx failed", KR(tmp_ret), K(tx_desc), K(ls_id), K(type)); } } - TRANS_LOG(DEBUG, "register multi source data on participant", KR(ret), K(tx_desc), K(ls_id), K(type)); + TRANS_LOG(DEBUG, "register multi source data on participant", KR(ret), K(tx_desc), K(ls_id), + K(type)); return ret; } diff --git a/src/storage/tx/ob_trans_service.h b/src/storage/tx/ob_trans_service.h index 72bd3a686..de574d185 100644 --- a/src/storage/tx/ob_trans_service.h +++ b/src/storage/tx/ob_trans_service.h @@ -200,12 +200,14 @@ public: const ObTxDataSourceType &type, const char *buf, const int64_t buf_len, - const int64_t request_id = 0); + const int64_t request_id = 0, + const ObRegisterMdsFlag ®ister_flag = ObRegisterMdsFlag()); int register_mds_into_ctx(ObTxDesc &tx_desc, - const share::ObLSID &ls_id, - const ObTxDataSourceType &type, - const char *buf, - const int64_t buf_len); + const share::ObLSID &ls_id, + const ObTxDataSourceType &type, + const char *buf, + const int64_t buf_len, + const ObRegisterMdsFlag ®ister_flag); ObTxELRUtil &get_tx_elr_util() { return elr_util_; } #ifdef ENABLE_DEBUG_LOG transaction::ObDefensiveCheckMgr *get_defensive_check_mgr() { return defensive_check_mgr_; } diff --git a/src/storage/tx/ob_trans_service_v4.cpp b/src/storage/tx/ob_trans_service_v4.cpp old mode 100644 new mode 100755 index 3618d7732..9261eeff6 --- a/src/storage/tx/ob_trans_service_v4.cpp +++ b/src/storage/tx/ob_trans_service_v4.cpp @@ -39,7 +39,6 @@ #include "storage/tx_storage/ob_ls_handle.h" #include "storage/ls/ob_ls.h" #include "ob_xa_service.h" -#include "rootserver/ob_tenant_recovery_reportor.h" /* interface(s) */ namespace oceanbase { @@ -232,10 +231,7 @@ int ObTransService::do_commit_tx_(ObTxDesc &tx, return ret; } -#define DELETED_UNRETRYABLE_ERROR(ret) \ - (OB_TABLE_IS_DELETED == ret \ - /*|| OB_LS_IS_DELETED == ret*/ \ - ) +#define DELETED_UNRETRYABLE_ERROR(ret) (OB_LS_IS_DELETED == ret) /* * try send commit msg to coordinator, and register retry task * if msg send fail, the retry task will retry later @@ -962,11 +958,10 @@ int ObTransService::get_read_store_ctx(const ObTxReadSnapshot &snapshot, TRANS_LOG(WARN, "invalid speficied snapshot", K(ret), K(snapshot), K(store_ctx)); } } else if (snapshot.is_ls_snapshot() && snapshot.snapshot_lsid_ != ls_id) { - // try to access differ logstream with snapshot from another logstream - // FIXME: return code should hint to indicate caller to make sens - ret = OB_NOT_SUPPORTED; - TRANS_LOG(WARN, "use a local snapshot to access other logstream", - K(ret), K(store_ctx), K(snapshot)); + // try to access differ logstream with snapshot from another logstream + // it is possible when tablet is tranfered, ignore ret + TRANS_LOG(WARN, "use a local snapshot to access other logstream", + K(ret), K(store_ctx), K(snapshot)); } bool check_readable_ok = false; @@ -1068,7 +1063,8 @@ int ObTransService::get_read_store_ctx(const SCN snapshot_version, int ObTransService::get_write_store_ctx(ObTxDesc &tx, const ObTxReadSnapshot &snapshot, const concurrent_control::ObWriteFlag write_flag, - storage::ObStoreCtx &store_ctx) + storage::ObStoreCtx &store_ctx, + const bool special) { int ret = OB_SUCCESS; const share::ObLSID &ls_id = store_ctx.ls_id_; @@ -1088,7 +1084,7 @@ int ObTransService::get_write_store_ctx(ObTxDesc &tx, } else if (snapshot.is_ls_snapshot() && snapshot.snapshot_lsid_ != ls_id) { ret = OB_NOT_SUPPORTED; TRANS_LOG(WARN, "use ls snapshot access another ls", K(ret), K(snapshot), K(ls_id)); - } else if (OB_FAIL(acquire_tx_ctx(ls_id, tx, tx_ctx, store_ctx.ls_))) { + } else if (OB_FAIL(acquire_tx_ctx(ls_id, tx, tx_ctx, store_ctx.ls_, special))) { TRANS_LOG(WARN, "acquire tx ctx fail", K(ret), K(tx), K(ls_id), KPC(this)); } else if (OB_FAIL(tx_ctx->start_access(tx, data_scn))) { TRANS_LOG(WARN, "tx ctx start access fail", K(ret), K(tx_ctx), K(ls_id), KPC(this)); @@ -1143,7 +1139,8 @@ int ObTransService::get_write_store_ctx(ObTxDesc &tx, * the create must ensure current replica is leader * at the time of create finish */ -int ObTransService::acquire_tx_ctx(const share::ObLSID &ls_id, const ObTxDesc &tx, ObPartTransCtx *&ctx, ObLS *ls) +int ObTransService::acquire_tx_ctx(const share::ObLSID &ls_id, const ObTxDesc &tx, ObPartTransCtx *&ctx, + ObLS *ls, const bool special) { int ret = OB_SUCCESS; bool exist = false; @@ -1155,10 +1152,11 @@ int ObTransService::acquire_tx_ctx(const share::ObLSID &ls_id, const ObTxDesc &t TRANS_LOG(WARN, "participant lost update", K(ls_id), K_(tx.tx_id)); } } - } else if (OB_FAIL(create_tx_ctx_(ls_id, ls, tx, ctx))) { - TRANS_LOG(WARN, "create tx ctx fail", K(ret), K(ls_id), K(tx)); + } else if (OB_FAIL(create_tx_ctx_(ls_id, ls, tx, ctx, special))) { + TRANS_LOG(WARN, "create tx ctx fail", K(ret), K(ls_id), K(tx), K(special)); } - TRANS_LOG(TRACE, "acquire tx ctx", K(ret), K(*this), K(ls_id), K(tx), KP(ctx)); + + TRANS_LOG(TRACE, "acquire tx ctx", K(ret), K(*this), K(ls_id), K(tx), KP(ctx), K(special)); return ret; } @@ -1204,16 +1202,20 @@ int ObTransService::revert_tx_ctx_(ObPartTransCtx *ctx) * create fresh tranaction ctx * 1) allocate * 2) initialize + * + * NB: special tx_ctx would not blocked when in block_normal state */ int ObTransService::create_tx_ctx_(const share::ObLSID &ls_id, ObLS *ls, const ObTxDesc &tx, - ObPartTransCtx *&ctx) + ObPartTransCtx *&ctx, + const bool special) { int ret = OB_SUCCESS; bool existed = false; int64_t epoch = 0; ObTxCreateArg arg(false, /* for_replay */ + special, /* speclial tx not blocked when in block_normal state */ tx.tenant_id_, tx.tx_id_, ls_id, @@ -1239,7 +1241,7 @@ int ObTransService::create_tx_ctx_(const share::ObLSID &ls_id, int ObTransService::create_tx_ctx_(const share::ObLSID &ls_id, const ObTxDesc &tx, ObPartTransCtx *&ctx) -{ return create_tx_ctx_(ls_id, NULL, tx, ctx); } +{ return create_tx_ctx_(ls_id, NULL, tx, ctx, false); } void ObTransService::fetch_cflict_tx_ids_from_mem_ctx_to_desc_(ObMvccAccessCtx &acc_ctx)// for deadlock { @@ -1301,7 +1303,7 @@ int ObTransService::revert_store_ctx(storage::ObStoreCtx &store_ctx) } if (OB_SUCC(ret) && (acc_ctx.is_read())) { - if (acc_ctx.tx_table_guard_.check_ls_offline()) { + if (acc_ctx.tx_table_guards_.check_ls_offline()) { ret = OB_LS_OFFLINE; STORAGE_LOG(WARN, "ls offline during the read operation", K(ret), K(acc_ctx.snapshot_)); } @@ -1986,7 +1988,7 @@ int ObTransService::handle_tx_batch_req(int msg_type, OB_PARTITION_NOT_EXIST == ret || \ OB_LS_NOT_EXIST == ret) { \ /* need_check_leader : just for unittest case*/ \ - handle_orphan_2pc_msg_(msg, need_check_leader); \ + (void)handle_orphan_2pc_msg_(msg, need_check_leader, false); \ } \ } else if (OB_FAIL(ctx->get_ls_tx_ctx_mgr() \ ->get_ls_log_adapter()->get_role(leader, UNUSED))) { \ @@ -1997,7 +1999,7 @@ int ObTransService::handle_tx_batch_req(int msg_type, } else if (ctx->is_exiting()) { \ ret = OB_TRANS_CTX_NOT_EXIST; \ TRANS_LOG(INFO, "tx context is exiting",K(ret),K(msg)); \ - handle_orphan_2pc_msg_(msg, false); \ + (void)handle_orphan_2pc_msg_(msg, false, false); \ } else if (OB_FAIL(ctx->msg_handler__(msg))) { \ TRANS_LOG(WARN, "handle 2pc request fail", K(ret), K(msg)); \ } \ @@ -2039,6 +2041,7 @@ int ObTransService::handle_tx_batch_req(int msg_type, || OB_LS_NOT_EXIST == ret \ || OB_PARTITION_NOT_EXIST == ret \ || OB_TENANT_NOT_EXIST == ret \ + || is_location_service_renew_error(ret) \ ) int ObTransService::handle_sp_rollback_resp(const share::ObLSID &ls_id, @@ -2179,7 +2182,7 @@ int ObTransService::update_max_read_ts_(const uint64_t tenant_id, } // need_check_leader : just for unittest case -void ObTransService::handle_orphan_2pc_msg_(const ObTxMsg &msg, const bool need_check_leader) +int ObTransService::handle_orphan_2pc_msg_(const ObTxMsg &msg, const bool need_check_leader, const bool ls_deleted) { int ret = OB_SUCCESS; bool leader = false; @@ -2196,11 +2199,12 @@ void ObTransService::handle_orphan_2pc_msg_(const ObTxMsg &msg, const bool need_ TRANS_LOG(WARN, "receiver not master", K(ret), K(msg)); } - if (OB_SUCC(ret) && OB_FAIL(ObPartTransCtx::handle_tx_orphan_2pc_msg(msg, get_server(), get_trans_rpc()))) { + if (OB_SUCC(ret) && OB_FAIL(ObPartTransCtx::handle_tx_orphan_2pc_msg(msg, get_server(), get_trans_rpc(), ls_deleted))) { TRANS_LOG(WARN, "handle tx orphan 2pc msg failed", K(ret), K(msg)); } else { // do nothing } + return ret; } int ObTransService::refresh_location_cache(const share::ObLSID ls) @@ -2227,7 +2231,7 @@ int ObTransService::refresh_location_cache(const share::ObLSID ls) return ret; } -int ObTransService::gen_trans_id_(ObTransID &trans_id) +int ObTransService::gen_trans_id(ObTransID &trans_id) { int ret = OB_SUCCESS; @@ -3421,6 +3425,11 @@ int ObTransService::handle_trans_collect_state_response(const ObCollectStateResp return ret; } +int ObTransService::handle_ls_deleted(const ObTxMsg &msg) +{ + TRANS_LOG(INFO, "handle ls deleted", K(msg)); + return handle_orphan_2pc_msg_(msg, false, true); +} void ObTransService::register_standby_cleanup_task() { int ret = OB_SUCCESS; diff --git a/src/storage/tx/ob_trans_service_v4.h b/src/storage/tx/ob_trans_service_v4.h index 60b3b981c..4460fc79e 100644 --- a/src/storage/tx/ob_trans_service_v4.h +++ b/src/storage/tx/ob_trans_service_v4.h @@ -79,13 +79,15 @@ int get_read_store_ctx(const share::SCN snapshot_version, int get_write_store_ctx(ObTxDesc &tx, const ObTxReadSnapshot &snapshot, const concurrent_control::ObWriteFlag write_flag, - storage::ObStoreCtx &store_ctx); + storage::ObStoreCtx &store_ctx, + const bool special); int revert_store_ctx(storage::ObStoreCtx &store_ctx); int acquire_tx_ctx(const share::ObLSID &ls_id, const ObTxDesc &tx, ObPartTransCtx *&ctx, - ObLS *ls); + ObLS *ls, + const bool special); //handle msg int handle_trans_commit_request(ObTxCommitMsg &commit_req, obrpc::ObTransRpcResult &result); int handle_trans_commit_response(ObTxCommitRespMsg &commit_resp, obrpc::ObTransRpcResult &result); @@ -155,6 +157,7 @@ int handle_sub_rollback_request(const ObTxSubRollbackMsg &msg, obrpc::ObTransRpc int handle_sub_rollback_response(const ObTxSubRollbackRespMsg &msg, obrpc::ObTransRpcResult &result); int handle_sub_rollback_result(const ObTransID &tx_id, const int result); int check_scheduler_status(const share::ObLSID &ls_id); +int gen_trans_id(ObTransID &trans_id); //for standby int check_and_fill_state_info(const ObTransID &tx_id, ObStateInfo &state_info); @@ -162,6 +165,7 @@ int handle_trans_ask_state(const ObAskStateMsg &msg, obrpc::ObTransRpcResult &re int handle_trans_ask_state_response(const ObAskStateRespMsg &msg, obrpc::ObTransRpcResult &result); int handle_trans_collect_state(const ObCollectStateMsg &msg, obrpc::ObTransRpcResult &result); int handle_trans_collect_state_response(const ObCollectStateRespMsg &msg, obrpc::ObTransRpcResult &result); +int handle_ls_deleted(const ObTxMsg &msg); void build_tx_collect_state_resp_(ObCollectStateRespMsg &resp, const ObCollectStateMsg &msg); void build_tx_ask_state_resp_(ObAskStateRespMsg &resp, const ObAskStateMsg &msg); int check_for_standby(const share::ObLSID &ls_id, @@ -200,8 +204,8 @@ int create_tx_ctx_(const share::ObLSID &ls_id, int create_tx_ctx_(const share::ObLSID &ls_id, ObLS *ls, const ObTxDesc &tx, - ObPartTransCtx *&ctx); - + ObPartTransCtx *&ctx, + const bool special); int get_tx_ctx_(const share::ObLSID &ls_id, ObLS *ls, const ObTransID &tx_id, @@ -248,7 +252,7 @@ int post_tx_abort_part_msg_(const ObTxDesc &tx_desc, const ObTxPart &p); bool is_sync_replica_(const share::ObLSID &ls_id); -void handle_orphan_2pc_msg_(const ObTxMsg &msg, const bool need_check_leader); +int handle_orphan_2pc_msg_(const ObTxMsg &msg, const bool need_check_leader, const bool ls_deleted); int update_max_read_ts_(const uint64_t tenant_id, const share::ObLSID &lsid, diff --git a/src/storage/tx/ob_tx_2pc_msg_handler.cpp b/src/storage/tx/ob_tx_2pc_msg_handler.cpp index c35703568..3e578ee96 100644 --- a/src/storage/tx/ob_tx_2pc_msg_handler.cpp +++ b/src/storage/tx/ob_tx_2pc_msg_handler.cpp @@ -263,7 +263,8 @@ void ObPartTransCtx::build_tx_common_msg_(const ObLSID &receiver, int ObPartTransCtx::post_orphan_msg_(const ObTwoPhaseCommitMsgType &msg_type, const ObTxMsg &recv_msg, const common::ObAddr &self_addr, - ObITransRpc* rpc) + ObITransRpc* rpc, + const bool ls_deleted) { int ret = OB_SUCCESS; @@ -291,9 +292,29 @@ int ObPartTransCtx::post_orphan_msg_(const ObTwoPhaseCommitMsgType &msg_type, build_tx_common_msg_(recv_msg, self_addr, clear_req); - if (OB_FAIL(MTL(ObTransService*)->get_max_decided_scn(clear_req.sender_, clear_req.max_commit_log_scn_))) { - TRANS_LOG(WARN, "get max get_max_decided_scn failed", K(ret), K(clear_req)); + ObTransService *trans_service = MTL(ObTransService *); + if (OB_ISNULL(trans_service)) { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(WARN, "trans service is null", K(ret)); + } else if (ls_deleted) { + bool unused = false; + SCN scn; + ObITsMgr *ts_mgr = trans_service->get_ts_mgr(); + if (OB_ISNULL(ts_mgr)) { + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(WARN, "ts mgr is null", K(ret)); + } else if (OB_FAIL(ts_mgr->get_ts_sync(MTL_ID(), 1000000, scn, unused))) { + TRANS_LOG(WARN, "get gts sync failed", K(ret)); + } else { + clear_req.max_commit_log_scn_ = scn; + } + TRANS_LOG(INFO, "ls is deleted, use gts to build clear request", K(ret), K(clear_req)); } else { + if (OB_FAIL(trans_service->get_max_decided_scn(clear_req.sender_, clear_req.max_commit_log_scn_))) { + TRANS_LOG(WARN, "get max get_max_decided_scn failed", K(ret), K(clear_req)); + } + } + if (OB_SUCC(ret)) { ret = rpc->post_msg(recv_msg.get_sender_addr(), clear_req); } break; @@ -949,7 +970,8 @@ int ObPartTransCtx::handle_tx_2pc_clear_resp(const Ob2pcClearRespMsg &msg) int ObPartTransCtx::handle_tx_orphan_2pc_msg(const ObTxMsg &recv_msg, const common::ObAddr& self_addr, - ObITransRpc* rpc) + ObITransRpc* rpc, + const bool ls_deleted) { int ret = OB_SUCCESS; TRANS_LOG(INFO, "handle_tx_orphan_2pc_msg", K(recv_msg)); @@ -978,7 +1000,8 @@ int ObPartTransCtx::handle_tx_orphan_2pc_msg(const ObTxMsg &recv_msg, } else if (need_ack && OB_FAIL(post_orphan_msg_(send_msg_type, recv_msg, self_addr, - rpc))) { + rpc, + ls_deleted))) { TRANS_LOG(WARN, "post_orphan_msg_ failed", KR(ret), K(recv_msg), K(send_msg_type)); } return ret; diff --git a/src/storage/tx/ob_tx_api.cpp b/src/storage/tx/ob_tx_api.cpp index a27cf41d3..a3bcc79fa 100644 --- a/src/storage/tx/ob_tx_api.cpp +++ b/src/storage/tx/ob_tx_api.cpp @@ -1591,33 +1591,39 @@ inline int ObTransService::sync_rollback_savepoint__(ObTxDesc &tx, tx.rpc_cond_.reset(); /* reset rpc_cond */ if (OB_FAIL(batch_post_tx_msg_(msg, remain))) { TRANS_LOG(WARN, "batch post tx msg fail", K(msg), K(remain), K(retries)); - } - // wait result - int rpc_ret = OB_SUCCESS; - if (OB_FAIL(tx.rpc_cond_.wait(waittime, rpc_ret))) { - TRANS_LOG(WARN, "tx rpc condition wakeup", K(ret), - K(waittime), K(rpc_ret), K(expire_ts), K(remain), K(remain_cnt), K(retries), - K_(tx.state)); - // if trans is terminated, rollback savepoint should be terminated - // NOTE that this case is only for xa trans - // EXAMPLE, tx desc is shared by branch 1 and branch 2 - // 1. branch 1 starts to rollback savepoint - // 2. branch 2 is terminated - // 3. branch 1 receives callback of rollback savepoint - if (tx.is_terminated()) { - ret = OB_TRANS_HAS_DECIDED; - } else { + if (is_location_service_renew_error(ret)) { + // ignore ret ret = OB_SUCCESS; } } - if (OB_SUCCESS != rpc_ret) { - TRANS_LOG(WARN, "tx rpc fail", K(rpc_ret), K_(tx.tx_id), K(waittime), K(remain), K(remain_cnt), K(retries)); - if (rpc_ret == OB_TRANS_CTX_NOT_EXIST) { - // participant has quit, may be txn is timeout or other failure occured - // txn need abort - ret = tx.is_tx_timeout() ? OB_TRANS_TIMEOUT : OB_TRANS_KILLED; - } else { - ret = rpc_ret; + if (OB_SUCC(ret)) { + // wait result + int rpc_ret = OB_SUCCESS; + if (OB_FAIL(tx.rpc_cond_.wait(waittime, rpc_ret))) { + TRANS_LOG(WARN, "tx rpc condition wakeup", K(ret), + K(waittime), K(rpc_ret), K(expire_ts), K(remain), K(remain_cnt), K(retries), + K_(tx.state)); + // if trans is terminated, rollback savepoint should be terminated + // NOTE that this case is only for xa trans + // EXAMPLE, tx desc is shared by branch 1 and branch 2 + // 1. branch 1 starts to rollback savepoint + // 2. branch 2 is terminated + // 3. branch 1 receives callback of rollback savepoint + if (tx.is_terminated()) { + ret = OB_TRANS_HAS_DECIDED; + } else { + ret = OB_SUCCESS; + } + } + if (OB_SUCCESS != rpc_ret) { + TRANS_LOG(WARN, "tx rpc fail", K(rpc_ret), K_(tx.tx_id), K(waittime), K(remain), K(remain_cnt), K(retries)); + if (rpc_ret == OB_TRANS_CTX_NOT_EXIST) { + // participant has quit, may be txn is timeout or other failure occured + // txn need abort + ret = tx.is_tx_timeout() ? OB_TRANS_TIMEOUT : OB_TRANS_KILLED; + } else { + ret = rpc_ret; + } } } } diff --git a/src/storage/tx/ob_tx_log.cpp b/src/storage/tx/ob_tx_log.cpp index 89daaac75..3615b97ff 100644 --- a/src/storage/tx/ob_tx_log.cpp +++ b/src/storage/tx/ob_tx_log.cpp @@ -25,21 +25,31 @@ using namespace share; namespace transaction { -bool ObTxLogTypeChecker::need_pre_replay_barrier(const ObTxLogType log_type, - const ObTxDataSourceType data_source_type) +logservice::ObReplayBarrierType +ObTxLogTypeChecker::need_replay_barrier(const ObTxLogType log_type, + const ObTxDataSourceType data_source_type) { - bool need_barrier = false; - //multi data source trans's redo log + logservice::ObReplayBarrierType barrier_flag = logservice::ObReplayBarrierType::NO_NEED_BARRIER; + + // multi data source trans's redo log if (ObTxLogType::TX_MULTI_DATA_SOURCE_LOG == log_type) { - if (data_source_type == ObTxDataSourceType::CREATE_TABLET - || data_source_type == ObTxDataSourceType::REMOVE_TABLET - || data_source_type == ObTxDataSourceType::MODIFY_TABLET_BINDING) { - need_barrier = true; + if (data_source_type == ObTxDataSourceType::CREATE_TABLET_NEW_MDS + || data_source_type == ObTxDataSourceType::DELETE_TABLET_NEW_MDS + || data_source_type == ObTxDataSourceType::UNBIND_TABLET_NEW_MDS + || data_source_type == ObTxDataSourceType::START_TRANSFER_OUT + || data_source_type == ObTxDataSourceType::FINISH_TRANSFER_OUT) { + + barrier_flag = logservice::ObReplayBarrierType::PRE_BARRIER; + + } else if (data_source_type == ObTxDataSourceType::START_TRANSFER_IN + || data_source_type == ObTxDataSourceType::FINISH_TRANSFER_IN) { + + barrier_flag = logservice::ObReplayBarrierType::STRICT_BARRIER; } } - return need_barrier; + return barrier_flag; } // ============================== Tx Log Header ============================= @@ -664,15 +674,16 @@ int ObTxRedoLog::format_mutator_row_(const memtable::ObMemtableMutatorRow &row, int64_t version = 0; int32_t flag = 0; int64_t seq_no = 0; + int64_t column_cnt = 0; ObStoreRowkey rowkey; memtable::ObRowData new_row; memtable::ObRowData old_row; blocksstable::ObDmlFlag dml_flag = blocksstable::ObDmlFlag::DF_NOT_EXIST; if (OB_FAIL(row.copy(table_id, rowkey, table_version, new_row, old_row, dml_flag, - modify_count, acc_checksum, version, flag, seq_no))) { + modify_count, acc_checksum, version, flag, seq_no, column_cnt))) { TRANS_LOG(WARN, "row_.copy fail", K(ret), K(table_id), K(rowkey), K(table_version), K(new_row), - K(old_row), K(dml_flag), K(modify_count), K(acc_checksum), K(version)); + K(old_row), K(dml_flag), K(modify_count), K(acc_checksum), K(version), K(column_cnt)); } else { arg.log_stat_->new_row_size_ += new_row.size_; arg.log_stat_->old_row_size_ += old_row.size_; @@ -713,6 +724,8 @@ int ObTxRedoLog::format_mutator_row_(const memtable::ObMemtableMutatorRow &row, arg.writer_ptr_->dump_int64(new_row.size_); arg.writer_ptr_->dump_key("OldRowSize"); arg.writer_ptr_->dump_int64(old_row.size_); + arg.writer_ptr_->dump_key("ColumnCnt"); + arg.writer_ptr_->dump_int64(column_cnt); } return ret; } diff --git a/src/storage/tx/ob_tx_log.h b/src/storage/tx/ob_tx_log.h old mode 100644 new mode 100755 index 592312329..4f7b94cf0 --- a/src/storage/tx/ob_tx_log.h +++ b/src/storage/tx/ob_tx_log.h @@ -170,7 +170,7 @@ public: #endif ; } - static bool need_pre_replay_barrier(const ObTxLogType log_type, const ObTxDataSourceType data_source_type); + static logservice::ObReplayBarrierType need_replay_barrier(const ObTxLogType log_type, const ObTxDataSourceType data_source_type); }; // ============================== Tx Log Header ============================== diff --git a/src/storage/tx/ob_tx_replay_executor.cpp b/src/storage/tx/ob_tx_replay_executor.cpp old mode 100644 new mode 100755 index 7605d1718..83a282216 --- a/src/storage/tx/ob_tx_replay_executor.cpp +++ b/src/storage/tx/ob_tx_replay_executor.cpp @@ -23,6 +23,7 @@ #include "storage/tx/ob_timestamp_service.h" #include "storage/tx/ob_trans_id_service.h" #include "storage/tablelock/ob_lock_memtable.h" +#include "logservice/replayservice/ob_tablet_replay_executor.h" #include "storage/tablet/ob_tablet.h" namespace oceanbase @@ -248,7 +249,8 @@ int ObTxReplayExecutor::try_get_tx_ctx_(int64_t tx_id, int64_t tenant_id, const ret = OB_SUCCESS; bool tx_ctx_existed = false; common::ObAddr scheduler = log_block_header_.get_scheduler(); - ObTxCreateArg arg(true, /* for_replay */ + ObTxCreateArg arg(true, /* for_replay */ + false, /* for_special_tx */ tenant_id, tx_id, ls_id, @@ -256,7 +258,7 @@ int ObTxReplayExecutor::try_get_tx_ctx_(int64_t tx_id, int64_t tenant_id, const GET_MIN_CLUSTER_VERSION(), 0, /*session_id*/ scheduler, - INT64_MAX, /*trans_expired_time_*/ + INT64_MAX, /*trans_expired_time_*/ ls_tx_srv_->get_trans_service()); if (OB_FAIL(ls_tx_srv_->create_tx_ctx(arg, tx_ctx_existed, ctx_))) { TRANS_LOG(WARN, "get_tx_ctx error", K(ret), K(tx_id), KP(ctx_)); @@ -602,7 +604,7 @@ int ObTxReplayExecutor::replay_one_row_in_memtable_(ObMutatorRowHeader &row_head ObTabletHandle tablet_handle; if (OB_FAIL(ls_->replay_get_tablet(row_head.tablet_id_, log_ts_ns_, tablet_handle))) { - if (OB_TABLET_NOT_EXIST == ret) { + if (OB_OBSOLETE_CLOG_NEED_SKIP == ret) { ctx_->force_no_need_replay_checksum(); ret = OB_SUCCESS; TRANS_LOG(WARN, "[Replay Tx] tablet gc, skip this log entry", K(ret), K(row_head.tablet_id_), @@ -615,6 +617,23 @@ int ObTxReplayExecutor::replay_one_row_in_memtable_(ObMutatorRowHeader &row_head KP(ls_), K(log_ts_ns_), K(tx_part_log_no_), K(ctx_)); ret = OB_EAGAIN; } + } else if (OB_FAIL(logservice::ObTabletReplayExecutor::replay_check_restore_status(tablet_handle, false/*update_tx_data*/))) { + if (OB_NO_NEED_UPDATE == ret) { + ctx_->check_no_need_replay_checksum(log_ts_ns_); + ret = OB_SUCCESS; + if (REACH_TIME_INTERVAL(1000 * 1000)) { + TRANS_LOG(INFO, "[Replay Tx] Not need replay, skip this log entry", K(row_head.tablet_id_), + K(log_ts_ns_), K(tx_part_log_no_)); + } + } else if (OB_EAGAIN == ret) { + if (REACH_TIME_INTERVAL(1000 * 1000)) { + TRANS_LOG(INFO, "[Replay Tx] tablet not ready, retry this log entry", K(ret), K(row_head.tablet_id_), + K(log_ts_ns_), K(tx_part_log_no_)); + } + } else { + TRANS_LOG(WARN, "[Replay Tx] replay check restore status error", K(ret), K(row_head.tablet_id_), + K(log_ts_ns_), K(tx_part_log_no_)); + } } else if (OB_FAIL(get_compat_mode_(row_head.tablet_id_, mode))) { TRANS_LOG(WARN, "[Replay Tx] get compat mode error", K(ret), K(mode)); } else { diff --git a/src/storage/tx/ob_unique_id_service.h b/src/storage/tx/ob_unique_id_service.h new file mode 100644 index 000000000..f0ef59410 --- /dev/null +++ b/src/storage/tx/ob_unique_id_service.h @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2021 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_TRANSACTION_OB_UNIQUE_ID_SERVICE_ +#define OCEANBASE_TRANSACTION_OB_UNIQUE_ID_SERVICE_ + +#include "ob_trans_service.h" + +namespace oceanbase +{ + +namespace transaction +{ + +class ObUniqueIDService +{ +public: + ObUniqueIDService() {} + ~ObUniqueIDService() {} + static int mtl_init(ObUniqueIDService *&unique_id_service) + { + return OB_SUCCESS; + } + void destroy() {} + int gen_unique_id(int64_t &unique_id, const int64_t timeout_ts) + { + int ret = OB_SUCCESS; + ObTransID trans_id; + int64_t expire_ts = ObTimeUtility::current_time() + timeout_ts; + + do { + if (OB_SUCC(MTL(transaction::ObTransService *)->gen_trans_id(trans_id))) { + unique_id = trans_id.get_id(); + } else if (OB_GTI_NOT_READY == ret) { + if (ObTimeUtility::current_time() > expire_ts) { + ret = OB_NEED_RETRY; + TRANS_LOG(WARN, "get unique id not ready", K(ret), K(expire_ts)); + } else { + ob_usleep(1000); + } + } else { + TRANS_LOG(WARN, "get unique id fail", KR(ret)); + } + } while (OB_GTI_NOT_READY == ret); + return ret; + } +}; + +} +} +#endif \ No newline at end of file diff --git a/src/storage/tx/wrs/ob_black_list.cpp b/src/storage/tx/wrs/ob_black_list.cpp index 3067237e7..e93410b5b 100644 --- a/src/storage/tx/wrs/ob_black_list.cpp +++ b/src/storage/tx/wrs/ob_black_list.cpp @@ -300,7 +300,7 @@ int ObBLService::get_info_from_result_(sqlclient::ObMySQLResult &result, ObBLKey (void)GET_COL_IGNORE_NULL(result.get_int, "svr_port", port); (void)GET_COL_IGNORE_NULL(result.get_int, "tenant_id", tenant_id); (void)GET_COL_IGNORE_NULL(result.get_int, "ls_id", id); - (void)GET_COL_IGNORE_NULL(result.get_varchar, "ls_state", ls_state_str); + (void)GET_COL_IGNORE_NULL(result.get_varchar, "role", ls_state_str); (void)GET_COL_IGNORE_NULL(result.get_uint, "weak_read_scn", weak_read_scn_uint); (void)GET_COL_IGNORE_NULL(result.get_int, "migrate_status", migrate_status_int); diff --git a/src/storage/tx/wrs/ob_black_list.h b/src/storage/tx/wrs/ob_black_list.h index dfe2182d8..d50f4ea6c 100644 --- a/src/storage/tx/wrs/ob_black_list.h +++ b/src/storage/tx/wrs/ob_black_list.h @@ -31,8 +31,9 @@ // 查询 __all_virtual_ls_info 的语句,设置了2s超时时间 #define BLACK_LIST_SELECT_LS_INFO_STMT \ - "select /*+query_timeout(2000000)*/ svr_ip, svr_port, tenant_id, ls_id, ls_state, \ - weak_read_scn, migrate_status from oceanbase.__all_virtual_ls_info;" + "select /*+query_timeout(2000000)*/ a.svr_ip, a.svr_port, a.tenant_id, a.ls_id, b.role, a.weak_read_scn, a.migrate_status \ + from oceanbase.__all_virtual_ls_info a, oceanbase.__all_virtual_log_stat b \ + where a.svr_ip = b.svr_ip and a.svr_port = b.svr_port and a.tenant_id = b.tenant_id and a.ls_id = b.ls_id;" namespace oceanbase { diff --git a/src/storage/tx_storage/ob_access_service.cpp b/src/storage/tx_storage/ob_access_service.cpp old mode 100644 new mode 100755 index 60894fc3d..981fd1928 --- a/src/storage/tx_storage/ob_access_service.cpp +++ b/src/storage/tx_storage/ob_access_service.cpp @@ -21,6 +21,7 @@ #include "storage/tx_storage/ob_ls_service.h" #include "storage/tx_storage/ob_tenant_freezer.h" #include "storage/tablelock/ob_table_lock_rpc_struct.h" +#include "storage/tablet/ob_tablet.h" #include "storage/access/ob_dml_param.h" #include "share/schema/ob_table_dml_param.h" #include "share/stat/ob_opt_stat_monitor_manager.h" @@ -255,7 +256,9 @@ int ObAccessService::table_scan( param, iter->get_ctx_guard(), user_specified_snapshot_scn))) { - LOG_WARN("fail to check query allowed", K(ret), K(ls_id), K(data_tablet_id)); + if (OB_TABLET_NOT_EXIST != ret) { + LOG_WARN("fail to check query allowed", K(ret), K(ls_id), K(data_tablet_id)); + } // skip inner table, one key reason is to let tablet merge going } else if (OB_ISNULL(ls = iter->get_ctx_guard().get_ls_handle().get_ls())) { ret = OB_ERR_UNEXPECTED; @@ -263,7 +266,7 @@ int ObAccessService::table_scan( } else if (OB_ISNULL(tablet_service = ls->get_tablet_svr())) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet service should not be null.", K(ret), K(ls_id)); - } else if (OB_FAIL(tablet_service->table_scan(*iter, param))) { + } else if (OB_FAIL(tablet_service->table_scan(iter->get_ctx_guard().get_tablet_handle(), *iter, param))) { LOG_WARN("Fail to scan table, ", K(ret), K(ls_id), K(param)); } else { NG_TRACE(storage_table_scan_end); @@ -310,7 +313,9 @@ int ObAccessService::table_rescan( param, /*scan_param*/ iter->get_ctx_guard(), user_specified_snapshot_scn))) { - LOG_WARN("fail to check query allowed", K(ret), K(result), K(ls_id), K(data_tablet_id)); + if (OB_TABLET_NOT_EXIST != ret) { + LOG_WARN("fail to check query allowed", K(ret), K(result), K(ls_id), K(data_tablet_id)); + } // skip inner table, one key reason is to let tablet merge going } else if (OB_ISNULL(ls = iter->get_ctx_guard().get_ls_handle().get_ls())) { ret = OB_ERR_UNEXPECTED; @@ -318,7 +323,7 @@ int ObAccessService::table_rescan( } else if (OB_ISNULL(tablet_service = ls->get_tablet_svr())) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet service should not be null.", K(ret), K(ls_id)); - } else if (OB_FAIL(tablet_service->table_rescan(param, result))) { + } else if (OB_FAIL(tablet_service->table_rescan(iter->get_ctx_guard().get_tablet_handle(), param, result))) { LOG_WARN("Fail to scan table, ", K(ret), K(result), K(ls_id), K(param)); } else { NG_TRACE(storage_table_scan_end); @@ -359,6 +364,80 @@ int ObAccessService::get_write_store_ctx_guard_( return ret; } +int ObAccessService::get_source_ls_tx_table_guard_(ObStoreCtxGuard &ctx_guard) +{ + int ret = OB_SUCCESS; + ObTabletCreateDeleteMdsUserData user_data; + ObTablet *tablet = nullptr; + if (OB_ISNULL(tablet = ctx_guard.get_tablet_handle().get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), KPC(tablet)); + } else if (!tablet->get_tablet_meta().has_transfer_table()) { + // do nothing + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(tablet), K(user_data)); + } else if (ObTabletStatus::TRANSFER_IN != user_data.tablet_status_ || !user_data.transfer_ls_id_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet status is unexpected", K(ret), K(user_data)); + } else { + ObLS *src_ls = nullptr; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + ObTxTableGuard src_tx_table_guard; + if (!user_data.transfer_ls_id_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table type is unexpected", K(ret), K(user_data)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(user_data.transfer_ls_id_, ls_handle, ObLSGetMod::HA_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(user_data)); + } else if (OB_ISNULL(src_ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret), KP(src_ls), K(user_data)); + } else if (OB_FAIL(src_ls->get_tx_table_guard(src_tx_table_guard))) { + LOG_WARN("failed to get tablet", K(ret)); + } else if (!user_data.transfer_scn_.is_valid() || !src_tx_table_guard.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("transfer_scn or source ls tx_table_guard is invalid", K(ret), K(src_tx_table_guard), K(user_data)); + } else { + auto &ctx = ctx_guard.get_store_ctx(); + ctx.mvcc_acc_ctx_.set_src_tx_table_guard(src_tx_table_guard); + ctx.mvcc_acc_ctx_.set_transfer_scn(user_data.transfer_scn_); + LOG_DEBUG("succ get src tx table guard", K(ret), K(src_ls->get_ls_id()), K(src_tx_table_guard), K(user_data)); + } + } + + return ret; +} + +int ObAccessService::construct_store_ctx_other_variables_( + ObLS &ls, + const common::ObTabletID &tablet_id, + const int64_t timeout, + const share::SCN &snapshot, + ObStoreCtxGuard &ctx_guard) +{ + int ret = OB_SUCCESS; + const share::ObLSID &ls_id = ls.get_ls_id(); + ObLSTabletService *tablet_service = ls.get_tablet_svr(); + if (OB_ISNULL(tablet_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tablet service should not be null.", K(ret), K(ls_id)); + } else if (OB_FAIL(tablet_service->check_allow_to_read())) { + if (OB_REPLICA_NOT_READABLE == ret) { + LOG_WARN("replica unreadable", K(ret), K(ls_id), K(tablet_id)); + } else { + LOG_ERROR("failed to check allow to read", K(ret), K(ls_id), K(tablet_id)); + } + } else if (OB_FAIL(tablet_service->get_tablet_with_timeout( + tablet_id, ctx_guard.get_tablet_handle(), timeout, ObMDSGetTabletMode::READ_READABLE_COMMITED, snapshot))) { + LOG_WARN("failed to check and get tablet", K(ret), K(ls_id), K(tablet_id), K(timeout), K(snapshot)); + } else if (OB_FAIL(get_source_ls_tx_table_guard_(ctx_guard))) { + LOG_WARN("failed to get src ls tx table guard", K(ret), K(ls_id), K(tablet_id)); + } + return ret; +} /* * check_read_allowed - check replica can serve transactional read * @@ -374,6 +453,7 @@ int ObAccessService::check_read_allowed_( { int ret = OB_SUCCESS; ObLS *ls = nullptr; + LOG_TRACE("print check read allowed, scan param", K(ls_id), K(tablet_id), K(scan_param.fb_read_tx_uncommitted_)); if (OB_FAIL(ctx_guard.init(ls_id))) { LOG_WARN("ctx_guard init fail", K(ret), K(ls_id)); @@ -422,6 +502,7 @@ int ObAccessService::check_read_allowed_( } } } + // If this select is for foreign key check, // we should get tx_id and tx_desc for deadlock detection. if (OB_SUCC(ret)) { @@ -440,6 +521,11 @@ int ObAccessService::check_read_allowed_( } } } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(construct_store_ctx_other_variables_(*ls, tablet_id, scan_param.timeout_, + ctx.mvcc_acc_ctx_.get_snapshot_version(), ctx_guard))) { + LOG_WARN("failed to check replica allow to read", K(ret), K(tablet_id), "timeout", scan_param.timeout_); + } } return ret; } @@ -465,8 +551,9 @@ int ObAccessService::check_write_allowed_( ObLockParam lock_param; const ObTableLockMode lock_mode = ROW_EXCLUSIVE; const ObTableLockOpType lock_op_type = IN_TRANS_DML_LOCK; - const ObTableLockOwnerID lock_owner = 0; + const ObTableLockOwnerID lock_owner(0); const bool is_try_lock = false; + const bool is_deadlock_avoid_enabled = false; if (OB_FAIL(check_tenant_out_of_memstore_limit_(is_out_of_mem))) { LOG_WARN("fail to check tenant out of mem limit", K(ret), K_(tenant_id)); } else if (is_out_of_mem && !tablet_id.is_inner_tablet()) { @@ -483,6 +570,9 @@ int ObAccessService::check_write_allowed_( } else if (OB_ISNULL(ls = ctx_guard.get_ls_handle().get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("ls should not be null", K(ret), K(ls_id), K_(tenant_id)); + } else if (OB_FAIL(construct_store_ctx_other_variables_(*ls, tablet_id, dml_param.timeout_, + share::SCN::max_scn(), ctx_guard))) { + LOG_WARN("failed to check replica allow to read", K(ret), K(tablet_id)); } else { // TODO: this may confuse user, because of txn timeout won't notify user proactively auto lock_expired_ts = MIN(dml_param.timeout_, tx_desc.get_expire_ts()); @@ -493,6 +583,7 @@ int ObAccessService::check_write_allowed_( lock_owner, lock_op_type, dml_param.schema_version_, + is_deadlock_avoid_enabled, is_try_lock, lock_expired_ts))) { LOG_WARN("get lock param failed", K(ret), K(lock_id)); @@ -550,7 +641,8 @@ int ObAccessService::delete_rows( ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet service should not be null.", K(ret), K(ls_id)); } else { - ret = tablet_service->delete_rows(ctx_guard.get_store_ctx(), + ret = tablet_service->delete_rows(ctx_guard.get_tablet_handle(), + ctx_guard.get_store_ctx(), dml_param, column_ids, row_iter, @@ -604,7 +696,8 @@ int ObAccessService::put_rows( ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet service should not be null.", K(ret), K(ls_id)); } else { - ret = tablet_service->put_rows(ctx_guard.get_store_ctx(), + ret = tablet_service->put_rows(ctx_guard.get_tablet_handle(), + ctx_guard.get_store_ctx(), dml_param, column_ids, row_iter, @@ -658,7 +751,8 @@ int ObAccessService::insert_rows( ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet service should not be null.", K(ret), K(ls_id)); } else { - ret = tablet_service->insert_rows(ctx_guard.get_store_ctx(), + ret = tablet_service->insert_rows(ctx_guard.get_tablet_handle(), + ctx_guard.get_store_ctx(), dml_param, column_ids, row_iter, @@ -716,7 +810,8 @@ int ObAccessService::insert_row( ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet service should not be null.", K(ret), K(ls_id)); } else { - ret = tablet_service->insert_row(ctx_guard.get_store_ctx(), + ret = tablet_service->insert_row(ctx_guard.get_tablet_handle(), + ctx_guard.get_store_ctx(), dml_param, column_ids, duplicated_column_ids, @@ -783,7 +878,8 @@ int ObAccessService::update_rows( ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet service should not be null.", K(ret), K(ls_id)); } else { - ret = tablet_service->update_rows(ctx_guard.get_store_ctx(), + ret = tablet_service->update_rows(ctx_guard.get_tablet_handle(), + ctx_guard.get_store_ctx(), dml_param, column_ids, updated_column_ids, @@ -838,7 +934,8 @@ int ObAccessService::lock_rows( ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet service should not be null.", K(ret), K(ls_id)); } else { - ret = tablet_service->lock_rows(ctx_guard.get_store_ctx(), + ret = tablet_service->lock_rows(ctx_guard.get_tablet_handle(), + ctx_guard.get_store_ctx(), dml_param, abs_lock_timeout, lock_flag, @@ -887,7 +984,8 @@ int ObAccessService::lock_row( ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet service should not be null.", K(ret), K(ls_id)); } else { - ret = tablet_service->lock_row(ctx_guard.get_store_ctx(), + ret = tablet_service->lock_row(ctx_guard.get_tablet_handle(), + ctx_guard.get_store_ctx(), dml_param, abs_lock_timeout, row, @@ -1082,6 +1180,7 @@ void ObAccessService::ObStoreCtxGuard::reset() LOG_WARN_RET(OB_ERR_TOO_MUCH_TIME, "guard used too much time", K(guard_used_us), K_(ls_id), K(lbt())); } ls_id_.reset(); + tablet_handle_.reset(); is_inited_ = false; } } diff --git a/src/storage/tx_storage/ob_access_service.h b/src/storage/tx_storage/ob_access_service.h index 6b7c8a788..6b43bea71 100644 --- a/src/storage/tx_storage/ob_access_service.h +++ b/src/storage/tx_storage/ob_access_service.h @@ -64,11 +64,13 @@ public: void reset(); ObStoreCtx &get_store_ctx() { return ctx_; } ObLSHandle &get_ls_handle() { return handle_; } + ObTabletHandle &get_tablet_handle() { return tablet_handle_; } private: bool is_inited_; ObStoreCtx ctx_; share::ObLSID ls_id_; ObLSHandle handle_; + ObTabletHandle tablet_handle_; int64_t init_ts_; }; public: @@ -221,6 +223,13 @@ protected: const common::ObTabletID &tablet_id, const common::ObOptDmlStatType dml_stat_type, const int64_t affected_rows); + int get_source_ls_tx_table_guard_(ObStoreCtxGuard &ctx_guard); + int construct_store_ctx_other_variables_( + ObLS &ls, + const common::ObTabletID &tablet_id, + const int64_t timeout, + const share::SCN &snapshot, + ObStoreCtxGuard &ctx_guard); private: bool is_inited_; uint64_t tenant_id_; diff --git a/src/storage/tx_storage/ob_checkpoint_service.cpp b/src/storage/tx_storage/ob_checkpoint_service.cpp index 3f506cf51..b0407620f 100644 --- a/src/storage/tx_storage/ob_checkpoint_service.cpp +++ b/src/storage/tx_storage/ob_checkpoint_service.cpp @@ -140,6 +140,7 @@ void ObCheckPointService::ObCheckpointTask::runTimerTask() } else if (OB_ISNULL(iter = guard.get_ptr())) { STORAGE_LOG(WARN, "iter is NULL", K(ret)); } else { + DEBUG_SYNC(BEFORE_CHECKPOINT_TASK); ObLS *ls = nullptr; int ls_cnt = 0; for (; OB_SUCC(ret) && OB_SUCC(iter->get_next(ls)); ++ls_cnt) { diff --git a/src/storage/tx_storage/ob_empty_shell_task.cpp b/src/storage/tx_storage/ob_empty_shell_task.cpp new file mode 100644 index 000000000..7320badf5 --- /dev/null +++ b/src/storage/tx_storage/ob_empty_shell_task.cpp @@ -0,0 +1,395 @@ +/** + * Copyright (c) 2021 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 "ob_empty_shell_task.h" +#include "storage/tx_storage/ob_ls_map.h" // ObLSIterator +#include "storage/tx_storage/ob_ls_service.h" // ObLSService +#include "storage/tablet/ob_tablet.h" // ObTablet +#include "storage/tablet/ob_tablet_iterator.h" +#include "share/ob_tenant_info_proxy.h" +#include "rootserver/ob_tenant_info_loader.h" +#include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" + +namespace oceanbase +{ +using namespace share; +namespace storage +{ +namespace checkpoint +{ + +// The time interval for checking deleted tablet trigger is 5s +const int64_t ObEmptyShellTask::GC_EMPTY_TABLET_SHELL_INTERVAL = 5 * 1000 * 1000L; + +// The time interval for tablet become empty shell is 24 * 720 * 5s = 1d +const int64_t ObEmptyShellTask::GLOBAL_EMPTY_CHECK_INTERVAL_TIMES = 24 * 720; + +void ObEmptyShellTask::runTimerTask() +{ + STORAGE_LOG(INFO, "====== [emptytablet] empty shell timer task ======", K(GC_EMPTY_TABLET_SHELL_INTERVAL)); + int ret = OB_SUCCESS; + ObLSIterator *iter = NULL; + common::ObSharedGuard guard; + ObLSService *ls_svr = MTL(ObLSService*); + bool skip_empty_shell_task = false; + RLOCAL_STATIC(int64_t, times) = 0; + times = (times + 1) % GLOBAL_EMPTY_CHECK_INTERVAL_TIMES; + + skip_empty_shell_task = (OB_SUCCESS != (OB_E(EventTable::EN_TABLET_EMPTY_SHELL_TASK_FAILED) OB_SUCCESS)); + + if (!ObServerCheckpointSlogHandler::get_instance().is_started()) { + // do nothing + STORAGE_LOG(DEBUG, "ob block manager has not started"); + } else if (OB_ISNULL(ls_svr)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "mtl ObLSService should not be null", KR(ret)); + } else if (OB_UNLIKELY(skip_empty_shell_task)) { + // do nothing + } else if (OB_FAIL(ls_svr->get_ls_iter(guard, ObLSGetMod::TXSTORAGE_MOD))) { + STORAGE_LOG(WARN, "get log stream iter failed", KR(ret)); + } else if (OB_ISNULL(iter = guard.get_ptr())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "iter is NULL", KR(ret)); + } else { + ObLS *ls = NULL; + int ls_cnt = 0; + for (; OB_SUCC(ret) && OB_SUCC(iter->get_next(ls)); ++ls_cnt) { + ObTabletEmptyShellHandler *tablet_empty_shell_handler = NULL; + if (OB_ISNULL(ls)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls is NULL", KR(ret)); + } else if (FALSE_IT(tablet_empty_shell_handler = ls->get_tablet_empty_shell_handler())) { + } else if (tablet_empty_shell_handler->check_stop()) { + STORAGE_LOG(INFO, "[emptytablet] tablet_gc_handler is stop", K(ls->get_ls_id())); + } else if (0 == times || tablet_empty_shell_handler->get_empty_shell_trigger()) { + STORAGE_LOG(INFO, "[emptytablet] task check ls", "ls_id", ls->get_ls_id(), K(tablet_empty_shell_handler)); + tablet_empty_shell_handler->set_empty_shell_trigger(false); + obsys::ObRLockGuard lock(tablet_empty_shell_handler->wait_lock_); + bool need_retry = false; + common::ObTabletIDArray empty_shell_tablet_ids; + if (OB_FAIL(tablet_empty_shell_handler->get_empty_shell_tablet_ids(empty_shell_tablet_ids, need_retry))) { + need_retry = true; + STORAGE_LOG(WARN, "[emptytablet] tablet_empty_shell_handler get empty shell tablet ids failed", K(ret), "ls_id", ls->get_ls_id()); + } else if (empty_shell_tablet_ids.empty()) { + // do nothing + } else if (OB_FAIL(tablet_empty_shell_handler->update_tablets_to_empty_shell(ls, empty_shell_tablet_ids))) { + need_retry = true; + STORAGE_LOG(WARN, "update tablet to empty shell failed", KR(ret), "ls_id", ls->get_ls_id()); + } + if (need_retry) { + STORAGE_LOG(INFO, "[emptytablet] tablet become empty shell error, need try", KR(ret), KPC(ls), K(empty_shell_tablet_ids)); + if (!tablet_empty_shell_handler->get_empty_shell_trigger()) { + tablet_empty_shell_handler->set_empty_shell_trigger(true); + } + } + } + } + if (ret == OB_ITER_END) { + ret = OB_SUCCESS; + if (ls_cnt > 0) { + STORAGE_LOG(INFO, "[emptytablet] succeed to change tablet to empty shell", KR(ret), K(ls_cnt), K(times)); + } else { + STORAGE_LOG(INFO, "[emptytablet] no logstream", KR(ret), K(ls_cnt), K(times)); + } + } + } +} + +int ObTabletEmptyShellHandler::init(ObLS *ls) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + STORAGE_LOG(WARN, "ObTabletGCHandler init twice", KR(ret)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", KR(ret)); + } else { + ls_ = ls; + is_inited_ = true; + } + return ret; +} + +int ObTabletEmptyShellHandler::get_empty_shell_tablet_ids(common::ObTabletIDArray &empty_shell_tablet_ids, bool &need_retry) +{ + int ret = OB_SUCCESS; + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "tablet empty shell handler is not inited", KR(ret)); + } else if (OB_FAIL(ls_->get_tablet_svr()->build_tablet_iter(tablet_iter))) { + STORAGE_LOG(WARN, "failed to build ls tablet iter", KR(ret), KPC(this)); + } else { + ObTabletHandle tablet_handle; + ObTablet *tablet = NULL; + bool can_become_shell = false; + bool is_deleted = false; + bool is_locked = false; + while (OB_SUCC(ret)) { + if (check_stop()) { + ret = OB_EAGAIN; + STORAGE_LOG(INFO, "tablet empty shell handler stop", KR(ret), KPC(this), K(tablet_handle), KPC(ls_), K(ls_->get_ls_meta())); + } else if (OB_FAIL(tablet_iter.get_next_tablet(tablet_handle))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + STORAGE_LOG(WARN, "failed to get tablet", KR(ret), KPC(this), K(tablet_handle)); + } + } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "invalid tablet handle", KR(ret), KPC(this), K(tablet_handle)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "tablet is NULL", KR(ret)); + } else if (tablet->is_ls_inner_tablet()) { + // skip ls inner tablet + } else if (OB_FAIL(tablet->is_locked_by_others(is_locked))) { + STORAGE_LOG(WARN, "failed to get is locked", KR(ret), KPC(tablet)); + } else if (is_locked) { + STORAGE_LOG(INFO, "tablet_status is changing", KR(ret), KPC(tablet)); + need_retry = true; + } + + if (OB_FAIL(ret) || need_retry) { + } else if (OB_FAIL(check_tablet_deleted_(tablet, is_deleted))) { + STORAGE_LOG(WARN, "fail to check_tablet_deleted", KR(ret)); + } else if (!is_deleted) { + } else if (OB_FAIL(check_can_become_empty_shell_(tablet, can_become_shell, need_retry))) { + STORAGE_LOG(WARN, "check tablet can become empty shell failed", KR(ret), KPC(tablet)); + } else if (!can_become_shell) { + STORAGE_LOG(INFO, "table can not become shell", KR(ret), KPC(tablet)); + } else if (OB_FAIL(empty_shell_tablet_ids.push_back(tablet->get_tablet_meta().tablet_id_))) { + STORAGE_LOG(WARN, "update tablet to empty shell failed", KR(ret), KPC(tablet)); + } + + } + } + + return ret; +} + +int ObTabletEmptyShellHandler::update_tablets_to_empty_shell(ObLS *ls, const common::ObIArray &tablet_ids) { + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { + const ObTabletID &tablet_id = tablet_ids.at(i); + if (OB_FAIL(ls->get_tablet_svr()->update_tablet_to_empty_shell(tablet_id))) { + STORAGE_LOG(WARN, "failed to update tablet to shell", K(ret), K(ls_id), K(tablet_id)); + } else { + #ifdef ERRSIM + const uint64_t tenant_id = MTL_ID(); + SERVER_EVENT_ADD("gc", "turn_into_empty_shell", "tenant_id", tenant_id, "ls_id", ls->get_ls_id(), "tablet_id", tablet_id); + #endif + } + } + + return ret; +} + +int ObTabletEmptyShellHandler::check_tablet_deleted_(ObTablet *tablet, bool &is_deleted) +{ + int ret = OB_SUCCESS; + is_deleted = false; + bool is_finish = false; + ObTabletCreateDeleteMdsUserData data; + if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "tablet is null", KR(ret)); + } else if (tablet->is_empty_shell()) { + // do nothing + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + if (OB_EMPTY_RESULT == ret) { + STORAGE_LOG(INFO, "tablet_status is null", KR(ret), KPC(tablet)); + ret = OB_SUCCESS; + } else { + STORAGE_LOG(WARN, "failed to get latest tablet status", K(ret), KP(tablet)); + } + } else if (ObTabletStatus::DELETED == data.tablet_status_ + || ObTabletStatus::TRANSFER_OUT_DELETED == data.tablet_status_) { + is_deleted = true; + STORAGE_LOG(INFO, "get tablet for deleting", KPC(tablet), K(data)); + } + return ret; +} + +int ObTabletEmptyShellHandler::check_can_become_empty_shell_(ObTablet *tablet, bool &can, bool &need_retry) +{ + int ret = OB_SUCCESS; + can = false; + bool is_committed = false; + ObTabletCreateDeleteMdsUserData user_data; + const uint64_t tenant_id = MTL_ID(); + bool is_shell = false; + if (!is_user_tenant(tenant_id)) { + can = true; + STORAGE_LOG(INFO, "tenant is not a user tenant", KR(ret), K(tenant_id), KP(tablet)); + } else if (OB_ISNULL(tablet)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "tablet is NULL", KR(ret), KPC(this->ls_), K(tablet)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + if (OB_EMPTY_RESULT == ret) { + can = true; + STORAGE_LOG(INFO, "tablet_status is null", KR(ret), KPC(tablet)); + ret = OB_SUCCESS; + } else { + STORAGE_LOG(WARN, "failed to get latest tablet status", K(ret), KP(tablet)); + } + } else if (MTL_IS_PRIMARY_TENANT() && OB_FAIL(check_tablet_empty_shell_for_primary_(user_data, can, need_retry))) { + STORAGE_LOG(WARN, "failed to check tablet can become empty shell for primary", K(ret), KPC(tablet)); + } else if (!MTL_IS_PRIMARY_TENANT() && OB_FAIL(check_tablet_empty_shell_for_standby_(user_data, can, need_retry))) { + STORAGE_LOG(WARN, "failed to update tablet to shell", K(ret), KPC(tablet)); + } + return ret; +} + +int ObTabletEmptyShellHandler::check_tablet_empty_shell_for_standby_( + const ObTabletCreateDeleteMdsUserData &user_data, + bool &can, bool &need_retry) +{ + int ret = OB_SUCCESS; + can = false; + bool not_depend_on = false; + ObTabletStatus::Status tablet_status = user_data.get_tablet_status(); + rootserver::ObTenantInfoLoader *info = MTL(rootserver::ObTenantInfoLoader*); + SCN readable_scn = SCN::base_scn(); + if (!user_data.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(user_data)); + } else if (OB_FAIL(info->get_readable_scn(readable_scn))) { + STORAGE_LOG(WARN, "failed to get readable scn", K(ret), K(readable_scn), K(user_data)); + } else if (MTL_IS_PRIMARY_TENANT() || !readable_scn.is_valid()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "The tenant is belong to the primary database or readable_scn is invalid", + K(ret), K(readable_scn), K(user_data)); + } else if (ObTabletStatus::TRANSFER_OUT_DELETED == tablet_status && OB_FAIL(check_transfer_out_deleted_tablet_(user_data, not_depend_on, need_retry))) { + STORAGE_LOG(WARN, "failed to check transfer out deleted tablet", K(ret), K(readable_scn), K(user_data)); + } else if (ObTabletStatus::DELETED == tablet_status || not_depend_on) { + if (user_data.delete_commit_scn_.is_valid() && user_data.delete_commit_scn_ <= readable_scn) { + can = true; + STORAGE_LOG(INFO, "readable_scn is buggerer than finish_scn", K(readable_scn), K(user_data)); + } else { + need_retry = true; + if (REACH_TENANT_TIME_INTERVAL(1 * 1000 * 1000/*1s*/)) { + STORAGE_LOG(INFO, "readable_scn is smaller than finish_scn", K(info), K(user_data)); + } + } + } + return ret; +} + +int ObTabletEmptyShellHandler::check_tablet_empty_shell_for_primary_( + const ObTabletCreateDeleteMdsUserData &user_data, + bool &can, bool &need_retry) +{ + int ret = OB_SUCCESS; + const ObTabletStatus &tablet_status = user_data.tablet_status_; + if (!user_data.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(user_data)); + } else if (!MTL_IS_PRIMARY_TENANT()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "The tenant does not belong to the primary database", K(ret), K(user_data)); + } else if (ObTabletStatus::DELETED == tablet_status) { + can = true; + STORAGE_LOG(INFO, "tablet_status is deleted in primary", K(ret), K(user_data)); + } else if (ObTabletStatus::TRANSFER_OUT_DELETED == tablet_status) { + if (OB_FAIL(check_transfer_out_deleted_tablet_(user_data, can, need_retry))) { + STORAGE_LOG(WARN, "failed to update tablet to shell", K(ret), K(user_data)); + } + } + return ret; +} + +int ObTabletEmptyShellHandler::check_transfer_out_deleted_tablet_( + const ObTabletCreateDeleteMdsUserData &user_data, bool &can, bool &need_retry) +{ + int ret = OB_SUCCESS; + can = false; + SCN decided_scn; + ObMigrationStatus migration_status; + ObLSService *ls_service = NULL; + ObLSHandle ls_handle; + ObLS *ls = NULL; + if (!user_data.is_valid() || !user_data.transfer_ls_id_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "user_data or transfer_ls_id is invalid", K(ret), K(user_data)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls service should not be null", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(user_data.transfer_ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + if (OB_LS_NOT_EXIST == ret) { + can = true; + STORAGE_LOG(INFO, "transfer dest ls not exist, src tablet can become empty shell", K(ret), K(user_data)); + ret = OB_SUCCESS; + } else { + STORAGE_LOG(WARN, "failed to get ls", K(ret), K(user_data)); + } + } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls should not be NULL", K(ret),K(user_data)); + } else if (OB_FAIL(ls->get_migration_status(migration_status))) { + STORAGE_LOG(WARN, "ls is get migration status", K(ret),K(user_data)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_ADD == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE == migration_status + || ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD == migration_status) { + can = true; + STORAGE_LOG(INFO, "migration_status is OB_MIGRATION_STATUS_MIGRATE", K(ret), K(can), K(user_data), K(migration_status)); + } else if (OB_FAIL(ls->get_max_decided_scn(decided_scn))) { + STORAGE_LOG(WARN, "failed to get max decided scn", K(ret), K(user_data)); + } else if (decided_scn >= user_data.delete_commit_scn_) { + can = true; + STORAGE_LOG(INFO, "decided_scn is bigger than transfer finish scn", K(ret), K(can), K(user_data), K(decided_scn)); + } else { + need_retry = true; + if (REACH_TENANT_TIME_INTERVAL(1 * 1000 * 1000/*1s*/)) { + STORAGE_LOG(INFO, "decided_scn is smaller than tablet delete commit scn", K(user_data), K(decided_scn)); + } + } + return ret; +} + +bool ObTabletEmptyShellHandler::get_empty_shell_trigger() const +{ + return ATOMIC_LOAD(&is_trigger_); +} + +void ObTabletEmptyShellHandler::set_empty_shell_trigger(bool is_trigger) +{ + ATOMIC_STORE(&is_trigger_, is_trigger); + STORAGE_LOG(INFO, "[emptytablet] set empty shell trigger", "ls_id", ls_->get_ls_id(), K(is_trigger)); +} + +int ObTabletEmptyShellHandler::offline() +{ + int ret = OB_SUCCESS; + set_stop(); + if (!is_finish()) { + ret = OB_EAGAIN; + STORAGE_LOG(INFO, "tablet empty shell handler not finish, retry", KR(ret), KPC(this), KPC(ls_), K(ls_->get_ls_meta())); + } else { + STORAGE_LOG(INFO, "tablet empty shell handler offline", KPC(this), KPC(ls_), K(ls_->get_ls_meta())); + } + return ret; +} + +void ObTabletEmptyShellHandler::online() +{ + set_empty_shell_trigger(true); + set_start(); + STORAGE_LOG(INFO, "empty shell handler online", KPC(this), KPC(ls_), K(ls_->get_ls_meta())); +} + + +} // checkpoint +} // storage +} // oceanbase diff --git a/src/storage/tx_storage/ob_empty_shell_task.h b/src/storage/tx_storage/ob_empty_shell_task.h new file mode 100644 index 000000000..4515db35a --- /dev/null +++ b/src/storage/tx_storage/ob_empty_shell_task.h @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2021 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 OCEABASE_STORAGE_OB_EMPTY_SHELL_TASK_ +#define OCEABASE_STORAGE_OB_EMPTY_SHELL_TASK_ + +#include "lib/oblog/ob_log.h" +#include "lib/task/ob_timer.h" +#include "share/scn.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "share/ob_tenant_info_proxy.h" + +namespace oceanbase +{ +namespace storage +{ +namespace checkpoint +{ + +class ObTabletGCService; +class ObTabletEmptyShellHandler +{ +public: + friend class ObEmptyShellTask; +public: + ObTabletEmptyShellHandler() + : ls_(NULL), + is_trigger_(true), + stopped_(false), + is_inited_(false) + {} + ~ObTabletEmptyShellHandler() { reset(); } + void reset() + { + ls_ = NULL; + is_inited_ = false; + } + int init(storage::ObLS *ls); + + bool check_stop() { return ATOMIC_LOAD(&stopped_) == true; } + int offline(); + void online(); + bool get_empty_shell_trigger() const; + void set_empty_shell_trigger(bool is_trigger); + TO_STRING_KV(K_(is_inited), K_(is_trigger), K_(stopped)); + +private: + void set_stop() { ATOMIC_STORE(&stopped_, true); } + void set_start() { ATOMIC_STORE(&stopped_, false); } + bool is_finish() { obsys::ObWLockGuard lock(wait_lock_, false); return lock.acquired(); } + int check_tablet_deleted_(ObTablet *tablet, bool &is_deleted); + int get_empty_shell_tablet_ids(common::ObTabletIDArray &empty_shell_tablet_ids, bool &need_retry); + int update_tablets_to_empty_shell(ObLS *ls, const common::ObIArray &tablet_ids); + // Conditions for a tablet status is transfer_out_deleted to become an empty shell in primary database(1 or 2 or 3): + // 1. The node dest_ls where the tablet resides does not exist; + // or 2. The migration status of dest_ls is OB_MIGRATION_STATUS_MIGRATE; + // or 3. The replay decided scn of dest_ls is greater than the finish_scn of transfer_out_deleted tablet + int check_tablet_empty_shell_for_primary_( + const ObTabletCreateDeleteMdsUserData &user_data, + bool &can, bool &need_retry); + // Conditions for a tablet status is transfer_out_deleted to become an empty shell in standby database(1 or 2 or 3 or 4): + // 1. Tenant-level replayable scn is greater than the finish_scn of transfer_out_deleted tablet + // 2. The node dest_ls where the tablet resides does not exist; + // 3. The migration status of dest_ls is OB_MIGRATION_STATUS_MIGRATE; + // 4. The replay decided scn of dest_ls is greater than the finish_scn of transfer_out_deleted tablet + int check_tablet_empty_shell_for_standby_( + const ObTabletCreateDeleteMdsUserData &user_data, + bool &can, bool &need_retry); + int check_can_become_empty_shell_(ObTablet *tablet, bool &can, bool &need_retry); + int check_transfer_out_deleted_tablet_(const ObTabletCreateDeleteMdsUserData &user_data, bool &can, bool &need_retry); + +public: + obsys::ObRWLock wait_lock_; + +private: + storage::ObLS *ls_; + bool is_trigger_; + bool stopped_; + bool is_inited_; +}; + + +class ObEmptyShellTask : public common::ObTimerTask +{ + +public: + static const int64_t GC_EMPTY_TABLET_SHELL_INTERVAL; + static const int64_t GLOBAL_EMPTY_CHECK_INTERVAL_TIMES; + ObEmptyShellTask(ObTabletGCService &tablet_gc_service) + : tablet_gc_service_(tablet_gc_service) + {} + virtual ~ObEmptyShellTask() {} + virtual void runTimerTask(); + +private: + ObTabletGCService &tablet_gc_service_; +}; + +} // checkpoint +} // storage +} // oceanbase + +#endif diff --git a/src/storage/tx_storage/ob_ls_service.cpp b/src/storage/tx_storage/ob_ls_service.cpp index 632cf0f2a..7c998bd45 100644 --- a/src/storage/tx_storage/ob_ls_service.cpp +++ b/src/storage/tx_storage/ob_ls_service.cpp @@ -31,6 +31,7 @@ #include "storage/tx/ob_trans_service.h" #include "storage/tx_storage/ob_ls_handle.h" //ObLSHandle #include "rootserver/ob_tenant_info_loader.h" +#include "observer/ob_server_event_history_table_operator.h" namespace oceanbase { @@ -711,8 +712,7 @@ int ObLSService::enable_replay() ObInnerLSStatus ls_status; common::ObSharedGuard ls_iter; ObLS *ls = nullptr; - share::ObLSRestoreStatus restore_status; - ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + bool can_replay = true; if (OB_FAIL(get_ls_iter(ls_iter, ObLSGetMod::TXSTORAGE_MOD))) { LOG_WARN("failed to get ls iter", K(ret)); } else { @@ -724,16 +724,10 @@ int ObLSService::enable_replay() } else if (nullptr == ls) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("ls is null", K(ret)); - } else if (ls->is_need_gc()) { - // this ls will be gc later, should not enable replay - } else if (OB_FAIL(ls->get_migration_status(migration_status))) { - LOG_WARN("failed to get ls migration status", K(ret)); - } else if (ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD == migration_status) { - // ls will online in rebuild process - } else if (OB_FAIL(ls->get_restore_status(restore_status))) { - LOG_WARN("fail to get ls restore status", K(ret)); - } else if (!restore_status.can_replay_log()) { - // while downtime, if ls's restore status is in [restore_start, wait_restore_tablet_meta], clog can't replay + } else if (OB_FAIL(ls->check_can_replay_clog(can_replay))) { + LOG_WARN("failed to check ls can replay clog", K(ret), KPC(ls)); + } else if (!can_replay) { + // ls can not enable replay } else if (OB_FAIL(ls->enable_replay())) { LOG_ERROR("fail to enable replay", K(ret)); } @@ -844,7 +838,7 @@ int ObLSService::replay_create_ls_(const ObLSMeta &ls_meta) unused_allow_log_sync))) { LOG_WARN("enable ls palf failed", K(ret), K(ls_meta)); } else { - // do nothing + LOG_INFO("success replay create ls", K(ret), K(ls_meta)); } } if (OB_FAIL(ret)) { @@ -1065,9 +1059,9 @@ int ObLSService::create_ls_for_ha( } else { state = ObLSCreateState::CREATE_STATE_FINISH; ls->finish_create(is_commit); - if (OB_SUCCESS != (tmp_ret = ls->start())) { + if (OB_FAIL(ls->start())) { LOG_ERROR("ls start failed", K(tmp_ret), K(ls_meta)); - } else if (OB_FAIL(OB_SUCCESS != (tmp_ret = ls->get_ls_migration_handler()->add_ls_migration_task(task_id, arg)))) { + } else if (OB_FAIL(ls->get_ls_migration_handler()->add_ls_migration_task(task_id, arg))) { LOG_WARN("failed to add ls migration task", K(ret), K(arg)); } else { FLOG_INFO("add ls to ls service succ", K(ls->get_ls_id()), K(ls_meta)); @@ -1220,78 +1214,6 @@ int ObLSService::get_ls_ids(common::ObIArray &ls_id_array) return ret; } -int ObLSService::create_tablet(const obrpc::ObBatchCreateTabletArg &batch_arg, - obrpc::ObCreateTabletBatchRes &result) -{ - int ret = OB_SUCCESS; - ObLSHandle handle; - share::ObLSID ls_id = batch_arg.id_; - ObLS *ls = NULL; - const bool is_replay = false; - lib::ObMutexGuard change_guard(change_lock_); - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (OB_UNLIKELY(!is_running_)) { - ret = OB_NOT_RUNNING; - LOG_WARN("ls service is not running.", K(ret)); - } else if (OB_UNLIKELY(!ObServerCheckpointSlogHandler::get_instance().is_started())) { - ret = OB_NOT_RUNNING; - LOG_WARN("ls service does not service before slog replay finished", K(ret)); - } else if (OB_UNLIKELY(!batch_arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(batch_arg)); - } else if (OB_FAIL(get_ls(ls_id, handle, ObLSGetMod::TXSTORAGE_MOD))) { - LOG_WARN("get log stream failed", K(ret), K(ls_id)); - } else if (OB_ISNULL(ls = handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("log stream is null, unexpected error", K(ret), K(ls_id)); - } else if (OB_FAIL(ls->batch_create_tablets(batch_arg, SCN(), is_replay))) { - LOG_WARN("batch create tablet failed", K(ret), K(batch_arg)); - } else { - // do nothing - } - result.ret_ = ret; - return ret; -} - -int ObLSService::remove_tablet(const obrpc::ObBatchRemoveTabletArg &batch_arg, - obrpc::ObRemoveTabletRes &result) -{ - int ret = OB_SUCCESS; - ObLSHandle handle; - share::ObLSID ls_id = batch_arg.id_; - ObLS *ls = NULL; - const bool is_replay = false; - lib::ObMutexGuard change_guard(change_lock_); - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (OB_UNLIKELY(!is_running_)) { - ret = OB_NOT_RUNNING; - LOG_WARN("ls service is not running.", K(ret)); - } else if (OB_UNLIKELY(!ObServerCheckpointSlogHandler::get_instance().is_started())) { - ret = OB_NOT_RUNNING; - LOG_WARN("ls service does not service before slog replay finished", K(ret)); - } else if (OB_UNLIKELY(!batch_arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(batch_arg)); - } else if (OB_FAIL(get_ls(ls_id, handle, ObLSGetMod::TXSTORAGE_MOD))) { - LOG_WARN("get log stream failed", K(ret), K(ls_id)); - } else if (OB_ISNULL(ls = handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("log stream is null, unexpected error", K(ls_id)); - } else if (OB_FAIL(ls->batch_remove_tablets(batch_arg, is_replay))) { - LOG_WARN("batch remove tablet failed", K(ret), K(batch_arg)); - } else { - // do nothing - } - result.ret_ = ret; - return ret; -} - bool ObLSService::is_ls_to_restore_(const obrpc::ObCreateLSArg &arg) const { return arg.get_tenant_info().is_restore(); diff --git a/src/storage/tx_storage/ob_ls_service.h b/src/storage/tx_storage/ob_ls_service.h index d8ca2fe03..09673dfe1 100644 --- a/src/storage/tx_storage/ob_ls_service.h +++ b/src/storage/tx_storage/ob_ls_service.h @@ -121,15 +121,6 @@ public: // get all ls ids int get_ls_ids(common::ObIArray &ls_id_array); - // tablet operation - int create_tablet(const obrpc::ObBatchCreateTabletArg &batch_arg, - obrpc::ObCreateTabletBatchRes &result); - // remove tablets from a ls - // @param [in] arg, all the remove parameters needed. - // @param [out] result, the return code of the remove op. - int remove_tablet(const obrpc::ObBatchRemoveTabletArg &batch_arg, - obrpc::ObRemoveTabletRes &result); - // tablet operation in transactions // Create tablets for a ls // @param [in] tx_desc, trans descriptor diff --git a/src/storage/tx_storage/ob_tablet_gc_service.cpp b/src/storage/tx_storage/ob_tablet_gc_service.cpp old mode 100644 new mode 100755 index 03f6d62a5..d1301130b --- a/src/storage/tx_storage/ob_tablet_gc_service.cpp +++ b/src/storage/tx_storage/ob_tablet_gc_service.cpp @@ -23,9 +23,12 @@ #include "storage/tx_storage/ob_ls_service.h" // ObLSService #include "logservice/ob_log_service.h" #include "logservice/palf/log_define.h" +#include "observer/ob_server_event_history_table_operator.h" +#include "share/ob_tenant_info_proxy.h" #include "storage/tablet/ob_tablet.h" // ObTablet #include "rootserver/ob_tenant_info_loader.h" #include "share/ob_tenant_info_proxy.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" namespace oceanbase { @@ -44,9 +47,6 @@ const int64_t ObTabletGCHandler::FLUSH_CHECK_MAX_TIMES = 72; // The time interval for checking tablet_persist_trigger_ is 5s const int64_t ObTabletGCService::GC_CHECK_INTERVAL = 5 * 1000 * 1000L; -// The time interval for checking deleted tablet trigger is 5s -const int64_t ObTabletGCService::GC_CHECK_DELETE_INTERVAL = 30 * 1000 * 1000L; - // The time interval for gc tablet and persist tablet whether the tablet_persist_trigger_ is 24 * 720 * 5s = 1d const int64_t ObTabletGCService::GLOBAL_GC_CHECK_INTERVAL_TIMES = 24 * 720; @@ -71,14 +71,14 @@ int ObTabletGCService::start() { int ret = OB_SUCCESS; timer_for_tablet_change_.set_run_wrapper(MTL_CTX()); - timer_for_tablet_gc_.set_run_wrapper(MTL_CTX()); + timer_for_tablet_shell_.set_run_wrapper(MTL_CTX()); if (OB_FAIL(timer_for_tablet_change_.init())) { STORAGE_LOG(ERROR, "fail to init timer", KR(ret)); - } else if (OB_FAIL(timer_for_tablet_gc_.init("TabletGcTimer", ObMemAttr(MTL_ID(), "TabletGcTimer")))) { + } else if (OB_FAIL(timer_for_tablet_shell_.init("TabletShellTimer", ObMemAttr(MTL_ID(), "TabShellTimer")))) { STORAGE_LOG(ERROR, "fail to init timer", KR(ret)); } else if (OB_FAIL(timer_for_tablet_change_.schedule(tablet_change_task_, GC_CHECK_INTERVAL, true))) { STORAGE_LOG(ERROR, "fail to schedule task", KR(ret)); - } else if (OB_FAIL(timer_for_tablet_gc_.schedule(tablet_gc_task_, GC_CHECK_DELETE_INTERVAL, true))) { + } else if (OB_FAIL(timer_for_tablet_shell_.schedule(tablet_shell_task_, ObEmptyShellTask::GC_EMPTY_TABLET_SHELL_INTERVAL, true))) { STORAGE_LOG(ERROR, "fail to schedule task", KR(ret)); } return ret; @@ -94,27 +94,27 @@ int ObTabletGCService::stop() STORAGE_LOG(INFO, "ObTabletGCService stoped"); } timer_for_tablet_change_.stop(); - timer_for_tablet_gc_.stop(); + timer_for_tablet_shell_.stop(); return ret; } void ObTabletGCService::wait() { timer_for_tablet_change_.wait(); - timer_for_tablet_gc_.wait(); + timer_for_tablet_shell_.wait(); } void ObTabletGCService::destroy() { is_inited_ = false; timer_for_tablet_change_.destroy(); - timer_for_tablet_gc_.destroy(); + timer_for_tablet_shell_.destroy(); } void ObTabletGCService::ObTabletChangeTask::runTimerTask() { STORAGE_LOG(INFO, "====== [tabletchange] timer task ======", K(GC_CHECK_INTERVAL)); - static int64_t times = 0; + RLOCAL_STATIC(int64_t, times) = 0; times = (times + 1) % GLOBAL_GC_CHECK_INTERVAL_TIMES; int ret = OB_SUCCESS; ObLSIterator *iter = NULL; @@ -144,60 +144,67 @@ void ObTabletGCService::ObTabletChangeTask::runTimerTask() STORAGE_LOG(WARN, "ls is NULL", KR(ret)); } else if (FALSE_IT(tablet_gc_handler = ls->get_tablet_gc_handler())) { } else if (tablet_gc_handler->check_stop()) { - STORAGE_LOG(INFO, "[tabletgc] tablet_gc_handler is offline", K(ls->get_ls_id())); + STORAGE_LOG(INFO, "[tabletchange] tablet_gc_handler is offline", K(ls->get_ls_id())); } else { uint8_t tablet_persist_trigger = tablet_gc_handler->get_tablet_persist_trigger_and_reset(); STORAGE_LOG(INFO, "[tabletchange] task check ls", K(ls->get_ls_id()), K(tablet_persist_trigger)); if (times == 0 || ObTabletGCHandler::is_set_tablet_persist_trigger(tablet_persist_trigger) || ObTabletGCHandler::is_tablet_gc_trigger(tablet_persist_trigger)) { + const bool only_persist = 0 != times && !ObTabletGCHandler::is_tablet_gc_trigger(tablet_persist_trigger); obsys::ObRLockGuard lock(tablet_gc_handler->wait_lock_); bool need_retry = false; - SCN checkpoint_scn; + SCN decided_scn; ObFreezer *freezer = ls->get_freezer(); common::ObTabletIDArray unpersist_tablet_ids; + common::ObSEArray deleted_tablets; const bool is_deleted = true; - const bool only_deleted = true; - bool is_gc = false; if (OB_ISNULL(freezer)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "freezer should not null", K(ls->get_ls_id()), KR(ret)); } // 1. get minor merge point - else if (OB_FAIL(freezer->decide_max_decided_scn(checkpoint_scn))) { + else if (OB_FAIL(ls->get_max_decided_scn(decided_scn))) { need_retry = true; STORAGE_LOG(WARN, "decide_max_decided_scn failed", KR(ret), K(freezer->get_ls_id())); - } else if (!checkpoint_scn.is_valid() - || SCN::min_scn() == checkpoint_scn - || checkpoint_scn < ls->get_tablet_change_checkpoint_scn()) { + } else if (!decided_scn.is_valid() + || SCN::min_scn() == decided_scn + || decided_scn < ls->get_tablet_change_checkpoint_scn()) { STORAGE_LOG(INFO, "no any log callback and no need to update clog checkpoint", - K(freezer->get_ls_id()), K(checkpoint_scn), KPC(ls), K(ls->get_ls_meta())); + K(freezer->get_ls_id()), K(decided_scn), KPC(ls), K(ls->get_ls_meta())); } - // 2. get gc tablet. tablet_change_ts cannot update when gc tablet failed. - else if (OB_FAIL(tablet_gc_handler->gc_tablets(is_gc, need_retry))) { - need_retry = true; - STORAGE_LOG(WARN, "failed to gc tablet", KR(ret)); - } - // 3. get unpersist_tablet_ids - else if (OB_FAIL(tablet_gc_handler->get_unpersist_tablet_ids(unpersist_tablet_ids, need_retry, !only_deleted))) { + // 2. get gc tablet and get unpersist_tablet_ids + else if (OB_FAIL(tablet_gc_handler->get_unpersist_tablet_ids(deleted_tablets, unpersist_tablet_ids, only_persist, need_retry, decided_scn))) { need_retry = true; STORAGE_LOG(WARN, "failed to get_unpersist_tablet_ids", KPC(ls), KR(ret)); } - // 4. flush unpersit_tablet_ids - else if (OB_FAIL(tablet_gc_handler->flush_unpersist_tablet_ids(unpersist_tablet_ids, checkpoint_scn))) { + // 3. flush unpersit_tablet_ids + else if (OB_FAIL(tablet_gc_handler->flush_unpersist_tablet_ids(unpersist_tablet_ids, decided_scn))) { need_retry = true; STORAGE_LOG(WARN, "failed to flush_unpersist_tablet_ids", KPC(ls), KR(ret), K(unpersist_tablet_ids)); } - // 5. update tablet_change_checkpoint in log meta - else if (checkpoint_scn > ls->get_tablet_change_checkpoint_scn() - && OB_FAIL(ls->set_tablet_change_checkpoint_scn(checkpoint_scn))) { + // 4. update tablet_change_checkpoint in log meta + else if (decided_scn > ls->get_tablet_change_checkpoint_scn() + && OB_FAIL(tablet_gc_handler->set_tablet_change_checkpoint_scn(decided_scn))) { need_retry = true; - STORAGE_LOG(WARN, "failed to set_tablet_change_checkpoint_scn", KPC(ls), KR(ret), K(checkpoint_scn)); + STORAGE_LOG(WARN, "failed to set_tablet_change_checkpoint_scn", KPC(ls), KR(ret), K(decided_scn)); } - STORAGE_LOG(INFO, "[tabletchange] tablet in a ls persist and gc process end", KR(ret), KPC(ls), K(checkpoint_scn), K(unpersist_tablet_ids)); + // 5. set ls transfer scn + else if (!only_persist && OB_FAIL(tablet_gc_handler->set_ls_transfer_scn(deleted_tablets))) { + need_retry = true; + STORAGE_LOG(WARN, "failed to set ls transfer scn", KPC(ls), KR(ret), K(decided_scn)); + } + // 6. check and gc deleted_tablets + else if (!only_persist) { + if (!deleted_tablets.empty() && OB_FAIL(tablet_gc_handler->gc_tablets(deleted_tablets))) { + need_retry = true; + STORAGE_LOG(WARN, "failed to gc tablet", KR(ret)); + } + } + STORAGE_LOG(INFO, "[tabletchange] tablet in a ls persist and gc process end", KR(ret), KPC(ls), K(decided_scn), K(unpersist_tablet_ids)); if (need_retry) { - STORAGE_LOG(INFO, "[tabletchange] persist or gc error, need try", KR(ret), KPC(ls), K(checkpoint_scn), K(tablet_persist_trigger)); + STORAGE_LOG(INFO, "[tabletchange] persist or gc error, need try", KR(ret), KPC(ls), K(decided_scn), K(tablet_persist_trigger)); if (ObTabletGCHandler::is_set_tablet_persist_trigger(tablet_persist_trigger)) { tablet_gc_handler->set_tablet_persist_trigger(); } @@ -219,74 +226,6 @@ void ObTabletGCService::ObTabletChangeTask::runTimerTask() } } -void ObTabletGCService::ObTabletGCTask::runTimerTask() -{ - STORAGE_LOG(INFO, "====== [tabletgc] timer task ======", K(GC_CHECK_INTERVAL)); - int ret = OB_SUCCESS; - ObLSIterator *iter = NULL; - common::ObSharedGuard guard; - ObLSService *ls_svr = MTL(ObLSService*); - bool skip_gc_task = false; - - if (OB_ISNULL(ls_svr)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "mtl ObLSService should not be null", KR(ret)); - } else if (OB_UNLIKELY(skip_gc_task)) { - // do nothing - } else if (OB_FAIL(ls_svr->get_ls_iter(guard, ObLSGetMod::TXSTORAGE_MOD))) { - STORAGE_LOG(WARN, "get log stream iter failed", KR(ret)); - } else if (OB_ISNULL(iter = guard.get_ptr())) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "iter is NULL", KR(ret)); - } else { - ObLS *ls = NULL; - int ls_cnt = 0; - for (; OB_SUCC(iter->get_next(ls)); ++ls_cnt) { - ObTabletGCHandler *tablet_gc_handler = NULL; - if (OB_ISNULL(ls)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "ls is NULL", KR(ret)); - } else if (FALSE_IT(tablet_gc_handler = ls->get_tablet_gc_handler())) { - } else if (tablet_gc_handler->check_stop()) { - STORAGE_LOG(INFO, "[tabletgc] tablet_gc_handler is stop", K(ls->get_ls_id())); - } else { - bool is_tablet_gc = tablet_gc_handler->is_tablet_gc_trigger_and_reset(); - STORAGE_LOG(INFO, "[tabletgc] task check ls", K(ls->get_ls_id()), K(is_tablet_gc)); - if (is_tablet_gc) { - obsys::ObRLockGuard lock(tablet_gc_handler->wait_lock_); - bool need_retry = false; - SCN checkpoint_scn; - const bool is_deleted = true; - const bool only_deleted = true; - bool is_gc = false; - - if (OB_FAIL(tablet_gc_handler->gc_tablets(is_gc, need_retry))) { - need_retry = true; - STORAGE_LOG(WARN, "failed to gc tablet", KR(ret)); - } else if (is_gc) { - tablet_gc_handler->set_tablet_persist_trigger(); - } - STORAGE_LOG(INFO, "[tabletgc] tablet in a ls gc process end", KR(ret), KPC(ls), K(checkpoint_scn)); - if (need_retry) { - STORAGE_LOG(INFO, "[tabletgc] persist or gc error, need try", KR(ret), KPC(ls), K(checkpoint_scn)); - if (is_tablet_gc) { - tablet_gc_handler->set_tablet_gc_trigger(); - } - } - } - } - } - if (ret == OB_ITER_END) { - ret = OB_SUCCESS; - if (ls_cnt > 0) { - STORAGE_LOG(INFO, "[tabletgc] succeed to gc_tablet", KR(ret), K(ls_cnt)); - } else { - STORAGE_LOG(INFO, "[tabletgc] no logstream", KR(ret), K(ls_cnt)); - } - } - } -} - int ObTabletGCHandler::init(ObLS *ls) { int ret = OB_SUCCESS; @@ -314,6 +253,7 @@ void ObTabletGCHandler::set_tablet_persist_trigger() break; } } while (ATOMIC_CAS(&tablet_persist_trigger_, old_v, new_v) != old_v); + STORAGE_LOG(INFO, "set_tablet_persist_trigger", KPC(this)); } void ObTabletGCHandler::set_tablet_gc_trigger() @@ -327,6 +267,7 @@ void ObTabletGCHandler::set_tablet_gc_trigger() break; } } while (ATOMIC_CAS(&tablet_persist_trigger_, old_v, new_v) != old_v); + STORAGE_LOG(INFO, "set_tablet_gc_trigger", KPC(this)); } uint8_t ObTabletGCHandler::get_tablet_persist_trigger_and_reset() @@ -342,41 +283,33 @@ uint8_t ObTabletGCHandler::get_tablet_persist_trigger_and_reset() return old_v; } -int ObTabletGCHandler::check_tablet_gc_for_standby_(bool &cannot_gc, ObTabletHandle &tablet_handle) +void ObTabletGCHandler::disable_gc() { - int ret = OB_SUCCESS; - cannot_gc = false; - SCN readable_scn = SCN::base_scn(); - ObTablet *tablet = NULL; - rootserver::ObTenantInfoLoader *info = MTL(rootserver::ObTenantInfoLoader*); - ObTabletTxMultiSourceDataUnit tx_data; - if (MTL_IS_PRIMARY_TENANT()) { - } else if (OB_ISNULL(info)) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "mtl ObTenantRecoveryReportor should not be null", KR(ret)); - } else if (OB_FAIL(info->get_readable_scn(readable_scn))) { - LOG_WARN("fail to get readable_scn", KPC(info)); - } else if (!readable_scn.is_valid()) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "readable scn is invalid", KR(ret), KPC(this->ls_), K(readable_scn)); - } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "tablet is NULL", KR(ret), KPC(this->ls_), K(tablet_handle)); - } else if (OB_FAIL(tablet->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), KPC(this->ls_), KPC(tablet)); - } else if (tx_data.tx_scn_ >= readable_scn) { - LOG_INFO("[tabletgc] tablet cannot gc for standby", K(ret), KPC(this->ls_), KPC(tablet), K(tx_data), K(readable_scn)); - cannot_gc = true; - } - return ret; + const int64_t cost_time = 10 * 1000 * 1000; //10s + common::ObTimeGuard timeguard("disable gc", cost_time); + timeguard.click(); + gc_lock_.lock(); + timeguard.click(); } -int ObTabletGCHandler::check_tablet_gc_(bool &cannot_gc, ObTabletHandle &tablet_handle) +void ObTabletGCHandler::enable_gc() +{ + gc_lock_.unlock(); +} + +int ObTabletGCHandler::set_tablet_change_checkpoint_scn(const share::SCN &scn) { int ret = OB_SUCCESS; - cannot_gc = false; - if (OB_FAIL(check_tablet_gc_for_standby_(cannot_gc, tablet_handle))) { - LOG_WARN("failed to check_tablet_gc_for_standby", K(ret), KPC(this->ls_)); + if (OB_FAIL(gc_lock_.trylock())) { + ret = OB_EAGAIN; + LOG_WARN("try lock failed, please retry later", K(ret)); + } else { + if (OB_FAIL(ls_->set_tablet_change_checkpoint_scn(scn))) { + LOG_WARN("fail to set tablet_change_checkpoint_scn", K(ret), K(scn)); + } else { + // do nothing + } + gc_lock_.unlock(); } return ret; } @@ -395,13 +328,103 @@ bool ObTabletGCHandler::is_tablet_gc_trigger_and_reset() return 0 != (old_v & 2); } -int ObTabletGCHandler::get_unpersist_tablet_ids(common::ObTabletIDArray &unpersist_tablet_ids, - bool &need_retry, - bool only_deleted /* = false */) +int ObTabletGCHandler::check_tablet_need_persist_( + ObTabletHandle &tablet_handle, + bool &need_persist, + bool &need_retry, + const SCN &decided_scn) { - int64_t ret = OB_SUCCESS; - ObLSTabletIterator tablet_iter(ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US); - ObTabletTxMultiSourceDataUnit tx_data; + int ret = OB_SUCCESS; + need_persist = false; + ObTablet *tablet = NULL; + bool is_locked = false; + SCN rec_scn; + if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "tablet is NULL", KR(ret)); + } else if (OB_FAIL(tablet->is_locked_by_others(is_locked))) { + LOG_WARN("failed to get is locked", KR(ret), KPC(tablet)); + } else if (is_locked) { + LOG_INFO("tablet_status is changing", KR(ret), KPC(tablet)); + need_retry = true; + } + + if (OB_FAIL(ret)) { + } else if (tablet->is_empty_shell()) { + } else if (OB_FAIL(tablet->get_mds_table_rec_log_scn(rec_scn))) { + STORAGE_LOG(WARN, "failed to get_mds_table_rec_log_scn", KR(ret), KPC(tablet)); + } else if (!rec_scn.is_valid()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "rec_scn is invalid", KR(ret), KPC(tablet)); + } else if (rec_scn > decided_scn) { + // todo check tablet_status and binding_info scn to mds_checkpoint_scn + } else { + need_persist = true; + STORAGE_LOG(INFO, "[tabletgc] get tablet for persist", K(rec_scn), KPC(tablet)); + } + + return ret; +} + +int ObTabletGCHandler::check_tablet_need_gc_( + ObTabletHandle &tablet_handle, + bool &need_gc, + bool &need_retry, + const SCN &decided_scn) +{ + int ret = OB_SUCCESS; + need_gc = false; + ObTablet *tablet = NULL; + if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "tablet is NULL", KR(ret)); + // for tablet shell + } else if (tablet->is_empty_shell()) { + SCN deleted_commit_scn = tablet->get_tablet_meta().mds_checkpoint_scn_; + if (!deleted_commit_scn.is_valid()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "deleted_commit_scn is unvalid", KR(ret), KPC(tablet)); + } else if (deleted_commit_scn > decided_scn) { + need_retry = true; + LOG_INFO("tablet cannot be gc, as deleted_commit_scn_ is more than decided_scn, retry", KR(ret), KPC(tablet), K(decided_scn)); + } else { + LOG_INFO("tablet is shell, need gc", KR(ret), KPC(tablet), K(decided_scn)); + need_gc = true; + } + } else { + // for create tablet abort + ObTabletCreateDeleteMdsUserData data; + bool mds_table_not_null = false; + bool is_finish = false; + if (OB_FAIL(tablet->check_mds_written(mds_table_not_null))) { + STORAGE_LOG(WARN, "failed to check mds written", KR(ret), KPC(tablet)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_latest_tablet_status(data, is_finish))) { + if (OB_EMPTY_RESULT == ret) { + ret = OB_SUCCESS; + if (mds_table_not_null) { + need_gc = true; + STORAGE_LOG(INFO, "create tablet abort, need gc", KPC(tablet)); + } else { + STORAGE_LOG(INFO, "tablet_status is not commit", KR(ret), KPC(tablet)); + } + } else { + STORAGE_LOG(WARN, "failed to get CreateDeleteMdsUserData", KR(ret), KPC(tablet)); + } + } else if (!is_finish) { + need_retry = true; + } + } + return ret; +} + +int ObTabletGCHandler::get_unpersist_tablet_ids(common::ObIArray &deleted_tablets, + common::ObTabletIDArray &unpersist_tablet_ids, + const bool only_persist, + bool &need_retry, + const SCN &decided_scn) +{ + int ret = OB_SUCCESS; + ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); if (IS_NOT_INIT) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "tablet gc handle is not inited", KR(ret)); @@ -409,8 +432,10 @@ int ObTabletGCHandler::get_unpersist_tablet_ids(common::ObTabletIDArray &unpersi STORAGE_LOG(WARN, "failed to build ls tablet iter", KR(ret), KPC(this)); } else { ObTabletHandle tablet_handle; + ObTablet *tablet = NULL; + bool need_gc = false; + bool need_persist = false; while (OB_SUCC(ret)) { - tx_data.reset(); if (check_stop()) { ret = OB_EAGAIN; STORAGE_LOG(INFO, "tablet gc handler stop", KR(ret), KPC(this), K(tablet_handle), KPC(ls_), K(ls_->get_ls_meta())); @@ -424,63 +449,83 @@ int ObTabletGCHandler::get_unpersist_tablet_ids(common::ObTabletIDArray &unpersi } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "invalid tablet handle", KR(ret), KPC(this), K(tablet_handle)); - } else if (tablet_handle.get_obj()->is_ls_inner_tablet()) { + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "tablet is NULL", KR(ret)); + } else if (tablet->is_ls_inner_tablet()) { // skip ls inner tablet + continue; + } + + if (OB_FAIL(ret)) { + } else if (only_persist) { + } else if (OB_FAIL(check_tablet_need_gc_(tablet_handle, need_gc, need_retry, decided_scn))) { + STORAGE_LOG(WARN, "failed to check_tablet_need_gc_", KR(ret), KPC(tablet)); + } else if (!need_gc) { + } else if (OB_FAIL(deleted_tablets.push_back(tablet_handle))) { + STORAGE_LOG(WARN, "failed to push_back", KR(ret)); } else { - const ObTabletMeta &tablet_meta = tablet_handle.get_obj()->get_tablet_meta(); - const ObTabletID &tablet_id = tablet_meta.tablet_id_; - SCN tmp_scn; - if (OB_FAIL(tablet_handle.get_obj()->get_tx_data(tx_data))) { - LOG_WARN("failed to get tx data", K(ret), K(tablet_id)); - } else if (only_deleted) { - bool cannot_gc = false; - if (OB_FAIL(check_tablet_gc_(cannot_gc, tablet_handle))) { - LOG_WARN("failed to check tablet gc", KR(ret), KPC(tablet_handle.get_obj())); - } else if (cannot_gc) { - need_retry = true; - } else if (ObTabletStatus::DELETED == tx_data.tablet_status_) { - STORAGE_LOG(INFO, "[tabletgc] get tx_data for gc", K(tx_data), K(tablet_meta)); - if (OB_FAIL(unpersist_tablet_ids.push_back(tablet_id))) { - STORAGE_LOG(WARN, "failed to push_back deleted tablet", KR(ret)); - } - } - } else if (tx_data.tx_scn_ > tablet_meta.clog_checkpoint_scn_) { - STORAGE_LOG(INFO, "[tabletgc] get tx_data for persist", K(tx_data), K(tablet_meta)); - if (OB_FAIL(unpersist_tablet_ids.push_back(tablet_id))) { - STORAGE_LOG(WARN, "failed to push_back", KR(ret)); - } - } + STORAGE_LOG(INFO, "[tabletgc] get tablet for gc", KPC(tablet), K(decided_scn)); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(check_tablet_need_persist_(tablet_handle, need_persist, need_retry, decided_scn))) { + STORAGE_LOG(WARN, "failed to check_tablet_need_persist_", KR(ret), KPC(tablet)); + } else if (!need_persist) { + } else if (OB_FAIL(unpersist_tablet_ids.push_back(tablet->get_tablet_meta().tablet_id_))) { + STORAGE_LOG(WARN, "failed to push_back", KR(ret)); + } else { + STORAGE_LOG(INFO, "[tabletgc] get tablet for persist", KPC(tablet), K(decided_scn)); } } } - STORAGE_LOG(INFO, "[tabletgc] get unpersist_tablet_ids", KR(ret), K(unpersist_tablet_ids), K(only_deleted)); + STORAGE_LOG(INFO, "[tabletgc] get unpersist_tablet_ids", KR(ret), K(deleted_tablets.count()), K(unpersist_tablet_ids.count()), K(decided_scn)); return ret; } int ObTabletGCHandler::flush_unpersist_tablet_ids(const common::ObTabletIDArray &unpersist_tablet_ids, - const SCN checkpoint_scn) + const SCN &decided_scn) { int ret = OB_SUCCESS; if (IS_NOT_INIT) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "tablet gc handle is not inited", KR(ret)); - } else if (OB_FAIL(freeze_unpersist_tablet_ids(unpersist_tablet_ids))) { + } else if (OB_FAIL(freeze_unpersist_tablet_ids(unpersist_tablet_ids, decided_scn))) { STORAGE_LOG(WARN, "fail to freeze unpersist tablet", KR(ret), KPC(this->ls_), K(unpersist_tablet_ids)); - } else if (OB_FAIL(wait_unpersist_tablet_ids_flushed(unpersist_tablet_ids, checkpoint_scn))) { + } else if (OB_FAIL(wait_unpersist_tablet_ids_flushed(unpersist_tablet_ids, decided_scn))) { STORAGE_LOG(WARN, "fail to wait unpersist tablet ids flushed", KR(ret), KPC(this->ls_), K(unpersist_tablet_ids)); } return ret; } -int ObTabletGCHandler::freeze_unpersist_tablet_ids(const common::ObTabletIDArray &unpersist_tablet_ids) +int ObTabletGCHandler::freeze_unpersist_tablet_ids(const common::ObTabletIDArray &unpersist_tablet_ids, + const SCN &decided_scn) { int ret = OB_SUCCESS; const int64_t start_ts = ObTimeUtility::fast_current_time(); if (IS_NOT_INIT) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "tablet gc handle is not inited", KR(ret)); - } else if (OB_FAIL(ls_->batch_tablet_freeze(unpersist_tablet_ids, true/*is_sync*/))){ - STORAGE_LOG(WARN, "fail to batch freeze tablet", KR(ret), KPC(this->ls_), K(unpersist_tablet_ids)); + } else { + DEBUG_SYNC(BEFORE_TABLET_MDS_FLUSH); + // freeze all tablets + for (int64_t i = 0; i < unpersist_tablet_ids.count() && OB_SUCC(ret); i++) { + if (!unpersist_tablet_ids.at(i).is_valid()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "invalid tablet_id", KR(ret), KPC(this->ls_), K(unpersist_tablet_ids)); + } else { + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + if (OB_FAIL(ls_->get_tablet_svr()->get_tablet(unpersist_tablet_ids.at(i), tablet_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + STORAGE_LOG(WARN, "fail to get tablet", KR(ret), K(i), KPC(this->ls_), K(unpersist_tablet_ids)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "tablet is NULL", KR(ret), K(i), KPC(this->ls_), K(unpersist_tablet_ids)); + } else if (OB_FAIL(tablet->mds_table_flush(decided_scn))) { + STORAGE_LOG(WARN, "failed to persist mds table", KR(ret), KPC(tablet), K(this->ls_), K(unpersist_tablet_ids.at(i))); + } + } + } } const int64_t end_ts = ObTimeUtility::fast_current_time(); const int64_t cost = end_ts - start_ts; @@ -489,7 +534,7 @@ int ObTabletGCHandler::freeze_unpersist_tablet_ids(const common::ObTabletIDArray } int ObTabletGCHandler::wait_unpersist_tablet_ids_flushed(const common::ObTabletIDArray &unpersist_tablet_ids, - const SCN checkpoint_scn) + const SCN &decided_scn) { int ret = OB_SUCCESS; const int64_t start_ts = ObTimeUtility::fast_current_time(); @@ -508,23 +553,26 @@ int ObTabletGCHandler::wait_unpersist_tablet_ids_flushed(const common::ObTabletI while (unpersist_tablet_ids.count() > i && OB_SUCC(ret)) { ObTabletHandle handle; ObTablet *tablet = nullptr; - SCN rec_log_scn = SCN::min_scn(); + SCN rec_scn = SCN::min_scn(); if (check_stop()) { ret = OB_EAGAIN; STORAGE_LOG(INFO, "tablet gc handler stop", KR(ret), KPC(this), KPC(ls_), K(ls_->get_ls_meta())); - } else if (OB_FAIL(ls_->get_tablet_svr()->get_tablet(unpersist_tablet_ids.at(i), handle, ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US))) { + } else if (OB_FAIL(ls_->get_tablet_svr()->get_tablet(unpersist_tablet_ids.at(i), handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { STORAGE_LOG(WARN, "fail to get tablet", KR(ret), K(i), KPC(this->ls_), K(unpersist_tablet_ids)); } else if (OB_ISNULL(tablet = handle.get_obj())) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "tablet is NULL", KR(ret), K(i), KPC(this->ls_), K(unpersist_tablet_ids)); - } else if (OB_FAIL(tablet->get_rec_log_scn(rec_log_scn))) { - STORAGE_LOG(WARN, "fail to get rec log ts", KR(ret), K(handle)); - } else if (rec_log_scn > checkpoint_scn) { - STORAGE_LOG(INFO, "[tabletgc] finish tablet flush", K(rec_log_scn), K(checkpoint_scn), + } else if (OB_FAIL(tablet->get_mds_table_rec_log_scn(rec_scn))) { + STORAGE_LOG(WARN, "fail to get rec log scn", KR(ret), K(handle)); + } + + if (OB_FAIL(ret)) { + } else if (rec_scn > decided_scn) { + STORAGE_LOG(INFO, "[tabletgc] finish tablet flush", K(rec_scn), K(decided_scn), K(retry_times), K(i), K(ls_->get_ls_id()), KPC(tablet)); i++; } else { - STORAGE_LOG(INFO, "[tabletgc] wait tablet flush", K(rec_log_scn), K(checkpoint_scn), + STORAGE_LOG(INFO, "[tabletgc] wait tablet flush", K(rec_scn), K(decided_scn), K(retry_times), K(i), K(ls_->get_ls_id()), KPC(tablet)); break; } @@ -544,26 +592,100 @@ int ObTabletGCHandler::wait_unpersist_tablet_ids_flushed(const common::ObTabletI return ret; } -int ObTabletGCHandler::gc_tablets(bool &is_gc, bool &need_retry) +int ObTabletGCHandler::gc_tablets(const common::ObIArray &deleted_tablets) { int ret = OB_SUCCESS; - obsys::ObWLockGuard lock(gc_lock_); - const bool only_deleted = true; - common::ObTabletIDArray deleted_tablet_ids; - is_gc = false; + if (IS_NOT_INIT) { ret = OB_NOT_INIT; STORAGE_LOG(WARN, "tablet gc handler is not inited", KR(ret)); - } else if (check_stop()) { - ret = OB_EAGAIN; - STORAGE_LOG(INFO, "tablet gc handler stop", KR(ret), KPC(this), KPC(ls_), K(ls_->get_ls_meta())); - } else if (OB_FAIL(get_unpersist_tablet_ids(deleted_tablet_ids, need_retry, only_deleted))) { - STORAGE_LOG(WARN, "failed to get_unpersist_tablet_ids", KPC(ls_), KR(ret)); - } else if (!deleted_tablet_ids.empty() && OB_FAIL(ls_->get_tablet_svr()->remove_tablets(deleted_tablet_ids))) { - STORAGE_LOG(WARN, "failed to remove tablets", K(ret), K(deleted_tablet_ids)); } else { - is_gc = !deleted_tablet_ids.empty(); - STORAGE_LOG(INFO, "gc tablet finish", K(ret), K(deleted_tablet_ids)); + DEBUG_SYNC(BEFORE_TABLET_GC); + + bool need_retry = false; + for (int64_t i = 0; OB_SUCC(ret) && i < deleted_tablets.count(); ++i) { + const ObTabletHandle &tablet_handle = deleted_tablets.at(i); + if (check_stop()) { + ret = OB_EAGAIN; + STORAGE_LOG(INFO, "tablet gc handler stop", KR(ret), KPC(this), KPC(ls_), K(ls_->get_ls_meta())); + } else if (OB_FAIL(ls_->get_tablet_svr()->remove_tablet(tablet_handle))) { + if (OB_EAGAIN == ret) { + need_retry = true; + ret = OB_SUCCESS; + } else { + STORAGE_LOG(WARN, "failed to remove tablet", K(ret), K(tablet_handle)); + } + } else { + STORAGE_LOG(INFO, "gc tablet finish", K(ret), + "ls_id", tablet_handle.get_obj()->get_tablet_meta().ls_id_, + "tablet_id", tablet_handle.get_obj()->get_tablet_meta().tablet_id_); + } + } + + if (OB_FAIL(ret)) { + } else if (need_retry) { + ret = OB_EAGAIN; + } + } + return ret; +} + + +int ObTabletGCHandler::get_max_tablet_transfer_scn( + const common::ObIArray &deleted_tablets, + share::SCN &transfer_scn) +{ + int ret = OB_SUCCESS; + const bool need_initial_state = false; + ObHALSTabletIDIterator iter(ls_->get_ls_id(), need_initial_state); + share::SCN max_transfer_scn = share::SCN::min_scn(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "tablet gc handler is not inited", KR(ret)); + } else { + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + common::ObTabletID tablet_id; + ObTabletMapKey key; + key.ls_id_ = ls_->get_ls_id(); + ObTabletCreateDeleteMdsUserData mds_data; + ObTabletHandle tablet_handle; + const WashTabletPriority priority = WashTabletPriority::WTP_LOW; + for (int i = 0; OB_SUCC(ret) && i < deleted_tablets.count(); i++) { + mds_data.reset(); + const ObTabletHandle &tablet_handle = deleted_tablets.at(i); + if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_tablet_status( + share::SCN::max_scn(), mds_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + if (OB_EMPTY_RESULT == ret) { + ret = OB_SUCCESS; + LOG_INFO("create tablet abort, need gc", K(tablet_id)); + continue; + } else { + LOG_WARN("failed to get mds table", KR(ret), K(tablet_handle)); + } + } else if (share::SCN::invalid_scn() == mds_data.transfer_scn_) { + // do nothing + } else { + transfer_scn = mds_data.transfer_scn_; + max_transfer_scn = MAX(transfer_scn, max_transfer_scn); + } + } + if (OB_SUCC(ret)) { + transfer_scn = max_transfer_scn; + } + } + return ret; +} + +int ObTabletGCHandler::set_ls_transfer_scn(const common::ObIArray &deleted_tablets) +{ + int ret = OB_SUCCESS; + share::SCN tablet_max_transfer_scn; + if (0 == deleted_tablets.count()) { + // do nothing + } else if (OB_FAIL(get_max_tablet_transfer_scn(deleted_tablets, tablet_max_transfer_scn))) { + STORAGE_LOG(WARN, "failed to get max tablet transfer scn", K(ret)); + } else if (OB_FAIL(ls_->inc_update_transfer_scn(tablet_max_transfer_scn))) { + LOG_WARN("failed to set transfer scn", K(ret)); } return ret; } @@ -575,7 +697,12 @@ int ObTabletGCHandler::offline() if (!is_finish()) { ret = OB_EAGAIN; STORAGE_LOG(INFO, "tablet gc handler not finish, retry", KR(ret), KPC(this), KPC(ls_), K(ls_->get_ls_meta())); + } else if (OB_FAIL(gc_lock_.trylock())) { + // make sure 'gc_lock_' is not using. + ret = OB_EAGAIN; + LOG_WARN("tablet gc handler not finish, retry", K(ret)); } else { + gc_lock_.unlock(); STORAGE_LOG(INFO, "tablet gc handler offline", KPC(this), KPC(ls_), K(ls_->get_ls_meta())); } return ret; @@ -584,6 +711,7 @@ int ObTabletGCHandler::offline() void ObTabletGCHandler::online() { set_tablet_persist_trigger(); + set_tablet_gc_trigger(); set_start(); STORAGE_LOG(INFO, "tablet gc handler online", KPC(this), KPC(ls_), K(ls_->get_ls_meta())); } diff --git a/src/storage/tx_storage/ob_tablet_gc_service.h b/src/storage/tx_storage/ob_tablet_gc_service.h old mode 100644 new mode 100755 index 850ccbebc..823bd4e2b --- a/src/storage/tx_storage/ob_tablet_gc_service.h +++ b/src/storage/tx_storage/ob_tablet_gc_service.h @@ -18,6 +18,9 @@ #include "common/ob_tablet_id.h" #include "share/scn.h" #include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/tablet/ob_tablet_multi_source_data.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/tx_storage/ob_empty_shell_task.h" namespace oceanbase { @@ -26,14 +29,15 @@ namespace storage class ObLS; namespace checkpoint { - +#define TABLET_PERSIST 0x01 /* tablet persist trigger */ +#define TABLET_GC 0x02 /* tablet gc trigger */ class ObTabletGCHandler { friend class ObTabletGCService; public: ObTabletGCHandler() : ls_(NULL), - tablet_persist_trigger_(0), + tablet_persist_trigger_(TABLET_PERSIST | TABLET_GC), update_enabled_(true), is_inited_(false) {} @@ -48,22 +52,38 @@ public: uint8_t &get_tablet_persist_trigger() { return tablet_persist_trigger_; } static bool is_set_tablet_persist_trigger(uint8_t tablet_persist_trigger) - { return 0 != (tablet_persist_trigger & 1); } + { return 0 != (tablet_persist_trigger & TABLET_PERSIST); } static bool is_tablet_gc_trigger(uint8_t tablet_persist_trigger) - { return 0 != (tablet_persist_trigger & 2); } + { return 0 != (tablet_persist_trigger & TABLET_GC); } bool is_tablet_gc_trigger_and_reset(); - int check_tablet_gc_for_standby_(bool &cannot_gc, ObTabletHandle &tablet_handle); - int check_tablet_gc_(bool &cannot_gc, ObTabletHandle &tablet_handle); + void set_tablet_persist_trigger(); void set_tablet_gc_trigger(); uint8_t get_tablet_persist_trigger_and_reset(); - int get_unpersist_tablet_ids(common::ObTabletIDArray &unpersist_create_tablet_ids, - bool &need_retry, - bool only_deleted = false); + int check_tablet_need_persist_( + ObTabletHandle &tablet_handle, + bool &need_persist, + bool &need_retry, + const share::SCN &decided_scn); + int check_tablet_need_gc_( + ObTabletHandle &tablet_handle, + bool &need_gc, + bool &need_retry, + const share::SCN &decided_scn); + int get_unpersist_tablet_ids(common::ObIArray &deleted_tablets, + common::ObTabletIDArray &unpersist_tablet_ids, + const bool only_persist, + bool &need_retry, + const share::SCN &decided_scn); int flush_unpersist_tablet_ids(const common::ObTabletIDArray &unpersist_tablet_ids, - const share::SCN checkpoint_scn); - int gc_tablets(bool &is_gc, bool &need_retry); + const share::SCN &decided_scn); + int get_max_tablet_transfer_scn(const common::ObIArray &deleted_tablets, share::SCN &transfer_scn); + int set_ls_transfer_scn(const common::ObIArray &deleted_tablets); + int gc_tablets(const common::ObIArray &deleted_tablets); bool check_stop() { return ATOMIC_LOAD(&update_enabled_) == false; } + void disable_gc(); + void enable_gc(); + int set_tablet_change_checkpoint_scn(const share::SCN &scn); int offline(); void online(); TO_STRING_KV(K_(tablet_persist_trigger), K_(is_inited)); @@ -71,16 +91,17 @@ public: private: static const int64_t FLUSH_CHECK_MAX_TIMES; static const int64_t FLUSH_CHECK_INTERVAL; - int freeze_unpersist_tablet_ids(const common::ObTabletIDArray &unpersist_tablet_ids); + int freeze_unpersist_tablet_ids(const common::ObTabletIDArray &unpersist_tablet_ids, + const share::SCN &decided_scn); int wait_unpersist_tablet_ids_flushed(const common::ObTabletIDArray &unpersist_tablet_ids, - const share::SCN checkpoint_scn); + const share::SCN &decided_scn); bool is_finish() { obsys::ObWLockGuard lock(wait_lock_, false); return lock.acquired(); } void set_stop() { ATOMIC_STORE(&update_enabled_, false); } void set_start() { ATOMIC_STORE(&update_enabled_, true); } public: obsys::ObRWLock wait_lock_; - obsys::ObRWLock gc_lock_; + lib::ObMutex gc_lock_; private: storage::ObLS *ls_; @@ -95,9 +116,9 @@ public: ObTabletGCService() : is_inited_(false), timer_for_tablet_change_(), - timer_for_tablet_gc_(), tablet_change_task_(*this), - tablet_gc_task_(*this) + timer_for_tablet_shell_(), + tablet_shell_task_(*this) {} static int mtl_init(ObTabletGCService *&m); @@ -127,22 +148,11 @@ private: ObTabletGCService &tablet_gc_service_; }; - class ObTabletGCTask : public common::ObTimerTask - { - public: - ObTabletGCTask(ObTabletGCService &tablet_gc_service) - : tablet_gc_service_(tablet_gc_service) - {} - virtual ~ObTabletGCTask() {} - - virtual void runTimerTask(); - private: - ObTabletGCService &tablet_gc_service_; - }; common::ObTimer timer_for_tablet_change_; - common::ObTimer timer_for_tablet_gc_; ObTabletChangeTask tablet_change_task_; - ObTabletGCTask tablet_gc_task_; + + common::ObTimer timer_for_tablet_shell_; + ObEmptyShellTask tablet_shell_task_; }; } // checkpoint diff --git a/src/storage/tx_storage/ob_tenant_freezer.cpp b/src/storage/tx_storage/ob_tenant_freezer.cpp index f037380ff..de00e8dda 100755 --- a/src/storage/tx_storage/ob_tenant_freezer.cpp +++ b/src/storage/tx_storage/ob_tenant_freezer.cpp @@ -25,16 +25,19 @@ #include "storage/tx_storage/ob_ls_handle.h" #include "storage/tx_storage/ob_ls_service.h" #include "storage/tx_storage/ob_tenant_freezer.h" +#include "storage/multi_data_source/runtime_utility/mds_tenant_service.h" namespace oceanbase { using namespace share; namespace storage { - +using namespace mds; typedef ObMemstoreAllocatorMgr::TAllocator ObTenantMemstoreAllocator; +double ObTenantFreezer::MDS_TABLE_FREEZE_TRIGGER_TENANT_PERCENTAGE = 5; + ObTenantFreezer::ObTenantFreezer() : is_inited_(false), is_freezing_tx_data_(false), @@ -606,6 +609,38 @@ int ObTenantFreezer::check_and_freeze_tx_data_() return ret; } +// design document : +int ObTenantFreezer::check_and_freeze_mds_table_() +{ + int ret = OB_SUCCESS; + + if (REACH_TIME_INTERVAL(10 * 1000 * 1000 /*10 seconds*/)) { + bool trigger_flush = false; + int64_t total_memory = lib::get_tenant_memory_limit(tenant_info_.tenant_id_); + int64_t trigger_freeze_memory = total_memory * (ObTenantFreezer::MDS_TABLE_FREEZE_TRIGGER_TENANT_PERCENTAGE / 100); + ObTenantMdsAllocator &mds_allocator = MTL(ObTenantMdsService *)->get_allocator(); + int64_t hold_memory = mds_allocator.hold(); + + if (OB_UNLIKELY(0 == trigger_freeze_memory)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid trigger freeze memory", + K(trigger_freeze_memory), + K(total_memory), + K(ObTenantFreezer::MDS_TABLE_FREEZE_TRIGGER_TENANT_PERCENTAGE)); + } else if (hold_memory >= trigger_freeze_memory) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(post_mds_table_freeze_request_())) { + LOG_WARN("[TenantFreezer] fail to do mds table self freeze", K(tmp_ret)); + } + + LOG_INFO( + "[TenantFreezer] Trigger Mds Table Self Freeze. ", KR(tmp_ret), K(total_memory), K(trigger_freeze_memory)); + } + } + + return ret; +} + int ObTenantFreezer::check_and_do_freeze() { int ret = OB_SUCCESS; @@ -623,6 +658,8 @@ int ObTenantFreezer::check_and_do_freeze() LOG_WARN("[TenantFreezer] check and freeze normal data failed.", KR(ret)); } else if (OB_FAIL(check_and_freeze_tx_data_())) { LOG_WARN("[TenantFreezer] check and freeze tx data failed.", KR(ret)); + } else if (OB_FAIL(check_and_freeze_mds_table_())) { + LOG_WARN("[TenantFreezer] check and freeze mds table failed.", KR(ret)); } int64_t check_and_freeze_end_ts = ObTimeUtil::current_time(); @@ -1165,6 +1202,22 @@ int ObTenantFreezer::post_tx_data_freeze_request_() return ret; } +int ObTenantFreezer::post_mds_table_freeze_request_() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("tenant manager not init", KR(ret)); + } else { + ObTenantFreezeArg arg; + arg.freeze_type_ = ObFreezeType::MDS_TABLE_FREEZE; + if (OB_FAIL(rpc_proxy_.to(self_).by(tenant_info_.tenant_id_).post_freeze_request(arg, &tenant_mgr_cb_))) { + LOG_WARN("[TenantFreezer] fail to post freeze request", K(arg), KR(ret)); + } + } + return ret; +} + int ObTenantFreezer::rpc_callback() { int ret = OB_SUCCESS; diff --git a/src/storage/tx_storage/ob_tenant_freezer.h b/src/storage/tx_storage/ob_tenant_freezer.h index cd98e3bd2..12f9a5376 100755 --- a/src/storage/tx_storage/ob_tenant_freezer.h +++ b/src/storage/tx_storage/ob_tenant_freezer.h @@ -21,6 +21,7 @@ #include "share/ob_occam_timer.h" #include "share/ob_tenant_mgr.h" #include "storage/tx_storage/ob_tenant_freezer_rpc.h" +#include "storage/multi_data_source/runtime_utility/mds_factory.h" namespace oceanbase { @@ -39,6 +40,8 @@ class ObTenantFreezer { friend ObTenantTxDataFreezeGuard; friend class ObFreezer; + +public: const static int64_t TIME_WHEEL_PRECISION = 100_ms; const static int64_t SLOW_FREEZE_INTERVAL = 30_s; const static int FREEZE_TRIGGER_THREAD_NUM= 1; @@ -49,6 +52,8 @@ friend class ObFreezer; // replay use 1G/s const static int64_t REPLAY_RESERVE_MEMSTORE_BYTES = 100 * 1024 * 1024; // 100 MB const static int64_t MEMSTORE_USED_CACHE_REFRESH_INTERVAL = 100_ms; + static double MDS_TABLE_FREEZE_TRIGGER_TENANT_PERCENTAGE; + public: ObTenantFreezer(); ~ObTenantFreezer(); @@ -166,6 +171,7 @@ private: int retry_failed_major_freeze_(bool &triggered); int get_global_frozen_scn_(int64_t &frozen_version); int post_tx_data_freeze_request_(); + int post_mds_table_freeze_request_(); int get_tenant_mem_usage_(ObTenantFreezeCtx &ctx); static int get_freeze_trigger_(ObTenantFreezeCtx &ctx); static bool need_freeze_(const ObTenantFreezeCtx &ctx); @@ -179,6 +185,7 @@ private: int unset_tenant_slow_freeze_(); int check_and_freeze_normal_data_(ObTenantFreezeCtx &ctx); int check_and_freeze_tx_data_(); + int check_and_freeze_mds_table_(); int get_tenant_tx_data_mem_used_(int64_t &tenant_tx_data_mem_used); int get_ls_tx_data_mem_used_(ObLS *ls, int64_t &ls_tx_data_mem_used); private: diff --git a/src/storage/tx_storage/ob_tenant_freezer_rpc.cpp b/src/storage/tx_storage/ob_tenant_freezer_rpc.cpp index 435501f93..66c38fc06 100644 --- a/src/storage/tx_storage/ob_tenant_freezer_rpc.cpp +++ b/src/storage/tx_storage/ob_tenant_freezer_rpc.cpp @@ -20,11 +20,13 @@ #include "storage/tx_storage/ob_ls_service.h" #include "storage/tx_storage/ob_tenant_freezer.h" #include "storage/tx_storage/ob_tenant_freezer_common.h" +#include "storage/multi_data_source/mds_table_mgr.h" namespace oceanbase { using namespace storage; using namespace share; +using namespace storage::mds; using namespace rootserver; namespace obrpc { @@ -60,6 +62,10 @@ int ObTenantFreezerP::process() if (OB_FAIL(do_major_freeze_())) { LOG_WARN("do major freeze failed", K(ret)); } + } else if (storage::MDS_TABLE_FREEZE == arg_.freeze_type_) { + if (OB_FAIL(do_mds_table_freeze_())) { + LOG_WARN("do mds table freeze failed.", KR(ret), K(arg_)); + } } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("unknown freeze type", K(arg_), K(ret)); @@ -167,5 +173,50 @@ int ObTenantFreezerP::do_major_freeze_() return ret; } +int ObTenantFreezerP::do_mds_table_freeze_() +{ + int ret = OB_SUCCESS; + LOG_INFO("start mds table self freeze task in rpc handle thread", K(arg_)); + + common::ObSharedGuard iter_guard; + ObLSService *ls_srv = MTL(ObLSService *); + + if (OB_FAIL(ls_srv->get_ls_iter(iter_guard, ObLSGetMod::TXSTORAGE_MOD))) { + LOG_WARN("[TenantFreezer] fail to get log stream iterator", K(ret)); + } else { + int ls_cnt = 0; + while (OB_SUCC(ret)) { + ObLS *ls = nullptr; + MdsTableMgrHandle mgr_handle; + ObMdsTableMgr *mds_table_mgr = nullptr; + + if (OB_FAIL(iter_guard->get_next(ls))) { + if (OB_ITER_END != ret) { + LOG_WARN("get next ls failed.", KR(ret), K(arg_)); + } + } else if (OB_ISNULL(ls) || OB_ISNULL(ls->get_tablet_svr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is unexpected nullptr", KR(ret), K(arg_)); + } else { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(ls->flush_mds_table(INT64_MAX))) { + LOG_WARN("flush mds table failed", KR(tmp_ret), KPC(ls)); + } + } + ++ls_cnt; + } + + if (ret == OB_ITER_END) { + ret = OB_SUCCESS; + if (0 == ls_cnt) { + LOG_WARN("[TenantFreezer] no logstream", K(ret), K(ls_cnt)); + } + } + } + + LOG_INFO("finish mds table self freeze task in rpc handle thread", KR(ret), K(arg_)); + return ret; +} + } // obrpc } // oceanbase diff --git a/src/storage/tx_storage/ob_tenant_freezer_rpc.h b/src/storage/tx_storage/ob_tenant_freezer_rpc.h index 3121942a9..78c8455d5 100644 --- a/src/storage/tx_storage/ob_tenant_freezer_rpc.h +++ b/src/storage/tx_storage/ob_tenant_freezer_rpc.h @@ -49,6 +49,7 @@ protected: private: int do_tx_data_table_freeze_(); int do_major_freeze_(); + int do_mds_table_freeze_(); private: DISALLOW_COPY_AND_ASSIGN(ObTenantFreezerP); }; diff --git a/src/storage/tx_table/ob_tx_ctx_memtable.cpp b/src/storage/tx_table/ob_tx_ctx_memtable.cpp index f01c64630..3a815948b 100644 --- a/src/storage/tx_table/ob_tx_ctx_memtable.cpp +++ b/src/storage/tx_table/ob_tx_ctx_memtable.cpp @@ -28,7 +28,6 @@ ObTxCtxMemtable::ObTxCtxMemtable() : ObIMemtable(), is_inited_(false), is_frozen_(false), - ls_id_(), ls_ctx_mgr_guard_(), flush_lock_() { @@ -118,59 +117,6 @@ int ObTxCtxMemtable::get(const storage::ObTableIterParam ¶m, return OB_NOT_SUPPORTED; } - -int ObTxCtxMemtable::set(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObIArray &columns, - const storage::ObStoreRow &row, - const share::ObEncryptMeta *encrypt_meta) -{ - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(columns); - UNUSED(row); - UNUSED(encrypt_meta); - return OB_NOT_SUPPORTED; -} - -int ObTxCtxMemtable::lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - common::ObNewRowIterator &row_iter) -{ - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(row_iter); - return OB_NOT_SUPPORTED; -} - -int ObTxCtxMemtable::lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObNewRow &row) -{ - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(row); - return OB_NOT_SUPPORTED; -} - -int ObTxCtxMemtable::lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const blocksstable::ObDatumRowkey &rowkey) -{ - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(rowkey); - return OB_NOT_SUPPORTED; -} - int ObTxCtxMemtable::get(const storage::ObTableIterParam ¶m, storage::ObTableAccessContext &context, const blocksstable::ObDatumRowkey &rowkey, diff --git a/src/storage/tx_table/ob_tx_ctx_memtable.h b/src/storage/tx_table/ob_tx_ctx_memtable.h index f790035d0..cd12bf9af 100644 --- a/src/storage/tx_table/ob_tx_ctx_memtable.h +++ b/src/storage/tx_table/ob_tx_ctx_memtable.h @@ -46,7 +46,6 @@ public: int init(const ObITable::TableKey &table_key, const share::ObLSID &ls_id); void reset(); - int on_memtable_flushed() override; bool is_frozen_memtable() const override; bool is_active_memtable() const override; @@ -79,28 +78,6 @@ public: const blocksstable::ObDatumRowkey &rowkey, blocksstable::ObDatumRow &row) override; - virtual int set(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObIArray &columns, - const storage::ObStoreRow &row, - const share::ObEncryptMeta *encrypt_meta) override; - - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - common::ObNewRowIterator &row_iter) override; - - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObNewRow &row) override; - - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const blocksstable::ObDatumRowkey &rowkey) override; - virtual int get(const storage::ObTableIterParam ¶m, storage::ObTableAccessContext &context, const blocksstable::ObDatumRowkey &rowkey, @@ -124,7 +101,6 @@ public: private: bool is_inited_; bool is_frozen_; - share::ObLSID ls_id_; ObTxCtxTable ls_ctx_mgr_guard_; common::ObSpinLock flush_lock_; }; diff --git a/src/storage/tx_table/ob_tx_ctx_table.cpp b/src/storage/tx_table/ob_tx_ctx_table.cpp index 0b552a00f..d0d278f0a 100644 --- a/src/storage/tx_table/ob_tx_ctx_table.cpp +++ b/src/storage/tx_table/ob_tx_ctx_table.cpp @@ -105,6 +105,7 @@ int ObTxCtxTableRecoverHelper::recover_one_tx_ctx_(transaction::ObLSTxCtxMgr* ls bool tx_ctx_existed = true; common::ObAddr scheduler; transaction::ObTxCreateArg arg(true, /* for_replay */ + false, MTL_ID(), ctx_info.tx_id_, ctx_info.ls_id_, diff --git a/src/storage/tx_table/ob_tx_data_memtable.cpp b/src/storage/tx_table/ob_tx_data_memtable.cpp index 45df41d8f..019915e2b 100644 --- a/src/storage/tx_table/ob_tx_data_memtable.cpp +++ b/src/storage/tx_table/ob_tx_data_memtable.cpp @@ -22,6 +22,7 @@ #include "storage/tx_table/ob_tx_data_table.h" #include "storage/tx_table/ob_tx_table_iterator.h" #include "storage/tablet/ob_tablet.h" +#include "storage/blocksstable/ob_storage_cache_suite.h" namespace oceanbase { @@ -38,6 +39,7 @@ int64_t ObTxDataMemtable::PERIODICAL_SELECT_INTERVAL_NS = 1000LL * 1000LL * 1000 int ObTxDataMemtable::init(const ObITable::TableKey &table_key, SliceAllocator *slice_allocator, ObTxDataMemtableMgr *memtable_mgr, + storage::ObFreezer *freezer, const int64_t buckets_cnt) { int ret = OB_SUCCESS; @@ -55,12 +57,15 @@ int ObTxDataMemtable::init(const ObITable::TableKey &table_key, STORAGE_LOG(WARN, "init tx data map failed.", KR(ret), K(table_key), KPC(memtable_mgr)); } else if (OB_FAIL(buf_.reserve(common::OB_MAX_VARCHAR_LENGTH))) { STORAGE_LOG(WARN, "reserve space for tx data memtable failed.", KR(ret), K(table_key), KPC(memtable_mgr)); + } else if (OB_FAIL(set_freezer(freezer))) { + STORAGE_LOG(WARN, "fail to set freezer", K(ret), KP(freezer)); } else { for (int i = 0; i < MAX_TX_DATA_TABLE_CONCURRENCY; i++) { min_tx_scn_[i] = SCN::max_scn(); min_start_scn_[i] = SCN::max_scn(); occupied_size_[i] = 0; } + ls_id_ = freezer_->get_ls_id(); construct_list_done_ = false; pre_process_done_ = false; max_tx_scn_.set_min(); @@ -435,12 +440,10 @@ int ObTxDataMemtable::get_past_commit_versions_(ObCommitVersionsArray &past_comm ObLSTabletService *tablet_svr = get_tx_data_memtable_mgr()->get_ls_tablet_svr(); // Must copy iter param ! ObTableIterParam iter_param = get_tx_data_memtable_mgr()->get_tx_data_table()->get_read_schema().iter_param_; - ObTabletHandle &tablet_handle = iter_param.tablet_handle_; + ObTabletHandle tablet_handle; + ObTabletMemberWrapper wrapper; - if (tablet_handle.is_valid()) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tablet handle should be empty", KR(ret), K(tablet_handle)); - } else if (OB_ISNULL(tablet_svr)) { + if (OB_ISNULL(tablet_svr)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(ERROR, "tablet svr is nullptr", KR(ret), KPC(this)); } else if (OB_FAIL(tablet_svr->get_tablet(LS_TX_DATA_TABLET, tablet_handle))) { @@ -448,19 +451,28 @@ int ObTxDataMemtable::get_past_commit_versions_(ObCommitVersionsArray &past_comm } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "invalid tablet handle", KR(ret), K(tablet_handle)); + } else if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(wrapper))) { + STORAGE_LOG(WARN, "get table store fail", KR(ret), K(tablet_handle)); } else { - // get the lastest sstable - ObITable *table - = tablet_handle.get_obj()->get_table_store().get_minor_sstables().get_boundary_table( - true /*is_last*/); - - if (OB_NOT_NULL(table)) { - ObCommitVersionsGetter getter(iter_param, table); - if (OB_FAIL(getter.get_next_row(past_commit_versions))) { - STORAGE_LOG(WARN, "get commit versions from tx data sstable failed.", KR(ret)); + ObSSTable *sstable = static_cast(wrapper.get_member()->get_minor_sstables().get_boundary_table(true)); + if (OB_NOT_NULL(sstable)) { + ObStorageMetaHandle sstable_handle; + ObSSTable *tmp_sstable = nullptr; + if (sstable->is_loaded()) { + tmp_sstable = sstable; + } else if (OB_FAIL(ObTabletTableStore::load_sstable(sstable->get_addr(), sstable_handle))) { + STORAGE_LOG(WARN, "fail to load sstable", K(ret), KPC(sstable)); + } else if (OB_FAIL(sstable_handle.get_sstable(tmp_sstable))) { + STORAGE_LOG(WARN, "fail to get sstable", K(ret), K(sstable_handle)); + } + if (OB_SUCC(ret)) { + ObCommitVersionsGetter getter(iter_param, tmp_sstable); + if (OB_FAIL(getter.get_next_row(past_commit_versions))) { + STORAGE_LOG(WARN, "get commit versions from tx data sstable failed.", KR(ret)); + } } } else { - STORAGE_LOG(DEBUG, "There is no tx data sstable yet", KR(ret), KPC(table)); + STORAGE_LOG(DEBUG, "There is no tx data sstable yet", KR(ret), KPC(sstable)); } } @@ -1289,65 +1301,6 @@ int ObTxDataMemtable::get(const storage::ObTableIterParam ¶m, return ret; } -int ObTxDataMemtable::set(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObIArray &columns, - const storage::ObStoreRow &row, - const share::ObEncryptMeta *encrypt_meta) -{ - int ret = OB_NOT_SUPPORTED; - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(columns); - UNUSED(row); - UNUSED(encrypt_meta); - return ret; -} - -int ObTxDataMemtable::lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - common::ObNewRowIterator &row_iter) -{ - - int ret = OB_NOT_SUPPORTED; - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(row_iter); - return ret; -} - -int ObTxDataMemtable::lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObNewRow &row) -{ - int ret = OB_NOT_SUPPORTED; - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(row); - return ret; -} - -int ObTxDataMemtable::lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const blocksstable::ObDatumRowkey &rowkey) -{ - int ret = OB_NOT_SUPPORTED; - UNUSED(ctx); - UNUSED(table_id); - UNUSED(read_info); - UNUSED(rowkey); - return ret; -} - - - } // namespace storage diff --git a/src/storage/tx_table/ob_tx_data_memtable.h b/src/storage/tx_table/ob_tx_data_memtable.h index 12e632c91..987908c4f 100644 --- a/src/storage/tx_table/ob_tx_data_memtable.h +++ b/src/storage/tx_table/ob_tx_data_memtable.h @@ -162,8 +162,8 @@ public: // ObTxDataMemtable int init(const ObITable::TableKey &table_key, SliceAllocator *slice_allocator, ObTxDataMemtableMgr *memtable_mgr, + storage::ObFreezer *freezer, const int64_t buckets_cnt); - /** * @brief Insert the tx data into this tx data memtable * @@ -290,28 +290,6 @@ public: /* derived from ObIMemtable */ storage::ObTableAccessContext &context, const blocksstable::ObDatumRowkey &rowkey, blocksstable::ObDatumRow &row) override; - // not supported - virtual int set(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObIArray &columns, - const storage::ObStoreRow &row, - const share::ObEncryptMeta *encrypt_meta) override; - // not supported - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - common::ObNewRowIterator &row_iter) override; - // not supported - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const common::ObNewRow &row) override; - // not supported - virtual int lock(storage::ObStoreCtx &ctx, - const uint64_t table_id, - const storage::ObTableReadInfo &read_info, - const blocksstable::ObDatumRowkey &rowkey) override; public: // checkpoint share::SCN get_rec_scn() diff --git a/src/storage/tx_table/ob_tx_data_memtable_mgr.cpp b/src/storage/tx_table/ob_tx_data_memtable_mgr.cpp index a20641636..65c5bdeb5 100755 --- a/src/storage/tx_table/ob_tx_data_memtable_mgr.cpp +++ b/src/storage/tx_table/ob_tx_data_memtable_mgr.cpp @@ -174,12 +174,10 @@ int ObTxDataMemtableMgr::create_memtable_(const SCN clog_checkpoint_scn, } else if (OB_ISNULL(tx_data_memtable)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(ERROR, "dynamic cast failed", KR(ret), KPC(this)); - } else if (OB_FAIL(tx_data_memtable->init(table_key, slice_allocator_, this, buckets_cnt))) { + } else if (OB_FAIL(tx_data_memtable->init(table_key, slice_allocator_, this, freezer_, buckets_cnt))) { STORAGE_LOG(WARN, "memtable init fail.", KR(ret), KPC(tx_data_memtable)); } else if (OB_FAIL(add_memtable_(handle))) { STORAGE_LOG(WARN, "add memtable fail.", KR(ret)); - } else if (OB_FAIL(tx_data_memtable->set_freezer(freezer_))) { - STORAGE_LOG(WARN, "tx_data_memtable set freezer failed", KR(ret), KPC(tx_data_memtable)); } else { // create memtable success STORAGE_LOG(INFO, "create tx data memtable done", KR(ret), KPC(tx_data_memtable)); diff --git a/src/storage/tx_table/ob_tx_data_table.cpp b/src/storage/tx_table/ob_tx_data_table.cpp old mode 100644 new mode 100755 index 85f64164b..e2ddd5e42 --- a/src/storage/tx_table/ob_tx_data_table.cpp +++ b/src/storage/tx_table/ob_tx_data_table.cpp @@ -113,7 +113,6 @@ int ObTxDataTable::init_tx_data_read_schema_() auto &read_info = read_schema_.read_info_; auto &full_read_info = read_schema_.full_read_info_; common::ObSEArray columns; - common::ObSEArray full_columns; share::schema::ObColDesc key; key.col_id_ = TX_ID; @@ -163,31 +162,16 @@ int ObTxDataTable::init_tx_data_read_schema_() STORAGE_LOG(WARN, "failed to push back end_ts", KR(ret), K(end_ts)); } else if (OB_FAIL(columns.push_back(value))) { STORAGE_LOG(WARN, "failed to push back value", KR(ret), K(value)); - } else if (OB_FAIL(full_columns.push_back(key))) { - STORAGE_LOG(WARN, "failed to push back key", KR(ret), K(key)); - } else if (OB_FAIL(full_columns.push_back(idx))) { - STORAGE_LOG(WARN, "failed to push back idx", KR(ret), K(idx)); - } else if (OB_FAIL(full_columns.push_back(trans_col))) { - STORAGE_LOG(WARN, "failed to push back trans col", KR(ret), K(key)); - } else if (OB_FAIL(full_columns.push_back(sequence_col))) { - STORAGE_LOG(WARN, "failed to push back sequence col", KR(ret), K(key)); - } else if (OB_FAIL(full_columns.push_back(total_row_cnt))) { - STORAGE_LOG(WARN, "failed to push back total row cnt", KR(ret), K(total_row_cnt)); - } else if (OB_FAIL(full_columns.push_back(end_ts))) { - STORAGE_LOG(WARN, "failed to push back end ts", KR(ret), K(end_ts)); - } else if (OB_FAIL(full_columns.push_back(value))) { - STORAGE_LOG(WARN, "failed to push back value", KR(ret), K(value)); } else if (OB_FAIL(read_info.init(arena_allocator_, LS_TX_DATA_SCHEMA_COLUMN_CNT, LS_TX_DATA_SCHEMA_ROWKEY_CNT, lib::is_oracle_mode(), - columns))) { + columns, nullptr/*storage_cols_index*/))) { STORAGE_LOG(WARN, "Fail to init read_info", K(ret)); } else if (OB_FAIL(full_read_info.init(arena_allocator_, LS_TX_DATA_SCHEMA_COLUMN_CNT, LS_TX_DATA_SCHEMA_ROWKEY_CNT, lib::is_oracle_mode(), - full_columns, true))) { + columns))) { STORAGE_LOG(WARN, "Fail to init read_info", K(ret)); } else { read_schema_.iter_param_.read_info_ = &read_info; - read_schema_.iter_param_.full_read_info_ = &full_read_info; } return ret; @@ -703,19 +687,20 @@ int ObTxDataTable::get_tx_data_in_sstable_(const transaction::ObTransID tx_id, O { int ret = OB_SUCCESS; ObTableIterParam iter_param = read_schema_.iter_param_; - ObTabletHandle &tablet_handle = iter_param.tablet_handle_; + ObTabletMemberWrapper table_store_wrapper; + ObTabletHandle tablet_handle; - if (tablet_handle.is_valid()) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tablet handle should be empty", KR(ret), K(tablet_handle)); - } else if (FALSE_IT(tx_data.tx_id_ = tx_id)) { + if (FALSE_IT(tx_data.tx_id_ = tx_id)) { } else if (OB_FAIL(ls_tablet_svr_->get_tablet(tablet_id_, tablet_handle))) { STORAGE_LOG(WARN, "get tablet from ls tablet service fail.", KR(ret), KP(this), K(tablet_id_)); } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid tablet handle", KR(ret), K(tablet_handle), K(tablet_id_)); + } else if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - ObTxDataSingleRowGetter getter(iter_param, slice_allocator_, recycled_scn); + const ObSSTableArray &sstables = table_store_wrapper.get_member()->get_minor_sstables(); + ObTxDataSingleRowGetter getter(iter_param, sstables, slice_allocator_, recycled_scn); if (OB_FAIL(getter.init(tx_id))) { STORAGE_LOG(WARN, "init ObTxDataSingleRowGetter fail.", KR(ret), KP(this), K(tablet_id_)); } else if (OB_FAIL(getter.get_next_row(tx_data))) { @@ -734,7 +719,7 @@ int ObTxDataTable::get_recycle_scn(SCN &recycle_scn) { int ret = OB_SUCCESS; ObTabletHandle tablet_handle; - ObLSTabletIterator iterator; + ObLSTabletIterator iterator(ObMDSGetTabletMode::READ_READABLE_COMMITED); ObMigrationStatus migration_status; share::ObLSRestoreStatus restore_status; ObTimeGuard tg("get recycle scn", 0); @@ -758,12 +743,9 @@ int ObTxDataTable::get_recycle_scn(SCN &recycle_scn) } else if (ObLSRestoreStatus::RESTORE_NONE != restore_status) { recycle_scn.set_min(); STORAGE_LOG(INFO, "logstream is in restore state. skip recycle tx data", "ls_id", ls_->get_ls_id()); - } else if (OB_FAIL(get_ls_min_end_scn_in_latest_tablets_(min_end_scn_from_latest_tablets))) { - // get_ls_min_end_scn_in_latest_tablets must before get_ls_min_end_scn_in_old_tablets - STORAGE_LOG(WARN, "fail to get ls min end log ts in all of latest tablets", KR(ret)); - } else if (FALSE_IT(tg.click("iterate tablet finish"))) { - } else if (OB_FAIL(ls_tablet_svr_->get_ls_min_end_scn_in_old_tablets(min_end_scn_from_old_tablets))) { - STORAGE_LOG(WARN, "fail to get ls min end log ts in all of old tablets", KR(ret)); + } else if (OB_FAIL(ls_tablet_svr_->get_ls_min_end_scn(min_end_scn_from_latest_tablets, + min_end_scn_from_old_tablets))) { + STORAGE_LOG(WARN, "fail to get ls min end log ts", KR(ret)); } else { min_end_scn = std::min(min_end_scn_from_old_tablets, min_end_scn_from_latest_tablets); if (!min_end_scn.is_max()) { @@ -791,62 +773,6 @@ int ObTxDataTable::get_recycle_scn(SCN &recycle_scn) return ret; } -int ObTxDataTable::get_ls_min_end_scn_in_latest_tablets_(SCN &min_end_scn) -{ - int ret = OB_SUCCESS; - ObLSTabletIterator iterator(ObTabletCommon::NO_CHECK_GET_TABLET_TIMEOUT_US); - ObTabletHandle tablet_handle; - min_end_scn.set_max(); - - if (OB_FAIL(ls_tablet_svr_->build_tablet_iter(iterator))) { - STORAGE_LOG(WARN, "build ls table iter failed.", KR(ret)); - } else { - while (OB_SUCC(iterator.get_next_tablet(tablet_handle))) { - SCN end_scn_from_single_tablet = SCN::max_scn(); - if (OB_FAIL(get_min_end_scn_from_single_tablet_(tablet_handle, end_scn_from_single_tablet))) { - STORAGE_LOG(WARN, "get min end_scn from a single tablet failed.", KR(ret)); - } else if (end_scn_from_single_tablet < min_end_scn) { - min_end_scn = end_scn_from_single_tablet; - } - } - - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - } - } - return ret; -} - -int ObTxDataTable::get_min_end_scn_from_single_tablet_(ObTabletHandle &tablet_handle, - SCN &end_scn) -{ - int ret = OB_SUCCESS; - ObTablet *tablet = nullptr; - if (OB_ISNULL(tablet = tablet_handle.get_obj())) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tablet is nullptr.", KR(ret), KP(this), K(tablet_id_)); - } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { - // skip inner tablet - } else { - ObTabletTableStore &table_store = tablet->get_table_store(); - ObITable *first_minor_mini_sstable = table_store.get_minor_sstables().get_boundary_table(false /*is_last*/); - ObITable *last_major_sstable = nullptr; - - if (OB_NOT_NULL(first_minor_mini_sstable)) { - // step 1 : get end_scn if minor/mini sstable exist - end_scn = first_minor_mini_sstable->get_end_scn(); - } else if (FALSE_IT(last_major_sstable = table_store.get_major_sstables().get_boundary_table(true /*is_last*/))) { - } else if (OB_NOT_NULL(last_major_sstable)) { - // step 2 : if minor/mini sstable do not exist, get end_scn from major sstable - end_scn = last_major_sstable->get_end_scn(); - } else { - // step 3 : if minor/major sstable do not exist, get end_scn from tablet clog_checkpoint - end_scn = tablet->get_tablet_meta().clog_checkpoint_scn_; - } - } - return ret; -} - // This task is used to do freeze by tx data table itself. The following conditions are set to // trigger self freeze: // 1. Tx data memtable uses more than TX_DATA_FREEZE_TRIGGER_MAX_PERCENTAGE% memory in total tenant @@ -900,7 +826,7 @@ int ObTxDataTable::get_upper_trans_version_before_given_scn(const SCN sstable_en ret = OB_ERR_UNEXPECTED; STORAGE_LOG(ERROR, "invalid cache for upper trans version calculation", KR(ret)); } else if (OB_FAIL(calc_upper_trans_scn_(sstable_end_scn, upper_trans_version))) { - STORAGE_LOG(WARN, "calc upper trans version failed", KR(ret), K(ls_id_)); + STORAGE_LOG(WARN, "calc upper trans version failed", KR(ret), "ls_id", get_ls_id()); } else { FLOG_INFO("get upper trans version finish.", KR(ret), @@ -954,20 +880,19 @@ int ObTxDataTable::DEBUG_calc_with_all_sstables_(ObTableAccessContext &access_co int ret = OB_SUCCESS; ObTableIterParam iter_param = read_schema_.iter_param_; - ObTabletHandle &tablet_handle = iter_param.tablet_handle_; + ObTabletHandle tablet_handle; + ObTabletMemberWrapper table_store_wrapper; ObStoreRowIterator *row_iter = nullptr; - if (tablet_handle.is_valid()) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tablet handle should be empty", KR(ret), K(tablet_handle)); - } else if (OB_FAIL(ls_tablet_svr_->get_tablet(tablet_id_, tablet_handle))) { + if (OB_FAIL(ls_tablet_svr_->get_tablet(tablet_id_, tablet_handle))) { STORAGE_LOG(WARN, "get tablet from ls tablet service failed.", KR(ret)); } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid tablet handle", KR(ret), K(tablet_handle), K(tablet_id_)); + } else if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - ObTabletTableStore &table_store = tablet_handle.get_obj()->get_table_store(); - ObSSTableArray &sstables = table_store.get_minor_sstables(); + const ObSSTableArray &sstables = table_store_wrapper.get_member()->get_minor_sstables(); blocksstable::ObDatumRange whole_range; whole_range.set_whole_range(); @@ -1175,12 +1100,14 @@ int ObTxDataTable::update_cache_if_needed_(bool &skip_calc) { int ret = OB_SUCCESS; ObTabletHandle tablet_handle; + ObTabletMemberWrapper table_store_wrapper; if (OB_FAIL(ls_tablet_svr_->get_tablet(LS_TX_DATA_TABLET, tablet_handle))) { STORAGE_LOG(WARN, "get tablet from ls tablet service failed.", KR(ret)); + } else if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else { - ObITable *table = - tablet_handle.get_obj()->get_table_store().get_minor_sstables().get_boundary_table(true /*is_last*/); + ObITable *table =table_store_wrapper.get_member()->get_minor_sstables().get_boundary_table(true /*is_last*/); if (nullptr == table) { skip_calc = true; @@ -1205,24 +1132,31 @@ int ObTxDataTable::update_calc_upper_trans_version_cache_(ObITable *table) int ret = OB_SUCCESS; STORAGE_LOG(DEBUG, "update calc upper trans version cache once."); ObTableIterParam iter_param = read_schema_.iter_param_; - ObTabletHandle &tablet_handle = iter_param.tablet_handle_; + ObTabletHandle tablet_handle; - if (tablet_handle.is_valid()) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tablet handle should be empty", KR(ret), K(tablet_handle)); - } else if (OB_FAIL(ls_tablet_svr_->get_tablet(tablet_id_, tablet_handle))) { + if (OB_FAIL(ls_tablet_svr_->get_tablet(tablet_id_, tablet_handle))) { STORAGE_LOG(WARN, "get tablet from ls tablet service fail.", KR(ret), KP(this), K(tablet_id_)); } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid tablet handle", KR(ret), K(tablet_handle), K(tablet_id_)); } else { - ObCommitVersionsGetter getter(iter_param, table); - if (OB_FAIL(getter.get_next_row(calc_upper_trans_version_cache_.commit_versions_))) { - STORAGE_LOG(WARN, "update calc_upper_trans_trans_version_cache failed.", KR(ret), KPC(table)); - } else { - calc_upper_trans_version_cache_.is_inited_ = true; - calc_upper_trans_version_cache_.cache_version_ = table->get_end_scn(); - // update calc_upper_trans_scn_cache succeed. + ObStorageMetaHandle sstable_handle; + ObSSTable *sstable = static_cast(table); + if (sstable->is_loaded()) { + } else if (OB_FAIL(ObTabletTableStore::load_sstable(sstable->get_addr(), sstable_handle))) { + STORAGE_LOG(WARN, "fail to load sstable", K(ret), KPC(sstable)); + } else if (OB_FAIL(sstable_handle.get_sstable(sstable))) { + STORAGE_LOG(WARN, "fail to get sstable", K(ret), K(sstable_handle)); + } + if (OB_SUCC(ret)) { + ObCommitVersionsGetter getter(iter_param, sstable); + if (OB_FAIL(getter.get_next_row(calc_upper_trans_version_cache_.commit_versions_))) { + STORAGE_LOG(WARN, "update calc_upper_trans_trans_version_cache failed.", KR(ret), KPC(sstable)); + } else { + calc_upper_trans_version_cache_.is_inited_ = true; + calc_upper_trans_version_cache_.cache_version_ = table->get_end_scn(); + // update calc_upper_trans_scn_cache succeed. + } } } return ret; @@ -1307,6 +1241,8 @@ int ObTxDataTable::get_start_tx_scn(SCN &start_tx_scn) start_tx_scn.set_max(); ObTabletHandle tablet_handle; ObTablet *tablet = nullptr; + ObTabletMemberWrapper table_store_wrapper; + ObSSTableMetaHandle meta_handle; ObSSTable *oldest_minor_sstable = nullptr; if (IS_NOT_INIT) { @@ -1317,11 +1253,15 @@ int ObTxDataTable::get_start_tx_scn(SCN &start_tx_scn) } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(ERROR, "tablet is nullptr.", KR(ret), KP(this), K(tablet_id_)); - } else if (OB_ISNULL(oldest_minor_sstable = - (ObSSTable *)tablet->get_table_store().get_minor_sstables().get_boundary_table(false /*is_last*/))) { + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_ISNULL(oldest_minor_sstable = static_cast( + table_store_wrapper.get_member()->get_minor_sstables().get_boundary_table(false /*is_last*/)))) { start_tx_scn.set_max(); STORAGE_LOG(INFO, "this logstream do not have tx data sstable", K(start_tx_scn), K(get_ls_id()), KPC(tablet)); - } else if (FALSE_IT(start_tx_scn = oldest_minor_sstable->get_filled_tx_scn())) { + } else if (OB_FAIL(oldest_minor_sstable->get_meta(meta_handle))) { + LOG_WARN("fail to get sstable meta", K(ret)); + } else if (FALSE_IT(start_tx_scn = meta_handle.get_sstable_meta().get_filled_tx_scn())) { } else if (start_tx_scn.is_max()) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(ERROR, "start_tx_scn is unexpected INT64_MAX", KR(ret), KPC(tablet), KPC(oldest_minor_sstable)); diff --git a/src/storage/tx_table/ob_tx_data_table.h b/src/storage/tx_table/ob_tx_data_table.h old mode 100644 new mode 100755 index 3611bdf61..1e4c64e22 --- a/src/storage/tx_table/ob_tx_data_table.h +++ b/src/storage/tx_table/ob_tx_data_table.h @@ -39,7 +39,7 @@ struct TxDataReadSchema { ObTableIterParam iter_param_; ObTableReadInfo read_info_; - ObTableReadInfo full_read_info_; + ObRowkeyReadInfo full_read_info_; TxDataReadSchema() : iter_param_(), read_info_(), full_read_info_() {} }; @@ -252,8 +252,6 @@ public: // getter and setter private: virtual ObTxDataMemtableMgr *get_memtable_mgr_() { return memtable_mgr_; } - int get_ls_min_end_scn_in_latest_tablets_(share::SCN &min_end_ts); - int init_slice_allocator_(); int init_arena_allocator_(); @@ -283,7 +281,6 @@ private: int insert_into_memtable_(ObTxDataMemtable *tx_data_memtable, ObTxData *&tx_data); // free the whole undo status list allocated by slice allocator - int get_min_end_scn_from_single_tablet_(ObTabletHandle &tablet_handle, share::SCN &end_scn); int deep_copy_undo_status_list_(const ObUndoStatusList &in_list, ObUndoStatusList &out_list); int init_tx_data_read_schema_(); @@ -295,7 +292,7 @@ private: int calc_upper_trans_scn_(const share::SCN sstable_end_scn, share::SCN &upper_trans_version); int update_freeze_trigger_threshold_(); - + int check_need_update_memtables_cache_(bool &need_update); int get_tx_data_in_memtables_cache_(const transaction::ObTransID tx_id, diff --git a/src/storage/tx_table/ob_tx_table.cpp b/src/storage/tx_table/ob_tx_table.cpp old mode 100644 new mode 100755 index 64f899afd..60f401ce8 --- a/src/storage/tx_table/ob_tx_table.cpp +++ b/src/storage/tx_table/ob_tx_table.cpp @@ -200,8 +200,10 @@ int ObTxTable::create_tablet(const lib::Worker::CompatMode compat_mode, const SC LOG_WARN("create ctx tablet failed", K(ret)); } if (OB_FAIL(ret)) { - int tmp_ret = remove_tablet(); - LOG_WARN("remove tablet init failed", K(tmp_ret)); + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(remove_tablet())) { + LOG_WARN("remove tablet failed", K(tmp_ret)); + } } } return ret; @@ -271,75 +273,25 @@ int ObTxTable::get_ctx_table_schema_(const uint64_t tenant_id, share::schema::Ob return ret; } -int ObTxTable::gen_create_tablet_arg_(const ObTabletID &tablet_id, - const uint64_t tenant_id, - const ObLSID ls_id, - const lib::Worker::CompatMode compat_mode, - const schema::ObTableSchema &table_schema, - obrpc::ObBatchCreateTabletArg &arg) +int ObTxTable::create_ctx_tablet_( + const uint64_t tenant_id, + const ObLSID ls_id, + const lib::Worker::CompatMode compat_mode, + const share::SCN &create_scn) { int ret = OB_SUCCESS; - ObCreateTabletInfo create_tablet_info; - ObArray tablet_ids; - ObArray tablet_schema_idxs; - - // frozen_timestamp: next merge time - - arg.reset(); - // create ObCreateTabletInfo - if (OB_FAIL(tablet_ids.push_back(tablet_id))) { - LOG_WARN("insert tablet id failed", K(ret), K(tablet_id)); - // only one tablet, only one schema - } else if (OB_FAIL(tablet_schema_idxs.push_back(0))) { - LOG_WARN("insert tablet schema idx failed", K(ret)); - // TODO ls inited in sys tenant, the special tablet always init as mysql mode?? @cxf262476 - } else if (OB_FAIL(create_tablet_info.init( - tablet_ids, tablet_id, tablet_schema_idxs, compat_mode, false /*is_create_bind_hidden_tablets*/))) { - LOG_WARN("create tablet info init failed", K(ret), K(tablet_ids), K(tablet_id)); - // create ObBatchCreateTabletArg - } else if (OB_FAIL(arg.init_create_tablet(ls_id, SCN::base_scn(), false/*need_check_tablet_cnt*/))) { - LOG_WARN("ObBatchCreateTabletArg init create tablet failed", K(ret), K(tenant_id), K(ls_id)); - } else if (OB_FAIL(arg.table_schemas_.push_back(table_schema))) { - LOG_WARN("add table schema failed", K(ret), K(table_schema)); - } else if (OB_FAIL(arg.tablets_.push_back(create_tablet_info))) { - LOG_WARN("add create tablet info failed", K(ret), K(create_tablet_info)); - } - - return ret; -} - -int ObTxTable::gen_remove_tablet_arg_(const common::ObTabletID &tablet_id, - const uint64_t tenant_id, - const share::ObLSID ls_id, - obrpc::ObBatchRemoveTabletArg &arg) -{ - int ret = OB_SUCCESS; - arg.reset(); - if (OB_FAIL(arg.tablet_ids_.push_back(tablet_id))) { - LOG_WARN("insert tablet id failed", K(ret), K(tablet_id)); - } else { - arg.id_ = ls_id; - } - return ret; -} - -int ObTxTable::create_ctx_tablet_(const uint64_t tenant_id, - const ObLSID ls_id, - const lib::Worker::CompatMode compat_mode, - const SCN &create_scn) -{ - int ret = OB_SUCCESS; - obrpc::ObBatchCreateTabletArg arg; - const bool no_need_write_clog = true; share::schema::ObTableSchema table_schema; - SCN tmp_scn; - if (OB_FAIL(get_ctx_table_schema_(tenant_id, table_schema))) { LOG_WARN("get ctx table schema failed", K(ret)); - } else if (OB_FAIL(gen_create_tablet_arg_(LS_TX_CTX_TABLET, tenant_id, ls_id, compat_mode, table_schema, arg))) { - LOG_WARN("gen create tablet arg failed", K(ret), K(LS_TX_CTX_TABLET), K(tenant_id), K(ls_id), K(table_schema)); - } else if (OB_FAIL(ls_->batch_create_tablets(arg, create_scn, no_need_write_clog))) { - LOG_WARN("create ctx tablet failed", K(ret), K(arg), K(create_scn)); + } else if (OB_FAIL(ls_->create_ls_inner_tablet(ls_id, + LS_TX_CTX_TABLET, + ObLS::LS_INNER_TABLET_FROZEN_SCN, + table_schema, + compat_mode, + create_scn))) { + LOG_WARN("create tx ctx tablet failed", K(ret), K(ls_id), + K(LS_TX_CTX_TABLET), K(ObLS::LS_INNER_TABLET_FROZEN_SCN), + K(table_schema), K(compat_mode), K(create_scn)); } return ret; } @@ -446,19 +398,21 @@ int ObTxTable::get_data_table_schema_(const uint64_t tenant_id, share::schema::O int ObTxTable::create_data_tablet_(const uint64_t tenant_id, const ObLSID ls_id, const lib::Worker::CompatMode compat_mode, - const SCN &create_scn) + const share::SCN &create_scn) { int ret = OB_SUCCESS; - obrpc::ObBatchCreateTabletArg arg; - const bool no_need_write_clog = true; share::schema::ObTableSchema table_schema; - if (OB_FAIL(get_data_table_schema_(tenant_id, table_schema))) { LOG_WARN("get data table schema failed", K(ret)); - } else if (OB_FAIL(gen_create_tablet_arg_(LS_TX_DATA_TABLET, tenant_id, ls_id, compat_mode, table_schema, arg))) { - LOG_WARN("gen create tablet arg failed", K(ret), K(LS_TX_DATA_TABLET), K(tenant_id), K(ls_id), K(table_schema)); - } else if (OB_FAIL(ls_->batch_create_tablets(arg, create_scn, no_need_write_clog))) { - LOG_WARN("create ctx tablet failed", K(ret), K(arg), K(create_scn)); + } else if (OB_FAIL(ls_->create_ls_inner_tablet(ls_id, + LS_TX_DATA_TABLET, + ObLS::LS_INNER_TABLET_FROZEN_SCN, + table_schema, + compat_mode, + create_scn))) { + LOG_WARN("create tx data tablet failed", K(ret), K(ls_id), + K(LS_TX_DATA_TABLET), K(ObLS::LS_INNER_TABLET_FROZEN_SCN), + K(table_schema), K(compat_mode), K(create_scn)); } return ret; } @@ -466,31 +420,9 @@ int ObTxTable::create_data_tablet_(const uint64_t tenant_id, int ObTxTable::remove_tablet_(const common::ObTabletID &tablet_id) { int ret = OB_SUCCESS; - obrpc::ObBatchRemoveTabletArg arg; - const bool no_need_write_clog = true; - uint64_t tenant_id = ls_->get_tenant_id(); - if (OB_FAIL(gen_remove_tablet_arg_(tablet_id, tenant_id, ls_->get_ls_id(), arg))) { - LOG_WARN("gen remove tablet arg failed", K(ret), K(tablet_id), K(tenant_id), K(ls_->get_ls_id())); - } else if (OB_FAIL(ls_->batch_remove_tablets(arg, no_need_write_clog))) { - LOG_WARN("remove tablet failed", K(ret), K(arg)); - } - return ret; -} - -int ObTxTable::remove_data_tablet_() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(remove_tablet_(LS_TX_DATA_TABLET))) { - LOG_WARN("remove tablet failed", K(ret), K(LS_TX_DATA_TABLET)); - } - return ret; -} - -int ObTxTable::remove_ctx_tablet_() -{ - int ret = OB_SUCCESS; - if (OB_FAIL(remove_tablet_(LS_TX_CTX_TABLET))) { - LOG_WARN("remove tablet failed", K(ret), K(LS_TX_CTX_TABLET)); + const share::ObLSID &ls_id = ls_->get_ls_id(); + if (OB_FAIL(ls_->remove_ls_inner_tablet(ls_id, tablet_id))) { + LOG_WARN("remove ls inner tablet failed", K(ret), K(ls_id), K(tablet_id)); } return ret; } @@ -499,11 +431,11 @@ int ObTxTable::remove_tablet() { int ret = OB_SUCCESS; if (OB_NOT_NULL(ls_)) { - if (OB_FAIL(remove_data_tablet_())) { - LOG_WARN("remove data tablet failed", K(ret)); + if (OB_FAIL(remove_tablet_(LS_TX_DATA_TABLET))) { + LOG_WARN("remove tx data tablet failed", K(ret)); } - if (OB_FAIL(remove_ctx_tablet_())) { - LOG_WARN("remove ctx tablet failed", K(ret)); + if (OB_FAIL(remove_tablet_(LS_TX_CTX_TABLET))) { + LOG_WARN("remove tx ctx tablet failed", K(ret)); } } return ret; @@ -514,6 +446,7 @@ int ObTxTable::load_tx_ctx_table_() int ret = OB_SUCCESS; ObTabletHandle handle; ObTablet *tablet; + ObTabletMemberWrapper table_store_wrapper; ObLSTabletService *ls_tablet_svr = ls_->get_tablet_svr(); if (NULL == ls_tablet_svr) { @@ -522,14 +455,25 @@ int ObTxTable::load_tx_ctx_table_() } else if (OB_FAIL(ls_tablet_svr->get_tablet(LS_TX_CTX_TABLET, handle))) { LOG_WARN("get tablet failed", K(ret)); } else if (FALSE_IT(tablet = handle.get_obj())) { + } else if (OB_FAIL(tablet->fetch_table_store(table_store_wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); } else if (OB_FAIL(ls_tablet_svr->create_memtable(LS_TX_CTX_TABLET, 0 /* schema_version */))) { LOG_WARN("failed to create memtable", K(ret)); } else { - ObTabletTableStore &table_store = tablet->get_table_store(); - ObSSTableArray &sstables = table_store.get_minor_sstables(); + const ObSSTableArray &sstables = table_store_wrapper.get_member()->get_minor_sstables(); if (!sstables.empty()) { - ret = restore_tx_ctx_table_(*sstables[0]); + ObStorageMetaHandle sstable_handle; + ObSSTable *sstable = static_cast(sstables[0]); + if (sstable->is_loaded()) { + } else if (OB_FAIL(ObTabletTableStore::load_sstable(sstable->get_addr(), sstable_handle))) { + LOG_WARN("fail to load sstable", K(ret), KPC(sstable)); + } else if (OB_FAIL(sstable_handle.get_sstable(sstable))) { + LOG_WARN("fail to get sstable", K(ret), K(sstable_handle)); + } + if (FAILEDx(restore_tx_ctx_table_(*sstable))) { + LOG_WARN("fail to restore tx ctx table", K(ret), KPC(sstable)); + } } } @@ -626,15 +570,19 @@ int ObTxTable::restore_tx_ctx_table_(ObITable &trans_sstable) LOG_WARN("failed to push back meta", K(ret), K(meta)); } else if (OB_FAIL(columns.push_back(value))) { LOG_WARN("failed to push back value", K(ret), K(value)); - } else if (OB_FAIL(read_info.init(allocator, - LS_TX_CTX_SCHEMA_COLUMN_CNT, - LS_TX_CTX_SCHEMA_ROWKEY_CNT, - lib::is_oracle_mode(), - columns))) { + } else if (OB_FAIL(read_info.init( + allocator, + LS_TX_CTX_SCHEMA_COLUMN_CNT, + LS_TX_CTX_SCHEMA_ROWKEY_CNT, + lib::is_oracle_mode(), + columns, + nullptr/*storage_cols_index*/))) { LOG_WARN("Fail to init read_info", K(ret)); } else if (FALSE_IT(iter_param.read_info_ = &read_info)) { - } else if (FALSE_IT(iter_param.full_read_info_ = &read_info)) { - } else if (OB_FAIL(trans_sstable.scan(iter_param, access_context, whole_range, row_iter))) { + } else if (OB_FAIL(trans_sstable.scan(iter_param, + access_context, + whole_range, + row_iter))) { LOG_WARN("failed to scan trans table", K(ret)); } else if (NULL == row_iter) { // do nothing diff --git a/src/storage/tx_table/ob_tx_table.h b/src/storage/tx_table/ob_tx_table.h index 751b243ec..93955626f 100644 --- a/src/storage/tx_table/ob_tx_table.h +++ b/src/storage/tx_table/ob_tx_table.h @@ -276,26 +276,12 @@ private: const lib::Worker::CompatMode compat_mode, const share::SCN &create_scn); int remove_tablet_(const common::ObTabletID &tablet_id); - int remove_data_tablet_(); - int remove_ctx_tablet_(); int get_data_table_schema_( const uint64_t tenant_id, share::schema::ObTableSchema &schema); int get_ctx_table_schema_( const uint64_t tenant_id, share::schema::ObTableSchema &schema); - int gen_create_tablet_arg_( - const common::ObTabletID &tablet_id, - const uint64_t tenant_id, - const share::ObLSID ls_id, - const lib::Worker::CompatMode compat_mode, - const share::schema::ObTableSchema &table_schema, - obrpc::ObBatchCreateTabletArg &arg); - int gen_remove_tablet_arg_( - const common::ObTabletID &tablet_id, - const uint64_t tenant_id, - const share::ObLSID ls_id, - obrpc::ObBatchRemoveTabletArg &arg); int restore_tx_ctx_table_(ObITable &trans_sstable); int load_tx_ctx_table_(); int load_tx_data_table_(); diff --git a/src/storage/tx_table/ob_tx_table_guards.cpp b/src/storage/tx_table/ob_tx_table_guards.cpp new file mode 100644 index 000000000..c4c9aa1dd --- /dev/null +++ b/src/storage/tx_table/ob_tx_table_guards.cpp @@ -0,0 +1,325 @@ +/** + * 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. + */ +#define USING_LOG_PREFIX STORAGE +#include "storage/tx_table/ob_tx_table_guards.h" +#include "lib/utility/ob_macro_utils.h" +#include "lib/oblog/ob_log_module.h" +#include "storage/tx_table/ob_tx_table_interface.h" +#include "storage/tx_table/ob_tx_table.h" + +namespace oceanbase +{ +namespace storage +{ +#define PRINT_ERROR_LOG(tx_id, ret, this) \ +{ \ + if (OB_TRANS_CTX_NOT_EXIST == ret) { \ + LOG_ERROR("trans ctx not exit", KR(ret), K(tx_id), K(*this));\ + }\ +} + +// There are two log streams(ls_id=1001 and ls_id=1002). After the transaction is started, there may be scenarios +// *********************************************** +// |scene | tx_id | ls_id=1001 | ls_id=1002 | +// *********************************************** +// |scene 1 | 1 | Y | Y | +// |scene 2 | 2 | N | Y | +// |scene 3 | 3 | Y | N | +// |scene 4 | 4 | N | N | +// *********************************************** + +// Only in the transfer scenario, src_tx_table_guard may be effective. +// In the transfer scenario, suppose ls_id=1001 is src_ls, ls_id=1002 is dest_ls, +// and then obtain the the output parameters of each interface in different scenarios. +// tx_table_guard_ belongs to 1002, src_tx_table_guard belongs to 1001 +// **************************************************************************** +// | api | scene 1 | scene 2 | scene 3 | scene 4 | +// **************************************************************************** +// |check_row_locked | 1002 + 1001 | 1002 | 1001 | ERROR | +// |check_sql_sequence_can_read | 1002 + 1001 | 1002 | 1001 | ERROR | +// |lock_for_read | 1002 + 1001 | 1002 | 1001 | ERROR | +// |get_tx_state_with_log_ts | 1002 | 1002 | 1001 | ERROR | +// |cleanout_tx_node | 1002 + 1001 | 1002 | 1001 | ERROR | +// **************************************************************************** + +int ObTxTableGuards::check_row_locked( + const transaction::ObTransID &read_tx_id, + const transaction::ObTransID &data_tx_id, + const int64_t sql_sequence, + const share::SCN &scn, + storage::ObStoreRowLockState &lock_state) +{ + int ret = OB_SUCCESS; + bool dest_succ = false; + if (!is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tx table guard is invalid", K(ret), K(data_tx_id), K(tx_table_guard_)); + } else if (OB_SUCC(tx_table_guard_.check_row_locked(read_tx_id, data_tx_id, sql_sequence, lock_state))) { + dest_succ = true; + } else if (OB_TRANS_CTX_NOT_EXIST != ret || !is_need_read_src(scn)) { + LOG_WARN("failed to check row locked", K(ret), K(data_tx_id), K(*this)); + } else { + ret = OB_SUCCESS; + } + + if (OB_FAIL(ret)) { + } else if (lock_state.is_locked_ || !is_need_read_src(scn)) { + // do nothing + } else { + storage::ObStoreRowLockState src_lock_state; + if (OB_FAIL(src_tx_table_guard_.check_row_locked(read_tx_id, data_tx_id, sql_sequence, src_lock_state))) { + if (dest_succ && OB_TRANS_CTX_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("trans ctx is not exist", K(data_tx_id)); + } else { + LOG_WARN("failed to check row locked", K(ret), K(data_tx_id), K(*this)); + } + } else { + lock_state = src_lock_state; + } + PRINT_ERROR_LOG(data_tx_id, ret, this); + } + + return ret; +} + +// dest_succ is true or false, indicating whether the transaction status information is queried in tx_table_guard +// can_read is true or false, indicating whether the queried transaction is readable, and it is the output parameter of the interface; +// case 1: dest_succ = true, can_read = false; The transaction is unreadable, in this case, only dest tx_table_guard can be read; +// case 2: dest_succ = true, can_read = true; There is a readable transaction, in this case, both src tx_table_guard and dest tx_table_guard are read; +// case 3: dest_succ = false; The transaction does not exist on dest, in this case, both src tx_table_guard and dest tx_table_guard are read; +// If the conditions of case 2 and case 3 are met, but scn > transfer_start_scn, only read dest tx_table_guard; +// The interface lock_for_read also applies this logic. +int ObTxTableGuards::check_sql_sequence_can_read( + const transaction::ObTransID &data_tx_id, + const int64_t sql_sequence, + const share::SCN &scn, + bool &can_read) +{ + int ret = OB_SUCCESS; + bool src_can_read = false; + bool dest_succ = false; + can_read = false; + if (!is_valid() || !scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tx table guard is invalid", K(ret), KPC(this), K(data_tx_id), K(scn)); + } else if (OB_SUCC(tx_table_guard_.check_sql_sequence_can_read(data_tx_id, sql_sequence, can_read))) { + dest_succ = true; + } else if (OB_TRANS_CTX_NOT_EXIST != ret || !is_need_read_src(scn)) { + LOG_WARN("failed to check sql sepuence can read", K(ret), K(data_tx_id), K(*this)); + } else { + ret = OB_SUCCESS; + } + // Both tx_table_guard need to be checked + if (OB_FAIL(ret)) { + } else if ((dest_succ && !can_read) || !is_need_read_src(scn)) { + // do nothing + } else { + if (OB_FAIL(src_tx_table_guard_.check_sql_sequence_can_read(data_tx_id, sql_sequence, src_can_read))) { + if (dest_succ && OB_TRANS_CTX_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("trans ctx is not exist", K(data_tx_id)); + } else { + LOG_WARN("failed to check sql sepuence can read from source tx table", K(ret), K(data_tx_id), K(*this)); + } + } else { + can_read = src_can_read; + } + PRINT_ERROR_LOG(data_tx_id, ret, this); + } + + return ret; +} + +int ObTxTableGuards::get_tx_state_with_scn( + const transaction::ObTransID &data_trans_id, + const share::SCN scn, + int64_t &state, + share::SCN &trans_version) +{ + int ret = OB_SUCCESS; + if (!is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tx table guard is invalid", K(ret), KPC(this), K(data_trans_id)); + } else if (OB_SUCC(tx_table_guard_.get_tx_state_with_scn(data_trans_id, scn, state, trans_version))) { + } else if (OB_TRANS_CTX_NOT_EXIST != ret || !is_need_read_src(scn)) { + LOG_WARN("failed to get tx state with log ts", K(ret), K(data_trans_id), K(*this)); + } else { + if (OB_FAIL(src_tx_table_guard_.get_tx_state_with_scn(data_trans_id, scn, state, trans_version))) { + LOG_WARN("failed to get tx state with log ts from source tx table", K(ret), K(data_trans_id), K(*this)); + } + PRINT_ERROR_LOG(data_trans_id, ret, this); + } + return ret; +} + +int ObTxTableGuards::lock_for_read( + const transaction::ObLockForReadArg &lock_for_read_arg, + bool &can_read, + share::SCN &trans_version, + bool &is_determined_state, + ObCleanoutOp &cleanout_op, + ObReCheckOp &recheck_op) +{ + int ret = OB_SUCCESS; + bool dest_succ = false; + can_read = false; + if (!is_valid() || !lock_for_read_arg.scn_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tx table guard is invalid", K(ret), KPC(this), K(lock_for_read_arg)); + } else if (OB_SUCC(tx_table_guard_.lock_for_read(lock_for_read_arg, + can_read, trans_version, is_determined_state, cleanout_op, recheck_op))) { + dest_succ = true; + } else if (OB_TRANS_CTX_NOT_EXIST != ret || !is_need_read_src(lock_for_read_arg.scn_)) { + LOG_WARN("failed to lock for read", K(ret), "tx_id", lock_for_read_arg.data_trans_id_, K(*this)); + } else { + ret = OB_SUCCESS; + } + + if (OB_FAIL(ret)) { + } else if ((dest_succ && !can_read) || !is_need_read_src(lock_for_read_arg.scn_)) { + // do nothing + } else { + // Both tx_table_guard need to be checked + bool src_can_read = false; + share::SCN src_trans_version = share::SCN::invalid_scn(); + bool src_is_determined_state = false; + if (OB_FAIL(src_tx_table_guard_.lock_for_read(lock_for_read_arg, + src_can_read, src_trans_version, src_is_determined_state, cleanout_op, recheck_op))) { + if (dest_succ && OB_TRANS_CTX_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("trans ctx is not exist", K(lock_for_read_arg)); + } else { + LOG_WARN("failed to lock for read from source tx table", K(ret), "tx_id", lock_for_read_arg.data_trans_id_, K(*this)); + } + } else { + can_read = src_can_read; + trans_version = src_trans_version; + is_determined_state = src_is_determined_state; + } + PRINT_ERROR_LOG(lock_for_read_arg.data_trans_id_, ret, this); + } + + return ret; +} + +int ObTxTableGuards::lock_for_read( + const transaction::ObLockForReadArg &lock_for_read_arg, + bool &can_read, + share::SCN &trans_version, + bool &is_determined_state) +{ + int ret = OB_SUCCESS; + bool dest_succ = false; + if (!tx_table_guard_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tx table guard is invalid", K(ret), K(tx_table_guard_)); + } else if (OB_SUCC(tx_table_guard_.lock_for_read(lock_for_read_arg, + can_read, trans_version, is_determined_state))) { + dest_succ = true; + } else if (OB_TRANS_CTX_NOT_EXIST != ret || !is_need_read_src(lock_for_read_arg.scn_)) { + LOG_WARN("failed to lock for read", K(ret), "tx_id", lock_for_read_arg.data_trans_id_, K(*this)); + } else { + ret = OB_SUCCESS; + } + if (OB_FAIL(ret)) { + } else if ((dest_succ && !can_read) || !is_need_read_src(lock_for_read_arg.scn_)) { + } else { + bool src_can_read = false; + share::SCN src_trans_version = share::SCN::invalid_scn(); + bool src_is_determined_state = false; + if (OB_FAIL(src_tx_table_guard_.lock_for_read(lock_for_read_arg, + src_can_read, src_trans_version, src_is_determined_state))) { + if (dest_succ && OB_TRANS_CTX_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("trans ctx is not exist", K(lock_for_read_arg)); + } else { + LOG_WARN("failed to lock for read from source tx table", K(ret), "tx_id", lock_for_read_arg.data_trans_id_, K(*this)); + } + } else { + can_read = src_can_read; + trans_version = src_trans_version; + is_determined_state = src_is_determined_state; + } + PRINT_ERROR_LOG(lock_for_read_arg.data_trans_id_, ret, this); + } + return ret; +} + +int ObTxTableGuards::cleanout_tx_node( + const transaction::ObTransID &tx_id, + memtable::ObMvccRow &value, + memtable::ObMvccTransNode &tnode, + const bool need_row_latch) +{ + int ret = OB_SUCCESS; + bool dest_succ = false; + if (!is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tx table guard is invalid", K(ret), KPC(this), K(tx_id)); + } else if (OB_SUCC(tx_table_guard_.cleanout_tx_node(tx_id, value, tnode, need_row_latch))) { + dest_succ = true; + } else if (OB_TRANS_CTX_NOT_EXIST != ret || !is_need_read_src(tnode.get_scn())) { + LOG_WARN("failed to cleanout tx node", K(ret), K(tx_id), K(*this)); + } else { + ret = OB_SUCCESS; + } + if (OB_FAIL(ret)) { + } else if (!is_need_read_src(tnode.get_scn())) { + // do nothing + } else { + if (OB_FAIL(src_tx_table_guard_.cleanout_tx_node(tx_id, value, tnode, need_row_latch))) { + if (dest_succ && OB_TRANS_CTX_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("trans ctx is not exist", K(tx_id)); + } else { + LOG_WARN("failed to cleanout tx nod from source tx table", K(ret), K(tx_id), K(*this)); + } + } + PRINT_ERROR_LOG(tx_id, ret, this); + } + return ret; +} + +bool ObTxTableGuards::check_ls_offline() +{ + bool discover_ls_offline = false; + if (!src_tx_table_guard_.is_valid()) { + discover_ls_offline = tx_table_guard_.check_ls_offline(); + } else { + discover_ls_offline = tx_table_guard_.check_ls_offline() && src_tx_table_guard_.check_ls_offline(); + } + return discover_ls_offline; +} + +// scn: sstable is end_scn, memtable is ObMvccTransNode scn +// src_tx_table_guard_ and transfer_start_scn_ are valid, indicating that it is an operation during the transfer process. +// By comparing the size of scn and transfer_start_scn_, you can indirectly determine which log stream the data corresponding to this transaction belongs to. +// scn <= transfer_start_scn_ : the data is on the src ls of the transfer, you need to read src_tx_table_guard_. +// scn > transfer_start_scn_ : the data is on the dest ls of the transfer, you need to check tx_table_guard_. +bool ObTxTableGuards::is_need_read_src(const share::SCN scn) const +{ + bool is_need = false; + if (src_tx_table_guard_.is_valid() + && transfer_start_scn_.is_valid() + && scn.is_valid() + && !scn.is_max() + && scn <= transfer_start_scn_) { + is_need = true; + LOG_INFO("need read src", K(scn), KPC(this), K(is_need)); + } + return is_need; +} + + +} // end namespace oceanbase +} diff --git a/src/storage/tx_table/ob_tx_table_guards.h b/src/storage/tx_table/ob_tx_table_guards.h new file mode 100644 index 000000000..ba0204df0 --- /dev/null +++ b/src/storage/tx_table/ob_tx_table_guards.h @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2021 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_STORAGE_OB_TRANS_TABLE_GUARDS_ +#define OCEANBASE_STORAGE_OB_TRANS_TABLE_GUARDS_ + +#include "lib/ob_define.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/utility/ob_print_utils.h" +#include "lib/function/ob_function.h" +#include "share/scn.h" +#include "storage/tx_table/ob_tx_table_interface.h" + +namespace oceanbase +{ +namespace transaction { +class ObLockForReadArg; +class ObTransID; +} +namespace memtable +{ +class ObMvccRow; +class ObMvccTransNode; +} +namespace storage +{ +class ObStoreRowLockState; +class ObTxData; +class ObTxCCCtx; +class ObCleanoutNothingOperation; +class ObReCheckNothingOperation; +class ObCleanoutOp; +class ObReCheckOp; +class ObTxTableGuards +{ +public: + ObTxTableGuards() + : tx_table_guard_(), + src_tx_table_guard_(), + transfer_start_scn_(share::SCN::invalid_scn()) {} + ~ObTxTableGuards() { reset(); } + void reset() + { + tx_table_guard_.reset(); + src_tx_table_guard_.reset(); + transfer_start_scn_.reset(); + } + void reuse() + { + tx_table_guard_.reuse(); + src_tx_table_guard_.reuse(); + } + bool is_valid() const { return tx_table_guard_.is_valid() && (src_tx_table_guard_.is_valid() == transfer_start_scn_.is_valid()); } + /** + * @brief check whether the row key is locked by tx id + * + * @param[in] read_trans_id + * @param[in] data_trans_id + * @param[in] sql_sequence + * @param[out] lock_state + */ + int check_row_locked( + const transaction::ObTransID &read_tx_id, + const transaction::ObTransID &data_tx_id, + const int64_t sql_sequence, + const share::SCN &scn, + storage::ObStoreRowLockState &lock_state); + /** + * @brief check whether transaction data_tx_id with sql_sequence is readable. (sql_sequence may be unreadable for txn or stmt rollback) + * + * @param[in] data_tx_id + * @param[in] sql_sequence + * @param[in] scn + * @param[out] can_read + */ + int check_sql_sequence_can_read( + const transaction::ObTransID &data_tx_id, + const int64_t sql_sequence, + const share::SCN &scn, + bool &can_read); + /** + * @brief fetch the state of txn DATA_TRANS_ID when replaying to LOG_TS the requirement can be seen from + * + * + * @param[in] data_trans_id + * @param[in] scn + * @param[out] state + * @param[out] trans_version + */ + int get_tx_state_with_scn( + const transaction::ObTransID &data_trans_id, + const share::SCN scn, + int64_t &state, + share::SCN &trans_version); + /** + * @brief the txn READ_TRANS_ID use SNAPSHOT_VERSION to read the data, and check whether the data is locked, readable or unreadable by txn DATA_TRANS_ID. READ_LATEST is used to check whether read the data belong to the same txn + * + * @param[in] lock_for_read_arg + * @param[out] can_read + * @param[out] trans_version + * @param[out] is_determined_state + * @param[in] op + */ + int lock_for_read( + const transaction::ObLockForReadArg &lock_for_read_arg, + bool &can_read, + share::SCN &trans_version, + bool &is_determined_state, + ObCleanoutOp &cleanout_op, + ObReCheckOp &recheck_op); + + int lock_for_read( + const transaction::ObLockForReadArg &lock_for_read_arg, + bool &can_read, + share::SCN &trans_version, + bool &is_determined_state); + /** + * @brief cleanout the tx state when encountering the uncommitted node. The node will be cleaned out if the state of + * the txn is decided or prepared. You neeed notice that txn commit or abort is pereformed both on mvcc row and mvcc + * txn node. And need row latch is used for lock_for_read to shorten critical path. + * + * @param[in] tx_id + * @param[in] value + * @param[in] tnode + * @param[in] need_row_latch + */ + int cleanout_tx_node( + const transaction::ObTransID &tx_id, + memtable::ObMvccRow &value, + memtable::ObMvccTransNode &tnode, + const bool need_row_latch); + bool check_ls_offline(); + bool is_need_read_src(const share::SCN scn) const; + TO_STRING_KV(K_(tx_table_guard), K_(src_tx_table_guard), K_(transfer_start_scn)); +public: + storage::ObTxTableGuard tx_table_guard_; + // transfer_start_scn_ and src_tx_table_guard_ need to be valid at the same time. + // dml executed during transfer, src_tx_table_guard_ will be valid. + storage::ObTxTableGuard src_tx_table_guard_; + share::SCN transfer_start_scn_; // Use transfer_start_scn to judge whether you need to read src_tx_table_guard +}; + +} // namespace storage +} // namespace oceanbase + +#endif diff --git a/src/storage/tx_table/ob_tx_table_interface.h b/src/storage/tx_table/ob_tx_table_interface.h index 26ae95d20..0364baed2 100644 --- a/src/storage/tx_table/ob_tx_table_interface.h +++ b/src/storage/tx_table/ob_tx_table_interface.h @@ -52,7 +52,7 @@ public: } int init(ObTxTable *tx_table); - bool is_valid() const { return nullptr != tx_table_ ? true : false; } + bool is_valid() const { return nullptr != tx_table_; } ObTxTable *get_tx_table() const { return tx_table_; } diff --git a/src/storage/tx_table/ob_tx_table_iterator.cpp b/src/storage/tx_table/ob_tx_table_iterator.cpp index 1b85a24a3..da14a5227 100644 --- a/src/storage/tx_table/ob_tx_table_iterator.cpp +++ b/src/storage/tx_table/ob_tx_table_iterator.cpp @@ -415,32 +415,33 @@ int ObTxDataSingleRowGetter::init(const transaction::ObTransID &tx_id) int ObTxDataSingleRowGetter::get_next_row(ObTxData &tx_data) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(!iter_param_.tablet_handle_.is_valid())) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "Unexpected invalid tablet handle", K(ret), K(iter_param_.tablet_handle_)); + if (sstables_.empty()) { + ret = OB_ITER_END; + STORAGE_LOG(WARN, "This tablet does not have sstables.", KR(ret)); } else { - ObTabletTableStore &table_store = iter_param_.tablet_handle_.get_obj()->get_table_store(); - ObSSTableArray &sstables = table_store.get_minor_sstables(); - - if (sstables.empty()) { - ret = OB_ITER_END; - STORAGE_LOG(WARN, "This tablet does not have sstables.", KR(ret), K(table_store)); - } else { - tx_data_buffers_.reset(); - ret = get_next_row_(sstables, tx_data); - if (OB_TIMEOUT == ret || OB_DISK_HUNG == ret) { - ret = OB_EAGAIN; - STORAGE_LOG(WARN, "modify ret code from OB_TIMEOUT or OB_DISK_HUNG to OB_EAGAIN", KR(ret)); - } else if (OB_FAIL(ret)) { - recycled_scn_ = static_cast(sstables[0])->get_filled_tx_scn(); - STORAGE_LOG(WARN, "get tx data from sstable failed", K(recycled_scn_)); + tx_data_buffers_.reset(); + ret = get_next_row_(sstables_, tx_data); + if (OB_TIMEOUT == ret || OB_DISK_HUNG == ret) { + ret = OB_EAGAIN; + STORAGE_LOG(WARN, + "modify ret code from OB_TIMEOUT or OB_DISK_HUNG to OB_EAGAIN", + KR(ret)); + } else if (OB_FAIL(ret)) { + ObSSTableMetaHandle sst_meta_handle; + int tmp_ret = static_cast(sstables_[0])->get_meta(sst_meta_handle); + if (OB_TMP_FAIL(tmp_ret)) { + STORAGE_LOG(WARN, "get sstable meta handle failed", KR(tmp_ret)); + recycled_scn_.set_invalid(); + } else { + recycled_scn_ = sst_meta_handle.get_sstable_meta().get_filled_tx_scn(); } + STORAGE_LOG(WARN, "get tx data from sstable failed", KR(ret), KR(tmp_ret), K(recycled_scn_)); } } return ret; } -int ObTxDataSingleRowGetter::get_next_row_(ObSSTableArray &sstables, ObTxData &tx_data) +int ObTxDataSingleRowGetter::get_next_row_(const ObSSTableArray &sstables, ObTxData &tx_data) { int ret = OB_SUCCESS; @@ -503,7 +504,7 @@ int ObTxDataSingleRowGetter::get_next_row_(ObSSTableArray &sstables, ObTxData &t } int ObTxDataSingleRowGetter::get_row_from_sstables_(blocksstable::ObDatumRowkey &row_key, - ObSSTableArray &sstables, + const ObSSTableArray &sstables, const ObTableIterParam &iter_param, ObTableAccessContext &access_context, ObStringHolder &temp_buffer, @@ -512,15 +513,22 @@ int ObTxDataSingleRowGetter::get_row_from_sstables_(blocksstable::ObDatumRowkey int ret = OB_SUCCESS; ObStoreRowIterator *row_iter = nullptr; - ObITable *table = nullptr; + ObSSTable *table = nullptr; int tmp_ret = OB_SUCCESS; bool find = false; const blocksstable::ObDatumRow *row = nullptr; for (int i = sstables.count() - 1; OB_SUCC(ret) && !find && i >= 0; i--) { + ObStorageMetaHandle sstable_handle; if (OB_ISNULL(table = sstables[i])) { ret = OB_ERR_SYS; STORAGE_LOG(ERROR, "Unexpected null table", KR(ret), K(i), K(sstables)); - } else if (OB_FAIL(table->get(iter_param, access_context, row_key, row_iter))) { + } else if (table->is_loaded()) { + } else if (OB_FAIL(ObTabletTableStore::load_sstable(table->get_addr(), sstable_handle))) { + STORAGE_LOG(WARN, "fail to load sstable", K(ret), KPC(table)); + } else if (OB_FAIL(sstable_handle.get_sstable(table))) { + STORAGE_LOG(WARN, "fail to get sstable", K(ret), K(sstable_handle)); + } + if (FAILEDx(table->get(iter_param, access_context, row_key, row_iter))) { STORAGE_LOG(WARN, "Failed to get param", KR(ret), KPC(table)); } else if (OB_FAIL(row_iter->get_next_row(row))) { if (OB_ITER_END != ret) { @@ -612,10 +620,7 @@ int ObCommitVersionsGetter::get_next_row(ObCommitVersionsArray &commit_versions) if (OB_SUCC(ret)) { ObStoreRowIterator *row_iter = nullptr; const ObDatumRow *row = nullptr; - if (!iter_param_.tablet_handle_.is_valid()) { - ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(ERROR, "tablet handle in iter param is invalid", KR(ret), K(iter_param_)); - } else if (OB_FAIL(table_->get(iter_param_, access_context, row_key, row_iter))) { + if (OB_FAIL(table_->get(iter_param_, access_context, row_key, row_iter))) { STORAGE_LOG(WARN, "Failed to get param", K(ret), KPC(table_)); } else if (OB_FAIL(row_iter->get_next_row(row))) { STORAGE_LOG(ERROR, "Failed to get pre-process data for upper trans version calculation", diff --git a/src/storage/tx_table/ob_tx_table_iterator.h b/src/storage/tx_table/ob_tx_table_iterator.h index 75da8564d..5b420792e 100644 --- a/src/storage/tx_table/ob_tx_table_iterator.h +++ b/src/storage/tx_table/ob_tx_table_iterator.h @@ -172,10 +172,12 @@ class ObTxDataSingleRowGetter { using SliceAllocator = ObSliceAlloc; public: - ObTxDataSingleRowGetter(const ObTableIterParam &iter_param, - SliceAllocator &slice_allocator, - share::SCN &recycled_scn) - : iter_param_(iter_param), slice_allocator_(slice_allocator), recycled_scn_(recycled_scn), key_datums_() {} + ObTxDataSingleRowGetter( + const ObTableIterParam &iter_param, + const ObSSTableArray &sstables, + SliceAllocator &slice_allocator, + share::SCN &recycled_scn) + : iter_param_(iter_param), sstables_(sstables), slice_allocator_(slice_allocator), recycled_scn_(recycled_scn), key_datums_() {} virtual ~ObTxDataSingleRowGetter() {} /** @@ -187,9 +189,9 @@ public: int get_next_row(ObTxData &tx_data); private: - int get_next_row_(ObSSTableArray &sstables, ObTxData &tx_data); + int get_next_row_(const ObSSTableArray &sstables, ObTxData &tx_data); int get_row_from_sstables_(blocksstable::ObDatumRowkey &row_key, - ObSSTableArray &sstables, + const ObSSTableArray &sstables, const ObTableIterParam &iter_param, ObTableAccessContext &access_context, ObStringHolder &temp_buffer, @@ -198,6 +200,7 @@ private: private: const ObTableIterParam &iter_param_; + const ObSSTableArray &sstables_; SliceAllocator &slice_allocator_; share::SCN &recycled_scn_; transaction::ObTransID tx_id_; diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result index 1f15093bc..e2cab7f9b 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result @@ -158,6 +158,7 @@ ob_ssl_invited_common_names ob_startup_mode open_cursors opt_tab_stat_cache_priority +partition_balance_schedule_interval plan_cache_evict_interval plan_cache_high_watermark plan_cache_low_watermark @@ -206,6 +207,7 @@ stack_size standby_db_fetch_log_rpc_timeout standby_db_preferred_upstream_log_region standby_fetch_log_bandwidth_limit +storage_meta_cache_priority syslog_io_bandwidth_limit syslog_level system_memory @@ -247,6 +249,7 @@ _audit_mode _backup_idle_time _backup_task_keep_alive_interval _backup_task_keep_alive_timeout +_balance_kill_transaction_threshold _bloom_filter_enabled _bloom_filter_ratio _cache_wash_interval @@ -257,6 +260,7 @@ _datafile_usage_upper_bound_percentage _data_storage_io_timeout _enable_adaptive_compaction _enable_backtrace_function +_enable_balance_kill_transaction _enable_block_file_punch_hole _enable_compaction_diagnose _enable_convert_real_to_decimal @@ -358,6 +362,12 @@ _sqlexec_disable_hash_based_distagg_tiv _storage_meta_memory_limit_percentage _temporary_file_io_area_size _trace_control_info +_transfer_finish_trans_timeout +_transfer_process_lock_tx_timeout +_transfer_service_wakeup_interval +_transfer_start_retry_count +_transfer_start_rpc_timeout +_transfer_start_trans_timeout _tx_result_retention _upgrade_stage _wait_interval_after_truncate diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/inner_table_overall.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/inner_table_overall.result index e2937b1fb..33d571063 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/inner_table_overall.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/inner_table_overall.result @@ -216,6 +216,12 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 412 __all_service_epoch 0 201001 1 413 __all_spatial_reference_systems 0 201001 1 416 __all_column_checksum_error_info 0 201001 1 +423 __all_transfer_task 0 201001 1 +424 __all_transfer_task_history 0 201001 1 +425 __all_balance_job 0 201001 1 +426 __all_balance_job_history 0 201001 1 +427 __all_balance_task 0 201001 1 +428 __all_balance_task_history 0 201001 1 429 __all_arbitration_service 0 201001 1 430 __all_ls_arb_replica_task 0 201001 1 431 __all_data_dictionary_in_log 0 201001 1 @@ -233,9 +239,11 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 443 __all_tenant_rewrite_rules 0 201001 1 444 __all_reserved_snapshot 0 201001 1 445 __all_cluster_event_history 0 201001 1 +446 __all_ls_transfer_member_list_lock_info 0 201001 1 450 __all_external_table_file 0 201001 1 451 __all_task_opt_stat_gather_history 0 201001 1 452 __all_table_opt_stat_gather_history 0 201001 1 +459 __all_balance_task_helper 0 201001 1 10001 __tenant_virtual_all_table 2 201001 1 10002 __tenant_virtual_table_column 2 201001 1 10003 __tenant_virtual_table_index 2 201001 1 @@ -570,6 +578,12 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 12339 __all_virtual_show_trace 2 201001 1 12340 __all_virtual_ha_diagnose 2 201001 1 12341 __all_virtual_data_dictionary_in_log 2 201001 1 +12342 __all_virtual_transfer_task 2 201001 1 +12343 __all_virtual_transfer_task_history 2 201001 1 +12344 __all_virtual_balance_job 2 201001 1 +12345 __all_virtual_balance_job_history 2 201001 1 +12346 __all_virtual_balance_task 2 201001 1 +12347 __all_virtual_balance_task_history 2 201001 1 12348 __all_virtual_rls_policy 2 201001 1 12349 __all_virtual_rls_policy_history 2 201001 1 12350 __all_virtual_rls_security_column 2 201001 1 @@ -589,6 +603,8 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 12366 __all_virtual_archive_dest_status 2 201001 1 12369 __all_virtual_io_scheduler 2 201001 1 12371 __all_virtual_external_table_file 2 201001 1 +12373 __all_virtual_mds_node_stat 2 201001 1 +12374 __all_virtual_mds_event_history 2 201001 1 12376 __all_virtual_dup_ls_lease_mgr 2 201001 1 12378 __all_virtual_dup_ls_tablet_set 2 201001 1 12379 __all_virtual_dup_ls_tablets 2 201001 1 @@ -600,9 +616,13 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 12385 __all_virtual_arbitration_member_info 2 201001 1 12387 __all_virtual_arbitration_service_status 2 201001 1 12393 __all_virtual_virtual_long_ops_status_mysql_sys_agent 2 201001 1 +12394 __all_virtual_ls_transfer_member_list_lock_info 2 201001 1 12395 __all_virtual_timestamp_service 2 201001 1 +12396 __all_virtual_resource_pool_mysql_sys_agent 2 201001 1 12397 __all_virtual_px_p2p_datahub 2 201001 1 12400 __all_virtual_ls_log_restore_status 2 201001 1 +12401 __all_virtual_tenant_parameter 2 201001 1 +12405 __all_virtual_tablet_buffer_info 2 201001 1 20001 GV$OB_PLAN_CACHE_STAT 1 201001 1 20002 GV$OB_PLAN_CACHE_PLAN_STAT 1 201001 1 20003 SCHEMATA 1 201002 1 @@ -911,6 +931,18 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 21401 CDB_OB_LOG_RESTORE_SOURCE 1 201001 1 21402 DBA_OB_LOG_RESTORE_SOURCE 1 201001 1 21404 V$OB_TIMESTAMP_SERVICE 1 201001 1 +21405 DBA_OB_BALANCE_JOBS 1 201001 1 +21406 CDB_OB_BALANCE_JOBS 1 201001 1 +21407 DBA_OB_BALANCE_JOB_HISTORY 1 201001 1 +21408 CDB_OB_BALANCE_JOB_HISTORY 1 201001 1 +21409 DBA_OB_BALANCE_TASKS 1 201001 1 +21410 CDB_OB_BALANCE_TASKS 1 201001 1 +21411 DBA_OB_BALANCE_TASK_HISTORY 1 201001 1 +21412 CDB_OB_BALANCE_TASK_HISTORY 1 201001 1 +21413 DBA_OB_TRANSFER_TASKS 1 201001 1 +21414 CDB_OB_TRANSFER_TASKS 1 201001 1 +21415 DBA_OB_TRANSFER_TASK_HISTORY 1 201001 1 +21416 CDB_OB_TRANSFER_TASK_HISTORY 1 201001 1 21417 DBA_OB_EXTERNAL_TABLE_FILES 1 201001 1 21418 ALL_OB_EXTERNAL_TABLE_FILES 1 201001 1 21419 GV$OB_PX_P2P_DATAHUB 1 201001 1 diff --git a/tools/deploy/mysql_test/test_suite/meta_info/r/mysql/meta_build_in_func_test.result b/tools/deploy/mysql_test/test_suite/meta_info/r/mysql/meta_build_in_func_test.result index 65a84b45d..1729b456d 100644 --- a/tools/deploy/mysql_test/test_suite/meta_info/r/mysql/meta_build_in_func_test.result +++ b/tools/deploy/mysql_test/test_suite/meta_info/r/mysql/meta_build_in_func_test.result @@ -2203,6 +2203,7 @@ def str_to_date('04/30/2004 ', '%m/%d/%Y ') 10 10 10 Y 128 0 63 | 2004-04-30 | +-----------------------------------------+ +###ADD CASE select '+' + 1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def '+' + 1 5 23 1 N 32897 31 63 diff --git a/tools/deploy/mysql_test/test_suite/meta_info/t/meta_build_in_func_test.test b/tools/deploy/mysql_test/test_suite/meta_info/t/meta_build_in_func_test.test index 5cbc4759f..be54fd726 100644 --- a/tools/deploy/mysql_test/test_suite/meta_info/t/meta_build_in_func_test.test +++ b/tools/deploy/mysql_test/test_suite/meta_info/t/meta_build_in_func_test.test @@ -422,6 +422,7 @@ select str_to_date('04/30/2004 ', '%m/%d/%Y '); #select date_add(str_to_date(substr('2014-06-05 16:24:54.270374',1,8),'%Y%m%d'),interval 2 day); #--error 16 #select str_to_date('2014-06-','%Y%m%d'); +###ADD CASE #--error 5085 select '+' + 1; #--error 5085 diff --git a/tools/ob_admin/backup_tool/ob_admin_dump_backup_data_executor.cpp b/tools/ob_admin/backup_tool/ob_admin_dump_backup_data_executor.cpp index 8ccbc1d4b..c0bbc8b42 100644 --- a/tools/ob_admin/backup_tool/ob_admin_dump_backup_data_executor.cpp +++ b/tools/ob_admin/backup_tool/ob_admin_dump_backup_data_executor.cpp @@ -175,6 +175,32 @@ int ObAdminDumpBackupDataUtil::read_index_file_trailer(const common::ObString &b return ret; } +int ObAdminDumpBackupDataUtil::read_tablet_metas_file_trailer(const common::ObString &backup_path, + const common::ObString &storage_info_str, backup::ObTabletInfoTrailer &tablet_meta_trailer) +{ + int ret = OB_SUCCESS; + int64_t file_length = 0; + char *buf = NULL; + ObArenaAllocator allocator; + ObBackupSerializeHeaderWrapper serializer_wrapper(&tablet_meta_trailer); + const int64_t trailer_len = serializer_wrapper.get_serialize_size(); + int64_t pos = 0; + if (OB_FAIL(get_backup_file_length(backup_path, storage_info_str, file_length))) { + STORAGE_LOG(WARN, "failed to get file length", K(ret), K(backup_path), K(storage_info_str)); + } else if (OB_UNLIKELY(file_length <= trailer_len)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "backup index file too small", K(ret), K(file_length), K(trailer_len)); + } else if (OB_ISNULL(buf = static_cast(allocator.alloc(trailer_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "failed to alloc memory", K(ret), K(trailer_len)); + } else if (OB_FAIL(pread_file(backup_path, storage_info_str, file_length - trailer_len, trailer_len, buf))) { + STORAGE_LOG(WARN, "failed to pread file", K(ret), K(backup_path), K(storage_info_str), K(file_length), K(trailer_len)); + } else if (OB_FAIL(serializer_wrapper.deserialize(buf, trailer_len, pos))) { + STORAGE_LOG(WARN, "failed to deserialize.", K(ret)); + } + return ret; +} + int ObAdminDumpBackupDataUtil::pread_file(const common::ObString &backup_path, const common::ObString &storage_info_str, const int64_t offset, const int64_t read_size, char *buf) { @@ -793,6 +819,12 @@ int ObAdminDumpBackupDataExecutor::do_execute_() } break; } + case share::ObBackupFileType::BACKUP_TABLET_METAS_INFO: { + if (OB_FAIL(print_ls_tablet_meta_tablets_())) { + STORAGE_LOG(WARN, "failed to print ls tablet meta tablets", K(ret)); + } + break; + } default: { ret = OB_ERR_SYS; STORAGE_LOG(WARN, "invalid type", K(ret), K_(file_type)); @@ -915,10 +947,10 @@ int ObAdminDumpBackupDataExecutor::dump_tenant_backup_path_() { int ret = OB_SUCCESS; ObBackupIoAdapter util; - share::ObBackupSetFilter op; + storage::ObBackupSetFilter op; share::ObBackupPath path; share::ObBackupStorageInfo storage_info; - share::ObTenantBackupSetInfosDesc tenant_backup_set_infos; + storage::ObTenantBackupSetInfosDesc tenant_backup_set_infos; ObSArray backup_set_array; ObArray target_backup_set; if (OB_FAIL(get_backup_set_placeholder_dir_path(path))) { @@ -930,7 +962,7 @@ int ObAdminDumpBackupDataExecutor::dump_tenant_backup_path_() } else if (OB_FAIL(op.get_backup_set_array(backup_set_array))) { STORAGE_LOG(WARN, "fail to get backup set names", K(ret)); } else { - share::ObBackupDataStore::ObBackupSetDescComparator cmp; + storage::ObBackupDataStore::ObBackupSetDescComparator cmp; std::sort(backup_set_array.begin(), backup_set_array.end(), cmp); for (int64_t i = backup_set_array.count() - 1; i >= 0; i--) { path.reset(); @@ -1276,7 +1308,7 @@ int ObAdminDumpBackupDataExecutor::print_meta_index_index_list_() int ObAdminDumpBackupDataExecutor::print_ls_attr_info_() { int ret = OB_SUCCESS; - share::ObBackupDataLSAttrDesc ls_attr_desc; + storage::ObBackupDataLSAttrDesc ls_attr_desc; if (OB_FAIL(inner_print_common_header_(backup_path_, storage_info_))) { STORAGE_LOG(WARN, "fail to inner print common header", K(ret)); } else if (OB_FAIL(ObAdminDumpBackupDataUtil::read_backup_info_file(ObString(backup_path_), ObString(storage_info_), ls_attr_desc))) { @@ -1296,14 +1328,14 @@ int ObAdminDumpBackupDataExecutor::print_ls_attr_info_() int ObAdminDumpBackupDataExecutor::print_tablet_to_ls_info_() { int ret = OB_SUCCESS; - share::ObBackupDataTabletToLSDesc tablet_to_ls_desc; + storage::ObBackupDataTabletToLSDesc tablet_to_ls_desc; if (OB_FAIL(inner_print_common_header_(backup_path_, storage_info_))) { STORAGE_LOG(WARN, "fail to inner print common header", K(ret)); } else if (OB_FAIL(ObAdminDumpBackupDataUtil::read_backup_info_file(ObString(backup_path_), ObString(storage_info_), tablet_to_ls_desc))) { STORAGE_LOG(WARN, "fail to read tablet to ls info", K(ret), K(backup_path_), K(storage_info_)); } else { ARRAY_FOREACH_X(tablet_to_ls_desc.tablet_to_ls_, i , cnt, OB_SUCC(ret)) { - const share::ObBackupDataTabletToLSInfo tablet_to_ls = tablet_to_ls_desc.tablet_to_ls_.at(i); + const storage::ObBackupDataTabletToLSInfo tablet_to_ls = tablet_to_ls_desc.tablet_to_ls_.at(i); if (OB_FAIL(dump_tablet_to_ls_info_(tablet_to_ls))) { STORAGE_LOG(WARN, "fail to dump ls attr info", K(ret), K(tablet_to_ls)); } @@ -1316,14 +1348,14 @@ int ObAdminDumpBackupDataExecutor::print_tablet_to_ls_info_() int ObAdminDumpBackupDataExecutor::print_deleted_tablet_info_() { int ret = OB_SUCCESS; - share::ObBackupDeletedTabletToLSDesc deleted_tablet_to_ls; + storage::ObBackupDeletedTabletToLSDesc deleted_tablet_to_ls; if (OB_FAIL(inner_print_common_header_(backup_path_, storage_info_))) { STORAGE_LOG(WARN, "fail to inner print common header", K(ret)); } else if (OB_FAIL(ObAdminDumpBackupDataUtil::read_backup_info_file(ObString(backup_path_), ObString(storage_info_), deleted_tablet_to_ls))) { STORAGE_LOG(WARN, "fail to read tablet to ls info", K(ret), K(backup_path_), K(storage_info_)); } else { ARRAY_FOREACH_X(deleted_tablet_to_ls.deleted_tablet_to_ls_, i , cnt, OB_SUCC(ret)) { - const share::ObBackupDataTabletToLSInfo tablet_to_ls = deleted_tablet_to_ls.deleted_tablet_to_ls_.at(i); + const storage::ObBackupDataTabletToLSInfo tablet_to_ls = deleted_tablet_to_ls.deleted_tablet_to_ls_.at(i); if (OB_FAIL(dump_tablet_to_ls_info_(tablet_to_ls))) { STORAGE_LOG(WARN, "fail to dump ls attr info", K(ret), K(tablet_to_ls)); } @@ -1336,7 +1368,7 @@ int ObAdminDumpBackupDataExecutor::print_deleted_tablet_info_() int ObAdminDumpBackupDataExecutor::print_tenant_locality_info_() { int ret = OB_SUCCESS; - share::ObExternTenantLocalityInfoDesc locality_desc; + storage::ObExternTenantLocalityInfoDesc locality_desc; if (OB_FAIL(inner_print_common_header_(backup_path_, storage_info_))) { STORAGE_LOG(WARN, "fail to inner print common header", K(ret)); } else if (OB_FAIL(ObAdminDumpBackupDataUtil::read_backup_info_file(ObString(backup_path_), ObString(storage_info_), locality_desc))) { @@ -1350,7 +1382,7 @@ int ObAdminDumpBackupDataExecutor::print_tenant_locality_info_() int ObAdminDumpBackupDataExecutor::print_tenant_diagnose_info_() { int ret = OB_SUCCESS; - share::ObExternTenantDiagnoseInfoDesc diagnose_info; + storage::ObExternTenantDiagnoseInfoDesc diagnose_info; if (OB_FAIL(inner_print_common_header_(backup_path_, storage_info_))) { STORAGE_LOG(WARN, "fail to inner print common header", K(ret)); } else if (OB_FAIL(ObAdminDumpBackupDataUtil::read_backup_info_file(ObString(backup_path_), ObString(storage_info_), diagnose_info))) { @@ -1364,7 +1396,7 @@ int ObAdminDumpBackupDataExecutor::print_tenant_diagnose_info_() int ObAdminDumpBackupDataExecutor::print_backup_set_info_() { int ret = OB_SUCCESS; - share::ObExternBackupSetInfoDesc backup_set_info_desc; + storage::ObExternBackupSetInfoDesc backup_set_info_desc; if (OB_FAIL(inner_print_common_header_(backup_path_, storage_info_))) { STORAGE_LOG(WARN, "fail to inner print common header", K(ret)); } else if (OB_FAIL(ObAdminDumpBackupDataUtil::read_backup_info_file(ObString(backup_path_), ObString(storage_info_), backup_set_info_desc))) { @@ -1510,6 +1542,75 @@ int ObAdminDumpBackupDataExecutor::print_tenant_archive_piece_infos_file_() return ret; } +int ObAdminDumpBackupDataExecutor::print_ls_tablet_meta_tablets_() +{ + int ret = OB_SUCCESS; + backup::ObTabletInfoTrailer tablet_meta_trailer; + if (OB_FAIL(ObAdminDumpBackupDataUtil::read_tablet_metas_file_trailer(backup_path_, storage_info_, tablet_meta_trailer))) { + STORAGE_LOG(WARN, "failed to read tablet metas file trailer", K(ret)); + } else { + common::ObArenaAllocator allocator; + const int64_t DEFAULT_BUF_LEN = 2 * 1024 * 1024; // 2M + int64_t cur_buf_offset = tablet_meta_trailer.offset_; + int64_t cur_total_len = 0; + char *buf = nullptr; + while (OB_SUCC(ret) && cur_buf_offset < tablet_meta_trailer.length_) { + const uint64_t buf_len = tablet_meta_trailer.length_ - cur_buf_offset < DEFAULT_BUF_LEN ? + tablet_meta_trailer.length_ - cur_buf_offset : DEFAULT_BUF_LEN; + if (OB_ISNULL(buf = reinterpret_cast(allocator.alloc(buf_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "failed to alloc read buf", K(ret), K(buf_len)); + } else if (OB_FAIL(ObAdminDumpBackupDataUtil::pread_file(backup_path_, storage_info_, cur_buf_offset, buf_len, buf))) { + STORAGE_LOG(WARN, "failed to pread file", K(ret), K(backup_path_), K(storage_info_), K(cur_buf_offset), K(buf_len)); + } else { + backup::ObBackupTabletMeta tablet_meta; + blocksstable::ObBufferReader buffer_reader(buf, buf_len); + while (OB_SUCC(ret)) { + tablet_meta.reset(); + int64_t pos = 0; + const ObBackupCommonHeader *common_header = nullptr; + if (buffer_reader.remain() == 0) { + cur_total_len = buffer_reader.capacity(); + STORAGE_LOG(INFO, "read buf finish", K(buffer_reader)); + break; + } else if (OB_FAIL(buffer_reader.get(common_header))) { + STORAGE_LOG(WARN, "failed to get common_header", K(ret), K(backup_path_), K(buffer_reader)); + } else if (OB_ISNULL(common_header)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "common header is null", K(ret), K(backup_path_), K(buffer_reader)); + } else if (OB_FAIL(common_header->check_valid())) { + STORAGE_LOG(WARN, "common_header is not valid", K(ret), K(backup_path_), K(buffer_reader)); + } else if (common_header->data_zlength_ > buffer_reader.remain()) { + cur_total_len = buffer_reader.pos() - sizeof(ObBackupCommonHeader); + STORAGE_LOG(INFO, "buf not enough, wait later", K(cur_total_len), K(buffer_reader)); + break; + } else if (OB_FAIL(common_header->check_data_checksum(buffer_reader.current(), common_header->data_zlength_))) { + STORAGE_LOG(WARN, "failed to check data checksum", K(ret), K(*common_header), K(backup_path_), K(buffer_reader)); + } else if (OB_FAIL(tablet_meta.tablet_meta_.deserialize(buffer_reader.current(), common_header->data_zlength_, pos))) { + STORAGE_LOG(WARN, "failed to read data_header", K(ret), K(*common_header), K(backup_path_), K(buffer_reader)); + } else if (OB_FAIL(buffer_reader.advance(common_header->data_length_ + common_header->align_length_))) { + STORAGE_LOG(WARN, "failed to advance buffer", K(ret)); + } else { + tablet_meta.tablet_id_ = tablet_meta.tablet_meta_.tablet_id_; + if (OB_FAIL(dump_common_header_(*common_header))) { + STORAGE_LOG(WARN, "failed to dump common header", K(ret)); + } else if (OB_FAIL(dump_backup_tablet_meta_(tablet_meta))) { + STORAGE_LOG(WARN, "failed to dump backup tablet meta", K(ret)); + } + } + } + if (OB_SUCC(ret)) { + cur_buf_offset += cur_total_len; + } + } + } + if (OB_SUCC(ret) && OB_FAIL(dump_tablet_trailer_(tablet_meta_trailer))) { + STORAGE_LOG(WARN, "failed to inner print tablet trailer", K(ret)); + } + } + return ret; +} + int ObAdminDumpBackupDataExecutor::print_backup_format_file_() { int ret = OB_SUCCESS; @@ -1527,7 +1628,7 @@ int ObAdminDumpBackupDataExecutor::print_backup_format_file_() int ObAdminDumpBackupDataExecutor::print_tenant_backup_set_infos_() { int ret = OB_SUCCESS; - share::ObTenantBackupSetInfosDesc file_desc; + storage::ObTenantBackupSetInfosDesc file_desc; if (OB_FAIL(inner_print_common_header_(backup_path_, storage_info_))) { STORAGE_LOG(WARN, "fail to inner print common header", K(ret)); } else if (OB_FAIL(ObAdminDumpBackupDataUtil::read_backup_info_file(ObString(backup_path_), ObString(storage_info_), file_desc))) { @@ -1541,7 +1642,7 @@ int ObAdminDumpBackupDataExecutor::print_tenant_backup_set_infos_() int ObAdminDumpBackupDataExecutor::print_backup_ls_meta_infos_file_() { int ret = OB_SUCCESS; - share::ObBackupLSMetaInfosDesc file_desc; + storage::ObBackupLSMetaInfosDesc file_desc; if (OB_FAIL(inner_print_common_header_(backup_path_, storage_info_))) { STORAGE_LOG(WARN, "fail to inner print common header", K(ret)); } else if (OB_FAIL(ObAdminDumpBackupDataUtil::read_backup_info_file(ObString(backup_path_), ObString(storage_info_), file_desc))) { @@ -1900,6 +2001,18 @@ int ObAdminDumpBackupDataExecutor::dump_data_file_trailer_(const backup::ObBacku return ret; } +int ObAdminDumpBackupDataExecutor::dump_tablet_trailer_(const backup::ObTabletInfoTrailer &tablet_meta_trailer) +{ + int ret = OB_SUCCESS; + PrintHelper::print_dump_title("Tablet Meta Trailer"); + PrintHelper::print_dump_line("file_id", tablet_meta_trailer.file_id_); + PrintHelper::print_dump_line("tablet_count", tablet_meta_trailer.tablet_cnt_); + PrintHelper::print_dump_line("offset", tablet_meta_trailer.offset_); + PrintHelper::print_dump_line("length", tablet_meta_trailer.length_); + PrintHelper::print_end_line(); + return ret; +} + int ObAdminDumpBackupDataExecutor::dump_index_file_trailer_(const backup::ObBackupMultiLevelIndexTrailer &trailer) { int ret = OB_SUCCESS; @@ -2090,7 +2203,8 @@ int ObAdminDumpBackupDataExecutor::dump_backup_tablet_meta_(const backup::ObBack PrintHelper::print_dump_line("tablet_meta:ref_tablet_id", tablet_meta.tablet_meta_.ref_tablet_id_.id()); PrintHelper::print_dump_line("tablet_meta:clog_checkpoint_scn", tablet_meta.tablet_meta_.clog_checkpoint_scn_.get_val_for_logservice()); PrintHelper::print_dump_line("tablet_meta:ddl_checkpoint_scn", tablet_meta.tablet_meta_.ddl_checkpoint_scn_.get_val_for_logservice()); - PrintHelper::print_dump_line("tablet_meta:tablet_status", tablet_meta.tablet_meta_.tx_data_.tablet_status_); + // TODO yq: print migration param tablet status + // PrintHelper::print_dump_line("tablet_meta:tablet_status", tablet_meta.tablet_meta_.tx_data_.tablet_status_); PrintHelper::print_end_line(); return ret; } @@ -2152,25 +2266,25 @@ int ObAdminDumpBackupDataExecutor::dump_ls_attr_info_(const share::ObLSAttr &ls_ PrintHelper::print_dump_line("ls_group_id", ls_attr.get_ls_group_id()); PrintHelper::print_dump_line("flag", ls_attr.get_ls_flag().get_flag_value()); PrintHelper::print_dump_line("status", ls_attr.get_ls_status()); - PrintHelper::print_dump_line("operation_type", ls_attr.get_ls_operatin_type()); + PrintHelper::print_dump_line("operation_type", ls_attr.get_ls_operation_type()); return ret; } -int ObAdminDumpBackupDataExecutor::dump_tablet_to_ls_info_(const share::ObBackupDataTabletToLSInfo &tablet_to_ls_info) +int ObAdminDumpBackupDataExecutor::dump_tablet_to_ls_info_(const storage::ObBackupDataTabletToLSInfo &tablet_to_ls_info) { int ret = OB_SUCCESS; PrintHelper::print_dump_title("tablet_to_ls info"); PrintHelper::print_dump_line("ls_id", tablet_to_ls_info.ls_id_.id()); PrintHelper::print_dump_list_start("tablet_id"); ARRAY_FOREACH_X(tablet_to_ls_info.tablet_id_list_, i , cnt, OB_SUCC(ret)) { - const ObTabletID &tablet_id = tablet_to_ls_info.tablet_id_list_.at(i); + const common::ObTabletID &tablet_id = tablet_to_ls_info.tablet_id_list_.at(i); PrintHelper::print_dump_list_value(to_cstring(tablet_id.id()), i == cnt - 1); } PrintHelper::print_dump_list_end(); return ret; } -int ObAdminDumpBackupDataExecutor::dump_tenant_locality_info_(const share::ObExternTenantLocalityInfoDesc &locality_info) +int ObAdminDumpBackupDataExecutor::dump_tenant_locality_info_(const storage::ObExternTenantLocalityInfoDesc &locality_info) { int ret = OB_SUCCESS; PrintHelper::print_dump_title("locality info"); @@ -2182,11 +2296,12 @@ int ObAdminDumpBackupDataExecutor::dump_tenant_locality_info_(const share::ObExt PrintHelper::print_dump_line("compat_mode", static_cast(locality_info.compat_mode_)); PrintHelper::print_dump_line("locality", locality_info.locality_.ptr()); PrintHelper::print_dump_line("primary_zone", locality_info.primary_zone_.ptr()); + PrintHelper::print_dump_line("sys_time_zone", locality_info.sys_time_zone_.ptr()); PrintHelper::print_end_line(); return ret; } -int ObAdminDumpBackupDataExecutor::dump_tenant_diagnose_info_(const share::ObExternTenantDiagnoseInfoDesc &diagnose_info) +int ObAdminDumpBackupDataExecutor::dump_tenant_diagnose_info_(const storage::ObExternTenantDiagnoseInfoDesc &diagnose_info) { int ret = OB_SUCCESS; PrintHelper::print_dump_title("diagnose info"); @@ -2218,7 +2333,7 @@ int ObAdminDumpBackupDataExecutor::dump_tenant_backup_set_infos_(const ObIArray< return ret; } -int ObAdminDumpBackupDataExecutor::dump_backup_ls_meta_infos_file_(const share::ObBackupLSMetaInfosDesc &ls_meta_infos) +int ObAdminDumpBackupDataExecutor::dump_backup_ls_meta_infos_file_(const storage::ObBackupLSMetaInfosDesc &ls_meta_infos) { int ret = OB_SUCCESS; PrintHelper::print_dump_title("ls meta infos"); @@ -2478,9 +2593,9 @@ int ObAdminDumpBackupDataExecutor::dump_check_exist_result_( int ObAdminDumpBackupDataExecutor::print_tablet_autoinc_seq_(const share::ObTabletAutoincSeq &autoinc_seq) { int ret = OB_SUCCESS; - const common::ObSArray &intervals = autoinc_seq.get_intervals(); - for (int64_t i = 0; OB_SUCC(ret) && intervals.count(); ++i) { - const share::ObTabletAutoincInterval &interval = intervals.at(i); + const share::ObTabletAutoincInterval *intervals = autoinc_seq.get_intervals(); + for (int64_t i = 0; OB_SUCC(ret) && i < autoinc_seq.get_intervals_count(); ++i) { + const share::ObTabletAutoincInterval &interval = intervals[i]; PrintHelper::print_dump_line("tablet_meta:autoinc_seq:start", interval.start_); PrintHelper::print_dump_line("tablet_meta:autoinc_seq:end", interval.end_); } @@ -2517,7 +2632,7 @@ int ObAdminDumpBackupDataExecutor::get_backup_set_placeholder_dir_path( } int ObAdminDumpBackupDataExecutor::filter_backup_set_( - const share::ObTenantBackupSetInfosDesc &tenant_backup_set_infos, + const storage::ObTenantBackupSetInfosDesc &tenant_backup_set_infos, const ObSArray &placeholder_infos, ObIArray &target_backup_set) { diff --git a/tools/ob_admin/backup_tool/ob_admin_dump_backup_data_executor.h b/tools/ob_admin/backup_tool/ob_admin_dump_backup_data_executor.h index 78c9c317c..71c044757 100644 --- a/tools/ob_admin/backup_tool/ob_admin_dump_backup_data_executor.h +++ b/tools/ob_admin/backup_tool/ob_admin_dump_backup_data_executor.h @@ -14,11 +14,12 @@ #define OB_ADMIN_DUMP_BACKUP_DATA_EXECUTOR_H_ #include "../ob_admin_executor.h" #include "storage/backup/ob_backup_data_struct.h" -#include "share/backup/ob_backup_data_store.h" +#include "storage/backup/ob_backup_data_store.h" #include "lib/string/ob_fixed_length_string.h" #include "share/backup/ob_archive_store.h" #include "share/ob_tablet_autoincrement_param.h" #include "storage/backup/ob_backup_restore_util.h" +#include "storage/backup/ob_backup_extern_info_mgr.h" namespace oceanbase { namespace tools { @@ -34,6 +35,8 @@ public: backup::ObBackupDataFileTrailer &file_trailer); static int read_index_file_trailer(const common::ObString &backup_path, const common::ObString &storage_info_str, backup::ObBackupMultiLevelIndexTrailer &index_trailer); + static int read_tablet_metas_file_trailer(const common::ObString &backup_path, const common::ObString &storage_info_str, + backup::ObTabletInfoTrailer &tablet_meta_trailer); static int pread_file(const common::ObString &backup_path, const common::ObString &storage_info_str, const int64_t offset, const int64_t read_size, char *buf); static int get_backup_file_length( @@ -119,10 +122,11 @@ private: int print_archive_single_ls_info_file_(); int print_archive_piece_list_info_file_(); int print_tenant_archive_piece_infos_file_(); + int print_ls_tablet_meta_tablets_(); int print_backup_format_file_(); int print_tenant_backup_set_infos_(); int print_backup_ls_meta_infos_file_(); - + int print_tablet_tx_data_file_(); private: int inner_print_macro_block_(const int64_t offset, const int64_t length, const int64_t idx = -1); int inner_print_tablet_meta_(const int64_t offset, const int64_t length); @@ -137,6 +141,7 @@ private: int inner_print_common_header_(const char *data_path, const char *storage_info_str); private: + int dump_tablet_trailer_(const backup::ObTabletInfoTrailer &tablet_meta_trailer); int dump_backup_file_header_(const backup::ObBackupFileHeader &file_header); int dump_common_header_(const share::ObBackupCommonHeader &common_header); int dump_data_file_trailer_(const backup::ObBackupDataFileTrailer &trailer); @@ -156,12 +161,12 @@ private: int dump_backup_sstable_meta_(const backup::ObBackupSSTableMeta &sstable_meta); int dump_backup_macro_block_id_mapping_meta_(const backup::ObBackupMacroBlockIDMappingsMeta &mapping_meta); int dump_ls_attr_info_(const share::ObLSAttr &ls_attr); - int dump_tablet_to_ls_info_(const share::ObBackupDataTabletToLSInfo &tablet_to_ls_info); - int dump_tenant_locality_info_(const share::ObExternTenantLocalityInfoDesc &locality_info); - int dump_tenant_diagnose_info_(const share::ObExternTenantDiagnoseInfoDesc &diagnose_info); + int dump_tablet_to_ls_info_(const storage::ObBackupDataTabletToLSInfo &tablet_to_ls_info); + int dump_tenant_locality_info_(const storage::ObExternTenantLocalityInfoDesc &locality_info); + int dump_tenant_diagnose_info_(const storage::ObExternTenantDiagnoseInfoDesc &diagnose_info); int dump_backup_set_info(const share::ObBackupSetFileDesc &backup_set_info); int dump_tenant_backup_set_infos_(const ObIArray &backup_set_infos); - int dump_backup_ls_meta_infos_file_(const share::ObBackupLSMetaInfosDesc &ls_meta_infos); + int dump_backup_ls_meta_infos_file_(const storage::ObBackupLSMetaInfosDesc &ls_meta_infos); int dump_archive_round_start_file_(const share::ObRoundStartDesc &round_start_file); int dump_archive_round_end_file_(const share::ObRoundEndDesc round_end_file); int dump_archive_piece_start_file_(const share::ObPieceStartDesc &piece_start_file); @@ -180,7 +185,7 @@ private: int get_tenant_backup_set_infos_path_(const share::ObBackupSetDesc &backup_set_dir_name, share::ObBackupPath &target_path); int get_backup_set_placeholder_dir_path(share::ObBackupPath &path); - int filter_backup_set_(const share::ObTenantBackupSetInfosDesc &tenant_backup_set_infos, + int filter_backup_set_(const storage::ObTenantBackupSetInfosDesc &tenant_backup_set_infos, const ObSArray &placeholder_infos, ObIArray &target_backup_set); diff --git a/tools/ob_admin/dump_ckpt/ob_admin_dump_ckpt_executor.cpp b/tools/ob_admin/dump_ckpt/ob_admin_dump_ckpt_executor.cpp index 70958b9de..c188bc35d 100644 --- a/tools/ob_admin/dump_ckpt/ob_admin_dump_ckpt_executor.cpp +++ b/tools/ob_admin/dump_ckpt/ob_admin_dump_ckpt_executor.cpp @@ -274,7 +274,7 @@ int ObAdminDumpCkptExecutor::dump_tablet( if (OB_ISNULL(buf)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret)); - } else if (OB_FAIL(tablet_meta.deserialize(allocator, buf, buf_len, pos))) { + } else if (OB_FAIL(tablet_meta.deserialize(buf, buf_len, pos))) { LOG_WARN("fail to deserialize tablet", K(ret)); } else if (fprintf(stream, "%s\n", to_cstring(tablet_meta)) < 0) { ret = OB_ERR_SYS; diff --git a/tools/ob_admin/dumpsst/ob_admin_dumpsst_executor.cpp b/tools/ob_admin/dumpsst/ob_admin_dumpsst_executor.cpp index 53bdbdec7..d821fc28c 100644 --- a/tools/ob_admin/dumpsst/ob_admin_dumpsst_executor.cpp +++ b/tools/ob_admin/dumpsst/ob_admin_dumpsst_executor.cpp @@ -49,7 +49,7 @@ ObAdminDumpsstExecutor::~ObAdminDumpsstExecutor() int ObAdminDumpsstExecutor::execute(int argc, char *argv[]) { int ret = OB_SUCCESS; - + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); if (OB_SUCC(parse_cmd(argc, argv))) { OB_LOGGER.set_log_level( is_quiet_ ? "ERROR" : "INFO"); lib::set_memory_limit(96 * 1024 * 1024 * 1024LL); @@ -64,7 +64,8 @@ int ObAdminDumpsstExecutor::execute(int argc, char *argv[]) storage_env_.user_row_cache_priority_, storage_env_.fuse_row_cache_priority_, storage_env_.bf_cache_priority_, - storage_env_.bf_cache_miss_count_threshold_))) { + storage_env_.bf_cache_miss_count_threshold_, + storage_env_.storage_meta_cache_priority_))) { STORAGE_LOG(WARN, "Fail to init OB_STORE_CACHE, ", K(ret), K(storage_env_.data_dir_)); } else if (OB_FAIL(load_config())) { STORAGE_LOG(WARN, "fail to load config", K(ret)); diff --git a/tools/ob_admin/ob_admin_executor.cpp b/tools/ob_admin/ob_admin_executor.cpp index ca1af6b64..51b3010ca 100644 --- a/tools/ob_admin/ob_admin_executor.cpp +++ b/tools/ob_admin/ob_admin_executor.cpp @@ -61,6 +61,7 @@ ObAdminExecutor::ObAdminExecutor() storage_env_.user_row_cache_priority_ = 1; storage_env_.fuse_row_cache_priority_ = 1; storage_env_.tablet_ls_cache_priority_ = 1; + storage_env_.storage_meta_cache_priority_ = 10; storage_env_.ethernet_speed_ = 10000; storage_env_.data_disk_size_ = 1000 * storage_env_.default_block_size_; diff --git a/tools/ob_admin/server_tool/ob_admin_routine.cpp b/tools/ob_admin/server_tool/ob_admin_routine.cpp index eef862d62..226d32ee8 100644 --- a/tools/ob_admin/server_tool/ob_admin_routine.cpp +++ b/tools/ob_admin/server_tool/ob_admin_routine.cpp @@ -670,7 +670,7 @@ DEF_COMMAND(TRANS, remove_lock, 1, "tenant_id ls_id obj_type obj_id lock_mode ow ObLockID lock_id; ObLockOBJType real_obj_type = static_cast(obj_type); ObTableLockMode real_lock_mode = static_cast(lock_mode); - ObTableLockOwnerID real_owner_id = owner_id; + ObTableLockOwnerID real_owner_id = static_cast(owner_id); ObTransID real_create_tx_id = create_tx_id; ObTableLockOpType real_op_type = static_cast(op_type); ObTableLockOpStatus real_lock_op_status = static_cast(lock_op_status); @@ -752,7 +752,7 @@ DEF_COMMAND(TRANS, update_lock, 1, "tenant_id ls_id obj_type obj_id lock_mode ow ObLockID lock_id; ObLockOBJType real_obj_type = static_cast(obj_type); ObTableLockMode real_lock_mode = static_cast(lock_mode); - ObTableLockOwnerID real_owner_id = owner_id; + ObTableLockOwnerID real_owner_id = static_cast(owner_id); ObTransID real_create_tx_id = create_tx_id; ObTableLockOpType real_op_type = static_cast(op_type); ObTableLockOpStatus real_lock_op_status = static_cast(lock_op_status); diff --git a/unittest/logservice/CMakeLists.txt b/unittest/logservice/CMakeLists.txt index 5a82d0327..b26d91119 100644 --- a/unittest/logservice/CMakeLists.txt +++ b/unittest/logservice/CMakeLists.txt @@ -29,10 +29,11 @@ ob_unittest(test_ob_election_message_compat2) ob_unittest(test_ls_election_reference_info) ob_unittest(test_ob_tuple) #ob_unittest(test_ob_role_change_service) -ob_unittest(test_log_config_mgr) +#ob_unittest(test_log_config_mgr)TODO(yunlong.cb): fix it ob_unittest(test_clear_up_tmp_files) ob_unittest(test_log_dir_match) ob_unittest(test_server_log_block_mgr) +ob_unittest(test_tablet_replay_executor) log_unittest(test_role_change_handler) log_unittest(test_log_mode_mgr) ob_unittest(test_palf_throttling) diff --git a/unittest/logservice/mock_logservice_container/mock_log_config_mgr.h b/unittest/logservice/mock_logservice_container/mock_log_config_mgr.h old mode 100644 new mode 100755 index da6cd8012..20d9728bf --- a/unittest/logservice/mock_logservice_container/mock_log_config_mgr.h +++ b/unittest/logservice/mock_logservice_container/mock_log_config_mgr.h @@ -97,7 +97,7 @@ public: int get_curr_member_list(common::ObMemberList &member_list, int64_t &replica_num) const { int ret = OB_SUCCESS; - if (OB_FAIL(log_ms_meta_.curr_.get_expected_paxos_memberlist(member_list, replica_num))) { + if (OB_FAIL(log_ms_meta_.curr_.config_.get_expected_paxos_memberlist(member_list, replica_num))) { PALF_LOG(WARN, "get_expected_paxos_memberlist failed", KR(ret), K_(palf_id), K_(self)); } return ret; @@ -105,10 +105,10 @@ public: int get_log_sync_member_list(common::ObMemberList &member_list, int64_t &replica_num) const { int ret = OB_SUCCESS; - if (OB_FAIL(member_list.deep_copy(log_ms_meta_.curr_.log_sync_memberlist_))) { + if (OB_FAIL(member_list.deep_copy(log_ms_meta_.curr_.config_.log_sync_memberlist_))) { PALF_LOG(WARN, "deep_copy member_list failed", KR(ret), KPC(this)); } else { - replica_num = log_ms_meta_.curr_.log_sync_replica_num_; + replica_num = log_ms_meta_.curr_.config_.log_sync_replica_num_; } return ret; } @@ -130,15 +130,15 @@ public: reconfig_barrier_.prev_end_lsn_.is_valid())) { is_before_barrier = true; barrier_lsn = reconfig_barrier_.prev_end_lsn_; - if (OB_FAIL(member_list.deep_copy(log_ms_meta_.prev_.log_sync_memberlist_))) { + if (OB_FAIL(member_list.deep_copy(log_ms_meta_.prev_.config_.log_sync_memberlist_))) { PALF_LOG(WARN, "deep_copy member_list failed", KR(ret), K_(palf_id), K_(self)); } else { - replica_num = log_ms_meta_.prev_.log_sync_replica_num_; + replica_num = log_ms_meta_.prev_.config_.log_sync_replica_num_; } - } else if (OB_FAIL(member_list.deep_copy(log_ms_meta_.curr_.log_sync_memberlist_))) { + } else if (OB_FAIL(member_list.deep_copy(log_ms_meta_.curr_.config_.log_sync_memberlist_))) { PALF_LOG(WARN, "deep_copy member_list failed", KR(ret), K_(palf_id), K_(self)); } else { - replica_num = log_ms_meta_.curr_.log_sync_replica_num_; + replica_num = log_ms_meta_.curr_.config_.log_sync_replica_num_; } return ret; } @@ -146,7 +146,7 @@ public: { int ret = OB_SUCCESS; GlobalLearnerList all_learners; - if (OB_FAIL(log_ms_meta_.curr_.convert_to_complete_config(member_list, replica_num, all_learners))) { + if (OB_FAIL(log_ms_meta_.curr_.config_.convert_to_complete_config(member_list, replica_num, all_learners))) { PALF_LOG(WARN, "convert_to_complete_config failed", K(ret), KPC(this)); } return ret; @@ -154,7 +154,7 @@ public: int get_prev_member_list(common::ObMemberList &member_list) const { int ret = OB_SUCCESS; - if (OB_FAIL(member_list.deep_copy(log_ms_meta_.prev_.log_sync_memberlist_))) { + if (OB_FAIL(member_list.deep_copy(log_ms_meta_.prev_.config_.log_sync_memberlist_))) { PALF_LOG(WARN, "deep_copy member_list failed", KR(ret), KPC(this)); } return ret; @@ -167,14 +167,14 @@ public: int get_config_version(LogConfigVersion &config_version) const { int ret = OB_SUCCESS; - config_version = log_ms_meta_.curr_.config_version_; + config_version = log_ms_meta_.curr_.config_.config_version_; return ret; } int get_replica_num(int64_t &replica_num) const { int ret = OB_SUCCESS; common::ObMemberList member_list; - if (OB_FAIL(log_ms_meta_.curr_.get_expected_paxos_memberlist(member_list, replica_num))) { + if (OB_FAIL(log_ms_meta_.curr_.config_.get_expected_paxos_memberlist(member_list, replica_num))) { PALF_LOG(WARN, "get_expected_paxos_memberlist failed", KR(ret), KPC(this)); } return ret; diff --git a/unittest/logservice/test_log_config_mgr.cpp b/unittest/logservice/test_log_config_mgr.cpp old mode 100644 new mode 100755 index 649b41371..282e9c830 --- a/unittest/logservice/test_log_config_mgr.cpp +++ b/unittest/logservice/test_log_config_mgr.cpp @@ -70,7 +70,7 @@ public: OB_DELETE(LogPlugins, "TestLog", mock_plugins_); } void init_test_log_config_env(const common::ObAddr &self, - const LogConfigInfo &config_info, + const LogConfigInfoV2 &config_info, LogConfigMgr &cm, common::ObRole role = LEADER, ObReplicaState state = ACTIVE) @@ -114,7 +114,7 @@ public: TEST_F(TestLogConfigMgr, test_set_initial_member_list) { - LogConfigInfo default_config_info; + LogConfigInfoV2 default_config_info; common::ObMemberList init_member_list; GlobalLearnerList learner_list; LogConfigVersion init_config_version; @@ -249,6 +249,168 @@ TEST_F(TestLogConfigMgr, test_set_paxos_member_region_map) EXPECT_EQ(default_region, tmp_region); } +TEST_F(TestLogConfigMgr, test_config_change_lock) +{ + ObMemberList init_member_list; + init_member_list.add_server(addr1); + init_member_list.add_server(addr2); + init_member_list.add_server(addr3); + LogConfigVersion init_config_version; + init_config_version.generate(1, 1); + GlobalLearnerList learner_list; + LogConfigInfoV2 default_config_info; + EXPECT_EQ(OB_SUCCESS, default_config_info.generate(init_member_list, 3, learner_list, init_config_version)); + + + const int64_t lock_type_try_lock = ConfigChangeLockType::LOCK_PAXOS_MEMBER_CHANGE; + const int64_t lock_type_unlock = ConfigChangeLockType::LOCK_NOTHING; + LogLockMeta lock_meta; + EXPECT_EQ(OB_SUCCESS, lock_meta.generate(2, lock_type_try_lock)); + LogConfigInfoV2 locked_config_info; + EXPECT_EQ(OB_SUCCESS, locked_config_info.generate(init_member_list, 3, learner_list, init_config_version, lock_meta)); + + LogLockMeta unlock_meta = lock_meta; + unlock_meta.unlock(); + LogConfigInfoV2 unlock_config_info; + ASSERT_EQ(OB_SUCCESS, unlock_config_info.generate(init_member_list, 3, learner_list, init_config_version, unlock_meta)); + + std::vector config_info_list; + std::vector arg_list; + std::vector expect_ret_list; + std::vector expect_finished_list; + std::vector expect_whether_lock_list; + std::vector expect_lock_owner_list; + std::vector get_config_change_stat_lock_owner_list; + std::vector get_config_change_stat_lock_stat_list; + + //[try_lock] invalid argument + config_info_list.push_back(default_config_info); + arg_list.push_back(LogConfigChangeArgs(-1, lock_type_try_lock, TRY_LOCK_CONFIG_CHANGE)); + expect_ret_list.push_back(OB_INVALID_ARGUMENT); + expect_finished_list.push_back(false); + expect_whether_lock_list.push_back(false); + expect_lock_owner_list.push_back(OB_INVALID_CONFIG_CHANGE_LOCK_OWNER); + get_config_change_stat_lock_owner_list.push_back(OB_INVALID_CONFIG_CHANGE_LOCK_OWNER); + get_config_change_stat_lock_stat_list.push_back(false); + + //[try_lock] OB_SUCCESS is_finish =false + config_info_list.push_back(default_config_info); + arg_list.push_back(LogConfigChangeArgs(2, lock_type_try_lock, TRY_LOCK_CONFIG_CHANGE)); + expect_ret_list.push_back(OB_SUCCESS); + expect_finished_list.push_back(false); + expect_whether_lock_list.push_back(true); + expect_lock_owner_list.push_back(2); + get_config_change_stat_lock_owner_list.push_back(2); + get_config_change_stat_lock_stat_list.push_back(true); + + //[try_lock] OB_SUCCESS is_finish = true + config_info_list.push_back(locked_config_info); + arg_list.push_back(LogConfigChangeArgs(2, lock_type_try_lock, TRY_LOCK_CONFIG_CHANGE)); + expect_ret_list.push_back(OB_SUCCESS); + expect_finished_list.push_back(true); + expect_whether_lock_list.push_back(true); + expect_lock_owner_list.push_back(2); + get_config_change_stat_lock_owner_list.push_back(2); + get_config_change_stat_lock_stat_list.push_back(true); + + //[try_lock] OB_TRY_LOCK_CONFIG_CHANGE_CONFLICT + config_info_list.push_back(locked_config_info); + arg_list.push_back(LogConfigChangeArgs(3, lock_type_try_lock, TRY_LOCK_CONFIG_CHANGE)); + expect_ret_list.push_back(OB_TRY_LOCK_CONFIG_CHANGE_CONFLICT); + expect_finished_list.push_back(false); + expect_whether_lock_list.push_back(true); + expect_lock_owner_list.push_back(2); + get_config_change_stat_lock_owner_list.push_back(2); + get_config_change_stat_lock_stat_list.push_back(true); + + + //[try_unlock]: owner is someone else, return OB_SUCCESS + config_info_list.push_back(locked_config_info); + arg_list.push_back(LogConfigChangeArgs(1, lock_type_unlock, UNLOCK_CONFIG_CHANGE)); + expect_ret_list.push_back(OB_STATE_NOT_MATCH); + expect_finished_list.push_back(false); + expect_whether_lock_list.push_back(true); + expect_lock_owner_list.push_back(2); + get_config_change_stat_lock_owner_list.push_back(2); + get_config_change_stat_lock_stat_list.push_back(true); + + //[try_unlock]: need unlock and unlocked successfully + config_info_list.push_back(locked_config_info); + arg_list.push_back(LogConfigChangeArgs(2, lock_type_unlock, UNLOCK_CONFIG_CHANGE)); + expect_ret_list.push_back(OB_SUCCESS); + expect_finished_list.push_back(false); + expect_whether_lock_list.push_back(false); + expect_lock_owner_list.push_back(2); + get_config_change_stat_lock_owner_list.push_back(2); + get_config_change_stat_lock_stat_list.push_back(false); + + //[try_unlock]: is already unlock + config_info_list.push_back(unlock_config_info); + arg_list.push_back(LogConfigChangeArgs(2, lock_type_unlock, UNLOCK_CONFIG_CHANGE)); + expect_ret_list.push_back(OB_SUCCESS); + expect_finished_list.push_back(true); + expect_whether_lock_list.push_back(false); + expect_lock_owner_list.push_back(2); + get_config_change_stat_lock_owner_list.push_back(2); + get_config_change_stat_lock_stat_list.push_back(false); + + //[try_unlock]: bigger lock owner + config_info_list.push_back(unlock_config_info); + arg_list.push_back(LogConfigChangeArgs(3, lock_type_unlock, UNLOCK_CONFIG_CHANGE)); + expect_ret_list.push_back(OB_STATE_NOT_MATCH); + expect_finished_list.push_back(false); + expect_whether_lock_list.push_back(false); + expect_lock_owner_list.push_back(2); + get_config_change_stat_lock_owner_list.push_back(2); + get_config_change_stat_lock_stat_list.push_back(false); + +//[try_unlock]: smaller lock owner + config_info_list.push_back(unlock_config_info); + arg_list.push_back(LogConfigChangeArgs(1, lock_type_unlock, UNLOCK_CONFIG_CHANGE)); + expect_ret_list.push_back(OB_STATE_NOT_MATCH); + expect_finished_list.push_back(false); + expect_whether_lock_list.push_back(false); + expect_lock_owner_list.push_back(2); + get_config_change_stat_lock_owner_list.push_back(2); + get_config_change_stat_lock_stat_list.push_back(false); + + + + for (int i = 0; i < arg_list.size(); ++i) { + PALF_LOG(INFO, "test_check_config_change_args for lock begin case", K(i+1)); + LogConfigMgr cm; + LogConfigVersion config_version, expect_config_version; + init_test_log_config_env(addr1, config_info_list[i], cm); + init_config_version.generate(cm.log_ms_meta_.proposal_id_, 1); + expect_config_version = init_config_version; + expect_config_version.inc_update_version(cm.log_ms_meta_.proposal_id_); + bool already_finished = false; + int tmp_ret = OB_SUCCESS; + LSN prev_lsn; + prev_lsn.val_ = PALF_INITIAL_LSN_VAL; + tmp_ret = cm.append_log_ms_meta_.1, arg_list[i], already_finished); + config_version = cm.log_ms_meta_.curr_.config_.config_version_; + ASSERT_EQ(tmp_ret, expect_ret_list[i]) << "ret failed case: " << (i+1); + ASSERT_EQ(already_finished, expect_finished_list[i]) << "finished failed case:" << (i+1); + ASSERT_EQ(cm.log_ms_meta_.curr_.lock_meta_.is_locked(), expect_whether_lock_list[i])<< "lock_stat failed case:" << (i+1); + ASSERT_EQ(cm.log_ms_meta_.curr_.lock_meta_.lock_owner_, expect_lock_owner_list[i])<< "lock_owner failed case:" << (i+1); + + int64_t get_lock_owner = -1; + bool is_locked = false; + ASSERT_EQ(OB_SUCCESS, cm.get_config_change_lock_stat(get_lock_owner, is_locked)); + ASSERT_EQ(get_lock_owner, get_config_change_stat_lock_owner_list[i])<< "get_lock_owner failed case:" << (i+1); + ASSERT_EQ(is_locked, get_config_change_stat_lock_stat_list[i])<< "get_lock_stat failed case:" << (i+1); + if (tmp_ret == OB_SUCCESS) { + if (already_finished) { + ASSERT_EQ(config_version, init_config_version) << i; + } else { + ASSERT_EQ(config_version, expect_config_version) << i; + } + } + PALF_LOG(INFO, "test_check_config_change_args for lock end case", K(i+1)); + } +} + TEST_F(TestLogConfigMgr, test_apply_config_meta) { ObMemberList init_member_list, one_f_member_list, @@ -271,25 +433,25 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) LogConfigVersion init_config_version; init_config_version.generate(1, 1); GlobalLearnerList learner_list; - LogConfigInfo default_config_info, one_f_one_a_config_info, + LogConfigInfoV2 default_config_info, one_f_one_a_config_info, two_f_one_a_config_info, four_f_one_a_config_info, five_f_config_info, four_f_config_info, two_f_config_info, three_f_one_learner_config_info; EXPECT_EQ(OB_SUCCESS, default_config_info.generate(init_member_list, 3, learner_list, init_config_version)); EXPECT_EQ(OB_SUCCESS, one_f_one_a_config_info.generate(one_f_member_list, 1, learner_list, init_config_version)); - one_f_one_a_config_info.arbitration_member_ = ObMember(addr2, -1); + one_f_one_a_config_info.config_.arbitration_member_ = ObMember(addr2, -1); EXPECT_EQ(OB_SUCCESS, two_f_one_a_config_info.generate(two_f_member_list, 2, learner_list, init_config_version)); - two_f_one_a_config_info.arbitration_member_ = ObMember(addr3, -1); + two_f_one_a_config_info.config_.arbitration_member_ = ObMember(addr3, -1); EXPECT_EQ(OB_SUCCESS, two_f_config_info.generate(two_f_member_list, 2, learner_list, init_config_version)); EXPECT_EQ(OB_SUCCESS, four_f_one_a_config_info.generate(four_f_member_list, 4, learner_list, init_config_version)); - four_f_one_a_config_info.arbitration_member_ = ObMember(addr5, -1); + four_f_one_a_config_info.config_.arbitration_member_ = ObMember(addr5, -1); EXPECT_EQ(OB_SUCCESS, four_f_config_info.generate(four_f_member_list, 4, learner_list, init_config_version)); EXPECT_EQ(OB_SUCCESS, five_f_config_info.generate(five_f_member_list, 5, learner_list, init_config_version)); + std::vector config_info_list; three_f_one_learner_config_info = default_config_info; - three_f_one_learner_config_info.learnerlist_.add_learner(ObMember(addr4, -1)); + three_f_one_learner_config_info.config_.learnerlist_.add_learner(ObMember(addr4, -1)); - std::vector config_info_list; std::vector arg_list; std::vector expect_member_list; std::vector expect_num_list; @@ -424,11 +586,11 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) expect_finished_list.push_back(false); expect_member_list.push_back(init_member_list); expect_member_list.back().remove_server(addr2); - // in degrade scenario, new member_list will not take effect after calling append_config_meta_, + // in degrade scenario, new member_list will not take effect after calling append_log_ms_meta_. // so the expect_member_list is init_member_list // 21. 3F, upgrade a normal learner config_info_list.push_back(default_config_info); - config_info_list.back().learnerlist_.add_learner(ObMember(addr4, -1)); + config_info_list.back().config_.learnerlist_.add_learner(ObMember(addr4, -1)); arg_list.push_back(LogConfigChangeArgs(ObMember(addr4, -1), 0, palf::UPGRADE_LEARNER_TO_ACCEPTOR)); expect_ret_list.push_back(OB_INVALID_ARGUMENT); expect_finished_list.push_back(false); @@ -441,7 +603,7 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) expect_member_list.push_back(init_member_list); // 23. 3F, upgrade a degraded learner config_info_list.push_back(default_config_info); - config_info_list.back().degraded_learnerlist_.add_learner(ObMember(addr4, -1)); + config_info_list.back().config_.degraded_learnerlist_.add_learner(ObMember(addr4, -1)); arg_list.push_back(LogConfigChangeArgs(ObMember(addr4, -1), 0, palf::UPGRADE_LEARNER_TO_ACCEPTOR)); expect_ret_list.push_back(OB_SUCCESS); expect_finished_list.push_back(false); @@ -449,7 +611,7 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) expect_member_list.back().add_server(addr4); // 24. 2F, add_member(C, 5) config_info_list.push_back(two_f_one_a_config_info); - config_info_list.back().arbitration_member_.reset(); + config_info_list.back().config_.arbitration_member_.reset(); arg_list.push_back(LogConfigChangeArgs(ObMember(addr3, -1), 5, palf::ADD_MEMBER)); expect_ret_list.push_back(OB_SUCCESS); expect_finished_list.push_back(false); @@ -485,8 +647,8 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) // 29. 3F, change_replica_num, invalid config_info_list.push_back(default_config_info); arg_list.push_back(LogConfigChangeArgs( - default_config_info.log_sync_memberlist_, - default_config_info.log_sync_replica_num_, + default_config_info.config_.log_sync_memberlist_, + default_config_info.config_.log_sync_replica_num_, 2, palf::CHANGE_REPLICA_NUM)); expect_ret_list.push_back(OB_INVALID_ARGUMENT); expect_finished_list.push_back(false); @@ -494,19 +656,20 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) // 30. 3F, change_replica_num, 3->5 config_info_list.push_back(default_config_info); arg_list.push_back(LogConfigChangeArgs( - default_config_info.log_sync_memberlist_, - default_config_info.log_sync_replica_num_, + default_config_info.config_.log_sync_memberlist_, + default_config_info.config_.log_sync_replica_num_, 5, palf::CHANGE_REPLICA_NUM)); expect_ret_list.push_back(OB_SUCCESS); expect_finished_list.push_back(false); expect_member_list.push_back(init_member_list); + // 31. 3F replica_num 5, change_replica_num, 5->3 - LogConfigInfo three_f_num5_config_info; - EXPECT_EQ(OB_SUCCESS, three_f_num5_config_info.generate(init_member_list, 5, learner_list, init_config_version)); + LogConfigInfoV2 three_f_num5_config_info; + EXPECT_EQ(OB_SUCCESS, three_f_num5_config_info.generate(init_member_list, 4, learner_list, init_config_version)); config_info_list.push_back(three_f_num5_config_info); arg_list.push_back(LogConfigChangeArgs( - three_f_num5_config_info.log_sync_memberlist_, - three_f_num5_config_info.log_sync_replica_num_, + three_f_num5_config_info.config_.log_sync_memberlist_, + three_f_num5_config_info.config_.log_sync_replica_num_, 3, palf::CHANGE_REPLICA_NUM)); expect_ret_list.push_back(OB_SUCCESS); expect_finished_list.push_back(false); @@ -521,7 +684,7 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) expect_member_list.push_back(five_f_member_list); // 33. 3F1A replica_num 5, change_replica_num, 4->3 EXPECT_EQ(OB_SUCCESS, three_f_num5_config_info.generate(init_member_list, 4, learner_list, init_config_version)); - three_f_num5_config_info.arbitration_member_ = ObMember(addr4, -1); + three_f_num5_config_info.config_.arbitration_member_ = ObMember(addr4, -1); config_info_list.push_back(three_f_num5_config_info); arg_list.push_back(LogConfigChangeArgs( init_member_list, @@ -532,7 +695,7 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) expect_member_list.back().add_member(ObMember(addr4, -1)); // 34. 3F1A replica_num 5, change_replica_num, 5->3 EXPECT_EQ(OB_SUCCESS, three_f_num5_config_info.generate(init_member_list, 4, learner_list, init_config_version)); - three_f_num5_config_info.arbitration_member_ = ObMember(addr4, -1); + three_f_num5_config_info.config_.arbitration_member_ = ObMember(addr4, -1); config_info_list.push_back(three_f_num5_config_info); arg_list.push_back(LogConfigChangeArgs( four_f_member_list, @@ -562,7 +725,7 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) expect_member_list.back().add_member(ObMember(addr5, -1)); // 38. 2F1A - abc, degrade b, migrate b to d: add d. config_info_list.push_back(one_f_one_a_config_info); - config_info_list.back().degraded_learnerlist_.add_learner(ObMember(addr3, -1)); + config_info_list.back().config_.degraded_learnerlist_.add_learner(ObMember(addr3, -1)); arg_list.push_back(LogConfigChangeArgs(ObMember(addr4, -1), 0, palf::ADD_MEMBER_AND_NUM)); expect_ret_list.push_back(OB_SUCCESS); expect_finished_list.push_back(false); @@ -571,14 +734,14 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) expect_member_list.back().add_server(addr4); // 39. 2F1A - abc, degrade b, migrate b to d: add d, remove degraded b. config_info_list.push_back(two_f_one_a_config_info); - config_info_list.back().degraded_learnerlist_.add_learner(ObMember(addr4, -1)); + config_info_list.back().config_.degraded_learnerlist_.add_learner(ObMember(addr4, -1)); arg_list.push_back(LogConfigChangeArgs(ObMember(addr4, -1), 0, palf::REMOVE_MEMBER_AND_NUM)); expect_ret_list.push_back(OB_SUCCESS); expect_finished_list.push_back(false); expect_member_list.push_back(init_member_list); // 40. 2F1A - abc, degrade b, RS wants to remove b when permanent offline occurs. config_info_list.push_back(one_f_one_a_config_info); - config_info_list.back().degraded_learnerlist_.add_learner(ObMember(addr3, -1)); + config_info_list.back().config_.degraded_learnerlist_.add_learner(ObMember(addr3, -1)); arg_list.push_back(LogConfigChangeArgs(ObMember(addr3, -1), 2, palf::REMOVE_MEMBER)); expect_ret_list.push_back(OB_SUCCESS); expect_finished_list.push_back(false); @@ -586,7 +749,7 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) expect_member_list.back().remove_server(addr3); // 41. 2F1A - abc, degrade b, RS wants to switch b to acceptor config_info_list.push_back(one_f_one_a_config_info); - config_info_list.back().degraded_learnerlist_.add_learner(ObMember(addr3, -1)); + config_info_list.back().config_.degraded_learnerlist_.add_learner(ObMember(addr3, -1)); arg_list.push_back(LogConfigChangeArgs(ObMember(addr3, -1), 3, palf::SWITCH_LEARNER_TO_ACCEPTOR)); expect_ret_list.push_back(OB_INVALID_ARGUMENT); expect_finished_list.push_back(false); @@ -594,7 +757,7 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) expect_member_list.back().remove_server(addr3); // 42. 2F1A - abc, degrade b, RS wants to switch b to acceptor config_info_list.push_back(one_f_one_a_config_info); - config_info_list.back().degraded_learnerlist_.add_learner(ObMember(addr3, -1)); + config_info_list.back().config_.degraded_learnerlist_.add_learner(ObMember(addr3, -1)); arg_list.push_back(LogConfigChangeArgs(ObMember(addr3, -1), 2, palf::SWITCH_ACCEPTOR_TO_LEARNER)); expect_ret_list.push_back(OB_INVALID_ARGUMENT); expect_finished_list.push_back(false); @@ -681,10 +844,13 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) int tmp_ret = OB_SUCCESS; LSN prev_lsn; prev_lsn.val_ = PALF_INITIAL_LSN_VAL; - tmp_ret = cm.append_config_meta_(1, arg_list[i], already_finished); - config_version = cm.log_ms_meta_.curr_.config_version_; - EXPECT_EQ(tmp_ret, expect_ret_list[i]) << "ret failed case: " << (i+1); - EXPECT_EQ(already_finished, expect_finished_list[i]) << "finished failed case:" << (i+1); + LogConfigChangeArgs args; + args = arg_list[i]; + args.config_version_ = init_config_version; + tmp_ret = cm.append_log_ms_meta_.1, args, already_finished); + config_version = cm.log_ms_meta_.curr_.config_.config_version_; + ASSERT_EQ(tmp_ret, expect_ret_list[i]) << "ret failed case: " << (i+1); + ASSERT_EQ(already_finished, expect_finished_list[i]) << "finished failed case:" << (i+1); // memberlist will not be applied right now when there is arb member, so use alive_paxos_memberlist_ bool member_equal = (cm.alive_paxos_memberlist_.member_addr_equal(expect_member_list[i])); EXPECT_TRUE(member_equal) << "ret failed case: " << (i+1); @@ -708,7 +874,7 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) prev_lsn.val_ = PALF_INITIAL_LSN_VAL; // remove(D, 5) LogConfigChangeArgs remove_d_arg(ObMember(addr4, -1), 5, palf::REMOVE_MEMBER); - tmp_ret = cm.append_config_meta_(1, remove_d_arg, already_finished); + tmp_ret = cm.append_log_ms_meta_.1, remove_d_arg, already_finished); EXPECT_EQ(tmp_ret, OB_SUCCESS) << "remove(D, 5)"; EXPECT_EQ(already_finished, false) << "remove(D, 5)"; ObMemberList expect_member_list = four_f_member_list; @@ -720,10 +886,34 @@ TEST_F(TestLogConfigMgr, test_apply_config_meta) // remove(C, 5) cm.reset_status(); LogConfigChangeArgs remove_c_arg(ObMember(addr3, -1), 5, palf::REMOVE_MEMBER); - tmp_ret = cm.append_config_meta_(1, remove_c_arg, already_finished); + tmp_ret = cm.append_log_ms_meta_.1, remove_c_arg, already_finished); EXPECT_EQ(tmp_ret, OB_INVALID_ARGUMENT) << "remove(C, 5)"; PALF_LOG(INFO, "test_check_config_change_args end case 26"); } + { + oceanbase::common::ObClusterVersion::get_instance().update_cluster_version(CLUSTER_VERSION_4_2_0_0); + // test reentrance of add_member + PALF_LOG(INFO, "test_check_config_change_args begin case 27"); + LogConfigMgr cm; + init_test_log_config_env(addr1, default_config_info, cm); + LogConfigVersion config_version = cm.log_ms_meta_.curr_.config_.config_version_; + bool already_finished = false; + // add (D, 4) + LogConfigChangeArgs add_d_arg(ObMember(addr4, -1), 4, config_version, palf::ADD_MEMBER); + EXPECT_EQ(OB_SUCCESS, cm.append_log_ms_meta_.1, add_d_arg, already_finished)); + EXPECT_EQ(already_finished, false) << "add(D, 4)"; + ObMemberList expect_member_list = default_config_info.config_.log_sync_memberlist_; + expect_member_list.add_server(addr4); + EXPECT_TRUE(cm.alive_paxos_memberlist_.member_addr_equal(expect_member_list)); + // add (D, 4) again, success + EXPECT_EQ(OB_SUCCESS, cm.append_log_ms_meta_.1, add_d_arg, already_finished)); + EXPECT_EQ(already_finished, true) << "add(D, 4)"; + // add (D, 4) again with greater config_version , fail + add_d_arg.config_version_.inc_update_version(2); + EXPECT_EQ(OB_ERR_UNEXPECTED, cm.append_log_ms_meta_.1, add_d_arg, already_finished)); + EXPECT_EQ(already_finished, false) << "add(D, 4)"; + PALF_LOG(INFO, "test_check_config_change_args end case 27"); + } } TEST_F(TestLogConfigMgr, test_submit_start_working_log) @@ -738,7 +928,7 @@ TEST_F(TestLogConfigMgr, test_submit_start_working_log) init_config_version.generate(1, 1); { LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; LogConfigVersion sw_config_version; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr1, config_info, cm, FOLLOWER); @@ -747,11 +937,11 @@ TEST_F(TestLogConfigMgr, test_submit_start_working_log) } { LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; LogConfigVersion sw_config_version; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr1, config_info, cm, LEADER, RECONFIRM); - EXPECT_EQ(OB_SUCCESS, cm.log_ms_meta_.curr_.learnerlist_.add_learner(ObMember(addr4, -1))); + EXPECT_EQ(OB_SUCCESS, cm.log_ms_meta_.curr_.config_.learnerlist_.add_learner(ObMember(addr4, -1))); LSN prev_lsn; prev_lsn.val_ = PALF_INITIAL_LSN_VAL; int64_t prev_log_proposal_id = INVALID_PROPOSAL_ID; @@ -766,7 +956,7 @@ TEST_F(TestLogConfigMgr, test_submit_start_working_log) LogConfigVersion config_version, expect_config_version; EXPECT_EQ(OB_SUCCESS, expect_config_version.generate(1, 2)); EXPECT_EQ(OB_EAGAIN, cm.confirm_start_working_log(INIT_PROPOSAL_ID, INIT_ELE_EPOCH, sw_config_version)); - config_version = cm.log_ms_meta_.curr_.config_version_; + config_version = cm.log_ms_meta_.curr_.config_.config_version_; EXPECT_EQ(config_version, expect_config_version); // invoke resend ms log EXPECT_EQ(OB_EAGAIN, cm.confirm_start_working_log(INIT_PROPOSAL_ID, INIT_ELE_EPOCH, sw_config_version)); @@ -811,7 +1001,7 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) init_member_list.add_server(addr1); init_member_list.add_server(addr2); init_member_list.add_server(addr3); - LogConfigInfo config_info; + LogConfigInfoV2 config_info; GlobalLearnerList learner_list; LogConfigVersion init_config_version; init_config_version.generate(1, 1); @@ -820,21 +1010,23 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) LogConfigMgr cm; init_test_log_config_env(addr1, config_info, cm, LEADER); int64_t proposal_id = INVALID_PROPOSAL_ID; - EXPECT_EQ(OB_INVALID_ARGUMENT, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, proposal_id, 1, LSN(0), 1, cm.log_ms_meta_)); - EXPECT_EQ(OB_INVALID_ARGUMENT, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, 1, 1, LSN(), 1, cm.log_ms_meta_)); - EXPECT_EQ(OB_INVALID_ARGUMENT, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, 1, 1, LSN(0), INVALID_PROPOSAL_ID, cm.log_ms_meta_)); - EXPECT_EQ(OB_INVALID_ARGUMENT, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, 1, 1, LSN(0), 1, LogConfigMeta())); + EXPECT_EQ(OB_INVALID_ARGUMENT, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, proposal_id, 1, LSN(0), 1, cm.log_ms_meta_)); + EXPECT_EQ(OB_INVALID_ARGUMENT, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, 1, 1, LSN(), 1, cm.log_ms_meta_)); + EXPECT_EQ(OB_INVALID_ARGUMENT, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, 1, 1, LSN(0), INVALID_PROPOSAL_ID, cm.log_ms_meta_)); + EXPECT_EQ(OB_INVALID_ARGUMENT, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, 1, 1, LSN(0), 1, LogConfigMeta())); proposal_id = 1; mock_sw_->mock_max_flushed_lsn_.val_ = PALF_INITIAL_LSN_VAL; mock_sw_->mock_max_flushed_log_pid_ = 0; mock_mode_mgr_->mock_accepted_mode_meta_.proposal_id_ = 1; - EXPECT_EQ(OB_SUCCESS, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, proposal_id, INVALID_PROPOSAL_ID, LSN(0), 1, cm.log_ms_meta_)); + EXPECT_EQ(OB_SUCCESS, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, proposal_id, INVALID_PROPOSAL_ID, LSN(0), 1, cm.log_ms_meta_)); EXPECT_GT(cm.last_submit_config_log_time_us_, 0); } { // submit config log when no mode has been flushed LogConfigMgr cm; init_test_log_config_env(addr1, config_info, cm); + init_config_version.generate(cm.log_ms_meta_.proposal_id_, 1); + int64_t proposal_id = 1; LogConfigVersion config_version; LSN prev_lsn; @@ -843,6 +1035,7 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) LogConfigChangeArgs args; args.type_ = palf::ADD_MEMBER_AND_NUM; args.server_ = common::ObMember(addr4, -1); + args.config_version_ = init_config_version; bool is_already_finished = false; mock_sw_->mock_last_submit_lsn_ = prev_lsn; mock_sw_->mock_last_submit_end_lsn_ = prev_lsn; @@ -852,19 +1045,20 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) mock_sw_->mock_max_flushed_log_pid_ = 0; mock_mode_mgr_->mock_accepted_mode_meta_.proposal_id_ = INVALID_PROPOSAL_ID; EXPECT_EQ(OB_EAGAIN, cm.change_config_(args, proposal_id, INIT_ELE_EPOCH, config_version)); - EXPECT_EQ(OB_EAGAIN, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, proposal_id, 1, prev_lsn, 2, cm.log_ms_meta_)); - EXPECT_EQ(OB_EAGAIN, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, proposal_id, 0, prev_lsn, 2, cm.log_ms_meta_)); + EXPECT_EQ(OB_EAGAIN, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, proposal_id, 1, prev_lsn, 2, cm.log_ms_meta_)); + EXPECT_EQ(OB_EAGAIN, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, proposal_id, 0, prev_lsn, 2, cm.log_ms_meta_)); EXPECT_EQ(cm.state_, 1); EXPECT_EQ(cm.last_submit_config_log_time_us_, OB_INVALID_TIMESTAMP); mock_sw_->mock_max_flushed_log_pid_ = 1; mock_mode_mgr_->mock_accepted_mode_meta_.proposal_id_ = 2; - EXPECT_EQ(OB_SUCCESS, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, proposal_id, 1, prev_lsn, 2, cm.log_ms_meta_)); + EXPECT_EQ(OB_SUCCESS, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, proposal_id, 1, prev_lsn, 2, cm.log_ms_meta_)); EXPECT_GT(cm.last_submit_config_log_time_us_, 0); } { // submit config log when no logs LogConfigMgr cm; init_test_log_config_env(addr1, config_info, cm); + init_config_version.generate(cm.log_ms_meta_.proposal_id_, 1); int64_t proposal_id = 1; LogConfigVersion config_version; LSN prev_lsn; @@ -872,6 +1066,7 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) const int64_t prev_pid = 0; LogConfigChangeArgs args; args.type_ = palf::ADD_MEMBER_AND_NUM; + args.config_version_ = init_config_version; args.server_ = common::ObMember(addr4, -1); bool is_already_finished = false; mock_sw_->mock_last_submit_lsn_ = prev_lsn; @@ -882,7 +1077,7 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) mock_sw_->mock_max_flushed_log_pid_ = 0; mock_mode_mgr_->mock_accepted_mode_meta_.proposal_id_ = 0; EXPECT_EQ(OB_EAGAIN, cm.change_config_(args, proposal_id, INIT_ELE_EPOCH, config_version)); - EXPECT_EQ(OB_SUCCESS, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, proposal_id, prev_pid, prev_lsn, prev_pid, cm.log_ms_meta_)); + EXPECT_EQ(OB_SUCCESS, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, proposal_id, prev_pid, prev_lsn, prev_pid, cm.log_ms_meta_)); EXPECT_GT(cm.last_submit_config_log_time_us_, 0); EXPECT_EQ(cm.state_, 1); } @@ -890,6 +1085,7 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) // submit config log when logs exist in disk LogConfigMgr cm; init_test_log_config_env(addr1, config_info, cm); + init_config_version.generate(cm.log_ms_meta_.proposal_id_, 1); int64_t proposal_id = 1; mock_state_mgr_->mock_proposal_id_ = proposal_id; LogConfigVersion config_version; @@ -898,6 +1094,7 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) const int64_t prev_pid = 1; LogConfigChangeArgs args; args.type_ = palf::ADD_MEMBER_AND_NUM; + args.config_version_ = init_config_version; args.server_ = common::ObMember(addr4, -1); bool is_already_finished = false; mock_sw_->mock_last_submit_lsn_ = prev_lsn; @@ -908,11 +1105,11 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) mock_sw_->mock_max_flushed_log_pid_ = 1; mock_mode_mgr_->mock_accepted_mode_meta_.proposal_id_ = 3; EXPECT_EQ(OB_EAGAIN, cm.change_config_(args, proposal_id, INIT_ELE_EPOCH, config_version)); - EXPECT_EQ(OB_EAGAIN, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, proposal_id, prev_pid, prev_lsn, prev_pid, cm.log_ms_meta_)); + EXPECT_EQ(OB_EAGAIN, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, proposal_id, prev_pid, prev_lsn, prev_pid, cm.log_ms_meta_)); EXPECT_EQ(cm.last_submit_config_log_time_us_, OB_INVALID_TIMESTAMP); EXPECT_EQ(cm.state_, 1); mock_sw_->mock_max_flushed_lsn_.val_ = 20000; - EXPECT_EQ(OB_SUCCESS, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, proposal_id, prev_pid, prev_lsn, prev_pid, cm.log_ms_meta_)); + EXPECT_EQ(OB_SUCCESS, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, proposal_id, prev_pid, prev_lsn, prev_pid, cm.log_ms_meta_)); EXPECT_GT(cm.last_submit_config_log_time_us_, 0); EXPECT_EQ(cm.state_, 1); } @@ -921,6 +1118,7 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) // proposal_id of prev log is smaller than current proposal_id LogConfigMgr cm; init_test_log_config_env(addr1, config_info, cm); + init_config_version.generate(cm.log_ms_meta_.proposal_id_, 1); int64_t proposal_id = 2; mock_state_mgr_->mock_proposal_id_ = proposal_id; LogConfigVersion config_version; @@ -929,6 +1127,7 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) const int64_t prev_pid = 1; LogConfigChangeArgs args; args.type_ = palf::ADD_MEMBER_AND_NUM; + args.config_version_ = init_config_version; args.server_ = common::ObMember(addr4, -1); bool is_already_finished = false; mock_sw_->mock_last_submit_lsn_ = prev_lsn; @@ -939,7 +1138,7 @@ TEST_F(TestLogConfigMgr, test_submit_config_log) mock_sw_->mock_max_flushed_log_pid_ = 2; mock_mode_mgr_->mock_accepted_mode_meta_.proposal_id_ = 3; EXPECT_EQ(OB_EAGAIN, cm.change_config_(args, proposal_id, INIT_ELE_EPOCH, config_version)); - EXPECT_EQ(OB_SUCCESS, cm.submit_config_log_(cm.log_ms_meta_.curr_.log_sync_memberlist_, proposal_id, prev_pid, prev_lsn, prev_pid, cm.log_ms_meta_)); + EXPECT_EQ(OB_SUCCESS, cm.submit_config_log_(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_, proposal_id, prev_pid, prev_lsn, prev_pid, cm.log_ms_meta_)); EXPECT_GT(cm.last_submit_config_log_time_us_, 0); EXPECT_EQ(cm.state_, 1); } @@ -960,13 +1159,13 @@ TEST_F(TestLogConfigMgr, test_after_flush_config_log) // self is paxos member, retire parent // child is not learner, retire child LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr1, config_info, cm); cm.parent_ = addr2; cm.register_time_us_ = 555; EXPECT_EQ(OB_SUCCESS, cm.children_.add_learner(LogLearner(addr3, 1))); - EXPECT_EQ(OB_SUCCESS, cm.after_flush_config_log(cm.log_ms_meta_.curr_.config_version_)); + EXPECT_EQ(OB_SUCCESS, cm.after_flush_config_log(cm.log_ms_meta_.curr_.config_.config_version_)); EXPECT_EQ(OB_INVALID_TIMESTAMP, cm.register_time_us_); EXPECT_EQ(OB_INVALID_TIMESTAMP, cm.parent_keepalive_time_us_); EXPECT_EQ(OB_INVALID_TIMESTAMP, cm.last_submit_register_req_time_us_); @@ -975,7 +1174,7 @@ TEST_F(TestLogConfigMgr, test_after_flush_config_log) PALF_LOG(INFO, "test_after_flush_config_log end case"); } -TEST_F(TestLogConfigMgr, test_degrade__upgrade_scenario) +TEST_F(TestLogConfigMgr, test_degrade_upgrade_scenario) { PALF_LOG(INFO, "test_degrade_upgrade_scenario begin case"); ObMemberList init_member_list; @@ -986,9 +1185,9 @@ TEST_F(TestLogConfigMgr, test_degrade__upgrade_scenario) init_config_version.generate(1, 1); { LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 2, learner_list, init_config_version)); - config_info.arbitration_member_ = ObMember(addr3, 1); + config_info.config_.arbitration_member_ = ObMember(addr3, 1); init_test_log_config_env(addr1, config_info, cm, LEADER, ACTIVE); LSN prev_lsn(PALF_INITIAL_LSN_VAL); int64_t prev_log_proposal_id = INVALID_PROPOSAL_ID; @@ -1007,19 +1206,20 @@ TEST_F(TestLogConfigMgr, test_degrade__upgrade_scenario) EXPECT_EQ(OB_SUCCESS, cm.renew_config_change_barrier()); EXPECT_EQ(OB_EAGAIN, cm.change_config(args, INIT_PROPOSAL_ID, INIT_ELE_EPOCH, de_config_version)); EXPECT_EQ(1, cm.state_); - EXPECT_FALSE(cm.log_ms_meta_.curr_.log_sync_memberlist_.contains(addr2)); + // member_list will not take effect after append_config_meta_ + EXPECT_FALSE(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(addr2)); // self ack config log - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr1, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_version_)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr1, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_)); // reach majority - 1 EXPECT_EQ(OB_EAGAIN, cm.change_config(args, INIT_PROPOSAL_ID, INIT_ELE_EPOCH, de_config_version)); EXPECT_EQ(1, cm.state_); - EXPECT_FALSE(cm.log_ms_meta_.curr_.log_sync_memberlist_.contains(addr2)); + EXPECT_FALSE(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(addr2)); // ack config log - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr3, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_version_)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr3, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_)); // degrade success, switch to INIT state EXPECT_EQ(OB_SUCCESS, cm.change_config(args, INIT_PROPOSAL_ID, INIT_ELE_EPOCH, de_config_version)); EXPECT_EQ(0, cm.state_); - EXPECT_FALSE(cm.log_ms_meta_.curr_.log_sync_memberlist_.contains(addr2)); + EXPECT_FALSE(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(addr2)); // upgrade LogConfigChangeArgs up_args(ObMember(addr2, OB_INVALID_TIMESTAMP), 0, UPGRADE_LEARNER_TO_ACCEPTOR); @@ -1027,19 +1227,19 @@ TEST_F(TestLogConfigMgr, test_degrade__upgrade_scenario) EXPECT_EQ(OB_EAGAIN, cm.change_config(up_args, INIT_PROPOSAL_ID, INIT_ELE_EPOCH, up_config_version)); EXPECT_EQ(1, cm.state_); // member_list will not take effect after append_config_meta_ - EXPECT_TRUE(cm.log_ms_meta_.curr_.log_sync_memberlist_.contains(addr2)); + EXPECT_TRUE(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(addr2)); // self ack config log - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr1, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_version_)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr1, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_)); // reach majority - 1 EXPECT_EQ(OB_EAGAIN, cm.change_config(up_args, INIT_PROPOSAL_ID, INIT_ELE_EPOCH, up_config_version)); - EXPECT_TRUE(cm.log_ms_meta_.curr_.log_sync_memberlist_.contains(addr2)); + EXPECT_TRUE(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(addr2)); EXPECT_EQ(1, cm.state_); // ack config log - EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr3, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_version_)); + EXPECT_EQ(OB_SUCCESS, cm.ack_config_log(addr3, cm.log_ms_meta_.proposal_id_, cm.log_ms_meta_.curr_.config_.config_version_)); // degrade success, switch to INIT state EXPECT_EQ(OB_SUCCESS, cm.change_config(args, INIT_PROPOSAL_ID, INIT_ELE_EPOCH, up_config_version)); EXPECT_EQ(0, cm.state_); - EXPECT_TRUE(cm.log_ms_meta_.curr_.log_sync_memberlist_.contains(addr2)); + EXPECT_TRUE(cm.log_ms_meta_.curr_.config_.log_sync_memberlist_.contains(addr2)); } } @@ -1056,7 +1256,7 @@ TEST_F(TestLogConfigMgr, test_handle_register_parent_req) { // paxos member register, ignore LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr1, config_info, cm); EXPECT_EQ(OB_SUCCESS, cm.handle_register_parent_req(LogLearner(addr3, 1), true)); @@ -1066,7 +1266,7 @@ TEST_F(TestLogConfigMgr, test_handle_register_parent_req) { // duplicate register req LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr1, config_info, cm); LogLearner child(addr4, 1); @@ -1079,7 +1279,7 @@ TEST_F(TestLogConfigMgr, test_handle_register_parent_req) { // register to leader LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr1, config_info, cm); LogLearner child1(addr4, 1); @@ -1112,7 +1312,7 @@ TEST_F(TestLogConfigMgr, test_handle_register_parent_req) { // register to follower LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr1, config_info, cm); // diff region @@ -1155,7 +1355,7 @@ TEST_F(TestLogConfigMgr, test_handle_register_parent_resp) { // state not match LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr1, config_info, cm, FOLLOWER); EXPECT_EQ(OB_STATE_NOT_MATCH, cm.handle_register_parent_resp(LogLearner(addr4, 1), LogCandidateList(), REGISTER_DONE)); @@ -1170,7 +1370,7 @@ TEST_F(TestLogConfigMgr, test_handle_register_parent_resp) { // register continue LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr1, config_info, cm, FOLLOWER); cm.register_time_us_ = 1; @@ -1189,7 +1389,7 @@ TEST_F(TestLogConfigMgr, test_handle_register_parent_resp) { // register not master LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr4, config_info, cm, FOLLOWER); mock_state_mgr_->leader_ = addr1; @@ -1221,7 +1421,7 @@ TEST_F(TestLogConfigMgr, test_region_changed) LogConfigVersion init_config_version; init_config_version.generate(1, 1); LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr5, config_info, cm, FOLLOWER); cm.parent_ = addr4; @@ -1250,7 +1450,7 @@ TEST_F(TestLogConfigMgr, test_check_children_health) { // active leader LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr1, config_info, cm); LogLearner timeout_child(addr4, 1); @@ -1268,7 +1468,7 @@ TEST_F(TestLogConfigMgr, test_check_children_health) { // active follower LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr2, config_info, cm, FOLLOWER); LogLearner timeout_child(addr4, 1); @@ -1301,7 +1501,7 @@ TEST_F(TestLogConfigMgr, test_check_parent_health) { // registering timeout LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr2, config_info, cm, FOLLOWER); cm.last_submit_register_req_time_us_ = 1; @@ -1313,7 +1513,7 @@ TEST_F(TestLogConfigMgr, test_check_parent_health) { // first registration LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr2, config_info, cm, FOLLOWER); mock_state_mgr_->leader_ = addr1; @@ -1324,7 +1524,7 @@ TEST_F(TestLogConfigMgr, test_check_parent_health) { // parent timeout LogConfigMgr cm; - LogConfigInfo config_info; + LogConfigInfoV2 config_info; EXPECT_EQ(OB_SUCCESS, config_info.generate(init_member_list, 3, learner_list, init_config_version)); init_test_log_config_env(addr2, config_info, cm, FOLLOWER); mock_state_mgr_->leader_ = addr1; @@ -1344,7 +1544,7 @@ TEST_F(TestLogConfigMgr, test_handle_retire_msg) init_member_list.add_server(addr1); init_member_list.add_server(addr2); init_member_list.add_server(addr3); - LogConfigInfo config_info; + LogConfigInfoV2 config_info; GlobalLearnerList learner_list; LogConfigVersion init_config_version; init_config_version.generate(1, 1); @@ -1393,10 +1593,10 @@ TEST_F(TestLogConfigMgr, test_handle_retire_msg) TEST_F(TestLogConfigMgr, test_init_by_default_config_meta) { const int64_t init_log_proposal_id = 0; - LogConfigInfo init_config_info; + LogConfigInfoV2 init_config_info; LogConfigVersion init_config_version; init_config_version.generate(init_log_proposal_id, 0); - init_config_info.config_version_ = init_config_version; + init_config_info.generate(init_config_version); LogConfigMeta log_config_meta; LogConfigMgr cm; EXPECT_EQ(OB_SUCCESS, log_config_meta.generate_for_default(init_log_proposal_id, diff --git a/unittest/logservice/test_log_meta.cpp b/unittest/logservice/test_log_meta.cpp index 24f6c51d8..4d4b40139 100644 --- a/unittest/logservice/test_log_meta.cpp +++ b/unittest/logservice/test_log_meta.cpp @@ -69,10 +69,10 @@ TEST(TestLogMeta, test_log_meta) EXPECT_EQ(OB_SUCCESS, curr_config_version.generate(curr_log_proposal_id, curr_config_seq)); EXPECT_TRUE(curr_config_version.is_valid()); - LogConfigInfo prev_config_info; + LogConfigInfoV2 prev_config_info; EXPECT_EQ(OB_INVALID_ARGUMENT, prev_config_info.generate(prev_member_list, -1, prev_learner_list, prev_config_version)); EXPECT_EQ(OB_SUCCESS, prev_config_info.generate(prev_member_list, prev_replica_num, prev_learner_list, prev_config_version)); - LogConfigInfo curr_config_info; + LogConfigInfoV2 curr_config_info; EXPECT_EQ(OB_SUCCESS, curr_config_info.generate(curr_member_list, curr_replica_num, curr_learner_list, curr_config_version)); EXPECT_TRUE(curr_config_info.is_valid()); EXPECT_EQ(OB_SUCCESS, log_config_meta1.generate(curr_log_proposal_id, prev_config_info, curr_config_info, @@ -90,8 +90,19 @@ TEST(TestLogMeta, test_log_meta) LogReplicaPropertyMeta replica_meta1; EXPECT_EQ(OB_SUCCESS, replica_meta1.generate(true, LogReplicaType::NORMAL_REPLICA)); + const int64_t init_log_proposal_id(0); + LogConfigMeta log_config_meta; + LogConfigInfoV2 init_config_info; + LogConfigVersion init_config_version; + EXPECT_EQ(OB_SUCCESS, init_config_version.generate(init_log_proposal_id, 0)); + EXPECT_EQ(OB_SUCCESS, init_config_info.generate(init_config_version)); + log_config_meta.version_ = LogConfigMeta::LOG_CONFIG_META_VERSION_INC; + log_config_meta.proposal_id_ = init_log_proposal_id; + log_config_meta.curr_ = init_config_info; + log_config_meta.prev_ = init_config_info; LogMeta log_meta1; log_meta1.update_log_prepare_meta(log_prepare_meta1); + EXPECT_EQ(OB_SUCCESS, log_meta1.update_log_config_meta(log_config_meta)); // Test invalid EXPECT_FALSE(log_meta1.is_valid()); @@ -134,8 +145,8 @@ TEST(TestLogMeta, test_log_meta_generate) EXPECT_EQ(OB_SUCCESS, meta1.generate_by_palf_base_info(base_info, AccessMode::APPEND, palf::NORMAL_REPLICA)); EXPECT_EQ(meta1.log_prepare_meta_.log_proposal_id_, base_info.prev_log_info_.log_proposal_id_); EXPECT_EQ(meta1.log_config_meta_.proposal_id_, base_info.prev_log_info_.log_proposal_id_); - EXPECT_EQ(meta1.log_config_meta_.curr_.config_version_.proposal_id_, base_info.prev_log_info_.log_proposal_id_); - EXPECT_EQ(meta1.log_config_meta_.prev_.config_version_.proposal_id_, base_info.prev_log_info_.log_proposal_id_); + EXPECT_EQ(meta1.log_config_meta_.curr_.config_.config_version_.proposal_id_, base_info.prev_log_info_.log_proposal_id_); + EXPECT_EQ(meta1.log_config_meta_.prev_.config_.config_version_.proposal_id_, base_info.prev_log_info_.log_proposal_id_); EXPECT_EQ(meta1.log_mode_meta_.proposal_id_, base_info.prev_log_info_.log_proposal_id_); EXPECT_EQ(meta1.log_mode_meta_.mode_version_, base_info.prev_log_info_.log_proposal_id_); EXPECT_EQ(meta1.log_snapshot_meta_.base_lsn_, base_info.curr_lsn_); diff --git a/unittest/logservice/test_log_meta_entry.cpp b/unittest/logservice/test_log_meta_entry.cpp index cea2acf6f..72e080561 100644 --- a/unittest/logservice/test_log_meta_entry.cpp +++ b/unittest/logservice/test_log_meta_entry.cpp @@ -64,8 +64,8 @@ TEST(TestLogMetaEntry, test_log_meta_entry) common::GlobalLearnerList curr_learner_list; curr_learner_list.add_learner(learner2); - LogConfigInfo prev_config_info; - LogConfigInfo curr_config_info; + LogConfigInfoV2 prev_config_info; + LogConfigInfoV2 curr_config_info; LogConfigVersion prev_config_version; LogConfigVersion curr_config_version; @@ -92,6 +92,7 @@ TEST(TestLogMetaEntry, test_log_meta_entry) char buf[BUFSIZE]; int64_t pos = 0; // Test serialize and deserialize + EXPECT_EQ(OB_SUCCESS, log_meta1.update_log_config_meta(log_config_meta1)); EXPECT_EQ(OB_SUCCESS, log_meta1.serialize(buf, BUFSIZE, pos)); EXPECT_EQ(pos, log_meta1.get_serialize_size()); diff --git a/unittest/logservice/test_log_meta_info.cpp b/unittest/logservice/test_log_meta_info.cpp old mode 100644 new mode 100755 index 212a41006..cf3907c0c --- a/unittest/logservice/test_log_meta_info.cpp +++ b/unittest/logservice/test_log_meta_info.cpp @@ -86,6 +86,50 @@ TEST(TestLogMetaInfos, test_log_prepare_meta) TEST(TestLogMetaInfos, test_log_config_meta) { + //test LogLockMeta + LogLockMeta lock_meta; + EXPECT_EQ(false, lock_meta.is_valid()); + lock_meta.version_ = LogLockMeta::LOG_LOCK_META_VERSION; + EXPECT_EQ(true, lock_meta.is_valid()); + EXPECT_EQ(false, lock_meta.is_lock_owner_valid()); + + lock_meta.lock_owner_ = 1; + lock_meta.lock_type_ = LOCK_NOTHING; + EXPECT_EQ(false, lock_meta.is_valid()); + EXPECT_EQ(OB_INVALID_ARGUMENT, lock_meta.generate(1, LOCK_NOTHING)); + EXPECT_EQ(OB_INVALID_ARGUMENT, lock_meta.generate(-1, LOCK_PAXOS_MEMBER_CHANGE)); + EXPECT_EQ(OB_SUCCESS, lock_meta.generate(1, LOCK_PAXOS_MEMBER_CHANGE)); + EXPECT_EQ(true, lock_meta.is_locked()); + EXPECT_EQ(true, lock_meta.is_lock_owner_valid()); + + lock_meta.unlock(); + EXPECT_EQ(false, lock_meta.is_locked()); + EXPECT_EQ(LOCK_NOTHING, lock_meta.lock_type_); + EXPECT_EQ(1, lock_meta.lock_owner_); + EXPECT_EQ(true, lock_meta.version_ == LogLockMeta::LOG_LOCK_META_VERSION); + EXPECT_EQ(true, lock_meta.is_lock_owner_valid()); + + lock_meta.reset_as_unlocked(); + EXPECT_EQ(false, lock_meta.is_locked()); + EXPECT_EQ(LOCK_NOTHING, lock_meta.lock_type_); + EXPECT_EQ(-1, lock_meta.lock_owner_); + EXPECT_EQ(true, lock_meta.version_ == LogLockMeta::LOG_LOCK_META_VERSION); + EXPECT_EQ(false, lock_meta.is_lock_owner_valid()); + + LogLockMeta new_lock_meta; + new_lock_meta = lock_meta; + EXPECT_EQ(true, new_lock_meta == lock_meta); + + const int64_t SER_BUF_SIZE = 512; + char ser_buf[SER_BUF_SIZE] = {0}; + int64_t pos = 0; + EXPECT_EQ(OB_SUCCESS, lock_meta.serialize(ser_buf, SER_BUF_SIZE, pos)); + int64_t new_pos = 0; + EXPECT_EQ(OB_SUCCESS, new_lock_meta.deserialize(ser_buf, pos, new_pos)); + EXPECT_EQ(pos, new_pos); + EXPECT_EQ(new_lock_meta, lock_meta); + //end of test LogLockMeta + static const int64_t BUFSIZE = 1 << 21; ObAddr addr1(ObAddr::IPV4, "127.0.0.1", 4096); ObAddr addr2(ObAddr::IPV4, "127.0.0.1", 4097); @@ -114,8 +158,10 @@ TEST(TestLogMetaInfos, test_log_config_meta) LogConfigVersion prev_config_version; LogConfigVersion curr_config_version; - LogConfigInfo prev_config_info; - LogConfigInfo curr_config_info; + LogConfigInfoV2 prev_config_info; + LogConfigInfoV2 curr_config_info; + LogConfigInfo old_config_info; + LogConfigInfoV2 new_config_info; // log barrier const int64_t barrier_log_proposal_id = 3; @@ -136,17 +182,26 @@ TEST(TestLogMetaInfos, test_log_config_meta) EXPECT_EQ(OB_SUCCESS, prev_config_version.generate(prev_log_proposal_id, prev_config_seq)); EXPECT_EQ(OB_SUCCESS, curr_config_version.generate(curr_log_proposal_id, curr_config_seq)); + lock_meta.reset(); + EXPECT_EQ(OB_INVALID_ARGUMENT, prev_config_info.generate(prev_member_list, prev_replica_num, prev_learner_list, prev_config_version, lock_meta)); + lock_meta.reset_as_unlocked(); + ASSERT_EQ(OB_SUCCESS, prev_config_info.generate(prev_member_list, prev_replica_num, prev_learner_list, prev_config_version, lock_meta)); EXPECT_EQ(OB_SUCCESS, prev_config_info.generate(prev_member_list, prev_replica_num, prev_learner_list, prev_config_version)); EXPECT_EQ(OB_SUCCESS, curr_config_info.generate(curr_member_list, curr_replica_num, curr_learner_list, curr_config_version)); EXPECT_TRUE(curr_config_info.is_valid()); EXPECT_TRUE(prev_config_info.is_valid()); // test lists overlap - { - LogConfigInfo invalid_info = curr_config_info; - invalid_info.learnerlist_.add_learner(member2); - EXPECT_FALSE(invalid_info.is_valid()); - } +// { +// LogConfigInfo invalid_info = curr_config_info; //TODO(yaoying): fix it +// invalid_info.learnerlist_.add_learner(member2); +// EXPECT_FALSE(invalid_info.is_valid()); +// } + + EXPECT_EQ(OB_SUCCESS, old_config_info.generate(curr_member_list, curr_replica_num, curr_learner_list, curr_config_version)); + EXPECT_EQ(OB_SUCCESS, new_config_info.generate(old_config_info)); + EXPECT_EQ(true, new_config_info.lock_meta_.is_valid()); + EXPECT_EQ(false, new_config_info.lock_meta_.is_locked()); // test basic serialization { @@ -219,7 +274,9 @@ TEST(TestLogMetaInfos, test_log_config_info_convert) EXPECT_EQ(OB_SUCCESS, curr_config_version.generate(curr_log_proposal_id, curr_config_seq)); // 2F1A, 2 degraded learners { - LogConfigInfo curr_config_info; + LogConfigInfoV2 curr_config_info_v2; + + LogConfigInfo &curr_config_info = curr_config_info_v2.config_; int64_t log_sync_replica_num = 2; ObMemberList log_sync_member_list; log_sync_member_list.add_member(ObMember(addr1, 1)); @@ -243,7 +300,7 @@ TEST(TestLogMetaInfos, test_log_config_info_convert) common::ObMemberList result_memberlist; int64_t result_replica_num; GlobalLearnerList result_learners; - EXPECT_EQ(OB_SUCCESS, curr_config_info.convert_to_complete_config(result_memberlist, result_replica_num, result_learners)); + EXPECT_EQ(OB_SUCCESS, curr_config_info_v2.convert_to_complete_config(result_memberlist, result_replica_num, result_learners)); EXPECT_EQ(result_replica_num, expected_paxos_replica_num); EXPECT_TRUE(result_memberlist.member_addr_equal(expected_paxos_memberlist)); EXPECT_EQ(3, result_memberlist.get_member_number()); diff --git a/unittest/logservice/test_log_mode_mgr.cpp b/unittest/logservice/test_log_mode_mgr.cpp index 0102ffff5..06515a7fe 100644 --- a/unittest/logservice/test_log_mode_mgr.cpp +++ b/unittest/logservice/test_log_mode_mgr.cpp @@ -75,7 +75,7 @@ public: const int64_t init_pid = 1; LogConfigInfo config_info; LogConfigMeta config_meta; - LogConfigInfo default_config_info; + LogConfigInfoV2 default_config_info; ObMemberList init_member_list; GlobalLearnerList learner_list; LogConfigVersion init_config_version; diff --git a/unittest/logservice/test_log_reconfirm.cpp b/unittest/logservice/test_log_reconfirm.cpp index d2c4299ff..ba2c1df9e 100644 --- a/unittest/logservice/test_log_reconfirm.cpp +++ b/unittest/logservice/test_log_reconfirm.cpp @@ -104,10 +104,10 @@ void TestLogReconfirm::set_default_config_meta() default_mlist.add_server(self_); GlobalLearnerList learners; LogConfigMeta config_meta; - LogConfigInfo init_config_info; + LogConfigInfoV2 init_config_info; LogConfigVersion init_config_version; init_config_version.generate(curr_proposal_id, 0); - init_config_info.config_version_ = init_config_version; + init_config_info.config_.config_version_ = init_config_version; EXPECT_EQ(OB_SUCCESS, init_config_info.generate(default_mlist, 1, learners, init_config_version)); config_meta.curr_ = init_config_info; mock_mm_.log_ms_meta_ = config_meta; diff --git a/unittest/logservice/test_log_sliding_window.cpp b/unittest/logservice/test_log_sliding_window.cpp index 2345d2a60..86bf9f621 100644 --- a/unittest/logservice/test_log_sliding_window.cpp +++ b/unittest/logservice/test_log_sliding_window.cpp @@ -545,7 +545,7 @@ TEST_F(TestLogSlidingWindow, test_after_flush_log) default_mlist.add_server(self_); GlobalLearnerList learners; LogConfigMeta config_meta; - LogConfigInfo init_config_info; + LogConfigInfoV2 init_config_info; LogConfigVersion init_config_version; init_config_version.generate(curr_proposal_id, 0); EXPECT_EQ(OB_SUCCESS, init_config_info.generate(default_mlist, 1, learners, init_config_version)); @@ -719,7 +719,7 @@ TEST_F(TestLogSlidingWindow, test_ack_log) default_mlist.add_server(self_); GlobalLearnerList learners; LogConfigMeta config_meta; - LogConfigInfo init_config_info; + LogConfigInfoV2 init_config_info; LogConfigVersion init_config_version; init_config_version.generate(curr_proposal_id, 0); EXPECT_EQ(OB_SUCCESS, init_config_info.generate(default_mlist, 1, learners, init_config_version)); @@ -740,8 +740,8 @@ TEST_F(TestLogSlidingWindow, test_ack_log) default_mlist.add_server(server); LSN invalid_lsn; EXPECT_EQ(OB_INVALID_ARGUMENT, log_sw_.ack_log(server, invalid_lsn)); - LogConfigInfo new_config_info = init_config_info; - new_config_info.log_sync_memberlist_ = default_mlist; + LogConfigInfoV2 new_config_info = init_config_info; + new_config_info.config_.log_sync_memberlist_ = default_mlist; mock_mm_.log_ms_meta_.curr_ = new_config_info; mock_state_mgr_.role_ = LEADER; diff --git a/unittest/logservice/test_log_state_mgr.cpp b/unittest/logservice/test_log_state_mgr.cpp index ee197b8a1..2dd0d952f 100644 --- a/unittest/logservice/test_log_state_mgr.cpp +++ b/unittest/logservice/test_log_state_mgr.cpp @@ -93,7 +93,7 @@ TEST_F(TestLogStateMgr, replay_to_leader_active) default_mlist.add_server(self_); GlobalLearnerList learners; LogConfigMeta config_meta; - LogConfigInfo init_config_info; + LogConfigInfoV2 init_config_info; LogConfigVersion init_config_version; EXPECT_EQ(OB_SUCCESS, init_config_version.generate(1, 0)); EXPECT_EQ(OB_SUCCESS, init_config_info.generate(default_mlist, 1, learners, init_config_version)); diff --git a/unittest/logservice/test_tablet_replay_executor.cpp b/unittest/logservice/test_tablet_replay_executor.cpp new file mode 100644 index 000000000..89f90b84a --- /dev/null +++ b/unittest/logservice/test_tablet_replay_executor.cpp @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2021 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 + +#define USING_LOG_PREFIX CLOG + +#define protected public +#define private public + +#include "logservice/replayservice/ob_tablet_replay_executor.h" +#include "share/ob_tablet_autoincrement_param.h" + +namespace oceanbase +{ +namespace logservice +{ +class TestTabletReplayexecutor : public ::testing::Test, public ObTabletReplayExecutor +{ +public: + TestTabletReplayexecutor() = default; + virtual ~TestTabletReplayexecutor() = default; + + virtual void SetUp() override; + virtual void TearDown() override; + + virtual bool is_replay_update_user_data_() const override; + virtual int do_replay_(storage::ObTabletHandle &tablet_handle) override; + virtual bool is_replay_update_mds_table_() const override; +}; + +void TestTabletReplayexecutor::SetUp() +{ +} + +void TestTabletReplayexecutor::TearDown() +{ +} + +bool TestTabletReplayexecutor::is_replay_update_user_data_() const +{ + return false; +} + +int TestTabletReplayexecutor::do_replay_(storage::ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + UNUSED(tablet_handle); + return ret; +} + +bool TestTabletReplayexecutor::is_replay_update_mds_table_() const +{ + return true; +} + +int ObTabletReplayExecutor::replay_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + const ObTabletCreateDeleteMdsUserData &mds, + storage::mds::MdsCtx &ctx, + const share::SCN &scn) +{ + int ret = 123; + UNUSEDx(tablet_handle, mds, ctx, scn); + return ret; +} + +int ObTabletReplayExecutor::replay_to_mds_table_( + storage::ObTabletHandle &tablet_handle, + const ObTabletBindingMdsUserData &mds, + storage::mds::MdsCtx &ctx, + const share::SCN &scn) +{ + int ret = 456; + UNUSEDx(tablet_handle, mds, ctx, scn); + return ret; +} + +TEST_F(TestTabletReplayexecutor, template_specialization) +{ + int ret = OB_SUCCESS; + storage::ObTabletHandle tablet_handle; + storage::mds::MdsCtx ctx; + share::SCN scn; + ObTabletCreateDeleteMdsUserData user_data1; + ObTabletBindingMdsUserData user_data2; + share::ObTabletAutoincSeq user_data3; + + ret = this->replay_to_mds_table_(tablet_handle, user_data1, ctx, scn); + ASSERT_EQ(123, ret); + ret = this->replay_to_mds_table_(tablet_handle, user_data2, ctx, scn); + ASSERT_EQ(456, ret); + ret = this->replay_to_mds_table_(tablet_handle, user_data3, ctx, scn); + ASSERT_EQ(OB_ERR_UNEXPECTED, ret); +} +} // namespace logservice +} // namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -f test_tablet_replay_executor.log*"); + OB_LOGGER.set_file_name("test_tablet_replay_executor.log", true); + OB_LOGGER.set_log_level("INFO"); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/unittest/observer/table/test_create_executor.cpp b/unittest/observer/table/test_create_executor.cpp index 11bb9dc66..1b2565151 100644 --- a/unittest/observer/table/test_create_executor.cpp +++ b/unittest/observer/table/test_create_executor.cpp @@ -148,6 +148,7 @@ TestCreateExecutor::TestCreateExecutor() void TestCreateExecutor::SetUp() { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); schema_service_.init(); create_table_schema(&table_schema_, columns_); schema_service_.add_table_schema(table_schema_, 1); diff --git a/unittest/rootserver/test_archive_checkpoint.cpp b/unittest/rootserver/test_archive_checkpoint.cpp index 54dd1ae55..6a9541703 100644 --- a/unittest/rootserver/test_archive_checkpoint.cpp +++ b/unittest/rootserver/test_archive_checkpoint.cpp @@ -1961,6 +1961,228 @@ TEST_F(ArchiveCheckpointerTest, in_doing_05) ASSERT_EQ(g_call_cnt, 3); } +// Some log stream is deleted during archive. +TEST_F(ArchiveCheckpointerTest, in_doing_06) +{ + // old round's status is DOING + ObTenantArchiveRoundAttr old_round; + fill_round( + ObArchiveRoundState::doing()/* status */, + "2022-01-01 00:00:30"/* start_time */, + "2022-01-01 00:00:35"/* checkpoint_time */, + "2022-01-01 00:00:40"/* max_time */, + 1/* used_piece_id */, + 0/* frozen_input_bytes */, + 0/* frozen_output_bytes */, + 100/* active_input_bytes */, + 10/* active_output_bytes */, + 0/* deleted_input_bytes */, + 0/* deleted_output_bytes */, + old_round); + + // 3 log streams, one is deleted. + ObDestRoundSummary summary; + // log stream 1001 is archiving. + ObLSDestRoundSummary ls_1001; + ObArchiveLSPieceSummary piece_1001_1; + fill_archive_ls_piece( + 1001/* ls_id */, + false/* is_deleted */, + 1/* piece_id */, + ObArchiveRoundState::doing()/* state */, + "2022-01-01 00:00:30"/* start_time */, + "2022-01-01 00:00:50"/* checkpoint_time */, + 0/* min_lsn */, + 2000/* max_lsn */, + 200/* input_bytes */, + 20/* output_bytes */, + piece_1001_1); + ASSERT_EQ(ls_1001.add_one_piece(piece_1001_1), OB_SUCCESS); + + // log stream 1002 is archiving. + ObLSDestRoundSummary ls_1002; + ObArchiveLSPieceSummary piece_1002_1; + fill_archive_ls_piece( + 1002/* ls_id */, + false/* is_deleted */, + 1/* piece_id */, + ObArchiveRoundState::doing()/* state */, + "2022-01-01 00:00:30"/* start_time */, + "2022-01-01 00:00:55"/* checkpoint_time */, + 0/* min_lsn */, + 1000/* max_lsn */, + 100/* input_bytes */, + 10/* output_bytes */, + piece_1002_1); + ASSERT_EQ(ls_1002.add_one_piece(piece_1002_1), OB_SUCCESS); + + // log stream 1003 is deleted. + ObLSDestRoundSummary ls_1003; + ObArchiveLSPieceSummary piece_1003_1; + fill_archive_ls_piece( + 1003/* ls_id */, + true/* is_deleted */, + 1/* piece_id */, + ObArchiveRoundState::doing()/* state */, + "2022-01-01 00:00:30"/* start_time */, + "2022-01-01 00:00:40"/* checkpoint_time */, + 0/* min_lsn */, + 1000/* max_lsn */, + 100/* input_bytes */, + 10/* output_bytes */, + piece_1003_1); + ASSERT_EQ(ls_1003.add_one_piece(piece_1003_1), OB_SUCCESS); + + + ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1001), OB_SUCCESS); + ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1002), OB_SUCCESS); + ASSERT_EQ(summary.add_ls_dest_round_summary(ls_1003), OB_SUCCESS); + + + class MockRoundHandler final: public ObArchiveRoundHandler + { + public: + int checkpoint_to( + const ObTenantArchiveRoundAttr &old_round, + const ObTenantArchiveRoundAttr &new_round, + const common::ObIArray &pieces) override + { + int ret = OB_SUCCESS; + g_call_cnt++; + ArchiveCheckpointerTest test; + ObTenantArchiveRoundAttr expect_round; + test.fill_new_round( + old_round, + ObArchiveRoundState::doing()/* state */, + "2022-01-01 00:00:50"/* checkpoint_time */, + "2022-01-01 00:00:55"/* max_time */, + 1/* used_piece_id */, + 0/* frozen_input_bytes */, + 0/* frozen_output_bytes */, + 400/* active_input_bytes */, + 40/* active_output_bytes */, + 0/* deleted_input_bytes */, + 0/* deleted_output_bytes */, + expect_round); + + ObTenantArchivePieceAttr expect_piece; + test.fill_piece( + old_round, + 1/* piece_id */, + "2022-01-01 00:00:50"/* checkpoint_time */, + "2022-01-01 00:00:55"/* max_time */, + 400/* input_bytes */, + 40/* output_bytes */, + ObArchivePieceStatus::active()/* status */, + ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE/* file_status */, + expect_piece); + + + ret = test.compare_two_rounds(new_round, expect_round); + if (OB_SUCC(ret)) { + if (pieces.count() != 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid pieces count", K(ret), K(pieces)); + } else { + const ObTenantArchivePieceAttr &piece = pieces.at(0); + ret = test.compare_two_pieces(piece, expect_piece); + } + } + return ret; + } + }; + + ObDestRoundCheckpointer::PieceGeneratedCb gen_piece_cb = + [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObDestRoundCheckpointer::Result &result, const ObDestRoundCheckpointer::GeneratedPiece &piece) + { + int ret = OB_SUCCESS; + g_call_cnt++; + ArchiveCheckpointerTest test; + ObDestRoundCheckpointer::GeneratedPiece expect_piece; + test.fill_piece( + old_round, + 1/* piece_id */, + "2022-01-01 00:00:50"/* checkpoint_time */, + "2022-01-01 00:00:55"/* max_time */, + 400/* input_bytes */, + 40/* output_bytes */, + ObArchivePieceStatus::active()/* status */, + ObBackupFileStatus::STATUS::BACKUP_FILE_AVAILABLE/* file_status */, + expect_piece.piece_info_); + + ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1001 = test.gen_checkpoint_ls_piece( + 1001/* ls_id */, + "2022-01-01 00:00:30"/* start_time */, + "2022-01-01 00:00:50"/* checkpoint_time */, + 0/* min_lsn */, + 2000/* max_lsn */, + 200/* input_bytes */, + 20/* output_bytes */); + + ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1002 = test.gen_checkpoint_ls_piece( + 1002/* ls_id */, + "2022-01-01 00:00:30"/* start_time */, + "2022-01-01 00:00:55"/* checkpoint_time */, + 0/* min_lsn */, + 1000/* max_lsn */, + 100/* input_bytes */, + 10/* output_bytes */); + + ObDestRoundCheckpointer::GeneratedLSPiece ls_piece_1003 = test.gen_checkpoint_ls_piece( + 1003/* ls_id */, + "2022-01-01 00:00:30"/* start_time */, + "2022-01-01 00:00:40"/* checkpoint_time */, + 0/* min_lsn */, + 1000/* max_lsn */, + 100/* input_bytes */, + 10/* output_bytes */); + + expect_piece.ls_piece_list_.push_back(ls_piece_1001); + expect_piece.ls_piece_list_.push_back(ls_piece_1002); + expect_piece.ls_piece_list_.push_back(ls_piece_1003); + ret = test.compare_two_checkpoint_pieces(piece, expect_piece); + return ret; + }; + + ObDestRoundCheckpointer::RoundCheckpointCb round_cb = + [](common::ObISQLClient *proxy, const ObTenantArchiveRoundAttr &old_round, const ObTenantArchiveRoundAttr &new_round) + { + int ret = OB_SUCCESS; + g_call_cnt++; + ArchiveCheckpointerTest test; + ObTenantArchiveRoundAttr expect_round; + test.fill_new_round( + old_round, + ObArchiveRoundState::doing()/* state */, + "2022-01-01 00:00:50"/* checkpoint_time */, + "2022-01-01 00:00:55"/* max_time */, + 1/* used_piece_id */, + 0/* frozen_input_bytes */, + 0/* frozen_output_bytes */, + 400/* active_input_bytes */, + 40/* active_output_bytes */, + 0/* deleted_input_bytes */, + 0/* deleted_output_bytes */, + expect_round); + + ret = test.compare_two_rounds(new_round, expect_round); + return ret; + }; + + int ret = OB_SUCCESS; + g_call_cnt = 0; + MockRoundHandler mock_handler; + ObDestRoundCheckpointer checkpointer; + share::SCN limit_scn; + (void)limit_scn.convert_for_logservice(convert_timestr_2_scn("2022-01-01 00:00:59")); + ret = checkpointer.init(&mock_handler, gen_piece_cb, round_cb, limit_scn); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = checkpointer.checkpoint(old_round, summary); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(g_call_cnt, 3); +} + TEST_F(ArchiveCheckpointerTest, in_stopping_01) { diff --git a/unittest/rootserver/test_primary_ls_service.cpp b/unittest/rootserver/test_primary_ls_service.cpp index 40e64edc8..23d57a550 100644 --- a/unittest/rootserver/test_primary_ls_service.cpp +++ b/unittest/rootserver/test_primary_ls_service.cpp @@ -14,6 +14,8 @@ #include #include #define private public +#include "rootserver/ob_balance_ls_primary_zone.h" +#include "share/ls/ob_ls_status_operator.h" #include "rootserver/ob_primary_ls_service.h" #include "share/ls/ob_ls_operator.h" namespace oceanbase { @@ -58,12 +60,12 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(ret, OB_SUCCESS); ret = primary_zone_array.push_back(z1); ASSERT_EQ(ret, OB_SUCCESS); - ret = ObTenantLSInfo::set_ls_to_primary_zone(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::set_ls_to_primary_zone_(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); ASSERT_EQ(ret, OB_SUCCESS); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(z1, ls_primary_zone.at(0)); ASSERT_EQ(1, count_group_by_zone.at(0)); - ret = ObTenantLSInfo::balance_ls_primary_zone(primary_zone_array, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::balance_ls_primary_zone_(primary_zone_array, ls_primary_zone, count_group_by_zone); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z1, ls_primary_zone.at(0)); ASSERT_EQ(1, count_group_by_zone.at(0)); @@ -75,14 +77,14 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(ret, OB_SUCCESS); ret = primary_zone_array.push_back(z2); ASSERT_EQ(ret, OB_SUCCESS); - ret = ObTenantLSInfo::set_ls_to_primary_zone(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::set_ls_to_primary_zone_(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z2, ls_primary_zone.at(0)); ASSERT_EQ(z2, ls_primary_zone.at(1)); ASSERT_EQ(0, count_group_by_zone.at(0)); ASSERT_EQ(2, count_group_by_zone.at(1)); - ret = ObTenantLSInfo::balance_ls_primary_zone(primary_zone_array, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::balance_ls_primary_zone_(primary_zone_array, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z1, ls_primary_zone.at(0)); @@ -98,14 +100,14 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(ret, OB_SUCCESS); ret = primary_zone_array.push_back(z3); ASSERT_EQ(ret, OB_SUCCESS); - ret = ObTenantLSInfo::set_ls_to_primary_zone(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::set_ls_to_primary_zone_(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z1, ls_primary_zone.at(0)); ASSERT_EQ(z3, ls_primary_zone.at(1)); ASSERT_EQ(1, count_group_by_zone.at(0)); ASSERT_EQ(1, count_group_by_zone.at(1)); - ret = ObTenantLSInfo::balance_ls_primary_zone(primary_zone_array, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::balance_ls_primary_zone_(primary_zone_array, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z1, ls_primary_zone.at(0)); @@ -118,7 +120,7 @@ TEST_F(TestPrimaryLSService, zone_balance) count_group_by_zone.reset(); ret = primary_zone_array.push_back(z2); ASSERT_EQ(ret, OB_SUCCESS); - ret = ObTenantLSInfo::set_ls_to_primary_zone(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::set_ls_to_primary_zone_(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z2, ls_primary_zone.at(0)); @@ -126,7 +128,7 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(0, count_group_by_zone.at(0)); ASSERT_EQ(0, count_group_by_zone.at(1)); ASSERT_EQ(2, count_group_by_zone.at(2)); - ret = ObTenantLSInfo::balance_ls_primary_zone(primary_zone_array, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::balance_ls_primary_zone_(primary_zone_array, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z1, ls_primary_zone.at(0)); @@ -146,7 +148,7 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(ret, OB_SUCCESS); ret = primary_zone_infos.push_back(info); ASSERT_EQ(ret, OB_SUCCESS); - ret = ObTenantLSInfo::set_ls_to_primary_zone(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::set_ls_to_primary_zone_(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z2, ls_primary_zone.at(0)); @@ -156,7 +158,7 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(1, count_group_by_zone.at(0)); ASSERT_EQ(0, count_group_by_zone.at(1)); ASSERT_EQ(3, count_group_by_zone.at(2)); - ret = ObTenantLSInfo::balance_ls_primary_zone(primary_zone_array, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::balance_ls_primary_zone_(primary_zone_array, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z3, ls_primary_zone.at(0)); @@ -185,7 +187,7 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(ret, OB_SUCCESS); ret = primary_zone_infos.push_back(info); ASSERT_EQ(ret, OB_SUCCESS); - ret = ObTenantLSInfo::set_ls_to_primary_zone(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::set_ls_to_primary_zone_(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z1, ls_primary_zone.at(0)); @@ -196,7 +198,7 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(3, count_group_by_zone.at(0)); ASSERT_EQ(1, count_group_by_zone.at(1)); ASSERT_EQ(1, count_group_by_zone.at(2)); - ret = ObTenantLSInfo::balance_ls_primary_zone(primary_zone_array, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::balance_ls_primary_zone_(primary_zone_array, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(z3, ls_primary_zone.at(0)); ASSERT_EQ(z1, ls_primary_zone.at(1)); @@ -207,7 +209,7 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(2, count_group_by_zone.at(1)); ASSERT_EQ(1, count_group_by_zone.at(2)); - //case 6 pirmary zone to z1,z3,z1, ls to z1, z1, z1,z1,z2,z2,z2,z2 + //case 6 pirmary zone to z1,z3,z2, ls to z1, z1, z1,z1,z2,z2,z2,z2 ls_primary_zone.reset(); count_group_by_zone.reset(); @@ -233,7 +235,7 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(ret, OB_SUCCESS); ret = primary_zone_infos.push_back(info); ASSERT_EQ(ret, OB_SUCCESS); - ret = ObTenantLSInfo::set_ls_to_primary_zone(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::set_ls_to_primary_zone_(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(z1, ls_primary_zone.at(0)); @@ -247,7 +249,7 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(4, count_group_by_zone.at(0)); ASSERT_EQ(0, count_group_by_zone.at(1)); ASSERT_EQ(4, count_group_by_zone.at(2)); - ret = ObTenantLSInfo::balance_ls_primary_zone(primary_zone_array, ls_primary_zone, count_group_by_zone); + ret = ObBalanceLSPrimaryZone::balance_ls_primary_zone_(primary_zone_array, ls_primary_zone, count_group_by_zone); LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); ASSERT_EQ(z3, ls_primary_zone.at(0)); ASSERT_EQ(z1, ls_primary_zone.at(1)); @@ -261,6 +263,55 @@ TEST_F(TestPrimaryLSService, zone_balance) ASSERT_EQ(2, count_group_by_zone.at(1)); ASSERT_EQ(3, count_group_by_zone.at(2)); + //case 8 pirmary zone to z1,z2, z3. ls to z1, z1, z2, z2 + ls_primary_zone.reset(); + count_group_by_zone.reset(); + primary_zone_infos.reset(); + primary_zone_array.reset(); + ret = primary_zone_array.push_back(z1); + ASSERT_EQ(ret, OB_SUCCESS); + ret = primary_zone_array.push_back(z2); + ASSERT_EQ(ret, OB_SUCCESS); + ret = primary_zone_array.push_back(z3); + ASSERT_EQ(ret, OB_SUCCESS); + + ret = info.init(1002, 1001, ls_id, z1, z1.str()); + ASSERT_EQ(ret, OB_SUCCESS); + ret = primary_zone_infos.push_back(info); + ASSERT_EQ(ret, OB_SUCCESS); + ret = info.init(1002, 1001, ls_id, z1, z1.str()); + ASSERT_EQ(ret, OB_SUCCESS); + ret = primary_zone_infos.push_back(info); + ASSERT_EQ(ret, OB_SUCCESS); + ret = info.init(1002, 1001, ls_id, z2, z1.str()); + ASSERT_EQ(ret, OB_SUCCESS); + ret = primary_zone_infos.push_back(info); + ASSERT_EQ(ret, OB_SUCCESS); + ret = info.init(1002, 1001, ls_id, z2, z1.str()); + ASSERT_EQ(ret, OB_SUCCESS); + ret = primary_zone_infos.push_back(info); + ASSERT_EQ(ret, OB_SUCCESS); + + ret = ObBalanceLSPrimaryZone::set_ls_to_primary_zone_(primary_zone_array, primary_zone_infos, ls_primary_zone, count_group_by_zone); + LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); + ASSERT_EQ(ret, OB_SUCCESS); + ASSERT_EQ(z1, ls_primary_zone.at(0)); + ASSERT_EQ(z1, ls_primary_zone.at(1)); + ASSERT_EQ(z2, ls_primary_zone.at(2)); + ASSERT_EQ(z2, ls_primary_zone.at(3)); + ASSERT_EQ(2, count_group_by_zone.at(0)); + ASSERT_EQ(2, count_group_by_zone.at(1)); + ASSERT_EQ(0, count_group_by_zone.at(2)); + ret = ObBalanceLSPrimaryZone::balance_ls_primary_zone_(primary_zone_array, ls_primary_zone, count_group_by_zone); + LOG_INFO("set ls to primary zone", K(ls_primary_zone), K(count_group_by_zone)); + ASSERT_EQ(ret, OB_SUCCESS); + ASSERT_EQ(z3, ls_primary_zone.at(0)); + ASSERT_EQ(z1, ls_primary_zone.at(1)); + ASSERT_EQ(z2, ls_primary_zone.at(2)); + ASSERT_EQ(z2, ls_primary_zone.at(3)); + ASSERT_EQ(1, count_group_by_zone.at(0)); + ASSERT_EQ(2, count_group_by_zone.at(1)); + ASSERT_EQ(1, count_group_by_zone.at(2)); } TEST_F(TestPrimaryLSService, LS_FLAG) @@ -367,6 +418,7 @@ TEST_F(TestPrimaryLSService, LS_FLAG) } + } } int main(int argc, char **argv) diff --git a/unittest/share/backup/test_backup_struct.cpp b/unittest/share/backup/test_backup_struct.cpp index 0488a8e41..5aad69464 100644 --- a/unittest/share/backup/test_backup_struct.cpp +++ b/unittest/share/backup/test_backup_struct.cpp @@ -16,7 +16,6 @@ #include "lib/container/ob_array_iterator.h" #define private public #include "share/backup/ob_backup_path.h" -#include "share/backup/ob_log_archive_backup_info_mgr.h" using namespace oceanbase; using namespace common; diff --git a/unittest/share/backup/test_log_archive_backup_info_mgr.cpp b/unittest/share/backup/test_log_archive_backup_info_mgr.cpp index 8b9a7a738..49c754e95 100644 --- a/unittest/share/backup/test_log_archive_backup_info_mgr.cpp +++ b/unittest/share/backup/test_log_archive_backup_info_mgr.cpp @@ -15,7 +15,6 @@ #include #define private public #include "share/backup/ob_backup_path.h" -#include "share/backup/ob_log_archive_backup_info_mgr.h" using namespace oceanbase; using namespace common; using namespace share; diff --git a/unittest/share/cache/CMakeLists.txt b/unittest/share/cache/CMakeLists.txt index 4c1290663..715398f9c 100644 --- a/unittest/share/cache/CMakeLists.txt +++ b/unittest/share/cache/CMakeLists.txt @@ -3,3 +3,5 @@ storage_unittest(test_kv_storecache) #ob_unittest(test_working_set_mgr) #ob_unittest(test_cache_working_set) #ob_unittest(test_perf_kv_storecache) +storage_unittest(test_recycle_multi_kvcache) +storage_unittest(test_vtable_event_recycle_buffer) \ No newline at end of file diff --git a/unittest/share/cache/test_recycle_multi_kvcache.cpp b/unittest/share/cache/test_recycle_multi_kvcache.cpp new file mode 100644 index 000000000..48d7e1aa1 --- /dev/null +++ b/unittest/share/cache/test_recycle_multi_kvcache.cpp @@ -0,0 +1,364 @@ +/** + * Copyright (c) 2021 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/allocator/ob_allocator.h" +#define UNITTEST_DEBUG +#include +#define private public +#define protected public +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#include "share/ob_ls_id.h" +#include "storage/multi_data_source/mds_writer.h" +#include +#include +#include +#include +#include +#include "lib/ob_errno.h" +#include "share/ob_errno.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include "lib/allocator/ob_malloc.h" +#include "storage/multi_data_source/mds_node.h" +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_row.h" +#include "storage/multi_data_source/mds_unit.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/multi_data_source/mds_table_handler.h" +#include "storage/tx/ob_trans_define.h" +#include +#include +#include "storage/multi_data_source/runtime_utility/mds_lock.h" +#include "storage/tablet/ob_tablet_meta.h" +#include "share/cache/ob_recycle_multi_kvcache.h" + +namespace oceanbase { +namespace unittest { + +struct DefaultAllocator : public ObIAllocator +{ + void *alloc(const int64_t size) { return ob_malloc(size, "MDS"); } + void *alloc(const int64_t size, const ObMemAttr &attr) { return ob_malloc(size, attr); } + void free(void *ptr) { ob_free(ptr); } + void set_label(const lib::ObLabel &) {} + static DefaultAllocator &get_instance() { static DefaultAllocator alloc; return alloc; } + static int64_t get_alloc_times() { return ATOMIC_LOAD(&get_instance().alloc_times_); } + static int64_t get_free_times() { return ATOMIC_LOAD(&get_instance().free_times_); } +private: + DefaultAllocator() : alloc_times_(0), free_times_(0) {} + int64_t alloc_times_; + int64_t free_times_; +}; + +using namespace common; +using namespace std; +using namespace storage; +using namespace mds; +using namespace transaction; +using namespace common::cache; + +class TestObVtableRecycleEventBuffer: public ::testing::Test +{ +public: + TestObVtableRecycleEventBuffer() {} + virtual ~TestObVtableRecycleEventBuffer() {} + virtual void SetUp() { + } + virtual void TearDown() { + } +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestObVtableRecycleEventBuffer); +}; + +struct TestEvent { + TestEvent() : buffer_(nullptr), len_(0), alloc_(nullptr) {} + TestEvent &operator=(const TestEvent &rhs) = delete; + ~TestEvent() { + if (OB_NOT_NULL(alloc_)) { + alloc_->free(buffer_); + alloc_ = nullptr; + buffer_ = nullptr; + len_ = 0; + } + } + int init(ObIAllocator &alloc, int64_t size) { + int ret = OB_SUCCESS; + if (nullptr == (buffer_ = (char *)alloc.alloc(size))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + OCCAM_LOG(DEBUG, "fail to alloc", K(*this)); + } else { + alloc_ = &alloc; + len_ = size; + } + return ret; + } + int assign(ObIAllocator &alloc, const TestEvent &rhs) { + return init(alloc, rhs.len_); + } + TO_STRING_KV(KP(this), KP_(buffer), KP_(alloc), K_(len)); + char *buffer_; + int64_t len_; + ObIAllocator *alloc_; +}; + +struct HashKey { + HashKey() : key_(0) {} + HashKey(int key) : key_(key) {} + bool operator<(const HashKey &rhs) { return key_ < rhs.key_; } + bool operator==(const HashKey &rhs) { return key_ == rhs.key_; } + int64_t hash() const { return key_ % 3; } + TO_STRING_KV(K_(key)); + int key_; +}; + +struct Simple { + Simple() : val_(0) {} + Simple(int val) : val_(val) {} + bool operator==(const Simple &rhs) const { return val_ == rhs.val_; } + TO_STRING_KV(K_(val)); + int val_; +}; + +struct Complicated { + Complicated() : data_(nullptr), len_(0), alloc_(nullptr) {} + ~Complicated() { + if (OB_NOT_NULL(alloc_)) { + alloc_->free(data_); + alloc_ = nullptr; + len_ = 0; + alloc_ = 0; + } + } + Complicated(char c, int len) : Complicated() { + data_ = new char[len]; + for (int i = 0; i < len; ++i) { + data_[i] = c; + } + len_ = len; + } + bool operator==(const Complicated &rhs) const { + bool ret = false; + if (len_ == rhs.len_) { + int i = 0; + for (; i < rhs.len_; ++i) { + if (data_[i] != rhs.data_[i]) { + break; + } + } + if (i == len_) { + ret = true; + } + } + return ret; + } + bool operator!=(const Complicated &rhs) const { + return !this->operator==(rhs); + } + int assign(ObIAllocator &alloc, const Complicated &rhs) { + int ret = OB_SUCCESS; + if (nullptr == (data_ = (char*)alloc.alloc(rhs.len_))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + } else { + OCCAM_LOG(DEBUG, "assign new", KP_(data)); + for (int i = 0; i < rhs.len_; ++i) { + data_[i] = rhs.data_[i]; + } + len_ = rhs.len_; + alloc_ = &alloc; + } + return ret; + } + TO_STRING_KV(KP_(data), K_(len), KP_(alloc)); + char *data_; + int64_t len_; + ObIAllocator *alloc_; +}; + +TEST_F(TestObVtableRecycleEventBuffer, test_hash_bkt) { + KVNode *stack_buffer[3]; + ObRecycleMultiKVCache::HashBkt hash_bkt(stack_buffer, 3, 0); + auto node1_1 = new KVNode(1, 1); + auto node1_2 = new KVNode(1, 2); + auto node1_3 = new KVNode(1, 3); + auto node2_1 = new KVNode(2, 1); + auto node4_1 = new KVNode(4, 1); + auto node4_2 = new KVNode(4, 2); + auto node4_3 = new KVNode(4, 3); + hash_bkt.insert(node1_1); + ASSERT_EQ(node1_1, hash_bkt.hash_bkt_[1]); + ASSERT_EQ(nullptr, hash_bkt.hash_bkt_[1]->hash_bkt_next_); + ASSERT_EQ(node1_1, hash_bkt.hash_bkt_[1]->key_node_next_); + ASSERT_EQ(node1_1, hash_bkt.hash_bkt_[1]->key_node_prev_); + hash_bkt.insert(node2_1); + ASSERT_EQ(node2_1, hash_bkt.hash_bkt_[2]); + hash_bkt.insert(node4_1); + ASSERT_EQ(node4_1, hash_bkt.hash_bkt_[1]->hash_bkt_next_); + ASSERT_EQ(hash_bkt.hash_bkt_[1]->hash_bkt_next_, *node4_1->hash_bkt_prev_next_ptr_); + ASSERT_EQ(nullptr, hash_bkt.hash_bkt_[1]->hash_bkt_next_->hash_bkt_next_); + hash_bkt.insert(node1_2); + ASSERT_EQ(node1_2, hash_bkt.hash_bkt_[1]->key_node_next_); + ASSERT_EQ(node1_2, hash_bkt.hash_bkt_[1]->key_node_prev_); + ASSERT_EQ(hash_bkt.hash_bkt_[1], node1_2->key_node_next_); + ASSERT_EQ(hash_bkt.hash_bkt_[1], node1_2->key_node_prev_); + hash_bkt.remove(node1_2); + ASSERT_EQ(node1_1, hash_bkt.hash_bkt_[1]->key_node_next_); + ASSERT_EQ(node1_1, hash_bkt.hash_bkt_[1]->key_node_prev_); + hash_bkt.insert(node1_2); + hash_bkt.remove(node1_1); + ASSERT_EQ(node1_2, hash_bkt.hash_bkt_[1]); + ASSERT_EQ(node1_2, hash_bkt.hash_bkt_[1]->key_node_next_); + ASSERT_EQ(node1_2, hash_bkt.hash_bkt_[1]->key_node_prev_); + ASSERT_EQ(node4_1, hash_bkt.hash_bkt_[1]->hash_bkt_next_); + ASSERT_EQ(node1_2->hash_bkt_next_, *node4_1->hash_bkt_prev_next_ptr_); + hash_bkt.remove(node1_2); + ASSERT_EQ(node4_1, hash_bkt.hash_bkt_[1]); + KVNode **bkt_prev_node_next_ptr; + KVNode *bkt_next; + auto list = hash_bkt.find_list(4, bkt_prev_node_next_ptr, bkt_next); + ASSERT_EQ(Simple(1), list->v_); + ASSERT_EQ(list, list->key_node_next_); + hash_bkt.insert(node4_2); + hash_bkt.insert(node4_3); + list = hash_bkt.find_list(4, bkt_prev_node_next_ptr, bkt_next); + ASSERT_EQ(Simple(1), list->v_); + ASSERT_EQ(Simple(2), list->key_node_next_->v_); + ASSERT_EQ(Simple(3), list->key_node_next_->key_node_next_->v_); + ASSERT_EQ(list, list->key_node_next_->key_node_next_->key_node_next_); + hash_bkt.remove(node4_2); + hash_bkt.insert(node4_2); + ASSERT_EQ(Simple(1), list->v_); + ASSERT_EQ(Simple(3), list->key_node_next_->v_); + ASSERT_EQ(Simple(2), list->key_node_next_->key_node_next_->v_); + ASSERT_EQ(list, list->key_node_next_->key_node_next_->key_node_next_); +} + +TEST_F(TestObVtableRecycleEventBuffer, test_recycle_buffer) { + ObRecycleMultiKVCache recycle_buffer; + int64_t sizeof_event_node = sizeof(KVNode); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.init("TEST", + DefaultAllocator::get_instance(), + 3 * (sizeof_event_node + 1), + 3)); + ASSERT_EQ(recycle_buffer.total_buffer_ + sizeof(void*) * 3, recycle_buffer.buffer_); + ASSERT_EQ((char *)recycle_buffer.hash_bkt_.hash_bkt_, recycle_buffer.total_buffer_); + ASSERT_EQ(recycle_buffer.round_end_(recycle_buffer.offset_next_to_appended_), recycle_buffer.offset_can_write_end_); + auto value1 = Complicated({'1', 1}); + auto value2 = Complicated({'2', 1}); + auto value3 = Complicated({'3', 1}); + auto value4 = Complicated({'4', 1}); + auto value5 = Complicated({'5', 1}); + auto value6 = Complicated({'6', 2}); + auto value7 = Complicated({'7', 2}); + auto value8 = Complicated({'8', 1}); + auto value9 = Complicated({'9', 1}); + auto value10 = Complicated({'0', 1}); + auto value11 = Complicated({'1', 1_KB}); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.append({1}, value1)); + ASSERT_EQ(sizeof_event_node + 1, recycle_buffer.offset_next_to_appended_); + ASSERT_EQ(recycle_buffer.round_end_(recycle_buffer.offset_next_to_appended_), recycle_buffer.offset_can_write_end_); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.append({1}, value2)); + ASSERT_EQ(2 * (sizeof_event_node + 1), recycle_buffer.offset_next_to_appended_); + ASSERT_EQ(recycle_buffer.round_end_(recycle_buffer.offset_next_to_appended_), recycle_buffer.offset_can_write_end_); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.append({1}, value3)); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.append({1}, value4)); + ASSERT_EQ(4 * (sizeof_event_node + 1), recycle_buffer.offset_next_to_appended_); + ASSERT_EQ(recycle_buffer.buffer_len_ + (sizeof_event_node + 1), recycle_buffer.offset_can_write_end_); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.append({1}, value5)); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.append({1}, value6)); + ASSERT_EQ(recycle_buffer.buffer_len_ * 2 + (sizeof_event_node + 2), recycle_buffer.offset_next_to_appended_); + ASSERT_EQ(recycle_buffer.buffer_len_ * 2 + 2 * (sizeof_event_node + 1), recycle_buffer.offset_reserved_); + ASSERT_EQ(recycle_buffer.buffer_len_ * 3, recycle_buffer.offset_can_write_end_); + int idx = 0; + int ret = recycle_buffer.for_each(HashKey(1), [&](const Complicated &vale) -> int { + int ret = OB_SUCCESS; + switch (++idx) { + case 1: + if (value6 != vale) { + ret = OB_ERR_UNEXPECTED; + OCCAM_LOG(ERROR, "not expected", K(vale)); + } + break; + default: + OB_ASSERT(false); + break; + } + return ret; + }); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.append({1}, value7)); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.append({1}, value8)); + ASSERT_EQ(recycle_buffer.buffer_len_ * 3 + (sizeof_event_node + 1), recycle_buffer.offset_next_to_appended_); + ASSERT_EQ(recycle_buffer.buffer_len_ * 3 + 2 * (sizeof_event_node + 2), recycle_buffer.offset_reserved_); + ASSERT_EQ(recycle_buffer.buffer_len_ * 3 + sizeof_event_node + 2, recycle_buffer.offset_can_write_end_); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.append({1}, value9)); + ASSERT_EQ(recycle_buffer.buffer_len_ * 3 + 2 * (sizeof_event_node + 1), recycle_buffer.offset_next_to_appended_); + ASSERT_EQ(recycle_buffer.buffer_len_ * 3 + 2 * (sizeof_event_node + 2), recycle_buffer.offset_reserved_); + ASSERT_EQ(recycle_buffer.buffer_len_ * 4, recycle_buffer.offset_can_write_end_); + ASSERT_EQ(OB_SUCCESS, recycle_buffer.append({1}, value10)); + ASSERT_EQ(recycle_buffer.buffer_len_ * 4, recycle_buffer.offset_next_to_appended_); + ASSERT_EQ(recycle_buffer.buffer_len_ * 3 + 2 * (sizeof_event_node + 2), recycle_buffer.offset_reserved_); + ASSERT_EQ(recycle_buffer.buffer_len_ * 4, recycle_buffer.offset_can_write_end_); + idx = 0; + ret = recycle_buffer.for_each(HashKey(1), [&](const Complicated &vale) -> int { + int ret = OB_SUCCESS; + switch (++idx) { + case 1: + if (value8 != vale) { + ret = OB_ERR_UNEXPECTED; + OCCAM_LOG(ERROR, "not expected", K(vale)); + } + break; + case 2: + if (value9 != vale) { + ret = OB_ERR_UNEXPECTED; + OCCAM_LOG(ERROR, "not expected", K(vale)); + } + break; + case 3: + if (value10 != vale) { + ret = OB_ERR_UNEXPECTED; + OCCAM_LOG(ERROR, "not expected", K(vale)); + } + break; + default: + OB_ASSERT(false); + break; + } + return ret; + }); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_BUF_NOT_ENOUGH, recycle_buffer.append({11}, value11)); + ASSERT_EQ(recycle_buffer.buffer_len_ * 4, recycle_buffer.offset_next_to_appended_); + ASSERT_EQ(recycle_buffer.buffer_len_ * 3 + 2 * (sizeof_event_node + 2), recycle_buffer.offset_reserved_); + ASSERT_EQ(recycle_buffer.buffer_len_ * 5, recycle_buffer.offset_can_write_end_); +} + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_recycle_multi_kvcache.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_recycle_multi_kvcache.log", false); + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + int64_t alloc_times = oceanbase::unittest::DefaultAllocator::get_alloc_times(); + int64_t free_times = oceanbase::unittest::DefaultAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + ret = -1; + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} diff --git a/unittest/share/cache/test_vtable_event_recycle_buffer.cpp b/unittest/share/cache/test_vtable_event_recycle_buffer.cpp new file mode 100644 index 000000000..e3d42cbcb --- /dev/null +++ b/unittest/share/cache/test_vtable_event_recycle_buffer.cpp @@ -0,0 +1,230 @@ +/** + * Copyright (c) 2021 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 +#define private public +#define protected public +#include "lib/allocator/ob_allocator.h" +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#include "share/ob_ls_id.h" +#include "storage/multi_data_source/mds_writer.h" +#include +#include +#include +#include +#include +#include "lib/ob_errno.h" +#include "share/ob_errno.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include "lib/allocator/ob_malloc.h" +#include "storage/multi_data_source/mds_node.h" +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_row.h" +#include "storage/multi_data_source/mds_unit.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/multi_data_source/mds_table_handler.h" +#include "storage/tx/ob_trans_define.h" +#include +#include +#include "storage/multi_data_source/runtime_utility/mds_lock.h" +#include "storage/tablet/ob_tablet_meta.h" +#include "share/cache/ob_vtable_event_recycle_buffer.h" +#include "observer/virtual_table/ob_mds_event_buffer.h" + +namespace oceanbase { +namespace unittest { + +struct DefaultAllocator : public ObIAllocator +{ + void *alloc(const int64_t size) { return ob_malloc(size, "MDS"); } + void *alloc(const int64_t size, const ObMemAttr &attr) { return ob_malloc(size, attr); } + void free(void *ptr) { ob_free(ptr); } + void set_label(const lib::ObLabel &) {} + static DefaultAllocator &get_instance() { static DefaultAllocator alloc; return alloc; } + static int64_t get_alloc_times() { return ATOMIC_LOAD(&get_instance().alloc_times_); } + static int64_t get_free_times() { return ATOMIC_LOAD(&get_instance().free_times_); } +private: + DefaultAllocator() : alloc_times_(0), free_times_(0) {} + int64_t alloc_times_; + int64_t free_times_; +}; + +using namespace common; +using namespace std; +using namespace storage; +using namespace mds; +using namespace transaction; +using namespace common::cache; + +class TestObVtableEventRecycleBuffer: public ::testing::Test +{ +public: + TestObVtableEventRecycleBuffer() {} + virtual ~TestObVtableEventRecycleBuffer() {} + virtual void SetUp() { + } + virtual void TearDown() { + } +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestObVtableEventRecycleBuffer); +}; + +struct TestEvent { + TestEvent() : buffer_(nullptr), len_(0), alloc_(nullptr) {} + TestEvent &operator=(const TestEvent &rhs) = delete; + ~TestEvent() { + if (OB_NOT_NULL(alloc_)) { + alloc_->free(buffer_); + alloc_ = nullptr; + buffer_ = nullptr; + len_ = 0; + } + } + int init(ObIAllocator &alloc, int64_t size) { + int ret = OB_SUCCESS; + if (nullptr == (buffer_ = (char *)alloc.alloc(size))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + OCCAM_LOG(DEBUG, "fail to alloc", K(*this)); + } else { + alloc_ = &alloc; + len_ = size; + } + return ret; + } + int assign(ObIAllocator &alloc, const TestEvent &rhs) { + return init(alloc, rhs.len_); + } + TO_STRING_KV(KP(this), KP_(buffer), KP_(alloc), K_(len)); + char *buffer_; + int64_t len_; + ObIAllocator *alloc_; +}; + +struct HashKey { + HashKey() : key_(0) {} + HashKey(int key) : key_(key) {} + bool operator<(const HashKey &rhs) { return key_ < rhs.key_; } + bool operator==(const HashKey &rhs) { return key_ == rhs.key_; } + int64_t hash() const { return key_ % 3; } + TO_STRING_KV(K_(key)); + int key_; +}; + +struct Simple { + Simple() : val_(0) {} + Simple(int val) : val_(val) {} + bool operator==(const Simple &rhs) const { return val_ == rhs.val_; } + TO_STRING_KV(K_(val)); + int val_; +}; + +struct Complicated { + Complicated() : data_(nullptr), len_(0), alloc_(nullptr) {} + ~Complicated() { + if (OB_NOT_NULL(alloc_)) { + alloc_->free(data_); + alloc_ = nullptr; + len_ = 0; + alloc_ = 0; + } + } + Complicated(char c, int len) : Complicated() { + data_ = new char[len]; + for (int i = 0; i < len; ++i) { + data_[i] = c; + } + len_ = len; + } + bool operator==(const Complicated &rhs) const { + bool ret = false; + if (len_ == rhs.len_) { + int i = 0; + for (; i < rhs.len_; ++i) { + if (data_[i] != rhs.data_[i]) { + break; + } + } + if (i == len_) { + ret = true; + } + } + return ret; + } + bool operator!=(const Complicated &rhs) const { + return !this->operator==(rhs); + } + int assign(ObIAllocator &alloc, const Complicated &rhs) { + int ret = OB_SUCCESS; + if (nullptr == (data_ = (char*)alloc.alloc(rhs.len_))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + } else { + OCCAM_LOG(DEBUG, "assign new", KP_(data)); + for (int i = 0; i < rhs.len_; ++i) { + data_[i] = rhs.data_[i]; + } + len_ = rhs.len_; + alloc_ = &alloc; + } + return ret; + } + TO_STRING_KV(KP_(data), K_(len), KP_(alloc)); + char *data_; + int64_t len_; + ObIAllocator *alloc_; +}; + +TEST_F(TestObVtableEventRecycleBuffer, basic_test) { + ObVtableEventRecycleBuffer vtable_event_buffer; + auto value1 = Complicated({'1', 1}); + auto value2 = Complicated({'2', 1}); + auto for_each_dummy_op = [](const Complicated &) { return OB_SUCCESS; }; + ASSERT_EQ(OB_SUCCESS, vtable_event_buffer.init("TEST", DefaultAllocator::get_instance(), 2, 100, 100)); + ASSERT_EQ(OB_SUCCESS, vtable_event_buffer.append({1}, value1)); + ASSERT_NE(HashKey(1).hash(), vtable_event_buffer.buffer_bkt_[1].cache_.hash_bkt_.re_hash_idx_({1})); + ASSERT_EQ(OB_SUCCESS, vtable_event_buffer.for_each({1}, for_each_dummy_op)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, vtable_event_buffer.for_each({0}, for_each_dummy_op)); + ASSERT_EQ(OB_SUCCESS, vtable_event_buffer.append({0}, value2)); + ASSERT_EQ(OB_SUCCESS, vtable_event_buffer.buffer_bkt_[1].cache_.for_each({1}, for_each_dummy_op)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, vtable_event_buffer.buffer_bkt_[1].cache_.for_each({0}, for_each_dummy_op)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, vtable_event_buffer.buffer_bkt_[0].cache_.for_each({1}, for_each_dummy_op)); + ASSERT_EQ(OB_SUCCESS, vtable_event_buffer.buffer_bkt_[0].cache_.for_each({0}, for_each_dummy_op)); +} + +// TEST_F(TestObVtableEventRecycleBuffer, test_global_event_buffer) { +// ASSERT_EQ(OB_SUCCESS, observer::ObMdsEventBuffer::init()); +// observer::MdsEvent e; +// ASSERT_EQ(OB_SUCCESS, e.set_event(DefaultAllocator::get_instance(), "TEST EVENT", ObString("test info str"))); +// observer::ObMdsEventBuffer::append({1, share::ObLSID(1), ObTabletID(1)}, e); +// observer::ObMdsEventBuffer::destroy(); +// } + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_vtable_event_recycle_buffer.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_vtable_event_recycle_buffer.log", false); + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + int64_t alloc_times = oceanbase::unittest::DefaultAllocator::get_alloc_times(); + int64_t free_times = oceanbase::unittest::DefaultAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + ret = -1; + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} diff --git a/unittest/share/deadlock/test_deadlock.cpp b/unittest/share/deadlock/test_deadlock.cpp index 6c97495fe..dc46e1920 100644 --- a/unittest/share/deadlock/test_deadlock.cpp +++ b/unittest/share/deadlock/test_deadlock.cpp @@ -10,7 +10,7 @@ * See the Mulan PubL v2 for more details. */ -#define UNIITTEST_DEBUG +#define UNITTEST_DEBUG #include #include #define private public diff --git a/unittest/share/redolog/test_log_file_handler.cpp b/unittest/share/redolog/test_log_file_handler.cpp index 2dd28bfda..35c83017d 100644 --- a/unittest/share/redolog/test_log_file_handler.cpp +++ b/unittest/share/redolog/test_log_file_handler.cpp @@ -243,7 +243,6 @@ TEST_F(TestLogFileHandler, file_read) ret = file_handler.write((void *) buf, TestLogFileHandler::DIO_WRITE_ALIGN_SIZE, 0); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(0, file_handler.get_pwrite_ts()); ret = file_handler.close(); ASSERT_EQ(OB_SUCCESS, ret); diff --git a/unittest/share/scheduler/test_dag_net_in_dag_scheduler.cpp b/unittest/share/scheduler/test_dag_net_in_dag_scheduler.cpp index a421a7f0d..34b862e6a 100644 --- a/unittest/share/scheduler/test_dag_net_in_dag_scheduler.cpp +++ b/unittest/share/scheduler/test_dag_net_in_dag_scheduler.cpp @@ -18,6 +18,7 @@ #define private public #include "share/scheduler/ob_dag_scheduler.h" #include "lib/atomic/ob_atomic.h" +#include "lib/alloc/ob_malloc_allocator.h" #include "observer/omt/ob_tenant_node_balancer.h" #include "share/scheduler/ob_dag_warning_history_mgr.h" #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" @@ -49,6 +50,7 @@ namespace oceanbase using namespace common; using namespace share; using namespace omt; +using namespace lib; namespace storage { @@ -67,6 +69,7 @@ public: TestDagScheduler() : tenant_id_(500), scheduler_(nullptr), + dag_history_mgr_(nullptr), tenant_base_(500) {} ~TestDagScheduler() {} @@ -84,9 +87,16 @@ public: scheduler_ = OB_NEW(ObTenantDagScheduler, ObModIds::TEST); tenant_base_.set(scheduler_); + dag_history_mgr_ = OB_NEW(ObDagWarningHistoryManager, ObModIds::TEST); + tenant_base_.set(dag_history_mgr_); + ObTenantEnv::set_tenant(&tenant_base_); ASSERT_EQ(OB_SUCCESS, tenant_base_.init()); + ObMallocAllocator *ma = ObMallocAllocator::get_instance(); + ASSERT_EQ(OB_SUCCESS, ma->create_and_add_tenant_allocator(tenant_id_)); + ASSERT_EQ(OB_SUCCESS, ma->set_tenant_limit(tenant_id_, 1LL << 30)); + ASSERT_EQ(OB_SUCCESS, t3m->init()); ASSERT_EQ(OB_SUCCESS, scheduler_->init(tenant_id_, time_slice, check_waiting_list_period, MAX_DAG_CNT)); } @@ -94,6 +104,8 @@ public: { scheduler_->destroy(); scheduler_ = nullptr; + dag_history_mgr_->~ObDagWarningHistoryManager(); + dag_history_mgr_ = nullptr; tenant_base_.destroy(); ObTenantEnv::set_tenant(nullptr); } @@ -101,6 +113,7 @@ private: const static int64_t MAX_DAG_CNT = 64; const uint64_t tenant_id_; ObTenantDagScheduler *scheduler_; + ObDagWarningHistoryManager *dag_history_mgr_; ObTenantBase tenant_base_; DISALLOW_COPY_AND_ASSIGN(TestDagScheduler); }; @@ -131,7 +144,17 @@ public: } return bret; } - virtual int fill_comment(char *buf,const int64_t size) const override { UNUSEDx(buf, size); return OB_SUCCESS; } + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, + ObIAllocator &allocator) const override + { + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), id_, id_+1, "is_test", true))) { + COMMON_LOG(WARN, "fail to add dag warning info param", K(ret)); + } + return ret; + } virtual int fill_dag_key(char *buf,const int64_t size) const override { UNUSEDx(buf, size); return OB_SUCCESS; } virtual lib::Worker::CompatMode get_compat_mode() const override { return lib::Worker::CompatMode::MYSQL; } @@ -193,7 +216,6 @@ public: } return common::OB_SUCCESS; } - bool check_can_retry() { bool bret = true; @@ -229,13 +251,16 @@ TEST_F(TestDagScheduler, test_task_wait_to_schedule) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); - ObWaitDag *dag = NULL; + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + EXPECT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis")); + for (int i = 0; i < 10; ++i) { - EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag(nullptr, dag)); + EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag(nullptr)); } wait_scheduler(); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + EXPECT_EQ(0, MTL(ObDagWarningHistoryManager *)->size()); } /* @@ -313,14 +338,16 @@ TEST_F(TestDagScheduler, test_task_retry) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + EXPECT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis")); for (int i = 0; i < 2; ++i) { - ObTaskRetryDag *dag = NULL; - EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag(nullptr, dag)); + EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag(nullptr)); } wait_scheduler(); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + EXPECT_EQ(0, MTL(ObDagWarningHistoryManager *)->size()); } class ObDagRetryTask : public ObITask @@ -432,6 +459,9 @@ TEST_F(TestDagScheduler, test_dag_retry) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + EXPECT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis")); int ret = OB_SUCCESS; for (int i = 0; OB_SUCC(ret) && i < 5; ++i) { @@ -442,16 +472,17 @@ TEST_F(TestDagScheduler, test_dag_retry) param.id_ = i + 1; snprintf(str, str_len, "Hello OceanBase_%d", i); param.str_ = ObString(str); - if (OB_FAIL(scheduler->create_and_add_dag(¶m, dag))) { - COMMON_LOG(WARN, "failed to create first task", K(ret)); - } else { - dag->set_max_retry_times(3); + if (OB_FAIL(scheduler->create_dag(¶m, dag))) { + COMMON_LOG(WARN, "failed to create dag", K(ret)); + } else if (FALSE_IT(dag->set_max_retry_times(3))) { + } else if (OB_FAIL(scheduler->add_dag(dag))) { + COMMON_LOG(WARN, "failed to add dag", K(ret)); } EXPECT_EQ(OB_SUCCESS, ret); } wait_scheduler(); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + EXPECT_EQ(0, MTL(ObDagWarningHistoryManager *)->size()); } class ObOperator @@ -751,14 +782,16 @@ TEST_F(TestDagScheduler, test_basic_dag_net) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + EXPECT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis")); - ObFatherDagNet *dag_net = nullptr; for (int i = 0; i < 2; ++i) { - EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr, dag_net)); + EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr)); } wait_scheduler(); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + EXPECT_EQ(0, MTL(ObDagWarningHistoryManager *)->size()); } class ObFatherWithRetryDagNet : public ObFatherDagNet @@ -822,14 +855,16 @@ TEST_F(TestDagScheduler, test_basic_dag_net_with_one_retry_dag) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + EXPECT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis")); - ObFatherWithRetryDagNet *dag_net = nullptr; for (int i = 0; i < 1; ++i) { - EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr, dag_net)); + EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr)); } wait_scheduler(); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + EXPECT_EQ(0, MTL(ObDagWarningHistoryManager *)->size()); } /* @@ -902,15 +937,24 @@ TEST_F(TestDagScheduler, test_generage_task_failed) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis")); + int ret = OB_SUCCESS; ObGenerateFailedDag *dag = nullptr; for (int i = 0; i < 1; ++i) { - EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag(nullptr, dag)); - dag->set_max_retry_times(7); + if (OB_FAIL(scheduler->create_dag(nullptr, dag))) { + COMMON_LOG(WARN, "failed to create dag", K(ret)); + } else if (FALSE_IT(dag->set_max_retry_times(7))) { + } else if (OB_FAIL(scheduler->add_dag(dag))) { + COMMON_LOG(WARN, "failed to add dag", K(ret)); + } + EXPECT_EQ(OB_SUCCESS, ret); } wait_scheduler(); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + ASSERT_EQ(1, MTL(ObDagWarningHistoryManager *)->size()); } //generate next dag @@ -1233,6 +1277,9 @@ TEST_F(TestDagScheduler, generate_next_dag) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + EXPECT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis")); ObStartGenerateNextDag *dag = nullptr; EXPECT_EQ(OB_SUCCESS, scheduler->alloc_dag(dag)); @@ -1241,7 +1288,7 @@ TEST_F(TestDagScheduler, generate_next_dag) EXPECT_EQ(OB_SUCCESS, scheduler->add_dag(dag)); wait_scheduler(); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + EXPECT_EQ(0, MTL(ObDagWarningHistoryManager *)->size()); } class ObCreateChildTask : public ObITask @@ -1377,11 +1424,14 @@ TEST_F(TestDagScheduler, test_add_dag_failed_in_generate_dag_net) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); - ObCreateDagNet *dag_net = nullptr; - EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr, dag_net)); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis")); + + ASSERT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr)); wait_scheduler(); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + ASSERT_EQ(1, MTL(ObDagWarningHistoryManager *)->size()); } class ObFreeDagNet: public ObFatherDagNet @@ -1426,11 +1476,14 @@ TEST_F(TestDagScheduler, test_free_dag_func) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); - ObFreeDagNet *dag_net = nullptr; - EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr, dag_net)); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + EXPECT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis")); + + EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr)); wait_scheduler(); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + EXPECT_EQ(0, MTL(ObDagWarningHistoryManager *)->size()); } class ObCancelDag : public ObBasicDag @@ -1493,8 +1546,16 @@ TEST_F(TestDagScheduler, test_cancel_dag_func) { ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); - ObCancelDagNet *dag_net = nullptr; - EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr, dag_net)); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + EXPECT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis")); + + EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr)); + ObIDagNet *tmp_dag_net = nullptr; + EXPECT_EQ(OB_SUCCESS, scheduler->get_first_dag_net(tmp_dag_net)); + EXPECT_NE(nullptr, tmp_dag_net); + + ObCancelDagNet *dag_net = static_cast(tmp_dag_net); while (scheduler->get_cur_dag_cnt() < 3) { usleep(100); @@ -1508,7 +1569,7 @@ TEST_F(TestDagScheduler, test_cancel_dag_func) } EXPECT_EQ(true, scheduler->is_empty()); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + EXPECT_EQ(0, MTL(ObDagWarningHistoryManager *)->size()); } @@ -1518,8 +1579,12 @@ TEST_F(TestDagScheduler, test_cancel_dag_net_func) int ret = OB_SUCCESS; ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); ASSERT_TRUE(nullptr != scheduler); - ObCancelDagNet *dag_net = nullptr; - EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr, dag_net)); + EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr)); + ObIDagNet *tmp_dag_net = nullptr; + EXPECT_EQ(OB_SUCCESS, scheduler->get_first_dag_net(tmp_dag_net)); + EXPECT_NE(nullptr, tmp_dag_net); + + ObCancelDagNet *dag_net = static_cast(tmp_dag_net); while (scheduler->get_cur_dag_cnt() < 3) { usleep(100); @@ -1538,24 +1603,24 @@ TEST_F(TestDagScheduler, test_cancel_dag_net_func) ob_usleep(5000 * 1000); EXPECT_EQ(true, scheduler->is_empty()); - EXPECT_EQ(0, ObDagWarningHistoryManager::get_instance().size()); + EXPECT_EQ(0, MTL(ObDagWarningHistoryManager *)->size()); } -TEST_F(TestDagScheduler, test_destroy_when_running) +TEST_F(TestDagScheduler, test_destroy_when_running) //TODO(renju.rj): fix it { - ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); - ASSERT_TRUE(nullptr != scheduler); - - #ifndef BUILD_COVERAGE - // not participate in coverage compilation to fix hang problem - ObCancelDagNet *dag_net = nullptr; - EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr, dag_net)); - - while (scheduler->get_cur_dag_cnt() < 3) { - usleep(100); - } - #endif +// ObTenantDagScheduler *scheduler = MTL(ObTenantDagScheduler*); +// ASSERT_TRUE(nullptr != scheduler); +// +// #ifndef BUILD_COVERAGE +// // not participate in coverage compilation to fix hang problem +// ObCancelDagNet *dag_net = nullptr; +// EXPECT_EQ(OB_SUCCESS, scheduler->create_and_add_dag_net(nullptr)); +// +// while (scheduler->get_cur_dag_cnt() < 3) { +// usleep(100); +// } +// #endif } diff --git a/unittest/share/scheduler/test_dag_scheduler.cpp b/unittest/share/scheduler/test_dag_scheduler.cpp index 19f48f486..cda4ad386 100644 --- a/unittest/share/scheduler/test_dag_scheduler.cpp +++ b/unittest/share/scheduler/test_dag_scheduler.cpp @@ -424,10 +424,14 @@ public: void set_id(int64_t id) { id_ = id; } AtomicOperator &get_op() { return op_; } void set_running() { running_ = true; } - int fill_comment(char *buf,const int64_t size) const { + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, + ObIAllocator &allocator) const override + { int ret = OB_SUCCESS; - if (OB_ISNULL(buf) || size <0) { - COMMON_LOG(INFO,"buf is NULL",K(ret),K(size)); + if (!is_inited_) { + ret = OB_NOT_INIT; + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), 1, 1, "table_id", 10))) { + COMMON_LOG(WARN, "fail to add dag warning info param", K(ret)); } return ret; } @@ -479,7 +483,7 @@ private: class TestHALowDag : public TestDag { public: - TestHALowDag() : TestDag(ObDagType::DAG_TYPE_BACKUP) {} + TestHALowDag() : TestDag(ObDagType::DAG_TYPE_BACKUP_PREPARE) {} private: DISALLOW_COPY_AND_ASSIGN(TestHALowDag); }; @@ -800,6 +804,7 @@ public: TestDagScheduler() : tenant_id_(500), scheduler_(nullptr), + dag_history_mgr_(nullptr), tenant_base_(500), allocator_("DagScheduler") { } @@ -809,18 +814,29 @@ public: scheduler_ = OB_NEW(ObTenantDagScheduler, ObModIds::TEST); tenant_base_.set(scheduler_); + dag_history_mgr_ = OB_NEW(ObDagWarningHistoryManager, ObModIds::TEST); + tenant_base_.set(dag_history_mgr_); + ObTenantEnv::set_tenant(&tenant_base_); ASSERT_EQ(OB_SUCCESS, tenant_base_.init()); + + ObMallocAllocator *ma = ObMallocAllocator::get_instance(); + ASSERT_EQ(OB_SUCCESS, ma->create_and_add_tenant_allocator(tenant_id_)); + ASSERT_EQ(OB_SUCCESS, ma->set_tenant_limit(tenant_id_, 1LL << 30)); } void TearDown() { scheduler_->destroy(); + scheduler_ = nullptr; + dag_history_mgr_->~ObDagWarningHistoryManager(); + dag_history_mgr_ = nullptr; tenant_base_.destroy(); ObTenantEnv::set_tenant(nullptr); } private: const uint64_t tenant_id_; ObTenantDagScheduler *scheduler_; + ObDagWarningHistoryManager *dag_history_mgr_; ObTenantBase tenant_base_; ObArenaAllocator allocator_; DISALLOW_COPY_AND_ASSIGN(TestDagScheduler); diff --git a/unittest/share/test_ob_function.cpp b/unittest/share/test_ob_function.cpp index e3f28ba39..3541d1e8f 100644 --- a/unittest/share/test_ob_function.cpp +++ b/unittest/share/test_ob_function.cpp @@ -10,7 +10,7 @@ * See the Mulan PubL v2 for more details. */ -#define UNIITTEST_DEBUG +#define UNITTEST_DEBUG #include "lib/function/ob_function.h" #include "lib/container/ob_array.h" diff --git a/unittest/share/test_ob_future.cpp b/unittest/share/test_ob_future.cpp index 9c7bd75b1..b6ca32162 100644 --- a/unittest/share/test_ob_future.cpp +++ b/unittest/share/test_ob_future.cpp @@ -10,7 +10,7 @@ * See the Mulan PubL v2 for more details. */ -#define UNIITTEST_DEBUG +#define UNITTEST_DEBUG #include "lib/future/ob_future.h" #include diff --git a/unittest/share/test_ob_guard.cpp b/unittest/share/test_ob_guard.cpp index 8a3f72c15..d9c30b267 100644 --- a/unittest/share/test_ob_guard.cpp +++ b/unittest/share/test_ob_guard.cpp @@ -10,7 +10,7 @@ * See the Mulan PubL v2 for more details. */ -#define UNIITTEST_DEBUG +#define UNITTEST_DEBUG #include "lib/guard/ob_shared_guard.h" #include "lib/guard/ob_unique_guard.h" diff --git a/unittest/share/test_ob_occam_thread_pool.cpp b/unittest/share/test_ob_occam_thread_pool.cpp index cc9dcaaf2..5e46415ec 100644 --- a/unittest/share/test_ob_occam_thread_pool.cpp +++ b/unittest/share/test_ob_occam_thread_pool.cpp @@ -10,7 +10,7 @@ * See the Mulan PubL v2 for more details. */ -#define UNIITTEST_DEBUG +#define UNITTEST_DEBUG #include "share/ob_occam_thread_pool.h" #include diff --git a/unittest/share/test_ob_occam_time_guard.cpp b/unittest/share/test_ob_occam_time_guard.cpp index 201d708df..eae620ada 100644 --- a/unittest/share/test_ob_occam_time_guard.cpp +++ b/unittest/share/test_ob_occam_time_guard.cpp @@ -10,7 +10,7 @@ * See the Mulan PubL v2 for more details. */ -#define UNIITTEST_DEBUG +#define UNITTEST_DEBUG #include "share/ob_occam_time_guard.h" #include #include @@ -101,6 +101,7 @@ int main(int argc, char **argv) { system("rm -rf test_ob_occam_time_guard.log"); oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + oceanbase::common::ObTscTimestamp::get_instance().init(); logger.set_file_name("test_ob_occam_time_guard.log", false); logger.set_log_level(OB_LOG_LEVEL_DEBUG); testing::InitGoogleTest(&argc, argv); diff --git a/unittest/share/test_ob_occam_timer.cpp b/unittest/share/test_ob_occam_timer.cpp index 67371d4fd..81f65eefc 100644 --- a/unittest/share/test_ob_occam_timer.cpp +++ b/unittest/share/test_ob_occam_timer.cpp @@ -10,7 +10,7 @@ * See the Mulan PubL v2 for more details. */ -#define UNIITTEST_DEBUG +#define UNITTEST_DEBUG #include "share/ob_occam_timer.h" #include @@ -206,7 +206,7 @@ TEST_F(TestObOccamTimer, hung) { TEST_F(TestObOccamTimer, stop_and_wait) { int ret = OB_SUCCESS; - ret = occam_timer->schedule_task_ignore_handle_repeat_and_immediately(20_ms, [](){ return false; }); + ret = occam_timer->schedule_task_ignore_handle_repeat(20_s, [](){ return false; }); ASSERT_EQ(ret, OB_SUCCESS); occam_timer->destroy(); } diff --git a/unittest/sql/executor/test_disk_interm_result.cpp b/unittest/sql/executor/test_disk_interm_result.cpp index c6ecd5bb3..972472aab 100644 --- a/unittest/sql/executor/test_disk_interm_result.cpp +++ b/unittest/sql/executor/test_disk_interm_result.cpp @@ -70,9 +70,7 @@ TEST_F(TestDiskIntermResult, disk_write_read) ret = ObIntermResultManager::get_instance()->alloc_result(ir); ASSERT_EQ(OB_SUCCESS, ret); lib::ObMallocAllocator *malloc_allocator = lib::ObMallocAllocator::get_instance(); - ret = malloc_allocator->create_tenant_ctx_allocator(OB_SYS_TENANT_ID); - ASSERT_EQ(OB_SUCCESS, ret); - ret = malloc_allocator->create_tenant_ctx_allocator(OB_SYS_TENANT_ID, common::ObCtxIds::WORK_AREA); + ret = malloc_allocator->create_and_add_tenant_allocator(OB_SYS_TENANT_ID); ASSERT_EQ(OB_SUCCESS, ret); malloc_allocator->set_tenant_limit(OB_SYS_TENANT_ID, 1L << 30); ASSERT_EQ(OB_SUCCESS, ret); diff --git a/unittest/sql/optimizer/storage_perf/ob_storage_perf_data.cpp b/unittest/sql/optimizer/storage_perf/ob_storage_perf_data.cpp index 61a276203..3c7fc9756 100644 --- a/unittest/sql/optimizer/storage_perf/ob_storage_perf_data.cpp +++ b/unittest/sql/optimizer/storage_perf/ob_storage_perf_data.cpp @@ -232,7 +232,6 @@ int ObStoragePerfData::backup_sstable_meta(ObSSTable &sstable) int64_t pos = 0; char *buf = NULL; ObArenaAllocator allocator(ObModIds::TEST); - ObIAllocator &tenant_allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); if(-1 == (fd = open(sstable_meta_path_, O_RDONLY, 0777))){ ret = OB_ERR_UNEXPECTED; @@ -249,9 +248,7 @@ int ObStoragePerfData::backup_sstable_meta(ObSSTable &sstable) } else if (size != read(fd, buf, size)){ ret = OB_ERR_UNEXPECTED; STORAGE_LOG(ERROR, "fail to read meta"); - } else if(OB_SUCCESS != (ret = sstable.deserialize(tenant_allocator, buf, size, pos))){ - STORAGE_LOG(WARN, "fail to deserialize sstable", K(ret)); - } else if(OB_SUCCESS != (ret = sstable.deserialize_post_work())){ + } else if(OB_SUCCESS != (ret = sstable.deserialize(allocator_, buf, size, pos))){ STORAGE_LOG(WARN, "fail to deserialize sstable", K(ret)); } else { STORAGE_LOG(INFO, "backup sstable meta success"); diff --git a/unittest/sql/optimizer/storage_perf/ob_storage_perf_read.cpp b/unittest/sql/optimizer/storage_perf/ob_storage_perf_read.cpp index 8721ed18d..396264e0b 100644 --- a/unittest/sql/optimizer/storage_perf/ob_storage_perf_read.cpp +++ b/unittest/sql/optimizer/storage_perf/ob_storage_perf_read.cpp @@ -1111,7 +1111,6 @@ int ObStoragePerfRead::backup_sstable_meta(ObSSTable &sstable) int64_t pos = 0; char *buf = NULL; ObArenaAllocator allocator(ObModIds::TEST); - ObIAllocator &tenant_allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); if(-1 == (fd = open(sstable_meta_path_, O_RDONLY, 0777))){ ret = OB_ERR_UNEXPECTED; @@ -1128,9 +1127,7 @@ int ObStoragePerfRead::backup_sstable_meta(ObSSTable &sstable) } else if (size != read(fd, buf, size)){ ret = OB_ERR_UNEXPECTED; STORAGE_LOG(ERROR, "fail to read meta"); - } else if(OB_SUCCESS != (ret = sstable.deserialize(tenant_allocator, buf, size, pos))){ - STORAGE_LOG(WARN, "fail to deserialize sstable", K(ret)); - } else if(OB_SUCCESS != (ret = sstable.deserialize_post_work())){ + } else if(OB_SUCCESS != (ret = sstable.deserialize(allocator_, buf, size, pos))){ STORAGE_LOG(WARN, "fail to deserialize sstable", K(ret)); } else { STORAGE_LOG(INFO, "backup sstable meta success"); diff --git a/unittest/storage/CMakeLists.txt b/unittest/storage/CMakeLists.txt index 86b07a869..7f9a047e8 100644 --- a/unittest/storage/CMakeLists.txt +++ b/unittest/storage/CMakeLists.txt @@ -44,9 +44,18 @@ storage_unittest(test_row_fuse) storage_unittest(test_query_engine memtable/mvcc/test_query_engine.cpp) storage_unittest(test_memtable_basic memtable/test_memtable_basic.cpp) storage_unittest(test_mvcc_callback memtable/mvcc/test_mvcc_callback.cpp) +# storage_unittest(test_mds_compile multi_data_source/test_mds_compile.cpp) +storage_unittest(test_mds_list multi_data_source/test_mds_list.cpp) +storage_unittest(test_mds_node multi_data_source/test_mds_node.cpp) +# storage_unittest(test_mds_row multi_data_source/test_mds_row.cpp) +# storage_unittest(test_mds_unit multi_data_source/test_mds_unit.cpp) +storage_unittest(test_mds_table multi_data_source/test_mds_table.cpp) +storage_unittest(test_mds_table_flush multi_data_source/test_mds_table_flush.cpp) +storage_unittest(test_mds_dump_kv multi_data_source/test_mds_dump_kv.cpp) #storage_unittest(test_multiple_merge) #storage_unittest(test_memtable_multi_version_row_iterator memtable/test_memtable_multi_version_row_iterator.cpp) #storage_unittest(test_new_table_store) +storage_unittest(test_mds_table_handle multi_data_source/test_mds_table_handle.cpp) storage_unittest(test_fixed_size_block_allocator) storage_unittest(test_dag_warning_history) storage_unittest(test_storage_schema) @@ -75,8 +84,8 @@ storage_unittest(test_partition_major_sstable_range_spliter) storage_unittest(test_parallel_minor_dag) storage_dml_unittest(test_partition_range_splite) storage_dml_unittest(test_major_rows_merger) +storage_dml_unittest(test_tablet tablet/test_tablet.cpp) #storage_dml_unittest(test_table_scan_pure_index_table) storage_unittest(test_sstable_log_ts_range_cut test_sstable_log_ts_range_cut.cpp) -storage_unittest(test_medium_compaction_mgr test_medium_compaction_mgr.cpp) diff --git a/unittest/storage/backup/test_backup_index_merger.cpp b/unittest/storage/backup/test_backup_index_merger.cpp index f3bb71844..0e358c6ae 100644 --- a/unittest/storage/backup/test_backup_index_merger.cpp +++ b/unittest/storage/backup/test_backup_index_merger.cpp @@ -381,7 +381,7 @@ void TestBackupIndexMerger::fake_init_meta_index_merger_(ObFakeBackupMetaIndexMe ObBackupIndexMergeParam merge_param; build_backup_index_merge_param_(merge_param); const bool is_sec_meta = false; - ret = merger.init(merge_param, is_sec_meta, sql_proxy, throttle_); + ret = merger.init(merge_param, is_sec_meta, sql_proxy); EXPECT_EQ(OB_SUCCESS, ret); } @@ -394,7 +394,7 @@ void TestBackupIndexMerger::fake_init_macro_index_merger_(ObFakeBackupMacroIndex const int64_t file_count = 80; const int64_t per_file_item_count = 1024; merger.set_count(file_count, per_file_item_count); - ret = merger.init(merge_param, sql_proxy, throttle_); + ret = merger.init(merge_param, sql_proxy); EXPECT_EQ(OB_SUCCESS, ret); } diff --git a/unittest/storage/backup/test_backup_iterator.cpp b/unittest/storage/backup/test_backup_iterator.cpp index bf7c8398a..43092868d 100644 --- a/unittest/storage/backup/test_backup_iterator.cpp +++ b/unittest/storage/backup/test_backup_iterator.cpp @@ -171,7 +171,7 @@ void TestBackupIndexIterator::fake_init_macro_index_merger_(const int64_t file_c ObBackupIndexMergeParam merge_param; build_backup_index_merge_param_(merge_param); merger.set_count(file_count, per_file_item_count); - ret = merger.init(merge_param, sql_proxy, throttle_); + ret = merger.init(merge_param, sql_proxy); ASSERT_EQ(OB_SUCCESS, ret); } diff --git a/unittest/storage/blocksstable/encoding/CMakeLists.txt b/unittest/storage/blocksstable/encoding/CMakeLists.txt index ba9300eac..1a9d5b04e 100644 --- a/unittest/storage/blocksstable/encoding/CMakeLists.txt +++ b/unittest/storage/blocksstable/encoding/CMakeLists.txt @@ -7,4 +7,4 @@ storage_unittest(test_hex) storage_unittest(test_encoding_util) storage_unittest(test_raw_decoder) storage_unittest(test_const_decoder) -storage_unittest(test_general_column_decoder) \ No newline at end of file +storage_unittest(test_general_column_decoder) diff --git a/unittest/storage/blocksstable/encoding/test_column_decoder.h b/unittest/storage/blocksstable/encoding/test_column_decoder.h index 352d908b1..5f761b6f9 100644 --- a/unittest/storage/blocksstable/encoding/test_column_decoder.h +++ b/unittest/storage/blocksstable/encoding/test_column_decoder.h @@ -29,6 +29,7 @@ #include "lib/string/ob_sql_string.h" #include "../ob_row_generate.h" #include "common/rowkey/ob_rowkey.h" +#include "unittest/storage/mock_ob_table_read_info.h" namespace oceanbase { @@ -103,7 +104,7 @@ protected: ObMicroBlockEncodingCtx ctx_; common::ObArray col_descs_; ObMicroBlockEncoder encoder_; - ObTableReadInfo read_info_; + MockObTableReadInfo read_info_; ObArenaAllocator allocator_; bool is_retro_; ObColumnHeader::Type column_encoding_type_; @@ -247,8 +248,7 @@ void TestColumnDecoder::SetUp() table.get_column_count(), table.get_rowkey_column_num(), lib::is_oracle_mode(), - col_descs_, - true)); + col_descs_)); ctx_.micro_block_size_ = 64L << 11; ctx_.macro_block_size_ = 2L << 20; diff --git a/unittest/storage/blocksstable/encoding/test_const_decoder.cpp b/unittest/storage/blocksstable/encoding/test_const_decoder.cpp index 1ef244595..a9919283c 100644 --- a/unittest/storage/blocksstable/encoding/test_const_decoder.cpp +++ b/unittest/storage/blocksstable/encoding/test_const_decoder.cpp @@ -657,7 +657,7 @@ TEST_F(TestConstDecoder, batch_decode_to_datum_test_with_expection) int main(int argc, char **argv) { system("rm -f test_const_decoder.log*"); - OB_LOGGER.set_file_name("test_const_decoder.log", true, false); + OB_LOGGER.set_file_name("test_const_decoder.log"); oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/unittest/storage/blocksstable/encoding/test_micro_block_encoder.cpp b/unittest/storage/blocksstable/encoding/test_micro_block_encoder.cpp index 905ae9b0f..d3c3a7a7e 100644 --- a/unittest/storage/blocksstable/encoding/test_micro_block_encoder.cpp +++ b/unittest/storage/blocksstable/encoding/test_micro_block_encoder.cpp @@ -56,7 +56,7 @@ protected: ObObjType *col_types_; ObRowGenerate row_generate_; ObMicroBlockEncodingCtx ctx_; - ObTableReadInfo read_info_; + ObRowkeyReadInfo read_info_; ObArenaAllocator allocator_; common::ObArray col_descs_; bool is_multi_version_row_; @@ -65,6 +65,7 @@ protected: void TestIColumnEncoder::SetUp() { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); const int64_t tid = 200001; ObTableSchema table; ObColumnSchemaV2 col; @@ -105,8 +106,7 @@ void TestIColumnEncoder::SetUp() row_generate_.get_schema().get_column_count(), row_generate_.get_schema().get_rowkey_column_num(), lib::is_oracle_mode(), - col_descs_, - true)); + col_descs_)); ctx_.micro_block_size_ = 1L << 20; // 1MB, maximum micro block size; ctx_.macro_block_size_ = 2L << 20; @@ -217,7 +217,7 @@ TEST_F(TestDictLargeVarchar, test_dict_large_varchar) ObMicroBlockDecoder decoder; ObDatumRow read_row; ASSERT_EQ(OB_SUCCESS, read_row.init(full_column_cnt_)); - ASSERT_EQ(OB_SUCCESS, decoder.init(micro_data, read_info_)); + ASSERT_EQ(OB_SUCCESS, decoder.init(micro_data, nullptr)); ASSERT_EQ(OB_SUCCESS, decoder.get_row(0, read_row)); STORAGE_LOG(DEBUG, "read row", K(read_row)); @@ -304,7 +304,7 @@ TEST_F(TestColumnEqualExceptionList, test_column_equal_ext_offset_overflow) ObMicroBlockDecoder decoder; ObDatumRow read_row; ASSERT_EQ(OB_SUCCESS, read_row.init(column_cnt_)); - ASSERT_EQ(OB_SUCCESS, decoder.init(micro_data, read_info_)); + ASSERT_EQ(OB_SUCCESS, decoder.init(micro_data, nullptr)); int64_t new_checksum = 0; for (int64_t i = 0; i < row_cnt; ++i) { @@ -337,7 +337,7 @@ TEST_F(TestEncodingRowBufHolder, test_encoding_row_buf_holder) ASSERT_EQ(OB_SUCCESS, buf_holder.init(OB_DEFAULT_MACRO_BLOCK_SIZE)); ASSERT_EQ(OB_INVALID_ARGUMENT, buf_holder.try_alloc(4 * OB_DEFAULT_MACRO_BLOCK_SIZE)); const char *test_mark = "fly me to the moon"; - + const int test_mark_len = strlen(test_mark); const int64_t first_alloc_size = 4096; const int64_t snd_alloc_size = static_cast(first_alloc_size * 1.2); @@ -365,7 +365,7 @@ TEST_F(TestEncodingRowBufHolder, test_encoding_row_buf_holder) int main(int argc, char **argv) { system("rm -f test_micro_block_encoder.log*"); - OB_LOGGER.set_file_name("test_micro_block_encoder.log", true, false); + OB_LOGGER.set_file_name("test_micro_block_encoder.log"); oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/unittest/storage/blocksstable/encoding/test_raw_decoder.cpp b/unittest/storage/blocksstable/encoding/test_raw_decoder.cpp index 576367aae..2d37bb682 100644 --- a/unittest/storage/blocksstable/encoding/test_raw_decoder.cpp +++ b/unittest/storage/blocksstable/encoding/test_raw_decoder.cpp @@ -27,6 +27,7 @@ #include "lib/string/ob_sql_string.h" #include "../ob_row_generate.h" #include "common/rowkey/ob_rowkey.h" +#include "unittest/storage/mock_ob_table_read_info.h" namespace oceanbase @@ -205,7 +206,7 @@ public: virtual void SetUp(); virtual void TearDown() {} - TestRawDecoder():tenant_ctx_(OB_SERVER_TENANT_ID) + TestRawDecoder(): tenant_ctx_(OB_SERVER_TENANT_ID) { share::ObTenantEnv::set_tenant(&tenant_ctx_); } @@ -224,7 +225,7 @@ protected: ObMicroBlockEncodingCtx ctx_; common::ObArray col_descs_; ObMicroBlockRawEncoder encoder_; - ObTableReadInfo read_info_; + MockObTableReadInfo read_info_; int64_t full_column_cnt_; ObArenaAllocator allocator_; share::ObTenantBase tenant_ctx_; @@ -232,6 +233,7 @@ protected: void TestRawDecoder::SetUp() { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); const int64_t tid = 200001; ObTableSchema table; ObColumnSchemaV2 col; @@ -299,8 +301,7 @@ void TestRawDecoder::SetUp() table.get_column_count(), table.get_rowkey_column_num(), lib::is_oracle_mode(), - col_descs_, - true)); + col_descs_)); const int64_t extra_rowkey_cnt = ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); full_column_cnt_ = COLUMN_CNT + extra_rowkey_cnt; @@ -532,11 +533,6 @@ TEST_F(TestRawDecoder, filter_push_down_gt_lt_ge_le) ASSERT_EQ(OB_SUCCESS, test_filter_pushdown(col_idx, decoder, white_filter, result_bitmap, objs)); ASSERT_EQ(seed0_count + seed1_count, result_bitmap.popcnt()); - - // Invalid input parameter - objs.pop_back(); - ASSERT_EQ(objs.count(), 0); - ASSERT_EQ(OB_INVALID_ARGUMENT, test_filter_pushdown(col_idx, decoder, white_filter, result_bitmap, objs)); } } diff --git a/unittest/storage/blocksstable/ob_data_file_prepare.h b/unittest/storage/blocksstable/ob_data_file_prepare.h index 4bdb2faa7..bf6d7dbf7 100644 --- a/unittest/storage/blocksstable/ob_data_file_prepare.h +++ b/unittest/storage/blocksstable/ob_data_file_prepare.h @@ -177,6 +177,7 @@ int TestDataFilePrepareUtil::init( storage_env_.user_row_cache_priority_ = 1; storage_env_.fuse_row_cache_priority_ = 1; storage_env_.tablet_ls_cache_priority_ = 1; + storage_env_.storage_meta_cache_priority_ = 10; storage_env_.ethernet_speed_ = 1000000; storage_env_.redundancy_level_ = ObStorageEnv::NORMAL_REDUNDANCY; @@ -288,7 +289,8 @@ int TestDataFilePrepareUtil::open() storage_env_.user_row_cache_priority_, storage_env_.fuse_row_cache_priority_, storage_env_.bf_cache_priority_, - storage_env_.bf_cache_miss_count_threshold_))) { + storage_env_.bf_cache_miss_count_threshold_, + storage_env_.storage_meta_cache_priority_))) { STORAGE_LOG(WARN, "Fail to init OB_STORE_CACHE, ", K(ret), K(storage_env_.data_dir_)); } else if (OB_FAIL(ObIOManager::get_instance().start())) { STORAGE_LOG(WARN, "Fail to star io mgr", K(ret)); diff --git a/unittest/storage/blocksstable/ob_multi_version_sstable_test.h b/unittest/storage/blocksstable/ob_multi_version_sstable_test.h index 12f47f81e..274e09ac8 100644 --- a/unittest/storage/blocksstable/ob_multi_version_sstable_test.h +++ b/unittest/storage/blocksstable/ob_multi_version_sstable_test.h @@ -37,6 +37,7 @@ #include "share/ob_simple_mem_limit_getter.h" #include "../mockcontainer/mock_ob_iterator.h" #include "storage/tablet/ob_tablet_create_sstable_param.h" +#include "unittest/storage/mock_ob_table_read_info.h" #define OK(ass) ASSERT_EQ(OB_SUCCESS, (ass)) @@ -97,6 +98,7 @@ int init_io_device(const char *test_name, storage_env.user_block_cache_priority_ = 1; storage_env.user_row_cache_priority_ = 1; storage_env.fuse_row_cache_priority_ = 1; + storage_env.storage_meta_cache_priority_ = 10; storage_env.ethernet_speed_ = 1000000; storage_env.redundancy_level_ = ObStorageEnv::NORMAL_REDUNDANCY; @@ -128,7 +130,8 @@ int init_io_device(const char *test_name, storage_env.user_row_cache_priority_, storage_env.fuse_row_cache_priority_, storage_env.bf_cache_priority_, - storage_env.bf_cache_miss_count_threshold_))) { + storage_env.bf_cache_miss_count_threshold_, + storage_env.storage_meta_cache_priority_))) { STORAGE_LOG(WARN, "Fail to init OB_STORE_CACHE, ", K(ret), K(storage_env.data_dir_)); } } @@ -191,7 +194,6 @@ protected: ObMergeType merge_type_; ObTenantFreezeInfoMgr *mgr_; ObTableSchema table_schema_; - ObTableSchema index_schema_; ObITable::TableKey table_key_; ObDataStoreDesc data_desc_; @@ -208,15 +210,17 @@ protected: ObFixedArray full_cols_; ObTableIterParam iter_param_; ObTableAccessContext context_; - ObTableReadInfo full_read_info_; + storage::MockObTableReadInfo full_read_info_; ObDatumRow datum_row_; - ObArenaAllocator allocator_; + static ObArenaAllocator allocator_; char test_name_[100]; MockObMetaReport rs_reporter_; MockDiskUsageReport disk_reporter_; }; +ObArenaAllocator ObMultiVersionSSTableTest::allocator_; + void ObMultiVersionSSTableTest::SetUpTestCase() { int ret = OB_SUCCESS; @@ -227,16 +231,8 @@ void ObMultiVersionSSTableTest::SetUpTestCase() ObServerCheckpointSlogHandler::get_instance().is_started_ = true; //OK(init_io_device("multi_version_test")); - const int64_t bucket_num = 1024L; - const int64_t max_cache_size = 1024L * 1024L * 512; - const int64_t block_size = common::OB_MALLOC_BIG_BLOCK_SIZE; ObIOManager::get_instance().add_tenant_io_manager( tenant_id_, ObTenantIOConfig::default_instance()); - OK(ObKVGlobalCache::get_instance().init(&getter, - bucket_num, - max_cache_size, - block_size)); - OK(OB_STORE_CACHE.init(10, 1, 1, 1, 1, 10000)); // create ls ObLSHandle ls_handle; @@ -264,7 +260,6 @@ ObMultiVersionSSTableTest::ObMultiVersionSSTableTest( : merge_type_(merge_type), mgr_(nullptr), table_schema_(), - index_schema_(), row_store_type_(row_store_type), root_index_builder_(nullptr), data_iter_cursor_(0), @@ -278,6 +273,7 @@ ObMultiVersionSSTableTest::~ObMultiVersionSSTableTest() void ObMultiVersionSSTableTest::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); } void ObMultiVersionSSTableTest::TearDown() @@ -338,8 +334,7 @@ void ObMultiVersionSSTableTest::prepare_table_schema( column_cnt - extra_rowkey_cnt, schema_rowkey_cnt, lib::is_oracle_mode(), - tmp_col_descs, - true)); + tmp_col_descs)); //init table schema table_schema_.reset(); @@ -355,26 +350,12 @@ void ObMultiVersionSSTableTest::prepare_table_schema( table_schema_.set_row_store_type(FLAT_ROW_STORE); table_schema_.set_storage_format_version(OB_STORAGE_FORMAT_VERSION_V4); - index_schema_.reset(); - ASSERT_EQ(OB_SUCCESS, index_schema_.set_table_name("test_index_block")); - index_schema_.set_tenant_id(tenant_id_); - index_schema_.set_tablegroup_id(1); - index_schema_.set_database_id(1); - index_schema_.set_table_id(table_id_); - index_schema_.set_rowkey_column_num(full_read_info_.get_schema_rowkey_count()); - index_schema_.set_max_used_column_id(common::OB_APP_MIN_COLUMN_ID + full_read_info_.get_request_count()); - index_schema_.set_block_size(2 * 1024); - index_schema_.set_compress_func_name("none"); - index_schema_.set_row_store_type(FLAT_ROW_STORE); - index_schema_.set_storage_format_version(OB_STORAGE_FORMAT_VERSION_V4); - ObColumnSchemaV2 column; //init column char name[OB_MAX_FILE_NAME_LENGTH]; memset(name, 0, sizeof(name)); column_cnt = full_read_info_.get_request_count(); - const common::ObIArray &cols_desc = full_read_info_.get_columns_desc(); - for(int64_t i = 0; i < cols_desc.count(); ++i) { + for(int64_t i = 0; i < tmp_col_descs.count(); ++i) { column.reset(); bool is_rowkey_col = false; if (i < schema_rowkey_cnt) { @@ -386,24 +367,13 @@ void ObMultiVersionSSTableTest::prepare_table_schema( column.set_table_id(table_id_); sprintf(name, "test%020ld", i); ASSERT_EQ(OB_SUCCESS, column.set_column_name(name)); - column.set_data_type(cols_desc.at(i).col_type_.get_type()); - column.set_column_id(cols_desc.at(i).col_id_); + column.set_data_type(tmp_col_descs.at(i).col_type_.get_type()); + column.set_column_id(tmp_col_descs.at(i).col_id_); column.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); column.set_data_length(1); ASSERT_EQ(OB_SUCCESS, table_schema_.add_column(column)); - if (is_rowkey_col) { - ASSERT_EQ(OB_SUCCESS, index_schema_.add_column(column)); - } } column.reset(); - column.set_table_id(table_id_); - column.set_column_id(column_cnt + OB_APP_MIN_COLUMN_ID); - ASSERT_EQ(OB_SUCCESS, column.set_column_name("Index block data")); - column.set_data_type(ObVarcharType); - column.set_collation_type(CS_TYPE_BINARY); - column.set_data_length(1); - column.set_rowkey_position(0); - ASSERT_EQ(OB_SUCCESS, index_schema_.add_column(column)); table_key_.table_type_ = get_merged_table_type(); table_key_.tablet_id_ = tablet_id_; @@ -419,12 +389,15 @@ void ObMultiVersionSSTableTest::prepare_table_schema( ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); ObTabletHandle tablet_handle; + void *ptr = nullptr; ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); ObTablet *tablet = tablet_handle.get_obj(); - tablet->storage_schema_.reset(); - tablet->storage_schema_.init(*tablet->allocator_, table_schema_, lib::Worker::CompatMode::MYSQL); - tablet->full_read_info_.reset(); - tablet->build_read_info(*tablet->allocator_); + ASSERT_NE(nullptr, ptr = allocator_.alloc(sizeof(ObStorageSchema))); + tablet->storage_schema_addr_.ptr_ = new (ptr) ObStorageSchema(); + tablet->storage_schema_addr_.get_ptr()->init(allocator_, table_schema_, lib::Worker::CompatMode::MYSQL); + ASSERT_NE(nullptr, ptr = allocator_.alloc(sizeof(ObRowkeyReadInfo))); + tablet->rowkey_read_info_ = new (ptr) ObRowkeyReadInfo(); + tablet->build_read_info(allocator_); } void ObMultiVersionSSTableTest::reset_writer(const int64_t snapshot_version) @@ -452,7 +425,7 @@ void ObMultiVersionSSTableTest::reset_writer(const int64_t snapshot_version) data_desc_.row_store_type_ = row_store_type_; ASSERT_TRUE(data_desc_.is_valid()); - ASSERT_EQ(OB_SUCCESS, index_desc_.init(index_schema_, ls_id, tablet_id, merge_type_, snapshot_version, DATA_VERSION_4_1_0_0)); + ASSERT_EQ(OB_SUCCESS, index_desc_.init_as_index(table_schema_, ls_id, tablet_id, merge_type_, snapshot_version, DATA_VERSION_4_1_0_0)); ASSERT_TRUE(index_desc_.is_valid()); ASSERT_EQ(OB_SUCCESS, root_index_builder_->init(index_desc_)); @@ -517,10 +490,12 @@ void ObMultiVersionSSTableTest::prepare_data_end( ObSSTableMergeRes res; const int64_t column_cnt = table_schema_.get_column_count() + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); - ASSERT_EQ(OB_SUCCESS, root_index_builder_->close(column_cnt, res)); + ASSERT_EQ(OB_SUCCESS, root_index_builder_->close(res)); ObTabletCreateSSTableParam param; table_key_.table_type_ = table_type; + param.data_block_ids_ = res.data_block_ids_; + param.other_block_ids_ = res.other_block_ids_; param.table_key_ = table_key_; param.schema_version_ = SCHEMA_VERSION; param.create_snapshot_version_ = 0; @@ -561,7 +536,16 @@ void ObMultiVersionSSTableTest::prepare_data_end( ObLSService *ls_svr = MTL(ObLSService*); ObLSID lsid(ls_id_); OK(ls_svr->get_ls(lsid, ls_handle, ObLSGetMod::STORAGE_MOD)); - OK(ObTabletCreateDeleteHelper::create_sstable(param, handle)); + void *buf = allocator_.alloc(sizeof(ObSSTable)); + ASSERT_TRUE(nullptr != buf); + ObSSTable *sstable = new (buf) ObSSTable(); + OK(ObTabletCreateDeleteHelper::create_sstable(param, allocator_, *sstable)); + ObTableReadInfo read_info; + ObSEArray cols_desc; + ASSERT_EQ(OB_SUCCESS, table_schema_.get_multi_version_column_descs(cols_desc)); + ASSERT_EQ(OB_SUCCESS, read_info.init(allocator_, table_schema_.get_rowkey_column_num() + 1, + table_schema_.get_rowkey_column_num(), false, cols_desc, nullptr/*storage_cols_index*/)); + ASSERT_EQ(OB_SUCCESS, handle.set_sstable(sstable, &allocator_)); } void ObMultiVersionSSTableTest::prepare_data( diff --git a/unittest/storage/blocksstable/test_block_manager.cpp b/unittest/storage/blocksstable/test_block_manager.cpp index e06f475e8..3f4651e48 100644 --- a/unittest/storage/blocksstable/test_block_manager.cpp +++ b/unittest/storage/blocksstable/test_block_manager.cpp @@ -96,27 +96,27 @@ TEST_F(TestBlockManager, test_inc_and_dec_ref_cnt) ASSERT_TRUE(macro_id.is_valid()); ret = OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(1, block_info.mem_ref_cnt_); + ASSERT_EQ(1, block_info.ref_cnt_); ASSERT_TRUE(block_info.access_time_ > 0); ret = OB_SERVER_BLOCK_MGR.inc_ref(macro_id); ASSERT_EQ(OB_SUCCESS, ret); ret = OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(2, block_info.mem_ref_cnt_); + ASSERT_EQ(2, block_info.ref_cnt_); ASSERT_TRUE(block_info.access_time_ > 0); ret = OB_SERVER_BLOCK_MGR.dec_ref(macro_id); ASSERT_EQ(OB_SUCCESS, ret); ret = OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(1, block_info.mem_ref_cnt_); + ASSERT_EQ(1, block_info.ref_cnt_); ASSERT_TRUE(block_info.access_time_ > 0); macro_handle.reset(); ret = OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(0, block_info.mem_ref_cnt_); + ASSERT_EQ(0, block_info.ref_cnt_); ASSERT_TRUE(block_info.access_time_ > 0); } @@ -155,7 +155,7 @@ TEST_F(TestBlockManager, test_mark_and_sweep) ASSERT_TRUE(macro_id.is_valid()); ret = OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(1, block_info.mem_ref_cnt_); + ASSERT_EQ(1, block_info.ref_cnt_); ASSERT_TRUE(block_info.access_time_ > 0); } @@ -213,32 +213,25 @@ TEST_F(TestBlockManager, test_ref_cnt_wash_and_load) ret = OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(2, block_info.mem_ref_cnt_); - ASSERT_EQ(0, block_info.disk_ref_cnt_); + ASSERT_EQ(2, block_info.ref_cnt_); ASSERT_TRUE(block_info.access_time_ > 0); // test wash block - ret = OB_SERVER_BLOCK_MGR.inc_disk_ref(macro_id); - ASSERT_EQ(OB_SUCCESS, ret); ret = OB_SERVER_BLOCK_MGR.dec_ref(macro_id); ASSERT_EQ(OB_SUCCESS, ret); ret = OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(1, block_info.mem_ref_cnt_); - ASSERT_EQ(1, block_info.disk_ref_cnt_); + ASSERT_EQ(1, block_info.ref_cnt_); ASSERT_TRUE(block_info.access_time_ > 0); // test load block ret = OB_SERVER_BLOCK_MGR.inc_ref(macro_id); ASSERT_EQ(OB_SUCCESS, ret); - ret = OB_SERVER_BLOCK_MGR.dec_disk_ref(macro_id); - ASSERT_EQ(OB_SUCCESS, ret); ret = OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(2, block_info.mem_ref_cnt_); - ASSERT_EQ(0, block_info.disk_ref_cnt_); + ASSERT_EQ(2, block_info.ref_cnt_); ASSERT_TRUE(block_info.access_time_ > 0); ret = OB_SERVER_BLOCK_MGR.dec_ref(macro_id); @@ -246,15 +239,14 @@ TEST_F(TestBlockManager, test_ref_cnt_wash_and_load) ret = OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(1, block_info.mem_ref_cnt_); - ASSERT_EQ(0, block_info.disk_ref_cnt_); + ASSERT_EQ(1, block_info.ref_cnt_); ASSERT_TRUE(block_info.access_time_ > 0); macro_handle.reset(); ret = OB_SERVER_BLOCK_MGR.block_map_.get(macro_id, block_info); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(0, block_info.mem_ref_cnt_); + ASSERT_EQ(0, block_info.ref_cnt_); ASSERT_TRUE(block_info.access_time_ > 0); } diff --git a/unittest/storage/blocksstable/test_micro_block_reader.cpp b/unittest/storage/blocksstable/test_micro_block_reader.cpp index 7f3f34017..6d8bc41f6 100644 --- a/unittest/storage/blocksstable/test_micro_block_reader.cpp +++ b/unittest/storage/blocksstable/test_micro_block_reader.cpp @@ -49,8 +49,6 @@ public: TestMicroBlockReader() : allocator_(ObModIds::TEST), read_info_() { } void SetUp(); virtual void TearDown() {} - static void SetUpTestCase() {} - static void TearDownTestCase() {} protected: ObRowGenerate row_generate_; @@ -60,6 +58,7 @@ protected: void TestMicroBlockReader::SetUp() { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); const int64_t table_id = 3001; ObTableSchema table_schema; ObColumnSchemaV2 column; @@ -141,7 +140,7 @@ TEST_F(TestMicroBlockReader, test_success) ObArray columns; ASSERT_EQ(OB_SUCCESS, row_generate_.get_schema().get_column_ids(columns)); ASSERT_EQ(OB_SUCCESS, read_info_.init( - allocator_, 16000, row_generate_.get_schema().get_rowkey_column_num(), lib::is_oracle_mode(), columns)); + allocator_, 16000, row_generate_.get_schema().get_rowkey_column_num(), lib::is_oracle_mode(), columns, nullptr/*storage_cols_index*/)); /*** init reader ***/ ObMicroBlockReader reader; ObMicroBlockData block(buf, size); diff --git a/unittest/storage/blocksstable/test_micro_block_writer.cpp b/unittest/storage/blocksstable/test_micro_block_writer.cpp index 7cb115cf4..402c68c19 100644 --- a/unittest/storage/blocksstable/test_micro_block_writer.cpp +++ b/unittest/storage/blocksstable/test_micro_block_writer.cpp @@ -42,8 +42,6 @@ public: TestMicroBlockWriter() : allocator_(ObModIds::TEST), read_info_() {}; void SetUp(); virtual void TearDown() {} - static void SetUpTestCase() {} - static void TearDownTestCase() {} void test_alloc(char *&ptr, const int64_t size); protected: @@ -78,6 +76,7 @@ void TestMicroBlockWriter::test_alloc(char *&ptr, const int64_t size) void TestMicroBlockWriter::SetUp() { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); const int64_t table_id = 3001; ObTableSchema table_schema; ObColumnSchemaV2 column; @@ -168,7 +167,7 @@ TEST_F(TestMicroBlockWriter, append_success) ASSERT_EQ(OB_SUCCESS, row_generate_.get_schema().get_column_ids(columns)); ObTableReadInfo read_info; ASSERT_EQ(OB_SUCCESS, read_info_.init( - allocator_, 16000, row_generate_.get_schema().get_rowkey_column_num(), lib::is_oracle_mode(), columns)); + allocator_, 16000, row_generate_.get_schema().get_rowkey_column_num(), lib::is_oracle_mode(), columns, nullptr/*storage_cols_index*/)); ObMicroBlockReader reader; ObMicroBlockData block(buf, size); ret = reader.init(block, read_info_); diff --git a/unittest/storage/blocksstable/test_row_reader.cpp b/unittest/storage/blocksstable/test_row_reader.cpp index a532cf1af..b7cbe1336 100644 --- a/unittest/storage/blocksstable/test_row_reader.cpp +++ b/unittest/storage/blocksstable/test_row_reader.cpp @@ -26,6 +26,7 @@ #include "storage/blocksstable/ob_row_reader.h" #include "ob_data_file_prepare.h" #include "storage/memtable/ob_nop_bitmap.h" +#include "unittest/storage/mock_ob_table_read_info.h" #ifndef INT24_MIN #define INT24_MIN (-8388607 - 1) @@ -48,6 +49,7 @@ static ObSimpleMemLimitGetter getter; namespace unittest { + class TestNewRowReader : public TestDataFilePrepare { public: @@ -82,7 +84,7 @@ private: char *serialize_buf_; protected: ObRowGenerate row_generate_; - ObTableReadInfo read_info_; + MockObTableReadInfo read_info_; ObTableSchema table_schema_; ObArenaAllocator allocator_; common::ObArray full_schema_cols_; @@ -95,9 +97,6 @@ int TestNewRowReader::init_read_columns( { int ret = OB_SUCCESS; read_info_.reset(); - read_info_.cols_desc_.set_allocator(&allocator_); - read_info_.cols_index_.set_allocator(&allocator_); - read_info_.cols_param_.set_allocator(&allocator_); cols_desc.reuse(); for (int64_t i = 0; OB_SUCC(ret) && i < projector.count(); ++i) { ObColDesc col_desc; @@ -123,21 +122,14 @@ int TestNewRowReader::init_read_columns( } if (OB_FAIL(read_info_.init( allocator_, - 16000, + writer_row.count_, row_generate_.get_schema().get_rowkey_column_num(), lib::is_oracle_mode(), cols_desc, - true, &projector))) { STORAGE_LOG(WARN, "failed to init column map"); } - read_info_.schema_column_count_ = 10000; - read_info_.schema_rowkey_cnt_ = row_generate_.get_schema().get_rowkey_column_num(); - read_info_.seq_read_column_count_ = read_info_.schema_rowkey_cnt_; - read_info_.cols_desc_.assign(cols_desc); - read_info_.cols_index_.assign(projector); - read_info_.rowkey_cnt_ = read_info_.schema_rowkey_cnt_; - read_info_.datum_utils_.init(cols_desc, read_info_.rowkey_cnt_, lib::is_oracle_mode(), allocator_); + return ret; } @@ -170,12 +162,11 @@ int TestNewRowReader::init_read_columns( col_desc.col_id_ = i + 30; ret = cols_desc.push_back(col_desc); } - if (OB_FAIL(read_info_.init(allocator_, 16000, + if (OB_FAIL(read_info_.init(allocator_, writer_row.count_, row_generate_.get_schema().get_rowkey_column_num(), lib::is_oracle_mode(), cols_desc))) { STORAGE_LOG(WARN, "failed to init column map"); } - read_info_.rowkey_cnt_ = read_info_.schema_rowkey_cnt_; return ret; } @@ -251,12 +242,10 @@ void TestNewRowReader::build_column_read_info(const int64_t rowkey_column_count, ObColDesc col_desc; // col desc is no use in flat reader for (int i = 0; i < writer_row.row_val_.count_; ++i) { + col_desc.col_id_ = i + common::OB_APP_MIN_COLUMN_ID; full_schema_cols_.push_back(col_desc); } - read_info_.init(allocator_, 16000, rowkey_column_count, lib::is_oracle_mode(), full_schema_cols_, true); - read_info_.rowkey_cnt_ = rowkey_column_count; - read_info_.memtable_cols_index_.reuse(); - read_info_.memtable_cols_index_.assign(read_info_.cols_index_); + read_info_.init(allocator_, writer_row.row_val_.count_, rowkey_column_count, lib::is_oracle_mode(), full_schema_cols_); } void TestNewRowReader::build_column_read_info(const int64_t rowkey_column_count, const ObDatumRow &writer_row) @@ -267,12 +256,10 @@ void TestNewRowReader::build_column_read_info(const int64_t rowkey_column_count, ObColDesc col_desc; // col desc is no use in flat reader for (int i = 0; i < writer_row.count_; ++i) { + col_desc.col_id_ = i + common::OB_APP_MIN_COLUMN_ID; full_schema_cols_.push_back(col_desc); } - read_info_.init(allocator_, 16000, rowkey_column_count, lib::is_oracle_mode(), full_schema_cols_, true); - read_info_.rowkey_cnt_ = rowkey_column_count; - read_info_.memtable_cols_index_.reuse(); - read_info_.memtable_cols_index_.assign(read_info_.cols_index_); + read_info_.init(allocator_, writer_row.count_, rowkey_column_count, lib::is_oracle_mode(), full_schema_cols_); } void TestNewRowReader::check_read_datum_row( @@ -370,7 +357,7 @@ void TestNewRowReader::check_read_datums(const char* buf, const int64_t buf_len, ObRowWriter row_writer; ret = row_writer.write(rowkey_cnt, datum_row, extra_buf, len); ASSERT_EQ(OB_SUCCESS, ret); - STORAGE_LOG(INFO, "check_read_datums, write datums"); + STORAGE_LOG(INFO, "check_read_datums, write datums", K(datum_row)); // read with ObTableReadInfo ObRowReader row_reader2; @@ -839,7 +826,6 @@ TEST_F(TestNewRowReader, test_read_row) &read_info_, reader_row); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_TRUE(column_num == reader_row.count_); //every obj should equal for (int64_t i = 0; i < column_num; ++i) { @@ -962,7 +948,7 @@ TEST_F(TestNewRowReader, test_read_row_in_random_order) reader_row.count_ = num; ret = row_reader.read_row(buf, pos, &read_info_, reader_row); ASSERT_EQ(OB_SUCCESS, ret); - + STORAGE_LOG(INFO, "projector2", K(reader_row), K(writer_row)); for (int i = 0; i < reader_row.count_; ++i) { STORAGE_LOG(INFO, "projector2", K(i), K(column_idx_array2[i]), K(reader_row.storage_datums_[i])); ObStorageDatum datum; @@ -1643,7 +1629,7 @@ TEST_F(TestLoopCells, test_loop_cells) int main(int argc, char **argv) { system("rm -rf test_row_reader.log"); - OB_LOGGER.set_file_name("test_row_reader.log", true, true); + OB_LOGGER.set_file_name("test_row_reader.log"); oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/unittest/storage/blocksstable/test_sstable_meta.cpp b/unittest/storage/blocksstable/test_sstable_meta.cpp index 8896ddd88..f39524287 100644 --- a/unittest/storage/blocksstable/test_sstable_meta.cpp +++ b/unittest/storage/blocksstable/test_sstable_meta.cpp @@ -20,11 +20,13 @@ #include "common/ob_tablet_id.h" #include "share/ob_simple_mem_limit_getter.h" #include "storage/blocksstable/ob_sstable_meta.h" +#include "storage/blocksstable/ob_sstable.h" #include "storage/blocksstable/ob_block_manager.h" #include "storage/blocksstable/ob_data_file_prepare.h" #include "storage/blocksstable/ob_index_block_builder.h" #include "storage/schema_utils.h" #include "storage/ls/ob_ls_tablet_service.h" +#include "storage/tablet/ob_tablet_meta.h" namespace oceanbase { @@ -71,6 +73,7 @@ TestRootBlockInfo::TestRootBlockInfo() void TestRootBlockInfo::SetUp() { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); TestDataFilePrepare::SetUp(); prepare_tablet_read_info(); des_meta_.encrypt_id_ = ObAesOpMode::ob_invalid_mode; @@ -100,7 +103,7 @@ void TestRootBlockInfo::prepare_tablet_read_info() desc.col_order_ = ObOrderType::ASC; ASSERT_EQ(OB_SUCCESS, columns.push_back(desc)); } - ASSERT_EQ(OB_SUCCESS, table_read_info_.init(allocator_, schema_version, ROWKEY_COL_CNT, lib::is_oracle_mode(), columns, true)); + ASSERT_EQ(OB_SUCCESS, table_read_info_.init(allocator_, schema_version, ROWKEY_COL_CNT, lib::is_oracle_mode(), columns, nullptr/*storage_cols_index*/)); } void TestRootBlockInfo::prepare_block_root() @@ -154,7 +157,7 @@ void TestRootBlockInfo::prepare_block_root() write_info.size_ = buf_size; ASSERT_EQ(OB_SUCCESS, ObBlockManager::write_block(write_info, handle)); block_addr_.second_id_ = handle.get_macro_id().second_id(); - ASSERT_EQ(OB_SUCCESS, root_info_.init_root_block_info(&allocator_, block_addr_, block_data_)); + ASSERT_EQ(OB_SUCCESS, root_info_.init_root_block_info(allocator_, block_addr_, block_data_)); ASSERT_TRUE(root_info_.is_valid()); } @@ -165,19 +168,33 @@ public: virtual ~TestSSTableMacroInfo() = default; virtual void SetUp() override; virtual void TearDown() override; +private: + void prepare_create_sstable_param(); private: ObTabletCreateSSTableParam param_; + ObTabletID tablet_id_; + int64_t data_version_; + int64_t snapshot_version_; + share::schema::ObTableSchema table_schema_; + common::ObArenaAllocator allocator_; }; TestSSTableMacroInfo::TestSSTableMacroInfo() : TestRootBlockInfo(), - param_() + param_(), + tablet_id_(1), + data_version_(0), + snapshot_version_(0), + table_schema_(), + allocator_() { } void TestSSTableMacroInfo::SetUp() { TestRootBlockInfo::SetUp(); + TestSchemaUtils::prepare_data_schema(table_schema_); + prepare_create_sstable_param(); param_.data_block_macro_meta_addr_ = block_addr_; param_.data_block_macro_meta_ = block_data_; } @@ -187,6 +204,42 @@ void TestSSTableMacroInfo::TearDown() TestRootBlockInfo::TearDown(); } +void TestSSTableMacroInfo::prepare_create_sstable_param() +{ + const int64_t multi_version_col_cnt = ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + param_.table_key_.table_type_ = ObITable::TableType::MAJOR_SSTABLE; + param_.table_key_.tablet_id_ = tablet_id_; + param_.table_key_.version_range_.base_version_ = ObVersionRange::MIN_VERSION; + param_.table_key_.version_range_.snapshot_version_ = snapshot_version_; + param_.schema_version_ = table_schema_.get_schema_version(); + param_.create_snapshot_version_ = 0; + param_.progressive_merge_round_ = table_schema_.get_progressive_merge_round(); + param_.progressive_merge_step_ = 0; + param_.table_mode_ = table_schema_.get_table_mode_struct(); + param_.index_type_ = table_schema_.get_index_type(); + param_.rowkey_column_cnt_ = table_schema_.get_rowkey_column_num() + + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + param_.root_block_addr_.set_none_addr(); + param_.data_block_macro_meta_addr_.set_none_addr(); + param_.root_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + param_.latest_row_store_type_ = ObRowStoreType::DUMMY_ROW_STORE; + param_.data_index_tree_height_ = 0; + param_.index_blocks_cnt_ = 0; + param_.data_blocks_cnt_ = 0; + param_.micro_block_cnt_ = 0; + param_.use_old_macro_block_count_ = 0; + param_.column_cnt_ = table_schema_.get_column_count() + multi_version_col_cnt; + param_.data_checksum_ = 0; + param_.occupy_size_ = 0; + param_.ddl_scn_.set_min(); + param_.filled_tx_scn_.set_min(); + param_.original_size_ = 0; + param_.compressor_type_ = ObCompressorType::NONE_COMPRESSOR; + param_.encrypt_id_ = 0; + param_.master_key_id_ = 0; + ASSERT_EQ(OB_SUCCESS, ObSSTableMergeRes::fill_column_checksum_for_empty_major(param_.column_cnt_, param_.column_checksums_)); +} + class TestSSTableMeta : public TestDataFilePrepare { public: @@ -291,11 +344,11 @@ void TestMigrationSSTableParam::SetUp() ASSERT_TRUE(!sstable_meta_.is_valid()); sstable_meta_.reset(); ASSERT_TRUE(!sstable_meta_.is_valid()); - ASSERT_EQ(OB_SUCCESS, sstable_meta_.init(param_, &allocator_)); + ASSERT_EQ(OB_SUCCESS, sstable_meta_.init(param_, allocator_)); ASSERT_TRUE(sstable_meta_.is_valid()); ASSERT_TRUE(sstable_meta_.data_root_info_.is_valid()); ASSERT_TRUE(sstable_meta_.macro_info_.is_valid()); - ASSERT_TRUE(sstable_meta_.get_col_checksum().count() > 0); + ASSERT_TRUE(sstable_meta_.get_col_checksum_cnt() > 0); table_key_.table_type_ = ObITable::TableType::MAJOR_SSTABLE; table_key_.tablet_id_ = 1101; table_key_.version_range_.base_version_ = 0; @@ -314,8 +367,8 @@ void TestMigrationSSTableParam::TearDown() TEST_F(TestRootBlockInfo, test_load_and_transform_root_block) { ASSERT_TRUE(root_info_.get_addr().is_block()); - ASSERT_EQ(OB_SUCCESS, root_info_.load_root_block_data(des_meta_)); - ASSERT_EQ(OB_SUCCESS, root_info_.transform_root_block_data(table_read_info_)); + ASSERT_EQ(OB_SUCCESS, root_info_.load_root_block_data(allocator_, des_meta_)); + ASSERT_EQ(OB_SUCCESS, root_info_.transform_root_block_data(allocator_)); } TEST_F(TestRootBlockInfo, test_serialize_and_deserialize) @@ -332,12 +385,11 @@ TEST_F(TestRootBlockInfo, test_serialize_and_deserialize) ObRootBlockInfo tmp_info; pos = 0; - ASSERT_EQ(OB_SUCCESS, tmp_info.deserialize(&allocator_, des_meta_, buf, buf_len_1, pos)); + ASSERT_EQ(OB_SUCCESS, tmp_info.deserialize(allocator_, des_meta_, buf, buf_len_1, pos)); ASSERT_EQ(buf_len_1, pos); ASSERT_TRUE(tmp_info.is_valid()); ASSERT_EQ(root_info_.get_addr(), tmp_info.get_addr()); - ASSERT_EQ(root_info_.get_block_data().type_, tmp_info.get_block_data().type_); - ASSERT_EQ(0, memcmp(tmp_info.get_block_data().get_buf(), block_data_.get_buf(), block_data_.get_buf_size())); + ASSERT_EQ(0, memcmp(tmp_info.block_data_.get_buf(), block_data_.get_buf(), block_data_.get_buf_size())); delete [] buf; // test memory address. @@ -351,7 +403,7 @@ TEST_F(TestRootBlockInfo, test_serialize_and_deserialize) block_data.buf_ = data; block_data.size_ = BUF_LEN; block_data.type_ = ObMicroBlockData::INDEX_BLOCK; - ASSERT_EQ(OB_SUCCESS, root_info_.init_root_block_info(&allocator_, addr, block_data)); + ASSERT_EQ(OB_SUCCESS, root_info_.init_root_block_info(allocator_, addr, block_data)); ASSERT_TRUE(root_info_.is_valid()); ASSERT_TRUE(root_info_.get_addr().is_memory()); @@ -363,13 +415,13 @@ TEST_F(TestRootBlockInfo, test_serialize_and_deserialize) ASSERT_TRUE(root_info_.is_valid()); pos = 0; - ASSERT_EQ(OB_SUCCESS, tmp_info.deserialize(&allocator_, des_meta_, buf, buf_len_2, pos)); + tmp_info.reset(); + ASSERT_EQ(OB_SUCCESS, tmp_info.deserialize(allocator_, des_meta_, buf, buf_len_2, pos)); ASSERT_EQ(buf_len_2, pos); ASSERT_TRUE(tmp_info.is_valid()); ASSERT_EQ(root_info_.get_addr(), tmp_info.get_addr()); - ASSERT_EQ(root_info_.get_block_data().type_, tmp_info.get_block_data().type_); ASSERT_TRUE(tmp_info.get_addr().is_memory()); - ASSERT_EQ(0, memcmp(tmp_info.get_block_data().get_buf(), block_data.buf_, BUF_LEN)); + ASSERT_EQ(0, memcmp(tmp_info.block_data_.get_buf(), block_data.buf_, BUF_LEN)); delete [] buf; // test none address. @@ -377,7 +429,7 @@ TEST_F(TestRootBlockInfo, test_serialize_and_deserialize) ASSERT_TRUE(!root_info_.is_valid()); addr.set_none_addr(); block_data.type_ = ObMicroBlockData::INDEX_BLOCK; - ASSERT_EQ(OB_SUCCESS, root_info_.init_root_block_info(&allocator_, addr, block_data)); + ASSERT_EQ(OB_SUCCESS, root_info_.init_root_block_info(allocator_, addr, block_data)); ASSERT_TRUE(root_info_.is_valid()); ASSERT_TRUE(root_info_.get_addr().is_none()); @@ -390,11 +442,11 @@ TEST_F(TestRootBlockInfo, test_serialize_and_deserialize) ASSERT_TRUE(root_info_.get_addr().is_none()); pos = 0; - ASSERT_EQ(OB_SUCCESS, tmp_info.deserialize(&allocator_, des_meta_, buf, buf_len_3, pos)); + tmp_info.reset(); + ASSERT_EQ(OB_SUCCESS, tmp_info.deserialize(allocator_, des_meta_, buf, buf_len_3, pos)); ASSERT_EQ(buf_len_3, pos); ASSERT_TRUE(tmp_info.is_valid()); ASSERT_EQ(root_info_.get_addr(), tmp_info.get_addr()); - ASSERT_EQ(root_info_.get_block_data().type_, tmp_info.get_block_data().type_); delete [] buf; } @@ -404,11 +456,11 @@ TEST_F(TestSSTableMacroInfo, test_serialize_and_deserialize) ASSERT_TRUE(!sstable_macro_info.is_valid()); sstable_macro_info.reset(); ASSERT_TRUE(!sstable_macro_info.is_valid()); - ASSERT_EQ(OB_SUCCESS, sstable_macro_info.init_macro_info(&allocator_, param_)); + ASSERT_EQ(OB_SUCCESS, sstable_macro_info.init_macro_info(allocator_, param_)); ASSERT_TRUE(sstable_macro_info.is_valid()); ASSERT_EQ(block_addr_, sstable_macro_info.get_macro_meta_addr()); - ASSERT_EQ(0, sstable_macro_info.get_data_block_ids().count()); - ASSERT_EQ(0, sstable_macro_info.get_other_block_ids().count()); + ASSERT_EQ(0, sstable_macro_info.get_data_block_count()); + ASSERT_EQ(0, sstable_macro_info.get_other_block_count()); int64_t pos = 0; const int64_t buf_len = sstable_macro_info.get_serialize_size(); @@ -418,42 +470,69 @@ TEST_F(TestSSTableMacroInfo, test_serialize_and_deserialize) ObSSTableMacroInfo tmp_info; pos = 0; - ASSERT_EQ(OB_SUCCESS, tmp_info.deserialize(&allocator_, des_meta_, buf, buf_len, pos)); + ASSERT_EQ(OB_SUCCESS, tmp_info.deserialize(allocator_, des_meta_, buf, buf_len, pos)); ASSERT_TRUE(tmp_info.is_valid()); ASSERT_EQ(block_addr_, tmp_info.get_macro_meta_addr()); - ASSERT_EQ(0, tmp_info.get_data_block_ids().count()); - ASSERT_EQ(0, tmp_info.get_other_block_ids().count()); + ASSERT_EQ(0, tmp_info.get_data_block_count()); + ASSERT_EQ(0, tmp_info.get_other_block_count()); ASSERT_EQ(sstable_macro_info.macro_meta_info_.addr_, tmp_info.macro_meta_info_.addr_); - ASSERT_EQ(sstable_macro_info.data_block_ids_.count(), tmp_info.data_block_ids_.count()); - ASSERT_EQ(sstable_macro_info.other_block_ids_.count(), tmp_info.other_block_ids_.count()); + ASSERT_EQ(sstable_macro_info.data_block_count_, tmp_info.data_block_count_); + ASSERT_EQ(sstable_macro_info.other_block_count_, tmp_info.other_block_count_); } TEST_F(TestSSTableMacroInfo, test_huge_block_ids) { ObSSTableMacroInfo sstable_macro_info; - ASSERT_EQ(OB_SUCCESS, sstable_macro_info.init_macro_info(&allocator_, param_)); MacroBlockId block_id; - sstable_macro_info.data_block_ids_.set_capacity(blocksstable::ObSSTableMacroInfo::BLOCK_CNT_THRESHOLD); - sstable_macro_info.other_block_ids_.set_capacity(1); + block_id.second_id_ = 10000; + ASSERT_EQ(OB_SUCCESS, param_.other_block_ids_.push_back(block_id)); for (int64_t i = 0; i < blocksstable::ObSSTableMacroInfo::BLOCK_CNT_THRESHOLD; i++) { block_id.reset(); block_id.second_id_ = ObRandom::rand(1, 10<<10); - ASSERT_EQ(OB_SUCCESS, sstable_macro_info.data_block_ids_.push_back(block_id)); + ASSERT_EQ(OB_SUCCESS, param_.data_block_ids_.push_back(block_id)); } - + ASSERT_EQ(OB_SUCCESS, sstable_macro_info.init_macro_info(allocator_, param_)); int64_t pos = 0; const int64_t buf_len = sstable_macro_info.get_serialize_size(); char *buf = new char[buf_len]; + ASSERT_NE(nullptr, sstable_macro_info.linked_block_ids_); + ASSERT_NE(0, sstable_macro_info.linked_block_count_); ASSERT_EQ(OB_SUCCESS, sstable_macro_info.serialize(buf, buf_len, pos)); - ASSERT_NE(0, sstable_macro_info.linked_block_ids_.count()); + ASSERT_NE(nullptr, sstable_macro_info.linked_block_ids_); + ASSERT_NE(0, sstable_macro_info.linked_block_count_); ObSSTableMacroInfo tmp_info; pos = 0; - ASSERT_EQ(OB_SUCCESS, tmp_info.deserialize(&allocator_, des_meta_, buf, buf_len, pos)); + ASSERT_EQ(OB_SUCCESS, tmp_info.deserialize(allocator_, des_meta_, buf, buf_len, pos)); + ObMacroIdIterator iter; + ASSERT_EQ(OB_SUCCESS, tmp_info.get_data_block_iter(iter)); for (int i = 0; i < blocksstable::ObSSTableMacroInfo::BLOCK_CNT_THRESHOLD; i++) { - ASSERT_EQ(sstable_macro_info.data_block_ids_.at(i), tmp_info.data_block_ids_.at(i)); + MacroBlockId macro_id; + ASSERT_EQ(OB_SUCCESS, iter.get_next_macro_id(macro_id)); + ASSERT_EQ(param_.data_block_ids_.at(i), macro_id); } + ASSERT_EQ(sstable_macro_info.data_block_count_, tmp_info.data_block_count_); + ASSERT_EQ(sstable_macro_info.other_block_count_, tmp_info.other_block_count_); + ASSERT_EQ(sstable_macro_info.entry_id_, tmp_info.entry_id_); + ASSERT_EQ(sstable_macro_info.linked_block_count_, tmp_info.linked_block_count_); + + ObSSTableMacroInfo deep_copy_info; + const int64_t variable_size = sstable_macro_info.get_variable_size(); + char *d_buf = new char [variable_size]; + pos = 0; + sstable_macro_info.deep_copy(d_buf, variable_size, pos, deep_copy_info); + ASSERT_NE(nullptr, deep_copy_info.linked_block_ids_); + ASSERT_NE(0, deep_copy_info.linked_block_count_); + iter.reset(); + ASSERT_EQ(OB_SUCCESS, deep_copy_info.get_data_block_iter(iter)); + for (int i = 0; i < blocksstable::ObSSTableMacroInfo::BLOCK_CNT_THRESHOLD; i++) { + MacroBlockId macro_id; + ASSERT_EQ(OB_SUCCESS, iter.get_next_macro_id(macro_id)); + ASSERT_EQ(param_.data_block_ids_.at(i), macro_id); + } + ASSERT_EQ(sstable_macro_info.data_block_count_, deep_copy_info.data_block_count_); + ASSERT_EQ(sstable_macro_info.other_block_count_, deep_copy_info.other_block_count_); } TEST_F(TestSSTableMeta, test_empty_sstable_serialize_and_deserialize) @@ -462,11 +541,11 @@ TEST_F(TestSSTableMeta, test_empty_sstable_serialize_and_deserialize) ASSERT_TRUE(!sstable_meta.is_valid()); sstable_meta.reset(); ASSERT_TRUE(!sstable_meta.is_valid()); - ASSERT_EQ(OB_SUCCESS, sstable_meta.init(param_, &allocator_)); + ASSERT_EQ(OB_SUCCESS, sstable_meta.init(param_, allocator_)); ASSERT_TRUE(sstable_meta.is_valid()); ASSERT_TRUE(sstable_meta.data_root_info_.is_valid()); ASSERT_TRUE(sstable_meta.macro_info_.is_valid()); - ASSERT_TRUE(sstable_meta.get_col_checksum().count() > 0); + ASSERT_TRUE(sstable_meta.get_col_checksum_cnt() > 0); int64_t pos = 0; const int64_t buf_len = sstable_meta.get_serialize_size(); @@ -475,22 +554,51 @@ TEST_F(TestSSTableMeta, test_empty_sstable_serialize_and_deserialize) ASSERT_TRUE(sstable_meta.is_valid()); ASSERT_TRUE(sstable_meta.data_root_info_.is_valid()); ASSERT_TRUE(sstable_meta.macro_info_.is_valid()); - ASSERT_TRUE(sstable_meta.get_col_checksum().count() > 0); + ASSERT_TRUE(sstable_meta.get_col_checksum_cnt() > 0); ObSSTableMeta tmp_meta; pos = 0; - ASSERT_EQ(OB_SUCCESS, tmp_meta.deserialize(&allocator_, buf, buf_len, pos)); + ASSERT_EQ(OB_SUCCESS, tmp_meta.deserialize(allocator_, buf, buf_len, pos)); ASSERT_TRUE(tmp_meta.is_valid()); ASSERT_TRUE(tmp_meta.data_root_info_.is_valid()); ASSERT_TRUE(tmp_meta.macro_info_.is_valid()); - ASSERT_TRUE(tmp_meta.get_col_checksum().count() > 0); + ASSERT_TRUE(tmp_meta.get_col_checksum_cnt() > 0); ASSERT_EQ(sstable_meta.basic_meta_, tmp_meta.basic_meta_); - ASSERT_EQ(sstable_meta.column_checksums_.count(), tmp_meta.column_checksums_.count()); + ASSERT_EQ(sstable_meta.get_col_checksum_cnt(), tmp_meta.get_col_checksum_cnt()); ASSERT_EQ(sstable_meta.data_root_info_.addr_, tmp_meta.data_root_info_.addr_); - ASSERT_EQ(sstable_meta.macro_info_.data_block_ids_.count(), tmp_meta.macro_info_.data_block_ids_.count()); - ASSERT_EQ(sstable_meta.macro_info_.other_block_ids_.count(), tmp_meta.macro_info_.other_block_ids_.count()); + ASSERT_EQ(sstable_meta.macro_info_.data_block_count_, tmp_meta.macro_info_.data_block_count_); + ASSERT_EQ(sstable_meta.macro_info_.other_block_count_, tmp_meta.macro_info_.other_block_count_); free(buf); } + +TEST_F(TestSSTableMeta, test_sstable_deep_copy) +{ + ObSSTable full_sstable; + ASSERT_EQ(OB_SUCCESS, full_sstable.init(param_, &allocator_)); + const int64_t buf_len = full_sstable.get_deep_copy_size(); + char *buf = static_cast(allocator_.alloc(buf_len)); + ASSERT_TRUE(nullptr != buf); + ObIStorageMetaObj *value = nullptr; + ASSERT_EQ(OB_SUCCESS, full_sstable.deep_copy(buf, buf_len, value)); + ObSSTable *tiny_sstable = static_cast(value); + ASSERT_EQ(full_sstable.key_, tiny_sstable->key_); + ASSERT_EQ(full_sstable.valid_for_reading_, tiny_sstable->valid_for_reading_); + ASSERT_EQ(true, full_sstable.is_tmp_sstable_); + ASSERT_EQ(false, tiny_sstable->is_tmp_sstable_); + ASSERT_EQ(full_sstable.meta_->basic_meta_, tiny_sstable->meta_->basic_meta_); + ASSERT_EQ(full_sstable.meta_->data_root_info_.addr_, tiny_sstable->meta_->data_root_info_.addr_); + ASSERT_EQ(full_sstable.meta_->data_root_info_.block_data_.type_, tiny_sstable->meta_->data_root_info_.block_data_.type_); + ASSERT_EQ(full_sstable.meta_->macro_info_.macro_meta_info_.block_data_.type_, tiny_sstable->meta_->macro_info_.macro_meta_info_.block_data_.type_); + ASSERT_EQ(full_sstable.meta_->macro_info_.macro_meta_info_.addr_, tiny_sstable->meta_->macro_info_.macro_meta_info_.addr_); + ASSERT_EQ(full_sstable.meta_->macro_info_.data_block_count_, tiny_sstable->meta_->macro_info_.data_block_count_); + ASSERT_EQ(full_sstable.meta_->macro_info_.other_block_count_, tiny_sstable->meta_->macro_info_.other_block_count_); + ASSERT_EQ(full_sstable.meta_->macro_info_.linked_block_count_, tiny_sstable->meta_->macro_info_.linked_block_count_); + ASSERT_EQ(full_sstable.meta_->macro_info_.entry_id_, tiny_sstable->meta_->macro_info_.entry_id_); + ASSERT_EQ(full_sstable.meta_->column_checksum_count_, tiny_sstable->meta_->column_checksum_count_); + ASSERT_EQ(0, memcmp(full_sstable.meta_->column_checksums_, tiny_sstable->meta_->column_checksums_, full_sstable.meta_->column_checksum_count_)); + ASSERT_EQ(full_sstable.meta_->is_inited_, tiny_sstable->meta_->is_inited_); +} + TEST_F(TestMigrationSSTableParam, test_empty_sstable_serialize_and_deserialize) { ObMigrationSSTableParam mig_param; @@ -498,7 +606,9 @@ TEST_F(TestMigrationSSTableParam, test_empty_sstable_serialize_and_deserialize) mig_param.reset(); ASSERT_TRUE(!mig_param.is_valid()); mig_param.basic_meta_ = sstable_meta_.get_basic_meta(); - ASSERT_EQ(OB_SUCCESS, mig_param.column_checksums_.assign(sstable_meta_.get_col_checksum())); + for (int64_t i = 0; i < sstable_meta_.get_col_checksum_cnt(); ++i) { + ASSERT_EQ(OB_SUCCESS, mig_param.column_checksums_.push_back(sstable_meta_.get_col_checksum()[i])); + } mig_param.table_key_ = table_key_; ASSERT_TRUE(mig_param.is_valid()); ASSERT_TRUE(mig_param.basic_meta_.is_valid()); @@ -506,7 +616,7 @@ TEST_F(TestMigrationSSTableParam, test_empty_sstable_serialize_and_deserialize) ASSERT_TRUE(mig_param.table_key_.is_valid()); ASSERT_EQ(sstable_meta_.get_basic_meta(), mig_param.basic_meta_); ASSERT_EQ(table_key_, mig_param.table_key_); - ASSERT_EQ(sstable_meta_.get_col_checksum().count(), mig_param.column_checksums_.count()); + ASSERT_EQ(sstable_meta_.get_col_checksum_cnt(), mig_param.column_checksums_.count()); int64_t pos = 0; const int64_t buf_len = mig_param.get_serialize_size(); @@ -567,14 +677,15 @@ TEST_F(TestMigrationSSTableParam, test_migrate_sstable) ASSERT_EQ(OB_SUCCESS, ret); ObSSTableMeta src_meta; - ret = src_meta.init(src_sstable_param, &allocator); + ret = src_meta.init(src_sstable_param, allocator); ASSERT_EQ(OB_SUCCESS, ret); ObMigrationSSTableParam mig_param; mig_param.basic_meta_ = src_meta.get_basic_meta(); mig_param.table_key_ = src_sstable_param.table_key_; - ret = mig_param.column_checksums_.assign(src_meta.get_col_checksum()); - ASSERT_EQ(OB_SUCCESS, ret); + for (int64_t i = 0; i < sstable_meta_.get_col_checksum_cnt(); ++i) { + ASSERT_EQ(OB_SUCCESS, mig_param.column_checksums_.push_back(src_meta.get_col_checksum()[i])); + } ObTabletCreateSSTableParam dest_sstable_param; ret = ObLSTabletService::build_create_sstable_param_for_migration(mig_param, dest_sstable_param); @@ -582,6 +693,7 @@ TEST_F(TestMigrationSSTableParam, test_migrate_sstable) ASSERT_TRUE(dest_sstable_param.encrypt_id_ == src_sstable_param.encrypt_id_); } + } // end namespace unittest } // end namespace oceanbase diff --git a/unittest/storage/blocksstable/test_storage_cache_suite.cpp b/unittest/storage/blocksstable/test_storage_cache_suite.cpp index 829a6e07d..efc0e0958 100644 --- a/unittest/storage/blocksstable/test_storage_cache_suite.cpp +++ b/unittest/storage/blocksstable/test_storage_cache_suite.cpp @@ -37,33 +37,33 @@ TEST_F(TestStorageCacheSuite, test_cache_suite) const int64_t max_cache_size = 1024 * 1024 * 512; const int64_t block_size = common::OB_MALLOC_BIG_BLOCK_SIZE; ObKVGlobalCache::get_instance().init(&getter, bucket_num, max_cache_size, block_size); - ASSERT_EQ(OB_SUCCESS, OB_STORE_CACHE.init(1,2,3,4,5, 10)); + ASSERT_EQ(OB_SUCCESS, OB_STORE_CACHE.init(1,2,3,4,5, 10, 10)); ASSERT_EQ(OB_SUCCESS, OB_STORE_CACHE.reset_priority(6,5,4,3,2)); - ASSERT_EQ(OB_INIT_TWICE, OB_STORE_CACHE.init(1,2,3,4,5, 10)); + ASSERT_EQ(OB_INIT_TWICE, OB_STORE_CACHE.init(1,2,3,4,5, 10, 10)); OB_STORE_CACHE.destroy(); ObKVGlobalCache::get_instance().destroy(); ASSERT_EQ(OB_SUCCESS, ObKVGlobalCache::get_instance().init(&getter, bucket_num, max_cache_size, block_size)); - ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.init(-1,2,3,4,1, 10)); + ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.init(-1,2,3,4,1, 10, 10)); OB_STORE_CACHE.destroy(); ObKVGlobalCache::get_instance().destroy(); ASSERT_EQ(OB_SUCCESS, ObKVGlobalCache::get_instance().init(&getter, bucket_num, max_cache_size, block_size)); - ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.init(-1,2,3,4,1, 10)); + ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.init(-1,2,3,4,1, 10, 10)); OB_STORE_CACHE.destroy(); ObKVGlobalCache::get_instance().destroy(); ASSERT_EQ(OB_SUCCESS, ObKVGlobalCache::get_instance().init(&getter, bucket_num, max_cache_size, block_size)); - ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.init(1,-2,3,4,1, 10)); + ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.init(1,-2,3,4,1, 10, 10)); OB_STORE_CACHE.destroy(); ObKVGlobalCache::get_instance().destroy(); ASSERT_EQ(OB_SUCCESS, ObKVGlobalCache::get_instance().init(&getter, bucket_num, max_cache_size, block_size)); - ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.init(1,2,-3,4,1, 10)); + ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.init(1,2,-3,4,1, 10, 10)); OB_STORE_CACHE.destroy(); ObKVGlobalCache::get_instance().destroy(); ASSERT_EQ(OB_SUCCESS, ObKVGlobalCache::get_instance().init(&getter, bucket_num, max_cache_size, block_size)); - ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.init(1,2,3,-4,1, 10)); + ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.init(1,2,3,-4,1, 10, 10)); ObKVGlobalCache::get_instance().destroy(); OB_STORE_CACHE.destroy(); ObKVGlobalCache::get_instance().init(&getter, bucket_num, max_cache_size, block_size); - ASSERT_EQ(OB_SUCCESS, OB_STORE_CACHE.init(1,2,3,4, 5, 10)); + ASSERT_EQ(OB_SUCCESS, OB_STORE_CACHE.init(1,2,3,4, 5, 10, 10)); ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.reset_priority(-6,6,5,4,3,1)); ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.reset_priority(6,-6,5,4,3,1)); ASSERT_EQ(OB_INVALID_ARGUMENT, OB_STORE_CACHE.reset_priority(6,6,-5,4,3,1)); diff --git a/unittest/storage/ddl/CMakeLists.txt b/unittest/storage/ddl/CMakeLists.txt index 70d6a2aec..63fd732ac 100644 --- a/unittest/storage/ddl/CMakeLists.txt +++ b/unittest/storage/ddl/CMakeLists.txt @@ -1 +1 @@ -storage_unittest(test_ddl_kv) +#storage_unittest(test_ddl_kv) diff --git a/unittest/storage/direct_load/test_direct_load_data_block_writer.cpp b/unittest/storage/direct_load/test_direct_load_data_block_writer.cpp index d387becdb..2c1bd4645 100644 --- a/unittest/storage/direct_load/test_direct_load_data_block_writer.cpp +++ b/unittest/storage/direct_load/test_direct_load_data_block_writer.cpp @@ -44,9 +44,6 @@ public: TestDataBlockWriter() : TestDataFilePrepare(&getter, "TestDataBlockWriter", 8 * 1024 * 1024, 2048){}; virtual void SetUp(); virtual void TearDown(); - static void SetUpTestCase() {} - static void TearDownTestCase() {} - void check_row(const ObDatumRow *next_row, const ObDatumRow *curr_row); void test_alloc(char *&ptr, const int64_t size); @@ -124,6 +121,7 @@ void TestDataBlockWriter::prepare_schema() void TestDataBlockWriter::SetUp() { int ret = OB_SUCCESS; + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); // init file const int64_t bucket_num = 1024; const int64_t max_cache_size = 1024 * 1024 * 1024; @@ -217,7 +215,7 @@ TEST_F(TestDataBlockWriter, test_empty_write_and_scan) ObTableReadInfo read_info; // init access_param ret = read_info.init(allocator_, table_schema_.get_column_count(), - table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs); + table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs, nullptr/*storage_cols_index*/); ASSERT_EQ(OB_SUCCESS, ret); ret = access_param.init_merge_param(table_schema_.get_table_id(), param.tablet_id_, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -312,7 +310,7 @@ TEST_F(TestDataBlockWriter, test_write_and_scan) ObTableReadInfo read_info; // init access_param ret = read_info.init(allocator_, table_schema_.get_column_count(), - table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs); + table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs, nullptr/*storage_cols_index*/); ASSERT_EQ(OB_SUCCESS, ret); ret = access_param.init_merge_param(table_schema_.get_table_id(), param.tablet_id_, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -456,7 +454,7 @@ TEST_F(TestDataBlockWriter, test_write_and_scan_range) ObTableReadInfo read_info; // init access_param ret = read_info.init(allocator_, table_schema_.get_column_count(), - table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs); + table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs, nullptr/*storage_cols_index*/); ASSERT_EQ(OB_SUCCESS, ret); ret = access_param.init_merge_param(table_schema_.get_table_id(), param.tablet_id_, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -568,7 +566,7 @@ TEST_F(TestDataBlockWriter, test_scan_less_range) ObTableReadInfo read_info; // init access_param ret = read_info.init(allocator_, table_schema_.get_column_count(), - table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs); + table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs, nullptr/*storage_cols_index*/); ASSERT_EQ(OB_SUCCESS, ret); ret = access_param.init_merge_param(table_schema_.get_table_id(), param.tablet_id_, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -685,7 +683,7 @@ TEST_F(TestDataBlockWriter, test_scan_range) // init access_param ret = read_info.init(allocator_, table_schema_.get_column_count(), - table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs); + table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs, nullptr/*storage_cols_index*/); ASSERT_EQ(OB_SUCCESS, ret); ret = access_param.init_merge_param(table_schema_.get_table_id(), param.tablet_id_, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -825,7 +823,7 @@ TEST_F(TestDataBlockWriter, test_write_and_scan_large_low) ObTableReadInfo read_info; // init access_param ret = read_info.init(allocator_, table_schema_.get_column_count(), - table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs); + table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs, nullptr/*storage_cols_index*/); ASSERT_EQ(OB_SUCCESS, ret); ret = access_param.init_merge_param(table_schema_.get_table_id(), param.tablet_id_, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -971,7 +969,7 @@ TEST_F(TestDataBlockWriter, test_write_and_scan_range_large_low) ObTableReadInfo read_info; // init access_param ret = read_info.init(allocator_, table_schema_.get_column_count(), - table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs); + table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs, nullptr/*storage_cols_index*/); ASSERT_EQ(OB_SUCCESS, ret); ret = access_param.init_merge_param(table_schema_.get_table_id(), param.tablet_id_, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -1069,7 +1067,7 @@ TEST_F(TestDataBlockWriter, test_scan_range_large_low) ObTableReadInfo read_info; // init access_param ret = read_info.init(allocator_, table_schema_.get_column_count(), - table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs); + table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs, nullptr/*storage_cols_index*/); ASSERT_EQ(OB_SUCCESS, ret); ret = access_param.init_merge_param(table_schema_.get_table_id(), param.tablet_id_, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -1174,7 +1172,7 @@ TEST_F(TestDataBlockWriter, test_write_and_compact) // init access_param ret = read_info.init(allocator_, table_schema_.get_column_count(), - table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs); + table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs, nullptr/*storage_cols_index*/); ASSERT_EQ(OB_SUCCESS, ret); ret = access_param.init_merge_param(table_schema_.get_table_id(), param.tablet_id_, read_info); ASSERT_EQ(OB_SUCCESS, ret); @@ -1386,7 +1384,7 @@ TEST_F(TestDataBlockWriter, test_write_and_compact_large_row) // init access_param ret = read_info.init(allocator_, table_schema_.get_column_count(), - table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs); + table_schema_.get_rowkey_column_num(), lib::is_oracle_mode(), col_descs, nullptr/*storage_cols_index*/); ASSERT_EQ(OB_SUCCESS, ret); ret = access_param.init_merge_param(table_schema_.get_table_id(), param.tablet_id_, read_info); ASSERT_EQ(OB_SUCCESS, ret); diff --git a/unittest/storage/memtable/test_memtable_basic.cpp b/unittest/storage/memtable/test_memtable_basic.cpp index a284b64b3..2d87429e3 100644 --- a/unittest/storage/memtable/test_memtable_basic.cpp +++ b/unittest/storage/memtable/test_memtable_basic.cpp @@ -188,7 +188,7 @@ public: // iter_param_.rowkey_cnt_ = rowkey_cnt_; iter_param_.tablet_id_ = tablet_id_; iter_param_.table_id_ = tablet_id_.id(); - read_info_.init(allocator_, 16000, rowkey_cnt_, false, columns_); + read_info_.init(allocator_, 16000, rowkey_cnt_, false, columns_, nullptr/*storage_cols_index*/); iter_param_.read_info_ = &read_info_; return OB_SUCCESS; @@ -297,7 +297,22 @@ public: store_ctx.table_iter_ = &table_iter; ObStoreRow write_row; tm_->mock_row(key, val, row_key, write_row); - return mt.set_(store_ctx, tm_->tablet_id_.id(), tm_->read_info_, tm_->columns_, write_row, NULL, NULL); + + ObArenaAllocator allocator; + ObTableAccessContext context; + ObVersionRange trans_version_range; + const bool read_latest = true; + ObQueryFlag query_flag; + + trans_version_range.base_version_ = 0; + trans_version_range.multi_version_start_ = 0; + trans_version_range.snapshot_version_ = EXIST_READ_SNAPSHOT_VERSION; + query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; + query_flag.read_latest_ = read_latest & ObQueryFlag::OBSF_MASK_READ_LATEST; + + context.init(query_flag, store_ctx, allocator, trans_version_range); + + return mt.set_(tm_->iter_param_, context, tm_->columns_, write_row, NULL, NULL); } int write(int64_t key, int64_t val, ObMemtable &mt, int64_t snapshot_version = 1000) { ObDatumRowkey row_key; diff --git a/unittest/storage/mock_access_service.cpp b/unittest/storage/mock_access_service.cpp index 27605dcbc..49d7224ac 100644 --- a/unittest/storage/mock_access_service.cpp +++ b/unittest/storage/mock_access_service.cpp @@ -59,7 +59,8 @@ int MockObAccessService::insert_rows( ctx_guard))) { LOG_WARN("fail to check query allowed", K(ret), K(ls_id), K(tablet_id)); } else { - ret = tablet_service_->insert_rows(ctx_guard.get_store_ctx(), + ret = tablet_service_->insert_rows(ctx_guard.get_tablet_handle(), + ctx_guard.get_store_ctx(), dml_param, column_ids, row_iter, diff --git a/unittest/storage/mock_ob_log_handler.h b/unittest/storage/mock_ob_log_handler.h index 4b24ed33c..1962e070e 100644 --- a/unittest/storage/mock_ob_log_handler.h +++ b/unittest/storage/mock_ob_log_handler.h @@ -270,6 +270,11 @@ public: { return OB_SUCCESS; } + int get_leader_config_version(palf::LogConfigVersion &config_version) const + { + UNUSED(config_version); + return OB_SUCCESS; + } int change_replica_num(const common::ObMemberList &member_list, const int64_t curr_replica_num, const int64_t new_replica_num, @@ -284,11 +289,10 @@ public: } int add_member(const common::ObMember &member, const int64_t paxos_replica_num, + const palf::LogConfigVersion &config_version, const int64_t timeout_ns) { - UNUSED(member); - UNUSED(paxos_replica_num); - UNUSED(timeout_ns); + UNUSEDx(member, paxos_replica_num, config_version, timeout_ns); return OB_SUCCESS; } int remove_member(const common::ObMember &member, @@ -302,10 +306,12 @@ public: } int replace_member(const common::ObMember &added_member, const common::ObMember &removed_member, + const palf::LogConfigVersion &config_version, const int64_t timeout_ns) { UNUSED(added_member); UNUSED(removed_member); + UNUSED(config_version); UNUSED(timeout_ns); return OB_SUCCESS; } @@ -338,9 +344,11 @@ public: int switch_learner_to_acceptor(const common::ObMember &learner, const int64_t new_replica_num, + const palf::LogConfigVersion &config_version, const int64_t timeout_us) { int ret = OB_SUCCESS; + UNUSED(config_version); UNUSEDx(learner, new_replica_num, timeout_us); return ret; } @@ -400,6 +408,25 @@ public: return OB_SUCCESS; } + int try_lock_config_change(const int64_t lock_owner, const int64_t timeout_us) + { + UNUSED(lock_owner); + UNUSED(timeout_us); + return OB_SUCCESS; + } + int unlock_config_change(const int64_t lock_owner, const int64_t timeout_us) + { + UNUSED(lock_owner); + UNUSED(timeout_us); + return OB_SUCCESS; + } + int get_config_change_lock_stat(int64_t &lock_owner, bool &is_locked) + { + lock_owner = palf::OB_INVALID_CONFIG_CHANGE_LOCK_OWNER; + is_locked = false; + return OB_SUCCESS; + } + LSN base_lsn_; int64_t result_ts_ns_; share::SCN result_scn_; diff --git a/unittest/storage/mock_ob_table_read_info.h b/unittest/storage/mock_ob_table_read_info.h new file mode 100644 index 000000000..a57499147 --- /dev/null +++ b/unittest/storage/mock_ob_table_read_info.h @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2021 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 +#include +#include +#include +#include "src/storage/access/ob_table_read_info.h" +#include "src/storage/ob_i_store.h" + +namespace oceanbase +{ +using namespace common; +namespace storage +{ + +// only for unittest +class MockObTableReadInfo final : public ObTableReadInfo +{ +public: + MockObTableReadInfo() = default; + ~MockObTableReadInfo() = default; + int init( + common::ObIAllocator &allocator, + const int64_t schema_column_count, + const int64_t schema_rowkey_cnt, + const bool is_oracle_mode, + const common::ObIArray &cols_desc, + const common::ObIArray *storage_cols_index = nullptr, + const common::ObIArray *cols_param = nullptr); +}; + +int MockObTableReadInfo::init(common::ObIAllocator &allocator, + const int64_t schema_column_count, + const int64_t schema_rowkey_cnt, + const bool is_oracle_mode, + const common::ObIArray &cols_desc, + const common::ObIArray *storage_cols_index, + const common::ObIArray *cols_param) +{ + int ret = OB_SUCCESS; + const int64_t out_cols_cnt = cols_desc.count(); + + const int64_t extra_rowkey_col_cnt = storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + init_basic_info(schema_column_count, schema_rowkey_cnt, is_oracle_mode); // init basic info + if (OB_FAIL(prepare_arrays(allocator, cols_desc, out_cols_cnt))) { + } else if (nullptr != cols_param && OB_FAIL(cols_param_.init_and_assign(*cols_param, allocator))) { + STORAGE_LOG(WARN, "Fail to assign cols_param", K(ret)); + } else if (OB_UNLIKELY(cols_index_.rowkey_mode_ || memtable_cols_index_.rowkey_mode_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "cols index is unexpected rowkey_mode", K(ret), K(cols_index_), K(memtable_cols_index_)); + } else { + int32_t col_index = OB_INVALID_INDEX; + for (int64_t i = 0; i < out_cols_cnt; i++) { + col_index = (nullptr == storage_cols_index) ? i : storage_cols_index->at(i); + cols_index_.array_[i] = col_index; + memtable_cols_index_.array_[i] = col_index; + } + if (FAILEDx(init_datum_utils(allocator))) { + STORAGE_LOG(WARN, "failed to init sequence read info & datum utils", K(ret)); + } else { + is_inited_ = true; + } + } + return ret; +} + +} +} \ No newline at end of file diff --git a/unittest/storage/mockcontainer/mock_ob_iterator.cpp b/unittest/storage/mockcontainer/mock_ob_iterator.cpp index b1b181bc2..97c0e542b 100644 --- a/unittest/storage/mockcontainer/mock_ob_iterator.cpp +++ b/unittest/storage/mockcontainer/mock_ob_iterator.cpp @@ -1592,7 +1592,7 @@ OB_DEF_SERIALIZE_SIZE(MockObNewRowIterator) int ObMockDirectReadIterator::init(ObStoreRowIterator *iter, common::ObIAllocator &alloc, - ObTableReadInfo &read_info) + const ObITableReadInfo &read_info) { int ret = OB_SUCCESS; const blocksstable::ObDatumRow *row = nullptr; diff --git a/unittest/storage/mockcontainer/mock_ob_iterator.h b/unittest/storage/mockcontainer/mock_ob_iterator.h index 5081b7f19..00dd49a8a 100644 --- a/unittest/storage/mockcontainer/mock_ob_iterator.h +++ b/unittest/storage/mockcontainer/mock_ob_iterator.h @@ -436,7 +436,7 @@ public: int get_next_row(const storage::ObStoreRow *&row); int init(ObStoreRowIterator *iter, common::ObIAllocator &alloc, - ObTableReadInfo &read_info); + const ObITableReadInfo &read_info); int reset_scanner(); bool end_of_block() { return current_ == -1 || @@ -450,7 +450,7 @@ public: ObIMicroBlockRowScanner *scanner_; ObIMicroBlockReader *reader_; ObDatumRow row_; - const ObTableReadInfo *read_info_; + const ObITableReadInfo *read_info_; ObStoreRow sstable_row_; }; diff --git a/unittest/storage/multi_data_source/common_define.h b/unittest/storage/multi_data_source/common_define.h new file mode 100644 index 000000000..93f026b5d --- /dev/null +++ b/unittest/storage/multi_data_source/common_define.h @@ -0,0 +1,13 @@ +#ifndef UNITTEST_STORAGE_MULTI_DATA_SOURCE_COMMON_DEFINE_H +#define UNITTEST_STORAGE_MULTI_DATA_SOURCE_COMMON_DEFINE_H +#include "src/share/scn.h" +#include "example_user_data_define.h" + +namespace oceanbase { +namespace unittest { + +inline share::SCN mock_scn(int64_t val) { share::SCN scn; scn.convert_for_gts(val); return scn; } + +} +} +#endif \ No newline at end of file diff --git a/unittest/storage/multi_data_source/example_user_data_define.h b/unittest/storage/multi_data_source/example_user_data_define.h new file mode 100644 index 000000000..f2455f30b --- /dev/null +++ b/unittest/storage/multi_data_source/example_user_data_define.h @@ -0,0 +1,129 @@ +#ifndef UNITTEST_SHARE_MULTI_DATA_SOURCE_EXAMPLE_USER_DATA_DEFINE_H +#define UNITTEST_SHARE_MULTI_DATA_SOURCE_EXAMPLE_USER_DATA_DEFINE_H +#include "lib/ob_errno.h" +#include "lib/utility/ob_print_utils.h" +#include "lib/utility/ob_unify_serialize.h" +#include "lib/utility/serialization.h" +#include "meta_programming/ob_meta_serialization.h" +#include "common_define.h" +namespace oceanbase { +namespace unittest { +struct ExampleUserKey { + OB_UNIS_VERSION(1); +public: + ExampleUserKey() : value_(0) {} + ExampleUserKey(const int val) : value_(val) {} + TO_STRING_KV(K_(value)); + bool operator<(const ExampleUserKey &rhs) const { return value_ < rhs.value_; } + bool operator==(const ExampleUserKey &rhs) const { return value_ == rhs.value_; } + int64_t value_; +}; + +OB_SERIALIZE_MEMBER_TEMP(inline, ExampleUserKey, value_); +struct ExampleUserData1 {// simple data structure + OB_UNIS_VERSION(1); +public: + bool operator==(const ExampleUserData1 &rhs) const { return value_ == rhs.value_; } + ExampleUserData1() : value_(0) {} + ExampleUserData1(const int val) : value_(val) {} + TO_STRING_KV(K_(value)); + int value_; +}; + +OB_SERIALIZE_MEMBER_TEMP(inline, ExampleUserData1, value_); + +struct ExampleUserData2 {// complicated data structure +public: + ExampleUserData2() : alloc_(nullptr) {} + ~ExampleUserData2() { + if (OB_NOT_NULL(alloc_)) { + if (!data_.empty()) { + alloc_->free(data_.ptr()); + } + } + } + int serialize(char *buf, const int64_t buf_len, int64_t &pos) const { + int ret = OB_SUCCESS; + if (OB_ISNULL(alloc_)) { + } else if (OB_FAIL(serialization::encode(buf, buf_len, pos, (int64_t)data_.length()))) { + } else { + for (int64_t idx = 0; idx < data_.length() && OB_SUCC(ret); ++idx) { + ret = serialization::encode(buf, buf_len, pos, data_.ptr()[idx]); + } + } + return ret; + } + int deserialize(ObIAllocator &alloc, const char *buf, const int64_t buf_len, int64_t &pos) { + int ret = OB_SUCCESS; + int64_t length = 0; + char *buffer = nullptr; + if (OB_FAIL(serialization::decode(buf, buf_len, pos, length))) { + } else if (OB_ISNULL(buffer = (char *)alloc.alloc(length))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + } else { + for (int64_t idx = 0; idx < length && OB_SUCC(ret); ++idx) { + ret = serialization::decode(buf, buf_len, pos, buffer[idx]); + } + if (OB_SUCC(ret)) { + data_.assign(buffer, length); + alloc_ = &alloc; + } + } + return ret; + } + int64_t get_serialize_size() const { + int64_t total_size = 0; + total_size += serialization::encoded_length((int64_t)data_.length()); + for (int64_t idx = 0; idx < data_.length(); ++idx) { + total_size += serialization::encoded_length(data_.ptr()[idx]); + } + return total_size; + } + int assign(ObIAllocator &alloc, const char *str) { + int ret = OB_SUCCESS; + OB_ASSERT(OB_ISNULL(alloc_) && data_.empty()); + int64_t len = strlen(str); + char *buffer = nullptr; + if (OB_ISNULL(buffer = (char *)alloc.alloc(len))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + } else { + memcpy(buffer, str, len); + alloc_ = &alloc; + data_.assign(buffer, len); + } + return ret; + } + int assign(ObIAllocator &alloc, const ExampleUserData2 &rhs) { + int ret = OB_SUCCESS; + if (OB_NOT_NULL(rhs.alloc_)) { + OB_ASSERT(OB_ISNULL(alloc_) && data_.empty()); + int64_t len = rhs.data_.length(); + char *buffer = nullptr; + if (OB_ISNULL(buffer = (char *)alloc.alloc(len))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + } else { + memcpy(buffer, rhs.data_.ptr(), len); + alloc_ = &alloc; + data_.assign(buffer, len); + } + } + return ret; + } + // support move semantic + ExampleUserData2(ExampleUserData2 &&rhs) { + if (OB_NOT_NULL(rhs.alloc_)) { + data_ = rhs.data_; + alloc_ = rhs.alloc_; + rhs.alloc_ = nullptr; + rhs.data_.reset(); + MDS_LOG(INFO, "call move construction", K(*this)); + } + } + TO_STRING_KV(KP(data_.ptr()), K(data_.length())); + ObIAllocator *alloc_; + ObString data_; +}; + +} +} +#endif \ No newline at end of file diff --git a/unittest/storage/multi_data_source/example_user_helper_define.cpp b/unittest/storage/multi_data_source/example_user_helper_define.cpp new file mode 100644 index 000000000..e9c33b0ce --- /dev/null +++ b/unittest/storage/multi_data_source/example_user_helper_define.cpp @@ -0,0 +1,123 @@ +#ifdef TEST_MDS_TRANSACTION +#include "example_user_helper_define.h" +#include "storage/multi_data_source/mds_table_handle.h" +namespace oceanbase { +namespace unittest { + +using namespace storage; +using namespace mds; + +MdsTableHandle TestMdsTable; + +const storage::mds::MdsWriter ExampleUserHelperCtx::get_writer() const +{ + return storage::mds::MdsWriter(transaction::ObTransID(0)); +} + +int ExampleUserHelperFunction1::on_register(const char* buf, + const int64_t len, + storage::mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + int64_t test_value; + int64_t pos = 0; + if (OB_FAIL(serialization::decode(buf, len, pos, test_value))) { + MDS_LOG(ERROR, "[UNITTEST] ExampleUserHelperFunction1 fail to deserialize", KR(ret)); + } else { + MDS_LOG(INFO, "[UNITTEST] ExampleUserHelperFunction1 call on_register with helper", K(test_value)); + } + return ret; +} + +int ExampleUserHelperFunction1::on_replay(const char* buf, + const int64_t len, + const share::SCN &scn, // 日志scn + storage::mds::BufferCtx &ctx) +{ + UNUSED(scn); + return on_register(buf, len, ctx); +} + +int ExampleUserHelperFunction2::on_register(const char* buf, + const int64_t len, + storage::mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + int64_t test_value; + int64_t pos = 0; + if (OB_FAIL(serialization::decode(buf, len, pos, test_value))) { + MDS_LOG(ERROR, "[UNITTEST] ExampleUserHelperFunction2 fail to deserialize", KR(ret)); + } else { + ExampleUserData1 data(test_value); + MdsCtx &mds_ctx = dynamic_cast(ctx); + if (OB_FAIL(TestMdsTable.set(data, mds_ctx))) { + MDS_LOG(ERROR, "[UNITTEST] ExampleUserHelperFunction2 fail to set mdstable", KR(ret)); + } else { + MDS_LOG(INFO, "[UNITTEST] ExampleUserHelperFunction2 call on_register with helper", K(test_value)); + } + } + return ret; +} + +int ExampleUserHelperFunction2::on_replay(const char* buf, + const int64_t len, + const share::SCN &scn, // 日志scn + storage::mds::BufferCtx &ctx) +{ + UNUSED(scn); + return on_register(buf, len, ctx); +} + +int ExampleUserHelperFunction3::on_register(const char* buf, + const int64_t len, + storage::mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + int64_t test_value; + int64_t pos = 0; + if (OB_FAIL(serialization::decode(buf, len, pos, test_value))) { + MDS_LOG(ERROR, "[UNITTEST] ExampleUserHelperFunction3 fail to deserialize", KR(ret)); + } else { + MDS_LOG(INFO, "[UNITTEST] ExampleUserHelperFunction3 call on_register with helper", K(test_value)); + } + return ret; +} + +int ExampleUserHelperFunction3::on_replay(const char* buf, + const int64_t len, + const share::SCN &scn, // 日志scn + storage::mds::BufferCtx &ctx) +{ + UNUSED(scn); + return on_register(buf, len, ctx); +} + +void ExampleUserHelperCtx::on_redo(const share::SCN &) +{ + MDS_LOG(INFO, "[UNITTEST] call on_redo with ctx", K(++call_times_)); +} + +void ExampleUserHelperCtx::before_prepare() +{ + MDS_LOG(INFO, "[UNITTEST] call before_prepare with ctx", K(++call_times_)); +} + +void ExampleUserHelperCtx::on_prepare(const share::SCN &prepare_version) +{ + MDS_LOG(INFO, "[UNITTEST] call on_prepare with ctx", K(++call_times_)); +} + +void ExampleUserHelperCtx::on_commit(const share::SCN &commit_version, const share::SCN &) +{ + MDS_LOG(INFO, "[UNITTEST] call on_commit with ctx", K(++call_times_)); +} + +void ExampleUserHelperCtx::on_abort(const share::SCN &end_scn) +{ + MDS_LOG(INFO, "[UNITTEST] call on_abort with ctx", K(++call_times_), K(end_scn)); +} + + +} +} +#endif \ No newline at end of file diff --git a/unittest/storage/multi_data_source/example_user_helper_define.h b/unittest/storage/multi_data_source/example_user_helper_define.h new file mode 100644 index 000000000..96ed9f213 --- /dev/null +++ b/unittest/storage/multi_data_source/example_user_helper_define.h @@ -0,0 +1,151 @@ +#ifndef UNITTEST_SHARE_MULTI_DATA_SOURCE_EXAMPLE_USER_HELPER_DEFINE_H +#define UNITTEST_SHARE_MULTI_DATA_SOURCE_EXAMPLE_USER_HELPER_DEFINE_H +#include "storage/multi_data_source/buffer_ctx.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/utility/serialization.h" +#include "share/scn.h" +#include "storage/multi_data_source/runtime_utility/common_define.h" + +namespace oceanbase { +namespace unittest { + +struct ExampleUserHelperFunction1 { + static int on_register(const char* buf, + const int64_t len, + storage::mds::BufferCtx &ctx); // 出参,将对应修改记录在Ctx中 + + static int on_replay(const char* buf, + const int64_t len, + const share::SCN &scn, // 日志scn + storage::mds::BufferCtx &ctx); // 备机回放 +}; + +struct ExampleUserHelperFunction2 { + static int on_register(const char* buf, + const int64_t len, + storage::mds::BufferCtx &ctx); // 出参,将对应修改记录在Ctx中 + + static int on_replay(const char* buf, + const int64_t len, + const share::SCN &scn, // 日志scn + storage::mds::BufferCtx &ctx); // 备机回放 +}; + +struct ExampleUserHelperFunction3 { + static int on_register(const char* buf, + const int64_t len, + storage::mds::BufferCtx &ctx); // 出参,将对应修改记录在Ctx中 + + static int on_replay(const char* buf, + const int64_t len, + const share::SCN &scn, // 日志scn + storage::mds::BufferCtx &ctx); // 备机回放 +}; + +struct ExampleUserHelperCtx : public storage::mds::BufferCtx { + ExampleUserHelperCtx() : call_times_(0) {} + virtual const storage::mds::MdsWriter get_writer() const override; + virtual void on_redo(const share::SCN &redo_scn) override; + virtual void before_prepare() override; + virtual void on_prepare(const share::SCN &prepare_version) override; + virtual void on_commit(const share::SCN &commit_version, const share::SCN &scn) override; + virtual void on_abort(const share::SCN &scn) override; + int assign(const ExampleUserHelperCtx &rhs) { + call_times_ = rhs.call_times_; + return OB_SUCCESS; + } + int call_times_;// 这个类可以有自己的内部状态 + virtual int64_t to_string(char*, const int64_t buf_len) const { return 0; } + // 同事务状态一起持久化以及恢复 + virtual int serialize(char*, const int64_t, int64_t&) const { return OB_SUCCESS; } + virtual int deserialize(const char*, const int64_t, int64_t&) { return OB_SUCCESS; } + virtual int64_t get_serialize_size(void) const { return 0; } +}; + +#ifndef TEST_MDS_TRANSACTION + +inline int ExampleUserHelperFunction1::on_register(const char* buf, + const int64_t len, + storage::mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + return ret; +} + +inline int ExampleUserHelperFunction1::on_replay(const char* buf, + const int64_t len, + const share::SCN &scn, // 日志scn + storage::mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + return ret; +} + +inline int ExampleUserHelperFunction2::on_register(const char*, + const int64_t, + storage::mds::BufferCtx &) +{ + int ret = OB_SUCCESS; + return ret; +} + +inline int ExampleUserHelperFunction2::on_replay(const char*, + const int64_t, + const share::SCN &, // 日志scn + storage::mds::BufferCtx &) +{ + int ret = OB_SUCCESS; + return ret; +} + +inline int ExampleUserHelperFunction3::on_register(const char*, + const int64_t, + storage::mds::BufferCtx &) +{ + int ret = OB_SUCCESS; + return ret; +} + +inline int ExampleUserHelperFunction3::on_replay(const char* buf, + const int64_t len, + const share::SCN &scn, // 日志scn + storage::mds::BufferCtx &ctx) +{ + UNUSED(scn); + return on_register(buf, len, ctx); +} + +inline const storage::mds::MdsWriter ExampleUserHelperCtx::get_writer() const +{ + return storage::mds::MdsWriter(storage::mds::WriterType::TRANSACTION, 1); +} + +inline void ExampleUserHelperCtx::on_redo(const share::SCN &redo_scn) +{ + MDS_LOG(INFO, "[UNITTEST] call on_redo with ctx", K(++call_times_)); +} + +inline void ExampleUserHelperCtx::before_prepare() +{ + MDS_LOG(INFO, "[UNITTEST] call before_prepare with ctx", K(++call_times_)); +} + +inline void ExampleUserHelperCtx::on_prepare(const share::SCN &prepare_version) +{ + MDS_LOG(INFO, "[UNITTEST] call on_prepare with ctx", K(++call_times_)); +} + +inline void ExampleUserHelperCtx::on_commit(const share::SCN &commit_version, const share::SCN &scn) +{ + MDS_LOG(INFO, "[UNITTEST] call on_commit with ctx", K(++call_times_)); +} + +inline void ExampleUserHelperCtx::on_abort(const share::SCN &scn) +{ + MDS_LOG(INFO, "[UNITTEST] call on_abort with ctx", K(++call_times_)); +} +#endif + +} +} +#endif \ No newline at end of file diff --git a/unittest/storage/multi_data_source/test_mds_compile.cpp b/unittest/storage/multi_data_source/test_mds_compile.cpp new file mode 100644 index 000000000..2de70cdf7 --- /dev/null +++ b/unittest/storage/multi_data_source/test_mds_compile.cpp @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2021 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. + */ + +#define UNITTEST_DEBUG +#include +#include +#include +#include +#include +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/multi_data_source/compile_utility/compile_mapper.h" +namespace oceanbase { +namespace unittest { + +using namespace common; +using namespace std; + +class TestMdsCompile: public ::testing::Test +{ +public: + TestMdsCompile() {}; + virtual ~TestMdsCompile() {}; + virtual void SetUp() { + }; + virtual void TearDown() { + }; +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestMdsCompile); +}; + +TEST_F(TestMdsCompile, basic) { + ObTuple tuple_; + tuple_.element() = 1; +} + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_ob_occam_timer.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_ob_occam_timer.log", false); + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/unittest/storage/multi_data_source/test_mds_dump_kv.cpp b/unittest/storage/multi_data_source/test_mds_dump_kv.cpp new file mode 100644 index 000000000..45239c596 --- /dev/null +++ b/unittest/storage/multi_data_source/test_mds_dump_kv.cpp @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2021 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 "share/ob_ls_id.h" +#define UNITTEST_DEBUG +#include +#define private public +#define protected public +#include "storage/multi_data_source/compile_utility/mds_dummy_key.h" +#include "storage/multi_data_source/compile_utility/map_type_index_in_tuple.h" +#include "common_define.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include +#include +#include +#include +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_node.h" +#include "example_user_helper_define.cpp" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/tablet/ob_tablet_meta.h" +namespace oceanbase { +namespace storage +{ +namespace mds +{ +void *MdsAllocator::alloc(const int64_t size) +{ + void *ptr = ob_malloc(size, "MDS"); + ATOMIC_INC(&alloc_times_); + MDS_LOG(DEBUG, "alloc obj", KP(ptr), K(size), K(lbt())); + return ptr; +} +void MdsAllocator::free(void *ptr) { + ATOMIC_INC(&free_times_); + MDS_LOG(DEBUG, "free obj", KP(ptr), K(lbt())); + ob_free(ptr); +} +} +} +namespace unittest { + +using namespace common; +using namespace std; +using namespace storage; +using namespace mds; + +class TestMdsDumpKV: public ::testing::Test +{ +public: + TestMdsDumpKV() {}; + virtual ~TestMdsDumpKV() {}; + virtual void SetUp() { + }; + virtual void TearDown() { + }; + static void test_dump_node_convert_and_serialize_and_compare(); + static void test_dump_dummy_key(); +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestMdsDumpKV); +}; + +void TestMdsDumpKV::test_dump_node_convert_and_serialize_and_compare() +{ + ExampleUserData2 first_data; + ASSERT_EQ(OB_SUCCESS, first_data.assign(MdsAllocator::get_instance(), "123")); + UserMdsNode user_mds_node(nullptr, MdsNodeType::SET, WriterType::TRANSACTION, 1); + ASSERT_EQ(OB_SUCCESS, meta::move_or_copy_or_assign(first_data, user_mds_node.user_data_, MdsAllocator::get_instance())); + ASSERT_EQ(true, first_data.data_.ptr() != user_mds_node.user_data_.data_.ptr()); + ASSERT_EQ(0, memcmp(first_data.data_.ptr(), user_mds_node.user_data_.data_.ptr(), first_data.data_.length())); + user_mds_node.try_on_redo(mock_scn(10)); + user_mds_node.try_before_prepare(); + user_mds_node.try_on_prepare(mock_scn(11)); + user_mds_node.try_on_commit(mock_scn(11), mock_scn(11)); + MdsDumpNode dump_node; + ASSERT_EQ(OB_SUCCESS, dump_node.init(GET_MDS_TABLE_ID::value, GET_MDS_UNIT_ID::value, user_mds_node, mds::MdsAllocator::get_instance())); + constexpr int buf_len = 1024; + char buffer[buf_len] = {0}; + int64_t pos = 0; + ASSERT_EQ(OB_SUCCESS, dump_node.serialize(buffer, buf_len, pos)); + MdsDumpNode dump_node2; + pos = 0; + + ObArenaAllocator allocator; + ASSERT_EQ(OB_SUCCESS, dump_node2.deserialize(allocator, buffer, buf_len, pos)); + OB_ASSERT(dump_node2.crc_check_number_ == dump_node2.generate_hash()); + ASSERT_EQ(dump_node2.generate_hash(), dump_node2.crc_check_number_); + ASSERT_EQ(dump_node2.crc_check_number_, dump_node.crc_check_number_); + UserMdsNode user_mds_node2; + ASSERT_EQ(OB_SUCCESS, dump_node2.convert_to_user_mds_node(user_mds_node2, share::ObLSID(1), ObTabletID(1))); + ASSERT_EQ(0, memcmp(user_mds_node.user_data_.data_.ptr(), user_mds_node2.user_data_.data_.ptr(), user_mds_node.user_data_.data_.length())); + ASSERT_EQ(user_mds_node.redo_scn_, user_mds_node2.redo_scn_); + ASSERT_EQ(user_mds_node.end_scn_, user_mds_node2.end_scn_); + ASSERT_EQ(user_mds_node.trans_version_, user_mds_node2.trans_version_); + ASSERT_EQ(user_mds_node.status_.union_.value_, user_mds_node2.status_.union_.value_); + ASSERT_EQ(user_mds_node.seq_no_, user_mds_node2.seq_no_); +} + +void TestMdsDumpKV::test_dump_dummy_key() +{ + DummyKey key; + MdsDumpKey dump_key1, dump_key2; + dump_key1.init(0, 0, key, MdsAllocator::get_instance()); + constexpr int buf_len = 1024; + char buffer[buf_len] = {0}; + int64_t pos = 0; + ASSERT_EQ(OB_SUCCESS, dump_key1.serialize(buffer, buf_len, pos)); + pos = 0; + ASSERT_EQ(OB_SUCCESS, dump_key2.deserialize(buffer, buf_len, pos)); + int compare_result = 0; + ASSERT_EQ(OB_SUCCESS, dump_key1.compare(dump_key2, compare_result)); + ASSERT_EQ(0, compare_result); +} + + +TEST_F(TestMdsDumpKV, test_convert_and_serialize_and_compare) { TestMdsDumpKV::test_dump_node_convert_and_serialize_and_compare(); } +TEST_F(TestMdsDumpKV, test_dump_dummy_key) { TestMdsDumpKV::test_dump_dummy_key(); } + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_mds_dump_kv.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_mds_dump_kv.log", false); + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + testing::InitGoogleTest(&argc, argv); + oceanbase::observer::ObMdsEventBuffer::init(); + int ret = RUN_ALL_TESTS(); + oceanbase::observer::ObMdsEventBuffer::destroy(); + int64_t alloc_times = oceanbase::storage::mds::MdsAllocator::get_alloc_times(); + int64_t free_times = oceanbase::storage::mds::MdsAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + ret = -1; + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} diff --git a/unittest/storage/multi_data_source/test_mds_list.cpp b/unittest/storage/multi_data_source/test_mds_list.cpp new file mode 100644 index 000000000..d2c961b2a --- /dev/null +++ b/unittest/storage/multi_data_source/test_mds_list.cpp @@ -0,0 +1,206 @@ +/** + * Copyright (c) 2021 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. + */ +#define UNITTEST_DEBUG +#include "lib/utility/utility.h" +#include +#include +#include +#define private public +#define protected public +#include "storage/multi_data_source/compile_utility/mds_dummy_key.h" +#include "storage/multi_data_source/runtime_utility/common_define.h" +#include +#include +#include +#include +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_node.h" +#include "example_user_helper_define.cpp" +#include "common/meta_programming/ob_type_traits.h" +#include "storage/multi_data_source/mds_row.h" +namespace oceanbase { +namespace storage +{ +namespace mds +{ +void *MdsAllocator::alloc(const int64_t size) +{ + void *ptr = ob_malloc(size, "MDS"); + ATOMIC_INC(&alloc_times_); + MDS_LOG(DEBUG, "alloc obj", KP(ptr), K(size), K(lbt())); + return ptr; +} +void MdsAllocator::free(void *ptr) { + ATOMIC_INC(&free_times_); + MDS_LOG(DEBUG, "free obj", KP(ptr), K(lbt())); + ob_free(ptr); +} +} +} +namespace unittest { + +using namespace common; +using namespace std; +using namespace storage; +using namespace mds; + +class TestMdsList: public ::testing::Test +{ +public: + TestMdsList() {}; + virtual ~TestMdsList() {}; + virtual void SetUp() { + }; + virtual void TearDown() { + }; +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestMdsList); +}; + +TEST_F(TestMdsList, del_from_tail) { + SortedList, SORT_TYPE::DESC> list; + for (int i = 0; i < 10; ++i) { + ListNode> *new_node = new UserMdsNode(); + list.append(new_node); + } + list.for_each_node_from_tail_to_head_until_true([&list](const UserMdsNode &node) { + list.del((ListNode> *)(&node)); + delete &node; + return false; + }); + ASSERT_EQ(list.empty(), true); +} + +TEST_F(TestMdsList, del_from_head) { + SortedList, SORT_TYPE::DESC> list; + for (int i = 0; i < 10; ++i) { + ListNode> *new_node = new UserMdsNode(); + list.append(new_node); + } + list.for_each_node_from_head_to_tail_until_true([&list](const UserMdsNode &node) { + list.del((ListNode> *)(&node)); + delete &node; + return false; + }); + ASSERT_EQ(list.empty(), true); +} + +TEST_F(TestMdsList, random_del) { + for (int i = 0; i < 100; ++i) { + SortedList, SORT_TYPE::DESC> list; + vector> *> v; + for (int j = 0; j < 10; ++j) { + ListNode> *new_node = new UserMdsNode(); + list.append(new_node); + v.push_back(new_node); + } + int idx = rand() % 10; + for (int k = 0; k < 10; ++k) { + list.del(v[(idx + k) % 10]); + } + ASSERT_EQ(list.empty(), true); + } +} + +TEST_F(TestMdsList, insert_to_tail) { + SortedList, SORT_TYPE::DESC> list; + for (int j = 0; j < 10; ++j) { + UserMdsNode *new_node = new UserMdsNode(); + new_node->redo_scn_ = mock_scn(j); + list.insert(new_node); + } + list.for_each_node_from_head_to_tail_until_true([&list](const UserMdsNode &node) { + list.del((ListNode> *)(&node)); + delete &node; + return false; + }); +} + +TEST_F(TestMdsList, insert_to_head) { + SortedList, SORT_TYPE::DESC> list; + for (int j = 0; j < 10; ++j) { + UserMdsNode *new_node = new UserMdsNode(); + new_node->redo_scn_ = mock_scn(10 - j); + list.insert(new_node); + } + list.for_each_node_from_head_to_tail_until_true([&list](const UserMdsNode &node) { + list.del((ListNode> *)(&node)); + delete &node; + return false; + }); +} + +TEST_F(TestMdsList, random_insert_del) { + for (int i = 0; i < 100; ++i) { + SortedList, SORT_TYPE::DESC> list; + vector> *> v; + for (int j = 0; j < 10; ++j) { + UserMdsNode *new_node = new UserMdsNode(); + new_node->redo_scn_ = mock_scn(rand() % 10); + list.insert(new_node); + v.push_back(new_node); + } + int idx = rand() % 10; + for (int k = 0; k < 10; ++k) { + list.del(v[(idx + k) % 10]); + } + ASSERT_EQ(list.empty(), true); + } +} + +TEST_F(TestMdsList, fetch_and_insert) { + SortedList, SORT_TYPE::DESC> list; + UserMdsNode *new_node = new UserMdsNode(); + UserMdsNode *new_node2 = new UserMdsNode(); + list.insert_into_head(new_node); + ListNode> *node = list.fetch_from_head(); + ASSERT_NE(nullptr, node); + ASSERT_EQ(true, list.empty()); + list.insert_into_head(new_node); + node = list.fetch_from_head(); + ASSERT_NE(nullptr, node); + ASSERT_EQ(true, list.empty()); + list.insert_into_head(new_node); + list.insert_into_head(new_node2); + node = list.fetch_from_head(); + ASSERT_EQ(new_node2, node); + ASSERT_EQ(false, list.empty()); + list.insert_into_head(new_node2); + node = list.fetch_from_head(); + ASSERT_EQ(new_node2, node); + delete new_node; + delete new_node2; +} + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_mds_list.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_mds_list.log", false); + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + int64_t alloc_times = oceanbase::storage::mds::MdsAllocator::get_alloc_times(); + int64_t free_times = oceanbase::storage::mds::MdsAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + ret = -1; + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} \ No newline at end of file diff --git a/unittest/storage/multi_data_source/test_mds_node.cpp b/unittest/storage/multi_data_source/test_mds_node.cpp new file mode 100644 index 000000000..0f5041a09 --- /dev/null +++ b/unittest/storage/multi_data_source/test_mds_node.cpp @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2021 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. + */ +#define UNITTEST_DEBUG +#include "lib/utility/utility.h" +#include +#include +#define private public +#define protected public +#include "storage/multi_data_source/compile_utility/mds_dummy_key.h" +#include "storage/multi_data_source/runtime_utility/common_define.h" + +#include +#include +#include +#include +#include "storage/multi_data_source/runtime_utility/mds_factory.h" +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_node.h" +#include "example_user_helper_define.cpp" +#include "common/meta_programming/ob_type_traits.h" +#include "storage/multi_data_source/mds_row.h" +namespace oceanbase { +namespace storage +{ +namespace mds +{ +void *MdsAllocator::alloc(const int64_t size) +{ + void *ptr = ob_malloc(size, "MDS"); + ATOMIC_INC(&alloc_times_); + MDS_LOG(DEBUG, "alloc obj", KP(ptr), K(size), K(lbt())); + return ptr; +} +void MdsAllocator::free(void *ptr) { + ATOMIC_INC(&free_times_); + MDS_LOG(DEBUG, "free obj", KP(ptr), K(lbt())); + ob_free(ptr); +} +} +} +namespace unittest { + +using namespace common; +using namespace std; +using namespace storage; +using namespace mds; + +class TestMdsNode: public ::testing::Test +{ +public: + TestMdsNode() {}; + virtual ~TestMdsNode() {}; + virtual void SetUp() { + }; + virtual void TearDown() { + }; +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestMdsNode); +}; + +std::atomic_int call_on_set(0); +std::atomic_int call_try_on_redo(0); +std::atomic_int call_try_on_commit(0); +std::atomic_int call_try_on_abort(0); + +struct UserDataWithCallBack +{ + UserDataWithCallBack() : val_(-1) {} + UserDataWithCallBack(int val) : val_(val) {} + void on_set() { + static_assert(OB_TRAIT_HAS_ON_SET(UserDataWithCallBack), "compile check on_set will not be called be MDS"); + call_on_set++; + } + void on_redo(share::SCN redo_scn) { + static_assert(OB_TRAIT_HAS_ON_REDO(UserDataWithCallBack), "compile check try_on_redo will not be called be MDS"); + call_try_on_redo++; + } + void on_commit(share::SCN commit_version, share::SCN commit_scn) { + static_assert(OB_TRAIT_HAS_ON_COMMIT(UserDataWithCallBack), "compile check try_on_commit will not be called be MDS"); + ob_usleep(100_ms); + call_try_on_commit++; + } + void on_abort(share::SCN abort_version) { + static_assert(OB_TRAIT_HAS_ON_ABORT(UserDataWithCallBack), "compile check try_on_abort will not be called be MDS"); + call_try_on_abort++; + } + TO_STRING_KV("test", val_); + int val_; +}; + +TEST_F(TestMdsNode, call_user_method) { + MdsRow row; + MdsCtx ctx(mds::MdsWriter(transaction::ObTransID(100)));// commit finally + ASSERT_EQ(OB_SUCCESS, row.set(UserDataWithCallBack(1), ctx, 0)); + ctx.on_redo(mock_scn(1)); + ctx.before_prepare(); + ctx.on_prepare(mock_scn(2)); + ctx.on_commit(mock_scn(3), mock_scn(3)); + ASSERT_NE(call_on_set, 0); + ASSERT_NE(call_try_on_redo, 0); + ASSERT_NE(call_try_on_commit, 0); + ASSERT_EQ(call_try_on_abort, 0); +} + +TEST_F(TestMdsNode, release_node_while_node_in_ctx) { + MdsRow row; + MdsCtx ctx(mds::MdsWriter(transaction::ObTransID(100)));// commit finally + ASSERT_EQ(OB_SUCCESS, row.set(UserDataWithCallBack(1), ctx, 0)); + ctx.on_redo(mock_scn(1)); + ctx.before_prepare(); + row.~MdsRow(); + ASSERT_EQ(true, ctx.write_list_.empty()); + ctx.on_prepare(mock_scn(2)); + ctx.on_commit(mock_scn(3), mock_scn(3)); +} + +TEST_F(TestMdsNode, release_node_while_node_in_ctx_concurrent) { + call_on_set = 0; + call_try_on_redo = 0; + call_try_on_commit = 0; + call_try_on_abort = 0; + MdsRow row; + MdsCtx ctx(mds::MdsWriter(transaction::ObTransID(100)));// commit finally + // 提交这些node将会耗时50ms + ASSERT_EQ(OB_SUCCESS, row.set(UserDataWithCallBack(1), ctx, 0)); + ASSERT_EQ(OB_SUCCESS, row.set(UserDataWithCallBack(2), ctx, 0)); + ASSERT_EQ(OB_SUCCESS, row.set(UserDataWithCallBack(3), ctx, 0)); + ASSERT_EQ(OB_SUCCESS, row.set(UserDataWithCallBack(4), ctx, 0)); + ASSERT_EQ(OB_SUCCESS, row.set(UserDataWithCallBack(5), ctx, 0)); + + std::thread t1([&ctx]() { + OCCAM_LOG(DEBUG, "t1 start"); + ctx.on_redo(mock_scn(1)); + ctx.before_prepare(); + ctx.on_prepare(mock_scn(2)); + ctx.on_commit(mock_scn(3), mock_scn(3));// will cost 500ms + }); + std::thread t2([&row]() { + OCCAM_LOG(DEBUG, "t2 start"); + ob_usleep(250_ms); + row.~MdsRow(); + }); + t1.join(); + t2.join(); + ASSERT_EQ(5, call_on_set); + ASSERT_EQ(5, call_try_on_redo); + ASSERT_GE(call_try_on_commit, 0); + ASSERT_LE(call_try_on_commit, 5); +} + +// TEST_F(TestMdsNode, test_prepare_version_with_commit) { +// UserMdsNode node(nullptr, MdsNodeType::SET, WriterType::TRANSACTION, 1); +// ASSERT_EQ(node.get_prepare_version_(), share::SCN::max_scn()); +// node.try_on_redo(mock_scn(1)); +// ASSERT_EQ(node.get_prepare_version_(), share::SCN::max_scn()); +// node.try_before_prepare(); +// ASSERT_EQ(node.get_prepare_version_(), share::SCN::min_scn()); +// node.try_on_prepare(mock_scn(2)); +// ASSERT_EQ(node.get_prepare_version_(), mock_scn(2)); // prepare version没有传下来 +// ASSERT_EQ(node.is_aborted_(), false); +// ASSERT_EQ(node.is_committed_(), false); +// ASSERT_EQ(node.is_decided_(), false); +// node.try_on_commit(mock_scn(3), mock_scn(3)); +// ASSERT_EQ(node.is_aborted_(), false); +// ASSERT_EQ(node.is_committed_(), true); +// ASSERT_EQ(node.is_decided_(), true); +// ASSERT_EQ(node.get_prepare_version_(), mock_scn(3)); +// } + +// TEST_F(TestMdsNode, test_prepare_version_with_abort) { +// UserMdsNode node(nullptr, MdsNodeType::SET, WriterType::TRANSACTION, 1); +// ASSERT_EQ(node.is_aborted_(), false); +// ASSERT_EQ(node.is_committed_(), false); +// ASSERT_EQ(node.is_decided_(), false); +// node.try_on_abort(share::SCN::max_scn()); +// ASSERT_EQ(node.is_aborted_(), true); +// ASSERT_EQ(node.is_committed_(), false); +// ASSERT_EQ(node.is_decided_(), true); +// ASSERT_EQ(call_try_on_abort, true); +// ASSERT_EQ(node.get_prepare_version_(), share::SCN::max_scn()); +// } + +// TEST_F(TestMdsNode, test_commit_version_with_commit) { +// UserMdsNode node(nullptr, MdsNodeType::SET, WriterType::TRANSACTION, 1); +// ASSERT_EQ(node.get_commit_version_(), share::SCN::max_scn()); +// node.try_on_redo(mock_scn(1)); +// ASSERT_EQ(node.get_commit_version_(), share::SCN::max_scn()); +// node.try_before_prepare(); +// ASSERT_EQ(node.get_commit_version_(), share::SCN::max_scn()); +// node.try_on_prepare(mock_scn(2)); +// ASSERT_EQ(node.get_commit_version_(), share::SCN::max_scn()); +// node.try_on_commit(mock_scn(3), mock_scn(3)); +// ASSERT_EQ(node.get_commit_version_(), mock_scn(3));// only valid after commit +// } + +// TEST_F(TestMdsNode, test_commit_version_with_abort) { +// UserMdsNode node(nullptr, MdsNodeType::SET, WriterType::TRANSACTION, 1); +// node.try_on_abort(share::SCN::max_scn()); +// ASSERT_EQ(node.get_commit_version_(), share::SCN::max_scn()); +// } + +TEST_F(TestMdsNode, test_node_print) { + UserMdsNode node0(nullptr, MdsNodeType::SET, WriterType::TRANSACTION, 1); + UserMdsNode node1(nullptr, MdsNodeType::SET, WriterType::TRANSACTION, 1); +} + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_mds_node.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_mds_node.log", false); + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + int64_t alloc_times = oceanbase::storage::mds::MdsAllocator::get_alloc_times(); + int64_t free_times = oceanbase::storage::mds::MdsAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + ret = -1; + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} \ No newline at end of file diff --git a/unittest/storage/multi_data_source/test_mds_row.cpp b/unittest/storage/multi_data_source/test_mds_row.cpp new file mode 100644 index 000000000..bc8610c34 --- /dev/null +++ b/unittest/storage/multi_data_source/test_mds_row.cpp @@ -0,0 +1,229 @@ +/** + * Copyright (c) 2021 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. + */ +#define UNITTEST_DEBUG +#include +#include "lib/ob_errno.h" +#include "share/ob_errno.h" +#include +#define private public +#define protected public +#include "common_define.h" +#include "lib/allocator/ob_malloc.h" +#include "storage/multi_data_source/mds_node.h" +#include +#include +#include +#include +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_row.h" +#include "example_user_helper_define.cpp" +namespace oceanbase { +namespace unittest { + +using namespace common; +using namespace std; +using namespace storage; +using namespace mds; + +class TestMdsRowAndMdsCtx: public ::testing::Test +{ +public: + TestMdsRowAndMdsCtx() {}; + virtual ~TestMdsRowAndMdsCtx() {}; + virtual void SetUp() { + }; + virtual void TearDown() { + }; + static void mds_row_set_element(); + static void two_thread_set_conflict(); + static void get_uncommitted(); + static void get_latest(); + static void get_by_writer(); + static void get_snapshop_until_timeout(); + static void get_snapshop_disgard(); + static MdsRow row_; +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestMdsRowAndMdsCtx); +}; + +MdsRow TestMdsRowAndMdsCtx::row_; + +void TestMdsRowAndMdsCtx::mds_row_set_element() { + ExampleUserData2 data1(1); + MdsCtx ctx1(1); + ASSERT_EQ(OB_SUCCESS, row_.set(data1, ctx1, 0));// copy user data + UserMdsNode *user_node = dynamic_cast *>(row_.sorted_list_.list_.list_head_); + ASSERT_NE(user_node->user_data_.data_.ptr(), data1.data_.ptr()); + auto p_data = data1.data_.ptr(); + ASSERT_EQ(OB_SUCCESS, row_.set(std::move(data1), ctx1, 0));// move user data + user_node = dynamic_cast *>(row_.sorted_list_.list_.list_head_); + ASSERT_EQ(user_node->user_data_.data_.ptr(), p_data); + MdsCtx ctx2(2); + ExampleUserData2 data2(2); + ASSERT_EQ(OB_TRY_LOCK_ROW_CONFLICT, row_.set(data2, ctx2, 0));// 不设超时,报6005 + ASSERT_EQ(OB_ERR_EXCLUSIVE_LOCK_CONFLICT, row_.set(data2, ctx2, 200_ms));// 设超时,报6003 + ctx1.on_redo(mock_scn(1)); + ASSERT_EQ(OB_TRY_LOCK_ROW_CONFLICT, row_.set(data2, ctx2, 0));// 不设超时,报6005 + ctx1.before_prepare(); + ASSERT_EQ(OB_TRY_LOCK_ROW_CONFLICT, row_.set(data2, ctx2, 0));// 不设超时,报6005 + ctx1.on_prepare(mock_scn(2)); + ASSERT_EQ(OB_TRY_LOCK_ROW_CONFLICT, row_.set(data2, ctx2, 0));// 不设超时,报6005 + ctx1.on_commit(mock_scn(3)); + ASSERT_EQ(OB_SUCCESS, row_.set(data2, ctx2, 0)); +} + +void TestMdsRowAndMdsCtx::two_thread_set_conflict() { + std::thread t1([]() { + ExampleUserData2 data(6); + MdsCtx ctx(3); + ASSERT_EQ(OB_SUCCESS, row_.set(data, ctx, 0)); + ob_usleep(500_ms); + ctx.on_redo(mock_scn(6)); + ctx.before_prepare(); + ctx.on_prepare(mock_scn(6)); + ctx.on_commit(mock_scn(6)); + }); + std::thread t2([]() { + ExampleUserData2 data(7); + MdsCtx ctx(4); + ob_usleep(100_ms); + ASSERT_EQ(OB_TRY_LOCK_ROW_CONFLICT, row_.set(data, ctx, 0)); + ASSERT_EQ(OB_SUCCESS, row_.set(data, ctx, 1_s)); + ob_usleep(500_ms); + ctx.on_redo(mock_scn(9)); + ctx.before_prepare(); + ctx.on_prepare(mock_scn(9)); + ctx.on_commit(mock_scn(9)); + }); + t1.join(); + t2.join(); +} + +void TestMdsRowAndMdsCtx::get_uncommitted() { + ExampleUserData2 data(12); + MdsCtx ctx(5); + ASSERT_EQ(OB_SUCCESS, row_.set(data, ctx, 0)); + MdsCtx ctx2(6); + int64_t data_size = 0; + ASSERT_EQ(OB_SUCCESS, row_.get_uncommitted([&data_size](const ExampleUserData2 &data) { + data_size = data.data_.length(); + return OB_SUCCESS; + }, 0)); + ASSERT_EQ(12, data_size); + ctx.on_redo(mock_scn(10)); + ctx.before_prepare(); + ctx.on_prepare(mock_scn(10)); + ctx.on_commit(mock_scn(10)); +} + +void TestMdsRowAndMdsCtx::get_latest() { + int64_t data_size = 0; + ASSERT_EQ(OB_SUCCESS, row_.get_snapshot([&data_size](const ExampleUserData2 &data) { + data_size = data.data_.length(); + return OB_SUCCESS; + }, share::SCN::max_scn(), 0, 0)); + ExampleUserData2 data(13); + MdsCtx ctx(7); + ASSERT_EQ(OB_SUCCESS, row_.set(data, ctx, 0)); + ASSERT_EQ(OB_ERR_SHARED_LOCK_CONFLICT, row_.get_snapshot([&data_size](const ExampleUserData2 &data) { + data_size = data.data_.length(); + return OB_SUCCESS; + }, share::SCN::max_scn(), 0, 0)); + ASSERT_EQ(12, data_size); +} + +void TestMdsRowAndMdsCtx::get_by_writer() { + ExampleUserData2 data(13); + MdsCtx ctx(9); + int64_t data_size = 0; + ASSERT_EQ(OB_SUCCESS, row_.get_by_writer([&data_size](const ExampleUserData2 &data) { + data_size = data.data_.length(); + return OB_SUCCESS; + }, 9, mock_scn(6), 0, 0));// read snapshot + ASSERT_EQ(6, data_size);// read committed version + + ASSERT_EQ(OB_SUCCESS, row_.set(data, ctx, 0)); + ASSERT_EQ(OB_SUCCESS, row_.get_by_writer([&data_size](const ExampleUserData2 &data) { + data_size = data.data_.length(); + return OB_SUCCESS; + }, 9, mock_scn(10)/*not affected*/, 0, 0)); + ASSERT_EQ(13, data_size);// read self write +} + +void TestMdsRowAndMdsCtx::get_snapshop_until_timeout() { + ExampleUserData2 data(20); + MdsCtx ctx(20); + int64_t data_size = 0; + ASSERT_EQ(OB_SUCCESS, row_.set(data, ctx, 0)); + ctx.before_prepare();// block all read operations + ASSERT_EQ(OB_ERR_SHARED_LOCK_CONFLICT, row_.get_by_writer([&data_size](const ExampleUserData2 &data) { + data_size = data.data_.length(); + return OB_SUCCESS; + }, 10, mock_scn(6), 0, 500_ms));// read snapshot timeout + ASSERT_EQ(OB_ERR_SHARED_LOCK_CONFLICT, row_.get_snapshot([&data_size](const ExampleUserData2 &data) { + data_size = data.data_.length(); + return OB_SUCCESS; + }, mock_scn(6), 0, 500_ms));// read snapshot timeout + + ctx.on_redo(mock_scn(20)); + ctx.on_prepare(mock_scn(20)); + ctx.on_commit(mock_scn(20)); + + ASSERT_EQ(OB_SUCCESS, row_.get_snapshot([&data_size](const ExampleUserData2 &data) { + data_size = data.data_.length(); + return OB_SUCCESS; + }, mock_scn(6), 0, 500_ms));// read snapshot + ASSERT_EQ(6, data_size); + ASSERT_EQ(OB_SUCCESS, row_.get_snapshot([&data_size](const ExampleUserData2 &data) { + data_size = data.data_.length(); + return OB_SUCCESS; + }, mock_scn(21), 0, 500_ms));// read snapshot + ASSERT_EQ(20, data_size); +} + +void TestMdsRowAndMdsCtx::get_snapshop_disgard() { + ASSERT_EQ(OB_SNAPSHOT_DISCARDED, row_.get_snapshot([](const ExampleUserData2 &data) { + return OB_SUCCESS; + }, mock_scn(1), 0, 500_ms));// read snapshot timeout +} + +TEST_F(TestMdsRowAndMdsCtx, mds_row_set_element) { TestMdsRowAndMdsCtx::mds_row_set_element(); } +TEST_F(TestMdsRowAndMdsCtx, two_thread_set_conflict) { TestMdsRowAndMdsCtx::two_thread_set_conflict(); } +TEST_F(TestMdsRowAndMdsCtx, get_uncommitted) { TestMdsRowAndMdsCtx::get_uncommitted(); } +TEST_F(TestMdsRowAndMdsCtx, get_latest) { TestMdsRowAndMdsCtx::get_latest(); } +TEST_F(TestMdsRowAndMdsCtx, get_by_writer) { TestMdsRowAndMdsCtx::get_by_writer(); } +TEST_F(TestMdsRowAndMdsCtx, get_snapshop_until_timeout) { TestMdsRowAndMdsCtx::get_snapshop_until_timeout(); } +TEST_F(TestMdsRowAndMdsCtx, get_snapshop_disgard) { TestMdsRowAndMdsCtx::get_snapshop_disgard(); } + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_mds_row.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_mds_row.log", false); + logger.set_log_level(OB_LOG_LEVEL_TRACE); + testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + oceanbase::unittest::TestMdsRowAndMdsCtx::row_.~MdsRow(); + int64_t alloc_times = oceanbase::storage::mds::MdsAllocator::get_alloc_times(); + int64_t free_times = oceanbase::storage::mds::MdsAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + ret = -1; + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} \ No newline at end of file diff --git a/unittest/storage/multi_data_source/test_mds_table.cpp b/unittest/storage/multi_data_source/test_mds_table.cpp new file mode 100644 index 000000000..7018abcf6 --- /dev/null +++ b/unittest/storage/multi_data_source/test_mds_table.cpp @@ -0,0 +1,654 @@ +/** + * Copyright (c) 2021 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. + */ +#define UNITTEST_DEBUG +#include "lib/utility/utility.h" +#include +#define private public +#define protected public +#include "multi_data_source/example_user_data_define.h" +#include "share/ob_ls_id.h" +#include "storage/multi_data_source/mds_writer.h" +#include +#include +#include +#include +#include +#include "common_define.h" +#include "lib/ob_errno.h" +#include "share/ob_errno.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include "lib/allocator/ob_malloc.h" +#include "storage/multi_data_source/mds_node.h" +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_row.h" +#include "storage/multi_data_source/mds_unit.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/multi_data_source/mds_table_handler.h" +#include "example_user_helper_define.cpp" +#include "storage/tx/ob_trans_define.h" +#include +#include +#include "storage/multi_data_source/runtime_utility/mds_lock.h" +#include "storage/tablet/ob_tablet_meta.h" +namespace oceanbase { +namespace storage +{ +namespace mds +{ +void *MdsAllocator::alloc(const int64_t size) +{ + void *ptr = ob_malloc(size, "MDS"); + ATOMIC_INC(&alloc_times_); + MDS_LOG(DEBUG, "alloc obj", KP(ptr), K(size), K(lbt())); + return ptr; +} +void MdsAllocator::free(void *ptr) { + ATOMIC_INC(&free_times_); + MDS_LOG(DEBUG, "free obj", KP(ptr), K(lbt())); + ob_free(ptr); +} +} +} +namespace unittest { + +using namespace common; +using namespace std; +using namespace storage; +using namespace mds; +using namespace transaction; + +class TestMdsTable: public ::testing::Test +{ +public: + TestMdsTable() {} + virtual ~TestMdsTable() {} + virtual void SetUp() { + } + virtual void TearDown() { + } + static void set(); + static void replay(); + static void get_latest(); + static void get_snapshot(); + static void get_snapshot_hung_1s(); + static void get_by_writer(); + static void insert_multi_row(); + static void get_multi_row(); + // static void for_each_scan(); + static void standard_iterator(); + static void OB_iterator(); + static void test_flush(); + static void test_is_locked_by_others(); + static void test_multi_key_remove(); +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestMdsTable); +}; + +ObMdsTableHandler mds_table_hanlder; +MdsTableHandle &mds_table_ = mds_table_hanlder.mds_table_handle_; + +/***********************************************Single Row*************************************************************/ +struct A { ObSpinLock lock_; }; +struct B { MdsLock lock_; }; + +#define GET_REAL_MDS_TABLE(mds_table) (*((MdsTableImpl*)(dynamic_cast>*>((mds_table.p_mds_table_base_.ctrl_ptr_->p_data_block_))->data_))) + +void TestMdsTable::set() { + ASSERT_EQ(OB_SUCCESS, mds_table_.init(MdsAllocator::get_instance(), ObTabletID(1), share::ObLSID(1), (ObTabletPointer*)0x111)); + MDS_LOG(INFO, "test sizeof", K(sizeof(MdsTableImpl)), K(sizeof(B)), K(mds_table_.p_mds_table_base_.ctrl_ptr_->ref_)); + ExampleUserData1 data1(1); + ExampleUserData2 data2; + ASSERT_EQ(OB_SUCCESS, data2.assign(MdsAllocator::get_instance(), "123")); + MdsCtx ctx1(mds::MdsWriter(ObTransID(1)));// commit finally + DummyKey key; + ASSERT_EQ(OB_SUCCESS, mds_table_.set(data1, ctx1)); + ASSERT_EQ(OB_SUCCESS, mds_table_.set(data2, ctx1)); + ctx1.on_redo(mock_scn(10)); + ctx1.before_prepare(); + ctx1.on_prepare(mock_scn(10)); + ctx1.on_commit(mock_scn(10), mock_scn(10)); + ExampleUserData1 data3(3); + MdsCtx ctx2(mds::MdsWriter(ObTransID(2)));// abort by RAII finally + ASSERT_EQ(OB_SUCCESS, mds_table_.set(data1, ctx2)); + ctx2.on_abort(mock_scn(8)); +} +// : (data:1, writer:1, ver:10) +// : (data:2, writer:1, ver:10) + +void TestMdsTable::replay() { + ExampleUserData1 data1(3); + MdsCtx ctx1(mds::MdsWriter(ObTransID(1)));// commit finally + ASSERT_EQ(OB_SUCCESS, mds_table_.replay(data1, ctx1, mock_scn(9))); + // ctx1.on_redo(mock_scn(9));// insert to tail on unit ExampleUserData1 + ctx1.before_prepare(); + ctx1.on_prepare(mock_scn(9)); + ctx1.on_commit(mock_scn(9), mock_scn(9)); + auto &unit = GET_REAL_MDS_TABLE(mds_table_).unit_tuple_.element>(); + MDS_LOG(INFO, "xuwang test", K(unit.single_row_)); + + share::SCN recorde_scn = mock_scn(0); + unit.single_row_.v_.sorted_list_.for_each_node_from_tail_to_head_until_true([&](const UserMdsNode &node) -> int { + if (!node.is_aborted_()) { + OB_ASSERT(node.redo_scn_ > recorde_scn); + recorde_scn = node.redo_scn_; + } + return OB_SUCCESS; + }); +} +// : (data:1, writer:1, ver:10) -> (data:3, writer:1, ver:9) +// : (data:2, writer:1, ver:10) + +void TestMdsTable::get_latest() +{ + ExampleUserData1 data1(5); + MdsCtx ctx1(mds::MdsWriter(ObTransID(1)));// abort finally + ASSERT_EQ(OB_SUCCESS, mds_table_.set(data1, ctx1)); + int value = 0; + bool unused_committed_flag = false; + ASSERT_EQ(OB_SUCCESS, mds_table_.get_latest([&value](const ExampleUserData1 &data) { + value = data.value_; + return OB_SUCCESS; + }, unused_committed_flag)); + ASSERT_EQ(5, value);// read uncommitted + ctx1.on_abort(mock_scn(11)); +} + +void TestMdsTable::get_snapshot() +{ + int value = 0; + ASSERT_EQ(OB_SUCCESS, mds_table_.get_snapshot([&value](const ExampleUserData1 &data) { + value = data.value_; + return OB_SUCCESS; + }, mock_scn(9))); + ASSERT_EQ(3, value);// read snapshot +} + +void TestMdsTable::get_snapshot_hung_1s() +{ + std::thread th1([&]() { + MdsCtx ctx(mds::MdsWriter(ObTransID(1)));// abort finally + ExampleUserData1 data(1); + ASSERT_EQ(OB_SUCCESS, mds_table_.set(data, ctx)); + ctx.on_redo(mock_scn(3)); + ctx.before_prepare(); + this_thread::sleep_for(chrono::milliseconds(1200)); + ctx.on_abort(mock_scn(12)); + }); + + std::thread th2([&]() { + this_thread::sleep_for(chrono::milliseconds(100)); + ExampleUserData1 data; + int64_t start_ts = ObClockGenerator::getRealClock(); + ASSERT_EQ(OB_SUCCESS, mds_table_.get_snapshot([&data](const ExampleUserData1 &node_data) { + data = node_data; + return OB_SUCCESS; + }, share::SCN::max_scn(), 0, 2_s)); + ASSERT_LE(1_s, ObClockGenerator::getRealClock() - start_ts); + ASSERT_EQ(1, data.value_);// read snapshot + }); + + th1.join(); + th2.join(); +} + +void TestMdsTable::get_by_writer() +{ + ExampleUserData1 data1(15); + MdsCtx ctx1(mds::MdsWriter(ObTransID(15)));// abort finally + ASSERT_EQ(OB_SUCCESS, mds_table_.set(data1, ctx1)); + ExampleUserData2 data2; + ASSERT_EQ(OB_SUCCESS, data2.assign(MdsAllocator::get_instance(), "3456")); + MdsCtx ctx2(mds::MdsWriter(ObTransID(20)));// commit finally with version 20 + ASSERT_EQ(OB_SUCCESS, mds_table_.set(data2, ctx2)); + ctx2.on_redo(mock_scn(20)); + ctx2.before_prepare(); + ctx2.on_prepare(mock_scn(20)); + ctx2.on_commit(mock_scn(20), mock_scn(20)); + int value = 0; + ASSERT_EQ(OB_SUCCESS, mds_table_.get_by_writer([&value](const ExampleUserData1 &data) { + value = data.value_; + return OB_SUCCESS; + }, mds::MdsWriter(ObTransID(15)), mock_scn(15)));// read self uncommitted change + ASSERT_EQ(15, value);// read uncommitted + ASSERT_EQ(OB_SUCCESS, mds_table_.get_by_writer([&value](const ExampleUserData2 &data) { + value = data.data_.length(); + return OB_SUCCESS; + }, mds::MdsWriter(ObTransID(15)), mock_scn(15)));// read others committed change + ASSERT_EQ(3, value);// read last committed + ctx1.on_abort(mock_scn(20)); +} +// : (data:1, writer:1, ver:10) -> (data:3, writer:1, ver:9) +// : (data:20, writer:20, ver:20) -> (data:2, writer:1, ver:10) + + +/***********************************************Multi Row**************************************************************/ + +void TestMdsTable::insert_multi_row() { + ExampleUserKey key(1); + ExampleUserData1 data1(1); + MdsCtx ctx(mds::MdsWriter(ObTransID(1)));// commit finally + ASSERT_EQ(OB_SUCCESS, mds_table_.set(key, data1, ctx)); + ctx.on_redo(mock_scn(1)); + ctx.before_prepare(); + ctx.on_prepare(mock_scn(1)); + ctx.on_commit(mock_scn(1), mock_scn(1)); + + ExampleUserKey key2(2); + ExampleUserData1 data2(2); + MdsCtx ctx2(mds::MdsWriter(ObTransID(2)));// commit finally + ASSERT_EQ(OB_SUCCESS, mds_table_.set(key2, data2, ctx2)); + ASSERT_EQ(OB_SUCCESS, mds_table_.set(key, data2, ctx2));// 因为只存储单版本,所以data1读不到了 + ctx2.on_redo(mock_scn(2)); + ctx2.before_prepare(); + ctx2.on_prepare(mock_scn(2)); + ctx2.on_commit(mock_scn(2), mock_scn(2)); +} +// : (data:1, writer:1, ver:10) -> (data:3, writer:1, ver:9) +// : (data:20, writer:20, ver:20) -> (data:2, writer:1, ver:10) +// : <1> : (data:2, writer:2, ver:2) -> (data:1, writer:1, ver:1) +// <2> : (data:2, writer:2, ver:2) + +void TestMdsTable::get_multi_row() { + ExampleUserData1 read_data; + ExampleUserKey key(1); + ExampleUserData1 data3(3); + MdsCtx ctx3(mds::MdsWriter(ObTransID(3)));// abort finally + ASSERT_EQ(OB_SUCCESS, mds_table_.set(key, data3, ctx3)); + auto read_op = [&read_data](const ExampleUserData1 &data) { read_data = data; return OB_SUCCESS; }; + int ret = mds_table_.get_snapshot(ExampleUserKey(1), read_op, mock_scn(2)); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(2, read_data.value_); + ret = mds_table_.get_snapshot(ExampleUserKey(1), read_op, mock_scn(1));// 没有转储,旧版本还是保留的 + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(1, read_data.value_); + + bool unused_committed_flag = false; + ret = mds_table_.get_latest(ExampleUserKey(1), read_op, unused_committed_flag); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(3, read_data.value_); + ctx3.on_abort(mock_scn(3)); +} + +struct ScanOp { + ScanOp() : valid_count_(0), total_count_(0) {} + int operator()(const MdsNode &node) { + if (!node.is_aborted_()) + ++valid_count_; + return OB_SUCCESS; + } + int valid_count_; + int total_count_; +}; + +// void TestMdsTable::for_each_scan() { +// ScanOp op; +// ASSERT_EQ(OB_SUCCESS, mds_table_.for_each_scan_node(op)); +// ASSERT_EQ(op.valid_count_, 7); +// } + +void TestMdsTable::standard_iterator() { + // iter kv unit, range for + MdsUnit *p_mds_unit = nullptr; + ASSERT_EQ(OB_SUCCESS, mds_table_.get_mds_unit(p_mds_unit));// need handle protect table life + { + MdsRLockGuard lg(p_mds_unit->lock_);// lock unit + for (auto &kv_row : *p_mds_unit) { + MdsRLockGuard lg(kv_row.v_.lock_);// lock row + for (auto &mds_node : kv_row.v_) { + MDS_LOG(INFO, "print iter mds node", K(mds_node)); + } + } + } + // iter dummy key unit, reverse iter + MdsUnit *p_mds_unit2 = nullptr; + ASSERT_EQ(OB_SUCCESS, mds_table_.get_mds_unit(p_mds_unit2));// need handle protect table life + { + int64_t cnt_committed = 0; + // using KvRowIter = MdsUnit::iterator; + // using NodeIter = KvRowIter::row_type::iterator; + using KvRowIter = MdsUnit::reverse_iterator; + using NodeIter = KvRowIter::row_type::reverse_iterator; + MdsRLockGuard lg(p_mds_unit->lock_);// lock unit + for (KvRowIter iter1 = p_mds_unit2->rbegin(); iter1 != p_mds_unit2->rend(); ++iter1) {// there is actually only one + MdsRLockGuard lg(iter1->v_.lock_);// lock row + for (NodeIter iter2 = iter1->v_.rbegin(); iter2 != iter1->v_.rend(); ++iter2) { + if (iter2->is_committed_()) { + cnt_committed += 1; + } + } + int64_t cnt = std::count_if(iter1->v_.begin(), iter1->v_.end(), [](UserMdsNode &node){ return node.is_committed_(); }); + ASSERT_EQ(cnt_committed, cnt); + } + } +} + +void TestMdsTable::OB_iterator() { + ObMdsUnitRowNodeScanIterator iter; + ExampleUserKey key; + UserMdsNode *p_node = nullptr; + ASSERT_EQ(OB_SUCCESS, iter.init(mds_table_)); + ASSERT_EQ(OB_SUCCESS, iter.get_next(key, p_node)); + MDS_LOG(INFO, "print iter kv", K(key), K(*p_node)); + ASSERT_EQ(ExampleUserKey(1), key); + { + ASSERT_EQ(ExampleUserData1(2), p_node->user_data_); + ASSERT_EQ(true, p_node->is_committed_()); + ASSERT_EQ(mock_scn(2), p_node->get_commit_version_()); + } + ASSERT_EQ(OB_SUCCESS, iter.get_next(key, p_node)); + MDS_LOG(INFO, "print iter kv", K(key), K(*p_node)); + ASSERT_EQ(ExampleUserKey(1), key); + { + ASSERT_EQ(ExampleUserData1(1), p_node->user_data_); + ASSERT_EQ(true, p_node->is_committed_()); + ASSERT_EQ(mock_scn(1), p_node->get_commit_version_()); + } + ASSERT_EQ(OB_SUCCESS, iter.get_next(key, p_node)); + ASSERT_EQ(ExampleUserKey(2), key); + ASSERT_EQ(OB_ITER_END, iter.get_next(key, p_node)); +} + +// : (data:1, writer:1, ver:10) -> (data:3, writer:1, ver:9) +// : (data:20, writer:20, ver:20) -> (data:2, writer:1, ver:10) +// : <1> : (data:100, writer:100, ver:19001) -> (data:2, writer:2, ver:2) -> (data:1, writer:1, ver:1) +// <2> : (data:200, writer:200, ver:MAX) +void TestMdsTable::test_flush() { + ExampleUserKey key(1); + ExampleUserData1 data1(100); + MdsCtx ctx(mds::MdsWriter(ObTransID(100)));// commit finally + ASSERT_EQ(OB_SUCCESS, mds_table_.set(key, data1, ctx)); + ctx.on_redo(mock_scn(19001)); + ctx.before_prepare(); + ctx.on_prepare(mock_scn(19001)); + ctx.on_commit(mock_scn(19002), mock_scn(19002)); + + ExampleUserKey key2(2); + ExampleUserData1 data2(200); + MdsCtx ctx2(mds::MdsWriter(ObTransID(200)));// abort finally + ASSERT_EQ(OB_SUCCESS, mds_table_.set(key2, data2, ctx2)); + ctx2.on_redo(mock_scn(200)); + + int idx = 0; + ASSERT_EQ(OB_SUCCESS, mds_table_.flush(mock_scn(300)));// 1. 以300为版本号进行flush动作 + ASSERT_EQ(mock_scn(199), mds_table_.p_mds_table_base_->flushing_scn_);// 2. 实际上以199为版本号进行flush动作 + ASSERT_EQ(OB_SUCCESS, mds_table_.for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump( + [&idx](const MdsDumpKV &kv) -> int {// 2. 转储时扫描mds table + OB_ASSERT(kv.v_.end_scn_ < mock_scn(199));// 扫描时看不到199版本以上的提交 + OB_ASSERT(idx < 10); + MDS_LOG(INFO, "print dump node kv", K(kv)); + return OB_SUCCESS; + }, true) + ); + mds_table_.on_flush(mock_scn(199), OB_SUCCESS);// 3. 推大rec_scn【至少】到200 + share::SCN rec_scn; + ASSERT_EQ(OB_SUCCESS, mds_table_.get_rec_scn(rec_scn)); + MDS_LOG(INFO, "print rec scn", K(rec_scn)); + ASSERT_EQ(rec_scn, mock_scn(200)); + MdsCtx ctx3(mds::MdsWriter(ObTransID(101)));// abort finally + ASSERT_EQ(OB_SUCCESS, mds_table_.replay(ExampleUserKey(111), ExampleUserData1(111), ctx3, mock_scn(100))); + ASSERT_EQ(OB_SUCCESS, mds_table_.get_rec_scn(rec_scn)); + ASSERT_EQ(rec_scn, mock_scn(100)); + ctx3.on_abort(mock_scn(100)); + + ScanOp op; + // 未转储:一个已决node + 一个未决node + MDS_LOG(INFO, "print free times", K(oceanbase::storage::mds::MdsAllocator::get_alloc_times()), K(oceanbase::storage::mds::MdsAllocator::get_free_times()));// 回收已转储的node + ASSERT_EQ(OB_SUCCESS, mds_table_.try_recycle(mock_scn(200))); + // ASSERT_EQ(OB_SUCCESS, mds_table_.for_each_scan_node(op)); + // ASSERT_EQ(op.valid_count_, 2); + ctx2.on_abort(mock_scn(200)); + MDS_LOG(INFO, "print free times", K(oceanbase::storage::mds::MdsAllocator::get_free_times()));// 回收已转储的node +} +// : <1> : (data:100, writer:100, ver:19001) + +void TestMdsTable::test_is_locked_by_others() { + int ret = OB_SUCCESS; + bool is_locked = false; + ret = mds_table_.is_locked_by_others(ExampleUserKey(1), is_locked); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(false, is_locked); + ExampleUserData1 data1(300); + MdsCtx ctx(mds::MdsWriter(ObTransID(100)));// abort finally + ASSERT_EQ(OB_SUCCESS, mds_table_.set(ExampleUserKey(1), data1, ctx)); + ret = mds_table_.is_locked_by_others(ExampleUserKey(1), is_locked); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(true, is_locked); + ret = mds_table_.is_locked_by_others(ExampleUserKey(1), is_locked, mds::MdsWriter(ObTransID(100))); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(false, is_locked); +} + +// : <1> : (data:100, writer:100, ver:19001) +void TestMdsTable::test_multi_key_remove() { + bool is_committed = false; + int ret = mds_table_.get_latest(ExampleUserKey(1), [](const ExampleUserData1 &data){ + return OB_SUCCESS; + }, is_committed); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, mds_table_.flush(mock_scn(200))); + ASSERT_EQ(OB_SUCCESS, mds_table_.try_recycle(mock_scn(200))); + ret = mds_table_.get_latest(ExampleUserKey(2), [](const ExampleUserData1 &data){ + return OB_SUCCESS; + }, is_committed); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret); + MdsCtx ctx(mds::MdsWriter(ObTransID(1))); + ret = mds_table_.remove(ExampleUserKey(1), ctx); + ASSERT_EQ(OB_SUCCESS, ret); + ret = mds_table_.get_latest(ExampleUserKey(1), [](const ExampleUserData1 &data){ + return OB_SUCCESS; + }, is_committed); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret); +} + +TEST_F(TestMdsTable, set) { TestMdsTable::set(); } +TEST_F(TestMdsTable, replay) { TestMdsTable::replay(); } +TEST_F(TestMdsTable, get_latest) { TestMdsTable::get_latest(); } +TEST_F(TestMdsTable, get_snapshot) { TestMdsTable::get_snapshot(); } +TEST_F(TestMdsTable, get_snapshot_hung_1s) { TestMdsTable::get_snapshot_hung_1s(); } +TEST_F(TestMdsTable, get_by_writer) { TestMdsTable::get_by_writer(); } +TEST_F(TestMdsTable, insert_multi_row) { TestMdsTable::insert_multi_row(); } +TEST_F(TestMdsTable, get_multi_row) { TestMdsTable::get_multi_row(); } +TEST_F(TestMdsTable, test_standard_style_iterator) { TestMdsTable::standard_iterator(); } +TEST_F(TestMdsTable, test_OB_style_iterator) { TestMdsTable::OB_iterator(); } +TEST_F(TestMdsTable, test_flush) { TestMdsTable::test_flush(); } +TEST_F(TestMdsTable, test_is_locked_by_others) { TestMdsTable::test_is_locked_by_others(); } +TEST_F(TestMdsTable, test_multi_key_remove) { TestMdsTable::test_multi_key_remove(); } + +TEST_F(TestMdsTable, basic_trans_example) { + MdsTableHandle mth; + // 1. 初始化为UnitTestMdsTable + ASSERT_EQ(OB_SUCCESS, mth.init(mds::DefaultAllocator::get_instance(), + ObTabletID(1), + share::ObLSID(1), + nullptr)); + MdsTableHandle mth2 = mth;// 两个引用计数 + MdsCtx ctx(mds::MdsWriter(ObTransID(123)));// 创建一个写入句柄,接入多源事务,ctx由事务层创建 + // 2. 写入数据 + ASSERT_EQ(OB_SUCCESS, mth.set(ExampleUserData1(1), ctx));// 写入第一个数据单元,成功 + ASSERT_EQ(OB_OBJ_TYPE_ERROR, mth.set((int)54321, ctx));// 写入第二个数据单元,但UnitTestMdsTable并未注册该类型数据,Type ERROR + // 3. 对写入数据写CLOG并进行两阶段提交,接入多源事务,则该流程由事务层代为执行, 用户无感知 + ctx.on_redo(mock_scn(100)); + ctx.before_prepare(); + ctx.on_prepare(mock_scn(100)); + ctx.on_commit(mock_scn(100), mock_scn(100)); + // 4. 读取最新已提交数据 + ASSERT_EQ(OB_SUCCESS, mth.get_snapshot([](const ExampleUserData1 &data) { + return data.value_ != 1 ? OB_ERR_UNEXPECTED : OB_SUCCESS; + })); +}// 5. 最后一个Handle析构的时候,MdsTable发生真正的析构行为 + +TEST_F(TestMdsTable, basic_non_trans_example) { + MdsTableHandle mth; + // 1. 初始化为UnitTestMdsTable + ASSERT_EQ(OB_SUCCESS, mth.init(mds::DefaultAllocator::get_instance(), + ObTabletID(1), + share::ObLSID(1), + nullptr)); + MdsTableHandle mth2 = mth;// 两个引用计数 + MdsCtx ctx(MdsWriter(WriterType::AUTO_INC_SEQ, 1));// 创建一个写入句柄,不接入事务,自己写日志 + // 2. 写入数据 + ASSERT_EQ(OB_SUCCESS, mth.set(ExampleUserData1(1), ctx));// 写入第一个数据单元,成功 + ASSERT_EQ(OB_OBJ_TYPE_ERROR, mth.set((int)54321, ctx));// 写入第二个数据单元,但UnitTestMdsTable并未注册该类型数据,Type ERROR + // 3. 对写入数据写CLOG并进行单条日志提交 + ctx.single_log_commit(mock_scn(100), mock_scn(100)); + // 4. 读取最新已提交数据 + ASSERT_EQ(OB_SUCCESS, mth.get_snapshot([](const ExampleUserData1 &data) { + return data.value_ != 1 ? OB_ERR_UNEXPECTED : OB_SUCCESS; + })); +}// 5. 最后一个Handle析构的时候,MdsTable发生真正的析构行为 + +TEST_F(TestMdsTable, test_recycle) { + int64_t alloc_times = oceanbase::storage::mds::MdsAllocator::get_alloc_times(); + int64_t free_times = oceanbase::storage::mds::MdsAllocator::get_free_times(); + ASSERT_NE(alloc_times, free_times); + ASSERT_EQ(OB_SUCCESS, mds_table_.try_recycle(mock_scn(20000))); + int64_t valid_cnt = 0; + ASSERT_EQ(OB_SUCCESS, mds_table_.get_node_cnt(valid_cnt)); + ASSERT_EQ(1, valid_cnt);// 此时还有一个19001版本的已提交数据,因为rec_scn没有推上去 + ASSERT_EQ(OB_SUCCESS, mds_table_.flush(mock_scn(20000))); + mds_table_.for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump([](const MdsDumpKV &){ + return OB_SUCCESS; + }, true); + mds_table_.on_flush(mock_scn(20000), OB_SUCCESS); + share::SCN rec_scn; + ASSERT_EQ(OB_SUCCESS, mds_table_.get_rec_scn(rec_scn)); + MDS_LOG(INFO, "print rec scn", K(rec_scn)); + ASSERT_EQ(share::SCN::max_scn(), rec_scn); + ASSERT_EQ(OB_SUCCESS, mds_table_.try_recycle(mock_scn(20000))); + ASSERT_EQ(OB_SUCCESS, mds_table_.get_node_cnt(valid_cnt)); + ASSERT_EQ(0, valid_cnt);// 此时还有一个19001版本的已提交数据,因为rec_scn没有推上去 +} + +TEST_F(TestMdsTable, test_recalculate_flush_scn_op) { + MdsTableHandle mds_table; + ASSERT_EQ(OB_SUCCESS, mds_table.init(MdsAllocator::get_instance(), ObTabletID(1), share::ObLSID(1), (ObTabletPointer*)0x111)); + MdsCtx ctx1(mds::MdsWriter(ObTransID(1))); + MdsCtx ctx2(mds::MdsWriter(ObTransID(2))); + MdsCtx ctx3(mds::MdsWriter(ObTransID(3))); + ASSERT_EQ(OB_SUCCESS, mds_table.set(ExampleUserData1(1), ctx1)); + ctx1.on_redo(mock_scn(1)); + ctx1.on_commit(mock_scn(3), mock_scn(3)); + ASSERT_EQ(OB_SUCCESS, mds_table.set(ExampleUserData1(2), ctx2)); + ctx2.on_redo(mock_scn(5)); + ctx2.on_commit(mock_scn(7), mock_scn(7)); + ASSERT_EQ(OB_SUCCESS, mds_table.set(ExampleUserData1(3), ctx3)); + ctx3.on_redo(mock_scn(9)); + ctx3.on_commit(mock_scn(11), mock_scn(11)); + ASSERT_EQ(OB_SUCCESS, mds_table.flush(mock_scn(4))); + ASSERT_EQ(mock_scn(4), mds_table.p_mds_table_base_->flushing_scn_); + mds_table.on_flush(mock_scn(4), OB_SUCCESS); + ASSERT_EQ(OB_SUCCESS, mds_table.flush(mock_scn(5)));// no need do flush, directly advance rec_scn + ASSERT_EQ(false, mds_table.p_mds_table_base_->flushing_scn_.is_valid()); + ASSERT_EQ(OB_SUCCESS, mds_table.flush(mock_scn(6)));// no need do flush, directly advance rec_scn + ASSERT_EQ(false, mds_table.p_mds_table_base_->flushing_scn_.is_valid()); + ASSERT_EQ(OB_SUCCESS, mds_table.flush(mock_scn(7))); + ASSERT_EQ(mock_scn(7), mds_table.p_mds_table_base_->flushing_scn_); + mds_table.on_flush(mock_scn(7), OB_SUCCESS); + ASSERT_EQ(OB_SUCCESS, mds_table.flush(mock_scn(8))); + ASSERT_EQ(false, mds_table.p_mds_table_base_->flushing_scn_.is_valid()); + ASSERT_EQ(mock_scn(9), mds_table.p_mds_table_base_->rec_scn_); +} + +// TEST_F(TestMdsTable, test_node_commit_in_row) { +// MdsRow row; +// MdsCtx ctx1(mds::MdsWriter(WriterType::AUTO_INC_SEQ, 1)); +// ASSERT_EQ(OB_SUCCESS, row.set(ExampleUserData1(1), ctx1, 0)); +// ctx1.single_log_commit(mock_scn(1), mock_scn(1)); +// MdsCtx ctx2(mds::MdsWriter(WriterType::AUTO_INC_SEQ, 2)); +// ASSERT_EQ(OB_SUCCESS, row.set(ExampleUserData1(2), ctx2, 0)); +// ctx1.single_log_commit(mock_scn(2), mock_scn(2));// won't release last committed node +// int node_cnt = 0; +// row.sorted_list_.for_each_node_from_head_to_tail_until_true([&node_cnt](const UserMdsNode &){ ++node_cnt; return false; }); +// ASSERT_EQ(2, node_cnt); +// } + +TEST_F(TestMdsTable, test_rw_lock_rrlock) { + MdsLock lock; + std::thread t1([&lock]() { + MdsRLockGuard lg(lock); + ob_usleep(1_s); + }); + std::thread t2([&lock]() { + MdsRLockGuard lg(lock); + ob_usleep(1_s); + }); + t1.join(); + t2.join(); +} + +TEST_F(TestMdsTable, test_rw_lock_wrlock) { + MdsLock lock; + std::thread t1([&lock]() { + MdsWLockGuard lg(lock); + ob_usleep(1_s); + }); + std::thread t2([&lock]() { + ob_usleep(200_ms); + MdsRLockGuard lg(lock); + ob_usleep(1_s); + }); + t1.join(); + t2.join(); +} + +TEST_F(TestMdsTable, test_rw_lock_rwlock) { + MdsLock lock; + std::thread t1([&lock]() { + ob_usleep(200_ms); + MdsWLockGuard lg(lock); + ob_usleep(1_s); + }); + std::thread t2([&lock]() { + MdsRLockGuard lg(lock); + ob_usleep(1_s); + }); + t1.join(); + t2.join(); +} + +TEST_F(TestMdsTable, test_rw_lock_wwlock) { + MdsLock lock; + std::thread t1([&lock]() { + MdsWLockGuard lg(lock); + ob_usleep(1_s); + }); + std::thread t2([&lock]() { + MdsWLockGuard lg(lock); + ob_usleep(1_s); + }); + t1.join(); + t2.join(); +} + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_mds_table.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_mds_table.log", false); + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + oceanbase::unittest::mds_table_.~MdsTableHandle(); + int64_t alloc_times = oceanbase::storage::mds::MdsAllocator::get_alloc_times(); + int64_t free_times = oceanbase::storage::mds::MdsAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + ret = -1; + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} diff --git a/unittest/storage/multi_data_source/test_mds_table_flush.cpp b/unittest/storage/multi_data_source/test_mds_table_flush.cpp new file mode 100644 index 000000000..d77444030 --- /dev/null +++ b/unittest/storage/multi_data_source/test_mds_table_flush.cpp @@ -0,0 +1,256 @@ +/** + * Copyright (c) 2021 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/utility/utility.h" +#include "storage/multi_data_source/compile_utility/mds_dummy_key.h" +#include +#define private public +#define protected public +#include "multi_data_source/example_user_data_define.h" +#include "share/ob_ls_id.h" +#include "storage/multi_data_source/mds_writer.h" +#include +#include +#include +#include +#include +#include "common_define.h" +#include "lib/ob_errno.h" +#include "share/ob_errno.h" +#include "storage/multi_data_source/adapter_define/mds_dump_node.h" +#include "lib/allocator/ob_malloc.h" +#include "storage/multi_data_source/mds_node.h" +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_row.h" +#include "storage/multi_data_source/mds_unit.h" +#include "storage/multi_data_source/mds_table_handle.h" +#include "storage/multi_data_source/mds_table_handler.h" +#include "example_user_helper_define.cpp" +#include "storage/tx/ob_trans_define.h" +#include +#include +#include "storage/multi_data_source/runtime_utility/mds_lock.h" +#include "storage/tablet/ob_tablet_meta.h" +namespace oceanbase { +namespace storage +{ + +share::SCN MOCK_MAX_CONSEQUENT_CALLBACKED_SCN; +share::SCN MOCK_FLUSHING_SCN; + +namespace mds +{ +void *MdsAllocator::alloc(const int64_t size) +{ + void *ptr = ob_malloc(size, "MDS"); + ATOMIC_INC(&alloc_times_); + MDS_LOG(DEBUG, "alloc obj", KP(ptr), K(size), K(lbt())); + return ptr; +} +void MdsAllocator::free(void *ptr) { + ATOMIC_INC(&free_times_); + MDS_LOG(DEBUG, "free obj", KP(ptr), K(lbt())); + ob_free(ptr); +} + +int MdsTableBase::get_ls_max_consequent_callbacked_scn_(share::SCN &max_consequent_callbacked_scn) const +{ + max_consequent_callbacked_scn = MOCK_MAX_CONSEQUENT_CALLBACKED_SCN; + return OB_SUCCESS; +} + +int MdsTableBase::merge(const share::SCN &flushing_scn) +{ + MOCK_FLUSHING_SCN = flushing_scn; + return OB_SUCCESS; +} + +} +} +namespace unittest { + +using namespace common; +using namespace std; +using namespace storage; +using namespace mds; +using namespace transaction; + +class TestMdsTableFlush: public ::testing::Test +{ +public: + TestMdsTableFlush() {} + virtual ~TestMdsTableFlush() {} + virtual void SetUp() { + } + virtual void TearDown() { + } +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestMdsTableFlush); +}; + + +// max_decided_scn:475 +// │ +// │ +// │ +// ┌──────────┐ │ ┌──────────┐ ┌──────────┐ +// MdsUnit │(MAX, 500]│◄─┼──────────────────────┤[300, 250]│◄──────────────────────────┤(100, 50]│ +// └──────────┘ │ └──────────┘ └──────────┘ +// │ +// │ +// │ +// │ +// │ ┌──────────┐ ┌──────────┐ +// MdsUnit │ │[400, 350]│◄──────────────────────────┤[225, 200]│ +// │ └──────────┘ └──────────┘ +// │ +// │ +// │ +// │ +int construct_tested_mds_table(MdsTableHandle &handle) { + int ret = OB_SUCCESS; + handle.reset(); + vector v_ctx; + for (int i = 0; i < 7; ++i) { + v_ctx.push_back(new MdsCtx(MdsWriter(transaction::ObTransID(i)))); + } + if (OB_FAIL(handle.init(MdsAllocator::get_instance(), ObTabletID(1), share::ObLSID(1), (ObTabletPointer*)0x111))) { + } else if (OB_FAIL(handle.set(1, *v_ctx[0]))) { + } else if (FALSE_IT(v_ctx[0]->on_redo(mock_scn(50)))) { + } else if (FALSE_IT(v_ctx[0]->on_commit(mock_scn(100), mock_scn(100)))) { + } else if (OB_FAIL(handle.set(2, *v_ctx[1]))) { + } else if (FALSE_IT(v_ctx[1]->on_redo(mock_scn(250)))) { + } else if (FALSE_IT(v_ctx[1]->on_commit(mock_scn(300), mock_scn(300)))) { + } else if (OB_FAIL(handle.set(3, *v_ctx[2]))) { + } else if (FALSE_IT(v_ctx[2]->on_redo(mock_scn(500)))) { + } else if (OB_FAIL(handle.set(ExampleUserData2(), *v_ctx[3]))) { + } else if (FALSE_IT(v_ctx[3]->on_redo(mock_scn(200)))) { + } else if (FALSE_IT(v_ctx[3]->on_commit(mock_scn(225), mock_scn(225)))) { + } else if (OB_FAIL(handle.set(ExampleUserData2(), *v_ctx[4]))) { + } else if (FALSE_IT(v_ctx[4]->on_redo(mock_scn(350)))) { + } else if (FALSE_IT(v_ctx[4]->on_commit(mock_scn(400), mock_scn(400)))) { + } else if (OB_SUCCESS != (ret = handle.set(ExampleUserKey(1), ExampleUserData1(1), *v_ctx[5]))) { + } else if (OB_SUCCESS != (ret = handle.set(ExampleUserKey(2), ExampleUserData1(2), *v_ctx[6]))) { + } + v_ctx[6]->on_abort(mock_scn(10)); + return ret; +} + +TEST_F(TestMdsTableFlush, normal_flush) { + MOCK_MAX_CONSEQUENT_CALLBACKED_SCN = mock_scn(125);// 只转储一个node + MdsTableHandle handle; + ASSERT_EQ(OB_SUCCESS, construct_tested_mds_table(handle)); + share::SCN rec_scn; + ASSERT_EQ(OB_SUCCESS, handle.get_rec_scn(rec_scn)); + ASSERT_EQ(mock_scn(50), rec_scn);// 没转储的时候是最小的node的redo scn值 + + // 第一次转储 + ASSERT_EQ(OB_SUCCESS, handle.flush(mock_scn(1000)));// 因为max_decided_scn较小,所以会用125做flush + bool is_flusing = false; + ASSERT_EQ(OB_SUCCESS, handle.is_flushing(is_flusing));// 在flush流程中 + ASSERT_EQ(true, is_flusing); + ASSERT_EQ(mock_scn(125), handle.p_mds_table_base_->flushing_scn_); + int scan_cnt = 0; + ASSERT_EQ(OB_SUCCESS, handle.for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump([&scan_cnt](const MdsDumpKV &kv) -> int { + scan_cnt++; + return OB_SUCCESS; + }, true)); + ASSERT_EQ(1, scan_cnt); + handle.on_flush(MOCK_FLUSHING_SCN, OB_SUCCESS); + ASSERT_EQ(OB_SUCCESS, handle.get_rec_scn(rec_scn)); + OCCAM_LOG(INFO, "print rec scn", K(rec_scn)); + ASSERT_EQ(mock_scn(200), rec_scn); + + // 第二次转储 + MOCK_MAX_CONSEQUENT_CALLBACKED_SCN = mock_scn(140);// 对这个MdsTable没有影响 + ASSERT_EQ(OB_SUCCESS, handle.flush(mock_scn(1000))); + ASSERT_EQ(OB_SUCCESS, handle.is_flushing(is_flusing)); + ASSERT_EQ(false, is_flusing);// 没转储 + ASSERT_EQ(OB_SUCCESS, handle.get_rec_scn(rec_scn)); + OCCAM_LOG(INFO, "print rec scn", K(rec_scn)); + ASSERT_EQ(mock_scn(200), rec_scn);// 没变化 + + // 第三次转储 + MOCK_MAX_CONSEQUENT_CALLBACKED_SCN = mock_scn(275);// 多转一个node + ASSERT_EQ(OB_SUCCESS, handle.flush(mock_scn(1000))); + ASSERT_EQ(OB_SUCCESS, handle.is_flushing(is_flusing));// 在flush流程中 + ASSERT_EQ(true, is_flusing); + ASSERT_EQ(mock_scn(249), handle.p_mds_table_base_->flushing_scn_); + scan_cnt = 0; + ASSERT_EQ(OB_SUCCESS, handle.for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump([&scan_cnt](const MdsDumpKV &kv) -> int { + scan_cnt++; + return OB_SUCCESS; + }, true)); + ASSERT_EQ(1, scan_cnt); + handle.on_flush(MOCK_FLUSHING_SCN, OB_SUCCESS); + ASSERT_EQ(OB_SUCCESS, handle.get_rec_scn(rec_scn)); + OCCAM_LOG(INFO, "print rec scn", K(rec_scn)); + ASSERT_EQ(mock_scn(250), rec_scn); + + // 第四次转储 + MOCK_MAX_CONSEQUENT_CALLBACKED_SCN = mock_scn(550);// 都转下去 + ASSERT_EQ(OB_SUCCESS, handle.flush(mock_scn(1000))); + ASSERT_EQ(OB_SUCCESS, handle.is_flushing(is_flusing));// 在flush流程中 + ASSERT_EQ(true, is_flusing); + ASSERT_EQ(mock_scn(499), handle.p_mds_table_base_->flushing_scn_); + scan_cnt = 0; + ASSERT_EQ(OB_SUCCESS, handle.for_each_unit_from_small_key_to_big_from_old_node_to_new_to_dump([&scan_cnt](const MdsDumpKV &kv) -> int { + scan_cnt++; + return OB_SUCCESS; + }, true)); + ASSERT_EQ(2, scan_cnt); + handle.on_flush(MOCK_FLUSHING_SCN, OB_SUCCESS); + ASSERT_EQ(OB_SUCCESS, handle.get_rec_scn(rec_scn)); + OCCAM_LOG(INFO, "print rec scn", K(rec_scn)); + ASSERT_EQ(mock_scn(500), rec_scn); + + // 第五次转储 + MOCK_MAX_CONSEQUENT_CALLBACKED_SCN = mock_scn(600);// 对这个MdsTable没有影响 + ASSERT_EQ(OB_SUCCESS, handle.flush(mock_scn(1000))); + ASSERT_EQ(OB_SUCCESS, handle.is_flushing(is_flusing)); + ASSERT_EQ(false, is_flusing);// 没转储 + ASSERT_EQ(OB_SUCCESS, handle.get_rec_scn(rec_scn)); + OCCAM_LOG(INFO, "print rec scn", K(rec_scn)); + ASSERT_EQ(mock_scn(500), rec_scn);// 没变化 + + // 第六次转储 + MOCK_MAX_CONSEQUENT_CALLBACKED_SCN = mock_scn(590);// 直接被过滤掉了 + ASSERT_EQ(OB_SUCCESS, handle.flush(mock_scn(1000))); + ASSERT_EQ(OB_SUCCESS, handle.is_flushing(is_flusing)); + ASSERT_EQ(false, is_flusing);// 没转储 + ASSERT_EQ(OB_SUCCESS, handle.get_rec_scn(rec_scn)); + OCCAM_LOG(INFO, "print rec scn", K(rec_scn)); + ASSERT_EQ(mock_scn(500), rec_scn);// 没变化 +} + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_mds_table_flush.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_mds_table_flush.log", false); + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + int64_t alloc_times = oceanbase::storage::mds::MdsAllocator::get_alloc_times(); + int64_t free_times = oceanbase::storage::mds::MdsAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + ret = -1; + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} diff --git a/unittest/storage/multi_data_source/test_mds_table_handle.cpp b/unittest/storage/multi_data_source/test_mds_table_handle.cpp new file mode 100644 index 000000000..3e75285a1 --- /dev/null +++ b/unittest/storage/multi_data_source/test_mds_table_handle.cpp @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2021 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 "multi_data_source/example_user_data_define.h" +#include "share/ob_errno.h" +#include + +#define USING_LOG_PREFIX STORAGE + +#define protected public +#define private public + +#include "lib/guard/ob_light_shared_gaurd.h" +#include "storage/multi_data_source/mds_table_impl.h" +#include "storage/tablet/ob_tablet_meta.h" + +namespace oceanbase +{ +//using namespace share; +namespace storage +{ +namespace mds +{ +void *MdsAllocator::alloc(const int64_t size) +{ + void *ptr = ob_malloc(size, "MDS"); + ATOMIC_INC(&alloc_times_); + MDS_LOG(DEBUG, "alloc obj", KP(ptr), K(lbt())); + return ptr; +} +void MdsAllocator::free(void *ptr) { + ATOMIC_INC(&free_times_); + MDS_LOG(DEBUG, "free obj", KP(ptr), K(lbt())); + ob_free(ptr); +} +} +class TestMdsTableHandle : public ::testing::Test +{ +public: + TestMdsTableHandle() {} + virtual ~TestMdsTableHandle() = default; + virtual void SetUp() override {} + virtual void TearDown() override {} +}; + +TEST_F(TestMdsTableHandle, normal) { + ObLightSharedPtr lsp; + lsp.construct(mds::MdsAllocator::get_instance()); + ObLightSharedPtr lsp2 = lsp; +} + +} // end namespace storage +} // end namespace oceanbase + +int main(int argc, char **argv) +{ + int ret = 0; + system("rm -f test_mds_table_handle.log*"); + OB_LOGGER.set_file_name("test_mds_table_handle.log", true); + OB_LOGGER.set_log_level("INFO"); + signal(49, SIG_IGN); + testing::InitGoogleTest(&argc, argv); + ret = RUN_ALL_TESTS(); + int64_t alloc_times = oceanbase::storage::mds::MdsAllocator::get_alloc_times(); + int64_t free_times = oceanbase::storage::mds::MdsAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + ret = -1; + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} diff --git a/unittest/storage/multi_data_source/test_mds_unit.cpp b/unittest/storage/multi_data_source/test_mds_unit.cpp new file mode 100644 index 000000000..895158e94 --- /dev/null +++ b/unittest/storage/multi_data_source/test_mds_unit.cpp @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2021 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. + */ +#define UNITTEST_DEBUG +#include +#include "lib/ob_errno.h" +#include "lib/utility/utility.h" +#include "share/ob_errno.h" +#include +#include "common_define.h" +#include "lib/allocator/ob_malloc.h" +#include "storage/multi_data_source/mds_node.h" +#include +#include +#include +#include +#include "common/ob_clock_generator.h" +#include "storage/multi_data_source/mds_row.h" +#include "storage/multi_data_source/mds_unit.h" +#include "example_user_helper_define.cpp" +namespace oceanbase { +namespace unittest { + +using namespace common; +using namespace std; +using namespace storage; +using namespace mds; + +class TestMdsUnit: public ::testing::Test +{ +public: + TestMdsUnit() {}; + virtual ~TestMdsUnit() {}; + virtual void SetUp() { + }; + virtual void TearDown() { + }; + static void set_single_row(); + static void get_single_row(); + static MdsUnit signle_row_unit_; +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(TestMdsUnit); +}; + +MdsUnit TestMdsUnit::signle_row_unit_; + +void TestMdsUnit::set_single_row() { + ExampleUserData2 data(1); + MdsCtx ctx(1); + +} + +void TestMdsUnit::get_single_row() { + +} + +TEST_F(TestMdsUnit, set_single_row) { TestMdsUnit::set_single_row(); } +TEST_F(TestMdsUnit, get_single_row) { TestMdsUnit::get_single_row(); } + +} +} + +int main(int argc, char **argv) +{ + system("rm -rf test_mds_unit.log"); + oceanbase::common::ObLogger &logger = oceanbase::common::ObLogger::get_logger(); + logger.set_file_name("test_mds_unit.log", false); + logger.set_log_level(OB_LOG_LEVEL_TRACE); + testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + oceanbase::unittest::TestMdsUnit::signle_row_unit_.~MdsUnit(); + int64_t alloc_times = oceanbase::storage::mds::MdsAllocator::get_alloc_times(); + int64_t free_times = oceanbase::storage::mds::MdsAllocator::get_free_times(); + if (alloc_times != free_times) { + MDS_LOG(ERROR, "memory may leak", K(free_times), K(alloc_times)); + if (ret == 0) { + ret = -1; + } + } else { + MDS_LOG(INFO, "all memory released", K(free_times), K(alloc_times)); + } + return ret; +} \ No newline at end of file diff --git a/unittest/storage/ob_uncommitted_trans_test.h b/unittest/storage/ob_uncommitted_trans_test.h index c96c30f12..fa6f247c2 100644 --- a/unittest/storage/ob_uncommitted_trans_test.h +++ b/unittest/storage/ob_uncommitted_trans_test.h @@ -140,10 +140,12 @@ public: int check_sql_sequence_can_read( const transaction::ObTransID &data_trans_id, const int64_t sql_sequence, + const share::SCN scn, bool &can_read) { int ret = OB_SUCCESS; UNUSED(data_trans_id); + UNUSED(scn); if (ROLLBACK_SQL_SEQUENCE != sql_sequence && ROLLBACK_SQL_SEQUENCE_2 != sql_sequence && ROLLBACK_SQL_SEQUENCE_3 != sql_sequence) { diff --git a/unittest/storage/schema_utils.h b/unittest/storage/schema_utils.h index 825b2caa2..b9ad793ec 100644 --- a/unittest/storage/schema_utils.h +++ b/unittest/storage/schema_utils.h @@ -49,6 +49,7 @@ void TestSchemaUtils::prepare_data_schema(share::schema::ObTableSchema &table_sc table_schema.reset(); ret = table_schema.set_table_name("test_ls_tablet_service_data_table"); ASSERT_EQ(common::OB_SUCCESS, ret); + table_schema.set_schema_version(100); table_schema.set_tenant_id(TEST_TENANT_ID); table_schema.set_tablegroup_id(1); table_schema.set_database_id(1); diff --git a/unittest/storage/slog/simple_ob_storage_redo_module.h b/unittest/storage/slog/simple_ob_storage_redo_module.h index d106099ab..4b9d67e32 100644 --- a/unittest/storage/slog/simple_ob_storage_redo_module.h +++ b/unittest/storage/slog/simple_ob_storage_redo_module.h @@ -20,6 +20,14 @@ #include "lib/random/ob_random.h" #include "lib/allocator/ob_mod_define.h" #include "storage/slog/ob_storage_log_struct.h" +#include "src/storage/meta_mem/ob_tablet_map_key.h" +#include "src/storage/ob_super_block_struct.h" +#include "src/storage/slog/ob_storage_log_reader.h" +#include "src/storage/slog/ob_storage_logger.h" +#include "src/storage/ls/ob_ls_tablet_service.h" +#include "src/storage/tx_storage/ob_ls_handle.h" +#include "src/storage/tx_storage/ob_ls_service.h" +#include "src/storage/tablet/ob_tablet.h" namespace oceanbase { @@ -132,6 +140,16 @@ public: const char *buf, const int64_t len, FILE *stream) override; + int inner_replay_empty_shell_tablet(const ObRedoModuleReplayParam ¶m); + int read_from_disk( + const ObMetaDiskAddr &addr, + common::ObArenaAllocator &allocator, + char *&buf, + int64_t &buf_len); + int read_from_disk_addr(const ObMetaDiskAddr &phy_addr, char *buf, const int64_t buf_len, char *&r_buf, int64_t &r_len); + int read_from_share_blk(const ObMetaDiskAddr &addr, common::ObArenaAllocator &allocator, char *&buf, int64_t &buf_len); + int read_from_slog(const ObMetaDiskAddr &phy_addr, char *buf, const int64_t buf_len, int64_t &pos); + int get_tablet_svr(const share::ObLSID &ls_id, ObLSTabletService *&ls_tablet_svr, ObLSHandle &ls_handle); bool operator ==(SimpleObStorageModule &redo_module); void reset(); @@ -182,6 +200,10 @@ int SimpleObStorageModule::replay(const ObRedoModuleReplayParam ¶m) } } else if (ObRedoLogSubType::OB_REDO_LOG_DELETE_LS == sub_type) { // do nothing + } else if (ObRedoLogSubType::OB_REDO_LOG_EMPTY_SHELL_TABLET == sub_type) { + if (OB_FAIL(inner_replay_empty_shell_tablet(param))) { + STORAGE_REDO_LOG(WARN, "Fail to inner replay empty shell tablet", K(sub_type), K(param)); + } } if (OB_SUCC(ret)) { @@ -192,6 +214,151 @@ int SimpleObStorageModule::replay(const ObRedoModuleReplayParam ¶m) return ret; } +int SimpleObStorageModule::get_tablet_svr( + const ObLSID &ls_id, + ObLSTabletService *&ls_tablet_svr, + ObLSHandle &ls_handle) +{ + int ret = OB_SUCCESS; + ObLS *ls = nullptr; + if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + STORAGE_LOG(WARN, "fail to get ls handle", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls is null", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls_tablet_svr = ls->get_tablet_svr())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "tablet service is null", K(ret), K(ls_id)); + } + return ret; +} + +int SimpleObStorageModule::inner_replay_empty_shell_tablet(const ObRedoModuleReplayParam ¶m) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + ObArenaAllocator allocator; + ObLSTabletService *ls_tablet_svr = nullptr; + ObLSHandle ls_handle; + char *buf = nullptr; + int64_t buf_len = 0; + ObEmptyShellTabletLog slog; + ObTabletTransferInfo tablet_transfer_info; + if (OB_FAIL(slog.deserialize_id(param.buf_, param.disk_addr_.size(), pos))) { + STORAGE_LOG(WARN, "failed to serialize tablet_id_", K(ret), K(param.disk_addr_.size()), K(pos)); + } else if (OB_FAIL(read_from_disk(param.disk_addr_, allocator, buf, buf_len))) { + STORAGE_LOG(WARN, "read from disk failed", K(ret), K(param.disk_addr_), K(buf_len)); + } else if (OB_FAIL(get_tablet_svr(slog.ls_id_, ls_tablet_svr, ls_handle))) { + STORAGE_LOG(WARN, "get tablet svr failed", K(ret), K(slog.ls_id_)); + } else if (OB_FAIL(ls_tablet_svr->replay_create_tablet(param.disk_addr_, buf, buf_len, slog.tablet_id_, tablet_transfer_info))) { + STORAGE_LOG(WARN, "replay empty shell tablet failed", K(ret), K(param.disk_addr_), K(slog.tablet_id_)); + } + + return ret; +} + +int SimpleObStorageModule::read_from_disk( + const ObMetaDiskAddr &addr, + common::ObArenaAllocator &allocator, + char *&buf, + int64_t &buf_len) +{ + int ret = OB_SUCCESS; + char *read_buf = nullptr; + const int64_t read_buf_len = addr.size(); + if (ObMetaDiskAddr::DiskType::FILE == addr.type()) { + ObEmptyShellTabletLog slog; + int64_t pos = 0; + if (OB_ISNULL(buf)) { + if (OB_ISNULL(buf = static_cast(allocator.alloc(addr.size())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + } else { + buf_len = addr.size(); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(read_from_slog(addr, buf, buf_len, pos))) { + STORAGE_LOG(WARN, "fail to read from slog", K(ret), K(addr), KP(buf), K(buf_len), K(pos)); + } else if (OB_FAIL(slog.deserialize_id(buf, buf_len, pos))) { + STORAGE_LOG(WARN, "fail to deserialize id", K(ret), K(addr), KP(buf), K(buf_len), K(pos)); + } else { + buf += pos; + buf_len -= pos; + } + } + } else if (OB_ISNULL(read_buf = static_cast(allocator.alloc(read_buf_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "fail to allocate buffer", K(ret), K(read_buf_len), KP(read_buf)); + } else if (OB_FAIL(read_from_disk_addr(addr, read_buf, read_buf_len, buf, buf_len))) { + STORAGE_LOG(WARN, "fail to read tablet from addr", K(ret), K(addr), KP(read_buf), K(read_buf_len)); + } + return ret; +} + +int SimpleObStorageModule::read_from_disk_addr(const ObMetaDiskAddr &addr, + char *buf, const int64_t buf_len, char *&r_buf, int64_t &r_len) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!addr.is_valid() || buf_len < addr.size()) || OB_ISNULL(buf)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(addr), KP(buf), K(buf_len)); + } else { + switch (addr.type()) { + case ObMetaDiskAddr::DiskType::FILE: { + int64_t pos = 0; + if (OB_FAIL(read_from_slog(addr, buf, buf_len, pos))) { + STORAGE_LOG(WARN, "fail to read from slog", K(ret), K(addr), KP(buf), K(buf_len)); + } else { + r_buf = buf + pos; + r_len = addr.size() - pos; + } + break; + } + default: { + ret = OB_NOT_SUPPORTED; + STORAGE_LOG(WARN, "unknown meta disk address type", K(ret), K(addr), KP(buf), K(buf_len)); + break; + } + } + } + return ret; +} + +int SimpleObStorageModule::read_from_slog(const ObMetaDiskAddr &addr, + char *buf, const int64_t buf_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + ObStorageLogger *logger = MTL(ObStorageLogger*); + + if (OB_UNLIKELY(!addr.is_valid() + || !addr.is_file() + || buf_len < addr.size()) + || OB_ISNULL(buf) + || OB_ISNULL(logger)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(addr), KP(buf), K(buf_len), KP(logger)); + } else { + // The reason for retrying, here, is that the current SLOG didn't handle the read and write + // concurrency for the latest item, and an -4103 error will be returned. At present, the + // optimized changes for SLOG are relatively large, and we will bypass it in the short term. + int64_t retry_count = 2; + do { + int64_t tmp_pos = pos; + if (OB_FAIL(ObStorageLogReader::read_log(logger->get_dir(), addr, buf_len, buf, tmp_pos, MTL_ID()))) { + STORAGE_LOG(WARN, "fail to read slog", K(ret), "logger directory", logger->get_dir(), K(addr), + K(buf_len), KP(buf)); + if (retry_count > 1) { + sleep(1); // sleep 1s + } + } else { + pos = tmp_pos; + } + } while (OB_FAIL(ret) && --retry_count > 0); + } + return ret; +} + bool SimpleObStorageModule::operator ==(SimpleObStorageModule &redo_module) { bool ret = true; diff --git a/unittest/storage/slog/test_storage_logger_manager.cpp b/unittest/storage/slog/test_storage_logger_manager.cpp index 8cc6b5986..9aea7e43f 100644 --- a/unittest/storage/slog/test_storage_logger_manager.cpp +++ b/unittest/storage/slog/test_storage_logger_manager.cpp @@ -135,7 +135,6 @@ TEST_F(TestStorageLoggerManager, test_slogger_basic) SLOGGERMGR.init(dir_, MAX_FILE_SIZE, log_file_spec_); ObStorageLogger *tmp_slogger = OB_NEW(ObStorageLogger, ObModIds::TEST); - ASSERT_EQ(0, tmp_slogger->get_pwrite_ts()); ASSERT_EQ(OB_SUCCESS, tmp_slogger->init(SLOGGERMGR, 500)); ASSERT_EQ(OB_SUCCESS, tmp_slogger->start()); @@ -149,7 +148,6 @@ TEST_F(TestStorageLoggerManager, test_slogger_basic) guard.switch_to(5); ObStorageLogger *slogger = MTL(ObStorageLogger*); slogger->start_log(cursor); - ASSERT_EQ(0, slogger->get_pwrite_ts()); // test get_active_cursor ObLogCursor tmp_cursor; diff --git a/unittest/storage/slog_ckpt/test_linked_macro_block.cpp b/unittest/storage/slog_ckpt/test_linked_macro_block.cpp index 8fb9ee9ce..5db5d1967 100644 --- a/unittest/storage/slog_ckpt/test_linked_macro_block.cpp +++ b/unittest/storage/slog_ckpt/test_linked_macro_block.cpp @@ -130,7 +130,7 @@ void TestLinkedMacroBlock::write_items(ObArray &item_arr) ObIArray &block_list = item_writer.get_meta_block_list(); - block_handle_.add_macro_blocks(block_list, true); + block_handle_.add_macro_blocks(block_list); ASSERT_EQ(OB_SUCCESS, item_writer.get_entry_block(entry_block_)); } diff --git a/unittest/storage/tablet/test_tablet.cpp b/unittest/storage/tablet/test_tablet.cpp new file mode 100644 index 000000000..a00a419f8 --- /dev/null +++ b/unittest/storage/tablet/test_tablet.cpp @@ -0,0 +1,526 @@ + +/** + * Copyright (c) 2021 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 +#define protected public +#define private public + +#define USING_LOG_PREFIX STORAGE + +#include "share/scn.h" +#include "share/ob_tablet_autoincrement_param.h" +#include "storage/ob_storage_struct.h" +#include "storage/tablet/ob_tablet_meta.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_multi_source_data.h" +#include "storage/high_availability/ob_tablet_ha_status.h" +#include "storage/tablet/ob_tablet_binding_helper.h" +#include "storage/tablet/ob_tablet_table_store_flag.h" + +namespace oceanbase +{ +namespace unittest +{ + +using namespace storage; +using namespace common; +using namespace share; + +class ObTabletMetaV1 final +{ +public: + int64_t get_serialize_size() const; + int serialize(char *buf, const int64_t len, int64_t &pos) const; + +public: + static const int32_t TABLET_META_VERSION_V1 = 1; + + int32_t version_; + int32_t length_; + share::ObLSID ls_id_; + common::ObTabletID tablet_id_; + common::ObTabletID data_tablet_id_; + common::ObTabletID ref_tablet_id_; + bool has_next_tablet_; + share::SCN create_scn_; + share::SCN start_scn_; + share::SCN clog_checkpoint_scn_; + share::SCN ddl_checkpoint_scn_; + int64_t snapshot_version_; + int64_t multi_version_start_; + lib::Worker::CompatMode compat_mode_; + share::ObTabletAutoincSeq autoinc_seq_; + ObTabletHAStatus ha_status_; + ObTabletReportStatus report_status_; + ObTabletTxMultiSourceDataUnit tx_data_; + ObTabletBindingInfo ddl_data_; + ObTabletTableStoreFlag table_store_flag_; + share::SCN ddl_start_scn_; + int64_t ddl_snapshot_version_; + int64_t max_sync_storage_schema_version_; + int64_t ddl_execution_id_; + int64_t ddl_cluster_version_; + int64_t max_serialized_medium_scn_; + // keep member same to 4.1 !!! +}; + +int ObTabletMetaV1::serialize(char *buf, const int64_t len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + const int64_t length = get_serialize_size(); + + if (OB_UNLIKELY(length > len - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer's length is not enough", K(ret), K(length), K(len - new_pos)); + } else if (OB_FAIL(serialization::encode_i32(buf, len, new_pos, version_))) { + LOG_WARN("failed to serialize tablet meta's version", K(ret), K(len), K(new_pos), K_(version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i32(buf, len, new_pos, length))) { + LOG_WARN("failed to serialize tablet meta's length", K(ret), K(len), K(new_pos), K(length)); + } else if (new_pos - pos < length && OB_FAIL(ls_id_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ls id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(tablet_id_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize tablet id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(data_tablet_id_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize data tablet id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ref_tablet_id_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ref tablet id", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_bool(buf, len, new_pos, has_next_tablet_))) { + LOG_WARN("failed to serialize has next tablet", K(ret), K(len), K(new_pos), K_(has_next_tablet)); + } else if (new_pos - pos < length && OB_FAIL(create_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize create scn", K(ret), K(len), K(new_pos), K_(create_scn)); + } else if (new_pos - pos < length && OB_FAIL(start_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize start scn", K(ret), K(len), K(new_pos), K_(start_scn)); + } else if (new_pos - pos < length && OB_FAIL(clog_checkpoint_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize clog checkpoint ts", K(ret), K(len), K(new_pos), K_(clog_checkpoint_scn)); + } else if (new_pos - pos < length && OB_FAIL(ddl_checkpoint_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ddl checkpoint ts", K(ret), K(len), K(new_pos), K_(ddl_checkpoint_scn)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, snapshot_version_))) { + LOG_WARN("failed to serialize snapshot version", K(ret), K(len), K(new_pos), K_(snapshot_version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, multi_version_start_))) { + LOG_WARN("failed to serialize multi version start", K(ret), K(len), K(new_pos), K_(multi_version_start)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i8(buf, len, new_pos, static_cast(compat_mode_)))) { + LOG_WARN("failed to serialize compat mode", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(autoinc_seq_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize auto inc seq", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ha_status_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ha status", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(report_status_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize report status", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(tx_data_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize multi source data", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ddl_data_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ddl data", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(table_store_flag_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize table store flag", K(ret), K(len), K(new_pos)); + } else if (new_pos - pos < length && OB_FAIL(ddl_start_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ddl start log ts", K(ret), K(len), K(new_pos), K_(ddl_start_scn)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_snapshot_version_))) { + LOG_WARN("failed to serialize ddl snapshot version", K(ret), K(len), K(new_pos), K_(ddl_snapshot_version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, max_sync_storage_schema_version_))) { + LOG_WARN("failed to serialize max_sync_storage_schema_version", K(ret), K(len), K(new_pos), K_(max_sync_storage_schema_version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_execution_id_))) { + LOG_WARN("failed to serialize ddl execution id", K(ret), K(len), K(new_pos), K_(ddl_execution_id)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_cluster_version_))) { + LOG_WARN("failed to serialize ddl cluster version", K(ret), K(len), K(new_pos), K_(ddl_cluster_version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, max_serialized_medium_scn_))) { + LOG_WARN("failed to serialize max_serialized_medium_scn", K(ret), K(len), K(new_pos), K_(max_serialized_medium_scn)); + } else if (OB_UNLIKELY(length != new_pos - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet meta's length doesn't match standard length", K(ret), K(new_pos), K(pos), K(length)); + } else { + pos = new_pos; + } + + return ret; +} + +int64_t ObTabletMetaV1::get_serialize_size() const +{ + int64_t size = 0; + size += serialization::encoded_length_i32(version_); + size += serialization::encoded_length_i32(length_); + size += ls_id_.get_serialize_size(); + size += tablet_id_.get_serialize_size(); + size += data_tablet_id_.get_serialize_size(); + size += ref_tablet_id_.get_serialize_size(); + size += serialization::encoded_length_bool(has_next_tablet_); + size += create_scn_.get_fixed_serialize_size(); + size += start_scn_.get_fixed_serialize_size(); + size += clog_checkpoint_scn_.get_fixed_serialize_size(); + size += ddl_checkpoint_scn_.get_fixed_serialize_size(); + size += serialization::encoded_length_i64(snapshot_version_); + size += serialization::encoded_length_i64(multi_version_start_); + size += serialization::encoded_length_i8(static_cast(compat_mode_)); + size += autoinc_seq_.get_serialize_size(); + size += ha_status_.get_serialize_size(); + size += report_status_.get_serialize_size(); + size += tx_data_.get_serialize_size(); + size += ddl_data_.get_serialize_size(); + size += table_store_flag_.get_serialize_size(); + size += ddl_start_scn_.get_fixed_serialize_size(); + size += serialization::encoded_length_i64(ddl_snapshot_version_); + size += serialization::encoded_length_i64(max_sync_storage_schema_version_); + size += serialization::encoded_length_i64(ddl_execution_id_); + size += serialization::encoded_length_i64(ddl_cluster_version_); + size += serialization::encoded_length_i64(max_serialized_medium_scn_); + return size; +} + +struct ObMigrationTabletParamV1 final +{ +public: + int serialize(char *buf, const int64_t len, int64_t &pos) const; + int deserialize(const char *buf, const int64_t len, int64_t &pos); + int64_t get_serialize_size() const; + + // magic_number_ is added to support upgrade from old format(without version and length compatibility) + // The old format first member is ls_id_(also 8 bytes long), which is not possible be a negative number. + const static int64_t MAGIC_NUM = -20230111; + const static int64_t PARAM_VERSION = 1; + + TO_STRING_KV(K_(magic_number), + K_(version), + K_(ls_id), + K_(tablet_id), + K_(data_tablet_id), + K_(ref_tablet_id), + K_(create_scn), + K_(start_scn), + K_(clog_checkpoint_scn), + K_(ddl_checkpoint_scn), + K_(ddl_snapshot_version), + K_(ddl_start_scn), + K_(snapshot_version), + K_(multi_version_start), + K_(autoinc_seq), + K_(compat_mode), + K_(ha_status), + K_(report_status), + K_(tx_data), + K_(ddl_data), + K_(storage_schema), + K_(medium_info_list), + K_(table_store_flag), + K_(max_sync_storage_schema_version), + K_(max_serialized_medium_scn), + K_(ddl_commit_scn)); + +public: + int64_t magic_number_; + int64_t version_; + share::ObLSID ls_id_; + common::ObTabletID tablet_id_; + common::ObTabletID data_tablet_id_; + common::ObTabletID ref_tablet_id_; + share::SCN create_scn_; + share::SCN start_scn_; // for migration + share::SCN clog_checkpoint_scn_; + share::SCN ddl_checkpoint_scn_; + int64_t snapshot_version_; + int64_t multi_version_start_; + lib::Worker::CompatMode compat_mode_; + share::ObTabletAutoincSeq autoinc_seq_; + ObTabletHAStatus ha_status_; + ObTabletReportStatus report_status_; + ObTabletTxMultiSourceDataUnit tx_data_; + ObTabletBindingInfo ddl_data_; + ObStorageSchema storage_schema_; + compaction::ObMediumCompactionInfoList medium_info_list_; + ObTabletTableStoreFlag table_store_flag_; + share::SCN ddl_start_scn_; + int64_t ddl_snapshot_version_; + // max_sync_version may less than storage_schema.schema_version_ when major update schema + int64_t max_sync_storage_schema_version_; + int64_t ddl_execution_id_; + int64_t ddl_data_format_version_; + int64_t max_serialized_medium_scn_; + share::SCN ddl_commit_scn_; + + // Add new serialization member before this line, below members won't serialize + common::ObArenaAllocator allocator_; // for storage schema +}; + +int ObMigrationTabletParamV1::serialize(char *buf, const int64_t len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + int64_t new_pos = pos; + int64_t length = 0; + + if (OB_ISNULL(buf) + || OB_UNLIKELY(len <= 0) + || OB_UNLIKELY(pos < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(buf), K(len), K(pos)); + } else if (FALSE_IT(length = get_serialize_size())) { + } else if (OB_UNLIKELY(length > len - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer's length is not enough", K(ret), K(length), K(len - new_pos)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, magic_number_))) { + LOG_WARN("failed to serialize magic number", K(ret), K(len), K(new_pos), K_(magic_number)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, version_))) { + LOG_WARN("failed to serialize version", K(ret), K(len), K(new_pos), K_(version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, length))) { + LOG_WARN("failed to serialize length", K(ret), K(len), K(new_pos), K(length)); + } else if (new_pos - pos < length && OB_FAIL(ls_id_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ls id", K(ret), K(len), K(new_pos), K_(ls_id)); + } else if (new_pos - pos < length && OB_FAIL(tablet_id_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize tablet id", K(ret), K(len), K(new_pos), K_(tablet_id)); + } else if (new_pos - pos < length && OB_FAIL(data_tablet_id_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize data tablet id", K(ret), K(len), K(new_pos), K_(data_tablet_id)); + } else if (new_pos - pos < length && OB_FAIL(ref_tablet_id_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ref tablet id", K(ret), K(len), K(new_pos), K_(ref_tablet_id)); + } else if (new_pos - pos < length && OB_FAIL(create_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize clog checkpoint ts", K(ret), K(len), K(new_pos), K_(create_scn)); + } else if (new_pos - pos < length && OB_FAIL(start_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize start scn", K(ret), K(len), K(new_pos), K_(start_scn)); + } else if (new_pos - pos < length && OB_FAIL(clog_checkpoint_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize clog checkpoint ts", K(ret), K(len), K(new_pos), K_(clog_checkpoint_scn)); + } else if (new_pos - pos < length && OB_FAIL(ddl_checkpoint_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ddl checkpoint ts", K(ret), K(len), K(new_pos), K_(ddl_checkpoint_scn)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, snapshot_version_))) { + LOG_WARN("failed to serialize clog checkpoint ts", K(ret), K(len), K(new_pos), K_(snapshot_version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, multi_version_start_))) { + LOG_WARN("failed to serialize clog checkpoint ts", K(ret), K(len), K(new_pos), K_(multi_version_start)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i8(buf, len, new_pos, static_cast(compat_mode_)))) { + LOG_WARN("failed to serialize compat mode", K(ret), K(len), K(new_pos), K_(compat_mode)); + } else if (new_pos - pos < length && OB_FAIL(autoinc_seq_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize auto inc seq", K(ret), K(len), K(new_pos), K_(autoinc_seq)); + } else if (new_pos - pos < length && OB_FAIL(ha_status_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ha status", K(ret), K(len), K(new_pos), K_(ha_status)); + } else if (new_pos - pos < length && OB_FAIL(report_status_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize report status", K(ret), K(len), K(new_pos), K_(report_status)); + } else if (new_pos - pos < length && OB_FAIL(tx_data_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize multi source data", K(ret), K(len), K(new_pos), K_(tx_data)); + } else if (new_pos - pos < length && OB_FAIL(ddl_data_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ddl data", K(ret), K(len), K(new_pos), K_(ddl_data)); + } else if (new_pos - pos < length && OB_FAIL(storage_schema_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize storage schema", K(ret), K(len), K(new_pos), K_(storage_schema)); + } else if (new_pos - pos < length && OB_FAIL(medium_info_list_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize medium compaction list", K(ret), K(len), K(new_pos), K_(medium_info_list)); + } else if (new_pos - pos < length && OB_FAIL(table_store_flag_.serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize table store flag", K(ret), K(len), K(new_pos), K_(table_store_flag)); + } else if (new_pos - pos < length && OB_FAIL(ddl_start_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ddl start log ts", K(ret), K(len), K(new_pos), K_(ddl_start_scn)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_snapshot_version_))) { + LOG_WARN("failed to serialize ddl snapshot version", K(ret), K(len), K(new_pos), K_(ddl_snapshot_version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, max_sync_storage_schema_version_))) { + LOG_WARN("failed to serialize max_sync_storage_schema_version", K(ret), K(len), K(new_pos), K_(max_sync_storage_schema_version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_execution_id_))) { + LOG_WARN("failed to serialize ddl execution id", K(ret), K(len), K(new_pos), K_(ddl_execution_id)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, ddl_data_format_version_))) { + LOG_WARN("failed to serialize ddl data format version", K(ret), K(len), K(new_pos), K_(ddl_data_format_version)); + } else if (new_pos - pos < length && OB_FAIL(serialization::encode_i64(buf, len, new_pos, max_serialized_medium_scn_))) { + LOG_WARN("failed to serialize max_serialized_medium_scn", K(ret), K(len), K(new_pos), K_(max_serialized_medium_scn)); + } else if (new_pos - pos < length && OB_FAIL(ddl_commit_scn_.fixed_serialize(buf, len, new_pos))) { + LOG_WARN("failed to serialize ddl commit scn", K(ret), K(len), K(new_pos), K_(ddl_commit_scn)); + } else if (OB_UNLIKELY(length != new_pos - pos)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("length doesn't match standard length", K(ret), K(new_pos), K(pos), K(length)); + } else { + pos = new_pos; + } + + return ret; +} + +int64_t ObMigrationTabletParamV1::get_serialize_size() const +{ + int64_t size = 0; + int64_t length = 0; + size += serialization::encoded_length_i64(magic_number_); + size += serialization::encoded_length_i64(version_); + size += serialization::encoded_length_i64(length); + size += ls_id_.get_serialize_size(); + size += tablet_id_.get_serialize_size(); + size += data_tablet_id_.get_serialize_size(); + size += ref_tablet_id_.get_serialize_size(); + size += create_scn_.get_fixed_serialize_size(); + size += start_scn_.get_fixed_serialize_size(); + size += clog_checkpoint_scn_.get_fixed_serialize_size(); + size += ddl_checkpoint_scn_.get_fixed_serialize_size(); + size += serialization::encoded_length_i64(snapshot_version_); + size += serialization::encoded_length_i64(multi_version_start_); + size += serialization::encoded_length_i8(static_cast(compat_mode_)); + size += autoinc_seq_.get_serialize_size(); + size += ha_status_.get_serialize_size(); + size += report_status_.get_serialize_size(); + size += tx_data_.get_serialize_size(); + size += ddl_data_.get_serialize_size(); + size += storage_schema_.get_serialize_size(); + size += medium_info_list_.get_serialize_size(); + size += table_store_flag_.get_serialize_size(); + size += ddl_start_scn_.get_fixed_serialize_size(); + size += serialization::encoded_length_i64(ddl_snapshot_version_); + size += serialization::encoded_length_i64(max_sync_storage_schema_version_); + size += serialization::encoded_length_i64(ddl_execution_id_); + size += serialization::encoded_length_i64(ddl_data_format_version_); + size += serialization::encoded_length_i64(max_serialized_medium_scn_); + size += ddl_commit_scn_.get_fixed_serialize_size(); + return size; +} + +class TestTablet : public ::testing::Test +{ +public: + TestTablet(); + virtual ~TestTablet(); + virtual void SetUp(); + virtual void TearDown(); +private: + ObArenaAllocator allocator_; +}; + +TestTablet::TestTablet() +{ +} + +TestTablet::~TestTablet() +{ +} + +void TestTablet::SetUp() +{ +} + +void TestTablet::TearDown() +{ +} + +TEST_F(TestTablet, test_serialize_meta_compat) +{ + int ret = OB_SUCCESS; + ObTabletMetaV1 tablet_meta; + tablet_meta.version_ = ObTabletMetaV1::TABLET_META_VERSION_V1; + tablet_meta.ls_id_ = ObLSID(3); + tablet_meta.tablet_id_ = ObTabletID(1); + tablet_meta.data_tablet_id_ = ObTabletID(4); + tablet_meta.ref_tablet_id_ = ObTabletID(1); + bool has_next_tablet_ = true; + tablet_meta.create_scn_ = share::SCN::base_scn(); + tablet_meta.start_scn_ = share::SCN::base_scn(); + tablet_meta.clog_checkpoint_scn_ = share::SCN::base_scn(); + tablet_meta.ddl_checkpoint_scn_ = share::SCN::base_scn(); + tablet_meta.snapshot_version_ = 5; + tablet_meta.multi_version_start_ = 9; + tablet_meta.compat_mode_ = lib::Worker::CompatMode::MYSQL; + tablet_meta.autoinc_seq_.set_autoinc_seq_value(allocator_, 1); + ASSERT_EQ(OB_SUCCESS, tablet_meta.ha_status_.init_status()); + tablet_meta.ddl_start_scn_ = share::SCN::base_scn(); + tablet_meta.ddl_snapshot_version_ = 3; + tablet_meta.max_sync_storage_schema_version_ = 1; + tablet_meta.ddl_execution_id_ = 4; + tablet_meta.ddl_cluster_version_ = 1; + tablet_meta.max_serialized_medium_scn_ = 5; + tablet_meta.length_ = tablet_meta.get_serialize_size(); + tablet_meta.tx_data_.tablet_status_ = ObTabletStatus::NORMAL; + + char *buf = nullptr; + int64_t len = tablet_meta.get_serialize_size(); + buf = reinterpret_cast(allocator_.alloc(len)); + int64_t pos = 0; + ASSERT_EQ(OB_SUCCESS, tablet_meta.serialize(buf, len, pos)); + + pos = 0; + ObTablet tablet; + ObTabletAutoincSeq autoinc_seq; + ObTabletTxMultiSourceDataUnit tx_data; + ObTabletBindingInfo ddl_data; + ASSERT_EQ(OB_SUCCESS, + tablet.deserialize_meta_v1(allocator_, buf, len, pos, autoinc_seq, tx_data, ddl_data)); + uint64_t autoinc_seq_v1; + ASSERT_EQ(OB_SUCCESS, tablet_meta.autoinc_seq_.get_autoinc_seq_value(autoinc_seq_v1)); + uint64_t autoinc_seq_v2; + ASSERT_EQ(OB_SUCCESS, autoinc_seq.get_autoinc_seq_value(autoinc_seq_v2)); + ASSERT_EQ(autoinc_seq_v1, autoinc_seq_v2); + ASSERT_EQ(tx_data.tablet_status_, ObTabletStatus::NORMAL); +} + +TEST_F(TestTablet, test_serialize_mig_param_compat) +{ + int ret = OB_SUCCESS; + ObMigrationTabletParamV1 mig_param; + mig_param.magic_number_ = ObMigrationTabletParamV1::MAGIC_NUM; + mig_param.version_ = ObMigrationTabletParamV1::PARAM_VERSION; + mig_param.ls_id_ = ObLSID(3); + mig_param.tablet_id_ = ObTabletID(1); + mig_param.data_tablet_id_ = ObTabletID(4); + mig_param.ref_tablet_id_ = ObTabletID(1); + mig_param.create_scn_ = share::SCN::base_scn(); + mig_param.start_scn_ = share::SCN::base_scn(); + mig_param.clog_checkpoint_scn_ = share::SCN::base_scn(); + mig_param.ddl_checkpoint_scn_ = share::SCN::base_scn(); + mig_param.snapshot_version_ = 9; + mig_param.multi_version_start_ = 5; + mig_param.compat_mode_ = lib::Worker::CompatMode::MYSQL; + mig_param.autoinc_seq_.set_autoinc_seq_value(allocator_, 1); + ASSERT_EQ(OB_SUCCESS, mig_param.ha_status_.init_status()); + mig_param.tx_data_.tablet_status_ = ObTabletStatus::NORMAL; + mig_param.ddl_start_scn_ = share::SCN::base_scn(); + mig_param.ddl_snapshot_version_ = 3; + mig_param.max_sync_storage_schema_version_ = 1; + mig_param.ddl_execution_id_ = 4; + mig_param.ddl_data_format_version_ = 6; + mig_param.max_serialized_medium_scn_ = 5; + mig_param.ddl_commit_scn_ = share::SCN::base_scn(); + mig_param.storage_schema_.storage_schema_version_ = ObStorageSchema::STORAGE_SCHEMA_VERSION_V2; + mig_param.storage_schema_.schema_version_ = 1; + mig_param.storage_schema_.column_cnt_ = 1; + mig_param.storage_schema_.table_type_ = SYSTEM_TABLE; + const ObStorageColumnSchema column_schema; + mig_param.storage_schema_.column_array_.set_allocator(&mig_param.allocator_); + ASSERT_EQ(OB_SUCCESS, mig_param.storage_schema_.column_array_.reserve(mig_param.storage_schema_.column_cnt_)); + ASSERT_EQ(OB_SUCCESS, mig_param.storage_schema_.column_array_.push_back(column_schema)); + ASSERT_EQ(mig_param.storage_schema_.column_array_.count(), 1); + mig_param.storage_schema_.is_inited_ = true; + + int8_t head_val = 3; + int8_t tail_val = 4; + char *buf = nullptr; + int64_t len = serialization::encoded_length_i8(head_val) + mig_param.get_serialize_size() + serialization::encoded_length_i8(tail_val); + buf = reinterpret_cast(allocator_.alloc(len)); + int64_t pos = 0; + serialization::encode_i8(buf, len, pos, head_val); + ASSERT_EQ(OB_SUCCESS, mig_param.serialize(buf, len, pos)); + serialization::encode_i8(buf, len, pos, tail_val); + + ObMigrationTabletParam new_mig_param; + pos = 0; + serialization::decode_i8(buf, len, pos, &head_val); + ASSERT_EQ(head_val, 3); + ret = new_mig_param.deserialize(buf, len, pos); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(new_mig_param.storage_schema_.column_array_.count(), 1); + ASSERT_TRUE(new_mig_param.is_valid()); + serialization::decode_i8(buf, len, pos, &tail_val); + ASSERT_EQ(tail_val, 4); + ObTabletCreateDeleteMdsUserData user_data; + mds::MdsDumpNode *v = &new_mig_param.mds_data_.tablet_status_committed_kv_.v_; + pos = 0; + ret = user_data.deserialize(v->user_data_.ptr(), v->user_data_.length(), pos); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(user_data.tablet_status_, ObTabletStatus::NORMAL); + +} + +} // end namespace unittest +} // end namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -f test_tablet.log*"); + oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); + OB_LOGGER.set_file_name("test_tablet.log", true, true); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/unittest/storage/test_compaction_policy.cpp b/unittest/storage/test_compaction_policy.cpp index 74b211e29..7636d9ddf 100644 --- a/unittest/storage/test_compaction_policy.cpp +++ b/unittest/storage/test_compaction_policy.cpp @@ -10,6 +10,7 @@ * See the Mulan PubL v2 for more details. */ +#define UNITTEST_DEBUG #define USING_LOG_PREFIX STORAGE #include #include @@ -44,7 +45,24 @@ using namespace memtable; using namespace share::schema; using namespace share; using namespace compaction; - +namespace storage +{ +namespace mds +{ +void *MdsAllocator::alloc(const int64_t size) +{ + void *ptr = ob_malloc(size, "MDS"); + ATOMIC_INC(&alloc_times_); + MDS_LOG(DEBUG, "alloc obj", KP(ptr), K(lbt())); + return ptr; +} +void MdsAllocator::free(void *ptr) { + ATOMIC_INC(&free_times_); + MDS_LOG(DEBUG, "free obj", KP(ptr), K(lbt())); + ob_free(ptr); +} +} +} namespace memtable { @@ -67,6 +85,7 @@ public: const int64_t end_scn, ObITable::TableKey &table_key); static int mock_sstable( + common::ObArenaAllocator &allocator, const ObITable::TableType &type, const int64_t start_scn, const int64_t end_scn, @@ -80,14 +99,17 @@ public: ObTablet &tablet, ObTableHandleV2 &table_handle); static int mock_tablet( + common::ObArenaAllocator &allocator, const int64_t clog_checkpoint_ts, const int64_t snapshot_version, ObTabletHandle &tablet_handle); static int mock_table_store( + common::ObArenaAllocator &allocator, ObTabletHandle &tablet_handle, common::ObIArray &major_tables, common::ObIArray &minor_tables); static int batch_mock_sstables( + common::ObArenaAllocator &allocator, const char *key_data, common::ObIArray &major_tables, common::ObIArray &minor_tables); @@ -96,6 +118,7 @@ public: ObTabletHandle &tablet_handle, common::ObIArray &memtables); static int batch_mock_tables( + common::ObArenaAllocator &allocator, const char *key_data, common::ObIArray &major_tables, common::ObIArray &minor_tables, @@ -140,7 +163,7 @@ public: ObSEArray memtables_; ObMediumCompactionInfo medium_info_; ObSEArray array_; - ObArenaAllocator allocator_; + common::ObArenaAllocator allocator_; }; TestCompactionPolicy::TestCompactionPolicy() @@ -156,6 +179,7 @@ TestCompactionPolicy::TestCompactionPolicy() void TestCompactionPolicy::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); int ret = OB_SUCCESS; ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); t3m->stop(); @@ -254,6 +278,7 @@ void TestCompactionPolicy::generate_table_key( } int TestCompactionPolicy::mock_sstable( + common::ObArenaAllocator &allocator, const ObITable::TableType &type, const int64_t start_scn, const int64_t end_scn, @@ -279,15 +304,26 @@ int TestCompactionPolicy::mock_sstable( param.max_merged_trans_version_ = max_merged_trans_version; } + void *buf = nullptr; ObSSTable *sstable = nullptr; if (OB_FAIL(ret)) { - } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, table_handle))) { - LOG_WARN("failed to create sstable", K(param)); - } else if (OB_FAIL(table_handle.get_sstable(sstable))) { - LOG_WARN("failed to get sstable", K(ret), K(table_handle)); + } else if (OB_ISNULL(buf = allocator.alloc(sizeof(ObSSTable)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate sstable memory", K(ret)); + } else if (OB_ISNULL(sstable = new (buf)ObSSTable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get table", K(ret)); + } else if (OB_FAIL(sstable->init(param, &allocator))) { + LOG_WARN("fail to init sstable", K(ret), K(param)); + } else if (OB_FAIL(table_handle.set_sstable(sstable, &allocator))) { + LOG_WARN("failed to set table handle", K(ret), KPC(sstable)); } else { - sstable->meta_.basic_meta_.max_merged_trans_version_ = max_merged_trans_version; - sstable->meta_.basic_meta_.upper_trans_version_ = upper_trans_version; + sstable->meta_->basic_meta_.max_merged_trans_version_ = max_merged_trans_version; + sstable->meta_->basic_meta_.upper_trans_version_ = upper_trans_version; + sstable->max_merged_trans_version_ = max_merged_trans_version; + sstable->upper_trans_version_ = upper_trans_version; + sstable->nested_size_ = 0; + sstable->nested_offset_ = 0; } return ret; } @@ -349,6 +385,7 @@ int TestCompactionPolicy::mock_memtable( } int TestCompactionPolicy::mock_tablet( + common::ObArenaAllocator &allocator, const int64_t clog_checkpoint_ts, const int64_t snapshot_version, ObTabletHandle &tablet_handle) @@ -365,7 +402,6 @@ int TestCompactionPolicy::mock_tablet( const ObTabletMapKey key(ls_id, tablet_id); ObTablet *tablet = nullptr; - ObTableHandleV2 table_handle; ObLSHandle ls_handle; ObLSService *ls_svr = nullptr; @@ -381,11 +417,11 @@ int TestCompactionPolicy::mock_tablet( ret = OB_ERR_UNEXPECTED; } else if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { LOG_WARN("failed to get ls handle", K(ret)); - } else if (OB_FAIL(ObTabletCreateDeleteHelper::acquire_tablet(key, tablet_handle))) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_tmp_tablet(key, allocator, tablet_handle))) { LOG_WARN("failed to acquire tablet", K(ret), K(key)); } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { - } else if (OB_FAIL(tablet->init(ls_id, tablet_id, tablet_id, empty_tablet_id, empty_tablet_id, - SCN::min_scn(), snapshot_version, table_schema, compat_mode, table_store_flag, table_handle, ls_handle.get_ls()->get_freezer()))) { + } else if (OB_FAIL(tablet->init(allocator, ls_id, tablet_id, tablet_id, empty_tablet_id, empty_tablet_id, + SCN::min_scn(), snapshot_version, table_schema, compat_mode, table_store_flag, nullptr, ls_handle.get_ls()->get_freezer()))) { LOG_WARN("failed to init tablet", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(table_schema), K(compat_mode)); } else { @@ -426,10 +462,10 @@ int TestCompactionPolicy::prepare_medium_list( int ret = OB_SUCCESS; ObTablet &tablet = *tablet_handle.get_obj(); construct_array(snapshot_list, array_); - tablet.medium_info_list_.reset_list(); + tablet.medium_info_list_addr_.get_ptr()->reset_list(); for (int i = 0; OB_SUCC(ret) && i < array_.count(); ++i) { medium_info_.medium_snapshot_ = array_.at(i); - ret = tablet.medium_info_list_.add_medium_compaction_info(medium_info_); + ret = tablet.medium_info_list_addr_.get_ptr()->add_medium_compaction_info(medium_info_); } return ret; } @@ -454,6 +490,7 @@ int TestCompactionPolicy::check_result_tables_handle( } int TestCompactionPolicy::mock_table_store( + common::ObArenaAllocator &allocator, ObTabletHandle &tablet_handle, common::ObIArray &major_table_handles, common::ObIArray &minor_table_handles) @@ -473,16 +510,16 @@ int TestCompactionPolicy::mock_table_store( } } - ObTablet &tablet = *tablet_handle.get_obj(); - ObTabletTableStore &table_store = tablet.table_store_; + ObTablet *tablet = tablet_handle.get_obj(); + ObTabletTableStore &table_store = *tablet->table_store_addr_.get_ptr(); if (OB_SUCC(ret) && major_tables.count() > 0) { - if (OB_FAIL(table_store.major_tables_.init_and_copy(*tablet.allocator_, major_tables))) { + if (OB_FAIL(table_store.major_tables_.init(allocator, major_tables))) { LOG_WARN("failed to init major tables", K(ret)); } } if (OB_SUCC(ret) && minor_tables.count() > 0) { - if (OB_FAIL(table_store.minor_tables_.init_and_copy(*tablet.allocator_, minor_tables))) { + if (OB_FAIL(table_store.minor_tables_.init(allocator, minor_tables))) { LOG_WARN("failed to init major tables", K(ret)); } } @@ -490,6 +527,7 @@ int TestCompactionPolicy::mock_table_store( } int TestCompactionPolicy::batch_mock_sstables( + common::ObArenaAllocator &allocator, const char *key_data, common::ObIArray &major_tables, common::ObIArray &minor_tables) @@ -507,7 +545,7 @@ int TestCompactionPolicy::batch_mock_sstables( ObTableHandleV2 table_handle; const int64_t type = cells[0].get_int(); ObITable::TableType table_type = (type == 10) ? ObITable::MAJOR_SSTABLE : ((type == 11) ? ObITable::MINOR_SSTABLE : ObITable::MINI_SSTABLE); - if (OB_FAIL(mock_sstable(table_type, cells[1].get_int(), cells[2].get_int(), cells[3].get_int(), cells[4].get_int(), table_handle))) { + if (OB_FAIL(mock_sstable(allocator, table_type, cells[1].get_int(), cells[2].get_int(), cells[3].get_int(), cells[4].get_int(), table_handle))) { LOG_WARN("failed to mock sstable", K(ret)); } else if (ObITable::MAJOR_SSTABLE == table_type) { if (OB_FAIL(major_tables.push_back(table_handle))) { @@ -548,6 +586,7 @@ int TestCompactionPolicy::batch_mock_memtables( } int TestCompactionPolicy::batch_mock_tables( + common::ObArenaAllocator &allocator, const char *key_data, common::ObIArray &major_tables, common::ObIArray &minor_tables, @@ -574,7 +613,7 @@ int TestCompactionPolicy::batch_mock_tables( } } else { ObITable::TableType table_type = (type == 10) ? ObITable::MAJOR_SSTABLE : ((type == 11) ? ObITable::MINOR_SSTABLE : ObITable::MINI_SSTABLE); - if (OB_FAIL(mock_sstable(table_type, cells[1].get_int(), cells[2].get_int(), cells[3].get_int(), cells[4].get_int(), table_handle))) { + if (OB_FAIL(mock_sstable(allocator, table_type, cells[1].get_int(), cells[2].get_int(), cells[3].get_int(), cells[4].get_int(), table_handle))) { LOG_WARN("failed to mock sstable", K(ret)); } else if (ObITable::MAJOR_SSTABLE == table_type) { if (OB_FAIL(major_tables.push_back(table_handle))) { @@ -602,12 +641,12 @@ int TestCompactionPolicy::prepare_tablet( if (OB_UNLIKELY(clog_checkpoint_ts <= 0 || snapshot_version <= 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid arguments", K(ret), K(snapshot_version)); - } else if (OB_FAIL(mock_tablet(clog_checkpoint_ts, snapshot_version, tablet_handle_))) { + } else if (OB_FAIL(mock_tablet(allocator_, clog_checkpoint_ts, snapshot_version, tablet_handle_))) { LOG_WARN("failed to mock tablet", K(ret)); } else if (OB_ISNULL(key_data)) { - } else if (OB_FAIL(batch_mock_tables(key_data, major_tables_, minor_tables_, memtables_, tablet_handle_))) { + } else if (OB_FAIL(batch_mock_tables(allocator_, key_data, major_tables_, minor_tables_, memtables_, tablet_handle_))) { LOG_WARN("failed to batch mock tables", K(ret)); - } else if (OB_FAIL(mock_table_store(tablet_handle_, major_tables_, minor_tables_))) { + } else if (OB_FAIL(mock_table_store(allocator_, tablet_handle_, major_tables_, minor_tables_))) { LOG_WARN("failed to mock table store", K(ret)); } return ret; @@ -711,15 +750,15 @@ TEST_F(TestCompactionPolicy, basic_create_sstable) ASSERT_NE(nullptr, t3m); ObTableHandleV2 major_table_handle; - ret = TestCompactionPolicy::mock_sstable(ObITable::MAJOR_SSTABLE, 0, 100, 100, 100, major_table_handle); + ret = TestCompactionPolicy::mock_sstable(allocator_, ObITable::MAJOR_SSTABLE, 0, 100, 100, 100, major_table_handle); ASSERT_EQ(OB_SUCCESS, ret); ObTableHandleV2 mini_table_handle; - ret = TestCompactionPolicy::mock_sstable(ObITable::MINI_SSTABLE, 100, 120, 120, 120, mini_table_handle); + ret = TestCompactionPolicy::mock_sstable(allocator_, ObITable::MINI_SSTABLE, 100, 120, 120, 120, mini_table_handle); ASSERT_EQ(OB_SUCCESS, ret); ObTableHandleV2 minor_table_handle; - ret = TestCompactionPolicy::mock_sstable(ObITable::MINOR_SSTABLE, 120, 180, 180, INT64_MAX, minor_table_handle); + ret = TestCompactionPolicy::mock_sstable(allocator_, ObITable::MINOR_SSTABLE, 120, 180, 180, INT64_MAX, minor_table_handle); ASSERT_EQ(OB_SUCCESS, ret); } @@ -735,21 +774,21 @@ TEST_F(TestCompactionPolicy, basic_create_tablet) ASSERT_NE(nullptr, t3m); ObTabletHandle tablet_handle; - ret = TestCompactionPolicy::mock_tablet(100, 100, tablet_handle); + ret = TestCompactionPolicy::mock_tablet(allocator_, 100, 100, tablet_handle); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(true, tablet_handle.is_valid()); - ObTablet &tablet = *tablet_handle.get_obj(); - ObTabletTableStore &table_store = tablet.get_table_store(); + ObTablet *tablet = tablet_handle.get_obj(); + ObTabletTableStore &table_store = *tablet->table_store_addr_.get_ptr(); ASSERT_EQ(true, table_store.is_valid()); - ASSERT_TRUE(nullptr != tablet.memtable_mgr_); + ASSERT_TRUE(nullptr != tablet->memtable_mgr_); } TEST_F(TestCompactionPolicy, basic_create_memtable) { int ret = OB_SUCCESS; ObTabletHandle tablet_handle; - ret = TestCompactionPolicy::mock_tablet(100, 100, tablet_handle); + ret = TestCompactionPolicy::mock_tablet(allocator_, 100, 100, tablet_handle); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(true, tablet_handle.is_valid()); @@ -776,43 +815,43 @@ TEST_F(TestCompactionPolicy, basic_create_table_store) { int ret = OB_SUCCESS; ObTabletHandle tablet_handle; - ret = TestCompactionPolicy::mock_tablet(100, 100, tablet_handle); + ret = TestCompactionPolicy::mock_tablet(allocator_, 100, 100, tablet_handle); ASSERT_EQ(OB_SUCCESS, ret); ObSEArray major_tables; ObTableHandleV2 major_table_handle_1; - ret = TestCompactionPolicy::mock_sstable(ObITable::MAJOR_SSTABLE, 0, 1, 1, 1, major_table_handle_1); + ret = TestCompactionPolicy::mock_sstable(allocator_, ObITable::MAJOR_SSTABLE, 0, 1, 1, 1, major_table_handle_1); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(OB_SUCCESS, major_tables.push_back(major_table_handle_1)); ObTableHandleV2 major_table_handle_2; - ret = TestCompactionPolicy::mock_sstable(ObITable::MAJOR_SSTABLE, 0, 100, 100, 100, major_table_handle_2); + ret = TestCompactionPolicy::mock_sstable(allocator_, ObITable::MAJOR_SSTABLE, 0, 100, 100, 100, major_table_handle_2); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(OB_SUCCESS, major_tables.push_back(major_table_handle_2)); ObTableHandleV2 major_table_handle_3; - ret = TestCompactionPolicy::mock_sstable(ObITable::MAJOR_SSTABLE, 0, 150, 150, 150, major_table_handle_3); + ret = TestCompactionPolicy::mock_sstable(allocator_, ObITable::MAJOR_SSTABLE, 0, 150, 150, 150, major_table_handle_3); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(OB_SUCCESS, major_tables.push_back(major_table_handle_3)); ObSEArray minor_tables; ObTableHandleV2 minor_table_handle_1; - ret = TestCompactionPolicy::mock_sstable(ObITable::MINI_SSTABLE, 100, 150, 150, 160, minor_table_handle_1); + ret = TestCompactionPolicy::mock_sstable(allocator_, ObITable::MINI_SSTABLE, 100, 150, 150, 160, minor_table_handle_1); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(OB_SUCCESS, minor_tables.push_back(minor_table_handle_1)); ObTableHandleV2 minor_table_handle_2; - ret = TestCompactionPolicy::mock_sstable(ObITable::MINI_SSTABLE, 150, 200, 190, 200, minor_table_handle_2); + ret = TestCompactionPolicy::mock_sstable(allocator_, ObITable::MINI_SSTABLE, 150, 200, 190, 200, minor_table_handle_2); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(OB_SUCCESS, minor_tables.push_back(minor_table_handle_2)); ObTableHandleV2 minor_table_handle_3; - ret = TestCompactionPolicy::mock_sstable(ObITable::MINI_SSTABLE, 200, 350, 350, INT64_MAX, minor_table_handle_3); + ret = TestCompactionPolicy::mock_sstable(allocator_, ObITable::MINI_SSTABLE, 200, 350, 350, INT64_MAX, minor_table_handle_3); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(OB_SUCCESS, minor_tables.push_back(minor_table_handle_3)); - ret = TestCompactionPolicy::mock_table_store(tablet_handle, major_tables, minor_tables); + ret = TestCompactionPolicy::mock_table_store(allocator_, tablet_handle, major_tables, minor_tables); ASSERT_EQ(OB_SUCCESS, ret); LOG_INFO("Print tablet", KPC(tablet_handle.get_obj())); @@ -830,7 +869,7 @@ TEST_F(TestCompactionPolicy, basic_batch_create_sstable) ObArray major_tables; ObArray minor_tables; - ret = TestCompactionPolicy::batch_mock_sstables(key_data, major_tables, minor_tables); + ret = TestCompactionPolicy::batch_mock_sstables(allocator_, key_data, major_tables, minor_tables); ASSERT_EQ(OB_SUCCESS, ret); ASSERT_EQ(2, major_tables.count()); ASSERT_EQ(2, minor_tables.count()); @@ -851,7 +890,7 @@ TEST_F(TestCompactionPolicy, basic_prepare_tablet) ret = prepare_tablet(key_data, 150, 150); ASSERT_EQ(OB_SUCCESS, ret); - ObTabletTableStore &table_store = tablet_handle_.get_obj()->table_store_; + ObTabletTableStore &table_store = *tablet_handle_.get_obj()->table_store_addr_.get_ptr(); ASSERT_EQ(2, table_store.major_tables_.count()); ASSERT_EQ(2, table_store.minor_tables_.count()); diff --git a/unittest/storage/test_dag_warning_history.cpp b/unittest/storage/test_dag_warning_history.cpp index 4ff9e4e33..dd45ec247 100644 --- a/unittest/storage/test_dag_warning_history.cpp +++ b/unittest/storage/test_dag_warning_history.cpp @@ -17,201 +17,466 @@ #include "share/scheduler/ob_dag_warning_history_mgr.h" #include "share/scheduler/ob_dag_scheduler.h" +#include "storage/ob_sstable_struct.h" +#include "observer/omt/ob_tenant_node_balancer.h" namespace oceanbase { using namespace common; using namespace storage; using namespace share; +using namespace lib; namespace unittest { +static const int64_t INFO_PAGE_SIZE = (1 << 11); // 2KB class TestDagWarningHistory : public ::testing::Test { public: - TestDagWarningHistory() {} - virtual ~TestDagWarningHistory() {} + TestDagWarningHistory() + : tenant_id_(1), + dag_history_mgr_(nullptr), + tenant_base_(tenant_id_) + { } + ~TestDagWarningHistory() {} + void SetUp() + { + ObUnitInfoGetter::ObTenantConfig unit_config; + unit_config.mode_ = lib::Worker::CompatMode::MYSQL; + unit_config.tenant_id_ = tenant_id_; + TenantUnits units; + ASSERT_EQ(OB_SUCCESS, units.push_back(unit_config)); + + dag_history_mgr_ = OB_NEW(ObDagWarningHistoryManager, ObModIds::TEST); + tenant_base_.set(dag_history_mgr_); + + ObTenantEnv::set_tenant(&tenant_base_); + ASSERT_EQ(OB_SUCCESS, tenant_base_.init()); + + ObMallocAllocator *ma = ObMallocAllocator::get_instance(); + ASSERT_EQ(OB_SUCCESS, ma->create_and_add_tenant_allocator(tenant_id_)); + ASSERT_EQ(OB_SUCCESS, ma->set_tenant_limit(tenant_id_, 1LL << 30)); + } + void TearDown() + { + dag_history_mgr_->~ObDagWarningHistoryManager(); + dag_history_mgr_ = nullptr; + tenant_base_.destroy(); + ObTenantEnv::set_tenant(nullptr); + } +private: + const uint64_t tenant_id_; + ObDagWarningHistoryManager *dag_history_mgr_; + ObTenantBase tenant_base_; + DISALLOW_COPY_AND_ASSIGN(TestDagWarningHistory); }; -TEST_F(TestDagWarningHistory, init) +class ObBasicDag : public ObIDag { - ASSERT_EQ(OB_SUCCESS, ObDagWarningHistoryManager::get_instance().init()); -} +public: + ObBasicDag() : + ObIDag(ObDagType::DAG_TYPE_MINI_MERGE) + {} + void init() { is_inited_ = true; } + virtual int64_t hash() const { + return KEY_START; + } + virtual bool operator == (const ObIDag &other) const + { + bool bret = false; + if (get_type() == other.get_type()) { + const ObBasicDag &dag = static_cast(other); + bret = dag.id_ == id_; + } + return bret; + } + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, + ObIAllocator &allocator) const override + { + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), 1, 2, "table_id", 10))) { + COMMON_LOG(WARN, "fail to add dag warning info param", K(ret)); + } + return ret; + } + virtual int fill_dag_key(char *buf,const int64_t size) const override { UNUSEDx(buf, size); return OB_SUCCESS; } + virtual lib::Worker::CompatMode get_compat_mode() const override + { return lib::Worker::CompatMode::MYSQL; } + virtual uint64_t get_consumer_group_id() const override + { return consumer_group_id_; } + INHERIT_TO_STRING_KV("ObIDag", ObIDag, K_(is_inited), K_(type), K(task_list_.get_size()), K_(dag_ret)); + +private: + DISALLOW_COPY_AND_ASSIGN(ObBasicDag); + +public: + static const int64_t KEY_START = 8888; + static const int DAG_RET_START = -4016; +}; + +class ObSeqDag : public ObBasicDag +{ +public: + ObSeqDag() : + ObBasicDag() + {} + virtual int64_t hash() const { + static int64_t key = KEY_START; + return key++; + } +}; + +class ObComplexDag : public ObBasicDag +{ +public: + ObComplexDag(int64_t hash) : + ObBasicDag() + { + hash_ = hash; + } + virtual int64_t hash() const { + return hash_; + } + int64_t hash_; +}; TEST_F(TestDagWarningHistory, simple_add) { int ret = OB_SUCCESS; - ObDagWarningHistoryManager& manager = ObDagWarningHistoryManager::get_instance(); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); - ObDagWarningInfo *info = NULL; - const int64_t key = 8888; - ret = manager.alloc_and_add_with_no_lock(key, info); + ObBasicDag dag; + dag.init(); + dag.set_dag_ret(ObBasicDag::DAG_RET_START); + dag.set_dag_status(ObBasicDag::ObDagStatus::DAG_STATUS_ABORT); + + //not init + ret = MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag); + ASSERT_NE(OB_SUCCESS, ret); + ret = MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis", INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + ret = MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag); ASSERT_EQ(OB_SUCCESS, ret); - info->dag_ret_ = -4016; - info->dag_status_ = ObDagWarningInfo::ODS_WARNING; - info->dag_type_ = share::ObDagType::DAG_TYPE_MERGE_EXECUTE; - strcpy(info->warning_info_, "table_id=1101710651081571, partition_id=66, mini merge error"); - - ObDagWarningInfo *ret_info = NULL; - ret = manager.get(key + 1, ret_info); + compaction::ObInfoParamBuffer allocator; + ObDagWarningInfo ret_info; + ret = MTL(ObDagWarningHistoryManager *)->get_with_param(ObBasicDag::KEY_START+1, &ret_info, allocator); ASSERT_EQ(OB_HASH_NOT_EXIST, ret); - ASSERT_EQ(NULL, ret_info); - ret = manager.get(key, ret_info); + allocator.reuse(); + ret = MTL(ObDagWarningHistoryManager *)->get_with_param(ObBasicDag::KEY_START, &ret_info, allocator); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ (TRUE, *ret_info == *info); - STORAGE_LOG(INFO, "ret", KPC(ret_info)); + ASSERT_EQ(TRUE, ret_info.dag_ret_ == ObBasicDag::DAG_RET_START); + STORAGE_LOG(DEBUG, "", K(ret_info)); + ASSERT_EQ(TRUE, ret_info.tenant_id_ == tenant_id_); - // duplicated key - ret = manager.alloc_and_add_with_no_lock(key, info); - ASSERT_EQ(OB_HASH_EXIST, ret); + char comment[common::OB_DAG_WARNING_INFO_LENGTH]; + memset(comment, '\0', sizeof(comment)); + allocator.reuse(); + ret = MTL(ObDagWarningHistoryManager *)->get_with_param(ObBasicDag::KEY_START, &ret_info, allocator); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ (TRUE, ret_info.dag_ret_ == ObBasicDag::DAG_RET_START); + memset(comment, '\0', sizeof(comment)); + ASSERT_EQ(OB_SUCCESS, ret_info.info_param_->fill_comment(comment, sizeof(comment))); + STORAGE_LOG(DEBUG, "comment", K(comment)); } -TEST_F(TestDagWarningHistory, simple_del_with_no_lock) +TEST_F(TestDagWarningHistory, simple_del) { int ret = OB_SUCCESS; - ObDagWarningHistoryManager& manager = ObDagWarningHistoryManager::get_instance(); - manager.clear(); - ObDagWarningInfo *info = NULL; - const int64_t key = 8888; - ASSERT_EQ(OB_SUCCESS, manager.alloc_and_add_with_no_lock(key, info)); - info->dag_ret_ = -4016; - info->dag_status_ = ObDagWarningInfo::ODS_WARNING; - info->dag_type_ = share::ObDagType::DAG_TYPE_MERGE_EXECUTE; - strcpy(info->warning_info_, "table_id=1101710651081571, partition_id=66, mini merge error"); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + ret = MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis", INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(OB_HASH_NOT_EXIST, manager.del_with_no_lock(key + 1)); + ObBasicDag dag; + dag.init(); + dag.set_dag_ret(ObBasicDag::DAG_RET_START); + dag.set_dag_status(ObBasicDag::ObDagStatus::DAG_STATUS_ABORT); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag)); + ASSERT_EQ(OB_HASH_NOT_EXIST, MTL(ObDagWarningHistoryManager *)->delete_info(ObBasicDag::KEY_START + 1)); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->delete_info(ObBasicDag::KEY_START)); + ASSERT_EQ(1, MTL(ObDagWarningHistoryManager *)->size()); - ASSERT_EQ(OB_SUCCESS, manager.del_with_no_lock(key)); + compaction::ObInfoParamBuffer allocator; + ObDagWarningInfo ret_info; + ret = MTL(ObDagWarningHistoryManager *)->get_with_param(ObBasicDag::KEY_START, &ret_info, allocator); + ASSERT_EQ(OB_HASH_NOT_EXIST, ret); - ObDagWarningInfo *ret_info = NULL; - ret = manager.get(key, ret_info); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag)); + compaction::ObIDiagnoseInfoMgr::Iterator iterator; + ret = MTL(ObDagWarningHistoryManager *)->open_iter(iterator); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->delete_info(ObBasicDag::KEY_START)); + // delete_info only delete info from map, there is still 2 info in list + ASSERT_EQ(2, MTL(ObDagWarningHistoryManager *)->size()); + ASSERT_EQ(OB_ITER_END, iterator.get_next(&ret_info, nullptr, 0)); + + allocator.reuse(); + ret = MTL(ObDagWarningHistoryManager *)->get_with_param(ObBasicDag::KEY_START, &ret_info, allocator); ASSERT_EQ(OB_HASH_NOT_EXIST, ret); } TEST_F(TestDagWarningHistory, simple_loop_get) { int ret = OB_SUCCESS; - ObDagWarningHistoryManager& manager = ObDagWarningHistoryManager::get_instance(); - manager.clear(); - const int64_t tenant_id = 100; - ObDagWarningInfo basic_info; - basic_info.tenant_id_ = tenant_id; - basic_info.dag_ret_ = -4016; - basic_info.dag_status_ = ObDagWarningInfo::ODS_WARNING; - basic_info.dag_type_ = share::ObDagType::DAG_TYPE_MERGE_EXECUTE; - strcpy(basic_info.warning_info_, "table_id=1101710651081571, partition_id=66, mini merge error"); + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + ret = MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis", INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); - const int64_t max_cnt = 20; - ObDagWarningInfo *info = NULL; - int64_t key = 0; + const int64_t max_cnt = 4000; for (int i = 0; i < max_cnt; ++i) { - key = 8888 + i; - ASSERT_EQ(OB_SUCCESS, manager.alloc_and_add_with_no_lock(key, info)); - info->tenant_id_ = tenant_id; - info->dag_ret_ = -4016 + i; - info->dag_status_ = ObDagWarningInfo::ODS_WARNING; - info->dag_type_ = share::ObDagType::DAG_TYPE_MERGE_EXECUTE; - strcpy(info->warning_info_, "table_id=1101710651081571, partition_id=66, mini merge error"); + ObSeqDag dag; + dag.init(); + dag.set_dag_status(ObBasicDag::ObDagStatus::DAG_STATUS_ABORT); + dag.set_dag_ret(ObBasicDag::DAG_RET_START + i); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag)); } - ObDagWarningInfoIterator iterator; - iterator.open(tenant_id); + + ASSERT_EQ(max_cnt, MTL(ObDagWarningHistoryManager *)->size()); + + compaction::ObIDiagnoseInfoMgr::Iterator iterator; + ret = MTL(ObDagWarningHistoryManager *)->open_iter(iterator); + ASSERT_EQ(OB_SUCCESS, ret); + ObDagWarningInfo read_info; + char comment[common::OB_DAG_WARNING_INFO_LENGTH]; int i = 0; while (OB_SUCC(ret)) { - if (OB_FAIL(iterator.get_next_info(read_info))) { + if (OB_FAIL(iterator.get_next(&read_info, comment, sizeof(comment)))) { ASSERT_EQ(OB_ITER_END, ret); } else { - basic_info.dag_ret_ = -4016 + i; - STORAGE_LOG(DEBUG, "print info", K(ret), K(read_info), K(basic_info)); - ASSERT_EQ(TRUE, read_info == basic_info); + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + i)); ++i; } } - for (int i = 0; i < max_cnt; i += 2) { - key = 8888 + i; - ASSERT_EQ(OB_SUCCESS, manager.del_with_no_lock(key)); + int64_t key = 0; + const int64_t del_cnt = 3000; + for (int i = 0; i < del_cnt; i += 1) { + key = ObBasicDag::KEY_START + i; + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->delete_info(key)); } iterator.reset(); - iterator.open(tenant_id); - i = 0; + ret = MTL(ObDagWarningHistoryManager *)->open_iter(iterator); + ASSERT_EQ(OB_SUCCESS, ret); + i = del_cnt; while (OB_SUCC(ret)) { - if (OB_SUCC(iterator.get_next_info(read_info))) { - basic_info.dag_ret_ = -4016 + i; - ASSERT_EQ(TRUE, read_info == basic_info); - STORAGE_LOG(DEBUG, "print info", K(ret), K(read_info), KPC(info)); - i += 2; + if (OB_SUCC(iterator.get_next(&read_info, nullptr, 0))) { + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + i)); + i += 1; } } - manager.clear(); - ASSERT_EQ(0, manager.size()); + MTL(ObDagWarningHistoryManager *)->clear(); + ASSERT_EQ(0, MTL(ObDagWarningHistoryManager *)->size()); } - -TEST_F(TestDagWarningHistory, test_rebuild) +TEST_F(TestDagWarningHistory, resize) { int ret = OB_SUCCESS; - ObDagWarningHistoryManager& manager = ObDagWarningHistoryManager::get_instance(); - manager.clear(); - const int64_t tenant_id = 100; + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + ret = MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis", INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + const int64_t max_cnt = 20; - ObDagWarningInfo basic_info; - basic_info.tenant_id_ = tenant_id; - basic_info.dag_ret_ = -4016; - basic_info.dag_status_ = ObDagWarningInfo::ODS_WARNING; - basic_info.dag_type_ = share::ObDagType::DAG_TYPE_MERGE_EXECUTE; - strcpy(basic_info.warning_info_, "table_id=1101710651081571, partition_id=66, mini merge error"); - - ObDagWarningInfo *info = NULL; - int64_t key = 0; for (int i = 0; i < max_cnt; ++i) { - key = 8888 + i; - ASSERT_EQ(OB_SUCCESS, manager.alloc_and_add_with_no_lock(key, info)); - info->tenant_id_ = tenant_id; - info->dag_ret_ = -4016 + i; - info->dag_status_ = ObDagWarningInfo::ODS_WARNING; - info->dag_type_ = share::ObDagType::DAG_TYPE_MERGE_EXECUTE; - strcpy(info->warning_info_, "table_id=1101710651081571, partition_id=66, mini merge error"); - STORAGE_LOG(DEBUG, "print info", K(ret), K(i), K(key), KPC(info)); + ObSeqDag dag; + dag.init(); + dag.set_dag_status(ObBasicDag::ObDagStatus::DAG_STATUS_ABORT); + dag.set_dag_ret(ObBasicDag::DAG_RET_START + i); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag)); } - ASSERT_EQ(max_cnt, manager.size()); + ASSERT_EQ(max_cnt, MTL(ObDagWarningHistoryManager *)->size()); - for (int i = 0; i < max_cnt; i += 2) { - key = 8888 + i; - ASSERT_EQ(OB_SUCCESS, manager.del_with_no_lock(key)); - } + // every info is 240 bytes, each page contains 7 info + // 20 infos are in 3 pages (7 7 6), set_max will left 6 info (6 * 240 < 4096 * 0.4), means 1 page (6) + ret = MTL(ObDagWarningHistoryManager *)->set_max(2 * INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(6, MTL(ObDagWarningHistoryManager *)->size()); - ASSERT_EQ(max_cnt / 2, manager.size()); + ret = MTL(ObDagWarningHistoryManager *)->set_max(3 * INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(6, MTL(ObDagWarningHistoryManager *)->size()); + + compaction::ObIDiagnoseInfoMgr::Iterator iterator; + ret = MTL(ObDagWarningHistoryManager *)->open_iter(iterator); + ASSERT_EQ(OB_SUCCESS, ret); - ObDagWarningInfoIterator iterator; - iterator.open(tenant_id); ObDagWarningInfo read_info; - int i = 1; + char comment[common::OB_DAG_WARNING_INFO_LENGTH]; + int i = 14; while (OB_SUCC(ret)) { - if (OB_SUCC(iterator.get_next_info(read_info))) { - basic_info.dag_ret_ = -4016 + i; - STORAGE_LOG(DEBUG, "print info", K(ret), K(read_info), K(basic_info)); - ASSERT_EQ(TRUE, read_info == basic_info); - i += 2; + if (OB_FAIL(iterator.get_next(&read_info, comment, sizeof(comment)))) { + ASSERT_EQ(OB_ITER_END, ret); + } else { + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + i)); + ++i; + } + } +} + +TEST_F(TestDagWarningHistory, gc_info) +{ + int ret = OB_SUCCESS; + + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + ret = MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis", INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + ret = MTL(ObDagWarningHistoryManager *)->set_max(10 * INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t hash_value = ObBasicDag::KEY_START; + const int64_t max_cnt = 69; + for (int i = 0; i < max_cnt; ++i) { + ObComplexDag dag(hash_value++); + dag.init(); + dag.set_dag_status(ObBasicDag::ObDagStatus::DAG_STATUS_ABORT); + dag.set_dag_ret(ObBasicDag::DAG_RET_START + i); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag)); + } + // 9 page full, 1 page contain 6 info (7 7 7 7 7 7 7 7 7 6) + ASSERT_EQ(max_cnt, MTL(ObDagWarningHistoryManager *)->size()); + + for (int i = 0; i < 30; ++i) { + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->delete_info(ObBasicDag::KEY_START+i)); + } + + // every info is 240 bytes, each page contains 7 info + // 69 * 240 > 20480 * 0.8 // after gc, left 34 info (34 * 240 < 20480 * 0.4), means 1 page (7 7 7 7 6) + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->gc_info()); + ASSERT_EQ(34, MTL(ObDagWarningHistoryManager *)->size()); +} + +TEST_F(TestDagWarningHistory, complex_test) +{ + int ret = OB_SUCCESS; + + ObDagWarningHistoryManager* manager = MTL(ObDagWarningHistoryManager *); + ASSERT_TRUE(nullptr != manager); + ret = MTL(ObDagWarningHistoryManager *)->init(true, MTL_ID(), "DagWarnHis", INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + ret = MTL(ObDagWarningHistoryManager *)->set_max(2 * INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t hash_value = ObBasicDag::KEY_START; + const int64_t max_cnt = 20; + for (int i = 0; i < max_cnt; ++i) { + ObComplexDag dag(hash_value++); + dag.init(); + dag.set_dag_status(ObBasicDag::ObDagStatus::DAG_STATUS_ABORT); + dag.set_dag_ret(ObBasicDag::DAG_RET_START + i); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag)); + } + // every info is 240 bytes, each page contains 7 info + // 10 info will be purged , left 2 page (4 6) + ASSERT_EQ(10, MTL(ObDagWarningHistoryManager *)->size()); + + compaction::ObIDiagnoseInfoMgr::Iterator iterator; + ret = MTL(ObDagWarningHistoryManager *)->open_iter(iterator); + ASSERT_EQ(OB_SUCCESS, ret); + + ObDagWarningInfo read_info; + char comment[common::OB_DAG_WARNING_INFO_LENGTH]; + // the first 10 info have been purged + int i = 10; + while (OB_SUCC(ret)) { + if (OB_FAIL(iterator.get_next(&read_info, comment, sizeof(comment)))) { + ASSERT_EQ(OB_ITER_END, ret); + } else { + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + i)); + ++i; } } - manager.clear(); - ASSERT_EQ(0, manager.size()); -} + // test when two iter is accessing info pool + compaction::ObIDiagnoseInfoMgr::Iterator iterator1; + compaction::ObIDiagnoseInfoMgr::Iterator iterator2; + ret = MTL(ObDagWarningHistoryManager *)->open_iter(iterator1); + ASSERT_EQ(OB_SUCCESS, ret); + ret = MTL(ObDagWarningHistoryManager *)->open_iter(iterator2); + ASSERT_EQ(OB_SUCCESS, ret); + i = 10; + ASSERT_EQ(OB_SUCCESS, iterator1.get_next(&read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + i++)); + ASSERT_EQ(OB_SUCCESS, iterator1.get_next(&read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + i++)); -TEST_F(TestDagWarningHistory, simple_destory) -{ - ObDagWarningHistoryManager& manager = ObDagWarningHistoryManager::get_instance(); - manager.destroy(); + i = 10; + ASSERT_EQ(OB_SUCCESS, iterator2.get_next(&read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + i++)); + ASSERT_EQ(OB_SUCCESS, iterator2.get_next(&read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + i++)); + ASSERT_EQ(OB_SUCCESS, iterator2.get_next(&read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + i++)); + + i = max_cnt; + { + ObComplexDag dag(hash_value++); + dag.init(); + dag.set_dag_status(ObBasicDag::ObDagStatus::DAG_STATUS_ABORT); + dag.set_dag_ret(ObBasicDag::DAG_RET_START + i++); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag)); + ASSERT_EQ(11, MTL(ObDagWarningHistoryManager *)->size()); + } + { + ObComplexDag dag(hash_value++); + dag.init(); + dag.set_dag_status(ObBasicDag::ObDagStatus::DAG_STATUS_ABORT); + dag.set_dag_ret(ObBasicDag::DAG_RET_START + i++); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag)); + ASSERT_EQ(2, MTL(ObDagWarningHistoryManager *)->size()); + } + + // let the iterator1 in iter_end + int j = 20; + while (OB_SUCC(ret)) { + if (OB_FAIL(iterator1.get_next(&read_info, comment, sizeof(comment)))) { + ASSERT_EQ(OB_ITER_END, ret); + } else { + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + j)); + ++j; + } + } + + // before set_max (1 1), after set_max (1) + ret = MTL(ObDagWarningHistoryManager *)->set_max(INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(1, MTL(ObDagWarningHistoryManager *)->size()); + + { + ObComplexDag dag(hash_value++); + dag.init(); + dag.set_dag_status(ObBasicDag::ObDagStatus::DAG_STATUS_ABORT); + dag.set_dag_ret(ObBasicDag::DAG_RET_START + i++); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag)); + ASSERT_EQ(2, MTL(ObDagWarningHistoryManager *)->size()); + } + + ASSERT_EQ(OB_ITER_END, iterator1.get_next(&read_info, comment, sizeof(comment))); + ASSERT_EQ(OB_SUCCESS, iterator2.get_next(&read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.dag_ret_ == (ObBasicDag::DAG_RET_START + 21)); + + // test purge cuz add when there are some deleted info on list + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->delete_info(hash_value-1)); + for (int i = 0; i < max_cnt; ++i) { + ObComplexDag dag(hash_value++); + dag.init(); + dag.set_dag_status(ObBasicDag::ObDagStatus::DAG_STATUS_ABORT); + dag.set_dag_ret(ObBasicDag::DAG_RET_START + i); + ASSERT_EQ(OB_SUCCESS, MTL(ObDagWarningHistoryManager *)->add_dag_warning_info(&dag)); + } } } // end namespace unittest diff --git a/unittest/storage/test_dml_common.h b/unittest/storage/test_dml_common.h index ae2eee7c7..cd45294c2 100644 --- a/unittest/storage/test_dml_common.h +++ b/unittest/storage/test_dml_common.h @@ -217,21 +217,7 @@ int TestDmlCommon::create_data_tablet( STORAGE_LOG(WARN, "failed to build pure data tablet arg", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); } else { - transaction::ObMulSourceDataNotifyArg trans_flags; - trans_flags.tx_id_ = 123; - trans_flags.scn_ = share::SCN::invalid_scn(); - trans_flags.for_replay_ = false; - - ObLS *ls = ls_handle.get_ls(); - if (OB_FAIL(ls->get_tablet_svr()->on_prepare_create_tablets(arg, trans_flags))) { - STORAGE_LOG(WARN, "failed to prepare create tablets", K(ret), K(arg)); - } else if (FALSE_IT(trans_flags.scn_ = share::SCN::minus(share::SCN::max_scn(), 100))) { - } else if (OB_FAIL(ls->get_tablet_svr()->on_redo_create_tablets(arg, trans_flags))) { - STORAGE_LOG(WARN, "failed to redo create tablets", K(ret), K(arg)); - } else if (FALSE_IT(trans_flags.scn_ = share::SCN::plus(trans_flags.scn_, 1))) { - } else if (OB_FAIL(ls->get_tablet_svr()->on_commit_create_tablets(arg, trans_flags))) { - STORAGE_LOG(WARN, "failed to commit create tablets", K(ret), K(arg)); - } + ret = OB_NOT_SUPPORTED; } return ret; @@ -247,18 +233,14 @@ int TestDmlCommon::create_data_and_index_tablets( ObLSHandle ls_handle; obrpc::ObBatchCreateTabletArg arg; - share::SCN log_scn; if (OB_FAIL(create_ls(tenant_id, ls_id, ls_handle))) { STORAGE_LOG(WARN, "failed to create ls", K(ret), K(tenant_id), K(ls_id)); } else if (OB_FAIL(build_mixed_tablets_arg(tenant_id, ls_id, data_tablet_id, index_tablet_id_array, arg))) { STORAGE_LOG(WARN, "failed to build pure data tablet arg", K(ret), K(tenant_id), K(ls_id), K(data_tablet_id), K(index_tablet_id_array)); - } else if (OB_FAIL(log_scn.convert_for_logservice(1))) { - STORAGE_LOG(WARN, "failed to convert_for_logservice", K(ret)); - - } else if (OB_FAIL(ls_handle.get_ls()->batch_create_tablets(arg, log_scn, true/*is_replay*/))) { - STORAGE_LOG(WARN, "failed to batch create tablets", K(ret), K(arg)); + } else { + ret = OB_NOT_SUPPORTED; } return ret; diff --git a/unittest/storage/test_io_manager.cpp b/unittest/storage/test_io_manager.cpp index b17cbe55e..5b9c2157b 100644 --- a/unittest/storage/test_io_manager.cpp +++ b/unittest/storage/test_io_manager.cpp @@ -136,24 +136,19 @@ class TestIOCallback : public ObIOCallback { public: TestIOCallback() - : number_(nullptr), allocator_(nullptr), user_offset_(0), - user_size_(0), raw_buf_(nullptr), user_buf_(nullptr) + : number_(nullptr), allocator_(nullptr), help_buf_(nullptr) {} virtual ~TestIOCallback(); - virtual const char *get_data() override { return (char *)user_buf_; } + virtual const char *get_data() override { return help_buf_; } virtual int64_t size() const override { return sizeof(TestIOCallback); } virtual int inner_deep_copy(char *buf, const int64_t buf_len, ObIOCallback *&callback) const override; - virtual int alloc_io_buf(char *&io_buf, int64_t &io_buf_size, int64_t &aligned_offset) override; - virtual int inner_process(const bool is_success) override; - TO_STRING_KV(KP(number_), KP(allocator_), K(user_offset_), K(user_size_), KP(raw_buf_), KP(user_buf_)); + virtual int inner_process(const char *data_buffer, const int64_t size) override; + TO_STRING_KV(KP(number_), KP(allocator_), KP(help_buf_)); public: int64_t *number_; ObIAllocator *allocator_; - int64_t user_offset_; - int64_t user_size_; - void *raw_buf_; - void *user_buf_; + char *help_buf_; }; TEST_F(TestIOStruct, IOFlag) @@ -789,8 +784,6 @@ TEST_F(TestIOManager, simple) TestIOCallback callback; callback.number_ = &tmp_number; callback.allocator_ = &allocator; - callback.user_offset_ = io_info.offset_; - callback.user_size_ = io_info.size_; io_info.callback_ = &callback; ASSERT_SUCC(io_mgr.read(io_info, io_handle, io_timeout_ms)); ASSERT_NE(nullptr, io_handle.get_buffer()); @@ -1335,15 +1328,12 @@ TestIOCallback::~TestIOCallback() if (nullptr != number_) { *number_ -= 90; } - if (nullptr != allocator_ && nullptr != raw_buf_) { - allocator_->free(raw_buf_); - } number_ = nullptr; allocator_ = nullptr; - user_offset_ = 0; - user_size_ = 0; - raw_buf_ = nullptr; - user_buf_ = nullptr; + if (nullptr != help_buf_ && nullptr != allocator_) { + allocator_->free(help_buf_); + help_buf_ = nullptr; + } } @@ -1361,31 +1351,25 @@ int TestIOCallback::inner_deep_copy(char *buf, const int64_t buf_len, ObIOCallba TestIOCallback *tmp_callback = new (buf) TestIOCallback(); tmp_callback->number_ = number_; tmp_callback->allocator_ = allocator_; - tmp_callback->user_offset_ = user_offset_; - tmp_callback->user_size_ = user_size_; callback = tmp_callback; } return ret; } -int TestIOCallback::alloc_io_buf(char *&io_buf, int64_t &io_buf_size, int64_t &aligned_offset) +int TestIOCallback::inner_process(const char *data_buffer, const int64_t size) { int ret = OB_SUCCESS; - align_offset_size(user_offset_, user_size_, aligned_offset, io_buf_size); - if (OB_ISNULL(raw_buf_ = allocator_->alloc(io_buf_size + DIO_READ_ALIGN_SIZE))) { + if (OB_ISNULL(allocator_)) { + // for test, ignore + } else if (OB_ISNULL(help_buf_ = static_cast(allocator_->alloc(size)))) { ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("allocate memory failed", K(ret), K(user_size_)); + LOG_WARN("Failed to allocate help buf", K(ret), K(size), KP(data_buffer)); } else { - io_buf = reinterpret_cast(upper_align(reinterpret_cast(raw_buf_), DIO_READ_ALIGN_SIZE)); - user_buf_ = io_buf + user_offset_ - aligned_offset; + memset(help_buf_, 0, size); + MEMCPY(help_buf_, data_buffer, size); } - return ret; -} - -int TestIOCallback::inner_process(const bool is_success) -{ if (nullptr != number_) { - is_success ? *number_ += 100 : *number_ -=100; + *number_ += 100; } return OB_SUCCESS; } diff --git a/unittest/storage/test_major_rows_merger.cpp b/unittest/storage/test_major_rows_merger.cpp index 7929b4b0b..40a209e32 100644 --- a/unittest/storage/test_major_rows_merger.cpp +++ b/unittest/storage/test_major_rows_merger.cpp @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #define USING_LOG_PREFIX STORAGE #include #define private public @@ -31,7 +30,15 @@ using namespace compaction; using namespace unittest; namespace storage { - +namespace mds +{ +void *MdsAllocator::alloc(const int64_t size) { + return ob_malloc(size, "MDS"); +} +void MdsAllocator::free(void *ptr) { + return ob_free(ptr); +} +} template int prepare_partition_merge_iter(ObMergeParameter &merge_param, common::ObIAllocator &allocator, @@ -90,13 +97,10 @@ void ObMajorRowsMergerTest::SetUpTestCase() ObLSService *ls_svr = MTL(ObLSService*); ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); - // create tablet - obrpc::ObBatchCreateTabletArg create_tablet_arg; share::schema::ObTableSchema table_schema; - ASSERT_EQ(OB_SUCCESS, gen_create_tablet_arg(tenant_id_, ls_id, tablet_id, create_tablet_arg, 1, &table_schema)); - - ObLSTabletService *ls_tablet_svr = ls_handle.get_ls()->get_tablet_svr(); - ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(*ls_tablet_svr, create_tablet_arg)); + uint64_t table_id = 12345; + ASSERT_EQ(OB_SUCCESS, build_test_schema(table_schema, table_id)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema, allocator_)); } void ObMajorRowsMergerTest::TearDownTestCase() @@ -150,9 +154,10 @@ void ObMajorRowsMergerTest::prepare_merge_context(const ObMergeType &merge_type, merge_context.sstable_version_range_ = trans_version_range; merge_context.param_.report_ = &rs_reporter_; merge_context.progressive_merge_num_ = 0; - const common::ObIArray &tables = merge_context.tables_handle_.get_tables(); - merge_context.scn_range_.start_scn_ = tables.at(0)->get_start_scn(); - merge_context.scn_range_.end_scn_ = tables.at(tables.count() - 1)->get_end_scn(); + const int64_t tables_count = merge_context.tables_handle_.get_count(); + merge_context.scn_range_.start_scn_ = merge_context.tables_handle_.get_table(0)->get_start_scn(); + merge_context.scn_range_.end_scn_ = merge_context.tables_handle_.get_table(tables_count - 1)->get_end_scn(); + merge_context.merge_scn_ = merge_context.scn_range_.end_scn_; ASSERT_EQ(OB_SUCCESS, merge_context.init_merge_info()); ASSERT_EQ(OB_SUCCESS, merge_context.merge_info_.prepare_index_builder(index_desc_)); @@ -234,7 +239,7 @@ TEST_F(ObMajorRowsMergerTest, tset_compare_func) OK(iter_0->next()); OK(iter_1->next()); - const ObTableReadInfo &read_info = iter_0->get_read_info(); + const ObITableReadInfo &read_info = iter_0->get_read_info(); int64_t cmp_ret; ObPartitionMergeLoserTreeItem item_0, item_1; item_0.iter_ = iter_0; @@ -346,7 +351,7 @@ TEST_F(ObMajorRowsMergerTest, single) ObPartitionMergeLoserTreeItem item_0, item_1; item_0.iter_ = iter_0; item_0.iter_idx_ = 0; item_1.iter_ = iter_1; item_1.iter_idx_ = 1; - const ObTableReadInfo &read_info = iter_0->get_read_info(); + const ObITableReadInfo &read_info = iter_0->get_read_info(); ObPartitionMergeLoserTreeCmp cmp(read_info.get_datum_utils(), read_info.get_schema_rowkey_count()); ObPartitionMajorRowsMerger merger(cmp); @@ -455,7 +460,7 @@ TEST_F(ObMajorRowsMergerTest, two_iters) item_0.iter_idx_ = 0; item_1.iter_ = iter_1; item_1.iter_idx_ = 1; - const ObTableReadInfo &read_info = iter_0->get_read_info(); + const ObITableReadInfo &read_info = iter_0->get_read_info(); ObPartitionMergeLoserTreeCmp cmp(read_info.get_datum_utils(), read_info.get_schema_rowkey_count()); ObPartitionMajorRowsMerger merger(cmp); @@ -496,8 +501,8 @@ TEST_F(ObMajorRowsMergerTest, two_iters) int main(int argc, char **argv) { system("rm -rf test_major_rows_merger.log*"); - OB_LOGGER.set_file_name("test_major_rows_merger.log"); OB_LOGGER.set_log_level("INFO"); + OB_LOGGER.set_file_name("test_major_rows_merger.log", true, false); oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/unittest/storage/test_medium_compaction_mgr.cpp b/unittest/storage/test_medium_compaction_mgr.cpp deleted file mode 100644 index 0f53f9c7b..000000000 --- a/unittest/storage/test_medium_compaction_mgr.cpp +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright 2019-2021 Alibaba Inc. All Rights Reserved. -// Author: -// -// This file defines test_medium_compaction_mgr.cpp -// - -#include -#define protected public -#define private public -#include -#include "storage/compaction/ob_medium_compaction_mgr.h" -#include "share/schema/ob_column_schema.h" - -namespace oceanbase -{ -using namespace common; -using namespace compaction; -using namespace storage; - -namespace unittest -{ - -class TestMediumCompactionMgr : public ::testing::Test -{ -public: - virtual void SetUp() - { - share::schema::ObTableSchema table_schema; - prepare_schema(table_schema); - - medium_info_.compaction_type_ = ObMediumCompactionInfo::MEDIUM_COMPACTION; - medium_info_.medium_snapshot_ = 100; - medium_info_.data_version_ = 100; - medium_info_.cluster_id_ = INIT_CLUSTER_ID; - - medium_info_.storage_schema_.init(allocator_, table_schema, lib::Worker::CompatMode::MYSQL); - GCONF.cluster_id = 1; - } - virtual void TearDown() - { - medium_info_.reset(); - allocator_.reset(); - } - int construct_list( - const char *snapshot_list, - ObMediumCompactionInfoList &list, - const int64_t cluster_id = INIT_CLUSTER_ID); - int construct_array( - const char *snapshot_list, - ObIArray &array); - void prepare_schema(share::schema::ObTableSchema &table_schema); - - static const int64_t INIT_CLUSTER_ID = 1; - static const int64_t OTHER_CLUSTER_ID = 2; -private: - ObMediumCompactionInfo medium_info_; - ObSEArray array_; - ObArenaAllocator allocator_; -}; - -int TestMediumCompactionMgr::construct_array( - const char *snapshot_list, - ObIArray &array) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(snapshot_list)) { - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "invalid argument", K(ret), K(snapshot_list)); - } else { - array.reset(); - std::string copy(snapshot_list); - char *org = const_cast(copy.c_str()); - static const char *delim = " "; - char *s = std::strtok(org, delim); - if (NULL != s) { - array.push_back(atoi(s)); - while (NULL != (s= strtok(NULL, delim))) { - array.push_back(atoi(s)); - } - } - } - return ret; -} - -int TestMediumCompactionMgr::construct_list( - const char *snapshot_list, - ObMediumCompactionInfoList &list, - const int64_t cluster_id) -{ - int ret = OB_SUCCESS; - if (!list.is_inited_ && OB_FAIL(list.init(allocator_))) { - COMMON_LOG(WARN, "failed to init list", K(ret)); - } - construct_array(snapshot_list, array_); - for (int i = 0; OB_SUCC(ret) && i < array_.count(); ++i) { - medium_info_.cluster_id_ = cluster_id; - medium_info_.medium_snapshot_ = array_.at(i); - ret = list.add_medium_compaction_info(medium_info_); - } - return ret; -} - -static const int64_t TENANT_ID = 1; -static const int64_t TABLE_ID = 7777; -static const int64_t TEST_ROWKEY_COLUMN_CNT = 3; -static const int64_t TEST_COLUMN_CNT = 6; - -void TestMediumCompactionMgr::prepare_schema(share::schema::ObTableSchema &table_schema) -{ - int ret = OB_SUCCESS; - int64_t micro_block_size = 16 * 1024; - const uint64_t tenant_id = TENANT_ID; - const uint64_t table_id = TABLE_ID; - share::schema::ObColumnSchemaV2 column; - - //generate data table schema - table_schema.reset(); - ret = table_schema.set_table_name("test_merge_multi_version"); - ASSERT_EQ(OB_SUCCESS, ret); - table_schema.set_tenant_id(tenant_id); - table_schema.set_tablegroup_id(1); - table_schema.set_database_id(1); - table_schema.set_table_id(table_id); - table_schema.set_rowkey_column_num(TEST_ROWKEY_COLUMN_CNT); - table_schema.set_max_used_column_id(TEST_COLUMN_CNT); - table_schema.set_block_size(micro_block_size); - table_schema.set_compress_func_name("none"); - table_schema.set_row_store_type(FLAT_ROW_STORE); - //init column - char name[OB_MAX_FILE_NAME_LENGTH]; - memset(name, 0, sizeof(name)); - const int64_t column_ids[] = {16,17,20,21,22,23,24,29}; - for(int64_t i = 0; i < TEST_COLUMN_CNT; ++i){ - ObObjType obj_type = ObIntType; - const int64_t column_id = column_ids[i]; - - if (i == 1) { - obj_type = ObVarcharType; - } - column.reset(); - column.set_table_id(table_id); - column.set_column_id(column_id); - sprintf(name, "test%020ld", i); - ASSERT_EQ(OB_SUCCESS, column.set_column_name(name)); - column.set_data_type(obj_type); - column.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); - column.set_data_length(10); - if (i < TEST_ROWKEY_COLUMN_CNT) { - column.set_rowkey_position(i + 1); - } else { - column.set_rowkey_position(0); - } - COMMON_LOG(INFO, "add column", K(i), K(column)); - ASSERT_EQ(OB_SUCCESS, table_schema.add_column(column)); - } - COMMON_LOG(INFO, "dump stable schema", LITERAL_K(TEST_ROWKEY_COLUMN_CNT), K(table_schema)); -} - -TEST_F(TestMediumCompactionMgr, test_basic_init) -{ - ObMediumCompactionInfoList list_1; - ASSERT_EQ(OB_SUCCESS, construct_list("300, 400, 500", list_1)); - - ObMediumCompactionInfoList list_2; - ASSERT_EQ(OB_SUCCESS, construct_list("100, 200", list_2)); - - ObMediumCompactionInfoList out_list; - ASSERT_EQ(OB_SUCCESS, out_list.init(allocator_, &list_2, &list_1, 0)); - - ASSERT_EQ(5, out_list.size()); - ASSERT_EQ(100, out_list.get_min_medium_snapshot()); - ASSERT_EQ(500, out_list.get_max_medium_snapshot()); - - out_list.reset(); - - ASSERT_EQ(OB_SUCCESS, out_list.init(allocator_, &list_2, &list_1, 400)); - ASSERT_EQ(1, out_list.size()); - ASSERT_EQ(500, out_list.get_min_medium_snapshot()); - ASSERT_EQ(500, out_list.get_max_medium_snapshot()); -} - -TEST_F(TestMediumCompactionMgr, test_push_list_error) -{ - ObMediumCompactionInfoList test_list; - ASSERT_EQ(OB_SUCCESS, construct_list("300, 500, 400", test_list)); - ASSERT_EQ(test_list.get_max_medium_snapshot(), 500); - ASSERT_EQ(test_list.get_list().get_size(), 2); - - medium_info_.medium_snapshot_ = 900; - ASSERT_EQ(OB_SUCCESS, test_list.add_medium_compaction_info(medium_info_)); - ASSERT_EQ(test_list.get_list().get_size(), 3); - - medium_info_.medium_snapshot_ = 700; - ASSERT_EQ(OB_SUCCESS, test_list.add_medium_compaction_info(medium_info_)); - ASSERT_EQ(test_list.get_list().get_size(), 3); - ASSERT_EQ(test_list.get_max_medium_snapshot(), 900); - - medium_info_.medium_snapshot_ = 1000; - ASSERT_EQ(OB_SUCCESS, test_list.add_medium_compaction_info(medium_info_)); - ASSERT_EQ(test_list.get_list().get_size(), 4); - - medium_info_.medium_snapshot_ = 1200; - ASSERT_EQ(OB_SUCCESS, test_list.add_medium_compaction_info(medium_info_)); - ASSERT_EQ(test_list.get_list().get_size(), 5); - - medium_info_.medium_snapshot_ = 100; - ASSERT_EQ(OB_SUCCESS, test_list.add_medium_compaction_info(medium_info_)); - ASSERT_EQ(test_list.get_list().get_size(), 5); - - medium_info_.medium_snapshot_ = 100; - ASSERT_EQ(test_list.size(), 5); // 300 500 900 1000 1200 - - ObMediumCompactionInfoList test_list_2; - ASSERT_EQ(OB_SUCCESS, test_list_2.init(allocator_, &test_list, nullptr, 900)); - ASSERT_EQ(1000, test_list_2.get_min_medium_snapshot()); - ASSERT_EQ(test_list_2.size(), 2); - const ObMediumCompactionInfo *ret_info = nullptr; - ASSERT_EQ(OB_ENTRY_NOT_EXIST, test_list_2.get_specified_scn_info(900, ret_info)); - - test_list_2.reset(); - ASSERT_EQ(OB_SUCCESS, test_list_2.init(allocator_, &test_list, nullptr, 900)); -} - -}//end namespace unittest -}//end namespace oceanbase - -int main(int argc, char **argv) -{ - system("rm -f test_medium_compaction_mgr.log*"); - OB_LOGGER.set_file_name("test_medium_compaction_mgr.log"); - OB_LOGGER.set_log_level("DEBUG"); - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/unittest/storage/test_meta_pointer_map.cpp b/unittest/storage/test_meta_pointer_map.cpp index d6e83764d..d145dac0d 100644 --- a/unittest/storage/test_meta_pointer_map.cpp +++ b/unittest/storage/test_meta_pointer_map.cpp @@ -39,12 +39,11 @@ template<> int ObMetaPointerMap::load_meta_obj( const ObTabletMapKey &key, ObMetaPointer *meta_pointer, - common::ObIAllocator &allocator, + common::ObArenaAllocator &allocator, ObMetaDiskAddr &load_addr, - ObTablet *&t, - const bool using_obj_pool) + ObTablet *t) { - UNUSEDx(key, meta_pointer, allocator, load_addr, t, using_obj_pool); + UNUSEDx(key, meta_pointer, allocator, load_addr, t); return OB_SUCCESS; } @@ -61,6 +60,7 @@ public: private: static constexpr uint64_t TEST_TENANT_ID = OB_SERVER_TENANT_ID; ObMetaPointerMap tablet_map_; + common::ObArenaAllocator allocator_; ObTenantBase tenant_base_; }; @@ -105,7 +105,6 @@ void TestMetaPointerMap::FakeLs(ObLS &ls) ls.ls_meta_.rebuild_seq_ = 0; } - class CalculateSize final { public: @@ -149,8 +148,6 @@ TEST_F(TestMetaPointerMap, test_meta_pointer_handle) ObMemtableMgrHandle memtable_mgr_hdl; ObDDLKvMgrHandle ddl_kv_mgr_hdl; - common::ObIAllocator &allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); - ret = MTL(ObTenantMetaMemMgr*)->acquire_tablet_memtable_mgr(memtable_mgr_hdl); ASSERT_EQ(common::OB_SUCCESS, ret); @@ -216,8 +213,6 @@ TEST_F(TestMetaPointerMap, test_meta_pointer_map) ObMemtableMgrHandle memtable_mgr_hdl; ObDDLKvMgrHandle ddl_kv_mgr_hdl; - common::ObIAllocator &allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); - ret = MTL(ObTenantMetaMemMgr*)->acquire_tablet_memtable_mgr(memtable_mgr_hdl); ASSERT_EQ(common::OB_SUCCESS, ret); @@ -241,7 +236,7 @@ TEST_F(TestMetaPointerMap, test_meta_pointer_map) ASSERT_EQ(1, tablet_map_.map_.size()); ObTabletHandle handle; - ret = tablet_map_.get_meta_obj(key, allocator, handle); + ret = tablet_map_.get_meta_obj(key, handle); ASSERT_EQ(common::OB_ITEM_NOT_SETTED, ret); ASSERT_TRUE(!handle.is_valid()); ASSERT_EQ(nullptr, handle.get_obj()); @@ -251,36 +246,40 @@ TEST_F(TestMetaPointerMap, test_meta_pointer_map) ObTablet *old_tablet = new ObTablet(); ObMetaObj old_tablet_obj; old_tablet_obj.ptr_ = old_tablet; - old_tablet_obj.pool_ = &MTL(ObTenantMetaMemMgr*)->tablet_pool_; + old_tablet_obj.pool_ = &MTL(ObTenantMetaMemMgr*)->tablet_buffer_pool_; handle.set_obj(old_tablet_obj); + /** ret = tablet_map_.set_meta_obj(key, handle); ASSERT_EQ(common::OB_SUCCESS, ret); + */ phy_addr.first_id_ = 1; phy_addr.second_id_ = 2; phy_addr.offset_ = 0; phy_addr.size_ = 4096; phy_addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; - ret = tablet_map_.compare_and_swap_address_and_object(key, phy_addr, handle, handle); + ret = tablet_map_.compare_and_swap_addr_and_object(key, phy_addr, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ObTablet *tablet = new ObTablet(); + tablet->tablet_addr_ = phy_addr; ObMetaObj tablet_obj; tablet_obj.ptr_ = tablet; - tablet_obj.pool_ = &MTL(ObTenantMetaMemMgr*)->tablet_pool_; + tablet_obj.pool_ = &MTL(ObTenantMetaMemMgr*)->tablet_buffer_pool_; ObTabletHandle tablet_handle; tablet_handle.set_obj(tablet_obj); - ret = tablet_map_.compare_and_swap_address_and_object(key, phy_addr, handle, tablet_handle); + ret = tablet_map_.compare_and_swap_addr_and_object(key, phy_addr, handle, tablet_handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet_map_.map_.size()); - ret = tablet_map_.get_meta_obj(key, allocator, handle); + ret = tablet_map_.get_meta_obj(key, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_TRUE(handle.is_valid()); ASSERT_EQ(tablet, handle.get_obj()); - ret = tablet_map_.erase(key, allocator); + ObTabletHandle tmp_handle; + ret = tablet_map_.erase(key, tmp_handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(0, tablet_map_.map_.size()); } @@ -298,8 +297,6 @@ TEST_F(TestMetaPointerMap, test_erase_and_load_concurrency) ObMemtableMgrHandle memtable_mgr_hdl; ObDDLKvMgrHandle ddl_kv_mgr_hdl; - common::ObIAllocator &allocator = MTL(ObTenantMetaMemMgr*)->get_tenant_allocator(); - ret = MTL(ObTenantMetaMemMgr*)->acquire_tablet_memtable_mgr(memtable_mgr_hdl); ASSERT_EQ(common::OB_SUCCESS, ret); @@ -323,7 +320,7 @@ TEST_F(TestMetaPointerMap, test_erase_and_load_concurrency) ASSERT_EQ(1, tablet_map_.map_.size()); ObTabletHandle handle; - ret = tablet_map_.get_meta_obj(key, allocator, handle); + ret = tablet_map_.get_meta_obj(key, handle); ASSERT_EQ(common::OB_ITEM_NOT_SETTED, ret); ASSERT_TRUE(!handle.is_valid()); ASSERT_EQ(nullptr, handle.get_obj()); @@ -333,18 +330,20 @@ TEST_F(TestMetaPointerMap, test_erase_and_load_concurrency) ObTablet *old_tablet = new ObTablet(); ObMetaObj old_tablet_obj; old_tablet_obj.ptr_ = old_tablet; - old_tablet_obj.pool_ = &MTL(ObTenantMetaMemMgr*)->tablet_pool_; + old_tablet_obj.pool_ = &MTL(ObTenantMetaMemMgr*)->tablet_buffer_pool_; handle.set_obj(old_tablet_obj); + /** ret = tablet_map_.set_meta_obj(key, handle); ASSERT_EQ(common::OB_SUCCESS, ret); + */ phy_addr.first_id_ = 1; phy_addr.second_id_ = 2; phy_addr.offset_ = 0; phy_addr.size_ = 4096; phy_addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; - ret = tablet_map_.compare_and_swap_address_and_object(key, phy_addr, handle, handle); + ret = tablet_map_.compare_and_swap_addr_and_object(key, phy_addr, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ObMetaPointerHandle ptr_hdl(tablet_map_); @@ -353,12 +352,12 @@ TEST_F(TestMetaPointerMap, test_erase_and_load_concurrency) ASSERT_TRUE(ptr_hdl.get_resource_ptr()->is_in_memory()); ptr_hdl.get_resource_ptr()->reset_obj(); - ret = tablet_map_.erase(key); - ASSERT_EQ(common::OB_SUCCESS, ret); - ASSERT_EQ(0, tablet_map_.map_.size()); - - ret = tablet_map_.load_and_hook_meta_obj(key, ptr_hdl, allocator, handle); - ASSERT_EQ(common::OB_ENTRY_NOT_EXIST, ret); +// ret = tablet_map_.erase(key); +// ASSERT_EQ(common::OB_SUCCESS, ret); +// ASSERT_EQ(0, tablet_map_.map_.size()); +// +// ret = tablet_map_.load_and_hook_meta_obj(key, ptr_hdl, handle); +// ASSERT_EQ(common::OB_ENTRY_NOT_EXIST, ret); } class TestMetaDiskAddr : public ::testing::Test diff --git a/unittest/storage/test_parallel_minor_dag.cpp b/unittest/storage/test_parallel_minor_dag.cpp index b698df02b..c0827ae02 100644 --- a/unittest/storage/test_parallel_minor_dag.cpp +++ b/unittest/storage/test_parallel_minor_dag.cpp @@ -56,7 +56,7 @@ public: const uint64_t tenant_id_; common::ObArenaAllocator allocator_; ObTenantBase tenant_base_; - ObSSTable fake_sstables_[MAX_SSTABLE_CNT]; + ObSSTable *fake_sstables_[MAX_SSTABLE_CNT]; }; void TestParallelMinorDag::SetUpTestCase() @@ -71,22 +71,32 @@ void TestParallelMinorDag::TearDownTestCase() void TestParallelMinorDag::SetUp() { - ObTenantMetaMemMgr *t3m = OB_NEW(ObTenantMetaMemMgr, ObModIds::TEST, tenant_id_); - ASSERT_EQ(OB_SUCCESS, t3m->init()); + ObTenantMetaMemMgr *t3m = OB_NEW(ObTenantMetaMemMgr, ObModIds::TEST, tenant_id_); + ASSERT_EQ(OB_SUCCESS, t3m->init()); - tenant_base_.set(t3m); - ObTenantEnv::set_tenant(&tenant_base_); - ASSERT_EQ(OB_SUCCESS, tenant_base_.init()); + tenant_base_.set(t3m); + ObTenantEnv::set_tenant(&tenant_base_); + ASSERT_EQ(OB_SUCCESS, tenant_base_.init()); + + MEMSET(fake_sstables_, 0, sizeof(ObSSTable*) * MAX_SSTABLE_CNT ); } void TestParallelMinorDag::TearDown() { + for (int i = 0; i < MAX_SSTABLE_CNT; ++i) { + if (nullptr != fake_sstables_[i]) { + fake_sstables_[i]->~ObSSTable(); + allocator_.free(fake_sstables_[i]); + fake_sstables_[i] = nullptr; + } + } + allocator_.reset(); + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr *); t3m->destroy(); ObTenantEnv::set_tenant(nullptr); } - int TestParallelMinorDag::prepare_merge_result( const int64_t sstable_cnt, ObGetMergeTablesResult &result) @@ -105,25 +115,32 @@ int TestParallelMinorDag::prepare_merge_result( int64_t log_ts = 1; for (int i = 0; OB_SUCC(ret) && i < sstable_cnt; ++i) { - fake_sstables_[i].key_.scn_range_.start_scn_.convert_for_tx(log_ts++); - fake_sstables_[i].key_.scn_range_.end_scn_.convert_for_tx(log_ts); - if (OB_FAIL(result.handle_.add_table(&fake_sstables_[i]))) { - COMMON_LOG(WARN, "failed to push table", K(ret), K(i), K(fake_sstables_[i])); + char *buf = static_cast(allocator_.alloc(sizeof(ObSSTable))); + ObSSTable *tmp_sstable = new (buf) ObSSTable(); + fake_sstables_[i] = tmp_sstable; + fake_sstables_[i]->key_.scn_range_.start_scn_.convert_for_tx(log_ts++); + fake_sstables_[i]->key_.scn_range_.end_scn_.convert_for_tx(log_ts); + fake_sstables_[i]->key_.table_type_ = ObITable::TableType::MINI_SSTABLE; + ObTableHandleV2 table_handle; + if (OB_FAIL(table_handle.set_sstable(fake_sstables_[i], &allocator_))) { + COMMON_LOG(WARN, "failed to set stable", K(ret)); + } else if (OB_FAIL(result.handle_.add_table(table_handle))) { + COMMON_LOG(WARN, "failed to push table", K(ret), K(i), KPC(fake_sstables_[i])); } } - result.scn_range_.start_scn_ = fake_sstables_[0].key_.scn_range_.start_scn_; - result.scn_range_.end_scn_ = fake_sstables_[sstable_cnt - 1].key_.scn_range_.end_scn_; + result.scn_range_.start_scn_ = fake_sstables_[0]->key_.scn_range_.start_scn_; + result.scn_range_.end_scn_ = fake_sstables_[sstable_cnt - 1]->key_.scn_range_.end_scn_; return ret; } share::SCN TestParallelMinorDag::get_start_log_ts(const int64_t idx) { - return fake_sstables_[idx].key_.scn_range_.start_scn_; + return fake_sstables_[idx]->key_.scn_range_.start_scn_; } share::SCN TestParallelMinorDag::get_end_log_ts(const int64_t idx) { - return fake_sstables_[idx].key_.scn_range_.end_scn_; + return fake_sstables_[idx]->key_.scn_range_.end_scn_; } void check_result_valid(const ObGetMergeTablesResult &result) @@ -190,9 +207,9 @@ TEST_F(TestParallelMinorDag, test_parallel_interval) } #define CHECK_IN_RANGE(start_log_ts, end_log_ts, flag) \ - fake_sstables_[0].key_.scn_range_.start_scn_.convert_for_tx(start_log_ts); \ - fake_sstables_[0].key_.scn_range_.end_scn_.convert_for_tx(end_log_ts); \ - ASSERT_EQ(flag, range_mgr.in_execute_range(&fake_sstables_[0])); + fake_sstables_[0]->key_.scn_range_.start_scn_.convert_for_tx(start_log_ts); \ + fake_sstables_[0]->key_.scn_range_.end_scn_.convert_for_tx(end_log_ts); \ + ASSERT_EQ(flag, range_mgr.in_execute_range(fake_sstables_[0])); ObScnRange construct_scn_range(const int64_t start_scn, const int64_t end_scn) { @@ -205,6 +222,9 @@ ObScnRange construct_scn_range(const int64_t start_scn, const int64_t end_scn) TEST_F(TestParallelMinorDag, test_range_mgr) { ObMinorExecuteRangeMgr range_mgr; + int64_t sstable_cnt = 40; + ObGetMergeTablesResult result; + ASSERT_EQ(OB_SUCCESS, prepare_merge_result(sstable_cnt, result)); range_mgr.exe_range_array_.push_back(construct_scn_range(60, 80)); range_mgr.exe_range_array_.push_back(construct_scn_range(50, 70)); diff --git a/unittest/storage/test_partition_incremental_range_spliter.cpp b/unittest/storage/test_partition_incremental_range_spliter.cpp index dd557ed1a..518c244b5 100644 --- a/unittest/storage/test_partition_incremental_range_spliter.cpp +++ b/unittest/storage/test_partition_incremental_range_spliter.cpp @@ -29,11 +29,6 @@ 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; @@ -614,13 +609,15 @@ class TestPartitionIncrementalRangeSliter : public ::testing::Test public: TestPartitionIncrementalRangeSliter() : tenant_id_(1), tenant_base_(tenant_id_), merge_ctx_(param_, allocator_), buf_(nullptr), is_inited_(false) - {} + { + major_sstable_.meta_ = &major_sstable_meta_; + minor_sstable_.meta_ = &minor_sstable_meta_; + } virtual ~TestPartitionIncrementalRangeSliter() {} public: virtual void SetUp(); virtual void TearDown(); - private: void set_tablet_size(int64_t tablet_size) { @@ -629,9 +626,12 @@ private: } void set_major_sstable_meta(int64_t macro_block_count, int64_t occupy_size, int64_t row_count) { - major_sstable_.meta_.basic_meta_.data_macro_block_count_ = macro_block_count; - major_sstable_.meta_.basic_meta_.occupy_size_ = occupy_size; - major_sstable_.meta_.basic_meta_.row_count_ = row_count; + major_sstable_.meta_->basic_meta_.data_macro_block_count_ = macro_block_count; + major_sstable_.meta_->basic_meta_.occupy_size_ = occupy_size; + major_sstable_.meta_->basic_meta_.row_count_ = row_count; + major_sstable_.addr_.set_none_addr(); + major_sstable_.data_macro_block_count_ = macro_block_count; + major_sstable_.meta_->is_inited_ = true; } int set_major_sstable_macro_blocks(const ObString &str); void reset_major_sstable() @@ -662,7 +662,11 @@ private: ObStorageSchema storage_schema_; ObTablet tablet_; ObMockSSTableV2 major_sstable_; + ObSSTableMeta major_sstable_meta_; + ObStorageMetaHandle mock_major_sstable_handle_; ObSSTable minor_sstable_; // 增量 + ObSSTableMeta minor_sstable_meta_; + ObStorageMetaHandle mock_minor_sstable_handle_; compaction::ObTabletMergeCtx merge_ctx_; ObSEArray col_descs_; @@ -675,10 +679,11 @@ private: void TestPartitionIncrementalRangeSliter::SetUp() { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); if (!is_inited_) { + int ret = OB_SUCCESS; OB_SERVER_BLOCK_MGR.super_block_.body_.macro_block_size_ = 1; - int ret = OB_SUCCESS; ObTenantMetaMemMgr *t3m = OB_NEW(ObTenantMetaMemMgr, ObModIds::TEST, tenant_id_); ret = t3m->init(); ASSERT_EQ(OB_SUCCESS, ret); @@ -699,27 +704,37 @@ void TestPartitionIncrementalRangeSliter::SetUp() // major sstable major_sstable_.set_table_type(ObITable::MAJOR_SSTABLE); major_sstable_.key_.tablet_id_ = 1; - major_sstable_.meta_.basic_meta_.data_macro_block_count_ = 0; - major_sstable_.meta_.basic_meta_.occupy_size_ = 0; - major_sstable_.meta_.basic_meta_.row_count_ = 0; + major_sstable_.meta_->basic_meta_.data_macro_block_count_ = 0; + major_sstable_.meta_->basic_meta_.occupy_size_ = 0; + major_sstable_.meta_->basic_meta_.row_count_ = 0; major_sstable_.valid_for_reading_ = true; + major_sstable_.addr_.set_none_addr(); + major_sstable_.data_macro_block_count_ = major_sstable_.meta_->basic_meta_.data_macro_block_count_; + major_sstable_.meta_->is_inited_ = true; // minor sstable minor_sstable_.set_table_type(ObITable::MINOR_SSTABLE); minor_sstable_.key_.tablet_id_ = 1; + minor_sstable_.addr_.set_none_addr(); + minor_sstable_.data_macro_block_count_ = minor_sstable_.meta_->basic_meta_.data_macro_block_count_; + minor_sstable_.meta_->is_inited_ = true; // merge ctx merge_ctx_.schema_ctx_.storage_schema_ = &storage_schema_; - ASSERT_EQ(OB_SUCCESS, merge_ctx_.tables_handle_.add_table(&major_sstable_)); - ASSERT_EQ(OB_SUCCESS, merge_ctx_.tables_handle_.add_table(&minor_sstable_)); + ASSERT_EQ(OB_SUCCESS, merge_ctx_.tables_handle_.add_sstable(&major_sstable_, mock_major_sstable_handle_)); + ASSERT_EQ(OB_SUCCESS, merge_ctx_.tables_handle_.add_sstable(&minor_sstable_, mock_minor_sstable_handle_)); merge_ctx_.tablet_handle_.obj_ = &tablet_; + merge_ctx_.tablet_handle_.allocator_ = &allocator_; ObColDesc col_desc; - col_desc.col_id_ = 1; + col_desc.col_id_ = 1 + common::OB_APP_MIN_COLUMN_ID; col_desc.col_type_.set_int(); col_descs_.reset(); ASSERT_EQ(OB_SUCCESS, col_descs_.push_back(col_desc)); ASSERT_EQ(OB_SUCCESS, storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(col_descs_)); - ASSERT_EQ(OB_SUCCESS, tablet_.full_read_info_.init(allocator_, 16000, 1, lib::is_oracle_mode(), col_descs_, true)); + void *ptr = nullptr; + ASSERT_NE(nullptr, ptr = allocator_.alloc(sizeof(ObRowkeyReadInfo))); + tablet_.rowkey_read_info_ = new (ptr) ObRowkeyReadInfo(); + ASSERT_EQ(OB_SUCCESS, tablet_.rowkey_read_info_->init(allocator_, col_descs_.count(), 1, lib::is_oracle_mode(), col_descs_)); // buf buf_ = static_cast(allocator_.alloc(MAX_BUF_LENGTH)); @@ -735,7 +750,7 @@ void TestPartitionIncrementalRangeSliter::SetUp() void TestPartitionIncrementalRangeSliter::TearDown() { ASSERT_TRUE(is_inited_); - merge_ctx_.tablet_handle_.get_obj()->full_read_info_.reset(); + merge_ctx_.tablet_handle_.get_obj()->rowkey_read_info_->reset(); merge_ctx_.tablet_handle_.obj_ = nullptr; reset_major_sstable(); reset_ranges(); diff --git a/unittest/storage/test_partition_major_sstable_range_spliter.cpp b/unittest/storage/test_partition_major_sstable_range_spliter.cpp index 463b27409..42e8f29a1 100644 --- a/unittest/storage/test_partition_major_sstable_range_spliter.cpp +++ b/unittest/storage/test_partition_major_sstable_range_spliter.cpp @@ -209,7 +209,12 @@ class TestPartitionMajorSSTableRangeSliter : public ::testing::Test { static const int64_t MAX_BUF_LENGTH = 1024; public: - TestPartitionMajorSSTableRangeSliter() : buf_(nullptr), is_inited_(false) {} + TestPartitionMajorSSTableRangeSliter() : buf_(nullptr), is_inited_(false) + { + major_sstable_.meta_ = &sstable_meta_; + major_sstable_.addr_.set_none_addr(); + major_sstable_.meta_->is_inited_ = true; + } virtual ~TestPartitionMajorSSTableRangeSliter() {} public: @@ -219,9 +224,12 @@ public: private: void set_major_sstable_meta(int64_t macro_block_count, int64_t occupy_size, int64_t row_count) { - major_sstable_.meta_.basic_meta_.data_macro_block_count_ = macro_block_count; - major_sstable_.meta_.basic_meta_.occupy_size_ = occupy_size; - major_sstable_.meta_.basic_meta_.row_count_ = row_count; + major_sstable_.meta_->basic_meta_.data_macro_block_count_ = macro_block_count; + major_sstable_.meta_->basic_meta_.occupy_size_ = occupy_size; + major_sstable_.meta_->basic_meta_.row_count_ = row_count; + major_sstable_.addr_.set_none_addr(); + major_sstable_.data_macro_block_count_ = macro_block_count; + major_sstable_.meta_->is_inited_ = true; } int set_major_sstable_macro_blocks(const ObString &str); void reset_major_sstable() @@ -238,33 +246,38 @@ private: private: common::ObArenaAllocator allocator_; ObMockSSTableV2 major_sstable_; + ObSSTableMeta sstable_meta_; char *buf_; ObSEArray col_descs_; - ObTableReadInfo full_read_info_; + ObTableReadInfo idx_read_info_; bool is_inited_; }; void TestPartitionMajorSSTableRangeSliter::SetUp() { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); if (!is_inited_) { OB_SERVER_BLOCK_MGR.super_block_.body_.macro_block_size_ = 1; // major sstable major_sstable_.set_table_type(ObITable::MAJOR_SSTABLE); - major_sstable_.meta_.basic_meta_.data_macro_block_count_ = 0; - major_sstable_.meta_.basic_meta_.occupy_size_ = 0; - major_sstable_.meta_.basic_meta_.row_count_ = 0; + major_sstable_.meta_->basic_meta_.data_macro_block_count_ = 0; + major_sstable_.meta_->basic_meta_.occupy_size_ = 0; + major_sstable_.meta_->basic_meta_.row_count_ = 0; major_sstable_.valid_for_reading_ = true; + major_sstable_.addr_.set_none_addr(); + major_sstable_.data_macro_block_count_ = 0; + major_sstable_.meta_->is_inited_ = true; ObColDesc col_desc; col_desc.col_id_ = 1; col_desc.col_type_.set_int(); col_descs_.reset(); - full_read_info_.reset(); + idx_read_info_.reset(); ASSERT_EQ(OB_SUCCESS, col_descs_.push_back(col_desc)); ASSERT_EQ(OB_SUCCESS, col_descs_.push_back(col_desc)); ASSERT_EQ(OB_SUCCESS, storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(col_descs_)); - ASSERT_EQ(OB_SUCCESS, full_read_info_.init(allocator_, 16000, 1, lib::is_oracle_mode(), col_descs_, true)); + ASSERT_EQ(OB_SUCCESS, idx_read_info_.init(allocator_, 2, 1, lib::is_oracle_mode(), col_descs_, nullptr/*storage_cols_index*/)); // buf buf_ = static_cast(allocator_.alloc(MAX_BUF_LENGTH)); @@ -351,7 +364,7 @@ void TestPartitionMajorSSTableRangeSliter::inner_test_split_ranges( ASSERT_EQ(OB_SUCCESS, set_major_sstable_macro_blocks(macro_block_str)); } - ASSERT_EQ(OB_SUCCESS, range_spliter.init(*full_read_info_.get_index_read_info(), &major_sstable_, tablet_size, allocator_)); + ASSERT_EQ(OB_SUCCESS, range_spliter.init(idx_read_info_, &major_sstable_, tablet_size, allocator_)); ASSERT_EQ(OB_SUCCESS, range_spliter.split_ranges(range_array)); ASSERT_EQ(OB_SUCCESS, check_ranges_result(range_array, split_ranges, equal)); ASSERT_TRUE(equal); @@ -413,6 +426,7 @@ TEST_F(TestPartitionMajorSSTableRangeSliter, test_split_ranges) int main(int argc, char **argv) { + system("rm -f test_partition_major_sstable_range_spliter.log*"); oceanbase::common::ObLogger::get_logger().set_file_name("test_partition_major_sstable_range_spliter.log", true); oceanbase::common::ObLogger::get_logger().set_log_level("DEBUG"); ::testing::InitGoogleTest(&argc, argv); diff --git a/unittest/storage/test_partition_range_splite.cpp b/unittest/storage/test_partition_range_splite.cpp index ab981d607..dbed4ae4c 100644 --- a/unittest/storage/test_partition_range_splite.cpp +++ b/unittest/storage/test_partition_range_splite.cpp @@ -110,7 +110,7 @@ void TestRangeSpliter::SetUpTestCase() ASSERT_EQ(OB_SUCCESS, gen_create_tablet_arg(tenant_id_, ls_id, tablet_id, create_tablet_arg, 1, &table_schema)); ObLSTabletService *ls_tablet_svr = ls_handle.get_ls()->get_tablet_svr(); - ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(*ls_tablet_svr, create_tablet_arg)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema, ObMultiVersionSSTableTest::allocator_)); } void TestRangeSpliter::TearDownTestCase() @@ -351,7 +351,7 @@ void TestRangeSpliter::prepare_sstable_handle(ObTableHandleV2 &handle, prepare_data_end(handle); ObSSTable *sstable = nullptr; ASSERT_EQ(OB_SUCCESS, handle.get_sstable(sstable)); - sstable->meta_.basic_meta_.occupy_size_ = (2<<20) * macro_cnt; + sstable->meta_->basic_meta_.occupy_size_ = (2<<20) * macro_cnt; sstable->key_.table_type_ = ObITable::MINOR_SSTABLE; } @@ -369,7 +369,7 @@ TEST_F(TestRangeSpliter, test_single_basic) split_range.set_whole_range(); prepare_sstable_handle(handle, 0, 20, 10); - const ObTableReadInfo *index_read_info = full_read_info_.get_index_read_info(); + const ObTableReadInfo *index_read_info = &full_read_info_; ASSERT_EQ(OB_SUCCESS, sstables.push_back(handle.table_)); ASSERT_EQ(OB_SUCCESS, range_spliter.get_range_split_info(sstables, *index_read_info, split_range, range_split_info)); @@ -450,7 +450,7 @@ TEST_F(TestRangeSpliter, test_single_multi_sstable) prepare_sstable_handle(handle1, 5, 15, 20); ASSERT_EQ(OB_SUCCESS, sstables.push_back(handle1.table_)); - const ObTableReadInfo *index_read_info = full_read_info_.get_index_read_info(); + const ObTableReadInfo *index_read_info = &full_read_info_; ASSERT_EQ(OB_SUCCESS, range_spliter.get_range_split_info(sstables, *index_read_info, split_range, range_split_info)); range_split_info.set_parallel_target(2); @@ -508,7 +508,7 @@ TEST_F(TestRangeSpliter, test_micro_level_split) split_range.set_whole_range(); prepare_sstable_handle(handle, 0, 2, 10, 10); - const ObTableReadInfo *index_read_info = full_read_info_.get_index_read_info(); + const ObTableReadInfo *index_read_info = &full_read_info_; ASSERT_EQ(OB_SUCCESS, sstables.push_back(handle.table_)); ASSERT_EQ(OB_SUCCESS, range_spliter.get_range_split_info(sstables, *index_read_info, split_range, range_split_info)); diff --git a/unittest/storage/test_sstable_log_ts_range_cut.cpp b/unittest/storage/test_sstable_log_ts_range_cut.cpp index 8feb102de..42e011756 100644 --- a/unittest/storage/test_sstable_log_ts_range_cut.cpp +++ b/unittest/storage/test_sstable_log_ts_range_cut.cpp @@ -40,19 +40,24 @@ public: static void generate_mock_sstable( const int64_t start_log_ts, const int64_t end_log_ts, - ObSSTable &sstable) + ObSSTable &sstable, + blocksstable::ObSSTableMeta &meta) { + meta.basic_meta_.root_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + meta.basic_meta_.latest_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + meta.basic_meta_.status_ = SSTABLE_READY_FOR_READ; + meta.data_root_info_.addr_.set_none_addr(); + meta.macro_info_.macro_meta_info_.addr_.set_none_addr(); + meta.basic_meta_.compressor_type_ = ObCompressorType::NONE_COMPRESSOR; + meta.is_inited_ = true; + sstable.key_.table_type_ = ObITable::MINOR_SSTABLE; sstable.key_.tablet_id_ = 1; sstable.key_.scn_range_.start_scn_.convert_for_gts(start_log_ts); sstable.key_.scn_range_.end_scn_.convert_for_gts(end_log_ts); - sstable.meta_.basic_meta_.root_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; - sstable.meta_.basic_meta_.latest_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + sstable.meta_ = &meta; + sstable.valid_for_reading_ = true; - sstable.meta_.basic_meta_.status_ = SSTABLE_WRITE_BUILDING; - sstable.meta_.data_root_info_.addr_.set_none_addr(); - sstable.meta_.macro_info_.macro_meta_info_.addr_.set_none_addr(); - sstable.meta_.basic_meta_.compressor_type_ = ObCompressorType::NONE_COMPRESSOR; } }; @@ -98,18 +103,22 @@ private: TEST_F(TestSSTableScnRangeCut, sstable_scn_range_no_cross_and_continue) { int ret = OB_SUCCESS; + ObArenaAllocator allocator; ObTabletTableStore tablet_table_store; ObSSTable sstable1; - TestMockSSTable::generate_mock_sstable(0, 100, sstable1); + blocksstable::ObSSTableMeta meta1; + TestMockSSTable::generate_mock_sstable(0, 100, sstable1, meta1); ObSSTable sstable2; - TestMockSSTable::generate_mock_sstable(100, 200, sstable2); + blocksstable::ObSSTableMeta meta2; + TestMockSSTable::generate_mock_sstable(100, 200, sstable2, meta2); ObSSTable sstable3; - TestMockSSTable::generate_mock_sstable(200, 300, sstable3); + blocksstable::ObSSTableMeta meta3; + TestMockSSTable::generate_mock_sstable(200, 300, sstable3, meta3); ObArray minor_sstables; - ObTablesHandleArray tables_handle; + ObArray cut_minor_sstables; ret = minor_sstables.push_back(&sstable1); ASSERT_EQ(OB_SUCCESS, ret); @@ -117,18 +126,17 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_no_cross_and_continue) ASSERT_EQ(OB_SUCCESS, ret); ret = minor_sstables.push_back(&sstable3); ASSERT_EQ(OB_SUCCESS, ret); - ret = tablet_table_store.cut_ha_sstable_scn_range_(minor_sstables, tables_handle); + ret = tablet_table_store.cut_ha_sstable_scn_range_(allocator, minor_sstables, cut_minor_sstables); ASSERT_EQ(OB_SUCCESS, ret); - tables_handle.meta_mem_mgr_ = nullptr; - ASSERT_EQ(0, tables_handle.get_table(0)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(100, tables_handle.get_table(0)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(0, cut_minor_sstables.at(0)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(100, cut_minor_sstables.at(0)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(100, tables_handle.get_table(1)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(200, tables_handle.get_table(1)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(100, cut_minor_sstables.at(1)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(200, cut_minor_sstables.at(1)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(200, tables_handle.get_table(2)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(300, tables_handle.get_table(2)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(200, cut_minor_sstables.at(2)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(300, cut_minor_sstables.at(2)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); } @@ -140,19 +148,23 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_no_cross_and_continue) TEST_F(TestSSTableScnRangeCut, sstable_scn_range_is_not_continue) { int ret = OB_SUCCESS; + ObArenaAllocator allocator; ObTabletTableStore tablet_table_store; ObSSTable sstable1; - TestMockSSTable::generate_mock_sstable(0, 100, sstable1); + blocksstable::ObSSTableMeta meta1; + TestMockSSTable::generate_mock_sstable(0, 100, sstable1, meta1); ObSSTable sstable2; - TestMockSSTable::generate_mock_sstable(200, 300, sstable2); + blocksstable::ObSSTableMeta meta2; + TestMockSSTable::generate_mock_sstable(200, 300, sstable2, meta2); ObSSTable sstable3; - TestMockSSTable::generate_mock_sstable(300, 500, sstable3); + blocksstable::ObSSTableMeta meta3; + TestMockSSTable::generate_mock_sstable(300, 500, sstable3, meta3); ObArray minor_sstables; - ObTablesHandleArray tables_handle; + ObArray cut_minor_sstables; ret = minor_sstables.push_back(&sstable1); ASSERT_EQ(OB_SUCCESS, ret); @@ -160,9 +172,8 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_is_not_continue) ASSERT_EQ(OB_SUCCESS, ret); ret = minor_sstables.push_back(&sstable3); ASSERT_EQ(OB_SUCCESS, ret); - ret = tablet_table_store.cut_ha_sstable_scn_range_(minor_sstables, tables_handle); + ret = tablet_table_store.cut_ha_sstable_scn_range_(allocator, minor_sstables, cut_minor_sstables); ASSERT_EQ(OB_ERR_UNEXPECTED, ret); - tables_handle.meta_mem_mgr_ = nullptr; } @@ -174,19 +185,23 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_is_not_continue) TEST_F(TestSSTableScnRangeCut, sstable_scn_range_contain) { int ret = OB_SUCCESS; + ObArenaAllocator allocator; ObTabletTableStore tablet_table_store; ObSSTable sstable1; - TestMockSSTable::generate_mock_sstable(0, 100, sstable1); + blocksstable::ObSSTableMeta meta1; + TestMockSSTable::generate_mock_sstable(0, 100, sstable1, meta1); ObSSTable sstable2; - TestMockSSTable::generate_mock_sstable(0, 200, sstable2); + blocksstable::ObSSTableMeta meta2; + TestMockSSTable::generate_mock_sstable(0, 200, sstable2, meta2); ObSSTable sstable3; - TestMockSSTable::generate_mock_sstable(200, 500, sstable3); + blocksstable::ObSSTableMeta meta3; + TestMockSSTable::generate_mock_sstable(200, 500, sstable3, meta3); ObArray minor_sstables; - ObTablesHandleArray tables_handle; + ObArray cut_minor_sstables; ret = minor_sstables.push_back(&sstable1); ASSERT_EQ(OB_SUCCESS, ret); @@ -194,18 +209,17 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_contain) ASSERT_EQ(OB_SUCCESS, ret); ret = minor_sstables.push_back(&sstable3); ASSERT_EQ(OB_SUCCESS, ret); - ret = tablet_table_store.cut_ha_sstable_scn_range_(minor_sstables, tables_handle); + ret = tablet_table_store.cut_ha_sstable_scn_range_(allocator, minor_sstables, cut_minor_sstables); ASSERT_EQ(OB_SUCCESS, ret); - tables_handle.meta_mem_mgr_ = nullptr; - ASSERT_EQ(0, tables_handle.get_table(0)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(100, tables_handle.get_table(0)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(0, cut_minor_sstables.at(0)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(100, cut_minor_sstables.at(0)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(100, tables_handle.get_table(1)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(200, tables_handle.get_table(1)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(100, cut_minor_sstables.at(1)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(200, cut_minor_sstables.at(1)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(200, tables_handle.get_table(2)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(500, tables_handle.get_table(2)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(200, cut_minor_sstables.at(2)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(500, cut_minor_sstables.at(2)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); } @@ -217,19 +231,23 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_contain) TEST_F(TestSSTableScnRangeCut, sstable_scn_range_has_overlap) { int ret = OB_SUCCESS; + ObArenaAllocator allocator; ObTabletTableStore tablet_table_store; ObSSTable sstable1; - TestMockSSTable::generate_mock_sstable(0, 100, sstable1); + blocksstable::ObSSTableMeta meta1; + TestMockSSTable::generate_mock_sstable(0, 100, sstable1, meta1); ObSSTable sstable2; - TestMockSSTable::generate_mock_sstable(50, 200, sstable2); + blocksstable::ObSSTableMeta meta2; + TestMockSSTable::generate_mock_sstable(50, 200, sstable2, meta2); ObSSTable sstable3; - TestMockSSTable::generate_mock_sstable(200, 500, sstable3); + blocksstable::ObSSTableMeta meta3; + TestMockSSTable::generate_mock_sstable(200, 500, sstable3, meta3); ObArray minor_sstables; - ObTablesHandleArray tables_handle; + ObArray cut_minor_sstables; ret = minor_sstables.push_back(&sstable1); ASSERT_EQ(OB_SUCCESS, ret); @@ -237,18 +255,17 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_has_overlap) ASSERT_EQ(OB_SUCCESS, ret); ret = minor_sstables.push_back(&sstable3); ASSERT_EQ(OB_SUCCESS, ret); - ret = tablet_table_store.cut_ha_sstable_scn_range_(minor_sstables, tables_handle); + ret = tablet_table_store.cut_ha_sstable_scn_range_(allocator, minor_sstables, cut_minor_sstables); ASSERT_EQ(OB_SUCCESS, ret); - tables_handle.meta_mem_mgr_ = nullptr; - ASSERT_EQ(0, tables_handle.get_table(0)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(100, tables_handle.get_table(0)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(0, cut_minor_sstables.at(0)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(100, cut_minor_sstables.at(0)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(100, tables_handle.get_table(1)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(200, tables_handle.get_table(1)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(100, cut_minor_sstables.at(1)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(200, cut_minor_sstables.at(1)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(200, tables_handle.get_table(2)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); - ASSERT_EQ(500, tables_handle.get_table(2)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(200, cut_minor_sstables.at(2)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); + ASSERT_EQ(500, cut_minor_sstables.at(2)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); } diff --git a/unittest/storage/test_sstable_merge_info_mgr.cpp b/unittest/storage/test_sstable_merge_info_mgr.cpp index c0f1a3fee..49dcb264a 100644 --- a/unittest/storage/test_sstable_merge_info_mgr.cpp +++ b/unittest/storage/test_sstable_merge_info_mgr.cpp @@ -25,19 +25,19 @@ using namespace omt; namespace unittest { - +static const int64_t MERGE_INFO_PAGE_SIZE = 1LL << 13; // 8KB class TestSSTableMergeInfoMgr : public ::testing::Test { public: TestSSTableMergeInfoMgr() - : tenant_id_(1001), + : tenant_id_(1), merge_info_mgr_(nullptr), - tenant_base_(1001) + tenant_base_(tenant_id_) { } ~TestSSTableMergeInfoMgr() {} void SetUp() { - ObMallocAllocator::get_instance()->create_and_add_tenant_allocator(1001); + ObMallocAllocator::get_instance()->create_and_add_tenant_allocator(tenant_id_); ObUnitInfoGetter::ObTenantConfig unit_config; unit_config.mode_ = lib::Worker::CompatMode::MYSQL; unit_config.tenant_id_ = 0; @@ -49,6 +49,10 @@ public: ObTenantEnv::set_tenant(&tenant_base_); ASSERT_EQ(OB_SUCCESS, tenant_base_.init()); + + ObMallocAllocator *ma = ObMallocAllocator::get_instance(); + ASSERT_EQ(OB_SUCCESS, ma->create_and_add_tenant_allocator(tenant_id_)); + ASSERT_EQ(OB_SUCCESS, ma->set_tenant_limit(tenant_id_, 1LL << 30)); } void TearDown() { @@ -56,7 +60,7 @@ public: merge_info_mgr_ = nullptr; tenant_base_.destroy(); ObTenantEnv::set_tenant(nullptr); - ObMallocAllocator::get_instance()->recycle_tenant_allocator(1001); + ObMallocAllocator::get_instance()->recycle_tenant_allocator(tenant_id_); } private: const uint64_t tenant_id_; @@ -69,22 +73,22 @@ TEST_F(TestSSTableMergeInfoMgr, normal) { int ret = OB_SUCCESS; ObSSTableMergeInfo merge_info; + compaction::ObDiagnoseInfoParam<2, 0> info_param; + info_param.type_.suspect_type_ = ObSuspectInfoType::SUSPECT_MEMTABLE_CANT_MINOR_MERGE; + info_param.struct_type_ = compaction::ObInfoParamStructType::SUSPECT_INFO_PARAM; + merge_info.info_param_ = &info_param; + ObTenantSSTableMergeInfoMgr *merge_info_mgr = MTL(ObTenantSSTableMergeInfoMgr*); ASSERT_TRUE(nullptr != merge_info_mgr); //not init ret = MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info); ASSERT_NE(OB_SUCCESS, ret); - ret = MTL(ObTenantSSTableMergeInfoMgr*)->init(0); - ASSERT_NE(OB_SUCCESS, ret); - ret = MTL(ObTenantSSTableMergeInfoMgr*)->init(1); + ret = MTL(ObTenantSSTableMergeInfoMgr*)->init(MERGE_INFO_PAGE_SIZE); ASSERT_EQ(OB_SUCCESS, ret); - ret = MTL(ObTenantSSTableMergeInfoMgr*)->init(1); - ASSERT_NE(OB_SUCCESS, ret); ret = MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info); ASSERT_NE(OB_SUCCESS, ret); - const uint64_t tenant_id = 1001; merge_info.tenant_id_ = 1; merge_info.ls_id_ = 1; merge_info.tablet_id_ = 2; @@ -96,16 +100,224 @@ TEST_F(TestSSTableMergeInfoMgr, normal) ret = MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info); ASSERT_EQ(OB_SUCCESS, ret); - //test iter - ObSSTableMergeInfoIterator iter; - ret = iter.open(tenant_id); +} + +TEST_F(TestSSTableMergeInfoMgr, iterator) +{ + int ret = OB_SUCCESS; + ObTenantSSTableMergeInfoMgr *merge_info_mgr = MTL(ObTenantSSTableMergeInfoMgr*); + ASSERT_TRUE(nullptr != merge_info_mgr); + + ret = MTL(ObTenantSSTableMergeInfoMgr*)->init(MERGE_INFO_PAGE_SIZE); ASSERT_EQ(OB_SUCCESS, ret); - ret = iter.get_next_merge_info(merge_info); + + ObSSTableMergeInfo merge_info; + compaction::ObDiagnoseInfoParam<2, 0> info_param; + info_param.type_.suspect_type_ = ObSuspectInfoType::SUSPECT_MEMTABLE_CANT_MINOR_MERGE; + info_param.struct_type_ = compaction::ObInfoParamStructType::SUSPECT_INFO_PARAM; + merge_info.info_param_ = &info_param; + + merge_info.tenant_id_ = 1; + merge_info.ls_id_ = 1; + merge_info.tablet_id_ = 3; + merge_info.compaction_scn_ = 100; + merge_info.merge_type_ = ObMergeType::MINOR_MERGE; + ret = MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info); ASSERT_EQ(OB_SUCCESS, ret); - ret = iter.get_next_merge_info(merge_info); - ASSERT_EQ(OB_ITER_END, ret); - ret = iter.get_next_merge_info(merge_info); - ASSERT_EQ(OB_ITER_END, ret); + + merge_info.tablet_id_ = 4; + ret = MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info); + ASSERT_EQ(OB_SUCCESS, ret); + + merge_info.tablet_id_ = 1; + merge_info.merge_type_ = ObMergeType::MAJOR_MERGE; + ret = MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info); + ASSERT_EQ(OB_SUCCESS, ret); + + merge_info.tablet_id_ = 2; + ret = MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info); + ASSERT_EQ(OB_SUCCESS, ret); + + ASSERT_EQ(4, MTL(ObTenantSSTableMergeInfoMgr*)->size()); + + compaction::ObIDiagnoseInfoMgr::Iterator major_iterator; + compaction::ObIDiagnoseInfoMgr::Iterator minor_iterator; + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantSSTableMergeInfoMgr *)->open_iter(major_iterator, minor_iterator)); + + ObSSTableMergeInfo read_info; + char comment[common::OB_COMPACTION_EVENT_STR_LENGTH]; + int i = 1; + while (OB_SUCC(ret)) { + if (OB_FAIL(ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator, minor_iterator, read_info, comment, sizeof(comment)))) { + ASSERT_EQ(OB_ITER_END, ret); + } else { + ASSERT_EQ(ObTabletID(i), read_info.tablet_id_); + ++i; + } + } + ASSERT_EQ(OB_ITER_END, ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator, minor_iterator, read_info, comment, sizeof(comment))); + + compaction::ObIDiagnoseInfoMgr::Iterator major_iterator1; + compaction::ObIDiagnoseInfoMgr::Iterator minor_iterator1; + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantSSTableMergeInfoMgr *)->open_iter(major_iterator1, minor_iterator1)); + i = 1; + ASSERT_EQ(OB_SUCCESS, ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator1, minor_iterator1, read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(i++)); + ASSERT_EQ(TRUE, read_info.merge_type_ == MAJOR_MERGE); + ASSERT_EQ(OB_SUCCESS, ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator1, minor_iterator1, read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(i++)); + ASSERT_EQ(TRUE, read_info.merge_type_ == MAJOR_MERGE); + ASSERT_EQ(OB_SUCCESS, ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator1, minor_iterator1, read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(i++)); + ASSERT_EQ(TRUE, read_info.merge_type_ == MINOR_MERGE); + + compaction::ObIDiagnoseInfoMgr::Iterator major_iterator2; + compaction::ObIDiagnoseInfoMgr::Iterator minor_iterator2; + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantSSTableMergeInfoMgr *)->open_iter(major_iterator2, minor_iterator2)); + i = 1; + ASSERT_EQ(OB_SUCCESS, ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator2, minor_iterator2, read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(i++)); + ASSERT_EQ(TRUE, read_info.merge_type_ == MAJOR_MERGE); + ASSERT_EQ(OB_SUCCESS, ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator2, minor_iterator2, read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(i++)); + ASSERT_EQ(TRUE, read_info.merge_type_ == MAJOR_MERGE); +} + +TEST_F(TestSSTableMergeInfoMgr, resize) +{ + int ret = OB_SUCCESS; + ObTenantSSTableMergeInfoMgr *merge_info_mgr = MTL(ObTenantSSTableMergeInfoMgr*); + ASSERT_TRUE(nullptr != merge_info_mgr); + + ret = MTL(ObTenantSSTableMergeInfoMgr*)->init(MERGE_INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + + ObSSTableMergeInfo merge_info; + compaction::ObDiagnoseInfoParam<2, 0> info_param; + info_param.type_.suspect_type_ = ObSuspectInfoType::SUSPECT_MEMTABLE_CANT_MINOR_MERGE; + info_param.struct_type_ = compaction::ObInfoParamStructType::SUSPECT_INFO_PARAM; + merge_info.info_param_ = &info_param; + + merge_info.tenant_id_ = 1; + merge_info.ls_id_ = 1; + merge_info.compaction_scn_ = 100; + merge_info.merge_type_ = ObMergeType::MINOR_MERGE; + const int64_t max_cnt = 20; + int i = 0; + for (i = 0; i < max_cnt; ++i) { + merge_info.tablet_id_ = 1+i; + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info)); + } + ASSERT_EQ(max_cnt, MTL(ObTenantSSTableMergeInfoMgr*)->size()); + + merge_info.merge_type_ = ObMergeType::MAJOR_MERGE; + for (i = 0; i < max_cnt; ++i) { + merge_info.tablet_id_ = 1+i; + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info)); + } + ASSERT_EQ(2 * max_cnt, MTL(ObTenantSSTableMergeInfoMgr*)->size()); + + compaction::ObIDiagnoseInfoMgr::Iterator major_iterator; + compaction::ObIDiagnoseInfoMgr::Iterator minor_iterator; + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantSSTableMergeInfoMgr *)->open_iter(major_iterator, minor_iterator)); + + ObSSTableMergeInfo read_info; + char comment[common::OB_COMPACTION_EVENT_STR_LENGTH]; + ASSERT_EQ(OB_SUCCESS, ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator, minor_iterator, read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(1)); + ASSERT_EQ(TRUE, read_info.merge_type_ == ObMergeType::MAJOR_MERGE); + + // every info is 880 bytes, each page contains 8 info, 20 infos are in 3 pages (8 8 4) + // after set_max, major pool has 1 page, minor pool has 3 page + // major pool left 3 info (3 * 880 < 8192 * 0.4) + // minor pool don't need to purge + ret = MTL(ObTenantSSTableMergeInfoMgr*)->set_max(4 * MERGE_INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(3 + 20, MTL(ObTenantSSTableMergeInfoMgr*)->size()); + + i = 18; + while (i <= 20 && OB_SUCC(ret)) { + if (OB_FAIL(ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator, minor_iterator, read_info, comment, sizeof(comment)))) { + ASSERT_EQ(OB_ITER_END, ret); + } else { + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(i)); + ASSERT_EQ(TRUE, read_info.merge_type_ == ObMergeType::MAJOR_MERGE); + ++i; + } + } + i = 1; + while (i <= 20 && OB_SUCC(ret)) { + if (OB_FAIL(ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator, minor_iterator, read_info, comment, sizeof(comment)))) { + ASSERT_EQ(OB_ITER_END, ret); + } else { + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(i)); + ASSERT_EQ(TRUE, read_info.merge_type_ == ObMergeType::MINOR_MERGE); + ++i; + } + } + + merge_info.merge_type_ = ObMergeType::MAJOR_MERGE; + // before add , major pool has one page which contains 4 info (1 purged, 3 valid) + for (i = 1; i <= 10; ++i) { + merge_info.tablet_id_ = max_cnt+i; + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info)); + } + ASSERT_EQ(6 + 20, MTL(ObTenantSSTableMergeInfoMgr*)->size()); + + major_iterator.reset(); + minor_iterator.reset(); + ret = MTL(ObTenantSSTableMergeInfoMgr *)->open_iter(major_iterator, minor_iterator); + ASSERT_EQ(OB_SUCCESS, ret); + + // let the iter in the major merge info pool iter_end + i = 25; + while (i <= 30 && OB_SUCC(ret)) { + if (OB_FAIL(ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator, minor_iterator, read_info, comment, sizeof(comment)))) { + ASSERT_EQ(OB_ITER_END, ret); + } else { + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(i)); + ASSERT_EQ(TRUE, read_info.merge_type_ == ObMergeType::MAJOR_MERGE); + ++i; + } + } + ASSERT_EQ(OB_SUCCESS, ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator, minor_iterator, read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(1)); + ASSERT_EQ(TRUE, read_info.merge_type_ == ObMergeType::MINOR_MERGE); + + compaction::ObIDiagnoseInfoMgr::Iterator major_iterator1; + compaction::ObIDiagnoseInfoMgr::Iterator minor_iterator1; + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantSSTableMergeInfoMgr *)->open_iter(major_iterator1, minor_iterator1)); + i = 25; + while (i <= 30 && OB_SUCC(ret)) { + if (OB_FAIL(ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator1, minor_iterator1, read_info, comment, sizeof(comment)))) { + ASSERT_EQ(OB_ITER_END, ret); + } else { + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(i)); + ASSERT_EQ(TRUE, read_info.merge_type_ == ObMergeType::MAJOR_MERGE); + ++i; + } + } + + // after set_max, major pool has 1 page, minor pool has 2 pages + // major pool don't need to purge (5) + // minor pool left 7 info (7 * 880 < 16384 * 0.4) (3 4) + ret = MTL(ObTenantSSTableMergeInfoMgr*)->set_max(2 * MERGE_INFO_PAGE_SIZE); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(6 + 7, MTL(ObTenantSSTableMergeInfoMgr*)->size()); + + merge_info.merge_type_ = ObMergeType::MAJOR_MERGE; + merge_info.tablet_id_ = 31; + ASSERT_EQ(OB_SUCCESS, MTL(ObTenantSSTableMergeInfoMgr*)->add_sstable_merge_info(merge_info)); + + // the iterator will not get the new major merge info because it is in the iter_end + // but it can continue to get the info in minor merge info pool + ASSERT_EQ(OB_SUCCESS, ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator, minor_iterator, read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(14)); + ASSERT_EQ(TRUE, read_info.merge_type_ == ObMergeType::MINOR_MERGE); + + ASSERT_EQ(OB_SUCCESS, ObTenantSSTableMergeInfoMgr::get_next_info(major_iterator1, minor_iterator1, read_info, comment, sizeof(comment))); + ASSERT_EQ(TRUE, read_info.tablet_id_ == ObTabletID(31)); + ASSERT_EQ(TRUE, read_info.merge_type_ == ObMergeType::MAJOR_MERGE); } } // end namespace unittest @@ -115,7 +327,7 @@ int main(int argc, char **argv) { system("rm -f test_sstable_merge_info_mgr.log*"); OB_LOGGER.set_file_name("test_sstable_merge_info_mgr.log"); - OB_LOGGER.set_log_level("INFO"); + OB_LOGGER.set_log_level("DEBUG"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/unittest/storage/test_table_scan_pure_index_table.cpp b/unittest/storage/test_table_scan_pure_index_table.cpp index 40a9385e5..d9e74b8ab 100644 --- a/unittest/storage/test_table_scan_pure_index_table.cpp +++ b/unittest/storage/test_table_scan_pure_index_table.cpp @@ -29,6 +29,10 @@ public: public: static void SetUpTestCase(); static void TearDownTestCase(); + void SetUp() + { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); + } public: void insert_data_to_tablet(MockObAccessService *access_service); void table_scan( diff --git a/unittest/storage/test_tablet_helper.h b/unittest/storage/test_tablet_helper.h index 1dbdd66f2..aab72c8a9 100644 --- a/unittest/storage/test_tablet_helper.h +++ b/unittest/storage/test_tablet_helper.h @@ -13,12 +13,20 @@ #ifndef OCEANBASE_STORAGE_TEST_TABLET_HELPER #define OCEANBASE_STORAGE_TEST_TABLET_HELPER +#define private public +#define protected public + #include "lib/ob_errno.h" #include "lib/oblog/ob_log_module.h" #include "share/ob_rpc_struct.h" #include "storage/tx/ob_trans_define.h" #include "storage/ls/ob_ls_tablet_service.h" +#include "storage/ls/ob_ls.h" #include "share/scn.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/tablet/ob_tablet_slog_helper.h" +#include "storage/init_basic_struct.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" namespace oceanbase { @@ -27,39 +35,161 @@ namespace storage class TestTabletHelper { public: - static int create_tablet(ObLSTabletService &ls_tablet_svr, obrpc::ObBatchCreateTabletArg &arg); - static int remove_tablet(ObLSTabletService &ls_tablet_svr, obrpc::ObBatchRemoveTabletArg &arg); + static void prepare_sstable_param( + const common::ObTabletID &tablet_id, + const share::schema::ObTableSchema &table_schema, + ObTabletCreateSSTableParam ¶m); + static int create_tablet( + ObLSHandle &ls_handle, + const common::ObTabletID &tablet_id, + const share::schema::ObTableSchema &table_schema, + common::ObArenaAllocator &allocator, + const ObTabletStatus::Status tablet_status = ObTabletStatus::Status::NORMAL, + const share::SCN &create_commit_scn = share::SCN::min_scn()); + static int remove_tablet( + const ObLSHandle &ls_handle, + const common::ObTabletID &tablet_id); }; -int TestTabletHelper::create_tablet(ObLSTabletService &ls_tablet_svr, obrpc::ObBatchCreateTabletArg &arg) +inline void TestTabletHelper::prepare_sstable_param( + const common::ObTabletID &tablet_id, + const share::schema::ObTableSchema &table_schema, + ObTabletCreateSSTableParam ¶m) { - int ret = common::OB_SUCCESS; - transaction::ObMulSourceDataNotifyArg trans_flags; - trans_flags.tx_id_ = 123; - trans_flags.scn_ = share::SCN::invalid_scn(); - trans_flags.for_replay_ = false; + const int64_t multi_version_col_cnt = ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + param.table_key_.table_type_ = ObITable::TableType::MAJOR_SSTABLE; + param.table_key_.tablet_id_ = tablet_id; + param.table_key_.version_range_.base_version_ = ObVersionRange::MIN_VERSION; + param.table_key_.version_range_.snapshot_version_ = 1; + param.schema_version_ = table_schema.get_schema_version(); + param.create_snapshot_version_ = 0; + param.progressive_merge_round_ = table_schema.get_progressive_merge_round(); + param.progressive_merge_step_ = 0; + param.table_mode_ = table_schema.get_table_mode_struct(); + param.index_type_ = table_schema.get_index_type(); + param.rowkey_column_cnt_ = table_schema.get_rowkey_column_num() + + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + param.root_block_addr_.set_none_addr(); + param.data_block_macro_meta_addr_.set_none_addr(); + param.root_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + param.latest_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + param.data_index_tree_height_ = 0; + param.index_blocks_cnt_ = 0; + param.data_blocks_cnt_ = 0; + param.micro_block_cnt_ = 0; + param.use_old_macro_block_count_ = 0; + param.column_cnt_ = table_schema.get_column_count() + multi_version_col_cnt; + param.data_checksum_ = 0; + param.occupy_size_ = 0; + param.ddl_scn_.set_min(); + param.filled_tx_scn_.set_min(); + param.original_size_ = 0; + param.compressor_type_ = ObCompressorType::NONE_COMPRESSOR; + param.encrypt_id_ = 0; + param.master_key_id_ = 0; +} - if (OB_FAIL(ls_tablet_svr.on_prepare_create_tablets(arg, trans_flags))) { - STORAGE_LOG(WARN, "failed to prepare create tablets", K(ret), K(arg)); - } else if (FALSE_IT(trans_flags.scn_ = share::SCN::minus(share::SCN::max_scn(), 100))) { - } else if (OB_FAIL(ls_tablet_svr.on_redo_create_tablets(arg, trans_flags))) { - STORAGE_LOG(WARN, "failed to redo create tablets", K(ret), K(arg)); - } else if (FALSE_IT(trans_flags.scn_ = share::SCN::plus(trans_flags.scn_, 1))) { - } else if (OB_FAIL(ls_tablet_svr.on_tx_end_create_tablets(arg, trans_flags))) { - STORAGE_LOG(WARN, "failed to tx end create tablets", K(ret), K(arg)); - } else if (FALSE_IT(trans_flags.scn_ = share::SCN::plus(trans_flags.scn_, 1))) { - } else if (OB_FAIL(ls_tablet_svr.on_commit_create_tablets(arg, trans_flags))) { - STORAGE_LOG(WARN, "failed to commit create tablets", K(ret), K(arg)); +inline int TestTabletHelper::create_tablet( + ObLSHandle &ls_handle, + const common::ObTabletID &tablet_id, + const share::schema::ObTableSchema &table_schema, + common::ObArenaAllocator &allocator, + const ObTabletStatus::Status tablet_status, + const share::SCN &create_commit_scn) +{ + int ret = OB_SUCCESS; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + + ObTabletCreateSSTableParam param; + prepare_sstable_param(tablet_id, table_schema, param); + void *buff = nullptr; + ObSSTable *sstable = nullptr; + if (OB_ISNULL(buff = allocator.alloc(sizeof(ObSSTable)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "fail to allocate memory", K(ret)); + } else if (FALSE_IT(sstable = new (buff) ObSSTable())) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, allocator, *sstable))) { + STORAGE_LOG(WARN, "failed to acquire sstable", K(ret)); + } else if (OB_FAIL(ObSSTableMergeRes::fill_column_checksum_for_empty_major(param.column_cnt_, param.column_checksums_))) { + STORAGE_LOG(WARN, "fill column checksum failed", K(ret), K(param)); + } else { + const int64_t snapshot_version = 1; + const share::ObLSID &ls_id = ls_handle.get_ls()->get_ls_id(); + ObFreezer *freezer = ls_handle.get_ls()->get_freezer(); + ObTabletTableStoreFlag store_flag; + const lib::Worker::CompatMode compat_mode = lib::Worker::CompatMode::MYSQL; + ObTabletHandle tablet_handle; + const ObTabletMapKey key(ls_id, tablet_id); + if (OB_FAIL(t3m->create_msd_tablet(WashTabletPriority::WTP_HIGH, key, ls_handle, tablet_handle))) { + STORAGE_LOG(WARN, "t3m acquire tablet failed", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->init( + *tablet_handle.get_allocator(), + ls_id, tablet_id, tablet_id, share::SCN::base_scn(), + snapshot_version, table_schema, compat_mode, store_flag, sstable, freezer))){ + STORAGE_LOG(WARN, "tablet init failed", K(ret), K(ls_id), K(tablet_id)); + } else { + ObTabletCreateDeleteMdsUserData data; + data.tablet_status_ = tablet_status; + data.create_commit_scn_ = create_commit_scn; + data.create_commit_version_ = create_commit_scn.get_val_for_tx(); + if (tablet_status == ObTabletStatus::Status::DELETED) { + data.delete_commit_scn_ = SCN::base_scn(); + } + const int64_t data_serialize_size = data.get_serialize_size(); + int64_t pos = 0; + char *buf = static_cast(t3m->full_tablet_creator_.get_allocator().alloc(data_serialize_size)); + if (OB_FAIL(data.serialize(buf, data_serialize_size, pos))) { + STORAGE_LOG(WARN, "data serialize failed", K(ret), K(data_serialize_size), K(pos)); + } else { + tablet_handle.get_obj()->mds_data_.tablet_status_.committed_kv_.get_ptr()->v_.user_data_.assign(buf, data_serialize_size); + ObMetaDiskAddr disk_addr; + disk_addr.set_mem_addr(0, sizeof(ObTablet)); + if(OB_FAIL(t3m->compare_and_swap_tablet(key, + tablet_handle, + tablet_handle))) { + STORAGE_LOG(WARN, "failed to compare and swap tablet", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); + } else { + ObLSTabletService *ls_tablet_svr = ls_handle.get_ls()->get_tablet_svr(); + if OB_FAIL(ls_tablet_svr->tablet_id_set_.set(tablet_id)) { + STORAGE_LOG(WARN, "set tablet id failed", K(ret), K(tablet_id)); + } + } + } + } + } + return ret; +} + +inline int TestTabletHelper::remove_tablet(const ObLSHandle &ls_handle, const ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + + ObTabletHandle tablet_handle; + ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle); + const share::ObLSID &ls_id = ls_handle.get_ls()->get_ls_id(); + + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + ObTabletCreateDeleteMdsUserData data; + ObTabletStatus status(ObTabletStatus::DELETING); + data.tablet_status_ = status; + const int64_t data_serialize_size = data.get_serialize_size(); + int64_t pos = 0; + char *buf = reinterpret_cast(t3m->full_tablet_creator_.get_allocator().alloc(data_serialize_size)); + if (OB_FAIL(data.serialize(buf, data_serialize_size, pos))) { + STORAGE_LOG(WARN, "data serialize failed", K(ret), K(data_serialize_size), K(pos)); + } else { + tablet_handle.get_obj()->mds_data_.tablet_status_.committed_kv_.get_ptr()->v_.user_data_.assign(buf, data_serialize_size); + ObMetaDiskAddr disk_addr; + disk_addr.set_mem_addr(0, sizeof(ObTablet)); + if(OB_FAIL(t3m->compare_and_swap_tablet( + ObTabletMapKey(ls_id, tablet_id), tablet_handle, tablet_handle))) { + STORAGE_LOG(WARN, "failed to compare and swap tablet", K(ret), K(ls_id), K(tablet_id), K(disk_addr)); + } } return ret; } -int TestTabletHelper::remove_tablet(ObLSTabletService &ls_tablet_svr, obrpc::ObBatchRemoveTabletArg &arg) -{ - int ret = OB_SUCCESS; - return ret; -} } // namespace storage } // namespace oceanbase diff --git a/unittest/storage/test_tenant_meta_obj_pool.cpp b/unittest/storage/test_tenant_meta_obj_pool.cpp index 6847c2b07..12f92e176 100644 --- a/unittest/storage/test_tenant_meta_obj_pool.cpp +++ b/unittest/storage/test_tenant_meta_obj_pool.cpp @@ -37,14 +37,12 @@ public: static const int64_t MAX_TEST_TABLET_CNT_IN_OBJ_POOL = 10000; private: - TryWashTabletFunc wash_func_; ObTenantMetaObjPool obj_pool_; ObTenantMetaMemMgr t3m_; }; TestTenantMetaObjPool::TestTenantMetaObjPool() - : wash_func_(t3m_), - obj_pool_(common::OB_SERVER_TENANT_ID, MAX_TEST_TABLET_CNT_IN_OBJ_POOL, "TestPool", ObCtxIds::META_OBJ_CTX_ID, wash_func_), + : obj_pool_(common::OB_SERVER_TENANT_ID, MAX_TEST_TABLET_CNT_IN_OBJ_POOL, "TestPool", ObCtxIds::META_OBJ_CTX_ID), t3m_(common::OB_SERVER_TENANT_ID) { } diff --git a/unittest/storage/test_tenant_tablet_stat_mgr.cpp b/unittest/storage/test_tenant_tablet_stat_mgr.cpp index a02f54496..8a57ba5b1 100644 --- a/unittest/storage/test_tenant_tablet_stat_mgr.cpp +++ b/unittest/storage/test_tenant_tablet_stat_mgr.cpp @@ -21,25 +21,6 @@ using namespace common; using namespace storage; using namespace compaction; - -template -int ObTabletStream::get_bucket_tablet_stat( - const ObTabletStatBucket &bucket, - common::ObIArray &tablet_stats) const -{ - int ret = OB_SUCCESS; - int64_t idx = bucket.head_idx_; - - for (int64_t i = 0; OB_SUCC(ret) && i < bucket.count(); ++i) { - int64_t curr_idx = bucket.get_idx(idx); - if (OB_FAIL(tablet_stats.push_back(bucket.units_[curr_idx]))) { - LOG_WARN("failed to add tablet stat", K(ret), K(idx)); - } - ++idx; - } - return ret; -} - class TestTenantTabletStatMgr : public ::testing::Test { public: @@ -77,6 +58,7 @@ void TestTenantTabletStatMgr::TearDownTestCase() void TestTenantTabletStatMgr::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); int ret = OB_SUCCESS; ObTenantEnv::set_tenant(&tenant_base_); @@ -143,7 +125,7 @@ TEST_F(TestTenantTabletStatMgr, basic_tablet_stat_bucket) tablet_stat.scan_physical_row_cnt_ = 100; { - int64_t step = 1; + uint32_t step = 1; ObTabletStatBucket<8> bucket(step); ObTabletStat retired_stat; bool has_retired = false; @@ -160,7 +142,7 @@ TEST_F(TestTenantTabletStatMgr, basic_tablet_stat_bucket) } { - int64_t step = 16; + uint32_t step = 16; ObTabletStatBucket<4> bucket(step); ObTabletStat retired_stat; bool has_retired = false; @@ -179,7 +161,7 @@ TEST_F(TestTenantTabletStatMgr, basic_tablet_stat_bucket) } { - int64_t step = 32; + uint32_t step = 32; ObTabletStatBucket<4> bucket(step); ObTabletStat retired_stat; bool has_retired = false; diff --git a/unittest/storage/tx/it/test_tx.cpp b/unittest/storage/tx/it/test_tx.cpp index d74d25849..c8b79729c 100644 --- a/unittest/storage/tx/it/test_tx.cpp +++ b/unittest/storage/tx/it/test_tx.cpp @@ -47,6 +47,7 @@ class ObTestTx : public ::testing::Test public: virtual void SetUp() override { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); ObMallocAllocator::get_instance()->create_and_add_tenant_allocator(1001); const uint64_t tv = ObTimeUtility::current_time(); ObCurTraceId::set(&tv); diff --git a/unittest/storage/tx/it/test_tx_ctx.cpp b/unittest/storage/tx/it/test_tx_ctx.cpp index f30532071..ffcf79a9b 100644 --- a/unittest/storage/tx/it/test_tx_ctx.cpp +++ b/unittest/storage/tx/it/test_tx_ctx.cpp @@ -35,6 +35,7 @@ class ObTestTxCtx : public ::testing::Test public: virtual void SetUp() override { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); ObMallocAllocator::get_instance()->create_and_add_tenant_allocator(1001); const uint64_t tv = ObTimeUtility::current_time(); ObCurTraceId::set(&tv); diff --git a/unittest/storage/tx/it/test_tx_free_route.cpp b/unittest/storage/tx/it/test_tx_free_route.cpp index 7a9f8c1b4..4a211055d 100644 --- a/unittest/storage/tx/it/test_tx_free_route.cpp +++ b/unittest/storage/tx/it/test_tx_free_route.cpp @@ -600,6 +600,7 @@ class ObTestTxFreeRoute : public ::testing::Test public: virtual void SetUp() override { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); ObMallocAllocator::get_instance()->create_and_add_tenant_allocator(1001); const uint64_t tv = ObTimeUtility::current_time(); ObCurTraceId::set(&tv); diff --git a/unittest/storage/tx/it/tx_node.cpp b/unittest/storage/tx/it/tx_node.cpp index 0b0db9bf1..7f1089914 100644 --- a/unittest/storage/tx/it/tx_node.cpp +++ b/unittest/storage/tx/it/tx_node.cpp @@ -496,7 +496,7 @@ int ObTxNode::read(const ObTxReadSnapshot &snapshot, read_store_ctx.ls_id_ = ls_id_; OZ(txs_.get_read_store_ctx(snapshot, false, 5000ll * 1000, read_store_ctx)); // HACK, refine: mock LS's each member in some way - read_store_ctx.mvcc_acc_ctx_.tx_table_guard_.init(&fake_tx_table_); + read_store_ctx.mvcc_acc_ctx_.tx_table_guards_.tx_table_guard_.init(&fake_tx_table_); read_store_ctx.mvcc_acc_ctx_.abs_lock_timeout_ = ObTimeUtility::current_time() + 5000ll * 1000; blocksstable::ObDatumRow row; { @@ -504,11 +504,10 @@ int ObTxNode::read(const ObTxReadSnapshot &snapshot, ObArenaAllocator allocator; ObTableReadInfo read_info; const int64_t schema_version = 100; - read_info.init(allocator, schema_version, 1, false, columns_); + read_info.init(allocator, schema_version, 1, false, columns_, nullptr/*storage_cols_index*/); iter_param.table_id_ = 1; iter_param.tablet_id_ = 100; iter_param.read_info_ = &read_info; - iter_param.full_read_info_ = nullptr; iter_param.out_cols_project_ = NULL; iter_param.agg_cols_project_ = NULL; iter_param.is_multi_version_minor_merge_ = false; @@ -582,12 +581,13 @@ int ObTxNode::write(ObTxDesc &tx, { TRANS_LOG(INFO, "write", K(key), K(value), K(snapshot), K(tx), KPC(this)); int ret = OB_SUCCESS; + const transaction::ObSerializeEncryptMeta *encrypt_meta = NULL; ObTenantEnv::set_tenant(&tenant_); ObStoreCtx write_store_ctx; auto iter = new ObTableStoreIterator(); iter->reset(); ObITable *mtb = memtable_; - iter->add_tables(&mtb, 1); + iter->add_table(mtb); write_store_ctx.ls_ = &mock_ls_; write_store_ctx.ls_id_ = ls_id_; write_store_ctx.table_iter_ = iter; @@ -595,13 +595,10 @@ int ObTxNode::write(ObTxDesc &tx, OZ(txs_.get_write_store_ctx(tx, snapshot, write_flag, - write_store_ctx)); - write_store_ctx.mvcc_acc_ctx_.tx_table_guard_.init(&fake_tx_table_); + write_store_ctx, + false)); + write_store_ctx.mvcc_acc_ctx_.tx_table_guards_.tx_table_guard_.init(&fake_tx_table_); ObArenaAllocator allocator; - ObTableReadInfo read_info; - const transaction::ObSerializeEncryptMeta *encrypt_meta = NULL; - const int64_t schema_version = 100; - read_info.init(allocator, schema_version, 1, false, columns_); ObStoreRow row; ObObj cols[2] = {ObObj(key), ObObj(value)}; row.capacity_ = 2; @@ -609,7 +606,29 @@ int ObTxNode::write(ObTxDesc &tx, row.row_val_.count_ = 2; row.flag_ = blocksstable::ObDmlFlag::DF_UPDATE; row.trans_id_.reset(); - OZ(memtable_->set(write_store_ctx, 1, read_info, columns_, row, encrypt_meta)); + + ObTableIterParam param; + ObTableAccessContext context; + ObVersionRange trans_version_range; + const bool read_latest = true; + ObQueryFlag query_flag; + ObTableReadInfo read_info; + + const int64_t schema_version = 100; + read_info.init(allocator, 2, 1, false, columns_, nullptr/*storage_cols_index*/); + + trans_version_range.base_version_ = 0; + trans_version_range.multi_version_start_ = 0; + trans_version_range.snapshot_version_ = EXIST_READ_SNAPSHOT_VERSION; + query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; + query_flag.read_latest_ = read_latest & ObQueryFlag::OBSF_MASK_READ_LATEST; + + param.table_id_ = 1; + param.tablet_id_ = 1; + param.read_info_ = &read_info; + + context.init(query_flag, write_store_ctx, allocator, trans_version_range); + OZ(memtable_->set(param, context, columns_, row, encrypt_meta)); OZ(txs_.revert_store_ctx(write_store_ctx)); delete iter; return ret; @@ -624,14 +643,15 @@ int ObTxNode::write_begin(ObTxDesc &tx, auto iter = new ObTableStoreIterator(); iter->reset(); ObITable *mtb = memtable_; - iter->add_tables(&mtb, 1); + iter->add_table(mtb); write_store_ctx.ls_id_ = ls_id_; write_store_ctx.table_iter_ = iter; concurrent_control::ObWriteFlag write_flag; OZ(txs_.get_write_store_ctx(tx, snapshot, write_flag, - write_store_ctx)); + write_store_ctx, + false)); return ret; } @@ -644,13 +664,33 @@ int ObTxNode::write_one_row(ObStoreCtx& write_store_ctx, const int64_t key, cons ObTableReadInfo read_info; const transaction::ObSerializeEncryptMeta *encrypt_meta = NULL; const int64_t schema_version = 100; - read_info.init(allocator, schema_version, 1, false, columns_); + read_info.init(allocator, 2, 1, false, columns_, nullptr/*storage_cols_index*/); ObStoreRow row; ObObj cols[2] = {ObObj(key), ObObj(value)}; row.flag_ = blocksstable::ObDmlFlag::DF_INSERT; row.row_val_.cells_ = cols; row.row_val_.count_ = 2; - OZ(memtable_->set(write_store_ctx, 1, read_info, columns_, row, encrypt_meta)); + + ObTableIterParam param; + ObTableAccessContext context; + ObVersionRange trans_version_range; + const bool read_latest = true; + ObQueryFlag query_flag; + + + trans_version_range.base_version_ = 0; + trans_version_range.multi_version_start_ = 0; + trans_version_range.snapshot_version_ = EXIST_READ_SNAPSHOT_VERSION; + query_flag.use_row_cache_ = ObQueryFlag::DoNotUseCache; + query_flag.read_latest_ = read_latest & ObQueryFlag::OBSF_MASK_READ_LATEST; + + param.table_id_ = 1; + param.tablet_id_ = 1; + param.read_info_ = &read_info; + + OZ(context.init(query_flag, write_store_ctx, allocator, trans_version_range)); + + OZ(memtable_->set(param, context, columns_, row, encrypt_meta)); return ret; } diff --git a/unittest/storage/tx/test_ob_tx_log.cpp b/unittest/storage/tx/test_ob_tx_log.cpp index c7ca26e51..a2e877fde 100644 --- a/unittest/storage/tx/test_ob_tx_log.cpp +++ b/unittest/storage/tx/test_ob_tx_log.cpp @@ -158,7 +158,7 @@ TEST_F(TestObTxLog, tx_log_body_except_redo) ObTxBufferNodeArray TEST_TX_BUFFER_NODE_ARRAY; ObString str("TEST CASE"); ObTxBufferNode node; - node.init(ObTxDataSourceType::LS_TABLE, str); + node.init(ObTxDataSourceType::LS_TABLE, str, share::SCN(), nullptr); TEST_TX_BUFFER_NODE_ARRAY.push_back(node); ObTxCommitInfoLog fill_commit_state(TEST_ADDR, @@ -296,7 +296,7 @@ TEST_F(TestObTxLog, tx_log_body_redo) ObTxBufferNodeArray TEST_TX_BUFFER_NODE_ARRAY; ObString str("TEST CASE"); ObTxBufferNode node; - node.init(ObTxDataSourceType::LS_TABLE, str); + node.init(ObTxDataSourceType::LS_TABLE, str, share::SCN(), nullptr); TEST_TX_BUFFER_NODE_ARRAY.push_back(node); ObTxCommitInfoLog fill_commit_state(TEST_ADDR, @@ -414,7 +414,7 @@ TEST_F(TestObTxLog, test_compat_bytes) ObTxBufferNodeArray TEST_TX_BUFFER_NODE_ARRAY; ObString str("TEST CASE"); ObTxBufferNode node; - node.init(ObTxDataSourceType::LS_TABLE, str); + node.init(ObTxDataSourceType::LS_TABLE, str, share::SCN(), nullptr); TEST_TX_BUFFER_NODE_ARRAY.push_back(node); ObTxCommitInfoLog fill_commit_info(TEST_ADDR, diff --git a/unittest/storage/tx_storage/test_create_tablet_clog.cpp b/unittest/storage/tx_storage/test_create_tablet_clog.cpp index 8eb58c39d..8d1a02baa 100644 --- a/unittest/storage/tx_storage/test_create_tablet_clog.cpp +++ b/unittest/storage/tx_storage/test_create_tablet_clog.cpp @@ -55,6 +55,7 @@ public: void TestCreateTabletClog::SetUp() { + ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); } void TestCreateTabletClog::TearDown() diff --git a/unittest/storage/tx_table/test_tx_ctx_table.cpp b/unittest/storage/tx_table/test_tx_ctx_table.cpp index e6a6ad285..84eae2eef 100644 --- a/unittest/storage/tx_table/test_tx_ctx_table.cpp +++ b/unittest/storage/tx_table/test_tx_ctx_table.cpp @@ -36,13 +36,6 @@ using namespace storage; using namespace blocksstable; using namespace share; -namespace storage -{ -int64_t ObTenantMetaMemMgr::cal_adaptive_bucket_num() -{ - return 1000; -} -} namespace unittest { @@ -110,6 +103,7 @@ public: protected: virtual void SetUp() override { + oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); ObTxPalfParam palf_param((logservice::ObLogHandler *)(0x01), (transaction::ObDupTableLSHandler *)(0x02)); freezer_.init(&ls_); @@ -212,7 +206,7 @@ TEST_F(TestTxCtxTable, test_tx_ctx_memtable_mgr) ObColDesc col_desc; columns_.push_back(col_desc); param.reset(); - read_info.init(allocator, 16000, 1, lib::is_oracle_mode(), columns_); + read_info.init(allocator, 16000, 1, lib::is_oracle_mode(), columns_, nullptr/*storage_cols_index*/); param.tablet_id_ = tablet_id_; param.read_info_ = &read_info; param.is_multi_version_minor_merge_ = true;